Added ssl_handshake_step() to allow single stepping the handshake

process

Single stepping the handshake process allows for better support of
non-blocking network stacks and for getting information from specific
handshake messages if wanted.
This commit is contained in:
Paul Bakker 2013-01-25 14:49:24 +01:00
parent 9c94cddeae
commit 1961b709d8
5 changed files with 222 additions and 203 deletions

View file

@ -1274,121 +1274,113 @@ static int ssl_write_certificate_verify( ssl_context *ssl )
}
/*
* SSL handshake -- client side
* SSL handshake -- client side -- single step
*/
int ssl_handshake_client( ssl_context *ssl )
int ssl_handshake_client_step( ssl_context *ssl )
{
int ret = 0;
SSL_DEBUG_MSG( 2, ( "=> handshake client" ) );
if( ssl->state == SSL_HANDSHAKE_OVER )
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
while( ssl->state != SSL_HANDSHAKE_OVER )
SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
if( ( ret = ssl_flush_output( ssl ) ) != 0 )
return( ret );
switch( ssl->state )
{
SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
if( ( ret = ssl_flush_output( ssl ) ) != 0 )
case SSL_HELLO_REQUEST:
ssl->state = SSL_CLIENT_HELLO;
break;
switch( ssl->state )
{
case SSL_HELLO_REQUEST:
ssl->state = SSL_CLIENT_HELLO;
break;
/*
* ==> ClientHello
*/
case SSL_CLIENT_HELLO:
ret = ssl_write_client_hello( ssl );
break;
/*
* ==> ClientHello
*/
case SSL_CLIENT_HELLO:
ret = ssl_write_client_hello( ssl );
break;
/*
* <== ServerHello
* Certificate
* ( ServerKeyExchange )
* ( CertificateRequest )
* ServerHelloDone
*/
case SSL_SERVER_HELLO:
ret = ssl_parse_server_hello( ssl );
break;
/*
* <== ServerHello
* Certificate
* ( ServerKeyExchange )
* ( CertificateRequest )
* ServerHelloDone
*/
case SSL_SERVER_HELLO:
ret = ssl_parse_server_hello( ssl );
break;
case SSL_SERVER_CERTIFICATE:
ret = ssl_parse_certificate( ssl );
break;
case SSL_SERVER_CERTIFICATE:
ret = ssl_parse_certificate( ssl );
break;
case SSL_SERVER_KEY_EXCHANGE:
ret = ssl_parse_server_key_exchange( ssl );
break;
case SSL_SERVER_KEY_EXCHANGE:
ret = ssl_parse_server_key_exchange( ssl );
break;
case SSL_CERTIFICATE_REQUEST:
ret = ssl_parse_certificate_request( ssl );
break;
case SSL_CERTIFICATE_REQUEST:
ret = ssl_parse_certificate_request( ssl );
break;
case SSL_SERVER_HELLO_DONE:
ret = ssl_parse_server_hello_done( ssl );
break;
case SSL_SERVER_HELLO_DONE:
ret = ssl_parse_server_hello_done( ssl );
break;
/*
* ==> ( Certificate/Alert )
* ClientKeyExchange
* ( CertificateVerify )
* ChangeCipherSpec
* Finished
*/
case SSL_CLIENT_CERTIFICATE:
ret = ssl_write_certificate( ssl );
break;
/*
* ==> ( Certificate/Alert )
* ClientKeyExchange
* ( CertificateVerify )
* ChangeCipherSpec
* Finished
*/
case SSL_CLIENT_CERTIFICATE:
ret = ssl_write_certificate( ssl );
break;
case SSL_CLIENT_KEY_EXCHANGE:
ret = ssl_write_client_key_exchange( ssl );
break;
case SSL_CLIENT_KEY_EXCHANGE:
ret = ssl_write_client_key_exchange( ssl );
break;
case SSL_CERTIFICATE_VERIFY:
ret = ssl_write_certificate_verify( ssl );
break;
case SSL_CERTIFICATE_VERIFY:
ret = ssl_write_certificate_verify( ssl );
break;
case SSL_CLIENT_CHANGE_CIPHER_SPEC:
ret = ssl_write_change_cipher_spec( ssl );
break;
case SSL_CLIENT_CHANGE_CIPHER_SPEC:
ret = ssl_write_change_cipher_spec( ssl );
break;
case SSL_CLIENT_FINISHED:
ret = ssl_write_finished( ssl );
break;
case SSL_CLIENT_FINISHED:
ret = ssl_write_finished( ssl );
break;
/*
* <== ChangeCipherSpec
* Finished
*/
case SSL_SERVER_CHANGE_CIPHER_SPEC:
ret = ssl_parse_change_cipher_spec( ssl );
break;
/*
* <== ChangeCipherSpec
* Finished
*/
case SSL_SERVER_CHANGE_CIPHER_SPEC:
ret = ssl_parse_change_cipher_spec( ssl );
break;
case SSL_SERVER_FINISHED:
ret = ssl_parse_finished( ssl );
break;
case SSL_SERVER_FINISHED:
ret = ssl_parse_finished( ssl );
break;
case SSL_FLUSH_BUFFERS:
SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
ssl->state = SSL_HANDSHAKE_WRAPUP;
break;
case SSL_FLUSH_BUFFERS:
SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
ssl->state = SSL_HANDSHAKE_WRAPUP;
break;
case SSL_HANDSHAKE_WRAPUP:
ssl_handshake_wrapup( ssl );
break;
case SSL_HANDSHAKE_WRAPUP:
ssl_handshake_wrapup( ssl );
break;
default:
SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
}
if( ret != 0 )
break;
}
SSL_DEBUG_MSG( 2, ( "<= handshake client" ) );
default:
SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
}
return( ret );
}
#endif