OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/ct_log_verifier.h" | 5 #include "net/cert/ct_log_verifier.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
(...skipping 19 matching lines...) Expand all Loading... |
30 uint64_t CalculateNearestPowerOfTwo(uint64_t n) { | 30 uint64_t CalculateNearestPowerOfTwo(uint64_t n) { |
31 DCHECK_GT(n, 1u); | 31 DCHECK_GT(n, 1u); |
32 | 32 |
33 uint64_t ret = UINT64_C(1) << 63; | 33 uint64_t ret = UINT64_C(1) << 63; |
34 while (ret >= n) | 34 while (ret >= n) |
35 ret >>= 1; | 35 ret >>= 1; |
36 | 36 |
37 return ret; | 37 return ret; |
38 } | 38 } |
39 | 39 |
| 40 // Copies a raw SHA-256 hash (32 bytes) into a std::string. |
| 41 std::string HashAsStr(const uint8_t (&hash)[32]) { |
| 42 return std::string(std::begin(hash), std::end(hash)); |
| 43 } |
| 44 |
40 // A single consistency proof. Contains the old and new tree sizes | 45 // A single consistency proof. Contains the old and new tree sizes |
41 // (snapshot1 and snapshot2), the length of the proof (proof_length) and | 46 // (snapshot1 and snapshot2), the length of the proof (proof_length) and |
42 // at most 3 proof nodes (all test proofs will be for a tree of size 8). | 47 // at most 3 proof nodes (all test proofs will be for a tree of size 8). |
43 struct ProofTestVector { | 48 struct ProofTestVector { |
44 uint64_t snapshot1; | 49 uint64_t snapshot1; |
45 uint64_t snapshot2; | 50 uint64_t snapshot2; |
46 size_t proof_length; | 51 size_t proof_length; |
47 const char* const proof[3]; | 52 const uint8_t proof[3][32]; |
48 }; | 53 }; |
49 | 54 |
50 // All test data replicated from | 55 // All test data replicated from |
51 // https://github.com/google/certificate-transparency/blob/c41b090ecc14ddd6b3531
dc7e5ce36b21e253fdd/cpp/merkletree/merkle_tree_test.cc | 56 // https://github.com/google/certificate-transparency/blob/c41b090ecc14ddd6b3531
dc7e5ce36b21e253fdd/cpp/merkletree/merkle_tree_test.cc |
52 // A hash of the empty string. | 57 // A hash of the empty string. |
53 const uint8_t kSHA256EmptyTreeHash[32] = { | 58 const uint8_t kSHA256EmptyTreeHash[32] = { |
54 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, | 59 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, |
55 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, | 60 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, |
56 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; | 61 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; |
57 | 62 |
58 // Node hashes for a sample tree of size 8 (each element in this array is | 63 // Node hashes for a sample tree of size 8 (each element in this array is |
59 // a node hash, not leaf data; order represents order of the nodes in the tree). | 64 // a node hash, not leaf data; order represents order of the nodes in the tree). |
60 const char* const kSHA256Roots[8] = { | 65 const uint8_t kSHA256Roots[8][32] = { |
61 "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", | 66 {0x6e, 0x34, 0x0b, 0x9c, 0xff, 0xb3, 0x7a, 0x98, 0x9c, 0xa5, 0x44, |
62 "fac54203e7cc696cf0dfcb42c92a1d9dbaf70ad9e621f4bd8d98662f00e3c125", | 67 0xe6, 0xbb, 0x78, 0x0a, 0x2c, 0x78, 0x90, 0x1d, 0x3f, 0xb3, 0x37, |
63 "aeb6bcfe274b70a14fb067a5e5578264db0fa9b51af5e0ba159158f329e06e77", | 68 0x38, 0x76, 0x85, 0x11, 0xa3, 0x06, 0x17, 0xaf, 0xa0, 0x1d}, |
64 "d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7", | 69 {0xfa, 0xc5, 0x42, 0x03, 0xe7, 0xcc, 0x69, 0x6c, 0xf0, 0xdf, 0xcb, |
65 "4e3bbb1f7b478dcfe71fb631631519a3bca12c9aefca1612bfce4c13a86264d4", | 70 0x42, 0xc9, 0x2a, 0x1d, 0x9d, 0xba, 0xf7, 0x0a, 0xd9, 0xe6, 0x21, |
66 "76e67dadbcdf1e10e1b74ddc608abd2f98dfb16fbce75277b5232a127f2087ef", | 71 0xf4, 0xbd, 0x8d, 0x98, 0x66, 0x2f, 0x00, 0xe3, 0xc1, 0x25}, |
67 "ddb89be403809e325750d3d263cd78929c2942b7942a34b77e122c9594a74c8c", | 72 {0xae, 0xb6, 0xbc, 0xfe, 0x27, 0x4b, 0x70, 0xa1, 0x4f, 0xb0, 0x67, |
68 "5dc9da79a70659a9ad559cb701ded9a2ab9d823aad2f4960cfe370eff4604328"}; | 73 0xa5, 0xe5, 0x57, 0x82, 0x64, 0xdb, 0x0f, 0xa9, 0xb5, 0x1a, 0xf5, |
| 74 0xe0, 0xba, 0x15, 0x91, 0x58, 0xf3, 0x29, 0xe0, 0x6e, 0x77}, |
| 75 {0xd3, 0x7e, 0xe4, 0x18, 0x97, 0x6d, 0xd9, 0x57, 0x53, 0xc1, 0xc7, |
| 76 0x38, 0x62, 0xb9, 0x39, 0x8f, 0xa2, 0xa2, 0xcf, 0x9b, 0x4f, 0xf0, |
| 77 0xfd, 0xfe, 0x8b, 0x30, 0xcd, 0x95, 0x20, 0x96, 0x14, 0xb7}, |
| 78 {0x4e, 0x3b, 0xbb, 0x1f, 0x7b, 0x47, 0x8d, 0xcf, 0xe7, 0x1f, 0xb6, |
| 79 0x31, 0x63, 0x15, 0x19, 0xa3, 0xbc, 0xa1, 0x2c, 0x9a, 0xef, 0xca, |
| 80 0x16, 0x12, 0xbf, 0xce, 0x4c, 0x13, 0xa8, 0x62, 0x64, 0xd4}, |
| 81 {0x76, 0xe6, 0x7d, 0xad, 0xbc, 0xdf, 0x1e, 0x10, 0xe1, 0xb7, 0x4d, |
| 82 0xdc, 0x60, 0x8a, 0xbd, 0x2f, 0x98, 0xdf, 0xb1, 0x6f, 0xbc, 0xe7, |
| 83 0x52, 0x77, 0xb5, 0x23, 0x2a, 0x12, 0x7f, 0x20, 0x87, 0xef}, |
| 84 {0xdd, 0xb8, 0x9b, 0xe4, 0x03, 0x80, 0x9e, 0x32, 0x57, 0x50, 0xd3, |
| 85 0xd2, 0x63, 0xcd, 0x78, 0x92, 0x9c, 0x29, 0x42, 0xb7, 0x94, 0x2a, |
| 86 0x34, 0xb7, 0x7e, 0x12, 0x2c, 0x95, 0x94, 0xa7, 0x4c, 0x8c}, |
| 87 {0x5d, 0xc9, 0xda, 0x79, 0xa7, 0x06, 0x59, 0xa9, 0xad, 0x55, 0x9c, |
| 88 0xb7, 0x01, 0xde, 0xd9, 0xa2, 0xab, 0x9d, 0x82, 0x3a, 0xad, 0x2f, |
| 89 0x49, 0x60, 0xcf, 0xe3, 0x70, 0xef, 0xf4, 0x60, 0x43, 0x28}}; |
69 | 90 |
70 // A collection of consistency proofs between various sub-trees of the tree | 91 // A collection of consistency proofs between various sub-trees of the tree |
71 // defined by |kSHA256Roots|. | 92 // defined by |kSHA256Roots|. |
72 const ProofTestVector kSHA256Proofs[4] = { | 93 const ProofTestVector kSHA256Proofs[4] = { |
73 // Empty consistency proof between trees of the same size (1). | 94 // Empty consistency proof between trees of the same size (1). |
74 {1, 1, 0, {"", "", ""}}, | 95 {1, 1, 0, {"", "", ""}}, |
75 // Consistency proof between tree of size 1 and tree of size 8, with 3 | 96 // Consistency proof between tree of size 1 and tree of size 8, with 3 |
76 // nodes in the proof. | 97 // nodes in the proof. |
77 {1, | 98 {1, |
78 8, | 99 8, |
79 3, | 100 3, |
80 {"96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7", | 101 {{0x96, 0xa2, 0x96, 0xd2, 0x24, 0xf2, 0x85, 0xc6, 0x7b, 0xee, 0x93, |
81 "5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e", | 102 0xc3, 0x0f, 0x8a, 0x30, 0x91, 0x57, 0xf0, 0xda, 0xa3, 0x5d, 0xc5, |
82 "6b47aaf29ee3c2af9af889bc1fb9254dabd31177f16232dd6aab035ca39bf6e4"}}, | 103 0xb8, 0x7e, 0x41, 0x0b, 0x78, 0x63, 0x0a, 0x09, 0xcf, 0xc7}, |
| 104 {0x5f, 0x08, 0x3f, 0x0a, 0x1a, 0x33, 0xca, 0x07, 0x6a, 0x95, 0x27, |
| 105 0x98, 0x32, 0x58, 0x0d, 0xb3, 0xe0, 0xef, 0x45, 0x84, 0xbd, 0xff, |
| 106 0x1f, 0x54, 0xc8, 0xa3, 0x60, 0xf5, 0x0d, 0xe3, 0x03, 0x1e}, |
| 107 {0x6b, 0x47, 0xaa, 0xf2, 0x9e, 0xe3, 0xc2, 0xaf, 0x9a, 0xf8, 0x89, |
| 108 0xbc, 0x1f, 0xb9, 0x25, 0x4d, 0xab, 0xd3, 0x11, 0x77, 0xf1, 0x62, |
| 109 0x32, 0xdd, 0x6a, 0xab, 0x03, 0x5c, 0xa3, 0x9b, 0xf6, 0xe4}}}, |
83 // Consistency proof between tree of size 6 and tree of size 8, with 3 | 110 // Consistency proof between tree of size 6 and tree of size 8, with 3 |
84 // nodes in the proof. | 111 // nodes in the proof. |
85 {6, | 112 {6, |
86 8, | 113 8, |
87 3, | 114 3, |
88 {"0ebc5d3437fbe2db158b9f126a1d118e308181031d0a949f8dededebc558ef6a", | 115 {{0x0e, 0xbc, 0x5d, 0x34, 0x37, 0xfb, 0xe2, 0xdb, 0x15, 0x8b, 0x9f, |
89 "ca854ea128ed050b41b35ffc1b87b8eb2bde461e9e3b5596ece6b9d5975a0ae0", | 116 0x12, 0x6a, 0x1d, 0x11, 0x8e, 0x30, 0x81, 0x81, 0x03, 0x1d, 0x0a, |
90 "d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7"}}, | 117 0x94, 0x9f, 0x8d, 0xed, 0xed, 0xeb, 0xc5, 0x58, 0xef, 0x6a}, |
| 118 {0xca, 0x85, 0x4e, 0xa1, 0x28, 0xed, 0x05, 0x0b, 0x41, 0xb3, 0x5f, |
| 119 0xfc, 0x1b, 0x87, 0xb8, 0xeb, 0x2b, 0xde, 0x46, 0x1e, 0x9e, 0x3b, |
| 120 0x55, 0x96, 0xec, 0xe6, 0xb9, 0xd5, 0x97, 0x5a, 0x0a, 0xe0}, |
| 121 {0xd3, 0x7e, 0xe4, 0x18, 0x97, 0x6d, 0xd9, 0x57, 0x53, 0xc1, 0xc7, |
| 122 0x38, 0x62, 0xb9, 0x39, 0x8f, 0xa2, 0xa2, 0xcf, 0x9b, 0x4f, 0xf0, |
| 123 0xfd, 0xfe, 0x8b, 0x30, 0xcd, 0x95, 0x20, 0x96, 0x14, 0xb7}}}, |
91 // Consistency proof between tree of size 2 and tree of size 5, with 2 | 124 // Consistency proof between tree of size 2 and tree of size 5, with 2 |
92 // nodes in the proof. | 125 // nodes in the proof. |
93 {2, | 126 {2, |
94 5, | 127 5, |
95 2, | 128 2, |
96 {"5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e", | 129 {{0x5f, 0x08, 0x3f, 0x0a, 0x1a, 0x33, 0xca, 0x07, 0x6a, 0x95, 0x27, |
97 "bc1a0643b12e4d2d7c77918f44e0f4f79a838b6cf9ec5b5c283e1f4d88599e6b", ""}}}; | 130 0x98, 0x32, 0x58, 0x0d, 0xb3, 0xe0, 0xef, 0x45, 0x84, 0xbd, 0xff, |
98 | 131 0x1f, 0x54, 0xc8, 0xa3, 0x60, 0xf5, 0x0d, 0xe3, 0x03, 0x1e}, |
99 // Decodes a hexadecimal string into the binary data it represents. | 132 {0xbc, 0x1a, 0x06, 0x43, 0xb1, 0x2e, 0x4d, 0x2d, 0x7c, 0x77, 0x91, |
100 std::string HexToBytes(const std::string& hex_data) { | 133 0x8f, 0x44, 0xe0, 0xf4, 0xf7, 0x9a, 0x83, 0x8b, 0x6c, 0xf9, 0xec, |
101 std::vector<uint8_t> output; | 134 0x5b, 0x5c, 0x28, 0x3e, 0x1f, 0x4d, 0x88, 0x59, 0x9e, 0x6b}}}}; |
102 std::string result; | |
103 if (base::HexStringToBytes(hex_data, &output)) | |
104 result.assign(output.begin(), output.end()); | |
105 return result; | |
106 } | |
107 | |
108 std::string GetEmptyTreeHash() { | |
109 return std::string(std::begin(kSHA256EmptyTreeHash), | |
110 std::end(kSHA256EmptyTreeHash)); | |
111 } | |
112 | 135 |
113 // Creates a ct::MerkleConsistencyProof and returns the result of | 136 // Creates a ct::MerkleConsistencyProof and returns the result of |
114 // calling log->VerifyConsistencyProof with that proof and snapshots. | 137 // calling log->VerifyConsistencyProof with that proof and snapshots. |
115 bool VerifyConsistencyProof(scoped_refptr<const CTLogVerifier> log, | 138 bool VerifyConsistencyProof(scoped_refptr<const CTLogVerifier> log, |
116 uint64_t old_tree_size, | 139 uint64_t old_tree_size, |
117 const std::string& old_tree_root, | 140 const std::string& old_tree_root, |
118 uint64_t new_tree_size, | 141 uint64_t new_tree_size, |
119 const std::string& new_tree_root, | 142 const std::string& new_tree_root, |
120 const std::vector<std::string>& proof) { | 143 const std::vector<std::string>& proof) { |
121 return log->VerifyConsistencyProof( | 144 return log->VerifyConsistencyProof( |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 | 209 |
187 // Variations of wrong proofs, all of which should be rejected. | 210 // Variations of wrong proofs, all of which should be rejected. |
188 std::vector<std::string> wrong_proof; | 211 std::vector<std::string> wrong_proof; |
189 // Empty proof. | 212 // Empty proof. |
190 EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2, | 213 EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2, |
191 root2, wrong_proof)); | 214 root2, wrong_proof)); |
192 | 215 |
193 // Modify a single element in the proof. | 216 // Modify a single element in the proof. |
194 for (size_t j = 0; j < proof.size(); ++j) { | 217 for (size_t j = 0; j < proof.size(); ++j) { |
195 wrong_proof = proof; | 218 wrong_proof = proof; |
196 wrong_proof[j] = GetEmptyTreeHash(); | 219 wrong_proof[j] = HashAsStr(kSHA256EmptyTreeHash); |
197 EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2, | 220 EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2, |
198 root2, wrong_proof)); | 221 root2, wrong_proof)); |
199 } | 222 } |
200 | 223 |
201 // Add garbage at the end of the proof. | 224 // Add garbage at the end of the proof. |
202 wrong_proof = proof; | 225 wrong_proof = proof; |
203 wrong_proof.push_back(std::string()); | 226 wrong_proof.push_back(std::string()); |
204 EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2, | 227 EXPECT_FALSE(VerifyConsistencyProof(log_, snapshot1, root1, snapshot2, |
205 root2, wrong_proof)); | 228 root2, wrong_proof)); |
206 wrong_proof.pop_back(); | 229 wrong_proof.pop_back(); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 std::string key = ct::GetTestPublicKey(); | 331 std::string key = ct::GetTestPublicKey(); |
309 key += "extra"; | 332 key += "extra"; |
310 | 333 |
311 scoped_refptr<const CTLogVerifier> log = CTLogVerifier::Create( | 334 scoped_refptr<const CTLogVerifier> log = CTLogVerifier::Create( |
312 key, "testlog", "https://ct.example.com", "ct.example.com"); | 335 key, "testlog", "https://ct.example.com", "ct.example.com"); |
313 EXPECT_FALSE(log); | 336 EXPECT_FALSE(log); |
314 } | 337 } |
315 | 338 |
316 TEST_F(CTLogVerifierTest, VerifiesConsistencyProofEdgeCases_EmptyProof) { | 339 TEST_F(CTLogVerifierTest, VerifiesConsistencyProofEdgeCases_EmptyProof) { |
317 std::vector<std::string> empty_proof; | 340 std::vector<std::string> empty_proof; |
318 std::string root1(GetEmptyTreeHash()), root2(GetEmptyTreeHash()); | 341 std::string root1(HashAsStr(kSHA256EmptyTreeHash)), |
| 342 root2(HashAsStr(kSHA256EmptyTreeHash)); |
319 | 343 |
320 // Snapshots that are always consistent, because they are either | 344 // Snapshots that are always consistent, because they are either |
321 // from an empty tree to a non-empty one or for trees of the same | 345 // from an empty tree to a non-empty one or for trees of the same |
322 // size. | 346 // size. |
323 EXPECT_TRUE(VerifyConsistencyProof(log_, 0, root1, 0, root2, empty_proof)); | 347 EXPECT_TRUE(VerifyConsistencyProof(log_, 0, root1, 0, root2, empty_proof)); |
324 EXPECT_TRUE(VerifyConsistencyProof(log_, 0, root1, 1, root2, empty_proof)); | 348 EXPECT_TRUE(VerifyConsistencyProof(log_, 0, root1, 1, root2, empty_proof)); |
325 EXPECT_TRUE(VerifyConsistencyProof(log_, 1, root1, 1, root2, empty_proof)); | 349 EXPECT_TRUE(VerifyConsistencyProof(log_, 1, root1, 1, root2, empty_proof)); |
326 | 350 |
327 // Invalid consistency proofs. | 351 // Invalid consistency proofs. |
328 // Time travel to the past. | 352 // Time travel to the past. |
329 EXPECT_FALSE(VerifyConsistencyProof(log_, 1, root1, 0, root2, empty_proof)); | 353 EXPECT_FALSE(VerifyConsistencyProof(log_, 1, root1, 0, root2, empty_proof)); |
330 EXPECT_FALSE(VerifyConsistencyProof(log_, 2, root1, 1, root2, empty_proof)); | 354 EXPECT_FALSE(VerifyConsistencyProof(log_, 2, root1, 1, root2, empty_proof)); |
331 // Proof between two trees of different size can never be empty. | 355 // Proof between two trees of different size can never be empty. |
332 EXPECT_FALSE(VerifyConsistencyProof(log_, 1, root1, 2, root2, empty_proof)); | 356 EXPECT_FALSE(VerifyConsistencyProof(log_, 1, root1, 2, root2, empty_proof)); |
333 } | 357 } |
334 | 358 |
335 TEST_F(CTLogVerifierTest, VerifiesConsistencyProofEdgeCases_MismatchingRoots) { | 359 TEST_F(CTLogVerifierTest, VerifiesConsistencyProofEdgeCases_MismatchingRoots) { |
336 std::vector<std::string> empty_proof; | 360 std::vector<std::string> empty_proof; |
337 std::string root2; | 361 std::string root2; |
338 const std::string empty_tree_hash(GetEmptyTreeHash()); | 362 const std::string empty_tree_hash(HashAsStr(kSHA256EmptyTreeHash)); |
339 | 363 |
340 // Roots don't match. | 364 // Roots don't match. |
341 EXPECT_FALSE( | 365 EXPECT_FALSE( |
342 VerifyConsistencyProof(log_, 0, empty_tree_hash, 0, root2, empty_proof)); | 366 VerifyConsistencyProof(log_, 0, empty_tree_hash, 0, root2, empty_proof)); |
343 EXPECT_FALSE( | 367 EXPECT_FALSE( |
344 VerifyConsistencyProof(log_, 1, empty_tree_hash, 1, root2, empty_proof)); | 368 VerifyConsistencyProof(log_, 1, empty_tree_hash, 1, root2, empty_proof)); |
345 } | 369 } |
346 | 370 |
347 TEST_F(CTLogVerifierTest, | 371 TEST_F(CTLogVerifierTest, |
348 VerifiesConsistencyProofEdgeCases_MatchingRootsNonEmptyProof) { | 372 VerifiesConsistencyProofEdgeCases_MatchingRootsNonEmptyProof) { |
349 const std::string empty_tree_hash(GetEmptyTreeHash()); | 373 const std::string empty_tree_hash(HashAsStr(kSHA256EmptyTreeHash)); |
350 | 374 |
351 std::vector<std::string> proof; | 375 std::vector<std::string> proof; |
352 proof.push_back(empty_tree_hash); | 376 proof.push_back(empty_tree_hash); |
353 | 377 |
354 // Roots match and the tree size is either the same or the old tree size is 0, | 378 // Roots match and the tree size is either the same or the old tree size is 0, |
355 // but the proof is not empty (the verification code should not accept | 379 // but the proof is not empty (the verification code should not accept |
356 // proofs with redundant nodes in this case). | 380 // proofs with redundant nodes in this case). |
357 proof.push_back(empty_tree_hash); | 381 proof.push_back(empty_tree_hash); |
358 EXPECT_FALSE(VerifyConsistencyProof(log_, 0, empty_tree_hash, 0, | 382 EXPECT_FALSE(VerifyConsistencyProof(log_, 0, empty_tree_hash, 0, |
359 empty_tree_hash, proof)); | 383 empty_tree_hash, proof)); |
360 EXPECT_FALSE(VerifyConsistencyProof(log_, 0, empty_tree_hash, 1, | 384 EXPECT_FALSE(VerifyConsistencyProof(log_, 0, empty_tree_hash, 1, |
361 empty_tree_hash, proof)); | 385 empty_tree_hash, proof)); |
362 EXPECT_FALSE(VerifyConsistencyProof(log_, 1, empty_tree_hash, 1, | 386 EXPECT_FALSE(VerifyConsistencyProof(log_, 1, empty_tree_hash, 1, |
363 empty_tree_hash, proof)); | 387 empty_tree_hash, proof)); |
364 } | 388 } |
365 | 389 |
366 TEST_F(CTLogVerifierTest, VerifiesValidConsistencyProofs) { | 390 TEST_F(CTLogVerifierTest, VerifiesValidConsistencyProofs) { |
367 std::vector<std::string> proof; | 391 std::vector<std::string> proof; |
368 std::string root1, root2; | |
369 | 392 |
370 // Known good proofs. | 393 // Known good proofs. |
371 for (size_t i = 0; i < arraysize(kSHA256Proofs); ++i) { | 394 for (size_t i = 0; i < arraysize(kSHA256Proofs); ++i) { |
372 proof.clear(); | 395 proof.clear(); |
373 for (size_t j = 0; j < kSHA256Proofs[i].proof_length; ++j) { | 396 for (size_t j = 0; j < kSHA256Proofs[i].proof_length; ++j) { |
374 const char* const v = kSHA256Proofs[i].proof[j]; | 397 proof.push_back(HashAsStr(kSHA256Proofs[i].proof[j])); |
375 proof.push_back(HexToBytes(v)); | |
376 } | 398 } |
377 const uint64_t snapshot1 = kSHA256Proofs[i].snapshot1; | 399 const uint64_t snapshot1 = kSHA256Proofs[i].snapshot1; |
378 const uint64_t snapshot2 = kSHA256Proofs[i].snapshot2; | 400 const uint64_t snapshot2 = kSHA256Proofs[i].snapshot2; |
379 const char* const old_root = kSHA256Roots[snapshot1 - 1]; | 401 const std::string old_root = HashAsStr(kSHA256Roots[snapshot1 - 1]); |
380 const char* const new_root = kSHA256Roots[snapshot2 - 1]; | 402 const std::string new_root = HashAsStr(kSHA256Roots[snapshot2 - 1]); |
381 VerifierConsistencyCheck(snapshot1, snapshot2, HexToBytes(old_root), | 403 VerifierConsistencyCheck(snapshot1, snapshot2, old_root, new_root, proof); |
382 HexToBytes(new_root), proof); | |
383 } | 404 } |
384 } | 405 } |
385 | 406 |
386 const char kLeafPrefix[] = {'\x00'}; | 407 const char kLeafPrefix[] = {'\x00'}; |
387 | 408 |
388 // Reference implementation of RFC6962. | 409 // Reference implementation of RFC6962. |
389 // This allows generation of arbitrary-sized Merkle trees and consistency | 410 // This allows generation of arbitrary-sized Merkle trees and consistency |
390 // proofs between them for testing the consistency proof validation | 411 // proofs between them for testing the consistency proof validation |
391 // code. | 412 // code. |
392 class TreeHasher { | 413 class TreeHasher { |
(...skipping 11 matching lines...) Expand all Loading... |
404 return std::string(reinterpret_cast<const char*>(sha256.data), | 425 return std::string(reinterpret_cast<const char*>(sha256.data), |
405 sizeof(sha256.data)); | 426 sizeof(sha256.data)); |
406 } | 427 } |
407 }; | 428 }; |
408 | 429 |
409 // Reference implementation of Merkle hash, for cross-checking. | 430 // Reference implementation of Merkle hash, for cross-checking. |
410 // Recursively calculates the hash of the root given the leaf data | 431 // Recursively calculates the hash of the root given the leaf data |
411 // specified in |inputs|. | 432 // specified in |inputs|. |
412 std::string ReferenceMerkleTreeHash(std::string* inputs, uint64_t input_size) { | 433 std::string ReferenceMerkleTreeHash(std::string* inputs, uint64_t input_size) { |
413 if (!input_size) | 434 if (!input_size) |
414 return GetEmptyTreeHash(); | 435 return HashAsStr(kSHA256EmptyTreeHash); |
415 if (input_size == 1) | 436 if (input_size == 1) |
416 return TreeHasher::HashLeaf(inputs[0]); | 437 return TreeHasher::HashLeaf(inputs[0]); |
417 | 438 |
418 const uint64_t split = CalculateNearestPowerOfTwo(input_size); | 439 const uint64_t split = CalculateNearestPowerOfTwo(input_size); |
419 | 440 |
420 return ct::internal::HashNodes( | 441 return ct::internal::HashNodes( |
421 ReferenceMerkleTreeHash(&inputs[0], split), | 442 ReferenceMerkleTreeHash(&inputs[0], split), |
422 ReferenceMerkleTreeHash(&inputs[split], input_size - split)); | 443 ReferenceMerkleTreeHash(&inputs[split], input_size - split)); |
423 } | 444 } |
424 | 445 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 | 518 |
498 // Test verification of consistency proofs between all tree sizes from 1 to 128. | 519 // Test verification of consistency proofs between all tree sizes from 1 to 128. |
499 INSTANTIATE_TEST_CASE_P(RangeOfTreeSizesAndSnapshots, | 520 INSTANTIATE_TEST_CASE_P(RangeOfTreeSizesAndSnapshots, |
500 CTLogVerifierTestUsingReferenceGenerator, | 521 CTLogVerifierTestUsingReferenceGenerator, |
501 testing::Range(UINT64_C(1), | 522 testing::Range(UINT64_C(1), |
502 (kReferenceTreeSize / 2) + 1)); | 523 (kReferenceTreeSize / 2) + 1)); |
503 | 524 |
504 } // namespace | 525 } // namespace |
505 | 526 |
506 } // namespace net | 527 } // namespace net |
OLD | NEW |