TLSIntoleranceTest.cpp (16123B)
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/. */ 6 7 #include "nsNSSIOLayer.h" 8 #include "sslproto.h" 9 #include "sslerr.h" 10 11 #include "gtest/gtest.h" 12 13 constexpr auto HOST = "example.org"_ns; 14 const int16_t PORT = 443; 15 16 class psm_TLSIntoleranceTest : public ::testing::Test { 17 protected: 18 RefPtr<nsSSLIOLayerHelpers> helpers = 19 new nsSSLIOLayerHelpers(PublicOrPrivate::Public, 0); 20 }; 21 22 TEST_F(psm_TLSIntoleranceTest, FullFallbackProcess) { 23 ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, helpers->mVersionFallbackLimit); 24 25 // No adjustment made when there is no entry for the site. 26 { 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); 32 } 33 34 { 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); 40 41 ASSERT_TRUE(helpers->rememberIntolerantAtVersion(HOST, PORT, range.min, 42 range.max, 0)); 43 } 44 45 { 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); 51 52 ASSERT_TRUE(helpers->rememberIntolerantAtVersion(HOST, PORT, range.min, 53 range.max, 0)); 54 } 55 56 { 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); 62 63 ASSERT_FALSE(helpers->rememberIntolerantAtVersion(HOST, PORT, range.min, 64 range.max, 0)); 65 } 66 67 { 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); 75 } 76 } 77 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)); 88 } 89 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)); 95 { 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); 101 } 102 103 ASSERT_FALSE(helpers->rememberIntolerantAtVersion( 104 HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1, SSL_LIBRARY_VERSION_TLS_1_1, 0)); 105 } 106 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); 116 } 117 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); 127 } 128 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); 140 } 141 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)); 148 149 { 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); 154 } 155 156 { 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); 161 } 162 } 163 164 TEST_F(psm_TLSIntoleranceTest, IntoleranceReasonInitial) { 165 ASSERT_EQ(0, helpers->getIntoleranceReason(HOST, 1)); 166 167 helpers->rememberTolerantAtVersion(HOST, 2, SSL_LIBRARY_VERSION_TLS_1_2); 168 ASSERT_EQ(0, helpers->getIntoleranceReason(HOST, 2)); 169 } 170 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)); 176 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)); 181 } 182 183 TEST_F(psm_TLSIntoleranceTest, IntoleranceReasonCleared) { 184 ASSERT_EQ(0, helpers->getIntoleranceReason(HOST, 1)); 185 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)); 191 192 helpers->rememberTolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_2); 193 ASSERT_EQ(0, helpers->getIntoleranceReason(HOST, 1)); 194 } 195 196 TEST_F(psm_TLSIntoleranceTest, TLSForgetIntolerance) { 197 { 198 ASSERT_TRUE(helpers->rememberIntolerantAtVersion( 199 HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, 200 0)); 201 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); 207 } 208 209 { 210 helpers->forgetIntolerance(HOST, PORT); 211 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); 217 } 218 } 219 220 TEST_F(psm_TLSIntoleranceTest, TLSDontForgetTolerance) { 221 { 222 helpers->rememberTolerantAtVersion(HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1); 223 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); 229 } 230 231 { 232 ASSERT_TRUE(helpers->rememberIntolerantAtVersion( 233 HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, 234 0)); 235 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); 241 } 242 243 { 244 helpers->forgetIntolerance(HOST, PORT); 245 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); 251 } 252 } 253 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; 258 259 helpers->mVersionFallbackLimit = SSL_LIBRARY_VERSION_TLS_1_0; 260 261 ASSERT_FALSE( 262 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); 263 ASSERT_FALSE( 264 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); 265 ASSERT_TRUE( 266 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); 267 ASSERT_FALSE( 268 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); 269 ASSERT_FALSE( 270 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); 271 ASSERT_TRUE( 272 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); 273 ASSERT_FALSE( 274 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); 275 ASSERT_FALSE( 276 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); 277 ASSERT_TRUE( 278 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); 279 280 helpers->mVersionFallbackLimit = SSL_LIBRARY_VERSION_TLS_1_2; 281 282 ASSERT_TRUE( 283 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); 284 ASSERT_TRUE( 285 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); 286 ASSERT_TRUE( 287 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); 288 ASSERT_TRUE( 289 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); 290 ASSERT_TRUE( 291 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); 292 ASSERT_TRUE( 293 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); 294 ASSERT_TRUE( 295 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); 296 ASSERT_TRUE( 297 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); 298 ASSERT_TRUE( 299 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); 300 301 helpers->setInsecureFallbackSites(example_com); 302 303 ASSERT_FALSE( 304 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); 305 ASSERT_FALSE( 306 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); 307 ASSERT_TRUE( 308 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); 309 ASSERT_TRUE( 310 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); 311 ASSERT_TRUE( 312 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); 313 ASSERT_TRUE( 314 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); 315 ASSERT_TRUE( 316 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); 317 ASSERT_TRUE( 318 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); 319 ASSERT_TRUE( 320 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); 321 322 helpers->setInsecureFallbackSites("example.com,example.net"_ns); 323 324 ASSERT_FALSE( 325 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); 326 ASSERT_FALSE( 327 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); 328 ASSERT_TRUE( 329 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); 330 ASSERT_FALSE( 331 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); 332 ASSERT_FALSE( 333 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); 334 ASSERT_TRUE( 335 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); 336 ASSERT_TRUE( 337 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); 338 ASSERT_TRUE( 339 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); 340 ASSERT_TRUE( 341 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); 342 343 helpers->setInsecureFallbackSites(example_net); 344 345 ASSERT_TRUE( 346 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); 347 ASSERT_TRUE( 348 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); 349 ASSERT_TRUE( 350 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); 351 ASSERT_FALSE( 352 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); 353 ASSERT_FALSE( 354 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); 355 ASSERT_TRUE( 356 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); 357 ASSERT_TRUE( 358 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); 359 ASSERT_TRUE( 360 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); 361 ASSERT_TRUE( 362 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); 363 364 helpers->setInsecureFallbackSites(""_ns); 365 366 ASSERT_TRUE( 367 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); 368 ASSERT_TRUE( 369 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); 370 ASSERT_TRUE( 371 helpers->fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); 372 ASSERT_TRUE( 373 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); 374 ASSERT_TRUE( 375 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); 376 ASSERT_TRUE( 377 helpers->fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); 378 ASSERT_TRUE( 379 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); 380 ASSERT_TRUE( 381 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); 382 ASSERT_TRUE( 383 helpers->fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); 384 }