From 1aedc35fd6c2f40f269c88b2f7d5a617172b47c5 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 1 May 2019 11:02:43 +0100 Subject: Instead of global data store it in an OPENSSL_CTX Various core and property related code files used global data. We should store all of that in an OPENSSL_CTX instead. Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/8857) --- crypto/property/defn_cache.c | 41 +++++++++++------ crypto/property/property.c | 50 ++++++++------------ crypto/property/property_lcl.h | 25 ++++------ crypto/property/property_parse.c | 46 ++++++++++--------- crypto/property/property_string.c | 97 +++++++++++++++++++++++++++------------ 5 files changed, 150 insertions(+), 109 deletions(-) (limited to 'crypto/property') diff --git a/crypto/property/defn_cache.c b/crypto/property/defn_cache.c index df87c19f55..aec05c1ae3 100644 --- a/crypto/property/defn_cache.c +++ b/crypto/property/defn_cache.c @@ -29,8 +29,6 @@ typedef struct { DEFINE_LHASH_OF(PROPERTY_DEFN_ELEM); -static LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = NULL; - static unsigned long property_defn_hash(const PROPERTY_DEFN_ELEM *a) { return OPENSSL_LH_strhash(a->prop); @@ -48,35 +46,52 @@ static void property_defn_free(PROPERTY_DEFN_ELEM *elem) OPENSSL_free(elem); } -int ossl_prop_defn_init(void) +static void property_defns_free(void *vproperty_defns) { - property_defns = lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash, - &property_defn_cmp); - return property_defns != NULL; -} + LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = vproperty_defns; -void ossl_prop_defn_cleanup(void) -{ if (property_defns != NULL) { - lh_PROPERTY_DEFN_ELEM_doall(property_defns, &property_defn_free); + lh_PROPERTY_DEFN_ELEM_doall(property_defns, + &property_defn_free); lh_PROPERTY_DEFN_ELEM_free(property_defns); - property_defns = NULL; } } -OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop) +static void *property_defns_new(OPENSSL_CTX *ctx) { + return lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash, &property_defn_cmp); +} + +static const OPENSSL_CTX_METHOD property_defns_method = { + property_defns_new, + property_defns_free, +}; + +OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop) { PROPERTY_DEFN_ELEM elem, *r; + LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns; + + property_defns = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_DEFN_INDEX, + &property_defns_method); + if (property_defns == NULL) + return NULL; elem.prop = prop; r = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem); return r != NULL ? r->defn : NULL; } -int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl) +int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop, + OSSL_PROPERTY_LIST *pl) { PROPERTY_DEFN_ELEM elem, *old, *p = NULL; size_t len; + LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns; + + property_defns = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_DEFN_INDEX, + &property_defns_method); + if (property_defns == NULL) + return 0; if (prop == NULL) return 1; diff --git a/crypto/property/property.c b/crypto/property/property.c index a2122dc1bc..930c89bf48 100644 --- a/crypto/property/property.c +++ b/crypto/property/property.c @@ -47,6 +47,7 @@ typedef struct { } ALGORITHM; struct ossl_method_store_st { + OPENSSL_CTX *ctx; size_t nelem; SPARSE_ARRAY_OF(ALGORITHM) *algs; OSSL_PROPERTY_LIST *global_properties; @@ -82,29 +83,10 @@ int ossl_property_unlock(OSSL_METHOD_STORE *p) return p != 0 ? CRYPTO_THREAD_unlock(p->lock) : 0; } -int ossl_method_store_init(void) +static openssl_ctx_run_once_fn do_method_store_init; +int do_method_store_init(OPENSSL_CTX *ctx) { - if (ossl_property_string_init() - && ossl_prop_defn_init() - && ossl_property_parse_init()) - return 1; - - ossl_method_store_cleanup(); - return 0; -} - -void ossl_method_store_cleanup(void) -{ - ossl_property_string_cleanup(); - ossl_prop_defn_cleanup(); -} - -static CRYPTO_ONCE method_store_init_flag = CRYPTO_ONCE_STATIC_INIT; -DEFINE_RUN_ONCE_STATIC(do_method_store_init) -{ - return OPENSSL_init_crypto(0, NULL) - && ossl_method_store_init() - && OPENSSL_atexit(&ossl_method_store_cleanup); + return ossl_property_parse_init(ctx); } static unsigned long query_hash(const QUERY *a) @@ -141,15 +123,22 @@ static void alg_cleanup(ossl_uintmax_t idx, ALGORITHM *a) } } -OSSL_METHOD_STORE *ossl_method_store_new(void) +/* + * The OPENSSL_CTX param here allows access to underlying property data needed + * for computation + */ +OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx) { OSSL_METHOD_STORE *res; - if (!RUN_ONCE(&method_store_init_flag, do_method_store_init)) - return 0; + if (!openssl_ctx_run_once(ctx, + OPENSSL_CTX_METHOD_STORE_RUN_ONCE_INDEX, + do_method_store_init)) + return NULL; res = OPENSSL_zalloc(sizeof(*res)); if (res != NULL) { + res->ctx = ctx; if ((res->algs = ossl_sa_ALGORITHM_new()) == NULL) { OPENSSL_free(res); return NULL; @@ -212,10 +201,11 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store, */ ossl_property_write_lock(store); ossl_method_cache_flush(store, nid); - if ((impl->properties = ossl_prop_defn_get(properties)) == NULL) { - if ((impl->properties = ossl_parse_property(properties)) == NULL) + if ((impl->properties = ossl_prop_defn_get(store->ctx, properties)) == NULL) { + impl->properties = ossl_parse_property(store->ctx, properties); + if (impl->properties == NULL) goto err; - ossl_prop_defn_set(properties, impl->properties); + ossl_prop_defn_set(store->ctx, properties, impl->properties); } alg = ossl_method_store_retrieve(store, nid); @@ -310,7 +300,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, } goto fin; } - pq = ossl_parse_query(prop_query); + pq = ossl_parse_query(store->ctx, prop_query); if (pq == NULL) goto fin; if (store->global_properties != NULL) { @@ -350,7 +340,7 @@ int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store, ossl_property_unlock(store); return 1; } - store->global_properties = ossl_parse_query(prop_query); + store->global_properties = ossl_parse_query(store->ctx, prop_query); ret = store->global_properties != NULL; ossl_property_unlock(store); return ret; diff --git a/crypto/property/property_lcl.h b/crypto/property/property_lcl.h index faf3fe151c..304dc22ad9 100644 --- a/crypto/property/property_lcl.h +++ b/crypto/property/property_lcl.h @@ -14,18 +14,14 @@ typedef struct ossl_property_list_st OSSL_PROPERTY_LIST; typedef int OSSL_PROPERTY_IDX; -/* Initialisation and finalisation for subsystem */ -int ossl_method_store_init(void); -void ossl_method_store_cleanup(void); - /* Property string functions */ -OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create); -OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create); -int ossl_property_string_init(void); -void ossl_property_string_cleanup(void); +OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s, + int create); +OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s, + int create); /* Property list functions */ -int ossl_property_parse_init(void); +int ossl_property_parse_init(OPENSSL_CTX *ctx); void ossl_property_free(OSSL_PROPERTY_LIST *p); int ossl_property_match(const OSSL_PROPERTY_LIST *query, const OSSL_PROPERTY_LIST *defn); @@ -33,16 +29,15 @@ OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a, const OSSL_PROPERTY_LIST *b); /* Property definition functions */ -OSSL_PROPERTY_LIST *ossl_parse_property(const char *s); +OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *s); /* Property query functions */ -OSSL_PROPERTY_LIST *ossl_parse_query(const char *s); +OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s); /* Property definition cache functions */ -int ossl_prop_defn_init(void); -void ossl_prop_defn_cleanup(void); -OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop); -int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl); +OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop); +int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop, + OSSL_PROPERTY_LIST *pl); /* Property cache lock / unlock */ int ossl_property_write_lock(OSSL_METHOD_STORE *); diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c index faaaee8fb2..efc459a919 100644 --- a/crypto/property/property_parse.c +++ b/crypto/property/property_parse.c @@ -78,7 +78,8 @@ static int match(const char *t[], const char m[], size_t m_len) return 0; } -static int parse_name(const char *t[], int create, OSSL_PROPERTY_IDX *idx) +static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create, + OSSL_PROPERTY_IDX *idx) { char name[100]; int err = 0; @@ -109,7 +110,7 @@ static int parse_name(const char *t[], int create, OSSL_PROPERTY_IDX *idx) name[i] = '\0'; *t = skip_space(s); if (!err) { - *idx = ossl_property_name(name, user_name && create); + *idx = ossl_property_name(ctx, name, user_name && create); return 1; } PROPerr(PROP_F_PARSE_NAME, PROP_R_NAME_TOO_LONG); @@ -180,8 +181,8 @@ static int parse_oct(const char *t[], PROPERTY_DEFINITION *res) return 1; } -static int parse_string(const char *t[], char delim, PROPERTY_DEFINITION *res, - const int create) +static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim, + PROPERTY_DEFINITION *res, const int create) { char v[1000]; const char *s = *t; @@ -205,13 +206,13 @@ static int parse_string(const char *t[], char delim, PROPERTY_DEFINITION *res, if (err) PROPerr(PROP_F_PARSE_STRING, PROP_R_STRING_TOO_LONG); else - res->v.str_val = ossl_property_value(v, create); + res->v.str_val = ossl_property_value(ctx, v, create); res->type = PROPERTY_TYPE_STRING; return !err; } -static int parse_unquoted(const char *t[], PROPERTY_DEFINITION *res, - const int create) +static int parse_unquoted(OPENSSL_CTX *ctx, const char *t[], + PROPERTY_DEFINITION *res, const int create) { char v[1000]; const char *s = *t; @@ -236,19 +237,20 @@ static int parse_unquoted(const char *t[], PROPERTY_DEFINITION *res, if (err) PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_STRING_TOO_LONG); else - res->v.str_val = ossl_property_value(v, create); + res->v.str_val = ossl_property_value(ctx, v, create); res->type = PROPERTY_TYPE_STRING; return !err; } -static int parse_value(const char *t[], PROPERTY_DEFINITION *res, int create) +static int parse_value(OPENSSL_CTX *ctx, const char *t[], + PROPERTY_DEFINITION *res, int create) { const char *s = *t; int r = 0; if (*s == '"' || *s == '\'') { s++; - r = parse_string(&s, s[-1], res, create); + r = parse_string(ctx, &s, s[-1], res, create); } else if (*s == '+') { s++; r = parse_number(&s, res); @@ -265,7 +267,7 @@ static int parse_value(const char *t[], PROPERTY_DEFINITION *res, int create) } else if (ossl_isdigit(*s)) { return parse_number(t, res); } else if (ossl_isalpha(*s)) - return parse_unquoted(t, res, create); + return parse_unquoted(ctx, t, res, create); if (r) *t = s; return r; @@ -312,7 +314,7 @@ static OSSL_PROPERTY_LIST *stack_to_property_list(STACK_OF(PROPERTY_DEFINITION) return r; } -OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn) +OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn) { PROPERTY_DEFINITION *prop = NULL; OSSL_PROPERTY_LIST *res = NULL; @@ -330,7 +332,7 @@ OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn) if (prop == NULL) goto err; memset(&prop->v, 0, sizeof(prop->v)); - if (!parse_name(&s, 1, &prop->name_idx)) + if (!parse_name(ctx, &s, 1, &prop->name_idx)) goto err; prop->oper = PROPERTY_OPER_EQ; if (prop->name_idx == 0) { @@ -338,7 +340,7 @@ OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn) goto err; } if (match_ch(&s, '=')) { - if (!parse_value(&s, prop, 1)) { + if (!parse_value(ctx, &s, prop, 1)) { PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_NO_VALUE); goto err; } @@ -365,7 +367,7 @@ err: return res; } -OSSL_PROPERTY_LIST *ossl_parse_query(const char *s) +OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s) { STACK_OF(PROPERTY_DEFINITION) *sk; OSSL_PROPERTY_LIST *res = NULL; @@ -385,11 +387,11 @@ OSSL_PROPERTY_LIST *ossl_parse_query(const char *s) if (match_ch(&s, '-')) { prop->oper = PROPERTY_OVERRIDE; - if (!parse_name(&s, 0, &prop->name_idx)) + if (!parse_name(ctx, &s, 0, &prop->name_idx)) goto err; goto skip_value; } - if (!parse_name(&s, 0, &prop->name_idx)) + if (!parse_name(ctx, &s, 0, &prop->name_idx)) goto err; if (match_ch(&s, '=')) { @@ -403,7 +405,7 @@ OSSL_PROPERTY_LIST *ossl_parse_query(const char *s) prop->v.str_val = ossl_property_true; goto skip_value; } - if (!parse_value(&s, prop, 0)) + if (!parse_value(ctx, &s, prop, 0)) prop->type = PROPERTY_TYPE_VALUE_UNDEFINED; skip_value: @@ -519,7 +521,7 @@ OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a, return r; } -int ossl_property_parse_init(void) +int ossl_property_parse_init(OPENSSL_CTX *ctx) { static const char *const predefined_names[] = { "default", /* Being provided by the default built-in provider */ @@ -532,12 +534,12 @@ int ossl_property_parse_init(void) size_t i; for (i = 0; i < OSSL_NELEM(predefined_names); i++) - if (ossl_property_name(predefined_names[i], 1) == 0) + if (ossl_property_name(ctx, predefined_names[i], 1) == 0) goto err; /* Pre-populate the two Boolean values */ - if ((ossl_property_true = ossl_property_value("yes", 1)) == 0 - || (ossl_property_false = ossl_property_value("no", 1)) == 0) + if ((ossl_property_true = ossl_property_value(ctx, "yes", 1)) == 0 + || (ossl_property_false = ossl_property_value(ctx, "no", 1)) == 0) goto err; return 1; diff --git a/crypto/property/property_string.c b/crypto/property/property_string.c index 7f6e30effb..dcf5dcc2a4 100644 --- a/crypto/property/property_string.c +++ b/crypto/property/property_string.c @@ -34,10 +34,12 @@ typedef struct { DEFINE_LHASH_OF(PROPERTY_STRING); typedef LHASH_OF(PROPERTY_STRING) PROP_TABLE; -static PROP_TABLE *prop_names; -static PROP_TABLE *prop_values; -static OSSL_PROPERTY_IDX prop_name_idx = 0; -static OSSL_PROPERTY_IDX prop_value_idx = 0; +typedef struct { + PROP_TABLE *prop_names; + PROP_TABLE *prop_values; + OSSL_PROPERTY_IDX prop_name_idx; + OSSL_PROPERTY_IDX prop_value_idx; +} PROPERTY_STRING_DATA; static unsigned long property_hash(const PROPERTY_STRING *a) { @@ -65,6 +67,48 @@ static void property_table_free(PROP_TABLE **pt) } } +static void property_string_data_free(void *vpropdata) +{ + PROPERTY_STRING_DATA *propdata = vpropdata; + + if (propdata == NULL) + return; + + property_table_free(&propdata->prop_names); + property_table_free(&propdata->prop_values); + propdata->prop_name_idx = propdata->prop_value_idx = 0; + + OPENSSL_free(propdata); +} + +static void *property_string_data_new(OPENSSL_CTX *ctx) { + PROPERTY_STRING_DATA *propdata = OPENSSL_zalloc(sizeof(*propdata)); + + if (propdata == NULL) + return NULL; + + propdata->prop_names = lh_PROPERTY_STRING_new(&property_hash, + &property_cmp); + if (propdata->prop_names == NULL) + goto err; + + propdata->prop_values = lh_PROPERTY_STRING_new(&property_hash, + &property_cmp); + if (propdata->prop_values == NULL) + goto err; + + return propdata; + +err: + property_string_data_free(propdata); + return NULL; +} + +static const OPENSSL_CTX_METHOD property_string_data_method = { + property_string_data_new, + property_string_data_free, +}; + static PROPERTY_STRING *new_property_string(const char *s, OSSL_PROPERTY_IDX *pidx) { @@ -103,35 +147,30 @@ static OSSL_PROPERTY_IDX ossl_property_string(PROP_TABLE *t, return ps != NULL ? ps->idx : 0; } -OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create) +OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s, + int create) { - return ossl_property_string(prop_names, create ? &prop_name_idx : NULL, s); -} - -OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create) -{ - return ossl_property_string(prop_values, create ? &prop_value_idx : NULL, s); -} + PROPERTY_STRING_DATA *propdata + = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_STRING_INDEX, + &property_string_data_method); -int ossl_property_string_init(void) -{ - prop_names = lh_PROPERTY_STRING_new(&property_hash, &property_cmp); - if (prop_names == NULL) + if (propdata == NULL) return 0; - - prop_values = lh_PROPERTY_STRING_new(&property_hash, &property_cmp); - if (prop_values == NULL) - goto err; - return 1; - -err: - ossl_property_string_cleanup(); - return 0; + return ossl_property_string(propdata->prop_names, + create ? &propdata->prop_name_idx : NULL, + s); } -void ossl_property_string_cleanup(void) +OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s, + int create) { - property_table_free(&prop_names); - property_table_free(&prop_values); - prop_name_idx = prop_value_idx = 0; + PROPERTY_STRING_DATA *propdata + = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_STRING_INDEX, + &property_string_data_method); + + if (propdata == NULL) + return 0; + return ossl_property_string(propdata->prop_values, + create ? &propdata->prop_value_idx : NULL, + s); } -- cgit v1.2.3