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_CLIENT_STREAM_H_ 6 #define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_ 7 8 #include <cstdint> 9 #include <memory> 10 #include <string> 11 12 #include "quiche/quic/core/crypto/proof_verifier.h" 13 #include "quiche/quic/core/crypto/quic_crypto_client_config.h" 14 #include "quiche/quic/core/proto/cached_network_parameters_proto.h" 15 #include "quiche/quic/core/quic_config.h" 16 #include "quiche/quic/core/quic_crypto_handshaker.h" 17 #include "quiche/quic/core/quic_crypto_stream.h" 18 #include "quiche/quic/core/quic_server_id.h" 19 #include "quiche/quic/core/quic_session.h" 20 #include "quiche/quic/core/quic_types.h" 21 #include "quiche/quic/core/quic_versions.h" 22 #include "quiche/quic/platform/api/quic_export.h" 23 24 namespace quic { 25 26 namespace test { 27 class QuicCryptoClientStreamPeer; 28 } // namespace test 29 30 class TlsClientHandshaker; 31 32 class QUIC_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream { 33 public: 34 explicit QuicCryptoClientStreamBase(QuicSession* session); 35 ~QuicCryptoClientStreamBase()36 ~QuicCryptoClientStreamBase() override {} 37 38 // Performs a crypto handshake with the server. Returns true if the connection 39 // is still connected. 40 virtual bool CryptoConnect() = 0; 41 42 // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or 43 // ReceivedInchoateReject instead. 44 // 45 // num_sent_client_hellos returns the number of client hello messages that 46 // have been sent. If the handshake has completed then this is one greater 47 // than the number of round-trips needed for the handshake. 48 virtual int num_sent_client_hellos() const = 0; 49 50 // Returns true if the handshake performed was a resumption instead of a full 51 // handshake. Resumption only makes sense for TLS handshakes - there is no 52 // concept of resumption for QUIC crypto even though it supports a 0-RTT 53 // handshake. This function only returns valid results once the handshake is 54 // complete. 55 virtual bool IsResumption() const = 0; 56 57 // Returns true if early data (0-RTT) was accepted in the connection. 58 virtual bool EarlyDataAccepted() const = 0; 59 60 // Returns true if the client received an inchoate REJ during the handshake, 61 // extending the handshake by one round trip. This only applies for QUIC 62 // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet, 63 // but that is handled at the connection layer instead of the crypto layer. 64 virtual bool ReceivedInchoateReject() const = 0; 65 66 // The number of server config update messages received by the 67 // client. Does not count update messages that were received prior 68 // to handshake confirmation. 69 virtual int num_scup_messages_received() const = 0; 70 ExportKeyingMaterial(absl::string_view,absl::string_view,size_t,std::string *)71 bool ExportKeyingMaterial(absl::string_view /*label*/, 72 absl::string_view /*context*/, 73 size_t /*result_len*/, 74 std::string* /*result*/) override { 75 QUICHE_NOTREACHED(); 76 return false; 77 } 78 GetAddressToken(const CachedNetworkParameters *)79 std::string GetAddressToken( 80 const CachedNetworkParameters* /*cached_network_params*/) const override { 81 QUICHE_DCHECK(false); 82 return ""; 83 } 84 ValidateAddressToken(absl::string_view)85 bool ValidateAddressToken(absl::string_view /*token*/) const override { 86 QUICHE_DCHECK(false); 87 return false; 88 } 89 PreviousCachedNetworkParams()90 const CachedNetworkParameters* PreviousCachedNetworkParams() const override { 91 QUICHE_DCHECK(false); 92 return nullptr; 93 } 94 SetPreviousCachedNetworkParams(CachedNetworkParameters)95 void SetPreviousCachedNetworkParams( 96 CachedNetworkParameters /*cached_network_params*/) override { 97 QUICHE_DCHECK(false); 98 } 99 }; 100 101 class QUIC_EXPORT_PRIVATE QuicCryptoClientStream 102 : public QuicCryptoClientStreamBase { 103 public: 104 // kMaxClientHellos is the maximum number of times that we'll send a client 105 // hello. The value 4 accounts for: 106 // * One failure due to an incorrect or missing source-address token. 107 // * One failure due the server's certificate chain being unavailible and 108 // the server being unwilling to send it without a valid source-address 109 // token. 110 // * One failure due to the ServerConfig private key being located on a 111 // remote oracle which has become unavailable, forcing the server to send 112 // the client a fallback ServerConfig. 113 static const int kMaxClientHellos = 4; 114 115 // QuicCryptoClientStream creates a HandshakerInterface at construction time 116 // based on the QuicTransportVersion of the connection. Different 117 // HandshakerInterfaces provide implementations of different crypto handshake 118 // protocols. Currently QUIC crypto is the only protocol implemented; a future 119 // HandshakerInterface will use TLS as the handshake protocol. 120 // QuicCryptoClientStream delegates all of its public methods to its 121 // HandshakerInterface. 122 // 123 // This setup of the crypto stream delegating its implementation to the 124 // handshaker results in the handshaker reading and writing bytes on the 125 // crypto stream, instead of the handshaker passing the stream bytes to send. 126 class QUIC_EXPORT_PRIVATE HandshakerInterface { 127 public: ~HandshakerInterface()128 virtual ~HandshakerInterface() {} 129 130 // Performs a crypto handshake with the server. Returns true if the 131 // connection is still connected. 132 virtual bool CryptoConnect() = 0; 133 134 // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or 135 // ReceivedInchoateReject instead. 136 // 137 // num_sent_client_hellos returns the number of client hello messages that 138 // have been sent. If the handshake has completed then this is one greater 139 // than the number of round-trips needed for the handshake. 140 virtual int num_sent_client_hellos() const = 0; 141 142 // Returns true if the handshake performed was a resumption instead of a 143 // full handshake. Resumption only makes sense for TLS handshakes - there is 144 // no concept of resumption for QUIC crypto even though it supports a 0-RTT 145 // handshake. This function only returns valid results once the handshake is 146 // complete. 147 virtual bool IsResumption() const = 0; 148 149 // Returns true if early data (0-RTT) was accepted in the connection. 150 virtual bool EarlyDataAccepted() const = 0; 151 152 // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or 153 // rejected. 154 virtual ssl_early_data_reason_t EarlyDataReason() const = 0; 155 156 // Returns true if the client received an inchoate REJ during the handshake, 157 // extending the handshake by one round trip. This only applies for QUIC 158 // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet, 159 // but that is handled at the connection layer instead of the crypto layer. 160 virtual bool ReceivedInchoateReject() const = 0; 161 162 // The number of server config update messages received by the 163 // client. Does not count update messages that were received prior 164 // to handshake confirmation. 165 virtual int num_scup_messages_received() const = 0; 166 167 virtual std::string chlo_hash() const = 0; 168 169 // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set 170 // for the connection. 171 virtual bool encryption_established() const = 0; 172 173 // Returns true if receiving CRYPTO_FRAME at encryption `level` is expected. 174 virtual bool IsCryptoFrameExpectedForEncryptionLevel( 175 EncryptionLevel level) const = 0; 176 177 // Returns the encryption level to send CRYPTO_FRAME for `space`. 178 virtual EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace( 179 PacketNumberSpace space) const = 0; 180 181 // Returns true once 1RTT keys are available. 182 virtual bool one_rtt_keys_available() const = 0; 183 184 // Returns the parameters negotiated in the crypto handshake. 185 virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params() 186 const = 0; 187 188 // Used by QuicCryptoStream to parse data received on this stream. 189 virtual CryptoMessageParser* crypto_message_parser() = 0; 190 191 // Used by QuicCryptoStream to know how much unprocessed data can be 192 // buffered at each encryption level. 193 virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0; 194 195 // Called to generate a decrypter for the next key phase. Each call should 196 // generate the key for phase n+1. 197 virtual std::unique_ptr<QuicDecrypter> 198 AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0; 199 200 // Called to generate an encrypter for the same key phase of the last 201 // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter(). 202 virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0; 203 204 // Returns current handshake state. 205 virtual HandshakeState GetHandshakeState() const = 0; 206 207 // Called when a 1RTT packet has been acknowledged. 208 virtual void OnOneRttPacketAcknowledged() = 0; 209 210 // Called when a packet of ENCRYPTION_HANDSHAKE gets sent. 211 virtual void OnHandshakePacketSent() = 0; 212 213 // Called when connection gets closed. 214 virtual void OnConnectionClosed(QuicErrorCode error, 215 ConnectionCloseSource source) = 0; 216 217 // Called when handshake done has been received. 218 virtual void OnHandshakeDoneReceived() = 0; 219 220 // Called when new token has been received. 221 virtual void OnNewTokenReceived(absl::string_view token) = 0; 222 223 // Called when application state is received. 224 virtual void SetServerApplicationStateForResumption( 225 std::unique_ptr<ApplicationState> application_state) = 0; 226 227 // Called to obtain keying material export of length |result_len| with the 228 // given |label| and |context|. Returns false on failure. 229 virtual bool ExportKeyingMaterial(absl::string_view label, 230 absl::string_view context, 231 size_t result_len, 232 std::string* result) = 0; 233 }; 234 235 // ProofHandler is an interface that handles callbacks from the crypto 236 // stream when the client has proof verification details of the server. 237 class QUIC_EXPORT_PRIVATE ProofHandler { 238 public: ~ProofHandler()239 virtual ~ProofHandler() {} 240 241 // Called when the proof in |cached| is marked valid. If this is a secure 242 // QUIC session, then this will happen only after the proof verifier 243 // completes. 244 virtual void OnProofValid( 245 const QuicCryptoClientConfig::CachedState& cached) = 0; 246 247 // Called when proof verification details become available, either because 248 // proof verification is complete, or when cached details are used. This 249 // will only be called for secure QUIC connections. 250 virtual void OnProofVerifyDetailsAvailable( 251 const ProofVerifyDetails& verify_details) = 0; 252 }; 253 254 QuicCryptoClientStream(const QuicServerId& server_id, QuicSession* session, 255 std::unique_ptr<ProofVerifyContext> verify_context, 256 QuicCryptoClientConfig* crypto_config, 257 ProofHandler* proof_handler, 258 bool has_application_state); 259 QuicCryptoClientStream(const QuicCryptoClientStream&) = delete; 260 QuicCryptoClientStream& operator=(const QuicCryptoClientStream&) = delete; 261 262 ~QuicCryptoClientStream() override; 263 264 // From QuicCryptoClientStreamBase 265 bool CryptoConnect() override; 266 int num_sent_client_hellos() const override; 267 bool IsResumption() const override; 268 bool EarlyDataAccepted() const override; 269 ssl_early_data_reason_t EarlyDataReason() const override; 270 bool ReceivedInchoateReject() const override; 271 272 int num_scup_messages_received() const override; 273 274 // From QuicCryptoStream 275 bool encryption_established() const override; 276 bool one_rtt_keys_available() const override; 277 const QuicCryptoNegotiatedParameters& crypto_negotiated_params() 278 const override; 279 CryptoMessageParser* crypto_message_parser() override; OnPacketDecrypted(EncryptionLevel)280 void OnPacketDecrypted(EncryptionLevel /*level*/) override {} 281 void OnOneRttPacketAcknowledged() override; 282 void OnHandshakePacketSent() override; 283 void OnConnectionClosed(QuicErrorCode error, 284 ConnectionCloseSource source) override; 285 void OnHandshakeDoneReceived() override; 286 void OnNewTokenReceived(absl::string_view token) override; 287 HandshakeState GetHandshakeState() const override; 288 void SetServerApplicationStateForResumption( 289 std::unique_ptr<ApplicationState> application_state) override; 290 size_t BufferSizeLimitForLevel(EncryptionLevel level) const override; 291 std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() 292 override; 293 std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override; 294 SSL* GetSsl() const override; 295 bool IsCryptoFrameExpectedForEncryptionLevel( 296 EncryptionLevel level) const override; 297 EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace( 298 PacketNumberSpace space) const override; 299 300 bool ExportKeyingMaterial(absl::string_view label, absl::string_view context, 301 size_t result_len, std::string* result) override; 302 std::string chlo_hash() const; 303 304 protected: set_handshaker(std::unique_ptr<HandshakerInterface> handshaker)305 void set_handshaker(std::unique_ptr<HandshakerInterface> handshaker) { 306 handshaker_ = std::move(handshaker); 307 } 308 309 private: 310 friend class test::QuicCryptoClientStreamPeer; 311 std::unique_ptr<HandshakerInterface> handshaker_; 312 // Points to |handshaker_| if it uses TLS1.3. Otherwise, nullptr. 313 // TODO(danzh) change the type of |handshaker_| to TlsClientHandshaker after 314 // deprecating Google QUIC. 315 TlsClientHandshaker* tls_handshaker_{nullptr}; 316 }; 317 318 } // namespace quic 319 320 #endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_ 321