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.
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 42ddf41..545906a 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1274,121 +1274,113 @@
 }
 
 /*
- * 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