xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/tls_handshaker.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2017 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_TLS_HANDSHAKER_H_
6 #define QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
7 
8 #include "absl/strings/string_view.h"
9 #include "openssl/base.h"
10 #include "openssl/ssl.h"
11 #include "quiche/quic/core/crypto/crypto_handshake.h"
12 #include "quiche/quic/core/crypto/crypto_message_parser.h"
13 #include "quiche/quic/core/crypto/proof_verifier.h"
14 #include "quiche/quic/core/crypto/quic_decrypter.h"
15 #include "quiche/quic/core/crypto/quic_encrypter.h"
16 #include "quiche/quic/core/crypto/tls_connection.h"
17 #include "quiche/quic/core/quic_session.h"
18 #include "quiche/quic/platform/api/quic_export.h"
19 #include "quiche/quic/platform/api/quic_flags.h"
20 
21 namespace quic {
22 
23 class QuicCryptoStream;
24 
25 // Base class for TlsClientHandshaker and TlsServerHandshaker. TlsHandshaker
26 // provides functionality common to both the client and server, such as moving
27 // messages between the TLS stack and the QUIC crypto stream, and handling
28 // derivation of secrets.
29 class QUICHE_EXPORT TlsHandshaker : public TlsConnection::Delegate,
30                                     public CryptoMessageParser {
31  public:
32   // TlsHandshaker does not take ownership of any of its arguments; they must
33   // outlive the TlsHandshaker.
34   TlsHandshaker(QuicCryptoStream* stream, QuicSession* session);
35   TlsHandshaker(const TlsHandshaker&) = delete;
36   TlsHandshaker& operator=(const TlsHandshaker&) = delete;
37 
38   ~TlsHandshaker() override;
39 
40   // From CryptoMessageParser
41   bool ProcessInput(absl::string_view input, EncryptionLevel level) override;
InputBytesRemaining()42   size_t InputBytesRemaining() const override { return 0; }
error()43   QuicErrorCode error() const override { return parser_error_; }
error_detail()44   const std::string& error_detail() const override {
45     return parser_error_detail_;
46   }
47 
48   // The following methods provide implementations to subclasses of
49   // TlsHandshaker which use them to implement methods of QuicCryptoStream.
crypto_message_parser()50   CryptoMessageParser* crypto_message_parser() { return this; }
51   size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
52   ssl_early_data_reason_t EarlyDataReason() const;
53   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter();
54   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter();
55   virtual HandshakeState GetHandshakeState() const = 0;
56   bool ExportKeyingMaterialForLabel(absl::string_view label,
57                                     absl::string_view context,
58                                     size_t result_len, std::string* result);
59 
60  protected:
61   // Called when a new message is received on the crypto stream and is available
62   // for the TLS stack to read.
63   virtual void AdvanceHandshake();
64 
65   void CloseConnection(QuicErrorCode error, const std::string& reason_phrase);
66   // Closes the connection, specifying the wire error code |ietf_error|
67   // explicitly.
68   void CloseConnection(QuicErrorCode error,
69                        QuicIetfTransportErrorCodes ietf_error,
70                        const std::string& reason_phrase);
71 
72   void OnConnectionClosed(QuicErrorCode error, ConnectionCloseSource source);
73 
is_connection_closed()74   bool is_connection_closed() const { return is_connection_closed_; }
75 
76   // Called when |SSL_do_handshake| returns 1, indicating that the handshake has
77   // finished. Note that a handshake only finishes once, entering early data
78   // does not count.
79   virtual void FinishHandshake() = 0;
80 
81   // Called when |SSL_do_handshake| returns 1 and the connection is in early
82   // data. In that case, |AdvanceHandshake| will call |OnEnterEarlyData| and
83   // retry |SSL_do_handshake| once.
OnEnterEarlyData()84   virtual void OnEnterEarlyData() {
85     // By default, do nothing but check the preconditions.
86     QUICHE_DCHECK(SSL_in_early_data(ssl()));
87   }
88 
89   // Called when a handshake message is received after the handshake is
90   // complete.
91   virtual void ProcessPostHandshakeMessage() = 0;
92 
93   // Called when an unexpected error code is received from |SSL_get_error|. If a
94   // subclass can expect more than just a single error (as provided by
95   // |set_expected_ssl_error|), it can override this method to handle that case.
96   virtual bool ShouldCloseConnectionOnUnexpectedError(int ssl_error);
97 
set_expected_ssl_error(int ssl_error)98   void set_expected_ssl_error(int ssl_error) {
99     expected_ssl_error_ = ssl_error;
100   }
expected_ssl_error()101   int expected_ssl_error() const { return expected_ssl_error_; }
102 
103   // Called to verify a cert chain. This can be implemented as a simple wrapper
104   // around ProofVerifier, which optionally gathers additional arguments to pass
105   // into their VerifyCertChain method. This class retains a non-owning pointer
106   // to |callback|; the callback must live until this function returns
107   // QUIC_SUCCESS or QUIC_FAILURE, or until the callback is run.
108   //
109   // If certificate verification fails, |*out_alert| may be set to a TLS alert
110   // that will be sent when closing the connection; it defaults to
111   // certificate_unknown. Implementations of VerifyCertChain may retain the
112   // |out_alert| pointer while performing an async operation.
113   virtual QuicAsyncStatus VerifyCertChain(
114       const std::vector<std::string>& certs, std::string* error_details,
115       std::unique_ptr<ProofVerifyDetails>* details, uint8_t* out_alert,
116       std::unique_ptr<ProofVerifierCallback> callback) = 0;
117   // Called when certificate verification is completed.
118   virtual void OnProofVerifyDetailsAvailable(
119       const ProofVerifyDetails& verify_details) = 0;
120 
121   // Returns the PRF used by the cipher suite negotiated in the TLS handshake.
122   const EVP_MD* Prf(const SSL_CIPHER* cipher);
123 
124   virtual const TlsConnection* tls_connection() const = 0;
125 
ssl()126   SSL* ssl() const { return tls_connection()->ssl(); }
127 
stream()128   QuicCryptoStream* stream() { return stream_; }
handshaker_delegate()129   HandshakerDelegateInterface* handshaker_delegate() {
130     return handshaker_delegate_;
131   }
132 
133   enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) override;
134 
135   // SetWriteSecret provides the encryption secret used to encrypt messages at
136   // encryption level |level|. The secret provided here is the one from the TLS
137   // 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
138   // traffic secrets and application traffic secrets. The provided write secret
139   // must be used with the provided cipher suite |cipher|.
140   void SetWriteSecret(EncryptionLevel level, const SSL_CIPHER* cipher,
141                       absl::Span<const uint8_t> write_secret) override;
142 
143   // SetReadSecret is similar to SetWriteSecret, except that it is used for
144   // decrypting messages. SetReadSecret at a particular level is always called
145   // after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT, where
146   // the EncryptionLevel for SetWriteSecret is ENCRYPTION_FORWARD_SECURE.
147   bool SetReadSecret(EncryptionLevel level, const SSL_CIPHER* cipher,
148                      absl::Span<const uint8_t> read_secret) override;
149 
150   // WriteMessage is called when there is |data| from the TLS stack ready for
151   // the QUIC stack to write in a crypto frame. The data must be transmitted at
152   // encryption level |level|.
153   void WriteMessage(EncryptionLevel level, absl::string_view data) override;
154 
155   // FlushFlight is called to signal that the current flight of
156   // messages have all been written (via calls to WriteMessage) and can be
157   // flushed to the underlying transport.
158   void FlushFlight() override;
159 
160   // SendAlert causes this TlsHandshaker to close the QUIC connection with an
161   // error code corresponding to the TLS alert description |desc|.
162   void SendAlert(EncryptionLevel level, uint8_t desc) override;
163 
164   // Informational callback from BoringSSL. Subclasses can override it to do
165   // logging, tracing, etc.
166   // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
InfoCallback(int,int)167   void InfoCallback(int /*type*/, int /*value*/) override {}
168 
169   // Message callback from BoringSSL, for debugging purposes. See
170   // |SSL_CTX_set_msg_callback| for how to interpret |version|, |content_type|,
171   // and |data|.
172   void MessageCallback(bool is_write, int version, int content_type,
173                        absl::string_view data) override;
174 
175  private:
176   // ProofVerifierCallbackImpl handles the result of an asynchronous certificate
177   // verification operation.
178   class QUICHE_EXPORT ProofVerifierCallbackImpl : public ProofVerifierCallback {
179    public:
180     explicit ProofVerifierCallbackImpl(TlsHandshaker* parent);
181     ~ProofVerifierCallbackImpl() override;
182 
183     // ProofVerifierCallback interface.
184     void Run(bool ok, const std::string& error_details,
185              std::unique_ptr<ProofVerifyDetails>* details) override;
186 
187     // If called, Cancel causes the pending callback to be a no-op.
188     void Cancel();
189 
190    private:
191     // Non-owning pointer to the TlsHandshaker responsible for this callback.
192     // |parent_| must be valid for the life of this callback or until |Cancel|
193     // is called.
194     TlsHandshaker* parent_;
195   };
196 
197   // ProofVerifierCallback used for async certificate verification. Ownership of
198   // this object is transferred to |VerifyCertChain|;
199   ProofVerifierCallbackImpl* proof_verify_callback_ = nullptr;
200   std::unique_ptr<ProofVerifyDetails> verify_details_;
201   enum ssl_verify_result_t verify_result_ = ssl_verify_retry;
202   uint8_t cert_verify_tls_alert_ = SSL_AD_CERTIFICATE_UNKNOWN;
203   std::string cert_verify_error_details_;
204 
205   int expected_ssl_error_ = SSL_ERROR_WANT_READ;
206   bool is_connection_closed_ = false;
207 
208   QuicCryptoStream* stream_;
209   HandshakerDelegateInterface* handshaker_delegate_;
210 
211   QuicErrorCode parser_error_ = QUIC_NO_ERROR;
212   std::string parser_error_detail_;
213 
214   // The most recently derived 1-RTT read and write secrets, which are updated
215   // on each key update.
216   std::vector<uint8_t> latest_read_secret_;
217   std::vector<uint8_t> latest_write_secret_;
218   // 1-RTT header protection keys, which are not changed during key update.
219   std::vector<uint8_t> one_rtt_read_header_protection_key_;
220   std::vector<uint8_t> one_rtt_write_header_protection_key_;
221 
222   struct TlsAlert {
223     EncryptionLevel level;
224     // The TLS alert code as listed in
225     // https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-6
226     uint8_t desc;
227   };
228   std::optional<TlsAlert> last_tls_alert_;
229 };
230 
231 }  // namespace quic
232 
233 #endif  // QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
234