OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/crypto/quic_crypto_client_config.h" | 5 #include "net/quic/crypto/quic_crypto_client_config.h" |
6 | 6 |
7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
9 #include "net/quic/crypto/cert_compressor.h" | 9 #include "net/quic/crypto/cert_compressor.h" |
10 #include "net/quic/crypto/chacha20_poly1305_encrypter.h" | 10 #include "net/quic/crypto/chacha20_poly1305_encrypter.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 | 21 |
22 using base::StringPiece; | 22 using base::StringPiece; |
23 using std::find; | 23 using std::find; |
24 using std::make_pair; | 24 using std::make_pair; |
25 using std::map; | 25 using std::map; |
26 using std::string; | 26 using std::string; |
27 using std::vector; | 27 using std::vector; |
28 | 28 |
29 namespace net { | 29 namespace net { |
30 | 30 |
31 QuicCryptoClientConfig::QuicCryptoClientConfig() | 31 QuicCryptoClientConfig::QuicCryptoClientConfig() : disable_ecdsa_(false) { |
32 : disable_ecdsa_(false) {} | 32 } |
33 | 33 |
34 QuicCryptoClientConfig::~QuicCryptoClientConfig() { | 34 QuicCryptoClientConfig::~QuicCryptoClientConfig() { |
35 STLDeleteValues(&cached_states_); | 35 STLDeleteValues(&cached_states_); |
36 } | 36 } |
37 | 37 |
38 QuicCryptoClientConfig::CachedState::CachedState() | 38 QuicCryptoClientConfig::CachedState::CachedState() |
39 : server_config_valid_(false), | 39 : server_config_valid_(false), generation_counter_(0) { |
40 generation_counter_(0) {} | 40 } |
41 | 41 |
42 QuicCryptoClientConfig::CachedState::~CachedState() {} | 42 QuicCryptoClientConfig::CachedState::~CachedState() { |
| 43 } |
43 | 44 |
44 bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const { | 45 bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const { |
45 if (server_config_.empty() || !server_config_valid_) { | 46 if (server_config_.empty() || !server_config_valid_) { |
46 return false; | 47 return false; |
47 } | 48 } |
48 | 49 |
49 const CryptoHandshakeMessage* scfg = GetServerConfig(); | 50 const CryptoHandshakeMessage* scfg = GetServerConfig(); |
50 if (!scfg) { | 51 if (!scfg) { |
51 // Should be impossible short of cache corruption. | 52 // Should be impossible short of cache corruption. |
52 DCHECK(false); | 53 DCHECK(false); |
(...skipping 20 matching lines...) Expand all Loading... |
73 } | 74 } |
74 | 75 |
75 if (!scfg_.get()) { | 76 if (!scfg_.get()) { |
76 scfg_.reset(CryptoFramer::ParseMessage(server_config_)); | 77 scfg_.reset(CryptoFramer::ParseMessage(server_config_)); |
77 DCHECK(scfg_.get()); | 78 DCHECK(scfg_.get()); |
78 } | 79 } |
79 return scfg_.get(); | 80 return scfg_.get(); |
80 } | 81 } |
81 | 82 |
82 QuicErrorCode QuicCryptoClientConfig::CachedState::SetServerConfig( | 83 QuicErrorCode QuicCryptoClientConfig::CachedState::SetServerConfig( |
83 StringPiece server_config, QuicWallTime now, string* error_details) { | 84 StringPiece server_config, |
| 85 QuicWallTime now, |
| 86 string* error_details) { |
84 const bool matches_existing = server_config == server_config_; | 87 const bool matches_existing = server_config == server_config_; |
85 | 88 |
86 // Even if the new server config matches the existing one, we still wish to | 89 // Even if the new server config matches the existing one, we still wish to |
87 // reject it if it has expired. | 90 // reject it if it has expired. |
88 scoped_ptr<CryptoHandshakeMessage> new_scfg_storage; | 91 scoped_ptr<CryptoHandshakeMessage> new_scfg_storage; |
89 const CryptoHandshakeMessage* new_scfg; | 92 const CryptoHandshakeMessage* new_scfg; |
90 | 93 |
91 if (!matches_existing) { | 94 if (!matches_existing) { |
92 new_scfg_storage.reset(CryptoFramer::ParseMessage(server_config)); | 95 new_scfg_storage.reset(CryptoFramer::ParseMessage(server_config)); |
93 new_scfg = new_scfg_storage.get(); | 96 new_scfg = new_scfg_storage.get(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 const vector<string>& certs, | 184 const vector<string>& certs, |
182 StringPiece signature, | 185 StringPiece signature, |
183 QuicWallTime now) { | 186 QuicWallTime now) { |
184 DCHECK(server_config_.empty()); | 187 DCHECK(server_config_.empty()); |
185 | 188 |
186 if (server_config.empty()) { | 189 if (server_config.empty()) { |
187 return false; | 190 return false; |
188 } | 191 } |
189 | 192 |
190 string error_details; | 193 string error_details; |
191 QuicErrorCode error = SetServerConfig(server_config, now, | 194 QuicErrorCode error = SetServerConfig(server_config, now, &error_details); |
192 &error_details); | |
193 if (error != QUIC_NO_ERROR) { | 195 if (error != QUIC_NO_ERROR) { |
194 DVLOG(1) << "SetServerConfig failed with " << error_details; | 196 DVLOG(1) << "SetServerConfig failed with " << error_details; |
195 return false; | 197 return false; |
196 } | 198 } |
197 | 199 |
198 signature.CopyToString(&server_config_sig_); | 200 signature.CopyToString(&server_config_sig_); |
199 source_address_token.CopyToString(&source_address_token_); | 201 source_address_token.CopyToString(&source_address_token_); |
200 certs_ = certs; | 202 certs_ = certs; |
201 return true; | 203 return true; |
202 } | 204 } |
203 | 205 |
204 const string& QuicCryptoClientConfig::CachedState::server_config() const { | 206 const string& QuicCryptoClientConfig::CachedState::server_config() const { |
205 return server_config_; | 207 return server_config_; |
206 } | 208 } |
207 | 209 |
208 const string& | 210 const string& QuicCryptoClientConfig::CachedState::source_address_token() |
209 QuicCryptoClientConfig::CachedState::source_address_token() const { | 211 const { |
210 return source_address_token_; | 212 return source_address_token_; |
211 } | 213 } |
212 | 214 |
213 const vector<string>& QuicCryptoClientConfig::CachedState::certs() const { | 215 const vector<string>& QuicCryptoClientConfig::CachedState::certs() const { |
214 return certs_; | 216 return certs_; |
215 } | 217 } |
216 | 218 |
217 const string& QuicCryptoClientConfig::CachedState::signature() const { | 219 const string& QuicCryptoClientConfig::CachedState::signature() const { |
218 return server_config_sig_; | 220 return server_config_sig_; |
219 } | 221 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 } | 279 } |
278 | 280 |
279 CachedState* cached = new CachedState; | 281 CachedState* cached = new CachedState; |
280 cached_states_.insert(make_pair(server_id, cached)); | 282 cached_states_.insert(make_pair(server_id, cached)); |
281 PopulateFromCanonicalConfig(server_id, cached); | 283 PopulateFromCanonicalConfig(server_id, cached); |
282 return cached; | 284 return cached; |
283 } | 285 } |
284 | 286 |
285 void QuicCryptoClientConfig::ClearCachedStates() { | 287 void QuicCryptoClientConfig::ClearCachedStates() { |
286 for (CachedStateMap::const_iterator it = cached_states_.begin(); | 288 for (CachedStateMap::const_iterator it = cached_states_.begin(); |
287 it != cached_states_.end(); ++it) { | 289 it != cached_states_.end(); |
| 290 ++it) { |
288 it->second->Clear(); | 291 it->second->Clear(); |
289 } | 292 } |
290 } | 293 } |
291 | 294 |
292 void QuicCryptoClientConfig::FillInchoateClientHello( | 295 void QuicCryptoClientConfig::FillInchoateClientHello( |
293 const QuicServerId& server_id, | 296 const QuicServerId& server_id, |
294 const QuicVersion preferred_version, | 297 const QuicVersion preferred_version, |
295 const CachedState* cached, | 298 const CachedState* cached, |
296 QuicCryptoNegotiatedParameters* out_params, | 299 QuicCryptoNegotiatedParameters* out_params, |
297 CryptoHandshakeMessage* out) const { | 300 CryptoHandshakeMessage* out) const { |
(...skipping 25 matching lines...) Expand all Loading... |
323 | 326 |
324 const vector<string>& certs = cached->certs(); | 327 const vector<string>& certs = cached->certs(); |
325 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the | 328 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the |
326 // client config is being used for multiple connections, another connection | 329 // client config is being used for multiple connections, another connection |
327 // doesn't update the cached certificates and cause us to be unable to | 330 // doesn't update the cached certificates and cause us to be unable to |
328 // process the server's compressed certificate chain. | 331 // process the server's compressed certificate chain. |
329 out_params->cached_certs = certs; | 332 out_params->cached_certs = certs; |
330 if (!certs.empty()) { | 333 if (!certs.empty()) { |
331 vector<uint64> hashes; | 334 vector<uint64> hashes; |
332 hashes.reserve(certs.size()); | 335 hashes.reserve(certs.size()); |
333 for (vector<string>::const_iterator i = certs.begin(); | 336 for (vector<string>::const_iterator i = certs.begin(); i != certs.end(); |
334 i != certs.end(); ++i) { | 337 ++i) { |
335 hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size())); | 338 hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size())); |
336 } | 339 } |
337 out->SetVector(kCCRT, hashes); | 340 out->SetVector(kCCRT, hashes); |
338 } | 341 } |
339 } | 342 } |
340 | 343 |
341 QuicErrorCode QuicCryptoClientConfig::FillClientHello( | 344 QuicErrorCode QuicCryptoClientConfig::FillClientHello( |
342 const QuicServerId& server_id, | 345 const QuicServerId& server_id, |
343 QuicConnectionId connection_id, | 346 QuicConnectionId connection_id, |
344 const QuicVersion preferred_version, | 347 const QuicVersion preferred_version, |
345 uint32 initial_flow_control_window_bytes, | 348 uint32 initial_flow_control_window_bytes, |
346 const CachedState* cached, | 349 const CachedState* cached, |
347 QuicWallTime now, | 350 QuicWallTime now, |
348 QuicRandom* rand, | 351 QuicRandom* rand, |
349 QuicCryptoNegotiatedParameters* out_params, | 352 QuicCryptoNegotiatedParameters* out_params, |
350 CryptoHandshakeMessage* out, | 353 CryptoHandshakeMessage* out, |
351 string* error_details) const { | 354 string* error_details) const { |
352 DCHECK(error_details != NULL); | 355 DCHECK(error_details != NULL); |
353 | 356 |
354 FillInchoateClientHello(server_id, preferred_version, cached, | 357 FillInchoateClientHello( |
355 out_params, out); | 358 server_id, preferred_version, cached, out_params, out); |
356 | 359 |
357 // Set initial receive window for flow control. | 360 // Set initial receive window for flow control. |
358 out->SetValue(kIFCW, initial_flow_control_window_bytes); | 361 out->SetValue(kIFCW, initial_flow_control_window_bytes); |
359 | 362 |
360 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); | 363 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); |
361 if (!scfg) { | 364 if (!scfg) { |
362 // This should never happen as our caller should have checked | 365 // This should never happen as our caller should have checked |
363 // cached->IsComplete() before calling this function. | 366 // cached->IsComplete() before calling this function. |
364 *error_details = "Handshake not ready"; | 367 *error_details = "Handshake not ready"; |
365 return QUIC_CRYPTO_INTERNAL_ERROR; | 368 return QUIC_CRYPTO_INTERNAL_ERROR; |
366 } | 369 } |
367 | 370 |
368 StringPiece scid; | 371 StringPiece scid; |
369 if (!scfg->GetStringPiece(kSCID, &scid)) { | 372 if (!scfg->GetStringPiece(kSCID, &scid)) { |
370 *error_details = "SCFG missing SCID"; | 373 *error_details = "SCFG missing SCID"; |
371 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 374 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
372 } | 375 } |
373 out->SetStringPiece(kSCID, scid); | 376 out->SetStringPiece(kSCID, scid); |
374 | 377 |
375 const QuicTag* their_aeads; | 378 const QuicTag* their_aeads; |
376 const QuicTag* their_key_exchanges; | 379 const QuicTag* their_key_exchanges; |
377 size_t num_their_aeads, num_their_key_exchanges; | 380 size_t num_their_aeads, num_their_key_exchanges; |
378 if (scfg->GetTaglist(kAEAD, &their_aeads, | 381 if (scfg->GetTaglist(kAEAD, &their_aeads, &num_their_aeads) != |
379 &num_their_aeads) != QUIC_NO_ERROR || | 382 QUIC_NO_ERROR || |
380 scfg->GetTaglist(kKEXS, &their_key_exchanges, | 383 scfg->GetTaglist(kKEXS, &their_key_exchanges, &num_their_key_exchanges) != |
381 &num_their_key_exchanges) != QUIC_NO_ERROR) { | 384 QUIC_NO_ERROR) { |
382 *error_details = "Missing AEAD or KEXS"; | 385 *error_details = "Missing AEAD or KEXS"; |
383 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 386 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
384 } | 387 } |
385 | 388 |
386 // AEAD: the work loads on the client and server are symmetric. Since the | 389 // AEAD: the work loads on the client and server are symmetric. Since the |
387 // client is more likely to be CPU-constrained, break the tie by favoring | 390 // client is more likely to be CPU-constrained, break the tie by favoring |
388 // the client's preference. | 391 // the client's preference. |
389 // Key exchange: the client does more work than the server, so favor the | 392 // Key exchange: the client does more work than the server, so favor the |
390 // client's preference. | 393 // client's preference. |
391 size_t key_exchange_index; | 394 size_t key_exchange_index; |
392 if (!QuicUtils::FindMutualTag( | 395 if (!QuicUtils::FindMutualTag(aead, |
393 aead, their_aeads, num_their_aeads, QuicUtils::LOCAL_PRIORITY, | 396 their_aeads, |
394 &out_params->aead, NULL) || | 397 num_their_aeads, |
395 !QuicUtils::FindMutualTag( | 398 QuicUtils::LOCAL_PRIORITY, |
396 kexs, their_key_exchanges, num_their_key_exchanges, | 399 &out_params->aead, |
397 QuicUtils::LOCAL_PRIORITY, &out_params->key_exchange, | 400 NULL) || |
398 &key_exchange_index)) { | 401 !QuicUtils::FindMutualTag(kexs, |
| 402 their_key_exchanges, |
| 403 num_their_key_exchanges, |
| 404 QuicUtils::LOCAL_PRIORITY, |
| 405 &out_params->key_exchange, |
| 406 &key_exchange_index)) { |
399 *error_details = "Unsupported AEAD or KEXS"; | 407 *error_details = "Unsupported AEAD or KEXS"; |
400 return QUIC_CRYPTO_NO_SUPPORT; | 408 return QUIC_CRYPTO_NO_SUPPORT; |
401 } | 409 } |
402 out->SetTaglist(kAEAD, out_params->aead, 0); | 410 out->SetTaglist(kAEAD, out_params->aead, 0); |
403 out->SetTaglist(kKEXS, out_params->key_exchange, 0); | 411 out->SetTaglist(kKEXS, out_params->key_exchange, 0); |
404 | 412 |
405 StringPiece public_value; | 413 StringPiece public_value; |
406 if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) != | 414 if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) != |
407 QUIC_NO_ERROR) { | 415 QUIC_NO_ERROR) { |
408 *error_details = "Missing public value"; | 416 *error_details = "Missing public value"; |
409 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 417 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
410 } | 418 } |
411 | 419 |
412 StringPiece orbit; | 420 StringPiece orbit; |
413 if (!scfg->GetStringPiece(kORBT, &orbit) || orbit.size() != kOrbitSize) { | 421 if (!scfg->GetStringPiece(kORBT, &orbit) || orbit.size() != kOrbitSize) { |
414 *error_details = "SCFG missing OBIT"; | 422 *error_details = "SCFG missing OBIT"; |
415 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; | 423 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; |
416 } | 424 } |
417 | 425 |
418 CryptoUtils::GenerateNonce(now, rand, orbit, &out_params->client_nonce); | 426 CryptoUtils::GenerateNonce(now, rand, orbit, &out_params->client_nonce); |
419 out->SetStringPiece(kNONC, out_params->client_nonce); | 427 out->SetStringPiece(kNONC, out_params->client_nonce); |
420 if (!out_params->server_nonce.empty()) { | 428 if (!out_params->server_nonce.empty()) { |
421 out->SetStringPiece(kServerNonceTag, out_params->server_nonce); | 429 out->SetStringPiece(kServerNonceTag, out_params->server_nonce); |
422 } | 430 } |
423 | 431 |
424 switch (out_params->key_exchange) { | 432 switch (out_params->key_exchange) { |
425 case kC255: | 433 case kC255: |
426 out_params->client_key_exchange.reset(Curve25519KeyExchange::New( | 434 out_params->client_key_exchange.reset(Curve25519KeyExchange::New( |
427 Curve25519KeyExchange::NewPrivateKey(rand))); | 435 Curve25519KeyExchange::NewPrivateKey(rand))); |
428 break; | 436 break; |
429 case kP256: | 437 case kP256: |
430 out_params->client_key_exchange.reset(P256KeyExchange::New( | 438 out_params->client_key_exchange.reset( |
431 P256KeyExchange::NewPrivateKey())); | 439 P256KeyExchange::New(P256KeyExchange::NewPrivateKey())); |
432 break; | 440 break; |
433 default: | 441 default: |
434 DCHECK(false); | 442 DCHECK(false); |
435 *error_details = "Configured to support an unknown key exchange"; | 443 *error_details = "Configured to support an unknown key exchange"; |
436 return QUIC_CRYPTO_INTERNAL_ERROR; | 444 return QUIC_CRYPTO_INTERNAL_ERROR; |
437 } | 445 } |
438 | 446 |
439 if (!out_params->client_key_exchange->CalculateSharedKey( | 447 if (!out_params->client_key_exchange->CalculateSharedKey( |
440 public_value, &out_params->initial_premaster_secret)) { | 448 public_value, &out_params->initial_premaster_secret)) { |
441 *error_details = "Key exchange failure"; | 449 *error_details = "Key exchange failure"; |
442 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 450 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
443 } | 451 } |
444 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value()); | 452 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value()); |
445 | 453 |
446 bool do_channel_id = false; | 454 bool do_channel_id = false; |
447 if (channel_id_signer_.get()) { | 455 if (channel_id_signer_.get()) { |
448 const QuicTag* their_proof_demands; | 456 const QuicTag* their_proof_demands; |
449 size_t num_their_proof_demands; | 457 size_t num_their_proof_demands; |
450 if (scfg->GetTaglist(kPDMD, &their_proof_demands, | 458 if (scfg->GetTaglist(kPDMD, |
| 459 &their_proof_demands, |
451 &num_their_proof_demands) == QUIC_NO_ERROR) { | 460 &num_their_proof_demands) == QUIC_NO_ERROR) { |
452 for (size_t i = 0; i < num_their_proof_demands; i++) { | 461 for (size_t i = 0; i < num_their_proof_demands; i++) { |
453 if (their_proof_demands[i] == kCHID) { | 462 if (their_proof_demands[i] == kCHID) { |
454 do_channel_id = true; | 463 do_channel_id = true; |
455 break; | 464 break; |
456 } | 465 } |
457 } | 466 } |
458 } | 467 } |
459 } | 468 } |
460 | 469 |
(...skipping 11 matching lines...) Expand all Loading... |
472 const QuicData& client_hello_serialized = out->GetSerialized(); | 481 const QuicData& client_hello_serialized = out->GetSerialized(); |
473 hkdf_input.append(QuicCryptoConfig::kCETVLabel, | 482 hkdf_input.append(QuicCryptoConfig::kCETVLabel, |
474 strlen(QuicCryptoConfig::kCETVLabel) + 1); | 483 strlen(QuicCryptoConfig::kCETVLabel) + 1); |
475 hkdf_input.append(reinterpret_cast<char*>(&connection_id), | 484 hkdf_input.append(reinterpret_cast<char*>(&connection_id), |
476 sizeof(connection_id)); | 485 sizeof(connection_id)); |
477 hkdf_input.append(client_hello_serialized.data(), | 486 hkdf_input.append(client_hello_serialized.data(), |
478 client_hello_serialized.length()); | 487 client_hello_serialized.length()); |
479 hkdf_input.append(cached->server_config()); | 488 hkdf_input.append(cached->server_config()); |
480 | 489 |
481 string key, signature; | 490 string key, signature; |
482 if (!channel_id_signer_->Sign(server_id.host(), hkdf_input, | 491 if (!channel_id_signer_->Sign( |
483 &key, &signature)) { | 492 server_id.host(), hkdf_input, &key, &signature)) { |
484 *error_details = "Channel ID signature failed"; | 493 *error_details = "Channel ID signature failed"; |
485 return QUIC_INVALID_CHANNEL_ID_SIGNATURE; | 494 return QUIC_INVALID_CHANNEL_ID_SIGNATURE; |
486 } | 495 } |
487 | 496 |
488 cetv.SetStringPiece(kCIDK, key); | 497 cetv.SetStringPiece(kCIDK, key); |
489 cetv.SetStringPiece(kCIDS, signature); | 498 cetv.SetStringPiece(kCIDS, signature); |
490 | 499 |
491 CrypterPair crypters; | 500 CrypterPair crypters; |
492 if (!CryptoUtils::DeriveKeys(out_params->initial_premaster_secret, | 501 if (!CryptoUtils::DeriveKeys(out_params->initial_premaster_secret, |
493 out_params->aead, out_params->client_nonce, | 502 out_params->aead, |
494 out_params->server_nonce, hkdf_input, | 503 out_params->client_nonce, |
495 CryptoUtils::CLIENT, &crypters)) { | 504 out_params->server_nonce, |
| 505 hkdf_input, |
| 506 CryptoUtils::CLIENT, |
| 507 &crypters)) { |
496 *error_details = "Symmetric key setup failed"; | 508 *error_details = "Symmetric key setup failed"; |
497 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 509 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
498 } | 510 } |
499 | 511 |
500 const QuicData& cetv_plaintext = cetv.GetSerialized(); | 512 const QuicData& cetv_plaintext = cetv.GetSerialized(); |
501 scoped_ptr<QuicData> cetv_ciphertext(crypters.encrypter->EncryptPacket( | 513 scoped_ptr<QuicData> cetv_ciphertext( |
502 0 /* sequence number */, | 514 crypters.encrypter->EncryptPacket(0 /* sequence number */, |
503 StringPiece() /* associated data */, | 515 StringPiece() /* associated data */, |
504 cetv_plaintext.AsStringPiece())); | 516 cetv_plaintext.AsStringPiece())); |
505 if (!cetv_ciphertext.get()) { | 517 if (!cetv_ciphertext.get()) { |
506 *error_details = "Packet encryption failed"; | 518 *error_details = "Packet encryption failed"; |
507 return QUIC_ENCRYPTION_FAILURE; | 519 return QUIC_ENCRYPTION_FAILURE; |
508 } | 520 } |
509 | 521 |
510 out->SetStringPiece(kCETV, cetv_ciphertext->AsStringPiece()); | 522 out->SetStringPiece(kCETV, cetv_ciphertext->AsStringPiece()); |
511 out->MarkDirty(); | 523 out->MarkDirty(); |
512 | 524 |
513 out->set_minimum_size(orig_min_size); | 525 out->set_minimum_size(orig_min_size); |
514 } | 526 } |
515 | 527 |
516 out_params->hkdf_input_suffix.clear(); | 528 out_params->hkdf_input_suffix.clear(); |
517 out_params->hkdf_input_suffix.append(reinterpret_cast<char*>(&connection_id), | 529 out_params->hkdf_input_suffix.append(reinterpret_cast<char*>(&connection_id), |
518 sizeof(connection_id)); | 530 sizeof(connection_id)); |
519 const QuicData& client_hello_serialized = out->GetSerialized(); | 531 const QuicData& client_hello_serialized = out->GetSerialized(); |
520 out_params->hkdf_input_suffix.append(client_hello_serialized.data(), | 532 out_params->hkdf_input_suffix.append(client_hello_serialized.data(), |
521 client_hello_serialized.length()); | 533 client_hello_serialized.length()); |
522 out_params->hkdf_input_suffix.append(cached->server_config()); | 534 out_params->hkdf_input_suffix.append(cached->server_config()); |
523 | 535 |
524 string hkdf_input; | 536 string hkdf_input; |
525 const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; | 537 const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; |
526 hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size()); | 538 hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size()); |
527 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); | 539 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); |
528 hkdf_input.append(out_params->hkdf_input_suffix); | 540 hkdf_input.append(out_params->hkdf_input_suffix); |
529 | 541 |
530 if (!CryptoUtils::DeriveKeys( | 542 if (!CryptoUtils::DeriveKeys(out_params->initial_premaster_secret, |
531 out_params->initial_premaster_secret, out_params->aead, | 543 out_params->aead, |
532 out_params->client_nonce, out_params->server_nonce, hkdf_input, | 544 out_params->client_nonce, |
533 CryptoUtils::CLIENT, &out_params->initial_crypters)) { | 545 out_params->server_nonce, |
| 546 hkdf_input, |
| 547 CryptoUtils::CLIENT, |
| 548 &out_params->initial_crypters)) { |
534 *error_details = "Symmetric key setup failed"; | 549 *error_details = "Symmetric key setup failed"; |
535 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 550 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
536 } | 551 } |
537 | 552 |
538 return QUIC_NO_ERROR; | 553 return QUIC_NO_ERROR; |
539 } | 554 } |
540 | 555 |
541 QuicErrorCode QuicCryptoClientConfig::ProcessRejection( | 556 QuicErrorCode QuicCryptoClientConfig::ProcessRejection( |
542 const CryptoHandshakeMessage& rej, | 557 const CryptoHandshakeMessage& rej, |
543 QuicWallTime now, | 558 QuicWallTime now, |
(...skipping 26 matching lines...) Expand all Loading... |
570 StringPiece nonce; | 585 StringPiece nonce; |
571 if (rej.GetStringPiece(kServerNonceTag, &nonce)) { | 586 if (rej.GetStringPiece(kServerNonceTag, &nonce)) { |
572 out_params->server_nonce = nonce.as_string(); | 587 out_params->server_nonce = nonce.as_string(); |
573 } | 588 } |
574 | 589 |
575 StringPiece proof, cert_bytes; | 590 StringPiece proof, cert_bytes; |
576 bool has_proof = rej.GetStringPiece(kPROF, &proof); | 591 bool has_proof = rej.GetStringPiece(kPROF, &proof); |
577 bool has_cert = rej.GetStringPiece(kCertificateTag, &cert_bytes); | 592 bool has_cert = rej.GetStringPiece(kCertificateTag, &cert_bytes); |
578 if (has_proof && has_cert) { | 593 if (has_proof && has_cert) { |
579 vector<string> certs; | 594 vector<string> certs; |
580 if (!CertCompressor::DecompressChain(cert_bytes, out_params->cached_certs, | 595 if (!CertCompressor::DecompressChain( |
581 common_cert_sets, &certs)) { | 596 cert_bytes, out_params->cached_certs, common_cert_sets, &certs)) { |
582 *error_details = "Certificate data invalid"; | 597 *error_details = "Certificate data invalid"; |
583 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 598 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
584 } | 599 } |
585 | 600 |
586 cached->SetProof(certs, proof); | 601 cached->SetProof(certs, proof); |
587 } else { | 602 } else { |
588 cached->ClearProof(); | 603 cached->ClearProof(); |
589 if (has_proof && !has_cert) { | 604 if (has_proof && !has_cert) { |
590 *error_details = "Certificate missing"; | 605 *error_details = "Certificate missing"; |
591 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 606 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
(...skipping 18 matching lines...) Expand all Loading... |
610 DCHECK(error_details != NULL); | 625 DCHECK(error_details != NULL); |
611 | 626 |
612 if (server_hello.tag() != kSHLO) { | 627 if (server_hello.tag() != kSHLO) { |
613 *error_details = "Bad tag"; | 628 *error_details = "Bad tag"; |
614 return QUIC_INVALID_CRYPTO_MESSAGE_TYPE; | 629 return QUIC_INVALID_CRYPTO_MESSAGE_TYPE; |
615 } | 630 } |
616 | 631 |
617 const QuicTag* supported_version_tags; | 632 const QuicTag* supported_version_tags; |
618 size_t num_supported_versions; | 633 size_t num_supported_versions; |
619 | 634 |
620 if (server_hello.GetTaglist(kVER, &supported_version_tags, | 635 if (server_hello.GetTaglist(kVER, |
| 636 &supported_version_tags, |
621 &num_supported_versions) != QUIC_NO_ERROR) { | 637 &num_supported_versions) != QUIC_NO_ERROR) { |
622 *error_details = "server hello missing version list"; | 638 *error_details = "server hello missing version list"; |
623 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 639 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
624 } | 640 } |
625 if (!negotiated_versions.empty()) { | 641 if (!negotiated_versions.empty()) { |
626 bool mismatch = num_supported_versions != negotiated_versions.size(); | 642 bool mismatch = num_supported_versions != negotiated_versions.size(); |
627 for (size_t i = 0; i < num_supported_versions && !mismatch; ++i) { | 643 for (size_t i = 0; i < num_supported_versions && !mismatch; ++i) { |
628 mismatch = QuicTagToQuicVersion(supported_version_tags[i]) != | 644 mismatch = QuicTagToQuicVersion(supported_version_tags[i]) != |
629 negotiated_versions[i]; | 645 negotiated_versions[i]; |
630 } | 646 } |
631 // The server sent a list of supported versions, and the connection | 647 // The server sent a list of supported versions, and the connection |
632 // reports that there was a version negotiation during the handshake. | 648 // reports that there was a version negotiation during the handshake. |
633 // Ensure that these two lists are identical. | 649 // Ensure that these two lists are identical. |
634 if (mismatch) { | 650 if (mismatch) { |
635 *error_details = "Downgrade attack detected"; | 651 *error_details = "Downgrade attack detected"; |
636 return QUIC_VERSION_NEGOTIATION_MISMATCH; | 652 return QUIC_VERSION_NEGOTIATION_MISMATCH; |
637 } | 653 } |
638 } | 654 } |
639 | 655 |
640 // Learn about updated source address tokens. | 656 // Learn about updated source address tokens. |
641 StringPiece token; | 657 StringPiece token; |
642 if (server_hello.GetStringPiece(kSourceAddressTokenTag, &token)) { | 658 if (server_hello.GetStringPiece(kSourceAddressTokenTag, &token)) { |
643 cached->set_source_address_token(token); | 659 cached->set_source_address_token(token); |
(...skipping 13 matching lines...) Expand all Loading... |
657 *error_details = "Key exchange failure"; | 673 *error_details = "Key exchange failure"; |
658 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 674 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
659 } | 675 } |
660 | 676 |
661 string hkdf_input; | 677 string hkdf_input; |
662 const size_t label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; | 678 const size_t label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; |
663 hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size()); | 679 hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size()); |
664 hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, label_len); | 680 hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, label_len); |
665 hkdf_input.append(out_params->hkdf_input_suffix); | 681 hkdf_input.append(out_params->hkdf_input_suffix); |
666 | 682 |
667 if (!CryptoUtils::DeriveKeys( | 683 if (!CryptoUtils::DeriveKeys(out_params->forward_secure_premaster_secret, |
668 out_params->forward_secure_premaster_secret, out_params->aead, | 684 out_params->aead, |
669 out_params->client_nonce, out_params->server_nonce, hkdf_input, | 685 out_params->client_nonce, |
670 CryptoUtils::CLIENT, &out_params->forward_secure_crypters)) { | 686 out_params->server_nonce, |
| 687 hkdf_input, |
| 688 CryptoUtils::CLIENT, |
| 689 &out_params->forward_secure_crypters)) { |
671 *error_details = "Symmetric key setup failed"; | 690 *error_details = "Symmetric key setup failed"; |
672 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 691 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
673 } | 692 } |
674 | 693 |
675 return QUIC_NO_ERROR; | 694 return QUIC_NO_ERROR; |
676 } | 695 } |
677 | 696 |
678 ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { | 697 ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { |
679 return proof_verifier_.get(); | 698 return proof_verifier_.get(); |
680 } | 699 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 DCHECK(server_state->IsEmpty()); | 749 DCHECK(server_state->IsEmpty()); |
731 size_t i = 0; | 750 size_t i = 0; |
732 for (; i < canoncial_suffixes_.size(); ++i) { | 751 for (; i < canoncial_suffixes_.size(); ++i) { |
733 if (EndsWith(server_id.host(), canoncial_suffixes_[i], false)) { | 752 if (EndsWith(server_id.host(), canoncial_suffixes_[i], false)) { |
734 break; | 753 break; |
735 } | 754 } |
736 } | 755 } |
737 if (i == canoncial_suffixes_.size()) | 756 if (i == canoncial_suffixes_.size()) |
738 return; | 757 return; |
739 | 758 |
740 QuicServerId suffix_server_id(canoncial_suffixes_[i], server_id.port(), | 759 QuicServerId suffix_server_id(canoncial_suffixes_[i], |
| 760 server_id.port(), |
741 server_id.is_https(), | 761 server_id.is_https(), |
742 server_id.privacy_mode()); | 762 server_id.privacy_mode()); |
743 if (!ContainsKey(canonical_server_map_, suffix_server_id)) { | 763 if (!ContainsKey(canonical_server_map_, suffix_server_id)) { |
744 // This is the first host we've seen which matches the suffix, so make it | 764 // This is the first host we've seen which matches the suffix, so make it |
745 // canonical. | 765 // canonical. |
746 canonical_server_map_[suffix_server_id] = server_id; | 766 canonical_server_map_[suffix_server_id] = server_id; |
747 return; | 767 return; |
748 } | 768 } |
749 | 769 |
750 const QuicServerId& canonical_server_id = | 770 const QuicServerId& canonical_server_id = |
751 canonical_server_map_[suffix_server_id]; | 771 canonical_server_map_[suffix_server_id]; |
752 CachedState* canonical_state = cached_states_[canonical_server_id]; | 772 CachedState* canonical_state = cached_states_[canonical_server_id]; |
753 if (!canonical_state->proof_valid()) { | 773 if (!canonical_state->proof_valid()) { |
754 return; | 774 return; |
755 } | 775 } |
756 | 776 |
757 // Update canonical version to point at the "most recent" entry. | 777 // Update canonical version to point at the "most recent" entry. |
758 canonical_server_map_[suffix_server_id] = server_id; | 778 canonical_server_map_[suffix_server_id] = server_id; |
759 | 779 |
760 server_state->InitializeFrom(*canonical_state); | 780 server_state->InitializeFrom(*canonical_state); |
761 } | 781 } |
762 | 782 |
763 } // namespace net | 783 } // namespace net |
OLD | NEW |