ssl_v2_client_hello_unittest.cc (13988B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=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 file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "pk11pub.h" 8 #include "ssl.h" 9 #include "sslerr.h" 10 #include "sslproto.h" 11 12 extern "C" { 13 // This is not something that should make you happy. 14 #include "libssl_internals.h" 15 } 16 17 #include "gtest_utils.h" 18 #include "tls_connect.h" 19 #include "tls_filter.h" 20 21 namespace nss_test { 22 23 // Replaces the client hello with an SSLv2 version once. 24 class SSLv2ClientHelloFilter : public PacketFilter { 25 public: 26 SSLv2ClientHelloFilter(const std::shared_ptr<TlsAgent>& client, 27 uint16_t version) 28 : replaced_(false), 29 client_(client), 30 version_(version), 31 pad_len_(0), 32 reported_pad_len_(0), 33 client_random_len_(16), 34 ciphers_(0), 35 send_escape_(false) {} 36 37 void SetVersion(uint16_t version) { version_ = version; } 38 39 void SetCipherSuites(const std::vector<uint16_t>& ciphers) { 40 ciphers_ = ciphers; 41 } 42 43 // Set a padding length and announce it correctly. 44 void SetPadding(uint8_t pad_len) { SetPadding(pad_len, pad_len); } 45 46 // Set a padding length and allow to lie about its length. 47 void SetPadding(uint8_t pad_len, uint8_t reported_pad_len) { 48 pad_len_ = pad_len; 49 reported_pad_len_ = reported_pad_len; 50 } 51 52 void SetClientRandomLength(uint16_t client_random_len) { 53 client_random_len_ = client_random_len; 54 } 55 56 void SetSendEscape(bool send_escape) { send_escape_ = send_escape; } 57 58 protected: 59 virtual PacketFilter::Action Filter(const DataBuffer& input, 60 DataBuffer* output) { 61 if (replaced_) { 62 return KEEP; 63 } 64 65 // Replace only the very first packet. 66 replaced_ = true; 67 68 // The SSLv2 client hello size. 69 size_t packet_len = SSL_HL_CLIENT_HELLO_HBYTES + (ciphers_.size() * 3) + 70 client_random_len_ + pad_len_; 71 72 size_t idx = 0; 73 *output = input; 74 output->Allocate(packet_len); 75 output->Truncate(packet_len); 76 77 // Write record length. 78 if (pad_len_ > 0) { 79 size_t masked_len = 0x3fff & packet_len; 80 if (send_escape_) { 81 masked_len |= 0x4000; 82 } 83 84 idx = output->Write(idx, masked_len, 2); 85 idx = output->Write(idx, reported_pad_len_, 1); 86 } else { 87 PR_ASSERT(!send_escape_); 88 idx = output->Write(idx, 0x8000 | packet_len, 2); 89 } 90 91 // Remember header length. 92 size_t hdr_len = idx; 93 94 // Write client hello. 95 idx = output->Write(idx, SSL_MT_CLIENT_HELLO, 1); 96 idx = output->Write(idx, version_, 2); 97 98 // Cipher list length. 99 idx = output->Write(idx, (ciphers_.size() * 3), 2); 100 101 // Session ID length. 102 idx = output->Write(idx, static_cast<uint32_t>(0), 2); 103 104 // ClientRandom length. 105 idx = output->Write(idx, client_random_len_, 2); 106 107 // Cipher suites. 108 for (auto cipher : ciphers_) { 109 idx = output->Write(idx, static_cast<uint32_t>(cipher), 3); 110 } 111 112 // Challenge. 113 std::vector<uint8_t> challenge(client_random_len_); 114 PK11_GenerateRandom(challenge.data(), challenge.size()); 115 idx = output->Write(idx, challenge.data(), challenge.size()); 116 117 // Add padding if any. 118 if (pad_len_ > 0) { 119 std::vector<uint8_t> pad(pad_len_); 120 idx = output->Write(idx, pad.data(), pad.size()); 121 } 122 123 // Update the client random so that the handshake succeeds. 124 SECStatus rv = SSLInt_UpdateSSLv2ClientRandom( 125 client_.lock()->ssl_fd(), challenge.data(), challenge.size(), 126 output->data() + hdr_len, output->len() - hdr_len); 127 EXPECT_EQ(SECSuccess, rv); 128 129 return CHANGE; 130 } 131 132 private: 133 bool replaced_; 134 std::weak_ptr<TlsAgent> client_; 135 uint16_t version_; 136 uint8_t pad_len_; 137 uint8_t reported_pad_len_; 138 uint16_t client_random_len_; 139 std::vector<uint16_t> ciphers_; 140 bool send_escape_; 141 }; 142 143 class SSLv2ClientHelloTestF : public TlsConnectTestBase { 144 public: 145 SSLv2ClientHelloTestF() 146 : TlsConnectTestBase(ssl_variant_stream, 0), filter_(nullptr) {} 147 148 SSLv2ClientHelloTestF(SSLProtocolVariant variant, uint16_t version) 149 : TlsConnectTestBase(variant, version), filter_(nullptr) {} 150 151 void SetUp() override { 152 TlsConnectTestBase::SetUp(); 153 filter_ = MakeTlsFilter<SSLv2ClientHelloFilter>(client_, version_); 154 server_->SetOption(SSL_ENABLE_V2_COMPATIBLE_HELLO, PR_TRUE); 155 } 156 157 void SetExpectedVersion(uint16_t version) { 158 TlsConnectTestBase::SetExpectedVersion(version); 159 filter_->SetVersion(version); 160 } 161 162 void SetAvailableCipherSuite(uint16_t cipher) { 163 filter_->SetCipherSuites(std::vector<uint16_t>(1, cipher)); 164 } 165 166 void SetAvailableCipherSuites(const std::vector<uint16_t>& ciphers) { 167 filter_->SetCipherSuites(ciphers); 168 } 169 170 void SetPadding(uint8_t pad_len) { filter_->SetPadding(pad_len); } 171 172 void SetPadding(uint8_t pad_len, uint8_t reported_pad_len) { 173 filter_->SetPadding(pad_len, reported_pad_len); 174 } 175 176 void SetClientRandomLength(uint16_t client_random_len) { 177 filter_->SetClientRandomLength(client_random_len); 178 } 179 180 void SetSendEscape(bool send_escape) { filter_->SetSendEscape(send_escape); } 181 182 private: 183 std::shared_ptr<SSLv2ClientHelloFilter> filter_; 184 }; 185 186 // Parameterized version of SSLv2ClientHelloTestF we can 187 // use with TEST_P to test multiple TLS versions easily. 188 class SSLv2ClientHelloTest : public SSLv2ClientHelloTestF, 189 public ::testing::WithParamInterface<uint16_t> { 190 public: 191 SSLv2ClientHelloTest() 192 : SSLv2ClientHelloTestF(ssl_variant_stream, GetParam()) {} 193 }; 194 195 // Test negotiating TLS 1.0 - 1.2. 196 TEST_P(SSLv2ClientHelloTest, Connect) { 197 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 198 Connect(); 199 } 200 201 TEST_P(SSLv2ClientHelloTest, ConnectDisabled) { 202 server_->SetOption(SSL_ENABLE_V2_COMPATIBLE_HELLO, PR_FALSE); 203 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 204 205 StartConnect(); 206 client_->Handshake(); // Send the modified ClientHello. 207 server_->Handshake(); // Read some. 208 // The problem here is that the v2 ClientHello puts the version where the v3 209 // ClientHello puts a version number. So the version number (0x0301+) appears 210 // to be a length and server blocks waiting for that much data. 211 EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); 212 213 // This is usually what happens with v2-compatible: the server hangs. 214 // But to be certain, feed in more data to see if an error comes out. 215 uint8_t zeros[SSL_LIBRARY_VERSION_TLS_1_2] = {0}; 216 client_->SendDirect(DataBuffer(zeros, sizeof(zeros))); 217 ExpectAlert(server_, kTlsAlertUnexpectedMessage); 218 server_->Handshake(); 219 client_->Handshake(); 220 } 221 222 // Sending a v2 ClientHello after a no-op v3 record must fail. 223 TEST_P(SSLv2ClientHelloTest, ConnectAfterEmptyV3Record) { 224 DataBuffer buffer; 225 226 size_t idx = 0; 227 idx = buffer.Write(idx, 0x16, 1); // handshake 228 idx = buffer.Write(idx, 0x0301, 2); // record_version 229 (void)buffer.Write(idx, 0U, 2); // length=0 230 231 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 232 EnsureTlsSetup(); 233 client_->SendDirect(buffer); 234 235 // Need padding so the connection doesn't just time out. With a v2 236 // ClientHello parsed as a v3 record we will use the record version 237 // as the record length. 238 SetPadding(255); 239 240 ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage); 241 EXPECT_EQ(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, server_->error_code()); 242 } 243 244 // Test negotiating TLS 1.3. 245 TEST_F(SSLv2ClientHelloTestF, Connect13) { 246 EnsureTlsSetup(); 247 SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_3); 248 ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); 249 250 std::vector<uint16_t> cipher_suites = {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}; 251 SetAvailableCipherSuites(cipher_suites); 252 253 ConnectExpectAlert(server_, kTlsAlertIllegalParameter); 254 EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code()); 255 } 256 257 // Test negotiating an EC suite. 258 TEST_P(SSLv2ClientHelloTest, NegotiateECSuite) { 259 SetAvailableCipherSuite(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA); 260 Connect(); 261 } 262 263 // Test negotiating TLS 1.0 - 1.2 with a padded client hello. 264 TEST_P(SSLv2ClientHelloTest, AddPadding) { 265 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 266 SetPadding(255); 267 Connect(); 268 } 269 270 // Test that sending a security escape fails the handshake. 271 TEST_P(SSLv2ClientHelloTest, SendSecurityEscape) { 272 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 273 274 // Send a security escape. 275 SetSendEscape(true); 276 277 // Set a big padding so that the server fails instead of timing out. 278 SetPadding(255); 279 280 ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage); 281 } 282 283 // Invalid SSLv2 client hello padding must fail the handshake. 284 TEST_P(SSLv2ClientHelloTest, AddErroneousPadding) { 285 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 286 287 // Append 5 bytes of padding but say it's only 4. 288 SetPadding(5, 4); 289 290 ConnectExpectAlert(server_, kTlsAlertIllegalParameter); 291 EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code()); 292 } 293 294 // Invalid SSLv2 client hello padding must fail the handshake. 295 TEST_P(SSLv2ClientHelloTest, AddErroneousPadding2) { 296 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 297 298 // Append 5 bytes of padding but say it's 6. 299 SetPadding(5, 6); 300 301 ConnectExpectAlert(server_, kTlsAlertIllegalParameter); 302 EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code()); 303 } 304 305 // Wrong amount of bytes for the ClientRandom must fail the handshake. 306 TEST_P(SSLv2ClientHelloTest, SmallClientRandom) { 307 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 308 309 // Send a ClientRandom that's too small. 310 SetClientRandomLength(15); 311 312 ConnectExpectAlert(server_, kTlsAlertIllegalParameter); 313 EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code()); 314 } 315 316 // Test sending the maximum accepted number of ClientRandom bytes. 317 TEST_P(SSLv2ClientHelloTest, MaxClientRandom) { 318 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 319 SetClientRandomLength(32); 320 Connect(); 321 } 322 323 // Wrong amount of bytes for the ClientRandom must fail the handshake. 324 TEST_P(SSLv2ClientHelloTest, BigClientRandom) { 325 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 326 327 // Send a ClientRandom that's too big. 328 SetClientRandomLength(33); 329 330 ConnectExpectAlert(server_, kTlsAlertIllegalParameter); 331 EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code()); 332 } 333 334 // Connection must fail if we require safe renegotiation but the client doesn't 335 // include TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the list of cipher suites. 336 TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiation) { 337 server_->SetOption(SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE); 338 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 339 ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); 340 EXPECT_EQ(SSL_ERROR_UNSAFE_NEGOTIATION, server_->error_code()); 341 } 342 343 // Connection must succeed when requiring safe renegotiation and the client 344 // includes TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the list of cipher suites. 345 TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiationWithSCSV) { 346 server_->SetOption(SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE); 347 std::vector<uint16_t> cipher_suites = {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 348 TLS_EMPTY_RENEGOTIATION_INFO_SCSV}; 349 SetAvailableCipherSuites(cipher_suites); 350 Connect(); 351 } 352 353 TEST_P(SSLv2ClientHelloTest, CheckServerRandom) { 354 ConfigureSessionCache(RESUME_NONE, RESUME_NONE); 355 SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); 356 357 static const size_t random_len = 32; 358 uint8_t srandom1[random_len]; 359 uint8_t z[random_len] = {0}; 360 361 auto sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello); 362 Connect(); 363 ASSERT_TRUE(sh->buffer().len() > (random_len + 2)); 364 memcpy(srandom1, sh->buffer().data() + 2, random_len); 365 EXPECT_NE(0, memcmp(srandom1, z, random_len)); 366 367 Reset(); 368 sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello); 369 Connect(); 370 ASSERT_TRUE(sh->buffer().len() > (random_len + 2)); 371 const uint8_t* srandom2 = sh->buffer().data() + 2; 372 373 EXPECT_NE(0, memcmp(srandom2, z, random_len)); 374 EXPECT_NE(0, memcmp(srandom1, srandom2, random_len)); 375 } 376 377 // Connect to the server with TLS 1.1, signalling that this is a fallback from 378 // a higher version. As the server doesn't support anything higher than TLS 1.1 379 // it must accept the connection. 380 TEST_F(SSLv2ClientHelloTestF, FallbackSCSV) { 381 EnsureTlsSetup(); 382 SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1); 383 ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_1); 384 385 std::vector<uint16_t> cipher_suites = {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 386 TLS_FALLBACK_SCSV}; 387 SetAvailableCipherSuites(cipher_suites); 388 Connect(); 389 } 390 391 // Connect to the server with TLS 1.1, signalling that this is a fallback from 392 // a higher version. As the server supports TLS 1.2 though it must reject the 393 // connection due to a possible downgrade attack. 394 TEST_F(SSLv2ClientHelloTestF, InappropriateFallbackSCSV) { 395 SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1); 396 client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, 397 SSL_LIBRARY_VERSION_TLS_1_1); 398 server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1, 399 SSL_LIBRARY_VERSION_TLS_1_2); 400 401 std::vector<uint16_t> cipher_suites = {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 402 TLS_FALLBACK_SCSV}; 403 SetAvailableCipherSuites(cipher_suites); 404 405 ConnectExpectAlert(server_, kTlsAlertInappropriateFallback); 406 EXPECT_EQ(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, server_->error_code()); 407 } 408 409 INSTANTIATE_TEST_SUITE_P(VersionsStream10Pre13, SSLv2ClientHelloTest, 410 TlsConnectTestBase::kTlsV10); 411 INSTANTIATE_TEST_SUITE_P(VersionsStreamPre13, SSLv2ClientHelloTest, 412 TlsConnectTestBase::kTlsV11V12); 413 414 } // namespace nss_test