Merged massive SSL Testing improvements
diff --git a/.gitignore b/.gitignore
index 02b0a98..fdd50b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@
cmake_install.cmake
Testing
Coverage
+*.gcno
+*.gcda
+library/polarssl.info
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0be112e..ac4be4c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -76,10 +76,22 @@
COMMAND tests/scripts/test-ref-configs.pl
)
+# add programs/test/selftest even though the selftest functions are
+# called from the testsuites since it runs them in verbose mode,
+# avoiding spurious "uncovered" printf lines
+ADD_CUSTOM_TARGET(covtest
+ COMMAND make test
+ COMMAND programs/test/selftest
+ COMMAND cd tests && ./compat.sh
+ COMMAND cd tests && ./ssl-opt.sh
+ )
+
ADD_CUSTOM_TARGET(lcov
- COMMAND geninfo *.gcda
- COMMAND genhtml -o ../../../Coverage *.info
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/library/CMakeFiles/polarssl.dir
+ COMMAND rm -rf Coverage
+ COMMAND lcov --capture --directory library/CMakeFiles/polarssl.dir -o polarssl.info
+ COMMAND gendesc tests/Descriptions.txt -o descriptions
+ COMMAND genhtml --title PolarSSL --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage polarssl.info
+ COMMAND rm -f polarssl.info descriptions
)
ADD_CUSTOM_TARGET(memcheck
diff --git a/ChangeLog b/ChangeLog
index e6f1679..0667d23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,7 +3,7 @@
= PolarSSL 1.3 branch
Features
* HMAC-DRBG as a separate module
- * Option to set the Curve preference order
+ * Option to set the Curve preference order (disabled by default)
* Single Platform compatilibity layer (for memory / printf / fprintf)
* Ability to provide alternate timing implementation
* Ability to force the entropy module to use SHA-256 as its basis
@@ -35,6 +35,14 @@
* Programs rsa_sign_pss and rsa_verify_pss were not using PSS since 1.3.0
* Bignum's MIPS-32 assembly was used on MIPS-64, causing chaos. (Found by
Alex Wilson.)
+ * ssl_cache was creating entries when max_entries=0 if TIMING_C was enabled.
+ * m_sleep() was sleeping twice too long on most Unix platforms.
+ * Fixed bug with session tickets and non-blocking I/O in the unlikely case
+ send() would return an EAGAIN error when sending the ticket.
+ * ssl_cache was leaking memory when reusing a timed out entry containing a
+ client certificate.
+ * ssl_srv was leaking memory when client presented a timed out ticket
+ containing a client certificate
= PolarSSL 1.3.4 released on 2014-01-27
Features
diff --git a/Makefile b/Makefile
index 2ca3cf5..ec09f9c 100644
--- a/Makefile
+++ b/Makefile
@@ -56,10 +56,23 @@
test-ref-configs:
tests/scripts/test-ref-configs.pl
+# note: for coverage testing, build with:
+# CFLAGS='--coverage' make OFLAGS='-g3 -O0'
+covtest:
+ make check
+ # add programs/test/selftest even though the selftest functions are
+ # called from the testsuites since it runs them in verbose mode,
+ # avoiding spurious "uncovered" printf lines
+ programs/test/selftest
+ ( cd tests && ./compat.sh )
+ ( cd tests && ./ssl-opt.sh )
+
lcov:
rm -rf Coverage
- ( cd library && geninfo *.gcda )
- ( cd library && genhtml -o ../Coverage *.info )
+ lcov --capture --directory library -o polarssl.info
+ gendesc tests/Descriptions.txt -o descriptions
+ genhtml --title PolarSSL --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage polarssl.info
+ rm -f polarssl.info descriptions
apidoc:
mkdir -p apidoc
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index 74e8189..c070df2 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -2273,6 +2273,11 @@
#error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites"
#endif
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) && \
+ !defined(POLARSSL_X509_CRT_PARSE_C)
+#error "POLARSSL_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
+#endif
+
#if defined(POLARSSL_THREADING_PTHREAD)
#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL)
#error "POLARSSL_THREADING_PTHREAD defined, but not all prerequisites"
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 89e3375..2e33ffd 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -1118,7 +1118,7 @@
*
* If set, the PSK callback is called for each
* handshake where a PSK ciphersuite was negotiated.
- * The callback provides the identity received and wants to
+ * The caller provides the identity received and wants to
* receive the actual PSK data and length.
*
* The callback has the following parameters: (void *parameter,
diff --git a/include/polarssl/ssl_cache.h b/include/polarssl/ssl_cache.h
index daa07ac..16144fe 100644
--- a/include/polarssl/ssl_cache.h
+++ b/include/polarssl/ssl_cache.h
@@ -106,7 +106,7 @@
* A timeout of 0 indicates no timeout.
*
* \param cache SSL cache context
- * \param timeout cache entry timeout
+ * \param timeout cache entry timeout in seconds
*/
void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout );
#endif /* POLARSSL_HAVE_TIME */
diff --git a/library/certs.c b/library/certs.c
index 17775b8..7409efa 100644
--- a/library/certs.c
+++ b/library/certs.c
@@ -169,55 +169,56 @@
const char test_srv_crt_rsa[] =
"-----BEGIN CERTIFICATE-----\r\n"
-"MIIDPzCCAiegAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
+"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
-"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n"
-"A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN\r\n"
-"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/\r\n"
-"uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD\r\n"
-"d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf\r\n"
-"CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr\r\n"
-"lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w\r\n"
-"bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB\r\n"
-"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9Q1kCpjAf\r\n"
-"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQUFAAOC\r\n"
-"AQEAvc+WwZUemsJu2IiI2Cp6liA+UAvIx98dQe3kZs2zAoF9VwQbXcYzWQ/BILkj\r\n"
-"NImKbPL9x0g2jIDn4ZvGYFywMwIO/d++YbwYiQw42/v7RiMy94zBPnzeHi86dy/0\r\n"
-"jpOOJUx3IXRsGLdyjb/1T11klcFqGnARiK+8VYolMPP6afKvLXX7K4kiUpsFQhUp\r\n"
-"E5VeM5pV1Mci2ETOJau2cO40FJvI/C9W/wR+GAArMaw2fxG77E3laaa0LAOlexM6\r\n"
-"A4KOb5f5cGTM5Ih6tEF5FVq3/9vzNIYMa1FqzacBLZF8zSHYLEimXBdzjBoN4qDU\r\n"
-"/WzRyYRBRjAI49mzHX6raleqnw==\r\n"
+"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n"
+"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n"
+"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n"
+"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n"
+"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n"
+"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n"
+"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n"
+"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n"
+"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n"
+"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJxnXClY\r\n"
+"oHkbp70cqBrsGXLybA74czbO5RdLEgFs7rHVS9r+c293luS/KdliLScZqAzYVylw\r\n"
+"UfRWvKMoWhHYKp3dEIS4xTXk6/5zXxhv9Rw8SGc8qn6vITHk1S1mPevtekgasY5Y\r\n"
+"iWQuM3h4YVlRH3HHEMAD1TnAexfXHHDFQGe+Bd1iAbz1/sH9H8l4StwX6egvTK3M\r\n"
+"wXRwkKkvjKaEDA9ATbZx0mI8LGsxSuCqe9r9dyjmttd47J1p1Rulz3CLzaRcVIuS\r\n"
+"RRQfaD8neM9c1S/iJ/amTVqJxA1KOdOS5780WhPfSArA+g4qAmSjelc3p4wWpha8\r\n"
+"zhuYwjVuX6JHG0c=\r\n"
"-----END CERTIFICATE-----\r\n";
const char test_srv_key_rsa[] =
"-----BEGIN RSA PRIVATE KEY-----\r\n"
-"MIIEogIBAAKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/uOhFkNvuiBZS0/FDUEeW\r\n"
-"Ellkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFDd185fAkER4KwVzlw7aPs\r\n"
-"FRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVfCrFTxjB+FTms+Vruf5Ke\r\n"
-"pgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTrlZvc/kFeF6babFtpzAK6\r\n"
-"FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9wbp7OvViJ4lNZnm5akmXi\r\n"
-"iD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQABAoIBABaJ9eiRQq4Ypv+w\r\n"
-"UTcVpLC0oTueWzcpor1i1zjG4Vzqe/Ok2FqyGToGKMlFK7Hwwa+LEyeJ3xyV5yd4\r\n"
-"v1Mw9bDZFdJC1eCBjoUAHtX6k9HOE0Vd6woVQ4Vi6OPI1g7B5Mnr/58rNrnN6TMs\r\n"
-"x58NF6euecwTU811QJrZtLbX7j2Cr28yB2Vs8qyYlHwVw5jbDOv43D7vU5gmlIDN\r\n"
-"0JQRuWAnOuPzZNoJr4SfJKqHNGxYYY6pHZ1s0dOTLIDb/B8KQWapA2kRmZyid2EH\r\n"
-"nwzgLbAsHJCf+bQnhXjXuxtUsrcIL8noZLazlOMxwNEammglVWW23Ud/QRnFgJg5\r\n"
-"UgcAcRECgYEA19uYetht5qmwdJ+12oC6zeO+vXLcyD9gon23T5J6w2YThld7/OW0\r\n"
-"oArQJGgkAdaq0pcTyOIjtTQVMFygdVmCEJmxh/3RutPcTeydqW9fphKDMej32J8e\r\n"
-"GniGmNGiclbcfNOS8E5TGp445yZb9P1+7AHng16bGg3Ykj5EA4G+HCcCgYEAyHAl\r\n"
-"//ekk8YjQElm+8izLtFkymIK0aCtEe9C/RIRhFYBeFaotC5dStNhBOncn4ovMAPD\r\n"
-"lX/92yDi9OP8PPLN3a4B9XpW3k/SS5GrbT5cwOivBHNllZSmu/2qz5WPGcjVCOrB\r\n"
-"LYl3YWr2h3EGKICT03kEoTkiDBvCeOpW7cCGl2cCgYBD5whoXHz1+ptPlI4YVjZt\r\n"
-"Xh86aU+ajpVPiEyJ84I6xXmO4SZXv8q6LaycR0ZMbcL+zBelMb4Z2nBv7jNrtuR7\r\n"
-"ZF28cdPv+YVr3esaybZE/73VjXup4SQPH6r3l7qKTVi+y6+FeJ4b2Xn8/MwgnT23\r\n"
-"8EFrye7wmzpthrjOgZnUMQKBgE9Lhsz/5J0Nis6Y+2Pqn3CLKEukg9Ewtqdct2y0\r\n"
-"5Dcta0F3TyCRIxlCDKTL/BslqMtfAdY4H268UO0+8IAQMn9boqzBrHIgs/pvc5kx\r\n"
-"TbKHmw2wtWR6vYersBKVgVpbCGSRssDYHGFu1n74qM4HJ/RGcR1zI9QUe1gopSFD\r\n"
-"xDtLAoGAVAdWvrqDwgoL2hHW3scGpxdE/ygJDOwHnf+1B9goKAOP5lf2FJaiAxf3\r\n"
-"ectoPOgZbCmm/iiDmigu703ld3O+VoCLDD4qx3R+KyALL78gtVJYzSRiKhzgCZ3g\r\n"
-"mKsIVRBq4IfwiwyMNG2BYZQAwbSDjjPtn/kPBduPzPj7eriByhI=\r\n"
+"MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n"
+"lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n"
+"2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n"
+"Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n"
+"GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n"
+"y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n"
+"++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n"
+"Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n"
+"/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n"
+"WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n"
+"GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n"
+"TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n"
+"CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n"
+"nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n"
+"AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n"
+"sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n"
+"mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n"
+"BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n"
+"whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n"
+"vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n"
+"3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n"
+"3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n"
+"ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n"
+"4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n"
+"TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n"
"-----END RSA PRIVATE KEY-----\r\n";
+
const char test_cli_crt_rsa[] =
"-----BEGIN CERTIFICATE-----\r\n"
"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
diff --git a/library/ssl_cache.c b/library/ssl_cache.c
index 6fff54b..4c7d3db 100644
--- a/library/ssl_cache.c
+++ b/library/ssl_cache.c
@@ -186,17 +186,15 @@
/*
* Reuse oldest entry if max_entries reached
*/
- if( old != NULL && count >= cache->max_entries )
+ if( count >= cache->max_entries )
{
- cur = old;
- memset( &cur->session, 0, sizeof(ssl_session) );
-#if defined(POLARSSL_X509_CRT_PARSE_C)
- if( cur->peer_cert.p != NULL )
+ if( old == NULL )
{
- polarssl_free( cur->peer_cert.p );
- memset( &cur->peer_cert, 0, sizeof(x509_buf) );
+ ret = 1;
+ goto exit;
}
-#endif /* POLARSSL_X509_CRT_PARSE_C */
+
+ cur = old;
}
#else /* POLARSSL_HAVE_TIME */
/*
@@ -213,21 +211,15 @@
cur = cache->chain;
cache->chain = cur->next;
-
-#if defined(POLARSSL_X509_CRT_PARSE_C)
- if( cur->peer_cert.p != NULL )
- {
- polarssl_free( cur->peer_cert.p );
- memset( &cur->peer_cert, 0, sizeof(x509_buf) );
- }
-#endif /* POLARSSL_X509_CRT_PARSE_C */
-
- memset( cur, 0, sizeof(ssl_cache_entry) );
+ cur->next = NULL;
prv->next = cur;
}
#endif /* POLARSSL_HAVE_TIME */
else
{
+ /*
+ * max_entries not reached, create new entry
+ */
cur = (ssl_cache_entry *) polarssl_malloc( sizeof(ssl_cache_entry) );
if( cur == NULL )
{
@@ -252,6 +244,15 @@
#if defined(POLARSSL_X509_CRT_PARSE_C)
/*
+ * If we're reusing an entry, free its certificate first
+ */
+ if( cur->peer_cert.p != NULL )
+ {
+ polarssl_free( cur->peer_cert.p );
+ memset( &cur->peer_cert, 0, sizeof(x509_buf) );
+ }
+
+ /*
* Store peer certificate
*/
if( session->peer_cert != NULL )
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 54c931a..8549050 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -310,7 +310,7 @@
if( ( ret = ssl_load_session( &session, ticket, clear_len ) ) != 0 )
{
SSL_DEBUG_MSG( 1, ( "failed to parse ticket content" ) );
- memset( &session, 0, sizeof( ssl_session ) );
+ ssl_session_free( &session );
return( ret );
}
@@ -319,7 +319,7 @@
if( (int) ( time( NULL) - session.start ) > ssl->ticket_lifetime )
{
SSL_DEBUG_MSG( 1, ( "session ticket expired" ) );
- memset( &session, 0, sizeof( ssl_session ) );
+ ssl_session_free( &session );
return( POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED );
}
#endif
@@ -367,6 +367,8 @@
size_t servername_list_size, hostname_len;
const unsigned char *p;
+ SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) );
+
servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
if( servername_list_size + 2 != len )
{
@@ -389,6 +391,7 @@
ret = ssl_sni_wrapper( ssl, p + 3, hostname_len );
if( ret != 0 )
{
+ SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret );
ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL,
SSL_ALERT_MSG_UNRECOGNIZED_NAME );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
@@ -1690,6 +1693,7 @@
ssl->f_get_cache != NULL &&
ssl->f_get_cache( ssl->p_get_cache, ssl->session_negotiate ) == 0 )
{
+ SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
ssl->handshake->resume = 1;
}
@@ -2041,7 +2045,7 @@
{
ssl_get_ecdh_params_from_cert( ssl );
- SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
+ SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
ssl->state++;
return( 0 );
}
@@ -2999,15 +3003,18 @@
ssl->out_msglen = 10 + tlen;
+ /*
+ * Morally equivalent to updating ssl->state, but NewSessionTicket and
+ * ChangeCipherSpec share the same state.
+ */
+ ssl->handshake->new_session_ticket = 0;
+
if( ( ret = ssl_write_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_write_record", ret );
return( ret );
}
- /* No need to remember writing a NewSessionTicket any more */
- ssl->handshake->new_session_ticket = 0;
-
SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) );
return( 0 );
diff --git a/library/timing.c b/library/timing.c
index c70b78c..f1d8a1f 100644
--- a/library/timing.c
+++ b/library/timing.c
@@ -302,7 +302,7 @@
struct timeval tv;
tv.tv_sec = milliseconds / 1000;
- tv.tv_usec = milliseconds * 1000;
+ tv.tv_usec = ( milliseconds % 1000 ) * 1000;
select( 0, NULL, NULL, NULL, &tv );
}
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 5f7c3be..3b8dec7 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -37,10 +37,16 @@
#include "polarssl/x509.h"
#include "polarssl/error.h"
+#if defined(POLARSSL_TIMING_C)
+#include "polarssl/timing.h"
+#endif
+
#define DFL_SERVER_NAME "localhost"
+#define DFL_SERVER_ADDR NULL
#define DFL_SERVER_PORT 4433
#define DFL_REQUEST_PAGE "/"
#define DFL_DEBUG_LEVEL 0
+#define DFL_NBIO 0
#define DFL_CA_FILE ""
#define DFL_CA_PATH ""
#define DFL_CRT_FILE ""
@@ -50,12 +56,14 @@
#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_REQUIRED
#define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE
#define DFL_TRUNC_HMAC 0
#define DFL_RECONNECT 0
+#define DFL_RECO_DELAY 0
#define DFL_TICKETS SSL_SESSION_TICKETS_ENABLED
#define LONG_HEADER "User-agent: blah-blah-blah-blah-blah-blah-blah-blah-" \
@@ -71,17 +79,16 @@
* 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
*/
struct options
{
const char *server_name; /* hostname of the server (client only) */
+ const char *server_addr; /* address of the server (client only) */
int server_port; /* port on which the ssl service runs */
int debug_level; /* level of debugging */
+ int nbio; /* should I/O be blocking? */
const char *request_page; /* page on server to request */
const char *ca_file; /* the file with the CA certificate(s) */
const char *ca_path; /* the path with the CA certificate(s) reside */
@@ -92,12 +99,14 @@
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 */
unsigned char mfl_code; /* code for maximum fragment length */
int trunc_hmac; /* negotiate truncated hmac or not */
int reconnect; /* attempt to resume session */
+ int reco_delay; /* delay in seconds before resuming session */
int tickets; /* enable / disable session tickets */
} opt;
@@ -110,6 +119,44 @@
}
}
+/*
+ * Test recv/send functions that make sure each try returns
+ * WANT_READ/WANT_WRITE at least once before sucesseding
+ */
+static int my_recv( void *ctx, unsigned char *buf, size_t len )
+{
+ static int first_try = 1;
+ int ret;
+
+ if( first_try )
+ {
+ first_try = 0;
+ return( POLARSSL_ERR_NET_WANT_READ );
+ }
+
+ ret = net_recv( ctx, buf, len );
+ if( ret != POLARSSL_ERR_NET_WANT_READ )
+ first_try = 1; /* Next call will be a new operation */
+ return( ret );
+}
+
+static int my_send( void *ctx, const unsigned char *buf, size_t len )
+{
+ static int first_try = 1;
+ int ret;
+
+ if( first_try )
+ {
+ first_try = 0;
+ return( POLARSSL_ERR_NET_WANT_WRITE );
+ }
+
+ ret = net_send( ctx, buf, len );
+ if( ret != POLARSSL_ERR_NET_WANT_WRITE )
+ first_try = 1; /* Next call will be a new operation */
+ return( ret );
+}
+
#if defined(POLARSSL_X509_CRT_PARSE_C)
/*
* Enabled if debug_level > 1 in code below
@@ -199,18 +246,38 @@
#define USAGE_MAX_FRAG_LEN ""
#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
+#if defined(POLARSSL_TIMING_C)
+#define USAGE_TIME \
+ " reco_delay=%%d default: 0 seconds\n"
+#else
+#define USAGE_TIME ""
+#endif /* POLARSSL_TIMING_C */
+
#define USAGE \
"\n usage: ssl_client2 param=<>...\n" \
"\n acceptable parameters:\n" \
" server_name=%%s default: localhost\n" \
+ " server_addr=%%s default: given by name\n" \
" server_port=%%d default: 4433\n" \
- " debug_level=%%d default: 0 (disabled)\n" \
- USAGE_IO \
" request_page=%%s default: \".\"\n" \
+ " debug_level=%%d default: 0 (disabled)\n" \
+ " nbio=%%d default: 0 (blocking I/O)\n" \
+ " options: 1 (non-blocking), 2 (added delays)\n" \
+ "\n" \
+ " auth_mode=%%s default: \"optional\"\n" \
+ " options: none, optional, required\n" \
+ USAGE_IO \
+ "\n" \
+ USAGE_PSK \
+ "\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_TIME \
USAGE_TICKETS \
+ USAGE_MAX_FRAG_LEN \
+ USAGE_TRUNC_HMAC \
"\n" \
" min_version=%%s default: \"\" (ssl3)\n" \
" max_version=%%s default: \"\" (tls1_2)\n" \
@@ -218,9 +285,6 @@
" options: ssl3, tls1, tls1_1, tls1_2\n" \
" auth_mode=%%s default: \"required\"\n" \
" options: none, optional, required\n" \
- USAGE_MAX_FRAG_LEN \
- USAGE_TRUNC_HMAC \
- USAGE_PSK \
"\n" \
" force_ciphersuite=<name> default: all enabled\n"\
" acceptable ciphersuite names:\n"
@@ -296,8 +360,10 @@
}
opt.server_name = DFL_SERVER_NAME;
+ opt.server_addr = DFL_SERVER_ADDR;
opt.server_port = DFL_SERVER_PORT;
opt.debug_level = DFL_DEBUG_LEVEL;
+ opt.nbio = DFL_NBIO;
opt.request_page = DFL_REQUEST_PAGE;
opt.ca_file = DFL_CA_FILE;
opt.ca_path = DFL_CA_PATH;
@@ -308,12 +374,14 @@
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;
opt.mfl_code = DFL_MFL_CODE;
opt.trunc_hmac = DFL_TRUNC_HMAC;
opt.reconnect = DFL_RECONNECT;
+ opt.reco_delay = DFL_RECO_DELAY;
opt.tickets = DFL_TICKETS;
for( i = 1; i < argc; i++ )
@@ -325,6 +393,8 @@
if( strcmp( p, "server_name" ) == 0 )
opt.server_name = q;
+ else if( strcmp( p, "server_addr" ) == 0 )
+ opt.server_addr = q;
else if( strcmp( p, "server_port" ) == 0 )
{
opt.server_port = atoi( q );
@@ -337,6 +407,12 @@
if( opt.debug_level < 0 || opt.debug_level > 65535 )
goto usage;
}
+ else if( strcmp( p, "nbio" ) == 0 )
+ {
+ opt.nbio = atoi( q );
+ if( opt.nbio < 0 || opt.nbio > 2 )
+ goto usage;
+ }
else if( strcmp( p, "request_page" ) == 0 )
opt.request_page = q;
else if( strcmp( p, "ca_file" ) == 0 )
@@ -375,12 +451,24 @@
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 );
if( opt.reconnect < 0 || opt.reconnect > 2 )
goto usage;
}
+ else if( strcmp( p, "reco_delay" ) == 0 )
+ {
+ opt.reco_delay = atoi( q );
+ if( opt.reco_delay < 0 )
+ goto usage;
+ }
else if( strcmp( p, "tickets" ) == 0 )
{
opt.tickets = atoi( q );
@@ -573,9 +661,15 @@
#if defined(POLARSSL_FS_IO)
if( strlen( opt.ca_path ) )
- ret = x509_crt_parse_path( &cacert, opt.ca_path );
+ if( strcmp( opt.ca_path, "none" ) == 0 )
+ ret = 0;
+ else
+ ret = x509_crt_parse_path( &cacert, opt.ca_path );
else if( strlen( opt.ca_file ) )
- ret = x509_crt_parse_file( &cacert, opt.ca_file );
+ if( strcmp( opt.ca_file, "none" ) == 0 )
+ ret = 0;
+ else
+ ret = x509_crt_parse_file( &cacert, opt.ca_file );
else
#endif
#if defined(POLARSSL_CERTS_C)
@@ -605,7 +699,10 @@
#if defined(POLARSSL_FS_IO)
if( strlen( opt.crt_file ) )
- ret = x509_crt_parse_file( &clicert, opt.crt_file );
+ if( strcmp( opt.crt_file, "none" ) == 0 )
+ ret = 0;
+ else
+ ret = x509_crt_parse_file( &clicert, opt.crt_file );
else
#endif
#if defined(POLARSSL_CERTS_C)
@@ -625,7 +722,10 @@
#if defined(POLARSSL_FS_IO)
if( strlen( opt.key_file ) )
- ret = pk_parse_keyfile( &pkey, opt.key_file, "" );
+ if( strcmp( opt.key_file, "none" ) == 0 )
+ ret = 0;
+ else
+ ret = pk_parse_keyfile( &pkey, opt.key_file, "" );
else
#endif
#if defined(POLARSSL_CERTS_C)
@@ -649,17 +749,30 @@
/*
* 2. Start the connection
*/
- printf( " . Connecting to tcp/%s/%-4d...", opt.server_name,
+ if( opt.server_addr == NULL)
+ opt.server_addr = opt.server_name;
+
+ printf( " . Connecting to tcp/%s/%-4d...", opt.server_addr,
opt.server_port );
fflush( stdout );
- if( ( ret = net_connect( &server_fd, opt.server_name,
+ if( ( ret = net_connect( &server_fd, opt.server_addr,
opt.server_port ) ) != 0 )
{
printf( " failed\n ! net_connect returned -0x%x\n\n", -ret );
goto exit;
}
+ if( opt.nbio > 0 )
+ ret = net_set_nonblock( server_fd );
+ else
+ ret = net_set_block( server_fd );
+ if( ret != 0 )
+ {
+ printf( " failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret );
+ goto exit;
+ }
+
printf( " ok\n" );
/*
@@ -695,8 +808,11 @@
ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
ssl_set_dbg( &ssl, my_debug, stdout );
- ssl_set_bio( &ssl, net_recv, &server_fd,
- net_send, &server_fd );
+
+ if( opt.nbio == 2 )
+ ssl_set_bio( &ssl, my_recv, &server_fd, my_send, &server_fd );
+ else
+ ssl_set_bio( &ssl, net_recv, &server_fd, net_send, &server_fd );
#if defined(POLARSSL_SSL_SESSION_TICKETS)
ssl_set_session_tickets( &ssl, opt.tickets );
@@ -709,8 +825,16 @@
ssl_legacy_renegotiation( &ssl, opt.allow_legacy );
#if defined(POLARSSL_X509_CRT_PARSE_C)
- ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
- ssl_set_own_cert( &ssl, &clicert, &pkey );
+ if( strcmp( opt.ca_path, "none" ) != 0 &&
+ strcmp( opt.ca_file, "none" ) != 0 )
+ {
+ ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
+ }
+ if( strcmp( opt.crt_file, "none" ) != 0 &&
+ strcmp( opt.key_file, "none" ) != 0 )
+ {
+ ssl_set_own_cert( &ssl, &clicert, &pkey );
+ }
#endif
#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
@@ -804,23 +928,25 @@
}
#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
@@ -829,7 +955,10 @@
printf( " > Write to server:" );
fflush( stdout );
- len = sprintf( (char *) buf, GET_REQUEST, opt.request_page );
+ if( strcmp( opt.request_page, "SERVERQUIT" ) == 0 )
+ len = sprintf( (char *) buf, "%s", opt.request_page );
+ else
+ len = sprintf( (char *) buf, GET_REQUEST, opt.request_page );
for( written = 0, frags = 0; written < len; written += ret, frags++ )
{
@@ -887,8 +1016,10 @@
{
--opt.reconnect;
- // printf( " ! Press a key to reconnect\n" );
- // (void) getchar();
+#if defined(POLARSSL_TIMING_C)
+ if( opt.reco_delay > 0 )
+ m_sleep( 1000 * opt.reco_delay );
+#endif
printf( " . Reconnecting with saved session..." );
fflush( stdout );
@@ -931,6 +1062,9 @@
char error_buf[100];
polarssl_strerror( ret, error_buf, 100 );
printf("Last error was: -0x%X - %s\n\n", -ret, error_buf );
+
+ if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
+ ret = 0;
}
#endif
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index c916b8b..7a23e77 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -25,6 +25,17 @@
#include "polarssl/config.h"
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) && defined(POLARSSL_FS_IO)
+#define POLARSSL_SNI
+#endif
+
+#if defined(POLARSSL_PLATFORM_C)
+#include "polarssl/platform.h"
+#else
+#define polarssl_malloc malloc
+#define polarssl_free free
+#endif
+
#if defined(_WIN32)
#include <windows.h>
#endif
@@ -52,6 +63,7 @@
#define DFL_SERVER_ADDR NULL
#define DFL_SERVER_PORT 4433
#define DFL_DEBUG_LEVEL 0
+#define DFL_NBIO 0
#define DFL_CA_FILE ""
#define DFL_CA_PATH ""
#define DFL_CRT_FILE ""
@@ -63,11 +75,16 @@
#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
#define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE
#define DFL_TICKETS SSL_SESSION_TICKETS_ENABLED
+#define DFL_TICKET_TIMEOUT -1
+#define DFL_CACHE_MAX -1
+#define DFL_CACHE_TIMEOUT -1
+#define DFL_SNI NULL
#define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
"02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
@@ -84,9 +101,6 @@
"<h2>PolarSSL Test Server</h2>\r\n" \
"<p>Successful connection using: %s</p>\r\n" // LONG_RESPONSE
-/* Uncomment to test server-initiated renegotiation */
-// #define TEST_RENEGO
-
/*
* global options
*/
@@ -95,6 +109,7 @@
const char *server_addr; /* address on which the ssl service runs */
int server_port; /* port on which the ssl service runs */
int debug_level; /* level of debugging */
+ int nbio; /* should I/O be blocking? */
const char *ca_file; /* the file with the CA certificate(s) */
const char *ca_path; /* the path with the CA certificate(s) reside */
const char *crt_file; /* the file with the server certificate */
@@ -106,11 +121,16 @@
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 */
unsigned char mfl_code; /* code for maximum fragment length */
int tickets; /* enable / disable session tickets */
+ int ticket_timeout; /* session ticket lifetime */
+ int cache_max; /* max number of session cache entries */
+ int cache_timeout; /* expiration delay of session cache entries */
+ char *sni; /* string decribing sni information */
} opt;
static void my_debug( void *ctx, int level, const char *str )
@@ -122,6 +142,43 @@
}
}
+/*
+ * Test recv/send functions that make sure each try returns
+ * WANT_READ/WANT_WRITE at least once before sucesseding
+ */
+static int my_recv( void *ctx, unsigned char *buf, size_t len )
+{
+ static int first_try = 1;
+ int ret;
+
+ if( first_try )
+ {
+ first_try = 0;
+ return( POLARSSL_ERR_NET_WANT_READ );
+ }
+
+ ret = net_recv( ctx, buf, len );
+ if( ret != POLARSSL_ERR_NET_WANT_READ )
+ first_try = 1; /* Next call will be a new operation */
+ return( ret );
+}
+
+static int my_send( void *ctx, const unsigned char *buf, size_t len )
+{
+ static int first_try = 1;
+ int ret;
+
+ if( first_try )
+ {
+ first_try = 0;
+ return( POLARSSL_ERR_NET_WANT_WRITE );
+ }
+
+ ret = net_send( ctx, buf, len );
+ if( ret != POLARSSL_ERR_NET_WANT_WRITE )
+ first_try = 1; /* Next call will be a new operation */
+ return( ret );
+}
#if defined(POLARSSL_X509_CRT_PARSE_C)
#if defined(POLARSSL_FS_IO)
@@ -158,11 +215,28 @@
#if defined(POLARSSL_SSL_SESSION_TICKETS)
#define USAGE_TICKETS \
- " tickets=%%d default: 1 (enabled)\n"
+ " tickets=%%d default: 1 (enabled)\n" \
+ " ticket_timeout=%%d default: ticket default (1d)\n"
#else
#define USAGE_TICKETS ""
#endif /* POLARSSL_SSL_SESSION_TICKETS */
+#if defined(POLARSSL_SSL_CACHE_C)
+#define USAGE_CACHE \
+ " cache_max=%%d default: cache default (50)\n" \
+ " cache_timeout=%%d default: cache default (1d)\n"
+#else
+#define USAGE_CACHE ""
+#endif /* POLARSSL_SSL_CACHE_C */
+
+#if defined(POLARSSL_SNI)
+#define USAGE_SNI \
+ " sni=%%s name1,cert1,key1[,name2,cert2,key2[,...]]\n" \
+ " default: disabled\n"
+#else
+#define USAGE_SNI ""
+#endif /* POLARSSL_SNI */
+
#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
#define USAGE_MAX_FRAG_LEN \
" max_frag_len=%%d default: 16384 (tls default)\n" \
@@ -177,19 +251,27 @@
" server_addr=%%d default: (all interfaces)\n" \
" server_port=%%d default: 4433\n" \
" debug_level=%%d default: 0 (disabled)\n" \
+ " nbio=%%d default: 0 (blocking I/O)\n" \
+ " options: 1 (non-blocking), 2 (added delays)\n" \
+ "\n" \
+ " auth_mode=%%s default: \"optional\"\n" \
+ " options: none, optional, required\n" \
USAGE_IO \
- " request_page=%%s default: \".\"\n" \
+ USAGE_SNI \
+ "\n" \
+ USAGE_PSK \
+ "\n" \
" renegotiation=%%d default: 1 (enabled)\n" \
- USAGE_TICKETS \
" allow_legacy=%%d default: 0 (disabled)\n" \
+ " renegotiate=%%d default: 0 (disabled)\n" \
+ USAGE_TICKETS \
+ USAGE_CACHE \
+ USAGE_MAX_FRAG_LEN \
+ "\n" \
" min_version=%%s default: \"ssl3\"\n" \
" max_version=%%s default: \"tls1_2\"\n" \
" force_version=%%s default: \"\" (none)\n" \
" options: ssl3, tls1, tls1_1, tls1_2\n" \
- " auth_mode=%%s default: \"optional\"\n" \
- " options: none, optional, required\n" \
- USAGE_MAX_FRAG_LEN \
- USAGE_PSK \
"\n" \
" force_ciphersuite=<name> default: all enabled\n"\
" acceptable ciphersuite names:\n"
@@ -208,6 +290,116 @@
return( 0 );
}
#else
+
+#if defined(POLARSSL_SNI)
+typedef struct _sni_entry sni_entry;
+
+struct _sni_entry {
+ const char *name;
+ x509_crt *cert;
+ pk_context *key;
+ sni_entry *next;
+};
+
+/*
+ * Parse a string of triplets name1,crt1,key1[,name2,crt2,key2[,...]]
+ * into a usable sni_entry list.
+ *
+ * Note: this is not production quality: leaks memory if parsing fails,
+ * and error reporting is poor.
+ */
+sni_entry *sni_parse( char *sni_string )
+{
+ sni_entry *cur = NULL, *new = NULL;
+ char *p = sni_string;
+ char *end = p;
+ char *crt_file, *key_file;
+
+ while( *end != '\0' )
+ ++end;
+ *end = ',';
+
+ while( p <= end )
+ {
+ if( ( new = polarssl_malloc( sizeof( sni_entry ) ) ) == NULL )
+ return( NULL );
+
+ memset( new, 0, sizeof( sni_entry ) );
+
+ if( ( new->cert = polarssl_malloc( sizeof( x509_crt ) ) ) == NULL ||
+ ( new->key = polarssl_malloc( sizeof( pk_context ) ) ) == NULL )
+ return( NULL );
+
+ x509_crt_init( new->cert );
+ pk_init( new->key );
+
+ new->name = p;
+ while( *p != ',' ) if( ++p > end ) return( NULL );
+ *p++ = '\0';
+
+ crt_file = p;
+ while( *p != ',' ) if( ++p > end ) return( NULL );
+ *p++ = '\0';
+
+ key_file = p;
+ while( *p != ',' ) if( ++p > end ) return( NULL );
+ *p++ = '\0';
+
+ if( x509_crt_parse_file( new->cert, crt_file ) != 0 ||
+ pk_parse_keyfile( new->key, key_file, "" ) != 0 )
+ return( NULL );
+
+ new->next = cur;
+ cur = new;
+
+ }
+
+ return( cur );
+}
+
+void sni_free( sni_entry *head )
+{
+ sni_entry *cur = head, *next;
+
+ while( cur != NULL )
+ {
+ x509_crt_free( cur->cert );
+ polarssl_free( cur->cert );
+
+ pk_free( cur->key );
+ polarssl_free( cur->key );
+
+ next = cur->next;
+ polarssl_free( cur );
+ cur = next;
+ }
+}
+
+/*
+ * SNI callback.
+ */
+int sni_callback( void *p_info, ssl_context *ssl,
+ const unsigned char *name, size_t name_len )
+{
+ sni_entry *cur = (sni_entry *) p_info;
+
+ while( cur != NULL )
+ {
+ if( name_len == strlen( cur->name ) &&
+ memcmp( name, cur->name, name_len ) == 0 )
+ {
+ ssl_set_own_cert( ssl, cur->cert, cur->key );
+ return( 0 );
+ }
+
+ cur = cur->next;
+ }
+
+ return( -1 );
+}
+
+#endif /* POLARSSL_SNI */
+
int main( int argc, char *argv[] )
{
int ret = 0, len, written, frags;
@@ -234,6 +426,9 @@
#if defined(POLARSSL_SSL_CACHE_C)
ssl_cache_context cache;
#endif
+#if defined(POLARSSL_SNI)
+ sni_entry *sni_info = NULL;
+#endif
#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
unsigned char alloc_buf[100000];
#endif
@@ -287,6 +482,7 @@
opt.server_addr = DFL_SERVER_ADDR;
opt.server_port = DFL_SERVER_PORT;
opt.debug_level = DFL_DEBUG_LEVEL;
+ opt.nbio = DFL_NBIO;
opt.ca_file = DFL_CA_FILE;
opt.ca_path = DFL_CA_PATH;
opt.crt_file = DFL_CRT_FILE;
@@ -298,11 +494,16 @@
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;
opt.mfl_code = DFL_MFL_CODE;
opt.tickets = DFL_TICKETS;
+ opt.ticket_timeout = DFL_TICKET_TIMEOUT;
+ opt.cache_max = DFL_CACHE_MAX;
+ opt.cache_timeout = DFL_CACHE_TIMEOUT;
+ opt.sni = DFL_SNI;
for( i = 1; i < argc; i++ )
{
@@ -325,6 +526,12 @@
if( opt.debug_level < 0 || opt.debug_level > 65535 )
goto usage;
}
+ else if( strcmp( p, "nbio" ) == 0 )
+ {
+ opt.nbio = atoi( q );
+ if( opt.nbio < 0 || opt.nbio > 2 )
+ goto usage;
+ }
else if( strcmp( p, "ca_file" ) == 0 )
opt.ca_file = q;
else if( strcmp( p, "ca_path" ) == 0 )
@@ -365,6 +572,12 @@
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 )
@@ -446,6 +659,28 @@
if( opt.tickets < 0 || opt.tickets > 1 )
goto usage;
}
+ else if( strcmp( p, "ticket_timeout" ) == 0 )
+ {
+ opt.ticket_timeout = atoi( q );
+ if( opt.ticket_timeout < 0 )
+ goto usage;
+ }
+ else if( strcmp( p, "cache_max" ) == 0 )
+ {
+ opt.cache_max = atoi( q );
+ if( opt.cache_max < 0 )
+ goto usage;
+ }
+ else if( strcmp( p, "cache_timeout" ) == 0 )
+ {
+ opt.cache_timeout = atoi( q );
+ if( opt.cache_timeout < 0 )
+ goto usage;
+ }
+ else if( strcmp( p, "sni" ) == 0 )
+ {
+ opt.sni = q;
+ }
else
goto usage;
}
@@ -551,9 +786,15 @@
#if defined(POLARSSL_FS_IO)
if( strlen( opt.ca_path ) )
- ret = x509_crt_parse_path( &cacert, opt.ca_path );
+ if( strcmp( opt.ca_path, "none" ) == 0 )
+ ret = 0;
+ else
+ ret = x509_crt_parse_path( &cacert, opt.ca_path );
else if( strlen( opt.ca_file ) )
- ret = x509_crt_parse_file( &cacert, opt.ca_file );
+ if( strcmp( opt.ca_file, "none" ) == 0 )
+ ret = 0;
+ else
+ ret = x509_crt_parse_file( &cacert, opt.ca_file );
else
#endif
#if defined(POLARSSL_CERTS_C)
@@ -580,7 +821,7 @@
fflush( stdout );
#if defined(POLARSSL_FS_IO)
- if( strlen( opt.crt_file ) )
+ if( strlen( opt.crt_file ) && strcmp( opt.crt_file, "none" ) != 0 )
{
key_cert_init++;
if( ( ret = x509_crt_parse_file( &srvcert, opt.crt_file ) ) != 0 )
@@ -590,7 +831,7 @@
goto exit;
}
}
- if( strlen( opt.key_file ) )
+ if( strlen( opt.key_file ) && strcmp( opt.key_file, "none" ) != 0 )
{
key_cert_init++;
if( ( ret = pk_parse_keyfile( &pkey, opt.key_file, "" ) ) != 0 )
@@ -605,7 +846,7 @@
goto exit;
}
- if( strlen( opt.crt_file2 ) )
+ if( strlen( opt.crt_file2 ) && strcmp( opt.crt_file2, "none" ) != 0 )
{
key_cert_init2++;
if( ( ret = x509_crt_parse_file( &srvcert2, opt.crt_file2 ) ) != 0 )
@@ -615,7 +856,7 @@
goto exit;
}
}
- if( strlen( opt.key_file2 ) )
+ if( strlen( opt.key_file2 ) && strcmp( opt.key_file2, "none" ) != 0 )
{
key_cert_init2++;
if( ( ret = pk_parse_keyfile( &pkey2, opt.key_file2, "" ) ) != 0 )
@@ -631,7 +872,12 @@
goto exit;
}
#endif
- if( key_cert_init == 0 && key_cert_init2 == 0 )
+ if( key_cert_init == 0 &&
+ strcmp( opt.crt_file, "none" ) != 0 &&
+ strcmp( opt.key_file, "none" ) != 0 &&
+ key_cert_init2 == 0 &&
+ strcmp( opt.crt_file2, "none" ) != 0 &&
+ strcmp( opt.key_file2, "none" ) != 0 )
{
#if !defined(POLARSSL_CERTS_C)
printf( "Not certificated or key provided, and \n"
@@ -678,6 +924,22 @@
printf( " ok\n" );
#endif /* POLARSSL_X509_CRT_PARSE_C */
+#if defined(POLARSSL_SNI)
+ if( opt.sni != NULL )
+ {
+ printf( " . Setting up SNI information..." );
+ fflush( stdout );
+
+ if( ( sni_info = sni_parse( opt.sni ) ) == NULL )
+ {
+ printf( " failed\n" );
+ goto exit;
+ }
+
+ printf( " ok\n" );
+ }
+#endif /* POLARSSL_SNI */
+
/*
* 2. Setup the listening TCP socket
*/
@@ -716,12 +978,21 @@
ssl_set_dbg( &ssl, my_debug, stdout );
#if defined(POLARSSL_SSL_CACHE_C)
+ if( opt.cache_max != -1 )
+ ssl_cache_set_max_entries( &cache, opt.cache_max );
+
+ if( opt.cache_timeout != -1 )
+ ssl_cache_set_timeout( &cache, opt.cache_timeout );
+
ssl_set_session_cache( &ssl, ssl_cache_get, &cache,
ssl_cache_set, &cache );
#endif
#if defined(POLARSSL_SSL_SESSION_TICKETS)
ssl_set_session_tickets( &ssl, opt.tickets );
+
+ if( opt.ticket_timeout != -1 )
+ ssl_set_session_ticket_lifetime( &ssl, opt.ticket_timeout );
#endif
if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
@@ -731,13 +1002,22 @@
ssl_legacy_renegotiation( &ssl, opt.allow_legacy );
#if defined(POLARSSL_X509_CRT_PARSE_C)
- ssl_set_ca_chain( &ssl, &cacert, NULL, NULL );
+ if( strcmp( opt.ca_path, "none" ) != 0 &&
+ strcmp( opt.ca_file, "none" ) != 0 )
+ {
+ ssl_set_ca_chain( &ssl, &cacert, NULL, NULL );
+ }
if( key_cert_init )
ssl_set_own_cert( &ssl, &srvcert, &pkey );
if( key_cert_init2 )
ssl_set_own_cert( &ssl, &srvcert2, &pkey2 );
#endif
+#if defined(POLARSSL_SNI)
+ if( opt.sni != NULL )
+ ssl_set_sni( &ssl, sni_callback, sni_info );
+#endif
+
#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
ssl_set_psk( &ssl, psk, psk_len, (const unsigned char *) opt.psk_identity,
strlen( opt.psk_identity ) );
@@ -788,8 +1068,20 @@
goto exit;
}
- ssl_set_bio( &ssl, net_recv, &client_fd,
- net_send, &client_fd );
+ if( opt.nbio > 0 )
+ ret = net_set_nonblock( client_fd );
+ else
+ ret = net_set_block( client_fd );
+ if( ret != 0 )
+ {
+ printf( " failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret );
+ goto exit;
+ }
+
+ if( opt.nbio == 2 )
+ ssl_set_bio( &ssl, my_recv, &client_fd, my_send, &client_fd );
+ else
+ ssl_set_bio( &ssl, net_recv, &client_fd, net_send, &client_fd );
printf( " ok\n" );
@@ -926,43 +1218,48 @@
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;
@@ -986,6 +1283,9 @@
x509_crt_free( &srvcert2 );
pk_free( &pkey2 );
#endif
+#if defined(POLARSSL_SNI)
+ sni_free( sni_info );
+#endif
ssl_free( &ssl );
entropy_free( &entropy );
diff --git a/tests/Descriptions.txt b/tests/Descriptions.txt
new file mode 100644
index 0000000..5b546e9
--- /dev/null
+++ b/tests/Descriptions.txt
@@ -0,0 +1,16 @@
+test_suites
+ The various 'test_suite_XXX' programs from the 'tests' directory, executed
+ using 'make check' (Unix make) or 'make test' (Cmake), include test cases
+ (reference test vectors, sanity checks, etc.) for all modules except the
+ SSL modules.
+
+compat
+ The 'tests/compat.sh' script checks interoperability with OpenSSL for every
+ ciphersuite, in every version, using client authentication or not. For
+ each ciphersuite/version it performs a full handshake and a small data
+ exchange.
+
+ssl_opt
+ The 'tests/ssl-opt.sh' script checks various options and/or operations not
+ covered by compat.sh: session resumption (using session cache or tickets),
+ renegotiation, SNI, other extensions, etc.
diff --git a/tests/compat.sh b/tests/compat.sh
index bf1691b..d06adb8 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -1,69 +1,87 @@
#!/bin/bash
-killall -q openssl ssl_server ssl_server2
+# Test interop with OpenSSL for each common ciphersuite and version.
+# Also test selfop for ciphersuites not shared with OpenSSL.
+
+set -u
let "tests = 0"
let "failed = 0"
let "skipped = 0"
+let "srvmem = 0"
+
+# default values, can be overriden by the environment
+: ${P_SRV:=../programs/ssl/ssl_server2}
+: ${P_CLI:=../programs/ssl/ssl_client2}
+: ${OPENSSL_CMD:=openssl} # OPENSSL would conflict with the build system
+: ${GNUTLS_CLI:=gnutls-cli}
+: ${GNUTLS_SERV:=gnutls-serv}
MODES="ssl3 tls1 tls1_1 tls1_2"
VERIFIES="NO YES"
TYPES="ECDSA RSA PSK"
-OPENSSL=openssl
FILTER=""
+EXCLUDE='NULL\|DES-CBC-' # avoid plain DES but keep 3DES-EDE-CBC (PolarSSL), DES-CBC3 (OpenSSL)
VERBOSE=""
+PEERS="OpenSSL PolarSSL" # GnuTLS not enabled by default, 3.2.4 might not be available on all buildbot machines
+MEMCHECK=0
-# Parse arguments
-#
-until [ -z "$1" ]
-do
- case "$1" in
- -f|--filter)
- # Filter ciphersuites
- shift
- FILTER=$1
- ;;
- -m|--modes)
- # Perform modes
- shift
- MODES=$1
- ;;
- -t|--types)
- # Key exchange types
- shift
- TYPES=$1
- ;;
- -V|--verify)
- # Verifiction modes
- shift
- VERIFIES=$1
- ;;
- -v|--verbose)
- # Set verbosity
- shift
- VERBOSE=1
- ;;
- -h|--help)
- # print help
- echo "Usage: $0"
- echo -e " -f|--filter\tFilter ciphersuites to test (Default: all)"
- echo -e " -h|--help\t\tPrint this help."
- echo -e " -m|--modes\tWhich modes to perform (Default: \"ssl3 tls1 tls1_1 tls1_2\")"
- echo -e " -t|--types\tWhich key exchange type to perform (Default: \"ECDSA RSA PSK\")"
- echo -e " -V|--verify\tWhich verification modes to perform (Default: \"NO YES\")"
- echo -e " -v|--verbose\t\tSet verbose output."
- exit 1
- ;;
- *)
- # print error
- echo "Unknown argument: '$1'"
- exit 1
- ;;
- esac
- shift
-done
+print_usage() {
+ echo "Usage: $0"
+ echo -e " -h|--help\tPrint this help."
+ echo -e " -f|--filter\tOnly matching ciphersuites are tested (Default: '$FILTER')"
+ echo -e " -e|--exclude\tMatching ciphersuites are excluded (Default: '$EXCLUDE')"
+ echo -e " -m|--modes\tWhich modes to perform (Default: '$MODES')"
+ echo -e " -t|--types\tWhich key exchange type to perform (Default: '$TYPES')"
+ echo -e " -V|--verify\tWhich verification modes to perform (Default: '$VERIFIES')"
+ echo -e " -p|--peers\tWhich peers to use (Default: '$PEERS')"
+ echo -e " \tAlso available: GnuTLS (needs v3.2.4 or higher)"
+ echo -e " -M|--memcheck\tCheck memory leaks and errors."
+ echo -e " -v|--verbose\tSet verbose output."
+}
-log () {
+get_options() {
+ while [ $# -gt 0 ]; do
+ case "$1" in
+ -f|--filter)
+ shift; FILTER=$1
+ ;;
+ -e|--exclude)
+ shift; EXCLUDE=$1
+ ;;
+ -m|--modes)
+ shift; MODES=$1
+ ;;
+ -t|--types)
+ shift; TYPES=$1
+ ;;
+ -V|--verify)
+ shift; VERIFIES=$1
+ ;;
+ -p|--peers)
+ shift; PEERS=$1
+ ;;
+ -v|--verbose)
+ VERBOSE=1
+ ;;
+ -M|--memcheck)
+ MEMCHECK=1
+ ;;
+ -h|--help)
+ print_usage
+ exit 0
+ ;;
+ *)
+ echo "Unknown argument: '$1'"
+ print_usage
+ exit 1
+ ;;
+ esac
+ shift
+ done
+}
+
+log() {
if [ "X" != "X$VERBOSE" ]; then
echo "$@"
fi
@@ -71,509 +89,822 @@
filter()
{
- LIST=$1
- FILTER=$2
-
+ LIST="$1"
NEW_LIST=""
for i in $LIST;
do
- NEW_LIST="$NEW_LIST $( echo "$i" | grep "$FILTER" )"
+ NEW_LIST="$NEW_LIST $( echo "$i" | grep "$FILTER" | grep -v "$EXCLUDE" )"
done
- echo "$NEW_LIST"
+ # normalize whitespace
+ echo "$NEW_LIST" | sed -e 's/[[:space:]]\+/ /g' -e 's/^ //' -e 's/ $//'
}
-for VERIFY in $VERIFIES;
-do
-
-if [ "X$VERIFY" = "XYES" ];
-then
- P_SERVER_BASE="ca_file=data_files/test-ca_cat12.crt auth_mode=required"
- P_CLIENT_BASE="ca_file=data_files/test-ca_cat12.crt"
- O_SERVER_BASE="-CAfile data_files/test-ca_cat12.crt -Verify 10"
- O_CLIENT_BASE="-CAfile data_files/test-ca_cat12.crt"
-else
- P_SERVER_BASE=""
- P_CLIENT_BASE=""
- O_SERVER_BASE=""
- O_CLIENT_BASE=""
-fi
-
-
-for MODE in $MODES;
-do
-
-# avoid an avalanche of errors due to typos
-case $MODE in
- ssl3|tls1|tls1_1|tls1_2)
- ;;
- *)
- echo "error: invalid mode: $MODE" >&2
- exit 1;
-esac
-
-echo "-----------"
-echo "Running for $MODE (Verify: $VERIFY)"
-echo "-----------"
-
-for TYPE in $TYPES;
-do
-
-P_CIPHERS=""
-O_CIPHERS=""
-
-case $TYPE in
-
- "ECDSA")
-
- P_SERVER_ARGS="$P_SERVER_BASE crt_file=data_files/server5.crt key_file=data_files/server5.key"
- P_CLIENT_ARGS="$P_CLIENT_BASE crt_file=data_files/server6.crt key_file=data_files/server6.key"
- O_SERVER_ARGS="$O_SERVER_BASE -cert data_files/server5.crt -key data_files/server5.key"
- O_CLIENT_ARGS="$O_CLIENT_BASE -cert data_files/server6.crt -key data_files/server6.key"
-
- if [ "$MODE" != "ssl3" ];
- then
- P_CIPHERS="$P_CIPHERS \
- TLS-ECDHE-ECDSA-WITH-NULL-SHA \
- TLS-ECDHE-ECDSA-WITH-RC4-128-SHA \
- TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA \
- TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA \
- TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA \
- TLS-ECDH-ECDSA-WITH-NULL-SHA \
- TLS-ECDH-ECDSA-WITH-RC4-128-SHA \
- TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA \
- TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA \
- TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA \
- "
-
- O_CIPHERS="$O_CIPHERS \
- ECDHE-ECDSA-NULL-SHA \
- ECDHE-ECDSA-RC4-SHA \
- ECDHE-ECDSA-DES-CBC3-SHA \
- ECDHE-ECDSA-AES128-SHA \
- ECDHE-ECDSA-AES256-SHA \
- ECDH-ECDSA-NULL-SHA \
- ECDH-ECDSA-RC4-SHA \
- ECDH-ECDSA-DES-CBC3-SHA \
- ECDH-ECDSA-AES128-SHA \
- ECDH-ECDSA-AES256-SHA \
- "
- fi
-
- if [ "$MODE" = "tls1_2" ];
- then
- P_CIPHERS="$P_CIPHERS \
- TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 \
- TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384 \
- TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
- TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 \
- TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256 \
- TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384 \
- TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256 \
- TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384 \
- "
-
- O_CIPHERS="$O_CIPHERS \
- ECDHE-ECDSA-AES128-SHA256 \
- ECDHE-ECDSA-AES256-SHA384 \
- ECDHE-ECDSA-AES128-GCM-SHA256 \
- ECDHE-ECDSA-AES256-GCM-SHA384 \
- ECDH-ECDSA-AES128-SHA256 \
- ECDH-ECDSA-AES256-SHA384 \
- ECDH-ECDSA-AES128-GCM-SHA256 \
- ECDH-ECDSA-AES256-GCM-SHA384 \
- "
- fi
-
- ;;
-
- "RSA")
-
- P_SERVER_ARGS="$P_SERVER_BASE crt_file=data_files/server1.crt key_file=data_files/server1.key"
- P_CLIENT_ARGS="$P_CLIENT_BASE crt_file=data_files/server2.crt key_file=data_files/server2.key"
- O_SERVER_ARGS="$O_SERVER_BASE -cert data_files/server1.crt -key data_files/server1.key"
- O_CLIENT_ARGS="$O_CLIENT_BASE -cert data_files/server2.crt -key data_files/server2.key"
-
- P_CIPHERS="$P_CIPHERS \
- TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
- TLS-DHE-RSA-WITH-AES-256-CBC-SHA \
- TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA \
- TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA \
- TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA \
- TLS-RSA-WITH-AES-256-CBC-SHA \
- TLS-RSA-WITH-CAMELLIA-256-CBC-SHA \
- TLS-RSA-WITH-AES-128-CBC-SHA \
- TLS-RSA-WITH-CAMELLIA-128-CBC-SHA \
- TLS-RSA-WITH-3DES-EDE-CBC-SHA \
- TLS-RSA-WITH-RC4-128-SHA \
- TLS-RSA-WITH-RC4-128-MD5 \
- TLS-RSA-WITH-NULL-MD5 \
- TLS-RSA-WITH-NULL-SHA \
- TLS-RSA-WITH-DES-CBC-SHA \
- TLS-DHE-RSA-WITH-DES-CBC-SHA \
- "
-
- O_CIPHERS="$O_CIPHERS \
- DHE-RSA-AES128-SHA \
- DHE-RSA-AES256-SHA \
- DHE-RSA-CAMELLIA128-SHA \
- DHE-RSA-CAMELLIA256-SHA \
- EDH-RSA-DES-CBC3-SHA \
- AES256-SHA \
- CAMELLIA256-SHA \
- AES128-SHA \
- CAMELLIA128-SHA \
- DES-CBC3-SHA \
- RC4-SHA \
- RC4-MD5 \
- NULL-MD5 \
- NULL-SHA \
- DES-CBC-SHA \
- EDH-RSA-DES-CBC-SHA \
- "
-
- if [ "$MODE" != "ssl3" ];
- then
- P_CIPHERS="$P_CIPHERS \
- TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA \
- TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA \
- TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA \
- TLS-ECDHE-RSA-WITH-RC4-128-SHA \
- TLS-ECDHE-RSA-WITH-NULL-SHA \
- "
-
- O_CIPHERS="$O_CIPHERS \
- ECDHE-RSA-AES256-SHA \
- ECDHE-RSA-AES128-SHA \
- ECDHE-RSA-DES-CBC3-SHA \
- ECDHE-RSA-RC4-SHA \
- ECDHE-RSA-NULL-SHA \
- "
- fi
-
- if [ "$MODE" = "tls1_2" ];
- then
- P_CIPHERS="$P_CIPHERS \
- TLS-RSA-WITH-NULL-SHA256 \
- TLS-RSA-WITH-AES-128-CBC-SHA256 \
- TLS-DHE-RSA-WITH-AES-128-CBC-SHA256 \
- TLS-RSA-WITH-AES-256-CBC-SHA256 \
- TLS-DHE-RSA-WITH-AES-256-CBC-SHA256 \
- TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256 \
- TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384 \
- TLS-RSA-WITH-AES-128-GCM-SHA256 \
- TLS-RSA-WITH-AES-256-GCM-SHA384 \
- TLS-DHE-RSA-WITH-AES-128-GCM-SHA256 \
- TLS-DHE-RSA-WITH-AES-256-GCM-SHA384 \
- TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256 \
- TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384 \
- "
-
- O_CIPHERS="$O_CIPHERS \
- NULL-SHA256 \
- AES128-SHA256 \
- DHE-RSA-AES128-SHA256 \
- AES256-SHA256 \
- DHE-RSA-AES256-SHA256 \
- ECDHE-RSA-AES128-SHA256 \
- ECDHE-RSA-AES256-SHA384 \
- AES128-GCM-SHA256 \
- DHE-RSA-AES128-GCM-SHA256 \
- AES256-GCM-SHA384 \
- DHE-RSA-AES256-GCM-SHA384 \
- ECDHE-RSA-AES128-GCM-SHA256 \
- ECDHE-RSA-AES256-GCM-SHA384 \
- "
- fi
-
- ;;
-
- "PSK")
-
- P_SERVER_ARGS="$P_SERVER_BASE psk=6162636465666768696a6b6c6d6e6f70"
- P_CLIENT_ARGS="$P_CLIENT_BASE psk=6162636465666768696a6b6c6d6e6f70"
- # openssl s_server won't start without certificates...
- O_SERVER_ARGS="$O_SERVER_BASE -psk 6162636465666768696a6b6c6d6e6f70 -cert data_files/server1.crt -key data_files/server1.key"
- O_CLIENT_ARGS="$O_CLIENT_BASE -psk 6162636465666768696a6b6c6d6e6f70"
-
- P_CIPHERS="$P_CIPHERS \
- TLS-PSK-WITH-RC4-128-SHA \
- TLS-PSK-WITH-3DES-EDE-CBC-SHA \
- TLS-PSK-WITH-AES-128-CBC-SHA \
- TLS-PSK-WITH-AES-256-CBC-SHA \
- "
-
- O_CIPHERS="$O_CIPHERS \
- PSK-RC4-SHA \
- PSK-3DES-EDE-CBC-SHA \
- PSK-AES128-CBC-SHA \
- PSK-AES256-CBC-SHA \
- "
-
- ;;
-
-esac
-
-# Filter ciphersuites
-if [ "X" != "X$FILTER" ];
-then
- O_CIPHERS=$( filter "$O_CIPHERS" "$FILTER" )
- P_CIPHERS=$( filter "$P_CIPHERS" "$FILTER" )
-fi
-
-
-log "$OPENSSL s_server -www -quiet -cipher NULL,ALL $O_SERVER_ARGS -$MODE"
-$OPENSSL s_server -www -quiet -cipher NULL,ALL $O_SERVER_ARGS -$MODE >/dev/null 2>&1 &
-PROCESS_ID=$!
-
-sleep 1
-
-for i in $P_CIPHERS;
-do
- let "tests++"
- log "../programs/ssl/ssl_client2 $P_CLIENT_ARGS force_ciphersuite=$i force_version=$MODE"
- RESULT="$( ../programs/ssl/ssl_client2 $P_CLIENT_ARGS force_ciphersuite=$i force_version=$MODE )"
- EXIT=$?
- echo -n "OpenSSL Server - PolarSSL Client - $i : $EXIT - "
- if [ "$EXIT" = "2" ];
+filter_ciphersuites()
+{
+ if [ "X" != "X$FILTER" -o "X" != "X$EXCLUDE" ];
then
- echo Ciphersuite not supported in client
- let "skipped++"
- elif [ "$EXIT" != "0" ];
- then
- echo Failed
- echo "$OPENSSL s_server -www -quiet -cipher NULL,ALL $O_SERVER_ARGS -$MODE"
- echo "ssl_client2 force_ciphersuite=$i force_version=$MODE $P_CLIENT_ARGS"
- echo $RESULT
- let "failed++"
- else
- echo Success
+ P_CIPHERS=$( filter "$P_CIPHERS" )
+ O_CIPHERS=$( filter "$O_CIPHERS" )
+ G_CIPHERS=$( filter "$G_CIPHERS" )
fi
-done
-kill $PROCESS_ID 2>/dev/null
-wait $PROCESS_ID 2>/dev/null
+}
-log "../programs/ssl/ssl_server2 server_addr=0.0.0.0 $P_SERVER_ARGS force_version=$MODE > /dev/null"
-../programs/ssl/ssl_server2 server_addr=0.0.0.0 $P_SERVER_ARGS force_version=$MODE > /dev/null &
-PROCESS_ID=$!
+reset_ciphersuites()
+{
+ P_CIPHERS=""
+ O_CIPHERS=""
+ G_CIPHERS=""
+}
-sleep 1
+add_openssl_ciphersuites()
+{
+ case $TYPE in
-for i in $O_CIPHERS;
-do
- let "tests++"
- log "$OPENSSL s_client -$MODE -cipher $i $O_CLIENT_ARGS"
- RESULT="$( ( echo -e 'GET HTTP/1.0'; echo; sleep 1 ) | $OPENSSL s_client -$MODE -cipher $i $O_CLIENT_ARGS 2>&1 )"
- EXIT=$?
- echo -n "PolarSSL Server - OpenSSL Client - $i : $EXIT - "
+ "ECDSA")
+ if [ "$MODE" != "ssl3" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-ECDHE-ECDSA-WITH-NULL-SHA \
+ TLS-ECDHE-ECDSA-WITH-RC4-128-SHA \
+ TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA \
+ TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA \
+ TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA \
+ TLS-ECDH-ECDSA-WITH-NULL-SHA \
+ TLS-ECDH-ECDSA-WITH-RC4-128-SHA \
+ TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA \
+ TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA \
+ TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA \
+ "
+ O_CIPHERS="$O_CIPHERS \
+ ECDHE-ECDSA-NULL-SHA \
+ ECDHE-ECDSA-RC4-SHA \
+ ECDHE-ECDSA-DES-CBC3-SHA \
+ ECDHE-ECDSA-AES128-SHA \
+ ECDHE-ECDSA-AES256-SHA \
+ ECDH-ECDSA-NULL-SHA \
+ ECDH-ECDSA-RC4-SHA \
+ ECDH-ECDSA-DES-CBC3-SHA \
+ ECDH-ECDSA-AES128-SHA \
+ ECDH-ECDSA-AES256-SHA \
+ "
+ fi
+ if [ "$MODE" = "tls1_2" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 \
+ TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384 \
+ TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 \
+ TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256 \
+ TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384 \
+ TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256 \
+ TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384 \
+ "
+ O_CIPHERS="$O_CIPHERS \
+ ECDHE-ECDSA-AES128-SHA256 \
+ ECDHE-ECDSA-AES256-SHA384 \
+ ECDHE-ECDSA-AES128-GCM-SHA256 \
+ ECDHE-ECDSA-AES256-GCM-SHA384 \
+ ECDH-ECDSA-AES128-SHA256 \
+ ECDH-ECDSA-AES256-SHA384 \
+ ECDH-ECDSA-AES128-GCM-SHA256 \
+ ECDH-ECDSA-AES256-GCM-SHA384 \
+ "
+ fi
+ ;;
- if [ "$EXIT" != "0" ];
- then
- SUPPORTED="$( echo $RESULT | grep 'Cipher is (NONE)' )"
- if [ "X$SUPPORTED" != "X" ]
- then
- echo "Ciphersuite not supported in server"
- let "skipped++"
- else
- echo Failed
- echo "ssl_server2 $P_SERVER_ARGS force_version=$MODE"
- echo "$OPENSSL s_client -$MODE -cipher $i $O_CLIENT_ARGS"
- echo $RESULT
- let "failed++"
- fi
- else
- echo Success
- fi
-done
-
-kill $PROCESS_ID 2>/dev/null
-wait $PROCESS_ID 2>/dev/null
-
-log "../programs/ssl/ssl_server2 server_addr=0.0.0.0 $P_SERVER_ARGS force_version=$MODE"
-../programs/ssl/ssl_server2 server_addr=0.0.0.0 $P_SERVER_ARGS force_version=$MODE > /dev/null &
-PROCESS_ID=$!
-
-sleep 1
-
-# Add ciphersuites supported by PolarSSL only
-
-case $TYPE in
-
- "ECDSA")
-
- if [ "$MODE" != "ssl3" ];
- then
- P_CIPHERS="$P_CIPHERS \
- TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256 \
- TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384 \
- TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256 \
- TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384 \
- "
- fi
-
- if [ "$MODE" = "tls1_2" ];
- then
- P_CIPHERS="$P_CIPHERS \
- TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256 \
- TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384 \
- TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256 \
- TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384 \
- "
- fi
-
- ;;
-
- "RSA")
-
- if [ "$MODE" != "ssl3" ];
- then
- P_CIPHERS="$P_CIPHERS \
- TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256 \
- TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384 \
- "
- fi
-
- if [ "$MODE" = "tls1_2" ];
- then
- P_CIPHERS="$P_CIPHERS \
- TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256 \
- TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256 \
- TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256 \
- TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256 \
- TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256 \
- TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384 \
- TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256 \
- TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384 \
- TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256 \
- TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384 \
- "
- fi
-
- ;;
-
- "PSK")
-
- P_CIPHERS="$P_CIPHERS \
- TLS-DHE-PSK-WITH-RC4-128-SHA \
- TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA \
- TLS-DHE-PSK-WITH-AES-128-CBC-SHA \
- TLS-DHE-PSK-WITH-AES-256-CBC-SHA \
- TLS-DHE-PSK-WITH-NULL-SHA \
- TLS-PSK-WITH-NULL-SHA \
- TLS-RSA-PSK-WITH-RC4-128-SHA \
- TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA \
- TLS-RSA-PSK-WITH-AES-256-CBC-SHA \
- TLS-RSA-PSK-WITH-AES-128-CBC-SHA \
- TLS-RSA-WITH-NULL-SHA \
- TLS-RSA-WITH-NULL-MD5 \
- TLS-PSK-WITH-AES-128-CBC-SHA256 \
- TLS-PSK-WITH-AES-256-CBC-SHA384 \
- TLS-DHE-PSK-WITH-AES-128-CBC-SHA256 \
- TLS-DHE-PSK-WITH-AES-256-CBC-SHA384 \
- TLS-PSK-WITH-NULL-SHA256 \
- TLS-PSK-WITH-NULL-SHA384 \
- TLS-DHE-PSK-WITH-NULL-SHA256 \
- TLS-DHE-PSK-WITH-NULL-SHA384 \
- TLS-RSA-PSK-WITH-AES-256-CBC-SHA384 \
- TLS-RSA-PSK-WITH-AES-128-CBC-SHA256 \
- TLS-RSA-PSK-WITH-NULL-SHA256 \
- TLS-RSA-PSK-WITH-NULL-SHA384 \
- TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256 \
- TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384 \
- TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256 \
- TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384 \
- TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384 \
- TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256 \
- "
-
-
- if [ "$MODE" != "ssl3" ];
- then
+ "RSA")
P_CIPHERS="$P_CIPHERS \
- TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA \
- TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA \
- TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA \
- TLS-ECDHE-PSK-WITH-RC4-128-SHA \
- TLS-ECDHE-PSK-WITH-NULL-SHA \
- TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384 \
- TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384 \
- TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256 \
- TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256 \
- TLS-ECDHE-PSK-WITH-NULL-SHA384 \
- TLS-ECDHE-PSK-WITH-NULL-SHA256 \
+ TLS-DHE-RSA-WITH-AES-128-CBC-SHA \
+ TLS-DHE-RSA-WITH-AES-256-CBC-SHA \
+ TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA \
+ TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA \
+ TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA \
+ TLS-RSA-WITH-AES-256-CBC-SHA \
+ TLS-RSA-WITH-CAMELLIA-256-CBC-SHA \
+ TLS-RSA-WITH-AES-128-CBC-SHA \
+ TLS-RSA-WITH-CAMELLIA-128-CBC-SHA \
+ TLS-RSA-WITH-3DES-EDE-CBC-SHA \
+ TLS-RSA-WITH-RC4-128-SHA \
+ TLS-RSA-WITH-RC4-128-MD5 \
+ TLS-RSA-WITH-NULL-MD5 \
+ TLS-RSA-WITH-NULL-SHA \
+ TLS-RSA-WITH-DES-CBC-SHA \
+ TLS-DHE-RSA-WITH-DES-CBC-SHA \
"
- fi
+ O_CIPHERS="$O_CIPHERS \
+ DHE-RSA-AES128-SHA \
+ DHE-RSA-AES256-SHA \
+ DHE-RSA-CAMELLIA128-SHA \
+ DHE-RSA-CAMELLIA256-SHA \
+ EDH-RSA-DES-CBC3-SHA \
+ AES256-SHA \
+ CAMELLIA256-SHA \
+ AES128-SHA \
+ CAMELLIA128-SHA \
+ DES-CBC3-SHA \
+ RC4-SHA \
+ RC4-MD5 \
+ NULL-MD5 \
+ NULL-SHA \
+ DES-CBC-SHA \
+ EDH-RSA-DES-CBC-SHA \
+ "
+ if [ "$MODE" != "ssl3" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA \
+ TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA \
+ TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA \
+ TLS-ECDHE-RSA-WITH-RC4-128-SHA \
+ TLS-ECDHE-RSA-WITH-NULL-SHA \
+ "
+ O_CIPHERS="$O_CIPHERS \
+ ECDHE-RSA-AES256-SHA \
+ ECDHE-RSA-AES128-SHA \
+ ECDHE-RSA-DES-CBC3-SHA \
+ ECDHE-RSA-RC4-SHA \
+ ECDHE-RSA-NULL-SHA \
+ "
+ fi
+ if [ "$MODE" = "tls1_2" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-RSA-WITH-NULL-SHA256 \
+ TLS-RSA-WITH-AES-128-CBC-SHA256 \
+ TLS-DHE-RSA-WITH-AES-128-CBC-SHA256 \
+ TLS-RSA-WITH-AES-256-CBC-SHA256 \
+ TLS-DHE-RSA-WITH-AES-256-CBC-SHA256 \
+ TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256 \
+ TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384 \
+ TLS-RSA-WITH-AES-128-GCM-SHA256 \
+ TLS-RSA-WITH-AES-256-GCM-SHA384 \
+ TLS-DHE-RSA-WITH-AES-128-GCM-SHA256 \
+ TLS-DHE-RSA-WITH-AES-256-GCM-SHA384 \
+ TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256 \
+ TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384 \
+ "
+ O_CIPHERS="$O_CIPHERS \
+ NULL-SHA256 \
+ AES128-SHA256 \
+ DHE-RSA-AES128-SHA256 \
+ AES256-SHA256 \
+ DHE-RSA-AES256-SHA256 \
+ ECDHE-RSA-AES128-SHA256 \
+ ECDHE-RSA-AES256-SHA384 \
+ AES128-GCM-SHA256 \
+ DHE-RSA-AES128-GCM-SHA256 \
+ AES256-GCM-SHA384 \
+ DHE-RSA-AES256-GCM-SHA384 \
+ ECDHE-RSA-AES128-GCM-SHA256 \
+ ECDHE-RSA-AES256-GCM-SHA384 \
+ "
+ fi
+ ;;
- if [ "$MODE" = "tls1_2" ];
- then
+ "PSK")
+ P_CIPHERS="$P_CIPHERS \
+ TLS-PSK-WITH-RC4-128-SHA \
+ TLS-PSK-WITH-3DES-EDE-CBC-SHA \
+ TLS-PSK-WITH-AES-128-CBC-SHA \
+ TLS-PSK-WITH-AES-256-CBC-SHA \
+ "
+ O_CIPHERS="$O_CIPHERS \
+ PSK-RC4-SHA \
+ PSK-3DES-EDE-CBC-SHA \
+ PSK-AES128-CBC-SHA \
+ PSK-AES256-CBC-SHA \
+ "
+ ;;
+ esac
+}
+
+add_gnutls_ciphersuites()
+{
+ case $TYPE in
+
+ "ECDSA")
+ if [ "$MODE" = "tls1_2" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256 \
+ TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384 \
+ TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256 \
+ TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384 \
+ "
+ G_CIPHERS="$G_CIPHERS \
+ +ECDHE-ECDSA:+CAMELLIA-128-CBC:+SHA256 \
+ +ECDHE-ECDSA:+CAMELLIA-256-CBC:+SHA384 \
+ +ECDHE-ECDSA:+CAMELLIA-128-GCM:+AEAD \
+ +ECDHE-ECDSA:+CAMELLIA-256-GCM:+AEAD \
+ "
+ fi
+ ;;
+
+ "RSA")
+ if [ "$MODE" = "tls1_2" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256 \
+ TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384 \
+ TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256 \
+ TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256 \
+ TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256 \
+ TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256 \
+ TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256 \
+ TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384 \
+ TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256 \
+ TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384 \
+ TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256 \
+ TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384 \
+ TLS-RSA-WITH-NULL-SHA256 \
+ TLS-RSA-WITH-NULL-SHA \
+ TLS-RSA-WITH-NULL-MD5 \
+ "
+ G_CIPHERS="$G_CIPHERS \
+ +ECDHE-RSA:+CAMELLIA-128-CBC:+SHA256 \
+ +ECDHE-RSA:+CAMELLIA-256-CBC:+SHA384 \
+ +RSA:+CAMELLIA-128-CBC:+SHA256 \
+ +RSA:+CAMELLIA-256-CBC:+SHA256 \
+ +DHE-RSA:+CAMELLIA-128-CBC:+SHA256 \
+ +DHE-RSA:+CAMELLIA-256-CBC:+SHA256 \
+ +ECDHE-RSA:+CAMELLIA-128-GCM:+AEAD \
+ +ECDHE-RSA:+CAMELLIA-256-GCM:+AEAD \
+ +DHE-RSA:+CAMELLIA-128-GCM:+AEAD \
+ +DHE-RSA:+CAMELLIA-256-GCM:+AEAD \
+ +RSA:+CAMELLIA-128-GCM:+AEAD \
+ +RSA:+CAMELLIA-256-GCM:+AEAD \
+ +RSA:+NULL:+SHA256 \
+ +RSA:+NULL:+SHA1 \
+ +RSA:+NULL:+MD5 \
+ "
+ fi
+ ;;
+
+ "PSK")
+ # GnuTLS 3.2.11 (2014-02-13) requires TLS 1.x for most *PSK suites
+ if [ "$MODE" != "ssl3" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA \
+ TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA \
+ TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA \
+ TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA \
+ TLS-DHE-PSK-WITH-AES-128-CBC-SHA \
+ TLS-DHE-PSK-WITH-AES-256-CBC-SHA \
+ TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA \
+ TLS-RSA-PSK-WITH-AES-256-CBC-SHA \
+ TLS-RSA-PSK-WITH-AES-128-CBC-SHA \
+ "
+ G_CIPHERS="$G_CIPHERS \
+ +ECDHE-PSK:+AES-256-CBC:+SHA1 \
+ +ECDHE-PSK:+AES-128-CBC:+SHA1 \
+ +ECDHE-PSK:+3DES-CBC:+SHA1 \
+ +DHE-PSK:+3DES-CBC:+SHA1 \
+ +DHE-PSK:+AES-128-CBC:+SHA1 \
+ +DHE-PSK:+AES-256-CBC:+SHA1 \
+ +RSA-PSK:+3DES-CBC:+SHA1 \
+ +RSA-PSK:+AES-256-CBC:+SHA1 \
+ +RSA-PSK:+AES-128-CBC:+SHA1 \
+ "
+ fi
+ if [ "$MODE" = "tls1_2" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384 \
+ TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384 \
+ TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256 \
+ TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256 \
+ TLS-ECDHE-PSK-WITH-NULL-SHA384 \
+ TLS-ECDHE-PSK-WITH-NULL-SHA256 \
+ TLS-PSK-WITH-AES-128-CBC-SHA256 \
+ TLS-PSK-WITH-AES-256-CBC-SHA384 \
+ TLS-DHE-PSK-WITH-AES-128-CBC-SHA256 \
+ TLS-DHE-PSK-WITH-AES-256-CBC-SHA384 \
+ TLS-PSK-WITH-NULL-SHA256 \
+ TLS-PSK-WITH-NULL-SHA384 \
+ TLS-DHE-PSK-WITH-NULL-SHA256 \
+ TLS-DHE-PSK-WITH-NULL-SHA384 \
+ TLS-RSA-PSK-WITH-AES-256-CBC-SHA384 \
+ TLS-RSA-PSK-WITH-AES-128-CBC-SHA256 \
+ TLS-RSA-PSK-WITH-NULL-SHA256 \
+ TLS-RSA-PSK-WITH-NULL-SHA384 \
+ TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256 \
+ TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384 \
+ TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256 \
+ TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384 \
+ TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384 \
+ TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256 \
+ TLS-PSK-WITH-AES-128-GCM-SHA256 \
+ TLS-PSK-WITH-AES-256-GCM-SHA384 \
+ TLS-DHE-PSK-WITH-AES-128-GCM-SHA256 \
+ TLS-DHE-PSK-WITH-AES-256-GCM-SHA384 \
+ TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256 \
+ TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384 \
+ TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256 \
+ TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384 \
+ TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256 \
+ TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384 \
+ TLS-RSA-PSK-WITH-AES-256-GCM-SHA384 \
+ TLS-RSA-PSK-WITH-AES-128-GCM-SHA256 \
+ "
+ G_CIPHERS="$G_CIPHERS \
+ +ECDHE-PSK:+AES-256-CBC:+SHA384 \
+ +ECDHE-PSK:+CAMELLIA-256-CBC:+SHA384 \
+ +ECDHE-PSK:+AES-128-CBC:+SHA256 \
+ +ECDHE-PSK:+CAMELLIA-128-CBC:+SHA256 \
+ +PSK:+AES-128-CBC:+SHA256 \
+ +PSK:+AES-256-CBC:+SHA384 \
+ +DHE-PSK:+AES-128-CBC:+SHA256 \
+ +DHE-PSK:+AES-256-CBC:+SHA384 \
+ +RSA-PSK:+AES-256-CBC:+SHA384 \
+ +RSA-PSK:+AES-128-CBC:+SHA256 \
+ +DHE-PSK:+CAMELLIA-128-CBC:+SHA256 \
+ +DHE-PSK:+CAMELLIA-256-CBC:+SHA384 \
+ +PSK:+CAMELLIA-128-CBC:+SHA256 \
+ +PSK:+CAMELLIA-256-CBC:+SHA384 \
+ +RSA-PSK:+CAMELLIA-256-CBC:+SHA384 \
+ +RSA-PSK:+CAMELLIA-128-CBC:+SHA256 \
+ +PSK:+AES-128-GCM:+AEAD \
+ +PSK:+AES-256-GCM:+AEAD \
+ +DHE-PSK:+AES-128-GCM:+AEAD \
+ +DHE-PSK:+AES-256-GCM:+AEAD \
+ +RSA-PSK:+CAMELLIA-128-GCM:+AEAD \
+ +RSA-PSK:+CAMELLIA-256-GCM:+AEAD \
+ +PSK:+CAMELLIA-128-GCM:+AEAD \
+ +PSK:+CAMELLIA-256-GCM:+AEAD \
+ +DHE-PSK:+CAMELLIA-128-GCM:+AEAD \
+ +DHE-PSK:+CAMELLIA-256-GCM:+AEAD \
+ +RSA-PSK:+AES-256-GCM:+AEAD \
+ +RSA-PSK:+AES-128-GCM:+AEAD \
+ +ECDHE-PSK:+NULL:+SHA384 \
+ +ECDHE-PSK:+NULL:+SHA256 \
+ +PSK:+NULL:+SHA256 \
+ +PSK:+NULL:+SHA384 \
+ +DHE-PSK:+NULL:+SHA256 \
+ +DHE-PSK:+NULL:+SHA384 \
+ +RSA-PSK:+NULL:+SHA256 \
+ +RSA-PSK:+NULL:+SHA384 \
+ "
+ fi
+ ;;
+ esac
+}
+
+add_polarssl_ciphersuites()
+{
+ case $TYPE in
+
+ "ECDSA")
+ if [ "$MODE" != "ssl3" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256 \
+ TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384 \
+ "
+ fi
+ if [ "$MODE" = "tls1_2" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256 \
+ TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384 \
+ "
+ fi
+ ;;
+
+ "RSA")
+ ;;
+
+ "PSK")
P_CIPHERS="$P_CIPHERS \
- TLS-PSK-WITH-AES-128-GCM-SHA256 \
- TLS-PSK-WITH-AES-256-GCM-SHA384 \
- TLS-DHE-PSK-WITH-AES-128-GCM-SHA256 \
- TLS-DHE-PSK-WITH-AES-256-GCM-SHA384 \
- TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256 \
- TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384 \
- TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256 \
- TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384 \
- TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256 \
- TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384 \
- TLS-RSA-PSK-WITH-AES-256-GCM-SHA384 \
- TLS-RSA-PSK-WITH-AES-128-GCM-SHA256 \
- TLS-RSA-WITH-NULL-SHA256 \
+ TLS-PSK-WITH-NULL-SHA \
+ TLS-DHE-PSK-WITH-RC4-128-SHA \
+ TLS-DHE-PSK-WITH-NULL-SHA \
+ TLS-RSA-PSK-WITH-RC4-128-SHA \
"
- fi
+ if [ "$MODE" != "ssl3" ];
+ then
+ P_CIPHERS="$P_CIPHERS \
+ TLS-ECDHE-PSK-WITH-RC4-128-SHA \
+ TLS-ECDHE-PSK-WITH-NULL-SHA \
+ "
+ fi
+ ;;
+ esac
+}
-esac
+setup_arguments()
+{
+ case $MODE in
+ "ssl3")
+ G_PRIO_MODE="+VERS-SSL3.0"
+ ;;
+ "tls1")
+ G_PRIO_MODE="+VERS-TLS1.0"
+ ;;
+ "tls1_1")
+ G_PRIO_MODE="+VERS-TLS1.1"
+ ;;
+ "tls1_2")
+ G_PRIO_MODE="+VERS-TLS1.2"
+ ;;
+ *)
+ echo "error: invalid mode: $MODE" >&2
+ exit 1;
+ esac
-# Filter ciphersuites
-if [ "X" != "X$FILTER" ];
-then
- O_CIPHERS=$( filter "$O_CIPHERS" "$FILTER" )
- P_CIPHERS=$( filter "$P_CIPHERS" "$FILTER" )
-fi
+ P_SERVER_ARGS="server_addr=0.0.0.0 force_version=$MODE"
+ O_SERVER_ARGS="-www -cipher NULL,ALL -$MODE"
+ G_SERVER_ARGS="-p 4433 --http"
+ G_SERVER_PRIO="EXPORT:+NULL:+PSK:+DHE-PSK:+ECDHE-PSK:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
-for i in $P_CIPHERS;
-do
- let "tests++"
- log "../programs/ssl/ssl_client2 force_ciphersuite=$i force_version=$MODE $P_CLIENT_ARGS"
- RESULT="$( ../programs/ssl/ssl_client2 force_ciphersuite=$i force_version=$MODE $P_CLIENT_ARGS )"
- EXIT=$?
- echo -n "PolarSSL Server - PolarSSL Client - $i : $EXIT - "
- if [ "$EXIT" = "2" ];
+ P_CLIENT_ARGS="force_version=$MODE"
+ O_CLIENT_ARGS="-$MODE"
+ G_CLIENT_ARGS="-p 4433 --debug 3"
+ G_CLIENT_PRIO="NONE:$G_PRIO_MODE:+COMP-NULL:+CURVE-ALL:+SIGN-ALL"
+
+ if [ "X$VERIFY" = "XYES" ];
then
- echo Ciphersuite not supported in client
- let "skipped++"
- elif [ "$EXIT" != "0" ];
- then
- echo Failed
- echo "ssl_server2 $P_SERVER_ARGS"
- echo "ssl_client2 force_ciphersuite=$i force_version=$MODE $P_CLIENT_ARGS"
- echo $RESULT
- let "failed++"
+ P_SERVER_ARGS="$P_SERVER_ARGS ca_file=data_files/test-ca_cat12.crt auth_mode=required"
+ O_SERVER_ARGS="$O_SERVER_ARGS -CAfile data_files/test-ca_cat12.crt -Verify 10"
+ G_SERVER_ARGS="$G_SERVER_ARGS --x509cafile data_files/test-ca_cat12.crt --require-client-cert"
+
+ P_CLIENT_ARGS="$P_CLIENT_ARGS ca_file=data_files/test-ca_cat12.crt auth_mode=required"
+ O_CLIENT_ARGS="$O_CLIENT_ARGS -CAfile data_files/test-ca_cat12.crt -verify 10"
+ G_CLIENT_ARGS="$G_CLIENT_ARGS --x509cafile data_files/test-ca_cat12.crt"
else
- echo Success
+ # don't request a client cert at all
+ P_SERVER_ARGS="$P_SERVER_ARGS ca_file=none auth_mode=none"
+ G_SERVER_ARGS="$G_SERVER_ARGS --disable-client-cert"
+
+ # give dummy CA to clients
+ P_CLIENT_ARGS="$P_CLIENT_ARGS ca_file=data_files/cli2.crt auth_mode=optional"
+ O_CLIENT_ARGS="$O_CLIENT_ARGS -CAfile data_files/cli2.crt"
+ G_CLIENT_ARGS="$G_CLIENT_ARGS --x509cafile data_files/cli2.crt --insecure"
+ fi
+
+ case $TYPE in
+ "ECDSA")
+ P_SERVER_ARGS="$P_SERVER_ARGS crt_file=data_files/server5.crt key_file=data_files/server5.key"
+ O_SERVER_ARGS="$O_SERVER_ARGS -cert data_files/server5.crt -key data_files/server5.key"
+ G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server5.crt --x509keyfile data_files/server5.key"
+
+ if [ "X$VERIFY" = "XYES" ]; then
+ P_CLIENT_ARGS="$P_CLIENT_ARGS crt_file=data_files/server6.crt key_file=data_files/server6.key"
+ O_CLIENT_ARGS="$O_CLIENT_ARGS -cert data_files/server6.crt -key data_files/server6.key"
+ G_CLIENT_ARGS="$G_CLIENT_ARGS --x509certfile data_files/server6.crt --x509keyfile data_files/server6.key"
+ else
+ P_CLIENT_ARGS="$P_CLIENT_ARGS crt_file=none key_file=none"
+ fi
+ ;;
+
+ "RSA")
+ P_SERVER_ARGS="$P_SERVER_ARGS crt_file=data_files/server2.crt key_file=data_files/server2.key"
+ O_SERVER_ARGS="$O_SERVER_ARGS -cert data_files/server2.crt -key data_files/server2.key"
+ G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server2.crt --x509keyfile data_files/server2.key"
+
+ if [ "X$VERIFY" = "XYES" ]; then
+ P_CLIENT_ARGS="$P_CLIENT_ARGS crt_file=data_files/server1.crt key_file=data_files/server1.key"
+ O_CLIENT_ARGS="$O_CLIENT_ARGS -cert data_files/server1.crt -key data_files/server1.key"
+ G_CLIENT_ARGS="$G_CLIENT_ARGS --x509certfile data_files/server1.crt --x509keyfile data_files/server1.key"
+ else
+ P_CLIENT_ARGS="$P_CLIENT_ARGS crt_file=none key_file=none"
+ fi
+ ;;
+
+ "PSK")
+ # give RSA-PSK-capable server a RSA cert
+ # (should be a separate type, but harder to close with openssl)
+ P_SERVER_ARGS="$P_SERVER_ARGS psk=6162636465666768696a6b6c6d6e6f70 ca_file=none crt_file=data_files/server2.crt key_file=data_files/server2.key"
+ O_SERVER_ARGS="$O_SERVER_ARGS -psk 6162636465666768696a6b6c6d6e6f70 -nocert"
+ G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server2.crt --x509keyfile data_files/server2.key --pskpasswd data_files/passwd.psk"
+
+ P_CLIENT_ARGS="$P_CLIENT_ARGS psk=6162636465666768696a6b6c6d6e6f70 crt_file=none key_file=none"
+ O_CLIENT_ARGS="$O_CLIENT_ARGS -psk 6162636465666768696a6b6c6d6e6f70"
+ G_CLIENT_ARGS="$G_CLIENT_ARGS --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70"
+ ;;
+ esac
+}
+
+# is_polar <cmd_line>
+is_polar() {
+ echo "$1" | grep 'ssl_server2\|ssl_client2' > /dev/null
+}
+
+# has_mem_err <log_file_name>
+has_mem_err() {
+ if ( grep -F 'All heap blocks were freed -- no leaks are possible' "$1" &&
+ grep -F 'ERROR SUMMARY: 0 errors from 0 contexts' "$1" ) > /dev/null
+ then
+ return 1 # false: does not have errors
+ else
+ return 0 # true: has errors
+ fi
+}
+
+# start_server <name>
+# also saves name and command
+start_server() {
+ case $1 in
+ [Oo]pen*)
+ SERVER_CMD="$OPENSSL_CMD s_server $O_SERVER_ARGS"
+ ;;
+ [Gg]nu*)
+ SERVER_CMD="$GNUTLS_SERV $G_SERVER_ARGS --priority $G_SERVER_PRIO"
+ ;;
+ [Pp]olar*)
+ SERVER_CMD="$P_SRV $P_SERVER_ARGS"
+ if [ "$MEMCHECK" -gt 0 ]; then
+ SERVER_CMD="valgrind --leak-check=full $SERVER_CMD"
+ fi
+ ;;
+ *)
+ echo "error: invalid server name: $1" >&2
+ exit 1
+ ;;
+ esac
+ SERVER_NAME=$1
+
+ log "$SERVER_CMD"
+ echo "$SERVER_CMD" > srv_out
+ $SERVER_CMD >> srv_out 2>&1 &
+ PROCESS_ID=$!
+
+ sleep 1
+}
+
+# terminate the running server (closing it cleanly if it is ours)
+stop_server() {
+ case $SERVER_NAME in
+ [Pp]olar*)
+ # we must force a PSK suite when in PSK mode (otherwise client
+ # auth will fail), so try every entry in $P_CIPHERS in turn (in
+ # case the first one is not implemented in this configuration)
+ for i in $P_CIPHERS; do
+ "$P_CLI" $P_CLIENT_ARGS request_page=SERVERQUIT auth_mode=none \
+ crt_file=data_files/cli2.crt key_file=data_files/cli2.key \
+ force_ciphersuite=$i >/dev/null
+ if [ "$?" == 0 ]; then
+ break
+ fi
+ done
+ ;;
+ *)
+ kill $PROCESS_ID 2>/dev/null
+ esac
+
+ wait $PROCESS_ID 2>/dev/null
+
+ if [ "$MEMCHECK" -gt 0 ]; then
+ if is_polar "$SERVER_CMD" && has_mem_err srv_out; then
+ echo " ! Server had memory errors"
+ let "srvmem++"
+ return
+ fi
+ fi
+
+ rm -f srv_out
+}
+
+# kill the running server (used when killed by signal)
+cleanup() {
+ rm -f srv_out cli_out
+ kill $PROCESS_ID
+ exit 1
+}
+
+# run_client <name> <cipher>
+run_client() {
+ # announce what we're going to do
+ let "tests++"
+ VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
+ TITLE="${1:0:1}->${SERVER_NAME:0:1} $MODE,$VERIF $2 "
+ echo -n "$TITLE"
+ LEN=`echo "$TITLE" | wc -c`
+ LEN=`echo 72 - $LEN | bc`
+ for i in `seq 1 $LEN`; do echo -n '.'; done; echo -n ' '
+
+ # run the command and interpret result
+ case $1 in
+ [Oo]pen*)
+ CLIENT_CMD="$OPENSSL_CMD s_client $O_CLIENT_ARGS -cipher $2"
+ log "$CLIENT_CMD"
+ echo "$CLIENT_CMD" > cli_out
+ ( echo -e 'GET HTTP/1.0'; echo; ) | $CLIENT_CMD >> cli_out 2>&1
+ EXIT=$?
+
+ if [ "$EXIT" == "0" ]; then
+ RESULT=0
+ else
+ if grep 'Cipher is (NONE)' cli_out >/dev/null; then
+ RESULT=1
+ else
+ RESULT=2
+ fi
+ fi
+ ;;
+
+ [Gg]nu*)
+ CLIENT_CMD="$GNUTLS_CLI $G_CLIENT_ARGS --priority $G_PRIO_MODE:$2 localhost"
+ log "$CLIENT_CMD"
+ echo "$CLIENT_CMD" > cli_out
+ ( echo -e 'GET HTTP/1.0'; echo; ) | $CLIENT_CMD >> cli_out 2>&1
+ EXIT=$?
+
+ if [ "$EXIT" == "0" ]; then
+ RESULT=0
+ else
+ RESULT=2
+ # interpret early failure, with a handshake_failure alert
+ # before the server hello, as "no ciphersuite in common"
+ if grep -F 'Received alert [40]: Handshake failed' cli_out; then
+ if grep -i 'SERVER HELLO .* was received' cli_out; then :
+ else
+ RESULT=1
+ fi
+ fi >/dev/null
+ fi
+ ;;
+
+ [Pp]olar*)
+ CLIENT_CMD="$P_CLI $P_CLIENT_ARGS force_ciphersuite=$2"
+ if [ "$MEMCHECK" -gt 0 ]; then
+ CLIENT_CMD="valgrind --leak-check=full $CLIENT_CMD"
+ fi
+ log "$CLIENT_CMD"
+ echo "$CLIENT_CMD" > cli_out
+ $CLIENT_CMD >> cli_out 2>&1
+ EXIT=$?
+
+ case $EXIT in
+ "0") RESULT=0 ;;
+ "2") RESULT=1 ;;
+ *) RESULT=2 ;;
+ esac
+
+ if [ "$MEMCHECK" -gt 0 ]; then
+ if is_polar "$CLIENT_CMD" && has_mem_err cli_out; then
+ RESULT=2
+ fi
+ fi
+
+ ;;
+
+ *)
+ echo "error: invalid client name: $1" >&2
+ exit 1
+ ;;
+ esac
+
+ # report and count result
+ case $RESULT in
+ "0")
+ echo PASS
+ ;;
+ "1")
+ echo SKIP
+ let "skipped++"
+ ;;
+ "2")
+ echo FAIL
+ echo " ! $SERVER_CMD"
+ echo " ! $CLIENT_CMD"
+ cp srv_out c-srv-${tests}.log
+ cp cli_out c-cli-${tests}.log
+ echo " ! outputs saved to c-srv-${tests}.log, c-cli-${tests}.log"
+ let "failed++"
+ ;;
+ esac
+
+ rm -f cli_out
+}
+
+#
+# MAIN
+#
+
+# sanity checks, avoid an avalanche of errors
+if [ ! -x "$P_SRV" ]; then
+ echo "Command '$P_SRV' is not an executable file"
+ exit 1
+fi
+if [ ! -x "$P_CLI" ]; then
+ echo "Command '$P_CLI' is not an executable file"
+ exit 1
+fi
+for CMD in $OPENSSL_CMD $GNUTLS_CLI $GNUTLS_SERV; do
+ if which "$CMD" >/dev/null 2>&1; then :; else
+ echo "Command '$CMD' not found"
+ exit 1
fi
done
-kill $PROCESS_ID 2>/dev/null
-wait $PROCESS_ID 2>/dev/null
-done
-done
+get_options "$@"
+
+killall -q gnutls-serv openssl ssl_server ssl_server2
+trap cleanup INT TERM HUP
+
+for VERIFY in $VERIFIES; do
+ for MODE in $MODES; do
+ for TYPE in $TYPES; do
+ for PEER in $PEERS; do
+
+ setup_arguments
+
+ case "$PEER" in
+
+ [Oo]pen*)
+
+ reset_ciphersuites
+ add_openssl_ciphersuites
+ filter_ciphersuites
+
+ if [ "X" != "X$P_CIPHERS" ]; then
+ start_server "OpenSSL"
+ for i in $P_CIPHERS; do
+ run_client PolarSSL $i
+ done
+ stop_server
+ fi
+
+ if [ "X" != "X$O_CIPHERS" ]; then
+ start_server "PolarSSL"
+ for i in $O_CIPHERS; do
+ run_client OpenSSL $i
+ done
+ stop_server
+ fi
+
+ ;;
+
+ [Gg]nu*)
+
+ reset_ciphersuites
+ add_gnutls_ciphersuites
+ filter_ciphersuites
+
+ if [ "X" != "X$P_CIPHERS" ]; then
+ start_server "GnuTLS"
+ for i in $P_CIPHERS; do
+ run_client PolarSSL $i
+ done
+ stop_server
+ fi
+
+ if [ "X" != "X$G_CIPHERS" ]; then
+ start_server "PolarSSL"
+ for i in $G_CIPHERS; do
+ run_client GnuTLS $i
+ done
+ stop_server
+ fi
+
+ ;;
+
+ [Pp]olar*)
+
+ reset_ciphersuites
+ add_openssl_ciphersuites
+ add_gnutls_ciphersuites
+ add_polarssl_ciphersuites
+ filter_ciphersuites
+
+ if [ "X" != "X$P_CIPHERS" ]; then
+ start_server "PolarSSL"
+ for i in $P_CIPHERS; do
+ run_client PolarSSL $i
+ done
+ stop_server
+ fi
+
+ ;;
+
+ esac
+
+ done
+ done
+ done
done
-echo ""
-echo "-------------------------------------------------------------------------"
-echo ""
+echo "------------------------------------------------------------------------"
-if (( failed != 0 ));
+if (( failed != 0 && srvmem != 0 ));
then
echo -n "FAILED"
else
echo -n "PASSED"
fi
-let "passed = tests - failed"
-echo " ($passed / $tests tests ($skipped skipped))"
+if [ "$MEMCHECK" -gt 0 ]; then
+ MEMREPORT=", $srvmem server memory errors"
+else
+ MEMREPORT=""
+fi
+let "passed = tests - failed"
+echo " ($passed / $tests tests ($skipped skipped$MEMREPORT))"
+
+let "failed += srvmem"
exit $failed
diff --git a/tests/data_files/passwd.psk b/tests/data_files/passwd.psk
new file mode 100644
index 0000000..17fee37
--- /dev/null
+++ b/tests/data_files/passwd.psk
@@ -0,0 +1 @@
+Client_identity:6162636465666768696a6b6c6d6e6f70
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
new file mode 100755
index 0000000..51e2e0b
--- /dev/null
+++ b/tests/ssl-opt.sh
@@ -0,0 +1,887 @@
+#!/bin/sh
+
+# Test various options that are not covered by compat.sh
+#
+# Here the goal is not to cover every ciphersuite/version, but
+# rather specific options (max fragment length, truncated hmac, etc)
+# or procedures (session resumption from cache or ticket, renego, etc).
+#
+# Assumes all options are compiled in.
+
+set -u
+
+# default values, can be overriden by the environment
+: ${P_SRV:=../programs/ssl/ssl_server2}
+: ${P_CLI:=../programs/ssl/ssl_client2}
+: ${OPENSSL_CMD:=openssl} # OPENSSL would conflict with the build system
+
+O_SRV="$OPENSSL_CMD s_server -www -cert data_files/server5.crt -key data_files/server5.key"
+O_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_CMD s_client"
+
+TESTS=0
+FAILS=0
+
+MEMCHECK=0
+FILTER='.*'
+EXCLUDE='SSLv2' # disabled by default, needs OpenSSL compiled with SSLv2
+
+print_usage() {
+ echo "Usage: $0 [options]"
+ echo -e " -h|--help\tPrint this help."
+ echo -e " -m|--memcheck\tCheck memory leaks and errors."
+ echo -e " -f|--filter\tOnly matching tests are executed (default: '$FILTER')"
+ echo -e " -e|--exclude\tMatching tests are excluded (default: '$EXCLUDE')"
+}
+
+get_options() {
+ while [ $# -gt 0 ]; do
+ case "$1" in
+ -f|--filter)
+ shift; FILTER=$1
+ ;;
+ -e|--exclude)
+ shift; EXCLUDE=$1
+ ;;
+ -m|--memcheck)
+ MEMCHECK=1
+ ;;
+ -h|--help)
+ print_usage
+ exit 0
+ ;;
+ *)
+ echo "Unkown argument: '$1'"
+ print_usage
+ exit 1
+ ;;
+ esac
+ shift
+ done
+}
+
+# print_name <name>
+print_name() {
+ echo -n "$1 "
+ LEN=`echo "$1" | wc -c`
+ LEN=`echo 72 - $LEN | bc`
+ for i in `seq 1 $LEN`; do echo -n '.'; done
+ echo -n ' '
+
+ TESTS=`echo $TESTS + 1 | bc`
+}
+
+# fail <message>
+fail() {
+ echo "FAIL"
+ echo " ! $1"
+
+ cp srv_out o-srv-${TESTS}.log
+ cp cli_out o-cli-${TESTS}.log
+ echo " ! outputs saved to o-srv-${TESTS}.log and o-cli-${TESTS}.log"
+
+ FAILS=`echo $FAILS + 1 | bc`
+}
+
+# is_polar <cmd_line>
+is_polar() {
+ echo "$1" | grep 'ssl_server2\|ssl_client2' > /dev/null
+}
+
+# has_mem_err <log_file_name>
+has_mem_err() {
+ if ( grep -F 'All heap blocks were freed -- no leaks are possible' "$1" &&
+ grep -F 'ERROR SUMMARY: 0 errors from 0 contexts' "$1" ) > /dev/null
+ then
+ return 1 # false: does not have errors
+ else
+ return 0 # true: has errors
+ fi
+}
+
+# Usage: run_test name srv_cmd cli_cmd cli_exit [option [...]]
+# Options: -s pattern pattern that must be present in server output
+# -c pattern pattern that must be present in client output
+# -S pattern pattern that must be absent in server output
+# -C pattern pattern that must be absent in client output
+run_test() {
+ NAME="$1"
+ SRV_CMD="$2"
+ CLI_CMD="$3"
+ CLI_EXPECT="$4"
+ shift 4
+
+ if echo "$NAME" | grep "$FILTER" | grep -v "$EXCLUDE" >/dev/null; then :
+ else
+ return
+ fi
+
+ print_name "$NAME"
+
+ # prepend valgrind to our commands if active
+ if [ "$MEMCHECK" -gt 0 ]; then
+ if is_polar "$SRV_CMD"; then
+ SRV_CMD="valgrind --leak-check=full $SRV_CMD"
+ fi
+ if is_polar "$CLI_CMD"; then
+ CLI_CMD="valgrind --leak-check=full $CLI_CMD"
+ fi
+ fi
+
+ # run the commands
+ echo "$SRV_CMD" > srv_out
+ $SHELL -c "$SRV_CMD" >> srv_out 2>&1 &
+ SRV_PID=$!
+ sleep 1
+ echo "$CLI_CMD" > cli_out
+ $SHELL -c "$CLI_CMD" >> cli_out 2>&1
+ CLI_EXIT=$?
+ if is_polar "$SRV_CMD"; then
+ "$P_CLI" request_page=SERVERQUIT tickets=0 auth_mode=none \
+ crt_file=data_files/cli2.crt key_file=data_files/cli2.key \
+ >/dev/null
+ else
+ kill $SRV_PID
+ fi
+ wait $SRV_PID
+
+ # check if the client and server went at least to the handshake stage
+ # (usefull to avoid tests with only negative assertions and non-zero
+ # expected client exit to incorrectly succeed in case of catastrophic
+ # failure)
+ if is_polar "$SRV_CMD"; then
+ if grep "Performing the SSL/TLS handshake" srv_out >/dev/null; then :;
+ else
+ fail "server failed to start"
+ return
+ fi
+ fi
+ if is_polar "$CLI_CMD"; then
+ if grep "Performing the SSL/TLS handshake" cli_out >/dev/null; then :;
+ else
+ fail "client failed to start"
+ return
+ fi
+ fi
+
+ # check server exit code
+ if [ $? != 0 ]; then
+ fail "server fail"
+ return
+ fi
+
+ # check client exit code
+ if [ \( "$CLI_EXPECT" = 0 -a "$CLI_EXIT" != 0 \) -o \
+ \( "$CLI_EXPECT" != 0 -a "$CLI_EXIT" = 0 \) ]
+ then
+ fail "bad client exit code"
+ return
+ fi
+
+ # check other assertions
+ while [ $# -gt 0 ]
+ do
+ case $1 in
+ "-s")
+ if grep "$2" srv_out >/dev/null; then :; else
+ fail "-s $2"
+ return
+ fi
+ ;;
+
+ "-c")
+ if grep "$2" cli_out >/dev/null; then :; else
+ fail "-c $2"
+ return
+ fi
+ ;;
+
+ "-S")
+ if grep "$2" srv_out >/dev/null; then
+ fail "-S $2"
+ return
+ fi
+ ;;
+
+ "-C")
+ if grep "$2" cli_out >/dev/null; then
+ fail "-C $2"
+ return
+ fi
+ ;;
+
+ *)
+ echo "Unkown test: $1" >&2
+ exit 1
+ esac
+ shift 2
+ done
+
+ # check valgrind's results
+ if [ "$MEMCHECK" -gt 0 ]; then
+ if is_polar "$SRV_CMD" && has_mem_err srv_out; then
+ fail "Server has memory errors"
+ return
+ fi
+ if is_polar "$CLI_CMD" && has_mem_err cli_out; then
+ fail "Client has memory errors"
+ return
+ fi
+ fi
+
+ # if we're here, everything is ok
+ echo "PASS"
+ rm -f srv_out cli_out
+}
+
+cleanup() {
+ rm -f cli_out srv_out sess
+ kill $SRV_PID
+ exit 1
+}
+
+#
+# MAIN
+#
+
+# sanity checks, avoid an avalanche of errors
+if [ ! -x "$P_SRV" ]; then
+ echo "Command '$P_SRV' is not an executable file"
+ exit 1
+fi
+if [ ! -x "$P_CLI" ]; then
+ echo "Command '$P_CLI' is not an executable file"
+ exit 1
+fi
+if which $OPENSSL_CMD >/dev/null 2>&1; then :; else
+ echo "Command '$OPENSSL_CMD' not found"
+ exit 1
+fi
+
+get_options "$@"
+
+killall -q openssl ssl_server ssl_server2
+trap cleanup INT TERM HUP
+
+# Test for SSLv2 ClientHello
+
+run_test "SSLv2 ClientHello #0 (reference)" \
+ "$P_SRV debug_level=3" \
+ "$O_CLI -no_ssl2" \
+ 0 \
+ -S "parse client hello v2" \
+ -S "ssl_handshake returned"
+
+# Adding a SSL2-only suite makes OpenSSL client send SSLv2 ClientHello
+run_test "SSLv2 ClientHello #1 (actual test)" \
+ "$P_SRV debug_level=3" \
+ "$O_CLI -cipher 'DES-CBC-MD5:ALL'" \
+ 0 \
+ -s "parse client hello v2" \
+ -S "ssl_handshake returned"
+
+# Tests for Truncated HMAC extension
+
+run_test "Truncated HMAC #0" \
+ "$P_SRV debug_level=5" \
+ "$P_CLI trunc_hmac=0 force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
+ 0 \
+ -s "dumping 'computed mac' (20 bytes)"
+
+run_test "Truncated HMAC #1" \
+ "$P_SRV debug_level=5" \
+ "$P_CLI 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 #1 (basic)" \
+ "$P_SRV debug_level=4 tickets=1" \
+ "$P_CLI debug_level=4 tickets=1 reconnect=1" \
+ 0 \
+ -c "client hello, adding session ticket extension" \
+ -s "found session ticket extension" \
+ -s "server hello, adding session ticket extension" \
+ -c "found session_ticket extension" \
+ -c "parse new session ticket" \
+ -S "session successfully restored from cache" \
+ -s "session successfully restored from ticket" \
+ -s "a session has been resumed" \
+ -c "a session has been resumed"
+
+run_test "Session resume using tickets #2 (cache disabled)" \
+ "$P_SRV debug_level=4 tickets=1 cache_max=0" \
+ "$P_CLI debug_level=4 tickets=1 reconnect=1" \
+ 0 \
+ -c "client hello, adding session ticket extension" \
+ -s "found session ticket extension" \
+ -s "server hello, adding session ticket extension" \
+ -c "found session_ticket extension" \
+ -c "parse new session ticket" \
+ -S "session successfully restored from cache" \
+ -s "session successfully restored from ticket" \
+ -s "a session has been resumed" \
+ -c "a session has been resumed"
+
+run_test "Session resume using tickets #3 (timeout)" \
+ "$P_SRV debug_level=4 tickets=1 cache_max=0 ticket_timeout=1" \
+ "$P_CLI debug_level=4 tickets=1 reconnect=1 reco_delay=2" \
+ 0 \
+ -c "client hello, adding session ticket extension" \
+ -s "found session ticket extension" \
+ -s "server hello, adding session ticket extension" \
+ -c "found session_ticket extension" \
+ -c "parse new session ticket" \
+ -S "session successfully restored from cache" \
+ -S "session successfully restored from ticket" \
+ -S "a session has been resumed" \
+ -C "a session has been resumed"
+
+run_test "Session resume using tickets #4 (openssl server)" \
+ "$O_SRV" \
+ "$P_CLI debug_level=4 tickets=1 reconnect=1" \
+ 0 \
+ -c "client hello, adding session ticket extension" \
+ -c "found session_ticket extension" \
+ -c "parse new session ticket" \
+ -c "a session has been resumed"
+
+run_test "Session resume using tickets #5 (openssl client)" \
+ "$P_SRV debug_level=4 tickets=1" \
+ "($O_CLI -sess_out sess; $O_CLI -sess_in sess; rm -f sess)" \
+ 0 \
+ -s "found session ticket extension" \
+ -s "server hello, adding session ticket extension" \
+ -S "session successfully restored from cache" \
+ -s "session successfully restored from ticket" \
+ -s "a session has been resumed"
+
+# Tests for Session Resume based on session-ID and cache
+
+run_test "Session resume using cache #1 (tickets enabled on client)" \
+ "$P_SRV debug_level=4 tickets=0" \
+ "$P_CLI debug_level=4 tickets=1 reconnect=1" \
+ 0 \
+ -c "client hello, adding session ticket extension" \
+ -s "found session ticket extension" \
+ -S "server hello, adding session ticket extension" \
+ -C "found session_ticket extension" \
+ -C "parse new session ticket" \
+ -s "session successfully restored from cache" \
+ -S "session successfully restored from ticket" \
+ -s "a session has been resumed" \
+ -c "a session has been resumed"
+
+run_test "Session resume using cache #2 (tickets enabled on server)" \
+ "$P_SRV debug_level=4 tickets=1" \
+ "$P_CLI debug_level=4 tickets=0 reconnect=1" \
+ 0 \
+ -C "client hello, adding session ticket extension" \
+ -S "found session ticket extension" \
+ -S "server hello, adding session ticket extension" \
+ -C "found session_ticket extension" \
+ -C "parse new session ticket" \
+ -s "session successfully restored from cache" \
+ -S "session successfully restored from ticket" \
+ -s "a session has been resumed" \
+ -c "a session has been resumed"
+
+run_test "Session resume using cache #3 (cache_max=0)" \
+ "$P_SRV debug_level=4 tickets=0 cache_max=0" \
+ "$P_CLI debug_level=4 tickets=0 reconnect=1" \
+ 0 \
+ -S "session successfully restored from cache" \
+ -S "session successfully restored from ticket" \
+ -S "a session has been resumed" \
+ -C "a session has been resumed"
+
+run_test "Session resume using cache #4 (cache_max=1)" \
+ "$P_SRV debug_level=4 tickets=0 cache_max=1" \
+ "$P_CLI debug_level=4 tickets=0 reconnect=1" \
+ 0 \
+ -s "session successfully restored from cache" \
+ -S "session successfully restored from ticket" \
+ -s "a session has been resumed" \
+ -c "a session has been resumed"
+
+run_test "Session resume using cache #5 (timemout > delay)" \
+ "$P_SRV debug_level=4 tickets=0" \
+ "$P_CLI debug_level=4 tickets=0 reconnect=1 reco_delay=0" \
+ 0 \
+ -s "session successfully restored from cache" \
+ -S "session successfully restored from ticket" \
+ -s "a session has been resumed" \
+ -c "a session has been resumed"
+
+run_test "Session resume using cache #6 (timeout < delay)" \
+ "$P_SRV debug_level=4 tickets=0 cache_timeout=1" \
+ "$P_CLI debug_level=4 tickets=0 reconnect=1 reco_delay=2" \
+ 0 \
+ -S "session successfully restored from cache" \
+ -S "session successfully restored from ticket" \
+ -S "a session has been resumed" \
+ -C "a session has been resumed"
+
+run_test "Session resume using cache #7 (no timeout)" \
+ "$P_SRV debug_level=4 tickets=0 cache_timeout=0" \
+ "$P_CLI debug_level=4 tickets=0 reconnect=1 reco_delay=2" \
+ 0 \
+ -s "session successfully restored from cache" \
+ -S "session successfully restored from ticket" \
+ -s "a session has been resumed" \
+ -c "a session has been resumed"
+
+run_test "Session resume using cache #8 (openssl client)" \
+ "$P_SRV debug_level=4 tickets=0" \
+ "($O_CLI -sess_out sess; $O_CLI -sess_in sess; rm -f sess)" \
+ 0 \
+ -s "found session ticket extension" \
+ -S "server hello, adding session ticket extension" \
+ -s "session successfully restored from cache" \
+ -S "session successfully restored from ticket" \
+ -s "a session has been resumed"
+
+run_test "Session resume using cache #9 (openssl server)" \
+ "$O_SRV" \
+ "$P_CLI debug_level=4 tickets=0 reconnect=1" \
+ 0 \
+ -C "found session_ticket extension" \
+ -C "parse new session ticket" \
+ -c "a session has been resumed"
+
+# Tests for Max Fragment Length extension
+
+run_test "Max fragment length #1" \
+ "$P_SRV debug_level=4" \
+ "$P_CLI debug_level=4" \
+ 0 \
+ -C "client hello, adding max_fragment_length extension" \
+ -S "found max fragment length extension" \
+ -S "server hello, max_fragment_length extension" \
+ -C "found max_fragment_length extension"
+
+run_test "Max fragment length #2" \
+ "$P_SRV debug_level=4" \
+ "$P_CLI debug_level=4 max_frag_len=4096" \
+ 0 \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+run_test "Max fragment length #3" \
+ "$P_SRV debug_level=4 max_frag_len=4096" \
+ "$P_CLI debug_level=4" \
+ 0 \
+ -C "client hello, adding max_fragment_length extension" \
+ -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)" \
+ "$P_SRV debug_level=4" \
+ "$P_CLI 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)" \
+ "$P_SRV debug_level=4" \
+ "$P_CLI 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)" \
+ "$P_SRV debug_level=4 renegotiate=1" \
+ "$P_CLI 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)" \
+ "$P_SRV debug_level=4 renegotiate=1" \
+ "$P_CLI 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)" \
+ "$P_SRV debug_level=4 renegotiation=0" \
+ "$P_CLI 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)" \
+ "$P_SRV debug_level=4 renegotiate=1" \
+ "$P_CLI 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"
+
+# Tests for auth_mode
+
+run_test "Authentication #1 (server badcert, client required)" \
+ "$P_SRV crt_file=data_files/server5-badsign.crt \
+ key_file=data_files/server5.key" \
+ "$P_CLI debug_level=2 auth_mode=required" \
+ 1 \
+ -c "x509_verify_cert() returned" \
+ -c "! self-signed or not signed by a trusted CA" \
+ -c "! ssl_handshake returned" \
+ -c "X509 - Certificate verification failed"
+
+run_test "Authentication #2 (server badcert, client optional)" \
+ "$P_SRV crt_file=data_files/server5-badsign.crt \
+ key_file=data_files/server5.key" \
+ "$P_CLI debug_level=2 auth_mode=optional" \
+ 0 \
+ -c "x509_verify_cert() returned" \
+ -c "! self-signed or not signed by a trusted CA" \
+ -C "! ssl_handshake returned" \
+ -C "X509 - Certificate verification failed"
+
+run_test "Authentication #3 (server badcert, client none)" \
+ "$P_SRV crt_file=data_files/server5-badsign.crt \
+ key_file=data_files/server5.key" \
+ "$P_CLI debug_level=2 auth_mode=none" \
+ 0 \
+ -C "x509_verify_cert() returned" \
+ -C "! self-signed or not signed by a trusted CA" \
+ -C "! ssl_handshake returned" \
+ -C "X509 - Certificate verification failed"
+
+run_test "Authentication #4 (client badcert, server required)" \
+ "$P_SRV debug_level=4 auth_mode=required" \
+ "$P_CLI debug_level=4 crt_file=data_files/server5-badsign.crt \
+ key_file=data_files/server5.key" \
+ 1 \
+ -S "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got a certificate request" \
+ -C "skip write certificate" \
+ -C "skip write certificate verify" \
+ -S "skip parse certificate verify" \
+ -s "x509_verify_cert() returned" \
+ -S "! self-signed or not signed by a trusted CA" \
+ -s "! ssl_handshake returned" \
+ -c "! ssl_handshake returned" \
+ -s "X509 - Certificate verification failed"
+
+run_test "Authentication #5 (client badcert, server optional)" \
+ "$P_SRV debug_level=4 auth_mode=optional" \
+ "$P_CLI debug_level=4 crt_file=data_files/server5-badsign.crt \
+ key_file=data_files/server5.key" \
+ 0 \
+ -S "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got a certificate request" \
+ -C "skip write certificate" \
+ -C "skip write certificate verify" \
+ -S "skip parse certificate verify" \
+ -s "x509_verify_cert() returned" \
+ -s "! self-signed or not signed by a trusted CA" \
+ -S "! ssl_handshake returned" \
+ -C "! ssl_handshake returned" \
+ -S "X509 - Certificate verification failed"
+
+run_test "Authentication #6 (client badcert, server none)" \
+ "$P_SRV debug_level=4 auth_mode=none" \
+ "$P_CLI debug_level=4 crt_file=data_files/server5-badsign.crt \
+ key_file=data_files/server5.key" \
+ 0 \
+ -s "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got no certificate request" \
+ -c "skip write certificate" \
+ -c "skip write certificate verify" \
+ -s "skip parse certificate verify" \
+ -S "x509_verify_cert() returned" \
+ -S "! self-signed or not signed by a trusted CA" \
+ -S "! ssl_handshake returned" \
+ -C "! ssl_handshake returned" \
+ -S "X509 - Certificate verification failed"
+
+run_test "Authentication #7 (client no cert, server optional)" \
+ "$P_SRV debug_level=4 auth_mode=optional" \
+ "$P_CLI debug_level=4 crt_file=none key_file=none" \
+ 0 \
+ -S "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got a certificate request" \
+ -C "skip write certificate$" \
+ -C "got no certificate to send" \
+ -S "SSLv3 client has no certificate" \
+ -c "skip write certificate verify" \
+ -s "skip parse certificate verify" \
+ -s "! no client certificate sent" \
+ -S "! ssl_handshake returned" \
+ -C "! ssl_handshake returned" \
+ -S "X509 - Certificate verification failed"
+
+run_test "Authentication #8 (openssl client no cert, server optional)" \
+ "$P_SRV debug_level=4 auth_mode=optional" \
+ "$O_CLI" \
+ 0 \
+ -S "skip write certificate request" \
+ -s "skip parse certificate verify" \
+ -s "! no client certificate sent" \
+ -S "! ssl_handshake returned" \
+ -S "X509 - Certificate verification failed"
+
+run_test "Authentication #9 (client no cert, openssl server optional)" \
+ "$O_SRV -verify 10" \
+ "$P_CLI debug_level=4 crt_file=none key_file=none" \
+ 0 \
+ -C "skip parse certificate request" \
+ -c "got a certificate request" \
+ -C "skip write certificate$" \
+ -c "skip write certificate verify" \
+ -C "! ssl_handshake returned"
+
+run_test "Authentication #10 (client no cert, ssl3)" \
+ "$P_SRV debug_level=4 auth_mode=optional force_version=ssl3" \
+ "$P_CLI debug_level=4 crt_file=none key_file=none" \
+ 0 \
+ -S "skip write certificate request" \
+ -C "skip parse certificate request" \
+ -c "got a certificate request" \
+ -C "skip write certificate$" \
+ -c "skip write certificate verify" \
+ -c "got no certificate to send" \
+ -s "SSLv3 client has no certificate" \
+ -s "skip parse certificate verify" \
+ -s "! no client certificate sent" \
+ -S "! ssl_handshake returned" \
+ -C "! ssl_handshake returned" \
+ -S "X509 - Certificate verification failed"
+
+# tests for SNI
+
+run_test "SNI #0 (no SNI callback)" \
+ "$P_SRV debug_level=4 server_addr=127.0.0.1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key" \
+ "$P_CLI debug_level=0 server_addr=127.0.0.1 \
+ server_name=localhost" \
+ 0 \
+ -S "parse ServerName extension" \
+ -c "issuer name *: C=NL, O=PolarSSL, CN=Polarssl Test EC CA" \
+ -c "subject name *: C=NL, O=PolarSSL, CN=localhost"
+
+run_test "SNI #1 (matching cert 1)" \
+ "$P_SRV debug_level=4 server_addr=127.0.0.1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni='localhost,data_files/server2.crt,data_files/server2.key,PolarSSL Server 1,data_files/server1.crt,data_files/server1.key'" \
+ "$P_CLI debug_level=0 server_addr=127.0.0.1 \
+ server_name=localhost" \
+ 0 \
+ -s "parse ServerName extension" \
+ -c "issuer name *: C=NL, O=PolarSSL, CN=PolarSSL Test CA" \
+ -c "subject name *: C=NL, O=PolarSSL, CN=localhost"
+
+run_test "SNI #2 (matching cert 2)" \
+ "$P_SRV debug_level=4 server_addr=127.0.0.1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni='localhost,data_files/server2.crt,data_files/server2.key,PolarSSL Server 1,data_files/server1.crt,data_files/server1.key'" \
+ "$P_CLI debug_level=0 server_addr=127.0.0.1 \
+ server_name='PolarSSL Server 1'" \
+ 0 \
+ -s "parse ServerName extension" \
+ -c "issuer name *: C=NL, O=PolarSSL, CN=PolarSSL Test CA" \
+ -c "subject name *: C=NL, O=PolarSSL, CN=PolarSSL Server 1"
+
+run_test "SNI #3 (no matching cert)" \
+ "$P_SRV debug_level=4 server_addr=127.0.0.1 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ sni='localhost,data_files/server2.crt,data_files/server2.key,PolarSSL Server 1,data_files/server1.crt,data_files/server1.key'" \
+ "$P_CLI debug_level=0 server_addr=127.0.0.1 \
+ server_name='PolarSSL Server 2'" \
+ 1 \
+ -s "parse ServerName extension" \
+ -s "ssl_sni_wrapper() returned" \
+ -s "ssl_handshake returned" \
+ -c "ssl_handshake returned" \
+ -c "SSL - A fatal alert message was received from our peer"
+
+# Tests for non-blocking I/O: exercise a variety of handshake flows
+
+run_test "Non-blocking I/O #1 (basic handshake)" \
+ "$P_SRV nbio=2 tickets=0 auth_mode=none" \
+ "$P_CLI nbio=2 tickets=0" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -c "Read from server: .* bytes read"
+
+run_test "Non-blocking I/O #2 (client auth)" \
+ "$P_SRV nbio=2 tickets=0 auth_mode=required" \
+ "$P_CLI nbio=2 tickets=0" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -c "Read from server: .* bytes read"
+
+run_test "Non-blocking I/O #3 (ticket)" \
+ "$P_SRV nbio=2 tickets=1 auth_mode=none" \
+ "$P_CLI nbio=2 tickets=1" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -c "Read from server: .* bytes read"
+
+run_test "Non-blocking I/O #4 (ticket + client auth)" \
+ "$P_SRV nbio=2 tickets=1 auth_mode=required" \
+ "$P_CLI nbio=2 tickets=1" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -c "Read from server: .* bytes read"
+
+run_test "Non-blocking I/O #5 (ticket + client auth + resume)" \
+ "$P_SRV nbio=2 tickets=1 auth_mode=required" \
+ "$P_CLI nbio=2 tickets=1 reconnect=1" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -c "Read from server: .* bytes read"
+
+run_test "Non-blocking I/O #6 (ticket + resume)" \
+ "$P_SRV nbio=2 tickets=1 auth_mode=none" \
+ "$P_CLI nbio=2 tickets=1 reconnect=1" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -c "Read from server: .* bytes read"
+
+run_test "Non-blocking I/O #7 (session-id resume)" \
+ "$P_SRV nbio=2 tickets=0 auth_mode=none" \
+ "$P_CLI nbio=2 tickets=0 reconnect=1" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -c "Read from server: .* bytes read"
+
+run_test "Version check #1 (all -> 1.2)" \
+ "$P_SRV" \
+ "$P_CLI" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -s "Protocol is TLSv1.2" \
+ -c "Protocol is TLSv1.2"
+
+run_test "Version check #2 (cli max 1.1 -> 1.1)" \
+ "$P_SRV" \
+ "$P_CLI max_version=tls1_1" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -s "Protocol is TLSv1.1" \
+ -c "Protocol is TLSv1.1"
+
+run_test "Version check #3 (srv max 1.1 -> 1.1)" \
+ "$P_SRV max_version=tls1_1" \
+ "$P_CLI" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -s "Protocol is TLSv1.1" \
+ -c "Protocol is TLSv1.1"
+
+run_test "Version check #4 (cli+srv max 1.1 -> 1.1)" \
+ "$P_SRV max_version=tls1_1" \
+ "$P_CLI max_version=tls1_1" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -s "Protocol is TLSv1.1" \
+ -c "Protocol is TLSv1.1"
+
+run_test "Version check #5 (cli max 1.1, srv min 1.1 -> 1.1)" \
+ "$P_SRV min_version=tls1_1" \
+ "$P_CLI max_version=tls1_1" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -s "Protocol is TLSv1.1" \
+ -c "Protocol is TLSv1.1"
+
+run_test "Version check #6 (cli min 1.1, srv max 1.1 -> 1.1)" \
+ "$P_SRV max_version=tls1_1" \
+ "$P_CLI min_version=tls1_1" \
+ 0 \
+ -S "ssl_handshake returned" \
+ -C "ssl_handshake returned" \
+ -s "Protocol is TLSv1.1" \
+ -c "Protocol is TLSv1.1"
+
+run_test "Version check #7 (cli min 1.2, srv max 1.1 -> fail)" \
+ "$P_SRV max_version=tls1_1" \
+ "$P_CLI min_version=tls1_2" \
+ 1 \
+ -s "ssl_handshake returned" \
+ -c "ssl_handshake returned" \
+ -c "SSL - Handshake protocol not within min/max boundaries"
+
+run_test "Version check #8 (srv min 1.2, cli max 1.1 -> fail)" \
+ "$P_SRV min_version=tls1_2" \
+ "$P_CLI max_version=tls1_1" \
+ 1 \
+ -s "ssl_handshake returned" \
+ -c "ssl_handshake returned" \
+ -s "SSL - Handshake protocol not within min/max boundaries"
+
+# Final report
+
+echo "------------------------------------------------------------------------"
+
+if [ $FAILS = 0 ]; then
+ echo -n "PASSED"
+else
+ echo -n "FAILED"
+fi
+PASSES=`echo $TESTS - $FAILS | bc`
+echo " ($PASSES / $TESTS tests)"
+
+exit $FAILS