/* -*- 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 <functional>
#include <memory>
#include <vector>
#include "secerr.h"
#include "ssl.h"
#include "sslerr.h"
#include "sslproto.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(TlsConnectGeneric, SetupOnly) {}

TEST_P(TlsConnectGeneric, Connect) {
  SetExpectedVersion(std::get<1>(GetParam()));
  Connect();
  CheckKeys();
}

TEST_P(TlsConnectGeneric, ConnectEcdsa) {
  SetExpectedVersion(std::get<1>(GetParam()));
  Reset(TlsAgent::kServerEcdsa256);
  Connect();
  CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
}

TEST_P(TlsConnectGeneric, CipherSuiteMismatch) {
  EnsureTlsSetup();
  if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
    client_->EnableSingleCipher(TLS_AES_128_GCM_SHA256);
    server_->EnableSingleCipher(TLS_AES_256_GCM_SHA384);
  } else {
    client_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
    server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
  }
  ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
  client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
  server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
}

class TlsAlertRecorder : public TlsRecordFilter {
 public:
  TlsAlertRecorder(const std::shared_ptr<TlsAgent>& a)
      : TlsRecordFilter(a), level_(255), description_(255) {}

  PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                    const DataBuffer& input,
                                    DataBuffer* output) override {
    if (level_ != 255) {  // Already captured.
      return KEEP;
    }
    if (header.content_type() != ssl_ct_alert) {
      return KEEP;
    }

    std::cerr << "Alert: " << input << std::endl;

    TlsParser parser(input);
    EXPECT_TRUE(parser.Read(&level_));
    EXPECT_TRUE(parser.Read(&description_));
    return KEEP;
  }

  uint8_t level() const { return level_; }
  uint8_t description() const { return description_; }

 private:
  uint8_t level_;
  uint8_t description_;
};

class HelloTruncator : public TlsHandshakeFilter {
 public:
  HelloTruncator(const std::shared_ptr<TlsAgent>& a)
      : TlsHandshakeFilter(
            a, {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {}
  PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                       const DataBuffer& input,
                                       DataBuffer* output) override {
    output->Assign(input.data(), input.len() - 1);
    return CHANGE;
  }
};

// Verify that when NSS reports that an alert is sent, it is actually sent.
TEST_P(TlsConnectGeneric, CaptureAlertServer) {
  MakeTlsFilter<HelloTruncator>(client_);
  auto alert_recorder = MakeTlsFilter<TlsAlertRecorder>(server_);

  ConnectExpectAlert(server_, kTlsAlertDecodeError);
  EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
  EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description());
}

TEST_P(TlsConnectGenericPre13, CaptureAlertClient) {
  MakeTlsFilter<HelloTruncator>(server_);
  auto alert_recorder = MakeTlsFilter<TlsAlertRecorder>(client_);

  ConnectExpectAlert(client_, kTlsAlertDecodeError);
  EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
  EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description());
}

// In TLS 1.3, the server can't read the client alert.
TEST_P(TlsConnectTls13, CaptureAlertClient) {
  MakeTlsFilter<HelloTruncator>(server_);
  auto alert_recorder = MakeTlsFilter<TlsAlertRecorder>(client_);

  StartConnect();

  client_->Handshake();
  client_->ExpectSendAlert(kTlsAlertDecodeError);
  server_->Handshake();
  client_->Handshake();
  if (variant_ == ssl_variant_stream) {
    // DTLS just drops the alert it can't decrypt.
    server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
  }
  server_->Handshake();
  EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
  EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description());
}

TEST_P(TlsConnectGenericPre13, ConnectFalseStart) {
  client_->EnableFalseStart();
  Connect();
  SendReceive();
}

TEST_P(TlsConnectGeneric, ConnectAlpn) {
  EnableAlpn();
  Connect();
  CheckAlpn("a");
}

TEST_P(TlsConnectGeneric, ConnectAlpnPriorityA) {
  // "alpn" "npn"
  // alpn is the fallback here. npn has the highest priority and should be
  // picked.
  const std::vector<uint8_t> alpn = {0x04, 0x61, 0x6c, 0x70, 0x6e,
                                     0x03, 0x6e, 0x70, 0x6e};
  EnableAlpn(alpn);
  Connect();
  CheckAlpn("npn");
}

TEST_P(TlsConnectGeneric, ConnectAlpnPriorityB) {
  // "alpn" "npn" "http"
  // npn has the highest priority and should be picked.
  const std::vector<uint8_t> alpn = {0x04, 0x61, 0x6c, 0x70, 0x6e, 0x03, 0x6e,
                                     0x70, 0x6e, 0x04, 0x68, 0x74, 0x74, 0x70};
  EnableAlpn(alpn);
  Connect();
  CheckAlpn("npn");
}

TEST_P(TlsConnectGeneric, ConnectAlpnClone) {
  EnsureModelSockets();
  client_model_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
  server_model_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
  Connect();
  CheckAlpn("a");
}

TEST_P(TlsConnectGeneric, ConnectAlpnWithCustomCallbackA) {
  // "ab" "alpn"
  const std::vector<uint8_t> client_alpn = {0x02, 0x61, 0x62, 0x04,
                                            0x61, 0x6c, 0x70, 0x6e};
  EnableAlpnWithCallback(client_alpn, "alpn");
  Connect();
  CheckAlpn("alpn");
}

TEST_P(TlsConnectGeneric, ConnectAlpnWithCustomCallbackB) {
  // "ab" "alpn"
  const std::vector<uint8_t> client_alpn = {0x02, 0x61, 0x62, 0x04,
                                            0x61, 0x6c, 0x70, 0x6e};
  EnableAlpnWithCallback(client_alpn, "ab");
  Connect();
  CheckAlpn("ab");
}

TEST_P(TlsConnectGeneric, ConnectAlpnWithCustomCallbackC) {
  // "cd" "npn" "alpn"
  const std::vector<uint8_t> client_alpn = {0x02, 0x63, 0x64, 0x03, 0x6e, 0x70,
                                            0x6e, 0x04, 0x61, 0x6c, 0x70, 0x6e};
  EnableAlpnWithCallback(client_alpn, "npn");
  Connect();
  CheckAlpn("npn");
}

TEST_P(TlsConnectDatagram, ConnectSrtp) {
  EnableSrtp();
  Connect();
  CheckSrtp();
  SendReceive();
}

TEST_P(TlsConnectGeneric, ConnectSendReceive) {
  Connect();
  SendReceive();
}

class SaveTlsRecord : public TlsRecordFilter {
 public:
  SaveTlsRecord(const std::shared_ptr<TlsAgent>& a, size_t index)
      : TlsRecordFilter(a), index_(index), count_(0), contents_() {}

  const DataBuffer& contents() const { return contents_; }

 protected:
  PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                    const DataBuffer& data,
                                    DataBuffer* changed) override {
    if (count_++ == index_) {
      contents_ = data;
    }
    return KEEP;
  }

 private:
  const size_t index_;
  size_t count_;
  DataBuffer contents_;
};

// Check that decrypting filters work and can read any record.
// This test (currently) only works in TLS 1.3 where we can decrypt.
TEST_F(TlsConnectStreamTls13, DecryptRecordClient) {
  EnsureTlsSetup();
  // 0 = ClientHello, 1 = Finished, 2 = SendReceive, 3 = SendBuffer
  auto saved = MakeTlsFilter<SaveTlsRecord>(client_, 3);
  saved->EnableDecryption();
  Connect();
  SendReceive();

  static const uint8_t data[] = {0xde, 0xad, 0xdc};
  DataBuffer buf(data, sizeof(data));
  client_->SendBuffer(buf);
  EXPECT_EQ(buf, saved->contents());
}

TEST_F(TlsConnectStreamTls13, DecryptRecordServer) {
  EnsureTlsSetup();
  // Disable tickets so that we are sure to not get NewSessionTicket.
  EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(),
                                      SSL_ENABLE_SESSION_TICKETS, PR_FALSE));
  // 0 = ServerHello, 1 = other handshake, 2 = SendReceive, 3 = SendBuffer
  auto saved = MakeTlsFilter<SaveTlsRecord>(server_, 3);
  saved->EnableDecryption();
  Connect();
  SendReceive();

  static const uint8_t data[] = {0xde, 0xad, 0xd5};
  DataBuffer buf(data, sizeof(data));
  server_->SendBuffer(buf);
  EXPECT_EQ(buf, saved->contents());
}

class DropTlsRecord : public TlsRecordFilter {
 public:
  DropTlsRecord(const std::shared_ptr<TlsAgent>& a, size_t index)
      : TlsRecordFilter(a), index_(index), count_(0) {}

 protected:
  PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                    const DataBuffer& data,
                                    DataBuffer* changed) override {
    if (count_++ == index_) {
      return DROP;
    }
    return KEEP;
  }

 private:
  const size_t index_;
  size_t count_;
};

// Test that decrypting filters work correctly and are able to drop records.
TEST_F(TlsConnectStreamTls13, DropRecordServer) {
  EnsureTlsSetup();
  // Disable session tickets so that the server doesn't send an extra record.
  EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(),
                                      SSL_ENABLE_SESSION_TICKETS, PR_FALSE));

  // 0 = ServerHello, 1 = other handshake, 2 = first write
  auto filter = MakeTlsFilter<DropTlsRecord>(server_, 2);
  filter->EnableDecryption();
  Connect();
  server_->SendData(23, 23);  // This should be dropped, so it won't be counted.
  server_->ResetSentBytes();
  SendReceive();
}

TEST_F(TlsConnectStreamTls13, DropRecordClient) {
  EnsureTlsSetup();
  // 0 = ClientHello, 1 = Finished, 2 = first write
  auto filter = MakeTlsFilter<DropTlsRecord>(client_, 2);
  filter->EnableDecryption();
  Connect();
  client_->SendData(26, 26);  // This should be dropped, so it won't be counted.
  client_->ResetSentBytes();
  SendReceive();
}

// Check that a server can use 0.5 RTT if client authentication isn't enabled.
TEST_P(TlsConnectTls13, WriteBeforeClientFinished) {
  EnsureTlsSetup();
  StartConnect();
  client_->Handshake();  // ClientHello
  server_->Handshake();  // ServerHello

  server_->SendData(10);
  client_->ReadBytes(10);  // Client should emit the Finished as a side-effect.
  server_->Handshake();    // Server consumes the Finished.
  CheckConnected();
}

// We don't allow 0.5 RTT if client authentication is requested.
TEST_P(TlsConnectTls13, WriteBeforeClientFinishedClientAuth) {
  client_->SetupClientAuth();
  server_->RequestClientAuth(false);
  StartConnect();
  client_->Handshake();  // ClientHello
  server_->Handshake();  // ServerHello

  static const uint8_t data[] = {1, 2, 3};
  EXPECT_GT(0, PR_Write(server_->ssl_fd(), data, sizeof(data)));
  EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());

  Handshake();
  CheckConnected();
  SendReceive();
}

// 0.5 RTT should fail with client authentication required.
TEST_P(TlsConnectTls13, WriteBeforeClientFinishedClientAuthRequired) {
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);
  StartConnect();
  client_->Handshake();  // ClientHello
  server_->Handshake();  // ServerHello

  static const uint8_t data[] = {1, 2, 3};
  EXPECT_GT(0, PR_Write(server_->ssl_fd(), data, sizeof(data)));
  EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());

  Handshake();
  CheckConnected();
  SendReceive();
}

// The next two tests takes advantage of the fact that we
// automatically read the first 1024 bytes, so if
// we provide 1200 bytes, they overrun the read buffer
// provided by the calling test.

// DTLS should return an error.
TEST_P(TlsConnectDatagram, ShortRead) {
  Connect();
  client_->ExpectReadWriteError();
  server_->SendData(50, 50);
  client_->ReadBytes(20);
  EXPECT_EQ(0U, client_->received_bytes());
  EXPECT_EQ(SSL_ERROR_RX_SHORT_DTLS_READ, PORT_GetError());

  // Now send and receive another packet.
  server_->ResetSentBytes();  // Reset the counter.
  SendReceive();
}

// TLS should get the write in two chunks.
TEST_P(TlsConnectStream, ShortRead) {
  // This test behaves oddly with TLS 1.0 because of 1/n+1 splitting,
  // so skip in that case.
  if (version_ < SSL_LIBRARY_VERSION_TLS_1_1) GTEST_SKIP();

  Connect();
  server_->SendData(50, 50);
  // Read the first tranche.
  client_->ReadBytes(20);
  ASSERT_EQ(20U, client_->received_bytes());
  // The second tranche should now immediately be available.
  client_->ReadBytes();
  ASSERT_EQ(50U, client_->received_bytes());
}

// We enable compression via the API but it's disabled internally,
// so we should never get it.
TEST_P(TlsConnectGeneric, ConnectWithCompressionEnabled) {
  EnsureTlsSetup();
  client_->SetOption(SSL_ENABLE_DEFLATE, PR_TRUE);
  server_->SetOption(SSL_ENABLE_DEFLATE, PR_TRUE);
  Connect();
  EXPECT_FALSE(client_->is_compressed());
  SendReceive();
}

class TlsHolddownTest : public TlsConnectDatagram {
 protected:
  // This causes all timers to run to completion.  It advances the clock and
  // handshakes on both peers until both peers have no more timers pending,
  // which should happen at the end of a handshake.  This is necessary to ensure
  // that the relatively long holddown timer expires, but that any other timers
  // also expire and run correctly.
  void RunAllTimersDown() {
    while (true) {
      PRIntervalTime time;
      SECStatus rv = DTLS_GetHandshakeTimeout(client_->ssl_fd(), &time);
      if (rv != SECSuccess) {
        rv = DTLS_GetHandshakeTimeout(server_->ssl_fd(), &time);
        if (rv != SECSuccess) {
          break;  // Neither peer has an outstanding timer.
        }
      }

      if (g_ssl_gtest_verbose) {
        std::cerr << "Shifting timers" << std::endl;
      }
      ShiftDtlsTimers();
      Handshake();
    }
  }
};

TEST_P(TlsHolddownTest, TestDtlsHolddownExpiry) {
  Connect();
  std::cerr << "Expiring holddown timer" << std::endl;
  RunAllTimersDown();
  SendReceive();
  if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
    // One for send, one for receive.
    EXPECT_EQ(2, SSLInt_CountCipherSpecs(client_->ssl_fd()));
  }
}

TEST_P(TlsHolddownTest, TestDtlsHolddownExpiryResumption) {
  ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
  Connect();
  SendReceive();

  Reset();
  ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
  ExpectResumption(RESUME_TICKET);
  Connect();
  RunAllTimersDown();
  SendReceive();
  // One for send, one for receive.
  EXPECT_EQ(2, SSLInt_CountCipherSpecs(client_->ssl_fd()));
}

class TlsPreCCSHeaderInjector : public TlsRecordFilter {
 public:
  TlsPreCCSHeaderInjector(const std::shared_ptr<TlsAgent>& a)
      : TlsRecordFilter(a) {}
  virtual PacketFilter::Action FilterRecord(
      const TlsRecordHeader& record_header, const DataBuffer& input,
      size_t* offset, DataBuffer* output) override {
    if (record_header.content_type() != ssl_ct_change_cipher_spec) {
      return KEEP;
    }

    std::cerr << "Injecting Finished header before CCS\n";
    const uint8_t hhdr[] = {kTlsHandshakeFinished, 0x00, 0x00, 0x0c};
    DataBuffer hhdr_buf(hhdr, sizeof(hhdr));
    TlsRecordHeader nhdr(record_header.variant(), record_header.version(),
                         ssl_ct_handshake, 0);
    *offset = nhdr.Write(output, *offset, hhdr_buf);
    *offset = record_header.Write(output, *offset, input);
    return CHANGE;
  }
};

TEST_P(TlsConnectStreamPre13, ClientFinishedHeaderBeforeCCS) {
  MakeTlsFilter<TlsPreCCSHeaderInjector>(client_);
  ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage);
  client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
  server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
}

TEST_P(TlsConnectStreamPre13, ServerFinishedHeaderBeforeCCS) {
  MakeTlsFilter<TlsPreCCSHeaderInjector>(server_);
  StartConnect();
  ExpectAlert(client_, kTlsAlertUnexpectedMessage);
  Handshake();
  EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
  client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
  EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
  server_->Handshake();  // Make sure alert is consumed.
}

TEST_P(TlsConnectTls13, UnknownAlert) {
  Connect();
  server_->ExpectSendAlert(0xff, kTlsAlertWarning);
  client_->ExpectReceiveAlert(0xff, kTlsAlertWarning);
  SSLInt_SendAlert(server_->ssl_fd(), kTlsAlertWarning,
                   0xff);  // Unknown value.
  client_->ExpectReadWriteError();
  client_->WaitForErrorCode(SSL_ERROR_RX_UNKNOWN_ALERT, 2000);
}

TEST_P(TlsConnectTls13, AlertWrongLevel) {
  Connect();
  server_->ExpectSendAlert(kTlsAlertUnexpectedMessage, kTlsAlertWarning);
  client_->ExpectReceiveAlert(kTlsAlertUnexpectedMessage, kTlsAlertWarning);
  SSLInt_SendAlert(server_->ssl_fd(), kTlsAlertWarning,
                   kTlsAlertUnexpectedMessage);
  client_->ExpectReadWriteError();
  client_->WaitForErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT, 2000);
}

TEST_P(TlsConnectTls13, UnknownRecord) {
  static const uint8_t kUknownRecord[] = {
      0xff, SSL_LIBRARY_VERSION_TLS_1_2 >> 8,
      SSL_LIBRARY_VERSION_TLS_1_2 & 0xff, 0, 0};

  Connect();
  if (variant_ == ssl_variant_stream) {
    // DTLS just drops the record with an invalid type.
    server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
  }
  client_->SendDirect(DataBuffer(kUknownRecord, sizeof(kUknownRecord)));
  server_->ExpectReadWriteError();
  server_->ReadBytes();
  if (variant_ == ssl_variant_stream) {
    EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, server_->error_code());
  } else {
    EXPECT_EQ(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, server_->error_code());
  }
}

TEST_F(TlsConnectStreamTls13, Tls13FailedWriteSecondFlight) {
  EnsureTlsSetup();
  StartConnect();
  client_->Handshake();
  server_->Handshake();  // Send first flight.
  client_->adapter()->SetWriteError(PR_IO_ERROR);
  client_->Handshake();  // This will get an error, but shouldn't crash.
  client_->CheckErrorCode(SSL_ERROR_SOCKET_WRITE_FAILURE);
}

TEST_P(TlsConnectDatagram, BlockedWrite) {
  Connect();

  // Mark the socket as blocked.
  client_->adapter()->SetWriteError(PR_WOULD_BLOCK_ERROR);
  static const uint8_t data[] = {1, 2, 3};
  int32_t rv = PR_Write(client_->ssl_fd(), data, sizeof(data));
  EXPECT_GT(0, rv);
  EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());

  // Remove the write error and though the previous write failed, future reads
  // and writes should just work as if it never happened.
  client_->adapter()->SetWriteError(0);
  SendReceive();
}

TEST_F(TlsConnectTest, ConnectSSLv3) {
  ConfigureVersion(SSL_LIBRARY_VERSION_3_0);
  EnableOnlyStaticRsaCiphers();
  Connect();
  CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none);
}

TEST_F(TlsConnectTest, ConnectSSLv3ClientAuth) {
  ConfigureVersion(SSL_LIBRARY_VERSION_3_0);
  EnableOnlyStaticRsaCiphers();
  client_->SetupClientAuth();
  server_->RequestClientAuth(true);
  Connect();
  CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none);
}

static size_t ExpectedCbcLen(size_t in, size_t hmac = 20, size_t block = 16) {
  // MAC-then-Encrypt expansion formula:
  return ((in + hmac + (block - 1)) / block) * block;
}

TEST_F(TlsConnectTest, OneNRecordSplitting) {
  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_0);
  EnsureTlsSetup();
  ConnectWithCipherSuite(TLS_RSA_WITH_AES_128_CBC_SHA);
  auto records = MakeTlsFilter<TlsRecordRecorder>(server_);
  // This should be split into 1, 16384 and 20.
  DataBuffer big_buffer;
  big_buffer.Allocate(1 + 16384 + 20);
  server_->SendBuffer(big_buffer);
  ASSERT_EQ(3U, records->count());
  EXPECT_EQ(ExpectedCbcLen(1), records->record(0).buffer.len());
  EXPECT_EQ(ExpectedCbcLen(16384), records->record(1).buffer.len());
  EXPECT_EQ(ExpectedCbcLen(20), records->record(2).buffer.len());
}

// We can't test for randomness easily here, but we can test that we don't
// produce a zero value, or produce the same value twice.  There are 5 values
// here: two ClientHello.random, two ServerHello.random, and one zero value.
// Matrix them and fail if any are the same.
TEST_P(TlsConnectGeneric, CheckRandoms) {
  ConfigureSessionCache(RESUME_NONE, RESUME_NONE);

  static const size_t random_len = 32;
  uint8_t crandom1[random_len], srandom1[random_len];
  uint8_t z[random_len] = {0};

  auto ch = MakeTlsFilter<TlsHandshakeRecorder>(client_, ssl_hs_client_hello);
  auto sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
  Connect();
  ASSERT_TRUE(ch->buffer().len() > (random_len + 2));
  ASSERT_TRUE(sh->buffer().len() > (random_len + 2));
  memcpy(crandom1, ch->buffer().data() + 2, random_len);
  memcpy(srandom1, sh->buffer().data() + 2, random_len);
  EXPECT_NE(0, memcmp(crandom1, srandom1, random_len));
  EXPECT_NE(0, memcmp(crandom1, z, random_len));
  EXPECT_NE(0, memcmp(srandom1, z, random_len));

  Reset();
  ch = MakeTlsFilter<TlsHandshakeRecorder>(client_, ssl_hs_client_hello);
  sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
  Connect();
  ASSERT_TRUE(ch->buffer().len() > (random_len + 2));
  ASSERT_TRUE(sh->buffer().len() > (random_len + 2));
  const uint8_t* crandom2 = ch->buffer().data() + 2;
  const uint8_t* srandom2 = sh->buffer().data() + 2;

  EXPECT_NE(0, memcmp(crandom2, srandom2, random_len));
  EXPECT_NE(0, memcmp(crandom2, z, random_len));
  EXPECT_NE(0, memcmp(srandom2, z, random_len));

  EXPECT_NE(0, memcmp(crandom1, crandom2, random_len));
  EXPECT_NE(0, memcmp(crandom1, srandom2, random_len));
  EXPECT_NE(0, memcmp(srandom1, crandom2, random_len));
  EXPECT_NE(0, memcmp(srandom1, srandom2, random_len));
}

void FailOnCloseNotify(const PRFileDesc* fd, void* arg, const SSLAlert* alert) {
  ADD_FAILURE() << "received alert " << alert->description;
}

void CheckCloseNotify(const PRFileDesc* fd, void* arg, const SSLAlert* alert) {
  *reinterpret_cast<bool*>(arg) = true;
  EXPECT_EQ(close_notify, alert->description);
  EXPECT_EQ(alert_warning, alert->level);
}

TEST_P(TlsConnectGeneric, ShutdownOneSide) {
  Connect();

  // Setup to check alerts.
  EXPECT_EQ(SECSuccess, SSL_AlertSentCallback(server_->ssl_fd(),
                                              FailOnCloseNotify, nullptr));
  EXPECT_EQ(SECSuccess, SSL_AlertReceivedCallback(client_->ssl_fd(),
                                                  FailOnCloseNotify, nullptr));

  bool client_sent = false;
  EXPECT_EQ(SECSuccess, SSL_AlertSentCallback(client_->ssl_fd(),
                                              CheckCloseNotify, &client_sent));
  bool server_received = false;
  EXPECT_EQ(SECSuccess,
            SSL_AlertReceivedCallback(server_->ssl_fd(), CheckCloseNotify,
                                      &server_received));
  EXPECT_EQ(PR_SUCCESS, PR_Shutdown(client_->ssl_fd(), PR_SHUTDOWN_SEND));

  // Make sure that the server reads out the close_notify.
  uint8_t buf[10];
  EXPECT_EQ(0, PR_Read(server_->ssl_fd(), buf, sizeof(buf)));

  // Reading and writing should still work in the one open direction.
  EXPECT_TRUE(client_sent);
  EXPECT_TRUE(server_received);
  server_->SendData(10, 10);
  client_->ReadBytes(10);

  // Now close the other side and do the same checks.
  bool server_sent = false;
  EXPECT_EQ(SECSuccess, SSL_AlertSentCallback(server_->ssl_fd(),
                                              CheckCloseNotify, &server_sent));
  bool client_received = false;
  EXPECT_EQ(SECSuccess,
            SSL_AlertReceivedCallback(client_->ssl_fd(), CheckCloseNotify,
                                      &client_received));
  EXPECT_EQ(PR_SUCCESS, PR_Shutdown(server_->ssl_fd(), PR_SHUTDOWN_SEND));

  EXPECT_EQ(0, PR_Read(client_->ssl_fd(), buf, sizeof(buf)));
  EXPECT_TRUE(server_sent);
  EXPECT_TRUE(client_received);
}

TEST_P(TlsConnectGeneric, ShutdownOneSideThenCloseTcp) {
  Connect();

  bool client_sent = false;
  EXPECT_EQ(SECSuccess, SSL_AlertSentCallback(client_->ssl_fd(),
                                              CheckCloseNotify, &client_sent));
  bool server_received = false;
  EXPECT_EQ(SECSuccess,
            SSL_AlertReceivedCallback(server_->ssl_fd(), CheckCloseNotify,
                                      &server_received));
  EXPECT_EQ(PR_SUCCESS, PR_Shutdown(client_->ssl_fd(), PR_SHUTDOWN_SEND));

  // Make sure that the server reads out the close_notify.
  uint8_t buf[10];
  EXPECT_EQ(0, PR_Read(server_->ssl_fd(), buf, sizeof(buf)));

  // Now simulate the underlying connection closing.
  client_->adapter()->Reset();

  // Now close the other side and see that things don't explode.
  EXPECT_EQ(PR_SUCCESS, PR_Shutdown(server_->ssl_fd(), PR_SHUTDOWN_SEND));

  EXPECT_GT(0, PR_Read(client_->ssl_fd(), buf, sizeof(buf)));
  EXPECT_EQ(PR_NOT_CONNECTED_ERROR, PR_GetError());
}

INSTANTIATE_TEST_SUITE_P(
    GenericStream, TlsConnectGeneric,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
                       TlsConnectTestBase::kTlsVAll));
INSTANTIATE_TEST_SUITE_P(
    GenericDatagram, TlsConnectGeneric,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
                       TlsConnectTestBase::kTlsV11Plus));

INSTANTIATE_TEST_SUITE_P(StreamOnly, TlsConnectStream,
                         TlsConnectTestBase::kTlsVAll);
INSTANTIATE_TEST_SUITE_P(DatagramOnly, TlsConnectDatagram,
                         TlsConnectTestBase::kTlsV11Plus);
INSTANTIATE_TEST_SUITE_P(DatagramHolddown, TlsHolddownTest,
                         TlsConnectTestBase::kTlsV11Plus);

INSTANTIATE_TEST_SUITE_P(
    Pre12Stream, TlsConnectPre12,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
                       TlsConnectTestBase::kTlsV10V11));
INSTANTIATE_TEST_SUITE_P(
    Pre12Datagram, TlsConnectPre12,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
                       TlsConnectTestBase::kTlsV11));

INSTANTIATE_TEST_SUITE_P(Version12Only, TlsConnectTls12,
                         TlsConnectTestBase::kTlsVariantsAll);
#ifndef NSS_DISABLE_TLS_1_3
INSTANTIATE_TEST_SUITE_P(Version13Only, TlsConnectTls13,
                         TlsConnectTestBase::kTlsVariantsAll);
#endif

INSTANTIATE_TEST_SUITE_P(
    Pre13Stream, TlsConnectGenericPre13,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
                       TlsConnectTestBase::kTlsV10ToV12));
INSTANTIATE_TEST_SUITE_P(
    Pre13Datagram, TlsConnectGenericPre13,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
                       TlsConnectTestBase::kTlsV11V12));
INSTANTIATE_TEST_SUITE_P(Pre13StreamOnly, TlsConnectStreamPre13,
                         TlsConnectTestBase::kTlsV10ToV12);

INSTANTIATE_TEST_SUITE_P(Version12Plus, TlsConnectTls12Plus,
                         ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                                            TlsConnectTestBase::kTlsV12Plus));

INSTANTIATE_TEST_SUITE_P(
    GenericStream, TlsConnectGenericResumption,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
                       TlsConnectTestBase::kTlsVAll,
                       ::testing::Values(true, false)));
INSTANTIATE_TEST_SUITE_P(
    GenericDatagram, TlsConnectGenericResumption,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
                       TlsConnectTestBase::kTlsV11Plus,
                       ::testing::Values(true, false)));

INSTANTIATE_TEST_SUITE_P(
    GenericStream, TlsConnectGenericResumptionToken,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
                       TlsConnectTestBase::kTlsVAll));
INSTANTIATE_TEST_SUITE_P(
    GenericDatagram, TlsConnectGenericResumptionToken,
    ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
                       TlsConnectTestBase::kTlsV11Plus));

INSTANTIATE_TEST_SUITE_P(GenericDatagram, TlsConnectTls13ResumptionToken,
                         TlsConnectTestBase::kTlsVariantsAll);

}  // namespace nss_test
