Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
+ *) Added functionality to create an EVP_PKEY from user data. This
+ is effectively the same as creating a RSA, DH or DSA object and
+ then assigning them to an EVP_PKEY, but directly using algorithm
+ agnostic EVP functions. A benefit is that this should be future
+ proof for public key algorithms to come.
+ [Richard Levitte]
+
*) Change the interpretation of the '--api' configuration option to
mean that this is a desired API compatibility level with no
further meaning. The previous interpretation, that this would
}
}
+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 */
#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)
{
--- /dev/null
+=pod
+
+=head1 NAME
+
+EVP_PKEY_param_fromdata_init, EVP_PKEY_key_fromdata_init, EVP_PKEY_fromdata,
+EVP_PKEY_param_fromdata_settable, EVP_PKEY_key_fromdata_settable
+- functions to create domain parameters and keys from user data
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[]);
+ const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx);
+ const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx);
+
+=head1 DESCRIPTION
+
+EVP_PKEY_param_fromdata_init() initializes a public key algorithm context
+for creating domain parameters from user data.
+
+EVP_PKEY_key_fromdata_init() initializes a public key algorithm context for
+creating a key from user data.
+
+EVP_PKEY_fromdata() creates domain parameters or a key, given data from
+I<params> and a context that's been initialized with
+EVP_PKEY_param_fromdata_init() or EVP_PKEY_key_fromdata_init(). The result is
+written to I<*ppkey>.
+
+EVP_PKEY_param_fromdata_settable() and EVP_PKEY_key_fromdata_settable()
+get a constant B<OSSL_PARAM> array that describes the settable parameters
+that can be used with EVP_PKEY_fromdata().
+See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
+
+=head1 NOTES
+
+These functions only work with key management methods coming from a
+provider.
+
+=for comment We may choose to make this available for legacy methods too...
+
+=head1 RETURN VALUES
+
+EVP_PKEY_key_fromdata_init(), EVP_PKEY_param_fromdata_init() and
+EVP_PKEY_fromdata() return 1 for success and 0 or a negative value for
+failure. In particular a return value of -2 indicates the operation is
+not supported by the public key algorithm.
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)>, L<provider(7)>
+
+=head1 HISTORY
+
+These functions were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
+
void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
int domainparams);
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);
+
/* KEYMGMT provider interface functions */
void *evp_keymgmt_importdomparams(const EVP_KEYMGMT *keymgmt,
# define EVP_PKEY_OP_UNDEFINED 0
# define EVP_PKEY_OP_PARAMGEN (1<<1)
# define EVP_PKEY_OP_KEYGEN (1<<2)
-# define EVP_PKEY_OP_SIGN (1<<3)
-# define EVP_PKEY_OP_VERIFY (1<<4)
-# define EVP_PKEY_OP_VERIFYRECOVER (1<<5)
-# define EVP_PKEY_OP_SIGNCTX (1<<6)
-# define EVP_PKEY_OP_VERIFYCTX (1<<7)
-# define EVP_PKEY_OP_ENCRYPT (1<<8)
-# define EVP_PKEY_OP_DECRYPT (1<<9)
-# define EVP_PKEY_OP_DERIVE (1<<10)
+# define EVP_PKEY_OP_PARAMFROMDATA (1<<3)
+# define EVP_PKEY_OP_KEYFROMDATA (1<<4)
+# define EVP_PKEY_OP_SIGN (1<<5)
+# define EVP_PKEY_OP_VERIFY (1<<6)
+# define EVP_PKEY_OP_VERIFYRECOVER (1<<7)
+# define EVP_PKEY_OP_SIGNCTX (1<<8)
+# define EVP_PKEY_OP_VERIFYCTX (1<<9)
+# define EVP_PKEY_OP_ENCRYPT (1<<10)
+# define EVP_PKEY_OP_DECRYPT (1<<11)
+# define EVP_PKEY_OP_DERIVE (1<<12)
# define EVP_PKEY_OP_TYPE_SIG \
(EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
(EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_DERIVE)
# define EVP_PKEY_OP_TYPE_GEN \
- (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+ (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+
+# define EVP_PKEY_OP_TYPE_FROMDATA \
+ (EVP_PKEY_OP_PARAMFROMDATA | EVP_PKEY_OP_KEYFROMDATA)
# define EVP_PKEY_CTX_set_mac_key(ctx, key, len) \
EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, \
typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM param[]);
+const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx);
+const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx);
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
X509_STORE_load_file ? 3_0_0 EXIST::FUNCTION:
X509_STORE_load_path ? 3_0_0 EXIST::FUNCTION:
X509_STORE_load_store ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_param_fromdata_init ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_key_fromdata_init ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_fromdata ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_param_fromdata_settable ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_key_fromdata_settable ? 3_0_0 EXIST::FUNCTION: