From 0cedc4e1acc68c59a2f509c0da6a1786b6c85fd9 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz <49391366+julek-wolfssl@users.noreply.github.com> Date: Tue, 14 Feb 2023 18:38:28 +0100 Subject: [PATCH] stunnel 5.67 support (#6020) * stunnel 5.67 support - ssl->session->ticketAdd may be set when parsing a ticket before PSK - PSK binders should be calculated based on ciphersuite associated with PSK - Add option to prioritise PSK order instead of ciphersuite order - Update ctx->method->version when using Set_CTX_max_proto_version API - Simplify wolfSSL_parse_cipher_list - Keep copy of old list and then add in the previous ciphersuites depending on whether we are doing only TLS 1.3 ciphersuites or not - Specify CRL revocation in alert - Match reason string to match OpenSSL - Add support for external data callbacks for WOLFSSL_SESSION * Upref the session for stunnel instead of duplicating it * Add small stack option for wolfSSL_parse_cipher_list --- configure.ac | 2 + src/internal.c | 81 ++++-- src/pk.c | 2 + src/ssl.c | 484 +++++++++++++++++++++------------ src/tls13.c | 43 +-- src/x509.c | 4 +- tests/api.c | 458 ++++++++++++++++++++++++++++++- wolfssl/internal.h | 21 +- wolfssl/openssl/compat_types.h | 10 + wolfssl/openssl/crypto.h | 10 +- wolfssl/ssl.h | 14 +- wolfssl/test.h | 2 + 12 files changed, 887 insertions(+), 244 deletions(-) diff --git a/configure.ac b/configure.ac index 1f46cca8f..008efb4bc 100644 --- a/configure.ac +++ b/configure.ac @@ -7578,6 +7578,8 @@ then AM_CFLAGS="$AM_CFLAGS -DNO_SESSION_CACHE_REF" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TLS13_NO_PEEK_HANDSHAKE_DONE" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALT_CERT_CHAINS" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_PRIORITIZE_PSK" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CHECK_ALERT_ON_ERR" ENABLED_TRUSTED_PEER_CERT=yes fi diff --git a/src/internal.c b/src/internal.c index 0b68388a5..4c8a6c2f8 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6630,6 +6630,8 @@ int ReinitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) { int ret = 0; + WOLFSSL_ENTER("ReinitSSL"); + /* arrays */ if (!writeDup && ssl->arrays == NULL) { ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap, @@ -6686,6 +6688,8 @@ int ReinitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) } (void)ctx; + ssl->options.shutdownDone = 0; + return ret; } @@ -12314,7 +12318,7 @@ void DoCertFatalAlert(WOLFSSL* ssl, int ret) } else if (ret == ASN_NO_SIGNER_E) { alertWhy = unknown_ca; } -#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) +#ifdef OPENSSL_EXTRA else if (ret == CRL_CERT_REVOKED) { alertWhy = certificate_revoked; } @@ -22778,6 +22782,8 @@ static int SendAlert_ex(WOLFSSL* ssl, int severity, int type) WOLFSSL_ENTER("SendAlert"); + WOLFSSL_MSG_EX("SendAlert: %d %s", type, AlertTypeToString(type)); + #ifdef WOLFSSL_QUIC if (WOLFSSL_IS_QUIC(ssl)) { ret = !ssl->quic.method->send_alert(ssl, ssl->quic.enc_level_write, (uint8_t)type); @@ -23162,7 +23168,11 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) return "OCSP Cert revoked"; case CRL_CERT_REVOKED: +#ifdef OPENSSL_EXTRA + return "certificate revoked"; +#else return "CRL Cert revoked"; +#endif case CRL_MISSING: return "CRL missing, not loaded"; @@ -23428,7 +23438,7 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) return "unable to get local issuer certificate"; #endif case UNSUPPORTED_PROTO_VERSION: - #ifdef OPENSSL_ALL + #ifdef OPENSSL_EXTRA return "WRONG_SSL_VERSION"; #else return "bad/unsupported protocol version"; @@ -24354,8 +24364,15 @@ int GetCipherSuiteFromName(const char* name, byte* cipherSuite0, len = (unsigned long)XSTRLEN(name); for (i = 0; i < GetCipherNamesSize(); i++) { - if ((XSTRNCMP(name, cipher_names[i].name, len) == 0) && - (cipher_names[i].name[len] == 0)) { + int found = (XSTRNCMP(name, cipher_names[i].name, len) == 0) && + (cipher_names[i].name[len] == 0); +#ifndef NO_ERROR_STRINGS + if (!found) + found = (XSTRNCMP(name, cipher_names[i].name_iana, len) == 0) && + (cipher_names[i].name_iana[len] == 0); +#endif + + if (found) { *cipherSuite0 = cipher_names[i].cipherSuite0; *cipherSuite = cipher_names[i].cipherSuite; *flags = cipher_names[i].flags; @@ -24385,24 +24402,26 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) { int ret = 0; int idx = 0; - int haveRSAsig = 0; - int haveECDSAsig = 0; - int haveFalconSig = 0; - int haveDilithiumSig = 0; - int haveAnon = 0; + word16 haveRSAsig = 0; + word16 haveECDSAsig = 0; + word16 haveFalconSig = 0; + word16 haveDilithiumSig = 0; + word16 haveAnon = 0; + word16 haveRSA = 0; #ifdef OPENSSL_EXTRA - int haveRSA = 0; - int haveDH = 0; - int haveECC = 0; - int haveStaticRSA = 1; /* allowed by default if compiled in */ - int haveStaticECC = 0; - int haveNull = 1; /* allowed by default if compiled in */ + word16 haveDH = 0; + word16 haveECC = 0; + word16 haveStaticRSA = 1; /* allowed by default if compiled in */ + word16 haveStaticECC = 0; + word16 haveNull = 1; /* allowed by default if compiled in */ int callInitSuites = 0; - int havePSK = 0; + word16 havePSK = 0; #endif const int suiteSz = GetCipherNamesSize(); const char* next = list; + (void)haveRSA; + if (suites == NULL || list == NULL) { WOLFSSL_MSG("SetCipherList parameter error"); return 0; @@ -24410,15 +24429,18 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) if (next[0] == 0 || XSTRCMP(next, "ALL") == 0 || XSTRCMP(next, "DEFAULT") == 0 || XSTRCMP(next, "HIGH") == 0) { - /* Add all ciphersuites except anonymous and null ciphers */ + /* Add all ciphersuites except anonymous and null ciphers. Prefer RSA */ +#ifndef NO_RSA + haveRSA = 1; +#endif InitSuites(suites, ctx->method->version, #ifndef NO_CERTS ctx->privateKeySz, #else 0, #endif - 1, 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, ctx->method->side); + haveRSA, 1, 1, !haveRSA, 1, haveRSA, !haveRSA, 1, 1, 0, 0, + ctx->method->side); return 1; /* wolfSSL default */ } @@ -24428,7 +24450,7 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) int i; word32 length; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) - int allowing = 1; + word16 allowing = 1; #endif next = XSTRSTR(next, ":"); @@ -24738,12 +24760,12 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) suites->setSuites = 0; /* Force InitSuites */ suites->hashSigAlgoSz = 0; /* Force InitSuitesHashSigAlgo call * inside InitSuites */ - InitSuites(suites, ctx->method->version, keySz, (word16)haveRSA, - (word16)havePSK, (word16)haveDH, (word16)haveECDSAsig, - (word16)haveECC, (word16)haveStaticRSA, - (word16)haveStaticECC, (word16)haveFalconSig, - (word16)haveDilithiumSig, (word16)haveAnon, - (word16)haveNull, ctx->method->side); + InitSuites(suites, ctx->method->version, keySz, haveRSA, + havePSK, haveDH, haveECDSAsig, + haveECC, haveStaticRSA, + haveStaticECC, haveFalconSig, + haveDilithiumSig, haveAnon, + haveNull, ctx->method->side); /* Restore user ciphers ahead of defaults */ XMEMMOVE(suites->suites + idx, suites->suites, min(suites->suiteSz, WOLFSSL_MAX_SUITE_SZ-idx)); @@ -34440,7 +34462,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word16 inLen; WOLFSSL_START(WC_FUNC_TICKET_DO); - WOLFSSL_ENTER("DoClientTicket"); + WOLFSSL_ENTER("DoDecryptTicket"); if (len > SESSION_TICKET_LEN || len < (word32)(sizeof(InternalTicket) + WOLFSSL_TICKET_FIXED_SZ)) { @@ -34508,8 +34530,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_ENTER("DoClientTicket"); ret = DoDecryptTicket(ssl, input, len, &it); - if (ret != WOLFSSL_TICKET_RET_OK && ret != WOLFSSL_TICKET_RET_CREATE) + if (ret != WOLFSSL_TICKET_RET_OK && ret != WOLFSSL_TICKET_RET_CREATE) { + WOLFSSL_LEAVE("DoClientTicket", ret); return ret; + } #ifdef WOLFSSL_CHECK_MEM_ZERO /* Internal ticket successfully decrypted. */ wc_MemZero_Add("Do Client Ticket internal", it, sizeof(InternalTicket)); @@ -34594,6 +34618,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(ssl->session->masterSecret, it->msecret, SECRET_LEN); if (it->ticketNonceLen > MAX_TICKET_NONCE_STATIC_SZ) { WOLFSSL_MSG("Unsupported ticketNonce len in ticket"); + WOLFSSL_LEAVE("DoClientTicket", BAD_TICKET_ENCRYPT); return BAD_TICKET_ENCRYPT; } #if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \ diff --git a/src/pk.c b/src/pk.c index d25b0d4dc..d0aff7e67 100644 --- a/src/pk.c +++ b/src/pk.c @@ -7614,6 +7614,8 @@ static int wolfssl_dhparams_to_der(WOLFSSL_DH* dh, unsigned char** out, word32 derSz; DhKey* key; + (void)heap; + /* Set internal parameters based on external parameters. */ if ((dh->inSet == 0) && (SetDhInternal(dh) != 1)) { WOLFSSL_ERROR_MSG("Unable to set internal DH structure"); diff --git a/src/ssl.c b/src/ssl.c index 341d217a5..49b0312a2 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3236,7 +3236,7 @@ static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek) */ /* make sure bidirectional TLS shutdown completes */ - if (ssl->error == WOLFSSL_ERROR_SYSCALL) { + if (ssl->error == WOLFSSL_ERROR_SYSCALL || ssl->options.shutdownDone) { /* ask the underlying transport the connection is closed */ if (ssl->CBIORecv(ssl, (char*)data, 0, ssl->IOCB_ReadCtx) == WOLFSSL_CBIO_ERR_CONN_CLOSE) { @@ -4367,8 +4367,10 @@ int wolfSSL_shutdown(WOLFSSL* ssl) return WOLFSSL_FATAL_ERROR; } ssl->options.sentNotify = 1; /* don't send close_notify twice */ - if (ssl->options.closeNotify) + if (ssl->options.closeNotify) { ret = WOLFSSL_SUCCESS; + ssl->options.shutdownDone = 1; + } else { ret = WOLFSSL_SHUTDOWN_NOT_DONE; WOLFSSL_LEAVE("SSL_shutdown()", ret); @@ -4389,7 +4391,9 @@ int wolfSSL_shutdown(WOLFSSL* ssl) ret = ProcessReply(ssl); if (ret == ZERO_RETURN) { /* simulate OpenSSL behavior */ - ssl->error = WOLFSSL_ERROR_SYSCALL; + ssl->options.shutdownDone = 1; + /* Clear error */ + ssl->error = WOLFSSL_ERROR_NONE; ret = WOLFSSL_SUCCESS; } else if (ssl->error == WOLFSSL_ERROR_NONE) { ret = WOLFSSL_SHUTDOWN_NOT_DONE; @@ -4444,7 +4448,7 @@ int wolfSSL_get_error(WOLFSSL* ssl, int ret) return WOLFSSL_ERROR_WANT_READ; /* convert to OpenSSL type */ else if (ssl->error == WANT_WRITE) return WOLFSSL_ERROR_WANT_WRITE; /* convert to OpenSSL type */ - else if (ssl->error == ZERO_RETURN) + else if (ssl->error == ZERO_RETURN || ssl->options.shutdownDone) return WOLFSSL_ERROR_ZERO_RETURN; /* convert to OpenSSL type */ return ssl->error; } @@ -12361,121 +12365,6 @@ int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm) #ifdef OPENSSL_EXTRA -/* - * build enabled cipher list w/ TLS13 or w/o TLS13 suites - * @param ctx a pointer to WOLFSSL_CTX structure - * @param suites currently enabled suites - * @param onlytlsv13suites flag whether correcting w/ TLS13 suites - * or w/o TLS13 suties - * @param list suites list that user wants to update - * @return suites list on success, otherwise NULL - */ -static char* buildEnabledCipherList(WOLFSSL_CTX* ctx, Suites* suites, - int tls13Only, const char* list) -{ - word32 idx = 0; - word32 listsz = 0; - word32 len = 0; - word32 ianasz = 0; - const char* enabledcs = NULL; - char* locallist = NULL; - char* head = NULL; - byte cipherSuite0; - byte cipherSuite; - - /* sanity check */ - if (ctx == NULL || suites == NULL || list == NULL) - return NULL; - - if (!suites->setSuites) - return NULL; - - listsz = (word32)XSTRLEN(list); - - /* calculate necessary buffer length */ - for(idx = 0; idx < suites->suiteSz; idx++) { - - cipherSuite0 = suites->suites[idx]; - cipherSuite = suites->suites[++idx]; - - if (tls13Only && cipherSuite0 == TLS13_BYTE) { - enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite); - } - else if (!tls13Only && cipherSuite0 != TLS13_BYTE) { - enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite); - } - else - continue; - - if (XSTRCMP(enabledcs, "None") != 0) { - len += (word32)XSTRLEN(enabledcs) + 2; - } - } - - len += listsz + 2; - - /* build string */ - if (len > (listsz + 2)) { - locallist = (char*)XMALLOC(len, ctx->heap, - DYNAMIC_TYPE_TMP_BUFFER); - /* sanity check */ - if (!locallist) - return NULL; - - XMEMSET(locallist, 0, len); - - head = locallist; - - if (!tls13Only) - { - /* always tls13 suites in the head position */ - XSTRNCPY(locallist, list, len); - locallist += listsz; - *locallist++ = ':'; - *locallist = 0; - len -= listsz + 1; - } - - for(idx = 0; idx < suites->suiteSz; idx++) { - cipherSuite0 = suites->suites[idx]; - cipherSuite = suites->suites[++idx]; - - if (tls13Only && cipherSuite0 == TLS13_BYTE) { - enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite); - } - else if (!tls13Only && cipherSuite0 != TLS13_BYTE) { - enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite); - } - else - continue; - - ianasz = (int)XSTRLEN(enabledcs); - if (ianasz + 1 < len) { - XSTRNCPY(locallist, enabledcs, len); - locallist += ianasz; - - *locallist++ = ':'; - *locallist = 0; - len -= ianasz + 1; - } - else{ - XFREE(locallist, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); - return NULL; - } - } - - if (tls13Only) { - XSTRNCPY(locallist, list, len); - locallist += listsz; - *locallist = 0; - } - - return head; - } - else - return NULL; -} - /* * check if the list has TLS13 and pre-TLS13 suites * @param list cipher suite list that user want to set @@ -12508,17 +12397,22 @@ static int CheckcipherList(const char* list) XMEMCPY(name, current, length); name[length] = 0; + if (XSTRCMP(name, "ALL") == 0 || XSTRCMP(name, "DEFAULT") == 0 || + XSTRCMP(name, "HIGH") == 0) { + findTLSv13Suites = 1; + findbeforeSuites = 1; + break; + } + ret = wolfSSL_get_cipher_suite_from_name(name, &cipherSuite0, &cipherSuite1, &flags); if (ret == 0) { if (cipherSuite0 == TLS13_BYTE) { /* TLSv13 suite */ findTLSv13Suites = 1; - break; } else { findbeforeSuites = 1; - break; } } @@ -12567,10 +12461,17 @@ static int CheckcipherList(const char* list) static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, Suites* suites, const char* list) { - int ret = 0; - int listattribute = 0; - char* buildcipherList = NULL; - int tls13Only = 0; + int ret = 0; + int listattribute = 0; + int tls13Only = 0; +#ifndef WOLFSSL_SMALL_STACK + byte suitesCpy[WOLFSSL_MAX_SUITE_SZ]; +#else + byte* suitesCpy; +#endif + word16 suitesCpySz = 0; + word16 i = 0; + word16 j = 0; if (suites == NULL || list == NULL) { WOLFSSL_MSG("NULL argument"); @@ -12590,26 +12491,77 @@ static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, Suites* suites, /* list has only pre-TLSv13 suites. * Only update before TLSv13 suites. */ - tls13Only = 1; + tls13Only = 0; } else if (listattribute == 2) { /* list has only TLSv13 suites. Only update TLv13 suites * simulate set_ciphersuites() compatibility layer API */ - tls13Only = 0; + tls13Only = 1; + if (!IsAtLeastTLSv1_3(ctx->method->version)) { + /* Silently ignore TLS 1.3 ciphers if we don't support it. */ + return WOLFSSL_SUCCESS; + } } - buildcipherList = buildEnabledCipherList(ctx, ctx->suites, - tls13Only, list); + /* list contains ciphers either only for TLS 1.3 or <= TLS 1.2 */ - if (buildcipherList) { - ret = SetCipherList(ctx, suites, buildcipherList); - XFREE(buildcipherList, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); - } - else { - ret = SetCipherList(ctx, suites, list); +#ifdef WOLFSSL_SMALL_STACK + suitesCpy = (byte*)XMALLOC(suites->suiteSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (suitesCpy == NULL) + return WOLFSSL_FAILURE; +#endif + + XMEMCPY(suitesCpy, suites->suites, suites->suiteSz); + suitesCpySz = suites->suiteSz; + + ret = SetCipherList(ctx, suites, list); + if (ret != 1) { +#ifdef WOLFSSL_SMALL_STACK + XFREE(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return WOLFSSL_FAILURE; } + for (i = 0; i < suitesCpySz && + suites->suiteSz <= (WOLFSSL_MAX_SUITE_SZ - SUITE_LEN); i += 2) { + /* Check for duplicates */ + int duplicate = 0; + for (j = 0; j < suites->suiteSz; j += 2) { + if (suitesCpy[i] == suites->suites[j] && + suitesCpy[i+1] == suites->suites[j+1]) { + duplicate = 1; + break; + } + } + if (!duplicate) { + if (tls13Only) { + /* Updating TLS 1.3 ciphers */ + if (suitesCpy[i] != TLS13_BYTE) { + /* Only copy over <= TLS 1.2 ciphers */ + /* TLS 1.3 ciphers take precedence */ + suites->suites[suites->suiteSz++] = suitesCpy[i]; + suites->suites[suites->suiteSz++] = suitesCpy[i+1]; + } + } + else { + /* Updating <= TLS 1.2 ciphers */ + if (suitesCpy[i] == TLS13_BYTE) { + /* Only copy over TLS 1.3 ciphers */ + /* TLS 1.3 ciphers take precedence */ + XMEMMOVE(suites->suites + SUITE_LEN, suites->suites, + suites->suiteSz); + suites->suites[0] = suitesCpy[i]; + suites->suites[1] = suitesCpy[i+1]; + suites->suiteSz += 2; + } + } + } + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif return ret; } @@ -14269,6 +14221,15 @@ int wolfSSL_Cleanup(void) #endif #endif +#if defined(HAVE_EX_DATA) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ + defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || \ + defined(HAVE_LIGHTY)) || defined(HAVE_EX_DATA) || \ + defined(WOLFSSL_WPAS_SMALL) + crypto_ex_cb_free(crypto_ex_cb_ctx_session); + crypto_ex_cb_ctx_session = NULL; +#endif + return ret; } @@ -14640,7 +14601,7 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output) WOLFSSL_MSG("Session found in external cache"); error = wolfSSL_DupSession(sess, output, 0); #ifdef HAVE_EX_DATA - output->ownExData = 0; /* Session cache owns external data */ + output->ownExData = 1; #endif /* If copy not set then free immediately */ if (!copy) @@ -14914,11 +14875,24 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session) ret = WOLFSSL_FAILURE; } - - if (ret == WOLFSSL_SUCCESS && - wolfSSL_DupSession(session, ssl->session, 0) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Session duplicate failed"); - ret = WOLFSSL_FAILURE; + if (ret == WOLFSSL_SUCCESS) { +#ifdef HAVE_STUNNEL + /* stunnel depends on the ex_data not being duplicated. Copy OpenSSL + * behaviour for now. */ + if (session->type != WOLFSSL_SESSION_TYPE_CACHE) { + if (wolfSSL_SESSION_up_ref(session) == WOLFSSL_SUCCESS) { + wolfSSL_SESSION_free(ssl->session); + ssl->session = session; + } + else + ret = WOLFSSL_FAILURE; + } + else +#endif + { + ret = wolfSSL_DupSession(session, ssl->session, 0); + WOLFSSL_MSG("Session duplicate failed"); + } } /* Let's copy over the altSessionID for local cache purposes */ @@ -15181,6 +15155,8 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession, (void)useTicket; (void)clientCacheEntry; + WOLFSSL_ENTER("AddSessionToCache"); + if (idSz == 0) { WOLFSSL_MSG("AddSessionToCache idSz == 0"); return BAD_FUNC_ARG; @@ -15268,11 +15244,15 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession, cacheSession = &sessRow->Sessions[idx]; #ifdef HAVE_EX_DATA - if (cacheSession->rem_sess_cb && cacheSession->ownExData) { - cacheSession->rem_sess_cb(NULL, cacheSession); - /* Make sure not to call remove functions again */ - cacheSession->ownExData = 0; - cacheSession->rem_sess_cb = NULL; + if (cacheSession->ownExData) { + crypto_ex_cb_free_data(cacheSession, crypto_ex_cb_ctx_session, + &cacheSession->ex_data); + if (cacheSession->rem_sess_cb) { + cacheSession->rem_sess_cb(NULL, cacheSession); + /* Make sure not to call remove functions again */ + cacheSession->ownExData = 0; + cacheSession->rem_sess_cb = NULL; + } } #endif @@ -18152,6 +18132,7 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) */ static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver) { + int ret; WOLFSSL_ENTER("Set_CTX_max_proto_version"); if (!ctx || !ctx->method) { @@ -18190,7 +18171,68 @@ static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver) return WOLFSSL_FAILURE; } - return CheckSslMethodVersion(ctx->method->version.major, ctx->mask); + ret = CheckSslMethodVersion(ctx->method->version.major, ctx->mask); + if (ret == WOLFSSL_SUCCESS) { + /* Check the major */ + switch (ver) { + #ifndef NO_TLS + case SSL3_VERSION: + case TLS1_VERSION: + case TLS1_1_VERSION: + case TLS1_2_VERSION: + case TLS1_3_VERSION: + if (ctx->method->version.major != SSLv3_MAJOR) { + WOLFSSL_MSG("Mismatched protocol version"); + return WOLFSSL_FAILURE; + } + break; + #endif + #ifdef WOLFSSL_DTLS + case DTLS1_VERSION: + case DTLS1_2_VERSION: + if (ctx->method->version.major != DTLS_MAJOR) { + WOLFSSL_MSG("Mismatched protocol version"); + return WOLFSSL_FAILURE; + } + break; + #endif + } + /* Update the method */ + switch (ver) { + case SSL2_VERSION: + WOLFSSL_MSG("wolfSSL does not support SSLv2"); + return WOLFSSL_FAILURE; + #ifndef NO_TLS + case SSL3_VERSION: + ctx->method->version.minor = SSLv3_MINOR; + break; + case TLS1_VERSION: + ctx->method->version.minor = TLSv1_MINOR; + break; + case TLS1_1_VERSION: + ctx->method->version.minor = TLSv1_1_MINOR; + break; + case TLS1_2_VERSION: + ctx->method->version.minor = TLSv1_2_MINOR; + break; + case TLS1_3_VERSION: + ctx->method->version.minor = TLSv1_3_MINOR; + break; + #endif + #ifdef WOLFSSL_DTLS + case DTLS1_VERSION: + ctx->method->version.minor = DTLS_MINOR; + break; + case DTLS1_2_VERSION: + ctx->method->version.minor = DTLSv1_2_MINOR; + break; + #endif + default: + WOLFSSL_MSG("Unrecognized protocol version or not compiled in"); + return WOLFSSL_FAILURE; + } + } + return ret; } @@ -19787,6 +19829,9 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, } } + /* reset error */ + ssl->error = 0; + /* reset option bits */ ssl->options.isClosed = 0; ssl->options.connReset = 0; @@ -21057,7 +21102,7 @@ int wolfSSL_get_shutdown(const WOLFSSL* ssl) if (ssl) { #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) - if (ssl->options.handShakeState == NULL_STATE) { + if (ssl->options.shutdownDone) { /* The SSL object was possibly cleared with wolfSSL_clear after * a successful shutdown. Simulate a response for a full * bidirectional shutdown. */ @@ -21075,6 +21120,8 @@ int wolfSSL_get_shutdown(const WOLFSSL* ssl) } } + + WOLFSSL_LEAVE("wolfSSL_get_shutdown", isShutdown); return isShutdown; } @@ -21125,16 +21172,9 @@ WOLFSSL_SESSION* wolfSSL_NewSession(void* heap) ret->ticketNonce.data = ret->ticketNonce.dataStatic; #endif #endif -#ifdef HAVE_STUNNEL - /* stunnel has this funny mechanism of storing the "is_authenticated" - * session info in the session ex data. This is basically their - * default so let's just hard code it. */ - if (wolfSSL_SESSION_set_ex_data(ret, 0, (void *)(-1)) - != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Error setting up ex data for stunnel"); - XFREE(ret, NULL, DYNAMIC_TYPE_SESSION); - return NULL; - } +#ifdef HAVE_EX_DATA + crypto_ex_cb_setup_new_data(ret, crypto_ex_cb_ctx_session, + &ret->ex_data); #endif #ifdef HAVE_EX_DATA ret->ownExData = 1; @@ -21405,6 +21445,16 @@ static int wolfSSL_DupSessionEx(const WOLFSSL_SESSION* input, #endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/ #endif /* HAVE_SESSION_TICKET */ + +#ifdef HAVE_EX_DATA + if (input->type != WOLFSSL_SESSION_TYPE_CACHE && + output->type != WOLFSSL_SESSION_TYPE_CACHE) { + /* Not called with cache as that passes ownership of ex_data */ + ret = crypto_ex_cb_dup_data(&input->ex_data, &output->ex_data, + crypto_ex_cb_ctx_session); + } +#endif + return ret; } @@ -21480,6 +21530,12 @@ void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session) } #if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA) +#ifdef HAVE_EX_DATA + if (session->ownExData) { + crypto_ex_cb_free_data(session, crypto_ex_cb_ctx_session, + &session->ex_data); + } +#endif if (ctx != NULL && ctx->rem_sess_cb #ifdef HAVE_EX_DATA && session->ownExData /* This will be true if we are not using the @@ -31658,6 +31714,78 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || \ defined(HAVE_LIGHTY)) || defined(HAVE_EX_DATA) || \ defined(WOLFSSL_WPAS_SMALL) +CRYPTO_EX_cb_ctx* crypto_ex_cb_ctx_session = NULL; + +static int crypto_ex_cb_new(CRYPTO_EX_cb_ctx** dst, long ctx_l, void* ctx_ptr, + WOLFSSL_CRYPTO_EX_new* new_func, WOLFSSL_CRYPTO_EX_dup* dup_func, + WOLFSSL_CRYPTO_EX_free* free_func) +{ + CRYPTO_EX_cb_ctx* new_ctx = (CRYPTO_EX_cb_ctx*)XMALLOC( + sizeof(CRYPTO_EX_cb_ctx), NULL, DYNAMIC_TYPE_OPENSSL); + if (new_ctx == NULL) + return -1; + new_ctx->ctx_l = ctx_l; + new_ctx->ctx_ptr = ctx_ptr; + new_ctx->new_func = new_func; + new_ctx->free_func = free_func; + new_ctx->dup_func = dup_func; + new_ctx->next = NULL; + /* Push to end of list */ + while (*dst != NULL) + dst = &(*dst)->next; + *dst = new_ctx; + return 0; +} + +void crypto_ex_cb_free(CRYPTO_EX_cb_ctx* cb_ctx) +{ + while (cb_ctx != NULL) { + CRYPTO_EX_cb_ctx* next = cb_ctx->next; + XFREE(cb_ctx, NULL, DYNAMIC_TYPE_OPENSSL); + cb_ctx = next; + } +} + +void crypto_ex_cb_setup_new_data(void *new_obj, CRYPTO_EX_cb_ctx* cb_ctx, + WOLFSSL_CRYPTO_EX_DATA* ex_data) +{ + int idx = 0; + for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) { + if (cb_ctx->new_func != NULL) + cb_ctx->new_func(new_obj, NULL, ex_data, idx, cb_ctx->ctx_l, + cb_ctx->ctx_ptr); + } +} + +int crypto_ex_cb_dup_data(const WOLFSSL_CRYPTO_EX_DATA *in, + WOLFSSL_CRYPTO_EX_DATA *out, CRYPTO_EX_cb_ctx* cb_ctx) +{ + int idx = 0; + for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) { + if (cb_ctx->dup_func != NULL) { + void* ptr = wolfSSL_CRYPTO_get_ex_data(in, idx); + if (!cb_ctx->dup_func(out, in, + &ptr, idx, + cb_ctx->ctx_l, cb_ctx->ctx_ptr)) { + return WOLFSSL_FAILURE; + } + wolfSSL_CRYPTO_set_ex_data(out, idx, ptr); + } + } + return WOLFSSL_SUCCESS; +} + +void crypto_ex_cb_free_data(void *obj, CRYPTO_EX_cb_ctx* cb_ctx, + WOLFSSL_CRYPTO_EX_DATA* ex_data) +{ + int idx = 0; + for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) { + if (cb_ctx->free_func != NULL) + cb_ctx->free_func(obj, NULL, ex_data, idx, cb_ctx->ctx_l, + cb_ctx->ctx_ptr); + } +} + /** * get_ex_new_index is a helper function for the following * xx_get_ex_new_index functions: @@ -31668,7 +31796,9 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) * Returns an index number greater or equal to zero on success, * -1 on failure. */ -int wolfssl_get_ex_new_index(int class_index) +int wolfssl_get_ex_new_index(int class_index, long ctx_l, void* ctx_ptr, + WOLFSSL_CRYPTO_EX_new* new_func, WOLFSSL_CRYPTO_EX_dup* dup_func, + WOLFSSL_CRYPTO_EX_free* free_func) { /* index counter for each class index*/ static int ctx_idx = 0; @@ -31680,15 +31810,24 @@ int wolfssl_get_ex_new_index(int class_index) switch(class_index) { case WOLF_CRYPTO_EX_INDEX_SSL: + WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func, + dup_func, free_func); idx = ssl_idx++; break; case WOLF_CRYPTO_EX_INDEX_SSL_CTX: + WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func, + dup_func, free_func); idx = ctx_idx++; break; case WOLF_CRYPTO_EX_INDEX_X509: + WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func, + dup_func, free_func); idx = x509_idx++; break; case WOLF_CRYPTO_EX_INDEX_SSL_SESSION: + if (crypto_ex_cb_new(&crypto_ex_cb_ctx_session, ctx_l, ctx_ptr, + new_func, dup_func, free_func) != 0) + return -1; idx = ssl_session_idx++; break; @@ -31708,6 +31847,8 @@ int wolfssl_get_ex_new_index(int class_index) default: break; } + if (idx >= MAX_EX_DATA) + return -1; return idx; } #endif /* HAVE_EX_DATA || WOLFSSL_WPAS_SMALL */ @@ -31733,9 +31874,8 @@ int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b, WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index"); - WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(idx, arg, a, b, c); - - return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX); + return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX, idx, arg, a, + b, c); } /* Return the index that can be used for the WOLFSSL structure to store @@ -31748,9 +31888,8 @@ int wolfSSL_get_ex_new_index(long argValue, void* arg, { WOLFSSL_ENTER("wolfSSL_get_ex_new_index"); - WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(argValue, arg, cb1, cb2, cb3); - - return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL); + return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL, argValue, arg, + cb1, cb2, cb3); } @@ -32501,12 +32640,13 @@ void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx) defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \ defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))) #ifdef HAVE_EX_DATA -int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1, - void* cb2, CRYPTO_free_func* cb3) +int wolfSSL_SESSION_get_ex_new_index(long ctx_l,void* ctx_ptr, + WOLFSSL_CRYPTO_EX_new* new_func, WOLFSSL_CRYPTO_EX_dup* dup_func, + WOLFSSL_CRYPTO_EX_free* free_func) { WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_new_index"); - WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(idx, data, cb1, cb2, cb3); - return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_SESSION); + return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_SESSION, ctx_l, + ctx_ptr, new_func, dup_func, free_func); } #endif @@ -39332,10 +39472,8 @@ int wolfSSL_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, { WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_new_index"); - WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(argl, argp, new_func, dup_func, - free_func); - - return wolfssl_get_ex_new_index(class_index); + return wolfssl_get_ex_new_index(class_index, argl, argp, new_func, + dup_func, free_func); } #endif /* HAVE_EX_DATA */ diff --git a/src/tls13.c b/src/tls13.c index 23dcde933..318f8a11b 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -69,6 +69,8 @@ * When only one PSK ID is used and only one call to the PSK callback can * be made per connect. * You cannot use wc_psk_client_cs_callback type callback on client. + * WOLFSSL_PRIORITIZE_PSK + * During a handshake, prioritize PSK order instead of ciphersuite order. * WOLFSSL_CHECK_ALERT_ON_ERR * Check for alerts during the handshake in the event of an error. * WOLFSSL_NO_CLIENT_CERT_ERROR @@ -3245,7 +3247,7 @@ exit_buildmsg: * suite Cipher suite to look for. * returns 1 when suite is found in SSL/TLS object's list and 0 otherwise. */ -static int FindSuiteSSL(WOLFSSL* ssl, byte* suite) +static int FindSuiteSSL(const WOLFSSL* ssl, byte* suite) { word16 i; const Suites* suites = WOLFSSL_SUITES(ssl); @@ -3544,6 +3546,9 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello) #ifdef HAVE_SESSION_TICKET if (psk->resumption) { if (clientHello) { + suite[0] = psk->cipherSuite0; + suite[1] = psk->cipherSuite; + /* Ensure cipher suite is supported or changed suite to one with * the same MAC algorithm. */ if (!FindSuiteSSL(ssl, suite)) { @@ -3551,6 +3556,9 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello) return PSK_KEY_ERROR; } + ssl->options.cipherSuite0 = suite[0]; + ssl->options.cipherSuite = suite[1]; + /* Setting mac for binder and keys for deriving EarlyData. */ ret = SetCipherSpecs(ssl); if (ret != 0) @@ -5481,6 +5489,8 @@ static int FindPsk(WOLFSSL* ssl, PreSharedKey* psk, const byte* suite, int* err) byte cipherSuite = WOLFSSL_DEF_PSK_CIPHER; Arrays* sa = ssl->arrays; + (void)suite; + if (ssl->options.server_psk_tls13_cb != NULL) { sa->psk_keySz = ssl->options.server_psk_tls13_cb(ssl, sa->client_identity, sa->psk_key, MAX_PSK_KEY_LEN, &cipherName); @@ -5499,11 +5509,12 @@ static int FindPsk(WOLFSSL* ssl, PreSharedKey* psk, const byte* suite, int* err) } if (found) { if (sa->psk_keySz > MAX_PSK_KEY_LEN) { + WOLFSSL_MSG("Key len too long in FindPsk()"); ret = PSK_KEY_ERROR; WOLFSSL_ERROR_VERBOSE(ret); } if (ret == 0) { - #ifndef WOLFSSL_PSK_ONE_ID + #if !defined(WOLFSSL_PSK_ONE_ID) && !defined(WOLFSSL_PRIORITIZE_PSK) /* Check whether PSK ciphersuite is in SSL. */ found = (suite[0] == cipherSuite0) && (suite[1] == cipherSuite); #else @@ -5525,7 +5536,7 @@ static int FindPsk(WOLFSSL* ssl, PreSharedKey* psk, const byte* suite, int* err) ssl->options.verifyPeer = 0; /* PSK age is always zero. */ - if (psk->ticketAge != ssl->session->ticketAdd) { + if (psk->ticketAge != 0) { ret = PSK_KEY_ERROR; WOLFSSL_ERROR_VERBOSE(ret); } @@ -5581,8 +5592,8 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz, } /* Look through all client's pre-shared keys for a match. */ - current = (PreSharedKey*)ext->data; - while (current != NULL) { + for (current = (PreSharedKey*)ext->data; current != NULL; + current = current->next) { #ifndef NO_PSK if (current->identityLen > MAX_PSK_ID_LEN) { return BUFFER_ERROR; @@ -5614,7 +5625,6 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz, diff -= ssl->session->ticketSeen; if (diff > (sword64)ssl->timeout * 1000 || diff > (sword64)TLS13_MAX_TICKET_AGE * 1000) { - current = current->next; continue; } #else @@ -5628,7 +5638,6 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz, diff -= ssl->session->ticketSeen; if (diff > (sword64)ssl->timeout * 1000 || diff > (sword64)TLS13_MAX_TICKET_AGE * 1000) { - current = current->next; continue; } #endif @@ -5638,30 +5647,24 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz, /* Check session and ticket age timeout. * Allow +/- 1000 milliseconds on ticket age. */ - if (diff < -1000 || diff - MAX_TICKET_AGE_DIFF * 1000 > 1000) { - current = current->next; + if (diff < -1000 || diff - MAX_TICKET_AGE_DIFF * 1000 > 1000) continue; - } - #ifndef WOLFSSL_PSK_ONE_ID + #if !defined(WOLFSSL_PSK_ONE_ID) && !defined(WOLFSSL_PRIORITIZE_PSK) /* Check whether resumption is possible based on suites in SSL and * ciphersuite in ticket. */ if ((suite[0] != ssl->session->cipherSuite0) || - (suite[1] != ssl->session->cipherSuite)) { - current = current->next; + (suite[1] != ssl->session->cipherSuite)) continue; - } #else { byte s[2] = { ssl->session->cipherSuite0, ssl->session->cipherSuite, }; - if (!FindSuiteSSL(ssl, s)) { - current = current->next; + if (!FindSuiteSSL(ssl, s)) continue; - } } #endif @@ -5719,7 +5722,6 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz, else #endif { - current = current->next; continue; } @@ -5838,14 +5840,17 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, ret = DoPreSharedKeys(ssl, input, helloSz - bindersLen, suites->suites + i, usingPSK, &first); if (ret != 0) { + WOLFSSL_MSG_EX("DoPreSharedKeys: %d", ret); return ret; } } #else ret = DoPreSharedKeys(ssl, input, helloSz - bindersLen, suite, usingPSK, &first); - if (ret != 0) + if (ret != 0) { + WOLFSSL_MSG_EX("DoPreSharedKeys: %d", ret); return ret; + } #endif if (*usingPSK) { diff --git a/src/x509.c b/src/x509.c index ee166fa3e..44a9a5427 100644 --- a/src/x509.c +++ b/src/x509.c @@ -12372,9 +12372,7 @@ int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a, void *b, void *c) { WOLFSSL_ENTER("wolfSSL_X509_get_ex_new_index"); - WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(idx, arg, a, b, c); - - return wolfssl_get_ex_new_index(CRYPTO_EX_INDEX_X509); + return wolfssl_get_ex_new_index(CRYPTO_EX_INDEX_X509, idx, arg, a, b, c); } #endif diff --git a/tests/api.c b/tests/api.c index 40ce66ea7..edf3ef01c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -461,6 +461,12 @@ static int testDevId = WOLFSSL_CAAM_DEVID; static int testDevId = INVALID_DEVID; #endif +#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ + !defined(NO_RSA) && !defined(SINGLE_THREADED) && \ + !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) +#define HAVE_IO_TESTS_DEPENDENCIES +#endif + /*----------------------------------------------------------------------------* | Setup *----------------------------------------------------------------------------*/ @@ -3582,6 +3588,51 @@ static int test_wolfSSL_set_minmax_proto_version(void) return res; } +#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12) && \ + defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES) +static void test_wolfSSL_CTX_set_max_proto_version_on_result(WOLFSSL* ssl) +{ + AssertStrEQ(wolfSSL_get_version(ssl), "TLSv1.2"); +} + +static void test_wolfSSL_CTX_set_max_proto_version_ctx_ready(WOLFSSL_CTX* ctx) +{ + /* Set TLS 1.2 */ + AssertIntEQ(wolfSSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION), + WOLFSSL_SUCCESS); +} + +/* Test using wolfSSL_CTX_set_max_proto_version to limit the version below + * what was set at ctx creation. */ +static int test_wolfSSL_CTX_set_max_proto_version(void) +{ + callback_functions client_cbs, server_cbs; + + XMEMSET(&client_cbs, 0, sizeof(client_cbs)); + XMEMSET(&server_cbs, 0, sizeof(server_cbs)); + + client_cbs.method = wolfTLS_client_method; + server_cbs.method = wolfTLS_server_method; + + server_cbs.ctx_ready = test_wolfSSL_CTX_set_max_proto_version_ctx_ready; + + client_cbs.on_result = test_wolfSSL_CTX_set_max_proto_version_on_result; + server_cbs.on_result = test_wolfSSL_CTX_set_max_proto_version_on_result; + + test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs); + + AssertIntEQ(client_cbs.return_code, TEST_SUCCESS); + AssertIntEQ(server_cbs.return_code, TEST_SUCCESS); + + return TEST_RES_CHECK(1); +} +#else +static int test_wolfSSL_CTX_set_max_proto_version(void) +{ + return TEST_SKIPPED; +} +#endif + /*----------------------------------------------------------------------------* | SSL *----------------------------------------------------------------------------*/ @@ -4886,11 +4937,6 @@ static int test_wolfSSL_EVP_CIPHER_CTX(void) /*----------------------------------------------------------------------------* | IO *----------------------------------------------------------------------------*/ -#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ - !defined(NO_RSA) && !defined(SINGLE_THREADED) && \ - !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) -#define HAVE_IO_TESTS_DEPENDENCIES -#endif /* helper functions */ #ifdef HAVE_IO_TESTS_DEPENDENCIES @@ -5089,6 +5135,8 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) int doUdp = 0; SOCKADDR_IN_T cliAddr; socklen_t cliLen; + const char* certFile = svrCertFile; + const char* keyFile = svrKeyFile; #ifdef WOLFSSL_HAVE_TLS_UNIQUE size_t msg_len = 0; @@ -5178,22 +5226,28 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) /*err_sys("can't load ca file, Please run from wolfSSL home dir");*/ goto done; } + + if (cbf != NULL && cbf->certPemFile != NULL) + certFile = cbf->certPemFile; #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) - if (!sharedCtx && wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, + if (!sharedCtx && wolfSSL_CTX_use_certificate_file(ctx, certFile, WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { #else - if (wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, + if (wolfSSL_CTX_use_certificate_file(ctx, certFile, WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { #endif /*err_sys("can't load server cert chain file, " "Please run from wolfSSL home dir");*/ goto done; } + + if (cbf != NULL && cbf->keyPemFile != NULL) + keyFile = cbf->keyPemFile; #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) - if (!sharedCtx && wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, + if (!sharedCtx && wolfSSL_CTX_use_PrivateKey_file(ctx, keyFile, WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { #else - if (wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, + if (wolfSSL_CTX_use_PrivateKey_file(ctx, keyFile, WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { #endif /*err_sys("can't load server key file, " @@ -5201,6 +5255,16 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) goto done; } +#ifdef HAVE_CRL + if (cbf != NULL && cbf->crlPemFile != NULL) { + if (wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL) != WOLFSSL_SUCCESS) + goto done; + if (wolfSSL_CTX_LoadCRLFile(ctx, cbf->crlPemFile, WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) + goto done; + } +#endif + /* call ctx setup callback */ if (cbf != NULL && cbf->ctx_ready != NULL) { cbf->ctx_ready(ctx); @@ -5336,6 +5400,8 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) done: if (cbf != NULL) cbf->last_err = err; + if (cbf != NULL && cbf->on_cleanup != NULL) + cbf->on_cleanup(ssl); wolfSSL_shutdown(ssl); wolfSSL_free(ssl); @@ -5651,6 +5717,16 @@ static int test_client_nofail(void* args, cbType cb) goto done; } +#ifdef HAVE_CRL + if (cbf != NULL && cbf->crlPemFile != NULL) { + if (wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL) != WOLFSSL_SUCCESS) + goto done; + if (wolfSSL_CTX_LoadCRLFile(ctx, cbf->crlPemFile, WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) + goto done; + } +#endif + /* call ctx setup callback */ if (cbf != NULL && cbf->ctx_ready != NULL) { cbf->ctx_ready(ctx); @@ -5770,6 +5846,8 @@ static int test_client_nofail(void* args, cbType cb) done: if (cbf != NULL) cbf->last_err = err; + if (cbf != NULL && cbf->on_cleanup != NULL) + cbf->on_cleanup(ssl); wolfSSL_free(ssl); if (!sharedCtx) @@ -6288,6 +6366,14 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args) wolfSSL_CTX_use_PrivateKey_file(ctx, callbacks->keyPemFile, WOLFSSL_FILETYPE_PEM)); +#ifdef HAVE_CRL + if (callbacks->crlPemFile != NULL) { + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_LoadCRLFile(ctx, callbacks->crlPemFile, + WOLFSSL_FILETYPE_PEM)); + } +#endif + if (callbacks->ctx_ready) callbacks->ctx_ready(ctx); @@ -6504,6 +6590,14 @@ static void run_wolfssl_client(void* args) WOLFSSL_FILETYPE_PEM)); } +#ifdef HAVE_CRL + if (callbacks->crlPemFile != NULL) { + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_LoadCRLFile(ctx, callbacks->crlPemFile, + WOLFSSL_FILETYPE_PEM)); + } +#endif + if (callbacks->ctx_ready) callbacks->ctx_ready(ctx); @@ -59535,6 +59629,82 @@ static int test_wolfSSL_CRYPTO_get_ex_new_index(void) return res; } +#if defined(HAVE_EX_DATA) && \ + (defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \ + (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \ + defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \ + defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))) + +#define SESSION_NEW_IDX_LONG 0xDEADBEEF +#define SESSION_NEW_IDX_VAL ((void*)0xAEADAEAD) +#define SESSION_DUP_IDX_VAL ((void*)0xDEDEDEDE) +#define SESSION_NEW_IDX_PTR "Testing" + +static void test_wolfSSL_SESSION_get_ex_new_index_new_cb(void* p, void* ptr, + CRYPTO_EX_DATA* a, int idx, long argValue, void* arg) +{ + AssertNotNull(p); + AssertNull(ptr); + AssertIntEQ(CRYPTO_set_ex_data(a, idx, SESSION_NEW_IDX_VAL), SSL_SUCCESS); + AssertIntEQ(argValue, SESSION_NEW_IDX_LONG); + AssertStrEQ(arg, SESSION_NEW_IDX_PTR); +} + +static int test_wolfSSL_SESSION_get_ex_new_index_dup_cb(CRYPTO_EX_DATA* out, + const CRYPTO_EX_DATA* in, void* inPtr, int idx, long argV, + void* arg) +{ + AssertNotNull(out); + AssertNotNull(in); + AssertPtrEq(*(void**)inPtr, SESSION_NEW_IDX_VAL); + AssertPtrEq(CRYPTO_get_ex_data(in, idx), SESSION_NEW_IDX_VAL); + AssertPtrEq(CRYPTO_get_ex_data(out, idx), SESSION_NEW_IDX_VAL); + AssertIntEQ(argV, SESSION_NEW_IDX_LONG); + AssertStrEQ(arg, SESSION_NEW_IDX_PTR); + *(void**)inPtr = SESSION_DUP_IDX_VAL; + return SSL_SUCCESS; +} + +static int test_wolfSSL_SESSION_get_ex_new_index_free_cb_called = 0; +static void test_wolfSSL_SESSION_get_ex_new_index_free_cb(void* p, void* ptr, + CRYPTO_EX_DATA* a, int idx, long argValue, void* arg) +{ + AssertNotNull(p); + AssertNull(ptr); + AssertPtrNE(CRYPTO_get_ex_data(a, idx), 0); + AssertIntEQ(argValue, SESSION_NEW_IDX_LONG); + AssertStrEQ(arg, SESSION_NEW_IDX_PTR); + test_wolfSSL_SESSION_get_ex_new_index_free_cb_called++; +} + +static int test_wolfSSL_SESSION_get_ex_new_index(void) +{ + int idx = SSL_SESSION_get_ex_new_index(SESSION_NEW_IDX_LONG, + (void*)SESSION_NEW_IDX_PTR, + test_wolfSSL_SESSION_get_ex_new_index_new_cb, + test_wolfSSL_SESSION_get_ex_new_index_dup_cb, + test_wolfSSL_SESSION_get_ex_new_index_free_cb); + SSL_SESSION* s = SSL_SESSION_new(); + SSL_SESSION* d = NULL; + + AssertNotNull(s); + AssertPtrEq(SSL_SESSION_get_ex_data(s, idx), SESSION_NEW_IDX_VAL); + AssertNotNull(d = SSL_SESSION_dup(s)); + AssertPtrEq(SSL_SESSION_get_ex_data(d, idx), SESSION_DUP_IDX_VAL); + SSL_SESSION_free(s); + AssertIntEQ(test_wolfSSL_SESSION_get_ex_new_index_free_cb_called, 1); + SSL_SESSION_free(d); + AssertIntEQ(test_wolfSSL_SESSION_get_ex_new_index_free_cb_called, 2); + + return TEST_RES_CHECK(1); +} +#else +static int test_wolfSSL_SESSION_get_ex_new_index(void) +{ + return TEST_SKIPPED; +} +#endif + static int test_wolfSSL_set_psk_use_session_callback(void) { int res = TEST_SKIPPED; @@ -61389,6 +61559,270 @@ static int test_ticket_ret_create(void) } #endif +#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && defined(HAVE_SESSION_TICKET) \ + && defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \ + defined(HAVE_AESGCM) && !defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \ + defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) +static void test_ticket_and_psk_mixing_on_result(WOLFSSL* ssl) +{ + int ret; + WOLFSSL_SESSION* session = NULL; + AssertIntEQ(wolfSSL_get_current_cipher_suite(ssl), 0x1301); + if (!wolfSSL_is_server(ssl)) { + session = wolfSSL_SESSION_dup(wolfSSL_get_session(ssl)); + AssertNotNull(session); + } + do { + ret = wolfSSL_shutdown(ssl); + } while (ret == WOLFSSL_SHUTDOWN_NOT_DONE); + AssertIntEQ(wolfSSL_clear(ssl), WOLFSSL_SUCCESS); + wolfSSL_set_psk_callback_ctx(ssl, (void*)"TLS13-AES256-GCM-SHA384"); +#ifndef OPENSSL_COMPATIBLE_DEFAULTS + /* OpenSSL considers PSK to be verified. We error out with NO_PEER_CERT. */ + wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_NONE, NULL); +#endif + + if (!wolfSSL_is_server(ssl)) { + /* client */ + AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:" + "TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS); + wolfSSL_set_session(ssl, session); + wolfSSL_SESSION_free(session); + wolfSSL_set_psk_client_tls13_callback(ssl, my_psk_client_tls13_cb); + AssertIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS); + } + else { + /* server */ + /* Different ciphersuite so that the ticket will be invalidated based on + * the ciphersuite */ + AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384"), + WOLFSSL_SUCCESS); + wolfSSL_set_psk_server_tls13_callback(ssl, my_psk_server_tls13_cb); + AssertIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS); + } +} + +static void test_ticket_and_psk_mixing_ssl_ready(WOLFSSL* ssl) +{ + AssertIntEQ(wolfSSL_UseSessionTicket(ssl), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES128-GCM-SHA256"), + WOLFSSL_SUCCESS); +} + +static int test_ticket_and_psk_mixing(void) +{ + /* Test mixing tickets and regular PSK */ + callback_functions client_cbs, server_cbs; + + XMEMSET(&client_cbs, 0, sizeof(client_cbs)); + XMEMSET(&server_cbs, 0, sizeof(server_cbs)); + + client_cbs.method = wolfTLSv1_3_client_method; + server_cbs.method = wolfTLSv1_3_server_method; + + client_cbs.ssl_ready = test_ticket_and_psk_mixing_ssl_ready; + + client_cbs.on_result = test_ticket_and_psk_mixing_on_result; + server_cbs.on_result = test_ticket_and_psk_mixing_on_result; + + test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs); + + AssertIntEQ(client_cbs.return_code, TEST_SUCCESS); + AssertIntEQ(server_cbs.return_code, TEST_SUCCESS); + + return TEST_RES_CHECK(1); +} +#else +static int test_ticket_and_psk_mixing(void) +{ + return TEST_SKIPPED; +} +#endif + +#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && defined(HAVE_SESSION_TICKET) \ + && defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \ + defined(HAVE_AESGCM) && !defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \ + defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) +static int test_prioritize_psk_cb_called = FALSE; + +static unsigned int test_prioritize_psk_cb(WOLFSSL* ssl, + const char* identity, unsigned char* key, unsigned int key_max_len, + const char** ciphersuite) +{ + test_prioritize_psk_cb_called = TRUE; + return my_psk_server_tls13_cb(ssl, identity, key, key_max_len, ciphersuite); +} + +static void test_prioritize_psk_on_result(WOLFSSL* ssl) +{ + int ret; + WOLFSSL_SESSION* session = NULL; + AssertIntEQ(wolfSSL_get_current_cipher_suite(ssl), 0x1301); + if (!wolfSSL_is_server(ssl)) { + session = wolfSSL_SESSION_dup(wolfSSL_get_session(ssl)); + AssertNotNull(session); + } + do { + ret = wolfSSL_shutdown(ssl); + } while (ret == WOLFSSL_SHUTDOWN_NOT_DONE); + AssertIntEQ(wolfSSL_clear(ssl), WOLFSSL_SUCCESS); + wolfSSL_set_psk_callback_ctx(ssl, (void*)"TLS13-AES256-GCM-SHA384"); + /* Previous connection was made with TLS13-AES128-GCM-SHA256. Order is + * important. */ + AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:" + "TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS); +#ifndef OPENSSL_COMPATIBLE_DEFAULTS + /* OpenSSL considers PSK to be verified. We error out with NO_PEER_CERT. */ + wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_NONE, NULL); +#endif + + if (!wolfSSL_is_server(ssl)) { + /* client */ + wolfSSL_set_psk_client_tls13_callback(ssl, my_psk_client_tls13_cb); + wolfSSL_set_session(ssl, session); + wolfSSL_SESSION_free(session); + AssertIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS); + } + else { + /* server */ + wolfSSL_set_psk_server_tls13_callback(ssl, test_prioritize_psk_cb); + AssertIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS); +#ifdef WOLFSSL_PRIORITIZE_PSK + /* The ticket should be first tried with all ciphersuites and chosen */ + AssertFalse(test_prioritize_psk_cb_called); +#else + /* Ciphersuites should be tried with each PSK. This triggers the PSK + * callback that sets this var. */ + AssertTrue(test_prioritize_psk_cb_called); +#endif + } +} + +static void test_prioritize_psk_ssl_ready(WOLFSSL* ssl) +{ + if (!wolfSSL_is_server(ssl)) + AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES128-GCM-SHA256"), + WOLFSSL_SUCCESS); + else + AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:" + "TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS); +} + +static int test_prioritize_psk(void) +{ + /* We always send the ticket first. With WOLFSSL_PRIORITIZE_PSK the order + * of the PSK's will be followed instead of the ciphersuite. */ + callback_functions client_cbs, server_cbs; + + XMEMSET(&client_cbs, 0, sizeof(client_cbs)); + XMEMSET(&server_cbs, 0, sizeof(server_cbs)); + + client_cbs.method = wolfTLSv1_3_client_method; + server_cbs.method = wolfTLSv1_3_server_method; + + client_cbs.ssl_ready = test_prioritize_psk_ssl_ready; + server_cbs.ssl_ready = test_prioritize_psk_ssl_ready; + + client_cbs.on_result = test_prioritize_psk_on_result; + server_cbs.on_result = test_prioritize_psk_on_result; + + test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs); + + AssertIntEQ(client_cbs.return_code, TEST_SUCCESS); + AssertIntEQ(server_cbs.return_code, TEST_SUCCESS); + + return TEST_RES_CHECK(1); +} +#else +static int test_prioritize_psk(void) +{ + return TEST_SKIPPED; +} +#endif + +#if defined(WOLFSSL_TLS13) && defined(OPENSSL_EXTRA) && \ + defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_AESGCM) && \ + !defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \ + !defined(WOLFSSL_NO_TLS12) +static void test_wolfSSL_CTX_set_ciphersuites_ctx_ready_server(WOLFSSL_CTX* ctx) +{ + AssertTrue(SSL_CTX_set_cipher_list(ctx, "DEFAULT")); + /* Set TLS 1.3 specific suite */ + AssertTrue(SSL_CTX_set_ciphersuites(ctx, "TLS13-AES128-GCM-SHA256")); +} + +static int test_wolfSSL_CTX_set_ciphersuites(void) +{ + /* Test using SSL_CTX_set_cipher_list and SSL_CTX_set_ciphersuites and then + * do a 1.2 connection. */ + callback_functions client_cbs, server_cbs; + + XMEMSET(&client_cbs, 0, sizeof(client_cbs)); + XMEMSET(&server_cbs, 0, sizeof(server_cbs)); + + client_cbs.method = wolfTLSv1_2_client_method; + server_cbs.method = wolfTLS_server_method; /* Allow downgrade */ + + server_cbs.ctx_ready = test_wolfSSL_CTX_set_ciphersuites_ctx_ready_server; + + test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs); + + AssertIntEQ(client_cbs.return_code, TEST_SUCCESS); + AssertIntEQ(server_cbs.return_code, TEST_SUCCESS); + + return TEST_RES_CHECK(1); +} +#else +static int test_wolfSSL_CTX_set_ciphersuites(void) +{ + return TEST_SKIPPED; +} +#endif + +#if defined(HAVE_CRL) && defined(WOLFSSL_CHECK_ALERT_ON_ERR) && \ + defined(HAVE_IO_TESTS_DEPENDENCIES) +static void test_wolfSSL_CRL_CERT_REVOKED_alert_ctx_ready(WOLFSSL_CTX* ctx) +{ + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL); +} + +static void test_wolfSSL_CRL_CERT_REVOKED_alert_on_cleanup(WOLFSSL* ssl) +{ + WOLFSSL_ALERT_HISTORY h; + AssertIntEQ(wolfSSL_get_alert_history(ssl, &h), WOLFSSL_SUCCESS); + AssertIntEQ(h.last_rx.level, alert_fatal); + AssertIntEQ(h.last_rx.code, certificate_revoked); +} + +static int test_wolfSSL_CRL_CERT_REVOKED_alert(void) +{ + callback_functions client_cbs, server_cbs; + + XMEMSET(&client_cbs, 0, sizeof(client_cbs)); + XMEMSET(&server_cbs, 0, sizeof(server_cbs)); + + server_cbs.certPemFile = "./certs/server-revoked-cert.pem"; + server_cbs.keyPemFile = "./certs/server-revoked-key.pem"; + client_cbs.crlPemFile = "./certs/crl/crl.revoked"; + + client_cbs.ctx_ready = test_wolfSSL_CRL_CERT_REVOKED_alert_ctx_ready; + server_cbs.on_cleanup = test_wolfSSL_CRL_CERT_REVOKED_alert_on_cleanup; + + test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs); + + AssertIntEQ(client_cbs.return_code, TEST_FAIL); + AssertIntEQ(server_cbs.return_code, TEST_FAIL); + + return TEST_RES_CHECK(1); + +} +#else +static int test_wolfSSL_CRL_CERT_REVOKED_alert(void) +{ + return TEST_SKIPPED; +} +#endif + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -61678,6 +62112,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_Tls13_postauth), TEST_DECL(test_wolfSSL_CTX_set_ecdh_auto), TEST_DECL(test_wolfSSL_set_minmax_proto_version), + TEST_DECL(test_wolfSSL_CTX_set_max_proto_version), TEST_DECL(test_wolfSSL_THREADID_hash), TEST_DECL(test_wolfSSL_RAND_set_rand_method), TEST_DECL(test_wolfSSL_RAND_bytes), @@ -62029,10 +62464,13 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_CTX_set_timeout), TEST_DECL(test_wolfSSL_OpenSSL_version), TEST_DECL(test_wolfSSL_set_psk_use_session_callback), + TEST_DECL(test_ticket_and_psk_mixing), + TEST_DECL(test_prioritize_psk), TEST_DECL(test_CONF_CTX_FILE), TEST_DECL(test_CONF_CTX_CMDLINE), TEST_DECL(test_wolfSSL_CRYPTO_get_ex_new_index), + TEST_DECL(test_wolfSSL_SESSION_get_ex_new_index), /* wolfcrypt */ TEST_DECL(test_wolfCrypt_Init), @@ -62367,6 +62805,8 @@ TEST_CASE testCases[] = { #endif /* !defined(NO_OLD_TLS) */ #endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \ * !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) */ + TEST_DECL(test_wolfSSL_CTX_set_ciphersuites), + TEST_DECL(test_wolfSSL_CRL_CERT_REVOKED_alert), TEST_DECL(test_WOLFSSL_dtls_version_alert), TEST_DECL(test_ForceZero), diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 8511217fc..f63f8b65f 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4220,6 +4220,7 @@ typedef struct Options { word16 isClosed:1; /* if we consider conn closed */ word16 closeNotify:1; /* we've received a close notify */ word16 sentNotify:1; /* we've sent a close notify */ + word16 shutdownDone:1; /* we've completed a shutdown */ word16 usingCompression:1; /* are we using compression */ word16 haveRSA:1; /* RSA available */ word16 haveECC:1; /* ECC available */ @@ -6081,7 +6082,25 @@ WOLFSSL_LOCAL int GetX509Error(int e); defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || \ defined(HAVE_LIGHTY)) || defined(HAVE_EX_DATA) || \ defined(WOLFSSL_WPAS_SMALL) -WOLFSSL_LOCAL int wolfssl_get_ex_new_index(int class_index); +typedef struct CRYPTO_EX_cb_ctx { + long ctx_l; + void *ctx_ptr; + WOLFSSL_CRYPTO_EX_new* new_func; + WOLFSSL_CRYPTO_EX_free* free_func; + WOLFSSL_CRYPTO_EX_dup* dup_func; + struct CRYPTO_EX_cb_ctx* next; +} CRYPTO_EX_cb_ctx; +extern CRYPTO_EX_cb_ctx* crypto_ex_cb_ctx_session; +WOLFSSL_LOCAL void crypto_ex_cb_free(CRYPTO_EX_cb_ctx* cb_ctx); +WOLFSSL_LOCAL void crypto_ex_cb_setup_new_data(void *new_obj, + CRYPTO_EX_cb_ctx* cb_ctx, WOLFSSL_CRYPTO_EX_DATA* ex_data); +WOLFSSL_LOCAL void crypto_ex_cb_free_data(void *obj, CRYPTO_EX_cb_ctx* cb_ctx, + WOLFSSL_CRYPTO_EX_DATA* ex_data); +WOLFSSL_LOCAL int crypto_ex_cb_dup_data(const WOLFSSL_CRYPTO_EX_DATA *in, + WOLFSSL_CRYPTO_EX_DATA *out, CRYPTO_EX_cb_ctx* cb_ctx); +WOLFSSL_LOCAL int wolfssl_get_ex_new_index(int class_index, long ctx_l, + void* ctx_ptr, WOLFSSL_CRYPTO_EX_new* new_func, + WOLFSSL_CRYPTO_EX_dup* dup_func, WOLFSSL_CRYPTO_EX_free* free_func); #endif WOLFSSL_LOCAL WC_RNG* wolfssl_get_global_rng(void); diff --git a/wolfssl/openssl/compat_types.h b/wolfssl/openssl/compat_types.h index b1861b40f..bdf4aa3f2 100644 --- a/wolfssl/openssl/compat_types.h +++ b/wolfssl/openssl/compat_types.h @@ -63,4 +63,14 @@ typedef WOLFSSL_ENGINE ENGINE; typedef WOLFSSL_EVP_PKEY_CTX EVP_PKEY_CTX; #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ +#ifdef HAVE_EX_DATA +typedef void (WOLFSSL_CRYPTO_EX_new)(void* p, void* ptr, + WOLFSSL_CRYPTO_EX_DATA* a, int idx, long argValue, void* arg); +typedef int (WOLFSSL_CRYPTO_EX_dup)(WOLFSSL_CRYPTO_EX_DATA* out, + const WOLFSSL_CRYPTO_EX_DATA* in, void* inPtr, int idx, long argV, + void* arg); +typedef void (WOLFSSL_CRYPTO_EX_free)(void* p, void* ptr, + WOLFSSL_CRYPTO_EX_DATA* a, int idx, long argValue, void* arg); +#endif + #endif /* !WOLFSSL_OPENSSL_COMPAT_TYPES_H_ */ diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index e4fd419f6..52576d096 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -25,6 +25,7 @@ #define WOLFSSL_CRYPTO_H_ #include +#include typedef struct WOLFSSL_INIT_SETTINGS { char* appname; @@ -37,8 +38,12 @@ typedef struct WOLFSSL_CRYPTO_THREADID { typedef struct crypto_threadid_st CRYPTO_THREADID; typedef struct CRYPTO_EX_DATA CRYPTO_EX_DATA; -typedef void (CRYPTO_free_func)(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx, - long argl, void* argp); + +#ifdef HAVE_EX_DATA +typedef WOLFSSL_CRYPTO_EX_new CRYPTO_new_func; +typedef WOLFSSL_CRYPTO_EX_dup CRYPTO_dup_func; +typedef WOLFSSL_CRYPTO_EX_free CRYPTO_free_func; +#endif #include #include @@ -148,6 +153,7 @@ WOLFSSL_API int wolfSSL_OPENSSL_init_crypto(word64 opts, const OPENSSL_INIT_SETT #define CRYPTO_THREAD_write_lock wc_LockMutex #define CRYPTO_THREAD_lock_free wc_FreeMutex +#define CRYPTO_get_ex_data wolfSSL_CRYPTO_get_ex_data #define CRYPTO_set_ex_data wolfSSL_CRYPTO_set_ex_data #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || HAVE_EX_DATA */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 167114701..65aac3b58 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1303,13 +1303,6 @@ typedef void (CallbackInfoState)(const WOLFSSL* ssl, int, int); } \ } while(0) -typedef int (WOLFSSL_CRYPTO_EX_new)(void* p, void* ptr, - WOLFSSL_CRYPTO_EX_DATA* a, int idx, long argValue, void* arg); -typedef int (WOLFSSL_CRYPTO_EX_dup)(WOLFSSL_CRYPTO_EX_DATA* out, - WOLFSSL_CRYPTO_EX_DATA* in, void* inPtr, int idx, long argV, void* arg); -typedef void (WOLFSSL_CRYPTO_EX_free)(void* p, void* ptr, - WOLFSSL_CRYPTO_EX_DATA* a, int idx, long argValue, void* arg); - WOLFSSL_API int wolfSSL_get_ex_new_index(long argValue, void* arg, WOLFSSL_CRYPTO_EX_new* a, WOLFSSL_CRYPTO_EX_dup* b, WOLFSSL_CRYPTO_EX_free* c); @@ -4675,8 +4668,11 @@ WOLFSSL_API int wolfSSL_SESSION_set_ex_data_with_cleanup( #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) \ || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) -WOLFSSL_API int wolfSSL_SESSION_get_ex_new_index(long idx,void* data,void* cb1,void* cb2, - CRYPTO_free_func* cb3); +#ifdef HAVE_EX_DATA +WOLFSSL_API int wolfSSL_SESSION_get_ex_new_index(long ctx_l,void* ctx_ptr, + WOLFSSL_CRYPTO_EX_new* new_func, WOLFSSL_CRYPTO_EX_dup* dup_func, + WOLFSSL_CRYPTO_EX_free* free_func); +#endif WOLFSSL_API const unsigned char* wolfSSL_SESSION_get_id( const WOLFSSL_SESSION* sess, unsigned int* idLen); diff --git a/wolfssl/test.h b/wolfssl/test.h index d273c64c5..b6bc86c43 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -576,10 +576,12 @@ typedef struct callback_functions { ctx_callback ctx_ready; ssl_callback ssl_ready; ssl_callback on_result; + ssl_callback on_cleanup; WOLFSSL_CTX* ctx; const char* caPemFile; const char* certPemFile; const char* keyPemFile; + const char* crlPemFile; #ifdef WOLFSSL_STATIC_MEMORY byte* mem; word32 memSz;