OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/crypto/quic_crypto_server_config.h" | 5 #include "net/quic/crypto/quic_crypto_server_config.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 | 9 |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 StringPiece client_nonce; | 81 StringPiece client_nonce; |
82 StringPiece server_nonce; | 82 StringPiece server_nonce; |
83 }; | 83 }; |
84 | 84 |
85 struct ValidateClientHelloResultCallback::Result { | 85 struct ValidateClientHelloResultCallback::Result { |
86 Result(const CryptoHandshakeMessage& in_client_hello, | 86 Result(const CryptoHandshakeMessage& in_client_hello, |
87 IPEndPoint in_client_ip, | 87 IPEndPoint in_client_ip, |
88 QuicWallTime in_now) | 88 QuicWallTime in_now) |
89 : client_hello(in_client_hello), | 89 : client_hello(in_client_hello), |
90 info(in_client_ip, in_now), | 90 info(in_client_ip, in_now), |
91 error_code(QUIC_NO_ERROR) { | 91 error_code(QUIC_NO_ERROR) {} |
92 } | |
93 | 92 |
94 CryptoHandshakeMessage client_hello; | 93 CryptoHandshakeMessage client_hello; |
95 ClientHelloInfo info; | 94 ClientHelloInfo info; |
96 QuicErrorCode error_code; | 95 QuicErrorCode error_code; |
97 string error_details; | 96 string error_details; |
98 }; | 97 }; |
99 | 98 |
100 class ValidateClientHelloHelper { | 99 class ValidateClientHelloHelper { |
101 public: | 100 public: |
102 ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result, | 101 ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result, |
103 ValidateClientHelloResultCallback* done_cb) | 102 ValidateClientHelloResultCallback* done_cb) |
104 : result_(result), done_cb_(done_cb) { | 103 : result_(result), done_cb_(done_cb) {} |
105 } | |
106 | 104 |
107 ~ValidateClientHelloHelper() { | 105 ~ValidateClientHelloHelper() { |
108 LOG_IF(DFATAL, done_cb_ != NULL) | 106 LOG_IF(DFATAL, done_cb_ != NULL) |
109 << "Deleting ValidateClientHelloHelper with a pending callback."; | 107 << "Deleting ValidateClientHelloHelper with a pending callback."; |
110 } | 108 } |
111 | 109 |
112 void ValidationComplete(QuicErrorCode error_code, const char* error_details) { | 110 void ValidationComplete(QuicErrorCode error_code, const char* error_details) { |
113 result_->error_code = error_code; | 111 result_->error_code = error_code; |
114 result_->error_details = error_details; | 112 result_->error_details = error_details; |
115 done_cb_->Run(result_); | 113 done_cb_->Run(result_); |
116 DetachCallback(); | 114 DetachCallback(); |
117 } | 115 } |
118 | 116 |
119 void StartedAsyncCallback() { | 117 void StartedAsyncCallback() { DetachCallback(); } |
120 DetachCallback(); | |
121 } | |
122 | 118 |
123 private: | 119 private: |
124 void DetachCallback() { | 120 void DetachCallback() { |
125 LOG_IF(DFATAL, done_cb_ == NULL) << "Callback already detached."; | 121 LOG_IF(DFATAL, done_cb_ == NULL) << "Callback already detached."; |
126 done_cb_ = NULL; | 122 done_cb_ = NULL; |
127 } | 123 } |
128 | 124 |
129 ValidateClientHelloResultCallback::Result* result_; | 125 ValidateClientHelloResultCallback::Result* result_; |
130 ValidateClientHelloResultCallback* done_cb_; | 126 ValidateClientHelloResultCallback* done_cb_; |
131 | 127 |
132 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); | 128 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); |
133 }; | 129 }; |
134 | 130 |
135 class VerifyNonceIsValidAndUniqueCallback | 131 class VerifyNonceIsValidAndUniqueCallback |
136 : public StrikeRegisterClient::ResultCallback { | 132 : public StrikeRegisterClient::ResultCallback { |
137 public: | 133 public: |
138 VerifyNonceIsValidAndUniqueCallback( | 134 VerifyNonceIsValidAndUniqueCallback( |
139 ValidateClientHelloResultCallback::Result* result, | 135 ValidateClientHelloResultCallback::Result* result, |
140 ValidateClientHelloResultCallback* done_cb) | 136 ValidateClientHelloResultCallback* done_cb) |
141 : result_(result), done_cb_(done_cb) { | 137 : result_(result), done_cb_(done_cb) {} |
142 } | |
143 | 138 |
144 protected: | 139 protected: |
145 virtual void RunImpl(bool nonce_is_valid_and_unique) OVERRIDE { | 140 virtual void RunImpl(bool nonce_is_valid_and_unique) OVERRIDE { |
146 DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique; | 141 DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique; |
147 result_->info.unique = nonce_is_valid_and_unique; | 142 result_->info.unique = nonce_is_valid_and_unique; |
148 done_cb_->Run(result_); | 143 done_cb_->Run(result_); |
149 } | 144 } |
150 | 145 |
151 private: | 146 private: |
152 ValidateClientHelloResultCallback::Result* result_; | 147 ValidateClientHelloResultCallback::Result* result_; |
(...skipping 19 matching lines...) Expand all Loading... |
172 | 167 |
173 void ValidateClientHelloResultCallback::Run(const Result* result) { | 168 void ValidateClientHelloResultCallback::Run(const Result* result) { |
174 RunImpl(result->client_hello, *result); | 169 RunImpl(result->client_hello, *result); |
175 delete result; | 170 delete result; |
176 delete this; | 171 delete this; |
177 } | 172 } |
178 | 173 |
179 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() | 174 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() |
180 : expiry_time(QuicWallTime::Zero()), | 175 : expiry_time(QuicWallTime::Zero()), |
181 channel_id_enabled(false), | 176 channel_id_enabled(false), |
182 p256(false) {} | 177 p256(false) { |
| 178 } |
183 | 179 |
184 QuicCryptoServerConfig::QuicCryptoServerConfig( | 180 QuicCryptoServerConfig::QuicCryptoServerConfig( |
185 StringPiece source_address_token_secret, | 181 StringPiece source_address_token_secret, |
186 QuicRandom* rand) | 182 QuicRandom* rand) |
187 : replay_protection_(true), | 183 : replay_protection_(true), |
188 configs_lock_(), | 184 configs_lock_(), |
189 primary_config_(NULL), | 185 primary_config_(NULL), |
190 next_config_promotion_time_(QuicWallTime::Zero()), | 186 next_config_promotion_time_(QuicWallTime::Zero()), |
191 server_nonce_strike_register_lock_(), | 187 server_nonce_strike_register_lock_(), |
192 strike_register_no_startup_period_(false), | 188 strike_register_no_startup_period_(false), |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 return AddConfig(config.get(), clock->WallNow()); | 358 return AddConfig(config.get(), clock->WallNow()); |
363 } | 359 } |
364 | 360 |
365 bool QuicCryptoServerConfig::SetConfigs( | 361 bool QuicCryptoServerConfig::SetConfigs( |
366 const vector<QuicServerConfigProtobuf*>& protobufs, | 362 const vector<QuicServerConfigProtobuf*>& protobufs, |
367 const QuicWallTime now) { | 363 const QuicWallTime now) { |
368 vector<scoped_refptr<Config> > parsed_configs; | 364 vector<scoped_refptr<Config> > parsed_configs; |
369 bool ok = true; | 365 bool ok = true; |
370 | 366 |
371 for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin(); | 367 for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin(); |
372 i != protobufs.end(); ++i) { | 368 i != protobufs.end(); |
| 369 ++i) { |
373 scoped_refptr<Config> config(ParseConfigProtobuf(*i)); | 370 scoped_refptr<Config> config(ParseConfigProtobuf(*i)); |
374 if (!config.get()) { | 371 if (!config.get()) { |
375 ok = false; | 372 ok = false; |
376 break; | 373 break; |
377 } | 374 } |
378 | 375 |
379 parsed_configs.push_back(config); | 376 parsed_configs.push_back(config); |
380 } | 377 } |
381 | 378 |
382 if (parsed_configs.empty()) { | 379 if (parsed_configs.empty()) { |
383 LOG(WARNING) << "New config list is empty."; | 380 LOG(WARNING) << "New config list is empty."; |
384 ok = false; | 381 ok = false; |
385 } | 382 } |
386 | 383 |
387 if (!ok) { | 384 if (!ok) { |
388 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; | 385 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; |
389 } else { | 386 } else { |
390 VLOG(1) << "Updating configs:"; | 387 VLOG(1) << "Updating configs:"; |
391 | 388 |
392 base::AutoLock locked(configs_lock_); | 389 base::AutoLock locked(configs_lock_); |
393 ConfigMap new_configs; | 390 ConfigMap new_configs; |
394 | 391 |
395 for (vector<scoped_refptr<Config> >::const_iterator i = | 392 for (vector<scoped_refptr<Config> >::const_iterator i = |
396 parsed_configs.begin(); | 393 parsed_configs.begin(); |
397 i != parsed_configs.end(); ++i) { | 394 i != parsed_configs.end(); |
| 395 ++i) { |
398 scoped_refptr<Config> config = *i; | 396 scoped_refptr<Config> config = *i; |
399 | 397 |
400 ConfigMap::iterator it = configs_.find(config->id); | 398 ConfigMap::iterator it = configs_.find(config->id); |
401 if (it != configs_.end()) { | 399 if (it != configs_.end()) { |
402 VLOG(1) | 400 VLOG(1) << "Keeping scid: " |
403 << "Keeping scid: " << base::HexEncode( | 401 << base::HexEncode(config->id.data(), config->id.size()) |
404 config->id.data(), config->id.size()) | 402 << " orbit: " |
405 << " orbit: " << base::HexEncode( | 403 << base::HexEncode(reinterpret_cast<const char*>(config->orbit), |
406 reinterpret_cast<const char *>(config->orbit), kOrbitSize) | 404 kOrbitSize) << " new primary_time " |
407 << " new primary_time " << config->primary_time.ToUNIXSeconds() | 405 << config->primary_time.ToUNIXSeconds() << " old primary_time " |
408 << " old primary_time " << it->second->primary_time.ToUNIXSeconds() | 406 << it->second->primary_time.ToUNIXSeconds() << " new priority " |
409 << " new priority " << config->priority | 407 << config->priority << " old priority " << it->second->priority; |
410 << " old priority " << it->second->priority; | |
411 // Update primary_time and priority. | 408 // Update primary_time and priority. |
412 it->second->primary_time = config->primary_time; | 409 it->second->primary_time = config->primary_time; |
413 it->second->priority = config->priority; | 410 it->second->priority = config->priority; |
414 new_configs.insert(*it); | 411 new_configs.insert(*it); |
415 } else { | 412 } else { |
416 VLOG(1) << "Adding scid: " << base::HexEncode( | 413 VLOG(1) << "Adding scid: " |
417 config->id.data(), config->id.size()) | 414 << base::HexEncode(config->id.data(), config->id.size()) |
418 << " orbit: " << base::HexEncode( | 415 << " orbit: " |
419 reinterpret_cast<const char *>(config->orbit), kOrbitSize) | 416 << base::HexEncode(reinterpret_cast<const char*>(config->orbit), |
420 << " primary_time " << config->primary_time.ToUNIXSeconds() | 417 kOrbitSize) << " primary_time " |
421 << " priority " << config->priority; | 418 << config->primary_time.ToUNIXSeconds() << " priority " |
| 419 << config->priority; |
422 new_configs.insert(make_pair(config->id, config)); | 420 new_configs.insert(make_pair(config->id, config)); |
423 } | 421 } |
424 } | 422 } |
425 | 423 |
426 configs_.swap(new_configs); | 424 configs_.swap(new_configs); |
427 SelectNewPrimaryConfig(now); | 425 SelectNewPrimaryConfig(now); |
428 DCHECK(primary_config_); | 426 DCHECK(primary_config_); |
429 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); | 427 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
430 } | 428 } |
431 | 429 |
432 return ok; | 430 return ok; |
433 } | 431 } |
434 | 432 |
435 void QuicCryptoServerConfig::GetConfigIds(vector<string>* scids) const { | 433 void QuicCryptoServerConfig::GetConfigIds(vector<string>* scids) const { |
436 base::AutoLock locked(configs_lock_); | 434 base::AutoLock locked(configs_lock_); |
437 for (ConfigMap::const_iterator it = configs_.begin(); | 435 for (ConfigMap::const_iterator it = configs_.begin(); it != configs_.end(); |
438 it != configs_.end(); ++it) { | 436 ++it) { |
439 scids->push_back(it->first); | 437 scids->push_back(it->first); |
440 } | 438 } |
441 } | 439 } |
442 | 440 |
443 void QuicCryptoServerConfig::ValidateClientHello( | 441 void QuicCryptoServerConfig::ValidateClientHello( |
444 const CryptoHandshakeMessage& client_hello, | 442 const CryptoHandshakeMessage& client_hello, |
445 IPEndPoint client_ip, | 443 IPEndPoint client_ip, |
446 const QuicClock* clock, | 444 const QuicClock* clock, |
447 ValidateClientHelloResultCallback* done_cb) const { | 445 ValidateClientHelloResultCallback* done_cb) const { |
448 const QuicWallTime now(clock->WallNow()); | 446 const QuicWallTime now(clock->WallNow()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 | 483 |
486 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( | 484 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( |
487 const ValidateClientHelloResultCallback::Result& validate_chlo_result, | 485 const ValidateClientHelloResultCallback::Result& validate_chlo_result, |
488 QuicConnectionId connection_id, | 486 QuicConnectionId connection_id, |
489 IPEndPoint client_address, | 487 IPEndPoint client_address, |
490 QuicVersion version, | 488 QuicVersion version, |
491 const QuicVersionVector& supported_versions, | 489 const QuicVersionVector& supported_versions, |
492 uint32 initial_flow_control_window_bytes, | 490 uint32 initial_flow_control_window_bytes, |
493 const QuicClock* clock, | 491 const QuicClock* clock, |
494 QuicRandom* rand, | 492 QuicRandom* rand, |
495 QuicCryptoNegotiatedParameters *params, | 493 QuicCryptoNegotiatedParameters* params, |
496 CryptoHandshakeMessage* out, | 494 CryptoHandshakeMessage* out, |
497 string* error_details) const { | 495 string* error_details) const { |
498 DCHECK(error_details); | 496 DCHECK(error_details); |
499 | 497 |
500 const CryptoHandshakeMessage& client_hello = | 498 const CryptoHandshakeMessage& client_hello = |
501 validate_chlo_result.client_hello; | 499 validate_chlo_result.client_hello; |
502 const ClientHelloInfo& info = validate_chlo_result.info; | 500 const ClientHelloInfo& info = validate_chlo_result.info; |
503 | 501 |
504 // If the client's preferred version is not the version we are currently | 502 // If the client's preferred version is not the version we are currently |
505 // speaking, then the client went through a version negotiation. In this | 503 // speaking, then the client went through a version negotiation. In this |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 requested_config = GetConfigWithScid(requested_scid); | 550 requested_config = GetConfigWithScid(requested_scid); |
553 } | 551 } |
554 | 552 |
555 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { | 553 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { |
556 *error_details = validate_chlo_result.error_details; | 554 *error_details = validate_chlo_result.error_details; |
557 return validate_chlo_result.error_code; | 555 return validate_chlo_result.error_code; |
558 } | 556 } |
559 | 557 |
560 out->Clear(); | 558 out->Clear(); |
561 | 559 |
562 if (!info.valid_source_address_token || | 560 if (!info.valid_source_address_token || !info.client_nonce_well_formed || |
563 !info.client_nonce_well_formed || | 561 !info.unique || !requested_config.get()) { |
564 !info.unique || | |
565 !requested_config.get()) { | |
566 BuildRejection(*primary_config, client_hello, info, rand, out); | 562 BuildRejection(*primary_config, client_hello, info, rand, out); |
567 return QUIC_NO_ERROR; | 563 return QUIC_NO_ERROR; |
568 } | 564 } |
569 | 565 |
570 const QuicTag* their_aeads; | 566 const QuicTag* their_aeads; |
571 const QuicTag* their_key_exchanges; | 567 const QuicTag* their_key_exchanges; |
572 size_t num_their_aeads, num_their_key_exchanges; | 568 size_t num_their_aeads, num_their_key_exchanges; |
573 if (client_hello.GetTaglist(kAEAD, &their_aeads, | 569 if (client_hello.GetTaglist(kAEAD, &their_aeads, &num_their_aeads) != |
574 &num_their_aeads) != QUIC_NO_ERROR || | 570 QUIC_NO_ERROR || |
575 client_hello.GetTaglist(kKEXS, &their_key_exchanges, | 571 client_hello.GetTaglist(kKEXS, |
| 572 &their_key_exchanges, |
576 &num_their_key_exchanges) != QUIC_NO_ERROR || | 573 &num_their_key_exchanges) != QUIC_NO_ERROR || |
577 num_their_aeads != 1 || | 574 num_their_aeads != 1 || num_their_key_exchanges != 1) { |
578 num_their_key_exchanges != 1) { | |
579 *error_details = "Missing or invalid AEAD or KEXS"; | 575 *error_details = "Missing or invalid AEAD or KEXS"; |
580 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 576 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
581 } | 577 } |
582 | 578 |
583 size_t key_exchange_index; | 579 size_t key_exchange_index; |
584 if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads, | 580 if (!QuicUtils::FindMutualTag(requested_config->aead, |
585 num_their_aeads, QuicUtils::LOCAL_PRIORITY, | 581 their_aeads, |
586 ¶ms->aead, NULL) || | 582 num_their_aeads, |
587 !QuicUtils::FindMutualTag( | 583 QuicUtils::LOCAL_PRIORITY, |
588 requested_config->kexs, their_key_exchanges, num_their_key_exchanges, | 584 ¶ms->aead, |
589 QuicUtils::LOCAL_PRIORITY, ¶ms->key_exchange, | 585 NULL) || |
590 &key_exchange_index)) { | 586 !QuicUtils::FindMutualTag(requested_config->kexs, |
| 587 their_key_exchanges, |
| 588 num_their_key_exchanges, |
| 589 QuicUtils::LOCAL_PRIORITY, |
| 590 ¶ms->key_exchange, |
| 591 &key_exchange_index)) { |
591 *error_details = "Unsupported AEAD or KEXS"; | 592 *error_details = "Unsupported AEAD or KEXS"; |
592 return QUIC_CRYPTO_NO_SUPPORT; | 593 return QUIC_CRYPTO_NO_SUPPORT; |
593 } | 594 } |
594 | 595 |
595 StringPiece public_value; | 596 StringPiece public_value; |
596 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { | 597 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { |
597 *error_details = "Missing public value"; | 598 *error_details = "Missing public value"; |
598 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 599 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
599 } | 600 } |
600 | 601 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 string hkdf_input; | 635 string hkdf_input; |
635 hkdf_input.append(QuicCryptoConfig::kCETVLabel, | 636 hkdf_input.append(QuicCryptoConfig::kCETVLabel, |
636 strlen(QuicCryptoConfig::kCETVLabel) + 1); | 637 strlen(QuicCryptoConfig::kCETVLabel) + 1); |
637 hkdf_input.append(reinterpret_cast<char*>(&connection_id), | 638 hkdf_input.append(reinterpret_cast<char*>(&connection_id), |
638 sizeof(connection_id)); | 639 sizeof(connection_id)); |
639 hkdf_input.append(client_hello_serialized.data(), | 640 hkdf_input.append(client_hello_serialized.data(), |
640 client_hello_serialized.length()); | 641 client_hello_serialized.length()); |
641 hkdf_input.append(requested_config->serialized); | 642 hkdf_input.append(requested_config->serialized); |
642 | 643 |
643 CrypterPair crypters; | 644 CrypterPair crypters; |
644 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, | 645 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, |
645 info.client_nonce, info.server_nonce, | 646 params->aead, |
646 hkdf_input, CryptoUtils::SERVER, &crypters)) { | 647 info.client_nonce, |
| 648 info.server_nonce, |
| 649 hkdf_input, |
| 650 CryptoUtils::SERVER, |
| 651 &crypters)) { |
647 *error_details = "Symmetric key setup failed"; | 652 *error_details = "Symmetric key setup failed"; |
648 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 653 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
649 } | 654 } |
650 | 655 |
651 scoped_ptr<QuicData> cetv_plaintext(crypters.decrypter->DecryptPacket( | 656 scoped_ptr<QuicData> cetv_plaintext( |
652 0 /* sequence number */, StringPiece() /* associated data */, | 657 crypters.decrypter->DecryptPacket(0 /* sequence number */, |
653 cetv_ciphertext)); | 658 StringPiece() /* associated data */, |
| 659 cetv_ciphertext)); |
654 if (!cetv_plaintext.get()) { | 660 if (!cetv_plaintext.get()) { |
655 *error_details = "CETV decryption failure"; | 661 *error_details = "CETV decryption failure"; |
656 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 662 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
657 } | 663 } |
658 | 664 |
659 scoped_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage( | 665 scoped_ptr<CryptoHandshakeMessage> cetv( |
660 cetv_plaintext->AsStringPiece())); | 666 CryptoFramer::ParseMessage(cetv_plaintext->AsStringPiece())); |
661 if (!cetv.get()) { | 667 if (!cetv.get()) { |
662 *error_details = "CETV parse error"; | 668 *error_details = "CETV parse error"; |
663 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 669 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
664 } | 670 } |
665 | 671 |
666 StringPiece key, signature; | 672 StringPiece key, signature; |
667 if (cetv->GetStringPiece(kCIDK, &key) && | 673 if (cetv->GetStringPiece(kCIDK, &key) && |
668 cetv->GetStringPiece(kCIDS, &signature)) { | 674 cetv->GetStringPiece(kCIDS, &signature)) { |
669 if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { | 675 if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { |
670 *error_details = "ChannelID signature failure"; | 676 *error_details = "ChannelID signature failure"; |
671 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 677 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
672 } | 678 } |
673 | 679 |
674 params->channel_id = key.as_string(); | 680 params->channel_id = key.as_string(); |
675 } | 681 } |
676 } | 682 } |
677 | 683 |
678 string hkdf_input; | 684 string hkdf_input; |
679 size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; | 685 size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; |
680 hkdf_input.reserve(label_len + hkdf_suffix.size()); | 686 hkdf_input.reserve(label_len + hkdf_suffix.size()); |
681 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); | 687 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); |
682 hkdf_input.append(hkdf_suffix); | 688 hkdf_input.append(hkdf_suffix); |
683 | 689 |
684 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, | 690 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, |
685 info.client_nonce, info.server_nonce, hkdf_input, | 691 params->aead, |
| 692 info.client_nonce, |
| 693 info.server_nonce, |
| 694 hkdf_input, |
686 CryptoUtils::SERVER, | 695 CryptoUtils::SERVER, |
687 ¶ms->initial_crypters)) { | 696 ¶ms->initial_crypters)) { |
688 *error_details = "Symmetric key setup failed"; | 697 *error_details = "Symmetric key setup failed"; |
689 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 698 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
690 } | 699 } |
691 | 700 |
692 string forward_secure_public_value; | 701 string forward_secure_public_value; |
693 if (ephemeral_key_source_.get()) { | 702 if (ephemeral_key_source_.get()) { |
694 params->forward_secure_premaster_secret = | 703 params->forward_secure_premaster_secret = |
695 ephemeral_key_source_->CalculateForwardSecureKey( | 704 ephemeral_key_source_->CalculateForwardSecureKey( |
696 key_exchange, rand, clock->ApproximateNow(), public_value, | 705 key_exchange, |
| 706 rand, |
| 707 clock->ApproximateNow(), |
| 708 public_value, |
697 &forward_secure_public_value); | 709 &forward_secure_public_value); |
698 } else { | 710 } else { |
699 scoped_ptr<KeyExchange> forward_secure_key_exchange( | 711 scoped_ptr<KeyExchange> forward_secure_key_exchange( |
700 key_exchange->NewKeyPair(rand)); | 712 key_exchange->NewKeyPair(rand)); |
701 forward_secure_public_value = | 713 forward_secure_public_value = |
702 forward_secure_key_exchange->public_value().as_string(); | 714 forward_secure_key_exchange->public_value().as_string(); |
703 if (!forward_secure_key_exchange->CalculateSharedKey( | 715 if (!forward_secure_key_exchange->CalculateSharedKey( |
704 public_value, ¶ms->forward_secure_premaster_secret)) { | 716 public_value, ¶ms->forward_secure_premaster_secret)) { |
705 *error_details = "Invalid public value"; | 717 *error_details = "Invalid public value"; |
706 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 718 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
707 } | 719 } |
708 } | 720 } |
709 | 721 |
710 string forward_secure_hkdf_input; | 722 string forward_secure_hkdf_input; |
711 label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; | 723 label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; |
712 forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size()); | 724 forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size()); |
713 forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, | 725 forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, |
714 label_len); | 726 label_len); |
715 forward_secure_hkdf_input.append(hkdf_suffix); | 727 forward_secure_hkdf_input.append(hkdf_suffix); |
716 | 728 |
717 if (!CryptoUtils::DeriveKeys( | 729 if (!CryptoUtils::DeriveKeys(params->forward_secure_premaster_secret, |
718 params->forward_secure_premaster_secret, params->aead, | 730 params->aead, |
719 info.client_nonce, info.server_nonce, forward_secure_hkdf_input, | 731 info.client_nonce, |
720 CryptoUtils::SERVER, ¶ms->forward_secure_crypters)) { | 732 info.server_nonce, |
| 733 forward_secure_hkdf_input, |
| 734 CryptoUtils::SERVER, |
| 735 ¶ms->forward_secure_crypters)) { |
721 *error_details = "Symmetric key setup failed"; | 736 *error_details = "Symmetric key setup failed"; |
722 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 737 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
723 } | 738 } |
724 | 739 |
725 out->set_tag(kSHLO); | 740 out->set_tag(kSHLO); |
726 QuicTagVector supported_version_tags; | 741 QuicTagVector supported_version_tags; |
727 for (size_t i = 0; i < supported_versions.size(); ++i) { | 742 for (size_t i = 0; i < supported_versions.size(); ++i) { |
728 supported_version_tags.push_back | 743 supported_version_tags.push_back( |
729 (QuicVersionToQuicTag(supported_versions[i])); | 744 QuicVersionToQuicTag(supported_versions[i])); |
730 } | 745 } |
731 out->SetVector(kVER, supported_version_tags); | 746 out->SetVector(kVER, supported_version_tags); |
732 out->SetStringPiece(kSourceAddressTokenTag, | 747 out->SetStringPiece( |
733 NewSourceAddressToken( | 748 kSourceAddressTokenTag, |
734 *requested_config, | 749 NewSourceAddressToken(*requested_config, client_address, rand, info.now)); |
735 client_address, rand, | |
736 info.now)); | |
737 QuicSocketAddressCoder address_coder(client_address); | 750 QuicSocketAddressCoder address_coder(client_address); |
738 out->SetStringPiece(kCADR, address_coder.Encode()); | 751 out->SetStringPiece(kCADR, address_coder.Encode()); |
739 out->SetStringPiece(kPUBS, forward_secure_public_value); | 752 out->SetStringPiece(kPUBS, forward_secure_public_value); |
740 | 753 |
741 // Set initial receive window for flow control. | 754 // Set initial receive window for flow control. |
742 out->SetValue(kIFCW, initial_flow_control_window_bytes); | 755 out->SetValue(kIFCW, initial_flow_control_window_bytes); |
743 | 756 |
744 return QUIC_NO_ERROR; | 757 return QUIC_NO_ERROR; |
745 } | 758 } |
746 | 759 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 // Primary times and priorities are equal, sort by config id. | 792 // Primary times and priorities are equal, sort by config id. |
780 return a->id < b->id; | 793 return a->id < b->id; |
781 } | 794 } |
782 } | 795 } |
783 | 796 |
784 void QuicCryptoServerConfig::SelectNewPrimaryConfig( | 797 void QuicCryptoServerConfig::SelectNewPrimaryConfig( |
785 const QuicWallTime now) const { | 798 const QuicWallTime now) const { |
786 vector<scoped_refptr<Config> > configs; | 799 vector<scoped_refptr<Config> > configs; |
787 configs.reserve(configs_.size()); | 800 configs.reserve(configs_.size()); |
788 | 801 |
789 for (ConfigMap::const_iterator it = configs_.begin(); | 802 for (ConfigMap::const_iterator it = configs_.begin(); it != configs_.end(); |
790 it != configs_.end(); ++it) { | 803 ++it) { |
791 // TODO(avd) Exclude expired configs? | 804 // TODO(avd) Exclude expired configs? |
792 configs.push_back(it->second); | 805 configs.push_back(it->second); |
793 } | 806 } |
794 | 807 |
795 if (configs.empty()) { | 808 if (configs.empty()) { |
796 if (primary_config_.get()) { | 809 if (primary_config_.get()) { |
797 LOG(DFATAL) << "No valid QUIC server config. Keeping the current config."; | 810 LOG(DFATAL) << "No valid QUIC server config. Keeping the current config."; |
798 } else { | 811 } else { |
799 LOG(DFATAL) << "No valid QUIC server config."; | 812 LOG(DFATAL) << "No valid QUIC server config."; |
800 } | 813 } |
(...skipping 28 matching lines...) Expand all Loading... |
829 next_config_promotion_time_ = config->primary_time; | 842 next_config_promotion_time_ = config->primary_time; |
830 } | 843 } |
831 | 844 |
832 if (primary_config_.get()) { | 845 if (primary_config_.get()) { |
833 primary_config_->is_primary = false; | 846 primary_config_->is_primary = false; |
834 } | 847 } |
835 primary_config_ = new_primary; | 848 primary_config_ = new_primary; |
836 new_primary->is_primary = true; | 849 new_primary->is_primary = true; |
837 DVLOG(1) << "New primary config. orbit: " | 850 DVLOG(1) << "New primary config. orbit: " |
838 << base::HexEncode( | 851 << base::HexEncode( |
839 reinterpret_cast<const char*>(primary_config_->orbit), | 852 reinterpret_cast<const char*>(primary_config_->orbit), |
840 kOrbitSize); | 853 kOrbitSize); |
841 if (primary_config_changed_cb_.get() != NULL) { | 854 if (primary_config_changed_cb_.get() != NULL) { |
842 primary_config_changed_cb_->Run(primary_config_->id); | 855 primary_config_changed_cb_->Run(primary_config_->id); |
843 } | 856 } |
844 | 857 |
845 return; | 858 return; |
846 } | 859 } |
847 | 860 |
848 // All config's primary times are in the past. We should make the most recent | 861 // All config's primary times are in the past. We should make the most recent |
849 // and highest priority candidate primary. | 862 // and highest priority candidate primary. |
850 scoped_refptr<Config> new_primary(best_candidate); | 863 scoped_refptr<Config> new_primary(best_candidate); |
851 if (primary_config_.get()) { | 864 if (primary_config_.get()) { |
852 primary_config_->is_primary = false; | 865 primary_config_->is_primary = false; |
853 } | 866 } |
854 primary_config_ = new_primary; | 867 primary_config_ = new_primary; |
855 new_primary->is_primary = true; | 868 new_primary->is_primary = true; |
856 DVLOG(1) << "New primary config. orbit: " | 869 DVLOG(1) << "New primary config. orbit: " |
857 << base::HexEncode( | 870 << base::HexEncode( |
858 reinterpret_cast<const char*>(primary_config_->orbit), | 871 reinterpret_cast<const char*>(primary_config_->orbit), |
859 kOrbitSize) | 872 kOrbitSize) |
860 << " scid: " << base::HexEncode(primary_config_->id.data(), | 873 << " scid: " << base::HexEncode(primary_config_->id.data(), |
861 primary_config_->id.size()); | 874 primary_config_->id.size()); |
862 next_config_promotion_time_ = QuicWallTime::Zero(); | 875 next_config_promotion_time_ = QuicWallTime::Zero(); |
863 if (primary_config_changed_cb_.get() != NULL) { | 876 if (primary_config_changed_cb_.get() != NULL) { |
864 primary_config_changed_cb_->Run(primary_config_->id); | 877 primary_config_changed_cb_->Run(primary_config_->id); |
865 } | 878 } |
866 } | 879 } |
867 | 880 |
868 void QuicCryptoServerConfig::EvaluateClientHello( | 881 void QuicCryptoServerConfig::EvaluateClientHello( |
869 const uint8* primary_orbit, | 882 const uint8* primary_orbit, |
870 scoped_refptr<Config> requested_config, | 883 scoped_refptr<Config> requested_config, |
871 ValidateClientHelloResultCallback::Result* client_hello_state, | 884 ValidateClientHelloResultCallback::Result* client_hello_state, |
872 ValidateClientHelloResultCallback* done_cb) const { | 885 ValidateClientHelloResultCallback* done_cb) const { |
873 ValidateClientHelloHelper helper(client_hello_state, done_cb); | 886 ValidateClientHelloHelper helper(client_hello_state, done_cb); |
874 | 887 |
875 const CryptoHandshakeMessage& client_hello = | 888 const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello; |
876 client_hello_state->client_hello; | |
877 ClientHelloInfo* info = &(client_hello_state->info); | 889 ClientHelloInfo* info = &(client_hello_state->info); |
878 | 890 |
879 if (client_hello.size() < kClientHelloMinimumSize) { | 891 if (client_hello.size() < kClientHelloMinimumSize) { |
880 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, | 892 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, |
881 "Client hello too small"); | 893 "Client hello too small"); |
882 return; | 894 return; |
883 } | 895 } |
884 | 896 |
885 if (client_hello.GetStringPiece(kSNI, &info->sni) && | 897 if (client_hello.GetStringPiece(kSNI, &info->sni) && |
886 !CryptoUtils::IsValidSNI(info->sni)) { | 898 !CryptoUtils::IsValidSNI(info->sni)) { |
887 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 899 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
888 "Invalid SNI name"); | 900 "Invalid SNI name"); |
889 return; | 901 return; |
890 } | 902 } |
891 | 903 |
892 StringPiece srct; | 904 StringPiece srct; |
893 if (requested_config.get() != NULL && | 905 if (requested_config.get() != NULL && |
894 client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && | 906 client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && |
895 ValidateSourceAddressToken(*requested_config, | 907 ValidateSourceAddressToken( |
896 srct, | 908 *requested_config, srct, info->client_ip, info->now)) { |
897 info->client_ip, | |
898 info->now)) { | |
899 info->valid_source_address_token = true; | 909 info->valid_source_address_token = true; |
900 } else { | 910 } else { |
901 // No server config with the requested ID, or no valid source address token. | 911 // No server config with the requested ID, or no valid source address token. |
902 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 912 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
903 return; | 913 return; |
904 } | 914 } |
905 | 915 |
906 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && | 916 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && |
907 info->client_nonce.size() == kNonceSize) { | 917 info->client_nonce.size() == kNonceSize) { |
908 info->client_nonce_well_formed = true; | 918 info->client_nonce_well_formed = true; |
(...skipping 24 matching lines...) Expand all Loading... |
933 StrikeRegisterClient* strike_register_client; | 943 StrikeRegisterClient* strike_register_client; |
934 { | 944 { |
935 base::AutoLock locked(strike_register_client_lock_); | 945 base::AutoLock locked(strike_register_client_lock_); |
936 | 946 |
937 if (strike_register_client_.get() == NULL) { | 947 if (strike_register_client_.get() == NULL) { |
938 strike_register_client_.reset(new LocalStrikeRegisterClient( | 948 strike_register_client_.reset(new LocalStrikeRegisterClient( |
939 strike_register_max_entries_, | 949 strike_register_max_entries_, |
940 static_cast<uint32>(info->now.ToUNIXSeconds()), | 950 static_cast<uint32>(info->now.ToUNIXSeconds()), |
941 strike_register_window_secs_, | 951 strike_register_window_secs_, |
942 primary_orbit, | 952 primary_orbit, |
943 strike_register_no_startup_period_ ? | 953 strike_register_no_startup_period_ |
944 StrikeRegister::NO_STARTUP_PERIOD_NEEDED : | 954 ? StrikeRegister::NO_STARTUP_PERIOD_NEEDED |
945 StrikeRegister::DENY_REQUESTS_AT_STARTUP)); | 955 : StrikeRegister::DENY_REQUESTS_AT_STARTUP)); |
946 } | 956 } |
947 strike_register_client = strike_register_client_.get(); | 957 strike_register_client = strike_register_client_.get(); |
948 } | 958 } |
949 | 959 |
950 strike_register_client->VerifyNonceIsValidAndUnique( | 960 strike_register_client->VerifyNonceIsValidAndUnique( |
951 info->client_nonce, | 961 info->client_nonce, |
952 info->now, | 962 info->now, |
953 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); | 963 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); |
954 helper.StartedAsyncCallback(); | 964 helper.StartedAsyncCallback(); |
955 } | 965 } |
956 | 966 |
957 void QuicCryptoServerConfig::BuildRejection( | 967 void QuicCryptoServerConfig::BuildRejection( |
958 const Config& config, | 968 const Config& config, |
959 const CryptoHandshakeMessage& client_hello, | 969 const CryptoHandshakeMessage& client_hello, |
960 const ClientHelloInfo& info, | 970 const ClientHelloInfo& info, |
961 QuicRandom* rand, | 971 QuicRandom* rand, |
962 CryptoHandshakeMessage* out) const { | 972 CryptoHandshakeMessage* out) const { |
963 out->set_tag(kREJ); | 973 out->set_tag(kREJ); |
964 out->SetStringPiece(kSCFG, config.serialized); | 974 out->SetStringPiece(kSCFG, config.serialized); |
965 out->SetStringPiece(kSourceAddressTokenTag, | 975 out->SetStringPiece( |
966 NewSourceAddressToken( | 976 kSourceAddressTokenTag, |
967 config, | 977 NewSourceAddressToken(config, info.client_ip, rand, info.now)); |
968 info.client_ip, | |
969 rand, | |
970 info.now)); | |
971 if (replay_protection_) { | 978 if (replay_protection_) { |
972 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); | 979 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); |
973 } | 980 } |
974 | 981 |
975 // The client may have requested a certificate chain. | 982 // The client may have requested a certificate chain. |
976 const QuicTag* their_proof_demands; | 983 const QuicTag* their_proof_demands; |
977 size_t num_their_proof_demands; | 984 size_t num_their_proof_demands; |
978 | 985 |
979 if (proof_source_.get() == NULL || | 986 if (proof_source_.get() == NULL || |
980 client_hello.GetTaglist(kPDMD, &their_proof_demands, | 987 client_hello.GetTaglist(kPDMD, |
981 &num_their_proof_demands) != | 988 &their_proof_demands, |
982 QUIC_NO_ERROR) { | 989 &num_their_proof_demands) != QUIC_NO_ERROR) { |
983 return; | 990 return; |
984 } | 991 } |
985 | 992 |
986 bool x509_supported = false, x509_ecdsa_supported = false; | 993 bool x509_supported = false, x509_ecdsa_supported = false; |
987 for (size_t i = 0; i < num_their_proof_demands; i++) { | 994 for (size_t i = 0; i < num_their_proof_demands; i++) { |
988 switch (their_proof_demands[i]) { | 995 switch (their_proof_demands[i]) { |
989 case kX509: | 996 case kX509: |
990 x509_supported = true; | 997 x509_supported = true; |
991 x509_ecdsa_supported = true; | 998 x509_ecdsa_supported = true; |
992 break; | 999 break; |
993 case kX59R: | 1000 case kX59R: |
994 x509_supported = true; | 1001 x509_supported = true; |
995 break; | 1002 break; |
996 } | 1003 } |
997 } | 1004 } |
998 | 1005 |
999 if (!x509_supported) { | 1006 if (!x509_supported) { |
1000 return; | 1007 return; |
1001 } | 1008 } |
1002 | 1009 |
1003 const vector<string>* certs; | 1010 const vector<string>* certs; |
1004 string signature; | 1011 string signature; |
1005 if (!proof_source_->GetProof(info.sni.as_string(), config.serialized, | 1012 if (!proof_source_->GetProof(info.sni.as_string(), |
1006 x509_ecdsa_supported, &certs, &signature)) { | 1013 config.serialized, |
| 1014 x509_ecdsa_supported, |
| 1015 &certs, |
| 1016 &signature)) { |
1007 return; | 1017 return; |
1008 } | 1018 } |
1009 | 1019 |
1010 StringPiece their_common_set_hashes; | 1020 StringPiece their_common_set_hashes; |
1011 StringPiece their_cached_cert_hashes; | 1021 StringPiece their_cached_cert_hashes; |
1012 client_hello.GetStringPiece(kCCS, &their_common_set_hashes); | 1022 client_hello.GetStringPiece(kCCS, &their_common_set_hashes); |
1013 client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes); | 1023 client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes); |
1014 | 1024 |
1015 const string compressed = CertCompressor::CompressChain( | 1025 const string compressed = |
1016 *certs, their_common_set_hashes, their_cached_cert_hashes, | 1026 CertCompressor::CompressChain(*certs, |
1017 config.common_cert_sets); | 1027 their_common_set_hashes, |
| 1028 their_cached_cert_hashes, |
| 1029 config.common_cert_sets); |
1018 | 1030 |
1019 // kREJOverheadBytes is a very rough estimate of how much of a REJ | 1031 // kREJOverheadBytes is a very rough estimate of how much of a REJ |
1020 // message is taken up by things other than the certificates. | 1032 // message is taken up by things other than the certificates. |
1021 // STK: 56 bytes | 1033 // STK: 56 bytes |
1022 // SNO: 56 bytes | 1034 // SNO: 56 bytes |
1023 // SCFG | 1035 // SCFG |
1024 // SCID: 16 bytes | 1036 // SCID: 16 bytes |
1025 // PUBS: 38 bytes | 1037 // PUBS: 38 bytes |
1026 const size_t kREJOverheadBytes = 166; | 1038 const size_t kREJOverheadBytes = 166; |
1027 // kMultiplier is the multiple of the CHLO message size that a REJ message | 1039 // kMultiplier is the multiple of the CHLO message size that a REJ message |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 StrikeRegisterClient* strike_register_client; | 1128 StrikeRegisterClient* strike_register_client; |
1117 { | 1129 { |
1118 base::AutoLock locked(strike_register_client_lock_); | 1130 base::AutoLock locked(strike_register_client_lock_); |
1119 strike_register_client = strike_register_client_.get(); | 1131 strike_register_client = strike_register_client_.get(); |
1120 } | 1132 } |
1121 | 1133 |
1122 if (strike_register_client != NULL && | 1134 if (strike_register_client != NULL && |
1123 !strike_register_client->IsKnownOrbit(orbit)) { | 1135 !strike_register_client->IsKnownOrbit(orbit)) { |
1124 LOG(WARNING) | 1136 LOG(WARNING) |
1125 << "Rejecting server config with orbit that the strike register " | 1137 << "Rejecting server config with orbit that the strike register " |
1126 "client doesn't know about."; | 1138 "client doesn't know about."; |
1127 return NULL; | 1139 return NULL; |
1128 } | 1140 } |
1129 } | 1141 } |
1130 | 1142 |
1131 if (kexs_len != protobuf->key_size()) { | 1143 if (kexs_len != protobuf->key_size()) { |
1132 LOG(WARNING) << "Server config has " << kexs_len | 1144 LOG(WARNING) << "Server config has " << kexs_len |
1133 << " key exchange methods configured, but " | 1145 << " key exchange methods configured, but " |
1134 << protobuf->key_size() << " private keys"; | 1146 << protobuf->key_size() << " private keys"; |
1135 return NULL; | 1147 return NULL; |
1136 } | 1148 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1185 return NULL; | 1197 return NULL; |
1186 } | 1198 } |
1187 break; | 1199 break; |
1188 default: | 1200 default: |
1189 LOG(WARNING) << "Server config message contains unknown key exchange " | 1201 LOG(WARNING) << "Server config message contains unknown key exchange " |
1190 "method: " << tag; | 1202 "method: " << tag; |
1191 return NULL; | 1203 return NULL; |
1192 } | 1204 } |
1193 | 1205 |
1194 for (vector<KeyExchange*>::const_iterator i = config->key_exchanges.begin(); | 1206 for (vector<KeyExchange*>::const_iterator i = config->key_exchanges.begin(); |
1195 i != config->key_exchanges.end(); ++i) { | 1207 i != config->key_exchanges.end(); |
| 1208 ++i) { |
1196 if ((*i)->tag() == tag) { | 1209 if ((*i)->tag() == tag) { |
1197 LOG(WARNING) << "Duplicate key exchange in config: " << tag; | 1210 LOG(WARNING) << "Duplicate key exchange in config: " << tag; |
1198 return NULL; | 1211 return NULL; |
1199 } | 1212 } |
1200 } | 1213 } |
1201 | 1214 |
1202 config->key_exchanges.push_back(ka.release()); | 1215 config->key_exchanges.push_back(ka.release()); |
1203 } | 1216 } |
1204 | 1217 |
1205 return config; | 1218 return config; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 DCHECK(!server_nonce_strike_register_.get()); | 1279 DCHECK(!server_nonce_strike_register_.get()); |
1267 server_nonce_strike_register_window_secs_ = window_secs; | 1280 server_nonce_strike_register_window_secs_ = window_secs; |
1268 } | 1281 } |
1269 | 1282 |
1270 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( | 1283 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( |
1271 PrimaryConfigChangedCallback* cb) { | 1284 PrimaryConfigChangedCallback* cb) { |
1272 base::AutoLock locked(configs_lock_); | 1285 base::AutoLock locked(configs_lock_); |
1273 primary_config_changed_cb_.reset(cb); | 1286 primary_config_changed_cb_.reset(cb); |
1274 } | 1287 } |
1275 | 1288 |
1276 string QuicCryptoServerConfig::NewSourceAddressToken( | 1289 string QuicCryptoServerConfig::NewSourceAddressToken(const Config& config, |
1277 const Config& config, | 1290 const IPEndPoint& ip, |
1278 const IPEndPoint& ip, | 1291 QuicRandom* rand, |
1279 QuicRandom* rand, | 1292 QuicWallTime now) const { |
1280 QuicWallTime now) const { | |
1281 SourceAddressToken source_address_token; | 1293 SourceAddressToken source_address_token; |
1282 source_address_token.set_ip(IPAddressToPackedString(ip.address())); | 1294 source_address_token.set_ip(IPAddressToPackedString(ip.address())); |
1283 source_address_token.set_timestamp(now.ToUNIXSeconds()); | 1295 source_address_token.set_timestamp(now.ToUNIXSeconds()); |
1284 | 1296 |
1285 return config.source_address_token_boxer->Box( | 1297 return config.source_address_token_boxer->Box( |
1286 rand, source_address_token.SerializeAsString()); | 1298 rand, source_address_token.SerializeAsString()); |
1287 } | 1299 } |
1288 | 1300 |
1289 bool QuicCryptoServerConfig::ValidateSourceAddressToken( | 1301 bool QuicCryptoServerConfig::ValidateSourceAddressToken( |
1290 const Config& config, | 1302 const Config& config, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1362 | 1374 |
1363 if (plaintext.size() != kServerNoncePlaintextSize) { | 1375 if (plaintext.size() != kServerNoncePlaintextSize) { |
1364 // This should never happen because the value decrypted correctly. | 1376 // This should never happen because the value decrypted correctly. |
1365 LOG(DFATAL) << "Seemingly valid server nonce had incorrect length."; | 1377 LOG(DFATAL) << "Seemingly valid server nonce had incorrect length."; |
1366 return false; | 1378 return false; |
1367 } | 1379 } |
1368 | 1380 |
1369 uint8 server_nonce[32]; | 1381 uint8 server_nonce[32]; |
1370 memcpy(server_nonce, plaintext.data(), 4); | 1382 memcpy(server_nonce, plaintext.data(), 4); |
1371 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); | 1383 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); |
1372 memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, | 1384 memcpy( |
1373 20); | 1385 server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, 20); |
1374 COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), | 1386 COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), |
1375 bad_nonce_buffer_length); | 1387 bad_nonce_buffer_length); |
1376 | 1388 |
1377 bool is_unique; | 1389 bool is_unique; |
1378 { | 1390 { |
1379 base::AutoLock auto_lock(server_nonce_strike_register_lock_); | 1391 base::AutoLock auto_lock(server_nonce_strike_register_lock_); |
1380 if (server_nonce_strike_register_.get() == NULL) { | 1392 if (server_nonce_strike_register_.get() == NULL) { |
1381 server_nonce_strike_register_.reset(new StrikeRegister( | 1393 server_nonce_strike_register_.reset( |
1382 server_nonce_strike_register_max_entries_, | 1394 new StrikeRegister(server_nonce_strike_register_max_entries_, |
1383 static_cast<uint32>(now.ToUNIXSeconds()), | 1395 static_cast<uint32>(now.ToUNIXSeconds()), |
1384 server_nonce_strike_register_window_secs_, server_nonce_orbit_, | 1396 server_nonce_strike_register_window_secs_, |
1385 StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); | 1397 server_nonce_orbit_, |
| 1398 StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); |
1386 } | 1399 } |
1387 is_unique = server_nonce_strike_register_->Insert( | 1400 is_unique = server_nonce_strike_register_->Insert( |
1388 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); | 1401 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); |
1389 } | 1402 } |
1390 | 1403 |
1391 return is_unique; | 1404 return is_unique; |
1392 } | 1405 } |
1393 | 1406 |
1394 QuicCryptoServerConfig::Config::Config() | 1407 QuicCryptoServerConfig::Config::Config() |
1395 : channel_id_enabled(false), | 1408 : channel_id_enabled(false), |
1396 is_primary(false), | 1409 is_primary(false), |
1397 primary_time(QuicWallTime::Zero()), | 1410 primary_time(QuicWallTime::Zero()), |
1398 priority(0), | 1411 priority(0), |
1399 source_address_token_boxer(NULL) {} | 1412 source_address_token_boxer(NULL) { |
| 1413 } |
1400 | 1414 |
1401 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } | 1415 QuicCryptoServerConfig::Config::~Config() { |
| 1416 STLDeleteElements(&key_exchanges); |
| 1417 } |
1402 | 1418 |
1403 } // namespace net | 1419 } // namespace net |
OLD | NEW |