evp_pkey_ctx_free_old_ops(ctx);
ctx->operation = EVP_PKEY_OP_DERIVE;
- if (ctx->engine != NULL || ctx->algorithm == NULL)
+ if (ctx->engine != NULL || ctx->keytype == NULL)
goto legacy;
- /*
- * Because we cleared out old ops, we shouldn't need to worry about
- * checking if exchange is already there. Keymgmt is a different
- * matter, as it isn't tied to a specific EVP_PKEY op.
- */
- exchange = EVP_KEYEXCH_fetch(ctx->libctx, ctx->algorithm, ctx->propquery);
- if (exchange != NULL && ctx->keymgmt == NULL) {
- int name_id = EVP_KEYEXCH_number(exchange);
-
+ if (ctx->keymgmt == NULL)
ctx->keymgmt =
- evp_keymgmt_fetch_by_number(ctx->libctx, name_id, ctx->propquery);
+ EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery);
+ if (ctx->keymgmt != NULL) {
+ const char *supported_exch = NULL;
+
+ if (ctx->keymgmt->query_operation_name != NULL)
+ supported_exch =
+ ctx->keymgmt->query_operation_name(OSSL_OP_KEYEXCH);
+
+ /*
+ * If we didn't get a supported exch, assume there is one with the
+ * same name as the key type.
+ */
+ if (supported_exch == NULL)
+ supported_exch = ctx->keytype;
+
+ /*
+ * Because we cleared out old ops, we shouldn't need to worry about
+ * checking if exchange is already there.
+ */
+ exchange =
+ EVP_KEYEXCH_fetch(ctx->libctx, supported_exch, ctx->propquery);
}
if (ctx->keymgmt == NULL
locpctx = ctx->pctx;
evp_pkey_ctx_free_old_ops(locpctx);
- if (locpctx->algorithm == NULL)
+ if (locpctx->keytype == NULL)
goto legacy;
if (mdname == NULL) {
}
}
- /*
- * Because we cleared out old ops, we shouldn't need to worry about
- * checking if signature is already there. Keymgmt is a different
- * matter, as it isn't tied to a specific EVP_PKEY op.
- */
- signature = EVP_SIGNATURE_fetch(locpctx->libctx, locpctx->algorithm,
- locpctx->propquery);
- if (signature != NULL && locpctx->keymgmt == NULL) {
- int name_id = EVP_SIGNATURE_number(signature);
+ if (locpctx->keymgmt == NULL)
+ locpctx->keymgmt = EVP_KEYMGMT_fetch(locpctx->libctx, locpctx->keytype,
+ locpctx->propquery);
+ if (locpctx->keymgmt != NULL) {
+ const char *supported_sig = NULL;
+
+ if (locpctx->keymgmt->query_operation_name != NULL)
+ supported_sig =
+ locpctx->keymgmt->query_operation_name(OSSL_OP_SIGNATURE);
+
+ /*
+ * If we didn't get a supported sig, assume there is one with the
+ * same name as the key type.
+ */
+ if (supported_sig == NULL)
+ supported_sig = locpctx->keytype;
- locpctx->keymgmt =
- evp_keymgmt_fetch_by_number(locpctx->libctx, name_id,
+ /*
+ * Because we cleared out old ops, we shouldn't need to worry about
+ * checking if signature is already there.
+ */
+ signature = EVP_SIGNATURE_fetch(locpctx->libctx, supported_sig,
locpctx->propquery);
}
evp_pkey_ctx_free_old_ops(ctx);
ctx->operation = operation;
- if (ctx->algorithm == NULL)
+ if (ctx->keytype == NULL)
goto legacy;
- /*
- * Because we cleared out old ops, we shouldn't need to worry about
- * checking if signature is already there. Keymgmt is a different
- * matter, as it isn't tied to a specific EVP_PKEY op.
- */
- signature = EVP_SIGNATURE_fetch(ctx->libctx, ctx->algorithm,
- ctx->propquery);
- if (signature != NULL && ctx->keymgmt == NULL) {
- int name_id = EVP_SIGNATURE_number(signature);
+ if (ctx->keymgmt == NULL)
+ ctx->keymgmt =
+ EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery);
+ if (ctx->keymgmt != NULL) {
+ const char *supported_sig = NULL;
+
+ if (ctx->keymgmt->query_operation_name != NULL)
+ supported_sig =
+ ctx->keymgmt->query_operation_name(OSSL_OP_SIGNATURE);
+
+ /*
+ * If we didn't get a supported sig, assume there is one with the
+ * same name as the key type.
+ */
+ if (supported_sig == NULL)
+ supported_sig = ctx->keytype;
- ctx->keymgmt = evp_keymgmt_fetch_by_number(ctx->libctx, name_id,
- ctx->propquery);
+ /*
+ * Because we cleared out old ops, we shouldn't need to worry about
+ * checking if signature is already there.
+ */
+ signature =
+ EVP_SIGNATURE_fetch(ctx->libctx, supported_sig, ctx->propquery);
}
if (ctx->keymgmt == NULL
evp_pkey_ctx_free_old_ops(ctx);
ctx->operation = operation;
- if (ctx->algorithm == NULL || ctx->engine != NULL)
+ if (ctx->keytype == NULL || ctx->engine != NULL)
goto legacy;
- /*
- * Because we cleared out old ops, we shouldn't need to worry about
- * checking if exchange is already there. Keymgmt is a different
- * matter, as it isn't tied to a specific EVP_PKEY op.
- */
- cipher = EVP_ASYM_CIPHER_fetch(ctx->libctx, ctx->algorithm, ctx->propquery);
- if (cipher != NULL && ctx->keymgmt == NULL) {
- int name_id = EVP_ASYM_CIPHER_number(cipher);
-
+ if (ctx->keymgmt == NULL)
ctx->keymgmt =
- evp_keymgmt_fetch_by_number(ctx->libctx, name_id, ctx->propquery);
+ EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery);
+ if (ctx->keymgmt != NULL) {
+ const char *supported_ciph = NULL;
+
+ if (ctx->keymgmt->query_operation_name != NULL)
+ supported_ciph =
+ ctx->keymgmt->query_operation_name(OSSL_OP_ASYM_CIPHER);
+
+ /*
+ * If we didn't get a supported ciph, assume there is one with the
+ * same name as the key type.
+ */
+ if (supported_ciph == NULL)
+ supported_ciph = ctx->keytype;
+
+ /*
+ * Because we cleared out old ops, we shouldn't need to worry about
+ * checking if cipher is already there.
+ */
+ cipher =
+ EVP_ASYM_CIPHER_fetch(ctx->libctx, supported_ciph, ctx->propquery);
}
if (ctx->keymgmt == NULL
static int fromdata_init(EVP_PKEY_CTX *ctx, int operation)
{
- if (ctx == NULL || ctx->algorithm == NULL)
+ if (ctx == NULL || ctx->keytype == 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);
+ ctx->keymgmt = EVP_KEYMGMT_fetch(NULL, ctx->keytype, ctx->propquery);
if (ctx->keymgmt == NULL)
goto not_supported;
return NULL;
}
ret->libctx = libctx;
- ret->algorithm = name;
+ ret->keytype = name;
ret->propquery = propquery;
ret->engine = e;
ret->pmeth = pmeth;
rctx->pkey = pctx->pkey;
rctx->operation = pctx->operation;
rctx->libctx = pctx->libctx;
- rctx->algorithm = pctx->algorithm;
+ rctx->keytype = pctx->keytype;
rctx->propquery = pctx->propquery;
if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) {
=head1 DESCRIPTION
The EVP_PKEY_CTX_new() function allocates public key algorithm context using
-the algorithm specified in I<pkey> and ENGINE I<e>.
+the I<pkey> key type and ENGINE I<e>.
The EVP_PKEY_CTX_new_id() function allocates public key algorithm context
-using the algorithm specified by I<id> and ENGINE I<e>.
+using the key type specified by I<id> and ENGINE I<e>.
The EVP_PKEY_CTX_new_provided() function allocates a public key algorithm
context using the library context I<libctx> (see L<OPENSSL_CTX(3)>), the
-algorithm specified by I<name> and the property query I<propquery>. None
+key type specified by I<name> and the property query I<propquery>. None
of the arguments are duplicated, so they must remain unchanged for the
lifetime of the returned B<EVP_PKEY_CTX> or of any of its duplicates.
=head1 NOTES
+=over 4
+
+=item 1.
+
The B<EVP_PKEY_CTX> structure is an opaque public key algorithm context used
by the OpenSSL high level public key API. Contexts B<MUST NOT> be shared between
threads: that is it is not permissible to use the same context simultaneously
in two threads.
+=item 2.
+
+We mention "key type" in this manual, which is the same
+as "algorithm" in most cases, allowing either term to be used
+interchangeably. There are algorithms where the I<key type> and the
+I<algorithm> of the operations that use the keys are not the same,
+such as EC keys being used for ECDSA and ECDH operations.
+
+=back
+
=head1 RETURN VALUES
EVP_PKEY_CTX_new(), EVP_PKEY_CTX_new_id(), EVP_PKEY_CTX_dup() returns either
int operation;
/*
- * Library context, Algorithm name and properties associated
+ * Library context, Key type name and properties associated
* with this context
*/
OPENSSL_CTX *libctx;
- const char *algorithm;
+ const char *keytype;
const char *propquery;
/* cached key manager */