| 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 |