QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_ |
| 6 | #define QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_ |
| 7 | |
| 8 | #include <cstdint> |
| 9 | #include <memory> |
vasilvv | 872e7a3 | 2019-03-12 16:42:44 -0700 | [diff] [blame] | 10 | #include <string> |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 11 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 12 | #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h" |
| 13 | #include "net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h" |
| 14 | #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h" |
| 15 | #include "net/third_party/quiche/src/quic/core/quic_config.h" |
| 16 | #include "net/third_party/quiche/src/quic/core/quic_crypto_handshaker.h" |
| 17 | #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h" |
| 18 | #include "net/third_party/quiche/src/quic/core/quic_session.h" |
| 19 | #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 20 | |
| 21 | namespace quic { |
| 22 | |
| 23 | class CachedNetworkParameters; |
| 24 | class CryptoHandshakeMessage; |
| 25 | class QuicCryptoServerConfig; |
| 26 | class QuicCryptoServerStreamBase; |
| 27 | |
| 28 | // TODO(alyssar) see what can be moved out of QuicCryptoServerStream with |
| 29 | // various code and test refactoring. |
| 30 | class QUIC_EXPORT_PRIVATE QuicCryptoServerStreamBase : public QuicCryptoStream { |
| 31 | public: |
| 32 | explicit QuicCryptoServerStreamBase(QuicSession* session); |
| 33 | |
| 34 | ~QuicCryptoServerStreamBase() override {} |
| 35 | |
| 36 | // Cancel any outstanding callbacks, such as asynchronous validation of client |
| 37 | // hello. |
| 38 | virtual void CancelOutstandingCallbacks() = 0; |
| 39 | |
| 40 | // GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded, |
| 41 | // SHA-256 hash of the client's ChannelID key and returns true, if the client |
| 42 | // presented a ChannelID. Otherwise it returns false. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 43 | virtual bool GetBase64SHA256ClientChannelID(std::string* output) const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 44 | |
| 45 | virtual int NumServerConfigUpdateMessagesSent() const = 0; |
| 46 | |
| 47 | // Sends the latest server config and source-address token to the client. |
| 48 | virtual void SendServerConfigUpdate( |
| 49 | const CachedNetworkParameters* cached_network_params) = 0; |
| 50 | |
| 51 | // These are all accessors and setters to their respective counters. |
| 52 | virtual uint8_t NumHandshakeMessages() const = 0; |
| 53 | virtual uint8_t NumHandshakeMessagesWithServerNonces() const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 54 | virtual bool ZeroRttAttempted() const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 55 | virtual const CachedNetworkParameters* PreviousCachedNetworkParams() |
| 56 | const = 0; |
| 57 | virtual void SetPreviousCachedNetworkParams( |
| 58 | CachedNetworkParameters cached_network_params) = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 59 | }; |
| 60 | |
| 61 | class QUIC_EXPORT_PRIVATE QuicCryptoServerStream |
| 62 | : public QuicCryptoServerStreamBase { |
| 63 | public: |
| 64 | // QuicCryptoServerStream creates a HandshakerDelegate at construction time |
| 65 | // based on the QuicTransportVersion of the connection. Different |
| 66 | // HandshakerDelegates provide implementations of different crypto handshake |
| 67 | // protocols. Currently QUIC crypto is the only protocol implemented; a future |
| 68 | // HandshakerDelegate will use TLS as the handshake protocol. |
| 69 | // QuicCryptoServerStream delegates all of its public methods to its |
| 70 | // HandshakerDelegate. |
| 71 | // |
| 72 | // This setup of the crypto stream delegating its implementation to the |
| 73 | // handshaker results in the handshaker reading and writing bytes on the |
| 74 | // crypto stream, instead of the handshake rpassing the stream bytes to send. |
| 75 | class QUIC_EXPORT_PRIVATE HandshakerDelegate { |
| 76 | public: |
| 77 | virtual ~HandshakerDelegate() {} |
| 78 | |
| 79 | // Cancel any outstanding callbacks, such as asynchronous validation of |
| 80 | // client hello. |
| 81 | virtual void CancelOutstandingCallbacks() = 0; |
| 82 | |
| 83 | // GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded, |
| 84 | // SHA-256 hash of the client's ChannelID key and returns true, if the |
| 85 | // client presented a ChannelID. Otherwise it returns false. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 86 | virtual bool GetBase64SHA256ClientChannelID(std::string* output) const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 87 | |
| 88 | // Sends the latest server config and source-address token to the client. |
| 89 | virtual void SendServerConfigUpdate( |
| 90 | const CachedNetworkParameters* cached_network_params) = 0; |
| 91 | |
| 92 | // These are all accessors and setters to their respective counters. |
| 93 | virtual uint8_t NumHandshakeMessages() const = 0; |
| 94 | virtual uint8_t NumHandshakeMessagesWithServerNonces() const = 0; |
| 95 | virtual int NumServerConfigUpdateMessagesSent() const = 0; |
| 96 | virtual const CachedNetworkParameters* PreviousCachedNetworkParams() |
| 97 | const = 0; |
| 98 | virtual bool ZeroRttAttempted() const = 0; |
| 99 | virtual void SetPreviousCachedNetworkParams( |
| 100 | CachedNetworkParameters cached_network_params) = 0; |
fayang | d58736d | 2019-11-27 13:35:31 -0800 | [diff] [blame] | 101 | virtual void OnPacketDecrypted(EncryptionLevel level) = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 102 | |
| 103 | // NOTE: Indicating that the Expect-CT header should be sent here presents a |
| 104 | // layering violation to some extent. The Expect-CT header only applies to |
| 105 | // HTTP connections, while this class can be used for non-HTTP applications. |
| 106 | // However, it is exposed here because that is the only place where the |
| 107 | // configuration for the certificate used in the connection is accessible. |
| 108 | virtual bool ShouldSendExpectCTHeader() const = 0; |
| 109 | |
| 110 | // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set |
| 111 | // for the connection. |
| 112 | virtual bool encryption_established() const = 0; |
| 113 | |
| 114 | // Returns true once the crypto handshake has completed. |
| 115 | virtual bool handshake_confirmed() const = 0; |
| 116 | |
| 117 | // Returns the parameters negotiated in the crypto handshake. |
| 118 | virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params() |
| 119 | const = 0; |
| 120 | |
| 121 | // Used by QuicCryptoStream to parse data received on this stream. |
| 122 | virtual CryptoMessageParser* crypto_message_parser() = 0; |
nharper | 486a8a9 | 2019-08-28 16:25:10 -0700 | [diff] [blame] | 123 | |
| 124 | // Used by QuicCryptoStream to know how much unprocessed data can be |
| 125 | // buffered at each encryption level. |
| 126 | virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 127 | }; |
| 128 | |
dschinazi | f25169a | 2019-10-23 08:12:18 -0700 | [diff] [blame] | 129 | class QUIC_EXPORT_PRIVATE Helper { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 130 | public: |
| 131 | virtual ~Helper() {} |
| 132 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 133 | // Returns true if |message|, which was received on |self_address| is |
| 134 | // acceptable according to the visitor's policy. Otherwise, returns false |
| 135 | // and populates |error_details|. |
| 136 | virtual bool CanAcceptClientHello(const CryptoHandshakeMessage& message, |
| 137 | const QuicSocketAddress& client_address, |
| 138 | const QuicSocketAddress& peer_address, |
| 139 | const QuicSocketAddress& self_address, |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 140 | std::string* error_details) const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 141 | }; |
| 142 | |
| 143 | // |crypto_config| must outlive the stream. |
| 144 | // |session| must outlive the stream. |
| 145 | // |helper| must outlive the stream. |
| 146 | QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config, |
| 147 | QuicCompressedCertsCache* compressed_certs_cache, |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 148 | QuicSession* session, |
| 149 | Helper* helper); |
| 150 | QuicCryptoServerStream(const QuicCryptoServerStream&) = delete; |
| 151 | QuicCryptoServerStream& operator=(const QuicCryptoServerStream&) = delete; |
| 152 | |
| 153 | ~QuicCryptoServerStream() override; |
| 154 | |
| 155 | // From QuicCryptoServerStreamBase |
| 156 | void CancelOutstandingCallbacks() override; |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 157 | bool GetBase64SHA256ClientChannelID(std::string* output) const override; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 158 | void SendServerConfigUpdate( |
| 159 | const CachedNetworkParameters* cached_network_params) override; |
| 160 | uint8_t NumHandshakeMessages() const override; |
| 161 | uint8_t NumHandshakeMessagesWithServerNonces() const override; |
| 162 | int NumServerConfigUpdateMessagesSent() const override; |
| 163 | const CachedNetworkParameters* PreviousCachedNetworkParams() const override; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 164 | bool ZeroRttAttempted() const override; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 165 | void SetPreviousCachedNetworkParams( |
| 166 | CachedNetworkParameters cached_network_params) override; |
| 167 | |
| 168 | // NOTE: Indicating that the Expect-CT header should be sent here presents |
| 169 | // a layering violation to some extent. The Expect-CT header only applies to |
| 170 | // HTTP connections, while this class can be used for non-HTTP applications. |
| 171 | // However, it is exposed here because that is the only place where the |
| 172 | // configuration for the certificate used in the connection is accessible. |
| 173 | bool ShouldSendExpectCTHeader() const; |
| 174 | |
| 175 | bool encryption_established() const override; |
| 176 | bool handshake_confirmed() const override; |
| 177 | const QuicCryptoNegotiatedParameters& crypto_negotiated_params() |
| 178 | const override; |
| 179 | CryptoMessageParser* crypto_message_parser() override; |
fayang | d58736d | 2019-11-27 13:35:31 -0800 | [diff] [blame] | 180 | void OnPacketDecrypted(EncryptionLevel level) override; |
nharper | 486a8a9 | 2019-08-28 16:25:10 -0700 | [diff] [blame] | 181 | size_t BufferSizeLimitForLevel(EncryptionLevel level) const override; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 182 | void OnSuccessfulVersionNegotiation( |
| 183 | const ParsedQuicVersion& version) override; |
| 184 | |
| 185 | protected: |
| 186 | // Provided so that subclasses can provide their own handshaker. |
| 187 | virtual HandshakerDelegate* handshaker() const; |
| 188 | |
| 189 | private: |
| 190 | std::unique_ptr<HandshakerDelegate> handshaker_; |
| 191 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 192 | // Arguments from QuicCryptoServerStream constructor that might need to be |
| 193 | // passed to the HandshakerDelegate constructor in its late construction. |
| 194 | const QuicCryptoServerConfig* crypto_config_; |
| 195 | QuicCompressedCertsCache* compressed_certs_cache_; |
| 196 | Helper* helper_; |
| 197 | }; |
| 198 | |
| 199 | } // namespace quic |
| 200 | |
| 201 | #endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_ |