crypto_handshake.cc revision d3868032626d59662ff73b372b5d584c1d144c53
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 3// found in the LICENSE file. 4 5#include "net/quic/crypto/crypto_handshake.h" 6 7#include <ctype.h> 8 9#include "base/memory/scoped_ptr.h" 10#include "base/stl_util.h" 11#include "base/strings/stringprintf.h" 12#include "base/strings/string_number_conversions.h" 13#include "base/strings/string_split.h" 14#include "crypto/secure_hash.h" 15#include "net/base/net_util.h" 16#include "net/quic/crypto/cert_compressor.h" 17#include "net/quic/crypto/channel_id.h" 18#include "net/quic/crypto/common_cert_set.h" 19#include "net/quic/crypto/crypto_framer.h" 20#include "net/quic/crypto/crypto_utils.h" 21#include "net/quic/crypto/curve25519_key_exchange.h" 22#include "net/quic/crypto/key_exchange.h" 23#include "net/quic/crypto/p256_key_exchange.h" 24#include "net/quic/crypto/proof_verifier.h" 25#include "net/quic/crypto/quic_decrypter.h" 26#include "net/quic/crypto/quic_encrypter.h" 27#include "net/quic/crypto/quic_random.h" 28#include "net/quic/quic_protocol.h" 29#include "net/quic/quic_utils.h" 30 31using base::StringPiece; 32using base::StringPrintf; 33using std::map; 34using std::string; 35using std::vector; 36 37namespace net { 38 39CryptoHandshakeMessage::CryptoHandshakeMessage() 40 : tag_(0), 41 minimum_size_(0) {} 42 43CryptoHandshakeMessage::CryptoHandshakeMessage( 44 const CryptoHandshakeMessage& other) 45 : tag_(other.tag_), 46 tag_value_map_(other.tag_value_map_), 47 minimum_size_(other.minimum_size_) { 48 // Don't copy serialized_. scoped_ptr doesn't have a copy constructor. 49 // The new object can lazily reconstruct serialized_. 50} 51 52CryptoHandshakeMessage::~CryptoHandshakeMessage() {} 53 54CryptoHandshakeMessage& CryptoHandshakeMessage::operator=( 55 const CryptoHandshakeMessage& other) { 56 tag_ = other.tag_; 57 tag_value_map_ = other.tag_value_map_; 58 // Don't copy serialized_. scoped_ptr doesn't have an assignment operator. 59 // However, invalidate serialized_. 60 serialized_.reset(); 61 minimum_size_ = other.minimum_size_; 62 return *this; 63} 64 65void CryptoHandshakeMessage::Clear() { 66 tag_ = 0; 67 tag_value_map_.clear(); 68 minimum_size_ = 0; 69 serialized_.reset(); 70} 71 72const QuicData& CryptoHandshakeMessage::GetSerialized() const { 73 if (!serialized_.get()) { 74 serialized_.reset(CryptoFramer::ConstructHandshakeMessage(*this)); 75 } 76 return *serialized_.get(); 77} 78 79void CryptoHandshakeMessage::MarkDirty() { 80 serialized_.reset(); 81} 82 83void CryptoHandshakeMessage::Insert(QuicTagValueMap::const_iterator begin, 84 QuicTagValueMap::const_iterator end) { 85 tag_value_map_.insert(begin, end); 86} 87 88void CryptoHandshakeMessage::SetTaglist(QuicTag tag, ...) { 89 // Warning, if sizeof(QuicTag) > sizeof(int) then this function will break 90 // because the terminating 0 will only be promoted to int. 91 COMPILE_ASSERT(sizeof(QuicTag) <= sizeof(int), 92 crypto_tag_may_not_be_larger_than_int_or_varargs_will_break); 93 94 vector<QuicTag> tags; 95 va_list ap; 96 97 va_start(ap, tag); 98 for (;;) { 99 QuicTag list_item = va_arg(ap, QuicTag); 100 if (list_item == 0) { 101 break; 102 } 103 tags.push_back(list_item); 104 } 105 106 // Because of the way that we keep tags in memory, we can copy the contents 107 // of the vector and get the correct bytes in wire format. See 108 // crypto_protocol.h. This assumes that the system is little-endian. 109 SetVector(tag, tags); 110 111 va_end(ap); 112} 113 114void CryptoHandshakeMessage::SetStringPiece(QuicTag tag, StringPiece value) { 115 tag_value_map_[tag] = value.as_string(); 116} 117 118void CryptoHandshakeMessage::Erase(QuicTag tag) { 119 tag_value_map_.erase(tag); 120} 121 122QuicErrorCode CryptoHandshakeMessage::GetTaglist(QuicTag tag, 123 const QuicTag** out_tags, 124 size_t* out_len) const { 125 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag); 126 QuicErrorCode ret = QUIC_NO_ERROR; 127 128 if (it == tag_value_map_.end()) { 129 ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; 130 } else if (it->second.size() % sizeof(QuicTag) != 0) { 131 ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 132 } 133 134 if (ret != QUIC_NO_ERROR) { 135 *out_tags = NULL; 136 *out_len = 0; 137 return ret; 138 } 139 140 *out_tags = reinterpret_cast<const QuicTag*>(it->second.data()); 141 *out_len = it->second.size() / sizeof(QuicTag); 142 return ret; 143} 144 145bool CryptoHandshakeMessage::GetStringPiece(QuicTag tag, 146 StringPiece* out) const { 147 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag); 148 if (it == tag_value_map_.end()) { 149 return false; 150 } 151 *out = it->second; 152 return true; 153} 154 155QuicErrorCode CryptoHandshakeMessage::GetNthValue24(QuicTag tag, 156 unsigned index, 157 StringPiece* out) const { 158 StringPiece value; 159 if (!GetStringPiece(tag, &value)) { 160 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; 161 } 162 163 for (unsigned i = 0;; i++) { 164 if (value.empty()) { 165 return QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND; 166 } 167 if (value.size() < 3) { 168 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 169 } 170 171 const unsigned char* data = 172 reinterpret_cast<const unsigned char*>(value.data()); 173 size_t size = static_cast<size_t>(data[0]) | 174 (static_cast<size_t>(data[1]) << 8) | 175 (static_cast<size_t>(data[2]) << 16); 176 value.remove_prefix(3); 177 178 if (value.size() < size) { 179 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 180 } 181 182 if (i == index) { 183 *out = StringPiece(value.data(), size); 184 return QUIC_NO_ERROR; 185 } 186 187 value.remove_prefix(size); 188 } 189} 190 191QuicErrorCode CryptoHandshakeMessage::GetUint16(QuicTag tag, 192 uint16* out) const { 193 return GetPOD(tag, out, sizeof(uint16)); 194} 195 196QuicErrorCode CryptoHandshakeMessage::GetUint32(QuicTag tag, 197 uint32* out) const { 198 return GetPOD(tag, out, sizeof(uint32)); 199} 200 201QuicErrorCode CryptoHandshakeMessage::GetUint64(QuicTag tag, 202 uint64* out) const { 203 return GetPOD(tag, out, sizeof(uint64)); 204} 205 206size_t CryptoHandshakeMessage::size() const { 207 size_t ret = sizeof(QuicTag) + 208 sizeof(uint16) /* number of entries */ + 209 sizeof(uint16) /* padding */; 210 ret += (sizeof(QuicTag) + sizeof(uint32) /* end offset */) * 211 tag_value_map_.size(); 212 for (QuicTagValueMap::const_iterator i = tag_value_map_.begin(); 213 i != tag_value_map_.end(); ++i) { 214 ret += i->second.size(); 215 } 216 217 return ret; 218} 219 220void CryptoHandshakeMessage::set_minimum_size(size_t min_bytes) { 221 if (min_bytes == minimum_size_) { 222 return; 223 } 224 serialized_.reset(); 225 minimum_size_ = min_bytes; 226} 227 228size_t CryptoHandshakeMessage::minimum_size() const { 229 return minimum_size_; 230} 231 232string CryptoHandshakeMessage::DebugString() const { 233 return DebugStringInternal(0); 234} 235 236QuicErrorCode CryptoHandshakeMessage::GetPOD( 237 QuicTag tag, void* out, size_t len) const { 238 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag); 239 QuicErrorCode ret = QUIC_NO_ERROR; 240 241 if (it == tag_value_map_.end()) { 242 ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; 243 } else if (it->second.size() != len) { 244 ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 245 } 246 247 if (ret != QUIC_NO_ERROR) { 248 memset(out, 0, len); 249 return ret; 250 } 251 252 memcpy(out, it->second.data(), len); 253 return ret; 254} 255 256string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const { 257 string ret = string(2 * indent, ' ') + QuicUtils::TagToString(tag_) + "<\n"; 258 ++indent; 259 for (QuicTagValueMap::const_iterator it = tag_value_map_.begin(); 260 it != tag_value_map_.end(); ++it) { 261 ret += string(2 * indent, ' ') + QuicUtils::TagToString(it->first) + ": "; 262 263 bool done = false; 264 switch (it->first) { 265 case kKATO: 266 case kVERS: 267 // uint32 value 268 if (it->second.size() == 4) { 269 uint32 value; 270 memcpy(&value, it->second.data(), sizeof(value)); 271 ret += base::UintToString(value); 272 done = true; 273 } 274 break; 275 case kKEXS: 276 case kAEAD: 277 case kCGST: 278 case kPDMD: 279 // tag lists 280 if (it->second.size() % sizeof(QuicTag) == 0) { 281 for (size_t j = 0; j < it->second.size(); j += sizeof(QuicTag)) { 282 QuicTag tag; 283 memcpy(&tag, it->second.data() + j, sizeof(tag)); 284 if (j > 0) { 285 ret += ","; 286 } 287 ret += QuicUtils::TagToString(tag); 288 } 289 done = true; 290 } 291 break; 292 case kSCFG: 293 // nested messages. 294 if (!it->second.empty()) { 295 scoped_ptr<CryptoHandshakeMessage> msg( 296 CryptoFramer::ParseMessage(it->second)); 297 if (msg.get()) { 298 ret += "\n"; 299 ret += msg->DebugStringInternal(indent + 1); 300 301 done = true; 302 } 303 } 304 break; 305 case kPAD: 306 ret += StringPrintf("(%d bytes of padding)", 307 static_cast<int>(it->second.size())); 308 done = true; 309 break; 310 } 311 312 if (!done) { 313 // If there's no specific format for this tag, or the value is invalid, 314 // then just use hex. 315 ret += base::HexEncode(it->second.data(), it->second.size()); 316 } 317 ret += "\n"; 318 } 319 --indent; 320 ret += string(2 * indent, ' ') + ">"; 321 return ret; 322} 323 324QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters() 325 : version(0), 326 key_exchange(0), 327 aead(0) { 328} 329 330QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() {} 331 332CrypterPair::CrypterPair() {} 333 334CrypterPair::~CrypterPair() {} 335 336// static 337const char QuicCryptoConfig::kInitialLabel[] = "QUIC key expansion"; 338 339// static 340const char QuicCryptoConfig::kCETVLabel[] = "QUIC CETV block"; 341 342// static 343const char QuicCryptoConfig::kForwardSecureLabel[] = 344 "QUIC forward secure key expansion"; 345 346QuicCryptoConfig::QuicCryptoConfig() 347 : version(0), 348 common_cert_sets(CommonCertSets::GetInstanceQUIC()) { 349} 350 351QuicCryptoConfig::~QuicCryptoConfig() {} 352 353QuicCryptoClientConfig::QuicCryptoClientConfig() {} 354 355QuicCryptoClientConfig::~QuicCryptoClientConfig() { 356 STLDeleteValues(&cached_states_); 357} 358 359QuicCryptoClientConfig::CachedState::CachedState() 360 : server_config_valid_(false), 361 generation_counter_(0) {} 362 363QuicCryptoClientConfig::CachedState::~CachedState() {} 364 365bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const { 366 if (server_config_.empty() || !server_config_valid_) { 367 return false; 368 } 369 370 const CryptoHandshakeMessage* scfg = GetServerConfig(); 371 if (!scfg) { 372 // Should be impossible short of cache corruption. 373 DCHECK(false); 374 return false; 375 } 376 377 uint64 expiry_seconds; 378 if (scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR || 379 now.ToUNIXSeconds() >= expiry_seconds) { 380 return false; 381 } 382 383 return true; 384} 385 386const CryptoHandshakeMessage* 387QuicCryptoClientConfig::CachedState::GetServerConfig() const { 388 if (server_config_.empty()) { 389 return NULL; 390 } 391 392 if (!scfg_.get()) { 393 scfg_.reset(CryptoFramer::ParseMessage(server_config_)); 394 DCHECK(scfg_.get()); 395 } 396 return scfg_.get(); 397} 398 399QuicErrorCode QuicCryptoClientConfig::CachedState::SetServerConfig( 400 StringPiece server_config, QuicWallTime now, string* error_details) { 401 const bool matches_existing = server_config == server_config_; 402 403 // Even if the new server config matches the existing one, we still wish to 404 // reject it if it has expired. 405 scoped_ptr<CryptoHandshakeMessage> new_scfg_storage; 406 const CryptoHandshakeMessage* new_scfg; 407 408 if (!matches_existing) { 409 new_scfg_storage.reset(CryptoFramer::ParseMessage(server_config)); 410 new_scfg = new_scfg_storage.get(); 411 } else { 412 new_scfg = GetServerConfig(); 413 } 414 415 if (!new_scfg) { 416 *error_details = "SCFG invalid"; 417 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 418 } 419 420 uint64 expiry_seconds; 421 if (new_scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) { 422 *error_details = "SCFG missing EXPY"; 423 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 424 } 425 426 if (now.ToUNIXSeconds() >= expiry_seconds) { 427 *error_details = "SCFG has expired"; 428 return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED; 429 } 430 431 if (!matches_existing) { 432 server_config_ = server_config.as_string(); 433 SetProofInvalid(); 434 scfg_.reset(new_scfg_storage.release()); 435 } 436 return QUIC_NO_ERROR; 437} 438 439void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { 440 server_config_.clear(); 441 scfg_.reset(); 442 SetProofInvalid(); 443} 444 445void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs, 446 StringPiece signature) { 447 bool has_changed = 448 signature != server_config_sig_ || certs_.size() != certs.size(); 449 450 if (!has_changed) { 451 for (size_t i = 0; i < certs_.size(); i++) { 452 if (certs_[i] != certs[i]) { 453 has_changed = true; 454 break; 455 } 456 } 457 } 458 459 if (!has_changed) { 460 return; 461 } 462 463 // If the proof has changed then it needs to be revalidated. 464 SetProofInvalid(); 465 certs_ = certs; 466 server_config_sig_ = signature.as_string(); 467} 468 469void QuicCryptoClientConfig::CachedState::SetProofValid() { 470 server_config_valid_ = true; 471} 472 473void QuicCryptoClientConfig::CachedState::SetProofInvalid() { 474 server_config_valid_ = false; 475 ++generation_counter_; 476} 477 478const string& QuicCryptoClientConfig::CachedState::server_config() const { 479 return server_config_; 480} 481 482const string& 483QuicCryptoClientConfig::CachedState::source_address_token() const { 484 return source_address_token_; 485} 486 487const vector<string>& QuicCryptoClientConfig::CachedState::certs() const { 488 return certs_; 489} 490 491const string& QuicCryptoClientConfig::CachedState::signature() const { 492 return server_config_sig_; 493} 494 495bool QuicCryptoClientConfig::CachedState::proof_valid() const { 496 return server_config_valid_; 497} 498 499uint64 QuicCryptoClientConfig::CachedState::generation_counter() const { 500 return generation_counter_; 501} 502 503const ProofVerifyDetails* 504QuicCryptoClientConfig::CachedState::proof_verify_details() const { 505 return proof_verify_details_.get(); 506} 507 508void QuicCryptoClientConfig::CachedState::set_source_address_token( 509 StringPiece token) { 510 source_address_token_ = token.as_string(); 511} 512 513void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails( 514 ProofVerifyDetails* details) { 515 proof_verify_details_.reset(details); 516} 517 518void QuicCryptoClientConfig::SetDefaults() { 519 // Version must be 0. 520 // TODO(agl): this version stuff is obsolete now. 521 version = QuicCryptoConfig::CONFIG_VERSION; 522 523 // Key exchange methods. 524 kexs.resize(2); 525 kexs[0] = kC255; 526 kexs[1] = kP256; 527 528 // Authenticated encryption algorithms. 529 aead.resize(1); 530 aead[0] = kAESG; 531} 532 533QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate( 534 const string& server_hostname) { 535 map<string, CachedState*>::const_iterator it = 536 cached_states_.find(server_hostname); 537 if (it != cached_states_.end()) { 538 return it->second; 539 } 540 541 CachedState* cached = new CachedState; 542 cached_states_.insert(make_pair(server_hostname, cached)); 543 return cached; 544} 545 546void QuicCryptoClientConfig::FillInchoateClientHello( 547 const string& server_hostname, 548 const CachedState* cached, 549 QuicCryptoNegotiatedParameters* out_params, 550 CryptoHandshakeMessage* out) const { 551 out->set_tag(kCHLO); 552 out->set_minimum_size(kClientHelloMinimumSize); 553 554 // Server name indication. We only send SNI if it's a valid domain name, as 555 // per the spec. 556 if (CryptoUtils::IsValidSNI(server_hostname)) { 557 out->SetStringPiece(kSNI, server_hostname); 558 } 559 out->SetValue(kVERS, version); 560 561 if (!cached->source_address_token().empty()) { 562 out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token()); 563 } 564 565 if (proof_verifier_.get()) { 566 // TODO(rtenneti): Enable ECDSA proof verification on Windows. Disabled it 567 // because X509Certificate::GetPublicKeyInfo is not returning the correct 568 // type for ECDSA certificates. 569#if defined(OS_WIN) 570 out->SetTaglist(kPDMD, kX59R, 0); 571#else 572 out->SetTaglist(kPDMD, kX509, 0); 573#endif 574 } 575 576 if (proof_verifier_.get() && !cached->proof_valid()) { 577 // If we are expecting a certificate chain, double the size of the client 578 // hello so that the response from the server can be larger - hopefully 579 // including the whole certificate chain. 580 out->set_minimum_size(kClientHelloMinimumSize * 2); 581 } 582 583 if (common_cert_sets) { 584 out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes()); 585 } 586 587 const vector<string>& certs = cached->certs(); 588 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the 589 // client config is being used for multiple connections, another connection 590 // doesn't update the cached certificates and cause us to be unable to 591 // process the server's compressed certificate chain. 592 out_params->cached_certs = certs; 593 if (!certs.empty()) { 594 vector<uint64> hashes; 595 hashes.reserve(certs.size()); 596 for (vector<string>::const_iterator i = certs.begin(); 597 i != certs.end(); ++i) { 598 hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size())); 599 } 600 out->SetVector(kCCRT, hashes); 601 } 602} 603 604QuicErrorCode QuicCryptoClientConfig::FillClientHello( 605 const string& server_hostname, 606 QuicGuid guid, 607 const CachedState* cached, 608 QuicWallTime now, 609 QuicRandom* rand, 610 QuicCryptoNegotiatedParameters* out_params, 611 CryptoHandshakeMessage* out, 612 string* error_details) const { 613 DCHECK(error_details != NULL); 614 615 FillInchoateClientHello(server_hostname, cached, out_params, out); 616 617 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); 618 if (!scfg) { 619 // This should never happen as our caller should have checked 620 // cached->IsComplete() before calling this function. 621 *error_details = "Handshake not ready"; 622 return QUIC_CRYPTO_INTERNAL_ERROR; 623 } 624 625 StringPiece scid; 626 if (!scfg->GetStringPiece(kSCID, &scid)) { 627 *error_details = "SCFG missing SCID"; 628 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 629 } 630 out->SetStringPiece(kSCID, scid); 631 632 const QuicTag* their_aeads; 633 const QuicTag* their_key_exchanges; 634 size_t num_their_aeads, num_their_key_exchanges; 635 if (scfg->GetTaglist(kAEAD, &their_aeads, 636 &num_their_aeads) != QUIC_NO_ERROR || 637 scfg->GetTaglist(kKEXS, &their_key_exchanges, 638 &num_their_key_exchanges) != QUIC_NO_ERROR) { 639 *error_details = "Missing AEAD or KEXS"; 640 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 641 } 642 643 size_t key_exchange_index; 644 if (!QuicUtils::FindMutualTag( 645 aead, their_aeads, num_their_aeads, QuicUtils::PEER_PRIORITY, 646 &out_params->aead, NULL) || 647 !QuicUtils::FindMutualTag( 648 kexs, their_key_exchanges, num_their_key_exchanges, 649 QuicUtils::PEER_PRIORITY, &out_params->key_exchange, 650 &key_exchange_index)) { 651 *error_details = "Unsupported AEAD or KEXS"; 652 return QUIC_CRYPTO_NO_SUPPORT; 653 } 654 out->SetTaglist(kAEAD, out_params->aead, 0); 655 out->SetTaglist(kKEXS, out_params->key_exchange, 0); 656 657 StringPiece public_value; 658 if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) != 659 QUIC_NO_ERROR) { 660 *error_details = "Missing public value"; 661 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 662 } 663 664 StringPiece orbit; 665 if (!scfg->GetStringPiece(kORBT, &orbit) || orbit.size() != kOrbitSize) { 666 *error_details = "SCFG missing OBIT"; 667 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; 668 } 669 670 CryptoUtils::GenerateNonce(now, rand, orbit, &out_params->client_nonce); 671 out->SetStringPiece(kNONC, out_params->client_nonce); 672 if (!out_params->server_nonce.empty()) { 673 out->SetStringPiece(kServerNonceTag, out_params->server_nonce); 674 } 675 676 switch (out_params->key_exchange) { 677 case kC255: 678 out_params->client_key_exchange.reset(Curve25519KeyExchange::New( 679 Curve25519KeyExchange::NewPrivateKey(rand))); 680 break; 681 case kP256: 682 out_params->client_key_exchange.reset(P256KeyExchange::New( 683 P256KeyExchange::NewPrivateKey())); 684 break; 685 default: 686 DCHECK(false); 687 *error_details = "Configured to support an unknown key exchange"; 688 return QUIC_CRYPTO_INTERNAL_ERROR; 689 } 690 691 if (!out_params->client_key_exchange->CalculateSharedKey( 692 public_value, &out_params->initial_premaster_secret)) { 693 *error_details = "Key exchange failure"; 694 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 695 } 696 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value()); 697 698 bool do_channel_id = false; 699 if (channel_id_signer_.get()) { 700 const QuicTag* their_proof_demands; 701 size_t num_their_proof_demands; 702 if (scfg->GetTaglist(kPDMD, &their_proof_demands, 703 &num_their_proof_demands) == QUIC_NO_ERROR) { 704 for (size_t i = 0; i < num_their_proof_demands; i++) { 705 if (their_proof_demands[i] == kCHID) { 706 do_channel_id = true; 707 break; 708 } 709 } 710 } 711 } 712 713 if (do_channel_id) { 714 // In order to calculate the encryption key for the CETV block we need to 715 // serialise the client hello as it currently is (i.e. without the CETV 716 // block). For this, the client hello is serialized without padding. 717 const size_t orig_min_size = out->minimum_size(); 718 out->set_minimum_size(0); 719 720 CryptoHandshakeMessage cetv; 721 cetv.set_tag(kCETV); 722 723 string hkdf_input; 724 const QuicData& client_hello_serialized = out->GetSerialized(); 725 hkdf_input.append(QuicCryptoConfig::kCETVLabel, 726 strlen(QuicCryptoConfig::kCETVLabel) + 1); 727 hkdf_input.append(reinterpret_cast<char*>(&guid), sizeof(guid)); 728 hkdf_input.append(client_hello_serialized.data(), 729 client_hello_serialized.length()); 730 hkdf_input.append(cached->server_config()); 731 732 string key, signature; 733 if (!channel_id_signer_->Sign(server_hostname, hkdf_input, 734 &key, &signature)) { 735 *error_details = "Channel ID signature failed"; 736 return QUIC_INTERNAL_ERROR; 737 } 738 739 cetv.SetStringPiece(kCIDK, key); 740 cetv.SetStringPiece(kCIDS, signature); 741 742 CrypterPair crypters; 743 CryptoUtils::DeriveKeys(out_params->initial_premaster_secret, 744 out_params->aead, out_params->client_nonce, 745 out_params->server_nonce, hkdf_input, 746 CryptoUtils::CLIENT, &crypters); 747 748 const QuicData& cetv_plaintext = cetv.GetSerialized(); 749 scoped_ptr<QuicData> cetv_ciphertext(crypters.encrypter->EncryptPacket( 750 0 /* sequence number */, 751 StringPiece() /* associated data */, 752 cetv_plaintext.AsStringPiece())); 753 754 out->SetStringPiece(kCETV, cetv_ciphertext->AsStringPiece()); 755 out->MarkDirty(); 756 757 out->set_minimum_size(orig_min_size); 758 } 759 760 out_params->hkdf_input_suffix.clear(); 761 out_params->hkdf_input_suffix.append(reinterpret_cast<char*>(&guid), 762 sizeof(guid)); 763 const QuicData& client_hello_serialized = out->GetSerialized(); 764 out_params->hkdf_input_suffix.append(client_hello_serialized.data(), 765 client_hello_serialized.length()); 766 out_params->hkdf_input_suffix.append(cached->server_config()); 767 768 string hkdf_input; 769 const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; 770 hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size()); 771 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); 772 hkdf_input.append(out_params->hkdf_input_suffix); 773 774 CryptoUtils::DeriveKeys(out_params->initial_premaster_secret, 775 out_params->aead, out_params->client_nonce, 776 out_params->server_nonce, hkdf_input, 777 CryptoUtils::CLIENT, &out_params->initial_crypters); 778 779 return QUIC_NO_ERROR; 780} 781 782QuicErrorCode QuicCryptoClientConfig::ProcessRejection( 783 CachedState* cached, 784 const CryptoHandshakeMessage& rej, 785 QuicWallTime now, 786 QuicCryptoNegotiatedParameters* out_params, 787 string* error_details) { 788 DCHECK(error_details != NULL); 789 790 if (rej.tag() != kREJ) { 791 *error_details = "Message is not REJ"; 792 return QUIC_CRYPTO_INTERNAL_ERROR; 793 } 794 795 StringPiece scfg; 796 if (!rej.GetStringPiece(kSCFG, &scfg)) { 797 *error_details = "Missing SCFG"; 798 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; 799 } 800 801 QuicErrorCode error = cached->SetServerConfig(scfg, now, error_details); 802 if (error != QUIC_NO_ERROR) { 803 return error; 804 } 805 806 StringPiece token; 807 if (rej.GetStringPiece(kSourceAddressTokenTag, &token)) { 808 cached->set_source_address_token(token); 809 } 810 811 StringPiece nonce; 812 if (rej.GetStringPiece(kServerNonceTag, &nonce)) { 813 out_params->server_nonce = nonce.as_string(); 814 } 815 816 StringPiece proof, cert_bytes; 817 if (rej.GetStringPiece(kPROF, &proof) && 818 rej.GetStringPiece(kCertificateTag, &cert_bytes)) { 819 vector<string> certs; 820 if (!CertCompressor::DecompressChain(cert_bytes, out_params->cached_certs, 821 common_cert_sets, &certs)) { 822 *error_details = "Certificate data invalid"; 823 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 824 } 825 826 cached->SetProof(certs, proof); 827 } 828 829 return QUIC_NO_ERROR; 830} 831 832QuicErrorCode QuicCryptoClientConfig::ProcessServerHello( 833 const CryptoHandshakeMessage& server_hello, 834 QuicGuid guid, 835 QuicCryptoNegotiatedParameters* out_params, 836 string* error_details) { 837 DCHECK(error_details != NULL); 838 839 if (server_hello.tag() != kSHLO) { 840 *error_details = "Bad tag"; 841 return QUIC_INVALID_CRYPTO_MESSAGE_TYPE; 842 } 843 844 // TODO(agl): 845 // learn about updated SCFGs. 846 847 StringPiece public_value; 848 if (!server_hello.GetStringPiece(kPUBS, &public_value)) { 849 *error_details = "server hello missing forward secure public value"; 850 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 851 } 852 853 if (!out_params->client_key_exchange->CalculateSharedKey( 854 public_value, &out_params->forward_secure_premaster_secret)) { 855 *error_details = "Key exchange failure"; 856 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 857 } 858 859 string hkdf_input; 860 const size_t label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; 861 hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size()); 862 hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, label_len); 863 hkdf_input.append(out_params->hkdf_input_suffix); 864 865 CryptoUtils::DeriveKeys( 866 out_params->forward_secure_premaster_secret, out_params->aead, 867 out_params->client_nonce, out_params->server_nonce, hkdf_input, 868 CryptoUtils::CLIENT, &out_params->forward_secure_crypters); 869 870 return QUIC_NO_ERROR; 871} 872 873ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { 874 return proof_verifier_.get(); 875} 876 877void QuicCryptoClientConfig::SetProofVerifier(ProofVerifier* verifier) { 878 proof_verifier_.reset(verifier); 879} 880 881ChannelIDSigner* QuicCryptoClientConfig::channel_id_signer() const { 882 return channel_id_signer_.get(); 883} 884 885void QuicCryptoClientConfig::SetChannelIDSigner(ChannelIDSigner* signer) { 886 channel_id_signer_.reset(signer); 887} 888 889} // namespace net 890