[Android WebView] Fix webview perf bot switchover to use org.chromium.webview_shell...
[chromium-blink-merge.git] / net / quic / crypto / quic_crypto_server_config.h
blobf7716e25f2b2dc46a6b5cd729b0619d74f8a1aef
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/base/net_util.h"
19 #include "net/quic/crypto/crypto_handshake.h"
20 #include "net/quic/crypto/crypto_handshake_message.h"
21 #include "net/quic/crypto/crypto_protocol.h"
22 #include "net/quic/crypto/crypto_secret_boxer.h"
23 #include "net/quic/proto/cached_network_parameters.pb.h"
24 #include "net/quic/proto/source_address_token.pb.h"
25 #include "net/quic/quic_time.h"
27 namespace net {
29 class CryptoHandshakeMessage;
30 class EphemeralKeySource;
31 class KeyExchange;
32 class ProofSource;
33 class QuicClock;
34 class QuicDecrypter;
35 class QuicEncrypter;
36 class QuicRandom;
37 class QuicServerConfigProtobuf;
38 class StrikeRegister;
39 class StrikeRegisterClient;
41 // ClientHelloInfo contains information about a client hello message that is
42 // only kept for as long as it's being processed.
43 struct ClientHelloInfo {
44 ClientHelloInfo(const IPAddressNumber& in_client_ip, QuicWallTime in_now);
45 ~ClientHelloInfo();
47 // Inputs to EvaluateClientHello.
48 const IPAddressNumber client_ip;
49 const QuicWallTime now;
51 // Outputs from EvaluateClientHello.
52 bool valid_source_address_token;
53 bool client_nonce_well_formed;
54 bool unique;
55 base::StringPiece sni;
56 base::StringPiece client_nonce;
57 base::StringPiece server_nonce;
58 base::StringPiece user_agent_id;
59 SourceAddressTokens source_address_tokens;
61 // Errors from EvaluateClientHello.
62 std::vector<uint32> reject_reasons;
63 static_assert(sizeof(QuicTag) == sizeof(uint32), "header out of sync");
66 namespace test {
67 class QuicCryptoServerConfigPeer;
68 } // namespace test
70 // Hook that allows application code to subscribe to primary config changes.
71 class PrimaryConfigChangedCallback {
72 public:
73 PrimaryConfigChangedCallback();
74 virtual ~PrimaryConfigChangedCallback();
75 virtual void Run(const std::string& scid) = 0;
77 private:
78 DISALLOW_COPY_AND_ASSIGN(PrimaryConfigChangedCallback);
81 // Callback used to accept the result of the |client_hello| validation step.
82 class NET_EXPORT_PRIVATE ValidateClientHelloResultCallback {
83 public:
84 // Opaque token that holds information about the client_hello and
85 // its validity. Can be interpreted by calling ProcessClientHello.
86 struct Result {
87 Result(const CryptoHandshakeMessage& in_client_hello,
88 IPAddressNumber in_client_ip,
89 QuicWallTime in_now);
90 ~Result();
92 CryptoHandshakeMessage client_hello;
93 ClientHelloInfo info;
94 QuicErrorCode error_code;
95 std::string error_details;
97 // Populated if the CHLO STK contained a CachedNetworkParameters proto.
98 CachedNetworkParameters cached_network_params;
101 ValidateClientHelloResultCallback();
102 virtual ~ValidateClientHelloResultCallback();
103 void Run(const Result* result);
105 protected:
106 virtual void RunImpl(const CryptoHandshakeMessage& client_hello,
107 const Result& result) = 0;
109 private:
110 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloResultCallback);
113 // QuicCryptoServerConfig contains the crypto configuration of a QUIC server.
114 // Unlike a client, a QUIC server can have multiple configurations active in
115 // order to support clients resuming with a previous configuration.
116 // TODO(agl): when adding configurations at runtime is added, this object will
117 // need to consider locking.
118 class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
119 public:
120 // ConfigOptions contains options for generating server configs.
121 struct NET_EXPORT_PRIVATE ConfigOptions {
122 ConfigOptions();
124 // expiry_time is the time, in UNIX seconds, when the server config will
125 // expire. If unset, it defaults to the current time plus six months.
126 QuicWallTime expiry_time;
127 // channel_id_enabled controls whether the server config will indicate
128 // support for ChannelIDs.
129 bool channel_id_enabled;
130 // id contains the server config id for the resulting config. If empty, a
131 // random id is generated.
132 std::string id;
133 // orbit contains the kOrbitSize bytes of the orbit value for the server
134 // config. If |orbit| is empty then a random orbit is generated.
135 std::string orbit;
136 // p256 determines whether a P-256 public key will be included in the
137 // server config. Note that this breaks deterministic server-config
138 // generation since P-256 key generation doesn't use the QuicRandom given
139 // to DefaultConfig().
140 bool p256;
143 // |source_address_token_secret|: secret key material used for encrypting and
144 // decrypting source address tokens. It can be of any length as it is fed
145 // into a KDF before use. In tests, use TESTING.
146 // |server_nonce_entropy|: an entropy source used to generate the orbit and
147 // key for server nonces, which are always local to a given instance of a
148 // server.
149 QuicCryptoServerConfig(base::StringPiece source_address_token_secret,
150 QuicRandom* server_nonce_entropy);
151 ~QuicCryptoServerConfig();
153 // TESTING is a magic parameter for passing to the constructor in tests.
154 static const char TESTING[];
156 // Generates a QuicServerConfigProtobuf protobuf suitable for
157 // AddConfig and SetConfigs.
158 static QuicServerConfigProtobuf* GenerateConfig(
159 QuicRandom* rand,
160 const QuicClock* clock,
161 const ConfigOptions& options);
163 // AddConfig adds a QuicServerConfigProtobuf to the availible configurations.
164 // It returns the SCFG message from the config if successful. The caller
165 // takes ownership of the CryptoHandshakeMessage. |now| is used in
166 // conjunction with |protobuf->primary_time()| to determine whether the
167 // config should be made primary.
168 CryptoHandshakeMessage* AddConfig(QuicServerConfigProtobuf* protobuf,
169 QuicWallTime now);
171 // AddDefaultConfig calls DefaultConfig to create a config and then calls
172 // AddConfig to add it. See the comment for |DefaultConfig| for details of
173 // the arguments.
174 CryptoHandshakeMessage* AddDefaultConfig(
175 QuicRandom* rand,
176 const QuicClock* clock,
177 const ConfigOptions& options);
179 // SetConfigs takes a vector of config protobufs and the current time.
180 // Configs are assumed to be uniquely identified by their server config ID.
181 // Previously unknown configs are added and possibly made the primary config
182 // depending on their |primary_time| and the value of |now|. Configs that are
183 // known, but are missing from the protobufs are deleted, unless they are
184 // currently the primary config. SetConfigs returns false if any errors were
185 // encountered and no changes to the QuicCryptoServerConfig will occur.
186 bool SetConfigs(const std::vector<QuicServerConfigProtobuf*>& protobufs,
187 QuicWallTime now);
189 // Get the server config ids for all known configs.
190 void GetConfigIds(std::vector<std::string>* scids) const;
192 // Checks |client_hello| for gross errors and determines whether it
193 // can be shown to be fresh (i.e. not a replay). The result of the
194 // validation step must be interpreted by calling
195 // QuicCryptoServerConfig::ProcessClientHello from the done_cb.
197 // ValidateClientHello may invoke the done_cb before unrolling the
198 // stack if it is able to assess the validity of the client_nonce
199 // without asynchronous operations.
201 // client_hello: the incoming client hello message.
202 // client_ip: the IP address of the client, which is used to generate and
203 // validate source-address tokens.
204 // clock: used to validate client nonces and ephemeral keys.
205 // done_cb: single-use callback that accepts an opaque
206 // ValidatedClientHelloMsg token that holds information about
207 // the client hello. The callback will always be called exactly
208 // once, either under the current call stack, or after the
209 // completion of an asynchronous operation.
210 void ValidateClientHello(const CryptoHandshakeMessage& client_hello,
211 IPAddressNumber client_ip,
212 const QuicClock* clock,
213 ValidateClientHelloResultCallback* done_cb) const;
215 // ProcessClientHello processes |client_hello| and decides whether to accept
216 // or reject the connection. If the connection is to be accepted, |out| is
217 // set to the contents of the ServerHello, |out_params| is completed and
218 // QUIC_NO_ERROR is returned. Otherwise |out| is set to be a REJ or SREJ
219 // message and QUIC_NO_ERROR is returned.
221 // validate_chlo_result: Output from the asynchronous call to
222 // ValidateClientHello. Contains the client hello message and
223 // information about it.
224 // connection_id: the ConnectionId for the connection, which is used in key
225 // derivation.
226 // server_ip: the IP address and port of the server. The IP address may be
227 // used for certificate selection.
228 // client_address: the IP address and port of the client. The IP address is
229 // used to generate and validate source-address tokens.
230 // version: version of the QUIC protocol in use for this connection
231 // supported_versions: versions of the QUIC protocol that this server
232 // supports.
233 // initial_flow_control_window: size of initial flow control window this
234 // server uses for new streams.
235 // clock: used to validate client nonces and ephemeral keys.
236 // rand: an entropy source
237 // params: the state of the handshake. This may be updated with a server
238 // nonce when we send a rejection. After a successful handshake, this will
239 // contain the state of the connection.
240 // out: the resulting handshake message (either REJ or SHLO)
241 // error_details: used to store a string describing any error.
242 QuicErrorCode ProcessClientHello(
243 const ValidateClientHelloResultCallback::Result& validate_chlo_result,
244 QuicConnectionId connection_id,
245 const IPAddressNumber& server_ip,
246 const IPEndPoint& client_address,
247 QuicVersion version,
248 const QuicVersionVector& supported_versions,
249 bool use_stateless_rejects,
250 QuicConnectionId server_designated_connection_id,
251 const QuicClock* clock,
252 QuicRandom* rand,
253 QuicCryptoNegotiatedParameters* params,
254 CryptoHandshakeMessage* out,
255 std::string* error_details) const;
257 // BuildServerConfigUpdateMessage sets |out| to be a SCUP message containing
258 // the current primary config, an up to date source-address token, and cert
259 // chain and proof in the case of secure QUIC. Returns true if successfully
260 // filled |out|.
262 // |cached_network_params| is optional, and can be nullptr.
263 bool BuildServerConfigUpdateMessage(
264 const SourceAddressTokens& previous_source_address_tokens,
265 const IPAddressNumber& server_ip,
266 const IPAddressNumber& client_ip,
267 const QuicClock* clock,
268 QuicRandom* rand,
269 const QuicCryptoNegotiatedParameters& params,
270 const CachedNetworkParameters* cached_network_params,
271 CryptoHandshakeMessage* out) const;
273 // SetProofSource installs |proof_source| as the ProofSource for handshakes.
274 // This object takes ownership of |proof_source|.
275 void SetProofSource(ProofSource* proof_source);
277 // SetEphemeralKeySource installs an object that can cache ephemeral keys for
278 // a short period of time. This object takes ownership of
279 // |ephemeral_key_source|. If not set then ephemeral keys will be generated
280 // per-connection.
281 void SetEphemeralKeySource(EphemeralKeySource* ephemeral_key_source);
283 // Install an externall created StrikeRegisterClient for use to
284 // interact with the strike register. This object takes ownership
285 // of the |strike_register_client|.
286 void SetStrikeRegisterClient(StrikeRegisterClient* strike_register_client);
288 // set_replay_protection controls whether replay protection is enabled. If
289 // replay protection is disabled then no strike registers are needed and
290 // frontends can share an orbit value without a shared strike-register.
291 // However, an attacker can duplicate a handshake and cause a client's
292 // request to be processed twice.
293 void set_replay_protection(bool on);
295 // set_strike_register_no_startup_period configures the strike register to
296 // not have a startup period.
297 void set_strike_register_no_startup_period();
299 // set_strike_register_max_entries sets the maximum number of entries that
300 // the internal strike register will hold. If the strike register fills up
301 // then the oldest entries (by the client's clock) will be dropped.
302 void set_strike_register_max_entries(uint32 max_entries);
304 // set_strike_register_window_secs sets the number of seconds around the
305 // current time that the strike register will attempt to be authoritative
306 // for. Setting a larger value allows for greater client clock-skew, but
307 // means that the quiescent startup period must be longer.
308 void set_strike_register_window_secs(uint32 window_secs);
310 // set_source_address_token_future_secs sets the number of seconds into the
311 // future that source-address tokens will be accepted from. Since
312 // source-address tokens are authenticated, this should only happen if
313 // another, valid server has clock-skew.
314 void set_source_address_token_future_secs(uint32 future_secs);
316 // set_source_address_token_lifetime_secs sets the number of seconds that a
317 // source-address token will be valid for.
318 void set_source_address_token_lifetime_secs(uint32 lifetime_secs);
320 // set_server_nonce_strike_register_max_entries sets the number of entries in
321 // the server-nonce strike-register. This is used to record that server nonce
322 // values have been used. If the number of entries is too small then clients
323 // which are depending on server nonces may fail to handshake because their
324 // nonce has expired in the amount of time it took to go from the server to
325 // the client and back.
326 void set_server_nonce_strike_register_max_entries(uint32 max_entries);
328 // set_server_nonce_strike_register_window_secs sets the number of seconds
329 // around the current time that the server-nonce strike-register will accept
330 // nonces from. Setting a larger value allows for clients to delay follow-up
331 // client hellos for longer and still use server nonces as proofs of
332 // uniqueness.
333 void set_server_nonce_strike_register_window_secs(uint32 window_secs);
335 // Set and take ownership of the callback to invoke on primary config changes.
336 void AcquirePrimaryConfigChangedCb(PrimaryConfigChangedCallback* cb);
338 // Returns true if this config has a |proof_source_|.
339 bool HasProofSource() const;
341 // Returns the number of configs this object owns.
342 int NumberOfConfigs() const;
344 private:
345 friend class test::QuicCryptoServerConfigPeer;
347 // Config represents a server config: a collection of preferences and
348 // Diffie-Hellman public values.
349 class NET_EXPORT_PRIVATE Config : public QuicCryptoConfig,
350 public base::RefCounted<Config> {
351 public:
352 Config();
354 // TODO(rtenneti): since this is a class, we should probably do
355 // getters/setters here.
356 // |serialized| contains the bytes of this server config, suitable for
357 // sending on the wire.
358 std::string serialized;
359 // id contains the SCID of this server config.
360 std::string id;
361 // orbit contains the orbit value for this config: an opaque identifier
362 // used to identify clusters of server frontends.
363 unsigned char orbit[kOrbitSize];
365 // key_exchanges contains key exchange objects with the private keys
366 // already loaded. The values correspond, one-to-one, with the tags in
367 // |kexs| from the parent class.
368 std::vector<KeyExchange*> key_exchanges;
370 // tag_value_map contains the raw key/value pairs for the config.
371 QuicTagValueMap tag_value_map;
373 // channel_id_enabled is true if the config in |serialized| specifies that
374 // ChannelIDs are supported.
375 bool channel_id_enabled;
377 // is_primary is true if this config is the one that we'll give out to
378 // clients as the current one.
379 bool is_primary;
381 // primary_time contains the timestamp when this config should become the
382 // primary config. A value of QuicWallTime::Zero() means that this config
383 // will not be promoted at a specific time.
384 QuicWallTime primary_time;
386 // Secondary sort key for use when selecting primary configs and
387 // there are multiple configs with the same primary time.
388 // Smaller numbers mean higher priority.
389 uint64 priority;
391 // source_address_token_boxer_ is used to protect the
392 // source-address tokens that are given to clients.
393 // Points to either source_address_token_boxer_storage or the
394 // default boxer provided by QuicCryptoServerConfig.
395 const CryptoSecretBoxer* source_address_token_boxer;
397 // Holds the override source_address_token_boxer instance if the
398 // Config is not using the default source address token boxer
399 // instance provided by QuicCryptoServerConfig.
400 scoped_ptr<CryptoSecretBoxer> source_address_token_boxer_storage;
402 private:
403 friend class base::RefCounted<Config>;
405 virtual ~Config();
407 DISALLOW_COPY_AND_ASSIGN(Config);
410 typedef std::map<ServerConfigID, scoped_refptr<Config> > ConfigMap;
412 // Get a ref to the config with a given server config id.
413 scoped_refptr<Config> GetConfigWithScid(
414 base::StringPiece requested_scid) const;
416 // ConfigPrimaryTimeLessThan returns true if a->primary_time <
417 // b->primary_time.
418 static bool ConfigPrimaryTimeLessThan(const scoped_refptr<Config>& a,
419 const scoped_refptr<Config>& b);
421 // SelectNewPrimaryConfig reevaluates the primary config based on the
422 // "primary_time" deadlines contained in each.
423 void SelectNewPrimaryConfig(QuicWallTime now) const;
425 // EvaluateClientHello checks |client_hello| for gross errors and determines
426 // whether it can be shown to be fresh (i.e. not a replay). The results are
427 // written to |info|.
428 void EvaluateClientHello(
429 const uint8* primary_orbit,
430 scoped_refptr<Config> requested_config,
431 ValidateClientHelloResultCallback::Result* client_hello_state,
432 ValidateClientHelloResultCallback* done_cb) const;
434 // BuildRejection sets |out| to be a REJ message in reply to |client_hello|.
435 void BuildRejection(const IPAddressNumber& server_ip,
436 const Config& config,
437 const CryptoHandshakeMessage& client_hello,
438 const ClientHelloInfo& info,
439 const CachedNetworkParameters& cached_network_params,
440 bool use_stateless_rejects,
441 QuicConnectionId server_designated_connection_id,
442 QuicRandom* rand,
443 QuicCryptoNegotiatedParameters* params,
444 CryptoHandshakeMessage* out) const;
446 // ParseConfigProtobuf parses the given config protobuf and returns a
447 // scoped_refptr<Config> if successful. The caller adopts the reference to the
448 // Config. On error, ParseConfigProtobuf returns nullptr.
449 scoped_refptr<Config> ParseConfigProtobuf(QuicServerConfigProtobuf* protobuf);
451 // NewSourceAddressToken returns a fresh source address token for the given
452 // IP address. |cached_network_params| is optional, and can be nullptr.
453 std::string NewSourceAddressToken(
454 const Config& config,
455 const SourceAddressTokens& previous_tokens,
456 const IPAddressNumber& ip,
457 QuicRandom* rand,
458 QuicWallTime now,
459 const CachedNetworkParameters* cached_network_params) const;
461 // ParseSourceAddressToken parses the source address tokens contained in
462 // the encrypted |token|, and populates |tokens| with the parsed tokens.
463 // Returns HANDSHAKE_OK if |token| could be parsed, or the reason for the
464 // failure.
465 HandshakeFailureReason ParseSourceAddressToken(
466 const Config& config,
467 base::StringPiece token,
468 SourceAddressTokens* tokens) const;
470 // ValidateSourceAddressTokens returns HANDSHAKE_OK if the source address
471 // tokens in |tokens| contain a valid and timely token for the IP address
472 // |ip| given that the current time is |now|. Otherwise it returns the
473 // reason for failure. |cached_network_params| is populated if the valid
474 // token contains a CachedNetworkParameters proto.
475 HandshakeFailureReason ValidateSourceAddressTokens(
476 const SourceAddressTokens& tokens,
477 const IPAddressNumber& ip,
478 QuicWallTime now,
479 CachedNetworkParameters* cached_network_params) const;
481 // ValidateSingleSourceAddressToken returns HANDSHAKE_OK if the source
482 // address token in |token| is a timely token for the IP address |ip|
483 // given that the current time is |now|. Otherwise it returns the reason
484 // for failure.
485 HandshakeFailureReason ValidateSingleSourceAddressToken(
486 const SourceAddressToken& token,
487 const IPAddressNumber& ip,
488 QuicWallTime now) const;
490 // Returns HANDSHAKE_OK if the source address token in |token| is a timely
491 // token given that the current time is |now|. Otherwise it returns the
492 // reason for failure.
493 HandshakeFailureReason ValidateSourceAddressTokenTimestamp(
494 const SourceAddressToken& token,
495 QuicWallTime now) const;
497 // NewServerNonce generates and encrypts a random nonce.
498 std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const;
500 // ValidateServerNonce decrypts |token| and verifies that it hasn't been
501 // previously used and is recent enough that it is plausible that it was part
502 // of a very recently provided rejection ("recent" will be on the order of
503 // 10-30 seconds). If so, it records that it has been used and returns
504 // HANDSHAKE_OK. Otherwise it returns the reason for failure.
505 HandshakeFailureReason ValidateServerNonce(
506 base::StringPiece echoed_server_nonce,
507 QuicWallTime now) const;
509 // replay_protection_ controls whether the server enforces that handshakes
510 // aren't replays.
511 bool replay_protection_;
513 // configs_ satisfies the following invariants:
514 // 1) configs_.empty() <-> primary_config_ == nullptr
515 // 2) primary_config_ != nullptr -> primary_config_->is_primary
516 // 3) ∀ c∈configs_, c->is_primary <-> c == primary_config_
517 mutable base::Lock configs_lock_;
518 // configs_ contains all active server configs. It's expected that there are
519 // about half-a-dozen configs active at any one time.
520 ConfigMap configs_;
521 // primary_config_ points to a Config (which is also in |configs_|) which is
522 // the primary config - i.e. the one that we'll give out to new clients.
523 mutable scoped_refptr<Config> primary_config_;
524 // next_config_promotion_time_ contains the nearest, future time when an
525 // active config will be promoted to primary.
526 mutable QuicWallTime next_config_promotion_time_;
527 // Callback to invoke when the primary config changes.
528 scoped_ptr<PrimaryConfigChangedCallback> primary_config_changed_cb_;
530 // Protects access to the pointer held by strike_register_client_.
531 mutable base::Lock strike_register_client_lock_;
532 // strike_register_ contains a data structure that keeps track of previously
533 // observed client nonces in order to prevent replay attacks.
534 mutable scoped_ptr<StrikeRegisterClient> strike_register_client_;
536 // Default source_address_token_boxer_ used to protect the
537 // source-address tokens that are given to clients. Individual
538 // configs may use boxers with alternate secrets.
539 CryptoSecretBoxer default_source_address_token_boxer_;
541 // server_nonce_boxer_ is used to encrypt and validate suggested server
542 // nonces.
543 CryptoSecretBoxer server_nonce_boxer_;
545 // server_nonce_orbit_ contains the random, per-server orbit values that this
546 // server will use to generate server nonces (the moral equivalent of a SYN
547 // cookies).
548 uint8 server_nonce_orbit_[8];
550 mutable base::Lock server_nonce_strike_register_lock_;
551 // server_nonce_strike_register_ contains a data structure that keeps track of
552 // previously observed server nonces from this server, in order to prevent
553 // replay attacks.
554 mutable scoped_ptr<StrikeRegister> server_nonce_strike_register_;
556 // proof_source_ contains an object that can provide certificate chains and
557 // signatures.
558 scoped_ptr<ProofSource> proof_source_;
560 // ephemeral_key_source_ contains an object that caches ephemeral keys for a
561 // short period of time.
562 scoped_ptr<EphemeralKeySource> ephemeral_key_source_;
564 // These fields store configuration values. See the comments for their
565 // respective setter functions.
566 bool strike_register_no_startup_period_;
567 uint32 strike_register_max_entries_;
568 uint32 strike_register_window_secs_;
569 uint32 source_address_token_future_secs_;
570 uint32 source_address_token_lifetime_secs_;
571 uint32 server_nonce_strike_register_max_entries_;
572 uint32 server_nonce_strike_register_window_secs_;
574 DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerConfig);
577 } // namespace net
579 #endif // NET_QUIC_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_