Refactor ssl_parse_server_key_exchange() a bit

This commit is contained in:
Manuel Pégourié-Gonnard 2013-08-19 12:06:38 +02:00
parent 32ea60a127
commit efebb0a394

View File

@ -1157,20 +1157,29 @@ static int ssl_parse_server_psk_hint( ssl_context *ssl,
static int ssl_parse_signature_algorithm( ssl_context *ssl, static int ssl_parse_signature_algorithm( ssl_context *ssl,
unsigned char **p, unsigned char **p,
unsigned char *end, unsigned char *end,
md_type_t *md_alg ) md_type_t *md_alg,
size_t *hash_len,
pk_type_t *pk_alg )
{ {
const md_info_t *md_info;
((void) ssl); ((void) ssl);
*md_alg = POLARSSL_MD_NONE; *md_alg = POLARSSL_MD_NONE;
*pk_alg = POLARSSL_PK_NONE;
/* Only in TLS 1.2 */
if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
{
*hash_len = 36;
return( 0 );
}
if( (*p) + 2 > end ) if( (*p) + 2 > end )
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
if( (*p)[1] != SSL_SIG_RSA ) /*
{ * Get hash algorithm
SSL_DEBUG_MSG( 2, ( "server used unsupported SignatureAlgorithm %d", (*p)[1] ) ); */
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
switch( (*p)[0] ) switch( (*p)[0] )
{ {
#if defined(POLARSSL_MD5_C) #if defined(POLARSSL_MD5_C)
@ -1200,7 +1209,43 @@ static int ssl_parse_signature_algorithm( ssl_context *ssl,
break; break;
#endif #endif
default: default:
SSL_DEBUG_MSG( 2, ( "Server used unsupported HashAlgorithm %d", *(p)[0] ) ); SSL_DEBUG_MSG( 2, ( "Server used unsupported "
"HashAlgorithm %d", *(p)[0] ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
/*
* Get hash_len from hash alg
*/
if( ( md_info = md_info_from_type( *md_alg ) ) == NULL )
{
SSL_DEBUG_MSG( 2, ( "Server used unsupported "
"HashAlgorithm %d", *(p)[0] ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
*hash_len = md_info->size;
/*
* Get signature algorithm
*/
switch( (*p)[1] )
{
#if defined(POLARSSL_RSA_C)
case SSL_SIG_RSA:
*pk_alg = POLARSSL_PK_RSA;
break;
#endif
#if defined(POLARSSL_ECDSA_C)
case SSL_SIG_ECDSA:
*pk_alg = POLARSSL_PK_ECDSA;
break;
#endif
default:
SSL_DEBUG_MSG( 2, ( "server used unsupported "
"SignatureAlgorithm %d", (*p)[1] ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
@ -1220,10 +1265,11 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
unsigned char *p, *end; unsigned char *p, *end;
#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
size_t n; size_t sig_len, params_len;
unsigned char hash[64]; unsigned char hash[64];
md_type_t md_alg = POLARSSL_MD_NONE; md_type_t md_alg = POLARSSL_MD_NONE;
unsigned int hashlen = 0; size_t hashlen;
pk_type_t pk_alg = POLARSSL_PK_NONE;
#endif #endif
SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
@ -1325,41 +1371,30 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA || if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ||
ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ) ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{ {
params_len = p - ( ssl->in_msg + 4 );
/* /*
* Handle the digitally-signed structure * Handle the digitally-signed structure
*/ */
if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) if( ssl_parse_signature_algorithm( ssl, &p, end,
{ &md_alg, &hashlen, &pk_alg ) != 0 )
if( ssl_parse_signature_algorithm( ssl, &p, end, &md_alg ) != 0 )
{ {
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); 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 );
} }
}
n = ( p[0] << 8 ) | p[1]; sig_len = ( p[0] << 8 ) | p[1];
p += 2; p += 2;
if( end != p + n ) if( end != p + sig_len )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
POLARSSL_PK_RSA ) )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
}
if( 8 * (unsigned int)( end - p ) !=
pk_get_size( &ssl->session_negotiate->peer_cert->pk ) )
{ {
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); 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 );
} }
/*
* Compute the hash that has been signed
*/
if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
{ {
md5_context md5; md5_context md5;
@ -1378,27 +1413,20 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
* SHA(ClientHello.random + ServerHello.random * SHA(ClientHello.random + ServerHello.random
* + ServerParams); * + ServerParams);
*/ */
n = ssl->in_hslen - ( end - p ) - 6;
md5_starts( &md5 ); md5_starts( &md5 );
md5_update( &md5, ssl->handshake->randbytes, 64 ); md5_update( &md5, ssl->handshake->randbytes, 64 );
md5_update( &md5, ssl->in_msg + 4, n ); md5_update( &md5, ssl->in_msg + 4, params_len );
md5_finish( &md5, hash ); md5_finish( &md5, hash );
sha1_starts( &sha1 ); sha1_starts( &sha1 );
sha1_update( &sha1, ssl->handshake->randbytes, 64 ); sha1_update( &sha1, ssl->handshake->randbytes, 64 );
sha1_update( &sha1, ssl->in_msg + 4, n ); sha1_update( &sha1, ssl->in_msg + 4, params_len );
sha1_finish( &sha1, hash + 16 ); sha1_finish( &sha1, hash + 16 );
md_alg = POLARSSL_MD_NONE;
hashlen = 36;
} }
else else
{ {
md_context_t ctx; md_context_t ctx;
n = ssl->in_hslen - ( end - p ) - 8;
/* /*
* digitally-signed struct { * digitally-signed struct {
* opaque client_random[32]; * opaque client_random[32];
@ -1414,13 +1442,30 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
md_starts( &ctx ); md_starts( &ctx );
md_update( &ctx, ssl->handshake->randbytes, 64 ); md_update( &ctx, ssl->handshake->randbytes, 64 );
md_update( &ctx, ssl->in_msg + 4, n ); md_update( &ctx, ssl->in_msg + 4, params_len );
md_finish( &ctx, hash ); md_finish( &ctx, hash );
md_free_ctx( &ctx ); md_free_ctx( &ctx );
} }
SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
/*
* Verify signature
*/
if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
POLARSSL_PK_RSA ) )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
}
if( 8 * sig_len !=
pk_get_size( &ssl->session_negotiate->peer_cert->pk ) )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
if( ( ret = rsa_pkcs1_verify( if( ( ret = rsa_pkcs1_verify(
pk_rsa( ssl->session_negotiate->peer_cert->pk ), pk_rsa( ssl->session_negotiate->peer_cert->pk ),
RSA_PUBLIC, md_alg, hashlen, hash, p ) ) != 0 ) RSA_PUBLIC, md_alg, hashlen, hash, p ) ) != 0 )