Allow ssl_renegotiate() to be called in a loop
Previously broken if waiting for network I/O in the middle of a re-handshake
initiated by the client.
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index cbec352..6808487 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -200,7 +200,8 @@
#define SSL_VERIFY_REQUIRED 2
#define SSL_INITIAL_HANDSHAKE 0
-#define SSL_RENEGOTIATION 1
+#define SSL_RENEGOTIATION 1 /* In progress */
+#define SSL_RENEGOTIATION_DONE 2 /* Done */
#define SSL_LEGACY_RENEGOTIATION 0
#define SSL_SECURE_RENEGOTIATION 1
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 6dd5cc0..f6f3e10 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3023,6 +3023,9 @@
polarssl_free( ssl->handshake );
ssl->handshake = NULL;
+ if( ssl->renegotiation == SSL_RENEGOTIATION )
+ ssl->renegotiation = SSL_RENEGOTIATION_DONE;
+
/*
* Switch in our now active transform context
*/
@@ -3977,14 +3980,20 @@
SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) );
- if( ssl->state != SSL_HANDSHAKE_OVER )
- return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+ /*
+ * If renegotiation is already in progress, skip checks/init
+ */
+ if( ssl->renegotiation != SSL_RENEGOTIATION )
+ {
+ if( ssl->state != SSL_HANDSHAKE_OVER )
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
- ssl->state = SSL_HELLO_REQUEST;
- ssl->renegotiation = SSL_RENEGOTIATION;
+ if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
+ return( ret );
- if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
- return( ret );
+ ssl->state = SSL_HELLO_REQUEST;
+ ssl->renegotiation = SSL_RENEGOTIATION;
+ }
if( ( ret = ssl_handshake( ssl ) ) != 0 )
{