mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 18:40:49 +02:00
verify ciphersuite in CH2 matches HRR
This commit is contained in:
+24
-2
@@ -6635,8 +6635,10 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie)
|
||||
hrrIdx += ssl->session->sessionIDSz;
|
||||
}
|
||||
|
||||
/* Cipher Suite */
|
||||
/* Restore the cipher suite from the cookie. */
|
||||
ssl->options.hrrCipherSuite0 = cookieData[idx];
|
||||
hrr[hrrIdx++] = cookieData[idx++];
|
||||
ssl->options.hrrCipherSuite = cookieData[idx];
|
||||
hrr[hrrIdx++] = cookieData[idx++];
|
||||
|
||||
/* Compression not supported in TLS v1.3. */
|
||||
@@ -7350,6 +7352,21 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Verify the cipher suite is the same as what was chosen in HRR.
|
||||
* got_client_hello == 2 covers the stateful path.
|
||||
* cookieGood covers the stateless DTLS path. */
|
||||
if ((ssl->msgsReceived.got_client_hello == 2
|
||||
#ifdef WOLFSSL_SEND_HRR_COOKIE
|
||||
|| ssl->options.cookieGood
|
||||
#endif
|
||||
) &&
|
||||
(ssl->options.cipherSuite0 != ssl->options.hrrCipherSuite0 ||
|
||||
ssl->options.cipherSuite != ssl->options.hrrCipherSuite)) {
|
||||
WOLFSSL_MSG("Cipher suite in second ClientHello does not match "
|
||||
"HelloRetryRequest");
|
||||
ERROR_OUT(INVALID_PARAMETER, exit_dch);
|
||||
}
|
||||
|
||||
/* Advance state and proceed */
|
||||
ssl->options.asyncState = TLS_ASYNC_VERIFY;
|
||||
} /* case TLS_ASYNC_BUILD || TLS_ASYNC_DO */
|
||||
@@ -7657,7 +7674,9 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
|
||||
* In case of stateless DTLS, we do not store the group, however, as it is
|
||||
* already stored in the cookie that is sent to the client. We later recover
|
||||
* the group from the cookie to prevent storing a state in a stateless
|
||||
* server. */
|
||||
* server.
|
||||
*
|
||||
* Similar logic holds for the hrrCipherSuite. */
|
||||
if (extMsgType == hello_retry_request
|
||||
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
|
||||
&& (!ssl->options.dtls || ssl->options.dtlsStateful)
|
||||
@@ -7669,6 +7688,9 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
|
||||
if (kse != NULL)
|
||||
ssl->hrr_keyshare_group = kse->group;
|
||||
}
|
||||
|
||||
ssl->options.hrrCipherSuite0 = ssl->options.cipherSuite0;
|
||||
ssl->options.hrrCipherSuite = ssl->options.cipherSuite;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SEND_HRR_COOKIE
|
||||
|
||||
@@ -2542,6 +2542,129 @@ int test_tls13_hrr_different_cs(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Server-side complement to test_tls13_hrr_different_cs: the client sends a
|
||||
* different cipher suite in CH2 than what the server selected in the HRR. */
|
||||
int test_tls13_ch2_different_cs(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
defined(BUILD_TLS_AES_256_GCM_SHA384) && \
|
||||
defined(BUILD_TLS_AES_128_GCM_SHA256) && \
|
||||
defined(HAVE_ECC) && defined(HAVE_ECC384)
|
||||
/*
|
||||
* First ClientHello: cipher suite TLS_AES_256_GCM_SHA384 (0x1302),
|
||||
* empty key_share, secp384r1 in supported_groups. This triggers the
|
||||
* server to send a HelloRetryRequest selecting TLS_AES_256_GCM_SHA384
|
||||
* and requesting a secp384r1 key share.
|
||||
*/
|
||||
/*
|
||||
* TLSv1.3 Record Layer: Handshake Protocol: Client Hello
|
||||
* Content Type: Handshake (22)
|
||||
* Version: TLS 1.2 (0x0303)
|
||||
* Length: 110
|
||||
* Handshake Protocol: Client Hello
|
||||
* Handshake Type: Client Hello (1)
|
||||
* Length: 106
|
||||
* Version: TLS 1.2 (0x0303)
|
||||
* Random: 0101010101010101010101010101010101010101010101010101010101010101
|
||||
* Session ID Length: 32
|
||||
* Session ID: 0303030303030303030303030303030303030303030303030303030303030303
|
||||
* Cipher Suites Length: 2
|
||||
* Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
|
||||
* Compression Methods Length: 1
|
||||
* Compression Method: null (0)
|
||||
* Extensions Length: 31
|
||||
* Extension: supported_groups (len=4) secp384r1 (0x0018)
|
||||
* Extension: signature_algorithms (len=6) rsa_pkcs1_sha256 (0x0401),
|
||||
* rsa_pss_rsae_sha256 (0x0804)
|
||||
* Extension: key_share (len=2) client_shares length=0 (empty)
|
||||
* Extension: supported_versions (len=3) TLS 1.3 (0x0304)
|
||||
*/
|
||||
unsigned char ch1[] = {
|
||||
0x16, 0x03, 0x03, 0x00, 0x6e, 0x01, 0x00, 0x00, 0x6a, 0x03, 0x03, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x00, 0x02, 0x13, 0x02, 0x01, 0x00, 0x00, 0x1f,
|
||||
0x00, 0x0a, 0x00, 0x04, 0x00, 0x02, 0x00, 0x18, 0x00, 0x0d, 0x00, 0x06,
|
||||
0x00, 0x04, 0x04, 0x01, 0x08, 0x04, 0x00, 0x33, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00, 0x2b, 0x00, 0x03, 0x02, 0x03, 0x04
|
||||
};
|
||||
/*
|
||||
* TLSv1.3 Record Layer: Handshake Protocol: Client Hello
|
||||
* Content Type: Handshake (22)
|
||||
* Version: TLS 1.2 (0x0303)
|
||||
* Length: 211
|
||||
* Handshake Protocol: Client Hello
|
||||
* Handshake Type: Client Hello (1)
|
||||
* Length: 207
|
||||
* Version: TLS 1.2 (0x0303)
|
||||
* Random: 0101010101010101010101010101010101010101010101010101010101010101
|
||||
* Session ID Length: 32
|
||||
* Session ID: 0303030303030303030303030303030303030303030303030303030303030303
|
||||
* Cipher Suites Length: 2
|
||||
* Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
|
||||
* Compression Methods Length: 1
|
||||
* Compression Method: null (0)
|
||||
* Extensions Length: 132
|
||||
* Extension: supported_groups (len=4) secp384r1 (0x0018)
|
||||
* Extension: signature_algorithms (len=6) rsa_pkcs1_sha256 (0x0401),
|
||||
* rsa_pss_rsae_sha256 (0x0804)
|
||||
* Extension: key_share (len=103)
|
||||
* client_shares length: 101
|
||||
* KeyShareEntry: group secp384r1 (0x0018), key_exchange length: 97
|
||||
* key_exchange: 04 || X(48) || Y(48) (uncompressed P-384 point)
|
||||
* Extension: supported_versions (len=3) TLS 1.3 (0x0304)
|
||||
*/
|
||||
unsigned char ch2[] = {
|
||||
0x16, 0x03, 0x03, 0x00, 0xd3, 0x01, 0x00, 0x00, 0xcf, 0x03, 0x03, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x00, 0x02, 0x13, 0x01, 0x01, 0x00, 0x00, 0x84,
|
||||
0x00, 0x0a, 0x00, 0x04, 0x00, 0x02, 0x00, 0x18, 0x00, 0x0d, 0x00, 0x06,
|
||||
0x00, 0x04, 0x04, 0x01, 0x08, 0x04, 0x00, 0x33, 0x00, 0x67, 0x00, 0x65,
|
||||
0x00, 0x18, 0x00, 0x61, 0x04, 0x53, 0x3e, 0xe5, 0xbf, 0x40, 0xec, 0x2d,
|
||||
0x67, 0x98, 0x8b, 0x77, 0xf3, 0x17, 0x48, 0x9b, 0xb6, 0xdf, 0x95, 0x29,
|
||||
0x25, 0xc7, 0x09, 0xfc, 0x03, 0x81, 0x11, 0x1a, 0x59, 0x56, 0xf2, 0xd7,
|
||||
0x58, 0x11, 0x0e, 0x59, 0xd3, 0xd7, 0xc1, 0x72, 0x9e, 0x2c, 0x0d, 0x70,
|
||||
0xea, 0xf7, 0x73, 0xe6, 0x12, 0x01, 0x16, 0x42, 0x6d, 0xe2, 0x43, 0x6a,
|
||||
0x2f, 0x5f, 0xdd, 0x7f, 0xe5, 0x4f, 0xaf, 0x95, 0x2b, 0x04, 0xfd, 0x13,
|
||||
0xf5, 0x16, 0xce, 0x62, 0x7f, 0x89, 0xd2, 0x01, 0x9d, 0x4c, 0x87, 0x96,
|
||||
0x95, 0x9e, 0x43, 0x33, 0xc7, 0x06, 0x5b, 0x49, 0x6c, 0xa6, 0x34, 0xd5,
|
||||
0xdc, 0x63, 0xbd, 0xe9, 0x1f, 0x00, 0x2b, 0x00, 0x03, 0x02, 0x03, 0x04
|
||||
};
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, NULL, &ctx_s, NULL, &ssl_s,
|
||||
NULL, wolfTLSv1_3_server_method), 0);
|
||||
|
||||
/* Server reads CH1, sends HRR, then waits for CH2 */
|
||||
ExpectIntEQ(test_memio_inject_message(&test_ctx, 0, (char*)ch1,
|
||||
sizeof(ch1)), 0);
|
||||
ExpectIntEQ(wolfSSL_accept(ssl_s), -1);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
|
||||
|
||||
/* Server must reject CH2 because the cipher suite changed from the HRR */
|
||||
ExpectIntEQ(test_memio_inject_message(&test_ctx, 0, (char*)ch2,
|
||||
sizeof(ch2)), 0);
|
||||
ExpectIntEQ(wolfSSL_accept(ssl_s), -1);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), INVALID_PARAMETER);
|
||||
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
defined(HAVE_ECC)
|
||||
/* Called when writing. */
|
||||
|
||||
@@ -32,6 +32,7 @@ int test_tls13_pq_groups(void);
|
||||
int test_tls13_early_data(void);
|
||||
int test_tls13_same_ch(void);
|
||||
int test_tls13_hrr_different_cs(void);
|
||||
int test_tls13_ch2_different_cs(void);
|
||||
int test_tls13_sg_missing(void);
|
||||
int test_tls13_ks_missing(void);
|
||||
int test_tls13_duplicate_extension(void);
|
||||
@@ -51,6 +52,7 @@ int test_tls13_derive_keys_no_key(void);
|
||||
TEST_DECL_GROUP("tls13", test_tls13_early_data), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_same_ch), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_hrr_different_cs), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_ch2_different_cs), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_sg_missing), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_ks_missing), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_duplicate_extension), \
|
||||
|
||||
Reference in New Issue
Block a user