From 4cae07fef3b24bee1646f6085c52175ef3755d5b Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 10 Jul 2019 14:30:55 +0200 Subject: [PATCH] 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 (Merged from https://github.com/openssl/openssl/pull/9312) --- crypto/evp/keymgmt_lib.c | 27 ++++++++++++++----- crypto/evp/p_lib.c | 3 +++ crypto/include/internal/evp_int.h | 3 ++- .../man3/evp_keymgmt_export_to_provider.pod | 12 ++++++--- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index 76c4a30a1c..7169f4270e 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -80,13 +80,7 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) return NULL; if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy) - for (i = 0; - 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; - } + evp_keymgmt_clear_pkey_cache(pk); } /* @@ -186,3 +180,22 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) } 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); + } + } +} diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index c6ebfe6462..653693e1dc 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -613,6 +613,9 @@ void EVP_PKEY_free(EVP_PKEY *x) static void EVP_PKEY_free_it(EVP_PKEY *x) { /* internal function; x is never NULL */ + + evp_keymgmt_clear_pkey_cache(x); + if (x->ameth && x->ameth->pkey_free) { x->ameth->pkey_free(x); x->pkey.ptr = NULL; diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index ff9b6e545b..af273f2bf3 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -560,8 +560,9 @@ void openssl_add_all_kdfs_int(void); void evp_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_clear_pkey_cache(EVP_PKEY *pk); /* Pulling defines out of C source files */ diff --git a/doc/internal/man3/evp_keymgmt_export_to_provider.pod b/doc/internal/man3/evp_keymgmt_export_to_provider.pod index 51234bd609..72b766fb93 100644 --- a/doc/internal/man3/evp_keymgmt_export_to_provider.pod +++ b/doc/internal/man3/evp_keymgmt_export_to_provider.pod @@ -2,13 +2,16 @@ =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 #include "internal/evp_int.h" void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt); + void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk); =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 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 -evp_keymgmt_export_to_provider() returns a pointer to the newly -created provider side key, or NULL on error. +evp_keymgmt_export_to_provider() returns a pointer to the appropriate +provider side key (created or found again), or NULL on error. =head1 NOTES -- 2.34.1