Merge remote-tracking branch 'hanno/sig_hash_compatibility' into development

* hanno/sig_hash_compatibility:
  Improve documentation
  Split long lines
  Remember suitable hash function for any signature algorithm.
  Introduce macros and functions to characterize certain ciphersuites.
This commit is contained in:
Manuel Pégourié-Gonnard 2017-06-06 18:14:57 +02:00
commit 23b33f8663
8 changed files with 623 additions and 184 deletions

View file

@ -1,9 +1,11 @@
mbed TLS ChangeLog (Sorted per branch, date) mbed TLS ChangeLog (Sorted per branch, date)
= mbed TLS x.x.x branch released xxxx-xx-xx mbed TLS 2.x.x branch released xxxx-xx-xx
Bugfix Bugfix
* Remove invalid use of size zero arrays in ECJPAKE test suite. * Remove invalid use of size zero arrays in ECJPAKE test suite.
* Fix insufficient support for signature-hash-algorithm extension,
resulting in compatibility problems with Chrome. Found by hfloyrd. #823
= mbed TLS 2.5.0 branch released 2017-05-17 = mbed TLS 2.5.0 branch released 2017-05-17

View file

@ -534,6 +534,7 @@ typedef struct mbedtls_ssl_config mbedtls_ssl_config;
/* Defined in ssl_internal.h */ /* Defined in ssl_internal.h */
typedef struct mbedtls_ssl_transform mbedtls_ssl_transform; typedef struct mbedtls_ssl_transform mbedtls_ssl_transform;
typedef struct mbedtls_ssl_handshake_params mbedtls_ssl_handshake_params; typedef struct mbedtls_ssl_handshake_params mbedtls_ssl_handshake_params;
typedef struct mbedtls_ssl_sig_hash_set_t mbedtls_ssl_sig_hash_set_t;
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert; typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert;
#endif #endif

View file

@ -260,6 +260,47 @@ typedef enum {
#define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED #define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED
#endif #endif
/* Key exchanges allowing client certificate requests */
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED
#endif
/* Key exchanges involving server signature in ServerKeyExchange */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED
#endif
/* Key exchanges using ECDH */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED
#endif
/* Key exchanges that don't involve ephemeral keys */
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED
#endif
/* Key exchanges that involve ephemeral keys */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED
#endif
/* Key exchanges using a PSK */ /* Key exchanges using a PSK */
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
@ -268,7 +309,13 @@ typedef enum {
#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED #define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED
#endif #endif
/* Key exchanges using a ECDHE */ /* Key exchanges using DHE */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED
#endif
/* Key exchanges using ECDHE */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
@ -309,10 +356,159 @@ const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuit
#if defined(MBEDTLS_PK_C) #if defined(MBEDTLS_PK_C)
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ); mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info );
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info );
#endif #endif
int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info ); #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ); static inline int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
return( 1 );
default:
return( 0 );
}
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
return( 1 );
default:
return( 0 );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
case MBEDTLS_KEY_EXCHANGE_RSA:
case MBEDTLS_KEY_EXCHANGE_PSK:
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
return( 1 );
default:
return( 0 );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
return( 1 );
default:
return( 0 );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_PSK:
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
return( 1 );
default:
return( 0 );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_RSA:
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return( 1 );
default:
return( 0 );
}
}
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
return( 1 );
default:
return( 0 );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
return( 1 );
default:
return( 0 );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) */
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_server_signature( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return( 1 );
default:
return( 0 );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -157,6 +157,24 @@
extern "C" { extern "C" {
#endif #endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
/*
* Abstraction for a grid of allowed signature-hash-algorithm pairs.
*/
struct mbedtls_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. */
mbedtls_md_type_t rsa;
mbedtls_md_type_t ecdsa;
};
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
/* /*
* This structure contains the parameters only needed during handshake. * This structure contains the parameters only needed during handshake.
*/ */
@ -165,8 +183,11 @@ struct mbedtls_ssl_handshake_params
/* /*
* Handshake specific crypto variables * Handshake specific crypto variables
*/ */
int sig_alg; /*!< Hash algorithm for signature */
int verify_sig_alg; /*!< Signature algorithm for verify */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
mbedtls_ssl_sig_hash_set_t hash_algs; /*!< Set of suitable sig-hash pairs */
#endif
#if defined(MBEDTLS_DHM_C) #if defined(MBEDTLS_DHM_C)
mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */
#endif #endif
@ -179,7 +200,7 @@ struct mbedtls_ssl_handshake_params
unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */ unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */
size_t ecjpake_cache_len; /*!< Length of cached data */ size_t ecjpake_cache_len; /*!< Length of cached data */
#endif #endif
#endif #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */ const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */
@ -195,7 +216,7 @@ struct mbedtls_ssl_handshake_params
mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */
mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */ mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */
mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */ mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */
#endif #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#endif /* MBEDTLS_X509_CRT_PARSE_C */ #endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_PROTO_DTLS)
unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */ unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */
@ -218,7 +239,7 @@ struct mbedtls_ssl_handshake_params
resending messages */ resending messages */
unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter
for resending messages */ for resending messages */
#endif #endif /* MBEDTLS_SSL_PROTO_DTLS */
/* /*
* Checksum contexts * Checksum contexts
@ -329,6 +350,28 @@ struct mbedtls_ssl_flight_item
}; };
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
/* Find an entry in a signature-hash set matching a given hash algorithm. */
mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
mbedtls_pk_type_t sig_alg );
/* Add a signature-hash-pair to a signature-hash set */
void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
mbedtls_pk_type_t sig_alg,
mbedtls_md_type_t md_alg );
/* Allow exactly one hash algorithm for each signature. */
void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
mbedtls_md_type_t md_alg );
/* Setup an empty signature-hash set */
static inline void mbedtls_ssl_sig_hash_set_init( mbedtls_ssl_sig_hash_set_t *set )
{
mbedtls_ssl_sig_hash_set_const_hash( set, MBEDTLS_MD_NONE );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
/** /**
* \brief Free referenced items in an SSL transform context and clear * \brief Free referenced items in an SSL transform context and clear
@ -384,6 +427,7 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
#if defined(MBEDTLS_PK_C) #if defined(MBEDTLS_PK_C)
unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ); unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk );
unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type );
mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig );
#endif #endif

View file

@ -1817,41 +1817,23 @@ mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciph
return( MBEDTLS_PK_NONE ); return( MBEDTLS_PK_NONE );
} }
} }
mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_RSA:
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
return( MBEDTLS_PK_RSA );
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return( MBEDTLS_PK_ECDSA );
default:
return( MBEDTLS_PK_NONE );
}
}
#endif /* MBEDTLS_PK_C */ #endif /* MBEDTLS_PK_C */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
return( 1 );
default:
return( 0 );
}
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_PSK:
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
return( 1 );
default:
return( 0 );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
#endif /* MBEDTLS_SSL_TLS_C */ #endif /* MBEDTLS_SSL_TLS_C */

View file

@ -1991,7 +1991,8 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
if( (*p) + len > end ) if( (*p) + len > end )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
"(psk_identity_hint length)" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
@ -2192,7 +2193,8 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
{ {
int ret; int ret;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
unsigned char *p, *end; unsigned char *p, *end;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
@ -2332,12 +2334,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
{ {
size_t sig_len, hashlen; size_t sig_len, hashlen;
unsigned char hash[64]; unsigned char hash[64];
@ -2506,9 +2504,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
return( ret ); return( ret );
} }
} }
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
exit: exit:
ssl->state++; ssl->state++;
@ -2518,23 +2514,15 @@ exit:
return( 0 ); return( 0 );
} }
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ #if ! defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED)
!defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{ {
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
ssl->state++; ssl->state++;
@ -2544,22 +2532,19 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
#else #else /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{ {
int ret; int ret;
unsigned char *buf; unsigned char *buf;
size_t n = 0; size_t n = 0;
size_t cert_type_len = 0, dn_len = 0; size_t cert_type_len = 0, dn_len = 0;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
ssl->state++; ssl->state++;
@ -2645,7 +2630,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
for( i = 0; i < sig_alg_len; i += 2 ) for( i = 0; i < sig_alg_len; i += 2 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d,%d", sig_alg[i], sig_alg[i + 1] ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d"
",%d", sig_alg[i], sig_alg[i + 1] ) );
} }
#endif #endif
@ -2675,12 +2661,7 @@ exit:
return( 0 ); return( 0 );
} }
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && #endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
{ {
@ -2727,7 +2708,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
{ {
int ret; int ret;
size_t i, n; size_t i, n;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
@ -2814,10 +2796,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{ {
/* /*
* opaque psk_identity<0..2^16-1>; * opaque psk_identity<0..2^16-1>;
@ -2987,7 +2966,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{ {
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
int ret; int ret;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
@ -3016,7 +2996,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{ {
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
size_t n = 0, offset = 0; size_t n = 0, offset = 0;
unsigned char hash[48]; unsigned char hash[48];
unsigned char *hash_start = hash; unsigned char *hash_start = hash;

View file

@ -186,15 +186,30 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) defined(MBEDTLS_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( mbedtls_ssl_context *ssl, static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf, const unsigned char *buf,
size_t len ) size_t len )
{ {
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;
mbedtls_md_type_t md_cur;
mbedtls_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 ||
@ -204,29 +219,49 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_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 = ssl->conf->sig_hashes; *md_cur != MBEDTLS_MD_NONE; md_cur++ ) {
for( p = buf + 2; p < end; p += 2 ) { for( p = buf + 2; p < end; p += 2 )
if( *md_cur == (int) mbedtls_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 = mbedtls_ssl_pk_alg_from_sig( p[1] ) ) == MBEDTLS_PK_NONE )
{
MBEDTLS_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 = mbedtls_ssl_md_alg_from_hash( p[0] );
if( md_cur == MBEDTLS_MD_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:"
" unknown hash alg encoding %d", p[0] ) );
continue;
}
if( mbedtls_ssl_check_sig_hash( ssl, md_cur ) == 0 )
{
mbedtls_ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:"
" match sig %d and hash %d",
sig_cur, md_cur ) );
}
else
{
MBEDTLS_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 */
MBEDTLS_SSL_DEBUG_MSG( 3, ( "no signature_algorithm in common" ) );
return( 0 );
have_sig_alg:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d",
ssl->handshake->sig_alg ) );
return( 0 ); return( 0 );
} }
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
@ -607,7 +642,8 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
const mbedtls_ssl_ciphersuite_t * ciphersuite_info ) const mbedtls_ssl_ciphersuite_t * ciphersuite_info )
{ {
mbedtls_ssl_key_cert *cur, *list, *fallback = NULL; mbedtls_ssl_key_cert *cur, *list, *fallback = NULL;
mbedtls_pk_type_t pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); mbedtls_pk_type_t pk_alg =
mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
uint32_t flags; uint32_t flags;
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@ -710,6 +746,11 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
{ {
const mbedtls_ssl_ciphersuite_t *suite_info; const mbedtls_ssl_ciphersuite_t *suite_info;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
mbedtls_pk_type_t sig_type;
#endif
suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id ); suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id );
if( suite_info == NULL ) if( suite_info == NULL )
{ {
@ -776,6 +817,25 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
} }
#endif #endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
/* If the ciphersuite requires signing, check whether
* a suitable hash algorithm is present. */
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
sig_type = mbedtls_ssl_get_ciphersuite_sig_alg( suite_info );
if( sig_type != MBEDTLS_PK_NONE &&
mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == MBEDTLS_MD_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm "
"for signature algorithm %d", sig_type ) );
return( 0 );
}
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
/* /*
* Final check: if ciphersuite requires us to have a * Final check: if ciphersuite requires us to have a
@ -1085,6 +1145,15 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
const mbedtls_ssl_ciphersuite_t *ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
int major, minor; int major, minor;
/* If there is no signature-algorithm extension present,
* we need to fall back to the default values for allowed
* signature-hash pairs. */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
int sig_hash_alg_ext_present = 0;
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
@ -1204,7 +1273,8 @@ read_record_header:
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 ) if( ( ret = mbedtls_ssl_fetch_input( ssl,
mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
return( ret ); return( ret );
@ -1582,10 +1652,11 @@ read_record_header:
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
break; break;
#endif #endif
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 /* MBEDTLS_SSL_PROTO_TLS1_2 && #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
@ -1722,6 +1793,26 @@ read_record_header:
} }
#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ #endif /* MBEDTLS_SSL_FALLBACK_SCSV */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_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 )
{
mbedtls_md_type_t md_default = MBEDTLS_MD_SHA1;
if( mbedtls_ssl_check_sig_hash( ssl, md_default ) != 0 )
md_default = MBEDTLS_MD_NONE;
mbedtls_ssl_sig_hash_set_const_hash( &ssl->handshake->hash_algs, md_default );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
/* /*
* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
*/ */
@ -1733,7 +1824,8 @@ read_record_header:
#if defined(MBEDTLS_SSL_RENEGOTIATION) #if defined(MBEDTLS_SSL_RENEGOTIATION)
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV "
"during renegotiation" ) );
if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
return( ret ); return( ret );
@ -1847,6 +1939,28 @@ have_ciphersuite:
mbedtls_ssl_recv_flight_completed( ssl ); mbedtls_ssl_recv_flight_completed( ssl );
#endif #endif
/* Debugging-only output for testsuite */
#if defined(MBEDTLS_DEBUG_C) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info );
if( sig_alg != MBEDTLS_PK_NONE )
{
mbedtls_md_type_t md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs,
sig_alg );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d",
mbedtls_ssl_hash_from_md_alg( md_alg ) ) );
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "no hash algorithm for signature algorithm "
"%d - should not happen", sig_alg ) );
}
}
#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) );
return( 0 ); return( 0 );
@ -2452,7 +2566,8 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{ {
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
@ -2474,7 +2589,8 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{ {
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
size_t dn_size, total_dn_size; /* excluding length bytes */ size_t dn_size, total_dn_size; /* excluding length bytes */
size_t ct_len, sa_len; /* including length bytes */ size_t ct_len, sa_len; /* including length bytes */
unsigned char *buf, *p; unsigned char *buf, *p;
@ -2675,74 +2791,81 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info; ssl->transform_negotiate->ciphersuite_info;
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
unsigned char *p = ssl->out_msg + 4; unsigned char *p = ssl->out_msg + 4;
size_t len;
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
unsigned char *dig_signed = p; unsigned char *dig_signed = p;
size_t dig_signed_len = 0, len; size_t dig_signed_len = 0;
((void) dig_signed); #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
((void) dig_signed_len); #endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
((void) len);
#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ /*
defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ *
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) * Part 1: Extract static ECDH parameters and abort
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA || * if ServerKeyExchange not needed.
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || *
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) */
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
ssl->state++;
return( 0 );
}
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ /* For suites involving ECDH, extract DH parameters
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) * from certificate at this point. */
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || #if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
{ {
ssl_get_ecdh_params_from_cert( ssl ); ssl_get_ecdh_params_from_cert( ssl );
}
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
/* Key exchanges not involving ephemeral keys don't use
* ServerKeyExchange, so end here. */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
ssl->state++; ssl->state++;
return( 0 ); return( 0 );
} }
#endif #endif /* MBEDTLS_KEY_EXCHANGE__NON_PFS__ENABLED */
/*
*
* Part 2: Provide key exchange parameters for chosen ciphersuite.
*
*/
/*
* - ECJPAKE key exchanges
*/
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
size_t jlen;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
p, end - p, &jlen, ssl->conf->f_rng, ssl->conf->p_rng ); p, end - p, &len, ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 ) if( ret != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
return( ret ); return( ret );
} }
p += jlen; p += len;
n += jlen; n += len;
} }
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ /*
* For (EC)DHE key exchanges with PSK, parameters are prefixed by support
* identity hint (RFC 4279, Sec. 3). Until someone needs this feature,
* we use empty support identity hints here.
**/
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{ {
/* Note: we don't support identity hints, until someone asks
* for them. */
*(p++) = 0x00; *(p++) = 0x00;
*(p++) = 0x00; *(p++) = 0x00;
@ -2751,10 +2874,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ /*
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) * - DHE key exchanges
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || */
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) )
{ {
if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL ) if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL )
{ {
@ -2786,8 +2910,10 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
return( ret ); return( ret );
} }
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
dig_signed = p; dig_signed = p;
dig_signed_len = len; dig_signed_len = len;
#endif
p += len; p += len;
n += len; n += len;
@ -2797,13 +2923,13 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
} }
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || #endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED */
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
/*
* - ECDHE key exchanges
*/
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || if( mbedtls_ssl_ciphersuite_uses_ecdhe( ciphersuite_info ) )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{ {
/* /*
* Ephemeral ECDH parameters: * Ephemeral ECDH parameters:
@ -2846,8 +2972,10 @@ curve_matching_done:
return( ret ); return( ret );
} }
dig_signed = p; #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
dig_signed = p;
dig_signed_len = len; dig_signed_len = len;
#endif
p += len; p += len;
n += len; n += len;
@ -2856,29 +2984,44 @@ curve_matching_done:
} }
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ /*
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ *
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) * Part 3: For key exchanges involving the server signing the
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || * exchange parameters, compute and add the signature here.
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || *
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) */
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
{ {
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];
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
/* /*
* Choose hash algorithm. NONE means MD5 + SHA1 here. * 3.1: Choose hash algorithm:
* A: For TLS 1.2, obey signature-hash-algorithm extension
* to choose appropriate hash.
* B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1
* (RFC 4492, Sec. 5.4)
* C: Otherwise, use MD5 + SHA1 (RFC 4346, Sec. 7.4.3)
*/ */
mbedtls_md_type_t md_alg;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
mbedtls_pk_type_t sig_alg =
mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{ {
md_alg = mbedtls_ssl_md_alg_from_hash( ssl->handshake->sig_alg ); /* A: For TLS 1.2, obey signature-hash-algorithm extension
* (RFC 5246, Sec. 7.4.1.4.1). */
if( md_alg == MBEDTLS_MD_NONE ) if( sig_alg == MBEDTLS_PK_NONE ||
( md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs,
sig_alg ) ) == MBEDTLS_MD_NONE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
/* (... because we choose a cipher suite
* only if there is a matching hash.) */
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
} }
@ -2886,19 +3029,23 @@ curve_matching_done:
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1) defined(MBEDTLS_SSL_PROTO_TLS1_1)
if( ciphersuite_info->key_exchange == if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
{ {
/* B: Default hash SHA1 */
md_alg = MBEDTLS_MD_SHA1; md_alg = MBEDTLS_MD_SHA1;
} }
else else
#endif #endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
MBEDTLS_SSL_PROTO_TLS1_1 */
{ {
/* C: MD5 + SHA1 */
md_alg = MBEDTLS_MD_NONE; md_alg = MBEDTLS_MD_NONE;
} }
MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) );
/* /*
* Compute the hash to be signed * 3.2: Compute the hash to be signed
*/ */
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1) defined(MBEDTLS_SSL_PROTO_TLS1_1)
@ -2923,6 +3070,7 @@ curve_matching_done:
* SHA(ClientHello.random + ServerHello.random * SHA(ClientHello.random + ServerHello.random
* + ServerParams); * + ServerParams);
*/ */
mbedtls_md5_starts( &mbedtls_md5 ); mbedtls_md5_starts( &mbedtls_md5 );
mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 ); mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 );
mbedtls_md5_update( &mbedtls_md5, dig_signed, dig_signed_len ); mbedtls_md5_update( &mbedtls_md5, dig_signed, dig_signed_len );
@ -2984,7 +3132,7 @@ curve_matching_done:
(unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) ); (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
/* /*
* Make the signature * 3.3: Compute and add the signature
*/ */
if( mbedtls_ssl_own_key( ssl ) == NULL ) if( mbedtls_ssl_own_key( ssl ) == NULL )
{ {
@ -2995,16 +3143,31 @@ curve_matching_done:
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{ {
*(p++) = ssl->handshake->sig_alg; /*
*(p++) = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) ); * For TLS 1.2, we need to specify signature and hash algorithm
* explicitly through a prefix to the signature.
*
* struct {
* HashAlgorithm hash;
* SignatureAlgorithm signature;
* } SignatureAndHashAlgorithm;
*
* struct {
* SignatureAndHashAlgorithm algorithm;
* opaque signature<0..2^16-1>;
* } DigitallySigned;
*
*/
*(p++) = mbedtls_ssl_hash_from_md_alg( md_alg );
*(p++) = mbedtls_ssl_sig_from_pk_alg( sig_alg );
n += 2; n += 2;
} }
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen, if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen,
p + 2 , &signature_len, p + 2 , &signature_len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
return( ret ); return( ret );
@ -3018,9 +3181,9 @@ curve_matching_done:
n += signature_len; n += signature_len;
} }
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ /* Done with actual work; add header and send. */
ssl->out_msglen = 4 + n; ssl->out_msglen = 4 + n;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
@ -3536,7 +3699,8 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{ {
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
@ -3566,7 +3730,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
mbedtls_pk_type_t pk_alg; mbedtls_pk_type_t pk_alg;
#endif #endif
mbedtls_md_type_t md_alg; mbedtls_md_type_t md_alg;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );

View file

@ -5244,7 +5244,11 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
handshake->update_checksum = ssl_update_checksum_start; handshake->update_checksum = ssl_update_checksum_start;
handshake->sig_alg = MBEDTLS_SSL_HASH_SHA1;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs );
#endif
#if defined(MBEDTLS_DHM_C) #if defined(MBEDTLS_DHM_C)
mbedtls_dhm_init( &handshake->dhm_ctx ); mbedtls_dhm_init( &handshake->dhm_ctx );
@ -7387,6 +7391,19 @@ unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk )
return( MBEDTLS_SSL_SIG_ANON ); return( MBEDTLS_SSL_SIG_ANON );
} }
unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type )
{
switch( type ) {
case MBEDTLS_PK_RSA:
return( MBEDTLS_SSL_SIG_RSA );
case MBEDTLS_PK_ECDSA:
case MBEDTLS_PK_ECKEY:
return( MBEDTLS_SSL_SIG_ECDSA );
default:
return( MBEDTLS_SSL_SIG_ANON );
}
}
mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ) mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig )
{ {
switch( sig ) switch( sig )
@ -7405,6 +7422,57 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig )
} }
#endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */ #endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
/* Find an entry in a signature-hash set matching a given hash algorithm. */
mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
mbedtls_pk_type_t sig_alg )
{
switch( sig_alg )
{
case MBEDTLS_PK_RSA:
return( set->rsa );
case MBEDTLS_PK_ECDSA:
return( set->ecdsa );
default:
return( MBEDTLS_MD_NONE );
}
}
/* Add a signature-hash-pair to a signature-hash set */
void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
mbedtls_pk_type_t sig_alg,
mbedtls_md_type_t md_alg )
{
switch( sig_alg )
{
case MBEDTLS_PK_RSA:
if( set->rsa == MBEDTLS_MD_NONE )
set->rsa = md_alg;
break;
case MBEDTLS_PK_ECDSA:
if( set->ecdsa == MBEDTLS_MD_NONE )
set->ecdsa = md_alg;
break;
default:
break;
}
}
/* Allow exactly one hash algorithm for each signature. */
void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
mbedtls_md_type_t md_alg )
{
set->rsa = md_alg;
set->ecdsa = md_alg;
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
/* /*
* Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
*/ */