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 |