Exemplo n.º 1
0
        private static Dictionary <string, string> GetKeywords(X509Store store, X509FindType findType, string searchString)
        {
            Dictionary <string, string> keywords = KeywordsFromX509Store.GetKeywords(store);

            KeywordFromString.GetKeyword(keywords, "x509findtype", findType.ToString());
            KeywordFromString.GetKeyword(keywords, "searchstring", searchString);
            return(keywords);
        }
        public string[] Build()
        {
            string[] result = new string[10];

            result[0] = $"-{nameof(StoreName)}";
            result[1] = StoreName.ToString();

            result[2] = $"-{nameof(StoreLocation)}";
            result[3] = StoreLocation.ToString();

            result[4] = $"-{nameof(X509FindType)}";
            result[5] = X509FindType.ToString();

            result[6] = $"-{nameof(OpenFlags)}";
            result[7] = OpenFlags.ToString();

            result[8] = $"-{nameof(FindValue)}";
            result[9] = FindValue;

            return(result);
        }
Exemplo n.º 3
0
 public static string GetString(X509FindType type)
 {
     return(type.ToString().Replace("FindBy", string.Empty));
 }
Exemplo n.º 4
0
        public static X509Certificate2Collection FindMatchingCertificates(
            StoreLocation storeLocation,
            string storeName,
            X509FindType findType,
            string findValue,
            string secondaryFindValue,
            bool doTakeMostRecentOnly)
        {
            X509Store store;

            var certificates = new X509Certificate2Collection();

            if (string.IsNullOrWhiteSpace(storeName) ||
                string.IsNullOrWhiteSpace(findValue))
            {
                Console.WriteLine("PaasCoordinator: No certificate configured");

                // Fall back to 'anonymous' self-signed certificate so that WRP's web host
                // does not reject the connection for lacking a cert. This certificate is
                // installed by the ServiceFabric extension when no cluster security is configured.
                // It is not trusted in any way, and only works when cert security is disabled for
                // the cluster resource.

                // CoreCLR Does not support StoreLocation.LocalMachine, hence using StoreLocation.CurrentUser
#if DotNetCoreClrLinux
                store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
#else
                store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
#endif
                try
                {
                    store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

                    var certCollections = store.Certificates.Find(
                        X509FindType.FindBySubjectDistinguishedName,
                        "AnonymousCertDistiguishedName",
                        false /*load self-signed cert*/);

                    if (certCollections.Count > 0)
                    {
                        certificates.Add(certCollections[0]);
                    }
                }
                finally
                {
#if DotNetCoreClrLinux
                    store.Dispose();
#else
                    store.Close();
#endif
                }

                return(certificates);
            }

            IsCertificateAMatchForFindValue matchCert;
            switch (findType)
            {
            case X509FindType.FindByThumbprint:
                matchCert = IsMatchByThumbprint;
                break;

            case X509FindType.FindBySubjectName:
                matchCert = IsMatchBySubjectCommonName;
                break;

            default:
                throw new ArgumentException("Unsupported X509FindType: '{0}'; supported values are FindByThumbprint and FindBySubjectName", findType.ToString());
            }

            // SFRP is generating ClusterManifests setting this value to StoreLocation.LocalMachine
            // Using hard-coded value of StoreLocation.CurrentUser for TP9 till SFRP is updated to set this value appropriately.
#if DotNetCoreClrLinux
            using (store = new X509Store(storeName, StoreLocation.CurrentUser))
#else
            using (store = new X509Store(storeName, storeLocation))
#endif
            {
                X509Certificate2 selectedCert = null;
                try
                {
                    bool     excludeExpiredCerts = true; // todo [dragosav]: update when enabling support for expired certs
                    bool     isTimeValidCert     = false;
                    bool     isExpiredCert       = false;
                    bool     anyMatchFound       = false;
                    DateTime now = DateTime.Now;        // cert validity is presented in local time.

                    store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

                    var findValues = new List <string>()
                    {
                        findValue
                    };
                    if (!string.IsNullOrEmpty(secondaryFindValue))
                    {
                        findValues.Add(secondaryFindValue);
                    }

                    foreach (var value in findValues)
                    {
                        Console.WriteLine("Finding matching certificates for find value '{0}'; excludeExpiredCerts = '{1}'", findValue, excludeExpiredCerts);
                        foreach (var enumeratedCert in store.Certificates)
                        {
                            isExpiredCert   = DateTime.Compare(now, enumeratedCert.NotAfter) > 0;
                            isTimeValidCert = !(excludeExpiredCerts && isExpiredCert) &&
                                              DateTime.Compare(now, enumeratedCert.NotBefore) >= 0;
                            if (matchCert(enumeratedCert, value) &&
                                isTimeValidCert)
                            {
                                anyMatchFound = true;

                                Console.WriteLine("Found matching certificate: Thumbprint {0}, NotBefore {1}, NotAfter {2}, Subject {3}",
                                                  enumeratedCert.Thumbprint,
                                                  enumeratedCert.NotBefore,
                                                  enumeratedCert.NotAfter,
                                                  enumeratedCert.Subject);

                                if (!doTakeMostRecentOnly)
                                {
                                    // if taking all, add it here and continue
                                    certificates.Add(enumeratedCert);
                                    continue;
                                }

                                // Select the most recent and farthest valid matching cert.
                                // This should make it predictible if certificate is compromised and it needs to be replaced with a newer one.
                                if (selectedCert == null ||
                                    selectedCert.NotBefore < enumeratedCert.NotBefore)
                                {
                                    selectedCert = enumeratedCert;
                                }
                                else if (selectedCert.NotBefore == enumeratedCert.NotBefore &&
                                         !selectedCert.Thumbprint.Equals(enumeratedCert.Thumbprint))
                                {
                                    // if both were issued at the same time, prefer the farthest valid
                                    selectedCert = selectedCert.NotAfter >= enumeratedCert.NotAfter ? selectedCert : enumeratedCert;
                                }
                            }
                        }
                    }

                    if (selectedCert != null &&
                        doTakeMostRecentOnly)
                    {
                        Console.WriteLine("Selected certificate: Thumbprint {0}, NotBefore {1}, NotAfter {2}, Subject {3}",
                                          selectedCert.Thumbprint,
                                          selectedCert.NotBefore,
                                          selectedCert.NotAfter,
                                          selectedCert.Subject);

                        certificates.Add(selectedCert);
                    }
                    else
                    {
                        Console.WriteLine("No {0} certificate found: StoreName {1}, StoreLocation {2}, FindType {3}, FindValue {4}",
                                          anyMatchFound ? "valid" : "matching",
                                          storeName,
                                          storeLocation,
                                          findType,
                                          findValue);
                    }
                }
                finally
                {
#if DotNetCoreClrLinux
                    store.Dispose();
#else
                    store.Close();
#endif
                }
            }

            if (certificates.Count == 0)
            {
                throw new InvalidOperationException("Could not load primary and secondary certificate");
            }

            return(certificates);
        }