From dc46e3dde58c781b5f29942d787a2c8765ba5514 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 20 Mar 2019 17:51:29 +0000 Subject: [PATCH] Use the right NID when putting a method in the store When we attempt to fetch a method with a given NID we will ask the providers for it if we don't already know about it. During that process we may be told about other methods with a different NID. We need to make sure we don't confuse the two. Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/8541) --- crypto/core_fetch.c | 5 ++-- crypto/evp/digest.c | 9 ++++++- crypto/evp/evp_fetch.c | 27 ++++++++++++++------- crypto/evp/evp_locl.h | 3 ++- doc/internal/man3/evp_generic_fetch.pod | 7 +++++- doc/internal/man3/ossl_method_construct.pod | 7 +++--- include/internal/core.h | 4 +-- 7 files changed, 43 insertions(+), 19 deletions(-) diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c index d38e1325c6..2c4b0d71de 100644 --- a/crypto/core_fetch.c +++ b/crypto/core_fetch.c @@ -35,8 +35,9 @@ static int ossl_method_construct_this(OSSL_PROVIDER *provider, void *cbdata) const OSSL_ALGORITHM *thismap = map++; void *method = NULL; - if ((method = data->mcm->construct(thismap->implementation, provider, - data->mcm_data)) == NULL) + if ((method = data->mcm->construct(thismap->algorithm_name, + thismap->implementation, provider, + data->mcm_data)) == NULL) continue; /* diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index b93a014564..1af8d82658 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -585,10 +585,17 @@ static void evp_md_free(void *md) EVP_MD_meth_free(md); } +static int evp_md_nid(void *vmd) +{ + EVP_MD *md = vmd; + + return md->type; +} + EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm, const char *properties) { return evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties, evp_md_from_dispatch, evp_md_upref, - evp_md_free); + evp_md_free, evp_md_nid); } diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index 329129d133..012383f098 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -62,6 +62,7 @@ struct method_data_st { OSSL_PROVIDER *); int (*refcnt_up_method)(void *method); void (*destruct_method)(void *method); + int (*nid_method)(void *method); }; /* @@ -106,29 +107,35 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store, } static int put_method_in_store(OPENSSL_CTX *libctx, void *store, - const char *propdef, void *method, - void *data) + const char *propdef, + void *method, void *data) { struct method_data_st *methdata = data; + int nid = methdata->nid_method(method); + + if (nid == NID_undef) + return 0; if (store == NULL && (store = get_default_method_store(libctx)) == NULL) return 0; if (methdata->refcnt_up_method(method) - && ossl_method_store_add(store, methdata->nid, propdef, method, + && ossl_method_store_add(store, nid, propdef, method, methdata->destruct_method)) return 1; return 0; } -static void *construct_method(const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov, +static void *construct_method(const char *algorithm_name, + const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov, void *data) { struct method_data_st *methdata = data; void *method = NULL; + int nid = OBJ_sn2nid(algorithm_name); - if (methdata->nid == NID_undef) { + if (nid == NID_undef) { /* Create a new NID for that name on the fly */ ASN1_OBJECT tmpobj; @@ -139,13 +146,13 @@ static void *construct_method(const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov, tmpobj.length = 0; tmpobj.data = NULL; - methdata->nid = OBJ_add_object(&tmpobj); + nid = OBJ_add_object(&tmpobj); } - if (methdata->nid == NID_undef) + if (nid == NID_undef) return NULL; - method = methdata->method_from_dispatch(methdata->nid, fns, prov); + method = methdata->method_from_dispatch(nid, fns, prov); if (method == NULL) return NULL; return method; @@ -163,7 +170,8 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, void *(*new_method)(int nid, const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov), int (*upref_method)(void *), - void (*free_method)(void *)) + void (*free_method)(void *), + int (*nid_method)(void *)) { int nid = OBJ_sn2nid(algorithm); void *method = NULL; @@ -186,6 +194,7 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, mcmdata.destruct_method = free_method; mcmdata.refcnt_up_method = upref_method; mcmdata.destruct_method = free_method; + mcmdata.nid_method = nid_method; method = ossl_method_construct(libctx, operation_id, algorithm, properties, 0 /* !force_cache */, &mcm, &mcmdata); diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index 2453effe1d..efa2db8f75 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -90,4 +90,5 @@ void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id, void *(*new_method)(int nid, const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov), int (*upref_method)(void *), - void (*free_method)(void *)); + void (*free_method)(void *), + int (*nid_method)(void *)); diff --git a/doc/internal/man3/evp_generic_fetch.pod b/doc/internal/man3/evp_generic_fetch.pod index b871cd1fee..881aaf954a 100644 --- a/doc/internal/man3/evp_generic_fetch.pod +++ b/doc/internal/man3/evp_generic_fetch.pod @@ -14,7 +14,8 @@ evp_generic_fetch - generic algorithm fetcher and method creator for EVP void *(*new_method)(int nid, const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov), int (*upref_method)(void *), - void (*free_method)(void *)); + void (*free_method)(void *), + int (*nid_method)(void *)); =head1 DESCRIPTION @@ -41,6 +42,10 @@ one. frees the given method. +=item nid_method() + +returns the nid associated with the given method. + =back =head1 RETURN VALUES diff --git a/doc/internal/man3/ossl_method_construct.pod b/doc/internal/man3/ossl_method_construct.pod index 3664635467..7b682dd085 100644 --- a/doc/internal/man3/ossl_method_construct.pod +++ b/doc/internal/man3/ossl_method_construct.pod @@ -21,8 +21,8 @@ OSSL_METHOD_CONSTRUCT_METHOD, ossl_method_construct int (*put)(OPENSSL_CTX *libctx, void *store, const char *propdef, void *method, void *data); /* Construct a new method */ - void *(*construct)(const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov, - void *data); + void *(*construct)(const char *algorithm_name, const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, void *data); /* Destruct a method */ void (*destruct)(void *method); }; @@ -107,7 +107,8 @@ This function is expected to increment the C's reference count. =item construct() -Constructs a sub-system method given a dispatch table C. +Constructs a sub-system method for the given C and the given +dispatch table C. The associated I C is passed as well, to make it possible for the sub-system constructor to keep a reference, which diff --git a/include/internal/core.h b/include/internal/core.h index b395025ecc..06a0775f85 100644 --- a/include/internal/core.h +++ b/include/internal/core.h @@ -38,8 +38,8 @@ typedef struct ossl_method_construct_method_st { int (*put)(OPENSSL_CTX *libctx, void *store, const char *propdef, void *method, void *data); /* Construct a new method */ - void *(*construct)(const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov, - void *data); + void *(*construct)(const char *algorithm_name, const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov, void *data); /* Destruct a method */ void (*destruct)(void *method, void *data); } OSSL_METHOD_CONSTRUCT_METHOD; -- 2.39.2