From f9e504e8b1d4da4b8c9c16ee4c11e9815a800422 Mon Sep 17 00:00:00 2001 From: Pauli Date: Fri, 12 Jun 2020 10:34:46 +1000 Subject: property: Move global default properties to the library context. Fixes a problem where global properties don't work with a NULL query. Specifying an algorithm with a NULL query ignores the default properties. Reviewed-by: Tomas Mraz Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/12123) --- crypto/err/openssl.txt | 1 + crypto/evp/evp_err.c | 2 + crypto/evp/evp_fetch.c | 54 ++++++++++---- crypto/property/property.c | 148 ++++++++++++++------------------------- crypto/property/property_local.h | 2 - 5 files changed, 97 insertions(+), 110 deletions(-) (limited to 'crypto') diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index c308036003..e5df6bc092 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2522,6 +2522,7 @@ EVP_R_CTRL_NOT_IMPLEMENTED:132:ctrl not implemented EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED:133:ctrl operation not implemented EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:138:data not multiple of block length EVP_R_DECODE_ERROR:114:decode error +EVP_R_DEFAULT_QUERY_PARSE_ERROR:210:default query parse error EVP_R_DIFFERENT_KEY_TYPES:101:different key types EVP_R_DIFFERENT_PARAMETERS:153:different parameters EVP_R_ERROR_LOADING_SECTION:165:error loading section diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 0908b1ca16..3dba7f2931 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -44,6 +44,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH), "data not multiple of block length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DECODE_ERROR), "decode error"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DEFAULT_QUERY_PARSE_ERROR), + "default query parse error"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_KEY_TYPES), "different key types"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS), diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index 596f592535..f63e135d3a 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -361,33 +361,63 @@ void *evp_generic_fetch_by_number(OPENSSL_CTX *libctx, int operation_id, return ret; } -int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq) +static int evp_set_default_properties(OPENSSL_CTX *libctx, + OSSL_PROPERTY_LIST *def_prop) { OSSL_METHOD_STORE *store = get_evp_method_store(libctx); - - if (store != NULL) - return ossl_method_store_set_global_properties(store, propq); + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx); + + if (plp != NULL) { + ossl_property_free(*plp); + *plp = def_prop; + if (store != NULL) + ossl_method_store_flush_cache(store); + return 1; + } EVPerr(0, ERR_R_INTERNAL_ERROR); return 0; } +int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq) +{ + OSSL_PROPERTY_LIST *pl = NULL; + + if (propq != NULL && (pl = ossl_parse_query(libctx, propq)) == NULL) { + EVPerr(0, EVP_R_DEFAULT_QUERY_PARSE_ERROR); + return 0; + } + return evp_set_default_properties(libctx, pl); +} + static int evp_default_properties_merge(OPENSSL_CTX *libctx, const char *propq) { - OSSL_METHOD_STORE *store = get_evp_method_store(libctx); - - if (store != NULL) - return ossl_method_store_merge_global_properties(store, propq); - EVPerr(0, ERR_R_INTERNAL_ERROR); - return 0; + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx); + OSSL_PROPERTY_LIST *pl1, *pl2; + + if (propq == NULL) + return 1; + if (plp == NULL || *plp == NULL) + return EVP_set_default_properties(libctx, propq); + if ((pl1 = ossl_parse_query(libctx, propq)) == NULL) { + EVPerr(0, EVP_R_DEFAULT_QUERY_PARSE_ERROR); + return 0; + } + pl2 = ossl_property_merge(pl1, *plp); + ossl_property_free(pl1); + if (pl2 == NULL) { + EVPerr(0, ERR_R_MALLOC_FAILURE); + return 0; + } + return evp_set_default_properties(libctx, pl2); } static int evp_default_property_is_enabled(OPENSSL_CTX *libctx, const char *prop_name) { - OSSL_METHOD_STORE *store = get_evp_method_store(libctx); + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx); - return ossl_method_store_global_property_is_enabled(store, prop_name); + return plp != NULL && ossl_property_is_enabled(libctx, prop_name, *plp); } int EVP_default_properties_is_fips_enabled(OPENSSL_CTX *libctx) diff --git a/crypto/property/property.c b/crypto/property/property.c index ef39057c54..a72ccb02b4 100644 --- a/crypto/property/property.c +++ b/crypto/property/property.c @@ -60,7 +60,6 @@ struct ossl_method_store_st { OPENSSL_CTX *ctx; size_t nelem; SPARSE_ARRAY_OF(ALGORITHM) *algs; - OSSL_PROPERTY_LIST *global_properties; int need_flush; CRYPTO_RWLOCK *lock; }; @@ -74,7 +73,34 @@ typedef struct { DEFINE_SPARSE_ARRAY_OF(ALGORITHM); static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid); -static void ossl_method_cache_flush_all(OSSL_METHOD_STORE *c); + +/* Global properties are stored per library context */ +static void ossl_ctx_global_properties_free(void *vstore) +{ + OSSL_PROPERTY_LIST **plp = vstore; + + if (plp != NULL) { + ossl_property_free(*plp); + OPENSSL_free(plp); + } +} + +static void *ossl_ctx_global_properties_new(OPENSSL_CTX *ctx) +{ + return OPENSSL_zalloc(sizeof(OSSL_PROPERTY_LIST **)); +} + + +static const OPENSSL_CTX_METHOD ossl_ctx_global_properties_method = { + ossl_ctx_global_properties_new, + ossl_ctx_global_properties_free, +}; + +OSSL_PROPERTY_LIST **ossl_ctx_global_properties(OPENSSL_CTX *libctx) +{ + return openssl_ctx_get_data(libctx, OPENSSL_CTX_GLOBAL_PROPERTIES, + &ossl_ctx_global_properties_method); +} static int ossl_method_up_ref(METHOD *method) { @@ -166,7 +192,6 @@ void ossl_method_store_free(OSSL_METHOD_STORE *store) if (store != NULL) { ossl_sa_ALGORITHM_doall(store->algs, &alg_cleanup); ossl_sa_ALGORITHM_free(store->algs); - ossl_property_free(store->global_properties); CRYPTO_THREAD_lock_free(store->lock); OPENSSL_free(store); } @@ -296,11 +321,13 @@ int ossl_method_store_remove(OSSL_METHOD_STORE *store, int nid, } int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, - const char *prop_query, void **method) + const char *prop_query, + void **method) { + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(store->ctx); ALGORITHM *alg; IMPLEMENTATION *impl; - OSSL_PROPERTY_LIST *pq = NULL, *p2; + OSSL_PROPERTY_LIST *pq = NULL, *p2 = NULL; METHOD *best_method = NULL; int ret = 0; int j, best = -1, score, optional; @@ -323,23 +350,28 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, return 0; } - if (prop_query == NULL) { + if (prop_query != NULL) { + p2 = pq = ossl_parse_query(store->ctx, prop_query); + } + if (plp != NULL && *plp != NULL) { + if (pq == NULL) { + pq = *plp; + } else { + p2 = ossl_property_merge(pq, *plp); + if (p2 == NULL) + goto fin; + ossl_property_free(pq); + pq = p2; + } + } + + if (pq == NULL) { if ((impl = sk_IMPLEMENTATION_value(alg->impls, 0)) != NULL) { best_method = &impl->method; ret = 1; } goto fin; } - pq = ossl_parse_query(store->ctx, prop_query); - if (pq == NULL) - goto fin; - if (store->global_properties != NULL) { - p2 = ossl_property_merge(pq, store->global_properties); - if (p2 == NULL) - goto fin; - ossl_property_free(pq); - pq = p2; - } optional = ossl_property_has_optional(pq); for (j = 0; j < sk_IMPLEMENTATION_num(alg->impls); j++) { impl = sk_IMPLEMENTATION_value(alg->impls, j); @@ -358,88 +390,10 @@ fin: else ret = 0; ossl_property_unlock(store); - ossl_property_free(pq); - return ret; -} - -int ossl_method_store_global_property_is_enabled(OSSL_METHOD_STORE *store, - const char *prop_name) -{ - int ret = 0; - - if (store == NULL) - return 0; - - ossl_property_read_lock(store); - ret = ossl_property_is_enabled(store->ctx, prop_name, - store->global_properties); - ossl_property_unlock(store); - return ret; -} - -int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store, - const char *prop_query) -{ - int ret = 0; - - if (store == NULL) - return 1; - - ossl_property_write_lock(store); - ossl_method_cache_flush_all(store); - - ossl_property_free(store->global_properties); - store->global_properties = NULL; - - if (prop_query == NULL) { - ossl_property_unlock(store); - return 1; - } - store->global_properties = ossl_parse_query(store->ctx, prop_query); - ret = store->global_properties != NULL; - ossl_property_unlock(store); - return ret; -} - -int ossl_method_store_merge_global_properties(OSSL_METHOD_STORE *store, - const char *prop_query) -{ - int ret = 0; - OSSL_PROPERTY_LIST *prop = NULL, *global; - - if (store == NULL) - return 1; - - ossl_property_write_lock(store); - ossl_method_cache_flush_all(store); - if (prop_query == NULL) { - ossl_property_free(store->global_properties); - store->global_properties = NULL; - goto success; - } - prop = ossl_parse_query(store->ctx, prop_query); - if (prop == NULL) - goto end; - - if (store->global_properties == NULL) { - store->global_properties = prop; - prop = NULL; - goto success; - } - global = ossl_property_merge(prop, store->global_properties); - if (global == NULL) - goto end; - ossl_property_free(store->global_properties); - store->global_properties = global; - success: - ret = 1; - end: - ossl_property_unlock(store); - ossl_property_free(prop); + ossl_property_free(p2); return ret; } - static void impl_cache_flush_alg(ossl_uintmax_t idx, ALGORITHM *alg) { lh_QUERY_doall(alg->cache, &impl_cache_free); @@ -456,10 +410,12 @@ static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid) } } -static void ossl_method_cache_flush_all(OSSL_METHOD_STORE *store) +void ossl_method_store_flush_cache(OSSL_METHOD_STORE *store) { + ossl_property_write_lock(store); ossl_sa_ALGORITHM_doall(store->algs, &impl_cache_flush_alg); store->nelem = 0; + ossl_property_unlock(store); } IMPLEMENT_LHASH_DOALL_ARG(QUERY, IMPL_CACHE_FLUSH); diff --git a/crypto/property/property_local.h b/crypto/property/property_local.h index 950a0c6c07..2b5a1e663e 100644 --- a/crypto/property/property_local.h +++ b/crypto/property/property_local.h @@ -22,8 +22,6 @@ OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s, /* Property list functions */ void ossl_property_free(OSSL_PROPERTY_LIST *p); int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query); -OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a, - const OSSL_PROPERTY_LIST *b); /* Property definition cache functions */ OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop); -- cgit v1.2.3