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