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/core/crypto/quic_crypto_server_config.h" | 5 #include "net/quic/core/crypto/quic_crypto_server_config.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include "net/quic/core/quic_socket_address_coder.h" | 34 #include "net/quic/core/quic_socket_address_coder.h" |
35 #include "net/quic/core/quic_utils.h" | 35 #include "net/quic/core/quic_utils.h" |
36 #include "net/quic/platform/api/quic_bug_tracker.h" | 36 #include "net/quic/platform/api/quic_bug_tracker.h" |
37 #include "net/quic/platform/api/quic_clock.h" | 37 #include "net/quic/platform/api/quic_clock.h" |
38 #include "net/quic/platform/api/quic_hostname_utils.h" | 38 #include "net/quic/platform/api/quic_hostname_utils.h" |
39 #include "net/quic/platform/api/quic_logging.h" | 39 #include "net/quic/platform/api/quic_logging.h" |
40 #include "net/quic/platform/api/quic_reference_counted.h" | 40 #include "net/quic/platform/api/quic_reference_counted.h" |
41 #include "net/quic/platform/api/quic_text_utils.h" | 41 #include "net/quic/platform/api/quic_text_utils.h" |
42 #include "third_party/boringssl/src/include/openssl/sha.h" | 42 #include "third_party/boringssl/src/include/openssl/sha.h" |
43 | 43 |
44 using base::StringPiece; | |
45 using std::string; | 44 using std::string; |
46 | 45 |
47 namespace net { | 46 namespace net { |
48 | 47 |
49 namespace { | 48 namespace { |
50 | 49 |
51 // kMultiplier is the multiple of the CHLO message size that a REJ message | 50 // kMultiplier is the multiple of the CHLO message size that a REJ message |
52 // must stay under when the client doesn't present a valid source-address | 51 // must stay under when the client doesn't present a valid source-address |
53 // token. This is used to protect QUIC from amplification attacks. | 52 // token. This is used to protect QUIC from amplification attacks. |
54 // TODO(rch): Reduce this to 2 again once b/25933682 is fixed. | 53 // TODO(rch): Reduce this to 2 again once b/25933682 is fixed. |
55 const size_t kMultiplier = 3; | 54 const size_t kMultiplier = 3; |
56 | 55 |
57 const int kMaxTokenAddresses = 4; | 56 const int kMaxTokenAddresses = 4; |
58 | 57 |
59 string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) { | 58 string DeriveSourceAddressTokenKey( |
60 crypto::HKDF hkdf(source_address_token_secret, StringPiece() /* no salt */, | 59 QuicStringPiece source_address_token_secret) { |
61 "QUIC source address token key", | 60 crypto::HKDF hkdf( |
62 CryptoSecretBoxer::GetKeySize(), 0 /* no fixed IV needed */, | 61 source_address_token_secret, QuicStringPiece() /* no salt */, |
63 0 /* no subkey secret */); | 62 "QUIC source address token key", CryptoSecretBoxer::GetKeySize(), |
| 63 0 /* no fixed IV needed */, 0 /* no subkey secret */); |
64 return hkdf.server_write_key().as_string(); | 64 return hkdf.server_write_key().as_string(); |
65 } | 65 } |
66 | 66 |
67 } // namespace | 67 } // namespace |
68 | 68 |
69 class ValidateClientHelloHelper { | 69 class ValidateClientHelloHelper { |
70 public: | 70 public: |
71 // Note: stores a pointer to a unique_ptr, and std::moves the unique_ptr when | 71 // Note: stores a pointer to a unique_ptr, and std::moves the unique_ptr when |
72 // ValidationComplete is called. | 72 // ValidationComplete is called. |
73 ValidateClientHelloHelper( | 73 ValidateClientHelloHelper( |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 : expiry_time(QuicWallTime::Zero()), | 141 : expiry_time(QuicWallTime::Zero()), |
142 channel_id_enabled(false), | 142 channel_id_enabled(false), |
143 p256(false) {} | 143 p256(false) {} |
144 | 144 |
145 QuicCryptoServerConfig::ConfigOptions::ConfigOptions( | 145 QuicCryptoServerConfig::ConfigOptions::ConfigOptions( |
146 const ConfigOptions& other) = default; | 146 const ConfigOptions& other) = default; |
147 | 147 |
148 QuicCryptoServerConfig::ConfigOptions::~ConfigOptions() {} | 148 QuicCryptoServerConfig::ConfigOptions::~ConfigOptions() {} |
149 | 149 |
150 QuicCryptoServerConfig::QuicCryptoServerConfig( | 150 QuicCryptoServerConfig::QuicCryptoServerConfig( |
151 StringPiece source_address_token_secret, | 151 QuicStringPiece source_address_token_secret, |
152 QuicRandom* server_nonce_entropy, | 152 QuicRandom* server_nonce_entropy, |
153 std::unique_ptr<ProofSource> proof_source) | 153 std::unique_ptr<ProofSource> proof_source) |
154 : replay_protection_(true), | 154 : replay_protection_(true), |
155 chlo_multiplier_(kMultiplier), | 155 chlo_multiplier_(kMultiplier), |
156 configs_lock_(), | 156 configs_lock_(), |
157 primary_config_(nullptr), | 157 primary_config_(nullptr), |
158 next_config_promotion_time_(QuicWallTime::Zero()), | 158 next_config_promotion_time_(QuicWallTime::Zero()), |
159 proof_source_(std::move(proof_source)), | 159 proof_source_(std::move(proof_source)), |
160 source_address_token_future_secs_(3600), | 160 source_address_token_future_secs_(3600), |
161 source_address_token_lifetime_secs_(86400), | 161 source_address_token_lifetime_secs_(86400), |
(...skipping 20 matching lines...) Expand all Loading... |
182 std::unique_ptr<QuicServerConfigProtobuf> | 182 std::unique_ptr<QuicServerConfigProtobuf> |
183 QuicCryptoServerConfig::GenerateConfig(QuicRandom* rand, | 183 QuicCryptoServerConfig::GenerateConfig(QuicRandom* rand, |
184 const QuicClock* clock, | 184 const QuicClock* clock, |
185 const ConfigOptions& options) { | 185 const ConfigOptions& options) { |
186 CryptoHandshakeMessage msg; | 186 CryptoHandshakeMessage msg; |
187 | 187 |
188 const string curve25519_private_key = | 188 const string curve25519_private_key = |
189 Curve25519KeyExchange::NewPrivateKey(rand); | 189 Curve25519KeyExchange::NewPrivateKey(rand); |
190 std::unique_ptr<Curve25519KeyExchange> curve25519( | 190 std::unique_ptr<Curve25519KeyExchange> curve25519( |
191 Curve25519KeyExchange::New(curve25519_private_key)); | 191 Curve25519KeyExchange::New(curve25519_private_key)); |
192 StringPiece curve25519_public_value = curve25519->public_value(); | 192 QuicStringPiece curve25519_public_value = curve25519->public_value(); |
193 | 193 |
194 string encoded_public_values; | 194 string encoded_public_values; |
195 // First three bytes encode the length of the public value. | 195 // First three bytes encode the length of the public value. |
196 DCHECK_LT(curve25519_public_value.size(), (1U << 24)); | 196 DCHECK_LT(curve25519_public_value.size(), (1U << 24)); |
197 encoded_public_values.push_back( | 197 encoded_public_values.push_back( |
198 static_cast<char>(curve25519_public_value.size())); | 198 static_cast<char>(curve25519_public_value.size())); |
199 encoded_public_values.push_back( | 199 encoded_public_values.push_back( |
200 static_cast<char>(curve25519_public_value.size() >> 8)); | 200 static_cast<char>(curve25519_public_value.size() >> 8)); |
201 encoded_public_values.push_back( | 201 encoded_public_values.push_back( |
202 static_cast<char>(curve25519_public_value.size() >> 16)); | 202 static_cast<char>(curve25519_public_value.size() >> 16)); |
203 encoded_public_values.append(curve25519_public_value.data(), | 203 encoded_public_values.append(curve25519_public_value.data(), |
204 curve25519_public_value.size()); | 204 curve25519_public_value.size()); |
205 | 205 |
206 string p256_private_key; | 206 string p256_private_key; |
207 if (options.p256) { | 207 if (options.p256) { |
208 p256_private_key = P256KeyExchange::NewPrivateKey(); | 208 p256_private_key = P256KeyExchange::NewPrivateKey(); |
209 std::unique_ptr<P256KeyExchange> p256( | 209 std::unique_ptr<P256KeyExchange> p256( |
210 P256KeyExchange::New(p256_private_key)); | 210 P256KeyExchange::New(p256_private_key)); |
211 StringPiece p256_public_value = p256->public_value(); | 211 QuicStringPiece p256_public_value = p256->public_value(); |
212 | 212 |
213 DCHECK_LT(p256_public_value.size(), (1U << 24)); | 213 DCHECK_LT(p256_public_value.size(), (1U << 24)); |
214 encoded_public_values.push_back( | 214 encoded_public_values.push_back( |
215 static_cast<char>(p256_public_value.size())); | 215 static_cast<char>(p256_public_value.size())); |
216 encoded_public_values.push_back( | 216 encoded_public_values.push_back( |
217 static_cast<char>(p256_public_value.size() >> 8)); | 217 static_cast<char>(p256_public_value.size() >> 8)); |
218 encoded_public_values.push_back( | 218 encoded_public_values.push_back( |
219 static_cast<char>(p256_public_value.size() >> 16)); | 219 static_cast<char>(p256_public_value.size() >> 16)); |
220 encoded_public_values.append(p256_public_value.data(), | 220 encoded_public_values.append(p256_public_value.data(), |
221 p256_public_value.size()); | 221 p256_public_value.size()); |
(...skipping 18 matching lines...) Expand all Loading... |
240 msg.SetValue(kEXPY, options.expiry_time.ToUNIXSeconds()); | 240 msg.SetValue(kEXPY, options.expiry_time.ToUNIXSeconds()); |
241 } | 241 } |
242 | 242 |
243 char orbit_bytes[kOrbitSize]; | 243 char orbit_bytes[kOrbitSize]; |
244 if (options.orbit.size() == sizeof(orbit_bytes)) { | 244 if (options.orbit.size() == sizeof(orbit_bytes)) { |
245 memcpy(orbit_bytes, options.orbit.data(), sizeof(orbit_bytes)); | 245 memcpy(orbit_bytes, options.orbit.data(), sizeof(orbit_bytes)); |
246 } else { | 246 } else { |
247 DCHECK(options.orbit.empty()); | 247 DCHECK(options.orbit.empty()); |
248 rand->RandBytes(orbit_bytes, sizeof(orbit_bytes)); | 248 rand->RandBytes(orbit_bytes, sizeof(orbit_bytes)); |
249 } | 249 } |
250 msg.SetStringPiece(kORBT, StringPiece(orbit_bytes, sizeof(orbit_bytes))); | 250 msg.SetStringPiece(kORBT, QuicStringPiece(orbit_bytes, sizeof(orbit_bytes))); |
251 | 251 |
252 if (options.channel_id_enabled) { | 252 if (options.channel_id_enabled) { |
253 msg.SetVector(kPDMD, QuicTagVector{kCHID}); | 253 msg.SetVector(kPDMD, QuicTagVector{kCHID}); |
254 } | 254 } |
255 | 255 |
256 if (!options.token_binding_params.empty()) { | 256 if (!options.token_binding_params.empty()) { |
257 msg.SetVector(kTBKP, options.token_binding_params); | 257 msg.SetVector(kTBKP, options.token_binding_params); |
258 } | 258 } |
259 | 259 |
260 if (options.id.empty()) { | 260 if (options.id.empty()) { |
261 // We need to ensure that the SCID changes whenever the server config does | 261 // We need to ensure that the SCID changes whenever the server config does |
262 // thus we make it a hash of the rest of the server config. | 262 // thus we make it a hash of the rest of the server config. |
263 std::unique_ptr<QuicData> serialized( | 263 std::unique_ptr<QuicData> serialized( |
264 CryptoFramer::ConstructHandshakeMessage(msg)); | 264 CryptoFramer::ConstructHandshakeMessage(msg)); |
265 | 265 |
266 uint8_t scid_bytes[SHA256_DIGEST_LENGTH]; | 266 uint8_t scid_bytes[SHA256_DIGEST_LENGTH]; |
267 SHA256(reinterpret_cast<const uint8_t*>(serialized->data()), | 267 SHA256(reinterpret_cast<const uint8_t*>(serialized->data()), |
268 serialized->length(), scid_bytes); | 268 serialized->length(), scid_bytes); |
269 // The SCID is a truncated SHA-256 digest. | 269 // The SCID is a truncated SHA-256 digest. |
270 static_assert(16 <= SHA256_DIGEST_LENGTH, "SCID length too high."); | 270 static_assert(16 <= SHA256_DIGEST_LENGTH, "SCID length too high."); |
271 msg.SetStringPiece( | 271 msg.SetStringPiece( |
272 kSCID, StringPiece(reinterpret_cast<const char*>(scid_bytes), 16)); | 272 kSCID, QuicStringPiece(reinterpret_cast<const char*>(scid_bytes), 16)); |
273 } else { | 273 } else { |
274 msg.SetStringPiece(kSCID, options.id); | 274 msg.SetStringPiece(kSCID, options.id); |
275 } | 275 } |
276 // Don't put new tags below this point. The SCID generation should hash over | 276 // Don't put new tags below this point. The SCID generation should hash over |
277 // everything but itself and so extra tags should be added prior to the | 277 // everything but itself and so extra tags should be added prior to the |
278 // preceding if block. | 278 // preceding if block. |
279 | 279 |
280 std::unique_ptr<QuicData> serialized( | 280 std::unique_ptr<QuicData> serialized( |
281 CryptoFramer::ConstructHandshakeMessage(msg)); | 281 CryptoFramer::ConstructHandshakeMessage(msg)); |
282 | 282 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 QuicVersion version, | 433 QuicVersion version, |
434 const QuicClock* clock, | 434 const QuicClock* clock, |
435 QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config, | 435 QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config, |
436 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { | 436 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { |
437 const QuicWallTime now(clock->WallNow()); | 437 const QuicWallTime now(clock->WallNow()); |
438 | 438 |
439 QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> result( | 439 QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> result( |
440 new ValidateClientHelloResultCallback::Result(client_hello, client_ip, | 440 new ValidateClientHelloResultCallback::Result(client_hello, client_ip, |
441 now)); | 441 now)); |
442 | 442 |
443 StringPiece requested_scid; | 443 QuicStringPiece requested_scid; |
444 client_hello.GetStringPiece(kSCID, &requested_scid); | 444 client_hello.GetStringPiece(kSCID, &requested_scid); |
445 | 445 |
446 QuicReferenceCountedPointer<Config> requested_config; | 446 QuicReferenceCountedPointer<Config> requested_config; |
447 QuicReferenceCountedPointer<Config> primary_config; | 447 QuicReferenceCountedPointer<Config> primary_config; |
448 { | 448 { |
449 QuicReaderMutexLock locked(&configs_lock_); | 449 QuicReaderMutexLock locked(&configs_lock_); |
450 | 450 |
451 if (!primary_config_.get()) { | 451 if (!primary_config_.get()) { |
452 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; | 452 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; |
453 result->error_details = "No configurations loaded"; | 453 result->error_details = "No configurations loaded"; |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 const ClientHelloInfo& info = validate_chlo_result->info; | 633 const ClientHelloInfo& info = validate_chlo_result->info; |
634 | 634 |
635 string error_details; | 635 string error_details; |
636 QuicErrorCode valid = CryptoUtils::ValidateClientHello( | 636 QuicErrorCode valid = CryptoUtils::ValidateClientHello( |
637 client_hello, version, supported_versions, &error_details); | 637 client_hello, version, supported_versions, &error_details); |
638 if (valid != QUIC_NO_ERROR) { | 638 if (valid != QUIC_NO_ERROR) { |
639 helper.Fail(valid, error_details); | 639 helper.Fail(valid, error_details); |
640 return; | 640 return; |
641 } | 641 } |
642 | 642 |
643 StringPiece requested_scid; | 643 QuicStringPiece requested_scid; |
644 client_hello.GetStringPiece(kSCID, &requested_scid); | 644 client_hello.GetStringPiece(kSCID, &requested_scid); |
645 const QuicWallTime now(clock->WallNow()); | 645 const QuicWallTime now(clock->WallNow()); |
646 | 646 |
647 QuicReferenceCountedPointer<Config> requested_config; | 647 QuicReferenceCountedPointer<Config> requested_config; |
648 QuicReferenceCountedPointer<Config> primary_config; | 648 QuicReferenceCountedPointer<Config> primary_config; |
649 bool no_primary_config = false; | 649 bool no_primary_config = false; |
650 { | 650 { |
651 QuicReaderMutexLock locked(&configs_lock_); | 651 QuicReaderMutexLock locked(&configs_lock_); |
652 | 652 |
653 if (!primary_config_) { | 653 if (!primary_config_) { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 helper.Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof"); | 750 helper.Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof"); |
751 return; | 751 return; |
752 } | 752 } |
753 | 753 |
754 const CryptoHandshakeMessage& client_hello = | 754 const CryptoHandshakeMessage& client_hello = |
755 validate_chlo_result.client_hello; | 755 validate_chlo_result.client_hello; |
756 const ClientHelloInfo& info = validate_chlo_result.info; | 756 const ClientHelloInfo& info = validate_chlo_result.info; |
757 std::unique_ptr<DiversificationNonce> out_diversification_nonce( | 757 std::unique_ptr<DiversificationNonce> out_diversification_nonce( |
758 new DiversificationNonce); | 758 new DiversificationNonce); |
759 | 759 |
760 StringPiece cert_sct; | 760 QuicStringPiece cert_sct; |
761 if (client_hello.GetStringPiece(kCertificateSCTTag, &cert_sct) && | 761 if (client_hello.GetStringPiece(kCertificateSCTTag, &cert_sct) && |
762 cert_sct.empty()) { | 762 cert_sct.empty()) { |
763 params->sct_supported_by_client = true; | 763 params->sct_supported_by_client = true; |
764 } | 764 } |
765 | 765 |
766 std::unique_ptr<CryptoHandshakeMessage> out(new CryptoHandshakeMessage); | 766 std::unique_ptr<CryptoHandshakeMessage> out(new CryptoHandshakeMessage); |
767 if (!info.reject_reasons.empty() || !requested_config.get()) { | 767 if (!info.reject_reasons.empty() || !requested_config.get()) { |
768 BuildRejection(version, clock->WallNow(), *primary_config, client_hello, | 768 BuildRejection(version, clock->WallNow(), *primary_config, client_hello, |
769 info, validate_chlo_result.cached_network_params, | 769 info, validate_chlo_result.cached_network_params, |
770 use_stateless_rejects, server_designated_connection_id, rand, | 770 use_stateless_rejects, server_designated_connection_id, rand, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 nullptr)) { | 819 nullptr)) { |
820 break; | 820 break; |
821 } | 821 } |
822 default: | 822 default: |
823 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 823 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
824 "Invalid Token Binding key parameter"); | 824 "Invalid Token Binding key parameter"); |
825 return; | 825 return; |
826 } | 826 } |
827 } | 827 } |
828 | 828 |
829 StringPiece public_value; | 829 QuicStringPiece public_value; |
830 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { | 830 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { |
831 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Missing public value"); | 831 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Missing public value"); |
832 return; | 832 return; |
833 } | 833 } |
834 | 834 |
835 const KeyExchange* key_exchange = | 835 const KeyExchange* key_exchange = |
836 requested_config->key_exchanges[key_exchange_index].get(); | 836 requested_config->key_exchanges[key_exchange_index].get(); |
837 if (!key_exchange->CalculateSharedKey(public_value, | 837 if (!key_exchange->CalculateSharedKey(public_value, |
838 ¶ms->initial_premaster_secret)) { | 838 ¶ms->initial_premaster_secret)) { |
839 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Invalid public value"); | 839 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Invalid public value"); |
(...skipping 16 matching lines...) Expand all Loading... |
856 hkdf_suffix.append(client_hello_serialized.data(), | 856 hkdf_suffix.append(client_hello_serialized.data(), |
857 client_hello_serialized.length()); | 857 client_hello_serialized.length()); |
858 hkdf_suffix.append(requested_config->serialized); | 858 hkdf_suffix.append(requested_config->serialized); |
859 DCHECK(proof_source_.get()); | 859 DCHECK(proof_source_.get()); |
860 if (signed_config->chain->certs.empty()) { | 860 if (signed_config->chain->certs.empty()) { |
861 helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "Failed to get certs"); | 861 helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "Failed to get certs"); |
862 return; | 862 return; |
863 } | 863 } |
864 hkdf_suffix.append(signed_config->chain->certs.at(0)); | 864 hkdf_suffix.append(signed_config->chain->certs.at(0)); |
865 | 865 |
866 StringPiece cetv_ciphertext; | 866 QuicStringPiece cetv_ciphertext; |
867 if (requested_config->channel_id_enabled && | 867 if (requested_config->channel_id_enabled && |
868 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) { | 868 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) { |
869 CryptoHandshakeMessage client_hello_copy(client_hello); | 869 CryptoHandshakeMessage client_hello_copy(client_hello); |
870 client_hello_copy.Erase(kCETV); | 870 client_hello_copy.Erase(kCETV); |
871 client_hello_copy.Erase(kPAD); | 871 client_hello_copy.Erase(kPAD); |
872 | 872 |
873 const QuicData& client_hello_copy_serialized = | 873 const QuicData& client_hello_copy_serialized = |
874 client_hello_copy.GetSerialized(); | 874 client_hello_copy.GetSerialized(); |
875 string hkdf_input; | 875 string hkdf_input; |
876 hkdf_input.append(QuicCryptoConfig::kCETVLabel, | 876 hkdf_input.append(QuicCryptoConfig::kCETVLabel, |
(...skipping 12 matching lines...) Expand all Loading... |
889 &crypters, nullptr /* subkey secret */)) { | 889 &crypters, nullptr /* subkey secret */)) { |
890 helper.Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED, | 890 helper.Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED, |
891 "Symmetric key setup failed"); | 891 "Symmetric key setup failed"); |
892 return; | 892 return; |
893 } | 893 } |
894 | 894 |
895 char plaintext[kMaxPacketSize]; | 895 char plaintext[kMaxPacketSize]; |
896 size_t plaintext_length = 0; | 896 size_t plaintext_length = 0; |
897 const bool success = crypters.decrypter->DecryptPacket( | 897 const bool success = crypters.decrypter->DecryptPacket( |
898 QUIC_VERSION_35, 0 /* packet number */, | 898 QUIC_VERSION_35, 0 /* packet number */, |
899 StringPiece() /* associated data */, cetv_ciphertext, plaintext, | 899 QuicStringPiece() /* associated data */, cetv_ciphertext, plaintext, |
900 &plaintext_length, kMaxPacketSize); | 900 &plaintext_length, kMaxPacketSize); |
901 if (!success) { | 901 if (!success) { |
902 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 902 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
903 "CETV decryption failure"); | 903 "CETV decryption failure"); |
904 return; | 904 return; |
905 } | 905 } |
906 std::unique_ptr<CryptoHandshakeMessage> cetv( | 906 std::unique_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage( |
907 CryptoFramer::ParseMessage(StringPiece(plaintext, plaintext_length))); | 907 QuicStringPiece(plaintext, plaintext_length))); |
908 if (!cetv.get()) { | 908 if (!cetv.get()) { |
909 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "CETV parse error"); | 909 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "CETV parse error"); |
910 return; | 910 return; |
911 } | 911 } |
912 | 912 |
913 StringPiece key, signature; | 913 QuicStringPiece key, signature; |
914 if (cetv->GetStringPiece(kCIDK, &key) && | 914 if (cetv->GetStringPiece(kCIDK, &key) && |
915 cetv->GetStringPiece(kCIDS, &signature)) { | 915 cetv->GetStringPiece(kCIDS, &signature)) { |
916 if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { | 916 if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { |
917 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 917 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
918 "ChannelID signature failure"); | 918 "ChannelID signature failure"); |
919 return; | 919 return; |
920 } | 920 } |
921 | 921 |
922 params->channel_id = key.as_string(); | 922 params->channel_id = key.as_string(); |
923 } | 923 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 client_address.host(), rand, info.now, nullptr)); | 998 client_address.host(), rand, info.now, nullptr)); |
999 QuicSocketAddressCoder address_coder(client_address); | 999 QuicSocketAddressCoder address_coder(client_address); |
1000 out->SetStringPiece(kCADR, address_coder.Encode()); | 1000 out->SetStringPiece(kCADR, address_coder.Encode()); |
1001 out->SetStringPiece(kPUBS, forward_secure_public_value); | 1001 out->SetStringPiece(kPUBS, forward_secure_public_value); |
1002 | 1002 |
1003 helper.Succeed(std::move(out), std::move(out_diversification_nonce), | 1003 helper.Succeed(std::move(out), std::move(out_diversification_nonce), |
1004 std::move(proof_source_details)); | 1004 std::move(proof_source_details)); |
1005 } | 1005 } |
1006 | 1006 |
1007 QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> | 1007 QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> |
1008 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { | 1008 QuicCryptoServerConfig::GetConfigWithScid( |
| 1009 QuicStringPiece requested_scid) const { |
1009 configs_lock_.AssertReaderHeld(); | 1010 configs_lock_.AssertReaderHeld(); |
1010 | 1011 |
1011 if (!requested_scid.empty()) { | 1012 if (!requested_scid.empty()) { |
1012 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); | 1013 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); |
1013 if (it != configs_.end()) { | 1014 if (it != configs_.end()) { |
1014 // We'll use the config that the client requested in order to do | 1015 // We'll use the config that the client requested in order to do |
1015 // key-agreement. | 1016 // key-agreement. |
1016 return QuicReferenceCountedPointer<Config>(it->second); | 1017 return QuicReferenceCountedPointer<Config>(it->second); |
1017 } | 1018 } |
1018 } | 1019 } |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1200 if (client_hello.GetStringPiece(kSNI, &info->sni) && | 1201 if (client_hello.GetStringPiece(kSNI, &info->sni) && |
1201 !QuicHostnameUtils::IsValidSNI(info->sni)) { | 1202 !QuicHostnameUtils::IsValidSNI(info->sni)) { |
1202 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 1203 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
1203 "Invalid SNI name", nullptr); | 1204 "Invalid SNI name", nullptr); |
1204 return; | 1205 return; |
1205 } | 1206 } |
1206 | 1207 |
1207 client_hello.GetStringPiece(kUAID, &info->user_agent_id); | 1208 client_hello.GetStringPiece(kUAID, &info->user_agent_id); |
1208 | 1209 |
1209 HandshakeFailureReason source_address_token_error = MAX_FAILURE_REASON; | 1210 HandshakeFailureReason source_address_token_error = MAX_FAILURE_REASON; |
1210 StringPiece srct; | 1211 QuicStringPiece srct; |
1211 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { | 1212 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { |
1212 Config& config = | 1213 Config& config = |
1213 requested_config != nullptr ? *requested_config : *primary_config; | 1214 requested_config != nullptr ? *requested_config : *primary_config; |
1214 source_address_token_error = | 1215 source_address_token_error = |
1215 ParseSourceAddressToken(config, srct, &info->source_address_tokens); | 1216 ParseSourceAddressToken(config, srct, &info->source_address_tokens); |
1216 | 1217 |
1217 if (source_address_token_error == HANDSHAKE_OK) { | 1218 if (source_address_token_error == HANDSHAKE_OK) { |
1218 source_address_token_error = ValidateSourceAddressTokens( | 1219 source_address_token_error = ValidateSourceAddressTokens( |
1219 info->source_address_tokens, info->client_ip, info->now, | 1220 info->source_address_tokens, info->client_ip, info->now, |
1220 &client_hello_state->cached_network_params); | 1221 &client_hello_state->cached_network_params); |
1221 } | 1222 } |
1222 info->valid_source_address_token = | 1223 info->valid_source_address_token = |
1223 (source_address_token_error == HANDSHAKE_OK); | 1224 (source_address_token_error == HANDSHAKE_OK); |
1224 } else { | 1225 } else { |
1225 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE; | 1226 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE; |
1226 } | 1227 } |
1227 | 1228 |
1228 if (!requested_config.get()) { | 1229 if (!requested_config.get()) { |
1229 StringPiece requested_scid; | 1230 QuicStringPiece requested_scid; |
1230 if (client_hello.GetStringPiece(kSCID, &requested_scid)) { | 1231 if (client_hello.GetStringPiece(kSCID, &requested_scid)) { |
1231 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); | 1232 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); |
1232 } else { | 1233 } else { |
1233 info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE); | 1234 info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE); |
1234 } | 1235 } |
1235 // No server config with the requested ID. | 1236 // No server config with the requested ID. |
1236 helper.ValidationComplete(QUIC_NO_ERROR, "", nullptr); | 1237 helper.ValidationComplete(QUIC_NO_ERROR, "", nullptr); |
1237 return; | 1238 return; |
1238 } | 1239 } |
1239 | 1240 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1330 // for DoS reasons then we must reject the CHLO. | 1331 // for DoS reasons then we must reject the CHLO. |
1331 if (FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation && | 1332 if (FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation && |
1332 info->server_nonce.empty()) { | 1333 info->server_nonce.empty()) { |
1333 info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); | 1334 info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); |
1334 } | 1335 } |
1335 helper.ValidationComplete(QUIC_NO_ERROR, "", std::move(proof_source_details)); | 1336 helper.ValidationComplete(QUIC_NO_ERROR, "", std::move(proof_source_details)); |
1336 } | 1337 } |
1337 | 1338 |
1338 void QuicCryptoServerConfig::BuildServerConfigUpdateMessage( | 1339 void QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
1339 QuicVersion version, | 1340 QuicVersion version, |
1340 StringPiece chlo_hash, | 1341 QuicStringPiece chlo_hash, |
1341 const SourceAddressTokens& previous_source_address_tokens, | 1342 const SourceAddressTokens& previous_source_address_tokens, |
1342 const QuicSocketAddress& server_address, | 1343 const QuicSocketAddress& server_address, |
1343 const QuicIpAddress& client_ip, | 1344 const QuicIpAddress& client_ip, |
1344 const QuicClock* clock, | 1345 const QuicClock* clock, |
1345 QuicRandom* rand, | 1346 QuicRandom* rand, |
1346 QuicCompressedCertsCache* compressed_certs_cache, | 1347 QuicCompressedCertsCache* compressed_certs_cache, |
1347 const QuicCryptoNegotiatedParameters& params, | 1348 const QuicCryptoNegotiatedParameters& params, |
1348 const CachedNetworkParameters* cached_network_params, | 1349 const CachedNetworkParameters* cached_network_params, |
1349 const QuicTagVector& connection_options, | 1350 const QuicTagVector& connection_options, |
1350 std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const { | 1351 std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1491 // Send client the reject reason for debugging purposes. | 1492 // Send client the reject reason for debugging purposes. |
1492 DCHECK_LT(0u, info.reject_reasons.size()); | 1493 DCHECK_LT(0u, info.reject_reasons.size()); |
1493 out->SetVector(kRREJ, info.reject_reasons); | 1494 out->SetVector(kRREJ, info.reject_reasons); |
1494 | 1495 |
1495 // The client may have requested a certificate chain. | 1496 // The client may have requested a certificate chain. |
1496 if (!ClientDemandsX509Proof(client_hello)) { | 1497 if (!ClientDemandsX509Proof(client_hello)) { |
1497 QUIC_BUG << "x509 certificates not supported in proof demand"; | 1498 QUIC_BUG << "x509 certificates not supported in proof demand"; |
1498 return; | 1499 return; |
1499 } | 1500 } |
1500 | 1501 |
1501 StringPiece client_common_set_hashes; | 1502 QuicStringPiece client_common_set_hashes; |
1502 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) { | 1503 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) { |
1503 params->client_common_set_hashes = client_common_set_hashes.as_string(); | 1504 params->client_common_set_hashes = client_common_set_hashes.as_string(); |
1504 } | 1505 } |
1505 | 1506 |
1506 StringPiece client_cached_cert_hashes; | 1507 QuicStringPiece client_cached_cert_hashes; |
1507 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) { | 1508 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) { |
1508 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string(); | 1509 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string(); |
1509 } | 1510 } |
1510 | 1511 |
1511 const string compressed = | 1512 const string compressed = |
1512 CompressChain(compressed_certs_cache, signed_config.chain, | 1513 CompressChain(compressed_certs_cache, signed_config.chain, |
1513 params->client_common_set_hashes, | 1514 params->client_common_set_hashes, |
1514 params->client_cached_cert_hashes, config.common_cert_sets); | 1515 params->client_cached_cert_hashes, config.common_cert_sets); |
1515 | 1516 |
1516 DCHECK_GT(chlo_packet_size, client_hello.size()); | 1517 DCHECK_GT(chlo_packet_size, client_hello.size()); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1595 config->serialized = protobuf->config(); | 1596 config->serialized = protobuf->config(); |
1596 config->source_address_token_boxer = &source_address_token_boxer_; | 1597 config->source_address_token_boxer = &source_address_token_boxer_; |
1597 | 1598 |
1598 if (protobuf->has_primary_time()) { | 1599 if (protobuf->has_primary_time()) { |
1599 config->primary_time = | 1600 config->primary_time = |
1600 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); | 1601 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); |
1601 } | 1602 } |
1602 | 1603 |
1603 config->priority = protobuf->priority(); | 1604 config->priority = protobuf->priority(); |
1604 | 1605 |
1605 StringPiece scid; | 1606 QuicStringPiece scid; |
1606 if (!msg->GetStringPiece(kSCID, &scid)) { | 1607 if (!msg->GetStringPiece(kSCID, &scid)) { |
1607 QUIC_LOG(WARNING) << "Server config message is missing SCID"; | 1608 QUIC_LOG(WARNING) << "Server config message is missing SCID"; |
1608 return nullptr; | 1609 return nullptr; |
1609 } | 1610 } |
1610 config->id = scid.as_string(); | 1611 config->id = scid.as_string(); |
1611 | 1612 |
1612 const QuicTag* aead_tags; | 1613 const QuicTag* aead_tags; |
1613 size_t aead_len; | 1614 size_t aead_len; |
1614 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { | 1615 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { |
1615 QUIC_LOG(WARNING) << "Server config message is missing AEAD"; | 1616 QUIC_LOG(WARNING) << "Server config message is missing AEAD"; |
(...skipping 12 matching lines...) Expand all Loading... |
1628 size_t tbkp_len; | 1629 size_t tbkp_len; |
1629 QuicErrorCode err; | 1630 QuicErrorCode err; |
1630 if ((err = msg->GetTaglist(kTBKP, &tbkp_tags, &tbkp_len)) != | 1631 if ((err = msg->GetTaglist(kTBKP, &tbkp_tags, &tbkp_len)) != |
1631 QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND && | 1632 QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND && |
1632 err != QUIC_NO_ERROR) { | 1633 err != QUIC_NO_ERROR) { |
1633 QUIC_LOG(WARNING) << "Server config message is missing or has invalid TBKP"; | 1634 QUIC_LOG(WARNING) << "Server config message is missing or has invalid TBKP"; |
1634 return nullptr; | 1635 return nullptr; |
1635 } | 1636 } |
1636 config->tb_key_params = std::vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len); | 1637 config->tb_key_params = std::vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len); |
1637 | 1638 |
1638 StringPiece orbit; | 1639 QuicStringPiece orbit; |
1639 if (!msg->GetStringPiece(kORBT, &orbit)) { | 1640 if (!msg->GetStringPiece(kORBT, &orbit)) { |
1640 QUIC_LOG(WARNING) << "Server config message is missing ORBT"; | 1641 QUIC_LOG(WARNING) << "Server config message is missing ORBT"; |
1641 return nullptr; | 1642 return nullptr; |
1642 } | 1643 } |
1643 | 1644 |
1644 if (orbit.size() != kOrbitSize) { | 1645 if (orbit.size() != kOrbitSize) { |
1645 QUIC_LOG(WARNING) << "Orbit value in server config is the wrong length." | 1646 QUIC_LOG(WARNING) << "Orbit value in server config is the wrong length." |
1646 " Got " | 1647 " Got " |
1647 << orbit.size() << " want " << kOrbitSize; | 1648 << orbit.size() << " want " << kOrbitSize; |
1648 return nullptr; | 1649 return nullptr; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1807 rand, source_address_tokens.SerializeAsString()); | 1808 rand, source_address_tokens.SerializeAsString()); |
1808 } | 1809 } |
1809 | 1810 |
1810 int QuicCryptoServerConfig::NumberOfConfigs() const { | 1811 int QuicCryptoServerConfig::NumberOfConfigs() const { |
1811 QuicReaderMutexLock locked(&configs_lock_); | 1812 QuicReaderMutexLock locked(&configs_lock_); |
1812 return configs_.size(); | 1813 return configs_.size(); |
1813 } | 1814 } |
1814 | 1815 |
1815 HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken( | 1816 HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken( |
1816 const Config& config, | 1817 const Config& config, |
1817 StringPiece token, | 1818 QuicStringPiece token, |
1818 SourceAddressTokens* tokens) const { | 1819 SourceAddressTokens* tokens) const { |
1819 string storage; | 1820 string storage; |
1820 StringPiece plaintext; | 1821 QuicStringPiece plaintext; |
1821 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { | 1822 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { |
1822 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE; | 1823 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE; |
1823 } | 1824 } |
1824 | 1825 |
1825 if (!tokens->ParseFromArray(plaintext.data(), plaintext.size())) { | 1826 if (!tokens->ParseFromArray(plaintext.data(), plaintext.size())) { |
1826 // Some clients might still be using the old source token format so | 1827 // Some clients might still be using the old source token format so |
1827 // attempt to parse that format. | 1828 // attempt to parse that format. |
1828 // TODO(rch): remove this code once the new format is ubiquitous. | 1829 // TODO(rch): remove this code once the new format is ubiquitous. |
1829 SourceAddressToken token; | 1830 SourceAddressToken token; |
1830 if (!token.ParseFromArray(plaintext.data(), plaintext.size())) { | 1831 if (!token.ParseFromArray(plaintext.data(), plaintext.size())) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1900 uint8_t server_nonce[kServerNoncePlaintextSize]; | 1901 uint8_t server_nonce[kServerNoncePlaintextSize]; |
1901 static_assert(sizeof(server_nonce) > sizeof(timestamp), "nonce too small"); | 1902 static_assert(sizeof(server_nonce) > sizeof(timestamp), "nonce too small"); |
1902 server_nonce[0] = static_cast<uint8_t>(timestamp >> 24); | 1903 server_nonce[0] = static_cast<uint8_t>(timestamp >> 24); |
1903 server_nonce[1] = static_cast<uint8_t>(timestamp >> 16); | 1904 server_nonce[1] = static_cast<uint8_t>(timestamp >> 16); |
1904 server_nonce[2] = static_cast<uint8_t>(timestamp >> 8); | 1905 server_nonce[2] = static_cast<uint8_t>(timestamp >> 8); |
1905 server_nonce[3] = static_cast<uint8_t>(timestamp); | 1906 server_nonce[3] = static_cast<uint8_t>(timestamp); |
1906 rand->RandBytes(&server_nonce[sizeof(timestamp)], | 1907 rand->RandBytes(&server_nonce[sizeof(timestamp)], |
1907 sizeof(server_nonce) - sizeof(timestamp)); | 1908 sizeof(server_nonce) - sizeof(timestamp)); |
1908 | 1909 |
1909 return server_nonce_boxer_.Box( | 1910 return server_nonce_boxer_.Box( |
1910 rand, | 1911 rand, QuicStringPiece(reinterpret_cast<char*>(server_nonce), |
1911 StringPiece(reinterpret_cast<char*>(server_nonce), sizeof(server_nonce))); | 1912 sizeof(server_nonce))); |
1912 } | 1913 } |
1913 | 1914 |
1914 bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate( | 1915 bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate( |
1915 const CryptoHandshakeMessage& client_hello, | 1916 const CryptoHandshakeMessage& client_hello, |
1916 const std::vector<string>& certs) const { | 1917 const std::vector<string>& certs) const { |
1917 if (certs.empty()) { | 1918 if (certs.empty()) { |
1918 return false; | 1919 return false; |
1919 } | 1920 } |
1920 | 1921 |
1921 uint64_t hash_from_client; | 1922 uint64_t hash_from_client; |
(...skipping 29 matching lines...) Expand all Loading... |
1951 expiry_time(QuicWallTime::Zero()), | 1952 expiry_time(QuicWallTime::Zero()), |
1952 priority(0), | 1953 priority(0), |
1953 source_address_token_boxer(nullptr) {} | 1954 source_address_token_boxer(nullptr) {} |
1954 | 1955 |
1955 QuicCryptoServerConfig::Config::~Config() {} | 1956 QuicCryptoServerConfig::Config::~Config() {} |
1956 | 1957 |
1957 QuicSignedServerConfig::QuicSignedServerConfig() {} | 1958 QuicSignedServerConfig::QuicSignedServerConfig() {} |
1958 QuicSignedServerConfig::~QuicSignedServerConfig() {} | 1959 QuicSignedServerConfig::~QuicSignedServerConfig() {} |
1959 | 1960 |
1960 } // namespace net | 1961 } // namespace net |
OLD | NEW |