• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2019 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_CRYPTO_TLS_CONNECTION_H_
6 #define QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
7 
8 #include <vector>
9 
10 #include "absl/strings/string_view.h"
11 #include "openssl/ssl.h"
12 #include "quiche/quic/core/quic_types.h"
13 
14 namespace quic {
15 
16 // TlsConnection wraps BoringSSL's SSL object which represents a single TLS
17 // connection. Callbacks set in BoringSSL which are called with an SSL* argument
18 // will get dispatched to the TlsConnection object owning that SSL. In turn, the
19 // TlsConnection will delegate the implementation of that callback to its
20 // Delegate.
21 //
22 // The owner of the TlsConnection is responsible for driving the TLS handshake
23 // (and other interactions with the SSL*). This class only handles mapping
24 // callbacks to the correct instance.
25 class QUIC_EXPORT_PRIVATE TlsConnection {
26  public:
27   // A TlsConnection::Delegate implements the methods that are set as callbacks
28   // of TlsConnection.
29   class QUIC_EXPORT_PRIVATE Delegate {
30    public:
~Delegate()31     virtual ~Delegate() {}
32 
33    protected:
34     // Certificate management functions:
35 
36     // Verifies the peer's certificate chain. It may use
37     // SSL_get0_peer_certificates to get the cert chain. This method returns
38     // ssl_verify_ok if the cert is valid, ssl_verify_invalid if it is invalid,
39     // or ssl_verify_retry if verification is happening asynchronously.
40     virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0;
41 
42     // QUIC-TLS interface functions:
43 
44     // SetWriteSecret provides the encryption secret used to encrypt messages at
45     // encryption level |level|. The secret provided here is the one from the
46     // TLS 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
47     // traffic secrets and application traffic secrets. The provided write
48     // secret must be used with the provided cipher suite |cipher|.
49     virtual void SetWriteSecret(EncryptionLevel level, const SSL_CIPHER* cipher,
50                                 absl::Span<const uint8_t> write_secret) = 0;
51 
52     // SetReadSecret is similar to SetWriteSecret, except that it is used for
53     // decrypting messages. SetReadSecret at a particular level is always called
54     // after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT,
55     // where the EncryptionLevel for SetWriteSecret is
56     // ENCRYPTION_FORWARD_SECURE.
57     virtual bool SetReadSecret(EncryptionLevel level, const SSL_CIPHER* cipher,
58                                absl::Span<const uint8_t> read_secret) = 0;
59 
60     // WriteMessage is called when there is |data| from the TLS stack ready for
61     // the QUIC stack to write in a crypto frame. The data must be transmitted
62     // at encryption level |level|.
63     virtual void WriteMessage(EncryptionLevel level,
64                               absl::string_view data) = 0;
65 
66     // FlushFlight is called to signal that the current flight of messages have
67     // all been written (via calls to WriteMessage) and can be flushed to the
68     // underlying transport.
69     virtual void FlushFlight() = 0;
70 
71     // SendAlert causes this TlsConnection to close the QUIC connection with an
72     // error code corersponding to the TLS alert description |desc| sent at
73     // level |level|.
74     virtual void SendAlert(EncryptionLevel level, uint8_t desc) = 0;
75 
76     // Informational callback from BoringSSL. This callback is disabled by
77     // default, but can be enabled by TlsConnection::EnableInfoCallback.
78     //
79     // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
80     virtual void InfoCallback(int type, int value) = 0;
81 
82     friend class TlsConnection;
83   };
84 
85   TlsConnection(const TlsConnection&) = delete;
86   TlsConnection& operator=(const TlsConnection&) = delete;
87 
88   // Configure the SSL such that delegate_->InfoCallback will be called.
89   void EnableInfoCallback();
90 
91   // Configure the SSL to disable session ticket support. Note that, this
92   // function simply sets the |SSL_OP_NO_TICKET| option on the SSL object, it
93   // does not check whether it is too late to do so.
94   void DisableTicketSupport();
95 
96   // Functions to convert between BoringSSL's enum ssl_encryption_level_t and
97   // QUIC's EncryptionLevel.
98   static EncryptionLevel QuicEncryptionLevel(enum ssl_encryption_level_t level);
99   static enum ssl_encryption_level_t BoringEncryptionLevel(
100       EncryptionLevel level);
101 
ssl()102   SSL* ssl() const { return ssl_.get(); }
103 
ssl_config()104   const QuicSSLConfig& ssl_config() const { return ssl_config_; }
105 
106  protected:
107   // TlsConnection does not take ownership of |ssl_ctx| or |delegate|; they must
108   // outlive the TlsConnection object.
109   TlsConnection(SSL_CTX* ssl_ctx, Delegate* delegate, QuicSSLConfig ssl_config);
110 
111   // Creates an SSL_CTX and configures it with the options that are appropriate
112   // for both client and server. The caller is responsible for ownership of the
113   // newly created struct.
114   static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
115 
116   // From a given SSL* |ssl|, returns a pointer to the TlsConnection that it
117   // belongs to. This helper method allows the callbacks set in BoringSSL to be
118   // dispatched to the correct TlsConnection from the SSL* passed into the
119   // callback.
120   static TlsConnection* ConnectionFromSsl(const SSL* ssl);
121 
122   // Registered as the callback for SSL(_CTX)_set_custom_verify. The
123   // implementation is delegated to Delegate::VerifyCert.
124   static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert);
125 
mutable_ssl_config()126   QuicSSLConfig& mutable_ssl_config() { return ssl_config_; }
127 
128  private:
129   // TlsConnection implements SSL_QUIC_METHOD, which provides the interface
130   // between BoringSSL's TLS stack and a QUIC implementation.
131   static const SSL_QUIC_METHOD kSslQuicMethod;
132 
133   // The following static functions make up the members of kSslQuicMethod:
134   static int SetReadSecretCallback(SSL* ssl, enum ssl_encryption_level_t level,
135                                    const SSL_CIPHER* cipher,
136                                    const uint8_t* secret, size_t secret_len);
137   static int SetWriteSecretCallback(SSL* ssl, enum ssl_encryption_level_t level,
138                                     const SSL_CIPHER* cipher,
139                                     const uint8_t* secret, size_t secret_len);
140   static int WriteMessageCallback(SSL* ssl, enum ssl_encryption_level_t level,
141                                   const uint8_t* data, size_t len);
142   static int FlushFlightCallback(SSL* ssl);
143   static int SendAlertCallback(SSL* ssl, enum ssl_encryption_level_t level,
144                                uint8_t desc);
145 
146   Delegate* delegate_;
147   bssl::UniquePtr<SSL> ssl_;
148   QuicSSLConfig ssl_config_;
149 };
150 
151 }  // namespace quic
152 
153 #endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
154