xref: /aosp_15_r20/external/webrtc/rtc_base/openssl_adapter.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef RTC_BASE_OPENSSL_ADAPTER_H_
12 #define RTC_BASE_OPENSSL_ADAPTER_H_
13 
14 #include <openssl/ossl_typ.h>
15 #include <stddef.h>
16 #include <stdint.h>
17 
18 #include <memory>
19 #include <string>
20 #include <vector>
21 
22 #include "absl/strings/string_view.h"
23 #include "api/task_queue/pending_task_safety_flag.h"
24 #include "rtc_base/buffer.h"
25 #ifdef OPENSSL_IS_BORINGSSL
26 #include "rtc_base/boringssl_identity.h"
27 #else
28 #include "rtc_base/openssl_identity.h"
29 #endif
30 #include "rtc_base/openssl_session_cache.h"
31 #include "rtc_base/socket.h"
32 #include "rtc_base/socket_address.h"
33 #include "rtc_base/ssl_adapter.h"
34 #include "rtc_base/ssl_certificate.h"
35 #include "rtc_base/ssl_identity.h"
36 #include "rtc_base/ssl_stream_adapter.h"
37 
38 namespace rtc {
39 
40 namespace webrtc_openssl_adapter_internal {
41 
42 // Local definition, since absl::StrJoin is not allow-listed. Declared in header
43 // file only for unittests.
44 std::string StrJoin(const std::vector<std::string>& list, char delimiter);
45 
46 }  // namespace webrtc_openssl_adapter_internal
47 
48 class OpenSSLAdapter final : public SSLAdapter {
49  public:
50   static bool InitializeSSL();
51   static bool CleanupSSL();
52 
53   // Creating an OpenSSLAdapter requires a socket to bind to, an optional
54   // session cache if you wish to improve performance by caching sessions for
55   // hostnames you have previously connected to and an optional
56   // SSLCertificateVerifier which can override any existing trusted roots to
57   // validate a peer certificate. The cache and verifier are effectively
58   // immutable after the the SSL connection starts.
59   explicit OpenSSLAdapter(Socket* socket,
60                           OpenSSLSessionCache* ssl_session_cache = nullptr,
61                           SSLCertificateVerifier* ssl_cert_verifier = nullptr);
62   ~OpenSSLAdapter() override;
63 
64   void SetIgnoreBadCert(bool ignore) override;
65   void SetAlpnProtocols(const std::vector<std::string>& protos) override;
66   void SetEllipticCurves(const std::vector<std::string>& curves) override;
67   void SetMode(SSLMode mode) override;
68   void SetCertVerifier(SSLCertificateVerifier* ssl_cert_verifier) override;
69   void SetIdentity(std::unique_ptr<SSLIdentity> identity) override;
70   void SetRole(SSLRole role) override;
71   int StartSSL(absl::string_view hostname) override;
72   int Send(const void* pv, size_t cb) override;
73   int SendTo(const void* pv, size_t cb, const SocketAddress& addr) override;
74   int Recv(void* pv, size_t cb, int64_t* timestamp) override;
75   int RecvFrom(void* pv,
76                size_t cb,
77                SocketAddress* paddr,
78                int64_t* timestamp) override;
79   int Close() override;
80   // Note that the socket returns ST_CONNECTING while SSL is being negotiated.
81   ConnState GetState() const override;
82   bool IsResumedSession() override;
83   // Creates a new SSL_CTX object, configured for client-to-server usage
84   // with SSLMode `mode`, and if `enable_cache` is true, with support for
85   // storing successful sessions so that they can be later resumed.
86   // OpenSSLAdapterFactory will call this method to create its own internal
87   // SSL_CTX, and OpenSSLAdapter will also call this when used without a
88   // factory.
89   static SSL_CTX* CreateContext(SSLMode mode, bool enable_cache);
90 
91  protected:
92   void OnConnectEvent(Socket* socket) override;
93   void OnReadEvent(Socket* socket) override;
94   void OnWriteEvent(Socket* socket) override;
95   void OnCloseEvent(Socket* socket, int err) override;
96 
97  private:
98   class EarlyExitCatcher {
99    public:
100     EarlyExitCatcher(OpenSSLAdapter& adapter_ptr);
101     void disable();
102     ~EarlyExitCatcher();
103 
104    private:
105     bool disabled_ = false;
106     OpenSSLAdapter& adapter_ptr_;
107   };
108   enum SSLState {
109     SSL_NONE,
110     SSL_WAIT,
111     SSL_CONNECTING,
112     SSL_CONNECTED,
113     SSL_ERROR
114   };
115 
116   int BeginSSL();
117   int ContinueSSL();
118   void Error(absl::string_view context, int err, bool signal = true);
119   void Cleanup();
120   void OnTimeout();
121 
122   // Return value and arguments have the same meanings as for Send; `error` is
123   // an output parameter filled with the result of SSL_get_error.
124   int DoSslWrite(const void* pv, size_t cb, int* error);
125   bool SSLPostConnectionCheck(SSL* ssl, absl::string_view host);
126 
127 #if !defined(NDEBUG)
128   // In debug builds, logs info about the state of the SSL connection.
129   static void SSLInfoCallback(const SSL* ssl, int where, int ret);
130 #endif
131 
132 #if defined(OPENSSL_IS_BORINGSSL) && \
133     defined(WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS)
134   static enum ssl_verify_result_t SSLVerifyCallback(SSL* ssl,
135                                                     uint8_t* out_alert);
136   enum ssl_verify_result_t SSLVerifyInternal(SSL* ssl, uint8_t* out_alert);
137 #else
138   static int SSLVerifyCallback(int ok, X509_STORE_CTX* store);
139   // Call a custom verifier, if installed.
140   // Returns 1 on success, `status_on_error` on error or verification failure.
141   int SSLVerifyInternal(int status_on_error, SSL* ssl, X509_STORE_CTX* store);
142 #endif
143   friend class OpenSSLStreamAdapter;  // for custom_verify_callback_;
144 
145   // If the SSL_CTX was created with `enable_cache` set to true, this callback
146   // will be called when a SSL session has been successfully established,
147   // to allow its SSL_SESSION* to be cached for later resumption.
148   static int NewSSLSessionCallback(SSL* ssl, SSL_SESSION* session);
149 
150   // Optional SSL Shared session cache to improve performance.
151   OpenSSLSessionCache* ssl_session_cache_ = nullptr;
152   // Optional SSL Certificate verifier which can be set by a third party.
153   SSLCertificateVerifier* ssl_cert_verifier_ = nullptr;
154   // The current connection state of the (d)TLS connection.
155   SSLState state_;
156 
157 #ifdef OPENSSL_IS_BORINGSSL
158   std::unique_ptr<BoringSSLIdentity> identity_;
159 #else
160   std::unique_ptr<OpenSSLIdentity> identity_;
161 #endif
162   // Indicates whethere this is a client or a server.
163   SSLRole role_;
164   bool ssl_read_needs_write_;
165   bool ssl_write_needs_read_;
166   // This buffer is used if SSL_write fails with SSL_ERROR_WANT_WRITE, which
167   // means we need to keep retrying with *the same exact data* until it
168   // succeeds. Afterwards it will be cleared.
169   Buffer pending_data_;
170   SSL* ssl_;
171   // Holds the SSL context, which may be shared if an session cache is provided.
172   SSL_CTX* ssl_ctx_;
173   // Hostname of server that is being connected, used for SNI.
174   std::string ssl_host_name_;
175   // Set the adapter to DTLS or TLS mode before creating the context.
176   SSLMode ssl_mode_;
177   // If true, the server certificate need not match the configured hostname.
178   bool ignore_bad_cert_;
179   // List of protocols to be used in the TLS ALPN extension.
180   std::vector<std::string> alpn_protocols_;
181   // List of elliptic curves to be used in the TLS elliptic curves extension.
182   std::vector<std::string> elliptic_curves_;
183   // Holds the result of the call to run of the ssl_cert_verify_->Verify()
184   bool custom_cert_verifier_status_;
185   // Flag to cancel pending timeout task.
186   webrtc::ScopedTaskSafety timer_;
187 };
188 
189 // The OpenSSLAdapterFactory is responsbile for creating multiple new
190 // OpenSSLAdapters with a shared SSL_CTX and a shared SSL_SESSION cache. The
191 // SSL_SESSION cache allows existing SSL_SESSIONS to be reused instead of
192 // recreating them leading to a significant performance improvement.
193 class OpenSSLAdapterFactory : public SSLAdapterFactory {
194  public:
195   OpenSSLAdapterFactory();
196   ~OpenSSLAdapterFactory() override;
197   // Set the SSL Mode to use with this factory. This should only be set before
198   // the first adapter is created with the factory. If it is called after it
199   // will DCHECK.
200   void SetMode(SSLMode mode) override;
201 
202   // Set a custom certificate verifier to be passed down to each instance
203   // created with this factory. This should only ever be set before the first
204   // call to the factory and cannot be changed after the fact.
205   void SetCertVerifier(SSLCertificateVerifier* ssl_cert_verifier) override;
206 
207   void SetIdentity(std::unique_ptr<SSLIdentity> identity) override;
208 
209   // Choose whether the socket acts as a server socket or client socket.
210   void SetRole(SSLRole role) override;
211 
212   // Methods that control server certificate verification, used in unit tests.
213   // Do not call these methods in production code.
214   void SetIgnoreBadCert(bool ignore) override;
215 
216   // Constructs a new socket using the shared OpenSSLSessionCache. This means
217   // existing SSLSessions already in the cache will be reused instead of
218   // re-created for improved performance.
219   OpenSSLAdapter* CreateAdapter(Socket* socket) override;
220 
221  private:
222   // Holds the SSLMode (DTLS,TLS) that will be used to set the session cache.
223   SSLMode ssl_mode_ = SSL_MODE_TLS;
224   SSLRole ssl_role_ = SSL_CLIENT;
225   bool ignore_bad_cert_ = false;
226 
227   std::unique_ptr<SSLIdentity> identity_;
228 
229   // Holds a cache of existing SSL Sessions.
230   std::unique_ptr<OpenSSLSessionCache> ssl_session_cache_;
231   // Provides an optional custom callback for verifying SSL certificates, this
232   // in currently only used for TLS-TURN connections.
233   SSLCertificateVerifier* ssl_cert_verifier_ = nullptr;
234   // TODO(benwright): Remove this when context is moved to OpenSSLCommon.
235   // Hold a friend class to the OpenSSLAdapter to retrieve the context.
236   friend class OpenSSLAdapter;
237 };
238 
239 // The EarlyExitCatcher is responsible for calling OpenSSLAdapter::Cleanup on
240 // destruction. By doing this we have scoped cleanup which can be disabled if
241 // there were no errors, aka early exits.
242 
243 std::string TransformAlpnProtocols(const std::vector<std::string>& protos);
244 
245 }  // namespace rtc
246 
247 #endif  // RTC_BASE_OPENSSL_ADAPTER_H_
248