Browse Source

Extended certificate validation options

release/3.x.x
Christian Kratky 7 years ago
parent
commit
9bca4aa53f
5 changed files with 56 additions and 11 deletions
  1. +21
    -4
      Frameworks/MQTTnet.NetFramework/Implementations/MqttTcpChannel.cs
  2. +21
    -4
      Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpChannel.cs
  3. +8
    -2
      Frameworks/MQTTnet.UniversalWindows/Implementations/MqttTcpChannel.cs
  4. +3
    -1
      MQTTnet.Core/Client/MqttClientTlsOptions.cs
  5. +3
    -0
      Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs

+ 21
- 4
Frameworks/MQTTnet.NetFramework/Implementations/MqttTcpChannel.cs View File

@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using MQTTnet.Core.Channel; using MQTTnet.Core.Channel;
using MQTTnet.Core.Client; using MQTTnet.Core.Client;
using System.IO; using System.IO;
using System.Linq;


namespace MQTTnet.Implementations namespace MQTTnet.Implementations
{ {
@@ -57,7 +58,7 @@ namespace MQTTnet.Implementations
if (_options.TlsOptions.UseTls) if (_options.TlsOptions.UseTls)
{ {
_sslStream = new SslStream(new NetworkStream(_socket, true), false, UserCertificateValidationCallback); _sslStream = new SslStream(new NetworkStream(_socket, true), false, UserCertificateValidationCallback);
await _sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(_options), SslProtocols.Tls12, _options.TlsOptions.CheckCertificateRevocation).ConfigureAwait(false);
await _sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(_options), SslProtocols.Tls12, _options.TlsOptions.IgnoreCertificateRevocationErrors).ConfigureAwait(false);
} }


CreateStreams(_socket, _sslStream); CreateStreams(_socket, _sslStream);
@@ -99,12 +100,28 @@ namespace MQTTnet.Implementations


private bool UserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) private bool UserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{ {
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
if (sslPolicyErrors == SslPolicyErrors.None)
{ {
return _options.TlsOptions.IgnoreCertificateChainErrors;
return true;
} }


return false;
if (chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.RevocationStatusUnknown || c.Status == X509ChainStatusFlags.Revoked || c.Status == X509ChainStatusFlags.RevocationStatusUnknown))
{
if (!_options.TlsOptions.IgnoreCertificateRevocationErrors)
{
return false;
}
}

if (chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.PartialChain))
{
if (!_options.TlsOptions.IgnoreCertificateChainErrors)
{
return false;
}
}
return _options.TlsOptions.AllowUntrustedCertificates;
} }


private static X509CertificateCollection LoadCertificates(MqttClientOptions options) private static X509CertificateCollection LoadCertificates(MqttClientOptions options)


+ 21
- 4
Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpChannel.cs View File

@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using MQTTnet.Core.Channel; using MQTTnet.Core.Channel;
using MQTTnet.Core.Client; using MQTTnet.Core.Client;
using System.IO; using System.IO;
using System.Linq;


namespace MQTTnet.Implementations namespace MQTTnet.Implementations
{ {
@@ -53,7 +54,7 @@ namespace MQTTnet.Implementations
{ {
_sslStream = new SslStream(new NetworkStream(_socket, true), false, UserCertificateValidationCallback); _sslStream = new SslStream(new NetworkStream(_socket, true), false, UserCertificateValidationCallback);
ReceiveStream = _sslStream; ReceiveStream = _sslStream;
await _sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(_options), SslProtocols.Tls12, _options.TlsOptions.CheckCertificateRevocation).ConfigureAwait(false);
await _sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(_options), SslProtocols.Tls12, _options.TlsOptions.IgnoreCertificateRevocationErrors).ConfigureAwait(false);
} }
else else
{ {
@@ -78,12 +79,28 @@ namespace MQTTnet.Implementations


private bool UserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) private bool UserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{ {
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
if (sslPolicyErrors == SslPolicyErrors.None)
{ {
return _options.TlsOptions.IgnoreCertificateChainErrors;
return true;
} }


return false;
if (chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.RevocationStatusUnknown || c.Status == X509ChainStatusFlags.Revoked || c.Status == X509ChainStatusFlags.RevocationStatusUnknown))
{
if (!_options.TlsOptions.IgnoreCertificateRevocationErrors)
{
return false;
}
}

if (chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.PartialChain))
{
if (!_options.TlsOptions.IgnoreCertificateChainErrors)
{
return false;
}
}

return _options.TlsOptions.AllowUntrustedCertificates;
} }


private static X509CertificateCollection LoadCertificates(MqttClientOptions options) private static X509CertificateCollection LoadCertificates(MqttClientOptions options)


+ 8
- 2
Frameworks/MQTTnet.UniversalWindows/Implementations/MqttTcpChannel.cs View File

@@ -47,10 +47,11 @@ namespace MQTTnet.Implementations
{ {
_socket.Control.ClientCertificate = LoadCertificate(_options); _socket.Control.ClientCertificate = LoadCertificate(_options);


if (!_options.TlsOptions.CheckCertificateRevocation)
if (_options.TlsOptions.IgnoreCertificateRevocationErrors)
{ {
_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationInformationMissing); _socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationInformationMissing);
_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Revoked);
//_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Revoked); Not supported.
_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationFailure);
} }


if (_options.TlsOptions.IgnoreCertificateChainErrors) if (_options.TlsOptions.IgnoreCertificateChainErrors)
@@ -58,6 +59,11 @@ namespace MQTTnet.Implementations
_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.IncompleteChain); _socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.IncompleteChain);
} }


if (_options.TlsOptions.AllowUntrustedCertificates)
{
_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
}
await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString(), SocketProtectionLevel.Tls12); await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString(), SocketProtectionLevel.Tls12);
} }




+ 3
- 1
MQTTnet.Core/Client/MqttClientTlsOptions.cs View File

@@ -6,10 +6,12 @@ namespace MQTTnet.Core.Client
{ {
public bool UseTls { get; set; } public bool UseTls { get; set; }


public bool CheckCertificateRevocation { get; set; }
public bool IgnoreCertificateRevocationErrors { get; set; }


public bool IgnoreCertificateChainErrors { get; set; } public bool IgnoreCertificateChainErrors { get; set; }


public bool AllowUntrustedCertificates { get; set; }

public List<byte[]> Certificates { get; set; } public List<byte[]> Certificates { get; set; }
} }
} }

+ 3
- 0
Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs View File

@@ -63,6 +63,9 @@ namespace MQTTnet.TestApp.UniversalWindows
options.Password = Password.Text; options.Password = Password.Text;
options.ClientId = ClientId.Text; options.ClientId = ClientId.Text;
options.TlsOptions.UseTls = UseTls.IsChecked == true; options.TlsOptions.UseTls = UseTls.IsChecked == true;
options.TlsOptions.IgnoreCertificateChainErrors = true;
options.TlsOptions.IgnoreCertificateRevocationErrors = true;
options.TlsOptions.AllowUntrustedCertificates = true;
try try
{ {


Loading…
Cancel
Save