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 <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16765)
This commit is contained in:
Richard Levitte 2021-09-29 10:58:21 +02:00
parent 23effeb81f
commit f3ba626538
2 changed files with 34 additions and 8 deletions

View File

@ -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)

View File

@ -37,8 +37,8 @@ in B<from> and B<to> are both present and match this function has no effect.
The function EVP_PKEY_parameters_eq() checks the parameters of keys
B<a> and B<b> for equality.
The function EVP_PKEY_eq() checks the public key components and parameters
(if present) of keys B<a> and B<b> for equality.
The function EVP_PKEY_eq() checks the keys B<a> and B<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<EVP_PKEY(3)> 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 B<EVP_PKEY>s, 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