tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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