|  | // Copyright 2013 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_ | 
|  | #define QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_ | 
|  |  | 
|  | #include <cstddef> | 
|  | #include <cstdint> | 
|  | #include <map> | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "third_party/boringssl/src/include/openssl/base.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/crypto_secret_boxer.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/key_exchange.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/proof_source.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h" | 
|  | #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_proof.h" | 
|  | #include "net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h" | 
|  | #include "net/third_party/quiche/src/quic/core/proto/source_address_token_proto.h" | 
|  | #include "net/third_party/quiche/src/quic/core/quic_time.h" | 
|  | #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" | 
|  | #include "net/third_party/quiche/src/quic/platform/api/quic_mutex.h" | 
|  | #include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h" | 
|  | #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" | 
|  | #include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h" | 
|  |  | 
|  | namespace quic { | 
|  |  | 
|  | class CryptoHandshakeMessage; | 
|  | class ProofSource; | 
|  | class QuicClock; | 
|  | class QuicRandom; | 
|  | class QuicServerConfigProtobuf; | 
|  | struct QuicSignedServerConfig; | 
|  |  | 
|  | // ClientHelloInfo contains information about a client hello message that is | 
|  | // only kept for as long as it's being processed. | 
|  | struct QUIC_EXPORT_PRIVATE ClientHelloInfo { | 
|  | ClientHelloInfo(const QuicIpAddress& in_client_ip, QuicWallTime in_now); | 
|  | ClientHelloInfo(const ClientHelloInfo& other); | 
|  | ~ClientHelloInfo(); | 
|  |  | 
|  | // Inputs to EvaluateClientHello. | 
|  | const QuicIpAddress client_ip; | 
|  | const QuicWallTime now; | 
|  |  | 
|  | // Outputs from EvaluateClientHello. | 
|  | bool valid_source_address_token; | 
|  | QuicStringPiece sni; | 
|  | QuicStringPiece client_nonce; | 
|  | QuicStringPiece server_nonce; | 
|  | QuicStringPiece user_agent_id; | 
|  | SourceAddressTokens source_address_tokens; | 
|  |  | 
|  | // Errors from EvaluateClientHello. | 
|  | std::vector<uint32_t> reject_reasons; | 
|  | static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync"); | 
|  | }; | 
|  |  | 
|  | namespace test { | 
|  | class QuicCryptoServerConfigPeer; | 
|  | }  // namespace test | 
|  |  | 
|  | // Hook that allows application code to subscribe to primary config changes. | 
|  | class QUIC_EXPORT_PRIVATE PrimaryConfigChangedCallback { | 
|  | public: | 
|  | PrimaryConfigChangedCallback(); | 
|  | PrimaryConfigChangedCallback(const PrimaryConfigChangedCallback&) = delete; | 
|  | PrimaryConfigChangedCallback& operator=(const PrimaryConfigChangedCallback&) = | 
|  | delete; | 
|  | virtual ~PrimaryConfigChangedCallback(); | 
|  | virtual void Run(const std::string& scid) = 0; | 
|  | }; | 
|  |  | 
|  | // Callback used to accept the result of the |client_hello| validation step. | 
|  | class QUIC_EXPORT_PRIVATE ValidateClientHelloResultCallback { | 
|  | public: | 
|  | // Opaque token that holds information about the client_hello and | 
|  | // its validity.  Can be interpreted by calling ProcessClientHello. | 
|  | struct QUIC_EXPORT_PRIVATE Result : public QuicReferenceCounted { | 
|  | Result(const CryptoHandshakeMessage& in_client_hello, | 
|  | QuicIpAddress in_client_ip, | 
|  | QuicWallTime in_now); | 
|  |  | 
|  | CryptoHandshakeMessage client_hello; | 
|  | ClientHelloInfo info; | 
|  | QuicErrorCode error_code; | 
|  | std::string error_details; | 
|  |  | 
|  | // Populated if the CHLO STK contained a CachedNetworkParameters proto. | 
|  | CachedNetworkParameters cached_network_params; | 
|  |  | 
|  | protected: | 
|  | ~Result() override; | 
|  | }; | 
|  |  | 
|  | ValidateClientHelloResultCallback(); | 
|  | ValidateClientHelloResultCallback(const ValidateClientHelloResultCallback&) = | 
|  | delete; | 
|  | ValidateClientHelloResultCallback& operator=( | 
|  | const ValidateClientHelloResultCallback&) = delete; | 
|  | virtual ~ValidateClientHelloResultCallback(); | 
|  | virtual void Run(QuicReferenceCountedPointer<Result> result, | 
|  | std::unique_ptr<ProofSource::Details> details) = 0; | 
|  | }; | 
|  |  | 
|  | // Callback used to accept the result of the ProcessClientHello method. | 
|  | class QUIC_EXPORT_PRIVATE ProcessClientHelloResultCallback { | 
|  | public: | 
|  | ProcessClientHelloResultCallback(); | 
|  | ProcessClientHelloResultCallback(const ProcessClientHelloResultCallback&) = | 
|  | delete; | 
|  | ProcessClientHelloResultCallback& operator=( | 
|  | const ProcessClientHelloResultCallback&) = delete; | 
|  | virtual ~ProcessClientHelloResultCallback(); | 
|  | virtual void Run(QuicErrorCode error, | 
|  | const std::string& error_details, | 
|  | std::unique_ptr<CryptoHandshakeMessage> message, | 
|  | std::unique_ptr<DiversificationNonce> diversification_nonce, | 
|  | std::unique_ptr<ProofSource::Details> details) = 0; | 
|  | }; | 
|  |  | 
|  | // Callback used to receive the results of a call to | 
|  | // BuildServerConfigUpdateMessage. | 
|  | class QUIC_EXPORT_PRIVATE BuildServerConfigUpdateMessageResultCallback { | 
|  | public: | 
|  | BuildServerConfigUpdateMessageResultCallback() = default; | 
|  | virtual ~BuildServerConfigUpdateMessageResultCallback() {} | 
|  | BuildServerConfigUpdateMessageResultCallback( | 
|  | const BuildServerConfigUpdateMessageResultCallback&) = delete; | 
|  | BuildServerConfigUpdateMessageResultCallback& operator=( | 
|  | const BuildServerConfigUpdateMessageResultCallback&) = delete; | 
|  | virtual void Run(bool ok, const CryptoHandshakeMessage& message) = 0; | 
|  | }; | 
|  |  | 
|  | // Object that is interested in built rejections (which include REJ, SREJ and | 
|  | // cheap SREJ). | 
|  | class QUIC_EXPORT_PRIVATE RejectionObserver { | 
|  | public: | 
|  | RejectionObserver() = default; | 
|  | virtual ~RejectionObserver() {} | 
|  | RejectionObserver(const RejectionObserver&) = delete; | 
|  | RejectionObserver& operator=(const RejectionObserver&) = delete; | 
|  | // Called after a rejection is built. | 
|  | virtual void OnRejectionBuilt(const std::vector<uint32_t>& reasons, | 
|  | CryptoHandshakeMessage* out) const = 0; | 
|  | }; | 
|  |  | 
|  | // Factory for creating KeyExchange objects. | 
|  | class QUIC_EXPORT_PRIVATE KeyExchangeSource { | 
|  | public: | 
|  | virtual ~KeyExchangeSource() = default; | 
|  |  | 
|  | // Returns the default KeyExchangeSource. | 
|  | static std::unique_ptr<KeyExchangeSource> Default(); | 
|  |  | 
|  | // Create a new KeyExchange using the curve specified by |type| using the | 
|  | // specified private key.  |private_key| may be empty for key-exchange | 
|  | // mechanisms which do not hold the private key in-process.  If |is_fallback| | 
|  | // is set, |private_key| is required to be set, and a local key-exchange | 
|  | // object should be returned. | 
|  | virtual std::unique_ptr<AsynchronousKeyExchange> Create( | 
|  | std::string server_config_id, | 
|  | bool is_fallback, | 
|  | QuicTag type, | 
|  | QuicStringPiece private_key) = 0; | 
|  | }; | 
|  |  | 
|  | // QuicCryptoServerConfig contains the crypto configuration of a QUIC server. | 
|  | // Unlike a client, a QUIC server can have multiple configurations active in | 
|  | // order to support clients resuming with a previous configuration. | 
|  | // TODO(agl): when adding configurations at runtime is added, this object will | 
|  | // need to consider locking. | 
|  | class QUIC_EXPORT_PRIVATE QuicCryptoServerConfig { | 
|  | public: | 
|  | // ConfigOptions contains options for generating server configs. | 
|  | struct QUIC_EXPORT_PRIVATE ConfigOptions { | 
|  | ConfigOptions(); | 
|  | ConfigOptions(const ConfigOptions& other); | 
|  | ~ConfigOptions(); | 
|  |  | 
|  | // expiry_time is the time, in UNIX seconds, when the server config will | 
|  | // expire. If unset, it defaults to the current time plus six months. | 
|  | QuicWallTime expiry_time; | 
|  | // channel_id_enabled controls whether the server config will indicate | 
|  | // support for ChannelIDs. | 
|  | bool channel_id_enabled; | 
|  | // id contains the server config id for the resulting config. If empty, a | 
|  | // random id is generated. | 
|  | std::string id; | 
|  | // orbit contains the kOrbitSize bytes of the orbit value for the server | 
|  | // config. If |orbit| is empty then a random orbit is generated. | 
|  | std::string orbit; | 
|  | // p256 determines whether a P-256 public key will be included in the | 
|  | // server config. Note that this breaks deterministic server-config | 
|  | // generation since P-256 key generation doesn't use the QuicRandom given | 
|  | // to DefaultConfig(). | 
|  | bool p256; | 
|  | }; | 
|  |  | 
|  | // |source_address_token_secret|: secret key material used for encrypting and | 
|  | //     decrypting source address tokens. It can be of any length as it is fed | 
|  | //     into a KDF before use. In tests, use TESTING. | 
|  | // |server_nonce_entropy|: an entropy source used to generate the orbit and | 
|  | //     key for server nonces, which are always local to a given instance of a | 
|  | //     server. Not owned. | 
|  | // |proof_source|: provides certificate chains and signatures. | 
|  | // |key_exchange_source|: provides key-exchange functionality. | 
|  | QuicCryptoServerConfig( | 
|  | QuicStringPiece source_address_token_secret, | 
|  | QuicRandom* server_nonce_entropy, | 
|  | std::unique_ptr<ProofSource> proof_source, | 
|  | std::unique_ptr<KeyExchangeSource> key_exchange_source); | 
|  | QuicCryptoServerConfig(const QuicCryptoServerConfig&) = delete; | 
|  | QuicCryptoServerConfig& operator=(const QuicCryptoServerConfig&) = delete; | 
|  | ~QuicCryptoServerConfig(); | 
|  |  | 
|  | // TESTING is a magic parameter for passing to the constructor in tests. | 
|  | static const char TESTING[]; | 
|  |  | 
|  | // Generates a QuicServerConfigProtobuf protobuf suitable for | 
|  | // AddConfig and SetConfigs. | 
|  | static QuicServerConfigProtobuf GenerateConfig(QuicRandom* rand, | 
|  | const QuicClock* clock, | 
|  | const ConfigOptions& options); | 
|  |  | 
|  | // AddConfig adds a QuicServerConfigProtobuf to the available configurations. | 
|  | // It returns the SCFG message from the config if successful. |now| is used in | 
|  | // conjunction with |protobuf->primary_time()| to determine whether the | 
|  | // config should be made primary. | 
|  | std::unique_ptr<CryptoHandshakeMessage> AddConfig( | 
|  | const QuicServerConfigProtobuf& protobuf, | 
|  | QuicWallTime now); | 
|  |  | 
|  | // AddDefaultConfig calls DefaultConfig to create a config and then calls | 
|  | // AddConfig to add it. See the comment for |DefaultConfig| for details of | 
|  | // the arguments. | 
|  | std::unique_ptr<CryptoHandshakeMessage> AddDefaultConfig( | 
|  | QuicRandom* rand, | 
|  | const QuicClock* clock, | 
|  | const ConfigOptions& options); | 
|  |  | 
|  | // SetConfigs takes a vector of config protobufs and the current time. | 
|  | // Configs are assumed to be uniquely identified by their server config ID. | 
|  | // Previously unknown configs are added and possibly made the primary config | 
|  | // depending on their |primary_time| and the value of |now|. Configs that are | 
|  | // known, but are missing from the protobufs are deleted, unless they are | 
|  | // currently the primary config. SetConfigs returns false if any errors were | 
|  | // encountered and no changes to the QuicCryptoServerConfig will occur. | 
|  | bool SetConfigs(const std::vector<QuicServerConfigProtobuf>& protobufs, | 
|  | const QuicServerConfigProtobuf* fallback_protobuf, | 
|  | QuicWallTime now); | 
|  |  | 
|  | // SetSourceAddressTokenKeys sets the keys to be tried, in order, when | 
|  | // decrypting a source address token.  Note that these keys are used *without* | 
|  | // passing them through a KDF, in contradistinction to the | 
|  | // |source_address_token_secret| argument to the constructor. | 
|  | void SetSourceAddressTokenKeys(const std::vector<std::string>& keys); | 
|  |  | 
|  | // Get the server config ids for all known configs. | 
|  | void GetConfigIds(std::vector<std::string>* scids) const; | 
|  |  | 
|  | // Checks |client_hello| for gross errors and determines whether it can be | 
|  | // shown to be fresh (i.e. not a replay).  The result of the validation step | 
|  | // must be interpreted by calling QuicCryptoServerConfig::ProcessClientHello | 
|  | // from the done_cb. | 
|  | // | 
|  | // ValidateClientHello may invoke the done_cb before unrolling the | 
|  | // stack if it is able to assess the validity of the client_nonce | 
|  | // without asynchronous operations. | 
|  | // | 
|  | // client_hello: the incoming client hello message. | 
|  | // client_ip: the IP address of the client, which is used to generate and | 
|  | //     validate source-address tokens. | 
|  | // server_address: the IP address and port of the server. The IP address and | 
|  | //     port may be used for certificate selection. | 
|  | // version: protocol version used for this connection. | 
|  | // clock: used to validate client nonces and ephemeral keys. | 
|  | // crypto_proof: in/out parameter to which will be written the crypto proof | 
|  | //               used in reply to a proof demand.  The pointed-to-object must | 
|  | //               live until the callback is invoked. | 
|  | // done_cb: single-use callback that accepts an opaque | 
|  | //     ValidatedClientHelloMsg token that holds information about | 
|  | //     the client hello.  The callback will always be called exactly | 
|  | //     once, either under the current call stack, or after the | 
|  | //     completion of an asynchronous operation. | 
|  | void ValidateClientHello( | 
|  | const CryptoHandshakeMessage& client_hello, | 
|  | const QuicIpAddress& client_ip, | 
|  | const QuicSocketAddress& server_address, | 
|  | QuicTransportVersion version, | 
|  | const QuicClock* clock, | 
|  | QuicReferenceCountedPointer<QuicSignedServerConfig> crypto_proof, | 
|  | std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const; | 
|  |  | 
|  | // ProcessClientHello processes |client_hello| and decides whether to accept | 
|  | // or reject the connection. If the connection is to be accepted, |done_cb| is | 
|  | // invoked with the contents of the ServerHello and QUIC_NO_ERROR. Otherwise | 
|  | // |done_cb| is called with a REJ or SREJ message and QUIC_NO_ERROR. | 
|  | // | 
|  | // validate_chlo_result: Output from the asynchronous call to | 
|  | //     ValidateClientHello.  Contains the client hello message and | 
|  | //     information about it. | 
|  | // reject_only: Only generate rejections, not server hello messages. | 
|  | // connection_id: the ConnectionId for the connection, which is used in key | 
|  | //     derivation. | 
|  | // server_ip: the IP address of the server. The IP address may be used for | 
|  | //     certificate selection. | 
|  | // client_address: the IP address and port of the client. The IP address is | 
|  | //     used to generate and validate source-address tokens. | 
|  | // version: version of the QUIC protocol in use for this connection | 
|  | // supported_versions: versions of the QUIC protocol that this server | 
|  | //     supports. | 
|  | // clock: used to validate client nonces and ephemeral keys. | 
|  | // rand: an entropy source | 
|  | // compressed_certs_cache: the cache that caches a set of most recently used | 
|  | //     certs. Owned by QuicDispatcher. | 
|  | // params: the state of the handshake. This may be updated with a server | 
|  | //     nonce when we send a rejection. | 
|  | // crypto_proof: output structure containing the crypto proof used in reply to | 
|  | //     a proof demand. | 
|  | // total_framing_overhead: the total per-packet overhead for a stream frame | 
|  | // chlo_packet_size: the size, in bytes, of the CHLO packet | 
|  | // done_cb: the callback invoked on completion | 
|  | void ProcessClientHello( | 
|  | QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> | 
|  | validate_chlo_result, | 
|  | bool reject_only, | 
|  | QuicConnectionId connection_id, | 
|  | const QuicSocketAddress& server_address, | 
|  | const QuicSocketAddress& client_address, | 
|  | ParsedQuicVersion version, | 
|  | const ParsedQuicVersionVector& supported_versions, | 
|  | const QuicClock* clock, | 
|  | QuicRandom* rand, | 
|  | QuicCompressedCertsCache* compressed_certs_cache, | 
|  | QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params, | 
|  | QuicReferenceCountedPointer<QuicSignedServerConfig> crypto_proof, | 
|  | QuicByteCount total_framing_overhead, | 
|  | QuicByteCount chlo_packet_size, | 
|  | std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const; | 
|  |  | 
|  | // BuildServerConfigUpdateMessage invokes |cb| with a SCUP message containing | 
|  | // the current primary config, an up to date source-address token, and cert | 
|  | // chain and proof in the case of secure QUIC. Passes true to |cb| if the | 
|  | // message was generated successfully, and false otherwise.  This method | 
|  | // assumes ownership of |cb|. | 
|  | // | 
|  | // |cached_network_params| is optional, and can be nullptr. | 
|  | void BuildServerConfigUpdateMessage( | 
|  | QuicTransportVersion version, | 
|  | QuicStringPiece chlo_hash, | 
|  | const SourceAddressTokens& previous_source_address_tokens, | 
|  | const QuicSocketAddress& server_address, | 
|  | const QuicIpAddress& client_ip, | 
|  | const QuicClock* clock, | 
|  | QuicRandom* rand, | 
|  | QuicCompressedCertsCache* compressed_certs_cache, | 
|  | const QuicCryptoNegotiatedParameters& params, | 
|  | const CachedNetworkParameters* cached_network_params, | 
|  | std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const; | 
|  |  | 
|  | // set_replay_protection controls whether replay protection is enabled. If | 
|  | // replay protection is disabled then no strike registers are needed and | 
|  | // frontends can share an orbit value without a shared strike-register. | 
|  | // However, an attacker can duplicate a handshake and cause a client's | 
|  | // request to be processed twice. | 
|  | void set_replay_protection(bool on); | 
|  |  | 
|  | // set_chlo_multiplier specifies the multiple of the CHLO message size | 
|  | // that a REJ message must stay under when the client doesn't present a | 
|  | // valid source-address token. | 
|  | void set_chlo_multiplier(size_t multiplier); | 
|  |  | 
|  | // When sender is allowed to not pad client hello (not standards compliant), | 
|  | // we need to disable the client hello check. | 
|  | void set_validate_chlo_size(bool new_value) { | 
|  | validate_chlo_size_ = new_value; | 
|  | } | 
|  |  | 
|  | // Returns whether the sender is allowed to not pad the client hello. | 
|  | bool validate_chlo_size() const { return validate_chlo_size_; } | 
|  |  | 
|  | // When QUIC is tunneled through some other mechanism, source token validation | 
|  | // may be disabled. Do not disable it if you are not providing other | 
|  | // protection. (|true| protects against UDP amplification attack.). | 
|  | void set_validate_source_address_token(bool new_value) { | 
|  | validate_source_address_token_ = new_value; | 
|  | } | 
|  |  | 
|  | // set_source_address_token_future_secs sets the number of seconds into the | 
|  | // future that source-address tokens will be accepted from. Since | 
|  | // source-address tokens are authenticated, this should only happen if | 
|  | // another, valid server has clock-skew. | 
|  | void set_source_address_token_future_secs(uint32_t future_secs); | 
|  |  | 
|  | // set_source_address_token_lifetime_secs sets the number of seconds that a | 
|  | // source-address token will be valid for. | 
|  | void set_source_address_token_lifetime_secs(uint32_t lifetime_secs); | 
|  |  | 
|  | // set_enable_serving_sct enables or disables serving signed cert timestamp | 
|  | // (RFC6962) in server hello. | 
|  | void set_enable_serving_sct(bool enable_serving_sct); | 
|  |  | 
|  | // Set and take ownership of the callback to invoke on primary config changes. | 
|  | void AcquirePrimaryConfigChangedCb( | 
|  | std::unique_ptr<PrimaryConfigChangedCallback> cb); | 
|  |  | 
|  | // Returns the number of configs this object owns. | 
|  | int NumberOfConfigs() const; | 
|  |  | 
|  | // Callers retain the ownership of |rejection_observer| which must outlive the | 
|  | // config. | 
|  | void set_rejection_observer(RejectionObserver* rejection_observer) { | 
|  | rejection_observer_ = rejection_observer; | 
|  | } | 
|  |  | 
|  | ProofSource* proof_source() const; | 
|  |  | 
|  | SSL_CTX* ssl_ctx() const; | 
|  |  | 
|  | void set_pre_shared_key(QuicStringPiece psk) { | 
|  | pre_shared_key_ = std::string(psk); | 
|  | } | 
|  |  | 
|  | bool pad_rej() const { return pad_rej_; } | 
|  | void set_pad_rej(bool new_value) { pad_rej_ = new_value; } | 
|  |  | 
|  | bool pad_shlo() const { return pad_shlo_; } | 
|  | void set_pad_shlo(bool new_value) { pad_shlo_ = new_value; } | 
|  |  | 
|  | private: | 
|  | friend class test::QuicCryptoServerConfigPeer; | 
|  | friend struct QuicSignedServerConfig; | 
|  |  | 
|  | // Config represents a server config: a collection of preferences and | 
|  | // Diffie-Hellman public values. | 
|  | class QUIC_EXPORT_PRIVATE Config : public QuicCryptoConfig, | 
|  | public QuicReferenceCounted { | 
|  | public: | 
|  | Config(); | 
|  | Config(const Config&) = delete; | 
|  | Config& operator=(const Config&) = delete; | 
|  |  | 
|  | // TODO(rtenneti): since this is a class, we should probably do | 
|  | // getters/setters here. | 
|  | // |serialized| contains the bytes of this server config, suitable for | 
|  | // sending on the wire. | 
|  | std::string serialized; | 
|  | // id contains the SCID of this server config. | 
|  | std::string id; | 
|  | // orbit contains the orbit value for this config: an opaque identifier | 
|  | // used to identify clusters of server frontends. | 
|  | unsigned char orbit[kOrbitSize]; | 
|  |  | 
|  | // key_exchanges contains key exchange objects. The values correspond, | 
|  | // one-to-one, with the tags in |kexs| from the parent class. | 
|  | std::vector<std::unique_ptr<AsynchronousKeyExchange>> key_exchanges; | 
|  |  | 
|  | // tag_value_map contains the raw key/value pairs for the config. | 
|  | QuicTagValueMap tag_value_map; | 
|  |  | 
|  | // channel_id_enabled is true if the config in |serialized| specifies that | 
|  | // ChannelIDs are supported. | 
|  | bool channel_id_enabled; | 
|  |  | 
|  | // is_primary is true if this config is the one that we'll give out to | 
|  | // clients as the current one. | 
|  | bool is_primary; | 
|  |  | 
|  | // primary_time contains the timestamp when this config should become the | 
|  | // primary config. A value of QuicWallTime::Zero() means that this config | 
|  | // will not be promoted at a specific time. | 
|  | QuicWallTime primary_time; | 
|  |  | 
|  | // expiry_time contains the timestamp when this config expires. | 
|  | QuicWallTime expiry_time; | 
|  |  | 
|  | // Secondary sort key for use when selecting primary configs and | 
|  | // there are multiple configs with the same primary time. | 
|  | // Smaller numbers mean higher priority. | 
|  | uint64_t priority; | 
|  |  | 
|  | // source_address_token_boxer_ is used to protect the | 
|  | // source-address tokens that are given to clients. | 
|  | // Points to either source_address_token_boxer_storage or the | 
|  | // default boxer provided by QuicCryptoServerConfig. | 
|  | const CryptoSecretBoxer* source_address_token_boxer; | 
|  |  | 
|  | // Holds the override source_address_token_boxer instance if the | 
|  | // Config is not using the default source address token boxer | 
|  | // instance provided by QuicCryptoServerConfig. | 
|  | std::unique_ptr<CryptoSecretBoxer> source_address_token_boxer_storage; | 
|  |  | 
|  | private: | 
|  | ~Config() override; | 
|  | }; | 
|  |  | 
|  | typedef std::map<ServerConfigID, QuicReferenceCountedPointer<Config>> | 
|  | ConfigMap; | 
|  |  | 
|  | // Get a ref to the config with a given server config id. | 
|  | QuicReferenceCountedPointer<Config> GetConfigWithScid( | 
|  | QuicStringPiece requested_scid) const | 
|  | QUIC_SHARED_LOCKS_REQUIRED(configs_lock_); | 
|  |  | 
|  | // A snapshot of the configs associated with an in-progress handshake. | 
|  | struct QUIC_EXPORT_PRIVATE Configs { | 
|  | QuicReferenceCountedPointer<Config> requested; | 
|  | QuicReferenceCountedPointer<Config> primary; | 
|  | QuicReferenceCountedPointer<Config> fallback; | 
|  | }; | 
|  |  | 
|  | // Get a snapshot of the current configs associated with a handshake.  If this | 
|  | // method was called earlier in this handshake |old_primary_config| should be | 
|  | // set to the primary config returned from that invocation, otherwise nullptr. | 
|  | // | 
|  | // Returns true if any configs are loaded.  If false is returned, |configs| is | 
|  | // not modified. | 
|  | bool GetCurrentConfigs(const QuicWallTime& now, | 
|  | QuicStringPiece requested_scid, | 
|  | QuicReferenceCountedPointer<Config> old_primary_config, | 
|  | Configs* configs) const; | 
|  |  | 
|  | // ConfigPrimaryTimeLessThan returns true if a->primary_time < | 
|  | // b->primary_time. | 
|  | static bool ConfigPrimaryTimeLessThan( | 
|  | const QuicReferenceCountedPointer<Config>& a, | 
|  | const QuicReferenceCountedPointer<Config>& b); | 
|  |  | 
|  | // SelectNewPrimaryConfig reevaluates the primary config based on the | 
|  | // "primary_time" deadlines contained in each. | 
|  | void SelectNewPrimaryConfig(QuicWallTime now) const | 
|  | QUIC_EXCLUSIVE_LOCKS_REQUIRED(configs_lock_); | 
|  |  | 
|  | // EvaluateClientHello checks |client_hello_state->client_hello| for gross | 
|  | // errors and determines whether it is fresh (i.e. not a replay). The results | 
|  | // are written to |client_hello_state->info|. | 
|  | void EvaluateClientHello( | 
|  | const QuicSocketAddress& server_address, | 
|  | QuicTransportVersion version, | 
|  | const Configs& configs, | 
|  | QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> | 
|  | client_hello_state, | 
|  | std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const; | 
|  |  | 
|  | // Convenience class which carries the arguments passed to | 
|  | // |ProcessClientHellp| along. | 
|  | class QUIC_EXPORT_PRIVATE ProcessClientHelloContext { | 
|  | public: | 
|  | ProcessClientHelloContext( | 
|  | QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> | 
|  | validate_chlo_result, | 
|  | bool reject_only, | 
|  | QuicConnectionId connection_id, | 
|  | const QuicSocketAddress& server_address, | 
|  | const QuicSocketAddress& client_address, | 
|  | ParsedQuicVersion version, | 
|  | const ParsedQuicVersionVector& supported_versions, | 
|  | const QuicClock* clock, | 
|  | QuicRandom* rand, | 
|  | QuicCompressedCertsCache* compressed_certs_cache, | 
|  | QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params, | 
|  | QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config, | 
|  | QuicByteCount total_framing_overhead, | 
|  | QuicByteCount chlo_packet_size, | 
|  | std::unique_ptr<ProcessClientHelloResultCallback> done_cb) | 
|  | : validate_chlo_result_(validate_chlo_result), | 
|  | reject_only_(reject_only), | 
|  | connection_id_(connection_id), | 
|  | server_address_(server_address), | 
|  | client_address_(client_address), | 
|  | version_(version), | 
|  | supported_versions_(supported_versions), | 
|  | clock_(clock), | 
|  | rand_(rand), | 
|  | compressed_certs_cache_(compressed_certs_cache), | 
|  | params_(params), | 
|  | signed_config_(signed_config), | 
|  | total_framing_overhead_(total_framing_overhead), | 
|  | chlo_packet_size_(chlo_packet_size), | 
|  | done_cb_(std::move(done_cb)) {} | 
|  |  | 
|  | ~ProcessClientHelloContext(); | 
|  |  | 
|  | // Invoke |done_cb_| with an error status | 
|  | void Fail(QuicErrorCode error, const std::string& error_details); | 
|  |  | 
|  | // Invoke |done_cb_| with a success status | 
|  | void Succeed(std::unique_ptr<CryptoHandshakeMessage> message, | 
|  | std::unique_ptr<DiversificationNonce> diversification_nonce, | 
|  | std::unique_ptr<ProofSource::Details> proof_source_details); | 
|  |  | 
|  | // Member accessors | 
|  | QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> | 
|  | validate_chlo_result() const { | 
|  | return validate_chlo_result_; | 
|  | } | 
|  | bool reject_only() const { return reject_only_; } | 
|  | QuicConnectionId connection_id() const { return connection_id_; } | 
|  | QuicSocketAddress server_address() const { return server_address_; } | 
|  | QuicSocketAddress client_address() const { return client_address_; } | 
|  | ParsedQuicVersion version() const { return version_; } | 
|  | ParsedQuicVersionVector supported_versions() const { | 
|  | return supported_versions_; | 
|  | } | 
|  | const QuicClock* clock() const { return clock_; } | 
|  | QuicRandom* rand() const { return rand_; }  // NOLINT | 
|  | QuicCompressedCertsCache* compressed_certs_cache() const { | 
|  | return compressed_certs_cache_; | 
|  | } | 
|  | QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params() const { | 
|  | return params_; | 
|  | } | 
|  | QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config() const { | 
|  | return signed_config_; | 
|  | } | 
|  | QuicByteCount total_framing_overhead() const { | 
|  | return total_framing_overhead_; | 
|  | } | 
|  | QuicByteCount chlo_packet_size() const { return chlo_packet_size_; } | 
|  |  | 
|  | // Derived value accessors | 
|  | const CryptoHandshakeMessage& client_hello() const { | 
|  | return validate_chlo_result()->client_hello; | 
|  | } | 
|  | const ClientHelloInfo& info() const { return validate_chlo_result()->info; } | 
|  | QuicTransportVersion transport_version() const { | 
|  | return version().transport_version; | 
|  | } | 
|  |  | 
|  | private: | 
|  | const QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> | 
|  | validate_chlo_result_; | 
|  | const bool reject_only_; | 
|  | const QuicConnectionId connection_id_; | 
|  | const QuicSocketAddress server_address_; | 
|  | const QuicSocketAddress client_address_; | 
|  | const ParsedQuicVersion version_; | 
|  | const ParsedQuicVersionVector supported_versions_; | 
|  | const QuicClock* const clock_; | 
|  | QuicRandom* const rand_; | 
|  | QuicCompressedCertsCache* const compressed_certs_cache_; | 
|  | const QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_; | 
|  | const QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_; | 
|  | const QuicByteCount total_framing_overhead_; | 
|  | const QuicByteCount chlo_packet_size_; | 
|  | std::unique_ptr<ProcessClientHelloResultCallback> done_cb_; | 
|  | }; | 
|  |  | 
|  | // Callback class for bridging between ProcessClientHello and | 
|  | // ProcessClientHelloAfterGetProof. | 
|  | class ProcessClientHelloCallback; | 
|  | friend class ProcessClientHelloCallback; | 
|  |  | 
|  | // Portion of ProcessClientHello which executes after GetProof. | 
|  | void ProcessClientHelloAfterGetProof( | 
|  | bool found_error, | 
|  | std::unique_ptr<ProofSource::Details> proof_source_details, | 
|  | std::unique_ptr<ProcessClientHelloContext> context, | 
|  | const Configs& configs) const; | 
|  |  | 
|  | // Callback class for bridging between ProcessClientHelloAfterGetProof and | 
|  | // ProcessClientHelloAfterCalculateSharedKeys. | 
|  | class ProcessClientHelloAfterGetProofCallback; | 
|  | friend class ProcessClientHelloAfterGetProofCallback; | 
|  |  | 
|  | // Portion of ProcessClientHello which executes after CalculateSharedKeys. | 
|  | void ProcessClientHelloAfterCalculateSharedKeys( | 
|  | bool found_error, | 
|  | std::unique_ptr<ProofSource::Details> proof_source_details, | 
|  | QuicTag key_exchange_type, | 
|  | std::unique_ptr<CryptoHandshakeMessage> out, | 
|  | QuicStringPiece public_value, | 
|  | std::unique_ptr<ProcessClientHelloContext> context, | 
|  | const Configs& configs) const; | 
|  |  | 
|  | // Send a REJ which contains a different ServerConfig than the one the client | 
|  | // originally used.  This is necessary in cases where we discover in the | 
|  | // middle of the handshake that the private key for the ServerConfig the | 
|  | // client used is not accessible. | 
|  | void SendRejectWithFallbackConfig( | 
|  | std::unique_ptr<ProcessClientHelloContext> context, | 
|  | QuicReferenceCountedPointer<Config> fallback_config) const; | 
|  |  | 
|  | // Callback class for bridging between SendRejectWithFallbackConfig and | 
|  | // SendRejectWithFallbackConfigAfterGetProof. | 
|  | class SendRejectWithFallbackConfigCallback; | 
|  | friend class SendRejectWithFallbackConfigCallback; | 
|  |  | 
|  | // Portion of ProcessClientHello which executes after GetProof in the case | 
|  | // where we have received a CHLO but need to reject it due to the ServerConfig | 
|  | // private keys being inaccessible. | 
|  | void SendRejectWithFallbackConfigAfterGetProof( | 
|  | bool found_error, | 
|  | std::unique_ptr<ProofSource::Details> proof_source_details, | 
|  | std::unique_ptr<ProcessClientHelloContext> context, | 
|  | QuicReferenceCountedPointer<Config> fallback_config) const; | 
|  |  | 
|  | // BuildRejectionAndRecordStats calls |BuildRejection| below and also informs | 
|  | // the RejectionObserver. | 
|  | void BuildRejectionAndRecordStats(const ProcessClientHelloContext& context, | 
|  | const Config& config, | 
|  | const std::vector<uint32_t>& reject_reasons, | 
|  | CryptoHandshakeMessage* out) const; | 
|  |  | 
|  | // BuildRejection sets |out| to be a REJ message in reply to |client_hello|. | 
|  | void BuildRejection(const ProcessClientHelloContext& context, | 
|  | const Config& config, | 
|  | const std::vector<uint32_t>& reject_reasons, | 
|  | CryptoHandshakeMessage* out) const; | 
|  |  | 
|  | // CompressChain compresses the certificates in |chain->certs| and returns a | 
|  | // compressed representation. |common_sets| contains the common certificate | 
|  | // sets known locally and |client_common_set_hashes| contains the hashes of | 
|  | // the common sets known to the peer. |client_cached_cert_hashes| contains | 
|  | // 64-bit, FNV-1a hashes of certificates that the peer already possesses. | 
|  | static std::string CompressChain( | 
|  | QuicCompressedCertsCache* compressed_certs_cache, | 
|  | const QuicReferenceCountedPointer<ProofSource::Chain>& chain, | 
|  | const std::string& client_common_set_hashes, | 
|  | const std::string& client_cached_cert_hashes, | 
|  | const CommonCertSets* common_sets); | 
|  |  | 
|  | // ParseConfigProtobuf parses the given config protobuf and returns a | 
|  | // QuicReferenceCountedPointer<Config> if successful. The caller adopts the | 
|  | // reference to the Config. On error, ParseConfigProtobuf returns nullptr. | 
|  | QuicReferenceCountedPointer<Config> ParseConfigProtobuf( | 
|  | const QuicServerConfigProtobuf& protobuf, | 
|  | bool is_fallback) const; | 
|  |  | 
|  | // NewSourceAddressToken returns a fresh source address token for the given | 
|  | // IP address. |cached_network_params| is optional, and can be nullptr. | 
|  | std::string NewSourceAddressToken( | 
|  | const Config& config, | 
|  | const SourceAddressTokens& previous_tokens, | 
|  | const QuicIpAddress& ip, | 
|  | QuicRandom* rand, | 
|  | QuicWallTime now, | 
|  | const CachedNetworkParameters* cached_network_params) const; | 
|  |  | 
|  | // ParseSourceAddressToken parses the source address tokens contained in | 
|  | // the encrypted |token|, and populates |tokens| with the parsed tokens. | 
|  | // Returns HANDSHAKE_OK if |token| could be parsed, or the reason for the | 
|  | // failure. | 
|  | HandshakeFailureReason ParseSourceAddressToken( | 
|  | const Config& config, | 
|  | QuicStringPiece token, | 
|  | SourceAddressTokens* tokens) const; | 
|  |  | 
|  | // ValidateSourceAddressTokens returns HANDSHAKE_OK if the source address | 
|  | // tokens in |tokens| contain a valid and timely token for the IP address | 
|  | // |ip| given that the current time is |now|. Otherwise it returns the | 
|  | // reason for failure. |cached_network_params| is populated if the valid | 
|  | // token contains a CachedNetworkParameters proto. | 
|  | HandshakeFailureReason ValidateSourceAddressTokens( | 
|  | const SourceAddressTokens& tokens, | 
|  | const QuicIpAddress& ip, | 
|  | QuicWallTime now, | 
|  | CachedNetworkParameters* cached_network_params) const; | 
|  |  | 
|  | // ValidateSingleSourceAddressToken returns HANDSHAKE_OK if the source | 
|  | // address token in |token| is a timely token for the IP address |ip| | 
|  | // given that the current time is |now|. Otherwise it returns the reason | 
|  | // for failure. | 
|  | HandshakeFailureReason ValidateSingleSourceAddressToken( | 
|  | const SourceAddressToken& token, | 
|  | const QuicIpAddress& ip, | 
|  | QuicWallTime now) const; | 
|  |  | 
|  | // Returns HANDSHAKE_OK if the source address token in |token| is a timely | 
|  | // token given that the current time is |now|. Otherwise it returns the | 
|  | // reason for failure. | 
|  | HandshakeFailureReason ValidateSourceAddressTokenTimestamp( | 
|  | const SourceAddressToken& token, | 
|  | QuicWallTime now) const; | 
|  |  | 
|  | // NewServerNonce generates and encrypts a random nonce. | 
|  | std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const; | 
|  |  | 
|  | // ValidateExpectedLeafCertificate checks the |client_hello| to see if it has | 
|  | // an XLCT tag, and if so, verifies that its value matches the hash of the | 
|  | // server's leaf certificate. |certs| is used to compare against the XLCT | 
|  | // value.  This method returns true if the XLCT tag is not present, or if the | 
|  | // XLCT tag is present and valid. It returns false otherwise. | 
|  | bool ValidateExpectedLeafCertificate( | 
|  | const CryptoHandshakeMessage& client_hello, | 
|  | const std::vector<std::string>& certs) const; | 
|  |  | 
|  | // Callback to receive the results of ProofSource::GetProof.  Note: this | 
|  | // callback has no cancellation support, since the lifetime of the ProofSource | 
|  | // is controlled by this object via unique ownership.  If that ownership | 
|  | // stricture changes, this decision may need to be revisited. | 
|  | class BuildServerConfigUpdateMessageProofSourceCallback | 
|  | : public ProofSource::Callback { | 
|  | public: | 
|  | BuildServerConfigUpdateMessageProofSourceCallback( | 
|  | const BuildServerConfigUpdateMessageProofSourceCallback&) = delete; | 
|  | ~BuildServerConfigUpdateMessageProofSourceCallback() override; | 
|  | void operator=(const BuildServerConfigUpdateMessageProofSourceCallback&) = | 
|  | delete; | 
|  | BuildServerConfigUpdateMessageProofSourceCallback( | 
|  | const QuicCryptoServerConfig* config, | 
|  | QuicCompressedCertsCache* compressed_certs_cache, | 
|  | const CommonCertSets* common_cert_sets, | 
|  | const QuicCryptoNegotiatedParameters& params, | 
|  | CryptoHandshakeMessage message, | 
|  | std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb); | 
|  |  | 
|  | void Run(bool ok, | 
|  | const QuicReferenceCountedPointer<ProofSource::Chain>& chain, | 
|  | const QuicCryptoProof& proof, | 
|  | std::unique_ptr<ProofSource::Details> details) override; | 
|  |  | 
|  | private: | 
|  | const QuicCryptoServerConfig* config_; | 
|  | QuicCompressedCertsCache* compressed_certs_cache_; | 
|  | const CommonCertSets* common_cert_sets_; | 
|  | const std::string client_common_set_hashes_; | 
|  | const std::string client_cached_cert_hashes_; | 
|  | const bool sct_supported_by_client_; | 
|  | const std::string sni_; | 
|  | CryptoHandshakeMessage message_; | 
|  | std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb_; | 
|  | }; | 
|  |  | 
|  | // Invoked by BuildServerConfigUpdateMessageProofSourceCallback::Run once | 
|  | // the proof has been acquired.  Finishes building the server config update | 
|  | // message and invokes |cb|. | 
|  | void FinishBuildServerConfigUpdateMessage( | 
|  | QuicCompressedCertsCache* compressed_certs_cache, | 
|  | const CommonCertSets* common_cert_sets, | 
|  | const std::string& client_common_set_hashes, | 
|  | const std::string& client_cached_cert_hashes, | 
|  | bool sct_supported_by_client, | 
|  | const std::string& sni, | 
|  | bool ok, | 
|  | const QuicReferenceCountedPointer<ProofSource::Chain>& chain, | 
|  | const std::string& signature, | 
|  | const std::string& leaf_cert_sct, | 
|  | std::unique_ptr<ProofSource::Details> details, | 
|  | CryptoHandshakeMessage message, | 
|  | std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const; | 
|  |  | 
|  | // Returns true if the next config promotion should happen now. | 
|  | bool IsNextConfigReady(QuicWallTime now) const | 
|  | QUIC_SHARED_LOCKS_REQUIRED(configs_lock_); | 
|  |  | 
|  | // replay_protection_ controls whether the server enforces that handshakes | 
|  | // aren't replays. | 
|  | bool replay_protection_; | 
|  |  | 
|  | // The multiple of the CHLO message size that a REJ message must stay under | 
|  | // when the client doesn't present a valid source-address token. This is | 
|  | // used to protect QUIC from amplification attacks. | 
|  | size_t chlo_multiplier_; | 
|  |  | 
|  | // configs_ satisfies the following invariants: | 
|  | //   1) configs_.empty() <-> primary_config_ == nullptr | 
|  | //   2) primary_config_ != nullptr -> primary_config_->is_primary | 
|  | //   3) ∀ c∈configs_, c->is_primary <-> c == primary_config_ | 
|  | mutable QuicMutex configs_lock_; | 
|  |  | 
|  | // configs_ contains all active server configs. It's expected that there are | 
|  | // about half-a-dozen configs active at any one time. | 
|  | ConfigMap configs_ QUIC_GUARDED_BY(configs_lock_); | 
|  |  | 
|  | // primary_config_ points to a Config (which is also in |configs_|) which is | 
|  | // the primary config - i.e. the one that we'll give out to new clients. | 
|  | mutable QuicReferenceCountedPointer<Config> primary_config_ | 
|  | QUIC_GUARDED_BY(configs_lock_); | 
|  |  | 
|  | // fallback_config_ points to a Config (which is also in |configs_|) which is | 
|  | // the fallback config, which will be used if the other configs are unuseable | 
|  | // for some reason. | 
|  | // | 
|  | // TODO(b/112548056): This is currently always nullptr. | 
|  | QuicReferenceCountedPointer<Config> fallback_config_ | 
|  | QUIC_GUARDED_BY(configs_lock_); | 
|  |  | 
|  | // next_config_promotion_time_ contains the nearest, future time when an | 
|  | // active config will be promoted to primary. | 
|  | mutable QuicWallTime next_config_promotion_time_ | 
|  | QUIC_GUARDED_BY(configs_lock_); | 
|  |  | 
|  | // Callback to invoke when the primary config changes. | 
|  | std::unique_ptr<PrimaryConfigChangedCallback> primary_config_changed_cb_ | 
|  | QUIC_GUARDED_BY(configs_lock_); | 
|  |  | 
|  | // Used to protect the source-address tokens that are given to clients. | 
|  | CryptoSecretBoxer source_address_token_boxer_; | 
|  |  | 
|  | // server_nonce_boxer_ is used to encrypt and validate suggested server | 
|  | // nonces. | 
|  | CryptoSecretBoxer server_nonce_boxer_; | 
|  |  | 
|  | // server_nonce_orbit_ contains the random, per-server orbit values that this | 
|  | // server will use to generate server nonces (the moral equivalent of a SYN | 
|  | // cookies). | 
|  | uint8_t server_nonce_orbit_[8]; | 
|  |  | 
|  | // proof_source_ contains an object that can provide certificate chains and | 
|  | // signatures. | 
|  | std::unique_ptr<ProofSource> proof_source_; | 
|  |  | 
|  | // key_exchange_source_ contains an object that can provide key exchange | 
|  | // objects. | 
|  | std::unique_ptr<KeyExchangeSource> key_exchange_source_; | 
|  |  | 
|  | // ssl_ctx_ contains the server configuration for doing TLS handshakes. | 
|  | bssl::UniquePtr<SSL_CTX> ssl_ctx_; | 
|  |  | 
|  | // These fields store configuration values. See the comments for their | 
|  | // respective setter functions. | 
|  | uint32_t source_address_token_future_secs_; | 
|  | uint32_t source_address_token_lifetime_secs_; | 
|  |  | 
|  | // Enable serving SCT or not. | 
|  | bool enable_serving_sct_; | 
|  |  | 
|  | // Does not own this observer. | 
|  | RejectionObserver* rejection_observer_; | 
|  |  | 
|  | // If non-empty, the server will operate in the pre-shared key mode by | 
|  | // incorporating |pre_shared_key_| into the key schedule. | 
|  | std::string pre_shared_key_; | 
|  |  | 
|  | // Whether REJ message should be padded to max packet size. | 
|  | bool pad_rej_; | 
|  |  | 
|  | // Whether SHLO message should be padded to max packet size. | 
|  | bool pad_shlo_; | 
|  |  | 
|  | // If client is allowed to send a small client hello (by disabling padding), | 
|  | // server MUST not check for the client hello size. | 
|  | // DO NOT disable this unless you have some other way of validating client. | 
|  | // (e.g. in realtime scenarios, where quic is tunneled through ICE, ICE will | 
|  | // do its own peer validation using STUN pings with ufrag/upass). | 
|  | bool validate_chlo_size_; | 
|  |  | 
|  | // When source address is validated by some other means (e.g. when using ICE), | 
|  | // source address token validation may be disabled. | 
|  | bool validate_source_address_token_; | 
|  | }; | 
|  |  | 
|  | struct QUIC_EXPORT_PRIVATE QuicSignedServerConfig | 
|  | : public QuicReferenceCounted { | 
|  | QuicSignedServerConfig(); | 
|  |  | 
|  | QuicCryptoProof proof; | 
|  | QuicReferenceCountedPointer<ProofSource::Chain> chain; | 
|  | // The server config that is used for this proof (and the rest of the | 
|  | // request). | 
|  | QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> config; | 
|  | std::string primary_scid; | 
|  |  | 
|  | protected: | 
|  | ~QuicSignedServerConfig() override; | 
|  | }; | 
|  |  | 
|  | }  // namespace quic | 
|  |  | 
|  | #endif  // QUICHE_QUIC_CORE_CRYPTO_QUIC_CRYPTO_SERVER_CONFIG_H_ |