Use private key to check suitability of PK type when picking srv CRT
The server-side routine `ssl_pick_cert()` is responsible for
picking a suitable CRT from the list of CRTs configured on the
server. For that, it previously used the public key context
from the certificate to check whether its type (including the
curve type for ECC keys) suits the ciphersuite and the client's
preferences.
This commit changes the code to instead use the PK context
holding the corresponding private key. For inferring the type
of the key, this makes no difference, and it removes a PK-from-CRT
extraction step which, if CRTs are stored raw, is costly in terms
of computation and memory: CRTs need to be parsed, and memory needs
to be allocated for the PK context.
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index e886cd3..8ac7dd4 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -797,10 +797,19 @@
for( cur = list; cur != NULL; cur = cur->next )
{
- MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
- cur->cert );
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ /* ASYNC_PRIVATE may use a NULL entry for the opaque private key, so
+ * we have to use the public key context to infer the capabilities
+ * of the key. */
+ mbedtls_pk_context *pk = &cur->cert->pk;
+#else
+ /* Outside of ASYNC_PRIVATE, use private key context directly
+ * instead of querying for the public key context from the
+ * certificate, so save a few bytes of code. */
+ mbedtls_pk_context *pk = cur->key;
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
- if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) )
+ if( ! mbedtls_pk_can_do( pk, pk_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
continue;
@@ -824,7 +833,7 @@
#if defined(MBEDTLS_ECDSA_C)
if( pk_alg == MBEDTLS_PK_ECDSA &&
- ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 )
+ ssl_check_key_curve( pk, ssl->handshake->curves ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
continue;