@@ -192,6 +192,111 @@ int test_tls13_unexpected_ccs(void)
192192#endif
193193 return EXPECT_RESULT ();
194194}
195+
196+ /* A record whose length field exceeds the protocol limit must be answered
197+ * with a record_overflow alert (RFC 8446 section 5.1, RFC 5246 section 6.2.1).
198+ * Before the fix the alert was only sent when HAVE_MAX_FRAGMENT was defined,
199+ * so a default build dropped the connection with no alert on the wire. */
200+ int test_tls_record_overflow_alert (void )
201+ {
202+ EXPECT_DECLS ;
203+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES ) && \
204+ (!defined(WOLFSSL_NO_TLS12 ) || defined(WOLFSSL_TLS13 ))
205+ /* Record header only: handshake type, legacy version, length 0xFFFF.
206+ * 0xFFFF is past MAX_RECORD_SIZE + MAX_MSG_EXTRA, so GetRecordHeader()
207+ * returns LENGTH_ERROR before any body bytes are needed. The handshake
208+ * type keeps the server off the OLD_HELLO_ALLOWED SSLv2 detection path. */
209+ const byte oversized [] = {
210+ 0x16 , /* handshake type */
211+ 0x03 , 0x03 , /* legacy record version */
212+ 0xFF , 0xFF /* length 65535 */
213+ };
214+ /* Cleartext record_overflow alert the peer is expected to emit. */
215+ const byte overflowAlert [] = {
216+ 0x15 , /* alert record */
217+ 0x03 , 0x03 , /* version */
218+ 0x00 , 0x02 , /* length */
219+ 0x02 , /* level: fatal */
220+ 0x16 /* description: record_overflow (22) */
221+ };
222+ WOLFSSL_CTX * ctx_s = NULL ;
223+ WOLFSSL * ssl_s = NULL ;
224+ struct test_memio_ctx test_ctx ;
225+ #ifdef WOLFSSL_TLS13
226+ WOLFSSL_CTX * ctx_c = NULL ;
227+ WOLFSSL * ssl_c = NULL ;
228+ WOLFSSL_ALERT_HISTORY history ;
229+ byte readBuf [64 ];
230+ #endif
231+
232+ /* Server side before negotiation: the alert is in the clear, so the exact
233+ * record can be matched on the wire. */
234+ #ifndef WOLFSSL_NO_TLS12
235+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
236+ ExpectIntEQ (test_memio_inject_message (& test_ctx , 0 ,
237+ (const char * )oversized , sizeof (oversized )), 0 );
238+ ExpectIntEQ (test_memio_setup (& test_ctx , NULL , & ctx_s , NULL , & ssl_s ,
239+ NULL , wolfTLSv1_2_server_method ), 0 );
240+ ExpectIntEQ (wolfSSL_accept (ssl_s ), WOLFSSL_FATAL_ERROR );
241+ ExpectIntEQ (wolfSSL_get_error (ssl_s , WOLFSSL_FATAL_ERROR ), LENGTH_ERROR );
242+ ExpectIntEQ (test_ctx .c_len , sizeof (overflowAlert ));
243+ ExpectBufEQ (test_ctx .c_buff , overflowAlert , sizeof (overflowAlert ));
244+ wolfSSL_free (ssl_s );
245+ wolfSSL_CTX_free (ctx_s );
246+ ssl_s = NULL ;
247+ ctx_s = NULL ;
248+ #endif /* !WOLFSSL_NO_TLS12 */
249+
250+ #ifdef WOLFSSL_TLS13
251+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
252+ ExpectIntEQ (test_memio_inject_message (& test_ctx , 0 ,
253+ (const char * )oversized , sizeof (oversized )), 0 );
254+ ExpectIntEQ (test_memio_setup (& test_ctx , NULL , & ctx_s , NULL , & ssl_s ,
255+ NULL , wolfTLSv1_3_server_method ), 0 );
256+ ExpectIntEQ (wolfSSL_accept (ssl_s ), WOLFSSL_FATAL_ERROR );
257+ ExpectIntEQ (wolfSSL_get_error (ssl_s , WOLFSSL_FATAL_ERROR ), LENGTH_ERROR );
258+ ExpectIntEQ (test_ctx .c_len , sizeof (overflowAlert ));
259+ ExpectBufEQ (test_ctx .c_buff , overflowAlert , sizeof (overflowAlert ));
260+ wolfSSL_free (ssl_s );
261+ wolfSSL_CTX_free (ctx_s );
262+ ssl_s = NULL ;
263+ ctx_s = NULL ;
264+
265+ /* Client side after a completed TLS 1.3 handshake: the reported scenario.
266+ * The alert is encrypted now, so it is decoded by letting the server read
267+ * it and inspecting its received-alert history. */
268+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
269+ ExpectIntEQ (test_memio_setup (& test_ctx , & ctx_c , & ctx_s , & ssl_c , & ssl_s ,
270+ wolfTLSv1_3_client_method , wolfTLSv1_3_server_method ), 0 );
271+ ExpectIntEQ (test_memio_do_handshake (ssl_c , ssl_s , 10 , NULL ), 0 );
272+
273+ /* Drop any queued post-handshake traffic (session tickets) so only the
274+ * crafted record and the resulting alert remain in the buffers. */
275+ test_memio_clear_buffer (& test_ctx , 1 );
276+ test_memio_clear_buffer (& test_ctx , 0 );
277+
278+ ExpectIntEQ (test_memio_inject_message (& test_ctx , 1 ,
279+ (const char * )oversized , sizeof (oversized )), 0 );
280+ ExpectIntEQ (wolfSSL_read (ssl_c , readBuf , sizeof (readBuf )),
281+ WOLFSSL_FATAL_ERROR );
282+ ExpectIntEQ (wolfSSL_get_error (ssl_c , WOLFSSL_FATAL_ERROR ), LENGTH_ERROR );
283+
284+ /* Server consumes the encrypted alert and records it. */
285+ ExpectIntLE (wolfSSL_read (ssl_s , readBuf , sizeof (readBuf )), 0 );
286+ XMEMSET (& history , 0 , sizeof (history ));
287+ ExpectIntEQ (wolfSSL_get_alert_history (ssl_s , & history ), WOLFSSL_SUCCESS );
288+ ExpectIntEQ (history .last_rx .code , record_overflow );
289+ ExpectIntEQ (history .last_rx .level , alert_fatal );
290+
291+ wolfSSL_free (ssl_c );
292+ wolfSSL_free (ssl_s );
293+ wolfSSL_CTX_free (ctx_c );
294+ wolfSSL_CTX_free (ctx_s );
295+ #endif /* WOLFSSL_TLS13 */
296+ #endif /* HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES && (!NO_TLS12 || TLS13) */
297+ return EXPECT_RESULT ();
298+ }
299+
195300int test_tls12_curve_intersection (void ) {
196301 EXPECT_DECLS ;
197302#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES ) && \
0 commit comments