mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-03 18:54:14 +01:00
Merge remote-tracking branch 'hanno/iotssl-1241-backport-1.3' into mbedtls-1.3
* hanno/iotssl-1241-backport-1.3: Remember suitable hash function for any signature algorithm.
This commit is contained in:
commit
bbe01032a4
@ -9,6 +9,10 @@ Security
|
|||||||
Found and fix proposed by Michael Schwarz, Samuel Weiser, Daniel Gruss,
|
Found and fix proposed by Michael Schwarz, Samuel Weiser, Daniel Gruss,
|
||||||
Clémentine Maurice and Stefan Mangard.
|
Clémentine Maurice and Stefan Mangard.
|
||||||
|
|
||||||
|
Bugfix
|
||||||
|
* Fix insufficient support for signature-hash-algorithm extension,
|
||||||
|
resulting in compatibility problems with Chrome. Found by hfloyrd. #823
|
||||||
|
|
||||||
= mbed TLS 1.3.19 branch released 2017-03-08
|
= mbed TLS 1.3.19 branch released 2017-03-08
|
||||||
|
|
||||||
Security
|
Security
|
||||||
|
@ -539,6 +539,7 @@ typedef struct _ssl_session ssl_session;
|
|||||||
typedef struct _ssl_context ssl_context;
|
typedef struct _ssl_context ssl_context;
|
||||||
typedef struct _ssl_transform ssl_transform;
|
typedef struct _ssl_transform ssl_transform;
|
||||||
typedef struct _ssl_handshake_params ssl_handshake_params;
|
typedef struct _ssl_handshake_params ssl_handshake_params;
|
||||||
|
typedef struct _ssl_sig_hash_set_t ssl_sig_hash_set_t;
|
||||||
#if defined(POLARSSL_SSL_SESSION_TICKETS)
|
#if defined(POLARSSL_SSL_SESSION_TICKETS)
|
||||||
typedef struct _ssl_ticket_keys ssl_ticket_keys;
|
typedef struct _ssl_ticket_keys ssl_ticket_keys;
|
||||||
#endif
|
#endif
|
||||||
@ -625,6 +626,24 @@ struct _ssl_transform
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
/*
|
||||||
|
* Abstraction for a grid of allowed signature-hash-algorithm pairs.
|
||||||
|
*/
|
||||||
|
struct _ssl_sig_hash_set_t
|
||||||
|
{
|
||||||
|
/* At the moment, we only need to remember a single suitable
|
||||||
|
* hash algorithm per signature algorithm. As long as that's
|
||||||
|
* the case - and we don't need a general lookup function -
|
||||||
|
* we can implement the sig-hash-set as a map from signatures
|
||||||
|
* to hash algorithms. */
|
||||||
|
md_type_t rsa;
|
||||||
|
md_type_t ecdsa;
|
||||||
|
};
|
||||||
|
#endif /* POLARSSL_SSL_PROTO_TLS1_2) &&
|
||||||
|
POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This structure contains the parameters only needed during handshake.
|
* This structure contains the parameters only needed during handshake.
|
||||||
*/
|
*/
|
||||||
@ -633,7 +652,10 @@ struct _ssl_handshake_params
|
|||||||
/*
|
/*
|
||||||
* Handshake specific crypto variables
|
* Handshake specific crypto variables
|
||||||
*/
|
*/
|
||||||
int sig_alg; /*!< Hash algorithm for signature */
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
ssl_sig_hash_set_t hash_algs; /*!< Set of suitable sig-hash pairs */
|
||||||
|
#endif
|
||||||
int cert_type; /*!< Requested cert type */
|
int cert_type; /*!< Requested cert type */
|
||||||
int verify_sig_alg; /*!< Signature algorithm for verify */
|
int verify_sig_alg; /*!< Signature algorithm for verify */
|
||||||
#if defined(POLARSSL_DHM_C)
|
#if defined(POLARSSL_DHM_C)
|
||||||
@ -1957,15 +1979,40 @@ int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex );
|
|||||||
|
|
||||||
#if defined(POLARSSL_PK_C)
|
#if defined(POLARSSL_PK_C)
|
||||||
unsigned char ssl_sig_from_pk( pk_context *pk );
|
unsigned char ssl_sig_from_pk( pk_context *pk );
|
||||||
|
unsigned char ssl_sig_from_pk_alg( pk_type_t type );
|
||||||
pk_type_t ssl_pk_alg_from_sig( unsigned char sig );
|
pk_type_t ssl_pk_alg_from_sig( unsigned char sig );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
md_type_t ssl_md_alg_from_hash( unsigned char hash );
|
md_type_t ssl_md_alg_from_hash( unsigned char hash );
|
||||||
|
unsigned char ssl_hash_from_md_alg( md_type_t md );
|
||||||
|
|
||||||
#if defined(POLARSSL_SSL_SET_CURVES)
|
#if defined(POLARSSL_SSL_SET_CURVES)
|
||||||
int ssl_curve_is_acceptable( const ssl_context *ssl, ecp_group_id grp_id );
|
int ssl_curve_is_acceptable( const ssl_context *ssl, ecp_group_id grp_id );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
|
||||||
|
/* Find an entry in a signature-hash set matching a given hash algorithm. */
|
||||||
|
md_type_t ssl_sig_hash_set_find( ssl_sig_hash_set_t *set,
|
||||||
|
pk_type_t sig_alg );
|
||||||
|
/* Add a signature-hash-pair to a signature-hash set */
|
||||||
|
void ssl_sig_hash_set_add( ssl_sig_hash_set_t *set,
|
||||||
|
pk_type_t sig_alg,
|
||||||
|
md_type_t md_alg );
|
||||||
|
/* Allow exactly one hash algorithm for each signature. */
|
||||||
|
void ssl_sig_hash_set_const_hash( ssl_sig_hash_set_t *set,
|
||||||
|
md_type_t md_alg );
|
||||||
|
|
||||||
|
/* Setup an empty signature-hash set */
|
||||||
|
static inline void ssl_sig_hash_set_init( ssl_sig_hash_set_t *set )
|
||||||
|
{
|
||||||
|
ssl_sig_hash_set_const_hash( set, POLARSSL_MD_NONE );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* POLARSSL_SSL_PROTO_TLS1_2) &&
|
||||||
|
POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
|
||||||
|
|
||||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
static inline pk_context *ssl_own_key( ssl_context *ssl )
|
static inline pk_context *ssl_own_key( ssl_context *ssl )
|
||||||
{
|
{
|
||||||
@ -1979,6 +2026,12 @@ static inline x509_crt *ssl_own_cert( ssl_context *ssl )
|
|||||||
: ssl->handshake->key_cert->cert );
|
: ssl->handshake->key_cert->cert );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if a hash proposed by the peer is in our list.
|
||||||
|
* Return 0 if we're willing to use it, -1 otherwise.
|
||||||
|
*/
|
||||||
|
int ssl_check_sig_hash( md_type_t md );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check usage of a certificate wrt extensions:
|
* Check usage of a certificate wrt extensions:
|
||||||
* keyUsage, extendedKeyUsage (later), and nSCertType (later).
|
* keyUsage, extendedKeyUsage (later), and nSCertType (later).
|
||||||
|
@ -290,6 +290,7 @@ const ssl_ciphersuite_t *ssl_ciphersuite_from_id( int ciphersuite_id );
|
|||||||
|
|
||||||
#if defined(POLARSSL_PK_C)
|
#if defined(POLARSSL_PK_C)
|
||||||
pk_type_t ssl_get_ciphersuite_sig_pk_alg( const ssl_ciphersuite_t *info );
|
pk_type_t ssl_get_ciphersuite_sig_pk_alg( const ssl_ciphersuite_t *info );
|
||||||
|
pk_type_t ssl_get_ciphersuite_sig_alg( const ssl_ciphersuite_t *info );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int ssl_ciphersuite_uses_ec( const ssl_ciphersuite_t *info );
|
int ssl_ciphersuite_uses_ec( const ssl_ciphersuite_t *info );
|
||||||
|
@ -1803,6 +1803,24 @@ pk_type_t ssl_get_ciphersuite_sig_pk_alg( const ssl_ciphersuite_t *info )
|
|||||||
return( POLARSSL_PK_NONE );
|
return( POLARSSL_PK_NONE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pk_type_t ssl_get_ciphersuite_sig_alg( const ssl_ciphersuite_t *info )
|
||||||
|
{
|
||||||
|
switch( info->key_exchange )
|
||||||
|
{
|
||||||
|
case POLARSSL_KEY_EXCHANGE_RSA:
|
||||||
|
case POLARSSL_KEY_EXCHANGE_DHE_RSA:
|
||||||
|
case POLARSSL_KEY_EXCHANGE_ECDHE_RSA:
|
||||||
|
return( POLARSSL_PK_RSA );
|
||||||
|
|
||||||
|
case POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA:
|
||||||
|
return( POLARSSL_PK_ECDSA );
|
||||||
|
|
||||||
|
default:
|
||||||
|
return( POLARSSL_PK_NONE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* POLARSSL_PK_C */
|
#endif /* POLARSSL_PK_C */
|
||||||
|
|
||||||
#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
|
#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
|
||||||
|
@ -467,6 +467,18 @@ static int ssl_parse_renegotiation_info( ssl_context *ssl,
|
|||||||
|
|
||||||
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
/*
|
||||||
|
* Status of the implementation of signature-algorithms extension:
|
||||||
|
*
|
||||||
|
* Currently, we are only considering the signature-algorithm extension
|
||||||
|
* to pick a ciphersuite which allows us to send the ServerKeyExchange
|
||||||
|
* message with a signature-hash combination that the user allows.
|
||||||
|
*
|
||||||
|
* We do *not* check whether all certificates in our certificate
|
||||||
|
* chain are signed with an allowed signature-hash pair.
|
||||||
|
* This needs to be done at a later stage.
|
||||||
|
*
|
||||||
|
*/
|
||||||
static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
|
static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
|
||||||
const unsigned char *buf,
|
const unsigned char *buf,
|
||||||
size_t len )
|
size_t len )
|
||||||
@ -474,8 +486,9 @@ static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
|
|||||||
size_t sig_alg_list_size;
|
size_t sig_alg_list_size;
|
||||||
const unsigned char *p;
|
const unsigned char *p;
|
||||||
const unsigned char *end = buf + len;
|
const unsigned char *end = buf + len;
|
||||||
const int *md_cur;
|
|
||||||
|
|
||||||
|
md_type_t md_cur;
|
||||||
|
pk_type_t sig_cur;
|
||||||
|
|
||||||
sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
|
sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
|
||||||
if( sig_alg_list_size + 2 != len ||
|
if( sig_alg_list_size + 2 != len ||
|
||||||
@ -485,35 +498,48 @@ static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
|
|||||||
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
|
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Currently we only guarantee signing the ServerKeyExchange message according
|
||||||
* For now, ignore the SignatureAlgorithm part and rely on offered
|
* to the constraints specified in this extension (see above), so it suffices
|
||||||
* ciphersuites only for that part. To be fixed later.
|
* to remember only one suitable hash for each possible signature algorithm.
|
||||||
*
|
*
|
||||||
* So, just look at the HashAlgorithm part.
|
* This will change when we also consider certificate signatures,
|
||||||
|
* in which case we will need to remember the whole signature-hash
|
||||||
|
* pair list from the extension.
|
||||||
*/
|
*/
|
||||||
for( md_cur = md_list(); *md_cur != POLARSSL_MD_NONE; md_cur++ ) {
|
|
||||||
#if !defined(POLARSSL_SSL_ENABLE_MD5_SIGNATURES)
|
|
||||||
/* Skip MD5 */
|
|
||||||
if( *md_cur == POLARSSL_MD_MD5 )
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for( p = buf + 2; p < end; p += 2 ) {
|
for( p = buf + 2; p < end; p += 2 ) {
|
||||||
if( *md_cur == (int) ssl_md_alg_from_hash( p[0] ) ) {
|
|
||||||
ssl->handshake->sig_alg = p[0];
|
/* Silently ignore unknown signature or hash algorithms. */
|
||||||
goto have_sig_alg;
|
|
||||||
}
|
if( (sig_cur = ssl_pk_alg_from_sig( p[1] ) ) == POLARSSL_PK_NONE )
|
||||||
|
{
|
||||||
|
SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: unknown sig alg encoding %d",
|
||||||
|
p[1] ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we support the hash the user proposes */
|
||||||
|
md_cur = ssl_md_alg_from_hash( p[0] );
|
||||||
|
if( md_cur == POLARSSL_MD_NONE )
|
||||||
|
{
|
||||||
|
SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: "
|
||||||
|
"unknown hash alg encoding %d", p[0] ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ssl_check_sig_hash( md_cur ) == 0 )
|
||||||
|
{
|
||||||
|
ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur );
|
||||||
|
SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: match sig %d and hash %d",
|
||||||
|
sig_cur, md_cur ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: hash alg %d not supported",
|
||||||
|
md_cur ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some key echanges do not need signatures at all */
|
|
||||||
SSL_DEBUG_MSG( 3, ( "no signature_algorithm in common" ) );
|
|
||||||
return( 0 );
|
|
||||||
|
|
||||||
have_sig_alg:
|
|
||||||
SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d",
|
|
||||||
ssl->handshake->sig_alg ) );
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
#endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
|
#endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
|
||||||
@ -932,6 +958,11 @@ static int ssl_ciphersuite_match( ssl_context *ssl, int suite_id,
|
|||||||
{
|
{
|
||||||
const ssl_ciphersuite_t *suite_info;
|
const ssl_ciphersuite_t *suite_info;
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
pk_type_t sig_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
suite_info = ssl_ciphersuite_from_id( suite_id );
|
suite_info = ssl_ciphersuite_from_id( suite_id );
|
||||||
if( suite_info == NULL )
|
if( suite_info == NULL )
|
||||||
{
|
{
|
||||||
@ -979,6 +1010,26 @@ static int ssl_ciphersuite_match( ssl_context *ssl, int suite_id,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
/* If the ciphersuite requires signing, check whether
|
||||||
|
* a suitable hash algorithm is present. */
|
||||||
|
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
|
||||||
|
{
|
||||||
|
sig_type = ssl_get_ciphersuite_sig_alg( suite_info );
|
||||||
|
if( sig_type != POLARSSL_PK_NONE &&
|
||||||
|
ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == POLARSSL_MD_NONE )
|
||||||
|
{
|
||||||
|
SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm "
|
||||||
|
"for signature algorithm %d", sig_type ) );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
|
||||||
|
POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
|
||||||
|
|
||||||
|
|
||||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
/*
|
/*
|
||||||
* Final check: if ciphersuite requires us to have a
|
* Final check: if ciphersuite requires us to have a
|
||||||
@ -1287,6 +1338,15 @@ static int ssl_parse_client_hello( ssl_context *ssl )
|
|||||||
const int *ciphersuites;
|
const int *ciphersuites;
|
||||||
const ssl_ciphersuite_t *ciphersuite_info;
|
const ssl_ciphersuite_t *ciphersuite_info;
|
||||||
|
|
||||||
|
/* If there is no signature-algorithm extension present,
|
||||||
|
* we need to fall back to the default values for allowed
|
||||||
|
* signature-hash pairs. */
|
||||||
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
int sig_hash_alg_ext_present = 0;
|
||||||
|
#endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
|
||||||
|
POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
|
||||||
|
|
||||||
SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
|
SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
|
||||||
|
|
||||||
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
#if defined(POLARSSL_SSL_RENEGOTIATION)
|
||||||
@ -1621,6 +1681,8 @@ static int ssl_parse_client_hello( ssl_context *ssl )
|
|||||||
ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
|
ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
|
||||||
if( ret != 0 )
|
if( ret != 0 )
|
||||||
return( ret );
|
return( ret );
|
||||||
|
|
||||||
|
sig_hash_alg_ext_present = 1;
|
||||||
break;
|
break;
|
||||||
#endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
|
#endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
|
||||||
POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
|
POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
|
||||||
@ -1764,6 +1826,27 @@ static int ssl_parse_client_hello( ssl_context *ssl )
|
|||||||
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
|
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to fall back to default hash SHA1 if the client
|
||||||
|
* hasn't provided any preferred signature-hash combinations.
|
||||||
|
*/
|
||||||
|
if( sig_hash_alg_ext_present == 0 )
|
||||||
|
{
|
||||||
|
md_type_t md_default = POLARSSL_MD_SHA1;
|
||||||
|
|
||||||
|
if( ssl_check_sig_hash( md_default ) != 0 )
|
||||||
|
md_default = POLARSSL_MD_NONE;
|
||||||
|
|
||||||
|
ssl_sig_hash_set_const_hash( &ssl->handshake->hash_algs, md_default );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* POLARSSL_SSL_PROTO_TLS1_2 &&
|
||||||
|
POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for a matching ciphersuite
|
* Search for a matching ciphersuite
|
||||||
* (At the end because we need information from the EC-based extensions
|
* (At the end because we need information from the EC-based extensions
|
||||||
@ -1821,6 +1904,28 @@ have_ciphersuite:
|
|||||||
ssl->in_left = 0;
|
ssl->in_left = 0;
|
||||||
ssl->state++;
|
ssl->state++;
|
||||||
|
|
||||||
|
/* Debugging-only output for testsuite */
|
||||||
|
#if defined(POLARSSL_DEBUG_C) && \
|
||||||
|
defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
|
||||||
|
{
|
||||||
|
pk_type_t sig_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
|
||||||
|
if( sig_alg != POLARSSL_PK_NONE )
|
||||||
|
{
|
||||||
|
md_type_t md_alg = ssl_sig_hash_set_find( &ssl->handshake->hash_algs,
|
||||||
|
sig_alg );
|
||||||
|
SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d",
|
||||||
|
ssl_hash_from_md_alg( md_alg ) ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SSL_DEBUG_MSG( 3, ( "no hash algorithm for signature algorithm %d - should not happen",
|
||||||
|
sig_alg ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) );
|
SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -2665,17 +2770,25 @@ curve_matching_done:
|
|||||||
size_t signature_len = 0;
|
size_t signature_len = 0;
|
||||||
unsigned int hashlen = 0;
|
unsigned int hashlen = 0;
|
||||||
unsigned char hash[64];
|
unsigned char hash[64];
|
||||||
md_type_t md_alg = POLARSSL_MD_NONE;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Choose hash algorithm. NONE means MD5 + SHA1 here.
|
* Choose hash algorithm:
|
||||||
|
* - For TLS 1.2, obey signature-hash-algorithm extension to choose appropriate hash.
|
||||||
|
* - For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1 (RFC 4492, Sec. 5.4)
|
||||||
|
* - Otherwise, use MD5 + SHA1 (RFC 4346, Sec. 7.4.3)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
md_type_t md_alg;
|
||||||
|
|
||||||
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
|
||||||
|
pk_type_t sig_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
|
||||||
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
|
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
|
||||||
{
|
{
|
||||||
md_alg = ssl_md_alg_from_hash( ssl->handshake->sig_alg );
|
/* For TLS 1.2, obey signature-hash-algorithm extension
|
||||||
|
* (RFC 5246, Sec. 7.4.1.4.1). */
|
||||||
|
|
||||||
if( md_alg == POLARSSL_MD_NONE )
|
if( sig_alg == POLARSSL_PK_NONE ||
|
||||||
|
( md_alg = ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_alg ) ) == POLARSSL_MD_NONE )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
||||||
return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
|
return( POLARSSL_ERR_SSL_INTERNAL_ERROR );
|
||||||
@ -2696,6 +2809,8 @@ curve_matching_done:
|
|||||||
md_alg = POLARSSL_MD_NONE;
|
md_alg = POLARSSL_MD_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute the hash to be signed
|
* Compute the hash to be signed
|
||||||
*/
|
*/
|
||||||
@ -2794,8 +2909,8 @@ curve_matching_done:
|
|||||||
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2)
|
||||||
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
|
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
|
||||||
{
|
{
|
||||||
*(p++) = ssl->handshake->sig_alg;
|
*(p++) = ssl_hash_from_md_alg( md_alg );
|
||||||
*(p++) = ssl_sig_from_pk( ssl_own_key( ssl ) );
|
*(p++) = ssl_sig_from_pk_alg( sig_alg );
|
||||||
|
|
||||||
n += 2;
|
n += 2;
|
||||||
}
|
}
|
||||||
|
@ -3526,7 +3526,11 @@ static void ssl_handshake_params_init( ssl_handshake_params *handshake )
|
|||||||
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
|
#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
|
||||||
|
|
||||||
handshake->update_checksum = ssl_update_checksum_start;
|
handshake->update_checksum = ssl_update_checksum_start;
|
||||||
handshake->sig_alg = SSL_HASH_SHA1;
|
|
||||||
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
ssl_sig_hash_set_init( &handshake->hash_algs );
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(POLARSSL_DHM_C)
|
#if defined(POLARSSL_DHM_C)
|
||||||
dhm_init( &handshake->dhm_ctx );
|
dhm_init( &handshake->dhm_ctx );
|
||||||
@ -5166,6 +5170,19 @@ unsigned char ssl_sig_from_pk( pk_context *pk )
|
|||||||
return( SSL_SIG_ANON );
|
return( SSL_SIG_ANON );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char ssl_sig_from_pk_alg( pk_type_t type )
|
||||||
|
{
|
||||||
|
switch( type ) {
|
||||||
|
case POLARSSL_PK_RSA:
|
||||||
|
return( SSL_SIG_RSA );
|
||||||
|
case POLARSSL_PK_ECDSA:
|
||||||
|
case POLARSSL_PK_ECKEY:
|
||||||
|
return( SSL_SIG_ECDSA );
|
||||||
|
default:
|
||||||
|
return( SSL_SIG_ANON );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pk_type_t ssl_pk_alg_from_sig( unsigned char sig )
|
pk_type_t ssl_pk_alg_from_sig( unsigned char sig )
|
||||||
{
|
{
|
||||||
switch( sig )
|
switch( sig )
|
||||||
@ -5184,6 +5201,57 @@ pk_type_t ssl_pk_alg_from_sig( unsigned char sig )
|
|||||||
}
|
}
|
||||||
#endif /* POLARSSL_PK_C */
|
#endif /* POLARSSL_PK_C */
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SSL_PROTO_TLS1_2) && \
|
||||||
|
defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
|
||||||
|
/* Find an entry in a signature-hash set matching a given hash algorithm. */
|
||||||
|
md_type_t ssl_sig_hash_set_find( ssl_sig_hash_set_t *set,
|
||||||
|
pk_type_t sig_alg )
|
||||||
|
{
|
||||||
|
switch( sig_alg )
|
||||||
|
{
|
||||||
|
case POLARSSL_PK_RSA:
|
||||||
|
return( set->rsa );
|
||||||
|
case POLARSSL_PK_ECDSA:
|
||||||
|
return( set->ecdsa );
|
||||||
|
default:
|
||||||
|
return( POLARSSL_MD_NONE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a signature-hash-pair to a signature-hash set */
|
||||||
|
void ssl_sig_hash_set_add( ssl_sig_hash_set_t *set,
|
||||||
|
pk_type_t sig_alg,
|
||||||
|
md_type_t md_alg )
|
||||||
|
{
|
||||||
|
switch( sig_alg )
|
||||||
|
{
|
||||||
|
case POLARSSL_PK_RSA:
|
||||||
|
if( set->rsa == POLARSSL_MD_NONE )
|
||||||
|
set->rsa = md_alg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case POLARSSL_PK_ECDSA:
|
||||||
|
if( set->ecdsa == POLARSSL_MD_NONE )
|
||||||
|
set->ecdsa = md_alg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow exactly one hash algorithm for each signature. */
|
||||||
|
void ssl_sig_hash_set_const_hash( ssl_sig_hash_set_t *set,
|
||||||
|
md_type_t md_alg )
|
||||||
|
{
|
||||||
|
set->rsa = md_alg;
|
||||||
|
set->ecdsa = md_alg;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* POLARSSL_SSL_PROTO_TLS1_2) &&
|
||||||
|
POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert between SSL_HASH_XXX and POLARSSL_MD_XXX
|
* Convert between SSL_HASH_XXX and POLARSSL_MD_XXX
|
||||||
*/
|
*/
|
||||||
@ -5216,6 +5284,38 @@ md_type_t ssl_md_alg_from_hash( unsigned char hash )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert from POLARSSL_MD_XXX to SSL_HASH_XXX
|
||||||
|
*/
|
||||||
|
unsigned char ssl_hash_from_md_alg( md_type_t md )
|
||||||
|
{
|
||||||
|
switch( md )
|
||||||
|
{
|
||||||
|
#if defined(POLARSSL_MD5_C)
|
||||||
|
case POLARSSL_MD_MD5:
|
||||||
|
return( SSL_HASH_MD5 );
|
||||||
|
#endif
|
||||||
|
#if defined(POLARSSL_SHA1_C)
|
||||||
|
case POLARSSL_MD_SHA1:
|
||||||
|
return( SSL_HASH_SHA1 );
|
||||||
|
#endif
|
||||||
|
#if defined(POLARSSL_SHA256_C)
|
||||||
|
case POLARSSL_MD_SHA224:
|
||||||
|
return( SSL_HASH_SHA224 );
|
||||||
|
case POLARSSL_MD_SHA256:
|
||||||
|
return( SSL_HASH_SHA256 );
|
||||||
|
#endif
|
||||||
|
#if defined(POLARSSL_SHA512_C)
|
||||||
|
case POLARSSL_MD_SHA384:
|
||||||
|
return( SSL_HASH_SHA384 );
|
||||||
|
case POLARSSL_MD_SHA512:
|
||||||
|
return( SSL_HASH_SHA512 );
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return( SSL_HASH_NONE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(POLARSSL_SSL_SET_CURVES)
|
#if defined(POLARSSL_SSL_SET_CURVES)
|
||||||
/*
|
/*
|
||||||
* Check is a curve proposed by the peer is in our list.
|
* Check is a curve proposed by the peer is in our list.
|
||||||
@ -5233,6 +5333,30 @@ int ssl_curve_is_acceptable( const ssl_context *ssl, ecp_group_id grp_id )
|
|||||||
}
|
}
|
||||||
#endif /* POLARSSL_SSL_SET_CURVES */
|
#endif /* POLARSSL_SSL_SET_CURVES */
|
||||||
|
|
||||||
|
#if defined(POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
|
/*
|
||||||
|
* Check if a hash proposed by the peer is in our list.
|
||||||
|
* Return 0 if we're willing to use it, -1 otherwise.
|
||||||
|
*/
|
||||||
|
int ssl_check_sig_hash( md_type_t md )
|
||||||
|
{
|
||||||
|
const int *cur;
|
||||||
|
|
||||||
|
for( cur = md_list(); *cur != POLARSSL_MD_NONE; cur++ )
|
||||||
|
{
|
||||||
|
#if !defined(POLARSSL_SSL_ENABLE_MD5_SIGNATURES)
|
||||||
|
/* Skip MD5 */
|
||||||
|
if( *cur == POLARSSL_MD_MD5 )
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
if( *cur == (int) md )
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
#endif /* POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED */
|
||||||
|
|
||||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
int ssl_check_cert_usage( const x509_crt *cert,
|
int ssl_check_cert_usage( const x509_crt *cert,
|
||||||
const ssl_ciphersuite_t *ciphersuite,
|
const ssl_ciphersuite_t *ciphersuite,
|
||||||
|
Loading…
Reference in New Issue
Block a user