[squid-dev] [PATCH] replacement of sslversion=N by tls-min-version=1.N

Amos Jeffries squid3 at treenet.co.nz
Fri May 15 02:19:21 UTC 2015


This patch is slightly different to what we have been discussing in
regard to the tls-min-version parameter values.


Overall the default behaviour is changed from enumerating the protocols
wanted. To limiting the unwanted.


* sslversion= parameter is removed from documentation.

* sslversion= code logics is converted from setting the SSL_*_method()
function to setting the ssloptions= masking parameters.

Yes this will open a hole for future libraries use of TLSv1.3. However
that is kind of desirable and if it becomes a problem the
ssloptions=NO_TLSv1_3 should be made available.


* The SSL_*_method() logic is all converted to using the flexible
SSLv23_*_method() API.

That API follows the latest specification behaviour: to send a protocol
frame type that any recipient should be able to parse (library decides
which), while only negotiating the protocol type permitted.


* A new option tls-min-version=1.N is added to server connection
directives. It controls *only* the TLS version range.

 - http(s)_port directives are not (yet) implemented using
Security::PeerOptions. For now they are left with options= masking to
select protocol support.

 - SSLv3 is left at the library default unless ssloptions=NO_SSLv3 is used.


* ssloptions= is left alone so anyone can still set the library options
masks to control SSLv3 enable/disable or specific TLS versions higher
than the configured minimum.


Amos

-------------- next part --------------
=== modified file 'doc/release-notes/release-4.sgml'
--- doc/release-notes/release-4.sgml	2015-03-28 11:12:46 +0000
+++ doc/release-notes/release-4.sgml	2015-05-14 22:48:22 +0000
@@ -100,114 +100,115 @@
 <descrip>
 	<tag>tls_outgoing_options</tag>
 	<p>New tag to define TLS security context options for outgoing
 	   connections. For example to HTTPS servers.
 
 	<tag>url_rewrite_timeout</tag>
 	<p>Squid times active requests to redirector. This option sets
 	   the timeout value and the Squid reaction to a timed out
 	   request.
 
 </descrip>
 
 <sect1>Changes to existing tags<label id="modifiedtags">
 <p>
 <descrip>
 	<tag>auth_param</tag>
 	<p>New parameter <em>queue-size=</em> to set the maximum number
 	   of queued requests.
 
 	<tag>cache_peer</tag>
-	<p>All <em>ssloption=</em> and <em>sslversion=</em> values for
+	<p>New option <em>tls-min-version=1.N</em> to set minimum TLS version allowed.
+	<p>All <em>ssloptions=</em> values for
 	   SSLv2 configuration or disabling have been removed.
+	<p>Removed <em>sslversion=</em> option. Use <em>ssloptions=</em> instead.
 	<p>Manual squid.conf update may be required on upgrade.
 
 	<tag>external_acl_type</tag>
 	<p>New parameter <em>queue-size=</em> to set the maximum number
 	   of queued requests.
 
 	<tag>http_port</tag>
-	<p>All <em>version=</em> <em>option=</em> values for SSLv2
+	<p>All <em>option=</em> values for SSLv2
 	   configuration or disabling have been removed.
+	<p>Removed <em>version=</em> option. Use <em>options=</em> instead.
 	<p>Manual squid.conf update may be required on upgrade.
 
 	<tag>https_port</tag>
-	<p>All <em>version=</em> <em>option=</em> values for SSLv2
+	<p>All <em>options=</em> values for SSLv2
 	   configuration or disabling have been removed.
+	<p>Removed <em>version=</em> option. Use <em>options=</em> instead.
 	<p>Manual squid.conf update may be required on upgrade.
 
 	<tag>sslcrtd_children</tag>
 	<p>New parameter <em>queue-size=</em> to set the maximum number
 	   of queued requests.
 
 	<tag>sslcrtvalidator_children</tag>
 	<p>New parameter <em>queue-size=</em> to set the maximum number
 	   of queued requests.
 
-	<tag>sslproxy_options</tag>
-	<p>All values for SSLv2 configuration or disabling have been removed.
-	<p>Manual squid.conf update may be required on upgrade.
-
-	<tag>sslproxy_version</tag>
-	<p>Value '2' for SSLv2-only operation is no longer supported.
-
 	<tag>url_rewrite_children</tag>
 	<p>New parameter <em>queue-size=</em> to set the maximum number
 	   of queued requests.
 
 </descrip>
 
 <sect1>Removed tags<label id="removedtags">
 <p>
 <descrip>
 	<tag>cache_peer_domain</tag>
 	<p>Superceded by <em>cache_peer_access</em>. Use dstdomain ACL
 	   in the access control list to restrict domains requested.
 
 	<tag>refresh_pattern</tag>
 	<p>Option <em>ignore-auth</em> removed. Its original intent was
 	   to improve caching. HTTP/1.1 permits caching of authenticated
 	   messages under conditions which Squid does check for and obey.
 
 	<tag>sslproxy_cafile</tag>
 	<p>Replaced by <em>tls_outgoing_options cafile=</em>.
 
 	<tag>sslproxy_capath</tag>
 	<p>Replaced by <em>tls_outgoing_options capath=</em>.
 
 	<tag>sslproxy_cipher</tag>
 	<p>Replaced by <em>tls_outgoing_options cipher=</em>.
 
 	<tag>sslproxy_client_certificate</tag>
 	<p>Replaced by <em>tls_outgoing_options cert=</em>.
 
 	<tag>sslproxy_client_key</tag>
 	<p>Replaced by <em>tls_outgoing_options key=</em>.
 
 	<tag>sslproxy_flags</tag>
 	<p>Replaced by <em>tls_outgoing_options flags=</em>.
 
 	<tag>sslproxy_options</tag>
 	<p>Replaced by <em>tls_outgoing_options options=</em>.
+	<p>All values for SSLv2 configuration or disabling have been removed.
+	<p>Manual squid.conf update may be required on upgrade.
 
 	<tag>sslproxy_version</tag>
-	<p>Replaced by <em>tls_outgoing_options version=</em>.
+	<p>Replaced by <em>tls_outgoing_options options=</em>.
+	<p>All values for SSLv2 configuration or disabling have been removed.
+	<p>Manual squid.conf update may be required on upgrade.
 
 </descrip>
 
 
 <sect>Changes to ./configure options since Squid-3.5
 <p>
 There have been some changes to Squid's build configuration since Squid-3.5.
 
 This section gives an account of those changes in three categories:
 
 <itemize>
 	<item><ref id="newoptions" name="New options">
 	<item><ref id="modifiedoptions" name="Changes to existing options">
 	<item><ref id="removedoptions" name="Removed options">
 </itemize>
 
 
 <sect1>New options<label id="newoptions">
 <p>
 <descrip>

=== modified file 'src/anyp/PortCfg.cc'
--- src/anyp/PortCfg.cc	2015-01-14 17:10:20 +0000
+++ src/anyp/PortCfg.cc	2015-05-08 15:15:42 +0000
@@ -1,32 +1,33 @@
 /*
  * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #include "squid.h"
 #include "anyp/PortCfg.h"
 #include "comm.h"
 #include "fatal.h"
+#include "SBuf.h"
 #if USE_OPENSSL
 #include "ssl/support.h"
 #endif
 
 #include <cstring>
 #include <limits>
 
 AnyP::PortCfgPointer HttpPortList;
 #if USE_OPENSSL
 AnyP::PortCfgPointer HttpsPortList;
 #endif
 AnyP::PortCfgPointer FtpPortList;
 
 int NHttpSockets = 0;
 int HttpSockets[MAXTCPLISTENPORTS];
 
 AnyP::PortCfg::PortCfg() :
     next(),
     s(),
     transport(AnyP::PROTO_HTTP,1,1), // "Squid is an HTTP proxy", etc.
@@ -171,41 +172,71 @@
         debugs(3, DBG_IMPORTANT, "No SSL private key configured for  " << AnyP::ProtocolType_str[transport.protocol] << "_port " << s);
 
     Ssl::generateUntrustedCert(untrustedSigningCert, untrustedSignPkey,
                                signingCert, signPkey);
 
     if (!untrustedSigningCert) {
         char buf[128];
         fatalf("Unable to generate signing SSL certificate for untrusted sites for %s_port %s", AnyP::ProtocolType_str[transport.protocol], s.toUrl(buf, sizeof(buf)));
     }
 
     if (crlfile)
         clientVerifyCrls.reset(Ssl::loadCrl(crlfile, sslContextFlags));
 
     if (clientca) {
         clientCA.reset(SSL_load_client_CA_file(clientca));
         if (clientCA.get() == NULL) {
             fatalf("Unable to read client CAs! from %s", clientca);
         }
     }
 
-    contextMethod = Ssl::contextMethod(version);
-    if (!contextMethod)
-        fatalf("Unable to compute context method to use");
+    // backward compatibility hack for sslversion= configuration
+    if (version > 2) {
+        const char *add = NULL;
+        switch (version) {
+        case 3:
+            add = "NO_TLSv1,NO_TLSv1_1,NO_TLSv1_2";
+            break;
+        case 4:
+            add = "NO_SSLv3,NO_TLSv1_1,NO_TLSv1_2";
+            break;
+        case 5:
+            add = "NO_SSLv3,NO_TLSv1,NO_TLSv1_2";
+            break;
+        case 6:
+            add = "NO_SSLv3,NO_TLSv1,NO_TLSv1_1";
+            break;
+        default: // nothing
+            break;
+        }
+        if (add) {
+            SBuf tmpOpts;
+            if (options) {
+                tmpOpts.append(options, strlen(options));
+                tmpOpts.append(",",1);
+            }
+            tmpOpts.append(add, strlen(add));
+            xfree(options);
+            options = xstrdup(tmpOpts.c_str());
+        }
+        version = 0; // prevent options being repeatedly appended
+    }
+
+    contextMethod = SSLv23_server_method();
 
     if (dhfile)
         dhParams.reset(Ssl::readDHParams(dhfile));
 
     if (sslflags)
         sslContextFlags = Ssl::parse_flags(sslflags);
 
     sslOptions = Ssl::parse_options(options);
 
     staticSslContext.reset(sslCreateServerContext(*this));
 
     if (!staticSslContext) {
         char buf[128];
         fatalf("%s_port %s initialization error", AnyP::ProtocolType_str[transport.protocol],  s.toUrl(buf, sizeof(buf)));
     }
 }
 #endif
 

=== modified file 'src/cache_cf.cc'
--- src/cache_cf.cc	2015-02-26 10:25:12 +0000
+++ src/cache_cf.cc	2015-05-14 22:36:44 +0000
@@ -2177,41 +2177,47 @@
             p->standby.limit = xatoi(token + 8);
         } else if (!strcmp(token, "originserver")) {
             p->options.originserver = true;
         } else if (!strncmp(token, "name=", 5)) {
             safe_free(p->name);
 
             if (token[5])
                 p->name = xstrdup(token + 5);
         } else if (!strncmp(token, "forceddomain=", 13)) {
             safe_free(p->domain);
             if (token[13])
                 p->domain = xstrdup(token + 13);
 
         } else if (strncmp(token, "ssl", 3) == 0) {
 #if !USE_OPENSSL
             debugs(0, DBG_CRITICAL, "WARNING: cache_peer option '" << token << "' requires --with-openssl");
 #else
             p->secure.encryptTransport = true;
             p->secure.parse(token+3);
 #endif
-
+        } else if (strncmp(token, "tls-", 4) == 0) {
+#if !USE_OPENSSL
+            debugs(0, DBG_CRITICAL, "WARNING: cache_peer option '" << token << "' requires --with-openssl");
+#else
+            p->secure.encryptTransport = true;
+            p->secure.parse(token+4);
+#endif
         } else if (strcmp(token, "front-end-https") == 0) {
             p->front_end_https = 1;
         } else if (strcmp(token, "front-end-https=on") == 0) {
             p->front_end_https = 1;
         } else if (strcmp(token, "front-end-https=auto") == 0) {
             p->front_end_https = 2;
         } else if (strcmp(token, "connection-auth=off") == 0) {
             p->connection_auth = 0;
         } else if (strcmp(token, "connection-auth") == 0) {
             p->connection_auth = 1;
         } else if (strcmp(token, "connection-auth=on") == 0) {
             p->connection_auth = 1;
         } else if (strcmp(token, "connection-auth=auto") == 0) {
             p->connection_auth = 2;
         } else if (token[0] == '#') {
             // start of a text comment. stop reading this line.
             break;
         } else {
             debugs(3, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Ignoring unknown cache_peer option '" << token << "'");
         }
@@ -3564,42 +3570,44 @@
             t = strchr(t, ',');
         }
         if (t) {
             ++t;
             s->tcp_keepalive.timeout = xatoui(t);
         }
 #if USE_OPENSSL
     } else if (strcmp(token, "sslBump") == 0) {
         debugs(3, DBG_CRITICAL, "WARNING: '" << token << "' is deprecated " <<
                "in " << cfg_directive << ". Use 'ssl-bump' instead.");
         s->flags.tunnelSslBumping = true;
     } else if (strcmp(token, "ssl-bump") == 0) {
         s->flags.tunnelSslBumping = true;
     } else if (strncmp(token, "cert=", 5) == 0) {
         safe_free(s->cert);
         s->cert = xstrdup(token + 5);
     } else if (strncmp(token, "key=", 4) == 0) {
         safe_free(s->key);
         s->key = xstrdup(token + 4);
     } else if (strncmp(token, "version=", 8) == 0) {
+        debugs(3, DBG_PARSE_NOTE(1), "UPGRADE WARNING: '" << token << "' is deprecated " <<
+               "in " << cfg_directive << ". Use 'options=' instead.");
         s->version = xatoi(token + 8);
-        if (s->version < 1 || s->version > 4)
+        if (s->version < 1 || s->version > 6)
             self_destruct();
     } else if (strncmp(token, "options=", 8) == 0) {
         safe_free(s->options);
         s->options = xstrdup(token + 8);
     } else if (strncmp(token, "cipher=", 7) == 0) {
         safe_free(s->cipher);
         s->cipher = xstrdup(token + 7);
     } else if (strncmp(token, "clientca=", 9) == 0) {
         safe_free(s->clientca);
         s->clientca = xstrdup(token + 9);
     } else if (strncmp(token, "cafile=", 7) == 0) {
         safe_free(s->cafile);
         s->cafile = xstrdup(token + 7);
     } else if (strncmp(token, "capath=", 7) == 0) {
         safe_free(s->capath);
         s->capath = xstrdup(token + 7);
     } else if (strncmp(token, "crlfile=", 8) == 0) {
         safe_free(s->crlfile);
         s->crlfile = xstrdup(token + 8);
     } else if (strncmp(token, "dhparams=", 9) == 0) {
@@ -3790,43 +3798,40 @@
         storeAppendPrintf(e, " ipv4");
 
     if (s->tcp_keepalive.enabled) {
         if (s->tcp_keepalive.idle || s->tcp_keepalive.interval || s->tcp_keepalive.timeout) {
             storeAppendPrintf(e, " tcpkeepalive=%d,%d,%d", s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout);
         } else {
             storeAppendPrintf(e, " tcpkeepalive");
         }
     }
 
 #if USE_OPENSSL
     if (s->flags.tunnelSslBumping)
         storeAppendPrintf(e, " ssl-bump");
 
     if (s->cert)
         storeAppendPrintf(e, " cert=%s", s->cert);
 
     if (s->key)
         storeAppendPrintf(e, " key=%s", s->key);
 
-    if (s->version)
-        storeAppendPrintf(e, " version=%d", s->version);
-
     if (s->options)
         storeAppendPrintf(e, " options=%s", s->options);
 
     if (s->cipher)
         storeAppendPrintf(e, " cipher=%s", s->cipher);
 
     if (s->cafile)
         storeAppendPrintf(e, " cafile=%s", s->cafile);
 
     if (s->capath)
         storeAppendPrintf(e, " capath=%s", s->capath);
 
     if (s->crlfile)
         storeAppendPrintf(e, " crlfile=%s", s->crlfile);
 
     if (s->dhfile)
         storeAppendPrintf(e, " dhparams=%s", s->dhfile);
 
     if (s->sslflags)
         storeAppendPrintf(e, " sslflags=%s", s->sslflags);

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2015-05-08 08:11:53 +0000
+++ src/cf.data.pre	2015-05-14 22:54:04 +0000
@@ -183,41 +183,41 @@
 TYPE: obsolete
 DOC_START
 	Remove this line. Use tls_outgoing_options key= instead.
 DOC_END
 
 NAME: sslproxy_flags
 TYPE: obsolete
 DOC_START
 	Remove this line. Use tls_outgoing_options flags= instead.
 DOC_END
 
 NAME: sslproxy_options
 TYPE: obsolete
 DOC_START
 	Remove this line. Use tls_outgoing_options options= instead.
 DOC_END
 
 NAME: sslproxy_version
 TYPE: obsolete
 DOC_START
-	Remove this line. Use tls_outgoing_options version= instead.
+	Remove this line. Use tls_outgoing_options options= instead.
 DOC_END
 
 # Options removed in 3.5
 NAME: hierarchy_stoplist
 TYPE: obsolete
 DOC_START
 	Remove this line. Use always_direct or cache_peer_access ACLs instead if you need to prevent cache_peer use.
 DOC_END
 
 # Options removed in 3.4
 NAME: log_access
 TYPE: obsolete
 DOC_START
 	Remove this line. Use acls with access_log directives to control access logging
 DOC_END
 
 NAME: log_icap
 TYPE: obsolete
 DOC_START
 	Remove this line. Use acls with icap_log directives to control icap logging
@@ -1897,47 +1897,40 @@
 			certificate equals lifetime of the CA certificate. If
 			generated certificate is selfsigned lifetime is three 
 			years.
 			This option is enabled by default when ssl-bump is used.
 			See the ssl-bump option above for more information.
 			
 	   dynamic_cert_mem_cache_size=SIZE
 			Approximate total RAM size spent on cached generated
 			certificates. If set to zero, caching is disabled. The
 			default value is 4MB.
 
 	TLS / SSL Options:
 
 	   cert=	Path to SSL certificate (PEM format).
 
 	   key=		Path to SSL private key file (PEM format)
 			if not specified, the certificate file is
 			assumed to be a combined certificate and
 			key file.
 
-	   version=	The version of SSL/TLS supported
-			    1	automatic (default)
-			    3	SSLv3 only
-			    4	TLSv1.0 only
-			    5	TLSv1.1 only
-			    6	TLSv1.2 only
-
 	   cipher=	Colon separated list of supported ciphers.
 			NOTE: some ciphers such as EDH ciphers depend on
 			      additional settings. If those settings are
 			      omitted the ciphers may be silently ignored
 			      by the OpenSSL library.
 
 	   options=	Various SSL implementation options. The most important
 			being:
 
 			    NO_SSLv3    Disallow the use of SSLv3
 
 			    NO_TLSv1    Disallow the use of TLSv1.0
 
 			    NO_TLSv1_1  Disallow the use of TLSv1.1
 
 			    NO_TLSv1_2  Disallow the use of TLSv1.2
 
 			    SINGLE_DH_USE
 				      Always create a new key when using
 				      temporary/ephemeral DH key exchanges
@@ -2083,45 +2076,40 @@
 			An "ssl_bump server-first" match is required to
 			fully enable bumping of intercepted SSL	connections.
 
 			Requires tproxy or intercept.
 
 	Omitting the mode flag causes default forward proxy mode to be used.
 
 
 	See http_port for a list of generic options
 
 
 	SSL Options:
 
 	   cert=	Path to SSL certificate (PEM format).
 
 	   key=		Path to SSL private key file (PEM format)
 			if not specified, the certificate file is
 			assumed to be a combined certificate and
 			key file.
 
-	   version=	The version of SSL/TLS supported
-			    1	automatic (default)
-			    3	SSLv3 only
-			    4	TLSv1 only
-
 	   cipher=	Colon separated list of supported ciphers.
 
 	   options=	Various SSL engine options. The most important
 			being:
 
 			    NO_SSLv3    Disallow the use of SSLv3
 
 			    NO_TLSv1    Disallow the use of TLSv1.0
 
 			    NO_TLSv1_1  Disallow the use of TLSv1.1
 
 			    NO_TLSv1_2  Disallow the use of TLSv1.2
 
 			    SINGLE_DH_USE
 				      Always create a new key when using
 				      temporary/ephemeral DH key exchanges
 
 			    SSL_OP_NO_TICKET
 				      Disable use of RFC5077 session tickets.
 				      Some servers may have problems
@@ -2583,50 +2571,47 @@
  TLS OPTIONS
  -----------------------------------------------------------------------------
 COMMENT_END
 
 NAME: tls_outgoing_options
 IFDEF: USE_GNUTLS||USE_OPENSSL
 TYPE: securePeerOptions
 DEFAULT: disable
 LOC: Security::ProxyOutgoingConfig
 DOC_START
 	disable		Do not support https:// URLs.
 	
 	cert=/path/to/client/certificate
 			A client TLS certificate to use when connecting.
 	
 	key=/path/to/client/private_key
 			The private TLS key corresponding to the cert= above.
 			If key= is not specified cert= is assumed to reference
 			a PEM file containing both the certificate and the key.
 	
-	version=1|3|4|5|6
-			The TLS/SSL version to use when connecting
-				1 = automatic (default)
-				3 = SSL v3 only
-				4 = TLS v1.0 only
-				5 = TLS v1.1 only
-				6 = TLS v1.2 only
-	
 	cipher=...	The list of valid TLS ciphers to use.
-	
+
+	min-version=1.N
+			The minimum TLS protocol version to permit. To control
+			SSLv3 use the options= parameter.
+			Supported Values: 1.0 (default), 1.1, 1.2
+
 	options=... 	Specify various TLS/SSL implementation options:
 
 			    NO_SSLv3    Disallow the use of SSLv3
 
 			    NO_TLSv1    Disallow the use of TLSv1.0
 
 			    NO_TLSv1_1  Disallow the use of TLSv1.1
 
 			    NO_TLSv1_2  Disallow the use of TLSv1.2
 
 			    SINGLE_DH_USE
 				      Always create a new key when using
 				      temporary/ephemeral DH key exchanges
 
 			    SSL_OP_NO_TICKET
 				      Disable use of RFC5077 session tickets.
 				      Some servers may have problems
 				      understanding the TLS extension due
 				      to ambiguous specification in RFC4507.
 
@@ -3322,51 +3307,48 @@
 			connection oriented authentication, and any such
 			challenges received from there should be ignored.
 			Default is auto to automatically determine the status
 			of the peer.
 	
 	
 	==== SSL / HTTPS / TLS OPTIONS ====
 	
 	ssl		Encrypt connections to this peer with SSL/TLS.
 	
 	sslcert=/path/to/ssl/certificate
 			A client SSL certificate to use when connecting to
 			this peer.
 	
 	sslkey=/path/to/ssl/key
 			The private SSL key corresponding to sslcert above.
 			If 'sslkey' is not specified 'sslcert' is assumed to
 			reference a combined file containing both the
 			certificate and the key.
 	
-	sslversion=1|3|4|5|6
-			The SSL version to use when connecting to this peer
-				1 = automatic (default)
-				3 = SSL v3 only
-				4 = TLS v1.0 only
-				5 = TLS v1.1 only
-				6 = TLS v1.2 only
-	
 	sslcipher=...	The list of valid SSL ciphers to use when connecting
 			to this peer.
-	
+
+	tls-min-version=1.N
+			The minimum TLS protocol version to permit. To control
+			SSLv3 use the ssloptions= parameter.
+			Supported Values: 1.0 (default), 1.1, 1.2
+
 	ssloptions=... 	Specify various SSL implementation options:
 
 			    NO_SSLv3    Disallow the use of SSLv3
 
 			    NO_TLSv1    Disallow the use of TLSv1.0
 
 			    NO_TLSv1_1  Disallow the use of TLSv1.1
 
 			    NO_TLSv1_2  Disallow the use of TLSv1.2
 
 			    SINGLE_DH_USE
 				      Always create a new key when using
 				      temporary/ephemeral DH key exchanges
 
 			    SSL_OP_NO_TICKET
 				      Disable use of RFC5077 session tickets.
 				      Some servers may have problems
 				      understanding the TLS extension due
 				      to ambiguous specification in RFC4507.
 
@@ -8481,52 +8463,48 @@
 		
 
 	max-conn=number
 		Use the given number as the Max-Connections limit, regardless
 		of the Max-Connections value given by the service, if any.
 
 	==== SSL / ICAPS / TLS OPTIONS ====
 
 	These options are used for Secure ICAP (icaps://....) services only.
 
 	sslcert=/path/to/ssl/certificate
 			A client SSL certificate to use when connecting to
 			this icap server.
 
 	sslkey=/path/to/ssl/key
 			The private SSL key corresponding to sslcert above.
 			If 'sslkey' is not specified 'sslcert' is assumed to
 			reference a combined file containing both the
 			certificate and the key.
 
-	sslversion=1|3|4|5|6
-			The SSL version to use when connecting to this icap
-			server
-				1 = automatic (default)
-				3 = SSL v3 only
-				4 = TLS v1.0 only
-				5 = TLS v1.1 only
-				6 = TLS v1.2 only
-
 	sslcipher=...	The list of valid SSL ciphers to use when connecting
 			to this icap server.
 
+	tls-min-version=1.N
+			The minimum TLS protocol version to permit. To control
+			SSLv3 use the ssloptions= parameter.
+			Supported Values: 1.0 (default), 1.1, 1.2
+
 	ssloptions=...	Specify various SSL implementation options:
 
 			    NO_SSLv3    Disallow the use of SSLv3
 			    NO_TLSv1    Disallow the use of TLSv1.0
 			    NO_TLSv1_1  Disallow the use of TLSv1.1
 			    NO_TLSv1_2  Disallow the use of TLSv1.2
 			    SINGLE_DH_USE
 				      Always create a new key when using
 				      temporary/ephemeral DH key exchanges
 			    ALL       Enable various bug workarounds
 			    suggested as "harmless" by OpenSSL
 			    Be warned that this reduces SSL/TLS
 			    strength to some attacks.
 
 			See the OpenSSL SSL_CTX_set_options documentation for a
 			more complete list.
 
 	sslcafile=...	A file containing additional CA certificates to use
 			when verifying the icap server certificate.
 

=== modified file 'src/security/PeerOptions.cc'
--- src/security/PeerOptions.cc	2015-02-26 12:12:11 +0000
+++ src/security/PeerOptions.cc	2015-05-14 23:52:12 +0000
@@ -1,80 +1,130 @@
 /*
  * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #include "squid.h"
 #include "Debug.h"
 #include "globals.h"
+#include "parser/Tokenizer.h"
 #include "Parsing.h"
 #include "security/PeerOptions.h"
 
 #if USE_OPENSSL
 #include "ssl/support.h"
 #endif
 
 Security::PeerOptions Security::ProxyOutgoingConfig;
 
 void
 Security::PeerOptions::parse(const char *token)
 {
     if (strncmp(token, "cert=", 5) == 0) {
         certFile = SBuf(token + 5);
         if (privateKeyFile.isEmpty())
             privateKeyFile = certFile;
     } else if (strncmp(token, "key=", 4) == 0) {
         privateKeyFile = SBuf(token + 4);
         if (certFile.isEmpty()) {
             debugs(0, DBG_PARSE_NOTE(1), "WARNING: cert= option needs to be set before key= is used.");
             certFile = privateKeyFile;
         }
     } else if (strncmp(token, "version=", 8) == 0) {
+        debugs(0, DBG_PARSE_NOTE(1), "UPGRADE WARNING: SSL version= is deprecated. Use options= to limit protocols instead.");
         sslVersion = xatoi(token + 8);
+    } else if (strncmp(token, "min-version=", 12) == 0) {
+        tlsMinVersion = SBuf(token + 12);
     } else if (strncmp(token, "options=", 8) == 0) {
         sslOptions = SBuf(token + 8);
 #if USE_OPENSSL
         // Pre-parse SSL client options to be applied when the client SSL objects created.
         // Options must not used in the case of peek or stare bump mode.
         // XXX: performance regression. c_str() can reallocate
         parsedOptions = Ssl::parse_options(sslOptions.c_str());
 #endif
     } else if (strncmp(token, "cipher=", 7) == 0) {
         sslCipher = SBuf(token + 7);
     } else if (strncmp(token, "cafile=", 7) == 0) {
         caFile = SBuf(token + 7);
     } else if (strncmp(token, "capath=", 7) == 0) {
         caDir = SBuf(token + 7);
     } else if (strncmp(token, "crlfile=", 8) == 0) {
         crlFile = SBuf(token + 8);
     } else if (strncmp(token, "flags=", 6) == 0) {
         sslFlags = SBuf(token + 6);
     } else if (strncmp(token, "domain=", 7) == 0) {
         sslDomain = SBuf(token + 7);
     }
 }
 
 // XXX: make a GnuTLS variant
 Security::ContextPointer
 Security::PeerOptions::createContext(bool setOptions)
 {
     Security::ContextPointer t = NULL;
 
+    if (!tlsMinVersion.isEmpty()) {
+        ::Parser::Tokenizer tok(tlsMinVersion);
+        int64_t v = 0;
+        if (tok.skip('1') && tok.skip('.') && tok.int64(v, 10, false, 1) && v <= 2) {
+            // only account for TLS here - SSL versions are handled by options= parameter
+            if (v > 0)
+                sslOptions.append(",NO_TLSv1",9);
+            if (v > 1)
+                sslOptions.append(",NO_TLSv1_1",11);
+            if (v > 2)
+                sslOptions.append(",NO_TLSv1_2",11);
+
+        } else {
+            debugs(0, DBG_PARSE_NOTE(1), "WARNING: Unknown TLS minimum version: " << tlsMinVersion);
+        }
+
+    } else if (sslVersion > 2) {
+        // backward compatibility hack for sslversion= configuration
+        // only use if tls-min-version=N.N is not present
+
+        const char *add = NULL;
+        switch (sslVersion) {
+        case 3:
+            add = "NO_TLSv1,NO_TLSv1_1,NO_TLSv1_2";
+            break;
+        case 4:
+            add = "NO_SSLv3,NO_TLSv1_1,NO_TLSv1_2";
+            break;
+        case 5:
+            add = "NO_SSLv3,NO_TLSv1,NO_TLSv1_2";
+            break;
+        case 6:
+            add = "NO_SSLv3,NO_TLSv1,NO_TLSv1_1";
+            break;
+        default: // nothing
+            break;
+        }
+        if (add) {
+            if (!sslOptions.isEmpty())
+                sslOptions.append(",",1);
+            sslOptions.append(add, strlen(add));
+        }
+        sslVersion = 0; // prevent sslOptions being repeatedly appended
+    }
+
 #if USE_OPENSSL
     // XXX: temporary performance regression. c_str() data copies and prevents this being a const method
-    t = sslCreateClientContext(certFile.c_str(), privateKeyFile.c_str(), sslVersion, sslCipher.c_str(),
-                               (setOptions ? sslOptions.c_str() : NULL), sslFlags.c_str(), caFile.c_str(), caDir.c_str(), crlFile.c_str());
+    t = sslCreateClientContext(certFile.c_str(), privateKeyFile.c_str(), sslCipher.c_str(),
+                               (setOptions ? sslOptions.c_str() : NULL), sslFlags.c_str(),
+                               caFile.c_str(), caDir.c_str(), crlFile.c_str());
 #endif
 
     return t;
 }
 
 void
 parse_securePeerOptions(Security::PeerOptions *opt)
 {
     while(const char *token = ConfigParser::NextToken())
         opt->parse(token);
 }
 

=== modified file 'src/security/PeerOptions.h'
--- src/security/PeerOptions.h	2015-03-20 15:10:07 +0000
+++ src/security/PeerOptions.h	2015-05-14 22:50:10 +0000
@@ -25,40 +25,44 @@
     /// parse a TLS squid.conf option
     void parse(const char *);
 
     /// reset the configuration details to default
     void clear() {*this = PeerOptions();}
 
     /// generate a security context from these configured options
     Security::ContextPointer createContext(bool setOptions);
 
     SBuf certFile;       ///< path of file containing PEM format X509 certificate
     SBuf privateKeyFile; ///< path of file containing private key in PEM format
     SBuf sslOptions;     ///< library-specific options string
     SBuf caFile;         ///< path of file containing trusted Certificate Authority
     SBuf caDir;          ///< path of directory containing a set of trusted Certificate Authorities
     SBuf crlFile;        ///< path of file containing Certificate Revoke List
 
     SBuf sslCipher;
     SBuf sslFlags;
     SBuf sslDomain;
 
+    SBuf tlsMinVersion;  ///< version label for minimum TLS version to permit
+
     long parsedOptions; ///< parsed value of sslOptions
 
+private:
     int sslVersion;
 
+public:
     /// whether transport encryption (TLS/SSL) is to be used on connections to the peer
     bool encryptTransport;
 };
 
 /// configuration options for DIRECT server access
 extern PeerOptions ProxyOutgoingConfig;
 
 } // namespace Security
 
 // parse the tls_outgoing_options directive
 void parse_securePeerOptions(Security::PeerOptions *);
 #define free_securePeerOptions(x) Security::ProxyOutgoingConfig.clear()
 #define dump_securePeerOptions(e,n,x) // not supported yet
 
 #endif /* SQUID_SRC_SECURITY_PEEROPTIONS_H */
 

=== modified file 'src/ssl/bio.cc'
--- src/ssl/bio.cc	2015-05-08 11:18:30 +0000
+++ src/ssl/bio.cc	2015-05-08 11:37:37 +0000
@@ -1129,41 +1129,40 @@
     memcpy(client_random, ciphers + ciphersLen, SSL3_RANDOM_SIZE);
     debugs(83, 7, "Client random: " <<  objToString(client_random, SSL3_RANDOM_SIZE));
 
     compressMethod = 0;
     return true;
 #else
     return false;
 #endif
 }
 
 void
 Ssl::Bio::sslFeatures::applyToSSL(SSL *ssl, Ssl::BumpMode bumpMode) const
 {
     // To increase the possibility for bumping after peek mode selection or
     // splicing after stare mode selection it is good to set the
     // SSL protocol version.
     // The SSL_set_ssl_method is not the correct method because it will strict
     // SSL version which can be used to the SSL version used for client hello message.
     // For example will prevent comunnicating with a tls1.0 server if the
     // client sent and tlsv1.2 Hello message.
-    //SSL_set_ssl_method(ssl, Ssl::clientMethod(features.toSquidSSLVersion()));
 #if defined(TLSEXT_NAMETYPE_host_name)
     if (!serverName.isEmpty()) {
         SSL_set_tlsext_host_name(ssl, serverName.c_str());
     }
 #endif
     if (!clientRequestedCiphers.empty())
         SSL_set_cipher_list(ssl, clientRequestedCiphers.c_str());
 #if defined(SSL_OP_NO_COMPRESSION) /* XXX: OpenSSL 0.9.8k lacks SSL_OP_NO_COMPRESSION */
     if (compressMethod == 0)
         SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
 #endif
 
 #if defined(TLSEXT_STATUSTYPE_ocsp)
     if (tlsStatusRequest)
         SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp);
 #endif
 
 #if defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
     if (!tlsAppLayerProtoNeg.isEmpty()) {
         if (bumpMode == Ssl::bumpPeek)

=== modified file 'src/ssl/support.cc'
--- src/ssl/support.cc	2015-05-08 11:18:30 +0000
+++ src/ssl/support.cc	2015-05-08 15:17:21 +0000
@@ -901,54 +901,53 @@
         debugs(83, 9, "Not requiring any client certificates");
         SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
     }
 
     if (port.dhParams.get()) {
         SSL_CTX_set_tmp_dh(sslContext, port.dhParams.get());
     }
 
     if (port.sslContextFlags & SSL_FLAG_DONT_VERIFY_DOMAIN)
         SSL_CTX_set_ex_data(sslContext, ssl_ctx_ex_index_dont_verify_domain, (void *) -1);
 
     setSessionCallbacks(sslContext);
 
     return true;
 }
 
 SSL_CTX *
 sslCreateServerContext(AnyP::PortCfg &port)
 {
     int ssl_error;
-    SSL_CTX *sslContext;
     const char *keyfile, *certfile;
     certfile = port.cert;
     keyfile = port.key;
 
     ssl_initialize();
 
     if (!keyfile)
         keyfile = certfile;
 
     if (!certfile)
         certfile = keyfile;
 
-    sslContext = SSL_CTX_new(port.contextMethod);
+    SSL_CTX *sslContext = SSL_CTX_new(port.contextMethod);
 
     if (sslContext == NULL) {
         ssl_error = ERR_get_error();
         debugs(83, DBG_CRITICAL, "ERROR: Failed to allocate SSL context: " << ERR_error_string(ssl_error, NULL));
         return NULL;
     }
 
     if (!SSL_CTX_use_certificate(sslContext, port.signingCert.get())) {
         ssl_error = ERR_get_error();
         debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << certfile << "': " << ERR_error_string(ssl_error, NULL));
         SSL_CTX_free(sslContext);
         return NULL;
     }
 
     if (!SSL_CTX_use_PrivateKey(sslContext, port.signPkey.get())) {
         ssl_error = ERR_get_error();
         debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << keyfile << "': " << ERR_error_string(ssl_error, NULL));
         SSL_CTX_free(sslContext);
         return NULL;
     }
@@ -996,173 +995,60 @@
 }
 
 int Ssl::OpenSSLtoSquidSSLVersion(int sslVersion)
 {
     if (sslVersion == SSL2_VERSION)
         return 2;
     else if (sslVersion == SSL3_VERSION)
         return 3;
     else if (sslVersion == TLS1_VERSION)
         return 4;
 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
     else if (sslVersion == TLS1_1_VERSION)
         return 5;
     else if (sslVersion == TLS1_2_VERSION)
         return 6;
 #endif
     else
         return 1;
 }
 
-#if OPENSSL_VERSION_NUMBER < 0x00909000L
-SSL_METHOD *
-#else
-const SSL_METHOD *
-#endif
-Ssl::clientMethod(int version)
-{
-    switch (version) {
-
-    case 2:
-        debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy.");
-        return NULL;
-        break;
-
-    case 3:
-        debugs(83, 5, "Using SSLv3.");
-        return SSLv3_client_method();
-        break;
-
-    case 4:
-        debugs(83, 5, "Using TLSv1.");
-        return TLSv1_client_method();
-        break;
-
-    case 5:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L  // NP: not sure exactly which sub-version yet.
-        debugs(83, 5, "Using TLSv1.1.");
-        return TLSv1_1_client_method();
-#else
-        debugs(83, DBG_IMPORTANT, "TLSv1.1 is not available in this Proxy.");
-        return NULL;
-#endif
-        break;
-
-    case 6:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
-        debugs(83, 5, "Using TLSv1.2");
-        return TLSv1_2_client_method();
-#else
-        debugs(83, DBG_IMPORTANT, "TLSv1.2 is not available in this Proxy.");
-        return NULL;
-#endif
-        break;
-
-    case 1:
-
-    default:
-        debugs(83, 5, "Using SSLv2/SSLv3.");
-        return SSLv23_client_method();
-        break;
-    }
-
-    //Not reached
-    return NULL;
-}
-
-const SSL_METHOD *
-Ssl::serverMethod(int version)
-{
-    switch (version) {
-
-    case 2:
-        debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy.");
-        return NULL;
-        break;
-
-    case 3:
-        debugs(83, 5, "Using SSLv3.");
-        return SSLv3_server_method();
-        break;
-
-    case 4:
-        debugs(83, 5, "Using TLSv1.");
-        return TLSv1_server_method();
-        break;
-
-    case 5:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L  // NP: not sure exactly which sub-version yet.
-        debugs(83, 5, "Using TLSv1.1.");
-        return TLSv1_1_server_method();
-#else
-        debugs(83, DBG_IMPORTANT, "TLSv1.1 is not available in this Proxy.");
-        return NULL;
-#endif
-        break;
-
-    case 6:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
-        debugs(83, 5, "Using TLSv1.2");
-        return TLSv1_2_server_method();
-#else
-        debugs(83, DBG_IMPORTANT, "TLSv1.2 is not available in this Proxy.");
-        return NULL;
-#endif
-        break;
-
-    case 1:
-
-    default:
-        debugs(83, 5, "Using SSLv2/SSLv3.");
-        return SSLv23_server_method();
-        break;
-    }
-
-    //Not reached
-    return NULL;
-}
-
 #if defined(TLSEXT_TYPE_next_proto_neg)
 //Dummy next_proto_neg callback
 static int
 ssl_next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
 {
     static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
     (void)SSL_select_next_proto(out, outlen, in, inlen, supported_protos, sizeof(supported_protos));
     return SSL_TLSEXT_ERR_OK;
 }
 #endif
 
 SSL_CTX *
-sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile)
+sslCreateClientContext(const char *certfile, const char *keyfile, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile)
 {
     int ssl_error;
-    Ssl::ContextMethod method;
-    SSL_CTX * sslContext;
     long fl = Ssl::parse_flags(flags);
 
     ssl_initialize();
 
-    if (!(method = Ssl::clientMethod(version)))
-        return NULL;
-
-    sslContext = SSL_CTX_new(method);
+    SSL_CTX *sslContext = SSL_CTX_new(SSLv23_client_method());
 
     if (sslContext == NULL) {
         ssl_error = ERR_get_error();
         fatalf("Failed to allocate SSL context: %s\n",
                ERR_error_string(ssl_error, NULL));
     }
 
     SSL_CTX_set_options(sslContext, Ssl::parse_options(options));
 
     if (*cipher) {
         debugs(83, 5, "Using chiper suite " << cipher << ".");
 
         if (!SSL_CTX_set_cipher_list(sslContext, cipher)) {
             ssl_error = ERR_get_error();
             fatalf("Failed to set SSL cipher suite '%s': %s\n",
                    cipher, ERR_error_string(ssl_error, NULL));
         }
     }
 
     if (*certfile) {
@@ -1461,92 +1347,40 @@
         return sslGetUserCertificatePEM(ssl);
 
     mem = BIO_new(BIO_s_mem());
 
     for (i = 0; i < sk_X509_num(chain); ++i) {
         X509 *cert = sk_X509_value(chain, i);
         PEM_write_bio_X509(mem, cert);
     }
 
     len = BIO_get_mem_data(mem, &ptr);
 
     str = (char *)xmalloc(len + 1);
     memcpy(str, ptr, len);
     str[len] = '\0';
 
     BIO_free(mem);
 
     return str;
 }
 
-Ssl::ContextMethod
-Ssl::contextMethod(int version)
-{
-    Ssl::ContextMethod method;
-
-    switch (version) {
-
-    case 2:
-        debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy.");
-        return NULL;
-        break;
-
-    case 3:
-        debugs(83, 5, "Using SSLv3.");
-        method = SSLv3_server_method();
-        break;
-
-    case 4:
-        debugs(83, 5, "Using TLSv1.");
-        method = TLSv1_server_method();
-        break;
-
-    case 5:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L  // NP: not sure exactly which sub-version yet.
-        debugs(83, 5, "Using TLSv1.1.");
-        method = TLSv1_1_server_method();
-#else
-        debugs(83, DBG_IMPORTANT, "TLSv1.1 is not available in this Proxy.");
-        return NULL;
-#endif
-        break;
-
-    case 6:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version yet.
-        debugs(83, 5, "Using TLSv1.2");
-        method = TLSv1_2_server_method();
-#else
-        debugs(83, DBG_IMPORTANT, "TLSv1.2 is not available in this Proxy.");
-        return NULL;
-#endif
-        break;
-
-    case 1:
-
-    default:
-        debugs(83, 5, "Using SSLv2/SSLv3.");
-        method = SSLv23_server_method();
-        break;
-    }
-    return method;
-}
-
 /// \ingroup ServerProtocolSSLInternal
 /// Create SSL context and apply ssl certificate and private key to it.
 SSL_CTX *
 Ssl::createSSLContext(Ssl::X509_Pointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port)
 {
     Ssl::SSL_CTX_Pointer sslContext(SSL_CTX_new(port.contextMethod));
 
     if (!SSL_CTX_use_certificate(sslContext.get(), x509.get()))
         return NULL;
 
     if (!SSL_CTX_use_PrivateKey(sslContext.get(), pkey.get()))
         return NULL;
 
     if (!configureSslContext(sslContext.get(), port))
         return NULL;
 
     return sslContext.release();
 }
 
 SSL_CTX *

=== modified file 'src/ssl/support.h'
--- src/ssl/support.h	2015-05-08 11:18:30 +0000
+++ src/ssl/support.h	2015-05-08 15:16:19 +0000
@@ -75,41 +75,41 @@
 {
 public:
     ssl_error_t code; ///< certificate error code
     X509_Pointer cert; ///< certificate with the above error code
     CertError(ssl_error_t anErr, X509 *aCert);
     CertError(CertError const &err);
     CertError & operator = (const CertError &old);
     bool operator == (const CertError &ce) const;
     bool operator != (const CertError &ce) const;
 };
 
 /// Holds a list of certificate SSL errors
 typedef CbDataList<Ssl::CertError> CertErrors;
 
 } //namespace Ssl
 
 /// \ingroup ServerProtocolSSLAPI
 SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port);
 
 /// \ingroup ServerProtocolSSLAPI
-SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile);
+SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile);
 
 /// \ingroup ServerProtocolSSLAPI
 int ssl_read_method(int, char *, int);
 
 /// \ingroup ServerProtocolSSLAPI
 int ssl_write_method(int, const char *, int);
 
 /// \ingroup ServerProtocolSSLAPI
 void ssl_shutdown_method(SSL *ssl);
 
 /// \ingroup ServerProtocolSSLAPI
 const char *sslGetUserEmail(SSL *ssl);
 
 /// \ingroup ServerProtocolSSLAPI
 const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name);
 
 /// \ingroup ServerProtocolSSLAPI
 const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name);
 
 /// \ingroup ServerProtocolSSLAPI
@@ -165,46 +165,40 @@
 
 /**
  \ingroup ServerProtocolSSLAPI
  * Parses the SSL options.
  */
 long parse_options(const char *options);
 
 /**
  \ingroup ServerProtocolSSLAPI
  * Load a CRLs list stored in a file
  */
 STACK_OF(X509_CRL) *loadCrl(const char *CRLFile, long &flags);
 
 /**
  \ingroup ServerProtocolSSLAPI
  * Load DH params from file
  */
 DH *readDHParams(const char *dhfile);
 
 /**
- \ingroup ServerProtocolSSLAPI
- * Compute the Ssl::ContextMethod (SSL_METHOD) from SSL version
- */
-ContextMethod contextMethod(int version);
-
-/**
   \ingroup ServerProtocolSSLAPI
   * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA
 */
 bool generateUntrustedCert(X509_Pointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey);
 
 /**
   \ingroup ServerProtocolSSLAPI
   * Decide on the kind of certificate and generate a CA- or self-signed one
 */
 SSL_CTX * generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port);
 
 /**
   \ingroup ServerProtocolSSLAPI
   * Check if the certificate of the given context is still valid
   \param sslContext The context to check
   \param properties Check if the context certificate matches the given properties
   \return true if the contexts certificate is valid, false otherwise
  */
 bool verifySslCertificate(SSL_CTX * sslContext,  CertificateProperties const &properties);
 
@@ -273,47 +267,40 @@
 /**
    \ingroup ServerProtocolSSLAPI
    * Convert a given ASN1_TIME to a string form.
    \param tm the time in ASN1_TIME form
    \param buf the buffer to write the output
    \param len write at most len bytes
    \return The number of bytes written
  */
 int asn1timeToString(ASN1_TIME *tm, char *buf, int len);
 
 /**
    \ingroup ServerProtocolSSLAPI
    * Sets the hostname for the Server Name Indication (SNI) TLS extension
    * if supported by the used openssl toolkit.
    \return true if SNI set false otherwise
 */
 bool setClientSNI(SSL *ssl, const char *fqdn);
 
 int OpenSSLtoSquidSSLVersion(int sslVersion);
 
-#if OPENSSL_VERSION_NUMBER >= 0x00909000L
-const
-#endif
-SSL_METHOD *clientMethod(int version);
-
-const SSL_METHOD *serverMethod(int version);
-
 /**
    \ingroup ServerProtocolSSLAPI
    * Initializes the shared session cache if configured
 */
 void initialize_session_cache();
 
 /**
    \ingroup ServerProtocolSSLAPI
    * Destroy the shared session cache if configured
 */
 void destruct_session_cache();
 } //namespace Ssl
 
 #if _SQUID_WINDOWS_
 
 #if defined(__cplusplus)
 
 /** \cond AUTODOCS-IGNORE */
 namespace Squid
 {

=== modified file 'src/tests/stub_libsslsquid.cc'
--- src/tests/stub_libsslsquid.cc	2015-01-13 07:25:36 +0000
+++ src/tests/stub_libsslsquid.cc	2015-05-08 15:17:39 +0000
@@ -40,56 +40,55 @@
 void Ssl::GlobalContextStorage::reconfigureStart() STUB
 //Ssl::GlobalContextStorage Ssl::TheGlobalContextStorage;
 
 #include "ssl/ErrorDetail.h"
 Ssl::ssl_error_t parseErrorString(const char *name) STUB_RETVAL(0)
 //const char *Ssl::getErrorName(ssl_error_t value) STUB_RETVAL(NULL)
 Ssl::ErrorDetail::ErrorDetail(ssl_error_t err_no, X509 *, X509 *, const char *) STUB
 Ssl::ErrorDetail::ErrorDetail(ErrorDetail const &) STUB
 const String & Ssl::ErrorDetail::toString() const STUB_RETSTATREF(String)
 
 #include "ssl/support.h"
 namespace Ssl
 {
 //CertError::CertError(ssl_error_t anErr, X509 *aCert) STUB
 //CertError::CertError(CertError const &err) STUB
 CertError & CertError::operator = (const CertError &old) STUB_RETVAL(*this)
 bool CertError::operator == (const CertError &ce) const STUB_RETVAL(false)
 bool CertError::operator != (const CertError &ce) const STUB_RETVAL(false)
 } // namespace Ssl
 SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port) STUB_RETVAL(NULL)
-SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile) STUB_RETVAL(NULL)
+SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile) STUB_RETVAL(NULL)
 int ssl_read_method(int, char *, int) STUB_RETVAL(0)
 int ssl_write_method(int, const char *, int) STUB_RETVAL(0)
 void ssl_shutdown_method(SSL *ssl) STUB
 const char *sslGetUserEmail(SSL *ssl) STUB_RETVAL(NULL)
 const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name) STUB_RETVAL(NULL)
 const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name) STUB_RETVAL(NULL)
 const char *sslGetUserCertificatePEM(SSL *ssl) STUB_RETVAL(NULL)
 const char *sslGetUserCertificateChainPEM(SSL *ssl) STUB_RETVAL(NULL)
 namespace Ssl
 {
 //GETX509ATTRIBUTE GetX509UserAttribute;
 //GETX509ATTRIBUTE GetX509CAAttribute;
 //GETX509ATTRIBUTE GetX509Fingerprint;
 const char *BumpModeStr[] = {""};
 long parse_flags(const char *flags) STUB_RETVAL(0)
 long parse_options(const char *options) STUB_RETVAL(0)
 STACK_OF(X509_CRL) *loadCrl(const char *CRLFile, long &flags) STUB_RETVAL(NULL)
 DH *readDHParams(const char *dhfile) STUB_RETVAL(NULL)
-ContextMethod contextMethod(int version) STUB_RETVAL(ContextMethod())
 bool generateUntrustedCert(X509_Pointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey) STUB_RETVAL(false)
 SSL_CTX * generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port) STUB_RETVAL(NULL)
 bool verifySslCertificate(SSL_CTX * sslContext,  CertificateProperties const &properties) STUB_RETVAL(false)
 SSL_CTX * generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg &port) STUB_RETVAL(NULL)
 void addChainToSslContext(SSL_CTX *sslContext, STACK_OF(X509) *certList) STUB
 void readCertChainAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename) STUB
 int matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data,  ASN1_STRING *cn_data)) STUB_RETVAL(0)
 bool checkX509ServerValidity(X509 *cert, const char *server) STUB_RETVAL(false)
 int asn1timeToString(ASN1_TIME *tm, char *buf, int len) STUB_RETVAL(0)
 bool setClientSNI(SSL *ssl, const char *fqdn) STUB_RETVAL(false)
 void initialize_session_cache() STUB
 void destruct_session_cache() STUB
 } //namespace Ssl
 
 #endif
 



More information about the squid-dev mailing list