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_srv.c b/library/ssl_srv.c
index 3825393..df57cb3 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1293,121 +1293,113 @@
 }
 
 /*
- * SSL handshake -- server side
+ * SSL handshake -- server side -- single step
  */
-int ssl_handshake_server( ssl_context *ssl )
+int ssl_handshake_server_step( ssl_context *ssl )
 {
     int ret = 0;
 
-    SSL_DEBUG_MSG( 2, ( "=> handshake server" ) );
+    if( ssl->state == SSL_HANDSHAKE_OVER )
+        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
 
-    while( ssl->state != SSL_HANDSHAKE_OVER )
+    SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) );
+
+    if( ( ret = ssl_flush_output( ssl ) ) != 0 )
+        return( ret );
+
+    switch( ssl->state )
     {
-        SSL_DEBUG_MSG( 2, ( "server 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_parse_client_hello( ssl );
-                break;
-
-            /*
-             *  ==>   ServerHello
-             *        Certificate
-             *      ( ServerKeyExchange  )
-             *      ( CertificateRequest )
-             *        ServerHelloDone
-             */
-            case SSL_SERVER_HELLO:
-                ret = ssl_write_server_hello( ssl );
-                break;
-
-            case SSL_SERVER_CERTIFICATE:
-                ret = ssl_write_certificate( ssl );
-                break;
-
-            case SSL_SERVER_KEY_EXCHANGE:
-                ret = ssl_write_server_key_exchange( ssl );
-                break;
-
-            case SSL_CERTIFICATE_REQUEST:
-                ret = ssl_write_certificate_request( ssl );
-                break;
-
-            case SSL_SERVER_HELLO_DONE:
-                ret = ssl_write_server_hello_done( ssl );
-                break;
-
-            /*
-             *  <== ( Certificate/Alert  )
-             *        ClientKeyExchange
-             *      ( CertificateVerify  )
-             *        ChangeCipherSpec
-             *        Finished
-             */
-            case SSL_CLIENT_CERTIFICATE:
-                ret = ssl_parse_certificate( ssl );
-                break;
-
-            case SSL_CLIENT_KEY_EXCHANGE:
-                ret = ssl_parse_client_key_exchange( ssl );
-                break;
-
-            case SSL_CERTIFICATE_VERIFY:
-                ret = ssl_parse_certificate_verify( ssl );
-                break;
-
-            case SSL_CLIENT_CHANGE_CIPHER_SPEC:
-                ret = ssl_parse_change_cipher_spec( ssl );
-                break;
-
-            case SSL_CLIENT_FINISHED:
-                ret = ssl_parse_finished( ssl );
-                break;
-
-            /*
-             *  ==>   ChangeCipherSpec
-             *        Finished
-             */
-            case SSL_SERVER_CHANGE_CIPHER_SPEC:
-                ret = ssl_write_change_cipher_spec( ssl );
-                break;
-
-            case SSL_SERVER_FINISHED:
-                ret = ssl_write_finished( ssl );
-                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;
-
-            default:
-                SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
-                return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
-        }
-
-        if( ret != 0 )
+        /*
+         *  <==   ClientHello
+         */
+        case SSL_CLIENT_HELLO:
+            ret = ssl_parse_client_hello( ssl );
             break;
+
+        /*
+         *  ==>   ServerHello
+         *        Certificate
+         *      ( ServerKeyExchange  )
+         *      ( CertificateRequest )
+         *        ServerHelloDone
+         */
+        case SSL_SERVER_HELLO:
+            ret = ssl_write_server_hello( ssl );
+            break;
+
+        case SSL_SERVER_CERTIFICATE:
+            ret = ssl_write_certificate( ssl );
+            break;
+
+        case SSL_SERVER_KEY_EXCHANGE:
+            ret = ssl_write_server_key_exchange( ssl );
+            break;
+
+        case SSL_CERTIFICATE_REQUEST:
+            ret = ssl_write_certificate_request( ssl );
+            break;
+
+        case SSL_SERVER_HELLO_DONE:
+            ret = ssl_write_server_hello_done( ssl );
+            break;
+
+        /*
+         *  <== ( Certificate/Alert  )
+         *        ClientKeyExchange
+         *      ( CertificateVerify  )
+         *        ChangeCipherSpec
+         *        Finished
+         */
+        case SSL_CLIENT_CERTIFICATE:
+            ret = ssl_parse_certificate( ssl );
+            break;
+
+        case SSL_CLIENT_KEY_EXCHANGE:
+            ret = ssl_parse_client_key_exchange( ssl );
+            break;
+
+        case SSL_CERTIFICATE_VERIFY:
+            ret = ssl_parse_certificate_verify( ssl );
+            break;
+
+        case SSL_CLIENT_CHANGE_CIPHER_SPEC:
+            ret = ssl_parse_change_cipher_spec( ssl );
+            break;
+
+        case SSL_CLIENT_FINISHED:
+            ret = ssl_parse_finished( ssl );
+            break;
+
+        /*
+         *  ==>   ChangeCipherSpec
+         *        Finished
+         */
+        case SSL_SERVER_CHANGE_CIPHER_SPEC:
+            ret = ssl_write_change_cipher_spec( ssl );
+            break;
+
+        case SSL_SERVER_FINISHED:
+            ret = ssl_write_finished( ssl );
+            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;
+
+        default:
+            SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
+            return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    SSL_DEBUG_MSG( 2, ( "<= handshake server" ) );
-
     return( ret );
 }
-
 #endif