- add sources.
[platform/framework/web/crosswalk.git] / src / net / quic / crypto / quic_crypto_server_config.h
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 #ifndef NET_QUIC_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
6 #define NET_QUIC_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
7
8 #include <map>
9 #include <string>
10 #include <vector>
11
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/strings/string_piece.h"
15 #include "base/synchronization/lock.h"
16 #include "net/base/ip_endpoint.h"
17 #include "net/base/net_export.h"
18 #include "net/quic/crypto/crypto_handshake.h"
19 #include "net/quic/crypto/crypto_protocol.h"
20 #include "net/quic/crypto/crypto_secret_boxer.h"
21 #include "net/quic/quic_time.h"
22
23 namespace net {
24
25 class EphemeralKeySource;
26 class KeyExchange;
27 class ProofSource;
28 class QuicClock;
29 class QuicDecrypter;
30 class QuicEncrypter;
31 class QuicRandom;
32 class QuicServerConfigProtobuf;
33 class StrikeRegister;
34
35 struct ClientHelloInfo;
36
37 namespace test {
38 class QuicCryptoServerConfigPeer;
39 }  // namespace test
40
41 // QuicCryptoServerConfig contains the crypto configuration of a QUIC server.
42 // Unlike a client, a QUIC server can have multiple configurations active in
43 // order to support clients resuming with a previous configuration.
44 // TODO(agl): when adding configurations at runtime is added, this object will
45 // need to consider locking.
46 class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
47  public:
48   // ConfigOptions contains options for generating server configs.
49   struct NET_EXPORT_PRIVATE ConfigOptions {
50     ConfigOptions();
51
52     // expiry_time is the time, in UNIX seconds, when the server config will
53     // expire. If unset, it defaults to the current time plus six months.
54     QuicWallTime expiry_time;
55     // channel_id_enabled controls whether the server config will indicate
56     // support for ChannelIDs.
57     bool channel_id_enabled;
58     // id contains the server config id for the resulting config. If empty, a
59     // random id is generated.
60     std::string id;
61     // orbit contains the kOrbitSize bytes of the orbit value for the server
62     // config. If |orbit| is empty then a random orbit is generated.
63     std::string orbit;
64     // p256 determines whether a P-256 public key will be included in the
65     // server config. Note that this breaks deterministic server-config
66     // generation since P-256 key generation doesn't use the QuicRandom given
67     // to DefaultConfig().
68     bool p256;
69   };
70
71   // |source_address_token_secret|: secret key material used for encrypting and
72   //     decrypting source address tokens. It can be of any length as it is fed
73   //     into a KDF before use. In tests, use TESTING.
74   // |server_nonce_entropy|: an entropy source used to generate the orbit and
75   //     key for server nonces, which are always local to a given instance of a
76   //     server.
77   QuicCryptoServerConfig(base::StringPiece source_address_token_secret,
78                          QuicRandom* server_nonce_entropy);
79   ~QuicCryptoServerConfig();
80
81   // TESTING is a magic parameter for passing to the constructor in tests.
82   static const char TESTING[];
83
84   // DefaultConfig generates a QuicServerConfigProtobuf protobuf suitable for
85   // using in tests.
86   static QuicServerConfigProtobuf* DefaultConfig(
87       QuicRandom* rand,
88       const QuicClock* clock,
89       const ConfigOptions& options);
90
91   // AddConfig adds a QuicServerConfigProtobuf to the availible configurations.
92   // It returns the SCFG message from the config if successful. The caller
93   // takes ownership of the CryptoHandshakeMessage. |now| is used in
94   // conjunction with |protobuf->primary_time()| to determine whether the
95   // config should be made primary.
96   CryptoHandshakeMessage* AddConfig(QuicServerConfigProtobuf* protobuf,
97                                     QuicWallTime now);
98
99   // AddDefaultConfig calls DefaultConfig to create a config and then calls
100   // AddConfig to add it. See the comment for |DefaultConfig| for details of
101   // the arguments.
102   CryptoHandshakeMessage* AddDefaultConfig(
103       QuicRandom* rand,
104       const QuicClock* clock,
105       const ConfigOptions& options);
106
107   // SetConfigs takes a vector of config protobufs and the current time.
108   // Configs are assumed to be uniquely identified by their server config ID.
109   // Previously unknown configs are added and possibly made the primary config
110   // depending on their |primary_time| and the value of |now|. Configs that are
111   // known, but are missing from the protobufs are deleted, unless they are
112   // currently the primary config. SetConfigs returns false if any errors were
113   // encountered and no changes to the QuicCryptoServerConfig will occur.
114   bool SetConfigs(const std::vector<QuicServerConfigProtobuf*>& protobufs,
115                   QuicWallTime now);
116
117   // ProcessClientHello processes |client_hello| and decides whether to accept
118   // or reject the connection. If the connection is to be accepted, |out| is
119   // set to the contents of the ServerHello, |out_params| is completed and
120   // QUIC_NO_ERROR is returned. Otherwise |out| is set to be a REJ message and
121   // an error code is returned.
122   //
123   // client_hello: the incoming client hello message.
124   // guid: the GUID for the connection, which is used in key derivation.
125   // client_ip: the IP address of the client, which is used to generate and
126   //     validate source-address tokens.
127   // clock: used to validate client nonces and ephemeral keys.
128   // rand: an entropy source
129   // params: the state of the handshake. This may be updated with a server
130   //     nonce when we send a rejection. After a successful handshake, this will
131   //     contain the state of the connection.
132   // out: the resulting handshake message (either REJ or SHLO)
133   // error_details: used to store a string describing any error.
134   QuicErrorCode ProcessClientHello(const CryptoHandshakeMessage& client_hello,
135                                    QuicGuid guid,
136                                    const IPEndPoint& client_ip,
137                                    const QuicClock* clock,
138                                    QuicRandom* rand,
139                                    QuicCryptoNegotiatedParameters* params,
140                                    CryptoHandshakeMessage* out,
141                                    std::string* error_details) const;
142
143   // SetProofSource installs |proof_source| as the ProofSource for handshakes.
144   // This object takes ownership of |proof_source|.
145   void SetProofSource(ProofSource* proof_source);
146
147   // SetEphemeralKeySource installs an object that can cache ephemeral keys for
148   // a short period of time. This object takes ownership of
149   // |ephemeral_key_source|. If not set then ephemeral keys will be generated
150   // per-connection.
151   void SetEphemeralKeySource(EphemeralKeySource* ephemeral_key_source);
152
153   // set_replay_protection controls whether replay protection is enabled. If
154   // replay protection is disabled then no strike registers are needed and
155   // frontends can share an orbit value without a shared strike-register.
156   // However, an attacker can duplicate a handshake and cause a client's
157   // request to be processed twice.
158   void set_replay_protection(bool on);
159
160   // set_strike_register_no_startup_period configures the strike register to
161   // not have a startup period.
162   void set_strike_register_no_startup_period();
163
164   // set_strike_register_max_entries sets the maximum number of entries that
165   // the internal strike register will hold. If the strike register fills up
166   // then the oldest entries (by the client's clock) will be dropped.
167   void set_strike_register_max_entries(uint32 max_entries);
168
169   // set_strike_register_window_secs sets the number of seconds around the
170   // current time that the strike register will attempt to be authoritative
171   // for. Setting a larger value allows for greater client clock-skew, but
172   // means that the quiescent startup period must be longer.
173   void set_strike_register_window_secs(uint32 window_secs);
174
175   // set_source_address_token_future_secs sets the number of seconds into the
176   // future that source-address tokens will be accepted from. Since
177   // source-address tokens are authenticated, this should only happen if
178   // another, valid server has clock-skew.
179   void set_source_address_token_future_secs(uint32 future_secs);
180
181   // set_source_address_token_lifetime_secs sets the number of seconds that a
182   // source-address token will be valid for.
183   void set_source_address_token_lifetime_secs(uint32 lifetime_secs);
184
185   // set_server_nonce_strike_register_max_entries sets the number of entries in
186   // the server-nonce strike-register. This is used to record that server nonce
187   // values have been used. If the number of entries is too small then clients
188   // which are depending on server nonces may fail to handshake because their
189   // nonce has expired in the amount of time it took to go from the server to
190   // the client and back.
191   void set_server_nonce_strike_register_max_entries(uint32 max_entries);
192
193   // set_server_nonce_strike_register_window_secs sets the number of seconds
194   // around the current time that the server-nonce strike-register will accept
195   // nonces from. Setting a larger value allows for clients to delay follow-up
196   // client hellos for longer and still use server nonces as proofs of
197   // uniqueness.
198   void set_server_nonce_strike_register_window_secs(uint32 window_secs);
199
200  private:
201   friend class test::QuicCryptoServerConfigPeer;
202
203   // Config represents a server config: a collection of preferences and
204   // Diffie-Hellman public values.
205   class NET_EXPORT_PRIVATE Config : public QuicCryptoConfig,
206                                     public base::RefCounted<Config> {
207    public:
208     Config();
209
210     // TODO(rtenneti): since this is a class, we should probably do
211     // getters/setters here.
212     // |serialized| contains the bytes of this server config, suitable for
213     // sending on the wire.
214     std::string serialized;
215     // id contains the SCID of this server config.
216     std::string id;
217     // orbit contains the orbit value for this config: an opaque identifier
218     // used to identify clusters of server frontends.
219     unsigned char orbit[kOrbitSize];
220
221     // key_exchanges contains key exchange objects with the private keys
222     // already loaded. The values correspond, one-to-one, with the tags in
223     // |kexs| from the parent class.
224     std::vector<KeyExchange*> key_exchanges;
225
226     // tag_value_map contains the raw key/value pairs for the config.
227     QuicTagValueMap tag_value_map;
228
229     // channel_id_enabled is true if the config in |serialized| specifies that
230     // ChannelIDs are supported.
231     bool channel_id_enabled;
232
233     // is_primary is true if this config is the one that we'll give out to
234     // clients as the current one.
235     bool is_primary;
236
237     // primary_time contains the timestamp when this config should become the
238     // primary config. A value of QuicWallTime::Zero() means that this config
239     // will not be promoted at a specific time.
240     QuicWallTime primary_time;
241
242    private:
243     friend class base::RefCounted<Config>;
244     virtual ~Config();
245
246     DISALLOW_COPY_AND_ASSIGN(Config);
247   };
248
249   typedef std::map<ServerConfigID, scoped_refptr<Config> > ConfigMap;
250
251   // ConfigPrimaryTimeLessThan returns true if a->primary_time <
252   // b->primary_time.
253   static bool ConfigPrimaryTimeLessThan(const scoped_refptr<Config>& a,
254                                         const scoped_refptr<Config>& b);
255
256   // SelectNewPrimaryConfig reevaluates the primary config based on the
257   // "primary_time" deadlines contained in each.
258   void SelectNewPrimaryConfig(QuicWallTime now) const;
259
260   // EvaluateClientHello checks |client_hello| for gross errors and determines
261   // whether it can be shown to be fresh (i.e. not a replay). The results are
262   // written to |info|.
263   QuicErrorCode EvaluateClientHello(
264       const CryptoHandshakeMessage& client_hello,
265       const uint8* orbit,
266       ClientHelloInfo* info,
267       std::string* error_details) const;
268
269   // BuildRejection sets |out| to be a REJ message in reply to |client_hello|.
270   void BuildRejection(
271       const scoped_refptr<Config>& config,
272       const CryptoHandshakeMessage& client_hello,
273       const ClientHelloInfo& info,
274       QuicRandom* rand,
275       CryptoHandshakeMessage* out) const;
276
277   // ParseConfigProtobuf parses the given config protobuf and returns a
278   // scoped_refptr<Config> if successful. The caller adopts the reference to the
279   // Config. On error, ParseConfigProtobuf returns NULL.
280   scoped_refptr<Config> ParseConfigProtobuf(QuicServerConfigProtobuf* protobuf);
281
282   // NewSourceAddressToken returns a fresh source address token for the given
283   // IP address.
284   std::string NewSourceAddressToken(const IPEndPoint& ip,
285                                     QuicRandom* rand,
286                                     QuicWallTime now) const;
287
288   // ValidateSourceAddressToken returns true if the source address token in
289   // |token| is a valid and timely token for the IP address |ip| given that the
290   // current time is |now|.
291   bool ValidateSourceAddressToken(base::StringPiece token,
292                                   const IPEndPoint& ip,
293                                   QuicWallTime now) const;
294
295   // NewServerNonce generates and encrypts a random nonce.
296   std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const;
297
298   // ValidateServerNonce decrypts |token| and verifies that it hasn't been
299   // previously used and is recent enough that it is plausible that it was part
300   // of a very recently provided rejection ("recent" will be on the order of
301   // 10-30 seconds). If so, it records that it has been used and returns true.
302   // Otherwise it returns false.
303   bool ValidateServerNonce(base::StringPiece echoed_server_nonce,
304                            QuicWallTime now) const;
305
306   // replay_protection_ controls whether the server enforces that handshakes
307   // aren't replays.
308   bool replay_protection_;
309
310   // configs_ satisfies the following invariants:
311   //   1) configs_.empty() <-> primary_config_ == NULL
312   //   2) primary_config_ != NULL -> primary_config_->is_primary
313   //   3) ∀ c∈configs_, c->is_primary <-> c == primary_config_
314   mutable base::Lock configs_lock_;
315   // configs_ contains all active server configs. It's expected that there are
316   // about half-a-dozen configs active at any one time.
317   ConfigMap configs_;
318   // primary_config_ points to a Config (which is also in |configs_|) which is
319   // the primary config - i.e. the one that we'll give out to new clients.
320   mutable scoped_refptr<Config> primary_config_;
321   // next_config_promotion_time_ contains the nearest, future time when an
322   // active config will be promoted to primary.
323   mutable QuicWallTime next_config_promotion_time_;
324
325   mutable base::Lock strike_register_lock_;
326   // strike_register_ contains a data structure that keeps track of previously
327   // observed client nonces in order to prevent replay attacks.
328   mutable scoped_ptr<StrikeRegister> strike_register_;
329
330   // source_address_token_boxer_ is used to protect the source-address tokens
331   // that are given to clients.
332   CryptoSecretBoxer source_address_token_boxer_;
333
334   // server_nonce_boxer_ is used to encrypt and validate suggested server
335   // nonces.
336   CryptoSecretBoxer server_nonce_boxer_;
337
338   // server_nonce_orbit_ contains the random, per-server orbit values that this
339   // server will use to generate server nonces (the moral equivalent of a SYN
340   // cookies).
341   uint8 server_nonce_orbit_[8];
342
343   mutable base::Lock server_nonce_strike_register_lock_;
344   // server_nonce_strike_register_ contains a data structure that keeps track of
345   // previously observed server nonces from this server, in order to prevent
346   // replay attacks.
347   mutable scoped_ptr<StrikeRegister> server_nonce_strike_register_;
348
349   // proof_source_ contains an object that can provide certificate chains and
350   // signatures.
351   scoped_ptr<ProofSource> proof_source_;
352
353   // ephemeral_key_source_ contains an object that caches ephemeral keys for a
354   // short period of time.
355   scoped_ptr<EphemeralKeySource> ephemeral_key_source_;
356
357   // These fields store configuration values. See the comments for their
358   // respective setter functions.
359   bool strike_register_no_startup_period_;
360   uint32 strike_register_max_entries_;
361   uint32 strike_register_window_secs_;
362   uint32 source_address_token_future_secs_;
363   uint32 source_address_token_lifetime_secs_;
364   uint32 server_nonce_strike_register_max_entries_;
365   uint32 server_nonce_strike_register_window_secs_;
366 };
367
368 }  // namespace net
369
370 #endif  // NET_QUIC_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_