summaryrefslogtreecommitdiffstats
path: root/crypto/dsa/dsa_ameth.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/dsa/dsa_ameth.c')
-rw-r--r--crypto/dsa/dsa_ameth.c62
1 files changed, 60 insertions, 2 deletions
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
index e4c739daf9..1009f1a5c7 100644
--- a/crypto/dsa/dsa_ameth.c
+++ b/crypto/dsa/dsa_ameth.c
@@ -475,7 +475,7 @@ static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
OSSL_PARAM_BLD_free_params(params);
-err:
+ err:
OSSL_PARAM_BLD_free(tmpl);
return rv;
}
@@ -500,6 +500,63 @@ 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;
+ DSA *dupkey = NULL;
+ int ret;
+
+ if (dsa != NULL) {
+ dupkey = dsa_dup(dsa);
+ if (dupkey == NULL)
+ return 0;
+ }
+
+ ret = EVP_PKEY_assign_DSA(to, dupkey);
+ if (!ret)
+ DSA_free(dupkey);
+ return ret;
+}
+
/* NB these are sorted in pkey_id order, lowest first */
const EVP_PKEY_ASN1_METHOD ossl_dsa_asn1_meths[5] = {
@@ -564,6 +621,7 @@ const EVP_PKEY_ASN1_METHOD ossl_dsa_asn1_meths[5] = {
dsa_pkey_dirty_cnt,
dsa_pkey_export_to,
- dsa_pkey_import_from
+ dsa_pkey_import_from,
+ dsa_pkey_copy
}
};