[openssl] master update
Richard Levitte
levitte at openssl.org
Thu Oct 17 11:03:38 UTC 2019
The branch master has been updated
via cd32a0f5894344b6c8739a3586a20683a6bf2d5a (commit)
via 13aa5d29601683e0971763836ec37302fc7cece9 (commit)
via c8f2301629b06ef43767d7d2750afaadc3d55deb (commit)
via 073f59c407b06c1b64d84808f1bee9f9457222f9 (commit)
via 14e3e00fe2c20a8594e3e20545d9f001fd7fa850 (commit)
via 02f060d17e667a2805eb0c71266c35de9e7e3864 (commit)
from c00d9311c1a8fc7f25a65dcfbdfc90d4e7709e23 (commit)
- Log -----------------------------------------------------------------
commit cd32a0f5894344b6c8739a3586a20683a6bf2d5a
Author: Richard Levitte <levitte at openssl.org>
Date: Tue Oct 15 11:35:09 2019 +0200
Don't abuse the API when that's not what is tested
test_EVP_PKEY_CTX_get_set_params() in test/evp_extra_test.c abused
previously sloppy checking in EVP_PKEY_sign_init_ex(), by passing a
"key to sign with" that was really just domain parameters.
Now that underlying provider import of key payload has become a bit
more strict, that leads to errors, so we need to provide at least a
public part (even though fake), and because this is a signing
operation, a private part as well.
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10169)
commit 13aa5d29601683e0971763836ec37302fc7cece9
Author: Richard Levitte <levitte at openssl.org>
Date: Mon Oct 14 10:37:08 2019 +0200
DSA: Add export of keys and domain parameters from provider
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10169)
commit c8f2301629b06ef43767d7d2750afaadc3d55deb
Author: Richard Levitte <levitte at openssl.org>
Date: Mon Oct 14 10:36:14 2019 +0200
DH: Add export of keys and domain parameters from provider
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10169)
commit 073f59c407b06c1b64d84808f1bee9f9457222f9
Author: Richard Levitte <levitte at openssl.org>
Date: Mon Oct 14 10:11:40 2019 +0200
DSA: Add export of domain parameters to provider
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10169)
commit 14e3e00fe2c20a8594e3e20545d9f001fd7fa850
Author: Richard Levitte <levitte at openssl.org>
Date: Mon Oct 14 10:10:58 2019 +0200
DH: Add export of domain parameters to provider
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10169)
commit 02f060d17e667a2805eb0c71266c35de9e7e3864
Author: Richard Levitte <levitte at openssl.org>
Date: Mon Oct 14 08:41:17 2019 +0200
PKEY: adapt the export_to_provider funtions to handle domain params too
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10169)
-----------------------------------------------------------------------
Summary of changes:
crypto/dh/dh_ameth.c | 23 +++--
crypto/dsa/dsa_ameth.c | 19 ++--
crypto/evp/exchange.c | 7 +-
crypto/evp/keymgmt_lib.c | 69 +++++++++-----
crypto/evp/m_sigver.c | 3 +-
crypto/evp/pmeth_fn.c | 3 +-
include/crypto/asn1.h | 3 +-
include/crypto/evp.h | 13 ++-
providers/implementations/keymgmt/dh_kmgmt.c | 121 +++++++++++++++++++++---
providers/implementations/keymgmt/dsa_kmgmt.c | 127 ++++++++++++++++++++++----
test/evp_extra_test.c | 17 ++--
11 files changed, 314 insertions(+), 91 deletions(-)
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index a699afabbf..abb9bfdcbe 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -548,7 +548,8 @@ static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey)
return pkey->pkey.dh->dirty_cnt;
}
-static void *dh_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
+static void *dh_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
+ int want_domainparams)
{
DH *dh = pk->pkey.dh;
OSSL_PARAM_BLD tmpl;
@@ -556,7 +557,7 @@ static void *dh_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
const BIGNUM *pub_key = DH_get0_pub_key(dh);
const BIGNUM *priv_key = DH_get0_priv_key(dh);
OSSL_PARAM *params;
- void *provkey = NULL;
+ void *provdata = NULL;
if (p == NULL || g == NULL)
return NULL;
@@ -565,19 +566,15 @@ static void *dh_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
return NULL;
-
if (q != NULL) {
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q))
return NULL;
}
- /*
- * This may be used to pass domain parameters only without any key data -
- * so "pub_key" is optional. We can never have a "priv_key" without a
- * corresponding "pub_key" though.
- */
- if (pub_key != NULL) {
- if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY, pub_key))
+ if (!want_domainparams) {
+ /* A key must at least have a public part. */
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY,
+ pub_key))
return NULL;
if (priv_key != NULL) {
@@ -590,10 +587,12 @@ static void *dh_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
params = ossl_param_bld_to_param(&tmpl);
/* We export, the provider imports */
- provkey = evp_keymgmt_importkey(keymgmt, params);
+ provdata = want_domainparams
+ ? evp_keymgmt_importdomparams(keymgmt, params)
+ : evp_keymgmt_importkey(keymgmt, params);
ossl_param_bld_free(params);
- return provkey;
+ return provdata;
}
const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
index b72005af2c..ddd262bdde 100644
--- a/crypto/dsa/dsa_ameth.c
+++ b/crypto/dsa/dsa_ameth.c
@@ -533,7 +533,8 @@ static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey)
return pkey->pkey.dsa->dirty_cnt;
}
-static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
+static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
+ int want_domainparams)
{
DSA *dsa = pk->pkey.dsa;
OSSL_PARAM_BLD tmpl;
@@ -541,7 +542,7 @@ static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa);
const BIGNUM *priv_key = DSA_get0_priv_key(dsa);
OSSL_PARAM *params;
- void *provkey = NULL;
+ void *provdata = NULL;
if (p == NULL || q == NULL || g == NULL)
return NULL;
@@ -552,12 +553,8 @@ static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
return NULL;
- /*
- * This may be used to pass domain parameters only without any key data -
- * so "pub_key" is optional. We can never have a "priv_key" without a
- * corresponding "pub_key" though.
- */
- if (pub_key != NULL) {
+ if (!want_domainparams) {
+ /* A key must at least have a public part. */
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY,
pub_key))
return NULL;
@@ -572,10 +569,12 @@ static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
params = ossl_param_bld_to_param(&tmpl);
/* We export, the provider imports */
- provkey = evp_keymgmt_importkey(keymgmt, params);
+ provdata = want_domainparams
+ ? evp_keymgmt_importdomparams(keymgmt, params)
+ : evp_keymgmt_importkey(keymgmt, params);
ossl_param_bld_free(params);
- return provkey;
+ return provdata;
}
/* NB these are sorted in pkey_id order, lowest first */
diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c
index faece8af3c..dfc309ecd7 100644
--- a/crypto/evp/exchange.c
+++ b/crypto/evp/exchange.c
@@ -224,7 +224,8 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange)
ctx->op.kex.exchange = exchange;
if (ctx->pkey != NULL) {
- provkey = evp_keymgmt_export_to_provider(ctx->pkey, exchange->keymgmt);
+ provkey =
+ evp_keymgmt_export_to_provider(ctx->pkey, exchange->keymgmt, 0);
if (provkey == NULL) {
EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR);
goto err;
@@ -283,8 +284,8 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
return -2;
}
- provkey = evp_keymgmt_export_to_provider(peer,
- ctx->op.kex.exchange->keymgmt);
+ provkey =
+ evp_keymgmt_export_to_provider(peer, ctx->op.kex.exchange->keymgmt, 0);
if (provkey == NULL) {
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, ERR_R_INTERNAL_ERROR);
return 0;
diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c
index 0eb12ca317..87629157e2 100644
--- a/crypto/evp/keymgmt_lib.c
+++ b/crypto/evp/keymgmt_lib.c
@@ -52,6 +52,9 @@ static void *allocate_params_space(OSSL_PARAM *params)
for (space = 0, p = params; p->key != NULL; p++)
space += ((p->return_size + ALIGN_SIZE - 1) / ALIGN_SIZE) * ALIGN_SIZE;
+ if (space == 0)
+ return NULL;
+
data = OPENSSL_zalloc(space);
for (space = 0, p = params; p->key != NULL; p++) {
@@ -62,9 +65,10 @@ static void *allocate_params_space(OSSL_PARAM *params)
return data;
}
-void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
+void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
+ int want_domainparams)
{
- void *provkey = NULL;
+ void *provdata = NULL;
size_t i, j;
/*
@@ -90,8 +94,9 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
for (i = 0;
i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL;
i++) {
- if (keymgmt == pk->pkeys[i].keymgmt)
- return pk->pkeys[i].provkey;
+ if (keymgmt == pk->pkeys[i].keymgmt
+ && want_domainparams == pk->pkeys[i].domainparams)
+ return pk->pkeys[i].provdata;
}
if (pk->pkey.ptr != NULL) {
@@ -101,11 +106,11 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
if (pk->ameth->export_to == NULL)
return NULL;
- /* Otherwise, simply use it */
- provkey = pk->ameth->export_to(pk, keymgmt);
+ /* Otherwise, simply use it. */
+ provdata = pk->ameth->export_to(pk, keymgmt, want_domainparams);
/* Synchronize the dirty count, but only if we exported successfully */
- if (provkey != NULL)
+ if (provdata != NULL)
pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
} else {
@@ -116,10 +121,13 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
* the new provider.
*/
+ void *(*importfn)(void *provctx, const OSSL_PARAM params[]) =
+ want_domainparams ? keymgmt->importdomparams : keymgmt->importkey;
+
/*
* If the given keymgmt doesn't have an import function, give up
*/
- if (keymgmt->importkey == NULL)
+ if (importfn == NULL)
return NULL;
for (j = 0; j < i && pk->pkeys[j].keymgmt != NULL; j++) {
@@ -129,6 +137,14 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
void *data = NULL;
void *provctx =
ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
+ int (*exportfn)(void *provctx, OSSL_PARAM params[]) = NULL;
+
+ if (pk->pkeys[j].domainparams != want_domainparams)
+ continue;
+
+ exportfn = want_domainparams
+ ? pk->pkeys[j].keymgmt->exportdomparams
+ : pk->pkeys[j].keymgmt->exportkey;
paramdefs = pk->pkeys[j].keymgmt->exportkey_types();
/*
@@ -138,29 +154,35 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
*/
params = paramdefs_to_params(paramdefs);
/* Get 'return_size' filled */
- pk->pkeys[j].keymgmt->exportkey(pk->pkeys[j].provkey, params);
+ exportfn(pk->pkeys[j].provdata, params);
/*
* Allocate space and assign 'data' to point into the
- * data block
+ * data block.
+ * If something goes wrong, go to the next cached key.
*/
- data = allocate_params_space(params);
+ if ((data = allocate_params_space(params)) == NULL)
+ goto cont;
/*
* Call the exportkey function a second time, to get
- * the data filled
+ * the data filled.
+ * If something goes wrong, go to the next cached key.
*/
- pk->pkeys[j].keymgmt->exportkey(pk->pkeys[j].provkey, params);
+ if (!exportfn(pk->pkeys[j].provdata, params))
+ goto cont;
/*
* We should have all the data at this point, so import
* into the new provider and hope to get a key back.
*/
- provkey = keymgmt->importkey(provctx, params);
+ provdata = importfn(provctx, params);
+
+ cont:
OPENSSL_free(params);
OPENSSL_free(data);
- if (provkey != NULL)
+ if (provdata != NULL)
break;
}
}
@@ -173,12 +195,14 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
*/
j = ossl_assert(i < OSSL_NELEM(pk->pkeys));
- if (provkey != NULL) {
+ if (provdata != NULL) {
EVP_KEYMGMT_up_ref(keymgmt);
pk->pkeys[i].keymgmt = keymgmt;
- pk->pkeys[i].provkey = provkey;
+ pk->pkeys[i].provdata = provdata;
+ pk->pkeys[i].domainparams = want_domainparams;
}
- return provkey;
+
+ return provdata;
}
void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk)
@@ -190,11 +214,14 @@ void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk)
i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL;
i++) {
EVP_KEYMGMT *keymgmt = pk->pkeys[i].keymgmt;
- void *provkey = pk->pkeys[i].provkey;
+ void *provdata = pk->pkeys[i].provdata;
pk->pkeys[i].keymgmt = NULL;
- pk->pkeys[i].provkey = NULL;
- keymgmt->freekey(provkey);
+ pk->pkeys[i].provdata = NULL;
+ if (pk->pkeys[i].domainparams)
+ keymgmt->freedomparams(provdata);
+ else
+ keymgmt->freekey(provdata);
EVP_KEYMGMT_free(keymgmt);
}
}
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 7912c8dd59..c02325cf6b 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -94,7 +94,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
goto err;
}
- provkey = evp_keymgmt_export_to_provider(locpctx->pkey, signature->keymgmt);
+ provkey =
+ evp_keymgmt_export_to_provider(locpctx->pkey, signature->keymgmt, 0);
if (provkey == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
goto err;
diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/pmeth_fn.c
index a78839b992..d06edb218b 100644
--- a/crypto/evp/pmeth_fn.c
+++ b/crypto/evp/pmeth_fn.c
@@ -393,7 +393,8 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
ctx->op.sig.signature = signature;
if (ctx->pkey != NULL) {
- provkey = evp_keymgmt_export_to_provider(ctx->pkey, signature->keymgmt);
+ provkey =
+ evp_keymgmt_export_to_provider(ctx->pkey, signature->keymgmt, 0);
if (provkey == NULL) {
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
goto err;
diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h
index 674fa704a1..2581619831 100644
--- a/include/crypto/asn1.h
+++ b/include/crypto/asn1.h
@@ -70,7 +70,8 @@ struct evp_pkey_asn1_method_st {
*/
/* Exports to providers */
size_t (*dirty_cnt) (const EVP_PKEY *pk);
- void *(*export_to) (const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
+ void *(*export_to) (const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
+ int want_domainparams);
} /* EVP_PKEY_ASN1_METHOD */ ;
DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 22ef7e5602..dad7174bc5 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -538,13 +538,15 @@ struct evp_pkey_st {
/*
* To support transparent export/import between providers that
* support the methods for it, and still not having to do the
- * export/import every time a key is used, we maintain a cache
- * of imported key, indexed by provider address.
- * pkeys[0] is *always* the "original" key.
+ * export/import every time a key or domain params are used, we
+ * maintain a cache of imported key / domain params, indexed by
+ * provider address. pkeys[0] is *always* the "original" data.
*/
struct {
EVP_KEYMGMT *keymgmt;
- void *provkey;
+ void *provdata;
+ /* 0 = provdata is a key, 1 = provdata is domain params */
+ int domainparams;
} pkeys[10];
/*
* If there is a legacy key assigned to this structure, we keep
@@ -569,7 +571,8 @@ void evp_cleanup_int(void);
void evp_app_cleanup_int(void);
/* KEYMGMT helper functions */
-void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
+void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
+ int domainparams);
void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk);
/* KEYMGMT provider interface functions */
diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c
index e2999bde18..4120155619 100644
--- a/providers/implementations/keymgmt/dh_kmgmt.c
+++ b/providers/implementations/keymgmt/dh_kmgmt.c
@@ -14,18 +14,67 @@
#include <openssl/params.h>
#include "prov/implementations.h"
+static OSSL_OP_keymgmt_importdomparams_fn dh_importdomparams;
+static OSSL_OP_keymgmt_exportdomparams_fn dh_exportdomparams;
static OSSL_OP_keymgmt_importkey_fn dh_importkey;
+static OSSL_OP_keymgmt_exportkey_fn dh_exportkey;
-static int params_to_key(DH *dh, const OSSL_PARAM params[])
+static int params_to_domparams(DH *dh, const OSSL_PARAM params[])
{
- const OSSL_PARAM *param_p, *param_g, *param_priv_key, *param_pub_key;
- BIGNUM *p = NULL, *g = NULL, *priv_key = NULL, *pub_key = NULL;
+ const OSSL_PARAM *param_p, *param_g;
+ BIGNUM *p = NULL, *g = NULL;
if (dh == NULL)
return 0;
param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P);
param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G);
+
+ if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
+ || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g)))
+ goto err;
+
+ if (!DH_set0_pqg(dh, p, NULL, g))
+ goto err;
+
+ return 1;
+
+ err:
+ BN_free(p);
+ BN_free(g);
+ return 0;
+}
+
+static int domparams_to_params(DH *dh, OSSL_PARAM params[])
+{
+ OSSL_PARAM *p;
+ const BIGNUM *dh_p = NULL, *dh_g = NULL;
+
+ if (dh == NULL)
+ return 0;
+
+ DH_get0_pqg(dh, &dh_p, NULL, &dh_g);
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_FFC_P)) != NULL
+ && !OSSL_PARAM_set_BN(p, dh_p))
+ return 0;
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_FFC_G)) != NULL
+ && !OSSL_PARAM_set_BN(p, dh_g))
+ return 0;
+
+ return 1;
+}
+
+static int params_to_key(DH *dh, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *param_priv_key, *param_pub_key;
+ BIGNUM *priv_key = NULL, *pub_key = NULL;
+
+ if (dh == NULL)
+ return 0;
+
+ if (!params_to_domparams(dh, params))
+ return 0;
+
param_priv_key =
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_KEY);
param_pub_key =
@@ -40,31 +89,64 @@ static int params_to_key(DH *dh, const OSSL_PARAM params[])
if (param_pub_key == NULL)
return 0;
- if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
- || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g))
- || (param_priv_key != NULL
- && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
+ if ((param_priv_key != NULL
+ && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
|| !OSSL_PARAM_get_BN(param_pub_key, &pub_key))
goto err;
- if (!DH_set0_pqg(dh, p, NULL, g))
- goto err;
- p = g = NULL;
-
if (!DH_set0_key(dh, pub_key, priv_key))
goto err;
- priv_key = pub_key = NULL;
return 1;
err:
- BN_free(p);
- BN_free(g);
BN_free(priv_key);
BN_free(pub_key);
return 0;
}
+static int key_to_params(DH *dh, OSSL_PARAM params[])
+{
+ OSSL_PARAM *p;
+ const BIGNUM *priv_key = NULL, *pub_key = NULL;
+
+ if (dh == NULL)
+ return 0;
+ if (!domparams_to_params(dh, params))
+ return 0;
+
+ DH_get0_key(dh, &pub_key, &priv_key);
+ if ((p = OSSL_PARAM_locate(params,
+ OSSL_PKEY_PARAM_DH_PRIV_KEY)) != NULL
+ && !OSSL_PARAM_set_BN(p, priv_key))
+ return 0;
+ if ((p = OSSL_PARAM_locate(params,
+ OSSL_PKEY_PARAM_DH_PUB_KEY)) != NULL
+ && !OSSL_PARAM_set_BN(p, pub_key))
+ return 0;
+
+ return 1;
+}
+
+static void *dh_importdomparams(void *provctx, const OSSL_PARAM params[])
+{
+ DH *dh;
+
+ if ((dh = DH_new()) == NULL
+ || !params_to_domparams(dh, params)) {
+ DH_free(dh);
+ dh = NULL;
+ }
+ return dh;
+}
+
+static int dh_exportdomparams(void *domparams, OSSL_PARAM params[])
+{
+ DH *dh = domparams;
+
+ return dh != NULL && !domparams_to_params(dh, params);
+}
+
static void *dh_importkey(void *provctx, const OSSL_PARAM params[])
{
DH *dh;
@@ -77,12 +159,23 @@ static void *dh_importkey(void *provctx, const OSSL_PARAM params[])
return dh;
}
+static int dh_exportkey(void *key, OSSL_PARAM params[])
+{
+ DH *dh = key;
+
+ return dh != NULL && !key_to_params(dh, params);
+}
+
const OSSL_DISPATCH dh_keymgmt_functions[] = {
/*
* TODO(3.0) When implementing OSSL_FUNC_KEYMGMT_GENKEY, remember to also
* implement OSSL_FUNC_KEYMGMT_EXPORTKEY.
*/
+ { OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS, (void (*)(void))dh_importdomparams },
+ { OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS, (void (*)(void))dh_exportdomparams },
+ { OSSL_FUNC_KEYMGMT_FREEDOMPARAMS, (void (*)(void))DH_free },
{ OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dh_importkey },
+ { OSSL_FUNC_KEYMGMT_EXPORTKEY, (void (*)(void))dh_exportkey },
{ OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DH_free },
{ 0, NULL }
};
diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c
index 818a451bb9..a3bf11a570 100644
--- a/providers/implementations/keymgmt/dsa_kmgmt.c
+++ b/providers/implementations/keymgmt/dsa_kmgmt.c
@@ -14,13 +14,15 @@
#include <openssl/params.h>
#include "prov/implementations.h"
+static OSSL_OP_keymgmt_importdomparams_fn dsa_importdomparams;
+static OSSL_OP_keymgmt_exportdomparams_fn dsa_exportdomparams;
static OSSL_OP_keymgmt_importkey_fn dsa_importkey;
+static OSSL_OP_keymgmt_exportkey_fn dsa_exportkey;
-static int params_to_key(DSA *dsa, const OSSL_PARAM params[])
+static int params_to_domparams(DSA *dsa, const OSSL_PARAM params[])
{
- const OSSL_PARAM *param_p, *param_q, *param_g, *param_priv_key;
- const OSSL_PARAM *param_pub_key;
- BIGNUM *p = NULL, *q = NULL, *g = NULL, *priv_key = NULL, *pub_key = NULL;
+ const OSSL_PARAM *param_p, *param_q, *param_g;
+ BIGNUM *p = NULL, *q = NULL, *g = NULL;
if (dsa == NULL)
return 0;
@@ -28,6 +30,57 @@ static int params_to_key(DSA *dsa, const OSSL_PARAM params[])
param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P);
param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q);
param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G);
+
+ if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
+ || (param_q != NULL && !OSSL_PARAM_get_BN(param_q, &q))
+ || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g)))
+ goto err;
+
+ if (!DSA_set0_pqg(dsa, p, q, g))
+ goto err;
+
+ return 1;
+
+ err:
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ return 0;
+}
+
+static int domparams_to_params(DSA *dsa, OSSL_PARAM params[])
+{
+ OSSL_PARAM *p;
+ const BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
+
+ if (dsa == NULL)
+ return 0;
+
+ DSA_get0_pqg(dsa, &dsa_p, &dsa_q, &dsa_g);
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_FFC_P)) != NULL
+ && !OSSL_PARAM_set_BN(p, dsa_p))
+ return 0;
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_FFC_Q)) != NULL
+ && !OSSL_PARAM_set_BN(p, dsa_q))
+ return 0;
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_FFC_G)) != NULL
+ && !OSSL_PARAM_set_BN(p, dsa_g))
+ return 0;
+
+ return 1;
+}
+
+static int params_to_key(DSA *dsa, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *param_priv_key, *param_pub_key;
+ BIGNUM *priv_key = NULL, *pub_key = NULL;
+
+ if (dsa == NULL)
+ return 0;
+
+ if (!params_to_domparams(dsa, params))
+ return 0;
+
param_priv_key =
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PRIV_KEY);
param_pub_key =
@@ -40,34 +93,63 @@ static int params_to_key(DSA *dsa, const OSSL_PARAM params[])
if (param_priv_key != NULL && param_pub_key == NULL)
return 0;
- if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
- || (param_q != NULL && !OSSL_PARAM_get_BN(param_q, &q))
- || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g))
- || (param_priv_key != NULL
- && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
+ if ((param_priv_key != NULL
+ && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
|| (param_pub_key != NULL
&& !OSSL_PARAM_get_BN(param_pub_key, &pub_key)))
goto err;
- if (!DSA_set0_pqg(dsa, p, q, g))
- goto err;
- p = q = g = NULL;
-
if (pub_key != NULL && !DSA_set0_key(dsa, pub_key, priv_key))
goto err;
- priv_key = pub_key = NULL;
return 1;
err:
- BN_free(p);
- BN_free(q);
- BN_free(g);
BN_free(priv_key);
BN_free(pub_key);
return 0;
}
+static int key_to_params(DSA *dsa, OSSL_PARAM params[])
+{
+ OSSL_PARAM *p;
+ const BIGNUM *priv_key = NULL, *pub_key = NULL;
+
+ if (dsa == NULL)
+ return 0;
+ if (!domparams_to_params(dsa, params))
+ return 0;
+
+ DSA_get0_key(dsa, &pub_key, &priv_key);
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DSA_PRIV_KEY)) != NULL
+ && !OSSL_PARAM_set_BN(p, priv_key))
+ return 0;
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DSA_PUB_KEY)) != NULL
+ && !OSSL_PARAM_set_BN(p, pub_key))
+ return 0;
+
+ return 1;
+}
+
+static void *dsa_importdomparams(void *provctx, const OSSL_PARAM params[])
+{
+ DSA *dsa;
+
+ if ((dsa = DSA_new()) == NULL
+ || !params_to_domparams(dsa, params)) {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+ return dsa;
+}
+
+static int dsa_exportdomparams(void *domparams, OSSL_PARAM params[])
+{
+ DSA *dsa = domparams;
+
+ return dsa != NULL && !domparams_to_params(dsa, params);
+}
+
static void *dsa_importkey(void *provctx, const OSSL_PARAM params[])
{
DSA *dsa;
@@ -80,12 +162,23 @@ static void *dsa_importkey(void *provctx, const OSSL_PARAM params[])
return dsa;
}
+static int dsa_exportkey(void *key, OSSL_PARAM params[])
+{
+ DSA *dsa = key;
+
+ return dsa != NULL && !key_to_params(dsa, params);
+}
+
const OSSL_DISPATCH dsa_keymgmt_functions[] = {
/*
* TODO(3.0) When implementing OSSL_FUNC_KEYMGMT_GENKEY, remember to also
* implement OSSL_FUNC_KEYMGMT_EXPORTKEY.
*/
+ { OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS, (void (*)(void))dsa_importdomparams },
+ { OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS, (void (*)(void))dsa_exportdomparams },
+ { OSSL_FUNC_KEYMGMT_FREEDOMPARAMS, (void (*)(void))DSA_free },
{ OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dsa_importkey },
+ { OSSL_FUNC_KEYMGMT_EXPORTKEY, (void (*)(void))dsa_exportkey },
{ OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DSA_free },
{ 0, NULL }
};
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 3a843e6a43..cea1c318c6 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -1201,7 +1201,7 @@ static int test_EVP_PKEY_CTX_get_set_params(void)
const OSSL_PARAM *params;
OSSL_PARAM ourparams[2], *param = ourparams;
DSA *dsa = NULL;
- BIGNUM *p = NULL, *q = NULL, *g = NULL;
+ BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL;
EVP_PKEY *pkey = NULL;
int ret = 0;
const EVP_MD *md;
@@ -1209,21 +1209,24 @@ static int test_EVP_PKEY_CTX_get_set_params(void)
char ssl3ms[48];
/*
- * Setup the parameters for our DSA object. For our purposes they don't have
- * to actually be *valid* parameters. We just need to set something. We
- * don't even need a pub_key/priv_key.
+ * Setup the parameters for our DSA object. For our purposes they don't
+ * have to actually be *valid* parameters. We just need to set something.
*/
dsa = DSA_new();
p = BN_new();
q = BN_new();
g = BN_new();
+ pub = BN_new();
+ priv = BN_new();
if (!TEST_ptr(dsa)
|| !TEST_ptr(p)
|| !TEST_ptr(q)
|| !TEST_ptr(g)
- || !DSA_set0_pqg(dsa, p, q, g))
+ || !TEST_ptr(pub)
+ || !DSA_set0_pqg(dsa, p, q, g)
+ || !DSA_set0_key(dsa, pub, priv))
goto err;
- p = q = g = NULL;
+ p = q = g = pub = priv = NULL;
pkey = EVP_PKEY_new();
if (!TEST_ptr(pkey)
@@ -1331,6 +1334,8 @@ static int test_EVP_PKEY_CTX_get_set_params(void)
BN_free(p);
BN_free(q);
BN_free(g);
+ BN_free(pub);
+ BN_free(priv);
return ret;
}
More information about the openssl-commits
mailing list