Revert of Remove code interfacing legacy openssl. (patchset #3 id:40001 of https://codereview.webrtc.org/1808763002/ )

Reason for revert:
We will make it possible to link to BoringSSL for WebRTC's usages of the crypto APIs and OpenSSL for other usages in the same binary. Once that is completed, we will reland this.

Original issue's description:
> Remove code interfacing legacy openssl.
>
> BUG=webrtc:5664
>
> Committed: https://crrev.com/4cd331beade6de16c073dcdaf89c4e038bdbf73f
> Cr-Commit-Position: refs/heads/master@{#12041}

TBR=tommi@webrtc.org,davidben@webrtc.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:5664

Review URL: https://codereview.webrtc.org/1828773003 .

Cr-Commit-Position: refs/heads/master@{#12117}
diff --git a/webrtc/base/openssl.h b/webrtc/base/openssl.h
index 58e480f..2071619 100644
--- a/webrtc/base/openssl.h
+++ b/webrtc/base/openssl.h
@@ -13,4 +13,8 @@
 
 #include <openssl/ssl.h>
 
+#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
+#error OpenSSL is older than 1.0.0, which is the minimum supported version.
+#endif
+
 #endif  // WEBRTC_BASE_OPENSSL_H_
diff --git a/webrtc/base/openssladapter.cc b/webrtc/base/openssladapter.cc
index 818e326..264dae9 100644
--- a/webrtc/base/openssladapter.cc
+++ b/webrtc/base/openssladapter.cc
@@ -40,6 +40,34 @@
 #include "webrtc/base/stringutils.h"
 #include "webrtc/base/thread.h"
 
+#ifndef OPENSSL_IS_BORINGSSL
+
+// TODO: Use a nicer abstraction for mutex.
+
+#if defined(WEBRTC_WIN)
+  #define MUTEX_TYPE HANDLE
+  #define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL)
+  #define MUTEX_CLEANUP(x) CloseHandle(x)
+  #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE)
+  #define MUTEX_UNLOCK(x) ReleaseMutex(x)
+  #define THREAD_ID GetCurrentThreadId()
+#elif defined(WEBRTC_POSIX)
+  #define MUTEX_TYPE pthread_mutex_t
+  #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
+  #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
+  #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
+  #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
+  #define THREAD_ID pthread_self()
+#else
+  #error You must define mutex operations appropriate for your platform!
+#endif
+
+struct CRYPTO_dynlock_value {
+  MUTEX_TYPE mutex;
+};
+
+#endif  // #ifndef OPENSSL_IS_BORINGSSL
+
 //////////////////////////////////////////////////////////////////////
 // SocketBIO
 //////////////////////////////////////////////////////////////////////
@@ -149,14 +177,105 @@
 
 namespace rtc {
 
+#ifndef OPENSSL_IS_BORINGSSL
+
+// This array will store all of the mutexes available to OpenSSL.
+static MUTEX_TYPE* mutex_buf = NULL;
+
+static void locking_function(int mode, int n, const char * file, int line) {
+  if (mode & CRYPTO_LOCK) {
+    MUTEX_LOCK(mutex_buf[n]);
+  } else {
+    MUTEX_UNLOCK(mutex_buf[n]);
+  }
+}
+
+static unsigned long id_function() {  // NOLINT
+  // Use old-style C cast because THREAD_ID's type varies with the platform,
+  // in some cases requiring static_cast, and in others requiring
+  // reinterpret_cast.
+  return (unsigned long)THREAD_ID; // NOLINT
+}
+
+static CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) {
+  CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value;
+  if (!value)
+    return NULL;
+  MUTEX_SETUP(value->mutex);
+  return value;
+}
+
+static void dyn_lock_function(int mode, CRYPTO_dynlock_value* l,
+                              const char* file, int line) {
+  if (mode & CRYPTO_LOCK) {
+    MUTEX_LOCK(l->mutex);
+  } else {
+    MUTEX_UNLOCK(l->mutex);
+  }
+}
+
+static void dyn_destroy_function(CRYPTO_dynlock_value* l,
+                                 const char* file, int line) {
+  MUTEX_CLEANUP(l->mutex);
+  delete l;
+}
+
+#endif  // #ifndef OPENSSL_IS_BORINGSSL
+
 VerificationCallback OpenSSLAdapter::custom_verify_callback_ = NULL;
 
 bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) {
-  CRYPTO_library_init();
+  if (!InitializeSSLThread() || !SSL_library_init())
+      return false;
+#if !defined(ADDRESS_SANITIZER) || !defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
+  // Loading the error strings crashes mac_asan.  Omit this debugging aid there.
+  SSL_load_error_strings();
+#endif
+  ERR_load_BIO_strings();
+  OpenSSL_add_all_algorithms();
+  RAND_poll();
   custom_verify_callback_ = callback;
   return true;
 }
 
+bool OpenSSLAdapter::InitializeSSLThread() {
+  // BoringSSL is doing the locking internally, so the callbacks are not used
+  // in this case (and are no-ops anyways).
+#ifndef OPENSSL_IS_BORINGSSL
+  mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
+  if (!mutex_buf)
+    return false;
+  for (int i = 0; i < CRYPTO_num_locks(); ++i)
+    MUTEX_SETUP(mutex_buf[i]);
+
+  // we need to cast our id_function to return an unsigned long -- pthread_t is
+  // a pointer
+  CRYPTO_set_id_callback(id_function);
+  CRYPTO_set_locking_callback(locking_function);
+  CRYPTO_set_dynlock_create_callback(dyn_create_function);
+  CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
+  CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
+#endif  // #ifndef OPENSSL_IS_BORINGSSL
+  return true;
+}
+
+bool OpenSSLAdapter::CleanupSSL() {
+#ifndef OPENSSL_IS_BORINGSSL
+  if (!mutex_buf)
+    return false;
+  CRYPTO_set_id_callback(NULL);
+  CRYPTO_set_locking_callback(NULL);
+  CRYPTO_set_dynlock_create_callback(NULL);
+  CRYPTO_set_dynlock_lock_callback(NULL);
+  CRYPTO_set_dynlock_destroy_callback(NULL);
+  for (int i = 0; i < CRYPTO_num_locks(); ++i)
+    MUTEX_CLEANUP(mutex_buf[i]);
+  delete [] mutex_buf;
+  mutex_buf = NULL;
+#endif  // #ifndef OPENSSL_IS_BORINGSSL
+  return true;
+}
+
 OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket)
   : SSLAdapter(socket),
     state_(SSL_NONE),
diff --git a/webrtc/base/openssladapter.h b/webrtc/base/openssladapter.h
index 14d8bea..cdf45e6 100644
--- a/webrtc/base/openssladapter.h
+++ b/webrtc/base/openssladapter.h
@@ -27,6 +27,8 @@
 class OpenSSLAdapter : public SSLAdapter, public MessageHandler {
 public:
   static bool InitializeSSL(VerificationCallback callback);
+  static bool InitializeSSLThread();
+  static bool CleanupSSL();
 
   OpenSSLAdapter(AsyncSocket* socket);
   ~OpenSSLAdapter() override;
diff --git a/webrtc/base/opensslidentity.cc b/webrtc/base/opensslidentity.cc
index 269bfce..3c421db 100644
--- a/webrtc/base/opensslidentity.cc
+++ b/webrtc/base/opensslidentity.cc
@@ -174,7 +174,11 @@
 }
 
 void OpenSSLKeyPair::AddReference() {
+#if defined(OPENSSL_IS_BORINGSSL)
   EVP_PKEY_up_ref(pkey_);
+#else
+  CRYPTO_add(&pkey_->references, 1, CRYPTO_LOCK_EVP_PKEY);
+#endif
 }
 
 #if !defined(NDEBUG)
@@ -357,7 +361,11 @@
 
 void OpenSSLCertificate::AddReference() const {
   ASSERT(x509_ != NULL);
+#if defined(OPENSSL_IS_BORINGSSL)
   X509_up_ref(x509_);
+#else
+  CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509);
+#endif
 }
 
 // Documented in sslidentity.h.
diff --git a/webrtc/base/opensslstreamadapter.cc b/webrtc/base/opensslstreamadapter.cc
index 831136c..44f1b71 100644
--- a/webrtc/base/opensslstreamadapter.cc
+++ b/webrtc/base/opensslstreamadapter.cc
@@ -38,6 +38,11 @@
 
 namespace rtc {
 
+#if (OPENSSL_VERSION_NUMBER >= 0x10001000L)
+#define HAVE_DTLS_SRTP
+#endif
+
+#ifdef HAVE_DTLS_SRTP
 // SRTP cipher suite table. |internal_name| is used to construct a
 // colon-separated profile strings which is needed by
 // SSL_CTX_set_tlsext_use_srtp().
@@ -51,6 +56,90 @@
     {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80},
     {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32},
     {nullptr, 0}};
+#endif
+
+#ifndef OPENSSL_IS_BORINGSSL
+
+// Cipher name table. Maps internal OpenSSL cipher ids to the RFC name.
+struct SslCipherMapEntry {
+  uint32_t openssl_id;
+  const char* rfc_name;
+};
+
+#define DEFINE_CIPHER_ENTRY_SSL3(name)  {SSL3_CK_##name, "TLS_"#name}
+#define DEFINE_CIPHER_ENTRY_TLS1(name)  {TLS1_CK_##name, "TLS_"#name}
+
+// There currently is no method available to get a RFC-compliant name for a
+// cipher suite from BoringSSL, so we need to define the mapping manually here.
+// This should go away once BoringSSL supports "SSL_CIPHER_standard_name"
+// (as available in OpenSSL if compiled with tracing enabled) or a similar
+// method.
+static const SslCipherMapEntry kSslCipherMap[] = {
+  // TLS v1.0 ciphersuites from RFC2246.
+  DEFINE_CIPHER_ENTRY_SSL3(RSA_RC4_128_SHA),
+  {SSL3_CK_RSA_DES_192_CBC3_SHA,
+      "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
+
+  // AES ciphersuites from RFC3268.
+  {TLS1_CK_RSA_WITH_AES_128_SHA,
+      "TLS_RSA_WITH_AES_128_CBC_SHA"},
+  {TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
+      "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"},
+  {TLS1_CK_RSA_WITH_AES_256_SHA,
+      "TLS_RSA_WITH_AES_256_CBC_SHA"},
+  {TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
+      "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
+
+  // ECC ciphersuites from RFC4492.
+  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_RC4_128_SHA),
+  {TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
+      "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"},
+  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_128_CBC_SHA),
+  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_256_CBC_SHA),
+
+  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_RC4_128_SHA),
+  {TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
+      "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"},
+  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_128_CBC_SHA),
+  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_256_CBC_SHA),
+
+  // TLS v1.2 ciphersuites.
+  {TLS1_CK_RSA_WITH_AES_128_SHA256,
+      "TLS_RSA_WITH_AES_128_CBC_SHA256"},
+  {TLS1_CK_RSA_WITH_AES_256_SHA256,
+      "TLS_RSA_WITH_AES_256_CBC_SHA256"},
+  {TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
+      "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"},
+  {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
+      "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
+
+  // TLS v1.2 GCM ciphersuites from RFC5288.
+  DEFINE_CIPHER_ENTRY_TLS1(RSA_WITH_AES_128_GCM_SHA256),
+  DEFINE_CIPHER_ENTRY_TLS1(RSA_WITH_AES_256_GCM_SHA384),
+  DEFINE_CIPHER_ENTRY_TLS1(DHE_RSA_WITH_AES_128_GCM_SHA256),
+  DEFINE_CIPHER_ENTRY_TLS1(DHE_RSA_WITH_AES_256_GCM_SHA384),
+  DEFINE_CIPHER_ENTRY_TLS1(DH_RSA_WITH_AES_128_GCM_SHA256),
+  DEFINE_CIPHER_ENTRY_TLS1(DH_RSA_WITH_AES_256_GCM_SHA384),
+
+  // ECDH HMAC based ciphersuites from RFC5289.
+  {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
+      "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"},
+  {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
+      "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"},
+  {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
+      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
+  {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
+      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
+
+  // ECDH GCM based ciphersuites from RFC5289.
+  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
+  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_256_GCM_SHA384),
+  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_128_GCM_SHA256),
+  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_256_GCM_SHA384),
+
+  {0, NULL}
+};
+#endif  // #ifndef OPENSSL_IS_BORINGSSL
 
 #if defined(_MSC_VER)
 #pragma warning(push)
@@ -237,6 +326,7 @@
 }
 
 std::string OpenSSLStreamAdapter::SslCipherSuiteToName(int cipher_suite) {
+#ifdef OPENSSL_IS_BORINGSSL
   const SSL_CIPHER* ssl_cipher = SSL_get_cipher_by_value(cipher_suite);
   if (!ssl_cipher) {
     return std::string();
@@ -245,6 +335,15 @@
   std::string rfc_name = std::string(cipher_name);
   OPENSSL_free(cipher_name);
   return rfc_name;
+#else
+  for (const SslCipherMapEntry* entry = kSslCipherMap; entry->rfc_name;
+       ++entry) {
+    if (cipher_suite == static_cast<int>(entry->openssl_id)) {
+      return entry->rfc_name;
+    }
+  }
+  return std::string();
+#endif
 }
 
 bool OpenSSLStreamAdapter::GetSslCipherSuite(int* cipher_suite) {
@@ -289,6 +388,7 @@
                                                 bool use_context,
                                                 uint8_t* result,
                                                 size_t result_len) {
+#ifdef HAVE_DTLS_SRTP
   int i;
 
   i = SSL_export_keying_material(ssl_, result, result_len, label.c_str(),
@@ -299,10 +399,14 @@
     return false;
 
   return true;
+#else
+  return false;
+#endif
 }
 
 bool OpenSSLStreamAdapter::SetDtlsSrtpCryptoSuites(
     const std::vector<int>& ciphers) {
+#ifdef HAVE_DTLS_SRTP
   std::string internal_ciphers;
 
   if (state_ != SSL_NONE)
@@ -333,9 +437,13 @@
 
   srtp_ciphers_ = internal_ciphers;
   return true;
+#else
+  return false;
+#endif
 }
 
 bool OpenSSLStreamAdapter::GetDtlsSrtpCryptoSuite(int* crypto_suite) {
+#ifdef HAVE_DTLS_SRTP
   ASSERT(state_ == SSL_CONNECTED);
   if (state_ != SSL_CONNECTED)
     return false;
@@ -349,6 +457,9 @@
   *crypto_suite = srtp_profile->id;
   ASSERT(!SrtpCryptoSuiteToName(*crypto_suite).empty());
   return true;
+#else
+  return false;
+#endif
 }
 
 int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
@@ -661,6 +772,13 @@
   SSL_set_app_data(ssl_, this);
 
   SSL_set_bio(ssl_, bio, bio);  // the SSL object owns the bio now.
+#ifndef OPENSSL_IS_BORINGSSL
+  if (ssl_mode_ == SSL_MODE_DTLS) {
+    // Enable read-ahead for DTLS so whole packets are read from internal BIO
+    // before parsing. This is done internally by BoringSSL for DTLS.
+    SSL_set_read_ahead(ssl_, 1);
+  }
+#endif
 
   SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
                SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
@@ -780,13 +898,73 @@
 SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
   SSL_CTX *ctx = NULL;
 
+#ifdef OPENSSL_IS_BORINGSSL
     ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
         DTLS_method() : TLS_method());
     // Version limiting for BoringSSL will be done below.
+#else
+  const SSL_METHOD* method;
+  switch (ssl_max_version_) {
+    case SSL_PROTOCOL_TLS_10:
+    case SSL_PROTOCOL_TLS_11:
+      // OpenSSL doesn't support setting min/max versions, so we always use
+      // (D)TLS 1.0 if a max. version below the max. available is requested.
+      if (ssl_mode_ == SSL_MODE_DTLS) {
+        if (role_ == SSL_CLIENT) {
+          method = DTLSv1_client_method();
+        } else {
+          method = DTLSv1_server_method();
+        }
+      } else {
+        if (role_ == SSL_CLIENT) {
+          method = TLSv1_client_method();
+        } else {
+          method = TLSv1_server_method();
+        }
+      }
+      break;
+    case SSL_PROTOCOL_TLS_12:
+    default:
+      if (ssl_mode_ == SSL_MODE_DTLS) {
+#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
+        // DTLS 1.2 only available starting from OpenSSL 1.0.2
+        if (role_ == SSL_CLIENT) {
+          method = DTLS_client_method();
+        } else {
+          method = DTLS_server_method();
+        }
+#else
+        if (role_ == SSL_CLIENT) {
+          method = DTLSv1_client_method();
+        } else {
+          method = DTLSv1_server_method();
+        }
+#endif
+      } else {
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
+        // New API only available starting from OpenSSL 1.1.0
+        if (role_ == SSL_CLIENT) {
+          method = TLS_client_method();
+        } else {
+          method = TLS_server_method();
+        }
+#else
+        if (role_ == SSL_CLIENT) {
+          method = SSLv23_client_method();
+        } else {
+          method = SSLv23_server_method();
+        }
+#endif
+      }
+      break;
+  }
+  ctx = SSL_CTX_new(method);
+#endif  // OPENSSL_IS_BORINGSSL
 
   if (ctx == NULL)
     return NULL;
 
+#ifdef OPENSSL_IS_BORINGSSL
   SSL_CTX_set_min_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
       DTLS1_VERSION : TLS1_VERSION);
   switch (ssl_max_version_) {
@@ -804,6 +982,7 @@
           DTLS1_2_VERSION : TLS1_2_VERSION);
       break;
   }
+#endif
 
   if (identity_ && !identity_->ConfigureIdentity(ctx)) {
     SSL_CTX_free(ctx);
@@ -831,12 +1010,14 @@
   SSL_CTX_set_cipher_list(ctx,
       "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK");
 
+#ifdef HAVE_DTLS_SRTP
   if (!srtp_ciphers_.empty()) {
     if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
       SSL_CTX_free(ctx);
       return NULL;
     }
   }
+#endif
 
   return ctx;
 }
@@ -928,11 +1109,19 @@
 }
 
 bool OpenSSLStreamAdapter::HaveDtlsSrtp() {
+#ifdef HAVE_DTLS_SRTP
   return true;
+#else
+  return false;
+#endif
 }
 
 bool OpenSSLStreamAdapter::HaveExporter() {
+#ifdef HAVE_DTLS_SRTP
   return true;
+#else
+  return false;
+#endif
 }
 
 #define CDEF(X) \
diff --git a/webrtc/base/ssladapter.cc b/webrtc/base/ssladapter.cc
index 68c3840..454a566 100644
--- a/webrtc/base/ssladapter.cc
+++ b/webrtc/base/ssladapter.cc
@@ -44,14 +44,20 @@
   return OpenSSLAdapter::InitializeSSL(callback);
 }
 
+bool InitializeSSLThread() {
+  return OpenSSLAdapter::InitializeSSLThread();
+}
+
+bool CleanupSSL() {
+  return OpenSSLAdapter::CleanupSSL();
+}
+
 #else  // !SSL_USE_OPENSSL
 
 bool InitializeSSL(VerificationCallback callback) {
   return true;
 }
 
-#endif  // SSL_USE_OPENSSL
-
 bool InitializeSSLThread() {
   return true;
 }
@@ -60,6 +66,8 @@
   return true;
 }
 
+#endif  // SSL_USE_OPENSSL
+
 ///////////////////////////////////////////////////////////////////////////////
 
 }  // namespace rtc