summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/include/opt.h1
-rw-r--r--apps/lib/opt.c43
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;
}