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 <stdlib.h>
      8 #include <algorithm>
      9 
     10 #include "base/stl_util.h"
     11 #include "base/strings/string_number_conversions.h"
     12 #include "crypto/hkdf.h"
     13 #include "crypto/secure_hash.h"
     14 #include "net/base/net_util.h"
     15 #include "net/quic/crypto/aes_128_gcm_12_decrypter.h"
     16 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
     17 #include "net/quic/crypto/cert_compressor.h"
     18 #include "net/quic/crypto/chacha20_poly1305_encrypter.h"
     19 #include "net/quic/crypto/channel_id.h"
     20 #include "net/quic/crypto/crypto_framer.h"
     21 #include "net/quic/crypto/crypto_server_config_protobuf.h"
     22 #include "net/quic/crypto/crypto_utils.h"
     23 #include "net/quic/crypto/curve25519_key_exchange.h"
     24 #include "net/quic/crypto/ephemeral_key_source.h"
     25 #include "net/quic/crypto/key_exchange.h"
     26 #include "net/quic/crypto/local_strike_register_client.h"
     27 #include "net/quic/crypto/p256_key_exchange.h"
     28 #include "net/quic/crypto/proof_source.h"
     29 #include "net/quic/crypto/quic_decrypter.h"
     30 #include "net/quic/crypto/quic_encrypter.h"
     31 #include "net/quic/crypto/quic_random.h"
     32 #include "net/quic/crypto/source_address_token.h"
     33 #include "net/quic/crypto/strike_register.h"
     34 #include "net/quic/crypto/strike_register_client.h"
     35 #include "net/quic/quic_clock.h"
     36 #include "net/quic/quic_flags.h"
     37 #include "net/quic/quic_protocol.h"
     38 #include "net/quic/quic_socket_address_coder.h"
     39 #include "net/quic/quic_utils.h"
     40 
     41 using base::StringPiece;
     42 using crypto::SecureHash;
     43 using std::map;
     44 using std::sort;
     45 using std::string;
     46 using std::vector;
     47 
     48 namespace net {
     49 
     50 namespace {
     51 
     52 string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) {
     53   crypto::HKDF hkdf(source_address_token_secret,
     54                     StringPiece() /* no salt */,
     55                     "QUIC source address token key",
     56                     CryptoSecretBoxer::GetKeySize(),
     57                     0 /* no fixed IV needed */,
     58                     0 /* no subkey secret */);
     59   return hkdf.server_write_key().as_string();
     60 }
     61 
     62 }  // namespace
     63 
     64 // ClientHelloInfo contains information about a client hello message that is
     65 // only kept for as long as it's being processed.
     66 struct ClientHelloInfo {
     67   ClientHelloInfo(const IPEndPoint& in_client_ip, QuicWallTime in_now)
     68       : client_ip(in_client_ip),
     69         now(in_now),
     70         valid_source_address_token(false),
     71         client_nonce_well_formed(false),
     72         unique(false) {}
     73 
     74   // Inputs to EvaluateClientHello.
     75   const IPEndPoint client_ip;
     76   const QuicWallTime now;
     77 
     78   // Outputs from EvaluateClientHello.
     79   bool valid_source_address_token;
     80   bool client_nonce_well_formed;
     81   bool unique;
     82   StringPiece sni;
     83   StringPiece client_nonce;
     84   StringPiece server_nonce;
     85   StringPiece user_agent_id;
     86 
     87   // Errors from EvaluateClientHello.
     88   vector<uint32> reject_reasons;
     89   COMPILE_ASSERT(sizeof(QuicTag) == sizeof(uint32), header_out_of_sync);
     90 };
     91 
     92 struct ValidateClientHelloResultCallback::Result {
     93   Result(const CryptoHandshakeMessage& in_client_hello,
     94          IPEndPoint in_client_ip,
     95          QuicWallTime in_now)
     96       : client_hello(in_client_hello),
     97         info(in_client_ip, in_now),
     98         error_code(QUIC_NO_ERROR) {
     99   }
    100 
    101   CryptoHandshakeMessage client_hello;
    102   ClientHelloInfo info;
    103   QuicErrorCode error_code;
    104   string error_details;
    105 };
    106 
    107 class ValidateClientHelloHelper {
    108  public:
    109   ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result,
    110                             ValidateClientHelloResultCallback* done_cb)
    111       : result_(result), done_cb_(done_cb) {
    112   }
    113 
    114   ~ValidateClientHelloHelper() {
    115     LOG_IF(DFATAL, done_cb_ != NULL)
    116         << "Deleting ValidateClientHelloHelper with a pending callback.";
    117   }
    118 
    119   void ValidationComplete(QuicErrorCode error_code, const char* error_details) {
    120     result_->error_code = error_code;
    121     result_->error_details = error_details;
    122     done_cb_->Run(result_);
    123     DetachCallback();
    124   }
    125 
    126   void StartedAsyncCallback() {
    127     DetachCallback();
    128   }
    129 
    130  private:
    131   void DetachCallback() {
    132     LOG_IF(DFATAL, done_cb_ == NULL) << "Callback already detached.";
    133     done_cb_ = NULL;
    134   }
    135 
    136   ValidateClientHelloResultCallback::Result* result_;
    137   ValidateClientHelloResultCallback* done_cb_;
    138 
    139   DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper);
    140 };
    141 
    142 class VerifyNonceIsValidAndUniqueCallback
    143     : public StrikeRegisterClient::ResultCallback {
    144  public:
    145   VerifyNonceIsValidAndUniqueCallback(
    146       ValidateClientHelloResultCallback::Result* result,
    147       ValidateClientHelloResultCallback* done_cb)
    148       : result_(result), done_cb_(done_cb) {
    149   }
    150 
    151  protected:
    152   virtual void RunImpl(bool nonce_is_valid_and_unique,
    153                        InsertStatus nonce_error) OVERRIDE {
    154     DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique
    155              << " nonce_error: " << nonce_error;
    156     result_->info.unique = nonce_is_valid_and_unique;
    157     if (!nonce_is_valid_and_unique) {
    158       HandshakeFailureReason client_nonce_error;
    159       switch (nonce_error) {
    160         case NONCE_INVALID_FAILURE:
    161           client_nonce_error = CLIENT_NONCE_INVALID_FAILURE;
    162           break;
    163         case NONCE_NOT_UNIQUE_FAILURE:
    164           client_nonce_error = CLIENT_NONCE_NOT_UNIQUE_FAILURE;
    165           break;
    166         case NONCE_INVALID_ORBIT_FAILURE:
    167           client_nonce_error = CLIENT_NONCE_INVALID_ORBIT_FAILURE;
    168           break;
    169         case NONCE_INVALID_TIME_FAILURE:
    170           client_nonce_error = CLIENT_NONCE_INVALID_TIME_FAILURE;
    171           break;
    172         case STRIKE_REGISTER_TIMEOUT:
    173           client_nonce_error = CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT;
    174           break;
    175         case STRIKE_REGISTER_FAILURE:
    176           client_nonce_error = CLIENT_NONCE_STRIKE_REGISTER_FAILURE;
    177           break;
    178         case NONCE_UNKNOWN_FAILURE:
    179           client_nonce_error = CLIENT_NONCE_UNKNOWN_FAILURE;
    180           break;
    181         case NONCE_OK:
    182         default:
    183           LOG(DFATAL) << "Unexpected client nonce error: " << nonce_error;
    184           client_nonce_error = CLIENT_NONCE_UNKNOWN_FAILURE;
    185           break;
    186       }
    187       result_->info.reject_reasons.push_back(client_nonce_error);
    188     }
    189     done_cb_->Run(result_);
    190   }
    191 
    192  private:
    193   ValidateClientHelloResultCallback::Result* result_;
    194   ValidateClientHelloResultCallback* done_cb_;
    195 
    196   DISALLOW_COPY_AND_ASSIGN(VerifyNonceIsValidAndUniqueCallback);
    197 };
    198 
    199 // static
    200 const char QuicCryptoServerConfig::TESTING[] = "secret string for testing";
    201 
    202 PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() {
    203 }
    204 
    205 PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() {
    206 }
    207 
    208 ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() {
    209 }
    210 
    211 ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() {
    212 }
    213 
    214 void ValidateClientHelloResultCallback::Run(const Result* result) {
    215   RunImpl(result->client_hello, *result);
    216   delete result;
    217   delete this;
    218 }
    219 
    220 QuicCryptoServerConfig::ConfigOptions::ConfigOptions()
    221     : expiry_time(QuicWallTime::Zero()),
    222       channel_id_enabled(false),
    223       p256(false) {}
    224 
    225 QuicCryptoServerConfig::QuicCryptoServerConfig(
    226     StringPiece source_address_token_secret,
    227     QuicRandom* rand)
    228     : replay_protection_(true),
    229       configs_lock_(),
    230       primary_config_(NULL),
    231       next_config_promotion_time_(QuicWallTime::Zero()),
    232       server_nonce_strike_register_lock_(),
    233       strike_register_no_startup_period_(false),
    234       strike_register_max_entries_(1 << 10),
    235       strike_register_window_secs_(600),
    236       source_address_token_future_secs_(3600),
    237       source_address_token_lifetime_secs_(86400),
    238       server_nonce_strike_register_max_entries_(1 << 10),
    239       server_nonce_strike_register_window_secs_(120) {
    240   default_source_address_token_boxer_.SetKey(
    241       DeriveSourceAddressTokenKey(source_address_token_secret));
    242 
    243   // Generate a random key and orbit for server nonces.
    244   rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_));
    245   const size_t key_size = server_nonce_boxer_.GetKeySize();
    246   scoped_ptr<uint8[]> key_bytes(new uint8[key_size]);
    247   rand->RandBytes(key_bytes.get(), key_size);
    248 
    249   server_nonce_boxer_.SetKey(
    250       StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size));
    251 }
    252 
    253 QuicCryptoServerConfig::~QuicCryptoServerConfig() {
    254   primary_config_ = NULL;
    255 }
    256 
    257 // static
    258 QuicServerConfigProtobuf* QuicCryptoServerConfig::GenerateConfig(
    259     QuicRandom* rand,
    260     const QuicClock* clock,
    261     const ConfigOptions& options) {
    262   CryptoHandshakeMessage msg;
    263 
    264   const string curve25519_private_key =
    265       Curve25519KeyExchange::NewPrivateKey(rand);
    266   scoped_ptr<Curve25519KeyExchange> curve25519(
    267       Curve25519KeyExchange::New(curve25519_private_key));
    268   StringPiece curve25519_public_value = curve25519->public_value();
    269 
    270   string encoded_public_values;
    271   // First three bytes encode the length of the public value.
    272   encoded_public_values.push_back(curve25519_public_value.size());
    273   encoded_public_values.push_back(curve25519_public_value.size() >> 8);
    274   encoded_public_values.push_back(curve25519_public_value.size() >> 16);
    275   encoded_public_values.append(curve25519_public_value.data(),
    276                                curve25519_public_value.size());
    277 
    278   string p256_private_key;
    279   if (options.p256) {
    280     p256_private_key = P256KeyExchange::NewPrivateKey();
    281     scoped_ptr<P256KeyExchange> p256(P256KeyExchange::New(p256_private_key));
    282     StringPiece p256_public_value = p256->public_value();
    283 
    284     encoded_public_values.push_back(p256_public_value.size());
    285     encoded_public_values.push_back(p256_public_value.size() >> 8);
    286     encoded_public_values.push_back(p256_public_value.size() >> 16);
    287     encoded_public_values.append(p256_public_value.data(),
    288                                  p256_public_value.size());
    289   }
    290 
    291   msg.set_tag(kSCFG);
    292   if (options.p256) {
    293     msg.SetTaglist(kKEXS, kC255, kP256, 0);
    294   } else {
    295     msg.SetTaglist(kKEXS, kC255, 0);
    296   }
    297   if (ChaCha20Poly1305Encrypter::IsSupported()) {
    298     msg.SetTaglist(kAEAD, kAESG, kCC12, 0);
    299   } else {
    300     msg.SetTaglist(kAEAD, kAESG, 0);
    301   }
    302   msg.SetStringPiece(kPUBS, encoded_public_values);
    303 
    304   if (options.expiry_time.IsZero()) {
    305     const QuicWallTime now = clock->WallNow();
    306     const QuicWallTime expiry = now.Add(QuicTime::Delta::FromSeconds(
    307         60 * 60 * 24 * 180 /* 180 days, ~six months */));
    308     const uint64 expiry_seconds = expiry.ToUNIXSeconds();
    309     msg.SetValue(kEXPY, expiry_seconds);
    310   } else {
    311     msg.SetValue(kEXPY, options.expiry_time.ToUNIXSeconds());
    312   }
    313 
    314   char orbit_bytes[kOrbitSize];
    315   if (options.orbit.size() == sizeof(orbit_bytes)) {
    316     memcpy(orbit_bytes, options.orbit.data(), sizeof(orbit_bytes));
    317   } else {
    318     DCHECK(options.orbit.empty());
    319     rand->RandBytes(orbit_bytes, sizeof(orbit_bytes));
    320   }
    321   msg.SetStringPiece(kORBT, StringPiece(orbit_bytes, sizeof(orbit_bytes)));
    322 
    323   if (options.channel_id_enabled) {
    324     msg.SetTaglist(kPDMD, kCHID, 0);
    325   }
    326 
    327   if (options.id.empty()) {
    328     // We need to ensure that the SCID changes whenever the server config does
    329     // thus we make it a hash of the rest of the server config.
    330     scoped_ptr<QuicData> serialized(
    331         CryptoFramer::ConstructHandshakeMessage(msg));
    332     scoped_ptr<SecureHash> hash(SecureHash::Create(SecureHash::SHA256));
    333     hash->Update(serialized->data(), serialized->length());
    334 
    335     char scid_bytes[16];
    336     hash->Finish(scid_bytes, sizeof(scid_bytes));
    337     msg.SetStringPiece(kSCID, StringPiece(scid_bytes, sizeof(scid_bytes)));
    338   } else {
    339     msg.SetStringPiece(kSCID, options.id);
    340   }
    341   // Don't put new tags below this point. The SCID generation should hash over
    342   // everything but itself and so extra tags should be added prior to the
    343   // preceeding if block.
    344 
    345   scoped_ptr<QuicData> serialized(CryptoFramer::ConstructHandshakeMessage(msg));
    346 
    347   scoped_ptr<QuicServerConfigProtobuf> config(new QuicServerConfigProtobuf);
    348   config->set_config(serialized->AsStringPiece());
    349   QuicServerConfigProtobuf::PrivateKey* curve25519_key = config->add_key();
    350   curve25519_key->set_tag(kC255);
    351   curve25519_key->set_private_key(curve25519_private_key);
    352 
    353   if (options.p256) {
    354     QuicServerConfigProtobuf::PrivateKey* p256_key = config->add_key();
    355     p256_key->set_tag(kP256);
    356     p256_key->set_private_key(p256_private_key);
    357   }
    358 
    359   return config.release();
    360 }
    361 
    362 CryptoHandshakeMessage* QuicCryptoServerConfig::AddConfig(
    363     QuicServerConfigProtobuf* protobuf,
    364     const QuicWallTime now) {
    365   scoped_ptr<CryptoHandshakeMessage> msg(
    366       CryptoFramer::ParseMessage(protobuf->config()));
    367 
    368   if (!msg.get()) {
    369     LOG(WARNING) << "Failed to parse server config message";
    370     return NULL;
    371   }
    372 
    373   scoped_refptr<Config> config(ParseConfigProtobuf(protobuf));
    374   if (!config.get()) {
    375     LOG(WARNING) << "Failed to parse server config message";
    376     return NULL;
    377   }
    378 
    379   {
    380     base::AutoLock locked(configs_lock_);
    381     if (configs_.find(config->id) != configs_.end()) {
    382       LOG(WARNING) << "Failed to add config because another with the same "
    383                       "server config id already exists: "
    384                    << base::HexEncode(config->id.data(), config->id.size());
    385       return NULL;
    386     }
    387 
    388     configs_[config->id] = config;
    389     SelectNewPrimaryConfig(now);
    390     DCHECK(primary_config_.get());
    391     DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_);
    392   }
    393 
    394   return msg.release();
    395 }
    396 
    397 CryptoHandshakeMessage* QuicCryptoServerConfig::AddDefaultConfig(
    398     QuicRandom* rand,
    399     const QuicClock* clock,
    400     const ConfigOptions& options) {
    401   scoped_ptr<QuicServerConfigProtobuf> config(
    402       GenerateConfig(rand, clock, options));
    403   return AddConfig(config.get(), clock->WallNow());
    404 }
    405 
    406 bool QuicCryptoServerConfig::SetConfigs(
    407     const vector<QuicServerConfigProtobuf*>& protobufs,
    408     const QuicWallTime now) {
    409   vector<scoped_refptr<Config> > parsed_configs;
    410   bool ok = true;
    411 
    412   for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin();
    413        i != protobufs.end(); ++i) {
    414     scoped_refptr<Config> config(ParseConfigProtobuf(*i));
    415     if (!config.get()) {
    416       ok = false;
    417       break;
    418     }
    419 
    420     parsed_configs.push_back(config);
    421   }
    422 
    423   if (parsed_configs.empty()) {
    424     LOG(WARNING) << "New config list is empty.";
    425     ok = false;
    426   }
    427 
    428   if (!ok) {
    429     LOG(WARNING) << "Rejecting QUIC configs because of above errors";
    430   } else {
    431     VLOG(1) << "Updating configs:";
    432 
    433     base::AutoLock locked(configs_lock_);
    434     ConfigMap new_configs;
    435 
    436     for (vector<scoped_refptr<Config> >::const_iterator i =
    437              parsed_configs.begin();
    438          i != parsed_configs.end(); ++i) {
    439       scoped_refptr<Config> config = *i;
    440 
    441       ConfigMap::iterator it = configs_.find(config->id);
    442       if (it != configs_.end()) {
    443         VLOG(1)
    444             << "Keeping scid: " << base::HexEncode(
    445                 config->id.data(), config->id.size())
    446             << " orbit: " << base::HexEncode(
    447                 reinterpret_cast<const char *>(config->orbit), kOrbitSize)
    448             << " new primary_time " << config->primary_time.ToUNIXSeconds()
    449             << " old primary_time " << it->second->primary_time.ToUNIXSeconds()
    450             << " new priority " << config->priority
    451             << " old priority " << it->second->priority;
    452         // Update primary_time and priority.
    453         it->second->primary_time = config->primary_time;
    454         it->second->priority = config->priority;
    455         new_configs.insert(*it);
    456       } else {
    457         VLOG(1) << "Adding scid: " << base::HexEncode(
    458                     config->id.data(), config->id.size())
    459                 << " orbit: " << base::HexEncode(
    460                     reinterpret_cast<const char *>(config->orbit), kOrbitSize)
    461                 << " primary_time " << config->primary_time.ToUNIXSeconds()
    462                 << " priority " << config->priority;
    463         new_configs.insert(make_pair(config->id, config));
    464       }
    465     }
    466 
    467     configs_.swap(new_configs);
    468     SelectNewPrimaryConfig(now);
    469     DCHECK(primary_config_.get());
    470     DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_);
    471   }
    472 
    473   return ok;
    474 }
    475 
    476 void QuicCryptoServerConfig::GetConfigIds(vector<string>* scids) const {
    477   base::AutoLock locked(configs_lock_);
    478   for (ConfigMap::const_iterator it = configs_.begin();
    479        it != configs_.end(); ++it) {
    480     scids->push_back(it->first);
    481   }
    482 }
    483 
    484 void QuicCryptoServerConfig::ValidateClientHello(
    485     const CryptoHandshakeMessage& client_hello,
    486     IPEndPoint client_ip,
    487     const QuicClock* clock,
    488     ValidateClientHelloResultCallback* done_cb) const {
    489   const QuicWallTime now(clock->WallNow());
    490 
    491   ValidateClientHelloResultCallback::Result* result =
    492       new ValidateClientHelloResultCallback::Result(
    493           client_hello, client_ip, now);
    494 
    495   StringPiece requested_scid;
    496   client_hello.GetStringPiece(kSCID, &requested_scid);
    497 
    498   uint8 primary_orbit[kOrbitSize];
    499   scoped_refptr<Config> requested_config;
    500   {
    501     base::AutoLock locked(configs_lock_);
    502 
    503     if (!primary_config_.get()) {
    504       result->error_code = QUIC_CRYPTO_INTERNAL_ERROR;
    505       result->error_details = "No configurations loaded";
    506     } else {
    507       if (!next_config_promotion_time_.IsZero() &&
    508           next_config_promotion_time_.IsAfter(now)) {
    509         SelectNewPrimaryConfig(now);
    510         DCHECK(primary_config_.get());
    511         DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_);
    512       }
    513 
    514       memcpy(primary_orbit, primary_config_->orbit, sizeof(primary_orbit));
    515     }
    516 
    517     requested_config = GetConfigWithScid(requested_scid);
    518   }
    519 
    520   if (result->error_code == QUIC_NO_ERROR) {
    521     EvaluateClientHello(primary_orbit, requested_config, result, done_cb);
    522   } else {
    523     done_cb->Run(result);
    524   }
    525 }
    526 
    527 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
    528     const ValidateClientHelloResultCallback::Result& validate_chlo_result,
    529     QuicConnectionId connection_id,
    530     IPEndPoint client_address,
    531     QuicVersion version,
    532     const QuicVersionVector& supported_versions,
    533     const QuicClock* clock,
    534     QuicRandom* rand,
    535     QuicCryptoNegotiatedParameters *params,
    536     CryptoHandshakeMessage* out,
    537     string* error_details) const {
    538   DCHECK(error_details);
    539 
    540   const CryptoHandshakeMessage& client_hello =
    541       validate_chlo_result.client_hello;
    542   const ClientHelloInfo& info = validate_chlo_result.info;
    543 
    544   // If the client's preferred version is not the version we are currently
    545   // speaking, then the client went through a version negotiation.  In this
    546   // case, we need to make sure that we actually do not support this version
    547   // and that it wasn't a downgrade attack.
    548   QuicTag client_version_tag;
    549   if (client_hello.GetUint32(kVER, &client_version_tag) != QUIC_NO_ERROR) {
    550     *error_details = "client hello missing version list";
    551     return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
    552   }
    553   QuicVersion client_version = QuicTagToQuicVersion(client_version_tag);
    554   if (client_version != version) {
    555     // Just because client_version is a valid version enum doesn't mean that
    556     // this server actually supports that version, so we check to see if
    557     // it's actually in the supported versions list.
    558     for (size_t i = 0; i < supported_versions.size(); ++i) {
    559       if (client_version == supported_versions[i]) {
    560         *error_details = "Downgrade attack detected";
    561         return QUIC_VERSION_NEGOTIATION_MISMATCH;
    562       }
    563     }
    564   }
    565 
    566   StringPiece requested_scid;
    567   client_hello.GetStringPiece(kSCID, &requested_scid);
    568   const QuicWallTime now(clock->WallNow());
    569 
    570   scoped_refptr<Config> requested_config;
    571   scoped_refptr<Config> primary_config;
    572   {
    573     base::AutoLock locked(configs_lock_);
    574 
    575     if (!primary_config_.get()) {
    576       *error_details = "No configurations loaded";
    577       return QUIC_CRYPTO_INTERNAL_ERROR;
    578     }
    579 
    580     if (!next_config_promotion_time_.IsZero() &&
    581         next_config_promotion_time_.IsAfter(now)) {
    582       SelectNewPrimaryConfig(now);
    583       DCHECK(primary_config_.get());
    584       DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_);
    585     }
    586 
    587     // We'll use the config that the client requested in order to do
    588     // key-agreement. Otherwise we'll give it a copy of |primary_config_|
    589     // to use.
    590     primary_config = primary_config_;
    591 
    592     requested_config = GetConfigWithScid(requested_scid);
    593   }
    594 
    595   if (validate_chlo_result.error_code != QUIC_NO_ERROR) {
    596     *error_details = validate_chlo_result.error_details;
    597     return validate_chlo_result.error_code;
    598   }
    599 
    600   out->Clear();
    601 
    602   if (!info.valid_source_address_token ||
    603       !info.client_nonce_well_formed ||
    604       !info.unique ||
    605       !requested_config.get()) {
    606     BuildRejection(
    607         *primary_config.get(), client_hello, info, rand, params, out);
    608     return QUIC_NO_ERROR;
    609   }
    610 
    611   const QuicTag* their_aeads;
    612   const QuicTag* their_key_exchanges;
    613   size_t num_their_aeads, num_their_key_exchanges;
    614   if (client_hello.GetTaglist(kAEAD, &their_aeads,
    615                               &num_their_aeads) != QUIC_NO_ERROR ||
    616       client_hello.GetTaglist(kKEXS, &their_key_exchanges,
    617                               &num_their_key_exchanges) != QUIC_NO_ERROR ||
    618       num_their_aeads != 1 ||
    619       num_their_key_exchanges != 1) {
    620     *error_details = "Missing or invalid AEAD or KEXS";
    621     return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
    622   }
    623 
    624   size_t key_exchange_index;
    625   if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads,
    626                                 num_their_aeads, QuicUtils::LOCAL_PRIORITY,
    627                                 &params->aead, NULL) ||
    628       !QuicUtils::FindMutualTag(
    629           requested_config->kexs, their_key_exchanges, num_their_key_exchanges,
    630           QuicUtils::LOCAL_PRIORITY, &params->key_exchange,
    631           &key_exchange_index)) {
    632     *error_details = "Unsupported AEAD or KEXS";
    633     return QUIC_CRYPTO_NO_SUPPORT;
    634   }
    635 
    636   StringPiece public_value;
    637   if (!client_hello.GetStringPiece(kPUBS, &public_value)) {
    638     *error_details = "Missing public value";
    639     return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
    640   }
    641 
    642   const KeyExchange* key_exchange =
    643       requested_config->key_exchanges[key_exchange_index];
    644   if (!key_exchange->CalculateSharedKey(public_value,
    645                                         &params->initial_premaster_secret)) {
    646     *error_details = "Invalid public value";
    647     return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
    648   }
    649 
    650   if (!info.sni.empty()) {
    651     scoped_ptr<char[]> sni_tmp(new char[info.sni.length() + 1]);
    652     memcpy(sni_tmp.get(), info.sni.data(), info.sni.length());
    653     sni_tmp[info.sni.length()] = 0;
    654     params->sni = CryptoUtils::NormalizeHostname(sni_tmp.get());
    655   }
    656 
    657   string hkdf_suffix;
    658   const QuicData& client_hello_serialized = client_hello.GetSerialized();
    659   hkdf_suffix.reserve(sizeof(connection_id) + client_hello_serialized.length() +
    660                       requested_config->serialized.size());
    661   hkdf_suffix.append(reinterpret_cast<char*>(&connection_id),
    662                      sizeof(connection_id));
    663   hkdf_suffix.append(client_hello_serialized.data(),
    664                      client_hello_serialized.length());
    665   hkdf_suffix.append(requested_config->serialized);
    666 
    667   StringPiece cetv_ciphertext;
    668   if (requested_config->channel_id_enabled &&
    669       client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) {
    670     CryptoHandshakeMessage client_hello_copy(client_hello);
    671     client_hello_copy.Erase(kCETV);
    672     client_hello_copy.Erase(kPAD);
    673 
    674     const QuicData& client_hello_serialized = client_hello_copy.GetSerialized();
    675     string hkdf_input;
    676     hkdf_input.append(QuicCryptoConfig::kCETVLabel,
    677                       strlen(QuicCryptoConfig::kCETVLabel) + 1);
    678     hkdf_input.append(reinterpret_cast<char*>(&connection_id),
    679                       sizeof(connection_id));
    680     hkdf_input.append(client_hello_serialized.data(),
    681                       client_hello_serialized.length());
    682     hkdf_input.append(requested_config->serialized);
    683 
    684     CrypterPair crypters;
    685     if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead,
    686                                  info.client_nonce, info.server_nonce,
    687                                  hkdf_input, CryptoUtils::SERVER, &crypters,
    688                                  NULL /* subkey secret */)) {
    689       *error_details = "Symmetric key setup failed";
    690       return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
    691     }
    692 
    693     scoped_ptr<QuicData> cetv_plaintext(crypters.decrypter->DecryptPacket(
    694         0 /* sequence number */, StringPiece() /* associated data */,
    695         cetv_ciphertext));
    696     if (!cetv_plaintext.get()) {
    697       *error_details = "CETV decryption failure";
    698       return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
    699     }
    700 
    701     scoped_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage(
    702         cetv_plaintext->AsStringPiece()));
    703     if (!cetv.get()) {
    704       *error_details = "CETV parse error";
    705       return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
    706     }
    707 
    708     StringPiece key, signature;
    709     if (cetv->GetStringPiece(kCIDK, &key) &&
    710         cetv->GetStringPiece(kCIDS, &signature)) {
    711       if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) {
    712         *error_details = "ChannelID signature failure";
    713         return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
    714       }
    715 
    716       params->channel_id = key.as_string();
    717     }
    718   }
    719 
    720   string hkdf_input;
    721   size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
    722   hkdf_input.reserve(label_len + hkdf_suffix.size());
    723   hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
    724   hkdf_input.append(hkdf_suffix);
    725 
    726   if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead,
    727                                info.client_nonce, info.server_nonce, hkdf_input,
    728                                CryptoUtils::SERVER,
    729                                &params->initial_crypters,
    730                                NULL /* subkey secret */)) {
    731     *error_details = "Symmetric key setup failed";
    732     return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
    733   }
    734 
    735   string forward_secure_public_value;
    736   if (ephemeral_key_source_.get()) {
    737     params->forward_secure_premaster_secret =
    738         ephemeral_key_source_->CalculateForwardSecureKey(
    739             key_exchange, rand, clock->ApproximateNow(), public_value,
    740             &forward_secure_public_value);
    741   } else {
    742     scoped_ptr<KeyExchange> forward_secure_key_exchange(
    743         key_exchange->NewKeyPair(rand));
    744     forward_secure_public_value =
    745         forward_secure_key_exchange->public_value().as_string();
    746     if (!forward_secure_key_exchange->CalculateSharedKey(
    747             public_value, &params->forward_secure_premaster_secret)) {
    748       *error_details = "Invalid public value";
    749       return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
    750     }
    751   }
    752 
    753   string forward_secure_hkdf_input;
    754   label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1;
    755   forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size());
    756   forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel,
    757                                    label_len);
    758   forward_secure_hkdf_input.append(hkdf_suffix);
    759 
    760   if (!CryptoUtils::DeriveKeys(
    761            params->forward_secure_premaster_secret, params->aead,
    762            info.client_nonce, info.server_nonce, forward_secure_hkdf_input,
    763            CryptoUtils::SERVER, &params->forward_secure_crypters,
    764            &params->subkey_secret)) {
    765     *error_details = "Symmetric key setup failed";
    766     return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
    767   }
    768 
    769   out->set_tag(kSHLO);
    770   QuicTagVector supported_version_tags;
    771   for (size_t i = 0; i < supported_versions.size(); ++i) {
    772     supported_version_tags.push_back
    773         (QuicVersionToQuicTag(supported_versions[i]));
    774   }
    775   out->SetVector(kVER, supported_version_tags);
    776   out->SetStringPiece(
    777       kSourceAddressTokenTag,
    778       NewSourceAddressToken(
    779           *requested_config.get(), client_address, rand, info.now, NULL));
    780   QuicSocketAddressCoder address_coder(client_address);
    781   out->SetStringPiece(kCADR, address_coder.Encode());
    782   out->SetStringPiece(kPUBS, forward_secure_public_value);
    783 
    784   return QUIC_NO_ERROR;
    785 }
    786 
    787 scoped_refptr<QuicCryptoServerConfig::Config>
    788 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const {
    789   // In Chromium, we will dead lock if the lock is held by the current thread.
    790   // Chromium doesn't have AssertReaderHeld API call.
    791   // configs_lock_.AssertReaderHeld();
    792 
    793   if (!requested_scid.empty()) {
    794     ConfigMap::const_iterator it = configs_.find(requested_scid.as_string());
    795     if (it != configs_.end()) {
    796       // We'll use the config that the client requested in order to do
    797       // key-agreement.
    798       return scoped_refptr<Config>(it->second);
    799     }
    800   }
    801 
    802   return scoped_refptr<Config>();
    803 }
    804 
    805 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for
    806 // Config's based on their primary_time.
    807 // static
    808 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan(
    809     const scoped_refptr<Config>& a,
    810     const scoped_refptr<Config>& b) {
    811   if (a->primary_time.IsBefore(b->primary_time) ||
    812       b->primary_time.IsBefore(a->primary_time)) {
    813     // Primary times differ.
    814     return a->primary_time.IsBefore(b->primary_time);
    815   } else if (a->priority != b->priority) {
    816     // Primary times are equal, sort backwards by priority.
    817     return a->priority < b->priority;
    818   } else {
    819     // Primary times and priorities are equal, sort by config id.
    820     return a->id < b->id;
    821   }
    822 }
    823 
    824 void QuicCryptoServerConfig::SelectNewPrimaryConfig(
    825     const QuicWallTime now) const {
    826   vector<scoped_refptr<Config> > configs;
    827   configs.reserve(configs_.size());
    828 
    829   for (ConfigMap::const_iterator it = configs_.begin();
    830        it != configs_.end(); ++it) {
    831     // TODO(avd) Exclude expired configs?
    832     configs.push_back(it->second);
    833   }
    834 
    835   if (configs.empty()) {
    836     if (primary_config_.get()) {
    837       LOG(DFATAL) << "No valid QUIC server config. Keeping the current config.";
    838     } else {
    839       LOG(DFATAL) << "No valid QUIC server config.";
    840     }
    841     return;
    842   }
    843 
    844   sort(configs.begin(), configs.end(), ConfigPrimaryTimeLessThan);
    845 
    846   Config* best_candidate = configs[0].get();
    847 
    848   for (size_t i = 0; i < configs.size(); ++i) {
    849     const scoped_refptr<Config> config(configs[i]);
    850     if (!config->primary_time.IsAfter(now)) {
    851       if (config->primary_time.IsAfter(best_candidate->primary_time)) {
    852         best_candidate = config.get();
    853       }
    854       continue;
    855     }
    856 
    857     // This is the first config with a primary_time in the future. Thus the
    858     // previous Config should be the primary and this one should determine the
    859     // next_config_promotion_time_.
    860     scoped_refptr<Config> new_primary(best_candidate);
    861     if (i == 0) {
    862       // We need the primary_time of the next config.
    863       if (configs.size() > 1) {
    864         next_config_promotion_time_ = configs[1]->primary_time;
    865       } else {
    866         next_config_promotion_time_ = QuicWallTime::Zero();
    867       }
    868     } else {
    869       next_config_promotion_time_ = config->primary_time;
    870     }
    871 
    872     if (primary_config_.get()) {
    873       primary_config_->is_primary = false;
    874     }
    875     primary_config_ = new_primary;
    876     new_primary->is_primary = true;
    877     DVLOG(1) << "New primary config.  orbit: "
    878              << base::HexEncode(
    879                  reinterpret_cast<const char*>(primary_config_->orbit),
    880                  kOrbitSize);
    881     if (primary_config_changed_cb_.get() != NULL) {
    882       primary_config_changed_cb_->Run(primary_config_->id);
    883     }
    884 
    885     return;
    886   }
    887 
    888   // All config's primary times are in the past. We should make the most recent
    889   // and highest priority candidate primary.
    890   scoped_refptr<Config> new_primary(best_candidate);
    891   if (primary_config_.get()) {
    892     primary_config_->is_primary = false;
    893   }
    894   primary_config_ = new_primary;
    895   new_primary->is_primary = true;
    896   DVLOG(1) << "New primary config.  orbit: "
    897            << base::HexEncode(
    898                reinterpret_cast<const char*>(primary_config_->orbit),
    899                kOrbitSize)
    900            << " scid: " << base::HexEncode(primary_config_->id.data(),
    901                                            primary_config_->id.size());
    902   next_config_promotion_time_ = QuicWallTime::Zero();
    903   if (primary_config_changed_cb_.get() != NULL) {
    904     primary_config_changed_cb_->Run(primary_config_->id);
    905   }
    906 }
    907 
    908 void QuicCryptoServerConfig::EvaluateClientHello(
    909     const uint8* primary_orbit,
    910     scoped_refptr<Config> requested_config,
    911     ValidateClientHelloResultCallback::Result* client_hello_state,
    912     ValidateClientHelloResultCallback* done_cb) const {
    913   ValidateClientHelloHelper helper(client_hello_state, done_cb);
    914 
    915   const CryptoHandshakeMessage& client_hello =
    916       client_hello_state->client_hello;
    917   ClientHelloInfo* info = &(client_hello_state->info);
    918 
    919   if (client_hello.size() < kClientHelloMinimumSize) {
    920     helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH,
    921                               "Client hello too small");
    922     return;
    923   }
    924 
    925   if (client_hello.GetStringPiece(kSNI, &info->sni) &&
    926       !CryptoUtils::IsValidSNI(info->sni)) {
    927     helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
    928                               "Invalid SNI name");
    929     return;
    930   }
    931 
    932   client_hello.GetStringPiece(kUAID, &info->user_agent_id);
    933 
    934   if (!requested_config.get()) {
    935     StringPiece requested_scid;
    936     if (client_hello.GetStringPiece(kSCID, &requested_scid)) {
    937       info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
    938     } else {
    939       info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
    940     }
    941     // No server config with the requested ID.
    942     helper.ValidationComplete(QUIC_NO_ERROR, "");
    943     return;
    944   }
    945 
    946   HandshakeFailureReason source_address_token_error;
    947   StringPiece srct;
    948   if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
    949     source_address_token_error = ValidateSourceAddressToken(
    950         *requested_config.get(), srct, info->client_ip, info->now);
    951     info->valid_source_address_token =
    952         (source_address_token_error == HANDSHAKE_OK);
    953   } else {
    954     source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
    955   }
    956 
    957   bool found_error = false;
    958   if (source_address_token_error != HANDSHAKE_OK) {
    959     info->reject_reasons.push_back(source_address_token_error);
    960     // No valid source address token.
    961     if (FLAGS_use_early_return_when_verifying_chlo) {
    962       helper.ValidationComplete(QUIC_NO_ERROR, "");
    963       return;
    964     }
    965     found_error = true;
    966   }
    967 
    968   if (client_hello.GetStringPiece(kNONC, &info->client_nonce) &&
    969       info->client_nonce.size() == kNonceSize) {
    970     info->client_nonce_well_formed = true;
    971   } else {
    972     info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE);
    973     // Invalid client nonce.
    974     DVLOG(1) << "Invalid client nonce.";
    975     if (FLAGS_use_early_return_when_verifying_chlo) {
    976       helper.ValidationComplete(QUIC_NO_ERROR, "");
    977       return;
    978     }
    979     found_error = true;
    980   }
    981 
    982   if (!replay_protection_) {
    983     if (!found_error) {
    984       info->unique = true;
    985     }
    986     DVLOG(1) << "No replay protection.";
    987     helper.ValidationComplete(QUIC_NO_ERROR, "");
    988     return;
    989   }
    990 
    991   client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce);
    992   if (!info->server_nonce.empty()) {
    993     // If the server nonce is present, use it to establish uniqueness.
    994     HandshakeFailureReason server_nonce_error =
    995         ValidateServerNonce(info->server_nonce, info->now);
    996     if (server_nonce_error == HANDSHAKE_OK) {
    997       info->unique = true;
    998     } else {
    999       info->reject_reasons.push_back(server_nonce_error);
   1000       info->unique = false;
   1001     }
   1002     DVLOG(1) << "Using server nonce, unique: " << info->unique;
   1003     helper.ValidationComplete(QUIC_NO_ERROR, "");
   1004     return;
   1005   }
   1006 
   1007   // We want to contact strike register only if there are no errors because it
   1008   // is a RPC call and is expensive.
   1009   if (found_error) {
   1010     helper.ValidationComplete(QUIC_NO_ERROR, "");
   1011     return;
   1012   }
   1013 
   1014   // Use the client nonce to establish uniqueness.
   1015   StrikeRegisterClient* strike_register_client;
   1016   {
   1017     base::AutoLock locked(strike_register_client_lock_);
   1018 
   1019     if (strike_register_client_.get() == NULL) {
   1020       strike_register_client_.reset(new LocalStrikeRegisterClient(
   1021           strike_register_max_entries_,
   1022           static_cast<uint32>(info->now.ToUNIXSeconds()),
   1023           strike_register_window_secs_,
   1024           primary_orbit,
   1025           strike_register_no_startup_period_ ?
   1026           StrikeRegister::NO_STARTUP_PERIOD_NEEDED :
   1027           StrikeRegister::DENY_REQUESTS_AT_STARTUP));
   1028     }
   1029     strike_register_client = strike_register_client_.get();
   1030   }
   1031 
   1032   strike_register_client->VerifyNonceIsValidAndUnique(
   1033       info->client_nonce,
   1034       info->now,
   1035       new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb));
   1036   helper.StartedAsyncCallback();
   1037 }
   1038 
   1039 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
   1040     const IPEndPoint& client_ip,
   1041     const QuicClock* clock,
   1042     QuicRandom* rand,
   1043     const QuicCryptoNegotiatedParameters& params,
   1044     const CachedNetworkParameters* cached_network_params,
   1045     CryptoHandshakeMessage* out) const {
   1046   base::AutoLock locked(configs_lock_);
   1047   out->set_tag(kSCUP);
   1048   out->SetStringPiece(kSCFG, primary_config_->serialized);
   1049   out->SetStringPiece(kSourceAddressTokenTag,
   1050                       NewSourceAddressToken(*primary_config_.get(),
   1051                                             client_ip,
   1052                                             rand,
   1053                                             clock->WallNow(),
   1054                                             cached_network_params));
   1055 
   1056   if (proof_source_ == NULL) {
   1057     // Insecure QUIC, can send SCFG without proof.
   1058     return true;
   1059   }
   1060 
   1061   const vector<string>* certs;
   1062   string signature;
   1063   if (!proof_source_->GetProof(params.sni, primary_config_->serialized,
   1064                                params.x509_ecdsa_supported, &certs,
   1065                                &signature)) {
   1066     DVLOG(1) << "Server: failed to get proof.";
   1067     return false;
   1068   }
   1069 
   1070   const string compressed = CertCompressor::CompressChain(
   1071       *certs, params.client_common_set_hashes, params.client_cached_cert_hashes,
   1072       primary_config_->common_cert_sets);
   1073 
   1074   out->SetStringPiece(kCertificateTag, compressed);
   1075   out->SetStringPiece(kPROF, signature);
   1076   return true;
   1077 }
   1078 
   1079 void QuicCryptoServerConfig::BuildRejection(
   1080     const Config& config,
   1081     const CryptoHandshakeMessage& client_hello,
   1082     const ClientHelloInfo& info,
   1083     QuicRandom* rand,
   1084     QuicCryptoNegotiatedParameters *params,
   1085     CryptoHandshakeMessage* out) const {
   1086   out->set_tag(kREJ);
   1087   out->SetStringPiece(kSCFG, config.serialized);
   1088   out->SetStringPiece(kSourceAddressTokenTag,
   1089                       NewSourceAddressToken(
   1090                           config,
   1091                           info.client_ip,
   1092                           rand,
   1093                           info.now,
   1094                           NULL));
   1095   if (replay_protection_) {
   1096     out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now));
   1097   }
   1098 
   1099   if (FLAGS_send_quic_crypto_reject_reason) {
   1100     // Send client the reject reason for debugging purposes.
   1101     DCHECK_LT(0u, info.reject_reasons.size());
   1102     out->SetVector(kRREJ, info.reject_reasons);
   1103   }
   1104 
   1105   // The client may have requested a certificate chain.
   1106   const QuicTag* their_proof_demands;
   1107   size_t num_their_proof_demands;
   1108 
   1109   if (proof_source_.get() == NULL ||
   1110       client_hello.GetTaglist(kPDMD, &their_proof_demands,
   1111                               &num_their_proof_demands) !=
   1112           QUIC_NO_ERROR) {
   1113     return;
   1114   }
   1115 
   1116   bool x509_supported = false;
   1117   for (size_t i = 0; i < num_their_proof_demands; i++) {
   1118     switch (their_proof_demands[i]) {
   1119       case kX509:
   1120         x509_supported = true;
   1121         params->x509_ecdsa_supported = true;
   1122         break;
   1123       case kX59R:
   1124         x509_supported = true;
   1125         break;
   1126     }
   1127   }
   1128 
   1129   if (!x509_supported) {
   1130     return;
   1131   }
   1132 
   1133   const vector<string>* certs;
   1134   string signature;
   1135   if (!proof_source_->GetProof(info.sni.as_string(), config.serialized,
   1136                                params->x509_ecdsa_supported, &certs,
   1137                                &signature)) {
   1138     return;
   1139   }
   1140 
   1141   StringPiece client_common_set_hashes;
   1142   if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) {
   1143     params->client_common_set_hashes = client_common_set_hashes.as_string();
   1144   }
   1145 
   1146   StringPiece client_cached_cert_hashes;
   1147   if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) {
   1148     params->client_cached_cert_hashes = client_cached_cert_hashes.as_string();
   1149   }
   1150 
   1151   const string compressed = CertCompressor::CompressChain(
   1152       *certs, params->client_common_set_hashes,
   1153       params->client_cached_cert_hashes, config.common_cert_sets);
   1154 
   1155   // kREJOverheadBytes is a very rough estimate of how much of a REJ
   1156   // message is taken up by things other than the certificates.
   1157   // STK: 56 bytes
   1158   // SNO: 56 bytes
   1159   // SCFG
   1160   //   SCID: 16 bytes
   1161   //   PUBS: 38 bytes
   1162   const size_t kREJOverheadBytes = 166;
   1163   // kMultiplier is the multiple of the CHLO message size that a REJ message
   1164   // must stay under when the client doesn't present a valid source-address
   1165   // token.
   1166   const size_t kMultiplier = 2;
   1167   // max_unverified_size is the number of bytes that the certificate chain
   1168   // and signature can consume before we will demand a valid source-address
   1169   // token.
   1170   const size_t max_unverified_size =
   1171       client_hello.size() * kMultiplier - kREJOverheadBytes;
   1172   COMPILE_ASSERT(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes,
   1173                  overhead_calculation_may_underflow);
   1174   if (info.valid_source_address_token ||
   1175       signature.size() + compressed.size() < max_unverified_size) {
   1176     out->SetStringPiece(kCertificateTag, compressed);
   1177     out->SetStringPiece(kPROF, signature);
   1178   }
   1179 }
   1180 
   1181 scoped_refptr<QuicCryptoServerConfig::Config>
   1182 QuicCryptoServerConfig::ParseConfigProtobuf(
   1183     QuicServerConfigProtobuf* protobuf) {
   1184   scoped_ptr<CryptoHandshakeMessage> msg(
   1185       CryptoFramer::ParseMessage(protobuf->config()));
   1186 
   1187   if (msg->tag() != kSCFG) {
   1188     LOG(WARNING) << "Server config message has tag " << msg->tag()
   1189                  << " expected " << kSCFG;
   1190     return NULL;
   1191   }
   1192 
   1193   scoped_refptr<Config> config(new Config);
   1194   config->serialized = protobuf->config();
   1195 
   1196   if (!protobuf->has_source_address_token_secret_override()) {
   1197     // Use the default boxer.
   1198     config->source_address_token_boxer = &default_source_address_token_boxer_;
   1199   } else {
   1200     // Create override boxer instance.
   1201     CryptoSecretBoxer* boxer = new CryptoSecretBoxer;
   1202     boxer->SetKey(DeriveSourceAddressTokenKey(
   1203         protobuf->source_address_token_secret_override()));
   1204     config->source_address_token_boxer_storage.reset(boxer);
   1205     config->source_address_token_boxer = boxer;
   1206   }
   1207 
   1208   if (protobuf->has_primary_time()) {
   1209     config->primary_time =
   1210         QuicWallTime::FromUNIXSeconds(protobuf->primary_time());
   1211   }
   1212 
   1213   config->priority = protobuf->priority();
   1214 
   1215   StringPiece scid;
   1216   if (!msg->GetStringPiece(kSCID, &scid)) {
   1217     LOG(WARNING) << "Server config message is missing SCID";
   1218     return NULL;
   1219   }
   1220   config->id = scid.as_string();
   1221 
   1222   const QuicTag* aead_tags;
   1223   size_t aead_len;
   1224   if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) {
   1225     LOG(WARNING) << "Server config message is missing AEAD";
   1226     return NULL;
   1227   }
   1228   config->aead = vector<QuicTag>(aead_tags, aead_tags + aead_len);
   1229 
   1230   const QuicTag* kexs_tags;
   1231   size_t kexs_len;
   1232   if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) {
   1233     LOG(WARNING) << "Server config message is missing KEXS";
   1234     return NULL;
   1235   }
   1236 
   1237   StringPiece orbit;
   1238   if (!msg->GetStringPiece(kORBT, &orbit)) {
   1239     LOG(WARNING) << "Server config message is missing ORBT";
   1240     return NULL;
   1241   }
   1242 
   1243   if (orbit.size() != kOrbitSize) {
   1244     LOG(WARNING) << "Orbit value in server config is the wrong length."
   1245                     " Got " << orbit.size() << " want " << kOrbitSize;
   1246     return NULL;
   1247   }
   1248   COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size);
   1249   memcpy(config->orbit, orbit.data(), sizeof(config->orbit));
   1250 
   1251   {
   1252     StrikeRegisterClient* strike_register_client;
   1253     {
   1254       base::AutoLock locked(strike_register_client_lock_);
   1255       strike_register_client = strike_register_client_.get();
   1256     }
   1257 
   1258     if (strike_register_client != NULL &&
   1259         !strike_register_client->IsKnownOrbit(orbit)) {
   1260       LOG(WARNING)
   1261           << "Rejecting server config with orbit that the strike register "
   1262           "client doesn't know about.";
   1263       return NULL;
   1264     }
   1265   }
   1266 
   1267   if (kexs_len != protobuf->key_size()) {
   1268     LOG(WARNING) << "Server config has " << kexs_len
   1269                  << " key exchange methods configured, but "
   1270                  << protobuf->key_size() << " private keys";
   1271     return NULL;
   1272   }
   1273 
   1274   const QuicTag* proof_demand_tags;
   1275   size_t num_proof_demand_tags;
   1276   if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) ==
   1277       QUIC_NO_ERROR) {
   1278     for (size_t i = 0; i < num_proof_demand_tags; i++) {
   1279       if (proof_demand_tags[i] == kCHID) {
   1280         config->channel_id_enabled = true;
   1281         break;
   1282       }
   1283     }
   1284   }
   1285 
   1286   for (size_t i = 0; i < kexs_len; i++) {
   1287     const QuicTag tag = kexs_tags[i];
   1288     string private_key;
   1289 
   1290     config->kexs.push_back(tag);
   1291 
   1292     for (size_t j = 0; j < protobuf->key_size(); j++) {
   1293       const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i);
   1294       if (key.tag() == tag) {
   1295         private_key = key.private_key();
   1296         break;
   1297       }
   1298     }
   1299 
   1300     if (private_key.empty()) {
   1301       LOG(WARNING) << "Server config contains key exchange method without "
   1302                       "corresponding private key: " << tag;
   1303       return NULL;
   1304     }
   1305 
   1306     scoped_ptr<KeyExchange> ka;
   1307     switch (tag) {
   1308       case kC255:
   1309         ka.reset(Curve25519KeyExchange::New(private_key));
   1310         if (!ka.get()) {
   1311           LOG(WARNING) << "Server config contained an invalid curve25519"
   1312                           " private key.";
   1313           return NULL;
   1314         }
   1315         break;
   1316       case kP256:
   1317         ka.reset(P256KeyExchange::New(private_key));
   1318         if (!ka.get()) {
   1319           LOG(WARNING) << "Server config contained an invalid P-256"
   1320                           " private key.";
   1321           return NULL;
   1322         }
   1323         break;
   1324       default:
   1325         LOG(WARNING) << "Server config message contains unknown key exchange "
   1326                         "method: " << tag;
   1327         return NULL;
   1328     }
   1329 
   1330     for (vector<KeyExchange*>::const_iterator i = config->key_exchanges.begin();
   1331          i != config->key_exchanges.end(); ++i) {
   1332       if ((*i)->tag() == tag) {
   1333         LOG(WARNING) << "Duplicate key exchange in config: " << tag;
   1334         return NULL;
   1335       }
   1336     }
   1337 
   1338     config->key_exchanges.push_back(ka.release());
   1339   }
   1340 
   1341   return config;
   1342 }
   1343 
   1344 void QuicCryptoServerConfig::SetProofSource(ProofSource* proof_source) {
   1345   proof_source_.reset(proof_source);
   1346 }
   1347 
   1348 void QuicCryptoServerConfig::SetEphemeralKeySource(
   1349     EphemeralKeySource* ephemeral_key_source) {
   1350   ephemeral_key_source_.reset(ephemeral_key_source);
   1351 }
   1352 
   1353 void QuicCryptoServerConfig::SetStrikeRegisterClient(
   1354     StrikeRegisterClient* strike_register_client) {
   1355   base::AutoLock locker(strike_register_client_lock_);
   1356   DCHECK(!strike_register_client_.get());
   1357   strike_register_client_.reset(strike_register_client);
   1358 }
   1359 
   1360 void QuicCryptoServerConfig::set_replay_protection(bool on) {
   1361   replay_protection_ = on;
   1362 }
   1363 
   1364 void QuicCryptoServerConfig::set_strike_register_no_startup_period() {
   1365   base::AutoLock locker(strike_register_client_lock_);
   1366   DCHECK(!strike_register_client_.get());
   1367   strike_register_no_startup_period_ = true;
   1368 }
   1369 
   1370 void QuicCryptoServerConfig::set_strike_register_max_entries(
   1371     uint32 max_entries) {
   1372   base::AutoLock locker(strike_register_client_lock_);
   1373   DCHECK(!strike_register_client_.get());
   1374   strike_register_max_entries_ = max_entries;
   1375 }
   1376 
   1377 void QuicCryptoServerConfig::set_strike_register_window_secs(
   1378     uint32 window_secs) {
   1379   base::AutoLock locker(strike_register_client_lock_);
   1380   DCHECK(!strike_register_client_.get());
   1381   strike_register_window_secs_ = window_secs;
   1382 }
   1383 
   1384 void QuicCryptoServerConfig::set_source_address_token_future_secs(
   1385     uint32 future_secs) {
   1386   source_address_token_future_secs_ = future_secs;
   1387 }
   1388 
   1389 void QuicCryptoServerConfig::set_source_address_token_lifetime_secs(
   1390     uint32 lifetime_secs) {
   1391   source_address_token_lifetime_secs_ = lifetime_secs;
   1392 }
   1393 
   1394 void QuicCryptoServerConfig::set_server_nonce_strike_register_max_entries(
   1395     uint32 max_entries) {
   1396   DCHECK(!server_nonce_strike_register_.get());
   1397   server_nonce_strike_register_max_entries_ = max_entries;
   1398 }
   1399 
   1400 void QuicCryptoServerConfig::set_server_nonce_strike_register_window_secs(
   1401     uint32 window_secs) {
   1402   DCHECK(!server_nonce_strike_register_.get());
   1403   server_nonce_strike_register_window_secs_ = window_secs;
   1404 }
   1405 
   1406 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
   1407     PrimaryConfigChangedCallback* cb) {
   1408   base::AutoLock locked(configs_lock_);
   1409   primary_config_changed_cb_.reset(cb);
   1410 }
   1411 
   1412 string QuicCryptoServerConfig::NewSourceAddressToken(
   1413     const Config& config,
   1414     const IPEndPoint& ip,
   1415     QuicRandom* rand,
   1416     QuicWallTime now,
   1417     const CachedNetworkParameters* cached_network_params) const {
   1418   IPAddressNumber ip_address = ip.address();
   1419   if (ip.GetSockAddrFamily() == AF_INET) {
   1420     ip_address = ConvertIPv4NumberToIPv6Number(ip_address);
   1421   }
   1422   SourceAddressToken source_address_token;
   1423   source_address_token.set_ip(IPAddressToPackedString(ip_address));
   1424   source_address_token.set_timestamp(now.ToUNIXSeconds());
   1425   if (cached_network_params != NULL) {
   1426     source_address_token.set_cached_network_parameters(*cached_network_params);
   1427   }
   1428 
   1429   return config.source_address_token_boxer->Box(
   1430       rand, source_address_token.SerializeAsString());
   1431 }
   1432 
   1433 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken(
   1434     const Config& config,
   1435     StringPiece token,
   1436     const IPEndPoint& ip,
   1437     QuicWallTime now) const {
   1438   string storage;
   1439   StringPiece plaintext;
   1440   if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) {
   1441     return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE;
   1442   }
   1443 
   1444   SourceAddressToken source_address_token;
   1445   if (!source_address_token.ParseFromArray(plaintext.data(),
   1446                                            plaintext.size())) {
   1447     return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE;
   1448   }
   1449 
   1450   IPAddressNumber ip_address = ip.address();
   1451   if (ip.GetSockAddrFamily() == AF_INET) {
   1452     ip_address = ConvertIPv4NumberToIPv6Number(ip_address);
   1453   }
   1454   if (source_address_token.ip() != IPAddressToPackedString(ip_address)) {
   1455     // It's for a different IP address.
   1456     return SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
   1457   }
   1458 
   1459   const QuicWallTime timestamp(
   1460       QuicWallTime::FromUNIXSeconds(source_address_token.timestamp()));
   1461   const QuicTime::Delta delta(now.AbsoluteDifference(timestamp));
   1462 
   1463   if (now.IsBefore(timestamp) &&
   1464       delta.ToSeconds() > source_address_token_future_secs_) {
   1465     return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE;
   1466   }
   1467 
   1468   if (now.IsAfter(timestamp) &&
   1469       delta.ToSeconds() > source_address_token_lifetime_secs_) {
   1470     return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE;
   1471   }
   1472 
   1473   return HANDSHAKE_OK;
   1474 }
   1475 
   1476 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server
   1477 // nonce.
   1478 static const size_t kServerNoncePlaintextSize =
   1479     4 /* timestamp */ + 20 /* random bytes */;
   1480 
   1481 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand,
   1482                                               QuicWallTime now) const {
   1483   const uint32 timestamp = static_cast<uint32>(now.ToUNIXSeconds());
   1484 
   1485   uint8 server_nonce[kServerNoncePlaintextSize];
   1486   COMPILE_ASSERT(sizeof(server_nonce) > sizeof(timestamp), nonce_too_small);
   1487   server_nonce[0] = static_cast<uint8>(timestamp >> 24);
   1488   server_nonce[1] = static_cast<uint8>(timestamp >> 16);
   1489   server_nonce[2] = static_cast<uint8>(timestamp >> 8);
   1490   server_nonce[3] = static_cast<uint8>(timestamp);
   1491   rand->RandBytes(&server_nonce[sizeof(timestamp)],
   1492                   sizeof(server_nonce) - sizeof(timestamp));
   1493 
   1494   return server_nonce_boxer_.Box(
   1495       rand,
   1496       StringPiece(reinterpret_cast<char*>(server_nonce), sizeof(server_nonce)));
   1497 }
   1498 
   1499 HandshakeFailureReason QuicCryptoServerConfig::ValidateServerNonce(
   1500     StringPiece token,
   1501     QuicWallTime now) const {
   1502   string storage;
   1503   StringPiece plaintext;
   1504   if (!server_nonce_boxer_.Unbox(token, &storage, &plaintext)) {
   1505     return SERVER_NONCE_DECRYPTION_FAILURE;
   1506   }
   1507 
   1508   // plaintext contains:
   1509   //   uint32 timestamp
   1510   //   uint8[20] random bytes
   1511 
   1512   if (plaintext.size() != kServerNoncePlaintextSize) {
   1513     // This should never happen because the value decrypted correctly.
   1514     LOG(DFATAL) << "Seemingly valid server nonce had incorrect length.";
   1515     return SERVER_NONCE_INVALID_FAILURE;
   1516   }
   1517 
   1518   uint8 server_nonce[32];
   1519   memcpy(server_nonce, plaintext.data(), 4);
   1520   memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_));
   1521   memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4,
   1522          20);
   1523   COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce),
   1524                  bad_nonce_buffer_length);
   1525 
   1526   InsertStatus nonce_error;
   1527   {
   1528     base::AutoLock auto_lock(server_nonce_strike_register_lock_);
   1529     if (server_nonce_strike_register_.get() == NULL) {
   1530       server_nonce_strike_register_.reset(new StrikeRegister(
   1531           server_nonce_strike_register_max_entries_,
   1532           static_cast<uint32>(now.ToUNIXSeconds()),
   1533           server_nonce_strike_register_window_secs_, server_nonce_orbit_,
   1534           StrikeRegister::NO_STARTUP_PERIOD_NEEDED));
   1535     }
   1536     nonce_error = server_nonce_strike_register_->Insert(
   1537         server_nonce, static_cast<uint32>(now.ToUNIXSeconds()));
   1538   }
   1539 
   1540   switch (nonce_error) {
   1541     case NONCE_OK:
   1542       return HANDSHAKE_OK;
   1543     case NONCE_INVALID_FAILURE:
   1544     case NONCE_INVALID_ORBIT_FAILURE:
   1545       return SERVER_NONCE_INVALID_FAILURE;
   1546     case NONCE_NOT_UNIQUE_FAILURE:
   1547       return SERVER_NONCE_NOT_UNIQUE_FAILURE;
   1548     case NONCE_INVALID_TIME_FAILURE:
   1549       return SERVER_NONCE_INVALID_TIME_FAILURE;
   1550     case NONCE_UNKNOWN_FAILURE:
   1551     case STRIKE_REGISTER_TIMEOUT:
   1552     case STRIKE_REGISTER_FAILURE:
   1553     default:
   1554       LOG(DFATAL) << "Unexpected server nonce error: " << nonce_error;
   1555       return SERVER_NONCE_NOT_UNIQUE_FAILURE;
   1556   }
   1557 }
   1558 
   1559 QuicCryptoServerConfig::Config::Config()
   1560     : channel_id_enabled(false),
   1561       is_primary(false),
   1562       primary_time(QuicWallTime::Zero()),
   1563       priority(0),
   1564       source_address_token_boxer(NULL) {}
   1565 
   1566 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); }
   1567 
   1568 }  // namespace net
   1569