| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |