diff options
Diffstat (limited to 'apps/lib/opt.c')
-rw-r--r-- | apps/lib/opt.c | 43 |
1 files changed, 37 insertions, 6 deletions
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; } |