diff options
author | Jose <jose@zeroc.com> | 2019-09-10 11:14:12 +0200 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2019-09-10 11:18:30 +0200 |
commit | 1389c577b783cb9bf6827d9b889b35873a1f9f44 (patch) | |
tree | 7b05de99d01c7be3cdd6d7ae753f1b1c5c8833aa /csharp/src | |
parent | IceSSL cert name verification fixes - Close #512 (#515) (diff) | |
download | ice-1389c577b783cb9bf6827d9b889b35873a1f9f44.tar.bz2 ice-1389c577b783cb9bf6827d9b889b35873a1f9f44.tar.xz ice-1389c577b783cb9bf6827d9b889b35873a1f9f44.zip |
Dispose the X509Chain with .NET Standard 2.0 - Close #518
Diffstat (limited to 'csharp/src')
-rw-r--r-- | csharp/src/IceSSL/TransceiverI.cs | 328 |
1 files changed, 170 insertions, 158 deletions
diff --git a/csharp/src/IceSSL/TransceiverI.cs b/csharp/src/IceSSL/TransceiverI.cs index daa2bb201a2..f744ad3a035 100644 --- a/csharp/src/IceSSL/TransceiverI.cs +++ b/csharp/src/IceSSL/TransceiverI.cs @@ -58,16 +58,6 @@ namespace IceSSL _authenticated = true; _cipher = _sslStream.CipherAlgorithm.ToString(); - List<string> certs = new List<string>(); - if(_chain.ChainElements != null && _chain.ChainElements.Count > 0) - { - _certs = new X509Certificate2[_chain.ChainElements.Count]; - for(int i = 0; i < _chain.ChainElements.Count; ++i) - { - _certs[i] = _chain.ChainElements[i].Certificate; - } - } - _instance.verifyPeer(_host, (ConnectionInfo)getInfo(), ToString()); if(_instance.securityTraceLevel() >= 1) @@ -368,26 +358,6 @@ namespace IceSSL _sslStream = null; _verifyPeer = _instance.properties().getPropertyAsIntWithDefault("IceSSL.VerifyPeer", 2); - - _chain = new X509Chain(_instance.engine().useMachineContext()); - - if(_instance.checkCRL() == 0) - { - _chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; - } - - X509Certificate2Collection caCerts = _instance.engine().caCerts(); - if(caCerts != null) - { - // - // We need to set this flag to be able to use a certificate authority from the extra store. - // - _chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; - foreach(X509Certificate2 cert in caCerts) - { - _chain.ChainPolicy.ExtraStore.Add(cert); - } - } } private bool startAuthenticate(IceInternal.AsyncCallback callback, object state) @@ -526,30 +496,57 @@ namespace IceSSL private bool validationCallback(object sender, X509Certificate certificate, X509Chain chainEngine, SslPolicyErrors policyErrors) { - string message = ""; - int errors = (int)policyErrors; - if(certificate != null) + X509Chain chain = new X509Chain(_instance.engine().useMachineContext()); + try { - _chain.Build(new X509Certificate2(certificate)); - if(_chain.ChainStatus != null && _chain.ChainStatus.Length > 0) + if(_instance.checkCRL() == 0) + { + chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; + } + + X509Certificate2Collection caCerts = _instance.engine().caCerts(); + if(caCerts != null) { - errors |= (int)SslPolicyErrors.RemoteCertificateChainErrors; + // + // We need to set this flag to be able to use a certificate authority from the extra store. + // + chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; + foreach(X509Certificate2 cert in caCerts) + { + chain.ChainPolicy.ExtraStore.Add(cert); + } } - else if(_instance.engine().caCerts() != null) + + string message = ""; + int errors = (int)policyErrors; + if(certificate != null) { - X509ChainElement e = _chain.ChainElements[_chain.ChainElements.Count - 1]; - if(!_chain.ChainPolicy.ExtraStore.Contains(e.Certificate)) + chain.Build(new X509Certificate2(certificate)); + if(chain.ChainStatus != null && chain.ChainStatus.Length > 0) { - if(_verifyPeer > 0) + errors |= (int)SslPolicyErrors.RemoteCertificateChainErrors; + } + else if(_instance.engine().caCerts() != null) + { + X509ChainElement e = chain.ChainElements[chain.ChainElements.Count - 1]; + if(!chain.ChainPolicy.ExtraStore.Contains(e.Certificate)) { - message = message + "\npuntrusted root certificate"; + if(_verifyPeer > 0) + { + message = message + "\npuntrusted root certificate"; + } + else + { + message = message + "\nuntrusted root certificate (ignored)"; + _verified = false; + } + errors |= (int)SslPolicyErrors.RemoteCertificateChainErrors; } else { - message = message + "\nuntrusted root certificate (ignored)"; - _verified = false; + _verified = true; + return true; } - errors |= (int)SslPolicyErrors.RemoteCertificateChainErrors; } else { @@ -557,175 +554,191 @@ namespace IceSSL return true; } } - else - { - _verified = true; - return true; - } - } - if((errors & (int)SslPolicyErrors.RemoteCertificateNotAvailable) > 0) - { - // - // The RemoteCertificateNotAvailable case does not appear to be possible - // for an outgoing connection. Since .NET requires an authenticated - // connection, the remote peer closes the socket if it does not have a - // certificate to provide. - // - - if(_incoming) + if((errors & (int)SslPolicyErrors.RemoteCertificateNotAvailable) > 0) { - if(_verifyPeer > 1) + // + // The RemoteCertificateNotAvailable case does not appear to be possible + // for an outgoing connection. Since .NET requires an authenticated + // connection, the remote peer closes the socket if it does not have a + // certificate to provide. + // + + if(_incoming) { - if(_instance.securityTraceLevel() >= 1) + if(_verifyPeer > 1) { - _instance.logger().trace(_instance.securityTraceCategory(), - "SSL certificate validation failed - client certificate not provided"); + if(_instance.securityTraceLevel() >= 1) + { + _instance.logger().trace(_instance.securityTraceCategory(), + "SSL certificate validation failed - client certificate not provided"); + } + return false; } - return false; + errors ^= (int)SslPolicyErrors.RemoteCertificateNotAvailable; + message = message + "\nremote certificate not provided (ignored)"; } - errors ^= (int)SslPolicyErrors.RemoteCertificateNotAvailable; - message = message + "\nremote certificate not provided (ignored)"; } - } - bool certificateNameMismatch = (errors & (int)SslPolicyErrors.RemoteCertificateNameMismatch) > 0; - if(certificateNameMismatch) - { - if(_instance.engine().getCheckCertName() && !string.IsNullOrEmpty(_host)) + bool certificateNameMismatch = (errors & (int)SslPolicyErrors.RemoteCertificateNameMismatch) > 0; + if(certificateNameMismatch) { - if(_instance.securityTraceLevel() >= 1) + if(_instance.engine().getCheckCertName() && !string.IsNullOrEmpty(_host)) { - string msg = "SSL certificate validation failed - Hostname mismatch"; - if(_verifyPeer == 0) + if(_instance.securityTraceLevel() >= 1) { - msg += " (ignored)"; + string msg = "SSL certificate validation failed - Hostname mismatch"; + if(_verifyPeer == 0) + { + msg += " (ignored)"; + } + _instance.logger().trace(_instance.securityTraceCategory(), msg); } - _instance.logger().trace(_instance.securityTraceCategory(), msg); - } - if(_verifyPeer > 0) - { - return false; + if(_verifyPeer > 0) + { + return false; + } + else + { + errors ^= (int)SslPolicyErrors.RemoteCertificateNameMismatch; + } } else { errors ^= (int)SslPolicyErrors.RemoteCertificateNameMismatch; + certificateNameMismatch = false; } } - else - { - errors ^= (int)SslPolicyErrors.RemoteCertificateNameMismatch; - certificateNameMismatch = false; - } - } - if((errors & (int)SslPolicyErrors.RemoteCertificateChainErrors) > 0 && - _chain.ChainStatus != null && _chain.ChainStatus.Length > 0) - { - int errorCount = 0; - foreach(X509ChainStatus status in _chain.ChainStatus) + if((errors & (int)SslPolicyErrors.RemoteCertificateChainErrors) > 0 && + chain.ChainStatus != null && chain.ChainStatus.Length > 0) { - if(status.Status == X509ChainStatusFlags.UntrustedRoot && _instance.engine().caCerts() != null) + int errorCount = 0; + foreach(X509ChainStatus status in chain.ChainStatus) { - // - // Untrusted root is OK when using our custom chain engine if - // the CA certificate is present in the chain policy extra store. - // - X509ChainElement e = _chain.ChainElements[_chain.ChainElements.Count - 1]; - if(!_chain.ChainPolicy.ExtraStore.Contains(e.Certificate)) + if(status.Status == X509ChainStatusFlags.UntrustedRoot && _instance.engine().caCerts() != null) { - if(_verifyPeer > 0) + // + // Untrusted root is OK when using our custom chain engine if + // the CA certificate is present in the chain policy extra store. + // + X509ChainElement e = chain.ChainElements[chain.ChainElements.Count - 1]; + if(!chain.ChainPolicy.ExtraStore.Contains(e.Certificate)) { - message = message + "\npuntrusted root certificate"; - ++errorCount; + if(_verifyPeer > 0) + { + message = message + "\npuntrusted root certificate"; + ++errorCount; + } + else + { + message = message + "\nuntrusted root certificate (ignored)"; + } } else { - message = message + "\nuntrusted root certificate (ignored)"; + _verified = !certificateNameMismatch; } } - else + else if(status.Status == X509ChainStatusFlags.Revoked) { - _verified = !certificateNameMismatch; + if(_instance.checkCRL() > 0) + { + message = message + "\ncertificate revoked"; + ++errorCount; + } + else + { + message = message + "\ncertificate revoked (ignored)"; + } } - } - else if(status.Status == X509ChainStatusFlags.Revoked) - { - if(_instance.checkCRL() > 0) + else if(status.Status == X509ChainStatusFlags.RevocationStatusUnknown) { - message = message + "\ncertificate revoked"; - ++errorCount; + // + // If a certificate's revocation status cannot be determined, the strictest + // policy is to reject the connection. + // + if(_instance.checkCRL() > 1) + { + message = message + "\ncertificate revocation status unknown"; + ++errorCount; + } + else + { + message = message + "\ncertificate revocation status unknown (ignored)"; + } } - else + else if(status.Status == X509ChainStatusFlags.PartialChain) { - message = message + "\ncertificate revoked (ignored)"; + if(_verifyPeer > 0) + { + message = message + "\npartial certificate chain"; + ++errorCount; + } + else + { + message = message + "\npartial certificate chain (ignored)"; + } } - } - else if(status.Status == X509ChainStatusFlags.RevocationStatusUnknown) - { - // - // If a certificate's revocation status cannot be determined, the strictest - // policy is to reject the connection. - // - if(_instance.checkCRL() > 1) + else if(status.Status != X509ChainStatusFlags.NoError) { - message = message + "\ncertificate revocation status unknown"; + message = message + "\ncertificate chain error: " + status.Status.ToString(); ++errorCount; } - else - { - message = message + "\ncertificate revocation status unknown (ignored)"; - } } - else if(status.Status == X509ChainStatusFlags.PartialChain) + + if(errorCount == 0) { - if(_verifyPeer > 0) + errors ^= (int)SslPolicyErrors.RemoteCertificateChainErrors; + } + } + + if(errors > 0) + { + if(_instance.securityTraceLevel() >= 1) + { + if(message.Length > 0) { - message = message + "\npartial certificate chain"; - ++errorCount; + _instance.logger().trace(_instance.securityTraceCategory(), + "SSL certificate validation failed:" + message); } else { - message = message + "\npartial certificate chain (ignored)"; + _instance.logger().trace(_instance.securityTraceCategory(), + "SSL certificate validation failed"); } } - else if(status.Status != X509ChainStatusFlags.NoError) - { - message = message + "\ncertificate chain error: " + status.Status.ToString(); - ++errorCount; - } + return false; } - - if(errorCount == 0) + else if(message.Length > 0 && _instance.securityTraceLevel() >= 1) { - errors ^= (int)SslPolicyErrors.RemoteCertificateChainErrors; + _instance.logger().trace(_instance.securityTraceCategory(), + "SSL certificate validation status:" + message); } + return true; } - - if(errors > 0) + finally { - if(_instance.securityTraceLevel() >= 1) + if(chain.ChainElements != null && chain.ChainElements.Count > 0) { - if(message.Length > 0) - { - _instance.logger().trace(_instance.securityTraceCategory(), - "SSL certificate validation failed:" + message); - } - else + _certs = new X509Certificate2[chain.ChainElements.Count]; + for(int i = 0; i < chain.ChainElements.Count; ++i) { - _instance.logger().trace(_instance.securityTraceCategory(), - "SSL certificate validation failed"); + _certs[i] = chain.ChainElements[i].Certificate; } } - return false; - } - else if(message.Length > 0 && _instance.securityTraceLevel() >= 1) - { - _instance.logger().trace(_instance.securityTraceCategory(), - "SSL certificate validation status:" + message); + +#if NETSTANDARD2_0 + try + { + chain.Dispose(); + } + catch(Exception) + { + } +#endif } - return true; } internal void readCompleted(IAsyncResult result) @@ -767,7 +780,6 @@ namespace IceSSL private IAsyncResult _readResult; private IceInternal.AsyncCallback _readCallback; private IceInternal.AsyncCallback _writeCallback; - private X509Chain _chain; private int _maxSendPacketSize; private int _maxRecvPacketSize; private string _cipher; |