Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ public async Task CertificateSelectionCallback_DelayedCertificate_OK(bool delayC
using (server)
{
int count = 0;
bool validationCallbackCalled = false;
SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions();
clientOptions.TargetHost = "localhost";
clientOptions.AllowTlsResume = false;
// Force Tls 1.2 to avoid issues with certain OpenSSL versions and Tls 1.3
// https://github.com/openssl/openssl/issues/7384
clientOptions.EnabledSslProtocols = SslProtocols.Tls12;
Expand All @@ -81,6 +83,7 @@ public async Task CertificateSelectionCallback_DelayedCertificate_OK(bool delayC
serverOptions.ClientCertificateRequired = true;
serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
validationCallbackCalled = true;
if (sendClientCertificate)
{
Assert.NotNull(certificate);
Expand All @@ -100,6 +103,8 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
client.AuthenticateAsClientAsync(clientOptions),
server.AuthenticateAsServerAsync(serverOptions));

Assert.True(validationCallbackCalled);

// verify that the session is usable with or without client's certificate
await TestHelper.PingPong(client, server);
await TestHelper.PingPong(server, client);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,28 @@ public async Task CertificateValidationRemoteServer_EndToEnd_Ok(bool useAsync)
throw new SkipTestException($"Unable to connect to '{Configuration.Security.TlsServer.IdnHost}': {ex.Message}");
}

using (SslStream sslStream = new SslStream(client.GetStream(), false, RemoteHttpsCertValidation, null))
bool callbackCalled = false;
using (SslStream sslStream = new SslStream(client.GetStream()))
{
var options = new SslClientAuthenticationOptions
{
TargetHost = Configuration.Security.TlsServer.IdnHost,
AllowTlsResume = false,
RemoteCertificateValidationCallback = (sender, certificate, chain, errors) =>
{
callbackCalled = true;
return RemoteHttpsCertValidation(sender, certificate, chain, errors);
}
};
try
{
if (useAsync)
{
await sslStream.AuthenticateAsClientAsync(Configuration.Security.TlsServer.IdnHost);
await sslStream.AuthenticateAsClientAsync(options);
}
else
{
sslStream.AuthenticateAsClient(Configuration.Security.TlsServer.IdnHost);
sslStream.AuthenticateAsClient(options);
}
}
catch (IOException ex) when (ex.InnerException is SocketException &&
Expand All @@ -61,6 +72,8 @@ public async Task CertificateValidationRemoteServer_EndToEnd_Ok(bool useAsync)
// caused most likely by environmental failures.
throw new SkipTestException($"Unable to connect to '{Configuration.Security.TlsServer.IdnHost}': {ex.InnerException.Message}");
}

Assert.True(callbackCalled);
}
}
}
Expand Down Expand Up @@ -135,7 +148,7 @@ public Task ConnectWithRevocation_ServerCertWithoutContext_NoStapledOcsp()
[InlineData(X509RevocationMode.Offline)]
[InlineData(X509RevocationMode.Online)]
[InlineData(X509RevocationMode.NoCheck)]
public Task ConnectWithRevocation_RemoteServer_StapledOcsp_FromWindows(X509RevocationMode revocationMode)
public async Task ConnectWithRevocation_RemoteServer_StapledOcsp_FromWindows(X509RevocationMode revocationMode)
{
// This test could ideally end at the Client Hello, because it really only wants to
// ensure that the status_request extension was asserted. Since the SslStream tests
Expand All @@ -146,22 +159,26 @@ public Task ConnectWithRevocation_RemoteServer_StapledOcsp_FromWindows(X509Revoc
// but it's the best we can do right now.

string serverName = Configuration.Http.Http2Host;
bool callbackCalled = false;

SslClientAuthenticationOptions clientOpts = new SslClientAuthenticationOptions
{
TargetHost = serverName,
AllowTlsResume = false,
RemoteCertificateValidationCallback = CertificateValidationCallback,
CertificateRevocationCheckMode = revocationMode,
};

return EndToEndHelper(clientOpts);
await EndToEndHelper(clientOpts);
Assert.True(callbackCalled);

static bool CertificateValidationCallback(
bool CertificateValidationCallback(
object sender,
X509Certificate? certificate,
X509Chain? chain,
SslPolicyErrors sslPolicyErrors)
{
callbackCalled = true;
Assert.NotNull(certificate);

using (SafeCertContextHandle ctx = new SafeCertContextHandle(certificate.Handle, ownsHandle: false))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ public async Task ClientAsyncAuthenticate_ServerRequireEncryption_ConnectWithEnc
[ActiveIssue("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/dotnet/runtime/issues/115467", TestPlatforms.Android)]
public async Task ClientAsyncAuthenticate_ConnectionInfoInCallback_DoesNotThrow()
{
await ClientAsyncSslHelper(EncryptionPolicy.RequireEncryption, SslProtocols.Tls12, SslProtocolSupport.DefaultSslProtocols, AllowAnyServerCertificateAndVerifyConnectionInfo);
bool callbackCalled = false;
await ClientAsyncSslHelper(EncryptionPolicy.RequireEncryption, SslProtocols.Tls12, SslProtocolSupport.DefaultSslProtocols,
(sender, certificate, chain, errors) =>
{
callbackCalled = true;
return AllowAnyServerCertificateAndVerifyConnectionInfo(sender, certificate, chain, errors);
});
Assert.True(callbackCalled);
}

[Fact]
Expand Down Expand Up @@ -147,6 +154,7 @@ private async Task ClientAsyncSslHelper(
{
EnabledSslProtocols = clientSslProtocols,
RemoteCertificateValidationCallback = certificateCallback ?? AllowAnyServerCertificate,
AllowTlsResume = certificateCallback is null,
TargetHost = serverName
});
serverTask = server.AuthenticateAsServerAsync(new SslServerAuthenticationOptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public async Task SslStream_AllowRenegotiation_True_Succeeds()
ClientCertificates = certBundle,
EnabledSslProtocols = SslProtocols.Tls12,
CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
AllowTlsResume = false,
AllowRenegotiation = true
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,13 @@ public async Task SslStream_NetworkStream_Renegotiation_Succeeds(bool useSync)
certBundle.Add(clientCert);

// Perform handshake to establish secure connection.
await ssl.AuthenticateAsClientAsync(Configuration.Security.TlsRenegotiationServer, certBundle, SslProtocols.Tls12, false);
await ssl.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
{
TargetHost = Configuration.Security.TlsRenegotiationServer,
ClientCertificates = certBundle,
EnabledSslProtocols = SslProtocols.Tls12,
AllowTlsResume = false,
});
Assert.True(ssl.IsAuthenticated);
Assert.True(ssl.IsEncrypted);

Expand Down Expand Up @@ -760,7 +766,8 @@ public async Task SslStream_TargetHostName_Succeeds(bool useEmptyName, bool useC
Assert.Equal(string.Empty, client.TargetHostName);
Assert.Equal(string.Empty, server.TargetHostName);

SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions() { TargetHost = targetName };
// A resumed handshake skips the certificate validation callback.
SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions() { TargetHost = targetName, AllowTlsResume = false };
clientOptions.RemoteCertificateValidationCallback =
(sender, certificate, chain, sslPolicyErrors) =>
{
Expand Down Expand Up @@ -811,7 +818,7 @@ public async Task SslStream_ServerUntrustedCaWithCustomTrust_OK(bool usePartialC

int split = Random.Shared.Next(0, _certificates.ServerChain.Count - 1);

var clientOptions = new SslClientAuthenticationOptions() { TargetHost = "localhost" };
var clientOptions = new SslClientAuthenticationOptions() { TargetHost = "localhost", AllowTlsResume = false };
clientOptions.CertificateChainPolicy = new X509ChainPolicy()
{
RevocationMode = X509RevocationMode.NoCheck,
Expand Down Expand Up @@ -875,10 +882,13 @@ private async Task SslStream_ClientSendsChain_Core(SslClientAuthenticationOption
{
List<SslStream> streams = new List<SslStream>();

var serverOptions = new SslServerAuthenticationOptions() { ClientCertificateRequired = true };
int validationCount = 0;
// Exercise credential caching, but require the client to send its chain on every connection.
var serverOptions = new SslServerAuthenticationOptions() { ClientCertificateRequired = true, AllowTlsResume = false };
serverOptions.ServerCertificateContext = SslStreamCertificateContext.Create(Configuration.Certificates.GetServerCertificate(), null);
serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
validationCount++;
// Client should send chain without root CA. There is no good way how to know if the chain was built from certificates
// from wire or from system store. However, SslStream adds certificates from wire to ExtraStore in RemoteCertificateValidationCallback.
// So we verify the operation by checking the ExtraStore. On Windows, that includes leaf itself.
Expand Down Expand Up @@ -906,6 +916,8 @@ private async Task SslStream_ClientSendsChain_Core(SslClientAuthenticationOption
Task t2 = server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None);
await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);

Assert.Equal(i + 1, validationCount);

// hold to the streams so they stay in credential cache
streams.Add(client);
streams.Add(server);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class SslStreamSniTest
public async Task SslStream_ClientSendsSNIServerReceives_Ok(string hostName)
{
using X509Certificate serverCert = Configuration.Certificates.GetSelfSignedServerCertificate();
bool validationCallbackCalled = false;

await WithVirtualConnection(async (server, client) =>
{
Expand All @@ -33,6 +34,7 @@ await WithVirtualConnection(async (server, client) =>
});

SslServerAuthenticationOptions options = DefaultServerOptions();
options.AllowTlsResume = false;

int timesCallbackCalled = 0;
options.ServerCertificateSelectionCallback = (sender, actualHostName) =>
Expand All @@ -50,10 +52,12 @@ await WithVirtualConnection(async (server, client) =>
},
(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
{
validationCallbackCalled = true;
Assert.Equal(serverCert, certificate);
return true;
}
);
Assert.True(validationCallbackCalled);
}

[Theory]
Expand Down Expand Up @@ -110,6 +114,7 @@ public async Task SslStream_ServerCallbackNotSet_UsesLocalCertificateSelection(s
using X509Certificate serverCert = Configuration.Certificates.GetSelfSignedServerCertificate();

int timesCallbackCalled = 0;
bool validationCallbackCalled = false;

var selectionCallback = new LocalCertificateSelectionCallback((object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] issuers) =>
{
Expand All @@ -121,6 +126,7 @@ public async Task SslStream_ServerCallbackNotSet_UsesLocalCertificateSelection(s

var validationCallback = new RemoteCertificateValidationCallback((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
{
validationCallbackCalled = true;
Assert.Equal(serverCert, certificate);
return true;
});
Expand All @@ -135,11 +141,13 @@ public async Task SslStream_ServerCallbackNotSet_UsesLocalCertificateSelection(s
});

SslServerAuthenticationOptions options = DefaultServerOptions();
options.AllowTlsResume = false;
options.ServerCertificate = serverCert;

await TaskTimeoutExtensions.WhenAllOrAnyFailed(new[] { clientJob, server.AuthenticateAsServerAsync(options, CancellationToken.None) });

Assert.Equal(1, timesCallbackCalled);
Assert.True(validationCallbackCalled);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public async Task SslStream_StreamToStream_Authentication_IncorrectServerName_Fa
using (var server = new SslStream(stream2))
using (var certificate = Configuration.Certificates.GetServerCertificate())
{
Name = "incorrectServer";
Name = $"incorrectServer-{Guid.NewGuid():N}";
Task t1 = client.AuthenticateAsClientAsync(Name);
Task t2 = server.AuthenticateAsServerAsync(certificate);

Expand Down
Loading