fix tls12 openssl/gnutls server fail
To test version negotiation with tls12 OpenSSL/GnuTLS server, If
`rsa_pss_rsae_*` were sent to server before `rsa_pkcs_*`, server
will return `rsa_pss_rsae_*` as key exchange sig alg. OpenSSL/GnuTLS
can work with this case. mbedTLS will fail due to `rsa_pss_rsae_*`
unsupported.
Signed-off-by: Jerry Yu <jerry.h.yu@arm.com>
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 715d036..ff39075 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -1969,107 +1969,103 @@
return( 0 );
}
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
static inline int mbedtls_ssl_tls13_get_pk_type_and_md_alg_from_sig_alg(
uint16_t sig_alg, mbedtls_pk_type_t *pk_type, mbedtls_md_type_t *md_alg )
{
- *pk_type = MBEDTLS_PK_NONE;
- *md_alg = MBEDTLS_MD_NONE;
+ *pk_type = mbedtls_ssl_pk_alg_from_sig( sig_alg & 0xff );
+ *md_alg = mbedtls_ssl_md_alg_from_hash( ( sig_alg >> 8 ) & 0xff );
+
+ if( *pk_type != MBEDTLS_PK_NONE && *md_alg != MBEDTLS_MD_NONE )
+ return( 0 );
switch( sig_alg )
{
-#if defined(MBEDTLS_ECDSA_C)
-
-#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
- case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
- *md_alg = MBEDTLS_MD_SHA256;
- *pk_type = MBEDTLS_PK_ECDSA;
- break;
-#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */
-
-#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
- case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
- *md_alg = MBEDTLS_MD_SHA384;
- *pk_type = MBEDTLS_PK_ECDSA;
- break;
-#endif /* MBEDTLS_SHA384_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
-
-#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
- case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
- *md_alg = MBEDTLS_MD_SHA512;
- *pk_type = MBEDTLS_PK_ECDSA;
- break;
-#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP521R1_ENABLED */
-
-#endif /* MBEDTLS_ECDSA_C */
-
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
-
#if defined(MBEDTLS_SHA256_C)
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
*md_alg = MBEDTLS_MD_SHA256;
*pk_type = MBEDTLS_PK_RSASSA_PSS;
break;
#endif /* MBEDTLS_SHA256_C */
-
#if defined(MBEDTLS_SHA384_C)
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
*md_alg = MBEDTLS_MD_SHA384;
*pk_type = MBEDTLS_PK_RSASSA_PSS;
break;
#endif /* MBEDTLS_SHA384_C */
-
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
*md_alg = MBEDTLS_MD_SHA512;
*pk_type = MBEDTLS_PK_RSASSA_PSS;
break;
#endif /* MBEDTLS_SHA512_C */
-
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_PKCS1_V15) && \
- defined(MBEDTLS_RSA_C)
-
-#if defined(MBEDTLS_SHA256_C)
- case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
- *md_alg = MBEDTLS_MD_SHA256;
- *pk_type = MBEDTLS_PK_RSA;
- break;
-#endif /* MBEDTLS_SHA256_C */
-
-#if defined(MBEDTLS_SHA384_C)
- case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384:
- *md_alg = MBEDTLS_MD_SHA384;
- *pk_type = MBEDTLS_PK_RSA;
- break;
-#endif /* MBEDTLS_SHA384_C */
-
-#if defined(MBEDTLS_SHA512_C)
- case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512:
- *md_alg = MBEDTLS_MD_SHA512;
- *pk_type = MBEDTLS_PK_RSA;
- break;
-#endif /* MBEDTLS_SHA512_C */
-
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_PKCS1_V15 &&
- MBEDTLS_RSA_C */
-
default:
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
}
return( 0 );
}
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
static inline int mbedtls_ssl_tls13_sig_alg_is_supported(
const uint16_t sig_alg )
{
- mbedtls_pk_type_t pk_type;
- mbedtls_md_type_t md_alg;
- return( ! mbedtls_ssl_tls13_get_pk_type_and_md_alg_from_sig_alg(
- sig_alg, &pk_type, &md_alg ) );
+ switch( sig_alg )
+ {
+#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+ case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
+ break;
+#endif /* MBEDTLS_SHA256_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+#if defined(MBEDTLS_SHA384_C) && defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+ case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
+ break;
+#endif /* MBEDTLS_SHA384_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+ case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
+ break;
+#endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP521R1_ENABLED */
+#endif /* MBEDTLS_ECDSA_C */
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
+ break;
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA384_C)
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
+ break;
+#endif /* MBEDTLS_SHA384_C */
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
+ break;
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C)
+
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
+ break;
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA384_C)
+ case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384:
+ break;
+#endif /* MBEDTLS_SHA384_C */
+
+#if defined(MBEDTLS_SHA512_C)
+ case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512:
+ break;
+#endif /* MBEDTLS_SHA512_C */
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C */
+
+
+ default:
+ return( 0 );
+ }
+ return( 1 );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index f516efa..25c1797 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -2010,65 +2010,6 @@
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
-static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
- unsigned char **p,
- unsigned char *end,
- mbedtls_md_type_t *md_alg,
- mbedtls_pk_type_t *pk_alg )
-{
- *md_alg = MBEDTLS_MD_NONE;
- *pk_alg = MBEDTLS_PK_NONE;
-
- if( (*p) + 2 > end )
- return( MBEDTLS_ERR_SSL_DECODE_ERROR );
-
- /*
- * Get hash algorithm
- */
- if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) )
- == MBEDTLS_MD_NONE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1,
- ( "Server used unsupported HashAlgorithm %d", *(p)[0] ) );
- return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
- }
-
- /*
- * Get signature algorithm
- */
- if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) )
- == MBEDTLS_PK_NONE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1,
- ( "server used unsupported SignatureAlgorithm %d", (*p)[1] ) );
- return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
- }
-
- /*
- * Check if the signature algorithm is acceptable
- */
- if( !mbedtls_ssl_sig_alg_is_offered( ssl, MBEDTLS_GET_UINT16_BE( *p, 0 ) ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1,
- ( "server used HashAlgorithm %d that was not offered", *(p)[0] ) );
- return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d",
- (*p)[1] ) );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d",
- (*p)[0] ) );
- *p += 2;
-
- return( 0 );
-}
-#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
-
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
@@ -2362,14 +2303,31 @@
unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
size_t params_len = p - params;
void *rs_ctx = NULL;
+ uint16_t sig_alg;
mbedtls_pk_context * peer_pk;
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ peer_pk = &ssl->handshake->peer_pubkey;
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( ssl->session_negotiate->peer_cert == NULL )
+ {
+ /* Should never happen */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ peer_pk = &ssl->session_negotiate->peer_cert->pk;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
/*
* Handle the digitally-signed structure
*/
- if( ssl_parse_signature_algorithm( ssl, &p, end,
- &md_alg, &pk_alg ) != 0 )
+ MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
+ sig_alg = MBEDTLS_GET_UINT16_BE( p, 0 );
+ if( mbedtls_ssl_tls13_get_pk_type_and_md_alg_from_sig_alg(
+ sig_alg, &pk_alg, &md_alg ) != 0 &&
+ ! mbedtls_ssl_sig_alg_is_offered( ssl, sig_alg ) &&
+ ! mbedtls_ssl_sig_alg_is_supported( ssl, sig_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "bad server key exchange message" ) );
@@ -2379,9 +2337,9 @@
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
}
+ p += 2;
- if( pk_alg !=
- mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
+ if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "bad server key exchange message" ) );
@@ -2439,18 +2397,6 @@
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
-#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- peer_pk = &ssl->handshake->peer_pubkey;
-#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- if( ssl->session_negotiate->peer_cert == NULL )
- {
- /* Should never happen */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- peer_pk = &ssl->session_negotiate->peer_cert->pk;
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-
/*
* Verify signature
*/
@@ -2469,8 +2415,28 @@
rs_ctx = &ssl->handshake->ecrs_ctx.pk;
#endif
- if( ( ret = mbedtls_pk_verify_restartable( peer_pk,
- md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 )
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+ if( pk_alg == MBEDTLS_PK_RSASSA_PSS )
+ {
+ const mbedtls_md_info_t* md_info;
+ mbedtls_pk_rsassa_pss_options rsassa_pss_options;
+ rsassa_pss_options.mgf1_hash_id = md_alg;
+ if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
+ {
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ rsassa_pss_options.expected_salt_len = mbedtls_md_get_size( md_info );
+ ret = mbedtls_pk_verify_ext( pk_alg, &rsassa_pss_options,
+ peer_pk,
+ md_alg, hash, hashlen,
+ p, sig_len );
+ }
+ else
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+ ret = mbedtls_pk_verify_restartable( peer_pk,
+ md_alg, hash, hashlen, p, sig_len, rs_ctx );
+
+ if( ret != 0 )
{
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )