Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / net / quic / crypto / quic_crypto_server_config_test.cc
blobfbf25f0947d51ca46b0a4b66669a43af999355bd
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/quic/crypto/quic_crypto_server_config.h"
7 #include <stdarg.h>
9 #include "base/stl_util.h"
10 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
11 #include "net/quic/crypto/crypto_handshake_message.h"
12 #include "net/quic/crypto/crypto_server_config_protobuf.h"
13 #include "net/quic/crypto/quic_random.h"
14 #include "net/quic/crypto/strike_register_client.h"
15 #include "net/quic/quic_time.h"
16 #include "net/quic/test_tools/mock_clock.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using base::StringPiece;
21 using std::make_pair;
22 using std::map;
23 using std::pair;
24 using std::string;
25 using std::vector;
27 namespace net {
28 namespace test {
30 class QuicCryptoServerConfigPeer {
31 public:
32 explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config)
33 : server_config_(server_config) {}
35 string NewSourceAddressToken(IPEndPoint ip,
36 QuicRandom* rand,
37 QuicWallTime now) {
38 return server_config_->NewSourceAddressToken(ip, rand, now);
41 bool ValidateSourceAddressToken(StringPiece srct,
42 IPEndPoint ip,
43 QuicWallTime now) {
44 return server_config_->ValidateSourceAddressToken(srct, ip, now);
47 base::Lock* GetStrikeRegisterClientLock() {
48 return &server_config_->strike_register_client_lock_;
51 // CheckConfigs compares the state of the Configs in |server_config_| to the
52 // description given as arguments. The arguments are given as NULL-terminated
53 // pairs. The first of each pair is the server config ID of a Config. The
54 // second is a boolean describing whether the config is the primary. For
55 // example:
56 // CheckConfigs(NULL); // checks that no Configs are loaded.
58 // // Checks that exactly three Configs are loaded with the given IDs and
59 // // status.
60 // CheckConfigs(
61 // "id1", false,
62 // "id2", true,
63 // "id3", false,
64 // NULL);
65 void CheckConfigs(const char* server_config_id1, ...) {
66 va_list ap;
67 va_start(ap, server_config_id1);
69 vector<pair<ServerConfigID, bool> > expected;
70 bool first = true;
71 for (;;) {
72 const char* server_config_id;
73 if (first) {
74 server_config_id = server_config_id1;
75 first = false;
76 } else {
77 server_config_id = va_arg(ap, const char*);
80 if (!server_config_id) {
81 break;
84 // varargs will promote the value to an int so we have to read that from
85 // the stack and cast down.
86 const bool is_primary = static_cast<bool>(va_arg(ap, int));
87 expected.push_back(make_pair(server_config_id, is_primary));
90 va_end(ap);
92 base::AutoLock locked(server_config_->configs_lock_);
94 ASSERT_EQ(expected.size(), server_config_->configs_.size())
95 << ConfigsDebug();
97 for (QuicCryptoServerConfig::ConfigMap::const_iterator
98 i = server_config_->configs_.begin();
99 i != server_config_->configs_.end(); ++i) {
100 bool found = false;
101 for (vector<pair<ServerConfigID, bool> >::iterator j = expected.begin();
102 j != expected.end(); ++j) {
103 if (i->first == j->first && i->second->is_primary == j->second) {
104 found = true;
105 j->first.clear();
106 break;
110 ASSERT_TRUE(found) << "Failed to find match for " << i->first
111 << " in configs:\n" << ConfigsDebug();
115 // ConfigsDebug returns a string that contains debugging information about
116 // the set of Configs loaded in |server_config_| and their status.
117 // ConfigsDebug() should be called after acquiring
118 // server_config_->configs_lock_.
119 string ConfigsDebug() {
120 if (server_config_->configs_.empty()) {
121 return "No Configs in QuicCryptoServerConfig";
124 string s;
126 for (QuicCryptoServerConfig::ConfigMap::const_iterator
127 i = server_config_->configs_.begin();
128 i != server_config_->configs_.end(); ++i) {
129 const scoped_refptr<QuicCryptoServerConfig::Config> config = i->second;
130 if (config->is_primary) {
131 s += "(primary) ";
132 } else {
133 s += " ";
135 s += config->id;
136 s += "\n";
139 return s;
142 void SelectNewPrimaryConfig(int seconds) {
143 base::AutoLock locked(server_config_->configs_lock_);
144 server_config_->SelectNewPrimaryConfig(
145 QuicWallTime::FromUNIXSeconds(seconds));
148 private:
149 const QuicCryptoServerConfig* server_config_;
152 class TestStrikeRegisterClient : public StrikeRegisterClient {
153 public:
154 explicit TestStrikeRegisterClient(QuicCryptoServerConfig* config)
155 : config_(config),
156 is_known_orbit_called_(false) {
159 virtual bool IsKnownOrbit(StringPiece orbit) const OVERRIDE {
160 // Ensure that the strike register client lock is not held.
161 QuicCryptoServerConfigPeer peer(config_);
162 base::Lock* m = peer.GetStrikeRegisterClientLock();
163 // In Chromium, we will dead lock if the lock is held by the current thread.
164 // Chromium doesn't have AssertNotHeld API call.
165 // m->AssertNotHeld();
166 base::AutoLock lock(*m);
168 is_known_orbit_called_ = true;
169 return true;
172 virtual void VerifyNonceIsValidAndUnique(
173 StringPiece nonce,
174 QuicWallTime now,
175 ResultCallback* cb) OVERRIDE {
176 LOG(FATAL) << "Not implemented";
179 bool is_known_orbit_called() { return is_known_orbit_called_; }
181 private:
182 QuicCryptoServerConfig* config_;
183 mutable bool is_known_orbit_called_;
186 TEST(QuicCryptoServerConfigTest, ServerConfig) {
187 QuicRandom* rand = QuicRandom::GetInstance();
188 QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
189 MockClock clock;
191 scoped_ptr<CryptoHandshakeMessage>(
192 server.AddDefaultConfig(rand, &clock,
193 QuicCryptoServerConfig::ConfigOptions()));
196 TEST(QuicCryptoServerConfigTest, GetOrbitIsCalledWithoutTheStrikeRegisterLock) {
197 QuicRandom* rand = QuicRandom::GetInstance();
198 QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
199 MockClock clock;
201 TestStrikeRegisterClient* strike_register =
202 new TestStrikeRegisterClient(&server);
203 server.SetStrikeRegisterClient(strike_register);
205 QuicCryptoServerConfig::ConfigOptions options;
206 scoped_ptr<CryptoHandshakeMessage>(
207 server.AddDefaultConfig(rand, &clock, options));
208 EXPECT_TRUE(strike_register->is_known_orbit_called());
211 TEST(QuicCryptoServerConfigTest, SourceAddressTokens) {
212 QuicRandom* rand = QuicRandom::GetInstance();
213 QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
214 IPAddressNumber ip;
215 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
216 IPEndPoint ip4 = IPEndPoint(ip, 1);
217 CHECK(ParseIPLiteralToNumber("2001:db8:0::42", &ip));
218 IPEndPoint ip6 = IPEndPoint(ip, 2);
219 MockClock clock;
220 clock.AdvanceTime(QuicTime::Delta::FromSeconds(1000000));
221 QuicCryptoServerConfigPeer peer(&server);
223 QuicWallTime now = clock.WallNow();
224 const QuicWallTime original_time = now;
226 const string token4 = peer.NewSourceAddressToken(ip4, rand, now);
227 const string token6 = peer.NewSourceAddressToken(ip6, rand, now);
228 EXPECT_TRUE(peer.ValidateSourceAddressToken(token4, ip4, now));
229 EXPECT_FALSE(peer.ValidateSourceAddressToken(token4, ip6, now));
230 EXPECT_TRUE(peer.ValidateSourceAddressToken(token6, ip6, now));
232 now = original_time.Add(QuicTime::Delta::FromSeconds(86400 * 7));
233 EXPECT_FALSE(peer.ValidateSourceAddressToken(token4, ip4, now));
235 now = original_time.Subtract(QuicTime::Delta::FromSeconds(3600 * 2));
236 EXPECT_FALSE(peer.ValidateSourceAddressToken(token4, ip4, now));
239 class CryptoServerConfigsTest : public ::testing::Test {
240 public:
241 CryptoServerConfigsTest()
242 : rand_(QuicRandom::GetInstance()),
243 config_(QuicCryptoServerConfig::TESTING, rand_),
244 test_peer_(&config_) {}
246 virtual void SetUp() {
247 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000));
250 // SetConfigs constructs suitable config protobufs and calls SetConfigs on
251 // |config_|. The arguments are given as NULL-terminated pairs. The first of
252 // each pair is the server config ID of a Config. The second is the
253 // |primary_time| of that Config, given in epoch seconds. (Although note
254 // that, in these tests, time is set to 1000 seconds since the epoch.) For
255 // example:
256 // SetConfigs(NULL); // calls |config_.SetConfigs| with no protobufs.
258 // // Calls |config_.SetConfigs| with two protobufs: one for a Config with
259 // // a |primary_time| of 900 and priority 1, and another with
260 // // a |primary_time| of 1000 and priority 2.
262 // CheckConfigs(
263 // "id1", 900, 1,
264 // "id2", 1000, 2,
265 // NULL);
267 // If the server config id starts with "INVALID" then the generated protobuf
268 // will be invalid.
269 void SetConfigs(const char* server_config_id1, ...) {
270 const char kOrbit[] = "12345678";
272 va_list ap;
273 va_start(ap, server_config_id1);
274 bool has_invalid = false;
275 bool is_empty = true;
277 vector<QuicServerConfigProtobuf*> protobufs;
278 bool first = true;
279 for (;;) {
280 const char* server_config_id;
281 if (first) {
282 server_config_id = server_config_id1;
283 first = false;
284 } else {
285 server_config_id = va_arg(ap, const char*);
288 if (!server_config_id) {
289 break;
292 is_empty = false;
293 int primary_time = va_arg(ap, int);
294 int priority = va_arg(ap, int);
296 QuicCryptoServerConfig::ConfigOptions options;
297 options.id = server_config_id;
298 options.orbit = kOrbit;
299 QuicServerConfigProtobuf* protobuf(
300 QuicCryptoServerConfig::GenerateConfig(rand_, &clock_, options));
301 protobuf->set_primary_time(primary_time);
302 protobuf->set_priority(priority);
303 if (string(server_config_id).find("INVALID") == 0) {
304 protobuf->clear_key();
305 has_invalid = true;
307 protobufs.push_back(protobuf);
310 ASSERT_EQ(!has_invalid && !is_empty,
311 config_.SetConfigs(protobufs, clock_.WallNow()));
312 STLDeleteElements(&protobufs);
315 protected:
316 QuicRandom* const rand_;
317 MockClock clock_;
318 QuicCryptoServerConfig config_;
319 QuicCryptoServerConfigPeer test_peer_;
322 TEST_F(CryptoServerConfigsTest, NoConfigs) {
323 test_peer_.CheckConfigs(NULL);
326 TEST_F(CryptoServerConfigsTest, MakePrimaryFirst) {
327 // Make sure that "b" is primary even though "a" comes first.
328 SetConfigs("a", 1100, 1,
329 "b", 900, 1,
330 NULL);
331 test_peer_.CheckConfigs(
332 "a", false,
333 "b", true,
334 NULL);
337 TEST_F(CryptoServerConfigsTest, MakePrimarySecond) {
338 // Make sure that a remains primary after b is added.
339 SetConfigs("a", 900, 1,
340 "b", 1100, 1,
341 NULL);
342 test_peer_.CheckConfigs(
343 "a", true,
344 "b", false,
345 NULL);
348 TEST_F(CryptoServerConfigsTest, Delete) {
349 // Ensure that configs get deleted when removed.
350 SetConfigs("a", 800, 1,
351 "b", 900, 1,
352 "c", 1100, 1,
353 NULL);
354 test_peer_.CheckConfigs(
355 "a", false,
356 "b", true,
357 "c", false,
358 NULL);
359 SetConfigs("b", 900, 1,
360 "c", 1100, 1,
361 NULL);
362 test_peer_.CheckConfigs(
363 "b", true,
364 "c", false,
365 NULL);
368 TEST_F(CryptoServerConfigsTest, DeletePrimary) {
369 // Ensure that deleting the primary config works.
370 SetConfigs("a", 800, 1,
371 "b", 900, 1,
372 "c", 1100, 1,
373 NULL);
374 test_peer_.CheckConfigs(
375 "a", false,
376 "b", true,
377 "c", false,
378 NULL);
379 SetConfigs("a", 800, 1,
380 "c", 1100, 1,
381 NULL);
382 test_peer_.CheckConfigs(
383 "a", true,
384 "c", false,
385 NULL);
388 TEST_F(CryptoServerConfigsTest, FailIfDeletingAllConfigs) {
389 // Ensure that configs get deleted when removed.
390 SetConfigs("a", 800, 1,
391 "b", 900, 1,
392 NULL);
393 test_peer_.CheckConfigs(
394 "a", false,
395 "b", true,
396 NULL);
397 SetConfigs(NULL);
398 // Config change is rejected, still using old configs.
399 test_peer_.CheckConfigs(
400 "a", false,
401 "b", true,
402 NULL);
405 TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) {
406 // Check that updates to primary time get picked up.
407 SetConfigs("a", 400, 1,
408 "b", 800, 1,
409 "c", 1200, 1,
410 NULL);
411 test_peer_.SelectNewPrimaryConfig(500);
412 test_peer_.CheckConfigs(
413 "a", true,
414 "b", false,
415 "c", false,
416 NULL);
417 SetConfigs("a", 1200, 1,
418 "b", 800, 1,
419 "c", 400, 1,
420 NULL);
421 test_peer_.SelectNewPrimaryConfig(500);
422 test_peer_.CheckConfigs(
423 "a", false,
424 "b", false,
425 "c", true,
426 NULL);
429 TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) {
430 // Check that the most recent config is selected.
431 SetConfigs("a", 400, 1,
432 "b", 800, 1,
433 "c", 1200, 1,
434 NULL);
435 test_peer_.SelectNewPrimaryConfig(1500);
436 test_peer_.CheckConfigs(
437 "a", false,
438 "b", false,
439 "c", true,
440 NULL);
443 TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) {
444 // Check that the first config is selected.
445 SetConfigs("a", 400, 1,
446 "b", 800, 1,
447 "c", 1200, 1,
448 NULL);
449 test_peer_.SelectNewPrimaryConfig(100);
450 test_peer_.CheckConfigs(
451 "a", true,
452 "b", false,
453 "c", false,
454 NULL);
457 TEST_F(CryptoServerConfigsTest, SortByPriority) {
458 // Check that priority is used to decide on a primary config when
459 // configs have the same primary time.
460 SetConfigs("a", 900, 1,
461 "b", 900, 2,
462 "c", 900, 3,
463 NULL);
464 test_peer_.CheckConfigs(
465 "a", true,
466 "b", false,
467 "c", false,
468 NULL);
469 test_peer_.SelectNewPrimaryConfig(800);
470 test_peer_.CheckConfigs(
471 "a", true,
472 "b", false,
473 "c", false,
474 NULL);
475 test_peer_.SelectNewPrimaryConfig(1000);
476 test_peer_.CheckConfigs(
477 "a", true,
478 "b", false,
479 "c", false,
480 NULL);
482 // Change priorities and expect sort order to change.
483 SetConfigs("a", 900, 2,
484 "b", 900, 1,
485 "c", 900, 0,
486 NULL);
487 test_peer_.CheckConfigs(
488 "a", false,
489 "b", false,
490 "c", true,
491 NULL);
492 test_peer_.SelectNewPrimaryConfig(800);
493 test_peer_.CheckConfigs(
494 "a", false,
495 "b", false,
496 "c", true,
497 NULL);
498 test_peer_.SelectNewPrimaryConfig(1000);
499 test_peer_.CheckConfigs(
500 "a", false,
501 "b", false,
502 "c", true,
503 NULL);
506 TEST_F(CryptoServerConfigsTest, AdvancePrimary) {
507 // Check that a new primary config is enabled at the right time.
508 SetConfigs("a", 900, 1,
509 "b", 1100, 1,
510 NULL);
511 test_peer_.SelectNewPrimaryConfig(1000);
512 test_peer_.CheckConfigs(
513 "a", true,
514 "b", false,
515 NULL);
516 test_peer_.SelectNewPrimaryConfig(1101);
517 test_peer_.CheckConfigs(
518 "a", false,
519 "b", true,
520 NULL);
523 TEST_F(CryptoServerConfigsTest, InvalidConfigs) {
524 // Ensure that invalid configs don't change anything.
525 SetConfigs("a", 800, 1,
526 "b", 900, 1,
527 "c", 1100, 1,
528 NULL);
529 test_peer_.CheckConfigs(
530 "a", false,
531 "b", true,
532 "c", false,
533 NULL);
534 SetConfigs("a", 800, 1,
535 "c", 1100, 1,
536 "INVALID1", 1000, 1,
537 NULL);
538 test_peer_.CheckConfigs(
539 "a", false,
540 "b", true,
541 "c", false,
542 NULL);
545 } // namespace test
546 } // namespace net