summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-10-15 14:50:35 +0200
committerRichard Levitte <levitte@openssl.org>2019-11-07 11:50:39 +0100
commit46e2dd05ef1456e3e8fc3d12bd839bae01576c19 (patch)
tree34349335133b5c1692863ce82627647867dbe426 /crypto
parent54a0d4ceb28d53f5b00a27fc5ca8ff8f0ddf9036 (diff)
Add EVP functionality to create domain params and keys by user data
This is the EVP operation that corresponds to creating direct RSA, DH and DSA keys and set their numbers, to then assign them to an EVP_PKEY, but done entirely using an algorithm agnostic EVP interface. Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/10187)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/evp/keymgmt_lib.c18
-rw-r--r--crypto/evp/pmeth_gn.c84
2 files changed, 102 insertions, 0 deletions
diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c
index 5e9ec73f7d..583e8b362a 100644
--- a/crypto/evp/keymgmt_lib.c
+++ b/crypto/evp/keymgmt_lib.c
@@ -254,6 +254,24 @@ void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk)
}
}
+void *evp_keymgmt_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
+ const OSSL_PARAM params[], int domainparams)
+{
+ void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
+ void *provdata = domainparams
+ ? keymgmt->importdomparams(provctx, params)
+ : keymgmt->importkey(provctx, params);
+
+ evp_keymgmt_clear_pkey_cache(target);
+ if (provdata != NULL) {
+ EVP_KEYMGMT_up_ref(keymgmt);
+ target->pkeys[0].keymgmt = keymgmt;
+ target->pkeys[0].provdata = provdata;
+ target->pkeys[0].domainparams = domainparams;
+ }
+
+ return provdata;
+}
/* internal functions */
/* TODO(3.0) decide if these should be public or internal */
diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c
index 2564bbd03e..f872377671 100644
--- a/crypto/evp/pmeth_gn.c
+++ b/crypto/evp/pmeth_gn.c
@@ -15,6 +15,90 @@
#include "crypto/bn.h"
#include "crypto/asn1.h"
#include "crypto/evp.h"
+#include "evp_local.h"
+
+static int fromdata_init(EVP_PKEY_CTX *ctx, int operation)
+{
+ if (ctx == NULL || ctx->algorithm == NULL)
+ goto not_supported;
+
+ evp_pkey_ctx_free_old_ops(ctx);
+ ctx->operation = operation;
+ if (ctx->keymgmt == NULL)
+ ctx->keymgmt = EVP_KEYMGMT_fetch(NULL, ctx->algorithm, ctx->propquery);
+ if (ctx->keymgmt == NULL)
+ goto not_supported;
+
+ return 1;
+
+ not_supported:
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+}
+
+int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx)
+{
+ return fromdata_init(ctx, EVP_PKEY_OP_PARAMFROMDATA);
+}
+
+int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx)
+{
+ return fromdata_init(ctx, EVP_PKEY_OP_KEYFROMDATA);
+}
+
+int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[])
+{
+ void *provdata = NULL;
+
+ if (ctx == NULL || (ctx->operation & EVP_PKEY_OP_TYPE_FROMDATA) == 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ if (ppkey == NULL)
+ return -1;
+
+ if (*ppkey == NULL)
+ *ppkey = EVP_PKEY_new();
+
+ if (*ppkey == NULL) {
+ ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ provdata =
+ evp_keymgmt_fromdata(*ppkey, ctx->keymgmt, params,
+ ctx->operation == EVP_PKEY_OP_PARAMFROMDATA);
+
+ if (provdata == NULL)
+ return 0;
+ /* provdata is cached in *ppkey, so we need not bother with it further */
+ return 1;
+}
+
+/*
+ * TODO(3.0) Re-evalutate the names, it's possible that we find these to be
+ * better:
+ *
+ * EVP_PKEY_param_settable()
+ * EVP_PKEY_param_gettable()
+ */
+const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx)
+{
+ /* We call fromdata_init to get ctx->keymgmt populated */
+ if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
+ return evp_keymgmt_importdomparam_types(ctx->keymgmt);
+ return NULL;
+}
+
+const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx)
+{
+ /* We call fromdata_init to get ctx->keymgmt populated */
+ if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
+ return evp_keymgmt_importdomparam_types(ctx->keymgmt);
+ return NULL;
+}
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
{