From eaf8a40d97d642ccd2c55fbf8bb8ee3242aec04a Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 26 Apr 2021 12:08:27 +0200 Subject: Prefer fetch over legacy get_digestby/get_cipherby Fixes #14198 Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/15028) --- apps/include/opt.h | 2 ++ apps/lib/opt.c | 53 +++++++++++++++++++++++---------- apps/req.c | 11 +++---- apps/speed.c | 86 +++++++++++++----------------------------------------- 4 files changed, 65 insertions(+), 87 deletions(-) (limited to 'apps') diff --git a/apps/include/opt.h b/apps/include/opt.h index c8024975b2..f9ac5accae 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -368,7 +368,9 @@ int opt_umax(const char *arg, uintmax_t *result); int opt_pair(const char *arg, const OPT_PAIR * pairs, int *result); int opt_string(const char *name, const char **options); int opt_cipher(const char *name, EVP_CIPHER **cipherp); +int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp); int opt_md(const char *name, EVP_MD **mdp); +int opt_md_silent(const char *name, EVP_MD **mdp); char *opt_name(void); char *opt_arg(void); char *opt_flag(void); diff --git a/apps/lib/opt.c b/apps/lib/opt.c index 0c7405a921..83ae28cdc1 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -359,34 +360,56 @@ void print_format_error(int format, unsigned long flags) } /* Parse a cipher name, put it in *EVP_CIPHER; return 0 on failure, else 1. */ -int opt_cipher(const char *name, EVP_CIPHER **cipherp) +int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp) { - *cipherp = EVP_CIPHER_fetch(NULL, name, NULL); - if (*cipherp != NULL) - return 1; - *cipherp = (EVP_CIPHER *)EVP_get_cipherbyname(name); - if (*cipherp != NULL) + EVP_CIPHER_free(*cipherp); + + ERR_set_mark(); + if ((*cipherp = EVP_CIPHER_fetch(NULL, name, NULL)) != NULL + || (*cipherp = (EVP_CIPHER *)EVP_get_cipherbyname(name)) != NULL) { + ERR_pop_to_mark(); return 1; - opt_printf_stderr("%s: Unknown cipher: %s\n", prog, name); + } + ERR_clear_last_mark(); return 0; } +int opt_cipher(const char *name, EVP_CIPHER **cipherp) +{ + int ret; + + if ((ret = opt_cipher_silent(name, cipherp)) == 0) + opt_printf_stderr("%s: Unknown cipher: %s\n", prog, name); + return ret; +} + /* * Parse message digest name, put it in *EVP_MD; return 0 on failure, else 1. */ -int opt_md(const char *name, EVP_MD **mdp) +int opt_md_silent(const char *name, EVP_MD **mdp) { - *mdp = (EVP_MD *)EVP_get_digestbyname(name); - if (*mdp != NULL) - return 1; - *mdp = EVP_MD_fetch(NULL, name, NULL); - if (*mdp != NULL) + EVP_MD_free(*mdp); + + ERR_set_mark(); + if ((*mdp = EVP_MD_fetch(NULL, name, NULL)) != NULL + || (*mdp = (EVP_MD *)EVP_get_digestbyname(name)) != NULL) { + ERR_pop_to_mark(); return 1; - opt_printf_stderr("%s: Unknown option or message digest: %s\n", prog, - name != NULL ? name : "\"\""); + } + ERR_clear_last_mark(); return 0; } +int opt_md(const char *name, EVP_MD **mdp) +{ + int ret; + + if ((ret = opt_md_silent(name, mdp)) == 0) + opt_printf_stderr("%s: Unknown option or message digest: %s\n", prog, + name != NULL ? name : "\"\""); + return ret; +} + /* Look through a list of name/value pairs. */ int opt_pair(const char *name, const OPT_PAIR* pairs, int *result) { diff --git a/apps/req.c b/apps/req.c index 4e1cae6ba6..89bde55b93 100644 --- a/apps/req.c +++ b/apps/req.c @@ -240,7 +240,7 @@ int req_main(int argc, char **argv) X509 *new_x509 = NULL, *CAcert = NULL; X509_REQ *req = NULL; EVP_CIPHER *cipher = NULL; - EVP_MD *md_alg = NULL, *digest = NULL; + EVP_MD *digest = NULL; int ext_copy = EXT_COPY_UNSET; BIO *addext_bio = NULL; char *extensions = NULL; @@ -482,9 +482,8 @@ int req_main(int argc, char **argv) goto end; if (digestname != NULL) { - if (!opt_md(digestname, &md_alg)) + if (!opt_md(digestname, &digest)) goto opthelp; - digest = md_alg; } if (!gen_x509) { @@ -536,14 +535,13 @@ int req_main(int argc, char **argv) if (!add_oid_section(req_conf)) goto end; - if (md_alg == NULL) { + if (digest == NULL) { p = NCONF_get_string(req_conf, section, "default_md"); if (p == NULL) { ERR_clear_error(); } else { - if (!opt_md(p, &md_alg)) + if (!opt_md(p, &digest)) goto opthelp; - digest = md_alg; } } @@ -1058,7 +1056,6 @@ int req_main(int argc, char **argv) BIO_free(addext_bio); BIO_free_all(out); EVP_PKEY_free(pkey); - EVP_MD_free(md_alg); EVP_MD_free(digest); EVP_PKEY_CTX_free(genctx); sk_OPENSSL_STRING_free(pkeyopts); diff --git a/apps/speed.c b/apps/speed.c index 939baf934d..5363b0d7f8 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -502,73 +502,35 @@ static const char *evp_md_name = NULL; static char *evp_mac_ciphername = "aes-128-cbc"; static char *evp_cmac_name = NULL; -static EVP_MD *obtain_md(const char *name, int *fetched) -{ - EVP_MD *md = NULL; - - *fetched = 0; - /* Look through providers' digests */ - ERR_set_mark(); - md = EVP_MD_fetch(NULL, name, NULL); - ERR_pop_to_mark(); - if (md != NULL) { - *fetched = 1; - return md; - } - - return (EVP_MD *)EVP_get_digestbyname(name); -} - static int have_md(const char *name) { - int fetched = 0; int ret = 0; - EVP_MD *md = obtain_md(name, &fetched); + EVP_MD *md = NULL; - if (md != NULL) { + if (opt_md_silent(name, &md)) { EVP_MD_CTX *ctx = EVP_MD_CTX_new(); if (ctx != NULL && EVP_DigestInit(ctx, md) > 0) ret = 1; EVP_MD_CTX_free(ctx); - if (fetched) - EVP_MD_free(md); + EVP_MD_free(md); } return ret; } -static EVP_CIPHER *obtain_cipher(const char *name, int *fetched) -{ - EVP_CIPHER *cipher = NULL; - - *fetched = 0; - /* Look through providers' digests */ - ERR_set_mark(); - cipher = EVP_CIPHER_fetch(NULL, name, NULL); - ERR_pop_to_mark(); - if (cipher != NULL) { - *fetched = 1; - return cipher; - } - - return (EVP_CIPHER *)EVP_get_cipherbyname(name); -} - static int have_cipher(const char *name) { - int fetched = 0; int ret = 0; - EVP_CIPHER *cipher = obtain_cipher(name, &fetched); + EVP_CIPHER *cipher = NULL; - if (cipher != NULL) { + if (opt_cipher_silent(name, &cipher)) { EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); if (ctx != NULL && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0) ret = 1; EVP_CIPHER_CTX_free(ctx); - if (fetched) - EVP_CIPHER_free(cipher); + EVP_CIPHER_free(cipher); } return ret; } @@ -578,10 +540,10 @@ static int EVP_Digest_loop(const char *mdname, int algindex, void *args) loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; unsigned char digest[EVP_MAX_MD_SIZE]; - int count, fetched = 0; - EVP_MD *md = obtain_md(mdname, &fetched); + int count; + EVP_MD *md = NULL; - if (md == NULL) + if (!opt_md_silent(mdname, &md)) return -1; for (count = 0; COND(c[algindex][testnum]); count++) { if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md, @@ -590,8 +552,7 @@ static int EVP_Digest_loop(const char *mdname, int algindex, void *args) break; } } - if (fetched) - EVP_MD_free(md); + EVP_MD_free(md); return count; } @@ -714,10 +675,9 @@ static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername, int keylen) { EVP_CIPHER_CTX *ctx = NULL; - int fetched = 0; - EVP_CIPHER *cipher = obtain_cipher(ciphername, &fetched); + EVP_CIPHER *cipher = NULL; - if (cipher == NULL) + if (!opt_cipher_silent(ciphername, &cipher)) return NULL; if ((ctx = EVP_CIPHER_CTX_new()) == NULL) @@ -742,8 +702,7 @@ static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername, } end: - if (fetched) - EVP_CIPHER_free(cipher); + EVP_CIPHER_free(cipher); return ctx; } @@ -1388,7 +1347,6 @@ int speed_main(int argc, char **argv) unsigned int i, k, loopargs_len = 0, async_jobs = 0; int keylen; int buflen; - int fetched_cipher = 0; BIGNUM *bn = NULL; EVP_PKEY_CTX *genctx = NULL; #ifndef NO_FORK @@ -1533,17 +1491,19 @@ int speed_main(int argc, char **argv) BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog); goto opterr; } - evp_cipher = obtain_cipher(opt_arg(), &fetched_cipher); - if (evp_cipher == NULL) { + ERR_set_mark(); + if (!opt_cipher_silent(opt_arg(), &evp_cipher)) { if (have_md(opt_arg())) evp_md_name = opt_arg(); } if (evp_cipher == NULL && evp_md_name == NULL) { + ERR_clear_last_mark(); BIO_printf(bio_err, "%s: %s is an unknown cipher or digest\n", prog, opt_arg()); goto end; } + ERR_pop_to_mark(); doit[D_EVP] = 1; break; case OPT_HMAC: @@ -2294,17 +2254,15 @@ int speed_main(int argc, char **argv) if (doit[D_EVP_CMAC]) { EVP_MAC *mac = EVP_MAC_fetch(NULL, "CMAC", NULL); OSSL_PARAM params[3]; - EVP_CIPHER *cipher; - int fetched = 0; + EVP_CIPHER *cipher = NULL; if (mac == NULL || evp_mac_ciphername == NULL) goto end; - if ((cipher = obtain_cipher(evp_mac_ciphername, &fetched)) == NULL) + if (!opt_cipher(evp_mac_ciphername, &cipher)) goto end; keylen = EVP_CIPHER_key_length(cipher); - if (fetched) - EVP_CIPHER_free(cipher); + EVP_CIPHER_free(cipher); if (keylen <= 0 || keylen > (int)sizeof(key32)) { BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n"); goto end; @@ -3360,9 +3318,7 @@ int speed_main(int argc, char **argv) } OPENSSL_free(loopargs); release_engine(e); - if (fetched_cipher) { - EVP_CIPHER_free(evp_cipher); - } + EVP_CIPHER_free(evp_cipher); return ret; } -- cgit v1.2.3