Esempio n. 1
0
        internal AcceptorI(Instance instance, string adapterName, string host, int port)
        {
            _instance    = instance;
            _adapterName = adapterName;
            _logger      = instance.communicator().getLogger();
            _backlog     = instance.communicator().getProperties().getPropertyAsIntWithDefault("Ice.TCP.Backlog", 511);

            //
            // .NET requires that a certificate be supplied.
            //
            X509Certificate2Collection certs = instance.certs();

            if (certs.Count == 0)
            {
                Ice.SecurityException ex = new Ice.SecurityException();
                ex.reason = "IceSSL: certificate required for server endpoint";
                throw ex;
            }

            try
            {
                int protocol = instance.protocolSupport();
                _addr = (IPEndPoint)IceInternal.Network.getAddressForServer(host, port, protocol, instance.preferIPv6());
                _fd   = IceInternal.Network.createServerSocket(false, _addr.AddressFamily, protocol);
                IceInternal.Network.setBlock(_fd, false);
                IceInternal.Network.setTcpBufSize(_fd, _instance.communicator().getProperties(), _logger);
                if (IceInternal.AssemblyUtil.platform_ != IceInternal.AssemblyUtil.Platform.Windows)
                {
                    //
                    // Enable SO_REUSEADDR on Unix platforms to allow
                    // re-using the socket even if it's in the TIME_WAIT
                    // state. On Windows, this doesn't appear to be
                    // necessary and enabling SO_REUSEADDR would actually
                    // not be a good thing since it allows a second
                    // process to bind to an address even it's already
                    // bound by another process.
                    //
                    // TODO: using SO_EXCLUSIVEADDRUSE on Windows would
                    // probably be better but it's only supported by recent
                    // Windows versions (XP SP2, Windows Server 2003).
                    //
                    IceInternal.Network.setReuseAddress(_fd, true);
                }
                if (_instance.networkTraceLevel() >= 2)
                {
                    string s = "attempting to bind to ssl socket " + IceInternal.Network.addrToString(_addr);
                    _logger.trace(_instance.networkTraceCategory(), s);
                }
                _addr = IceInternal.Network.doBind(_fd, _addr);
            }
            catch (System.Exception)
            {
                _fd = null;
                throw;
            }
        }
Esempio n. 2
0
        internal AcceptorI(Instance instance, string adapterName, string host, int port)
        {
            _instance = instance;
            _adapterName = adapterName;
            _logger = instance.communicator().getLogger();
            _backlog = instance.communicator().getProperties().getPropertyAsIntWithDefault("Ice.TCP.Backlog", 511);

            //
            // .NET requires that a certificate be supplied.
            //
            X509Certificate2Collection certs = instance.certs();
            if(certs.Count == 0)
            {
                Ice.SecurityException ex = new Ice.SecurityException();
                ex.reason = "IceSSL: certificate required for server endpoint";
                throw ex;
            }

            try
            {
                _addr = IceInternal.Network.getAddressForServer(host, port, _instance.protocolSupport());
                _fd = IceInternal.Network.createSocket(false, _addr.AddressFamily);
                IceInternal.Network.setBlock(_fd, false);
                IceInternal.Network.setTcpBufSize(_fd, _instance.communicator().getProperties(), _logger);
                if(IceInternal.AssemblyUtil.platform_ != IceInternal.AssemblyUtil.Platform.Windows)
                {
                    //
                    // Enable SO_REUSEADDR on Unix platforms to allow
                    // re-using the socket even if it's in the TIME_WAIT
                    // state. On Windows, this doesn't appear to be
                    // necessary and enabling SO_REUSEADDR would actually
                    // not be a good thing since it allows a second
                    // process to bind to an address even it's already
                    // bound by another process.
                    //
                    // TODO: using SO_EXCLUSIVEADDRUSE on Windows would
                    // probably be better but it's only supported by recent
                    // Windows versions (XP SP2, Windows Server 2003).
                    //
                    IceInternal.Network.setReuseAddress(_fd, true);
                }
                if(_instance.networkTraceLevel() >= 2)
                {
                    string s = "attempting to bind to ssl socket " + IceInternal.Network.addrToString(_addr);
                    _logger.trace(_instance.networkTraceCategory(), s);
                }
                _addr = IceInternal.Network.doBind(_fd, _addr);
            }
            catch(System.Exception)
            {
                _fd = null;
                throw;
            }
        }
Esempio n. 3
0
        internal AcceptorI(EndpointI endpoint, Instance instance, IceInternal.Acceptor del, string adapterName)
        {
            _endpoint    = endpoint;
            _delegate    = del;
            _instance    = instance;
            _adapterName = adapterName;

            //
            // .NET requires that a certificate be supplied.
            //
            if (instance.certs().Count == 0)
            {
                Ice.SecurityException ex = new Ice.SecurityException();
                ex.reason = "IceSSL: certificate required for server endpoint";
                throw ex;
            }
        }
Esempio n. 4
0
        internal AcceptorI(EndpointI endpoint, Instance instance, IceInternal.Acceptor del, string adapterName)
        {
            _endpoint = endpoint;
            _delegate = del;
            _instance = instance;
            _adapterName = adapterName;

            //
            // .NET requires that a certificate be supplied.
            //
            if(instance.certs().Count == 0)
            {
                Ice.SecurityException ex = new Ice.SecurityException();
                ex.reason = "IceSSL: certificate required for server endpoint";
                throw ex;
            }
        }
Esempio n. 5
0
        internal void verifyPeer(string address, NativeConnectionInfo info, string desc)
        {
            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" + desc;
                if (_securityTraceLevel >= 1)
                {
                    _logger.trace(_securityTraceCategory, msg);
                }
                Ice.SecurityException ex = new Ice.SecurityException();
                ex.reason = msg;
                throw ex;
            }

            if (!_trustManager.verify(info, desc))
            {
                string msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected by trust manager\n" +
                             desc;
                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" + desc;
                if (_securityTraceLevel >= 1)
                {
                    _logger.trace(_securityTraceCategory, msg);
                }

                Ice.SecurityException ex = new Ice.SecurityException();
                ex.reason = "IceSSL: " + msg;
                throw ex;
            }
        }
Esempio n. 6
0
        private void finishAuthenticate()
        {
            Debug.Assert(_writeResult != null);

            try
            {
                if (!_incoming)
                {
                    _sslStream.EndAuthenticateAsClient(_writeResult);
                }
                else
                {
                    _sslStream.EndAuthenticateAsServer(_writeResult);
                }
            }
            catch (IOException ex)
            {
                if (IceInternal.Network.connectionLost(ex))
                {
                    //
                    // This situation occurs when connectToSelf is called; the "remote" end
                    // closes the socket immediately.
                    //
                    throw new Ice.ConnectionLostException();
                }
                throw new Ice.SocketException(ex);
            }
#if !UNITY
            catch (AuthenticationException ex)
            {
                Ice.SecurityException e = new Ice.SecurityException(ex);
                e.reason = ex.Message;
                throw e;
            }
#endif
            catch (Exception ex)
            {
                throw new Ice.SyscallException(ex);
            }
        }
Esempio n. 7
0
        private void finishAuthenticate()
        {
            Debug.Assert(_writeResult != null);

            try
            {
                try
                {
                    _writeResult.Wait();
                }
                catch (AggregateException ex)
                {
                    throw ex.InnerException;
                }
            }
            catch (IOException ex)
            {
                if (IceInternal.Network.connectionLost(ex))
                {
                    //
                    // This situation occurs when connectToSelf is called; the "remote" end
                    // closes the socket immediately.
                    //
                    throw new Ice.ConnectionLostException();
                }
                throw new Ice.SocketException(ex);
            }
            catch (AuthenticationException ex)
            {
                Ice.SecurityException e = new Ice.SecurityException(ex);
                e.reason = ex.Message;
                throw e;
            }
            catch (Exception ex)
            {
                throw new Ice.SyscallException(ex);
            }
        }
Esempio n. 8
0
        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)
            {
                string msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected:\n" +
                             "length of peer's certificate chain (" + info.nativeCerts.Length + ") exceeds maximum of " +
                             _verifyDepthMax + "\n" + desc;
                if (_securityTraceLevel >= 1)
                {
                    _logger.trace(_securityTraceCategory, msg);
                }
                Ice.SecurityException ex = new Ice.SecurityException();
                ex.reason = msg;
                throw ex;
            }

            if (!_trustManager.verify(info, desc))
            {
                string msg = (info.incoming ? "incoming" : "outgoing") + " connection rejected by trust manager\n" +
                             desc;
                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" + desc;
                if (_securityTraceLevel >= 1)
                {
                    _logger.trace(_securityTraceCategory, msg);
                }

                Ice.SecurityException ex = new Ice.SecurityException();
                ex.reason = "IceSSL: " + msg;
                throw ex;
            }
        }
Esempio n. 9
0
        private void endAuthenticate()
        {
            Debug.Assert(_writeResult != null);

            try
            {
                if(_adapterName == null)
                {
                    _stream.EndAuthenticateAsClient(_writeResult);
                }
                else
                {
                    _stream.EndAuthenticateAsServer(_writeResult);
                }

                _instance.verifyPeer(getNativeConnectionInfo(), _fd, _host);

                if(_instance.networkTraceLevel() >= 1)
                {
                    string s;
                    if(_adapterName == null)
                    {
                        s = "ssl connection established\n" + _desc;
                    }
                    else
                    {
                        s = "accepted ssl connection\n" + _desc;
                    }
                    _logger.trace(_instance.networkTraceCategory(), s);
                }

                if(_instance.securityTraceLevel() >= 1)
                {
                    _instance.traceStream(_stream, _desc);
                }
            }
            catch(IOException ex)
            {
                if(IceInternal.Network.connectionLost(ex))
                {
                    //
                    // This situation occurs when connectToSelf is called; the "remote" end
                    // closes the socket immediately.
                    //
                    throw new Ice.ConnectionLostException();
                }
                throw new Ice.SocketException(ex);
            }
            catch(AuthenticationException ex)
            {
                Ice.SecurityException e = new Ice.SecurityException(ex);
                e.reason = ex.Message;
                throw e;
            }
            catch(Ice.LocalException)
            {
                throw;
            }
            catch(Exception ex)
            {
                throw new Ice.SyscallException(ex);
            }
        }
Esempio n. 10
0
        private bool beginAuthenticate(IceInternal.AsyncCallback callback, object state)
        {
            NetworkStream ns = new NetworkStream(_fd, true);
            _stream = new SslStream(ns, false, new RemoteCertificateValidationCallback(validationCallback), null);

            try
            {
                if(_adapterName == null)
                {
                    //
                    // Client authentication.
                    //
                    _writeResult = _stream.BeginAuthenticateAsClient(_host, _instance.certs(),
                                                                     _instance.protocols(),
                                                                     _instance.checkCRL() > 0,
                                                                     delegate(IAsyncResult result)
                                                                     {
                                                                         if(!result.CompletedSynchronously)
                                                                         {
                                                                             callback(result.AsyncState);
                                                                         }
                                                                     }, state);
                }
                else
                {
                    //
                    // Server authentication.
                    //
                    // Get the certificate collection and select the first one.
                    //
                    X509Certificate2Collection certs = _instance.certs();
                    X509Certificate2 cert = null;
                    if(certs.Count > 0)
                    {
                        cert = certs[0];
                    }

                    _writeResult = _stream.BeginAuthenticateAsServer(cert, _verifyPeer > 1, _instance.protocols(),
                                                                     _instance.checkCRL() > 0, 
                                                                     delegate(IAsyncResult result)
                                                                     {
                                                                         if(!result.CompletedSynchronously)
                                                                         {
                                                                             callback(result.AsyncState);
                                                                         }
                                                                     }, state);
                }
            }
            catch(IOException ex)
            {
                if(IceInternal.Network.connectionLost(ex))
                {
                    //
                    // This situation occurs when connectToSelf is called; the "remote" end
                    // closes the socket immediately.
                    //
                    throw new Ice.ConnectionLostException();
                }
                throw new Ice.SocketException(ex);
            }
            catch(AuthenticationException ex)
            {
                Ice.SecurityException e = new Ice.SecurityException(ex);
                e.reason = ex.Message;
                throw e;
            }
            catch(Exception ex)
            {
                throw new Ice.SyscallException(ex);
            }

            Debug.Assert(_writeResult != null);
            return _writeResult.CompletedSynchronously;
        }
Esempio n. 11
0
        private bool startAuthenticate(IceInternal.AsyncCallback callback, object state)
        {
            try
            {
                _writeCallback = callback;
                if (!_incoming)
                {
                    //
                    // Client authentication.
                    //
                    _writeResult = _sslStream.BeginAuthenticateAsClient(_host,
                                                                        _instance.certs(),
                                                                        _instance.protocols(),
                                                                        _instance.checkCRL() > 0,
                                                                        writeCompleted,
                                                                        state);
                }
                else
                {
                    //
                    // Server authentication.
                    //
                    // Get the certificate collection and select the first one.
                    //
                    X509Certificate2Collection certs = _instance.certs();
                    X509Certificate2           cert  = null;
                    if (certs.Count > 0)
                    {
                        cert = certs[0];
                    }

                    _writeResult = _sslStream.BeginAuthenticateAsServer(cert,
                                                                        _verifyPeer > 0,
                                                                        _instance.protocols(),
                                                                        _instance.checkCRL() > 0,
                                                                        writeCompleted,
                                                                        state);
                }
            }
            catch (IOException ex)
            {
                if (IceInternal.Network.connectionLost(ex))
                {
                    //
                    // This situation occurs when connectToSelf is called; the "remote" end
                    // closes the socket immediately.
                    //
                    throw new Ice.ConnectionLostException();
                }
                throw new Ice.SocketException(ex);
            }
            catch (AuthenticationException ex)
            {
                Ice.SecurityException e = new Ice.SecurityException(ex);
                e.reason = ex.Message;
                throw e;
            }
            catch (Exception ex)
            {
                throw new Ice.SyscallException(ex);
            }

            Debug.Assert(_writeResult != null);
            return(_writeResult.CompletedSynchronously);
        }
Esempio n. 12
0
        private bool startAuthenticate(IceInternal.AsyncCallback callback, object state)
        {
            try
            {
                _writeCallback = callback;
                if(!_incoming)
                {
                    //
                    // Client authentication.
                    //
                    _writeResult = _sslStream.BeginAuthenticateAsClient(_host,
                                                                        _instance.certs(),
                                                                        _instance.protocols(),
                                                                        _instance.checkCRL() > 0,
                                                                        writeCompleted,
                                                                        state);
                }
                else
                {
            #if UNITY
                    throw new Ice.FeatureNotSupportedException("ssl server socket");
            #else
                    //
                    // Server authentication.
                    //
                    // Get the certificate collection and select the first one.
                    //
                    X509Certificate2Collection certs = _instance.certs();
                    X509Certificate2 cert = null;
                    if(certs.Count > 0)
                    {
                        cert = certs[0];
                    }

                    _writeResult = _sslStream.BeginAuthenticateAsServer(cert,
                                                                        _verifyPeer > 0,
                                                                        _instance.protocols(),
                                                                        _instance.checkCRL() > 0,
                                                                        writeCompleted,
                                                                        state);
            #endif
                }
            }
            catch(IOException ex)
            {
                if(IceInternal.Network.connectionLost(ex))
                {
                    //
                    // This situation occurs when connectToSelf is called; the "remote" end
                    // closes the socket immediately.
                    //
                    throw new Ice.ConnectionLostException();
                }
                throw new Ice.SocketException(ex);
            }
            #if !UNITY
            catch(AuthenticationException ex)
            {
                Ice.SecurityException e = new Ice.SecurityException(ex);
                e.reason = ex.Message;
                throw e;
            }
            #endif
            catch(Exception ex)
            {
                throw new Ice.SyscallException(ex);
            }

            Debug.Assert(_writeResult != null);
            return _writeResult.CompletedSynchronously;
        }
Esempio n. 13
0
        private void finishAuthenticate()
        {
            Debug.Assert(_writeResult != null);

            try
            {
                if(!_incoming)
                {
                    _sslStream.EndAuthenticateAsClient(_writeResult);
                }
                else
                {
                    _sslStream.EndAuthenticateAsServer(_writeResult);
                }
            }
            catch(IOException ex)
            {
                if(IceInternal.Network.connectionLost(ex))
                {
                    //
                    // This situation occurs when connectToSelf is called; the "remote" end
                    // closes the socket immediately.
                    //
                    throw new Ice.ConnectionLostException();
                }
                throw new Ice.SocketException(ex);
            }
            #if !UNITY
            catch(AuthenticationException ex)
            {
                Ice.SecurityException e = new Ice.SecurityException(ex);
                e.reason = ex.Message;
                throw e;
            }
            #endif
            catch(Exception ex)
            {
                throw new Ice.SyscallException(ex);
            }
        }
Esempio n. 14
0
        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;
            }
        }
Esempio n. 15
0
        private void endAuthenticate()
        {
            Debug.Assert(_writeResult != null);

            try
            {
                if (_adapterName == null)
                {
                    _stream.EndAuthenticateAsClient(_writeResult);
                }
                else
                {
                    _stream.EndAuthenticateAsServer(_writeResult);
                }

                _instance.verifyPeer(getNativeConnectionInfo(), _fd, _host);

                if (_instance.networkTraceLevel() >= 1)
                {
                    string s;
                    if (_adapterName == null)
                    {
                        s = "ssl connection established\n" + _desc;
                    }
                    else
                    {
                        s = "accepted ssl connection\n" + _desc;
                    }
                    _logger.trace(_instance.networkTraceCategory(), s);
                }

                if (_instance.securityTraceLevel() >= 1)
                {
                    _instance.traceStream(_stream, _desc);
                }
            }
            catch (IOException ex)
            {
                if (IceInternal.Network.connectionLost(ex))
                {
                    //
                    // This situation occurs when connectToSelf is called; the "remote" end
                    // closes the socket immediately.
                    //
                    throw new Ice.ConnectionLostException();
                }
                throw new Ice.SocketException(ex);
            }
            catch (AuthenticationException ex)
            {
                Ice.SecurityException e = new Ice.SecurityException(ex);
                e.reason = ex.Message;
                throw e;
            }
            catch (Ice.LocalException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new Ice.SyscallException(ex);
            }
        }
Esempio n. 16
0
        private bool beginAuthenticate(IceInternal.AsyncCallback callback, object state)
        {
            NetworkStream ns = new NetworkStream(_fd, true);

            _stream = new SslStream(ns, false, new RemoteCertificateValidationCallback(validationCallback), null);

            try
            {
                if (_adapterName == null)
                {
                    //
                    // Client authentication.
                    //
                    _writeResult = _stream.BeginAuthenticateAsClient(_host, _instance.certs(),
                                                                     _instance.protocols(),
                                                                     _instance.checkCRL() > 0,
                                                                     delegate(IAsyncResult result)
                    {
                        if (!result.CompletedSynchronously)
                        {
                            callback(result.AsyncState);
                        }
                    }, state);
                }
                else
                {
                    //
                    // Server authentication.
                    //
                    // Get the certificate collection and select the first one.
                    //
                    X509Certificate2Collection certs = _instance.certs();
                    X509Certificate2           cert  = null;
                    if (certs.Count > 0)
                    {
                        cert = certs[0];
                    }

                    _writeResult = _stream.BeginAuthenticateAsServer(cert, _verifyPeer > 1, _instance.protocols(),
                                                                     _instance.checkCRL() > 0,
                                                                     delegate(IAsyncResult result)
                    {
                        if (!result.CompletedSynchronously)
                        {
                            callback(result.AsyncState);
                        }
                    }, state);
                }
            }
            catch (IOException ex)
            {
                if (IceInternal.Network.connectionLost(ex))
                {
                    //
                    // This situation occurs when connectToSelf is called; the "remote" end
                    // closes the socket immediately.
                    //
                    throw new Ice.ConnectionLostException();
                }
                throw new Ice.SocketException(ex);
            }
            catch (AuthenticationException ex)
            {
                Ice.SecurityException e = new Ice.SecurityException(ex);
                e.reason = ex.Message;
                throw e;
            }
            catch (Exception ex)
            {
                throw new Ice.SyscallException(ex);
            }

            Debug.Assert(_writeResult != null);
            return(_writeResult.CompletedSynchronously);
        }