Skip to content

Commit 8a6297d

Browse files
authored
Merge pull request #9267 from julek-wolfssl/dtls-stricter-ordering
Add message order sanity checks
2 parents f8c2e9c + 42238c5 commit 8a6297d

11 files changed

Lines changed: 684 additions & 50 deletions

File tree

doc/dox_comments/header_files/ssl.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15213,6 +15213,102 @@ int wolfSSL_set_client_cert_type(WOLFSSL* ssl, const char* buf, int len);
1521315213
*/
1521415214
int wolfSSL_set_server_cert_type(WOLFSSL* ssl, const char* buf, int len);
1521515215

15216+
/*!
15217+
\ingroup Setup
15218+
15219+
\brief Enables handshake message grouping for the given WOLFSSL_CTX context.
15220+
15221+
This function turns on handshake message grouping for all SSL objects created from the specified context.
15222+
15223+
\return WOLFSSL_SUCCESS on success.
15224+
\return BAD_FUNC_ARG if ctx is NULL.
15225+
15226+
\param ctx Pointer to the WOLFSSL_CTX structure.
15227+
15228+
_Example_
15229+
\code
15230+
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
15231+
wolfSSL_CTX_set_group_messages(ctx);
15232+
\endcode
15233+
15234+
\sa wolfSSL_CTX_clear_group_messages
15235+
\sa wolfSSL_set_group_messages
15236+
\sa wolfSSL_clear_group_messages
15237+
*/
15238+
int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx);
15239+
15240+
/*!
15241+
\ingroup Setup
15242+
15243+
\brief Disables handshake message grouping for the given WOLFSSL_CTX context.
15244+
15245+
This function turns off handshake message grouping for all SSL objects created from the specified context.
15246+
15247+
\return WOLFSSL_SUCCESS on success.
15248+
\return BAD_FUNC_ARG if ctx is NULL.
15249+
15250+
\param ctx Pointer to the WOLFSSL_CTX structure.
15251+
15252+
_Example_
15253+
\code
15254+
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
15255+
wolfSSL_CTX_clear_group_messages(ctx);
15256+
\endcode
15257+
15258+
\sa wolfSSL_CTX_set_group_messages
15259+
\sa wolfSSL_set_group_messages
15260+
\sa wolfSSL_clear_group_messages
15261+
*/
15262+
int wolfSSL_CTX_clear_group_messages(WOLFSSL_CTX* ctx);
15263+
15264+
/*!
15265+
\ingroup Setup
15266+
15267+
\brief Enables handshake message grouping for the given WOLFSSL object.
15268+
15269+
This function turns on handshake message grouping for the specified SSL object.
15270+
15271+
\return WOLFSSL_SUCCESS on success.
15272+
\return BAD_FUNC_ARG if ssl is NULL.
15273+
15274+
\param ssl Pointer to the WOLFSSL structure.
15275+
15276+
_Example_
15277+
\code
15278+
WOLFSSL* ssl = wolfSSL_new(ctx);
15279+
wolfSSL_set_group_messages(ssl);
15280+
\endcode
15281+
15282+
\sa wolfSSL_clear_group_messages
15283+
\sa wolfSSL_CTX_set_group_messages
15284+
\sa wolfSSL_CTX_clear_group_messages
15285+
*/
15286+
int wolfSSL_set_group_messages(WOLFSSL* ssl);
15287+
15288+
/*!
15289+
\ingroup Setup
15290+
15291+
\brief Disables handshake message grouping for the given WOLFSSL object.
15292+
15293+
This function turns off handshake message grouping for the specified SSL object.
15294+
15295+
\return WOLFSSL_SUCCESS on success.
15296+
\return BAD_FUNC_ARG if ssl is NULL.
15297+
15298+
\param ssl Pointer to the WOLFSSL structure.
15299+
15300+
_Example_
15301+
\code
15302+
WOLFSSL* ssl = wolfSSL_new(ctx);
15303+
wolfSSL_clear_group_messages(ssl);
15304+
\endcode
15305+
15306+
\sa wolfSSL_set_group_messages
15307+
\sa wolfSSL_CTX_set_group_messages
15308+
\sa wolfSSL_CTX_clear_group_messages
15309+
*/
15310+
int wolfSSL_clear_group_messages(WOLFSSL* ssl);
15311+
1521615312
/*!
1521715313
\ingroup SSL
1521815314
\brief This function returns the result of the client certificate type

src/internal.c

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17525,6 +17525,15 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1752517525
WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E);
1752617526
return DUPLICATE_MSG_E;
1752717527
}
17528+
if (!ssl->msgsReceived.got_server_hello ||
17529+
ssl->msgsReceived.got_change_cipher ||
17530+
ssl->msgsReceived.got_finished ||
17531+
(!ssl->options.resuming &&
17532+
!ssl->msgsReceived.got_server_hello_done)) {
17533+
WOLFSSL_MSG("session_ticket received in wrong order");
17534+
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
17535+
return OUT_OF_ORDER_E;
17536+
}
1752817537
ssl->msgsReceived.got_session_ticket = 1;
1752917538

1753017539
break;
@@ -17540,20 +17549,36 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1754017549

1754117550
#ifndef NO_WOLFSSL_CLIENT
1754217551
if (ssl->options.side == WOLFSSL_CLIENT_END) {
17543-
if ( ssl->msgsReceived.got_server_hello == 0) {
17552+
if (!ssl->msgsReceived.got_server_hello) {
1754417553
WOLFSSL_MSG("No ServerHello before Cert");
1754517554
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
1754617555
return OUT_OF_ORDER_E;
1754717556
}
17557+
if (ssl->msgsReceived.got_certificate_status ||
17558+
ssl->msgsReceived.got_server_key_exchange ||
17559+
ssl->msgsReceived.got_certificate_request ||
17560+
ssl->msgsReceived.got_server_hello_done) {
17561+
WOLFSSL_MSG("Cert received in wrong order");
17562+
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
17563+
return OUT_OF_ORDER_E;
17564+
}
1754817565
}
1754917566
#endif
1755017567
#ifndef NO_WOLFSSL_SERVER
1755117568
if (ssl->options.side == WOLFSSL_SERVER_END) {
17552-
if ( ssl->msgsReceived.got_client_hello == 0) {
17569+
if (!ssl->msgsReceived.got_client_hello) {
1755317570
WOLFSSL_MSG("No ClientHello before Cert");
1755417571
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
1755517572
return OUT_OF_ORDER_E;
1755617573
}
17574+
if (ssl->msgsReceived.got_client_key_exchange ||
17575+
ssl->msgsReceived.got_certificate_verify ||
17576+
ssl->msgsReceived.got_change_cipher ||
17577+
ssl->msgsReceived.got_finished) {
17578+
WOLFSSL_MSG("Cert received in wrong order");
17579+
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
17580+
return OUT_OF_ORDER_E;
17581+
}
1755717582
}
1755817583
#endif
1755917584
break;
@@ -17572,7 +17597,6 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1757217597
WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E);
1757317598
return DUPLICATE_MSG_E;
1757417599
}
17575-
ssl->msgsReceived.got_certificate_status = 1;
1757617600

1757717601
if (ssl->msgsReceived.got_certificate == 0) {
1757817602
WOLFSSL_MSG("No Certificate before CertificateStatus");
@@ -17584,7 +17608,15 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1758417608
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
1758517609
return OUT_OF_ORDER_E;
1758617610
}
17611+
if (ssl->msgsReceived.got_server_key_exchange ||
17612+
ssl->msgsReceived.got_certificate_request ||
17613+
ssl->msgsReceived.got_server_hello_done) {
17614+
WOLFSSL_MSG("CertificateStatus received in wrong order");
17615+
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
17616+
return OUT_OF_ORDER_E;
17617+
}
1758717618

17619+
ssl->msgsReceived.got_certificate_status = 1;
1758817620
break;
1758917621
#endif
1759017622

@@ -17602,14 +17634,19 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1760217634
WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E);
1760317635
return DUPLICATE_MSG_E;
1760417636
}
17605-
ssl->msgsReceived.got_server_key_exchange = 1;
17606-
1760717637
if (ssl->msgsReceived.got_server_hello == 0) {
1760817638
WOLFSSL_MSG("No ServerHello before ServerKeyExchange");
1760917639
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
1761017640
return OUT_OF_ORDER_E;
1761117641
}
17642+
if (ssl->msgsReceived.got_certificate_request ||
17643+
ssl->msgsReceived.got_server_hello_done) {
17644+
WOLFSSL_MSG("ServerKeyExchange received in wrong order");
17645+
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
17646+
return OUT_OF_ORDER_E;
17647+
}
1761217648

17649+
ssl->msgsReceived.got_server_key_exchange = 1;
1761317650
break;
1761417651
#endif
1761517652

@@ -17627,6 +17664,16 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1762717664
WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E);
1762817665
return DUPLICATE_MSG_E;
1762917666
}
17667+
if (ssl->msgsReceived.got_server_hello == 0) {
17668+
WOLFSSL_MSG("No ServerHello before CertificateRequest");
17669+
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
17670+
return OUT_OF_ORDER_E;
17671+
}
17672+
if (ssl->msgsReceived.got_server_hello_done) {
17673+
WOLFSSL_MSG("CertificateRequest received in wrong order");
17674+
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
17675+
return OUT_OF_ORDER_E;
17676+
}
1763017677
ssl->msgsReceived.got_certificate_request = 1;
1763117678

1763217679
break;
@@ -17746,13 +17793,18 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1774617793
WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E);
1774717794
return DUPLICATE_MSG_E;
1774817795
}
17749-
ssl->msgsReceived.got_certificate_verify = 1;
17750-
1775117796
if ( ssl->msgsReceived.got_certificate == 0) {
1775217797
WOLFSSL_MSG("No Cert before CertVerify");
1775317798
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
1775417799
return OUT_OF_ORDER_E;
1775517800
}
17801+
if (ssl->msgsReceived.got_change_cipher ||
17802+
ssl->msgsReceived.got_finished) {
17803+
WOLFSSL_MSG("CertVerify received in wrong order");
17804+
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
17805+
return OUT_OF_ORDER_E;
17806+
}
17807+
ssl->msgsReceived.got_certificate_verify = 1;
1775617808
break;
1775717809
#endif
1775817810

@@ -17770,13 +17822,19 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1777017822
WOLFSSL_ERROR_VERBOSE(DUPLICATE_MSG_E);
1777117823
return DUPLICATE_MSG_E;
1777217824
}
17773-
ssl->msgsReceived.got_client_key_exchange = 1;
17774-
1777517825
if (ssl->msgsReceived.got_client_hello == 0) {
1777617826
WOLFSSL_MSG("No ClientHello before ClientKeyExchange");
1777717827
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
1777817828
return OUT_OF_ORDER_E;
1777917829
}
17830+
if (ssl->msgsReceived.got_certificate_verify||
17831+
ssl->msgsReceived.got_change_cipher ||
17832+
ssl->msgsReceived.got_finished) {
17833+
WOLFSSL_MSG("ClientKeyExchange received in wrong order");
17834+
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
17835+
return OUT_OF_ORDER_E;
17836+
}
17837+
ssl->msgsReceived.got_client_key_exchange = 1;
1778017838
break;
1778117839
#endif
1778217840

@@ -17795,13 +17853,12 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
1779517853
}
1779617854
}
1779717855
#endif
17798-
ssl->msgsReceived.got_finished = 1;
17799-
1780017856
if (ssl->msgsReceived.got_change_cipher == 0) {
1780117857
WOLFSSL_MSG("Finished received before ChangeCipher");
1780217858
WOLFSSL_ERROR_VERBOSE(NO_CHANGE_CIPHER_E);
1780317859
return NO_CHANGE_CIPHER_E;
1780417860
}
17861+
ssl->msgsReceived.got_finished = 1;
1780517862
break;
1780617863

1780717864
case change_cipher_hs:

src/ssl.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,7 +1830,7 @@ int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req)
18301830
{
18311831
if (ctx == NULL)
18321832
return BAD_FUNC_ARG;
1833-
if (ctx->method->side == WOLFSSL_CLIENT_END)
1833+
if (ctx->method->side != WOLFSSL_SERVER_END)
18341834
return SIDE_ERROR;
18351835

18361836
ctx->mutualAuth = (byte)req;
@@ -1843,14 +1843,14 @@ int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req)
18431843
*
18441844
* ssl The SSL/TLS object.
18451845
* req 1 to indicate required and 0 when not.
1846-
* returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
1847-
* SIDE_ERROR when not a client and 0 on success.
1846+
* returns BAD_FUNC_ARG when ssl is NULL and
1847+
* SIDE_ERROR when not a server and 0 on success.
18481848
*/
18491849
int wolfSSL_mutual_auth(WOLFSSL* ssl, int req)
18501850
{
18511851
if (ssl == NULL)
18521852
return BAD_FUNC_ARG;
1853-
if (ssl->options.side == WOLFSSL_SERVER_END)
1853+
if (ssl->options.side != WOLFSSL_SERVER_END)
18541854
return SIDE_ERROR;
18551855

18561856
ssl->options.mutualAuth = (word16)req;
@@ -5159,6 +5159,16 @@ int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
51595159

51605160
return WOLFSSL_SUCCESS;
51615161
}
5162+
5163+
int wolfSSL_CTX_clear_group_messages(WOLFSSL_CTX* ctx)
5164+
{
5165+
if (ctx == NULL)
5166+
return BAD_FUNC_ARG;
5167+
5168+
ctx->groupMessages = 0;
5169+
5170+
return WOLFSSL_SUCCESS;
5171+
}
51625172
#endif
51635173

51645174

@@ -5192,6 +5202,15 @@ int wolfSSL_set_group_messages(WOLFSSL* ssl)
51925202
return WOLFSSL_SUCCESS;
51935203
}
51945204

5205+
int wolfSSL_clear_group_messages(WOLFSSL* ssl)
5206+
{
5207+
if (ssl == NULL)
5208+
return BAD_FUNC_ARG;
5209+
5210+
ssl->options.groupMessages = 0;
5211+
5212+
return WOLFSSL_SUCCESS;
5213+
}
51955214

51965215
/* make minVersion the internal equivalent SSL version */
51975216
static int SetMinVersionHelper(byte* minVersion, int version)

tests/api.c

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -51380,13 +51380,6 @@ TEST_CASE testCases[] = {
5138051380
/* Can't memory test as client/server hangs. */
5138151381
TEST_DECL(test_dtls_msg_from_other_peer),
5138251382
TEST_DECL(test_dtls_ipv6_check),
51383-
TEST_DECL(test_dtls_short_ciphertext),
51384-
TEST_DECL(test_dtls12_record_length_mismatch),
51385-
TEST_DECL(test_dtls12_short_read),
51386-
TEST_DECL(test_dtls13_longer_length),
51387-
TEST_DECL(test_dtls13_short_read),
51388-
TEST_DECL(test_records_span_network_boundaries),
51389-
TEST_DECL(test_dtls_record_cross_boundaries),
5139051383
TEST_DECL(test_wolfSSL_SCR_after_resumption),
5139151384
TEST_DECL(test_dtls_no_extensions),
5139251385
TEST_DECL(test_tls_alert_no_server_hello),
@@ -51406,12 +51399,10 @@ TEST_CASE testCases[] = {
5140651399
TEST_DECL(test_dtls13_frag_ch_pq),
5140751400
TEST_DECL(test_dtls_empty_keyshare_with_cookie),
5140851401
TEST_DECL(test_dtls_old_seq_number),
51409-
TEST_DECL(test_dtls12_basic_connection_id),
51410-
TEST_DECL(test_dtls13_basic_connection_id),
5141151402
TEST_DECL(test_dtls12_missing_finished),
5141251403
TEST_DECL(test_dtls13_missing_finished_client),
5141351404
TEST_DECL(test_dtls13_missing_finished_server),
51414-
TEST_DECL(test_wolfSSL_dtls_set_pending_peer),
51405+
TEST_DTLS_DECLS,
5141551406
TEST_DECL(test_tls_multi_handshakes_one_record),
5141651407
TEST_DECL(test_write_dup),
5141751408
TEST_DECL(test_read_write_hs),
@@ -51422,25 +51413,12 @@ TEST_CASE testCases[] = {
5142251413
TEST_DECL(test_wolfSSL_SendUserCanceled),
5142351414
TEST_DECL(test_wolfSSL_SSLDisableRead),
5142451415
TEST_DECL(test_wolfSSL_inject),
51425-
TEST_DECL(test_wolfSSL_dtls_cid_parse),
51426-
TEST_DECL(test_dtls13_epochs),
51427-
TEST_DECL(test_dtls_rtx_across_epoch_change),
51428-
TEST_DECL(test_dtls_drop_client_ack),
51429-
TEST_DECL(test_dtls_bogus_finished_epoch_zero),
51430-
TEST_DECL(test_dtls_replay),
51431-
TEST_DECL(test_dtls_srtp),
51432-
TEST_DECL(test_dtls_timeout),
51433-
TEST_DECL(test_dtls13_ack_order),
51434-
TEST_DECL(test_dtls_version_checking),
5143551416
TEST_DECL(test_ocsp_status_callback),
5143651417
TEST_DECL(test_ocsp_basic_verify),
5143751418
TEST_DECL(test_ocsp_response_parsing),
5143851419
TEST_DECL(test_ocsp_certid_enc_dec),
5143951420
TEST_DECL(test_ocsp_tls_cert_cb),
51440-
TEST_DECL(test_tls12_unexpected_ccs),
51441-
TEST_DECL(test_tls13_unexpected_ccs),
51442-
TEST_DECL(test_tls12_curve_intersection),
51443-
TEST_DECL(test_tls13_curve_intersection),
51421+
TEST_TLS_DECLS,
5144451422
TEST_DECL(test_wc_DhSetNamedKey),
5144551423
/* This test needs to stay at the end to clean up any caches allocated. */
5144651424
TEST_DECL(test_wolfSSL_Cleanup)

0 commit comments

Comments
 (0)