// 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_
