diff options
-rw-r--r-- | CHANGES.md | 6 | ||||
-rw-r--r-- | crypto/err/openssl.txt | 5 | ||||
-rw-r--r-- | crypto/evp/evp_err.c | 7 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 254 | ||||
-rw-r--r-- | crypto/evp/pmeth_gn.c | 8 | ||||
-rw-r--r-- | include/crypto/asn1.h | 5 | ||||
-rw-r--r-- | include/crypto/evp.h | 4 | ||||
-rw-r--r-- | include/openssl/evperr.h | 11 | ||||
-rw-r--r-- | test/keymgmt_internal_test.c | 12 |
9 files changed, 173 insertions, 139 deletions
diff --git a/CHANGES.md b/CHANGES.md index ba2569bf62..82c186a6cd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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. diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index cb106e23b1..1a21faa1e1 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -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 diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 20921710ee..3f2b814f18 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -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"}, diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 9c11da697e..92d65d9f43 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -94,16 +94,35 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) */ /* - * Only check that type match this early when both keys are legacy. - * If either of them is provided, we let evp_keymgmt_util_copy() - * do this check, after having exported either of them that isn't - * provided. + * If |to| is a legacy key and |from| isn't, we must downgrade |from|. + * If that fails, this function fails. */ - if (to->keymgmt == NULL && from->keymgmt == NULL) { - if (to->type == EVP_PKEY_NONE) { + if (to->type != EVP_PKEY_NONE && from->keymgmt != NULL) + if (!evp_pkey_downgrade((EVP_PKEY *)from)) + return 0; + + /* + * Make sure |to| is typed. Content is less important at this early + * stage. + * + * 1. If |to| is untyped, assign |from|'s key type to it. + * 2. If |to| contains a legacy key, compare its |type| to |from|'s. + * (|from| was already downgraded above) + * + * If |to| is a provided key, there's nothing more to do here, functions + * like evp_keymgmt_util_copy() and evp_pkey_export_to_provider() called + * further down help us find out if they are the same or not. + */ + if (to->type == EVP_PKEY_NONE && to->keymgmt == NULL) { + if (from->type != EVP_PKEY_NONE) { if (EVP_PKEY_set_type(to, from->type) == 0) return 0; - } else if (to->type != from->type) { + } else { + if (EVP_PKEY_set_type_by_keymgmt(to, from->keymgmt) == 0) + return 0; + } + } else if (to->type != EVP_PKEY_NONE) { + if (to->type != from->type) { EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES); goto err; } @@ -121,30 +140,6 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) return 0; } - /* - * If |from| is provided, we upgrade |to| to be provided as well. - * This drops the legacy key from |to|. - * evp_pkey_upgrade_to_provider() checks if |to| is already provided, - * we don't need to do that here. - * - * TODO(3.0) We should investigate if that's too aggressive and make - * this scenario unsupported instead. - */ - if (from->keymgmt != NULL) { - EVP_KEYMGMT *tmp_keymgmt = from->keymgmt; - - /* - * The returned pointer is known to be cached, so we don't have to - * save it. However, if it's NULL, something went wrong and we can't - * copy. - */ - if (evp_pkey_upgrade_to_provider(to, NULL, - &tmp_keymgmt, NULL) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); - return 0; - } - } - /* For purely provided keys, we just call the keymgmt utility */ if (to->keymgmt != NULL && from->keymgmt != NULL) return evp_keymgmt_util_copy(to, (EVP_PKEY *)from, @@ -161,8 +156,12 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) evp_pkey_export_to_provider((EVP_PKEY *)from, NULL, &to_keymgmt, NULL); + /* + * If we get a NULL, it could be an internal error, or it could be + * that there's a key mismatch. We're pretending the latter... + */ if (from_keydata == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); return 0; } return evp_keymgmt_copy(to->keymgmt, to->keydata, from_keydata, @@ -208,20 +207,25 @@ static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b, return evp_keymgmt_util_match((EVP_PKEY *)a, (EVP_PKEY *)b, selection); /* - * Here, we know that we have a mixture of legacy and provided keys. - * Try cross export and compare the resulting key data. + * At this point, one of them is provided, the other not. This allows + * us to compare types using legacy NIDs. + */ + if ((a->type != EVP_PKEY_NONE + && !EVP_KEYMGMT_is_a(b->keymgmt, OBJ_nid2sn(a->type))) + || (b->type != EVP_PKEY_NONE + && !EVP_KEYMGMT_is_a(a->keymgmt, OBJ_nid2sn(b->type)))) + return -1; /* not the same key type */ + + /* + * We've determined that they both are the same keytype, so the next + * step is to do a bit of cross export to ensure we have keydata for + * both keys in the same keymgmt. */ keymgmt1 = a->keymgmt; keydata1 = a->keydata; keymgmt2 = b->keymgmt; keydata2 = b->keydata; - if ((keymgmt1 == NULL - && !EVP_KEYMGMT_is_a(keymgmt2, OBJ_nid2sn(a->type))) - || (keymgmt2 == NULL - && !EVP_KEYMGMT_is_a(keymgmt1, OBJ_nid2sn(b->type)))) - return -1; /* not the same key type */ - if (keymgmt2 != NULL && keymgmt2->match != NULL) { tmp_keydata = evp_pkey_export_to_provider((EVP_PKEY *)a, NULL, &keymgmt2, NULL); @@ -359,6 +363,7 @@ EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e, int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, size_t *len) { + /* TODO(3.0) Do we need to do anything about provider side keys? */ if (pkey->ameth->get_priv_key == NULL) { EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); @@ -376,6 +381,7 @@ int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, size_t *len) { + /* TODO(3.0) Do we need to do anything about provider side keys? */ if (pkey->ameth->get_pub_key == NULL) { EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); @@ -524,6 +530,10 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) void *EVP_PKEY_get0(const EVP_PKEY *pkey) { + if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY); + return NULL; + } return pkey->pkey.ptr; } @@ -579,6 +589,10 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { + if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY); + return NULL; + } if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) { EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY); return NULL; @@ -606,6 +620,10 @@ int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { + if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY); + return NULL; + } if (pkey->type != EVP_PKEY_DSA) { EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY); return NULL; @@ -634,6 +652,10 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) { + if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY); + return NULL; + } if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY); return NULL; @@ -664,6 +686,10 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey) { + if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY); + return NULL; + } if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) { EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY); return NULL; @@ -1349,101 +1375,87 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx, } #ifndef FIPS_MODE -/* - * This differs from exporting in that it releases the legacy key and assigns - * the export keymgmt and keydata to the "origin" provider side key instead - * of the operation cache. - */ -void *evp_pkey_upgrade_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx, - EVP_KEYMGMT **keymgmt, - const char *propquery) +int evp_pkey_downgrade(EVP_PKEY *pk) { - EVP_KEYMGMT *allocated_keymgmt = NULL; - EVP_KEYMGMT *tmp_keymgmt = NULL; - void *keydata = NULL; + EVP_KEYMGMT *keymgmt = pk->keymgmt; + void *keydata = pk->keydata; + int type = pk->save_type; + const char *keytype = NULL; - if (pk == NULL) - return NULL; + /* If this isn't a provider side key, we're done */ + if (keymgmt == NULL) + return 1; + + /* Get the key type name for error reporting */ + if (type != EVP_PKEY_NONE) + keytype = OBJ_nid2sn(type); + else + keytype = + evp_first_name(EVP_KEYMGMT_provider(keymgmt), keymgmt->name_id); /* - * If this key is already "upgraded", this function shouldn't have been - * called. + * |save_type| was set when any of the EVP_PKEY_set_type functions + * was called. It was set to EVP_PKEY_NONE if the key type wasn't + * recognised to be any of the legacy key types, and the downgrade + * isn't possible. */ - if (!ossl_assert(pk->keymgmt == NULL)) - return NULL; - - if (keymgmt != NULL) { - tmp_keymgmt = *keymgmt; - *keymgmt = NULL; + if (type == EVP_PKEY_NONE) { + ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_KEY_TYPE, + "key type = %s, can't downgrade", keytype); + return 0; } - /* If the key isn't a legacy one, bail out, but with proper values */ - if (pk->pkey.ptr == NULL) { - tmp_keymgmt = pk->keymgmt; - keydata = pk->keydata; - } else { - /* If the legacy key doesn't have an export function, give up */ - if (pk->ameth->export_to == NULL) - return NULL; - - /* - * If no keymgmt was given or found, get a default keymgmt. We do - * so by letting EVP_PKEY_CTX_new_from_pkey() do it for us, then we - * steal it. - */ - if (tmp_keymgmt == NULL) { - EVP_PKEY_CTX *ctx = - EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery); - - tmp_keymgmt = ctx->keymgmt; - ctx->keymgmt = NULL; - EVP_PKEY_CTX_free(ctx); - } - - /* If we still don't have a keymgmt, give up */ - if (tmp_keymgmt == NULL) - goto end; - - /* Make sure that the keymgmt key type matches the legacy NID */ - if (!ossl_assert(EVP_KEYMGMT_is_a(tmp_keymgmt, OBJ_nid2sn(pk->type)))) - goto end; + /* + * To be able to downgrade, we steal the provider side "origin" keymgmt + * and keydata. We've already grabbed the pointers, so all we need to + * do is clear those pointers in |pk| and then call evp_pkey_free_it(). + * That way, we can restore |pk| if we need to. + */ + pk->keymgmt = NULL; + pk->keydata = NULL; + evp_pkey_free_it(pk); + if (EVP_PKEY_set_type(pk, type)) { + /* If the key is typed but empty, we're done */ + if (keydata == NULL) + return 1; - if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL) - goto end; + if (pk->ameth->import_from == NULL) { + ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION, + "key type = %s", keytype); + } else if (evp_keymgmt_export(keymgmt, keydata, + OSSL_KEYMGMT_SELECT_ALL, + pk->ameth->import_from, pk)) { + /* + * Save the provider side data in the operation cache, so they'll + * find it again. evp_pkey_free_it() cleared the cache, so it's + * safe to assume slot zero is free. + * Note that evp_keymgmt_util_cache_keydata() increments keymgmt's + * reference count. + */ + evp_keymgmt_util_cache_keydata(pk, 0, keymgmt, keydata); - if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt) - || !EVP_KEYMGMT_up_ref(tmp_keymgmt)) { - evp_keymgmt_freedata(tmp_keymgmt, keydata); - keydata = NULL; - goto end; + /* Synchronize the dirty count */ + pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk); + return 1; } - /* - * Clear the operation cache, all the legacy data, as well as the - * dirty counters - */ - evp_pkey_free_legacy(pk); - pk->dirty_cnt_copy = 0; - - evp_keymgmt_util_clear_operation_cache(pk); - pk->keymgmt = tmp_keymgmt; - pk->keydata = keydata; - evp_keymgmt_util_cache_keyinfo(pk); + ERR_raise_data(ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE, + "key type = %s", keytype); } - end: /* - * If nothing was upgraded, |tmp_keymgmt| might point at a freed - * EVP_KEYMGMT, so we clear it to be safe. It shouldn't be useful for - * the caller either way in that case. + * Something went wrong. This could for example happen if the keymgmt + * turns out to be an HSM implementation that refuses to let go of some + * of the key data, typically the private bits. In this case, we restore + * the provider side internal "origin" and leave it at that. */ - if (keydata == NULL) - tmp_keymgmt = NULL; - - if (keymgmt != NULL) - *keymgmt = tmp_keymgmt; - - EVP_KEYMGMT_free(allocated_keymgmt); - return keydata; + if (!ossl_assert(EVP_PKEY_set_type_by_keymgmt(pk, keymgmt))) { + /* This should not be impossible */ + ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + pk->keydata = keydata; + evp_keymgmt_util_cache_keyinfo(pk); + return 0; /* No downgrade, but at least the key is restored */ } #endif /* FIPS_MODE */ diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index 1bf95af2ac..67800282de 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -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) diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h index 0e7e9ba3d4..20732c2251 100644 --- a/include/crypto/asn1.h +++ b/include/crypto/asn1.h @@ -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) diff --git a/include/crypto/evp.h b/include/crypto/evp.h index e5f9aad010..63b6dad9c6 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -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 diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index 994268af91..9290cfff94 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -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 diff --git a/test/keymgmt_internal_test.c b/test/keymgmt_internal_test.c index 5ef238ccf1..fd60893a45 100644 --- a/test/keymgmt_internal_test.c +++ b/test/keymgmt_internal_test.c @@ -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; /* |