1 // Copyright 2016 The Chromium Authors
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/merkle_tree_leaf.h"
6
7 #include <string.h>
8
9 #include <string>
10
11 #include "base/strings/string_number_conversions.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 "net/test/test_data_directory.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace net::ct {
20
21 namespace {
22
23 MATCHER_P(HexEq, hexStr, "") {
24 std::vector<uint8_t> bytes;
25
26 if (!base::HexStringToBytes(hexStr, &bytes)) {
27 *result_listener << "expected value was not a valid hex string";
28 return false;
29 }
30
31 if (bytes.size() != arg.size()) {
32 *result_listener << "expected and actual are different lengths";
33 return false;
34 }
35
36 // Make sure we don't pass nullptrs to memcmp
37 if (arg.empty())
38 return true;
39
40 // Print hex string (easier to read than default GTest representation)
41 *result_listener << "a.k.a. 0x" << base::HexEncode(arg.data(), arg.size());
42 return memcmp(arg.data(), bytes.data(), bytes.size()) == 0;
43 }
44
45 class MerkleTreeLeafTest : public ::testing::Test {
46 public:
SetUp()47 void SetUp() override {
48 std::string der_test_cert(ct::GetDerEncodedX509Cert());
49 test_cert_ =
50 X509Certificate::CreateFromBytes(base::as_byte_span(der_test_cert));
51 ASSERT_TRUE(test_cert_);
52
53 GetX509CertSCT(&x509_sct_);
54 x509_sct_->origin = SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE;
55
56 test_precert_ = CreateCertificateChainFromFile(
57 GetTestCertsDirectory(), "ct-test-embedded-cert.pem",
58 X509Certificate::FORMAT_AUTO);
59 ASSERT_TRUE(test_precert_);
60 ASSERT_EQ(1u, test_precert_->intermediate_buffers().size());
61 GetPrecertSCT(&precert_sct_);
62 precert_sct_->origin = SignedCertificateTimestamp::SCT_EMBEDDED;
63 }
64
65 protected:
66 scoped_refptr<SignedCertificateTimestamp> x509_sct_;
67 scoped_refptr<SignedCertificateTimestamp> precert_sct_;
68 scoped_refptr<X509Certificate> test_cert_;
69 scoped_refptr<X509Certificate> test_precert_;
70 };
71
TEST_F(MerkleTreeLeafTest,CreatesForX509Cert)72 TEST_F(MerkleTreeLeafTest, CreatesForX509Cert) {
73 MerkleTreeLeaf leaf;
74 ASSERT_TRUE(GetMerkleTreeLeaf(test_cert_.get(), x509_sct_.get(), &leaf));
75
76 EXPECT_EQ(SignedEntryData::LOG_ENTRY_TYPE_X509, leaf.signed_entry.type);
77 EXPECT_FALSE(leaf.signed_entry.leaf_certificate.empty());
78 EXPECT_TRUE(leaf.signed_entry.tbs_certificate.empty());
79
80 EXPECT_EQ(x509_sct_->timestamp, leaf.timestamp);
81 EXPECT_EQ(x509_sct_->extensions, leaf.extensions);
82 }
83
TEST_F(MerkleTreeLeafTest,CreatesForPrecert)84 TEST_F(MerkleTreeLeafTest, CreatesForPrecert) {
85 MerkleTreeLeaf leaf;
86 ASSERT_TRUE(
87 GetMerkleTreeLeaf(test_precert_.get(), precert_sct_.get(), &leaf));
88
89 EXPECT_EQ(SignedEntryData::LOG_ENTRY_TYPE_PRECERT, leaf.signed_entry.type);
90 EXPECT_FALSE(leaf.signed_entry.tbs_certificate.empty());
91 EXPECT_TRUE(leaf.signed_entry.leaf_certificate.empty());
92
93 EXPECT_EQ(precert_sct_->timestamp, leaf.timestamp);
94 EXPECT_EQ(precert_sct_->extensions, leaf.extensions);
95 }
96
TEST_F(MerkleTreeLeafTest,DoesNotCreateForEmbeddedSCTButNotPrecert)97 TEST_F(MerkleTreeLeafTest, DoesNotCreateForEmbeddedSCTButNotPrecert) {
98 MerkleTreeLeaf leaf;
99 ASSERT_FALSE(GetMerkleTreeLeaf(test_cert_.get(), precert_sct_.get(), &leaf));
100 }
101
102 // Expected hashes calculated by:
103 // 1. Writing the serialized tree leaves from
104 // CtSerialization::EncodesLogEntryFor{X509Cert,Precert} to files.
105 // 2. Prepending a zero byte to both files.
106 // 3. Passing each file through the sha256sum tool.
107
TEST_F(MerkleTreeLeafTest,HashForX509Cert)108 TEST_F(MerkleTreeLeafTest, HashForX509Cert) {
109 MerkleTreeLeaf leaf;
110 ct::GetX509CertTreeLeaf(&leaf);
111
112 std::string hash;
113 ASSERT_TRUE(HashMerkleTreeLeaf(leaf, &hash));
114 EXPECT_THAT(hash, HexEq("452da788b3b8d15872ff0bb0777354b2a7f1c1887b5633201e76"
115 "2ba5a4b143fc"));
116 }
117
TEST_F(MerkleTreeLeafTest,HashForPrecert)118 TEST_F(MerkleTreeLeafTest, HashForPrecert) {
119 MerkleTreeLeaf leaf;
120 ct::GetPrecertTreeLeaf(&leaf);
121
122 std::string hash;
123 ASSERT_TRUE(HashMerkleTreeLeaf(leaf, &hash));
124 EXPECT_THAT(hash, HexEq("257ae85f08810445511e35e33f7aee99ee19407971e35e95822b"
125 "bf42a74be223"));
126 }
127
128 } // namespace
129
130 } // namespace net::ct
131