You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2021/11/16 16:35:57 UTC
[ignite] branch ignite-2.12 updated: IGNITE-15915 .NET: Allow null SslStreamFactory.CertificatePath (#9566)
This is an automated email from the ASF dual-hosted git repository.
ptupitsyn pushed a commit to branch ignite-2.12
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/ignite-2.12 by this push:
new 22ff78d IGNITE-15915 .NET: Allow null SslStreamFactory.CertificatePath (#9566)
22ff78d is described below
commit 22ff78d80c9c487cf904854a0e435960a4b0d836
Author: Pavel Tupitsyn <pt...@apache.org>
AuthorDate: Tue Nov 16 19:32:50 2021 +0300
IGNITE-15915 .NET: Allow null SslStreamFactory.CertificatePath (#9566)
Allow thin client to establish SSL connection without client-side certificate when `ClientConnectorConfiguration.sslClientAuth` is `false` on server.
(cherry picked from commit 52553241ea2986b966610592db180ac2291ea71a)
---
.../Apache.Ignite.Core.Tests.DotNetCore.csproj | 3 ++
.../Client/ClientConnectionTest.cs | 62 +++++++++++++++++++++
.../Client/RawSecureSocketTest.cs | 63 +++++++++++++++-------
...-ssl.xml => server-with-ssl-no-client-auth.xml} | 6 +--
.../Config/Client/server-with-ssl.xml | 2 +-
.../Apache.Ignite.Core/Client/SslStreamFactory.cs | 9 +++-
6 files changed, 120 insertions(+), 25 deletions(-)
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.DotNetCore.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.DotNetCore.csproj
index bcdedc2..a1dd4f1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.DotNetCore.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.DotNetCore.csproj
@@ -107,6 +107,9 @@
<None Update="Examples\ExpectedOutput\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
+ <None Update="Config\Client\server-with-ssl-no-client-auth.xml">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
</ItemGroup>
<ItemGroup>
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs
index 457d261..0cfe809 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs
@@ -22,6 +22,7 @@ namespace Apache.Ignite.Core.Tests.Client
using System.Linq;
using System.Net;
using System.Net.Sockets;
+ using System.Security.Authentication;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
@@ -666,6 +667,67 @@ namespace Apache.Ignite.Core.Tests.Client
}
/// <summary>
+ /// Tests SSL connection with client-side SSL certificate.
+ /// </summary>
+ [Test]
+ public void TestSslConnectionWithClientAuth()
+ {
+ Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration())
+ {
+ SpringConfigUrl = Path.Combine("Config", "Client", "server-with-ssl.xml")
+ });
+
+ var cfg = new IgniteClientConfiguration
+ {
+ Endpoints = new[] { "127.0.0.1:11110" },
+ SslStreamFactory = new SslStreamFactory
+ {
+ CertificatePath = Path.Combine("Config", "Client", "thin-client-cert.pfx"),
+ CertificatePassword = "123456",
+ SkipServerCertificateValidation = true,
+ CheckCertificateRevocation = true,
+ SslProtocols = SslProtocols.Tls12
+ }
+ };
+
+ using (var client = Ignition.StartClient(cfg))
+ {
+ Assert.AreEqual(1, client.GetCluster().GetNodes().Count);
+ }
+
+ // Does not connect without client certificate.
+ cfg.SslStreamFactory = new SslStreamFactory { SkipServerCertificateValidation = true };
+ Assert.Catch<Exception>(() => Ignition.StartClient(cfg));
+ }
+
+ /// <summary>
+ /// Tests SSL connection without client-side SSL certificate.
+ /// </summary>
+ [Test]
+ public void TestSslConnectionWithoutClientAuth()
+ {
+ Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration())
+ {
+ SpringConfigUrl = Path.Combine("Config", "Client", "server-with-ssl-no-client-auth.xml"),
+ });
+
+ var cfg = new IgniteClientConfiguration
+ {
+ Endpoints = new[] { "127.0.0.1:11120" },
+ SslStreamFactory = new SslStreamFactory
+ {
+ SkipServerCertificateValidation = true,
+ SslProtocols = SslProtocols.Tls12
+ }
+ };
+
+ using (var client = Ignition.StartClient(cfg))
+ {
+ Assert.AreEqual(1, client.GetCluster().GetNodes().Count);
+ }
+ }
+
+ /// <summary>
/// Starts the client.
/// </summary>
private static IIgniteClient StartClient()
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSecureSocketTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSecureSocketTest.cs
index 799c6c6..69b6f38 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSecureSocketTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSecureSocketTest.cs
@@ -31,35 +31,59 @@ namespace Apache.Ignite.Core.Tests.Client
/// </summary>
public class RawSecureSocketTest
{
+ [TestFixtureSetUp]
+ public void FixtureSetUp()
+ {
+ var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
+ {
+ SpringConfigUrl = Path.Combine("Config", "Client", "server-with-ssl.xml")
+ };
+
+ Ignition.Start(cfg);
+
+ var cfgNoClientAuth = new IgniteConfiguration(TestUtils.GetTestConfiguration())
+ {
+ SpringConfigUrl = Path.Combine("Config", "Client", "server-with-ssl-no-client-auth.xml"),
+ AutoGenerateIgniteInstanceName = true
+ };
+
+ Ignition.Start(cfgNoClientAuth);
+ }
+
+ [TestFixtureTearDown]
+ public void FixtureTearDown()
+ {
+ Ignition.StopAll(true);
+ }
+
/// <summary>
/// Tests that we can do handshake over SSL without using Ignite.NET APIs.
/// </summary>
[Test]
- public void TestHandshake()
+ public void TestHandshake([Values(true, false)] bool clientCert)
{
- var igniteConfiguration = new IgniteConfiguration(TestUtils.GetTestConfiguration())
- {
- SpringConfigUrl = Path.Combine("Config", "Client", "server-with-ssl.xml")
- };
+ const string host = "127.0.0.1";
+ var port = clientCert ? 11110 : 11120;
- using (Ignition.Start(igniteConfiguration))
+ using (var client = new TcpClient(host, port))
+ using (var sslStream = new SslStream(client.GetStream(), false, ValidateServerCertificate, null))
{
- const string host = "127.0.0.1";
- const int port = 11110;
+ var certsCollection = new X509CertificateCollection(new X509Certificate[] { LoadCertificateFile() });
- using (var client = new TcpClient(host, port))
- using (var sslStream = new SslStream(client.GetStream(), false, ValidateServerCertificate, null))
+ if (clientCert)
{
- var certsCollection = new X509CertificateCollection(new X509Certificate[] {LoadCertificateFile()});
-
sslStream.AuthenticateAsClient(host, certsCollection, SslProtocols.Tls12, false);
+ }
+ else
+ {
+ sslStream.AuthenticateAsClient(host);
+ }
- Assert.IsTrue(sslStream.IsAuthenticated);
- Assert.IsTrue(sslStream.IsMutuallyAuthenticated);
- Assert.IsTrue(sslStream.IsEncrypted);
+ Assert.IsTrue(sslStream.IsAuthenticated);
+ Assert.AreEqual(clientCert, sslStream.IsMutuallyAuthenticated);
+ Assert.IsTrue(sslStream.IsEncrypted);
- DoHandshake(sslStream);
- }
+ DoHandshake(sslStream);
}
}
@@ -123,7 +147,9 @@ namespace Apache.Ignite.Core.Tests.Client
private static byte[] ReceiveMessage(Stream sock)
{
var buf = new byte[4];
- sock.Read(buf, 0, 4);
+ var read = sock.Read(buf, 0, 4);
+
+ Assert.AreEqual(4, read);
using (var stream = new BinaryHeapStream(buf))
{
@@ -150,6 +176,5 @@ namespace Apache.Ignite.Core.Tests.Client
sock.Write(stream.GetArray(), 0, stream.Position);
}
}
-
}
}
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/server-with-ssl.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/server-with-ssl-no-client-auth.xml
similarity index 96%
copy from modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/server-with-ssl.xml
copy to modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/server-with-ssl-no-client-auth.xml
index 7ef8e17..731e162 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/server-with-ssl.xml
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/server-with-ssl-no-client-auth.xml
@@ -31,11 +31,11 @@
<property name="clientConnectorConfiguration">
<bean class="org.apache.ignite.configuration.ClientConnectorConfiguration">
<property name="host" value="127.0.0.1"/>
- <property name="port" value="11110"/>
+ <property name="port" value="11120"/>
<property name="portRange" value="10"/>
<property name="sslEnabled" value="true"/>
<property name="useIgniteSslContextFactory" value="false"/>
- <property name="sslClientAuth" value="true"/>
+ <property name="sslClientAuth" value="false"/>
<property name="sslContextFactory">
<bean class="org.apache.ignite.ssl.SslContextFactory">
@@ -64,4 +64,4 @@
</bean>
</property>
</bean>
-</beans>
\ No newline at end of file
+</beans>
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/server-with-ssl.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/server-with-ssl.xml
index 7ef8e17..821031f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/server-with-ssl.xml
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Client/server-with-ssl.xml
@@ -64,4 +64,4 @@
</bean>
</property>
</bean>
-</beans>
\ No newline at end of file
+</beans>
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Client/SslStreamFactory.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Client/SslStreamFactory.cs
index 3961b09..f7a656c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Client/SslStreamFactory.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Client/SslStreamFactory.cs
@@ -49,8 +49,13 @@ namespace Apache.Ignite.Core.Client
var sslStream = new SslStream(stream, false, ValidateServerCertificate, null);
- var cert = new X509Certificate2(CertificatePath, CertificatePassword);
- var certs = new X509CertificateCollection(new X509Certificate[] { cert });
+ var cert = string.IsNullOrEmpty(CertificatePath)
+ ? null
+ : new X509Certificate2(CertificatePath, CertificatePassword);
+
+ var certs = cert == null
+ ? null
+ : new X509CertificateCollection(new X509Certificate[] { cert });
sslStream.AuthenticateAsClient(targetHost, certs, SslProtocols, CheckCertificateRevocation);