diff --git a/crypto/crypto.h b/crypto/crypto.h index c6f186cf9..8a314a332 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h @@ -217,7 +217,8 @@ void RSA_print(const RSA_CTX *ctx); /************************************************************************** * RNG declarations **************************************************************************/ -EXP_FUNC void STDCALL RNG_initialize(const uint8_t *seed_buf, int size); +EXP_FUNC void STDCALL RNG_initialize(void); +EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size); EXP_FUNC void STDCALL RNG_terminate(void); EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data); void get_random_NZ(int num_rand_bytes, uint8_t *rand_data); diff --git a/crypto/crypto_misc.c b/crypto/crypto_misc.c index 9a9a4f957..1dea121d9 100644 --- a/crypto/crypto_misc.c +++ b/crypto/crypto_misc.c @@ -56,7 +56,6 @@ static HCRYPTPROV gCryptProv; static uint8_t entropy_pool[ENTROPY_POOL_SIZE]; #endif -static int rng_ref_count; const char * const unsupported_str = "Error: Feature not supported\n"; #ifndef CONFIG_SSL_SKELETON_MODE @@ -102,46 +101,44 @@ int get_file(const char *filename, uint8_t **buf) * - On Linux use /dev/urandom * - If none of these work then use a custom RNG. */ -EXP_FUNC void STDCALL RNG_initialize(const uint8_t *seed_buf, int size) +EXP_FUNC void STDCALL RNG_initialize() { - if (rng_ref_count == 0) - { #if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM) - rng_fd = ax_open("/dev/urandom", O_RDONLY); + rng_fd = ax_open("/dev/urandom", O_RDONLY); #elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB) - if (!CryptAcquireContext(&gCryptProv, - NULL, NULL, PROV_RSA_FULL, 0)) + if (!CryptAcquireContext(&gCryptProv, + NULL, NULL, PROV_RSA_FULL, 0)) + { + if (GetLastError() == NTE_BAD_KEYSET && + !CryptAcquireContext(&gCryptProv, + NULL, + NULL, + PROV_RSA_FULL, + CRYPT_NEWKEYSET)) { - if (GetLastError() == NTE_BAD_KEYSET && - !CryptAcquireContext(&gCryptProv, - NULL, - NULL, - PROV_RSA_FULL, - CRYPT_NEWKEYSET)) - { - printf("CryptoLib: %x\n", unsupported_str, GetLastError()); - exit(1); - } + printf("CryptoLib: %x\n", unsupported_str, GetLastError()); + exit(1); } -#else - int i; - uint32_t seed_addr_val = (uint32_t)&seed_buf; - uint32_t *ep = (uint32_t *)entropy_pool; - - /* help start the entropy with the user's private key - this is - a number that should be hard to find, due to the fact that it - relies on knowing the private key */ - memcpy(entropy_pool, seed_buf, ENTROPY_POOL_SIZE); - srand((long)entropy_pool); - - /* mix it up a little with a stack address */ - for (i = 0; i < ENTROPY_POOL_SIZE/4; i++) - ep[i] ^= seed_addr_val; - -#endif } +#else + /* start of with a stack to copy across */ + int i; + memcpy(entropy_pool, &i, ENTROPY_POOL_SIZE); + srand(&i); +#endif +} - rng_ref_count++; +/** + * If no /dev/urandom, then initialise the RNG with something interesting. + */ +EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size) +{ +#if defined(WIN32) || defined(CONFIG_WIN32_USE_CRYPTO_LIB) + int i; + + for (i = 0; i < ENTROPY_POOL_SIZE && i < size; i++) + entropy_pool[i] ^= seed_buf[i]; +#endif } /** @@ -149,14 +146,11 @@ EXP_FUNC void STDCALL RNG_initialize(const uint8_t *seed_buf, int size) */ EXP_FUNC void STDCALL RNG_terminate(void) { - if (--rng_ref_count == 0) - { #ifndef WIN32 - close(rng_fd); + close(rng_fd); #elif defined(CONFIG_WIN32_USE_CRYPTO_LIB) - CryptReleaseContext(gCryptProv, 0); + CryptReleaseContext(gCryptProv, 0); #endif - } } /** diff --git a/crypto/os_int.h b/crypto/os_int.h new file mode 100644 index 000000000..878856723 --- /dev/null +++ b/crypto/os_int.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012, Cameron Rich + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the axTLS project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file os_int.h + * + * Ensure a consistent bit size + */ + +#ifndef HEADER_OS_INT_H +#define HEADER_OS_INT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) +typedef UINT8 uint8_t; +typedef INT8 int8_t; +typedef UINT16 uint16_t; +typedef INT16 int16_t; +typedef UINT32 uint32_t; +typedef INT32 int32_t; +typedef UINT64 uint64_t; +typedef INT64 int64_t; +#else /* Not Win32 */ + +#ifdef CONFIG_PLATFORM_SOLARIS +#include +#else +#include +#endif /* Not Solaris */ + +#endif /* Not Win32 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/httpd/axhttpd.c b/httpd/axhttpd.c index 9a94ab0e1..ce57dbb9d 100644 --- a/httpd/axhttpd.c +++ b/httpd/axhttpd.c @@ -453,7 +453,7 @@ static void addtoservers(int sd) static void handlenewconnection(int listenfd, int is_ssl) { struct sockaddr_in6 their_addr; - int tp = sizeof(their_addr); + socklen_t tp = sizeof(their_addr); char ipbuf[100]; int connfd = accept(listenfd, (struct sockaddr *)&their_addr, &tp); @@ -506,8 +506,11 @@ static int openlistener(char *address, int port) my_addr.sin6_family = AF_INET6; my_addr.sin6_port = htons(port); - my_addr.sin6_addr.s_addr = address == NULL ? - INADDR_ANY : iinet_addr(address); + + if (address == NULL) + my_addr.sin6_addr = in6addr_any; + else + inet_pton(AF_INET6, address, &my_addr.sin6_addr); #endif setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &tp, sizeof(tp)); diff --git a/httpd/htpasswd.c b/httpd/htpasswd.c index 8fe571ab7..7c99abf1e 100644 --- a/httpd/htpasswd.c +++ b/httpd/htpasswd.c @@ -120,7 +120,7 @@ int main(int argc, char *argv[]) exit(1); } - RNG_initialize((uint8_t *)pw, sizeof(pw)); + RNG_initialize(); get_random(MD5_SIZE, md5_salt); RNG_terminate(); base64_encode(md5_salt, MD5_SIZE, b64_salt, sizeof(b64_salt)); diff --git a/ssl/asn1.c b/ssl/asn1.c index f3e17a37b..b082275b2 100644 --- a/ssl/asn1.c +++ b/ssl/asn1.c @@ -160,8 +160,8 @@ int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx) return X509_INVALID_PRIV_KEY; } - /* initialise the RNG */ - RNG_initialize(buf, len); + /* Use the private key to mix up the RNG if possible. */ + RNG_custom_init(buf, len); mod_len = asn1_get_int(buf, &offset, &modulus); pub_len = asn1_get_int(buf, &offset, &pub_exp); diff --git a/ssl/os_port.h b/ssl/os_port.h index af71651a8..1742868d5 100644 --- a/ssl/os_port.h +++ b/ssl/os_port.h @@ -41,6 +41,7 @@ extern "C" { #endif +#include "os_int.h" #include #if defined(WIN32) @@ -114,14 +115,6 @@ extern "C" { #pragma comment(lib, "WS2_32.lib") #pragma comment(lib, "AdvAPI32.lib") -typedef UINT8 uint8_t; -typedef INT8 int8_t; -typedef UINT16 uint16_t; -typedef INT16 int16_t; -typedef UINT32 uint32_t; -typedef INT32 int32_t; -typedef UINT64 uint64_t; -typedef INT64 int64_t; typedef int socklen_t; EXP_FUNC void STDCALL gettimeofday(struct timeval* t,void* timezone); @@ -130,12 +123,6 @@ EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size); #else /* Not Win32 */ -#ifdef CONFIG_PLATFORM_SOLARIS -#include -#else -#include -#endif /* Not Solaris */ - #include #include #include diff --git a/ssl/tls1.c b/ssl/tls1.c index 25405c825..407798d59 100755 --- a/ssl/tls1.c +++ b/ssl/tls1.c @@ -166,6 +166,7 @@ EXP_FUNC SSL_CTX *STDCALL ssl_ctx_new(uint32_t options, int num_sessions) { SSL_CTX *ssl_ctx = (SSL_CTX *)calloc(1, sizeof (SSL_CTX)); ssl_ctx->options = options; + RNG_initialize(); if (load_key_certs(ssl_ctx) < 0) { diff --git a/ssl/tls1.h b/ssl/tls1.h index 55552afe7..5a5d654e6 100755 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -42,6 +42,7 @@ extern "C" { #include "version.h" #include "crypto.h" +#include "os_int.h" #include "crypto_misc.h" #define SSL_PROTOCOL_MIN_VERSION 0x31 /* TLS v1.0 */