Merge branch 'fb-scsv' into dtls
* fb-scsv:
Update Changelog for FALLBACK_SCSV
Implement FALLBACK_SCSV server-side
Implement FALLBACK_SCSV client-side
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index c83e6ac..78572eb 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -658,6 +658,17 @@
*p++ = (unsigned char)( ciphersuites[i] );
}
+ /* Some versions of OpenSSL don't handle it correctly if not at end */
+#if defined(POLARSSL_SSL_FALLBACK_SCSV)
+ if( ssl->fallback == SSL_IS_FALLBACK )
+ {
+ SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
+ *p++ = (unsigned char)( SSL_FALLBACK_SCSV >> 8 );
+ *p++ = (unsigned char)( SSL_FALLBACK_SCSV );
+ n++;
+ }
+#endif
+
*q++ = (unsigned char)( n >> 7 );
*q++ = (unsigned char)( n << 1 );
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 32f1072..809a930 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1088,6 +1088,30 @@
}
}
+#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)
@@ -1719,6 +1743,29 @@
}
}
+#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 */
+
/*
* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
*/
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4549161..f7856ef 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -5411,6 +5411,13 @@
return( 0 );
}
+#if defined(POLARSSL_SSL_FALLBACK_SCSV) && defined(POLARSSL_SSL_CLI_C)
+void ssl_set_fallback( ssl_context *ssl, char fallback )
+{
+ ssl->fallback = fallback;
+}
+#endif
+
#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code )
{