Blame SOURCES/corefx-openssl-0004-Support-compiling-against-OpenSSL-3-headers.patch

debe55
From 49dc6e515d9ec0db1841e5d2d86f52916d35f667 Mon Sep 17 00:00:00 2001
debe55
From: Jeremy Barton <jbarton@microsoft.com>
debe55
Date: Mon, 5 Apr 2021 11:07:29 -0700
debe55
Subject: [PATCH 04/11] Support compiling against OpenSSL 3 headers
debe55
debe55
Building against OpenSSL 3's headers fails to compile, as X509_V_ERR_INVALID_CA has changed from 24 to 79, tripping a static assert.
debe55
debe55
* Rename the managed X509VerifyStatusCode enum to X509VerifyStatusCodeUniversal, to represent the name/values that are present in all current versions of OpenSSL (1.0.2, 1.1.1, 3.0 alpha)
debe55
* Add new enums for the name/value pairs that are unique to a given version
debe55
* Add an X509VerifyStatusCode struct that just wraps the int and is a faux-union of the various enums
debe55
* Use the OpenSSL runtime version to determine which mapping table to use (after the Universal table fails)
debe55
debe55
In addition to that, there are a few const-related changes in the 3.0 headers that are addressed.
debe55
debe55
`corefx/src/Native$ ./build_native.sh -portablebuild=false` on systems where find_package(OpenSSL) maps to 3.0 succeeds with these changes.  Portable builds still fail.
debe55
debe55
Not all tests pass with OpenSSL 3.0 (alpha 13) with these changes, but it does reduce to three categories of error:
debe55
debe55
* ICryptoTransform reset/reuse tests fail (OpenSSL regression is open)
debe55
* DSA small key generation fails (OpenSSL has fixed the regression for the next alpha/beta release)
debe55
* Some OuterLoop X.509 tests are failing as positively revoked when they expect ambiguous revocation states (investigation pending)
debe55
---
debe55
 .../Interop.OCSP.cs                           |   4 +-
debe55
 .../Interop.X509.cs                           | 109 +++++++++++-
debe55
 .../pal_evp_pkey_rsa.c                        |   8 +-
debe55
 .../pal_x509.c                                |  24 ++-
debe55
 .../pal_x509.h                                |  29 +++-
debe55
 .../Pal.Unix/OpenSslX509ChainProcessor.cs     | 155 ++++++++++++------
debe55
 6 files changed, 266 insertions(+), 63 deletions(-)
debe55
debe55
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs
debe55
index bcf9e2af48..8be162e284 100644
debe55
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs
debe55
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs
debe55
@@ -43,7 +43,7 @@ internal static X509VerifyStatusCode X509ChainGetCachedOcspStatus(SafeX509StoreC
debe55
         {
debe55
             X509VerifyStatusCode response = CryptoNative_X509ChainGetCachedOcspStatus(ctx, cachePath);
debe55
 
debe55
-            if (response < 0)
debe55
+            if (response.Code < 0)
debe55
             {
debe55
                 Debug.Fail($"Unexpected response from X509ChainGetCachedOcspSuccess: {response}");
debe55
                 throw new CryptographicException();
debe55
@@ -67,7 +67,7 @@ internal static X509VerifyStatusCode X509ChainGetCachedOcspStatus(SafeX509StoreC
debe55
         {
debe55
             X509VerifyStatusCode response = CryptoNative_X509ChainVerifyOcsp(ctx, req, resp, cachePath);
debe55
 
debe55
-            if (response < 0)
debe55
+            if (response.Code < 0)
debe55
             {
debe55
                 Debug.Fail($"Unexpected response from X509ChainGetCachedOcspSuccess: {response}");
debe55
                 throw new CryptographicException();
debe55
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.X509.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.X509.cs
debe55
index 8ffc70af6a..99747c276b 100644
debe55
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.X509.cs
debe55
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.X509.cs
debe55
@@ -216,13 +216,13 @@ internal static bool X509StoreCtxRebuildChain(SafeX509StoreCtxHandle ctx)
debe55
         [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509StoreCtxSetVerifyCallback")]
debe55
         internal static extern void X509StoreCtxSetVerifyCallback(SafeX509StoreCtxHandle ctx, X509StoreVerifyCallback callback);
debe55
 
debe55
-        internal static string GetX509VerifyCertErrorString(X509VerifyStatusCode n)
debe55
+        internal static string GetX509VerifyCertErrorString(int n)
debe55
         {
debe55
             return Marshal.PtrToStringAnsi(X509VerifyCertErrorString(n));
debe55
         }
debe55
 
debe55
         [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509VerifyCertErrorString")]
debe55
-        private static extern IntPtr X509VerifyCertErrorString(X509VerifyStatusCode n);
debe55
+        private static extern IntPtr X509VerifyCertErrorString(int n);
debe55
 
debe55
         [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509CrlDestroy")]
debe55
         internal static extern void X509CrlDestroy(IntPtr a);
debe55
@@ -239,11 +239,13 @@ internal static string GetX509VerifyCertErrorString(X509VerifyStatusCode n)
debe55
         [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EncodeX509SubjectPublicKeyInfo")]
debe55
         internal static extern int EncodeX509SubjectPublicKeyInfo(SafeX509Handle x509, byte[] buf);
debe55
 
debe55
-        internal enum X509VerifyStatusCode : int
debe55
+        internal enum X509VerifyStatusCodeUniversal
debe55
         {
debe55
             X509_V_OK = 0,
debe55
+            X509_V_ERR_UNSPECIFIED = 1,
debe55
             X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 2,
debe55
             X509_V_ERR_UNABLE_TO_GET_CRL = 3,
debe55
+            X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE = 4,
debe55
             X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE = 5,
debe55
             X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY = 6,
debe55
             X509_V_ERR_CERT_SIGNATURE_FAILURE = 7,
debe55
@@ -263,18 +265,25 @@ internal enum X509VerifyStatusCode : int
debe55
             X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 21,
debe55
             X509_V_ERR_CERT_CHAIN_TOO_LONG = 22,
debe55
             X509_V_ERR_CERT_REVOKED = 23,
debe55
-            X509_V_ERR_INVALID_CA = 24,
debe55
+
debe55
+            // Code 24 varies.
debe55
+
debe55
             X509_V_ERR_PATH_LENGTH_EXCEEDED = 25,
debe55
             X509_V_ERR_INVALID_PURPOSE = 26,
debe55
             X509_V_ERR_CERT_UNTRUSTED = 27,
debe55
             X509_V_ERR_CERT_REJECTED = 28,
debe55
+            X509_V_ERR_SUBJECT_ISSUER_MISMATCH = 29,
debe55
+            X509_V_ERR_AKID_SKID_MISMATCH = 30,
debe55
+            X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH = 31,
debe55
             X509_V_ERR_KEYUSAGE_NO_CERTSIGN = 32,
debe55
             X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER = 33,
debe55
             X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION = 34,
debe55
             X509_V_ERR_KEYUSAGE_NO_CRL_SIGN = 35,
debe55
             X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION = 36,
debe55
             X509_V_ERR_INVALID_NON_CA = 37,
debe55
+            X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED = 38,
debe55
             X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE = 39,
debe55
+            X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED = 40,
debe55
             X509_V_ERR_INVALID_EXTENSION = 41,
debe55
             X509_V_ERR_INVALID_POLICY_EXTENSION = 42,
debe55
             X509_V_ERR_NO_EXPLICIT_POLICY = 43,
debe55
@@ -289,7 +298,6 @@ internal enum X509VerifyStatusCode : int
debe55
             X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX = 52,
debe55
             X509_V_ERR_UNSUPPORTED_NAME_SYNTAX = 53,
debe55
             X509_V_ERR_CRL_PATH_VALIDATION_ERROR = 54,
debe55
-            X509_V_ERR_PATH_LOOP = 55,
debe55
             X509_V_ERR_SUITE_B_INVALID_VERSION = 56,
debe55
             X509_V_ERR_SUITE_B_INVALID_ALGORITHM = 57,
debe55
             X509_V_ERR_SUITE_B_INVALID_CURVE = 58,
debe55
@@ -299,6 +307,41 @@ internal enum X509VerifyStatusCode : int
debe55
             X509_V_ERR_HOSTNAME_MISMATCH = 62,
debe55
             X509_V_ERR_EMAIL_MISMATCH = 63,
debe55
             X509_V_ERR_IP_ADDRESS_MISMATCH = 64,
debe55
+        }
debe55
+        internal enum X509VerifyStatusCode102
debe55
+        {
debe55
+            X509_V_ERR_INVALID_CA = 24,
debe55
+
debe55
+            X509_V_ERR_INVALID_CALL = 65,
debe55
+            X509_V_ERR_STORE_LOOKUP = 66,
debe55
+            X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION = 67,
debe55
+        }
debe55
+
debe55
+        internal enum X509VerifyStatusCode111
debe55
+        {
debe55
+            X509_V_ERR_INVALID_CA = 24,
debe55
+
debe55
+            X509_V_ERR_DANE_NO_MATCH = 65,
debe55
+            X509_V_ERR_EE_KEY_TOO_SMALL = 66,
debe55
+            X509_V_ERR_CA_KEY_TOO_SMALL = 67,
debe55
+            X509_V_ERR_CA_MD_TOO_WEAK = 68,
debe55
+            X509_V_ERR_INVALID_CALL = 69,
debe55
+            X509_V_ERR_STORE_LOOKUP = 70,
debe55
+            X509_V_ERR_NO_VALID_SCTS = 71,
debe55
+            X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION = 72,
debe55
+            X509_V_ERR_OCSP_VERIFY_NEEDED = 73,
debe55
+            X509_V_ERR_OCSP_VERIFY_FAILED = 74,
debe55
+            X509_V_ERR_OCSP_CERT_UNKNOWN = 75,
debe55
+            X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH = 76,
debe55
+            X509_V_ERR_NO_ISSUER_PUBLIC_KEY = 77,
debe55
+            X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM = 78,
debe55
+            X509_V_ERR_EC_KEY_EXPLICIT_PARAMS = 79,
debe55
+        }
debe55
+
debe55
+        internal enum X509VerifyStatusCode30
debe55
+        {
debe55
+            X509_V_ERR_NO_ISSUER_PUBLIC_KEY = 24,
debe55
+
debe55
             X509_V_ERR_DANE_NO_MATCH = 65,
debe55
             X509_V_ERR_EE_KEY_TOO_SMALL = 66,
debe55
             X509_V_ERR_CA_KEY_TOO_SMALL = 67,
debe55
@@ -310,6 +353,62 @@ internal enum X509VerifyStatusCode : int
debe55
             X509_V_ERR_OCSP_VERIFY_NEEDED = 73,
debe55
             X509_V_ERR_OCSP_VERIFY_FAILED = 74,
debe55
             X509_V_ERR_OCSP_CERT_UNKNOWN = 75,
debe55
+            X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM = 76,
debe55
+            X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH = 77,
debe55
+            X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY = 78,
debe55
+            X509_V_ERR_INVALID_CA = 79,
debe55
+            X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA = 80,
debe55
+            X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN = 81,
debe55
+            X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA = 82,
debe55
+            X509_V_ERR_ISSUER_NAME_EMPTY = 83,
debe55
+            X509_V_ERR_SUBJECT_NAME_EMPTY = 84,
debe55
+            X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER = 85,
debe55
+            X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER = 86,
debe55
+            X509_V_ERR_EMPTY_SUBJECT_ALT_NAME = 87,
debe55
+            X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL = 88,
debe55
+            X509_V_ERR_CA_BCONS_NOT_CRITICAL = 89,
debe55
+            X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL = 90,
debe55
+            X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL = 91,
debe55
+            X509_V_ERR_CA_CERT_MISSING_KEY_USAGE = 92,
debe55
+            X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 = 93,
debe55
+            X509_V_ERR_EC_KEY_EXPLICIT_PARAMS = 94,
debe55
+        }
debe55
+
debe55
+        internal readonly struct X509VerifyStatusCode : IEquatable<X509VerifyStatusCode>
debe55
+        {
debe55
+            internal static readonly X509VerifyStatusCode X509_V_OK = X509VerifyStatusCodeUniversal.X509_V_OK;
debe55
+
debe55
+            public int Code { get; }
debe55
+
debe55
+            internal X509VerifyStatusCode(int code)
debe55
+            {
debe55
+                Code = code;
debe55
+            }
debe55
+
debe55
+            public X509VerifyStatusCodeUniversal UniversalCode => (X509VerifyStatusCodeUniversal)Code;
debe55
+            public X509VerifyStatusCode102 Code102 => (X509VerifyStatusCode102)Code;
debe55
+            public X509VerifyStatusCode111 Code111 => (X509VerifyStatusCode111)Code;
debe55
+            public X509VerifyStatusCode30 Code30 => (X509VerifyStatusCode30)Code;
debe55
+
debe55
+            public bool Equals(X509VerifyStatusCode other) => Code == other.Code;
debe55
+
debe55
+            public override bool Equals(object obj) => obj is X509VerifyStatusCode other && Equals(other);
debe55
+
debe55
+            public override int GetHashCode() => Code.GetHashCode();
debe55
+
debe55
+            public static bool operator ==(X509VerifyStatusCode left, X509VerifyStatusCode right) => left.Equals(right);
debe55
+
debe55
+            public static bool operator !=(X509VerifyStatusCode left, X509VerifyStatusCode right) => !left.Equals(right);
debe55
+
debe55
+            public static explicit operator X509VerifyStatusCode(int code)
debe55
+            {
debe55
+                return new X509VerifyStatusCode(code);
debe55
+            }
debe55
+
debe55
+            public static implicit operator X509VerifyStatusCode(X509VerifyStatusCodeUniversal code)
debe55
+            {
debe55
+                return new X509VerifyStatusCode((int)code);
debe55
+            }
debe55
         }
debe55
     }
debe55
 }
debe55
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
debe55
index 68b6a34a5d..02b31b4737 100644
debe55
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
debe55
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
debe55
@@ -6,7 +6,7 @@
debe55
 #include "pal_utilities.h"
debe55
 #include <assert.h>
debe55
 
debe55
-static int HasNoPrivateKey(RSA* rsa);
debe55
+static int HasNoPrivateKey(const RSA* rsa);
debe55
 
debe55
 EVP_PKEY* CryptoNative_RsaGenerateKey(int keySize)
debe55
 {
debe55
@@ -86,7 +86,7 @@ int32_t CryptoNative_RsaDecrypt(EVP_PKEY* pkey,
debe55
 
debe55
     // This check may no longer be needed on OpenSSL 3.0
debe55
     {
debe55
-        RSA* rsa = EVP_PKEY_get0_RSA(pkey);
debe55
+        const RSA* rsa = EVP_PKEY_get0_RSA(pkey);
debe55
 
debe55
         if (rsa == NULL || HasNoPrivateKey(rsa))
debe55
         {
debe55
@@ -161,7 +161,7 @@ int32_t CryptoNative_RsaSignHash(EVP_PKEY* pkey,
debe55
 
debe55
     // This check may no longer be needed on OpenSSL 3.0
debe55
     {
debe55
-        RSA* rsa = EVP_PKEY_get0_RSA(pkey);
debe55
+        const RSA* rsa = EVP_PKEY_get0_RSA(pkey);
debe55
 
debe55
         if (rsa == NULL || HasNoPrivateKey(rsa))
debe55
         {
debe55
@@ -196,7 +196,7 @@ int32_t CryptoNative_EvpPkeySetRsa(EVP_PKEY* pkey, RSA* rsa)
debe55
     return EVP_PKEY_set1_RSA(pkey, rsa);
debe55
 }
debe55
 
debe55
-static int HasNoPrivateKey(RSA* rsa)
debe55
+static int HasNoPrivateKey(const RSA* rsa)
debe55
 {
debe55
     if (rsa == NULL)
debe55
         return 1;
debe55
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.c
debe55
index 5dd31d0e62..0554c8d3e8 100644
debe55
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.c
debe55
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.c
debe55
@@ -33,7 +33,6 @@ c_static_assert(PAL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY == X509_V_ERR_U
debe55
 c_static_assert(PAL_X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
debe55
 c_static_assert(PAL_X509_V_ERR_CERT_CHAIN_TOO_LONG == X509_V_ERR_CERT_CHAIN_TOO_LONG);
debe55
 c_static_assert(PAL_X509_V_ERR_CERT_REVOKED == X509_V_ERR_CERT_REVOKED);
debe55
-c_static_assert(PAL_X509_V_ERR_INVALID_CA == X509_V_ERR_INVALID_CA);
debe55
 c_static_assert(PAL_X509_V_ERR_PATH_LENGTH_EXCEEDED == X509_V_ERR_PATH_LENGTH_EXCEEDED);
debe55
 c_static_assert(PAL_X509_V_ERR_INVALID_PURPOSE == X509_V_ERR_INVALID_PURPOSE);
debe55
 c_static_assert(PAL_X509_V_ERR_CERT_UNTRUSTED == X509_V_ERR_CERT_UNTRUSTED);
debe55
@@ -48,6 +47,26 @@ c_static_assert(PAL_X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE == X509_V_ERR_KEYUS
debe55
 c_static_assert(PAL_X509_V_ERR_INVALID_EXTENSION == X509_V_ERR_INVALID_EXTENSION);
debe55
 c_static_assert(PAL_X509_V_ERR_INVALID_POLICY_EXTENSION == X509_V_ERR_INVALID_POLICY_EXTENSION);
debe55
 c_static_assert(PAL_X509_V_ERR_NO_EXPLICIT_POLICY == X509_V_ERR_NO_EXPLICIT_POLICY);
debe55
+c_static_assert(PAL_X509_V_ERR_DIFFERENT_CRL_SCOPE == X509_V_ERR_DIFFERENT_CRL_SCOPE);
debe55
+c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE == X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE);
debe55
+c_static_assert(PAL_X509_V_ERR_UNNESTED_RESOURCE == X509_V_ERR_UNNESTED_RESOURCE);
debe55
+c_static_assert(PAL_X509_V_ERR_PERMITTED_VIOLATION == X509_V_ERR_PERMITTED_VIOLATION);
debe55
+c_static_assert(PAL_X509_V_ERR_EXCLUDED_VIOLATION == X509_V_ERR_EXCLUDED_VIOLATION);
debe55
+c_static_assert(PAL_X509_V_ERR_SUBTREE_MINMAX == X509_V_ERR_SUBTREE_MINMAX);
debe55
+c_static_assert(PAL_X509_V_ERR_APPLICATION_VERIFICATION == X509_V_ERR_APPLICATION_VERIFICATION);
debe55
+c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE == X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE);
debe55
+c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX == X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX);
debe55
+c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_NAME_SYNTAX == X509_V_ERR_UNSUPPORTED_NAME_SYNTAX);
debe55
+c_static_assert(PAL_X509_V_ERR_CRL_PATH_VALIDATION_ERROR == X509_V_ERR_CRL_PATH_VALIDATION_ERROR);
debe55
+c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_VERSION == X509_V_ERR_SUITE_B_INVALID_VERSION);
debe55
+c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_ALGORITHM == X509_V_ERR_SUITE_B_INVALID_ALGORITHM);
debe55
+c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_CURVE == X509_V_ERR_SUITE_B_INVALID_CURVE);
debe55
+c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM);
debe55
+c_static_assert(PAL_X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED);
debe55
+c_static_assert(PAL_X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 == X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256);
debe55
+c_static_assert(PAL_X509_V_ERR_HOSTNAME_MISMATCH == X509_V_ERR_HOSTNAME_MISMATCH);
debe55
+c_static_assert(PAL_X509_V_ERR_EMAIL_MISMATCH == X509_V_ERR_EMAIL_MISMATCH);
debe55
+c_static_assert(PAL_X509_V_ERR_IP_ADDRESS_MISMATCH == X509_V_ERR_IP_ADDRESS_MISMATCH);
debe55
 
debe55
 EVP_PKEY* CryptoNative_GetX509EvpPublicKey(X509* x509)
debe55
 {
debe55
@@ -1109,7 +1128,10 @@ CryptoNative_X509ChainVerifyOcsp(X509_STORE_CTX* storeCtx, OCSP_REQUEST* req, OC
debe55
 
debe55
                     if (bio != NULL)
debe55
                     {
debe55
+#pragma clang diagnostic push
debe55
+#pragma clang diagnostic ignored "-Wcast-qual"
debe55
                         if (i2d_OCSP_RESPONSE_bio(bio, resp))
debe55
+#pragma clang diagnostic pop
debe55
                         {
debe55
                             clearErr = 0;
debe55
                         }
debe55
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.h b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.h
debe55
index 7f242b4c2e..f7114e9642 100644
debe55
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.h
debe55
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.h
debe55
@@ -18,7 +18,10 @@ typedef enum {
debe55
 /*
debe55
 The error codes used when verifying X509 certificate chains.
debe55
 
debe55
-These values should be kept in sync with Interop.Crypto.X509VerifyStatusCode.
debe55
+These values should be kept in sync with Interop.Crypto.X509VerifyStatusCodeUniversal.
debe55
+
debe55
+Codes specific to specific versions of OpenSSL can also be returned,
debe55
+but are not represented in this enum due to their non-constant nature.
debe55
 */
debe55
 typedef enum {
debe55
     PAL_X509_V_OK = 0,
debe55
@@ -43,7 +46,9 @@ typedef enum {
debe55
     PAL_X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 21,
debe55
     PAL_X509_V_ERR_CERT_CHAIN_TOO_LONG = 22,
debe55
     PAL_X509_V_ERR_CERT_REVOKED = 23,
debe55
-    PAL_X509_V_ERR_INVALID_CA = 24,
debe55
+
debe55
+    // Code 24 varies
debe55
+
debe55
     PAL_X509_V_ERR_PATH_LENGTH_EXCEEDED = 25,
debe55
     PAL_X509_V_ERR_INVALID_PURPOSE = 26,
debe55
     PAL_X509_V_ERR_CERT_UNTRUSTED = 27,
debe55
@@ -58,6 +63,26 @@ typedef enum {
debe55
     PAL_X509_V_ERR_INVALID_EXTENSION = 41,
debe55
     PAL_X509_V_ERR_INVALID_POLICY_EXTENSION = 42,
debe55
     PAL_X509_V_ERR_NO_EXPLICIT_POLICY = 43,
debe55
+    PAL_X509_V_ERR_DIFFERENT_CRL_SCOPE = 44,
debe55
+    PAL_X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE = 45,
debe55
+    PAL_X509_V_ERR_UNNESTED_RESOURCE = 46,
debe55
+    PAL_X509_V_ERR_PERMITTED_VIOLATION = 47,
debe55
+    PAL_X509_V_ERR_EXCLUDED_VIOLATION = 48,
debe55
+    PAL_X509_V_ERR_SUBTREE_MINMAX = 49,
debe55
+    PAL_X509_V_ERR_APPLICATION_VERIFICATION = 50,
debe55
+    PAL_X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE = 51,
debe55
+    PAL_X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX = 52,
debe55
+    PAL_X509_V_ERR_UNSUPPORTED_NAME_SYNTAX = 53,
debe55
+    PAL_X509_V_ERR_CRL_PATH_VALIDATION_ERROR = 54,
debe55
+    PAL_X509_V_ERR_SUITE_B_INVALID_VERSION = 56,
debe55
+    PAL_X509_V_ERR_SUITE_B_INVALID_ALGORITHM = 57,
debe55
+    PAL_X509_V_ERR_SUITE_B_INVALID_CURVE = 58,
debe55
+    PAL_X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM = 59,
debe55
+    PAL_X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED = 60,
debe55
+    PAL_X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 = 61,
debe55
+    PAL_X509_V_ERR_HOSTNAME_MISMATCH = 62,
debe55
+    PAL_X509_V_ERR_EMAIL_MISMATCH = 63,
debe55
+    PAL_X509_V_ERR_IP_ADDRESS_MISMATCH = 64,
debe55
 } X509VerifyStatusCode;
debe55
 
debe55
 typedef int32_t (*X509StoreVerifyCallback)(int32_t, X509_STORE_CTX*);
debe55
diff --git a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs
debe55
index d28286f016..a7f777261e 100644
debe55
--- a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs
debe55
+++ b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs
debe55
@@ -13,10 +13,14 @@
debe55
 using System.Security.Cryptography.X509Certificates.Asn1;
debe55
 using Microsoft.Win32.SafeHandles;
debe55
 
debe55
+using X509VerifyStatusCodeUniversal = Interop.Crypto.X509VerifyStatusCodeUniversal;
debe55
+
debe55
 namespace Internal.Cryptography.Pal
debe55
 {
debe55
     internal sealed class OpenSslX509ChainProcessor : IChainPal
debe55
     {
debe55
+        private delegate X509ChainStatusFlags MapVersionSpecificCode(Interop.Crypto.X509VerifyStatusCode code);
debe55
+
debe55
         // The average chain is 3 (End-Entity, Intermediate, Root)
debe55
         // 10 is plenty big.
debe55
         private const int DefaultChainCapacity = 10;
debe55
@@ -30,6 +34,8 @@ internal sealed class OpenSslX509ChainProcessor : IChainPal
debe55
         private static readonly CachedDirectoryStoreProvider s_userPersonalStore =
debe55
             new CachedDirectoryStoreProvider(X509Store.MyStoreName);
debe55
 
debe55
+        private static readonly MapVersionSpecificCode s_mapVersionSpecificCode = GetVersionLookup();
debe55
+
debe55
         private SafeX509Handle _leafHandle;
debe55
         private SafeX509StoreHandle _store;
debe55
         private readonly SafeX509StackHandle _untrustedLookup;
debe55
@@ -156,10 +162,10 @@ internal Interop.Crypto.X509VerifyStatusCode FindFirstChain(X509Certificate2Coll
debe55
 
debe55
         internal static bool IsCompleteChain(Interop.Crypto.X509VerifyStatusCode statusCode)
debe55
         {
debe55
-            switch (statusCode)
debe55
+            switch (statusCode.UniversalCode)
debe55
             {
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
debe55
                     return false;
debe55
                 default:
debe55
                     return true;
debe55
@@ -173,7 +179,7 @@ internal static bool IsCompleteChain(Interop.Crypto.X509VerifyStatusCode statusC
debe55
             SafeX509StoreCtxHandle storeCtx = _storeCtx;
debe55
 
debe55
             Interop.Crypto.X509VerifyStatusCode statusCode =
debe55
-                Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
debe55
+                X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
debe55
 
debe55
             while (!IsCompleteChain(statusCode))
debe55
             {
debe55
@@ -426,7 +432,7 @@ private Interop.Crypto.X509VerifyStatusCode CheckOcsp()
debe55
             Interop.Crypto.X509VerifyStatusCode status =
debe55
                 Interop.Crypto.X509ChainGetCachedOcspStatus(_storeCtx, ocspCache);
debe55
 
debe55
-            if (status != Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL)
debe55
+            if (status != X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_CRL)
debe55
             {
debe55
                 return status;
debe55
             }
debe55
@@ -468,7 +474,7 @@ private Interop.Crypto.X509VerifyStatusCode CheckOcsp()
debe55
                 {
debe55
                     if (resp == null || resp.IsInvalid)
debe55
                     {
debe55
-                        return Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL;
debe55
+                        return X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_CRL;
debe55
                     }
debe55
 
debe55
                     try
debe55
@@ -744,77 +750,111 @@ private static void AddUniqueStatus(IList<X509ChainStatus> list, ref X509ChainSt
debe55
 
debe55
         private static X509ChainStatusFlags MapVerifyErrorToChainStatus(Interop.Crypto.X509VerifyStatusCode code)
debe55
         {
debe55
-            switch (code)
debe55
+            switch (code.UniversalCode)
debe55
             {
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_OK:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_OK:
debe55
                     return X509ChainStatusFlags.NoError;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_NOT_YET_VALID:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_HAS_EXPIRED:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_NOT_YET_VALID:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_HAS_EXPIRED:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
debe55
                     return X509ChainStatusFlags.NotTimeValid;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_REVOKED:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_REVOKED:
debe55
                     return X509ChainStatusFlags.Revoked;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_SIGNATURE_FAILURE:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_SIGNATURE_FAILURE:
debe55
                     return X509ChainStatusFlags.NotSignatureValid;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_UNTRUSTED:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_UNTRUSTED:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
debe55
                     return X509ChainStatusFlags.UntrustedRoot;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CRL_HAS_EXPIRED:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_CRL_HAS_EXPIRED:
debe55
                     return X509ChainStatusFlags.OfflineRevocation;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CRL_NOT_YET_VALID:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CRL_SIGNATURE_FAILURE:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_CRL_NOT_YET_VALID:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_CRL_SIGNATURE_FAILURE:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_CRL:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
debe55
                     return X509ChainStatusFlags.RevocationStatusUnknown;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_INVALID_EXTENSION:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_INVALID_EXTENSION:
debe55
                     return X509ChainStatusFlags.InvalidExtension;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
debe55
                     return X509ChainStatusFlags.PartialChain;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_INVALID_PURPOSE:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_INVALID_PURPOSE:
debe55
                     return X509ChainStatusFlags.NotValidForUsage;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_INVALID_CA:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_INVALID_NON_CA:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_PATH_LENGTH_EXCEEDED:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_INVALID_NON_CA:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_PATH_LENGTH_EXCEEDED:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
debe55
                     return X509ChainStatusFlags.InvalidBasicConstraints;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_INVALID_POLICY_EXTENSION:
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_NO_EXPLICIT_POLICY:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_INVALID_POLICY_EXTENSION:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_NO_EXPLICIT_POLICY:
debe55
                     return X509ChainStatusFlags.InvalidPolicyConstraints;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_REJECTED:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_REJECTED:
debe55
                     return X509ChainStatusFlags.ExplicitDistrust;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
debe55
                     return X509ChainStatusFlags.HasNotSupportedCriticalExtension;
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_CHAIN_TOO_LONG:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_CHAIN_TOO_LONG:
debe55
                     throw new CryptographicException();
debe55
 
debe55
-                case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_OUT_OF_MEM:
debe55
+                case X509VerifyStatusCodeUniversal.X509_V_ERR_OUT_OF_MEM:
debe55
                     throw new OutOfMemoryException();
debe55
 
debe55
+                default:
debe55
+                    return s_mapVersionSpecificCode(code);
debe55
+            }
debe55
+        }
debe55
+
debe55
+        private static X509ChainStatusFlags MapOpenSsl30Code(Interop.Crypto.X509VerifyStatusCode code)
debe55
+        {
debe55
+            switch (code.Code30)
debe55
+            {
debe55
+                case Interop.Crypto.X509VerifyStatusCode30.X509_V_ERR_INVALID_CA:
debe55
+                    return X509ChainStatusFlags.InvalidBasicConstraints;
debe55
+                default:
debe55
+                    Debug.Fail("Unrecognized X509VerifyStatusCode:" + code);
debe55
+                    throw new CryptographicException();
debe55
+            }
debe55
+        }
debe55
+
debe55
+        private static X509ChainStatusFlags MapOpenSsl102Code(Interop.Crypto.X509VerifyStatusCode code)
debe55
+        {
debe55
+            switch (code.Code102)
debe55
+            {
debe55
+                case Interop.Crypto.X509VerifyStatusCode102.X509_V_ERR_INVALID_CA:
debe55
+                    return X509ChainStatusFlags.InvalidBasicConstraints;
debe55
+                default:
debe55
+                    Debug.Fail("Unrecognized X509VerifyStatusCode:" + code);
debe55
+                    throw new CryptographicException();
debe55
+            }
debe55
+        }
debe55
+
debe55
+        private static X509ChainStatusFlags MapOpenSsl111Code(Interop.Crypto.X509VerifyStatusCode code)
debe55
+        {
debe55
+            switch (code.Code111)
debe55
+            {
debe55
+                case Interop.Crypto.X509VerifyStatusCode111.X509_V_ERR_INVALID_CA:
debe55
+                    return X509ChainStatusFlags.InvalidBasicConstraints;
debe55
                 default:
debe55
                     Debug.Fail("Unrecognized X509VerifyStatusCode:" + code);
debe55
                     throw new CryptographicException();
debe55
@@ -969,7 +1009,7 @@ internal int VerifyCallback(int ok, IntPtr ctx)
debe55
                         int errorDepth = Interop.Crypto.X509StoreCtxGetErrorDepth(storeCtx);
debe55
 
debe55
                         if (AbortOnSignatureError &&
debe55
-                            errorCode == Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_SIGNATURE_FAILURE)
debe55
+                            errorCode == X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_SIGNATURE_FAILURE)
debe55
                         {
debe55
                             AbortedForSignatureError = true;
debe55
                             return 0;
debe55
@@ -979,9 +1019,9 @@ internal int VerifyCallback(int ok, IntPtr ctx)
debe55
                         // * For compatibility with Windows / .NET Framework, do not report X509_V_CRL_NOT_YET_VALID.
debe55
                         // * X509_V_ERR_DIFFERENT_CRL_SCOPE will result in X509_V_ERR_UNABLE_TO_GET_CRL
debe55
                         //   which will trigger OCSP, so is ignorable.
debe55
-                        if (errorCode != Interop.Crypto.X509VerifyStatusCode.X509_V_OK &&
debe55
-                            errorCode != Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CRL_NOT_YET_VALID &&
debe55
-                            errorCode != Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_DIFFERENT_CRL_SCOPE)
debe55
+                        if (errorCode != X509VerifyStatusCodeUniversal.X509_V_OK &&
debe55
+                            errorCode != X509VerifyStatusCodeUniversal.X509_V_ERR_CRL_NOT_YET_VALID &&
debe55
+                            errorCode != X509VerifyStatusCodeUniversal.X509_V_ERR_DIFFERENT_CRL_SCOPE)
debe55
                         {
debe55
                             if (_errors == null)
debe55
                             {
debe55
@@ -1016,6 +1056,23 @@ internal int VerifyCallback(int ok, IntPtr ctx)
debe55
             }
debe55
         }
debe55
 
debe55
+        private static MapVersionSpecificCode GetVersionLookup()
debe55
+        {
debe55
+            // 3.0+ are M_NN_00_PP_p (Major, Minor, 0, Patch, Preview)
debe55
+            // 1.x.y are 1_XX_YY_PP_p
debe55
+            if (SafeEvpPKeyHandle.OpenSslVersion >= 0x3_00_00_00_0)
debe55
+            {
debe55
+                return MapOpenSsl30Code;
debe55
+            }
debe55
+
debe55
+            if (SafeEvpPKeyHandle.OpenSslVersion >= 0x1_01_01_00_0)
debe55
+            {
debe55
+                return MapOpenSsl111Code;
debe55
+            }
debe55
+
debe55
+            return MapOpenSsl102Code;
debe55
+        }
debe55
+
debe55
         private unsafe struct ErrorCollection
debe55
         {
debe55
             // As of OpenSSL 1.1.1 there are 75 defined X509_V_ERR values,
debe55
@@ -1059,7 +1116,7 @@ public Enumerator GetEnumerator()
debe55
 
debe55
             private static int FindBucket(Interop.Crypto.X509VerifyStatusCode statusCode, out int bitValue)
debe55
             {
debe55
-                int val = (int)statusCode;
debe55
+                int val = statusCode.Code;
debe55
 
debe55
                 int bucket;
debe55
 
debe55
-- 
debe55
2.31.1
debe55