You've already forked linux-packaging-mono
Imported Upstream version 5.10.0.69
Former-commit-id: fc39669a0b707dd3c063977486506b6793da2890
This commit is contained in:
parent
d8f8abd549
commit
e2950ec768
@@ -1,6 +1,6 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26923.0
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.Security.Tests", "tests\FunctionalTests\System.Net.Security.Tests.csproj", "{A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
@@ -35,10 +35,10 @@ Global
|
||||
{A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Debug|Any CPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Release|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{A55A2B9A-830F-4330-A0E7-02A9FB30ABD2}.Release|Any CPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{0D174EA9-9E61-4519-8D31-7BD2331A1982}.Debug|Any CPU.ActiveCfg = netstandard-Windows_NT-Debug|Any CPU
|
||||
{0D174EA9-9E61-4519-8D31-7BD2331A1982}.Debug|Any CPU.Build.0 = netstandard-Windows_NT-Debug|Any CPU
|
||||
{0D174EA9-9E61-4519-8D31-7BD2331A1982}.Release|Any CPU.ActiveCfg = netstandard-Windows_NT-Release|Any CPU
|
||||
{0D174EA9-9E61-4519-8D31-7BD2331A1982}.Release|Any CPU.Build.0 = netstandard-Windows_NT-Release|Any CPU
|
||||
{0D174EA9-9E61-4519-8D31-7BD2331A1982}.Debug|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{0D174EA9-9E61-4519-8D31-7BD2331A1982}.Debug|Any CPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{0D174EA9-9E61-4519-8D31-7BD2331A1982}.Release|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{0D174EA9-9E61-4519-8D31-7BD2331A1982}.Release|Any CPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU
|
||||
{89F37791-6254-4D60-AB96-ACD3CCA0E771}.Debug|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{89F37791-6254-4D60-AB96-ACD3CCA0E771}.Debug|Any CPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
|
||||
{89F37791-6254-4D60-AB96-ACD3CCA0E771}.Release|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
|
||||
@@ -57,7 +57,4 @@ Global
|
||||
{89F37791-6254-4D60-AB96-ACD3CCA0E771} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD}
|
||||
{A7488FC0-9A8F-4EF9-BC3E-C5EBA47E13F8} = {2E666815-2EDB-464B-9DF6-380BF4789AD4}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {72DFF69F-F9E9-4112-91E8-5FC8169B6F1F}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
// Changes to this file must follow the http://aka.ms/api-review process.
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.Net.Security
|
||||
{
|
||||
@@ -94,6 +99,48 @@ namespace System.Net.Security
|
||||
EncryptAndSign = 2
|
||||
}
|
||||
public delegate bool RemoteCertificateValidationCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors);
|
||||
public class SslServerAuthenticationOptions
|
||||
{
|
||||
public bool AllowRenegotiation { get { throw null; } set { } }
|
||||
public X509Certificate ServerCertificate { get { throw null; } set { } }
|
||||
public bool ClientCertificateRequired { get { throw null; } set { } }
|
||||
public SslProtocols EnabledSslProtocols { get { throw null; } set { } }
|
||||
public X509RevocationMode CertificateRevocationCheckMode { get { throw null; } set { } }
|
||||
public List<SslApplicationProtocol> ApplicationProtocols { get { throw null; } set { } }
|
||||
public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get { throw null; } set { } }
|
||||
public EncryptionPolicy EncryptionPolicy { get { throw null; } set { } }
|
||||
}
|
||||
public partial class SslClientAuthenticationOptions
|
||||
{
|
||||
public bool AllowRenegotiation { get { throw null; } set { } }
|
||||
public string TargetHost { get { throw null; } set { } }
|
||||
public X509CertificateCollection ClientCertificates { get { throw null; } set { } }
|
||||
public LocalCertificateSelectionCallback LocalCertificateSelectionCallback { get { throw null; } set { } }
|
||||
public SslProtocols EnabledSslProtocols { get { throw null; } set { } }
|
||||
public X509RevocationMode CertificateRevocationCheckMode { get { throw null; } set { } }
|
||||
public List<SslApplicationProtocol> ApplicationProtocols { get { throw null; } set { } }
|
||||
public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get { throw null; } set { } }
|
||||
public EncryptionPolicy EncryptionPolicy { get { throw null; } set { } }
|
||||
}
|
||||
public readonly partial struct SslApplicationProtocol : IEquatable<SslApplicationProtocol>
|
||||
{
|
||||
private readonly object _dummy;
|
||||
|
||||
public static readonly SslApplicationProtocol Http2;
|
||||
public static readonly SslApplicationProtocol Http11;
|
||||
|
||||
public SslApplicationProtocol(byte[] protocol) { throw null; }
|
||||
public SslApplicationProtocol(string protocol) { throw null; }
|
||||
|
||||
public ReadOnlyMemory<byte> Protocol { get { throw null; } }
|
||||
|
||||
public bool Equals(SslApplicationProtocol other) { throw null; }
|
||||
public override bool Equals(object obj) { throw null; }
|
||||
public override int GetHashCode() { throw null; }
|
||||
public override string ToString() { throw null; }
|
||||
public static bool operator ==(SslApplicationProtocol left, SslApplicationProtocol right) { throw null; }
|
||||
public static bool operator !=(SslApplicationProtocol left, SslApplicationProtocol right) { throw null; }
|
||||
}
|
||||
public partial class SslStream : AuthenticatedStream
|
||||
{
|
||||
public SslStream(System.IO.Stream innerStream) : base(innerStream, false) { }
|
||||
@@ -101,6 +148,7 @@ namespace System.Net.Security
|
||||
public SslStream(System.IO.Stream innerStream, bool leaveInnerStreamOpen, System.Net.Security.RemoteCertificateValidationCallback userCertificateValidationCallback) : base(innerStream, leaveInnerStreamOpen) { }
|
||||
public SslStream(System.IO.Stream innerStream, bool leaveInnerStreamOpen, System.Net.Security.RemoteCertificateValidationCallback userCertificateValidationCallback, System.Net.Security.LocalCertificateSelectionCallback userCertificateSelectionCallback) : base(innerStream, leaveInnerStreamOpen) { }
|
||||
public SslStream(System.IO.Stream innerStream, bool leaveInnerStreamOpen, System.Net.Security.RemoteCertificateValidationCallback userCertificateValidationCallback, System.Net.Security.LocalCertificateSelectionCallback userCertificateSelectionCallback, System.Net.Security.EncryptionPolicy encryptionPolicy) : base(innerStream, leaveInnerStreamOpen) { }
|
||||
public SslApplicationProtocol NegotiatedApplicationProtocol { get { throw null; } }
|
||||
public override bool CanRead { get { throw null; } }
|
||||
public override bool CanSeek { get { throw null; } }
|
||||
public override bool CanTimeout { get { throw null; } }
|
||||
@@ -134,9 +182,11 @@ namespace System.Net.Security
|
||||
public virtual System.Threading.Tasks.Task AuthenticateAsClientAsync(string targetHost) { throw null; }
|
||||
public virtual System.Threading.Tasks.Task AuthenticateAsClientAsync(string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, bool checkCertificateRevocation) { throw null; }
|
||||
public virtual System.Threading.Tasks.Task AuthenticateAsClientAsync(string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, bool checkCertificateRevocation) { throw null; }
|
||||
public Task AuthenticateAsClientAsync(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken) { throw null; }
|
||||
public virtual System.Threading.Tasks.Task AuthenticateAsServerAsync(System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate) { throw null; }
|
||||
public virtual System.Threading.Tasks.Task AuthenticateAsServerAsync(System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, bool clientCertificateRequired, System.Security.Authentication.SslProtocols enabledSslProtocols, bool checkCertificateRevocation) { throw null; }
|
||||
public virtual System.Threading.Tasks.Task AuthenticateAsServerAsync(System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, bool clientCertificateRequired, bool checkCertificateRevocation) { throw null; }
|
||||
public Task AuthenticateAsServerAsync(SslServerAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken) { throw null; }
|
||||
public virtual System.IAsyncResult BeginAuthenticateAsClient(string targetHost, System.AsyncCallback asyncCallback, object asyncState) { throw null; }
|
||||
public virtual System.IAsyncResult BeginAuthenticateAsClient(string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, bool checkCertificateRevocation, System.AsyncCallback asyncCallback, object asyncState) { throw null; }
|
||||
public virtual System.IAsyncResult BeginAuthenticateAsClient(string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, bool checkCertificateRevocation, System.AsyncCallback asyncCallback, object asyncState) { throw null; }
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\System.Collections.NonGeneric\ref\System.Collections.NonGeneric.csproj" />
|
||||
<ProjectReference Include="..\..\System.Collections\ref\System.Collections.csproj" />
|
||||
<ProjectReference Include="..\..\System.IO\ref\System.IO.csproj" />
|
||||
<ProjectReference Include="..\..\System.Net.Primitives\ref\System.Net.Primitives.csproj" />
|
||||
<ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" />
|
||||
@@ -21,5 +22,8 @@
|
||||
<ProjectReference Include="..\..\System.Security.Principal\ref\System.Security.Principal.csproj" />
|
||||
<ProjectReference Include="..\..\System.Threading.Tasks\ref\System.Threading.Tasks.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Memory" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
@@ -1,5 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
@@ -70,9 +129,6 @@
|
||||
<data name="net_MethodNotImplementedException" xml:space="preserve">
|
||||
<value>This method is not implemented by this class.</value>
|
||||
</data>
|
||||
<data name="net_completed_result" xml:space="preserve">
|
||||
<value>This operation cannot be performed on a completed asynchronous result object.</value>
|
||||
</data>
|
||||
<data name="net_io_readfailure" xml:space="preserve">
|
||||
<value>Unable to read data from the transport connection: {0}.</value>
|
||||
</data>
|
||||
@@ -115,6 +171,9 @@
|
||||
<data name="net_ssl_io_frame" xml:space="preserve">
|
||||
<value>The handshake failed due to an unexpected packet format.</value>
|
||||
</data>
|
||||
<data name="net_ssl_io_renego" xml:space="preserve">
|
||||
<value>The remote party requested renegotiation when AllowRenegotiation was set to false.</value>
|
||||
</data>
|
||||
<data name="net_ssl_io_cert_validation" xml:space="preserve">
|
||||
<value>The remote certificate is invalid according to the validation procedure.</value>
|
||||
</data>
|
||||
@@ -295,9 +354,6 @@
|
||||
<data name="net_ssl_encrypt_failed" xml:space="preserve">
|
||||
<value>Encrypt failed with OpenSSL error - {0}.</value>
|
||||
</data>
|
||||
<data name="net_get_ssl_method_failed" xml:space="preserve">
|
||||
<value>Failed to get SSL method '{0}'. Ensure the OpenSSL method exists on the current system.</value>
|
||||
</data>
|
||||
<data name="net_ssl_check_private_key_failed" xml:space="preserve">
|
||||
<value>SSL certificate private key check failed with OpenSSL error - {0}.</value>
|
||||
</data>
|
||||
@@ -355,10 +411,25 @@
|
||||
<data name="net_nego_not_supported_empty_target_with_defaultcreds" xml:space="preserve">
|
||||
<value>Target name should be non empty if default credentials are passed.</value>
|
||||
</data>
|
||||
<data name="net_security_sslprotocol_contiguous">
|
||||
<data name="net_security_sslprotocol_contiguous" xml:space="preserve">
|
||||
<value>The requested combination of SslProtocols ({0}) is not valid for this platform because it skips intermediate versions.</value>
|
||||
</data>
|
||||
<data name="net_encryptionpolicy_notsupported" xml:space="preserve">
|
||||
<value>The '{0}' encryption policy is not supported on this platform.</value>
|
||||
</data>
|
||||
<data name="net_alpn_config_failed" xml:space="preserve">
|
||||
<value>ALPN configuration failed on this platform.</value>
|
||||
</data>
|
||||
<data name="net_alpn_failed" xml:space="preserve">
|
||||
<value>No common application protocol exists between the client and the server. Application negotiation failed.</value>
|
||||
</data>
|
||||
<data name="net_ssl_app_protocols_invalid" xml:space="preserve">
|
||||
<value>The application protocol list is invalid.</value>
|
||||
</data>
|
||||
<data name="net_ssl_app_protocol_invalid" xml:space="preserve">
|
||||
<value>The application protocol value is invalid.</value>
|
||||
</data>
|
||||
<data name="net_conflicting_options" xml:space="preserve">
|
||||
<value>The '{0}' option was already set in the SslStream constructor.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
<Compile Include="System\Net\FixedSizeReader.cs" />
|
||||
<Compile Include="System\Net\HelperAsyncResults.cs" />
|
||||
<Compile Include="System\Net\Logging\NetEventSource.cs" />
|
||||
<Compile Include="System\Net\Security\SslApplicationProtocol.cs" />
|
||||
<Compile Include="System\Net\Security\SslAuthenticationOptions.cs" />
|
||||
<Compile Include="System\Net\Security\SslClientAuthenticationOptions.cs" />
|
||||
<Compile Include="System\Net\Security\SslServerAuthenticationOptions.cs" />
|
||||
<Compile Include="System\Net\Security\SslStreamInternal.Adapters.cs" />
|
||||
<Compile Include="System\Net\SslStreamContext.cs" />
|
||||
<Compile Include="System\Net\Security\AuthenticatedStream.cs" />
|
||||
@@ -161,6 +165,12 @@
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\SChannel\SecPkgContext_ConnectionInfo.cs">
|
||||
<Link>Common\Interop\Windows\SChannel\SecPkgContext_ConnectionInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs">
|
||||
<Link>Common\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\SChannel\Interop.Sec_Application_Protocols.cs">
|
||||
<Link>Common\Interop\Windows\SChannel\Interop.Sec_Application_Protocols.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\SChannel\UnmanagedCertificateContext.cs">
|
||||
<Link>Common\Interop\Windows\SChannel\UnmanagedCertificateContext.cs</Link>
|
||||
</Compile>
|
||||
@@ -396,6 +406,7 @@
|
||||
<Reference Include="System.Collections.NonGeneric" />
|
||||
<Reference Include="System.Diagnostics.Debug" />
|
||||
<Reference Include="System.Diagnostics.Tracing" />
|
||||
<Reference Include="System.Memory" />
|
||||
<Reference Include="System.Net.Primitives" />
|
||||
<Reference Include="System.Resources.ResourceManager" />
|
||||
<Reference Include="System.Runtime" />
|
||||
@@ -416,4 +427,4 @@
|
||||
<Reference Include="System.Security.Cryptography.Primitives" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace System.Net
|
||||
|
||||
public SafeSslHandle SslContext => _sslContext;
|
||||
|
||||
public SafeDeleteSslContext(SafeFreeSslCredentials credential, bool isServer)
|
||||
public SafeDeleteSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions)
|
||||
: base(credential)
|
||||
{
|
||||
Debug.Assert((null != credential) && !credential.IsInvalid, "Invalid credential used in SafeDeleteSslContext");
|
||||
@@ -35,7 +35,7 @@ namespace System.Net
|
||||
_writeCallback = WriteToConnection;
|
||||
}
|
||||
|
||||
_sslContext = CreateSslContext(credential, isServer);
|
||||
_sslContext = CreateSslContext(credential, sslAuthenticationOptions.IsServer);
|
||||
|
||||
int osStatus = Interop.AppleCrypto.SslSetIoCallbacks(
|
||||
_sslContext,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
140
external/corefx/src/System.Net.Security/src/System/Net/Security/SslApplicationProtocol.cs
vendored
Normal file
140
external/corefx/src/System.Net.Security/src/System/Net/Security/SslApplicationProtocol.cs
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Text;
|
||||
|
||||
namespace System.Net.Security
|
||||
{
|
||||
public readonly struct SslApplicationProtocol : IEquatable<SslApplicationProtocol>
|
||||
{
|
||||
private readonly ReadOnlyMemory<byte> _readOnlyProtocol;
|
||||
private static readonly Encoding s_utf8 = Encoding.GetEncoding(Encoding.UTF8.CodePage, EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback);
|
||||
|
||||
// Refer IANA on ApplicationProtocols: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
|
||||
// h2
|
||||
public static readonly SslApplicationProtocol Http2 = new SslApplicationProtocol(new byte[] { 0x68, 0x32 }, false);
|
||||
// http/1.1
|
||||
public static readonly SslApplicationProtocol Http11 = new SslApplicationProtocol(new byte[] { 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 }, false);
|
||||
|
||||
internal SslApplicationProtocol(byte[] protocol, bool copy)
|
||||
{
|
||||
if (protocol == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(protocol));
|
||||
}
|
||||
|
||||
// RFC 7301 states protocol size <= 255 bytes.
|
||||
if (protocol.Length == 0 || protocol.Length > 255)
|
||||
{
|
||||
throw new ArgumentException(SR.net_ssl_app_protocol_invalid, nameof(protocol));
|
||||
}
|
||||
|
||||
if (copy)
|
||||
{
|
||||
byte[] temp = new byte[protocol.Length];
|
||||
Array.Copy(protocol, 0, temp, 0, protocol.Length);
|
||||
_readOnlyProtocol = new ReadOnlyMemory<byte>(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
_readOnlyProtocol = new ReadOnlyMemory<byte>(protocol);
|
||||
}
|
||||
}
|
||||
|
||||
public SslApplicationProtocol(byte[] protocol) : this(protocol, true) { }
|
||||
|
||||
public SslApplicationProtocol(string protocol) : this(s_utf8.GetBytes(protocol), copy: false) { }
|
||||
|
||||
public ReadOnlyMemory<byte> Protocol
|
||||
{
|
||||
get => _readOnlyProtocol;
|
||||
}
|
||||
|
||||
public bool Equals(SslApplicationProtocol other)
|
||||
{
|
||||
if (_readOnlyProtocol.Length != other._readOnlyProtocol.Length)
|
||||
return false;
|
||||
|
||||
return (_readOnlyProtocol.IsEmpty && other._readOnlyProtocol.IsEmpty) ||
|
||||
_readOnlyProtocol.Span.SequenceEqual(other._readOnlyProtocol.Span);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is SslApplicationProtocol protocol)
|
||||
{
|
||||
return Equals(protocol);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (_readOnlyProtocol.Length == 0)
|
||||
return 0;
|
||||
|
||||
int hash1 = 0;
|
||||
ReadOnlySpan<byte> pSpan = _readOnlyProtocol.Span;
|
||||
for (int i = 0; i < _readOnlyProtocol.Length; i++)
|
||||
{
|
||||
hash1 = ((hash1 << 5) + hash1) ^ pSpan[i];
|
||||
}
|
||||
|
||||
return hash1;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_readOnlyProtocol.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return s_utf8.GetString(_readOnlyProtocol.Span);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// In case of decoding errors, return the byte values as hex string.
|
||||
int byteCharsLength = _readOnlyProtocol.Length * 5;
|
||||
char[] byteChars = new char[byteCharsLength];
|
||||
int index = 0;
|
||||
|
||||
ReadOnlySpan<byte> pSpan = _readOnlyProtocol.Span;
|
||||
for (int i = 0; i < byteCharsLength; i += 5)
|
||||
{
|
||||
byte b = pSpan[index++];
|
||||
byteChars[i] = '0';
|
||||
byteChars[i + 1] = 'x';
|
||||
byteChars[i + 2] = GetHexValue(Math.DivRem(b, 16, out int rem));
|
||||
byteChars[i + 3] = GetHexValue(rem);
|
||||
byteChars[i + 4] = ' ';
|
||||
}
|
||||
|
||||
return new string(byteChars, 0, byteCharsLength - 1);
|
||||
|
||||
char GetHexValue(int i)
|
||||
{
|
||||
if (i < 10)
|
||||
return (char)(i + '0');
|
||||
|
||||
return (char)(i - 10 + 'a');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(SslApplicationProtocol left, SslApplicationProtocol right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(SslApplicationProtocol left, SslApplicationProtocol right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
71
external/corefx/src/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs
vendored
Normal file
71
external/corefx/src/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace System.Net.Security
|
||||
{
|
||||
internal class SslAuthenticationOptions
|
||||
{
|
||||
internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthenticationOptions)
|
||||
{
|
||||
// Common options.
|
||||
AllowRenegotiation = sslClientAuthenticationOptions.AllowRenegotiation;
|
||||
ApplicationProtocols = sslClientAuthenticationOptions.ApplicationProtocols;
|
||||
CertValidationDelegate = sslClientAuthenticationOptions._certValidationDelegate;
|
||||
CheckCertName = true;
|
||||
EnabledSslProtocols = sslClientAuthenticationOptions.EnabledSslProtocols;
|
||||
EncryptionPolicy = sslClientAuthenticationOptions.EncryptionPolicy;
|
||||
IsServer = false;
|
||||
RemoteCertRequired = true;
|
||||
RemoteCertificateValidationCallback = sslClientAuthenticationOptions.RemoteCertificateValidationCallback;
|
||||
TargetHost = sslClientAuthenticationOptions.TargetHost;
|
||||
|
||||
// Client specific options.
|
||||
CertSelectionDelegate = sslClientAuthenticationOptions._certSelectionDelegate;
|
||||
CertificateRevocationCheckMode = sslClientAuthenticationOptions.CertificateRevocationCheckMode;
|
||||
ClientCertificates = sslClientAuthenticationOptions.ClientCertificates;
|
||||
LocalCertificateSelectionCallback = sslClientAuthenticationOptions.LocalCertificateSelectionCallback;
|
||||
}
|
||||
|
||||
internal SslAuthenticationOptions(SslServerAuthenticationOptions sslServerAuthenticationOptions)
|
||||
{
|
||||
// Common options.
|
||||
AllowRenegotiation = sslServerAuthenticationOptions.AllowRenegotiation;
|
||||
ApplicationProtocols = sslServerAuthenticationOptions.ApplicationProtocols;
|
||||
CertValidationDelegate = sslServerAuthenticationOptions._certValidationDelegate;
|
||||
CheckCertName = false;
|
||||
EnabledSslProtocols = sslServerAuthenticationOptions.EnabledSslProtocols;
|
||||
EncryptionPolicy = sslServerAuthenticationOptions.EncryptionPolicy;
|
||||
IsServer = true;
|
||||
RemoteCertRequired = sslServerAuthenticationOptions.ClientCertificateRequired;
|
||||
RemoteCertificateValidationCallback = sslServerAuthenticationOptions.RemoteCertificateValidationCallback;
|
||||
TargetHost = string.Empty;
|
||||
|
||||
// Server specific options.
|
||||
CertificateRevocationCheckMode = sslServerAuthenticationOptions.CertificateRevocationCheckMode;
|
||||
ServerCertificate = sslServerAuthenticationOptions.ServerCertificate;
|
||||
}
|
||||
|
||||
internal bool AllowRenegotiation { get; set; }
|
||||
internal string TargetHost { get; set; }
|
||||
internal X509CertificateCollection ClientCertificates { get; set; }
|
||||
internal List<SslApplicationProtocol> ApplicationProtocols { get; }
|
||||
internal bool IsServer { get; set; }
|
||||
internal RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; }
|
||||
internal LocalCertificateSelectionCallback LocalCertificateSelectionCallback { get; set; }
|
||||
internal X509Certificate ServerCertificate { get; set; }
|
||||
internal SslProtocols EnabledSslProtocols { get; set; }
|
||||
internal X509RevocationMode CertificateRevocationCheckMode { get; set; }
|
||||
internal EncryptionPolicy EncryptionPolicy { get; set; }
|
||||
internal bool RemoteCertRequired { get; set; }
|
||||
internal bool CheckCertName { get; set; }
|
||||
internal RemoteCertValidationCallback CertValidationDelegate { get; set; }
|
||||
internal LocalCertSelectionCallback CertSelectionDelegate { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace System.Net.Security
|
||||
{
|
||||
public class SslClientAuthenticationOptions
|
||||
{
|
||||
private EncryptionPolicy _encryptionPolicy = EncryptionPolicy.RequireEncryption;
|
||||
private X509RevocationMode _checkCertificateRevocation = X509RevocationMode.NoCheck;
|
||||
private SslProtocols _enabledSslProtocols = SecurityProtocol.SystemDefaultSecurityProtocols;
|
||||
private bool _allowRenegotiation = true;
|
||||
|
||||
internal RemoteCertValidationCallback _certValidationDelegate;
|
||||
internal LocalCertSelectionCallback _certSelectionDelegate;
|
||||
|
||||
public bool AllowRenegotiation
|
||||
{
|
||||
get => _allowRenegotiation;
|
||||
set => _allowRenegotiation = value;
|
||||
}
|
||||
|
||||
public LocalCertificateSelectionCallback LocalCertificateSelectionCallback { get; set; }
|
||||
|
||||
public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; }
|
||||
|
||||
public List<SslApplicationProtocol> ApplicationProtocols { get; set; }
|
||||
|
||||
public string TargetHost { get; set; }
|
||||
|
||||
public X509CertificateCollection ClientCertificates { get; set; }
|
||||
|
||||
public X509RevocationMode CertificateRevocationCheckMode
|
||||
{
|
||||
get => _checkCertificateRevocation;
|
||||
set
|
||||
{
|
||||
if (value != X509RevocationMode.NoCheck && value != X509RevocationMode.Offline && value != X509RevocationMode.Online)
|
||||
{
|
||||
throw new ArgumentException(SR.Format(SR.net_invalid_enum, nameof(X509RevocationMode)), nameof(value));
|
||||
}
|
||||
|
||||
_checkCertificateRevocation = value;
|
||||
}
|
||||
}
|
||||
|
||||
public EncryptionPolicy EncryptionPolicy
|
||||
{
|
||||
get => _encryptionPolicy;
|
||||
set
|
||||
{
|
||||
if (value != EncryptionPolicy.RequireEncryption && value != EncryptionPolicy.AllowNoEncryption && value != EncryptionPolicy.NoEncryption)
|
||||
{
|
||||
throw new ArgumentException(SR.Format(SR.net_invalid_enum, nameof(EncryptionPolicy)), nameof(value));
|
||||
}
|
||||
|
||||
_encryptionPolicy = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SslProtocols EnabledSslProtocols
|
||||
{
|
||||
get => _enabledSslProtocols;
|
||||
set => _enabledSslProtocols = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace System.Net.Security
|
||||
{
|
||||
public class SslServerAuthenticationOptions
|
||||
{
|
||||
private X509RevocationMode _checkCertificateRevocation = X509RevocationMode.NoCheck;
|
||||
private SslProtocols _enabledSslProtocols = SecurityProtocol.SystemDefaultSecurityProtocols;
|
||||
private EncryptionPolicy _encryptionPolicy = EncryptionPolicy.RequireEncryption;
|
||||
private bool _allowRenegotiation = true;
|
||||
|
||||
internal RemoteCertValidationCallback _certValidationDelegate;
|
||||
|
||||
public bool AllowRenegotiation
|
||||
{
|
||||
get => _allowRenegotiation;
|
||||
set => _allowRenegotiation = value;
|
||||
}
|
||||
|
||||
public bool ClientCertificateRequired { get; set; }
|
||||
|
||||
public List<SslApplicationProtocol> ApplicationProtocols { get; set; }
|
||||
|
||||
public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; }
|
||||
|
||||
public X509Certificate ServerCertificate { get; set; }
|
||||
|
||||
public SslProtocols EnabledSslProtocols
|
||||
{
|
||||
get => _enabledSslProtocols;
|
||||
set => _enabledSslProtocols = value;
|
||||
}
|
||||
|
||||
public X509RevocationMode CertificateRevocationCheckMode
|
||||
{
|
||||
get => _checkCertificateRevocation;
|
||||
set
|
||||
{
|
||||
if (value != X509RevocationMode.NoCheck && value != X509RevocationMode.Offline && value != X509RevocationMode.Online)
|
||||
{
|
||||
throw new ArgumentException(SR.Format(SR.net_invalid_enum, nameof(X509RevocationMode)), nameof(value));
|
||||
}
|
||||
|
||||
_checkCertificateRevocation = value;
|
||||
}
|
||||
}
|
||||
|
||||
public EncryptionPolicy EncryptionPolicy
|
||||
{
|
||||
get => _encryptionPolicy;
|
||||
set
|
||||
{
|
||||
if (value != EncryptionPolicy.RequireEncryption && value != EncryptionPolicy.AllowNoEncryption && value != EncryptionPolicy.NoEncryption)
|
||||
{
|
||||
throw new ArgumentException(SR.Format(SR.net_invalid_enum, nameof(EncryptionPolicy)), nameof(value));
|
||||
}
|
||||
|
||||
_encryptionPolicy = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace System.Net.Security
|
||||
//
|
||||
// Uses certificate thumb-print comparison.
|
||||
//
|
||||
private struct SslCredKey : IEquatable<SslCredKey>
|
||||
private readonly struct SslCredKey : IEquatable<SslCredKey>
|
||||
{
|
||||
private readonly byte[] _thumbPrint;
|
||||
private readonly int _allowedProtocols;
|
||||
|
||||
@@ -22,8 +22,7 @@ namespace System.Net.Security
|
||||
private static AsyncProtocolCallback s_readFrameCallback = new AsyncProtocolCallback(ReadFrameCallback);
|
||||
private static AsyncCallback s_writeCallback = new AsyncCallback(WriteCallback);
|
||||
|
||||
private RemoteCertValidationCallback _certValidationDelegate;
|
||||
private LocalCertSelectionCallback _certSelectionDelegate;
|
||||
internal SslAuthenticationOptions _sslAuthenticationOptions;
|
||||
|
||||
private Stream _innerStream;
|
||||
|
||||
@@ -33,7 +32,6 @@ namespace System.Net.Security
|
||||
private SecureChannel _context;
|
||||
|
||||
private bool _handshakeCompleted;
|
||||
private bool _certValidationFailed;
|
||||
private bool _shutdown;
|
||||
|
||||
private SecurityStatusPal _securityStatus;
|
||||
@@ -70,31 +68,17 @@ namespace System.Net.Security
|
||||
private int _lockReadState;
|
||||
private object _queuedReadStateRequest;
|
||||
|
||||
private readonly EncryptionPolicy _encryptionPolicy;
|
||||
|
||||
//
|
||||
// The public Client and Server classes enforce the parameters rules before
|
||||
// calling into this .ctor.
|
||||
//
|
||||
internal SslState(Stream innerStream, RemoteCertValidationCallback certValidationCallback, LocalCertSelectionCallback certSelectionCallback, EncryptionPolicy encryptionPolicy)
|
||||
internal SslState(Stream innerStream)
|
||||
{
|
||||
_innerStream = innerStream;
|
||||
_certValidationDelegate = certValidationCallback;
|
||||
_certSelectionDelegate = certSelectionCallback;
|
||||
_encryptionPolicy = encryptionPolicy;
|
||||
}
|
||||
|
||||
internal void ValidateCreateContext(bool isServer, string targetHost, SslProtocols enabledSslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertRevocationStatus)
|
||||
internal void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions)
|
||||
{
|
||||
ValidateCreateContext(isServer, targetHost, enabledSslProtocols, serverCertificate, clientCertificates, remoteCertRequired,
|
||||
checkCertRevocationStatus, !isServer);
|
||||
}
|
||||
|
||||
internal void ValidateCreateContext(bool isServer, string targetHost, SslProtocols enabledSslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertRevocationStatus, bool checkCertName)
|
||||
{
|
||||
//
|
||||
// We don't support SSL alerts right now, hence any exception is fatal and cannot be retried.
|
||||
//
|
||||
if (_exception != null)
|
||||
{
|
||||
_exception.Throw();
|
||||
@@ -105,31 +89,26 @@ namespace System.Net.Security
|
||||
throw new InvalidOperationException(SR.net_auth_reauth);
|
||||
}
|
||||
|
||||
if (Context != null && IsServer != isServer)
|
||||
if (Context != null && IsServer)
|
||||
{
|
||||
throw new InvalidOperationException(SR.net_auth_client_server);
|
||||
}
|
||||
|
||||
if (targetHost == null)
|
||||
if (sslClientAuthenticationOptions.TargetHost == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(targetHost));
|
||||
throw new ArgumentNullException(nameof(sslClientAuthenticationOptions.TargetHost));
|
||||
}
|
||||
|
||||
if (isServer && serverCertificate == null)
|
||||
if (sslClientAuthenticationOptions.TargetHost.Length == 0)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(serverCertificate));
|
||||
}
|
||||
|
||||
if (targetHost.Length == 0)
|
||||
{
|
||||
targetHost = "?" + Interlocked.Increment(ref s_uniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo);
|
||||
sslClientAuthenticationOptions.TargetHost = "?" + Interlocked.Increment(ref s_uniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo);
|
||||
}
|
||||
|
||||
_exception = null;
|
||||
try
|
||||
{
|
||||
_context = new SecureChannel(targetHost, isServer, enabledSslProtocols, serverCertificate, clientCertificates, remoteCertRequired,
|
||||
checkCertName, checkCertRevocationStatus, _encryptionPolicy, _certSelectionDelegate);
|
||||
_sslAuthenticationOptions = new SslAuthenticationOptions(sslClientAuthenticationOptions);
|
||||
_context = new SecureChannel(_sslAuthenticationOptions);
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
@@ -137,6 +116,51 @@ namespace System.Net.Security
|
||||
}
|
||||
}
|
||||
|
||||
internal void ValidateCreateContext(SslServerAuthenticationOptions sslServerAuthenticationOptions)
|
||||
{
|
||||
if (_exception != null)
|
||||
{
|
||||
_exception.Throw();
|
||||
}
|
||||
|
||||
if (Context != null && Context.IsValidContext)
|
||||
{
|
||||
throw new InvalidOperationException(SR.net_auth_reauth);
|
||||
}
|
||||
|
||||
if (Context != null && !IsServer)
|
||||
{
|
||||
throw new InvalidOperationException(SR.net_auth_client_server);
|
||||
}
|
||||
|
||||
if (sslServerAuthenticationOptions.ServerCertificate == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(sslServerAuthenticationOptions.ServerCertificate));
|
||||
}
|
||||
|
||||
_exception = null;
|
||||
try
|
||||
{
|
||||
_sslAuthenticationOptions = new SslAuthenticationOptions(sslServerAuthenticationOptions);
|
||||
_context = new SecureChannel(_sslAuthenticationOptions);
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
throw new AuthenticationException(SR.net_auth_SSPI, e);
|
||||
}
|
||||
}
|
||||
|
||||
internal SslApplicationProtocol NegotiatedApplicationProtocol
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Context == null)
|
||||
return default;
|
||||
|
||||
return Context.NegotiatedApplicationProtocol;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsAuthenticated
|
||||
{
|
||||
get
|
||||
@@ -172,14 +196,6 @@ namespace System.Net.Security
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SSL related properties
|
||||
//
|
||||
internal void SetCertValidationDelegate(RemoteCertValidationCallback certValidationCallback)
|
||||
{
|
||||
_certValidationDelegate = certValidationCallback;
|
||||
}
|
||||
|
||||
//
|
||||
// This will return selected local cert for both client/server streams
|
||||
//
|
||||
@@ -209,20 +225,7 @@ namespace System.Net.Security
|
||||
{
|
||||
get
|
||||
{
|
||||
return Context != null && Context.CheckCertRevocationStatus;
|
||||
}
|
||||
}
|
||||
|
||||
internal SecurityStatusPal LastSecurityStatus
|
||||
{
|
||||
get { return _securityStatus; }
|
||||
}
|
||||
|
||||
internal bool IsCertValidationFailed
|
||||
{
|
||||
get
|
||||
{
|
||||
return _certValidationFailed;
|
||||
return Context != null && Context.CheckCertRevocationStatus != X509RevocationMode.NoCheck;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,14 +393,6 @@ namespace System.Net.Security
|
||||
}
|
||||
}
|
||||
|
||||
internal int HeaderSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return Context.HeaderSize;
|
||||
}
|
||||
}
|
||||
|
||||
internal int MaxDataSize
|
||||
{
|
||||
get
|
||||
@@ -526,14 +521,14 @@ namespace System.Net.Security
|
||||
//
|
||||
// Must be called under the lock in case concurrent handshake is going.
|
||||
//
|
||||
internal int CheckOldKeyDecryptedData(byte[] buffer, int offset, int count)
|
||||
internal int CheckOldKeyDecryptedData(Memory<byte> buffer)
|
||||
{
|
||||
CheckThrow(true);
|
||||
if (_queuedReadData != null)
|
||||
{
|
||||
// This is inefficient yet simple and should be a REALLY rare case.
|
||||
int toCopy = Math.Min(_queuedReadCount, count);
|
||||
Buffer.BlockCopy(_queuedReadData, 0, buffer, offset, toCopy);
|
||||
int toCopy = Math.Min(_queuedReadCount, buffer.Length);
|
||||
new Span<byte>(_queuedReadData, 0, toCopy).CopyTo(buffer.Span);
|
||||
_queuedReadCount -= toCopy;
|
||||
if (_queuedReadCount == 0)
|
||||
{
|
||||
@@ -580,14 +575,15 @@ namespace System.Net.Security
|
||||
// Not aync so the connection is completed at this point.
|
||||
if (lazyResult == null && NetEventSource.IsEnabled)
|
||||
{
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Log.SspiSelectedCipherSuite(nameof(ProcessAuthentication),
|
||||
SslProtocol,
|
||||
CipherAlgorithm,
|
||||
CipherStrength,
|
||||
HashAlgorithm,
|
||||
HashStrength,
|
||||
KeyExchangeAlgorithm,
|
||||
KeyExchangeStrength);
|
||||
if (NetEventSource.IsEnabled)
|
||||
NetEventSource.Log.SspiSelectedCipherSuite(nameof(ProcessAuthentication),
|
||||
SslProtocol,
|
||||
CipherAlgorithm,
|
||||
CipherStrength,
|
||||
HashAlgorithm,
|
||||
HashStrength,
|
||||
KeyExchangeAlgorithm,
|
||||
KeyExchangeStrength);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
@@ -714,14 +710,15 @@ namespace System.Net.Security
|
||||
// Connection is completed at this point.
|
||||
if (NetEventSource.IsEnabled)
|
||||
{
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Log.SspiSelectedCipherSuite(nameof(EndProcessAuthentication),
|
||||
SslProtocol,
|
||||
CipherAlgorithm,
|
||||
CipherStrength,
|
||||
HashAlgorithm,
|
||||
HashStrength,
|
||||
KeyExchangeAlgorithm,
|
||||
KeyExchangeStrength);
|
||||
if (NetEventSource.IsEnabled)
|
||||
NetEventSource.Log.SspiSelectedCipherSuite(nameof(EndProcessAuthentication),
|
||||
SslProtocol,
|
||||
CipherAlgorithm,
|
||||
CipherStrength,
|
||||
HashAlgorithm,
|
||||
HashStrength,
|
||||
KeyExchangeAlgorithm,
|
||||
KeyExchangeStrength);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1014,23 +1011,24 @@ namespace System.Net.Security
|
||||
//
|
||||
private bool CompleteHandshake(ref ProtocolToken alertToken)
|
||||
{
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Enter(this);
|
||||
if (NetEventSource.IsEnabled)
|
||||
NetEventSource.Enter(this);
|
||||
|
||||
Context.ProcessHandshakeSuccess();
|
||||
|
||||
if (!Context.VerifyRemoteCertificate(_certValidationDelegate, ref alertToken))
|
||||
if (!Context.VerifyRemoteCertificate(_sslAuthenticationOptions.CertValidationDelegate, ref alertToken))
|
||||
{
|
||||
_handshakeCompleted = false;
|
||||
_certValidationFailed = true;
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(this, false);
|
||||
if (NetEventSource.IsEnabled)
|
||||
NetEventSource.Exit(this, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
_certValidationFailed = false;
|
||||
_handshakeCompleted = true;
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(this, true);
|
||||
if (NetEventSource.IsEnabled)
|
||||
NetEventSource.Exit(this, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1088,7 +1086,8 @@ namespace System.Net.Security
|
||||
|
||||
private static void PartialFrameCallback(AsyncProtocolRequest asyncRequest)
|
||||
{
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Enter(null);
|
||||
if (NetEventSource.IsEnabled)
|
||||
NetEventSource.Enter(null);
|
||||
|
||||
// Async ONLY completion.
|
||||
SslState sslState = (SslState)asyncRequest.AsyncObject;
|
||||
@@ -1112,7 +1111,8 @@ namespace System.Net.Security
|
||||
//
|
||||
private static void ReadFrameCallback(AsyncProtocolRequest asyncRequest)
|
||||
{
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Enter(null);
|
||||
if (NetEventSource.IsEnabled)
|
||||
NetEventSource.Enter(null);
|
||||
|
||||
// Async ONLY completion.
|
||||
SslState sslState = (SslState)asyncRequest.AsyncObject;
|
||||
@@ -1183,43 +1183,28 @@ namespace System.Net.Security
|
||||
}
|
||||
|
||||
_lockReadState = LockRead;
|
||||
object obj = _queuedReadStateRequest;
|
||||
if (obj == null)
|
||||
{
|
||||
// Other thread did not get under the lock yet.
|
||||
return;
|
||||
}
|
||||
|
||||
_queuedReadStateRequest = null;
|
||||
if (obj is LazyAsyncResult)
|
||||
{
|
||||
((LazyAsyncResult)obj).InvokeCallback();
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(new WaitCallback(CompleteRequestWaitCallback), obj);
|
||||
}
|
||||
HandleQueuedCallback(ref _queuedReadStateRequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns:
|
||||
// -1 - proceed
|
||||
// 0 - queued
|
||||
// X - some bytes are ready, no need for IO
|
||||
internal int CheckEnqueueRead(byte[] buffer, int offset, int count, AsyncProtocolRequest request)
|
||||
internal int CheckEnqueueRead(Memory<byte> buffer)
|
||||
{
|
||||
int lockState = Interlocked.CompareExchange(ref _lockReadState, LockRead, LockNone);
|
||||
|
||||
if (lockState != LockHandshake)
|
||||
{
|
||||
// Proceed, no concurrent handshake is ongoing so no need for a lock.
|
||||
return CheckOldKeyDecryptedData(buffer, offset, count);
|
||||
return CheckOldKeyDecryptedData(buffer);
|
||||
}
|
||||
|
||||
LazyAsyncResult lazyResult = null;
|
||||
lock (this)
|
||||
{
|
||||
int result = CheckOldKeyDecryptedData(buffer, offset, count);
|
||||
int result = CheckOldKeyDecryptedData(buffer);
|
||||
if (result != -1)
|
||||
{
|
||||
return result;
|
||||
@@ -1235,12 +1220,6 @@ namespace System.Net.Security
|
||||
|
||||
_lockReadState = LockPendingRead;
|
||||
|
||||
if (request != null)
|
||||
{
|
||||
// Request queued.
|
||||
_queuedReadStateRequest = request;
|
||||
return 0;
|
||||
}
|
||||
lazyResult = new LazyAsyncResult(null, null, /*must be */ null);
|
||||
_queuedReadStateRequest = lazyResult;
|
||||
}
|
||||
@@ -1248,7 +1227,40 @@ namespace System.Net.Security
|
||||
lazyResult.InternalWaitForCompletion();
|
||||
lock (this)
|
||||
{
|
||||
return CheckOldKeyDecryptedData(buffer, offset, count);
|
||||
return CheckOldKeyDecryptedData(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
internal ValueTask<int> CheckEnqueueReadAsync(Memory<byte> buffer)
|
||||
{
|
||||
int lockState = Interlocked.CompareExchange(ref _lockReadState, LockRead, LockNone);
|
||||
|
||||
if (lockState != LockHandshake)
|
||||
{
|
||||
// Proceed, no concurrent handshake is ongoing so no need for a lock.
|
||||
return new ValueTask<int>(CheckOldKeyDecryptedData(buffer));
|
||||
}
|
||||
|
||||
lock (this)
|
||||
{
|
||||
int result = CheckOldKeyDecryptedData(buffer);
|
||||
if (result != -1)
|
||||
{
|
||||
return new ValueTask<int>(result);
|
||||
}
|
||||
|
||||
// Check again under lock.
|
||||
if (_lockReadState != LockHandshake)
|
||||
{
|
||||
// The other thread has finished before we grabbed the lock.
|
||||
_lockReadState = LockRead;
|
||||
return new ValueTask<int>(-1);
|
||||
}
|
||||
|
||||
_lockReadState = LockPendingRead;
|
||||
TaskCompletionSource<int> taskCompletionSource = new TaskCompletionSource<int>(buffer, TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
_queuedReadStateRequest = taskCompletionSource;
|
||||
return new ValueTask<int>(taskCompletionSource.Task);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1346,23 +1358,30 @@ namespace System.Net.Security
|
||||
|
||||
lock (this)
|
||||
{
|
||||
HandleWriteCallback();
|
||||
HandleQueuedCallback(ref _queuedWriteStateRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleWriteCallback()
|
||||
private void HandleQueuedCallback(ref object queuedStateRequest)
|
||||
{
|
||||
object obj = _queuedWriteStateRequest;
|
||||
_queuedWriteStateRequest = null;
|
||||
object obj = queuedStateRequest;
|
||||
if (obj == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
queuedStateRequest = null;
|
||||
|
||||
switch (obj)
|
||||
{
|
||||
case null:
|
||||
break;
|
||||
case LazyAsyncResult lazy:
|
||||
lazy.InvokeCallback();
|
||||
break;
|
||||
case TaskCompletionSource<int> tsc:
|
||||
tsc.SetResult(0);
|
||||
case TaskCompletionSource<int> taskCompletionSource when taskCompletionSource.Task.AsyncState != null:
|
||||
Memory<byte> array = (Memory<byte>)taskCompletionSource.Task.AsyncState;
|
||||
taskCompletionSource.SetResult(CheckOldKeyDecryptedData(array));
|
||||
break;
|
||||
case TaskCompletionSource<int> taskCompletionSource:
|
||||
taskCompletionSource.SetResult(0);
|
||||
break;
|
||||
default:
|
||||
ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncResumeHandshake), obj);
|
||||
@@ -1427,7 +1446,7 @@ namespace System.Net.Security
|
||||
}
|
||||
|
||||
_lockWriteState = LockWrite;
|
||||
HandleWriteCallback();
|
||||
HandleQueuedCallback(ref _queuedWriteStateRequest);
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -1662,7 +1681,8 @@ namespace System.Net.Security
|
||||
// This is called from SslStream class too.
|
||||
internal int GetRemainingFrameSize(byte[] buffer, int offset, int dataSize)
|
||||
{
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Enter(this, buffer, offset, dataSize);
|
||||
if (NetEventSource.IsEnabled)
|
||||
NetEventSource.Enter(this, buffer, offset, dataSize);
|
||||
|
||||
int payloadSize = -1;
|
||||
switch (_Framing)
|
||||
@@ -1702,7 +1722,8 @@ namespace System.Net.Security
|
||||
break;
|
||||
}
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(this, payloadSize);
|
||||
if (NetEventSource.IsEnabled)
|
||||
NetEventSource.Exit(this, payloadSize);
|
||||
return payloadSize;
|
||||
}
|
||||
|
||||
@@ -1824,7 +1845,7 @@ namespace System.Net.Security
|
||||
|
||||
internal IAsyncResult BeginShutdown(AsyncCallback asyncCallback, object asyncState)
|
||||
{
|
||||
CheckThrow(authSuccessCheck:true, shutdownCheck:true);
|
||||
CheckThrow(authSuccessCheck: true, shutdownCheck: true);
|
||||
|
||||
ProtocolToken message = Context.CreateShutdownToken();
|
||||
return TaskToApm.Begin(InnerStream.WriteAsync(message.Payload, 0, message.Payload.Length), asyncCallback, asyncState);
|
||||
@@ -1832,7 +1853,7 @@ namespace System.Net.Security
|
||||
|
||||
internal void EndShutdown(IAsyncResult result)
|
||||
{
|
||||
CheckThrow(authSuccessCheck: true, shutdownCheck:true);
|
||||
CheckThrow(authSuccessCheck: true, shutdownCheck: true);
|
||||
|
||||
TaskToApm.End(result);
|
||||
_shutdown = true;
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
@@ -36,10 +38,14 @@ namespace System.Net.Security
|
||||
public class SslStream : AuthenticatedStream
|
||||
{
|
||||
private SslState _sslState;
|
||||
private RemoteCertificateValidationCallback _userCertificateValidationCallback;
|
||||
private LocalCertificateSelectionCallback _userCertificateSelectionCallback;
|
||||
private object _remoteCertificateOrBytes;
|
||||
|
||||
internal RemoteCertificateValidationCallback _userCertificateValidationCallback;
|
||||
internal LocalCertificateSelectionCallback _userCertificateSelectionCallback;
|
||||
internal RemoteCertValidationCallback _certValidationDelegate;
|
||||
internal LocalCertSelectionCallback _certSelectionDelegate;
|
||||
internal EncryptionPolicy _encryptionPolicy;
|
||||
|
||||
public SslStream(Stream innerStream)
|
||||
: this(innerStream, false, null, null)
|
||||
{
|
||||
@@ -72,9 +78,44 @@ namespace System.Net.Security
|
||||
|
||||
_userCertificateValidationCallback = userCertificateValidationCallback;
|
||||
_userCertificateSelectionCallback = userCertificateSelectionCallback;
|
||||
RemoteCertValidationCallback _userCertValidationCallbackWrapper = new RemoteCertValidationCallback(UserCertValidationCallbackWrapper);
|
||||
LocalCertSelectionCallback _userCertSelectionCallbackWrapper = userCertificateSelectionCallback == null ? null : new LocalCertSelectionCallback(UserCertSelectionCallbackWrapper);
|
||||
_sslState = new SslState(innerStream, _userCertValidationCallbackWrapper, _userCertSelectionCallbackWrapper, encryptionPolicy);
|
||||
_encryptionPolicy = encryptionPolicy;
|
||||
_certValidationDelegate = new RemoteCertValidationCallback(UserCertValidationCallbackWrapper);
|
||||
_certSelectionDelegate = userCertificateSelectionCallback == null ? null : new LocalCertSelectionCallback(UserCertSelectionCallbackWrapper);
|
||||
_sslState = new SslState(innerStream);
|
||||
}
|
||||
|
||||
public SslApplicationProtocol NegotiatedApplicationProtocol
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sslState.NegotiatedApplicationProtocol;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetAndVerifyValidationCallback(RemoteCertificateValidationCallback callback)
|
||||
{
|
||||
if (_userCertificateValidationCallback == null)
|
||||
{
|
||||
_userCertificateValidationCallback = callback;
|
||||
_certValidationDelegate = new RemoteCertValidationCallback(UserCertValidationCallbackWrapper);
|
||||
}
|
||||
else if (callback != null && _userCertificateValidationCallback != callback)
|
||||
{
|
||||
throw new InvalidOperationException(SR.Format(SR.net_conflicting_options, nameof(RemoteCertificateValidationCallback)));
|
||||
}
|
||||
}
|
||||
|
||||
private void SetAndVerifySelectionCallback(LocalCertificateSelectionCallback callback)
|
||||
{
|
||||
if (_userCertificateSelectionCallback == null)
|
||||
{
|
||||
_userCertificateSelectionCallback = callback;
|
||||
_certSelectionDelegate = _userCertificateSelectionCallback == null ? null : new LocalCertSelectionCallback(UserCertSelectionCallbackWrapper);
|
||||
}
|
||||
else if (callback != null && _userCertificateSelectionCallback != callback)
|
||||
{
|
||||
throw new InvalidOperationException(SR.Format(SR.net_conflicting_options, nameof(LocalCertificateSelectionCallback)));
|
||||
}
|
||||
}
|
||||
|
||||
private bool UserCertValidationCallbackWrapper(string hostName, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
|
||||
@@ -119,8 +160,29 @@ namespace System.Net.Security
|
||||
SslProtocols enabledSslProtocols, bool checkCertificateRevocation,
|
||||
AsyncCallback asyncCallback, object asyncState)
|
||||
{
|
||||
SecurityProtocol.ThrowOnNotAllowed(enabledSslProtocols);
|
||||
_sslState.ValidateCreateContext(false, targetHost, enabledSslProtocols, null, clientCertificates, true, checkCertificateRevocation);
|
||||
SslClientAuthenticationOptions options = new SslClientAuthenticationOptions
|
||||
{
|
||||
TargetHost = targetHost,
|
||||
ClientCertificates = clientCertificates,
|
||||
EnabledSslProtocols = enabledSslProtocols,
|
||||
CertificateRevocationCheckMode = checkCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck,
|
||||
EncryptionPolicy = _encryptionPolicy,
|
||||
};
|
||||
|
||||
return BeginAuthenticateAsClient(options, CancellationToken.None, asyncCallback, asyncState);
|
||||
}
|
||||
|
||||
internal virtual IAsyncResult BeginAuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback asyncCallback, object asyncState)
|
||||
{
|
||||
SecurityProtocol.ThrowOnNotAllowed(sslClientAuthenticationOptions.EnabledSslProtocols);
|
||||
SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback);
|
||||
SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback);
|
||||
|
||||
// Set the delegates on the options.
|
||||
sslClientAuthenticationOptions._certValidationDelegate = _certValidationDelegate;
|
||||
sslClientAuthenticationOptions._certSelectionDelegate = _certSelectionDelegate;
|
||||
|
||||
_sslState.ValidateCreateContext(sslClientAuthenticationOptions);
|
||||
|
||||
LazyAsyncResult result = new LazyAsyncResult(_sslState, asyncState, asyncCallback);
|
||||
_sslState.ProcessAuthentication(result);
|
||||
@@ -154,8 +216,28 @@ namespace System.Net.Security
|
||||
AsyncCallback asyncCallback,
|
||||
object asyncState)
|
||||
{
|
||||
SecurityProtocol.ThrowOnNotAllowed(enabledSslProtocols);
|
||||
_sslState.ValidateCreateContext(true, string.Empty, enabledSslProtocols, serverCertificate, null, clientCertificateRequired, checkCertificateRevocation);
|
||||
SslServerAuthenticationOptions options = new SslServerAuthenticationOptions
|
||||
{
|
||||
ServerCertificate = serverCertificate,
|
||||
ClientCertificateRequired = clientCertificateRequired,
|
||||
EnabledSslProtocols = enabledSslProtocols,
|
||||
CertificateRevocationCheckMode = checkCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck,
|
||||
EncryptionPolicy = _encryptionPolicy,
|
||||
};
|
||||
|
||||
return BeginAuthenticateAsServer(options, CancellationToken.None, asyncCallback, asyncState);
|
||||
}
|
||||
|
||||
private IAsyncResult BeginAuthenticateAsServer(SslServerAuthenticationOptions sslServerAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback asyncCallback, object asyncState)
|
||||
{
|
||||
SecurityProtocol.ThrowOnNotAllowed(sslServerAuthenticationOptions.EnabledSslProtocols);
|
||||
SetAndVerifyValidationCallback(sslServerAuthenticationOptions.RemoteCertificateValidationCallback);
|
||||
|
||||
// Set the delegate on the options.
|
||||
sslServerAuthenticationOptions._certValidationDelegate = _certValidationDelegate;
|
||||
|
||||
_sslState.ValidateCreateContext(sslServerAuthenticationOptions);
|
||||
|
||||
LazyAsyncResult result = new LazyAsyncResult(_sslState, asyncState, asyncCallback);
|
||||
_sslState.ProcessAuthentication(result);
|
||||
return result;
|
||||
@@ -202,8 +284,29 @@ namespace System.Net.Security
|
||||
|
||||
public virtual void AuthenticateAsClient(string targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
|
||||
{
|
||||
SecurityProtocol.ThrowOnNotAllowed(enabledSslProtocols);
|
||||
_sslState.ValidateCreateContext(false, targetHost, enabledSslProtocols, null, clientCertificates, true, checkCertificateRevocation);
|
||||
SslClientAuthenticationOptions options = new SslClientAuthenticationOptions
|
||||
{
|
||||
TargetHost = targetHost,
|
||||
ClientCertificates = clientCertificates,
|
||||
EnabledSslProtocols = enabledSslProtocols,
|
||||
CertificateRevocationCheckMode = checkCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck,
|
||||
EncryptionPolicy = _encryptionPolicy,
|
||||
};
|
||||
|
||||
AuthenticateAsClient(options);
|
||||
}
|
||||
|
||||
private void AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
|
||||
{
|
||||
SecurityProtocol.ThrowOnNotAllowed(sslClientAuthenticationOptions.EnabledSslProtocols);
|
||||
SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback);
|
||||
SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback);
|
||||
|
||||
// Set the delegates on the options.
|
||||
sslClientAuthenticationOptions._certValidationDelegate = _certValidationDelegate;
|
||||
sslClientAuthenticationOptions._certSelectionDelegate = _certSelectionDelegate;
|
||||
|
||||
_sslState.ValidateCreateContext(sslClientAuthenticationOptions);
|
||||
_sslState.ProcessAuthentication(null);
|
||||
}
|
||||
|
||||
@@ -219,8 +322,27 @@ namespace System.Net.Security
|
||||
|
||||
public virtual void AuthenticateAsServer(X509Certificate serverCertificate, bool clientCertificateRequired, SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
|
||||
{
|
||||
SecurityProtocol.ThrowOnNotAllowed(enabledSslProtocols);
|
||||
_sslState.ValidateCreateContext(true, string.Empty, enabledSslProtocols, serverCertificate, null, clientCertificateRequired, checkCertificateRevocation);
|
||||
SslServerAuthenticationOptions options = new SslServerAuthenticationOptions
|
||||
{
|
||||
ServerCertificate = serverCertificate,
|
||||
ClientCertificateRequired = clientCertificateRequired,
|
||||
EnabledSslProtocols = enabledSslProtocols,
|
||||
CertificateRevocationCheckMode = checkCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck,
|
||||
EncryptionPolicy = _encryptionPolicy,
|
||||
};
|
||||
|
||||
AuthenticateAsServer(options);
|
||||
}
|
||||
|
||||
private void AuthenticateAsServer(SslServerAuthenticationOptions sslServerAuthenticationOptions)
|
||||
{
|
||||
SecurityProtocol.ThrowOnNotAllowed(sslServerAuthenticationOptions.EnabledSslProtocols);
|
||||
SetAndVerifyValidationCallback(sslServerAuthenticationOptions.RemoteCertificateValidationCallback);
|
||||
|
||||
// Set the delegate on the options.
|
||||
sslServerAuthenticationOptions._certValidationDelegate = _certValidationDelegate;
|
||||
|
||||
_sslState.ValidateCreateContext(sslServerAuthenticationOptions);
|
||||
_sslState.ProcessAuthentication(null);
|
||||
}
|
||||
#endregion
|
||||
@@ -252,6 +374,15 @@ namespace System.Net.Security
|
||||
this);
|
||||
}
|
||||
|
||||
public Task AuthenticateAsClientAsync(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.Factory.FromAsync(
|
||||
(arg1, arg2, callback, state) => ((SslStream)state).BeginAuthenticateAsClient(arg1, arg2, callback, state),
|
||||
iar => ((SslStream)iar.AsyncState).EndAuthenticateAsClient(iar),
|
||||
sslClientAuthenticationOptions, cancellationToken,
|
||||
this);
|
||||
}
|
||||
|
||||
public virtual Task AuthenticateAsServerAsync(X509Certificate serverCertificate) =>
|
||||
Task.Factory.FromAsync(
|
||||
(arg1, callback, state) => ((SslStream)state).BeginAuthenticateAsServer(arg1, callback, state),
|
||||
@@ -278,6 +409,15 @@ namespace System.Net.Security
|
||||
this);
|
||||
}
|
||||
|
||||
public Task AuthenticateAsServerAsync(SslServerAuthenticationOptions sslServerAuthenticationOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.Factory.FromAsync(
|
||||
(arg1, arg2, callback, state) => ((SslStream)state).BeginAuthenticateAsServer(arg1, arg2, callback, state),
|
||||
iar => ((SslStream)iar.AsyncState).EndAuthenticateAsServer(iar),
|
||||
sslServerAuthenticationOptions, cancellationToken,
|
||||
this);
|
||||
}
|
||||
|
||||
public virtual Task ShutdownAsync() =>
|
||||
Task.Factory.FromAsync(
|
||||
(callback, state) => ((SslStream)state).BeginShutdown(callback, state),
|
||||
@@ -575,5 +715,15 @@ namespace System.Net.Security
|
||||
{
|
||||
return _sslState.SecureStream.WriteAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return _sslState.SecureStream.ReadAsync(buffer, offset, count, cancellationToken);
|
||||
}
|
||||
|
||||
public override ValueTask<int> ReadAsync(Memory<byte> destination, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return _sslState.SecureStream.ReadAsync(destination, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
using System.Threading;
|
||||
@@ -15,7 +15,40 @@ namespace System.Net.Security
|
||||
Task WriteAsync(byte[] buffer, int offset, int count);
|
||||
}
|
||||
|
||||
private struct SslWriteAsync : ISslWriteAdapter
|
||||
private interface ISslReadAdapter
|
||||
{
|
||||
ValueTask<int> ReadAsync(byte[] buffer, int offset, int count);
|
||||
ValueTask<int> LockAsync(Memory<byte> buffer);
|
||||
}
|
||||
|
||||
private readonly struct SslReadAsync : ISslReadAdapter
|
||||
{
|
||||
private readonly SslState _sslState;
|
||||
private readonly CancellationToken _cancellationToken;
|
||||
|
||||
public SslReadAsync(SslState sslState, CancellationToken cancellationToken)
|
||||
{
|
||||
_cancellationToken = cancellationToken;
|
||||
_sslState = sslState;
|
||||
}
|
||||
|
||||
public ValueTask<int> ReadAsync(byte[] buffer, int offset, int count) => _sslState.InnerStream.ReadAsync(new Memory<byte>(buffer, offset, count), _cancellationToken);
|
||||
|
||||
public ValueTask<int> LockAsync(Memory<byte> buffer) => _sslState.CheckEnqueueReadAsync(buffer);
|
||||
}
|
||||
|
||||
private readonly struct SslReadSync : ISslReadAdapter
|
||||
{
|
||||
private readonly SslState _sslState;
|
||||
|
||||
public SslReadSync(SslState sslState) => _sslState = sslState;
|
||||
|
||||
public ValueTask<int> ReadAsync(byte[] buffer, int offset, int count) => new ValueTask<int>(_sslState.InnerStream.Read(buffer, offset, count));
|
||||
|
||||
public ValueTask<int> LockAsync(Memory<byte> buffer) => new ValueTask<int>(_sslState.CheckEnqueueRead(buffer));
|
||||
}
|
||||
|
||||
private readonly struct SslWriteAsync : ISslWriteAdapter
|
||||
{
|
||||
private readonly SslState _sslState;
|
||||
private readonly CancellationToken _cancellationToken;
|
||||
@@ -31,7 +64,7 @@ namespace System.Net.Security
|
||||
public Task WriteAsync(byte[] buffer, int offset, int count) => _sslState.InnerStream.WriteAsync(buffer, offset, count, _cancellationToken);
|
||||
}
|
||||
|
||||
private struct SslWriteSync : ISslWriteAdapter
|
||||
private readonly struct SslWriteSync : ISslWriteAdapter
|
||||
{
|
||||
private readonly SslState _sslState;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,11 +37,21 @@ namespace System.Net.Security
|
||||
public static SecurityStatusPal AcceptSecurityContext(
|
||||
ref SafeFreeCredentials credential,
|
||||
ref SafeDeleteContext context,
|
||||
SecurityBuffer inputBuffer,
|
||||
SecurityBuffer[] inputBuffers,
|
||||
SecurityBuffer outputBuffer,
|
||||
bool remoteCertRequired)
|
||||
SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
return HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, true, remoteCertRequired, null);
|
||||
if (inputBuffers != null)
|
||||
{
|
||||
Debug.Assert(inputBuffers.Length == 2);
|
||||
Debug.Assert(inputBuffers[1].token == null);
|
||||
|
||||
return HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, sslAuthenticationOptions);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HandshakeInternal(credential, ref context, inputBuffer: null, outputBuffer, sslAuthenticationOptions);
|
||||
}
|
||||
}
|
||||
|
||||
public static SecurityStatusPal InitializeSecurityContext(
|
||||
@@ -49,9 +59,10 @@ namespace System.Net.Security
|
||||
ref SafeDeleteContext context,
|
||||
string targetName,
|
||||
SecurityBuffer inputBuffer,
|
||||
SecurityBuffer outputBuffer)
|
||||
SecurityBuffer outputBuffer,
|
||||
SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
return HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, false, false, targetName);
|
||||
return HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, sslAuthenticationOptions);
|
||||
}
|
||||
|
||||
public static SecurityStatusPal InitializeSecurityContext(
|
||||
@@ -59,11 +70,28 @@ namespace System.Net.Security
|
||||
ref SafeDeleteContext context,
|
||||
string targetName,
|
||||
SecurityBuffer[] inputBuffers,
|
||||
SecurityBuffer outputBuffer)
|
||||
SecurityBuffer outputBuffer,
|
||||
SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
Debug.Assert(inputBuffers.Length == 2);
|
||||
Debug.Assert(inputBuffers[1].token == null);
|
||||
return HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, false, false, targetName);
|
||||
return HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, sslAuthenticationOptions);
|
||||
}
|
||||
|
||||
public static SecurityBuffer[] GetIncomingSecurityBuffers(SslAuthenticationOptions options, ref SecurityBuffer incomingSecurity)
|
||||
{
|
||||
SecurityBuffer[] incomingSecurityBuffers = null;
|
||||
|
||||
if (incomingSecurity != null)
|
||||
{
|
||||
incomingSecurityBuffers = new SecurityBuffer[]
|
||||
{
|
||||
incomingSecurity,
|
||||
new SecurityBuffer(null, 0, 0, SecurityBufferType.SECBUFFER_EMPTY)
|
||||
};
|
||||
}
|
||||
|
||||
return incomingSecurityBuffers;
|
||||
}
|
||||
|
||||
public static SafeFreeCredentials AcquireCredentialsHandle(
|
||||
@@ -75,6 +103,12 @@ namespace System.Net.Security
|
||||
return new SafeFreeSslCredentials(certificate, protocols, policy);
|
||||
}
|
||||
|
||||
internal static byte[] GetNegotiatedApplicationProtocol(SafeDeleteContext context)
|
||||
{
|
||||
// OSX SecureTransport does not export APIs to support ALPN, no-op.
|
||||
return null;
|
||||
}
|
||||
|
||||
public static SecurityStatusPal EncryptMessage(
|
||||
SafeDeleteContext securityContext,
|
||||
ReadOnlyMemory<byte> input,
|
||||
@@ -97,7 +131,16 @@ namespace System.Net.Security
|
||||
MemoryHandle memHandle = input.Retain(pin: true);
|
||||
try
|
||||
{
|
||||
PAL_TlsIo status = Interop.AppleCrypto.SslWrite(sslHandle, (byte*)memHandle.PinnedPointer, input.Length, out int written);
|
||||
PAL_TlsIo status;
|
||||
|
||||
lock (sslHandle)
|
||||
{
|
||||
status = Interop.AppleCrypto.SslWrite(
|
||||
sslHandle,
|
||||
(byte*)memHandle.Pointer,
|
||||
input.Length,
|
||||
out int written);
|
||||
}
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
@@ -157,7 +200,12 @@ namespace System.Net.Security
|
||||
fixed (byte* offsetInput = &buffer[offset])
|
||||
{
|
||||
int written;
|
||||
PAL_TlsIo status = Interop.AppleCrypto.SslRead(sslHandle, offsetInput, count, out written);
|
||||
PAL_TlsIo status;
|
||||
|
||||
lock (sslHandle)
|
||||
{
|
||||
status = Interop.AppleCrypto.SslRead(sslHandle, offsetInput, count, out written);
|
||||
}
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
@@ -226,9 +274,7 @@ namespace System.Net.Security
|
||||
ref SafeDeleteContext context,
|
||||
SecurityBuffer inputBuffer,
|
||||
SecurityBuffer outputBuffer,
|
||||
bool isServer,
|
||||
bool remoteCertRequired,
|
||||
string targetName)
|
||||
SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
Debug.Assert(!credential.IsInvalid);
|
||||
|
||||
@@ -238,18 +284,17 @@ namespace System.Net.Security
|
||||
|
||||
if ((null == context) || context.IsInvalid)
|
||||
{
|
||||
sslContext = new SafeDeleteSslContext(credential as SafeFreeSslCredentials, isServer);
|
||||
sslContext = new SafeDeleteSslContext(credential as SafeFreeSslCredentials, sslAuthenticationOptions);
|
||||
context = sslContext;
|
||||
|
||||
if (!string.IsNullOrEmpty(targetName))
|
||||
if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost))
|
||||
{
|
||||
Debug.Assert(!isServer, "targetName should not be set for server-side handshakes");
|
||||
Interop.AppleCrypto.SslSetTargetName(sslContext.SslContext, targetName);
|
||||
Debug.Assert(!sslAuthenticationOptions.IsServer, "targetName should not be set for server-side handshakes");
|
||||
Interop.AppleCrypto.SslSetTargetName(sslContext.SslContext, sslAuthenticationOptions.TargetHost);
|
||||
}
|
||||
|
||||
if (remoteCertRequired)
|
||||
if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired)
|
||||
{
|
||||
Debug.Assert(isServer, "remoteCertRequired should not be set for client-side handshakes");
|
||||
Interop.AppleCrypto.SslSetAcceptClientCert(sslContext.SslContext);
|
||||
}
|
||||
}
|
||||
@@ -259,7 +304,13 @@ namespace System.Net.Security
|
||||
sslContext.Write(inputBuffer.token, inputBuffer.offset, inputBuffer.size);
|
||||
}
|
||||
|
||||
SecurityStatusPal status = PerformHandshake(sslContext.SslContext);
|
||||
SafeSslHandle sslHandle = sslContext.SslContext;
|
||||
SecurityStatusPal status;
|
||||
|
||||
lock (sslHandle)
|
||||
{
|
||||
status = PerformHandshake(sslHandle);
|
||||
}
|
||||
|
||||
byte[] output = sslContext.ReadPendingWrites();
|
||||
outputBuffer.offset = 0;
|
||||
@@ -320,7 +371,13 @@ namespace System.Net.Security
|
||||
SafeDeleteContext securityContext)
|
||||
{
|
||||
SafeDeleteSslContext sslContext = ((SafeDeleteSslContext)securityContext);
|
||||
int osStatus = Interop.AppleCrypto.SslShutdown(sslContext.SslContext);
|
||||
SafeSslHandle sslHandle = sslContext.SslContext;
|
||||
int osStatus;
|
||||
|
||||
lock (sslHandle)
|
||||
{
|
||||
osStatus = Interop.AppleCrypto.SslShutdown(sslHandle);
|
||||
}
|
||||
|
||||
if (osStatus == 0)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -29,22 +30,49 @@ namespace System.Net.Security
|
||||
}
|
||||
|
||||
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context,
|
||||
SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired)
|
||||
SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
return HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, true, remoteCertRequired);
|
||||
if (inputBuffers != null)
|
||||
{
|
||||
Debug.Assert(inputBuffers.Length == 2);
|
||||
Debug.Assert(inputBuffers[1].token == null);
|
||||
|
||||
return HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, sslAuthenticationOptions);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HandshakeInternal(credential, ref context, inputBuffer: null, outputBuffer, sslAuthenticationOptions);
|
||||
}
|
||||
}
|
||||
|
||||
public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context,
|
||||
string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer)
|
||||
string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
return HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, false, false);
|
||||
return HandshakeInternal(credential, ref context, inputBuffer, outputBuffer, sslAuthenticationOptions);
|
||||
}
|
||||
|
||||
public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer)
|
||||
public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
Debug.Assert(inputBuffers.Length == 2);
|
||||
Debug.Assert(inputBuffers[1].token == null);
|
||||
return HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, false, false);
|
||||
|
||||
return HandshakeInternal(credential, ref context, inputBuffers[0], outputBuffer, sslAuthenticationOptions);
|
||||
}
|
||||
|
||||
public static SecurityBuffer[] GetIncomingSecurityBuffers(SslAuthenticationOptions options, ref SecurityBuffer incomingSecurity)
|
||||
{
|
||||
SecurityBuffer[] incomingSecurityBuffers = null;
|
||||
|
||||
if (incomingSecurity != null)
|
||||
{
|
||||
incomingSecurityBuffers = new SecurityBuffer[]
|
||||
{
|
||||
incomingSecurity,
|
||||
new SecurityBuffer(null, 0, 0, SecurityBufferType.SECBUFFER_EMPTY)
|
||||
};
|
||||
}
|
||||
|
||||
return incomingSecurityBuffers;
|
||||
}
|
||||
|
||||
public static SafeFreeCredentials AcquireCredentialsHandle(X509Certificate certificate,
|
||||
@@ -55,7 +83,7 @@ namespace System.Net.Security
|
||||
|
||||
public static SecurityStatusPal EncryptMessage(SafeDeleteContext securityContext, ReadOnlyMemory<byte> input, int headerSize, int trailerSize, ref byte[] output, out int resultSize)
|
||||
{
|
||||
return EncryptDecryptHelper(securityContext, input, offset:0, size: 0, encrypt: true, output: ref output, resultSize: out resultSize);
|
||||
return EncryptDecryptHelper(securityContext, input, offset: 0, size: 0, encrypt: true, output: ref output, resultSize: out resultSize);
|
||||
}
|
||||
|
||||
public static SecurityStatusPal DecryptMessage(SafeDeleteContext securityContext, byte[] buffer, ref int offset, ref int count)
|
||||
@@ -102,8 +130,13 @@ namespace System.Net.Security
|
||||
connectionInfo = new SslConnectionInfo(((SafeDeleteSslContext)securityContext).SslContext);
|
||||
}
|
||||
|
||||
private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context,
|
||||
SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool isServer, bool remoteCertRequired)
|
||||
public static byte[] ConvertAlpnProtocolListToByteArray(List<SslApplicationProtocol> applicationProtocols)
|
||||
{
|
||||
return Interop.Ssl.ConvertAlpnProtocolListToByteArray(applicationProtocols);
|
||||
}
|
||||
|
||||
private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer,
|
||||
SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
Debug.Assert(!credential.IsInvalid);
|
||||
|
||||
@@ -111,7 +144,7 @@ namespace System.Net.Security
|
||||
{
|
||||
if ((null == context) || context.IsInvalid)
|
||||
{
|
||||
context = new SafeDeleteSslContext(credential as SafeFreeSslCredentials, isServer, remoteCertRequired);
|
||||
context = new SafeDeleteSslContext(credential as SafeFreeSslCredentials, sslAuthenticationOptions);
|
||||
}
|
||||
|
||||
byte[] output = null;
|
||||
@@ -127,6 +160,16 @@ namespace System.Net.Security
|
||||
done = Interop.OpenSsl.DoSslHandshake(((SafeDeleteSslContext)context).SslContext, inputBuffer.token, inputBuffer.offset, inputBuffer.size, 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 indiciates 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 = ((SafeDeleteSslContext)context).SslContext;
|
||||
if (done && sslAuthenticationOptions.IsServer && sslAuthenticationOptions.ApplicationProtocols != null && sslContext.AlpnHandle.IsAllocated && sslContext.AlpnHandle.Target == null)
|
||||
{
|
||||
return new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, Interop.OpenSsl.CreateSslException(SR.net_alpn_failed));
|
||||
}
|
||||
|
||||
outputBuffer.size = outputSize;
|
||||
outputBuffer.offset = 0;
|
||||
outputBuffer.token = outputSize > 0 ? output : null;
|
||||
@@ -139,6 +182,14 @@ namespace System.Net.Security
|
||||
}
|
||||
}
|
||||
|
||||
internal static byte[] GetNegotiatedApplicationProtocol(SafeDeleteContext context)
|
||||
{
|
||||
if (context == null)
|
||||
return null;
|
||||
|
||||
return Interop.Ssl.SslGetAlpnSelected(((SafeDeleteSslContext)context).SslContext);
|
||||
}
|
||||
|
||||
private static SecurityStatusPal EncryptDecryptHelper(SafeDeleteContext securityContext, ReadOnlyMemory<byte> input, int offset, int size, bool encrypt, ref byte[] output, out int resultSize)
|
||||
{
|
||||
resultSize = 0;
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Principal;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace System.Net.Security
|
||||
{
|
||||
@@ -41,24 +41,29 @@ namespace System.Net.Security
|
||||
SSPIWrapper.GetVerifyPackageInfo(GlobalSSPI.SSPISecureChannel, SecurityPackage, true);
|
||||
}
|
||||
|
||||
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired)
|
||||
public static byte[] ConvertAlpnProtocolListToByteArray(List<SslApplicationProtocol> protocols)
|
||||
{
|
||||
return Interop.Sec_Application_Protocols.ToByteArray(protocols);
|
||||
}
|
||||
|
||||
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags);
|
||||
|
||||
int errorCode = SSPIWrapper.AcceptSecurityContext(
|
||||
GlobalSSPI.SSPISecureChannel,
|
||||
ref credentialsHandle,
|
||||
credentialsHandle,
|
||||
ref context,
|
||||
ServerRequiredFlags | (remoteCertRequired ? Interop.SspiCli.ContextFlags.MutualAuth : Interop.SspiCli.ContextFlags.Zero),
|
||||
ServerRequiredFlags | (sslAuthenticationOptions.RemoteCertRequired ? Interop.SspiCli.ContextFlags.MutualAuth : Interop.SspiCli.ContextFlags.Zero),
|
||||
Interop.SspiCli.Endianness.SECURITY_NATIVE_DREP,
|
||||
inputBuffer,
|
||||
inputBuffers,
|
||||
outputBuffer,
|
||||
ref unusedAttributes);
|
||||
|
||||
return SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode);
|
||||
}
|
||||
|
||||
public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer)
|
||||
public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, string targetName, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags);
|
||||
|
||||
@@ -76,7 +81,7 @@ namespace System.Net.Security
|
||||
return SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode);
|
||||
}
|
||||
|
||||
public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer)
|
||||
public static SecurityStatusPal InitializeSecurityContext(SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, string targetName, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
|
||||
{
|
||||
Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags);
|
||||
|
||||
@@ -94,6 +99,45 @@ namespace System.Net.Security
|
||||
return SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode);
|
||||
}
|
||||
|
||||
public static SecurityBuffer[] GetIncomingSecurityBuffers(SslAuthenticationOptions options, ref SecurityBuffer incomingSecurity)
|
||||
{
|
||||
SecurityBuffer alpnBuffer = null;
|
||||
SecurityBuffer[] incomingSecurityBuffers = null;
|
||||
|
||||
if (options.ApplicationProtocols != null && options.ApplicationProtocols.Count != 0)
|
||||
{
|
||||
byte[] alpnBytes = SslStreamPal.ConvertAlpnProtocolListToByteArray(options.ApplicationProtocols);
|
||||
alpnBuffer = new SecurityBuffer(alpnBytes, 0, alpnBytes.Length, SecurityBufferType.SECBUFFER_APPLICATION_PROTOCOLS);
|
||||
}
|
||||
|
||||
if (incomingSecurity != null)
|
||||
{
|
||||
if (alpnBuffer != null)
|
||||
{
|
||||
incomingSecurityBuffers = new SecurityBuffer[]
|
||||
{
|
||||
incomingSecurity,
|
||||
new SecurityBuffer(null, 0, 0, SecurityBufferType.SECBUFFER_EMPTY),
|
||||
alpnBuffer
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
incomingSecurityBuffers = new SecurityBuffer[]
|
||||
{
|
||||
incomingSecurity,
|
||||
new SecurityBuffer(null, 0, 0, SecurityBufferType.SECBUFFER_EMPTY)
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (alpnBuffer != null)
|
||||
{
|
||||
incomingSecurity = alpnBuffer;
|
||||
}
|
||||
|
||||
return incomingSecurityBuffers;
|
||||
}
|
||||
|
||||
public static SafeFreeCredentials AcquireCredentialsHandle(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy, bool isServer)
|
||||
{
|
||||
int protocolFlags = GetProtocolFlagsFromSslProtocols(protocols, isServer);
|
||||
@@ -103,9 +147,9 @@ namespace System.Net.Security
|
||||
if (!isServer)
|
||||
{
|
||||
direction = Interop.SspiCli.CredentialUse.SECPKG_CRED_OUTBOUND;
|
||||
flags =
|
||||
Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_MANUAL_CRED_VALIDATION |
|
||||
Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_NO_DEFAULT_CREDS |
|
||||
flags =
|
||||
Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_MANUAL_CRED_VALIDATION |
|
||||
Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_NO_DEFAULT_CREDS |
|
||||
Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_SEND_AUX_RECORD;
|
||||
|
||||
// CoreFX: always opt-in SCH_USE_STRONG_CRYPTO except for SSL3.
|
||||
@@ -131,6 +175,24 @@ namespace System.Net.Security
|
||||
return AcquireCredentialsHandle(direction, secureCredential);
|
||||
}
|
||||
|
||||
internal static byte[] GetNegotiatedApplicationProtocol(SafeDeleteContext context)
|
||||
{
|
||||
Interop.SecPkgContext_ApplicationProtocol alpnContext = SSPIWrapper.QueryContextAttributes(
|
||||
GlobalSSPI.SSPISecureChannel,
|
||||
context,
|
||||
Interop.SspiCli.ContextAttribute.SECPKG_ATTR_APPLICATION_PROTOCOL) as Interop.SecPkgContext_ApplicationProtocol;
|
||||
|
||||
// Check if the context returned is alpn data, with successful negotiation.
|
||||
if (alpnContext == null ||
|
||||
alpnContext.ProtoNegoExt != Interop.ApplicationProtocolNegotiationExt.ALPN ||
|
||||
alpnContext.ProtoNegoStatus != Interop.ApplicationProtocolNegotiationStatus.Success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return alpnContext.Protocol;
|
||||
}
|
||||
|
||||
public static unsafe SecurityStatusPal EncryptMessage(SafeDeleteContext securityContext, ReadOnlyMemory<byte> input, int headerSize, int trailerSize, ref byte[] output, out int resultSize)
|
||||
{
|
||||
// Ensure that there is sufficient space for the message output.
|
||||
@@ -182,7 +244,8 @@ namespace System.Net.Security
|
||||
|
||||
if (errorCode != 0)
|
||||
{
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Info(securityContext, $"Encrypt ERROR {errorCode:X}");
|
||||
if (NetEventSource.IsEnabled)
|
||||
NetEventSource.Info(securityContext, $"Encrypt ERROR {errorCode:X}");
|
||||
resultSize = 0;
|
||||
return SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode);
|
||||
}
|
||||
@@ -266,7 +329,7 @@ namespace System.Net.Security
|
||||
ref securityContext,
|
||||
bufferDesc);
|
||||
|
||||
return SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(errorCode, attachException:true);
|
||||
return SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(errorCode, attachException: true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -287,7 +350,7 @@ namespace System.Net.Security
|
||||
ref securityContext,
|
||||
bufferDesc);
|
||||
|
||||
return SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(errorCode, attachException:true);
|
||||
return SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(errorCode, attachException: true);
|
||||
}
|
||||
|
||||
public static unsafe SafeFreeContextBufferChannelBinding QueryContextChannelBinding(SafeDeleteContext securityContext, ChannelBindingKind attribute)
|
||||
@@ -402,7 +465,7 @@ namespace System.Net.Security
|
||||
return SSPIWrapper.AcquireCredentialsHandle(GlobalSSPI.SSPISecureChannel, SecurityPackage, credUsage, secureCredential);
|
||||
});
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Fail("AcquireCredentialsHandle failed.", ex.ToString());
|
||||
return SSPIWrapper.AcquireCredentialsHandle(GlobalSSPI.SSPISecureChannel, SecurityPackage, credUsage, secureCredential);
|
||||
|
||||
@@ -12,14 +12,19 @@ namespace System.Security.Authentication
|
||||
/// remote party willingness of accepting that.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
#if !MONO
|
||||
[System.Runtime.CompilerServices.TypeForwardedFrom("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public class AuthenticationException : SystemException
|
||||
{
|
||||
public AuthenticationException() { }
|
||||
|
||||
public AuthenticationException(string message) : base(message) { }
|
||||
|
||||
public AuthenticationException(string message, Exception innerException) : base(message, innerException) { }
|
||||
|
||||
protected AuthenticationException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
|
||||
{
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,14 +36,19 @@ namespace System.Security.Authentication
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
#if !MONO
|
||||
[System.Runtime.CompilerServices.TypeForwardedFrom("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
|
||||
#endif
|
||||
public class InvalidCredentialException : AuthenticationException
|
||||
{
|
||||
public InvalidCredentialException() { }
|
||||
|
||||
public InvalidCredentialException(string message) : base(message) { }
|
||||
|
||||
public InvalidCredentialException(string message, Exception innerException) : base(message, innerException) { }
|
||||
|
||||
protected InvalidCredentialException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
|
||||
{
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user