OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/crypto_server_config.h" | 5 #include "net/quic/crypto/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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 // static | 43 // static |
44 const char QuicCryptoServerConfig::TESTING[] = "secret string for testing"; | 44 const char QuicCryptoServerConfig::TESTING[] = "secret string for testing"; |
45 | 45 |
46 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() | 46 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() |
47 : expiry_time(QuicWallTime::Zero()), | 47 : expiry_time(QuicWallTime::Zero()), |
48 channel_id_enabled(false) { } | 48 channel_id_enabled(false) { } |
49 | 49 |
50 QuicCryptoServerConfig::QuicCryptoServerConfig( | 50 QuicCryptoServerConfig::QuicCryptoServerConfig( |
51 StringPiece source_address_token_secret, | 51 StringPiece source_address_token_secret, |
52 QuicRandom* rand) | 52 QuicRandom* rand) |
53 : configs_lock_(), | 53 : replay_protection_(true), |
| 54 configs_lock_(), |
54 primary_config_(NULL), | 55 primary_config_(NULL), |
55 next_config_promotion_time_(QuicWallTime::Zero()), | 56 next_config_promotion_time_(QuicWallTime::Zero()), |
56 strike_register_lock_(), | 57 strike_register_lock_(), |
57 server_nonce_strike_register_lock_(), | 58 server_nonce_strike_register_lock_(), |
58 strike_register_max_entries_(1 << 10), | 59 strike_register_max_entries_(1 << 10), |
59 strike_register_window_secs_(600), | 60 strike_register_window_secs_(600), |
60 source_address_token_future_secs_(3600), | 61 source_address_token_future_secs_(3600), |
61 source_address_token_lifetime_secs_(86400), | 62 source_address_token_lifetime_secs_(86400), |
62 server_nonce_strike_register_max_entries_(1 << 10), | 63 server_nonce_strike_register_max_entries_(1 << 10), |
63 server_nonce_strike_register_window_secs_(120) { | 64 server_nonce_strike_register_window_secs_(120) { |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 *error_details = "Invalid SNI name"; | 613 *error_details = "Invalid SNI name"; |
613 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 614 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
614 } | 615 } |
615 | 616 |
616 // The client nonce is used first to try and establish uniqueness. | 617 // The client nonce is used first to try and establish uniqueness. |
617 bool unique_by_strike_register = false; | 618 bool unique_by_strike_register = false; |
618 | 619 |
619 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && | 620 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && |
620 info->client_nonce.size() == kNonceSize) { | 621 info->client_nonce.size() == kNonceSize) { |
621 info->client_nonce_well_formed = true; | 622 info->client_nonce_well_formed = true; |
622 base::AutoLock auto_lock(strike_register_lock_); | 623 if (replay_protection_) { |
| 624 base::AutoLock auto_lock(strike_register_lock_); |
623 | 625 |
624 if (strike_register_.get() == NULL) { | 626 if (strike_register_.get() == NULL) { |
625 strike_register_.reset(new StrikeRegister( | 627 strike_register_.reset(new StrikeRegister( |
626 strike_register_max_entries_, | 628 strike_register_max_entries_, |
627 static_cast<uint32>(info->now.ToUNIXSeconds()), | 629 static_cast<uint32>(info->now.ToUNIXSeconds()), |
628 strike_register_window_secs_, | 630 strike_register_window_secs_, |
629 orbit, | 631 orbit, |
630 StrikeRegister::DENY_REQUESTS_AT_STARTUP)); | 632 StrikeRegister::DENY_REQUESTS_AT_STARTUP)); |
| 633 } |
| 634 |
| 635 unique_by_strike_register = strike_register_->Insert( |
| 636 reinterpret_cast<const uint8*>(info->client_nonce.data()), |
| 637 static_cast<uint32>(info->now.ToUNIXSeconds())); |
631 } | 638 } |
632 unique_by_strike_register = strike_register_->Insert( | |
633 reinterpret_cast<const uint8*>(info->client_nonce.data()), | |
634 static_cast<uint32>(info->now.ToUNIXSeconds())); | |
635 } | 639 } |
636 | 640 |
637 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); | 641 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); |
638 | 642 |
639 // If the client nonce didn't establish uniqueness then an echoed server | 643 // If the client nonce didn't establish uniqueness then an echoed server |
640 // nonce may. | 644 // nonce may. |
641 bool unique_by_server_nonce = false; | 645 bool unique_by_server_nonce = false; |
642 if (!unique_by_strike_register && !info->server_nonce.empty()) { | 646 if (replay_protection_ && |
| 647 !unique_by_strike_register && |
| 648 !info->server_nonce.empty()) { |
643 unique_by_server_nonce = ValidateServerNonce(info->server_nonce, info->now); | 649 unique_by_server_nonce = ValidateServerNonce(info->server_nonce, info->now); |
644 } | 650 } |
645 | 651 |
646 info->unique = unique_by_strike_register || unique_by_server_nonce; | 652 info->unique = !replay_protection_ || |
| 653 unique_by_strike_register || |
| 654 unique_by_server_nonce; |
647 | 655 |
648 return QUIC_NO_ERROR; | 656 return QUIC_NO_ERROR; |
649 } | 657 } |
650 | 658 |
651 void QuicCryptoServerConfig::BuildRejection( | 659 void QuicCryptoServerConfig::BuildRejection( |
652 const scoped_refptr<Config>& config, | 660 const scoped_refptr<Config>& config, |
653 const CryptoHandshakeMessage& client_hello, | 661 const CryptoHandshakeMessage& client_hello, |
654 const ClientHelloInfo& info, | 662 const ClientHelloInfo& info, |
655 QuicRandom* rand, | 663 QuicRandom* rand, |
656 CryptoHandshakeMessage* out) const { | 664 CryptoHandshakeMessage* out) const { |
657 out->set_tag(kREJ); | 665 out->set_tag(kREJ); |
658 out->SetStringPiece(kSCFG, config->serialized); | 666 out->SetStringPiece(kSCFG, config->serialized); |
659 out->SetStringPiece(kSourceAddressTokenTag, | 667 out->SetStringPiece(kSourceAddressTokenTag, |
660 NewSourceAddressToken(info.client_ip, rand, info.now)); | 668 NewSourceAddressToken(info.client_ip, rand, info.now)); |
661 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); | 669 if (replay_protection_) { |
| 670 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); |
| 671 } |
662 | 672 |
663 // The client may have requested a certificate chain. | 673 // The client may have requested a certificate chain. |
664 const QuicTag* their_proof_demands; | 674 const QuicTag* their_proof_demands; |
665 size_t num_their_proof_demands; | 675 size_t num_their_proof_demands; |
666 | 676 |
667 if (proof_source_.get() != NULL && !info.sni.empty() && | 677 if (proof_source_.get() != NULL && !info.sni.empty() && |
668 client_hello.GetTaglist(kPDMD, &their_proof_demands, | 678 client_hello.GetTaglist(kPDMD, &their_proof_demands, |
669 &num_their_proof_demands) == | 679 &num_their_proof_demands) == |
670 QUIC_NO_ERROR) { | 680 QUIC_NO_ERROR) { |
671 for (size_t i = 0; i < num_their_proof_demands; i++) { | 681 for (size_t i = 0; i < num_their_proof_demands; i++) { |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 | 872 |
863 void QuicCryptoServerConfig::SetProofSource(ProofSource* proof_source) { | 873 void QuicCryptoServerConfig::SetProofSource(ProofSource* proof_source) { |
864 proof_source_.reset(proof_source); | 874 proof_source_.reset(proof_source); |
865 } | 875 } |
866 | 876 |
867 void QuicCryptoServerConfig::SetEphemeralKeySource( | 877 void QuicCryptoServerConfig::SetEphemeralKeySource( |
868 EphemeralKeySource* ephemeral_key_source) { | 878 EphemeralKeySource* ephemeral_key_source) { |
869 ephemeral_key_source_.reset(ephemeral_key_source); | 879 ephemeral_key_source_.reset(ephemeral_key_source); |
870 } | 880 } |
871 | 881 |
| 882 void QuicCryptoServerConfig::set_replay_protection(bool on) { |
| 883 replay_protection_ = on; |
| 884 } |
| 885 |
872 void QuicCryptoServerConfig::set_strike_register_max_entries( | 886 void QuicCryptoServerConfig::set_strike_register_max_entries( |
873 uint32 max_entries) { | 887 uint32 max_entries) { |
874 base::AutoLock locker(strike_register_lock_); | 888 base::AutoLock locker(strike_register_lock_); |
875 DCHECK(!strike_register_.get()); | 889 DCHECK(!strike_register_.get()); |
876 strike_register_max_entries_ = max_entries; | 890 strike_register_max_entries_ = max_entries; |
877 } | 891 } |
878 | 892 |
879 void QuicCryptoServerConfig::set_strike_register_window_secs( | 893 void QuicCryptoServerConfig::set_strike_register_window_secs( |
880 uint32 window_secs) { | 894 uint32 window_secs) { |
881 base::AutoLock locker(strike_register_lock_); | 895 base::AutoLock locker(strike_register_lock_); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 } | 1036 } |
1023 | 1037 |
1024 QuicCryptoServerConfig::Config::Config() | 1038 QuicCryptoServerConfig::Config::Config() |
1025 : channel_id_enabled(false), | 1039 : channel_id_enabled(false), |
1026 is_primary(false), | 1040 is_primary(false), |
1027 primary_time(QuicWallTime::Zero()) {} | 1041 primary_time(QuicWallTime::Zero()) {} |
1028 | 1042 |
1029 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } | 1043 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } |
1030 | 1044 |
1031 } // namespace net | 1045 } // namespace net |
OLD | NEW |