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; |
nharper | 23d4074 | 2020-01-03 14:55:01 -0800 | [diff] [blame] | 59 | |
| 60 | // NOTE: Indicating that the Expect-CT header should be sent here presents |
| 61 | // a layering violation to some extent. The Expect-CT header only applies to |
| 62 | // HTTP connections, while this class can be used for non-HTTP applications. |
| 63 | // However, it is exposed here because that is the only place where the |
| 64 | // configuration for the certificate used in the connection is accessible. |
| 65 | virtual bool ShouldSendExpectCTHeader() const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 66 | }; |
| 67 | |
| 68 | class QUIC_EXPORT_PRIVATE QuicCryptoServerStream |
| 69 | : public QuicCryptoServerStreamBase { |
| 70 | public: |
rch | 85240a1 | 2019-12-23 11:51:59 -0800 | [diff] [blame] | 71 | // QuicCryptoServerStream creates a HandshakerInterface at construction time |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 72 | // based on the QuicTransportVersion of the connection. Different |
rch | 85240a1 | 2019-12-23 11:51:59 -0800 | [diff] [blame] | 73 | // HandshakerInterfaces provide implementations of different crypto handshake |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 74 | // protocols. Currently QUIC crypto is the only protocol implemented; a future |
rch | 85240a1 | 2019-12-23 11:51:59 -0800 | [diff] [blame] | 75 | // HandshakerInterface will use TLS as the handshake protocol. |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 76 | // QuicCryptoServerStream delegates all of its public methods to its |
rch | 85240a1 | 2019-12-23 11:51:59 -0800 | [diff] [blame] | 77 | // HandshakerInterface. |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 78 | // |
| 79 | // This setup of the crypto stream delegating its implementation to the |
| 80 | // handshaker results in the handshaker reading and writing bytes on the |
| 81 | // crypto stream, instead of the handshake rpassing the stream bytes to send. |
rch | 85240a1 | 2019-12-23 11:51:59 -0800 | [diff] [blame] | 82 | class QUIC_EXPORT_PRIVATE HandshakerInterface { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 83 | public: |
rch | 85240a1 | 2019-12-23 11:51:59 -0800 | [diff] [blame] | 84 | virtual ~HandshakerInterface() {} |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 85 | |
| 86 | // Cancel any outstanding callbacks, such as asynchronous validation of |
| 87 | // client hello. |
| 88 | virtual void CancelOutstandingCallbacks() = 0; |
| 89 | |
| 90 | // GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded, |
| 91 | // SHA-256 hash of the client's ChannelID key and returns true, if the |
| 92 | // client presented a ChannelID. Otherwise it returns false. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 93 | virtual bool GetBase64SHA256ClientChannelID(std::string* output) const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 94 | |
| 95 | // Sends the latest server config and source-address token to the client. |
| 96 | virtual void SendServerConfigUpdate( |
| 97 | const CachedNetworkParameters* cached_network_params) = 0; |
| 98 | |
| 99 | // These are all accessors and setters to their respective counters. |
| 100 | virtual uint8_t NumHandshakeMessages() const = 0; |
| 101 | virtual uint8_t NumHandshakeMessagesWithServerNonces() const = 0; |
| 102 | virtual int NumServerConfigUpdateMessagesSent() const = 0; |
| 103 | virtual const CachedNetworkParameters* PreviousCachedNetworkParams() |
| 104 | const = 0; |
| 105 | virtual bool ZeroRttAttempted() const = 0; |
| 106 | virtual void SetPreviousCachedNetworkParams( |
| 107 | CachedNetworkParameters cached_network_params) = 0; |
fayang | d58736d | 2019-11-27 13:35:31 -0800 | [diff] [blame] | 108 | virtual void OnPacketDecrypted(EncryptionLevel level) = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 109 | |
| 110 | // NOTE: Indicating that the Expect-CT header should be sent here presents a |
| 111 | // layering violation to some extent. The Expect-CT header only applies to |
| 112 | // HTTP connections, while this class can be used for non-HTTP applications. |
| 113 | // However, it is exposed here because that is the only place where the |
| 114 | // configuration for the certificate used in the connection is accessible. |
| 115 | virtual bool ShouldSendExpectCTHeader() const = 0; |
| 116 | |
| 117 | // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set |
| 118 | // for the connection. |
| 119 | virtual bool encryption_established() const = 0; |
| 120 | |
fayang | 685367a | 2020-01-14 10:40:15 -0800 | [diff] [blame] | 121 | // Returns true once 1RTT keys are available. |
| 122 | virtual bool one_rtt_keys_available() const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 123 | |
| 124 | // Returns the parameters negotiated in the crypto handshake. |
| 125 | virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params() |
| 126 | const = 0; |
| 127 | |
| 128 | // Used by QuicCryptoStream to parse data received on this stream. |
| 129 | virtual CryptoMessageParser* crypto_message_parser() = 0; |
nharper | 486a8a9 | 2019-08-28 16:25:10 -0700 | [diff] [blame] | 130 | |
fayang | 9a863cf | 2020-01-16 14:12:11 -0800 | [diff] [blame] | 131 | // Get current handshake state. |
| 132 | virtual HandshakeState GetHandshakeState() const = 0; |
| 133 | |
nharper | 486a8a9 | 2019-08-28 16:25:10 -0700 | [diff] [blame] | 134 | // Used by QuicCryptoStream to know how much unprocessed data can be |
| 135 | // buffered at each encryption level. |
| 136 | virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 137 | }; |
| 138 | |
dschinazi | f25169a | 2019-10-23 08:12:18 -0700 | [diff] [blame] | 139 | class QUIC_EXPORT_PRIVATE Helper { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 140 | public: |
| 141 | virtual ~Helper() {} |
| 142 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 143 | // Returns true if |message|, which was received on |self_address| is |
| 144 | // acceptable according to the visitor's policy. Otherwise, returns false |
| 145 | // and populates |error_details|. |
| 146 | virtual bool CanAcceptClientHello(const CryptoHandshakeMessage& message, |
| 147 | const QuicSocketAddress& client_address, |
| 148 | const QuicSocketAddress& peer_address, |
| 149 | const QuicSocketAddress& self_address, |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 150 | std::string* error_details) const = 0; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 151 | }; |
| 152 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 153 | QuicCryptoServerStream(const QuicCryptoServerStream&) = delete; |
| 154 | QuicCryptoServerStream& operator=(const QuicCryptoServerStream&) = delete; |
| 155 | |
| 156 | ~QuicCryptoServerStream() override; |
| 157 | |
| 158 | // From QuicCryptoServerStreamBase |
| 159 | void CancelOutstandingCallbacks() override; |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 160 | bool GetBase64SHA256ClientChannelID(std::string* output) const override; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 161 | void SendServerConfigUpdate( |
| 162 | const CachedNetworkParameters* cached_network_params) override; |
| 163 | uint8_t NumHandshakeMessages() const override; |
| 164 | uint8_t NumHandshakeMessagesWithServerNonces() const override; |
| 165 | int NumServerConfigUpdateMessagesSent() const override; |
| 166 | const CachedNetworkParameters* PreviousCachedNetworkParams() const override; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 167 | bool ZeroRttAttempted() const override; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 168 | void SetPreviousCachedNetworkParams( |
| 169 | CachedNetworkParameters cached_network_params) override; |
nharper | 23d4074 | 2020-01-03 14:55:01 -0800 | [diff] [blame] | 170 | bool ShouldSendExpectCTHeader() const override; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 171 | |
| 172 | bool encryption_established() const override; |
fayang | 685367a | 2020-01-14 10:40:15 -0800 | [diff] [blame] | 173 | bool one_rtt_keys_available() const override; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 174 | const QuicCryptoNegotiatedParameters& crypto_negotiated_params() |
| 175 | const override; |
| 176 | CryptoMessageParser* crypto_message_parser() override; |
fayang | d58736d | 2019-11-27 13:35:31 -0800 | [diff] [blame] | 177 | void OnPacketDecrypted(EncryptionLevel level) override; |
fayang | 9a863cf | 2020-01-16 14:12:11 -0800 | [diff] [blame] | 178 | HandshakeState GetHandshakeState() const override; |
nharper | 486a8a9 | 2019-08-28 16:25:10 -0700 | [diff] [blame] | 179 | size_t BufferSizeLimitForLevel(EncryptionLevel level) const override; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 180 | void OnSuccessfulVersionNegotiation( |
| 181 | const ParsedQuicVersion& version) override; |
| 182 | |
| 183 | protected: |
nharper | bec1333 | 2020-01-09 12:20:03 -0800 | [diff] [blame] | 184 | QUIC_EXPORT_PRIVATE friend std::unique_ptr<QuicCryptoServerStreamBase> |
| 185 | CreateCryptoServerStream(const QuicCryptoServerConfig* crypto_config, |
| 186 | QuicCompressedCertsCache* compressed_certs_cache, |
| 187 | QuicSession* session, |
| 188 | Helper* helper); |
nharper | e5e28f9 | 2020-01-03 14:10:07 -0800 | [diff] [blame] | 189 | |
| 190 | QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config, |
| 191 | QuicCompressedCertsCache* compressed_certs_cache, |
| 192 | QuicSession* session, |
| 193 | Helper* helper); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 194 | // Provided so that subclasses can provide their own handshaker. |
nharper | b93b64e | 2019-12-19 18:53:19 -0800 | [diff] [blame] | 195 | // set_handshaker can only be called if this QuicCryptoServerStream's |
| 196 | // handshaker hasn't been set yet. If set_handshaker is called outside of |
| 197 | // OnSuccessfulVersionNegotiation, then that method must be overridden to not |
| 198 | // set a handshaker. |
nharper | fe59774 | 2019-12-20 16:30:05 -0800 | [diff] [blame] | 199 | QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config, |
| 200 | QuicCompressedCertsCache* compressed_certs_cache, |
| 201 | QuicSession* session, |
| 202 | Helper* helper, |
rch | 85240a1 | 2019-12-23 11:51:59 -0800 | [diff] [blame] | 203 | std::unique_ptr<HandshakerInterface> handshaker); |
| 204 | void set_handshaker(std::unique_ptr<HandshakerInterface> handshaker); |
| 205 | HandshakerInterface* handshaker() const; |
nharper | b93b64e | 2019-12-19 18:53:19 -0800 | [diff] [blame] | 206 | |
| 207 | const QuicCryptoServerConfig* crypto_config() const; |
| 208 | QuicCompressedCertsCache* compressed_certs_cache() const; |
| 209 | Helper* helper() const; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 210 | |
| 211 | private: |
rch | 85240a1 | 2019-12-23 11:51:59 -0800 | [diff] [blame] | 212 | std::unique_ptr<HandshakerInterface> handshaker_; |
nharper | fe59774 | 2019-12-20 16:30:05 -0800 | [diff] [blame] | 213 | // Latched value of quic_create_server_handshaker_in_constructor flag. |
| 214 | bool create_handshaker_in_constructor_; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 215 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 216 | // Arguments from QuicCryptoServerStream constructor that might need to be |
rch | 85240a1 | 2019-12-23 11:51:59 -0800 | [diff] [blame] | 217 | // passed to the HandshakerInterface constructor in its late construction. |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 218 | const QuicCryptoServerConfig* crypto_config_; |
| 219 | QuicCompressedCertsCache* compressed_certs_cache_; |
| 220 | Helper* helper_; |
| 221 | }; |
| 222 | |
nharper | e5e28f9 | 2020-01-03 14:10:07 -0800 | [diff] [blame] | 223 | // Creates an appropriate QuicCryptoServerStream for the provided parameters, |
| 224 | // including the version used by |session|. |crypto_config|, |session|, and |
| 225 | // |helper| must all outlive the stream. The caller takes ownership of the |
| 226 | // returned object. |
ianswett | 1f4fe2d | 2020-01-10 13:01:17 -0800 | [diff] [blame] | 227 | QUIC_EXPORT_PRIVATE std::unique_ptr<QuicCryptoServerStreamBase> |
| 228 | CreateCryptoServerStream(const QuicCryptoServerConfig* crypto_config, |
| 229 | QuicCompressedCertsCache* compressed_certs_cache, |
| 230 | QuicSession* session, |
| 231 | QuicCryptoServerStream::Helper* helper); |
nharper | e5e28f9 | 2020-01-03 14:10:07 -0800 | [diff] [blame] | 232 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 233 | } // namespace quic |
| 234 | |
| 235 | #endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_SERVER_STREAM_H_ |