diff --git a/ChangeLog b/ChangeLog index 32e20bdb7c..9d1d7eb496 100644 --- a/ChangeLog +++ b/ChangeLog @@ -56,6 +56,8 @@ Changes * A specific error is now returned when there are ciphersuites in common but none of them is usable due to external factors such as no certificate with a suitable (extended)KeyUsage or curve or no PSK set. + * It is now possible to disable neogtiation of truncated HMAC server-side + at runtime with ssl_set_truncated_hmac(). = PolarSSL 1.3.9 released 2014-10-20 Security diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 0c5d8b2668..012e6291ae 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -1523,15 +1523,15 @@ int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code ); #if defined(POLARSSL_SSL_TRUNCATED_HMAC) /** - * \brief Activate negotiation of truncated HMAC (Client only) - * (Default: SSL_TRUNC_HMAC_ENABLED) + * \brief Activate negotiation of truncated HMAC + * (Default: SSL_TRUNC_HMAC_DISABLED on client, + * SSL_TRUNC_HMAC_ENABLED on server.) * * \param ssl SSL context * \param truncate Enable or disable (SSL_TRUNC_HMAC_ENABLED or * SSL_TRUNC_HMAC_DISABLED) * - * \return O if successful, - * POLARSSL_ERR_SSL_BAD_INPUT_DATA if used server-side + * \return Always 0. */ int ssl_set_truncated_hmac( ssl_context *ssl, int truncate ); #endif /* POLARSSL_SSL_TRUNCATED_HMAC */ diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 4420e22953..1fa9e76d2d 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -633,7 +633,8 @@ static int ssl_parse_truncated_hmac_ext( ssl_context *ssl, ((void) buf); - ssl->session_negotiate->trunc_hmac = SSL_TRUNC_HMAC_ENABLED; + if( ssl->trunc_hmac == SSL_TRUNC_HMAC_ENABLED ) + ssl->session_negotiate->trunc_hmac = SSL_TRUNC_HMAC_ENABLED; return( 0 ); } diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 6b9df33695..050939b6e0 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3833,6 +3833,11 @@ void ssl_set_endpoint( ssl_context *ssl, int endpoint ) if( endpoint == SSL_IS_CLIENT ) ssl->session_tickets = SSL_SESSION_TICKETS_ENABLED; #endif + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + if( endpoint == SSL_IS_SERVER ) + ssl->trunc_hmac = SSL_TRUNC_HMAC_ENABLED; +#endif } void ssl_set_authmode( ssl_context *ssl, int authmode ) @@ -4258,9 +4263,6 @@ int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code ) #if defined(POLARSSL_SSL_TRUNCATED_HMAC) int ssl_set_truncated_hmac( ssl_context *ssl, int truncate ) { - if( ssl->endpoint != SSL_IS_CLIENT ) - return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); - ssl->trunc_hmac = truncate; return( 0 ); diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 71f5efa301..2e3364d40a 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -90,7 +90,7 @@ int main( int argc, char *argv[] ) #define DFL_MAX_VERSION -1 #define DFL_AUTH_MODE SSL_VERIFY_REQUIRED #define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE -#define DFL_TRUNC_HMAC 0 +#define DFL_TRUNC_HMAC -1 #define DFL_RECSPLIT -1 #define DFL_RECONNECT 0 #define DFL_RECO_DELAY 0 @@ -264,7 +264,7 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags ) #if defined(POLARSSL_SSL_TRUNCATED_HMAC) #define USAGE_TRUNC_HMAC \ - " trunc_hmac=%%d default: 0 (disabled)\n" + " trunc_hmac=%%d default: library default\n" #else #define USAGE_TRUNC_HMAC "" #endif /* POLARSSL_SSL_TRUNCATED_HMAC */ @@ -678,9 +678,12 @@ int main( int argc, char *argv[] ) } else if( strcmp( p, "trunc_hmac" ) == 0 ) { - opt.trunc_hmac = atoi( q ); - if( opt.trunc_hmac < 0 || opt.trunc_hmac > 1 ) - goto usage; + switch( atoi( q ) ) + { + case 0: opt.trunc_hmac = SSL_TRUNC_HMAC_DISABLED; break; + case 1: opt.trunc_hmac = SSL_TRUNC_HMAC_ENABLED; break; + default: goto usage; + } } else if( strcmp( p, "recsplit" ) == 0 ) { @@ -962,12 +965,8 @@ int main( int argc, char *argv[] ) #endif #if defined(POLARSSL_SSL_TRUNCATED_HMAC) - if( opt.trunc_hmac != 0 ) - if( ( ret = ssl_set_truncated_hmac( &ssl, SSL_TRUNC_HMAC_ENABLED ) ) != 0 ) - { - printf( " failed\n ! ssl_set_truncated_hmac returned %d\n\n", ret ); - goto exit; - } + if( opt.trunc_hmac != DFL_TRUNC_HMAC ) + ssl_set_truncated_hmac( &ssl, opt.trunc_hmac ); #endif #if defined(POLARSSL_SSL_EXTENDED_MASTER_SECRET) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 18513c9fd0..bf99b1905a 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -110,6 +110,7 @@ int main( int argc, char *argv[] ) #define DFL_MAX_VERSION -1 #define DFL_AUTH_MODE SSL_VERIFY_OPTIONAL #define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE +#define DFL_TRUNC_HMAC -1 #define DFL_TICKETS SSL_SESSION_TICKETS_ENABLED #define DFL_TICKET_TIMEOUT -1 #define DFL_CACHE_MAX -1 @@ -173,6 +174,7 @@ struct options int max_version; /* maximum protocol version accepted */ int auth_mode; /* verify mode for connection */ unsigned char mfl_code; /* code for maximum fragment length */ + int trunc_hmac; /* accept truncated hmac? */ int tickets; /* enable / disable session tickets */ int ticket_timeout; /* session ticket lifetime */ int cache_max; /* max number of session cache entries */ @@ -297,6 +299,13 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len ) #define USAGE_MAX_FRAG_LEN "" #endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) +#define USAGE_TRUNC_HMAC \ + " trunc_hmac=%%d default: library default\n" +#else +#define USAGE_TRUNC_HMAC "" +#endif + #if defined(POLARSSL_SSL_ALPN) #define USAGE_ALPN \ " alpn=%%s default: \"\" (disabled)\n" \ @@ -351,6 +360,7 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len ) USAGE_TICKETS \ USAGE_CACHE \ USAGE_MAX_FRAG_LEN \ + USAGE_TRUNC_HMAC \ USAGE_ALPN \ USAGE_EMS \ USAGE_ETM \ @@ -741,6 +751,7 @@ int main( int argc, char *argv[] ) opt.max_version = DFL_MAX_VERSION; opt.auth_mode = DFL_AUTH_MODE; opt.mfl_code = DFL_MFL_CODE; + opt.trunc_hmac = DFL_TRUNC_HMAC; opt.tickets = DFL_TICKETS; opt.ticket_timeout = DFL_TICKET_TIMEOUT; opt.cache_max = DFL_CACHE_MAX; @@ -927,6 +938,15 @@ int main( int argc, char *argv[] ) { opt.alpn_string = q; } + else if( strcmp( p, "trunc_hmac" ) == 0 ) + { + switch( atoi( q ) ) + { + case 0: opt.trunc_hmac = SSL_TRUNC_HMAC_DISABLED; break; + case 1: opt.trunc_hmac = SSL_TRUNC_HMAC_ENABLED; break; + default: goto usage; + } + } else if( strcmp( p, "extended_ms" ) == 0 ) { switch( atoi( q ) ) @@ -1322,6 +1342,11 @@ int main( int argc, char *argv[] ) }; #endif +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + if( opt.trunc_hmac != DFL_TRUNC_HMAC ) + ssl_set_truncated_hmac( &ssl, opt.trunc_hmac ); +#endif + #if defined(POLARSSL_SSL_EXTENDED_MASTER_SECRET) if( opt.extended_ms != DFL_EXTENDED_MS ) ssl_set_extended_master_secret( &ssl, opt.extended_ms ); diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 42e4eee8ba..2874c819ab 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -429,16 +429,43 @@ run_test "SSLv2 ClientHello: actual test" \ # Tests for Truncated HMAC extension -run_test "Truncated HMAC: reference" \ +run_test "Truncated HMAC: client default, server default" \ "$P_SRV debug_level=4" \ - "$P_CLI trunc_hmac=0 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \ + "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \ 0 \ - -s "dumping 'computed mac' (20 bytes)" + -s "dumping 'computed mac' (20 bytes)" \ + -S "dumping 'computed mac' (10 bytes)" -run_test "Truncated HMAC: actual test" \ +run_test "Truncated HMAC: client disabled, server default" \ "$P_SRV debug_level=4" \ - "$P_CLI trunc_hmac=1 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \ + "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \ + trunc_hmac=0" \ 0 \ + -s "dumping 'computed mac' (20 bytes)" \ + -S "dumping 'computed mac' (10 bytes)" + +run_test "Truncated HMAC: client enabled, server default" \ + "$P_SRV debug_level=4" \ + "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \ + trunc_hmac=1" \ + 0 \ + -S "dumping 'computed mac' (20 bytes)" \ + -s "dumping 'computed mac' (10 bytes)" + +run_test "Truncated HMAC: client enabled, server disabled" \ + "$P_SRV debug_level=4 trunc_hmac=0" \ + "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \ + trunc_hmac=1" \ + 0 \ + -s "dumping 'computed mac' (20 bytes)" \ + -S "dumping 'computed mac' (10 bytes)" + +run_test "Truncated HMAC: client enabled, server enabled" \ + "$P_SRV debug_level=4 trunc_hmac=1" \ + "$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA \ + trunc_hmac=1" \ + 0 \ + -S "dumping 'computed mac' (20 bytes)" \ -s "dumping 'computed mac' (10 bytes)" # Tests for Encrypt-then-MAC extension