diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 40d7187c34..ecb2d03906 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1678,6 +1678,8 @@ static inline mbedtls_x509_crt *mbedtls_ssl_own_cert(mbedtls_ssl_context *ssl) * keyUsage and extendedKeyUsage. * (Note: nSCertType is deprecated and not standard, we don't check it.) * + * Note: if tls_version is 1.3, ciphersuite is ignored and can be NULL. + * * Note: recv_endpoint is the receiver's endpoint. * * Return 0 if everything is OK, -1 if not. @@ -1686,6 +1688,7 @@ MBEDTLS_CHECK_RETURN_CRITICAL int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert, const mbedtls_ssl_ciphersuite_t *ciphersuite, int recv_endpoint, + mbedtls_ssl_protocol_version tls_version, uint32_t *flags); #endif /* MBEDTLS_X509_CRT_PARSE_C */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 4376146b5d..3f375be92c 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -6362,6 +6362,7 @@ const char *mbedtls_ssl_get_curve_name_from_tls_id(uint16_t tls_id) int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert, const mbedtls_ssl_ciphersuite_t *ciphersuite, int recv_endpoint, + mbedtls_ssl_protocol_version tls_version, uint32_t *flags) { int ret = 0; @@ -6369,11 +6370,17 @@ int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert, const char *ext_oid; size_t ext_len; + /* + * keyUsage + */ + /* Note: don't guard this with MBEDTLS_SSL_CLI_C because the server wants * to check what a compliant client will think while choosing which cert * to send to the client. */ - if (recv_endpoint == MBEDTLS_SSL_IS_CLIENT) { - /* Server part of the key exchange */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if (tls_version == MBEDTLS_SSL_VERSION_TLS1_2 && + recv_endpoint == MBEDTLS_SSL_IS_CLIENT) { + /* TLS 1.2 server part of the key exchange */ switch (ciphersuite->key_exchange) { case MBEDTLS_KEY_EXCHANGE_RSA: case MBEDTLS_KEY_EXCHANGE_RSA_PSK: @@ -6399,8 +6406,14 @@ int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert, case MBEDTLS_KEY_EXCHANGE_ECJPAKE: usage = 0; } - } else { - /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */ + } else +#endif + { + /* This is either TLS 1.3 autentication, which always uses signatures, + * or 1.2 client auth: rsa_sign and mbedtls_ecdsa_sign are the only + * options we implement, both using signatures. */ + (void) tls_version; + (void) ciphersuite; usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; } @@ -6409,6 +6422,10 @@ int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert, ret = -1; } + /* + * extKeyUsage + */ + if (recv_endpoint == MBEDTLS_SSL_IS_CLIENT) { ext_oid = MBEDTLS_OID_SERVER_AUTH; ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH); @@ -8065,6 +8082,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl, if (mbedtls_ssl_check_cert_usage(chain, ciphersuite_info, ssl->conf->endpoint, + MBEDTLS_SSL_VERSION_TLS1_2, &ssl->session_negotiate->verify_result) != 0) { MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)")); if (ret == 0) { diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 5bfab04adc..0878749464 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -756,7 +756,9 @@ static int ssl_pick_cert(mbedtls_ssl_context *ssl, * and decrypting with the same RSA key. */ if (mbedtls_ssl_check_cert_usage(cur->cert, ciphersuite_info, - MBEDTLS_SSL_IS_CLIENT, &flags) != 0) { + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_VERSION_TLS1_2, + &flags) != 0) { MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: " "(extended) key usage extension")); continue; diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index 651a17b5a2..8d8af2b19e 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -631,8 +631,6 @@ static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl) int authmode = MBEDTLS_SSL_VERIFY_REQUIRED; mbedtls_x509_crt *ca_chain; mbedtls_x509_crl *ca_crl; - const char *ext_oid; - size_t ext_len; uint32_t verify_result = 0; /* If SNI was used, overwrite authentication mode @@ -714,34 +712,15 @@ static int ssl_tls13_validate_certificate(mbedtls_ssl_context *ssl) /* * Secondary checks: always done, but change 'ret' only if it was 0 */ - /* keyUsage */ - if ((mbedtls_x509_crt_check_key_usage( - ssl->session_negotiate->peer_cert, - MBEDTLS_X509_KU_DIGITAL_SIGNATURE) != 0)) { + if (mbedtls_ssl_check_cert_usage(ssl->session_negotiate->peer_cert, + NULL, + ssl->conf->endpoint, + MBEDTLS_SSL_VERSION_TLS1_3, + &verify_result) != 0) { MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)")); if (ret == 0) { ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE; } - verify_result |= MBEDTLS_X509_BADCERT_KEY_USAGE; - } - - /* extKeyUsage */ - if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - ext_oid = MBEDTLS_OID_SERVER_AUTH; - ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH); - } else { - ext_oid = MBEDTLS_OID_CLIENT_AUTH; - ext_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH); - } - - if ((mbedtls_x509_crt_check_extended_key_usage( - ssl->session_negotiate->peer_cert, - ext_oid, ext_len) != 0)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate (usage extensions)")); - if (ret == 0) { - ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE; - } - verify_result |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE; } /* mbedtls_x509_crt_verify_with_profile is supposed to report a