mirror of https://github.com/wolfSSL/wolfssl.git
DTLS sequence number and cookie fixes
- dtls: check that the cookie secret is not emtpy - Dtls13DoDowngrade -> Dtls13ClientDoDowngrade - dtls: generate both 1.2 and 1.3 cookie secrets in case we downgrade - dtls: setup sequence numbers for downgrade - add dtls downgrade sequence number check test Fixes ZD17314pull/7214/head
parent
851f059023
commit
8bddeb10c7
|
@ -114,6 +114,7 @@ int DtlsIgnoreError(int err)
|
||||||
case SOCKET_ERROR_E:
|
case SOCKET_ERROR_E:
|
||||||
case WANT_READ:
|
case WANT_READ:
|
||||||
case WANT_WRITE:
|
case WANT_WRITE:
|
||||||
|
case COOKIE_ERROR:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -207,6 +208,13 @@ static int CreateDtls12Cookie(const WOLFSSL* ssl, const WolfSSL_CH* ch,
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
Hmac cookieHmac;
|
Hmac cookieHmac;
|
||||||
|
|
||||||
|
if (ssl->buffers.dtlsCookieSecret.buffer == NULL ||
|
||||||
|
ssl->buffers.dtlsCookieSecret.length == 0) {
|
||||||
|
WOLFSSL_MSG("Missing DTLS 1.2 cookie secret");
|
||||||
|
return COOKIE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ret = wc_HmacInit(&cookieHmac, ssl->heap, ssl->devId);
|
ret = wc_HmacInit(&cookieHmac, ssl->heap, ssl->devId);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = wc_HmacSetKey(&cookieHmac, DTLS_COOKIE_TYPE,
|
ret = wc_HmacSetKey(&cookieHmac, DTLS_COOKIE_TYPE,
|
||||||
|
|
|
@ -7456,15 +7456,14 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||||
|
|
||||||
#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
|
#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
|
||||||
if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) {
|
if (ssl->options.dtls && ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
if (!IsAtLeastTLSv1_3(ssl->version)) {
|
/* Initialize both in case we allow downgrading. */
|
||||||
ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0);
|
ret = wolfSSL_DTLS_SetCookieSecret(ssl, NULL, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
WOLFSSL_MSG("DTLS Cookie Secret error");
|
WOLFSSL_MSG("DTLS Cookie Secret error");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
|
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
|
||||||
else {
|
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||||
ret = wolfSSL_send_hrr_cookie(ssl, NULL, 0);
|
ret = wolfSSL_send_hrr_cookie(ssl, NULL, 0);
|
||||||
if (ret != WOLFSSL_SUCCESS) {
|
if (ret != WOLFSSL_SUCCESS) {
|
||||||
WOLFSSL_MSG("DTLS1.3 Cookie secret error");
|
WOLFSSL_MSG("DTLS1.3 Cookie secret error");
|
||||||
|
|
21
src/tls13.c
21
src/tls13.c
|
@ -3546,6 +3546,12 @@ int CreateCookieExt(const WOLFSSL* ssl, byte* hash, word16 hashSz,
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssl->buffers.tls13CookieSecret.buffer == NULL ||
|
||||||
|
ssl->buffers.tls13CookieSecret.length == 0) {
|
||||||
|
WOLFSSL_MSG("Missing DTLS 1.3 cookie secret");
|
||||||
|
return COOKIE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Cookie Data = Hash Len | Hash | CS | KeyShare Group */
|
/* Cookie Data = Hash Len | Hash | CS | KeyShare Group */
|
||||||
cookie[cookieSz++] = (byte)hashSz;
|
cookie[cookieSz++] = (byte)hashSz;
|
||||||
XMEMCPY(cookie + cookieSz, hash, hashSz);
|
XMEMCPY(cookie + cookieSz, hash, hashSz);
|
||||||
|
@ -4693,7 +4699,7 @@ int SendTls13ClientHello(WOLFSSL* ssl)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_NO_CLIENT)
|
#if defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_NO_CLIENT)
|
||||||
static int Dtls13DoDowngrade(WOLFSSL* ssl)
|
static int Dtls13ClientDoDowngrade(WOLFSSL* ssl)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
if (ssl->dtls13ClientHello == NULL)
|
if (ssl->dtls13ClientHello == NULL)
|
||||||
|
@ -5099,7 +5105,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
ssl->chVersion.minor = DTLSv1_2_MINOR;
|
ssl->chVersion.minor = DTLSv1_2_MINOR;
|
||||||
ssl->version.minor = DTLSv1_2_MINOR;
|
ssl->version.minor = DTLSv1_2_MINOR;
|
||||||
ret = Dtls13DoDowngrade(ssl);
|
ret = Dtls13ClientDoDowngrade(ssl);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -5193,7 +5199,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
ssl->chVersion.minor = DTLSv1_2_MINOR;
|
ssl->chVersion.minor = DTLSv1_2_MINOR;
|
||||||
ssl->version.minor = DTLSv1_2_MINOR;
|
ssl->version.minor = DTLSv1_2_MINOR;
|
||||||
ret = Dtls13DoDowngrade(ssl);
|
ret = Dtls13ClientDoDowngrade(ssl);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -5266,7 +5272,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS13
|
#ifdef WOLFSSL_DTLS13
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
ret = Dtls13DoDowngrade(ssl);
|
ret = Dtls13ClientDoDowngrade(ssl);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -6321,6 +6327,12 @@ int TlsCheckCookie(const WOLFSSL* ssl, const byte* cookie, word16 cookieSz)
|
||||||
byte cookieType = 0;
|
byte cookieType = 0;
|
||||||
byte macSz = 0;
|
byte macSz = 0;
|
||||||
|
|
||||||
|
if (ssl->buffers.tls13CookieSecret.buffer == NULL ||
|
||||||
|
ssl->buffers.tls13CookieSecret.length == 0) {
|
||||||
|
WOLFSSL_MSG("Missing DTLS 1.3 cookie secret");
|
||||||
|
return COOKIE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(NO_SHA) && defined(NO_SHA256)
|
#if !defined(NO_SHA) && defined(NO_SHA256)
|
||||||
cookieType = SHA;
|
cookieType = SHA;
|
||||||
macSz = WC_SHA_DIGEST_SIZE;
|
macSz = WC_SHA_DIGEST_SIZE;
|
||||||
|
@ -6695,6 +6707,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
* wolfSSL_accept_TLSv13 when changing this one. */
|
* wolfSSL_accept_TLSv13 when changing this one. */
|
||||||
if (IsDtlsNotSctpMode(ssl) && ssl->options.sendCookie &&
|
if (IsDtlsNotSctpMode(ssl) && ssl->options.sendCookie &&
|
||||||
!ssl->options.dtlsStateful) {
|
!ssl->options.dtlsStateful) {
|
||||||
|
DtlsSetSeqNumForReply(ssl);
|
||||||
ret = DoClientHelloStateless(ssl, input + *inOutIdx, helloSz, 0, NULL);
|
ret = DoClientHelloStateless(ssl, input + *inOutIdx, helloSz, 0, NULL);
|
||||||
if (ret != 0 || !ssl->options.dtlsStateful) {
|
if (ret != 0 || !ssl->options.dtlsStateful) {
|
||||||
*inOutIdx += helloSz;
|
*inOutIdx += helloSz;
|
||||||
|
|
76
tests/api.c
76
tests/api.c
|
@ -68547,6 +68547,81 @@ static int test_dtls_dropped_ccs(void)
|
||||||
#endif
|
#endif
|
||||||
return EXPECT_RESULT();
|
return EXPECT_RESULT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) \
|
||||||
|
&& !defined(WOLFSSL_NO_TLS12)
|
||||||
|
static int test_dtls_seq_num_downgrade_check_num(byte* ioBuf, int ioBufLen,
|
||||||
|
byte seq_num)
|
||||||
|
{
|
||||||
|
EXPECT_DECLS;
|
||||||
|
DtlsRecordLayerHeader* dtlsRH;
|
||||||
|
byte sequence_number[8];
|
||||||
|
|
||||||
|
XMEMSET(&sequence_number, 0, sizeof(sequence_number));
|
||||||
|
|
||||||
|
ExpectIntGE(ioBufLen, sizeof(*dtlsRH));
|
||||||
|
dtlsRH = (DtlsRecordLayerHeader*)ioBuf;
|
||||||
|
ExpectIntEQ(dtlsRH->type, handshake);
|
||||||
|
ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
|
||||||
|
ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
|
||||||
|
sequence_number[7] = seq_num;
|
||||||
|
ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
|
||||||
|
sizeof(sequence_number)), 0);
|
||||||
|
|
||||||
|
return EXPECT_RESULT();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that we send the correct sequence number after a HelloVerifyRequest
|
||||||
|
* and after a HelloRetryRequest. This is testing the server side as it is
|
||||||
|
* operating statelessly and should copy the sequence number of the ClientHello.
|
||||||
|
*/
|
||||||
|
static int test_dtls_seq_num_downgrade(void)
|
||||||
|
{
|
||||||
|
EXPECT_DECLS;
|
||||||
|
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) \
|
||||||
|
&& !defined(WOLFSSL_NO_TLS12)
|
||||||
|
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
|
||||||
|
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
|
||||||
|
struct test_memio_ctx test_ctx;
|
||||||
|
|
||||||
|
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||||
|
|
||||||
|
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||||
|
wolfDTLSv1_2_client_method, wolfDTLS_server_method), 0);
|
||||||
|
|
||||||
|
/* CH1 */
|
||||||
|
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
|
||||||
|
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
|
||||||
|
ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.s_buff,
|
||||||
|
test_ctx.s_len, 0), TEST_SUCCESS);
|
||||||
|
/* HVR */
|
||||||
|
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
|
||||||
|
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
|
||||||
|
ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.c_buff,
|
||||||
|
test_ctx.c_len, 0), TEST_SUCCESS);
|
||||||
|
/* CH2 */
|
||||||
|
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
|
||||||
|
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
|
||||||
|
ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.s_buff,
|
||||||
|
test_ctx.s_len, 1), TEST_SUCCESS);
|
||||||
|
/* Server first flight */
|
||||||
|
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
|
||||||
|
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
|
||||||
|
ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.c_buff,
|
||||||
|
test_ctx.c_len, 1), TEST_SUCCESS);
|
||||||
|
|
||||||
|
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
|
||||||
|
|
||||||
|
wolfSSL_free(ssl_c);
|
||||||
|
wolfSSL_CTX_free(ctx_c);
|
||||||
|
wolfSSL_free(ssl_s);
|
||||||
|
wolfSSL_CTX_free(ctx_s);
|
||||||
|
#endif
|
||||||
|
return EXPECT_RESULT();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure we don't send RSA Signature Hash Algorithms in the
|
* Make sure we don't send RSA Signature Hash Algorithms in the
|
||||||
* CertificateRequest when we don't have any such ciphers set.
|
* CertificateRequest when we don't have any such ciphers set.
|
||||||
|
@ -70649,6 +70724,7 @@ TEST_CASE testCases[] = {
|
||||||
TEST_DECL(test_dtls_client_hello_timeout_downgrade),
|
TEST_DECL(test_dtls_client_hello_timeout_downgrade),
|
||||||
TEST_DECL(test_dtls_client_hello_timeout),
|
TEST_DECL(test_dtls_client_hello_timeout),
|
||||||
TEST_DECL(test_dtls_dropped_ccs),
|
TEST_DECL(test_dtls_dropped_ccs),
|
||||||
|
TEST_DECL(test_dtls_seq_num_downgrade),
|
||||||
TEST_DECL(test_certreq_sighash_algos),
|
TEST_DECL(test_certreq_sighash_algos),
|
||||||
TEST_DECL(test_revoked_loaded_int_cert),
|
TEST_DECL(test_revoked_loaded_int_cert),
|
||||||
TEST_DECL(test_dtls_frag_ch),
|
TEST_DECL(test_dtls_frag_ch),
|
||||||
|
|
Loading…
Reference in New Issue