From 9b4b5a15a97618b5b826d742419ccd54c819fa42 Mon Sep 17 00:00:00 2001 From: Justin W Smith <103147162+justsmth@users.noreply.github.com> Date: Fri, 16 Aug 2024 10:43:17 -0400 Subject: [PATCH] EVP_PKEY_get0 implementation (#1749) ### Issues: Addresses CryptoAlg-1716 ### Description of changes: * Provide a working implementation of the (deprecated) function `EVP_PKEY_get0`. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- crypto/asn1/asn1_test.cc | 4 ++++ crypto/ecdh_extra/ecdh_test.cc | 4 +++- crypto/evp_extra/evp_test.cc | 10 ++++++++++ crypto/fipsmodule/evp/evp.c | 16 ++++++++++------ include/openssl/evp.h | 15 ++++++++------- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/crypto/asn1/asn1_test.cc b/crypto/asn1/asn1_test.cc index d738e59071..830605086c 100644 --- a/crypto/asn1/asn1_test.cc +++ b/crypto/asn1/asn1_test.cc @@ -2462,9 +2462,13 @@ TEST(ASN1Test, ASN1Dup) { 0); bssl::UniquePtr evp_pkey(EVP_PKEY_new()); + OPENSSL_BEGIN_ALLOW_DEPRECATED + ASSERT_FALSE(EVP_PKEY_get0(evp_pkey.get())); X509_PUBKEY *tmp_key = nullptr; ASSERT_TRUE(evp_pkey); ASSERT_TRUE(EVP_PKEY_set1_EC_KEY(evp_pkey.get(), key.get())); + ASSERT_EQ(key.get(), EVP_PKEY_get0(evp_pkey.get())); + OPENSSL_END_ALLOW_DEPRECATED ASSERT_TRUE(X509_PUBKEY_set(&tmp_key, evp_pkey.get())); bssl::UniquePtr x509_pubkey(tmp_key); bssl::UniquePtr x509_pubkey_copy((X509_PUBKEY *)ASN1_dup( diff --git a/crypto/ecdh_extra/ecdh_test.cc b/crypto/ecdh_extra/ecdh_test.cc index 45c40db3df..eaa29956b6 100644 --- a/crypto/ecdh_extra/ecdh_test.cc +++ b/crypto/ecdh_extra/ecdh_test.cc @@ -264,7 +264,9 @@ static void RunWycheproofTest(FileTest *t) { } EC_KEY *peer_ec = EVP_PKEY_get0_EC_KEY(peer_evp.get()); ASSERT_TRUE(peer_ec); - + OPENSSL_BEGIN_ALLOW_DEPRECATED + ASSERT_EQ(peer_ec, EVP_PKEY_get0(peer_evp.get())); + OPENSSL_END_ALLOW_DEPRECATED bssl::UniquePtr key(EC_KEY_new()); ASSERT_TRUE(key); ASSERT_TRUE(EC_KEY_set_group(key.get(), group)); diff --git a/crypto/evp_extra/evp_test.cc b/crypto/evp_extra/evp_test.cc index fb87e49818..3fe3f308e0 100644 --- a/crypto/evp_extra/evp_test.cc +++ b/crypto/evp_extra/evp_test.cc @@ -662,6 +662,9 @@ static void RunWycheproofVerifyTest(const char *path) { if (EVP_PKEY_id(key.get()) == EVP_PKEY_DSA) { // DSA is deprecated and is not usable via EVP. DSA *dsa = EVP_PKEY_get0_DSA(key.get()); + OPENSSL_BEGIN_ALLOW_DEPRECATED + ASSERT_EQ(dsa, EVP_PKEY_get0(key.get())); + OPENSSL_END_ALLOW_DEPRECATED uint8_t digest[EVP_MAX_MD_SIZE]; unsigned digest_len; ASSERT_TRUE( @@ -1022,6 +1025,9 @@ static EVP_PKEY * instantiate_and_set_private_key(const uint8_t *private_key, size_t private_key_size, int key_type, int curve_nid) { EVP_PKEY *pkey = NULL; + OPENSSL_BEGIN_ALLOW_DEPRECATED + EXPECT_FALSE(EVP_PKEY_get0(pkey)); + OPENSSL_END_ALLOW_DEPRECATED if (NID_X25519 == curve_nid) { pkey = EVP_PKEY_new_raw_private_key(curve_nid, nullptr, private_key, @@ -1037,7 +1043,11 @@ static EVP_PKEY * instantiate_and_set_private_key(const uint8_t *private_key, BN_free(private_key_bn); pkey = EVP_PKEY_new(); EXPECT_TRUE(pkey); + OPENSSL_BEGIN_ALLOW_DEPRECATED + EXPECT_FALSE(EVP_PKEY_get0(pkey)); EXPECT_TRUE(EVP_PKEY_assign(pkey, key_type, (EC_KEY *) ec_key)); + EXPECT_EQ(ec_key, EVP_PKEY_get0(pkey)); + OPENSSL_END_ALLOW_DEPRECATED } return pkey; diff --git a/crypto/fipsmodule/evp/evp.c b/crypto/fipsmodule/evp/evp.c index 7257621ceb..386b989538 100644 --- a/crypto/fipsmodule/evp/evp.c +++ b/crypto/fipsmodule/evp/evp.c @@ -581,12 +581,16 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { void *EVP_PKEY_get0(const EVP_PKEY *pkey) { SET_DIT_AUTO_DISABLE; - // Node references, but never calls this function, so for now we return NULL. - // If other projects require complete support, call |EVP_PKEY_get0_RSA|, etc., - // rather than reading |pkey->pkey.ptr| directly. This avoids problems if our - // internal representation does not match the type the caller expects from - // OpenSSL. - return NULL; + GUARD_PTR(pkey); + switch (pkey->type) { + case EVP_PKEY_RSA: + case EVP_PKEY_RSA_PSS: + case EVP_PKEY_DSA: + case EVP_PKEY_EC: + return pkey->pkey.ptr; + default: + return NULL; + } } void OpenSSL_add_all_algorithms(void) {} diff --git a/include/openssl/evp.h b/include/openssl/evp.h index eea831786f..42631fa72f 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1142,17 +1142,18 @@ OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *engine, size_t mac_key_len); -// General No-op Functions [Deprecated]. +// Deprecated functions -// EVP_PKEY_get0 returns NULL. This function is provided for compatibility with -// OpenSSL but does not return anything. Use the typed |EVP_PKEY_get0_*| -// functions instead. +// EVP_PKEY_get0 returns the consumed key. The type of value returned will be +// one of the following, depending on the type of the |EVP_PKEY|: +// |RSA|, |DSA| or |EC_KEY|. // -// Note: In OpenSSL, the returned type will be different depending on the type -// of |EVP_PKEY| consumed. This leads to misuage very easily and has been -// deprecated as a no-op to avoid so. +// This function is provided only for compatibility with OpenSSL. +// Prefer the use the typed |EVP_PKEY_get0_*| functions instead. OPENSSL_EXPORT OPENSSL_DEPRECATED void *EVP_PKEY_get0(const EVP_PKEY *pkey); +// General No-op Functions [Deprecated]. + // OpenSSL_add_all_algorithms does nothing. This has been deprecated since // OpenSSL 1.1.0. //