Commit acb90ba8 authored by Richard Levitte's avatar Richard Levitte

EVP: Downgrade keys rather than upgrade

Upgrading EVP_PKEYs from containing legacy keys to containing provider
side keys proved to be risky, with a number of unpleasant corner
cases, and with functions like EVP_PKEY_get0_DSA() failing
unexpectedly.

We therefore change course, and instead of upgrading legacy internal
keys to provider side internal keys, we downgrade provider side
internal keys to legacy ones.  To be able to do this, we add
|import_from| and make it a callback function designed for
evp_keymgmt_export().

This means that evp_pkey_upgrade_to_provider() is replaced with
evp_pkey_downgrade().

EVP_PKEY_copy_parameters() is the most deeply affected function of
this change.

Fixes #11366
Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11375)
parent 8243d8d1
......@@ -24,6 +24,12 @@ OpenSSL 3.0
### Changes between 1.1.1 and 3.0 [xx XXX xxxx] ###
* EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH(), and
EVP_PKEY_get0_EC_KEY() can now handle EVP_PKEYs with provider side
internal keys, if they correspond to one of those built in types.
*Richard Levitte*
* Added EVP_PKEY_set_type_by_keymgmt(), to initialise an EVP_PKEY to
contain a provider side internal key.
......
......@@ -2525,6 +2525,8 @@ EVP_R_FINAL_ERROR:188:final error
EVP_R_FIPS_MODE_NOT_SUPPORTED:167:fips mode not supported
EVP_R_GET_RAW_KEY_FAILED:182:get raw key failed
EVP_R_ILLEGAL_SCRYPT_PARAMETERS:171:illegal scrypt parameters
EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS:204:inaccessible domain parameters
EVP_R_INACCESSIBLE_KEY:203:inaccessible key
EVP_R_INITIALIZATION_ERROR:134:initialization error
EVP_R_INPUT_NOT_INITIALIZED:111:input not initialized
EVP_R_INVALID_CUSTOM_LENGTH:185:invalid custom length
......@@ -2537,6 +2539,7 @@ EVP_R_INVALID_OPERATION:148:invalid operation
EVP_R_INVALID_PROVIDER_FUNCTIONS:193:invalid provider functions
EVP_R_INVALID_SALT_LENGTH:186:invalid salt length
EVP_R_KEYGEN_FAILURE:120:keygen failure
EVP_R_KEYMGMT_EXPORT_FAILURE:205:keymgmt export failure
EVP_R_KEY_SETUP_FAILED:180:key setup failed
EVP_R_MEMORY_LIMIT_EXCEEDED:172:memory limit exceeded
EVP_R_MESSAGE_DIGEST_IS_NULL:159:message digest is null
......@@ -2547,6 +2550,7 @@ EVP_R_NOT_XOF_OR_INVALID_LENGTH:178:not XOF or invalid length
EVP_R_NO_CIPHER_SET:131:no cipher set
EVP_R_NO_DEFAULT_DIGEST:158:no default digest
EVP_R_NO_DIGEST_SET:139:no digest set
EVP_R_NO_IMPORT_FUNCTION:206:no import function
EVP_R_NO_KEYMGMT_AVAILABLE:199:no keymgmt available
EVP_R_NO_KEYMGMT_PRESENT:196:no keymgmt present
EVP_R_NO_KEY_SET:154:no key set
......@@ -2566,6 +2570,7 @@ EVP_R_PUBLIC_KEY_NOT_RSA:106:public key not rsa
EVP_R_TOO_MANY_RECORDS:183:too many records
EVP_R_UNKNOWN_CIPHER:160:unknown cipher
EVP_R_UNKNOWN_DIGEST:161:unknown digest
EVP_R_UNKNOWN_KEY_TYPE:207:unknown key type
EVP_R_UNKNOWN_OPTION:169:unknown option
EVP_R_UNKNOWN_PBE_ALGORITHM:121:unknown pbe algorithm
EVP_R_UNSUPPORTED_ALGORITHM:156:unsupported algorithm
......
......@@ -71,6 +71,9 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GET_RAW_KEY_FAILED), "get raw key failed"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ILLEGAL_SCRYPT_PARAMETERS),
"illegal scrypt parameters"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS),
"inaccessible domain parameters"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INACCESSIBLE_KEY), "inaccessible key"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INITIALIZATION_ERROR),
"initialization error"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INPUT_NOT_INITIALIZED),
......@@ -88,6 +91,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH),
"invalid salt length"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYGEN_FAILURE), "keygen failure"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYMGMT_EXPORT_FAILURE),
"keymgmt export failure"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEY_SETUP_FAILED), "key setup failed"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MEMORY_LIMIT_EXCEEDED),
"memory limit exceeded"},
......@@ -103,6 +108,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_CIPHER_SET), "no cipher set"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DEFAULT_DIGEST), "no default digest"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DIGEST_SET), "no digest set"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_IMPORT_FUNCTION), "no import function"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_AVAILABLE),
"no keymgmt available"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_PRESENT), "no keymgmt present"},
......@@ -129,6 +135,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_TOO_MANY_RECORDS), "too many records"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_CIPHER), "unknown cipher"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "unknown digest"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_KEY_TYPE), "unknown key type"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_OPTION), "unknown option"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_PBE_ALGORITHM),
"unknown pbe algorithm"},
......
This diff is collapsed.
......@@ -180,6 +180,8 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
#ifdef FIPS_MODE
goto not_supported;
#else
if (ctx->pkey && !evp_pkey_downgrade(ctx->pkey))
goto not_accessible;
switch (ctx->operation) {
case EVP_PKEY_OP_PARAMGEN:
ret = ctx->pmeth->paramgen(ctx, *ppkey);
......@@ -208,6 +210,12 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED);
ret = -1;
goto end;
#ifndef FIPS_MODE
not_accessible:
ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS);
ret = -1;
goto end;
#endif
}
int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
......
......@@ -11,6 +11,8 @@
/* ASN1 public key method structure */
#include <openssl/core.h>
struct evp_pkey_asn1_method_st {
int pkey_id;
int pkey_base_id;
......@@ -68,10 +70,11 @@ struct evp_pkey_asn1_method_st {
* TODO: Make sure these functions are defined for key types that are
* implemented in providers.
*/
/* Exports to providers */
/* Exports and imports to / from providers */
size_t (*dirty_cnt) (const EVP_PKEY *pk);
int (*export_to) (const EVP_PKEY *pk, void *to_keydata,
EVP_KEYMGMT *to_keymgmt);
OSSL_CALLBACK *import_from;
} /* EVP_PKEY_ASN1_METHOD */ ;
DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)
......
......@@ -630,10 +630,8 @@ void evp_app_cleanup_int(void);
void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
EVP_KEYMGMT **keymgmt,
const char *propquery);
void *evp_pkey_upgrade_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
EVP_KEYMGMT **keymgmt,
const char *propquery);
#ifndef FIPS_MODE
int evp_pkey_downgrade(EVP_PKEY *pk);
void evp_pkey_free_legacy(EVP_PKEY *x);
#endif
......
......@@ -10,12 +10,6 @@
#ifndef OPENSSL_EVPERR_H
# define OPENSSL_EVPERR_H
# pragma once
# include <openssl/macros.h>
# ifndef OPENSSL_NO_DEPRECATED_3_0
# define HEADER_EVPERR_H
# endif
# include <openssl/opensslconf.h>
# include <openssl/symhacks.h>
......@@ -199,6 +193,8 @@ int ERR_load_EVP_strings(void);
# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167
# define EVP_R_GET_RAW_KEY_FAILED 182
# define EVP_R_ILLEGAL_SCRYPT_PARAMETERS 171
# define EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS 204
# define EVP_R_INACCESSIBLE_KEY 203
# define EVP_R_INITIALIZATION_ERROR 134
# define EVP_R_INPUT_NOT_INITIALIZED 111
# define EVP_R_INVALID_CUSTOM_LENGTH 185
......@@ -211,6 +207,7 @@ int ERR_load_EVP_strings(void);
# define EVP_R_INVALID_PROVIDER_FUNCTIONS 193
# define EVP_R_INVALID_SALT_LENGTH 186
# define EVP_R_KEYGEN_FAILURE 120
# define EVP_R_KEYMGMT_EXPORT_FAILURE 205
# define EVP_R_KEY_SETUP_FAILED 180
# define EVP_R_MEMORY_LIMIT_EXCEEDED 172
# define EVP_R_MESSAGE_DIGEST_IS_NULL 159
......@@ -221,6 +218,7 @@ int ERR_load_EVP_strings(void);
# define EVP_R_NO_CIPHER_SET 131
# define EVP_R_NO_DEFAULT_DIGEST 158
# define EVP_R_NO_DIGEST_SET 139
# define EVP_R_NO_IMPORT_FUNCTION 206
# define EVP_R_NO_KEYMGMT_AVAILABLE 199
# define EVP_R_NO_KEYMGMT_PRESENT 196
# define EVP_R_NO_KEY_SET 154
......@@ -238,6 +236,7 @@ int ERR_load_EVP_strings(void);
# define EVP_R_TOO_MANY_RECORDS 183
# define EVP_R_UNKNOWN_CIPHER 160
# define EVP_R_UNKNOWN_DIGEST 161
# define EVP_R_UNKNOWN_KEY_TYPE 207
# define EVP_R_UNKNOWN_OPTION 169
# define EVP_R_UNKNOWN_PBE_ALGORITHM 121
# define EVP_R_UNSUPPORTED_ALGORITHM 156
......
......@@ -207,14 +207,10 @@ static int test_pass_rsa(FIXTURE *fixture)
|| !TEST_ptr_ne(km1, km2))
goto err;
if (!TEST_ptr(evp_pkey_export_to_provider(pk, NULL, &km1, NULL))
|| !TEST_ptr(evp_pkey_upgrade_to_provider(pk, NULL, &km1, NULL))
|| !TEST_ptr(provkey = evp_keymgmt_util_export_to_provider(pk, km2)))
goto err;
if (!TEST_true(evp_keymgmt_export(km2, provkey,
OSSL_KEYMGMT_SELECT_KEYPAIR,
&export_cb, keydata)))
if (!TEST_ptr(provkey = evp_pkey_export_to_provider(pk, NULL, &km1, NULL))
|| !TEST_true(evp_keymgmt_export(km2, provkey,
OSSL_KEYMGMT_SELECT_KEYPAIR,
&export_cb, keydata)))
goto err;
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment