summaryrefslogtreecommitdiff
path: root/csharp/src
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2019-09-10 11:14:12 +0200
committerJose <jose@zeroc.com>2019-09-10 11:18:30 +0200
commit1389c577b783cb9bf6827d9b889b35873a1f9f44 (patch)
tree7b05de99d01c7be3cdd6d7ae753f1b1c5c8833aa /csharp/src
parentIceSSL cert name verification fixes - Close #512 (#515) (diff)
downloadice-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.cs328
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;