Allow configuration of a range of SSL protocols independently
for accepting incoming connections (listening) and making
outgoing connections.
The default minimum version is TLS v1.1 which has the effect of
disabling SSL v3 and earlier by default.
The minimum version accepted by the options is SSL v3 and thus
it is not possible to enable SSL v2.
The default maximum version is to use OpenSSL's default value.
The maximum version accepted by the options is TLS v1.2.
The code will need to be updated to support any newer versions
of TLS as they become available in OpenSSL.
Based on work by Matthias Hunstock.
Cc: Matthias Hunstock <matthias.hunstock(a)tu-ilmenau.de>
Signed-off-by: Simon Horman <horms(a)verge.net.au>
---
v2
* Allow max version of "" to be specified as an option,
translate this to NULL which means that OpenSSL's default will be used.
"" is not allowed for min versions as we wish to enforce an
absolute minimum of SSLv3.
diff -r 6428070b4889 -r 0f9b612d6d07 configure.ac
--- a/configure.ac Sun Dec 01 17:26:51 2013 +0900
+++ b/configure.ac Wed May 11 08:57:22 2016 +0900
@@ -211,6 +211,9 @@
if test "$enable_ssl" = "yes"; then
AC_DEFINE(WITH_SSL_SUPPORT, 1, Compile with SSL/TLS support)
+ AC_CHECK_LIB(ssl, SSL_CTX_set_min_proto_version)
+ AC_CHECK_DECLS([SSL_CTX_set_min_proto_version], [], [], [[#include
<openssl/ssl.h>]])
+ AC_CHECK_DECLS([SSL_CTX_set_max_proto_version], [], [], [[#include
<openssl/ssl.h>]])
else
ssl_lib=""
ssl_includes=""
diff -r 6428070b4889 -r 0f9b612d6d07 etc/perdition/perdition.conf
--- a/etc/perdition/perdition.conf Sun Dec 01 17:26:51 2013 +0900
+++ b/etc/perdition/perdition.conf Wed May 11 08:57:22 2016 +0900
@@ -403,3 +403,30 @@
# to connect to the server.
#ssl_no_cn_verify
+# ssl_listen_min_proto_version PROTOCOL_VERSION:
+# Minimum permited SSL/TLS protocol version when accepting incoming
+# connections.
+# May not be empty ("").
+# (default "tlsv1")
+#ssl_listen_min_proto_version "tlsv1"
+
+# ssl_outgoing_min_proto_version PROTOCOL_VERSION:
+# Minimum permited SSL/TLS protocol version when making outgoing
+# connections.
+# May not be empty ("").
+# (default "tlsv1")
+#ssl_outgoing_min_proto_version "tlsv1"
+
+# ssl_listen_max_proto_version PROTOCOL_VERSION:
+# Maximum permited SSL/TLS protocol version when accepting incomaxg
+# connections.
+# If empty ("") then openssl's default will be used.
+# (default "")
+#ssl_listen_max_proto_version "tlsv1.2"
+
+# ssl_outgoing_max_proto_version PROTOCOL_VERSION:
+# Maximum permited SSL/TLS protocol version when making outgoing
+# connections.
+# If empty ("") then openssl's default will be used.
+# (default "")
+#ssl_outgoing_max_proto_version "tlsv1.2"
diff -r 6428070b4889 -r 0f9b612d6d07 perdition/options.c
--- a/perdition/options.c Sun Dec 01 17:26:51 2013 +0900
+++ b/perdition/options.c Wed May 11 08:57:22 2016 +0900
@@ -34,6 +34,7 @@
#include "options.h"
#include "config_file.h"
#include "perdition_globals.h"
+#include "ssl.h"
#ifdef DMALLOC
#include <dmalloc.h>
@@ -488,6 +489,14 @@
TAG_SSL_PASSPHRASE_FD, NULL, NULL},
{"ssl_passphrase_file", '\0', POPT_ARG_STRING, NULL,
TAG_SSL_PASSPHRASE_FILE, NULL, NULL},
+ {"ssl_listen_min_proto_version", '\0', POPT_ARG_STRING, NULL,
+ TAG_SSL_LISTEN_MIN_PROTO_VERSION, NULL, NULL},
+ {"ssl_outgoing_min_proto_version", '\0', POPT_ARG_STRING, NULL,
+ TAG_SSL_OUTGOING_MIN_PROTO_VERSION, NULL, NULL},
+ {"ssl_listen_max_proto_version", '\0', POPT_ARG_STRING, NULL,
+ TAG_SSL_LISTEN_MAX_PROTO_VERSION, NULL, NULL},
+ {"ssl_outgoing_max_proto_version", '\0', POPT_ARG_STRING, NULL,
+ TAG_SSL_OUTGOING_MAX_PROTO_VERSION, NULL, NULL},
{NULL, 0, 0, NULL,
0, NULL, NULL}
};
@@ -618,6 +627,14 @@
&i, 0, OPT_NOT_SET);
opt_p(&(opt.ssl_passphrase_file),DEFAULT_SSL_PASSPHRASE_FILE,
&i, 0, OPT_NOT_SET);
+ opt_p(&(opt.ssl_listen_min_proto_version),
+ DEFAULT_SSL_LISTEN_MIN_PROTO_VERSION, &i, 0, OPT_NOT_SET);
+ opt_p(&(opt.ssl_outgoing_min_proto_version),
+ DEFAULT_SSL_OUTGOING_MIN_PROTO_VERSION, &i, 0, OPT_NOT_SET);
+ opt_p(&(opt.ssl_listen_max_proto_version),
+ DEFAULT_SSL_LISTEN_MAX_PROTO_VERSION, &i, 0, OPT_NOT_SET);
+ opt_p(&(opt.ssl_outgoing_max_proto_version),
+ DEFAULT_SSL_OUTGOING_MAX_PROTO_VERSION, &i, 0, OPT_NOT_SET);
#endif /* WITH_SSL_SUPPORT */
}
@@ -1010,6 +1027,38 @@
NO_SSL_OPT("ssl_passphrase_file");
#endif /* WITH_SSL_SUPPORT */
break;
+ case TAG_SSL_LISTEN_MIN_PROTO_VERSION:
+#ifdef WITH_SSL_SUPPORT
+ opt_p(&(opt.ssl_listen_min_proto_version), optarg, &(opt.ssl_mask),
+ MASK_SSL_LISTEN_MIN_PROTO_VERSION, f);
+#else /* WITH_SSL_SUPPORT */
+ NO_SSL_OPT("ssl_listen_min_proto_version");
+#endif /* WITH_SSL_SUPPORT */
+ break;
+ case TAG_SSL_OUTGOING_MIN_PROTO_VERSION:
+#ifdef WITH_SSL_SUPPORT
+ opt_p(&(opt.ssl_outgoing_min_proto_version), optarg, &(opt.ssl_mask),
+ MASK_SSL_OUTGOING_MIN_PROTO_VERSION, f);
+#else /* WITH_SSL_SUPPORT */
+ NO_SSL_OPT("ssl_outgoing_min_proto_version");
+#endif /* WITH_SSL_SUPPORT */
+ break;
+ case TAG_SSL_LISTEN_MAX_PROTO_VERSION:
+#ifdef WITH_SSL_SUPPORT
+ opt_p(&(opt.ssl_listen_max_proto_version), optarg, &(opt.ssl_mask),
+ MASK_SSL_LISTEN_MAX_PROTO_VERSION, f);
+#else /* WITH_SSL_SUPPORT */
+ NO_SSL_OPT("ssl_listen_max_proto_version");
+#endif /* WITH_SSL_SUPPORT */
+ break;
+ case TAG_SSL_OUTGOING_MAX_PROTO_VERSION:
+#ifdef WITH_SSL_SUPPORT
+ opt_p(&(opt.ssl_outgoing_max_proto_version), optarg, &(opt.ssl_mask),
+ MASK_SSL_OUTGOING_MAX_PROTO_VERSION, f);
+#else /* WITH_SSL_SUPPORT */
+ NO_SSL_OPT("ssl_outgoing_max_proto_version");
+#endif /* WITH_SSL_SUPPORT */
+ break;
default:
VANESSA_LOGGER_DEBUG_RAW("Unknown Option");
break;
@@ -1029,6 +1078,128 @@
}
}
+ {
+ int min_ver = 0;
+ int max_ver = 0;
+
+ if (opt.ssl_listen_min_proto_version) {
+ VANESSA_LOGGER_DEBUG_RAW("min");
+ min_ver = perdition_parse_ssl_proto_version(
+ opt.ssl_listen_min_proto_version);
+ if (min_ver < 0) {
+ VANESSA_LOGGER_DEBUG_RAW("Unknown ssl_listen_min_proto_version");
+ if (f & OPT_ERR) {
+ usage(-1);
+ } else {
+ poptFreeContext(context);
+ return -1;
+ }
+ }
+ }
+
+ /*
+ * Translate empty max proto version to NULL which results in
+ * OpenSSL's defaults being used.
+ * This differs from min proto version handling where "" is
+ * not translated and rejected by
+ * perdition_parse_ssl_proto_version() so that a minimum protocol
+ * version of at least SSLv3 is enforced.
+ */
+ if (opt.ssl_listen_max_proto_version &&
+ *opt.ssl_listen_max_proto_version == '\0') {
+ free(opt.ssl_listen_max_proto_version);
+ opt.ssl_listen_max_proto_version = NULL;
+ }
+
+ if (opt.ssl_listen_max_proto_version) {
+ max_ver = perdition_parse_ssl_proto_version(
+ opt.ssl_listen_max_proto_version);
+ if (max_ver < 0) {
+ VANESSA_LOGGER_DEBUG_RAW("Unknown ssl_listen_max_proto_version");
+ if (f & OPT_ERR) {
+ usage(-1);
+ } else {
+ poptFreeContext(context);
+ return -1;
+ }
+ }
+ }
+
+ if (opt.ssl_listen_min_proto_version &&
+ opt.ssl_listen_max_proto_version && min_ver > max_ver) {
+ VANESSA_LOGGER_DEBUG_RAW("ssl_listen_min_proto_version is "
+ "greater than "
+ "ssl_listen_max_proto_version");
+ if (f&OPT_ERR) {
+ usage(-1);
+ } else {
+ poptFreeContext(context);
+ return -1;
+ }
+ }
+
+ }
+
+ {
+ int min_ver = 0;
+ int max_ver = 0;
+
+ if (opt.ssl_listen_min_proto_version) {
+ min_ver = perdition_parse_ssl_proto_version(
+ opt.ssl_listen_min_proto_version);
+ if (min_ver < 0) {
+ VANESSA_LOGGER_DEBUG_RAW("Unknown ssl_outgoing_min_proto_version");
+ if (f & OPT_ERR) {
+ usage(-1);
+ } else {
+ poptFreeContext(context);
+ return -1;
+ }
+ }
+ }
+
+ /*
+ * Translate empty max proto version to NULL which results in
+ * OpenSSL's defaults being used.
+ * This differs from min proto version handling where "" is
+ * not translated and rejected by
+ * perdition_parse_ssl_proto_version() so that a minimum protocol
+ * version of at least SSLv3 is enforced.
+ */
+ if (opt.ssl_outgoing_max_proto_version &&
+ *opt.ssl_outgoing_max_proto_version == '\0') {
+ free(opt.ssl_outgoing_max_proto_version);
+ opt.ssl_outgoing_max_proto_version = NULL;
+ }
+
+ if (opt.ssl_outgoing_max_proto_version) {
+ max_ver = perdition_parse_ssl_proto_version(
+ opt.ssl_outgoing_max_proto_version);
+ if (max_ver < 0) {
+ VANESSA_LOGGER_DEBUG_RAW("Unknown ssl_outgoing_max_proto_version");
+ if (f & OPT_ERR) {
+ usage(-1);
+ } else {
+ poptFreeContext(context);
+ return -1;
+ }
+ }
+ }
+
+ if (opt.ssl_listen_min_proto_version &&
+ opt.ssl_outgoing_max_proto_version && min_ver > max_ver) {
+ VANESSA_LOGGER_DEBUG_RAW("ssl_outgoing_min_proto_version is "
+ "greater than "
+ "ssl_outgoing_max_proto_version");
+ if (f & OPT_ERR) {
+ usage(-1);
+ } else {
+ poptFreeContext(context);
+ return -1;
+ }
+ }
+ }
+
if (c < -1) {
VANESSA_LOGGER_DEBUG_UNSAFE( "%s: %s",
poptBadOption(context, POPT_BADOPTION_NOALIAS), poptStrerror(c));
@@ -1400,6 +1571,10 @@
"ssl_no_cn_verify=\"%s\" "
"ssl_passphrase_fd=%d, "
"ssl_passphrase_file=\"%s\", "
+ "ssl_listen_min_proto_version=\"%s\", "
+ "ssl_outgoing_min_proto_version=\"%s\", "
+ "ssl_listen_max_proto_version=\"%s\", "
+ "ssl_outgoing_max_proto_version=\"%s\", "
"(ssl_mask=0x%08x) ",
ssl_mode,
OPT_STR(opt.ssl_ca_file),
@@ -1418,6 +1593,10 @@
BIN_OPT_STR(opt.ssl_no_cn_verify),
opt.ssl_passphrase_fd,
OPT_STR(opt.ssl_passphrase_file),
+ OPT_STR(opt.ssl_listen_min_proto_version),
+ OPT_STR(opt.ssl_outgoing_min_proto_version),
+ OPT_STR(opt.ssl_listen_max_proto_version),
+ OPT_STR(opt.ssl_outgoing_max_proto_version),
opt.ssl_mask);
out[MAX_LINE_LENGTH - 1] = '\0';
@@ -1716,6 +1895,26 @@
" --ssl_passphrase_file FILENAME:\n"
" File from with the passphrase for the certificate is read.\n"
" (default \"%s\")\n"
+ " --ssl_listen_min_proto_version PROTOCOL_VERSION:\n"
+ " Minimum permited SSL/TLS protocol version when accepting incomming\n"
+ " connections.\n"
+ " May not be empty (\"\").\n"
+ " (default \"%s\")\n"
+ " --ssl_outgoing_min_proto_version PROTOCOL_VERSION:\n"
+ " Minimum permited SSL/TLS protocol version when making outgoing\n"
+ " connections.\n"
+ " May not be empty (\"\").\n"
+ " (default \"%s\")\n"
+ " --ssl_listen_max_proto_version PROTOCOL_VERSION:\n"
+ " Maximum permited SSL/TLS protocol version when accepting incoming\n"
+ " connections.\n"
+ " If empty (\"\") then openssl's default will be used.\n"
+ " (default \"%s\")\n"
+ " --ssl_outgoing_max_proto_version PROTOCOL_VERSION:\n"
+ " Maximum permited SSL/TLS protocol version when making outgoing\n"
+ " connections.\n"
+ " If empty (\"\") then openssl's default will be used.\n"
+ " (default \"%s\")\n"
#endif /* WITH_SSL_SUPPORT */
"\n"
" Notes: Default value for binary flags is off.\n"
@@ -1760,7 +1959,11 @@
OPT_STR(DEFAULT_SSL_LISTEN_CIPHERS),
OPT_STR(DEFAULT_SSL_OUTGOING_CIPHERS),
DEFAULT_SSL_PASSPHRASE_FD,
- OPT_STR(DEFAULT_SSL_PASSPHRASE_FILE)
+ OPT_STR(DEFAULT_SSL_PASSPHRASE_FILE),
+ OPT_STR(DEFAULT_SSL_LISTEN_MIN_PROTO_VERSION),
+ OPT_STR(DEFAULT_SSL_OUTGOING_MIN_PROTO_VERSION),
+ OPT_STR(DEFAULT_SSL_LISTEN_MAX_PROTO_VERSION),
+ OPT_STR(DEFAULT_SSL_OUTGOING_MAX_PROTO_VERSION)
#endif /* WITH_SSL_SUPPORT */
);
diff -r 6428070b4889 -r 0f9b612d6d07 perdition/options.h
--- a/perdition/options.h Sun Dec 01 17:26:51 2013 +0900
+++ b/perdition/options.h Wed May 11 08:57:22 2016 +0900
@@ -181,6 +181,10 @@
#define DEFAULT_SSL_NO_CN_VERIFY 0
#define DEFAULT_SSL_PASSPHRASE_FD 0
#define DEFAULT_SSL_PASSPHRASE_FILE NULL
+#define DEFAULT_SSL_LISTEN_MIN_PROTO_VERSION "tlsv1"
+#define DEFAULT_SSL_OUTGOING_MIN_PROTO_VERSION "tlsv1"
+#define DEFAULT_SSL_LISTEN_MAX_PROTO_VERSION NULL
+#define DEFAULT_SSL_OUTGOING_MAX_PROTO_VERSION NULL
#endif /* WITH_SSL_SUPPORT */
@@ -249,6 +253,10 @@
int ssl_no_cn_verify;
int ssl_passphrase_fd;
char *ssl_passphrase_file;
+ char *ssl_listen_min_proto_version;
+ char *ssl_outgoing_min_proto_version;
+ char *ssl_listen_max_proto_version;
+ char *ssl_outgoing_max_proto_version;
flag_t ssl_mask;
} options_t;
@@ -317,6 +325,10 @@
#define MASK_SSL_NO_CN_VERIFY (flag_t) 0x00004000
#define MASK_SSL_PASSPHRASE_FD (flag_t) 0x00008000
#define MASK_SSL_PASSPHRASE_FILE (flag_t) 0x00010000
+#define MASK_SSL_LISTEN_MIN_PROTO_VERSION (flag_t) 0x00020000
+#define MASK_SSL_OUTGOING_MIN_PROTO_VERSION (flag_t) 0x00040000
+#define MASK_SSL_LISTEN_MAX_PROTO_VERSION (flag_t) 0x00080000
+#define MASK_SSL_OUTGOING_MAX_PROTO_VERSION (flag_t) 0x00100000
#endif /* WITH_SSL_SUPPORT */
/*
@@ -355,6 +367,10 @@
#define TAG_MANAGESIEVE_CAPABILITY (int) 155
#define TAG_POP_CAPABILITY (int) 156
#define TAG_TCP_KEEPALIVE (int) 157
+#define TAG_SSL_LISTEN_MIN_PROTO_VERSION (int) 158
+#define TAG_SSL_OUTGOING_MIN_PROTO_VERSION (int) 159
+#define TAG_SSL_LISTEN_MAX_PROTO_VERSION (int) 160
+#define TAG_SSL_OUTGOING_MAX_PROTO_VERSION (int) 161
/*Flag values for options()*/
#define OPT_ERR (flag_t) 0x1 /*Print error to stderr, enable help*/
diff -r 6428070b4889 -r 0f9b612d6d07 perdition/perdition.8
--- a/perdition/perdition.8 Sun Dec 01 17:26:51 2013 +0900
+++ b/perdition/perdition.8 Wed May 11 08:57:22 2016 +0900
@@ -635,6 +635,69 @@
be specified.
(default NULL, no file)
.TP
+.B \-\-ssl_listen_ciphers STRING:
+Cipher list when listening for SSL or TLS connections as per
+ciphers(1). If empty ("") then openssl's default will be used.
+.br
+(default "")
+.TP
+.B \-\-ssl_outgoing_ciphers STRING:
+Cipher list when making outgoing SSL or TLS connections as per
+ciphers(1). If empty ("") then openssl's default will be used.
+.br
+(default "")
+.TP
+.B \-\-ssl_no_cert_verify:
+Don't cryptographically verify the certificates.
+Used for SSL or TLS outgoing connections.
+.TP
+.B \-\-ssl_no_client_cert_verify:
+Don't cryptographically verify the end-user's certificate.
+Used for SSL or TLS outgoing connections.
+.TP
+.B \-\-ssl_no_cn_verify:
+Don't verify the real-server's common name with the name used.
+to connect to the server. Used for SSL or TLS outgoing connections.
+.TP
+.B \-\-ssl_passphrase_fd N:
+File descriptor to read the passphrase for the certificate from.
+Only the first line will be read.
+Only one of ssl_passphrase_fd and ssl_passphrase_file may
+be specified.
+(default 0)
+.TP
+.B \-\-ssl_listen_min_proto_version PROTOCOL_VERSIONS:
+Minimum permited SSL/TLS protocol version when accepting incomming
+connections. May not be empty ("").
+.sp
+The valid protocol versions are sslv3, tlsv1, tlsv1.1 and tlsv1.2.
+.sp
+(default "tlsv1")
+.TP
+.B \-\-ssl_outgoing_min_proto_version PROTOCOL_VERSIONS:
+Minimum permited SSL/TLS protocol version when making outgoing
+connections. May not be empty ("").
+.sp
+The valid protocol versions are sslv3, tlsv1, tlsv1.1 and tlsv1.2.
+.sp
+(default "tlsv1")
+.TP
+.B \-\-ssl_listen_max_proto_version PROTOCOL_VERSIONS:
+Maximum permited SSL/TLS protocol version when accepting incommaxg
+connections. If empty ("") then openssl's default will be used.
+.sp
+The valid protocol versions are sslv3, tlsv1, tlsv1.1 and tlsv1.2.
+.sp
+(default "")
+.TP
+.B \-\-ssl_outgoing_max_proto_version PROTOCOL_VERSIONS:
+Maximum permited SSL/TLS protocol version when making outgoing
+connections. If empty ("") then openssl's default will be used.
+.sp
+The valid protocol versions are sslv3, tlsv1, tlsv1.1 and tlsv1.2.
+.sp
+(default "")
+.TP
Notes:
Default value for binary flags is off.
.br
diff -r 6428070b4889 -r 0f9b612d6d07 perdition/ssl.c
--- a/perdition/ssl.c Sun Dec 01 17:26:51 2013 +0900
+++ b/perdition/ssl.c Wed May 11 08:57:22 2016 +0900
@@ -139,6 +139,23 @@
return strlen(buf);
}
+int perdition_parse_ssl_proto_version(const char *str)
+{
+ if (!strcasecmp(str, "sslv3")) {
+ return SSL3_VERSION;
+ }
+ if (!strcasecmp(str, "tlsv1")) {
+ return TLS1_VERSION;
+ }
+ if (!strcasecmp(str, "tlsv1.1")) {
+ return TLS1_1_VERSION;
+ }
+ if (!strcasecmp(str, "tlsv1.2")) {
+ return TLS1_2_VERSION;
+ }
+
+ return -1;
+}
/**********************************************************************
* perdition_ssl_ctx
@@ -486,6 +503,72 @@
return(verify);
}
+#if HAVE_DECL_SSL_CTX_SET_MIN_PROTO_VERSION == 0
+static int
+perdition_ssl_ctx_set_min_proto_version(SSL_CTX *ssl_ctx, int min_version)
+{
+ long options = SSL_OP_NO_SSLv2;
+
+ switch (min_version) {
+ case TLS1_2_VERSION:
+ options |= SSL_OP_NO_TLSv1_1;
+ /* fall-through */
+ case TLS1_1_VERSION:
+ options |= SSL_OP_NO_TLSv1;
+ /* fall-through */
+ case TLS1_VERSION:
+ options |= SSL_OP_NO_SSLv3;
+ /* fall-through */
+ case SSL3_VERSION:
+ /* Nothing more to do */
+ break;
+ default:
+ PERDITION_DEBUG_SSL_ERR("Unknown minumum version");
+ return 0;
+ }
+
+ SSL_CTX_set_options(ssl_ctx, options);
+ return 1;
+}
+
+#define SSL_CTX_set_min_proto_version perdition_ssl_ctx_set_min_proto_version
+#endif
+
+#if HAVE_DECL_SSL_CTX_SET_MAX_PROTO_VERSION == 0
+static int
+perdition_ssl_ctx_set_max_proto_version(SSL_CTX *ssl_ctx, int max_version)
+{
+ long options = 0;
+
+ switch (max_version) {
+ case SSL3_VERSION:
+ options |= SSL_OP_NO_TLSv1;
+ /* fall-through */
+ case TLS1_VERSION:
+ options |= SSL_OP_NO_TLSv1_1;
+ /* fall-through */
+ case TLS1_1_VERSION:
+ options |= SSL_OP_NO_TLSv1_2;
+ /* fall-through */
+ case TLS1_2_VERSION:
+ /* Nothing more to do */
+ break;
+ default:
+ PERDITION_DEBUG_SSL_ERR("Unknown maximum version");
+ return 0;
+ }
+
+ SSL_CTX_set_options(ssl_ctx, options);
+
+ VANESSA_LOGGER_ERR("warning: protocol versions greater than tlsv1.2 "
+ "may still be allowed if supported by the SSL/TLS "
+ "implementation");
+ return 1;
+}
+
+#define SSL_CTX_set_max_proto_version perdition_ssl_ctx_set_max_proto_version
+#endif
+
SSL_CTX *perdition_ssl_ctx(const char *ca_file, const char *ca_path,
const char *cert, const char *privkey,
const char *ca_chain_file, const char *ciphers, flag_t flag)
@@ -533,6 +616,60 @@
}
/*
+ * Set minimum protocol version
+ */
+ {
+ const char *ver_str;
+
+ if (flag == PERDITION_SSL_CLIENT)
+ ver_str = opt.ssl_outgoing_min_proto_version;
+ else
+ ver_str = opt.ssl_listen_min_proto_version;
+
+ if (ver_str) {
+ int ver_no = perdition_parse_ssl_proto_version(ver_str);
+
+
+ if (ver_no < 0) {
+ VANESSA_LOGGER_DEBUG("perdition_parse_ssl_proto_version");
+ goto err;
+ }
+
+ if (!SSL_CTX_set_min_proto_version(ssl_ctx, ver_no)) {
+ VANESSA_LOGGER_DEBUG("SSL_CTX_set_min_proto_version");
+ goto err;
+ }
+ }
+ }
+
+ /*
+ * Set maximum protocol version
+ */
+ {
+ const char *ver_str;
+
+ if (flag == PERDITION_SSL_CLIENT)
+ ver_str = opt.ssl_outgoing_max_proto_version;
+ else
+ ver_str = opt.ssl_listen_max_proto_version;
+
+ if (ver_str) {
+ int ver_no = perdition_parse_ssl_proto_version(ver_str);
+
+
+ if (ver_no < 0) {
+ VANESSA_LOGGER_DEBUG("perdition_parse_ssl_proto_version");
+ goto err;
+ }
+
+ if (!SSL_CTX_set_max_proto_version(ssl_ctx, ver_no)) {
+ VANESSA_LOGGER_DEBUG("SSL_CTX_set_max_proto_version");
+ goto err;
+ }
+ }
+ }
+
+ /*
* Set the available ciphers
*/
if(ciphers && SSL_CTX_set_cipher_list(ssl_ctx, ciphers) < 0) {
diff -r 6428070b4889 -r 0f9b612d6d07 perdition/ssl.h
--- a/perdition/ssl.h Sun Dec 01 17:26:51 2013 +0900
+++ b/perdition/ssl.h Wed May 11 08:57:22 2016 +0900
@@ -39,6 +39,8 @@
#define PERDITION_SSL_CLIENT (flag_t) 0x1
#define PERDITION_SSL_SERVER (flag_t) 0x2
+int perdition_parse_ssl_proto_version(const char *str);
+
/**********************************************************************
* perdition_ssl_ctx
* Create an SSL context