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