split parts of ssl_parse_server_key_exchange() into separate functions

Made ssl_parse_server_dh_params(), ssl_parse_server_ecdh_params() and
ssl_parse_signature_algorihm() in preparation for PSK-related code
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index c7f959f..0153b86 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -736,6 +736,136 @@
     return( 0 );
 }
 #else
+static int ssl_parse_server_dh_params( ssl_context *ssl, unsigned char **p,
+                                       unsigned char *end )
+{
+    int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
+
+#if defined(POLARSSL_DHM_C)
+    /*
+     * Ephemeral DH parameters:
+     *
+     * struct {
+     *     opaque dh_p<1..2^16-1>;
+     *     opaque dh_g<1..2^16-1>;
+     *     opaque dh_Ys<1..2^16-1>;
+     * } ServerDHParams;
+     */
+    if( ( ret = dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 2, ( "dhm_read_params" ), ret );
+        return( ret );
+    }
+
+    if( ssl->handshake->dhm_ctx.len < 64  ||
+        ssl->handshake->dhm_ctx.len > 512 )
+    {
+        SSL_DEBUG_MSG( 1, ( "bad server key exchange message (DHM length)" ) );
+        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+
+    SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P  );
+    SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G  );
+    SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
+#endif /* POLARSSL_DHM_C */
+
+    return( ret );
+}
+
+static int ssl_parse_server_ecdh_params( ssl_context *ssl,
+                                         unsigned char **p,
+                                         unsigned char *end )
+{
+    int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
+
+#if defined(POLARSSL_ECDH_C)
+    /*
+     * Ephemeral ECDH parameters:
+     *
+     * struct {
+     *     ECParameters curve_params;
+     *     ECPoint      public;
+     * } ServerECDHParams;
+     */
+    ecdh_init( &ssl->handshake->ecdh_ctx );
+
+    if( ( ret = ecdh_read_params( &ssl->handshake->ecdh_ctx,
+                                  (const unsigned char **) p, end ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 2, ( "ecdh_read_params" ), ret );
+        return( ret );
+    }
+
+    if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
+        ssl->handshake->ecdh_ctx.grp.nbits > 521 )
+    {
+        SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDH length)" ) );
+        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+
+    SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
+#endif /* POLARSSL_ECDH_C */
+
+    return( ret );
+}
+
+static int ssl_parse_signature_algorithm( ssl_context *ssl,
+                                          unsigned char **p,
+                                          unsigned char *end,
+                                          md_type_t *md_alg )
+{
+    *md_alg = POLARSSL_MD_NONE;
+
+    if( (*p) + 2 < end )
+        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+
+    if( (*p)[1] != SSL_SIG_RSA )
+    {
+        SSL_DEBUG_MSG( 2, ( "server used unsupported SignatureAlgorithm %d", (*p)[1] ) );
+        SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+
+    switch( (*p)[0] )
+    {
+#if defined(POLARSSL_MD5_C)
+        case SSL_HASH_MD5:
+            *md_alg = POLARSSL_MD_MD5;
+            break;
+#endif
+#if defined(POLARSSL_SHA1_C)
+        case SSL_HASH_SHA1:
+            *md_alg = POLARSSL_MD_SHA1;
+            break;
+#endif
+#if defined(POLARSSL_SHA2_C)
+        case SSL_HASH_SHA224:
+            *md_alg = POLARSSL_MD_SHA224;
+            break;
+        case SSL_HASH_SHA256:
+            *md_alg = POLARSSL_MD_SHA256;
+            break;
+#endif
+#if defined(POLARSSL_SHA4_C)
+        case SSL_HASH_SHA384:
+            *md_alg = POLARSSL_MD_SHA384;
+            break;
+        case SSL_HASH_SHA512:
+            *md_alg = POLARSSL_MD_SHA512;
+            break;
+#endif
+        default:
+            SSL_DEBUG_MSG( 2, ( "Server used unsupported HashAlgorithm %d", *(p)[0] ) );
+            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+
+    SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
+    SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
+    *p += 2;
+
+    return( 0 );
+}
+
 static int ssl_parse_server_key_exchange( ssl_context *ssl )
 {
     int ret;
@@ -780,210 +910,122 @@
     p   = ssl->in_msg + 4;
     end = ssl->in_msg + ssl->in_hslen;
 
-#if defined(POLARSSL_DHM_C)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
     {
-        /*
-         * Ephemeral DH parameters:
-         *
-         * struct {
-         *     opaque dh_p<1..2^16-1>;
-         *     opaque dh_g<1..2^16-1>;
-         *     opaque dh_Ys<1..2^16-1>;
-         * } ServerDHParams;
-         */
-        if( ( ret = dhm_read_params( &ssl->handshake->dhm_ctx, &p, end ) ) != 0 )
+        if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
         {
-            SSL_DEBUG_MSG( 2, ( "DHM Read Params returned -0x%x", -ret ) );
             SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
             return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
     }
-#endif /* POLARSSL_DHM_C */
 
-#if defined(POLARSSL_ECDH_C)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
     {
-        /*
-         * Ephemeral ECDH parameters:
-         *
-         * struct {
-         *     ECParameters curve_params;
-         *     ECPoint      public;
-         * } ServerECDHParams;
-         */
-        ecdh_init( &ssl->handshake->ecdh_ctx );
-
-        if( ( ret = ecdh_read_params( &ssl->handshake->ecdh_ctx,
-                                      (const unsigned char **) &p, end ) ) != 0 )
+        if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
         {
-            SSL_DEBUG_MSG( 2, ( "ECDH Read Params returned -0x%x", -ret ) );
             SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
             return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
     }
-#endif /* POLARSSL_ECDH_C */
 
-    if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
+    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
     {
-        if( p[1] != SSL_SIG_RSA )
+        /*
+         * Handle the digitally-signed structure
+         */
+        if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
         {
-            SSL_DEBUG_MSG( 2, ( "server used unsupported SignatureAlgorithm %d", p[1] ) );
-            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); 
-        }
-
-        switch( p[0] )
-        {
-#if defined(POLARSSL_MD5_C)
-            case SSL_HASH_MD5:
-                md_alg = POLARSSL_MD_MD5;
-                break;
-#endif
-#if defined(POLARSSL_SHA1_C)
-            case SSL_HASH_SHA1:
-                md_alg = POLARSSL_MD_SHA1;
-                break;
-#endif
-#if defined(POLARSSL_SHA2_C)
-            case SSL_HASH_SHA224:
-                md_alg = POLARSSL_MD_SHA224;
-                break;
-            case SSL_HASH_SHA256:
-                md_alg = POLARSSL_MD_SHA256;
-                break;
-#endif
-#if defined(POLARSSL_SHA4_C)
-            case SSL_HASH_SHA384:
-                md_alg = POLARSSL_MD_SHA384;
-                break;
-            case SSL_HASH_SHA512:
-                md_alg = POLARSSL_MD_SHA512;
-                break;
-#endif
-            default:
-                SSL_DEBUG_MSG( 2, ( "Server used unsupported HashAlgorithm %d", p[0] ) );
+            if( ssl_parse_signature_algorithm( ssl, &p, end, &md_alg ) != 0 )
+            {
                 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-                return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); 
-        }      
+                return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            }
+        }
 
-        SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", p[1] ) );
-        SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", p[0] ) );
+        n = ( p[0] << 8 ) | p[1];
         p += 2;
-    }
 
-    n = ( p[0] << 8 ) | p[1];
-    p += 2;
-
-    if( end != p + n )
-    {
-        SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
-    }
-
-    if( (unsigned int)( end - p ) !=
-        ssl->session_negotiate->peer_cert->rsa.len )
-    {
-        SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-        return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
-    }
-
-#if defined(POLARSSL_DHM_C)
-    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
-    {
-        if( ssl->handshake->dhm_ctx.len < 64  ||
-            ssl->handshake->dhm_ctx.len > 512 )
+        if( end != p + n )
         {
-            SSL_DEBUG_MSG( 1, ( "bad server key exchange message (DHM length)" ) );
+            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
             return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
 
-        SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P  );
-        SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G  );
-        SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
-    }
-#endif
-
-#if defined(POLARSSL_ECDH_C)
-    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
-    {
-        if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
-            ssl->handshake->ecdh_ctx.grp.nbits > 521 )
+        if( (unsigned int)( end - p ) !=
+            ssl->session_negotiate->peer_cert->rsa.len )
         {
-            SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDH length)" ) );
+            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
             return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
 
-        SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
-    }
-#endif
-
-    if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
-    {
-        md5_context md5;
-        sha1_context sha1;
-
-        /*
-         * digitally-signed struct {
-         *     opaque md5_hash[16];
-         *     opaque sha_hash[20];
-         * };
-         *
-         * md5_hash
-         *     MD5(ClientHello.random + ServerHello.random
-         *                            + ServerParams);
-         * sha_hash
-         *     SHA(ClientHello.random + ServerHello.random
-         *                            + ServerParams);
-         */
-        n = ssl->in_hslen - ( end - p ) - 6;
-
-        md5_starts( &md5 );
-        md5_update( &md5, ssl->handshake->randbytes, 64 );
-        md5_update( &md5, ssl->in_msg + 4, n );
-        md5_finish( &md5, hash );
-
-        sha1_starts( &sha1 );
-        sha1_update( &sha1, ssl->handshake->randbytes, 64 );
-        sha1_update( &sha1, ssl->in_msg + 4, n );
-        sha1_finish( &sha1, hash + 16 );
-
-        md_alg = POLARSSL_MD_NONE;
-        hashlen = 36;
-    }
-    else
-    {
-        md_context_t ctx;
-
-        n = ssl->in_hslen - ( end - p ) - 8;
-
-        /*
-         * digitally-signed struct {
-         *     opaque client_random[32];
-         *     opaque server_random[32];
-         *     ServerDHParams params;
-         * };
-         */
-        if( ( ret = md_init_ctx( &ctx, md_info_from_type( md_alg ) ) ) != 0 )
+        if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
         {
-            SSL_DEBUG_RET( 1, "md_init_ctx", ret );
+            md5_context md5;
+            sha1_context sha1;
+
+            /*
+             * digitally-signed struct {
+             *     opaque md5_hash[16];
+             *     opaque sha_hash[20];
+             * };
+             *
+             * md5_hash
+             *     MD5(ClientHello.random + ServerHello.random
+             *                            + ServerParams);
+             * sha_hash
+             *     SHA(ClientHello.random + ServerHello.random
+             *                            + ServerParams);
+             */
+            n = ssl->in_hslen - ( end - p ) - 6;
+
+            md5_starts( &md5 );
+            md5_update( &md5, ssl->handshake->randbytes, 64 );
+            md5_update( &md5, ssl->in_msg + 4, n );
+            md5_finish( &md5, hash );
+
+            sha1_starts( &sha1 );
+            sha1_update( &sha1, ssl->handshake->randbytes, 64 );
+            sha1_update( &sha1, ssl->in_msg + 4, n );
+            sha1_finish( &sha1, hash + 16 );
+
+            md_alg = POLARSSL_MD_NONE;
+            hashlen = 36;
+        }
+        else
+        {
+            md_context_t ctx;
+
+            n = ssl->in_hslen - ( end - p ) - 8;
+
+            /*
+             * digitally-signed struct {
+             *     opaque client_random[32];
+             *     opaque server_random[32];
+             *     ServerDHParams params;
+             * };
+             */
+            if( ( ret = md_init_ctx( &ctx, md_info_from_type( md_alg ) ) ) != 0 )
+            {
+                SSL_DEBUG_RET( 1, "md_init_ctx", ret );
+                return( ret );
+            }
+
+            md_starts( &ctx );
+            md_update( &ctx, ssl->handshake->randbytes, 64 );
+            md_update( &ctx, ssl->in_msg + 4, n );
+            md_finish( &ctx, hash );
+        }
+
+        SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
+
+        if( ( ret = rsa_pkcs1_verify( &ssl->session_negotiate->peer_cert->rsa,
+                                      RSA_PUBLIC,
+                                      md_alg, hashlen, hash, p ) ) != 0 )
+        {
+            SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
             return( ret );
         }
-
-        md_starts( &ctx );
-        md_update( &ctx, ssl->handshake->randbytes, 64 );
-        md_update( &ctx, ssl->in_msg + 4, n );
-        md_finish( &ctx, hash );
-    }
-    
-    SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
-
-    if( ( ret = rsa_pkcs1_verify( &ssl->session_negotiate->peer_cert->rsa,
-                                  RSA_PUBLIC,
-                                  md_alg, hashlen, hash, p ) ) != 0 )
-    {
-        SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
-        return( ret );
     }
 
     ssl->state++;