From 4c4539509cb523c1f6d1a3ee113a4a5a2bd5ec95 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sat, 7 Oct 2017 19:22:26 +0200 Subject: [PATCH] Add support for ignored certificate chain errors (Self signed) --- .../Implementations/MqttTcpChannel.cs | 14 ++++++++++++-- .../Implementations/MqttTcpChannel.cs | 12 +++++++++++- .../Implementations/MqttTcpChannel.cs | 8 +++++++- Images/Logo_128x128.png | Bin 2382 -> 1183 bytes MQTTnet.Core/Client/MqttClientTlsOptions.cs | 2 ++ 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Frameworks/MQTTnet.NetFramework/Implementations/MqttTcpChannel.cs b/Frameworks/MQTTnet.NetFramework/Implementations/MqttTcpChannel.cs index 85d9d87a..0ca1b5de 100644 --- a/Frameworks/MQTTnet.NetFramework/Implementations/MqttTcpChannel.cs +++ b/Frameworks/MQTTnet.NetFramework/Implementations/MqttTcpChannel.cs @@ -37,6 +37,7 @@ namespace MQTTnet.Implementations { _socket = socket ?? throw new ArgumentNullException(nameof(socket)); _sslStream = sslStream; + CreateStreams(socket, sslStream); } @@ -55,8 +56,7 @@ namespace MQTTnet.Implementations if (_options.TlsOptions.UseTls) { - _sslStream = new SslStream(new NetworkStream(_socket, true)); - + _sslStream = new SslStream(new NetworkStream(_socket, true), false, UserCertificateValidationCallback); await _sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(_options), SslProtocols.Tls12, _options.TlsOptions.CheckCertificateRevocation).ConfigureAwait(false); } @@ -97,6 +97,16 @@ namespace MQTTnet.Implementations ReceiveStream = new BufferedStream(RawReceiveStream, BufferSize); } + private bool UserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) + { + if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) + { + return _options.TlsOptions.IgnoreCertificateChainErrors; + } + + return false; + } + private static X509CertificateCollection LoadCertificates(MqttClientOptions options) { var certificates = new X509CertificateCollection(); diff --git a/Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpChannel.cs b/Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpChannel.cs index fd283487..aa91b121 100644 --- a/Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpChannel.cs +++ b/Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpChannel.cs @@ -51,7 +51,7 @@ namespace MQTTnet.Implementations if (_options.TlsOptions.UseTls) { - _sslStream = new SslStream(new NetworkStream(_socket, true)); + _sslStream = new SslStream(new NetworkStream(_socket, true), false, UserCertificateValidationCallback); ReceiveStream = _sslStream; await _sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(_options), SslProtocols.Tls12, _options.TlsOptions.CheckCertificateRevocation).ConfigureAwait(false); } @@ -76,6 +76,16 @@ namespace MQTTnet.Implementations _sslStream = null; } + private bool UserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) + { + if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) + { + return _options.TlsOptions.IgnoreCertificateChainErrors; + } + + return false; + } + private static X509CertificateCollection LoadCertificates(MqttClientOptions options) { var certificates = new X509CertificateCollection(); diff --git a/Frameworks/MQTTnet.UniversalWindows/Implementations/MqttTcpChannel.cs b/Frameworks/MQTTnet.UniversalWindows/Implementations/MqttTcpChannel.cs index 975928e0..c7501f09 100644 --- a/Frameworks/MQTTnet.UniversalWindows/Implementations/MqttTcpChannel.cs +++ b/Frameworks/MQTTnet.UniversalWindows/Implementations/MqttTcpChannel.cs @@ -24,6 +24,7 @@ namespace MQTTnet.Implementations public MqttTcpChannel(StreamSocket socket) { _socket = socket ?? throw new ArgumentNullException(nameof(socket)); + CreateStreams(); } @@ -48,8 +49,13 @@ namespace MQTTnet.Implementations if (!_options.TlsOptions.CheckCertificateRevocation) { - _socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.IncompleteChain); _socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationInformationMissing); + _socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Revoked); + } + + if (_options.TlsOptions.IgnoreCertificateChainErrors) + { + _socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.IncompleteChain); } await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString(), SocketProtectionLevel.Tls12); diff --git a/Images/Logo_128x128.png b/Images/Logo_128x128.png index 5b88e134b0364528eb767fcb359dcf219362734a..a528d7ce54a8fa545838b6ce8373d1bdf828436e 100644 GIT binary patch literal 1183 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSEa{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QBXK1nbV$&y}K{B2$ zjv*CsZ>I&WyJIH6QmhrP@O{7UKUsmshQj4XmQGtFSH7EDCzm$$8)oOF|x#fjQ%h*~ANfzs4YPYXVnp)jY@B#_ylK{C@xIVrGff zy4Cm2UVgv-^(6+WEvtpL1h03>4}r)kGb`M?856khY!6p%*pEU+jV&v+wn#$xJ8T-* za%ZPs*tYUQTS&%duU0c-tu2v>OcEgw^*eMLewE*qmAhhZUQ!;hu=+gL-T0Lk(%f3j zv};rvj-3g6&wJ}jNXF%0i1HZ>Y@r#(i=AeR>hUh9TW$R-Zl(1ubC9&JKg8&V$&4oJ z>Q;xnuuE!vXDfQ^%!&(Xt(*w~P}xrmufA{Ie?7nVSM3*M75!`r=H$Nme(`sQ=&tV} z5G(#gFnnDnz4zr_$Jz6M;i0uumcmFotzxh{sm z_tD(5qEP3{OFDek`f?1;m3Al=`SmswCM$d3q2!j@aHtR0GXB{jy6gD=-&+|?GKBws zSsRmMcxjOC(l4)>J8DT!GYO5NyWXcT zMI^Mov!2Ny7P0WRpIQTJ*o%FWIUl5n-g=Y5v?H?B%=+hJMwu^pT)FFSG=EFK$GZ3L zl-n#97UbK$vR003tXmHeVJ#4?eSfBWLHVk3$9(&zVT>Be)wfo#yafggFzj!h)MZ`} z8@ll9LMLe;Ig=~5tY|kw#$v54mTNBjJ;QbPJTMj}NB>hVIKp*zHZT%_qCP;YGldWE zeE9}aZp6sr^nNmg;gCNcn99^Y*Eh@#1!{vhcF9$H#w|OeLGHcEXrf)RAH>WQb!awA zkGm@m@>IOM!{h~b6IF~fOw0&oWq|;(nA(c-hI3N{(q+PZ;tA-%%8*#EKC?YUHx3vIVCg!05!-BEC2ui literal 2382 zcmd6o`#0467RM)4cK^rUz~9+8yXnUP2gkr6Y-C1RM|a|$)h0k@-oy901i%rU^j5%6>ZP8|oloB`SifaU^ty8x$M0Us*h;|BV=gLHS0 zaS~*BfPS8!|0&Sl3k;xvf!<)yY4D5>80-s%(803|Fw_qWWrAV;Aj=;N4*RLat^bML9@OE>fI}l;k1T z@{!U4TM)QOyHUZI!6*q3FpY(Ni%sqGz?D`p2UBI??kd=!>W5i)UyB4%uu)eogUpMxy2kY;} z-iztO2Hs(V{n+4pY-kW0`hX38#72j((P8Y<2*w-1$42q7PxxmZK0b!?$MA`9{0kqS zoWQ5P;M0@%^c4Pe3ja2ZfB%Yq|Aq^`<1^p!Sphyfga4Q#ev0`)%>N`7=81&`;@2Ya z`xo*1HzE8@073!;2oNM7h=3sife8d5L?Qx32}}$|;5b1LOG``QA^d+km~T(C_)Rh) z*3>W(>CfinSkWF_=_4*Guq<3zPQi2*n-=Oz3ZXI2u(Z$kvXu8}@731P+b8KBMIx=N zwJ|q6e$MkpG0LGhZ)tP6VSaIkQ^!?*P5;o{Y;NBA9J`;~mP>8QY*__8uKiy*Qw8qU z+T8mx8&sz8lBnzKmuR=4lA+1t3PCD>$IJl@eV;!@mA(Ysq93-dlt?(NyiQtbSr+1b zv-0!T)aj;Q;P%WGU)okvo8x}1P1S(V;?E^s|9YOf`$VWba+I39WB6XD3rtzCI85y2X9AB<*Uz&{*m9(AlHP?>jec@s_s?jI#YvsC8-B zXxQBRt4#OiUHb$@%DMw;@oT3Y7VC=?-#QntD_%K-tGmB4_*ZtMM0>~+8@Vr%8e>XT zfmo8s%%g;U;7=0?U`xpfqa7xvjhtNDtq02E9dD-$qMxWzcizEODHeO$B9K3wU@|@xyHgm)Husy_YLqP}f;WJf^1d>N>d1Td&-T zNz`2ASkLM-7-jpXfXixiluFZpaZ4mDkz8Ij}rPn?sXD|FRFIm=qnmfUw5(~R^Uton?uhqh-9X!gWx z%!oW@-n)q`yLQ4;|JIC5$cZt_8~Ql&!#2~AE>6S8OBYthp5}1=JyhfbNDVImW4`)Q z@xM~m6dYM&8JVTAR<6A%c$BXkT$KAy0*AtAk;PJmc5U}|KJ3w$9FthPxwO3K*SRcqbCohmth!5wea0BeuZU0S}5fRyHLKg(U0W7ds?!)jemjrC1e zn8o+yeOiA`e(|N+!k+3wjHpAxh=CY8fBWp%6}CRHwDAYmJe@T6S(8t)t@-r=GC%Cu z8`gGV*d1g5y^=&PQ3;+_Ke+PVwWb{>IrXg-Q)#;ll!%xC3xg5cmP~bH%RYMkhW+Pf zHzWnI1%X`$<>Fs4A(%HAn7VNi2+`=W1MpoMO*(q71NLSX_a;C1jO?x&PbiOM1(|ZD zn3b(1s-Ho!zfon zLbKzV2mC4Dm`oWUwZp}~b*iCkv<7m!6S-f~GLuMmxBqJzyvt@Kf396?&r` z4%hQ25#{x~RXX@hyL^von{=_Ozpmoequ#+A4SRupEuLANRVOzzJ6~gR<>duaRkBxN zb)QGXlc7hE$UA#Owte}aPeWP0pI*KU`F%dmgW#ec9|mYLav~PISN_;oP_6HoqV1v zXkL3@w2_@FtdchKZK$gZk}zi8ejmY#>o03a)!K16DznHrj~;LEzZJSH&n9_?bmM4s U-EO8s%YTuLg}r(85wFDm08p92HUIzs diff --git a/MQTTnet.Core/Client/MqttClientTlsOptions.cs b/MQTTnet.Core/Client/MqttClientTlsOptions.cs index 6a7b9cf3..a5595d2c 100644 --- a/MQTTnet.Core/Client/MqttClientTlsOptions.cs +++ b/MQTTnet.Core/Client/MqttClientTlsOptions.cs @@ -8,6 +8,8 @@ namespace MQTTnet.Core.Client public bool CheckCertificateRevocation { get; set; } + public bool IgnoreCertificateChainErrors { get; set; } + public List Certificates { get; set; } } }