CORE: ossl_namemap_add_names(): new function to add multiple names

This was originally the private add_names_to_namemap() in
crypto/evp/evp_fetch.c, but made more generally useful.

To make for more consistent function naming, ossl_namemap_add() and
ossl_namemap_add_n() are renamed to ossl_namemap_add_name() and
ossl_namemap_add_name_n().

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10394)
master
Richard Levitte 3 years ago
parent cc38e643cb
commit 3d83c73536

@ -224,8 +224,8 @@ const char *ossl_namemap_num2name(const OSSL_NAMEMAP *namemap, int number,
return data.name;
}
int ossl_namemap_add_n(OSSL_NAMEMAP *namemap, int number,
const char *name, size_t name_len)
int ossl_namemap_add_name_n(OSSL_NAMEMAP *namemap, int number,
const char *name, size_t name_len)
{
NAMENUM_ENTRY *namenum = NULL;
int tmp_number;
@ -265,10 +265,73 @@ int ossl_namemap_add_n(OSSL_NAMEMAP *namemap, int number,
return 0;
}
int ossl_namemap_add(OSSL_NAMEMAP *namemap, int number, const char *name)
int ossl_namemap_add_name(OSSL_NAMEMAP *namemap, int number, const char *name)
{
if (name == NULL)
return 0;
return ossl_namemap_add_n(namemap, number, name, strlen(name));
return ossl_namemap_add_name_n(namemap, number, name, strlen(name));
}
int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number,
const char *names, const char separator)
{
const char *p, *q;
size_t l;
/* Check that we have a namemap */
if (!ossl_assert(namemap != NULL)) {
ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
/*
* Check that no name is an empty string, and that all names have at
* most one numeric identity together.
*/
for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) {
int this_number;
if ((q = strchr(p, separator)) == NULL)
l = strlen(p); /* offset to \0 */
else
l = q - p; /* offset to the next separator */
this_number = ossl_namemap_name2num_n(namemap, p, l);
if (*p == '\0' || *p == separator) {
ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_BAD_ALGORITHM_NAME);
return 0;
}
if (number == 0) {
number = this_number;
} else if (this_number != 0 && this_number != number) {
ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_CONFLICTING_NAMES,
"\"%.*s\" has an existing different identity %d (from \"%s\")",
l, p, this_number, names);
return 0;
}
}
/* Now that we have checked, register all names */
for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) {
int this_number;
if ((q = strchr(p, separator)) == NULL)
l = strlen(p); /* offset to \0 */
else
l = q - p; /* offset to the next separator */
this_number = ossl_namemap_add_name_n(namemap, number, p, l);
if (number == 0) {
number = this_number;
} else if (this_number != number) {
ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR,
"Got number %d when expecting %d",
this_number, number);
return 0;
}
}
return number;
}

@ -14,6 +14,10 @@
#ifndef OPENSSL_NO_ERR
static const ERR_STRING_DATA CRYPTO_str_reasons[] = {
{ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_BAD_ALGORITHM_NAME),
"bad algorithm name"},
{ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_CONFLICTING_NAMES),
"conflicting names"},
{ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED),
"fips mode not supported"},
{ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ILLEGAL_HEX_DIGIT),

@ -2206,6 +2206,8 @@ CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO:115:\
unsupported method for creating popo
CRMF_R_UNSUPPORTED_POPO_METHOD:116:unsupported popo method
CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED:117:unsupported popo not accepted
CRYPTO_R_BAD_ALGORITHM_NAME:117:bad algorithm name
CRYPTO_R_CONFLICTING_NAMES:118:conflicting names
CRYPTO_R_FIPS_MODE_NOT_SUPPORTED:101:fips mode not supported
CRYPTO_R_ILLEGAL_HEX_DIGIT:102:illegal hex digit
CRYPTO_R_INSUFFICIENT_DATA_SPACE:106:insufficient data space

@ -52,75 +52,12 @@ struct evp_method_data_st {
void (*destruct_method)(void *method);
};
static int add_names_to_namemap(OSSL_NAMEMAP *namemap,
const char *names)
{
const char *p, *q;
size_t l;
int id = 0;
/* Check that we have a namemap and that there is at least one name */
if (namemap == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
/*
* Check that no name is an empty string, and that all names have at
* most one numeric identity together.
*/
for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) {
int this_id;
if ((q = strchr(p, NAME_SEPARATOR)) == NULL)
l = strlen(p); /* offset to \0 */
else
l = q - p; /* offset to the next separator */
this_id = ossl_namemap_name2num_n(namemap, p, l);
if (*p == '\0' || *p == NAME_SEPARATOR) {
ERR_raise(ERR_LIB_EVP, EVP_R_BAD_ALGORITHM_NAME);
return 0;
}
if (id == 0)
id = this_id;
else if (this_id != 0 && this_id != id) {
ERR_raise_data(ERR_LIB_EVP, EVP_R_CONFLICTING_ALGORITHM_NAME,
"\"%.*s\" has an existing different identity %d (from \"%s\")",
l, p, this_id, names);
return 0;
}
}
/* Now that we have checked, register all names */
for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) {
int this_id;
if ((q = strchr(p, NAME_SEPARATOR)) == NULL)
l = strlen(p); /* offset to \0 */
else
l = q - p; /* offset to the next separator */
this_id = ossl_namemap_add_n(namemap, id, p, l);
if (id == 0)
id = this_id;
else if (this_id != id) {
ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR,
"Got id %d when expecting %d", this_id, id);
return 0;
}
}
return id;
}
#ifndef FIPS_MODE
/* Creates an initial namemap with names found in the legacy method db */
static void get_legacy_evp_names(const char *main_name, const char *alias,
void *arg)
{
int main_id = ossl_namemap_add(arg, 0, main_name);
int main_id = ossl_namemap_add_name(arg, 0, main_name);
/*
* We could check that the returned value is the same as main_id,
@ -133,7 +70,7 @@ static void get_legacy_evp_names(const char *main_name, const char *alias,
* simply a no-op.
*/
if (alias != NULL)
(void)ossl_namemap_add(arg, main_id, alias);
(void)ossl_namemap_add_name(arg, main_id, alias);
}
static void get_legacy_cipher_names(const OBJ_NAME *on, void *arg)
@ -303,12 +240,13 @@ static void *construct_evp_method(const char *names, const OSSL_DISPATCH *fns,
* This function is only called if get_evp_method_from_store() returned
* NULL, so it's safe to say that of all the spots to create a new
* namemap entry, this is it. Should the name already exist there, we
* know that ossl_namemap_add() will return its corresponding number.
* know that ossl_namemap_add_name() will return its corresponding
* number.
*/
struct evp_method_data_st *methdata = data;
OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
int name_id = add_names_to_namemap(namemap, names);
int name_id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
if (name_id == 0)
return NULL;
@ -466,7 +404,8 @@ static void do_one(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo,
struct do_all_data_st *data = vdata;
OPENSSL_CTX *libctx = ossl_provider_library_context(provider);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
int name_id = add_names_to_namemap(namemap, algo->algorithm_names);
int name_id = ossl_namemap_add_names(namemap, 0, algo->algorithm_names,
NAME_SEPARATOR);
void *method = NULL;
if (name_id != 0)

@ -3,7 +3,7 @@
=head1 NAME
ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored, ossl_namemap_empty,
ossl_namemap_add, ossl_namemap_add_n,
ossl_namemap_add_name, ossl_namemap_add_name_n, ossl_namemap_add_names,
ossl_namemap_name2num, ossl_namemap_name2num_n,
ossl_namemap_doall_names
- internal number E<lt>-E<gt> name map
@ -18,9 +18,9 @@ ossl_namemap_doall_names
void ossl_namemap_free(OSSL_NAMEMAP *namemap);
int ossl_namemap_empty(OSSL_NAMEMAP *namemap);
int ossl_namemap_add(OSSL_NAMEMAP *namemap, int number, const char *name);
int ossl_namemap_add_n(OSSL_NAMEMAP *namemap, int number,
const char *name, size_t name_len);
int ossl_namemap_add_name(OSSL_NAMEMAP *namemap, int number, const char *name);
int ossl_namemap_add_name_n(OSSL_NAMEMAP *namemap, int number,
const char *name, size_t name_len);
int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name);
int ossl_namemap_name2num_n(const OSSL_NAMEMAP *namemap,
@ -29,6 +29,9 @@ ossl_namemap_doall_names
void (*fn)(const char *name, void *data),
void *data);
int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number,
const char *names, const char separator);
=head1 DESCRIPTION
A B<OSSL_NAMEMAP> is a one-to-many number E<lt>-E<gt> names map, which
@ -49,7 +52,7 @@ given library context.
The returned B<OSSL_NAMEMAP> can't be destructed using
ossl_namemap_free().
ossl_namemap_add() adds a new name to the namemap if it's not already
ossl_namemap_add_name() adds a new name to the namemap if it's not already
present.
If the given I<number> is zero, a new number will be allocated to
identify this I<name>.
@ -59,18 +62,23 @@ names already associated with that number.
ossl_namemap_name2num() finds the number corresponding to the given
I<name>.
ossl_namemap_add_n() and ossl_namemap_name2num_n() do the same thing
as ossl_namemap_add() and ossl_namemap_name2num(), but take a string
ossl_namemap_add_name_n() and ossl_namemap_name2num_n() do the same thing
as ossl_namemap_add_name() and ossl_namemap_name2num(), but take a string
length I<name_len> as well, allowing the caller to use a fragment of
a string as a name.
ossl_namemap_doall_names() walks through all names associated with
I<number> in the given I<namemap> and calls the function I<fn> for
each of them.
I<fn> is also passed the I<data> argument, which allows any caller to
pass extra data for that function to use.
ossl_namemap_add_names() divides up a set of names given in I<names>,
separated by I<separator>, and adds each to the I<namemap>, all with
the same number. If some of them already exist in the I<namemap>,
they must all have the same associated number, which will be adopted
for any name that doesn't exist yet.
=head1 RETURN VALUES
ossl_namemap_new() and ossl_namemap_stored() return the pointer to a
@ -79,8 +87,8 @@ B<OSSL_NAMEMAP>, or NULL on error.
ossl_namemap_empty() returns 1 if the B<OSSL_NAMEMAP> is NULL or
empty, or 0 if it's not empty.
ossl_namemap_add() and ossl_namemap_add_n() return the number associated
with the added string, or zero on error.
ossl_namemap_add_name() and ossl_namemap_add_name_n() return the number
associated with the added string, or zero on error.
ossl_namemap_num2names() returns a pointer to a NULL-terminated list of
pointers to the names corresponding to the given number, or NULL if
@ -90,6 +98,9 @@ ossl_namemap_name2num() and ossl_namemap_name2num_n() return the number
corresponding to the given name, or 0 if it's undefined in the given
B<OSSL_NAMEMAP>.
ossl_namemap_add_names() returns the number associated with the added
names, or zero on error.
=head1 NOTES
The result from ossl_namemap_num2names() isn't thread safe, other threads

@ -17,9 +17,9 @@ OSSL_NAMEMAP *ossl_namemap_new(void);
void ossl_namemap_free(OSSL_NAMEMAP *namemap);
int ossl_namemap_empty(OSSL_NAMEMAP *namemap);
int ossl_namemap_add(OSSL_NAMEMAP *namemap, int number, const char *name);
int ossl_namemap_add_n(OSSL_NAMEMAP *namemap, int number,
const char *name, size_t name_len);
int ossl_namemap_add_name(OSSL_NAMEMAP *namemap, int number, const char *name);
int ossl_namemap_add_name_n(OSSL_NAMEMAP *namemap, int number,
const char *name, size_t name_len);
/*
* The number<->name relationship is 1<->many
@ -34,3 +34,10 @@ const char *ossl_namemap_num2name(const OSSL_NAMEMAP *namemap, int number,
void ossl_namemap_doall_names(const OSSL_NAMEMAP *namemap, int number,
void (*fn)(const char *name, void *data),
void *data);
/*
* A utility that handles several names in a string, divided by a given
* separator.
*/
int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number,
const char *names, const char separator);

@ -83,6 +83,8 @@ int ERR_load_CRYPTO_strings(void);
/*
* CRYPTO reason codes.
*/
# define CRYPTO_R_BAD_ALGORITHM_NAME 117
# define CRYPTO_R_CONFLICTING_NAMES 118
# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101
# define CRYPTO_R_ILLEGAL_HEX_DIGIT 102
# define CRYPTO_R_INSUFFICIENT_DATA_SPACE 106

@ -18,10 +18,10 @@
static int test_namemap(OSSL_NAMEMAP *nm)
{
int num1 = ossl_namemap_add(nm, 0, NAME1);
int num2 = ossl_namemap_add(nm, 0, NAME2);
int num3 = ossl_namemap_add(nm, num1, ALIAS1);
int num4 = ossl_namemap_add(nm, 0, ALIAS1_UC);
int num1 = ossl_namemap_add_name(nm, 0, NAME1);
int num2 = ossl_namemap_add_name(nm, 0, NAME2);
int num3 = ossl_namemap_add_name(nm, num1, ALIAS1);
int num4 = ossl_namemap_add_name(nm, 0, ALIAS1_UC);
int check1 = ossl_namemap_name2num(nm, NAME1);
int check2 = ossl_namemap_name2num(nm, NAME2);
int check3 = ossl_namemap_name2num(nm, ALIAS1);
@ -66,10 +66,10 @@ static int test_digestbyname(void)
OSSL_NAMEMAP *nm = ossl_namemap_stored(NULL);
const EVP_MD *sha256, *foo;
id = ossl_namemap_add(nm, 0, "SHA256");
id = ossl_namemap_add_name(nm, 0, "SHA256");
if (!TEST_int_ne(id, 0))
return 0;
if (!TEST_int_eq(ossl_namemap_add(nm, id, "foo"), id))
if (!TEST_int_eq(ossl_namemap_add_name(nm, id, "foo"), id))
return 0;
sha256 = EVP_get_digestbyname("SHA256");
@ -92,10 +92,10 @@ static int test_cipherbyname(void)
OSSL_NAMEMAP *nm = ossl_namemap_stored(NULL);
const EVP_CIPHER *aes128, *bar;
id = ossl_namemap_add(nm, 0, "AES-128-CBC");
id = ossl_namemap_add_name(nm, 0, "AES-128-CBC");
if (!TEST_int_ne(id, 0))
return 0;
if (!TEST_int_eq(ossl_namemap_add(nm, id, "bar"), id))
if (!TEST_int_eq(ossl_namemap_add_name(nm, id, "bar"), id))
return 0;
aes128 = EVP_get_cipherbyname("AES-128-CBC");

Loading…
Cancel
Save