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