| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/core/crypto/quic_crypto_server_config.h" | 5 #include "net/quic/core/crypto/quic_crypto_server_config.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> | 10 #include <memory> |
| 11 | 11 |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
| 14 #include "base/stl_util.h" | |
| 15 #include "crypto/hkdf.h" | 14 #include "crypto/hkdf.h" |
| 16 #include "crypto/secure_hash.h" | 15 #include "crypto/secure_hash.h" |
| 17 #include "net/base/ip_address.h" | 16 #include "net/base/ip_address.h" |
| 18 #include "net/quic/core/crypto/aes_128_gcm_12_decrypter.h" | 17 #include "net/quic/core/crypto/aes_128_gcm_12_decrypter.h" |
| 19 #include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h" | 18 #include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h" |
| 20 #include "net/quic/core/crypto/cert_compressor.h" | 19 #include "net/quic/core/crypto/cert_compressor.h" |
| 21 #include "net/quic/core/crypto/chacha20_poly1305_encrypter.h" | 20 #include "net/quic/core/crypto/chacha20_poly1305_encrypter.h" |
| 22 #include "net/quic/core/crypto/channel_id.h" | 21 #include "net/quic/core/crypto/channel_id.h" |
| 23 #include "net/quic/core/crypto/crypto_framer.h" | 22 #include "net/quic/core/crypto/crypto_framer.h" |
| 24 #include "net/quic/core/crypto/crypto_handshake_message.h" | 23 #include "net/quic/core/crypto/crypto_handshake_message.h" |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 | 249 |
| 251 server_nonce_boxer_.SetKeys( | 250 server_nonce_boxer_.SetKeys( |
| 252 {string(reinterpret_cast<char*>(key_bytes.get()), key_size)}); | 251 {string(reinterpret_cast<char*>(key_bytes.get()), key_size)}); |
| 253 } | 252 } |
| 254 | 253 |
| 255 QuicCryptoServerConfig::~QuicCryptoServerConfig() { | 254 QuicCryptoServerConfig::~QuicCryptoServerConfig() { |
| 256 primary_config_ = nullptr; | 255 primary_config_ = nullptr; |
| 257 } | 256 } |
| 258 | 257 |
| 259 // static | 258 // static |
| 260 QuicServerConfigProtobuf* QuicCryptoServerConfig::GenerateConfig( | 259 std::unique_ptr<QuicServerConfigProtobuf> |
| 261 QuicRandom* rand, | 260 QuicCryptoServerConfig::GenerateConfig(QuicRandom* rand, |
| 262 const QuicClock* clock, | 261 const QuicClock* clock, |
| 263 const ConfigOptions& options) { | 262 const ConfigOptions& options) { |
| 264 CryptoHandshakeMessage msg; | 263 CryptoHandshakeMessage msg; |
| 265 | 264 |
| 266 const string curve25519_private_key = | 265 const string curve25519_private_key = |
| 267 Curve25519KeyExchange::NewPrivateKey(rand); | 266 Curve25519KeyExchange::NewPrivateKey(rand); |
| 268 std::unique_ptr<Curve25519KeyExchange> curve25519( | 267 std::unique_ptr<Curve25519KeyExchange> curve25519( |
| 269 Curve25519KeyExchange::New(curve25519_private_key)); | 268 Curve25519KeyExchange::New(curve25519_private_key)); |
| 270 StringPiece curve25519_public_value = curve25519->public_value(); | 269 StringPiece curve25519_public_value = curve25519->public_value(); |
| 271 | 270 |
| 272 string encoded_public_values; | 271 string encoded_public_values; |
| 273 // First three bytes encode the length of the public value. | 272 // First three bytes encode the length of the public value. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 hash->Update(serialized->data(), serialized->length()); | 343 hash->Update(serialized->data(), serialized->length()); |
| 345 | 344 |
| 346 char scid_bytes[16]; | 345 char scid_bytes[16]; |
| 347 hash->Finish(scid_bytes, sizeof(scid_bytes)); | 346 hash->Finish(scid_bytes, sizeof(scid_bytes)); |
| 348 msg.SetStringPiece(kSCID, StringPiece(scid_bytes, sizeof(scid_bytes))); | 347 msg.SetStringPiece(kSCID, StringPiece(scid_bytes, sizeof(scid_bytes))); |
| 349 } else { | 348 } else { |
| 350 msg.SetStringPiece(kSCID, options.id); | 349 msg.SetStringPiece(kSCID, options.id); |
| 351 } | 350 } |
| 352 // Don't put new tags below this point. The SCID generation should hash over | 351 // Don't put new tags below this point. The SCID generation should hash over |
| 353 // everything but itself and so extra tags should be added prior to the | 352 // everything but itself and so extra tags should be added prior to the |
| 354 // preceeding if block. | 353 // preceding if block. |
| 355 | 354 |
| 356 std::unique_ptr<QuicData> serialized( | 355 std::unique_ptr<QuicData> serialized( |
| 357 CryptoFramer::ConstructHandshakeMessage(msg)); | 356 CryptoFramer::ConstructHandshakeMessage(msg)); |
| 358 | 357 |
| 359 std::unique_ptr<QuicServerConfigProtobuf> config( | 358 std::unique_ptr<QuicServerConfigProtobuf> config( |
| 360 new QuicServerConfigProtobuf); | 359 new QuicServerConfigProtobuf); |
| 361 config->set_config(serialized->AsStringPiece()); | 360 config->set_config(serialized->AsStringPiece()); |
| 362 QuicServerConfigProtobuf::PrivateKey* curve25519_key = config->add_key(); | 361 QuicServerConfigProtobuf::PrivateKey* curve25519_key = config->add_key(); |
| 363 curve25519_key->set_tag(kC255); | 362 curve25519_key->set_tag(kC255); |
| 364 curve25519_key->set_private_key(curve25519_private_key); | 363 curve25519_key->set_private_key(curve25519_private_key); |
| 365 | 364 |
| 366 if (options.p256) { | 365 if (options.p256) { |
| 367 QuicServerConfigProtobuf::PrivateKey* p256_key = config->add_key(); | 366 QuicServerConfigProtobuf::PrivateKey* p256_key = config->add_key(); |
| 368 p256_key->set_tag(kP256); | 367 p256_key->set_tag(kP256); |
| 369 p256_key->set_private_key(p256_private_key); | 368 p256_key->set_private_key(p256_private_key); |
| 370 } | 369 } |
| 371 | 370 |
| 372 return config.release(); | 371 return config; |
| 373 } | 372 } |
| 374 | 373 |
| 375 CryptoHandshakeMessage* QuicCryptoServerConfig::AddConfig( | 374 CryptoHandshakeMessage* QuicCryptoServerConfig::AddConfig( |
| 376 QuicServerConfigProtobuf* protobuf, | 375 std::unique_ptr<QuicServerConfigProtobuf> protobuf, |
| 377 const QuicWallTime now) { | 376 const QuicWallTime now) { |
| 378 std::unique_ptr<CryptoHandshakeMessage> msg( | 377 std::unique_ptr<CryptoHandshakeMessage> msg( |
| 379 CryptoFramer::ParseMessage(protobuf->config())); | 378 CryptoFramer::ParseMessage(protobuf->config())); |
| 380 | 379 |
| 381 if (!msg.get()) { | 380 if (!msg.get()) { |
| 382 LOG(WARNING) << "Failed to parse server config message"; | 381 LOG(WARNING) << "Failed to parse server config message"; |
| 383 return nullptr; | 382 return nullptr; |
| 384 } | 383 } |
| 385 | 384 |
| 386 scoped_refptr<Config> config(ParseConfigProtobuf(protobuf)); | 385 scoped_refptr<Config> config(ParseConfigProtobuf(protobuf)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 404 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); | 403 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
| 405 } | 404 } |
| 406 | 405 |
| 407 return msg.release(); | 406 return msg.release(); |
| 408 } | 407 } |
| 409 | 408 |
| 410 CryptoHandshakeMessage* QuicCryptoServerConfig::AddDefaultConfig( | 409 CryptoHandshakeMessage* QuicCryptoServerConfig::AddDefaultConfig( |
| 411 QuicRandom* rand, | 410 QuicRandom* rand, |
| 412 const QuicClock* clock, | 411 const QuicClock* clock, |
| 413 const ConfigOptions& options) { | 412 const ConfigOptions& options) { |
| 414 std::unique_ptr<QuicServerConfigProtobuf> config( | 413 return AddConfig(GenerateConfig(rand, clock, options), clock->WallNow()); |
| 415 GenerateConfig(rand, clock, options)); | |
| 416 return AddConfig(config.get(), clock->WallNow()); | |
| 417 } | 414 } |
| 418 | 415 |
| 419 bool QuicCryptoServerConfig::SetConfigs( | 416 bool QuicCryptoServerConfig::SetConfigs( |
| 420 const vector<QuicServerConfigProtobuf*>& protobufs, | 417 const vector<std::unique_ptr<QuicServerConfigProtobuf>>& protobufs, |
| 421 const QuicWallTime now) { | 418 const QuicWallTime now) { |
| 422 vector<scoped_refptr<Config>> parsed_configs; | 419 vector<scoped_refptr<Config>> parsed_configs; |
| 423 bool ok = true; | 420 bool ok = true; |
| 424 | 421 |
| 425 for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin(); | 422 for (auto& protobuf : protobufs) { |
| 426 i != protobufs.end(); ++i) { | 423 scoped_refptr<Config> config(ParseConfigProtobuf(protobuf)); |
| 427 scoped_refptr<Config> config(ParseConfigProtobuf(*i)); | |
| 428 if (!config.get()) { | 424 if (!config.get()) { |
| 429 ok = false; | 425 ok = false; |
| 430 break; | 426 break; |
| 431 } | 427 } |
| 432 | 428 |
| 433 parsed_configs.push_back(config); | 429 parsed_configs.push_back(config); |
| 434 } | 430 } |
| 435 | 431 |
| 436 if (parsed_configs.empty()) { | 432 if (parsed_configs.empty()) { |
| 437 LOG(WARNING) << "New config list is empty."; | 433 LOG(WARNING) << "New config list is empty."; |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 } | 882 } |
| 887 } | 883 } |
| 888 | 884 |
| 889 StringPiece public_value; | 885 StringPiece public_value; |
| 890 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { | 886 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { |
| 891 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Missing public value"); | 887 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Missing public value"); |
| 892 return; | 888 return; |
| 893 } | 889 } |
| 894 | 890 |
| 895 const KeyExchange* key_exchange = | 891 const KeyExchange* key_exchange = |
| 896 requested_config->key_exchanges[key_exchange_index]; | 892 requested_config->key_exchanges[key_exchange_index].get(); |
| 897 if (!key_exchange->CalculateSharedKey(public_value, | 893 if (!key_exchange->CalculateSharedKey(public_value, |
| 898 ¶ms->initial_premaster_secret)) { | 894 ¶ms->initial_premaster_secret)) { |
| 899 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Invalid public value"); | 895 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Invalid public value"); |
| 900 return; | 896 return; |
| 901 } | 897 } |
| 902 | 898 |
| 903 if (!info.sni.empty()) { | 899 if (!info.sni.empty()) { |
| 904 std::unique_ptr<char[]> sni_tmp(new char[info.sni.length() + 1]); | 900 std::unique_ptr<char[]> sni_tmp(new char[info.sni.length() + 1]); |
| 905 memcpy(sni_tmp.get(), info.sni.data(), info.sni.length()); | 901 memcpy(sni_tmp.get(), info.sni.data(), info.sni.length()); |
| 906 sni_tmp[info.sni.length()] = 0; | 902 sni_tmp[info.sni.length()] = 0; |
| (...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1753 client_common_set_hashes, common_sets); | 1749 client_common_set_hashes, common_sets); |
| 1754 | 1750 |
| 1755 // Insert the newly compressed cert to cache. | 1751 // Insert the newly compressed cert to cache. |
| 1756 compressed_certs_cache->Insert(chain, client_common_set_hashes, | 1752 compressed_certs_cache->Insert(chain, client_common_set_hashes, |
| 1757 client_cached_cert_hashes, compressed); | 1753 client_cached_cert_hashes, compressed); |
| 1758 return compressed; | 1754 return compressed; |
| 1759 } | 1755 } |
| 1760 | 1756 |
| 1761 scoped_refptr<QuicCryptoServerConfig::Config> | 1757 scoped_refptr<QuicCryptoServerConfig::Config> |
| 1762 QuicCryptoServerConfig::ParseConfigProtobuf( | 1758 QuicCryptoServerConfig::ParseConfigProtobuf( |
| 1763 QuicServerConfigProtobuf* protobuf) { | 1759 const std::unique_ptr<QuicServerConfigProtobuf>& protobuf) { |
| 1764 std::unique_ptr<CryptoHandshakeMessage> msg( | 1760 std::unique_ptr<CryptoHandshakeMessage> msg( |
| 1765 CryptoFramer::ParseMessage(protobuf->config())); | 1761 CryptoFramer::ParseMessage(protobuf->config())); |
| 1766 | 1762 |
| 1767 if (msg->tag() != kSCFG) { | 1763 if (msg->tag() != kSCFG) { |
| 1768 LOG(WARNING) << "Server config message has tag " << msg->tag() | 1764 LOG(WARNING) << "Server config message has tag " << msg->tag() |
| 1769 << " expected " << kSCFG; | 1765 << " expected " << kSCFG; |
| 1770 return nullptr; | 1766 return nullptr; |
| 1771 } | 1767 } |
| 1772 | 1768 |
| 1773 scoped_refptr<Config> config(new Config); | 1769 scoped_refptr<Config> config(new Config); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1904 return nullptr; | 1900 return nullptr; |
| 1905 } | 1901 } |
| 1906 break; | 1902 break; |
| 1907 default: | 1903 default: |
| 1908 LOG(WARNING) << "Server config message contains unknown key exchange " | 1904 LOG(WARNING) << "Server config message contains unknown key exchange " |
| 1909 "method: " | 1905 "method: " |
| 1910 << tag; | 1906 << tag; |
| 1911 return nullptr; | 1907 return nullptr; |
| 1912 } | 1908 } |
| 1913 | 1909 |
| 1914 for (const KeyExchange* key_exchange : config->key_exchanges) { | 1910 for (const auto& key_exchange : config->key_exchanges) { |
| 1915 if (key_exchange->tag() == tag) { | 1911 if (key_exchange->tag() == tag) { |
| 1916 LOG(WARNING) << "Duplicate key exchange in config: " << tag; | 1912 LOG(WARNING) << "Duplicate key exchange in config: " << tag; |
| 1917 return nullptr; | 1913 return nullptr; |
| 1918 } | 1914 } |
| 1919 } | 1915 } |
| 1920 | 1916 |
| 1921 config->key_exchanges.push_back(ka.release()); | 1917 config->key_exchanges.push_back(std::move(ka)); |
| 1922 } | 1918 } |
| 1923 | 1919 |
| 1924 uint64_t expiry_seconds; | 1920 uint64_t expiry_seconds; |
| 1925 if (msg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) { | 1921 if (msg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) { |
| 1926 LOG(WARNING) << "Server config message is missing EXPY"; | 1922 LOG(WARNING) << "Server config message is missing EXPY"; |
| 1927 return nullptr; | 1923 return nullptr; |
| 1928 } | 1924 } |
| 1929 config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds); | 1925 config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds); |
| 1930 | 1926 |
| 1931 return config; | 1927 return config; |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2243 | 2239 |
| 2244 QuicCryptoServerConfig::Config::Config() | 2240 QuicCryptoServerConfig::Config::Config() |
| 2245 : channel_id_enabled(false), | 2241 : channel_id_enabled(false), |
| 2246 is_primary(false), | 2242 is_primary(false), |
| 2247 primary_time(QuicWallTime::Zero()), | 2243 primary_time(QuicWallTime::Zero()), |
| 2248 expiry_time(QuicWallTime::Zero()), | 2244 expiry_time(QuicWallTime::Zero()), |
| 2249 priority(0), | 2245 priority(0), |
| 2250 source_address_token_boxer(nullptr) {} | 2246 source_address_token_boxer(nullptr) {} |
| 2251 | 2247 |
| 2252 QuicCryptoServerConfig::Config::~Config() { | 2248 QuicCryptoServerConfig::Config::~Config() { |
| 2253 base::STLDeleteElements(&key_exchanges); | |
| 2254 } | 2249 } |
| 2255 | 2250 |
| 2256 QuicCryptoProof::QuicCryptoProof() {} | 2251 QuicCryptoProof::QuicCryptoProof() {} |
| 2257 QuicCryptoProof::~QuicCryptoProof() {} | 2252 QuicCryptoProof::~QuicCryptoProof() {} |
| 2258 } // namespace net | 2253 } // namespace net |
| OLD | NEW |