noCert(Ice.Current current) { try { IceSSL.NativeConnectionInfo info = (IceSSL.NativeConnectionInfo)current.con.getInfo(); test(info.nativeCerts == null); } catch (Ice.LocalException) { test(false); } }
checkCipher(string cipher, Ice.Current current) { try { IceSSL.NativeConnectionInfo info = (IceSSL.NativeConnectionInfo)current.con.getInfo(); test(info.cipher.Equals(cipher)); } catch (Ice.LocalException) { test(false); } }
checkCert(string subjectDN, string issuerDN, Ice.Current current) { try { IceSSL.NativeConnectionInfo info = (IceSSL.NativeConnectionInfo)current.con.getInfo(); test(info.nativeCerts.Length == 2 && info.nativeCerts[0].Subject.Equals(subjectDN) && info.nativeCerts[0].Issuer.Equals(issuerDN)); } catch (Ice.LocalException) { test(false); } }
public Ice.ConnectionInfo getInfo() { NativeConnectionInfo info = new NativeConnectionInfo(); info.nativeCerts = fillConnectionInfo(info); return info; }
public bool verify(IceSSL.NativeConnectionInfo info) { _hadCert = info.nativeCerts != null; _invoked = true; return(_returnValue); }
internal void verifyPeer(NativeConnectionInfo info, System.Net.Sockets.Socket fd, string address) { // // 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) { string msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected:\n" + "length of peer's certificate chain (" + info.nativeCerts.Length + ") exceeds maximum of " + _verifyDepthMax + "\n" + IceInternal.Network.fdToString(fd); if(_securityTraceLevel >= 1) { _logger.trace(_securityTraceCategory, msg); } Ice.SecurityException ex = new Ice.SecurityException(); ex.reason = msg; throw ex; } if(!_trustManager.verify(info)) { string msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected by trust manager\n" + IceInternal.Network.fdToString(fd); if(_securityTraceLevel >= 1) { _logger.trace(_securityTraceCategory, msg); } Ice.SecurityException ex = new Ice.SecurityException(); ex.reason = "IceSSL: " + msg; throw ex; } if(_verifier != null && !_verifier.verify(info)) { string msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected by certificate verifier\n" + IceInternal.Network.fdToString(fd); if(_securityTraceLevel >= 1) { _logger.trace(_securityTraceCategory, msg); } Ice.SecurityException ex = new Ice.SecurityException(); ex.reason = "IceSSL: " + msg; throw ex; } }
internal void verifyPeer(NativeConnectionInfo info, System.Net.Sockets.Socket fd, string address) { _engine.verifyPeer(info, fd, address); }
internal bool verify(NativeConnectionInfo info) { List<List<List<RFC2253.RDNPair>>> reject = new List<List<List<RFC2253.RDNPair>>>(), accept = new List<List<List<RFC2253.RDNPair>>>(); if(rejectAll_.Count != 0) { reject.Add(rejectAll_); } if(info.incoming) { if(rejectAllServer_.Count != 0) { reject.Add(rejectAllServer_); } if(info.adapterName.Length > 0) { List<List<RFC2253.RDNPair>> p = null; if(rejectServer_.TryGetValue(info.adapterName, out p)) { reject.Add(p); } } } else { if(rejectClient_.Count != 0) { reject.Add(rejectClient_); } } if(acceptAll_.Count != 0) { accept.Add(acceptAll_); } if(info.incoming) { if(acceptAllServer_.Count != 0) { accept.Add(acceptAllServer_); } if(info.adapterName.Length > 0) { List<List<RFC2253.RDNPair>> p = null; if(acceptServer_.TryGetValue(info.adapterName, out p)) { accept.Add(p); } } } else { if(acceptClient_.Count != 0) { accept.Add(acceptClient_); } } // // If there is nothing to match against, then we accept the cert. // if(reject.Count == 0 && accept.Count == 0) { return true; } // // If there is no certificate then we match false. // if(info.nativeCerts != null && info.nativeCerts.Length > 0) { #if UNITY throw new Ice.FeatureNotSupportedException("certificate subjectName not available"); #else X500DistinguishedName subjectDN = info.nativeCerts[0].SubjectName; string subjectName = subjectDN.Name; Debug.Assert(subjectName != null); try { // // Decompose the subject DN into the RDNs. // if(traceLevel_ > 0) { if(info.incoming) { communicator_.getLogger().trace("Security", "trust manager evaluating client:\n" + "subject = " + subjectName + "\n" + "adapter = " + info.adapterName + "\n" + "local addr = " + info.localAddress + ":" + info.localPort + "\n" + "remote addr = " + info.remoteAddress + ":" + info.remotePort); } else { communicator_.getLogger().trace("Security", "trust manager evaluating server:\n" + "subject = " + subjectName + "\n" + "local addr = " + info.localAddress + ":" + info.localPort + "\n" + "remote addr = " + info.remoteAddress + ":" + info.remotePort); } } List<RFC2253.RDNPair> dn = RFC2253.parseStrict(subjectName); // // Unescape the DN. Note that this isn't done in // the parser in order to keep the various RFC2253 // implementations as close as possible. // for(int i = 0; i < dn.Count; ++i) { RFC2253.RDNPair p = dn[i]; p.value = RFC2253.unescape(p.value); dn[i] = p; } // // Fail if we match anything in the reject set. // foreach(List<List<RFC2253.RDNPair>> matchSet in reject) { if(traceLevel_ > 0) { StringBuilder s = new StringBuilder("trust manager rejecting PDNs:\n"); stringify(matchSet, s); communicator_.getLogger().trace("Security", s.ToString()); } if(match(matchSet, dn)) { return false; } } // // Succeed if we match anything in the accept set. // foreach(List<List<RFC2253.RDNPair>> matchSet in accept) { if(traceLevel_ > 0) { StringBuilder s = new StringBuilder("trust manager accepting PDNs:\n"); stringify(matchSet, s); communicator_.getLogger().trace("Security", s.ToString()); } if(match(matchSet, dn)) { return true; } } } catch(RFC2253.ParseException e) { communicator_.getLogger().warning( "IceSSL: unable to parse certificate DN `" + subjectName + "'\nreason: " + e.reason); } // // At this point we accept the connection if there are no explicit accept rules. // return accept.Count == 0; #endif } return false; }
internal void verifyPeer(NativeConnectionInfo info, System.Net.Sockets.Socket fd, string address) { // // 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) { string msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected:\n" + "length of peer's certificate chain (" + info.nativeCerts.Length + ") exceeds maximum of " + _verifyDepthMax + "\n" + IceInternal.Network.fdToString(fd); if (_securityTraceLevel >= 1) { _logger.trace(_securityTraceCategory, msg); } Ice.SecurityException ex = new Ice.SecurityException(); ex.reason = msg; throw ex; } if (!_trustManager.verify(info)) { string msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected by trust manager\n" + IceInternal.Network.fdToString(fd); if (_securityTraceLevel >= 1) { _logger.trace(_securityTraceCategory, msg); } Ice.SecurityException ex = new Ice.SecurityException(); ex.reason = "IceSSL: " + msg; throw ex; } if (_verifier != null && !_verifier.verify(info)) { string msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected by certificate verifier\n" + IceInternal.Network.fdToString(fd); if (_securityTraceLevel >= 1) { _logger.trace(_securityTraceCategory, msg); } Ice.SecurityException ex = new Ice.SecurityException(); ex.reason = "IceSSL: " + msg; throw ex; } }
internal bool verify(NativeConnectionInfo info, string desc) { List <List <List <RFC2253.RDNPair> > > reject = new List <List <List <RFC2253.RDNPair> > >(), accept = new List <List <List <RFC2253.RDNPair> > >(); if (_rejectAll.Count != 0) { reject.Add(_rejectAll); } if (info.incoming) { if (_rejectAllServer.Count != 0) { reject.Add(_rejectAllServer); } if (info.adapterName.Length > 0) { List <List <RFC2253.RDNPair> > p = null; if (_rejectServer.TryGetValue(info.adapterName, out p)) { reject.Add(p); } } } else { if (_rejectClient.Count != 0) { reject.Add(_rejectClient); } } if (_acceptAll.Count != 0) { accept.Add(_acceptAll); } if (info.incoming) { if (_acceptAllServer.Count != 0) { accept.Add(_acceptAllServer); } if (info.adapterName.Length > 0) { List <List <RFC2253.RDNPair> > p = null; if (_acceptServer.TryGetValue(info.adapterName, out p)) { accept.Add(p); } } } else { if (_acceptClient.Count != 0) { accept.Add(_acceptClient); } } // // If there is nothing to match against, then we accept the cert. // if (reject.Count == 0 && accept.Count == 0) { return(true); } // // If there is no certificate then we match false. // if (info.nativeCerts != null && info.nativeCerts.Length > 0) { X500DistinguishedName subjectDN = info.nativeCerts[0].SubjectName; string subjectName = subjectDN.Name; Debug.Assert(subjectName != null); try { // // Decompose the subject DN into the RDNs. // if (_traceLevel > 0) { if (info.incoming) { _communicator.getLogger().trace("Security", "trust manager evaluating client:\n" + "subject = " + subjectName + "\n" + "adapter = " + info.adapterName + "\n" + desc); } else { _communicator.getLogger().trace("Security", "trust manager evaluating server:\n" + "subject = " + subjectName + "\n" + desc); } } List <RFC2253.RDNPair> dn = RFC2253.parseStrict(subjectName); // // Unescape the DN. Note that this isn't done in // the parser in order to keep the various RFC2253 // implementations as close as possible. // for (int i = 0; i < dn.Count; ++i) { RFC2253.RDNPair p = dn[i]; p.value = RFC2253.unescape(p.value); dn[i] = p; } // // Fail if we match anything in the reject set. // foreach (List <List <RFC2253.RDNPair> > matchSet in reject) { if (_traceLevel > 0) { StringBuilder s = new StringBuilder("trust manager rejecting PDNs:\n"); stringify(matchSet, s); _communicator.getLogger().trace("Security", s.ToString()); } if (match(matchSet, dn)) { return(false); } } // // Succeed if we match anything in the accept set. // foreach (List <List <RFC2253.RDNPair> > matchSet in accept) { if (_traceLevel > 0) { StringBuilder s = new StringBuilder("trust manager accepting PDNs:\n"); stringify(matchSet, s); _communicator.getLogger().trace("Security", s.ToString()); } if (match(matchSet, dn)) { return(true); } } } catch (RFC2253.ParseException e) { _communicator.getLogger().warning( "IceSSL: unable to parse certificate DN `" + subjectName + "'\nreason: " + e.reason); } // // At this point we accept the connection if there are no explicit accept rules. // return(accept.Count == 0); } return(false); }
internal void verifyPeer(string address, NativeConnectionInfo info, string desc) { _engine.verifyPeer(address, info, desc); }
public Ice.ConnectionInfo getInfo() { NativeConnectionInfo info = new NativeConnectionInfo(); info.underlying = _delegate.getInfo(); info.incoming = _incoming; info.adapterName = _adapterName; if(_sslStream != null) { info.cipher = _sslStream.CipherAlgorithm.ToString(); if(_chain.ChainElements != null && _chain.ChainElements.Count > 0) { info.nativeCerts = new X509Certificate2[_chain.ChainElements.Count]; for(int i = 0; i < _chain.ChainElements.Count; ++i) { info.nativeCerts[i] = _chain.ChainElements[i].Certificate; } } List<string> certs = new List<string>(); if(info.nativeCerts != null) { foreach(X509Certificate2 cert in info.nativeCerts) { StringBuilder s = new StringBuilder(); s.Append("-----BEGIN CERTIFICATE-----\n"); s.Append(Convert.ToBase64String(cert.Export(X509ContentType.Cert))); s.Append("\n-----END CERTIFICATE-----"); certs.Add(s.ToString()); } } info.certs = certs.ToArray(); info.verified = _verified; } return info; }
public bool verify(IceSSL.NativeConnectionInfo info) { hadCert_ = info.nativeCerts != null; invoked_ = true; return(returnValue_); }
internal void verifyPeer(NativeConnectionInfo info, System.Net.Sockets.Socket fd, string address) { _engine.verifyPeer(info, fd, address); }
internal void verifyPeer(string address, NativeConnectionInfo info, string desc) { _engine.verifyPeer(address, info, desc); }