Send TLS alerts in many more cases

The TLS client and server code was usually closing the connection in
case of a fatal error without sending an alert. This commit adds
alerts in many cases.

Added one test case to detect that we send the alert, where a server
complains that the client's certificate is from an unknown CA (case
tracked internally as IOTSSL-1330).
This commit is contained in:
Gilles Peskine 2017-05-03 16:28:34 +02:00
parent 071db41627
commit 1cc8e3472a
4 changed files with 265 additions and 4 deletions

View file

@ -1110,6 +1110,8 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
len != 1 || len != 1 ||
buf[0] != ssl->conf->mfl_code ) buf[0] != ssl->conf->mfl_code )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching max fragment length extension" ) );
mbedtls_ssl_send_fatal_handshake_failure( ssl );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1125,6 +1127,8 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED || if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
len != 0 ) len != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching truncated HMAC extension" ) );
mbedtls_ssl_send_fatal_handshake_failure( ssl );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1145,6 +1149,8 @@ static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
len != 0 ) len != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching encrypt-then-MAC extension" ) );
mbedtls_ssl_send_fatal_handshake_failure( ssl );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1165,6 +1171,8 @@ static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
len != 0 ) len != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching extended master secret extension" ) );
mbedtls_ssl_send_fatal_handshake_failure( ssl );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1184,6 +1192,8 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED || if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
len != 0 ) len != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching session ticket extension" ) );
mbedtls_ssl_send_fatal_handshake_failure( ssl );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1208,6 +1218,8 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
if( list_size + 1 != len ) if( list_size + 1 != len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1232,6 +1244,7 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
} }
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
mbedtls_ssl_send_fatal_handshake_failure( ssl );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
@ -1260,6 +1273,8 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
buf, len ) ) != 0 ) buf, len ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
return( ret );
return( ret ); return( ret );
} }
@ -1276,7 +1291,11 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
/* If we didn't send it, the server shouldn't send it */ /* If we didn't send it, the server shouldn't send it */
if( ssl->conf->alpn_list == NULL ) if( ssl->conf->alpn_list == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) );
mbedtls_ssl_send_fatal_handshake_failure( ssl );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
/* /*
* opaque ProtocolName<1..2^8-1>; * opaque ProtocolName<1..2^8-1>;
@ -1290,15 +1309,27 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
/* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
if( len < 4 ) if( len < 4 )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
list_len = ( buf[0] << 8 ) | buf[1]; list_len = ( buf[0] << 8 ) | buf[1];
if( list_len != len - 2 ) if( list_len != len - 2 )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
name_len = buf[2]; name_len = buf[2];
if( name_len != list_len - 1 ) if( name_len != list_len - 1 )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
/* Check that the server chosen protocol was in our list and save it */ /* Check that the server chosen protocol was in our list and save it */
for( p = ssl->conf->alpn_list; *p != NULL; p++ ) for( p = ssl->conf->alpn_list; *p != NULL; p++ )
@ -1311,6 +1342,8 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
} }
} }
MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) );
mbedtls_ssl_send_fatal_handshake_failure( ssl );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
#endif /* MBEDTLS_SSL_ALPN */ #endif /* MBEDTLS_SSL_ALPN */
@ -1415,6 +1448,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
{ {
/* No alert on a read error. */
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
return( ret ); return( ret );
} }
@ -1440,6 +1474,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_RENEGOTIATION */ #endif /* MBEDTLS_SSL_RENEGOTIATION */
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
} }
@ -1466,6 +1502,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO ) buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1520,6 +1558,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
if( n > 32 ) if( n > 32 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1532,6 +1572,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len ) ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
} }
@ -1542,6 +1584,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
else else
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1569,6 +1613,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
#endif/* MBEDTLS_ZLIB_SUPPORT */ #endif/* MBEDTLS_ZLIB_SUPPORT */
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
} }
@ -1580,6 +1626,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
if( ssl->transform_negotiate->ciphersuite_info == NULL ) if( ssl->transform_negotiate->ciphersuite_info == NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
} }
@ -1617,6 +1665,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( ret ); return( ret );
} }
} }
@ -1636,6 +1686,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1647,6 +1699,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 ) if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -1664,6 +1718,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
ssl->session_negotiate->compression = comp; ssl->session_negotiate->compression = comp;
@ -1682,6 +1738,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
if( ext_size + 4 > ext_len ) if( ext_size + 4 > ext_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
@ -2218,6 +2276,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( ret ); return( ret );
} }
@ -2239,6 +2299,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
} }
@ -2256,6 +2318,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
} }
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
} }
@ -2272,6 +2336,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 ) if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
} /* FALLTROUGH */ } /* FALLTROUGH */
@ -2293,6 +2359,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 ) if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
} }
@ -2309,6 +2377,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 ) if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
} }
@ -2324,6 +2394,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
if( ret != 0 ) if( ret != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
} }
@ -2358,12 +2430,16 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
&md_alg, &pk_alg ) != 0 ) &md_alg, &pk_alg ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) ) if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
} }
@ -2395,6 +2471,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
if( end != p + sig_len ) if( end != p + sig_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
@ -2466,6 +2544,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 ) mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( ret ); return( ret );
} }
@ -2489,6 +2569,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
if( ssl->session_negotiate->peer_cert == NULL ) if( ssl->session_negotiate->peer_cert == NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
} }
@ -2498,12 +2580,16 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
} }
if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
md_alg, hash, hashlen, p, sig_len ) ) != 0 ) md_alg, hash, hashlen, p, sig_len ) ) != 0 )
{ {
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
return( ret ); return( ret );
} }
@ -2579,6 +2665,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
} }
@ -2632,6 +2720,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
} }
@ -2656,6 +2746,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
} }
} }
@ -2669,6 +2761,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n ) if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
} }
@ -2710,6 +2804,8 @@ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE ) ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
} }
@ -3190,6 +3286,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
} }
@ -3207,6 +3305,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) ) ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
} }
@ -3220,6 +3320,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen ) if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
} }
@ -3245,6 +3347,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL ) if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
} }

View file

@ -101,6 +101,8 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
if( servername_list_size + 2 != len ) if( servername_list_size + 2 != len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -111,6 +113,8 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
if( hostname_len + 3 > servername_list_size ) if( hostname_len + 3 > servername_list_size )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -135,6 +139,8 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
if( servername_list_size != 0 ) if( servername_list_size != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -201,6 +207,8 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
sig_alg_list_size % 2 != 0 ) sig_alg_list_size % 2 != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -247,6 +255,8 @@ static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
list_size % 2 != 0 ) list_size % 2 != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -254,6 +264,8 @@ static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
if( ssl->handshake->curves != NULL ) if( ssl->handshake->curves != NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -264,7 +276,11 @@ static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
our_size = MBEDTLS_ECP_DP_MAX; our_size = MBEDTLS_ECP_DP_MAX;
if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL ) if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
}
ssl->handshake->curves = curves; ssl->handshake->curves = curves;
@ -297,6 +313,8 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
if( list_size + 1 != len ) if( list_size + 1 != len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -342,6 +360,8 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
buf, len ) ) != 0 ) buf, len ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( ret ); return( ret );
} }
@ -360,6 +380,8 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ) if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -377,6 +399,8 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
if( len != 0 ) if( len != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -397,6 +421,8 @@ static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
if( len != 0 ) if( len != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -420,6 +446,8 @@ static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
if( len != 0 ) if( len != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -531,11 +559,19 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
/* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
if( len < 4 ) if( len < 4 )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
list_len = ( buf[0] << 8 ) | buf[1]; list_len = ( buf[0] << 8 ) | buf[1];
if( list_len != len - 2 ) if( list_len != len - 2 )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
/* /*
* Use our order of preference * Use our order of preference
@ -549,13 +585,21 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
{ {
/* If the list is well formed, we should get equality first */ /* If the list is well formed, we should get equality first */
if( theirs > end ) if( theirs > end )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
cur_len = *theirs++; cur_len = *theirs++;
/* Empty strings MUST NOT be included */ /* Empty strings MUST NOT be included */
if( cur_len == 0 ) if( cur_len == 0 )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
if( cur_len == ours_len && if( cur_len == ours_len &&
memcmp( theirs, *ours, cur_len ) == 0 ) memcmp( theirs, *ours, cur_len ) == 0 )
@ -1064,6 +1108,9 @@ have_ciphersuite_v2:
} }
#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ #endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
/* This function doesn't alert on errors that happen early during
ClientHello parsing because they might indicate that the client is
not talking SSL/TLS at all and would not understand our alert. */
static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
{ {
int ret, got_common_suite; int ret, got_common_suite;
@ -1098,6 +1145,7 @@ read_record_header:
{ {
if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 )
{ {
/* No alert on a read error. */
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
return( ret ); return( ret );
} }
@ -1349,10 +1397,8 @@ read_record_header:
" [%d:%d] < [%d:%d]", " [%d:%d] < [%d:%d]",
ssl->major_ver, ssl->minor_ver, ssl->major_ver, ssl->minor_ver,
ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
} }
@ -1380,6 +1426,8 @@ read_record_header:
sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */ sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -1403,6 +1451,8 @@ read_record_header:
if( cookie_offset + 1 + cookie_len + 2 > msg_len ) if( cookie_offset + 1 + cookie_len + 2 > msg_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -1435,6 +1485,7 @@ read_record_header:
/* We know we didn't send a cookie, so it should be empty */ /* We know we didn't send a cookie, so it should be empty */
if( cookie_len != 0 ) if( cookie_len != 0 )
{ {
/* This may be an attacker's probe, so don't send an alert */
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -1459,6 +1510,8 @@ read_record_header:
( ciph_len % 2 ) != 0 ) ( ciph_len % 2 ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -1477,6 +1530,8 @@ read_record_header:
comp_len + comp_offset + 1 > msg_len ) comp_len + comp_offset + 1 > msg_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -1515,6 +1570,8 @@ read_record_header:
if( msg_len < ext_offset + 2 ) if( msg_len < ext_offset + 2 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
@ -1525,6 +1582,8 @@ read_record_header:
msg_len != ext_offset + 2 + ext_len ) msg_len != ext_offset + 2 + ext_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
} }
@ -1544,6 +1603,8 @@ read_record_header:
if( ext_size + 4 > ext_len ) if( ext_size + 4 > ext_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
switch( ext_id ) switch( ext_id )
@ -1689,6 +1750,8 @@ read_record_header:
if( ext_len > 0 && ext_len < 4 ) if( ext_len > 0 && ext_len < 4 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
} }

View file

@ -4030,6 +4030,7 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
ssl->out_msglen = 2; ssl->out_msglen = 2;
@ -4041,7 +4042,6 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
return( ret ); return( ret );
} }
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
return( 0 ); return( 0 );
@ -4262,6 +4262,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
{ {
/* mbedtls_ssl_read_record may have sent an alert already. We
let it decide whether to alert. */
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
return( ret ); return( ret );
} }
@ -4283,6 +4285,9 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
/* The client was asked for a certificate but didn't send
one. The client should know what's going on, so we
don't send an alert. */
ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
return( 0 ); return( 0 );
@ -4304,6 +4309,9 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
/* The client was asked for a certificate but didn't send
one. The client should know what's going on, so we
don't send an alert. */
ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
return( 0 ); return( 0 );
@ -4318,6 +4326,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
} }
@ -4325,6 +4335,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 ) ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
} }
@ -4339,6 +4351,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) ) ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
} }
@ -4354,6 +4368,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
sizeof( mbedtls_x509_crt ) ) ); sizeof( mbedtls_x509_crt ) ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
} }
@ -4366,6 +4382,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( ssl->in_msg[i] != 0 ) if( ssl->in_msg[i] != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
} }
@ -4376,13 +4394,35 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( n < 128 || i + n > ssl->in_hslen ) if( n < 128 || i + n > ssl->in_hslen )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
} }
ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert, ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert,
ssl->in_msg + i, n ); ssl->in_msg + i, n );
if( 0 != ret && ( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND ) != ret ) switch( ret )
{ {
uint8_t alert;
case 0: /*ok*/
case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
/* Ignore certificate with an unknown algorithm: maybe a
prior certificate was already trusted. */
break;
case MBEDTLS_ERR_X509_ALLOC_FAILED:
alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
goto crt_parse_der_failed;
case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
goto crt_parse_der_failed;
default:
alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
crt_parse_der_failed:
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret ); MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
return( ret ); return( ret );
} }
@ -4403,6 +4443,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( ssl->session->peer_cert == NULL ) if( ssl->session->peer_cert == NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
} }
@ -4413,6 +4455,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
ssl->session->peer_cert->raw.len ) != 0 ) ssl->session->peer_cert->raw.len ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
} }
} }
@ -4439,6 +4483,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( ca_chain == NULL ) if( ca_chain == NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_BAD_CERT );
return( MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED ); return( MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED );
} }
@ -4489,6 +4535,36 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
ret = 0; ret = 0;
if( ret != 0 )
{
/* The certificate may have been rejected for several reasons.
Pick one and send the corresponding alert. Which alert to send
may be a subject of debate in some cases. */
uint8_t alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER )
alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH )
alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE )
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE )
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE )
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK )
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY )
alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED )
alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED )
alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED )
alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
alert );
}
} }
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
@ -4541,12 +4617,16 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
} }
if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 ) if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC ); return( MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC );
} }
@ -4569,6 +4649,8 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
if( ++ssl->in_epoch == 0 ) if( ++ssl->in_epoch == 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
/* This is highly unlikely to happen for legitimate reasons, so
treat it as an attack and don't send an alert. */
return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
} }
} }
@ -4593,6 +4675,8 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 ) if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
} }
} }
@ -5171,6 +5255,8 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
} }
@ -5186,6 +5272,8 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len ) ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
} }
@ -5193,6 +5281,8 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
buf, hash_len ) != 0 ) buf, hash_len ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
} }

View file

@ -1840,8 +1840,12 @@ run_test "Authentication: client badcert, server required" \
-s "x509_verify_cert() returned" \ -s "x509_verify_cert() returned" \
-s "! The certificate is not correctly signed by the trusted CA" \ -s "! The certificate is not correctly signed by the trusted CA" \
-s "! mbedtls_ssl_handshake returned" \ -s "! mbedtls_ssl_handshake returned" \
-s "send alert level=2 message=48" \
-c "! mbedtls_ssl_handshake returned" \ -c "! mbedtls_ssl_handshake returned" \
-s "X509 - Certificate verification failed" -s "X509 - Certificate verification failed"
# We don't check that the client receives the alert because it might
# detect that its write end of the connection is closed and abort
# before reading the alert message.
run_test "Authentication: client badcert, server optional" \ run_test "Authentication: client badcert, server optional" \
"$P_SRV debug_level=3 auth_mode=optional" \ "$P_SRV debug_level=3 auth_mode=optional" \