| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/crypto_handshake.h" | 5 #include "net/quic/crypto/crypto_handshake.h" |
| 6 | 6 |
| 7 #include <ctype.h> | 7 #include <ctype.h> |
| 8 | 8 |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 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 "base/strings/string_split.h" | 12 #include "base/strings/string_split.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/cert_compressor.h" | |
| 16 #include "net/quic/crypto/common_cert_set.h" | |
| 17 #include "net/quic/crypto/crypto_framer.h" | 15 #include "net/quic/crypto/crypto_framer.h" |
| 18 #include "net/quic/crypto/crypto_utils.h" | 16 #include "net/quic/crypto/crypto_utils.h" |
| 19 #include "net/quic/crypto/curve25519_key_exchange.h" | 17 #include "net/quic/crypto/curve25519_key_exchange.h" |
| 20 #include "net/quic/crypto/key_exchange.h" | 18 #include "net/quic/crypto/key_exchange.h" |
| 21 #include "net/quic/crypto/p256_key_exchange.h" | 19 #include "net/quic/crypto/p256_key_exchange.h" |
| 22 #include "net/quic/crypto/proof_verifier.h" | 20 #include "net/quic/crypto/proof_verifier.h" |
| 23 #include "net/quic/crypto/quic_decrypter.h" | 21 #include "net/quic/crypto/quic_decrypter.h" |
| 24 #include "net/quic/crypto/quic_encrypter.h" | 22 #include "net/quic/crypto/quic_encrypter.h" |
| 25 #include "net/quic/crypto/quic_random.h" | 23 #include "net/quic/crypto/quic_random.h" |
| 26 #include "net/quic/quic_clock.h" | 24 #include "net/quic/quic_clock.h" |
| 27 #include "net/quic/quic_protocol.h" | 25 #include "net/quic/quic_protocol.h" |
| 28 #include "net/quic/quic_utils.h" | |
| 29 | 26 |
| 30 using base::StringPiece; | 27 using base::StringPiece; |
| 31 using std::map; | 28 using std::map; |
| 32 using std::string; | 29 using std::string; |
| 33 using std::vector; | 30 using std::vector; |
| 34 | 31 |
| 35 namespace net { | 32 namespace net { |
| 36 | 33 |
| 37 CryptoHandshakeMessage::CryptoHandshakeMessage() : tag_(0) {} | 34 CryptoHandshakeMessage::CryptoHandshakeMessage() : tag_(0) {} |
| 38 | 35 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 } | 98 } |
| 102 | 99 |
| 103 void CryptoHandshakeMessage::SetStringPiece(CryptoTag tag, StringPiece value) { | 100 void CryptoHandshakeMessage::SetStringPiece(CryptoTag tag, StringPiece value) { |
| 104 tag_value_map_[tag] = value.as_string(); | 101 tag_value_map_[tag] = value.as_string(); |
| 105 } | 102 } |
| 106 | 103 |
| 107 QuicErrorCode CryptoHandshakeMessage::GetTaglist(CryptoTag tag, | 104 QuicErrorCode CryptoHandshakeMessage::GetTaglist(CryptoTag tag, |
| 108 const CryptoTag** out_tags, | 105 const CryptoTag** out_tags, |
| 109 size_t* out_len) const { | 106 size_t* out_len) const { |
| 110 CryptoTagValueMap::const_iterator it = tag_value_map_.find(tag); | 107 CryptoTagValueMap::const_iterator it = tag_value_map_.find(tag); |
| 111 *out_len = 0; | |
| 112 QuicErrorCode ret = QUIC_NO_ERROR; | 108 QuicErrorCode ret = QUIC_NO_ERROR; |
| 113 | 109 |
| 114 if (it == tag_value_map_.end()) { | 110 if (it == tag_value_map_.end()) { |
| 115 ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; | 111 ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; |
| 116 } else if (it->second.size() % sizeof(CryptoTag) != 0) { | 112 } else if (it->second.size() % sizeof(CryptoTag) != 0) { |
| 117 ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 113 ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 118 } | 114 } |
| 119 | 115 |
| 120 if (ret != QUIC_NO_ERROR) { | 116 if (ret != QUIC_NO_ERROR) { |
| 121 *out_tags = NULL; | 117 *out_tags = NULL; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 } | 310 } |
| 315 | 311 |
| 316 QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() { | 312 QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() { |
| 317 } | 313 } |
| 318 | 314 |
| 319 | 315 |
| 320 // static | 316 // static |
| 321 const char QuicCryptoConfig::kLabel[] = "QUIC key expansion"; | 317 const char QuicCryptoConfig::kLabel[] = "QUIC key expansion"; |
| 322 | 318 |
| 323 QuicCryptoConfig::QuicCryptoConfig() | 319 QuicCryptoConfig::QuicCryptoConfig() |
| 324 : version(0), | 320 : version(0) { |
| 325 common_cert_set_(new CommonCertSetQUIC) { | |
| 326 } | 321 } |
| 327 | 322 |
| 328 QuicCryptoConfig::~QuicCryptoConfig() {} | 323 QuicCryptoConfig::~QuicCryptoConfig() {} |
| 329 | 324 |
| 330 QuicCryptoClientConfig::QuicCryptoClientConfig() {} | 325 QuicCryptoClientConfig::QuicCryptoClientConfig() {} |
| 331 | 326 |
| 332 QuicCryptoClientConfig::~QuicCryptoClientConfig() { | 327 QuicCryptoClientConfig::~QuicCryptoClientConfig() { |
| 333 STLDeleteValues(&cached_states_); | 328 STLDeleteValues(&cached_states_); |
| 334 } | 329 } |
| 335 | 330 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 359 StringPiece scfg) { | 354 StringPiece scfg) { |
| 360 scfg_.reset(CryptoFramer::ParseMessage(scfg)); | 355 scfg_.reset(CryptoFramer::ParseMessage(scfg)); |
| 361 if (!scfg_.get()) { | 356 if (!scfg_.get()) { |
| 362 return false; | 357 return false; |
| 363 } | 358 } |
| 364 server_config_ = scfg.as_string(); | 359 server_config_ = scfg.as_string(); |
| 365 return true; | 360 return true; |
| 366 } | 361 } |
| 367 | 362 |
| 368 void QuicCryptoClientConfig::CachedState::SetProof( | 363 void QuicCryptoClientConfig::CachedState::SetProof( |
| 369 const vector<string>& certs, StringPiece signature) { | 364 const vector<StringPiece>& certs, StringPiece signature) { |
| 370 bool has_changed = signature != server_config_sig_; | 365 bool has_changed = signature != server_config_sig_; |
| 371 | 366 |
| 372 if (certs_.size() != certs.size()) { | 367 if (certs.size() != certs_.size()) { |
| 373 has_changed = true; | 368 has_changed = true; |
| 374 } | 369 } |
| 375 if (!has_changed) { | 370 if (!has_changed) { |
| 376 for (size_t i = 0; i < certs_.size(); i++) { | 371 for (size_t i = 0; i < certs_.size(); i++) { |
| 377 if (certs_[i] != certs[i]) { | 372 if (certs[i] != certs_[i]) { |
| 378 has_changed = true; | 373 has_changed = true; |
| 379 break; | 374 break; |
| 380 } | 375 } |
| 381 } | 376 } |
| 382 } | 377 } |
| 383 | 378 |
| 384 if (!has_changed) { | 379 if (!has_changed) { |
| 385 return; | 380 return; |
| 386 } | 381 } |
| 387 | 382 |
| 388 // If the proof has changed then it needs to be revalidated. | 383 // If the proof has changed then it needs to be revalidated. |
| 389 server_config_valid_ = false; | 384 server_config_valid_ = false; |
| 390 certs_ = certs; | 385 certs_.clear(); |
| 386 for (vector<StringPiece>::const_iterator i = certs.begin(); |
| 387 i != certs.end(); ++i) { |
| 388 certs_.push_back(i->as_string()); |
| 389 } |
| 391 server_config_sig_ = signature.as_string(); | 390 server_config_sig_ = signature.as_string(); |
| 392 } | 391 } |
| 393 | 392 |
| 394 void QuicCryptoClientConfig::CachedState::SetProofValid() { | 393 void QuicCryptoClientConfig::CachedState::SetProofValid() { |
| 395 server_config_valid_ = true; | 394 server_config_valid_ = true; |
| 396 } | 395 } |
| 397 | 396 |
| 398 const string& | 397 const string& |
| 399 QuicCryptoClientConfig::CachedState::server_config() const { | 398 QuicCryptoClientConfig::CachedState::server_config() const { |
| 400 return server_config_; | 399 return server_config_; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 } | 444 } |
| 446 | 445 |
| 447 CachedState* cached = new CachedState; | 446 CachedState* cached = new CachedState; |
| 448 cached_states_.insert(make_pair(server_hostname, cached)); | 447 cached_states_.insert(make_pair(server_hostname, cached)); |
| 449 return cached; | 448 return cached; |
| 450 } | 449 } |
| 451 | 450 |
| 452 void QuicCryptoClientConfig::FillInchoateClientHello( | 451 void QuicCryptoClientConfig::FillInchoateClientHello( |
| 453 const string& server_hostname, | 452 const string& server_hostname, |
| 454 const CachedState* cached, | 453 const CachedState* cached, |
| 455 QuicCryptoNegotiatedParameters* out_params, | |
| 456 CryptoHandshakeMessage* out) const { | 454 CryptoHandshakeMessage* out) const { |
| 457 out->set_tag(kCHLO); | 455 out->set_tag(kCHLO); |
| 458 | 456 |
| 459 // Server name indication. | 457 // Server name indication. |
| 460 // If server_hostname is not an IP address literal, it is a DNS hostname. | 458 // If server_hostname is not an IP address literal, it is a DNS hostname. |
| 461 IPAddressNumber ip; | 459 IPAddressNumber ip; |
| 462 if (!server_hostname.empty() && | 460 if (!server_hostname.empty() && |
| 463 !ParseIPLiteralToNumber(server_hostname, &ip)) { | 461 !ParseIPLiteralToNumber(server_hostname, &ip)) { |
| 464 out->SetStringPiece(kSNI, server_hostname); | 462 out->SetStringPiece(kSNI, server_hostname); |
| 465 } | 463 } |
| 466 out->SetValue(kVERS, version); | 464 out->SetValue(kVERS, version); |
| 467 | 465 |
| 468 if (!cached->source_address_token().empty()) { | 466 if (!cached->source_address_token().empty()) { |
| 469 out->SetStringPiece(kSRCT, cached->source_address_token()); | 467 out->SetStringPiece(kSRCT, cached->source_address_token()); |
| 470 } | 468 } |
| 471 | 469 |
| 472 out->SetTaglist(kPDMD, kX509, 0); | 470 out->SetTaglist(kPDMD, kX509, 0); |
| 473 | |
| 474 if (common_cert_set_.get()) { | |
| 475 out->SetStringPiece(kCCS, common_cert_set_->GetCommonHashes()); | |
| 476 } | |
| 477 | |
| 478 const vector<string>& certs = cached->certs(); | |
| 479 if (!certs.empty()) { | |
| 480 vector<uint64> hashes; | |
| 481 hashes.reserve(certs.size()); | |
| 482 for (vector<string>::const_iterator i = certs.begin(); | |
| 483 i != certs.end(); ++i) { | |
| 484 hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size())); | |
| 485 } | |
| 486 out->SetVector(kCCRT, hashes); | |
| 487 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the | |
| 488 // client config is being used for multiple connections, another connection | |
| 489 // doesn't update the cached certificates and cause us to be unable to | |
| 490 // process the server's compressed certificate chain. | |
| 491 out_params->cached_certs = certs; | |
| 492 } | |
| 493 } | 471 } |
| 494 | 472 |
| 495 QuicErrorCode QuicCryptoClientConfig::FillClientHello( | 473 QuicErrorCode QuicCryptoClientConfig::FillClientHello( |
| 496 const string& server_hostname, | 474 const string& server_hostname, |
| 497 QuicGuid guid, | 475 QuicGuid guid, |
| 498 const CachedState* cached, | 476 const CachedState* cached, |
| 499 const QuicClock* clock, | 477 const QuicClock* clock, |
| 500 QuicRandom* rand, | 478 QuicRandom* rand, |
| 501 QuicCryptoNegotiatedParameters* out_params, | 479 QuicCryptoNegotiatedParameters* out_params, |
| 502 CryptoHandshakeMessage* out, | 480 CryptoHandshakeMessage* out, |
| 503 string* error_details) const { | 481 string* error_details) const { |
| 504 DCHECK(error_details != NULL); | 482 DCHECK(error_details != NULL); |
| 505 | 483 |
| 506 FillInchoateClientHello(server_hostname, cached, out_params, out); | 484 FillInchoateClientHello(server_hostname, cached, out); |
| 507 | 485 |
| 508 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); | 486 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); |
| 509 if (!scfg) { | 487 if (!scfg) { |
| 510 // This should never happen as our caller should have checked | 488 // This should never happen as our caller should have checked |
| 511 // cached->is_complete() before calling this function. | 489 // cached->is_complete() before calling this function. |
| 512 *error_details = "Handshake not ready"; | 490 *error_details = "Handshake not ready"; |
| 513 return QUIC_CRYPTO_INTERNAL_ERROR; | 491 return QUIC_CRYPTO_INTERNAL_ERROR; |
| 514 } | 492 } |
| 515 | 493 |
| 516 StringPiece scid; | 494 StringPiece scid; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 | 613 |
| 636 StringPiece nonce; | 614 StringPiece nonce; |
| 637 if (rej.GetStringPiece(kNONC, &nonce) && | 615 if (rej.GetStringPiece(kNONC, &nonce) && |
| 638 nonce.size() == kNonceSize) { | 616 nonce.size() == kNonceSize) { |
| 639 out_params->server_nonce = nonce.as_string(); | 617 out_params->server_nonce = nonce.as_string(); |
| 640 } | 618 } |
| 641 | 619 |
| 642 StringPiece proof, cert_bytes; | 620 StringPiece proof, cert_bytes; |
| 643 if (rej.GetStringPiece(kPROF, &proof) && | 621 if (rej.GetStringPiece(kPROF, &proof) && |
| 644 rej.GetStringPiece(kCERT, &cert_bytes)) { | 622 rej.GetStringPiece(kCERT, &cert_bytes)) { |
| 645 vector<string> certs; | 623 vector<StringPiece> certs; |
| 646 if (!CertCompressor::DecompressChain(cert_bytes, out_params->cached_certs, | 624 while (!cert_bytes.empty()) { |
| 647 common_cert_set_.get(), &certs)) { | 625 if (cert_bytes.size() < 3) { |
| 648 *error_details = "Certificate data invalid"; | 626 *error_details = "Certificate length truncated"; |
| 649 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 627 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 628 } |
| 629 size_t len = static_cast<size_t>(cert_bytes[0]) | |
| 630 static_cast<size_t>(cert_bytes[1]) << 8 | |
| 631 static_cast<size_t>(cert_bytes[2]) << 16; |
| 632 if (len == 0) { |
| 633 *error_details = "Zero length certificate"; |
| 634 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 635 } |
| 636 cert_bytes.remove_prefix(3); |
| 637 if (cert_bytes.size() < len) { |
| 638 *error_details = "Certificate truncated"; |
| 639 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 640 } |
| 641 certs.push_back(StringPiece(cert_bytes.data(), len)); |
| 642 cert_bytes.remove_prefix(len); |
| 650 } | 643 } |
| 651 | 644 |
| 652 cached->SetProof(certs, proof); | 645 cached->SetProof(certs, proof); |
| 653 } | 646 } |
| 654 | 647 |
| 655 return QUIC_NO_ERROR; | 648 return QUIC_NO_ERROR; |
| 656 } | 649 } |
| 657 | 650 |
| 658 QuicErrorCode QuicCryptoClientConfig::ProcessServerHello( | 651 QuicErrorCode QuicCryptoClientConfig::ProcessServerHello( |
| 659 const CryptoHandshakeMessage& server_hello, | 652 const CryptoHandshakeMessage& server_hello, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 676 | 669 |
| 677 const ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { | 670 const ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { |
| 678 return proof_verifier_.get(); | 671 return proof_verifier_.get(); |
| 679 } | 672 } |
| 680 | 673 |
| 681 void QuicCryptoClientConfig::SetProofVerifier(ProofVerifier* verifier) { | 674 void QuicCryptoClientConfig::SetProofVerifier(ProofVerifier* verifier) { |
| 682 proof_verifier_.reset(verifier); | 675 proof_verifier_.reset(verifier); |
| 683 } | 676 } |
| 684 | 677 |
| 685 } // namespace net | 678 } // namespace net |
| OLD | NEW |