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
4 changes: 2 additions & 2 deletions .nuget/packages.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit.ConsoleRunner" version="3.8.0" />
<package id="NUnit.ConsoleRunner" version="3.9.0" />
<package id="NUnit.Extension.NUnitV2ResultWriter" version="3.6.0" />
<package id="JetBrains.dotCover.CommandLineTools" version="2018.2.0" />
<package id="JetBrains.dotCover.CommandLineTools" version="2018.2.3" />
</packages>
37 changes: 33 additions & 4 deletions Hazelcast.Net/Hazelcast.Client.Connection/ClientConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
Expand Down Expand Up @@ -111,14 +113,41 @@ public ClientConnection(ClientConnectionManager clientConnectionManager,
_builder = new ClientMessageBuilder(invocationService.HandleClientMessage);

var networkStream = new NetworkStream(_clientSocket, false);
if (clientNetworkConfig.GetSSLConfig().IsEnabled())
var sslConfig = clientNetworkConfig.GetSSLConfig();
if (sslConfig.IsEnabled())
{
var sslStream = new SslStream(networkStream, false,
(sender, certificate, chain, sslPolicyErrors) =>
RemoteCertificateValidationCallback(sender, certificate, chain, sslPolicyErrors,
clientNetworkConfig), null);
var certificateName = clientNetworkConfig.GetSSLConfig().GetCertificateName() ?? "";
sslStream.AuthenticateAsClient(certificateName);
var certificateName = sslConfig.GetCertificateName() ?? "";
var cerPath = sslConfig.GetCertificateFilePath();
if (cerPath != null)
{
var clientCertificates= new X509Certificate2Collection();
try
{
clientCertificates.Import(cerPath, sslConfig.GetCertificatePassword(), X509KeyStorageFlags.DefaultKeySet);
}
catch (Exception)
{
Logger.Finest(string.Format("Cannot load client certificate:{0}.", cerPath));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we have a higher log level for this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Client will fail to start and receive the same exception so I think that's enough.

throw;
}

var enabledSslProtocols = sslConfig.GetSslProtocol();
var checkCertificateRevocation = sslConfig.IsCheckCertificateRevocation();
sslStream.AuthenticateAsClient(certificateName, clientCertificates, enabledSslProtocols, checkCertificateRevocation);
}
else
{
sslStream.AuthenticateAsClient(certificateName);
}

Logger.Info(string.Format(
"Client connection ready. Encrypted:{0}, MutualAuthenticated:{1} using ssl protocol:{2}",
sslStream.IsEncrypted, sslStream.IsMutuallyAuthenticated, sslStream.SslProtocol));

_stream = sslStream;
}
else
Expand All @@ -135,7 +164,7 @@ public ClientConnection(ClientConnectionManager clientConnectionManager,
{
_stream.Close();
}
throw new IOException("Cannot connect! Socket error:" + e.Message);
throw new IOException("Cannot init connection.", e);
}
}

Expand Down
73 changes: 69 additions & 4 deletions Hazelcast.Net/Hazelcast.Config/SSLConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Authentication;
using System.Text;

namespace Hazelcast.Config
Expand All @@ -23,10 +26,30 @@ namespace Hazelcast.Config
public class SSLConfig
{
/// <summary>
/// Certifate Name; CN part of the Certificate Subject.
/// Certificate Name to be validated against SAN field of the remote certificate, if not present then the CN part of the Certificate Subject.
/// </summary>
public const string CertificateName = "CertificateServerName";

/// <summary>
/// Certificate File path.
/// </summary>
public const string CertificateFilePath = "CertificateFilePath";

/// <summary>
/// Password need to import the certificates.
/// </summary>
public const string CertificatePassword = "CertificatePassword";

/// <summary>
/// SSL/TLS protocol. string value of enum type <see cref="System.Security.Authentication.SslProtocols"/>
/// </summary>
public const string SslProtocol = "SslProtocol";

/// <summary>
/// specifies whether the certificate revocation list is checked during authentication.
/// </summary>
public const string CheckCertificateRevocation = "CheckCertificateRevocation";

/// <summary>
/// The property is used to configure ssl to enable certificate chain validation.
/// </summary>
Expand All @@ -41,6 +64,11 @@ public class SSLConfig

private Dictionary<string, string> _properties = new Dictionary<string, string>();

public SSLConfig()
{
SetProperty(ValidateCertificateChain, true.ToString());
}

public bool IsEnabled()
{
return _enabled;
Expand All @@ -57,9 +85,9 @@ public virtual Dictionary<string, string> GetProperties()
return _properties;
}

public SSLConfig SetProperties(Dictionary<string, string> properites)
public SSLConfig SetProperties(Dictionary<string, string> properties)
{
_properties = properites;
_properties = properties;
return this;
}

Expand All @@ -72,7 +100,7 @@ public virtual string GetProperty(string name)

public virtual SSLConfig SetProperty(string name, string value)
{
_properties.Add(name, value);
_properties[name] = value;
return this;
}

Expand All @@ -93,6 +121,43 @@ internal string GetCertificateName()
return GetProperty(CertificateName);
}

internal string GetCertificateFilePath()
{
return GetProperty(CertificateFilePath);
}

internal string GetCertificatePassword()
{
return GetProperty(CertificatePassword);
}

internal SslProtocols GetSslProtocol()
{
var sslProtocol = GetProperty(SslProtocol);
if (sslProtocol == null)
{
#if NET40
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does NET40 exist for versions > 4.0 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NET40 represents the .net framework and includes all versions.
There is also NETSTANDART2_0 for net core side.
We need a compile time decision here as None option is added on Net core only.

return SslProtocols.Tls;
#else
return SslProtocols.None;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is ssl (no tls) supported for lower versions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes supported but deprecated. But None parameter means best supported TLS/SSL version to be chosen by OS level.

#endif
}
SslProtocols result;
if (Enum.TryParse(sslProtocol, true, out result))
{
return result;
}
throw new ArgumentException(
"Invalid ssl configuration: SslProtocol. You should use one of SslProtocol enum values: " +
string.Join(", ", Enum.GetNames(typeof(SslProtocols))));
}

internal bool IsCheckCertificateRevocation()
{
var prop = GetProperty(CheckCertificateRevocation);
return AbstractXmlConfigHelper.CheckTrue(prop);
}

/// <inheritdoc />
public override string ToString()
{
Expand Down
1 change: 1 addition & 0 deletions Hazelcast.Net/Hazelcast.Net.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<RootNamespace>
</RootNamespace>
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\Hazelcast.Net.xml</DocumentationFile>
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>
<PropertyGroup Label="sign">
<!--Condition=" '$(OS)' != 'Windows_NT' "-->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public virtual void TestXmlParserWithConfigFile()
[Test]
public virtual void TestXmlParserWithReader()
{
var clientConfig = XmlClientConfigBuilder.Build(new StringReader(Hazelcast.Test.Resources.hazelcast_config_full));
var clientConfig = XmlClientConfigBuilder.Build(new StringReader(Resources.hazelcast_config_full));
Assert.NotNull(clientConfig);
}
}
Expand Down
105 changes: 0 additions & 105 deletions Hazelcast.Test/Hazelcast.Client.Test/ClientSSLTest.cs

This file was deleted.

Loading