tls13: server: Add sig alg checks when selecting best certificate
When selecting the server certificate based on
the signature algorithms supported by the client,
check the signature algorithms as close as possible
to the way they are checked to compute the
signature for the server to prove it possesses
the private key associated to the certificate.
That way we minimize the odds of selecting a
certificate for which the server will not be
able to compute the signature to prove it
possesses the private key associated to the
certificate.
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index a10e59b..a854080 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -898,6 +898,34 @@
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+static psa_algorithm_t ssl_tls13_iana_sig_alg_to_psa_alg( uint16_t sig_alg )
+{
+ switch( sig_alg )
+ {
+ case MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256:
+ return( PSA_ALG_ECDSA( PSA_ALG_SHA_256 ) );
+ case MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384:
+ return( PSA_ALG_ECDSA( PSA_ALG_SHA_384 ) );
+ case MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512:
+ return( PSA_ALG_ECDSA( PSA_ALG_SHA_512 ) );
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256:
+ return( PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ) );
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384:
+ return( PSA_ALG_RSA_PSS( PSA_ALG_SHA_384 ) );
+ case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512:
+ return( PSA_ALG_RSA_PSS( PSA_ALG_SHA_512 ) );
+ case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256:
+ case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384:
+ case MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512:
+ return( PSA_ALG_RSA_PKCS1V15_CRYPT );
+ default:
+ return( PSA_ALG_NONE );
+ }
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
/*
* Pick best ( private key, certificate chain ) pair based on the signature
* algorithms supported by the client.
@@ -923,9 +951,19 @@
for( ; *sig_alg != MBEDTLS_TLS1_3_SIG_NONE; sig_alg++ )
{
+ if( !mbedtls_ssl_sig_alg_is_offered( ssl, *sig_alg ) )
+ continue;
+
+ if( !mbedtls_ssl_tls13_sig_alg_for_cert_verify_is_supported( *sig_alg ) )
+ continue;
+
for( key_cert = key_cert_list; key_cert != NULL;
key_cert = key_cert->next )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_algorithm_t psa_alg = PSA_ALG_NONE;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
MBEDTLS_SSL_DEBUG_CRT( 3, "certificate (chain) candidate",
key_cert->cert );
@@ -949,8 +987,18 @@
"check signature algorithm %s [%04x]",
mbedtls_ssl_sig_alg_to_str( *sig_alg ),
*sig_alg ) );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_alg = ssl_tls13_iana_sig_alg_to_psa_alg( *sig_alg );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
if( mbedtls_ssl_tls13_check_sig_alg_cert_key_match(
- *sig_alg, &key_cert->cert->pk ) )
+ *sig_alg, &key_cert->cert->pk )
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ && psa_alg != PSA_ALG_NONE &&
+ mbedtls_pk_can_do_ext( &key_cert->cert->pk, psa_alg,
+ PSA_KEY_USAGE_SIGN_HASH ) == 1
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ )
{
ssl->handshake->key_cert = key_cert;
MBEDTLS_SSL_DEBUG_MSG( 3,