From 74b89f605116fec08bc9f67746639e2b5fe82c24 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Sun, 17 Feb 2019 21:22:07 +0000 Subject: [PATCH] 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. --- library/ssl_srv.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/library/ssl_srv.c b/library/ssl_srv.c index e886cd36a2..8ac7dd49bd 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -797,10 +797,19 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, 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 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, #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;