From 7eb013faceea36a12aa4f629885162479c537305 Mon Sep 17 00:00:00 2001
From: Paul Bakker
Date: Thu, 6 Oct 2011 12:37:39 +0000
Subject: [PATCH] - Added ssl_session_reset() to allow re-use of already set
non-connection specific context information
---
ChangeLog | 6 ++++
include/polarssl/ssl.h | 9 +++++
library/ssl_tls.c | 43 +++++++++++++++++++++++
programs/ssl/ssl_server.c | 73 +++++++++++++++++++++------------------
4 files changed, 97 insertions(+), 34 deletions(-)
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: