internal static int GetChangedCnCount(ServerCertificateCommonNames currentCerts, ServerCertificateCommonNames targetCerts)
        {
            List <string> currentCns = CertificateClusterUpgradeFlow.GetCns(currentCerts).Keys.ToList();
            List <string> targetCns  = CertificateClusterUpgradeFlow.GetCns(targetCerts).Keys.ToList();

            return(CertificateClusterUpgradeFlow.GetChangedCertCount(currentCns, targetCns, isThumbprint: false));
        }
        private void GetClusterCertConfig(
            Security security,
            out CertificateDescription thumbprintClusterCert,
            out List <string> thumbprintClusterCertList,
            out ServerCertificateCommonNames commonNameClusterCert,
            out Dictionary <string, string> commonNameClusterCertList)
        {
            thumbprintClusterCert     = null;
            thumbprintClusterCertList = new List <string>();
            commonNameClusterCert     = null;
            commonNameClusterCertList = new Dictionary <string, string>();

            if (security != null && security.CertificateInformation != null)
            {
                if (security.CertificateInformation.ClusterCertificate != null)
                {
                    thumbprintClusterCert     = security.CertificateInformation.ClusterCertificate;
                    thumbprintClusterCertList = thumbprintClusterCert.ToThumbprintList();
                }

                if (security.CertificateInformation.ClusterCertificateCommonNames != null &&
                    security.CertificateInformation.ClusterCertificateCommonNames.Any())
                {
                    commonNameClusterCert     = security.CertificateInformation.ClusterCertificateCommonNames;
                    commonNameClusterCertList = commonNameClusterCert.CommonNames.ToDictionary(p => p.CertificateCommonName, p => p.CertificateIssuerThumbprint);
                }
            }
        }
        internal static List <string> GetAddedCns(
            ServerCertificateCommonNames originalList,
            ServerCertificateCommonNames newList)
        {
            List <string> currentCns = originalList == null || originalList.CommonNames == null ?
                                       new List <string>() : originalList.CommonNames.Select(p => p.CertificateCommonName).ToList();
            List <string> newCns = newList == null || newList.CommonNames == null ?
                                   new List <string>() : newList.CommonNames.Select(p => p.CertificateCommonName).ToList();

            return(newCns.Except(currentCns).ToList());
        }
示例#4
0
        public CertificateClusterUpgradeStep(
            List <string> thumbprintWhiteList,
            CertificateDescription thumbprintLoadList,
            CertificateDescription thumbprintFileStoreSvcList,
            Dictionary <string, string> commonNameWhiteList,
            ServerCertificateCommonNames commonNameLoadList,
            ServerCertificateCommonNames commonNameFileStoreSvcList)
        {
            this.ThumbprintWhiteList        = thumbprintWhiteList;
            this.ThumbprintLoadList         = thumbprintLoadList;
            this.ThumbprintFileStoreSvcList = thumbprintFileStoreSvcList;

            this.CommonNameWhiteList        = commonNameWhiteList;
            this.CommonNameLoadList         = commonNameLoadList;
            this.CommonNameFileStoreSvcList = commonNameFileStoreSvcList;
        }
 internal static void GetFileStoreSvcListForCertTypeChange(
     X509 currentCerts,
     X509 targetCerts,
     out CertificateDescription thumbprintFileStoreSvcCerts,
     out ServerCertificateCommonNames commonNameFileStoreSvcCerts)
 {
     if (targetCerts.ClusterCertificate == null)
     {
         thumbprintFileStoreSvcCerts = currentCerts.ClusterCertificate;
         commonNameFileStoreSvcCerts = targetCerts.ClusterCertificateCommonNames;
     }
     else
     {
         thumbprintFileStoreSvcCerts = targetCerts.ClusterCertificate;
         commonNameFileStoreSvcCerts = currentCerts.ClusterCertificateCommonNames;
     }
 }
示例#6
0
        internal static void ValidateCommonNamesAgainstThumbprints(X509 certInfo)
        {
            // for any cert except client cert, CN and thumbprint are not allowed to be configured together
            KeyValuePair <ServerCertificateCommonNames, CertificateDescription>[] pairs = new KeyValuePair <ServerCertificateCommonNames, CertificateDescription>[]
            {
                new KeyValuePair <ServerCertificateCommonNames, CertificateDescription>(certInfo.ClusterCertificateCommonNames, certInfo.ClusterCertificate),
                new KeyValuePair <ServerCertificateCommonNames, CertificateDescription>(certInfo.ServerCertificateCommonNames, certInfo.ServerCertificate),
                new KeyValuePair <ServerCertificateCommonNames, CertificateDescription>(certInfo.ReverseProxyCertificateCommonNames, certInfo.ReverseProxyCertificate),
            };

            foreach (var pair in pairs)
            {
                ServerCertificateCommonNames cns         = pair.Key;
                CertificateDescription       thumbprints = pair.Value;
                if (cns != null && thumbprints != null)
                {
                    throw new ValidationException(ClusterManagementErrorCode.InvalidCommonNameThumbprintPair);
                }
            }
        }
        internal static Dictionary <string, string> GetAddedCnsAndIssuers(
            ServerCertificateCommonNames originalList,
            ServerCertificateCommonNames newList)
        {
            Dictionary <string, string> currentCns = originalList == null || originalList.CommonNames == null ?
                                                     new Dictionary <string, string>() : originalList.CommonNames.ToDictionary(p => p.CertificateCommonName, p => p.CertificateIssuerThumbprint);
            Dictionary <string, string> newCns = newList == null || newList.CommonNames == null ?
                                                 new Dictionary <string, string>() : newList.CommonNames.ToDictionary(p => p.CertificateCommonName, p => p.CertificateIssuerThumbprint);

            Dictionary <string, string> result = new Dictionary <string, string>();

            foreach (var newCn in newCns)
            {
                string addedValue   = null;
                bool   isAddedFound = false;

                if (!currentCns.ContainsKey(newCn.Key))
                {
                    addedValue   = newCn.Value;
                    isAddedFound = true;
                }
                else if (currentCns[newCn.Key] != newCn.Value)
                {
                    string[]             currentThumbprints = currentCns[newCn.Key] == null ? new string[0] : currentCns[newCn.Key].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    string[]             newThumbprints     = newCn.Value == null ? new string[0] : newCn.Value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    IEnumerable <string> addedThumbprints   = newThumbprints.Except(currentThumbprints, StringComparer.OrdinalIgnoreCase);
                    if (addedThumbprints.Any())
                    {
                        addedValue   = string.Join(",", addedThumbprints);
                        isAddedFound = true;
                    }
                }

                if (isAddedFound)
                {
                    result[newCn.Key] = addedValue;
                }
            }

            return(result);
        }
        /// <summary>
        /// Overload this method to allow different seed node types.
        /// TODO: refactor to combine the two methods
        /// </summary>
        /// <param name="security"></param>
        /// <param name="existingClusterManifest"></param>
        /// <param name="nodeTypes"></param>
        /// <param name="currentFabricSettingsMetadata"></param>
        /// <param name="clusterManifestVersion"></param>
        /// <returns></returns>
        private ClusterManifestType UpdateClusterManifest(
            Security security,
            ClusterManifestType existingClusterManifest,
            IEnumerable <ClusterManifestTypeNodeType> nodeTypes,
            FabricSettingsMetadata currentFabricSettingsMetadata,
            string clusterManifestVersion,
            CertificateDescription thumbprintFileStoreCert,
            List <string> thumbprintWhiteList,
            ServerCertificateCommonNames commonNameFileStoreCert,
            Dictionary <string, string> commonNameWhiteList,
            List <NodeDescription> existingSeedNodes)
        {
            FabricSettingsGeneratorBase fabricSettingsGenerator = this.CreateFabricSettingsGenerator(
                this.TargetCsmConfig,
                this.TargetWrpConfig,
                this.ClusterManifestGeneratorSettings,
                currentFabricSettingsMetadata,
                existingClusterManifest);
            var fabricSettings = fabricSettingsGenerator.GenerateFabricSettings(
                security,
                thumbprintFileStoreCert,
                thumbprintWhiteList,
                commonNameFileStoreCert,
                commonNameWhiteList);

            var primaryNodesTypes = this.TargetCsmConfig.NodeTypes.Where(nodeType => nodeType.IsPrimary);

            var updatedCluterManifest = new ClusterManifestType
            {
                FabricSettings = fabricSettings,
                Infrastructure = this.OnGetInfrastructure(this.Topology, existingSeedNodes, nodeTypes),
                NodeTypes      = nodeTypes.ToArray(),
                Name           = StringConstants.ClusterManifestName,
                Version        = clusterManifestVersion,
                Description    = GeneratedCluterManifestDescription
            };

            this.SortClusterManifest(updatedCluterManifest);

            return(updatedCluterManifest);
        }
        internal static bool TryGetStepTwo(
            X509 currentCerts,
            X509 targetCerts,
            CertificateClusterUpgradeStep previousStep,
            out CertificateClusterUpgradeStep step)
        {
            // step 2:
            // white list: inherit from the previous step
            // load list: replace all current certs with target certs
            // fss list: change if necessary
            int changedThumbprintCount = CertificateClusterUpgradeFlow.GetChangedThumbprintCount(currentCerts.ClusterCertificate, targetCerts.ClusterCertificate);
            int changedCnCount         = CertificateClusterUpgradeFlow.GetChangedCnCount(currentCerts.ClusterCertificateCommonNames, targetCerts.ClusterCertificateCommonNames);

            List <string> removedThumbprints = CertificateClusterUpgradeFlow.GetAddedThumbprints(targetCerts.ClusterCertificate, currentCerts.ClusterCertificate);
            List <string> removedCns         = CertificateClusterUpgradeFlow.GetAddedCns(targetCerts.ClusterCertificateCommonNames, currentCerts.ClusterCertificateCommonNames);

            CertificateDescription       thumbprintFileStoreSvcCerts = null;
            ServerCertificateCommonNames commonNameFileStoreSvcCerts = null;
            bool shouldContinue = true;

            switch (changedThumbprintCount + changedCnCount)
            {
            case 1:
            {
                if (removedThumbprints.Any() || removedCns.Any())
                {
                    // cert removal
                    thumbprintFileStoreSvcCerts = currentCerts.ClusterCertificate;
                    commonNameFileStoreSvcCerts = currentCerts.ClusterCertificateCommonNames;
                }
                else
                {
                    // cert add
                    thumbprintFileStoreSvcCerts = targetCerts.ClusterCertificate;
                    commonNameFileStoreSvcCerts = targetCerts.ClusterCertificateCommonNames;
                    shouldContinue = false;
                }

                break;
            }

            case 2:
            {
                if (CertificateClusterUpgradeFlow.IsSwap(currentCerts.ClusterCertificate, targetCerts.ClusterCertificate))
                {
                    thumbprintFileStoreSvcCerts = new CertificateDescription()
                    {
                        Thumbprint          = currentCerts.ClusterCertificate.Thumbprint,
                        ThumbprintSecondary = currentCerts.ClusterCertificate.Thumbprint,
                        X509StoreName       = currentCerts.ClusterCertificate.X509StoreName,
                    };
                }
                else
                {
                    if (changedThumbprintCount == 2)
                    {
                        // thumbprint replace
                        thumbprintFileStoreSvcCerts = new CertificateDescription()
                        {
                            Thumbprint          = currentCerts.ClusterCertificate.Thumbprint,
                            ThumbprintSecondary = targetCerts.ClusterCertificate.Thumbprint,
                            X509StoreName       = currentCerts.ClusterCertificate.X509StoreName,
                        };
                    }
                    else if (changedCnCount == 2)
                    {
                        // cn replace
                        commonNameFileStoreSvcCerts = new ServerCertificateCommonNames()
                        {
                            CommonNames = new List <CertificateCommonNameBase>()
                            {
                                currentCerts.ClusterCertificateCommonNames.CommonNames[0],
                                targetCerts.ClusterCertificateCommonNames.CommonNames[0]
                            },
                            X509StoreName = currentCerts.ClusterCertificateCommonNames.X509StoreName
                        };
                    }
                    else
                    {
                        // 1 thumbprint <-> 1 cn
                        CertificateClusterUpgradeFlow.GetFileStoreSvcListForCertTypeChange(
                            currentCerts,
                            targetCerts,
                            out thumbprintFileStoreSvcCerts,
                            out commonNameFileStoreSvcCerts);
                    }
                }

                break;
            }

            case 3:
            case 4:
            {
                // 1 thumbprints <-> 2 cns, or 2 thumbprints <-> 1 cns, or 2 thumbprints <-> 2 cns
                CertificateClusterUpgradeFlow.GetFileStoreSvcListForCertTypeChange(
                    currentCerts,
                    targetCerts,
                    out thumbprintFileStoreSvcCerts,
                    out commonNameFileStoreSvcCerts);
                break;
            }

            default:
                throw new NotSupportedException(string.Format("It's not supported that {0} certificate thumbprints and {1} certificate common names have changed", changedThumbprintCount, changedCnCount));
            }

            step = new CertificateClusterUpgradeStep(
                thumbprintWhiteList: previousStep != null ? previousStep.ThumbprintWhiteList : CertificateClusterUpgradeFlow.GetThumbprints(currentCerts.ClusterCertificate),
                thumbprintLoadList: targetCerts.ClusterCertificate,
                thumbprintFileStoreSvcList: thumbprintFileStoreSvcCerts,
                commonNameWhiteList: previousStep != null ? previousStep.CommonNameWhiteList : CertificateClusterUpgradeFlow.GetCns(currentCerts.ClusterCertificateCommonNames),
                commonNameLoadList: targetCerts.ClusterCertificateCommonNames,
                commonNameFileStoreSvcList: commonNameFileStoreSvcCerts);

            return(shouldContinue);
        }
 internal static Dictionary <string, string> GetCns(ServerCertificateCommonNames certs)
 {
     return(certs == null || certs.CommonNames == null ?
            new Dictionary <string, string>() : certs.CommonNames.ToDictionary(p => p.CertificateCommonName, p => p.CertificateIssuerThumbprint));
 }