Merged massive SSL Testing improvements
This commit is contained in:
commit
a4b0343edf
3
.gitignore
vendored
3
.gitignore
vendored
@ -4,3 +4,6 @@ CTestTestfile.cmake
|
||||
cmake_install.cmake
|
||||
Testing
|
||||
Coverage
|
||||
*.gcno
|
||||
*.gcda
|
||||
library/polarssl.info
|
||||
|
@ -76,10 +76,22 @@ ADD_CUSTOM_TARGET(test-ref-config
|
||||
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
|
||||
|
10
ChangeLog
10
ChangeLog
@ -3,7 +3,7 @@ PolarSSL ChangeLog (Sorted per branch, date)
|
||||
= 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 @@ Bugfix
|
||||
* 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
|
||||
|
17
Makefile
17
Makefile
@ -56,10 +56,23 @@ check: lib
|
||||
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
|
||||
|
@ -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"
|
||||
|
@ -1118,7 +1118,7 @@ int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len,
|
||||
*
|
||||
* 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,
|
||||
|
@ -106,7 +106,7 @@ int ssl_cache_set( void *data, const ssl_session *session );
|
||||
* 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 */
|
||||
|
@ -169,55 +169,56 @@ const char test_ca_pwd_rsa[] = "PolarSSLTest";
|
||||
|
||||
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"
|
||||
"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\r\n"
|
||||
"-----END RSA PRIVATE KEY-----\r\n";
|
||||
|
||||
|
||||
const char test_cli_crt_rsa[] =
|
||||
"-----BEGIN CERTIFICATE-----\r\n"
|
||||
"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
|
||||
|
@ -186,17 +186,15 @@ int ssl_cache_set( void *data, const ssl_session *session )
|
||||
/*
|
||||
* 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 @@ int ssl_cache_set( void *data, const ssl_session *session )
|
||||
|
||||
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 )
|
||||
{
|
||||
@ -251,6 +243,15 @@ int ssl_cache_set( void *data, const ssl_session *session )
|
||||
memcpy( &cur->session, session, sizeof( ssl_session ) );
|
||||
|
||||
#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
|
||||
*/
|
||||
|
@ -310,7 +310,7 @@ static int ssl_parse_ticket( ssl_context *ssl,
|
||||
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 @@ static int ssl_parse_ticket( ssl_context *ssl,
|
||||
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 @@ static int ssl_parse_servername_ext( ssl_context *ssl,
|
||||
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 @@ static int ssl_parse_servername_ext( ssl_context *ssl,
|
||||
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 @@ static int ssl_write_server_hello( ssl_context *ssl )
|
||||
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 @@ static int ssl_write_server_key_exchange( ssl_context *ssl )
|
||||
{
|
||||
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 @@ static int ssl_write_new_session_ticket( ssl_context *ssl )
|
||||
|
||||
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 );
|
||||
|
@ -302,7 +302,7 @@ void m_sleep( int milliseconds )
|
||||
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 );
|
||||
}
|
||||
|
@ -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 @@ struct options
|
||||
int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
|
||||
int renegotiation; /* enable / disable renegotiation */
|
||||
int allow_legacy; /* allow legacy renegotiation */
|
||||
int renegotiate; /* attempt renegotiation? */
|
||||
int min_version; /* minimum protocol version accepted */
|
||||
int max_version; /* maximum protocol version accepted */
|
||||
int auth_mode; /* verify mode for connection */
|
||||
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 @@ static void my_debug( void *ctx, int level, const char *str )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
|
||||
#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 @@ static int my_verify( void *data, x509_crt *crt, int depth, int *flags )
|
||||
" 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 @@ int main( int argc, char *argv[] )
|
||||
}
|
||||
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
|
||||
opt.renegotiation = DFL_RENEGOTIATION;
|
||||
opt.allow_legacy = DFL_ALLOW_LEGACY;
|
||||
opt.renegotiate = DFL_RENEGOTIATE;
|
||||
opt.min_version = DFL_MIN_VERSION;
|
||||
opt.max_version = DFL_MAX_VERSION;
|
||||
opt.auth_mode = DFL_AUTH_MODE;
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
if( opt.allow_legacy < 0 || opt.allow_legacy > 1 )
|
||||
goto usage;
|
||||
}
|
||||
else if( strcmp( p, "renegotiate" ) == 0 )
|
||||
{
|
||||
opt.renegotiate = atoi( q );
|
||||
if( opt.renegotiate < 0 || opt.renegotiate > 1 )
|
||||
goto usage;
|
||||
}
|
||||
else if( strcmp( p, "reconnect" ) == 0 )
|
||||
{
|
||||
opt.reconnect = atoi( q );
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
|
||||
#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 @@ int main( int argc, char *argv[] )
|
||||
|
||||
#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 @@ int main( int argc, char *argv[] )
|
||||
|
||||
#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 @@ int main( int argc, char *argv[] )
|
||||
/*
|
||||
* 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 @@ int main( int argc, char *argv[] )
|
||||
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
}
|
||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||
|
||||
#ifdef TEST_RENEGO
|
||||
/*
|
||||
* Perform renegotiation (this must be done when the server is waiting
|
||||
* for input from our side).
|
||||
*/
|
||||
printf( " . Performing renegotiation..." );
|
||||
fflush( stdout );
|
||||
while( ( ret = ssl_renegotiate( &ssl ) ) != 0 )
|
||||
if( opt.renegotiate )
|
||||
{
|
||||
if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
|
||||
/*
|
||||
* Perform renegotiation (this must be done when the server is waiting
|
||||
* for input from our side).
|
||||
*/
|
||||
printf( " . Performing renegotiation..." );
|
||||
fflush( stdout );
|
||||
while( ( ret = ssl_renegotiate( &ssl ) ) != 0 )
|
||||
{
|
||||
printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret );
|
||||
goto exit;
|
||||
if( ret != POLARSSL_ERR_NET_WANT_READ &&
|
||||
ret != POLARSSL_ERR_NET_WANT_WRITE )
|
||||
{
|
||||
printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
printf( " ok\n" );
|
||||
}
|
||||
printf( " ok\n" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 6. Write the GET request
|
||||
@ -829,7 +955,10 @@ send_request:
|
||||
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 @@ send_request:
|
||||
{
|
||||
--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 @@ exit:
|
||||
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
|
||||
|
||||
|
@ -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 @@ struct options
|
||||
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 @@ struct options
|
||||
int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
|
||||
int renegotiation; /* enable / disable renegotiation */
|
||||
int allow_legacy; /* allow legacy renegotiation */
|
||||
int renegotiate; /* attempt renegotiation? */
|
||||
int min_version; /* minimum protocol version accepted */
|
||||
int max_version; /* maximum protocol version accepted */
|
||||
int auth_mode; /* verify mode for connection */
|
||||
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 @@ static void my_debug( void *ctx, int level, const char *str )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 @@ static void my_debug( void *ctx, int level, const char *str )
|
||||
|
||||
#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 @@ static void my_debug( void *ctx, int level, const char *str )
|
||||
" 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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
#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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
|
||||
opt.renegotiation = DFL_RENEGOTIATION;
|
||||
opt.allow_legacy = DFL_ALLOW_LEGACY;
|
||||
opt.renegotiate = DFL_RENEGOTIATE;
|
||||
opt.min_version = DFL_MIN_VERSION;
|
||||
opt.max_version = DFL_MAX_VERSION;
|
||||
opt.auth_mode = DFL_AUTH_MODE;
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
if( opt.allow_legacy < 0 || opt.allow_legacy > 1 )
|
||||
goto usage;
|
||||
}
|
||||
else if( strcmp( p, "renegotiate" ) == 0 )
|
||||
{
|
||||
opt.renegotiate = atoi( q );
|
||||
if( opt.renegotiate < 0 || opt.renegotiate > 1 )
|
||||
goto usage;
|
||||
}
|
||||
else if( strcmp( p, "min_version" ) == 0 )
|
||||
{
|
||||
if( strcmp( q, "ssl3" ) == 0 )
|
||||
@ -446,6 +659,28 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
|
||||
#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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ int main( int argc, char *argv[] )
|
||||
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 @@ reset:
|
||||
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 @@ reset:
|
||||
buf[written] = '\0';
|
||||
printf( " %d bytes written in %d fragments\n\n%s\n", written, frags, (char *) buf );
|
||||
|
||||
#ifdef TEST_RENEGO
|
||||
/*
|
||||
* Request renegotiation (this must be done when the client is still
|
||||
* waiting for input from our side).
|
||||
*/
|
||||
printf( " . Requestion renegotiation..." );
|
||||
fflush( stdout );
|
||||
while( ( ret = ssl_renegotiate( &ssl ) ) != 0 )
|
||||
if( opt.renegotiate )
|
||||
{
|
||||
if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
|
||||
/*
|
||||
* Request renegotiation (this must be done when the client is still
|
||||
* waiting for input from our side).
|
||||
*/
|
||||
printf( " . Requestion renegotiation..." );
|
||||
fflush( stdout );
|
||||
while( ( ret = ssl_renegotiate( &ssl ) ) != 0 )
|
||||
{
|
||||
printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Should be a while loop, not an if, but here we're not actually
|
||||
* expecting data from the client, and since we're running tests locally,
|
||||
* we can just hope the handshake will finish the during the first call.
|
||||
*/
|
||||
if( ( ret = ssl_read( &ssl, buf, 0 ) ) != 0 )
|
||||
{
|
||||
if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
|
||||
{
|
||||
printf( " failed\n ! ssl_read returned %d\n\n", ret );
|
||||
|
||||
/* Unexpected message probably means client didn't renegotiate */
|
||||
if( ret == POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE )
|
||||
goto reset;
|
||||
else
|
||||
if( ret != POLARSSL_ERR_NET_WANT_READ &&
|
||||
ret != POLARSSL_ERR_NET_WANT_WRITE )
|
||||
{
|
||||
printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf( " ok\n" );
|
||||
#endif
|
||||
/*
|
||||
* Should be a while loop, not an if, but here we're not actually
|
||||
* expecting data from the client, and since we're running tests
|
||||
* locally, we can just hope the handshake will finish the during the
|
||||
* first call.
|
||||
*/
|
||||
if( ( ret = ssl_read( &ssl, buf, 0 ) ) != 0 )
|
||||
{
|
||||
if( ret != POLARSSL_ERR_NET_WANT_READ &&
|
||||
ret != POLARSSL_ERR_NET_WANT_WRITE )
|
||||
{
|
||||
printf( " failed\n ! ssl_read returned %d\n\n", ret );
|
||||
|
||||
/* Unexpected message probably means client didn't renegotiate
|
||||
* as requested */
|
||||
if( ret == POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE )
|
||||
goto reset;
|
||||
else
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
printf( " ok\n" );
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
goto reset;
|
||||
@ -986,6 +1283,9 @@ exit:
|
||||
x509_crt_free( &srvcert2 );
|
||||
pk_free( &pkey2 );
|
||||
#endif
|
||||
#if defined(POLARSSL_SNI)
|
||||
sni_free( sni_info );
|
||||
#endif
|
||||
|
||||
ssl_free( &ssl );
|
||||
entropy_free( &entropy );
|
||||
|
16
tests/Descriptions.txt
Normal file
16
tests/Descriptions.txt
Normal file
@ -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.
|
1371
tests/compat.sh
1371
tests/compat.sh
File diff suppressed because it is too large
Load Diff
1
tests/data_files/passwd.psk
Normal file
1
tests/data_files/passwd.psk
Normal file
@ -0,0 +1 @@
|
||||
Client_identity:6162636465666768696a6b6c6d6e6f70
|
887
tests/ssl-opt.sh
Executable file
887
tests/ssl-opt.sh
Executable file
@ -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
|
Loading…
Reference in New Issue
Block a user