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_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/quic/crypto/aes_128_gcm_12_decrypter.h" 15 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" 16 #include "net/quic/crypto/cert_compressor.h" 17 #include "net/quic/crypto/channel_id.h" 18 #include "net/quic/crypto/crypto_framer.h" 19 #include "net/quic/crypto/crypto_server_config_protobuf.h" 20 #include "net/quic/crypto/crypto_utils.h" 21 #include "net/quic/crypto/curve25519_key_exchange.h" 22 #include "net/quic/crypto/ephemeral_key_source.h" 23 #include "net/quic/crypto/key_exchange.h" 24 #include "net/quic/crypto/p256_key_exchange.h" 25 #include "net/quic/crypto/proof_source.h" 26 #include "net/quic/crypto/quic_decrypter.h" 27 #include "net/quic/crypto/quic_encrypter.h" 28 #include "net/quic/crypto/quic_random.h" 29 #include "net/quic/crypto/source_address_token.h" 30 #include "net/quic/crypto/strike_register.h" 31 #include "net/quic/quic_clock.h" 32 #include "net/quic/quic_protocol.h" 33 #include "net/quic/quic_utils.h" 34 35 using base::StringPiece; 36 using crypto::SecureHash; 37 using std::map; 38 using std::string; 39 using std::vector; 40 41 namespace net { 42 43 // static 44 const char QuicCryptoServerConfig::TESTING[] = "secret string for testing"; 45 46 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() 47 : expiry_time(QuicWallTime::Zero()), 48 channel_id_enabled(false) { } 49 50 QuicCryptoServerConfig::QuicCryptoServerConfig( 51 StringPiece source_address_token_secret, 52 QuicRandom* rand) 53 : replay_protection_(true), 54 configs_lock_(), 55 primary_config_(NULL), 56 next_config_promotion_time_(QuicWallTime::Zero()), 57 strike_register_lock_(), 58 server_nonce_strike_register_lock_(), 59 strike_register_max_entries_(1 << 10), 60 strike_register_window_secs_(600), 61 source_address_token_future_secs_(3600), 62 source_address_token_lifetime_secs_(86400), 63 server_nonce_strike_register_max_entries_(1 << 10), 64 server_nonce_strike_register_window_secs_(120) { 65 crypto::HKDF hkdf(source_address_token_secret, StringPiece() /* no salt */, 66 "QUIC source address token key", 67 CryptoSecretBoxer::GetKeySize(), 68 0 /* no fixed IV needed */); 69 source_address_token_boxer_.SetKey(hkdf.server_write_key()); 70 71 // Generate a random key and orbit for server nonces. 72 rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_)); 73 const size_t key_size = server_nonce_boxer_.GetKeySize(); 74 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]); 75 rand->RandBytes(key_bytes.get(), key_size); 76 77 server_nonce_boxer_.SetKey( 78 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size)); 79 } 80 81 QuicCryptoServerConfig::~QuicCryptoServerConfig() { 82 primary_config_ = NULL; 83 } 84 85 // static 86 QuicServerConfigProtobuf* QuicCryptoServerConfig::DefaultConfig( 87 QuicRandom* rand, 88 const QuicClock* clock, 89 const ConfigOptions& options) { 90 CryptoHandshakeMessage msg; 91 92 const string curve25519_private_key = 93 Curve25519KeyExchange::NewPrivateKey(rand); 94 scoped_ptr<Curve25519KeyExchange> curve25519( 95 Curve25519KeyExchange::New(curve25519_private_key)); 96 StringPiece curve25519_public_value = curve25519->public_value(); 97 98 const string p256_private_key = P256KeyExchange::NewPrivateKey(); 99 scoped_ptr<P256KeyExchange> p256(P256KeyExchange::New(p256_private_key)); 100 StringPiece p256_public_value = p256->public_value(); 101 102 string encoded_public_values; 103 // First three bytes encode the length of the public value. 104 encoded_public_values.push_back(curve25519_public_value.size()); 105 encoded_public_values.push_back(curve25519_public_value.size() >> 8); 106 encoded_public_values.push_back(curve25519_public_value.size() >> 16); 107 encoded_public_values.append(curve25519_public_value.data(), 108 curve25519_public_value.size()); 109 encoded_public_values.push_back(p256_public_value.size()); 110 encoded_public_values.push_back(p256_public_value.size() >> 8); 111 encoded_public_values.push_back(p256_public_value.size() >> 16); 112 encoded_public_values.append(p256_public_value.data(), 113 p256_public_value.size()); 114 115 msg.set_tag(kSCFG); 116 msg.SetTaglist(kKEXS, kC255, kP256, 0); 117 msg.SetTaglist(kAEAD, kAESG, 0); 118 msg.SetValue(kVERS, static_cast<uint16>(0)); 119 msg.SetStringPiece(kPUBS, encoded_public_values); 120 121 if (options.expiry_time.IsZero()) { 122 const QuicWallTime now = clock->WallNow(); 123 const QuicWallTime expiry = now.Add(QuicTime::Delta::FromSeconds( 124 60 * 60 * 24 * 180 /* 180 days, ~six months */)); 125 const uint64 expiry_seconds = expiry.ToUNIXSeconds(); 126 msg.SetValue(kEXPY, expiry_seconds); 127 } else { 128 msg.SetValue(kEXPY, options.expiry_time.ToUNIXSeconds()); 129 } 130 131 if (options.id.empty()) { 132 char scid_bytes[16]; 133 rand->RandBytes(scid_bytes, sizeof(scid_bytes)); 134 msg.SetStringPiece(kSCID, StringPiece(scid_bytes, sizeof(scid_bytes))); 135 } else { 136 msg.SetStringPiece(kSCID, options.id); 137 } 138 139 char orbit_bytes[kOrbitSize]; 140 if (options.orbit.size() == sizeof(orbit_bytes)) { 141 memcpy(orbit_bytes, options.orbit.data(), sizeof(orbit_bytes)); 142 } else { 143 DCHECK(options.orbit.empty()); 144 rand->RandBytes(orbit_bytes, sizeof(orbit_bytes)); 145 } 146 msg.SetStringPiece(kORBT, StringPiece(orbit_bytes, sizeof(orbit_bytes))); 147 148 if (options.channel_id_enabled) { 149 msg.SetTaglist(kPDMD, kCHID, 0); 150 } 151 152 scoped_ptr<QuicData> serialized(CryptoFramer::ConstructHandshakeMessage(msg)); 153 154 scoped_ptr<QuicServerConfigProtobuf> config(new QuicServerConfigProtobuf); 155 config->set_config(serialized->AsStringPiece()); 156 QuicServerConfigProtobuf::PrivateKey* curve25519_key = config->add_key(); 157 curve25519_key->set_tag(kC255); 158 curve25519_key->set_private_key(curve25519_private_key); 159 QuicServerConfigProtobuf::PrivateKey* p256_key = config->add_key(); 160 p256_key->set_tag(kP256); 161 p256_key->set_private_key(p256_private_key); 162 163 return config.release(); 164 } 165 166 CryptoHandshakeMessage* QuicCryptoServerConfig::AddConfig( 167 QuicServerConfigProtobuf* protobuf, 168 const QuicWallTime now) { 169 scoped_ptr<CryptoHandshakeMessage> msg( 170 CryptoFramer::ParseMessage(protobuf->config())); 171 172 if (!msg.get()) { 173 LOG(WARNING) << "Failed to parse server config message"; 174 return NULL; 175 } 176 177 scoped_refptr<Config> config(ParseConfigProtobuf(protobuf)); 178 if (!config.get()) { 179 LOG(WARNING) << "Failed to parse server config message"; 180 return NULL; 181 } 182 183 { 184 base::AutoLock locked(configs_lock_); 185 if (configs_.find(config->id) != configs_.end()) { 186 LOG(WARNING) << "Failed to add config because another with the same " 187 "server config id already exists: " 188 << base::HexEncode(config->id.data(), config->id.size()); 189 return NULL; 190 } 191 192 configs_[config->id] = config; 193 SelectNewPrimaryConfig(now); 194 DCHECK(primary_config_.get()); 195 } 196 197 return msg.release(); 198 } 199 200 CryptoHandshakeMessage* QuicCryptoServerConfig::AddDefaultConfig( 201 QuicRandom* rand, 202 const QuicClock* clock, 203 const ConfigOptions& options) { 204 scoped_ptr<QuicServerConfigProtobuf> config( 205 DefaultConfig(rand, clock, options)); 206 return AddConfig(config.get(), clock->WallNow()); 207 } 208 209 bool QuicCryptoServerConfig::SetConfigs( 210 const vector<QuicServerConfigProtobuf*>& protobufs, 211 const QuicWallTime now) { 212 vector<scoped_refptr<Config> > new_configs; 213 bool ok = true; 214 215 for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin(); 216 i != protobufs.end(); ++i) { 217 scoped_refptr<Config> config(ParseConfigProtobuf(*i)); 218 if (!config.get()) { 219 ok = false; 220 break; 221 } 222 new_configs.push_back(config); 223 } 224 225 if (!ok) { 226 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; 227 } else { 228 base::AutoLock locked(configs_lock_); 229 typedef ConfigMap::iterator ConfigMapIterator; 230 vector<ConfigMapIterator> to_delete; 231 232 DCHECK_EQ(protobufs.size(), new_configs.size()); 233 234 // First, look for any configs that have been removed. 235 for (ConfigMapIterator i = configs_.begin(); 236 i != configs_.end(); ++i) { 237 const scoped_refptr<Config> old_config = i->second; 238 bool found = false; 239 240 for (vector<scoped_refptr<Config> >::const_iterator j = 241 new_configs.begin(); 242 j != new_configs.end(); ++j) { 243 if ((*j)->id == old_config->id) { 244 found = true; 245 break; 246 } 247 } 248 249 if (!found) { 250 // We cannot remove the primary config. This has probably happened 251 // because our source of config information failed for a time and we're 252 // suddenly seeing a jump in time. No matter - we'll configure a new 253 // primary config and then we'll be able to delete it next time. 254 if (!old_config->is_primary) { 255 to_delete.push_back(i); 256 } 257 } 258 } 259 260 for (vector<ConfigMapIterator>::const_iterator i = to_delete.begin(); 261 i != to_delete.end(); ++i) { 262 configs_.erase(*i); 263 } 264 265 // Find any configs that need to be added. 266 for (vector<scoped_refptr<Config> >::const_iterator i = new_configs.begin(); 267 i != new_configs.end(); ++i) { 268 const scoped_refptr<Config> new_config = *i; 269 if (configs_.find(new_config->id) != configs_.end()) { 270 continue; 271 } 272 273 configs_[new_config->id] = new_config; 274 } 275 276 SelectNewPrimaryConfig(now); 277 } 278 279 return ok; 280 } 281 282 // ClientHelloInfo contains information about a client hello message that is 283 // only kept for as long as it's being processed. 284 struct ClientHelloInfo { 285 ClientHelloInfo(const IPEndPoint& in_client_ip, QuicWallTime in_now) 286 : client_ip(in_client_ip), 287 now(in_now), 288 valid_source_address_token(false), 289 client_nonce_well_formed(false), 290 unique(false) {} 291 292 // Inputs to EvaluateClientHello. 293 const IPEndPoint client_ip; 294 const QuicWallTime now; 295 296 // Outputs from EvaluateClientHello. 297 bool valid_source_address_token; 298 bool client_nonce_well_formed; 299 bool unique; 300 StringPiece sni; 301 StringPiece client_nonce; 302 StringPiece server_nonce; 303 }; 304 305 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( 306 const CryptoHandshakeMessage& client_hello, 307 QuicVersion version, 308 QuicGuid guid, 309 const IPEndPoint& client_ip, 310 const QuicClock* clock, 311 QuicRandom* rand, 312 QuicCryptoNegotiatedParameters *params, 313 CryptoHandshakeMessage* out, 314 string* error_details) const { 315 DCHECK(error_details); 316 317 StringPiece requested_scid; 318 client_hello.GetStringPiece(kSCID, &requested_scid); 319 const QuicWallTime now(clock->WallNow()); 320 321 scoped_refptr<Config> requested_config; 322 scoped_refptr<Config> primary_config; 323 { 324 base::AutoLock locked(configs_lock_); 325 326 if (!primary_config_.get()) { 327 *error_details = "No configurations loaded"; 328 return QUIC_CRYPTO_INTERNAL_ERROR; 329 } 330 331 if (!next_config_promotion_time_.IsZero() && 332 next_config_promotion_time_.IsAfter(now)) { 333 SelectNewPrimaryConfig(now); 334 } 335 336 primary_config = primary_config_; 337 338 if (!requested_scid.empty()) { 339 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); 340 if (it != configs_.end()) { 341 // We'll use the config that the client requested in order to do 342 // key-agreement. Otherwise we'll give it a copy of |primary_config_| 343 // to use. 344 requested_config = it->second; 345 } 346 } 347 } 348 349 ClientHelloInfo info(client_ip, now); 350 QuicErrorCode error = EvaluateClientHello( 351 client_hello, primary_config->orbit, &info, error_details); 352 if (error != QUIC_NO_ERROR) { 353 return error; 354 } 355 356 out->Clear(); 357 358 if (!info.valid_source_address_token || 359 !info.client_nonce_well_formed || 360 !info.unique || 361 !requested_config.get()) { 362 BuildRejection(version, primary_config.get(), client_hello, info, rand, 363 out); 364 return QUIC_NO_ERROR; 365 } 366 367 const QuicTag* their_aeads; 368 const QuicTag* their_key_exchanges; 369 size_t num_their_aeads, num_their_key_exchanges; 370 if (client_hello.GetTaglist(kAEAD, &their_aeads, 371 &num_their_aeads) != QUIC_NO_ERROR || 372 client_hello.GetTaglist(kKEXS, &their_key_exchanges, 373 &num_their_key_exchanges) != QUIC_NO_ERROR || 374 num_their_aeads != 1 || 375 num_their_key_exchanges != 1) { 376 *error_details = "Missing or invalid AEAD or KEXS"; 377 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 378 } 379 380 size_t key_exchange_index; 381 if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads, 382 num_their_aeads, QuicUtils::LOCAL_PRIORITY, 383 ¶ms->aead, NULL) || 384 !QuicUtils::FindMutualTag( 385 requested_config->kexs, their_key_exchanges, num_their_key_exchanges, 386 QuicUtils::LOCAL_PRIORITY, ¶ms->key_exchange, 387 &key_exchange_index)) { 388 *error_details = "Unsupported AEAD or KEXS"; 389 return QUIC_CRYPTO_NO_SUPPORT; 390 } 391 392 StringPiece public_value; 393 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { 394 *error_details = "Missing public value"; 395 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 396 } 397 398 const KeyExchange* key_exchange = 399 requested_config->key_exchanges[key_exchange_index]; 400 if (!key_exchange->CalculateSharedKey(public_value, 401 ¶ms->initial_premaster_secret)) { 402 *error_details = "Invalid public value"; 403 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 404 } 405 406 if (!info.sni.empty()) { 407 scoped_ptr<char[]> sni_tmp(new char[info.sni.length() + 1]); 408 memcpy(sni_tmp.get(), info.sni.data(), info.sni.length()); 409 sni_tmp[info.sni.length()] = 0; 410 params->sni = CryptoUtils::NormalizeHostname(sni_tmp.get()); 411 } 412 413 string hkdf_suffix; 414 const QuicData& client_hello_serialized = client_hello.GetSerialized(); 415 hkdf_suffix.reserve(sizeof(guid) + client_hello_serialized.length() + 416 requested_config->serialized.size()); 417 hkdf_suffix.append(reinterpret_cast<char*>(&guid), sizeof(guid)); 418 hkdf_suffix.append(client_hello_serialized.data(), 419 client_hello_serialized.length()); 420 hkdf_suffix.append(requested_config->serialized); 421 422 StringPiece cetv_ciphertext; 423 if (requested_config->channel_id_enabled && 424 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) { 425 CryptoHandshakeMessage client_hello_copy(client_hello); 426 client_hello_copy.Erase(kCETV); 427 client_hello_copy.Erase(kPAD); 428 429 const QuicData& client_hello_serialized = client_hello_copy.GetSerialized(); 430 string hkdf_input; 431 hkdf_input.append(QuicCryptoConfig::kCETVLabel, 432 strlen(QuicCryptoConfig::kCETVLabel) + 1); 433 hkdf_input.append(reinterpret_cast<char*>(&guid), sizeof(guid)); 434 hkdf_input.append(client_hello_serialized.data(), 435 client_hello_serialized.length()); 436 hkdf_input.append(requested_config->serialized); 437 438 CrypterPair crypters; 439 CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, 440 info.client_nonce, info.server_nonce, hkdf_input, 441 CryptoUtils::SERVER, &crypters); 442 443 scoped_ptr<QuicData> cetv_plaintext(crypters.decrypter->DecryptPacket( 444 0 /* sequence number */, StringPiece() /* associated data */, 445 cetv_ciphertext)); 446 if (!cetv_plaintext.get()) { 447 *error_details = "CETV decryption failure"; 448 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 449 } 450 451 scoped_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage( 452 cetv_plaintext->AsStringPiece())); 453 if (!cetv.get()) { 454 *error_details = "CETV parse error"; 455 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 456 } 457 458 StringPiece key, signature; 459 if (cetv->GetStringPiece(kCIDK, &key) && 460 cetv->GetStringPiece(kCIDS, &signature)) { 461 if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { 462 *error_details = "ChannelID signature failure"; 463 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 464 } 465 466 params->channel_id = key.as_string(); 467 } 468 } 469 470 string hkdf_input; 471 size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; 472 hkdf_input.reserve(label_len + hkdf_suffix.size()); 473 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); 474 hkdf_input.append(hkdf_suffix); 475 476 CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, 477 info.client_nonce, info.server_nonce, hkdf_input, 478 CryptoUtils::SERVER, ¶ms->initial_crypters); 479 480 string forward_secure_public_value; 481 if (ephemeral_key_source_.get()) { 482 params->forward_secure_premaster_secret = 483 ephemeral_key_source_->CalculateForwardSecureKey( 484 key_exchange, rand, clock->ApproximateNow(), public_value, 485 &forward_secure_public_value); 486 } else { 487 scoped_ptr<KeyExchange> forward_secure_key_exchange( 488 key_exchange->NewKeyPair(rand)); 489 forward_secure_public_value = 490 forward_secure_key_exchange->public_value().as_string(); 491 if (!forward_secure_key_exchange->CalculateSharedKey( 492 public_value, ¶ms->forward_secure_premaster_secret)) { 493 *error_details = "Invalid public value"; 494 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 495 } 496 } 497 498 string forward_secure_hkdf_input; 499 label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; 500 forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size()); 501 forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, 502 label_len); 503 forward_secure_hkdf_input.append(hkdf_suffix); 504 505 CryptoUtils::DeriveKeys(params->forward_secure_premaster_secret, params->aead, 506 info.client_nonce, info.server_nonce, 507 forward_secure_hkdf_input, CryptoUtils::SERVER, 508 ¶ms->forward_secure_crypters); 509 510 out->set_tag(kSHLO); 511 out->SetStringPiece(kSourceAddressTokenTag, 512 NewSourceAddressToken(client_ip, rand, info.now)); 513 out->SetStringPiece(kPUBS, forward_secure_public_value); 514 return QUIC_NO_ERROR; 515 } 516 517 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for 518 // Config's based on their primary_time. 519 // static 520 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan( 521 const scoped_refptr<Config>& a, 522 const scoped_refptr<Config>& b) { 523 return a->primary_time.IsBefore(b->primary_time); 524 } 525 526 void QuicCryptoServerConfig::SelectNewPrimaryConfig( 527 const QuicWallTime now) const { 528 vector<scoped_refptr<Config> > configs; 529 configs.reserve(configs_.size()); 530 scoped_refptr<Config> first_config = NULL; 531 532 for (ConfigMap::const_iterator it = configs_.begin(); 533 it != configs_.end(); ++it) { 534 const scoped_refptr<Config> config(it->second); 535 if (!first_config.get()) { 536 first_config = config; 537 } 538 if (config->primary_time.IsZero()) { 539 continue; 540 } 541 configs.push_back(it->second); 542 } 543 544 if (configs.size() == 0) { 545 // Tests don't set |primary_time_|. For that case we promote the first 546 // Config and leave it as primary forever. 547 if (!primary_config_.get() && first_config.get()) { 548 primary_config_ = first_config; 549 primary_config_->is_primary = true; 550 } 551 return; 552 } 553 554 std::sort(configs.begin(), configs.end(), ConfigPrimaryTimeLessThan); 555 556 for (size_t i = 0; i < configs.size(); ++i) { 557 const scoped_refptr<Config> config(configs[i]); 558 559 if (!config->primary_time.IsAfter(now)) { 560 continue; 561 } 562 563 // This is the first config with a primary_time in the future. Thus the 564 // previous Config should be the primary and this one should determine the 565 // next_config_promotion_time_. 566 scoped_refptr<Config> new_primary; 567 if (i == 0) { 568 // There was no previous Config, so this will have to be primary. 569 new_primary = config; 570 571 // We need the primary_time of the next config. 572 if (configs.size() > 1) { 573 next_config_promotion_time_ = configs[1]->primary_time; 574 } else { 575 next_config_promotion_time_ = QuicWallTime::Zero(); 576 } 577 } else { 578 new_primary = configs[i - 1]; 579 next_config_promotion_time_ = config->primary_time; 580 } 581 582 if (primary_config_.get()) { 583 primary_config_->is_primary = false; 584 } 585 primary_config_ = new_primary; 586 new_primary->is_primary = true; 587 588 return; 589 } 590 591 // All config's primary times are in the past. We should make the most recent 592 // primary. 593 scoped_refptr<Config> new_primary = configs[configs.size() - 1]; 594 if (primary_config_.get()) { 595 primary_config_->is_primary = false; 596 } 597 primary_config_ = new_primary; 598 new_primary->is_primary = true; 599 next_config_promotion_time_ = QuicWallTime::Zero(); 600 } 601 602 QuicErrorCode QuicCryptoServerConfig::EvaluateClientHello( 603 const CryptoHandshakeMessage& client_hello, 604 const uint8* orbit, 605 ClientHelloInfo* info, 606 string* error_details) const { 607 if (client_hello.size() < kClientHelloMinimumSize) { 608 *error_details = "Client hello too small"; 609 return QUIC_CRYPTO_INVALID_VALUE_LENGTH; 610 } 611 612 StringPiece srct; 613 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && 614 ValidateSourceAddressToken(srct, info->client_ip, info->now)) { 615 info->valid_source_address_token = true; 616 } 617 618 if (client_hello.GetStringPiece(kSNI, &info->sni) && 619 !CryptoUtils::IsValidSNI(info->sni)) { 620 *error_details = "Invalid SNI name"; 621 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 622 } 623 624 // The client nonce is used first to try and establish uniqueness. 625 bool unique_by_strike_register = false; 626 627 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && 628 info->client_nonce.size() == kNonceSize) { 629 info->client_nonce_well_formed = true; 630 if (replay_protection_) { 631 base::AutoLock auto_lock(strike_register_lock_); 632 633 if (strike_register_.get() == NULL) { 634 strike_register_.reset(new StrikeRegister( 635 strike_register_max_entries_, 636 static_cast<uint32>(info->now.ToUNIXSeconds()), 637 strike_register_window_secs_, 638 orbit, 639 StrikeRegister::DENY_REQUESTS_AT_STARTUP)); 640 } 641 642 unique_by_strike_register = strike_register_->Insert( 643 reinterpret_cast<const uint8*>(info->client_nonce.data()), 644 static_cast<uint32>(info->now.ToUNIXSeconds())); 645 } 646 } 647 648 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); 649 650 // If the client nonce didn't establish uniqueness then an echoed server 651 // nonce may. 652 bool unique_by_server_nonce = false; 653 if (replay_protection_ && 654 !unique_by_strike_register && 655 !info->server_nonce.empty()) { 656 unique_by_server_nonce = ValidateServerNonce(info->server_nonce, info->now); 657 } 658 659 info->unique = !replay_protection_ || 660 unique_by_strike_register || 661 unique_by_server_nonce; 662 663 return QUIC_NO_ERROR; 664 } 665 666 void QuicCryptoServerConfig::BuildRejection( 667 QuicVersion version, 668 const scoped_refptr<Config>& config, 669 const CryptoHandshakeMessage& client_hello, 670 const ClientHelloInfo& info, 671 QuicRandom* rand, 672 CryptoHandshakeMessage* out) const { 673 out->set_tag(kREJ); 674 out->SetStringPiece(kSCFG, config->serialized); 675 out->SetStringPiece(kSourceAddressTokenTag, 676 NewSourceAddressToken(info.client_ip, rand, info.now)); 677 if (replay_protection_) { 678 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); 679 } 680 681 // The client may have requested a certificate chain. 682 const QuicTag* their_proof_demands; 683 size_t num_their_proof_demands; 684 685 if (proof_source_.get() == NULL || 686 client_hello.GetTaglist(kPDMD, &their_proof_demands, 687 &num_their_proof_demands) != 688 QUIC_NO_ERROR) { 689 return; 690 } 691 692 bool x509_supported = false, x509_ecdsa_supported = false; 693 for (size_t i = 0; i < num_their_proof_demands; i++) { 694 switch (their_proof_demands[i]) { 695 case kX509: 696 x509_supported = true; 697 x509_ecdsa_supported = true; 698 break; 699 case kX59R: 700 x509_supported = true; 701 break; 702 } 703 } 704 705 if (!x509_supported) { 706 return; 707 } 708 709 const vector<string>* certs; 710 string signature; 711 if (!proof_source_->GetProof(version, info.sni.as_string(), 712 config->serialized, x509_ecdsa_supported, 713 &certs, &signature)) { 714 return; 715 } 716 717 StringPiece their_common_set_hashes; 718 StringPiece their_cached_cert_hashes; 719 client_hello.GetStringPiece(kCCS, &their_common_set_hashes); 720 client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes); 721 722 const string compressed = CertCompressor::CompressChain( 723 *certs, their_common_set_hashes, their_cached_cert_hashes, 724 config->common_cert_sets); 725 726 // kREJOverheadBytes is a very rough estimate of how much of a REJ 727 // message is taken up by things other than the certificates. 728 const size_t kREJOverheadBytes = 112; 729 // max_unverified_size is the number of bytes that the certificate chain 730 // and signature can consume before we will demand a valid source-address 731 // token. 732 const size_t max_unverified_size = client_hello.size() - kREJOverheadBytes; 733 COMPILE_ASSERT(kClientHelloMinimumSize >= kREJOverheadBytes, 734 overhead_calculation_may_underflow); 735 if (info.valid_source_address_token || 736 signature.size() + compressed.size() < max_unverified_size) { 737 out->SetStringPiece(kCertificateTag, compressed); 738 out->SetStringPiece(kPROF, signature); 739 } 740 } 741 742 scoped_refptr<QuicCryptoServerConfig::Config> 743 QuicCryptoServerConfig::ParseConfigProtobuf( 744 QuicServerConfigProtobuf* protobuf) { 745 scoped_ptr<CryptoHandshakeMessage> msg( 746 CryptoFramer::ParseMessage(protobuf->config())); 747 748 if (msg->tag() != kSCFG) { 749 LOG(WARNING) << "Server config message has tag " << msg->tag() 750 << " expected " << kSCFG; 751 return NULL; 752 } 753 754 scoped_refptr<Config> config(new Config); 755 config->serialized = protobuf->config(); 756 757 if (protobuf->has_primary_time()) { 758 config->primary_time = 759 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); 760 } 761 762 StringPiece scid; 763 if (!msg->GetStringPiece(kSCID, &scid)) { 764 LOG(WARNING) << "Server config message is missing SCID"; 765 return NULL; 766 } 767 config->id = scid.as_string(); 768 769 const QuicTag* aead_tags; 770 size_t aead_len; 771 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { 772 LOG(WARNING) << "Server config message is missing AEAD"; 773 return NULL; 774 } 775 config->aead = vector<QuicTag>(aead_tags, aead_tags + aead_len); 776 777 const QuicTag* kexs_tags; 778 size_t kexs_len; 779 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { 780 LOG(WARNING) << "Server config message is missing KEXS"; 781 return NULL; 782 } 783 784 StringPiece orbit; 785 if (!msg->GetStringPiece(kORBT, &orbit)) { 786 LOG(WARNING) << "Server config message is missing OBIT"; 787 return NULL; 788 } 789 790 if (orbit.size() != kOrbitSize) { 791 LOG(WARNING) << "Orbit value in server config is the wrong length." 792 " Got " << orbit.size() << " want " << kOrbitSize; 793 return NULL; 794 } 795 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); 796 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); 797 798 { 799 base::AutoLock locked(strike_register_lock_); 800 if (strike_register_.get()) { 801 const uint8* orbit = strike_register_->orbit(); 802 if (0 != memcmp(orbit, config->orbit, kOrbitSize)) { 803 LOG(WARNING) 804 << "Server config has different orbit than current config. " 805 "Switching orbits at run-time is not supported."; 806 return NULL; 807 } 808 } 809 } 810 811 if (kexs_len != protobuf->key_size()) { 812 LOG(WARNING) << "Server config has " << kexs_len 813 << " key exchange methods configured, but " 814 << protobuf->key_size() << " private keys"; 815 return NULL; 816 } 817 818 const QuicTag* proof_demand_tags; 819 size_t num_proof_demand_tags; 820 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == 821 QUIC_NO_ERROR) { 822 for (size_t i = 0; i < num_proof_demand_tags; i++) { 823 if (proof_demand_tags[i] == kCHID) { 824 config->channel_id_enabled = true; 825 break; 826 } 827 } 828 } 829 830 for (size_t i = 0; i < kexs_len; i++) { 831 const QuicTag tag = kexs_tags[i]; 832 string private_key; 833 834 config->kexs.push_back(tag); 835 836 for (size_t j = 0; j < protobuf->key_size(); j++) { 837 const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i); 838 if (key.tag() == tag) { 839 private_key = key.private_key(); 840 break; 841 } 842 } 843 844 if (private_key.empty()) { 845 LOG(WARNING) << "Server config contains key exchange method without " 846 "corresponding private key: " << tag; 847 return NULL; 848 } 849 850 scoped_ptr<KeyExchange> ka; 851 switch (tag) { 852 case kC255: 853 ka.reset(Curve25519KeyExchange::New(private_key)); 854 if (!ka.get()) { 855 LOG(WARNING) << "Server config contained an invalid curve25519" 856 " private key."; 857 return NULL; 858 } 859 break; 860 case kP256: 861 ka.reset(P256KeyExchange::New(private_key)); 862 if (!ka.get()) { 863 LOG(WARNING) << "Server config contained an invalid P-256" 864 " private key."; 865 return NULL; 866 } 867 break; 868 default: 869 LOG(WARNING) << "Server config message contains unknown key exchange " 870 "method: " << tag; 871 return NULL; 872 } 873 874 for (vector<KeyExchange*>::const_iterator i = config->key_exchanges.begin(); 875 i != config->key_exchanges.end(); ++i) { 876 if ((*i)->tag() == tag) { 877 LOG(WARNING) << "Duplicate key exchange in config: " << tag; 878 return NULL; 879 } 880 } 881 882 config->key_exchanges.push_back(ka.release()); 883 } 884 885 if (msg->GetUint16(kVERS, &config->version) != QUIC_NO_ERROR) { 886 LOG(WARNING) << "Server config message is missing version"; 887 return NULL; 888 } 889 890 if (config->version != QuicCryptoConfig::CONFIG_VERSION) { 891 LOG(WARNING) << "Server config specifies an unsupported version"; 892 return NULL; 893 } 894 895 return config; 896 } 897 898 void QuicCryptoServerConfig::SetProofSource(ProofSource* proof_source) { 899 proof_source_.reset(proof_source); 900 } 901 902 void QuicCryptoServerConfig::SetEphemeralKeySource( 903 EphemeralKeySource* ephemeral_key_source) { 904 ephemeral_key_source_.reset(ephemeral_key_source); 905 } 906 907 void QuicCryptoServerConfig::set_replay_protection(bool on) { 908 replay_protection_ = on; 909 } 910 911 void QuicCryptoServerConfig::set_strike_register_max_entries( 912 uint32 max_entries) { 913 base::AutoLock locker(strike_register_lock_); 914 DCHECK(!strike_register_.get()); 915 strike_register_max_entries_ = max_entries; 916 } 917 918 void QuicCryptoServerConfig::set_strike_register_window_secs( 919 uint32 window_secs) { 920 base::AutoLock locker(strike_register_lock_); 921 DCHECK(!strike_register_.get()); 922 strike_register_window_secs_ = window_secs; 923 } 924 925 void QuicCryptoServerConfig::set_source_address_token_future_secs( 926 uint32 future_secs) { 927 source_address_token_future_secs_ = future_secs; 928 } 929 930 void QuicCryptoServerConfig::set_source_address_token_lifetime_secs( 931 uint32 lifetime_secs) { 932 source_address_token_lifetime_secs_ = lifetime_secs; 933 } 934 935 void QuicCryptoServerConfig::set_server_nonce_strike_register_max_entries( 936 uint32 max_entries) { 937 DCHECK(!server_nonce_strike_register_.get()); 938 server_nonce_strike_register_max_entries_ = max_entries; 939 } 940 941 void QuicCryptoServerConfig::set_server_nonce_strike_register_window_secs( 942 uint32 window_secs) { 943 DCHECK(!server_nonce_strike_register_.get()); 944 server_nonce_strike_register_window_secs_ = window_secs; 945 } 946 947 string QuicCryptoServerConfig::NewSourceAddressToken( 948 const IPEndPoint& ip, 949 QuicRandom* rand, 950 QuicWallTime now) const { 951 SourceAddressToken source_address_token; 952 source_address_token.set_ip(ip.ToString()); 953 source_address_token.set_timestamp(now.ToUNIXSeconds()); 954 955 return source_address_token_boxer_.Box( 956 rand, source_address_token.SerializeAsString()); 957 } 958 959 bool QuicCryptoServerConfig::ValidateSourceAddressToken( 960 StringPiece token, 961 const IPEndPoint& ip, 962 QuicWallTime now) const { 963 string storage; 964 StringPiece plaintext; 965 if (!source_address_token_boxer_.Unbox(token, &storage, &plaintext)) { 966 return false; 967 } 968 969 SourceAddressToken source_address_token; 970 if (!source_address_token.ParseFromArray(plaintext.data(), 971 plaintext.size())) { 972 return false; 973 } 974 975 if (source_address_token.ip() != ip.ToString()) { 976 // It's for a different IP address. 977 return false; 978 } 979 980 const QuicWallTime timestamp( 981 QuicWallTime::FromUNIXSeconds(source_address_token.timestamp())); 982 const QuicTime::Delta delta(now.AbsoluteDifference(timestamp)); 983 984 if (now.IsBefore(timestamp) && 985 delta.ToSeconds() > source_address_token_future_secs_) { 986 return false; 987 } 988 989 if (now.IsAfter(timestamp) && 990 delta.ToSeconds() > source_address_token_lifetime_secs_) { 991 return false; 992 } 993 994 return true; 995 } 996 997 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server 998 // nonce. 999 static const size_t kServerNoncePlaintextSize = 1000 4 /* timestamp */ + 20 /* random bytes */; 1001 1002 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand, 1003 QuicWallTime now) const { 1004 const uint32 timestamp = static_cast<uint32>(now.ToUNIXSeconds()); 1005 1006 uint8 server_nonce[kServerNoncePlaintextSize]; 1007 COMPILE_ASSERT(sizeof(server_nonce) > sizeof(timestamp), nonce_too_small); 1008 server_nonce[0] = static_cast<uint8>(timestamp >> 24); 1009 server_nonce[1] = static_cast<uint8>(timestamp >> 16); 1010 server_nonce[2] = static_cast<uint8>(timestamp >> 8); 1011 server_nonce[3] = static_cast<uint8>(timestamp); 1012 rand->RandBytes(&server_nonce[sizeof(timestamp)], 1013 sizeof(server_nonce) - sizeof(timestamp)); 1014 1015 return server_nonce_boxer_.Box( 1016 rand, 1017 StringPiece(reinterpret_cast<char*>(server_nonce), sizeof(server_nonce))); 1018 } 1019 1020 bool QuicCryptoServerConfig::ValidateServerNonce(StringPiece token, 1021 QuicWallTime now) const { 1022 string storage; 1023 StringPiece plaintext; 1024 if (!server_nonce_boxer_.Unbox(token, &storage, &plaintext)) { 1025 return false; 1026 } 1027 1028 // plaintext contains: 1029 // uint32 timestamp 1030 // uint8[20] random bytes 1031 1032 if (plaintext.size() != kServerNoncePlaintextSize) { 1033 // This should never happen because the value decrypted correctly. 1034 LOG(DFATAL) << "Seemingly valid server nonce had incorrect length."; 1035 return false; 1036 } 1037 1038 uint8 server_nonce[32]; 1039 memcpy(server_nonce, plaintext.data(), 4); 1040 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); 1041 memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, 1042 20); 1043 COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), 1044 bad_nonce_buffer_length); 1045 1046 bool is_unique; 1047 { 1048 base::AutoLock auto_lock(server_nonce_strike_register_lock_); 1049 if (server_nonce_strike_register_.get() == NULL) { 1050 server_nonce_strike_register_.reset(new StrikeRegister( 1051 server_nonce_strike_register_max_entries_, 1052 static_cast<uint32>(now.ToUNIXSeconds()), 1053 server_nonce_strike_register_window_secs_, server_nonce_orbit_, 1054 StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); 1055 } 1056 is_unique = server_nonce_strike_register_->Insert( 1057 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); 1058 } 1059 1060 return is_unique; 1061 } 1062 1063 QuicCryptoServerConfig::Config::Config() 1064 : channel_id_enabled(false), 1065 is_primary(false), 1066 primary_time(QuicWallTime::Zero()) {} 1067 1068 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } 1069 1070 } // namespace net 1071