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:
|
||||
return "Received too many fragmented messages from peer error";
|
||||
|
||||
case DUPLICATE_TLS_EXT_E:
|
||||
return "Duplicate TLS extension in message.";
|
||||
|
||||
default :
|
||||
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
|
||||
* available semaphores, check for a possible collision with with a
|
||||
* 'remapped' extension type.
|
||||
*
|
||||
* Update TLSX_Parse for duplicate detection if more added above 62.
|
||||
*/
|
||||
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))
|
||||
int pskDone = 0;
|
||||
#endif
|
||||
byte seenType[SEMAPHORE_SIZE]; /* Seen known extensions. */
|
||||
|
||||
if (!ssl || !input || (isRequest && !suites))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* No known extensions seen yet. */
|
||||
XMEMSET(seenType, 0, sizeof(seenType));
|
||||
|
||||
while (ret == 0 && offset < length) {
|
||||
word16 type;
|
||||
word16 size;
|
||||
|
@ -11942,6 +11948,22 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
|
|||
ato16(input + offset, &size);
|
||||
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)
|
||||
return BUFFER_ERROR;
|
||||
|
||||
|
|
108
tests/api.c
108
tests/api.c
|
@ -9132,6 +9132,113 @@ static int test_wolfSSL_wolfSSL_UseSecureRenegotiation(void)
|
|||
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
|
||||
|
@ -59358,6 +59465,7 @@ TEST_CASE testCases[] = {
|
|||
#endif
|
||||
TEST_DECL(test_wolfSSL_DisableExtendedMasterSecret),
|
||||
TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
|
||||
TEST_DECL(test_tls_ext_duplicate),
|
||||
|
||||
/* X509 tests */
|
||||
TEST_DECL(test_wolfSSL_X509_NAME_get_entry),
|
||||
|
|
|
@ -181,6 +181,8 @@ enum wolfSSL_ErrorCodes {
|
|||
DTLS_CID_ERROR = -454, /* Wrong or missing CID */
|
||||
DTLS_TOO_MANY_FRAGMENTS_E = -455, /* Received too many fragments */
|
||||
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 !!!!! */
|
||||
|
||||
/* begin negotiation parameter errors */
|
||||
|
|
Loading…
Reference in New Issue