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