summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/rtc_base/openssl_adapter.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/rtc_base/openssl_adapter.h')
-rw-r--r--third_party/libwebrtc/rtc_base/openssl_adapter.h245
1 files changed, 245 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/openssl_adapter.h b/third_party/libwebrtc/rtc_base/openssl_adapter.h
new file mode 100644
index 0000000000..558a04077a
--- /dev/null
+++ b/third_party/libwebrtc/rtc_base/openssl_adapter.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2004 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef RTC_BASE_OPENSSL_ADAPTER_H_
+#define RTC_BASE_OPENSSL_ADAPTER_H_
+
+#include <openssl/ossl_typ.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/task_queue/pending_task_safety_flag.h"
+#include "rtc_base/buffer.h"
+#ifdef OPENSSL_IS_BORINGSSL
+#include "rtc_base/boringssl_identity.h"
+#else
+#include "rtc_base/openssl_identity.h"
+#endif
+#include "rtc_base/openssl_session_cache.h"
+#include "rtc_base/socket.h"
+#include "rtc_base/socket_address.h"
+#include "rtc_base/ssl_adapter.h"
+#include "rtc_base/ssl_certificate.h"
+#include "rtc_base/ssl_identity.h"
+#include "rtc_base/ssl_stream_adapter.h"
+
+namespace rtc {
+
+namespace webrtc_openssl_adapter_internal {
+
+// Local definition, since absl::StrJoin is not allow-listed. Declared in header
+// file only for unittests.
+std::string StrJoin(const std::vector<std::string>& list, char delimiter);
+
+} // namespace webrtc_openssl_adapter_internal
+
+class OpenSSLAdapter final : public SSLAdapter {
+ public:
+ static bool InitializeSSL();
+ static bool CleanupSSL();
+
+ // Creating an OpenSSLAdapter requires a socket to bind to, an optional
+ // session cache if you wish to improve performance by caching sessions for
+ // hostnames you have previously connected to and an optional
+ // SSLCertificateVerifier which can override any existing trusted roots to
+ // validate a peer certificate. The cache and verifier are effectively
+ // immutable after the the SSL connection starts.
+ explicit OpenSSLAdapter(Socket* socket,
+ OpenSSLSessionCache* ssl_session_cache = nullptr,
+ SSLCertificateVerifier* ssl_cert_verifier = nullptr);
+ ~OpenSSLAdapter() override;
+
+ void SetIgnoreBadCert(bool ignore) override;
+ void SetAlpnProtocols(const std::vector<std::string>& protos) override;
+ void SetEllipticCurves(const std::vector<std::string>& curves) override;
+ void SetMode(SSLMode mode) override;
+ void SetCertVerifier(SSLCertificateVerifier* ssl_cert_verifier) override;
+ void SetIdentity(std::unique_ptr<SSLIdentity> identity) override;
+ void SetRole(SSLRole role) override;
+ int StartSSL(absl::string_view hostname) override;
+ int Send(const void* pv, size_t cb) override;
+ int SendTo(const void* pv, size_t cb, const SocketAddress& addr) override;
+ int Recv(void* pv, size_t cb, int64_t* timestamp) override;
+ int RecvFrom(void* pv,
+ size_t cb,
+ SocketAddress* paddr,
+ int64_t* timestamp) override;
+ int Close() override;
+ // Note that the socket returns ST_CONNECTING while SSL is being negotiated.
+ ConnState GetState() const override;
+ bool IsResumedSession() override;
+ // Creates a new SSL_CTX object, configured for client-to-server usage
+ // with SSLMode `mode`, and if `enable_cache` is true, with support for
+ // storing successful sessions so that they can be later resumed.
+ // OpenSSLAdapterFactory will call this method to create its own internal
+ // SSL_CTX, and OpenSSLAdapter will also call this when used without a
+ // factory.
+ static SSL_CTX* CreateContext(SSLMode mode, bool enable_cache);
+
+ protected:
+ void OnConnectEvent(Socket* socket) override;
+ void OnReadEvent(Socket* socket) override;
+ void OnWriteEvent(Socket* socket) override;
+ void OnCloseEvent(Socket* socket, int err) override;
+
+ private:
+ class EarlyExitCatcher {
+ public:
+ EarlyExitCatcher(OpenSSLAdapter& adapter_ptr);
+ void disable();
+ ~EarlyExitCatcher();
+
+ private:
+ bool disabled_ = false;
+ OpenSSLAdapter& adapter_ptr_;
+ };
+ enum SSLState {
+ SSL_NONE,
+ SSL_WAIT,
+ SSL_CONNECTING,
+ SSL_CONNECTED,
+ SSL_ERROR
+ };
+
+ int BeginSSL();
+ int ContinueSSL();
+ void Error(absl::string_view context, int err, bool signal = true);
+ void Cleanup();
+ void OnTimeout();
+
+ // Return value and arguments have the same meanings as for Send; `error` is
+ // an output parameter filled with the result of SSL_get_error.
+ int DoSslWrite(const void* pv, size_t cb, int* error);
+ bool SSLPostConnectionCheck(SSL* ssl, absl::string_view host);
+
+ // Logs info about the state of the SSL connection.
+ static void SSLInfoCallback(const SSL* ssl, int where, int ret);
+
+#if defined(OPENSSL_IS_BORINGSSL) && \
+ defined(WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS)
+ static enum ssl_verify_result_t SSLVerifyCallback(SSL* ssl,
+ uint8_t* out_alert);
+ enum ssl_verify_result_t SSLVerifyInternal(SSL* ssl, uint8_t* out_alert);
+#else
+ static int SSLVerifyCallback(int ok, X509_STORE_CTX* store);
+ // Call a custom verifier, if installed.
+ // Returns 1 on success, `status_on_error` on error or verification failure.
+ int SSLVerifyInternal(int status_on_error, SSL* ssl, X509_STORE_CTX* store);
+#endif
+ friend class OpenSSLStreamAdapter; // for custom_verify_callback_;
+
+ // If the SSL_CTX was created with `enable_cache` set to true, this callback
+ // will be called when a SSL session has been successfully established,
+ // to allow its SSL_SESSION* to be cached for later resumption.
+ static int NewSSLSessionCallback(SSL* ssl, SSL_SESSION* session);
+
+ // Optional SSL Shared session cache to improve performance.
+ OpenSSLSessionCache* ssl_session_cache_ = nullptr;
+ // Optional SSL Certificate verifier which can be set by a third party.
+ SSLCertificateVerifier* ssl_cert_verifier_ = nullptr;
+ // The current connection state of the (d)TLS connection.
+ SSLState state_;
+
+#ifdef OPENSSL_IS_BORINGSSL
+ std::unique_ptr<BoringSSLIdentity> identity_;
+#else
+ std::unique_ptr<OpenSSLIdentity> identity_;
+#endif
+ // Indicates whethere this is a client or a server.
+ SSLRole role_;
+ bool ssl_read_needs_write_;
+ bool ssl_write_needs_read_;
+ // This buffer is used if SSL_write fails with SSL_ERROR_WANT_WRITE, which
+ // means we need to keep retrying with *the same exact data* until it
+ // succeeds. Afterwards it will be cleared.
+ Buffer pending_data_;
+ SSL* ssl_;
+ // Holds the SSL context, which may be shared if an session cache is provided.
+ SSL_CTX* ssl_ctx_;
+ // Hostname of server that is being connected, used for SNI.
+ std::string ssl_host_name_;
+ // Set the adapter to DTLS or TLS mode before creating the context.
+ SSLMode ssl_mode_;
+ // If true, the server certificate need not match the configured hostname.
+ bool ignore_bad_cert_;
+ // List of protocols to be used in the TLS ALPN extension.
+ std::vector<std::string> alpn_protocols_;
+ // List of elliptic curves to be used in the TLS elliptic curves extension.
+ std::vector<std::string> elliptic_curves_;
+ // Holds the result of the call to run of the ssl_cert_verify_->Verify()
+ bool custom_cert_verifier_status_;
+ // Flag to cancel pending timeout task.
+ webrtc::ScopedTaskSafety timer_;
+};
+
+// The OpenSSLAdapterFactory is responsbile for creating multiple new
+// OpenSSLAdapters with a shared SSL_CTX and a shared SSL_SESSION cache. The
+// SSL_SESSION cache allows existing SSL_SESSIONS to be reused instead of
+// recreating them leading to a significant performance improvement.
+class OpenSSLAdapterFactory : public SSLAdapterFactory {
+ public:
+ OpenSSLAdapterFactory();
+ ~OpenSSLAdapterFactory() override;
+ // Set the SSL Mode to use with this factory. This should only be set before
+ // the first adapter is created with the factory. If it is called after it
+ // will DCHECK.
+ void SetMode(SSLMode mode) override;
+
+ // Set a custom certificate verifier to be passed down to each instance
+ // created with this factory. This should only ever be set before the first
+ // call to the factory and cannot be changed after the fact.
+ void SetCertVerifier(SSLCertificateVerifier* ssl_cert_verifier) override;
+
+ void SetIdentity(std::unique_ptr<SSLIdentity> identity) override;
+
+ // Choose whether the socket acts as a server socket or client socket.
+ void SetRole(SSLRole role) override;
+
+ // Methods that control server certificate verification, used in unit tests.
+ // Do not call these methods in production code.
+ void SetIgnoreBadCert(bool ignore) override;
+
+ // Constructs a new socket using the shared OpenSSLSessionCache. This means
+ // existing SSLSessions already in the cache will be reused instead of
+ // re-created for improved performance.
+ OpenSSLAdapter* CreateAdapter(Socket* socket) override;
+
+ private:
+ // Holds the SSLMode (DTLS,TLS) that will be used to set the session cache.
+ SSLMode ssl_mode_ = SSL_MODE_TLS;
+ SSLRole ssl_role_ = SSL_CLIENT;
+ bool ignore_bad_cert_ = false;
+
+ std::unique_ptr<SSLIdentity> identity_;
+
+ // Holds a cache of existing SSL Sessions.
+ std::unique_ptr<OpenSSLSessionCache> ssl_session_cache_;
+ // Provides an optional custom callback for verifying SSL certificates, this
+ // in currently only used for TLS-TURN connections.
+ SSLCertificateVerifier* ssl_cert_verifier_ = nullptr;
+ // TODO(benwright): Remove this when context is moved to OpenSSLCommon.
+ // Hold a friend class to the OpenSSLAdapter to retrieve the context.
+ friend class OpenSSLAdapter;
+};
+
+// The EarlyExitCatcher is responsible for calling OpenSSLAdapter::Cleanup on
+// destruction. By doing this we have scoped cleanup which can be disabled if
+// there were no errors, aka early exits.
+
+std::string TransformAlpnProtocols(const std::vector<std::string>& protos);
+
+} // namespace rtc
+
+#endif // RTC_BASE_OPENSSL_ADAPTER_H_