forked from wolfSSL/wolfssl
dtls13: additional epoch checks
This commit is contained in:
102
src/dtls13.c
102
src/dtls13.c
@ -1637,6 +1637,102 @@ static int Dtls13AcceptFragmented(WOLFSSL *ssl, enum HandShakeType type)
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Dtls13CheckEpoch(WOLFSSL* ssl, enum HandShakeType type)
|
||||||
|
{
|
||||||
|
w64wrapper plainEpoch = w64From32(0x0, 0x0);
|
||||||
|
w64wrapper hsEpoch = w64From32(0x0, DTLS13_EPOCH_HANDSHAKE);
|
||||||
|
w64wrapper t0Epoch = w64From32(0x0, DTLS13_EPOCH_TRAFFIC0);
|
||||||
|
|
||||||
|
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||||
|
switch (type) {
|
||||||
|
case client_hello:
|
||||||
|
case server_hello:
|
||||||
|
case hello_verify_request:
|
||||||
|
case hello_retry_request:
|
||||||
|
case hello_request:
|
||||||
|
if (!w64Equal(ssl->keys.curEpoch64, plainEpoch)) {
|
||||||
|
WOLFSSL_MSG("Msg should be epoch 0");
|
||||||
|
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||||
|
return SANITY_MSG_E;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case encrypted_extensions:
|
||||||
|
case server_key_exchange:
|
||||||
|
case server_hello_done:
|
||||||
|
case client_key_exchange:
|
||||||
|
if (!w64Equal(ssl->keys.curEpoch64, hsEpoch)) {
|
||||||
|
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||||
|
ssl->options.serverState < SERVER_HELLO_COMPLETE) {
|
||||||
|
/* before processing SH we don't know which version
|
||||||
|
* will be negotiated. */
|
||||||
|
if (!w64Equal(ssl->keys.curEpoch64, plainEpoch)) {
|
||||||
|
WOLFSSL_MSG("Msg should be epoch 2 or 0");
|
||||||
|
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||||
|
return SANITY_MSG_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WOLFSSL_MSG("Msg should be epoch 2");
|
||||||
|
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||||
|
return SANITY_MSG_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case certificate_request:
|
||||||
|
case certificate:
|
||||||
|
case certificate_verify:
|
||||||
|
case finished:
|
||||||
|
if (!ssl->options.handShakeDone) {
|
||||||
|
if (!w64Equal(ssl->keys.curEpoch64, hsEpoch)) {
|
||||||
|
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||||
|
ssl->options.serverState < SERVER_HELLO_COMPLETE) {
|
||||||
|
/* before processing SH we don't know which version
|
||||||
|
* will be negotiated. */
|
||||||
|
if (!w64Equal(ssl->keys.curEpoch64, plainEpoch)) {
|
||||||
|
WOLFSSL_MSG("Msg should be epoch 2 or 0");
|
||||||
|
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||||
|
return SANITY_MSG_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WOLFSSL_MSG("Msg should be epoch 2");
|
||||||
|
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||||
|
return SANITY_MSG_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Allow epoch 2 in case of rtx */
|
||||||
|
if (!w64GTE(ssl->keys.curEpoch64, hsEpoch)) {
|
||||||
|
WOLFSSL_MSG("Msg should be epoch 2+");
|
||||||
|
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||||
|
return SANITY_MSG_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case certificate_status:
|
||||||
|
case change_cipher_hs:
|
||||||
|
case key_update:
|
||||||
|
case session_ticket:
|
||||||
|
if (!w64GTE(ssl->keys.curEpoch64, t0Epoch)) {
|
||||||
|
WOLFSSL_MSG("Msg should be epoch 3+");
|
||||||
|
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||||
|
return SANITY_MSG_E;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case end_of_early_data:
|
||||||
|
case message_hash:
|
||||||
|
case no_shake:
|
||||||
|
default:
|
||||||
|
WOLFSSL_MSG("Unknown message type");
|
||||||
|
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||||
|
return SANITY_MSG_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dtls13HandshakeRecv() - process an handshake message. Deal with
|
* Dtls13HandshakeRecv() - process an handshake message. Deal with
|
||||||
fragmentation if needed
|
fragmentation if needed
|
||||||
@ -1672,6 +1768,12 @@ static int _Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input, word32 size,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = Dtls13CheckEpoch(ssl, handshakeType);
|
||||||
|
if (ret != 0) {
|
||||||
|
WOLFSSL_ERROR(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END &&
|
if (ssl->options.side == WOLFSSL_SERVER_END &&
|
||||||
ssl->options.acceptState < TLS13_ACCEPT_FIRST_REPLY_DONE) {
|
ssl->options.acceptState < TLS13_ACCEPT_FIRST_REPLY_DONE) {
|
||||||
if (handshakeType != client_hello) {
|
if (handshakeType != client_hello) {
|
||||||
|
@ -21013,6 +21013,16 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx, int sniff)
|
|||||||
isEarlyData = isEarlyData && w64Equal(ssl->keys.curEpoch64,
|
isEarlyData = isEarlyData && w64Equal(ssl->keys.curEpoch64,
|
||||||
w64From32(0x0, DTLS13_EPOCH_EARLYDATA));
|
w64From32(0x0, DTLS13_EPOCH_EARLYDATA));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WOLFSSL_DTLS13
|
||||||
|
/* Application data should never appear in epoch 0 or 2 */
|
||||||
|
if (ssl->options.tls1_3 && ssl->options.dtls &&
|
||||||
|
(w64Equal(ssl->keys.curEpoch64, w64From32(0x0, DTLS13_EPOCH_HANDSHAKE))
|
||||||
|
|| w64Equal(ssl->keys.curEpoch64, w64From32(0x0, 0x0))))
|
||||||
|
{
|
||||||
|
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||||
|
return SANITY_MSG_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_EARLY_DATA
|
#ifdef WOLFSSL_EARLY_DATA
|
||||||
if (isEarlyData && acceptEarlyData) {
|
if (isEarlyData && acceptEarlyData) {
|
||||||
|
@ -67811,6 +67811,7 @@ TEST_CASE testCases[] = {
|
|||||||
TEST_DECL(test_wolfSSL_SSLDisableRead),
|
TEST_DECL(test_wolfSSL_SSLDisableRead),
|
||||||
TEST_DECL(test_wolfSSL_inject),
|
TEST_DECL(test_wolfSSL_inject),
|
||||||
TEST_DECL(test_wolfSSL_dtls_cid_parse),
|
TEST_DECL(test_wolfSSL_dtls_cid_parse),
|
||||||
|
TEST_DECL(test_dtls13_epochs),
|
||||||
TEST_DECL(test_ocsp_status_callback),
|
TEST_DECL(test_ocsp_status_callback),
|
||||||
TEST_DECL(test_ocsp_basic_verify),
|
TEST_DECL(test_ocsp_basic_verify),
|
||||||
TEST_DECL(test_ocsp_response_parsing),
|
TEST_DECL(test_ocsp_response_parsing),
|
||||||
|
@ -595,3 +595,54 @@ int test_wolfSSL_dtls_cid_parse(void)
|
|||||||
#endif
|
#endif
|
||||||
return EXPECT_RESULT();
|
return EXPECT_RESULT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_dtls13_epochs(void) {
|
||||||
|
EXPECT_DECLS;
|
||||||
|
#if defined(WOLFSSL_DTLS13)
|
||||||
|
WOLFSSL_CTX* ctx = NULL;
|
||||||
|
WOLFSSL* ssl = NULL;
|
||||||
|
byte input[20];
|
||||||
|
word32 inOutIdx = 0;
|
||||||
|
|
||||||
|
XMEMSET(input, 0, sizeof(input));
|
||||||
|
|
||||||
|
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_3_client_method()));
|
||||||
|
ExpectNotNull(ssl = wolfSSL_new(ctx));
|
||||||
|
/* Some manual setup to enter the epoch check */
|
||||||
|
ExpectTrue(ssl->options.tls1_3 = 1);
|
||||||
|
|
||||||
|
inOutIdx = 0;
|
||||||
|
ssl->keys.curEpoch64 = w64From32(0x0, 0x0);
|
||||||
|
ExpectIntEQ(DoApplicationData(ssl, input, &inOutIdx, 0), SANITY_MSG_E);
|
||||||
|
inOutIdx = 0;
|
||||||
|
ssl->keys.curEpoch64 = w64From32(0x0, 0x2);
|
||||||
|
ExpectIntEQ(DoApplicationData(ssl, input, &inOutIdx, 0), SANITY_MSG_E);
|
||||||
|
|
||||||
|
ssl->keys.curEpoch64 = w64From32(0x0, 0x1);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, client_hello), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, server_hello), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, hello_verify_request), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, hello_retry_request), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, hello_request), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, encrypted_extensions), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, server_key_exchange), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, server_hello_done), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, client_key_exchange), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, certificate_request), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, certificate), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, certificate_verify), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, finished), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, certificate_status), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, change_cipher_hs), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, key_update), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, session_ticket), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, end_of_early_data), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, message_hash), SANITY_MSG_E);
|
||||||
|
ExpectIntEQ(Dtls13CheckEpoch(ssl, no_shake), SANITY_MSG_E);
|
||||||
|
|
||||||
|
wolfSSL_CTX_free(ctx);
|
||||||
|
wolfSSL_free(ssl);
|
||||||
|
#endif
|
||||||
|
return EXPECT_RESULT();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -25,5 +25,6 @@
|
|||||||
int test_dtls12_basic_connection_id(void);
|
int test_dtls12_basic_connection_id(void);
|
||||||
int test_dtls13_basic_connection_id(void);
|
int test_dtls13_basic_connection_id(void);
|
||||||
int test_wolfSSL_dtls_cid_parse(void);
|
int test_wolfSSL_dtls_cid_parse(void);
|
||||||
|
int test_dtls13_epochs(void);
|
||||||
|
|
||||||
#endif /* TESTS_API_DTLS_H */
|
#endif /* TESTS_API_DTLS_H */
|
||||||
|
@ -2222,7 +2222,7 @@ WOLFSSL_LOCAL int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
WOLFSSL_LOCAL int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
WOLFSSL_LOCAL int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
word32 size, word32 totalSz, int sniff);
|
word32 size, word32 totalSz, int sniff);
|
||||||
#endif
|
#endif
|
||||||
WOLFSSL_LOCAL int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
WOLFSSL_API int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||||
int sniff);
|
int sniff);
|
||||||
/* TLS v1.3 needs these */
|
/* TLS v1.3 needs these */
|
||||||
WOLFSSL_LOCAL int HandleTlsResumption(WOLFSSL* ssl, Suites* clSuites);
|
WOLFSSL_LOCAL int HandleTlsResumption(WOLFSSL* ssl, Suites* clSuites);
|
||||||
@ -7052,6 +7052,7 @@ WOLFSSL_LOCAL int Dtls13HandshakeSend(WOLFSSL* ssl, byte* output,
|
|||||||
word16 output_size, word16 length, enum HandShakeType handshake_type,
|
word16 output_size, word16 length, enum HandShakeType handshake_type,
|
||||||
int hash_output);
|
int hash_output);
|
||||||
WOLFSSL_LOCAL int Dtls13RecordRecvd(WOLFSSL* ssl);
|
WOLFSSL_LOCAL int Dtls13RecordRecvd(WOLFSSL* ssl);
|
||||||
|
WOLFSSL_API int Dtls13CheckEpoch(WOLFSSL* ssl, enum HandShakeType type);
|
||||||
WOLFSSL_LOCAL int Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input,
|
WOLFSSL_LOCAL int Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input,
|
||||||
word32* inOutIdx, word32 totalSz);
|
word32* inOutIdx, word32 totalSz);
|
||||||
WOLFSSL_LOCAL int Dtls13HandshakeAddHeader(WOLFSSL* ssl, byte* output,
|
WOLFSSL_LOCAL int Dtls13HandshakeAddHeader(WOLFSSL* ssl, byte* output,
|
||||||
|
Reference in New Issue
Block a user