Move some code around, improve documentation
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index e15efad..50ff986 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -1422,7 +1422,10 @@
int ssl_handshake_step( ssl_context *ssl );
/**
- * \brief Perform an SSL renegotiation on the running connection
+ * \brief Initiate an SSL renegotiation on the running connection.
+ * Client: perform the renegotiation right now.
+ * Server: request renegotiation, which will be performed
+ * during the next call to ssl_read() if honored by client.
*
* \param ssl SSL context
*
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 00372f9..94d9edf 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3998,30 +3998,23 @@
/*
* Actually renegotiate current connection, triggered by either:
* - calling ssl_renegotiate() on client,
- * - receiving a HelloRequestion on client during ssl_read(),
+ * - receiving a HelloRequest on client during ssl_read(),
* - receiving any handshake message on server during ssl_read() after the
* initial handshake is completed
+ * If the handshake doesn't complete due to waiting for I/O, it will continue
+ * during the next calls to ssl_renegotiate() or ssl_read() respectively.
*/
-static int ssl_do_renegotiate( ssl_context *ssl )
+static int ssl_start_renegotiation( ssl_context *ssl )
{
int ret;
SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) );
- /*
- * 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 );
+ 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;
- }
+ ssl->state = SSL_HELLO_REQUEST;
+ ssl->renegotiation = SSL_RENEGOTIATION;
if( ( ret = ssl_handshake( ssl ) ) != 0 )
{
@@ -4040,10 +4033,42 @@
*/
int ssl_renegotiate( ssl_context *ssl )
{
- if( ssl->endpoint == SSL_IS_CLIENT )
- return( ssl_do_renegotiate( ssl ) );
- else
+ int ret;
+
+ /* On server, just send the request */
+ if( ssl->endpoint == SSL_IS_SERVER )
+ {
+ if( ssl->state != SSL_HANDSHAKE_OVER )
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+
return( ssl_write_hello_request( ssl ) );
+ }
+
+ /*
+ * On client, either start the renegotiation process or,
+ * if already in progress, continue the handshake
+ */
+ if( ssl->renegotiation != SSL_RENEGOTIATION )
+ {
+ if( ssl->state != SSL_HANDSHAKE_OVER )
+ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+
+ if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
+ {
+ SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
+ return( ret );
+ }
+ }
+ else
+ {
+ if( ( ret = ssl_handshake( ssl ) ) != 0 )
+ {
+ SSL_DEBUG_RET( 1, "ssl_handshake", ret );
+ return( ret );
+ }
+ }
+
+ return( 0 );
}
/*
@@ -4141,9 +4166,9 @@
}
else
{
- if( ( ret = ssl_do_renegotiate( ssl ) ) != 0 )
+ if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
{
- SSL_DEBUG_RET( 1, "ssl_do_renegotiate", ret );
+ SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
return( ret );
}
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 6879f3e..e4a1426 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -71,7 +71,7 @@
* longer paquets (for fragmentation purposes) */
#define GET_REQUEST "GET %s HTTP/1.0\r\n" /* LONG_HEADER */ "\r\n"
-/* Temporary, should become a runtime option later */
+/* Uncomment to test client-initiated renegotiation */
// #define TEST_RENEGO
/*
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 890c119..d35ab77 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -83,7 +83,7 @@
"<h2>PolarSSL Test Server</h2>\r\n" \
"<p>Successful connection using: %s</p>\r\n" // LONG_RESPONSE
-/* Temporary, should become a runtime option later */
+/* Uncomment to test server-initiated renegotiation */
// #define TEST_RENEGO
/*
@@ -948,15 +948,20 @@
*/
printf( " . Requestion renegotiation..." );
fflush( stdout );
- while( ( ret = ssl_write_hello_request( &ssl ) ) != 0 )
+ while( ( ret = ssl_renegotiate( &ssl ) ) != 0 )
{
if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
{
- printf( " failed\n ! ssl_write_hello_request returned %d\n\n", ret );
+ 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 )