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 3 // found in the LICENSE file. 4 5 #include "net/quic/crypto/quic_crypto_server_config.h" 6 7 #include <stdlib.h> 8 #include <algorithm> 9 10 #include "base/stl_util.h" 11 #include "base/strings/string_number_conversions.h" 12 #include "crypto/hkdf.h" 13 #include "crypto/secure_hash.h" 14 #include "net/base/net_util.h" 15 #include "net/quic/crypto/aes_128_gcm_12_decrypter.h" 16 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" 17 #include "net/quic/crypto/cert_compressor.h" 18 #include "net/quic/crypto/chacha20_poly1305_encrypter.h" 19 #include "net/quic/crypto/channel_id.h" 20 #include "net/quic/crypto/crypto_framer.h" 21 #include "net/quic/crypto/crypto_server_config_protobuf.h" 22 #include "net/quic/crypto/crypto_utils.h" 23 #include "net/quic/crypto/curve25519_key_exchange.h" 24 #include "net/quic/crypto/ephemeral_key_source.h" 25 #include "net/quic/crypto/key_exchange.h" 26 #include "net/quic/crypto/local_strike_register_client.h" 27 #include "net/quic/crypto/p256_key_exchange.h" 28 #include "net/quic/crypto/proof_source.h" 29 #include "net/quic/crypto/quic_decrypter.h" 30 #include "net/quic/crypto/quic_encrypter.h" 31 #include "net/quic/crypto/quic_random.h" 32 #include "net/quic/crypto/source_address_token.h" 33 #include "net/quic/crypto/strike_register.h" 34 #include "net/quic/crypto/strike_register_client.h" 35 #include "net/quic/quic_clock.h" 36 #include "net/quic/quic_flags.h" 37 #include "net/quic/quic_protocol.h" 38 #include "net/quic/quic_socket_address_coder.h" 39 #include "net/quic/quic_utils.h" 40 41 using base::StringPiece; 42 using crypto::SecureHash; 43 using std::map; 44 using std::sort; 45 using std::string; 46 using std::vector; 47 48 namespace net { 49 50 namespace { 51 52 string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) { 53 crypto::HKDF hkdf(source_address_token_secret, 54 StringPiece() /* no salt */, 55 "QUIC source address token key", 56 CryptoSecretBoxer::GetKeySize(), 57 0 /* no fixed IV needed */, 58 0 /* no subkey secret */); 59 return hkdf.server_write_key().as_string(); 60 } 61 62 } // namespace 63 64 // ClientHelloInfo contains information about a client hello message that is 65 // only kept for as long as it's being processed. 66 struct ClientHelloInfo { 67 ClientHelloInfo(const IPEndPoint& in_client_ip, QuicWallTime in_now) 68 : client_ip(in_client_ip), 69 now(in_now), 70 valid_source_address_token(false), 71 client_nonce_well_formed(false), 72 unique(false) {} 73 74 // Inputs to EvaluateClientHello. 75 const IPEndPoint client_ip; 76 const QuicWallTime now; 77 78 // Outputs from EvaluateClientHello. 79 bool valid_source_address_token; 80 bool client_nonce_well_formed; 81 bool unique; 82 StringPiece sni; 83 StringPiece client_nonce; 84 StringPiece server_nonce; 85 StringPiece user_agent_id; 86 87 // Errors from EvaluateClientHello. 88 vector<uint32> reject_reasons; 89 COMPILE_ASSERT(sizeof(QuicTag) == sizeof(uint32), header_out_of_sync); 90 }; 91 92 struct ValidateClientHelloResultCallback::Result { 93 Result(const CryptoHandshakeMessage& in_client_hello, 94 IPEndPoint in_client_ip, 95 QuicWallTime in_now) 96 : client_hello(in_client_hello), 97 info(in_client_ip, in_now), 98 error_code(QUIC_NO_ERROR) { 99 } 100 101 CryptoHandshakeMessage client_hello; 102 ClientHelloInfo info; 103 QuicErrorCode error_code; 104 string error_details; 105 }; 106 107 class ValidateClientHelloHelper { 108 public: 109 ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result, 110 ValidateClientHelloResultCallback* done_cb) 111 : result_(result), done_cb_(done_cb) { 112 } 113 114 ~ValidateClientHelloHelper() { 115 LOG_IF(DFATAL, done_cb_ != NULL) 116 << "Deleting ValidateClientHelloHelper with a pending callback."; 117 } 118 119 void ValidationComplete(QuicErrorCode error_code, const char* error_details) { 120 result_->error_code = error_code; 121 result_->error_details = error_details; 122 done_cb_->Run(result_); 123 DetachCallback(); 124 } 125 126 void StartedAsyncCallback() { 127 DetachCallback(); 128 } 129 130 private: 131 void DetachCallback() { 132 LOG_IF(DFATAL, done_cb_ == NULL) << "Callback already detached."; 133 done_cb_ = NULL; 134 } 135 136 ValidateClientHelloResultCallback::Result* result_; 137 ValidateClientHelloResultCallback* done_cb_; 138 139 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); 140 }; 141 142 class VerifyNonceIsValidAndUniqueCallback 143 : public StrikeRegisterClient::ResultCallback { 144 public: 145 VerifyNonceIsValidAndUniqueCallback( 146 ValidateClientHelloResultCallback::Result* result, 147 ValidateClientHelloResultCallback* done_cb) 148 : result_(result), done_cb_(done_cb) { 149 } 150 151 protected: 152 virtual void RunImpl(bool nonce_is_valid_and_unique, 153 InsertStatus nonce_error) OVERRIDE { 154 DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique 155 << " nonce_error: " << nonce_error; 156 result_->info.unique = nonce_is_valid_and_unique; 157 if (!nonce_is_valid_and_unique) { 158 HandshakeFailureReason client_nonce_error; 159 switch (nonce_error) { 160 case NONCE_INVALID_FAILURE: 161 client_nonce_error = CLIENT_NONCE_INVALID_FAILURE; 162 break; 163 case NONCE_NOT_UNIQUE_FAILURE: 164 client_nonce_error = CLIENT_NONCE_NOT_UNIQUE_FAILURE; 165 break; 166 case NONCE_INVALID_ORBIT_FAILURE: 167 client_nonce_error = CLIENT_NONCE_INVALID_ORBIT_FAILURE; 168 break; 169 case NONCE_INVALID_TIME_FAILURE: 170 client_nonce_error = CLIENT_NONCE_INVALID_TIME_FAILURE; 171 break; 172 case STRIKE_REGISTER_TIMEOUT: 173 client_nonce_error = CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT; 174 break; 175 case STRIKE_REGISTER_FAILURE: 176 client_nonce_error = CLIENT_NONCE_STRIKE_REGISTER_FAILURE; 177 break; 178 case NONCE_UNKNOWN_FAILURE: 179 client_nonce_error = CLIENT_NONCE_UNKNOWN_FAILURE; 180 break; 181 case NONCE_OK: 182 default: 183 LOG(DFATAL) << "Unexpected client nonce error: " << nonce_error; 184 client_nonce_error = CLIENT_NONCE_UNKNOWN_FAILURE; 185 break; 186 } 187 result_->info.reject_reasons.push_back(client_nonce_error); 188 } 189 done_cb_->Run(result_); 190 } 191 192 private: 193 ValidateClientHelloResultCallback::Result* result_; 194 ValidateClientHelloResultCallback* done_cb_; 195 196 DISALLOW_COPY_AND_ASSIGN(VerifyNonceIsValidAndUniqueCallback); 197 }; 198 199 // static 200 const char QuicCryptoServerConfig::TESTING[] = "secret string for testing"; 201 202 PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() { 203 } 204 205 PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() { 206 } 207 208 ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() { 209 } 210 211 ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() { 212 } 213 214 void ValidateClientHelloResultCallback::Run(const Result* result) { 215 RunImpl(result->client_hello, *result); 216 delete result; 217 delete this; 218 } 219 220 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() 221 : expiry_time(QuicWallTime::Zero()), 222 channel_id_enabled(false), 223 p256(false) {} 224 225 QuicCryptoServerConfig::QuicCryptoServerConfig( 226 StringPiece source_address_token_secret, 227 QuicRandom* rand) 228 : replay_protection_(true), 229 configs_lock_(), 230 primary_config_(NULL), 231 next_config_promotion_time_(QuicWallTime::Zero()), 232 server_nonce_strike_register_lock_(), 233 strike_register_no_startup_period_(false), 234 strike_register_max_entries_(1 << 10), 235 strike_register_window_secs_(600), 236 source_address_token_future_secs_(3600), 237 source_address_token_lifetime_secs_(86400), 238 server_nonce_strike_register_max_entries_(1 << 10), 239 server_nonce_strike_register_window_secs_(120) { 240 default_source_address_token_boxer_.SetKey( 241 DeriveSourceAddressTokenKey(source_address_token_secret)); 242 243 // Generate a random key and orbit for server nonces. 244 rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_)); 245 const size_t key_size = server_nonce_boxer_.GetKeySize(); 246 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]); 247 rand->RandBytes(key_bytes.get(), key_size); 248 249 server_nonce_boxer_.SetKey( 250 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size)); 251 } 252 253 QuicCryptoServerConfig::~QuicCryptoServerConfig() { 254 primary_config_ = NULL; 255 } 256 257 // static 258 QuicServerConfigProtobuf* QuicCryptoServerConfig::GenerateConfig( 259 QuicRandom* rand, 260 const QuicClock* clock, 261 const ConfigOptions& options) { 262 CryptoHandshakeMessage msg; 263 264 const string curve25519_private_key = 265 Curve25519KeyExchange::NewPrivateKey(rand); 266 scoped_ptr<Curve25519KeyExchange> curve25519( 267 Curve25519KeyExchange::New(curve25519_private_key)); 268 StringPiece curve25519_public_value = curve25519->public_value(); 269 270 string encoded_public_values; 271 // First three bytes encode the length of the public value. 272 encoded_public_values.push_back(curve25519_public_value.size()); 273 encoded_public_values.push_back(curve25519_public_value.size() >> 8); 274 encoded_public_values.push_back(curve25519_public_value.size() >> 16); 275 encoded_public_values.append(curve25519_public_value.data(), 276 curve25519_public_value.size()); 277 278 string p256_private_key; 279 if (options.p256) { 280 p256_private_key = P256KeyExchange::NewPrivateKey(); 281 scoped_ptr<P256KeyExchange> p256(P256KeyExchange::New(p256_private_key)); 282 StringPiece p256_public_value = p256->public_value(); 283 284 encoded_public_values.push_back(p256_public_value.size()); 285 encoded_public_values.push_back(p256_public_value.size() >> 8); 286 encoded_public_values.push_back(p256_public_value.size() >> 16); 287 encoded_public_values.append(p256_public_value.data(), 288 p256_public_value.size()); 289 } 290 291 msg.set_tag(kSCFG); 292 if (options.p256) { 293 msg.SetTaglist(kKEXS, kC255, kP256, 0); 294 } else { 295 msg.SetTaglist(kKEXS, kC255, 0); 296 } 297 if (ChaCha20Poly1305Encrypter::IsSupported()) { 298 msg.SetTaglist(kAEAD, kAESG, kCC12, 0); 299 } else { 300 msg.SetTaglist(kAEAD, kAESG, 0); 301 } 302 msg.SetStringPiece(kPUBS, encoded_public_values); 303 304 if (options.expiry_time.IsZero()) { 305 const QuicWallTime now = clock->WallNow(); 306 const QuicWallTime expiry = now.Add(QuicTime::Delta::FromSeconds( 307 60 * 60 * 24 * 180 /* 180 days, ~six months */)); 308 const uint64 expiry_seconds = expiry.ToUNIXSeconds(); 309 msg.SetValue(kEXPY, expiry_seconds); 310 } else { 311 msg.SetValue(kEXPY, options.expiry_time.ToUNIXSeconds()); 312 } 313 314 char orbit_bytes[kOrbitSize]; 315 if (options.orbit.size() == sizeof(orbit_bytes)) { 316 memcpy(orbit_bytes, options.orbit.data(), sizeof(orbit_bytes)); 317 } else { 318 DCHECK(options.orbit.empty()); 319 rand->RandBytes(orbit_bytes, sizeof(orbit_bytes)); 320 } 321 msg.SetStringPiece(kORBT, StringPiece(orbit_bytes, sizeof(orbit_bytes))); 322 323 if (options.channel_id_enabled) { 324 msg.SetTaglist(kPDMD, kCHID, 0); 325 } 326 327 if (options.id.empty()) { 328 // We need to ensure that the SCID changes whenever the server config does 329 // thus we make it a hash of the rest of the server config. 330 scoped_ptr<QuicData> serialized( 331 CryptoFramer::ConstructHandshakeMessage(msg)); 332 scoped_ptr<SecureHash> hash(SecureHash::Create(SecureHash::SHA256)); 333 hash->Update(serialized->data(), serialized->length()); 334 335 char scid_bytes[16]; 336 hash->Finish(scid_bytes, sizeof(scid_bytes)); 337 msg.SetStringPiece(kSCID, StringPiece(scid_bytes, sizeof(scid_bytes))); 338 } else { 339 msg.SetStringPiece(kSCID, options.id); 340 } 341 // Don't put new tags below this point. The SCID generation should hash over 342 // everything but itself and so extra tags should be added prior to the 343 // preceeding if block. 344 345 scoped_ptr<QuicData> serialized(CryptoFramer::ConstructHandshakeMessage(msg)); 346 347 scoped_ptr<QuicServerConfigProtobuf> config(new QuicServerConfigProtobuf); 348 config->set_config(serialized->AsStringPiece()); 349 QuicServerConfigProtobuf::PrivateKey* curve25519_key = config->add_key(); 350 curve25519_key->set_tag(kC255); 351 curve25519_key->set_private_key(curve25519_private_key); 352 353 if (options.p256) { 354 QuicServerConfigProtobuf::PrivateKey* p256_key = config->add_key(); 355 p256_key->set_tag(kP256); 356 p256_key->set_private_key(p256_private_key); 357 } 358 359 return config.release(); 360 } 361 362 CryptoHandshakeMessage* QuicCryptoServerConfig::AddConfig( 363 QuicServerConfigProtobuf* protobuf, 364 const QuicWallTime now) { 365 scoped_ptr<CryptoHandshakeMessage> msg( 366 CryptoFramer::ParseMessage(protobuf->config())); 367 368 if (!msg.get()) { 369 LOG(WARNING) << "Failed to parse server config message"; 370 return NULL; 371 } 372 373 scoped_refptr<Config> config(ParseConfigProtobuf(protobuf)); 374 if (!config.get()) { 375 LOG(WARNING) << "Failed to parse server config message"; 376 return NULL; 377 } 378 379 { 380 base::AutoLock locked(configs_lock_); 381 if (configs_.find(config->id) != configs_.end()) { 382 LOG(WARNING) << "Failed to add config because another with the same " 383 "server config id already exists: " 384 << base::HexEncode(config->id.data(), config->id.size()); 385 return NULL; 386 } 387 388 configs_[config->id] = config; 389 SelectNewPrimaryConfig(now); 390 DCHECK(primary_config_.get()); 391 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); 392 } 393 394 return msg.release(); 395 } 396 397 CryptoHandshakeMessage* QuicCryptoServerConfig::AddDefaultConfig( 398 QuicRandom* rand, 399 const QuicClock* clock, 400 const ConfigOptions& options) { 401 scoped_ptr<QuicServerConfigProtobuf> config( 402 GenerateConfig(rand, clock, options)); 403 return AddConfig(config.get(), clock->WallNow()); 404 } 405 406 bool QuicCryptoServerConfig::SetConfigs( 407 const vector<QuicServerConfigProtobuf*>& protobufs, 408 const QuicWallTime now) { 409 vector<scoped_refptr<Config> > parsed_configs; 410 bool ok = true; 411 412 for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin(); 413 i != protobufs.end(); ++i) { 414 scoped_refptr<Config> config(ParseConfigProtobuf(*i)); 415 if (!config.get()) { 416 ok = false; 417 break; 418 } 419 420 parsed_configs.push_back(config); 421 } 422 423 if (parsed_configs.empty()) { 424 LOG(WARNING) << "New config list is empty."; 425 ok = false; 426 } 427 428 if (!ok) { 429 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; 430 } else { 431 VLOG(1) << "Updating configs:"; 432 433 base::AutoLock locked(configs_lock_); 434 ConfigMap new_configs; 435 436 for (vector<scoped_refptr<Config> >::const_iterator i = 437 parsed_configs.begin(); 438 i != parsed_configs.end(); ++i) { 439 scoped_refptr<Config> config = *i; 440 441 ConfigMap::iterator it = configs_.find(config->id); 442 if (it != configs_.end()) { 443 VLOG(1) 444 << "Keeping scid: " << base::HexEncode( 445 config->id.data(), config->id.size()) 446 << " orbit: " << base::HexEncode( 447 reinterpret_cast<const char *>(config->orbit), kOrbitSize) 448 << " new primary_time " << config->primary_time.ToUNIXSeconds() 449 << " old primary_time " << it->second->primary_time.ToUNIXSeconds() 450 << " new priority " << config->priority 451 << " old priority " << it->second->priority; 452 // Update primary_time and priority. 453 it->second->primary_time = config->primary_time; 454 it->second->priority = config->priority; 455 new_configs.insert(*it); 456 } else { 457 VLOG(1) << "Adding scid: " << base::HexEncode( 458 config->id.data(), config->id.size()) 459 << " orbit: " << base::HexEncode( 460 reinterpret_cast<const char *>(config->orbit), kOrbitSize) 461 << " primary_time " << config->primary_time.ToUNIXSeconds() 462 << " priority " << config->priority; 463 new_configs.insert(make_pair(config->id, config)); 464 } 465 } 466 467 configs_.swap(new_configs); 468 SelectNewPrimaryConfig(now); 469 DCHECK(primary_config_.get()); 470 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); 471 } 472 473 return ok; 474 } 475 476 void QuicCryptoServerConfig::GetConfigIds(vector<string>* scids) const { 477 base::AutoLock locked(configs_lock_); 478 for (ConfigMap::const_iterator it = configs_.begin(); 479 it != configs_.end(); ++it) { 480 scids->push_back(it->first); 481 } 482 } 483 484 void QuicCryptoServerConfig::ValidateClientHello( 485 const CryptoHandshakeMessage& client_hello, 486 IPEndPoint client_ip, 487 const QuicClock* clock, 488 ValidateClientHelloResultCallback* done_cb) const { 489 const QuicWallTime now(clock->WallNow()); 490 491 ValidateClientHelloResultCallback::Result* result = 492 new ValidateClientHelloResultCallback::Result( 493 client_hello, client_ip, now); 494 495 StringPiece requested_scid; 496 client_hello.GetStringPiece(kSCID, &requested_scid); 497 498 uint8 primary_orbit[kOrbitSize]; 499 scoped_refptr<Config> requested_config; 500 { 501 base::AutoLock locked(configs_lock_); 502 503 if (!primary_config_.get()) { 504 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; 505 result->error_details = "No configurations loaded"; 506 } else { 507 if (!next_config_promotion_time_.IsZero() && 508 next_config_promotion_time_.IsAfter(now)) { 509 SelectNewPrimaryConfig(now); 510 DCHECK(primary_config_.get()); 511 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); 512 } 513 514 memcpy(primary_orbit, primary_config_->orbit, sizeof(primary_orbit)); 515 } 516 517 requested_config = GetConfigWithScid(requested_scid); 518 } 519 520 if (result->error_code == QUIC_NO_ERROR) { 521 EvaluateClientHello(primary_orbit, requested_config, result, done_cb); 522 } else { 523 done_cb->Run(result); 524 } 525 } 526 527 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( 528 const ValidateClientHelloResultCallback::Result& validate_chlo_result, 529 QuicConnectionId connection_id, 530 IPEndPoint client_address, 531 QuicVersion version, 532 const QuicVersionVector& supported_versions, 533 const QuicClock* clock, 534 QuicRandom* rand, 535 QuicCryptoNegotiatedParameters *params, 536 CryptoHandshakeMessage* out, 537 string* error_details) const { 538 DCHECK(error_details); 539 540 const CryptoHandshakeMessage& client_hello = 541 validate_chlo_result.client_hello; 542 const ClientHelloInfo& info = validate_chlo_result.info; 543 544 // If the client's preferred version is not the version we are currently 545 // speaking, then the client went through a version negotiation. In this 546 // case, we need to make sure that we actually do not support this version 547 // and that it wasn't a downgrade attack. 548 QuicTag client_version_tag; 549 if (client_hello.GetUint32(kVER, &client_version_tag) != QUIC_NO_ERROR) { 550 *error_details = "client hello missing version list"; 551 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 552 } 553 QuicVersion client_version = QuicTagToQuicVersion(client_version_tag); 554 if (client_version != version) { 555 // Just because client_version is a valid version enum doesn't mean that 556 // this server actually supports that version, so we check to see if 557 // it's actually in the supported versions list. 558 for (size_t i = 0; i < supported_versions.size(); ++i) { 559 if (client_version == supported_versions[i]) { 560 *error_details = "Downgrade attack detected"; 561 return QUIC_VERSION_NEGOTIATION_MISMATCH; 562 } 563 } 564 } 565 566 StringPiece requested_scid; 567 client_hello.GetStringPiece(kSCID, &requested_scid); 568 const QuicWallTime now(clock->WallNow()); 569 570 scoped_refptr<Config> requested_config; 571 scoped_refptr<Config> primary_config; 572 { 573 base::AutoLock locked(configs_lock_); 574 575 if (!primary_config_.get()) { 576 *error_details = "No configurations loaded"; 577 return QUIC_CRYPTO_INTERNAL_ERROR; 578 } 579 580 if (!next_config_promotion_time_.IsZero() && 581 next_config_promotion_time_.IsAfter(now)) { 582 SelectNewPrimaryConfig(now); 583 DCHECK(primary_config_.get()); 584 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); 585 } 586 587 // We'll use the config that the client requested in order to do 588 // key-agreement. Otherwise we'll give it a copy of |primary_config_| 589 // to use. 590 primary_config = primary_config_; 591 592 requested_config = GetConfigWithScid(requested_scid); 593 } 594 595 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { 596 *error_details = validate_chlo_result.error_details; 597 return validate_chlo_result.error_code; 598 } 599 600 out->Clear(); 601 602 if (!info.valid_source_address_token || 603 !info.client_nonce_well_formed || 604 !info.unique || 605 !requested_config.get()) { 606 BuildRejection( 607 *primary_config.get(), client_hello, info, rand, params, out); 608 return QUIC_NO_ERROR; 609 } 610 611 const QuicTag* their_aeads; 612 const QuicTag* their_key_exchanges; 613 size_t num_their_aeads, num_their_key_exchanges; 614 if (client_hello.GetTaglist(kAEAD, &their_aeads, 615 &num_their_aeads) != QUIC_NO_ERROR || 616 client_hello.GetTaglist(kKEXS, &their_key_exchanges, 617 &num_their_key_exchanges) != QUIC_NO_ERROR || 618 num_their_aeads != 1 || 619 num_their_key_exchanges != 1) { 620 *error_details = "Missing or invalid AEAD or KEXS"; 621 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 622 } 623 624 size_t key_exchange_index; 625 if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads, 626 num_their_aeads, QuicUtils::LOCAL_PRIORITY, 627 ¶ms->aead, NULL) || 628 !QuicUtils::FindMutualTag( 629 requested_config->kexs, their_key_exchanges, num_their_key_exchanges, 630 QuicUtils::LOCAL_PRIORITY, ¶ms->key_exchange, 631 &key_exchange_index)) { 632 *error_details = "Unsupported AEAD or KEXS"; 633 return QUIC_CRYPTO_NO_SUPPORT; 634 } 635 636 StringPiece public_value; 637 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { 638 *error_details = "Missing public value"; 639 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 640 } 641 642 const KeyExchange* key_exchange = 643 requested_config->key_exchanges[key_exchange_index]; 644 if (!key_exchange->CalculateSharedKey(public_value, 645 ¶ms->initial_premaster_secret)) { 646 *error_details = "Invalid public value"; 647 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 648 } 649 650 if (!info.sni.empty()) { 651 scoped_ptr<char[]> sni_tmp(new char[info.sni.length() + 1]); 652 memcpy(sni_tmp.get(), info.sni.data(), info.sni.length()); 653 sni_tmp[info.sni.length()] = 0; 654 params->sni = CryptoUtils::NormalizeHostname(sni_tmp.get()); 655 } 656 657 string hkdf_suffix; 658 const QuicData& client_hello_serialized = client_hello.GetSerialized(); 659 hkdf_suffix.reserve(sizeof(connection_id) + client_hello_serialized.length() + 660 requested_config->serialized.size()); 661 hkdf_suffix.append(reinterpret_cast<char*>(&connection_id), 662 sizeof(connection_id)); 663 hkdf_suffix.append(client_hello_serialized.data(), 664 client_hello_serialized.length()); 665 hkdf_suffix.append(requested_config->serialized); 666 667 StringPiece cetv_ciphertext; 668 if (requested_config->channel_id_enabled && 669 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) { 670 CryptoHandshakeMessage client_hello_copy(client_hello); 671 client_hello_copy.Erase(kCETV); 672 client_hello_copy.Erase(kPAD); 673 674 const QuicData& client_hello_serialized = client_hello_copy.GetSerialized(); 675 string hkdf_input; 676 hkdf_input.append(QuicCryptoConfig::kCETVLabel, 677 strlen(QuicCryptoConfig::kCETVLabel) + 1); 678 hkdf_input.append(reinterpret_cast<char*>(&connection_id), 679 sizeof(connection_id)); 680 hkdf_input.append(client_hello_serialized.data(), 681 client_hello_serialized.length()); 682 hkdf_input.append(requested_config->serialized); 683 684 CrypterPair crypters; 685 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, 686 info.client_nonce, info.server_nonce, 687 hkdf_input, CryptoUtils::SERVER, &crypters, 688 NULL /* subkey secret */)) { 689 *error_details = "Symmetric key setup failed"; 690 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; 691 } 692 693 scoped_ptr<QuicData> cetv_plaintext(crypters.decrypter->DecryptPacket( 694 0 /* sequence number */, StringPiece() /* associated data */, 695 cetv_ciphertext)); 696 if (!cetv_plaintext.get()) { 697 *error_details = "CETV decryption failure"; 698 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 699 } 700 701 scoped_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage( 702 cetv_plaintext->AsStringPiece())); 703 if (!cetv.get()) { 704 *error_details = "CETV parse error"; 705 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 706 } 707 708 StringPiece key, signature; 709 if (cetv->GetStringPiece(kCIDK, &key) && 710 cetv->GetStringPiece(kCIDS, &signature)) { 711 if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { 712 *error_details = "ChannelID signature failure"; 713 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 714 } 715 716 params->channel_id = key.as_string(); 717 } 718 } 719 720 string hkdf_input; 721 size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; 722 hkdf_input.reserve(label_len + hkdf_suffix.size()); 723 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); 724 hkdf_input.append(hkdf_suffix); 725 726 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, 727 info.client_nonce, info.server_nonce, hkdf_input, 728 CryptoUtils::SERVER, 729 ¶ms->initial_crypters, 730 NULL /* subkey secret */)) { 731 *error_details = "Symmetric key setup failed"; 732 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; 733 } 734 735 string forward_secure_public_value; 736 if (ephemeral_key_source_.get()) { 737 params->forward_secure_premaster_secret = 738 ephemeral_key_source_->CalculateForwardSecureKey( 739 key_exchange, rand, clock->ApproximateNow(), public_value, 740 &forward_secure_public_value); 741 } else { 742 scoped_ptr<KeyExchange> forward_secure_key_exchange( 743 key_exchange->NewKeyPair(rand)); 744 forward_secure_public_value = 745 forward_secure_key_exchange->public_value().as_string(); 746 if (!forward_secure_key_exchange->CalculateSharedKey( 747 public_value, ¶ms->forward_secure_premaster_secret)) { 748 *error_details = "Invalid public value"; 749 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 750 } 751 } 752 753 string forward_secure_hkdf_input; 754 label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; 755 forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size()); 756 forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, 757 label_len); 758 forward_secure_hkdf_input.append(hkdf_suffix); 759 760 if (!CryptoUtils::DeriveKeys( 761 params->forward_secure_premaster_secret, params->aead, 762 info.client_nonce, info.server_nonce, forward_secure_hkdf_input, 763 CryptoUtils::SERVER, ¶ms->forward_secure_crypters, 764 ¶ms->subkey_secret)) { 765 *error_details = "Symmetric key setup failed"; 766 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; 767 } 768 769 out->set_tag(kSHLO); 770 QuicTagVector supported_version_tags; 771 for (size_t i = 0; i < supported_versions.size(); ++i) { 772 supported_version_tags.push_back 773 (QuicVersionToQuicTag(supported_versions[i])); 774 } 775 out->SetVector(kVER, supported_version_tags); 776 out->SetStringPiece( 777 kSourceAddressTokenTag, 778 NewSourceAddressToken( 779 *requested_config.get(), client_address, rand, info.now, NULL)); 780 QuicSocketAddressCoder address_coder(client_address); 781 out->SetStringPiece(kCADR, address_coder.Encode()); 782 out->SetStringPiece(kPUBS, forward_secure_public_value); 783 784 return QUIC_NO_ERROR; 785 } 786 787 scoped_refptr<QuicCryptoServerConfig::Config> 788 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { 789 // In Chromium, we will dead lock if the lock is held by the current thread. 790 // Chromium doesn't have AssertReaderHeld API call. 791 // configs_lock_.AssertReaderHeld(); 792 793 if (!requested_scid.empty()) { 794 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); 795 if (it != configs_.end()) { 796 // We'll use the config that the client requested in order to do 797 // key-agreement. 798 return scoped_refptr<Config>(it->second); 799 } 800 } 801 802 return scoped_refptr<Config>(); 803 } 804 805 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for 806 // Config's based on their primary_time. 807 // static 808 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan( 809 const scoped_refptr<Config>& a, 810 const scoped_refptr<Config>& b) { 811 if (a->primary_time.IsBefore(b->primary_time) || 812 b->primary_time.IsBefore(a->primary_time)) { 813 // Primary times differ. 814 return a->primary_time.IsBefore(b->primary_time); 815 } else if (a->priority != b->priority) { 816 // Primary times are equal, sort backwards by priority. 817 return a->priority < b->priority; 818 } else { 819 // Primary times and priorities are equal, sort by config id. 820 return a->id < b->id; 821 } 822 } 823 824 void QuicCryptoServerConfig::SelectNewPrimaryConfig( 825 const QuicWallTime now) const { 826 vector<scoped_refptr<Config> > configs; 827 configs.reserve(configs_.size()); 828 829 for (ConfigMap::const_iterator it = configs_.begin(); 830 it != configs_.end(); ++it) { 831 // TODO(avd) Exclude expired configs? 832 configs.push_back(it->second); 833 } 834 835 if (configs.empty()) { 836 if (primary_config_.get()) { 837 LOG(DFATAL) << "No valid QUIC server config. Keeping the current config."; 838 } else { 839 LOG(DFATAL) << "No valid QUIC server config."; 840 } 841 return; 842 } 843 844 sort(configs.begin(), configs.end(), ConfigPrimaryTimeLessThan); 845 846 Config* best_candidate = configs[0].get(); 847 848 for (size_t i = 0; i < configs.size(); ++i) { 849 const scoped_refptr<Config> config(configs[i]); 850 if (!config->primary_time.IsAfter(now)) { 851 if (config->primary_time.IsAfter(best_candidate->primary_time)) { 852 best_candidate = config.get(); 853 } 854 continue; 855 } 856 857 // This is the first config with a primary_time in the future. Thus the 858 // previous Config should be the primary and this one should determine the 859 // next_config_promotion_time_. 860 scoped_refptr<Config> new_primary(best_candidate); 861 if (i == 0) { 862 // We need the primary_time of the next config. 863 if (configs.size() > 1) { 864 next_config_promotion_time_ = configs[1]->primary_time; 865 } else { 866 next_config_promotion_time_ = QuicWallTime::Zero(); 867 } 868 } else { 869 next_config_promotion_time_ = config->primary_time; 870 } 871 872 if (primary_config_.get()) { 873 primary_config_->is_primary = false; 874 } 875 primary_config_ = new_primary; 876 new_primary->is_primary = true; 877 DVLOG(1) << "New primary config. orbit: " 878 << base::HexEncode( 879 reinterpret_cast<const char*>(primary_config_->orbit), 880 kOrbitSize); 881 if (primary_config_changed_cb_.get() != NULL) { 882 primary_config_changed_cb_->Run(primary_config_->id); 883 } 884 885 return; 886 } 887 888 // All config's primary times are in the past. We should make the most recent 889 // and highest priority candidate primary. 890 scoped_refptr<Config> new_primary(best_candidate); 891 if (primary_config_.get()) { 892 primary_config_->is_primary = false; 893 } 894 primary_config_ = new_primary; 895 new_primary->is_primary = true; 896 DVLOG(1) << "New primary config. orbit: " 897 << base::HexEncode( 898 reinterpret_cast<const char*>(primary_config_->orbit), 899 kOrbitSize) 900 << " scid: " << base::HexEncode(primary_config_->id.data(), 901 primary_config_->id.size()); 902 next_config_promotion_time_ = QuicWallTime::Zero(); 903 if (primary_config_changed_cb_.get() != NULL) { 904 primary_config_changed_cb_->Run(primary_config_->id); 905 } 906 } 907 908 void QuicCryptoServerConfig::EvaluateClientHello( 909 const uint8* primary_orbit, 910 scoped_refptr<Config> requested_config, 911 ValidateClientHelloResultCallback::Result* client_hello_state, 912 ValidateClientHelloResultCallback* done_cb) const { 913 ValidateClientHelloHelper helper(client_hello_state, done_cb); 914 915 const CryptoHandshakeMessage& client_hello = 916 client_hello_state->client_hello; 917 ClientHelloInfo* info = &(client_hello_state->info); 918 919 if (client_hello.size() < kClientHelloMinimumSize) { 920 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, 921 "Client hello too small"); 922 return; 923 } 924 925 if (client_hello.GetStringPiece(kSNI, &info->sni) && 926 !CryptoUtils::IsValidSNI(info->sni)) { 927 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, 928 "Invalid SNI name"); 929 return; 930 } 931 932 client_hello.GetStringPiece(kUAID, &info->user_agent_id); 933 934 if (!requested_config.get()) { 935 StringPiece requested_scid; 936 if (client_hello.GetStringPiece(kSCID, &requested_scid)) { 937 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); 938 } else { 939 info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE); 940 } 941 // No server config with the requested ID. 942 helper.ValidationComplete(QUIC_NO_ERROR, ""); 943 return; 944 } 945 946 HandshakeFailureReason source_address_token_error; 947 StringPiece srct; 948 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { 949 source_address_token_error = ValidateSourceAddressToken( 950 *requested_config.get(), srct, info->client_ip, info->now); 951 info->valid_source_address_token = 952 (source_address_token_error == HANDSHAKE_OK); 953 } else { 954 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE; 955 } 956 957 bool found_error = false; 958 if (source_address_token_error != HANDSHAKE_OK) { 959 info->reject_reasons.push_back(source_address_token_error); 960 // No valid source address token. 961 if (FLAGS_use_early_return_when_verifying_chlo) { 962 helper.ValidationComplete(QUIC_NO_ERROR, ""); 963 return; 964 } 965 found_error = true; 966 } 967 968 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && 969 info->client_nonce.size() == kNonceSize) { 970 info->client_nonce_well_formed = true; 971 } else { 972 info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); 973 // Invalid client nonce. 974 DVLOG(1) << "Invalid client nonce."; 975 if (FLAGS_use_early_return_when_verifying_chlo) { 976 helper.ValidationComplete(QUIC_NO_ERROR, ""); 977 return; 978 } 979 found_error = true; 980 } 981 982 if (!replay_protection_) { 983 if (!found_error) { 984 info->unique = true; 985 } 986 DVLOG(1) << "No replay protection."; 987 helper.ValidationComplete(QUIC_NO_ERROR, ""); 988 return; 989 } 990 991 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); 992 if (!info->server_nonce.empty()) { 993 // If the server nonce is present, use it to establish uniqueness. 994 HandshakeFailureReason server_nonce_error = 995 ValidateServerNonce(info->server_nonce, info->now); 996 if (server_nonce_error == HANDSHAKE_OK) { 997 info->unique = true; 998 } else { 999 info->reject_reasons.push_back(server_nonce_error); 1000 info->unique = false; 1001 } 1002 DVLOG(1) << "Using server nonce, unique: " << info->unique; 1003 helper.ValidationComplete(QUIC_NO_ERROR, ""); 1004 return; 1005 } 1006 1007 // We want to contact strike register only if there are no errors because it 1008 // is a RPC call and is expensive. 1009 if (found_error) { 1010 helper.ValidationComplete(QUIC_NO_ERROR, ""); 1011 return; 1012 } 1013 1014 // Use the client nonce to establish uniqueness. 1015 StrikeRegisterClient* strike_register_client; 1016 { 1017 base::AutoLock locked(strike_register_client_lock_); 1018 1019 if (strike_register_client_.get() == NULL) { 1020 strike_register_client_.reset(new LocalStrikeRegisterClient( 1021 strike_register_max_entries_, 1022 static_cast<uint32>(info->now.ToUNIXSeconds()), 1023 strike_register_window_secs_, 1024 primary_orbit, 1025 strike_register_no_startup_period_ ? 1026 StrikeRegister::NO_STARTUP_PERIOD_NEEDED : 1027 StrikeRegister::DENY_REQUESTS_AT_STARTUP)); 1028 } 1029 strike_register_client = strike_register_client_.get(); 1030 } 1031 1032 strike_register_client->VerifyNonceIsValidAndUnique( 1033 info->client_nonce, 1034 info->now, 1035 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); 1036 helper.StartedAsyncCallback(); 1037 } 1038 1039 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( 1040 const IPEndPoint& client_ip, 1041 const QuicClock* clock, 1042 QuicRandom* rand, 1043 const QuicCryptoNegotiatedParameters& params, 1044 const CachedNetworkParameters* cached_network_params, 1045 CryptoHandshakeMessage* out) const { 1046 base::AutoLock locked(configs_lock_); 1047 out->set_tag(kSCUP); 1048 out->SetStringPiece(kSCFG, primary_config_->serialized); 1049 out->SetStringPiece(kSourceAddressTokenTag, 1050 NewSourceAddressToken(*primary_config_.get(), 1051 client_ip, 1052 rand, 1053 clock->WallNow(), 1054 cached_network_params)); 1055 1056 if (proof_source_ == NULL) { 1057 // Insecure QUIC, can send SCFG without proof. 1058 return true; 1059 } 1060 1061 const vector<string>* certs; 1062 string signature; 1063 if (!proof_source_->GetProof(params.sni, primary_config_->serialized, 1064 params.x509_ecdsa_supported, &certs, 1065 &signature)) { 1066 DVLOG(1) << "Server: failed to get proof."; 1067 return false; 1068 } 1069 1070 const string compressed = CertCompressor::CompressChain( 1071 *certs, params.client_common_set_hashes, params.client_cached_cert_hashes, 1072 primary_config_->common_cert_sets); 1073 1074 out->SetStringPiece(kCertificateTag, compressed); 1075 out->SetStringPiece(kPROF, signature); 1076 return true; 1077 } 1078 1079 void QuicCryptoServerConfig::BuildRejection( 1080 const Config& config, 1081 const CryptoHandshakeMessage& client_hello, 1082 const ClientHelloInfo& info, 1083 QuicRandom* rand, 1084 QuicCryptoNegotiatedParameters *params, 1085 CryptoHandshakeMessage* out) const { 1086 out->set_tag(kREJ); 1087 out->SetStringPiece(kSCFG, config.serialized); 1088 out->SetStringPiece(kSourceAddressTokenTag, 1089 NewSourceAddressToken( 1090 config, 1091 info.client_ip, 1092 rand, 1093 info.now, 1094 NULL)); 1095 if (replay_protection_) { 1096 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); 1097 } 1098 1099 if (FLAGS_send_quic_crypto_reject_reason) { 1100 // Send client the reject reason for debugging purposes. 1101 DCHECK_LT(0u, info.reject_reasons.size()); 1102 out->SetVector(kRREJ, info.reject_reasons); 1103 } 1104 1105 // The client may have requested a certificate chain. 1106 const QuicTag* their_proof_demands; 1107 size_t num_their_proof_demands; 1108 1109 if (proof_source_.get() == NULL || 1110 client_hello.GetTaglist(kPDMD, &their_proof_demands, 1111 &num_their_proof_demands) != 1112 QUIC_NO_ERROR) { 1113 return; 1114 } 1115 1116 bool x509_supported = false; 1117 for (size_t i = 0; i < num_their_proof_demands; i++) { 1118 switch (their_proof_demands[i]) { 1119 case kX509: 1120 x509_supported = true; 1121 params->x509_ecdsa_supported = true; 1122 break; 1123 case kX59R: 1124 x509_supported = true; 1125 break; 1126 } 1127 } 1128 1129 if (!x509_supported) { 1130 return; 1131 } 1132 1133 const vector<string>* certs; 1134 string signature; 1135 if (!proof_source_->GetProof(info.sni.as_string(), config.serialized, 1136 params->x509_ecdsa_supported, &certs, 1137 &signature)) { 1138 return; 1139 } 1140 1141 StringPiece client_common_set_hashes; 1142 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) { 1143 params->client_common_set_hashes = client_common_set_hashes.as_string(); 1144 } 1145 1146 StringPiece client_cached_cert_hashes; 1147 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) { 1148 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string(); 1149 } 1150 1151 const string compressed = CertCompressor::CompressChain( 1152 *certs, params->client_common_set_hashes, 1153 params->client_cached_cert_hashes, config.common_cert_sets); 1154 1155 // kREJOverheadBytes is a very rough estimate of how much of a REJ 1156 // message is taken up by things other than the certificates. 1157 // STK: 56 bytes 1158 // SNO: 56 bytes 1159 // SCFG 1160 // SCID: 16 bytes 1161 // PUBS: 38 bytes 1162 const size_t kREJOverheadBytes = 166; 1163 // kMultiplier is the multiple of the CHLO message size that a REJ message 1164 // must stay under when the client doesn't present a valid source-address 1165 // token. 1166 const size_t kMultiplier = 2; 1167 // max_unverified_size is the number of bytes that the certificate chain 1168 // and signature can consume before we will demand a valid source-address 1169 // token. 1170 const size_t max_unverified_size = 1171 client_hello.size() * kMultiplier - kREJOverheadBytes; 1172 COMPILE_ASSERT(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes, 1173 overhead_calculation_may_underflow); 1174 if (info.valid_source_address_token || 1175 signature.size() + compressed.size() < max_unverified_size) { 1176 out->SetStringPiece(kCertificateTag, compressed); 1177 out->SetStringPiece(kPROF, signature); 1178 } 1179 } 1180 1181 scoped_refptr<QuicCryptoServerConfig::Config> 1182 QuicCryptoServerConfig::ParseConfigProtobuf( 1183 QuicServerConfigProtobuf* protobuf) { 1184 scoped_ptr<CryptoHandshakeMessage> msg( 1185 CryptoFramer::ParseMessage(protobuf->config())); 1186 1187 if (msg->tag() != kSCFG) { 1188 LOG(WARNING) << "Server config message has tag " << msg->tag() 1189 << " expected " << kSCFG; 1190 return NULL; 1191 } 1192 1193 scoped_refptr<Config> config(new Config); 1194 config->serialized = protobuf->config(); 1195 1196 if (!protobuf->has_source_address_token_secret_override()) { 1197 // Use the default boxer. 1198 config->source_address_token_boxer = &default_source_address_token_boxer_; 1199 } else { 1200 // Create override boxer instance. 1201 CryptoSecretBoxer* boxer = new CryptoSecretBoxer; 1202 boxer->SetKey(DeriveSourceAddressTokenKey( 1203 protobuf->source_address_token_secret_override())); 1204 config->source_address_token_boxer_storage.reset(boxer); 1205 config->source_address_token_boxer = boxer; 1206 } 1207 1208 if (protobuf->has_primary_time()) { 1209 config->primary_time = 1210 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); 1211 } 1212 1213 config->priority = protobuf->priority(); 1214 1215 StringPiece scid; 1216 if (!msg->GetStringPiece(kSCID, &scid)) { 1217 LOG(WARNING) << "Server config message is missing SCID"; 1218 return NULL; 1219 } 1220 config->id = scid.as_string(); 1221 1222 const QuicTag* aead_tags; 1223 size_t aead_len; 1224 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { 1225 LOG(WARNING) << "Server config message is missing AEAD"; 1226 return NULL; 1227 } 1228 config->aead = vector<QuicTag>(aead_tags, aead_tags + aead_len); 1229 1230 const QuicTag* kexs_tags; 1231 size_t kexs_len; 1232 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { 1233 LOG(WARNING) << "Server config message is missing KEXS"; 1234 return NULL; 1235 } 1236 1237 StringPiece orbit; 1238 if (!msg->GetStringPiece(kORBT, &orbit)) { 1239 LOG(WARNING) << "Server config message is missing ORBT"; 1240 return NULL; 1241 } 1242 1243 if (orbit.size() != kOrbitSize) { 1244 LOG(WARNING) << "Orbit value in server config is the wrong length." 1245 " Got " << orbit.size() << " want " << kOrbitSize; 1246 return NULL; 1247 } 1248 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); 1249 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); 1250 1251 { 1252 StrikeRegisterClient* strike_register_client; 1253 { 1254 base::AutoLock locked(strike_register_client_lock_); 1255 strike_register_client = strike_register_client_.get(); 1256 } 1257 1258 if (strike_register_client != NULL && 1259 !strike_register_client->IsKnownOrbit(orbit)) { 1260 LOG(WARNING) 1261 << "Rejecting server config with orbit that the strike register " 1262 "client doesn't know about."; 1263 return NULL; 1264 } 1265 } 1266 1267 if (kexs_len != protobuf->key_size()) { 1268 LOG(WARNING) << "Server config has " << kexs_len 1269 << " key exchange methods configured, but " 1270 << protobuf->key_size() << " private keys"; 1271 return NULL; 1272 } 1273 1274 const QuicTag* proof_demand_tags; 1275 size_t num_proof_demand_tags; 1276 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == 1277 QUIC_NO_ERROR) { 1278 for (size_t i = 0; i < num_proof_demand_tags; i++) { 1279 if (proof_demand_tags[i] == kCHID) { 1280 config->channel_id_enabled = true; 1281 break; 1282 } 1283 } 1284 } 1285 1286 for (size_t i = 0; i < kexs_len; i++) { 1287 const QuicTag tag = kexs_tags[i]; 1288 string private_key; 1289 1290 config->kexs.push_back(tag); 1291 1292 for (size_t j = 0; j < protobuf->key_size(); j++) { 1293 const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i); 1294 if (key.tag() == tag) { 1295 private_key = key.private_key(); 1296 break; 1297 } 1298 } 1299 1300 if (private_key.empty()) { 1301 LOG(WARNING) << "Server config contains key exchange method without " 1302 "corresponding private key: " << tag; 1303 return NULL; 1304 } 1305 1306 scoped_ptr<KeyExchange> ka; 1307 switch (tag) { 1308 case kC255: 1309 ka.reset(Curve25519KeyExchange::New(private_key)); 1310 if (!ka.get()) { 1311 LOG(WARNING) << "Server config contained an invalid curve25519" 1312 " private key."; 1313 return NULL; 1314 } 1315 break; 1316 case kP256: 1317 ka.reset(P256KeyExchange::New(private_key)); 1318 if (!ka.get()) { 1319 LOG(WARNING) << "Server config contained an invalid P-256" 1320 " private key."; 1321 return NULL; 1322 } 1323 break; 1324 default: 1325 LOG(WARNING) << "Server config message contains unknown key exchange " 1326 "method: " << tag; 1327 return NULL; 1328 } 1329 1330 for (vector<KeyExchange*>::const_iterator i = config->key_exchanges.begin(); 1331 i != config->key_exchanges.end(); ++i) { 1332 if ((*i)->tag() == tag) { 1333 LOG(WARNING) << "Duplicate key exchange in config: " << tag; 1334 return NULL; 1335 } 1336 } 1337 1338 config->key_exchanges.push_back(ka.release()); 1339 } 1340 1341 return config; 1342 } 1343 1344 void QuicCryptoServerConfig::SetProofSource(ProofSource* proof_source) { 1345 proof_source_.reset(proof_source); 1346 } 1347 1348 void QuicCryptoServerConfig::SetEphemeralKeySource( 1349 EphemeralKeySource* ephemeral_key_source) { 1350 ephemeral_key_source_.reset(ephemeral_key_source); 1351 } 1352 1353 void QuicCryptoServerConfig::SetStrikeRegisterClient( 1354 StrikeRegisterClient* strike_register_client) { 1355 base::AutoLock locker(strike_register_client_lock_); 1356 DCHECK(!strike_register_client_.get()); 1357 strike_register_client_.reset(strike_register_client); 1358 } 1359 1360 void QuicCryptoServerConfig::set_replay_protection(bool on) { 1361 replay_protection_ = on; 1362 } 1363 1364 void QuicCryptoServerConfig::set_strike_register_no_startup_period() { 1365 base::AutoLock locker(strike_register_client_lock_); 1366 DCHECK(!strike_register_client_.get()); 1367 strike_register_no_startup_period_ = true; 1368 } 1369 1370 void QuicCryptoServerConfig::set_strike_register_max_entries( 1371 uint32 max_entries) { 1372 base::AutoLock locker(strike_register_client_lock_); 1373 DCHECK(!strike_register_client_.get()); 1374 strike_register_max_entries_ = max_entries; 1375 } 1376 1377 void QuicCryptoServerConfig::set_strike_register_window_secs( 1378 uint32 window_secs) { 1379 base::AutoLock locker(strike_register_client_lock_); 1380 DCHECK(!strike_register_client_.get()); 1381 strike_register_window_secs_ = window_secs; 1382 } 1383 1384 void QuicCryptoServerConfig::set_source_address_token_future_secs( 1385 uint32 future_secs) { 1386 source_address_token_future_secs_ = future_secs; 1387 } 1388 1389 void QuicCryptoServerConfig::set_source_address_token_lifetime_secs( 1390 uint32 lifetime_secs) { 1391 source_address_token_lifetime_secs_ = lifetime_secs; 1392 } 1393 1394 void QuicCryptoServerConfig::set_server_nonce_strike_register_max_entries( 1395 uint32 max_entries) { 1396 DCHECK(!server_nonce_strike_register_.get()); 1397 server_nonce_strike_register_max_entries_ = max_entries; 1398 } 1399 1400 void QuicCryptoServerConfig::set_server_nonce_strike_register_window_secs( 1401 uint32 window_secs) { 1402 DCHECK(!server_nonce_strike_register_.get()); 1403 server_nonce_strike_register_window_secs_ = window_secs; 1404 } 1405 1406 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( 1407 PrimaryConfigChangedCallback* cb) { 1408 base::AutoLock locked(configs_lock_); 1409 primary_config_changed_cb_.reset(cb); 1410 } 1411 1412 string QuicCryptoServerConfig::NewSourceAddressToken( 1413 const Config& config, 1414 const IPEndPoint& ip, 1415 QuicRandom* rand, 1416 QuicWallTime now, 1417 const CachedNetworkParameters* cached_network_params) const { 1418 IPAddressNumber ip_address = ip.address(); 1419 if (ip.GetSockAddrFamily() == AF_INET) { 1420 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); 1421 } 1422 SourceAddressToken source_address_token; 1423 source_address_token.set_ip(IPAddressToPackedString(ip_address)); 1424 source_address_token.set_timestamp(now.ToUNIXSeconds()); 1425 if (cached_network_params != NULL) { 1426 source_address_token.set_cached_network_parameters(*cached_network_params); 1427 } 1428 1429 return config.source_address_token_boxer->Box( 1430 rand, source_address_token.SerializeAsString()); 1431 } 1432 1433 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken( 1434 const Config& config, 1435 StringPiece token, 1436 const IPEndPoint& ip, 1437 QuicWallTime now) const { 1438 string storage; 1439 StringPiece plaintext; 1440 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { 1441 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE; 1442 } 1443 1444 SourceAddressToken source_address_token; 1445 if (!source_address_token.ParseFromArray(plaintext.data(), 1446 plaintext.size())) { 1447 return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE; 1448 } 1449 1450 IPAddressNumber ip_address = ip.address(); 1451 if (ip.GetSockAddrFamily() == AF_INET) { 1452 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); 1453 } 1454 if (source_address_token.ip() != IPAddressToPackedString(ip_address)) { 1455 // It's for a different IP address. 1456 return SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE; 1457 } 1458 1459 const QuicWallTime timestamp( 1460 QuicWallTime::FromUNIXSeconds(source_address_token.timestamp())); 1461 const QuicTime::Delta delta(now.AbsoluteDifference(timestamp)); 1462 1463 if (now.IsBefore(timestamp) && 1464 delta.ToSeconds() > source_address_token_future_secs_) { 1465 return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE; 1466 } 1467 1468 if (now.IsAfter(timestamp) && 1469 delta.ToSeconds() > source_address_token_lifetime_secs_) { 1470 return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE; 1471 } 1472 1473 return HANDSHAKE_OK; 1474 } 1475 1476 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server 1477 // nonce. 1478 static const size_t kServerNoncePlaintextSize = 1479 4 /* timestamp */ + 20 /* random bytes */; 1480 1481 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand, 1482 QuicWallTime now) const { 1483 const uint32 timestamp = static_cast<uint32>(now.ToUNIXSeconds()); 1484 1485 uint8 server_nonce[kServerNoncePlaintextSize]; 1486 COMPILE_ASSERT(sizeof(server_nonce) > sizeof(timestamp), nonce_too_small); 1487 server_nonce[0] = static_cast<uint8>(timestamp >> 24); 1488 server_nonce[1] = static_cast<uint8>(timestamp >> 16); 1489 server_nonce[2] = static_cast<uint8>(timestamp >> 8); 1490 server_nonce[3] = static_cast<uint8>(timestamp); 1491 rand->RandBytes(&server_nonce[sizeof(timestamp)], 1492 sizeof(server_nonce) - sizeof(timestamp)); 1493 1494 return server_nonce_boxer_.Box( 1495 rand, 1496 StringPiece(reinterpret_cast<char*>(server_nonce), sizeof(server_nonce))); 1497 } 1498 1499 HandshakeFailureReason QuicCryptoServerConfig::ValidateServerNonce( 1500 StringPiece token, 1501 QuicWallTime now) const { 1502 string storage; 1503 StringPiece plaintext; 1504 if (!server_nonce_boxer_.Unbox(token, &storage, &plaintext)) { 1505 return SERVER_NONCE_DECRYPTION_FAILURE; 1506 } 1507 1508 // plaintext contains: 1509 // uint32 timestamp 1510 // uint8[20] random bytes 1511 1512 if (plaintext.size() != kServerNoncePlaintextSize) { 1513 // This should never happen because the value decrypted correctly. 1514 LOG(DFATAL) << "Seemingly valid server nonce had incorrect length."; 1515 return SERVER_NONCE_INVALID_FAILURE; 1516 } 1517 1518 uint8 server_nonce[32]; 1519 memcpy(server_nonce, plaintext.data(), 4); 1520 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); 1521 memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, 1522 20); 1523 COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), 1524 bad_nonce_buffer_length); 1525 1526 InsertStatus nonce_error; 1527 { 1528 base::AutoLock auto_lock(server_nonce_strike_register_lock_); 1529 if (server_nonce_strike_register_.get() == NULL) { 1530 server_nonce_strike_register_.reset(new StrikeRegister( 1531 server_nonce_strike_register_max_entries_, 1532 static_cast<uint32>(now.ToUNIXSeconds()), 1533 server_nonce_strike_register_window_secs_, server_nonce_orbit_, 1534 StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); 1535 } 1536 nonce_error = server_nonce_strike_register_->Insert( 1537 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); 1538 } 1539 1540 switch (nonce_error) { 1541 case NONCE_OK: 1542 return HANDSHAKE_OK; 1543 case NONCE_INVALID_FAILURE: 1544 case NONCE_INVALID_ORBIT_FAILURE: 1545 return SERVER_NONCE_INVALID_FAILURE; 1546 case NONCE_NOT_UNIQUE_FAILURE: 1547 return SERVER_NONCE_NOT_UNIQUE_FAILURE; 1548 case NONCE_INVALID_TIME_FAILURE: 1549 return SERVER_NONCE_INVALID_TIME_FAILURE; 1550 case NONCE_UNKNOWN_FAILURE: 1551 case STRIKE_REGISTER_TIMEOUT: 1552 case STRIKE_REGISTER_FAILURE: 1553 default: 1554 LOG(DFATAL) << "Unexpected server nonce error: " << nonce_error; 1555 return SERVER_NONCE_NOT_UNIQUE_FAILURE; 1556 } 1557 } 1558 1559 QuicCryptoServerConfig::Config::Config() 1560 : channel_id_enabled(false), 1561 is_primary(false), 1562 primary_time(QuicWallTime::Zero()), 1563 priority(0), 1564 source_address_token_boxer(NULL) {} 1565 1566 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } 1567 1568 } // namespace net 1569