Esempio n. 1
0
        public static IEnumerable <string> TryFindCertificate(
            string machineIpOrFqdn,
            StoreName storeName,
            IEnumerable <string> findValues,
            X509FindType findType,
            out IEnumerable <X509Certificate2> foundCertificates,
            ITraceLogger traceLogger = null)
        {
            machineIpOrFqdn.MustNotBeNull("machineIpOrFqdn");

            // The validation on each thumbprint string will be covered by RDBug 7682650.
            findValues.ToArray().MustNotBeEmptyCollection("findValues");

            List <X509Certificate2> tmpFoundCertificates = new List <X509Certificate2>();

            foundCertificates = Enumerable.Empty <X509Certificate2>();
            List <string> result = new List <string>();
            X509Store     store  = null;

            string strStoreName = storeName.ToString();

            if (machineIpOrFqdn != string.Empty)
            {
                strStoreName = machineIpOrFqdn + "\\" + storeName;
            }

            try
            {
                try
                {
                    store = new X509Store(strStoreName, StoreLocation.LocalMachine);
                    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                }
                catch (CryptographicException ex)
                {
                    // if the exception is access denied error, check if the read permission on the registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurePipeServers\winreg
                    // of the remote node machineIpOrFqdn has been granted to the caller account.
                    if (traceLogger != null)
                    {
                        traceLogger.WriteWarning(X509CertificateUtility.TraceType, ex.ToString());
                    }

                    return(findValues);
                }

                foreach (string findValue in findValues)
                {
                    X509Certificate2Collection certs = store.Certificates.Find(findType, findValue, validOnly: false);
                    if (certs != null && findType == X509FindType.FindBySubjectName)
                    {
                        certs.MatchExactSubject(findValue);
                    }

                    if (certs == null || certs.Count == 0)
                    {
                        result.Add(findValue);
                    }
                    else
                    {
                        tmpFoundCertificates.Add(findType == X509FindType.FindByThumbprint ? certs[0] : certs.LatestExpired());
                    }
                }

                foundCertificates = tmpFoundCertificates;
                return(result);
            }
            finally
            {
                // In .net 4.6, X509Store is changed to implement IDisposable.
                // But unfortunately, SF today is built on .net 4.5
                if (store != null)
                {
                    store.Close();
                }
            }
        }