mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-23 17:55:37 +00:00
Merge remote-tracking branch 'origin/pr/2390' into mbedtls-2.7
* origin/pr/2390: Correct length check for DTLS records from old epochs.
This commit is contained in:
commit
3a70ab9319
|
@ -3702,81 +3702,23 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
|
||||||
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check length against bounds of the current transform and version */
|
|
||||||
if( ssl->transform_in == NULL )
|
|
||||||
{
|
|
||||||
if( ssl->in_msglen < 1 ||
|
|
||||||
ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
|
|
||||||
{
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
|
|
||||||
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( ssl->in_msglen < ssl->transform_in->minlen )
|
|
||||||
{
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
|
|
||||||
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_SSL_PROTO_SSL3)
|
|
||||||
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
|
|
||||||
ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_MAX_CONTENT_LEN )
|
|
||||||
{
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
|
|
||||||
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
|
||||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
|
||||||
/*
|
|
||||||
* TLS encrypted messages can have up to 256 bytes of padding
|
|
||||||
*/
|
|
||||||
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 &&
|
|
||||||
ssl->in_msglen > ssl->transform_in->minlen +
|
|
||||||
MBEDTLS_SSL_MAX_CONTENT_LEN + 256 )
|
|
||||||
{
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
|
|
||||||
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DTLS-related tests done last, because most of them may result in
|
* DTLS-related tests.
|
||||||
* silently dropping the record (but not the whole datagram), and we only
|
* Check epoch before checking length constraint because
|
||||||
* want to consider that after ensuring that the "basic" fields (type,
|
* the latter varies with the epoch. E.g., if a ChangeCipherSpec
|
||||||
* version, length) are sane.
|
* message gets duplicated before the corresponding Finished message,
|
||||||
|
* the second ChangeCipherSpec should be discarded because it belongs
|
||||||
|
* to an old epoch, but not because its length is shorter than
|
||||||
|
* the minimum record length for packets using the new record transform.
|
||||||
|
* Note that these two kinds of failures are handled differently,
|
||||||
|
* as an unexpected record is silently skipped but an invalid
|
||||||
|
* record leads to the entire datagram being dropped.
|
||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||||
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
|
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
|
||||||
{
|
{
|
||||||
unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
|
unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
|
||||||
|
|
||||||
/* Drop unexpected ChangeCipherSpec messages */
|
|
||||||
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
|
|
||||||
ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
|
|
||||||
ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
|
|
||||||
{
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ChangeCipherSpec" ) );
|
|
||||||
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Drop unexpected ApplicationData records,
|
|
||||||
* except at the beginning of renegotiations */
|
|
||||||
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
|
|
||||||
ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
|
|
||||||
#if defined(MBEDTLS_SSL_RENEGOTIATION)
|
|
||||||
&& ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
|
|
||||||
ssl->state == MBEDTLS_SSL_SERVER_HELLO )
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
|
|
||||||
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check epoch (and sequence number) with DTLS */
|
/* Check epoch (and sequence number) with DTLS */
|
||||||
if( rec_epoch != ssl->in_epoch )
|
if( rec_epoch != ssl->in_epoch )
|
||||||
{
|
{
|
||||||
|
@ -3816,9 +3758,74 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
|
||||||
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
|
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Drop unexpected ChangeCipherSpec messages */
|
||||||
|
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
|
||||||
|
ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
|
||||||
|
ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
|
||||||
|
{
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ChangeCipherSpec" ) );
|
||||||
|
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drop unexpected ApplicationData records,
|
||||||
|
* except at the beginning of renegotiations */
|
||||||
|
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
|
||||||
|
ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
|
||||||
|
#if defined(MBEDTLS_SSL_RENEGOTIATION)
|
||||||
|
&& ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
|
||||||
|
ssl->state == MBEDTLS_SSL_SERVER_HELLO )
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
|
||||||
|
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_SSL_PROTO_DTLS */
|
#endif /* MBEDTLS_SSL_PROTO_DTLS */
|
||||||
|
|
||||||
|
|
||||||
|
/* Check length against bounds of the current transform and version */
|
||||||
|
if( ssl->transform_in == NULL )
|
||||||
|
{
|
||||||
|
if( ssl->in_msglen < 1 ||
|
||||||
|
ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN )
|
||||||
|
{
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
|
||||||
|
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( ssl->in_msglen < ssl->transform_in->minlen )
|
||||||
|
{
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
|
||||||
|
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_PROTO_SSL3)
|
||||||
|
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
|
||||||
|
ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_MAX_CONTENT_LEN )
|
||||||
|
{
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
|
||||||
|
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||||
|
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||||
|
/*
|
||||||
|
* TLS encrypted messages can have up to 256 bytes of padding
|
||||||
|
*/
|
||||||
|
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 &&
|
||||||
|
ssl->in_msglen > ssl->transform_in->minlen +
|
||||||
|
MBEDTLS_SSL_MAX_CONTENT_LEN + 256 )
|
||||||
|
{
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
|
||||||
|
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5137,8 +5137,8 @@ run_test "DTLS proxy: duplicate every packet" \
|
||||||
0 \
|
0 \
|
||||||
-c "replayed record" \
|
-c "replayed record" \
|
||||||
-s "replayed record" \
|
-s "replayed record" \
|
||||||
-c "discarding invalid record" \
|
-c "record from another epoch" \
|
||||||
-s "discarding invalid record" \
|
-s "record from another epoch" \
|
||||||
-S "resend" \
|
-S "resend" \
|
||||||
-s "Extra-header:" \
|
-s "Extra-header:" \
|
||||||
-c "HTTP/1.0 200 OK"
|
-c "HTTP/1.0 200 OK"
|
||||||
|
@ -5150,8 +5150,8 @@ run_test "DTLS proxy: duplicate every packet, server anti-replay off" \
|
||||||
0 \
|
0 \
|
||||||
-c "replayed record" \
|
-c "replayed record" \
|
||||||
-S "replayed record" \
|
-S "replayed record" \
|
||||||
-c "discarding invalid record" \
|
-c "record from another epoch" \
|
||||||
-s "discarding invalid record" \
|
-s "record from another epoch" \
|
||||||
-c "resend" \
|
-c "resend" \
|
||||||
-s "resend" \
|
-s "resend" \
|
||||||
-s "Extra-header:" \
|
-s "Extra-header:" \
|
||||||
|
@ -5212,8 +5212,6 @@ run_test "DTLS proxy: delay ChangeCipherSpec" \
|
||||||
0 \
|
0 \
|
||||||
-c "record from another epoch" \
|
-c "record from another epoch" \
|
||||||
-s "record from another epoch" \
|
-s "record from another epoch" \
|
||||||
-c "discarding invalid record" \
|
|
||||||
-s "discarding invalid record" \
|
|
||||||
-s "Extra-header:" \
|
-s "Extra-header:" \
|
||||||
-c "HTTP/1.0 200 OK"
|
-c "HTTP/1.0 200 OK"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue