Home | History | Annotate | Download | only in cert
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/cert/ct_objects_extractor.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "net/base/test_data_directory.h"
      9 #include "net/cert/ct_log_verifier.h"
     10 #include "net/cert/ct_serialization.h"
     11 #include "net/cert/signed_certificate_timestamp.h"
     12 #include "net/cert/x509_certificate.h"
     13 #include "net/test/cert_test_util.h"
     14 #include "net/test/ct_test_util.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace net {
     18 
     19 namespace ct {
     20 
     21 class CTObjectsExtractorTest : public ::testing::Test {
     22  public:
     23   virtual void SetUp() OVERRIDE {
     24     precert_chain_ =
     25         CreateCertificateListFromFile(GetTestCertsDirectory(),
     26                                       "ct-test-embedded-cert.pem",
     27                                       X509Certificate::FORMAT_AUTO);
     28     ASSERT_EQ(2u, precert_chain_.size());
     29 
     30     std::string der_test_cert(ct::GetDerEncodedX509Cert());
     31     test_cert_ = X509Certificate::CreateFromBytes(der_test_cert.data(),
     32                                                   der_test_cert.length());
     33 
     34     log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog").Pass();
     35     ASSERT_TRUE(log_);
     36   }
     37 
     38   void ExtractEmbeddedSCT(scoped_refptr<X509Certificate> cert,
     39                           scoped_refptr<SignedCertificateTimestamp>* sct) {
     40     std::string sct_list;
     41     EXPECT_TRUE(ExtractEmbeddedSCTList(cert->os_cert_handle(), &sct_list));
     42 
     43     std::vector<base::StringPiece> parsed_scts;
     44     base::StringPiece sct_list_sp(sct_list);
     45     // Make sure the SCT list can be decoded properly
     46     EXPECT_TRUE(DecodeSCTList(&sct_list_sp, &parsed_scts));
     47 
     48     EXPECT_TRUE(DecodeSignedCertificateTimestamp(&parsed_scts[0], sct));
     49   }
     50 
     51  protected:
     52   CertificateList precert_chain_;
     53   scoped_refptr<X509Certificate> test_cert_;
     54   scoped_ptr<CTLogVerifier> log_;
     55 };
     56 
     57 // Test that an SCT can be extracted and the extracted SCT contains the
     58 // expected data.
     59 TEST_F(CTObjectsExtractorTest, ExtractEmbeddedSCT) {
     60   scoped_refptr<ct::SignedCertificateTimestamp> sct(
     61       new ct::SignedCertificateTimestamp());
     62   ExtractEmbeddedSCT(precert_chain_[0], &sct);
     63 
     64   EXPECT_EQ(sct->version, SignedCertificateTimestamp::SCT_VERSION_1);
     65   EXPECT_EQ(ct::GetTestPublicKeyId(), sct->log_id);
     66 
     67   base::Time expected_timestamp =
     68       base::Time::UnixEpoch() +
     69       base::TimeDelta::FromMilliseconds(1365181456275);
     70   EXPECT_EQ(expected_timestamp, sct->timestamp);
     71 }
     72 
     73 TEST_F(CTObjectsExtractorTest, ExtractPrecert) {
     74   LogEntry entry;
     75   ASSERT_TRUE(GetPrecertLogEntry(precert_chain_[0]->os_cert_handle(),
     76                                  precert_chain_[1]->os_cert_handle(),
     77                                  &entry));
     78 
     79   ASSERT_EQ(ct::LogEntry::LOG_ENTRY_TYPE_PRECERT, entry.type);
     80   // Should have empty leaf cert for this log entry type.
     81   ASSERT_TRUE(entry.leaf_certificate.empty());
     82   // Compare hash values of issuer spki.
     83   SHA256HashValue expected_issuer_key_hash;
     84   memcpy(expected_issuer_key_hash.data, GetDefaultIssuerKeyHash().data(), 32);
     85   ASSERT_TRUE(expected_issuer_key_hash.Equals(entry.issuer_key_hash));
     86 }
     87 
     88 TEST_F(CTObjectsExtractorTest, ExtractOrdinaryX509Cert) {
     89   LogEntry entry;
     90   ASSERT_TRUE(GetX509LogEntry(test_cert_->os_cert_handle(), &entry));
     91 
     92   ASSERT_EQ(ct::LogEntry::LOG_ENTRY_TYPE_X509, entry.type);
     93   // Should have empty tbs_certificate for this log entry type.
     94   ASSERT_TRUE(entry.tbs_certificate.empty());
     95   // Length of leaf_certificate should be 718, see the CT Serialization tests.
     96   ASSERT_EQ(718U, entry.leaf_certificate.size());
     97 }
     98 
     99 // Test that the embedded SCT verifies
    100 TEST_F(CTObjectsExtractorTest, ExtractedSCTVerifies) {
    101   scoped_refptr<ct::SignedCertificateTimestamp> sct(
    102       new ct::SignedCertificateTimestamp());
    103   ExtractEmbeddedSCT(precert_chain_[0], &sct);
    104 
    105   LogEntry entry;
    106   ASSERT_TRUE(GetPrecertLogEntry(precert_chain_[0]->os_cert_handle(),
    107                                  precert_chain_[1]->os_cert_handle(),
    108                                  &entry));
    109 
    110   EXPECT_TRUE(log_->Verify(entry, *sct.get()));
    111 }
    112 
    113 // Test that an externally-provided SCT verifies over the LogEntry
    114 // of a regular X.509 Certificate
    115 TEST_F(CTObjectsExtractorTest, ComplementarySCTVerifies) {
    116   scoped_refptr<ct::SignedCertificateTimestamp> sct(
    117       new ct::SignedCertificateTimestamp());
    118   GetX509CertSCT(&sct);
    119 
    120   LogEntry entry;
    121   ASSERT_TRUE(GetX509LogEntry(test_cert_->os_cert_handle(), &entry));
    122 
    123   EXPECT_TRUE(log_->Verify(entry, *sct.get()));
    124 }
    125 
    126 // Test that the extractor can parse OCSP responses.
    127 TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponse) {
    128   std::string der_subject_cert(ct::GetDerEncodedFakeOCSPResponseCert());
    129   scoped_refptr<X509Certificate> subject_cert =
    130       X509Certificate::CreateFromBytes(der_subject_cert.data(),
    131                                        der_subject_cert.length());
    132   std::string der_issuer_cert(ct::GetDerEncodedFakeOCSPResponseIssuerCert());
    133   scoped_refptr<X509Certificate> issuer_cert =
    134       X509Certificate::CreateFromBytes(der_issuer_cert.data(),
    135                                        der_issuer_cert.length());
    136 
    137   std::string fake_sct_list = ct::GetFakeOCSPExtensionValue();
    138   ASSERT_FALSE(fake_sct_list.empty());
    139   std::string ocsp_response = ct::GetDerEncodedFakeOCSPResponse();
    140 
    141   std::string extracted_sct_list;
    142   EXPECT_TRUE(ct::ExtractSCTListFromOCSPResponse(
    143       issuer_cert->os_cert_handle(), subject_cert->serial_number(),
    144       ocsp_response, &extracted_sct_list));
    145   EXPECT_EQ(extracted_sct_list, fake_sct_list);
    146 }
    147 
    148 // Test that the extractor honours serial number.
    149 TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponseMatchesSerial) {
    150   std::string der_issuer_cert(ct::GetDerEncodedFakeOCSPResponseIssuerCert());
    151   scoped_refptr<X509Certificate> issuer_cert =
    152       X509Certificate::CreateFromBytes(der_issuer_cert.data(),
    153                                        der_issuer_cert.length());
    154 
    155   std::string ocsp_response = ct::GetDerEncodedFakeOCSPResponse();
    156 
    157   std::string extracted_sct_list;
    158   EXPECT_FALSE(ct::ExtractSCTListFromOCSPResponse(
    159       issuer_cert->os_cert_handle(), test_cert_->serial_number(),
    160       ocsp_response, &extracted_sct_list));
    161 }
    162 
    163 // Test that the extractor honours issuer ID.
    164 TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponseMatchesIssuer) {
    165   std::string der_subject_cert(ct::GetDerEncodedFakeOCSPResponseCert());
    166   scoped_refptr<X509Certificate> subject_cert =
    167       X509Certificate::CreateFromBytes(der_subject_cert.data(),
    168                                        der_subject_cert.length());
    169 
    170   std::string ocsp_response = ct::GetDerEncodedFakeOCSPResponse();
    171 
    172   std::string extracted_sct_list;
    173   // Use test_cert_ for issuer - it is not the correct issuer of |subject_cert|.
    174   EXPECT_FALSE(ct::ExtractSCTListFromOCSPResponse(
    175       test_cert_->os_cert_handle(), subject_cert->serial_number(),
    176       ocsp_response, &extracted_sct_list));
    177 }
    178 
    179 }  // namespace ct
    180 
    181 }  // namespace net
    182