From f3ba62653815b2f7991103cdbea1ac155c8c916a Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 29 Sep 2021 10:58:21 +0200 Subject: [PATCH] Fix EVP_PKEY_eq() to be possible to use with strictly private keys EVP_PKEY_eq() assumed that an EVP_PKEY always has the public key component if it has a private key component. However, this assumption no longer strictly holds true, at least for provider backed keys. EVP_PKEY_eq() therefore needs to be modified to specify that the private key should be checked too (at the discretion of what's reasonable for the implementation doing the actual comparison). Fixes #16267 Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/16765) --- crypto/evp/p_lib.c | 2 +- doc/man3/EVP_PKEY_copy_parameters.pod | 40 ++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 2552dd702a..27138af564 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -343,7 +343,7 @@ int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b) if (a->keymgmt != NULL || b->keymgmt != NULL) return evp_pkey_cmp_any(a, b, (SELECT_PARAMETERS - | OSSL_KEYMGMT_SELECT_PUBLIC_KEY)); + | OSSL_KEYMGMT_SELECT_KEYPAIR)); /* All legacy keys */ if (a->type != b->type) diff --git a/doc/man3/EVP_PKEY_copy_parameters.pod b/doc/man3/EVP_PKEY_copy_parameters.pod index 46ce8be19b..adb5c2084e 100644 --- a/doc/man3/EVP_PKEY_copy_parameters.pod +++ b/doc/man3/EVP_PKEY_copy_parameters.pod @@ -37,8 +37,8 @@ in B and B are both present and match this function has no effect. The function EVP_PKEY_parameters_eq() checks the parameters of keys B and B for equality. -The function EVP_PKEY_eq() checks the public key components and parameters -(if present) of keys B and B for equality. +The function EVP_PKEY_eq() checks the keys B and B for equality, +including their parameters if they are available. =head1 NOTES @@ -47,14 +47,40 @@ EVP_PKEY_copy_parameters() is to handle public keys in certificates where the parameters are sometimes omitted from a public key if they are inherited from the CA that signed it. -Since OpenSSL private keys contain public key components too the function -EVP_PKEY_eq() can also be used to determine if a private key matches -a public key. - The deprecated functions EVP_PKEY_cmp() and EVP_PKEY_cmp_parameters() differ in -their return values compared to other _cmp() functions. They are aliases for +their return values compared to other _cmp() functions. They are aliases for EVP_PKEY_eq() and EVP_PKEY_parameters_eq(). +The function EVP_PKEY_cmp() previously only checked the key parameters +(if there are any) and the public key, assuming that there always was +a public key and that private key equality could be derived from that. +Because it's no longer assumed that the private key in an L is +always accompanied by a public key, the comparison can not rely on public +key comparison alone. + +Instead, EVP_PKEY_eq() (and therefore also EVP_PKEY_cmp()) now compares: + +=over 4 + +=item 1. + +the key parameters (if there are any) + +=item 2. + +the public keys or the private keys of the two Bs, depending on +what they both contain. + +=back + +=begin comment + +Exactly what is compared is ultimately at the discretion of the provider +that holds the key, as they will compare what makes sense to them that fits +the selector bits they are passed. + +=end comment + =head1 RETURN VALUES The function EVP_PKEY_missing_parameters() returns 1 if the public key