mirror of https://github.com/wolfSSL/wolfssl.git
TLS: detect duplicate known extensions
TLS specification requires that there not be more than one extension of the same type in a given extension block. E.g. ClientHellopull/5872/head
parent
c959d22b98
commit
9ab8867b42
|
@ -23355,6 +23355,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
|
||||||
case DTLS_TOO_MANY_FRAGMENTS_E:
|
case DTLS_TOO_MANY_FRAGMENTS_E:
|
||||||
return "Received too many fragmented messages from peer error";
|
return "Received too many fragmented messages from peer error";
|
||||||
|
|
||||||
|
case DUPLICATE_TLS_EXT_E:
|
||||||
|
return "Duplicate TLS extension in message.";
|
||||||
|
|
||||||
default :
|
default :
|
||||||
return "unknown error number";
|
return "unknown error number";
|
||||||
}
|
}
|
||||||
|
|
22
src/tls.c
22
src/tls.c
|
@ -1246,6 +1246,8 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
|
||||||
* When adding a new extension type that don't extrapolate the number of
|
* When adding a new extension type that don't extrapolate the number of
|
||||||
* available semaphores, check for a possible collision with with a
|
* available semaphores, check for a possible collision with with a
|
||||||
* 'remapped' extension type.
|
* 'remapped' extension type.
|
||||||
|
*
|
||||||
|
* Update TLSX_Parse for duplicate detection if more added above 62.
|
||||||
*/
|
*/
|
||||||
static WC_INLINE word16 TLSX_ToSemaphore(word16 type)
|
static WC_INLINE word16 TLSX_ToSemaphore(word16 type)
|
||||||
{
|
{
|
||||||
|
@ -11918,10 +11920,14 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
|
||||||
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
|
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
|
||||||
int pskDone = 0;
|
int pskDone = 0;
|
||||||
#endif
|
#endif
|
||||||
|
byte seenType[SEMAPHORE_SIZE]; /* Seen known extensions. */
|
||||||
|
|
||||||
if (!ssl || !input || (isRequest && !suites))
|
if (!ssl || !input || (isRequest && !suites))
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
/* No known extensions seen yet. */
|
||||||
|
XMEMSET(seenType, 0, sizeof(seenType));
|
||||||
|
|
||||||
while (ret == 0 && offset < length) {
|
while (ret == 0 && offset < length) {
|
||||||
word16 type;
|
word16 type;
|
||||||
word16 size;
|
word16 size;
|
||||||
|
@ -11942,6 +11948,22 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
|
||||||
ato16(input + offset, &size);
|
ato16(input + offset, &size);
|
||||||
offset += OPAQUE16_LEN;
|
offset += OPAQUE16_LEN;
|
||||||
|
|
||||||
|
/* Check we have a bit for extension type. */
|
||||||
|
if ((type <= 62) || (type == TLSX_RENEGOTIATION_INFO)
|
||||||
|
#ifdef WOLFSSL_QUIC
|
||||||
|
|| (type == TLSX_KEY_QUIC_TP_PARAMS_DRAFT)
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Detect duplicate recognized extensions. */
|
||||||
|
if (IS_OFF(seenType, TLSX_ToSemaphore(type))) {
|
||||||
|
TURN_ON(seenType, TLSX_ToSemaphore(type));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return DUPLICATE_TLS_EXT_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (length - offset < size)
|
if (length - offset < size)
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
|
108
tests/api.c
108
tests/api.c
|
@ -9132,6 +9132,113 @@ static int test_wolfSSL_wolfSSL_UseSecureRenegotiation(void)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(NO_WOLFSSL_SERVER) && (!defined(NO_RSA) || defined(HAVE_ECC))
|
||||||
|
/* Called when writing. */
|
||||||
|
static int DummySend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
|
||||||
|
{
|
||||||
|
(void)ssl;
|
||||||
|
(void)buf;
|
||||||
|
(void)sz;
|
||||||
|
(void)ctx;
|
||||||
|
|
||||||
|
/* Force error return from wolfSSL_accept_TLSv13(). */
|
||||||
|
return WANT_WRITE;
|
||||||
|
}
|
||||||
|
/* Called when reading. */
|
||||||
|
static int BufferInfoRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
|
||||||
|
{
|
||||||
|
WOLFSSL_BUFFER_INFO* msg = (WOLFSSL_BUFFER_INFO*)ctx;
|
||||||
|
int len = (int)msg->length;
|
||||||
|
|
||||||
|
(void)ssl;
|
||||||
|
(void)sz;
|
||||||
|
|
||||||
|
/* Pass back as much of message as will fit in buffer. */
|
||||||
|
if (len > sz)
|
||||||
|
len = sz;
|
||||||
|
XMEMCPY(buf, msg->buffer, len);
|
||||||
|
/* Move over returned data. */
|
||||||
|
msg->buffer += len;
|
||||||
|
msg->length -= len;
|
||||||
|
|
||||||
|
/* Amount actually copied. */
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Test the detection of duplicate known TLS extensions.
|
||||||
|
* Specifically in a ClientHello.
|
||||||
|
*/
|
||||||
|
static int test_tls_ext_duplicate(void)
|
||||||
|
{
|
||||||
|
int res = TEST_SKIPPED;
|
||||||
|
#if !defined(NO_WOLFSSL_SERVER) && (!defined(NO_RSA) || defined(HAVE_ECC))
|
||||||
|
static unsigned char clientHelloDupTlsExt[] = {
|
||||||
|
0x16, 0x03, 0x03, 0x00, 0x6a, 0x01, 0x00, 0x00,
|
||||||
|
0x66, 0x03, 0x03, 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;
|
||||||
|
WOLFSSL *ssl;
|
||||||
|
|
||||||
|
#ifndef NO_RSA
|
||||||
|
testCertFile = svrCertFile;
|
||||||
|
testKeyFile = svrKeyFile;
|
||||||
|
#elif defined(HAVE_ECC)
|
||||||
|
testCertFile = eccCertFile;
|
||||||
|
testKeyFile = eccKeyFile;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
|
||||||
|
AssertNotNull(ctx);
|
||||||
|
|
||||||
|
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
|
||||||
|
WOLFSSL_FILETYPE_PEM));
|
||||||
|
AssertTrue(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);
|
||||||
|
AssertNotNull(ssl);
|
||||||
|
|
||||||
|
msg.buffer = clientHelloDupTlsExt;
|
||||||
|
msg.length = (unsigned int)sizeof(clientHelloDupTlsExt);
|
||||||
|
wolfSSL_SetIOReadCtx(ssl, &msg);
|
||||||
|
|
||||||
|
AssertIntNE(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
|
||||||
|
AssertIntEQ(wolfSSL_get_error(ssl, 0), DUPLICATE_TLS_EXT_E);
|
||||||
|
|
||||||
|
wolfSSL_free(ssl);
|
||||||
|
wolfSSL_CTX_free(ctx);
|
||||||
|
|
||||||
|
res = TEST_RES_CHECK(1);
|
||||||
|
#endif
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
| X509 Tests
|
| X509 Tests
|
||||||
|
@ -59358,6 +59465,7 @@ TEST_CASE testCases[] = {
|
||||||
#endif
|
#endif
|
||||||
TEST_DECL(test_wolfSSL_DisableExtendedMasterSecret),
|
TEST_DECL(test_wolfSSL_DisableExtendedMasterSecret),
|
||||||
TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
|
TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
|
||||||
|
TEST_DECL(test_tls_ext_duplicate),
|
||||||
|
|
||||||
/* X509 tests */
|
/* X509 tests */
|
||||||
TEST_DECL(test_wolfSSL_X509_NAME_get_entry),
|
TEST_DECL(test_wolfSSL_X509_NAME_get_entry),
|
||||||
|
|
|
@ -181,6 +181,8 @@ enum wolfSSL_ErrorCodes {
|
||||||
DTLS_CID_ERROR = -454, /* Wrong or missing CID */
|
DTLS_CID_ERROR = -454, /* Wrong or missing CID */
|
||||||
DTLS_TOO_MANY_FRAGMENTS_E = -455, /* Received too many fragments */
|
DTLS_TOO_MANY_FRAGMENTS_E = -455, /* Received too many fragments */
|
||||||
QUIC_WRONG_ENC_LEVEL = -456, /* QUIC data received on wrong encryption level */
|
QUIC_WRONG_ENC_LEVEL = -456, /* QUIC data received on wrong encryption level */
|
||||||
|
|
||||||
|
DUPLICATE_TLS_EXT_E = -457, /* Duplicate TLS extension in msg. */
|
||||||
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
|
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
|
||||||
|
|
||||||
/* begin negotiation parameter errors */
|
/* begin negotiation parameter errors */
|
||||||
|
|
Loading…
Reference in New Issue