Skip to content

Commit b4ee886

Browse files
authored
Merge pull request #9246 from julek-wolfssl/gh/9240
Abort connection if we are about to send the same CH
2 parents 1932c5a + f798a58 commit b4ee886

File tree

6 files changed

+85
-2
lines changed

6 files changed

+85
-2
lines changed

src/ssl.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14316,6 +14316,12 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
1431614316
ssl->options.haveSessionId = 0;
1431714317
ssl->options.tls = 0;
1431814318
ssl->options.tls1_1 = 0;
14319+
#ifdef WOLFSSL_TLS13
14320+
#ifdef WOLFSSL_SEND_HRR_COOKIE
14321+
ssl->options.hrrSentCookie = 0;
14322+
#endif
14323+
ssl->options.hrrSentKeyShare = 0;
14324+
#endif
1431914325
#ifdef WOLFSSL_DTLS
1432014326
ssl->options.dtlsStateful = 0;
1432114327
#endif

src/tls.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7318,9 +7318,11 @@ static int TLSX_Cookie_Parse(WOLFSSL* ssl, const byte* input, word16 length,
73187318
if (length - idx != len)
73197319
return BUFFER_E;
73207320

7321-
if (msgType == hello_retry_request)
7321+
if (msgType == hello_retry_request) {
7322+
ssl->options.hrrSentCookie = 1;
73227323
return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 1,
73237324
&ssl->extensions);
7325+
}
73247326

73257327
/* client_hello */
73267328
extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
@@ -10145,6 +10147,8 @@ int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input, word16 length,
1014510147
if (length != OPAQUE16_LEN)
1014610148
return BUFFER_ERROR;
1014710149

10150+
ssl->options.hrrSentKeyShare = 1;
10151+
1014810152
/* The data is the named group the server wants to use. */
1014910153
ato16(input, &group);
1015010154

src/tls13.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5635,6 +5635,21 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
56355635

56365636
}
56375637
else {
5638+
/* https://datatracker.ietf.org/doc/html/rfc8446#section-4.1.4
5639+
* Clients MUST abort the handshake with an
5640+
* "illegal_parameter" alert if the HelloRetryRequest would not result
5641+
* in any change in the ClientHello.
5642+
*/
5643+
/* Check if the HRR contained a cookie or a keyshare */
5644+
if (!ssl->options.hrrSentKeyShare
5645+
#ifdef WOLFSSL_SEND_HRR_COOKIE
5646+
&& !ssl->options.hrrSentCookie
5647+
#endif
5648+
) {
5649+
SendAlert(ssl, alert_fatal, illegal_parameter);
5650+
return DUPLICATE_MSG_E;
5651+
}
5652+
56385653
ssl->options.tls1_3 = 1;
56395654
ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
56405655

tests/api/test_tls13.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,3 +2141,53 @@ int test_tls13_early_data(void)
21412141
return EXPECT_RESULT();
21422142
}
21432143

2144+
2145+
/* Check that the client won't send the same CH after a HRR. An HRR without
2146+
* a KeyShare or a Cookie extension will trigger the error. */
2147+
int test_tls13_same_ch(void)
2148+
{
2149+
EXPECT_DECLS;
2150+
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
2151+
defined(WOLFSSL_TLS13) && defined(WOLFSSL_AES_128) && \
2152+
defined(HAVE_AESGCM) && !defined(NO_SHA256) && \
2153+
/* middlebox compat requires that the session ID is echoed */ \
2154+
!defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
2155+
WOLFSSL_CTX *ctx_c = NULL;
2156+
WOLFSSL *ssl_c = NULL;
2157+
struct test_memio_ctx test_ctx;
2158+
/* Transport Layer Security
2159+
* TLSv1.3 Record Layer: Handshake Protocol: Hello Retry Request
2160+
* Content Type: Handshake (22)
2161+
* Version: TLS 1.2 (0x0303)
2162+
* Length: 50
2163+
* Handshake Protocol: Hello Retry Request
2164+
* Handshake Type: Server Hello (2)
2165+
* Length: 46
2166+
* Version: TLS 1.2 (0x0303)
2167+
* Random: cf21ad74e59a6111be1d8c021e65b891c2a211167abb8c5e079e09e2c8a8339c (HelloRetryRequest magic)
2168+
* Session ID Length: 0
2169+
* Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
2170+
* Compression Method: null (0)
2171+
* Extensions Length: 6
2172+
* Extension: supported_versions (len=2) TLS 1.3 */
2173+
unsigned char hrr[] = {
2174+
0x16, 0x03, 0x03, 0x00, 0x32, 0x02, 0x00, 0x00, 0x2e, 0x03, 0x03, 0xcf,
2175+
0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e,
2176+
0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07,
2177+
0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, 0x00, 0x13, 0x01, 0x00, 0x00,
2178+
0x06, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04
2179+
};
2180+
2181+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
2182+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
2183+
wolfTLSv1_3_client_method, NULL), 0);
2184+
ExpectIntEQ(test_memio_inject_message(&test_ctx, 1, (char*)hrr,
2185+
sizeof(hrr)), 0);
2186+
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
2187+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), DUPLICATE_MSG_E);
2188+
2189+
wolfSSL_free(ssl_c);
2190+
wolfSSL_CTX_free(ctx_c);
2191+
#endif
2192+
return EXPECT_RESULT();
2193+
}

tests/api/test_tls13.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@ int test_tls13_bad_psk_binder(void);
3030
int test_tls13_rpk_handshake(void);
3131
int test_tls13_pq_groups(void);
3232
int test_tls13_early_data(void);
33+
int test_tls13_same_ch(void);
3334

3435
#define TEST_TLS13_DECLS \
3536
TEST_DECL_GROUP("tls13", test_tls13_apis), \
3637
TEST_DECL_GROUP("tls13", test_tls13_cipher_suites), \
3738
TEST_DECL_GROUP("tls13", test_tls13_bad_psk_binder), \
3839
TEST_DECL_GROUP("tls13", test_tls13_rpk_handshake), \
3940
TEST_DECL_GROUP("tls13", test_tls13_pq_groups), \
40-
TEST_DECL_GROUP("tls13", test_tls13_early_data)
41+
TEST_DECL_GROUP("tls13", test_tls13_early_data), \
42+
TEST_DECL_GROUP("tls13", test_tls13_same_ch)
4143

4244
#endif /* WOLFCRYPT_TEST_TLS13_H */

wolfssl/internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5061,6 +5061,12 @@ struct Options {
50615061
#if defined(HAVE_DANE)
50625062
word16 useDANE:1;
50635063
#endif /* HAVE_DANE */
5064+
#ifdef WOLFSSL_TLS13
5065+
#ifdef WOLFSSL_SEND_HRR_COOKIE
5066+
word16 hrrSentCookie:1; /* HRR sent with cookie */
5067+
#endif
5068+
word16 hrrSentKeyShare:1; /* HRR sent with key share */
5069+
#endif
50645070
word16 disableRead:1;
50655071
#ifdef WOLFSSL_DTLS
50665072
byte haveMcast; /* using multicast ? */

0 commit comments

Comments
 (0)