Add evp_keymgmt_clear_pkey_cache() and use it

This function clears the cache of provider key references, and is used
in evp_keymgmt_export_to_provider() when the internal key is dirty, as
well as by EVP_PKEY_free_it().

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9312)
This commit is contained in:
Richard Levitte 2019-07-10 14:30:55 +02:00
parent d0ea49a820
commit 4cae07fef3
4 changed files with 34 additions and 11 deletions

View file

@ -80,13 +80,7 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
return NULL; return NULL;
if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy) if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy)
for (i = 0; evp_keymgmt_clear_pkey_cache(pk);
i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL;
i++) {
pk->pkeys[i].keymgmt->freekey(pk->pkeys[i].provkey);
pk->pkeys[i].keymgmt = NULL;
pk->pkeys[i].provkey = NULL;
}
} }
/* /*
@ -186,3 +180,22 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
} }
return provkey; return provkey;
} }
void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk)
{
size_t i;
if (pk != NULL) {
for (i = 0;
i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL;
i++) {
EVP_KEYMGMT *keymgmt = pk->pkeys[i].keymgmt;
void *provkey = pk->pkeys[i].provkey;
pk->pkeys[i].keymgmt = NULL;
pk->pkeys[i].provkey = NULL;
keymgmt->freekey(provkey);
EVP_KEYMGMT_free(keymgmt);
}
}
}

View file

@ -613,6 +613,9 @@ void EVP_PKEY_free(EVP_PKEY *x)
static void EVP_PKEY_free_it(EVP_PKEY *x) static void EVP_PKEY_free_it(EVP_PKEY *x)
{ {
/* internal function; x is never NULL */ /* internal function; x is never NULL */
evp_keymgmt_clear_pkey_cache(x);
if (x->ameth && x->ameth->pkey_free) { if (x->ameth && x->ameth->pkey_free) {
x->ameth->pkey_free(x); x->ameth->pkey_free(x);
x->pkey.ptr = NULL; x->pkey.ptr = NULL;

View file

@ -560,8 +560,9 @@ void openssl_add_all_kdfs_int(void);
void evp_cleanup_int(void); void evp_cleanup_int(void);
void evp_app_cleanup_int(void); void evp_app_cleanup_int(void);
/* KEYMGMT helper functions */
void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt); void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk);
/* Pulling defines out of C source files */ /* Pulling defines out of C source files */

View file

@ -2,13 +2,16 @@
=head1 NAME =head1 NAME
evp_keymgmt_export_to_provider - key material exporter to providers for EVP evp_keymgmt_export_to_provider,
evp_keymgmt_clear_pkey_cache
- key material provider export for EVP
=head1 SYNOPSIS =head1 SYNOPSIS
#include "internal/evp_int.h" #include "internal/evp_int.h"
void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt); void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt);
void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk);
=head1 DESCRIPTION =head1 DESCRIPTION
@ -24,10 +27,13 @@ is_dirty() method returns 1.
If it has, the cache of already exported keys is cleared, and a new If it has, the cache of already exported keys is cleared, and a new
export is made with the new key material. export is made with the new key material.
evp_keymgmt_clear_pkey_cache() can be used to explicitly clear the
cache of provider key references.
=head1 RETURN VALUES =head1 RETURN VALUES
evp_keymgmt_export_to_provider() returns a pointer to the newly evp_keymgmt_export_to_provider() returns a pointer to the appropriate
created provider side key, or NULL on error. provider side key (created or found again), or NULL on error.
=head1 NOTES =head1 NOTES