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 0ff798bedd50f0..826d39abc09e1f 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
@@ -150,11 +150,8 @@ private static SslProtocols CalculateEffectiveProtocols(SslAuthenticationOptions
}
// This essentially wraps SSL_CTX* aka SSL_CTX_new + setting
- internal static unsafe SafeSslContextHandle AllocateSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions, SslProtocols protocols, bool enableResume)
+ internal static unsafe SafeSslContextHandle AllocateSslContext(SslAuthenticationOptions sslAuthenticationOptions, SslProtocols protocols, bool enableResume)
{
- SafeX509Handle? certHandle = credential.CertHandle;
- SafeEvpPKeyHandle? certKeyHandle = credential.CertKeyHandle;
-
// Always use SSLv23_method, regardless of protocols. It supports negotiating to the highest
// mutually supported version and can thus handle any of the set protocols, and we then use
// SetProtocolOptions to ensure we only allow the ones requested.
@@ -225,17 +222,10 @@ internal static unsafe SafeSslContextHandle AllocateSslContext(SafeFreeSslCreden
Interop.Ssl.SslCtxSetAlpnSelectCb(sslCtx, &AlpnServerSelectCallback, IntPtr.Zero);
}
- bool hasCertificateAndKey =
- certHandle != null && !certHandle.IsInvalid
- && certKeyHandle != null && !certKeyHandle.IsInvalid;
-
- if (hasCertificateAndKey)
- {
- SetSslCertificate(sslCtx, certHandle!, certKeyHandle!);
- }
-
if (sslAuthenticationOptions.CertificateContext != null)
{
+ SetSslCertificate(sslCtx, sslAuthenticationOptions.CertificateContext.CertificateHandle, sslAuthenticationOptions.CertificateContext.KeyHandle);
+
if (sslAuthenticationOptions.CertificateContext.IntermediateCertificates.Length > 0)
{
if (!Ssl.AddExtraChainCertificates(sslCtx, sslAuthenticationOptions.CertificateContext.IntermediateCertificates))
@@ -269,20 +259,16 @@ internal static void UpdateClientCertiticate(SafeSslHandle ssl, SslAuthenticatio
return;
}
- var credential = new SafeFreeSslCredentials(sslAuthenticationOptions.CertificateContext, sslAuthenticationOptions.EnabledSslProtocols, sslAuthenticationOptions.EncryptionPolicy, sslAuthenticationOptions.IsServer);
- SafeX509Handle? certHandle = credential.CertHandle;
- SafeEvpPKeyHandle? certKeyHandle = credential.CertKeyHandle;
+ Debug.Assert(sslAuthenticationOptions.CertificateContext.CertificateHandle != null);
+ Debug.Assert(sslAuthenticationOptions.CertificateContext.KeyHandle != null);
- Debug.Assert(certHandle != null);
- Debug.Assert(certKeyHandle != null);
-
- int retVal = Ssl.SslUseCertificate(ssl, certHandle);
+ int retVal = Ssl.SslUseCertificate(ssl, sslAuthenticationOptions.CertificateContext.CertificateHandle);
if (1 != retVal)
{
throw CreateSslException(SR.net_ssl_use_cert_failed);
}
- retVal = Ssl.SslUsePrivateKey(ssl, certKeyHandle);
+ retVal = Ssl.SslUsePrivateKey(ssl, sslAuthenticationOptions.CertificateContext.KeyHandle);
if (1 != retVal)
{
throw CreateSslException(SR.net_ssl_use_private_key_failed);
@@ -295,11 +281,10 @@ internal static void UpdateClientCertiticate(SafeSslHandle ssl, SslAuthenticatio
throw CreateSslException(SR.net_ssl_use_cert_failed);
}
}
-
}
// This essentially wraps SSL* SSL_new()
- internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions)
+ internal static SafeSslHandle AllocateSslHandle(SslAuthenticationOptions sslAuthenticationOptions)
{
SafeSslHandle? sslHandle = null;
SafeSslContextHandle? sslCtxHandle = null;
@@ -352,7 +337,7 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia
if (sslCtxHandle == null)
{
// We did not get SslContext from cache
- sslCtxHandle = newCtxHandle = AllocateSslContext(credential, sslAuthenticationOptions, protocols, cacheSslContext);
+ sslCtxHandle = newCtxHandle = AllocateSslContext(sslAuthenticationOptions, protocols, cacheSslContext);
if (cacheSslContext)
{
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 d4afcf1027dda3..bea9f4625a4ac0 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
@@ -327,7 +327,7 @@ internal enum SslErrorCode
namespace Microsoft.Win32.SafeHandles
{
- internal sealed class SafeSslHandle : SafeHandle
+ internal sealed class SafeSslHandle : SafeDeleteSslContext
{
private SafeBioHandle? _readBio;
private SafeBioHandle? _writeBio;
diff --git a/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteContext.cs b/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteContext.cs
index eab627c6afd9c0..b26e691ea40380 100644
--- a/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteContext.cs
+++ b/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteContext.cs
@@ -13,32 +13,21 @@ internal abstract class SafeDeleteContext : DebugSafeHandle
internal abstract class SafeDeleteContext : SafeHandle
{
#endif
- private SafeFreeCredentials _credential;
-
- protected SafeDeleteContext(SafeFreeCredentials credential)
- : base(IntPtr.Zero, true)
+ public SafeDeleteContext(IntPtr handle) : base(handle, true)
{
- Debug.Assert((null != credential), "Invalid credential passed to SafeDeleteContext");
+ }
- // When a credential handle is first associated with the context we keep credential
- // ref count bumped up to ensure ordered finalization. The credential properties
- // are used in the SSL/NEGO data structures and should survive the lifetime of
- // the SSL/NEGO context
- bool ignore = false;
- _credential = credential;
- _credential.DangerousAddRef(ref ignore);
+ public SafeDeleteContext(IntPtr handle, bool ownsHandle) : base(handle, ownsHandle)
+ {
}
public override bool IsInvalid
{
- get { return (null == _credential); }
+ get { return (IntPtr.Zero == handle); }
}
protected override bool ReleaseHandle()
{
- Debug.Assert((null != _credential), "Null credential in SafeDeleteContext");
- _credential.DangerousRelease();
- _credential = null!;
return true;
}
}
diff --git a/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteNegoContext.cs b/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteNegoContext.cs
index c3316ee343538b..443e98e9de4b4f 100644
--- a/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteNegoContext.cs
+++ b/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteNegoContext.cs
@@ -15,6 +15,7 @@ internal sealed class SafeDeleteNegoContext : SafeDeleteContext
private SafeGssNameHandle? _targetName;
private SafeGssContextHandle _context;
private bool _isNtlmUsed;
+ private SafeFreeNegoCredentials? _credential;
public SafeGssCredHandle AcceptorCredential
{
@@ -42,14 +43,17 @@ public SafeGssContextHandle GssContext
}
public SafeDeleteNegoContext(SafeFreeNegoCredentials credential)
- : base(credential)
+ : base(IntPtr.Zero)
{
Debug.Assert((null != credential), "Null credential in SafeDeleteNegoContext");
+ bool added = false;
+ credential.DangerousAddRef(ref added);
+ _credential = credential;
_context = new SafeGssContextHandle();
}
public SafeDeleteNegoContext(SafeFreeNegoCredentials credential, string targetName)
- : this(credential)
+ : base(IntPtr.Zero)
{
try
{
@@ -61,6 +65,9 @@ public SafeDeleteNegoContext(SafeFreeNegoCredentials credential, string targetNa
Dispose();
throw;
}
+ _credential = credential;
+ bool ignore = false;
+ _credential.DangerousAddRef(ref ignore);
}
public void SetGssContext(SafeGssContextHandle context)
@@ -73,6 +80,11 @@ public void SetAuthenticationPackage(bool isNtlmUsed)
_isNtlmUsed = isNtlmUsed;
}
+ public override bool IsInvalid
+ {
+ get { return (null == _credential); }
+ }
+
protected override void Dispose(bool disposing)
{
if (disposing)
@@ -93,5 +105,11 @@ protected override void Dispose(bool disposing)
}
base.Dispose(disposing);
}
+
+ protected override bool ReleaseHandle()
+ {
+ _credential?.DangerousRelease();
+ return true;
+ }
}
}
diff --git a/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteSslContext.cs b/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteSslContext.cs
index f35a693a651535..0a870ef627327d 100644
--- a/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteSslContext.cs
+++ b/src/libraries/Common/src/System/Net/Security/Unix/SafeDeleteSslContext.cs
@@ -13,55 +13,14 @@
namespace System.Net.Security
{
- internal sealed class SafeDeleteSslContext : SafeDeleteContext
+ internal class SafeDeleteSslContext : SafeDeleteContext
{
- private SafeSslHandle _sslContext;
-
- public SafeSslHandle SslContext
+ public SafeDeleteSslContext(IntPtr handle) : base(handle, true)
{
- get
- {
- return _sslContext;
- }
- }
-
- public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions)
- : base(credential)
- {
- Debug.Assert((null != credential) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext");
-
- try
- {
- _sslContext = Interop.OpenSsl.AllocateSslHandle(credential, sslAuthenticationOptions);
- }
- catch (Exception ex)
- {
- Debug.Write("Exception Caught. - " + ex);
- Dispose();
- throw;
- }
}
- public override bool IsInvalid
+ public SafeDeleteSslContext(IntPtr handle, bool ownsHandle) : base(handle, ownsHandle)
{
- get
- {
- return (null == _sslContext) || _sslContext.IsInvalid;
- }
- }
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (null != _sslContext)
- {
- _sslContext.Dispose();
- _sslContext = null!;
- }
- }
-
- base.Dispose(disposing);
}
}
}
diff --git a/src/libraries/Common/src/System/Net/Security/Unix/SafeFreeNegoCredentials.cs b/src/libraries/Common/src/System/Net/Security/Unix/SafeFreeNegoCredentials.cs
index 3f722378891643..4adf347cdfdb5b 100644
--- a/src/libraries/Common/src/System/Net/Security/Unix/SafeFreeNegoCredentials.cs
+++ b/src/libraries/Common/src/System/Net/Security/Unix/SafeFreeNegoCredentials.cs
@@ -44,7 +44,7 @@ public SafeFreeNegoCredentials(Interop.NetSecurityNative.PackageType packageType
const char At = '@';
const char Backwhack = '\\';
- // any invalid user format will not be mnipulated and passed as it is.
+ // any invalid user format will not be manipulated and passed as it is.
int index = username.IndexOf(Backwhack);
if (index > 0 && username.IndexOf(Backwhack, index + 1) < 0 && string.IsNullOrEmpty(domain))
{
diff --git a/src/libraries/Common/src/System/Net/Security/Unix/SafeFreeSslCredentials.cs b/src/libraries/Common/src/System/Net/Security/Unix/SafeFreeSslCredentials.cs
deleted file mode 100644
index c509a7c4c5b5e1..00000000000000
--- a/src/libraries/Common/src/System/Net/Security/Unix/SafeFreeSslCredentials.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Microsoft.Win32.SafeHandles;
-
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Security.Authentication;
-using System.Security.Authentication.ExtendedProtection;
-using System.Security.Cryptography;
-using System.Security.Cryptography.X509Certificates;
-
-namespace System.Net.Security
-{
- internal sealed class SafeFreeSslCredentials : SafeFreeCredentials
- {
- private SafeX509Handle? _certHandle;
- private SafeEvpPKeyHandle? _certKeyHandle;
- private SslProtocols _protocols = SslProtocols.None;
- private EncryptionPolicy _policy;
- private bool _isInvalid;
- private SslStreamCertificateContext? _context;
-
- internal SafeX509Handle? CertHandle
- {
- get { return _certHandle; }
- }
-
- internal SafeEvpPKeyHandle? CertKeyHandle
- {
- get { return _certKeyHandle; }
- }
-
- internal SslProtocols Protocols
- {
- get { return _protocols; }
- }
-
- internal EncryptionPolicy Policy
- {
- get { return _policy; }
- }
-
- public SafeFreeSslCredentials(SslStreamCertificateContext? context, SslProtocols protocols, EncryptionPolicy policy, bool isServer)
- : base(IntPtr.Zero, true)
- {
-
- Debug.Assert(
- context == null || context.Certificate is X509Certificate2,
- "Only X509Certificate2 certificates are supported at this time");
-
- X509Certificate2? cert = context?.Certificate;
-
- if (cert != null)
- {
- Debug.Assert(cert.HasPrivateKey, "cert.HasPrivateKey");
-
- using (RSAOpenSsl? rsa = (RSAOpenSsl?)cert.GetRSAPrivateKey())
- {
- if (rsa != null)
- {
- _certKeyHandle = rsa.DuplicateKeyHandle();
- Interop.Crypto.CheckValidOpenSslHandle(_certKeyHandle);
- }
- }
-
- if (_certKeyHandle == null)
- {
- using (ECDsaOpenSsl? ecdsa = (ECDsaOpenSsl?)cert.GetECDsaPrivateKey())
- {
- if (ecdsa != null)
- {
- _certKeyHandle = ecdsa.DuplicateKeyHandle();
- Interop.Crypto.CheckValidOpenSslHandle(_certKeyHandle);
- }
- }
- }
-
- if (_certKeyHandle == null)
- {
- throw new NotSupportedException(SR.net_ssl_io_no_server_cert);
- }
-
- _certHandle = Interop.Crypto.X509UpRef(cert.Handle);
- Interop.Crypto.CheckValidOpenSslHandle(_certHandle);
- }
-
- _protocols = protocols;
- _policy = policy;
- _context = context;
- }
-
- public override bool IsInvalid
- {
- get { return _isInvalid; }
- }
-
- protected override bool ReleaseHandle()
- {
- _certHandle?.Dispose();
- _certKeyHandle?.Dispose();
-
- _isInvalid = true;
- return true;
- }
- }
-}
diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj
index c586e4e9c9a758..fb6b48dd4fb1fe 100644
--- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj
+++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj
@@ -366,8 +366,6 @@
Link="Common\System\Net\Security\Unix\SafeDeleteSslContext.cs" />
-
-
@@ -416,7 +413,6 @@
-
diff --git a/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Unix.cs b/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Unix.cs
index 7e68a7c7f35c07..498a095410376a 100644
--- a/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Unix.cs
+++ b/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.Unix.cs
@@ -58,7 +58,7 @@ internal static SslPolicyErrors VerifyCertificateProperties(
}
using (SafeSharedX509StackHandle chainStack =
- Interop.OpenSsl.GetPeerCertificateChain(((SafeDeleteSslContext)securityContext).SslContext))
+ Interop.OpenSsl.GetPeerCertificateChain((SafeSslHandle)securityContext))
{
if (!chainStack.IsInvalid)
{
@@ -106,7 +106,7 @@ internal static SslPolicyErrors VerifyCertificateProperties(
//
internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext)
{
- using (SafeSharedX509NameStackHandle names = Interop.Ssl.SslGetClientCAList(((SafeDeleteSslContext)securityContext).SslContext))
+ using (SafeSharedX509NameStackHandle names = Interop.Ssl.SslGetClientCAList((SafeSslHandle)securityContext))
{
if (names.IsInvalid)
{
@@ -160,7 +160,7 @@ private static int QueryContextRemoteCertificate(SafeDeleteContext securityConte
remoteCertContext = null;
try
{
- SafeX509Handle remoteCertificate = Interop.OpenSsl.GetPeerCertificate(((SafeDeleteSslContext)securityContext).SslContext);
+ SafeX509Handle remoteCertificate = Interop.OpenSsl.GetPeerCertificate((SafeSslHandle)securityContext);
// Note that cert ownership is transferred to SafeFreeCertContext
remoteCertContext = new SafeFreeCertContext(remoteCertificate);
return 0;
diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs
index d653d56f115314..e4a2ee35c53d85 100644
--- a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs
+++ b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Android/SafeDeleteSslContext.cs
@@ -36,15 +36,13 @@ internal sealed class SafeDeleteSslContext : SafeDeleteContext
public SafeSslHandle SslContext => _sslContext;
- public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions authOptions)
- : base(credential)
+ public SafeDeleteSslContext(SslAuthenticationOptions authOptions)
+ : base(IntPtr.Zero)
{
- Debug.Assert((credential != null) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext");
-
try
{
- _sslContext = CreateSslContext(credential);
- InitializeSslContext(_sslContext, credential, authOptions);
+ _sslContext = CreateSslContext(authOptions);
+ InitializeSslContext(_sslContext, authOptions);
}
catch (Exception ex)
{
@@ -147,14 +145,14 @@ internal int ReadPendingWrites(byte[] buf, int offset, int count)
return limit;
}
- private static SafeSslHandle CreateSslContext(SafeFreeSslCredentials credential)
+ private static SafeSslHandle CreateSslContext(SslAuthenticationOptions authOptions)
{
- if (credential.CertificateContext == null)
+ if (authOptions.CertificateContext == null)
{
return Interop.AndroidCrypto.SSLStreamCreate();
}
- SslStreamCertificateContext context = credential.CertificateContext;
+ SslStreamCertificateContext context = authOptions.CertificateContext;
X509Certificate2 cert = context.Certificate;
Debug.Assert(context.Certificate.HasPrivateKey);
@@ -199,10 +197,9 @@ private static AsymmetricAlgorithm GetPrivateKeyAlgorithm(X509Certificate2 cert,
private unsafe void InitializeSslContext(
SafeSslHandle handle,
- SafeFreeSslCredentials credential,
SslAuthenticationOptions authOptions)
{
- switch (credential.Policy)
+ switch (authOptions.EncryptionPolicy)
{
case EncryptionPolicy.RequireEncryption:
#pragma warning disable SYSLIB0040 // NoEncryption and AllowNoEncryption are obsolete
@@ -210,7 +207,7 @@ private unsafe void InitializeSslContext(
break;
#pragma warning restore SYSLIB0040
default:
- throw new PlatformNotSupportedException(SR.Format(SR.net_encryptionpolicy_notsupported, credential.Policy));
+ throw new PlatformNotSupportedException(SR.Format(SR.net_encryptionpolicy_notsupported, authOptions.EncryptionPolicy));
}
bool isServer = authOptions.IsServer;
@@ -226,12 +223,12 @@ private unsafe void InitializeSslContext(
IntPtr managedContextHandle = GCHandle.ToIntPtr(GCHandle.Alloc(this, GCHandleType.Weak));
Interop.AndroidCrypto.SSLStreamInitialize(handle, isServer, managedContextHandle, &ReadFromConnection, &WriteToConnection, InitialBufferSize);
- if (credential.Protocols != SslProtocols.None)
+ if (authOptions.EnabledSslProtocols != SslProtocols.None)
{
- SslProtocols protocolsToEnable = credential.Protocols & s_supportedSslProtocols.Value;
+ SslProtocols protocolsToEnable = authOptions.EnabledSslProtocols & s_supportedSslProtocols.Value;
if (protocolsToEnable == 0)
{
- throw new PlatformNotSupportedException(SR.Format(SR.net_security_sslprotocol_notsupported, credential.Protocols));
+ throw new PlatformNotSupportedException(SR.Format(SR.net_security_sslprotocol_notsupported, authOptions.EnabledSslProtocols));
}
(int minIndex, int maxIndex) = protocolsToEnable.ValidateContiguous(s_orderedSslProtocols);
diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SafeFreeSslCredentials.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SafeFreeSslCredentials.cs
deleted file mode 100644
index 24a4e7be7843a6..00000000000000
--- a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.Managed/SafeFreeSslCredentials.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Diagnostics;
-using System.Net.Security;
-using System.Security.Authentication;
-using System.Security.Cryptography.X509Certificates;
-
-namespace System.Net
-{
- internal sealed class SafeFreeSslCredentials : SafeFreeCredentials
- {
- public SafeFreeSslCredentials(SslStreamCertificateContext? certificateContext, SslProtocols protocols, EncryptionPolicy policy)
- : base(IntPtr.Zero, true)
- {
- if (certificateContext != null)
- {
- // Make a defensive copy of the certificate. In some async cases the
- // certificate can have been disposed before being provided to the handshake.
- //
- // This meshes with the Unix (OpenSSL) PAL, because it extracts the private key
- // and cert handle (which get up-reffed) to match the API expectations.
- certificateContext = certificateContext.Duplicate();
-
- Debug.Assert(certificateContext.Certificate.HasPrivateKey, "cert clone.HasPrivateKey");
- }
-
- CertificateContext = certificateContext;
- Protocols = protocols;
- Policy = policy;
- }
-
- public EncryptionPolicy Policy { get; }
-
- public SslProtocols Protocols { get; }
-
- public SslStreamCertificateContext? CertificateContext { get; }
-
- public override bool IsInvalid => false;
-
- protected override bool ReleaseHandle()
- {
- CertificateContext?.Certificate.Dispose();
- return true;
- }
- }
-}
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 bb4f84ce8de8ff..fd86353ed1fa58 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
@@ -25,16 +25,14 @@ internal sealed class SafeDeleteSslContext : SafeDeleteContext
public SafeSslHandle SslContext => _sslContext;
- public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions)
- : base(credential)
+ public SafeDeleteSslContext(SslAuthenticationOptions sslAuthenticationOptions)
+ : base(IntPtr.Zero)
{
- Debug.Assert((null != credential) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext");
-
try
{
int osStatus;
- _sslContext = CreateSslContext(credential, sslAuthenticationOptions);
+ _sslContext = CreateSslContext(sslAuthenticationOptions);
// Make sure the class instance is associated to the session and is provided
// in the Read/Write callback connection parameter
@@ -129,9 +127,9 @@ public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthentication
}
}
- private static SafeSslHandle CreateSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions)
+ private static SafeSslHandle CreateSslContext(SslAuthenticationOptions sslAuthenticationOptions)
{
- switch (credential.Policy)
+ switch (sslAuthenticationOptions.EncryptionPolicy)
{
case EncryptionPolicy.RequireEncryption:
#pragma warning disable SYSLIB0040 // NoEncryption and AllowNoEncryption are obsolete
@@ -142,7 +140,7 @@ private static SafeSslHandle CreateSslContext(SafeFreeSslCredentials credential,
break;
#pragma warning restore SYSLIB0040
default:
- throw new PlatformNotSupportedException(SR.Format(SR.net_encryptionpolicy_notsupported, credential.Policy));
+ throw new PlatformNotSupportedException(SR.Format(SR.net_encryptionpolicy_notsupported, sslAuthenticationOptions.EncryptionPolicy));
}
SafeSslHandle sslContext = Interop.AppleCrypto.SslCreateContext(sslAuthenticationOptions.IsServer ? 1 : 0);
diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs
index 4f9a09347b7454..ac8db67ba27753 100644
--- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs
+++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs
@@ -687,11 +687,11 @@ private bool AcquireServerCredentials(ref byte[]? thumbPrint)
return cachedCred;
}
- private static SafeFreeCredentials AcquireCredentialsHandle(SslAuthenticationOptions sslAuthenticationOptions)
+ private static SafeFreeCredentials? AcquireCredentialsHandle(SslAuthenticationOptions sslAuthenticationOptions)
{
- SafeFreeCredentials cred = SslStreamPal.AcquireCredentialsHandle(sslAuthenticationOptions);
+ SafeFreeCredentials? cred = SslStreamPal.AcquireCredentialsHandle(sslAuthenticationOptions);
- if (sslAuthenticationOptions.CertificateContext != null)
+ if (sslAuthenticationOptions.CertificateContext != null && cred != null)
{
//
// Since the SafeFreeCredentials can be cached and reused, it may happen on long running processes that some cert on
@@ -869,6 +869,8 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan inputBuffer, ref byte
internal SecurityStatusPal Renegotiate(out byte[]? output)
{
+ Debug.Assert(_securityContext != null);
+
return SslStreamPal.Renegotiate(
ref _credentialsHandle!,
ref _securityContext,
diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs
index dedea329f240eb..fdc98705d426b2 100644
--- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs
+++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs
@@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Authentication;
+using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
@@ -17,6 +18,8 @@ public partial class SslStreamCertificateContext
{
private const bool TrimRootCertificate = true;
internal readonly ConcurrentDictionary SslContexts;
+ internal readonly SafeX509Handle CertificateHandle;
+ internal readonly SafeEvpPKeyHandle KeyHandle;
private bool _staplingForbidden;
private byte[]? _ocspResponse;
@@ -32,6 +35,32 @@ private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[]
IntermediateCertificates = intermediates;
Trust = trust;
SslContexts = new ConcurrentDictionary();
+
+ using (RSAOpenSsl? rsa = (RSAOpenSsl?)target.GetRSAPrivateKey())
+ {
+ if (rsa != null)
+ {
+ KeyHandle = rsa.DuplicateKeyHandle();
+ }
+ }
+
+ if (KeyHandle == null)
+ {
+ using (ECDsaOpenSsl? ecdsa = (ECDsaOpenSsl?)target.GetECDsaPrivateKey())
+ {
+ if (ecdsa != null)
+ {
+ KeyHandle = ecdsa.DuplicateKeyHandle();
+ }
+ }
+
+ if (KeyHandle== null)
+ {
+ throw new NotSupportedException(SR.net_ssl_io_no_server_cert);
+ }
+ }
+
+ CertificateHandle = Interop.Crypto.X509UpRef(target.Handle);
}
internal static SslStreamCertificateContext Create(X509Certificate2 target) =>
diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Android.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Android.cs
index 11889b0836f8c0..f01dd68e294b2d 100644
--- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Android.cs
+++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Android.cs
@@ -55,12 +55,9 @@ public static SecurityStatusPal Renegotiate(
throw new PlatformNotSupportedException();
}
- public static SafeFreeCredentials AcquireCredentialsHandle(SslAuthenticationOptions sslAuthenticationOptions)
+ public static SafeFreeCredentials? AcquireCredentialsHandle(SslAuthenticationOptions sslAuthenticationOptions)
{
- return new SafeFreeSslCredentials(
- sslAuthenticationOptions.CertificateContext,
- sslAuthenticationOptions.EnabledSslProtocols,
- sslAuthenticationOptions.EncryptionPolicy);
+ return null;
}
public static SecurityStatusPal EncryptMessage(
@@ -177,15 +174,13 @@ private static SecurityStatusPal HandshakeInternal(
ref byte[]? outputBuffer,
SslAuthenticationOptions sslAuthenticationOptions)
{
- Debug.Assert(!credential.IsInvalid);
-
try
{
SafeDeleteSslContext? sslContext = ((SafeDeleteSslContext?)context);
if ((context == null) || context.IsInvalid)
{
- context = new SafeDeleteSslContext((credential as SafeFreeSslCredentials)!, sslAuthenticationOptions);
+ context = new SafeDeleteSslContext(sslAuthenticationOptions);
sslContext = context;
}
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 5c96b2550ce821..255b30d7f2c2fe 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
@@ -62,12 +62,9 @@ public static SecurityStatusPal Renegotiate(
throw new PlatformNotSupportedException();
}
- public static SafeFreeCredentials AcquireCredentialsHandle(SslAuthenticationOptions sslAuthenticationOptions)
+ public static SafeFreeCredentials? AcquireCredentialsHandle(SslAuthenticationOptions sslAuthenticationOptions)
{
- return new SafeFreeSslCredentials(
- sslAuthenticationOptions.CertificateContext,
- sslAuthenticationOptions.EnabledSslProtocols,
- sslAuthenticationOptions.EncryptionPolicy);
+ return null;
}
public static SecurityStatusPal EncryptMessage(
@@ -227,15 +224,13 @@ private static SecurityStatusPal HandshakeInternal(
SslAuthenticationOptions sslAuthenticationOptions,
SelectClientCertificate? clientCertificateSelectionCallback)
{
- Debug.Assert(!credential.IsInvalid);
-
try
{
SafeDeleteSslContext? sslContext = ((SafeDeleteSslContext?)context);
if ((null == context) || context.IsInvalid)
{
- sslContext = new SafeDeleteSslContext((credential as SafeFreeSslCredentials)!, sslAuthenticationOptions);
+ sslContext = new SafeDeleteSslContext(sslAuthenticationOptions);
context = sslContext;
}
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 7a4f5a67f0fa94..1e1a0df55889e9 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
@@ -31,7 +31,7 @@ public static SecurityStatusPal AcceptSecurityContext(
ref byte[]? outputBuffer,
SslAuthenticationOptions sslAuthenticationOptions)
{
- return HandshakeInternal(credential!, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions, null);
+ return HandshakeInternal(ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions, null);
}
public static SecurityStatusPal InitializeSecurityContext(
@@ -43,23 +43,19 @@ public static SecurityStatusPal InitializeSecurityContext(
SslAuthenticationOptions sslAuthenticationOptions,
SelectClientCertificate? clientCertificateSelectionCallback)
{
- return HandshakeInternal(credential!, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions, clientCertificateSelectionCallback);
+ return HandshakeInternal(ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions, clientCertificateSelectionCallback);
}
- public static SafeFreeCredentials AcquireCredentialsHandle(SslAuthenticationOptions sslAuthenticationOptions)
+ public static SafeFreeCredentials? AcquireCredentialsHandle(SslAuthenticationOptions sslAuthenticationOptions)
{
- return new SafeFreeSslCredentials(
- sslAuthenticationOptions.CertificateContext,
- sslAuthenticationOptions.EnabledSslProtocols,
- sslAuthenticationOptions.EncryptionPolicy,
- sslAuthenticationOptions.IsServer);
+ return null;
}
public static SecurityStatusPal EncryptMessage(SafeDeleteSslContext securityContext, ReadOnlyMemory input, int headerSize, int trailerSize, ref byte[] output, out int resultSize)
{
try
{
- resultSize = Interop.OpenSsl.Encrypt(securityContext.SslContext, input.Span, ref output, out Interop.Ssl.SslErrorCode errorCode);
+ resultSize = Interop.OpenSsl.Encrypt((SafeSslHandle)securityContext, input.Span, ref output, out Interop.Ssl.SslErrorCode errorCode);
return MapNativeErrorCode(errorCode);
}
@@ -77,7 +73,7 @@ public static SecurityStatusPal DecryptMessage(SafeDeleteSslContext securityCont
try
{
- int resultSize = Interop.OpenSsl.Decrypt(securityContext.SslContext, buffer, out Interop.Ssl.SslErrorCode errorCode);
+ int resultSize = Interop.OpenSsl.Decrypt((SafeSslHandle)securityContext, buffer, out Interop.Ssl.SslErrorCode errorCode);
SecurityStatusPal retVal = MapNativeErrorCode(errorCode);
@@ -122,7 +118,7 @@ Interop.Ssl.SslErrorCode.SSL_ERROR_NONE or
else
{
bindingHandle = Interop.OpenSsl.QueryChannelBinding(
- securityContext.SslContext,
+ (SafeSslHandle)securityContext,
attribute);
}
@@ -131,19 +127,18 @@ Interop.Ssl.SslErrorCode.SSL_ERROR_NONE or
public static SecurityStatusPal Renegotiate(
ref SafeFreeCredentials? credentialsHandle,
- ref SafeDeleteSslContext? securityContext,
+ ref SafeDeleteSslContext context,
SslAuthenticationOptions sslAuthenticationOptions,
out byte[]? outputBuffer)
{
- var sslContext = ((SafeDeleteSslContext)securityContext!).SslContext;
- SecurityStatusPal status = Interop.OpenSsl.SslRenegotiate(sslContext, out _);
+ SecurityStatusPal status = Interop.OpenSsl.SslRenegotiate((SafeSslHandle)context, out _);
outputBuffer = Array.Empty();
if (status.ErrorCode != SecurityStatusPalErrorCode.OK)
{
return status;
}
- return HandshakeInternal(credentialsHandle!, ref securityContext, null, ref outputBuffer, sslAuthenticationOptions, null);
+ return HandshakeInternal(ref context!, null, ref outputBuffer, sslAuthenticationOptions, null);
}
public static void QueryContextStreamSizes(SafeDeleteContext? securityContext, out StreamSizes streamSizes)
@@ -153,14 +148,12 @@ public static void QueryContextStreamSizes(SafeDeleteContext? securityContext, o
public static void QueryContextConnectionInfo(SafeDeleteSslContext securityContext, ref SslConnectionInfo connectionInfo)
{
- connectionInfo.UpdateSslConnectionInfo(securityContext.SslContext);
+ connectionInfo.UpdateSslConnectionInfo((SafeSslHandle)securityContext);
}
- private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteSslContext? context,
+ private static SecurityStatusPal HandshakeInternal(ref SafeDeleteSslContext? context,
ReadOnlySpan inputBuffer, ref byte[]? outputBuffer, SslAuthenticationOptions sslAuthenticationOptions, SelectClientCertificate? clientCertificateSelectionCallback)
{
- Debug.Assert(!credential.IsInvalid);
-
byte[]? output = null;
int outputSize = 0;
@@ -168,10 +161,10 @@ private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credentia
{
if ((null == context) || context.IsInvalid)
{
- context = new SafeDeleteSslContext((credential as SafeFreeSslCredentials)!, sslAuthenticationOptions);
+ context = Interop.OpenSsl.AllocateSslHandle(sslAuthenticationOptions);
}
- SecurityStatusPalErrorCode errorCode = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, inputBuffer, out output, out outputSize);
+ SecurityStatusPalErrorCode errorCode = Interop.OpenSsl.DoSslHandshake((SafeSslHandle)context, inputBuffer, out output, out outputSize);
if (errorCode == SecurityStatusPalErrorCode.CredentialsNeeded && clientCertificateSelectionCallback != null)
{
@@ -181,22 +174,22 @@ private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credentia
sslAuthenticationOptions.CertificateContext = SslStreamCertificateContext.Create(clientCertificate);
}
- Interop.OpenSsl.UpdateClientCertiticate(((SafeDeleteSslContext)context).SslContext, sslAuthenticationOptions);
- errorCode = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, null, out output, out outputSize);
+ Interop.OpenSsl.UpdateClientCertiticate((SafeSslHandle)context, sslAuthenticationOptions);
+ errorCode = Interop.OpenSsl.DoSslHandshake((SafeSslHandle)context, null, out output, out outputSize);
}
// sometimes during renegotiation processing message 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))
+ if (outputSize == 0 && Interop.Ssl.IsSslRenegotiatePending((SafeSslHandle)context))
{
- errorCode = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, ReadOnlySpan.Empty, out output, out outputSize);
+ errorCode = Interop.OpenSsl.DoSslHandshake((SafeSslHandle)context, 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.
// If it was, then that indicates ALPN failed, send failure.
// 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;
+ SafeSslHandle sslContext = (SafeSslHandle)context;
if (errorCode == SecurityStatusPalErrorCode.OK && sslAuthenticationOptions.IsServer
&& sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0
&& sslContext.AlpnHandle.IsAllocated && sslContext.AlpnHandle.Target == null)
@@ -231,22 +224,22 @@ public static SecurityStatusPal ApplyAlertToken(ref SafeFreeCredentials? credent
return new SecurityStatusPal(SecurityStatusPalErrorCode.OK);
}
- public static SecurityStatusPal ApplyShutdownToken(ref SafeFreeCredentials? credentialsHandle, SafeDeleteSslContext sslContext)
+ public static SecurityStatusPal ApplyShutdownToken(ref SafeFreeCredentials? credentialsHandle, SafeDeleteSslContext context)
{
// Unset the quiet shutdown option initially configured.
- Interop.Ssl.SslSetQuietShutdown(sslContext.SslContext, 0);
+ Interop.Ssl.SslSetQuietShutdown((SafeSslHandle)context, 0);
- int status = Interop.Ssl.SslShutdown(sslContext.SslContext);
+ int status = Interop.Ssl.SslShutdown((SafeSslHandle)context);
if (status == 0)
{
// Call SSL_shutdown again for a bi-directional shutdown.
- status = Interop.Ssl.SslShutdown(sslContext.SslContext);
+ status = Interop.Ssl.SslShutdown((SafeSslHandle)context);
}
if (status == 1)
return new SecurityStatusPal(SecurityStatusPalErrorCode.OK);
- Interop.Ssl.SslErrorCode code = Interop.Ssl.SslGetError(sslContext.SslContext, status);
+ Interop.Ssl.SslErrorCode code = Interop.Ssl.SslGetError((SafeSslHandle)context, status);
if (code == Interop.Ssl.SslErrorCode.SSL_ERROR_WANT_READ ||
code == Interop.Ssl.SslErrorCode.SSL_ERROR_WANT_WRITE)
{