diff --git a/src/internal.c b/src/internal.c index 1add79966..0d3cb3677 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6495,6 +6495,70 @@ void FreeHandshakeHashes(WOLFSSL* ssl) } } +/* called if user attempts to re-use WOLFSSL object for a new session. + * For example wolfSSL_clear() is called then wolfSSL_connect or accept */ +int ReinitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) +{ + int ret = 0; + + /* arrays */ + if (!writeDup && ssl->arrays == NULL) { + ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap, + DYNAMIC_TYPE_ARRAYS); + if (ssl->arrays == NULL) { + WOLFSSL_MSG("Arrays Memory error"); + return MEMORY_E; + } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("SSL Arrays", ssl->arrays, sizeof(*ssl->arrays)); +#endif + XMEMSET(ssl->arrays, 0, sizeof(Arrays)); +#if defined(WOLFSSL_TLS13) || defined(WOLFSSL_SNIFFER) + ssl->arrays->preMasterSz = ENCRYPT_LEN; + ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN, ssl->heap, + DYNAMIC_TYPE_SECRET); + if (ssl->arrays->preMasterSecret == NULL) { + return MEMORY_E; + } +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Add("SSL Arrays", ssl->arrays->preMasterSecret, ENCRYPT_LEN); +#endif + XMEMSET(ssl->arrays->preMasterSecret, 0, ENCRYPT_LEN); +#endif + } + + /* RNG */ +#ifdef SINGLE_THREADED + if (ssl->rng == NULL) { + ssl->rng = ctx->rng; /* CTX may have one, if so use it */ + } +#endif + if (ssl->rng == NULL) { + ssl->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ssl->heap,DYNAMIC_TYPE_RNG); + if (ssl->rng == NULL) { + WOLFSSL_MSG("RNG Memory error"); + return MEMORY_E; + } + XMEMSET(ssl->rng, 0, sizeof(WC_RNG)); + ssl->options.weOwnRng = 1; + + /* FIPS RNG API does not accept a heap hint */ +#ifndef HAVE_FIPS + if ( (ret = wc_InitRng_ex(ssl->rng, ssl->heap, ssl->devId)) != 0) { + WOLFSSL_MSG("RNG Init error"); + return ret; + } +#else + if ( (ret = wc_InitRng(ssl->rng)) != 0) { + WOLFSSL_MSG("RNG Init error"); + return ret; + } +#endif + } + (void)ctx; + + return ret; +} /* init everything to 0, NULL, default values before calling anything that may fail so that destructor has a "good" state to cleanup @@ -6803,40 +6867,19 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) InitCipherSpecs(&ssl->specs); /* all done with init, now can return errors, call other stuff */ + if ((ret = ReinitSSL(ssl, ctx, writeDup)) != 0) { + return ret; + } if (!writeDup) { - /* arrays */ - ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap, - DYNAMIC_TYPE_ARRAYS); - if (ssl->arrays == NULL) { - WOLFSSL_MSG("Arrays Memory error"); - return MEMORY_E; - } -#ifdef WOLFSSL_CHECK_MEM_ZERO - wc_MemZero_Add("SSL Arrays", ssl->arrays, sizeof(*ssl->arrays)); -#endif - XMEMSET(ssl->arrays, 0, sizeof(Arrays)); -#if defined(WOLFSSL_TLS13) || defined(WOLFSSL_SNIFFER) - ssl->arrays->preMasterSz = ENCRYPT_LEN; - ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN, ssl->heap, - DYNAMIC_TYPE_SECRET); - if (ssl->arrays->preMasterSecret == NULL) { - return MEMORY_E; - } -#ifdef WOLFSSL_CHECK_MEM_ZERO - wc_MemZero_Add("SSL Arrays", ssl->arrays->preMasterSecret, ENCRYPT_LEN); -#endif - XMEMSET(ssl->arrays->preMasterSecret, 0, ENCRYPT_LEN); -#endif - #ifdef OPENSSL_EXTRA - if ((ssl->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC( - sizeof(WOLFSSL_X509_VERIFY_PARAM), - ssl->heap, DYNAMIC_TYPE_OPENSSL)) == NULL) { - WOLFSSL_MSG("ssl->param memory error"); - return MEMORY_E; - } - XMEMSET(ssl->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); + if ((ssl->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC( + sizeof(WOLFSSL_X509_VERIFY_PARAM), + ssl->heap, DYNAMIC_TYPE_OPENSSL)) == NULL) { + WOLFSSL_MSG("ssl->param memory error"); + return MEMORY_E; + } + XMEMSET(ssl->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); #endif #ifdef SINGLE_THREADED @@ -6862,43 +6905,15 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->options.ownSuites = 0; } #endif - } + } /* !writeDup */ /* Initialize SSL with the appropriate fields from it's ctx */ /* requires valid arrays and suites unless writeDup ing */ - if ((ret = SetSSL_CTX(ssl, ctx, writeDup)) != WOLFSSL_SUCCESS) + if ((ret = SetSSL_CTX(ssl, ctx, writeDup)) != WOLFSSL_SUCCESS) return ret; ssl->options.dtls = ssl->version.major == DTLS_MAJOR; -#ifdef SINGLE_THREADED - ssl->rng = ctx->rng; /* CTX may have one, if so use it */ -#endif - - if (ssl->rng == NULL) { - /* RNG */ - ssl->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ssl->heap,DYNAMIC_TYPE_RNG); - if (ssl->rng == NULL) { - WOLFSSL_MSG("RNG Memory error"); - return MEMORY_E; - } - XMEMSET(ssl->rng, 0, sizeof(WC_RNG)); - ssl->options.weOwnRng = 1; - - /* FIPS RNG API does not accept a heap hint */ -#ifndef HAVE_FIPS - if ( (ret = wc_InitRng_ex(ssl->rng, ssl->heap, ssl->devId)) != 0) { - WOLFSSL_MSG("RNG Init error"); - return ret; - } -#else - if ( (ret = wc_InitRng(ssl->rng)) != 0) { - WOLFSSL_MSG("RNG Init error"); - return ret; - } -#endif - } - #ifdef HAVE_WRITE_DUP if (writeDup) { /* all done */ diff --git a/src/ssl.c b/src/ssl.c index dc629deed..6f4855f8d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1779,6 +1779,10 @@ int wolfSSL_negotiate(WOLFSSL* ssl) int err = WOLFSSL_FATAL_ERROR; WOLFSSL_ENTER("wolfSSL_negotiate"); + + if (ssl == NULL) + return WOLFSSL_FATAL_ERROR; + #ifndef NO_WOLFSSL_SERVER if (ssl->options.side == WOLFSSL_SERVER_END) { #ifdef WOLFSSL_TLS13 @@ -12201,8 +12205,6 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, (void)ret; - WOLFSSL_ENTER("SSL_connect()"); - #ifdef HAVE_ERRNO_H errno = 0; #endif @@ -12236,6 +12238,14 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, return wolfSSL_connect_TLSv13(ssl); #endif + WOLFSSL_ENTER("SSL_connect()"); + + /* make sure this wolfSSL object has arrays and rng setup. Protects + * case where the WOLFSSL object is re-used via wolfSSL_clear() */ + if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) { + return ret; + } + #ifdef WOLFSSL_WOLFSENTRY_HOOKS if ((ssl->ConnectFilter != NULL) && (ssl->options.connectState == CONNECT_BEGIN)) { @@ -12272,7 +12282,6 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, ssl->options.connectState == HELLO_AGAIN || (ssl->options.connectState >= FIRST_REPLY_DONE && ssl->options.connectState <= FIRST_REPLY_FOURTH)); -; #ifdef WOLFSSL_DTLS13 if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) @@ -12708,6 +12717,12 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, #endif WOLFSSL_ENTER("SSL_accept()"); + /* make sure this wolfSSL object has arrays and rng setup. Protects + * case where the WOLFSSL object is re-used via wolfSSL_clear() */ + if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) { + return ret; + } + #ifdef WOLFSSL_WOLFSENTRY_HOOKS if ((ssl->AcceptFilter != NULL) && ((ssl->options.acceptState == ACCEPT_BEGIN) @@ -18604,6 +18619,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, } } + /* reset option bits */ ssl->options.isClosed = 0; ssl->options.connReset = 0; ssl->options.sentNotify = 0; @@ -18616,12 +18632,35 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, ssl->options.handShakeState = NULL_STATE; ssl->options.handShakeDone = 0; ssl->options.processReply = 0; /* doProcessInit */ + ssl->options.havePeerVerify = 0; + ssl->options.havePeerCert = 0; + ssl->options.peerAuthGood = 0; + ssl->options.tls1_3 = 0; + ssl->options.haveSessionId = 0; + ssl->options.tls = 0; + ssl->options.tls1_1 = 0; + ssl->options.noPskDheKe = 0; + #ifdef HAVE_SESSION_TICKET + #ifdef WOLFSSL_TLS13 + ssl->options.ticketsSent = 0; + #endif + ssl->options.rejectTicket = 0; + #endif + #ifdef WOLFSSL_EARLY_DATA + ssl->earlyData = no_early_data; + ssl->earlyDataSz = 0; + #endif + + #if defined(HAVE_TLS_EXTENSIONS) && !defined(NO_TLS) + TLSX_FreeAll(ssl->extensions, ssl->heap); + ssl->extensions = NULL; + #endif ssl->keys.encryptionOn = 0; XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived)); - if (ssl->hsHashes) - (void)InitHandshakeHashes(ssl); + if (InitHandshakeHashes(ssl) != 0) + return WOLFSSL_FAILURE; #ifdef KEEP_PEER_CERT FreeX509(&ssl->peerCert); diff --git a/src/tls.c b/src/tls.c index 6bd814a72..5ffd22dbb 100644 --- a/src/tls.c +++ b/src/tls.c @@ -1406,9 +1406,7 @@ int TLSX_HandleUnsupportedExtension(WOLFSSL* ssl) #endif /** Mark an extension to be sent back to the client. */ -void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type); - -void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type) +static void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type) { TLSX *extension = TLSX_Find(ssl->extensions, type); @@ -5991,7 +5989,7 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input, /* No upgrade allowed. */ if (versionIsGreater(isDtls, minor, ssl->version.minor)) - continue; + continue; /* Check downgrade. */ if (versionIsLesser(isDtls, minor, ssl->version.minor)) { @@ -6011,8 +6009,10 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL* ssl, const byte* input, } if (versionIsAtLeast(isDtls, minor, tls13minor)) { - if (!ssl->options.tls1_3) { - ssl->options.tls1_3 = 1; + ssl->options.tls1_3 = 1; + + /* TLS v1.3 requires supported version extension */ + if (TLSX_Find(ssl->extensions, TLSX_SUPPORTED_VERSIONS) == NULL) { ret = TLSX_Prepend(&ssl->extensions, TLSX_SUPPORTED_VERSIONS, ssl, ssl->heap); if (ret != 0) { diff --git a/src/tls13.c b/src/tls13.c index ec48af32c..8fbfd196e 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -10134,9 +10134,12 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl) WOLFSSL_ENTER("wolfSSL_connect_TLSv13()"); - #ifdef HAVE_ERRNO_H +#ifdef HAVE_ERRNO_H errno = 0; - #endif +#endif + + if (ssl == NULL) + return BAD_FUNC_ARG; if (ssl->options.side != WOLFSSL_CLIENT_END) { ssl->error = SIDE_ERROR; @@ -10144,6 +10147,12 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl) return WOLFSSL_FATAL_ERROR; } + /* make sure this wolfSSL object has arrays and rng setup. Protects + * case where the WOLFSSL object is re-used via wolfSSL_clear() */ + if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) { + return ret; + } + #ifdef WOLFSSL_WOLFSENTRY_HOOKS if ((ssl->ConnectFilter != NULL) && (ssl->options.connectState == CONNECT_BEGIN)) @@ -11185,11 +11194,13 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl) WOLFSSL_ENTER("SSL_accept_TLSv13()"); - #ifdef HAVE_ERRNO_H errno = 0; #endif + if (ssl == NULL) + return WOLFSSL_FATAL_ERROR; + #if !defined(NO_CERTS) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) havePSK = ssl->options.havePSK; #endif @@ -11200,6 +11211,12 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl) return WOLFSSL_FATAL_ERROR; } + /* make sure this wolfSSL object has arrays and rng setup. Protects + * case where the WOLFSSL object is re-used via wolfSSL_clear() */ + if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) { + return ret; + } + #ifdef WOLFSSL_WOLFSENTRY_HOOKS if ((ssl->AcceptFilter != NULL) && ((ssl->options.acceptState == TLS13_ACCEPT_BEGIN) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 39744f996..ea9e06980 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5062,6 +5062,7 @@ struct WOLFSSL { WOLFSSL_LOCAL int SSL_CTX_RefCount(WOLFSSL_CTX* ctx, int incr); WOLFSSL_LOCAL int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup); WOLFSSL_LOCAL int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup); +WOLFSSL_LOCAL int ReinitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup); WOLFSSL_LOCAL void FreeSSL(WOLFSSL* ssl, void* heap); WOLFSSL_API void SSL_ResourceFree(WOLFSSL* ssl); /* Micrium uses */