blob: e0a590c3ff6e30b0b09b2806cb1c7b8fbbffcdb4 [file] [log] [blame]
// 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 NET_THIRD_PARTY_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
#define NET_THIRD_PARTY_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_
#include <cstdint>
#include <memory>
#include "base/macros.h"
#include "net/third_party/quic/core/crypto/crypto_handshake.h"
#include "net/third_party/quic/core/crypto/quic_compressed_certs_cache.h"
#include "net/third_party/quic/core/crypto/quic_crypto_server_config.h"
#include "net/third_party/quic/core/quic_config.h"
#include "net/third_party/quic/core/quic_crypto_handshaker.h"
#include "net/third_party/quic/core/quic_crypto_stream.h"
#include "net/third_party/quic/core/quic_session.h"
#include "net/third_party/quic/platform/api/quic_export.h"
#include "net/third_party/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 // NET_THIRD_PARTY_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_