| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 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 #ifndef NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_ | 5 #ifndef NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_ |
| 6 #define NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_ | 6 #define NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/strings/string_piece.h" | 13 #include "base/strings/string_piece.h" |
| 14 #include "base/synchronization/lock.h" | |
| 15 #include "net/base/ip_endpoint.h" | |
| 16 #include "net/base/net_export.h" | 14 #include "net/base/net_export.h" |
| 17 #include "net/quic/crypto/crypto_protocol.h" | 15 #include "net/quic/crypto/crypto_protocol.h" |
| 18 #include "net/quic/quic_time.h" | 16 #include "net/quic/quic_time.h" |
| 19 | 17 |
| 20 namespace net { | 18 namespace net { |
| 21 | 19 |
| 22 class KeyExchange; | 20 class KeyExchange; |
| 23 class QuicClock; | 21 class QuicClock; |
| 24 class QuicDecrypter; | 22 class QuicDecrypter; |
| 25 class QuicEncrypter; | 23 class QuicEncrypter; |
| 26 class QuicRandom; | 24 class QuicRandom; |
| 27 class QuicServerConfigProtobuf; | |
| 28 class StrikeRegister; | |
| 29 | |
| 30 namespace test { | |
| 31 class QuicCryptoServerConfigPeer; | |
| 32 } // namespace test | |
| 33 | 25 |
| 34 // An intermediate format of a handshake message that's convenient for a | 26 // An intermediate format of a handshake message that's convenient for a |
| 35 // CryptoFramer to serialize from or parse into. | 27 // CryptoFramer to serialize from or parse into. |
| 36 class NET_EXPORT_PRIVATE CryptoHandshakeMessage { | 28 class NET_EXPORT_PRIVATE CryptoHandshakeMessage { |
| 37 public: | 29 public: |
| 38 CryptoHandshakeMessage(); | 30 CryptoHandshakeMessage(); |
| 39 CryptoHandshakeMessage(const CryptoHandshakeMessage& other); | 31 CryptoHandshakeMessage(const CryptoHandshakeMessage& other); |
| 40 ~CryptoHandshakeMessage(); | 32 ~CryptoHandshakeMessage(); |
| 41 | 33 |
| 42 CryptoHandshakeMessage& operator=(const CryptoHandshakeMessage& other); | 34 CryptoHandshakeMessage& operator=(const CryptoHandshakeMessage& other); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 std::string DebugStringInternal(size_t indent) const; | 111 std::string DebugStringInternal(size_t indent) const; |
| 120 | 112 |
| 121 CryptoTag tag_; | 113 CryptoTag tag_; |
| 122 CryptoTagValueMap tag_value_map_; | 114 CryptoTagValueMap tag_value_map_; |
| 123 | 115 |
| 124 // The serialized form of the handshake message. This member is constructed | 116 // The serialized form of the handshake message. This member is constructed |
| 125 // lasily. | 117 // lasily. |
| 126 mutable scoped_ptr<QuicData> serialized_; | 118 mutable scoped_ptr<QuicData> serialized_; |
| 127 }; | 119 }; |
| 128 | 120 |
| 129 // TODO(rch): sync with server more rationally | |
| 130 class NET_EXPORT_PRIVATE QuicServerConfigProtobuf { | |
| 131 public: | |
| 132 class NET_EXPORT_PRIVATE PrivateKey { | |
| 133 public: | |
| 134 CryptoTag tag() const { | |
| 135 return tag_; | |
| 136 } | |
| 137 void set_tag(CryptoTag tag) { | |
| 138 tag_ = tag; | |
| 139 } | |
| 140 std::string private_key() const { | |
| 141 return private_key_; | |
| 142 } | |
| 143 void set_private_key(std::string key) { | |
| 144 private_key_ = key; | |
| 145 } | |
| 146 | |
| 147 private: | |
| 148 CryptoTag tag_; | |
| 149 std::string private_key_; | |
| 150 }; | |
| 151 | |
| 152 QuicServerConfigProtobuf(); | |
| 153 ~QuicServerConfigProtobuf(); | |
| 154 | |
| 155 size_t key_size() const { | |
| 156 return keys_.size(); | |
| 157 } | |
| 158 | |
| 159 const PrivateKey& key(size_t i) const { | |
| 160 DCHECK_GT(keys_.size(), i); | |
| 161 return *keys_[i]; | |
| 162 } | |
| 163 | |
| 164 std::string config() const { | |
| 165 return config_; | |
| 166 } | |
| 167 | |
| 168 void set_config(base::StringPiece config) { | |
| 169 config_ = config.as_string(); | |
| 170 } | |
| 171 | |
| 172 QuicServerConfigProtobuf::PrivateKey* add_key() { | |
| 173 keys_.push_back(new PrivateKey); | |
| 174 return keys_.back(); | |
| 175 } | |
| 176 | |
| 177 private: | |
| 178 std::vector<PrivateKey*> keys_; | |
| 179 std::string config_; | |
| 180 }; | |
| 181 | |
| 182 // TODO(rtenneti): sync with server more rationally. | |
| 183 class NET_EXPORT_PRIVATE SourceAddressToken { | |
| 184 public: | |
| 185 SourceAddressToken(); | |
| 186 ~SourceAddressToken(); | |
| 187 | |
| 188 std::string SerializeAsString() const; | |
| 189 | |
| 190 bool ParseFromArray(unsigned char* plaintext, size_t plaintext_length); | |
| 191 | |
| 192 std::string ip() const { | |
| 193 return ip_; | |
| 194 } | |
| 195 | |
| 196 int64 timestamp() const { | |
| 197 return timestamp_; | |
| 198 } | |
| 199 | |
| 200 void set_ip(base::StringPiece ip) { | |
| 201 ip_ = ip.as_string(); | |
| 202 } | |
| 203 | |
| 204 void set_timestamp(int64 timestamp) { | |
| 205 timestamp_ = timestamp; | |
| 206 } | |
| 207 | |
| 208 private: | |
| 209 std::string ip_; | |
| 210 int64 timestamp_; | |
| 211 }; | |
| 212 | |
| 213 // Parameters negotiated by the crypto handshake. | 121 // Parameters negotiated by the crypto handshake. |
| 214 struct NET_EXPORT_PRIVATE QuicCryptoNegotiatedParameters { | 122 struct NET_EXPORT_PRIVATE QuicCryptoNegotiatedParameters { |
| 215 // Initializes the members to 0 or empty values. | 123 // Initializes the members to 0 or empty values. |
| 216 QuicCryptoNegotiatedParameters(); | 124 QuicCryptoNegotiatedParameters(); |
| 217 ~QuicCryptoNegotiatedParameters(); | 125 ~QuicCryptoNegotiatedParameters(); |
| 218 | 126 |
| 219 uint16 version; | 127 uint16 version; |
| 220 CryptoTag key_exchange; | 128 CryptoTag key_exchange; |
| 221 CryptoTag aead; | 129 CryptoTag aead; |
| 222 std::string premaster_secret; | 130 std::string premaster_secret; |
| 223 scoped_ptr<QuicEncrypter> encrypter; | 131 scoped_ptr<QuicEncrypter> encrypter; |
| 224 scoped_ptr<QuicDecrypter> decrypter; | 132 scoped_ptr<QuicDecrypter> decrypter; |
| 225 std::string server_config_id; | 133 std::string server_config_id; |
| 226 std::string server_nonce; | 134 std::string server_nonce; |
| 227 }; | 135 }; |
| 228 | 136 |
| 229 // QuicCryptoConfig contains common configuration between clients and servers. | 137 // QuicCryptoConfig contains common configuration between clients and servers. |
| 230 class NET_EXPORT_PRIVATE QuicCryptoConfig { | 138 class NET_EXPORT_PRIVATE QuicCryptoConfig { |
| 231 public: | 139 public: |
| 140 enum { |
| 141 // CONFIG_VERSION is the one (and, for the moment, only) version number that |
| 142 // we implement. |
| 143 CONFIG_VERSION = 0, |
| 144 }; |
| 145 |
| 146 // kLabel is constant that is used in key derivation to tie the resulting key |
| 147 // to this protocol. |
| 148 static const char kLabel[]; |
| 149 |
| 232 QuicCryptoConfig(); | 150 QuicCryptoConfig(); |
| 233 ~QuicCryptoConfig(); | 151 ~QuicCryptoConfig(); |
| 234 | 152 |
| 235 // Protocol version | 153 // Protocol version |
| 236 uint16 version; | 154 uint16 version; |
| 237 // Key exchange methods. The following two members' values correspond by | 155 // Key exchange methods. The following two members' values correspond by |
| 238 // index. | 156 // index. |
| 239 CryptoTagVector kexs; | 157 CryptoTagVector kexs; |
| 240 // Authenticated encryption with associated data (AEAD) algorithms. | 158 // Authenticated encryption with associated data (AEAD) algorithms. |
| 241 CryptoTagVector aead; | 159 CryptoTagVector aead; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 const std::string& nonce, | 255 const std::string& nonce, |
| 338 QuicCryptoNegotiatedParameters* out_params, | 256 QuicCryptoNegotiatedParameters* out_params, |
| 339 std::string* error_details); | 257 std::string* error_details); |
| 340 | 258 |
| 341 private: | 259 private: |
| 342 // cached_states_ maps from the server hostname to the cached information | 260 // cached_states_ maps from the server hostname to the cached information |
| 343 // about that server. | 261 // about that server. |
| 344 std::map<std::string, CachedState*> cached_states_; | 262 std::map<std::string, CachedState*> cached_states_; |
| 345 }; | 263 }; |
| 346 | 264 |
| 347 // QuicCryptoServerConfig contains the crypto configuration of a QUIC server. | |
| 348 // Unlike a client, a QUIC server can have multiple configurations active in | |
| 349 // order to support clients resuming with a previous configuration. | |
| 350 // TODO(agl): when adding configurations at runtime is added, this object will | |
| 351 // need to consider locking. | |
| 352 class NET_EXPORT_PRIVATE QuicCryptoServerConfig { | |
| 353 public: | |
| 354 // |source_address_token_secret|: secret key material used for encrypting and | |
| 355 // decrypting source address tokens. It can be of any length as it is fed | |
| 356 // into a KDF before use. In tests, use TESTING. | |
| 357 explicit QuicCryptoServerConfig( | |
| 358 base::StringPiece source_address_token_secret); | |
| 359 ~QuicCryptoServerConfig(); | |
| 360 | |
| 361 // TESTING is a magic parameter for passing to the constructor in tests. | |
| 362 static const char TESTING[]; | |
| 363 | |
| 364 // DefaultConfig generates a QuicServerConfigProtobuf protobuf suitable | |
| 365 // for using in tests. |extra_tags| contains additional key/value pairs that | |
| 366 // will be inserted into the config. | |
| 367 static QuicServerConfigProtobuf* DefaultConfig( | |
| 368 QuicRandom* rand, | |
| 369 const QuicClock* clock, | |
| 370 const CryptoHandshakeMessage& extra_tags); | |
| 371 | |
| 372 // AddConfig adds a QuicServerConfigProtobuf to the availible configurations. | |
| 373 // It returns the SCFG message from the config if successful. The caller | |
| 374 // takes ownership of the CryptoHandshakeMessage. | |
| 375 CryptoHandshakeMessage* AddConfig(QuicServerConfigProtobuf* protobuf); | |
| 376 | |
| 377 // AddDefaultConfig creates a config and then calls AddConfig to | |
| 378 // add it. Any tags in |extra_tags| will be copied into the config. | |
| 379 CryptoHandshakeMessage* AddDefaultConfig( | |
| 380 QuicRandom* rand, | |
| 381 const QuicClock* clock, | |
| 382 const CryptoHandshakeMessage& extra_tags); | |
| 383 | |
| 384 // ProcessClientHello processes |client_hello| and decides whether to accept | |
| 385 // or reject the connection. If the connection is to be accepted, |out| is | |
| 386 // set to the contents of the ServerHello, |out_params| is completed and | |
| 387 // QUIC_NO_ERROR is returned. Otherwise |out| is set to be a REJ message and | |
| 388 // an error code is returned. | |
| 389 // | |
| 390 // client_hello: the incoming client hello message. | |
| 391 // guid: the GUID for the connection, which is used in key derivation. | |
| 392 // client_ip: the IP address of the client, which is used to generate and | |
| 393 // validate source-address tokens. | |
| 394 // now_since_epoch: the current time, as a delta since the unix epoch, | |
| 395 // which is used to validate client nonces. | |
| 396 // rand: an entropy source | |
| 397 // params: the state of the handshake. This may be updated with a server | |
| 398 // nonce when we send a rejection. After a successful handshake, this will | |
| 399 // contain the state of the connection. | |
| 400 // out: the resulting handshake message (either REJ or SHLO) | |
| 401 // error_details: used to store a string describing any error. | |
| 402 QuicErrorCode ProcessClientHello(const CryptoHandshakeMessage& client_hello, | |
| 403 QuicGuid guid, | |
| 404 const IPEndPoint& client_ip, | |
| 405 QuicTime::Delta now_since_epoch, | |
| 406 QuicRandom* rand, | |
| 407 QuicCryptoNegotiatedParameters* params, | |
| 408 CryptoHandshakeMessage* out, | |
| 409 std::string* error_details) const; | |
| 410 | |
| 411 private: | |
| 412 friend class test::QuicCryptoServerConfigPeer; | |
| 413 | |
| 414 // Config represents a server config: a collection of preferences and | |
| 415 // Diffie-Hellman public values. | |
| 416 struct Config : public QuicCryptoConfig { | |
| 417 Config(); | |
| 418 ~Config(); | |
| 419 | |
| 420 // serialized contains the bytes of this server config, suitable for sending | |
| 421 // on the wire. | |
| 422 std::string serialized; | |
| 423 // id contains the SCID of this server config. | |
| 424 std::string id; | |
| 425 // orbit contains the orbit value for this config: an opaque identifier | |
| 426 // used to identify clusters of server frontends. | |
| 427 unsigned char orbit[kOrbitSize]; | |
| 428 | |
| 429 // key_exchanges contains key exchange objects with the private keys | |
| 430 // already loaded. The values correspond, one-to-one, with the tags in | |
| 431 // |kexs| from the parent class. | |
| 432 std::vector<KeyExchange*> key_exchanges; | |
| 433 | |
| 434 // tag_value_map contains the raw key/value pairs for the config. | |
| 435 CryptoTagValueMap tag_value_map; | |
| 436 | |
| 437 private: | |
| 438 DISALLOW_COPY_AND_ASSIGN(Config); | |
| 439 }; | |
| 440 | |
| 441 // NewSourceAddressToken returns a fresh source address token for the given | |
| 442 // IP address. | |
| 443 std::string NewSourceAddressToken(const IPEndPoint& ip, | |
| 444 QuicRandom* rand, | |
| 445 QuicTime::Delta now_since_epoch) const; | |
| 446 | |
| 447 // ValidateSourceAddressToken returns true if the source address token in | |
| 448 // |token| is a valid and timely token for the IP address |ip| given that the | |
| 449 // current time is |now|. | |
| 450 bool ValidateSourceAddressToken(base::StringPiece token, | |
| 451 const IPEndPoint& ip, | |
| 452 QuicTime::Delta now_since_epoch) const; | |
| 453 | |
| 454 std::map<ServerConfigID, Config*> configs_; | |
| 455 | |
| 456 ServerConfigID active_config_; | |
| 457 | |
| 458 mutable base::Lock strike_register_lock_; | |
| 459 // strike_register_ contains a data structure that keeps track of previously | |
| 460 // observed client nonces in order to prevent replay attacks. | |
| 461 mutable scoped_ptr<StrikeRegister> strike_register_; | |
| 462 | |
| 463 // These members are used to encrypt and decrypt the source address tokens | |
| 464 // that we receive from and send to clients. | |
| 465 scoped_ptr<QuicEncrypter> source_address_token_encrypter_; | |
| 466 scoped_ptr<QuicDecrypter> source_address_token_decrypter_; | |
| 467 }; | |
| 468 | |
| 469 } // namespace net | 265 } // namespace net |
| 470 | 266 |
| 471 #endif // NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_ | 267 #endif // NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_ |
| OLD | NEW |