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(); } } }