Skip to content

Commit e7f491a

Browse files
Check SNI/ALPN in TLS 1.3 session resumption
1 parent 43fabc6 commit e7f491a

4 files changed

Lines changed: 259 additions & 30 deletions

File tree

src/internal.c

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38691,8 +38691,22 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
3869138691
#endif
3869238692
#if defined(HAVE_SESSION_TICKET) && \
3869338693
(defined(HAVE_SNI) || defined(HAVE_ALPN))
38694-
if((ret=VerifyTicketBinding(ssl)))
38695-
goto out;
38694+
/* Only verify here for TLS 1.2 ticket-based resumption.
38695+
* For stateful (session-ID) resumption ssl->session is
38696+
* not loaded until HandleTlsResumption runs below, which
38697+
* performs its own binding check against the cached
38698+
* session. On mismatch decline the resumption (RFC 6066
38699+
* Section 3) but proceed with a full handshake; leave
38700+
* useTicket set so the server still issues a fresh
38701+
* ticket to the client. */
38702+
if (ssl->options.useTicket &&
38703+
VerifyTicketBinding(ssl) != 0) {
38704+
WOLFSSL_MSG("Ticket binding mismatch, "
38705+
"declining resumption and falling back "
38706+
"to full handshake");
38707+
ssl->options.resuming = 0;
38708+
ssl->options.peerAuthGood = 0;
38709+
}
3869638710
#endif
3869738711

3869838712
i += totalExtSz;
@@ -39519,15 +39533,30 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
3951939533
#endif
3952039534

3952139535
#if defined(HAVE_SNI) || defined(HAVE_ALPN)
39522-
/* Server-side: verify the SNI/ALPN bindings carried on a resumed
39523-
* session match what was negotiated for the current connection.
39524-
* Must be called after extension parsing and ALPN_Select.
39525-
* Returns 0 on match, WOLFSSL_FATAL_ERROR on mismatch. */
39536+
/* Server-side TLS 1.2 ticket-resumption binding check. Confirms the
39537+
* SNI/ALPN bound to the resumed session matches what was negotiated
39538+
* for the current connection. Must be called after extension
39539+
* parsing and ALPN_Select so the negotiated values are available,
39540+
* and only once DoClientTicketFinalize has populated
39541+
* ssl->session->sniHash/alpnHash from the decrypted ticket.
39542+
*
39543+
* Other resumption paths handle the same check themselves and do
39544+
* not use this function:
39545+
* - TLS 1.2 session-ID (stateful): HandleTlsResumption compares
39546+
* against the cached session at lookup time.
39547+
* - TLS 1.3 PSK: DoPreSharedKeys compares against each candidate
39548+
* ticket's bound hashes before committing, allowing the server
39549+
* to skip mismatching PSKs and pick the next one.
39550+
*
39551+
* Returns 0 on match, WOLFSSL_FATAL_ERROR on mismatch. The caller
39552+
* is responsible for the policy on mismatch -- RFC 6066 Section 3
39553+
* mandates declining the resumption and proceeding with a full
39554+
* handshake rather than aborting. */
3952639555
int VerifyTicketBinding(WOLFSSL* ssl)
3952739556
{
3952839557
byte curHash[TICKET_BINDING_HASH_SZ];
3952939558

39530-
if (!ssl->options.resuming || !ssl->options.useTicket)
39559+
if (!ssl->options.resuming)
3953139560
return 0;
3953239561

3953339562
#ifdef HAVE_SNI
@@ -40036,8 +40065,9 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
4003640065
ssl->sessionCtxSz) != 0))
4003740066
return WOLFSSL_FATAL_ERROR;
4003840067
#endif
40039-
/* SNI/ALPN binding is verified after ALPN_Select via
40040-
* VerifyTicketBinding(). */
40068+
/* SNI/ALPN binding is checked by the per-PSK loop in
40069+
* DoPreSharedKeys, not here, so that mismatching PSKs can be
40070+
* skipped in favor of the next candidate. */
4004140071
return 0;
4004240072
}
4004340073
#endif /* WOLFSSL_SLT13 */
@@ -40133,8 +40163,13 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
4013340163
}
4013440164
}
4013540165
#endif
40136-
/* Carry the ticket bindings on the session for the deferred
40137-
* VerifyTicketBinding() check. */
40166+
/* Carry the ticket bindings on the session. TLS 1.2 uses these
40167+
* for the deferred VerifyTicketBinding() check in DoClientHello
40168+
* (SNI/ALPN aren't known when DoClientTicket runs during
40169+
* extension parsing). TLS 1.3 checks bindings per-PSK before
40170+
* reaching this point, but still copies them so a subsequent
40171+
* SetupSession on a resumed session preserves them in the cache
40172+
* for future resumptions. */
4013840173
#ifdef HAVE_SNI
4013940174
XMEMCPY(ssl->session->sniHash, it->sniHash, TICKET_BINDING_HASH_SZ);
4014040175
#endif
@@ -40500,8 +40535,9 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
4050040535
goto cleanup;
4050140536
}
4050240537

40503-
/* SNI/ALPN binding is verified after ALPN_Select via
40504-
* VerifyTicketBinding(). */
40538+
/* SNI/ALPN binding is verified later in DoClientHello via
40539+
* VerifyTicketBinding(), once extension parsing and ALPN_Select
40540+
* have run and the negotiated values are available. */
4050540541
DoClientTicketFinalize(ssl, it, NULL);
4050640542

4050740543
cleanup:

src/tls13.c

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6429,6 +6429,37 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz,
64296429
}
64306430
#endif
64316431
ret = DoClientTicketCheck(ssl, current, ssl->timeout, suite);
6432+
#if defined(HAVE_SNI) || defined(HAVE_ALPN)
6433+
if (ret == 0) {
6434+
/* Decline this PSK if the SNI/ALPN bound to the ticket
6435+
* does not match the current connection. RFC 6066 Sect.
6436+
* 3 mandates this for SNI; wolfSSL applies the same
6437+
* policy to ALPN as defense in depth. Skipping the PSK
6438+
* (rather than aborting) lets the server try the next
6439+
* candidate or fall back to a full handshake naturally
6440+
* without unwinding committed PSK state. ALPN_Select
6441+
* has already run earlier in DoTls13ClientHello so the
6442+
* negotiated ALPN is available to TicketAlpnHash. */
6443+
byte curHash[TICKET_BINDING_HASH_SZ];
6444+
#ifdef HAVE_SNI
6445+
if (TicketSniHash(ssl, curHash) != 0 ||
6446+
XMEMCMP(curHash, current->it->sniHash,
6447+
TICKET_BINDING_HASH_SZ) != 0) {
6448+
WOLFSSL_MSG("Ticket SNI mismatch, skipping PSK");
6449+
ret = WOLFSSL_FATAL_ERROR;
6450+
}
6451+
#endif
6452+
#ifdef HAVE_ALPN
6453+
if (ret == 0 &&
6454+
(TicketAlpnHash(ssl, curHash) != 0 ||
6455+
XMEMCMP(curHash, current->it->alpnHash,
6456+
TICKET_BINDING_HASH_SZ) != 0)) {
6457+
WOLFSSL_MSG("Ticket ALPN mismatch, skipping PSK");
6458+
ret = WOLFSSL_FATAL_ERROR;
6459+
}
6460+
#endif
6461+
}
6462+
#endif
64326463
if (ret == 0)
64336464
DoClientTicketFinalize(ssl, current->it, current->sess);
64346465
if (current->sess_free_cb != NULL) {
@@ -6592,11 +6623,11 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
65926623
return ret;
65936624
}
65946625

6595-
/* Extensions pushed on stack/list and PSK must be last. */
6596-
if (ssl->extensions != ext) {
6597-
WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
6598-
return PSK_KEY_ERROR;
6599-
}
6626+
/* Wire-order check that PSK was the last extension in ClientHello is
6627+
* performed in DoTls13ClientHello immediately after TLSX_Parse, since
6628+
* post-parse code (e.g. ALPN_Select via TLSX_SetALPN) may legitimately
6629+
* prepend new entries to ssl->extensions before this point and would
6630+
* otherwise trip a head-of-list check here. */
66006631

66016632
/* Assume we are going to resume with a pre-shared key. */
66026633
ssl->options.resuming = 1;
@@ -7562,6 +7593,25 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
75627593
goto exit_dch;
75637594
}
75647595

7596+
#if (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) && \
7597+
defined(HAVE_TLS_EXTENSIONS)
7598+
/* RFC 8446 Section 4.2.11: the pre_shared_key extension MUST be the
7599+
* last extension in the ClientHello. wolfSSL stores extensions in
7600+
* reverse wire order (TLSX_Push prepends), so a well-formed
7601+
* ClientHello with PSK leaves PSK at the head of ssl->extensions
7602+
* here, before any post-parse code (e.g. ALPN_Select) modifies the
7603+
* list. */
7604+
{
7605+
TLSX* pskExt = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
7606+
if (pskExt != NULL && ssl->extensions != pskExt) {
7607+
WOLFSSL_MSG("pre_shared_key extension was not last in "
7608+
"ClientHello");
7609+
WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
7610+
ERROR_OUT(PSK_KEY_ERROR, exit_dch);
7611+
}
7612+
}
7613+
#endif
7614+
75657615
#if defined(HAVE_ECH)
75667616
if (!ssl->options.echProcessingInner && echX != NULL &&
75677617
((WOLFSSL_ECH*)echX->data)->state == ECH_WRITE_NONE) {
@@ -7671,6 +7721,15 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
76717721
}
76727722
#endif
76737723

7724+
#ifdef HAVE_ALPN
7725+
/* Select the ALPN protocol before PSK selection so that the
7726+
* selected value is available to the per-PSK SNI/ALPN binding check
7727+
* inside CheckPreSharedKeys/DoPreSharedKeys. ALPN_Select itself
7728+
* only inspects ssl->extensions and the app callback; it does not
7729+
* depend on any state set during PSK validation. */
7730+
if ((ret = ALPN_Select(ssl)) != 0)
7731+
goto exit_dch;
7732+
#endif
76747733
#if (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) && \
76757734
defined(HAVE_TLS_EXTENSIONS)
76767735
ret = CheckPreSharedKeys(ssl, input + args->begin, helloSz, ssl->clSuites,
@@ -7712,16 +7771,6 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
77127771
#endif
77137772
}
77147773

7715-
#ifdef HAVE_ALPN
7716-
/* With PSK and all other things validated, it's time to
7717-
* select the ALPN protocol, if so requested */
7718-
if ((ret = ALPN_Select(ssl)) != 0)
7719-
goto exit_dch;
7720-
#endif
7721-
#if defined(HAVE_SESSION_TICKET) && (defined(HAVE_SNI) || defined(HAVE_ALPN))
7722-
if ((ret = VerifyTicketBinding(ssl)) != 0)
7723-
goto exit_dch;
7724-
#endif
77257774
} /* case TLS_ASYNC_BEGIN */
77267775
FALL_THROUGH;
77277776

tests/api/test_tls.c

Lines changed: 142 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -907,8 +907,9 @@ int test_tls_set_session_min_downgrade(void)
907907
}
908908

909909
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
910-
!defined(WOLFSSL_NO_TLS12) && defined(HAVE_SNI) && \
911-
defined(HAVE_SESSION_TICKET) && !defined(NO_SESSION_CACHE)
910+
(!defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13)) && \
911+
defined(HAVE_SNI) && defined(HAVE_SESSION_TICKET) && \
912+
!defined(NO_SESSION_CACHE)
912913
/* Accept-all SNI callback. */
913914
static int accept_any_sni_cb(WOLFSSL* ssl, int* ret, void* arg)
914915
{
@@ -988,6 +989,145 @@ int test_tls12_session_id_resumption_sni_mismatch(void)
988989
return EXPECT_RESULT();
989990
}
990991

992+
/* TLS 1.3 PSK resumption must fall back to a full handshake if the SNI in
993+
* the resumed ClientHello does not match the SNI bound to the original
994+
* session (RFC 6066 Section 3 / RFC 8446 Section 4.6.1). */
995+
int test_tls13_session_resumption_sni_mismatch(void)
996+
{
997+
EXPECT_DECLS;
998+
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
999+
defined(HAVE_SNI) && defined(HAVE_SESSION_TICKET) && \
1000+
!defined(NO_SESSION_CACHE)
1001+
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
1002+
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
1003+
WOLFSSL_SESSION *sess = NULL;
1004+
struct test_memio_ctx test_ctx;
1005+
const char* sniA = "public.example";
1006+
const char* sniB = "admin.example";
1007+
byte readBuf[16];
1008+
1009+
/* Step 1: full TLS 1.3 handshake under SNI=public.example to obtain a
1010+
* session ticket. The server-side SNI callback ensures ssl->extensions
1011+
* retains the client's SNI in builds that don't compile in
1012+
* WOLFSSL_ALWAYS_KEEP_SNI. */
1013+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
1014+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
1015+
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
1016+
wolfSSL_CTX_set_servername_callback(ctx_s, accept_any_sni_cb);
1017+
ExpectIntEQ(wolfSSL_UseSNI(ssl_c, WOLFSSL_SNI_HOST_NAME,
1018+
sniA, (word16)XSTRLEN(sniA)), WOLFSSL_SUCCESS);
1019+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
1020+
/* Sanity: the first handshake was not a resumption. */
1021+
ExpectIntEQ(wolfSSL_session_reused(ssl_s), 0);
1022+
/* Drive the post-handshake NewSessionTicket through to the client so
1023+
* the saved session is a real resumption ticket. */
1024+
ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), -1);
1025+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
1026+
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
1027+
1028+
wolfSSL_free(ssl_c); ssl_c = NULL;
1029+
wolfSSL_free(ssl_s); ssl_s = NULL;
1030+
1031+
/* Step 2: new SSL objects on the SAME WOLFSSL_CTX (so the server's
1032+
* ticket key still matches). The client offers the saved session but
1033+
* advertises a *different* SNI. The server MUST NOT resume because the
1034+
* SNI differs from the original. */
1035+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
1036+
ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
1037+
wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
1038+
wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
1039+
ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
1040+
wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
1041+
wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
1042+
ExpectIntEQ(wolfSSL_UseSNI(ssl_c, WOLFSSL_SNI_HOST_NAME,
1043+
sniB, (word16)XSTRLEN(sniB)), WOLFSSL_SUCCESS);
1044+
ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
1045+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
1046+
1047+
/* Desired behavior: server falls back to a full handshake because the
1048+
* SNI in the ClientHello does not match the SNI bound to the cached
1049+
* ticket. Both sides should report no resumption. */
1050+
ExpectIntEQ(wolfSSL_session_reused(ssl_s), 0);
1051+
ExpectIntEQ(wolfSSL_session_reused(ssl_c), 0);
1052+
1053+
wolfSSL_SESSION_free(sess);
1054+
wolfSSL_free(ssl_c);
1055+
wolfSSL_free(ssl_s);
1056+
wolfSSL_CTX_free(ctx_c);
1057+
wolfSSL_CTX_free(ctx_s);
1058+
#endif
1059+
return EXPECT_RESULT();
1060+
}
1061+
1062+
/* Regression test for the post-ALPN_Select PSK-head check.
1063+
* When ALPN_Select runs before CheckPreSharedKeys (so the per-PSK
1064+
* binding check has the negotiated ALPN available), TLSX_SetALPN
1065+
* prepends a new ALPN entry to ssl->extensions, displacing the PSK
1066+
* extension from the head of the list. The "PSK was last in
1067+
* ClientHello" check therefore must run right after TLSX_Parse,
1068+
* not inside CheckPreSharedKeys. This test exercises that path
1069+
* (TLS 1.3 PSK resumption with ALPN, no SNI callback -- the grpc
1070+
* server scenario). */
1071+
int test_tls13_resumption_with_alpn(void)
1072+
{
1073+
EXPECT_DECLS;
1074+
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
1075+
defined(HAVE_SNI) && defined(HAVE_ALPN) && defined(HAVE_SESSION_TICKET) && \
1076+
!defined(NO_SESSION_CACHE)
1077+
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
1078+
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
1079+
WOLFSSL_SESSION *sess = NULL;
1080+
struct test_memio_ctx test_ctx;
1081+
const char* sni = "foo.test.google.fr";
1082+
const char alpn[] = "h2";
1083+
byte readBuf[16];
1084+
1085+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
1086+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
1087+
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
1088+
ExpectIntEQ(wolfSSL_UseSNI(ssl_c, WOLFSSL_SNI_HOST_NAME,
1089+
sni, (word16)XSTRLEN(sni)), WOLFSSL_SUCCESS);
1090+
ExpectIntEQ(wolfSSL_UseALPN(ssl_c, (char*)alpn, (word32)XSTRLEN(alpn),
1091+
WOLFSSL_ALPN_FAILED_ON_MISMATCH), WOLFSSL_SUCCESS);
1092+
ExpectIntEQ(wolfSSL_UseALPN(ssl_s, (char*)alpn, (word32)XSTRLEN(alpn),
1093+
WOLFSSL_ALPN_FAILED_ON_MISMATCH), WOLFSSL_SUCCESS);
1094+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
1095+
ExpectIntEQ(wolfSSL_session_reused(ssl_s), 0);
1096+
ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), -1);
1097+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
1098+
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
1099+
1100+
wolfSSL_free(ssl_c); ssl_c = NULL;
1101+
wolfSSL_free(ssl_s); ssl_s = NULL;
1102+
1103+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
1104+
ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
1105+
wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
1106+
wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
1107+
ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
1108+
wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
1109+
wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
1110+
ExpectIntEQ(wolfSSL_UseSNI(ssl_c, WOLFSSL_SNI_HOST_NAME,
1111+
sni, (word16)XSTRLEN(sni)), WOLFSSL_SUCCESS);
1112+
ExpectIntEQ(wolfSSL_UseALPN(ssl_c, (char*)alpn, (word32)XSTRLEN(alpn),
1113+
WOLFSSL_ALPN_FAILED_ON_MISMATCH), WOLFSSL_SUCCESS);
1114+
ExpectIntEQ(wolfSSL_UseALPN(ssl_s, (char*)alpn, (word32)XSTRLEN(alpn),
1115+
WOLFSSL_ALPN_FAILED_ON_MISMATCH), WOLFSSL_SUCCESS);
1116+
ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
1117+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
1118+
1119+
ExpectIntEQ(wolfSSL_session_reused(ssl_s), 1);
1120+
ExpectIntEQ(wolfSSL_session_reused(ssl_c), 1);
1121+
1122+
wolfSSL_SESSION_free(sess);
1123+
wolfSSL_free(ssl_c);
1124+
wolfSSL_free(ssl_s);
1125+
wolfSSL_CTX_free(ctx_c);
1126+
wolfSSL_CTX_free(ctx_s);
1127+
#endif
1128+
return EXPECT_RESULT();
1129+
}
1130+
9911131
int test_tls_set_curves_list_ecc_fallback(void)
9921132
{
9931133
EXPECT_DECLS;

tests/api/test_tls.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ int test_tls12_no_null_compression(void);
3434
int test_tls12_etm_failed_resumption(void);
3535
int test_tls_set_session_min_downgrade(void);
3636
int test_tls12_session_id_resumption_sni_mismatch(void);
37+
int test_tls13_session_resumption_sni_mismatch(void);
38+
int test_tls13_resumption_with_alpn(void);
3739
int test_tls_set_curves_list_ecc_fallback(void);
3840
int test_tls12_corrupted_finished(void);
3941
int test_tls12_peerauth_failsafe(void);
@@ -53,6 +55,8 @@ int test_wolfSSL_alert_desc_string(void);
5355
TEST_DECL_GROUP("tls", test_tls12_etm_failed_resumption), \
5456
TEST_DECL_GROUP("tls", test_tls_set_session_min_downgrade), \
5557
TEST_DECL_GROUP("tls", test_tls12_session_id_resumption_sni_mismatch), \
58+
TEST_DECL_GROUP("tls", test_tls13_session_resumption_sni_mismatch), \
59+
TEST_DECL_GROUP("tls", test_tls13_resumption_with_alpn), \
5660
TEST_DECL_GROUP("tls", test_tls_set_curves_list_ecc_fallback), \
5761
TEST_DECL_GROUP("tls", test_tls12_corrupted_finished), \
5862
TEST_DECL_GROUP("tls", test_tls12_peerauth_failsafe), \

0 commit comments

Comments
 (0)