aboutsummaryrefslogtreecommitdiff
path: root/providers
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-07-07 10:56:46 +0200
committerRichard Levitte <levitte@openssl.org>2019-07-23 19:43:09 +0200
commit8b84b075ff065554c0cdd1086950f1a8614d93a4 (patch)
tree504e19c43e2f8313665156f2220539830dece99d /providers
parent037439c46addc62130617bbba8c5e58e1548bfd8 (diff)
downloadopenssl-8b84b075ff065554c0cdd1086950f1a8614d93a4.zip
openssl-8b84b075ff065554c0cdd1086950f1a8614d93a4.tar.gz
openssl-8b84b075ff065554c0cdd1086950f1a8614d93a4.tar.bz2
Adapt DH to use with KEYMGMT
The biggest part in this was to move the key->param builder from EVP to the DH ASN.1 method, and to implement the KEYMGMT support in the provider DH. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9394)
Diffstat (limited to 'providers')
-rw-r--r--providers/common/build.info2
-rw-r--r--providers/common/exchange/build.info2
-rw-r--r--providers/common/exchange/dh_exch.c (renamed from providers/common/exchange/dh.c)70
-rw-r--r--providers/common/include/internal/provider_algs.h5
-rw-r--r--providers/common/keymgmt/build.info5
-rw-r--r--providers/common/keymgmt/dh_kmgmt.c88
-rw-r--r--providers/default/defltprov.c11
7 files changed, 123 insertions, 60 deletions
diff --git a/providers/common/build.info b/providers/common/build.info
index c77606a..bc106d0 100644
--- a/providers/common/build.info
+++ b/providers/common/build.info
@@ -1,4 +1,4 @@
-SUBDIRS=digests ciphers exchange
+SUBDIRS=digests ciphers exchange keymgmt
SOURCE[../../libcrypto]=\
provider_err.c provlib.c
diff --git a/providers/common/exchange/build.info b/providers/common/exchange/build.info
index 7957f51..c99c9d8 100644
--- a/providers/common/exchange/build.info
+++ b/providers/common/exchange/build.info
@@ -1,7 +1,7 @@
LIBS=../../../libcrypto
IF[{- !$disabled{dh} -}]
SOURCE[../../../libcrypto]=\
- dh.c
+ dh_exch.c
ENDIF
diff --git a/providers/common/exchange/dh.c b/providers/common/exchange/dh_exch.c
index ca6f0fc..439b28a 100644
--- a/providers/common/exchange/dh.c
+++ b/providers/common/exchange/dh_exch.c
@@ -21,6 +21,11 @@ static OSSL_OP_keyexch_derive_fn dh_derive;
static OSSL_OP_keyexch_freectx_fn dh_freectx;
static OSSL_OP_keyexch_dupctx_fn dh_dupctx;
+/*
+ * What's passed as an actual key is defined by the KEYMGMT interface.
+ * We happen to know that our KEYMGMT simply passes DH structures, so
+ * we use that here too.
+ */
typedef struct {
DH *dh;
@@ -33,71 +38,24 @@ static void *dh_newctx(void *provctx)
return OPENSSL_zalloc(sizeof(PROV_DH_CTX));
}
-static DH *param_to_dh(OSSL_PARAM params[], int priv)
-{
- DH *dh = DH_new();
- OSSL_PARAM *paramptr;
- BIGNUM *p = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL;
-
- if (dh == NULL)
- return NULL;
-
- paramptr = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DH_P);
- if (paramptr == NULL
- || !OSSL_PARAM_get_BN(paramptr, &p))
- goto err;
-
- paramptr = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DH_G);
- if (paramptr == NULL || !OSSL_PARAM_get_BN(paramptr, &g))
- goto err;
-
- if (!DH_set0_pqg(dh, p, NULL, g))
- goto err;
- p = g = NULL;
-
- paramptr = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DH_PUB_KEY);
- if (paramptr == NULL || !OSSL_PARAM_get_BN(paramptr, &pub_key))
- goto err;
-
- /* Private key is optional */
- if (priv) {
- paramptr = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DH_PRIV_KEY);
- if (paramptr == NULL
- || (priv_key = BN_secure_new()) == NULL
- || !OSSL_PARAM_get_BN(paramptr, &priv_key))
- goto err;
- }
-
- if (!DH_set0_key(dh, pub_key, priv_key))
- goto err;
-
- return dh;
-
- err:
- BN_free(p);
- BN_free(g);
- BN_free(pub_key);
- BN_free(priv_key);
- DH_free(dh);
- return NULL;
-}
-
-static int dh_init(void *vpdhctx, OSSL_PARAM params[])
+static int dh_init(void *vpdhctx, void *vdh)
{
PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
DH_free(pdhctx->dh);
- pdhctx->dh = param_to_dh(params, 1);
+ pdhctx->dh = vdh;
+ DH_up_ref(pdhctx->dh);
return pdhctx->dh != NULL;
}
-static int dh_set_peer(void *vpdhctx, OSSL_PARAM params[])
+static int dh_set_peer(void *vpdhctx, void *vdh)
{
PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
DH_free(pdhctx->dhpeer);
- pdhctx->dhpeer = param_to_dh(params, 0);
+ pdhctx->dhpeer = vdh;
+ DH_up_ref(pdhctx->dhpeer);
return pdhctx->dhpeer != NULL;
}
@@ -164,7 +122,7 @@ static void *dh_dupctx(void *vpdhctx)
return dstctx;
}
-static int dh_set_params(void *vpdhctx, OSSL_PARAM params[])
+static int dh_set_params(void *vpdhctx, const OSSL_PARAM params[])
{
PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
const OSSL_PARAM *p;
@@ -173,7 +131,7 @@ static int dh_set_params(void *vpdhctx, OSSL_PARAM params[])
if (pdhctx == NULL || params == NULL)
return 0;
- p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_PAD);
+ p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD);
if (p == NULL || !OSSL_PARAM_get_int(p, &pad))
return 0;
@@ -182,7 +140,7 @@ static int dh_set_params(void *vpdhctx, OSSL_PARAM params[])
return 1;
}
-const OSSL_DISPATCH dh_functions[] = {
+const OSSL_DISPATCH dh_keyexch_functions[] = {
{ OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
{ OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
{ OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))dh_derive },
diff --git a/providers/common/include/internal/provider_algs.h b/providers/common/include/internal/provider_algs.h
index dbc79a5..80946ca 100644
--- a/providers/common/include/internal/provider_algs.h
+++ b/providers/common/include/internal/provider_algs.h
@@ -58,5 +58,8 @@ extern const OSSL_DISPATCH aes256ctr_functions[];
extern const OSSL_DISPATCH aes192ctr_functions[];
extern const OSSL_DISPATCH aes128ctr_functions[];
+/* Key management */
+extern const OSSL_DISPATCH dh_keymgmt_functions[];
+
/* Key Exchange */
-extern const OSSL_DISPATCH dh_functions[];
+extern const OSSL_DISPATCH dh_keyexch_functions[];
diff --git a/providers/common/keymgmt/build.info b/providers/common/keymgmt/build.info
new file mode 100644
index 0000000..a41f3da
--- /dev/null
+++ b/providers/common/keymgmt/build.info
@@ -0,0 +1,5 @@
+LIBS=../../../libcrypto
+IF[{- !$disabled{dh} -}]
+ SOURCE[../../../libcrypto]=\
+ dh_kmgmt.c
+ENDIF
diff --git a/providers/common/keymgmt/dh_kmgmt.c b/providers/common/keymgmt/dh_kmgmt.c
new file mode 100644
index 0000000..67e3205
--- /dev/null
+++ b/providers/common/keymgmt/dh_kmgmt.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/params.h>
+#include "internal/provider_algs.h"
+
+static OSSL_OP_keymgmt_importkey_fn dh_importkey;
+
+static int params_to_key(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;
+
+ if (dh == NULL)
+ return 0;
+
+ param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_P);
+ param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_G);
+ param_priv_key =
+ OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_KEY);
+ param_pub_key =
+ OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PUB_KEY);
+
+ /*
+ * DH documentation says that a public key must be present if a
+ * private key is present.
+ * We want to have at least a public key either way, so we end up
+ * requiring it unconditionally.
+ */
+ 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))
+ || !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_importkey(void *provctx, const OSSL_PARAM params[])
+{
+ DH *dh;
+
+ if ((dh = DH_new()) == NULL
+ || !params_to_key(dh, params)) {
+ DH_free(dh);
+ dh = NULL;
+ }
+ return dh;
+}
+
+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_IMPORTKEY, (void (*)(void))dh_importkey },
+ { OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DH_free },
+ { 0, NULL }
+};
diff --git a/providers/default/defltprov.c b/providers/default/defltprov.c
index 2c25bf7..95534b1 100644
--- a/providers/default/defltprov.c
+++ b/providers/default/defltprov.c
@@ -116,7 +116,14 @@ static const OSSL_ALGORITHM deflt_ciphers[] = {
static const OSSL_ALGORITHM deflt_keyexch[] = {
#ifndef OPENSSL_NO_DH
- { "dhKeyAgreement", "default=yes", dh_functions },
+ { "dhKeyAgreement", "default=yes", dh_keyexch_functions },
+#endif
+ { NULL, NULL, NULL }
+};
+
+static const OSSL_ALGORITHM deflt_keymgmt[] = {
+#ifndef OPENSSL_NO_DH
+ { "dhKeyAgreement", "default=yes", dh_keymgmt_functions },
#endif
{ NULL, NULL, NULL }
};
@@ -131,6 +138,8 @@ static const OSSL_ALGORITHM *deflt_query(OSSL_PROVIDER *prov,
return deflt_digests;
case OSSL_OP_CIPHER:
return deflt_ciphers;
+ case OSSL_OP_KEYMGMT:
+ return deflt_keymgmt;
case OSSL_OP_KEYEXCH:
return deflt_keyexch;
}