Project import generated by Copybara.
PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_crypto_server_stream.h b/quic/core/quic_crypto_server_stream.h
new file mode 100644
index 0000000..53d4b38
--- /dev/null
+++ b/quic/core/quic_crypto_server_stream.h
@@ -0,0 +1,225 @@
+// Copyright (c) 2012 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_QUIC_CRYPTO_SERVER_STREAM_H_
+#define QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
+
+#include <cstdint>
+#include <memory>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.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_server_config.h"
+#include "net/third_party/quiche/src/quic/core/quic_config.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_handshaker.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_session.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+namespace quic {
+
+class CachedNetworkParameters;
+class CryptoHandshakeMessage;
+class QuicCryptoServerConfig;
+class QuicCryptoServerStreamBase;
+
+// TODO(alyssar) see what can be moved out of QuicCryptoServerStream with
+// various code and test refactoring.
+class QUIC_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream {
+ public:
+ explicit QuicCryptoServerStreamBase(QuicSession* session);
+
+ ~QuicCryptoServerStreamBase() override {}
+
+ // Cancel any outstanding callbacks, such as asynchronous validation of client
+ // hello.
+ virtual void CancelOutstandingCallbacks() = 0;
+
+ // GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded,
+ // SHA-256 hash of the client's ChannelID key and returns true, if the client
+ // presented a ChannelID. Otherwise it returns false.
+ virtual bool GetBase64SHA256ClientChannelID(QuicString* output) const = 0;
+
+ virtual int NumServerConfigUpdateMessagesSent() const = 0;
+
+ // Sends the latest server config and source-address token to the client.
+ virtual void SendServerConfigUpdate(
+ const CachedNetworkParameters* cached_network_params) = 0;
+
+ // These are all accessors and setters to their respective counters.
+ virtual uint8_t NumHandshakeMessages() const = 0;
+ virtual uint8_t NumHandshakeMessagesWithServerNonces() const = 0;
+ virtual bool UseStatelessRejectsIfPeerSupported() const = 0;
+ virtual bool PeerSupportsStatelessRejects() const = 0;
+ virtual bool ZeroRttAttempted() const = 0;
+ virtual void SetPeerSupportsStatelessRejects(bool set) = 0;
+ virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
+ const = 0;
+ virtual void SetPreviousCachedNetworkParams(
+ CachedNetworkParameters cached_network_params) = 0;
+
+ // Checks the options on the handshake-message to see whether the
+ // peer supports stateless-rejects.
+ static bool DoesPeerSupportStatelessRejects(
+ const CryptoHandshakeMessage& message);
+};
+
+class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
+ : public QuicCryptoServerStreamBase {
+ public:
+ // QuicCryptoServerStream creates a HandshakerDelegate at construction time
+ // based on the QuicTransportVersion of the connection. Different
+ // HandshakerDelegates provide implementations of different crypto handshake
+ // protocols. Currently QUIC crypto is the only protocol implemented; a future
+ // HandshakerDelegate will use TLS as the handshake protocol.
+ // QuicCryptoServerStream delegates all of its public methods to its
+ // HandshakerDelegate.
+ //
+ // This setup of the crypto stream delegating its implementation to the
+ // handshaker results in the handshaker reading and writing bytes on the
+ // crypto stream, instead of the handshake rpassing the stream bytes to send.
+ class QUIC_EXPORT_PRIVATE HandshakerDelegate {
+ public:
+ virtual ~HandshakerDelegate() {}
+
+ // Cancel any outstanding callbacks, such as asynchronous validation of
+ // client hello.
+ virtual void CancelOutstandingCallbacks() = 0;
+
+ // GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded,
+ // SHA-256 hash of the client's ChannelID key and returns true, if the
+ // client presented a ChannelID. Otherwise it returns false.
+ virtual bool GetBase64SHA256ClientChannelID(QuicString* output) const = 0;
+
+ // Sends the latest server config and source-address token to the client.
+ virtual void SendServerConfigUpdate(
+ const CachedNetworkParameters* cached_network_params) = 0;
+
+ // These are all accessors and setters to their respective counters.
+ virtual uint8_t NumHandshakeMessages() const = 0;
+ virtual uint8_t NumHandshakeMessagesWithServerNonces() const = 0;
+ virtual int NumServerConfigUpdateMessagesSent() const = 0;
+ virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
+ const = 0;
+ virtual bool ZeroRttAttempted() const = 0;
+ virtual void SetPreviousCachedNetworkParams(
+ CachedNetworkParameters cached_network_params) = 0;
+
+ // NOTE: Indicating that the Expect-CT header should be sent here presents a
+ // layering violation to some extent. The Expect-CT header only applies to
+ // HTTP connections, while this class can be used for non-HTTP applications.
+ // However, it is exposed here because that is the only place where the
+ // configuration for the certificate used in the connection is accessible.
+ virtual bool ShouldSendExpectCTHeader() const = 0;
+
+ // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set
+ // for the connection.
+ virtual bool encryption_established() const = 0;
+
+ // Returns true once the crypto handshake has completed.
+ virtual bool handshake_confirmed() const = 0;
+
+ // Returns the parameters negotiated in the crypto handshake.
+ virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+ const = 0;
+
+ // Used by QuicCryptoStream to parse data received on this stream.
+ virtual CryptoMessageParser* crypto_message_parser() = 0;
+ };
+
+ class Helper {
+ public:
+ virtual ~Helper() {}
+
+ // Given the current connection_id, generates a new ConnectionId to
+ // be returned with a stateless reject.
+ virtual QuicConnectionId GenerateConnectionIdForReject(
+ QuicTransportVersion version,
+ QuicConnectionId connection_id) const = 0;
+
+ // Returns true if |message|, which was received on |self_address| is
+ // acceptable according to the visitor's policy. Otherwise, returns false
+ // and populates |error_details|.
+ virtual bool CanAcceptClientHello(const CryptoHandshakeMessage& message,
+ const QuicSocketAddress& client_address,
+ const QuicSocketAddress& peer_address,
+ const QuicSocketAddress& self_address,
+ QuicString* error_details) const = 0;
+ };
+
+ // |crypto_config| must outlive the stream.
+ // |session| must outlive the stream.
+ // |helper| must outlive the stream.
+ QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
+ QuicCompressedCertsCache* compressed_certs_cache,
+ bool use_stateless_rejects_if_peer_supported,
+ QuicSession* session,
+ Helper* helper);
+ QuicCryptoServerStream(const QuicCryptoServerStream&) = delete;
+ QuicCryptoServerStream& operator=(const QuicCryptoServerStream&) = delete;
+
+ ~QuicCryptoServerStream() override;
+
+ // From QuicCryptoServerStreamBase
+ void CancelOutstandingCallbacks() override;
+ bool GetBase64SHA256ClientChannelID(QuicString* output) const override;
+ void SendServerConfigUpdate(
+ const CachedNetworkParameters* cached_network_params) override;
+ uint8_t NumHandshakeMessages() const override;
+ uint8_t NumHandshakeMessagesWithServerNonces() const override;
+ int NumServerConfigUpdateMessagesSent() const override;
+ const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
+ bool UseStatelessRejectsIfPeerSupported() const override;
+ bool PeerSupportsStatelessRejects() const override;
+ bool ZeroRttAttempted() const override;
+ void SetPeerSupportsStatelessRejects(
+ bool peer_supports_stateless_rejects) override;
+ void SetPreviousCachedNetworkParams(
+ CachedNetworkParameters cached_network_params) override;
+
+ // NOTE: Indicating that the Expect-CT header should be sent here presents
+ // a layering violation to some extent. The Expect-CT header only applies to
+ // HTTP connections, while this class can be used for non-HTTP applications.
+ // However, it is exposed here because that is the only place where the
+ // configuration for the certificate used in the connection is accessible.
+ bool ShouldSendExpectCTHeader() const;
+
+ bool encryption_established() const override;
+ bool handshake_confirmed() const override;
+ const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+ const override;
+ CryptoMessageParser* crypto_message_parser() override;
+ void OnSuccessfulVersionNegotiation(
+ const ParsedQuicVersion& version) override;
+
+ protected:
+ // Provided so that subclasses can provide their own handshaker.
+ virtual HandshakerDelegate* handshaker() const;
+
+ private:
+ std::unique_ptr<HandshakerDelegate> handshaker_;
+
+ // If true, the server should use stateless rejects, so long as the
+ // client supports them, as indicated by
+ // peer_supports_stateless_rejects_.
+ bool use_stateless_rejects_if_peer_supported_;
+
+ // Set to true, once the server has received information from the
+ // client that it supports stateless reject.
+ // TODO(jokulik): Remove once client stateless reject support
+ // becomes the default.
+ bool peer_supports_stateless_rejects_;
+
+ // Arguments from QuicCryptoServerStream constructor that might need to be
+ // passed to the HandshakerDelegate constructor in its late construction.
+ const QuicCryptoServerConfig* crypto_config_;
+ QuicCompressedCertsCache* compressed_certs_cache_;
+ Helper* helper_;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_