@@ -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) | ||||
@@ -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) | ||||
@@ -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); | ||||
} | } | ||||
@@ -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; } | ||||
} | } | ||||
} | } |
@@ -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 | ||||
{ | { | ||||