mirror of
https://github.com/openssl/openssl.git
synced 2025-04-06 20:20:50 +08:00
Modify EVP_CIPHER_is_a() and EVP_MD_is_a() to handle legacy methods too
These functions would only handle provided methods, but there are cases where the caller just passes along a received method without knowing the underlying method tech, so might pass along a legacy method. We therefore need to have them handle this case as well so they don't cause any unnecessary surprises. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/10845)
This commit is contained in:
parent
9bb3e5fd87
commit
e4a1d02300
@ -294,7 +294,7 @@ int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number,
|
||||
if (number == 0) {
|
||||
number = this_number;
|
||||
} else if (this_number != number) {
|
||||
ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR,
|
||||
ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
|
||||
"Got number %d when expecting %d",
|
||||
this_number, number);
|
||||
return 0;
|
||||
|
@ -381,11 +381,17 @@ const char *evp_first_name(OSSL_PROVIDER *prov, int name_id)
|
||||
return ossl_namemap_num2name(namemap, name_id, 0);
|
||||
}
|
||||
|
||||
int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name)
|
||||
int evp_is_a(OSSL_PROVIDER *prov, int number,
|
||||
const char *legacy_name, const char *name)
|
||||
{
|
||||
/*
|
||||
* For a |prov| that is NULL, the library context will be NULL
|
||||
*/
|
||||
OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
|
||||
if (prov == NULL)
|
||||
number = ossl_namemap_name2num(namemap, legacy_name);
|
||||
return ossl_namemap_name2num(namemap, name) == number;
|
||||
}
|
||||
|
||||
|
@ -532,14 +532,9 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
|
||||
|
||||
int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name)
|
||||
{
|
||||
#ifndef FIPS_MODE
|
||||
if (cipher->prov == NULL) {
|
||||
int nid = EVP_CIPHER_nid(cipher);
|
||||
|
||||
return nid == OBJ_sn2nid(name) || nid == OBJ_ln2nid(name);
|
||||
}
|
||||
#endif
|
||||
return evp_is_a(cipher->prov, cipher->name_id, name);
|
||||
if (cipher->prov != NULL)
|
||||
return evp_is_a(cipher->prov, cipher->name_id, NULL, name);
|
||||
return evp_is_a(NULL, 0, EVP_CIPHER_name(cipher), name);
|
||||
}
|
||||
|
||||
int EVP_CIPHER_number(const EVP_CIPHER *cipher)
|
||||
@ -578,7 +573,9 @@ int EVP_CIPHER_mode(const EVP_CIPHER *cipher)
|
||||
|
||||
int EVP_MD_is_a(const EVP_MD *md, const char *name)
|
||||
{
|
||||
return evp_is_a(md->prov, md->name_id, name);
|
||||
if (md->prov != NULL)
|
||||
return evp_is_a(md->prov, md->name_id, NULL, name);
|
||||
return evp_is_a(NULL, 0, EVP_MD_name(md), name);
|
||||
}
|
||||
|
||||
int EVP_MD_number(const EVP_MD *md)
|
||||
|
@ -270,7 +270,8 @@ void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx);
|
||||
|
||||
/* OSSL_PROVIDER * is only used to get the library context */
|
||||
const char *evp_first_name(OSSL_PROVIDER *prov, int name_id);
|
||||
int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name);
|
||||
int evp_is_a(OSSL_PROVIDER *prov, int number,
|
||||
const char *legacy_name, const char *name);
|
||||
void evp_names_do_all(OSSL_PROVIDER *prov, int number,
|
||||
void (*fn)(const char *name, void *data),
|
||||
void *data);
|
||||
|
@ -380,7 +380,7 @@ int EVP_KEYEXCH_number(const EVP_KEYEXCH *keyexch)
|
||||
|
||||
int EVP_KEYEXCH_is_a(const EVP_KEYEXCH *keyexch, const char *name)
|
||||
{
|
||||
return evp_is_a(keyexch->prov, keyexch->name_id, name);
|
||||
return evp_is_a(keyexch->prov, keyexch->name_id, NULL, name);
|
||||
}
|
||||
|
||||
void EVP_KEYEXCH_do_all_provided(OPENSSL_CTX *libctx,
|
||||
|
@ -90,7 +90,7 @@ int EVP_KDF_number(const EVP_KDF *kdf)
|
||||
|
||||
int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name)
|
||||
{
|
||||
return evp_is_a(kdf->prov, kdf->name_id, name);
|
||||
return evp_is_a(kdf->prov, kdf->name_id, NULL, name);
|
||||
}
|
||||
|
||||
const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf)
|
||||
|
@ -212,7 +212,7 @@ int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt)
|
||||
|
||||
int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name)
|
||||
{
|
||||
return evp_is_a(keymgmt->prov, keymgmt->name_id, name);
|
||||
return evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name);
|
||||
}
|
||||
|
||||
void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx,
|
||||
|
@ -165,7 +165,7 @@ int EVP_MAC_number(const EVP_MAC *mac)
|
||||
|
||||
int EVP_MAC_is_a(const EVP_MAC *mac, const char *name)
|
||||
{
|
||||
return evp_is_a(mac->prov, mac->name_id, name);
|
||||
return evp_is_a(mac->prov, mac->name_id, NULL, name);
|
||||
}
|
||||
|
||||
void EVP_MAC_names_do_all(const EVP_MAC *mac,
|
||||
|
@ -393,7 +393,7 @@ EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
|
||||
int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name)
|
||||
{
|
||||
return evp_is_a(cipher->prov, cipher->name_id, name);
|
||||
return evp_is_a(cipher->prov, cipher->name_id, NULL, name);
|
||||
}
|
||||
|
||||
int EVP_ASYM_CIPHER_number(const EVP_ASYM_CIPHER *cipher)
|
||||
|
@ -289,7 +289,7 @@ EVP_SIGNATURE *EVP_SIGNATURE_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
|
||||
int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name)
|
||||
{
|
||||
return evp_is_a(signature->prov, signature->name_id, name);
|
||||
return evp_is_a(signature->prov, signature->name_id, NULL, name);
|
||||
}
|
||||
|
||||
int EVP_SIGNATURE_number(const EVP_SIGNATURE *signature)
|
||||
|
@ -248,6 +248,11 @@ be initialized.
|
||||
Returns 1 if I<md> is an implementation of an algorithm that's
|
||||
identifiable with I<name>, otherwise 0.
|
||||
|
||||
If I<md> is a legacy digest (it's the return value from the likes of
|
||||
EVP_sha256() rather than the result of an EVP_MD_fetch()), only cipher
|
||||
names registered with the default library context (see
|
||||
L<OPENSSL_CTX(3)>) will be considered.
|
||||
|
||||
=item EVP_MD_number()
|
||||
|
||||
Returns the internal dynamic number assigned to the I<md>. This is
|
||||
|
@ -338,6 +338,10 @@ B<NID_undef>.
|
||||
|
||||
EVP_CIPHER_is_a() returns 1 if I<cipher> is an implementation of an
|
||||
algorithm that's identifiable with I<name>, otherwise 0.
|
||||
If I<cipher> is a legacy cipher (it's the return value from the likes
|
||||
of EVP_aes128() rather than the result of an EVP_CIPHER_fetch()), only
|
||||
cipher names registered with the default library context (see
|
||||
L<OPENSSL_CTX(3)>) will be considered.
|
||||
|
||||
EVP_CIPHER_number() returns the internal dynamic number assigned to
|
||||
the I<cipher>. This is only useful with fetched B<EVP_CIPHER>s.
|
||||
|
@ -108,6 +108,49 @@ static int test_cipherbyname(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that EVP_CIPHER_is_a() responds appropriately, even for ciphers that
|
||||
* are entirely legacy.
|
||||
*/
|
||||
static int test_cipher_is_a(void)
|
||||
{
|
||||
EVP_CIPHER *fetched = EVP_CIPHER_fetch(NULL, "AES-256-CCM", NULL);
|
||||
int rv = 1;
|
||||
|
||||
if (!TEST_ptr_ne(fetched, NULL))
|
||||
return 0;
|
||||
if (!TEST_true(EVP_CIPHER_is_a(fetched, "id-aes256-CCM"))
|
||||
|| !TEST_false(EVP_CIPHER_is_a(fetched, "AES-128-GCM")))
|
||||
rv = 0;
|
||||
if (!TEST_true(EVP_CIPHER_is_a(EVP_aes_256_gcm(), "AES-256-GCM"))
|
||||
|| !TEST_false(EVP_CIPHER_is_a(EVP_aes_256_gcm(), "AES-128-CCM")))
|
||||
rv = 0;
|
||||
|
||||
EVP_CIPHER_free(fetched);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that EVP_MD_is_a() responds appropriately, even for MDs that are
|
||||
* entirely legacy.
|
||||
*/
|
||||
static int test_digest_is_a(void)
|
||||
{
|
||||
EVP_MD *fetched = EVP_MD_fetch(NULL, "SHA2-512", NULL);
|
||||
int rv = 1;
|
||||
|
||||
if (!TEST_ptr_ne(fetched, NULL))
|
||||
return 0;
|
||||
if (!TEST_true(EVP_MD_is_a(fetched, "SHA512"))
|
||||
|| !TEST_false(EVP_MD_is_a(fetched, "SHA1")))
|
||||
rv = 0;
|
||||
if (!TEST_true(EVP_MD_is_a(EVP_sha256(), "SHA2-256"))
|
||||
|| !TEST_false(EVP_MD_is_a(EVP_sha256(), "SHA3-256")))
|
||||
rv = 0;
|
||||
|
||||
EVP_MD_free(fetched);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int setup_tests(void)
|
||||
{
|
||||
@ -115,5 +158,7 @@ int setup_tests(void)
|
||||
ADD_TEST(test_namemap_stored);
|
||||
ADD_TEST(test_digestbyname);
|
||||
ADD_TEST(test_cipherbyname);
|
||||
ADD_TEST(test_digest_is_a);
|
||||
ADD_TEST(test_cipher_is_a);
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user