DH: Add export of domain parameters to provider

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10169)
This commit is contained in:
Richard Levitte 2019-10-14 10:10:58 +02:00
parent 02f060d17e
commit 14e3e00fe2
2 changed files with 58 additions and 26 deletions

View File

@ -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 = {

View File

@ -14,18 +14,46 @@
#include <openssl/params.h>
#include "prov/implementations.h"
static OSSL_OP_keymgmt_importdomparams_fn dh_importdomparams;
static OSSL_OP_keymgmt_importkey_fn dh_importkey;
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 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 +68,34 @@ 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 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 void *dh_importkey(void *provctx, const OSSL_PARAM params[])
{
DH *dh;
@ -82,6 +113,8 @@ 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_FREEDOMPARAMS, (void (*)(void))DH_free },
{ OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dh_importkey },
{ OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DH_free },
{ 0, NULL }