diff options
author | Jose <jose@zeroc.com> | 2017-02-22 10:49:10 +0100 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2017-02-22 10:49:10 +0100 |
commit | c5b5faca606e38ecaa7049f54641f1587c1517c8 (patch) | |
tree | cf5b56fdf1cd547d8acefbe9bd61ae5393d27410 /csharp/src | |
parent | Another fix for compiler flag ordering (diff) | |
download | ice-c5b5faca606e38ecaa7049f54641f1587c1517c8.tar.bz2 ice-c5b5faca606e38ecaa7049f54641f1587c1517c8.tar.xz ice-c5b5faca606e38ecaa7049f54641f1587c1517c8.zip |
Fix (6462) - Consider changing some IceSSL checks to use native APIs
Diffstat (limited to 'csharp/src')
-rw-r--r-- | csharp/src/IceSSL/SSLEngine.cs | 197 | ||||
-rw-r--r-- | csharp/src/IceSSL/TransceiverI.cs | 11 |
2 files changed, 12 insertions, 196 deletions
diff --git a/csharp/src/IceSSL/SSLEngine.cs b/csharp/src/IceSSL/SSLEngine.cs index 6e2fe6d954f..a958d117ec6 100644 --- a/csharp/src/IceSSL/SSLEngine.cs +++ b/csharp/src/IceSSL/SSLEngine.cs @@ -407,6 +407,11 @@ namespace IceSSL return _verifier; } + internal bool getCheckCertName() + { + return _checkCertName; + } + internal void setPasswordCallback(PasswordCallback callback) { _passwordCallback = callback; @@ -474,197 +479,7 @@ namespace IceSSL internal void verifyPeer(string address, NativeConnectionInfo info, string desc) { - // - // For an outgoing connection, we compare the proxy address (if any) against - // fields in the server's certificate (if any). - // - if(info.nativeCerts != null && info.nativeCerts.Length > 0 && address.Length > 0) - { - // - // Extract the IP addresses and the DNS names from the subject - // alternative names. - // - List<string> dnsNames = null; - List<string> ipAddresses = null; - - // - // Search for "subject alternative name" extensions. The OID value - // of interest is 2.5.29.17 and the encoded data has the following - // ASN.1 syntax: - // - // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - // - // GeneralName ::= CHOICE { - // otherName [0] OtherName, - // rfc822Name [1] IA5String, - // dNSName [2] IA5String, - // x400Address [3] ORAddress, - // directoryName [4] Name, - // ediPartyName [5] EDIPartyName, - // uniformResourceIdentifier [6] IA5String, - // iPAddress [7] OCTET STRING, - // registeredID [8] OBJECT IDENTIFIER - // } - // - foreach(X509Extension ext in info.nativeCerts[0].Extensions) - { - if(ext.Oid.Value.Equals("2.5.29.17") && ext.RawData.Length > 0) - { - byte[] data = ext.RawData; - if(data.Length < 2 || data[0] != 0x30) // ASN.1 sequence - { - continue; - } - - int seqLen, pos; - if(!decodeASN1Length(data, 1, out seqLen, out pos)) - { - continue; - } - - while(pos < data.Length) - { - int tag = data[pos]; - - int len; - if(!decodeASN1Length(data, pos + 1, out len, out pos)) - { - break; - } - - if(tag == 0x82) - { - // - // Extract DNS name. - // - StringBuilder b = new StringBuilder(); - for(int j = pos; j < pos + len; ++j) - { - b.Append((char)data[j]); - } - if(dnsNames == null) - { - dnsNames = new List<string>(); - } - dnsNames.Add(b.ToString().ToUpperInvariant()); - } - else if(tag == 0x87) - { - // - // Extract IP address. - // - char sep = len == 4 ? '.' : ':'; - StringBuilder b = new StringBuilder(); - for(int j = pos; j < pos + len; ++j) - { - if(j > pos) - { - b.Append(sep); - } - b.Append(data[j].ToString(CultureInfo.InvariantCulture)); - } - if(ipAddresses == null) - { - ipAddresses = new List<string>(); - } - ipAddresses.Add(b.ToString().ToUpperInvariant()); - } - - pos += len; - } - } - } - - // - // Compare the peer's address against the common name as well as - // the dnsName and ipAddress values in the subject alternative name. - // - string dn = info.nativeCerts[0].Subject; - string addrLower = address.ToUpperInvariant(); - bool certNameOK = false; - { - string cn = "cn=" + addrLower; - int pos = dn.ToLower(CultureInfo.InvariantCulture).IndexOf(cn, StringComparison.Ordinal); - if(pos >= 0) - { - // - // Ensure we match the entire common name. - // - certNameOK = (pos + cn.Length == dn.Length) || (dn[pos + cn.Length] == ','); - } - } - - // - // Compare the peer's address against the dnsName and ipAddress - // values in the subject alternative name. - // - if(!certNameOK && ipAddresses != null) - { - certNameOK = ipAddresses.Contains(addrLower); - } - if(!certNameOK && dnsNames != null) - { - certNameOK = dnsNames.Contains(addrLower); - } - - // - // Log a message if the name comparison fails. If CheckCertName is defined, - // we also raise an exception to abort the connection. Don't log a message if - // CheckCertName is not defined and a verifier is present. - // - if(!certNameOK && (_checkCertName || (_securityTraceLevel >= 1 && _verifier == null))) - { - StringBuilder sb = new StringBuilder(); - sb.Append("IceSSL: "); - if(!_checkCertName) - { - sb.Append("ignoring "); - } - sb.Append("certificate validation failure:\npeer certificate does not have `"); - sb.Append(address); - sb.Append("' as its commonName or in its subjectAltName extension"); - if(dn.Length > 0) - { - sb.Append("\nSubject DN: "); - sb.Append(dn); - } - if(dnsNames != null) - { - sb.Append("\nDNS names found in certificate: "); - for(int j = 0; j < dnsNames.Count; ++j) - { - if(j > 0) - { - sb.Append(", "); - } - sb.Append(dnsNames[j]); - } - } - if(ipAddresses != null) - { - sb.Append("\nIP addresses found in certificate: "); - for(int j = 0; j < ipAddresses.Count; ++j) - { - if(j > 0) - { - sb.Append(", "); - } - sb.Append(ipAddresses[j]); - } - } - string msg = sb.ToString(); - if(_securityTraceLevel >= 1) - { - _logger.trace(_securityTraceCategory, msg); - } - if(_checkCertName) - { - Ice.SecurityException ex = new Ice.SecurityException(); - ex.reason = msg; - throw ex; - } - } - } + if(_verifyDepthMax > 0 && info.nativeCerts != null && info.nativeCerts.Length > _verifyDepthMax) { diff --git a/csharp/src/IceSSL/TransceiverI.cs b/csharp/src/IceSSL/TransceiverI.cs index 83b68981f1d..c659d491376 100644 --- a/csharp/src/IceSSL/TransceiverI.cs +++ b/csharp/src/IceSSL/TransceiverI.cs @@ -547,7 +547,7 @@ namespace IceSSL _chain.Build(new X509Certificate2(certificate)); if(_chain.ChainStatus != null && _chain.ChainStatus.Length > 0) { - errors = (int)SslPolicyErrors.RemoteCertificateChainErrors; + errors |= (int)SslPolicyErrors.RemoteCertificateChainErrors; } else if(_instance.engine().caCerts() != null) { @@ -605,10 +605,11 @@ namespace IceSSL if((errors & (int)SslPolicyErrors.RemoteCertificateNameMismatch) > 0) { - // - // Ignore this error here; we'll check the peer certificate in verifyPeer(). - // - errors ^= (int)SslPolicyErrors.RemoteCertificateNameMismatch; + if(_instance.engine().getCheckCertName()) + { + message = "SSL certificate validation failed - Hostname mismatch"; + return false; + } } |