mirror of https://github.com/wolfSSL/wolfssl.git
commit
31b9da2c8d
|
|
@ -93,6 +93,10 @@
|
|||
{"name": "dtls13-ocspstapling-cert-cb", "minutes": 3.1,
|
||||
"configure": ["--enable-dtls", "--enable-dtls13", "--enable-ocspstapling",
|
||||
"--enable-ocspstapling2", "--enable-cert-setup-cb", "--enable-sessioncerts"]},
|
||||
{"name": "nullcipher-tls13-in-default", "minutes": 3.0,
|
||||
"comment": "Legacy WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT mode: RFC 9150 integrity-only suites back in the default TLS 1.3/DTLS 1.3 cipher list. The only config that runs tests/test-tls13-null.conf and tests/test-dtls13-null.conf (they need the suites in the default list). The dtls-cid-renego-psk entry covers the default-exclusion mode of --enable-nullcipher.",
|
||||
"configure": ["--enable-dtls", "--enable-dtls13", "--enable-nullcipher",
|
||||
"CPPFLAGS=-DWOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT -DWOLFSSL_STATIC_RSA"]},
|
||||
{"name": "tsp-verifier", "minutes": 3,
|
||||
"comment": "Time-Stamp Protocol Verifier",
|
||||
"configure": ["--enable-tsp", "--enable-opensslall",
|
||||
|
|
|
|||
|
|
@ -1177,6 +1177,7 @@ WOLFSSL_TI_CURRTIME
|
|||
WOLFSSL_TLS13_DRAFT
|
||||
WOLFSSL_TLS13_IGNORE_AEAD_LIMITS
|
||||
WOLFSSL_TLS13_IGNORE_PT_ALERT_ON_ENC
|
||||
WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT
|
||||
WOLFSSL_TLS13_SHA512
|
||||
WOLFSSL_TLS13_TICKET_CHECK_PSK_MODES
|
||||
WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
|
||||
|
|
|
|||
103
src/internal.c
103
src/internal.c
|
|
@ -97,6 +97,8 @@
|
|||
* WOLFSSL_TICKET_ENC_CBC_HMAC:
|
||||
* CBC+HMAC for ticket encryption (non-AEAD) default: off
|
||||
* WOLFSSL_NO_TICKET_EXPIRE: Disable ticket expiration checking default: off
|
||||
* (server-side resumption and the client-side check
|
||||
* on a stored ticket before offering it)
|
||||
*
|
||||
* TLS 1.3 Internals:
|
||||
* WOLFSSL_TLS13_IGNORE_PT_ALERT_ON_ENC:
|
||||
|
|
@ -106,6 +108,9 @@
|
|||
* WOLFSSL_TLS13_IGNORE_AEAD_LIMITS:
|
||||
* Ignore AEAD message limits from RFC 9846 5.5, which
|
||||
* makes observing them a MUST default: off
|
||||
* WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT:
|
||||
* Include RFC 9150 integrity-only suites in the
|
||||
* default cipher suite list (HAVE_NULL_CIPHER) default: off
|
||||
* WOLFSSL_DTLS13_SEND_MOREACK_DEFAULT:
|
||||
* Send more ACKs by default in DTLS 1.3 default: off
|
||||
*
|
||||
|
|
@ -4054,19 +4059,35 @@ static word16 InitSuites_Tls13(Suites* suites, word16 idx, int tls1_3,
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
/* RFC 9150 integrity-only (zero-confidentiality) TLS 1.3 suites.
|
||||
* These provide authentication and integrity but no confidentiality, so
|
||||
* they are NOT advertised in the default cipher preference list. A caller
|
||||
* that genuinely needs them (e.g. constrained/IoT deployments) must opt in
|
||||
* explicitly with a cipher list, either by suite name:
|
||||
* wolfSSL_set_cipher_list(ssl, "TLS13-SHA256-SHA256");
|
||||
* or with the "eNULL" keyword. Define
|
||||
* WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT to restore the legacy behaviour of
|
||||
* including them in the default list. */
|
||||
#ifndef WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT
|
||||
if (haveNull == SUITES_NULL_EXPLICIT)
|
||||
#else
|
||||
if (haveNull)
|
||||
#endif
|
||||
{
|
||||
#ifdef BUILD_TLS_SHA256_SHA256
|
||||
if (tls1_3 && haveNull) {
|
||||
if (tls1_3) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_SHA256_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_SHA384_SHA384
|
||||
if (tls1_3 && haveNull) {
|
||||
if (tls1_3) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_SHA384_SHA384;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return idx;
|
||||
|
|
@ -27626,32 +27647,38 @@ int SendFinished(WOLFSSL* ssl)
|
|||
AddSession(ssl);
|
||||
#endif
|
||||
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||
/* Mark the handshake done before the info callback so the
|
||||
* callback (e.g. on WOLFSSL_CB_HANDSHAKE_DONE) can use APIs that
|
||||
* require a completed handshake, such as
|
||||
* wolfSSL_export_keying_material(). */
|
||||
ssl->options.handShakeState = HANDSHAKE_DONE;
|
||||
ssl->options.handShakeDone = 1;
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
ssl->options.resumed = ssl->options.resuming;
|
||||
#endif
|
||||
#ifdef OPENSSL_EXTRA
|
||||
ssl->options.serverState = SERVER_FINISHED_COMPLETE;
|
||||
ssl->cbmode = WOLFSSL_CB_MODE_WRITE;
|
||||
if (ssl->CBIS != NULL)
|
||||
ssl->CBIS(ssl, WOLFSSL_CB_HANDSHAKE_DONE, WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
/* Same ordering as the server side above: flags first so the
|
||||
* info callback sees a completed handshake. */
|
||||
ssl->options.handShakeState = HANDSHAKE_DONE;
|
||||
ssl->options.handShakeDone = 1;
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
ssl->options.resumed = ssl->options.resuming;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
#ifdef OPENSSL_EXTRA
|
||||
ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
|
||||
ssl->cbmode = WOLFSSL_CB_MODE_WRITE;
|
||||
if (ssl->CBIS != NULL)
|
||||
ssl->CBIS(ssl, WOLFSSL_CB_HANDSHAKE_DONE, WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
ssl->options.handShakeState = HANDSHAKE_DONE;
|
||||
ssl->options.handShakeDone = 1;
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
ssl->options.resumed = ssl->options.resuming;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -32161,7 +32188,7 @@ static int ParseCipherList(Suites* suites,
|
|||
}
|
||||
|
||||
if (XSTRCMP(name, "eNULL") == 0 || XSTRCMP(name, "NULL") == 0) {
|
||||
haveNull = allowing;
|
||||
haveNull = allowing ? SUITES_NULL_EXPLICIT : 0;
|
||||
/* Track exclusion (sticky) so an explicit NULL-cipher suite is
|
||||
* dropped at the end regardless of "!eNULL"/"!NULL" position; a
|
||||
* later allowing "eNULL" does not undo it. */
|
||||
|
|
@ -34612,16 +34639,45 @@ static void MakePSKPreMasterSecret(Arrays* arrays, byte use_psk_key)
|
|||
if (ssl->options.resuming && ssl->session->ticketLen > 0) {
|
||||
SessionTicket* ticket;
|
||||
|
||||
ticket = TLSX_SessionTicket_Create(0, ssl->session->ticket,
|
||||
ssl->session->ticketLen, ssl->heap);
|
||||
if (ticket == NULL) return MEMORY_E;
|
||||
|
||||
ret = TLSX_UseSessionTicket(&ssl->extensions, ticket, ssl->heap);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
TLSX_SessionTicket_Free(ticket, ssl->heap);
|
||||
return ret;
|
||||
#if !defined(WOLFSSL_NO_TICKET_EXPIRE) && !defined(NO_ASN_TIME)
|
||||
/* RFC 5077 Section 3.3 / RFC 8446 Section 4.6.1: a client SHOULD
|
||||
* NOT use a ticket whose lifetime has expired. Drop the expired
|
||||
* ticket and fall back to a full handshake. Skip the check when
|
||||
* bornOn or timeout is 0 (unknown lifetime) or a secret callback
|
||||
* is set (session is managed externally, e.g. hostap). */
|
||||
if (ssl->session->bornOn != 0 && ssl->session->timeout != 0 &&
|
||||
#ifdef HAVE_SECRET_CALLBACK
|
||||
ssl->sessionSecretCb == NULL &&
|
||||
#endif
|
||||
(LowResTimer() - ssl->session->bornOn) >=
|
||||
ssl->session->timeout) {
|
||||
WOLFSSL_MSG("Stored session ticket expired; full handshake");
|
||||
ssl->options.resuming = 0;
|
||||
/* The stale ticket stays on the session object, which may be
|
||||
* shared with the application; the replacement ticket from
|
||||
* the full handshake overwrites it in SetTicket(). */
|
||||
/* Send an empty SessionTicket extension (NULL ticket) so the
|
||||
* client still requests a new ticket from the server without
|
||||
* sending the stale one. */
|
||||
ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ticket = TLSX_SessionTicket_Create(0, ssl->session->ticket,
|
||||
ssl->session->ticketLen,
|
||||
ssl->heap);
|
||||
if (ticket == NULL) return MEMORY_E;
|
||||
|
||||
ret = TLSX_UseSessionTicket(&ssl->extensions, ticket,
|
||||
ssl->heap);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
TLSX_SessionTicket_Free(ticket, ssl->heap);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
idSz = 0;
|
||||
}
|
||||
#endif /* HAVE_SESSION_TICKET */
|
||||
|
|
@ -41384,9 +41440,10 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
|
|||
* Handles session resumption.
|
||||
* Session tickets are checked for validity based on the time each ticket
|
||||
* was created, timeout value and the current time. If the tickets are
|
||||
* judged expired, falls back to full-handshake. If you want disable this
|
||||
* session ticket validation check in TLS1.2 and below, define
|
||||
* WOLFSSL_NO_TICKET_EXPIRE.
|
||||
* judged expired, falls back to full-handshake. If you want disable
|
||||
* this session ticket validation check in TLS1.2 and below (both here
|
||||
* and the client-side check on a stored ticket in SendClientHello),
|
||||
* define WOLFSSL_NO_TICKET_EXPIRE.
|
||||
*/
|
||||
int HandleTlsResumption(WOLFSSL* ssl, Suites* clSuites)
|
||||
{
|
||||
|
|
|
|||
17
src/ssl.c
17
src/ssl.c
|
|
@ -3357,6 +3357,16 @@ int wolfSSL_export_keying_material(WOLFSSL *ssl,
|
|||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
/* RFC 8446 Section 7.5 / RFC 5705: keying-material exporters derive from
|
||||
* exporter_master_secret, which exists only after the handshake is
|
||||
* complete. Refuse the export until the handshake has completed so that
|
||||
* a premature call cannot derive material from an uninitialised
|
||||
* exporterSecret buffer. */
|
||||
if (ssl->options.handShakeDone == 0) {
|
||||
WOLFSSL_MSG("Handshake not complete; refusing keying-material export");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
/* Sanity check contextLen to prevent integer overflow when cast to word32
|
||||
* and to ensure it fits in the 2-byte length encoding (max 65535). */
|
||||
if (use_context && contextLen > WOLFSSL_MAX_16BIT) {
|
||||
|
|
@ -7587,9 +7597,12 @@ long wolfSSL_set_options(WOLFSSL* ssl, long op)
|
|||
* options limit the allowed ciphers so let's try to get as many as
|
||||
* possible.
|
||||
* - haveStaticECC turns off haveRSA
|
||||
* - haveECDSAsig turns off haveRSAsig */
|
||||
* - haveECDSAsig turns off haveRSAsig
|
||||
* - SUITES_NULL_EXPLICIT includes the integrity-only suites, so
|
||||
* an explicitly configured one is preserved */
|
||||
InitSuites(&tmpSuites, ssl->version, 0, 1, 1, 1, haveECDSAsig, 1, 1,
|
||||
haveStaticECC, 1, 1, 1, 1, 1, ssl->options.side);
|
||||
haveStaticECC, 1, SUITES_NULL_EXPLICIT, 1, 1, 1,
|
||||
ssl->options.side);
|
||||
for (in = 0, out = 0; in < ssl->suites->suiteSz; in += SUITE_LEN) {
|
||||
if (FindSuite(&tmpSuites, ssl->suites->suites[in],
|
||||
ssl->suites->suites[in+1]) >= 0) {
|
||||
|
|
|
|||
|
|
@ -69,6 +69,11 @@
|
|||
* WOLFSSL_CHECK_SIG_FAULTS: Verify signature after ECC signing default: off
|
||||
* to detect fault injection attacks
|
||||
* WOLFSSL_CIPHER_TEXT_CHECK: Verify ciphertext integrity default: off
|
||||
* WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT: Include RFC 9150 suites default: off
|
||||
* in the default cipher suite list (requires
|
||||
* HAVE_NULL_CIPHER). Without it the integrity-only
|
||||
* suites must be requested explicitly in the
|
||||
* cipher list, by name or with "eNULL".
|
||||
*
|
||||
* TLS 1.3 PSK:
|
||||
* WOLFSSL_PSK_ONE_ID: Single PSK identity per connect default: off
|
||||
|
|
|
|||
242
tests/api.c
242
tests/api.c
|
|
@ -2667,16 +2667,20 @@ static int test_wolfSSL_set_cipher_list_tls13_with_version(void)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(TEST_CIPHER_EXCLUDE_ANON) || defined(TEST_CIPHER_EXCLUDE_NULL)
|
||||
/* Does the parsed suite list on ssl contain the given suite bytes? */
|
||||
static int test_suites_contains(WOLFSSL* ssl, byte s0, byte s1)
|
||||
#if defined(TEST_CIPHER_EXCLUDE_ANON) || defined(TEST_CIPHER_EXCLUDE_NULL) || \
|
||||
defined(BUILD_TLS_SHA256_SHA256)
|
||||
/* Does the parsed suite list on ssl contain the given suite bytes?
|
||||
* WC_MAYBE_UNUSED: the TLS 1.3 null-cipher tests gate further inside their
|
||||
* bodies, so some builds compile this helper without a caller. */
|
||||
static WC_MAYBE_UNUSED int test_suites_contains(WOLFSSL* ssl, byte s0, byte s1)
|
||||
{
|
||||
int i;
|
||||
if (ssl == NULL || ssl->suites == NULL)
|
||||
const Suites* suites = (ssl != NULL) ? WOLFSSL_SUITES(ssl) : NULL;
|
||||
if (suites == NULL)
|
||||
return 0;
|
||||
for (i = 0; (i + 1) < ssl->suites->suiteSz; i += 2) {
|
||||
if ((ssl->suites->suites[i] == s0) &&
|
||||
(ssl->suites->suites[i + 1] == s1))
|
||||
for (i = 0; (i + 1) < suites->suiteSz; i += 2) {
|
||||
if ((suites->suites[i] == s0) &&
|
||||
(suites->suites[i + 1] == s1))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -2826,10 +2830,11 @@ static int test_wolfSSL_set_cipher_list_exclusions(void)
|
|||
wolfSSL_free(ssl);
|
||||
ssl = NULL;
|
||||
|
||||
/* OpenSSL compat: "ALL" is "all but eNULL" - it does not generate NULL
|
||||
* suites, but it is not a delete directive, so a following "eNULL"
|
||||
* re-enables them. (The earlier sticky excludeNull-for-ALL wrongly kept
|
||||
* them disabled; only "!eNULL"/"DEFAULT" should.) */
|
||||
/* The RFC 9150 integrity-only TLS 1.3 suites are zero-confidentiality:
|
||||
* they are kept out of the default preference list (unless
|
||||
* WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT is defined) and are never produced
|
||||
* by "ALL" alone, but an explicit "eNULL" keyword or suite name requests
|
||||
* them in either mode. */
|
||||
ExpectNotNull(ssl = wolfSSL_new(ctx));
|
||||
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "ALL"), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(test_suites_contains(ssl, ECC_BYTE,
|
||||
|
|
@ -2840,7 +2845,15 @@ static int test_wolfSSL_set_cipher_list_exclusions(void)
|
|||
ExpectNotNull(ssl = wolfSSL_new(ctx));
|
||||
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "ALL:eNULL"), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(test_suites_contains(ssl, ECC_BYTE,
|
||||
TLS_SHA256_SHA256), 1); /* "eNULL" after "ALL" re-enables NULL */
|
||||
TLS_SHA256_SHA256), 1); /* explicit "eNULL" requests them */
|
||||
wolfSSL_free(ssl);
|
||||
ssl = NULL;
|
||||
|
||||
ExpectNotNull(ssl = wolfSSL_new(ctx));
|
||||
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-SHA256-SHA256"),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(test_suites_contains(ssl, ECC_BYTE,
|
||||
TLS_SHA256_SHA256), 1); /* explicit suite name works too */
|
||||
wolfSSL_free(ssl);
|
||||
ssl = NULL;
|
||||
#endif /* BUILD_TLS_SHA256_SHA256 */
|
||||
|
|
@ -2858,6 +2871,77 @@ static int test_wolfSSL_set_cipher_list_exclusions(void)
|
|||
#undef TEST_CIPHER_EXCLUDE_NULL
|
||||
#endif
|
||||
|
||||
/* A client using the default cipher list must not offer the RFC 9150
|
||||
* integrity-only TLS 1.3 suites unless WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT
|
||||
* is defined. The server accepts only TLS13-SHA256-SHA256, so the handshake
|
||||
* outcome shows whether the default list contained it. */
|
||||
static int test_tls13_null_cipher_default_list(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(BUILD_TLS_SHA256_SHA256) && !defined(NO_RSA) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
|
||||
struct test_memio_ctx test_ctx;
|
||||
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
/* Client keeps the default cipher list. */
|
||||
test_ctx.s_ciphers = "TLS13-SHA256-SHA256";
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
|
||||
#ifdef WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
|
||||
ExpectIntEQ(ssl_c->options.cipherSuite0, ECC_BYTE);
|
||||
ExpectIntEQ(ssl_c->options.cipherSuite, TLS_SHA256_SHA256);
|
||||
#else
|
||||
/* no common suite: the server rejects the ClientHello */
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), -1);
|
||||
ExpectIntEQ(ssl_s->error, WC_NO_ERR_TRACE(MATCH_SUITE_ERROR));
|
||||
#endif
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* An explicitly configured integrity-only suite must survive
|
||||
* wolfSSL_[CTX_]set_options() and wolfSSL_new(): the preserve-overlap
|
||||
* rebuild in wolfSSL_set_options() must keep explicitly requested NULL
|
||||
* suites even though they are not in the default list. */
|
||||
static int test_tls13_null_cipher_explicit_keep(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(BUILD_TLS_SHA256_SHA256) && defined(OPENSSL_EXTRA) && \
|
||||
!defined(NO_WOLFSSL_CLIENT)
|
||||
WOLFSSL_CTX* ctx = NULL;
|
||||
WOLFSSL* ssl = NULL;
|
||||
|
||||
/* ctx-level cipher list set before ctx-level options */
|
||||
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
||||
ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx, "TLS13-SHA256-SHA256"),
|
||||
WOLFSSL_SUCCESS);
|
||||
wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_SSLv3);
|
||||
ExpectNotNull(ssl = wolfSSL_new(ctx));
|
||||
ExpectIntEQ(test_suites_contains(ssl, ECC_BYTE, TLS_SHA256_SHA256), 1);
|
||||
wolfSSL_free(ssl);
|
||||
ssl = NULL;
|
||||
|
||||
/* ssl-level options after an explicit ssl-level cipher list */
|
||||
ExpectNotNull(ssl = wolfSSL_new(ctx));
|
||||
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-SHA256-SHA256"),
|
||||
WOLFSSL_SUCCESS);
|
||||
wolfSSL_set_options(ssl, WOLFSSL_OP_NO_SSLv3);
|
||||
ExpectIntEQ(test_suites_contains(ssl, ECC_BYTE, TLS_SHA256_SHA256), 1);
|
||||
wolfSSL_free(ssl);
|
||||
ssl = NULL;
|
||||
|
||||
wolfSSL_CTX_free(ctx);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_wolfSSL_set_alpn_protos_default_fails(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
|
|
@ -31466,6 +31550,18 @@ static int test_export_keying_material_cb(WOLFSSL_CTX *ctx, WOLFSSL *ssl)
|
|||
/* Use some random context */
|
||||
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"Test label", XSTR_SIZEOF("Test label"), ekm, 10, 1), 1);
|
||||
/* The handshake-complete gate must be the deciding factor: clearing
|
||||
* handShakeDone on this otherwise fully established connection flips an
|
||||
* identical call from success to failure, and restoring it flips it
|
||||
* back. */
|
||||
ssl->options.handShakeDone = 0;
|
||||
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"Test label", XSTR_SIZEOF("Test label"), NULL, 0, 1),
|
||||
WOLFSSL_FAILURE);
|
||||
ssl->options.handShakeDone = 1;
|
||||
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"Test label", XSTR_SIZEOF("Test label"), NULL, 0, 1),
|
||||
WOLFSSL_SUCCESS);
|
||||
/* Failure cases */
|
||||
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"client finished", XSTR_SIZEOF("client finished"), NULL, 0, 0), 0);
|
||||
|
|
@ -31489,8 +31585,15 @@ static int test_export_keying_material_cb(WOLFSSL_CTX *ctx, WOLFSSL *ssl)
|
|||
|
||||
static int test_export_keying_material_ssl_cb(WOLFSSL* ssl)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
byte ekm[32] = {0};
|
||||
|
||||
wolfSSL_KeepArrays(ssl);
|
||||
return TEST_SUCCESS;
|
||||
/* Export must be refused until the handshake has completed. */
|
||||
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"Test label", XSTR_SIZEOF("Test label"), NULL, 0, 1),
|
||||
WOLFSSL_FAILURE);
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_export_keying_material(void)
|
||||
|
|
@ -31508,6 +31611,54 @@ static int test_export_keying_material(void)
|
|||
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_TLS12)
|
||||
static int test_ekm_info_cb_result = -1;
|
||||
|
||||
static void test_ekm_info_cb(const WOLFSSL* ssl, int type, int val)
|
||||
{
|
||||
byte ekm[32];
|
||||
(void)val;
|
||||
if (type == WOLFSSL_CB_HANDSHAKE_DONE) {
|
||||
test_ekm_info_cb_result = wolfSSL_export_keying_material(
|
||||
(WOLFSSL*)ssl, ekm, sizeof(ekm),
|
||||
"Test label", XSTR_SIZEOF("Test label"), NULL, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int test_ekm_info_ctx_ready(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
wolfSSL_CTX_set_info_callback(ctx, test_ekm_info_cb);
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA && !WOLFSSL_NO_TLS12 */
|
||||
|
||||
/* wolfSSL_export_keying_material() must work from inside the
|
||||
* WOLFSSL_CB_HANDSHAKE_DONE info callback: the handshake-done flags are set
|
||||
* before the callback fires (TLS 1.2 SendFinished, server side here). */
|
||||
static int test_export_keying_material_info_cb(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_TLS12)
|
||||
test_ssl_cbf serverCb;
|
||||
test_ssl_cbf clientCb;
|
||||
|
||||
XMEMSET(&serverCb, 0, sizeof(serverCb));
|
||||
XMEMSET(&clientCb, 0, sizeof(clientCb));
|
||||
clientCb.method = wolfTLSv1_2_client_method;
|
||||
serverCb.method = wolfTLSv1_2_server_method;
|
||||
serverCb.ctx_ready = test_ekm_info_ctx_ready;
|
||||
/* exporter needs the handshake arrays kept on the exporting side */
|
||||
serverCb.ssl_ready = test_export_keying_material_ssl_cb;
|
||||
|
||||
test_ekm_info_cb_result = -1;
|
||||
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&clientCb,
|
||||
&serverCb, NULL), TEST_SUCCESS);
|
||||
/* The callback fired and the export succeeded. */
|
||||
ExpectIntEQ(test_ekm_info_cb_result, WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
#endif /* HAVE_KEYING_MATERIAL */
|
||||
|
||||
static int test_wolfSSL_THREADID_hash(void)
|
||||
|
|
@ -35669,6 +35820,67 @@ static int test_ticket_ret_create(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* RFC 5077 Section 3.3: a stored ticket whose lifetime has expired must not
|
||||
* be offered; the client falls back to a full handshake. */
|
||||
static int test_ticket_expired_full_handshake(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
!defined(WOLFSSL_NO_TICKET_EXPIRE) && !defined(NO_ASN_TIME) && \
|
||||
!defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && !defined(NO_RSA) && \
|
||||
defined(HAVE_ECC) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
WOLFSSL_SESSION *sess = NULL;
|
||||
int i;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, 0);
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, 0);
|
||||
ExpectIntEQ(wolfSSL_CTX_UseSessionTicket(ctx_c), WOLFSSL_SUCCESS);
|
||||
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
|
||||
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
|
||||
|
||||
/* Round 0: control, the ticket resumes as-is. Round 1: same ticket made
|
||||
* to look expired; the client must do a full handshake instead. */
|
||||
for (i = 0; i < 2; i++) {
|
||||
wolfSSL_free(ssl_c);
|
||||
ssl_c = NULL;
|
||||
wolfSSL_free(ssl_s);
|
||||
ssl_s = NULL;
|
||||
|
||||
ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
|
||||
wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
|
||||
wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
|
||||
ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
|
||||
wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
|
||||
wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
|
||||
|
||||
ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
|
||||
if (i == 1 && ssl_c != NULL) {
|
||||
ssl_c->session->bornOn -= ssl_c->session->timeout + 1;
|
||||
}
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
|
||||
if (ssl_c != NULL) {
|
||||
ExpectIntEQ(ssl_c->options.resuming, i == 0 ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
wolfSSL_SESSION_free(sess);
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Build a valid TLS 1.2 ticket by completing an initial handshake, then tamper
|
||||
* with enc_len so it is larger than the true encrypted payload. */
|
||||
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
|
|
@ -42139,6 +42351,8 @@ TEST_CASE testCases[] = {
|
|||
TEST_DECL(test_wolfSSL_set_cipher_list_tls12_with_version),
|
||||
TEST_DECL(test_wolfSSL_set_cipher_list_tls13_with_version),
|
||||
TEST_DECL(test_wolfSSL_set_cipher_list_exclusions),
|
||||
TEST_DECL(test_tls13_null_cipher_default_list),
|
||||
TEST_DECL(test_tls13_null_cipher_explicit_keep),
|
||||
TEST_DECL(test_wolfSSL_set_alpn_protos_default_fails),
|
||||
TEST_DECL(test_wolfSSL_CTX_use_certificate),
|
||||
TEST_DECL(test_wolfSSL_CTX_use_certificate_file),
|
||||
|
|
@ -42388,6 +42602,7 @@ TEST_CASE testCases[] = {
|
|||
|
||||
#if defined(HAVE_KEYING_MATERIAL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
|
||||
TEST_DECL(test_export_keying_material),
|
||||
TEST_DECL(test_export_keying_material_info_cb),
|
||||
#endif
|
||||
|
||||
/* Can't memory test as client/server Asserts in thread. */
|
||||
|
|
@ -42438,6 +42653,7 @@ TEST_CASE testCases[] = {
|
|||
TEST_DECL(test_ticket_nonce_malloc),
|
||||
#endif
|
||||
TEST_DECL(test_ticket_ret_create),
|
||||
TEST_DECL(test_ticket_expired_full_handshake),
|
||||
TEST_DECL(test_ticket_enc_corrupted),
|
||||
TEST_DECL(test_wrong_cs_downgrade),
|
||||
TEST_DECL(test_tls13_no_ext_sh_alert),
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ EXTRA_DIST += tests/unit.h \
|
|||
tests/test-tls13.conf \
|
||||
tests/test-tls13-down.conf \
|
||||
tests/test-tls13-ecc.conf \
|
||||
tests/test-tls13-null.conf \
|
||||
tests/test-tls13-psk.conf \
|
||||
tests/test-tls13-pq-standalone.conf \
|
||||
tests/test-tls13-pq-hybrid.conf \
|
||||
|
|
@ -71,6 +72,7 @@ EXTRA_DIST += tests/unit.h \
|
|||
tests/test-dtls-srtp.conf \
|
||||
tests/test-dtls-srtp-fails.conf \
|
||||
tests/test-dtls13.conf \
|
||||
tests/test-dtls13-null.conf \
|
||||
tests/test-dtls13-downgrade.conf \
|
||||
tests/test-dtls13-downgrade-fails.conf \
|
||||
tests/test-dtls13-psk.conf \
|
||||
|
|
|
|||
|
|
@ -1180,6 +1180,20 @@ int SuiteTest(int argc, char** argv)
|
|||
goto exit;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_NULL_CIPHER) && \
|
||||
defined(WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT)
|
||||
/* add TLSv13 integrity-only suites; the harness repeats each case with
|
||||
* the default cipher list on one side, so these can only pass when the
|
||||
* default list includes the integrity-only suites */
|
||||
XSTRLCPY(argv0[1], "tests/test-tls13-null.conf", sizeof(argv0[1]));
|
||||
printf("starting TLSv13 integrity-only cipher suite tests\n");
|
||||
test_harness(&args);
|
||||
if (args.return_code != 0) {
|
||||
printf("error from script %d\n", args.return_code);
|
||||
args.return_code = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
/* add TLSv13 downgrade tests */
|
||||
XSTRLCPY(argv0[1], "tests/test-tls13-down.conf", sizeof(argv0[1]));
|
||||
|
|
@ -1651,6 +1665,19 @@ int SuiteTest(int argc, char** argv)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(HAVE_NULL_CIPHER) && \
|
||||
defined(WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT)
|
||||
/* see the test-tls13-null.conf note on the default-cipher-list repeat */
|
||||
XSTRLCPY(argv0[1], "tests/test-dtls13-null.conf", sizeof(argv0[1]));
|
||||
printf("starting DTLSv1.3 integrity-only cipher suite tests\n");
|
||||
test_harness(&args);
|
||||
if (args.return_code != 0) {
|
||||
printf("error from script %d\n", args.return_code);
|
||||
args.return_code = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
#endif /* HAVE_NULL_CIPHER && WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT */
|
||||
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
args.argc = 2;
|
||||
strcpy(argv0[1], "tests/test-dtls13-downgrade.conf");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
# DTLSv1.3 RFC 9150 integrity-only suites. Run only in HAVE_NULL_CIPHER builds
|
||||
# that also define WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT: the harness repeats
|
||||
# each case with the default cipher list on one side, which can only negotiate
|
||||
# these suites when they are in the default list.
|
||||
|
||||
# server DTLSv1.3 Integrity-only SHA256
|
||||
-u
|
||||
-v 4
|
||||
-l TLS13-SHA256-SHA256
|
||||
|
||||
# client DTLSv1.3 Integrity-only SHA256
|
||||
-u
|
||||
-v 4
|
||||
-l TLS13-SHA256-SHA256
|
||||
|
||||
# server DTLSv1.3 Integrity-only SHA384
|
||||
-u
|
||||
-v 4
|
||||
-l TLS13-SHA384-SHA384
|
||||
|
||||
# client DTLSv1.3 Integrity-only SHA384
|
||||
-u
|
||||
-v 4
|
||||
-l TLS13-SHA384-SHA384
|
||||
|
|
@ -271,26 +271,6 @@
|
|||
-v 4
|
||||
-l TLS_AES_128_GCM_SHA256
|
||||
|
||||
# server DTLSv1.3 Integrity-only SHA256
|
||||
-u
|
||||
-v 4
|
||||
-l TLS13-SHA256-SHA256
|
||||
|
||||
# client DTLSv1.3 Integrity-only SHA256
|
||||
-u
|
||||
-v 4
|
||||
-l TLS13-SHA256-SHA256
|
||||
|
||||
# server DTSv1.3 Integrity-only SHA384
|
||||
-u
|
||||
-v 4
|
||||
-l TLS13-SHA384-SHA384
|
||||
|
||||
# client DTLSv1.3 Integrity-only SHA384
|
||||
-u
|
||||
-v 4
|
||||
-l TLS13-SHA384-SHA384
|
||||
|
||||
# server DTLSv1.3 no (EC)DHE with PSK, must still key share in the HRR
|
||||
-u
|
||||
-v 4
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
# TLSv1.3 RFC 9150 integrity-only suites. Run only in HAVE_NULL_CIPHER builds
|
||||
# that also define WOLFSSL_TLS13_NULL_CIPHER_IN_DEFAULT: the harness repeats
|
||||
# each case with the default cipher list on one side, which can only negotiate
|
||||
# these suites when they are in the default list.
|
||||
|
||||
# server TLSv1.3 Integrity-only SHA256
|
||||
-v 4
|
||||
-l TLS13-SHA256-SHA256
|
||||
|
||||
# client TLSv1.3 Integrity-only SHA256
|
||||
-v 4
|
||||
-l TLS13-SHA256-SHA256
|
||||
|
||||
# server TLSv1.3 Integrity-only SHA384
|
||||
-v 4
|
||||
-l TLS13-SHA384-SHA384
|
||||
|
||||
# client TLSv1.3 Integrity-only SHA384
|
||||
-v 4
|
||||
-l TLS13-SHA384-SHA384
|
||||
|
|
@ -213,19 +213,3 @@
|
|||
# client TLSv1.3 Send Ticket explicitly
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
|
||||
# server TLSv1.3 Integrity-only SHA256
|
||||
-v 4
|
||||
-l TLS13-SHA256-SHA256
|
||||
|
||||
# client TLSv1.3 Integrity-only SHA256
|
||||
-v 4
|
||||
-l TLS13-SHA256-SHA256
|
||||
|
||||
# server TLSv1.3 Integrity-only SHA384
|
||||
-v 4
|
||||
-l TLS13-SHA384-SHA384
|
||||
|
||||
# client TLSv1.3 Integrity-only SHA384
|
||||
-v 4
|
||||
-l TLS13-SHA384-SHA384
|
||||
|
|
|
|||
|
|
@ -1940,6 +1940,10 @@ WOLFSSL_LOCAL int NamedGroupIsPqcHybrid(int group);
|
|||
/* 150 suites for now! */
|
||||
#endif
|
||||
|
||||
/* InitSuites() haveNull value used when NULL suites are requested explicitly
|
||||
* (cipher list "eNULL" keyword) rather than merely allowed by default (1). */
|
||||
#define SUITES_NULL_EXPLICIT 2
|
||||
|
||||
/* number of items in the signature algo list */
|
||||
#ifndef WOLFSSL_MAX_SIGALGO
|
||||
#if (defined(WOLFSSL_LEANPSK) || defined(WOLFSSL_LEANTLS)) && \
|
||||
|
|
|
|||
Loading…
Reference in New Issue