summaryrefslogtreecommitdiffstats
path: root/crypto/evp/pmeth_gn.c
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/evp/pmeth_gn.c
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/evp/pmeth_gn.c')
-rw-r--r--crypto/evp/pmeth_gn.c84
1 files changed, 84 insertions, 0 deletions
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)
{