diff --git a/ChangeLog b/ChangeLog index 2a18a341a..63ec3685c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ PolarSSL ChangeLog += Version Trunk +Features + * Added ssl_session_reset() to allow better multi-connection pools of + SSL contexts without needing to set all non-connection-specific + data and pointers again. Adapted ssl_server to use this functionality. + = Version 1.0.0 released on 2011-07-27 Features * Expanded cipher layer with support for CFB128 and CTR mode diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 45cb1cc03..8cdb63679 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -377,6 +377,15 @@ int ssl_get_ciphersuite_id( const char *ciphersuite_name ); */ int ssl_init( ssl_context *ssl ); +/** + * \brief Reset an already initialized SSL context for re-use + * while retaining application-set variables, function + * pointers and data. + * + * \param ssl SSL context + */ +void ssl_session_reset( ssl_context *ssl ); + /** * \brief Set the current endpoint type * diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 004c70ac0..7e6e86ceb 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1731,6 +1731,49 @@ int ssl_init( ssl_context *ssl ) return( 0 ); } +/* + * Reset an initialized and used SSL context for re-use while retaining + * all application-set variables, function pointers and data. + */ +void ssl_session_reset( ssl_context *ssl ) +{ + ssl->state = SSL_HELLO_REQUEST; + + ssl->in_offt = NULL; + + ssl->in_msgtype = 0; + ssl->in_msglen = 0; + ssl->in_left = 0; + + ssl->in_hslen = 0; + ssl->nb_zero = 0; + + ssl->out_msgtype = 0; + ssl->out_msglen = 0; + ssl->out_left = 0; + + ssl->do_crypt = 0; + ssl->pmslen = 0; + ssl->keylen = 0; + ssl->minlen = 0; + ssl->ivlen = 0; + ssl->maclen = 0; + + memset( ssl->out_ctr, 0, SSL_BUFFER_LEN ); + memset( ssl->in_ctr, 0, SSL_BUFFER_LEN ); + memset( ssl->randbytes, 0, 64 ); + memset( ssl->premaster, 0, 256 ); + memset( ssl->iv_enc, 0, 16 ); + memset( ssl->iv_dec, 0, 16 ); + memset( ssl->mac_enc, 0, 32 ); + memset( ssl->mac_dec, 0, 32 ); + memset( ssl->ctx_enc, 0, 128 ); + memset( ssl->ctx_dec, 0, 128 ); + + md5_starts( &ssl->fin_md5 ); + sha1_starts( &ssl->fin_sha1 ); +} + /* * SSL set accessors */ diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c index be92b0dd2..694908c44 100644 --- a/programs/ssl/ssl_server.c +++ b/programs/ssl/ssl_server.c @@ -186,7 +186,7 @@ int main( void ) { int ret, len; int listen_fd; - int client_fd; + int client_fd = -1; unsigned char buf[1024]; havege_state hs; @@ -249,45 +249,19 @@ int main( void ) printf( " ok\n" ); - /* - * 3. Wait until a client connects - */ -#ifdef WIN32 - ShellExecute( NULL, "open", "https://localhost:4433/", - NULL, NULL, SW_SHOWNORMAL ); -#endif - - client_fd = -1; - memset( &ssl, 0, sizeof( ssl ) ); - -accept: - - net_close( client_fd ); - ssl_free( &ssl ); - - printf( " . Waiting for a remote connection ..." ); - fflush( stdout ); - - if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 ) - { - printf( " failed\n ! net_accept returned %d\n\n", ret ); - goto exit; - } - - printf( " ok\n" ); - /* * 4. Setup stuff */ printf( " . Setting up the RNG and SSL data...." ); fflush( stdout ); + memset( &ssl, 0, sizeof( ssl ) ); havege_init( &hs ); if( ( ret = ssl_init( &ssl ) ) != 0 ) { printf( " failed\n ! ssl_init returned %d\n\n", ret ); - goto accept; + goto exit; } printf( " ok\n" ); @@ -297,8 +271,7 @@ accept: ssl_set_rng( &ssl, havege_rand, &hs ); ssl_set_dbg( &ssl, my_debug, stdout ); - ssl_set_bio( &ssl, net_recv, &client_fd, - net_send, &client_fd ); + ssl_set_scb( &ssl, my_get_session, my_set_session ); @@ -311,6 +284,38 @@ accept: ssl_set_own_cert( &ssl, &srvcert, &rsa ); ssl_set_dh_param( &ssl, my_dhm_P, my_dhm_G ); + printf( " ok\n" ); + +reset: + if( client_fd != -1 ) + net_close( client_fd ); + + ssl_session_reset( &ssl ); + + /* + * 3. Wait until a client connects + */ +#ifdef WIN32 + ShellExecute( NULL, "open", "https://localhost:4433/", + NULL, NULL, SW_SHOWNORMAL ); +#endif + + client_fd = -1; + + printf( " . Waiting for a remote connection ..." ); + fflush( stdout ); + + if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 ) + { + printf( " failed\n ! net_accept returned %d\n\n", ret ); + goto exit; + } + + ssl_set_bio( &ssl, net_recv, &client_fd, + net_send, &client_fd ); + + printf( " ok\n" ); + /* * 5. Handshake */ @@ -322,7 +327,7 @@ accept: if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { printf( " failed\n ! ssl_handshake returned %d\n\n", ret ); - goto accept; + goto reset; } } @@ -382,7 +387,7 @@ accept: if( ret == POLARSSL_ERR_NET_CONN_RESET ) { printf( " failed\n ! peer closed the connection\n\n" ); - goto accept; + goto reset; } if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) @@ -396,7 +401,7 @@ accept: printf( " %d bytes written\n\n%s\n", len, (char *) buf ); ssl_close_notify( &ssl ); - goto accept; + goto reset; exit: