[openssl] master update
tomas at openssl.org
tomas at openssl.org
Thu Apr 15 07:23:42 UTC 2021
The branch master has been updated
via 7e43baed2a4cc050b301650c4a45ebdd54a30b5f (commit)
via 85fcc3fb777c527a614e58c23609210a9edf893b (commit)
via b4f447c038c05260491eb880e4a9c420b476c119 (commit)
via 4a9fe33c8e12f4fefae0471c0834f8e674dc7e4e (commit)
from b9cd82f95bf99eab4e1b0420918e7139db091c4b (commit)
- Log -----------------------------------------------------------------
commit 7e43baed2a4cc050b301650c4a45ebdd54a30b5f
Author: Tomas Mraz <tomas at openssl.org>
Date: Thu Apr 8 19:27:06 2021 +0200
Do not allow creating empty RSA keys by duplication
Also avoid crashing in rsa_get_params on empty keys.
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/14793)
commit 85fcc3fb777c527a614e58c23609210a9edf893b
Author: Tomas Mraz <tomas at openssl.org>
Date: Thu Apr 8 19:02:44 2021 +0200
Remove keymgmt_copy function from the provider API
It is superceded by the keymgmt_dup.
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/14793)
commit b4f447c038c05260491eb880e4a9c420b476c119
Author: Tomas Mraz <tomas at openssl.org>
Date: Thu Apr 8 18:25:26 2021 +0200
Add selection support to the provider keymgmt_dup function
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/14793)
commit 4a9fe33c8e12f4fefae0471c0834f8e674dc7e4e
Author: Tomas Mraz <tomas at openssl.org>
Date: Wed Apr 7 19:35:13 2021 +0200
Implement provider-side keymgmt_dup function
To avoid mutating key data add OSSL_FUNC_KEYMGMT_DUP function
to the provider API and implement it for all asym-key key
managements.
Use it when copying everything to an empty EVP_PKEY
which is the case with EVP_PKEY_dup().
Fixes #14658
Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
(Merged from https://github.com/openssl/openssl/pull/14793)
-----------------------------------------------------------------------
Summary of changes:
crypto/dh/dh_ameth.c | 42 +----------
crypto/dh/dh_backend.c | 51 +++++++++++++
crypto/dsa/dsa_ameth.c | 41 +---------
crypto/dsa/dsa_backend.c | 50 +++++++++++++
crypto/ec/ec_backend.c | 88 ++++++++++++++++++++++
crypto/ec/ec_key.c | 12 +--
crypto/ec/ecx_backend.c | 45 +++++++++++
crypto/ec/ecx_key.c | 2 +-
crypto/ec/ecx_meth.c | 14 ++--
crypto/evp/evp_local.h | 2 +-
crypto/evp/keymgmt_lib.c | 23 ++----
crypto/evp/keymgmt_meth.c | 19 +++--
crypto/evp/p_lib.c | 13 ++--
crypto/rsa/rsa_ameth.c | 94 +----------------------
crypto/rsa/rsa_backend.c | 103 ++++++++++++++++++++++++++
doc/man7/provider-keymgmt.pod | 19 +++--
include/crypto/dh.h | 1 +
include/crypto/dsa.h | 1 +
include/crypto/ec.h | 1 +
include/crypto/ecx.h | 1 +
include/crypto/evp.h | 5 +-
include/crypto/rsa.h | 1 +
include/openssl/core_dispatch.h | 9 +--
providers/implementations/keymgmt/dh_kmgmt.c | 12 ++-
providers/implementations/keymgmt/dsa_kmgmt.c | 11 ++-
providers/implementations/keymgmt/ec_kmgmt.c | 10 +++
providers/implementations/keymgmt/ecx_kmgmt.c | 9 +++
providers/implementations/keymgmt/rsa_kmgmt.c | 19 ++++-
test/tls-provider.c | 14 ++--
29 files changed, 459 insertions(+), 253 deletions(-)
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index 907a867eca..d96b54285b 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -536,46 +536,6 @@ static int dhx_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
return dh_pkey_import_from_type(params, vpctx, EVP_PKEY_DHX);
}
-static ossl_inline int dh_bn_dup_check(BIGNUM **out, const BIGNUM *f)
-{
- if (f != NULL && (*out = BN_dup(f)) == NULL)
- return 0;
- return 1;
-}
-
-static DH *dh_dup(const DH *dh)
-{
- DH *dupkey = NULL;
-
- /* Do not try to duplicate foreign DH keys */
- if (ossl_dh_get_method(dh) != DH_OpenSSL())
- return NULL;
-
- if ((dupkey = ossl_dh_new_ex(dh->libctx)) == NULL)
- return NULL;
-
- dupkey->length = DH_get_length(dh);
- if (!ossl_ffc_params_copy(&dupkey->params, &dh->params))
- goto err;
-
- dupkey->flags = dh->flags;
-
- if (!dh_bn_dup_check(&dupkey->pub_key, dh->pub_key))
- goto err;
- if (!dh_bn_dup_check(&dupkey->priv_key, dh->priv_key))
- goto err;
-
- if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DH,
- &dupkey->ex_data, &dh->ex_data))
- goto err;
-
- return dupkey;
-
- err:
- DH_free(dupkey);
- return NULL;
-}
-
static int dh_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
{
DH *dh = from->pkey.dh;
@@ -583,7 +543,7 @@ static int dh_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
int ret;
if (dh != NULL) {
- dupkey = dh_dup(dh);
+ dupkey = ossl_dh_dup(dh, OSSL_KEYMGMT_SELECT_ALL);
if (dupkey == NULL)
return 0;
}
diff --git a/crypto/dh/dh_backend.c b/crypto/dh/dh_backend.c
index 97f5271a5a..18cf3f5992 100644
--- a/crypto/dh/dh_backend.c
+++ b/crypto/dh/dh_backend.c
@@ -17,6 +17,7 @@
#include <openssl/core_names.h>
#include "internal/param_build_set.h"
#include "crypto/dh.h"
+#include "dh_local.h"
/*
* The intention with the "backend" source file is to offer backend functions
@@ -117,6 +118,56 @@ int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
return 1;
}
+static ossl_inline int dh_bn_dup_check(BIGNUM **out, const BIGNUM *f)
+{
+ if (f != NULL && (*out = BN_dup(f)) == NULL)
+ return 0;
+ return 1;
+}
+
+DH *ossl_dh_dup(const DH *dh, int selection)
+{
+ DH *dupkey = NULL;
+
+#ifndef FIPS_MODULE
+ /* Do not try to duplicate foreign DH keys */
+ if (ossl_dh_get_method(dh) != DH_OpenSSL())
+ return NULL;
+#endif
+
+ if ((dupkey = ossl_dh_new_ex(dh->libctx)) == NULL)
+ return NULL;
+
+ dupkey->length = DH_get_length(dh);
+ if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0
+ && !ossl_ffc_params_copy(&dupkey->params, &dh->params))
+ goto err;
+
+ dupkey->flags = dh->flags;
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0
+ && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0
+ || !dh_bn_dup_check(&dupkey->pub_key, dh->pub_key)))
+ goto err;
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
+ && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0
+ || !dh_bn_dup_check(&dupkey->priv_key, dh->priv_key)))
+ goto err;
+
+#ifndef FIPS_MODULE
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DH,
+ &dupkey->ex_data, &dh->ex_data))
+ goto err;
+#endif
+
+ return dupkey;
+
+ err:
+ DH_free(dupkey);
+ return NULL;
+}
+
#ifndef FIPS_MODULE
DH *ossl_dh_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
OSSL_LIB_CTX *libctx, const char *propq)
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
index 69964c053c..2e1ad081dc 100644
--- a/crypto/dsa/dsa_ameth.c
+++ b/crypto/dsa/dsa_ameth.c
@@ -500,45 +500,6 @@ static int dsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
return 1;
}
-static ossl_inline int dsa_bn_dup_check(BIGNUM **out, const BIGNUM *f)
-{
- if (f != NULL && (*out = BN_dup(f)) == NULL)
- return 0;
- return 1;
-}
-
-static DSA *dsa_dup(const DSA *dsa)
-{
- DSA *dupkey = NULL;
-
- /* Do not try to duplicate foreign DSA keys */
- if (DSA_get_method((DSA *)dsa) != DSA_OpenSSL())
- return NULL;
-
- if ((dupkey = ossl_dsa_new(dsa->libctx)) == NULL)
- return NULL;
-
- if (!ossl_ffc_params_copy(&dupkey->params, &dsa->params))
- goto err;
-
- dupkey->flags = dsa->flags;
-
- if (!dsa_bn_dup_check(&dupkey->pub_key, dsa->pub_key))
- goto err;
- if (!dsa_bn_dup_check(&dupkey->priv_key, dsa->priv_key))
- goto err;
-
- if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DSA,
- &dupkey->ex_data, &dsa->ex_data))
- goto err;
-
- return dupkey;
-
- err:
- DSA_free(dupkey);
- return NULL;
-}
-
static int dsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
{
DSA *dsa = from->pkey.dsa;
@@ -546,7 +507,7 @@ static int dsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
int ret;
if (dsa != NULL) {
- dupkey = dsa_dup(dsa);
+ dupkey = ossl_dsa_dup(dsa, OSSL_KEYMGMT_SELECT_ALL);
if (dupkey == NULL)
return 0;
}
diff --git a/crypto/dsa/dsa_backend.c b/crypto/dsa/dsa_backend.c
index f3e54aeb13..2ef8cbc9f3 100644
--- a/crypto/dsa/dsa_backend.c
+++ b/crypto/dsa/dsa_backend.c
@@ -16,6 +16,7 @@
#include <openssl/core_names.h>
#include <openssl/err.h>
#include "crypto/dsa.h"
+#include "dsa_local.h"
/*
* The intention with the "backend" source file is to offer backend support
@@ -56,6 +57,55 @@ int ossl_dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[])
return 0;
}
+static ossl_inline int dsa_bn_dup_check(BIGNUM **out, const BIGNUM *f)
+{
+ if (f != NULL && (*out = BN_dup(f)) == NULL)
+ return 0;
+ return 1;
+}
+
+DSA *ossl_dsa_dup(const DSA *dsa, int selection)
+{
+ DSA *dupkey = NULL;
+
+#ifndef FIPS_MODULE
+ /* Do not try to duplicate foreign DSA keys */
+ if (DSA_get_method((DSA *)dsa) != DSA_OpenSSL())
+ return NULL;
+#endif
+
+ if ((dupkey = ossl_dsa_new(dsa->libctx)) == NULL)
+ return NULL;
+
+ if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0
+ && !ossl_ffc_params_copy(&dupkey->params, &dsa->params))
+ goto err;
+
+ dupkey->flags = dsa->flags;
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0
+ && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0
+ || !dsa_bn_dup_check(&dupkey->pub_key, dsa->pub_key)))
+ goto err;
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
+ && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0
+ || !dsa_bn_dup_check(&dupkey->priv_key, dsa->priv_key)))
+ goto err;
+
+#ifndef FIPS_MODULE
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DSA,
+ &dupkey->ex_data, &dsa->ex_data))
+ goto err;
+#endif
+
+ return dupkey;
+
+ err:
+ DSA_free(dupkey);
+ return NULL;
+}
+
#ifndef FIPS_MODULE
DSA *ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
OSSL_LIB_CTX *libctx, const char *propq)
diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c
index 9716ffc2f2..0189a33a91 100644
--- a/crypto/ec/ec_backend.c
+++ b/crypto/ec/ec_backend.c
@@ -17,6 +17,7 @@
#include <openssl/objects.h>
#include <openssl/params.h>
#include <openssl/err.h>
+#include <openssl/engine.h>
#include "crypto/bn.h"
#include "crypto/ec.h"
#include "ec_local.h"
@@ -519,6 +520,93 @@ int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
return 1;
}
+EC_KEY *ossl_ec_key_dup(const EC_KEY *src, int selection)
+{
+ EC_KEY *ret = ossl_ec_key_new_method_int(src->libctx, src->propq,
+ src->engine);
+
+ if (ret == NULL)
+ return NULL;
+
+ if (src == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
+ goto err;
+ }
+
+ /* copy the parameters */
+ if (src->group != NULL
+ && (selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
+ ret->group = ossl_ec_group_new_ex(src->libctx, src->propq,
+ src->group->meth);
+ if (ret->group == NULL
+ || !EC_GROUP_copy(ret->group, src->group))
+ goto err;
+
+ if (src->meth != NULL) {
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
+ if (src->engine != NULL && ENGINE_init(src->engine) == 0)
+ goto err;
+ ret->engine = src->engine;
+#endif
+ ret->meth = src->meth;
+ }
+ }
+
+ /* copy the public key */
+ if (src->pub_key != NULL
+ && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ if (ret->group == NULL)
+ /* no parameter-less keys allowed */
+ goto err;
+ ret->pub_key = EC_POINT_new(ret->group);
+ if (ret->pub_key == NULL
+ || !EC_POINT_copy(ret->pub_key, src->pub_key))
+ goto err;
+ }
+
+ /* copy the private key */
+ if (src->priv_key != NULL
+ && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+ if (ret->group == NULL)
+ /* no parameter-less keys allowed */
+ goto err;
+ ret->priv_key = BN_new();
+ if (ret->priv_key == NULL || !BN_copy(ret->priv_key, src->priv_key))
+ goto err;
+ if (ret->group->meth->keycopy
+ && ret->group->meth->keycopy(ret, src) == 0)
+ goto err;
+ }
+
+ /* copy the rest */
+ if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) {
+ ret->enc_flag = src->enc_flag;
+ ret->conv_form = src->conv_form;
+ }
+
+ ret->version = src->version;
+ ret->flags = src->flags;
+
+#ifndef FIPS_MODULE
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
+ &ret->ex_data, &src->ex_data))
+ goto err;
+#endif
+
+ if (ret->meth != NULL && ret->meth->copy != NULL) {
+ if ((selection
+ & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR)
+ goto err;
+ if (ret->meth->copy(ret, src) == 0)
+ goto err;
+ }
+
+ return ret;
+ err:
+ EC_KEY_free(ret);
+ return NULL;
+}
+
int ossl_ec_encoding_param2id(const OSSL_PARAM *p, int *id)
{
const char *name = NULL;
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
index 50b53f97ed..f06715fa6b 100644
--- a/crypto/ec/ec_key.c
+++ b/crypto/ec/ec_key.c
@@ -184,17 +184,7 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
{
- EC_KEY *ret = ossl_ec_key_new_method_int(ec_key->libctx, ec_key->propq,
- ec_key->engine);
-
- if (ret == NULL)
- return NULL;
-
- if (EC_KEY_copy(ret, ec_key) == NULL) {
- EC_KEY_free(ret);
- return NULL;
- }
- return ret;
+ return ossl_ec_key_dup(ec_key, OSSL_KEYMGMT_SELECT_ALL);
}
int EC_KEY_up_ref(EC_KEY *r)
diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c
index 8f8fdc7705..3a1314626b 100644
--- a/crypto/ec/ecx_backend.c
+++ b/crypto/ec/ecx_backend.c
@@ -92,6 +92,51 @@ int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[],
return 1;
}
+ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key, int selection)
+{
+ ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
+
+ if (ret == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ ret->lock = CRYPTO_THREAD_lock_new();
+ if (ret->lock == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ ret->libctx = key->libctx;
+ ret->haspubkey = key->haspubkey;
+ ret->keylen = key->keylen;
+ ret->type = key->type;
+ ret->references = 1;
+
+ if (key->propq != NULL) {
+ ret->propq = OPENSSL_strdup(key->propq);
+ if (ret->propq == NULL)
+ goto err;
+ }
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
+ memcpy(ret->pubkey, key->pubkey, sizeof(ret->pubkey));
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
+ && key->privkey != NULL) {
+ if (ossl_ecx_key_allocate_privkey(ret) == NULL)
+ goto err;
+ memcpy(ret->privkey, key->privkey, ret->keylen);
+ }
+
+ return ret;
+
+err:
+ ossl_ecx_key_free(ret);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ return NULL;
+}
+
#ifndef FIPS_MODULE
ECX_KEY *ossl_ecx_key_op(const X509_ALGOR *palg,
const unsigned char *p, int plen,
diff --git a/crypto/ec/ecx_key.c b/crypto/ec/ecx_key.c
index 60d9f3cc9f..dcec26c2e9 100644
--- a/crypto/ec/ecx_key.c
+++ b/crypto/ec/ecx_key.c
@@ -7,6 +7,7 @@
* https://www.openssl.org/source/license.html
*/
+#include <string.h>
#include <openssl/err.h>
#include "crypto/ecx.h"
@@ -39,7 +40,6 @@ ECX_KEY *ossl_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey
if (propq != NULL) {
ret->propq = OPENSSL_strdup(propq);
- ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
if (ret->propq == NULL)
goto err;
}
diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c
index 609d8609ea..61f062a2f8 100644
--- a/crypto/ec/ecx_meth.c
+++ b/crypto/ec/ecx_meth.c
@@ -406,16 +406,18 @@ static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx,
static int ecx_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
{
- ECX_KEY *ecx = from->pkey.ecx;
+ ECX_KEY *ecx = from->pkey.ecx, *dupkey = NULL;
int ret;
- /* We can do just up-ref as ECX keys are immutable */
- if (ecx != NULL && !ossl_ecx_key_up_ref(ecx))
- return 0;
+ if (ecx != NULL) {
+ dupkey = ossl_ecx_key_dup(ecx, OSSL_KEYMGMT_SELECT_ALL);
+ if (dupkey == NULL)
+ return 0;
+ }
- ret = EVP_PKEY_assign(to, from->type, ecx);
+ ret = EVP_PKEY_assign(to, from->type, dupkey);
if (!ret)
- ossl_ecx_key_free(ecx);
+ ossl_ecx_key_free(dupkey);
return ret;
}
diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h
index 72caf86aaf..9473d54817 100644
--- a/crypto/evp/evp_local.h
+++ b/crypto/evp/evp_local.h
@@ -112,7 +112,7 @@ struct evp_keymgmt_st {
OSSL_FUNC_keymgmt_import_types_fn *import_types;
OSSL_FUNC_keymgmt_export_fn *export;
OSSL_FUNC_keymgmt_export_types_fn *export_types;
- OSSL_FUNC_keymgmt_copy_fn *copy;
+ OSSL_FUNC_keymgmt_dup_fn *dup;
} /* EVP_KEYMGMT */ ;
struct evp_keyexch_st {
diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c
index 872a63ae47..80aea65e88 100644
--- a/crypto/evp/keymgmt_lib.c
+++ b/crypto/evp/keymgmt_lib.c
@@ -441,24 +441,13 @@ int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection)
if (to_keymgmt == NULL)
to_keymgmt = from->keymgmt;
- if (to_keymgmt == from->keymgmt && to_keymgmt->copy != NULL) {
- /* Make sure there's somewhere to copy to */
- if (to_keydata == NULL
- && ((to_keydata = alloc_keydata = evp_keymgmt_newdata(to_keymgmt))
- == NULL)) {
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-
- /*
- * |to| and |from| have the same keymgmt, and the copy function is
- * implemented, so just copy and be done
- */
- if (!evp_keymgmt_copy(to_keymgmt, to_keydata, from->keydata,
- selection)) {
- evp_keymgmt_freedata(to_keymgmt, alloc_keydata);
+ if (to_keymgmt == from->keymgmt && to_keymgmt->dup != NULL
+ && to_keydata == NULL) {
+ to_keydata = alloc_keydata = evp_keymgmt_dup(to_keymgmt,
+ from->keydata,
+ selection);
+ if (to_keydata == NULL)
return 0;
- }
} else if (match_type(to_keymgmt, from->keymgmt)) {
struct evp_keymgmt_util_try_import_data_st import_data;
diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c
index cdd7c70ed9..937faa99d6 100644
--- a/crypto/evp/keymgmt_meth.c
+++ b/crypto/evp/keymgmt_meth.c
@@ -129,9 +129,9 @@ static void *keymgmt_from_algorithm(int name_id,
if (keymgmt->has == NULL)
keymgmt->has = OSSL_FUNC_keymgmt_has(fns);
break;
- case OSSL_FUNC_KEYMGMT_COPY:
- if (keymgmt->copy == NULL)
- keymgmt->copy = OSSL_FUNC_keymgmt_copy(fns);
+ case OSSL_FUNC_KEYMGMT_DUP:
+ if (keymgmt->dup == NULL)
+ keymgmt->dup = OSSL_FUNC_keymgmt_dup(fns);
break;
case OSSL_FUNC_KEYMGMT_VALIDATE:
if (keymgmt->validate == NULL)
@@ -463,12 +463,11 @@ const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
return keymgmt->export_types(selection);
}
-int evp_keymgmt_copy(const EVP_KEYMGMT *keymgmt,
- void *keydata_to, const void *keydata_from,
- int selection)
+void *evp_keymgmt_dup(const EVP_KEYMGMT *keymgmt, const void *keydata_from,
+ int selection)
{
- /* We assume no copy if the implementation doesn't have a function */
- if (keymgmt->copy == NULL)
- return 0;
- return keymgmt->copy(keydata_to, keydata_from, selection);
+ /* We assume no dup if the implementation doesn't have a function */
+ if (keymgmt->dup == NULL)
+ return NULL;
+ return keymgmt->dup(keydata_from, selection);
}
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 0fc3af494f..de4f1811c1 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -180,10 +180,12 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
/*
* If |to| is provided, we know that |from| is legacy at this point.
- * Try exporting |from| to |to|'s keymgmt, then use evp_keymgmt_copy()
+ * Try exporting |from| to |to|'s keymgmt, then use evp_keymgmt_dup()
* to copy the appropriate data to |to|'s keydata.
+ * We cannot override existing data so do it only if there is no keydata
+ * in |to| yet.
*/
- if (to->keymgmt != NULL) {
+ if (to->keymgmt != NULL && to->keydata == NULL) {
EVP_KEYMGMT *to_keymgmt = to->keymgmt;
void *from_keydata =
evp_pkey_export_to_provider((EVP_PKEY *)from, NULL, &to_keymgmt,
@@ -196,8 +198,9 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
if (from_keydata == NULL)
ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
else
- ok = evp_keymgmt_copy(to->keymgmt, to->keydata, from_keydata,
- SELECT_PARAMETERS);
+ ok = (to->keydata = evp_keymgmt_dup(to->keymgmt,
+ from_keydata,
+ SELECT_PARAMETERS)) != NULL;
goto end;
}
@@ -1857,7 +1860,7 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
/* Synchronize the dirty count */
pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
-
+
CRYPTO_THREAD_unlock(pk->lock);
goto end;
}
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index e633fa5c93..2f9d60a7b3 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -884,98 +884,6 @@ static int rsa_pss_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
return rsa_int_import_from(params, vpctx, RSA_FLAG_TYPE_RSASSAPSS);
}
-static ossl_inline int rsa_bn_dup_check(BIGNUM **out, const BIGNUM *f)
-{
- if (f != NULL && (*out = BN_dup(f)) == NULL)
- return 0;
- return 1;
-}
-
-static RSA *rsa_dup(const RSA *rsa)
-{
- RSA *dupkey = NULL;
- int pnum, i;
-
- /* Do not try to duplicate foreign RSA keys */
- if (RSA_get_method(rsa) != RSA_PKCS1_OpenSSL())
- return NULL;
-
- if ((dupkey = ossl_rsa_new_with_ctx(rsa->libctx)) == NULL)
- return NULL;
-
- /* private and public key */
- if (!rsa_bn_dup_check(&dupkey->n, rsa->n))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->e, rsa->e))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->d, rsa->d))
- goto err;
-
- /* factors and crt params */
- if (!rsa_bn_dup_check(&dupkey->p, rsa->p))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->q, rsa->q))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->dmp1, rsa->dmp1))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->dmq1, rsa->dmq1))
- goto err;
- if (!rsa_bn_dup_check(&dupkey->iqmp, rsa->iqmp))
- goto err;
-
- /* multiprime */
- pnum = sk_RSA_PRIME_INFO_num(rsa->prime_infos);
- if (pnum > 0) {
- dupkey->prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum);
- for (i = 0; i < pnum; i++) {
- const RSA_PRIME_INFO *pinfo = NULL;
- RSA_PRIME_INFO *duppinfo = NULL;
-
- if ((duppinfo = OPENSSL_zalloc(sizeof(*duppinfo))) == NULL) {
- ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- /* push first so cleanup in error case works */
- (void)sk_RSA_PRIME_INFO_push(dupkey->prime_infos, duppinfo);
-
- pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i);
- if (!rsa_bn_dup_check(&duppinfo->r, pinfo->r))
- goto err;
- if (!rsa_bn_dup_check(&duppinfo->d, pinfo->d))
- goto err;
- if (!rsa_bn_dup_check(&duppinfo->t, pinfo->t))
- goto err;
- }
- if (!ossl_rsa_multip_calc_product(dupkey))
- goto err;
- }
-
- dupkey->version = rsa->version;
- dupkey->flags = rsa->flags;
-
- dupkey->pss_params = rsa->pss_params;
-
- if (rsa->pss != NULL) {
- dupkey->pss = RSA_PSS_PARAMS_dup(rsa->pss);
- if (rsa->pss->maskGenAlgorithm != NULL
- && dupkey->pss->maskGenAlgorithm == NULL) {
- dupkey->pss->maskHash = ossl_x509_algor_mgf1_decode(rsa->pss->maskGenAlgorithm);
- if (dupkey->pss->maskHash == NULL)
- goto err;
- }
- }
-
- if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_RSA,
- &dupkey->ex_data, &rsa->ex_data))
- goto err;
-
- return dupkey;
-
- err:
- RSA_free(dupkey);
- return NULL;
-}
-
static int rsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
{
RSA *rsa = from->pkey.rsa;
@@ -983,7 +891,7 @@ static int rsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
int ret;
if (rsa != NULL) {
- dupkey = rsa_dup(rsa);
+ dupkey = ossl_rsa_dup(rsa, OSSL_KEYMGMT_SELECT_ALL);
if (dupkey == NULL)
return 0;
}
diff --git a/crypto/rsa/rsa_backend.c b/crypto/rsa/rsa_backend.c
index 01ee875058..192b3fdbf7 100644
--- a/crypto/rsa/rsa_backend.c
+++ b/crypto/rsa/rsa_backend.c
@@ -22,6 +22,7 @@
#include "internal/param_build_set.h"
#include "crypto/asn1.h"
#include "crypto/rsa.h"
+#include "rsa_local.h"
#include "e_os.h" /* strcasecmp for Windows() */
@@ -322,6 +323,108 @@ int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params,
return ret;
}
+static ossl_inline int rsa_bn_dup_check(BIGNUM **out, const BIGNUM *f)
+{
+ if (f != NULL && (*out = BN_dup(f)) == NULL)
+ return 0;
+ return 1;
+}
+
+RSA *ossl_rsa_dup(const RSA *rsa, int selection)
+{
+ RSA *dupkey = NULL;
+#ifndef FIPS_MODULE
+ int pnum, i;
+
+ /* Do not try to duplicate foreign RSA keys */
+ if (RSA_get_method(rsa) != RSA_PKCS1_OpenSSL())
+ return NULL;
+#endif
+
+ if ((dupkey = ossl_rsa_new_with_ctx(rsa->libctx)) == NULL)
+ return NULL;
+
+ /* public key */
+ if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+ if (!rsa_bn_dup_check(&dupkey->n, rsa->n))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->e, rsa->e))
+ goto err;
+ }
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+
+ /* private key */
+ if (!rsa_bn_dup_check(&dupkey->d, rsa->d))
+ goto err;
+
+ /* factors and crt params */
+ if (!rsa_bn_dup_check(&dupkey->p, rsa->p))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->q, rsa->q))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->dmp1, rsa->dmp1))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->dmq1, rsa->dmq1))
+ goto err;
+ if (!rsa_bn_dup_check(&dupkey->iqmp, rsa->iqmp))
+ goto err;
+ }
+
+ dupkey->version = rsa->version;
+ dupkey->flags = rsa->flags;
+ /* we always copy the PSS parameters regardless of selection */
+ dupkey->pss_params = rsa->pss_params;
+
+#ifndef FIPS_MODULE
+ /* multiprime */
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
+ && (pnum = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) > 0) {
+ dupkey->prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum);
+ for (i = 0; i < pnum; i++) {
+ const RSA_PRIME_INFO *pinfo = NULL;
+ RSA_PRIME_INFO *duppinfo = NULL;
+
+ if ((duppinfo = OPENSSL_zalloc(sizeof(*duppinfo))) == NULL) {
+ ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ /* push first so cleanup in error case works */
+ (void)sk_RSA_PRIME_INFO_push(dupkey->prime_infos, duppinfo);
+
+ pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i);
+ if (!rsa_bn_dup_check(&duppinfo->r, pinfo->r))
+ goto err;
+ if (!rsa_bn_dup_check(&duppinfo->d, pinfo->d))
+ goto err;
+ if (!rsa_bn_dup_check(&duppinfo->t, pinfo->t))
+ goto err;
+ }
+ if (!ossl_rsa_multip_calc_product(dupkey))
+ goto err;
+ }
+
+ if (rsa->pss != NULL) {
+ dupkey->pss = RSA_PSS_PARAMS_dup(rsa->pss);
+ if (rsa->pss->maskGenAlgorithm != NULL
+ && dupkey->pss->maskGenAlgorithm == NULL) {
+ dupkey->pss->maskHash = ossl_x509_algor_mgf1_decode(rsa->pss->maskGenAlgorithm);
+ if (dupkey->pss->maskHash == NULL)
+ goto err;
+ }
+ }
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_RSA,
+ &dupkey->ex_data, &rsa->ex_data))
+ goto err;
+#endif
+
+ return dupkey;
+
+ err:
+ RSA_free(dupkey);
+ return NULL;
+}
+
#ifndef FIPS_MODULE
RSA_PSS_PARAMS *ossl_rsa_pss_decode(const X509_ALGOR *alg)
{
diff --git a/doc/man7/provider-keymgmt.pod b/doc/man7/provider-keymgmt.pod
index 9a11b316c2..c9280bc8ef 100644
--- a/doc/man7/provider-keymgmt.pod
+++ b/doc/man7/provider-keymgmt.pod
@@ -52,8 +52,8 @@ provider-keymgmt - The KEYMGMT library E<lt>-E<gt> provider functions
OSSL_CALLBACK *param_cb, void *cbarg);
const OSSL_PARAM *OSSL_FUNC_keymgmt_export_types(int selection);
- /* Key object copy */
- int OSSL_FUNC_keymgmt_copy(void *keydata_to, const void *keydata_from, int selection);
+ /* Key object duplication, a constructor */
+ void *OSSL_FUNC_keymgmt_dup(const void *keydata_from, int selection);
/* Key object validation */
int OSSL_FUNC_keymgmt_validate(const void *keydata, int selection, int checktype);
@@ -118,7 +118,7 @@ macros in L<openssl-core_dispatch.h(7)>, as follows:
OSSL_FUNC_keymgmt_export OSSL_FUNC_KEYMGMT_EXPORT
OSSL_FUNC_keymgmt_export_types OSSL_FUNC_KEYMGMT_EXPORT_TYPES
- OSSL_FUNC_keymgmt_copy OSSL_FUNC_KEYMGMT_COPY
+ OSSL_FUNC_keymgmt_dup OSSL_FUNC_KEYMGMT_DUP
=head2 Key Objects
@@ -320,7 +320,7 @@ I<selection> in I<keydata1> and I<keydata2> match. It is assumed that
the caller has ensured that I<keydata1> and I<keydata2> are both owned
by the implementation of this function.
-=head2 Key Object Import, Export and Copy Functions
+=head2 Key Object Import, Export and Duplication Functions
OSSL_FUNC_keymgmt_import() should import data indicated by I<selection> into
I<keydata> with values taken from the B<OSSL_PARAM> array I<params>.
@@ -337,10 +337,9 @@ OSSL_FUNC_keymgmt_export_types() should return a constant array of descriptor
B<OSSL_PARAM> for data indicated by I<selection>, that the
OSSL_FUNC_keymgmt_export() callback can expect to receive.
-OSSL_FUNC_keymgmt_copy() should copy data subsets indicated by I<selection>
-from I<keydata_from> to I<keydata_to>. It is assumed that the caller
-has ensured that I<keydata_to> and I<keydata_from> are both owned by
-the implementation of this function.
+OSSL_FUNC_keymgmt_dup() should duplicate data subsets indicated by
+I<selection> or the whole key data I<keydata_from> and create a new
+provider side key object with the data.
=head2 Common Information Parameters
@@ -379,8 +378,8 @@ Bits of security is defined in SP800-57.
=head1 RETURN VALUES
-OSSL_FUNC_keymgmt_new() should return a valid reference to the newly created provider
-side key object, or NULL on failure.
+OSSL_FUNC_keymgmt_new() and OSSL_FUNC_keymgmt_dup() should return a valid
+reference to the newly created provider side key object, or NULL on failure.
OSSL_FUNC_keymgmt_import(), OSSL_FUNC_keymgmt_export(), OSSL_FUNC_keymgmt_get_params() and
OSSL_FUNC_keymgmt_set_params() should return 1 for success or 0 on error.
diff --git a/include/crypto/dh.h b/include/crypto/dh.h
index ab6115d986..291e008c9c 100644
--- a/include/crypto/dh.h
+++ b/include/crypto/dh.h
@@ -56,5 +56,6 @@ int ossl_dh_kdf_X9_42_asn1(unsigned char *out, size_t outlen,
const unsigned char *ukm, size_t ukmlen,
const EVP_MD *md,
OSSL_LIB_CTX *libctx, const char *propq);
+DH *ossl_dh_dup(const DH *dh, int selection);
#endif /* OSSL_CRYPTO_DH_H */
diff --git a/include/crypto/dsa.h b/include/crypto/dsa.h
index 38c49c3295..ed0c887b83 100644
--- a/include/crypto/dsa.h
+++ b/include/crypto/dsa.h
@@ -43,5 +43,6 @@ int ossl_dsa_check_pub_key_partial(const DSA *dsa, const BIGNUM *pub_key,
int *ret);
int ossl_dsa_check_priv_key(const DSA *dsa, const BIGNUM *priv_key, int *ret);
int ossl_dsa_check_pairwise(const DSA *dsa);
+DSA *ossl_dsa_dup(const DSA *dsa, int selection);
#endif
diff --git a/include/crypto/ec.h b/include/crypto/ec.h
index c679fd8d11..80b5ce0735 100644
--- a/include/crypto/ec.h
+++ b/include/crypto/ec.h
@@ -79,6 +79,7 @@ int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]);
int ossl_ec_key_fromdata(EC_KEY *ecx, const OSSL_PARAM params[],
int include_private);
int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]);
+EC_KEY *ossl_ec_key_dup(const EC_KEY *key, int selection);
EC_KEY *ossl_ec_key_param_from_x509_algor(const X509_ALGOR *palg,
OSSL_LIB_CTX *libctx,
const char *propq);
diff --git a/include/crypto/ecx.h b/include/crypto/ecx.h
index 656ee94f09..82671a8f4d 100644
--- a/include/crypto/ecx.h
+++ b/include/crypto/ecx.h
@@ -83,6 +83,7 @@ void ossl_ecx_key_set0_libctx(ECX_KEY *key, OSSL_LIB_CTX *libctx);
unsigned char *ossl_ecx_key_allocate_privkey(ECX_KEY *key);
void ossl_ecx_key_free(ECX_KEY *key);
int ossl_ecx_key_up_ref(ECX_KEY *key);
+ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key, int selection);
int ossl_x25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
const uint8_t peer_public_value[32]);
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 8ea5a2bf35..88a1c3d857 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -810,9 +810,8 @@ int evp_keymgmt_export(const EVP_KEYMGMT *keymgmt, void *keydata,
int selection, OSSL_CALLBACK *param_cb, void *cbarg);
const OSSL_PARAM *evp_keymgmt_export_types(const EVP_KEYMGMT *keymgmt,
int selection);
-int evp_keymgmt_copy(const EVP_KEYMGMT *keymgmt,
- void *keydata_to, const void *keydata_from,
- int selection);
+void *evp_keymgmt_dup(const EVP_KEYMGMT *keymgmt,
+ const void *keydata_from, int selection);
/* Pulling defines out of C source files */
diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h
index 73bf03f615..f252363465 100644
--- a/include/crypto/rsa.h
+++ b/include/crypto/rsa.h
@@ -63,6 +63,7 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes,
STACK_OF(BIGNUM_const) *exps,
STACK_OF(BIGNUM_const) *coeffs);
+RSA *ossl_rsa_dup(const RSA *rsa, int selection);
int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]);
int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[]);
diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h
index 1cc2ebcc57..5385b65169 100644
--- a/include/openssl/core_dispatch.h
+++ b/include/openssl/core_dispatch.h
@@ -595,11 +595,10 @@ OSSL_CORE_MAKE_FUNC(int, keymgmt_export,
OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keymgmt_export_types,
(int selection))
-/* Copy function, only works for matching keymgmt */
-# define OSSL_FUNC_KEYMGMT_COPY 44
-OSSL_CORE_MAKE_FUNC(int, keymgmt_copy,
- ( void *keydata_to, const void *keydata_from,
- int selection))
+/* Dup function, constructor */
+# define OSSL_FUNC_KEYMGMT_DUP 44
+OSSL_CORE_MAKE_FUNC(void *, keymgmt_dup,
+ (const void *keydata_from, int selection))
/* Key Exchange */
diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c
index ba56abe04a..b3678c5e2a 100644
--- a/providers/implementations/keymgmt/dh_kmgmt.c
+++ b/providers/implementations/keymgmt/dh_kmgmt.c
@@ -45,6 +45,7 @@ static OSSL_FUNC_keymgmt_import_fn dh_import;
static OSSL_FUNC_keymgmt_import_types_fn dh_import_types;
static OSSL_FUNC_keymgmt_export_fn dh_export;
static OSSL_FUNC_keymgmt_export_types_fn dh_export_types;
+static OSSL_FUNC_keymgmt_dup_fn dh_dup;
#define DH_POSSIBLE_SELECTIONS \
(OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
@@ -707,7 +708,7 @@ static void dh_gen_cleanup(void *genctx)
OPENSSL_free(gctx);
}
-void *dh_load(const void *reference, size_t reference_sz)
+static void *dh_load(const void *reference, size_t reference_sz)
{
DH *dh = NULL;
@@ -721,6 +722,13 @@ void *dh_load(const void *reference, size_t reference_sz)
return NULL;
}
+static void *dh_dup(const void *keydata_from, int selection)
+{
+ if (ossl_prov_is_running())
+ return ossl_dh_dup(keydata_from, selection);
+ return NULL;
+}
+
const OSSL_DISPATCH ossl_dh_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dh_newdata },
{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dh_gen_init },
@@ -743,6 +751,7 @@ const OSSL_DISPATCH ossl_dh_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dh_import_types },
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dh_export },
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dh_export_types },
+ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dh_dup },
{ 0, NULL }
};
@@ -776,5 +785,6 @@ const OSSL_DISPATCH ossl_dhx_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dh_export_types },
{ OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
(void (*)(void))dhx_query_operation_name },
+ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dh_dup },
{ 0, NULL }
};
diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c
index 15a40df260..38e682f3b6 100644
--- a/providers/implementations/keymgmt/dsa_kmgmt.c
+++ b/providers/implementations/keymgmt/dsa_kmgmt.c
@@ -44,6 +44,7 @@ static OSSL_FUNC_keymgmt_import_fn dsa_import;
static OSSL_FUNC_keymgmt_import_types_fn dsa_import_types;
static OSSL_FUNC_keymgmt_export_fn dsa_export;
static OSSL_FUNC_keymgmt_export_types_fn dsa_export_types;
+static OSSL_FUNC_keymgmt_dup_fn dsa_dup;
#define DSA_DEFAULT_MD "SHA256"
#define DSA_POSSIBLE_SELECTIONS \
@@ -597,7 +598,7 @@ static void dsa_gen_cleanup(void *genctx)
OPENSSL_free(gctx);
}
-void *dsa_load(const void *reference, size_t reference_sz)
+static void *dsa_load(const void *reference, size_t reference_sz)
{
DSA *dsa = NULL;
@@ -611,6 +612,13 @@ void *dsa_load(const void *reference, size_t reference_sz)
return NULL;
}
+static void *dsa_dup(const void *keydata_from, int selection)
+{
+ if (ossl_prov_is_running())
+ return ossl_dsa_dup(keydata_from, selection);
+ return NULL;
+}
+
const OSSL_DISPATCH ossl_dsa_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata },
{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dsa_gen_init },
@@ -631,5 +639,6 @@ const OSSL_DISPATCH ossl_dsa_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dsa_import_types },
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dsa_export },
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dsa_export_types },
+ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))dsa_dup },
{ 0, NULL }
};
diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c
index fe5bd7a28a..f563d920c4 100644
--- a/providers/implementations/keymgmt/ec_kmgmt.c
+++ b/providers/implementations/keymgmt/ec_kmgmt.c
@@ -55,6 +55,7 @@ static OSSL_FUNC_keymgmt_import_types_fn ec_import_types;
static OSSL_FUNC_keymgmt_export_fn ec_export;
static OSSL_FUNC_keymgmt_export_types_fn ec_export_types;
static OSSL_FUNC_keymgmt_query_operation_name_fn ec_query_operation_name;
+static OSSL_FUNC_keymgmt_dup_fn ec_dup;
#ifndef FIPS_MODULE
# ifndef OPENSSL_NO_SM2
static OSSL_FUNC_keymgmt_new_fn sm2_newdata;
@@ -1361,6 +1362,13 @@ static void *sm2_load(const void *reference, size_t reference_sz)
# endif
#endif
+static void *ec_dup(const void *keydata_from, int selection)
+{
+ if (ossl_prov_is_running())
+ return ossl_ec_key_dup(keydata_from, selection);
+ return NULL;
+}
+
const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata },
{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init },
@@ -1386,6 +1394,7 @@ const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types },
{ OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
(void (*)(void))ec_query_operation_name },
+ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup },
{ 0, NULL }
};
@@ -1416,6 +1425,7 @@ const OSSL_DISPATCH ossl_sm2_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types },
{ OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
(void (*)(void))sm2_query_operation_name },
+ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup },
{ 0, NULL }
};
# endif
diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c
index a0284325cc..45593be544 100644
--- a/providers/implementations/keymgmt/ecx_kmgmt.c
+++ b/providers/implementations/keymgmt/ecx_kmgmt.c
@@ -71,6 +71,7 @@ static OSSL_FUNC_keymgmt_import_fn ecx_import;
static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types;
static OSSL_FUNC_keymgmt_export_fn ecx_export;
static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types;
+static OSSL_FUNC_keymgmt_dup_fn ecx_dup;
#define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
@@ -691,6 +692,13 @@ void *ecx_load(const void *reference, size_t reference_sz)
return NULL;
}
+static void *ecx_dup(const void *keydata_from, int selection)
+{
+ if (ossl_prov_is_running())
+ return ossl_ecx_key_dup(keydata_from, selection);
+ return NULL;
+}
+
static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type)
{
uint8_t pub[64];
@@ -788,6 +796,7 @@ static int ed448_validate(const void *keydata, int selection, int checktype)
{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
{ OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \
+ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup }, \
{ 0, NULL } \
};
diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c
index fbd99e3dc8..a075c54487 100644
--- a/providers/implementations/keymgmt/rsa_kmgmt.c
+++ b/providers/implementations/keymgmt/rsa_kmgmt.c
@@ -49,6 +49,7 @@ static OSSL_FUNC_keymgmt_import_types_fn rsa_import_types;
static OSSL_FUNC_keymgmt_export_fn rsa_export;
static OSSL_FUNC_keymgmt_export_types_fn rsa_export_types;
static OSSL_FUNC_keymgmt_query_operation_name_fn rsa_query_operation_name;
+static OSSL_FUNC_keymgmt_dup_fn rsa_dup;
#define RSA_DEFAULT_MD "SHA256"
#define RSA_PSS_DEFAULT_MD OSSL_DIGEST_NAME_SHA1
@@ -305,15 +306,16 @@ static int rsa_get_params(void *key, OSSL_PARAM params[])
const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30(rsa);
int rsa_type = RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK);
OSSL_PARAM *p;
+ int empty = RSA_get0_n(rsa) == NULL;
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
- && !OSSL_PARAM_set_int(p, RSA_bits(rsa)))
+ && (empty || !OSSL_PARAM_set_int(p, RSA_bits(rsa))))
return 0;
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
- && !OSSL_PARAM_set_int(p, RSA_security_bits(rsa)))
+ && (empty || !OSSL_PARAM_set_int(p, RSA_security_bits(rsa))))
return 0;
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
- && !OSSL_PARAM_set_int(p, RSA_size(rsa)))
+ && (empty || !OSSL_PARAM_set_int(p, RSA_size(rsa))))
return 0;
/*
@@ -645,6 +647,15 @@ static void *rsapss_load(const void *reference, size_t reference_sz)
return common_load(reference, reference_sz, RSA_FLAG_TYPE_RSASSAPSS);
}
+static void *rsa_dup(const void *keydata_from, int selection)
+{
+ if (ossl_prov_is_running()
+ /* do not allow creating empty keys by duplication */
+ && (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
+ return ossl_rsa_dup(keydata_from, selection);
+ return NULL;
+}
+
/* For any RSA key, we use the "RSA" algorithms regardless of sub-type. */
static const char *rsa_query_operation_name(int operation_id)
{
@@ -671,6 +682,7 @@ const OSSL_DISPATCH ossl_rsa_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))rsa_import_types },
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))rsa_export },
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsa_export_types },
+ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))rsa_dup },
{ 0, NULL }
};
@@ -695,5 +707,6 @@ const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsa_export_types },
{ OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
(void (*)(void))rsa_query_operation_name },
+ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))rsa_dup },
{ 0, NULL }
};
diff --git a/test/tls-provider.c b/test/tls-provider.c
index 1085273a32..482c3aa0da 100644
--- a/test/tls-provider.c
+++ b/test/tls-provider.c
@@ -52,7 +52,7 @@ typedef struct xorkey_st {
static OSSL_FUNC_keymgmt_new_fn xor_newdata;
static OSSL_FUNC_keymgmt_free_fn xor_freedata;
static OSSL_FUNC_keymgmt_has_fn xor_has;
-static OSSL_FUNC_keymgmt_copy_fn xor_copy;
+static OSSL_FUNC_keymgmt_dup_fn xor_dup;
static OSSL_FUNC_keymgmt_gen_init_fn xor_gen_init;
static OSSL_FUNC_keymgmt_gen_set_params_fn xor_gen_set_params;
static OSSL_FUNC_keymgmt_gen_settable_params_fn xor_gen_settable_params;
@@ -440,9 +440,9 @@ static int xor_has(const void *vkey, int selection)
return ok;
}
-static int xor_copy(void *vtokey, const void *vfromkey, int selection)
+static void *xor_dup(const void *vfromkey, int selection)
{
- XORKEY *tokey = vtokey;
+ XORKEY *tokey = xor_newdata(NULL);
const XORKEY *fromkey = vfromkey;
int ok = 0;
@@ -466,7 +466,11 @@ static int xor_copy(void *vtokey, const void *vfromkey, int selection)
}
}
}
- return ok;
+ if (!ok) {
+ xor_freedata(tokey);
+ tokey = NULL;
+ }
+ return tokey;
}
static ossl_inline int xor_get_params(void *vkey, OSSL_PARAM params[])
@@ -706,7 +710,7 @@ static const OSSL_DISPATCH xor_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))xor_set_params },
{ OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))xor_settable_params },
{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))xor_has },
- { OSSL_FUNC_KEYMGMT_COPY, (void (*)(void))xor_copy },
+ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))xor_dup },
{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))xor_freedata },
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))xor_import },
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))xor_import_types },
More information about the openssl-commits
mailing list