/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "secerr.h"
#include "ssl.h"
#include "sslexp.h"

extern "C" {
// This is not something that should make you happy.
#include "libssl_internals.h"
}

#include "gtest_utils.h"
#include "nss_scoped_ptrs.h"
#include "tls_connect.h"
#include "tls_filter.h"
#include "tls_parser.h"

namespace nss_test {

TEST_P(TlsConnectDatagramPre13, DropClientFirstFlightOnce) {
  client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x1));
  Connect();
  SendReceive();
}

TEST_P(TlsConnectDatagramPre13, DropServerFirstFlightOnce) {
  server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x1));
  Connect();
  SendReceive();
}

// This drops the first transmission from both the client and server of all
// flights that they send.  Note: In DTLS 1.3, the shorter handshake means that
// this will also drop some application data, so we can't call SendReceive().
TEST_P(TlsConnectDatagramPre13, DropAllFirstTransmissions) {
  client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x15));
  server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x5));
  Connect();
}

// This drops the server's first flight three times.
TEST_P(TlsConnectDatagramPre13, DropServerFirstFlightThrice) {
  server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x7));
  Connect();
}

// This drops the client's second flight once
TEST_P(TlsConnectDatagramPre13, DropClientSecondFlightOnce) {
  client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x2));
  Connect();
}

// This drops the client's second flight three times.
TEST_P(TlsConnectDatagramPre13, DropClientSecondFlightThrice) {
  client_->SetFilter(std::make_shared<SelectiveDropFilter>(0xe));
  Connect();
}

// This drops the server's second flight three times.
TEST_P(TlsConnectDatagramPre13, DropServerSecondFlightThrice) {
  server_->SetFilter(std::make_shared<SelectiveDropFilter>(0xe));
  Connect();
}

static void CheckAcks(const std::shared_ptr<TlsRecordRecorder>& acks,
                      size_t index, std::vector<uint64_t> expected) {
  ASSERT_LT(index, acks->count());
  const DataBuffer& buf = acks->record(index).buffer;
  size_t offset = 2;
  uint64_t len;

  EXPECT_EQ(2 + expected.size() * 8, buf.len());
  ASSERT_TRUE(buf.Read(0, 2, &len));
  ASSERT_EQ(static_cast<size_t>(len + 2), buf.len());
  if ((2 + expected.size() * 8) != buf.len()) {
    while (offset < buf.len()) {
      uint64_t ack;
      ASSERT_TRUE(buf.Read(offset, 8, &ack));
      offset += 8;
      std::cerr << "Ack=0x" << std::hex << ack << std::dec << std::endl;
    }
    return;
  }

  for (size_t i = 0; i < expected.size(); ++i) {
    uint64_t a = expected[i];
    uint64_t ack;
    ASSERT_TRUE(buf.Read(offset, 8, &ack));
    offset += 8;
    if (a != ack) {
      ADD_FAILURE() << "Wrong ack " << i << " expected=0x" << std::hex << a
                    << " got=0x" << ack << std::dec;
    }
  }
}

class TlsDropDatagram13 : public TlsConnectDatagram13,
                          public ::testing::WithParamInterface<bool> {
 public:
  TlsDropDatagram13()
      : client_filters_(),
        server_filters_(),
        expected_client_acks_(0),
        expected_server_acks_(1) {}

  void SetUp() override {
    TlsConnectDatagram13::SetUp();
    ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
    int short_header = GetParam() ? PR_TRUE : PR_FALSE;
    client_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, short_header);
    server_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, short_header);
    SetFilters();
  }

  void SetFilters() {
    EnsureTlsSetup();
    client_filters_.Init(client_);
    server_filters_.Init(server_);
  }

  void HandshakeAndAck(const std::shared_ptr<TlsAgent>& agent) {
    agent->Handshake();  // Read flight.
    ShiftDtlsTimers();
    agent->Handshake();  // Generate ACK.
  }

  void ShrinkPostServerHelloMtu() {
    // Abuse the custom extension mechanism to modify the MTU so that the
    // Certificate message is split into two pieces.
    ASSERT_EQ(
        SECSuccess,
        SSL_InstallExtensionHooks(
            server_->ssl_fd(), 1,
            [](PRFileDesc* fd, SSLHandshakeType message, PRUint8* data,
               unsigned int* len, unsigned int maxLen, void* arg) -> PRBool {
              SSLInt_SetMTU(fd, 500);  // Splits the certificate.
              return PR_FALSE;
            },
            nullptr,
            [](PRFileDesc* fd, SSLHandshakeType message, const PRUint8* data,
               unsigned int len, SSLAlertDescription* alert,
               void* arg) -> SECStatus { return SECSuccess; },
            nullptr));
  }

 protected:
  class DropAckChain {
   public:
    DropAckChain()
        : records_(nullptr), ack_(nullptr), drop_(nullptr), chain_(nullptr) {}

    void Init(const std::shared_ptr<TlsAgent>& agent) {
      records_ = std::make_shared<TlsRecordRecorder>(agent);
      ack_ = std::make_shared<TlsRecordRecorder>(agent, ssl_ct_ack);
      ack_->EnableDecryption();
      drop_ = std::make_shared<SelectiveRecordDropFilter>(agent, 0, false);
      chain_ = std::make_shared<ChainedPacketFilter>(
          ChainedPacketFilterInit({records_, ack_, drop_}));
      agent->SetFilter(chain_);
    }

    const TlsRecord& record(size_t i) const { return records_->record(i); }

    std::shared_ptr<TlsRecordRecorder> records_;
    std::shared_ptr<TlsRecordRecorder> ack_;
    std::shared_ptr<SelectiveRecordDropFilter> drop_;
    std::shared_ptr<PacketFilter> chain_;
  };

  void CheckedHandshakeSendReceive() {
    Handshake();
    CheckPostHandshake();
  }

  void CheckPostHandshake() {
    CheckConnected();
    SendReceive();
    EXPECT_EQ(expected_client_acks_, client_filters_.ack_->count());
    EXPECT_EQ(expected_server_acks_, server_filters_.ack_->count());
  }

 protected:
  DropAckChain client_filters_;
  DropAckChain server_filters_;
  size_t expected_client_acks_;
  size_t expected_server_acks_;
};

// All of these tests produce a minimum one ACK, from the server
// to the client upon receiving the client Finished.
// Dropping complete first and second flights does not produce
// ACKs
TEST_P(TlsDropDatagram13, DropClientFirstFlightOnce) {
  client_filters_.drop_->Reset({0});
  StartConnect();
  client_->Handshake();
  server_->Handshake();
  CheckedHandshakeSendReceive();
  CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
}

TEST_P(TlsDropDatagram13, DropServerFirstFlightOnce) {
  server_filters_.drop_->Reset(0xff);
  StartConnect();
  client_->Handshake();
  // Send the first flight, all dropped.
  server_->Handshake();
  server_filters_.drop_->Disable();
  CheckedHandshakeSendReceive();
  CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
}

// Dropping the server's first record also does not produce
// an ACK because the next record is ignored.
// TODO(ekr@rtfm.com): We should generate an empty ACK.
TEST_P(TlsDropDatagram13, DropServerFirstRecordOnce) {
  server_filters_.drop_->Reset({0});
  StartConnect();
  client_->Handshake();
  server_->Handshake();
  Handshake();
  CheckedHandshakeSendReceive();
  CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
}

// Dropping the second packet of the server's flight should
// produce an ACK.
TEST_P(TlsDropDatagram13, DropServerSecondRecordOnce) {
  server_filters_.drop_->Reset({1});
  StartConnect();
  client_->Handshake();
  server_->Handshake();
  HandshakeAndAck(client_);
  expected_client_acks_ = 1;
  CheckedHandshakeSendReceive();
  CheckAcks(client_filters_.ack_, 0, {0});  // ServerHello
  CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
}

// Drop the server ACK and verify that the client retransmits
// the ClientHello.
TEST_P(TlsDropDatagram13, DropServerAckOnce) {
  StartConnect();
  client_->Handshake();
  server_->Handshake();
  // At this point the server has sent it's first flight,
  // so make it drop the ACK.
  server_filters_.drop_->Reset({0});
  client_->Handshake();  // Send the client Finished.
  server_->Handshake();  // Receive the Finished and send the ACK.
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
  // Wait for the DTLS timeout to make sure we retransmit the
  // Finished.
  ShiftDtlsTimers();
  client_->Handshake();  // Retransmit the Finished.
  server_->Handshake();  // Read the Finished and send an ACK.
  uint8_t buf[1];
  PRInt32 rv = PR_Read(client_->ssl_fd(), buf, sizeof(buf));
  expected_server_acks_ = 2;
  EXPECT_GT(0, rv);
  EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
  CheckPostHandshake();
  // There should be two copies of the finished ACK
  CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
  CheckAcks(server_filters_.ack_, 1, {0x0002000000000000ULL});
}

// Drop the client certificate verify.
TEST_P(TlsDropDatagram13, DropClientCertVerify) {
  StartConnect();
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);
  client_->Handshake();
  server_->Handshake();
  // Have the client drop Cert Verify
  client_filters_.drop_->Reset({1});
  expected_server_acks_ = 2;
  CheckedHandshakeSendReceive();
  // Ack of the Cert.
  CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
  // Ack of the whole client handshake.
  CheckAcks(
      server_filters_.ack_, 1,
      {0x0002000000000000ULL,    // CH (we drop everything after this on client)
       0x0002000000000003ULL,    // CT (2)
       0x0002000000000004ULL});  // FIN (2)
}

// Shrink the MTU down so that certs get split and drop the first piece.
TEST_P(TlsDropDatagram13, DropFirstHalfOfServerCertificate) {
  server_filters_.drop_->Reset({2});
  StartConnect();
  ShrinkPostServerHelloMtu();
  client_->Handshake();
  server_->Handshake();
  // Check that things got split.
  EXPECT_EQ(6UL,
            server_filters_.records_->count());  // SH, EE, CT1, CT2, CV, FIN
  size_t ct1_size = server_filters_.record(2).buffer.len();
  server_filters_.records_->Clear();
  expected_client_acks_ = 1;
  HandshakeAndAck(client_);
  server_->Handshake();                               // Retransmit
  EXPECT_EQ(3UL, server_filters_.records_->count());  // CT2, CV, FIN
  // Check that the first record is CT1 (which is identical to the same
  // as the previous CT1).
  EXPECT_EQ(ct1_size, server_filters_.record(0).buffer.len());
  CheckedHandshakeSendReceive();
  CheckAcks(client_filters_.ack_, 0,
            {0,                        // SH
             0x0002000000000000ULL,    // EE
             0x0002000000000002ULL});  // CT2
  CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
}

// Shrink the MTU down so that certs get split and drop the second piece.
TEST_P(TlsDropDatagram13, DropSecondHalfOfServerCertificate) {
  server_filters_.drop_->Reset({3});
  StartConnect();
  ShrinkPostServerHelloMtu();
  client_->Handshake();
  server_->Handshake();
  // Check that things got split.
  EXPECT_EQ(6UL,
            server_filters_.records_->count());  // SH, EE, CT1, CT2, CV, FIN
  size_t ct1_size = server_filters_.record(3).buffer.len();
  server_filters_.records_->Clear();
  expected_client_acks_ = 1;
  HandshakeAndAck(client_);
  server_->Handshake();                               // Retransmit
  EXPECT_EQ(3UL, server_filters_.records_->count());  // CT1, CV, FIN
  // Check that the first record is CT1
  EXPECT_EQ(ct1_size, server_filters_.record(0).buffer.len());
  CheckedHandshakeSendReceive();
  CheckAcks(client_filters_.ack_, 0,
            {
                0,                      // SH
                0x0002000000000000ULL,  // EE
                0x0002000000000001ULL,  // CT1
            });
  CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
}

// In this test, the Certificate message is sent four times, we drop all or part
// of the first three attempts:
// 1. Without fragmentation so that we can see how big it is - we drop that.
// 2. In two pieces - we drop half AND the resulting ACK.
// 3. In three pieces - we drop the middle piece.
//
// After that we let all the ACKs through and allow the handshake to complete
// without further interference.
//
// This allows us to test that ranges of handshake messages are sent correctly
// even when there are overlapping acknowledgments; that ACKs with duplicate or
// overlapping message ranges are handled properly; and that extra
// retransmissions are handled properly.
class TlsFragmentationAndRecoveryTest : public TlsDropDatagram13 {
 public:
  TlsFragmentationAndRecoveryTest() : cert_len_(0) {}

 protected:
  void RunTest(size_t dropped_half) {
    FirstFlightDropCertificate();

    SecondAttemptDropHalf(dropped_half);
    size_t dropped_half_size = server_record_len(dropped_half);
    size_t second_flight_count = server_filters_.records_->count();

    ThirdAttemptDropMiddle();
    size_t repaired_third_size = server_record_len((dropped_half == 0) ? 0 : 2);
    size_t third_flight_count = server_filters_.records_->count();

    AckAndCompleteRetransmission();
    size_t final_server_flight_count = server_filters_.records_->count();
    EXPECT_LE(3U, final_server_flight_count);  // CT(sixth), CV, Fin
    CheckSizeOfSixth(dropped_half_size, repaired_third_size);

    SendDelayedAck();
    // Same number of messages as the last flight.
    EXPECT_EQ(final_server_flight_count, server_filters_.records_->count());
    // Double check that the Certificate size is still correct.
    CheckSizeOfSixth(dropped_half_size, repaired_third_size);

    CompleteHandshake(final_server_flight_count);

    // This is the ACK for the first attempt to send a whole certificate.
    std::vector<uint64_t> client_acks = {
        0,                     // SH
        0x0002000000000000ULL  // EE
    };
    CheckAcks(client_filters_.ack_, 0, client_acks);
    // And from the second attempt for the half was kept (we delayed this ACK).
    client_acks.push_back(0x0002000000000000ULL + second_flight_count +
                          ~dropped_half % 2);
    CheckAcks(client_filters_.ack_, 1, client_acks);
    // And the third attempt where the first and last thirds got through.
    client_acks.push_back(0x0002000000000000ULL + second_flight_count +
                          third_flight_count - 1);
    client_acks.push_back(0x0002000000000000ULL + second_flight_count +
                          third_flight_count + 1);
    CheckAcks(client_filters_.ack_, 2, client_acks);
    CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
  }

 private:
  void FirstFlightDropCertificate() {
    StartConnect();
    client_->Handshake();

    // Note: 1 << N is the Nth packet, starting from zero.
    server_filters_.drop_->Reset(1 << 2);  // Drop Cert0.
    server_->Handshake();
    EXPECT_EQ(5U, server_filters_.records_->count());  // SH, EE, CT, CV, Fin
    cert_len_ = server_filters_.records_->record(2).buffer.len();

    HandshakeAndAck(client_);
    EXPECT_EQ(2U, client_filters_.records_->count());
  }

  // Lower the MTU so that the server has to split the certificate in two
  // pieces.  The server resends Certificate (in two), plus CV and Fin.
  void SecondAttemptDropHalf(size_t dropped_half) {
    ASSERT_LE(0U, dropped_half);
    ASSERT_GT(2U, dropped_half);
    server_filters_.records_->Clear();
    server_filters_.drop_->Reset({dropped_half});  // Drop Cert1[half]
    SplitServerMtu(2);
    server_->Handshake();
    EXPECT_LE(4U, server_filters_.records_->count());  // CT x2, CV, Fin

    // Generate and capture the ACK from the client.
    client_filters_.drop_->Reset({0});
    HandshakeAndAck(client_);
    EXPECT_EQ(3U, client_filters_.records_->count());
  }

  // Lower the MTU again so that the server sends Certificate cut into three
  // pieces.  Drop the middle piece.
  void ThirdAttemptDropMiddle() {
    server_filters_.records_->Clear();
    server_filters_.drop_->Reset({1});  // Drop Cert2[1] (of 3)
    SplitServerMtu(3);
    // Because we dropped the client ACK, the server retransmits on a timer.
    ShiftDtlsTimers();
    server_->Handshake();
    EXPECT_LE(5U, server_filters_.records_->count());  // CT x3, CV, Fin
  }

  void AckAndCompleteRetransmission() {
    // Generate ACKs.
    HandshakeAndAck(client_);
    // The server should send the final sixth of the certificate: the client has
    // acknowledged the first half and the last third.  Also send CV and Fin.
    server_filters_.records_->Clear();
    server_->Handshake();
  }

  void CheckSizeOfSixth(size_t size_of_half, size_t size_of_third) {
    // Work out if the final sixth is the right size.  We get the records with
    // overheads added, which obscures the length of the payload.  We want to
    // ensure that the server only sent the missing sixth of the Certificate.
    //
    // We captured |size_of_half + overhead| and |size_of_third + overhead| and
    // want to calculate |size_of_third - size_of_third + overhead|.  We can't
    // calculate |overhead|, but it is is (currently) always a handshake message
    // header, a content type, and an authentication tag:
    static const size_t record_overhead = 12 + 1 + 16;
    EXPECT_EQ(size_of_half - size_of_third + record_overhead,
              server_filters_.records_->record(0).buffer.len());
  }

  void SendDelayedAck() {
    // Send the ACK we held back.  The reordered ACK doesn't add new
    // information,
    // but triggers an extra retransmission of the missing records again (even
    // though the client has all that it needs).
    client_->SendRecordDirect(client_filters_.records_->record(2));
    server_filters_.records_->Clear();
    server_->Handshake();
  }

  void CompleteHandshake(size_t extra_retransmissions) {
    // All this messing around shouldn't cause a failure...
    Handshake();
    // ...but it leaves a mess.  Add an extra few calls to Handshake() for the
    // client so that it absorbs the extra retransmissions.
    for (size_t i = 0; i < extra_retransmissions; ++i) {
      client_->Handshake();
    }
    CheckConnected();
  }

  // Split the server MTU so that the Certificate is split into |count| pieces.
  // The calculation doesn't need to be perfect as long as the Certificate
  // message is split into the right number of pieces.
  void SplitServerMtu(size_t count) {
    // Set the MTU based on the formula:
    // bare_size = cert_len_ - actual_overhead
    // MTU = ceil(bare_size / count) + pessimistic_overhead
    //
    // actual_overhead is the amount of actual overhead on the record we
    // captured, which is (note that our length doesn't include the header):
    static const size_t actual_overhead = 12 +  // handshake message header
                                          1 +   // content type
                                          16;   // authentication tag
    size_t bare_size = cert_len_ - actual_overhead;

    // pessimistic_overhead is the amount of expansion that NSS assumes will be
    // added to each handshake record.  Right now, that is DTLS_MIN_FRAGMENT:
    static const size_t pessimistic_overhead =
        12 +  // handshake message header
        1 +   // content type
        13 +  // record header length
        64;   // maximum record expansion: IV, MAC and block cipher expansion

    size_t mtu = (bare_size + count - 1) / count + pessimistic_overhead;
    if (g_ssl_gtest_verbose) {
      std::cerr << "server: set MTU to " << mtu << std::endl;
    }
    EXPECT_EQ(SECSuccess, SSLInt_SetMTU(server_->ssl_fd(), mtu));
  }

  size_t server_record_len(size_t index) const {
    return server_filters_.records_->record(index).buffer.len();
  }

  size_t cert_len_;
};

TEST_P(TlsFragmentationAndRecoveryTest, DropFirstHalf) { RunTest(0); }

TEST_P(TlsFragmentationAndRecoveryTest, DropSecondHalf) { RunTest(1); }

TEST_P(TlsDropDatagram13, NoDropsDuringZeroRtt) {
  SetupForZeroRtt();
  SetFilters();
  std::cerr << "Starting second handshake" << std::endl;
  client_->Set0RttEnabled(true);
  server_->Set0RttEnabled(true);
  ExpectResumption(RESUME_TICKET);
  ZeroRttSendReceive(true, true);
  Handshake();
  ExpectEarlyDataAccepted(true);
  CheckConnected();
  SendReceive();
  EXPECT_EQ(0U, client_filters_.ack_->count());
  CheckAcks(server_filters_.ack_, 0,
            {0x0001000000000001ULL,    // EOED
             0x0002000000000000ULL});  // Finished
}

TEST_P(TlsDropDatagram13, DropEEDuringZeroRtt) {
  SetupForZeroRtt();
  SetFilters();
  std::cerr << "Starting second handshake" << std::endl;
  client_->Set0RttEnabled(true);
  server_->Set0RttEnabled(true);
  ExpectResumption(RESUME_TICKET);
  server_filters_.drop_->Reset({1});
  ZeroRttSendReceive(true, true);
  HandshakeAndAck(client_);
  Handshake();
  ExpectEarlyDataAccepted(true);
  CheckConnected();
  SendReceive();
  CheckAcks(client_filters_.ack_, 0, {0});
  CheckAcks(server_filters_.ack_, 0,
            {0x0001000000000002ULL,    // EOED
             0x0002000000000000ULL});  // Finished
}

class TlsReorderDatagram13 : public TlsDropDatagram13 {
 public:
  TlsReorderDatagram13() {}

  // Send records from the records buffer in the given order.
  void ReSend(TlsAgent::Role side, std::vector<size_t> indices) {
    std::shared_ptr<TlsAgent> agent;
    std::shared_ptr<TlsRecordRecorder> records;

    if (side == TlsAgent::CLIENT) {
      agent = client_;
      records = client_filters_.records_;
    } else {
      agent = server_;
      records = server_filters_.records_;
    }

    for (auto i : indices) {
      agent->SendRecordDirect(records->record(i));
    }
  }
};

// Reorder the server records so that EE comes at the end
// of the flight and will still produce an ACK.
TEST_P(TlsDropDatagram13, ReorderServerEE) {
  server_filters_.drop_->Reset({1});
  StartConnect();
  client_->Handshake();
  server_->Handshake();
  // We dropped EE, now reinject.
  server_->SendRecordDirect(server_filters_.record(1));
  expected_client_acks_ = 1;
  HandshakeAndAck(client_);
  CheckedHandshakeSendReceive();
  CheckAcks(client_filters_.ack_, 0,
            {
                0,                   // SH
                0x0002000000000000,  // EE
            });
  CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
}

// The client sends an out of order non-handshake message
// but with the handshake key.
TEST_F(TlsConnectDatagram13, SendOutOfOrderAppWithHandshakeKey) {
  StartConnect();
  // Capturing secrets means that we can't use decrypting filters on the client.
  TlsSendCipherSpecCapturer capturer(client_);
  client_->Handshake();
  server_->Handshake();
  client_->Handshake();
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
  server_->Handshake();
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
  // After the client sends Finished, inject an app data record
  // with the handshake key. This should produce an alert.
  uint8_t buf[] = {'a', 'b', 'c'};
  auto spec = capturer.spec(0);
  ASSERT_NE(nullptr, spec.get());
  ASSERT_EQ(2, spec->epoch());

  uint8_t dtls13_ct = kCtDtlsCiphertext | kCtDtlsCiphertext16bSeqno |
                      kCtDtlsCiphertextLengthPresent;
  ASSERT_TRUE(client_->SendEncryptedRecord(spec, 0x0002000000000002, dtls13_ct,
                                           DataBuffer(buf, sizeof(buf))));

  // Now have the server consume the bogus message.
  server_->ExpectSendAlert(illegal_parameter, kTlsAlertFatal);
  server_->Handshake();
  EXPECT_EQ(TlsAgent::STATE_ERROR, server_->state());
  EXPECT_EQ(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, PORT_GetError());
}

TEST_F(TlsConnectDatagram13, SendOutOfOrderHsNonsenseWithHandshakeKey) {
  StartConnect();
  TlsSendCipherSpecCapturer capturer(client_);
  auto acks = MakeTlsFilter<TlsRecordRecorder>(server_, ssl_ct_ack);
  acks->EnableDecryption();

  client_->Handshake();
  server_->Handshake();
  client_->Handshake();
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
  server_->Handshake();
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
  // Inject a new bogus handshake record, which the server responds
  // to by just ACKing the original one (we ignore the contents).
  uint8_t buf[] = {'a', 'b', 'c'};
  auto spec = capturer.spec(0);
  ASSERT_NE(nullptr, spec.get());
  ASSERT_EQ(2, spec->epoch());
  ASSERT_TRUE(client_->SendEncryptedRecord(spec, 0x0002000000000002,
                                           ssl_ct_handshake,
                                           DataBuffer(buf, sizeof(buf))));
  server_->Handshake();
  EXPECT_EQ(2UL, acks->count());
  // The server acknowledges client Finished twice.
  CheckAcks(acks, 0, {0x0002000000000000ULL});
  CheckAcks(acks, 1, {0x0002000000000000ULL});
}

// Shrink the MTU down so that certs get split and then swap the first and
// second pieces of the server certificate.
TEST_P(TlsReorderDatagram13, ReorderServerCertificate) {
  StartConnect();
  ShrinkPostServerHelloMtu();
  client_->Handshake();
  // Drop the entire handshake flight so we can reorder.
  server_filters_.drop_->Reset(0xff);
  server_->Handshake();
  // Check that things got split.
  EXPECT_EQ(6UL,
            server_filters_.records_->count());  // CH, EE, CT1, CT2, CV, FIN
  // Now re-send things in a different order.
  ReSend(TlsAgent::SERVER, std::vector<size_t>{0, 1, 3, 2, 4, 5});
  // Clear.
  server_filters_.drop_->Disable();
  server_filters_.records_->Clear();
  // Wait for client to send ACK.
  ShiftDtlsTimers();
  CheckedHandshakeSendReceive();
  EXPECT_EQ(2UL, server_filters_.records_->count());  // ACK + Data
  CheckAcks(server_filters_.ack_, 0, {0x0002000000000000ULL});
}

TEST_P(TlsReorderDatagram13, DataAfterEOEDDuringZeroRtt) {
  SetupForZeroRtt();
  SetFilters();
  std::cerr << "Starting second handshake" << std::endl;
  client_->Set0RttEnabled(true);
  server_->Set0RttEnabled(true);
  ExpectResumption(RESUME_TICKET);
  // Send the client's first flight of zero RTT data.
  ZeroRttSendReceive(true, true);
  // Now send another client application data record but
  // capture it.
  client_filters_.records_->Clear();
  client_filters_.drop_->Reset(0xff);
  const char* k0RttData = "123456";
  const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData));
  PRInt32 rv =
      PR_Write(client_->ssl_fd(), k0RttData, k0RttDataLen);  // 0-RTT write.
  EXPECT_EQ(k0RttDataLen, rv);
  EXPECT_EQ(1UL, client_filters_.records_->count());  // data
  server_->Handshake();
  client_->Handshake();
  ExpectEarlyDataAccepted(true);
  // The server still hasn't received anything at this point.
  EXPECT_EQ(3UL, client_filters_.records_->count());  // data, EOED, FIN
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
  EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state());
  // Now re-send the client's messages: EOED, data, FIN
  ReSend(TlsAgent::CLIENT, std::vector<size_t>({1, 0, 2}));
  server_->Handshake();
  CheckConnected();
  EXPECT_EQ(0U, client_filters_.ack_->count());
  // Acknowledgements for EOED and Finished.
  CheckAcks(server_filters_.ack_, 0,
            {0x0001000000000002ULL, 0x0002000000000000ULL});
  uint8_t buf[8];
  rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf));
  EXPECT_EQ(-1, rv);
  EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
}

TEST_P(TlsReorderDatagram13, DataAfterFinDuringZeroRtt) {
  SetupForZeroRtt();
  SetFilters();
  std::cerr << "Starting second handshake" << std::endl;
  client_->Set0RttEnabled(true);
  server_->Set0RttEnabled(true);
  ExpectResumption(RESUME_TICKET);
  // Send the client's first flight of zero RTT data.
  ZeroRttSendReceive(true, true);
  // Now send another client application data record but
  // capture it.
  client_filters_.records_->Clear();
  client_filters_.drop_->Reset(0xff);
  const char* k0RttData = "123456";
  const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData));
  PRInt32 rv =
      PR_Write(client_->ssl_fd(), k0RttData, k0RttDataLen);  // 0-RTT write.
  EXPECT_EQ(k0RttDataLen, rv);
  EXPECT_EQ(1UL, client_filters_.records_->count());  // data
  server_->Handshake();
  client_->Handshake();
  ExpectEarlyDataAccepted(true);
  // The server still hasn't received anything at this point.
  EXPECT_EQ(3UL, client_filters_.records_->count());  // EOED, FIN, Data
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
  EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state());
  // Now re-send the client's messages: EOED, FIN, Data
  ReSend(TlsAgent::CLIENT, std::vector<size_t>({1, 2, 0}));
  server_->Handshake();
  CheckConnected();
  EXPECT_EQ(0U, client_filters_.ack_->count());
  // Acknowledgements for EOED and Finished.
  CheckAcks(server_filters_.ack_, 0,
            {0x0001000000000002ULL, 0x0002000000000000ULL});
  uint8_t buf[8];
  rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf));
  EXPECT_EQ(-1, rv);
  EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
}

static void GetCipherAndLimit(uint16_t version, uint16_t* cipher,
                              uint64_t* limit = nullptr) {
  uint64_t l;
  if (!limit) limit = &l;

  if (version < SSL_LIBRARY_VERSION_TLS_1_2) {
    *cipher = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
    *limit = 0x5aULL << 28;
  } else if (version == SSL_LIBRARY_VERSION_TLS_1_2) {
    *cipher = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
    *limit = (1ULL << 48) - 1;
  } else {
    // This test probably isn't especially useful for TLS 1.3, which has a much
    // shorter sequence number encoding.  That space can probably be searched in
    // a reasonable amount of time.
    *cipher = TLS_CHACHA20_POLY1305_SHA256;
    // Assume that we are starting with an expected sequence number of 0.
    *limit = (1ULL << 15) - 1;
  }
}

// This simulates a huge number of drops on one side.
// See Bug 12965514 where a large gap was handled very inefficiently.
TEST_P(TlsConnectDatagram, MissLotsOfPackets) {
  uint16_t cipher;
  uint64_t limit;

  GetCipherAndLimit(version_, &cipher, &limit);

  EnsureTlsSetup();
  server_->EnableSingleCipher(cipher);
  Connect();

  // Note that the limit for ChaCha is 2^48-1.
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), limit - 10));
  SendReceive();
}

// Send a sequence number of 0xfffd and it should be interpreted as that
// (and not -3 or UINT64_MAX - 2).
TEST_F(TlsConnectDatagram13, UnderflowSequenceNumber) {
  Connect();
  // This is only valid if short headers are disabled.
  client_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, PR_FALSE);
  EXPECT_EQ(SECSuccess,
            SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), (1ULL << 16) - 3));
  SendReceive();
}

class TlsConnectDatagram12Plus : public TlsConnectDatagram {
 public:
  TlsConnectDatagram12Plus() : TlsConnectDatagram() {}
};

// This simulates missing a window's worth of packets.
TEST_P(TlsConnectDatagram12Plus, MissAWindow) {
  EnsureTlsSetup();
  uint16_t cipher;
  GetCipherAndLimit(version_, &cipher);
  server_->EnableSingleCipher(cipher);
  Connect();
  EXPECT_EQ(SECSuccess, SSLInt_AdvanceWriteSeqByAWindow(client_->ssl_fd(), 0));
  SendReceive();
}

TEST_P(TlsConnectDatagram12Plus, MissAWindowAndOne) {
  EnsureTlsSetup();
  uint16_t cipher;
  GetCipherAndLimit(version_, &cipher);
  server_->EnableSingleCipher(cipher);
  Connect();

  EXPECT_EQ(SECSuccess, SSLInt_AdvanceWriteSeqByAWindow(client_->ssl_fd(), 1));
  SendReceive();
}

// This filter replaces the first record it sees with junk application data.
class TlsReplaceFirstRecordWithJunk : public TlsRecordFilter {
 public:
  TlsReplaceFirstRecordWithJunk(const std::shared_ptr<TlsAgent>& a)
      : TlsRecordFilter(a), replaced_(false) {}

 protected:
  PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                    const DataBuffer& record, size_t* offset,
                                    DataBuffer* output) override {
    if (replaced_) {
      return KEEP;
    }
    replaced_ = true;

    uint8_t dtls13_ct = kCtDtlsCiphertext | kCtDtlsCiphertext16bSeqno |
                        kCtDtlsCiphertextLengthPresent;
    TlsRecordHeader out_header(
        header.variant(), header.version(),
        is_dtls13() ? dtls13_ct : ssl_ct_application_data,
        header.sequence_number());

    static const uint8_t junk[] = {1, 2, 3, 4};
    *offset = out_header.Write(output, *offset, DataBuffer(junk, sizeof(junk)));
    return CHANGE;
  }

 private:
  bool replaced_;
};

// DTLS needs to discard application_data that it receives prior to handshake
// completion, not generate an error.
TEST_P(TlsConnectDatagram, ReplaceFirstServerRecordWithApplicationData) {
  MakeTlsFilter<TlsReplaceFirstRecordWithJunk>(server_);
  Connect();
}

TEST_P(TlsConnectDatagram, ReplaceFirstClientRecordWithApplicationData) {
  MakeTlsFilter<TlsReplaceFirstRecordWithJunk>(client_);
  Connect();
}

INSTANTIATE_TEST_SUITE_P(Datagram12Plus, TlsConnectDatagram12Plus,
                         TlsConnectTestBase::kTlsV12Plus);
INSTANTIATE_TEST_SUITE_P(DatagramPre13, TlsConnectDatagramPre13,
                         TlsConnectTestBase::kTlsV11V12);
INSTANTIATE_TEST_SUITE_P(DatagramDrop13, TlsDropDatagram13,
                         ::testing::Values(true, false));
INSTANTIATE_TEST_SUITE_P(DatagramReorder13, TlsReorderDatagram13,
                         ::testing::Values(true, false));
INSTANTIATE_TEST_SUITE_P(DatagramFragment13, TlsFragmentationAndRecoveryTest,
                         ::testing::Values(true, false));

}  // namespace nss_test
