From 6b9e37246d5fd8e701b825c71fa1a018916af33c Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 10 Jul 2019 22:22:16 +0200 Subject: [PATCH] Add a mechnism to save the name of fetched methods This will be useful for information display, as well as for code that want to check the name of an algorithm. This can eventually replace all NID checks. Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/9356) --- crypto/evp/cmeth_lib.c | 1 + crypto/evp/digest.c | 8 ++++++-- crypto/evp/evp_enc.c | 9 +++++++-- crypto/evp/evp_fetch.c | 8 +++++--- crypto/evp/evp_lib.c | 1 + crypto/evp/evp_locl.h | 6 ++++-- crypto/evp/exchange.c | 10 ++++++++-- crypto/evp/keymgmt_meth.c | 9 +++++++-- crypto/include/internal/evp_int.h | 2 ++ 9 files changed, 41 insertions(+), 13 deletions(-) diff --git a/crypto/evp/cmeth_lib.c b/crypto/evp/cmeth_lib.c index 40aca34e07..51c9b6ece2 100644 --- a/crypto/evp/cmeth_lib.c +++ b/crypto/evp/cmeth_lib.c @@ -55,6 +55,7 @@ void EVP_CIPHER_meth_free(EVP_CIPHER *cipher) if (i > 0) return; ossl_provider_free(cipher->prov); + OPENSSL_free(cipher->name); CRYPTO_THREAD_lock_free(cipher->lock); OPENSSL_free(cipher); } diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 65b12e315a..27f9d128ee 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -577,15 +577,19 @@ int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2) return 0; } -static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns, +static void *evp_md_from_dispatch(const char *name, const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov) { EVP_MD *md = NULL; int fncnt = 0; /* EVP_MD_fetch() will set the legacy NID if available */ - if ((md = EVP_MD_meth_new(NID_undef, NID_undef)) == NULL) + if ((md = EVP_MD_meth_new(NID_undef, NID_undef)) == NULL + || (md->name = OPENSSL_strdup(name)) == NULL) { + EVP_MD_meth_free(md); + EVPerr(0, ERR_R_MALLOC_FAILURE); return NULL; + } for (; fns->function_id != 0; fns++) { switch (fns->function_id) { diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index c1f7e77eb1..bfdd581e0d 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -1127,7 +1127,8 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) return 1; } -static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns, +static void *evp_cipher_from_dispatch(const char *name, + const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov) { EVP_CIPHER *cipher = NULL; @@ -1137,8 +1138,12 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns, * The legacy NID is set by EVP_CIPHER_fetch() if the name exists in * the object database. */ - if ((cipher = EVP_CIPHER_meth_new(0, 0, 0)) == NULL) + if ((cipher = EVP_CIPHER_meth_new(0, 0, 0)) == NULL + || (cipher->name = OPENSSL_strdup(name)) == NULL) { + EVP_CIPHER_meth_free(cipher); + EVPerr(0, ERR_R_MALLOC_FAILURE); return NULL; + } for (; fns->function_id != 0; fns++) { switch (fns->function_id) { diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index 0c25f0d558..82f6e5d970 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -40,7 +40,8 @@ struct method_data_st { OPENSSL_CTX *libctx; const char *name; OSSL_METHOD_CONSTRUCT_METHOD *mcm; - void *(*method_from_dispatch)(const OSSL_DISPATCH *, OSSL_PROVIDER *); + void *(*method_from_dispatch)(const char *, const OSSL_DISPATCH *, + OSSL_PROVIDER *); int (*refcnt_up_method)(void *method); void (*destruct_method)(void *method); }; @@ -143,7 +144,7 @@ static void *construct_method(const char *name, const OSSL_DISPATCH *fns, { struct method_data_st *methdata = data; - return methdata->method_from_dispatch(fns, prov); + return methdata->method_from_dispatch(name, fns, prov); } static void destruct_method(void *method, void *data) @@ -155,7 +156,8 @@ static void destruct_method(void *method, void *data) void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, const char *name, const char *properties, - void *(*new_method)(const OSSL_DISPATCH *fns, + void *(*new_method)(const char *name, + const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov), int (*up_ref_method)(void *), void (*free_method)(void *)) diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 47bbb2bd55..24441ef825 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -513,6 +513,7 @@ void EVP_MD_meth_free(EVP_MD *md) if (i > 0) return; ossl_provider_free(md->prov); + OPENSSL_free(md->name); CRYPTO_THREAD_lock_free(md->lock); OPENSSL_free(md); } diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index 740c159f05..d557e9c633 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -65,7 +65,7 @@ struct evp_kdf_ctx_st { struct evp_keymgmt_st { int id; /* libcrypto internal */ - const char *name; + char *name; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; CRYPTO_RWLOCK *lock; @@ -89,6 +89,7 @@ struct evp_keymgmt_st { } /* EVP_KEYMGMT */ ; struct evp_keyexch_st { + char *name; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; CRYPTO_RWLOCK *lock; @@ -133,7 +134,8 @@ int is_partially_overlapping(const void *ptr1, const void *ptr2, int len); void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id, const char *algorithm, const char *properties, - void *(*new_method)(const OSSL_DISPATCH *fns, + void *(*new_method)(const char *name, + const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov), int (*up_ref_method)(void *), void (*free_method)(void *)); diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index 208bb9885a..d8afcbd633 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -31,14 +31,19 @@ static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov) return exchange; } -static void *evp_keyexch_from_dispatch(const OSSL_DISPATCH *fns, +static void *evp_keyexch_from_dispatch(const char *name, + const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov) { EVP_KEYEXCH *exchange = NULL; int fncnt = 0; - if ((exchange = evp_keyexch_new(prov)) == NULL) + if ((exchange = evp_keyexch_new(prov)) == NULL + || (exchange->name = OPENSSL_strdup(name)) == NULL) { + EVP_KEYEXCH_free(exchange); + EVPerr(0, ERR_R_MALLOC_FAILURE); return NULL; + } for (; fns->function_id != 0; fns++) { switch (fns->function_id) { @@ -108,6 +113,7 @@ void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange) if (i > 0) return; ossl_provider_free(exchange->prov); + OPENSSL_free(exchange->name); CRYPTO_THREAD_lock_free(exchange->lock); OPENSSL_free(exchange); } diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c index 9723820203..67c33eb78b 100644 --- a/crypto/evp/keymgmt_meth.c +++ b/crypto/evp/keymgmt_meth.c @@ -24,6 +24,7 @@ static void *keymgmt_new(void) if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL || (keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) { EVP_KEYMGMT_free(keymgmt); + EVPerr(0, ERR_R_MALLOC_FAILURE); return NULL; } @@ -32,13 +33,16 @@ static void *keymgmt_new(void) return keymgmt; } -static void *keymgmt_from_dispatch(const OSSL_DISPATCH *fns, +static void *keymgmt_from_dispatch(const char *name, const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov) { EVP_KEYMGMT *keymgmt = NULL; - if ((keymgmt = keymgmt_new()) == NULL) + if ((keymgmt = keymgmt_new()) == NULL + || (keymgmt->name = OPENSSL_strdup(name)) == NULL) { + EVP_KEYMGMT_free(keymgmt); return NULL; + } for (; fns->function_id != 0; fns++) { switch (fns->function_id) { @@ -178,6 +182,7 @@ void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt) if (ref > 0) return; ossl_provider_free(keymgmt->prov); + OPENSSL_free(keymgmt->name); CRYPTO_THREAD_lock_free(keymgmt->lock); OPENSSL_free(keymgmt); } diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index 50ed933926..9d878987bc 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -201,6 +201,7 @@ struct evp_md_st { /* New structure members */ /* TODO(3.0): Remove above comment when legacy has gone */ + char *name; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; CRYPTO_RWLOCK *lock; @@ -251,6 +252,7 @@ struct evp_cipher_st { /* New structure members */ /* TODO(3.0): Remove above comment when legacy has gone */ + char *name; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; CRYPTO_RWLOCK *lock; -- 2.25.1