changeset 941:440bad5e5ba4

Provide SSL/TLS compression configuration options Disable SSL/TLS compression by default and allow it to be enabled by new configuration options independently for accepting incoming connections (listening) and making outgoing connections. Based on work by Matthias Hunstock. Cc: Matthias Hunstock <matthias.hunstock@tu-ilmenau.de> Signed-off-by: Simon Horman <horms@verge.net.au> --- Lightly tested v3 * Rebase onto tip from v2.1 v2 * New patch diff -r 6428070b4889 configure.ac --- a/configure.ac Sun Dec 01 17:26:51 2013 +0900 +++ b/configure.ac Tue May 10 22:01:45 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 etc/perdition/perdition.conf --- a/etc/perdition/perdition.conf Sun Dec 01 17:26:51 2013 +0900 +++ b/etc/perdition/perdition.conf Tue May 10 22:01:45 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. +# If empty ("") then openssl's default will be used. +# (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. +# If empty ("") then openssl's default will be used. +# (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 perdition/options.c --- a/perdition/options.c Sun Dec 01 17:26:51 2013 +0900 +++ b/perdition/options.c Tue May 10 22:01:45 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,100 @@ } } + { + 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; + } + } + } + + 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; + } + } + } + + 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 +1543,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 +1565,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 +1867,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" + " If empty (\"\") then openssl's default will be used.\n" + " (default \"%s\")\n" + " --ssl_outgoing_min_proto_version PROTOCOL_VERSION:\n" + " Minimum permited SSL/TLS protocol version when making outgoing\n" + " connections.\n" + " If empty (\"\") then openssl's default will be used.\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 +1931,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 perdition/options.h --- a/perdition/options.h Sun Dec 01 17:26:51 2013 +0900 +++ b/perdition/options.h Tue May 10 22:01:45 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 perdition/perdition.8 --- a/perdition/perdition.8 Sun Dec 01 17:26:51 2013 +0900 +++ b/perdition/perdition.8 Tue May 10 22:01:45 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. If empty ("") then openssl's default will be used. +.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. If empty ("") then openssl's default will be used. +.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 perdition/ssl.c --- a/perdition/ssl.c Sun Dec 01 17:26:51 2013 +0900 +++ b/perdition/ssl.c Tue May 10 22:01:45 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("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 perdition/ssl.h --- a/perdition/ssl.h Sun Dec 01 17:26:51 2013 +0900 +++ b/perdition/ssl.h Tue May 10 22:01:45 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
author Simon Horman <horms@verge.net.au>
date Wed, 11 May 2016 09:26:21 +0900
parents 83b5c4362c53
children d67d8e0db228
files etc/perdition/perdition.conf perdition/options.c perdition/options.h perdition/perdition.8 perdition/ssl.c
diffstat 5 files changed, 63 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/etc/perdition/perdition.conf	Wed May 11 08:57:22 2016 +0900
+++ b/etc/perdition/perdition.conf	Wed May 11 09:26:21 2016 +0900
@@ -435,3 +435,12 @@
 # If empty ("") then openssl's default will be used.
 # (default "")
 #ssl_outgoing_max_proto_version "tlsv1.2"
+
+# ssl_listen_compression
+# Allow SSL/TLS compression when accepting incoming connections.
+#ssl_listen_compression
+
+# ssl_outgoing_compression
+# Allow SSL/TLS compression when making outgoing connections.
+#ssl_outgoing_compression
+
--- a/perdition/options.c	Wed May 11 08:57:22 2016 +0900
+++ b/perdition/options.c	Wed May 11 09:26:21 2016 +0900
@@ -499,6 +499,10 @@
       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},
+    {"ssl_listen_compression", '\0', POPT_ARG_NONE, NULL,
+      TAG_SSL_LISTEN_COMPRESSION, NULL, NULL},
+    {"ssl_outgoing_compression", '\0', POPT_ARG_NONE, NULL,
+      TAG_SSL_OUTGOING_COMPRESSION, NULL, NULL},
     {NULL,                           0,   0,               NULL,
      0, NULL, NULL}
   };
@@ -638,6 +642,10 @@
 	  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);
+    opt_i(&(opt.ssl_listen_compression), DEFAULT_SSL_LISTEN_COMPRESSION,
+	  &i, 0, OPT_NOT_SET);
+    opt_i(&(opt.ssl_outgoing_compression), DEFAULT_SSL_OUTGOING_COMPRESSION,
+	  &i, 0, OPT_NOT_SET);
 #endif /* WITH_SSL_SUPPORT */
   }
 
@@ -1070,6 +1078,22 @@
 	NO_SSL_OPT("ssl_outgoing_max_proto_version");
 #endif /* WITH_SSL_SUPPORT */
         break;
+      case TAG_SSL_LISTEN_COMPRESSION:
+#ifdef WITH_SSL_SUPPORT
+        opt_i(&(opt.ssl_listen_compression), 1, &(opt.ssl_mask),
+			MASK_SSL_LISTEN_COMPRESSION, f);
+#else /* WITH_SSL_SUPPORT */
+	NO_SSL_OPT("ssl_listen_compression");
+#endif /* WITH_SSL_SUPPORT */
+        break;
+      case TAG_SSL_OUTGOING_COMPRESSION:
+#ifdef WITH_SSL_SUPPORT
+        opt_i(&(opt.ssl_outgoing_compression), 1, &(opt.ssl_mask),
+			MASK_SSL_OUTGOING_COMPRESSION, f);
+#else /* WITH_SSL_SUPPORT */
+	NO_SSL_OPT("ssl_outgoing_compression");
+#endif /* WITH_SSL_SUPPORT */
+        break;
       default:
         VANESSA_LOGGER_DEBUG_RAW("Unknown Option");
         break;
@@ -1586,6 +1610,8 @@
 		 "ssl_outgoing_min_proto_version=\"%s\", "
 		 "ssl_listen_max_proto_version=\"%s\", "
 		 "ssl_outgoing_max_proto_version=\"%s\", "
+		 "ssl_listen_compression=\"%s\", "
+		 "ssl_outgoing_compression=\"%s\", "
 		 "(ssl_mask=0x%08x) ",
 		 ssl_mode,
 		 OPT_STR(opt.ssl_ca_file),
@@ -1608,6 +1634,8 @@
 		 OPT_STR(opt.ssl_outgoing_min_proto_version),
 		 OPT_STR(opt.ssl_listen_max_proto_version),
 		 OPT_STR(opt.ssl_outgoing_max_proto_version),
+		 BIN_OPT_STR(opt.ssl_listen_compression),
+		 BIN_OPT_STR(opt.ssl_outgoing_compression),
 		 opt.ssl_mask);
 	out[MAX_LINE_LENGTH - 1] = '\0';
 
@@ -1926,6 +1954,10 @@
     "    connections.\n"
     "    If empty (\"\") then openssl's default will be used.\n"
     "    (default \"%s\")\n"
+    " --ssl_listen_compression\n"
+    "    Allow SSL/TLS compression when accepting incoming connections.\n"
+    " --ssl_outgoing_compression\n"
+    "    Allow SSL/TLS compression when making outgoing connections.\n"
 #endif /* WITH_SSL_SUPPORT */
     "\n"
     " Notes: Default value for binary flags is off.\n"
--- a/perdition/options.h	Wed May 11 08:57:22 2016 +0900
+++ b/perdition/options.h	Wed May 11 09:26:21 2016 +0900
@@ -186,6 +186,8 @@
 #define DEFAULT_SSL_OUTGOING_MIN_PROTO_VERSION "tlsv1"
 #define DEFAULT_SSL_LISTEN_MAX_PROTO_VERSION NULL
 #define DEFAULT_SSL_OUTGOING_MAX_PROTO_VERSION NULL
+#define DEFAULT_SSL_LISTEN_COMPRESSION       0
+#define DEFAULT_SSL_OUTGOING_COMPRESSION     0
 #endif /* WITH_SSL_SUPPORT */
 
 
@@ -259,6 +261,8 @@
   char            *ssl_outgoing_min_proto_version;
   char            *ssl_listen_max_proto_version;
   char            *ssl_outgoing_max_proto_version;
+  int             ssl_listen_compression;
+  int             ssl_outgoing_compression;
   flag_t          ssl_mask;
 } options_t;
 
@@ -332,6 +336,8 @@
 #define MASK_SSL_OUTGOING_MIN_PROTO_VERSION    (flag_t) 0x00080000
 #define MASK_SSL_LISTEN_MAX_PROTO_VERSION      (flag_t) 0x00100000
 #define MASK_SSL_OUTGOING_MAX_PROTO_VERSION    (flag_t) 0x00200000
+#define MASK_SSL_LISTEN_COMPRESSION            (flag_t) 0x00400000
+#define MASK_SSL_OUTGOING_COMPRESSION          (flag_t) 0x00800000
 #endif /* WITH_SSL_SUPPORT */
 
 /* 
@@ -375,6 +381,8 @@
 #define TAG_SSL_OUTGOING_MIN_PROTO_VERSION     (int) 160
 #define TAG_SSL_LISTEN_MAX_PROTO_VERSION       (int) 161
 #define TAG_SSL_OUTGOING_MAX_PROTO_VERSION     (int) 162
+#define TAG_SSL_LISTEN_COMPRESSION             (int) 163
+#define TAG_SSL_OUTGOING_COMPRESSION           (int) 164
 
 /*Flag values for options()*/
 #define OPT_ERR         (flag_t) 0x1  /*Print error to stderr, enable help*/
--- a/perdition/perdition.8	Wed May 11 08:57:22 2016 +0900
+++ b/perdition/perdition.8	Wed May 11 09:26:21 2016 +0900
@@ -704,6 +704,12 @@
 .sp
 (default "")
 .TP
+.B \-\-ssl_listen_compression:
+Allow SSL/TLS compression when accepting incoming connections.
+.TP
+.B \-\-ssl_outgoing_compression:
+Allow SSL/TLS compression when making outgoing connections.
+.TP
 Notes: 
 Default value for binary flags is off.
 .br
--- a/perdition/ssl.c	Wed May 11 08:57:22 2016 +0900
+++ b/perdition/ssl.c	Wed May 11 09:26:21 2016 +0900
@@ -680,6 +680,14 @@
 	}
 
 	/*
+	 * Set compression
+	 */
+	if ((flag == PERDITION_SSL_CLIENT && !opt.ssl_outgoing_compression) &&
+	    (flag != PERDITION_SSL_CLIENT && !opt.ssl_listen_compression)) {
+		SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_COMPRESSION);
+	}
+
+	/*
 	 * Load the Diffie-Hellman parameters:
 	 */
 	if (flag & PERDITION_SSL_SERVER &&