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

Side by Side Diff: components/certificate_transparency/log_dns_client_unittest.cc

Issue 2367523002: Merge LogDnsClient's QueryLeafIndex and QueryAuditProof methods (Closed)
Patch Set: Rebase Created 4 years, 2 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 | « components/certificate_transparency/log_dns_client.cc ('k') | 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "components/certificate_transparency/log_dns_client.h" 5 #include "components/certificate_transparency/log_dns_client.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <numeric> 8 #include <numeric>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 23 matching lines...) Expand all
34 using ::testing::AllOf; 34 using ::testing::AllOf;
35 using ::testing::Eq; 35 using ::testing::Eq;
36 using ::testing::IsEmpty; 36 using ::testing::IsEmpty;
37 using ::testing::IsNull; 37 using ::testing::IsNull;
38 using ::testing::Le; 38 using ::testing::Le;
39 using ::testing::Not; 39 using ::testing::Not;
40 using ::testing::NotNull; 40 using ::testing::NotNull;
41 using net::test::IsError; 41 using net::test::IsError;
42 using net::test::IsOk; 42 using net::test::IsOk;
43 43
44 // Sample Merkle leaf hashes.
44 const char* const kLeafHashes[] = { 45 const char* const kLeafHashes[] = {
45 "\x1f\x25\xe1\xca\xba\x4f\xf9\xb8\x27\x24\x83\x0f\xca\x60\xe4\xc2\xbe\xa8" 46 "\x1f\x25\xe1\xca\xba\x4f\xf9\xb8\x27\x24\x83\x0f\xca\x60\xe4\xc2\xbe\xa8"
46 "\xc3\xa9\x44\x1c\x27\xb0\xb4\x3e\x6a\x96\x94\xc7\xb8\x04", 47 "\xc3\xa9\x44\x1c\x27\xb0\xb4\x3e\x6a\x96\x94\xc7\xb8\x04",
47 "\x2c\x26\xb4\x6b\x68\xff\xc6\x8f\xf9\x9b\x45\x3c\x1d\x30\x41\x34\x13\x42" 48 "\x2c\x26\xb4\x6b\x68\xff\xc6\x8f\xf9\x9b\x45\x3c\x1d\x30\x41\x34\x13\x42"
48 "\x2d\x70\x64\x83\xbf\xa0\xf9\x8a\x5e\x88\x62\x66\xe7\xae", 49 "\x2d\x70\x64\x83\xbf\xa0\xf9\x8a\x5e\x88\x62\x66\xe7\xae",
49 "\xfc\xde\x2b\x2e\xdb\xa5\x6b\xf4\x08\x60\x1f\xb7\x21\xfe\x9b\x5c\x33\x8d" 50 "\xfc\xde\x2b\x2e\xdb\xa5\x6b\xf4\x08\x60\x1f\xb7\x21\xfe\x9b\x5c\x33\x8d"
50 "\x10\xee\x42\x9e\xa0\x4f\xae\x55\x11\xb6\x8f\xbf\x8f\xb9", 51 "\x10\xee\x42\x9e\xa0\x4f\xae\x55\x11\xb6\x8f\xbf\x8f\xb9",
51 }; 52 };
52 53
53 // Assumes log domain is "ct.test" 54 // DNS query names for looking up the leaf index associated with each hash in
54 const char* const kBase32LeafHashes[] = { 55 // |kLeafHashes|. Assumes the log domain is "ct.test".
56 const char* const kLeafIndexQnames[] = {
55 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", 57 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.",
56 "FQTLI23I77DI76M3IU6B2MCBGQJUELLQMSB37IHZRJPIQYTG46XA.hash.ct.test.", 58 "FQTLI23I77DI76M3IU6B2MCBGQJUELLQMSB37IHZRJPIQYTG46XA.hash.ct.test.",
57 "7TPCWLW3UVV7ICDAD63SD7U3LQZY2EHOIKPKAT5OKUI3ND57R64Q.hash.ct.test.", 59 "7TPCWLW3UVV7ICDAD63SD7U3LQZY2EHOIKPKAT5OKUI3ND57R64Q.hash.ct.test.",
58 }; 60 };
59 61
60 // Leaf indices and tree sizes for use with above leaf hashes. 62 // Leaf indices and tree sizes for use with |kLeafHashes|.
61 const uint64_t kLeafIndices[] = {0, 1, 2}; 63 const uint64_t kLeafIndices[] = {0, 1, 2};
62 const uint64_t kTreeSizes[] = {100, 10000, 1000000}; 64 const uint64_t kTreeSizes[] = {100, 10000, 1000000};
63 65
64 // Only 7 audit proof nodes can fit into a DNS response, because they are sent 66 // Only 7 audit proof nodes can fit into a DNS response, because they are sent
65 // in a TXT RDATA string, which has a maximum size of 255 bytes, and each node 67 // in a TXT RDATA string, which has a maximum size of 255 bytes, and each node
66 // is a SHA-256 hash (32 bytes), i.e. (255 / 32) == 7. 68 // is a SHA-256 hash (32 bytes), i.e. (255 / 32) == 7.
67 // This means audit proofs consisting of more than 7 nodes require multiple DNS 69 // This means audit proofs consisting of more than 7 nodes require multiple DNS
68 // requests to retrieve. 70 // requests to retrieve.
69 const size_t kMaxProofNodesPerDnsResponse = 7; 71 const size_t kMaxProofNodesPerDnsResponse = 7;
70 72
71 std::vector<std::string> GetSampleAuditProof(size_t length) { 73 std::vector<std::string> GetSampleAuditProof(size_t length) {
72 std::vector<std::string> audit_proof(length); 74 std::vector<std::string> audit_proof(length);
73 // Makes each node of the audit proof different, so that tests are able to 75 // Makes each node of the audit proof different, so that tests are able to
74 // confirm that the audit proof is reconstructed in the correct order. 76 // confirm that the audit proof is reconstructed in the correct order.
75 for (size_t i = 0; i < length; ++i) { 77 for (size_t i = 0; i < length; ++i) {
76 std::string node(crypto::kSHA256Length, '\0'); 78 std::string node(crypto::kSHA256Length, '\0');
77 // Each node is 32 bytes, with each byte having a different value. 79 // Each node is 32 bytes, with each byte having a different value.
78 for (size_t j = 0; j < crypto::kSHA256Length; ++j) { 80 for (size_t j = 0; j < crypto::kSHA256Length; ++j) {
79 node[j] = static_cast<char>((-127 + i + j) % 128); 81 node[j] = static_cast<char>((-127 + i + j) % 128);
80 } 82 }
81 audit_proof[i].assign(std::move(node)); 83 audit_proof[i].assign(std::move(node));
82 } 84 }
83 85
84 return audit_proof; 86 return audit_proof;
85 } 87 }
86 88
87 class MockLeafIndexCallback {
88 public:
89 MockLeafIndexCallback() : called_(false) {}
90
91 bool called() const { return called_; }
92 int net_error() const { return net_error_; }
93 uint64_t leaf_index() const { return leaf_index_; }
94
95 void Run(int net_error, uint64_t leaf_index) {
96 EXPECT_FALSE(called_);
97 called_ = true;
98 net_error_ = net_error;
99 leaf_index_ = leaf_index;
100 run_loop_.Quit();
101 }
102
103 LogDnsClient::LeafIndexCallback AsCallback() {
104 return base::Bind(&MockLeafIndexCallback::Run, base::Unretained(this));
105 }
106
107 void WaitUntilRun() { run_loop_.Run(); }
108
109 private:
110 bool called_;
111 int net_error_;
112 uint64_t leaf_index_;
113 base::RunLoop run_loop_;
114 };
115
116 class MockAuditProofCallback { 89 class MockAuditProofCallback {
117 public: 90 public:
118 MockAuditProofCallback() : called_(false) {} 91 MockAuditProofCallback() : called_(false) {}
119 92
120 bool called() const { return called_; } 93 bool called() const { return called_; }
121 int net_error() const { return net_error_; } 94 int net_error() const { return net_error_; }
122 const net::ct::MerkleAuditProof* proof() const { return proof_.get(); } 95 const net::ct::MerkleAuditProof* proof() const { return proof_.get(); }
123 96
124 void Run(int net_error, std::unique_ptr<net::ct::MerkleAuditProof> proof) { 97 void Run(int net_error, std::unique_ptr<net::ct::MerkleAuditProof> proof) {
125 EXPECT_FALSE(called_); 98 EXPECT_FALSE(called_);
(...skipping 24 matching lines...) Expand all
150 mock_dns_.InitializeDnsConfig(); 123 mock_dns_.InitializeDnsConfig();
151 } 124 }
152 125
153 std::unique_ptr<LogDnsClient> CreateLogDnsClient( 126 std::unique_ptr<LogDnsClient> CreateLogDnsClient(
154 size_t max_concurrent_queries) { 127 size_t max_concurrent_queries) {
155 return base::MakeUnique<LogDnsClient>(mock_dns_.CreateDnsClient(), 128 return base::MakeUnique<LogDnsClient>(mock_dns_.CreateDnsClient(),
156 net::NetLogWithSource(), 129 net::NetLogWithSource(),
157 max_concurrent_queries); 130 max_concurrent_queries);
158 } 131 }
159 132
160 void QueryLeafIndexAsync(LogDnsClient* log_client,
161 base::StringPiece log_domain,
162 const char leaf_hash[crypto::kSHA256Length],
163 const LogDnsClient::LeafIndexCallback& callback) {
164 log_client->QueryLeafIndex(log_domain, leaf_hash, callback);
165 }
166
167 // Convenience function for calling QueryLeafIndexAsync synchronously.
168 void QueryLeafIndex(base::StringPiece log_domain,
169 const char leaf_hash[crypto::kSHA256Length],
170 MockLeafIndexCallback* callback) {
171 std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0);
172 QueryLeafIndexAsync(log_client.get(), log_domain, leaf_hash,
173 callback->AsCallback());
174 callback->WaitUntilRun();
175 }
176
177 void QueryAuditProofAsync(LogDnsClient* log_client, 133 void QueryAuditProofAsync(LogDnsClient* log_client,
178 base::StringPiece log_domain, 134 const std::string& log_domain,
179 uint64_t leaf_index, 135 const char leaf_hash[crypto::kSHA256Length],
180 uint64_t tree_size, 136 uint64_t tree_size,
181 const LogDnsClient::AuditProofCallback& callback) { 137 const LogDnsClient::AuditProofCallback& callback) {
182 log_client->QueryAuditProof(log_domain, leaf_index, tree_size, callback); 138 log_client->QueryAuditProof(log_domain, leaf_hash, tree_size, callback);
183 } 139 }
184 140
185 // Convenience function for calling QueryAuditProofAsync synchronously. 141 // Convenience function for calling QueryAuditProofAsync synchronously.
186 void QueryAuditProof(base::StringPiece log_domain, 142 void QueryAuditProof(const std::string& log_domain,
187 uint64_t leaf_index, 143 const char leaf_hash[crypto::kSHA256Length],
188 uint64_t tree_size, 144 uint64_t tree_size,
189 MockAuditProofCallback* callback) { 145 MockAuditProofCallback* callback) {
190 std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0); 146 std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0);
191 QueryAuditProofAsync(log_client.get(), log_domain, leaf_index, tree_size, 147 QueryAuditProofAsync(log_client.get(), log_domain, leaf_hash, tree_size,
192 callback->AsCallback()); 148 callback->AsCallback());
193 callback->WaitUntilRun(); 149 callback->WaitUntilRun();
194 } 150 }
195 151
196 // This will be the NetworkChangeNotifier singleton for the duration of the 152 // This will be the NetworkChangeNotifier singleton for the duration of the
197 // test. It is accessed statically by LogDnsClient. 153 // test. It is accessed statically by LogDnsClient.
198 std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; 154 std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
199 // Queues and handles asynchronous DNS tasks. Indirectly used by LogDnsClient, 155 // Queues and handles asynchronous DNS tasks. Indirectly used by LogDnsClient,
200 // the underlying net::DnsClient, and NetworkChangeNotifier. 156 // the underlying net::DnsClient, and NetworkChangeNotifier.
201 base::MessageLoopForIO message_loop_; 157 base::MessageLoopForIO message_loop_;
202 // Allows mock DNS sockets to be setup. 158 // Allows mock DNS sockets to be setup.
203 MockLogDnsTraffic mock_dns_; 159 MockLogDnsTraffic mock_dns_;
204 }; 160 };
205 161
206 TEST_P(LogDnsClientTest, QueryLeafIndex) { 162 TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) {
207 mock_dns_.ExpectLeafIndexRequestAndResponse(kBase32LeafHashes[0], 123456); 163 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
208
209 MockLeafIndexCallback callback;
210 QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
211 ASSERT_TRUE(callback.called());
212 EXPECT_THAT(callback.net_error(), IsOk());
213 EXPECT_THAT(callback.leaf_index(), Eq(123456u));
214 }
215
216 TEST_P(LogDnsClientTest, QueryLeafIndexReportsThatLogDomainDoesNotExist) {
217 mock_dns_.ExpectRequestAndErrorResponse(kBase32LeafHashes[0],
218 net::dns_protocol::kRcodeNXDOMAIN); 164 net::dns_protocol::kRcodeNXDOMAIN);
219 165
220 MockLeafIndexCallback callback; 166 MockAuditProofCallback callback;
221 QueryLeafIndex("ct.test", kLeafHashes[0], &callback); 167 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
222 ASSERT_TRUE(callback.called()); 168 ASSERT_TRUE(callback.called());
223 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED)); 169 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED));
224 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 170 EXPECT_THAT(callback.proof(), IsNull());
225 }
226
227 TEST_P(LogDnsClientTest, QueryLeafIndexReportsServerFailure) {
228 mock_dns_.ExpectRequestAndErrorResponse(kBase32LeafHashes[0],
229 net::dns_protocol::kRcodeSERVFAIL);
230
231 MockLeafIndexCallback callback;
232 QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
233 ASSERT_TRUE(callback.called());
234 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
235 EXPECT_THAT(callback.leaf_index(), Eq(0u));
236 }
237
238 TEST_P(LogDnsClientTest, QueryLeafIndexReportsServerRefusal) {
239 mock_dns_.ExpectRequestAndErrorResponse(kBase32LeafHashes[0],
240 net::dns_protocol::kRcodeREFUSED);
241
242 MockLeafIndexCallback callback;
243 QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
244 ASSERT_TRUE(callback.called());
245 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
246 EXPECT_THAT(callback.leaf_index(), Eq(0u));
247 } 171 }
248 172
249 TEST_P(LogDnsClientTest, 173 TEST_P(LogDnsClientTest,
250 QueryLeafIndexReportsMalformedResponseIfContainsNoStrings) { 174 QueryAuditProofReportsServerFailuresDuringLeafIndexRequests) {
251 mock_dns_.ExpectRequestAndResponse( 175 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
252 kBase32LeafHashes[0], 176 net::dns_protocol::kRcodeSERVFAIL);
253 std::vector<base::StringPiece>());
254 177
255 MockLeafIndexCallback callback; 178 MockAuditProofCallback callback;
256 QueryLeafIndex("ct.test", kLeafHashes[0], &callback); 179 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
257 ASSERT_TRUE(callback.called()); 180 ASSERT_TRUE(callback.called());
258 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 181 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
259 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 182 EXPECT_THAT(callback.proof(), IsNull());
260 } 183 }
261 184
262 TEST_P(LogDnsClientTest, 185 TEST_P(LogDnsClientTest,
263 QueryLeafIndexReportsMalformedResponseIfContainsMoreThanOneString) { 186 QueryAuditProofReportsServerRefusalsDuringLeafIndexRequests) {
264 mock_dns_.ExpectRequestAndResponse( 187 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
265 kBase32LeafHashes[0], 188 net::dns_protocol::kRcodeREFUSED);
266 {"123456", "7"});
267 189
268 MockLeafIndexCallback callback; 190 MockAuditProofCallback callback;
269 QueryLeafIndex("ct.test", kLeafHashes[0], &callback); 191 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
270 ASSERT_TRUE(callback.called()); 192 ASSERT_TRUE(callback.called());
271 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 193 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
272 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 194 EXPECT_THAT(callback.proof(), IsNull());
273 } 195 }
274 196
275 TEST_P(LogDnsClientTest, 197 TEST_P(LogDnsClientTest,
276 QueryLeafIndexReportsMalformedResponseIfLeafIndexIsNotNumeric) { 198 QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsNoStrin gs) {
277 mock_dns_.ExpectRequestAndResponse(kBase32LeafHashes[0], {"foo"}); 199 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0],
200 std::vector<base::StringPiece>());
278 201
279 MockLeafIndexCallback callback; 202 MockAuditProofCallback callback;
280 QueryLeafIndex("ct.test", kLeafHashes[0], &callback); 203 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
281 ASSERT_TRUE(callback.called()); 204 ASSERT_TRUE(callback.called());
282 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 205 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
283 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 206 EXPECT_THAT(callback.proof(), IsNull());
284 } 207 }
285 208
286 TEST_P(LogDnsClientTest, 209 TEST_P(LogDnsClientTest,
287 QueryLeafIndexReportsMalformedResponseIfLeafIndexIsFloatingPoint) { 210 QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsMoreTha nOneString) {
288 mock_dns_.ExpectRequestAndResponse(kBase32LeafHashes[0], {"123456.0"}); 211 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456", "7"});
289 212
290 MockLeafIndexCallback callback; 213 MockAuditProofCallback callback;
291 QueryLeafIndex("ct.test", kLeafHashes[0], &callback); 214 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
292 ASSERT_TRUE(callback.called()); 215 ASSERT_TRUE(callback.called());
293 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 216 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
294 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 217 EXPECT_THAT(callback.proof(), IsNull());
295 } 218 }
296 219
297 TEST_P(LogDnsClientTest, 220 TEST_P(LogDnsClientTest,
298 QueryLeafIndexReportsMalformedResponseIfLeafIndexIsEmpty) { 221 QueryAuditProofReportsMalformedResponseIfLeafIndexIsNotNumeric) {
299 mock_dns_.ExpectRequestAndResponse(kBase32LeafHashes[0], {""}); 222 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo"});
300 223
301 MockLeafIndexCallback callback; 224 MockAuditProofCallback callback;
302 QueryLeafIndex("ct.test", kLeafHashes[0], &callback); 225 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
303 ASSERT_TRUE(callback.called()); 226 ASSERT_TRUE(callback.called());
304 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 227 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
305 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 228 EXPECT_THAT(callback.proof(), IsNull());
306 } 229 }
307 230
308 TEST_P(LogDnsClientTest, 231 TEST_P(LogDnsClientTest,
309 QueryLeafIndexReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) { 232 QueryAuditProofReportsMalformedResponseIfLeafIndexIsFloatingPoint) {
310 mock_dns_.ExpectRequestAndResponse(kBase32LeafHashes[0], {"foo123456"}); 233 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456.0"});
311 234
312 MockLeafIndexCallback callback; 235 MockAuditProofCallback callback;
313 QueryLeafIndex("ct.test", kLeafHashes[0], &callback); 236 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
314 ASSERT_TRUE(callback.called()); 237 ASSERT_TRUE(callback.called());
315 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 238 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
316 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 239 EXPECT_THAT(callback.proof(), IsNull());
317 } 240 }
318 241
319 TEST_P(LogDnsClientTest, 242 TEST_P(LogDnsClientTest,
320 QueryLeafIndexReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) { 243 QueryAuditProofReportsMalformedResponseIfLeafIndexIsEmpty) {
321 mock_dns_.ExpectRequestAndResponse(kBase32LeafHashes[0], {"123456foo"}); 244 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {""});
322 245
323 MockLeafIndexCallback callback; 246 MockAuditProofCallback callback;
324 QueryLeafIndex("ct.test", kLeafHashes[0], &callback); 247 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
325 ASSERT_TRUE(callback.called()); 248 ASSERT_TRUE(callback.called());
326 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 249 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
327 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 250 EXPECT_THAT(callback.proof(), IsNull());
328 } 251 }
329 252
330 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLogDomainIsEmpty) { 253 TEST_P(LogDnsClientTest,
331 MockLeafIndexCallback callback; 254 QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) {
332 QueryLeafIndex("", kLeafHashes[0], &callback); 255 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo123456"});
256
257 MockAuditProofCallback callback;
258 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
259 ASSERT_TRUE(callback.called());
260 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
261 EXPECT_THAT(callback.proof(), IsNull());
262 }
263
264 TEST_P(LogDnsClientTest,
265 QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) {
266 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456foo"});
267
268 MockAuditProofCallback callback;
269 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
270 ASSERT_TRUE(callback.called());
271 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
272 EXPECT_THAT(callback.proof(), IsNull());
273 }
274
275 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsEmpty) {
276 MockAuditProofCallback callback;
277 QueryAuditProof("", kLeafHashes[0], kTreeSizes[0], &callback);
333 ASSERT_TRUE(callback.called()); 278 ASSERT_TRUE(callback.called());
334 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); 279 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
335 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 280 EXPECT_THAT(callback.proof(), IsNull());
336 } 281 }
337 282
338 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLogDomainIsNull) { 283 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsInvalid) {
339 MockLeafIndexCallback callback; 284 MockAuditProofCallback callback;
340 QueryLeafIndex(nullptr, kLeafHashes[0], &callback); 285 QueryAuditProof("ct.test", "foo", kTreeSizes[0], &callback);
341 ASSERT_TRUE(callback.called()); 286 ASSERT_TRUE(callback.called());
342 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); 287 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
343 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 288 EXPECT_THAT(callback.proof(), IsNull());
344 } 289 }
345 290
346 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsInvalid) { 291 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsEmpty) {
347 MockLeafIndexCallback callback; 292 MockAuditProofCallback callback;
348 QueryLeafIndex("ct.test", "foo", &callback); 293 QueryAuditProof("ct.test", "", kTreeSizes[0], &callback);
349 ASSERT_TRUE(callback.called()); 294 ASSERT_TRUE(callback.called());
350 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); 295 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
351 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 296 EXPECT_THAT(callback.proof(), IsNull());
352 } 297 }
353 298
354 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsEmpty) { 299 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsNull) {
355 MockLeafIndexCallback callback; 300 MockAuditProofCallback callback;
356 QueryLeafIndex("ct.test", "", &callback); 301 QueryAuditProof("ct.test", nullptr, kTreeSizes[0], &callback);
357 ASSERT_TRUE(callback.called()); 302 ASSERT_TRUE(callback.called());
358 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); 303 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
359 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 304 EXPECT_THAT(callback.proof(), IsNull());
360 } 305 }
361 306
362 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsNull) { 307 TEST_P(LogDnsClientTest,
363 MockLeafIndexCallback callback; 308 QueryAuditProofReportsSocketErrorsDuringLeafIndexRequests) {
364 QueryLeafIndex("ct.test", nullptr, &callback); 309 mock_dns_.ExpectRequestAndSocketError(kLeafIndexQnames[0],
310 net::ERR_CONNECTION_REFUSED);
311
312 MockAuditProofCallback callback;
313 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
365 ASSERT_TRUE(callback.called()); 314 ASSERT_TRUE(callback.called());
366 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); 315 EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED));
367 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 316 EXPECT_THAT(callback.proof(), IsNull());
368 } 317 }
369 318
370 TEST_P(LogDnsClientTest, QueryLeafIndexReportsSocketError) { 319 TEST_P(LogDnsClientTest,
371 mock_dns_.ExpectRequestAndSocketError(kBase32LeafHashes[0], 320 QueryAuditProofReportsTimeoutsDuringLeafIndexRequests) {
372 net::ERR_CONNECTION_REFUSED); 321 mock_dns_.ExpectRequestAndTimeout(kLeafIndexQnames[0]);
373 322
374 MockLeafIndexCallback callback; 323 MockAuditProofCallback callback;
375 QueryLeafIndex("ct.test", kLeafHashes[0], &callback); 324 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
376 ASSERT_TRUE(callback.called());
377 EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED));
378 EXPECT_THAT(callback.leaf_index(), Eq(0u));
379 }
380
381 TEST_P(LogDnsClientTest, QueryLeafIndexReportsTimeout) {
382 mock_dns_.ExpectRequestAndTimeout(kBase32LeafHashes[0]);
383
384 MockLeafIndexCallback callback;
385 QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
386 ASSERT_TRUE(callback.called()); 325 ASSERT_TRUE(callback.called());
387 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT)); 326 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT));
388 EXPECT_THAT(callback.leaf_index(), Eq(0u)); 327 EXPECT_THAT(callback.proof(), IsNull());
389 } 328 }
390 329
391 TEST_P(LogDnsClientTest, QueryAuditProof) { 330 TEST_P(LogDnsClientTest, QueryAuditProof) {
392 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); 331 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
393 332
333 // Expect a leaf index query first, to map the leaf hash to a leaf index.
334 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
335
394 // It takes a number of DNS requests to retrieve the entire |audit_proof| 336 // It takes a number of DNS requests to retrieve the entire |audit_proof|
395 // (see |kMaxProofNodesPerDnsResponse|). 337 // (see |kMaxProofNodesPerDnsResponse|).
396 for (size_t nodes_begin = 0; nodes_begin < audit_proof.size(); 338 for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
397 nodes_begin += kMaxProofNodesPerDnsResponse) { 339 nodes_begin += kMaxProofNodesPerDnsResponse) {
398 const size_t nodes_end = std::min( 340 const size_t nodes_end = std::min(
399 nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size()); 341 nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
400 342
401 mock_dns_.ExpectAuditProofRequestAndResponse( 343 mock_dns_.ExpectAuditProofRequestAndResponse(
402 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin), 344 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
403 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end); 345 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end);
404 } 346 }
405 347
406 MockAuditProofCallback callback; 348 MockAuditProofCallback callback;
407 QueryAuditProof("ct.test", 123456, 999999, &callback); 349 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
408 ASSERT_TRUE(callback.called()); 350 ASSERT_TRUE(callback.called());
409 EXPECT_THAT(callback.net_error(), IsOk()); 351 EXPECT_THAT(callback.net_error(), IsOk());
410 ASSERT_THAT(callback.proof(), NotNull()); 352 ASSERT_THAT(callback.proof(), NotNull());
411 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u)); 353 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
412 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 354 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
413 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999)); 355 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999));
414 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof)); 356 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof));
415 } 357 }
416 358
417 TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) { 359 TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) {
418 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); 360 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
419 361
362 // Expect a leaf index query first, to map the leaf hash to a leaf index.
363 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
364
420 // Make some of the responses contain fewer proof nodes than they can hold. 365 // Make some of the responses contain fewer proof nodes than they can hold.
421 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", 366 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.",
422 audit_proof.begin(), 367 audit_proof.begin(),
423 audit_proof.begin() + 1); 368 audit_proof.begin() + 1);
424 mock_dns_.ExpectAuditProofRequestAndResponse("1.123456.999999.tree.ct.test.", 369 mock_dns_.ExpectAuditProofRequestAndResponse("1.123456.999999.tree.ct.test.",
425 audit_proof.begin() + 1, 370 audit_proof.begin() + 1,
426 audit_proof.begin() + 3); 371 audit_proof.begin() + 3);
427 mock_dns_.ExpectAuditProofRequestAndResponse("3.123456.999999.tree.ct.test.", 372 mock_dns_.ExpectAuditProofRequestAndResponse("3.123456.999999.tree.ct.test.",
428 audit_proof.begin() + 3, 373 audit_proof.begin() + 3,
429 audit_proof.begin() + 6); 374 audit_proof.begin() + 6);
430 mock_dns_.ExpectAuditProofRequestAndResponse("6.123456.999999.tree.ct.test.", 375 mock_dns_.ExpectAuditProofRequestAndResponse("6.123456.999999.tree.ct.test.",
431 audit_proof.begin() + 6, 376 audit_proof.begin() + 6,
432 audit_proof.begin() + 10); 377 audit_proof.begin() + 10);
433 mock_dns_.ExpectAuditProofRequestAndResponse("10.123456.999999.tree.ct.test.", 378 mock_dns_.ExpectAuditProofRequestAndResponse("10.123456.999999.tree.ct.test.",
434 audit_proof.begin() + 10, 379 audit_proof.begin() + 10,
435 audit_proof.begin() + 13); 380 audit_proof.begin() + 13);
436 mock_dns_.ExpectAuditProofRequestAndResponse("13.123456.999999.tree.ct.test.", 381 mock_dns_.ExpectAuditProofRequestAndResponse("13.123456.999999.tree.ct.test.",
437 audit_proof.begin() + 13, 382 audit_proof.begin() + 13,
438 audit_proof.end()); 383 audit_proof.end());
439 384
440 MockAuditProofCallback callback; 385 MockAuditProofCallback callback;
441 QueryAuditProof("ct.test", 123456, 999999, &callback); 386 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
442 ASSERT_TRUE(callback.called()); 387 ASSERT_TRUE(callback.called());
443 EXPECT_THAT(callback.net_error(), IsOk()); 388 EXPECT_THAT(callback.net_error(), IsOk());
444 ASSERT_THAT(callback.proof(), NotNull()); 389 ASSERT_THAT(callback.proof(), NotNull());
445 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u)); 390 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
446 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 391 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
447 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999)); 392 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999));
448 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof)); 393 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof));
449 } 394 }
450 395
451 TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) { 396 TEST_P(LogDnsClientTest,
397 QueryAuditProofReportsThatAuditProofQnameDoesNotExist) {
398 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
452 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", 399 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
453 net::dns_protocol::kRcodeNXDOMAIN); 400 net::dns_protocol::kRcodeNXDOMAIN);
454 401
455 MockAuditProofCallback callback; 402 MockAuditProofCallback callback;
456 QueryAuditProof("ct.test", 123456, 999999, &callback); 403 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
457 ASSERT_TRUE(callback.called()); 404 ASSERT_TRUE(callback.called());
458 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED)); 405 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED));
459 EXPECT_THAT(callback.proof(), IsNull()); 406 EXPECT_THAT(callback.proof(), IsNull());
460 } 407 }
461 408
462 TEST_P(LogDnsClientTest, QueryAuditProofReportsServerFailure) { 409 TEST_P(LogDnsClientTest,
410 QueryAuditProofReportsServerFailureDuringAuditProofRequests) {
411 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
463 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", 412 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
464 net::dns_protocol::kRcodeSERVFAIL); 413 net::dns_protocol::kRcodeSERVFAIL);
465 414
466 MockAuditProofCallback callback; 415 MockAuditProofCallback callback;
467 QueryAuditProof("ct.test", 123456, 999999, &callback); 416 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
468 ASSERT_TRUE(callback.called());
469 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
470 EXPECT_THAT(callback.proof(), IsNull());
471 }
472
473 TEST_P(LogDnsClientTest, QueryAuditProofReportsServerRefusal) {
474 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
475 net::dns_protocol::kRcodeREFUSED);
476
477 MockAuditProofCallback callback;
478 QueryAuditProof("ct.test", 123456, 999999, &callback);
479 ASSERT_TRUE(callback.called()); 417 ASSERT_TRUE(callback.called());
480 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED)); 418 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
481 EXPECT_THAT(callback.proof(), IsNull()); 419 EXPECT_THAT(callback.proof(), IsNull());
482 } 420 }
483 421
484 TEST_P(LogDnsClientTest, 422 TEST_P(LogDnsClientTest,
485 QueryAuditProofReportsResponseMalformedIfContainsNoStrings) { 423 QueryAuditProofReportsServerRefusalDuringAuditProofRequests) {
424 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
425 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
426 net::dns_protocol::kRcodeREFUSED);
427
428 MockAuditProofCallback callback;
429 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
430 ASSERT_TRUE(callback.called());
431 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
432 EXPECT_THAT(callback.proof(), IsNull());
433 }
434
435 TEST_P(LogDnsClientTest,
436 QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsNoStri ngs) {
437 // Expect a leaf index query first, to map the leaf hash to a leaf index.
438 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
439
486 mock_dns_.ExpectRequestAndResponse("0.123456.999999.tree.ct.test.", 440 mock_dns_.ExpectRequestAndResponse("0.123456.999999.tree.ct.test.",
487 std::vector<base::StringPiece>()); 441 std::vector<base::StringPiece>());
488 442
489 MockAuditProofCallback callback; 443 MockAuditProofCallback callback;
490 QueryAuditProof("ct.test", 123456, 999999, &callback); 444 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
491 ASSERT_TRUE(callback.called()); 445 ASSERT_TRUE(callback.called());
492 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 446 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
493 EXPECT_THAT(callback.proof(), IsNull()); 447 EXPECT_THAT(callback.proof(), IsNull());
494 } 448 }
495 449
496 TEST_P(LogDnsClientTest, 450 TEST_P(LogDnsClientTest,
497 QueryAuditProofReportsResponseMalformedIfContainsMoreThanOneString) { 451 QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsMoreTh anOneString) {
498 // The CT-over-DNS draft RFC states that the response will contain "exactly 452 // The CT-over-DNS draft RFC states that the response will contain "exactly
499 // one character-string." 453 // one character-string."
500 const std::vector<std::string> audit_proof = GetSampleAuditProof(10); 454 const std::vector<std::string> audit_proof = GetSampleAuditProof(10);
501 455
502 std::string first_chunk_of_proof = std::accumulate( 456 std::string first_chunk_of_proof = std::accumulate(
503 audit_proof.begin(), audit_proof.begin() + 7, std::string()); 457 audit_proof.begin(), audit_proof.begin() + 7, std::string());
504 std::string second_chunk_of_proof = std::accumulate( 458 std::string second_chunk_of_proof = std::accumulate(
505 audit_proof.begin() + 7, audit_proof.end(), std::string()); 459 audit_proof.begin() + 7, audit_proof.end(), std::string());
506 460
461 // Expect a leaf index query first, to map the leaf hash to a leaf index.
462 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
463
507 mock_dns_.ExpectRequestAndResponse( 464 mock_dns_.ExpectRequestAndResponse(
508 "0.123456.999999.tree.ct.test.", 465 "0.123456.999999.tree.ct.test.",
509 {first_chunk_of_proof, second_chunk_of_proof}); 466 {first_chunk_of_proof, second_chunk_of_proof});
510 467
511 MockAuditProofCallback callback; 468 MockAuditProofCallback callback;
512 QueryAuditProof("ct.test", 123456, 999999, &callback); 469 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
513 ASSERT_TRUE(callback.called()); 470 ASSERT_TRUE(callback.called());
514 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 471 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
515 EXPECT_THAT(callback.proof(), IsNull()); 472 EXPECT_THAT(callback.proof(), IsNull());
516 } 473 }
517 474
518 TEST_P(LogDnsClientTest, 475 TEST_P(LogDnsClientTest,
519 QueryAuditProofReportsResponseMalformedIfNodeTooShort) { 476 QueryAuditProofReportsResponseMalformedIfNodeTooShort) {
520 // node is shorter than a SHA-256 hash (31 vs 32 bytes) 477 // node is shorter than a SHA-256 hash (31 vs 32 bytes)
521 const std::vector<std::string> audit_proof(1, std::string(31, 'a')); 478 const std::vector<std::string> audit_proof(1, std::string(31, 'a'));
522 479
480 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
523 mock_dns_.ExpectAuditProofRequestAndResponse( 481 mock_dns_.ExpectAuditProofRequestAndResponse(
524 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()); 482 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
525 483
526 MockAuditProofCallback callback; 484 MockAuditProofCallback callback;
527 QueryAuditProof("ct.test", 123456, 999999, &callback); 485 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
528 ASSERT_TRUE(callback.called()); 486 ASSERT_TRUE(callback.called());
529 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 487 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
530 EXPECT_THAT(callback.proof(), IsNull()); 488 EXPECT_THAT(callback.proof(), IsNull());
531 } 489 }
532 490
533 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfNodeTooLong) { 491 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfNodeTooLong) {
534 // node is longer than a SHA-256 hash (33 vs 32 bytes) 492 // node is longer than a SHA-256 hash (33 vs 32 bytes)
535 const std::vector<std::string> audit_proof(1, std::string(33, 'a')); 493 const std::vector<std::string> audit_proof(1, std::string(33, 'a'));
536 494
495 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
537 mock_dns_.ExpectAuditProofRequestAndResponse( 496 mock_dns_.ExpectAuditProofRequestAndResponse(
538 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()); 497 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
539 498
540 MockAuditProofCallback callback; 499 MockAuditProofCallback callback;
541 QueryAuditProof("ct.test", 123456, 999999, &callback); 500 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
542 ASSERT_TRUE(callback.called()); 501 ASSERT_TRUE(callback.called());
543 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 502 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
544 EXPECT_THAT(callback.proof(), IsNull()); 503 EXPECT_THAT(callback.proof(), IsNull());
545 } 504 }
546 505
547 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfEmpty) { 506 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfEmpty) {
548 const std::vector<std::string> audit_proof; 507 const std::vector<std::string> audit_proof;
549 508
509 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
550 mock_dns_.ExpectAuditProofRequestAndResponse( 510 mock_dns_.ExpectAuditProofRequestAndResponse(
551 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()); 511 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
552 512
553 MockAuditProofCallback callback; 513 MockAuditProofCallback callback;
554 QueryAuditProof("ct.test", 123456, 999999, &callback); 514 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
555 ASSERT_TRUE(callback.called()); 515 ASSERT_TRUE(callback.called());
556 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); 516 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
557 EXPECT_THAT(callback.proof(), IsNull()); 517 EXPECT_THAT(callback.proof(), IsNull());
558 } 518 }
559 519
560 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsEmpty) {
561 MockAuditProofCallback callback;
562 QueryAuditProof("", 123456, 999999, &callback);
563 ASSERT_TRUE(callback.called());
564 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
565 EXPECT_THAT(callback.proof(), IsNull());
566 }
567
568 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsNull) {
569 MockAuditProofCallback callback;
570 QueryAuditProof(nullptr, 123456, 999999, &callback);
571 ASSERT_TRUE(callback.called());
572 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
573 EXPECT_THAT(callback.proof(), IsNull());
574 }
575
576 TEST_P(LogDnsClientTest, 520 TEST_P(LogDnsClientTest,
577 QueryAuditProofReportsInvalidArgIfLeafIndexEqualToTreeSize) { 521 QueryAuditProofReportsInvalidArgIfLeafIndexEqualToTreeSize) {
522 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
523
578 MockAuditProofCallback callback; 524 MockAuditProofCallback callback;
579 QueryAuditProof("ct.test", 123456, 123456, &callback); 525 QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback);
580 ASSERT_TRUE(callback.called()); 526 ASSERT_TRUE(callback.called());
581 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); 527 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
582 EXPECT_THAT(callback.proof(), IsNull()); 528 EXPECT_THAT(callback.proof(), IsNull());
583 } 529 }
584 530
585 TEST_P(LogDnsClientTest, 531 TEST_P(LogDnsClientTest,
586 QueryAuditProofReportsInvalidArgIfLeafIndexGreaterThanTreeSize) { 532 QueryAuditProofReportsInvalidArgIfLeafIndexGreaterThanTreeSize) {
533 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 999999);
534
587 MockAuditProofCallback callback; 535 MockAuditProofCallback callback;
588 QueryAuditProof("ct.test", 999999, 123456, &callback); 536 QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback);
589 ASSERT_TRUE(callback.called()); 537 ASSERT_TRUE(callback.called());
590 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); 538 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
591 EXPECT_THAT(callback.proof(), IsNull()); 539 EXPECT_THAT(callback.proof(), IsNull());
592 } 540 }
593 541
594 TEST_P(LogDnsClientTest, QueryAuditProofReportsSocketError) { 542 TEST_P(LogDnsClientTest,
543 QueryAuditProofReportsSocketErrorsDuringAuditProofRequests) {
544 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
595 mock_dns_.ExpectRequestAndSocketError("0.123456.999999.tree.ct.test.", 545 mock_dns_.ExpectRequestAndSocketError("0.123456.999999.tree.ct.test.",
596 net::ERR_CONNECTION_REFUSED); 546 net::ERR_CONNECTION_REFUSED);
597 547
598 MockAuditProofCallback callback; 548 MockAuditProofCallback callback;
599 QueryAuditProof("ct.test", 123456, 999999, &callback); 549 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
600 ASSERT_TRUE(callback.called()); 550 ASSERT_TRUE(callback.called());
601 EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED)); 551 EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED));
602 EXPECT_THAT(callback.proof(), IsNull()); 552 EXPECT_THAT(callback.proof(), IsNull());
603 } 553 }
604 554
605 TEST_P(LogDnsClientTest, QueryAuditProofReportsTimeout) { 555 TEST_P(LogDnsClientTest,
556 QueryAuditProofReportsTimeoutsDuringAuditProofRequests) {
557 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
606 mock_dns_.ExpectRequestAndTimeout("0.123456.999999.tree.ct.test."); 558 mock_dns_.ExpectRequestAndTimeout("0.123456.999999.tree.ct.test.");
607 559
608 MockAuditProofCallback callback; 560 MockAuditProofCallback callback;
609 QueryAuditProof("ct.test", 123456, 999999, &callback); 561 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
610 ASSERT_TRUE(callback.called()); 562 ASSERT_TRUE(callback.called());
611 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT)); 563 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT));
612 EXPECT_THAT(callback.proof(), IsNull()); 564 EXPECT_THAT(callback.proof(), IsNull());
613 } 565 }
614 566
615 TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) { 567 TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) {
616 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient(); 568 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient();
617 net::DnsClient* dns_client = tmp.get(); 569 net::DnsClient* dns_client = tmp.get();
618 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0); 570 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0);
619 571
(...skipping 17 matching lines...) Expand all
637 net::DnsConfig config(*dns_client->GetConfig()); 589 net::DnsConfig config(*dns_client->GetConfig());
638 ASSERT_THAT(config.nameservers, Not(IsEmpty())); 590 ASSERT_THAT(config.nameservers, Not(IsEmpty()));
639 config.nameservers.clear(); // Makes config invalid 591 config.nameservers.clear(); // Makes config invalid
640 mock_dns_.SetDnsConfig(config); 592 mock_dns_.SetDnsConfig(config);
641 593
642 // Let the DNS config change propogate. 594 // Let the DNS config change propogate.
643 base::RunLoop().RunUntilIdle(); 595 base::RunLoop().RunUntilIdle();
644 EXPECT_THAT(dns_client->GetConfig()->nameservers, Not(IsEmpty())); 596 EXPECT_THAT(dns_client->GetConfig()->nameservers, Not(IsEmpty()));
645 } 597 }
646 598
647 TEST_P(LogDnsClientTest, CanPerformLeafIndexQueriesInParallel) { 599 // Test that changes to the DNS config after starting a query are adopted and
648 // Test that leaf index queries can be performed in parallel. 600 // that the query is not disrupted.
649 constexpr size_t kNumOfParallelQueries = 3; 601 TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigMidQuery) {
650 ASSERT_THAT(kNumOfParallelQueries, AllOf(Le(arraysize(kLeafHashes)), 602 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
651 Le(arraysize(kBase32LeafHashes))))
652 << "Not enough test data for this many parallel queries";
653 603
654 std::unique_ptr<LogDnsClient> log_client = 604 // Expect a leaf index query first, to map the leaf hash to a leaf index.
655 CreateLogDnsClient(kNumOfParallelQueries); 605 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
656 MockLeafIndexCallback callbacks[kNumOfParallelQueries];
657 606
658 // Expect multiple queries. 607 // It takes a number of DNS requests to retrieve the entire |audit_proof|
659 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 608 // (see |kMaxProofNodesPerDnsResponse|).
660 mock_dns_.ExpectLeafIndexRequestAndResponse( 609 for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
661 kBase32LeafHashes[i], kLeafIndices[i]); 610 nodes_begin += kMaxProofNodesPerDnsResponse) {
611 const size_t nodes_end = std::min(
612 nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
613
614 mock_dns_.ExpectAuditProofRequestAndResponse(
615 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
616 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end);
662 } 617 }
663 618
664 // Start the queries. 619 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient();
665 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 620 net::DnsClient* dns_client = tmp.get();
666 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[i], 621 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0);
667 callbacks[i].AsCallback());
668 }
669 622
670 // Wait for each query to complete and check its results. 623 // Start query.
671 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 624 MockAuditProofCallback callback;
672 MockLeafIndexCallback& callback = callbacks[i]; 625 QueryAuditProofAsync(&log_client, "ct.test", kLeafHashes[0], 999999,
673 callback.WaitUntilRun(); 626 callback.AsCallback());
674 627
675 SCOPED_TRACE(testing::Message() << "callbacks[" << i << "]"); 628 // Get the current DNS config, modify it and broadcast the update.
676 ASSERT_TRUE(callback.called()); 629 net::DnsConfig config(*dns_client->GetConfig());
677 EXPECT_THAT(callback.net_error(), IsOk()); 630 ASSERT_NE(123, config.attempts);
678 EXPECT_THAT(callback.leaf_index(), Eq(kLeafIndices[i])); 631 config.attempts = 123;
679 } 632 mock_dns_.SetDnsConfig(config);
633
634 callback.WaitUntilRun();
635 // Check that the DNS changes propogated before the query completed.
636 EXPECT_EQ(123, dns_client->GetConfig()->attempts);
637
638 ASSERT_TRUE(callback.called());
639 EXPECT_THAT(callback.net_error(), IsOk());
640 ASSERT_THAT(callback.proof(), NotNull());
641 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
642 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
643 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999));
644 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof));
680 } 645 }
681 646
682 TEST_P(LogDnsClientTest, CanPerformAuditProofQueriesInParallel) { 647 TEST_P(LogDnsClientTest, CanPerformQueriesInParallel) {
683 // Check that 3 audit proof queries can be performed in parallel. 648 // Check that 3 queries can be performed in parallel.
684 constexpr size_t kNumOfParallelQueries = 3; 649 constexpr size_t kNumOfParallelQueries = 3;
685 ASSERT_THAT(kNumOfParallelQueries, 650 ASSERT_THAT(kNumOfParallelQueries,
686 AllOf(Le(arraysize(kLeafIndices)), Le(arraysize(kTreeSizes)))) 651 AllOf(Le(arraysize(kLeafIndexQnames)),
652 Le(arraysize(kLeafIndices)), Le(arraysize(kTreeSizes))))
687 << "Not enough test data for this many parallel queries"; 653 << "Not enough test data for this many parallel queries";
688 654
689 std::unique_ptr<LogDnsClient> log_client = 655 std::unique_ptr<LogDnsClient> log_client =
690 CreateLogDnsClient(kNumOfParallelQueries); 656 CreateLogDnsClient(kNumOfParallelQueries);
691 MockAuditProofCallback callbacks[kNumOfParallelQueries]; 657 MockAuditProofCallback callbacks[kNumOfParallelQueries];
692 658
693 // Each query should require one more DNS request than the last. 659 // Expect multiple leaf index requests.
694 // This helps to test that parallel queries do not intefere with each other, 660 for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
695 // e.g. one query causing another to end prematurely. 661 mock_dns_.ExpectLeafIndexRequestAndResponse(
662 kLeafIndexQnames[i], kLeafIndices[i]);
663 }
664
665 // Make each query require one more audit proof request than the last, by
666 // increasing the number of nodes in the audit proof by
667 // kMaxProofNodesPerDnsResponse for each query. This helps to test that
668 // parallel queries do not intefere with each other, e.g. one query causing
669 // another to end prematurely.
696 std::vector<std::string> audit_proofs[kNumOfParallelQueries]; 670 std::vector<std::string> audit_proofs[kNumOfParallelQueries];
697 for (size_t query_i = 0; query_i < kNumOfParallelQueries; ++query_i) { 671 for (size_t query_i = 0; query_i < kNumOfParallelQueries; ++query_i) {
698 const size_t dns_requests_required = query_i + 1; 672 const size_t dns_requests_required = query_i + 1;
699 audit_proofs[query_i] = GetSampleAuditProof(dns_requests_required * 673 audit_proofs[query_i] = GetSampleAuditProof(dns_requests_required *
700 kMaxProofNodesPerDnsResponse); 674 kMaxProofNodesPerDnsResponse);
701 } 675 }
702 // The most DNS requests that are made by any of the above N queries is N. 676 // The most DNS requests that are made by any of the above N queries is N.
703 const size_t kMaxDnsRequestsPerQuery = kNumOfParallelQueries; 677 const size_t kMaxDnsRequestsPerQuery = kNumOfParallelQueries;
704 678
705 // Setup expectations for up to N DNS requests per query performed. 679 // Setup expectations for up to N DNS requests per query performed.
(...skipping 17 matching lines...) Expand all
723 base::StringPrintf("%zu.%" PRIu64 ".%" PRIu64 ".tree.ct.test.", 697 base::StringPrintf("%zu.%" PRIu64 ".%" PRIu64 ".tree.ct.test.",
724 start_node, kLeafIndices[query_i], 698 start_node, kLeafIndices[query_i],
725 kTreeSizes[query_i]), 699 kTreeSizes[query_i]),
726 proof.begin() + start_node, proof.begin() + end_node); 700 proof.begin() + start_node, proof.begin() + end_node);
727 } 701 }
728 } 702 }
729 } 703 }
730 704
731 // Start the queries. 705 // Start the queries.
732 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 706 for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
733 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafIndices[i], 707 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[i],
734 kTreeSizes[i], callbacks[i].AsCallback()); 708 kTreeSizes[i], callbacks[i].AsCallback());
735 } 709 }
736 710
737 // Wait for each query to complete and check its results. 711 // Wait for each query to complete and check its results.
738 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 712 for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
739 MockAuditProofCallback& callback = callbacks[i]; 713 MockAuditProofCallback& callback = callbacks[i];
740 callbacks[i].WaitUntilRun(); 714 callbacks[i].WaitUntilRun();
741 715
742 SCOPED_TRACE(testing::Message() << "callbacks[" << i << "]"); 716 SCOPED_TRACE(testing::Message() << "callbacks[" << i << "]");
743 ASSERT_TRUE(callback.called()); 717 ASSERT_TRUE(callback.called());
744 EXPECT_THAT(callback.net_error(), IsOk()); 718 EXPECT_THAT(callback.net_error(), IsOk());
745 ASSERT_THAT(callback.proof(), NotNull()); 719 ASSERT_THAT(callback.proof(), NotNull());
746 EXPECT_THAT(callback.proof()->leaf_index, Eq(kLeafIndices[i])); 720 EXPECT_THAT(callback.proof()->leaf_index, Eq(kLeafIndices[i]));
747 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 721 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
748 // EXPECT_THAT(callback.proof()->tree_size, kTreeSizes[i]); 722 // EXPECT_THAT(callback.proof()->tree_size, kTreeSizes[i]);
749 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proofs[i])); 723 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proofs[i]));
750 } 724 }
751 } 725 }
752 726
753 TEST_P(LogDnsClientTest, CanPerformLeafIndexAndAuditProofQueriesInParallel) { 727 TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) {
754 // Check that a leaf index and audit proof query can be performed in parallel. 728 // Check that queries can be rate-limited to one at a time.
755 constexpr size_t kNumOfParallelQueries = 2; 729 // The second query, initiated while the first is in progress, should fail.
756 std::unique_ptr<LogDnsClient> log_client =
757 CreateLogDnsClient(kNumOfParallelQueries);
758 MockLeafIndexCallback leaf_index_callback;
759 MockAuditProofCallback audit_proof_callback;
760 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); 730 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
761 731
762 mock_dns_.ExpectLeafIndexRequestAndResponse(kBase32LeafHashes[0], 123456); 732 // Expect the first query to send leaf index and audit proof requests, but the
763 733 // second should not due to throttling.
764 // It should require 3 requests to collect the entire audit proof, as there is 734 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
765 // only space for 7 nodes per TXT record. One node is 32 bytes long and the
766 // TXT RDATA can have a maximum length of 255 bytes (255 / 32).
767 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.",
768 audit_proof.begin(),
769 audit_proof.begin() + 7);
770 mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.",
771 audit_proof.begin() + 7,
772 audit_proof.begin() + 14);
773 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.",
774 audit_proof.begin() + 14,
775 audit_proof.end());
776
777 // Start the queries.
778 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[0],
779 leaf_index_callback.AsCallback());
780 QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999,
781 audit_proof_callback.AsCallback());
782
783 // Wait for the queries to complete, then check their results.
784 leaf_index_callback.WaitUntilRun();
785 audit_proof_callback.WaitUntilRun();
786
787 ASSERT_TRUE(leaf_index_callback.called());
788 EXPECT_THAT(leaf_index_callback.net_error(), IsOk());
789 EXPECT_THAT(leaf_index_callback.leaf_index(), Eq(123456u));
790
791 ASSERT_TRUE(audit_proof_callback.called());
792 EXPECT_THAT(audit_proof_callback.net_error(), IsOk());
793 ASSERT_THAT(audit_proof_callback.proof(), NotNull());
794 EXPECT_THAT(audit_proof_callback.proof()->leaf_index, Eq(123456u));
795 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
796 // EXPECT_THAT(audit_proof_callback.proof()->tree_size, Eq(999999));
797 EXPECT_THAT(audit_proof_callback.proof()->nodes, Eq(audit_proof));
798 }
799
800 TEST_P(LogDnsClientTest, CanBeThrottledToOneLeafIndexQueryAtATime) {
801 // Check that leaf index queries can be rate-limited to one at a time.
802 // The second query, initiated while the first is in progress, should fail.
803 mock_dns_.ExpectLeafIndexRequestAndResponse(kBase32LeafHashes[0], 123456);
804
805 const size_t max_concurrent_queries = 1;
806 std::unique_ptr<LogDnsClient> log_client =
807 CreateLogDnsClient(max_concurrent_queries);
808
809 // Start the queries.
810 MockLeafIndexCallback callback1;
811 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[0],
812 callback1.AsCallback());
813 MockLeafIndexCallback callback2;
814 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[1],
815 callback2.AsCallback());
816
817 callback1.WaitUntilRun();
818 callback2.WaitUntilRun();
819
820 // Check that the first query succeeded.
821 ASSERT_TRUE(callback1.called());
822 EXPECT_THAT(callback1.net_error(), IsOk());
823 EXPECT_THAT(callback1.leaf_index(), Eq(123456u));
824
825 // Check that the second query failed.
826 ASSERT_TRUE(callback2.called());
827 EXPECT_THAT(callback2.net_error(), IsError(net::ERR_TEMPORARILY_THROTTLED));
828 EXPECT_THAT(callback2.leaf_index(), Eq(0u));
829
830 // Try a third query, which should succeed now that the first is finished.
831 mock_dns_.ExpectLeafIndexRequestAndResponse(kBase32LeafHashes[2], 666);
832
833 MockLeafIndexCallback callback3;
834 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[2],
835 callback3.AsCallback());
836
837 callback3.WaitUntilRun();
838
839 // Check that the third query succeeded.
840 ASSERT_TRUE(callback3.called());
841 EXPECT_THAT(callback3.net_error(), IsOk());
842 EXPECT_THAT(callback3.leaf_index(), Eq(666u));
843 }
844
845 TEST_P(LogDnsClientTest, CanBeThrottledToOneAuditProofQueryAtATime) {
846 // Check that audit proof queries can be rate-limited to one at a time.
847 // The second query, initiated while the first is in progress, should fail.
848 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
849 735
850 // It should require 3 requests to collect the entire audit proof, as there is 736 // It should require 3 requests to collect the entire audit proof, as there is
851 // only space for 7 nodes per TXT record. One node is 32 bytes long and the 737 // only space for 7 nodes per TXT record. One node is 32 bytes long and the
852 // TXT RDATA can have a maximum length of 255 bytes (255 / 32). 738 // TXT RDATA can have a maximum length of 255 bytes (255 / 32).
853 // Rate limiting should not interfere with these requests. 739 // Rate limiting should not interfere with these requests.
854 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", 740 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.",
855 audit_proof.begin(), 741 audit_proof.begin(),
856 audit_proof.begin() + 7); 742 audit_proof.begin() + 7);
857 mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.", 743 mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.",
858 audit_proof.begin() + 7, 744 audit_proof.begin() + 7,
859 audit_proof.begin() + 14); 745 audit_proof.begin() + 14);
860 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.", 746 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.",
861 audit_proof.begin() + 14, 747 audit_proof.begin() + 14,
862 audit_proof.end()); 748 audit_proof.end());
863 749
864 const size_t max_concurrent_queries = 1; 750 const size_t kMaxConcurrentQueries = 1;
865 std::unique_ptr<LogDnsClient> log_client = 751 std::unique_ptr<LogDnsClient> log_client =
866 CreateLogDnsClient(max_concurrent_queries); 752 CreateLogDnsClient(kMaxConcurrentQueries);
867 753
868 // Start the queries. 754 // Start the queries.
869 MockAuditProofCallback callback1; 755 MockAuditProofCallback callback1;
870 QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999, 756 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[0], 999999,
871 callback1.AsCallback()); 757 callback1.AsCallback());
872 MockAuditProofCallback callback2; 758 MockAuditProofCallback callback2;
873 QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999, 759 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[1], 999999,
874 callback2.AsCallback()); 760 callback2.AsCallback());
875 761
876 callback1.WaitUntilRun(); 762 callback1.WaitUntilRun();
877 callback2.WaitUntilRun(); 763 callback2.WaitUntilRun();
878 764
879 // Check that the first query succeeded. 765 // Check that the first query succeeded.
880 ASSERT_TRUE(callback1.called()); 766 ASSERT_TRUE(callback1.called());
881 EXPECT_THAT(callback1.net_error(), IsOk()); 767 EXPECT_THAT(callback1.net_error(), IsOk());
882 ASSERT_THAT(callback1.proof(), NotNull()); 768 ASSERT_THAT(callback1.proof(), NotNull());
883 EXPECT_THAT(callback1.proof()->leaf_index, Eq(123456u)); 769 EXPECT_THAT(callback1.proof()->leaf_index, Eq(123456u));
884 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 770 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
885 // EXPECT_THAT(callback1.proof()->tree_size, Eq(999999)); 771 // EXPECT_THAT(callback1.proof()->tree_size, Eq(999999));
886 EXPECT_THAT(callback1.proof()->nodes, Eq(audit_proof)); 772 EXPECT_THAT(callback1.proof()->nodes, Eq(audit_proof));
887 773
888 // Check that the second query failed. 774 // Check that the second query failed.
889 ASSERT_TRUE(callback2.called()); 775 ASSERT_TRUE(callback2.called());
890 EXPECT_THAT(callback2.net_error(), IsError(net::ERR_TEMPORARILY_THROTTLED)); 776 EXPECT_THAT(callback2.net_error(), IsError(net::ERR_TEMPORARILY_THROTTLED));
891 EXPECT_THAT(callback2.proof(), IsNull()); 777 EXPECT_THAT(callback2.proof(), IsNull());
892 778
893 // Try a third query, which should succeed now that the first is finished. 779 // Try a third query, which should succeed now that the first is finished.
894 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", 780 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[2], 666);
781 mock_dns_.ExpectAuditProofRequestAndResponse("0.666.999999.tree.ct.test.",
895 audit_proof.begin(), 782 audit_proof.begin(),
896 audit_proof.begin() + 7); 783 audit_proof.begin() + 7);
897 mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.", 784 mock_dns_.ExpectAuditProofRequestAndResponse("7.666.999999.tree.ct.test.",
898 audit_proof.begin() + 7, 785 audit_proof.begin() + 7,
899 audit_proof.begin() + 14); 786 audit_proof.begin() + 14);
900 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.", 787 mock_dns_.ExpectAuditProofRequestAndResponse("14.666.999999.tree.ct.test.",
901 audit_proof.begin() + 14, 788 audit_proof.begin() + 14,
902 audit_proof.end()); 789 audit_proof.end());
903 790
904 MockAuditProofCallback callback3; 791 MockAuditProofCallback callback3;
905 QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999, 792 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[2], 999999,
906 callback3.AsCallback()); 793 callback3.AsCallback());
907 794
908 callback3.WaitUntilRun(); 795 callback3.WaitUntilRun();
909 796
910 // Check that the third query succeeded. 797 // Check that the third query succeeded.
911 ASSERT_TRUE(callback3.called()); 798 ASSERT_TRUE(callback3.called());
912 EXPECT_THAT(callback3.net_error(), IsOk()); 799 EXPECT_THAT(callback3.net_error(), IsOk());
913 ASSERT_THAT(callback3.proof(), NotNull()); 800 ASSERT_THAT(callback3.proof(), NotNull());
914 EXPECT_THAT(callback3.proof()->leaf_index, Eq(123456u)); 801 EXPECT_THAT(callback3.proof()->leaf_index, Eq(666u));
915 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 802 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
916 // EXPECT_THAT(callback3.proof()->tree_size, Eq(999999)); 803 // EXPECT_THAT(callback3.proof()->tree_size, Eq(999999));
917 EXPECT_THAT(callback3.proof()->nodes, Eq(audit_proof)); 804 EXPECT_THAT(callback3.proof()->nodes, Eq(audit_proof));
918 } 805 }
919 806
920 TEST_P(LogDnsClientTest, ThrottlingAppliesAcrossQueryTypes) {
921 // Check that queries can be rate-limited to one at a time, regardless of the
922 // type of query. The second query, initiated while the first is in progress,
923 // should fail.
924 mock_dns_.ExpectLeafIndexRequestAndResponse(
925 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.",
926 123456);
927
928 const size_t max_concurrent_queries = 1;
929 std::unique_ptr<LogDnsClient> log_client =
930 CreateLogDnsClient(max_concurrent_queries);
931
932 // Start the queries.
933 MockLeafIndexCallback leaf_index_callback;
934 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[0],
935 leaf_index_callback.AsCallback());
936 MockAuditProofCallback audit_proof_callback;
937 QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999,
938 audit_proof_callback.AsCallback());
939
940 leaf_index_callback.WaitUntilRun();
941 audit_proof_callback.WaitUntilRun();
942
943 // Check that the first query succeeded.
944 ASSERT_TRUE(leaf_index_callback.called());
945 EXPECT_THAT(leaf_index_callback.net_error(), IsOk());
946 EXPECT_THAT(leaf_index_callback.leaf_index(), Eq(123456u));
947
948 // Check that the second query failed.
949 ASSERT_TRUE(audit_proof_callback.called());
950 EXPECT_THAT(audit_proof_callback.net_error(),
951 IsError(net::ERR_TEMPORARILY_THROTTLED));
952 EXPECT_THAT(audit_proof_callback.proof(), IsNull());
953 }
954
955 INSTANTIATE_TEST_CASE_P(ReadMode, 807 INSTANTIATE_TEST_CASE_P(ReadMode,
956 LogDnsClientTest, 808 LogDnsClientTest,
957 ::testing::Values(net::IoMode::ASYNC, 809 ::testing::Values(net::IoMode::ASYNC,
958 net::IoMode::SYNCHRONOUS)); 810 net::IoMode::SYNCHRONOUS));
959 811
960 } // namespace 812 } // namespace
961 } // namespace certificate_transparency 813 } // namespace certificate_transparency
OLDNEW
« no previous file with comments | « components/certificate_transparency/log_dns_client.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698