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

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

Issue 623003002: QUIC: if client provides an STK which includes CachedNetworkParams, then (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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/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"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "crypto/hkdf.h" 12 #include "crypto/hkdf.h"
13 #include "crypto/secure_hash.h" 13 #include "crypto/secure_hash.h"
14 #include "net/base/net_util.h" 14 #include "net/base/net_util.h"
15 #include "net/quic/crypto/aes_128_gcm_12_decrypter.h" 15 #include "net/quic/crypto/aes_128_gcm_12_decrypter.h"
16 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" 16 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
17 #include "net/quic/crypto/cert_compressor.h" 17 #include "net/quic/crypto/cert_compressor.h"
18 #include "net/quic/crypto/chacha20_poly1305_encrypter.h" 18 #include "net/quic/crypto/chacha20_poly1305_encrypter.h"
19 #include "net/quic/crypto/channel_id.h" 19 #include "net/quic/crypto/channel_id.h"
20 #include "net/quic/crypto/crypto_framer.h" 20 #include "net/quic/crypto/crypto_framer.h"
21 #include "net/quic/crypto/crypto_handshake_message.h"
21 #include "net/quic/crypto/crypto_server_config_protobuf.h" 22 #include "net/quic/crypto/crypto_server_config_protobuf.h"
22 #include "net/quic/crypto/crypto_utils.h" 23 #include "net/quic/crypto/crypto_utils.h"
23 #include "net/quic/crypto/curve25519_key_exchange.h" 24 #include "net/quic/crypto/curve25519_key_exchange.h"
24 #include "net/quic/crypto/ephemeral_key_source.h" 25 #include "net/quic/crypto/ephemeral_key_source.h"
25 #include "net/quic/crypto/key_exchange.h" 26 #include "net/quic/crypto/key_exchange.h"
26 #include "net/quic/crypto/local_strike_register_client.h" 27 #include "net/quic/crypto/local_strike_register_client.h"
27 #include "net/quic/crypto/p256_key_exchange.h" 28 #include "net/quic/crypto/p256_key_exchange.h"
28 #include "net/quic/crypto/proof_source.h" 29 #include "net/quic/crypto/proof_source.h"
29 #include "net/quic/crypto/quic_decrypter.h" 30 #include "net/quic/crypto/quic_decrypter.h"
30 #include "net/quic/crypto/quic_encrypter.h" 31 #include "net/quic/crypto/quic_encrypter.h"
(...skipping 23 matching lines...) Expand all
54 StringPiece() /* no salt */, 55 StringPiece() /* no salt */,
55 "QUIC source address token key", 56 "QUIC source address token key",
56 CryptoSecretBoxer::GetKeySize(), 57 CryptoSecretBoxer::GetKeySize(),
57 0 /* no fixed IV needed */, 58 0 /* no fixed IV needed */,
58 0 /* no subkey secret */); 59 0 /* no subkey secret */);
59 return hkdf.server_write_key().as_string(); 60 return hkdf.server_write_key().as_string();
60 } 61 }
61 62
62 } // namespace 63 } // namespace
63 64
64 // ClientHelloInfo contains information about a client hello message that is
65 // only kept for as long as it's being processed.
66 struct ClientHelloInfo {
67 ClientHelloInfo(const IPEndPoint& in_client_ip, QuicWallTime in_now)
68 : client_ip(in_client_ip),
69 now(in_now),
70 valid_source_address_token(false),
71 client_nonce_well_formed(false),
72 unique(false) {}
73
74 // Inputs to EvaluateClientHello.
75 const IPEndPoint client_ip;
76 const QuicWallTime now;
77
78 // Outputs from EvaluateClientHello.
79 bool valid_source_address_token;
80 bool client_nonce_well_formed;
81 bool unique;
82 StringPiece sni;
83 StringPiece client_nonce;
84 StringPiece server_nonce;
85 StringPiece user_agent_id;
86
87 // Errors from EvaluateClientHello.
88 vector<uint32> reject_reasons;
89 COMPILE_ASSERT(sizeof(QuicTag) == sizeof(uint32), header_out_of_sync);
90 };
91
92 struct ValidateClientHelloResultCallback::Result {
93 Result(const CryptoHandshakeMessage& in_client_hello,
94 IPEndPoint in_client_ip,
95 QuicWallTime in_now)
96 : client_hello(in_client_hello),
97 info(in_client_ip, in_now),
98 error_code(QUIC_NO_ERROR) {
99 }
100
101 CryptoHandshakeMessage client_hello;
102 ClientHelloInfo info;
103 QuicErrorCode error_code;
104 string error_details;
105 };
106
107 class ValidateClientHelloHelper { 65 class ValidateClientHelloHelper {
108 public: 66 public:
109 ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result, 67 ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result,
110 ValidateClientHelloResultCallback* done_cb) 68 ValidateClientHelloResultCallback* done_cb)
111 : result_(result), done_cb_(done_cb) { 69 : result_(result), done_cb_(done_cb) {
112 } 70 }
113 71
114 ~ValidateClientHelloHelper() { 72 ~ValidateClientHelloHelper() {
115 LOG_IF(DFATAL, done_cb_ != nullptr) 73 LOG_IF(DFATAL, done_cb_ != nullptr)
116 << "Deleting ValidateClientHelloHelper with a pending callback."; 74 << "Deleting ValidateClientHelloHelper with a pending callback.";
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 private: 150 private:
193 ValidateClientHelloResultCallback::Result* result_; 151 ValidateClientHelloResultCallback::Result* result_;
194 ValidateClientHelloResultCallback* done_cb_; 152 ValidateClientHelloResultCallback* done_cb_;
195 153
196 DISALLOW_COPY_AND_ASSIGN(VerifyNonceIsValidAndUniqueCallback); 154 DISALLOW_COPY_AND_ASSIGN(VerifyNonceIsValidAndUniqueCallback);
197 }; 155 };
198 156
199 // static 157 // static
200 const char QuicCryptoServerConfig::TESTING[] = "secret string for testing"; 158 const char QuicCryptoServerConfig::TESTING[] = "secret string for testing";
201 159
160 ClientHelloInfo::ClientHelloInfo(const IPEndPoint& in_client_ip,
161 QuicWallTime in_now)
162 : client_ip(in_client_ip),
163 now(in_now),
164 valid_source_address_token(false),
165 client_nonce_well_formed(false),
166 unique(false) {
167 }
168
169 ClientHelloInfo::~ClientHelloInfo() {
170 }
171
202 PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() { 172 PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() {
203 } 173 }
204 174
205 PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() { 175 PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() {
206 } 176 }
207 177
178 ValidateClientHelloResultCallback::Result::Result(
179 const CryptoHandshakeMessage& in_client_hello,
180 IPEndPoint in_client_ip,
181 QuicWallTime in_now)
182 : client_hello(in_client_hello),
183 info(in_client_ip, in_now),
184 error_code(QUIC_NO_ERROR) {
185 }
186
187 ValidateClientHelloResultCallback::Result::~Result() {
188 }
189
208 ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() { 190 ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() {
209 } 191 }
210 192
211 ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() { 193 ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() {
212 } 194 }
213 195
214 void ValidateClientHelloResultCallback::Run(const Result* result) { 196 void ValidateClientHelloResultCallback::Run(const Result* result) {
215 RunImpl(result->client_hello, *result); 197 RunImpl(result->client_hello, *result);
216 delete result; 198 delete result;
217 delete this; 199 delete this;
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 *error_details = validate_chlo_result.error_details; 578 *error_details = validate_chlo_result.error_details;
597 return validate_chlo_result.error_code; 579 return validate_chlo_result.error_code;
598 } 580 }
599 581
600 out->Clear(); 582 out->Clear();
601 583
602 if (!info.valid_source_address_token || 584 if (!info.valid_source_address_token ||
603 !info.client_nonce_well_formed || 585 !info.client_nonce_well_formed ||
604 !info.unique || 586 !info.unique ||
605 !requested_config.get()) { 587 !requested_config.get()) {
606 BuildRejection( 588 BuildRejection(*primary_config.get(), client_hello, info,
607 *primary_config.get(), client_hello, info, rand, params, out); 589 validate_chlo_result.cached_network_params, rand, params,
590 out);
608 return QUIC_NO_ERROR; 591 return QUIC_NO_ERROR;
609 } 592 }
610 593
611 const QuicTag* their_aeads; 594 const QuicTag* their_aeads;
612 const QuicTag* their_key_exchanges; 595 const QuicTag* their_key_exchanges;
613 size_t num_their_aeads, num_their_key_exchanges; 596 size_t num_their_aeads, num_their_key_exchanges;
614 if (client_hello.GetTaglist(kAEAD, &their_aeads, 597 if (client_hello.GetTaglist(kAEAD, &their_aeads,
615 &num_their_aeads) != QUIC_NO_ERROR || 598 &num_their_aeads) != QUIC_NO_ERROR ||
616 client_hello.GetTaglist(kKEXS, &their_key_exchanges, 599 client_hello.GetTaglist(kKEXS, &their_key_exchanges,
617 &num_their_key_exchanges) != QUIC_NO_ERROR || 600 &num_their_key_exchanges) != QUIC_NO_ERROR ||
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE); 925 info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
943 } 926 }
944 // No server config with the requested ID. 927 // No server config with the requested ID.
945 helper.ValidationComplete(QUIC_NO_ERROR, ""); 928 helper.ValidationComplete(QUIC_NO_ERROR, "");
946 return; 929 return;
947 } 930 }
948 931
949 HandshakeFailureReason source_address_token_error; 932 HandshakeFailureReason source_address_token_error;
950 StringPiece srct; 933 StringPiece srct;
951 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { 934 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
952 source_address_token_error = ValidateSourceAddressToken( 935 source_address_token_error =
953 *requested_config.get(), srct, info->client_ip, info->now); 936 ValidateSourceAddressToken(*requested_config.get(),
937 srct,
938 info->client_ip,
939 info->now,
940 &client_hello_state->cached_network_params);
954 info->valid_source_address_token = 941 info->valid_source_address_token =
955 (source_address_token_error == HANDSHAKE_OK); 942 (source_address_token_error == HANDSHAKE_OK);
956 } else { 943 } else {
957 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE; 944 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
958 } 945 }
959 946
960 bool found_error = false; 947 bool found_error = false;
961 if (source_address_token_error != HANDSHAKE_OK) { 948 if (source_address_token_error != HANDSHAKE_OK) {
962 info->reject_reasons.push_back(source_address_token_error); 949 info->reject_reasons.push_back(source_address_token_error);
963 // No valid source address token. 950 // No valid source address token.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 1063
1077 out->SetStringPiece(kCertificateTag, compressed); 1064 out->SetStringPiece(kCertificateTag, compressed);
1078 out->SetStringPiece(kPROF, signature); 1065 out->SetStringPiece(kPROF, signature);
1079 return true; 1066 return true;
1080 } 1067 }
1081 1068
1082 void QuicCryptoServerConfig::BuildRejection( 1069 void QuicCryptoServerConfig::BuildRejection(
1083 const Config& config, 1070 const Config& config,
1084 const CryptoHandshakeMessage& client_hello, 1071 const CryptoHandshakeMessage& client_hello,
1085 const ClientHelloInfo& info, 1072 const ClientHelloInfo& info,
1073 const CachedNetworkParameters& cached_network_params,
1086 QuicRandom* rand, 1074 QuicRandom* rand,
1087 QuicCryptoNegotiatedParameters *params, 1075 QuicCryptoNegotiatedParameters *params,
1088 CryptoHandshakeMessage* out) const { 1076 CryptoHandshakeMessage* out) const {
1089 out->set_tag(kREJ); 1077 out->set_tag(kREJ);
1090 out->SetStringPiece(kSCFG, config.serialized); 1078 out->SetStringPiece(kSCFG, config.serialized);
1091 out->SetStringPiece(kSourceAddressTokenTag, 1079 out->SetStringPiece(kSourceAddressTokenTag,
1092 NewSourceAddressToken( 1080 NewSourceAddressToken(
1093 config, 1081 config,
1094 info.client_ip, 1082 info.client_ip,
1095 rand, 1083 rand,
1096 info.now, 1084 info.now,
1097 nullptr)); 1085 &cached_network_params));
1098 if (replay_protection_) { 1086 if (replay_protection_) {
1099 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); 1087 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now));
1100 } 1088 }
1101 1089
1102 if (FLAGS_send_quic_crypto_reject_reason) { 1090 if (FLAGS_send_quic_crypto_reject_reason) {
1103 // Send client the reject reason for debugging purposes. 1091 // Send client the reject reason for debugging purposes.
1104 DCHECK_LT(0u, info.reject_reasons.size()); 1092 DCHECK_LT(0u, info.reject_reasons.size());
1105 out->SetVector(kRREJ, info.reject_reasons); 1093 out->SetVector(kRREJ, info.reject_reasons);
1106 } 1094 }
1107 1095
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 } 1418 }
1431 1419
1432 return config.source_address_token_boxer->Box( 1420 return config.source_address_token_boxer->Box(
1433 rand, source_address_token.SerializeAsString()); 1421 rand, source_address_token.SerializeAsString());
1434 } 1422 }
1435 1423
1436 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken( 1424 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken(
1437 const Config& config, 1425 const Config& config,
1438 StringPiece token, 1426 StringPiece token,
1439 const IPEndPoint& ip, 1427 const IPEndPoint& ip,
1440 QuicWallTime now) const { 1428 QuicWallTime now,
1429 CachedNetworkParameters* cached_network_params) const {
1441 string storage; 1430 string storage;
1442 StringPiece plaintext; 1431 StringPiece plaintext;
1443 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { 1432 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) {
1444 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE; 1433 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE;
1445 } 1434 }
1446 1435
1447 SourceAddressToken source_address_token; 1436 SourceAddressToken source_address_token;
1448 if (!source_address_token.ParseFromArray(plaintext.data(), 1437 if (!source_address_token.ParseFromArray(plaintext.data(),
1449 plaintext.size())) { 1438 plaintext.size())) {
1450 return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE; 1439 return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE;
(...skipping 15 matching lines...) Expand all
1466 if (now.IsBefore(timestamp) && 1455 if (now.IsBefore(timestamp) &&
1467 delta.ToSeconds() > source_address_token_future_secs_) { 1456 delta.ToSeconds() > source_address_token_future_secs_) {
1468 return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE; 1457 return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE;
1469 } 1458 }
1470 1459
1471 if (now.IsAfter(timestamp) && 1460 if (now.IsAfter(timestamp) &&
1472 delta.ToSeconds() > source_address_token_lifetime_secs_) { 1461 delta.ToSeconds() > source_address_token_lifetime_secs_) {
1473 return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE; 1462 return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE;
1474 } 1463 }
1475 1464
1465 if (FLAGS_quic_store_cached_network_params_from_chlo &&
1466 source_address_token.has_cached_network_parameters()) {
1467 *cached_network_params = source_address_token.cached_network_parameters();
1468 }
1469
1476 return HANDSHAKE_OK; 1470 return HANDSHAKE_OK;
1477 } 1471 }
1478 1472
1479 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server 1473 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server
1480 // nonce. 1474 // nonce.
1481 static const size_t kServerNoncePlaintextSize = 1475 static const size_t kServerNoncePlaintextSize =
1482 4 /* timestamp */ + 20 /* random bytes */; 1476 4 /* timestamp */ + 20 /* random bytes */;
1483 1477
1484 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand, 1478 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand,
1485 QuicWallTime now) const { 1479 QuicWallTime now) const {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 QuicCryptoServerConfig::Config::Config() 1556 QuicCryptoServerConfig::Config::Config()
1563 : channel_id_enabled(false), 1557 : channel_id_enabled(false),
1564 is_primary(false), 1558 is_primary(false),
1565 primary_time(QuicWallTime::Zero()), 1559 primary_time(QuicWallTime::Zero()),
1566 priority(0), 1560 priority(0),
1567 source_address_token_boxer(nullptr) {} 1561 source_address_token_boxer(nullptr) {}
1568 1562
1569 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } 1563 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); }
1570 1564
1571 } // namespace net 1565 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/quic_crypto_server_config.h ('k') | net/quic/crypto/quic_crypto_server_config_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698