Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: net/cert/ct_log_verifier_unittest.cc

Issue 2183073002: Improve documentation and readability of CTLogVerifier tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 23 matching lines...) Expand all
34 ret >>= 1; 34 ret >>= 1;
35 35
36 return ret; 36 return ret;
37 } 37 }
38 38
39 // The following structures, TestVector and ProofTestVector are used for 39 // The following structures, TestVector and ProofTestVector are used for
40 // definining test proofs later on. 40 // definining test proofs later on.
41 41
42 // A single hash node. 42 // A single hash node.
43 struct TestVector { 43 struct TestVector {
44 const char* const str; 44 const char* const str; // hex string
45 size_t length_bytes; 45 size_t length_bytes; // number of bytes represented by |str|
46 }; 46 };
47 47
48 // A single consistency proof. Contains the old and new tree sizes 48 // A single consistency proof. Contains the old and new tree sizes
49 // (snapshot1 and snapshot2), the length of the proof (proof_length) and 49 // (snapshot1 and snapshot2), the length of the proof (proof_length) and
50 // at most 3 proof nodes (all test proofs will be for a tree of size 8). 50 // at most 3 proof nodes (all test proofs will be for a tree of size 8).
51 struct ProofTestVector { 51 struct ProofTestVector {
52 uint64_t snapshot1; 52 uint64_t snapshot1;
53 uint64_t snapshot2; 53 uint64_t snapshot2;
54 size_t proof_length; 54 size_t proof_length;
55 TestVector proof[3]; 55 TestVector proof[3];
56 }; 56 };
57 57
58 // All test data replicated from 58 // All test data replicated from
59 // https://github.com/google/certificate-transparency/blob/c41b090ecc14ddd6b3531 dc7e5ce36b21e253fdd/cpp/merkletree/merkle_tree_test.cc 59 // https://github.com/google/certificate-transparency/blob/c41b090ecc14ddd6b3531 dc7e5ce36b21e253fdd/cpp/merkletree/merkle_tree_test.cc
60 // A hash of the empty string. 60 // A hash of the empty string.
61 const TestVector kSHA256EmptyTreeHash = { 61 const TestVector kSHA256EmptyTreeHash = {
62 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 32}; 62 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 32};
63 63
64 // Node hashes for a sample tree of size 8 (each element in this array is 64 // Incremental roots from building the sample tree of size 8 leaf-by-leaf.
65 // a node hash, not leaf data; order represents order of the nodes in the tree). 65 // The first entry is the root at size 0, the last is the root at size 8.
66 const TestVector kSHA256Roots[8] = { 66 const TestVector kSHA256Roots[8] = {
67 {"6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", 32}, 67 {"6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", 32},
68 {"fac54203e7cc696cf0dfcb42c92a1d9dbaf70ad9e621f4bd8d98662f00e3c125", 32}, 68 {"fac54203e7cc696cf0dfcb42c92a1d9dbaf70ad9e621f4bd8d98662f00e3c125", 32},
69 {"aeb6bcfe274b70a14fb067a5e5578264db0fa9b51af5e0ba159158f329e06e77", 32}, 69 {"aeb6bcfe274b70a14fb067a5e5578264db0fa9b51af5e0ba159158f329e06e77", 32},
70 {"d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7", 32}, 70 {"d37ee418976dd95753c1c73862b9398fa2a2cf9b4ff0fdfe8b30cd95209614b7", 32},
71 {"4e3bbb1f7b478dcfe71fb631631519a3bca12c9aefca1612bfce4c13a86264d4", 32}, 71 {"4e3bbb1f7b478dcfe71fb631631519a3bca12c9aefca1612bfce4c13a86264d4", 32},
72 {"76e67dadbcdf1e10e1b74ddc608abd2f98dfb16fbce75277b5232a127f2087ef", 32}, 72 {"76e67dadbcdf1e10e1b74ddc608abd2f98dfb16fbce75277b5232a127f2087ef", 32},
73 {"ddb89be403809e325750d3d263cd78929c2942b7942a34b77e122c9594a74c8c", 32}, 73 {"ddb89be403809e325750d3d263cd78929c2942b7942a34b77e122c9594a74c8c", 32},
74 {"5dc9da79a70659a9ad559cb701ded9a2ab9d823aad2f4960cfe370eff4604328", 32}}; 74 {"5dc9da79a70659a9ad559cb701ded9a2ab9d823aad2f4960cfe370eff4604328", 32}};
75 75
76 // A collection of consistency proofs between various sub-trees of the tree 76 // A collection of consistency proofs between various nodes of the sample tree.
77 // defined by |kSHA256Roots|.
78 const ProofTestVector kSHA256Proofs[4] = { 77 const ProofTestVector kSHA256Proofs[4] = {
79 // Empty consistency proof between trees of the same size (1). 78 // Empty consistency proof between trees of the same size (1).
80 {1, 1, 0, {{"", 0}, {"", 0}, {"", 0}}}, 79 {1, 1, 0, {{"", 0}, {"", 0}, {"", 0}}},
81 // Consistency proof between tree of size 1 and tree of size 8, with 3 80 // Consistency proof between tree of size 1 and tree of size 8, with 3
82 // nodes in the proof. 81 // nodes in the proof.
83 {1, 82 {1,
84 8, 83 8,
85 3, 84 3,
86 {{"96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7", 32}, 85 {{"96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7", 32},
87 {"5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e", 32}, 86 {"5f083f0a1a33ca076a95279832580db3e0ef4584bdff1f54c8a360f50de3031e", 32},
(...skipping 20 matching lines...) Expand all
108 // Decodes a hexadecimal string into the binary data it represents. 107 // Decodes a hexadecimal string into the binary data it represents.
109 std::string HexToBytes(const char* hex_data, size_t hex_data_length) { 108 std::string HexToBytes(const char* hex_data, size_t hex_data_length) {
110 std::vector<uint8_t> output; 109 std::vector<uint8_t> output;
111 std::string result; 110 std::string result;
112 std::string hex_data_input(hex_data, hex_data_length); 111 std::string hex_data_input(hex_data, hex_data_length);
113 if (base::HexStringToBytes(hex_data, &output)) 112 if (base::HexStringToBytes(hex_data, &output))
114 result.assign(reinterpret_cast<const char*>(&output[0]), output.size()); 113 result.assign(reinterpret_cast<const char*>(&output[0]), output.size());
115 return result; 114 return result;
116 } 115 }
117 116
117 std::string HexToBytes(const TestVector& x) {
118 std::string bytes = HexToBytes(x.str, x.length_bytes * 2);
119 CHECK_EQ(x.length_bytes, bytes.size());
120 return bytes;
121 }
122
118 std::string GetEmptyTreeHash() { 123 std::string GetEmptyTreeHash() {
119 return HexToBytes(kSHA256EmptyTreeHash.str, 124 return HexToBytes(kSHA256EmptyTreeHash);
120 kSHA256EmptyTreeHash.length_bytes);
Ryan Sleevi 2016/07/26 18:25:14 Wait, so this whole time, the empty tree hash was
Eran Messeri 2016/07/26 18:32:08 Turns out it wasn't, because of a bug in the HexTo
Ryan Sleevi 2016/07/26 18:36:24 So why does this CL leave the bug in place then? (
Rob Percival 2016/08/25 16:23:34 I've broken out a fix for this into https://codere
121 } 125 }
122 126
123 // Creates a ct::MerkleConsistencyProof and returns the result of 127 // Creates a ct::MerkleConsistencyProof and returns the result of
124 // calling log->VerifyConsistencyProof with that proof and snapshots. 128 // calling log->VerifyConsistencyProof with that proof and snapshots.
125 bool VerifyConsistencyProof(scoped_refptr<const CTLogVerifier> log, 129 bool VerifyConsistencyProof(scoped_refptr<const CTLogVerifier> log,
126 uint64_t old_tree_size, 130 uint64_t old_tree_size,
127 const std::string& old_tree_root, 131 const std::string& old_tree_root,
128 uint64_t new_tree_size, 132 uint64_t new_tree_size,
129 const std::string& new_tree_root, 133 const std::string& new_tree_root,
130 const std::vector<std::string>& proof) { 134 const std::vector<std::string>& proof) {
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 EXPECT_FALSE(VerifyConsistencyProof(log_, 1, empty_tree_hash, 1, 376 EXPECT_FALSE(VerifyConsistencyProof(log_, 1, empty_tree_hash, 1,
373 empty_tree_hash, proof)); 377 empty_tree_hash, proof));
374 } 378 }
375 379
376 TEST_F(CTLogVerifierTest, VerifiesValidConsistencyProofs) { 380 TEST_F(CTLogVerifierTest, VerifiesValidConsistencyProofs) {
377 std::vector<std::string> proof; 381 std::vector<std::string> proof;
378 std::string root1, root2; 382 std::string root1, root2;
379 383
380 // Known good proofs. 384 // Known good proofs.
381 for (size_t i = 0; i < arraysize(kSHA256Proofs); ++i) { 385 for (size_t i = 0; i < arraysize(kSHA256Proofs); ++i) {
386 SCOPED_TRACE(i);
382 proof.clear(); 387 proof.clear();
383 for (size_t j = 0; j < kSHA256Proofs[i].proof_length; ++j) { 388 for (size_t j = 0; j < kSHA256Proofs[i].proof_length; ++j) {
384 const TestVector& v = kSHA256Proofs[i].proof[j]; 389 const TestVector& v = kSHA256Proofs[i].proof[j];
385 proof.push_back(HexToBytes(v.str, v.length_bytes)); 390 proof.push_back(HexToBytes(v));
386 } 391 }
387 const uint64_t snapshot1 = kSHA256Proofs[i].snapshot1; 392 const uint64_t snapshot1 = kSHA256Proofs[i].snapshot1;
388 const uint64_t snapshot2 = kSHA256Proofs[i].snapshot2; 393 const uint64_t snapshot2 = kSHA256Proofs[i].snapshot2;
389 const TestVector& old_root = kSHA256Roots[snapshot1 - 1]; 394 const TestVector& old_root = kSHA256Roots[snapshot1 - 1];
390 const TestVector& new_root = kSHA256Roots[snapshot2 - 1]; 395 const TestVector& new_root = kSHA256Roots[snapshot2 - 1];
391 VerifierConsistencyCheck( 396 VerifierConsistencyCheck(snapshot1, snapshot2, HexToBytes(old_root),
392 snapshot1, snapshot2, HexToBytes(old_root.str, old_root.length_bytes), 397 HexToBytes(new_root), proof);
393 HexToBytes(new_root.str, new_root.length_bytes), proof);
394 } 398 }
395 } 399 }
396 400
397 const char kLeafPrefix[] = {'\x00'}; 401 const char kLeafPrefix[] = {'\x00'};
398 402
399 // Reference implementation of RFC6962. 403 // Reference implementation of RFC6962.
400 // This allows generation of arbitrary-sized Merkle trees and consistency 404 // This allows generation of arbitrary-sized Merkle trees and consistency
401 // proofs between them for testing the consistency proof validation 405 // proofs between them for testing the consistency proof validation
402 // code. 406 // code.
403 class TreeHasher { 407 class TreeHasher {
404 public: 408 public:
405 static std::string HashEmpty() { 409 static std::string HashEmpty() { return HexToBytes(kSHA256EmptyTreeHash); }
406 return HexToBytes(kSHA256EmptyTreeHash.str,
407 kSHA256EmptyTreeHash.length_bytes);
408 }
409 410
410 static std::string HashLeaf(const std::string& leaf) { 411 static std::string HashLeaf(const std::string& leaf) {
411 SHA256HashValue sha256; 412 SHA256HashValue sha256;
412 memset(sha256.data, 0, sizeof(sha256.data)); 413 memset(sha256.data, 0, sizeof(sha256.data));
413 414
414 std::unique_ptr<crypto::SecureHash> hash( 415 std::unique_ptr<crypto::SecureHash> hash(
415 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); 416 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
416 hash->Update(kLeafPrefix, 1); 417 hash->Update(kLeafPrefix, 1);
417 hash->Update(leaf.data(), leaf.size()); 418 hash->Update(leaf.data(), leaf.size());
418 hash->Finish(sha256.data, sizeof(sha256.data)); 419 hash->Finish(sha256.data, sizeof(sha256.data));
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 488
488 // Times out on Win7 test bot. http://crbug.com/598406 489 // Times out on Win7 test bot. http://crbug.com/598406
489 #if defined(OS_WIN) 490 #if defined(OS_WIN)
490 #define MAYBE_VerifiesValidConsistencyProofsFromReferenceGenerator \ 491 #define MAYBE_VerifiesValidConsistencyProofsFromReferenceGenerator \
491 DISABLED_VerifiesValidConsistencyProofsFromReferenceGenerator 492 DISABLED_VerifiesValidConsistencyProofsFromReferenceGenerator
492 #else 493 #else
493 #define MAYBE_VerifiesValidConsistencyProofsFromReferenceGenerator \ 494 #define MAYBE_VerifiesValidConsistencyProofsFromReferenceGenerator \
494 VerifiesValidConsistencyProofsFromReferenceGenerator 495 VerifiesValidConsistencyProofsFromReferenceGenerator
495 #endif 496 #endif
496 TEST_F(CTLogVerifierTest, 497 TEST_F(CTLogVerifierTest,
497 MAYBE_VerifiesValidConsistencyProofsFromReferenceGenerator) { 498 MAYBE_VerifiesValidConsistencyProofsFromReferenceGenerator) {
Ryan Sleevi 2016/07/26 18:40:29 Since you're improving documentation, this test is
Rob Percival 2016/08/25 16:23:34 Done.
498 std::vector<std::string> data; 499 std::vector<std::string> data;
499 for (int i = 0; i < 256; ++i) 500 for (int i = 0; i < 256; ++i)
500 data.push_back(std::string(1, i)); 501 data.push_back(std::string(1, i));
501 502
502 std::vector<std::string> proof; 503 std::vector<std::string> proof;
503 std::string root1, root2; 504 std::string root1, root2;
504 // More tests with reference proof generator. 505 // More tests with reference proof generator.
505 for (size_t tree_size = 1; tree_size <= data.size() / 2; ++tree_size) { 506 for (size_t tree_size = 1; tree_size <= data.size() / 2; ++tree_size) {
506 root2 = ReferenceMerkleTreeHash(data.data(), tree_size); 507 root2 = ReferenceMerkleTreeHash(data.data(), tree_size);
507 // Repeat for each snapshot in range. 508 // Repeat for each snapshot in range.
508 for (size_t snapshot = 1; snapshot <= tree_size; ++snapshot) { 509 for (size_t snapshot = 1; snapshot <= tree_size; ++snapshot) {
509 proof = 510 proof =
510 ReferenceSnapshotConsistency(data.data(), tree_size, snapshot, true); 511 ReferenceSnapshotConsistency(data.data(), tree_size, snapshot, true);
511 root1 = ReferenceMerkleTreeHash(data.data(), snapshot); 512 root1 = ReferenceMerkleTreeHash(data.data(), snapshot);
512 VerifierConsistencyCheck(snapshot, tree_size, root1, root2, proof); 513 VerifierConsistencyCheck(snapshot, tree_size, root1, root2, proof);
513 } 514 }
514 } 515 }
515 } 516 }
516 517
517 } // namespace 518 } // namespace
518 519
519 } // namespace net 520 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698