1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsNSSIOLayer.h"
11 #include "gtest/gtest.h"
13 constexpr auto HOST
= "example.org"_ns
;
14 const int16_t PORT
= 443;
16 class psm_TLSIntoleranceTest
: public ::testing::Test
{
18 RefPtr
<nsSSLIOLayerHelpers
> helpers
=
19 new nsSSLIOLayerHelpers(PublicOrPrivate::Public
, 0);
22 TEST_F(psm_TLSIntoleranceTest
, FullFallbackProcess
) {
23 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, helpers
->mVersionFallbackLimit
);
25 // No adjustment made when there is no entry for the site.
27 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
28 SSL_LIBRARY_VERSION_TLS_1_2
};
29 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
30 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
31 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2
, range
.max
);
35 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
36 SSL_LIBRARY_VERSION_TLS_1_2
};
37 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
38 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
39 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2
, range
.max
);
41 ASSERT_TRUE(helpers
->rememberIntolerantAtVersion(HOST
, PORT
, range
.min
,
46 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
47 SSL_LIBRARY_VERSION_TLS_1_2
};
48 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
49 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
50 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1
, range
.max
);
52 ASSERT_TRUE(helpers
->rememberIntolerantAtVersion(HOST
, PORT
, range
.min
,
57 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
58 SSL_LIBRARY_VERSION_TLS_1_2
};
59 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
60 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
61 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.max
);
63 ASSERT_FALSE(helpers
->rememberIntolerantAtVersion(HOST
, PORT
, range
.min
,
68 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
69 SSL_LIBRARY_VERSION_TLS_1_2
};
70 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
71 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
72 // When rememberIntolerantAtVersion returns false, it also resets the
73 // intolerance information for the server.
74 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2
, range
.max
);
78 TEST_F(psm_TLSIntoleranceTest
, DisableFallbackWithHighLimit
) {
79 // this value disables version fallback entirely: with this value, all efforts
80 // to mark an origin as version intolerant fail
81 helpers
->mVersionFallbackLimit
= SSL_LIBRARY_VERSION_TLS_1_2
;
82 ASSERT_FALSE(helpers
->rememberIntolerantAtVersion(
83 HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_0
, SSL_LIBRARY_VERSION_TLS_1_2
, 0));
84 ASSERT_FALSE(helpers
->rememberIntolerantAtVersion(
85 HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_0
, SSL_LIBRARY_VERSION_TLS_1_1
, 0));
86 ASSERT_FALSE(helpers
->rememberIntolerantAtVersion(
87 HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_0
, SSL_LIBRARY_VERSION_TLS_1_0
, 0));
90 TEST_F(psm_TLSIntoleranceTest
, FallbackLimitBelowMin
) {
91 // check that we still respect the minimum version,
92 // when it is higher than the fallback limit
93 ASSERT_TRUE(helpers
->rememberIntolerantAtVersion(
94 HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_1
, SSL_LIBRARY_VERSION_TLS_1_2
, 0));
96 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
97 SSL_LIBRARY_VERSION_TLS_1_2
};
98 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
99 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
100 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1
, range
.max
);
103 ASSERT_FALSE(helpers
->rememberIntolerantAtVersion(
104 HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_1
, SSL_LIBRARY_VERSION_TLS_1_1
, 0));
107 TEST_F(psm_TLSIntoleranceTest
, TolerantOverridesIntolerant1
) {
108 ASSERT_TRUE(helpers
->rememberIntolerantAtVersion(
109 HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_0
, SSL_LIBRARY_VERSION_TLS_1_1
, 0));
110 helpers
->rememberTolerantAtVersion(HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_1
);
111 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
112 SSL_LIBRARY_VERSION_TLS_1_2
};
113 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
114 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
115 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1
, range
.max
);
118 TEST_F(psm_TLSIntoleranceTest
, TolerantOverridesIntolerant2
) {
119 ASSERT_TRUE(helpers
->rememberIntolerantAtVersion(
120 HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_0
, SSL_LIBRARY_VERSION_TLS_1_1
, 0));
121 helpers
->rememberTolerantAtVersion(HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_2
);
122 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
123 SSL_LIBRARY_VERSION_TLS_1_2
};
124 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
125 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
126 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2
, range
.max
);
129 TEST_F(psm_TLSIntoleranceTest
, IntolerantDoesNotOverrideTolerant
) {
130 // No adjustment made when there is no entry for the site.
131 helpers
->rememberTolerantAtVersion(HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_1
);
132 // false because we reached the floor set by rememberTolerantAtVersion.
133 ASSERT_FALSE(helpers
->rememberIntolerantAtVersion(
134 HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_0
, SSL_LIBRARY_VERSION_TLS_1_1
, 0));
135 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
136 SSL_LIBRARY_VERSION_TLS_1_2
};
137 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
138 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
139 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2
, range
.max
);
142 TEST_F(psm_TLSIntoleranceTest
, PortIsRelevant
) {
143 helpers
->rememberTolerantAtVersion(HOST
, 1, SSL_LIBRARY_VERSION_TLS_1_2
);
144 ASSERT_FALSE(helpers
->rememberIntolerantAtVersion(
145 HOST
, 1, SSL_LIBRARY_VERSION_TLS_1_0
, SSL_LIBRARY_VERSION_TLS_1_2
, 0));
146 ASSERT_TRUE(helpers
->rememberIntolerantAtVersion(
147 HOST
, 2, SSL_LIBRARY_VERSION_TLS_1_0
, SSL_LIBRARY_VERSION_TLS_1_2
, 0));
150 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
151 SSL_LIBRARY_VERSION_TLS_1_2
};
152 helpers
->adjustForTLSIntolerance(HOST
, 1, range
);
153 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2
, range
.max
);
157 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
158 SSL_LIBRARY_VERSION_TLS_1_2
};
159 helpers
->adjustForTLSIntolerance(HOST
, 2, range
);
160 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1
, range
.max
);
164 TEST_F(psm_TLSIntoleranceTest
, IntoleranceReasonInitial
) {
165 ASSERT_EQ(0, helpers
->getIntoleranceReason(HOST
, 1));
167 helpers
->rememberTolerantAtVersion(HOST
, 2, SSL_LIBRARY_VERSION_TLS_1_2
);
168 ASSERT_EQ(0, helpers
->getIntoleranceReason(HOST
, 2));
171 TEST_F(psm_TLSIntoleranceTest
, IntoleranceReasonStored
) {
172 helpers
->rememberIntolerantAtVersion(HOST
, 1, SSL_LIBRARY_VERSION_TLS_1_0
,
173 SSL_LIBRARY_VERSION_TLS_1_2
,
174 SSL_ERROR_BAD_SERVER
);
175 ASSERT_EQ(SSL_ERROR_BAD_SERVER
, helpers
->getIntoleranceReason(HOST
, 1));
177 helpers
->rememberIntolerantAtVersion(HOST
, 1, SSL_LIBRARY_VERSION_TLS_1_0
,
178 SSL_LIBRARY_VERSION_TLS_1_1
,
179 SSL_ERROR_BAD_MAC_READ
);
180 ASSERT_EQ(SSL_ERROR_BAD_MAC_READ
, helpers
->getIntoleranceReason(HOST
, 1));
183 TEST_F(psm_TLSIntoleranceTest
, IntoleranceReasonCleared
) {
184 ASSERT_EQ(0, helpers
->getIntoleranceReason(HOST
, 1));
186 helpers
->rememberIntolerantAtVersion(HOST
, 1, SSL_LIBRARY_VERSION_TLS_1_0
,
187 SSL_LIBRARY_VERSION_TLS_1_2
,
188 SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT
);
189 ASSERT_EQ(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT
,
190 helpers
->getIntoleranceReason(HOST
, 1));
192 helpers
->rememberTolerantAtVersion(HOST
, 1, SSL_LIBRARY_VERSION_TLS_1_2
);
193 ASSERT_EQ(0, helpers
->getIntoleranceReason(HOST
, 1));
196 TEST_F(psm_TLSIntoleranceTest
, TLSForgetIntolerance
) {
198 ASSERT_TRUE(helpers
->rememberIntolerantAtVersion(
199 HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_0
, SSL_LIBRARY_VERSION_TLS_1_2
,
202 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
203 SSL_LIBRARY_VERSION_TLS_1_2
};
204 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
205 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
206 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1
, range
.max
);
210 helpers
->forgetIntolerance(HOST
, PORT
);
212 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
213 SSL_LIBRARY_VERSION_TLS_1_2
};
214 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
215 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
216 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2
, range
.max
);
220 TEST_F(psm_TLSIntoleranceTest
, TLSDontForgetTolerance
) {
222 helpers
->rememberTolerantAtVersion(HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_1
);
224 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
225 SSL_LIBRARY_VERSION_TLS_1_2
};
226 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
227 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
228 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2
, range
.max
);
232 ASSERT_TRUE(helpers
->rememberIntolerantAtVersion(
233 HOST
, PORT
, SSL_LIBRARY_VERSION_TLS_1_0
, SSL_LIBRARY_VERSION_TLS_1_2
,
236 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
237 SSL_LIBRARY_VERSION_TLS_1_2
};
238 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
239 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
240 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1
, range
.max
);
244 helpers
->forgetIntolerance(HOST
, PORT
);
246 SSLVersionRange range
= {SSL_LIBRARY_VERSION_TLS_1_0
,
247 SSL_LIBRARY_VERSION_TLS_1_2
};
248 helpers
->adjustForTLSIntolerance(HOST
, PORT
, range
);
249 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0
, range
.min
);
250 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2
, range
.max
);
254 TEST_F(psm_TLSIntoleranceTest
, TLSPerSiteFallbackLimit
) {
255 constexpr auto example_com
= "example.com"_ns
;
256 constexpr auto example_net
= "example.net"_ns
;
257 constexpr auto example_org
= "example.org"_ns
;
259 helpers
->mVersionFallbackLimit
= SSL_LIBRARY_VERSION_TLS_1_0
;
262 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_2
));
264 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_1
));
266 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_0
));
268 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_2
));
270 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_1
));
272 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_0
));
274 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_2
));
276 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_1
));
278 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_0
));
280 helpers
->mVersionFallbackLimit
= SSL_LIBRARY_VERSION_TLS_1_2
;
283 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_2
));
285 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_1
));
287 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_0
));
289 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_2
));
291 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_1
));
293 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_0
));
295 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_2
));
297 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_1
));
299 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_0
));
301 helpers
->setInsecureFallbackSites(example_com
);
304 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_2
));
306 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_1
));
308 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_0
));
310 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_2
));
312 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_1
));
314 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_0
));
316 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_2
));
318 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_1
));
320 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_0
));
322 helpers
->setInsecureFallbackSites("example.com,example.net"_ns
);
325 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_2
));
327 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_1
));
329 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_0
));
331 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_2
));
333 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_1
));
335 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_0
));
337 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_2
));
339 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_1
));
341 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_0
));
343 helpers
->setInsecureFallbackSites(example_net
);
346 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_2
));
348 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_1
));
350 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_0
));
352 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_2
));
354 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_1
));
356 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_0
));
358 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_2
));
360 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_1
));
362 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_0
));
364 helpers
->setInsecureFallbackSites(""_ns
);
367 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_2
));
369 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_1
));
371 helpers
->fallbackLimitReached(example_com
, SSL_LIBRARY_VERSION_TLS_1_0
));
373 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_2
));
375 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_1
));
377 helpers
->fallbackLimitReached(example_net
, SSL_LIBRARY_VERSION_TLS_1_0
));
379 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_2
));
381 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_1
));
383 helpers
->fallbackLimitReached(example_org
, SSL_LIBRARY_VERSION_TLS_1_0
));