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