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