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

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

Issue 2369373002: LogDnsClient now returns some errors synchronously (Closed)
Patch Set: Addresses Eran's comments 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>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/format_macros.h" 13 #include "base/format_macros.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h" 16 #include "base/run_loop.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "base/test/test_timeouts.h"
19 #include "components/certificate_transparency/mock_log_dns_traffic.h" 20 #include "components/certificate_transparency/mock_log_dns_traffic.h"
20 #include "crypto/sha2.h" 21 #include "crypto/sha2.h"
21 #include "net/base/net_errors.h" 22 #include "net/base/net_errors.h"
22 #include "net/cert/merkle_audit_proof.h" 23 #include "net/cert/merkle_audit_proof.h"
23 #include "net/cert/signed_certificate_timestamp.h" 24 #include "net/cert/signed_certificate_timestamp.h"
24 #include "net/dns/dns_client.h" 25 #include "net/dns/dns_client.h"
25 #include "net/dns/dns_config_service.h" 26 #include "net/dns/dns_config_service.h"
26 #include "net/dns/dns_protocol.h" 27 #include "net/dns/dns_protocol.h"
28 #include "net/log/net_log.h"
27 #include "net/test/gtest_util.h" 29 #include "net/test/gtest_util.h"
28 #include "testing/gmock/include/gmock/gmock.h" 30 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h" 31 #include "testing/gtest/include/gtest/gtest.h"
30 32
31 namespace certificate_transparency { 33 namespace certificate_transparency {
32 namespace { 34 namespace {
33 35
34 using ::testing::AllOf; 36 using ::testing::AllOf;
35 using ::testing::Eq; 37 using ::testing::Eq;
36 using ::testing::IsEmpty; 38 using ::testing::IsEmpty;
37 using ::testing::IsNull;
38 using ::testing::Le; 39 using ::testing::Le;
39 using ::testing::Not; 40 using ::testing::Not;
40 using ::testing::NotNull; 41 using ::testing::NotNull;
41 using net::test::IsError; 42 using net::test::IsError;
42 using net::test::IsOk; 43 using net::test::IsOk;
43 44
44 // Sample Merkle leaf hashes. 45 // Sample Merkle leaf hashes.
45 const char* const kLeafHashes[] = { 46 const char* const kLeafHashes[] = {
46 "\x1f\x25\xe1\xca\xba\x4f\xf9\xb8\x27\x24\x83\x0f\xca\x60\xe4\xc2\xbe\xa8" 47 "\x1f\x25\xe1\xca\xba\x4f\xf9\xb8\x27\x24\x83\x0f\xca\x60\xe4\xc2\xbe\xa8"
47 "\xc3\xa9\x44\x1c\x27\xb0\xb4\x3e\x6a\x96\x94\xc7\xb8\x04", 48 "\xc3\xa9\x44\x1c\x27\xb0\xb4\x3e\x6a\x96\x94\xc7\xb8\x04",
(...skipping 15 matching lines...) Expand all
63 const uint64_t kLeafIndices[] = {0, 1, 2}; 64 const uint64_t kLeafIndices[] = {0, 1, 2};
64 const uint64_t kTreeSizes[] = {100, 10000, 1000000}; 65 const uint64_t kTreeSizes[] = {100, 10000, 1000000};
65 66
66 // Only 7 audit proof nodes can fit into a DNS response, because they are sent 67 // Only 7 audit proof nodes can fit into a DNS response, because they are sent
67 // in a TXT RDATA string, which has a maximum size of 255 bytes, and each node 68 // in a TXT RDATA string, which has a maximum size of 255 bytes, and each node
68 // is a SHA-256 hash (32 bytes), i.e. (255 / 32) == 7. 69 // is a SHA-256 hash (32 bytes), i.e. (255 / 32) == 7.
69 // This means audit proofs consisting of more than 7 nodes require multiple DNS 70 // This means audit proofs consisting of more than 7 nodes require multiple DNS
70 // requests to retrieve. 71 // requests to retrieve.
71 const size_t kMaxProofNodesPerDnsResponse = 7; 72 const size_t kMaxProofNodesPerDnsResponse = 7;
72 73
74 // Returns an example Merkle audit proof containing |length| nodes.
75 // The proof cannot be used for cryptographic purposes; it is merely a
76 // placeholder.
73 std::vector<std::string> GetSampleAuditProof(size_t length) { 77 std::vector<std::string> GetSampleAuditProof(size_t length) {
74 std::vector<std::string> audit_proof(length); 78 std::vector<std::string> audit_proof(length);
75 // Makes each node of the audit proof different, so that tests are able to 79 // Makes each node of the audit proof different, so that tests are able to
76 // confirm that the audit proof is reconstructed in the correct order. 80 // confirm that the audit proof is reconstructed in the correct order.
77 for (size_t i = 0; i < length; ++i) { 81 for (size_t i = 0; i < length; ++i) {
78 std::string node(crypto::kSHA256Length, '\0'); 82 std::string node(crypto::kSHA256Length, '\0');
79 // Each node is 32 bytes, with each byte having a different value. 83 // Each node is 32 bytes, with each byte having a different value.
80 for (size_t j = 0; j < crypto::kSHA256Length; ++j) { 84 for (size_t j = 0; j < crypto::kSHA256Length; ++j) {
81 node[j] = static_cast<char>((-127 + i + j) % 128); 85 node[j] = static_cast<char>((-127 + i + j) % 128);
82 } 86 }
83 audit_proof[i].assign(std::move(node)); 87 audit_proof[i].assign(std::move(node));
84 } 88 }
85 89
86 return audit_proof; 90 return audit_proof;
87 } 91 }
88 92
89 class MockAuditProofCallback {
90 public:
91 MockAuditProofCallback() : called_(false) {}
92
93 bool called() const { return called_; }
94 int net_error() const { return net_error_; }
95 const net::ct::MerkleAuditProof* proof() const { return proof_.get(); }
96
97 void Run(int net_error, std::unique_ptr<net::ct::MerkleAuditProof> proof) {
98 EXPECT_FALSE(called_);
99 called_ = true;
100 net_error_ = net_error;
101 proof_ = std::move(proof);
102 run_loop_.Quit();
103 }
104
105 LogDnsClient::AuditProofCallback AsCallback() {
106 return base::Bind(&MockAuditProofCallback::Run, base::Unretained(this));
107 }
108
109 void WaitUntilRun() { run_loop_.Run(); }
110
111 private:
112 bool called_;
113 int net_error_;
114 std::unique_ptr<net::ct::MerkleAuditProof> proof_;
115 base::RunLoop run_loop_;
116 };
117
118 } // namespace 93 } // namespace
119 94
120 class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> { 95 class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> {
121 protected: 96 protected:
122 LogDnsClientTest() 97 LogDnsClientTest()
123 : network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) { 98 : network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {
124 mock_dns_.SetSocketReadMode(GetParam()); 99 mock_dns_.SetSocketReadMode(GetParam());
125 mock_dns_.InitializeDnsConfig(); 100 mock_dns_.InitializeDnsConfig();
126 } 101 }
127 102
128 std::unique_ptr<LogDnsClient> CreateLogDnsClient( 103 std::unique_ptr<LogDnsClient> CreateLogDnsClient(
129 size_t max_concurrent_queries) { 104 size_t max_concurrent_queries) {
130 return base::MakeUnique<LogDnsClient>(mock_dns_.CreateDnsClient(), 105 return base::MakeUnique<LogDnsClient>(mock_dns_.CreateDnsClient(),
131 net::NetLogWithSource(), 106 net::NetLogWithSource(),
132 max_concurrent_queries); 107 max_concurrent_queries);
133 } 108 }
134 109
135 void QueryAuditProofAsync(LogDnsClient* log_client, 110 // Convenience function for calling QueryAuditProof synchronously.
136 const std::string& log_domain, 111 template <typename... Types>
137 const char leaf_hash[crypto::kSHA256Length], 112 net::Error QueryAuditProof(Types&&... args) {
138 uint64_t tree_size, 113 std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0);
139 const LogDnsClient::AuditProofCallback& callback) { 114 net::TestCompletionCallback callback;
140 log_client->QueryAuditProof(log_domain, leaf_hash, tree_size, callback); 115 const net::Error result = log_client->QueryAuditProof(
141 } 116 std::forward<Types>(args)..., callback.callback());
142 117
143 // Convenience function for calling QueryAuditProofAsync synchronously. 118 return result != net::ERR_IO_PENDING
144 void QueryAuditProof(const std::string& log_domain, 119 ? result
145 const char leaf_hash[crypto::kSHA256Length], 120 : static_cast<net::Error>(callback.WaitForResult());
146 uint64_t tree_size,
147 MockAuditProofCallback* callback) {
148 std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0);
149 QueryAuditProofAsync(log_client.get(), log_domain, leaf_hash, tree_size,
150 callback->AsCallback());
151 callback->WaitUntilRun();
152 } 121 }
153 122
154 // This will be the NetworkChangeNotifier singleton for the duration of the 123 // This will be the NetworkChangeNotifier singleton for the duration of the
155 // test. It is accessed statically by LogDnsClient. 124 // test. It is accessed statically by LogDnsClient.
156 std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; 125 std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
157 // Queues and handles asynchronous DNS tasks. Indirectly used by LogDnsClient, 126 // Queues and handles asynchronous DNS tasks. Indirectly used by LogDnsClient,
158 // the underlying net::DnsClient, and NetworkChangeNotifier. 127 // the underlying net::DnsClient, and NetworkChangeNotifier.
159 base::MessageLoopForIO message_loop_; 128 base::MessageLoopForIO message_loop_;
160 // Allows mock DNS sockets to be setup. 129 // Allows mock DNS sockets to be setup.
161 MockLogDnsTraffic mock_dns_; 130 MockLogDnsTraffic mock_dns_;
162 }; 131 };
163 132
164 TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) { 133 TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) {
165 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0], 134 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
166 net::dns_protocol::kRcodeNXDOMAIN); 135 net::dns_protocol::kRcodeNXDOMAIN);
167 136
168 MockAuditProofCallback callback; 137 net::ct::MerkleAuditProof proof;
169 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 138 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
170 ASSERT_TRUE(callback.called()); 139 IsError(net::ERR_NAME_NOT_RESOLVED));
171 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED));
172 EXPECT_THAT(callback.proof(), IsNull());
173 } 140 }
174 141
175 TEST_P(LogDnsClientTest, 142 TEST_P(LogDnsClientTest,
176 QueryAuditProofReportsServerFailuresDuringLeafIndexRequests) { 143 QueryAuditProofReportsServerFailuresDuringLeafIndexRequests) {
177 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0], 144 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
178 net::dns_protocol::kRcodeSERVFAIL); 145 net::dns_protocol::kRcodeSERVFAIL);
179 146
180 MockAuditProofCallback callback; 147 net::ct::MerkleAuditProof proof;
181 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 148 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
182 ASSERT_TRUE(callback.called()); 149 IsError(net::ERR_DNS_SERVER_FAILED));
183 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
184 EXPECT_THAT(callback.proof(), IsNull());
185 } 150 }
186 151
187 TEST_P(LogDnsClientTest, 152 TEST_P(LogDnsClientTest,
188 QueryAuditProofReportsServerRefusalsDuringLeafIndexRequests) { 153 QueryAuditProofReportsServerRefusalsDuringLeafIndexRequests) {
189 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0], 154 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
190 net::dns_protocol::kRcodeREFUSED); 155 net::dns_protocol::kRcodeREFUSED);
191 156
192 MockAuditProofCallback callback; 157 net::ct::MerkleAuditProof proof;
193 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 158 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
194 ASSERT_TRUE(callback.called()); 159 IsError(net::ERR_DNS_SERVER_FAILED));
195 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
196 EXPECT_THAT(callback.proof(), IsNull());
197 } 160 }
198 161
199 TEST_P(LogDnsClientTest, 162 TEST_P(
200 QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsNoStrin gs) { 163 LogDnsClientTest,
164 QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsNoStrings) {
201 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], 165 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0],
202 std::vector<base::StringPiece>()); 166 std::vector<base::StringPiece>());
203 167
204 MockAuditProofCallback callback; 168 net::ct::MerkleAuditProof proof;
205 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 169 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
206 ASSERT_TRUE(callback.called()); 170 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
207 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
208 EXPECT_THAT(callback.proof(), IsNull());
209 } 171 }
210 172
211 TEST_P(LogDnsClientTest, 173 TEST_P(
212 QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsMoreTha nOneString) { 174 LogDnsClientTest,
175 QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsMoreThanOn eString) {
213 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456", "7"}); 176 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456", "7"});
214 177
215 MockAuditProofCallback callback; 178 net::ct::MerkleAuditProof proof;
216 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 179 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
217 ASSERT_TRUE(callback.called()); 180 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
218 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
219 EXPECT_THAT(callback.proof(), IsNull());
220 } 181 }
221 182
222 TEST_P(LogDnsClientTest, 183 TEST_P(LogDnsClientTest,
223 QueryAuditProofReportsMalformedResponseIfLeafIndexIsNotNumeric) { 184 QueryAuditProofReportsMalformedResponseIfLeafIndexIsNotNumeric) {
224 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo"}); 185 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo"});
225 186
226 MockAuditProofCallback callback; 187 net::ct::MerkleAuditProof proof;
227 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 188 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
228 ASSERT_TRUE(callback.called()); 189 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
229 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
230 EXPECT_THAT(callback.proof(), IsNull());
231 } 190 }
232 191
233 TEST_P(LogDnsClientTest, 192 TEST_P(LogDnsClientTest,
234 QueryAuditProofReportsMalformedResponseIfLeafIndexIsFloatingPoint) { 193 QueryAuditProofReportsMalformedResponseIfLeafIndexIsFloatingPoint) {
235 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456.0"}); 194 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456.0"});
236 195
237 MockAuditProofCallback callback; 196 net::ct::MerkleAuditProof proof;
238 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 197 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
239 ASSERT_TRUE(callback.called()); 198 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
240 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
241 EXPECT_THAT(callback.proof(), IsNull());
242 } 199 }
243 200
244 TEST_P(LogDnsClientTest, 201 TEST_P(LogDnsClientTest,
245 QueryAuditProofReportsMalformedResponseIfLeafIndexIsEmpty) { 202 QueryAuditProofReportsMalformedResponseIfLeafIndexIsEmpty) {
246 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {""}); 203 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {""});
247 204
248 MockAuditProofCallback callback; 205 net::ct::MerkleAuditProof proof;
249 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 206 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
250 ASSERT_TRUE(callback.called()); 207 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
251 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
252 EXPECT_THAT(callback.proof(), IsNull());
253 } 208 }
254 209
255 TEST_P(LogDnsClientTest, 210 TEST_P(LogDnsClientTest,
256 QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) { 211 QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) {
257 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo123456"}); 212 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo123456"});
258 213
259 MockAuditProofCallback callback; 214 net::ct::MerkleAuditProof proof;
260 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 215 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
261 ASSERT_TRUE(callback.called()); 216 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
262 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
263 EXPECT_THAT(callback.proof(), IsNull());
264 } 217 }
265 218
266 TEST_P(LogDnsClientTest, 219 TEST_P(LogDnsClientTest,
267 QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) { 220 QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) {
268 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456foo"}); 221 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456foo"});
269 222
270 MockAuditProofCallback callback; 223 net::ct::MerkleAuditProof proof;
271 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 224 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
272 ASSERT_TRUE(callback.called()); 225 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
273 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
274 EXPECT_THAT(callback.proof(), IsNull());
275 } 226 }
276 227
277 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsEmpty) { 228 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsEmpty) {
278 MockAuditProofCallback callback; 229 net::ct::MerkleAuditProof proof;
279 QueryAuditProof("", kLeafHashes[0], kTreeSizes[0], &callback); 230 ASSERT_THAT(QueryAuditProof("", kLeafHashes[0], kTreeSizes[0], &proof),
280 ASSERT_TRUE(callback.called()); 231 IsError(net::ERR_INVALID_ARGUMENT));
281 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
282 EXPECT_THAT(callback.proof(), IsNull());
283 } 232 }
284 233
285 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsInvalid) { 234 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsInvalid) {
286 MockAuditProofCallback callback; 235 net::ct::MerkleAuditProof proof;
287 QueryAuditProof("ct.test", "foo", kTreeSizes[0], &callback); 236 ASSERT_THAT(QueryAuditProof("ct.test", "foo", kTreeSizes[0], &proof),
288 ASSERT_TRUE(callback.called()); 237 IsError(net::ERR_INVALID_ARGUMENT));
289 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
290 EXPECT_THAT(callback.proof(), IsNull());
291 } 238 }
292 239
293 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsEmpty) { 240 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsEmpty) {
294 MockAuditProofCallback callback; 241 net::ct::MerkleAuditProof proof;
295 QueryAuditProof("ct.test", "", kTreeSizes[0], &callback); 242 ASSERT_THAT(QueryAuditProof("ct.test", "", kTreeSizes[0], &proof),
296 ASSERT_TRUE(callback.called()); 243 IsError(net::ERR_INVALID_ARGUMENT));
297 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
298 EXPECT_THAT(callback.proof(), IsNull());
299 }
300
301 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsNull) {
302 MockAuditProofCallback callback;
303 QueryAuditProof("ct.test", nullptr, kTreeSizes[0], &callback);
304 ASSERT_TRUE(callback.called());
305 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
306 EXPECT_THAT(callback.proof(), IsNull());
307 } 244 }
308 245
309 TEST_P(LogDnsClientTest, 246 TEST_P(LogDnsClientTest,
310 QueryAuditProofReportsSocketErrorsDuringLeafIndexRequests) { 247 QueryAuditProofReportsSocketErrorsDuringLeafIndexRequests) {
311 mock_dns_.ExpectRequestAndSocketError(kLeafIndexQnames[0], 248 mock_dns_.ExpectRequestAndSocketError(kLeafIndexQnames[0],
312 net::ERR_CONNECTION_REFUSED); 249 net::ERR_CONNECTION_REFUSED);
313 250
314 MockAuditProofCallback callback; 251 net::ct::MerkleAuditProof proof;
315 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 252 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
316 ASSERT_TRUE(callback.called()); 253 IsError(net::ERR_CONNECTION_REFUSED));
317 EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED));
318 EXPECT_THAT(callback.proof(), IsNull());
319 } 254 }
320 255
321 TEST_P(LogDnsClientTest, 256 TEST_P(LogDnsClientTest,
322 QueryAuditProofReportsTimeoutsDuringLeafIndexRequests) { 257 QueryAuditProofReportsTimeoutsDuringLeafIndexRequests) {
323 mock_dns_.ExpectRequestAndTimeout(kLeafIndexQnames[0]); 258 mock_dns_.ExpectRequestAndTimeout(kLeafIndexQnames[0]);
324 259
325 MockAuditProofCallback callback; 260 net::ct::MerkleAuditProof proof;
326 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 261 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
327 ASSERT_TRUE(callback.called()); 262 IsError(net::ERR_DNS_TIMED_OUT));
328 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT));
329 EXPECT_THAT(callback.proof(), IsNull());
330 } 263 }
331 264
332 TEST_P(LogDnsClientTest, QueryAuditProof) { 265 TEST_P(LogDnsClientTest, QueryAuditProof) {
333 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); 266 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
334 267
335 // Expect a leaf index query first, to map the leaf hash to a leaf index. 268 // Expect a leaf index query first, to map the leaf hash to a leaf index.
336 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 269 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
337 270
338 // It takes a number of DNS requests to retrieve the entire |audit_proof| 271 // It takes a number of DNS requests to retrieve the entire |audit_proof|
339 // (see |kMaxProofNodesPerDnsResponse|). 272 // (see |kMaxProofNodesPerDnsResponse|).
340 for (size_t nodes_begin = 0; nodes_begin < audit_proof.size(); 273 for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
341 nodes_begin += kMaxProofNodesPerDnsResponse) { 274 nodes_begin += kMaxProofNodesPerDnsResponse) {
342 const size_t nodes_end = std::min( 275 const size_t nodes_end = std::min(
343 nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size()); 276 nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
344 277
345 mock_dns_.ExpectAuditProofRequestAndResponse( 278 mock_dns_.ExpectAuditProofRequestAndResponse(
346 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin), 279 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
347 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end); 280 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end);
348 } 281 }
349 282
350 MockAuditProofCallback callback; 283 net::ct::MerkleAuditProof proof;
351 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 284 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
352 ASSERT_TRUE(callback.called()); 285 IsOk());
353 EXPECT_THAT(callback.net_error(), IsOk()); 286 EXPECT_THAT(proof.leaf_index, Eq(123456u));
354 ASSERT_THAT(callback.proof(), NotNull());
355 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
356 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 287 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
357 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999)); 288 // EXPECT_THAT(proof.tree_size, Eq(999999));
358 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof)); 289 EXPECT_THAT(proof.nodes, Eq(audit_proof));
359 } 290 }
360 291
361 TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) { 292 TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) {
362 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); 293 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
363 294
364 // Expect a leaf index query first, to map the leaf hash to a leaf index. 295 // Expect a leaf index query first, to map the leaf hash to a leaf index.
365 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 296 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
366 297
367 // Make some of the responses contain fewer proof nodes than they can hold. 298 // Make some of the responses contain fewer proof nodes than they can hold.
368 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", 299 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.",
369 audit_proof.begin(), 300 audit_proof.begin(),
370 audit_proof.begin() + 1); 301 audit_proof.begin() + 1);
371 mock_dns_.ExpectAuditProofRequestAndResponse("1.123456.999999.tree.ct.test.", 302 mock_dns_.ExpectAuditProofRequestAndResponse("1.123456.999999.tree.ct.test.",
372 audit_proof.begin() + 1, 303 audit_proof.begin() + 1,
373 audit_proof.begin() + 3); 304 audit_proof.begin() + 3);
374 mock_dns_.ExpectAuditProofRequestAndResponse("3.123456.999999.tree.ct.test.", 305 mock_dns_.ExpectAuditProofRequestAndResponse("3.123456.999999.tree.ct.test.",
375 audit_proof.begin() + 3, 306 audit_proof.begin() + 3,
376 audit_proof.begin() + 6); 307 audit_proof.begin() + 6);
377 mock_dns_.ExpectAuditProofRequestAndResponse("6.123456.999999.tree.ct.test.", 308 mock_dns_.ExpectAuditProofRequestAndResponse("6.123456.999999.tree.ct.test.",
378 audit_proof.begin() + 6, 309 audit_proof.begin() + 6,
379 audit_proof.begin() + 10); 310 audit_proof.begin() + 10);
380 mock_dns_.ExpectAuditProofRequestAndResponse("10.123456.999999.tree.ct.test.", 311 mock_dns_.ExpectAuditProofRequestAndResponse("10.123456.999999.tree.ct.test.",
381 audit_proof.begin() + 10, 312 audit_proof.begin() + 10,
382 audit_proof.begin() + 13); 313 audit_proof.begin() + 13);
383 mock_dns_.ExpectAuditProofRequestAndResponse("13.123456.999999.tree.ct.test.", 314 mock_dns_.ExpectAuditProofRequestAndResponse("13.123456.999999.tree.ct.test.",
384 audit_proof.begin() + 13, 315 audit_proof.begin() + 13,
385 audit_proof.end()); 316 audit_proof.end());
386 317
387 MockAuditProofCallback callback; 318 net::ct::MerkleAuditProof proof;
388 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 319 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
389 ASSERT_TRUE(callback.called()); 320 IsOk());
390 EXPECT_THAT(callback.net_error(), IsOk()); 321 EXPECT_THAT(proof.leaf_index, Eq(123456u));
391 ASSERT_THAT(callback.proof(), NotNull());
392 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
393 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 322 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
394 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999)); 323 // EXPECT_THAT(proof.tree_size, Eq(999999));
395 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof)); 324 EXPECT_THAT(proof.nodes, Eq(audit_proof));
396 } 325 }
397 326
398 TEST_P(LogDnsClientTest, 327 TEST_P(LogDnsClientTest,
399 QueryAuditProofReportsThatAuditProofQnameDoesNotExist) { 328 QueryAuditProofReportsThatAuditProofQnameDoesNotExist) {
400 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 329 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
401 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", 330 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
402 net::dns_protocol::kRcodeNXDOMAIN); 331 net::dns_protocol::kRcodeNXDOMAIN);
403 332
404 MockAuditProofCallback callback; 333 net::ct::MerkleAuditProof proof;
405 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 334 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
406 ASSERT_TRUE(callback.called()); 335 IsError(net::ERR_NAME_NOT_RESOLVED));
407 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED));
408 EXPECT_THAT(callback.proof(), IsNull());
409 } 336 }
410 337
411 TEST_P(LogDnsClientTest, 338 TEST_P(LogDnsClientTest,
412 QueryAuditProofReportsServerFailureDuringAuditProofRequests) { 339 QueryAuditProofReportsServerFailuresDuringAuditProofRequests) {
413 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 340 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
414 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", 341 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
415 net::dns_protocol::kRcodeSERVFAIL); 342 net::dns_protocol::kRcodeSERVFAIL);
416 343
417 MockAuditProofCallback callback; 344 net::ct::MerkleAuditProof proof;
418 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 345 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
419 ASSERT_TRUE(callback.called()); 346 IsError(net::ERR_DNS_SERVER_FAILED));
420 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
421 EXPECT_THAT(callback.proof(), IsNull());
422 } 347 }
423 348
424 TEST_P(LogDnsClientTest, 349 TEST_P(LogDnsClientTest,
425 QueryAuditProofReportsServerRefusalDuringAuditProofRequests) { 350 QueryAuditProofReportsServerRefusalsDuringAuditProofRequests) {
426 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 351 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
427 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", 352 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
428 net::dns_protocol::kRcodeREFUSED); 353 net::dns_protocol::kRcodeREFUSED);
429 354
430 MockAuditProofCallback callback; 355 net::ct::MerkleAuditProof proof;
431 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 356 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
432 ASSERT_TRUE(callback.called()); 357 IsError(net::ERR_DNS_SERVER_FAILED));
433 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
434 EXPECT_THAT(callback.proof(), IsNull());
435 } 358 }
436 359
437 TEST_P(LogDnsClientTest, 360 TEST_P(
438 QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsNoStri ngs) { 361 LogDnsClientTest,
362 QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsNoStrings ) {
439 // Expect a leaf index query first, to map the leaf hash to a leaf index. 363 // Expect a leaf index query first, to map the leaf hash to a leaf index.
440 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 364 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
441 365
442 mock_dns_.ExpectRequestAndResponse("0.123456.999999.tree.ct.test.", 366 mock_dns_.ExpectRequestAndResponse("0.123456.999999.tree.ct.test.",
443 std::vector<base::StringPiece>()); 367 std::vector<base::StringPiece>());
444 368
445 MockAuditProofCallback callback; 369 net::ct::MerkleAuditProof proof;
446 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 370 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
447 ASSERT_TRUE(callback.called()); 371 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
448 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
449 EXPECT_THAT(callback.proof(), IsNull());
450 } 372 }
451 373
452 TEST_P(LogDnsClientTest, 374 TEST_P(
453 QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsMoreTh anOneString) { 375 LogDnsClientTest,
376 QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsMoreThanO neString) {
454 // The CT-over-DNS draft RFC states that the response will contain "exactly 377 // The CT-over-DNS draft RFC states that the response will contain "exactly
455 // one character-string." 378 // one character-string."
456 const std::vector<std::string> audit_proof = GetSampleAuditProof(10); 379 const std::vector<std::string> audit_proof = GetSampleAuditProof(10);
457 380
458 std::string first_chunk_of_proof = std::accumulate( 381 std::string first_chunk_of_proof = std::accumulate(
459 audit_proof.begin(), audit_proof.begin() + 7, std::string()); 382 audit_proof.begin(), audit_proof.begin() + 7, std::string());
460 std::string second_chunk_of_proof = std::accumulate( 383 std::string second_chunk_of_proof = std::accumulate(
461 audit_proof.begin() + 7, audit_proof.end(), std::string()); 384 audit_proof.begin() + 7, audit_proof.end(), std::string());
462 385
463 // Expect a leaf index query first, to map the leaf hash to a leaf index. 386 // Expect a leaf index query first, to map the leaf hash to a leaf index.
464 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 387 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
465 388
466 mock_dns_.ExpectRequestAndResponse( 389 mock_dns_.ExpectRequestAndResponse(
467 "0.123456.999999.tree.ct.test.", 390 "0.123456.999999.tree.ct.test.",
468 {first_chunk_of_proof, second_chunk_of_proof}); 391 {first_chunk_of_proof, second_chunk_of_proof});
469 392
470 MockAuditProofCallback callback; 393 net::ct::MerkleAuditProof proof;
471 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 394 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
472 ASSERT_TRUE(callback.called()); 395 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
473 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
474 EXPECT_THAT(callback.proof(), IsNull());
475 } 396 }
476 397
477 TEST_P(LogDnsClientTest, 398 TEST_P(LogDnsClientTest,
478 QueryAuditProofReportsResponseMalformedIfNodeTooShort) { 399 QueryAuditProofReportsResponseMalformedIfNodeTooShort) {
479 // node is shorter than a SHA-256 hash (31 vs 32 bytes) 400 // node is shorter than a SHA-256 hash (31 vs 32 bytes)
480 const std::vector<std::string> audit_proof(1, std::string(31, 'a')); 401 const std::vector<std::string> audit_proof(1, std::string(31, 'a'));
481 402
482 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 403 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
483 mock_dns_.ExpectAuditProofRequestAndResponse( 404 mock_dns_.ExpectAuditProofRequestAndResponse(
484 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()); 405 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
485 406
486 MockAuditProofCallback callback; 407 net::ct::MerkleAuditProof proof;
487 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 408 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
488 ASSERT_TRUE(callback.called()); 409 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
489 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
490 EXPECT_THAT(callback.proof(), IsNull());
491 } 410 }
492 411
493 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfNodeTooLong) { 412 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfNodeTooLong) {
494 // node is longer than a SHA-256 hash (33 vs 32 bytes) 413 // node is longer than a SHA-256 hash (33 vs 32 bytes)
495 const std::vector<std::string> audit_proof(1, std::string(33, 'a')); 414 const std::vector<std::string> audit_proof(1, std::string(33, 'a'));
496 415
497 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 416 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
498 mock_dns_.ExpectAuditProofRequestAndResponse( 417 mock_dns_.ExpectAuditProofRequestAndResponse(
499 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()); 418 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
500 419
501 MockAuditProofCallback callback; 420 net::ct::MerkleAuditProof proof;
502 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 421 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
503 ASSERT_TRUE(callback.called()); 422 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
504 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
505 EXPECT_THAT(callback.proof(), IsNull());
506 } 423 }
507 424
508 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfEmpty) { 425 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfEmpty) {
509 const std::vector<std::string> audit_proof; 426 const std::vector<std::string> audit_proof;
510 427
511 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 428 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
512 mock_dns_.ExpectAuditProofRequestAndResponse( 429 mock_dns_.ExpectAuditProofRequestAndResponse(
513 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()); 430 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
514 431
515 MockAuditProofCallback callback; 432 net::ct::MerkleAuditProof proof;
516 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 433 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
517 ASSERT_TRUE(callback.called()); 434 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
518 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
519 EXPECT_THAT(callback.proof(), IsNull());
520 } 435 }
521 436
522 TEST_P(LogDnsClientTest, 437 TEST_P(LogDnsClientTest,
523 QueryAuditProofReportsInvalidArgIfLeafIndexEqualToTreeSize) { 438 QueryAuditProofReportsInvalidArgIfLeafIndexEqualToTreeSize) {
524 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 439 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
525 440
526 MockAuditProofCallback callback; 441 net::ct::MerkleAuditProof proof;
527 QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback); 442 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 123456, &proof),
528 ASSERT_TRUE(callback.called()); 443 IsError(net::ERR_INVALID_ARGUMENT));
529 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
530 EXPECT_THAT(callback.proof(), IsNull());
531 } 444 }
532 445
533 TEST_P(LogDnsClientTest, 446 TEST_P(LogDnsClientTest,
534 QueryAuditProofReportsInvalidArgIfLeafIndexGreaterThanTreeSize) { 447 QueryAuditProofReportsInvalidArgIfLeafIndexGreaterThanTreeSize) {
535 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 999999); 448 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 999999);
536 449
537 MockAuditProofCallback callback; 450 net::ct::MerkleAuditProof proof;
538 QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback); 451 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 123456, &proof),
539 ASSERT_TRUE(callback.called()); 452 IsError(net::ERR_INVALID_ARGUMENT));
540 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
541 EXPECT_THAT(callback.proof(), IsNull());
542 } 453 }
543 454
544 TEST_P(LogDnsClientTest, 455 TEST_P(LogDnsClientTest,
545 QueryAuditProofReportsSocketErrorsDuringAuditProofRequests) { 456 QueryAuditProofReportsSocketErrorsDuringAuditProofRequests) {
546 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 457 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
547 mock_dns_.ExpectRequestAndSocketError("0.123456.999999.tree.ct.test.", 458 mock_dns_.ExpectRequestAndSocketError("0.123456.999999.tree.ct.test.",
548 net::ERR_CONNECTION_REFUSED); 459 net::ERR_CONNECTION_REFUSED);
549 460
550 MockAuditProofCallback callback; 461 net::ct::MerkleAuditProof proof;
551 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 462 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
552 ASSERT_TRUE(callback.called()); 463 IsError(net::ERR_CONNECTION_REFUSED));
553 EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED));
554 EXPECT_THAT(callback.proof(), IsNull());
555 } 464 }
556 465
557 TEST_P(LogDnsClientTest, 466 TEST_P(LogDnsClientTest,
558 QueryAuditProofReportsTimeoutsDuringAuditProofRequests) { 467 QueryAuditProofReportsTimeoutsDuringAuditProofRequests) {
559 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 468 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
560 mock_dns_.ExpectRequestAndTimeout("0.123456.999999.tree.ct.test."); 469 mock_dns_.ExpectRequestAndTimeout("0.123456.999999.tree.ct.test.");
561 470
562 MockAuditProofCallback callback; 471 net::ct::MerkleAuditProof proof;
563 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 472 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
564 ASSERT_TRUE(callback.called()); 473 IsError(net::ERR_DNS_TIMED_OUT));
565 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT));
566 EXPECT_THAT(callback.proof(), IsNull());
567 } 474 }
568 475
569 TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) { 476 TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) {
570 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient(); 477 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient();
571 net::DnsClient* dns_client = tmp.get(); 478 net::DnsClient* dns_client = tmp.get();
572 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0); 479 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0);
573 480
574 // Get the current DNS config, modify it and broadcast the update. 481 // Get the current DNS config, modify it and broadcast the update.
575 net::DnsConfig config(*dns_client->GetConfig()); 482 net::DnsConfig config(*dns_client->GetConfig());
576 ASSERT_NE(123, config.attempts); 483 ASSERT_NE(123, config.attempts);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 mock_dns_.ExpectAuditProofRequestAndResponse( 523 mock_dns_.ExpectAuditProofRequestAndResponse(
617 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin), 524 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
618 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end); 525 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end);
619 } 526 }
620 527
621 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient(); 528 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient();
622 net::DnsClient* dns_client = tmp.get(); 529 net::DnsClient* dns_client = tmp.get();
623 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0); 530 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0);
624 531
625 // Start query. 532 // Start query.
626 MockAuditProofCallback callback; 533 net::ct::MerkleAuditProof proof;
627 QueryAuditProofAsync(&log_client, "ct.test", kLeafHashes[0], 999999, 534 net::TestCompletionCallback callback;
628 callback.AsCallback()); 535 ASSERT_THAT(log_client.QueryAuditProof("ct.test", kLeafHashes[0], 999999,
536 &proof, callback.callback()),
537 IsError(net::ERR_IO_PENDING));
629 538
630 // Get the current DNS config, modify it and broadcast the update. 539 // Get the current DNS config, modify it and publish the update.
540 // The new config is distributed asynchronously via NetworkChangeNotifier.
631 net::DnsConfig config(*dns_client->GetConfig()); 541 net::DnsConfig config(*dns_client->GetConfig());
632 ASSERT_NE(123, config.attempts); 542 ASSERT_NE(123, config.attempts);
633 config.attempts = 123; 543 config.attempts = 123;
634 mock_dns_.SetDnsConfig(config); 544 mock_dns_.SetDnsConfig(config);
545 // The new config is distributed asynchronously via NetworkChangeNotifier.
546 // Config change shouldn't have taken effect yet.
547 ASSERT_NE(123, dns_client->GetConfig()->attempts);
635 548
636 callback.WaitUntilRun(); 549 // Wait for the query to complete, then check that it was successful.
637 // Check that the DNS changes propogated before the query completed. 550 // The DNS config should be updated during this time.
638 EXPECT_EQ(123, dns_client->GetConfig()->attempts); 551 ASSERT_THAT(callback.WaitForResult(), IsOk());
552 EXPECT_THAT(proof.leaf_index, Eq(123456u));
553 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
554 // EXPECT_THAT(proof.tree_size, Eq(999999));
555 EXPECT_THAT(proof.nodes, Eq(audit_proof));
639 556
640 ASSERT_TRUE(callback.called()); 557 // Check that the DNS config change was adopted.
641 EXPECT_THAT(callback.net_error(), IsOk()); 558 ASSERT_EQ(123, dns_client->GetConfig()->attempts);
642 ASSERT_THAT(callback.proof(), NotNull());
643 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
644 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
645 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999));
646 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof));
647 } 559 }
648 560
649 TEST_P(LogDnsClientTest, CanPerformQueriesInParallel) { 561 TEST_P(LogDnsClientTest, CanPerformQueriesInParallel) {
650 // Check that 3 queries can be performed in parallel. 562 // Check that 3 queries can be performed in parallel.
651 constexpr size_t kNumOfParallelQueries = 3; 563 constexpr size_t kNumOfParallelQueries = 3;
652 ASSERT_THAT(kNumOfParallelQueries, 564 ASSERT_THAT(kNumOfParallelQueries,
653 AllOf(Le(arraysize(kLeafIndexQnames)), 565 AllOf(Le(arraysize(kLeafIndexQnames)),
654 Le(arraysize(kLeafIndices)), Le(arraysize(kTreeSizes)))) 566 Le(arraysize(kLeafIndices)), Le(arraysize(kTreeSizes))))
655 << "Not enough test data for this many parallel queries"; 567 << "Not enough test data for this many parallel queries";
656 568
657 std::unique_ptr<LogDnsClient> log_client = 569 std::unique_ptr<LogDnsClient> log_client =
658 CreateLogDnsClient(kNumOfParallelQueries); 570 CreateLogDnsClient(kNumOfParallelQueries);
659 MockAuditProofCallback callbacks[kNumOfParallelQueries]; 571 net::TestCompletionCallback callbacks[kNumOfParallelQueries];
660 572
661 // Expect multiple leaf index requests. 573 // Expect multiple leaf index requests.
662 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 574 for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
663 mock_dns_.ExpectLeafIndexRequestAndResponse( 575 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[i],
664 kLeafIndexQnames[i], kLeafIndices[i]); 576 kLeafIndices[i]);
665 } 577 }
666 578
667 // Make each query require one more audit proof request than the last, by 579 // Make each query require one more audit proof request than the last, by
668 // increasing the number of nodes in the audit proof by 580 // increasing the number of nodes in the audit proof by
669 // kMaxProofNodesPerDnsResponse for each query. This helps to test that 581 // kMaxProofNodesPerDnsResponse for each query. This helps to test that
670 // parallel queries do not intefere with each other, e.g. one query causing 582 // parallel queries do not intefere with each other, e.g. one query causing
671 // another to end prematurely. 583 // another to end prematurely.
672 std::vector<std::string> audit_proofs[kNumOfParallelQueries]; 584 std::vector<std::string> audit_proofs[kNumOfParallelQueries];
673 for (size_t query_i = 0; query_i < kNumOfParallelQueries; ++query_i) { 585 for (size_t query_i = 0; query_i < kNumOfParallelQueries; ++query_i) {
674 const size_t dns_requests_required = query_i + 1; 586 const size_t dns_requests_required = query_i + 1;
(...skipping 22 matching lines...) Expand all
697 if (start_node < end_node) { 609 if (start_node < end_node) {
698 mock_dns_.ExpectAuditProofRequestAndResponse( 610 mock_dns_.ExpectAuditProofRequestAndResponse(
699 base::StringPrintf("%zu.%" PRIu64 ".%" PRIu64 ".tree.ct.test.", 611 base::StringPrintf("%zu.%" PRIu64 ".%" PRIu64 ".tree.ct.test.",
700 start_node, kLeafIndices[query_i], 612 start_node, kLeafIndices[query_i],
701 kTreeSizes[query_i]), 613 kTreeSizes[query_i]),
702 proof.begin() + start_node, proof.begin() + end_node); 614 proof.begin() + start_node, proof.begin() + end_node);
703 } 615 }
704 } 616 }
705 } 617 }
706 618
619 net::ct::MerkleAuditProof proofs[kNumOfParallelQueries];
620
707 // Start the queries. 621 // Start the queries.
708 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 622 for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
709 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[i], 623 ASSERT_THAT(
710 kTreeSizes[i], callbacks[i].AsCallback()); 624 log_client->QueryAuditProof("ct.test", kLeafHashes[i], kTreeSizes[i],
625 &proofs[i], callbacks[i].callback()),
626 IsError(net::ERR_IO_PENDING))
627 << "query #" << i;
711 } 628 }
712 629
713 // Wait for each query to complete and check its results. 630 // Wait for each query to complete and check its results.
714 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 631 for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
715 MockAuditProofCallback& callback = callbacks[i]; 632 net::TestCompletionCallback& callback = callbacks[i];
716 callbacks[i].WaitUntilRun();
717 633
718 SCOPED_TRACE(testing::Message() << "callbacks[" << i << "]"); 634 SCOPED_TRACE(testing::Message() << "callbacks[" << i << "]");
719 ASSERT_TRUE(callback.called()); 635 EXPECT_THAT(callback.WaitForResult(), IsOk());
720 EXPECT_THAT(callback.net_error(), IsOk()); 636 EXPECT_THAT(proofs[i].leaf_index, Eq(kLeafIndices[i]));
721 ASSERT_THAT(callback.proof(), NotNull());
722 EXPECT_THAT(callback.proof()->leaf_index, Eq(kLeafIndices[i]));
723 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 637 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
724 // EXPECT_THAT(callback.proof()->tree_size, kTreeSizes[i]); 638 // EXPECT_THAT(proofs[i].tree_size, kTreeSizes[i]);
725 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proofs[i])); 639 EXPECT_THAT(proofs[i].nodes, Eq(audit_proofs[i]));
726 } 640 }
727 } 641 }
728 642
729 TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) { 643 TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) {
730 // Check that queries can be rate-limited to one at a time. 644 // Check that queries can be rate-limited to one at a time.
731 // The second query, initiated while the first is in progress, should fail. 645 // The second query, initiated while the first is in progress, should fail.
732 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); 646 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
733 647
734 // Expect the first query to send leaf index and audit proof requests, but the 648 // Expect the first query to send leaf index and audit proof requests, but the
735 // second should not due to throttling. 649 // second should not due to throttling.
(...skipping 10 matching lines...) Expand all
746 audit_proof.begin() + 7, 660 audit_proof.begin() + 7,
747 audit_proof.begin() + 14); 661 audit_proof.begin() + 14);
748 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.", 662 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.",
749 audit_proof.begin() + 14, 663 audit_proof.begin() + 14,
750 audit_proof.end()); 664 audit_proof.end());
751 665
752 const size_t kMaxConcurrentQueries = 1; 666 const size_t kMaxConcurrentQueries = 1;
753 std::unique_ptr<LogDnsClient> log_client = 667 std::unique_ptr<LogDnsClient> log_client =
754 CreateLogDnsClient(kMaxConcurrentQueries); 668 CreateLogDnsClient(kMaxConcurrentQueries);
755 669
756 // Start the queries. 670 // Try to start the queries.
757 MockAuditProofCallback callback1; 671 net::ct::MerkleAuditProof proof1;
758 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[0], 999999, 672 net::TestCompletionCallback callback1;
759 callback1.AsCallback()); 673 ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0], 999999,
760 MockAuditProofCallback callback2; 674 &proof1, callback1.callback()),
761 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[1], 999999, 675 IsError(net::ERR_IO_PENDING));
762 callback2.AsCallback());
763 676
764 callback1.WaitUntilRun(); 677 net::ct::MerkleAuditProof proof2;
765 callback2.WaitUntilRun(); 678 net::TestCompletionCallback callback2;
679 ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[1], 999999,
680 &proof2, callback2.callback()),
681 IsError(net::ERR_TEMPORARILY_THROTTLED));
766 682
767 // Check that the first query succeeded. 683 // Check that the first query succeeded.
768 ASSERT_TRUE(callback1.called()); 684 EXPECT_THAT(callback1.WaitForResult(), IsOk());
769 EXPECT_THAT(callback1.net_error(), IsOk()); 685 EXPECT_THAT(proof1.leaf_index, Eq(123456u));
770 ASSERT_THAT(callback1.proof(), NotNull());
771 EXPECT_THAT(callback1.proof()->leaf_index, Eq(123456u));
772 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 686 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
773 // EXPECT_THAT(callback1.proof()->tree_size, Eq(999999)); 687 // EXPECT_THAT(proof1.tree_size, Eq(999999));
774 EXPECT_THAT(callback1.proof()->nodes, Eq(audit_proof)); 688 EXPECT_THAT(proof1.nodes, Eq(audit_proof));
775
776 // Check that the second query failed.
777 ASSERT_TRUE(callback2.called());
778 EXPECT_THAT(callback2.net_error(), IsError(net::ERR_TEMPORARILY_THROTTLED));
779 EXPECT_THAT(callback2.proof(), IsNull());
780 689
781 // Try a third query, which should succeed now that the first is finished. 690 // Try a third query, which should succeed now that the first is finished.
782 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[2], 666); 691 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[2], 666);
783 mock_dns_.ExpectAuditProofRequestAndResponse("0.666.999999.tree.ct.test.", 692 mock_dns_.ExpectAuditProofRequestAndResponse("0.666.999999.tree.ct.test.",
784 audit_proof.begin(), 693 audit_proof.begin(),
785 audit_proof.begin() + 7); 694 audit_proof.begin() + 7);
786 mock_dns_.ExpectAuditProofRequestAndResponse("7.666.999999.tree.ct.test.", 695 mock_dns_.ExpectAuditProofRequestAndResponse("7.666.999999.tree.ct.test.",
787 audit_proof.begin() + 7, 696 audit_proof.begin() + 7,
788 audit_proof.begin() + 14); 697 audit_proof.begin() + 14);
789 mock_dns_.ExpectAuditProofRequestAndResponse("14.666.999999.tree.ct.test.", 698 mock_dns_.ExpectAuditProofRequestAndResponse("14.666.999999.tree.ct.test.",
790 audit_proof.begin() + 14, 699 audit_proof.begin() + 14,
791 audit_proof.end()); 700 audit_proof.end());
792 701
793 MockAuditProofCallback callback3; 702 net::ct::MerkleAuditProof proof3;
794 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[2], 999999, 703 net::TestCompletionCallback callback3;
795 callback3.AsCallback()); 704 ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[2], 999999,
796 705 &proof3, callback3.callback()),
797 callback3.WaitUntilRun(); 706 IsError(net::ERR_IO_PENDING));
798 707
799 // Check that the third query succeeded. 708 // Check that the third query succeeded.
800 ASSERT_TRUE(callback3.called()); 709 EXPECT_THAT(callback3.WaitForResult(), IsOk());
801 EXPECT_THAT(callback3.net_error(), IsOk()); 710 EXPECT_THAT(proof3.leaf_index, Eq(666u));
802 ASSERT_THAT(callback3.proof(), NotNull());
803 EXPECT_THAT(callback3.proof()->leaf_index, Eq(666u));
804 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 711 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
805 // EXPECT_THAT(callback3.proof()->tree_size, Eq(999999)); 712 // EXPECT_THAT(proof3.tree_size, Eq(999999));
806 EXPECT_THAT(callback3.proof()->nodes, Eq(audit_proof)); 713 EXPECT_THAT(proof3.nodes, Eq(audit_proof));
807 } 714 }
808 715
809 INSTANTIATE_TEST_CASE_P(ReadMode, 716 INSTANTIATE_TEST_CASE_P(ReadMode,
810 LogDnsClientTest, 717 LogDnsClientTest,
811 ::testing::Values(net::IoMode::ASYNC, 718 ::testing::Values(net::IoMode::ASYNC,
812 net::IoMode::SYNCHRONOUS)); 719 net::IoMode::SYNCHRONOUS));
813 720
814 } // namespace certificate_transparency 721 } // 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