Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / net / quic / crypto / quic_crypto_server_config.h
blob7c9ed428586796315b9c8120017a5d4cec3f8974
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.
5 #ifndef NET_QUIC_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
6 #define NET_QUIC_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_
8 #include <map>
9 #include <string>
10 #include <vector>
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"
23 namespace net {
25 class CryptoHandshakeMessage;
26 class EphemeralKeySource;
27 class KeyExchange;
28 class ProofSource;
29 class QuicClock;
30 class QuicDecrypter;
31 class QuicEncrypter;
32 class QuicRandom;
33 class QuicServerConfigProtobuf;
34 class StrikeRegister;
35 class StrikeRegisterClient;
37 struct ClientHelloInfo;
39 namespace test {
40 class QuicCryptoServerConfigPeer;
41 } // namespace test
43 // Hook that allows application code to subscribe to primary config changes.
44 class PrimaryConfigChangedCallback {
45 public:
46 PrimaryConfigChangedCallback();
47 virtual ~PrimaryConfigChangedCallback();
48 virtual void Run(const std::string& scid) = 0;
51 // Callback used to accept the result of the |client_hello| validation step.
52 class NET_EXPORT_PRIVATE ValidateClientHelloResultCallback {
53 public:
54 // Opaque token that holds information about the client_hello and
55 // its validity. Can be interpreted by calling ProcessClientHello.
56 struct Result;
58 ValidateClientHelloResultCallback();
59 virtual ~ValidateClientHelloResultCallback();
60 void Run(const Result* result);
62 protected:
63 virtual void RunImpl(const CryptoHandshakeMessage& client_hello,
64 const Result& result) = 0;
66 private:
67 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloResultCallback);
70 // QuicCryptoServerConfig contains the crypto configuration of a QUIC server.
71 // Unlike a client, a QUIC server can have multiple configurations active in
72 // order to support clients resuming with a previous configuration.
73 // TODO(agl): when adding configurations at runtime is added, this object will
74 // need to consider locking.
75 class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
76 public:
77 // ConfigOptions contains options for generating server configs.
78 struct NET_EXPORT_PRIVATE ConfigOptions {
79 ConfigOptions();
81 // expiry_time is the time, in UNIX seconds, when the server config will
82 // expire. If unset, it defaults to the current time plus six months.
83 QuicWallTime expiry_time;
84 // channel_id_enabled controls whether the server config will indicate
85 // support for ChannelIDs.
86 bool channel_id_enabled;
87 // id contains the server config id for the resulting config. If empty, a
88 // random id is generated.
89 std::string id;
90 // orbit contains the kOrbitSize bytes of the orbit value for the server
91 // config. If |orbit| is empty then a random orbit is generated.
92 std::string orbit;
93 // p256 determines whether a P-256 public key will be included in the
94 // server config. Note that this breaks deterministic server-config
95 // generation since P-256 key generation doesn't use the QuicRandom given
96 // to DefaultConfig().
97 bool p256;
100 // |source_address_token_secret|: secret key material used for encrypting and
101 // decrypting source address tokens. It can be of any length as it is fed
102 // into a KDF before use. In tests, use TESTING.
103 // |server_nonce_entropy|: an entropy source used to generate the orbit and
104 // key for server nonces, which are always local to a given instance of a
105 // server.
106 QuicCryptoServerConfig(base::StringPiece source_address_token_secret,
107 QuicRandom* server_nonce_entropy);
108 ~QuicCryptoServerConfig();
110 // TESTING is a magic parameter for passing to the constructor in tests.
111 static const char TESTING[];
113 // Generates a QuicServerConfigProtobuf protobuf suitable for
114 // AddConfig and SetConfigs.
115 static QuicServerConfigProtobuf* GenerateConfig(
116 QuicRandom* rand,
117 const QuicClock* clock,
118 const ConfigOptions& options);
120 // AddConfig adds a QuicServerConfigProtobuf to the availible configurations.
121 // It returns the SCFG message from the config if successful. The caller
122 // takes ownership of the CryptoHandshakeMessage. |now| is used in
123 // conjunction with |protobuf->primary_time()| to determine whether the
124 // config should be made primary.
125 CryptoHandshakeMessage* AddConfig(QuicServerConfigProtobuf* protobuf,
126 QuicWallTime now);
128 // AddDefaultConfig calls DefaultConfig to create a config and then calls
129 // AddConfig to add it. See the comment for |DefaultConfig| for details of
130 // the arguments.
131 CryptoHandshakeMessage* AddDefaultConfig(
132 QuicRandom* rand,
133 const QuicClock* clock,
134 const ConfigOptions& options);
136 // SetConfigs takes a vector of config protobufs and the current time.
137 // Configs are assumed to be uniquely identified by their server config ID.
138 // Previously unknown configs are added and possibly made the primary config
139 // depending on their |primary_time| and the value of |now|. Configs that are
140 // known, but are missing from the protobufs are deleted, unless they are
141 // currently the primary config. SetConfigs returns false if any errors were
142 // encountered and no changes to the QuicCryptoServerConfig will occur.
143 bool SetConfigs(const std::vector<QuicServerConfigProtobuf*>& protobufs,
144 QuicWallTime now);
146 // Get the server config ids for all known configs.
147 void GetConfigIds(std::vector<std::string>* scids) const;
149 // Checks |client_hello| for gross errors and determines whether it
150 // can be shown to be fresh (i.e. not a replay). The result of the
151 // validation step must be interpreted by calling
152 // QuicCryptoServerConfig::ProcessClientHello from the done_cb.
154 // ValidateClientHello may invoke the done_cb before unrolling the
155 // stack if it is able to assess the validity of the client_nonce
156 // without asynchronous operations.
158 // client_hello: the incoming client hello message.
159 // client_ip: the IP address of the client, which is used to generate and
160 // validate source-address tokens.
161 // clock: used to validate client nonces and ephemeral keys.
162 // done_cb: single-use callback that accepts an opaque
163 // ValidatedClientHelloMsg token that holds information about
164 // the client hello. The callback will always be called exactly
165 // once, either under the current call stack, or after the
166 // completion of an asynchronous operation.
167 void ValidateClientHello(
168 const CryptoHandshakeMessage& client_hello,
169 IPEndPoint client_ip,
170 const QuicClock* clock,
171 ValidateClientHelloResultCallback* done_cb) const;
173 // ProcessClientHello processes |client_hello| and decides whether to accept
174 // or reject the connection. If the connection is to be accepted, |out| is
175 // set to the contents of the ServerHello, |out_params| is completed and
176 // QUIC_NO_ERROR is returned. Otherwise |out| is set to be a REJ message and
177 // an error code is returned.
179 // validate_chlo_result: Output from the asynchronous call to
180 // ValidateClientHello. Contains the client hello message and
181 // information about it.
182 // connection_id: the ConnectionId for the connection, which is used in key
183 // derivation.
184 // client_address: the IP address and port of the client. The IP address is
185 // used to generate and validate source-address tokens.
186 // version: version of the QUIC protocol in use for this connection
187 // supported_versions: versions of the QUIC protocol that this server
188 // supports.
189 // clock: used to validate client nonces and ephemeral keys.
190 // rand: an entropy source
191 // params: the state of the handshake. This may be updated with a server
192 // nonce when we send a rejection. After a successful handshake, this will
193 // contain the state of the connection.
194 // out: the resulting handshake message (either REJ or SHLO)
195 // error_details: used to store a string describing any error.
196 QuicErrorCode ProcessClientHello(
197 const ValidateClientHelloResultCallback::Result& validate_chlo_result,
198 QuicConnectionId connection_id,
199 IPEndPoint client_address,
200 QuicVersion version,
201 const QuicVersionVector& supported_versions,
202 const QuicClock* clock,
203 QuicRandom* rand,
204 QuicCryptoNegotiatedParameters* params,
205 CryptoHandshakeMessage* out,
206 std::string* error_details) const;
208 // SetProofSource installs |proof_source| as the ProofSource for handshakes.
209 // This object takes ownership of |proof_source|.
210 void SetProofSource(ProofSource* proof_source);
212 // SetEphemeralKeySource installs an object that can cache ephemeral keys for
213 // a short period of time. This object takes ownership of
214 // |ephemeral_key_source|. If not set then ephemeral keys will be generated
215 // per-connection.
216 void SetEphemeralKeySource(EphemeralKeySource* ephemeral_key_source);
218 // Install an externall created StrikeRegisterClient for use to
219 // interact with the strike register. This object takes ownership
220 // of the |strike_register_client|.
221 void SetStrikeRegisterClient(StrikeRegisterClient* strike_register_client);
223 // set_replay_protection controls whether replay protection is enabled. If
224 // replay protection is disabled then no strike registers are needed and
225 // frontends can share an orbit value without a shared strike-register.
226 // However, an attacker can duplicate a handshake and cause a client's
227 // request to be processed twice.
228 void set_replay_protection(bool on);
230 // set_strike_register_no_startup_period configures the strike register to
231 // not have a startup period.
232 void set_strike_register_no_startup_period();
234 // set_strike_register_max_entries sets the maximum number of entries that
235 // the internal strike register will hold. If the strike register fills up
236 // then the oldest entries (by the client's clock) will be dropped.
237 void set_strike_register_max_entries(uint32 max_entries);
239 // set_strike_register_window_secs sets the number of seconds around the
240 // current time that the strike register will attempt to be authoritative
241 // for. Setting a larger value allows for greater client clock-skew, but
242 // means that the quiescent startup period must be longer.
243 void set_strike_register_window_secs(uint32 window_secs);
245 // set_source_address_token_future_secs sets the number of seconds into the
246 // future that source-address tokens will be accepted from. Since
247 // source-address tokens are authenticated, this should only happen if
248 // another, valid server has clock-skew.
249 void set_source_address_token_future_secs(uint32 future_secs);
251 // set_source_address_token_lifetime_secs sets the number of seconds that a
252 // source-address token will be valid for.
253 void set_source_address_token_lifetime_secs(uint32 lifetime_secs);
255 // set_server_nonce_strike_register_max_entries sets the number of entries in
256 // the server-nonce strike-register. This is used to record that server nonce
257 // values have been used. If the number of entries is too small then clients
258 // which are depending on server nonces may fail to handshake because their
259 // nonce has expired in the amount of time it took to go from the server to
260 // the client and back.
261 void set_server_nonce_strike_register_max_entries(uint32 max_entries);
263 // set_server_nonce_strike_register_window_secs sets the number of seconds
264 // around the current time that the server-nonce strike-register will accept
265 // nonces from. Setting a larger value allows for clients to delay follow-up
266 // client hellos for longer and still use server nonces as proofs of
267 // uniqueness.
268 void set_server_nonce_strike_register_window_secs(uint32 window_secs);
270 // Set and take ownership of the callback to invoke on primary config changes.
271 void AcquirePrimaryConfigChangedCb(PrimaryConfigChangedCallback* cb);
273 private:
274 friend class test::QuicCryptoServerConfigPeer;
276 // Config represents a server config: a collection of preferences and
277 // Diffie-Hellman public values.
278 class NET_EXPORT_PRIVATE Config : public QuicCryptoConfig,
279 public base::RefCounted<Config> {
280 public:
281 Config();
283 // TODO(rtenneti): since this is a class, we should probably do
284 // getters/setters here.
285 // |serialized| contains the bytes of this server config, suitable for
286 // sending on the wire.
287 std::string serialized;
288 // id contains the SCID of this server config.
289 std::string id;
290 // orbit contains the orbit value for this config: an opaque identifier
291 // used to identify clusters of server frontends.
292 unsigned char orbit[kOrbitSize];
294 // key_exchanges contains key exchange objects with the private keys
295 // already loaded. The values correspond, one-to-one, with the tags in
296 // |kexs| from the parent class.
297 std::vector<KeyExchange*> key_exchanges;
299 // tag_value_map contains the raw key/value pairs for the config.
300 QuicTagValueMap tag_value_map;
302 // channel_id_enabled is true if the config in |serialized| specifies that
303 // ChannelIDs are supported.
304 bool channel_id_enabled;
306 // is_primary is true if this config is the one that we'll give out to
307 // clients as the current one.
308 bool is_primary;
310 // primary_time contains the timestamp when this config should become the
311 // primary config. A value of QuicWallTime::Zero() means that this config
312 // will not be promoted at a specific time.
313 QuicWallTime primary_time;
315 // Secondary sort key for use when selecting primary configs and
316 // there are multiple configs with the same primary time.
317 // Smaller numbers mean higher priority.
318 uint64 priority;
320 private:
321 friend class base::RefCounted<Config>;
322 virtual ~Config();
324 DISALLOW_COPY_AND_ASSIGN(Config);
327 typedef std::map<ServerConfigID, scoped_refptr<Config> > ConfigMap;
329 // ConfigPrimaryTimeLessThan returns true if a->primary_time <
330 // b->primary_time.
331 static bool ConfigPrimaryTimeLessThan(const scoped_refptr<Config>& a,
332 const scoped_refptr<Config>& b);
334 // SelectNewPrimaryConfig reevaluates the primary config based on the
335 // "primary_time" deadlines contained in each.
336 void SelectNewPrimaryConfig(QuicWallTime now) const;
338 // EvaluateClientHello checks |client_hello| for gross errors and determines
339 // whether it can be shown to be fresh (i.e. not a replay). The results are
340 // written to |info|.
341 void EvaluateClientHello(
342 const uint8* primary_orbit,
343 ValidateClientHelloResultCallback::Result* client_hello_state,
344 ValidateClientHelloResultCallback* done_cb) const;
346 // BuildRejection sets |out| to be a REJ message in reply to |client_hello|.
347 void BuildRejection(
348 const scoped_refptr<Config>& config,
349 const CryptoHandshakeMessage& client_hello,
350 const ClientHelloInfo& info,
351 QuicRandom* rand,
352 CryptoHandshakeMessage* out) const;
354 // ParseConfigProtobuf parses the given config protobuf and returns a
355 // scoped_refptr<Config> if successful. The caller adopts the reference to the
356 // Config. On error, ParseConfigProtobuf returns NULL.
357 scoped_refptr<Config> ParseConfigProtobuf(QuicServerConfigProtobuf* protobuf);
359 // NewSourceAddressToken returns a fresh source address token for the given
360 // IP address.
361 std::string NewSourceAddressToken(const IPEndPoint& ip,
362 QuicRandom* rand,
363 QuicWallTime now) const;
365 // ValidateSourceAddressToken returns true if the source address token in
366 // |token| is a valid and timely token for the IP address |ip| given that the
367 // current time is |now|.
368 bool ValidateSourceAddressToken(base::StringPiece token,
369 const IPEndPoint& ip,
370 QuicWallTime now) const;
372 // NewServerNonce generates and encrypts a random nonce.
373 std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const;
375 // ValidateServerNonce decrypts |token| and verifies that it hasn't been
376 // previously used and is recent enough that it is plausible that it was part
377 // of a very recently provided rejection ("recent" will be on the order of
378 // 10-30 seconds). If so, it records that it has been used and returns true.
379 // Otherwise it returns false.
380 bool ValidateServerNonce(base::StringPiece echoed_server_nonce,
381 QuicWallTime now) const;
383 // replay_protection_ controls whether the server enforces that handshakes
384 // aren't replays.
385 bool replay_protection_;
387 // configs_ satisfies the following invariants:
388 // 1) configs_.empty() <-> primary_config_ == NULL
389 // 2) primary_config_ != NULL -> primary_config_->is_primary
390 // 3) ∀ c∈configs_, c->is_primary <-> c == primary_config_
391 mutable base::Lock configs_lock_;
392 // configs_ contains all active server configs. It's expected that there are
393 // about half-a-dozen configs active at any one time.
394 ConfigMap configs_;
395 // primary_config_ points to a Config (which is also in |configs_|) which is
396 // the primary config - i.e. the one that we'll give out to new clients.
397 mutable scoped_refptr<Config> primary_config_;
398 // next_config_promotion_time_ contains the nearest, future time when an
399 // active config will be promoted to primary.
400 mutable QuicWallTime next_config_promotion_time_;
401 // Callback to invoke when the primary config changes.
402 scoped_ptr<PrimaryConfigChangedCallback> primary_config_changed_cb_;
404 // Protects access to the pointer held by strike_register_client_.
405 mutable base::Lock strike_register_client_lock_;
406 // strike_register_ contains a data structure that keeps track of previously
407 // observed client nonces in order to prevent replay attacks.
408 mutable scoped_ptr<StrikeRegisterClient> strike_register_client_;
410 // source_address_token_boxer_ is used to protect the source-address tokens
411 // that are given to clients.
412 CryptoSecretBoxer source_address_token_boxer_;
414 // server_nonce_boxer_ is used to encrypt and validate suggested server
415 // nonces.
416 CryptoSecretBoxer server_nonce_boxer_;
418 // server_nonce_orbit_ contains the random, per-server orbit values that this
419 // server will use to generate server nonces (the moral equivalent of a SYN
420 // cookies).
421 uint8 server_nonce_orbit_[8];
423 mutable base::Lock server_nonce_strike_register_lock_;
424 // server_nonce_strike_register_ contains a data structure that keeps track of
425 // previously observed server nonces from this server, in order to prevent
426 // replay attacks.
427 mutable scoped_ptr<StrikeRegister> server_nonce_strike_register_;
429 // proof_source_ contains an object that can provide certificate chains and
430 // signatures.
431 scoped_ptr<ProofSource> proof_source_;
433 // ephemeral_key_source_ contains an object that caches ephemeral keys for a
434 // short period of time.
435 scoped_ptr<EphemeralKeySource> ephemeral_key_source_;
437 // These fields store configuration values. See the comments for their
438 // respective setter functions.
439 bool strike_register_no_startup_period_;
440 uint32 strike_register_max_entries_;
441 uint32 strike_register_window_secs_;
442 uint32 source_address_token_future_secs_;
443 uint32 source_address_token_lifetime_secs_;
444 uint32 server_nonce_strike_register_max_entries_;
445 uint32 server_nonce_strike_register_window_secs_;
448 } // namespace net
450 #endif // NET_QUIC_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_