/* -*- 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 "ssl.h"
#include "sslerr.h"
#include "sslproto.h"

#include <memory>

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

namespace nss_test {

// Tests for Certificate Transparency (RFC 6962)
// These don't work with TLS 1.3: see bug 1252745.

// Helper class - stores signed certificate timestamps as provided
// by the relevant callbacks on the client.
class SignedCertificateTimestampsExtractor {
 public:
  SignedCertificateTimestampsExtractor(std::shared_ptr<TlsAgent>& client)
      : client_(client) {
    client->SetAuthCertificateCallback(
        [this](TlsAgent* agent, bool checksig, bool isServer) -> SECStatus {
          const SECItem* scts = SSL_PeerSignedCertTimestamps(agent->ssl_fd());
          EXPECT_TRUE(scts);
          if (!scts) {
            return SECFailure;
          }
          auth_timestamps_.reset(new DataBuffer(scts->data, scts->len));
          return SECSuccess;
        });
    client->SetHandshakeCallback([this](TlsAgent* agent) {
      const SECItem* scts = SSL_PeerSignedCertTimestamps(agent->ssl_fd());
      ASSERT_TRUE(scts);
      handshake_timestamps_.reset(new DataBuffer(scts->data, scts->len));
    });
  }

  void assertTimestamps(const DataBuffer& timestamps) {
    EXPECT_TRUE(auth_timestamps_);
    EXPECT_EQ(timestamps, *auth_timestamps_);

    EXPECT_TRUE(handshake_timestamps_);
    EXPECT_EQ(timestamps, *handshake_timestamps_);

    const SECItem* current =
        SSL_PeerSignedCertTimestamps(client_.lock()->ssl_fd());
    EXPECT_EQ(timestamps, DataBuffer(current->data, current->len));
  }

 private:
  std::weak_ptr<TlsAgent> client_;
  std::unique_ptr<DataBuffer> auth_timestamps_;
  std::unique_ptr<DataBuffer> handshake_timestamps_;
};

static const uint8_t kSctValue[] = {0x01, 0x23, 0x45, 0x67, 0x89};
static const SECItem kSctItem = {siBuffer, const_cast<uint8_t*>(kSctValue),
                                 sizeof(kSctValue)};
static const DataBuffer kSctBuffer(kSctValue, sizeof(kSctValue));
static const SSLExtraServerCertData kExtraSctData = {ssl_auth_null, nullptr,
                                                     nullptr, &kSctItem};

// Test timestamps extraction during a successful handshake.
TEST_P(TlsConnectGenericPre13, SignedCertificateTimestampsLegacy) {
  EnsureTlsSetup();

  // We have to use the legacy API consistently here for configuring certs.
  // Also, this doesn't work in TLS 1.3 because this only configures the SCT for
  // RSA decrypt and PKCS#1 signing, not PSS.
  ScopedCERTCertificate cert;
  ScopedSECKEYPrivateKey priv;
  ASSERT_TRUE(TlsAgent::LoadCertificate(TlsAgent::kServerRsa, &cert, &priv));
  EXPECT_EQ(SECSuccess, SSL_ConfigSecureServerWithCertChain(
                            server_->ssl_fd(), cert.get(), nullptr, priv.get(),
                            ssl_kea_rsa));
  EXPECT_EQ(SECSuccess, SSL_SetSignedCertTimestamps(server_->ssl_fd(),
                                                    &kSctItem, ssl_kea_rsa));

  client_->SetOption(SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE);
  SignedCertificateTimestampsExtractor timestamps_extractor(client_);

  Connect();

  timestamps_extractor.assertTimestamps(kSctBuffer);
}

TEST_P(TlsConnectGeneric, SignedCertificateTimestampsSuccess) {
  EnsureTlsSetup();
  EXPECT_TRUE(
      server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kExtraSctData));
  client_->SetOption(SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE);
  SignedCertificateTimestampsExtractor timestamps_extractor(client_);

  Connect();

  timestamps_extractor.assertTimestamps(kSctBuffer);
}

// Test SSL_PeerSignedCertTimestamps returning zero-length SECItem
// when the client / the server / both have not enabled the feature.
TEST_P(TlsConnectGeneric, SignedCertificateTimestampsInactiveClient) {
  EnsureTlsSetup();
  EXPECT_TRUE(
      server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kExtraSctData));
  SignedCertificateTimestampsExtractor timestamps_extractor(client_);

  Connect();
  timestamps_extractor.assertTimestamps(DataBuffer());
}

TEST_P(TlsConnectGeneric, SignedCertificateTimestampsInactiveServer) {
  EnsureTlsSetup();
  client_->SetOption(SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE);
  SignedCertificateTimestampsExtractor timestamps_extractor(client_);

  Connect();
  timestamps_extractor.assertTimestamps(DataBuffer());
}

TEST_P(TlsConnectGeneric, SignedCertificateTimestampsInactiveBoth) {
  EnsureTlsSetup();
  SignedCertificateTimestampsExtractor timestamps_extractor(client_);

  Connect();
  timestamps_extractor.assertTimestamps(DataBuffer());
}

// Check that the given agent doesn't have an OCSP response for its peer.
static SECStatus CheckNoOCSP(TlsAgent* agent, bool checksig, bool isServer) {
  const SECItemArray* ocsp = SSL_PeerStapledOCSPResponses(agent->ssl_fd());
  EXPECT_TRUE(ocsp);
  EXPECT_EQ(0U, ocsp->len);
  return SECSuccess;
}

static const uint8_t kOcspValue1[] = {1, 2, 3, 4, 5, 6};
static const uint8_t kOcspValue2[] = {7, 8, 9};
static const SECItem kOcspItems[] = {
    {siBuffer, const_cast<uint8_t*>(kOcspValue1), sizeof(kOcspValue1)},
    {siBuffer, const_cast<uint8_t*>(kOcspValue2), sizeof(kOcspValue2)}};
static const SECItemArray kOcspResponses = {const_cast<SECItem*>(kOcspItems),
                                            PR_ARRAY_SIZE(kOcspItems)};
const static SSLExtraServerCertData kOcspExtraData = {ssl_auth_null, nullptr,
                                                      &kOcspResponses, nullptr};

TEST_P(TlsConnectGeneric, NoOcsp) {
  EnsureTlsSetup();
  client_->SetAuthCertificateCallback(CheckNoOCSP);
  Connect();
}

// The client doesn't get OCSP stapling unless it asks.
TEST_P(TlsConnectGeneric, OcspNotRequested) {
  EnsureTlsSetup();
  client_->SetAuthCertificateCallback(CheckNoOCSP);
  EXPECT_TRUE(
      server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kOcspExtraData));
  Connect();
}

// Even if the client asks, the server has nothing unless it is configured.
TEST_P(TlsConnectGeneric, OcspNotProvided) {
  EnsureTlsSetup();
  client_->SetOption(SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
  client_->SetAuthCertificateCallback(CheckNoOCSP);
  Connect();
}

TEST_P(TlsConnectGenericPre13, OcspMangled) {
  EnsureTlsSetup();
  client_->SetOption(SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
  EXPECT_TRUE(
      server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kOcspExtraData));

  static const uint8_t val[] = {1};
  auto replacer = MakeTlsFilter<TlsExtensionReplacer>(
      server_, ssl_cert_status_xtn, DataBuffer(val, sizeof(val)));
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}

TEST_P(TlsConnectGeneric, OcspSuccess) {
  EnsureTlsSetup();
  client_->SetOption(SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
  auto capture_ocsp =
      MakeTlsFilter<TlsExtensionCapture>(server_, ssl_cert_status_xtn);

  // The value should be available during the AuthCertificateCallback
  client_->SetAuthCertificateCallback([](TlsAgent* agent, bool checksig,
                                         bool isServer) -> SECStatus {
    const SECItemArray* ocsp = SSL_PeerStapledOCSPResponses(agent->ssl_fd());
    if (!ocsp) {
      return SECFailure;
    }
    EXPECT_EQ(1U, ocsp->len) << "We only provide the first item";
    EXPECT_EQ(0, SECITEM_CompareItem(&kOcspItems[0], &ocsp->items[0]));
    return SECSuccess;
  });
  EXPECT_TRUE(
      server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kOcspExtraData));

  Connect();
  // In TLS 1.3, the server doesn't provide a visible ServerHello extension.
  // For earlier versions, the extension is just empty.
  EXPECT_EQ(0U, capture_ocsp->extension().len());
}

TEST_P(TlsConnectGeneric, OcspHugeSuccess) {
  EnsureTlsSetup();
  client_->SetOption(SSL_ENABLE_OCSP_STAPLING, PR_TRUE);

  uint8_t hugeOcspValue[16385];
  memset(hugeOcspValue, 0xa1, sizeof(hugeOcspValue));
  const SECItem hugeOcspItems[] = {
      {siBuffer, const_cast<uint8_t*>(hugeOcspValue), sizeof(hugeOcspValue)}};
  const SECItemArray hugeOcspResponses = {const_cast<SECItem*>(hugeOcspItems),
                                          PR_ARRAY_SIZE(hugeOcspItems)};
  const SSLExtraServerCertData hugeOcspExtraData = {
      ssl_auth_null, nullptr, &hugeOcspResponses, nullptr};

  // The value should be available during the AuthCertificateCallback
  client_->SetAuthCertificateCallback([&](TlsAgent* agent, bool checksig,
                                          bool isServer) -> SECStatus {
    const SECItemArray* ocsp = SSL_PeerStapledOCSPResponses(agent->ssl_fd());
    if (!ocsp) {
      return SECFailure;
    }
    EXPECT_EQ(1U, ocsp->len) << "We only provide the first item";
    EXPECT_EQ(0, SECITEM_CompareItem(&hugeOcspItems[0], &ocsp->items[0]));
    return SECSuccess;
  });
  EXPECT_TRUE(server_->ConfigServerCert(TlsAgent::kServerRsa, true,
                                        &hugeOcspExtraData));

  Connect();
}

}  // namespace nss_test
