Exemple #1
0
        public bool startAccept(IceInternal.AsyncCallback callback, object state)
        {
            //
            // The plug-in may not be fully initialized.
            //
            if(!_instance.initialized())
            {
                Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
                ex.reason = "IceSSL: plug-in is not initialized";
                throw ex;
            }

            try
            {
                _result = _fd.BeginAccept(delegate(IAsyncResult result)
                                          {
                                              if(!result.CompletedSynchronously)
                                              {
                                                  callback(result.AsyncState);
                                              }
                                          }, state);
                return _result.CompletedSynchronously;
            }
            catch(SocketException ex)
            {
                throw new Ice.SocketException(ex);
            }
        }
Exemple #2
0
 public bool startAccept(IceInternal.AsyncCallback callback, object state)
 {
     //
     // The plug-in may not be fully initialized.
     //
     if(!_instance.initialized())
     {
         Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
         ex.reason = "IceSSL: plug-in is not initialized";
         throw ex;
     }
     return _delegate.startAccept(callback, state);
 }
Exemple #3
0
        public IceInternal.Transceiver connect()
        {
            //
            // The plug-in may not be fully initialized.
            //
            if(!_instance.initialized())
            {
                Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
                ex.reason = "IceSSL: plug-in is not initialized";
                throw ex;
            }

            return new TransceiverI(_instance, _delegate.connect(), _host, false);
        }
Exemple #4
0
        public IceInternal.Transceiver connect()
        {
            //
            // The plug-in may not be fully initialized.
            //
            if(!_instance.initialized())
            {
                Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
                ex.reason = "IceSSL: plug-in is not initialized";
                throw ex;
            }

            return new TransceiverI(_instance, new IceInternal.StreamSocket(_instance, _proxy, _addr, _sourceAddr),
                                    _host, false);
        }
Exemple #5
0
        public IceInternal.Transceiver connect()
        {
            //
            // The plug-in may not be fully initialized.
            //
            if(!_instance.initialized())
            {
                Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
                ex.reason = "IceSSL: plug-in is not initialized";
                throw ex;
            }

            if(_instance.networkTraceLevel() >= 2)
            {
                string s = "trying to establish ssl connection to " + ToString();
                _logger.trace(_instance.networkTraceCategory(), s);
            }

            try
            {
                Socket fd = IceInternal.Network.createSocket(false, _addr.AddressFamily);
                IceInternal.Network.setBlock(fd, true); // SSL requires a blocking socket.

                //
                // Windows XP has an IPv6 bug that makes a socket appear to be unconnected if you
                // set the socket's receive buffer size, and this in turn causes .NET to raise an
                // exception that would prevent us from using SSL.
                //
                if(_addr.AddressFamily != AddressFamily.InterNetworkV6 || !IceInternal.AssemblyUtil.xp_)
                {
                    IceInternal.Network.setTcpBufSize(fd, _instance.communicator().getProperties(), _logger);
                }

                //
                // Nonblocking connect is handled by the transceiver.
                //
                return new TransceiverI(_instance, fd, _addr, _host, false, null);
            }
            catch(Ice.LocalException ex)
            {
                if(_instance.networkTraceLevel() >= 2)
                {
                    string s = "failed to establish ssl connection to " + ToString() + "\n" + ex;
                    _logger.trace(_instance.networkTraceCategory(), s);
                }
                throw;
            }
        }
Exemple #6
0
        public IceInternal.Transceiver connect()
        {
            //
            // The plug-in may not be fully initialized.
            //
            if (!_instance.initialized())
            {
                Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
                ex.reason = "IceSSL: plug-in is not initialized";
                throw ex;
            }

            if (_instance.networkTraceLevel() >= 2)
            {
                string s = "trying to establish ssl connection to " + ToString();
                _logger.trace(_instance.networkTraceCategory(), s);
            }

            try
            {
                Socket fd = IceInternal.Network.createSocket(false, _addr.AddressFamily);
                IceInternal.Network.setBlock(fd, true); // SSL requires a blocking socket.

                //
                // Windows XP has an IPv6 bug that makes a socket appear to be unconnected if you
                // set the socket's receive buffer size, and this in turn causes .NET to raise an
                // exception that would prevent us from using SSL.
                //
                if (_addr.AddressFamily != AddressFamily.InterNetworkV6 || !IceInternal.AssemblyUtil.xp_)
                {
                    IceInternal.Network.setTcpBufSize(fd, _instance.communicator().getProperties(), _logger);
                }

                //
                // Nonblocking connect is handled by the transceiver.
                //
                return(new TransceiverI(_instance, fd, _host, false, false, null, _addr, _proxy));
            }
            catch (Ice.LocalException ex)
            {
                if (_instance.networkTraceLevel() >= 2)
                {
                    string s = "failed to establish ssl connection to " + ToString() + "\n" + ex;
                    _logger.trace(_instance.networkTraceCategory(), s);
                }
                throw;
            }
        }
Exemple #7
0
        internal TrustManager(Ice.Communicator communicator)
        {
            Debug.Assert(communicator != null);
            communicator_ = communicator;
            Ice.Properties properties = communicator.getProperties();
            traceLevel_ = properties.getPropertyAsInt("IceSSL.Trace.Security");
            string key = null;

            try
            {
                key = "IceSSL.TrustOnly";
                parse(properties.getProperty(key), rejectAll_, acceptAll_);
                key = "IceSSL.TrustOnly.Client";
                parse(properties.getProperty(key), rejectClient_, acceptClient_);
                key = "IceSSL.TrustOnly.Server";
                parse(properties.getProperty(key), rejectAllServer_, acceptAllServer_);
                Dictionary <string, string> dict = properties.getPropertiesForPrefix("IceSSL.TrustOnly.Server.");
                foreach (KeyValuePair <string, string> entry in dict)
                {
                    key = entry.Key;
                    string name = key.Substring("IceSSL.TrustOnly.Server.".Length);
                    List <List <RFC2253.RDNPair> > reject = new List <List <RFC2253.RDNPair> >();
                    List <List <RFC2253.RDNPair> > accept = new List <List <RFC2253.RDNPair> >();
                    parse(entry.Value, reject, accept);
                    if (reject.Count > 0)
                    {
                        rejectServer_[name] = reject;
                    }
                    if (accept.Count > 0)
                    {
                        acceptServer_[name] = accept;
                    }
                }
            }
            catch (RFC2253.ParseException e)
            {
                Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
                ex.reason = "IceSSL: invalid property " + key + ":\n" + e.reason;
                throw ex;
            }
        }
Exemple #8
0
 internal TrustManager(Ice.Communicator communicator)
 {
     Debug.Assert(communicator != null);
     communicator_ = communicator;
     Ice.Properties properties = communicator.getProperties();
     traceLevel_ = properties.getPropertyAsInt("IceSSL.Trace.Security");
     string key = null;
     try
     {
         key = "IceSSL.TrustOnly";
         parse(properties.getProperty(key), rejectAll_, acceptAll_);
         key = "IceSSL.TrustOnly.Client";
         parse(properties.getProperty(key), rejectClient_, acceptClient_);
         key = "IceSSL.TrustOnly.Server";
         parse(properties.getProperty(key), rejectAllServer_, acceptAllServer_);
         Dictionary<string, string> dict = properties.getPropertiesForPrefix("IceSSL.TrustOnly.Server.");
         foreach(KeyValuePair<string, string> entry in dict)
         {
             key = entry.Key;
             string name = key.Substring("IceSSL.TrustOnly.Server.".Length);
             List<List<RFC2253.RDNPair>> reject = new List<List<RFC2253.RDNPair>>();
             List<List<RFC2253.RDNPair>> accept = new List<List<RFC2253.RDNPair>>();
             parse(entry.Value, reject, accept);
             if(reject.Count > 0)
             {
                 rejectServer_[name] = reject;
             }
             if(accept.Count > 0)
             {
                 acceptServer_[name] = accept;
             }
         }
     }
     catch(RFC2253.ParseException e)
     {
         Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
         ex.reason = "IceSSL: invalid property " + key  + ":\n" + e.reason;
         throw ex;
     }
 }
Exemple #9
0
        private SslProtocols parseProtocols(string[] arr)
        {
            SslProtocols result = SslProtocols.Default;

            if (arr.Length > 0)
            {
                result = 0;
                for (int i = 0; i < arr.Length; ++i)
                {
                    string protocol = null;
                    string s        = arr[i].ToUpperInvariant();
                    switch (s)
                    {
                    case "SSL3":
                    case "SSLV3":
                    {
                        protocol = "Ssl3";
                        break;
                    }

                    case "TLS":
                    case "TLS1":
                    case "TLS1_0":
                    case "TLSV1":
                    case "TLSV1_0":
                    {
                        protocol = "Tls";
                        break;
                    }

                    case "TLS1_1":
                    case "TLSV1_1":
                    {
                        protocol = "Tls11";
                        break;
                    }

                    case "TLS1_2":
                    case "TLSV1_2":
                    {
                        protocol = "Tls12";
                        break;
                    }

                    default:
                    {
                        break;
                    }
                    }

                    try
                    {
                        SslProtocols value = (SslProtocols)Enum.Parse(typeof(SslProtocols), protocol);
                        result |= value;
                    }
                    catch (Exception)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: unrecognized protocol `" + s + "'";
                        throw e;
                    }
                }
            }
            return(result);
        }
Exemple #10
0
        internal void initialize()
        {
            if (_initialized)
            {
                return;
            }

            const string prefix = "IceSSL.";

            Ice.Properties properties = communicator().getProperties();

            //
            // Check for a default directory. We look in this directory for
            // files mentioned in the configuration.
            //
            _defaultDir = properties.getProperty(prefix + "DefaultDir");

            string        certStoreLocation = properties.getPropertyWithDefault(prefix + "CertStoreLocation", "CurrentUser");
            StoreLocation storeLocation;

            if (certStoreLocation == "CurrentUser")
            {
                storeLocation = StoreLocation.CurrentUser;
            }
            else if (certStoreLocation == "LocalMachine")
            {
                storeLocation = StoreLocation.LocalMachine;
            }
            else
            {
                _logger.warning("Invalid IceSSL.CertStoreLocation value `" + certStoreLocation +
                                "' adjusted to `CurrentUser'");
                storeLocation = StoreLocation.CurrentUser;
            }
            _useMachineContext = certStoreLocation == "LocalMachine";

            //
            // Protocols selects which protocols to enable, by default we only enable TLS1.0
            // TLS1.1 and TLS1.2 to avoid security issues with SSLv3
            //
            _protocols = parseProtocols(
                properties.getPropertyAsListWithDefault(prefix + "Protocols", new string[] { "TLS1_0", "TLS1_1", "TLS1_2" }));
            //
            // CheckCertName determines whether we compare the name in a peer's
            // certificate against its hostname.
            //
            _checkCertName = properties.getPropertyAsIntWithDefault(prefix + "CheckCertName", 0) > 0;

            //
            // VerifyDepthMax establishes the maximum length of a peer's certificate
            // chain, including the peer's certificate. A value of 0 means there is
            // no maximum.
            //
            _verifyDepthMax = properties.getPropertyAsIntWithDefault(prefix + "VerifyDepthMax", 3);

            //
            // CheckCRL determines whether the certificate revocation list is checked, and how strictly.
            //
            _checkCRL = properties.getPropertyAsIntWithDefault(prefix + "CheckCRL", 0);

            //
            // Check for a certificate verifier.
            //
            string certVerifierClass = properties.getProperty(prefix + "CertVerifier");

            if (certVerifierClass.Length > 0)
            {
                if (_verifier != null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: certificate verifier already installed";
                    throw e;
                }

                Type cls = _facade.findType(certVerifierClass);
                if (cls == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load certificate verifier class " + certVerifierClass;
                    throw e;
                }

                try
                {
                    _verifier = (CertificateVerifier)IceInternal.AssemblyUtil.createInstance(cls);
                }
                catch (Exception ex)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                    e.reason = "IceSSL: unable to instantiate certificate verifier class " + certVerifierClass;
                    throw e;
                }

                if (_verifier == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to instantiate certificate verifier class " + certVerifierClass;
                    throw e;
                }
            }

            //
            // Check for a password callback.
            //
            string passwordCallbackClass = properties.getProperty(prefix + "PasswordCallback");

            if (passwordCallbackClass.Length > 0)
            {
                if (_passwordCallback != null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: password callback already installed";
                    throw e;
                }

                Type cls = _facade.findType(passwordCallbackClass);
                if (cls == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }

                try
                {
                    _passwordCallback = (PasswordCallback)IceInternal.AssemblyUtil.createInstance(cls);
                }
                catch (Exception ex)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }

                if (_passwordCallback == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }
            }

            //
            // If the user hasn't supplied a certificate collection, we need to examine
            // the property settings.
            //
            if (_certs == null)
            {
                //
                // If IceSSL.CertFile is defined, load a certificate from a file and
                // add it to the collection.
                //
                // TODO: tracing?
                _certs = new X509Certificate2Collection();
                string       certFile    = properties.getProperty(prefix + "CertFile");
                string       passwordStr = properties.getProperty(prefix + "Password");
                string       findCert    = properties.getProperty(prefix + "FindCert");
                const string findPrefix  = prefix + "FindCert.";
                Dictionary <string, string> findCertProps = properties.getPropertiesForPrefix(findPrefix);

                if (certFile.Length > 0)
                {
                    if (!checkPath(ref certFile))
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: certificate file not found: " + certFile;
                        throw e;
                    }

                    SecureString password = null;
                    if (passwordStr.Length > 0)
                    {
                        password = createSecureString(passwordStr);
                    }
                    else if (_passwordCallback != null)
                    {
                        password = _passwordCallback.getPassword(certFile);
                    }

                    try
                    {
                        X509Certificate2    cert;
                        X509KeyStorageFlags importFlags;
                        if (_useMachineContext)
                        {
                            importFlags = X509KeyStorageFlags.MachineKeySet;
                        }
                        else
                        {
                            importFlags = X509KeyStorageFlags.UserKeySet;
                        }

                        if (password != null)
                        {
                            cert = new X509Certificate2(certFile, password, importFlags);
                        }
                        else
                        {
                            cert = new X509Certificate2(certFile, "", importFlags);
                        }
                        _certs.Add(cert);
                    }
                    catch (CryptographicException ex)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                        e.reason = "IceSSL: error while attempting to load certificate from " + certFile;
                        throw e;
                    }
                }
                else if (findCert.Length > 0)
                {
                    string certStore = properties.getPropertyWithDefault("IceSSL.CertStore", "My");
                    _certs.AddRange(findCertificates("IceSSL.FindCert", storeLocation, certStore, findCert));
                    if (_certs.Count == 0)
                    {
                        throw new Ice.PluginInitializationException("IceSSL: no certificates found");
                    }
                }
                else if (findCertProps.Count > 0)
                {
                    //
                    // If IceSSL.FindCert.* properties are defined, add the selected certificates
                    // to the collection.
                    //
                    foreach (KeyValuePair <string, string> entry in findCertProps)
                    {
                        string name = entry.Key;
                        string val  = entry.Value;
                        if (val.Length > 0)
                        {
                            string        storeSpec = name.Substring(findPrefix.Length);
                            StoreLocation storeLoc  = 0;
                            StoreName     storeName = 0;
                            string        sname     = null;
                            parseStore(name, storeSpec, ref storeLoc, ref storeName, ref sname);
                            if (sname == null)
                            {
                                sname = storeName.ToString();
                            }
                            X509Certificate2Collection coll = findCertificates(name, storeLoc, sname, val);
                            _certs.AddRange(coll);
                        }
                    }
                    if (_certs.Count == 0)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: no certificates found";
                        throw e;
                    }
                }
            }

            if (_caCerts == null)
            {
                string certAuthFile = properties.getProperty(prefix + "CAs");
                if (certAuthFile.Length == 0)
                {
                    certAuthFile = properties.getProperty(prefix + "CertAuthFile");
                }
                if (certAuthFile.Length > 0 || properties.getPropertyAsInt(prefix + "UsePlatformCAs") <= 0)
                {
                    _caCerts = new X509Certificate2Collection();
                }
                if (certAuthFile.Length > 0)
                {
                    if (!checkPath(ref certAuthFile))
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: CA certificate file not found: " + certAuthFile;
                        throw e;
                    }

                    try
                    {
                        using (System.IO.FileStream fs = System.IO.File.OpenRead(certAuthFile))
                        {
                            byte[] data = new byte[fs.Length];
                            fs.Read(data, 0, data.Length);

                            string strbuf = "";
                            try
                            {
                                strbuf = System.Text.Encoding.UTF8.GetString(data);
                            }
                            catch (Exception)
                            {
                                // Ignore
                            }

                            if (strbuf.Length == data.Length)
                            {
                                int  size, startpos, endpos = 0;
                                bool first = true;
                                while (true)
                                {
                                    startpos = strbuf.IndexOf("-----BEGIN CERTIFICATE-----", endpos);
                                    if (startpos != -1)
                                    {
                                        endpos = strbuf.IndexOf("-----END CERTIFICATE-----", startpos);
                                        size   = endpos - startpos + "-----END CERTIFICATE-----".Length;
                                    }
                                    else if (first)
                                    {
                                        startpos = 0;
                                        endpos   = strbuf.Length;
                                        size     = strbuf.Length;
                                    }
                                    else
                                    {
                                        break;
                                    }

                                    byte[] cert = new byte[size];
                                    System.Buffer.BlockCopy(data, startpos, cert, 0, size);
                                    _caCerts.Import(cert);
                                    first = false;
                                }
                            }
                            else
                            {
                                _caCerts.Import(data);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                        e.reason = "IceSSL: error while attempting to load CA certificate from " + certAuthFile;
                        throw e;
                    }
                }
            }
            _initialized = true;
        }
Exemple #11
0
        private X509Certificate2Collection findCertificates(string prop, string storeSpec, string value)
        {
            StoreLocation storeLoc = 0;
            StoreName storeName = 0;
            string storeNameStr = null;
            parseStore(prop, storeSpec, ref storeLoc, ref storeName, ref storeNameStr);

            //
            // Open the X509 certificate store.
            //
            X509Store store = null;
            try
            {
                if(storeNameStr != null)
                {
                    store = new X509Store(storeNameStr, storeLoc);
                }
                else
                {
                    store = new X509Store(storeName, storeLoc);
                }
                store.Open(OpenFlags.ReadOnly);
            }
            catch(Exception ex)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                e.reason = "IceSSL: failure while opening store specified by " + prop;
                throw e;
            }

            //
            // Start with all of the certificates in the collection and filter as necessary.
            //
            // - If the value is "*", return all certificates.
            // - Otherwise, search using key:value pairs. The following keys are supported:
            //
            //   Issuer
            //   IssuerDN
            //   Serial
            //   Subject
            //   SubjectDN
            //   SubjectKeyId
            //   Thumbprint
            //
            //   A value must be enclosed in single or double quotes if it contains whitespace.
            //
            X509Certificate2Collection result = new X509Certificate2Collection();
            result.AddRange(store.Certificates);
            try
            {
                if(value != "*")
                {
                    int start = 0;
                    int pos;
                    while((pos = value.IndexOf(':', start)) != -1)
                    {
                        //
                        // Parse the X509FindType.
                        //
                        string field = value.Substring(start, pos - start).Trim().ToUpperInvariant();
                        X509FindType findType;
                        if(field.Equals("SUBJECT"))
                        {
                            findType = X509FindType.FindBySubjectName;
                        }
                        else if(field.Equals("SUBJECTDN"))
                        {
                            findType = X509FindType.FindBySubjectDistinguishedName;
                        }
                        else if(field.Equals("ISSUER"))
                        {
                            findType = X509FindType.FindByIssuerName;
                        }
                        else if(field.Equals("ISSUERDN"))
                        {
                            findType = X509FindType.FindByIssuerDistinguishedName;
                        }
                        else if(field.Equals("THUMBPRINT"))
                        {
                            findType = X509FindType.FindByThumbprint;
                        }
                        else if(field.Equals("SUBJECTKEYID"))
                        {
                            findType = X509FindType.FindBySubjectKeyIdentifier;
                        }
                        else if(field.Equals("SERIAL"))
                        {
                            findType = X509FindType.FindBySerialNumber;
                        }
                        else
                        {
                            Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                            e.reason = "IceSSL: unknown key in `" + value + "'";
                            throw e;
                        }

                        //
                        // Parse the argument.
                        //
                        start = pos + 1;
                        while(start < value.Length && (value[start] == ' ' || value[start] == '\t'))
                        {
                            ++start;
                        }
                        if(start == value.Length)
                        {
                            Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                            e.reason = "IceSSL: missing argument in `" + value + "'";
                            throw e;
                        }

                        string arg;
                        if(value[start] == '"' || value[start] == '\'')
                        {
                            int end = start;
                            ++end;
                            while(end < value.Length)
                            {
                                if(value[end] == value[start] && value[end - 1] != '\\')
                                {
                                    break;
                                }
                                ++end;
                            }
                            if(end == value.Length || value[end] != value[start])
                            {
                                Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                                e.reason = "IceSSL: unmatched quote in `" + value + "'";
                                throw e;
                            }
                            ++start;
                            arg = value.Substring(start, end - start);
                            start = end + 1;
                        }
                        else
                        {
                            char[] ws = new char[] { ' ', '\t' };
                            int end = value.IndexOfAny(ws, start);
                            if(end == -1)
                            {
                                arg = value.Substring(start);
                                start = value.Length;
                            }
                            else
                            {
                                arg = value.Substring(start, end - start);
                                start = end + 1;
                            }
                        }

                        //
                        // Execute the query.
                        //
                        // TODO: allow user to specify a value for validOnly?
                        //
                        bool validOnly = false;
                        result = result.Find(findType, arg, validOnly);
                    }
                }
            }
            finally
            {
                store.Close();
            }

            return result;
        }
Exemple #12
0
 private SslProtocols parseProtocols(string property)
 {
     SslProtocols result = SslProtocols.Default;
     string[] arr = communicator().getProperties().getPropertyAsList(property);
     if(arr.Length > 0)
     {
         result = 0;
         for(int i = 0; i < arr.Length; ++i)
         {
             string s = arr[i].ToUpperInvariant();
             if(s.Equals("SSL3") || s.Equals("SSLV3"))
             {
                 result |= SslProtocols.Ssl3;
             }
             else if(s.Equals("TLS") || s.Equals("TLS1") || s.Equals("TLSV1"))
             {
                 result |= SslProtocols.Tls;
             }
             else
             {
                 Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                 e.reason = "IceSSL: unrecognized protocol `" + s + "'";
                 throw e;
             }
         }
     }
     return result;
 }
Exemple #13
0
        private void importCertificate(string propName, string propValue, X509KeyStorageFlags keyStorageFlags)
        {
            //
            // Expecting a property of the following form:
            //
            // IceSSL.ImportCert.<location>.<name>=<file>[;password]
            //
            const string prefix = "IceSSL.ImportCert.";
            StoreLocation loc = 0;
            StoreName name = 0;
            string sname = null;
            parseStore(propName, propName.Substring(prefix.Length), ref loc, ref name, ref sname);

            //
            // Extract the filename and password. Either or both can be quoted.
            //
            string[] arr = splitString(propValue, ';');
            if(arr == null)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                e.reason = "IceSSL: unmatched quote in `" + propValue + "'";
                throw e;
            }
            if(arr.Length == 0)
            {
                return;
            }
            string file = arr[0];
            string passwordStr = null;
            if(arr.Length > 1)
            {
                passwordStr = arr[1];
            }

            //
            // Open the X509 certificate store.
            //
            X509Store store = null;
            try
            {
                if(sname != null)
                {
                    store = new X509Store(sname, loc);
                }
                else
                {
                    store = new X509Store(name, loc);
                }
                store.Open(OpenFlags.ReadWrite);
            }
            catch(Exception ex)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                e.reason = "IceSSL: failure while opening store specified by " + propName;
                throw e;
            }

            if(!checkPath(ref file))
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                e.reason = "IceSSL: certificate file not found:\n" + file;
                throw e;
            }

            SecureString password = null;
            if(passwordStr != null)
            {
                password = createSecureString(passwordStr);
            }
            else if(_passwordCallback != null)
            {
                password = _passwordCallback.getImportPassword(file);
            }

            //
            // Add the certificate to the store.
            //
            try
            {
                X509Certificate2 cert;
                if(password != null)
                {
                    cert = new X509Certificate2(file, password, keyStorageFlags);
                }
                else
                {
                    cert = new X509Certificate2(file, "", keyStorageFlags);
                }
                store.Add(cert);
            }
            catch(Exception ex)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                e.reason = "IceSSL: failure while adding certificate file:\n" + file;
                throw e;
            }
            finally
            {
                store.Close();
            }
        }
Exemple #14
0
        internal void initialize()
        {
            if(_initialized)
            {
                return;
            }

            const string prefix = "IceSSL.";
            Ice.Properties properties = communicator().getProperties();

            //
            // Check for a default directory. We look in this directory for
            // files mentioned in the configuration.
            //
            _defaultDir = properties.getProperty(prefix + "DefaultDir");


            string keySet = properties.getPropertyWithDefault(prefix + "KeySet", "DefaultKeySet");
            if(!keySet.Equals("DefaultKeySet") && !keySet.Equals("UserKeySet") && !keySet.Equals("MachineKeySet"))
            {
                keySet = "DefaultKeySet";
                _logger.warning("Invalid IceSSL.KeySet value `" + keySet + "' adjusted to `DefaultKeySet'");
            }

            X509KeyStorageFlags keyStorageFlags = X509KeyStorageFlags.DefaultKeySet;
            if(keySet.Equals("UserKeySet"))
            {
                keyStorageFlags = X509KeyStorageFlags.UserKeySet;
            }
            else if(keySet.Equals("MachineKeySet"))
            {
                keyStorageFlags = X509KeyStorageFlags.MachineKeySet;
            }

            if(properties.getPropertyAsIntWithDefault(prefix + "PersistKeySet", 0) > 0)
            {
                keyStorageFlags |= X509KeyStorageFlags.PersistKeySet;
            }

            //
            // Process IceSSL.ImportCert.* properties.
            //
            Dictionary<string, string> certs = properties.getPropertiesForPrefix(prefix + "ImportCert.");
            foreach(KeyValuePair<string, string> entry in certs)
            {
                string name = entry.Key;
                string val = entry.Value;
                if(val.Length > 0)
                {
                    importCertificate(name, val, keyStorageFlags);
                }
            }

            //
            // Select protocols.
            //
            _protocols = parseProtocols(prefix + "Protocols");

            //
            // CheckCertName determines whether we compare the name in a peer's
            // certificate against its hostname.
            //
            _checkCertName = properties.getPropertyAsIntWithDefault(prefix + "CheckCertName", 0) > 0;

            //
            // VerifyDepthMax establishes the maximum length of a peer's certificate
            // chain, including the peer's certificate. A value of 0 means there is
            // no maximum.
            //
            _verifyDepthMax = properties.getPropertyAsIntWithDefault(prefix + "VerifyDepthMax", 2);

            //
            // CheckCRL determines whether the certificate revocation list is checked, and how strictly.
            //
            _checkCRL = properties.getPropertyAsIntWithDefault(prefix + "CheckCRL", 0);

            //
            // Check for a certificate verifier.
            //
            string certVerifierClass = properties.getProperty(prefix + "CertVerifier");
            if(certVerifierClass.Length > 0)
            {
                if(_verifier != null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: certificate verifier already installed";
                    throw e;
                }

                Type cls = _facade.findType(certVerifierClass);
                if(cls == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load certificate verifier class " + certVerifierClass;
                    throw e;
                }

                try
                {
                    _verifier = (CertificateVerifier)IceInternal.AssemblyUtil.createInstance(cls);
                }
                catch(Exception ex)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                    e.reason = "IceSSL: unable to instantiate certificate verifier class " + certVerifierClass;
                    throw e;
                }

                if(_verifier == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to instantiate certificate verifier class " + certVerifierClass;
                    throw e;
                }
            }

            //
            // Check for a password callback.
            //
            string passwordCallbackClass = properties.getProperty(prefix + "PasswordCallback");
            if(passwordCallbackClass.Length > 0)
            {
                if(_passwordCallback != null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: password callback already installed";
                    throw e;
                }

                Type cls = _facade.findType(passwordCallbackClass);
                if(cls == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }

                try
                {
                    _passwordCallback = (PasswordCallback)IceInternal.AssemblyUtil.createInstance(cls);
                }
                catch(Exception ex)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }

                if(_passwordCallback == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }
            }

            //
            // If the user hasn't supplied a certificate collection, we need to examine
            // the property settings.
            //
            if(_certs == null)
            {
                //
                // If IceSSL.CertFile is defined, load a certificate from a file and
                // add it to the collection.
                //
                // TODO: tracing?
                _certs = new X509Certificate2Collection();
                string certFile = properties.getProperty(prefix + "CertFile");
                string passwordStr = properties.getProperty(prefix + "Password");
                
                if(certFile.Length > 0)
                {
                    if(!checkPath(ref certFile))
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: certificate file not found: " + certFile;
                        throw e;
                    }

                    SecureString password = null;
                    if(passwordStr.Length > 0)
                    {
                        password = createSecureString(passwordStr);
                    }
                    else if(_passwordCallback != null)
                    {
                        password = _passwordCallback.getPassword(certFile);
                    }

                    try
                    {
                        X509Certificate2 cert;
                        if(password != null)
                        {
                            cert = new X509Certificate2(certFile, password, keyStorageFlags);
                        }
                        else
                        {
                            cert = new X509Certificate2(certFile, "", keyStorageFlags);
                        }
                        _certs.Add(cert);
                    }
                    catch(CryptographicException ex)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                        e.reason = "IceSSL: error while attempting to load certificate from " + certFile;
                        throw e;
                    }
                }

                //
                // If IceSSL.FindCert.* properties are defined, add the selected certificates
                // to the collection.
                //
                // TODO: tracing?
                const string findPrefix = prefix + "FindCert.";
                Dictionary<string, string> certProps = properties.getPropertiesForPrefix(findPrefix);
                if(certProps.Count > 0)
                {
                    foreach(KeyValuePair<string, string> entry in certProps)
                    {
                        string name = entry.Key;
                        string val = entry.Value;
                        if(val.Length > 0)
                        {
                            string storeSpec = name.Substring(findPrefix.Length);
                            X509Certificate2Collection coll = findCertificates(name, storeSpec, val);
                            _certs.AddRange(coll);
                        }
                    }
                    if(_certs.Count == 0)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: no certificates found";
                        throw e;
                    }
                }
            }

            _initialized = true;
        }
Exemple #15
0
        internal void initialize()
        {
            if(_initialized)
            {
                return;
            }

            const string prefix = "IceSSL.";
            Ice.Properties properties = communicator().getProperties();

            //
            // Check for a default directory. We look in this directory for
            // files mentioned in the configuration.
            //
            _defaultDir = properties.getProperty(prefix + "DefaultDir");

            string certStoreLocation = properties.getPropertyWithDefault(prefix + "CertStoreLocation", "CurrentUser");
            StoreLocation storeLocation;
            if(certStoreLocation == "CurrentUser")
            {
                storeLocation = StoreLocation.CurrentUser;
            }
            else if(certStoreLocation == "LocalMachine")
            {
                storeLocation = StoreLocation.LocalMachine;
            }
            else
            {
                _logger.warning("Invalid IceSSL.CertStoreLocation value `" + certStoreLocation +
                                "' adjusted to `CurrentUser'");
                storeLocation = StoreLocation.CurrentUser;
            }
            _useMachineContext = certStoreLocation == "LocalMachine";

#if !UNITY
            X509KeyStorageFlags keyStorageFlags;
            if(_useMachineContext)
            {
                keyStorageFlags = X509KeyStorageFlags.MachineKeySet;
            }
            else
            {
                keyStorageFlags = X509KeyStorageFlags.UserKeySet;
            }

            string keySet = properties.getProperty(prefix + "KeySet"); // Deprecated property
            if(keySet.Length > 0)
            {
                if(keySet.Equals("DefaultKeySet"))
                {
                    keyStorageFlags = X509KeyStorageFlags.DefaultKeySet;
                }
                else if(keySet.Equals("UserKeySet"))
                {
                    keyStorageFlags = X509KeyStorageFlags.UserKeySet;
                }
                else if(keySet.Equals("MachineKeySet"))
                {
                    keyStorageFlags = X509KeyStorageFlags.MachineKeySet;
                }
                else
                {
                    _logger.warning("Invalid IceSSL.KeySet value `" + keySet + "' adjusted to `DefaultKeySet'");
                    keyStorageFlags = X509KeyStorageFlags.DefaultKeySet;
                }
            }

            if(properties.getPropertyAsIntWithDefault(prefix + "PersistKeySet", 0) > 0) // Deprecated property
            {
                keyStorageFlags |= X509KeyStorageFlags.PersistKeySet;
            }

            //
            // Process IceSSL.ImportCert.* properties.
            //
            Dictionary<string, string> certs = properties.getPropertiesForPrefix(prefix + "ImportCert.");
            foreach(KeyValuePair<string, string> entry in certs)
            {
                string name = entry.Key;
                string val = entry.Value;
                if(val.Length > 0)
                {
                    importCertificate(name, val, keyStorageFlags);
                }
            }
#endif

            //
            // Protocols selects which protocols to enable, by default we only enable TLS1.0
            // TLS1.1 and TLS1.2 to avoid security issues with SSLv3
            //
            _protocols = parseProtocols(
                properties.getPropertyAsListWithDefault(prefix + "Protocols",
#if UNITY
                                                        new string[]{"TLS1_0"}));
#else
                                                        _tls12Support ? new string[]{"TLS1_0", "TLS1_1", "TLS1_2"} :
                                                                        new string[]{"TLS1_0", "TLS1_1"}));
#endif
            //
            // CheckCertName determines whether we compare the name in a peer's
            // certificate against its hostname.
            //
            _checkCertName = properties.getPropertyAsIntWithDefault(prefix + "CheckCertName", 0) > 0;

            //
            // VerifyDepthMax establishes the maximum length of a peer's certificate
            // chain, including the peer's certificate. A value of 0 means there is
            // no maximum.
            //
            _verifyDepthMax = properties.getPropertyAsIntWithDefault(prefix + "VerifyDepthMax", 3);

            //
            // CheckCRL determines whether the certificate revocation list is checked, and how strictly.
            //
            _checkCRL = properties.getPropertyAsIntWithDefault(prefix + "CheckCRL", 0);

#if !UNITY
            //
            // Check for a certificate verifier.
            //
            string certVerifierClass = properties.getProperty(prefix + "CertVerifier");
            if(certVerifierClass.Length > 0)
            {
                if(_verifier != null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: certificate verifier already installed";
                    throw e;
                }

                Type cls = _facade.findType(certVerifierClass);
                if(cls == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load certificate verifier class " + certVerifierClass;
                    throw e;
                }

                try
                {
                    _verifier = (CertificateVerifier)IceInternal.AssemblyUtil.createInstance(cls);
                }
                catch(Exception ex)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                    e.reason = "IceSSL: unable to instantiate certificate verifier class " + certVerifierClass;
                    throw e;
                }

                if(_verifier == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to instantiate certificate verifier class " + certVerifierClass;
                    throw e;
                }
            }

            //
            // Check for a password callback.
            //
            string passwordCallbackClass = properties.getProperty(prefix + "PasswordCallback");
            if(passwordCallbackClass.Length > 0)
            {
                if(_passwordCallback != null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: password callback already installed";
                    throw e;
                }

                Type cls = _facade.findType(passwordCallbackClass);
                if(cls == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }

                try
                {
                    _passwordCallback = (PasswordCallback)IceInternal.AssemblyUtil.createInstance(cls);
                }
                catch(Exception ex)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }

                if(_passwordCallback == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }
            }

            //
            // If the user hasn't supplied a certificate collection, we need to examine
            // the property settings.
            //
            if(_certs == null)
            {
                //
                // If IceSSL.CertFile is defined, load a certificate from a file and
                // add it to the collection.
                //
                // TODO: tracing?
                _certs = new X509Certificate2Collection();
                string certFile = properties.getProperty(prefix + "CertFile");
                string passwordStr = properties.getProperty(prefix + "Password");
                string findCert = properties.getProperty(prefix + "FindCert");
                const string findPrefix = prefix + "FindCert.";
                Dictionary<string, string> findCertProps = properties.getPropertiesForPrefix(findPrefix);

                if(certFile.Length > 0)
                {
                    if(!checkPath(ref certFile))
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: certificate file not found: " + certFile;
                        throw e;
                    }

                    SecureString password = null;
                    if(passwordStr.Length > 0)
                    {
                        password = createSecureString(passwordStr);
                    }
                    else if(_passwordCallback != null)
                    {
                        password = _passwordCallback.getPassword(certFile);
                    }

                    try
                    {
                        X509Certificate2 cert;
                        X509KeyStorageFlags importFlags;
                        if(_useMachineContext)
                        {
                            importFlags = X509KeyStorageFlags.MachineKeySet;
                        }
                        else
                        {
                            importFlags = X509KeyStorageFlags.UserKeySet;
                        }

                        if(password != null)
                        {
                            cert = new X509Certificate2(certFile, password, importFlags);
                        }
                        else
                        {
                            cert = new X509Certificate2(certFile, "", importFlags);
                        }
                        _certs.Add(cert);
                    }
                    catch(CryptographicException ex)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                        e.reason = "IceSSL: error while attempting to load certificate from " + certFile;
                        throw e;
                    }
                }
                else if(findCert.Length > 0)
                {
                    string certStore = properties.getPropertyWithDefault("IceSSL.CertStore", "My");
                    _certs.AddRange(findCertificates("IceSSL.FindCert", storeLocation, certStore, findCert));
                    if(_certs.Count == 0)
                    {
                        throw new Ice.PluginInitializationException("IceSSL: no certificates found");
                    }
                }
                else if(findCertProps.Count > 0)
                {
                    //
                    // If IceSSL.FindCert.* properties are defined, add the selected certificates
                    // to the collection.
                    //
                    foreach(KeyValuePair<string, string> entry in findCertProps)
                    {
                        string name = entry.Key;
                        string val = entry.Value;
                        if(val.Length > 0)
                        {
                            string storeSpec = name.Substring(findPrefix.Length);
                            StoreLocation storeLoc = 0;
                            StoreName storeName = 0;
                            string sname = null;
                            parseStore(name, storeSpec, ref storeLoc, ref storeName, ref sname);
                            if(sname == null)
                            {
                                sname = storeName.ToString();
                            }
                            X509Certificate2Collection coll = findCertificates(name, storeLoc, sname, val);
                            _certs.AddRange(coll);
                        }
                    }
                    if(_certs.Count == 0)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: no certificates found";
                        throw e;
                    }
                }
            }

            if(_caCerts == null)
            {
                string certAuthFile = properties.getProperty(prefix + "CAs");
                if(certAuthFile.Length == 0)
                {
                    certAuthFile = properties.getProperty(prefix + "CertAuthFile");
                }
                if(certAuthFile.Length > 0 || properties.getPropertyAsInt(prefix + "UsePlatformCAs") <= 0)
                {
                    _caCerts = new X509Certificate2Collection();
                }
                if(certAuthFile.Length > 0)
                {
                    if(!checkPath(ref certAuthFile))
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: CA certificate file not found: " + certAuthFile;
                        throw e;
                    }

                    try
                    {
                        using(System.IO.FileStream fs = System.IO.File.OpenRead(certAuthFile))
                        {
                            byte[] data = new byte[fs.Length];
                            fs.Read(data, 0, data.Length);

                            string strbuf = "";
                            try
                            {
                                strbuf = System.Text.Encoding.UTF8.GetString(data);
                            }
                            catch(Exception)
                            {
                                // Ignore
                            }

                            if(strbuf.Length == data.Length)
                            {
                                int size, startpos, endpos = 0;
                                bool first = true;
                                while(true)
                                {
                                    startpos = strbuf.IndexOf("-----BEGIN CERTIFICATE-----", endpos);
                                    if(startpos != -1)
                                    {
                                        endpos = strbuf.IndexOf("-----END CERTIFICATE-----", startpos);
                                        size = endpos - startpos + "-----END CERTIFICATE-----".Length;
                                    }
                                    else if(first)
                                    {
                                        startpos = 0;
                                        endpos = strbuf.Length;
                                        size = strbuf.Length;
                                    }
                                    else
                                    {
                                        break;
                                    }

                                    byte[] cert = new byte[size];
                                    System.Buffer.BlockCopy(data, startpos, cert, 0, size);
                                    _caCerts.Import(cert);
                                    first = false;
                                }
                            }
                            else
                            {
                                _caCerts.Import(data);
                            }
                        }
                    }
                    catch(Exception ex)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                        e.reason = "IceSSL: error while attempting to load CA certificate from " + certAuthFile;
                        throw e;
                    }
                }
            }
#endif

            _initialized = true;
        }
Exemple #16
0
        private SslProtocols parseProtocols(string[] arr)
        {
            SslProtocols result = SslProtocols.Default;

            if(arr.Length > 0)
            {
                result = 0;
                for(int i = 0; i < arr.Length; ++i)
                {
                    string protocol = null;
                    string s = arr[i].ToUpperInvariant();
                    switch(s)
                    {
                        case "SSL3":
                        case "SSLV3":
                        {
                            protocol = "Ssl3";
                            break;
                        }
                        case "TLS":
                        case "TLS1":
                        case "TLS1_0":
                        case "TLSV1":
                        case "TLSV1_0":
                        {
                            protocol = "Tls";
                            break;
                        }
                        case "TLS1_1":
                        case "TLSV1_1":
                        {
                            protocol = "Tls11";
                            break;
                        }
                        case "TLS1_2":
                        case "TLSV1_2":
                        {
                            protocol = "Tls12";
                            break;
                        }
                        default:
                        {
                            break;
                        }
                    }

                    try
                    {
                        SslProtocols value = (SslProtocols)Enum.Parse(typeof(SslProtocols), protocol);
                        result |= value;
                    }
                    catch(Exception)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: unrecognized protocol `" + s + "'";
                        throw e;
                    }
                }
            }
            return result;
        }
Exemple #17
0
        internal void initialize()
        {
            if (_initialized)
            {
                return;
            }

            const string prefix = "IceSSL.";

            Ice.Properties properties = communicator().getProperties();

            //
            // Check for a default directory. We look in this directory for
            // files mentioned in the configuration.
            //
            _defaultDir = properties.getProperty(prefix + "DefaultDir");

            string keySet = properties.getPropertyWithDefault(prefix + "KeySet", "DefaultKeySet");

            if (!keySet.Equals("DefaultKeySet") && !keySet.Equals("UserKeySet") && !keySet.Equals("MachineKeySet"))
            {
                _logger.warning("Invalid IceSSL.KeySet value `" + keySet + "' adjusted to `DefaultKeySet'");
                keySet = "DefaultKeySet";
            }

            X509KeyStorageFlags keyStorageFlags = X509KeyStorageFlags.DefaultKeySet;

            if (keySet.Equals("UserKeySet"))
            {
                keyStorageFlags = X509KeyStorageFlags.UserKeySet;
            }
            else if (keySet.Equals("MachineKeySet"))
            {
                keyStorageFlags = X509KeyStorageFlags.MachineKeySet;
            }

            if (properties.getPropertyAsIntWithDefault(prefix + "PersistKeySet", 0) > 0)
            {
                keyStorageFlags |= X509KeyStorageFlags.PersistKeySet;
            }

            //
            // Process IceSSL.ImportCert.* properties.
            //
            Dictionary <string, string> certs = properties.getPropertiesForPrefix(prefix + "ImportCert.");

            foreach (KeyValuePair <string, string> entry in certs)
            {
                string name = entry.Key;
                string val  = entry.Value;
                if (val.Length > 0)
                {
                    importCertificate(name, val, keyStorageFlags);
                }
            }

            //
            // Select protocols.
            //
            _protocols = parseProtocols(prefix + "Protocols");

            //
            // CheckCertName determines whether we compare the name in a peer's
            // certificate against its hostname.
            //
            _checkCertName = properties.getPropertyAsIntWithDefault(prefix + "CheckCertName", 0) > 0;

            //
            // VerifyDepthMax establishes the maximum length of a peer's certificate
            // chain, including the peer's certificate. A value of 0 means there is
            // no maximum.
            //
            _verifyDepthMax = properties.getPropertyAsIntWithDefault(prefix + "VerifyDepthMax", 2);

            //
            // CheckCRL determines whether the certificate revocation list is checked, and how strictly.
            //
            _checkCRL = properties.getPropertyAsIntWithDefault(prefix + "CheckCRL", 0);

            //
            // Check for a certificate verifier.
            //
            string certVerifierClass = properties.getProperty(prefix + "CertVerifier");

            if (certVerifierClass.Length > 0)
            {
                if (_verifier != null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: certificate verifier already installed";
                    throw e;
                }

                Type cls = _facade.findType(certVerifierClass);
                if (cls == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load certificate verifier class " + certVerifierClass;
                    throw e;
                }

                try
                {
                    _verifier = (CertificateVerifier)IceInternal.AssemblyUtil.createInstance(cls);
                }
                catch (Exception ex)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                    e.reason = "IceSSL: unable to instantiate certificate verifier class " + certVerifierClass;
                    throw e;
                }

                if (_verifier == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to instantiate certificate verifier class " + certVerifierClass;
                    throw e;
                }
            }

            //
            // Check for a password callback.
            //
            string passwordCallbackClass = properties.getProperty(prefix + "PasswordCallback");

            if (passwordCallbackClass.Length > 0)
            {
                if (_passwordCallback != null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: password callback already installed";
                    throw e;
                }

                Type cls = _facade.findType(passwordCallbackClass);
                if (cls == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }

                try
                {
                    _passwordCallback = (PasswordCallback)IceInternal.AssemblyUtil.createInstance(cls);
                }
                catch (Exception ex)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }

                if (_passwordCallback == null)
                {
                    Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                    e.reason = "IceSSL: unable to load password callback class " + passwordCallbackClass;
                    throw e;
                }
            }

            //
            // If the user hasn't supplied a certificate collection, we need to examine
            // the property settings.
            //
            if (_certs == null)
            {
                //
                // If IceSSL.CertFile is defined, load a certificate from a file and
                // add it to the collection.
                //
                // TODO: tracing?
                _certs = new X509Certificate2Collection();
                string certFile    = properties.getProperty(prefix + "CertFile");
                string passwordStr = properties.getProperty(prefix + "Password");

                if (certFile.Length > 0)
                {
                    if (!checkPath(ref certFile))
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: certificate file not found: " + certFile;
                        throw e;
                    }

                    SecureString password = null;
                    if (passwordStr.Length > 0)
                    {
                        password = createSecureString(passwordStr);
                    }
                    else if (_passwordCallback != null)
                    {
                        password = _passwordCallback.getPassword(certFile);
                    }

                    try
                    {
                        X509Certificate2 cert;
                        if (password != null)
                        {
                            cert = new X509Certificate2(certFile, password, keyStorageFlags);
                        }
                        else
                        {
                            cert = new X509Certificate2(certFile, "", keyStorageFlags);
                        }
                        _certs.Add(cert);
                    }
                    catch (CryptographicException ex)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                        e.reason = "IceSSL: error while attempting to load certificate from " + certFile;
                        throw e;
                    }
                }

                //
                // If IceSSL.FindCert.* properties are defined, add the selected certificates
                // to the collection.
                //
                // TODO: tracing?
                const string findPrefix = prefix + "FindCert.";
                Dictionary <string, string> certProps = properties.getPropertiesForPrefix(findPrefix);
                if (certProps.Count > 0)
                {
                    foreach (KeyValuePair <string, string> entry in certProps)
                    {
                        string name = entry.Key;
                        string val  = entry.Value;
                        if (val.Length > 0)
                        {
                            string storeSpec = name.Substring(findPrefix.Length);
                            X509Certificate2Collection coll = findCertificates(name, storeSpec, val);
                            _certs.AddRange(coll);
                        }
                    }
                    if (_certs.Count == 0)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: no certificates found";
                        throw e;
                    }
                }
            }

            _initialized = true;
        }
Exemple #18
0
        private static X509Certificate2Collection findCertificates(string prop, StoreLocation storeLocation,
                                                                   string name, string value)
        {
            //
            // Open the X509 certificate store.
            //
            X509Store store = null;

            try
            {
                try
                {
                    store = new X509Store((StoreName)Enum.Parse(typeof(StoreName), name, true), storeLocation);
                }
                catch (ArgumentException)
                {
                    store = new X509Store(name, storeLocation);
                }
                store.Open(OpenFlags.ReadOnly);
            }
            catch (Exception ex)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                e.reason = "IceSSL: failure while opening store specified by " + prop;
                throw e;
            }

            //
            // Start with all of the certificates in the collection and filter as necessary.
            //
            // - If the value is "*", return all certificates.
            // - Otherwise, search using key:value pairs. The following keys are supported:
            //
            //   Issuer
            //   IssuerDN
            //   Serial
            //   Subject
            //   SubjectDN
            //   SubjectKeyId
            //   Thumbprint
            //
            //   A value must be enclosed in single or double quotes if it contains whitespace.
            //
            X509Certificate2Collection result = new X509Certificate2Collection();

            result.AddRange(store.Certificates);
            try
            {
                if (value != "*")
                {
                    if (value.IndexOf(':') == -1)
                    {
                        Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                        e.reason = "IceSSL: no key in `" + value + "'";
                        throw e;
                    }
                    int start = 0;
                    int pos;
                    while ((pos = value.IndexOf(':', start)) != -1)
                    {
                        //
                        // Parse the X509FindType.
                        //
                        string       field = value.Substring(start, pos - start).Trim().ToUpperInvariant();
                        X509FindType findType;
                        if (field.Equals("SUBJECT"))
                        {
                            findType = X509FindType.FindBySubjectName;
                        }
                        else if (field.Equals("SUBJECTDN"))
                        {
                            findType = X509FindType.FindBySubjectDistinguishedName;
                        }
                        else if (field.Equals("ISSUER"))
                        {
                            findType = X509FindType.FindByIssuerName;
                        }
                        else if (field.Equals("ISSUERDN"))
                        {
                            findType = X509FindType.FindByIssuerDistinguishedName;
                        }
                        else if (field.Equals("THUMBPRINT"))
                        {
                            findType = X509FindType.FindByThumbprint;
                        }
                        else if (field.Equals("SUBJECTKEYID"))
                        {
                            findType = X509FindType.FindBySubjectKeyIdentifier;
                        }
                        else if (field.Equals("SERIAL"))
                        {
                            findType = X509FindType.FindBySerialNumber;
                        }
                        else
                        {
                            Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                            e.reason = "IceSSL: unknown key in `" + value + "'";
                            throw e;
                        }

                        //
                        // Parse the argument.
                        //
                        start = pos + 1;
                        while (start < value.Length && (value[start] == ' ' || value[start] == '\t'))
                        {
                            ++start;
                        }
                        if (start == value.Length)
                        {
                            Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                            e.reason = "IceSSL: missing argument in `" + value + "'";
                            throw e;
                        }

                        string arg;
                        if (value[start] == '"' || value[start] == '\'')
                        {
                            int end = start;
                            ++end;
                            while (end < value.Length)
                            {
                                if (value[end] == value[start] && value[end - 1] != '\\')
                                {
                                    break;
                                }
                                ++end;
                            }
                            if (end == value.Length || value[end] != value[start])
                            {
                                Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                                e.reason = "IceSSL: unmatched quote in `" + value + "'";
                                throw e;
                            }
                            ++start;
                            arg   = value.Substring(start, end - start);
                            start = end + 1;
                        }
                        else
                        {
                            char[] ws  = new char[] { ' ', '\t' };
                            int    end = value.IndexOfAny(ws, start);
                            if (end == -1)
                            {
                                arg   = value.Substring(start);
                                start = value.Length;
                            }
                            else
                            {
                                arg   = value.Substring(start, end - start);
                                start = end + 1;
                            }
                        }

                        //
                        // Execute the query.
                        //
                        // TODO: allow user to specify a value for validOnly?
                        //
                        bool validOnly = false;
                        if (findType == X509FindType.FindBySubjectDistinguishedName ||
                            findType == X509FindType.FindByIssuerDistinguishedName)
                        {
                            X500DistinguishedNameFlags[] flags =
                            {
                                X500DistinguishedNameFlags.None,
                                X500DistinguishedNameFlags.Reversed,
                            };
                            X500DistinguishedName      dn = new X500DistinguishedName(arg);
                            X509Certificate2Collection r  = result;
                            for (int i = 0; i < flags.Length; ++i)
                            {
                                r = result.Find(findType, dn.Decode(flags[i]), validOnly);
                                if (r.Count > 0)
                                {
                                    break;
                                }
                            }
                            result = r;
                        }
                        else
                        {
                            result = result.Find(findType, arg, validOnly);
                        }
                    }
                }
            }
            finally
            {
                store.Close();
            }

            return(result);
        }
Exemple #19
0
        //
        // Parse a string of the form "location.name" into two parts.
        //
        internal void parseStore(string prop, string store, ref StoreLocation loc, ref StoreName name, ref string sname)
        {
            int pos = store.IndexOf('.');
            if(pos == -1)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                e.reason = "IceSSL: property `" + prop + "' has invalid format";
                throw e;
            }

            string sloc = store.Substring(0, pos).ToUpperInvariant();
            if(sloc.Equals("CURRENTUSER"))
            {
                loc = StoreLocation.CurrentUser;
            }
            else if(sloc.Equals("LOCALMACHINE"))
            {
                loc = StoreLocation.LocalMachine;
            }
            else
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                e.reason = "IceSSL: unknown store location `" + sloc + "' in " + prop;
                throw e;
            }

            sname = store.Substring(pos + 1);
            if(sname.Length == 0)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                e.reason = "IceSSL: invalid store name in " + prop;
                throw e;
            }

            //
            // Try to convert the name into the StoreName enumeration.
            //
            try
            {
                name = (StoreName)Enum.Parse(typeof(StoreName), sname, true);
                sname = null;
            }
            catch(ArgumentException)
            {
                // Ignore - assume the user is selecting a non-standard store.
            }
        }
Exemple #20
0
        internal void setCertificates(X509Certificate2Collection certs)
        {
            if(_initialized)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                e.reason = "IceSSL: plug-in is already initialized";
                throw e;
            }

            _certs = certs;
        }
Exemple #21
0
        private void importCertificate(string propName, string propValue, X509KeyStorageFlags keyStorageFlags)
        {
            //
            // Expecting a property of the following form:
            //
            // IceSSL.ImportCert.<location>.<name>=<file>[;password]
            //
            const string  prefix = "IceSSL.ImportCert.";
            StoreLocation loc    = 0;
            StoreName     name   = 0;
            string        sname  = null;

            parseStore(propName, propName.Substring(prefix.Length), ref loc, ref name, ref sname);

            //
            // Extract the filename and password. Either or both can be quoted.
            //
            string[] arr = splitString(propValue, ';');
            if (arr == null)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                e.reason = "IceSSL: unmatched quote in `" + propValue + "'";
                throw e;
            }
            if (arr.Length == 0)
            {
                return;
            }
            string file        = arr[0];
            string passwordStr = null;

            if (arr.Length > 1)
            {
                passwordStr = arr[1];
            }

            //
            // Open the X509 certificate store.
            //
            X509Store store = null;

            try
            {
                if (sname != null)
                {
                    store = new X509Store(sname, loc);
                }
                else
                {
                    store = new X509Store(name, loc);
                }
                store.Open(OpenFlags.ReadWrite);
            }
            catch (Exception ex)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                e.reason = "IceSSL: failure while opening store specified by " + propName;
                throw e;
            }

            if (!checkPath(ref file))
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException();
                e.reason = "IceSSL: certificate file not found:\n" + file;
                throw e;
            }

            SecureString password = null;

            if (passwordStr != null)
            {
                password = createSecureString(passwordStr);
            }
            else if (_passwordCallback != null)
            {
                password = _passwordCallback.getImportPassword(file);
            }

            //
            // Add the certificate to the store.
            //
            try
            {
                X509Certificate2 cert;
                if (password != null)
                {
                    cert = new X509Certificate2(file, password, keyStorageFlags);
                }
                else
                {
                    cert = new X509Certificate2(file, "", keyStorageFlags);
                }
                store.Add(cert);
            }
            catch (Exception ex)
            {
                Ice.PluginInitializationException e = new Ice.PluginInitializationException(ex);
                e.reason = "IceSSL: failure while adding certificate file:\n" + file;
                throw e;
            }
            finally
            {
                store.Close();
            }
        }