Skip to content

Commit 52c6dc6

Browse files
author
Hanno Becker
committed
Correct length check for DTLS records from old epochs.
DTLS records from previous epochs were incorrectly checked against the current epoch transform's minimal content length, leading to the rejection of entire datagrams. This commit fixed that and adapts two test cases accordingly. Internal reference: IOTSSL-1417
1 parent d82d846 commit 52c6dc6

File tree

2 files changed

+79
-74
lines changed

2 files changed

+79
-74
lines changed

library/ssl_tls.c

Lines changed: 75 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3522,81 +3522,23 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
35223522
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
35233523
}
35243524

3525-
/* Check length against bounds of the current transform and version */
3526-
if( ssl->transform_in == NULL )
3527-
{
3528-
if( ssl->in_msglen < 1 ||
3529-
ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
3530-
{
3531-
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
3532-
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3533-
}
3534-
}
3535-
else
3536-
{
3537-
if( ssl->in_msglen < ssl->transform_in->minlen )
3538-
{
3539-
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
3540-
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3541-
}
3542-
3543-
#if defined(MBEDTLS_SSL_PROTO_SSL3)
3544-
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
3545-
ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_MAX_CONTENT_LEN )
3546-
{
3547-
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
3548-
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3549-
}
3550-
#endif
3551-
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
3552-
defined(MBEDTLS_SSL_PROTO_TLS1_2)
3553-
/*
3554-
* TLS encrypted messages can have up to 256 bytes of padding
3555-
*/
3556-
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 &&
3557-
ssl->in_msglen > ssl->transform_in->minlen +
3558-
MBEDTLS_SSL_MAX_CONTENT_LEN + 256 )
3559-
{
3560-
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
3561-
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3562-
}
3563-
#endif
3564-
}
3565-
35663525
/*
3567-
* DTLS-related tests done last, because most of them may result in
3568-
* silently dropping the record (but not the whole datagram), and we only
3569-
* want to consider that after ensuring that the "basic" fields (type,
3570-
* version, length) are sane.
3526+
* DTLS-related tests.
3527+
* Check epoch before checking length constraint because
3528+
* the latter varies with the epoch. E.g., if a ChangeCipherSpec
3529+
* message gets duplicated before the corresponding Finished message,
3530+
* the second ChangeCipherSpec should be discarded because it belongs
3531+
* to an old epoch, but not because its length is shorter than
3532+
* the minimum record length for packets using the new record transform.
3533+
* Note that these two kinds of failures are handled differently,
3534+
* as an unexpected record is silently skipped but an invalid
3535+
* record leads to the entire datagram being dropped.
35713536
*/
35723537
#if defined(MBEDTLS_SSL_PROTO_DTLS)
35733538
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
35743539
{
35753540
unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
35763541

3577-
/* Drop unexpected ChangeCipherSpec messages */
3578-
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
3579-
ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
3580-
ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
3581-
{
3582-
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ChangeCipherSpec" ) );
3583-
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
3584-
}
3585-
3586-
/* Drop unexpected ApplicationData records,
3587-
* except at the beginning of renegotiations */
3588-
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
3589-
ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
3590-
#if defined(MBEDTLS_SSL_RENEGOTIATION)
3591-
&& ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
3592-
ssl->state == MBEDTLS_SSL_SERVER_HELLO )
3593-
#endif
3594-
)
3595-
{
3596-
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
3597-
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
3598-
}
3599-
36003542
/* Check epoch (and sequence number) with DTLS */
36013543
if( rec_epoch != ssl->in_epoch )
36023544
{
@@ -3636,9 +3578,74 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
36363578
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
36373579
}
36383580
#endif
3581+
3582+
/* Drop unexpected ChangeCipherSpec messages */
3583+
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
3584+
ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
3585+
ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
3586+
{
3587+
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ChangeCipherSpec" ) );
3588+
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
3589+
}
3590+
3591+
/* Drop unexpected ApplicationData records,
3592+
* except at the beginning of renegotiations */
3593+
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
3594+
ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
3595+
#if defined(MBEDTLS_SSL_RENEGOTIATION)
3596+
&& ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
3597+
ssl->state == MBEDTLS_SSL_SERVER_HELLO )
3598+
#endif
3599+
)
3600+
{
3601+
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
3602+
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
3603+
}
36393604
}
36403605
#endif /* MBEDTLS_SSL_PROTO_DTLS */
36413606

3607+
3608+
/* Check length against bounds of the current transform and version */
3609+
if( ssl->transform_in == NULL )
3610+
{
3611+
if( ssl->in_msglen < 1 ||
3612+
ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
3613+
{
3614+
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
3615+
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3616+
}
3617+
}
3618+
else
3619+
{
3620+
if( ssl->in_msglen < ssl->transform_in->minlen )
3621+
{
3622+
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
3623+
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3624+
}
3625+
3626+
#if defined(MBEDTLS_SSL_PROTO_SSL3)
3627+
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
3628+
ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_MAX_CONTENT_LEN )
3629+
{
3630+
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
3631+
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3632+
}
3633+
#endif
3634+
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
3635+
defined(MBEDTLS_SSL_PROTO_TLS1_2)
3636+
/*
3637+
* TLS encrypted messages can have up to 256 bytes of padding
3638+
*/
3639+
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 &&
3640+
ssl->in_msglen > ssl->transform_in->minlen +
3641+
MBEDTLS_SSL_MAX_CONTENT_LEN + 256 )
3642+
{
3643+
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
3644+
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3645+
}
3646+
#endif
3647+
}
3648+
36423649
return( 0 );
36433650
}
36443651

tests/ssl-opt.sh

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3702,8 +3702,8 @@ run_test "DTLS proxy: duplicate every packet" \
37023702
0 \
37033703
-c "replayed record" \
37043704
-s "replayed record" \
3705-
-c "discarding invalid record" \
3706-
-s "discarding invalid record" \
3705+
-c "record from another epoch" \
3706+
-s "record from another epoch" \
37073707
-S "resend" \
37083708
-s "Extra-header:" \
37093709
-c "HTTP/1.0 200 OK"
@@ -3715,8 +3715,8 @@ run_test "DTLS proxy: duplicate every packet, server anti-replay off" \
37153715
0 \
37163716
-c "replayed record" \
37173717
-S "replayed record" \
3718-
-c "discarding invalid record" \
3719-
-s "discarding invalid record" \
3718+
-c "record from another epoch" \
3719+
-s "record from another epoch" \
37203720
-c "resend" \
37213721
-s "resend" \
37223722
-s "Extra-header:" \
@@ -3777,8 +3777,6 @@ run_test "DTLS proxy: delay ChangeCipherSpec" \
37773777
0 \
37783778
-c "record from another epoch" \
37793779
-s "record from another epoch" \
3780-
-c "discarding invalid record" \
3781-
-s "discarding invalid record" \
37823780
-s "Extra-header:" \
37833781
-c "HTTP/1.0 200 OK"
37843782

0 commit comments

Comments
 (0)