Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(321)

Side by Side Diff: net/quic/core/crypto/quic_crypto_server_config.cc

Issue 2740453006: Add QuicStringPiece which is actually StringPiece. (Closed)
Patch Set: fix compile error and rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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 &params->initial_premaster_secret)) { 838 &params->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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/quic/core/crypto/quic_crypto_server_config.h ('k') | net/quic/core/crypto/quic_crypto_server_config_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698