mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 20:24:39 +02:00
Merge pull request #8979 from anhu/abort_on_bad_legacy
Abort TLS connection if legacy version field is TLS 1.3 or higher
This commit is contained in:
@@ -614,6 +614,7 @@ WOLFSSL_AESNI_BY6
|
||||
WOLFSSL_AES_CTR_EXAMPLE
|
||||
WOLFSSL_AFTER_DATE_CLOCK_SKEW
|
||||
WOLFSSL_ALGO_HW_MUTEX
|
||||
WOLFSSL_ALLOW_BAD_TLS_LEGACY_VERSION
|
||||
WOLFSSL_ALLOW_CRIT_AIA
|
||||
WOLFSSL_ALLOW_CRIT_AKID
|
||||
WOLFSSL_ALLOW_CRIT_SKID
|
||||
|
17
src/tls13.c
17
src/tls13.c
@@ -6826,6 +6826,23 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
|
||||
if (!ssl->options.dtls) {
|
||||
#ifndef WOLFSSL_ALLOW_BAD_TLS_LEGACY_VERSION
|
||||
/* Check for TLS 1.3 version (0x0304) in legacy version field. RFC 8446
|
||||
* Section 4.2.1 allows this action:
|
||||
*
|
||||
* "Servers MAY abort the handshake upon receiving a ClientHello with
|
||||
* legacy_version 0x0304 or later."
|
||||
*
|
||||
* Note that if WOLFSSL_ALLOW_BAD_TLS_LEGACY_VERSION is defined then the
|
||||
* semantics of RFC 5246 Appendix E will be followed. A ServerHello with
|
||||
* version 1.2 will be sent. The same is true if TLS 1.3 is not enabled.
|
||||
*/
|
||||
if (args->pv.major == SSLv3_MAJOR && args->pv.minor >= TLSv1_3_MINOR) {
|
||||
WOLFSSL_MSG("Legacy version field is TLS 1.3 or later. Aborting.");
|
||||
ERROR_OUT(VERSION_ERROR, exit_dch);
|
||||
}
|
||||
#endif /* WOLFSSL_ALLOW_BAD_TLS_LEGACY_VERSION */
|
||||
|
||||
/* Legacy protocol version cannot negotiate TLS 1.3 or higher. */
|
||||
if (args->pv.major > SSLv3_MAJOR || (args->pv.major == SSLv3_MAJOR &&
|
||||
args->pv.minor >= TLSv1_3_MINOR)) {
|
||||
|
82
tests/api.c
82
tests/api.c
@@ -13348,6 +13348,87 @@ static int test_tls_ext_duplicate(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
|
||||
/* Test TLS connection abort when legacy version field indicates TLS 1.3 or
|
||||
* higher. Based on test_tls_ext_duplicate() but with legacy version modified
|
||||
* to 0x0304.
|
||||
*/
|
||||
static int test_tls_bad_legacy_version(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_ALLOW_BAD_TLS_LEGACY_VERSION)
|
||||
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS) && \
|
||||
!defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
|
||||
/* This is exactly the same as the buffer in test_tls_ext_duplicate() except
|
||||
* the 11th byte is set to 0x04. That change means the legacy protocol
|
||||
* version field is invalid. That will be caught before the dulplicate
|
||||
* signature algorithms extension. */
|
||||
const unsigned char clientHelloBadLegacyVersion[] = {
|
||||
0x16, 0x03, 0x03, 0x00, 0x6a, 0x01, 0x00, 0x00,
|
||||
0x66, 0x03, 0x04, 0xf4, 0x65, 0xbd, 0x22, 0xfe,
|
||||
0x6e, 0xab, 0x66, 0xdd, 0xcf, 0xe9, 0x65, 0x55,
|
||||
0xe8, 0xdf, 0xc3, 0x8e, 0x4b, 0x00, 0xbc, 0xf8,
|
||||
0x23, 0x57, 0x1b, 0xa0, 0xc8, 0xa9, 0xe2, 0x8c,
|
||||
0x91, 0x6e, 0xf9, 0x20, 0xf7, 0x5c, 0xc5, 0x5b,
|
||||
0x75, 0x8c, 0x47, 0x0a, 0x0e, 0xc4, 0x1a, 0xda,
|
||||
0xef, 0x75, 0xe5, 0x21, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x13, 0x01,
|
||||
0x00, 0x9e, 0x01, 0x00,
|
||||
/* Extensions - duplicate signature algorithms. */
|
||||
0x00, 0x19, 0x00, 0x0d,
|
||||
0x00, 0x04, 0x00, 0x02, 0x04, 0x01, 0x00, 0x0d,
|
||||
0x00, 0x04, 0x00, 0x02, 0x04, 0x01,
|
||||
/* Supported Versions extension for TLS 1.3. */
|
||||
0x00, 0x2b,
|
||||
0x00, 0x05, 0x04, 0x03, 0x04, 0x03, 0x03
|
||||
};
|
||||
|
||||
WOLFSSL_BUFFER_INFO msg;
|
||||
const char* testCertFile;
|
||||
const char* testKeyFile;
|
||||
WOLFSSL_CTX *ctx = NULL;
|
||||
WOLFSSL *ssl = NULL;
|
||||
|
||||
#ifndef NO_RSA
|
||||
testCertFile = svrCertFile;
|
||||
testKeyFile = svrKeyFile;
|
||||
#elif defined(HAVE_ECC)
|
||||
testCertFile = eccCertFile;
|
||||
testKeyFile = eccKeyFile;
|
||||
#endif
|
||||
|
||||
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
|
||||
|
||||
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
|
||||
/* Read from 'msg'. */
|
||||
wolfSSL_SetIORecv(ctx, BufferInfoRecv);
|
||||
/* No where to send to - dummy sender. */
|
||||
wolfSSL_SetIOSend(ctx, DummySend);
|
||||
|
||||
ssl = wolfSSL_new(ctx);
|
||||
ExpectNotNull(ssl);
|
||||
|
||||
msg.buffer = (unsigned char*)clientHelloBadLegacyVersion;
|
||||
msg.length = (unsigned int)sizeof(clientHelloBadLegacyVersion);
|
||||
wolfSSL_SetIOReadCtx(ssl, &msg);
|
||||
|
||||
ExpectIntNE(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
|
||||
/* Connection should fail due to bad legacy version field. When that
|
||||
* happens the return code is VERSION_ERROR but that gets transformed into
|
||||
* SOCKET_ERROR_E. */
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl, 0), WC_NO_ERR_TRACE(SOCKET_ERROR_E));
|
||||
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
#endif
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
/*----------------------------------------------------------------------------*
|
||||
| X509 Tests
|
||||
*----------------------------------------------------------------------------*/
|
||||
@@ -68795,6 +68876,7 @@ TEST_DECL(test_wc_RsaPSS_DigitalSignVerify),
|
||||
TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
|
||||
TEST_DECL(test_wolfSSL_SCR_Reconnect),
|
||||
TEST_DECL(test_tls_ext_duplicate),
|
||||
TEST_DECL(test_tls_bad_legacy_version),
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
|
||||
defined(HAVE_IO_TESTS_DEPENDENCIES)
|
||||
TEST_DECL(test_wolfSSL_Tls13_ECH_params),
|
||||
|
Reference in New Issue
Block a user