Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes to better handle re-use of a WOLFSSL object via wolfSSL_clear #5468

Merged
merged 1 commit into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 75 additions & 60 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
#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;
}
#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));
XMEMSET(ssl->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));
#endif

#ifdef SINGLE_THREADED
Expand All @@ -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 */
Expand Down
49 changes: 44 additions & 5 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -12201,8 +12205,6 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,

(void)ret;

WOLFSSL_ENTER("SSL_connect()");

#ifdef HAVE_ERRNO_H
errno = 0;
#endif
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
12 changes: 6 additions & 6 deletions src/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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)) {
Expand All @@ -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) {
Expand Down
23 changes: 20 additions & 3 deletions src/tls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -10134,16 +10134,25 @@ 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;
WOLFSSL_ERROR(ssl->error);
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))
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions wolfssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down