From a07c17ef57da20b7c6d075b303a6506f625dcd4e Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 15 Oct 2019 13:08:17 +0200 Subject: [PATCH] Add EVP_PKEY_CTX_new_provided() This works as much as possible EVP_PKEY_CTX_new_id(), except it takes data that's relevant for providers, algorithm name and property query string instead of NID and engine. Additionally, if EVP_PKEY_CTX_new() or EVP_PKEY_CTX_new_id() was called, the algorithm name in the EVP_PKEY context will be set to the short name of the given NID (explicit or the one of the given EVP_PKEY), thereby giving an easier transition from legacy methods to provided methods. The intent is that operations will use this information to fetch provider methods implicitly as needed. Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/10184) --- CHANGES | 8 ++++++++ crypto/evp/pmeth_lib.c | 20 +++++++++++++++++--- doc/man3/EVP_PKEY_CTX_new.pod | 21 +++++++++++++++++---- include/crypto/evp.h | 4 ++++ include/openssl/evp.h | 2 ++ util/libcrypto.num | 1 + 6 files changed, 49 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 442807f1d3..20e170c493 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,14 @@ Changes between 1.1.1 and 3.0.0 [xx XXX xxxx] + *) Added functionality to create an EVP_PKEY context based on data + for methods from providers. This takes an algorithm name and a + property query string and simply stores them, with the intent + that any operation that uses this context will use those strings + to fetch the needed methods implicitly, thereby making the port + of application written for pre-3.0 OpenSSL easier. + [Richard Levitte] + *) The undocumented function NCONF_WIN32() has been deprecated; for conversion details see the HISTORY section of doc/man5/config.pod [Rich Salz] diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 1ae22a7df4..c840a12b00 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -111,7 +111,9 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) return (**ret)(); } -static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) +static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, + const char *name, const char *propquery, + int id) { EVP_PKEY_CTX *ret; const EVP_PKEY_METHOD *pmeth = NULL; @@ -130,6 +132,8 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) return 0; id = pkey->type; } + name = OBJ_nid2sn(id); + propquery = NULL; #ifndef OPENSSL_NO_ENGINE if (e == NULL && pkey != NULL) e = pkey->pmeth_engine != NULL ? pkey->pmeth_engine : pkey->engine; @@ -171,6 +175,8 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE); return NULL; } + ret->algorithm = name; + ret->propquery = propquery; ret->engine = e; ret->pmeth = pmeth; ret->operation = EVP_PKEY_OP_UNDEFINED; @@ -277,12 +283,18 @@ void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { - return int_ctx_new(pkey, e, -1); + return int_ctx_new(pkey, e, NULL, NULL, -1); } EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { - return int_ctx_new(NULL, e, id); + return int_ctx_new(NULL, e, NULL, NULL, id); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(const char *name, + const char *propquery) +{ + return int_ctx_new(NULL, NULL, name, propquery, -1); } EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) @@ -312,6 +324,8 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) EVP_PKEY_up_ref(pctx->pkey); rctx->pkey = pctx->pkey; rctx->operation = pctx->operation; + rctx->algorithm = pctx->algorithm; + rctx->propquery = pctx->propquery; if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) { if (pctx->op.kex.exchange != NULL) { diff --git a/doc/man3/EVP_PKEY_CTX_new.pod b/doc/man3/EVP_PKEY_CTX_new.pod index 37f08e735d..7df650c12a 100644 --- a/doc/man3/EVP_PKEY_CTX_new.pod +++ b/doc/man3/EVP_PKEY_CTX_new.pod @@ -2,7 +2,9 @@ =head1 NAME -EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free - public key algorithm context functions +EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_new_provided, +EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free +- public key algorithm context functions =head1 SYNOPSIS @@ -10,6 +12,8 @@ EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free - pub EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); + EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(const char *name, + const char *propquery); EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx); void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); @@ -19,9 +23,18 @@ The EVP_PKEY_CTX_new() function allocates public key algorithm context using the algorithm specified in B and ENGINE B. The EVP_PKEY_CTX_new_id() function allocates public key algorithm context -using the algorithm specified by B and ENGINE B. It is normally used -when no B structure is associated with the operations, for example -during parameter generation of key generation for some algorithms. +using the algorithm specified by B and ENGINE B. + +The EVP_PKEY_CTX_new_provided() function allocates a public key +algorithm context using the algorithm specified by I and the +property query I. The strings aren't duplicated, so they +must remain unchanged for the lifetime of the returned B +or of any of its duplicates. + +EVP_PKEY_CTX_new_id() and EVP_PKEY_CTX_new_provided() are normally +used when no B structure is associated with the operations, +for example during parameter generation or key generation for some +algorithms. EVP_PKEY_CTX_dup() duplicates the context B. diff --git a/include/crypto/evp.h b/include/crypto/evp.h index c49ec404d6..22ef7e5602 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -21,6 +21,10 @@ struct evp_pkey_ctx_st { /* Actual operation */ int operation; + /* Algorithm name and properties associated with this context */ + const char *algorithm; + const char *propquery; + union { struct { EVP_KEYEXCH *exchange; diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 99eef2461d..9223df2f78 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1441,6 +1441,8 @@ const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt); EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(const char *name, + const char *propquery); EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx); void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); diff --git a/util/libcrypto.num b/util/libcrypto.num index d818197965..032936ed40 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4827,3 +4827,4 @@ EVP_DigestSignUpdate 4943 3_0_0 EXIST::FUNCTION: EVP_DigestVerifyInit_ex 4944 3_0_0 EXIST::FUNCTION: EVP_DigestVerifyUpdate 4945 3_0_0 EXIST::FUNCTION: BN_check_prime 4946 3_0_0 EXIST::FUNCTION: +EVP_PKEY_CTX_new_provided 4947 3_0_0 EXIST::FUNCTION: -- 2.25.1