Refactor ssl_parse_server_key_exchange() a bit
This commit is contained in:
parent
32ea60a127
commit
efebb0a394
@ -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" ) );
|
||||||
{
|
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
|
||||||
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
|
|
||||||
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 )
|
||||||
|
Loading…
Reference in New Issue
Block a user