From e117a8fc0dcdd9c2528856876748cfa8b06e4fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 9 Jan 2015 12:39:35 +0100 Subject: [PATCH] Make truncated hmac a runtime option server-side Reading the documentation of ssl_set_truncated_hmac() may give the impression I changed the default for clients but I didn't, the old documentation was wrong. --- ChangeLog | 4 ++++ include/polarssl/ssl.h | 8 ++++---- library/ssl_srv.c | 3 ++- library/ssl_tls.c | 8 +++++--- programs/ssl/ssl_server2.c | 25 +++++++++++++++++++++++++ tests/ssl-opt.sh | 37 ++++++++++++++++++++++++++++++++----- 6 files changed, 72 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 89c87e057..56436887e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,10 @@ Features * Add support for Extended Master Secret (draft-ietf-tls-session-hash) * Add support for Encrypt-then-MAC (RFC 7366) +Changes + * 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 * Lowest common hash was selected from signature_algorithms extension in diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 82ed04e11..5849a6212 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -1487,15 +1487,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 6d8626cc2..534525a47 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -629,7 +629,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 ea34f66b7..eda3d6da7 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3782,6 +3782,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 ) @@ -4203,9 +4208,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_server2.c b/programs/ssl/ssl_server2.c index 08f2ff864..d962d5b9e 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -109,6 +109,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 @@ -171,6 +172,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 */ @@ -295,6 +297,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" \ @@ -341,6 +350,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 \ @@ -726,6 +736,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; @@ -902,6 +913,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 ) ) @@ -1297,6 +1317,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 1349737f9..e4dc7ea3c 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -428,16 +428,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