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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 } | 343 } |
344 | 344 |
345 QuicErrorCode QuicCryptoClientConfig::FillClientHello( | 345 QuicErrorCode QuicCryptoClientConfig::FillClientHello( |
346 const QuicServerId& server_id, | 346 const QuicServerId& server_id, |
347 QuicConnectionId connection_id, | 347 QuicConnectionId connection_id, |
348 const QuicVersion preferred_version, | 348 const QuicVersion preferred_version, |
349 uint32 initial_flow_control_window_bytes, | 349 uint32 initial_flow_control_window_bytes, |
350 const CachedState* cached, | 350 const CachedState* cached, |
351 QuicWallTime now, | 351 QuicWallTime now, |
352 QuicRandom* rand, | 352 QuicRandom* rand, |
| 353 const ChannelIDKey* channel_id_key, |
353 QuicCryptoNegotiatedParameters* out_params, | 354 QuicCryptoNegotiatedParameters* out_params, |
354 CryptoHandshakeMessage* out, | 355 CryptoHandshakeMessage* out, |
355 string* error_details) const { | 356 string* error_details) const { |
356 DCHECK(error_details != NULL); | 357 DCHECK(error_details != NULL); |
357 | 358 |
358 FillInchoateClientHello(server_id, preferred_version, cached, | 359 FillInchoateClientHello(server_id, preferred_version, cached, |
359 out_params, out); | 360 out_params, out); |
360 | 361 |
361 // Set initial receive window for flow control. | 362 // Set initial receive window for flow control. |
362 out->SetValue(kIFCW, initial_flow_control_window_bytes); | 363 out->SetValue(kIFCW, initial_flow_control_window_bytes); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 return QUIC_CRYPTO_INTERNAL_ERROR; | 441 return QUIC_CRYPTO_INTERNAL_ERROR; |
441 } | 442 } |
442 | 443 |
443 if (!out_params->client_key_exchange->CalculateSharedKey( | 444 if (!out_params->client_key_exchange->CalculateSharedKey( |
444 public_value, &out_params->initial_premaster_secret)) { | 445 public_value, &out_params->initial_premaster_secret)) { |
445 *error_details = "Key exchange failure"; | 446 *error_details = "Key exchange failure"; |
446 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 447 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
447 } | 448 } |
448 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value()); | 449 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value()); |
449 | 450 |
450 bool do_channel_id = false; | 451 if (channel_id_key) { |
451 if (channel_id_source_.get()) { | |
452 const QuicTag* their_proof_demands; | |
453 size_t num_their_proof_demands; | |
454 if (scfg->GetTaglist(kPDMD, &their_proof_demands, | |
455 &num_their_proof_demands) == QUIC_NO_ERROR) { | |
456 for (size_t i = 0; i < num_their_proof_demands; i++) { | |
457 if (their_proof_demands[i] == kCHID) { | |
458 do_channel_id = true; | |
459 break; | |
460 } | |
461 } | |
462 } | |
463 } | |
464 | |
465 if (do_channel_id) { | |
466 // In order to calculate the encryption key for the CETV block we need to | 452 // In order to calculate the encryption key for the CETV block we need to |
467 // serialise the client hello as it currently is (i.e. without the CETV | 453 // serialise the client hello as it currently is (i.e. without the CETV |
468 // block). For this, the client hello is serialized without padding. | 454 // block). For this, the client hello is serialized without padding. |
469 const size_t orig_min_size = out->minimum_size(); | 455 const size_t orig_min_size = out->minimum_size(); |
470 out->set_minimum_size(0); | 456 out->set_minimum_size(0); |
471 | 457 |
472 CryptoHandshakeMessage cetv; | 458 CryptoHandshakeMessage cetv; |
473 cetv.set_tag(kCETV); | 459 cetv.set_tag(kCETV); |
474 | 460 |
475 string hkdf_input; | 461 string hkdf_input; |
476 const QuicData& client_hello_serialized = out->GetSerialized(); | 462 const QuicData& client_hello_serialized = out->GetSerialized(); |
477 hkdf_input.append(QuicCryptoConfig::kCETVLabel, | 463 hkdf_input.append(QuicCryptoConfig::kCETVLabel, |
478 strlen(QuicCryptoConfig::kCETVLabel) + 1); | 464 strlen(QuicCryptoConfig::kCETVLabel) + 1); |
479 hkdf_input.append(reinterpret_cast<char*>(&connection_id), | 465 hkdf_input.append(reinterpret_cast<char*>(&connection_id), |
480 sizeof(connection_id)); | 466 sizeof(connection_id)); |
481 hkdf_input.append(client_hello_serialized.data(), | 467 hkdf_input.append(client_hello_serialized.data(), |
482 client_hello_serialized.length()); | 468 client_hello_serialized.length()); |
483 hkdf_input.append(cached->server_config()); | 469 hkdf_input.append(cached->server_config()); |
484 | 470 |
485 scoped_ptr<ChannelIDKey> channel_id_key; | |
486 if (!channel_id_source_->GetChannelIDKey(server_id.host(), | |
487 &channel_id_key)) { | |
488 *error_details = "Channel ID lookup failed"; | |
489 return QUIC_INVALID_CHANNEL_ID_SIGNATURE; | |
490 } | |
491 string key = channel_id_key->SerializeKey(); | 471 string key = channel_id_key->SerializeKey(); |
492 string signature; | 472 string signature; |
493 if (!channel_id_key->Sign(hkdf_input, &signature)) { | 473 if (!channel_id_key->Sign(hkdf_input, &signature)) { |
494 *error_details = "Channel ID signature failed"; | 474 *error_details = "Channel ID signature failed"; |
495 return QUIC_INVALID_CHANNEL_ID_SIGNATURE; | 475 return QUIC_INVALID_CHANNEL_ID_SIGNATURE; |
496 } | 476 } |
497 | 477 |
498 cetv.SetStringPiece(kCIDK, key); | 478 cetv.SetStringPiece(kCIDK, key); |
499 cetv.SetStringPiece(kCIDS, signature); | 479 cetv.SetStringPiece(kCIDS, signature); |
500 | 480 |
(...skipping 15 matching lines...) Expand all Loading... |
516 *error_details = "Packet encryption failed"; | 496 *error_details = "Packet encryption failed"; |
517 return QUIC_ENCRYPTION_FAILURE; | 497 return QUIC_ENCRYPTION_FAILURE; |
518 } | 498 } |
519 | 499 |
520 out->SetStringPiece(kCETV, cetv_ciphertext->AsStringPiece()); | 500 out->SetStringPiece(kCETV, cetv_ciphertext->AsStringPiece()); |
521 out->MarkDirty(); | 501 out->MarkDirty(); |
522 | 502 |
523 out->set_minimum_size(orig_min_size); | 503 out->set_minimum_size(orig_min_size); |
524 } | 504 } |
525 | 505 |
| 506 // Derive the symmetric keys and set up the encrypters and decrypters. |
| 507 // Set the following members of out_params: |
| 508 // out_params->hkdf_input_suffix |
| 509 // out_params->initial_crypters |
526 out_params->hkdf_input_suffix.clear(); | 510 out_params->hkdf_input_suffix.clear(); |
527 out_params->hkdf_input_suffix.append(reinterpret_cast<char*>(&connection_id), | 511 out_params->hkdf_input_suffix.append(reinterpret_cast<char*>(&connection_id), |
528 sizeof(connection_id)); | 512 sizeof(connection_id)); |
529 const QuicData& client_hello_serialized = out->GetSerialized(); | 513 const QuicData& client_hello_serialized = out->GetSerialized(); |
530 out_params->hkdf_input_suffix.append(client_hello_serialized.data(), | 514 out_params->hkdf_input_suffix.append(client_hello_serialized.data(), |
531 client_hello_serialized.length()); | 515 client_hello_serialized.length()); |
532 out_params->hkdf_input_suffix.append(cached->server_config()); | 516 out_params->hkdf_input_suffix.append(cached->server_config()); |
533 | 517 |
534 string hkdf_input; | 518 string hkdf_input; |
535 const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; | 519 const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 return; | 748 return; |
765 } | 749 } |
766 | 750 |
767 // Update canonical version to point at the "most recent" entry. | 751 // Update canonical version to point at the "most recent" entry. |
768 canonical_server_map_[suffix_server_id] = server_id; | 752 canonical_server_map_[suffix_server_id] = server_id; |
769 | 753 |
770 server_state->InitializeFrom(*canonical_state); | 754 server_state->InitializeFrom(*canonical_state); |
771 } | 755 } |
772 | 756 |
773 } // namespace net | 757 } // namespace net |
OLD | NEW |