internal void ValidateCertificates()
        {
            if (this.clusterProperties.Security == null || this.clusterProperties.Security.CertificateInformation == null)
            {
                return;
            }

            X509 certInfo = this.clusterProperties.Security.CertificateInformation;
            List <ClientCertificateThumbprint> clientCertificateThumbprints = certInfo.ClientCertificateThumbprints;
            List <ClientCertificateCommonName> clientCertificateCommonNames = certInfo.ClientCertificateCommonNames;

            bool serverCertificatePresent    = certInfo.ServerCertificate != null || (certInfo.ServerCertificateCommonNames != null && certInfo.ServerCertificateCommonNames.Any());
            bool clientCertificatInfoPresent = (clientCertificateCommonNames != null && clientCertificateCommonNames.Count > 0) ||
                                               (clientCertificateThumbprints != null && clientCertificateThumbprints.Count > 0);

            if (clientCertificatInfoPresent && !serverCertificatePresent)
            {
                throw new ValidationException(ClusterManagementErrorCode.ClientCertDefinedWithoutServerCert);
            }

            SettingsValidator.ValidateThumbprints(certInfo);
            SettingsValidator.ValidateCommonNames(certInfo);
            SettingsValidator.ValidateCommonNamesAgainstThumbprints(certInfo);
            SettingsValidator.ValidateIssuerCertStore(certInfo);
        }
        internal static void ValidateCommonNames(X509 certInfo)
        {
            // CNs must not be null
            IEnumerable <CertificateCommonNameBase> allCns = SettingsValidator.GetAllCommonNames(certInfo);

            if (allCns.Any(cn => string.IsNullOrWhiteSpace(cn.CertificateCommonName)))
            {
                throw new ValidationException(ClusterManagementErrorCode.InvalidCommonName);
            }

            IEnumerable <CertificateCommonNameBase> allCnsWithoutItSupport = SettingsValidator.GetAllCommonNames(certInfo, false);

            if (allCnsWithoutItSupport.Any(cn => !string.IsNullOrWhiteSpace(cn.CertificateIssuerThumbprint)))
            {
                throw new ValidationException(ClusterManagementErrorCode.UnsupportedIssuerThumbprintPair);
            }

            // Issuer thumbprints must be separated by comma, and should not dupe under the same cn
            IEnumerable <CertificateCommonNameBase> allCnsWithItSupport = SettingsValidator.GetAllCommonNames(certInfo, true);

            foreach (CertificateCommonNameBase cn in allCnsWithItSupport)
            {
                if (!string.IsNullOrWhiteSpace(cn.CertificateIssuerThumbprint) &&
                    !SettingsValidator.AreValidIssuerThumbprints(cn.CertificateIssuerThumbprint))
                {
                    throw new ValidationException(ClusterManagementErrorCode.InvalidCertificateIssuerThumbprints, cn.CertificateIssuerThumbprint);
                }
            }

            // Up to 2 CNs are supported, except client CN
            List <ServerCertificateCommonNames> cnsWithCountCap = new List <ServerCertificateCommonNames>()
            {
                certInfo.ClusterCertificateCommonNames,
                certInfo.ReverseProxyCertificateCommonNames,
                certInfo.ServerCertificateCommonNames
            };

            if (cnsWithCountCap.Any(cns => cns != null && cns.CommonNames != null && cns.CommonNames.Count > 2))
            {
                throw new ValidationException(ClusterManagementErrorCode.InvalidCommonNameCount);
            }

            // no dupe CN is allowed for the same cert type, except client CN
            foreach (List <CertificateCommonNameBase> cns in cnsWithCountCap
                     .Where(p => p != null && p.CommonNames != null)
                     .Select(p => p.CommonNames))
            {
                if (cns.Any(current =>
                            cns.Any(other => current != other && current.CertificateCommonName == other.CertificateCommonName)))
                {
                    throw new ValidationException(ClusterManagementErrorCode.DupeCommonNameNotAllowedForClusterCert);
                }
            }
        }
        private static void ValidateClientIssuerCertStoreProperties(List <CertificateIssuerStore> clientIssuerStore)
        {
            SettingsValidator.ValidateIssuerCertStoreCommonProperties(clientIssuerStore);

            // Validate duplicate issuer CN
            bool hasDuplicate = clientIssuerStore.Any(current => clientIssuerStore.Any(other => current != other && string.Compare(current.IssuerCommonName, other.IssuerCommonName, true) == 0));

            if (hasDuplicate)
            {
                throw new ValidationException(ClusterManagementErrorCode.DupIssuerCertificateCN);
            }
        }
        private static void ValidateClusterServerIssuerCertStoreProperties(List <CertificateIssuerStore> issuerStore)
        {
            SettingsValidator.ValidateIssuerCertStoreCommonProperties(issuerStore);

            if (issuerStore.Count() > 2)
            {
                throw new ValidationException(ClusterManagementErrorCode.IssuerCertStoreCNMoreThan2);
            }

            // Validate duplicate issuer CN for server and cluster issuer certs
            if (issuerStore.Count() == 2)
            {
                if (string.Compare(issuerStore[0].IssuerCommonName, issuerStore[1].IssuerCommonName, true) == 0)
                {
                    throw new ValidationException(ClusterManagementErrorCode.DupIssuerCertificateCN);
                }
            }
        }
        internal static bool AreValidIssuerThumbprints(string issuerThumbprints)
        {
            string[] thumbprints = issuerThumbprints.Split(',');
            if (!thumbprints.All(p => SettingsValidator.IsValidThumbprint(p)))
            {
                return(false);
            }

            for (int i = 0; i < thumbprints.Length; i++)
            {
                for (int j = i + 1; j < thumbprints.Length; j++)
                {
                    if (string.Equals(thumbprints[i], thumbprints[j], StringComparison.OrdinalIgnoreCase))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        internal static void ValidateIssuerCertStore(X509 certInfo)
        {
            // Issuercertstore must not exist if corresponding cn does not exist for cert
            if (certInfo.ClusterCertificateCommonNames == null && certInfo.ClusterCertificateIssuerStores != null && certInfo.ClusterCertificateIssuerStores.Count() != 0)
            {
                throw new ValidationException(ClusterManagementErrorCode.IssuerCertStoreSpecifiedWithoutCommonNameCertificate);
            }

            if (certInfo.ServerCertificateCommonNames == null && certInfo.ServerCertificateIssuerStores != null && certInfo.ServerCertificateIssuerStores.Count() != 0)
            {
                throw new ValidationException(ClusterManagementErrorCode.IssuerCertStoreSpecifiedWithoutCommonNameCertificate);
            }

            if (certInfo.ClientCertificateCommonNames == null && certInfo.ClientCertificateIssuerStores != null && certInfo.ClientCertificateIssuerStores.Count() != 0)
            {
                throw new ValidationException(ClusterManagementErrorCode.IssuerCertStoreSpecifiedWithoutCommonNameCertificate);
            }

            // Issuer thumbprint pinning and issuer store cannot be specified together
            SettingsValidator.ValidateIssuerPinningAndIssuerStoresCannotExistTogether(certInfo);

            if (certInfo.ClusterCertificateIssuerStores != null && certInfo.ClusterCertificateIssuerStores.Count != 0)
            {
                SettingsValidator.ValidateClusterServerIssuerCertStoreProperties(certInfo.ClusterCertificateIssuerStores);
            }

            if (certInfo.ServerCertificateIssuerStores != null && certInfo.ServerCertificateIssuerStores.Count != 0)
            {
                SettingsValidator.ValidateClusterServerIssuerCertStoreProperties(certInfo.ServerCertificateIssuerStores);
            }

            if (certInfo.ClientCertificateIssuerStores != null && certInfo.ClientCertificateIssuerStores.Count != 0)
            {
                SettingsValidator.ValidateClientIssuerCertStoreProperties(certInfo.ClientCertificateIssuerStores);
            }
        }