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)
This commit is contained in:
Pauli 2021-06-15 14:06:17 +10:00
parent 6920055ec3
commit fa8ff9e4e8
2 changed files with 38 additions and 6 deletions

View File

@ -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);

View File

@ -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;
}