Imported Upstream version 6.4.0.137

Former-commit-id: 943baa9f16a098c33e129777827f3a9d20da00d6
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2019-07-26 19:53:28 +00:00
parent e9207cf623
commit ef583813eb
2712 changed files with 74169 additions and 40587 deletions

View File

@@ -46,6 +46,15 @@ namespace System.Net
{
throw Interop.AppleCrypto.CreateExceptionForOSStatus(osStatus);
}
if (sslAuthenticationOptions.ApplicationProtocols != null)
{
// On OSX coretls supports only client side. For server, we will silently ignore the option.
if (!sslAuthenticationOptions.IsServer)
{
Interop.AppleCrypto.SslCtxSetAlpnProtos(_sslContext, sslAuthenticationOptions.ApplicationProtocols);
}
}
}
catch (Exception ex)
{

View File

@@ -865,9 +865,12 @@ namespace System.Net.Security
}
output = outgoingSecurity.token;
byte[] alpnResult = SslStreamPal.GetNegotiatedApplicationProtocol(_securityContext);
_negotiatedApplicationProtocol = alpnResult == null ? default : new SslApplicationProtocol(alpnResult, false);
if (_negotiatedApplicationProtocol == default)
{
// try to get ALPN info unless we already have it. (this function can be called multiple times)
byte[] alpnResult = SslStreamPal.GetNegotiatedApplicationProtocol(_securityContext);
_negotiatedApplicationProtocol = alpnResult == null ? default : new SslApplicationProtocol(alpnResult, false);
}
return status;
}

View File

@@ -103,8 +103,10 @@ namespace System.Net.Security
internal static byte[] GetNegotiatedApplicationProtocol(SafeDeleteContext context)
{
// OSX SecureTransport does not export APIs to support ALPN, no-op.
return null;
if (context == null)
return null;
return Interop.AppleCrypto.SslGetAlpnSelected(((SafeDeleteSslContext)context).SslContext);
}
public static SecurityStatusPal EncryptMessage(

View File

@@ -159,7 +159,7 @@ namespace System.Net.Security
}
// 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.
// If it was, then that indicates ALPN failed, send failure.
// We have this workaround, as openssl supports terminating handshake only from version 1.1.0,
// whereas ALPN is supported from version 1.0.2.
SafeSslHandle sslContext = ((SafeDeleteSslContext)context).SslContext;

View File

@@ -42,6 +42,7 @@ namespace System.Net.Security.Tests
}
[Fact]
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono, "Mono ignores EncryptionPolicy")]
public async Task ClientAsyncAuthenticate_ServerNoEncryption_NoConnect()
{
await Assert.ThrowsAsync<IOException>(() => ClientAsyncSslHelper(EncryptionPolicy.NoEncryption));
@@ -57,11 +58,12 @@ namespace System.Net.Security.Tests
[Fact]
[PlatformSpecific(TestPlatforms.Windows)]
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono)]
public async Task ClientAsyncAuthenticate_Ssl2WithSelf_Success()
{
// Test Ssl2 against itself. This is a standalone test as even on versions where Windows supports Ssl2,
// it appears to have rules around not using it when other protocols are mentioned.
if (!PlatformDetection.IsWindows10Version1607OrGreater)
if (!PlatformDetection.IsMono && !PlatformDetection.IsWindows10Version1607OrGreater)
{
#pragma warning disable 0618
await ClientAsyncSslHelper(SslProtocols.Ssl2, SslProtocols.Ssl2);
@@ -114,9 +116,12 @@ namespace System.Net.Security.Tests
private static IEnumerable<object[]> ProtocolMismatchData()
{
#pragma warning disable 0618
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Ssl3, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Tls12, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl3, SslProtocols.Tls12, typeof(Exception) };
if (!PlatformDetection.IsMono)
{
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Ssl3, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Tls12, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl3, SslProtocols.Tls12, typeof(Exception) };
}
#pragma warning restore 0618
yield return new object[] { SslProtocols.Tls, SslProtocols.Tls11, typeof(IOException) };
yield return new object[] { SslProtocols.Tls, SslProtocols.Tls12, typeof(IOException) };

View File

@@ -75,6 +75,7 @@ namespace System.Net.Security.Tests
}
[Fact]
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono, "Mono ignores EncryptionPolicy")]
public async Task ClientDefaultEncryption_ServerNoEncryption_NoConnect()
{
using (var serverNoEncryption = new DummyTcpServer(

View File

@@ -9,6 +9,7 @@ using Xunit;
namespace System.Net.Security.Tests
{
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono)]
public class LoggingTest : RemoteExecutorTestBase
{
[Fact]

View File

@@ -23,6 +23,7 @@ namespace System.Net.Security.Tests
}
[Fact]
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono, "Mono ignores EncryptionPolicy")]
public async Task SslStreamConstructor_BadEncryptionPolicy_ThrowException()
{
using (var _remoteServer = new DummyTcpServer(

View File

@@ -59,7 +59,12 @@ namespace System.Net.Security.Tests
});
Assert.NotNull(e);
Assert.IsAssignableFrom(expectedException, e);
// FIXME: the exact exception type is an implementation detail and Mono sometimes throws
// IOException as well as AuthenticationException.
if (!PlatformDetection.IsMono)
{
Assert.IsAssignableFrom(expectedException, e);
}
}
[Theory]
@@ -73,9 +78,12 @@ namespace System.Net.Security.Tests
private static IEnumerable<object[]> ProtocolMismatchData()
{
#pragma warning disable 0618
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Ssl3, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Tls12, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl3, SslProtocols.Tls12, typeof(Exception) };
if (!PlatformDetection.IsMono)
{
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Ssl3, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Tls12, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl3, SslProtocols.Tls12, typeof(Exception) };
}
#pragma warning restore 0618
yield return new object[] { SslProtocols.Tls, SslProtocols.Tls11, typeof(AuthenticationException) };
yield return new object[] { SslProtocols.Tls, SslProtocols.Tls12, typeof(AuthenticationException) };
@@ -115,11 +123,21 @@ namespace System.Net.Security.Tests
TestConfiguration.PassingTestTimeoutMilliseconds);
using (TcpClient serverConnection = await serverAccept)
using (SslStream sslClientStream = new SslStream(clientConnection.GetStream()))
using (SslStream sslServerStream = new SslStream(
clientConnection.GetStream(),
false,
AllowEmptyClientCertificate))
using (SslStream sslClientStream = new SslStream(
serverConnection.GetStream(),
false,
AllowAnyServerCertificate))
delegate {
// Allow any certificate from the server.
// Note that simply ignoring exceptions from AuthenticateAsClientAsync() is not enough
// because in Mono, certificate validation is performed during the handshake and a failure
// would result in the connection being terminated before the handshake completed, thus
// making the server-side AuthenticateAsServerAsync() fail as well.
return true;
}))
{
string serverName = _serverCertificate.GetNameInfo(X509NameType.SimpleName, false);
@@ -167,7 +185,7 @@ namespace System.Net.Security.Tests
}
// The following method is invoked by the RemoteCertificateValidationDelegate.
private bool AllowAnyServerCertificate(
private bool AllowEmptyClientCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,

View File

@@ -13,6 +13,7 @@ using Xunit.Abstractions;
namespace System.Net.Security.Tests
{
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono, "Mono ignores EncryptionPolicy")]
public class ServerNoEncryptionTest
{
private readonly ITestOutputHelper _log;

View File

@@ -57,6 +57,7 @@ namespace System.Net.Security.Tests
}
[Fact]
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono)]
public async Task SslStream_StreamToStream_ServerInitiatedCloseNotify_Ok()
{
VirtualNetwork network = new VirtualNetwork();
@@ -89,6 +90,7 @@ namespace System.Net.Security.Tests
}
[Fact]
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono)]
public async Task SslStream_StreamToStream_ClientInitiatedCloseNotify_Ok()
{
VirtualNetwork network = new VirtualNetwork();

View File

@@ -15,19 +15,25 @@ using System.Threading;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
namespace System.Net.Security.Tests
{
using Configuration = System.Net.Test.Common.Configuration;
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono)]
public class SslStreamAlpnTests
{
// Windows - Schannel supports alpn from win8 and higher.
// Linux - OpenSsl supports alpn from openssl 1.0.2 and higher.
// OSX - SecureTransport doesn't expose alpn APIs.
private static bool BackendSupportsAlpn => (PlatformDetection.IsWindows && !PlatformDetection.IsWindows7) ||
(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) &&
(PlatformDetection.OpenSslVersion.Major >= 1 && (PlatformDetection.OpenSslVersion.Minor >= 1 || PlatformDetection.OpenSslVersion.Build >= 2)));
private static bool BackendSupportsAlpn => PlatformDetection.SupportsAlpn;
private static bool ClientSupportsAlpn => PlatformDetection.SupportsClientAlpn;
readonly ITestOutputHelper _output;
public static readonly object[][] Http2Servers = Configuration.Http.Http2Servers;
public SslStreamAlpnTests(ITestOutputHelper output)
{
_output = output;
}
private async Task DoHandshakeWithOptions(SslStream clientSslStream, SslStream serverSslStream, SslClientAuthenticationOptions clientOptions, SslServerAuthenticationOptions serverOptions)
{
@@ -185,6 +191,36 @@ namespace System.Net.Security.Tests
}
}
[OuterLoop("Uses external server")]
[ConditionalTheory(nameof(ClientSupportsAlpn))]
[MemberData(nameof(Http2Servers))]
public async Task SslStream_Http2_Alpn_Success(Uri server)
{
using (TcpClient client = new TcpClient())
{
try
{
await client.ConnectAsync(server.Host, server.Port);
using (SslStream clientStream = new SslStream(client.GetStream(), leaveInnerStreamOpen: false))
{
SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions
{
ApplicationProtocols = new List<SslApplicationProtocol> { SslApplicationProtocol.Http2 , SslApplicationProtocol.Http11 },
TargetHost = server.Host
};
await clientStream.AuthenticateAsClientAsync(clientOptions, CancellationToken.None);
Assert.Equal("h2", clientStream.NegotiatedApplicationProtocol.ToString());
}
}
catch (Exception e)
{
// Failures to connect do not cause test failure.
_output.WriteLine("Unable to connect: {0}", e);
}
}
}
internal static IEnumerable<object[]> Alpn_TestData()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))

View File

@@ -121,9 +121,12 @@ namespace System.Net.Security.Tests
false));
Assert.NotNull(e.InnerException);
Assert.True(e.InnerException.Message.Contains("SSL_ERROR_SSL"));
Assert.NotNull(e.InnerException.InnerException);
Assert.True(e.InnerException.InnerException.Message.Contains("protocol"));
if (!PlatformDetection.IsMono)
{
Assert.True(e.InnerException.Message.Contains("SSL_ERROR_SSL"));
Assert.NotNull(e.InnerException.InnerException);
Assert.True(e.InnerException.InnerException.Message.Contains("protocol"));
}
}
}

View File

@@ -55,7 +55,11 @@ namespace System.Net.Security.Tests
Task t2 = server.AuthenticateAsServerAsync(certificate);
await Assert.ThrowsAsync<AuthenticationException>(() => t1);
await t2;
// Mono closes the connection during the handshake.
if (PlatformDetection.IsMono)
await Assert.ThrowsAsync<VirtualNetwork.VirtualNetworkConnectionBroken>(() => t2);
else
await t2;
}
}
@@ -75,9 +79,15 @@ namespace System.Net.Security.Tests
using (var server = new SslStream(serverStream, false, null, selectionCallback))
using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
{
await Assert.ThrowsAsync<NotSupportedException>(async () =>
await TestConfiguration.WhenAllOrAnyFailedWithTimeout(client.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false)), server.AuthenticateAsServerAsync(certificate))
);
var clientJob = client.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false));
await Assert.ThrowsAsync<NotSupportedException>(() => server.AuthenticateAsServerAsync(certificate));
// Mono terminates the connection when the server handshake fails.
if (PlatformDetection.IsMono)
await Assert.ThrowsAsync<VirtualNetwork.VirtualNetworkConnectionBroken>(() => clientJob);
else
await TestConfiguration.WhenAllOrAnyFailedWithTimeout(clientJob);
}
}
@@ -360,7 +370,7 @@ namespace System.Net.Security.Tests
await clientSslStream.WriteAsync(new byte[] { 2 }, 0, 1);
if (PlatformDetection.IsFullFramework)
if (PlatformDetection.IsFullFramework || PlatformDetection.IsMono)
{
await Assert.ThrowsAsync<ObjectDisposedException>(() => serverReadTask);
}
@@ -426,7 +436,7 @@ namespace System.Net.Security.Tests
// Do normal reads as requested until the read mode is set
// to 1. Then do a single read of only 10 bytes to read only
// part of the message, and subsequently return EOF.
if (readMode == 0)
if (readMode == 0 || count < 15)
{
return serverNetworkStream.Read(buffer, offset, count);
}

View File

@@ -86,6 +86,14 @@ namespace System.Net.Security.Tests
public async Task ClientAndServer_OneUsesDefault_OtherUsesLowerProtocol_Fails(
SslProtocols? clientProtocols, SslProtocols? serverProtocols)
{
if (PlatformDetection.IsMono)
{
#pragma warning disable 0618
if (clientProtocols == SslProtocols.Ssl2 || serverProtocols == SslProtocols.Ssl2)
return;
#pragma warning restore 0618
}
using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate())
using (X509Certificate2 clientCertificate = Configuration.Certificates.GetClientCertificate())
{

View File

@@ -60,6 +60,9 @@
<Compile Include="$(CommonTestPath)\System\Net\Configuration.Certificates.cs">
<Link>Common\System\Net\Configuration.Certificates.cs</Link>
</Compile>
<Compile Include="$(CommonTestPath)\System\Net\Configuration.Http.cs">
<Link>Common\System\Net\Configuration.Http.cs</Link>
</Compile>
<Compile Include="$(CommonTestPath)\System\Net\HttpsTestClient.cs">
<Link>Common\System\Net\HttpsTestClient.cs</Link>
</Compile>
@@ -166,5 +169,4 @@
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

View File

@@ -12,6 +12,7 @@ using Xunit;
namespace System.Net.Security.Tests
{
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono)]
public class TransportContextTest
{
// The following method is invoked by the RemoteCertificateValidationDelegate.