From 627aee4a30a879533507b29e0bbab9b83571164b Mon Sep 17 00:00:00 2001 From: wfurt Date: Wed, 22 Dec 2021 19:41:07 -0800 Subject: [PATCH 01/10] fix LocalCertificateSelectionCallback on unix --- .../Interop.Ssl.cs | 26 ++++++++ .../Net/CertificateValidationPal.OSX.cs | 5 ++ .../Security/Pal.OSX/SafeDeleteSslContext.cs | 2 +- .../System/Net/Security/SslStreamPal.OSX.cs | 38 +++++++++++ .../CertificateValidationClientServer.cs | 65 +++++++++++++++++++ .../entrypoints.c | 1 + .../pal_ssl.c | 10 +++ .../pal_ssl.h | 12 ++++ 8 files changed, 158 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs index 2e6e72c9418b4..af6596efd51da 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs @@ -46,6 +46,7 @@ internal enum PAL_TlsHandshakeState WouldBlock, ServerAuthCompleted, ClientAuthCompleted, + ClientCertRequested, } internal enum PAL_TlsIo @@ -99,6 +100,12 @@ private static partial int AppleCryptoNative_SslSetBreakOnClientAuth( int setBreak, out int pOSStatus); + [GeneratedDllImport(Interop.Libraries.AppleCryptoNative)] + private static partial int AppleCryptoNative_SslSetBreakOnCertRequested( + SafeSslHandle sslHandle, + int setBreak, + out int pOSStatus); + [GeneratedDllImport(Interop.Libraries.AppleCryptoNative)] private static partial int AppleCryptoNative_SslSetCertificate( SafeSslHandle sslHandle, @@ -266,6 +273,25 @@ internal static void SslBreakOnClientAuth(SafeSslHandle sslHandle, bool setBreak throw new SslException(); } + internal static void SslBreakOnCertRequested(SafeSslHandle sslHandle, bool setBreak) + { + int osStatus; + int result = AppleCryptoNative_SslSetBreakOnCertRequested(sslHandle, setBreak ? 1 : 0, out osStatus); + + if (result == 1) + { + return; + } + + if (result == 0) + { + throw CreateExceptionForOSStatus(osStatus); + } + + Debug.Fail($"AppleCryptoNative_SslSetBreakOnCertRequested returned {result}"); + throw new SslException(); + } + internal static void SslSetCertificate(SafeSslHandle sslHandle, IntPtr[] certChainPtrs) { using (SafeCreateHandle cfCertRefs = CoreFoundation.CFArrayCreate(certChainPtrs, (UIntPtr)certChainPtrs.Length)) diff --git a/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs b/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs index f1fef45e08126..6e9455954c29a 100644 --- a/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs +++ b/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs @@ -128,6 +128,11 @@ internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext secu using (SafeCFArrayHandle dnArray = Interop.AppleCrypto.SslCopyCADistinguishedNames(sslContext)) { + if (dnArray.IsInvalid) + { + return Array.Empty(); + } + long size = Interop.CoreFoundation.CFArrayGetCount(dnArray); if (size == 0) diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs index b75ee2bee7475..3690837e33f67 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteSslContext.cs @@ -316,7 +316,7 @@ private static void SetProtocols(SafeSslHandle sslContext, SslProtocols protocol Interop.AppleCrypto.SslSetMaxProtocolVersion(sslContext, maxProtocolId); } - private static void SetCertificate(SafeSslHandle sslContext, SslStreamCertificateContext context) + internal static void SetCertificate(SafeSslHandle sslContext, SslStreamCertificateContext context) { Debug.Assert(sslContext != null, "sslContext != null"); diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs index 0414082781c1e..7043b7afe19f4 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs @@ -246,6 +246,13 @@ private static SecurityStatusPal HandshakeInternal( Interop.AppleCrypto.SslSetTargetName(sslContext.SslContext, sslAuthenticationOptions.TargetHost); } + if (sslAuthenticationOptions.CertificateContext == null && sslAuthenticationOptions.CertSelectionDelegate != null) + { + // certificate was not provided but there is user callback. We can break handshake if server asks for certificate + // and we can try to get it based on remote certificate and trusted issuers. + Interop.AppleCrypto.SslBreakOnCertRequested(sslContext.SslContext, true); + } + if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired) { Interop.AppleCrypto.SslSetAcceptClientCert(sslContext.SslContext); @@ -259,6 +266,35 @@ private static SecurityStatusPal HandshakeInternal( SafeSslHandle sslHandle = sslContext!.SslContext; SecurityStatusPal status = PerformHandshake(sslHandle); + if (status.ErrorCode == SecurityStatusPalErrorCode.CredentialsNeeded) + { + // we should not be here if CertSelectionDelegate is null but better check before dereferencing.. + if (sslAuthenticationOptions.CertSelectionDelegate != null) + { + X509Certificate2? remoteCert = null; + try + { + string[] issuers = CertificateValidationPal.GetRequestCertificateAuthorities(context); + remoteCert = CertificateValidationPal.GetRemoteCertificate(context); + if (sslAuthenticationOptions.ClientCertificates == null) + { + sslAuthenticationOptions.ClientCertificates = new X509CertificateCollection(); + } + X509Certificate2 clientCertificate = (X509Certificate2)sslAuthenticationOptions.CertSelectionDelegate(sslAuthenticationOptions.TargetHost!, sslAuthenticationOptions.ClientCertificates, remoteCert, issuers); + if (clientCertificate != null) + { + SafeDeleteSslContext.SetCertificate(sslContext.SslContext, SslStreamCertificateContext.Create(clientCertificate)); + } + } + finally + { + remoteCert?.Dispose(); + } + } + + // We either got certificate or we can proceed without it. It is up to the server to decide if either is OK. + status = PerformHandshake(sslHandle); + } outputBuffer = sslContext.ReadPendingWrites(); return status; @@ -290,6 +326,8 @@ private static SecurityStatusPal PerformHandshake(SafeSslHandle sslHandle) // So, call SslHandshake again to indicate to Secure Transport that we've // accepted this handshake and it should go into the ready state. break; + case PAL_TlsHandshakeState.ClientCertRequested: + return new SecurityStatusPal(SecurityStatusPalErrorCode.CredentialsNeeded); default: return new SecurityStatusPal( SecurityStatusPalErrorCode.InternalError, diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs index a605c859b4051..54bb02b9d53e0 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs @@ -4,6 +4,7 @@ using System.Net.Sockets; using System.Net.Test.Common; using System.Security.Cryptography.X509Certificates; +using System.Threading; using System.Threading.Tasks; using Xunit; @@ -34,6 +35,70 @@ public void Dispose() _clientCertificate.Dispose(); } + [ConditionalTheory] + [InlineData(true, true)] + [InlineData(false, true)] + [InlineData(true, false)] + [InlineData(false, false)] + public async Task CertificateSelectionCallback_DelayedCertificate_OK(bool delayCertificate, bool sendClientCertificate) + { + X509Certificate? remoteCertificate = null; + + (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams(); + using (client) + using (server) + { + SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions(); + clientOptions.TargetHost = "localhost"; + clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; + clientOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, certificate, acceptableIssuers) => + { + remoteCertificate = certificate; + if (delayCertificate && remoteCertificate == null) + { + // wait until we get remote certificate from peer e.g. handshake started. + return null; + } + + return sendClientCertificate ? _clientCertificate : null; + }; + + SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions(); + serverOptions.ServerCertificate = _serverCertificate; + serverOptions.ClientCertificateRequired = true; + serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => + { + if (sendClientCertificate) + { + Assert.NotNull(certificate); + // The client chain may be incomplete. + Assert.True(sslPolicyErrors == SslPolicyErrors.None || sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors); + } + else + { + Assert.Equal(SslPolicyErrors.RemoteCertificateNotAvailable, sslPolicyErrors); + } + + return true; + }; + + + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + client.AuthenticateAsClientAsync(clientOptions), + server.AuthenticateAsServerAsync(serverOptions)); + + // verify that the session is usable with or without client's certificate + await TestHelper.PingPong(client, server); + await TestHelper.PingPong(server, client); + + if (delayCertificate) + { + // LocalCertificateSelectionCallback should be called with real remote certificate. + Assert.NotNull(remoteCertificate); + } + } + } + [Theory] [InlineData(false)] [InlineData(true)] diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c b/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c index 78b451a781f53..875ce80316562 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c @@ -56,6 +56,7 @@ static const Entry s_cryptoAppleNative[] = DllImportEntry(AppleCryptoNative_SslCopyCertChain) DllImportEntry(AppleCryptoNative_SslIsHostnameMatch) DllImportEntry(AppleCryptoNative_SslRead) + DllImportEntry(AppleCryptoNative_SslSetBreakOnCertRequested) DllImportEntry(AppleCryptoNative_SslSetBreakOnClientAuth) DllImportEntry(AppleCryptoNative_SslSetBreakOnServerAuth) DllImportEntry(AppleCryptoNative_SslSetIoCallbacks) diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c index 0770a946bee1e..9c1035f13ca73 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c @@ -164,6 +164,14 @@ int32_t AppleCryptoNative_SslSetBreakOnClientAuth(SSLContextRef sslContext, int3 #pragma clang diagnostic pop } +int32_t AppleCryptoNative_SslSetBreakOnCertRequested(SSLContextRef sslContext, int32_t setBreak, int32_t* pOSStatus) +{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return AppleCryptoNative_SslSetSessionOption(sslContext, kSSLSessionOptionBreakOnCertRequested , setBreak, pOSStatus); +#pragma clang diagnostic pop +} + int32_t AppleCryptoNative_SslSetCertificate(SSLContextRef sslContext, CFArrayRef certRefs) { #pragma clang diagnostic push @@ -275,6 +283,8 @@ PAL_TlsHandshakeState AppleCryptoNative_SslHandshake(SSLContextRef sslContext) return PAL_TlsHandshakeState_WouldBlock; case errSSLServerAuthCompleted: return PAL_TlsHandshakeState_ServerAuthCompleted; + case errSSLClientCertRequested: + return PAL_TlsHandshakeState_ClientCertRequested; default: return osStatus; } diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h index 8a992bb9a4bc9..2c5961a72ac09 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h @@ -15,6 +15,7 @@ enum PAL_TlsHandshakeState_WouldBlock = 2, PAL_TlsHandshakeState_ServerAuthCompleted = 3, PAL_TlsHandshakeState_ClientAuthCompleted = 4, + PAL_TlsHandshakeState_ClientCertRequested = 5, }; typedef int32_t PAL_TlsHandshakeState; @@ -100,6 +101,17 @@ pOSStatus: Receives the value returned by SSLSetSessionOption PALEXPORT int32_t AppleCryptoNative_SslSetBreakOnServerAuth(SSLContextRef sslContext, int32_t setBreak, int32_t* pOSStatus); +/* +Sets the policy of whether or not to break when certificate request was received on client. + +Returns 1 on success, 0 on failure, other values on invalid state. + +Output: +pOSStatus: Receives the value returned by SSLSetSessionOption +*/ +PALEXPORT int32_t +AppleCryptoNative_SslSetBreakOnCertRequested(SSLContextRef sslContext, int32_t setBreak, int32_t* pOSStatus); + /* Sets the policy of whether or not to break when a client identity has been presented. From 2cee5042f85622324edab23be4c6418104828167 Mon Sep 17 00:00:00 2001 From: wfurt Date: Wed, 29 Dec 2021 12:22:01 -0800 Subject: [PATCH 02/10] fix linux --- .../Interop.OpenSsl.cs | 56 ++++++++++++++++++- .../Interop.Ssl.cs | 33 +++++++++++ .../System/Net/Security/SslStreamPal.Unix.cs | 39 +++++++++++-- .../entrypoints.c | 4 ++ .../opensslshim.h | 6 ++ .../pal_ssl.c | 39 ++++++++++++- .../pal_ssl.h | 32 ++++++++++- 7 files changed, 201 insertions(+), 8 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index 828af2acfac0e..834ef41e89005 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -215,6 +215,45 @@ internal static SafeSslContextHandle AllocateSslContext(SafeFreeSslCredentials c return sslCtx; } + internal static void UpdateClientCertiticate(SafeSslHandle ssl, SslAuthenticationOptions sslAuthenticationOptions) + { + // Disable certificate selection callback. We either got certificate or we will try to proseed without it. + Interop.Ssl.SslSetClientCertCallback(ssl, 0); + + if (sslAuthenticationOptions.CertificateContext == null) + { + return; + } + + var credential = new SafeFreeSslCredentials(sslAuthenticationOptions.CertificateContext, sslAuthenticationOptions.EnabledSslProtocols, sslAuthenticationOptions.EncryptionPolicy, sslAuthenticationOptions.IsServer); + SafeX509Handle? certHandle = credential.CertHandle; + SafeEvpPKeyHandle? certKeyHandle = credential.CertKeyHandle; + + Debug.Assert(certHandle != null); + Debug.Assert(certKeyHandle != null); + + int retVal = Ssl.SslUseCertificate(ssl, certHandle); + if (1 != retVal) + { + throw CreateSslException(SR.net_ssl_use_cert_failed); + } + + retVal = Ssl.SslUsePrivateKey(ssl, certKeyHandle); + if (1 != retVal) + { + throw CreateSslException(SR.net_ssl_use_private_key_failed); + } + + if (sslAuthenticationOptions.CertificateContext.IntermediateCertificates.Length > 0) + { + if (!Ssl.AddExtraChainCertificates(ssl, sslAuthenticationOptions.CertificateContext.IntermediateCertificates)) + { + throw CreateSslException(SR.net_ssl_use_cert_failed); + } + } + + } + // This essentially wraps SSL* SSL_new() internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions) { @@ -283,6 +322,13 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia { Crypto.ErrClearError(); } + + if (sslAuthenticationOptions.CertSelectionDelegate != null && sslAuthenticationOptions.CertificateContext == null) + { + // We don't have certificate but we have callback. We should wait for remote certificate and + // possible trusted issuer list. + Interop.Ssl.SslSetClientCertCallback(sslHandle, 1); + } } if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired) @@ -320,7 +366,7 @@ internal static SecurityStatusPal SslRenegotiate(SafeSslHandle sslContext, out b return new SecurityStatusPal(SecurityStatusPalErrorCode.OK); } - internal static bool DoSslHandshake(SafeSslHandle context, ReadOnlySpan input, out byte[]? sendBuf, out int sendCount) + internal static SecurityStatusPalErrorCode DoSslHandshake(SafeSslHandle context, ReadOnlySpan input, out byte[]? sendBuf, out int sendCount) { sendBuf = null; sendCount = 0; @@ -341,6 +387,11 @@ internal static bool DoSslHandshake(SafeSslHandle context, ReadOnlySpan in Exception? innerError; Ssl.SslErrorCode error = GetSslError(context, retVal, out innerError); + if (error == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) + { + return SecurityStatusPalErrorCode.CredentialsNeeded; + } + if ((retVal != -1) || (error != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) { // Handshake failed, but even if the handshake does not need to read, there may be an Alert going out. @@ -385,7 +436,8 @@ internal static bool DoSslHandshake(SafeSslHandle context, ReadOnlySpan in { context.MarkHandshakeCompleted(); } - return stateOk; + + return stateOk ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.ContinueNeeded; } internal static int Encrypt(SafeSslHandle context, ReadOnlySpan input, ref byte[] output, out Ssl.SslErrorCode errorCode) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs index 1db80064b2c80..e9d86e35a87e1 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Net.Security; using System.Runtime.InteropServices; +using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using Microsoft.Win32.SafeHandles; @@ -149,6 +150,15 @@ internal static partial class Ssl [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslSetData")] internal static partial int SslSetData(IntPtr ssl, IntPtr data); + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslUseCertificate")] + internal static extern int SslUseCertificate(SafeSslHandle ssl, SafeX509Handle certPtr); + + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslUsePrivateKey")] + internal static extern int SslUsePrivateKey(SafeSslHandle ssl, SafeEvpPKeyHandle keyPtr); + + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslSetClientCertCallback")] + internal static extern unsafe void SslSetClientCertCallback(SafeSslHandle ssl, int set); + internal static unsafe int SslSetAlpnProtos(SafeSslHandle ssl, List protocols) { byte[] buffer = ConvertAlpnProtocolListToByteArray(protocols); @@ -183,6 +193,28 @@ internal static byte[] ConvertAlpnProtocolListToByteArray(List new SecurityStatusPal(SecurityStatusPalErrorCode.Renegotiate), Interop.Ssl.SslErrorCode.SSL_ERROR_ZERO_RETURN => new SecurityStatusPal(SecurityStatusPalErrorCode.ContextExpired), + Interop.Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP => new SecurityStatusPal(SecurityStatusPalErrorCode.CredentialsNeeded), Interop.Ssl.SslErrorCode.SSL_ERROR_NONE or Interop.Ssl.SslErrorCode.SSL_ERROR_WANT_READ => new SecurityStatusPal(SecurityStatusPalErrorCode.OK), _ => new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, new Interop.OpenSsl.SslException((int)errorCode)) @@ -158,12 +159,42 @@ private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credentia context = new SafeDeleteSslContext((credential as SafeFreeSslCredentials)!, sslAuthenticationOptions); } - bool done = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, inputBuffer, out output, out outputSize); + var errorCode = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, inputBuffer, out output, out outputSize); + + if (errorCode == SecurityStatusPalErrorCode.CredentialsNeeded) + { + if (sslAuthenticationOptions.CertSelectionDelegate != null) + { + X509Certificate2? remoteCert = null; + string[] issuers = CertificateValidationPal.GetRequestCertificateAuthorities(context); + try + { + remoteCert = CertificateValidationPal.GetRemoteCertificate(context); + if (sslAuthenticationOptions.ClientCertificates == null) + { + sslAuthenticationOptions.ClientCertificates = new X509CertificateCollection(); + } + X509Certificate2 clientCertificate = (X509Certificate2)sslAuthenticationOptions.CertSelectionDelegate(sslAuthenticationOptions.TargetHost!, sslAuthenticationOptions.ClientCertificates, remoteCert, issuers); + if (clientCertificate != null && clientCertificate.HasPrivateKey) + { + sslAuthenticationOptions.CertificateContext = SslStreamCertificateContext.Create(clientCertificate); + } + } + finally + { + remoteCert?.Dispose(); + } + } + + Interop.OpenSsl.UpdateClientCertiticate(((SafeDeleteSslContext)context).SslContext, sslAuthenticationOptions); + errorCode = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, null, out output, out outputSize); + } + // sometimes during renegotiation processing messgae does not yield new output. // That seems to be flaw in OpenSSL state machine and we have workaround to peek it and try it again. if (outputSize == 0 && Interop.Ssl.IsSslRenegotiatePending(((SafeDeleteSslContext)context).SslContext)) { - done = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, ReadOnlySpan.Empty, out output, out outputSize); + errorCode = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, ReadOnlySpan.Empty, out output, out outputSize); } // When the handshake is done, and the context is server, check if the alpnHandle target was set to null during ALPN. @@ -171,7 +202,7 @@ private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credentia // We have this workaround, as openssl supports terminating handshake only from version 1.1.0, // whereas ALPN is supported from version 1.0.2. SafeSslHandle sslContext = context.SslContext; - if (done && sslAuthenticationOptions.IsServer + if (errorCode == SecurityStatusPalErrorCode.OK && sslAuthenticationOptions.IsServer && sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0 && sslContext.AlpnHandle.IsAllocated && sslContext.AlpnHandle.Target == null) { @@ -183,7 +214,7 @@ private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credentia outputSize == output!.Length ? output : new Span(output, 0, outputSize).ToArray(); - return new SecurityStatusPal(done ? SecurityStatusPalErrorCode.OK : SecurityStatusPalErrorCode.ContinueNeeded); + return new SecurityStatusPal(errorCode); } catch (Exception exc) { diff --git a/src/native/libs/System.Security.Cryptography.Native/entrypoints.c b/src/native/libs/System.Security.Cryptography.Native/entrypoints.c index 4a95b97756a32..abbc77e6dfc65 100644 --- a/src/native/libs/System.Security.Cryptography.Native/entrypoints.c +++ b/src/native/libs/System.Security.Cryptography.Native/entrypoints.c @@ -300,6 +300,7 @@ static const Entry s_cryptoNative[] = DllImportEntry(CryptoNative_SslCtxSetVerify) DllImportEntry(CryptoNative_SslCtxUseCertificate) DllImportEntry(CryptoNative_SslCtxUsePrivateKey) + DllImportEntry(CryptoNative_SslAddExtraChainCert) DllImportEntry(CryptoNative_SslDestroy) DllImportEntry(CryptoNative_SslDoHandshake) DllImportEntry(CryptoNative_SslGetClientCAList) @@ -316,12 +317,15 @@ static const Entry s_cryptoNative[] = DllImportEntry(CryptoNative_SslSetAcceptState) DllImportEntry(CryptoNative_SslSetAlpnProtos) DllImportEntry(CryptoNative_SslSetBio) + DllImportEntry(CryptoNative_SslSetClientCertCallback) DllImportEntry(CryptoNative_SslSetConnectState) DllImportEntry(CryptoNative_SslSetData) DllImportEntry(CryptoNative_SslSetQuietShutdown) DllImportEntry(CryptoNative_SslSetTlsExtHostName) DllImportEntry(CryptoNative_SslSetVerifyPeer) DllImportEntry(CryptoNative_SslShutdown) + DllImportEntry(CryptoNative_SslUseCertificate) + DllImportEntry(CryptoNative_SslUsePrivateKey) DllImportEntry(CryptoNative_SslV2_3Method) DllImportEntry(CryptoNative_SslWrite) DllImportEntry(CryptoNative_X509StoreCtxGetTargetCert) diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index 5675f4c0ca7fb..2c7b97b5c805c 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -503,6 +503,7 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void); FALLBACK_FUNCTION(SSL_session_reused) \ REQUIRED_FUNCTION(SSL_set_accept_state) \ REQUIRED_FUNCTION(SSL_set_bio) \ + REQUIRED_FUNCTION(SSL_set_cert_cb) \ REQUIRED_FUNCTION(SSL_set_cipher_list) \ LIGHTUP_FUNCTION(SSL_set_ciphersuites) \ REQUIRED_FUNCTION(SSL_set_connect_state) \ @@ -514,6 +515,8 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void); LEGACY_FUNCTION(SSLeay) \ RENAMED_FUNCTION(TLS_method, SSLv23_method) \ REQUIRED_FUNCTION(SSL_write) \ + REQUIRED_FUNCTION(SSL_use_certificate) \ + REQUIRED_FUNCTION(SSL_use_PrivateKey) \ FALLBACK_FUNCTION(X509_check_host) \ REQUIRED_FUNCTION(X509_check_purpose) \ REQUIRED_FUNCTION(X509_cmp_current_time) \ @@ -962,6 +965,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define SSL_session_reused SSL_session_reused_ptr #define SSL_set_accept_state SSL_set_accept_state_ptr #define SSL_set_bio SSL_set_bio_ptr +#define SSL_set_cert_cb SSL_set_cert_cb_ptr #define SSL_set_cipher_list SSL_set_cipher_list_ptr #define SSL_set_ciphersuites SSL_set_ciphersuites_ptr #define SSL_set_connect_state SSL_set_connect_state_ptr @@ -972,6 +976,8 @@ FOR_ALL_OPENSSL_FUNCTIONS #define SSL_state SSL_state_ptr #define SSLeay SSLeay_ptr #define SSL_write SSL_write_ptr +#define SSL_use_certificate SSL_use_certificate_ptr +#define SSL_use_PrivateKey SSL_use_PrivateKey_ptr #define TLS_method TLS_method_ptr #define X509_check_host X509_check_host_ptr #define X509_check_purpose X509_check_purpose_ptr diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c index 2b4eb271b022a..0f2f53fc0d931 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c @@ -433,6 +433,16 @@ X509Stack* CryptoNative_SslGetPeerCertChain(SSL* ssl) return SSL_get_peer_cert_chain(ssl); } +int32_t CryptoNative_SslUseCertificate(SSL* ssl, X509* x) +{ + return SSL_use_certificate(ssl, x); +} + +int32_t CryptoNative_SslUsePrivateKey(SSL* ssl, EVP_PKEY* pkey) +{ + return SSL_use_PrivateKey(ssl, pkey); +} + int32_t CryptoNative_SslCtxUseCertificate(SSL_CTX* ctx, X509* x) { return SSL_CTX_use_certificate(ctx, x); @@ -630,6 +640,21 @@ int32_t CryptoNative_SslCtxAddExtraChainCert(SSL_CTX* ctx, X509* x509) return 0; } +int32_t CryptoNative_SslAddExtraChainCert(SSL* ssl, X509* x509) +{ + if (!x509 || !ssl) + { + return 0; + } + + if (SSL_ctrl(ssl, SSL_CTRL_CHAIN_CERT, 1,(void*)x509) == 1) + { + return 1; + } + + return 0; +} + void CryptoNative_SslCtxSetAlpnSelectCb(SSL_CTX* ctx, SslCtxSetAlpnCallback cb, void* arg) { #if HAVE_OPENSSL_ALPN @@ -645,6 +670,19 @@ void CryptoNative_SslCtxSetAlpnSelectCb(SSL_CTX* ctx, SslCtxSetAlpnCallback cb, #endif } +static int client_certificate_cb(SSL *ssl, void* state) +{ + (void*)ssl; + (void*)state; + // if we return negative number handshake will pause with SSL_ERROR_WANT_X509_LOOKUP + return -1; +} + +void CryptoNative_SslSetClientCertCallback(SSL* ssl, int set) +{ + SSL_set_cert_cb(ssl, set ? client_certificate_cb : NULL, NULL); +} + int32_t CryptoNative_SslSetData(SSL* ssl, void *ptr) { return SSL_set_ex_data(ssl, 0, ptr); @@ -652,7 +690,6 @@ int32_t CryptoNative_SslSetData(SSL* ssl, void *ptr) void* CryptoNative_SslGetData(SSL* ssl) { -// void* data = SSL_get_ex_data(ssl, 0, ptr); return SSL_get_ex_data(ssl, 0); } diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h index 0a18f7a764c17..80fc328e991e3 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h @@ -144,6 +144,12 @@ Sets the specified protocols in the SSL_CTX options. */ PALEXPORT void CryptoNative_SslCtxSetProtocolOptions(SSL_CTX* ctx, SslProtocols protocols); +/* +Sets internal callback for client certificate selection is set is positive. +It will unset callback if set is zero. +*/ +PALEXPORT void CryptoNative_SslSetClientCertCallback(SSL* ssl, int set); + /* Shims the SSL_new method. @@ -274,6 +280,22 @@ Returns the certificate chain presented by the peer. */ PALEXPORT X509Stack* CryptoNative_SslGetPeerCertChain(SSL* ssl); +/* +Shims the SSL_use_certificate method. + +Returns 1 upon success, otherwise 0. +*/ +PALEXPORT int32_t CryptoNative_SslUseCertificate(SSL* ssl, X509* x); + +/* +Shims the SSL_use_PrivateKey method. + +Returns 1 upon success, otherwise 0. +*/ +PALEXPORT int32_t CryptoNative_SslUsePrivateKey(SSL* ssl, EVP_PKEY* pkey); + + + /* Shims the SSL_CTX_use_certificate method. @@ -366,13 +388,21 @@ Shims the SSL_session_reused macro. PALEXPORT int32_t CryptoNative_SslSessionReused(SSL* ssl); /* -adds the given certificate to the extra chain certificates associated with ctx. +Adds the given certificate to the extra chain certificates associated with ctx. libssl frees the x509 object. Returns 1 if success and 0 in case of failure */ PALEXPORT int32_t CryptoNative_SslCtxAddExtraChainCert(SSL_CTX* ctx, X509* x509); +/* +Adds the given certificate to the extra chain certificates associated with ssl state. + +libssl frees the x509 object. +Returns 1 if success and 0 in case of failure +*/ +PALEXPORT int32_t CryptoNative_SslAddExtraChainCert(SSL* ssl, X509* x509); + /* Shims the ssl_ctx_set_alpn_select_cb method. */ From 4088a37fc673bf202d994b419d793172767fbbed Mon Sep 17 00:00:00 2001 From: wfurt Date: Wed, 29 Dec 2021 18:26:07 -0800 Subject: [PATCH 03/10] use Tls12 --- .../FunctionalTests/CertificateValidationClientServer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs index 54bb02b9d53e0..e46693b17de92 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs @@ -3,6 +3,7 @@ using System.Net.Sockets; using System.Net.Test.Common; +using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -50,6 +51,9 @@ public async Task CertificateSelectionCallback_DelayedCertificate_OK(bool delayC { SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions(); clientOptions.TargetHost = "localhost"; + // Force Tls 1.2 to avoid issues with certain OpenSSL versions and Tls 1.3 + // https://github.com/openssl/openssl/issues/7384 + clientOptions.EnabledSslProtocols = SslProtocols.Tls12; clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; clientOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, certificate, acceptableIssuers) => { From d18c3b7183787b51ea8719a445a5decbfe10027e Mon Sep 17 00:00:00 2001 From: wfurt Date: Thu, 30 Dec 2021 11:10:45 -0800 Subject: [PATCH 04/10] attempt to fix build --- .../System.Security.Cryptography.Native.Apple/pal_ssl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c index 9c1035f13ca73..09db28f06b1fb 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c @@ -156,19 +156,19 @@ int32_t AppleCryptoNative_SslSetBreakOnServerAuth(SSLContextRef sslContext, int3 #pragma clang diagnostic pop } -int32_t AppleCryptoNative_SslSetBreakOnClientAuth(SSLContextRef sslContext, int32_t setBreak, int32_t* pOSStatus) +int32_t AppleCryptoNative_SslSetBreakOnCertRequested(SSLContextRef sslContext, int32_t setBreak, int32_t* pOSStatus) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - return AppleCryptoNative_SslSetSessionOption(sslContext, kSSLSessionOptionBreakOnClientAuth, setBreak, pOSStatus); + return AppleCryptoNative_SslSetSessionOption(sslContext, kSSLSessionOptionBreakOnCertRequested, setBreak, pOSStatus); #pragma clang diagnostic pop } -int32_t AppleCryptoNative_SslSetBreakOnCertRequested(SSLContextRef sslContext, int32_t setBreak, int32_t* pOSStatus) +int32_t AppleCryptoNative_SslSetBreakOnClientAuth(SSLContextRef sslContext, int32_t setBreak, int32_t* pOSStatus) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - return AppleCryptoNative_SslSetSessionOption(sslContext, kSSLSessionOptionBreakOnCertRequested , setBreak, pOSStatus); + return AppleCryptoNative_SslSetSessionOption(sslContext, kSSLSessionOptionBreakOnClientAuth, setBreak, pOSStatus); #pragma clang diagnostic pop } From 56f00e3f36a0a06b7f2cc17c78188912b007e4dd Mon Sep 17 00:00:00 2001 From: wfurt Date: Thu, 30 Dec 2021 11:22:01 -0800 Subject: [PATCH 05/10] fix macOS --- .../libs/System.Security.Cryptography.Native.Apple/pal_ssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c index 74562e52470ee..7a8a0eebe1317 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c @@ -160,7 +160,7 @@ int32_t AppleCryptoNative_SslSetBreakOnCertRequested(SSLContextRef sslContext, i { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - return AppleCryptoNative_SslSetSessionOption(sslContext, kSSLSessionOptionBreakOnCertRequested, setBreak, pOSStatus); + return SslSetSessionOption(sslContext, kSSLSessionOptionBreakOnCertRequested, setBreak, pOSStatus); #pragma clang diagnostic pop } From 20c2e5a3a1834e434ce5fa21f07dfba06b9f84f9 Mon Sep 17 00:00:00 2001 From: wfurt Date: Thu, 30 Dec 2021 15:38:59 -0800 Subject: [PATCH 06/10] fix test on windows --- .../CertificateValidationClientServer.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs index e46693b17de92..cd26a0800345b 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs @@ -36,19 +36,20 @@ public void Dispose() _clientCertificate.Dispose(); } - [ConditionalTheory] + [Theory] [InlineData(true, true)] [InlineData(false, true)] [InlineData(true, false)] [InlineData(false, false)] public async Task CertificateSelectionCallback_DelayedCertificate_OK(bool delayCertificate, bool sendClientCertificate) { - X509Certificate? remoteCertificate = null; + X509Certificate? remoteCertificate = null; (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams(); using (client) using (server) { + int count = 0; SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions(); clientOptions.TargetHost = "localhost"; // Force Tls 1.2 to avoid issues with certain OpenSSL versions and Tls 1.3 @@ -57,8 +58,9 @@ public async Task CertificateSelectionCallback_DelayedCertificate_OK(bool delayC clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; clientOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, certificate, acceptableIssuers) => { + count++; remoteCertificate = certificate; - if (delayCertificate && remoteCertificate == null) + if (delayCertificate && count == 1) { // wait until we get remote certificate from peer e.g. handshake started. return null; @@ -98,7 +100,11 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( if (delayCertificate) { // LocalCertificateSelectionCallback should be called with real remote certificate. - Assert.NotNull(remoteCertificate); + if (!OperatingSystem.IsWindows()) + { + // remote certificate does not work on windows. + Assert.NotNull(remoteCertificate); + } } } } From 1379e88f1b778ace0d413b484c985791dca29257 Mon Sep 17 00:00:00 2001 From: wfurt Date: Fri, 31 Dec 2021 10:38:09 -0800 Subject: [PATCH 07/10] skip win7 --- .../tests/FunctionalTests/CertificateValidationClientServer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs index cd26a0800345b..5dba551f04b32 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs @@ -5,7 +5,6 @@ using System.Net.Test.Common; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; -using System.Threading; using System.Threading.Tasks; using Xunit; @@ -36,7 +35,7 @@ public void Dispose() _clientCertificate.Dispose(); } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))] [InlineData(true, true)] [InlineData(false, true)] [InlineData(true, false)] From e7558ebcd988638e5b74f8f776055f8e917abc1c Mon Sep 17 00:00:00 2001 From: wfurt Date: Mon, 3 Jan 2022 16:51:21 -0800 Subject: [PATCH 08/10] add issue reference for windows --- .../tests/FunctionalTests/CertificateValidationClientServer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs index 5dba551f04b32..5ca6a63e0d4ac 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationClientServer.cs @@ -102,6 +102,7 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout( if (!OperatingSystem.IsWindows()) { // remote certificate does not work on windows. + // https://github.com/dotnet/runtime/issues/63321 Assert.NotNull(remoteCertificate); } } From 8a0d81ced50ccaa1b2bbad51ae966f8f5bbe64a5 Mon Sep 17 00:00:00 2001 From: wfurt Date: Fri, 7 Jan 2022 14:56:01 -0800 Subject: [PATCH 09/10] feedback from review --- .../System.Security.Cryptography.Native/Interop.OpenSsl.cs | 2 +- .../src/System/Net/Security/SslStreamPal.Unix.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index 34fa91ed887d4..ba0883c6ff984 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -217,7 +217,7 @@ internal static SafeSslContextHandle AllocateSslContext(SafeFreeSslCredentials c internal static void UpdateClientCertiticate(SafeSslHandle ssl, SslAuthenticationOptions sslAuthenticationOptions) { - // Disable certificate selection callback. We either got certificate or we will try to proseed without it. + // Disable certificate selection callback. We either got certificate or we will try to proceed without it. Interop.Ssl.SslSetClientCertCallback(ssl, 0); if (sslAuthenticationOptions.CertificateContext == null) diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs index 5d0739ed38fb8..de48bd563d420 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Unix.cs @@ -159,7 +159,7 @@ private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credentia context = new SafeDeleteSslContext((credential as SafeFreeSslCredentials)!, sslAuthenticationOptions); } - var errorCode = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, inputBuffer, out output, out outputSize); + SecurityStatusPalErrorCode errorCode = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, inputBuffer, out output, out outputSize); if (errorCode == SecurityStatusPalErrorCode.CredentialsNeeded) { @@ -214,7 +214,7 @@ private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credentia outputSize == output!.Length ? output : new Span(output, 0, outputSize).ToArray(); - return new SecurityStatusPal(errorCode); + return new SecurityStatusPal(errorCode); } catch (Exception exc) { From 026ab63ef7211f69b77b23648f1beaa078276f4e Mon Sep 17 00:00:00 2001 From: wfurt Date: Mon, 10 Jan 2022 20:49:23 -0800 Subject: [PATCH 10/10] fix space --- .../libs/System.Security.Cryptography.Native/opensslshim.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h index 5bad98abc745b..0b38944d502e8 100644 --- a/src/native/libs/System.Security.Cryptography.Native/opensslshim.h +++ b/src/native/libs/System.Security.Cryptography.Native/opensslshim.h @@ -964,7 +964,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define SSL_session_reused SSL_session_reused_ptr #define SSL_set_accept_state SSL_set_accept_state_ptr #define SSL_set_bio SSL_set_bio_ptr -#define SSL_set_cert_cb SSL_set_cert_cb_ptr +#define SSL_set_cert_cb SSL_set_cert_cb_ptr #define SSL_set_cipher_list SSL_set_cipher_list_ptr #define SSL_set_ciphersuites SSL_set_ciphersuites_ptr #define SSL_set_connect_state SSL_set_connect_state_ptr