mirror of https://github.com/openssl/openssl.git
Fix EVP_PKEY_can_sign() handling of NULL from query_operation_name()
EVP_PKEY_can_sign() assumed query_operation_name(OSSL_OP_SIGNATURE) always returns a non-NULL string. According to the documentation, query_operation_name() may return NULL, in which case EVP_KEYMGMT_get0_name() should be used as a fallback. Fixes #27790 Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/28620)
This commit is contained in:
parent
556ba81601
commit
051108ee53
|
@ -1135,15 +1135,14 @@ int EVP_PKEY_can_sign(const EVP_PKEY *pkey)
|
|||
} else {
|
||||
const OSSL_PROVIDER *prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt);
|
||||
OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
|
||||
const char *supported_sig =
|
||||
pkey->keymgmt->query_operation_name != NULL
|
||||
? pkey->keymgmt->query_operation_name(OSSL_OP_SIGNATURE)
|
||||
: EVP_KEYMGMT_get0_name(pkey->keymgmt);
|
||||
EVP_SIGNATURE *signature = NULL;
|
||||
EVP_SIGNATURE *sig;
|
||||
const char *name;
|
||||
|
||||
signature = EVP_SIGNATURE_fetch(libctx, supported_sig, NULL);
|
||||
if (signature != NULL) {
|
||||
EVP_SIGNATURE_free(signature);
|
||||
name = evp_keymgmt_util_query_operation_name(pkey->keymgmt,
|
||||
OSSL_OP_SIGNATURE);
|
||||
sig = EVP_SIGNATURE_fetch(libctx, name, NULL);
|
||||
if (sig != NULL) {
|
||||
EVP_SIGNATURE_free(sig);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ static int exptypes_selection;
|
|||
static int query_id;
|
||||
static int key_deleted;
|
||||
|
||||
unsigned fake_rsa_query_operation_name = 0;
|
||||
|
||||
typedef struct {
|
||||
OSSL_LIB_CTX *libctx;
|
||||
} PROV_FAKE_RSA_CTX;
|
||||
|
@ -90,7 +92,7 @@ static const char *fake_rsa_keymgmt_query(int id)
|
|||
/* record global for checking */
|
||||
query_id = id;
|
||||
|
||||
return "RSA";
|
||||
return fake_rsa_query_operation_name ? NULL: "RSA";
|
||||
}
|
||||
|
||||
static int fake_rsa_keymgmt_import(void *keydata, int selection,
|
||||
|
|
|
@ -14,5 +14,14 @@
|
|||
/* Fake RSA provider implementation */
|
||||
OSSL_PROVIDER *fake_rsa_start(OSSL_LIB_CTX *libctx);
|
||||
void fake_rsa_finish(OSSL_PROVIDER *p);
|
||||
|
||||
OSSL_PARAM *fake_rsa_key_params(int priv);
|
||||
void fake_rsa_restore_store_state(void);
|
||||
|
||||
/*
|
||||
* When fake_rsa_query_operation_name is set to a non-zero value,
|
||||
* query_operation_name() will return NULL.
|
||||
*
|
||||
* By default, it is 0, in which case query_operation_name() will return "RSA".
|
||||
*/
|
||||
extern unsigned fake_rsa_query_operation_name;
|
||||
|
|
|
@ -239,6 +239,77 @@ end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int test_pkey_can_sign(void)
|
||||
{
|
||||
OSSL_PROVIDER *fake_rsa = NULL;
|
||||
EVP_PKEY *pkey_fake = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
OSSL_PARAM *params = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Ensure other tests did not forget to reset fake_rsa_query_operation_name
|
||||
* to its default value: 0
|
||||
*/
|
||||
if (!TEST_int_eq(fake_rsa_query_operation_name, 0))
|
||||
goto end;
|
||||
|
||||
if (!TEST_ptr(params = fake_rsa_key_params(0))
|
||||
|| !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA",
|
||||
"provider=fake-rsa"))
|
||||
|| !TEST_true(EVP_PKEY_fromdata_init(ctx))
|
||||
|| !TEST_true(EVP_PKEY_fromdata(ctx, &pkey_fake, EVP_PKEY_PUBLIC_KEY,
|
||||
params))
|
||||
|| !TEST_true(EVP_PKEY_can_sign(pkey_fake))
|
||||
|| !TEST_ptr(pkey_fake))
|
||||
goto end;
|
||||
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
EVP_PKEY_free(pkey_fake);
|
||||
pkey_fake = NULL;
|
||||
OSSL_PARAM_free(params);
|
||||
params = NULL;
|
||||
|
||||
/*
|
||||
* Documented behavior for OSSL_FUNC_keymgmt_query_operation_name()
|
||||
* allows it to return NULL, in which case the fallback should be to use
|
||||
* EVP_KEYMGMT_get0_name(). That is exactly the thing we are testing here.
|
||||
*/
|
||||
fake_rsa_query_operation_name = 1;
|
||||
|
||||
if (!TEST_ptr(params = fake_rsa_key_params(0))
|
||||
|| !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA",
|
||||
"provider=fake-rsa"))
|
||||
|| !TEST_true(EVP_PKEY_fromdata_init(ctx))
|
||||
|| !TEST_true(EVP_PKEY_fromdata(ctx, &pkey_fake, EVP_PKEY_PUBLIC_KEY,
|
||||
params))
|
||||
|| !TEST_true(EVP_PKEY_can_sign(pkey_fake))
|
||||
|| !TEST_ptr(pkey_fake))
|
||||
goto end;
|
||||
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
EVP_PKEY_free(pkey_fake);
|
||||
pkey_fake = NULL;
|
||||
OSSL_PARAM_free(params);
|
||||
params = NULL;
|
||||
|
||||
ret = 1;
|
||||
end:
|
||||
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
EVP_PKEY_free(pkey_fake);
|
||||
OSSL_PARAM_free(params);
|
||||
fake_rsa_query_operation_name = 0;
|
||||
|
||||
fake_rsa_finish(fake_rsa);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_pkey_store(int idx)
|
||||
{
|
||||
OSSL_PROVIDER *deflt = NULL;
|
||||
|
@ -719,6 +790,7 @@ int setup_tests(void)
|
|||
ADD_TEST(test_pkey_sig);
|
||||
ADD_TEST(test_alternative_keygen_init);
|
||||
ADD_TEST(test_pkey_eq);
|
||||
ADD_TEST(test_pkey_can_sign);
|
||||
ADD_ALL_TESTS(test_pkey_store, 2);
|
||||
ADD_TEST(test_pkey_delete);
|
||||
ADD_TEST(test_pkey_store_open_ex);
|
||||
|
|
Loading…
Reference in New Issue