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 "third_party/boringssl/src/include/openssl/ssl.h"
12 #include "net/third_party/quiche/src/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,
50                                 const SSL_CIPHER* cipher,
51                                 const std::vector<uint8_t>& write_secret) = 0;
52 
53     // SetReadSecret is similar to SetWriteSecret, except that it is used for
54     // decrypting messages. SetReadSecret at a particular level is always called
55     // after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT,
56     // where the EncryptionLevel for SetWriteSecret is
57     // ENCRYPTION_FORWARD_SECURE.
58     virtual bool SetReadSecret(EncryptionLevel level,
59                                const SSL_CIPHER* cipher,
60                                const std::vector<uint8_t>& read_secret) = 0;
61 
62     // WriteMessage is called when there is |data| from the TLS stack ready for
63     // the QUIC stack to write in a crypto frame. The data must be transmitted
64     // at encryption level |level|.
65     virtual void WriteMessage(EncryptionLevel level,
66                               absl::string_view data) = 0;
67 
68     // FlushFlight is called to signal that the current flight of messages have
69     // all been written (via calls to WriteMessage) and can be flushed to the
70     // underlying transport.
71     virtual void FlushFlight() = 0;
72 
73     // SendAlert causes this TlsConnection to close the QUIC connection with an
74     // error code corersponding to the TLS alert description |desc| sent at
75     // level |level|.
76     virtual void SendAlert(EncryptionLevel level, uint8_t desc) = 0;
77 
78     friend class TlsConnection;
79   };
80 
81   TlsConnection(const TlsConnection&) = delete;
82   TlsConnection& operator=(const TlsConnection&) = delete;
83 
84   // Functions to convert between BoringSSL's enum ssl_encryption_level_t and
85   // QUIC's EncryptionLevel.
86   static EncryptionLevel QuicEncryptionLevel(enum ssl_encryption_level_t level);
87   static enum ssl_encryption_level_t BoringEncryptionLevel(
88       EncryptionLevel level);
89 
ssl()90   SSL* ssl() const { return ssl_.get(); }
91 
92  protected:
93   // TlsConnection does not take ownership of any of its arguments; they must
94   // outlive the TlsConnection object.
95   TlsConnection(SSL_CTX* ssl_ctx, Delegate* delegate);
96 
97   // Creates an SSL_CTX and configures it with the options that are appropriate
98   // for both client and server. The caller is responsible for ownership of the
99   // newly created struct.
100   //
101   // The provided |cert_verify_mode| is passed in as the |mode| argument for
102   // |SSL_CTX_set_verify|. See
103   // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_VERIFY_NONE
104   // for a description of possible values.
105   static bssl::UniquePtr<SSL_CTX> CreateSslCtx(int cert_verify_mode);
106 
107   // From a given SSL* |ssl|, returns a pointer to the TlsConnection that it
108   // belongs to. This helper method allows the callbacks set in BoringSSL to be
109   // dispatched to the correct TlsConnection from the SSL* passed into the
110   // callback.
111   static TlsConnection* ConnectionFromSsl(const SSL* ssl);
112 
113  private:
114   // Registered as the callback for SSL_CTX_set_custom_verify. The
115   // implementation is delegated to Delegate::VerifyCert.
116   static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert);
117 
118   // TlsConnection implements SSL_QUIC_METHOD, which provides the interface
119   // between BoringSSL's TLS stack and a QUIC implementation.
120   static const SSL_QUIC_METHOD kSslQuicMethod;
121 
122   // The following static functions make up the members of kSslQuicMethod:
123   static int SetReadSecretCallback(SSL* ssl,
124                                    enum ssl_encryption_level_t level,
125                                    const SSL_CIPHER* cipher,
126                                    const uint8_t* secret,
127                                    size_t secret_len);
128   static int SetWriteSecretCallback(SSL* ssl,
129                                     enum ssl_encryption_level_t level,
130                                     const SSL_CIPHER* cipher,
131                                     const uint8_t* secret,
132                                     size_t secret_len);
133   static int WriteMessageCallback(SSL* ssl,
134                                   enum ssl_encryption_level_t level,
135                                   const uint8_t* data,
136                                   size_t len);
137   static int FlushFlightCallback(SSL* ssl);
138   static int SendAlertCallback(SSL* ssl,
139                                enum ssl_encryption_level_t level,
140                                uint8_t desc);
141 
142   Delegate* delegate_;
143   bssl::UniquePtr<SSL> ssl_;
144 };
145 
146 }  // namespace quic
147 
148 #endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
149