2019-07-09 23:31:24 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
/*
|
2018-03-20 21:00:17 +08:00
|
|
|
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
2006-04-06 21:02:06 +08:00
|
|
|
*
|
2018-12-06 20:40:06 +08:00
|
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
2016-05-18 02:24:46 +08:00
|
|
|
* 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
|
2006-04-06 21:02:06 +08:00
|
|
|
*/
|
|
|
|
|
2020-02-03 17:05:31 +08:00
|
|
|
/*
|
|
|
|
* DH low level APIs are deprecated for public use, but still ok for
|
|
|
|
* internal use.
|
|
|
|
*/
|
|
|
|
#include "internal/deprecated.h"
|
|
|
|
|
2006-04-06 21:02:06 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2016-03-19 02:30:20 +08:00
|
|
|
#include <openssl/engine.h>
|
2015-12-27 22:59:04 +08:00
|
|
|
#include <openssl/evp.h>
|
2016-03-01 22:47:15 +08:00
|
|
|
#include <openssl/x509v3.h>
|
2019-06-27 23:37:44 +08:00
|
|
|
#include <openssl/core_names.h>
|
|
|
|
#include <openssl/dh.h>
|
2019-10-28 21:40:39 +08:00
|
|
|
#include <openssl/rsa.h>
|
2019-06-27 23:37:44 +08:00
|
|
|
#include "internal/cryptlib.h"
|
2019-09-28 06:45:33 +08:00
|
|
|
#include "crypto/asn1.h"
|
|
|
|
#include "crypto/evp.h"
|
2016-03-01 22:47:15 +08:00
|
|
|
#include "internal/numbers.h"
|
2019-09-02 23:48:26 +08:00
|
|
|
#include "internal/provider.h"
|
2019-09-28 06:45:40 +08:00
|
|
|
#include "evp_local.h"
|
2006-04-06 21:02:06 +08:00
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
#ifndef FIPS_MODE
|
|
|
|
|
2019-09-19 21:31:27 +08:00
|
|
|
typedef const EVP_PKEY_METHOD *(*pmeth_fn)(void);
|
2015-01-22 11:40:55 +08:00
|
|
|
typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
|
2008-06-04 19:01:43 +08:00
|
|
|
|
2015-09-05 20:32:58 +08:00
|
|
|
static STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
|
2006-04-06 21:02:06 +08:00
|
|
|
|
2017-07-23 02:04:55 +08:00
|
|
|
/* This array needs to be in order of NIDs */
|
2019-09-19 21:31:27 +08:00
|
|
|
static pmeth_fn standard_methods[] = {
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_RSA
|
2019-09-19 21:31:27 +08:00
|
|
|
rsa_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
|
|
|
# ifndef OPENSSL_NO_DH
|
2019-09-19 21:31:27 +08:00
|
|
|
dh_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
|
|
|
# ifndef OPENSSL_NO_DSA
|
2019-09-19 21:31:27 +08:00
|
|
|
dsa_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
|
|
|
# ifndef OPENSSL_NO_EC
|
2019-09-19 21:31:27 +08:00
|
|
|
ec_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2019-09-19 21:31:27 +08:00
|
|
|
hmac_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_CMAC
|
2019-09-19 21:31:27 +08:00
|
|
|
cmac_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
|
|
|
# ifndef OPENSSL_NO_RSA
|
2019-09-19 21:31:27 +08:00
|
|
|
rsa_pss_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
|
|
|
# ifndef OPENSSL_NO_DH
|
2019-09-19 21:31:27 +08:00
|
|
|
dhx_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
|
|
|
# ifndef OPENSSL_NO_SCRYPT
|
2019-09-19 21:31:27 +08:00
|
|
|
scrypt_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2019-09-19 21:31:27 +08:00
|
|
|
tls1_prf_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_EC
|
2019-09-19 21:31:27 +08:00
|
|
|
ecx25519_pkey_method,
|
|
|
|
ecx448_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2019-09-19 21:31:27 +08:00
|
|
|
hkdf_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_POLY1305
|
2019-09-19 21:31:27 +08:00
|
|
|
poly1305_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
|
|
|
# ifndef OPENSSL_NO_SIPHASH
|
2019-09-19 21:31:27 +08:00
|
|
|
siphash_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
|
|
|
# ifndef OPENSSL_NO_EC
|
2019-09-19 21:31:27 +08:00
|
|
|
ed25519_pkey_method,
|
|
|
|
ed448_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
|
|
|
# ifndef OPENSSL_NO_SM2
|
2019-09-19 21:31:27 +08:00
|
|
|
sm2_pkey_method,
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2015-01-22 11:40:55 +08:00
|
|
|
};
|
2006-04-06 21:02:06 +08:00
|
|
|
|
2019-09-19 21:31:27 +08:00
|
|
|
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, pmeth_fn, pmeth_func);
|
|
|
|
|
|
|
|
static int pmeth_func_cmp(const EVP_PKEY_METHOD *const *a, pmeth_fn const *b)
|
|
|
|
{
|
|
|
|
return ((*a)->pkey_id - ((**b)())->pkey_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, pmeth_fn, pmeth_func);
|
2008-10-12 22:32:47 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
static int pmeth_cmp(const EVP_PKEY_METHOD *const *a,
|
|
|
|
const EVP_PKEY_METHOD *const *b)
|
|
|
|
{
|
|
|
|
return ((*a)->pkey_id - (*b)->pkey_id);
|
|
|
|
}
|
2006-04-06 21:02:06 +08:00
|
|
|
|
2006-06-02 20:33:39 +08:00
|
|
|
const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2019-09-19 21:31:27 +08:00
|
|
|
pmeth_fn *ret;
|
2015-01-22 11:40:55 +08:00
|
|
|
EVP_PKEY_METHOD tmp;
|
2019-09-19 21:31:27 +08:00
|
|
|
const EVP_PKEY_METHOD *t = &tmp;
|
2019-09-17 03:28:57 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
tmp.pkey_id = type;
|
|
|
|
if (app_pkey_methods) {
|
|
|
|
int idx;
|
|
|
|
idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
|
|
|
|
if (idx >= 0)
|
|
|
|
return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
|
|
|
|
}
|
2019-09-19 21:31:27 +08:00
|
|
|
ret = OBJ_bsearch_pmeth_func(&t, standard_methods,
|
|
|
|
sizeof(standard_methods) /
|
|
|
|
sizeof(pmeth_fn));
|
2019-09-17 03:28:57 +08:00
|
|
|
if (ret == NULL || *ret == NULL)
|
2015-01-22 11:40:55 +08:00
|
|
|
return NULL;
|
2019-09-19 21:31:27 +08:00
|
|
|
return (**ret)();
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2006-04-06 21:02:06 +08:00
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
|
|
|
|
{
|
|
|
|
EVP_PKEY_METHOD *pmeth;
|
|
|
|
|
|
|
|
pmeth = OPENSSL_zalloc(sizeof(*pmeth));
|
|
|
|
if (pmeth == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pmeth->pkey_id = id;
|
|
|
|
pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
|
|
|
|
return pmeth;
|
|
|
|
}
|
|
|
|
#endif /* FIPS_MODE */
|
|
|
|
|
2019-11-01 23:56:31 +08:00
|
|
|
static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
|
|
|
EVP_PKEY *pkey, ENGINE *e,
|
2019-10-15 19:08:17 +08:00
|
|
|
const char *name, const char *propquery,
|
|
|
|
int id)
|
2020-01-12 09:32:12 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
EVP_PKEY_CTX *ret;
|
2019-07-09 23:31:24 +08:00
|
|
|
const EVP_PKEY_METHOD *pmeth = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* When using providers, the context is bound to the algo implementation
|
|
|
|
* later.
|
|
|
|
*/
|
|
|
|
if (pkey == NULL && e == NULL && id == -1)
|
|
|
|
goto common;
|
2018-06-19 03:49:15 +08:00
|
|
|
|
2019-12-02 19:00:58 +08:00
|
|
|
/*
|
|
|
|
* If the key doesn't contain anything legacy, then it must be provided,
|
|
|
|
* so we extract the necessary information and use that.
|
|
|
|
*/
|
2020-01-14 16:09:30 +08:00
|
|
|
if (pkey != NULL && pkey->ameth == NULL) {
|
2019-12-02 19:00:58 +08:00
|
|
|
/* If we have an engine, something went wrong somewhere... */
|
|
|
|
if (!ossl_assert(e == NULL))
|
|
|
|
return NULL;
|
2020-02-21 03:26:16 +08:00
|
|
|
name = evp_first_name(pkey->keymgmt->prov, pkey->keymgmt->name_id);
|
2019-12-02 19:00:58 +08:00
|
|
|
/*
|
|
|
|
* TODO: I wonder if the EVP_PKEY should have the name and propquery
|
|
|
|
* that were used when building it.... /RL
|
|
|
|
*/
|
|
|
|
goto common;
|
|
|
|
}
|
2020-01-12 09:32:12 +08:00
|
|
|
#ifndef FIPS_MODE
|
2019-07-09 23:31:24 +08:00
|
|
|
/* TODO(3.0) Legacy code should be removed when all is provider based */
|
|
|
|
/* BEGIN legacy */
|
2015-01-22 11:40:55 +08:00
|
|
|
if (id == -1) {
|
2018-09-07 07:04:59 +08:00
|
|
|
if (pkey == NULL)
|
2019-12-02 19:00:58 +08:00
|
|
|
return NULL;
|
2018-06-19 03:49:15 +08:00
|
|
|
id = pkey->type;
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2019-10-31 18:43:31 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Here, we extract what information we can for the purpose of
|
|
|
|
* supporting usage with implementations from providers, to make
|
|
|
|
* for a smooth transition from legacy stuff to provider based stuff.
|
|
|
|
*
|
|
|
|
* If an engine is given, this is entirely legacy, and we should not
|
|
|
|
* pretend anything else, so we only set the name when no engine is
|
|
|
|
* given. If both are already given, someone made a mistake, and
|
|
|
|
* since that can only happen internally, it's safe to make an
|
|
|
|
* assertion.
|
|
|
|
*/
|
|
|
|
if (!ossl_assert(e == NULL || name == NULL))
|
|
|
|
return NULL;
|
|
|
|
if (e == NULL)
|
|
|
|
name = OBJ_nid2sn(id);
|
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_ENGINE
|
2017-10-09 21:37:21 +08:00
|
|
|
if (e == NULL && pkey != NULL)
|
2017-10-09 22:21:11 +08:00
|
|
|
e = pkey->pmeth_engine != NULL ? pkey->pmeth_engine : pkey->engine;
|
2015-01-22 11:40:55 +08:00
|
|
|
/* Try to find an ENGINE which implements this method */
|
|
|
|
if (e) {
|
|
|
|
if (!ENGINE_init(e)) {
|
|
|
|
EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB);
|
|
|
|
return NULL;
|
|
|
|
}
|
2017-10-09 21:37:21 +08:00
|
|
|
} else {
|
2015-01-22 11:40:55 +08:00
|
|
|
e = ENGINE_get_pkey_meth_engine(id);
|
2017-10-09 21:37:21 +08:00
|
|
|
}
|
2015-01-22 11:40:55 +08:00
|
|
|
|
|
|
|
/*
|
2016-02-06 04:23:54 +08:00
|
|
|
* If an ENGINE handled this method look it up. Otherwise use internal
|
2015-01-22 11:40:55 +08:00
|
|
|
* tables.
|
|
|
|
*/
|
|
|
|
if (e)
|
|
|
|
pmeth = ENGINE_get_pkey_meth(e, id);
|
|
|
|
else
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2015-01-22 11:40:55 +08:00
|
|
|
pmeth = EVP_PKEY_meth_find(id);
|
2006-06-02 20:33:39 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
if (pmeth == NULL) {
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_ENGINE
|
2017-10-10 06:24:26 +08:00
|
|
|
ENGINE_finish(e);
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2015-01-22 11:40:55 +08:00
|
|
|
EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
|
|
|
|
return NULL;
|
|
|
|
}
|
2019-07-09 23:31:24 +08:00
|
|
|
/* END legacy */
|
2020-01-12 09:32:12 +08:00
|
|
|
#endif /* FIPS_MODE */
|
2019-07-09 23:31:24 +08:00
|
|
|
common:
|
2015-09-03 21:15:26 +08:00
|
|
|
ret = OPENSSL_zalloc(sizeof(*ret));
|
2015-10-30 19:12:26 +08:00
|
|
|
if (ret == NULL) {
|
2020-01-12 09:32:12 +08:00
|
|
|
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
|
2016-02-26 01:09:06 +08:00
|
|
|
ENGINE_finish(e);
|
2009-02-15 23:28:18 +08:00
|
|
|
#endif
|
2015-01-22 11:40:55 +08:00
|
|
|
EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
|
|
|
return NULL;
|
|
|
|
}
|
2019-11-01 23:56:31 +08:00
|
|
|
ret->libctx = libctx;
|
2019-12-18 20:24:27 +08:00
|
|
|
ret->keytype = name;
|
2019-10-15 19:08:17 +08:00
|
|
|
ret->propquery = propquery;
|
2015-01-22 11:40:55 +08:00
|
|
|
ret->engine = e;
|
|
|
|
ret->pmeth = pmeth;
|
|
|
|
ret->operation = EVP_PKEY_OP_UNDEFINED;
|
|
|
|
ret->pkey = pkey;
|
2018-09-07 07:04:59 +08:00
|
|
|
if (pkey != NULL)
|
2016-02-26 20:21:15 +08:00
|
|
|
EVP_PKEY_up_ref(pkey);
|
2015-01-22 11:40:55 +08:00
|
|
|
|
2019-07-07 16:56:46 +08:00
|
|
|
if (pmeth != NULL && pmeth->init != NULL) {
|
2015-01-22 11:40:55 +08:00
|
|
|
if (pmeth->init(ret) <= 0) {
|
2017-02-02 01:29:47 +08:00
|
|
|
ret->pmeth = NULL;
|
2015-01-22 11:40:55 +08:00
|
|
|
EVP_PKEY_CTX_free(ret);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
/*- All methods below can also be used in FIPS_MODE */
|
|
|
|
|
|
|
|
EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OPENSSL_CTX *libctx,
|
|
|
|
const char *name,
|
|
|
|
const char *propquery)
|
|
|
|
{
|
|
|
|
return int_ctx_new(libctx, NULL, NULL, name, propquery, -1);
|
|
|
|
}
|
|
|
|
|
2020-01-15 19:10:43 +08:00
|
|
|
EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OPENSSL_CTX *libctx, EVP_PKEY *pkey,
|
|
|
|
const char *propquery)
|
2020-01-12 09:32:12 +08:00
|
|
|
{
|
2020-01-15 19:10:43 +08:00
|
|
|
return int_ctx_new(libctx, pkey, NULL, NULL, propquery, -1);
|
2020-01-12 09:32:12 +08:00
|
|
|
}
|
|
|
|
|
2019-09-05 06:13:25 +08:00
|
|
|
void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx)
|
|
|
|
{
|
2020-01-12 09:32:12 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) {
|
2019-09-05 06:13:25 +08:00
|
|
|
if (ctx->op.sig.sigprovctx != NULL && ctx->op.sig.signature != NULL)
|
|
|
|
ctx->op.sig.signature->freectx(ctx->op.sig.sigprovctx);
|
|
|
|
EVP_SIGNATURE_free(ctx->op.sig.signature);
|
2019-10-30 05:17:19 +08:00
|
|
|
ctx->op.sig.sigprovctx = NULL;
|
|
|
|
ctx->op.sig.signature = NULL;
|
2020-01-23 18:33:28 +08:00
|
|
|
} else if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
|
2020-01-12 09:32:12 +08:00
|
|
|
if (ctx->op.kex.exchprovctx != NULL && ctx->op.kex.exchange != NULL)
|
|
|
|
ctx->op.kex.exchange->freectx(ctx->op.kex.exchprovctx);
|
|
|
|
EVP_KEYEXCH_free(ctx->op.kex.exchange);
|
|
|
|
ctx->op.kex.exchprovctx = NULL;
|
|
|
|
ctx->op.kex.exchange = NULL;
|
2020-01-23 18:33:28 +08:00
|
|
|
}
|
|
|
|
/* TODO(3.0): add dependancies and uncomment this when available for fips mode */
|
|
|
|
#ifndef FIPS_MODE
|
|
|
|
else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
|
2019-10-01 16:40:57 +08:00
|
|
|
if (ctx->op.ciph.ciphprovctx != NULL && ctx->op.ciph.cipher != NULL)
|
|
|
|
ctx->op.ciph.cipher->freectx(ctx->op.ciph.ciphprovctx);
|
|
|
|
EVP_ASYM_CIPHER_free(ctx->op.ciph.cipher);
|
|
|
|
ctx->op.ciph.ciphprovctx = NULL;
|
|
|
|
ctx->op.ciph.cipher = NULL;
|
2019-10-27 22:09:26 +08:00
|
|
|
} else if (EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
|
|
|
|
if (ctx->op.keymgmt.genctx != NULL && ctx->keymgmt != NULL)
|
|
|
|
evp_keymgmt_gen_cleanup(ctx->keymgmt, ctx->op.keymgmt.genctx);
|
2019-09-05 06:13:25 +08:00
|
|
|
}
|
2020-01-12 09:32:12 +08:00
|
|
|
#endif
|
2019-09-05 06:13:25 +08:00
|
|
|
}
|
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2020-01-12 09:32:12 +08:00
|
|
|
if (ctx == NULL)
|
|
|
|
return;
|
|
|
|
if (ctx->pmeth && ctx->pmeth->cleanup)
|
|
|
|
ctx->pmeth->cleanup(ctx);
|
2015-05-02 11:10:31 +08:00
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
evp_pkey_ctx_free_old_ops(ctx);
|
|
|
|
EVP_KEYMGMT_free(ctx->keymgmt);
|
2015-01-22 11:40:55 +08:00
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
EVP_PKEY_free(ctx->pkey);
|
|
|
|
EVP_PKEY_free(ctx->peerkey);
|
|
|
|
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
|
|
|
|
ENGINE_finish(ctx->engine);
|
|
|
|
#endif
|
|
|
|
OPENSSL_free(ctx);
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
#ifndef FIPS_MODE
|
|
|
|
|
2010-11-25 00:08:20 +08:00
|
|
|
void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
|
2015-01-22 11:40:55 +08:00
|
|
|
const EVP_PKEY_METHOD *meth)
|
|
|
|
{
|
|
|
|
if (ppkey_id)
|
|
|
|
*ppkey_id = meth->pkey_id;
|
|
|
|
if (pflags)
|
|
|
|
*pflags = meth->flags;
|
|
|
|
}
|
2010-11-25 00:08:20 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->init = src->init;
|
|
|
|
dst->copy = src->copy;
|
|
|
|
dst->cleanup = src->cleanup;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->paramgen_init = src->paramgen_init;
|
|
|
|
dst->paramgen = src->paramgen;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->keygen_init = src->keygen_init;
|
|
|
|
dst->keygen = src->keygen;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->sign_init = src->sign_init;
|
|
|
|
dst->sign = src->sign;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->verify_init = src->verify_init;
|
|
|
|
dst->verify = src->verify;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->verify_recover_init = src->verify_recover_init;
|
|
|
|
dst->verify_recover = src->verify_recover;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->signctx_init = src->signctx_init;
|
|
|
|
dst->signctx = src->signctx;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->verifyctx_init = src->verifyctx_init;
|
|
|
|
dst->verifyctx = src->verifyctx;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->encrypt_init = src->encrypt_init;
|
|
|
|
dst->encrypt = src->encrypt;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->decrypt_init = src->decrypt_init;
|
|
|
|
dst->decrypt = src->decrypt;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->derive_init = src->derive_init;
|
|
|
|
dst->derive = src->derive;
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
dst->ctrl = src->ctrl;
|
|
|
|
dst->ctrl_str = src->ctrl_str;
|
2017-09-04 22:02:59 +08:00
|
|
|
|
|
|
|
dst->check = src->check;
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2010-11-25 00:08:20 +08:00
|
|
|
|
2006-04-14 20:41:35 +08:00
|
|
|
void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
|
|
|
|
OPENSSL_free(pmeth);
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
2006-04-11 21:28:52 +08:00
|
|
|
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2019-11-01 23:56:31 +08:00
|
|
|
return int_ctx_new(NULL, pkey, e, NULL, NULL, -1);
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2006-04-11 21:28:52 +08:00
|
|
|
|
|
|
|
EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2019-11-01 23:56:31 +08:00
|
|
|
return int_ctx_new(NULL, NULL, e, NULL, NULL, id);
|
2019-10-15 19:08:17 +08:00
|
|
|
}
|
|
|
|
|
2019-01-16 04:51:25 +08:00
|
|
|
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
EVP_PKEY_CTX *rctx;
|
2019-06-27 17:48:17 +08:00
|
|
|
|
|
|
|
if (((pctx->pmeth == NULL) || (pctx->pmeth->copy == NULL))
|
2019-09-05 06:13:25 +08:00
|
|
|
&& ((EVP_PKEY_CTX_IS_DERIVE_OP(pctx)
|
|
|
|
&& pctx->op.kex.exchprovctx == NULL)
|
|
|
|
|| (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)
|
|
|
|
&& pctx->op.sig.sigprovctx == NULL)))
|
2015-01-22 11:40:55 +08:00
|
|
|
return NULL;
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_ENGINE
|
2015-01-22 11:40:55 +08:00
|
|
|
/* Make sure it's safe to copy a pkey context using an ENGINE */
|
|
|
|
if (pctx->engine && !ENGINE_init(pctx->engine)) {
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB);
|
|
|
|
return 0;
|
|
|
|
}
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2019-06-27 17:48:17 +08:00
|
|
|
rctx = OPENSSL_zalloc(sizeof(*rctx));
|
2018-03-30 02:59:58 +08:00
|
|
|
if (rctx == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_MALLOC_FAILURE);
|
2015-01-22 11:40:55 +08:00
|
|
|
return NULL;
|
2018-03-30 02:59:58 +08:00
|
|
|
}
|
2006-05-25 07:49:30 +08:00
|
|
|
|
2019-06-27 17:48:17 +08:00
|
|
|
if (pctx->pkey != NULL)
|
|
|
|
EVP_PKEY_up_ref(pctx->pkey);
|
|
|
|
rctx->pkey = pctx->pkey;
|
|
|
|
rctx->operation = pctx->operation;
|
2019-11-01 23:56:31 +08:00
|
|
|
rctx->libctx = pctx->libctx;
|
2019-12-18 20:24:27 +08:00
|
|
|
rctx->keytype = pctx->keytype;
|
2019-10-15 19:08:17 +08:00
|
|
|
rctx->propquery = pctx->propquery;
|
2019-06-27 17:48:17 +08:00
|
|
|
|
2019-09-05 06:13:25 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) {
|
|
|
|
if (pctx->op.kex.exchange != NULL) {
|
|
|
|
rctx->op.kex.exchange = pctx->op.kex.exchange;
|
|
|
|
if (!EVP_KEYEXCH_up_ref(rctx->op.kex.exchange)) {
|
|
|
|
OPENSSL_free(rctx);
|
|
|
|
return NULL;
|
|
|
|
}
|
2019-06-27 17:48:17 +08:00
|
|
|
}
|
2019-09-05 06:13:25 +08:00
|
|
|
if (pctx->op.kex.exchprovctx != NULL) {
|
|
|
|
if (!ossl_assert(pctx->op.kex.exchange != NULL))
|
|
|
|
return NULL;
|
|
|
|
rctx->op.kex.exchprovctx
|
|
|
|
= pctx->op.kex.exchange->dupctx(pctx->op.kex.exchprovctx);
|
|
|
|
if (rctx->op.kex.exchprovctx == NULL) {
|
|
|
|
EVP_KEYEXCH_free(rctx->op.kex.exchange);
|
|
|
|
OPENSSL_free(rctx);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return rctx;
|
|
|
|
}
|
|
|
|
} else if (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)) {
|
|
|
|
if (pctx->op.sig.signature != NULL) {
|
|
|
|
rctx->op.sig.signature = pctx->op.sig.signature;
|
|
|
|
if (!EVP_SIGNATURE_up_ref(rctx->op.sig.signature)) {
|
|
|
|
OPENSSL_free(rctx);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pctx->op.sig.sigprovctx != NULL) {
|
|
|
|
if (!ossl_assert(pctx->op.sig.signature != NULL))
|
|
|
|
return NULL;
|
|
|
|
rctx->op.sig.sigprovctx
|
|
|
|
= pctx->op.sig.signature->dupctx(pctx->op.sig.sigprovctx);
|
|
|
|
if (rctx->op.sig.sigprovctx == NULL) {
|
|
|
|
EVP_SIGNATURE_free(rctx->op.sig.signature);
|
|
|
|
OPENSSL_free(rctx);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return rctx;
|
2019-06-27 17:48:17 +08:00
|
|
|
}
|
2019-10-01 16:40:57 +08:00
|
|
|
} else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(pctx)) {
|
|
|
|
if (pctx->op.ciph.cipher != NULL) {
|
|
|
|
rctx->op.ciph.cipher = pctx->op.ciph.cipher;
|
|
|
|
if (!EVP_ASYM_CIPHER_up_ref(rctx->op.ciph.cipher)) {
|
|
|
|
OPENSSL_free(rctx);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pctx->op.ciph.ciphprovctx != NULL) {
|
|
|
|
if (!ossl_assert(pctx->op.ciph.cipher != NULL))
|
|
|
|
return NULL;
|
|
|
|
rctx->op.ciph.ciphprovctx
|
|
|
|
= pctx->op.ciph.cipher->dupctx(pctx->op.ciph.ciphprovctx);
|
|
|
|
if (rctx->op.ciph.ciphprovctx == NULL) {
|
|
|
|
EVP_ASYM_CIPHER_free(rctx->op.ciph.cipher);
|
|
|
|
OPENSSL_free(rctx);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return rctx;
|
|
|
|
}
|
2019-06-27 17:48:17 +08:00
|
|
|
}
|
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
rctx->pmeth = pctx->pmeth;
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_ENGINE
|
2015-01-22 11:40:55 +08:00
|
|
|
rctx->engine = pctx->engine;
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2006-05-25 07:49:30 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
if (pctx->peerkey)
|
2016-02-26 20:21:15 +08:00
|
|
|
EVP_PKEY_up_ref(pctx->peerkey);
|
2015-01-22 11:40:55 +08:00
|
|
|
rctx->peerkey = pctx->peerkey;
|
2006-05-25 07:49:30 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
if (pctx->pmeth->copy(rctx, pctx) > 0)
|
|
|
|
return rctx;
|
2006-05-25 07:49:30 +08:00
|
|
|
|
2017-02-02 01:29:47 +08:00
|
|
|
rctx->pmeth = NULL;
|
2015-01-22 11:40:55 +08:00
|
|
|
EVP_PKEY_CTX_free(rctx);
|
|
|
|
return NULL;
|
2006-05-25 07:49:30 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2006-05-25 07:49:30 +08:00
|
|
|
|
2006-04-14 20:41:35 +08:00
|
|
|
int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
if (app_pkey_methods == NULL) {
|
|
|
|
app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
|
2018-03-30 02:59:58 +08:00
|
|
|
if (app_pkey_methods == NULL){
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_METH_ADD0, ERR_R_MALLOC_FAILURE);
|
2015-01-22 11:40:55 +08:00
|
|
|
return 0;
|
2018-03-30 02:59:58 +08:00
|
|
|
}
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2018-03-30 02:59:58 +08:00
|
|
|
if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth)) {
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_METH_ADD0, ERR_R_MALLOC_FAILURE);
|
2015-01-22 11:40:55 +08:00
|
|
|
return 0;
|
2018-03-30 02:59:58 +08:00
|
|
|
}
|
2015-01-22 11:40:55 +08:00
|
|
|
sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
|
|
|
|
return 1;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
2017-09-11 23:15:55 +08:00
|
|
|
void evp_app_cleanup_int(void)
|
|
|
|
{
|
|
|
|
if (app_pkey_methods != NULL)
|
|
|
|
sk_EVP_PKEY_METHOD_pop_free(app_pkey_methods, EVP_PKEY_meth_free);
|
|
|
|
}
|
|
|
|
|
|
|
|
int EVP_PKEY_meth_remove(const EVP_PKEY_METHOD *pmeth)
|
|
|
|
{
|
|
|
|
const EVP_PKEY_METHOD *ret;
|
|
|
|
|
|
|
|
ret = sk_EVP_PKEY_METHOD_delete_ptr(app_pkey_methods, pmeth);
|
|
|
|
|
|
|
|
return ret == NULL ? 0 : 1;
|
|
|
|
}
|
|
|
|
|
2017-07-26 00:48:26 +08:00
|
|
|
size_t EVP_PKEY_meth_get_count(void)
|
|
|
|
{
|
|
|
|
size_t rv = OSSL_NELEM(standard_methods);
|
|
|
|
|
|
|
|
if (app_pkey_methods)
|
|
|
|
rv += sk_EVP_PKEY_METHOD_num(app_pkey_methods);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx)
|
|
|
|
{
|
|
|
|
if (idx < OSSL_NELEM(standard_methods))
|
2019-09-19 21:31:27 +08:00
|
|
|
return (standard_methods[idx])();
|
2017-07-26 00:48:26 +08:00
|
|
|
if (app_pkey_methods == NULL)
|
|
|
|
return NULL;
|
|
|
|
idx -= OSSL_NELEM(standard_methods);
|
|
|
|
if (idx >= (size_t)sk_EVP_PKEY_METHOD_num(app_pkey_methods))
|
|
|
|
return NULL;
|
|
|
|
return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
|
|
|
|
}
|
2020-01-12 09:32:12 +08:00
|
|
|
#endif
|
2017-07-26 00:48:26 +08:00
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2020-01-12 09:32:12 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
|
|
|
|
&& ctx->op.kex.exchprovctx != NULL
|
|
|
|
&& ctx->op.kex.exchange != NULL
|
|
|
|
&& ctx->op.kex.exchange->set_ctx_params != NULL)
|
|
|
|
return ctx->op.kex.exchange->set_ctx_params(ctx->op.kex.exchprovctx,
|
|
|
|
params);
|
|
|
|
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
|
|
|
&& ctx->op.sig.sigprovctx != NULL
|
|
|
|
&& ctx->op.sig.signature != NULL
|
|
|
|
&& ctx->op.sig.signature->set_ctx_params != NULL)
|
|
|
|
return ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx,
|
|
|
|
params);
|
|
|
|
if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
|
|
|
&& ctx->op.ciph.ciphprovctx != NULL
|
|
|
|
&& ctx->op.ciph.cipher != NULL
|
|
|
|
&& ctx->op.ciph.cipher->set_ctx_params != NULL)
|
|
|
|
return ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.ciphprovctx,
|
|
|
|
params);
|
2019-10-27 22:09:26 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_GEN_OP(ctx)
|
|
|
|
&& ctx->op.keymgmt.genctx != NULL
|
|
|
|
&& ctx->keymgmt != NULL
|
|
|
|
&& ctx->keymgmt->gen_set_params != NULL)
|
|
|
|
return evp_keymgmt_gen_set_params(ctx->keymgmt, ctx->op.keymgmt.genctx,
|
|
|
|
params);
|
2020-01-12 09:32:12 +08:00
|
|
|
return 0;
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2006-04-07 01:32:43 +08:00
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
#ifndef FIPS_MODE
|
2019-09-04 19:46:02 +08:00
|
|
|
int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
|
|
|
{
|
2019-12-15 06:20:53 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
|
|
|
|
&& ctx->op.kex.exchprovctx != NULL
|
|
|
|
&& ctx->op.kex.exchange != NULL
|
|
|
|
&& ctx->op.kex.exchange->get_ctx_params != NULL)
|
|
|
|
return ctx->op.kex.exchange->get_ctx_params(ctx->op.kex.exchprovctx,
|
|
|
|
params);
|
2019-09-05 06:13:25 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
|
|
|
&& ctx->op.sig.sigprovctx != NULL
|
|
|
|
&& ctx->op.sig.signature != NULL
|
|
|
|
&& ctx->op.sig.signature->get_ctx_params != NULL)
|
|
|
|
return ctx->op.sig.signature->get_ctx_params(ctx->op.sig.sigprovctx,
|
|
|
|
params);
|
2019-10-01 16:40:57 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
|
|
|
&& ctx->op.ciph.ciphprovctx != NULL
|
|
|
|
&& ctx->op.ciph.cipher != NULL
|
|
|
|
&& ctx->op.ciph.cipher->get_ctx_params != NULL)
|
|
|
|
return ctx->op.ciph.cipher->get_ctx_params(ctx->op.ciph.ciphprovctx,
|
|
|
|
params);
|
2019-09-04 19:46:02 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx)
|
|
|
|
{
|
2019-12-15 06:20:53 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
|
|
|
|
&& ctx->op.kex.exchange != NULL
|
|
|
|
&& ctx->op.kex.exchange->gettable_ctx_params != NULL)
|
|
|
|
return ctx->op.kex.exchange->gettable_ctx_params();
|
2019-09-05 06:13:25 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
|
|
|
&& ctx->op.sig.signature != NULL
|
|
|
|
&& ctx->op.sig.signature->gettable_ctx_params != NULL)
|
|
|
|
return ctx->op.sig.signature->gettable_ctx_params();
|
2019-09-04 19:46:02 +08:00
|
|
|
|
2019-10-01 16:40:57 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
|
|
|
&& ctx->op.ciph.cipher != NULL
|
|
|
|
&& ctx->op.ciph.cipher->gettable_ctx_params != NULL)
|
|
|
|
return ctx->op.ciph.cipher->gettable_ctx_params();
|
|
|
|
|
2019-09-04 19:46:02 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx)
|
|
|
|
{
|
2019-09-05 06:13:25 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
|
|
|
|
&& ctx->op.kex.exchange != NULL
|
|
|
|
&& ctx->op.kex.exchange->settable_ctx_params != NULL)
|
|
|
|
return ctx->op.kex.exchange->settable_ctx_params();
|
|
|
|
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
|
|
|
&& ctx->op.sig.signature != NULL
|
|
|
|
&& ctx->op.sig.signature->settable_ctx_params != NULL)
|
|
|
|
return ctx->op.sig.signature->settable_ctx_params();
|
2019-10-01 16:40:57 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
|
|
|
&& ctx->op.ciph.cipher != NULL
|
|
|
|
&& ctx->op.ciph.cipher->settable_ctx_params != NULL)
|
|
|
|
return ctx->op.ciph.cipher->settable_ctx_params();
|
2019-10-27 22:09:26 +08:00
|
|
|
if (EVP_PKEY_CTX_IS_GEN_OP(ctx)
|
|
|
|
&& ctx->keymgmt != NULL
|
|
|
|
&& ctx->keymgmt->gen_settable_params != NULL)
|
|
|
|
return evp_keymgmt_gen_settable_params(ctx->keymgmt);
|
2019-09-04 19:46:02 +08:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-12-15 06:20:53 +08:00
|
|
|
/*
|
|
|
|
* Internal helpers for stricter EVP_PKEY_CTX_{set,get}_params().
|
|
|
|
*
|
|
|
|
* Return 1 on success, 0 or negative for errors.
|
|
|
|
*
|
|
|
|
* In particular they return -2 if any of the params is not supported.
|
|
|
|
*
|
|
|
|
* They are not available in FIPS_MODE as they depend on
|
|
|
|
* - EVP_PKEY_CTX_{get,set}_params()
|
|
|
|
* - EVP_PKEY_CTX_{gettable,settable}_params()
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int evp_pkey_ctx_set_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
|
|
|
{
|
|
|
|
const OSSL_PARAM *p;
|
|
|
|
|
|
|
|
if (ctx == NULL || params == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
for (p = params; p->key != NULL; p++) {
|
|
|
|
/* Check the ctx actually understands this parameter */
|
|
|
|
if (OSSL_PARAM_locate_const(EVP_PKEY_CTX_settable_params(ctx),
|
|
|
|
p->key) == NULL )
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EVP_PKEY_CTX_set_params(ctx, params);
|
|
|
|
}
|
|
|
|
|
|
|
|
int evp_pkey_ctx_get_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
|
|
|
{
|
|
|
|
const OSSL_PARAM *p;
|
|
|
|
|
|
|
|
if (ctx == NULL || params == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
for (p = params; p->key != NULL; p++ ) {
|
|
|
|
/* Check the ctx actually understands this parameter */
|
|
|
|
if (OSSL_PARAM_locate_const(EVP_PKEY_CTX_gettable_params(ctx),
|
|
|
|
p->key) == NULL )
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EVP_PKEY_CTX_get_params(ctx, params);
|
|
|
|
}
|
|
|
|
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_DH
|
2019-06-27 23:37:44 +08:00
|
|
|
int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
|
|
|
|
{
|
|
|
|
OSSL_PARAM dh_pad_params[2];
|
2019-09-05 09:23:57 +08:00
|
|
|
unsigned int upad = pad;
|
2019-06-27 23:37:44 +08:00
|
|
|
|
2019-09-05 06:13:25 +08:00
|
|
|
/* We use EVP_PKEY_CTX_ctrl return values */
|
|
|
|
if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
|
|
|
|
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
2019-06-27 23:37:44 +08:00
|
|
|
/* TODO(3.0): Remove this eventually when no more legacy */
|
2019-09-05 06:13:25 +08:00
|
|
|
if (ctx->op.kex.exchprovctx == NULL)
|
2019-06-27 23:37:44 +08:00
|
|
|
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE,
|
|
|
|
EVP_PKEY_CTRL_DH_PAD, pad, NULL);
|
|
|
|
|
2019-09-05 09:23:57 +08:00
|
|
|
dh_pad_params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &upad);
|
2019-06-27 23:37:44 +08:00
|
|
|
dh_pad_params[1] = OSSL_PARAM_construct_end();
|
|
|
|
|
|
|
|
return EVP_PKEY_CTX_set_params(ctx, dh_pad_params);
|
|
|
|
}
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2019-06-27 23:37:44 +08:00
|
|
|
|
2019-09-04 19:46:02 +08:00
|
|
|
int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
|
|
|
|
{
|
|
|
|
OSSL_PARAM sig_md_params[3], *p = sig_md_params;
|
|
|
|
/* 80 should be big enough */
|
|
|
|
char name[80] = "";
|
|
|
|
const EVP_MD *tmp;
|
|
|
|
|
2019-09-05 06:13:25 +08:00
|
|
|
if (ctx == NULL || !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) {
|
2019-09-04 19:46:02 +08:00
|
|
|
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
|
|
|
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO(3.0): Remove this eventually when no more legacy */
|
2019-09-05 06:13:25 +08:00
|
|
|
if (ctx->op.sig.sigprovctx == NULL)
|
2019-09-04 19:46:02 +08:00
|
|
|
return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,
|
|
|
|
EVP_PKEY_CTRL_GET_MD, 0, (void *)(md));
|
|
|
|
|
|
|
|
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
|
|
|
|
name,
|
|
|
|
sizeof(name));
|
|
|
|
*p++ = OSSL_PARAM_construct_end();
|
|
|
|
|
|
|
|
if (!EVP_PKEY_CTX_get_params(ctx, sig_md_params))
|
|
|
|
return 0;
|
|
|
|
|
2019-11-01 22:13:49 +08:00
|
|
|
tmp = evp_get_digestbyname_ex(ctx->libctx, name);
|
2019-09-04 19:46:02 +08:00
|
|
|
if (tmp == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
*md = tmp;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2019-08-30 20:33:37 +08:00
|
|
|
int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
|
|
|
|
{
|
2020-02-02 19:55:05 +08:00
|
|
|
OSSL_PARAM sig_md_params[2], *p = sig_md_params;
|
2019-08-30 20:33:37 +08:00
|
|
|
const char *name;
|
|
|
|
|
2019-09-05 06:13:25 +08:00
|
|
|
if (ctx == NULL || !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) {
|
2019-09-04 19:46:02 +08:00
|
|
|
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
|
|
|
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
2019-08-30 20:33:37 +08:00
|
|
|
/* TODO(3.0): Remove this eventually when no more legacy */
|
2019-09-05 06:13:25 +08:00
|
|
|
if (ctx->op.sig.sigprovctx == NULL)
|
2019-08-30 20:33:37 +08:00
|
|
|
return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,
|
|
|
|
EVP_PKEY_CTRL_MD, 0, (void *)(md));
|
|
|
|
|
2019-09-04 19:46:02 +08:00
|
|
|
if (md == NULL) {
|
|
|
|
name = "";
|
|
|
|
} else {
|
|
|
|
name = EVP_MD_name(md);
|
|
|
|
}
|
2019-08-30 20:33:37 +08:00
|
|
|
|
2019-09-04 19:46:02 +08:00
|
|
|
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
|
|
|
|
/*
|
|
|
|
* Cast away the const. This is read
|
|
|
|
* only so should be safe
|
|
|
|
*/
|
2020-02-05 13:13:49 +08:00
|
|
|
(char *)name, 0);
|
2019-09-04 19:46:02 +08:00
|
|
|
*p++ = OSSL_PARAM_construct_end();
|
2019-08-30 20:33:37 +08:00
|
|
|
|
2019-09-04 19:46:02 +08:00
|
|
|
return EVP_PKEY_CTX_set_params(ctx, sig_md_params);
|
2019-08-30 20:33:37 +08:00
|
|
|
}
|
|
|
|
|
2019-06-27 23:37:44 +08:00
|
|
|
static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
|
|
|
int cmd, int p1, void *p2)
|
|
|
|
{
|
2020-01-20 23:17:44 +08:00
|
|
|
/*
|
|
|
|
* GOST CMS format is different for different cipher algorithms.
|
|
|
|
* Most of other algorithms don't have such a difference
|
|
|
|
* so this ctrl is just ignored.
|
|
|
|
*/
|
|
|
|
if (cmd == EVP_PKEY_CTRL_CIPHER)
|
|
|
|
return -2;
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_DH
|
2019-12-15 06:20:53 +08:00
|
|
|
if (keytype == EVP_PKEY_DH) {
|
|
|
|
switch (cmd) {
|
|
|
|
case EVP_PKEY_CTRL_DH_PAD:
|
|
|
|
return EVP_PKEY_CTX_set_dh_pad(ctx, p1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
# ifndef OPENSSL_NO_EC
|
|
|
|
if (keytype == EVP_PKEY_EC) {
|
|
|
|
switch (cmd) {
|
2019-12-01 22:01:50 +08:00
|
|
|
case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
|
|
|
|
if (p1 == -2) {
|
|
|
|
return EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx);
|
|
|
|
} else if (p1 < -1 || p1 > 1) {
|
|
|
|
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
|
|
|
return -2;
|
|
|
|
} else {
|
|
|
|
return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, p1);
|
|
|
|
}
|
|
|
|
case EVP_PKEY_CTRL_EC_KDF_TYPE:
|
|
|
|
if (p1 == -2) {
|
|
|
|
return EVP_PKEY_CTX_get_ecdh_kdf_type(ctx);
|
|
|
|
} else {
|
|
|
|
return EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, p1);
|
|
|
|
}
|
|
|
|
case EVP_PKEY_CTRL_GET_EC_KDF_MD:
|
|
|
|
return EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_EC_KDF_MD:
|
|
|
|
return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
|
|
|
|
return EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
|
|
|
|
return EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, p1);
|
|
|
|
case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
|
|
|
|
return EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_EC_KDF_UKM:
|
|
|
|
return EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p2, p1);
|
2019-12-15 06:20:53 +08:00
|
|
|
}
|
|
|
|
}
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2020-03-14 12:16:16 +08:00
|
|
|
if (keytype == EVP_PKEY_RSA) {
|
|
|
|
switch (cmd) {
|
|
|
|
case EVP_PKEY_CTRL_RSA_OAEP_MD:
|
|
|
|
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
|
|
|
|
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_RSA_MGF1_MD:
|
|
|
|
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
|
|
|
|
return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1);
|
|
|
|
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
|
|
|
|
return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2);
|
|
|
|
case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
|
|
|
|
return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, p1);
|
|
|
|
case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
|
|
|
|
return EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES:
|
|
|
|
return EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, p1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* keytype == -1 is used when several key types share the same structure,
|
|
|
|
* or for generic controls that are the same across multiple key types.
|
|
|
|
*/
|
2019-12-15 06:20:53 +08:00
|
|
|
if (keytype == -1) {
|
|
|
|
switch (cmd) {
|
2019-12-01 22:01:50 +08:00
|
|
|
case EVP_PKEY_CTRL_MD:
|
|
|
|
return EVP_PKEY_CTX_set_signature_md(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_GET_MD:
|
|
|
|
return EVP_PKEY_CTX_get_signature_md(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_RSA_PADDING:
|
|
|
|
return EVP_PKEY_CTX_set_rsa_padding(ctx, p1);
|
|
|
|
case EVP_PKEY_CTRL_GET_RSA_PADDING:
|
|
|
|
return EVP_PKEY_CTX_get_rsa_padding(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
|
|
|
|
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
|
|
|
|
return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, p1);
|
|
|
|
case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
|
|
|
|
return EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, p2);
|
|
|
|
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
|
|
|
|
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_CMS
|
2019-12-01 22:01:50 +08:00
|
|
|
case EVP_PKEY_CTRL_CMS_DECRYPT:
|
|
|
|
case EVP_PKEY_CTRL_CMS_ENCRYPT:
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2019-12-01 22:01:50 +08:00
|
|
|
if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
|
|
|
|
return 1;
|
|
|
|
ERR_raise(ERR_LIB_EVP,
|
|
|
|
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
|
|
|
return -2;
|
2019-12-15 06:20:53 +08:00
|
|
|
}
|
2019-06-27 23:37:44 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-04-06 21:02:06 +08:00
|
|
|
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
2015-01-22 11:40:55 +08:00
|
|
|
int cmd, int p1, void *p2)
|
|
|
|
{
|
|
|
|
int ret;
|
2018-09-04 17:21:10 +08:00
|
|
|
|
2019-06-27 23:37:44 +08:00
|
|
|
if (ctx == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
2019-09-05 06:13:25 +08:00
|
|
|
if ((EVP_PKEY_CTX_IS_DERIVE_OP(ctx) && ctx->op.kex.exchprovctx != NULL)
|
2019-10-21 02:49:32 +08:00
|
|
|
|| (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
2019-10-01 16:40:57 +08:00
|
|
|
&& ctx->op.sig.sigprovctx != NULL)
|
|
|
|
|| (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
2019-10-27 22:09:26 +08:00
|
|
|
&& ctx->op.ciph.ciphprovctx != NULL)
|
|
|
|
|| (EVP_PKEY_CTX_IS_GEN_OP(ctx)
|
|
|
|
&& ctx->op.keymgmt.genctx != NULL))
|
2019-06-27 23:37:44 +08:00
|
|
|
return legacy_ctrl_to_param(ctx, keytype, optype, cmd, p1, p2);
|
|
|
|
|
|
|
|
if (ctx->pmeth == NULL || ctx->pmeth->ctrl == NULL) {
|
2015-01-22 11:40:55 +08:00
|
|
|
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
|
|
|
|
return -1;
|
|
|
|
|
2018-09-04 17:21:10 +08:00
|
|
|
/* Skip the operation checks since this is called in a very early stage */
|
|
|
|
if (ctx->pmeth->digest_custom != NULL)
|
|
|
|
goto doit;
|
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((optype != -1) && !(ctx->operation & optype)) {
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-09-04 17:21:10 +08:00
|
|
|
doit:
|
2015-01-22 11:40:55 +08:00
|
|
|
ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
|
|
|
|
|
|
|
|
if (ret == -2)
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2006-04-06 21:02:06 +08:00
|
|
|
|
2017-07-23 02:04:55 +08:00
|
|
|
int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
2017-08-16 00:52:24 +08:00
|
|
|
int cmd, uint64_t value)
|
2017-07-23 02:04:55 +08:00
|
|
|
{
|
|
|
|
return EVP_PKEY_CTX_ctrl(ctx, keytype, optype, cmd, 0, &value);
|
|
|
|
}
|
|
|
|
|
2019-06-27 23:37:44 +08:00
|
|
|
static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
|
|
|
const char *value)
|
|
|
|
{
|
2020-01-25 19:27:47 +08:00
|
|
|
if (strcmp(name, "rsa_padding_mode") == 0)
|
|
|
|
name = OSSL_ASYM_CIPHER_PARAM_PAD_MODE;
|
|
|
|
else if (strcmp(name, "rsa_mgf1_md") == 0)
|
|
|
|
name = OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST;
|
|
|
|
else if (strcmp(name, "rsa_oaep_md") == 0)
|
|
|
|
name = OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST;
|
|
|
|
else if (strcmp(name, "rsa_oaep_label") == 0)
|
|
|
|
name = OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL;
|
2019-12-01 22:01:50 +08:00
|
|
|
else if (strcmp(name, "rsa_pss_saltlen") == 0)
|
|
|
|
name = OSSL_SIGNATURE_PARAM_PSS_SALTLEN;
|
2019-10-27 22:28:29 +08:00
|
|
|
else if (strcmp(name, "rsa_keygen_bits") == 0)
|
|
|
|
name = OSSL_PKEY_PARAM_RSA_BITS;
|
|
|
|
else if (strcmp(name, "rsa_keygen_pubexp") == 0)
|
|
|
|
name = OSSL_PKEY_PARAM_RSA_E;
|
|
|
|
else if (strcmp(name, "rsa_keygen_primes") == 0)
|
|
|
|
name = OSSL_PKEY_PARAM_RSA_PRIMES;
|
2020-01-12 09:32:12 +08:00
|
|
|
# ifndef OPENSSL_NO_DH
|
2020-01-25 19:27:47 +08:00
|
|
|
else if (strcmp(name, "dh_pad") == 0)
|
|
|
|
name = OSSL_EXCHANGE_PARAM_PAD;
|
2020-01-12 09:32:12 +08:00
|
|
|
# endif
|
2019-12-15 06:20:53 +08:00
|
|
|
# ifndef OPENSSL_NO_EC
|
|
|
|
else if (strcmp(name, "ecdh_cofactor_mode") == 0)
|
|
|
|
name = OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE;
|
|
|
|
else if (strcmp(name, "ecdh_kdf_md") == 0)
|
2020-02-16 17:54:08 +08:00
|
|
|
name = OSSL_EXCHANGE_PARAM_KDF_DIGEST;
|
2019-12-15 06:20:53 +08:00
|
|
|
# endif
|
2019-10-28 21:40:39 +08:00
|
|
|
|
2020-01-25 19:27:47 +08:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* TODO(3.0) reduce the code above to only translate known legacy
|
|
|
|
* string to the corresponding core name (see core_names.h), but
|
|
|
|
* otherwise leave it to this code block to do the actual work.
|
|
|
|
*/
|
|
|
|
const OSSL_PARAM *settable = EVP_PKEY_CTX_settable_params(ctx);
|
|
|
|
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
|
|
|
int rv = 0;
|
2020-02-10 11:32:36 +08:00
|
|
|
int exists = 0;
|
2019-10-28 21:40:39 +08:00
|
|
|
|
2020-01-25 19:27:47 +08:00
|
|
|
if (!OSSL_PARAM_allocate_from_text(¶ms[0], settable, name, value,
|
2020-02-10 11:32:36 +08:00
|
|
|
strlen(value), &exists)) {
|
|
|
|
if (!exists) {
|
|
|
|
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
|
|
|
return -2;
|
|
|
|
}
|
2019-10-28 21:40:39 +08:00
|
|
|
return 0;
|
2020-02-10 11:32:36 +08:00
|
|
|
}
|
2020-01-25 19:27:47 +08:00
|
|
|
if (EVP_PKEY_CTX_set_params(ctx, params))
|
|
|
|
rv = 1;
|
|
|
|
OPENSSL_free(params[0].data);
|
|
|
|
return rv;
|
2019-10-28 21:40:39 +08:00
|
|
|
}
|
2019-06-27 23:37:44 +08:00
|
|
|
}
|
|
|
|
|
2006-04-09 20:42:09 +08:00
|
|
|
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
|
2015-01-22 11:40:55 +08:00
|
|
|
const char *name, const char *value)
|
|
|
|
{
|
2019-06-27 23:37:44 +08:00
|
|
|
if (ctx == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
2019-09-05 06:13:25 +08:00
|
|
|
if ((EVP_PKEY_CTX_IS_DERIVE_OP(ctx) && ctx->op.kex.exchprovctx != NULL)
|
|
|
|
|| (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
2019-10-01 16:40:57 +08:00
|
|
|
&& ctx->op.sig.sigprovctx != NULL)
|
|
|
|
|| (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
2019-10-27 22:09:26 +08:00
|
|
|
&& ctx->op.ciph.ciphprovctx != NULL)
|
|
|
|
|| (EVP_PKEY_CTX_IS_GEN_OP(ctx)
|
|
|
|
&& ctx->op.keymgmt.genctx != NULL))
|
2019-06-27 23:37:44 +08:00
|
|
|
return legacy_ctrl_str_to_param(ctx, name, value);
|
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
|
|
|
return -2;
|
|
|
|
}
|
2016-12-01 00:21:01 +08:00
|
|
|
if (strcmp(name, "digest") == 0)
|
|
|
|
return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD,
|
|
|
|
value);
|
2015-01-22 11:40:55 +08:00
|
|
|
return ctx->pmeth->ctrl_str(ctx, name, value);
|
|
|
|
}
|
2006-04-11 21:28:52 +08:00
|
|
|
|
2016-03-01 22:47:15 +08:00
|
|
|
/* Utility functions to send a string of hex string to a ctrl */
|
|
|
|
|
|
|
|
int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
len = strlen(str);
|
|
|
|
if (len > INT_MAX)
|
|
|
|
return -1;
|
|
|
|
return ctx->pmeth->ctrl(ctx, cmd, len, (void *)str);
|
|
|
|
}
|
|
|
|
|
|
|
|
int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex)
|
|
|
|
{
|
|
|
|
unsigned char *bin;
|
|
|
|
long binlen;
|
|
|
|
int rv = -1;
|
|
|
|
|
2016-04-14 03:58:28 +08:00
|
|
|
bin = OPENSSL_hexstr2buf(hex, &binlen);
|
2016-03-01 22:47:15 +08:00
|
|
|
if (bin == NULL)
|
|
|
|
return 0;
|
|
|
|
if (binlen <= INT_MAX)
|
|
|
|
rv = ctx->pmeth->ctrl(ctx, cmd, binlen, bin);
|
|
|
|
OPENSSL_free(bin);
|
|
|
|
return rv;
|
|
|
|
}
|
2017-01-06 07:18:28 +08:00
|
|
|
|
2016-12-01 00:21:01 +08:00
|
|
|
/* Pass a message digest to a ctrl */
|
|
|
|
int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md)
|
|
|
|
{
|
|
|
|
const EVP_MD *m;
|
2017-01-08 01:17:30 +08:00
|
|
|
|
2016-12-01 00:21:01 +08:00
|
|
|
if (md == NULL || (m = EVP_get_digestbyname(md)) == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_PKEY_CTX_MD, EVP_R_INVALID_DIGEST);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, 0, (void *)m);
|
|
|
|
}
|
2016-03-01 22:47:15 +08:00
|
|
|
|
2006-06-01 01:34:14 +08:00
|
|
|
int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
return ctx->operation;
|
|
|
|
}
|
2006-06-01 01:34:14 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
ctx->keygen_info = dat;
|
|
|
|
ctx->keygen_info_count = datlen;
|
|
|
|
}
|
2006-06-01 01:34:14 +08:00
|
|
|
|
2006-04-11 21:28:52 +08:00
|
|
|
void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
ctx->data = data;
|
|
|
|
}
|
2006-04-11 21:28:52 +08:00
|
|
|
|
2019-01-16 04:51:25 +08:00
|
|
|
void *EVP_PKEY_CTX_get_data(const EVP_PKEY_CTX *ctx)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
return ctx->data;
|
|
|
|
}
|
2006-04-11 21:28:52 +08:00
|
|
|
|
2006-04-26 19:52:36 +08:00
|
|
|
EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
return ctx->pkey;
|
|
|
|
}
|
2006-04-26 19:52:36 +08:00
|
|
|
|
1. Changes for s_client.c to make it return non-zero exit code in case
of handshake failure
2. Changes to x509_certificate_type function (crypto/x509/x509type.c) to
make it recognize GOST certificates as EVP_PKT_SIGN|EVP_PKT_EXCH
(required for s3_srvr to accept GOST client certificates).
3. Changes to EVP
- adding of function EVP_PKEY_CTX_get0_peerkey
- Make function EVP_PKEY_derive_set_peerkey work for context with
ENCRYPT operation, because we use peerkey field in the context to
pass non-ephemeral secret key to GOST encrypt operation.
- added EVP_PKEY_CTRL_SET_IV control command. It is really
GOST-specific, but it is used in SSL code, so it has to go
in some header file, available during libssl compilation
4. Fix to HMAC to avoid call of OPENSSL_cleanse on undefined data
5. Include des.h if KSSL_DEBUG is defined into some libssl files, to
make debugging output which depends on constants defined there, work
and other KSSL_DEBUG output fixes
6. Declaration of real GOST ciphersuites, two authentication methods
SSL_aGOST94 and SSL_aGOST2001 and one key exchange method SSL_kGOST
7. Implementation of these methods.
8. Support for sending unsolicited serverhello extension if GOST
ciphersuite is selected. It is require for interoperability with
CryptoPro CSP 3.0 and 3.6 and controlled by
SSL_OP_CRYPTOPRO_TLSEXT_BUG constant.
This constant is added to SSL_OP_ALL, because it does nothing, if
non-GOST ciphersuite is selected, and all implementation of GOST
include compatibility with CryptoPro.
9. Support for CertificateVerify message without length field. It is
another CryptoPro bug, but support is made unconditional, because it
does no harm for draft-conforming implementation.
10. In tls1_mac extra copy of stream mac context is no more done.
When I've written currently commited code I haven't read
EVP_DigestSignFinal manual carefully enough and haven't noticed that
it does an internal digest ctx copying.
This implementation was tested against
1. CryptoPro CSP 3.6 client and server
2. Cryptopro CSP 3.0 server
2007-10-26 20:06:36 +08:00
|
|
|
EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
return ctx->peerkey;
|
|
|
|
}
|
|
|
|
|
2006-04-11 21:28:52 +08:00
|
|
|
void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
ctx->app_data = data;
|
|
|
|
}
|
2006-04-11 21:28:52 +08:00
|
|
|
|
|
|
|
void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
return ctx->app_data;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*init) (EVP_PKEY_CTX *ctx))
|
|
|
|
{
|
|
|
|
pmeth->init = init;
|
|
|
|
}
|
2006-05-25 07:49:30 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*copy) (EVP_PKEY_CTX *dst,
|
2019-01-16 04:51:25 +08:00
|
|
|
const EVP_PKEY_CTX *src))
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
pmeth->copy = copy;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
void (*cleanup) (EVP_PKEY_CTX *ctx))
|
|
|
|
{
|
|
|
|
pmeth->cleanup = cleanup;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*paramgen_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (*paramgen) (EVP_PKEY_CTX *ctx,
|
|
|
|
EVP_PKEY *pkey))
|
|
|
|
{
|
|
|
|
pmeth->paramgen_init = paramgen_init;
|
|
|
|
pmeth->paramgen = paramgen;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*keygen_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (*keygen) (EVP_PKEY_CTX *ctx,
|
|
|
|
EVP_PKEY *pkey))
|
|
|
|
{
|
|
|
|
pmeth->keygen_init = keygen_init;
|
|
|
|
pmeth->keygen = keygen;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*sign_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (*sign) (EVP_PKEY_CTX *ctx,
|
|
|
|
unsigned char *sig, size_t *siglen,
|
|
|
|
const unsigned char *tbs,
|
|
|
|
size_t tbslen))
|
|
|
|
{
|
|
|
|
pmeth->sign_init = sign_init;
|
|
|
|
pmeth->sign = sign;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*verify_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (*verify) (EVP_PKEY_CTX *ctx,
|
|
|
|
const unsigned char *sig,
|
|
|
|
size_t siglen,
|
|
|
|
const unsigned char *tbs,
|
|
|
|
size_t tbslen))
|
|
|
|
{
|
|
|
|
pmeth->verify_init = verify_init;
|
|
|
|
pmeth->verify = verify;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*verify_recover_init) (EVP_PKEY_CTX
|
|
|
|
*ctx),
|
|
|
|
int (*verify_recover) (EVP_PKEY_CTX
|
|
|
|
*ctx,
|
|
|
|
unsigned char
|
|
|
|
*sig,
|
|
|
|
size_t *siglen,
|
|
|
|
const unsigned
|
|
|
|
char *tbs,
|
|
|
|
size_t tbslen))
|
|
|
|
{
|
|
|
|
pmeth->verify_recover_init = verify_recover_init;
|
|
|
|
pmeth->verify_recover = verify_recover;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*signctx_init) (EVP_PKEY_CTX *ctx,
|
|
|
|
EVP_MD_CTX *mctx),
|
|
|
|
int (*signctx) (EVP_PKEY_CTX *ctx,
|
|
|
|
unsigned char *sig,
|
|
|
|
size_t *siglen,
|
|
|
|
EVP_MD_CTX *mctx))
|
|
|
|
{
|
|
|
|
pmeth->signctx_init = signctx_init;
|
|
|
|
pmeth->signctx = signctx;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
|
|
|
|
EVP_MD_CTX *mctx),
|
|
|
|
int (*verifyctx) (EVP_PKEY_CTX *ctx,
|
|
|
|
const unsigned char *sig,
|
|
|
|
int siglen,
|
|
|
|
EVP_MD_CTX *mctx))
|
|
|
|
{
|
|
|
|
pmeth->verifyctx_init = verifyctx_init;
|
|
|
|
pmeth->verifyctx = verifyctx;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*encrypt_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (*encryptfn) (EVP_PKEY_CTX *ctx,
|
|
|
|
unsigned char *out,
|
|
|
|
size_t *outlen,
|
|
|
|
const unsigned char *in,
|
|
|
|
size_t inlen))
|
|
|
|
{
|
|
|
|
pmeth->encrypt_init = encrypt_init;
|
|
|
|
pmeth->encrypt = encryptfn;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*decrypt_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (*decrypt) (EVP_PKEY_CTX *ctx,
|
|
|
|
unsigned char *out,
|
|
|
|
size_t *outlen,
|
|
|
|
const unsigned char *in,
|
|
|
|
size_t inlen))
|
|
|
|
{
|
|
|
|
pmeth->decrypt_init = decrypt_init;
|
|
|
|
pmeth->decrypt = decrypt;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*derive_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (*derive) (EVP_PKEY_CTX *ctx,
|
|
|
|
unsigned char *key,
|
|
|
|
size_t *keylen))
|
|
|
|
{
|
|
|
|
pmeth->derive_init = derive_init;
|
|
|
|
pmeth->derive = derive;
|
|
|
|
}
|
2006-04-14 20:41:35 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
|
2015-01-22 11:40:55 +08:00
|
|
|
int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
|
|
|
|
void *p2),
|
|
|
|
int (*ctrl_str) (EVP_PKEY_CTX *ctx,
|
|
|
|
const char *type,
|
|
|
|
const char *value))
|
|
|
|
{
|
|
|
|
pmeth->ctrl = ctrl;
|
|
|
|
pmeth->ctrl_str = ctrl_str;
|
|
|
|
}
|
2015-07-21 05:05:10 +08:00
|
|
|
|
2019-11-08 10:47:53 +08:00
|
|
|
void EVP_PKEY_meth_set_digestsign(EVP_PKEY_METHOD *pmeth,
|
|
|
|
int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
|
|
|
|
const unsigned char *tbs, size_t tbslen))
|
|
|
|
{
|
|
|
|
pmeth->digestsign = digestsign;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_digestverify(EVP_PKEY_METHOD *pmeth,
|
|
|
|
int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig,
|
|
|
|
size_t siglen, const unsigned char *tbs,
|
|
|
|
size_t tbslen))
|
|
|
|
{
|
|
|
|
pmeth->digestverify = digestverify;
|
|
|
|
}
|
|
|
|
|
2017-09-04 22:02:59 +08:00
|
|
|
void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth,
|
|
|
|
int (*check) (EVP_PKEY *pkey))
|
|
|
|
{
|
|
|
|
pmeth->check = check;
|
|
|
|
}
|
|
|
|
|
2017-11-01 00:45:24 +08:00
|
|
|
void EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth,
|
|
|
|
int (*check) (EVP_PKEY *pkey))
|
|
|
|
{
|
|
|
|
pmeth->public_check = check;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth,
|
|
|
|
int (*check) (EVP_PKEY *pkey))
|
|
|
|
{
|
|
|
|
pmeth->param_check = check;
|
|
|
|
}
|
|
|
|
|
2018-09-04 00:51:04 +08:00
|
|
|
void EVP_PKEY_meth_set_digest_custom(EVP_PKEY_METHOD *pmeth,
|
|
|
|
int (*digest_custom) (EVP_PKEY_CTX *ctx,
|
|
|
|
EVP_MD_CTX *mctx))
|
|
|
|
{
|
|
|
|
pmeth->digest_custom = digest_custom;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_init(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pinit) (EVP_PKEY_CTX *ctx))
|
|
|
|
{
|
|
|
|
*pinit = pmeth->init;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_copy(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pcopy) (EVP_PKEY_CTX *dst,
|
2019-01-16 04:51:25 +08:00
|
|
|
const EVP_PKEY_CTX *src))
|
2015-07-21 05:05:10 +08:00
|
|
|
{
|
|
|
|
*pcopy = pmeth->copy;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_cleanup(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
void (**pcleanup) (EVP_PKEY_CTX *ctx))
|
|
|
|
{
|
|
|
|
*pcleanup = pmeth->cleanup;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_paramgen(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pparamgen_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (**pparamgen) (EVP_PKEY_CTX *ctx,
|
|
|
|
EVP_PKEY *pkey))
|
|
|
|
{
|
|
|
|
if (pparamgen_init)
|
|
|
|
*pparamgen_init = pmeth->paramgen_init;
|
|
|
|
if (pparamgen)
|
|
|
|
*pparamgen = pmeth->paramgen;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_keygen(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pkeygen_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (**pkeygen) (EVP_PKEY_CTX *ctx,
|
|
|
|
EVP_PKEY *pkey))
|
|
|
|
{
|
|
|
|
if (pkeygen_init)
|
|
|
|
*pkeygen_init = pmeth->keygen_init;
|
|
|
|
if (pkeygen)
|
|
|
|
*pkeygen = pmeth->keygen;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_sign(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**psign_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (**psign) (EVP_PKEY_CTX *ctx,
|
|
|
|
unsigned char *sig, size_t *siglen,
|
|
|
|
const unsigned char *tbs,
|
|
|
|
size_t tbslen))
|
|
|
|
{
|
|
|
|
if (psign_init)
|
|
|
|
*psign_init = pmeth->sign_init;
|
|
|
|
if (psign)
|
|
|
|
*psign = pmeth->sign;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_verify(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pverify_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (**pverify) (EVP_PKEY_CTX *ctx,
|
|
|
|
const unsigned char *sig,
|
|
|
|
size_t siglen,
|
|
|
|
const unsigned char *tbs,
|
|
|
|
size_t tbslen))
|
|
|
|
{
|
|
|
|
if (pverify_init)
|
|
|
|
*pverify_init = pmeth->verify_init;
|
|
|
|
if (pverify)
|
|
|
|
*pverify = pmeth->verify;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_verify_recover(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pverify_recover_init) (EVP_PKEY_CTX
|
|
|
|
*ctx),
|
|
|
|
int (**pverify_recover) (EVP_PKEY_CTX
|
|
|
|
*ctx,
|
|
|
|
unsigned char
|
|
|
|
*sig,
|
|
|
|
size_t *siglen,
|
|
|
|
const unsigned
|
|
|
|
char *tbs,
|
|
|
|
size_t tbslen))
|
|
|
|
{
|
|
|
|
if (pverify_recover_init)
|
|
|
|
*pverify_recover_init = pmeth->verify_recover_init;
|
|
|
|
if (pverify_recover)
|
|
|
|
*pverify_recover = pmeth->verify_recover;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_signctx(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**psignctx_init) (EVP_PKEY_CTX *ctx,
|
|
|
|
EVP_MD_CTX *mctx),
|
|
|
|
int (**psignctx) (EVP_PKEY_CTX *ctx,
|
|
|
|
unsigned char *sig,
|
|
|
|
size_t *siglen,
|
|
|
|
EVP_MD_CTX *mctx))
|
|
|
|
{
|
|
|
|
if (psignctx_init)
|
|
|
|
*psignctx_init = pmeth->signctx_init;
|
|
|
|
if (psignctx)
|
|
|
|
*psignctx = pmeth->signctx;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_verifyctx(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pverifyctx_init) (EVP_PKEY_CTX *ctx,
|
|
|
|
EVP_MD_CTX *mctx),
|
|
|
|
int (**pverifyctx) (EVP_PKEY_CTX *ctx,
|
|
|
|
const unsigned char *sig,
|
|
|
|
int siglen,
|
|
|
|
EVP_MD_CTX *mctx))
|
|
|
|
{
|
|
|
|
if (pverifyctx_init)
|
|
|
|
*pverifyctx_init = pmeth->verifyctx_init;
|
|
|
|
if (pverifyctx)
|
|
|
|
*pverifyctx = pmeth->verifyctx;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_encrypt(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pencrypt_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (**pencryptfn) (EVP_PKEY_CTX *ctx,
|
|
|
|
unsigned char *out,
|
|
|
|
size_t *outlen,
|
|
|
|
const unsigned char *in,
|
|
|
|
size_t inlen))
|
|
|
|
{
|
|
|
|
if (pencrypt_init)
|
|
|
|
*pencrypt_init = pmeth->encrypt_init;
|
|
|
|
if (pencryptfn)
|
|
|
|
*pencryptfn = pmeth->encrypt;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_decrypt(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pdecrypt_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (**pdecrypt) (EVP_PKEY_CTX *ctx,
|
|
|
|
unsigned char *out,
|
|
|
|
size_t *outlen,
|
|
|
|
const unsigned char *in,
|
|
|
|
size_t inlen))
|
|
|
|
{
|
|
|
|
if (pdecrypt_init)
|
|
|
|
*pdecrypt_init = pmeth->decrypt_init;
|
|
|
|
if (pdecrypt)
|
|
|
|
*pdecrypt = pmeth->decrypt;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_derive(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pderive_init) (EVP_PKEY_CTX *ctx),
|
|
|
|
int (**pderive) (EVP_PKEY_CTX *ctx,
|
|
|
|
unsigned char *key,
|
|
|
|
size_t *keylen))
|
|
|
|
{
|
|
|
|
if (pderive_init)
|
|
|
|
*pderive_init = pmeth->derive_init;
|
|
|
|
if (pderive)
|
|
|
|
*pderive = pmeth->derive;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth,
|
2015-07-21 05:05:10 +08:00
|
|
|
int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
|
|
|
|
void *p2),
|
|
|
|
int (**pctrl_str) (EVP_PKEY_CTX *ctx,
|
|
|
|
const char *type,
|
|
|
|
const char *value))
|
|
|
|
{
|
|
|
|
if (pctrl)
|
|
|
|
*pctrl = pmeth->ctrl;
|
|
|
|
if (pctrl_str)
|
|
|
|
*pctrl_str = pmeth->ctrl_str;
|
|
|
|
}
|
2017-09-04 22:02:59 +08:00
|
|
|
|
2019-11-08 10:47:53 +08:00
|
|
|
void EVP_PKEY_meth_get_digestsign(EVP_PKEY_METHOD *pmeth,
|
|
|
|
int (**digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
|
|
|
|
const unsigned char *tbs, size_t tbslen))
|
|
|
|
{
|
|
|
|
if (digestsign)
|
|
|
|
*digestsign = pmeth->digestsign;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EVP_PKEY_meth_get_digestverify(EVP_PKEY_METHOD *pmeth,
|
|
|
|
int (**digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig,
|
|
|
|
size_t siglen, const unsigned char *tbs,
|
|
|
|
size_t tbslen))
|
|
|
|
{
|
|
|
|
if (digestverify)
|
|
|
|
*digestverify = pmeth->digestverify;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_check(const EVP_PKEY_METHOD *pmeth,
|
2017-09-04 22:02:59 +08:00
|
|
|
int (**pcheck) (EVP_PKEY *pkey))
|
|
|
|
{
|
2018-09-13 10:17:14 +08:00
|
|
|
if (pcheck != NULL)
|
2017-09-04 22:02:59 +08:00
|
|
|
*pcheck = pmeth->check;
|
|
|
|
}
|
2017-11-01 00:45:24 +08:00
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_public_check(const EVP_PKEY_METHOD *pmeth,
|
2017-11-01 00:45:24 +08:00
|
|
|
int (**pcheck) (EVP_PKEY *pkey))
|
|
|
|
{
|
2018-09-13 10:17:14 +08:00
|
|
|
if (pcheck != NULL)
|
2017-11-01 00:45:24 +08:00
|
|
|
*pcheck = pmeth->public_check;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:58:18 +08:00
|
|
|
void EVP_PKEY_meth_get_param_check(const EVP_PKEY_METHOD *pmeth,
|
2017-11-01 00:45:24 +08:00
|
|
|
int (**pcheck) (EVP_PKEY *pkey))
|
|
|
|
{
|
2018-09-13 10:17:14 +08:00
|
|
|
if (pcheck != NULL)
|
2017-11-01 00:45:24 +08:00
|
|
|
*pcheck = pmeth->param_check;
|
|
|
|
}
|
2018-09-04 00:51:04 +08:00
|
|
|
|
|
|
|
void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth,
|
|
|
|
int (**pdigest_custom) (EVP_PKEY_CTX *ctx,
|
|
|
|
EVP_MD_CTX *mctx))
|
|
|
|
{
|
2018-09-05 15:19:17 +08:00
|
|
|
if (pdigest_custom != NULL)
|
2018-09-04 00:51:04 +08:00
|
|
|
*pdigest_custom = pmeth->digest_custom;
|
|
|
|
}
|
2020-01-12 09:32:12 +08:00
|
|
|
|
|
|
|
#endif /* FIPS_MODE */
|