Merge commit '36adc36' into dtls

* commit '36adc36':
  Add support for getrandom()
  Use library default for trunc-hmac in ssl_client2
  Make truncated hmac a runtime option server-side
  Fix portability issue in script
  Specific error for suites in common but none good
  Prefer SHA-1 certificates for pre-1.2 clients
  Some more refactoring/tuning.
  Minor refactoring

Conflicts:
	include/polarssl/error.h
	include/polarssl/ssl.h
	library/error.c
This commit is contained in:
Manuel Pégourié-Gonnard 2015-01-21 13:48:45 +00:00
commit bfccdd3c92
11 changed files with 262 additions and 63 deletions

View File

@ -39,6 +39,10 @@ Features
length of an X.509 verification chain. length of an X.509 verification chain.
* Support for renegotiation can now be disabled at compile-time * Support for renegotiation can now be disabled at compile-time
* Support for 1/n-1 record splitting, a countermeasure against BEAST. * Support for 1/n-1 record splitting, a countermeasure against BEAST.
* Certificate selection based on signature hash, prefering SHA-1 over SHA-2
for pre-1.2 clients when multiple certificates are available.
* Add support for getrandom() syscall on recent Linux kernels with Glibc or
a compatible enough libc (eg uClibc).
Bugfix Bugfix
* Stack buffer overflow if ctr_drbg_update() is called with too large * Stack buffer overflow if ctr_drbg_update() is called with too large
@ -61,6 +65,11 @@ Changes
* debug_print_buf() now prints a text view in addition to hexadecimal. * debug_print_buf() now prints a text view in addition to hexadecimal.
* Skip writing and parsing signature_algorithm extension if none of the * Skip writing and parsing signature_algorithm extension if none of the
key exchanges enabled needs certificates. key exchanges enabled needs certificates.
* 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 = PolarSSL 1.3.9 released 2014-10-20
Security Security

View File

@ -91,7 +91,7 @@
* ECP 4 8 (Started from top) * ECP 4 8 (Started from top)
* MD 5 4 * MD 5 4
* CIPHER 6 6 * CIPHER 6 6
* SSL 6 12 (Started from top) * SSL 6 13 (Started from top)
* SSL 7 31 * SSL 7 31
* *
* Module dependent error code (5 bits 0x.00.-0x.F8.) * Module dependent error code (5 bits 0x.00.-0x.F8.)

View File

@ -158,6 +158,7 @@
#define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -0x6B00 /**< Unexpected message at ServerHello in renegotiation. */ #define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -0x6B00 /**< Unexpected message at ServerHello in renegotiation. */
#define POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED -0x6A80 /**< DTLS client must retry for hello verification */ #define POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED -0x6A80 /**< DTLS client must retry for hello verification */
#define POLARSSL_ERR_SSL_BUFFER_TOO_SMALL -0x6A00 /**< A buffer is too small to receive or write a message */ #define POLARSSL_ERR_SSL_BUFFER_TOO_SMALL -0x6A00 /**< A buffer is too small to receive or write a message */
#define POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE -0x6980 /**< None of the common ciphersuites is usable (eg, no suitable certificate) */
/* /*
* Various constants * Various constants
@ -1851,15 +1852,15 @@ int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code );
#if defined(POLARSSL_SSL_TRUNCATED_HMAC) #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
/** /**
* \brief Activate negotiation of truncated HMAC (Client only) * \brief Activate negotiation of truncated HMAC
* (Default: SSL_TRUNC_HMAC_ENABLED) * (Default: SSL_TRUNC_HMAC_DISABLED on client,
* SSL_TRUNC_HMAC_ENABLED on server.)
* *
* \param ssl SSL context * \param ssl SSL context
* \param truncate Enable or disable (SSL_TRUNC_HMAC_ENABLED or * \param truncate Enable or disable (SSL_TRUNC_HMAC_ENABLED or
* SSL_TRUNC_HMAC_DISABLED) * SSL_TRUNC_HMAC_DISABLED)
* *
* \return O if successful, * \return Always 0.
* POLARSSL_ERR_SSL_BAD_INPUT_DATA if used server-side
*/ */
int ssl_set_truncated_hmac( ssl_context *ssl, int truncate ); int ssl_set_truncated_hmac( ssl_context *ssl, int truncate );
#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ #endif /* POLARSSL_SSL_TRUNCATED_HMAC */

View File

@ -73,6 +73,43 @@ int platform_entropy_poll( void *data, unsigned char *output, size_t len,
} }
#else /* _WIN32 && !EFIX64 && !EFI32 */ #else /* _WIN32 && !EFIX64 && !EFI32 */
/*
* Test for Linux getrandom() support.
* Since there is no wrapper in the libc yet, use the generic syscall wrapper
* available in GNU libc and compatible libc's (eg uClibc).
*/
#if defined(__linux__) && defined(__GLIBC__)
#include <linux/version.h>
#include <unistd.h>
#include <sys/syscall.h>
#if defined(SYS_getrandom)
#define HAVE_GETRANDOM
static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
{
return( syscall( SYS_getrandom, buf, buflen, flags ) );
}
#endif /* SYS_getrandom */
#endif /* __linux__ */
#if defined(HAVE_GETRANDOM)
#include <errno.h>
int platform_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
int ret;
((void) data);
if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
*olen = ret;
return( 0 );
}
#else /* HAVE_GETRANDOM */
#include <stdio.h> #include <stdio.h>
int platform_entropy_poll( void *data, int platform_entropy_poll( void *data,
@ -100,6 +137,7 @@ int platform_entropy_poll( void *data,
return( 0 ); return( 0 );
} }
#endif /* HAVE_GETRANDOM */
#endif /* _WIN32 && !EFIX64 && !EFI32 */ #endif /* _WIN32 && !EFIX64 && !EFI32 */
#endif /* !POLARSSL_NO_PLATFORM_ENTROPY */ #endif /* !POLARSSL_NO_PLATFORM_ENTROPY */

View File

@ -456,6 +456,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen )
snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" ); snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" );
if( use_ret == -(POLARSSL_ERR_SSL_BUFFER_TOO_SMALL) ) if( use_ret == -(POLARSSL_ERR_SSL_BUFFER_TOO_SMALL) )
snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" ); snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" );
if( use_ret == -(POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE) )
snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate)" );
#endif /* POLARSSL_SSL_TLS_C */ #endif /* POLARSSL_SSL_TLS_C */
#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) #if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C)

View File

@ -663,6 +663,7 @@ static int ssl_parse_truncated_hmac_ext( ssl_context *ssl,
((void) buf); ((void) buf);
if( ssl->trunc_hmac == SSL_TRUNC_HMAC_ENABLED )
ssl->session_negotiate->trunc_hmac = SSL_TRUNC_HMAC_ENABLED; ssl->session_negotiate->trunc_hmac = SSL_TRUNC_HMAC_ENABLED;
return( 0 ); return( 0 );
@ -831,10 +832,10 @@ static int ssl_parse_alpn_ext( ssl_context *ssl,
#if defined(POLARSSL_X509_CRT_PARSE_C) #if defined(POLARSSL_X509_CRT_PARSE_C)
/* /*
* Return 1 if the given EC key uses the given curve, 0 otherwise * Return 0 if the given key uses one of the acceptable curves, -1 otherwise
*/ */
#if defined(POLARSSL_ECDSA_C) #if defined(POLARSSL_ECDSA_C)
static int ssl_key_matches_curves( pk_context *pk, static int ssl_check_key_curve( pk_context *pk,
const ecp_curve_info **curves ) const ecp_curve_info **curves )
{ {
const ecp_curve_info **crv = curves; const ecp_curve_info **crv = curves;
@ -843,11 +844,11 @@ static int ssl_key_matches_curves( pk_context *pk,
while( *crv != NULL ) while( *crv != NULL )
{ {
if( (*crv)->grp_id == grp_id ) if( (*crv)->grp_id == grp_id )
return( 1 ); return( 0 );
crv++; crv++;
} }
return( 0 ); return( -1 );
} }
#endif /* POLARSSL_ECDSA_C */ #endif /* POLARSSL_ECDSA_C */
@ -858,7 +859,7 @@ static int ssl_key_matches_curves( pk_context *pk,
static int ssl_pick_cert( ssl_context *ssl, static int ssl_pick_cert( ssl_context *ssl,
const ssl_ciphersuite_t * ciphersuite_info ) const ssl_ciphersuite_t * ciphersuite_info )
{ {
ssl_key_cert *cur, *list; ssl_key_cert *cur, *list, *fallback = NULL;
pk_type_t pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); pk_type_t pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) #if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
@ -891,22 +892,42 @@ static int ssl_pick_cert( ssl_context *ssl,
} }
#if defined(POLARSSL_ECDSA_C) #if defined(POLARSSL_ECDSA_C)
if( pk_alg == POLARSSL_PK_ECDSA ) if( pk_alg == POLARSSL_PK_ECDSA &&
{ ssl_check_key_curve( cur->key, ssl->handshake->curves ) != 0 )
if( ssl_key_matches_curves( cur->key, ssl->handshake->curves ) ) continue;
break;
}
else
#endif #endif
/*
* Try to select a SHA-1 certificate for pre-1.2 clients, but still
* present them a SHA-higher cert rather than failing if it's the only
* one we got that satisfies the other conditions.
*/
if( ssl->minor_ver < SSL_MINOR_VERSION_3 &&
cur->cert->sig_md != POLARSSL_MD_SHA1 )
{
if( fallback == NULL )
fallback = cur;
continue;
}
/* If we get there, we got a winner */
break; break;
} }
if( cur == NULL ) if( cur != NULL )
return( -1 ); {
ssl->handshake->key_cert = cur; ssl->handshake->key_cert = cur;
return( 0 ); return( 0 );
} }
if( fallback != NULL )
{
ssl->handshake->key_cert = fallback;
return( 0 );
}
return( -1 );
}
#endif /* POLARSSL_X509_CRT_PARSE_C */ #endif /* POLARSSL_X509_CRT_PARSE_C */
/* /*
@ -921,8 +942,8 @@ static int ssl_ciphersuite_match( ssl_context *ssl, int suite_id,
suite_info = ssl_ciphersuite_from_id( suite_id ); suite_info = ssl_ciphersuite_from_id( suite_id );
if( suite_info == NULL ) if( suite_info == NULL )
{ {
SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", suite_id ) ); SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
} }
if( suite_info->min_minor_ver > ssl->minor_ver || if( suite_info->min_minor_ver > ssl->minor_ver ||
@ -971,7 +992,7 @@ static int ssl_ciphersuite_match( ssl_context *ssl, int suite_id,
#if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) #if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
static int ssl_parse_client_hello_v2( ssl_context *ssl ) static int ssl_parse_client_hello_v2( ssl_context *ssl )
{ {
int ret; int ret, got_common_suite;
unsigned int i, j; unsigned int i, j;
size_t n; size_t n;
unsigned int ciph_len, sess_len, chal_len; unsigned int ciph_len, sess_len, chal_len;
@ -1169,6 +1190,7 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl )
} }
#endif /* POLARSSL_SSL_FALLBACK_SCSV */ #endif /* POLARSSL_SSL_FALLBACK_SCSV */
got_common_suite = 0;
ciphersuites = ssl->ciphersuite_list[ssl->minor_ver]; ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
ciphersuite_info = NULL; ciphersuite_info = NULL;
#if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) #if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
@ -1186,6 +1208,8 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl )
p[2] != ( ( ciphersuites[i] ) & 0xFF ) ) p[2] != ( ( ciphersuites[i] ) & 0xFF ) )
continue; continue;
got_common_suite = 1;
if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
&ciphersuite_info ) ) != 0 ) &ciphersuite_info ) ) != 0 )
return( ret ); return( ret );
@ -1195,9 +1219,17 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl )
} }
} }
if( got_common_suite )
{
SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, "
"but none of them usable" ) );
return( POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE );
}
else
{
SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
}
have_ciphersuite_v2: have_ciphersuite_v2:
ssl->session_negotiate->ciphersuite = ciphersuites[i]; ssl->session_negotiate->ciphersuite = ciphersuites[i];
@ -1229,7 +1261,7 @@ have_ciphersuite_v2:
static int ssl_parse_client_hello( ssl_context *ssl ) static int ssl_parse_client_hello( ssl_context *ssl )
{ {
int ret; int ret, got_common_suite;
unsigned int i, j; unsigned int i, j;
unsigned int ciph_offset, comp_offset, ext_offset; unsigned int ciph_offset, comp_offset, ext_offset;
unsigned int msg_len, ciph_len, sess_len, comp_len, ext_len; unsigned int msg_len, ciph_len, sess_len, comp_len, ext_len;
@ -1923,6 +1955,7 @@ read_record_header:
* (At the end because we need information from the EC-based extensions * (At the end because we need information from the EC-based extensions
* and certificate from the SNI callback triggered by the SNI extension.) * and certificate from the SNI callback triggered by the SNI extension.)
*/ */
got_common_suite = 0;
ciphersuites = ssl->ciphersuite_list[ssl->minor_ver]; ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
ciphersuite_info = NULL; ciphersuite_info = NULL;
#if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) #if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
@ -1939,6 +1972,8 @@ read_record_header:
p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) p[1] != ( ( ciphersuites[i] ) & 0xFF ) )
continue; continue;
got_common_suite = 1;
if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
&ciphersuite_info ) ) != 0 ) &ciphersuite_info ) ) != 0 )
return( ret ); return( ret );
@ -1948,12 +1983,19 @@ read_record_header:
} }
} }
if( got_common_suite )
{
SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, "
"but none of them usable" ) );
ssl_send_fatal_handshake_failure( ssl );
return( POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE );
}
else
{
SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
ssl_send_fatal_handshake_failure( ssl );
if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
return( ret );
return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
}
have_ciphersuite: have_ciphersuite:
ssl->session_negotiate->ciphersuite = ciphersuites[i]; ssl->session_negotiate->ciphersuite = ciphersuites[i];

View File

@ -5149,6 +5149,11 @@ void ssl_set_endpoint( ssl_context *ssl, int endpoint )
if( endpoint == SSL_IS_CLIENT ) if( endpoint == SSL_IS_CLIENT )
ssl->session_tickets = SSL_SESSION_TICKETS_ENABLED; ssl->session_tickets = SSL_SESSION_TICKETS_ENABLED;
#endif #endif
#if defined(POLARSSL_SSL_TRUNCATED_HMAC)
if( endpoint == SSL_IS_SERVER )
ssl->trunc_hmac = SSL_TRUNC_HMAC_ENABLED;
#endif
} }
int ssl_set_transport( ssl_context *ssl, int transport ) int ssl_set_transport( ssl_context *ssl, int transport )
@ -5692,9 +5697,6 @@ int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code )
#if defined(POLARSSL_SSL_TRUNCATED_HMAC) #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
int ssl_set_truncated_hmac( ssl_context *ssl, int truncate ) 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; ssl->trunc_hmac = truncate;
return( 0 ); return( 0 );

View File

@ -92,7 +92,7 @@ int main( int argc, char *argv[] )
#define DFL_MAX_VERSION -1 #define DFL_MAX_VERSION -1
#define DFL_AUTH_MODE SSL_VERIFY_REQUIRED #define DFL_AUTH_MODE SSL_VERIFY_REQUIRED
#define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE #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_RECSPLIT -1
#define DFL_RECONNECT 0 #define DFL_RECONNECT 0
#define DFL_RECO_DELAY 0 #define DFL_RECO_DELAY 0
@ -274,7 +274,7 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
#if defined(POLARSSL_SSL_TRUNCATED_HMAC) #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
#define USAGE_TRUNC_HMAC \ #define USAGE_TRUNC_HMAC \
" trunc_hmac=%%d default: 0 (disabled)\n" " trunc_hmac=%%d default: library default\n"
#else #else
#define USAGE_TRUNC_HMAC "" #define USAGE_TRUNC_HMAC ""
#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ #endif /* POLARSSL_SSL_TRUNCATED_HMAC */
@ -740,9 +740,12 @@ int main( int argc, char *argv[] )
} }
else if( strcmp( p, "trunc_hmac" ) == 0 ) else if( strcmp( p, "trunc_hmac" ) == 0 )
{ {
opt.trunc_hmac = atoi( q ); switch( atoi( q ) )
if( opt.trunc_hmac < 0 || opt.trunc_hmac > 1 ) {
goto usage; 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, "hs_timeout" ) == 0 ) else if( strcmp( p, "hs_timeout" ) == 0 )
{ {
@ -1057,12 +1060,8 @@ int main( int argc, char *argv[] )
#endif #endif
#if defined(POLARSSL_SSL_TRUNCATED_HMAC) #if defined(POLARSSL_SSL_TRUNCATED_HMAC)
if( opt.trunc_hmac != 0 ) if( opt.trunc_hmac != DFL_TRUNC_HMAC )
if( ( ret = ssl_set_truncated_hmac( &ssl, SSL_TRUNC_HMAC_ENABLED ) ) != 0 ) ssl_set_truncated_hmac( &ssl, opt.trunc_hmac );
{
printf( " failed\n ! ssl_set_truncated_hmac returned %d\n\n", ret );
goto exit;
}
#endif #endif
#if defined(POLARSSL_SSL_EXTENDED_MASTER_SECRET) #if defined(POLARSSL_SSL_EXTENDED_MASTER_SECRET)

View File

@ -115,6 +115,7 @@ int main( int argc, char *argv[] )
#define DFL_MAX_VERSION -1 #define DFL_MAX_VERSION -1
#define DFL_AUTH_MODE SSL_VERIFY_OPTIONAL #define DFL_AUTH_MODE SSL_VERIFY_OPTIONAL
#define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE #define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE
#define DFL_TRUNC_HMAC -1
#define DFL_TICKETS SSL_SESSION_TICKETS_ENABLED #define DFL_TICKETS SSL_SESSION_TICKETS_ENABLED
#define DFL_TICKET_TIMEOUT -1 #define DFL_TICKET_TIMEOUT -1
#define DFL_CACHE_MAX -1 #define DFL_CACHE_MAX -1
@ -185,6 +186,7 @@ struct options
int max_version; /* maximum protocol version accepted */ int max_version; /* maximum protocol version accepted */
int auth_mode; /* verify mode for connection */ int auth_mode; /* verify mode for connection */
unsigned char mfl_code; /* code for maximum fragment length */ unsigned char mfl_code; /* code for maximum fragment length */
int trunc_hmac; /* accept truncated hmac? */
int tickets; /* enable / disable session tickets */ int tickets; /* enable / disable session tickets */
int ticket_timeout; /* session ticket lifetime */ int ticket_timeout; /* session ticket lifetime */
int cache_max; /* max number of session cache entries */ int cache_max; /* max number of session cache entries */
@ -315,6 +317,13 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
#define USAGE_MAX_FRAG_LEN "" #define USAGE_MAX_FRAG_LEN ""
#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ #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) #if defined(POLARSSL_SSL_ALPN)
#define USAGE_ALPN \ #define USAGE_ALPN \
" alpn=%%s default: \"\" (disabled)\n" \ " alpn=%%s default: \"\" (disabled)\n" \
@ -407,6 +416,7 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
USAGE_TICKETS \ USAGE_TICKETS \
USAGE_CACHE \ USAGE_CACHE \
USAGE_MAX_FRAG_LEN \ USAGE_MAX_FRAG_LEN \
USAGE_TRUNC_HMAC \
USAGE_ALPN \ USAGE_ALPN \
USAGE_EMS \ USAGE_EMS \
USAGE_ETM \ USAGE_ETM \
@ -805,6 +815,7 @@ int main( int argc, char *argv[] )
opt.max_version = DFL_MAX_VERSION; opt.max_version = DFL_MAX_VERSION;
opt.auth_mode = DFL_AUTH_MODE; opt.auth_mode = DFL_AUTH_MODE;
opt.mfl_code = DFL_MFL_CODE; opt.mfl_code = DFL_MFL_CODE;
opt.trunc_hmac = DFL_TRUNC_HMAC;
opt.tickets = DFL_TICKETS; opt.tickets = DFL_TICKETS;
opt.ticket_timeout = DFL_TICKET_TIMEOUT; opt.ticket_timeout = DFL_TICKET_TIMEOUT;
opt.cache_max = DFL_CACHE_MAX; opt.cache_max = DFL_CACHE_MAX;
@ -1025,6 +1036,15 @@ int main( int argc, char *argv[] )
{ {
opt.alpn_string = q; 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 ) else if( strcmp( p, "extended_ms" ) == 0 )
{ {
switch( atoi( q ) ) switch( atoi( q ) )
@ -1475,6 +1495,11 @@ int main( int argc, char *argv[] )
}; };
#endif #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 defined(POLARSSL_SSL_EXTENDED_MASTER_SECRET)
if( opt.extended_ms != DFL_EXTENDED_MS ) if( opt.extended_ms != DFL_EXTENDED_MS )
ssl_set_extended_master_secret( &ssl, opt.extended_ms ); ssl_set_extended_master_secret( &ssl, opt.extended_ms );

View File

@ -46,7 +46,7 @@ close(FORMAT_FILE);
$/ = $line_separator; $/ = $line_separator;
open(GREP, "/bin/grep \"define POLARSSL_ERR_\" $include_dir/* |") || die("Failure when calling grep: $!"); open(GREP, "grep \"define POLARSSL_ERR_\" $include_dir/* |") || die("Failure when calling grep: $!");
my $ll_old_define = ""; my $ll_old_define = "";
my $hl_old_define = ""; my $hl_old_define = "";

View File

@ -558,16 +558,43 @@ run_test "SSLv2 ClientHello: actual test" \
# Tests for Truncated HMAC extension # Tests for Truncated HMAC extension
run_test "Truncated HMAC: reference" \ run_test "Truncated HMAC: client default, server default" \
"$P_SRV debug_level=4" \ "$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 \ 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_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 \ 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)" -s "dumping 'computed mac' (10 bytes)"
# Tests for Encrypt-then-MAC extension # Tests for Encrypt-then-MAC extension
@ -1604,6 +1631,60 @@ run_test "Authentication: client no cert, ssl3" \
-C "! ssl_handshake returned" \ -C "! ssl_handshake returned" \
-S "X509 - Certificate verification failed" -S "X509 - Certificate verification failed"
# Tests for certificate selection based on SHA verson
run_test "Certificate hash: client TLS 1.2 -> SHA-2" \
"$P_SRV crt_file=data_files/server5.crt \
key_file=data_files/server5.key \
crt_file2=data_files/server5-sha1.crt \
key_file2=data_files/server5.key" \
"$P_CLI force_version=tls1_2" \
0 \
-c "signed using.*ECDSA with SHA256" \
-C "signed using.*ECDSA with SHA1"
run_test "Certificate hash: client TLS 1.1 -> SHA-1" \
"$P_SRV crt_file=data_files/server5.crt \
key_file=data_files/server5.key \
crt_file2=data_files/server5-sha1.crt \
key_file2=data_files/server5.key" \
"$P_CLI force_version=tls1_1" \
0 \
-C "signed using.*ECDSA with SHA256" \
-c "signed using.*ECDSA with SHA1"
run_test "Certificate hash: client TLS 1.0 -> SHA-1" \
"$P_SRV crt_file=data_files/server5.crt \
key_file=data_files/server5.key \
crt_file2=data_files/server5-sha1.crt \
key_file2=data_files/server5.key" \
"$P_CLI force_version=tls1" \
0 \
-C "signed using.*ECDSA with SHA256" \
-c "signed using.*ECDSA with SHA1"
run_test "Certificate hash: client TLS 1.1, no SHA-1 -> SHA-2 (order 1)" \
"$P_SRV crt_file=data_files/server5.crt \
key_file=data_files/server5.key \
crt_file2=data_files/server6.crt \
key_file2=data_files/server6.key" \
"$P_CLI force_version=tls1_1" \
0 \
-c "serial number.*09" \
-c "signed using.*ECDSA with SHA256" \
-C "signed using.*ECDSA with SHA1"
run_test "Certificate hash: client TLS 1.1, no SHA-1 -> SHA-2 (order 2)" \
"$P_SRV crt_file=data_files/server6.crt \
key_file=data_files/server6.key \
crt_file2=data_files/server5.crt \
key_file2=data_files/server5.key" \
"$P_CLI force_version=tls1_1" \
0 \
-c "serial number.*0A" \
-c "signed using.*ECDSA with SHA256" \
-C "signed using.*ECDSA with SHA1"
# tests for SNI # tests for SNI
run_test "SNI: no SNI callback" \ run_test "SNI: no SNI callback" \
@ -2152,7 +2233,7 @@ run_test "PSK callback: psk, no callback" \
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \ "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123" \ psk_identity=foo psk=abc123" \
0 \ 0 \
-S "SSL - The server has no ciphersuites in common" \ -S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \ -S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed" -S "SSL - Verification of the message MAC failed"
@ -2161,7 +2242,7 @@ run_test "PSK callback: no psk, no callback" \
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \ "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123" \ psk_identity=foo psk=abc123" \
1 \ 1 \
-s "SSL - The server has no ciphersuites in common" \ -s "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \ -S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed" -S "SSL - Verification of the message MAC failed"
@ -2170,7 +2251,7 @@ run_test "PSK callback: callback overrides other settings" \
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \ "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=foo psk=abc123" \ psk_identity=foo psk=abc123" \
1 \ 1 \
-S "SSL - The server has no ciphersuites in common" \ -S "SSL - None of the common ciphersuites is usable" \
-s "SSL - Unknown identity received" \ -s "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed" -S "SSL - Verification of the message MAC failed"
@ -2179,7 +2260,7 @@ run_test "PSK callback: first id matches" \
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \ "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=abc psk=dead" \ psk_identity=abc psk=dead" \
0 \ 0 \
-S "SSL - The server has no ciphersuites in common" \ -S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \ -S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed" -S "SSL - Verification of the message MAC failed"
@ -2188,7 +2269,7 @@ run_test "PSK callback: second id matches" \
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \ "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=def psk=beef" \ psk_identity=def psk=beef" \
0 \ 0 \
-S "SSL - The server has no ciphersuites in common" \ -S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \ -S "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed" -S "SSL - Verification of the message MAC failed"
@ -2197,7 +2278,7 @@ run_test "PSK callback: no match" \
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \ "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=ghi psk=beef" \ psk_identity=ghi psk=beef" \
1 \ 1 \
-S "SSL - The server has no ciphersuites in common" \ -S "SSL - None of the common ciphersuites is usable" \
-s "SSL - Unknown identity received" \ -s "SSL - Unknown identity received" \
-S "SSL - Verification of the message MAC failed" -S "SSL - Verification of the message MAC failed"
@ -2206,7 +2287,7 @@ run_test "PSK callback: wrong key" \
"$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \ "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \
psk_identity=abc psk=beef" \ psk_identity=abc psk=beef" \
1 \ 1 \
-S "SSL - The server has no ciphersuites in common" \ -S "SSL - None of the common ciphersuites is usable" \
-S "SSL - Unknown identity received" \ -S "SSL - Unknown identity received" \
-s "SSL - Verification of the message MAC failed" -s "SSL - Verification of the message MAC failed"