// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/cert/ct_objects_extractor.h"

#include "base/files/file_path.h"
#include "net/base/test_data_directory.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/ct_serialization.h"
#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/x509_certificate.h"
#include "net/test/cert_test_util.h"
#include "net/test/ct_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace ct {

class CTObjectsExtractorTest : public ::testing::Test {
 public:
  void SetUp() override {
    precert_chain_ =
        CreateCertificateListFromFile(GetTestCertsDirectory(),
                                      "ct-test-embedded-cert.pem",
                                      X509Certificate::FORMAT_AUTO);
    ASSERT_EQ(2u, precert_chain_.size());

    std::string der_test_cert(ct::GetDerEncodedX509Cert());
    test_cert_ = X509Certificate::CreateFromBytes(der_test_cert.data(),
                                                  der_test_cert.length());

    log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog").Pass();
    ASSERT_TRUE(log_);
  }

  void ExtractEmbeddedSCT(scoped_refptr<X509Certificate> cert,
                          scoped_refptr<SignedCertificateTimestamp>* sct) {
    std::string sct_list;
    EXPECT_TRUE(ExtractEmbeddedSCTList(cert->os_cert_handle(), &sct_list));

    std::vector<base::StringPiece> parsed_scts;
    base::StringPiece sct_list_sp(sct_list);
    // Make sure the SCT list can be decoded properly
    EXPECT_TRUE(DecodeSCTList(&sct_list_sp, &parsed_scts));

    EXPECT_TRUE(DecodeSignedCertificateTimestamp(&parsed_scts[0], sct));
  }

 protected:
  CertificateList precert_chain_;
  scoped_refptr<X509Certificate> test_cert_;
  scoped_ptr<CTLogVerifier> log_;
};

// Test that an SCT can be extracted and the extracted SCT contains the
// expected data.
TEST_F(CTObjectsExtractorTest, ExtractEmbeddedSCT) {
  scoped_refptr<ct::SignedCertificateTimestamp> sct(
      new ct::SignedCertificateTimestamp());
  ExtractEmbeddedSCT(precert_chain_[0], &sct);

  EXPECT_EQ(sct->version, SignedCertificateTimestamp::SCT_VERSION_1);
  EXPECT_EQ(ct::GetTestPublicKeyId(), sct->log_id);

  base::Time expected_timestamp =
      base::Time::UnixEpoch() +
      base::TimeDelta::FromMilliseconds(1365181456275);
  EXPECT_EQ(expected_timestamp, sct->timestamp);
}

TEST_F(CTObjectsExtractorTest, ExtractPrecert) {
  LogEntry entry;
  ASSERT_TRUE(GetPrecertLogEntry(precert_chain_[0]->os_cert_handle(),
                                 precert_chain_[1]->os_cert_handle(),
                                 &entry));

  ASSERT_EQ(ct::LogEntry::LOG_ENTRY_TYPE_PRECERT, entry.type);
  // Should have empty leaf cert for this log entry type.
  ASSERT_TRUE(entry.leaf_certificate.empty());
  // Compare hash values of issuer spki.
  SHA256HashValue expected_issuer_key_hash;
  memcpy(expected_issuer_key_hash.data, GetDefaultIssuerKeyHash().data(), 32);
  ASSERT_TRUE(expected_issuer_key_hash.Equals(entry.issuer_key_hash));
}

TEST_F(CTObjectsExtractorTest, ExtractOrdinaryX509Cert) {
  LogEntry entry;
  ASSERT_TRUE(GetX509LogEntry(test_cert_->os_cert_handle(), &entry));

  ASSERT_EQ(ct::LogEntry::LOG_ENTRY_TYPE_X509, entry.type);
  // Should have empty tbs_certificate for this log entry type.
  ASSERT_TRUE(entry.tbs_certificate.empty());
  // Length of leaf_certificate should be 718, see the CT Serialization tests.
  ASSERT_EQ(718U, entry.leaf_certificate.size());
}

// Test that the embedded SCT verifies
TEST_F(CTObjectsExtractorTest, ExtractedSCTVerifies) {
  scoped_refptr<ct::SignedCertificateTimestamp> sct(
      new ct::SignedCertificateTimestamp());
  ExtractEmbeddedSCT(precert_chain_[0], &sct);

  LogEntry entry;
  ASSERT_TRUE(GetPrecertLogEntry(precert_chain_[0]->os_cert_handle(),
                                 precert_chain_[1]->os_cert_handle(),
                                 &entry));

  EXPECT_TRUE(log_->Verify(entry, *sct.get()));
}

// Test that an externally-provided SCT verifies over the LogEntry
// of a regular X.509 Certificate
TEST_F(CTObjectsExtractorTest, ComplementarySCTVerifies) {
  scoped_refptr<ct::SignedCertificateTimestamp> sct(
      new ct::SignedCertificateTimestamp());
  GetX509CertSCT(&sct);

  LogEntry entry;
  ASSERT_TRUE(GetX509LogEntry(test_cert_->os_cert_handle(), &entry));

  EXPECT_TRUE(log_->Verify(entry, *sct.get()));
}

// Test that the extractor can parse OCSP responses.
TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponse) {
  std::string der_subject_cert(ct::GetDerEncodedFakeOCSPResponseCert());
  scoped_refptr<X509Certificate> subject_cert =
      X509Certificate::CreateFromBytes(der_subject_cert.data(),
                                       der_subject_cert.length());
  std::string der_issuer_cert(ct::GetDerEncodedFakeOCSPResponseIssuerCert());
  scoped_refptr<X509Certificate> issuer_cert =
      X509Certificate::CreateFromBytes(der_issuer_cert.data(),
                                       der_issuer_cert.length());

  std::string fake_sct_list = ct::GetFakeOCSPExtensionValue();
  ASSERT_FALSE(fake_sct_list.empty());
  std::string ocsp_response = ct::GetDerEncodedFakeOCSPResponse();

  std::string extracted_sct_list;
  EXPECT_TRUE(ct::ExtractSCTListFromOCSPResponse(
      issuer_cert->os_cert_handle(), subject_cert->serial_number(),
      ocsp_response, &extracted_sct_list));
  EXPECT_EQ(extracted_sct_list, fake_sct_list);
}

// Test that the extractor honours serial number.
TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponseMatchesSerial) {
  std::string der_issuer_cert(ct::GetDerEncodedFakeOCSPResponseIssuerCert());
  scoped_refptr<X509Certificate> issuer_cert =
      X509Certificate::CreateFromBytes(der_issuer_cert.data(),
                                       der_issuer_cert.length());

  std::string ocsp_response = ct::GetDerEncodedFakeOCSPResponse();

  std::string extracted_sct_list;
  EXPECT_FALSE(ct::ExtractSCTListFromOCSPResponse(
      issuer_cert->os_cert_handle(), test_cert_->serial_number(),
      ocsp_response, &extracted_sct_list));
}

// Test that the extractor honours issuer ID.
TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponseMatchesIssuer) {
  std::string der_subject_cert(ct::GetDerEncodedFakeOCSPResponseCert());
  scoped_refptr<X509Certificate> subject_cert =
      X509Certificate::CreateFromBytes(der_subject_cert.data(),
                                       der_subject_cert.length());

  std::string ocsp_response = ct::GetDerEncodedFakeOCSPResponse();

  std::string extracted_sct_list;
  // Use test_cert_ for issuer - it is not the correct issuer of |subject_cert|.
  EXPECT_FALSE(ct::ExtractSCTListFromOCSPResponse(
      test_cert_->os_cert_handle(), subject_cert->serial_number(),
      ocsp_response, &extracted_sct_list));
}

}  // namespace ct

}  // namespace net
