From 9c1e1898b65427f3d2e5e4c13ed6578d61b3d6d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 30 Oct 2013 16:41:21 +0100 Subject: [PATCH] Move some code around, improve documentation --- include/polarssl/ssl.h | 5 ++- library/ssl_tls.c | 65 ++++++++++++++++++++++++++------------ programs/ssl/ssl_client2.c | 2 +- programs/ssl/ssl_server2.c | 11 +++++-- 4 files changed, 58 insertions(+), 25 deletions(-) diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index e15efad00..50ff9864e 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -1422,7 +1422,10 @@ int ssl_handshake( ssl_context *ssl ); 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 00372f962..94d9edf27 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3998,30 +3998,23 @@ static int ssl_write_hello_request( ssl_context *ssl ) /* * 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 @@ static int ssl_do_renegotiate( ssl_context *ssl ) */ 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 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len ) } 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 6879f3e5b..e4a1426a3 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 890c11955..d35ab77d7 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -83,7 +83,7 @@ "

PolarSSL Test Server

\r\n" \ "

Successful connection using: %s

\r\n" // LONG_RESPONSE -/* Temporary, should become a runtime option later */ +/* Uncomment to test server-initiated renegotiation */ // #define TEST_RENEGO /* @@ -948,15 +948,20 @@ reset: */ 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 )