// 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 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 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 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 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
      SHARED_LOCKS_REQUIRED(configs_lock_);

  // A snapshot of the configs associated with an in-progress handshake.
  struct 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
      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 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
      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_ 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_
      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_
      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_ GUARDED_BY(configs_lock_);

  // Callback to invoke when the primary config changes.
  std::unique_ptr<PrimaryConfigChangedCallback> primary_config_changed_cb_
      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_
