diff options
author | Pauli <pauli@openssl.org> | 2021-06-15 06:06:17 +0200 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2021-06-16 10:32:30 +0200 |
commit | fa8ff9e4e8e0937eb04bf16d0159c3aedbd33547 (patch) | |
tree | 96d31f85b2e4f047481e55eef6472bf244307ce7 | |
parent | doc: document the various get_cipher functions in the commands lib. (diff) | |
download | openssl-fa8ff9e4e8e0937eb04bf16d0159c3aedbd33547.tar.xz openssl-fa8ff9e4e8e0937eb04bf16d0159c3aedbd33547.zip |
apps: limit get_cipher() to not return AEAD or XTS ciphers
Add a get_cipher_any() function to access these in addition to more normal ciphers
Fixes #7720
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15747)
-rw-r--r-- | apps/include/opt.h | 1 | ||||
-rw-r--r-- | apps/lib/opt.c | 43 |
2 files changed, 38 insertions, 6 deletions
diff --git a/apps/include/opt.h b/apps/include/opt.h index 96e78e4b79..4a292213fd 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -366,6 +366,7 @@ char *opt_flag(void); char *opt_arg(void); char *opt_unknown(void); int opt_cipher(const char *name, EVP_CIPHER **cipherp); +int opt_cipher_any(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); diff --git a/apps/lib/opt.c b/apps/lib/opt.c index c6a506480a..c88c99b5e6 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -368,27 +368,58 @@ void print_format_error(int format, unsigned long flags) (void)opt_format_error(format2str(format), flags); } -/* Parse a cipher name, put it in *EVP_CIPHER; return 0 on failure, else 1. */ +/* + * Parse a cipher name, put it in *cipherp after freeing what was there, if + * cipherp is not NULL. Return 0 on failure, else 1. + */ int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp) { - EVP_CIPHER_free(*cipherp); + EVP_CIPHER *c; ERR_set_mark(); - if ((*cipherp = EVP_CIPHER_fetch(NULL, name, NULL)) != NULL - || (*cipherp = (EVP_CIPHER *)EVP_get_cipherbyname(name)) != NULL) { + if ((c = EVP_CIPHER_fetch(NULL, name, NULL)) != NULL + || (c = (EVP_CIPHER *)EVP_get_cipherbyname(name)) != NULL) { ERR_pop_to_mark(); + if (cipherp != NULL) { + EVP_CIPHER_free(*cipherp); + *cipherp = c; + } else { + EVP_CIPHER_free(c); + } return 1; } ERR_clear_last_mark(); return 0; } -int opt_cipher(const char *name, EVP_CIPHER **cipherp) +int opt_cipher_any(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); + opt_printf_stderr("%s: Unknown cipher: %s\n", prog, name); + return ret; +} + +int opt_cipher(const char *name, EVP_CIPHER **cipherp) +{ + int mode, ret = 0; + unsigned long int flags; + EVP_CIPHER *c = NULL; + + if (opt_cipher_any(name, &c)) { + mode = EVP_CIPHER_get_mode(c); + flags = EVP_CIPHER_get_flags(c); + if (mode == EVP_CIPH_XTS_MODE) { + opt_printf_stderr("%s XTS ciphers not supported\n", prog); + } else if ((flags & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) { + opt_printf_stderr("%s: AEAD ciphers not supported\n", prog); + } else { + ret = 1; + if (cipherp != NULL) + *cipherp = c; + } + } return ret; } |