@@ -1411,6 +1411,107 @@ int test_dtls13_short_read(void)
14111411}
14121412#endif /* WOLFSSL_DTLS13 && !defined(WOLFSSL_DTLS_RECORDS_CAN_SPAN_DATAGRAMS) */
14131413
1414+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES ) && defined(WOLFSSL_DTLS13 )
1415+ /* A plaintext (epoch 0) handshake message whose handshake message_length claims
1416+ * more than MAX_HANDSHAKE_SZ must not be buffered for reassembly. We use the
1417+ * server's plaintext ServerHello: the client accepts a fragmented ServerHello
1418+ * (Dtls13AcceptFragmented()), so an incomplete one is normally stored for
1419+ * reassembly. Without the message_length cap in _Dtls13HandshakeRecv() the
1420+ * spoofed message would be added to the rx list; with it the unauthenticated
1421+ * message is silently dropped. */
1422+ int test_dtls13_oversized_msg_length (void )
1423+ {
1424+ EXPECT_DECLS ;
1425+ WOLFSSL_CTX * ctx_c = NULL , * ctx_s = NULL ;
1426+ WOLFSSL * ssl_c = NULL , * ssl_s = NULL ;
1427+ struct test_memio_ctx test_ctx ;
1428+ char sh [TEST_MEMIO_BUF_SZ ];
1429+ int shSz = (int )sizeof (sh );
1430+ int recLen = 0 ;
1431+ byte hsMsg [DTLS_HANDSHAKE_HEADER_SZ + 1 ];
1432+ word32 idx = 0 ;
1433+
1434+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
1435+ ExpectIntEQ (test_memio_setup (& test_ctx , & ctx_c , & ctx_s , & ssl_c , & ssl_s ,
1436+ wolfDTLSv1_3_client_method , wolfDTLSv1_3_server_method ), 0 );
1437+
1438+ /* CH1 -> server, then server emits its first flight (plaintext ServerHello
1439+ * is the first record). */
1440+ ExpectIntEQ (wolfSSL_connect (ssl_c ), -1 );
1441+ ExpectIntEQ (wolfSSL_get_error (ssl_c , -1 ), WOLFSSL_ERROR_WANT_READ );
1442+ ExpectIntEQ (wolfSSL_accept (ssl_s ), -1 );
1443+ ExpectIntEQ (wolfSSL_get_error (ssl_s , -1 ), WOLFSSL_ERROR_WANT_READ );
1444+ ExpectIntGT (test_ctx .c_msg_count , 0 );
1445+ ExpectIntEQ (test_memio_copy_message (& test_ctx , 1 , sh , & shSz , 0 ), 0 );
1446+ ExpectIntGE (shSz , DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ );
1447+ /* First record is a plaintext handshake ServerHello. */
1448+ ExpectIntEQ ((byte )sh [0 ], handshake );
1449+ ExpectIntEQ ((byte )sh [DTLS_RECORD_HEADER_SZ ], server_hello );
1450+ if (EXPECT_SUCCESS ())
1451+ recLen = (((byte )sh [DTLS_RECORD_HEADER_SZ - 2 ]) << 8 ) |
1452+ (byte )sh [DTLS_RECORD_HEADER_SZ - 1 ];
1453+ /* the ServerHello record must be fully contained in the copied message */
1454+ ExpectIntLE (DTLS_RECORD_HEADER_SZ + recLen , shSz );
1455+
1456+ /* Spoof only the handshake message_length of the ServerHello record,
1457+ * leaving the record length and fragment_length intact so it clears record
1458+ * parsing and looks like the first fragment of an oversized message. */
1459+ c32to24 ((word32 )MAX_HANDSHAKE_SZ + 1 ,
1460+ (byte * )sh + DTLS_RECORD_HEADER_SZ + 1 );
1461+ test_memio_clear_buffer (& test_ctx , 1 );
1462+ ExpectIntEQ (test_memio_inject_message (& test_ctx , 1 , sh ,
1463+ DTLS_RECORD_HEADER_SZ + recLen ), 0 );
1464+
1465+ /* The client must reject the oversized ServerHello without buffering it. */
1466+ ExpectIntEQ (wolfSSL_connect (ssl_c ), -1 );
1467+ ExpectIntEQ (wolfSSL_get_error (ssl_c , -1 ), WOLFSSL_ERROR_WANT_READ );
1468+ ExpectNull (ssl_c -> dtls_rx_msg_list );
1469+ ExpectIntEQ (ssl_c -> dtls_rx_msg_list_sz , 0 );
1470+
1471+ wolfSSL_free (ssl_c );
1472+ ssl_c = NULL ;
1473+ wolfSSL_CTX_free (ctx_c );
1474+ ctx_c = NULL ;
1475+ wolfSSL_free (ssl_s );
1476+ ssl_s = NULL ;
1477+ wolfSSL_CTX_free (ctx_s );
1478+ ctx_s = NULL ;
1479+
1480+ /* Stretching the test suite a bit, ideally we should not test using
1481+ * internal state, but we have no way to forge encrypted packet yet */
1482+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
1483+ ExpectIntEQ (test_memio_setup (& test_ctx , & ctx_c , & ctx_s , & ssl_c , & ssl_s ,
1484+ wolfDTLSv1_3_client_method , wolfDTLSv1_3_server_method ), 0 );
1485+ ExpectIntEQ (test_memio_do_handshake (ssl_c , ssl_s , 10 , NULL ), 0 );
1486+ if (EXPECT_SUCCESS ()) {
1487+ ssl_c -> keys .curEpoch64 = w64From32 (0x0 , DTLS13_EPOCH_TRAFFIC0 );
1488+ ssl_c -> keys .decryptedCur = 1 ;
1489+ ssl_c -> curRL .pvMajor = ssl_c -> version .major ;
1490+ ssl_c -> curRL .pvMinor = DTLSv1_2_MINOR ;
1491+ }
1492+ XMEMSET (hsMsg , 0 , sizeof (hsMsg ));
1493+ hsMsg [0 ] = key_update ;
1494+ /* oversized message_length, single-byte first fragment of it */
1495+ c32to24 ((word32 )MAX_HANDSHAKE_SZ + 1 , hsMsg + 1 );
1496+ hsMsg [DTLS_HANDSHAKE_HEADER_SZ - 1 ] = 1 ;
1497+ ExpectIntEQ (Dtls13HandshakeRecv (ssl_c , hsMsg , & idx , (word32 )sizeof (hsMsg )),
1498+ HANDSHAKE_SIZE_ERROR );
1499+ ExpectNull (ssl_c -> dtls_rx_msg_list );
1500+
1501+ wolfSSL_free (ssl_c );
1502+ wolfSSL_CTX_free (ctx_c );
1503+ wolfSSL_free (ssl_s );
1504+ wolfSSL_CTX_free (ctx_s );
1505+
1506+ return EXPECT_RESULT ();
1507+ }
1508+ #else
1509+ int test_dtls13_oversized_msg_length (void )
1510+ {
1511+ return TEST_SKIPPED ;
1512+ }
1513+ #endif /* HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES && WOLFSSL_DTLS13 */
1514+
14141515#if !defined(WOLFSSL_DTLS_RECORDS_CAN_SPAN_DATAGRAMS )
14151516int test_dtls12_short_read (void )
14161517{
@@ -1658,6 +1759,10 @@ int test_dtls13_longer_length(void)
16581759{
16591760 return TEST_SKIPPED ;
16601761}
1762+ int test_dtls13_oversized_msg_length (void )
1763+ {
1764+ return TEST_SKIPPED ;
1765+ }
16611766int test_dtls_record_cross_boundaries (void )
16621767{
16631768 return TEST_SKIPPED ;
0 commit comments