diff options
Diffstat (limited to 'crypto/core_namemap.c')
-rw-r--r-- | crypto/core_namemap.c | 141 |
1 files changed, 71 insertions, 70 deletions
diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c index 5155a22134..31dc933af1 100644 --- a/crypto/core_namemap.c +++ b/crypto/core_namemap.c @@ -9,43 +9,48 @@ #include "internal/namemap.h" #include <openssl/lhash.h> -#include <openssl/safestack.h> -/* The namemap entry */ +/*- + * The namenum entry + * ================= + */ typedef struct { + char *name; int number; - const char *name; - char body[1]; /* Sized appropriately to contain the name */ -} NAMEMAP_ENTRY; +} NAMENUM_ENTRY; -DEFINE_LHASH_OF(NAMEMAP_ENTRY); -DEFINE_STACK_OF(NAMEMAP_ENTRY) +DEFINE_LHASH_OF(NAMENUM_ENTRY); -/* The namemap, which provides for bidirectional indexing */ +/*- + * The namemap itself + * ================== + */ struct ossl_namemap_st { /* Flags */ unsigned int stored:1; /* If 1, it's stored in a library context */ CRYPTO_RWLOCK *lock; - LHASH_OF(NAMEMAP_ENTRY) *namenum; /* Name->number mapping */ - STACK_OF(NAMEMAP_ENTRY) *numname; /* Number->name mapping */ + LHASH_OF(NAMENUM_ENTRY) *namenum; /* Name->number mapping */ + int max_number; /* Current max number */ }; /* LHASH callbacks */ -static unsigned long namemap_hash(const NAMEMAP_ENTRY *n) +static unsigned long namenum_hash(const NAMENUM_ENTRY *n) { return OPENSSL_LH_strhash(n->name); } -static int namemap_cmp(const NAMEMAP_ENTRY *a, const NAMEMAP_ENTRY *b) +static int namenum_cmp(const NAMENUM_ENTRY *a, const NAMENUM_ENTRY *b) { return strcmp(a->name, b->name); } -static void namemap_free(NAMEMAP_ENTRY *n) +static void namenum_free(NAMENUM_ENTRY *n) { + if (n != NULL) + OPENSSL_free(n->name); OPENSSL_free(n); } @@ -75,7 +80,10 @@ static const OPENSSL_CTX_METHOD stored_namemap_method = { stored_namemap_free, }; -/* API functions */ +/*- + * API functions + * ============= + */ OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx) { @@ -89,11 +97,9 @@ OSSL_NAMEMAP *ossl_namemap_new(void) if ((namemap = OPENSSL_zalloc(sizeof(*namemap))) != NULL && (namemap->lock = CRYPTO_THREAD_lock_new()) != NULL - && (namemap->numname = sk_NAMEMAP_ENTRY_new_null()) != NULL && (namemap->namenum = - lh_NAMEMAP_ENTRY_new(namemap_hash, namemap_cmp)) != NULL) { + lh_NAMENUM_ENTRY_new(namenum_hash, namenum_cmp)) != NULL) return namemap; - } ossl_namemap_free(namemap); return NULL; @@ -104,45 +110,46 @@ void ossl_namemap_free(OSSL_NAMEMAP *namemap) if (namemap == NULL || namemap->stored) return; - /* The elements will be freed by sk_NAMEMAP_ENTRY_pop_free() */ - lh_NAMEMAP_ENTRY_free(namemap->namenum); - - sk_NAMEMAP_ENTRY_pop_free(namemap->numname, namemap_free); + lh_NAMENUM_ENTRY_doall(namemap->namenum, namenum_free); + lh_NAMENUM_ENTRY_free(namemap->namenum); CRYPTO_THREAD_lock_free(namemap->lock); OPENSSL_free(namemap); } -/* - * TODO(3.0) It isn't currently possible to have a default namemap in the - * FIPS module because if init and cleanup constraints, so we currently - * disable the code that would allow it when FIPS_MODE is defined. - */ +typedef struct doall_names_data_st { + int number; + void (*fn)(const char *name, void *data); + void *data; +} DOALL_NAMES_DATA; -const char *ossl_namemap_name(const OSSL_NAMEMAP *namemap, int number) +static void do_name(const NAMENUM_ENTRY *namenum, DOALL_NAMES_DATA *data) { - NAMEMAP_ENTRY *entry; + if (namenum->number == data->number) + data->fn(namenum->name, data->data); +} -#ifndef FIPS_MODE - if (namemap == NULL) - namemap = ossl_namemap_stored(NULL); -#endif +IMPLEMENT_LHASH_DOALL_ARG_CONST(NAMENUM_ENTRY, DOALL_NAMES_DATA); - if (namemap == NULL || number == 0) - return NULL; +void ossl_namemap_doall_names(const OSSL_NAMEMAP *namemap, int number, + void (*fn)(const char *name, void *data), + void *data) +{ + DOALL_NAMES_DATA cbdata; + cbdata.number = number; + cbdata.fn = fn; + cbdata.data = data; CRYPTO_THREAD_read_lock(namemap->lock); - entry = sk_NAMEMAP_ENTRY_value(namemap->numname, number); + lh_NAMENUM_ENTRY_doall_DOALL_NAMES_DATA(namemap->namenum, do_name, + &cbdata); CRYPTO_THREAD_unlock(namemap->lock); - - if (entry != NULL) - return entry->name; - return NULL; } -int ossl_namemap_number(const OSSL_NAMEMAP *namemap, const char *name) +int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name) { - NAMEMAP_ENTRY *entry, template; + NAMENUM_ENTRY *namenum_entry, namenum_tmpl; + int number = 0; #ifndef FIPS_MODE if (namemap == NULL) @@ -152,21 +159,22 @@ int ossl_namemap_number(const OSSL_NAMEMAP *namemap, const char *name) if (namemap == NULL) return 0; - template.name = name; + namenum_tmpl.name = (char *)name; + namenum_tmpl.number = 0; CRYPTO_THREAD_read_lock(namemap->lock); - entry = lh_NAMEMAP_ENTRY_retrieve(namemap->namenum, &template); + namenum_entry = + lh_NAMENUM_ENTRY_retrieve(namemap->namenum, &namenum_tmpl); + if (namenum_entry != NULL) + number = namenum_entry->number; CRYPTO_THREAD_unlock(namemap->lock); - if (entry == NULL) - return 0; - - return entry->number; + return number; } -int ossl_namemap_add(OSSL_NAMEMAP *namemap, const char *name) +int ossl_namemap_add(OSSL_NAMEMAP *namemap, int number, const char *name) { - NAMEMAP_ENTRY *entry; - int number; + NAMENUM_ENTRY *namenum = NULL; + int tmp_number; #ifndef FIPS_MODE if (namemap == NULL) @@ -176,36 +184,29 @@ int ossl_namemap_add(OSSL_NAMEMAP *namemap, const char *name) if (name == NULL || namemap == NULL) return 0; - if ((number = ossl_namemap_number(namemap, name)) != 0) - return number; /* Pretend success */ - - if ((entry = OPENSSL_zalloc(sizeof(*entry) + strlen(name))) == NULL) - goto err; - - strcpy(entry->body, name); - entry->name = entry->body; + if ((tmp_number = ossl_namemap_name2num(namemap, name)) != 0) + return tmp_number; /* Pretend success */ CRYPTO_THREAD_write_lock(namemap->lock); - entry->number = sk_NAMEMAP_ENTRY_push(namemap->numname, entry); - - if (entry->number == 0) + if ((namenum = OPENSSL_zalloc(sizeof(*namenum))) == NULL + || (namenum->name = OPENSSL_strdup(name)) == NULL) goto err; - (void)lh_NAMEMAP_ENTRY_insert(namemap->namenum, entry); - if (lh_NAMEMAP_ENTRY_error(namemap->namenum)) + namenum->number = tmp_number = + number != 0 ? number : ++namemap->max_number; + (void)lh_NAMENUM_ENTRY_insert(namemap->namenum, namenum); + + if (lh_NAMENUM_ENTRY_error(namemap->namenum)) goto err; CRYPTO_THREAD_unlock(namemap->lock); - return entry->number; + return tmp_number; err: - if (entry != NULL) { - if (entry->number != 0) - (void)sk_NAMEMAP_ENTRY_pop(namemap->numname); - lh_NAMEMAP_ENTRY_delete(namemap->namenum, entry); - CRYPTO_THREAD_unlock(namemap->lock); - } + namenum_free(namenum); + + CRYPTO_THREAD_unlock(namemap->lock); return 0; } |