From 780d671f9d88f71d64c5830ab11ecf6562de8757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 20 Feb 2014 17:19:59 +0100 Subject: [PATCH] Add tests for renegotiation --- programs/ssl/ssl_client2.c | 41 +++++++++------ programs/ssl/ssl_server2.c | 82 ++++++++++++++++------------- tests/ssl-opt.sh | 102 ++++++++++++++++++++++++++++++++++++- 3 files changed, 172 insertions(+), 53 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index ddc1eac15..8ecaf4b83 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -50,6 +50,7 @@ #define DFL_FORCE_CIPHER 0 #define DFL_RENEGOTIATION SSL_RENEGOTIATION_ENABLED #define DFL_ALLOW_LEGACY SSL_LEGACY_NO_RENEGOTIATION +#define DFL_RENEGOTIATE 0 #define DFL_MIN_VERSION -1 #define DFL_MAX_VERSION -1 #define DFL_AUTH_MODE SSL_VERIFY_OPTIONAL @@ -71,9 +72,6 @@ * longer paquets (for fragmentation purposes) */ #define GET_REQUEST "GET %s HTTP/1.0\r\n" /* LONG_HEADER */ "\r\n" -/* Uncomment to test client-initiated renegotiation */ -// #define TEST_RENEGO - /* * global options */ @@ -92,6 +90,7 @@ struct options int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ int renegotiation; /* enable / disable renegotiation */ int allow_legacy; /* allow legacy renegotiation */ + int renegotiate; /* attempt renegotiation? */ int min_version; /* minimum protocol version accepted */ int max_version; /* maximum protocol version accepted */ int auth_mode; /* verify mode for connection */ @@ -215,6 +214,7 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags ) "\n" \ " renegotiation=%%d default: 1 (enabled)\n" \ " allow_legacy=%%d default: 0 (disabled)\n" \ + " renegotiate=%%d default: 0 (disabled)\n" \ " reconnect=%%d default: 0 (disabled)\n" \ USAGE_TICKETS \ USAGE_MAX_FRAG_LEN \ @@ -313,6 +313,7 @@ int main( int argc, char *argv[] ) opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; opt.renegotiation = DFL_RENEGOTIATION; opt.allow_legacy = DFL_ALLOW_LEGACY; + opt.renegotiate = DFL_RENEGOTIATE; opt.min_version = DFL_MIN_VERSION; opt.max_version = DFL_MAX_VERSION; opt.auth_mode = DFL_AUTH_MODE; @@ -380,6 +381,12 @@ int main( int argc, char *argv[] ) if( opt.allow_legacy < 0 || opt.allow_legacy > 1 ) goto usage; } + else if( strcmp( p, "renegotiate" ) == 0 ) + { + opt.renegotiate = atoi( q ); + if( opt.renegotiate < 0 || opt.renegotiate > 1 ) + goto usage; + } else if( strcmp( p, "reconnect" ) == 0 ) { opt.reconnect = atoi( q ); @@ -800,23 +807,25 @@ int main( int argc, char *argv[] ) } #endif /* POLARSSL_X509_CRT_PARSE_C */ -#ifdef TEST_RENEGO - /* - * Perform renegotiation (this must be done when the server is waiting - * for input from our side). - */ - printf( " . Performing renegotiation..." ); - fflush( stdout ); - while( ( ret = ssl_renegotiate( &ssl ) ) != 0 ) + if( opt.renegotiate ) { - if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) + /* + * Perform renegotiation (this must be done when the server is waiting + * for input from our side). + */ + printf( " . Performing renegotiation..." ); + fflush( stdout ); + while( ( ret = ssl_renegotiate( &ssl ) ) != 0 ) { - printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret ); - goto exit; + if( ret != POLARSSL_ERR_NET_WANT_READ && + ret != POLARSSL_ERR_NET_WANT_WRITE ) + { + printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret ); + goto exit; + } } + printf( " ok\n" ); } - printf( " ok\n" ); -#endif /* * 6. Write the GET request diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index a34b18795..955d87810 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -63,6 +63,7 @@ #define DFL_FORCE_CIPHER 0 #define DFL_RENEGOTIATION SSL_RENEGOTIATION_ENABLED #define DFL_ALLOW_LEGACY SSL_LEGACY_NO_RENEGOTIATION +#define DFL_RENEGOTIATE 0 #define DFL_MIN_VERSION -1 #define DFL_MAX_VERSION -1 #define DFL_AUTH_MODE SSL_VERIFY_OPTIONAL @@ -84,9 +85,6 @@ "

PolarSSL Test Server

\r\n" \ "

Successful connection using: %s

\r\n" // LONG_RESPONSE -/* Uncomment to test server-initiated renegotiation */ -// #define TEST_RENEGO - /* * global options */ @@ -106,6 +104,7 @@ struct options int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ int renegotiation; /* enable / disable renegotiation */ int allow_legacy; /* allow legacy renegotiation */ + int renegotiate; /* attempt renegotiation? */ int min_version; /* minimum protocol version accepted */ int max_version; /* maximum protocol version accepted */ int auth_mode; /* verify mode for connection */ @@ -186,6 +185,7 @@ static void my_debug( void *ctx, int level, const char *str ) "\n" \ " renegotiation=%%d default: 1 (enabled)\n" \ " allow_legacy=%%d default: 0 (disabled)\n" \ + " renegotiate=%%d default: 0 (disabled)\n" \ USAGE_TICKETS \ USAGE_MAX_FRAG_LEN \ "\n" \ @@ -301,6 +301,7 @@ int main( int argc, char *argv[] ) opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; opt.renegotiation = DFL_RENEGOTIATION; opt.allow_legacy = DFL_ALLOW_LEGACY; + opt.renegotiate = DFL_RENEGOTIATE; opt.min_version = DFL_MIN_VERSION; opt.max_version = DFL_MAX_VERSION; opt.auth_mode = DFL_AUTH_MODE; @@ -368,6 +369,12 @@ int main( int argc, char *argv[] ) if( opt.allow_legacy < 0 || opt.allow_legacy > 1 ) goto usage; } + else if( strcmp( p, "renegotiate" ) == 0 ) + { + opt.renegotiate = atoi( q ); + if( opt.renegotiate < 0 || opt.renegotiate > 1 ) + goto usage; + } else if( strcmp( p, "min_version" ) == 0 ) { if( strcmp( q, "ssl3" ) == 0 ) @@ -929,43 +936,48 @@ reset: buf[written] = '\0'; printf( " %d bytes written in %d fragments\n\n%s\n", written, frags, (char *) buf ); -#ifdef TEST_RENEGO - /* - * Request renegotiation (this must be done when the client is still - * waiting for input from our side). - */ - printf( " . Requestion renegotiation..." ); - fflush( stdout ); - while( ( ret = ssl_renegotiate( &ssl ) ) != 0 ) + if( opt.renegotiate ) { - if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) + /* + * Request renegotiation (this must be done when the client is still + * waiting for input from our side). + */ + printf( " . Requestion renegotiation..." ); + fflush( stdout ); + while( ( ret = ssl_renegotiate( &ssl ) ) != 0 ) { - printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret ); - goto exit; - } - } - - /* - * Should be a while loop, not an if, but here we're not actually - * expecting data from the client, and since we're running tests locally, - * we can just hope the handshake will finish the during the first call. - */ - if( ( ret = ssl_read( &ssl, buf, 0 ) ) != 0 ) - { - if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) - { - printf( " failed\n ! ssl_read returned %d\n\n", ret ); - - /* Unexpected message probably means client didn't renegotiate */ - if( ret == POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ) - goto reset; - else + if( ret != POLARSSL_ERR_NET_WANT_READ && + ret != POLARSSL_ERR_NET_WANT_WRITE ) + { + printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret ); goto exit; + } } - } - printf( " ok\n" ); -#endif + /* + * Should be a while loop, not an if, but here we're not actually + * expecting data from the client, and since we're running tests + * locally, we can just hope the handshake will finish the during the + * first call. + */ + if( ( ret = ssl_read( &ssl, buf, 0 ) ) != 0 ) + { + if( ret != POLARSSL_ERR_NET_WANT_READ && + ret != POLARSSL_ERR_NET_WANT_WRITE ) + { + printf( " failed\n ! ssl_read returned %d\n\n", ret ); + + /* Unexpected message probably means client didn't renegotiate + * as requested */ + if( ret == POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ) + goto reset; + else + goto exit; + } + } + + printf( " ok\n" ); + } ret = 0; goto reset; diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index ad0b2e5eb..0dd072b3d 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -32,7 +32,9 @@ run_test() { shift 2 # check client exit code - if [ "$1" = 0 -a "$CLI_EXIT" != 0 ]; then + if [ \( "$1" = 0 -a "$CLI_EXIT" != 0 \) -o \ + \( "$1" != 0 -a "$CLI_EXIT" = 0 \) ] + then echo "FAIL - client exit" return fi @@ -84,12 +86,22 @@ run_test() { killall -q openssl ssl_server ssl_server2 -run_test "Truncated HMAC" \ +# Tests for Truncated HMAC extension + +run_test "Truncated HMAC #0" \ + "debug_level=5" \ + "trunc_hmac=0 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \ + 0 \ + -s "dumping 'computed mac' (20 bytes)" + +run_test "Truncated HMAC #1" \ "debug_level=5" \ "trunc_hmac=1 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \ 0 \ -s "dumping 'computed mac' (10 bytes)" +# Tests for Session Tickets + run_test "Session resume using tickets" \ "debug_level=4 tickets=1" \ "debug_level=4 reconnect=1 tickets=1" \ @@ -99,6 +111,8 @@ run_test "Session resume using tickets" \ -s "a session has been resumed" \ -c "a session has been resumed" +# Test for Session Resume base in session-ID and cache + run_test "Session resume using cache #1" \ "debug_level=4 tickets=0" \ "debug_level=4 reconnect=1 tickets=1" \ @@ -117,6 +131,8 @@ run_test "Session resume using cache #2" \ -s "a session has been resumed" \ -c "a session has been resumed" +# Tests for Max Fragment Length extension + run_test "Max fragment length #1" \ "debug_level=4" \ "debug_level=4" \ @@ -143,3 +159,85 @@ run_test "Max fragment length #3" \ -S "found max fragment length extension" \ -S "server hello, max_fragment_length extension" \ -C "found max_fragment_length extension" + +# Tests for renegotiation + +run_test "Renegotiation #0 (none)" \ + "debug_level=4" \ + "debug_level=4" \ + 0 \ + -C "client hello, adding renegotiation extension" \ + -s "received TLS_EMPTY_RENEGOTIATION_INFO" \ + -S "found renegotiation extension" \ + -s "server hello, secure renegotiation extension" \ + -c "found renegotiation extension" \ + -C "renegotiate" \ + -S "renegotiate" \ + -S "write hello request" + +run_test "Renegotiation #1 (enabled, client-initiated)" \ + "debug_level=4" \ + "debug_level=4 renegotiate=1" \ + 0 \ + -c "client hello, adding renegotiation extension" \ + -s "received TLS_EMPTY_RENEGOTIATION_INFO" \ + -s "found renegotiation extension" \ + -s "server hello, secure renegotiation extension" \ + -c "found renegotiation extension" \ + -c "renegotiate" \ + -s "renegotiate" \ + -S "write hello request" + +run_test "Renegotiation #2 (enabled, server-initiated)" \ + "debug_level=4 renegotiate=1" \ + "debug_level=4" \ + 0 \ + -c "client hello, adding renegotiation extension" \ + -s "received TLS_EMPTY_RENEGOTIATION_INFO" \ + -s "found renegotiation extension" \ + -s "server hello, secure renegotiation extension" \ + -c "found renegotiation extension" \ + -c "renegotiate" \ + -s "renegotiate" \ + -s "write hello request" + +run_test "Renegotiation #3 (enabled, double)" \ + "debug_level=4 renegotiate=1" \ + "debug_level=4 renegotiate=1" \ + 0 \ + -c "client hello, adding renegotiation extension" \ + -s "received TLS_EMPTY_RENEGOTIATION_INFO" \ + -s "found renegotiation extension" \ + -s "server hello, secure renegotiation extension" \ + -c "found renegotiation extension" \ + -c "renegotiate" \ + -s "renegotiate" \ + -s "write hello request" + +run_test "Renegotiation #4 (client-initiated, server-rejected)" \ + "debug_level=4 renegotiation=0" \ + "debug_level=4 renegotiate=1" \ + 1 \ + -c "client hello, adding renegotiation extension" \ + -s "received TLS_EMPTY_RENEGOTIATION_INFO" \ + -S "found renegotiation extension" \ + -s "server hello, secure renegotiation extension" \ + -c "found renegotiation extension" \ + -c "renegotiate" \ + -S "renegotiate" \ + -S "write hello request" + +run_test "Renegotiation #5 (server-initiated, client-rejected)" \ + "debug_level=4 renegotiate=1" \ + "debug_level=4 renegotiation=0" \ + 0 \ + -C "client hello, adding renegotiation extension" \ + -s "received TLS_EMPTY_RENEGOTIATION_INFO" \ + -S "found renegotiation extension" \ + -s "server hello, secure renegotiation extension" \ + -c "found renegotiation extension" \ + -C "renegotiate" \ + -S "renegotiate" \ + -s "write hello request" \ + -s "SSL - An unexpected message was received from our peer" \ + -s "failed"