Blame SOURCES/0003-Add-hybrid-support-for-OpenSSL-1.0-and-1.1.patch

105ad9
From e4bcbd5885e93ea4620103efc303c9b61982851b Mon Sep 17 00:00:00 2001
105ad9
From: Jeremy Barton <jbarton@microsoft.com>
105ad9
Date: Tue, 4 Sep 2018 12:53:06 -0700
105ad9
Subject: [PATCH 3/7] Add hybrid support for OpenSSL 1.0 and 1.1
105ad9
105ad9
This changes the functional code to use OpenSSL 1.1 API in the places where the API changed. "apibridge" provides equivalent methods for the OpenSSL 1.0 environment.
105ad9
105ad9
The following configurations have been tested:
105ad9
105ad9
* Non-portable against OpenSSL 1.0
105ad9
* Non-portable against OpenSSL 1.1
105ad9
* Portable, built against OpenSSL 1.0 and run against OpenSSL 1.0
105ad9
* Portable, built against OpenSSL 1.0 and run against OpenSSL 1.1
105ad9
* Portable, built against OpenSSL 1.1 and run against OpenSSL 1.0
105ad9
* Portable, built against OpenSSL 1.1 and run against OpenSSL 1.1
105ad9
105ad9
In opensslshim, the PER_FUNCTION_BLOCK macro style has been broken up into a named purposes:
105ad9
105ad9
* REQUIRED_FUNCTION(fn)
105ad9
  * API that we use unconditionally, regardless of version
105ad9
  * Formerly PER_FUNCTION_BLOCK(fn, true)
105ad9
* NEW_REQUIRED_FUNCTION(fn)
105ad9
  * API that we use unconditionally in paths that only exist against OpenSSL 1.1, is not probed for when the runtime is 1.0
105ad9
* LIGHTUP_FUNCTION(fn)
105ad9
  * API that might not exist, must be probed with API_EXISTS checks before being utilized
105ad9
  * Formerly PER_FUNCTION_BLOCK(fn, false)
105ad9
* FALLBACK_FUNCTION(fn)
105ad9
  * API that is required on OpenSSL 1.1, and when not found will bind to a method named local_#fn in the shim library
105ad9
* RENAMED_FUNCTION(fn,oldfn)
105ad9
  * Handles a rename with no signature change from oldfn to newfn, binds appropriately based on the runtime library.
105ad9
* LEGACY_FUNCTION(fn)
105ad9
  * API that we use unconditionally in paths that only exist against OpenSSL 1.0, is not probed for when the runtime is 1.1.
105ad9
105ad9
Two new #defines are available, but ideally need no further usage:
105ad9
105ad9
* NEED_OPENSSL_1_0
105ad9
  * Defined when building portable, or on non-portable when the headers are OpenSSL 1.0
105ad9
* NEED_OPENSSL_1_1
105ad9
  * Defined when building portable, or on non-portable when the headers are OpenSSL 1.1
105ad9
---
105ad9
 .../SafeHandles/SafeEvpPKeyHandle.Unix.cs     |   7 +-
105ad9
 .../CMakeLists.txt                            |   3 +-
105ad9
 .../apibridge.cpp                             | 524 ++++++++++
105ad9
 .../apibridge.h                               |  45 +
105ad9
 .../configure.cmake                           |   5 -
105ad9
 .../openssl.cpp                               | 199 ++--
105ad9
 .../openssl.h                                 |  11 +
105ad9
 .../openssl_1_0_structs.h                     | 139 +++
105ad9
 .../opensslshim.cpp                           |  60 +-
105ad9
 .../opensslshim.h                             | 928 ++++++++++++------
105ad9
 .../pal_asn1.cpp                              |   2 +-
105ad9
 .../pal_asn1.h                                |   2 +-
105ad9
 .../pal_asn1_print.cpp                        |   9 +-
105ad9
 .../pal_crypto_config.h.in                    |   2 -
105ad9
 .../pal_dsa.cpp                               | 123 ++-
105ad9
 .../pal_dsa.h                                 |  10 +-
105ad9
 .../pal_evp.cpp                               |   6 +-
105ad9
 .../pal_evp_cipher.cpp                        |  26 +-
105ad9
 .../pal_evp_pkey.cpp                          |   2 +-
105ad9
 .../pal_hmac.cpp                              |  12 +-
105ad9
 .../pal_hmac.h                                |   1 -
105ad9
 .../pal_rsa.cpp                               | 158 +--
105ad9
 .../pal_rsa.h                                 |  16 +-
105ad9
 .../pal_ssl.cpp                               | 144 ++-
105ad9
 .../pal_x509.cpp                              |  16 +-
105ad9
 .../pal_x509_root.cpp                         |   1 +
105ad9
 .../Internal/Cryptography/OpenSslCipher.cs    |  19 +
105ad9
 27 files changed, 1878 insertions(+), 592 deletions(-)
105ad9
 create mode 100644 src/Native/Unix/System.Security.Cryptography.Native/apibridge.cpp
105ad9
 create mode 100644 src/Native/Unix/System.Security.Cryptography.Native/apibridge.h
105ad9
 create mode 100644 src/Native/Unix/System.Security.Cryptography.Native/openssl.h
105ad9
 create mode 100644 src/Native/Unix/System.Security.Cryptography.Native/openssl_1_0_structs.h
105ad9
105ad9
diff --git a/src/Common/src/Microsoft/Win32/SafeHandles/SafeEvpPKeyHandle.Unix.cs b/src/Common/src/Microsoft/Win32/SafeHandles/SafeEvpPKeyHandle.Unix.cs
105ad9
index c706b1ce88..e51a7ca981 100644
105ad9
--- a/src/Common/src/Microsoft/Win32/SafeHandles/SafeEvpPKeyHandle.Unix.cs
105ad9
+++ b/src/Common/src/Microsoft/Win32/SafeHandles/SafeEvpPKeyHandle.Unix.cs
105ad9
@@ -52,12 +52,9 @@ namespace System.Security.Cryptography
105ad9
             // that we don't lose a tracked reference in low-memory situations.
105ad9
             SafeEvpPKeyHandle safeHandle = new SafeEvpPKeyHandle();
105ad9
 
105ad9
-            int newRefCount = Interop.Crypto.UpRefEvpPkey(this);
105ad9
+            int success = Interop.Crypto.UpRefEvpPkey(this);
105ad9
 
105ad9
-            // UpRefEvpPkey returns the number of references to this key, if it's less than 2
105ad9
-            // (the incoming handle, and this one) then someone has already Disposed() this key
105ad9
-            // into non-existence.
105ad9
-            if (newRefCount < 2)
105ad9
+            if (success != 1)
105ad9
             {
105ad9
                 Debug.Fail("Called UpRefEvpPkey on a key which was already marked for destruction");
105ad9
                 throw Interop.Crypto.CreateOpenSslCryptographicException();
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt b/src/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt
105ad9
index 352f456d07..9fef63fda8 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt
105ad9
@@ -6,7 +6,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
105ad9
 # These are happening inside of OpenSSL-defined macros out of our control
105ad9
 add_compile_options(-Wno-cast-align)
105ad9
 
105ad9
-add_definitions(-DPIC=1)
105ad9
+add_definitions(-DPIC=1 -DOPENSSL_API_COMPAT=0x10100000L)
105ad9
 
105ad9
 if(CMAKE_STATIC_LIB_LINK)
105ad9
    set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
105ad9
@@ -16,6 +16,7 @@ find_package(OpenSSL REQUIRED)
105ad9
 include_directories(SYSTEM ${OPENSSL_INCLUDE_DIR})
105ad9
 
105ad9
 set(NATIVECRYPTO_SOURCES
105ad9
+    apibridge.cpp
105ad9
     openssl.cpp
105ad9
     pal_asn1.cpp
105ad9
     pal_asn1_print.cpp
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/apibridge.cpp b/src/Native/Unix/System.Security.Cryptography.Native/apibridge.cpp
105ad9
new file mode 100644
105ad9
index 0000000000..fd43051c3f
105ad9
--- /dev/null
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/apibridge.cpp
105ad9
@@ -0,0 +1,524 @@
105ad9
+// Licensed to the .NET Foundation under one or more agreements.
105ad9
+// The .NET Foundation licenses this file to you under the MIT license.
105ad9
+// See the LICENSE file in the project root for more information.
105ad9
+
105ad9
+#include "opensslshim.h"
105ad9
+#include "pal_crypto_types.h"
105ad9
+#include "pal_types.h"
105ad9
+
105ad9
+#ifdef NEED_OPENSSL_1_0
105ad9
+
105ad9
+#include "apibridge.h"
105ad9
+
105ad9
+// Minimally define the structs from 1.0.x which went opaque in 1.1.0 for the
105ad9
+// portable build building against the 1.1.x headers
105ad9
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM
105ad9
+#include "openssl_1_0_structs.h"
105ad9
+
105ad9
+#define CRYPTO_LOCK_X509 3
105ad9
+#define CRYPTO_LOCK_EVP_PKEY 10
105ad9
+
105ad9
+#define SSL_CTRL_GET_SESSION_REUSED 8
105ad9
+#define SSL_CTRL_OPTIONS 32
105ad9
+
105ad9
+#define SSL_ST_OK 3
105ad9
+#endif
105ad9
+
105ad9
+extern "C" const ASN1_TIME* local_X509_get0_notBefore(const X509* x509)
105ad9
+{
105ad9
+    if (x509 && x509->cert_info && x509->cert_info->validity)
105ad9
+    {
105ad9
+        return x509->cert_info->validity->notBefore;
105ad9
+    }
105ad9
+
105ad9
+    return nullptr;
105ad9
+}
105ad9
+
105ad9
+extern "C" const ASN1_TIME* local_X509_get0_notAfter(const X509* x509)
105ad9
+{
105ad9
+    if (x509 && x509->cert_info && x509->cert_info->validity)
105ad9
+    {
105ad9
+        return x509->cert_info->validity->notAfter;
105ad9
+    }
105ad9
+
105ad9
+    return nullptr;
105ad9
+}
105ad9
+
105ad9
+extern "C" const ASN1_TIME* local_X509_CRL_get0_nextUpdate(const X509_CRL* crl)
105ad9
+{
105ad9
+    if (crl && crl->crl)
105ad9
+    {
105ad9
+        return crl->crl->nextUpdate;
105ad9
+    }
105ad9
+
105ad9
+    return nullptr;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_X509_get_version(const X509* x509)
105ad9
+{
105ad9
+    if (x509 && x509->cert_info)
105ad9
+    {
105ad9
+        long ver = ASN1_INTEGER_get(x509->cert_info->version);
105ad9
+        return (int32_t)ver;
105ad9
+    }
105ad9
+
105ad9
+    return -1;
105ad9
+}
105ad9
+
105ad9
+extern "C" X509_PUBKEY* local_X509_get_X509_PUBKEY(const X509* x509)
105ad9
+{
105ad9
+    if (x509)
105ad9
+    {
105ad9
+        return x509->cert_info->key;
105ad9
+    }
105ad9
+
105ad9
+    return nullptr;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_X509_PUBKEY_get0_param(
105ad9
+    ASN1_OBJECT** palgOid, const uint8_t** pkeyBytes, int* pkeyBytesLen, X509_ALGOR** palg, X509_PUBKEY* pubkey)
105ad9
+{
105ad9
+    if (palgOid)
105ad9
+    {
105ad9
+        *palgOid = pubkey->algor->algorithm;
105ad9
+    }
105ad9
+
105ad9
+    if (pkeyBytes)
105ad9
+    {
105ad9
+        *pkeyBytes = pubkey->public_key->data;
105ad9
+        *pkeyBytesLen = pubkey->public_key->length;
105ad9
+    }
105ad9
+
105ad9
+    if (palg)
105ad9
+    {
105ad9
+        *palg = pubkey->algor;
105ad9
+    }
105ad9
+
105ad9
+    return 1;
105ad9
+}
105ad9
+
105ad9
+extern "C" const X509_ALGOR* local_X509_get0_tbs_sigalg(const X509* x509)
105ad9
+{
105ad9
+    if (x509 && x509->cert_info)
105ad9
+    {
105ad9
+        return x509->cert_info->signature;
105ad9
+    }
105ad9
+
105ad9
+    return nullptr;
105ad9
+}
105ad9
+
105ad9
+extern "C" ASN1_BIT_STRING* local_X509_get0_pubkey_bitstr(const X509* x509)
105ad9
+{
105ad9
+    if (x509 && x509->cert_info && x509->cert_info->key)
105ad9
+    {
105ad9
+        return x509->cert_info->key->public_key;
105ad9
+    }
105ad9
+
105ad9
+    return nullptr;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_X509_NAME_get0_der(X509_NAME* x509Name, const uint8_t** pder, size_t* pderlen)
105ad9
+{
105ad9
+    if (!x509Name || !x509Name->bytes)
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if (pder)
105ad9
+    {
105ad9
+        *pder = (unsigned char*)x509Name->bytes->data;
105ad9
+    }
105ad9
+
105ad9
+    if (pderlen)
105ad9
+    {
105ad9
+        *pderlen = x509Name->bytes->length;
105ad9
+    }
105ad9
+
105ad9
+    return 1;
105ad9
+}
105ad9
+
105ad9
+#ifndef SSLEAY_VERSION
105ad9
+#define SSLEAY_VERSION 0
105ad9
+#endif
105ad9
+
105ad9
+extern "C" const char* local_OpenSSL_version(int t)
105ad9
+{
105ad9
+    (void)t;
105ad9
+    return SSLeay_version(SSLEAY_VERSION);
105ad9
+}
105ad9
+
105ad9
+extern "C" const DSA_METHOD* local_DSA_get_method(const DSA* dsa)
105ad9
+{
105ad9
+    if (dsa)
105ad9
+    {
105ad9
+        return dsa->meth;
105ad9
+    }
105ad9
+
105ad9
+    return nullptr;
105ad9
+}
105ad9
+
105ad9
+extern "C" void local_DSA_get0_pqg(const DSA* dsa, const BIGNUM** p, const BIGNUM** q, const BIGNUM** g)
105ad9
+{
105ad9
+    if (!dsa)
105ad9
+    {
105ad9
+        return;
105ad9
+    }
105ad9
+
105ad9
+    if (p)
105ad9
+    {
105ad9
+        *p = dsa->p;
105ad9
+    }
105ad9
+
105ad9
+    if (q)
105ad9
+    {
105ad9
+        *q = dsa->q;
105ad9
+    }
105ad9
+
105ad9
+    if (g)
105ad9
+    {
105ad9
+        *g = dsa->g;
105ad9
+    }
105ad9
+}
105ad9
+
105ad9
+extern "C" const BIGNUM* local_DSA_get0_key(const DSA* dsa, const BIGNUM** pubKey, const BIGNUM** privKey)
105ad9
+{
105ad9
+    if (dsa)
105ad9
+    {
105ad9
+        if (pubKey)
105ad9
+        {
105ad9
+            *pubKey = dsa->pub_key;
105ad9
+        }
105ad9
+
105ad9
+        if (privKey)
105ad9
+        {
105ad9
+            *privKey = dsa->priv_key;
105ad9
+        }
105ad9
+    }
105ad9
+
105ad9
+    return nullptr;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_DSA_set0_pqg(DSA* dsa, BIGNUM* bnP, BIGNUM* bnQ, BIGNUM* bnG)
105ad9
+{
105ad9
+    if (!dsa)
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if ((dsa->p == nullptr && bnP == nullptr) || (dsa->q == nullptr && bnQ == nullptr) || (dsa->g == nullptr && bnG == nullptr))
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if (bnP)
105ad9
+    {
105ad9
+        BN_free(dsa->p);
105ad9
+        dsa->p = bnP;
105ad9
+    }
105ad9
+
105ad9
+    if (bnQ)
105ad9
+    {
105ad9
+        BN_free(dsa->q);
105ad9
+        dsa->q = bnQ;
105ad9
+    }
105ad9
+
105ad9
+    if (bnG)
105ad9
+    {
105ad9
+        BN_free(dsa->g);
105ad9
+        dsa->g = bnG;
105ad9
+    }
105ad9
+
105ad9
+    return 1;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_DSA_set0_key(DSA* dsa, BIGNUM* bnY, BIGNUM* bnX)
105ad9
+{
105ad9
+    if (!dsa)
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if (dsa->pub_key == nullptr && bnY == nullptr)
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if (bnY)
105ad9
+    {
105ad9
+        BN_free(dsa->pub_key);
105ad9
+        dsa->pub_key = bnY;
105ad9
+    }
105ad9
+
105ad9
+    if (bnX)
105ad9
+    {
105ad9
+        BN_free(dsa->priv_key);
105ad9
+        dsa->priv_key = bnX;
105ad9
+    }
105ad9
+
105ad9
+    return 1;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_EVP_PKEY_up_ref(EVP_PKEY* pkey)
105ad9
+{
105ad9
+    if (!pkey)
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    return CRYPTO_add_lock(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY, __FILE__, __LINE__) > 1;
105ad9
+}
105ad9
+
105ad9
+extern "C" EVP_CIPHER_CTX* local_EVP_CIPHER_CTX_new()
105ad9
+{
105ad9
+    EVP_CIPHER_CTX* ctx = (EVP_CIPHER_CTX*)calloc(1, sizeof(EVP_CIPHER_CTX));
105ad9
+    return ctx;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX* ctx)
105ad9
+{
105ad9
+    if (ctx)
105ad9
+    {
105ad9
+        int ret = EVP_CIPHER_CTX_cleanup(ctx);
105ad9
+        EVP_CIPHER_CTX_init(ctx);
105ad9
+        return ret;
105ad9
+    }
105ad9
+
105ad9
+    // OpenSSL 1.1 returns succes 1 on a NULL input
105ad9
+    return 1;
105ad9
+}
105ad9
+
105ad9
+extern "C" void local_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX* ctx)
105ad9
+{
105ad9
+    if (ctx)
105ad9
+    {
105ad9
+        local_EVP_CIPHER_CTX_reset(ctx);
105ad9
+        free(ctx);
105ad9
+    }
105ad9
+}
105ad9
+
105ad9
+extern "C" HMAC_CTX* local_HMAC_CTX_new()
105ad9
+{
105ad9
+    HMAC_CTX* ctx = (HMAC_CTX*)calloc(1, sizeof(HMAC_CTX));
105ad9
+
105ad9
+    if (ctx)
105ad9
+    {
105ad9
+        HMAC_CTX_init(ctx);
105ad9
+    }
105ad9
+
105ad9
+    return ctx;
105ad9
+}
105ad9
+
105ad9
+extern "C" void local_HMAC_CTX_free(HMAC_CTX* ctx)
105ad9
+{
105ad9
+    if (ctx != nullptr)
105ad9
+    {
105ad9
+        HMAC_CTX_cleanup(ctx);
105ad9
+        free(ctx);
105ad9
+    }
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_RSA_meth_get_flags(const RSA_METHOD* meth)
105ad9
+{
105ad9
+    if (meth)
105ad9
+    {
105ad9
+        return meth->flags;
105ad9
+    }
105ad9
+
105ad9
+    return 0;
105ad9
+}
105ad9
+
105ad9
+extern "C" void local_RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d)
105ad9
+{
105ad9
+    if (rsa)
105ad9
+    {
105ad9
+        if (n)
105ad9
+        {
105ad9
+            *n = rsa->n;
105ad9
+        }
105ad9
+
105ad9
+        if (e)
105ad9
+        {
105ad9
+            *e = rsa->e;
105ad9
+        }
105ad9
+
105ad9
+        if (d)
105ad9
+        {
105ad9
+            *d = rsa->d;
105ad9
+        }
105ad9
+    }
105ad9
+}
105ad9
+
105ad9
+extern "C" void local_RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q)
105ad9
+{
105ad9
+    if (rsa)
105ad9
+    {
105ad9
+        if (p)
105ad9
+        {
105ad9
+            *p = rsa->p;
105ad9
+        }
105ad9
+
105ad9
+        if (q)
105ad9
+        {
105ad9
+            *q = rsa->q;
105ad9
+        }
105ad9
+    }
105ad9
+}
105ad9
+
105ad9
+extern "C" void local_RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp)
105ad9
+{
105ad9
+    if (rsa)
105ad9
+    {
105ad9
+        if (dmp1)
105ad9
+        {
105ad9
+            *dmp1 = rsa->dmp1;
105ad9
+        }
105ad9
+
105ad9
+        if (dmq1)
105ad9
+        {
105ad9
+            *dmq1 = rsa->dmq1;
105ad9
+        }
105ad9
+
105ad9
+        if (iqmp)
105ad9
+        {
105ad9
+            *iqmp = rsa->iqmp;
105ad9
+        }
105ad9
+    }
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d)
105ad9
+{
105ad9
+    if (rsa == nullptr)
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if ((rsa->n == nullptr && n == nullptr) || (rsa->e == nullptr && e == nullptr))
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if (n != nullptr)
105ad9
+    {
105ad9
+        BN_free(rsa->n);
105ad9
+        rsa->n = n;
105ad9
+    }
105ad9
+
105ad9
+    if (e != nullptr)
105ad9
+    {
105ad9
+        BN_free(rsa->e);
105ad9
+        rsa->e = e;
105ad9
+    }
105ad9
+
105ad9
+    if (d != nullptr)
105ad9
+    {
105ad9
+        BN_free(rsa->d);
105ad9
+        rsa->d = d;
105ad9
+    }
105ad9
+
105ad9
+    return 1;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q)
105ad9
+{
105ad9
+    if (rsa == nullptr)
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if ((rsa->p == nullptr && p == nullptr) || (rsa->q == nullptr && q == nullptr))
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if (p != nullptr)
105ad9
+    {
105ad9
+        BN_free(rsa->p);
105ad9
+        rsa->p = p;
105ad9
+    }
105ad9
+
105ad9
+    if (q != nullptr)
105ad9
+    {
105ad9
+        BN_free(rsa->q);
105ad9
+        rsa->q = q;
105ad9
+    }
105ad9
+
105ad9
+    return 1;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp)
105ad9
+{
105ad9
+    if (rsa == nullptr)
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if ((rsa->dmp1 == nullptr && dmp1 == nullptr) || (rsa->dmq1 == nullptr && dmq1 == nullptr) ||
105ad9
+        (rsa->iqmp == nullptr && iqmp == nullptr))
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if (dmp1 != nullptr)
105ad9
+    {
105ad9
+        BN_free(rsa->dmp1);
105ad9
+        rsa->dmp1 = dmp1;
105ad9
+    }
105ad9
+
105ad9
+    if (dmq1 != nullptr)
105ad9
+    {
105ad9
+        BN_free(rsa->dmq1);
105ad9
+        rsa->dmq1 = dmq1;
105ad9
+    }
105ad9
+
105ad9
+    if (iqmp != nullptr)
105ad9
+    {
105ad9
+        BN_free(rsa->iqmp);
105ad9
+        rsa->iqmp = iqmp;
105ad9
+    }
105ad9
+
105ad9
+    return 1;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_SSL_is_init_finished(const SSL* ssl)
105ad9
+{
105ad9
+    return SSL_state(ssl) == SSL_ST_OK;
105ad9
+}
105ad9
+
105ad9
+extern "C" X509Stack* local_X509_STORE_CTX_get0_untrusted(X509_STORE_CTX* ctx)
105ad9
+{
105ad9
+    return ctx ? ctx->untrusted : nullptr;
105ad9
+}
105ad9
+
105ad9
+extern "C" X509* local_X509_STORE_CTX_get0_cert(X509_STORE_CTX* ctx)
105ad9
+{
105ad9
+    return ctx ? ctx->cert : nullptr;
105ad9
+}
105ad9
+
105ad9
+extern "C" int32_t local_X509_up_ref(X509* x509)
105ad9
+{
105ad9
+    if (x509 != nullptr)
105ad9
+    {
105ad9
+        return CRYPTO_add_lock(&x509->references, 1, CRYPTO_LOCK_X509, __FILE__, __LINE__) > 1;
105ad9
+    }
105ad9
+
105ad9
+    return 0;
105ad9
+}
105ad9
+
105ad9
+extern "C" unsigned long local_SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options)
105ad9
+{
105ad9
+    // SSL_CTX_ctrl is signed long in and signed long out; but SSL_CTX_set_options,
105ad9
+    // which was a macro call to SSL_CTX_ctrl in 1.0, is unsigned/unsigned.
105ad9
+    return (unsigned long)SSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, (long)options, nullptr);
105ad9
+}
105ad9
+
105ad9
+extern "C" int local_SSL_session_reused(SSL* ssl)
105ad9
+{
105ad9
+    return (int)SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, nullptr);
105ad9
+}
105ad9
+
105ad9
+extern "C" void local_SSL_CTX_set_security_level(SSL_CTX* ctx, int32_t level)
105ad9
+{
105ad9
+    (void)ctx;
105ad9
+    (void)level;
105ad9
+}
105ad9
+#endif
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/apibridge.h b/src/Native/Unix/System.Security.Cryptography.Native/apibridge.h
105ad9
new file mode 100644
105ad9
index 0000000000..39d2718a30
105ad9
--- /dev/null
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/apibridge.h
105ad9
@@ -0,0 +1,45 @@
105ad9
+// Licensed to the .NET Foundation under one or more agreements.
105ad9
+// The .NET Foundation licenses this file to you under the MIT license.
105ad9
+// See the LICENSE file in the project root for more information.
105ad9
+
105ad9
+// Functions based on OpenSSL 1.1 API, used when building against/running with OpenSSL 1.0
105ad9
+
105ad9
+#pragma once
105ad9
+#include "pal_types.h"
105ad9
+
105ad9
+extern "C" const BIGNUM* local_DSA_get0_key(const DSA* dsa, const BIGNUM** pubKey, const BIGNUM** privKey);
105ad9
+extern "C" void local_DSA_get0_pqg(const DSA* dsa, const BIGNUM** p, const BIGNUM** q, const BIGNUM** g);
105ad9
+extern "C" const DSA_METHOD* local_DSA_get_method(const DSA* dsa);
105ad9
+extern "C" int32_t local_DSA_set0_key(DSA* dsa, BIGNUM* bnY, BIGNUM* bnX);
105ad9
+extern "C" int32_t local_DSA_set0_pqg(DSA* dsa, BIGNUM* bnP, BIGNUM* bnQ, BIGNUM* bnG);
105ad9
+extern "C" void local_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX* ctx);
105ad9
+extern "C" EVP_CIPHER_CTX* local_EVP_CIPHER_CTX_new(void);
105ad9
+extern "C" int32_t local_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX* ctx);
105ad9
+extern "C" int32_t local_EVP_PKEY_up_ref(EVP_PKEY* pkey);
105ad9
+extern "C" void local_HMAC_CTX_free(HMAC_CTX* ctx);
105ad9
+extern "C" HMAC_CTX* local_HMAC_CTX_new(void);
105ad9
+extern "C" const char* local_OpenSSL_version(int t);
105ad9
+extern "C" void local_RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp);
105ad9
+extern "C" void local_RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q);
105ad9
+extern "C" void local_RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d);
105ad9
+extern "C" int32_t local_RSA_meth_get_flags(const RSA_METHOD* meth);
105ad9
+extern "C" int32_t local_RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);
105ad9
+extern "C" int32_t local_RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q);
105ad9
+extern "C" int32_t local_RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d);
105ad9
+extern "C" int32_t local_SSL_is_init_finished(const SSL* ssl);
105ad9
+extern "C" unsigned long local_SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options);
105ad9
+extern "C" void local_SSL_CTX_set_security_level(SSL_CTX* ctx, int32_t level);
105ad9
+extern "C" int local_SSL_session_reused(SSL* ssl);
105ad9
+extern "C" const ASN1_TIME* local_X509_CRL_get0_nextUpdate(const X509_CRL* crl);
105ad9
+extern "C" int32_t local_X509_NAME_get0_der(X509_NAME* x509Name, const uint8_t** pder, size_t* pderlen);
105ad9
+extern "C" int32_t local_X509_PUBKEY_get0_param(
105ad9
+    ASN1_OBJECT** palgOid, const uint8_t** pkeyBytes, int* pkeyBytesLen, X509_ALGOR** palg, X509_PUBKEY* pubkey);
105ad9
+extern "C" X509* local_X509_STORE_CTX_get0_cert(X509_STORE_CTX* ctx);
105ad9
+extern "C" STACK_OF(X509) * local_X509_STORE_CTX_get0_untrusted(X509_STORE_CTX* ctx);
105ad9
+extern "C" const ASN1_TIME* local_X509_get0_notAfter(const X509* x509);
105ad9
+extern "C" const ASN1_TIME* local_X509_get0_notBefore(const X509* x509);
105ad9
+extern "C" ASN1_BIT_STRING* local_X509_get0_pubkey_bitstr(const X509* x509);
105ad9
+extern "C" const X509_ALGOR* local_X509_get0_tbs_sigalg(const X509* x509);
105ad9
+extern "C" X509_PUBKEY* local_X509_get_X509_PUBKEY(const X509* x509);
105ad9
+extern "C" int32_t local_X509_get_version(const X509* x509);
105ad9
+extern "C" int32_t local_X509_up_ref(X509* x509);
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/configure.cmake b/src/Native/Unix/System.Security.Cryptography.Native/configure.cmake
105ad9
index 809ffe318e..cdc9f50f3c 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/configure.cmake
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/configure.cmake
105ad9
@@ -2,11 +2,6 @@ include(CheckLibraryExists)
105ad9
 include(CheckFunctionExists)
105ad9
 
105ad9
 set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
105ad9
-
105ad9
-# Check which versions of TLS the OpenSSL/ssl library supports
105ad9
-check_library_exists(${OPENSSL_SSL_LIBRARY} "TLSv1_1_method" "" HAVE_TLS_V1_1)
105ad9
-check_library_exists(${OPENSSL_SSL_LIBRARY} "TLSv1_2_method" "" HAVE_TLS_V1_2)
105ad9
-
105ad9
 set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
105ad9
 
105ad9
 check_function_exists(
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/openssl.cpp b/src/Native/Unix/System.Security.Cryptography.Native/openssl.cpp
105ad9
index 46396370b4..f419b755b7 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/openssl.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/openssl.cpp
105ad9
@@ -6,6 +6,7 @@
105ad9
 #include "pal_utilities.h"
105ad9
 #include "pal_safecrt.h"
105ad9
 #include "opensslshim.h"
105ad9
+#include "openssl.h"
105ad9
 
105ad9
 #include <assert.h>
105ad9
 #include <limits.h>
105ad9
@@ -78,7 +79,7 @@ extern "C" int32_t CryptoNative_GetX509Thumbprint(X509* x509, uint8_t* pBuf, int
105ad9
         return -SHA_DIGEST_LENGTH;
105ad9
     }
105ad9
 
105ad9
-    if (!X509_digest(x509, EVP_sha1(), pBuf, NULL))
105ad9
+    if (!X509_digest(x509, EVP_sha1(), pBuf, nullptr))
105ad9
     {
105ad9
         return 0;
105ad9
     }
105ad9
@@ -97,14 +98,14 @@ Return values:
105ad9
 NULL if the validity cannot be determined, a pointer to the ASN1_TIME structure for the NotBefore value
105ad9
 otherwise.
105ad9
 */
105ad9
-extern "C" ASN1_TIME* CryptoNative_GetX509NotBefore(X509* x509)
105ad9
+extern "C" const ASN1_TIME* CryptoNative_GetX509NotBefore(X509* x509)
105ad9
 {
105ad9
-    if (x509 && x509->cert_info && x509->cert_info->validity)
105ad9
+    if (x509)
105ad9
     {
105ad9
-        return x509->cert_info->validity->notBefore;
105ad9
+        return X509_get0_notBefore(x509);
105ad9
     }
105ad9
 
105ad9
-    return NULL;
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 /*
105ad9
@@ -118,14 +119,14 @@ Return values:
105ad9
 NULL if the validity cannot be determined, a pointer to the ASN1_TIME structure for the NotAfter value
105ad9
 otherwise.
105ad9
 */
105ad9
-extern "C" ASN1_TIME* CryptoNative_GetX509NotAfter(X509* x509)
105ad9
+extern "C" const ASN1_TIME* CryptoNative_GetX509NotAfter(X509* x509)
105ad9
 {
105ad9
-    if (x509 && x509->cert_info && x509->cert_info->validity)
105ad9
+    if (x509)
105ad9
     {
105ad9
-        return x509->cert_info->validity->notAfter;
105ad9
+        return X509_get0_notAfter(x509);
105ad9
     }
105ad9
 
105ad9
-    return NULL;
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 /*
105ad9
@@ -139,14 +140,14 @@ Return values:
105ad9
 NULL if the validity cannot be determined, a pointer to the ASN1_TIME structure for the NextUpdate value
105ad9
 otherwise.
105ad9
 */
105ad9
-extern "C" ASN1_TIME* CryptoNative_GetX509CrlNextUpdate(X509_CRL* crl)
105ad9
+extern "C" const ASN1_TIME* CryptoNative_GetX509CrlNextUpdate(X509_CRL* crl)
105ad9
 {
105ad9
     if (crl)
105ad9
     {
105ad9
-        return X509_CRL_get_nextUpdate(crl);
105ad9
+        return X509_CRL_get0_nextUpdate(crl);
105ad9
     }
105ad9
 
105ad9
-    return NULL;
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 /*
105ad9
@@ -165,9 +166,9 @@ The encoded value of the version, otherwise:
105ad9
 */
105ad9
 extern "C" int32_t CryptoNative_GetX509Version(X509* x509)
105ad9
 {
105ad9
-    if (x509 && x509->cert_info)
105ad9
+    if (x509)
105ad9
     {
105ad9
-        long ver = ASN1_INTEGER_get(x509->cert_info->version);
105ad9
+        long ver = X509_get_version(x509);
105ad9
         return static_cast<int32_t>(ver);
105ad9
     }
105ad9
 
105ad9
@@ -187,12 +188,18 @@ describing the object type.
105ad9
 */
105ad9
 extern "C" ASN1_OBJECT* CryptoNative_GetX509PublicKeyAlgorithm(X509* x509)
105ad9
 {
105ad9
-    if (x509 && x509->cert_info && x509->cert_info->key && x509->cert_info->key->algor)
105ad9
+    if (x509)
105ad9
     {
105ad9
-        return x509->cert_info->key->algor->algorithm;
105ad9
+        X509_PUBKEY* pubkey = X509_get_X509_PUBKEY(x509);
105ad9
+        ASN1_OBJECT* algOid;
105ad9
+
105ad9
+        if (pubkey && X509_PUBKEY_get0_param(&algOid, nullptr, nullptr, nullptr, pubkey))
105ad9
+        {
105ad9
+            return algOid;
105ad9
+        }
105ad9
     }
105ad9
 
105ad9
-    return NULL;
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 /*
105ad9
@@ -208,12 +215,17 @@ describing the object type.
105ad9
 */
105ad9
 extern "C" ASN1_OBJECT* CryptoNative_GetX509SignatureAlgorithm(X509* x509)
105ad9
 {
105ad9
-    if (x509 && x509->sig_alg && x509->sig_alg->algorithm)
105ad9
+    if (x509)
105ad9
     {
105ad9
-        return x509->sig_alg->algorithm;
105ad9
+        const X509_ALGOR* sigAlg = X509_get0_tbs_sigalg(x509);
105ad9
+
105ad9
+        if (sigAlg)
105ad9
+        {
105ad9
+            return sigAlg->algorithm;
105ad9
+        }
105ad9
     }
105ad9
 
105ad9
-    return NULL;
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 /*
105ad9
@@ -230,21 +242,35 @@ Any negative value: The input buffer size was reported as insufficient. A buffer
105ad9
 */
105ad9
 extern "C" int32_t CryptoNative_GetX509PublicKeyParameterBytes(X509* x509, uint8_t* pBuf, int32_t cBuf)
105ad9
 {
105ad9
-    if (!x509 || !x509->cert_info || !x509->cert_info->key || !x509->cert_info->key->algor)
105ad9
+    if (!x509)
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    X509_PUBKEY* pubkey = X509_get_X509_PUBKEY(x509);
105ad9
+
105ad9
+    if (!pubkey)
105ad9
+    {
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    X509_ALGOR* alg;
105ad9
+
105ad9
+    if (!X509_PUBKEY_get0_param(nullptr, nullptr, nullptr, &alg, pubkey) || !alg)
105ad9
     {
105ad9
         return 0;
105ad9
     }
105ad9
 
105ad9
-    ASN1_TYPE* parameter = x509->cert_info->key->algor->parameter;
105ad9
+    ASN1_TYPE* parameter = alg->parameter;
105ad9
 
105ad9
     if (!parameter)
105ad9
     {
105ad9
         // If pBuf is NULL we're asking for the length, so return 0 (which is negative-zero)
105ad9
         // If pBuf is non-NULL we're asking to fill the data, in which case we return 1.
105ad9
-        return pBuf != NULL;
105ad9
+        return pBuf != nullptr;
105ad9
     }
105ad9
-    
105ad9
-    int len = i2d_ASN1_TYPE(parameter, NULL);
105ad9
+
105ad9
+    int len = i2d_ASN1_TYPE(parameter, nullptr);
105ad9
 
105ad9
     if (cBuf < len)
105ad9
     {
105ad9
@@ -275,12 +301,12 @@ the public key.
105ad9
 */
105ad9
 extern "C" ASN1_BIT_STRING* CryptoNative_GetX509PublicKeyBytes(X509* x509)
105ad9
 {
105ad9
-    if (x509 && x509->cert_info && x509->cert_info->key)
105ad9
+    if (x509)
105ad9
     {
105ad9
-        return x509->cert_info->key->public_key;
105ad9
+        return X509_get0_pubkey_bitstr(x509);
105ad9
     }
105ad9
 
105ad9
-    return NULL;
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 /*
105ad9
@@ -353,7 +379,10 @@ Any negative value: The input buffer size was reported as insufficient. A buffer
105ad9
 */
105ad9
 extern "C" int32_t CryptoNative_GetX509NameRawBytes(X509_NAME* x509Name, uint8_t* pBuf, int32_t cBuf)
105ad9
 {
105ad9
-    if (!x509Name || !x509Name->bytes || cBuf < 0)
105ad9
+    const uint8_t* nameBuf;
105ad9
+    size_t nameBufLen;
105ad9
+
105ad9
+    if (!x509Name || cBuf < 0 || !X509_NAME_get0_der(x509Name, &nameBuf, &nameBufLen))
105ad9
     {
105ad9
         return 0;
105ad9
     }
105ad9
@@ -367,13 +396,13 @@ extern "C" int32_t CryptoNative_GetX509NameRawBytes(X509_NAME* x509Name, uint8_t
105ad9
      * value is less than INT_MAX in it's native format; once we know it is not
105ad9
      * too large, we can safely cast to an int to make sure it is not negative
105ad9
      */
105ad9
-    if (x509Name->bytes->length > INT_MAX)
105ad9
+    if (nameBufLen > INT_MAX)
105ad9
     {
105ad9
         assert(0 && "Huge length X509_NAME");
105ad9
         return 0;
105ad9
     }
105ad9
 
105ad9
-    int length = static_cast<int>(x509Name->bytes->length);
105ad9
+    int length = static_cast<int>(nameBufLen);
105ad9
 
105ad9
     if (length < 0)
105ad9
     {
105ad9
@@ -386,7 +415,7 @@ extern "C" int32_t CryptoNative_GetX509NameRawBytes(X509_NAME* x509Name, uint8_t
105ad9
         return -length;
105ad9
     }
105ad9
 
105ad9
-    memcpy_s(pBuf, UnsignedCast(cBuf), x509Name->bytes->data, UnsignedCast(length));
105ad9
+    memcpy_s(pBuf, UnsignedCast(cBuf), nameBuf, UnsignedCast(length));
105ad9
     return 1;
105ad9
 }
105ad9
 
105ad9
@@ -437,9 +466,9 @@ extern "C" BIO* CryptoNative_GetX509NameInfo(X509* x509, int32_t nameType, int32
105ad9
 {
105ad9
     static const char szOidUpn[] = "1.3.6.1.4.1.311.20.2.3";
105ad9
 
105ad9
-    if (!x509 || !x509->cert_info || nameType < NAME_TYPE_SIMPLE || nameType > NAME_TYPE_URL)
105ad9
+    if (!x509 || nameType < NAME_TYPE_SIMPLE || nameType > NAME_TYPE_URL)
105ad9
     {
105ad9
-        return NULL;
105ad9
+        return nullptr;
105ad9
     }
105ad9
 
105ad9
     // Algorithm behaviors (pseudocode).  When forIssuer is true, replace "Subject" with "Issuer" and
105ad9
@@ -454,15 +483,15 @@ extern "C" BIO* CryptoNative_GetX509NameInfo(X509* x509, int32_t nameType, int32
105ad9
     // UrlName: SAN.Entries.FirstOrDefault(type == GEN_URI);
105ad9
     if (nameType == NAME_TYPE_SIMPLE)
105ad9
     {
105ad9
-        X509_NAME* name = forIssuer ? x509->cert_info->issuer : x509->cert_info->subject;
105ad9
+        X509_NAME* name = forIssuer ? X509_get_issuer_name(x509) : X509_get_subject_name(x509);
105ad9
 
105ad9
         if (name)
105ad9
         {
105ad9
-            ASN1_STRING* cn = NULL;
105ad9
-            ASN1_STRING* ou = NULL;
105ad9
-            ASN1_STRING* o = NULL;
105ad9
-            ASN1_STRING* e = NULL;
105ad9
-            ASN1_STRING* firstRdn = NULL;
105ad9
+            ASN1_STRING* cn = nullptr;
105ad9
+            ASN1_STRING* ou = nullptr;
105ad9
+            ASN1_STRING* o = nullptr;
105ad9
+            ASN1_STRING* e = nullptr;
105ad9
+            ASN1_STRING* firstRdn = nullptr;
105ad9
 
105ad9
             // Walk the list backwards because it is stored in stack order
105ad9
             for (int i = X509_NAME_entry_count(name) - 1; i >= 0; --i)
105ad9
@@ -564,7 +593,7 @@ extern "C" BIO* CryptoNative_GetX509NameInfo(X509* x509, int32_t nameType, int32
105ad9
         }
105ad9
 
105ad9
         STACK_OF(GENERAL_NAME)* altNames = static_cast<STACK_OF(GENERAL_NAME)*>(
105ad9
-            X509_get_ext_d2i(x509, forIssuer ? NID_issuer_alt_name : NID_subject_alt_name, NULL, NULL));
105ad9
+            X509_get_ext_d2i(x509, forIssuer ? NID_issuer_alt_name : NID_subject_alt_name, nullptr, nullptr));
105ad9
 
105ad9
         if (altNames)
105ad9
         {
105ad9
@@ -576,7 +605,7 @@ extern "C" BIO* CryptoNative_GetX509NameInfo(X509* x509, int32_t nameType, int32
105ad9
 
105ad9
                 if (altName && altName->type == expectedType)
105ad9
                 {
105ad9
-                    ASN1_STRING* str = NULL;
105ad9
+                    ASN1_STRING* str = nullptr;
105ad9
 
105ad9
                     switch (nameType)
105ad9
                     {
105ad9
@@ -629,7 +658,7 @@ extern "C" BIO* CryptoNative_GetX509NameInfo(X509* x509, int32_t nameType, int32
105ad9
 
105ad9
     if (nameType == NAME_TYPE_EMAIL || nameType == NAME_TYPE_DNS)
105ad9
     {
105ad9
-        X509_NAME* name = forIssuer ? x509->cert_info->issuer : x509->cert_info->subject;
105ad9
+        X509_NAME* name = forIssuer ? X509_get_issuer_name(x509) : X509_get_subject_name(x509);
105ad9
         int expectedNid = NID_undef;
105ad9
 
105ad9
         switch (nameType)
105ad9
@@ -674,7 +703,7 @@ extern "C" BIO* CryptoNative_GetX509NameInfo(X509* x509, int32_t nameType, int32
105ad9
         }
105ad9
     }
105ad9
 
105ad9
-    return NULL;
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 /*
105ad9
@@ -821,7 +850,7 @@ extern "C" int32_t CryptoNative_CheckX509Hostname(X509* x509, const char* hostna
105ad9
     int subjectNid = NID_commonName;
105ad9
     int sanGenType = GEN_DNS;
105ad9
     GENERAL_NAMES* san = static_cast<GENERAL_NAMES*>(
105ad9
-        X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL));
105ad9
+        X509_get_ext_d2i(x509, NID_subject_alt_name, nullptr, nullptr));
105ad9
     char readSubject = 1;
105ad9
     int success = 0;
105ad9
 
105ad9
@@ -909,7 +938,7 @@ extern "C" int32_t CryptoNative_CheckX509IpAddress(
105ad9
 
105ad9
     int subjectNid = NID_commonName;
105ad9
     int sanGenType = GEN_IPADD;
105ad9
-    GENERAL_NAMES* san = static_cast<GENERAL_NAMES*>(X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL));
105ad9
+    GENERAL_NAMES* san = static_cast<GENERAL_NAMES*>(X509_get_ext_d2i(x509, NID_subject_alt_name, nullptr, nullptr));
105ad9
     int success = 0;
105ad9
 
105ad9
     if (san)
105ad9
@@ -1070,7 +1099,7 @@ otherwise NULL.
105ad9
 */
105ad9
 extern "C" X509* CryptoNative_ReadX509AsDerFromBio(BIO* bio)
105ad9
 {
105ad9
-    return d2i_X509_bio(bio, NULL);
105ad9
+    return d2i_X509_bio(bio, nullptr);
105ad9
 }
105ad9
 
105ad9
 /*
105ad9
@@ -1242,6 +1271,26 @@ extern "C" int32_t CryptoNative_LookupFriendlyNameByOid(const char* oidValue, co
105ad9
     return 0;
105ad9
 }
105ad9
 
105ad9
+#ifndef OPENSSL_VERSION
105ad9
+#define OPENSSL_VERSION 0
105ad9
+#endif
105ad9
+
105ad9
+/*
105ad9
+Function:
105ad9
+SSLEayVersion
105ad9
+
105ad9
+Gets the version of openssl library.
105ad9
+
105ad9
+Return values:
105ad9
+Textual description of the version on success.
105ad9
+"not available" string on failure.
105ad9
+*/
105ad9
+extern "C" char* CryptoNative_SSLEayVersion()
105ad9
+{
105ad9
+    return strdup(OpenSSL_version(OPENSSL_VERSION));
105ad9
+}
105ad9
+
105ad9
+#ifdef NEED_OPENSSL_1_0
105ad9
 // Lock used to make sure EnsureopenSslInitialized itself is thread safe
105ad9
 static pthread_mutex_t g_initLock = PTHREAD_MUTEX_INITIALIZER;
105ad9
 
105ad9
@@ -1262,6 +1311,10 @@ static void LockingCallback(int mode, int n, const char* file, int line)
105ad9
 #pragma clang diagnostic push
105ad9
 #pragma clang diagnostic ignored "-Wthread-safety-analysis"
105ad9
 
105ad9
+#ifndef CRYPTO_LOCK
105ad9
+#define CRYPTO_LOCK 1
105ad9
+#endif
105ad9
+
105ad9
     int result;
105ad9
     if (mode & CRYPTO_LOCK)
105ad9
     {
105ad9
@@ -1307,7 +1360,7 @@ Return values:
105ad9
 0 on success
105ad9
 non-zero on failure
105ad9
 */
105ad9
-extern "C" int32_t CryptoNative_EnsureOpenSslInitialized()
105ad9
+static int32_t EnsureOpenSsl10Initialized()
105ad9
 {
105ad9
     int ret = 0;
105ad9
     int numLocks = 0;
105ad9
@@ -1383,25 +1436,53 @@ done:
105ad9
                 pthread_mutex_destroy(&g_locks[i]); // ignore failures
105ad9
             }
105ad9
             delete[] g_locks;
105ad9
-            g_locks = NULL;
105ad9
+            g_locks = nullptr;
105ad9
         }
105ad9
     }
105ad9
 
105ad9
     pthread_mutex_unlock(&g_initLock);
105ad9
     return ret;
105ad9
 }
105ad9
+#endif // NEED_OPENSSL_1_0 */
105ad9
 
105ad9
-/*
105ad9
-Function:
105ad9
-SSLEayVersion
105ad9
+#ifdef NEED_OPENSSL_1_1
105ad9
 
105ad9
-Gets the version of openssl library.
105ad9
+static int32_t EnsureOpenSsl11Initialized()
105ad9
+{
105ad9
+    // In OpenSSL 1.0 we call OPENSSL_add_all_algorithms_conf() and ERR_load_crypto_strings(),
105ad9
+    // so do the same for 1.1
105ad9
+    OPENSSL_init_ssl(
105ad9
+        // OPENSSL_add_all_algorithms_conf
105ad9
+            OPENSSL_INIT_ADD_ALL_CIPHERS |
105ad9
+            OPENSSL_INIT_ADD_ALL_DIGESTS |
105ad9
+            OPENSSL_INIT_LOAD_CONFIG |
105ad9
+        // ERR_load_crypto_strings
105ad9
+            OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
105ad9
+            OPENSSL_INIT_LOAD_SSL_STRINGS,
105ad9
+        nullptr);
105ad9
 
105ad9
-Return values:
105ad9
-Textual description of the version on success.
105ad9
-"not available" string on failure.
105ad9
-*/
105ad9
-extern "C" char* CryptoNative_SSLEayVersion()
105ad9
+    return 0;
105ad9
+}
105ad9
+
105ad9
+#endif
105ad9
+
105ad9
+extern "C" int32_t CryptoNative_EnsureOpenSslInitialized()
105ad9
 {
105ad9
-    return strdup(SSLeay_version(SSLEAY_VERSION));
105ad9
+    // If portable then decide which OpenSSL we are, and call the right one.
105ad9
+    // If 1.0, call the 1.0 one.
105ad9
+    // Otherwise call the 1.1 one.
105ad9
+#ifdef FEATURE_DISTRO_AGNOSTIC_SSL
105ad9
+    if (API_EXISTS(SSL_state))
105ad9
+    {
105ad9
+        return EnsureOpenSsl10Initialized();
105ad9
+    }
105ad9
+    else
105ad9
+    {
105ad9
+        return EnsureOpenSsl11Initialized();
105ad9
+    }
105ad9
+#elif OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
105ad9
+    return EnsureOpenSsl10Initialized();
105ad9
+#else
105ad9
+    return EnsureOpenSsl11Initialized();
105ad9
+#endif
105ad9
 }
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/openssl.h b/src/Native/Unix/System.Security.Cryptography.Native/openssl.h
105ad9
new file mode 100644
105ad9
index 0000000000..372d6fd45a
105ad9
--- /dev/null
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/openssl.h
105ad9
@@ -0,0 +1,11 @@
105ad9
+// Licensed to the .NET Foundation under one or more agreements.
105ad9
+// The .NET Foundation licenses this file to you under the MIT license.
105ad9
+// See the LICENSE file in the project root for more information.
105ad9
+//
105ad9
+
105ad9
+#pragma once
105ad9
+
105ad9
+#include "pal_compiler.h"
105ad9
+#include "opensslshim.h"
105ad9
+
105ad9
+extern "C" char* CryptoNative_SSLEayVersion();
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/openssl_1_0_structs.h b/src/Native/Unix/System.Security.Cryptography.Native/openssl_1_0_structs.h
105ad9
new file mode 100644
105ad9
index 0000000000..8852c3c1b3
105ad9
--- /dev/null
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/openssl_1_0_structs.h
105ad9
@@ -0,0 +1,139 @@
105ad9
+// Licensed to the .NET Foundation under one or more agreements.
105ad9
+// The .NET Foundation licenses this file to you under the MIT license.
105ad9
+// See the LICENSE file in the project root for more information.
105ad9
+
105ad9
+// Definitions of structures from OpenSSL 1.0.2, modified as relevant to
105ad9
+// building .NET Core.
105ad9
+
105ad9
+// The CRYPTO_EX_DATA struct is smaller in 1.1, which changes the packing of
105ad9
+// dsa_st
105ad9
+struct crypto_ex_data_10_st
105ad9
+{
105ad9
+    STACK_OF(void) * sk;
105ad9
+    int dummy;
105ad9
+};
105ad9
+
105ad9
+struct dsa_st
105ad9
+{
105ad9
+    int _ignored0;
105ad9
+    long _ignored1;
105ad9
+    int _ignored2;
105ad9
+    BIGNUM* p;
105ad9
+    BIGNUM* q;
105ad9
+    BIGNUM* g;
105ad9
+    BIGNUM* pub_key;
105ad9
+    BIGNUM* priv_key;
105ad9
+    const void* _ignored3;
105ad9
+    const void* _ignored4;
105ad9
+    int _ignored5;
105ad9
+    const void* _ignored6;
105ad9
+    int _ignored7;
105ad9
+    struct crypto_ex_data_10_st ex_data;
105ad9
+    const DSA_METHOD* meth;
105ad9
+};
105ad9
+
105ad9
+struct evp_cipher_ctx_st
105ad9
+{
105ad9
+    // 0xA8 is the sizeof value when building against OpenSSL 1.0.2 on
105ad9
+    // Ubuntu 16.04
105ad9
+    unsigned char _ignored0[0xA8];
105ad9
+};
105ad9
+
105ad9
+struct evp_pkey_st
105ad9
+{
105ad9
+    int _ignored0;
105ad9
+    int _ignored1;
105ad9
+    int references;
105ad9
+};
105ad9
+
105ad9
+struct hmac_ctx_st
105ad9
+{
105ad9
+    // 0x120 is the sizeof value when building against OpenSSL 1.0.2 on
105ad9
+    // Ubuntu 16.04
105ad9
+    unsigned char _ignored0[0x120];
105ad9
+};
105ad9
+
105ad9
+struct rsa_meth_st
105ad9
+{
105ad9
+    const void* _ignored0;
105ad9
+    const void* _ignored1;
105ad9
+    const void* _ignored2;
105ad9
+    const void* _ignored3;
105ad9
+    const void* _ignored4;
105ad9
+    const void* _ignored5;
105ad9
+    const void* _ignored6;
105ad9
+    const void* _ignored7;
105ad9
+    const void* _ignored8;
105ad9
+    int flags;
105ad9
+};
105ad9
+
105ad9
+struct rsa_st
105ad9
+{
105ad9
+    int _ignored0;
105ad9
+    long _ignored1;
105ad9
+    const RSA_METHOD* meth;
105ad9
+    const void* _ignored2;
105ad9
+    BIGNUM* n;
105ad9
+    BIGNUM* e;
105ad9
+    BIGNUM* d;
105ad9
+    BIGNUM* p;
105ad9
+    BIGNUM* q;
105ad9
+    BIGNUM* dmp1;
105ad9
+    BIGNUM* dmq1;
105ad9
+    BIGNUM* iqmp;
105ad9
+};
105ad9
+
105ad9
+struct x509_cinf_st
105ad9
+{
105ad9
+    ASN1_INTEGER* version;
105ad9
+    ASN1_INTEGER* serialNumber;
105ad9
+    X509_ALGOR* signature;
105ad9
+    X509_NAME* issuer;
105ad9
+    X509_VAL* validity;
105ad9
+    X509_NAME* subject;
105ad9
+    X509_PUBKEY* key;
105ad9
+};
105ad9
+
105ad9
+struct X509_crl_info_st
105ad9
+{
105ad9
+    const void* _ignored0;
105ad9
+    const void* _ignored1;
105ad9
+    const void* _ignored2;
105ad9
+    const void* _ignored3;
105ad9
+    ASN1_TIME* nextUpdate;
105ad9
+};
105ad9
+
105ad9
+struct X509_crl_st
105ad9
+{
105ad9
+    X509_CRL_INFO* crl;
105ad9
+};
105ad9
+
105ad9
+struct X509_name_st
105ad9
+{
105ad9
+    STACK_OF(X509_NAME_ENTRY) * entries;
105ad9
+    int _ignored0;
105ad9
+    BUF_MEM* bytes;
105ad9
+};
105ad9
+
105ad9
+struct X509_pubkey_st
105ad9
+{
105ad9
+    X509_ALGOR* algor;
105ad9
+    ASN1_BIT_STRING* public_key;
105ad9
+};
105ad9
+
105ad9
+struct x509_st
105ad9
+{
105ad9
+    X509_CINF* cert_info;
105ad9
+    const void* _ignored0;
105ad9
+    const void* _ignored1;
105ad9
+    int _ignored2;
105ad9
+    int references;
105ad9
+};
105ad9
+
105ad9
+struct x509_store_ctx_st
105ad9
+{
105ad9
+    const void* _ignored0;
105ad9
+    int _ignored1;
105ad9
+    X509* cert;
105ad9
+    STACK_OF(X509*) untrusted;
105ad9
+};
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.cpp b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.cpp
105ad9
index f4e1cb71cb..585f7ac23f 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.cpp
105ad9
@@ -5,13 +5,25 @@
105ad9
 
105ad9
 #include <dlfcn.h>
105ad9
 #include <stdio.h>
105ad9
+#include <stdbool.h>
105ad9
+#include <string.h>
105ad9
 
105ad9
 #include "opensslshim.h"
105ad9
 
105ad9
-// Define pointers to all the used ICU functions
105ad9
-#define PER_FUNCTION_BLOCK(fn, isRequired) decltype(fn) fn##_ptr;
105ad9
+// Define pointers to all the used OpenSSL functions
105ad9
+#define REQUIRED_FUNCTION(fn) __typeof(fn) fn##_ptr;
105ad9
+#define NEW_REQUIRED_FUNCTION(fn) __typeof(fn) fn##_ptr;
105ad9
+#define LIGHTUP_FUNCTION(fn) __typeof(fn) fn##_ptr;
105ad9
+#define FALLBACK_FUNCTION(fn) __typeof(fn) fn##_ptr;
105ad9
+#define RENAMED_FUNCTION(fn,oldfn) __typeof(fn) fn##_ptr;
105ad9
+#define LEGACY_FUNCTION(fn) __typeof(fn) fn##_ptr;
105ad9
 FOR_ALL_OPENSSL_FUNCTIONS
105ad9
-#undef PER_FUNCTION_BLOCK
105ad9
+#undef LEGACY_FUNCTION
105ad9
+#undef RENAMED_FUNCTION
105ad9
+#undef FALLBACK_FUNCTION
105ad9
+#undef LIGHTUP_FUNCTION
105ad9
+#undef NEW_REQUIRED_FUNCTION
105ad9
+#undef REQUIRED_FUNCTION
105ad9
 
105ad9
 // x.x.x, considering the max number of decimal digits for each component
105ad9
 static const int MaxVersionStringLength = 32;
105ad9
@@ -35,6 +47,12 @@ bool OpenLibrary()
105ad9
         libssl = dlopen(soName, RTLD_LAZY);
105ad9
     }
105ad9
 
105ad9
+    if (libssl == nullptr)
105ad9
+    {
105ad9
+        // Prefer OpenSSL 1.1.x
105ad9
+        libssl = dlopen("libssl.so.1.1", RTLD_LAZY);
105ad9
+    }
105ad9
+
105ad9
     if (libssl == nullptr)
105ad9
     {
105ad9
         // Debian 9 has dropped support for SSLv3 and so they have bumped their soname. Let's try it
105ad9
@@ -63,17 +81,41 @@ void InitializeOpenSSLShim()
105ad9
 {
105ad9
     if (!OpenLibrary())
105ad9
     {
105ad9
-        fprintf(stderr, "No usable version of the libssl was found\n");
105ad9
+        fprintf(stderr, "No usable version of libssl was found\n");
105ad9
         abort();
105ad9
     }
105ad9
 
105ad9
-    // Get pointers to all the ICU functions that are needed
105ad9
-#define PER_FUNCTION_BLOCK(fn, isRequired) \
105ad9
-    fn##_ptr = reinterpret_cast<decltype(fn)>(dlsym(libssl, #fn)); \
105ad9
-    if ((fn##_ptr) == NULL && isRequired) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); }
105ad9
+    // A function defined in libcrypto.so.1.0.0/libssl.so.1.0.0 that is not defined in
105ad9
+    // libcrypto.so.1.1.0/libssl.so.1.1.0
105ad9
+    const void* v1_0_sentinel = dlsym(libssl, "SSL_state");
105ad9
+
105ad9
+    // Get pointers to all the functions that are needed
105ad9
+#define REQUIRED_FUNCTION(fn) \
105ad9
+    if (!(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); }
105ad9
+
105ad9
+#define NEW_REQUIRED_FUNCTION(fn) \
105ad9
+    if (!v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); }
105ad9
+
105ad9
+#define LIGHTUP_FUNCTION(fn) \
105ad9
+    fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn));
105ad9
+
105ad9
+#define FALLBACK_FUNCTION(fn) \
105ad9
+    if (!(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fn##_ptr = (__typeof(fn))local_##fn; }
105ad9
+
105ad9
+#define RENAMED_FUNCTION(fn,oldfn) \
105ad9
+    if (!v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); } \
105ad9
+    if (v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #oldfn)))) { fprintf(stderr, "Cannot get required symbol " #oldfn " from libssl\n"); abort(); }
105ad9
+
105ad9
+#define LEGACY_FUNCTION(fn) \
105ad9
+    if (v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); }
105ad9
 
105ad9
     FOR_ALL_OPENSSL_FUNCTIONS
105ad9
-#undef PER_FUNCTION_BLOCK    
105ad9
+#undef LEGACY_FUNCTION
105ad9
+#undef RENAMED_FUNCTION
105ad9
+#undef FALLBACK_FUNCTION
105ad9
+#undef LIGHTUP_FUNCTION
105ad9
+#undef NEW_REQUIRED_FUNCTION
105ad9
+#undef REQUIRED_FUNCTION
105ad9
 }
105ad9
 
105ad9
 __attribute__((destructor))
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
105ad9
index afb2559d12..c10cc1d534 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
105ad9
@@ -3,7 +3,7 @@
105ad9
 // See the LICENSE file in the project root for more information.
105ad9
 //
105ad9
 
105ad9
-// Enable calling OpenSSL functions through shims to enable support for 
105ad9
+// Enable calling OpenSSL functions through shims to enable support for
105ad9
 // different versioned so files naming and different configuration options
105ad9
 // on various Linux distributions.
105ad9
 
105ad9
@@ -16,8 +16,8 @@
105ad9
 #include <openssl/bn.h>
105ad9
 #include <openssl/crypto.h>
105ad9
 #include <openssl/dsa.h>
105ad9
-#include <openssl/ecdsa.h>
105ad9
 #include <openssl/ec.h>
105ad9
+#include <openssl/ecdsa.h>
105ad9
 #include <openssl/err.h>
105ad9
 #include <openssl/evp.h>
105ad9
 #include <openssl/hmac.h>
105ad9
@@ -35,34 +35,137 @@
105ad9
 #include <openssl/x509v3.h>
105ad9
 
105ad9
 #include "pal_crypto_config.h"
105ad9
+#define OPENSSL_VERSION_1_1_0_RTM 0x10100000L
105ad9
+#define OPENSSL_VERSION_1_0_2_RTM 0x10002000L
105ad9
+
105ad9
+#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
105ad9
+
105ad9
+// Remove problematic #defines
105ad9
+#undef SSL_get_state
105ad9
+#undef SSL_is_init_finished
105ad9
+#undef X509_get_X509_PUBKEY
105ad9
+#undef X509_get_version
105ad9
+
105ad9
+#endif
105ad9
+
105ad9
+#ifdef EVP_MD_CTX_create
105ad9
+#undef EVP_MD_CTX_create
105ad9
+#undef EVP_MD_CTX_init
105ad9
+#undef EVP_MD_CTX_destroy
105ad9
+#undef SSLv23_method
105ad9
+#endif
105ad9
+
105ad9
+#if defined FEATURE_DISTRO_AGNOSTIC_SSL || OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
105ad9
+#include "apibridge.h"
105ad9
+#endif
105ad9
 
105ad9
 #ifdef FEATURE_DISTRO_AGNOSTIC_SSL
105ad9
 
105ad9
+#define NEED_OPENSSL_1_0 true
105ad9
+#define NEED_OPENSSL_1_1 true
105ad9
+
105ad9
 #if !HAVE_OPENSSL_EC2M
105ad9
 // In portable build, we need to support the following functions even if they were not present
105ad9
 // on the build OS. The shim will detect their presence at runtime.
105ad9
 #undef HAVE_OPENSSL_EC2M
105ad9
 #define HAVE_OPENSSL_EC2M 1
105ad9
-const EC_METHOD *EC_GF2m_simple_method(void);
105ad9
-int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
105ad9
-int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
105ad9
-int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
105ad9
-        const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx);
105ad9
-int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
105ad9
-        const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx);
105ad9
+extern "C" const EC_METHOD* EC_GF2m_simple_method(void);
105ad9
+extern "C" int EC_GROUP_get_curve_GF2m(const EC_GROUP* group, BIGNUM* p, BIGNUM* a, BIGNUM* b, BN_CTX* ctx);
105ad9
+extern "C" int EC_GROUP_set_curve_GF2m(EC_GROUP* group, const BIGNUM* p, const BIGNUM* a, const BIGNUM* b, BN_CTX* ctx);
105ad9
+extern "C" int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP* group, const EC_POINT* p, BIGNUM* x, BIGNUM* y, BN_CTX* ctx);
105ad9
+extern "C" int EC_POINT_set_affine_coordinates_GF2m(
105ad9
+    const EC_GROUP* group, EC_POINT* p, const BIGNUM* x, const BIGNUM* y, BN_CTX* ctx);
105ad9
+#endif
105ad9
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM
105ad9
+typedef struct stack_st _STACK;
105ad9
+extern "C" ASN1_STRING* d2i_ASN1_type_bytes(ASN1_STRING** a, const unsigned char** pp, long length, int type);
105ad9
+extern "C" int CRYPTO_add_lock(int* pointer, int amount, int type, const char* file, int line);
105ad9
+extern "C" int CRYPTO_num_locks(void);
105ad9
+extern "C" void CRYPTO_set_locking_callback(void (*func)(int mode, int type, const char* file, int line));
105ad9
+extern "C" void ERR_load_crypto_strings(void);
105ad9
+extern "C" int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX* a);
105ad9
+extern "C" int EVP_CIPHER_CTX_init(EVP_CIPHER_CTX* a);
105ad9
+extern "C" void HMAC_CTX_cleanup(HMAC_CTX* ctx);
105ad9
+extern "C" void HMAC_CTX_init(HMAC_CTX* ctx);
105ad9
+extern "C" void OPENSSL_add_all_algorithms_conf(void);
105ad9
+extern "C" int SSL_library_init(void);
105ad9
+extern "C" void SSL_load_error_strings(void);
105ad9
+extern "C" int SSL_state(const SSL* ssl);
105ad9
+extern "C" const char* SSLeay_version(int t);
105ad9
+#else
105ad9
+typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS;
105ad9
+typedef struct stack_st OPENSSL_STACK;
105ad9
+
105ad9
+#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L
105ad9
+#define OPENSSL_INIT_ADD_ALL_CIPHERS 0x00000004L
105ad9
+#define OPENSSL_INIT_ADD_ALL_DIGESTS 0x00000008L
105ad9
+#define OPENSSL_INIT_LOAD_CONFIG 0x00000040L
105ad9
+#define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L
105ad9
+
105ad9
+extern "C" const BIGNUM* DSA_get0_key(const DSA* dsa, const BIGNUM** pubKey, const BIGNUM** privKey);
105ad9
+extern "C" void DSA_get0_pqg(const DSA* dsa, const BIGNUM** p, const BIGNUM** q, const BIGNUM** g);
105ad9
+extern "C" const DSA_METHOD* DSA_get_method(const DSA* dsa);
105ad9
+extern "C" int32_t DSA_set0_key(DSA* dsa, BIGNUM* bnY, BIGNUM* bnX);
105ad9
+extern "C" int32_t DSA_set0_pqg(DSA* dsa, BIGNUM* bnP, BIGNUM* bnQ, BIGNUM* bnG);
105ad9
+extern "C" void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX* ctx);
105ad9
+extern "C" EVP_CIPHER_CTX* EVP_CIPHER_CTX_new(void);
105ad9
+extern "C" int32_t EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX* ctx);
105ad9
+extern "C" void EVP_MD_CTX_free(EVP_MD_CTX* ctx);
105ad9
+extern "C" EVP_MD_CTX* EVP_MD_CTX_new(void);
105ad9
+extern "C" int32_t EVP_PKEY_up_ref(EVP_PKEY* pkey);
105ad9
+extern "C" void HMAC_CTX_free(HMAC_CTX* ctx);
105ad9
+extern "C" HMAC_CTX* HMAC_CTX_new(void);
105ad9
+extern "C" int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS* settings);
105ad9
+extern "C" void OPENSSL_sk_free(OPENSSL_STACK*);
105ad9
+extern "C" OPENSSL_STACK* OPENSSL_sk_new_null(void);
105ad9
+extern "C" int OPENSSL_sk_num(const OPENSSL_STACK*);
105ad9
+extern "C" void OPENSSL_sk_pop_free(OPENSSL_STACK* st, void (*func)(void*));
105ad9
+extern "C" int OPENSSL_sk_push(OPENSSL_STACK* st, const void* data);
105ad9
+extern "C" void* OPENSSL_sk_value(const OPENSSL_STACK*, int);
105ad9
+extern "C" const char* OpenSSL_version(int type);
105ad9
+extern "C" unsigned long OpenSSL_version_num();
105ad9
+extern "C" void RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp);
105ad9
+extern "C" void RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q);
105ad9
+extern "C" void RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d);
105ad9
+extern "C" int32_t RSA_meth_get_flags(const RSA_METHOD* meth);
105ad9
+extern "C" int32_t RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);
105ad9
+extern "C" int32_t RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q);
105ad9
+extern "C" int32_t RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d);
105ad9
+extern "C" int32_t SSL_is_init_finished(SSL* ssl);
105ad9
+#undef SSL_CTX_set_options
105ad9
+extern "C" unsigned long SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options);
105ad9
+extern "C" void SSL_CTX_set_security_level(SSL_CTX* ctx, int32_t level);
105ad9
+#undef SSL_session_reused
105ad9
+extern "C" int SSL_session_reused(SSL* ssl);
105ad9
+extern "C" const SSL_METHOD* TLS_method(void);
105ad9
+extern "C" const ASN1_TIME* X509_CRL_get0_nextUpdate(const X509_CRL* crl);
105ad9
+extern "C" int32_t X509_NAME_get0_der(X509_NAME* x509Name, const uint8_t** pder, size_t* pderlen);
105ad9
+extern "C" int32_t X509_PUBKEY_get0_param(
105ad9
+    ASN1_OBJECT** palgOid, const uint8_t** pkeyBytes, int* pkeyBytesLen, X509_ALGOR** palg, X509_PUBKEY* pubkey);
105ad9
+extern "C" X509* X509_STORE_CTX_get0_cert(X509_STORE_CTX* ctx);
105ad9
+extern "C" STACK_OF(X509) * X509_STORE_CTX_get0_untrusted(X509_STORE_CTX* ctx);
105ad9
+extern "C" const ASN1_TIME* X509_get0_notAfter(const X509* x509);
105ad9
+extern "C" const ASN1_TIME* X509_get0_notBefore(const X509* x509);
105ad9
+extern "C" ASN1_BIT_STRING* X509_get0_pubkey_bitstr(const X509* x509);
105ad9
+extern "C" const X509_ALGOR* X509_get0_tbs_sigalg(const X509* x509);
105ad9
+extern "C" X509_PUBKEY* X509_get_X509_PUBKEY(const X509* x509);
105ad9
+extern "C" int32_t X509_get_version(const X509* x509);
105ad9
+extern "C" int32_t X509_up_ref(X509* x509);
105ad9
 #endif
105ad9
 
105ad9
 #if !HAVE_OPENSSL_ALPN
105ad9
 #undef HAVE_OPENSSL_ALPN
105ad9
 #define HAVE_OPENSSL_ALPN 1
105ad9
-int SSL_CTX_set_alpn_protos(SSL_CTX* ctx, const unsigned char* protos, unsigned int protos_len);
105ad9
-void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx, int (*cb) (SSL *ssl,
105ad9
-                                            const unsigned char **out,
105ad9
-                                            unsigned char *outlen,
105ad9
-                                            const unsigned char *in,
105ad9
-                                            unsigned int inlen,
105ad9
-                                            void *arg), void *arg);
105ad9
-void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsigned int* len);
105ad9
+extern "C" int SSL_CTX_set_alpn_protos(SSL_CTX* ctx, const unsigned char* protos, unsigned int protos_len);
105ad9
+extern "C" void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
105ad9
+                                int (*cb)(SSL* ssl,
105ad9
+                                          const unsigned char** out,
105ad9
+                                          unsigned char* outlen,
105ad9
+                                          const unsigned char* in,
105ad9
+                                          unsigned int inlen,
105ad9
+                                          void* arg),
105ad9
+                                void* arg);
105ad9
+extern "C" void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsigned int* len);
105ad9
 #endif
105ad9
 
105ad9
 #define API_EXISTS(fn) (fn != nullptr)
105ad9
@@ -70,304 +173,350 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
105ad9
 // List of all functions from the libssl that are used in the System.Security.Cryptography.Native.
105ad9
 // Forgetting to add a function here results in build failure with message reporting the function
105ad9
 // that needs to be added.
105ad9
+
105ad9
 #define FOR_ALL_OPENSSL_FUNCTIONS \
105ad9
-    PER_FUNCTION_BLOCK(ASN1_BIT_STRING_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(ASN1_INTEGER_get, true) \
105ad9
-    PER_FUNCTION_BLOCK(ASN1_OBJECT_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(ASN1_OCTET_STRING_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(ASN1_OCTET_STRING_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(ASN1_OCTET_STRING_set, true) \
105ad9
-    PER_FUNCTION_BLOCK(ASN1_STRING_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(ASN1_STRING_print_ex, true) \
105ad9
-    PER_FUNCTION_BLOCK(BASIC_CONSTRAINTS_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(BIO_ctrl, true) \
105ad9
-    PER_FUNCTION_BLOCK(BIO_ctrl_pending, true) \
105ad9
-    PER_FUNCTION_BLOCK(BIO_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(BIO_gets, true) \
105ad9
-    PER_FUNCTION_BLOCK(BIO_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(BIO_new_file, true) \
105ad9
-    PER_FUNCTION_BLOCK(BIO_read, true) \
105ad9
-    PER_FUNCTION_BLOCK(BIO_s_mem, true) \
105ad9
-    PER_FUNCTION_BLOCK(BIO_write, true) \
105ad9
-    PER_FUNCTION_BLOCK(BN_bin2bn, true) \
105ad9
-    PER_FUNCTION_BLOCK(BN_bn2bin, true) \
105ad9
-    PER_FUNCTION_BLOCK(BN_clear_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(BN_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(BN_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(BN_num_bits, true) \
105ad9
-    PER_FUNCTION_BLOCK(CRYPTO_add_lock, true) \
105ad9
-    PER_FUNCTION_BLOCK(CRYPTO_num_locks, true) \
105ad9
-    PER_FUNCTION_BLOCK(CRYPTO_set_locking_callback, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_ASN1_BIT_STRING, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_ASN1_OCTET_STRING, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_ASN1_type_bytes, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_BASIC_CONSTRAINTS, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_EXTENDED_KEY_USAGE, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_PKCS12, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_PKCS12_bio, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_PKCS7, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_PKCS7_bio, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_RSAPublicKey, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_X509, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_X509_bio, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_X509_CRL, true) \
105ad9
-    PER_FUNCTION_BLOCK(d2i_X509_NAME, true) \
105ad9
-    PER_FUNCTION_BLOCK(DSA_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(DSA_generate_key, true) \
105ad9
-    PER_FUNCTION_BLOCK(DSA_generate_parameters_ex, true) \
105ad9
-    PER_FUNCTION_BLOCK(DSA_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(DSA_OpenSSL, true) \
105ad9
-    PER_FUNCTION_BLOCK(DSA_sign, true) \
105ad9
-    PER_FUNCTION_BLOCK(DSA_size, true) \
105ad9
-    PER_FUNCTION_BLOCK(DSA_up_ref, true) \
105ad9
-    PER_FUNCTION_BLOCK(DSA_verify, true) \
105ad9
-    PER_FUNCTION_BLOCK(ECDSA_sign, true) \
105ad9
-    PER_FUNCTION_BLOCK(ECDSA_size, true) \
105ad9
-    PER_FUNCTION_BLOCK(ECDSA_verify, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GFp_mont_method, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GFp_simple_method, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_check, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_get0_generator, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_get0_seed, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_get_cofactor, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_get_curve_GFp, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_get_curve_name, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_get_degree, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_get_order, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_get_seed_len, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_method_of, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_set_curve_GFp, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_set_generator, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_set_seed, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_check_key, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_generate_key, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_get0_group, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_get0_private_key, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_get0_public_key, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_new_by_curve_name, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_set_group, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_set_private_key, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_set_public_key_affine_coordinates, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_KEY_up_ref, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_METHOD_get_field_type, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_POINT_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_POINT_get_affine_coordinates_GFp, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_POINT_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_POINT_set_affine_coordinates_GFp, true) \
105ad9
-    PER_FUNCTION_BLOCK(ERR_clear_error, true) \
105ad9
-    PER_FUNCTION_BLOCK(ERR_error_string_n, true) \
105ad9
-    PER_FUNCTION_BLOCK(ERR_get_error, true) \
105ad9
-    PER_FUNCTION_BLOCK(ERR_load_crypto_strings, true) \
105ad9
-    PER_FUNCTION_BLOCK(ERR_put_error, true) \
105ad9
-    PER_FUNCTION_BLOCK(ERR_peek_error, true) \
105ad9
-    PER_FUNCTION_BLOCK(ERR_peek_last_error, true) \
105ad9
-    PER_FUNCTION_BLOCK(ERR_reason_error_string, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_aes_128_cbc, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_aes_128_ecb, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_aes_192_cbc, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_aes_192_ecb, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_aes_256_cbc, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_aes_256_ecb, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_CIPHER_CTX_cleanup, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_CIPHER_CTX_ctrl, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_CIPHER_CTX_init, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_CIPHER_CTX_set_key_length, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_CIPHER_CTX_set_padding, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_CipherFinal_ex, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_CipherInit_ex, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_CipherUpdate, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_des_cbc, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_des_ecb, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_des_ede3, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_des_ede3_cbc, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_DigestFinal_ex, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_DigestInit_ex, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_DigestUpdate, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_get_digestbyname, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_md5, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_MD_CTX_create, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_MD_CTX_destroy, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_MD_size, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_CTX_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_CTX_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_derive_set_peer, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_derive_init, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_derive, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_get1_DSA, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_get1_EC_KEY, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_get1_RSA, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_set1_DSA, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_set1_EC_KEY, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_PKEY_set1_RSA, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_rc2_cbc, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_rc2_ecb, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_sha1, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_sha256, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_sha384, true) \
105ad9
-    PER_FUNCTION_BLOCK(EVP_sha512, true) \
105ad9
-    PER_FUNCTION_BLOCK(EXTENDED_KEY_USAGE_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(GENERAL_NAMES_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(HMAC_CTX_cleanup, true) \
105ad9
-    PER_FUNCTION_BLOCK(HMAC_CTX_init, true) \
105ad9
-    PER_FUNCTION_BLOCK(HMAC_Final, true) \
105ad9
-    PER_FUNCTION_BLOCK(HMAC_Init_ex, true) \
105ad9
-    PER_FUNCTION_BLOCK(HMAC_Update, true) \
105ad9
-    PER_FUNCTION_BLOCK(i2d_ASN1_INTEGER, true) \
105ad9
-    PER_FUNCTION_BLOCK(i2d_ASN1_TYPE, true) \
105ad9
-    PER_FUNCTION_BLOCK(i2d_PKCS12, true) \
105ad9
-    PER_FUNCTION_BLOCK(i2d_PKCS7, true) \
105ad9
-    PER_FUNCTION_BLOCK(i2d_X509, true) \
105ad9
-    PER_FUNCTION_BLOCK(i2d_X509_PUBKEY, true) \
105ad9
-    PER_FUNCTION_BLOCK(OBJ_ln2nid, true) \
105ad9
-    PER_FUNCTION_BLOCK(OBJ_nid2ln, true) \
105ad9
-    PER_FUNCTION_BLOCK(OBJ_nid2sn, true) \
105ad9
-    PER_FUNCTION_BLOCK(OBJ_nid2obj, true) \
105ad9
-    PER_FUNCTION_BLOCK(OBJ_obj2nid, true) \
105ad9
-    PER_FUNCTION_BLOCK(OBJ_obj2txt, true) \
105ad9
-    PER_FUNCTION_BLOCK(OBJ_sn2nid, true) \
105ad9
-    PER_FUNCTION_BLOCK(OBJ_txt2nid, true) \
105ad9
-    PER_FUNCTION_BLOCK(OBJ_txt2obj, true) \
105ad9
-    PER_FUNCTION_BLOCK(OPENSSL_add_all_algorithms_conf, true) \
105ad9
-    PER_FUNCTION_BLOCK(OPENSSL_cleanse, true) \
105ad9
-    PER_FUNCTION_BLOCK(PEM_read_bio_PKCS7, true) \
105ad9
-    PER_FUNCTION_BLOCK(PEM_read_bio_X509_AUX, true) \
105ad9
-    PER_FUNCTION_BLOCK(PEM_read_bio_X509_CRL, true) \
105ad9
-    PER_FUNCTION_BLOCK(PEM_write_bio_X509_CRL, true) \
105ad9
-    PER_FUNCTION_BLOCK(PKCS12_create, true) \
105ad9
-    PER_FUNCTION_BLOCK(PKCS12_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(PKCS12_parse, true) \
105ad9
-    PER_FUNCTION_BLOCK(PKCS7_add_certificate, true) \
105ad9
-    PER_FUNCTION_BLOCK(PKCS7_content_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(PKCS7_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(PKCS7_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(PKCS7_set_type, true) \
105ad9
-    PER_FUNCTION_BLOCK(RAND_bytes, true) \
105ad9
-    PER_FUNCTION_BLOCK(RAND_poll, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_generate_key_ex, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_get_method, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_private_decrypt, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_private_encrypt, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_public_decrypt, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_public_encrypt, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_sign, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_size, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_up_ref, true) \
105ad9
-    PER_FUNCTION_BLOCK(RSA_verify, true) \
105ad9
-    PER_FUNCTION_BLOCK(sk_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(sk_new_null, true) \
105ad9
-    PER_FUNCTION_BLOCK(sk_num, true) \
105ad9
-    PER_FUNCTION_BLOCK(sk_pop_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(sk_push, true) \
105ad9
-    PER_FUNCTION_BLOCK(sk_value, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CIPHER_description, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_ctrl, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_set_quiet_shutdown, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_check_private_key, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_ctrl, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_set_alpn_protos, false) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_set_alpn_select_cb, false) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_set_cert_verify_callback, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_set_cipher_list, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_set_client_cert_cb, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_set_quiet_shutdown, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_set_verify, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_use_certificate, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_CTX_use_PrivateKey, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_do_handshake, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_get_client_CA_list, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_get_current_cipher, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_get_error, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_get_finished, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_get_peer_cert_chain, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_get_peer_certificate, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_get_peer_finished, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_get_SSL_CTX, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_get_version, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_get0_alpn_selected, false) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_library_init, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_load_error_strings, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_read, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_renegotiate_pending, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_set_accept_state, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_set_bio, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_set_connect_state, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_shutdown, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_state, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSLeay_version, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSLv23_method, true) \
105ad9
-    PER_FUNCTION_BLOCK(SSL_write, true) \
105ad9
-    PER_FUNCTION_BLOCK(TLSv1_1_method, true) \
105ad9
-    PER_FUNCTION_BLOCK(TLSv1_2_method, true) \
105ad9
-    PER_FUNCTION_BLOCK(TLSv1_method, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_check_issued, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_check_purpose, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_CRL_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_digest, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_dup, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_EXTENSION_create_by_OBJ, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_EXTENSION_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_EXTENSION_get_critical, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_EXTENSION_get_data, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_EXTENSION_get_object, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_get_default_cert_dir, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_get_default_cert_dir_env, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_get_default_cert_file, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_get_default_cert_file_env, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_get_ext, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_get_ext_count, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_get_ext_d2i, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_get_issuer_name, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_get_serialNumber, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_get_subject_name, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_issuer_name_hash, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_NAME_entry_count, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_NAME_ENTRY_get_data, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_NAME_ENTRY_get_object, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_NAME_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_NAME_get_entry, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_NAME_get_index_by_NID, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_PUBKEY_get, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_add_cert, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_add_crl, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_CTX_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_CTX_get0_param, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_CTX_get1_chain, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_CTX_get_error, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_CTX_get_error_depth, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_CTX_init, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_CTX_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_CTX_set_flags, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_CTX_set_verify_cb, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_free, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_new, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_STORE_set_flags, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509V3_EXT_print, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_verify_cert, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_verify_cert_error_string, true) \
105ad9
-    PER_FUNCTION_BLOCK(X509_VERIFY_PARAM_set_time, true) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GF2m_simple_method, false) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_get_curve_GF2m, false) \
105ad9
-    PER_FUNCTION_BLOCK(EC_GROUP_set_curve_GF2m, false) \
105ad9
-    PER_FUNCTION_BLOCK(EC_POINT_get_affine_coordinates_GF2m, false) \
105ad9
-    PER_FUNCTION_BLOCK(EC_POINT_set_affine_coordinates_GF2m, false) \
105ad9
+    REQUIRED_FUNCTION(ASN1_BIT_STRING_free) \
105ad9
+    REQUIRED_FUNCTION(ASN1_INTEGER_get) \
105ad9
+    REQUIRED_FUNCTION(ASN1_OBJECT_free) \
105ad9
+    REQUIRED_FUNCTION(ASN1_OCTET_STRING_free) \
105ad9
+    REQUIRED_FUNCTION(ASN1_OCTET_STRING_new) \
105ad9
+    REQUIRED_FUNCTION(ASN1_OCTET_STRING_set) \
105ad9
+    REQUIRED_FUNCTION(ASN1_STRING_free) \
105ad9
+    REQUIRED_FUNCTION(ASN1_STRING_print_ex) \
105ad9
+    REQUIRED_FUNCTION(BASIC_CONSTRAINTS_free) \
105ad9
+    REQUIRED_FUNCTION(BIO_ctrl) \
105ad9
+    REQUIRED_FUNCTION(BIO_ctrl_pending) \
105ad9
+    REQUIRED_FUNCTION(BIO_free) \
105ad9
+    REQUIRED_FUNCTION(BIO_gets) \
105ad9
+    REQUIRED_FUNCTION(BIO_new) \
105ad9
+    REQUIRED_FUNCTION(BIO_new_file) \
105ad9
+    REQUIRED_FUNCTION(BIO_read) \
105ad9
+    REQUIRED_FUNCTION(BIO_s_mem) \
105ad9
+    REQUIRED_FUNCTION(BIO_write) \
105ad9
+    REQUIRED_FUNCTION(BN_bin2bn) \
105ad9
+    REQUIRED_FUNCTION(BN_bn2bin) \
105ad9
+    REQUIRED_FUNCTION(BN_clear_free) \
105ad9
+    REQUIRED_FUNCTION(BN_free) \
105ad9
+    REQUIRED_FUNCTION(BN_new) \
105ad9
+    REQUIRED_FUNCTION(BN_num_bits) \
105ad9
+    LEGACY_FUNCTION(CRYPTO_add_lock) \
105ad9
+    LEGACY_FUNCTION(CRYPTO_num_locks) \
105ad9
+    LEGACY_FUNCTION(CRYPTO_set_locking_callback) \
105ad9
+    REQUIRED_FUNCTION(d2i_ASN1_BIT_STRING) \
105ad9
+    REQUIRED_FUNCTION(d2i_ASN1_OCTET_STRING) \
105ad9
+    LEGACY_FUNCTION(d2i_ASN1_type_bytes) \
105ad9
+    REQUIRED_FUNCTION(d2i_BASIC_CONSTRAINTS) \
105ad9
+    REQUIRED_FUNCTION(d2i_EXTENDED_KEY_USAGE) \
105ad9
+    REQUIRED_FUNCTION(d2i_PKCS12) \
105ad9
+    REQUIRED_FUNCTION(d2i_PKCS12_bio) \
105ad9
+    REQUIRED_FUNCTION(d2i_PKCS7) \
105ad9
+    REQUIRED_FUNCTION(d2i_PKCS7_bio) \
105ad9
+    REQUIRED_FUNCTION(d2i_RSAPublicKey) \
105ad9
+    REQUIRED_FUNCTION(d2i_X509) \
105ad9
+    REQUIRED_FUNCTION(d2i_X509_bio) \
105ad9
+    REQUIRED_FUNCTION(d2i_X509_CRL) \
105ad9
+    REQUIRED_FUNCTION(d2i_X509_NAME) \
105ad9
+    REQUIRED_FUNCTION(DSA_free) \
105ad9
+    REQUIRED_FUNCTION(DSA_generate_key) \
105ad9
+    REQUIRED_FUNCTION(DSA_generate_parameters_ex) \
105ad9
+    FALLBACK_FUNCTION(DSA_get0_key) \
105ad9
+    FALLBACK_FUNCTION(DSA_get0_pqg) \
105ad9
+    FALLBACK_FUNCTION(DSA_get_method) \
105ad9
+    REQUIRED_FUNCTION(DSA_new) \
105ad9
+    REQUIRED_FUNCTION(DSA_OpenSSL) \
105ad9
+    FALLBACK_FUNCTION(DSA_set0_key) \
105ad9
+    FALLBACK_FUNCTION(DSA_set0_pqg) \
105ad9
+    REQUIRED_FUNCTION(DSA_sign) \
105ad9
+    REQUIRED_FUNCTION(DSA_size) \
105ad9
+    REQUIRED_FUNCTION(DSA_up_ref) \
105ad9
+    REQUIRED_FUNCTION(DSA_verify) \
105ad9
+    REQUIRED_FUNCTION(ECDSA_sign) \
105ad9
+    REQUIRED_FUNCTION(ECDSA_size) \
105ad9
+    REQUIRED_FUNCTION(ECDSA_verify) \
105ad9
+    REQUIRED_FUNCTION(EC_GFp_mont_method) \
105ad9
+    REQUIRED_FUNCTION(EC_GFp_simple_method) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_check) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_free) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_get0_generator) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_get0_seed) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_get_cofactor) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_get_curve_GFp) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_get_curve_name) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_get_degree) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_get_order) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_get_seed_len) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_method_of) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_new) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_set_curve_GFp) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_set_generator) \
105ad9
+    REQUIRED_FUNCTION(EC_GROUP_set_seed) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_check_key) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_free) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_generate_key) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_get0_group) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_get0_private_key) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_get0_public_key) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_new) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_new_by_curve_name) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_set_group) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_set_private_key) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_set_public_key_affine_coordinates) \
105ad9
+    REQUIRED_FUNCTION(EC_KEY_up_ref) \
105ad9
+    REQUIRED_FUNCTION(EC_METHOD_get_field_type) \
105ad9
+    REQUIRED_FUNCTION(EC_POINT_free) \
105ad9
+    REQUIRED_FUNCTION(EC_POINT_get_affine_coordinates_GFp) \
105ad9
+    REQUIRED_FUNCTION(EC_POINT_new) \
105ad9
+    REQUIRED_FUNCTION(EC_POINT_set_affine_coordinates_GFp) \
105ad9
+    REQUIRED_FUNCTION(ERR_clear_error) \
105ad9
+    REQUIRED_FUNCTION(ERR_error_string_n) \
105ad9
+    REQUIRED_FUNCTION(ERR_get_error) \
105ad9
+    LEGACY_FUNCTION(ERR_load_crypto_strings) \
105ad9
+    REQUIRED_FUNCTION(ERR_put_error) \
105ad9
+    REQUIRED_FUNCTION(ERR_peek_error) \
105ad9
+    REQUIRED_FUNCTION(ERR_peek_last_error) \
105ad9
+    REQUIRED_FUNCTION(ERR_reason_error_string) \
105ad9
+    REQUIRED_FUNCTION(EVP_aes_128_cbc) \
105ad9
+    REQUIRED_FUNCTION(EVP_aes_128_ecb) \
105ad9
+    REQUIRED_FUNCTION(EVP_aes_192_cbc) \
105ad9
+    REQUIRED_FUNCTION(EVP_aes_192_ecb) \
105ad9
+    REQUIRED_FUNCTION(EVP_aes_256_cbc) \
105ad9
+    REQUIRED_FUNCTION(EVP_aes_256_ecb) \
105ad9
+    LEGACY_FUNCTION(EVP_CIPHER_CTX_cleanup) \
105ad9
+    REQUIRED_FUNCTION(EVP_CIPHER_CTX_ctrl) \
105ad9
+    FALLBACK_FUNCTION(EVP_CIPHER_CTX_free) \
105ad9
+    LEGACY_FUNCTION(EVP_CIPHER_CTX_init) \
105ad9
+    FALLBACK_FUNCTION(EVP_CIPHER_CTX_new) \
105ad9
+    FALLBACK_FUNCTION(EVP_CIPHER_CTX_reset) \
105ad9
+    REQUIRED_FUNCTION(EVP_CIPHER_CTX_set_key_length) \
105ad9
+    REQUIRED_FUNCTION(EVP_CIPHER_CTX_set_padding) \
105ad9
+    REQUIRED_FUNCTION(EVP_CipherFinal_ex) \
105ad9
+    REQUIRED_FUNCTION(EVP_CipherInit_ex) \
105ad9
+    REQUIRED_FUNCTION(EVP_CipherUpdate) \
105ad9
+    REQUIRED_FUNCTION(EVP_des_cbc) \
105ad9
+    REQUIRED_FUNCTION(EVP_des_ecb) \
105ad9
+    REQUIRED_FUNCTION(EVP_des_ede3) \
105ad9
+    REQUIRED_FUNCTION(EVP_des_ede3_cbc) \
105ad9
+    REQUIRED_FUNCTION(EVP_DigestFinal_ex) \
105ad9
+    REQUIRED_FUNCTION(EVP_DigestInit_ex) \
105ad9
+    REQUIRED_FUNCTION(EVP_DigestUpdate) \
105ad9
+    REQUIRED_FUNCTION(EVP_get_digestbyname) \
105ad9
+    REQUIRED_FUNCTION(EVP_md5) \
105ad9
+    RENAMED_FUNCTION(EVP_MD_CTX_free, EVP_MD_CTX_destroy) \
105ad9
+    RENAMED_FUNCTION(EVP_MD_CTX_new, EVP_MD_CTX_create) \
105ad9
+    REQUIRED_FUNCTION(EVP_MD_size) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_CTX_free) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_CTX_new) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_derive_set_peer) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_derive_init) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_derive) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_free) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_get1_DSA) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_get1_EC_KEY) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_get1_RSA) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_new) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_set1_DSA) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_set1_EC_KEY) \
105ad9
+    REQUIRED_FUNCTION(EVP_PKEY_set1_RSA) \
105ad9
+    FALLBACK_FUNCTION(EVP_PKEY_up_ref) \
105ad9
+    REQUIRED_FUNCTION(EVP_rc2_cbc) \
105ad9
+    REQUIRED_FUNCTION(EVP_rc2_ecb) \
105ad9
+    REQUIRED_FUNCTION(EVP_sha1) \
105ad9
+    REQUIRED_FUNCTION(EVP_sha256) \
105ad9
+    REQUIRED_FUNCTION(EVP_sha384) \
105ad9
+    REQUIRED_FUNCTION(EVP_sha512) \
105ad9
+    REQUIRED_FUNCTION(EXTENDED_KEY_USAGE_free) \
105ad9
+    REQUIRED_FUNCTION(GENERAL_NAMES_free) \
105ad9
+    LEGACY_FUNCTION(HMAC_CTX_cleanup) \
105ad9
+    FALLBACK_FUNCTION(HMAC_CTX_free) \
105ad9
+    LEGACY_FUNCTION(HMAC_CTX_init) \
105ad9
+    FALLBACK_FUNCTION(HMAC_CTX_new) \
105ad9
+    REQUIRED_FUNCTION(HMAC_Final) \
105ad9
+    REQUIRED_FUNCTION(HMAC_Init_ex) \
105ad9
+    REQUIRED_FUNCTION(HMAC_Update) \
105ad9
+    REQUIRED_FUNCTION(i2d_ASN1_INTEGER) \
105ad9
+    REQUIRED_FUNCTION(i2d_ASN1_TYPE) \
105ad9
+    REQUIRED_FUNCTION(i2d_PKCS12) \
105ad9
+    REQUIRED_FUNCTION(i2d_PKCS7) \
105ad9
+    REQUIRED_FUNCTION(i2d_X509) \
105ad9
+    REQUIRED_FUNCTION(i2d_X509_PUBKEY) \
105ad9
+    REQUIRED_FUNCTION(OBJ_ln2nid) \
105ad9
+    REQUIRED_FUNCTION(OBJ_nid2ln) \
105ad9
+    REQUIRED_FUNCTION(OBJ_nid2sn) \
105ad9
+    REQUIRED_FUNCTION(OBJ_nid2obj) \
105ad9
+    REQUIRED_FUNCTION(OBJ_obj2nid) \
105ad9
+    REQUIRED_FUNCTION(OBJ_obj2txt) \
105ad9
+    REQUIRED_FUNCTION(OBJ_sn2nid) \
105ad9
+    REQUIRED_FUNCTION(OBJ_txt2nid) \
105ad9
+    REQUIRED_FUNCTION(OBJ_txt2obj) \
105ad9
+    LEGACY_FUNCTION(OPENSSL_add_all_algorithms_conf) \
105ad9
+    REQUIRED_FUNCTION(OPENSSL_cleanse) \
105ad9
+    NEW_REQUIRED_FUNCTION(OPENSSL_init_ssl) \
105ad9
+    RENAMED_FUNCTION(OPENSSL_sk_free, sk_free) \
105ad9
+    RENAMED_FUNCTION(OPENSSL_sk_new_null, sk_new_null) \
105ad9
+    RENAMED_FUNCTION(OPENSSL_sk_num, sk_num) \
105ad9
+    RENAMED_FUNCTION(OPENSSL_sk_pop_free, sk_pop_free) \
105ad9
+    RENAMED_FUNCTION(OPENSSL_sk_push, sk_push) \
105ad9
+    RENAMED_FUNCTION(OPENSSL_sk_value, sk_value) \
105ad9
+    FALLBACK_FUNCTION(OpenSSL_version) \
105ad9
+    RENAMED_FUNCTION(OpenSSL_version_num, SSLeay) \
105ad9
+    REQUIRED_FUNCTION(PEM_read_bio_PKCS7) \
105ad9
+    REQUIRED_FUNCTION(PEM_read_bio_X509_AUX) \
105ad9
+    REQUIRED_FUNCTION(PEM_read_bio_X509_CRL) \
105ad9
+    REQUIRED_FUNCTION(PEM_write_bio_X509_CRL) \
105ad9
+    REQUIRED_FUNCTION(PKCS12_create) \
105ad9
+    REQUIRED_FUNCTION(PKCS12_free) \
105ad9
+    REQUIRED_FUNCTION(PKCS12_parse) \
105ad9
+    REQUIRED_FUNCTION(PKCS7_add_certificate) \
105ad9
+    REQUIRED_FUNCTION(PKCS7_free) \
105ad9
+    REQUIRED_FUNCTION(PKCS7_new) \
105ad9
+    REQUIRED_FUNCTION(PKCS7_set_type) \
105ad9
+    REQUIRED_FUNCTION(PKCS7_content_new) \
105ad9
+    REQUIRED_FUNCTION(RAND_bytes) \
105ad9
+    REQUIRED_FUNCTION(RAND_poll) \
105ad9
+    REQUIRED_FUNCTION(RSA_free) \
105ad9
+    REQUIRED_FUNCTION(RSA_generate_key_ex) \
105ad9
+    REQUIRED_FUNCTION(RSA_get_method) \
105ad9
+    FALLBACK_FUNCTION(RSA_get0_crt_params) \
105ad9
+    FALLBACK_FUNCTION(RSA_get0_factors) \
105ad9
+    FALLBACK_FUNCTION(RSA_get0_key) \
105ad9
+    FALLBACK_FUNCTION(RSA_meth_get_flags) \
105ad9
+    REQUIRED_FUNCTION(RSA_new) \
105ad9
+    REQUIRED_FUNCTION(RSA_private_decrypt) \
105ad9
+    REQUIRED_FUNCTION(RSA_private_encrypt) \
105ad9
+    REQUIRED_FUNCTION(RSA_public_decrypt) \
105ad9
+    REQUIRED_FUNCTION(RSA_public_encrypt) \
105ad9
+    FALLBACK_FUNCTION(RSA_set0_crt_params) \
105ad9
+    FALLBACK_FUNCTION(RSA_set0_factors) \
105ad9
+    FALLBACK_FUNCTION(RSA_set0_key) \
105ad9
+    REQUIRED_FUNCTION(RSA_sign) \
105ad9
+    REQUIRED_FUNCTION(RSA_size) \
105ad9
+    REQUIRED_FUNCTION(RSA_up_ref) \
105ad9
+    REQUIRED_FUNCTION(RSA_verify) \
105ad9
+    REQUIRED_FUNCTION(SSL_CIPHER_description) \
105ad9
+    REQUIRED_FUNCTION(SSL_CIPHER_get_bits) \
105ad9
+    REQUIRED_FUNCTION(SSL_ctrl) \
105ad9
+    REQUIRED_FUNCTION(SSL_set_quiet_shutdown) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_check_private_key) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_ctrl) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_free) \
105ad9
+    FALLBACK_FUNCTION(SSL_is_init_finished) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_new) \
105ad9
+    LIGHTUP_FUNCTION(SSL_CTX_set_alpn_protos) \
105ad9
+    LIGHTUP_FUNCTION(SSL_CTX_set_alpn_select_cb) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_set_cert_verify_callback) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_set_cipher_list) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_set_client_cert_cb) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_set_quiet_shutdown) \
105ad9
+    FALLBACK_FUNCTION(SSL_CTX_set_options) \
105ad9
+    FALLBACK_FUNCTION(SSL_CTX_set_security_level) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_set_verify) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_use_certificate) \
105ad9
+    REQUIRED_FUNCTION(SSL_CTX_use_PrivateKey) \
105ad9
+    REQUIRED_FUNCTION(SSL_do_handshake) \
105ad9
+    REQUIRED_FUNCTION(SSL_free) \
105ad9
+    REQUIRED_FUNCTION(SSL_get_client_CA_list) \
105ad9
+    REQUIRED_FUNCTION(SSL_get_current_cipher) \
105ad9
+    REQUIRED_FUNCTION(SSL_get_error) \
105ad9
+    REQUIRED_FUNCTION(SSL_get_finished) \
105ad9
+    REQUIRED_FUNCTION(SSL_get_peer_cert_chain) \
105ad9
+    REQUIRED_FUNCTION(SSL_get_peer_certificate) \
105ad9
+    REQUIRED_FUNCTION(SSL_get_peer_finished) \
105ad9
+    REQUIRED_FUNCTION(SSL_get_SSL_CTX) \
105ad9
+    REQUIRED_FUNCTION(SSL_get_version) \
105ad9
+    LIGHTUP_FUNCTION(SSL_get0_alpn_selected) \
105ad9
+    LEGACY_FUNCTION(SSL_library_init) \
105ad9
+    LEGACY_FUNCTION(SSL_load_error_strings) \
105ad9
+    REQUIRED_FUNCTION(SSL_new) \
105ad9
+    REQUIRED_FUNCTION(SSL_read) \
105ad9
+    REQUIRED_FUNCTION(SSL_renegotiate_pending) \
105ad9
+    FALLBACK_FUNCTION(SSL_session_reused) \
105ad9
+    REQUIRED_FUNCTION(SSL_set_accept_state) \
105ad9
+    REQUIRED_FUNCTION(SSL_set_bio) \
105ad9
+    REQUIRED_FUNCTION(SSL_set_connect_state) \
105ad9
+    REQUIRED_FUNCTION(SSL_shutdown) \
105ad9
+    LEGACY_FUNCTION(SSL_state) \
105ad9
+    LEGACY_FUNCTION(SSLeay_version) \
105ad9
+    RENAMED_FUNCTION(TLS_method, SSLv23_method) \
105ad9
+    REQUIRED_FUNCTION(SSL_write) \
105ad9
+    REQUIRED_FUNCTION(X509_check_issued) \
105ad9
+    REQUIRED_FUNCTION(X509_check_purpose) \
105ad9
+    REQUIRED_FUNCTION(X509_CRL_free) \
105ad9
+    FALLBACK_FUNCTION(X509_CRL_get0_nextUpdate) \
105ad9
+    REQUIRED_FUNCTION(X509_digest) \
105ad9
+    REQUIRED_FUNCTION(X509_dup) \
105ad9
+    REQUIRED_FUNCTION(X509_EXTENSION_create_by_OBJ) \
105ad9
+    REQUIRED_FUNCTION(X509_EXTENSION_free) \
105ad9
+    REQUIRED_FUNCTION(X509_EXTENSION_get_critical) \
105ad9
+    REQUIRED_FUNCTION(X509_EXTENSION_get_data) \
105ad9
+    REQUIRED_FUNCTION(X509_EXTENSION_get_object) \
105ad9
+    REQUIRED_FUNCTION(X509_free) \
105ad9
+    REQUIRED_FUNCTION(X509_get_default_cert_dir) \
105ad9
+    REQUIRED_FUNCTION(X509_get_default_cert_dir_env) \
105ad9
+    REQUIRED_FUNCTION(X509_get_default_cert_file) \
105ad9
+    REQUIRED_FUNCTION(X509_get_default_cert_file_env) \
105ad9
+    REQUIRED_FUNCTION(X509_get_ext) \
105ad9
+    REQUIRED_FUNCTION(X509_get_ext_count) \
105ad9
+    REQUIRED_FUNCTION(X509_get_ext_d2i) \
105ad9
+    REQUIRED_FUNCTION(X509_get_issuer_name) \
105ad9
+    REQUIRED_FUNCTION(X509_get_serialNumber) \
105ad9
+    REQUIRED_FUNCTION(X509_get_subject_name) \
105ad9
+    FALLBACK_FUNCTION(X509_get_version) \
105ad9
+    FALLBACK_FUNCTION(X509_get_X509_PUBKEY) \
105ad9
+    FALLBACK_FUNCTION(X509_get0_notBefore) \
105ad9
+    FALLBACK_FUNCTION(X509_get0_notAfter) \
105ad9
+    FALLBACK_FUNCTION(X509_get0_pubkey_bitstr) \
105ad9
+    FALLBACK_FUNCTION(X509_get0_tbs_sigalg) \
105ad9
+    REQUIRED_FUNCTION(X509_issuer_name_hash) \
105ad9
+    REQUIRED_FUNCTION(X509_NAME_entry_count) \
105ad9
+    REQUIRED_FUNCTION(X509_NAME_ENTRY_get_data) \
105ad9
+    REQUIRED_FUNCTION(X509_NAME_ENTRY_get_object) \
105ad9
+    REQUIRED_FUNCTION(X509_NAME_free) \
105ad9
+    REQUIRED_FUNCTION(X509_NAME_get_entry) \
105ad9
+    REQUIRED_FUNCTION(X509_NAME_get_index_by_NID) \
105ad9
+    FALLBACK_FUNCTION(X509_NAME_get0_der) \
105ad9
+    REQUIRED_FUNCTION(X509_PUBKEY_get) \
105ad9
+    FALLBACK_FUNCTION(X509_PUBKEY_get0_param) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_add_cert) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_add_crl) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_CTX_free) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_CTX_get0_param) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_CTX_get1_chain) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_CTX_get_error) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_CTX_get_error_depth) \
105ad9
+    FALLBACK_FUNCTION(X509_STORE_CTX_get0_cert) \
105ad9
+    FALLBACK_FUNCTION(X509_STORE_CTX_get0_untrusted) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_CTX_init) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_CTX_new) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_CTX_set_flags) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_CTX_set_verify_cb) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_free) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_new) \
105ad9
+    REQUIRED_FUNCTION(X509_STORE_set_flags) \
105ad9
+    REQUIRED_FUNCTION(X509V3_EXT_print) \
105ad9
+    FALLBACK_FUNCTION(X509_up_ref) \
105ad9
+    REQUIRED_FUNCTION(X509_verify_cert) \
105ad9
+    REQUIRED_FUNCTION(X509_verify_cert_error_string) \
105ad9
+    REQUIRED_FUNCTION(X509_VERIFY_PARAM_set_time) \
105ad9
+    LIGHTUP_FUNCTION(EC_GF2m_simple_method) \
105ad9
+    LIGHTUP_FUNCTION(EC_GROUP_get_curve_GF2m) \
105ad9
+    LIGHTUP_FUNCTION(EC_GROUP_set_curve_GF2m) \
105ad9
+    LIGHTUP_FUNCTION(EC_POINT_get_affine_coordinates_GF2m) \
105ad9
+    LIGHTUP_FUNCTION(EC_POINT_set_affine_coordinates_GF2m) \
105ad9
     
105ad9
 // Declare pointers to all the used OpenSSL functions
105ad9
-#define PER_FUNCTION_BLOCK(fn, isRequired) extern decltype(fn)* fn##_ptr;
105ad9
+#define REQUIRED_FUNCTION(fn) extern "C" __typeof(fn)* fn##_ptr;
105ad9
+#define NEW_REQUIRED_FUNCTION(fn) extern "C" __typeof(fn)* fn##_ptr;
105ad9
+#define LIGHTUP_FUNCTION(fn) extern "C" __typeof(fn)* fn##_ptr;
105ad9
+#define FALLBACK_FUNCTION(fn) extern "C" __typeof(fn)* fn##_ptr;
105ad9
+#define RENAMED_FUNCTION(fn,oldfn) extern "C" __typeof(fn)* fn##_ptr;
105ad9
+#define LEGACY_FUNCTION(fn) extern "C" __typeof(fn)* fn##_ptr;
105ad9
 FOR_ALL_OPENSSL_FUNCTIONS
105ad9
-#undef PER_FUNCTION_BLOCK
105ad9
+#undef LEGACY_FUNCTION
105ad9
+#undef RENAMED_FUNCTION
105ad9
+#undef FALLBACK_FUNCTION
105ad9
+#undef LIGHTUP_FUNCTION
105ad9
+#undef NEW_REQUIRED_FUNCTION
105ad9
+#undef REQUIRED_FUNCTION
105ad9
 
105ad9
 // Redefine all calls to OpenSSL functions as calls through pointers that are set
105ad9
 // to the functions from the libssl.so selected by the shim.
105ad9
@@ -415,8 +564,13 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define DSA_free DSA_free_ptr
105ad9
 #define DSA_generate_key DSA_generate_key_ptr
105ad9
 #define DSA_generate_parameters_ex DSA_generate_parameters_ex_ptr
105ad9
+#define DSA_get0_key DSA_get0_key_ptr
105ad9
+#define DSA_get0_pqg DSA_get0_pqg_ptr
105ad9
+#define DSA_get_method DSA_get_method_ptr
105ad9
 #define DSA_new DSA_new_ptr
105ad9
 #define DSA_OpenSSL DSA_OpenSSL_ptr
105ad9
+#define DSA_set0_key DSA_set0_key_ptr
105ad9
+#define DSA_set0_pqg DSA_set0_pqg_ptr
105ad9
 #define DSA_sign DSA_sign_ptr
105ad9
 #define DSA_size DSA_size_ptr
105ad9
 #define DSA_up_ref DSA_up_ref_ptr
105ad9
@@ -474,7 +628,10 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define EVP_aes_256_ecb EVP_aes_256_ecb_ptr
105ad9
 #define EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_cleanup_ptr
105ad9
 #define EVP_CIPHER_CTX_ctrl EVP_CIPHER_CTX_ctrl_ptr
105ad9
+#define EVP_CIPHER_CTX_free EVP_CIPHER_CTX_free_ptr
105ad9
 #define EVP_CIPHER_CTX_init EVP_CIPHER_CTX_init_ptr
105ad9
+#define EVP_CIPHER_CTX_new EVP_CIPHER_CTX_new_ptr
105ad9
+#define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_reset_ptr
105ad9
 #define EVP_CIPHER_CTX_set_key_length EVP_CIPHER_CTX_set_key_length_ptr
105ad9
 #define EVP_CIPHER_CTX_set_padding EVP_CIPHER_CTX_set_padding_ptr
105ad9
 #define EVP_CipherFinal_ex EVP_CipherFinal_ex_ptr
105ad9
@@ -489,8 +646,8 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define EVP_DigestUpdate EVP_DigestUpdate_ptr
105ad9
 #define EVP_get_digestbyname EVP_get_digestbyname_ptr
105ad9
 #define EVP_md5 EVP_md5_ptr
105ad9
-#define EVP_MD_CTX_create EVP_MD_CTX_create_ptr
105ad9
-#define EVP_MD_CTX_destroy EVP_MD_CTX_destroy_ptr
105ad9
+#define EVP_MD_CTX_free EVP_MD_CTX_free_ptr
105ad9
+#define EVP_MD_CTX_new EVP_MD_CTX_new_ptr
105ad9
 #define EVP_MD_size EVP_MD_size_ptr
105ad9
 #define EVP_PKEY_CTX_free EVP_PKEY_CTX_free_ptr
105ad9
 #define EVP_PKEY_CTX_new EVP_PKEY_CTX_new_ptr
105ad9
@@ -505,6 +662,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define EVP_PKEY_set1_DSA EVP_PKEY_set1_DSA_ptr
105ad9
 #define EVP_PKEY_set1_EC_KEY EVP_PKEY_set1_EC_KEY_ptr
105ad9
 #define EVP_PKEY_set1_RSA EVP_PKEY_set1_RSA_ptr
105ad9
+#define EVP_PKEY_up_ref EVP_PKEY_up_ref_ptr
105ad9
 #define EVP_rc2_cbc EVP_rc2_cbc_ptr
105ad9
 #define EVP_rc2_ecb EVP_rc2_ecb_ptr
105ad9
 #define EVP_sha1 EVP_sha1_ptr
105ad9
@@ -514,7 +672,9 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define EXTENDED_KEY_USAGE_free EXTENDED_KEY_USAGE_free_ptr
105ad9
 #define GENERAL_NAMES_free GENERAL_NAMES_free_ptr
105ad9
 #define HMAC_CTX_cleanup HMAC_CTX_cleanup_ptr
105ad9
+#define HMAC_CTX_free HMAC_CTX_free_ptr
105ad9
 #define HMAC_CTX_init HMAC_CTX_init_ptr
105ad9
+#define HMAC_CTX_new HMAC_CTX_new_ptr
105ad9
 #define HMAC_Final HMAC_Final_ptr
105ad9
 #define HMAC_Init_ex HMAC_Init_ex_ptr
105ad9
 #define HMAC_Update HMAC_Update_ptr
105ad9
@@ -535,6 +695,15 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define OBJ_txt2obj OBJ_txt2obj_ptr
105ad9
 #define OPENSSL_add_all_algorithms_conf OPENSSL_add_all_algorithms_conf_ptr
105ad9
 #define OPENSSL_cleanse OPENSSL_cleanse_ptr
105ad9
+#define OPENSSL_init_ssl OPENSSL_init_ssl_ptr
105ad9
+#define OPENSSL_sk_free OPENSSL_sk_free_ptr
105ad9
+#define OPENSSL_sk_new_null OPENSSL_sk_new_null_ptr
105ad9
+#define OPENSSL_sk_num OPENSSL_sk_num_ptr
105ad9
+#define OPENSSL_sk_pop_free OPENSSL_sk_pop_free_ptr
105ad9
+#define OPENSSL_sk_push OPENSSL_sk_push_ptr
105ad9
+#define OPENSSL_sk_value OPENSSL_sk_value_ptr
105ad9
+#define OpenSSL_version OpenSSL_version_ptr
105ad9
+#define OpenSSL_version_num OpenSSL_version_num_ptr
105ad9
 #define PEM_read_bio_PKCS7 PEM_read_bio_PKCS7_ptr
105ad9
 #define PEM_read_bio_X509_AUX PEM_read_bio_X509_AUX_ptr
105ad9
 #define PEM_read_bio_X509_CRL PEM_read_bio_X509_CRL_ptr
105ad9
@@ -551,22 +720,30 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define RAND_poll RAND_poll_ptr
105ad9
 #define RSA_free RSA_free_ptr
105ad9
 #define RSA_generate_key_ex RSA_generate_key_ex_ptr
105ad9
+#define RSA_get0_crt_params RSA_get0_crt_params_ptr
105ad9
+#define RSA_get0_factors RSA_get0_factors_ptr
105ad9
+#define RSA_get0_key RSA_get0_key_ptr
105ad9
 #define RSA_get_method RSA_get_method_ptr
105ad9
+#define RSA_meth_get_flags RSA_meth_get_flags_ptr
105ad9
 #define RSA_new RSA_new_ptr
105ad9
 #define RSA_private_decrypt RSA_private_decrypt_ptr
105ad9
 #define RSA_private_encrypt RSA_private_encrypt_ptr
105ad9
 #define RSA_public_decrypt RSA_public_decrypt_ptr
105ad9
 #define RSA_public_encrypt RSA_public_encrypt_ptr
105ad9
+#define RSA_set0_crt_params RSA_set0_crt_params_ptr
105ad9
+#define RSA_set0_factors RSA_set0_factors_ptr
105ad9
+#define RSA_set0_key RSA_set0_key_ptr
105ad9
 #define RSA_sign RSA_sign_ptr
105ad9
 #define RSA_size RSA_size_ptr
105ad9
 #define RSA_up_ref RSA_up_ref_ptr
105ad9
 #define RSA_verify RSA_verify_ptr
105ad9
-#define sk_free sk_free_ptr
105ad9
-#define sk_new_null sk_new_null_ptr
105ad9
-#define sk_num sk_num_ptr
105ad9
-#define sk_pop_free sk_pop_free_ptr
105ad9
-#define sk_push sk_push_ptr
105ad9
-#define sk_value sk_value_ptr
105ad9
+#define sk_free OPENSSL_sk_free_ptr
105ad9
+#define sk_new_null OPENSSL_sk_new_null_ptr
105ad9
+#define sk_num OPENSSL_sk_num_ptr
105ad9
+#define sk_pop_free OPENSSL_sk_pop_free_ptr
105ad9
+#define sk_push OPENSSL_sk_push_ptr
105ad9
+#define sk_value OPENSSL_sk_value_ptr
105ad9
+#define SSL_CIPHER_get_bits SSL_CIPHER_get_bits_ptr
105ad9
 #define SSL_CIPHER_description SSL_CIPHER_description_ptr
105ad9
 #define SSL_ctrl SSL_ctrl_ptr
105ad9
 #define SSL_set_quiet_shutdown SSL_set_quiet_shutdown_ptr
105ad9
@@ -579,7 +756,9 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define SSL_CTX_set_cert_verify_callback SSL_CTX_set_cert_verify_callback_ptr
105ad9
 #define SSL_CTX_set_cipher_list SSL_CTX_set_cipher_list_ptr
105ad9
 #define SSL_CTX_set_client_cert_cb SSL_CTX_set_client_cert_cb_ptr
105ad9
+#define SSL_CTX_set_options SSL_CTX_set_options_ptr
105ad9
 #define SSL_CTX_set_quiet_shutdown SSL_CTX_set_quiet_shutdown_ptr
105ad9
+#define SSL_CTX_set_security_level SSL_CTX_set_security_level_ptr
105ad9
 #define SSL_CTX_set_verify SSL_CTX_set_verify_ptr
105ad9
 #define SSL_CTX_use_certificate SSL_CTX_use_certificate_ptr
105ad9
 #define SSL_CTX_use_PrivateKey SSL_CTX_use_PrivateKey_ptr
105ad9
@@ -595,25 +774,26 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define SSL_get_SSL_CTX SSL_get_SSL_CTX_ptr
105ad9
 #define SSL_get_version SSL_get_version_ptr
105ad9
 #define SSL_get0_alpn_selected SSL_get0_alpn_selected_ptr
105ad9
+#define SSL_is_init_finished SSL_is_init_finished_ptr
105ad9
 #define SSL_library_init SSL_library_init_ptr
105ad9
 #define SSL_load_error_strings SSL_load_error_strings_ptr
105ad9
 #define SSL_new SSL_new_ptr
105ad9
 #define SSL_read SSL_read_ptr
105ad9
 #define SSL_renegotiate_pending SSL_renegotiate_pending_ptr
105ad9
+#define SSL_session_reused SSL_session_reused_ptr
105ad9
 #define SSL_set_accept_state SSL_set_accept_state_ptr
105ad9
 #define SSL_set_bio SSL_set_bio_ptr
105ad9
 #define SSL_set_connect_state SSL_set_connect_state_ptr
105ad9
 #define SSL_shutdown SSL_shutdown_ptr
105ad9
 #define SSL_state SSL_state_ptr
105ad9
 #define SSLeay_version SSLeay_version_ptr
105ad9
-#define SSLv23_method SSLv23_method_ptr
105ad9
+#define SSLeay SSLeay_ptr
105ad9
 #define SSL_write SSL_write_ptr
105ad9
-#define TLSv1_1_method TLSv1_1_method_ptr
105ad9
-#define TLSv1_2_method TLSv1_2_method_ptr
105ad9
-#define TLSv1_method TLSv1_method_ptr
105ad9
+#define TLS_method TLS_method_ptr
105ad9
 #define X509_check_issued X509_check_issued_ptr
105ad9
 #define X509_check_purpose X509_check_purpose_ptr
105ad9
 #define X509_CRL_free X509_CRL_free_ptr
105ad9
+#define X509_CRL_get0_nextUpdate X509_CRL_get0_nextUpdate_ptr
105ad9
 #define X509_digest X509_digest_ptr
105ad9
 #define X509_dup X509_dup_ptr
105ad9
 #define X509_EXTENSION_create_by_OBJ X509_EXTENSION_create_by_OBJ_ptr
105ad9
@@ -622,6 +802,10 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define X509_EXTENSION_get_data X509_EXTENSION_get_data_ptr
105ad9
 #define X509_EXTENSION_get_object X509_EXTENSION_get_object_ptr
105ad9
 #define X509_free X509_free_ptr
105ad9
+#define X509_get0_notAfter X509_get0_notAfter_ptr
105ad9
+#define X509_get0_notBefore X509_get0_notBefore_ptr
105ad9
+#define X509_get0_pubkey_bitstr X509_get0_pubkey_bitstr_ptr
105ad9
+#define X509_get0_tbs_sigalg X509_get0_tbs_sigalg_ptr
105ad9
 #define X509_get_default_cert_dir X509_get_default_cert_dir_ptr
105ad9
 #define X509_get_default_cert_dir_env X509_get_default_cert_dir_env_ptr
105ad9
 #define X509_get_default_cert_file X509_get_default_cert_file_ptr
105ad9
@@ -632,18 +816,24 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define X509_get_issuer_name X509_get_issuer_name_ptr
105ad9
 #define X509_get_serialNumber X509_get_serialNumber_ptr
105ad9
 #define X509_get_subject_name X509_get_subject_name_ptr
105ad9
+#define X509_get_X509_PUBKEY X509_get_X509_PUBKEY_ptr
105ad9
+#define X509_get_version X509_get_version_ptr
105ad9
 #define X509_issuer_name_hash X509_issuer_name_hash_ptr
105ad9
 #define X509_NAME_entry_count X509_NAME_entry_count_ptr
105ad9
 #define X509_NAME_ENTRY_get_data X509_NAME_ENTRY_get_data_ptr
105ad9
 #define X509_NAME_ENTRY_get_object X509_NAME_ENTRY_get_object_ptr
105ad9
 #define X509_NAME_free X509_NAME_free_ptr
105ad9
+#define X509_NAME_get0_der X509_NAME_get0_der_ptr
105ad9
 #define X509_NAME_get_entry X509_NAME_get_entry_ptr
105ad9
 #define X509_NAME_get_index_by_NID X509_NAME_get_index_by_NID_ptr
105ad9
+#define X509_PUBKEY_get0_param X509_PUBKEY_get0_param_ptr
105ad9
 #define X509_PUBKEY_get X509_PUBKEY_get_ptr
105ad9
 #define X509_STORE_add_cert X509_STORE_add_cert_ptr
105ad9
 #define X509_STORE_add_crl X509_STORE_add_crl_ptr
105ad9
 #define X509_STORE_CTX_free X509_STORE_CTX_free_ptr
105ad9
+#define X509_STORE_CTX_get0_cert X509_STORE_CTX_get0_cert_ptr
105ad9
 #define X509_STORE_CTX_get0_param X509_STORE_CTX_get0_param_ptr
105ad9
+#define X509_STORE_CTX_get0_untrusted X509_STORE_CTX_get0_untrusted_ptr
105ad9
 #define X509_STORE_CTX_get1_chain X509_STORE_CTX_get1_chain_ptr
105ad9
 #define X509_STORE_CTX_get_error X509_STORE_CTX_get_error_ptr
105ad9
 #define X509_STORE_CTX_get_error_depth X509_STORE_CTX_get_error_depth_ptr
105ad9
@@ -655,6 +845,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define X509_STORE_new X509_STORE_new_ptr
105ad9
 #define X509_STORE_set_flags X509_STORE_set_flags_ptr
105ad9
 #define X509V3_EXT_print X509V3_EXT_print_ptr
105ad9
+#define X509_up_ref X509_up_ref_ptr
105ad9
 #define X509_verify_cert X509_verify_cert_ptr
105ad9
 #define X509_verify_cert_error_string X509_verify_cert_error_string_ptr
105ad9
 #define X509_VERIFY_PARAM_set_time X509_VERIFY_PARAM_set_time_ptr
105ad9
@@ -664,8 +855,99 @@ FOR_ALL_OPENSSL_FUNCTIONS
105ad9
 #define EC_POINT_get_affine_coordinates_GF2m EC_POINT_get_affine_coordinates_GF2m_ptr
105ad9
 #define EC_POINT_set_affine_coordinates_GF2m EC_POINT_set_affine_coordinates_GF2m_ptr
105ad9
 
105ad9
+
105ad9
+// STACK_OF types will have been declared with inline functions to handle the pointer casting.
105ad9
+// Since these inline functions are strongly bound to the OPENSSL_sk_* functions in 1.1 we need to
105ad9
+// rebind things here.
105ad9
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM
105ad9
+// type-safe OPENSSL_sk_free
105ad9
+#define sk_GENERAL_NAME_free(stack) OPENSSL_sk_free((OPENSSL_STACK*)(1 ? stack : (STACK_OF(GENERAL_NAME)*)0))
105ad9
+
105ad9
+// type-safe OPENSSL_sk_num
105ad9
+#define sk_ASN1_OBJECT_num(stack) OPENSSL_sk_num((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(ASN1_OBJECT)*)0))
105ad9
+#define sk_GENERAL_NAME_num(stack) OPENSSL_sk_num((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(GENERAL_NAME)*)0))
105ad9
+#define sk_X509_NAME_num(stack) OPENSSL_sk_num((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(X509_NAME)*)0))
105ad9
+#define sk_X509_num(stack) OPENSSL_sk_num((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(X509)*)0))
105ad9
+
105ad9
+// type-safe OPENSSL_sk_new_null
105ad9
+#define sk_X509_new_null() (STACK_OF(X509)*)OPENSSL_sk_new_null()
105ad9
+#define sk_X509_NAME_new_null() (STACK_OF(X509_NAME)*)OPENSSL_sk_new_null()
105ad9
+
105ad9
+// type-safe OPENSSL_sk_push
105ad9
+#define sk_X509_push(stack,value) OPENSSL_sk_push((OPENSSL_STACK*)(1 ? stack : (STACK_OF(X509)*)0), (const void*)(1 ? value : (X509*)0))
105ad9
+#define sk_X509_NAME_push(stack,value) OPENSSL_sk_push((OPENSSL_STACK*)(1 ? stack : (STACK_OF(X509_NAME)*)0), (const void*)(1 ? value : (X509_NAME*)0))
105ad9
+
105ad9
+// type-safe OPENSSL_sk_pop_free
105ad9
+#define sk_X509_pop_free(stack, freefunc) OPENSSL_sk_pop_free((OPENSSL_STACK*)(1 ? stack : (STACK_OF(X509)*)0), (OPENSSL_sk_freefunc)(1 ? freefunc : (sk_X509_freefunc)0))
105ad9
+#define sk_X509_NAME_pop_free(stack, freefunc) OPENSSL_sk_pop_free((OPENSSL_STACK*)(1 ? stack : (STACK_OF(X509_NAME)*)0), (OPENSSL_sk_freefunc)(1 ? freefunc : (sk_X509_NAME_freefunc)0))
105ad9
+
105ad9
+// type-safe OPENSSL_sk_value
105ad9
+#define sk_ASN1_OBJECT_value(stack, idx) (ASN1_OBJECT*)OPENSSL_sk_value((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(ASN1_OBJECT)*)0), idx)
105ad9
+#define sk_GENERAL_NAME_value(stack, idx) (GENERAL_NAME*)OPENSSL_sk_value((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(GENERAL_NAME)*)0), idx)
105ad9
+#define sk_X509_NAME_value(stack, idx) (X509_NAME*)OPENSSL_sk_value((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(X509_NAME)*)0), idx)
105ad9
+#define sk_X509_value(stack, idx) (X509*)OPENSSL_sk_value((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(X509)*)0), idx)
105ad9
+#endif
105ad9
+
105ad9
+
105ad9
 #else // FEATURE_DISTRO_AGNOSTIC_SSL
105ad9
 
105ad9
 #define API_EXISTS(fn) true
105ad9
 
105ad9
+#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
105ad9
+
105ad9
+#define NEED_OPENSSL_1_0 true
105ad9
+
105ad9
+// Alias "future" API to the local_ version.
105ad9
+#define DSA_get0_key local_DSA_get0_key
105ad9
+#define DSA_get0_pqg local_DSA_get0_pqg
105ad9
+#define DSA_get_method local_DSA_get_method
105ad9
+#define DSA_set0_key local_DSA_set0_key
105ad9
+#define DSA_set0_pqg local_DSA_set0_pqg
105ad9
+#define EVP_CIPHER_CTX_free local_EVP_CIPHER_CTX_free
105ad9
+#define EVP_CIPHER_CTX_new local_EVP_CIPHER_CTX_new
105ad9
+#define EVP_CIPHER_CTX_reset local_EVP_CIPHER_CTX_reset
105ad9
+#define EVP_PKEY_up_ref local_EVP_PKEY_up_ref
105ad9
+#define HMAC_CTX_free local_HMAC_CTX_free
105ad9
+#define HMAC_CTX_new local_HMAC_CTX_new
105ad9
+#define OpenSSL_version local_OpenSSL_version
105ad9
+#define RSA_get0_crt_params local_RSA_get0_crt_params
105ad9
+#define RSA_get0_factors local_RSA_get0_factors
105ad9
+#define RSA_get0_key local_RSA_get0_key
105ad9
+#define RSA_meth_get_flags local_RSA_meth_get_flags
105ad9
+#define RSA_set0_crt_params local_RSA_set0_crt_params
105ad9
+#define RSA_set0_factors local_RSA_set0_factors
105ad9
+#define RSA_set0_key local_RSA_set0_key
105ad9
+#define SSL_CTX_set_security_level local_SSL_CTX_set_security_level
105ad9
+#define SSL_is_init_finished local_SSL_is_init_finished
105ad9
+#define X509_CRL_get0_nextUpdate local_X509_CRL_get0_nextUpdate
105ad9
+#define X509_NAME_get0_der local_X509_NAME_get0_der
105ad9
+#define X509_PUBKEY_get0_param local_X509_PUBKEY_get0_param
105ad9
+#define X509_STORE_CTX_get0_cert local_X509_STORE_CTX_get0_cert
105ad9
+#define X509_STORE_CTX_get0_untrusted local_X509_STORE_CTX_get0_untrusted
105ad9
+#define X509_get0_notAfter local_X509_get0_notAfter
105ad9
+#define X509_get0_notBefore local_X509_get0_notBefore
105ad9
+#define X509_get0_pubkey_bitstr local_X509_get0_pubkey_bitstr
105ad9
+#define X509_get0_tbs_sigalg local_X509_get0_tbs_sigalg
105ad9
+#define X509_get_X509_PUBKEY local_X509_get_X509_PUBKEY
105ad9
+#define X509_get_version local_X509_get_version
105ad9
+#define X509_up_ref local_X509_up_ref
105ad9
+
105ad9
+// Restore the old names for RENAMED_FUNCTION functions.
105ad9
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
105ad9
+#define EVP_MD_CTX_new EVP_MD_CTX_create
105ad9
+#define OPENSSL_sk_free sk_free
105ad9
+#define OPENSSL_sk_new_null sk_new_null
105ad9
+#define OPENSSL_sk_num sk_num
105ad9
+#define OPENSSL_sk_pop_free sk_pop_free
105ad9
+#define OPENSSL_sk_push sk_push
105ad9
+#define OPENSSL_sk_value sk_value
105ad9
+#define TLS_method SSLv23_method
105ad9
+#define OpenSSL_version_num SSLeay
105ad9
+
105ad9
+#else // if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
105ad9
+
105ad9
+#define NEED_OPENSSL_1_1 true
105ad9
+
105ad9
+#endif
105ad9
+
105ad9
 #endif // FEATURE_DISTRO_AGNOSTIC_SSL
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1.cpp
105ad9
index 5429592e57..006881aa33 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1.cpp
105ad9
@@ -42,7 +42,7 @@ extern "C" int32_t CryptoNative_ObjSn2Nid(const char* sn)
105ad9
     return OBJ_sn2nid(sn);
105ad9
 }
105ad9
 
105ad9
-extern "C" ASN1_OBJECT* CryptoNative_ObjNid2Obj(int32_t nid)
105ad9
+extern "C" const ASN1_OBJECT* CryptoNative_ObjNid2Obj(int32_t nid)
105ad9
 {
105ad9
     return OBJ_nid2obj(nid);
105ad9
 }
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1.h b/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1.h
105ad9
index 6ec1795d25..6f9445aa9f 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1.h
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1.h
105ad9
@@ -42,7 +42,7 @@ extern "C" int32_t CryptoNative_ObjSn2Nid(const char* sn);
105ad9
 /*
105ad9
 Direct shim to OBJ_nid2obj.
105ad9
 */
105ad9
-extern "C" ASN1_OBJECT* CryptoNative_ObjNid2Obj(int32_t nid);
105ad9
+extern "C" const ASN1_OBJECT* CryptoNative_ObjNid2Obj(int32_t nid);
105ad9
 
105ad9
 /*
105ad9
 Direct shim to ASN1_OBJECT_free.
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1_print.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1_print.cpp
105ad9
index 01a544f5e9..328b5e5935 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1_print.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_asn1_print.cpp
105ad9
@@ -31,12 +31,19 @@ static_assert(PAL_ASN1_STRFLGS_UTF8_CONVERT == ASN1_STRFLGS_UTF8_CONVERT, "");
105ad9
 
105ad9
 extern "C" ASN1_STRING* CryptoNative_DecodeAsn1TypeBytes(const uint8_t* buf, int32_t len, Asn1StringTypeFlags type)
105ad9
 {
105ad9
-    if (!buf || !len)
105ad9
+#if NEED_OPENSSL_1_0
105ad9
+    if (!API_EXISTS(d2i_ASN1_type_bytes) || !buf || !len)
105ad9
     {
105ad9
         return nullptr;
105ad9
     }
105ad9
 
105ad9
     return d2i_ASN1_type_bytes(nullptr, &buf, len, type);
105ad9
+#else
105ad9
+    (void)buf;
105ad9
+    (void)len;
105ad9
+    (void)type;
105ad9
+    return nullptr;
105ad9
+#endif
105ad9
 }
105ad9
 
105ad9
 extern "C" int32_t CryptoNative_Asn1StringPrintEx(BIO* out, ASN1_STRING* str, Asn1StringPrintFlags flags)
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_crypto_config.h.in b/src/Native/Unix/System.Security.Cryptography.Native/pal_crypto_config.h.in
105ad9
index 6aea13f2c6..1aa48ba9d7 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_crypto_config.h.in
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_crypto_config.h.in
105ad9
@@ -1,6 +1,4 @@
105ad9
 #pragma once
105ad9
 
105ad9
-#cmakedefine01 HAVE_TLS_V1_1
105ad9
-#cmakedefine01 HAVE_TLS_V1_2
105ad9
 #cmakedefine01 HAVE_OPENSSL_EC2M
105ad9
 #cmakedefine01 HAVE_OPENSSL_ALPN
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.cpp
105ad9
index af9ce59d64..74d76a89d7 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.cpp
105ad9
@@ -45,12 +45,34 @@ extern "C" int32_t CryptoNative_DsaSizeSignature(DSA* dsa)
105ad9
 
105ad9
 extern "C" int32_t CryptoNative_DsaSizeP(DSA* dsa)
105ad9
 {
105ad9
-    return BN_num_bytes(dsa->p);
105ad9
+    if (dsa)
105ad9
+    {
105ad9
+        const BIGNUM* p;
105ad9
+        DSA_get0_pqg(dsa, &p, nullptr, nullptr);
105ad9
+
105ad9
+        if (p)
105ad9
+        {
105ad9
+            return BN_num_bytes(p);
105ad9
+        }
105ad9
+    }
105ad9
+
105ad9
+    return -1;
105ad9
 }
105ad9
 
105ad9
 extern "C" int32_t CryptoNative_DsaSizeQ(DSA* dsa)
105ad9
 {
105ad9
-    return BN_num_bytes(dsa->q);
105ad9
+    if (dsa)
105ad9
+    {
105ad9
+        const BIGNUM* q;
105ad9
+        DSA_get0_pqg(dsa, nullptr, &q, nullptr);
105ad9
+
105ad9
+        if (q)
105ad9
+        {
105ad9
+            return BN_num_bytes(q);
105ad9
+        }
105ad9
+    }
105ad9
+
105ad9
+    return -1;
105ad9
 }
105ad9
 
105ad9
 extern "C" int32_t CryptoNative_DsaSign(
105ad9
@@ -67,11 +89,18 @@ extern "C" int32_t CryptoNative_DsaSign(
105ad9
     }
105ad9
 
105ad9
     // DSA_OpenSSL() returns a shared pointer, no need to free/cache.
105ad9
-    if (dsa->meth == DSA_OpenSSL() && dsa->priv_key == nullptr)
105ad9
+    if (DSA_get_method(dsa) == DSA_OpenSSL())
105ad9
     {
105ad9
-        *outSignatureLength = 0;
105ad9
-        ERR_PUT_error(ERR_LIB_DSA, DSA_F_DSA_DO_SIGN, DSA_R_MISSING_PARAMETERS, __FILE__, __LINE__);
105ad9
-        return 0;
105ad9
+        const BIGNUM* privKey;
105ad9
+
105ad9
+        DSA_get0_key(dsa, nullptr, &privKey);
105ad9
+
105ad9
+        if (!privKey)
105ad9
+        {
105ad9
+            *outSignatureLength = 0;
105ad9
+            ERR_PUT_error(ERR_LIB_DSA, DSA_F_DSA_DO_SIGN, DSA_R_MISSING_PARAMETERS, __FILE__, __LINE__);
105ad9
+            return 0;
105ad9
+        }
105ad9
     }
105ad9
 
105ad9
     unsigned int unsignedSigLen = 0;
105ad9
@@ -111,11 +140,11 @@ extern "C" int32_t CryptoNative_DsaVerify(
105ad9
 
105ad9
 extern "C" int32_t CryptoNative_GetDsaParameters(
105ad9
     const DSA* dsa,
105ad9
-    BIGNUM** p, int32_t* pLength,
105ad9
-    BIGNUM** q, int32_t* qLength,
105ad9
-    BIGNUM** g, int32_t* gLength,
105ad9
-    BIGNUM** y, int32_t* yLength,
105ad9
-    BIGNUM** x, int32_t* xLength)
105ad9
+    const BIGNUM** p, int32_t* pLength,
105ad9
+    const BIGNUM** q, int32_t* qLength,
105ad9
+    const BIGNUM** g, int32_t* gLength,
105ad9
+    const BIGNUM** y, int32_t* yLength,
105ad9
+    const BIGNUM** x, int32_t* xLength)
105ad9
 {
105ad9
     if (!dsa || !p || !q || !g || !y || !x)
105ad9
     {
105ad9
@@ -129,39 +158,28 @@ extern "C" int32_t CryptoNative_GetDsaParameters(
105ad9
         if (x) *x = nullptr; if (xLength) *xLength = 0;
105ad9
         return 0;
105ad9
     }
105ad9
-    
105ad9
-    *p = dsa->p; *pLength = BN_num_bytes(*p);
105ad9
-    *q = dsa->q; *qLength = BN_num_bytes(*q);
105ad9
-    *g = dsa->g; *gLength = BN_num_bytes(*g);
105ad9
-    *y = dsa->pub_key; *yLength = BN_num_bytes(*y);
105ad9
-
105ad9
-    // dsa->priv_key is optional
105ad9
-    *x = dsa->priv_key;
105ad9
+
105ad9
+    DSA_get0_pqg(dsa, p, q, g);
105ad9
+    *pLength = BN_num_bytes(*p);
105ad9
+    *qLength = BN_num_bytes(*q);
105ad9
+    *gLength = BN_num_bytes(*g);
105ad9
+
105ad9
+    DSA_get0_key(dsa, y, x);
105ad9
+    *yLength = BN_num_bytes(*y);
105ad9
+    // x (the private key) is optional
105ad9
     *xLength = (*x == nullptr) ? 0 : BN_num_bytes(*x);
105ad9
 
105ad9
     return 1;
105ad9
 }
105ad9
 
105ad9
-static int32_t SetDsaParameter(BIGNUM** dsaFieldAddress, uint8_t* buffer, int32_t bufferLength)
105ad9
+static BIGNUM* MakeBignum(uint8_t* buffer, int32_t bufferLength)
105ad9
 {
105ad9
-    assert(dsaFieldAddress != nullptr);
105ad9
-    if (dsaFieldAddress)
105ad9
+    if (buffer && bufferLength)
105ad9
     {
105ad9
-        if (!buffer || !bufferLength)
105ad9
-        {
105ad9
-            *dsaFieldAddress = nullptr;
105ad9
-            return 1;
105ad9
-        }
105ad9
-        else
105ad9
-        {
105ad9
-            BIGNUM* bigNum = BN_bin2bn(buffer, bufferLength, nullptr);
105ad9
-            *dsaFieldAddress = bigNum;
105ad9
-
105ad9
-            return bigNum != nullptr;
105ad9
-        }
105ad9
+        return BN_bin2bn(buffer, bufferLength, nullptr);
105ad9
     }
105ad9
 
105ad9
-    return 0;
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 extern "C" int32_t CryptoNative_DsaKeyCreateByExplicitParameters(
105ad9
@@ -191,10 +209,33 @@ extern "C" int32_t CryptoNative_DsaKeyCreateByExplicitParameters(
105ad9
 
105ad9
     DSA* dsa = *outDsa;
105ad9
 
105ad9
-    return
105ad9
-        SetDsaParameter(&dsa->p, p, pLength) &&
105ad9
-        SetDsaParameter(&dsa->q, q, qLength) &&
105ad9
-        SetDsaParameter(&dsa->g, g, gLength) &&
105ad9
-        SetDsaParameter(&dsa->pub_key, y, yLength) &&
105ad9
-        SetDsaParameter(&dsa->priv_key, x, xLength);
105ad9
+    BIGNUM* bnP = MakeBignum(p, pLength);
105ad9
+    BIGNUM* bnQ = MakeBignum(q, qLength);
105ad9
+    BIGNUM* bnG = MakeBignum(g, gLength);
105ad9
+
105ad9
+    if (!DSA_set0_pqg(dsa, bnP, bnQ, bnG))
105ad9
+    {
105ad9
+        // BN_free handles NULL input
105ad9
+        BN_free(bnP);
105ad9
+        BN_free(bnQ);
105ad9
+        BN_free(bnG);
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    // Control was transferred, do not free.
105ad9
+    bnP = nullptr;
105ad9
+    bnQ = nullptr;
105ad9
+    bnG = nullptr;
105ad9
+
105ad9
+    BIGNUM* bnY = MakeBignum(y, yLength);
105ad9
+    BIGNUM* bnX = MakeBignum(x, xLength);
105ad9
+
105ad9
+    if (!DSA_set0_key(dsa, bnY, bnX))
105ad9
+    {
105ad9
+        BN_free(bnY);
105ad9
+        BN_free(bnX);
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    return 1;
105ad9
 }
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.h b/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.h
105ad9
index ede7065992..0236741ffa 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.h
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.h
105ad9
@@ -87,11 +87,11 @@ Returns 1 upon success, otherwise 0.
105ad9
 */
105ad9
 extern "C" int32_t CryptoNative_GetDsaParameters(
105ad9
     const DSA* dsa,
105ad9
-    BIGNUM** p, int32_t* pLength,
105ad9
-    BIGNUM** q, int32_t* qLength,
105ad9
-    BIGNUM** g, int32_t* gLength,
105ad9
-    BIGNUM** y, int32_t* yLength,
105ad9
-    BIGNUM** x, int32_t* xLength);
105ad9
+    const BIGNUM** p, int32_t* pLength,
105ad9
+    const BIGNUM** q, int32_t* qLength,
105ad9
+    const BIGNUM** g, int32_t* gLength,
105ad9
+    const BIGNUM** y, int32_t* yLength,
105ad9
+    const BIGNUM** x, int32_t* xLength);
105ad9
 
105ad9
 /*
105ad9
 Sets all the parameters on the DSA instance.
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp.cpp
105ad9
index 1fbadce9af..d3157ead17 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp.cpp
105ad9
@@ -10,7 +10,7 @@
105ad9
 
105ad9
 extern "C" EVP_MD_CTX* CryptoNative_EvpMdCtxCreate(const EVP_MD* type)
105ad9
 {
105ad9
-    EVP_MD_CTX* ctx = EVP_MD_CTX_create();
105ad9
+    EVP_MD_CTX* ctx = EVP_MD_CTX_new();
105ad9
     if (ctx == nullptr)
105ad9
     {
105ad9
         // Allocation failed
105ad9
@@ -20,7 +20,7 @@ extern "C" EVP_MD_CTX* CryptoNative_EvpMdCtxCreate(const EVP_MD* type)
105ad9
     int ret = EVP_DigestInit_ex(ctx, type, nullptr);
105ad9
     if (!ret)
105ad9
     {
105ad9
-        EVP_MD_CTX_destroy(ctx);
105ad9
+        EVP_MD_CTX_free(ctx);
105ad9
         return nullptr;
105ad9
     }
105ad9
 
105ad9
@@ -31,7 +31,7 @@ extern "C" void CryptoNative_EvpMdCtxDestroy(EVP_MD_CTX* ctx)
105ad9
 {
105ad9
     if (ctx != nullptr)
105ad9
     {
105ad9
-        EVP_MD_CTX_destroy(ctx);
105ad9
+        EVP_MD_CTX_free(ctx);
105ad9
     }
105ad9
 }
105ad9
 
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.cpp
105ad9
index 1f2e80e114..1dc218cac3 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.cpp
105ad9
@@ -5,7 +5,6 @@
105ad9
 #include "pal_evp_cipher.h"
105ad9
 
105ad9
 #include <assert.h>
105ad9
-#include <memory>
105ad9
 
105ad9
 #define SUCCESS 1
105ad9
 #define KEEP_CURRENT_DIRECTION -1
105ad9
@@ -19,28 +18,34 @@ CryptoNative_EvpCipherCreate(const EVP_CIPHER* type, uint8_t* key, unsigned char
105ad9
 extern "C" EVP_CIPHER_CTX*
105ad9
 CryptoNative_EvpCipherCreate2(const EVP_CIPHER* type, uint8_t* key, int32_t keyLength, int32_t effectiveKeyLength, unsigned char* iv, int32_t enc)
105ad9
 {
105ad9
-    std::unique_ptr<EVP_CIPHER_CTX> ctx(new (std::nothrow) EVP_CIPHER_CTX);
105ad9
+    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
105ad9
     if (ctx == nullptr)
105ad9
     {
105ad9
         // Allocation failed
105ad9
         return nullptr;
105ad9
     }
105ad9
 
105ad9
-    EVP_CIPHER_CTX_init(ctx.get());
105ad9
+    if (!EVP_CIPHER_CTX_reset(ctx))
105ad9
+    {
105ad9
+        EVP_CIPHER_CTX_free(ctx);
105ad9
+        return nullptr;
105ad9
+    }
105ad9
 
105ad9
     // Perform partial initialization so we can set the key lengths
105ad9
-    int ret = EVP_CipherInit_ex(ctx.get(), type, nullptr, nullptr, nullptr, 0);
105ad9
+    int ret = EVP_CipherInit_ex(ctx, type, nullptr, nullptr, nullptr, 0);
105ad9
     if (!ret)
105ad9
     {
105ad9
+        EVP_CIPHER_CTX_free(ctx);
105ad9
         return nullptr;
105ad9
     }
105ad9
 
105ad9
     if (keyLength > 0)
105ad9
     {
105ad9
         // Necessary when the default key size is different than current
105ad9
-        ret = EVP_CIPHER_CTX_set_key_length(ctx.get(), keyLength / 8);
105ad9
+        ret = EVP_CIPHER_CTX_set_key_length(ctx, keyLength / 8);
105ad9
         if (!ret)
105ad9
         {
105ad9
+            EVP_CIPHER_CTX_free(ctx);
105ad9
             return nullptr;
105ad9
         }
105ad9
     }
105ad9
@@ -48,29 +53,30 @@ CryptoNative_EvpCipherCreate2(const EVP_CIPHER* type, uint8_t* key, int32_t keyL
105ad9
     if (effectiveKeyLength > 0)
105ad9
     {
105ad9
         // Necessary for RC2
105ad9
-        ret = EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_SET_RC2_KEY_BITS, effectiveKeyLength, nullptr);
105ad9
+        ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, effectiveKeyLength, nullptr);
105ad9
         if (ret <= 0)
105ad9
         {
105ad9
+            EVP_CIPHER_CTX_free(ctx);
105ad9
             return nullptr;
105ad9
         }
105ad9
     }
105ad9
 
105ad9
     // Perform final initialization specifying the remaining arguments
105ad9
-    ret = EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, key, iv, enc);
105ad9
+    ret = EVP_CipherInit_ex(ctx, nullptr, nullptr, key, iv, enc);
105ad9
     if (!ret)
105ad9
     {
105ad9
+        EVP_CIPHER_CTX_free(ctx);
105ad9
         return nullptr;
105ad9
     }
105ad9
 
105ad9
-    return ctx.release();
105ad9
+    return ctx;
105ad9
 }
105ad9
 
105ad9
 extern "C" void CryptoNative_EvpCipherDestroy(EVP_CIPHER_CTX* ctx)
105ad9
 {
105ad9
     if (ctx != nullptr)
105ad9
     {
105ad9
-        EVP_CIPHER_CTX_cleanup(ctx);
105ad9
-        delete ctx;
105ad9
+        EVP_CIPHER_CTX_free(ctx);
105ad9
     }
105ad9
 }
105ad9
 
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey.cpp
105ad9
index 384030740e..f27e93325f 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey.cpp
105ad9
@@ -24,5 +24,5 @@ extern "C" int32_t CryptoNative_UpRefEvpPkey(EVP_PKEY* pkey)
105ad9
         return 0;
105ad9
     }
105ad9
 
105ad9
-    return CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
105ad9
+    return EVP_PKEY_up_ref(pkey);
105ad9
 }
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_hmac.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_hmac.cpp
105ad9
index 10eef6809c..539dc07683 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_hmac.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_hmac.cpp
105ad9
@@ -7,7 +7,6 @@
105ad9
 #include "pal_hmac.h"
105ad9
 
105ad9
 #include <assert.h>
105ad9
-#include <memory>
105ad9
 
105ad9
 extern "C" HMAC_CTX* CryptoNative_HmacCreate(const uint8_t* key, int32_t keyLen, const EVP_MD* md)
105ad9
 {
105ad9
@@ -15,7 +14,7 @@ extern "C" HMAC_CTX* CryptoNative_HmacCreate(const uint8_t* key, int32_t keyLen,
105ad9
     assert(keyLen >= 0);
105ad9
     assert(md != nullptr);
105ad9
 
105ad9
-    std::unique_ptr<HMAC_CTX> ctx(new (std::nothrow) HMAC_CTX);
105ad9
+    HMAC_CTX* ctx = HMAC_CTX_new();
105ad9
     if (ctx == nullptr)
105ad9
     {
105ad9
         // Allocation failed
105ad9
@@ -28,23 +27,22 @@ extern "C" HMAC_CTX* CryptoNative_HmacCreate(const uint8_t* key, int32_t keyLen,
105ad9
     if (keyLen == 0)
105ad9
         key = &_;
105ad9
 
105ad9
-    HMAC_CTX_init(ctx.get());
105ad9
-    int ret = HMAC_Init_ex(ctx.get(), key, keyLen, md, nullptr);
105ad9
+    int ret = HMAC_Init_ex(ctx, key, keyLen, md, nullptr);
105ad9
 
105ad9
     if (!ret)
105ad9
     {
105ad9
+        free(ctx);
105ad9
         return nullptr;
105ad9
     }
105ad9
 
105ad9
-    return ctx.release();
105ad9
+    return ctx;
105ad9
 }
105ad9
 
105ad9
 extern "C" void CryptoNative_HmacDestroy(HMAC_CTX* ctx)
105ad9
 {
105ad9
     if (ctx != nullptr)
105ad9
     {
105ad9
-        HMAC_CTX_cleanup(ctx);
105ad9
-        delete ctx;
105ad9
+        HMAC_CTX_free(ctx);
105ad9
     }
105ad9
 }
105ad9
 
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_hmac.h b/src/Native/Unix/System.Security.Cryptography.Native/pal_hmac.h
105ad9
index 131e148c00..570d28e70c 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_hmac.h
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_hmac.h
105ad9
@@ -12,7 +12,6 @@
105ad9
 
105ad9
 // Forward declarations - shim API must not depend on knowing layout of these types.
105ad9
 typedef struct hmac_ctx_st HMAC_CTX;
105ad9
-typedef struct env_md_st EVP_MD;
105ad9
 
105ad9
 /**
105ad9
  * Creates and initializes an HMAC_CTX with the given key and EVP_MD.
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.cpp
105ad9
index 9ad896aa72..7fa6585c99 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.cpp
105ad9
@@ -58,8 +58,13 @@ static int HasNoPrivateKey(RSA* rsa)
105ad9
 
105ad9
     // The method has descibed itself as having the private key external to the structure.
105ad9
     // That doesn't mean it's actually present, but we can't tell.
105ad9
-    if (meth->flags & RSA_FLAG_EXT_PKEY)
105ad9
+#pragma clang diagnostic push
105ad9
+#pragma clang diagnostic ignored "-Wcast-qual"
105ad9
+    if (RSA_meth_get_flags((RSA_METHOD*)meth) & RSA_FLAG_EXT_PKEY)
105ad9
+#pragma clang diagnostic pop
105ad9
+    {
105ad9
         return 0;
105ad9
+    }
105ad9
 
105ad9
     // In the event that there's a middle-ground where we report failure when success is expected,
105ad9
     // one could do something like check if the RSA_METHOD intercepts all private key operations:
105ad9
@@ -72,11 +77,27 @@ static int HasNoPrivateKey(RSA* rsa)
105ad9
 
105ad9
     // The module is documented as accepting either d or the full set of CRT parameters (p, q, dp, dq, qInv)
105ad9
     // So if we see d, we're good. Otherwise, if any of the rest are missing, we're public-only.
105ad9
-    if (rsa->d != nullptr)
105ad9
+    const BIGNUM* d;
105ad9
+    RSA_get0_key(rsa, nullptr, nullptr, &d);
105ad9
+
105ad9
+    if (d != nullptr)
105ad9
+    {
105ad9
         return 0;
105ad9
+    }
105ad9
+
105ad9
+    const BIGNUM* p;
105ad9
+    const BIGNUM* q;
105ad9
+    const BIGNUM* dmp1;
105ad9
+    const BIGNUM* dmq1;
105ad9
+    const BIGNUM* iqmp;
105ad9
 
105ad9
-    if (rsa->p == nullptr || rsa->q == nullptr || rsa->dmp1 == nullptr || rsa->dmq1 == nullptr || rsa->iqmp == nullptr)
105ad9
+    RSA_get0_factors(rsa, &p, &q);
105ad9
+    RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
105ad9
+
105ad9
+    if (p == nullptr || q == nullptr || dmp1 == nullptr || dmq1 == nullptr || iqmp == nullptr)
105ad9
+    {
105ad9
         return 1;
105ad9
+    }
105ad9
 
105ad9
     return 0;
105ad9
 }
105ad9
@@ -93,7 +114,7 @@ CryptoNative_RsaPrivateDecrypt(int32_t flen, const uint8_t* from, uint8_t* to, R
105ad9
 {
105ad9
     if (HasNoPrivateKey(rsa))
105ad9
     {
105ad9
-        ERR_PUT_error(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_VALUE_MISSING, __FILE__, __LINE__);
105ad9
+        ERR_PUT_error(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_DECRYPT, RSA_R_VALUE_MISSING, __FILE__, __LINE__);
105ad9
         return -1;
105ad9
     }
105ad9
 
105ad9
@@ -105,7 +126,7 @@ extern "C" int32_t CryptoNative_RsaSignPrimitive(int32_t flen, const uint8_t* fr
105ad9
 {
105ad9
     if (HasNoPrivateKey(rsa))
105ad9
     {
105ad9
-        ERR_PUT_error(ERR_LIB_RSA, RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_VALUE_MISSING, __FILE__, __LINE__);
105ad9
+        ERR_PUT_error(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_ENCRYPT, RSA_R_VALUE_MISSING, __FILE__, __LINE__);
105ad9
         return -1;
105ad9
     }
105ad9
 
105ad9
@@ -169,14 +190,14 @@ CryptoNative_RsaVerify(int32_t type, const uint8_t* m, int32_t mlen, uint8_t* si
105ad9
 }
105ad9
 
105ad9
 extern "C" int32_t CryptoNative_GetRsaParameters(const RSA* rsa,
105ad9
-                                                 BIGNUM** n,
105ad9
-                                                 BIGNUM** e,
105ad9
-                                                 BIGNUM** d,
105ad9
-                                                 BIGNUM** p,
105ad9
-                                                 BIGNUM** dmp1,
105ad9
-                                                 BIGNUM** q,
105ad9
-                                                 BIGNUM** dmq1,
105ad9
-                                                 BIGNUM** iqmp)
105ad9
+                                                 const BIGNUM** n,
105ad9
+                                                 const BIGNUM** e,
105ad9
+                                                 const BIGNUM** d,
105ad9
+                                                 const BIGNUM** p,
105ad9
+                                                 const BIGNUM** dmp1,
105ad9
+                                                 const BIGNUM** q,
105ad9
+                                                 const BIGNUM** dmq1,
105ad9
+                                                 const BIGNUM** iqmp)
105ad9
 {
105ad9
     if (!rsa || !n || !e || !d || !p || !dmp1 || !q || !dmq1 || !iqmp)
105ad9
     {
105ad9
@@ -203,57 +224,40 @@ extern "C" int32_t CryptoNative_GetRsaParameters(const RSA* rsa,
105ad9
         return 0;
105ad9
     }
105ad9
 
105ad9
-    *n = rsa->n;
105ad9
-    *e = rsa->e;
105ad9
-    *d = rsa->d;
105ad9
-    *p = rsa->p;
105ad9
-    *dmp1 = rsa->dmp1;
105ad9
-    *q = rsa->q;
105ad9
-    *dmq1 = rsa->dmq1;
105ad9
-    *iqmp = rsa->iqmp;
105ad9
+    RSA_get0_key(rsa, n, e, d);
105ad9
+    RSA_get0_factors(rsa, p, q);
105ad9
+    RSA_get0_crt_params(rsa, dmp1, dmq1, iqmp);
105ad9
 
105ad9
     return 1;
105ad9
 }
105ad9
 
105ad9
-static int32_t SetRsaParameter(BIGNUM** rsaFieldAddress, uint8_t* buffer, int32_t bufferLength)
105ad9
+static BIGNUM* MakeBignum(uint8_t* buffer, int32_t bufferLength)
105ad9
 {
105ad9
-    assert(rsaFieldAddress != nullptr);
105ad9
-    if (rsaFieldAddress)
105ad9
+    if (buffer && bufferLength)
105ad9
     {
105ad9
-        if (!buffer || !bufferLength)
105ad9
-        {
105ad9
-            *rsaFieldAddress = nullptr;
105ad9
-            return 1;
105ad9
-        }
105ad9
-        else
105ad9
-        {
105ad9
-            BIGNUM* bigNum = BN_bin2bn(buffer, bufferLength, nullptr);
105ad9
-            *rsaFieldAddress = bigNum;
105ad9
-
105ad9
-            return bigNum != nullptr;
105ad9
-        }
105ad9
+        return BN_bin2bn(buffer, bufferLength, nullptr);
105ad9
     }
105ad9
 
105ad9
-    return 0;
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 extern "C" int32_t CryptoNative_SetRsaParameters(RSA* rsa,
105ad9
-                                              uint8_t* n,
105ad9
-                                              int32_t nLength,
105ad9
-                                              uint8_t* e,
105ad9
-                                              int32_t eLength,
105ad9
-                                              uint8_t* d,
105ad9
-                                              int32_t dLength,
105ad9
-                                              uint8_t* p,
105ad9
-                                              int32_t pLength,
105ad9
-                                              uint8_t* dmp1,
105ad9
-                                              int32_t dmp1Length,
105ad9
-                                              uint8_t* q,
105ad9
-                                              int32_t qLength,
105ad9
-                                              uint8_t* dmq1,
105ad9
-                                              int32_t dmq1Length,
105ad9
-                                              uint8_t* iqmp,
105ad9
-                                              int32_t iqmpLength)
105ad9
+                                                 uint8_t* n,
105ad9
+                                                 int32_t nLength,
105ad9
+                                                 uint8_t* e,
105ad9
+                                                 int32_t eLength,
105ad9
+                                                 uint8_t* d,
105ad9
+                                                 int32_t dLength,
105ad9
+                                                 uint8_t* p,
105ad9
+                                                 int32_t pLength,
105ad9
+                                                 uint8_t* dmp1,
105ad9
+                                                 int32_t dmp1Length,
105ad9
+                                                 uint8_t* q,
105ad9
+                                                 int32_t qLength,
105ad9
+                                                 uint8_t* dmq1,
105ad9
+                                                 int32_t dmq1Length,
105ad9
+                                                 uint8_t* iqmp,
105ad9
+                                                 int32_t iqmpLength)
105ad9
 {
105ad9
     if (!rsa)
105ad9
     {
105ad9
@@ -261,13 +265,43 @@ extern "C" int32_t CryptoNative_SetRsaParameters(RSA* rsa,
105ad9
         return 0;
105ad9
     }
105ad9
 
105ad9
-    return 
105ad9
-        SetRsaParameter(&rsa->n, n, nLength) &&
105ad9
-        SetRsaParameter(&rsa->e, e, eLength) &&
105ad9
-        SetRsaParameter(&rsa->d, d, dLength) &&
105ad9
-        SetRsaParameter(&rsa->p, p, pLength) &&
105ad9
-        SetRsaParameter(&rsa->dmp1, dmp1, dmp1Length) &&
105ad9
-        SetRsaParameter(&rsa->q, q, qLength) &&
105ad9
-        SetRsaParameter(&rsa->dmq1, dmq1, dmq1Length) &&
105ad9
-        SetRsaParameter(&rsa->iqmp, iqmp, iqmpLength);
105ad9
+    BIGNUM* bnN = MakeBignum(n, nLength);
105ad9
+    BIGNUM* bnE = MakeBignum(e, eLength);
105ad9
+    BIGNUM* bnD = MakeBignum(d, dLength);
105ad9
+
105ad9
+    if (!RSA_set0_key(rsa, bnN, bnE, bnD))
105ad9
+    {
105ad9
+        // BN_free handles NULL input
105ad9
+        BN_free(bnN);
105ad9
+        BN_free(bnE);
105ad9
+        BN_free(bnD);
105ad9
+        return 0;
105ad9
+    }
105ad9
+
105ad9
+    if (bnD != nullptr)
105ad9
+    {
105ad9
+        BIGNUM* bnP = MakeBignum(p, pLength);
105ad9
+        BIGNUM* bnQ = MakeBignum(q, qLength);
105ad9
+
105ad9
+        if (!RSA_set0_factors(rsa, bnP, bnQ))
105ad9
+        {
105ad9
+            BN_free(bnP);
105ad9
+            BN_free(bnQ);
105ad9
+            return 0;
105ad9
+        }
105ad9
+
105ad9
+        BIGNUM* bnDmp1 = MakeBignum(dmp1, dmp1Length);
105ad9
+        BIGNUM* bnDmq1 = MakeBignum(dmq1, dmq1Length);
105ad9
+        BIGNUM* bnIqmp = MakeBignum(iqmp, iqmpLength);
105ad9
+
105ad9
+        if (!RSA_set0_crt_params(rsa, bnDmp1, bnDmq1, bnIqmp))
105ad9
+        {
105ad9
+            BN_free(bnDmp1);
105ad9
+            BN_free(bnDmq1);
105ad9
+            BN_free(bnIqmp);
105ad9
+            return 0;
105ad9
+        }
105ad9
+    }
105ad9
+
105ad9
+    return 1;
105ad9
 }
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h
105ad9
index c4a2737ced..b075911c47 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h
105ad9
@@ -114,14 +114,14 @@ Gets all the parameters from the RSA instance.
105ad9
 Returns 1 upon success, otherwise 0.
105ad9
 */
105ad9
 extern "C" int32_t CryptoNative_GetRsaParameters(const RSA* rsa,
105ad9
-                                                 BIGNUM** n,
105ad9
-                                                 BIGNUM** e,
105ad9
-                                                 BIGNUM** d,
105ad9
-                                                 BIGNUM** p,
105ad9
-                                                 BIGNUM** dmp1,
105ad9
-                                                 BIGNUM** q,
105ad9
-                                                 BIGNUM** dmq1,
105ad9
-                                                 BIGNUM** iqmp);
105ad9
+                                                const BIGNUM** n,
105ad9
+                                                const BIGNUM** e,
105ad9
+                                                const BIGNUM** d,
105ad9
+                                                const BIGNUM** p,
105ad9
+                                                const BIGNUM** dmp1,
105ad9
+                                                const BIGNUM** q,
105ad9
+                                                const BIGNUM** dmq1,
105ad9
+                                                const BIGNUM** iqmp);
105ad9
 
105ad9
 /*
105ad9
 Sets all the parameters on the RSA instance.
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.cpp
105ad9
index 0d87a8a5f1..b0ebba0ce1 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.cpp
105ad9
@@ -3,6 +3,7 @@
105ad9
 // See the LICENSE file in the project root for more information.
105ad9
 
105ad9
 #include "pal_ssl.h"
105ad9
+#include "openssl.h"
105ad9
 
105ad9
 #include <assert.h>
105ad9
 #include <string.h>
105ad9
@@ -16,16 +17,34 @@ static_assert(PAL_SSL_ERROR_ZERO_RETURN == SSL_ERROR_ZERO_RETURN, "");
105ad9
 
105ad9
 extern "C" int32_t CryptoNative_EnsureOpenSslInitialized();
105ad9
 
105ad9
-extern "C" void CryptoNative_EnsureLibSslInitialized()
105ad9
+#ifdef NEED_OPENSSL_1_0
105ad9
+static void EnsureLibSsl10Initialized()
105ad9
 {
105ad9
-    CryptoNative_EnsureOpenSslInitialized();
105ad9
     SSL_library_init();
105ad9
     SSL_load_error_strings();
105ad9
 }
105ad9
+#endif
105ad9
+
105ad9
+extern "C" void CryptoNative_EnsureLibSslInitialized()
105ad9
+{
105ad9
+    CryptoNative_EnsureOpenSslInitialized();
105ad9
+
105ad9
+    // If portable, call the 1.0 initializer when needed.
105ad9
+    // If 1.0, call it statically.
105ad9
+    // In 1.1 no action is required, since EnsureOpenSslInitialized does both libraries.
105ad9
+#ifdef FEATURE_DISTRO_AGNOSTIC_SSL
105ad9
+    if (API_EXISTS(SSL_state))
105ad9
+    {
105ad9
+        EnsureLibSsl10Initialized();
105ad9
+    }
105ad9
+#elif OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
105ad9
+    EnsureLibSsl10Initialized();
105ad9
+#endif
105ad9
+}
105ad9
 
105ad9
 extern "C" const SSL_METHOD* CryptoNative_SslV2_3Method()
105ad9
 {
105ad9
-    const SSL_METHOD* method = SSLv23_method();
105ad9
+    const SSL_METHOD* method = TLS_method();
105ad9
     assert(method != nullptr);
105ad9
     return method;
105ad9
 }
105ad9
@@ -51,19 +70,39 @@ Returns 1 on success, 0 on failure.
105ad9
 */
105ad9
 static long TrySetECDHNamedCurve(SSL_CTX* ctx)
105ad9
 {
105ad9
-	long result = 0;
105ad9
-#ifdef SSL_CTX_set_ecdh_auto
105ad9
-	result = SSL_CTX_set_ecdh_auto(ctx, 1);
105ad9
-#else
105ad9
-	EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
105ad9
-	if (ecdh != nullptr)
105ad9
-	{
105ad9
-		result = SSL_CTX_set_tmp_ecdh(ctx, ecdh);
105ad9
-		EC_KEY_free(ecdh);
105ad9
-	}
105ad9
+#ifdef NEED_OPENSSL_1_0
105ad9
+    long result = 0;
105ad9
+    unsigned long version = OpenSSL_version_num();
105ad9
+
105ad9
+    if (version >= OPENSSL_VERSION_1_1_0_RTM)
105ad9
+    {
105ad9
+        // OpenSSL 1.1+ automatically set up ECDH
105ad9
+        result = 1;
105ad9
+    }
105ad9
+    else if (version >= OPENSSL_VERSION_1_0_2_RTM)
105ad9
+    {
105ad9
+#ifndef SSL_CTRL_SET_ECDH_AUTO
105ad9
+#define SSL_CTRL_SET_ECDH_AUTO 94
105ad9
 #endif
105ad9
+        // Expanded form of SSL_CTX_set_ecdh_auto(ctx, 1)
105ad9
+        result = SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, 1, nullptr);
105ad9
+    }
105ad9
+    else
105ad9
+    {
105ad9
+        EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
105ad9
+
105ad9
+        if (ecdh != nullptr)
105ad9
+        {
105ad9
+            result = SSL_CTX_set_tmp_ecdh(ctx, ecdh);
105ad9
+            EC_KEY_free(ecdh);
105ad9
+        }
105ad9
+    }
105ad9
 
105ad9
 	return result;
105ad9
+#else
105ad9
+    (void)ctx;
105ad9
+    return 1;
105ad9
+#endif
105ad9
 }
105ad9
 
105ad9
 extern "C" void CryptoNative_SetProtocolOptions(SSL_CTX* ctx, SslProtocols protocols)
105ad9
@@ -80,7 +119,7 @@ extern "C" void CryptoNative_SetProtocolOptions(SSL_CTX* ctx, SslProtocols proto
105ad9
         return;
105ad9
     }
105ad9
 
105ad9
-    long protocolOptions = 0;
105ad9
+    unsigned long protocolOptions = 0;
105ad9
 
105ad9
     if ((protocols & PAL_SSL_SSL2) != PAL_SSL_SSL2)
105ad9
     {
105ad9
@@ -94,20 +133,26 @@ extern "C" void CryptoNative_SetProtocolOptions(SSL_CTX* ctx, SslProtocols proto
105ad9
     {
105ad9
         protocolOptions |= SSL_OP_NO_TLSv1;
105ad9
     }
105ad9
-#if HAVE_TLS_V1_1
105ad9
     if ((protocols & PAL_SSL_TLS11) != PAL_SSL_TLS11)
105ad9
     {
105ad9
         protocolOptions |= SSL_OP_NO_TLSv1_1;
105ad9
     }
105ad9
-#endif
105ad9
-#if HAVE_TLS_V1_2
105ad9
     if ((protocols & PAL_SSL_TLS12) != PAL_SSL_TLS12)
105ad9
     {
105ad9
         protocolOptions |= SSL_OP_NO_TLSv1_2;
105ad9
     }
105ad9
+
105ad9
+    // protocol options were specified, and there's no handler yet for TLS 1.3.
105ad9
+#ifndef SSL_OP_NO_TLSv1_3
105ad9
+#define SSL_OP_NO_TLSv1_3 0x20000000U
105ad9
 #endif
105ad9
+    protocolOptions |= SSL_OP_NO_TLSv1_3;
105ad9
 
105ad9
+    // OpenSSL 1.0 calls this long, OpenSSL 1.1 calls it unsigned long.
105ad9
+#pragma clang diagnostic push
105ad9
+#pragma clang diagnostic ignored "-Wsign-conversion"
105ad9
     SSL_CTX_set_options(ctx, protocolOptions);
105ad9
+#pragma clang diagnostic pop
105ad9
 }
105ad9
 
105ad9
 extern "C" SSL* CryptoNative_SslCreate(SSL_CTX* ctx)
105ad9
@@ -254,54 +299,54 @@ static ExchangeAlgorithmType MapExchangeAlgorithmType(const char* keyExchange, s
105ad9
 
105ad9
 static void GetHashAlgorithmTypeAndSize(const char* mac,
105ad9
                                         size_t macLength,
105ad9
-                                        HashAlgorithmType& dataHashAlg,
105ad9
-                                        DataHashSize& hashKeySize)
105ad9
+                                        HashAlgorithmType* dataHashAlg,
105ad9
+                                        DataHashSize* hashKeySize)
105ad9
 {
105ad9
     if (StringSpanEquals(mac, "MD5", macLength))
105ad9
     {
105ad9
-        dataHashAlg = HashAlgorithmType::Md5;
105ad9
-        hashKeySize = DataHashSize::MD5_HashKeySize;
105ad9
+        *dataHashAlg = HashAlgorithmType::Md5;
105ad9
+        *hashKeySize = DataHashSize::MD5_HashKeySize;
105ad9
         return;
105ad9
     }
105ad9
     if (StringSpanEquals(mac, "SHA1", macLength))
105ad9
     {
105ad9
-        dataHashAlg = HashAlgorithmType::Sha1;
105ad9
-        hashKeySize = DataHashSize::SHA1_HashKeySize;
105ad9
+        *dataHashAlg = HashAlgorithmType::Sha1;
105ad9
+        *hashKeySize = DataHashSize::SHA1_HashKeySize;
105ad9
         return;
105ad9
     }
105ad9
     if (StringSpanEquals(mac, "GOST94", macLength))
105ad9
     {
105ad9
-        dataHashAlg = HashAlgorithmType::SSL_GOST94;
105ad9
-        hashKeySize = DataHashSize::GOST_HashKeySize;
105ad9
+        *dataHashAlg = HashAlgorithmType::SSL_GOST94;
105ad9
+        *hashKeySize = DataHashSize::GOST_HashKeySize;
105ad9
         return;
105ad9
     }
105ad9
     if (StringSpanEquals(mac, "GOST89", macLength))
105ad9
     {
105ad9
-        dataHashAlg = HashAlgorithmType::SSL_GOST89;
105ad9
-        hashKeySize = DataHashSize::GOST_HashKeySize;
105ad9
+        *dataHashAlg = HashAlgorithmType::SSL_GOST89;
105ad9
+        *hashKeySize = DataHashSize::GOST_HashKeySize;
105ad9
         return;
105ad9
     }
105ad9
     if (StringSpanEquals(mac, "SHA256", macLength))
105ad9
     {
105ad9
-        dataHashAlg = HashAlgorithmType::SSL_SHA256;
105ad9
-        hashKeySize = DataHashSize::SHA256_HashKeySize;
105ad9
+        *dataHashAlg = HashAlgorithmType::SSL_SHA256;
105ad9
+        *hashKeySize = DataHashSize::SHA256_HashKeySize;
105ad9
         return;
105ad9
     }
105ad9
     if (StringSpanEquals(mac, "SHA384", macLength))
105ad9
     {
105ad9
-        dataHashAlg = HashAlgorithmType::SSL_SHA384;
105ad9
-        hashKeySize = DataHashSize::SHA384_HashKeySize;
105ad9
+        *dataHashAlg = HashAlgorithmType::SSL_SHA384;
105ad9
+        *hashKeySize = DataHashSize::SHA384_HashKeySize;
105ad9
         return;
105ad9
     }
105ad9
     if (StringSpanEquals(mac, "AEAD", macLength))
105ad9
     {
105ad9
-        dataHashAlg = HashAlgorithmType::SSL_AEAD;
105ad9
-        hashKeySize = DataHashSize::Default;
105ad9
+        *dataHashAlg = HashAlgorithmType::SSL_AEAD;
105ad9
+        *hashKeySize = DataHashSize::Default;
105ad9
         return;
105ad9
     }
105ad9
 
105ad9
-    dataHashAlg = HashAlgorithmType::None;
105ad9
-    hashKeySize = DataHashSize::Default;
105ad9
+    *dataHashAlg = HashAlgorithmType::None;
105ad9
+    *hashKeySize = DataHashSize::Default;
105ad9
 }
105ad9
 
105ad9
 /*
105ad9
@@ -340,10 +385,10 @@ Parses the Kx, Enc, and Mac values out of the SSL_CIPHER_description and
105ad9
 maps the values to the corresponding .NET enum value.
105ad9
 */
105ad9
 static bool GetSslConnectionInfoFromDescription(const SSL_CIPHER* cipher,
105ad9
-                                                CipherAlgorithmType& dataCipherAlg,
105ad9
-                                                ExchangeAlgorithmType& keyExchangeAlg,
105ad9
-                                                HashAlgorithmType& dataHashAlg,
105ad9
-                                                DataHashSize& hashKeySize)
105ad9
+                                                CipherAlgorithmType* dataCipherAlg,
105ad9
+                                                ExchangeAlgorithmType* keyExchangeAlg,
105ad9
+                                                HashAlgorithmType* dataHashAlg,
105ad9
+                                                DataHashSize* hashKeySize)
105ad9
 {
105ad9
     const int descriptionLength = 256;
105ad9
     char description[descriptionLength] = {};
105ad9
@@ -370,8 +415,8 @@ static bool GetSslConnectionInfoFromDescription(const SSL_CIPHER* cipher,
105ad9
         return false;
105ad9
     }
105ad9
 
105ad9
-    keyExchangeAlg = MapExchangeAlgorithmType(keyExchange, keyExchangeLength);
105ad9
-    dataCipherAlg = MapCipherAlgorithmType(encryption, encryptionLength);
105ad9
+    *keyExchangeAlg = MapExchangeAlgorithmType(keyExchange, keyExchangeLength);
105ad9
+    *dataCipherAlg = MapCipherAlgorithmType(encryption, encryptionLength);
105ad9
     GetHashAlgorithmTypeAndSize(mac, macLength, dataHashAlg, hashKeySize);
105ad9
     return true;
105ad9
 }
105ad9
@@ -396,8 +441,9 @@ extern "C" int32_t CryptoNative_GetSslConnectionInfo(SSL* ssl,
105ad9
         goto err;
105ad9
     }
105ad9
 
105ad9
-    *dataKeySize = cipher->alg_bits;
105ad9
-    if (GetSslConnectionInfoFromDescription(cipher, *dataCipherAlg, *keyExchangeAlg, *dataHashAlg, *hashKeySize))
105ad9
+    SSL_CIPHER_get_bits(cipher, dataKeySize);
105ad9
+
105ad9
+    if (GetSslConnectionInfoFromDescription(cipher, dataCipherAlg, keyExchangeAlg, dataHashAlg, hashKeySize))
105ad9
     {
105ad9
         return 1;
105ad9
     }
105ad9
@@ -453,7 +499,7 @@ extern "C" int32_t CryptoNative_SslDoHandshake(SSL* ssl)
105ad9
 
105ad9
 extern "C" int32_t CryptoNative_IsSslStateOK(SSL* ssl)
105ad9
 {
105ad9
-    return SSL_state(ssl) == SSL_ST_OK;
105ad9
+    return SSL_is_init_finished(ssl);
105ad9
 }
105ad9
 
105ad9
 extern "C" X509* CryptoNative_SslGetPeerCertificate(SSL* ssl)
105ad9
@@ -517,6 +563,8 @@ CryptoNative_SslCtxSetCertVerifyCallback(SSL_CTX* ctx, SslCtxSetCertVerifyCallba
105ad9
 extern "C" int32_t CryptoNative_SetEncryptionPolicy(SSL_CTX* ctx, EncryptionPolicy policy)
105ad9
 {
105ad9
     const char* cipherString = nullptr;
105ad9
+    bool clearSecLevel = false;
105ad9
+
105ad9
     switch (policy)
105ad9
     {
105ad9
         case EncryptionPolicy::RequireEncryption:
105ad9
@@ -525,15 +573,23 @@ extern "C" int32_t CryptoNative_SetEncryptionPolicy(SSL_CTX* ctx, EncryptionPoli
105ad9
 
105ad9
         case EncryptionPolicy::AllowNoEncryption:
105ad9
             cipherString = SSL_TXT_AllIncludingNull;
105ad9
+            clearSecLevel = true;
105ad9
             break;
105ad9
 
105ad9
         case EncryptionPolicy::NoEncryption:
105ad9
             cipherString = SSL_TXT_eNULL;
105ad9
+            clearSecLevel = true;
105ad9
             break;
105ad9
     }
105ad9
 
105ad9
     assert(cipherString != nullptr);
105ad9
 
105ad9
+    if (clearSecLevel)
105ad9
+    {
105ad9
+        // No minimum security policy, same as OpenSSL 1.0
105ad9
+        SSL_CTX_set_security_level(ctx, 0);
105ad9
+    }
105ad9
+
105ad9
     return SSL_CTX_set_cipher_list(ctx, cipherString);
105ad9
 }
105ad9
 
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.cpp
105ad9
index 3118c9aa2c..b51bb77575 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.cpp
105ad9
@@ -230,12 +230,22 @@ extern "C" X509Stack* CryptoNative_X509StoreCtxGetChain(X509_STORE_CTX* ctx)
105ad9
 
105ad9
 extern "C" X509Stack* CryptoNative_X509StoreCtxGetSharedUntrusted(X509_STORE_CTX* ctx)
105ad9
 {
105ad9
-    return ctx ? ctx->untrusted : nullptr;
105ad9
+    if (ctx)
105ad9
+    {
105ad9
+        return X509_STORE_CTX_get0_untrusted(ctx);
105ad9
+    }
105ad9
+
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 extern "C" X509* CryptoNative_X509StoreCtxGetTargetCert(X509_STORE_CTX* ctx)
105ad9
 {
105ad9
-    return ctx ? ctx->cert : nullptr;
105ad9
+    if (ctx)
105ad9
+    {
105ad9
+        return X509_STORE_CTX_get0_cert(ctx);
105ad9
+    }
105ad9
+
105ad9
+    return nullptr;
105ad9
 }
105ad9
 
105ad9
 extern "C" X509VerifyStatusCode CryptoNative_X509StoreCtxGetError(X509_STORE_CTX* ctx)
105ad9
@@ -302,7 +312,7 @@ extern "C" X509* CryptoNative_X509UpRef(X509* x509)
105ad9
 {
105ad9
     if (x509 != nullptr)
105ad9
     {
105ad9
-        CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
105ad9
+        X509_up_ref(x509);
105ad9
     }
105ad9
 
105ad9
     return x509;
105ad9
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509_root.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509_root.cpp
105ad9
index 2132a81836..cc11e654dd 100644
105ad9
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509_root.cpp
105ad9
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509_root.cpp
105ad9
@@ -2,6 +2,7 @@
105ad9
 // The .NET Foundation licenses this file to you under the MIT license.
105ad9
 // See the LICENSE file in the project root for more information.
105ad9
 
105ad9
+#include "pal_types.h"
105ad9
 #include "pal_x509_root.h"
105ad9
 
105ad9
 #include <assert.h>
105ad9
diff --git a/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs b/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs
105ad9
index 47912ff085..8f870feae3 100644
105ad9
--- a/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs
105ad9
+++ b/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs
105ad9
@@ -3,6 +3,7 @@
105ad9
 // See the LICENSE file in the project root for more information.
105ad9
 
105ad9
 using System;
105ad9
+using System.Buffers;
105ad9
 using System.Diagnostics;
105ad9
 using System.Security.Cryptography;
105ad9
 using Microsoft.Win32.SafeHandles;
105ad9
@@ -49,6 +50,24 @@ namespace Internal.Cryptography
105ad9
             Debug.Assert(outputOffset >= 0);
105ad9
             Debug.Assert(output.Length - outputOffset >= count);
105ad9
 
105ad9
+            // OpenSSL 1.1 does not allow partial overlap.
105ad9
+            if (input == output && inputOffset != outputOffset)
105ad9
+            {
105ad9
+                byte[] tmp = ArrayPool<byte>.Shared.Rent(count);
105ad9
+
105ad9
+                try
105ad9
+                {
105ad9
+                    int written = CipherUpdate(input, inputOffset, count, tmp, 0);
105ad9
+                    Buffer.BlockCopy(tmp, 0, output, outputOffset, written);
105ad9
+                    return written;
105ad9
+                }
105ad9
+                finally
105ad9
+                {
105ad9
+                    CryptographicOperations.ZeroMemory(tmp.AsSpan(0, count));
105ad9
+                    ArrayPool<byte>.Shared.Return(tmp);
105ad9
+                }
105ad9
+            }
105ad9
+
105ad9
             return CipherUpdate(input, inputOffset, count, output, outputOffset);
105ad9
         }
105ad9
 
105ad9
-- 
105ad9
2.20.1
105ad9