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)); 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)); 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