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