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.
5 #include "net/cert/ct_objects_extractor.h"
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"
21 class CTObjectsExtractorTest
: public ::testing::Test
{
23 void SetUp() override
{
25 CreateCertificateListFromFile(GetTestCertsDirectory(),
26 "ct-test-embedded-cert.pem",
27 X509Certificate::FORMAT_AUTO
);
28 ASSERT_EQ(2u, precert_chain_
.size());
30 std::string
der_test_cert(ct::GetDerEncodedX509Cert());
31 test_cert_
= X509Certificate::CreateFromBytes(der_test_cert
.data(),
32 der_test_cert
.length());
34 log_
= CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog").Pass();
38 void ExtractEmbeddedSCT(scoped_refptr
<X509Certificate
> cert
,
39 scoped_refptr
<SignedCertificateTimestamp
>* sct
) {
41 EXPECT_TRUE(ExtractEmbeddedSCTList(cert
->os_cert_handle(), &sct_list
));
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
));
48 EXPECT_TRUE(DecodeSignedCertificateTimestamp(&parsed_scts
[0], sct
));
52 CertificateList precert_chain_
;
53 scoped_refptr
<X509Certificate
> test_cert_
;
54 scoped_ptr
<CTLogVerifier
> log_
;
57 // Test that an SCT can be extracted and the extracted SCT contains the
59 TEST_F(CTObjectsExtractorTest
, ExtractEmbeddedSCT
) {
60 scoped_refptr
<ct::SignedCertificateTimestamp
> sct(
61 new ct::SignedCertificateTimestamp());
62 ExtractEmbeddedSCT(precert_chain_
[0], &sct
);
64 EXPECT_EQ(sct
->version
, SignedCertificateTimestamp::SCT_VERSION_1
);
65 EXPECT_EQ(ct::GetTestPublicKeyId(), sct
->log_id
);
67 base::Time expected_timestamp
=
68 base::Time::UnixEpoch() +
69 base::TimeDelta::FromMilliseconds(1365181456275);
70 EXPECT_EQ(expected_timestamp
, sct
->timestamp
);
73 TEST_F(CTObjectsExtractorTest
, ExtractPrecert
) {
75 ASSERT_TRUE(GetPrecertLogEntry(precert_chain_
[0]->os_cert_handle(),
76 precert_chain_
[1]->os_cert_handle(),
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
));
88 TEST_F(CTObjectsExtractorTest
, ExtractOrdinaryX509Cert
) {
90 ASSERT_TRUE(GetX509LogEntry(test_cert_
->os_cert_handle(), &entry
));
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());
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
);
106 ASSERT_TRUE(GetPrecertLogEntry(precert_chain_
[0]->os_cert_handle(),
107 precert_chain_
[1]->os_cert_handle(),
110 EXPECT_TRUE(log_
->Verify(entry
, *sct
.get()));
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
);
121 ASSERT_TRUE(GetX509LogEntry(test_cert_
->os_cert_handle(), &entry
));
123 EXPECT_TRUE(log_
->Verify(entry
, *sct
.get()));
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());
137 std::string fake_sct_list
= ct::GetFakeOCSPExtensionValue();
138 ASSERT_FALSE(fake_sct_list
.empty());
139 std::string ocsp_response
= ct::GetDerEncodedFakeOCSPResponse();
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
);
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());
155 std::string ocsp_response
= ct::GetDerEncodedFakeOCSPResponse();
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
));
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());
170 std::string ocsp_response
= ct::GetDerEncodedFakeOCSPResponse();
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
));