Home | History | Annotate | Download | only in crypto
      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.
      4 
      5 #include "net/quic/crypto/quic_crypto_server_config.h"
      6 
      7 #include <stdarg.h>
      8 
      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_secret_boxer.h"
     13 #include "net/quic/crypto/crypto_server_config_protobuf.h"
     14 #include "net/quic/crypto/quic_random.h"
     15 #include "net/quic/crypto/strike_register_client.h"
     16 #include "net/quic/quic_time.h"
     17 #include "net/quic/test_tools/mock_clock.h"
     18 #include "net/quic/test_tools/quic_test_utils.h"
     19 #include "testing/gmock/include/gmock/gmock.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 
     22 using base::StringPiece;
     23 using std::make_pair;
     24 using std::map;
     25 using std::pair;
     26 using std::string;
     27 using std::vector;
     28 
     29 namespace net {
     30 namespace test {
     31 
     32 class QuicCryptoServerConfigPeer {
     33  public:
     34   explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config)
     35       : server_config_(server_config) {}
     36 
     37   scoped_refptr<QuicCryptoServerConfig::Config> GetConfig(string config_id) {
     38     base::AutoLock locked(server_config_->configs_lock_);
     39     if (config_id == "<primary>") {
     40       return scoped_refptr<QuicCryptoServerConfig::Config>(
     41           server_config_->primary_config_);
     42     } else {
     43       return server_config_->GetConfigWithScid(config_id);
     44     }
     45   }
     46 
     47   bool ConfigHasDefaultSourceAddressTokenBoxer(string config_id) {
     48     scoped_refptr<QuicCryptoServerConfig::Config> config = GetConfig(config_id);
     49     return config->source_address_token_boxer ==
     50         &(server_config_->default_source_address_token_boxer_);
     51   }
     52 
     53   string NewSourceAddressToken(
     54       string config_id,
     55       IPEndPoint ip,
     56       QuicRandom* rand,
     57       QuicWallTime now) {
     58     return server_config_->NewSourceAddressToken(
     59         *GetConfig(config_id), ip, rand, now, NULL);
     60   }
     61 
     62   HandshakeFailureReason ValidateSourceAddressToken(string config_id,
     63                                                     StringPiece srct,
     64                                                     IPEndPoint ip,
     65                                                     QuicWallTime now) {
     66     return server_config_->ValidateSourceAddressToken(
     67         *GetConfig(config_id), srct, ip, now);
     68   }
     69 
     70   string NewServerNonce(QuicRandom* rand, QuicWallTime now) const {
     71     return server_config_->NewServerNonce(rand, now);
     72   }
     73 
     74   HandshakeFailureReason ValidateServerNonce(StringPiece token,
     75                                              QuicWallTime now) {
     76     return server_config_->ValidateServerNonce(token, now);
     77   }
     78 
     79   base::Lock* GetStrikeRegisterClientLock() {
     80     return &server_config_->strike_register_client_lock_;
     81   }
     82 
     83   // CheckConfigs compares the state of the Configs in |server_config_| to the
     84   // description given as arguments. The arguments are given as NULL-terminated
     85   // pairs. The first of each pair is the server config ID of a Config. The
     86   // second is a boolean describing whether the config is the primary. For
     87   // example:
     88   //   CheckConfigs(NULL);  // checks that no Configs are loaded.
     89   //
     90   //   // Checks that exactly three Configs are loaded with the given IDs and
     91   //   // status.
     92   //   CheckConfigs(
     93   //     "id1", false,
     94   //     "id2", true,
     95   //     "id3", false,
     96   //     NULL);
     97   void CheckConfigs(const char* server_config_id1, ...) {
     98     va_list ap;
     99     va_start(ap, server_config_id1);
    100 
    101     vector<pair<ServerConfigID, bool> > expected;
    102     bool first = true;
    103     for (;;) {
    104       const char* server_config_id;
    105       if (first) {
    106         server_config_id = server_config_id1;
    107         first = false;
    108       } else {
    109         server_config_id = va_arg(ap, const char*);
    110       }
    111 
    112       if (!server_config_id) {
    113         break;
    114       }
    115 
    116       // varargs will promote the value to an int so we have to read that from
    117       // the stack and cast down.
    118       const bool is_primary = static_cast<bool>(va_arg(ap, int));
    119       expected.push_back(make_pair(server_config_id, is_primary));
    120     }
    121 
    122     va_end(ap);
    123 
    124     base::AutoLock locked(server_config_->configs_lock_);
    125 
    126     ASSERT_EQ(expected.size(), server_config_->configs_.size())
    127         << ConfigsDebug();
    128 
    129     for (QuicCryptoServerConfig::ConfigMap::const_iterator
    130              i = server_config_->configs_.begin();
    131          i != server_config_->configs_.end(); ++i) {
    132       bool found = false;
    133       for (vector<pair<ServerConfigID, bool> >::iterator j = expected.begin();
    134            j != expected.end(); ++j) {
    135         if (i->first == j->first && i->second->is_primary == j->second) {
    136           found = true;
    137           j->first.clear();
    138           break;
    139         }
    140       }
    141 
    142       ASSERT_TRUE(found) << "Failed to find match for " << i->first
    143                          << " in configs:\n" << ConfigsDebug();
    144     }
    145   }
    146 
    147   // ConfigsDebug returns a string that contains debugging information about
    148   // the set of Configs loaded in |server_config_| and their status.
    149   // ConfigsDebug() should be called after acquiring
    150   // server_config_->configs_lock_.
    151   string ConfigsDebug() {
    152     if (server_config_->configs_.empty()) {
    153       return "No Configs in QuicCryptoServerConfig";
    154     }
    155 
    156     string s;
    157 
    158     for (QuicCryptoServerConfig::ConfigMap::const_iterator
    159              i = server_config_->configs_.begin();
    160          i != server_config_->configs_.end(); ++i) {
    161       const scoped_refptr<QuicCryptoServerConfig::Config> config = i->second;
    162       if (config->is_primary) {
    163         s += "(primary) ";
    164       } else {
    165         s += "          ";
    166       }
    167       s += config->id;
    168       s += "\n";
    169     }
    170 
    171     return s;
    172   }
    173 
    174   void SelectNewPrimaryConfig(int seconds) {
    175     base::AutoLock locked(server_config_->configs_lock_);
    176     server_config_->SelectNewPrimaryConfig(
    177         QuicWallTime::FromUNIXSeconds(seconds));
    178   }
    179 
    180  private:
    181   const QuicCryptoServerConfig* server_config_;
    182 };
    183 
    184 class TestStrikeRegisterClient : public StrikeRegisterClient {
    185  public:
    186   explicit TestStrikeRegisterClient(QuicCryptoServerConfig* config)
    187       : config_(config),
    188         is_known_orbit_called_(false) {
    189   }
    190 
    191   virtual bool IsKnownOrbit(StringPiece orbit) const OVERRIDE {
    192     // Ensure that the strike register client lock is not held.
    193     QuicCryptoServerConfigPeer peer(config_);
    194     base::Lock* m = peer.GetStrikeRegisterClientLock();
    195     // In Chromium, we will dead lock if the lock is held by the current thread.
    196     // Chromium doesn't have AssertNotHeld API call.
    197     // m->AssertNotHeld();
    198     base::AutoLock lock(*m);
    199 
    200     is_known_orbit_called_ = true;
    201     return true;
    202   }
    203 
    204   virtual void VerifyNonceIsValidAndUnique(
    205       StringPiece nonce,
    206       QuicWallTime now,
    207       ResultCallback* cb) OVERRIDE {
    208     LOG(FATAL) << "Not implemented";
    209   }
    210 
    211   bool is_known_orbit_called() { return is_known_orbit_called_; }
    212 
    213  private:
    214   QuicCryptoServerConfig* config_;
    215   mutable bool is_known_orbit_called_;
    216 };
    217 
    218 TEST(QuicCryptoServerConfigTest, ServerConfig) {
    219   QuicRandom* rand = QuicRandom::GetInstance();
    220   QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
    221   MockClock clock;
    222 
    223   scoped_ptr<CryptoHandshakeMessage>(
    224       server.AddDefaultConfig(rand, &clock,
    225                               QuicCryptoServerConfig::ConfigOptions()));
    226 }
    227 
    228 TEST(QuicCryptoServerConfigTest, GetOrbitIsCalledWithoutTheStrikeRegisterLock) {
    229   QuicRandom* rand = QuicRandom::GetInstance();
    230   QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
    231   MockClock clock;
    232 
    233   TestStrikeRegisterClient* strike_register =
    234       new TestStrikeRegisterClient(&server);
    235   server.SetStrikeRegisterClient(strike_register);
    236 
    237   QuicCryptoServerConfig::ConfigOptions options;
    238   scoped_ptr<CryptoHandshakeMessage>(
    239       server.AddDefaultConfig(rand, &clock, options));
    240   EXPECT_TRUE(strike_register->is_known_orbit_called());
    241 }
    242 
    243 TEST(QuicCryptoServerConfigTest, SourceAddressTokens) {
    244   const string kPrimary = "<primary>";
    245   const string kOverride = "Config with custom source address token key";
    246 
    247   MockClock clock;
    248   clock.AdvanceTime(QuicTime::Delta::FromSeconds(1000000));
    249 
    250   QuicWallTime now = clock.WallNow();
    251   const QuicWallTime original_time = now;
    252 
    253   QuicRandom* rand = QuicRandom::GetInstance();
    254   QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
    255   QuicCryptoServerConfigPeer peer(&server);
    256 
    257   scoped_ptr<CryptoHandshakeMessage>(
    258       server.AddDefaultConfig(rand, &clock,
    259                               QuicCryptoServerConfig::ConfigOptions()));
    260 
    261   // Add a config that overrides the default boxer.
    262   QuicCryptoServerConfig::ConfigOptions options;
    263   options.id = kOverride;
    264   scoped_ptr<QuicServerConfigProtobuf> protobuf(
    265       QuicCryptoServerConfig::GenerateConfig(rand, &clock, options));
    266   protobuf->set_source_address_token_secret_override("a secret key");
    267   // Lower priority than the default config.
    268   protobuf->set_priority(1);
    269   scoped_ptr<CryptoHandshakeMessage>(
    270       server.AddConfig(protobuf.get(), now));
    271 
    272   EXPECT_TRUE(peer.ConfigHasDefaultSourceAddressTokenBoxer(kPrimary));
    273   EXPECT_FALSE(peer.ConfigHasDefaultSourceAddressTokenBoxer(kOverride));
    274 
    275   IPEndPoint ip4 = IPEndPoint(Loopback4(), 1);
    276   IPEndPoint ip4d = IPEndPoint(ConvertIPv4NumberToIPv6Number(ip4.address()), 1);
    277   IPEndPoint ip6 = IPEndPoint(Loopback6(), 2);
    278 
    279   // Primary config generates configs that validate successfully.
    280   const string token4 = peer.NewSourceAddressToken(kPrimary, ip4, rand, now);
    281   const string token4d = peer.NewSourceAddressToken(kPrimary, ip4d, rand, now);
    282   const string token6 = peer.NewSourceAddressToken(kPrimary, ip6, rand, now);
    283   EXPECT_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
    284       kPrimary, token4, ip4, now));
    285   DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
    286       kPrimary, token4, ip4d, now));
    287   DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
    288             peer.ValidateSourceAddressToken(kPrimary, token4, ip6, now));
    289   DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
    290       kPrimary, token4d, ip4, now));
    291   DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
    292       kPrimary, token4d, ip4d, now));
    293   DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
    294             peer.ValidateSourceAddressToken(kPrimary, token4d, ip6, now));
    295   DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
    296       kPrimary, token6, ip6, now));
    297 
    298   // Override config generates configs that validate successfully.
    299   const string override_token4 = peer.NewSourceAddressToken(
    300       kOverride, ip4, rand, now);
    301   const string override_token6 = peer.NewSourceAddressToken(
    302       kOverride, ip6, rand, now);
    303   DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
    304       kOverride, override_token4, ip4, now));
    305   DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
    306             peer.ValidateSourceAddressToken(kOverride, override_token4, ip6,
    307                                             now));
    308   DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
    309       kOverride, override_token6, ip6, now));
    310 
    311   // Tokens generated by the primary config do not validate
    312   // successfully against the override config, and vice versa.
    313   DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
    314             peer.ValidateSourceAddressToken(kOverride, token4, ip4, now));
    315   DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
    316             peer.ValidateSourceAddressToken(kOverride, token6, ip6, now));
    317   DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
    318             peer.ValidateSourceAddressToken(kPrimary, override_token4, ip4,
    319                                             now));
    320   DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
    321             peer.ValidateSourceAddressToken(kPrimary, override_token6, ip6,
    322                                             now));
    323 
    324   // Validation fails after tokens expire.
    325   now = original_time.Add(QuicTime::Delta::FromSeconds(86400 * 7));
    326   DCHECK_EQ(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE,
    327             peer.ValidateSourceAddressToken(kPrimary, token4, ip4, now));
    328 
    329   now = original_time.Subtract(QuicTime::Delta::FromSeconds(3600 * 2));
    330   DCHECK_EQ(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE,
    331             peer.ValidateSourceAddressToken(kPrimary, token4, ip4, now));
    332 }
    333 
    334 TEST(QuicCryptoServerConfigTest, ValidateServerNonce) {
    335   QuicRandom* rand = QuicRandom::GetInstance();
    336   QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
    337   QuicCryptoServerConfigPeer peer(&server);
    338 
    339   StringPiece message("hello world");
    340   const size_t key_size = CryptoSecretBoxer::GetKeySize();
    341   scoped_ptr<uint8[]> key(new uint8[key_size]);
    342   memset(key.get(), 0x11, key_size);
    343 
    344   CryptoSecretBoxer boxer;
    345   boxer.SetKey(StringPiece(reinterpret_cast<char*>(key.get()), key_size));
    346   const string box = boxer.Box(rand, message);
    347   MockClock clock;
    348   QuicWallTime now = clock.WallNow();
    349   const QuicWallTime original_time = now;
    350   EXPECT_EQ(SERVER_NONCE_DECRYPTION_FAILURE,
    351             peer.ValidateServerNonce(box, now));
    352 
    353   string server_nonce = peer.NewServerNonce(rand, now);
    354   EXPECT_EQ(HANDSHAKE_OK, peer.ValidateServerNonce(server_nonce, now));
    355   EXPECT_EQ(SERVER_NONCE_NOT_UNIQUE_FAILURE,
    356             peer.ValidateServerNonce(server_nonce, now));
    357 
    358   now = original_time.Add(QuicTime::Delta::FromSeconds(1000 * 7));
    359   server_nonce = peer.NewServerNonce(rand, now);
    360   EXPECT_EQ(HANDSHAKE_OK, peer.ValidateServerNonce(server_nonce, now));
    361 }
    362 
    363 class CryptoServerConfigsTest : public ::testing::Test {
    364  public:
    365   CryptoServerConfigsTest()
    366       : rand_(QuicRandom::GetInstance()),
    367         config_(QuicCryptoServerConfig::TESTING, rand_),
    368         test_peer_(&config_) {}
    369 
    370   virtual void SetUp() {
    371     clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000));
    372   }
    373 
    374   // SetConfigs constructs suitable config protobufs and calls SetConfigs on
    375   // |config_|. The arguments are given as NULL-terminated pairs. The first of
    376   // each pair is the server config ID of a Config. The second is the
    377   // |primary_time| of that Config, given in epoch seconds. (Although note
    378   // that, in these tests, time is set to 1000 seconds since the epoch.) For
    379   // example:
    380   //   SetConfigs(NULL);  // calls |config_.SetConfigs| with no protobufs.
    381   //
    382   //   // Calls |config_.SetConfigs| with two protobufs: one for a Config with
    383   //   // a |primary_time| of 900 and priority 1, and another with
    384   //   // a |primary_time| of 1000 and priority 2.
    385 
    386   //   CheckConfigs(
    387   //     "id1", 900, 1,
    388   //     "id2", 1000, 2,
    389   //     NULL);
    390   //
    391   // If the server config id starts with "INVALID" then the generated protobuf
    392   // will be invalid.
    393   void SetConfigs(const char* server_config_id1, ...) {
    394     const char kOrbit[] = "12345678";
    395 
    396     va_list ap;
    397     va_start(ap, server_config_id1);
    398     bool has_invalid = false;
    399     bool is_empty = true;
    400 
    401     vector<QuicServerConfigProtobuf*> protobufs;
    402     bool first = true;
    403     for (;;) {
    404       const char* server_config_id;
    405       if (first) {
    406         server_config_id = server_config_id1;
    407         first = false;
    408       } else {
    409         server_config_id = va_arg(ap, const char*);
    410       }
    411 
    412       if (!server_config_id) {
    413         break;
    414       }
    415 
    416       is_empty = false;
    417       int primary_time = va_arg(ap, int);
    418       int priority = va_arg(ap, int);
    419 
    420       QuicCryptoServerConfig::ConfigOptions options;
    421       options.id = server_config_id;
    422       options.orbit = kOrbit;
    423       QuicServerConfigProtobuf* protobuf(
    424           QuicCryptoServerConfig::GenerateConfig(rand_, &clock_, options));
    425       protobuf->set_primary_time(primary_time);
    426       protobuf->set_priority(priority);
    427       if (string(server_config_id).find("INVALID") == 0) {
    428         protobuf->clear_key();
    429         has_invalid = true;
    430       }
    431       protobufs.push_back(protobuf);
    432     }
    433 
    434     ASSERT_EQ(!has_invalid && !is_empty,
    435               config_.SetConfigs(protobufs, clock_.WallNow()));
    436     STLDeleteElements(&protobufs);
    437   }
    438 
    439  protected:
    440   QuicRandom* const rand_;
    441   MockClock clock_;
    442   QuicCryptoServerConfig config_;
    443   QuicCryptoServerConfigPeer test_peer_;
    444 };
    445 
    446 TEST_F(CryptoServerConfigsTest, NoConfigs) {
    447   test_peer_.CheckConfigs(NULL);
    448 }
    449 
    450 TEST_F(CryptoServerConfigsTest, MakePrimaryFirst) {
    451   // Make sure that "b" is primary even though "a" comes first.
    452   SetConfigs("a", 1100, 1,
    453              "b", 900, 1,
    454              NULL);
    455   test_peer_.CheckConfigs(
    456       "a", false,
    457       "b", true,
    458       NULL);
    459 }
    460 
    461 TEST_F(CryptoServerConfigsTest, MakePrimarySecond) {
    462   // Make sure that a remains primary after b is added.
    463   SetConfigs("a", 900, 1,
    464              "b", 1100, 1,
    465              NULL);
    466   test_peer_.CheckConfigs(
    467       "a", true,
    468       "b", false,
    469       NULL);
    470 }
    471 
    472 TEST_F(CryptoServerConfigsTest, Delete) {
    473   // Ensure that configs get deleted when removed.
    474   SetConfigs("a", 800, 1,
    475              "b", 900, 1,
    476              "c", 1100, 1,
    477              NULL);
    478   test_peer_.CheckConfigs(
    479       "a", false,
    480       "b", true,
    481       "c", false,
    482       NULL);
    483   SetConfigs("b", 900, 1,
    484              "c", 1100, 1,
    485              NULL);
    486   test_peer_.CheckConfigs(
    487       "b", true,
    488       "c", false,
    489       NULL);
    490 }
    491 
    492 TEST_F(CryptoServerConfigsTest, DeletePrimary) {
    493   // Ensure that deleting the primary config works.
    494   SetConfigs("a", 800, 1,
    495              "b", 900, 1,
    496              "c", 1100, 1,
    497              NULL);
    498   test_peer_.CheckConfigs(
    499       "a", false,
    500       "b", true,
    501       "c", false,
    502       NULL);
    503   SetConfigs("a", 800, 1,
    504              "c", 1100, 1,
    505              NULL);
    506   test_peer_.CheckConfigs(
    507       "a", true,
    508       "c", false,
    509       NULL);
    510 }
    511 
    512 TEST_F(CryptoServerConfigsTest, FailIfDeletingAllConfigs) {
    513   // Ensure that configs get deleted when removed.
    514   SetConfigs("a", 800, 1,
    515              "b", 900, 1,
    516              NULL);
    517   test_peer_.CheckConfigs(
    518       "a", false,
    519       "b", true,
    520       NULL);
    521   SetConfigs(NULL);
    522   // Config change is rejected, still using old configs.
    523   test_peer_.CheckConfigs(
    524       "a", false,
    525       "b", true,
    526       NULL);
    527 }
    528 
    529 TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) {
    530   // Check that updates to primary time get picked up.
    531   SetConfigs("a", 400, 1,
    532              "b", 800, 1,
    533              "c", 1200, 1,
    534              NULL);
    535   test_peer_.SelectNewPrimaryConfig(500);
    536   test_peer_.CheckConfigs(
    537       "a", true,
    538       "b", false,
    539       "c", false,
    540       NULL);
    541   SetConfigs("a", 1200, 1,
    542              "b", 800, 1,
    543              "c", 400, 1,
    544              NULL);
    545   test_peer_.SelectNewPrimaryConfig(500);
    546   test_peer_.CheckConfigs(
    547       "a", false,
    548       "b", false,
    549       "c", true,
    550       NULL);
    551 }
    552 
    553 TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) {
    554   // Check that the most recent config is selected.
    555   SetConfigs("a", 400, 1,
    556              "b", 800, 1,
    557              "c", 1200, 1,
    558              NULL);
    559   test_peer_.SelectNewPrimaryConfig(1500);
    560   test_peer_.CheckConfigs(
    561       "a", false,
    562       "b", false,
    563       "c", true,
    564       NULL);
    565 }
    566 
    567 TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) {
    568   // Check that the first config is selected.
    569   SetConfigs("a", 400, 1,
    570              "b", 800, 1,
    571              "c", 1200, 1,
    572              NULL);
    573   test_peer_.SelectNewPrimaryConfig(100);
    574   test_peer_.CheckConfigs(
    575       "a", true,
    576       "b", false,
    577       "c", false,
    578       NULL);
    579 }
    580 
    581 TEST_F(CryptoServerConfigsTest, SortByPriority) {
    582   // Check that priority is used to decide on a primary config when
    583   // configs have the same primary time.
    584   SetConfigs("a", 900, 1,
    585              "b", 900, 2,
    586              "c", 900, 3,
    587              NULL);
    588   test_peer_.CheckConfigs(
    589       "a", true,
    590       "b", false,
    591       "c", false,
    592       NULL);
    593   test_peer_.SelectNewPrimaryConfig(800);
    594   test_peer_.CheckConfigs(
    595       "a", true,
    596       "b", false,
    597       "c", false,
    598       NULL);
    599   test_peer_.SelectNewPrimaryConfig(1000);
    600   test_peer_.CheckConfigs(
    601       "a", true,
    602       "b", false,
    603       "c", false,
    604       NULL);
    605 
    606   // Change priorities and expect sort order to change.
    607   SetConfigs("a", 900, 2,
    608              "b", 900, 1,
    609              "c", 900, 0,
    610              NULL);
    611   test_peer_.CheckConfigs(
    612       "a", false,
    613       "b", false,
    614       "c", true,
    615       NULL);
    616   test_peer_.SelectNewPrimaryConfig(800);
    617   test_peer_.CheckConfigs(
    618       "a", false,
    619       "b", false,
    620       "c", true,
    621       NULL);
    622   test_peer_.SelectNewPrimaryConfig(1000);
    623   test_peer_.CheckConfigs(
    624       "a", false,
    625       "b", false,
    626       "c", true,
    627       NULL);
    628 }
    629 
    630 TEST_F(CryptoServerConfigsTest, AdvancePrimary) {
    631   // Check that a new primary config is enabled at the right time.
    632   SetConfigs("a", 900, 1,
    633              "b", 1100, 1,
    634              NULL);
    635   test_peer_.SelectNewPrimaryConfig(1000);
    636   test_peer_.CheckConfigs(
    637       "a", true,
    638       "b", false,
    639       NULL);
    640   test_peer_.SelectNewPrimaryConfig(1101);
    641   test_peer_.CheckConfigs(
    642       "a", false,
    643       "b", true,
    644       NULL);
    645 }
    646 
    647 TEST_F(CryptoServerConfigsTest, InvalidConfigs) {
    648   // Ensure that invalid configs don't change anything.
    649   SetConfigs("a", 800, 1,
    650              "b", 900, 1,
    651              "c", 1100, 1,
    652              NULL);
    653   test_peer_.CheckConfigs(
    654       "a", false,
    655       "b", true,
    656       "c", false,
    657       NULL);
    658   SetConfigs("a", 800, 1,
    659              "c", 1100, 1,
    660              "INVALID1", 1000, 1,
    661              NULL);
    662   test_peer_.CheckConfigs(
    663       "a", false,
    664       "b", true,
    665       "c", false,
    666       NULL);
    667 }
    668 
    669 }  // namespace test
    670 }  // namespace net
    671