tor-browser

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

ssl_gather_unittest.cc (5589B)


      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 "gtest_utils.h"
      8 #include "tls_connect.h"
      9 
     10 namespace nss_test {
     11 
     12 class GatherV2ClientHelloTest : public TlsConnectTestBase {
     13 public:
     14  GatherV2ClientHelloTest() : TlsConnectTestBase(ssl_variant_stream, 0) {}
     15 
     16  void ConnectExpectMalformedClientHello(const DataBuffer &data) {
     17    EnsureTlsSetup();
     18    server_->SetOption(SSL_ENABLE_V2_COMPATIBLE_HELLO, PR_TRUE);
     19    server_->ExpectSendAlert(kTlsAlertIllegalParameter);
     20    client_->SendDirect(data);
     21    server_->StartConnect();
     22    server_->Handshake();
     23    ASSERT_TRUE_WAIT(
     24        (server_->error_code() == SSL_ERROR_RX_MALFORMED_CLIENT_HELLO), 2000);
     25  }
     26 };
     27 
     28 // Gather a 5-byte v3 record, with a fragment length exceeding the maximum.
     29 TEST_F(TlsConnectTest, GatherExcessiveV3Record) {
     30  DataBuffer buffer;
     31 
     32  size_t idx = 0;
     33  idx = buffer.Write(idx, 0x16, 1);                            // handshake
     34  idx = buffer.Write(idx, 0x0301, 2);                          // record_version
     35  (void)buffer.Write(idx, MAX_FRAGMENT_LENGTH + 2048 + 1, 2);  // length=max+1
     36 
     37  EnsureTlsSetup();
     38  server_->ExpectSendAlert(kTlsAlertRecordOverflow);
     39  client_->SendDirect(buffer);
     40  server_->StartConnect();
     41  server_->Handshake();
     42  ASSERT_TRUE_WAIT((server_->error_code() == SSL_ERROR_RX_RECORD_TOO_LONG),
     43                   2000);
     44 }
     45 
     46 TEST_P(TlsConnectDatagram, DtlsGatherCIDRecord) {
     47  TlsRecordHeader cidRecordHeader(ssl_variant_datagram, version_, 0x30, 0);
     48  DataBuffer buffer = DataBuffer(10);
     49  TlsRecord cidRecord = {cidRecordHeader, buffer};
     50 
     51  EnsureTlsSetup();
     52  Connect();
     53  client_->SendRecordDirect(cidRecord);
     54 
     55  // CIDs are not supported, invalid records in DTLS should be silently
     56  // discarded.
     57  server_->WaitForErrorCode(0, 1000);
     58  client_->WaitForErrorCode(0, 1000);
     59 }
     60 
     61 // Gather a 3-byte v2 header, with a fragment length of 2.
     62 TEST_F(GatherV2ClientHelloTest, GatherV2RecordLongHeader) {
     63  DataBuffer buffer;
     64 
     65  size_t idx = 0;
     66  idx = buffer.Write(idx, 0x0002, 2);  // length=2 (long header)
     67  idx = buffer.Write(idx, 0U, 1);      // padding=0
     68  (void)buffer.Write(idx, 0U, 2);      // data
     69 
     70  ConnectExpectMalformedClientHello(buffer);
     71 }
     72 
     73 // Gather a 3-byte v2 header, with a fragment length of 1.
     74 TEST_F(GatherV2ClientHelloTest, GatherV2RecordLongHeader2) {
     75  DataBuffer buffer;
     76 
     77  size_t idx = 0;
     78  idx = buffer.Write(idx, 0x0001, 2);  // length=1 (long header)
     79  idx = buffer.Write(idx, 0U, 1);      // padding=0
     80  idx = buffer.Write(idx, 0U, 1);      // data
     81  (void)buffer.Write(idx, 0U, 1);      // surplus (need 5 bytes total)
     82 
     83  ConnectExpectMalformedClientHello(buffer);
     84 }
     85 
     86 // Gather a 3-byte v2 header, with a zero fragment length.
     87 TEST_F(GatherV2ClientHelloTest, GatherEmptyV2RecordLongHeader) {
     88  DataBuffer buffer;
     89 
     90  size_t idx = 0;
     91  idx = buffer.Write(idx, 0U, 2);  // length=0 (long header)
     92  idx = buffer.Write(idx, 0U, 1);  // padding=0
     93  (void)buffer.Write(idx, 0U, 2);  // surplus (need 5 bytes total)
     94 
     95  ConnectExpectMalformedClientHello(buffer);
     96 }
     97 
     98 // Gather a 2-byte v2 header, with a fragment length of 3.
     99 TEST_F(GatherV2ClientHelloTest, GatherV2RecordShortHeader) {
    100  DataBuffer buffer;
    101 
    102  size_t idx = 0;
    103  idx = buffer.Write(idx, 0x8003, 2);  // length=3 (short header)
    104  (void)buffer.Write(idx, 0U, 3);      // data
    105 
    106  ConnectExpectMalformedClientHello(buffer);
    107 }
    108 
    109 // Gather a 2-byte v2 header, with a fragment length of 2.
    110 TEST_F(GatherV2ClientHelloTest, GatherEmptyV2RecordShortHeader2) {
    111  DataBuffer buffer;
    112 
    113  size_t idx = 0;
    114  idx = buffer.Write(idx, 0x8002, 2);  // length=2 (short header)
    115  idx = buffer.Write(idx, 0U, 2);      // data
    116  (void)buffer.Write(idx, 0U, 1);      // surplus (need 5 bytes total)
    117 
    118  ConnectExpectMalformedClientHello(buffer);
    119 }
    120 
    121 // Gather a 2-byte v2 header, with a fragment length of 1.
    122 TEST_F(GatherV2ClientHelloTest, GatherEmptyV2RecordShortHeader3) {
    123  DataBuffer buffer;
    124 
    125  size_t idx = 0;
    126  idx = buffer.Write(idx, 0x8001, 2);  // length=1 (short header)
    127  idx = buffer.Write(idx, 0U, 1);      // data
    128  (void)buffer.Write(idx, 0U, 2);      // surplus (need 5 bytes total)
    129 
    130  ConnectExpectMalformedClientHello(buffer);
    131 }
    132 
    133 // Gather a 2-byte v2 header, with a zero fragment length.
    134 TEST_F(GatherV2ClientHelloTest, GatherEmptyV2RecordShortHeader) {
    135  DataBuffer buffer;
    136 
    137  size_t idx = 0;
    138  idx = buffer.Write(idx, 0x8000, 2);  // length=0 (short header)
    139  (void)buffer.Write(idx, 0U, 3);      // surplus (need 5 bytes total)
    140 
    141  ConnectExpectMalformedClientHello(buffer);
    142 }
    143 
    144 /* Test correct gather buffer clearing/freeing and (re-)allocation.
    145 *
    146 * Freeing and (re-)allocation of the gather buffers after reception of single
    147 * records is only done in DEBUG builds. Normally they are created and
    148 * destroyed with the SSL socket.
    149 *
    150 * TLS 1.0 record splitting leads to implicit complete read of the data.
    151 *
    152 * The NSS DTLS impelmentation does not allow partial reads
    153 * (see sslsecur.c, line 535-543). */
    154 TEST_P(TlsConnectStream, GatherBufferPartialReadTest) {
    155  EnsureTlsSetup();
    156  Connect();
    157 
    158  client_->SendData(1000);
    159 
    160  if (version_ > SSL_LIBRARY_VERSION_TLS_1_0) {
    161    for (unsigned i = 1; i <= 20; i++) {
    162      server_->ReadBytes(50);
    163      ASSERT_EQ(server_->received_bytes(), 50U * i);
    164    }
    165  } else {
    166    server_->ReadBytes(50);
    167    ASSERT_EQ(server_->received_bytes(), 1000U);
    168  }
    169 }
    170 
    171 }  // namespace nss_test