diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index a36e74219..875709c7b 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -369,6 +369,7 @@ #define SSL_ALERT_MSG_PROTOCOL_VERSION 70 /* 0x46 */ #define SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71 /* 0x47 */ #define SSL_ALERT_MSG_INTERNAL_ERROR 80 /* 0x50 */ +#define SSL_ALERT_MSG_INAPROPRIATE_FALLBACK 86 /* 0x56 */ #define SSL_ALERT_MSG_USER_CANCELED 90 /* 0x5A */ #define SSL_ALERT_MSG_NO_RENEGOTIATION 100 /* 0x64 */ #define SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */ diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 01b0aca20..57b0ecf30 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -1052,6 +1052,30 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl ) } } +#if defined(POLARSSL_SSL_FALLBACK_SCSV) + for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) + { + if( p[0] == 0 && + p[1] == (unsigned char)( ( SSL_FALLBACK_SCSV >> 8 ) & 0xff ) && + p[2] == (unsigned char)( ( SSL_FALLBACK_SCSV ) & 0xff ) ) + { + SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) ); + + if( ssl->minor_ver < ssl->max_minor_ver ) + { + SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); + + ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); + + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + break; + } + } +#endif /* POLARSSL_SSL_FALLBACK_SCSV */ + ciphersuites = ssl->ciphersuite_list[ssl->minor_ver]; ciphersuite_info = NULL; #if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) @@ -1365,6 +1389,29 @@ static int ssl_parse_client_hello( ssl_context *ssl ) } } +#if defined(POLARSSL_SSL_FALLBACK_SCSV) + for( i = 0, p = buf + 41 + sess_len; i < ciph_len; i += 2, p += 2 ) + { + if( p[0] == (unsigned char)( ( SSL_FALLBACK_SCSV >> 8 ) & 0xff ) && + p[1] == (unsigned char)( ( SSL_FALLBACK_SCSV ) & 0xff ) ) + { + SSL_DEBUG_MSG( 0, ( "received FALLBACK_SCSV" ) ); + + if( ssl->minor_ver < ssl->max_minor_ver ) + { + SSL_DEBUG_MSG( 0, ( "inapropriate fallback" ) ); + + ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); + + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + break; + } + } +#endif /* POLARSSL_SSL_FALLBACK_SCSV */ + ext = buf + 44 + sess_len + ciph_len + comp_len; while( ext_len ) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index ab7793a42..b0dcad95f 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -447,6 +447,8 @@ run_test "Fallback SCSV: default" \ "$P_CLI debug_level=3 force_version=tls1_1" \ 0 \ -C "adding FALLBACK_SCSV" \ + -S "received FALLBACK_SCSV" \ + -S "inapropriate fallback" \ -C "is a fatal alert message (msg 86)" run_test "Fallback SCSV: explicitly disabled" \ @@ -454,13 +456,26 @@ run_test "Fallback SCSV: explicitly disabled" \ "$P_CLI debug_level=3 force_version=tls1_1 fallback=0" \ 0 \ -C "adding FALLBACK_SCSV" \ + -S "received FALLBACK_SCSV" \ + -S "inapropriate fallback" \ -C "is a fatal alert message (msg 86)" run_test "Fallback SCSV: enabled" \ "$P_SRV" \ "$P_CLI debug_level=3 force_version=tls1_1 fallback=1" \ + 1 \ + -c "adding FALLBACK_SCSV" \ + -s "received FALLBACK_SCSV" \ + -s "inapropriate fallback" \ + -c "is a fatal alert message (msg 86)" + +run_test "Fallback SCSV: enabled, max version" \ + "$P_SRV" \ + "$P_CLI debug_level=3 fallback=1" \ 0 \ -c "adding FALLBACK_SCSV" \ + -s "received FALLBACK_SCSV" \ + -S "inapropriate fallback" \ -C "is a fatal alert message (msg 86)" requires_openssl_with_fallback_scsv @@ -479,6 +494,30 @@ run_test "Fallback SCSV: enabled, openssl server" \ -c "adding FALLBACK_SCSV" \ -c "is a fatal alert message (msg 86)" +requires_openssl_with_fallback_scsv +run_test "Fallback SCSV: disabled, openssl client" \ + "$P_SRV" \ + "$O_CLI -tls1_1" \ + 0 \ + -S "received FALLBACK_SCSV" \ + -S "inapropriate fallback" + +requires_openssl_with_fallback_scsv +run_test "Fallback SCSV: enabled, openssl client" \ + "$P_SRV" \ + "$O_CLI -tls1_1 -fallback_scsv" \ + 1 \ + -s "received FALLBACK_SCSV" \ + -s "inapropriate fallback" + +requires_openssl_with_fallback_scsv +run_test "Fallback SCSV: enabled, max version, openssl client" \ + "$P_SRV" \ + "$O_CLI -fallback_scsv" \ + 0 \ + -s "received FALLBACK_SCSV" \ + -S "inapropriate fallback" + # Tests for Session Tickets run_test "Session resume using tickets: basic" \