From 29e1f12f6b1f2de0c5444b1e28523efdfea5ac96 Mon Sep 17 00:00:00 2001
From: Paul Bakker
Date: Tue, 16 Apr 2013 13:07:56 +0200
Subject: [PATCH] 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
---
library/ssl_cli.c | 384 +++++++++++++++++++++++++---------------------
1 file changed, 213 insertions(+), 171 deletions(-)
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index c7f959ff8a..0153b86106 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -736,6 +736,136 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
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 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
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++;