提交 f4a3799c 编写于 作者: R Richard Levitte 提交者: Pauli

EVP: Make EVP_PKEY_set_params() increment the dirty count

When the internal key is changed, we must count it as muted, so that
next time the affected key is considered for an operation, it gets
re-exported to the signing provider.  In other words, this will clear
the EVP_PKEY export cache when the next export attempt occurs.

This also updates evp_keymgmt_util_export_to_provider() to actually
look at the dirty count for provider native origin keys, and act
appropriately.
Reviewed-by: NPaul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14056)
上级 7dc67708
...@@ -101,15 +101,22 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) ...@@ -101,15 +101,22 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
if (pk->keymgmt == keymgmt) if (pk->keymgmt == keymgmt)
return pk->keydata; return pk->keydata;
/* If this key is already exported to |keymgmt|, no more to do */
CRYPTO_THREAD_read_lock(pk->lock); CRYPTO_THREAD_read_lock(pk->lock);
i = evp_keymgmt_util_find_operation_cache_index(pk, keymgmt); /*
if (i < OSSL_NELEM(pk->operation_cache) * If the provider native "origin" hasn't changed since last time, we
&& pk->operation_cache[i].keymgmt != NULL) { * try to find our keymgmt in the operation cache. If it has changed,
void *ret = pk->operation_cache[i].keydata; * |i| remains zero, and we will clear the cache further down.
*/
if (pk->dirty_cnt == pk->dirty_cnt_copy) {
/* If this key is already exported to |keymgmt|, no more to do */
i = evp_keymgmt_util_find_operation_cache_index(pk, keymgmt);
if (i < OSSL_NELEM(pk->operation_cache)
&& pk->operation_cache[i].keymgmt != NULL) {
void *ret = pk->operation_cache[i].keydata;
CRYPTO_THREAD_unlock(pk->lock); CRYPTO_THREAD_unlock(pk->lock);
return ret; return ret;
}
} }
CRYPTO_THREAD_unlock(pk->lock); CRYPTO_THREAD_unlock(pk->lock);
...@@ -177,12 +184,22 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) ...@@ -177,12 +184,22 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
return ret; return ret;
} }
/*
* If the dirty counter changed since last time, then clear the
* operation cache. In that case, we know that |i| is zero.
*/
if (pk->dirty_cnt != pk->dirty_cnt_copy)
evp_keymgmt_util_clear_operation_cache(pk, 0);
/* Add the new export to the operation cache */ /* Add the new export to the operation cache */
if (!evp_keymgmt_util_cache_keydata(pk, i, keymgmt, import_data.keydata)) { if (!evp_keymgmt_util_cache_keydata(pk, i, keymgmt, import_data.keydata)) {
evp_keymgmt_freedata(keymgmt, import_data.keydata); evp_keymgmt_freedata(keymgmt, import_data.keydata);
return NULL; return NULL;
} }
/* Synchronize the dirty count */
pk->dirty_cnt_copy = pk->dirty_cnt;
CRYPTO_THREAD_unlock(pk->lock); CRYPTO_THREAD_unlock(pk->lock);
return import_data.keydata; return import_data.keydata;
......
...@@ -2228,11 +2228,12 @@ const OSSL_PARAM *EVP_PKEY_settable_params(EVP_PKEY *pkey) ...@@ -2228,11 +2228,12 @@ const OSSL_PARAM *EVP_PKEY_settable_params(EVP_PKEY *pkey)
int EVP_PKEY_set_params(EVP_PKEY *pkey, OSSL_PARAM params[]) int EVP_PKEY_set_params(EVP_PKEY *pkey, OSSL_PARAM params[])
{ {
if (pkey == NULL if (pkey == NULL)
|| pkey->keymgmt == NULL
|| pkey->keydata == NULL)
return 0; return 0;
return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params);
pkey->dirty_cnt++;
return evp_pkey_is_provided(pkey)
&& evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params);
} }
#ifndef FIPS_MODULE #ifndef FIPS_MODULE
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册