1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/cert/ct_objects_extractor.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/files/file_path.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/base/test_data_directory.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/cert/ct_log_verifier.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/cert/ct_serialization.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/cert/signed_certificate_timestamp.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/cert/x509_certificate.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/test/cert_test_util.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/test/ct_test_util.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace net {
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace ct {
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class CTObjectsExtractorTest : public ::testing::Test {
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    precert_chain_ =
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        CreateCertificateListFromFile(GetTestCertsDirectory(),
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      "ct-test-embedded-cert.pem",
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      X509Certificate::FORMAT_AUTO);
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_EQ(2u, precert_chain_.size());
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string der_test_cert(ct::GetDerEncodedX509Cert());
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    test_cert_ = X509Certificate::CreateFromBytes(der_test_cert.data(),
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                  der_test_cert.length());
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog").Pass();
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(log_);
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void ExtractEmbeddedSCT(scoped_refptr<X509Certificate> cert,
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          scoped_refptr<SignedCertificateTimestamp>* sct) {
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string sct_list;
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(ExtractEmbeddedSCTList(cert->os_cert_handle(), &sct_list));
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::vector<base::StringPiece> parsed_scts;
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::StringPiece sct_list_sp(sct_list);
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Make sure the SCT list can be decoded properly
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(DecodeSCTList(&sct_list_sp, &parsed_scts));
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(DecodeSignedCertificateTimestamp(&parsed_scts[0], sct));
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CertificateList precert_chain_;
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<X509Certificate> test_cert_;
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<CTLogVerifier> log_;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test that an SCT can be extracted and the extracted SCT contains the
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// expected data.
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(CTObjectsExtractorTest, ExtractEmbeddedSCT) {
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<ct::SignedCertificateTimestamp> sct(
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new ct::SignedCertificateTimestamp());
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ExtractEmbeddedSCT(precert_chain_[0], &sct);
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(sct->version, SignedCertificateTimestamp::SCT_VERSION_1);
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(ct::GetTestPublicKeyId(), sct->log_id);
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::Time expected_timestamp =
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Time::UnixEpoch() +
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(1365181456275);
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(expected_timestamp, sct->timestamp);
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(CTObjectsExtractorTest, ExtractPrecert) {
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LogEntry entry;
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(GetPrecertLogEntry(precert_chain_[0]->os_cert_handle(),
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 precert_chain_[1]->os_cert_handle(),
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 &entry));
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(ct::LogEntry::LOG_ENTRY_TYPE_PRECERT, entry.type);
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Should have empty leaf cert for this log entry type.
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(entry.leaf_certificate.empty());
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Compare hash values of issuer spki.
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SHA256HashValue expected_issuer_key_hash;
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  memcpy(expected_issuer_key_hash.data, GetDefaultIssuerKeyHash().data(), 32);
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(expected_issuer_key_hash.Equals(entry.issuer_key_hash));
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(CTObjectsExtractorTest, ExtractOrdinaryX509Cert) {
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LogEntry entry;
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(GetX509LogEntry(test_cert_->os_cert_handle(), &entry));
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(ct::LogEntry::LOG_ENTRY_TYPE_X509, entry.type);
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Should have empty tbs_certificate for this log entry type.
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(entry.tbs_certificate.empty());
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Length of leaf_certificate should be 718, see the CT Serialization tests.
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(718U, entry.leaf_certificate.size());
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test that the embedded SCT verifies
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(CTObjectsExtractorTest, ExtractedSCTVerifies) {
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<ct::SignedCertificateTimestamp> sct(
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new ct::SignedCertificateTimestamp());
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ExtractEmbeddedSCT(precert_chain_[0], &sct);
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LogEntry entry;
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(GetPrecertLogEntry(precert_chain_[0]->os_cert_handle(),
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 precert_chain_[1]->os_cert_handle(),
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 &entry));
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(log_->Verify(entry, *sct.get()));
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test that an externally-provided SCT verifies over the LogEntry
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// of a regular X.509 Certificate
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(CTObjectsExtractorTest, ComplementarySCTVerifies) {
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<ct::SignedCertificateTimestamp> sct(
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new ct::SignedCertificateTimestamp());
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GetX509CertSCT(&sct);
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LogEntry entry;
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(GetX509LogEntry(test_cert_->os_cert_handle(), &entry));
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(log_->Verify(entry, *sct.get()));
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that the extractor can parse OCSP responses.
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponse) {
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string der_subject_cert(ct::GetDerEncodedFakeOCSPResponseCert());
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<X509Certificate> subject_cert =
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      X509Certificate::CreateFromBytes(der_subject_cert.data(),
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       der_subject_cert.length());
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string der_issuer_cert(ct::GetDerEncodedFakeOCSPResponseIssuerCert());
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<X509Certificate> issuer_cert =
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      X509Certificate::CreateFromBytes(der_issuer_cert.data(),
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       der_issuer_cert.length());
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string fake_sct_list = ct::GetFakeOCSPExtensionValue();
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(fake_sct_list.empty());
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string ocsp_response = ct::GetDerEncodedFakeOCSPResponse();
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string extracted_sct_list;
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(ct::ExtractSCTListFromOCSPResponse(
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      issuer_cert->os_cert_handle(), subject_cert->serial_number(),
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ocsp_response, &extracted_sct_list));
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(extracted_sct_list, fake_sct_list);
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that the extractor honours serial number.
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponseMatchesSerial) {
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string der_issuer_cert(ct::GetDerEncodedFakeOCSPResponseIssuerCert());
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<X509Certificate> issuer_cert =
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      X509Certificate::CreateFromBytes(der_issuer_cert.data(),
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       der_issuer_cert.length());
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string ocsp_response = ct::GetDerEncodedFakeOCSPResponse();
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string extracted_sct_list;
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(ct::ExtractSCTListFromOCSPResponse(
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      issuer_cert->os_cert_handle(), test_cert_->serial_number(),
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ocsp_response, &extracted_sct_list));
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that the extractor honours issuer ID.
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponseMatchesIssuer) {
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string der_subject_cert(ct::GetDerEncodedFakeOCSPResponseCert());
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<X509Certificate> subject_cert =
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      X509Certificate::CreateFromBytes(der_subject_cert.data(),
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       der_subject_cert.length());
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string ocsp_response = ct::GetDerEncodedFakeOCSPResponse();
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string extracted_sct_list;
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Use test_cert_ for issuer - it is not the correct issuer of |subject_cert|.
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(ct::ExtractSCTListFromOCSPResponse(
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      test_cert_->os_cert_handle(), subject_cert->serial_number(),
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ocsp_response, &extracted_sct_list));
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace ct
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace net
182