[openssl] master update
Matt Caswell
matt at openssl.org
Mon Mar 8 15:25:17 UTC 2021
The branch master has been updated
via 7bc0fdd3fd4535e06c35b92d71afab9a6de94cc5 (commit)
via cc57dc962516410f6269023c8a93913617414b5e (commit)
via 8e53d94d9971bb29a303dd2295f2f169b1c9a35e (commit)
via b574c6a9ac96825b4f19c5e835273bf176174af8 (commit)
via ec961f866ac048a2d3dfd6adcfa95042114bef52 (commit)
via e8afd78af69d2229a5c36f542b13a54927709901 (commit)
from a2c911c2d069b5c6f9e2a8f20764de83a82b1c99 (commit)
- Log -----------------------------------------------------------------
commit 7bc0fdd3fd4535e06c35b92d71afab9a6de94cc5
Author: Matt Caswell <matt at openssl.org>
Date: Tue Mar 2 15:52:00 2021 +0000
Make the EVP_PKEY_get0* functions have a const return type
OTC have decided that the EVP_PKEY_get0* functions should have a const
return type. This is a breaking change to emphasise that these values
should be considered as immutable.
Reviewed-by: Richard Levitte <levitte at openssl.org>
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14319)
commit cc57dc962516410f6269023c8a93913617414b5e
Author: Matt Caswell <matt at openssl.org>
Date: Thu Feb 25 17:00:38 2021 +0000
Document the change in behaviour of the the low level key getters/setters
Reviewed-by: Richard Levitte <levitte at openssl.org>
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14319)
commit 8e53d94d9971bb29a303dd2295f2f169b1c9a35e
Author: Matt Caswell <matt at openssl.org>
Date: Thu Feb 25 16:27:46 2021 +0000
Ensure the various legacy key EVP_PKEY getters/setters are deprecated
Most of these were already deprecated but a few have been missed. This
commit corrects that.
Fixes #14303
Fixes #14317
Reviewed-by: Richard Levitte <levitte at openssl.org>
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14319)
commit b574c6a9ac96825b4f19c5e835273bf176174af8
Author: Matt Caswell <matt at openssl.org>
Date: Wed Feb 24 16:38:28 2021 +0000
Cache legacy keys instead of downgrading them
If someone calls an EVP_PKEY_get0*() function then we create a legacy
key and cache it in the EVP_PKEY - but it doesn't become an "origin" and
it doesn't ever get updated. This will be documented as a restriction of
the EVP_PKEY_get0*() function with provided keys.
Fixes #14020
Reviewed-by: Richard Levitte <levitte at openssl.org>
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14319)
commit ec961f866ac048a2d3dfd6adcfa95042114bef52
Author: Matt Caswell <matt at openssl.org>
Date: Wed Feb 24 15:04:41 2021 +0000
Avoid a null pointer deref on a malloc failure
Make sure we were sucessful in creating an EVP_PKEY
Reviewed-by: Richard Levitte <levitte at openssl.org>
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14319)
commit e8afd78af69d2229a5c36f542b13a54927709901
Author: Matt Caswell <matt at openssl.org>
Date: Fri Jan 29 17:25:33 2021 +0000
Add a multi thread test for downgrading keys
Reviewed-by: Richard Levitte <levitte at openssl.org>
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14319)
-----------------------------------------------------------------------
Summary of changes:
CHANGES.md | 57 +++++-
crypto/dh/dh_ameth.c | 5 +-
crypto/ec/ec_ameth.c | 5 +-
crypto/evp/ctrl_params_translate.c | 8 +-
crypto/evp/p_dec.c | 3 +-
crypto/evp/p_enc.c | 4 +-
crypto/evp/p_legacy.c | 32 +--
crypto/evp/p_lib.c | 235 ++++++++++------------
crypto/evp/pmeth_gn.c | 13 +-
crypto/evp/pmeth_lib.c | 3 +-
crypto/pem/pvkfmt.c | 16 +-
doc/internal/man3/evp_pkey_export_to_provider.pod | 26 +--
doc/internal/man7/EVP_PKEY.pod | 40 ++--
doc/man3/EVP_PKEY_set1_RSA.pod | 134 ++++++++----
doc/man7/evp.pod | 4 +-
include/crypto/evp.h | 45 +++--
include/openssl/evp.h | 47 +++--
test/endecoder_legacy_test.c | 12 +-
test/sslapitest.c | 14 +-
test/threadstest.c | 39 +++-
util/libcrypto.num | 20 +-
21 files changed, 459 insertions(+), 303 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index 33a335e689..c8f8e503ee 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -22,6 +22,47 @@ OpenSSL 3.0
-----------
### Changes between 1.1.1 and 3.0 [xx XXX xxxx]
+
+ * The deprecated functions EVP_PKEY_get0(), EVP_PKEY_get0_RSA(),
+ EVP_PKEY_get0_DSA(), EVP_PKEY_get0_EC_KEY(), EVP_PKEY_get0_DH(),
+ EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305() and EVP_PKEY_get0_siphash() as
+ well as the similarly named "get1" functions behave slightly differently in
+ OpenSSL 3.0. Previously they returned a pointer to the low-level key used
+ internally by libcrypto. From OpenSSL 3.0 this key may now be held in a
+ provider. Calling these functions will only return a handle on the internal
+ key where the EVP_PKEY was constructed using this key in the first place, for
+ example using a function or macro such as EVP_PKEY_assign_RSA(),
+ EVP_PKEY_set1_RSA(), etc. Where the EVP_PKEY holds a provider managed key,
+ then these functions now return a cached copy of the key. Changes to
+ the internal provider key that take place after the first time the cached key
+ is accessed will not be reflected back in the cached copy. Similarly any
+ changes made to the cached copy by application code will not be reflected
+ back in the internal provider key.
+
+ For the above reasons the keys returned from these functions should typically
+ be treated as read-only. To emphasise this the value returned from
+ EVP_PKEY_get0(), EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(),
+ EVP_PKEY_get0_EC_KEY() and EVP_PKEY_get0_DH() has been made const. This may
+ break some existing code. Applications broken by this change should be
+ modified. The preferred solution is to refactor the code to avoid the use of
+ these deprecated functions. Failing this the code should be modified to use a
+ const pointer instead. The EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(),
+ EVP_PKEY_get1_EC_KEY() and EVP_PKEY_get1_DH() functions continue to return a
+ non-const pointer to enable them to be "freed". However they should also be
+ treated as read-only.
+
+ *Matt Caswell*
+
+ * A number of functions handling low level keys or engines were deprecated
+ including EVP_PKEY_set1_engine(), EVP_PKEY_get0_engine(), EVP_PKEY_assign(),
+ EVP_PKEY_get0(), EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305() and
+ EVP_PKEY_get0_siphash(). Applications using engines should instead use
+ providers. Applications getting or setting low level keys in an EVP_PKEY
+ should instead use the OSSL_ENCODER or OSSL_DECODER APIs, or alternatively
+ use EVP_PKEY_fromdata() or EVP_PKEY_get_params().
+
+ *Matt Caswell*
+
* Deprecated obsolete EVP_PKEY_CTX_get0_dh_kdf_ukm() and
EVP_PKEY_CTX_get0_ecdh_kdf_ukm() functions. They are not needed
and require returning octet ptr parameters from providers that
@@ -35,6 +76,7 @@ OpenSSL 3.0
be used instead via EVP_RAND(3).
*Paul Dale*
+
* The SRP APIs have been deprecated. The old APIs do not work via providers,
and there is no EVP interface to them. Unfortunately there is no replacement
for these APIs at this time.
@@ -492,12 +534,6 @@ OpenSSL 3.0
*Kurt Roeckx*
- * EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH(), and
- EVP_PKEY_get0_EC_KEY() can now handle EVP_PKEYs with provider side
- internal keys, if they correspond to one of those built in types.
-
- *Richard Levitte*
-
* Added EVP_PKEY_set_type_by_keymgmt(), to initialise an EVP_PKEY to
contain a provider side internal key.
@@ -667,7 +703,7 @@ OpenSSL 3.0
`EVP_PKEY_set1_DH()` are also deprecated.
Applications should instead either read or write an
EVP_PKEY directly using the OSSL_DECODER and OSSL_ENCODER APIs.
- Or load an EVP_PKEY directly from DH data using `EVP_PKEY_fromdata()`.
+ Or load an EVP_PKEY directly from DH data using `EVP_PKEY_fromdata()`.
*Paul Dale and Matt Caswell*
@@ -695,6 +731,13 @@ OpenSSL 3.0
time. Instead applications should use L<EVP_DigestSignInit_ex(3)>,
L<EVP_DigestSignUpdate(3)> and L<EVP_DigestSignFinal(3)>.
+ Finaly functions that assign or obtain DSA objects from an EVP_PKEY such as
+ `EVP_PKEY_assign_DSA()`, `EVP_PKEY_get0_DSA()`, `EVP_PKEY_get1_DSA()`, and
+ `EVP_PKEY_set1_DSA()` are also deprecated.
+ Applications should instead either read or write an
+ EVP_PKEY directly using the OSSL_DECODER and OSSL_ENCODER APIs,
+ or load an EVP_PKEY directly from DSA data using `EVP_PKEY_fromdata()`.
+
*Paul Dale*
* Reworked the treatment of EC EVP_PKEYs with the SM2 curve to
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index 338f308934..18f4c9955e 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -433,7 +433,10 @@ static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
switch (op) {
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
- return ossl_dh_buf2key(EVP_PKEY_get0_DH(pkey), arg2, arg1);
+ /* We should only be here if we have a legacy key */
+ if (!ossl_assert(evp_pkey_is_legacy(pkey)))
+ return 0;
+ return ossl_dh_buf2key(evp_pkey_get0_DH_int(pkey), arg2, arg1);
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
return ossl_dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2, 0, 1);
default:
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index 89241b97c1..694fcb3789 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -482,7 +482,10 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
return 1;
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
- return EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(pkey), arg2, arg1, NULL);
+ /* We should only be here if we have a legacy key */
+ if (!ossl_assert(evp_pkey_is_legacy(pkey)))
+ return 0;
+ return EC_KEY_oct2key(evp_pkey_get0_EC_KEY_int(pkey), arg2, arg1, NULL);
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey),
diff --git a/crypto/evp/ctrl_params_translate.c b/crypto/evp/ctrl_params_translate.c
index ae3340395d..966278171c 100644
--- a/crypto/evp/ctrl_params_translate.c
+++ b/crypto/evp/ctrl_params_translate.c
@@ -1481,7 +1481,7 @@ static int get_payload_group_name(enum state state,
#ifndef OPENSSL_NO_DH
case EVP_PKEY_DH:
{
- DH *dh = EVP_PKEY_get0_DH(pkey);
+ const DH *dh = EVP_PKEY_get0_DH(pkey);
int uid = DH_get_nid(dh);
if (uid != NID_undef) {
@@ -1531,7 +1531,7 @@ static int get_payload_private_key(enum state state,
#ifndef OPENSSL_NO_DH
case EVP_PKEY_DH:
{
- DH *dh = EVP_PKEY_get0_DH(pkey);
+ const DH *dh = EVP_PKEY_get0_DH(pkey);
ctx->p2 = (BIGNUM *)DH_get0_priv_key(dh);
}
@@ -1540,7 +1540,7 @@ static int get_payload_private_key(enum state state,
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
{
- EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
+ const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
ctx->p2 = (BIGNUM *)EC_KEY_get0_private_key(ec);
}
@@ -1590,7 +1590,7 @@ static int get_payload_public_key(enum state state,
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
if (ctx->params->data_type == OSSL_PARAM_OCTET_STRING) {
- EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey);
+ const EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey);
BN_CTX *bnctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(eckey));
const EC_GROUP *ecg = EC_KEY_get0_group(eckey);
const EC_POINT *point = EC_KEY_get0_public_key(eckey);
diff --git a/crypto/evp/p_dec.c b/crypto/evp/p_dec.c
index 6ac344e394..2e90705656 100644
--- a/crypto/evp/p_dec.c
+++ b/crypto/evp/p_dec.c
@@ -16,6 +16,7 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
+#include "crypto/evp.h"
int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
EVP_PKEY *priv)
@@ -28,7 +29,7 @@ int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
}
ret =
- RSA_private_decrypt(ekl, ek, key, EVP_PKEY_get0_RSA(priv),
+ RSA_private_decrypt(ekl, ek, key, evp_pkey_get0_RSA_int(priv),
RSA_PKCS1_PADDING);
err:
return ret;
diff --git a/crypto/evp/p_enc.c b/crypto/evp/p_enc.c
index bdc490d884..5881153dbb 100644
--- a/crypto/evp/p_enc.c
+++ b/crypto/evp/p_enc.c
@@ -16,6 +16,7 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
+#include "crypto/evp.h"
int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key,
int key_len, EVP_PKEY *pubk)
@@ -26,8 +27,9 @@ int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key,
ERR_raise(ERR_LIB_EVP, EVP_R_PUBLIC_KEY_NOT_RSA);
goto err;
}
+
ret =
- RSA_public_encrypt(key_len, key, ek, EVP_PKEY_get0_RSA(pubk),
+ RSA_public_encrypt(key_len, key, ek, evp_pkey_get0_RSA_int(pubk),
RSA_PKCS1_PADDING);
err:
return ret;
diff --git a/crypto/evp/p_legacy.c b/crypto/evp/p_legacy.c
index 5d8468f949..af93288dcb 100644
--- a/crypto/evp/p_legacy.c
+++ b/crypto/evp/p_legacy.c
@@ -31,22 +31,23 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
return ret;
}
-RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey)
+RSA *evp_pkey_get0_RSA_int(const EVP_PKEY *pkey)
{
- if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
- ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
- return NULL;
- }
if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) {
ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_AN_RSA_KEY);
return NULL;
}
- return pkey->pkey.rsa;
+ return evp_pkey_get_legacy((EVP_PKEY *)pkey);
+}
+
+const RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey)
+{
+ return evp_pkey_get0_RSA_int(pkey);
}
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
{
- RSA *ret = EVP_PKEY_get0_RSA(pkey);
+ RSA *ret = evp_pkey_get0_RSA_int(pkey);
if (ret != NULL)
RSA_up_ref(ret);
@@ -63,22 +64,23 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
return ret;
}
-EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey)
+EC_KEY *evp_pkey_get0_EC_KEY_int(const EVP_PKEY *pkey)
{
- if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
- ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
- return NULL;
- }
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
- EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
+ ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_EC_KEY);
return NULL;
}
- return pkey->pkey.ec;
+ return evp_pkey_get_legacy((EVP_PKEY *)pkey);
+}
+
+const EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey)
+{
+ return evp_pkey_get0_EC_KEY_int(pkey);
}
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
{
- EC_KEY *ret = EVP_PKEY_get0_EC_KEY(pkey);
+ EC_KEY *ret = evp_pkey_get0_EC_KEY_int(pkey);
if (ret != NULL)
EC_KEY_up_ref(ret);
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 63f3f4cbc7..21fbc2ea4c 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -13,6 +13,7 @@
*/
#include "internal/deprecated.h"
+#include <assert.h>
#include <stdio.h>
#include "internal/cryptlib.h"
#include "internal/refcount.h"
@@ -660,7 +661,7 @@ int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len, NULL);
}
-#ifndef OPENSSL_NO_DEPRECATED_3_0
+# ifndef OPENSSL_NO_DEPRECATED_3_0
int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)
{
if (!evp_pkey_is_legacy(pkey)) {
@@ -689,7 +690,7 @@ int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)
pkey->type = type;
return 1;
}
-#endif
+# endif
# ifndef OPENSSL_NO_ENGINE
int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
@@ -715,18 +716,20 @@ ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
return pkey->engine;
}
# endif
+
+# ifndef OPENSSL_NO_DEPRECATED_3_0
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
{
int alias = type;
-#ifndef OPENSSL_NO_EC
+# ifndef OPENSSL_NO_EC
if ((key != NULL) && (EVP_PKEY_type(type) == EVP_PKEY_EC)) {
const EC_GROUP *group = EC_KEY_get0_group(key);
if (group != NULL && EC_GROUP_get_curve_name(group) == NID_sm2)
alias = EVP_PKEY_SM2;
}
-#endif
+# endif
if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
return 0;
@@ -735,21 +738,19 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
pkey->pkey.ptr = key;
return (key != NULL);
}
+# endif
-void *EVP_PKEY_get0(const EVP_PKEY *pkey)
+const void *EVP_PKEY_get0(const EVP_PKEY *pkey)
{
if (pkey == NULL)
return NULL;
- if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
- ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
- return NULL;
- }
- return pkey->pkey.ptr;
+
+ return evp_pkey_get_legacy((EVP_PKEY *)pkey);
}
const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
{
- ASN1_OCTET_STRING *os = NULL;
+ const ASN1_OCTET_STRING *os = NULL;
if (pkey->type != EVP_PKEY_HMAC) {
ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_AN_HMAC_KEY);
return NULL;
@@ -762,7 +763,7 @@ const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
# ifndef OPENSSL_NO_POLY1305
const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
{
- ASN1_OCTET_STRING *os = NULL;
+ const ASN1_OCTET_STRING *os = NULL;
if (pkey->type != EVP_PKEY_POLY1305) {
ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_POLY1305_KEY);
return NULL;
@@ -776,7 +777,7 @@ const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
# ifndef OPENSSL_NO_SIPHASH
const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
{
- ASN1_OCTET_STRING *os = NULL;
+ const ASN1_OCTET_STRING *os = NULL;
if (pkey->type != EVP_PKEY_SIPHASH) {
ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_SIPHASH_KEY);
@@ -789,17 +790,18 @@ const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
# endif
# ifndef OPENSSL_NO_DSA
-DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
+static DSA *evp_pkey_get0_DSA_int(const EVP_PKEY *pkey)
{
- if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
- ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
- return NULL;
- }
if (pkey->type != EVP_PKEY_DSA) {
ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_DSA_KEY);
return NULL;
}
- return pkey->pkey.dsa;
+ return evp_pkey_get_legacy((EVP_PKEY *)pkey);
+}
+
+const DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
+{
+ return evp_pkey_get0_DSA_int(pkey);
}
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
@@ -811,7 +813,8 @@ int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
}
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
{
- DSA *ret = EVP_PKEY_get0_DSA(pkey);
+ DSA *ret = evp_pkey_get0_DSA_int(pkey);
+
if (ret != NULL)
DSA_up_ref(ret);
return ret;
@@ -821,22 +824,18 @@ DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
#ifndef FIPS_MODULE
# ifndef OPENSSL_NO_EC
-static ECX_KEY *evp_pkey_get0_ECX_KEY(const EVP_PKEY *pkey, int type)
+static const ECX_KEY *evp_pkey_get0_ECX_KEY(const EVP_PKEY *pkey, int type)
{
- if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
- ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
- return NULL;
- }
if (EVP_PKEY_base_id(pkey) != type) {
ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_ECX_KEY);
return NULL;
}
- return pkey->pkey.ecx;
+ return evp_pkey_get_legacy((EVP_PKEY *)pkey);
}
static ECX_KEY *evp_pkey_get1_ECX_KEY(EVP_PKEY *pkey, int type)
{
- ECX_KEY *ret = evp_pkey_get0_ECX_KEY(pkey, type);
+ ECX_KEY *ret = (ECX_KEY *)evp_pkey_get0_ECX_KEY(pkey, type);
if (ret != NULL)
ossl_ecx_key_up_ref(ret);
return ret;
@@ -866,22 +865,24 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
return ret;
}
-DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey)
+DH *evp_pkey_get0_DH_int(const EVP_PKEY *pkey)
{
- if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
- ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
- return NULL;
- }
if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_DH_KEY);
return NULL;
}
- return pkey->pkey.dh;
+ return evp_pkey_get_legacy((EVP_PKEY *)pkey);
+}
+
+const DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey)
+{
+ return evp_pkey_get0_DH_int(pkey);
}
DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
{
- DH *ret = EVP_PKEY_get0_DH(pkey);
+ DH *ret = evp_pkey_get0_DH_int(pkey);
+
if (ret != NULL)
DH_up_ref(ret);
return ret;
@@ -1310,36 +1311,6 @@ size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY *pkey, unsigned char **ppub)
/*- All methods below can also be used in FIPS_MODULE */
-/*
- * This reset function must be used very carefully, as it literally throws
- * away everything in an EVP_PKEY without freeing them, and may cause leaks
- * of memory, what have you.
- * The only reason we have this is to have the same code for EVP_PKEY_new()
- * and evp_pkey_downgrade().
- */
-static int evp_pkey_reset_unlocked(EVP_PKEY *pk)
-{
- if (pk == NULL)
- return 0;
-
- if (pk->lock != NULL) {
- const size_t offset = (unsigned char *)&pk->lock - (unsigned char *)pk;
-
- memset(pk, 0, offset);
- memset((unsigned char *)pk + offset + sizeof(pk->lock),
- 0,
- sizeof(*pk) - offset - sizeof(pk->lock));
- }
- /* EVP_PKEY_new uses zalloc so no need to call memset if pk->lock is NULL */
-
- pk->type = EVP_PKEY_NONE;
- pk->save_type = EVP_PKEY_NONE;
- pk->references = 1;
- pk->save_parameters = 1;
-
- return 1;
-}
-
EVP_PKEY *EVP_PKEY_new(void)
{
EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
@@ -1349,8 +1320,10 @@ EVP_PKEY *EVP_PKEY_new(void)
return NULL;
}
- if (!evp_pkey_reset_unlocked(ret))
- goto err;
+ ret->type = EVP_PKEY_NONE;
+ ret->save_type = EVP_PKEY_NONE;
+ ret->references = 1;
+ ret->save_parameters = 1;
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
@@ -1559,12 +1532,32 @@ int EVP_PKEY_up_ref(EVP_PKEY *pkey)
#ifndef FIPS_MODULE
void evp_pkey_free_legacy(EVP_PKEY *x)
{
- if (x->ameth != NULL) {
- if (x->ameth->pkey_free != NULL)
- x->ameth->pkey_free(x);
+ const EVP_PKEY_ASN1_METHOD *ameth = x->ameth;
+ ENGINE *tmpe = NULL;
+
+ if (ameth == NULL && x->legacy_cache_pkey.ptr != NULL)
+ ameth = EVP_PKEY_asn1_find(&tmpe, x->type);
+
+ if (ameth != NULL) {
+ if (x->legacy_cache_pkey.ptr != NULL) {
+ /*
+ * We should never have both a legacy origin key, and a key in the
+ * legacy cache.
+ */
+ assert(x->pkey.ptr == NULL);
+ /*
+ * For the purposes of freeing we make the legacy cache look like
+ * a legacy origin key.
+ */
+ x->pkey = x->legacy_cache_pkey;
+ x->legacy_cache_pkey.ptr = NULL;
+ }
+ if (ameth->pkey_free != NULL)
+ ameth->pkey_free(x);
x->pkey.ptr = NULL;
}
# ifndef OPENSSL_NO_ENGINE
+ ENGINE_finish(tmpe);
ENGINE_finish(x->engine);
x->engine = NULL;
ENGINE_finish(x->pmeth_engine);
@@ -1824,10 +1817,15 @@ int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src)
keytype = OBJ_nid2sn(type);
/* Make sure we have a clean slate to copy into */
- if (*dest == NULL)
+ if (*dest == NULL) {
*dest = EVP_PKEY_new();
- else
+ if (*dest == NULL) {
+ ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ } else {
evp_pkey_free_it(*dest);
+ }
if (EVP_PKEY_set_type(*dest, type)) {
/* If the key is typed but empty, we're done */
@@ -1872,78 +1870,57 @@ int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src)
return 0;
}
-int evp_pkey_downgrade(EVP_PKEY *pk)
+void *evp_pkey_get_legacy(EVP_PKEY *pk)
{
- EVP_PKEY tmp_copy; /* Stack allocated! */
- int rv = 0;
+ EVP_PKEY *tmp_copy = NULL;
+ void *ret = NULL;
if (!ossl_assert(pk != NULL))
- return 0;
+ return NULL;
/*
- * Throughout this whole function, we must ensure that we lock / unlock
- * the exact same lock. Note that we do pass it around a bit.
+ * If this isn't an assigned provider side key, we just use any existing
+ * origin legacy key.
*/
- if (!CRYPTO_THREAD_write_lock(pk->lock))
- return 0;
+ if (!evp_pkey_is_assigned(pk))
+ return NULL;
+ if (!evp_pkey_is_provided(pk))
+ return pk->pkey.ptr;
- /* If this isn't an assigned provider side key, we're done */
- if (!evp_pkey_is_assigned(pk) || !evp_pkey_is_provided(pk)) {
- rv = 1;
- goto end;
- }
+ if (!CRYPTO_THREAD_read_lock(pk->lock))
+ return NULL;
- /*
- * To be able to downgrade, we steal the contents of |pk|, then reset
- * it, and finally try to make it a downgraded copy. If any of that
- * fails, we restore the copied contents into |pk|.
- */
- tmp_copy = *pk; /* |tmp_copy| now owns THE lock */
+ ret = pk->legacy_cache_pkey.ptr;
- if (evp_pkey_reset_unlocked(pk)
- && evp_pkey_copy_downgraded(&pk, &tmp_copy)) {
+ if (!CRYPTO_THREAD_unlock(pk->lock))
+ return NULL;
- /* Restore the common attributes, then empty |tmp_copy| */
- pk->references = tmp_copy.references;
- pk->attributes = tmp_copy.attributes;
- pk->save_parameters = tmp_copy.save_parameters;
- pk->ex_data = tmp_copy.ex_data;
+ if (ret != NULL)
+ return ret;
- /* Ensure that stuff we've copied won't be freed */
- tmp_copy.lock = NULL;
- tmp_copy.attributes = NULL;
- memset(&tmp_copy.ex_data, 0, sizeof(tmp_copy.ex_data));
+ if (!evp_pkey_copy_downgraded(&tmp_copy, pk))
+ return NULL;
- /*
- * Save the provider side data in the operation cache, so they'll
- * find it again. |pk| is new, so it's safe to assume slot zero
- * is free.
- * Note that evp_keymgmt_util_cache_keydata() increments keymgmt's
- * reference count, so we need to decrement it, or there will be a
- * leak.
- */
- evp_keymgmt_util_cache_keydata(pk, tmp_copy.keymgmt,
- tmp_copy.keydata);
- EVP_KEYMGMT_free(tmp_copy.keymgmt);
+ if (!CRYPTO_THREAD_write_lock(pk->lock))
+ goto err;
- /*
- * Clear keymgmt and keydata from |tmp_copy|, or they'll get
- * inadvertently freed.
- */
- tmp_copy.keymgmt = NULL;
- tmp_copy.keydata = NULL;
+ /* Check again in case some other thread has updated it in the meantime */
+ ret = pk->legacy_cache_pkey.ptr;
+ if (ret == NULL) {
+ /* Steal the legacy key reference from the temporary copy */
+ ret = pk->legacy_cache_pkey.ptr = tmp_copy->pkey.ptr;
+ tmp_copy->pkey.ptr = NULL;
+ }
- evp_pkey_free_it(&tmp_copy);
- rv = 1;
- } else {
- /* Restore the original key */
- *pk = tmp_copy;
+ if (!CRYPTO_THREAD_unlock(pk->lock)) {
+ ret = NULL;
+ goto err;
}
- end:
- if (!CRYPTO_THREAD_unlock(pk->lock))
- return 0;
- return rv;
+ err:
+ EVP_PKEY_free(tmp_copy);
+
+ return ret;
}
#endif /* FIPS_MODULE */
@@ -2201,7 +2178,7 @@ int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey)
|| pkey->keydata == NULL) {
#ifndef OPENSSL_NO_EC
/* Might work through the legacy route */
- EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
+ const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
if (ec == NULL)
return 0;
@@ -2241,7 +2218,7 @@ int EVP_PKEY_get_field_type(const EVP_PKEY *pkey)
|| pkey->keydata == NULL) {
#ifndef OPENSSL_NO_EC
/* Might work through the legacy route */
- EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
+ const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
const EC_GROUP *grp;
if (ec == NULL)
diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c
index 1e4078cfa7..1953e0f958 100644
--- a/crypto/evp/pmeth_gn.c
+++ b/crypto/evp/pmeth_gn.c
@@ -197,7 +197,7 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
#endif
/*
- * Because we still have legacy keys, and evp_pkey_downgrade()
+ * Because we still have legacy keys
* TODO remove this #legacy internal keys are gone
*/
(*ppkey)->type = ctx->legacy_keytype;
@@ -208,8 +208,17 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
#ifdef FIPS_MODULE
goto not_supported;
#else
- if (ctx->pkey && !evp_pkey_downgrade(ctx->pkey))
+ /*
+ * If we get here then we're using legacy paramgen/keygen. In that case
+ * the pkey in ctx (if there is one) had better not be provided (because the
+ * legacy methods may not know how to handle it). However we can only get
+ * here if ctx->op.keymgmt.genctx == NULL, but that should never be the case
+ * if ctx->pkey is provided because we don't allow this when we initialise
+ * the ctx.
+ */
+ if (ctx->pkey != NULL && !ossl_assert(!evp_pkey_is_provided(ctx->pkey)))
goto not_accessible;
+
switch (ctx->operation) {
case EVP_PKEY_OP_PARAMGEN:
ret = ctx->pmeth->paramgen(ctx, *ppkey);
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index b08d0d2e3c..96d103544d 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -266,8 +266,7 @@ static EVP_PKEY_CTX *int_ctx_new(OSSL_LIB_CTX *libctx,
/*
* Chase down the legacy NID, as that might be needed for diverse
* purposes, such as ensure that EVP_PKEY_type() can return sensible
- * values, or that there's a better chance to "downgrade" a key when
- * needed. We go through all keymgmt names, because the keytype
+ * values. We go through all keymgmt names, because the keytype
* that's passed to this function doesn't necessarily translate
* directly.
* TODO: Remove this when #legacy keys are gone.
diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c
index de673be005..8006c64b3a 100644
--- a/crypto/pem/pvkfmt.c
+++ b/crypto/pem/pvkfmt.c
@@ -450,12 +450,12 @@ static void write_lebn(unsigned char **out, const BIGNUM *bn, int len)
*out += len;
}
-static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
-static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
+static int check_bitlen_rsa(const RSA *rsa, int ispub, unsigned int *magic);
+static void write_rsa(unsigned char **out, const RSA *rsa, int ispub);
#ifndef OPENSSL_NO_DSA
-static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
-static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
+static int check_bitlen_dsa(const DSA *dsa, int ispub, unsigned int *magic);
+static void write_dsa(unsigned char **out, const DSA *dsa, int ispub);
#endif
static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub)
@@ -542,7 +542,7 @@ static int do_i2b_bio(BIO *out, const EVP_PKEY *pk, int ispub)
return -1;
}
-static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
+static int check_bitlen_rsa(const RSA *rsa, int ispub, unsigned int *pmagic)
{
int nbyte, hnbyte, bitlen;
const BIGNUM *e;
@@ -582,7 +582,7 @@ static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
return 0;
}
-static void write_rsa(unsigned char **out, RSA *rsa, int ispub)
+static void write_rsa(unsigned char **out, const RSA *rsa, int ispub)
{
int nbyte, hnbyte;
const BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1;
@@ -605,7 +605,7 @@ static void write_rsa(unsigned char **out, RSA *rsa, int ispub)
}
#ifndef OPENSSL_NO_DSA
-static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
+static int check_bitlen_dsa(const DSA *dsa, int ispub, unsigned int *pmagic)
{
int bitlen;
const BIGNUM *p = NULL, *q = NULL, *g = NULL;
@@ -633,7 +633,7 @@ static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
return 0;
}
-static void write_dsa(unsigned char **out, DSA *dsa, int ispub)
+static void write_dsa(unsigned char **out, const DSA *dsa, int ispub)
{
int nbyte;
const BIGNUM *p = NULL, *q = NULL, *g = NULL;
diff --git a/doc/internal/man3/evp_pkey_export_to_provider.pod b/doc/internal/man3/evp_pkey_export_to_provider.pod
index 6cea8a9aab..833ff44d53 100644
--- a/doc/internal/man3/evp_pkey_export_to_provider.pod
+++ b/doc/internal/man3/evp_pkey_export_to_provider.pod
@@ -2,7 +2,7 @@
=head1 NAME
-evp_pkey_export_to_provider, evp_pkey_copy_downgraded, evp_pkey_downgrade
+evp_pkey_export_to_provider, evp_pkey_copy_downgraded, evp_pkey_get_legacy
- internal EVP_PKEY support functions for providers
=head1 SYNOPSIS
@@ -14,7 +14,7 @@ evp_pkey_export_to_provider, evp_pkey_copy_downgraded, evp_pkey_downgrade
EVP_KEYMGMT **keymgmt,
const char *propquery);
int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src);
- int evp_pkey_downgrade(EVP_PKEY *pk);
+ void *evp_pkey_get_legacy(EVP_PKEY *pk);
=head1 DESCRIPTION
@@ -37,11 +37,14 @@ For example, L<PEM_write_bio_PrivateKey_traditional(3)> uses this to try its
best to get "traditional" PEM output even if the input B<EVP_PKEY> has a
provider-native internal key.
-evp_pkey_downgrade() converts an B<EVP_PKEY> with a provider side "origin" key
-to one with a legacy "origin", if there's a corresponding legacy implementation.
-This clears the operation cache, except for the provider side "origin" key.
-This function is used in spots where provider side keys aren't yet supported,
-in an attempt to keep operating with available implementations.
+evp_pkey_get_legacy() obtains and returns a legacy key structure. If the
+EVP_PKEY already contains a legacy key then it is simply returned. If it is a
+provider based key, then a new legacy key is constructed based on the provider
+key. The legacy key is cached inside the EVP_PKEY and its value returned from
+this function. Subsequent calls to evp_pkey_get_legacy() will return the cached
+key. Subsequent changes to the provider key are not reflected back in the
+legacy key. Similarly changes to the legacy key are not reflected back in the
+provider key.
=head1 RETURN VALUES
@@ -49,14 +52,13 @@ evp_pkey_export_to_provider() returns the provider key data if there was any
allocated. It also either sets I<*keymgmt> to the B<EVP_KEYMGMT> associated
with the returned key data, or NULL on error.
-evp_pkey_downgrade() returns 1 on success or 0 on error.
+evp_pkey_get_legacy() returns the legacy key or NULL on error.
=head1 NOTES
-Some functions calling evp_pkey_export_to_provider() or evp_pkey_downgrade()
-may have received a const key, and may therefore have to cast the key to
-non-const form to call this function. Since B<EVP_PKEY> is always dynamically
-allocated, this is OK.
+Some functions calling evp_pkey_export_to_provider() may have received a const
+key, and may therefore have to cast the key to non-const form to call this
+function. Since B<EVP_PKEY> is always dynamically allocated, this is OK.
=head1 SEE ALSO
diff --git a/doc/internal/man7/EVP_PKEY.pod b/doc/internal/man7/EVP_PKEY.pod
index 022f3f0e4e..cc738b9c28 100644
--- a/doc/internal/man7/EVP_PKEY.pod
+++ b/doc/internal/man7/EVP_PKEY.pod
@@ -65,7 +65,10 @@ The B<EVP_PKEY> internal keys are mutable.
This is especially visible with internal legacy keys, since they can
be extracted with functions like L<EVP_PKEY_get0_RSA(3)> and then
-modified at will with functions like L<RSA_set0_key(3)>.
+modified at will with functions like L<RSA_set0_key(3)>. Note that if the
+internal key is a provider key then the return value from functions such as
+L<EVP_PKEY_get0_RSA(3)> is a cached copy of the key. Changes to the cached
+copy are not reflected back in the provider key.
Internal provider native keys are also possible to be modified, if the
associated L<EVP_KEYMGMT(3)> implementation allows it. This is done
@@ -178,27 +181,20 @@ OSSL_FUNC_keymgmt_import() function.
=back
-=head2 Upgrading and downgrading a key
-
-An B<EVP_PKEY> with a legacy origin will I<never> be upgraded to
-become an B<EVP_PKEY> with a provider native origin. Instead, we have
-the operation cache as described above, that takes care of the needs
-of the diverse operation the application may want to perform.
-
-An B<EVP_PKEY> with a provider native origin, I<may> be downgraded to
-be I<transformed> into an B<EVP_PKEY> with a legacy origin. Because
-an B<EVP_PKEY> can't have two origins, it means that it stops having a
-provider native origin. The previous provider native key data is
-moved to the operation cache. Downgrading is performed with the
-internal function L<evp_pkey_downgrade(3)>.
-
-I<Downgrading a key is understandably fragile>, and possibly surprising,
-and should therefore be done I<as little as possible>, but is needed
-to be able to support functions like L<EVP_PKEY_get0_RSA(3)>.
-The general recommendation is to use L<evp_pkey_copy_downgraded(3)>
-whenever possible, which it should be if the need for a legacy origin
-is only internal, or better yet, to remove the need for downgrade at
-all.
+=head2 Changing a key origin
+
+It is never possible to change the origin of a key. An B<EVP_PKEY> with a legacy
+origin will I<never> be upgraded to become an B<EVP_PKEY> with a provider
+native origin. Instead, we have the operation cache as described above, that
+takes care of the needs of the diverse operation the application may want to
+perform.
+
+Similarly an B<EVP_PKEY> with a provider native origin, will I<never> be
+I<transformed> into an B<EVP_PKEY> with a legacy origin. Instead we may have a
+cached copy of the provider key in legacy form. Once the cached copy is created
+it is never updated. Changes made to the provider key are not reflected back in
+the cached legacy copy. Similarly changes made to the cached legacy copy are not
+reflected back in the provider key.
=head1 SEE ALSO
diff --git a/doc/man3/EVP_PKEY_set1_RSA.pod b/doc/man3/EVP_PKEY_set1_RSA.pod
index d4ab126e0a..64760b2923 100644
--- a/doc/man3/EVP_PKEY_set1_RSA.pod
+++ b/doc/man3/EVP_PKEY_set1_RSA.pod
@@ -15,6 +15,16 @@ EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions
#include <openssl/evp.h>
+ int EVP_PKEY_id(const EVP_PKEY *pkey);
+ int EVP_PKEY_base_id(const EVP_PKEY *pkey);
+ int EVP_PKEY_type(int type);
+
+Deprecated since OpenSSL 3.0, can be hidden entirely by defining
+B<OPENSSL_API_COMPAT> with a suitable version value, see
+L<openssl_user_macros(7)>:
+
+ int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type);
+
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key);
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key);
int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key);
@@ -28,10 +38,10 @@ EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions
const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len);
const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len);
const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len);
- RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey);
- DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey);
- DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey);
- EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey);
+ const RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey);
+ const DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey);
+ const DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey);
+ const EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey);
int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key);
int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key);
@@ -40,40 +50,11 @@ EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions
int EVP_PKEY_assign_POLY1305(EVP_PKEY *pkey, ASN1_OCTET_STRING *key);
int EVP_PKEY_assign_SIPHASH(EVP_PKEY *pkey, ASN1_OCTET_STRING *key);
- int EVP_PKEY_id(const EVP_PKEY *pkey);
- int EVP_PKEY_base_id(const EVP_PKEY *pkey);
- int EVP_PKEY_type(int type);
-
ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey);
int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *engine);
-Deprecated since OpenSSL 3.0, can be hidden entirely by defining
-B<OPENSSL_API_COMPAT> with a suitable version value, see
-L<openssl_user_macros(7)>:
-
- int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type);
-
=head1 DESCRIPTION
-EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and
-EVP_PKEY_set1_EC_KEY() set the key referenced by I<pkey> to I<key>.
-
-EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
-EVP_PKEY_get1_EC_KEY() return the referenced key in I<pkey> or NULL if the
-key is not of the correct type. The returned key must be freed after use.
-
-EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305(), EVP_PKEY_get0_siphash(),
-EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH() and
-EVP_PKEY_get0_EC_KEY() return the referenced key in I<pkey> or NULL if the
-key is not of the correct type but the reference count of the returned key
-is B<not> incremented and so must not be freed after use.
-
-EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH(),
-EVP_PKEY_assign_EC_KEY(), EVP_PKEY_assign_POLY1305() and
-EVP_PKEY_assign_SIPHASH() set the referenced key to I<key> however these use
-the supplied I<key> internally and so I<key> will be freed when the parent
-I<pkey> is freed.
-
EVP_PKEY_base_id() returns the type of I<pkey>. For example
an RSA key will return B<EVP_PKEY_RSA>.
@@ -87,15 +68,71 @@ often seen in practice.
EVP_PKEY_type() returns the underlying type of the NID I<type>. For example
EVP_PKEY_type(EVP_PKEY_RSA2) will return B<EVP_PKEY_RSA>.
-EVP_PKEY_get0_engine() returns a reference to the ENGINE handling I<pkey>.
+EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and
+EVP_PKEY_set1_EC_KEY() set the key referenced by I<pkey> to I<key>. These
+functions are deprecated. Applications should instead use
+L<EVP_PKEY_fromdata(3)>.
+
+EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH(),
+EVP_PKEY_assign_EC_KEY(), EVP_PKEY_assign_POLY1305() and
+EVP_PKEY_assign_SIPHASH() set the referenced key to I<key> however these use
+the supplied I<key> internally and so I<key> will be freed when the parent
+I<pkey> is freed. These macros are deprecated. Applications should instead read
+an EVP_PKEY directly using the OSSL_DECODER APIs (see
+L<OSSL_DECODER_CTX_new_for_pkey(3)>), or construct an EVP_PKEY from data using
+L<EVP_PKEY_fromdata(3)>.
+
+EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
+EVP_PKEY_get1_EC_KEY() return the referenced key in I<pkey> or NULL if the
+key is not of the correct type. The returned key must be freed after use.
+These functions are deprecated. Applications should instead use the EVP_PKEY
+directly where possible. If access to the low level key parameters is required
+then applications should use L<EVP_PKEY_get_params(3)> and other similar
+functions. To write an EVP_PKEY out use the OSSL_ENCODER APIs (see
+L<OSSL_ENCODER_CTX_new_for_pkey(3)>).
+
+EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305(), EVP_PKEY_get0_siphash(),
+EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH() and
+EVP_PKEY_get0_EC_KEY() return the referenced key in I<pkey> or NULL if the
+key is not of the correct type. The reference count of the returned key is
+B<not> incremented and so the key must not be freed after use. These functions
+are deprecated. Applications should instead use the EVP_PKEY directly where
+possible. If access to the low level key parameters is required then
+applications should use L<EVP_PKEY_get_params(3)> and other similar functions.
+To write an EVP_PKEY out use the OSSL_ENCODER APIs (see
+L<OSSL_ENCODER_CTX_new_for_pkey(3)>).
+
+Note that if an EVP_PKEY was not constructed using one of the deprecated
+functions such as EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH()
+or EVP_PKEY_set1_EC_KEY(), or via the similarly named B<EVP_PKEY_assign> macros
+described above then the internal key will be managed by a provider (see
+L<provider(7)>). In that case the key returned by EVP_PKEY_get1_RSA(),
+EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH(), EVP_PKEY_get1_EC_KEY(),
+EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305(), EVP_PKEY_get0_siphash(),
+EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH() or
+EVP_PKEY_get0_EC_KEY() will be a cached copy of the provider's key. Subsequent
+updates to the provider's key will not be reflected back in the cached copy, and
+updates made by an application to the returned key will not be reflected back in
+the provider's key. Subsequent calls to EVP_PKEY_get1_RSA(),
+EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and EVP_PKEY_get1_EC_KEY() will always
+return the cached copy returned by the first call.
+
+EVP_PKEY_get0_engine() returns a reference to the ENGINE handling I<pkey>. This
+function is deprecated. Applications should use providers instead of engines
+(see L<provider(7)> for details).
EVP_PKEY_set1_engine() sets the ENGINE handling I<pkey> to I<engine>. It
must be called after the key algorithm and components are set up.
If I<engine> does not include an B<EVP_PKEY_METHOD> for I<pkey> an
-error occurs.
+error occurs. This function is deprecated. Applications should use providers
+instead of engines (see L<provider(7)> for details).
-EVP_PKEY_set_alias_type() allows modifying a EVP_PKEY to use a
-different set of algorithms than the default.
+EVP_PKEY_set_alias_type() allows modifying an EVP_PKEY to use a
+different set of algorithms than the default. This function is deprecated and
+was previously needed as a workaround to recognise SM2 keys. From OpenSSL 3.0,
+this key type is internally recognised so the workaround is no longer needed.
+Functionality is still retained as it is, but will only work with EVP_PKEYs
+with a legacy internal key.
=head1 WARNINGS
@@ -106,6 +143,17 @@ EVP_PKEY_id(), EVP_PKEY_base_id(), EVP_PKEY_type(), EVP_PKEY_set_alias_type()
For EVP_PKEY key type checking purposes, L<EVP_PKEY_is_a(3)> is more generic.
+The keys returned from the functions EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(),
+EVP_PKEY_get0_DH() and EVP_PKEY_get0_EC_KEY() were changed to have a "const"
+return type in OpenSSL 3.0. As described above the keys returned may be cached
+copies of the key held in a provider. Due to this, and unlike in earlier
+versions of OpenSSL, they should be considered read-only copies of the key.
+Updates to these keys will not be reflected back in the provider side key. The
+EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
+EVP_PKEY_get1_EC_KEY() functions were not changed to have a "const" return type
+in order that applications can "free" the return value. However applications
+should still consider them as read-only copies.
+
=head1 NOTES
In accordance with the OpenSSL naming convention the key obtained
@@ -170,7 +218,17 @@ L<EVP_PKEY_new(3)>, L<SM2(7)>
=head1 HISTORY
-EVP_PKEY_set_alias_type() was deprecated in OpenSSL 3.0.
+EVP_PKEY_set1_RSA, EVP_PKEY_set1_DSA, EVP_PKEY_set1_DH, EVP_PKEY_set1_EC_KEY,
+EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY,
+EVP_PKEY_get0_RSA, EVP_PKEY_get0_DSA, EVP_PKEY_get0_DH, EVP_PKEY_get0_EC_KEY,
+EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH,
+EVP_PKEY_assign_EC_KEY, EVP_PKEY_assign_POLY1305, EVP_PKEY_assign_SIPHASH,
+EVP_PKEY_get0_hmac, EVP_PKEY_get0_poly1305, EVP_PKEY_get0_siphash,
+EVP_PKEY_set_alias_type, EVP_PKEY_set1_engine and EVP_PKEY_get0_engine were
+deprecated in OpenSSL 3.0.
+
+The return value from EVP_PKEY_get0_RSA, EVP_PKEY_get0_DSA, EVP_PKEY_get0_DH,
+EVP_PKEY_get0_EC_KEY were made const in OpenSSL 3.0.
=head1 COPYRIGHT
diff --git a/doc/man7/evp.pod b/doc/man7/evp.pod
index d8f5a2c1d3..c97abba3dd 100644
--- a/doc/man7/evp.pod
+++ b/doc/man7/evp.pod
@@ -29,7 +29,7 @@ The B<EVP_PKEY>I<XXX> functions provide a high-level interface to
asymmetric algorithms. To create a new EVP_PKEY see
L<EVP_PKEY_new(3)>. EVP_PKEYs can be associated
with a private key of a particular algorithm by using the functions
-described on the L<EVP_PKEY_set1_RSA(3)> page, or
+described on the L<EVP_PKEY_fromdata(3)> page, or
new keys can be generated using L<EVP_PKEY_keygen(3)>.
EVP_PKEYs can be compared using L<EVP_PKEY_cmp(3)>, or printed using
L<EVP_PKEY_print_private(3)>.
@@ -90,7 +90,7 @@ L<EVP_SignInit(3)>,
L<EVP_VerifyInit(3)>,
L<EVP_EncodeInit(3)>,
L<EVP_PKEY_new(3)>,
-L<EVP_PKEY_set1_RSA(3)>,
+L<EVP_PKEY_fromdata(3)>,
L<EVP_PKEY_keygen(3)>,
L<EVP_PKEY_print_private(3)>,
L<EVP_PKEY_decrypt(3)>,
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 41487d2af2..70cc6fff1c 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -608,6 +608,21 @@ DEFINE_STACK_OF(OP_CACHE_ELEM)
#define evp_pkey_is_provided(pk) \
((pk)->keymgmt != NULL)
+union legacy_pkey_st {
+ void *ptr;
+ struct rsa_st *rsa; /* RSA */
+# ifndef OPENSSL_NO_DSA
+ struct dsa_st *dsa; /* DSA */
+# endif
+# ifndef OPENSSL_NO_DH
+ struct dh_st *dh; /* DH */
+# endif
+# ifndef OPENSSL_NO_EC
+ struct ec_key_st *ec; /* ECC */
+ ECX_KEY *ecx; /* X25519, X448, Ed25519, Ed448 */
+# endif
+};
+
struct evp_pkey_st {
/* == Legacy attributes == */
int type;
@@ -621,24 +636,15 @@ struct evp_pkey_st {
const EVP_PKEY_ASN1_METHOD *ameth;
ENGINE *engine;
ENGINE *pmeth_engine; /* If not NULL public key ENGINE to use */
- union {
- void *ptr;
- struct rsa_st *rsa; /* RSA */
-# ifndef OPENSSL_NO_DSA
- struct dsa_st *dsa; /* DSA */
-# endif
-# ifndef OPENSSL_NO_DH
- struct dh_st *dh; /* DH */
-# endif
-# ifndef OPENSSL_NO_EC
- struct ec_key_st *ec; /* ECC */
- ECX_KEY *ecx; /* X25519, X448, Ed25519, Ed448 */
-# endif
- } pkey;
+
+ /* Union to store the reference to an origin legacy key */
+ union legacy_pkey_st pkey;
+
+ /* Union to store the reference to a non-origin legacy key */
+ union legacy_pkey_st legacy_cache_pkey;
# endif
/* == Common attributes == */
- /* If these are modified, so must evp_pkey_downgrade() */
CRYPTO_REF_COUNT references;
CRYPTO_RWLOCK *lock;
STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
@@ -719,7 +725,7 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
const char *propquery);
#ifndef FIPS_MODULE
int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src);
-int evp_pkey_downgrade(EVP_PKEY *pk);
+void *evp_pkey_get_legacy(EVP_PKEY *pk);
void evp_pkey_free_legacy(EVP_PKEY *x);
#endif
@@ -884,4 +890,11 @@ int evp_pkey_ctx_get_params_to_ctrl(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
/* This must ONLY be called for legacy EVP_PKEYs */
int evp_pkey_get_params_to_ctrl(const EVP_PKEY *pkey, OSSL_PARAM *params);
+/* Same as the public get0 functions but are not const */
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+DH *evp_pkey_get0_DH_int(const EVP_PKEY *pkey);
+EC_KEY *evp_pkey_get0_EC_KEY_int(const EVP_PKEY *pkey);
+RSA *evp_pkey_get0_RSA_int(const EVP_PKEY *pkey);
+# endif
+
#endif /* OSSL_CRYPTO_EVP_H */
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 96a82827fc..ec8503e7d8 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1240,55 +1240,62 @@ int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
int EVP_PKEY_set_type_by_keymgmt(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt);
# ifndef OPENSSL_NO_DEPRECATED_3_0
OSSL_DEPRECATEDIN_3_0 int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type);
-# endif
-# ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
+OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e);
+OSSL_DEPRECATEDIN_3_0
ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey);
-# endif
+# endif
+OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key);
-void *EVP_PKEY_get0(const EVP_PKEY *pkey);
+OSSL_DEPRECATEDIN_3_0
+const void *EVP_PKEY_get0(const EVP_PKEY *pkey);
+OSSL_DEPRECATEDIN_3_0
const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len);
-# ifndef OPENSSL_NO_POLY1305
+# ifndef OPENSSL_NO_POLY1305
+OSSL_DEPRECATEDIN_3_0
const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len);
-# endif
-# ifndef OPENSSL_NO_SIPHASH
+# endif
+# ifndef OPENSSL_NO_SIPHASH
+OSSL_DEPRECATEDIN_3_0
const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len);
-# endif
+# endif
-# ifndef OPENSSL_NO_DEPRECATED_3_0
struct rsa_st;
OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key);
OSSL_DEPRECATEDIN_3_0
-struct rsa_st *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey);
+const struct rsa_st *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey);
OSSL_DEPRECATEDIN_3_0
struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
-# endif
-# ifndef OPENSSL_NO_DSA
+
+# ifndef OPENSSL_NO_DSA
struct dsa_st;
+OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key);
-struct dsa_st *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey);
+OSSL_DEPRECATEDIN_3_0
+const struct dsa_st *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey);
+OSSL_DEPRECATEDIN_3_0
struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
-# endif
-# ifndef OPENSSL_NO_DEPRECATED_3_0
+# endif
+
# ifndef OPENSSL_NO_DH
struct dh_st;
OSSL_DEPRECATEDIN_3_0 int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key);
-OSSL_DEPRECATEDIN_3_0 struct dh_st *EVP_PKEY_get0_DH(const EVP_PKEY *pkey);
+OSSL_DEPRECATEDIN_3_0 const struct dh_st *EVP_PKEY_get0_DH(const EVP_PKEY *pkey);
OSSL_DEPRECATEDIN_3_0 struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
# endif
-# endif
-# ifndef OPENSSL_NO_DEPRECATED_3_0
+
# ifndef OPENSSL_NO_EC
struct ec_key_st;
OSSL_DEPRECATEDIN_3_0
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key);
OSSL_DEPRECATEDIN_3_0
-struct ec_key_st *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey);
+const struct ec_key_st *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey);
OSSL_DEPRECATEDIN_3_0
struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
# endif
-# endif
+# endif /* OPENSSL_NO_DEPRECATED_3_0 */
EVP_PKEY *EVP_PKEY_new(void);
int EVP_PKEY_up_ref(EVP_PKEY *pkey);
diff --git a/test/endecoder_legacy_test.c b/test/endecoder_legacy_test.c
index cdf86530ce..c72d15bdaa 100644
--- a/test/endecoder_legacy_test.c
+++ b/test/endecoder_legacy_test.c
@@ -58,11 +58,11 @@
#include "testutil.h"
-typedef int PEM_write_bio_of_void_protected(BIO *out, void *obj,
+typedef int PEM_write_bio_of_void_protected(BIO *out, const void *obj,
const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u);
-typedef int PEM_write_bio_of_void_unprotected(BIO *out, void *obj);
+typedef int PEM_write_bio_of_void_unprotected(BIO *out, const void *obj);
typedef void *PEM_read_bio_of_void(BIO *out, void **obj,
pem_password_cb *cb, void *u);
typedef int EVP_PKEY_print_fn(BIO *out, const EVP_PKEY *pkey,
@@ -294,7 +294,7 @@ static int test_membio_str_eq(BIO *bio_provided, BIO *bio_legacy)
}
static int test_protected_PEM(const char *keytype, int evp_type,
- void *legacy_key,
+ const void *legacy_key,
PEM_write_bio_of_void_protected *pem_write_bio,
PEM_read_bio_of_void *pem_read_bio,
EVP_PKEY_eq_fn *evp_pkey_eq,
@@ -362,7 +362,7 @@ static int test_protected_PEM(const char *keytype, int evp_type,
}
static int test_unprotected_PEM(const char *keytype, int evp_type,
- void *legacy_key,
+ const void *legacy_key,
PEM_write_bio_of_void_unprotected *pem_write_bio,
PEM_read_bio_of_void *pem_read_bio,
EVP_PKEY_eq_fn *evp_pkey_eq,
@@ -429,7 +429,7 @@ static int test_unprotected_PEM(const char *keytype, int evp_type,
}
static int test_DER(const char *keytype, int evp_type,
- void *legacy_key, i2d_of_void *i2d, d2i_of_void *d2i,
+ const void *legacy_key, i2d_of_void *i2d, d2i_of_void *d2i,
EVP_PKEY_eq_fn *evp_pkey_eq,
EVP_PKEY_print_fn *evp_pkey_print,
EVP_PKEY *provided_pkey, int selection,
@@ -506,7 +506,7 @@ static int test_key(int idx)
int ok = 0;
size_t i;
EVP_PKEY *pkey = NULL, *downgraded_pkey = NULL;
- void *legacy_obj = NULL;
+ const void *legacy_obj = NULL;
/* Get the test data */
if (!TEST_ptr(test_stanza = &test_stanzas[idx])
diff --git a/test/sslapitest.c b/test/sslapitest.c
index 06d8e80200..b469d80a17 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -8313,7 +8313,14 @@ static DH *tmp_dh_callback(SSL *s, int is_export, int keylen)
if (!TEST_ptr(dhpkey))
return NULL;
- ret = EVP_PKEY_get0_DH(dhpkey);
+ /*
+ * libssl does not free the returned DH, so we free it now knowing that even
+ * after we free dhpkey, there will still be a reference to the owning
+ * EVP_PKEY in tmp_dh_params, and so the DH object will live for the length
+ * of time we need it for.
+ */
+ ret = EVP_PKEY_get1_DH(dhpkey);
+ DH_free(ret);
EVP_PKEY_free(dhpkey);
@@ -8361,7 +8368,7 @@ static int test_set_tmp_dh(int idx)
}
# ifndef OPENSSL_NO_DEPRECATED_3_0
if (idx == 7 || idx == 8) {
- dh = EVP_PKEY_get0_DH(dhpkey);
+ dh = EVP_PKEY_get1_DH(dhpkey);
if (!TEST_ptr(dh))
goto end;
}
@@ -8431,6 +8438,9 @@ static int test_set_tmp_dh(int idx)
testresult = 1;
end:
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+ DH_free(dh);
+# endif
SSL_free(serverssl);
SSL_free(clientssl);
SSL_CTX_free(sctx);
diff --git a/test/threadstest.c b/test/threadstest.c
index 26807e294c..1967ec6dad 100644
--- a/test/threadstest.c
+++ b/test/threadstest.c
@@ -7,6 +7,9 @@
* https://www.openssl.org/source/license.html
*/
+/* test_multi below tests the thread safety of a deprecated function */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
#if defined(_WIN32)
# include <windows.h>
#endif
@@ -401,23 +404,46 @@ static void thread_shared_evp_pkey(void)
multi_success = 0;
}
+static void thread_downgrade_shared_evp_pkey(void)
+{
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ /*
+ * This test is only relevant for deprecated functions that perform
+ * downgrading
+ */
+ if (EVP_PKEY_get0(shared_evp_pkey) == NULL)
+ multi_success = 0;
+#else
+ /* Shouldn't ever get here */
+ multi_success = 0;
+#endif
+}
+
+
/*
* Do work in multiple worker threads at the same time.
* Test 0: General worker, using the default provider
* Test 1: General worker, using the fips provider
* Test 2: Simple fetch worker
- * Test 3: Worker using a shared EVP_PKEY
+ * Test 3: Worker downgrading a shared EVP_PKEY
+ * Test 4: Worker using a shared EVP_PKEY
*/
static int test_multi(int idx)
{
thread_t thread1, thread2;
int testresult = 0;
OSSL_PROVIDER *prov = NULL, *prov2 = NULL;
- void (*worker)(void);
+ void (*worker)(void) = NULL;
+ void (*worker2)(void) = NULL;
if (idx == 1 && !do_fips)
return TEST_skip("FIPS not supported");
+#ifdef OPENSSL_NO_DEPRECATED_3_0
+ if (idx == 3)
+ return TEST_skip("Skipping tests for deprected functions");
+#endif
+
multi_success = 1;
multi_libctx = OSSL_LIB_CTX_new();
if (!TEST_ptr(multi_libctx))
@@ -435,6 +461,9 @@ static int test_multi(int idx)
worker = thread_multi_simple_fetch;
break;
case 3:
+ worker2 = thread_downgrade_shared_evp_pkey;
+ /* fall through */
+ case 4:
/*
* If available we have both the default and fips providers for this
* test
@@ -450,9 +479,11 @@ static int test_multi(int idx)
TEST_error("Invalid test index");
goto err;
}
+ if (worker2 == NULL)
+ worker2 = worker;
if (!TEST_true(run_thread(&thread1, worker))
- || !TEST_true(run_thread(&thread2, worker)))
+ || !TEST_true(run_thread(&thread2, worker2)))
goto err;
worker();
@@ -547,7 +578,7 @@ int setup_tests(void)
ADD_TEST(test_thread_local);
ADD_TEST(test_atomic);
ADD_TEST(test_multi_load);
- ADD_ALL_TESTS(test_multi, 4);
+ ADD_ALL_TESTS(test_multi, 5);
return 1;
}
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 88b5648a74..309676f39b 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -1818,7 +1818,7 @@ PEM_write_PKCS8 1860 3_0_0 EXIST::FUNCTION:STDIO
PKCS7_digest_from_attributes 1861 3_0_0 EXIST::FUNCTION:
EC_GROUP_set_curve_GFp 1862 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC
X509_PURPOSE_get0 1863 3_0_0 EXIST::FUNCTION:
-EVP_PKEY_set1_DSA 1864 3_0_0 EXIST::FUNCTION:DSA
+EVP_PKEY_set1_DSA 1864 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DSA
X509_NAME_it 1865 3_0_0 EXIST::FUNCTION:
OBJ_add_object 1866 3_0_0 EXIST::FUNCTION:
DSA_generate_key 1867 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DSA
@@ -1938,7 +1938,7 @@ OBJ_NAME_do_all 1983 3_0_0 EXIST::FUNCTION:
d2i_TS_MSG_IMPRINT_fp 1984 3_0_0 EXIST::FUNCTION:STDIO,TS
X509_CRL_verify 1985 3_0_0 EXIST::FUNCTION:
X509_get0_uids 1986 3_0_0 EXIST::FUNCTION:
-EVP_PKEY_get0_DSA 1987 3_0_0 EXIST::FUNCTION:DSA
+EVP_PKEY_get0_DSA 1987 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DSA
d2i_CMS_ContentInfo 1988 3_0_0 EXIST::FUNCTION:CMS
EVP_CIPHER_meth_get_do_cipher 1989 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
i2d_DSA_PUBKEY 1990 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DSA
@@ -2093,7 +2093,7 @@ BN_GF2m_mod_sqr 2138 3_0_0 EXIST::FUNCTION:EC2M
ASN1_PRINTABLE_new 2139 3_0_0 EXIST::FUNCTION:
OBJ_NAME_new_index 2140 3_0_0 EXIST::FUNCTION:
EVP_PKEY_asn1_add_alias 2141 3_0_0 EXIST::FUNCTION:
-EVP_PKEY_get1_DSA 2142 3_0_0 EXIST::FUNCTION:DSA
+EVP_PKEY_get1_DSA 2142 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DSA
SEED_cbc_encrypt 2143 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,SEED
EVP_rc2_40_cbc 2144 3_0_0 EXIST::FUNCTION:RC2
ECDSA_SIG_new 2145 3_0_0 EXIST::FUNCTION:EC
@@ -2603,7 +2603,7 @@ TS_MSG_IMPRINT_print_bio 2658 3_0_0 EXIST::FUNCTION:TS
CONF_module_set_usr_data 2659 3_0_0 EXIST::FUNCTION:
EC_KEY_generate_key 2660 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC
BIO_ctrl_get_write_guarantee 2661 3_0_0 EXIST::FUNCTION:
-EVP_PKEY_assign 2662 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_assign 2662 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_aes_128_ofb 2663 3_0_0 EXIST::FUNCTION:
CMS_data 2664 3_0_0 EXIST::FUNCTION:CMS
X509_load_cert_file 2665 3_0_0 EXIST::FUNCTION:
@@ -2809,7 +2809,7 @@ i2d_OCSP_CERTID 2870 3_0_0 EXIST::FUNCTION:OCSP
BN_CTX_start 2871 3_0_0 EXIST::FUNCTION:
BN_print 2872 3_0_0 EXIST::FUNCTION:
EC_KEY_set_flags 2873 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC
-EVP_PKEY_get0 2874 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_get0 2874 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
ENGINE_set_default 2875 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,ENGINE
NCONF_get_number_e 2876 3_0_0 EXIST::FUNCTION:
OPENSSL_cleanse 2877 3_0_0 EXIST::FUNCTION:
@@ -4002,7 +4002,7 @@ PEM_write_bio_PrivateKey_traditional 4091 3_0_0 EXIST::FUNCTION:
X509_get_pathlen 4092 3_0_0 EXIST::FUNCTION:
ECDSA_SIG_set0 4093 3_0_0 EXIST::FUNCTION:EC
DSA_SIG_set0 4094 3_0_0 EXIST::FUNCTION:DSA
-EVP_PKEY_get0_hmac 4095 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_get0_hmac 4095 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
HMAC_CTX_get_md 4096 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
NAME_CONSTRAINTS_check_CN 4097 3_0_0 EXIST::FUNCTION:
OCSP_resp_get0_id 4098 3_0_0 EXIST::FUNCTION:OCSP
@@ -4089,9 +4089,9 @@ UI_method_set_ex_data 4178 3_0_0 EXIST::FUNCTION:
UI_method_get_ex_data 4179 3_0_0 EXIST::FUNCTION:
UI_UTIL_wrap_read_pem_callback 4180 3_0_0 EXIST::FUNCTION:
X509_VERIFY_PARAM_get_time 4181 3_0_0 EXIST::FUNCTION:
-EVP_PKEY_get0_poly1305 4182 3_0_0 EXIST::FUNCTION:POLY1305
+EVP_PKEY_get0_poly1305 4182 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,POLY1305
DH_check_params 4183 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH
-EVP_PKEY_get0_siphash 4184 3_0_0 EXIST::FUNCTION:SIPHASH
+EVP_PKEY_get0_siphash 4184 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,SIPHASH
EVP_aria_256_ofb 4185 3_0_0 EXIST::FUNCTION:ARIA
EVP_aria_256_cfb128 4186 3_0_0 EXIST::FUNCTION:ARIA
EVP_aria_128_cfb1 4187 3_0_0 EXIST::FUNCTION:ARIA
@@ -4234,7 +4234,7 @@ EVP_PKEY_meth_set_check 4341 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_
EVP_PKEY_meth_get_check 4342 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
EVP_PKEY_meth_remove 4343 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0
OPENSSL_sk_reserve 4344 3_0_0 EXIST::FUNCTION:
-EVP_PKEY_set1_engine 4347 3_0_0 EXIST::FUNCTION:ENGINE
+EVP_PKEY_set1_engine 4347 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,ENGINE
DH_new_by_nid 4348 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH
DH_get_nid 4349 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH
CRYPTO_get_alloc_counts 4350 3_0_0 EXIST::FUNCTION:CRYPTO_MDEBUG
@@ -4572,7 +4572,7 @@ OSSL_PARAM_get_octet_ptr ? 3_0_0 EXIST::FUNCTION:
OSSL_PARAM_set_octet_ptr ? 3_0_0 EXIST::FUNCTION:
X509_set0_distinguishing_id ? 3_0_0 EXIST::FUNCTION:
X509_get0_distinguishing_id ? 3_0_0 EXIST::FUNCTION:
-EVP_PKEY_get0_engine ? 3_0_0 EXIST::FUNCTION:ENGINE
+EVP_PKEY_get0_engine ? 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,ENGINE
EVP_MD_up_ref ? 3_0_0 EXIST::FUNCTION:
EVP_MD_fetch ? 3_0_0 EXIST::FUNCTION:
EVP_set_default_properties ? 3_0_0 EXIST::FUNCTION:
More information about the openssl-commits
mailing list