#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
#include <algorithm>
#include <cstdlib>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "absl/base/attributes.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "openssl/sha.h"
#include "openssl/ssl.h"
#include "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
#include "quiche/quic/core/crypto/cert_compressor.h"
#include "quiche/quic/core/crypto/certificate_view.h"
#include "quiche/quic/core/crypto/chacha20_poly1305_encrypter.h"
#include "quiche/quic/core/crypto/channel_id.h"
#include "quiche/quic/core/crypto/crypto_framer.h"
#include "quiche/quic/core/crypto/crypto_handshake_message.h"
#include "quiche/quic/core/crypto/crypto_utils.h"
#include "quiche/quic/core/crypto/curve25519_key_exchange.h"
#include "quiche/quic/core/crypto/key_exchange.h"
#include "quiche/quic/core/crypto/p256_key_exchange.h"
#include "quiche/quic/core/crypto/proof_source.h"
#include "quiche/quic/core/crypto/quic_decrypter.h"
#include "quiche/quic/core/crypto/quic_encrypter.h"
#include "quiche/quic/core/crypto/quic_hkdf.h"
#include "quiche/quic/core/crypto/quic_random.h"
#include "quiche/quic/core/crypto/tls_server_connection.h"
#include "quiche/quic/core/proto/crypto_server_config_proto.h"
#include "quiche/quic/core/proto/source_address_token_proto.h"
#include "quiche/quic/core/quic_clock.h"
#include "quiche/quic/core/quic_connection_context.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_socket_address_coder.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_flag_utils.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_hostname_utils.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/platform/api/quic_testvalue.h"
#include "quiche/common/platform/api/quiche_reference_counted.h"
namespace quic {
namespace {
const size_t kMultiplier = …;
const int kMaxTokenAddresses = …;
std::string DeriveSourceAddressTokenKey(
absl::string_view source_address_token_secret) { … }
class DefaultKeyExchangeSource : public KeyExchangeSource { … };
bool ClientDemandsX509Proof(const CryptoHandshakeMessage& client_hello) { … }
std::string FormatCryptoHandshakeMessageForTrace(
const CryptoHandshakeMessage* message) { … }
}
std::unique_ptr<KeyExchangeSource> KeyExchangeSource::Default() { … }
class ValidateClientHelloHelper { … };
const char QuicCryptoServerConfig::TESTING[] = …;
ClientHelloInfo::ClientHelloInfo(const QuicIpAddress& in_client_ip,
QuicWallTime in_now)
: … { … }
ClientHelloInfo::ClientHelloInfo(const ClientHelloInfo& other) = default;
ClientHelloInfo::~ClientHelloInfo() { … }
PrimaryConfigChangedCallback::PrimaryConfigChangedCallback() { … }
PrimaryConfigChangedCallback::~PrimaryConfigChangedCallback() { … }
ValidateClientHelloResultCallback::Result::Result(
const CryptoHandshakeMessage& in_client_hello, QuicIpAddress in_client_ip,
QuicWallTime in_now)
: … { … }
ValidateClientHelloResultCallback::Result::~Result() { … }
ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() { … }
ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() { … }
ProcessClientHelloResultCallback::ProcessClientHelloResultCallback() { … }
ProcessClientHelloResultCallback::~ProcessClientHelloResultCallback() { … }
QuicCryptoServerConfig::ConfigOptions::ConfigOptions()
: … { … }
QuicCryptoServerConfig::ConfigOptions::ConfigOptions(
const ConfigOptions& other) = default;
QuicCryptoServerConfig::ConfigOptions::~ConfigOptions() { … }
QuicCryptoServerConfig::ProcessClientHelloContext::
~ProcessClientHelloContext() { … }
void QuicCryptoServerConfig::ProcessClientHelloContext::Fail(
QuicErrorCode error, const std::string& error_details) { … }
void QuicCryptoServerConfig::ProcessClientHelloContext::Succeed(
std::unique_ptr<CryptoHandshakeMessage> message,
std::unique_ptr<DiversificationNonce> diversification_nonce,
std::unique_ptr<ProofSource::Details> proof_source_details) { … }
QuicCryptoServerConfig::QuicCryptoServerConfig(
absl::string_view source_address_token_secret,
QuicRandom* server_nonce_entropy, std::unique_ptr<ProofSource> proof_source,
std::unique_ptr<KeyExchangeSource> key_exchange_source)
: … { … }
QuicCryptoServerConfig::~QuicCryptoServerConfig() { … }
QuicServerConfigProtobuf QuicCryptoServerConfig::GenerateConfig(
QuicRandom* rand, const QuicClock* clock, const ConfigOptions& options) { … }
std::unique_ptr<CryptoHandshakeMessage> QuicCryptoServerConfig::AddConfig(
const QuicServerConfigProtobuf& protobuf, const QuicWallTime now) { … }
std::unique_ptr<CryptoHandshakeMessage>
QuicCryptoServerConfig::AddDefaultConfig(QuicRandom* rand,
const QuicClock* clock,
const ConfigOptions& options) { … }
bool QuicCryptoServerConfig::SetConfigs(
const std::vector<QuicServerConfigProtobuf>& protobufs,
const QuicServerConfigProtobuf* fallback_protobuf, const QuicWallTime now) { … }
void QuicCryptoServerConfig::SetSourceAddressTokenKeys(
const std::vector<std::string>& keys) { … }
std::vector<std::string> QuicCryptoServerConfig::GetConfigIds() const { … }
void QuicCryptoServerConfig::ValidateClientHello(
const CryptoHandshakeMessage& client_hello,
const QuicSocketAddress& client_address,
const QuicSocketAddress& server_address, QuicTransportVersion version,
const QuicClock* clock,
quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { … }
class QuicCryptoServerConfig::ProcessClientHelloCallback
: public ProofSource::Callback { … };
class QuicCryptoServerConfig::ProcessClientHelloAfterGetProofCallback
: public AsynchronousKeyExchange::Callback { … };
class QuicCryptoServerConfig::SendRejectWithFallbackConfigCallback
: public ProofSource::Callback { … };
void QuicCryptoServerConfig::ProcessClientHello(
quiche::QuicheReferenceCountedPointer<
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,
quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
params,
quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
QuicByteCount total_framing_overhead, QuicByteCount chlo_packet_size,
std::shared_ptr<ProcessClientHelloResultCallback> done_cb) const { … }
void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof(
bool found_error,
std::unique_ptr<ProofSource::Details> proof_source_details,
std::unique_ptr<ProcessClientHelloContext> context,
const Configs& configs) const { … }
void QuicCryptoServerConfig::ProcessClientHelloAfterCalculateSharedKeys(
bool found_error,
std::unique_ptr<ProofSource::Details> proof_source_details,
QuicTag key_exchange_type, std::unique_ptr<CryptoHandshakeMessage> out,
absl::string_view public_value,
std::unique_ptr<ProcessClientHelloContext> context,
const Configs& configs) const { … }
void QuicCryptoServerConfig::SendRejectWithFallbackConfig(
std::unique_ptr<ProcessClientHelloContext> context,
quiche::QuicheReferenceCountedPointer<Config> fallback_config) const { … }
void QuicCryptoServerConfig::SendRejectWithFallbackConfigAfterGetProof(
bool found_error,
std::unique_ptr<ProofSource::Details> proof_source_details,
std::unique_ptr<ProcessClientHelloContext> context,
quiche::QuicheReferenceCountedPointer<Config> fallback_config) const { … }
quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
QuicCryptoServerConfig::GetConfigWithScid(
absl::string_view requested_scid) const { … }
bool QuicCryptoServerConfig::GetCurrentConfigs(
const QuicWallTime& now, absl::string_view requested_scid,
quiche::QuicheReferenceCountedPointer<Config> old_primary_config,
Configs* configs) const { … }
bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan(
const quiche::QuicheReferenceCountedPointer<Config>& a,
const quiche::QuicheReferenceCountedPointer<Config>& b) { … }
void QuicCryptoServerConfig::SelectNewPrimaryConfig(
const QuicWallTime now) const { … }
void QuicCryptoServerConfig::EvaluateClientHello(
const QuicSocketAddress& ,
const QuicSocketAddress& ,
QuicTransportVersion , const Configs& configs,
quiche::QuicheReferenceCountedPointer<
ValidateClientHelloResultCallback::Result>
client_hello_state,
std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { … }
void QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
QuicTransportVersion version, absl::string_view chlo_hash,
const SourceAddressTokens& previous_source_address_tokens,
const QuicSocketAddress& server_address,
const QuicSocketAddress& client_address, const QuicClock* clock,
QuicRandom* rand, QuicCompressedCertsCache* compressed_certs_cache,
const QuicCryptoNegotiatedParameters& params,
const CachedNetworkParameters* cached_network_params,
std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const { … }
QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
~BuildServerConfigUpdateMessageProofSourceCallback() { … }
QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
BuildServerConfigUpdateMessageProofSourceCallback(
const QuicCryptoServerConfig* config,
QuicCompressedCertsCache* compressed_certs_cache,
const QuicCryptoNegotiatedParameters& params,
CryptoHandshakeMessage message,
std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb)
: … { … }
void QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback::
Run(bool ok,
const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
const QuicCryptoProof& proof,
std::unique_ptr<ProofSource::Details> details) { … }
void QuicCryptoServerConfig::FinishBuildServerConfigUpdateMessage(
QuicCompressedCertsCache* compressed_certs_cache,
const std::string& client_cached_cert_hashes, bool sct_supported_by_client,
const std::string& sni, bool ok,
const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
const std::string& signature, const std::string& leaf_cert_sct,
std::unique_ptr<ProofSource::Details> ,
CryptoHandshakeMessage message,
std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const { … }
void QuicCryptoServerConfig::BuildRejectionAndRecordStats(
const ProcessClientHelloContext& context, const Config& config,
const std::vector<uint32_t>& reject_reasons,
CryptoHandshakeMessage* out) const { … }
void QuicCryptoServerConfig::BuildRejection(
const ProcessClientHelloContext& context, const Config& config,
const std::vector<uint32_t>& reject_reasons,
CryptoHandshakeMessage* out) const { … }
std::string QuicCryptoServerConfig::CompressChain(
QuicCompressedCertsCache* compressed_certs_cache,
const quiche::QuicheReferenceCountedPointer<ProofSource::Chain>& chain,
const std::string& client_cached_cert_hashes) { … }
quiche::QuicheReferenceCountedPointer<QuicCryptoServerConfig::Config>
QuicCryptoServerConfig::ParseConfigProtobuf(
const QuicServerConfigProtobuf& protobuf, bool is_fallback) const { … }
void QuicCryptoServerConfig::set_replay_protection(bool on) { … }
void QuicCryptoServerConfig::set_chlo_multiplier(size_t multiplier) { … }
void QuicCryptoServerConfig::set_source_address_token_future_secs(
uint32_t future_secs) { … }
void QuicCryptoServerConfig::set_source_address_token_lifetime_secs(
uint32_t lifetime_secs) { … }
void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) { … }
void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
std::unique_ptr<PrimaryConfigChangedCallback> cb) { … }
std::string QuicCryptoServerConfig::NewSourceAddressToken(
const CryptoSecretBoxer& crypto_secret_boxer,
const SourceAddressTokens& previous_tokens, const QuicIpAddress& ip,
QuicRandom* rand, QuicWallTime now,
const CachedNetworkParameters* cached_network_params) const { … }
int QuicCryptoServerConfig::NumberOfConfigs() const { … }
ProofSource* QuicCryptoServerConfig::proof_source() const { … }
SSL_CTX* QuicCryptoServerConfig::ssl_ctx() const { … }
HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken(
const CryptoSecretBoxer& crypto_secret_boxer, absl::string_view token,
SourceAddressTokens& tokens) const { … }
HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressTokens(
const SourceAddressTokens& source_address_tokens, const QuicIpAddress& ip,
QuicWallTime now, CachedNetworkParameters* cached_network_params) const { … }
HandshakeFailureReason QuicCryptoServerConfig::ValidateSingleSourceAddressToken(
const SourceAddressToken& source_address_token, const QuicIpAddress& ip,
QuicWallTime now) const { … }
HandshakeFailureReason
QuicCryptoServerConfig::ValidateSourceAddressTokenTimestamp(
const SourceAddressToken& source_address_token, QuicWallTime now) const { … }
static const size_t kServerNoncePlaintextSize = … ;
std::string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand,
QuicWallTime now) const { … }
bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate(
const CryptoHandshakeMessage& client_hello,
const std::vector<std::string>& certs) const { … }
bool QuicCryptoServerConfig::IsNextConfigReady(QuicWallTime now) const { … }
QuicCryptoServerConfig::Config::Config()
: … { … }
QuicCryptoServerConfig::Config::~Config() { … }
QuicSignedServerConfig::QuicSignedServerConfig() { … }
QuicSignedServerConfig::~QuicSignedServerConfig() { … }
}