Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit cac1f05

Browse files
authored
Add SslStream test to validate options aren't mutated (#27203)
* Add SslStream test to validate options aren't mutated While reading the code, I thought I saw the AuthenticateAsClientAsync options mutating the input options bag, which it shouldn't do. I wrote a test for it, only to realize that I'd read the code incorrectly and it wasn't mutating things incorrectly. But since I'd written the test, figured I might as well check it in. * Address PR feedback
1 parent d3a69ff commit cac1f05

File tree

2 files changed

+110
-1
lines changed

2 files changed

+110
-1
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Collections.Generic;
6+
using System.Net.Test.Common;
7+
using System.Security.Cryptography.X509Certificates;
8+
using System.Security.Authentication;
9+
using System.Threading.Tasks;
10+
using Xunit;
11+
using System.Linq;
12+
13+
namespace System.Net.Security.Tests
14+
{
15+
using Configuration = System.Net.Test.Common.Configuration;
16+
17+
public class SslClientAuthenticationOptionsTest
18+
{
19+
[Fact]
20+
public async Task ClientOptions_ServerOptions_NotMutatedDuringAuthentication()
21+
{
22+
using (X509Certificate2 clientCert = Configuration.Certificates.GetClientCertificate())
23+
using (X509Certificate2 serverCert = Configuration.Certificates.GetServerCertificate())
24+
{
25+
// Values used to populate client options
26+
bool clientAllowRenegotiation = false;
27+
List<SslApplicationProtocol> clientAppProtocols = new List<SslApplicationProtocol> { SslApplicationProtocol.Http11 };
28+
X509RevocationMode clientRevocation = X509RevocationMode.NoCheck;
29+
X509CertificateCollection clientCertificates = new X509CertificateCollection() { clientCert };
30+
SslProtocols clientSslProtocols = SslProtocols.Tls12;
31+
EncryptionPolicy clientEncryption = EncryptionPolicy.RequireEncryption;
32+
LocalCertificateSelectionCallback clientLocalCallback = new LocalCertificateSelectionCallback(delegate { return null; });
33+
RemoteCertificateValidationCallback clientRemoteCallback = new RemoteCertificateValidationCallback(delegate { return true; });
34+
string clientHost = serverCert.GetNameInfo(X509NameType.SimpleName, false);
35+
36+
// Values used to populate server options
37+
bool serverAllowRenegotiation = true;
38+
List<SslApplicationProtocol> serverAppProtocols = new List<SslApplicationProtocol> { SslApplicationProtocol.Http11, SslApplicationProtocol.Http2 };
39+
X509RevocationMode serverRevocation = X509RevocationMode.NoCheck;
40+
bool serverCertRequired = false;
41+
SslProtocols serverSslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12;
42+
EncryptionPolicy serverEncryption = EncryptionPolicy.AllowNoEncryption;
43+
RemoteCertificateValidationCallback serverRemoteCallback = new RemoteCertificateValidationCallback(delegate { return true; });
44+
45+
var network = new VirtualNetwork();
46+
using (var client = new SslStream(new VirtualNetworkStream(network, isServer: false)))
47+
using (var server = new SslStream(new VirtualNetworkStream(network, isServer: true)))
48+
{
49+
// Create client options
50+
var clientOptions = new SslClientAuthenticationOptions
51+
{
52+
AllowRenegotiation = clientAllowRenegotiation,
53+
ApplicationProtocols = clientAppProtocols,
54+
CertificateRevocationCheckMode = clientRevocation,
55+
ClientCertificates = clientCertificates,
56+
EnabledSslProtocols = clientSslProtocols,
57+
EncryptionPolicy = clientEncryption,
58+
LocalCertificateSelectionCallback = clientLocalCallback,
59+
RemoteCertificateValidationCallback = clientRemoteCallback,
60+
TargetHost = clientHost
61+
};
62+
63+
// Create server options
64+
var serverOptions = new SslServerAuthenticationOptions
65+
{
66+
AllowRenegotiation = serverAllowRenegotiation,
67+
ApplicationProtocols = serverAppProtocols,
68+
CertificateRevocationCheckMode = serverRevocation,
69+
ClientCertificateRequired = serverCertRequired,
70+
EnabledSslProtocols = serverSslProtocols,
71+
EncryptionPolicy = serverEncryption,
72+
RemoteCertificateValidationCallback = serverRemoteCallback,
73+
ServerCertificate = serverCert
74+
};
75+
76+
// Authenticate
77+
Task clientTask = client.AuthenticateAsClientAsync(clientOptions, default);
78+
Task serverTask = server.AuthenticateAsServerAsync(serverOptions, default);
79+
await new[] { clientTask, serverTask }.WhenAllOrAnyFailed();
80+
81+
// Validate that client options are unchanged
82+
Assert.Equal(clientAllowRenegotiation, clientOptions.AllowRenegotiation);
83+
Assert.Same(clientAppProtocols, clientOptions.ApplicationProtocols);
84+
Assert.Equal(1, clientOptions.ApplicationProtocols.Count);
85+
Assert.Equal(clientRevocation, clientOptions.CertificateRevocationCheckMode);
86+
Assert.Same(clientCertificates, clientOptions.ClientCertificates);
87+
Assert.Contains(clientCert, clientOptions.ClientCertificates.Cast<X509Certificate2>());
88+
Assert.Equal(clientSslProtocols, clientOptions.EnabledSslProtocols);
89+
Assert.Equal(clientEncryption, clientOptions.EncryptionPolicy);
90+
Assert.Same(clientLocalCallback, clientOptions.LocalCertificateSelectionCallback);
91+
Assert.Same(clientRemoteCallback, clientOptions.RemoteCertificateValidationCallback);
92+
Assert.Same(clientHost, clientOptions.TargetHost);
93+
94+
// Validate that server options are unchanged
95+
Assert.Equal(serverAllowRenegotiation, serverOptions.AllowRenegotiation);
96+
Assert.Same(serverAppProtocols, serverOptions.ApplicationProtocols);
97+
Assert.Equal(2, serverOptions.ApplicationProtocols.Count);
98+
Assert.Equal(clientRevocation, serverOptions.CertificateRevocationCheckMode);
99+
Assert.Equal(serverCertRequired, serverOptions.ClientCertificateRequired);
100+
Assert.Equal(serverSslProtocols, serverOptions.EnabledSslProtocols);
101+
Assert.Equal(serverEncryption, serverOptions.EncryptionPolicy);
102+
Assert.Same(serverRemoteCallback, serverOptions.RemoteCertificateValidationCallback);
103+
Assert.Same(serverCert, serverOptions.ServerCertificate);
104+
}
105+
}
106+
}
107+
}
108+
}

src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
</ItemGroup>
9191
<ItemGroup Condition="'$(TargetGroup)'=='netcoreapp'">
9292
<!-- TODO #13070: Add net463 to the condition after the TFM gets updated to the actual .Net 4.7-->
93+
<Compile Include="SslAuthenticationOptionsTest.cs" />
9394
<Compile Include="SslStreamAlertsTest.cs" />
9495
<Compile Include="SslStreamAllowRenegotiationTests.cs" />
9596
<Compile Include="SslStreamAlpnTests.cs" />
@@ -155,4 +156,4 @@
155156
</ProjectReference>
156157
</ItemGroup>
157158
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
158-
</Project>
159+
</Project>

0 commit comments

Comments
 (0)