View | Details | Raw Unified | Return to bug 248856 | Differences between
and this patch

Collapse All | Expand All

(-)Makefile (-1 / +1 lines)
Lines 1-7 Link Here
1
# $FreeBSD$
1
# $FreeBSD$
2
2
3
PORTNAME=	squid
3
PORTNAME=	squid
4
PORTVERSION=	4.12
4
PORTVERSION=	4.13
5
CATEGORIES=	www
5
CATEGORIES=	www
6
MASTER_SITES=	http://www.squid-cache.org/Versions/v4/ \
6
MASTER_SITES=	http://www.squid-cache.org/Versions/v4/ \
7
		http://www2.us.squid-cache.org/Versions/v4/ \
7
		http://www2.us.squid-cache.org/Versions/v4/ \
(-)distinfo (-3 / +3 lines)
Lines 1-3 Link Here
1
TIMESTAMP = 1592288810
1
TIMESTAMP = 1598206369
2
SHA256 (squid-4.12.tar.xz) = f42a03c8b3dc020722c88bf1a87da8cb0c087b2f66b41d8256c77ee1b527e317
2
SHA256 (squid-4.13.tar.xz) = 6891a0f540e60779b4f24f1802a302f813c6f473ec7336a474ed68c3e2e53ee0
3
SIZE (squid-4.12.tar.xz) = 2450564
3
SIZE (squid-4.13.tar.xz) = 2452752
(-)files/patch-src_security_Handshake.cc (-147 lines)
Lines 1-147 Link Here
1
--- src/security/Handshake.cc.orig	2020-06-07 15:42:16 UTC
2
+++ src/security/Handshake.cc
3
@@ -9,6 +9,7 @@
4
 /* DEBUG: section 83    SSL-Bump Server/Peer negotiation */
5
 
6
 #include "squid.h"
7
+#include "sbuf/Stream.h"
8
 #include "security/Handshake.h"
9
 #if USE_OPENSSL
10
 #include "ssl/support.h"
11
@@ -104,25 +105,52 @@ class Extension (public)
12
 typedef std::unordered_set<Extension::Type> Extensions;
13
 static Extensions SupportedExtensions();
14
 
15
-} // namespace Security
16
-
17
 /// parse TLS ProtocolVersion (uint16) and convert it to AnyP::ProtocolVersion
18
+/// \retval PROTO_NONE for unsupported values (in relaxed mode)
19
 static AnyP::ProtocolVersion
20
-ParseProtocolVersion(Parser::BinaryTokenizer &tk, const char *contextLabel = ".version")
21
+ParseProtocolVersionBase(Parser::BinaryTokenizer &tk, const char *contextLabel, const bool beStrict)
22
 {
23
     Parser::BinaryTokenizerContext context(tk, contextLabel);
24
     uint8_t vMajor = tk.uint8(".major");
25
     uint8_t vMinor = tk.uint8(".minor");
26
+
27
     if (vMajor == 0 && vMinor == 2)
28
         return AnyP::ProtocolVersion(AnyP::PROTO_SSL, 2, 0);
29
 
30
-    Must(vMajor == 3);
31
-    if (vMinor == 0)
32
-        return AnyP::ProtocolVersion(AnyP::PROTO_SSL, 3, 0);
33
+    if (vMajor == 3) {
34
+        if (vMinor == 0)
35
+            return AnyP::ProtocolVersion(AnyP::PROTO_SSL, 3, 0);
36
+        return AnyP::ProtocolVersion(AnyP::PROTO_TLS, 1, (vMinor - 1));
37
+    }
38
 
39
-    return AnyP::ProtocolVersion(AnyP::PROTO_TLS, 1, (vMinor - 1));
40
+    /* handle unsupported versions */
41
+
42
+    const uint16_t vRaw = (vMajor << 8) | vMinor;
43
+    debugs(83, 7, "unsupported: " << asHex(vRaw));
44
+    if (beStrict)
45
+        throw TextException(ToSBuf("unsupported TLS version: ", asHex(vRaw)), Here());
46
+    // else hide unsupported version details from the caller behind PROTO_NONE
47
+    return AnyP::ProtocolVersion();
48
 }
49
 
50
+/// parse a framing-related TLS ProtocolVersion
51
+/// \returns a supported SSL or TLS Anyp::ProtocolVersion, never PROTO_NONE
52
+static AnyP::ProtocolVersion
53
+ParseProtocolVersion(Parser::BinaryTokenizer &tk)
54
+{
55
+    return ParseProtocolVersionBase(tk, ".version", true);
56
+}
57
+
58
+/// parse a framing-unrelated TLS ProtocolVersion
59
+/// \retval PROTO_NONE for unsupported values
60
+static AnyP::ProtocolVersion
61
+ParseOptionalProtocolVersion(Parser::BinaryTokenizer &tk, const char *contextLabel)
62
+{
63
+    return ParseProtocolVersionBase(tk, contextLabel, false);
64
+}
65
+
66
+} // namespace Security
67
+
68
 Security::TLSPlaintext::TLSPlaintext(Parser::BinaryTokenizer &tk)
69
 {
70
     Parser::BinaryTokenizerContext context(tk, "TLSPlaintext");
71
@@ -431,6 +459,8 @@ Security::HandshakeParser::parseExtensions(const SBuf 
72
             break;
73
         case 16: { // Application-Layer Protocol Negotiation Extension, RFC 7301
74
             Parser::BinaryTokenizer tkAPN(extension.data);
75
+            // Store the entire protocol list, including unsupported-by-Squid
76
+            // values (if any). We have to use all when peeking at the server.
77
             details->tlsAppLayerProtoNeg = tkAPN.pstring16("APN");
78
             break;
79
         }
80
@@ -441,8 +471,9 @@ Security::HandshakeParser::parseExtensions(const SBuf 
81
         case 43: // supported_versions extension; RFC 8446
82
             parseSupportedVersionsExtension(extension.data);
83
             break;
84
-        case 13172: // Next Protocol Negotiation Extension (expired draft?)
85
         default:
86
+            // other extensions, including those that Squid does not support, do
87
+            // not require special handling here, but see unsupportedExtensions
88
             break;
89
         }
90
     }
91
@@ -455,7 +486,7 @@ Security::HandshakeParser::parseCiphers(const SBuf &ra
92
     Parser::BinaryTokenizer tk(raw);
93
     while (!tk.atEnd()) {
94
         const uint16_t cipher = tk.uint16("cipher");
95
-        details->ciphers.insert(cipher);
96
+        details->ciphers.insert(cipher); // including Squid-unsupported ones
97
     }
98
 }
99
 
100
@@ -473,7 +504,7 @@ Security::HandshakeParser::parseV23Ciphers(const SBuf 
101
         const uint8_t prefix = tk.uint8("prefix");
102
         const uint16_t cipher = tk.uint16("cipher");
103
         if (prefix == 0)
104
-            details->ciphers.insert(cipher);
105
+            details->ciphers.insert(cipher); // including Squid-unsupported ones
106
     }
107
 }
108
 
109
@@ -486,6 +517,7 @@ Security::HandshakeParser::parseServerHelloHandshakeMe
110
     details->tlsSupportedVersion = ParseProtocolVersion(tk);
111
     tk.skip(HelloRandomSize, ".random");
112
     details->sessionId = tk.pstring8(".session_id");
113
+    // cipherSuite may be unsupported by a peeking Squid
114
     details->ciphers.insert(tk.uint16(".cipher_suite"));
115
     details->compressionSupported = tk.uint8(".compression_method") != 0; // not null
116
     if (!tk.atEnd()) // extensions present
117
@@ -554,12 +586,15 @@ Security::HandshakeParser::parseSupportedVersionsExten
118
         Parser::BinaryTokenizer tkList(extensionData);
119
         Parser::BinaryTokenizer tkVersions(tkList.pstring8("SupportedVersions"));
120
         while (!tkVersions.atEnd()) {
121
-            const auto version = ParseProtocolVersion(tkVersions, "supported_version");
122
+            const auto version = ParseOptionalProtocolVersion(tkVersions, "supported_version");
123
+            // ignore values unsupported by Squid,represented by a falsy version
124
+            if (!version)
125
+                continue;
126
             if (!supportedVersionMax || TlsVersionEarlierThan(supportedVersionMax, version))
127
                 supportedVersionMax = version;
128
         }
129
 
130
-        // ignore empty supported_versions
131
+        // ignore empty and ignored-values-only supported_versions
132
         if (!supportedVersionMax)
133
             return;
134
 
135
@@ -569,7 +604,11 @@ Security::HandshakeParser::parseSupportedVersionsExten
136
     } else {
137
         assert(messageSource == fromServer);
138
         Parser::BinaryTokenizer tkVersion(extensionData);
139
-        const auto version = ParseProtocolVersion(tkVersion, "selected_version");
140
+        const auto version = ParseOptionalProtocolVersion(tkVersion, "selected_version");
141
+        // Ignore values unsupported by Squid. There should not be any until we
142
+        // start seeing TLS v2+, but they do not affect TLS framing anyway.
143
+        if (!version)
144
+            return;
145
         // RFC 8446 Section 4.2.1:
146
         // A server which negotiates a version of TLS prior to TLS 1.3 [...]
147
         // MUST NOT send the "supported_versions" extension.

Return to bug 248856