diff --git a/.github/workflows/keyfactor-starter-workflow.yml b/.github/workflows/keyfactor-starter-workflow.yml index a942322..81fd2d0 100644 --- a/.github/workflows/keyfactor-starter-workflow.yml +++ b/.github/workflows/keyfactor-starter-workflow.yml @@ -24,7 +24,7 @@ jobs: with: release_version: ${{ needs.call-create-github-release-workflow.outputs.release_version }} release_url: ${{ needs.call-create-github-release-workflow.outputs.release_url }} - release_dir: IISU/bin/Release/netcoreapp3.1 + release_dir: IISU/bin/Release/net6.0 secrets: token: ${{ secrets.PRIVATE_PACKAGE_ACCESS }} diff --git a/CHANGELOG.md b/CHANGELOG.md index faa1419..872e330 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ +2.2.0 +* Added Support for GMSA Account by using no value for ServerUsernanme and ServerPassword. KF Command version 10.2 or later is required to specify empty credentials. +* Added local PowerShell support, triggered when specifying 'localhost' as the client machine while using the IISU or WinCert Orchestrator. This change was tested using KF Command 10.3 +* Moved to .NET 6 + +2.1.1 +* Fixed the missing site name error when issuing a WinCert job when writing trace log settings to the log file. +* Several display names changed in the documented certificate store type definitions. There are no changes to the internal type or parameter names, so no migration is necessary for currently configured stores. + * Display name for IISU changed to "IIS Bound Certificate". + * Display name for WinCert changed to "Windows Certificate". + * Display names for several Store and Entry parameters changed to be more descriptive and UI friendly. +* Significant readme cleanup + 2.1.0 -* Fixed issue that was occuring during renewal when there were bindings outside of http and https like net.tcp +* Fixed issue that was occurring during renewal when there were bindings outside of http and https like net.tcp * Added PAM registration/initialization documentation in README.md * Resolved Null HostName error * Added WinCert Cert Store Type @@ -8,7 +21,7 @@ 2.0.0 * Add support for reenrollment jobs (On Device Key Generation) with the ability to specify a cryptographic provider. Specification of cryptographic provider allows HSM (Hardware Security Module) use. -* Local PAM Support added (requires Univesal Orchestrator Framework version 10.1) +* Local PAM Support added (requires Universal Orchestrator Framework version 10.1) * Certificate store type changed from IISBin to IISU. See readme for migration notes. diff --git a/IISU/ClientPSCertStoreReEnrollment.cs b/IISU/ClientPSCertStoreReEnrollment.cs index fca10b0..d971c55 100644 --- a/IISU/ClientPSCertStoreReEnrollment.cs +++ b/IISU/ClientPSCertStoreReEnrollment.cs @@ -21,6 +21,7 @@ using System.Collections.ObjectModel; using System.Management.Automation.Runspaces; using System.Management.Automation; +using System.Management.Automation.Remoting; using System.Net; using System.Security.Cryptography.X509Certificates; using System.Text; @@ -28,7 +29,8 @@ using Keyfactor.Orchestrators.Extensions.Interfaces; using System.Linq; using System.IO; - +using Microsoft.PowerShell; + namespace Keyfactor.Extensions.Orchestrator.WindowsCertStore { internal class ClientPSCertStoreReEnrollment @@ -52,37 +54,28 @@ public JobResult PerformReEnrollment(ReenrollmentJobConfiguration config, Submit var serverUserName = PAMUtilities.ResolvePAMField(_resolver, _logger, "Server UserName", config.ServerUsername); var serverPassword = PAMUtilities.ResolvePAMField(_resolver, _logger, "Server Password", config.ServerPassword); - - // Extract values necessary to create remote PS connection - JobProperties properties = JsonConvert.DeserializeObject(config.CertificateStoreDetails.Properties, - new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Populate }); - - WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri($"{properties?.WinRmProtocol}://{config.CertificateStoreDetails.ClientMachine}:{properties?.WinRmPort}/wsman")) - { - IncludePortInSPN = properties.SpnPortFlag - }; - var pw = new NetworkCredential(serverUserName, serverPassword).SecurePassword; - _logger.LogTrace($"Credentials: UserName:{serverUserName}"); - - connectionInfo.Credential = new PSCredential(serverUserName, pw); - _logger.LogTrace($"PSCredential Created {pw}"); - - // Establish new remote ps session - _logger.LogTrace("Creating remote PS Workspace"); - using var runSpace = RunspaceFactory.CreateRunspace(connectionInfo); - _logger.LogTrace("Workspace created"); + JobProperties jobProperties = JsonConvert.DeserializeObject(config.CertificateStoreDetails.Properties, + new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Populate }); + + string protocol = jobProperties.WinRmProtocol; + string port = jobProperties.WinRmPort; + bool IncludePortInSPN = jobProperties.SpnPortFlag; + string clientMachineName = config.CertificateStoreDetails.ClientMachine; + string storePath = config.CertificateStoreDetails.StorePath; + + _logger.LogTrace($"Establishing runspace on client machine: {clientMachineName}"); + using var runSpace = PsHelper.GetClientPsRunspace(protocol, clientMachineName, port, IncludePortInSPN, serverUserName, serverPassword); + + _logger.LogTrace("Runspace created"); runSpace.Open(); - _logger.LogTrace("Workspace opened"); + _logger.LogTrace("Runspace opened"); - // NEW - var ps = PowerShell.Create(); + PowerShell ps = PowerShell.Create(); ps.Runspace = runSpace; string CSR = string.Empty; - string storePath = config.CertificateStoreDetails.StorePath; - var subjectText = config.JobProperties["subjectText"]; var providerName = config.JobProperties["ProviderName"]; var keyType = config.JobProperties["keyType"]; @@ -100,23 +93,23 @@ public JobResult PerformReEnrollment(ReenrollmentJobConfiguration config, Submit ps.AddScript("if (Test-Path $csrFilename) { Remove-Item $csrFilename }"); - ps.AddScript($"Set-Content $infFilename [NewRequest]"); - ps.AddScript($"Add-Content $infFilename 'Subject = \"{subjectText}\"'"); - ps.AddScript($"Add-Content $infFilename 'ProviderName = \"{providerName}\"'"); - ps.AddScript($"Add-Content $infFilename 'MachineKeySet = True'"); - ps.AddScript($"Add-Content $infFilename 'HashAlgorithm = SHA256'"); - ps.AddScript($"Add-Content $infFilename 'KeyAlgorithm = {keyType}'"); - ps.AddScript($"Add-Content $infFilename 'KeyLength={keySize}'"); - ps.AddScript($"Add-Content $infFilename 'KeySpec = 0'"); + ps.AddScript($"Set-Content $infFilename -Value [NewRequest]"); + ps.AddScript($"Add-Content $infFilename -Value 'Subject = \"{subjectText}\"'"); + ps.AddScript($"Add-Content $infFilename -Value 'ProviderName = \"{providerName}\"'"); + ps.AddScript($"Add-Content $infFilename -Value 'MachineKeySet = True'"); + ps.AddScript($"Add-Content $infFilename -Value 'HashAlgorithm = SHA256'"); + ps.AddScript($"Add-Content $infFilename -Value 'KeyAlgorithm = {keyType}'"); + ps.AddScript($"Add-Content $infFilename -Value 'KeyLength={keySize}'"); + ps.AddScript($"Add-Content $infFilename -Value 'KeySpec = 0'"); if (SAN != null) { - ps.AddScript($"Add-Content $infFilename '[Extensions]'"); - ps.AddScript(@"Add-Content $infFilename '2.5.29.17 = ""{text}""'"); + ps.AddScript($"Add-Content $infFilename -Value '[Extensions]'"); + ps.AddScript(@"Add-Content $infFilename -Value '2.5.29.17 = ""{text}""'"); foreach (string s in SAN.ToString().Split("&")) { - ps.AddScript($"Add-Content $infFilename '_continue_ = \"{s + "&"}\"'"); + ps.AddScript($"Add-Content $infFilename -Value '_continue_ = \"{s + "&"}\"'"); } } @@ -153,7 +146,7 @@ public JobResult PerformReEnrollment(ReenrollmentJobConfiguration config, Submit try { - ps.AddScript($"$CSR = Get-Content $csrFilename"); + ps.AddScript($"$CSR = Get-Content $csrFilename -Raw"); _logger.LogTrace("Attempting to get the contents of the CSR file."); results = ps.Invoke(); _logger.LogTrace("Finished getting the CSR Contents."); @@ -177,14 +170,14 @@ public JobResult PerformReEnrollment(ReenrollmentJobConfiguration config, Submit results = ps.Invoke(); if (hasError) runSpace.Close(); - } - - // Get the byte array - var CSRContent = ps.Runspace.SessionStateProxy.GetVariable("CSR").ToString(); + } + + // Get the byte array + var RawContent = runSpace.SessionStateProxy.GetVariable("CSR"); // Sign CSR in Keyfactor _logger.LogTrace("Get the signed CSR from KF."); - X509Certificate2 myCert = submitReenrollment.Invoke(CSRContent); + X509Certificate2 myCert = submitReenrollment.Invoke(RawContent.ToString()); if (myCert != null) { @@ -257,6 +250,19 @@ public JobResult PerformReEnrollment(ReenrollmentJobConfiguration config, Submit }; } + } + catch (PSRemotingTransportException psEx) + { + var failureMessage = $"ReEnrollment job failed for Site '{config.CertificateStoreDetails.StorePath}' on server '{config.CertificateStoreDetails.ClientMachine}' with a PowerShell Transport Exception: {psEx.Message}"; + _logger.LogError(failureMessage + LogHandler.FlattenException(psEx)); + + return new JobResult + { + Result = OrchestratorJobStatusJobResult.Failure, + JobHistoryId = config.JobHistoryId, + FailureMessage = failureMessage + }; + } catch (Exception ex) { diff --git a/IISU/ClientPSIIManager.cs b/IISU/ClientPSIIManager.cs index 4b03965..600f085 100644 --- a/IISU/ClientPSIIManager.cs +++ b/IISU/ClientPSIIManager.cs @@ -101,7 +101,7 @@ public ClientPSIIManager(ReenrollmentJobConfiguration config, string serverUsern bool includePortInSPN = jobProperties.SpnPortFlag; _logger.LogTrace($"Establishing runspace on client machine: {ClientMachineName}"); - _runSpace = PSHelper.GetClientPSRunspace(winRmProtocol, ClientMachineName, winRmPort, includePortInSPN, serverUsername, serverPassword); + _runSpace = PsHelper.GetClientPsRunspace(winRmProtocol, ClientMachineName, winRmPort, includePortInSPN, serverUsername, serverPassword); } catch (Exception e) { @@ -144,7 +144,7 @@ public ClientPSIIManager(ManagementJobConfiguration config, string serverUsernam bool includePortInSPN = jobProperties.SpnPortFlag; _logger.LogTrace($"Establishing runspace on client machine: {ClientMachineName}"); - _runSpace = PSHelper.GetClientPSRunspace(winRmProtocol, ClientMachineName, winRmPort, includePortInSPN, serverUsername, serverPassword); + _runSpace = PsHelper.GetClientPsRunspace(winRmProtocol, ClientMachineName, winRmPort, includePortInSPN, serverUsername, serverPassword); } catch (Exception e) { diff --git a/IISU/ImplementedStoreTypes/Win/Inventory.cs b/IISU/ImplementedStoreTypes/Win/Inventory.cs index 944ceb9..877aace 100644 --- a/IISU/ImplementedStoreTypes/Win/Inventory.cs +++ b/IISU/ImplementedStoreTypes/Win/Inventory.cs @@ -71,7 +71,7 @@ private JobResult PerformInventory(InventoryJobConfiguration config, SubmitInven if (storePath != null) { _logger.LogTrace($"Establishing runspace on client machine: {clientMachineName}"); - using var myRunspace = PSHelper.GetClientPSRunspace(protocol, clientMachineName, port, IncludePortInSPN, serverUserName, serverPassword); + using var myRunspace = PsHelper.GetClientPsRunspace(protocol, clientMachineName, port, IncludePortInSPN, serverUserName, serverPassword); myRunspace.Open(); _logger.LogTrace("Runspace is now open"); diff --git a/IISU/ImplementedStoreTypes/Win/Management.cs b/IISU/ImplementedStoreTypes/Win/Management.cs index ebba907..bb32272 100644 --- a/IISU/ImplementedStoreTypes/Win/Management.cs +++ b/IISU/ImplementedStoreTypes/Win/Management.cs @@ -66,7 +66,7 @@ public JobResult ProcessJob(ManagementJobConfiguration config) long JobHistoryID = config.JobHistoryId; _logger.LogTrace($"Establishing runspace on client machine: {clientMachineName}"); - myRunspace = PSHelper.GetClientPSRunspace(protocol, clientMachineName, port, IncludePortInSPN, serverUserName, serverPassword); + myRunspace = PsHelper.GetClientPsRunspace(protocol, clientMachineName, port, IncludePortInSPN, serverUserName, serverPassword); var complete = new JobResult { diff --git a/IISU/ImplementedStoreTypes/WinIIS/Inventory.cs b/IISU/ImplementedStoreTypes/WinIIS/Inventory.cs index 1b3613b..86fffe3 100644 --- a/IISU/ImplementedStoreTypes/WinIIS/Inventory.cs +++ b/IISU/ImplementedStoreTypes/WinIIS/Inventory.cs @@ -12,18 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Management.Automation; -using System.Management.Automation.Runspaces; -using System.Net; using Keyfactor.Logging; using Keyfactor.Orchestrators.Common.Enums; using Keyfactor.Orchestrators.Extensions; using Keyfactor.Orchestrators.Extensions.Interfaces; using Microsoft.Extensions.Logging; using Newtonsoft.Json; +using System; +using System.Collections.Generic; namespace Keyfactor.Extensions.Orchestrator.WindowsCertStore.IISU { @@ -43,6 +39,7 @@ public JobResult ProcessJob(InventoryJobConfiguration jobConfiguration, SubmitIn _logger = LogHandler.GetClassLogger(); _logger.MethodEntry(); + return PerformInventory(jobConfiguration, submitInventoryUpdate); } @@ -70,14 +67,14 @@ private JobResult PerformInventory(InventoryJobConfiguration config, SubmitInven if (storePath != null) { _logger.LogTrace($"Establishing runspace on client machine: {clientMachineName}"); - using var myRunspace = PSHelper.GetClientPSRunspace(protocol, clientMachineName, port, IncludePortInSPN, serverUserName, serverPassword); + using var myRunspace = PsHelper.GetClientPsRunspace(protocol, clientMachineName, port, IncludePortInSPN, serverUserName, serverPassword); myRunspace.Open(); _logger.LogTrace("Runspace is now open"); _logger.LogTrace($"Attempting to read bound IIS certificates from cert store: {storePath}"); WinIISInventory IISInventory = new WinIISInventory(_logger); inventoryItems = IISInventory.GetInventoryItems(myRunspace, storePath); - + _logger.LogTrace($"A total of {inventoryItems.Count} were found"); _logger.LogTrace("Closing runspace..."); myRunspace.Close(); diff --git a/IISU/ImplementedStoreTypes/WinIIS/Management.cs b/IISU/ImplementedStoreTypes/WinIIS/Management.cs index 89afcbd..e9bd38d 100644 --- a/IISU/ImplementedStoreTypes/WinIIS/Management.cs +++ b/IISU/ImplementedStoreTypes/WinIIS/Management.cs @@ -61,7 +61,7 @@ public JobResult ProcessJob(ManagementJobConfiguration config) long JobHistoryID = config.JobHistoryId; _logger.LogTrace($"Establishing runspace on client machine: {clientMachineName}"); - myRunspace = PSHelper.GetClientPSRunspace(protocol, clientMachineName, port, IncludePortInSPN, serverUserName, serverPassword); + myRunspace = PsHelper.GetClientPsRunspace(protocol, clientMachineName, port, IncludePortInSPN, serverUserName, serverPassword); var complete = new JobResult { diff --git a/IISU/ImplementedStoreTypes/WinIIS/WinIISInventory.cs b/IISU/ImplementedStoreTypes/WinIIS/WinIISInventory.cs index 5ac831f..457cdcf 100644 --- a/IISU/ImplementedStoreTypes/WinIIS/WinIISInventory.cs +++ b/IISU/ImplementedStoreTypes/WinIIS/WinIISInventory.cs @@ -15,6 +15,7 @@ using Keyfactor.Orchestrators.Common.Enums; using Keyfactor.Orchestrators.Extensions; using Microsoft.Extensions.Logging; +using Microsoft.PowerShell; using System; using System.Collections.Generic; using System.Linq; @@ -38,21 +39,30 @@ public List GetInventoryItems(Runspace runSpace, string st // Contains the inventory items to be sent back to KF List myBoundCerts = new List(); - using (var ps = PowerShell.Create()) + using (PowerShell ps2 = PowerShell.Create()) { - ps.Runspace = runSpace; + ps2.Runspace = runSpace; - ps.AddCommand("Import-Module") - .AddParameter("Name", "WebAdministration") - .AddStatement(); + if (runSpace.RunspaceIsRemote) + { + ps2.AddCommand("Import-Module") + .AddParameter("Name", "WebAdministration") + .AddStatement(); + } + else + { + ps2.AddScript("Set-ExecutionPolicy RemoteSigned"); + ps2.AddScript("Import-Module WebAdministration"); + //var result = ps.Invoke(); + } var searchScript = "Foreach($Site in get-website) { Foreach ($Bind in $Site.bindings.collection) {[pscustomobject]@{name=$Site.name;Protocol=$Bind.Protocol;Bindings=$Bind.BindingInformation;thumbprint=$Bind.certificateHash;sniFlg=$Bind.sslFlags}}}"; - ps.AddScript(searchScript).AddStatement(); - var iisBindings = ps.Invoke(); // Responsible for getting all bound certificates for each website + ps2.AddScript(searchScript); + var iisBindings = ps2.Invoke(); // Responsible for getting all bound certificates for each website - if (ps.HadErrors) + if (ps2.HadErrors) { - var psError = ps.Streams.Error.ReadAll().Aggregate(String.Empty, (current, error) => current + error.ErrorDetails.Message); + var psError = ps2.Streams.Error.ReadAll().Aggregate(String.Empty, (current, error) => current + error.ErrorDetails.Message); } if (iisBindings.Count == 0) diff --git a/IISU/JobConfigurationParser.cs b/IISU/JobConfigurationParser.cs index bd7889d..5cb0448 100644 --- a/IISU/JobConfigurationParser.cs +++ b/IISU/JobConfigurationParser.cs @@ -47,14 +47,15 @@ public static string ParseManagementJobConfiguration(ManagementJobConfiguration bool isEmpty = (config.JobProperties.Count == 0); // Check if the dictionary is empty or not if (!isEmpty) { - managementParser.CertificateStoreDetailProperties.SiteName = config.JobProperties["SiteName"].ToString(); - managementParser.CertificateStoreDetailProperties.Port = config.JobProperties["Port"].ToString(); - managementParser.CertificateStoreDetailProperties.HostName = config.JobProperties["HostName"]?.ToString(); - managementParser.CertificateStoreDetailProperties.Protocol = config.JobProperties["Protocol"].ToString(); - managementParser.CertificateStoreDetailProperties.SniFlag = config.JobProperties["SniFlag"].ToString()?[..1]; - managementParser.CertificateStoreDetailProperties.IPAddress = config.JobProperties["IPAddress"].ToString(); - managementParser.CertificateStoreDetailProperties.ProviderName = config.JobProperties["ProviderName"]?.ToString(); - managementParser.CertificateStoreDetailProperties.SAN = config.JobProperties["SAN"]?.ToString(); + object value = ""; + if (config.JobProperties.TryGetValue("SiteName", out value)) managementParser.CertificateStoreDetailProperties.SiteName = config.JobProperties["SiteName"].ToString(); + if (config.JobProperties.TryGetValue("Port", out value)) managementParser.CertificateStoreDetailProperties.Port = config.JobProperties["Port"].ToString(); + if (config.JobProperties.TryGetValue("HostName", out value)) managementParser.CertificateStoreDetailProperties.HostName = config.JobProperties["HostName"]?.ToString(); + if (config.JobProperties.TryGetValue("Protocol", out value)) managementParser.CertificateStoreDetailProperties.Protocol = config.JobProperties["Protocol"].ToString(); + if (config.JobProperties.TryGetValue("SniFlag", out value)) managementParser.CertificateStoreDetailProperties.SniFlag = config.JobProperties["SniFlag"].ToString()?[..1]; + if (config.JobProperties.TryGetValue("IPAddress", out value)) managementParser.CertificateStoreDetailProperties.IPAddress = config.JobProperties["IPAddress"].ToString(); + if (config.JobProperties.TryGetValue("ProviderName", out value)) managementParser.CertificateStoreDetailProperties.ProviderName = config.JobProperties["ProviderName"]?.ToString(); + if (config.JobProperties.TryGetValue("SAN", out value)) managementParser.CertificateStoreDetailProperties.SAN = config.JobProperties["SAN"]?.ToString(); } // Management Base diff --git a/IISU/PSHelper.cs b/IISU/PSHelper.cs index 1d7b5af..7a8464a 100644 --- a/IISU/PSHelper.cs +++ b/IISU/PSHelper.cs @@ -1,42 +1,61 @@ -// Copyright 2022 Keyfactor -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; -using System.Management.Automation; -using System.Management.Automation.Runspaces; -using System.Net; -using Keyfactor.Logging; -using Microsoft.Extensions.Logging; - -namespace Keyfactor.Extensions.Orchestrator.WindowsCertStore -{ - public class PSHelper - { - private static ILogger _logger; - - public static Runspace GetClientPSRunspace(string winRmProtocol, string clientMachineName, string WinRmPort, bool includePortInSPN, string serverUserName, string serverPassword) - { - _logger = LogHandler.GetClassLogger(); - _logger.MethodEntry(); - - var connInfo = new WSManConnectionInfo(new Uri($"{winRmProtocol}://{clientMachineName}:{WinRmPort}/wsman")); - connInfo.IncludePortInSPN = includePortInSPN; - - var pw = new NetworkCredential(serverUserName, serverPassword).SecurePassword; - connInfo.Credential = new PSCredential(serverUserName, pw); - - return RunspaceFactory.CreateRunspace(connInfo); - } - } -} +// Copyright 2022 Keyfactor +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Keyfactor.Logging; +using Microsoft.Extensions.Logging; +using System; +using System.Management.Automation; +using System.Management.Automation.Runspaces; +using System.Net; + +namespace Keyfactor.Extensions.Orchestrator.WindowsCertStore +{ + public class PsHelper + { + private static ILogger _logger; + + public static Runspace GetClientPsRunspace(string winRmProtocol, string clientMachineName, string winRmPort, bool includePortInSpn, string serverUserName, string serverPassword) + { + _logger = LogHandler.GetClassLogger(); + _logger.MethodEntry(); + + if (clientMachineName.ToLower() != "localhost") + + { + var connInfo = new WSManConnectionInfo(new Uri($"{winRmProtocol}://{clientMachineName}:{winRmPort}/wsman")); + connInfo.IncludePortInSPN = includePortInSpn; + + _logger.LogTrace($"Creating remote session at: {connInfo.ConnectionUri}"); + + if (!string.IsNullOrEmpty(serverUserName)) + { + _logger.LogTrace($"Credentials Specified"); + var pw = new NetworkCredential(serverUserName, serverPassword).SecurePassword; + connInfo.Credential = new PSCredential(serverUserName, pw); + } + return RunspaceFactory.CreateRunspace(connInfo); + } + + // Create an out of process PowerShell runspace and explictly use version 5.1 + // This is needed when running as a service, which is how the orchestrator extension operates + // Interestingly this is not needd when running as a console application + // TODO: Consider refactoring this so that we properly dispose of these objects instead of waiting on the GC + + PowerShellProcessInstance instance = new PowerShellProcessInstance(new Version(5, 1), null, null, false); + Runspace rs = RunspaceFactory.CreateOutOfProcessRunspace(new TypeTable(Array.Empty()), instance); + + return rs; + } + } +} diff --git a/IISU/WindowsCertStore.csproj b/IISU/WindowsCertStore.csproj index 5af1292..0a417fd 100644 --- a/IISU/WindowsCertStore.csproj +++ b/IISU/WindowsCertStore.csproj @@ -1,9 +1,10 @@  - netcoreapp3.1 Keyfactor.Extensions.Orchestrator.WindowsCertStore true + net6.0 + AnyCPU @@ -28,8 +29,8 @@ - - + + diff --git a/README.md b/README.md index 5e5e194..637e9b5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# IIS Orchestrator +# WinCertStore Orchestrator -The IIS Orchestrator treats the certificates bound (actively in use) on a Microsoft Internet Information Server (IIS) as a Keyfactor certificate store. Inventory and Management functions are supported. The orchestrator replaces the IIS orchestrator that ships with Keyfactor Command (which did not support binding.) +The Windows Certificate Store Orchestrator Extension implements two certificate store types. 1) “WinCert” which manages certificates in a Windows local machine store, and 2) “IISU” which manages certificates and their bindings in a Windows local machine store that are bound to Internet Information Server (IIS) websites. These extensions replace the now deprecated “IIS” cert store type that ships with Keyfactor Command. The “IISU” extension also replaces the “IISBin” certificate store type from prior versions of this repository. This orchestrator extension is in the process of being renamed from “IIS Orchestrator” as it now supports certificates that are not in use by IIS. #### Integration status: Production - Ready for use in production environments. @@ -45,7 +45,7 @@ The secrets that this orchestrator extension supports for use with a PAM Provide |Name|Description| |----|-----------| -|Server UserName|The user id that will be used to authenticate into the server hosting the store| +|Server Username|The user id that will be used to authenticate into the server hosting the store| |Server Password|The password that will be used to authenticate into the server hosting the store| @@ -53,6 +53,11 @@ It is not necessary to use a PAM Provider for all of the secrets available above If a PAM Provider will be used for one of the fields above, start by referencing the [Keyfactor Integration Catalog](https://keyfactor.github.io/integrations-catalog/content/pam). The GitHub repo for the PAM Provider to be used contains important information such as the format of the `json` needed. What follows is an example but does not reflect the `json` values for all PAM Providers as they have different "instance" and "initialization" parameter names and values. +
General PAM Provider Configuration +

+ + + ### Example PAM Provider Setup To use a PAM Provider to resolve a field, in this example the __Server Password__ will be resolved by the `Hashicorp-Vault` provider, first install the PAM Provider extension from the [Keyfactor Integration Catalog](https://keyfactor.github.io/integrations-catalog/content/pam) on the Universal Orchestrator. @@ -79,7 +84,8 @@ To have the __Server Password__ field resolved by the `Hashicorp-Vault` provider ~~~ This text would be entered in as the value for the __Server Password__, instead of entering in the actual password. The Orchestrator will attempt to use the PAM Provider to retrieve the __Server Password__. If PAM should not be used, just directly enter in the value for the field. - +

+
@@ -98,7 +104,7 @@ The returned list will contain the actual certificate store name to be used when By default, most certificates are stored in the “Personal” (My) and “Web Hosting” (WebHosting) stores. -This agent implements four job types: Inventory, Management Add/Remove, and ReEnrollment. +This extension implements four job types: Inventory, Management Add/Remove, and ReEnrollment. WinRM is used to remotely manage the certificate stores and IIS bindings. WinRM must be properly configured to allow the orchestrator on the server to manage the certificates. Setting up WinRM is not in the scope of this document. @@ -108,85 +114,82 @@ In version 2.0 of the IIS Orchestrator, the certificate store type has been rena 1. Delete existing IIS stores. Delete the IISBin store type. Create the new IISU store type. Recreate the IIS stores using the new IISU store type. 1. Convert existing IISBin certificate stores to IISU certificate stores. There is not currently a way to do this via the Keyfactor API, so direct updates to the underlying Keyfactor SQL database is required. A SQL script (IIS-Conversion.sql) is available in the repository to do this. Hosted customers, which do not have access to the underlying database, will need to work Keyfactor support to run the conversion. On-premises customers can run the script themselves, but are strongly encouraged to ensure that a SQL backup is taken prior running the script (and also be confident that they have a tested database restoration process.) -**Note: There is an additional certificate store type of “IIS” that ships with the Keyfactor platform. Migration of certificate stores from the “IIS” type to either the “IISBin” or “IISU” types is not currently supported.** +**Note: There is an additional (and deprecated) certificate store type of “IIS” that ships with the Keyfactor platform. Migration of certificate stores from the “IIS” type to either the “IISBin” or “IISU” types is not currently supported.** + +**Note: If Looking to use GMSA Accounts to run the Service Kefyactor Command 10.2 or greater is required for No Value checkbox to work** ## Creating New Certificate Store Types -Currently this orchestrator handles two extensions: IISU for IIS servers with bound certificates and WinCert for general Windows Certificates. Below describes how each of these certificate store types are created and configured. +Currently this orchestrator handles two extensions: IISU for IIS servers with bound certificates and WinCert for general Windows Certificates. +Below describes how each of these certificate store types are created and configured.
IISU Extension -**In Keyfactor Command create a new Certificate Store Type similar to the one below:** +**In Keyfactor Command create a new Certificate Store Type as specified below:** **Basic Settings:** -CONFIG ELEMENT | DESCRIPTION -------------------|------------------ -Name |A descriptive name for the extension. Example: IISU -Short Name |The short name that identifies the registered functionality of the orchestrator. Must be IISU. -Custom Capability|Store type name orchestrator will register with. Check the box and enter IISU. -Job Types |Inventory (Checked), check the additional checkboxes: Add, Remove, and Reenrollment. -General Settings|Needs Server - Checked
Blueprint Allowed - Unchecked
Uses PowerShell - Unchecked -Requires Store Password |Determines if a store password is required when configuring an individual store. This must be unchecked. -Supports Entry Password |Determined if an individual entry within a store can have a password. This must be unchecked. +CONFIG ELEMENT | VALUE | DESCRIPTION +--|--|-- +Name | IIS Bound Certificate | Display name for the store type (may be customized) +Short Name| IISU | Short display name for the store type +Custom Capability | IISU | Store type name orchestrator will register with. Check the box to allow entry of value +Supported Job Types | Inventory, Add, Remove, Reenrollment | Job types the extension supports +Needs Server | Checked | Determines if a target server name is required when creating store +Blueprint Allowed | Unchecked | Determines if store type may be included in an Orchestrator blueprint +Uses PowerShell | Unchecked | Determines if underlying implementation is PowerShell +Requires Store Password | Unchecked | Determines if a store password is required when configuring an individual store. +Supports Entry Password | Unchecked | Determines if an individual entry within a store can have a password. ![](images/IISUCertStoreBasic.png) **Advanced Settings:** -CONFIG ELEMENT | DESCRIPTION -------------------|------------------ -Store Path Type |Determines what restrictions are applied to the store path field when configuring a new store. Select Multiple Choice. -Store Path Value|This must be a comma separated list of options to select from for the Store Path. This, combined with the hostname, will determine the location used for the certificate store management and inventory. Must be My, WebHosting -Supports Custom Alias |Determines if an individual entry within a store can have a custom Alias. This must be Forbidden. -Private Keys |This determines if Keyfactor can send the private key associated with a certificate to the store. This is required since IIS will need the private key material to establish TLS connections. -PFX Password Style |This determines how the platform generate passwords to protect a PFX enrollment job that is delivered to the store. This can be either Default (system generated) or Custom (user determined). +CONFIG ELEMENT | VALUE | DESCRIPTION +--|--|-- +Store Path Type | Multiple Choice | Determines what restrictions are applied to the store path field when configuring a new store. +Store Path Value | My,WebHosting | Comma separated list of options configure multiple choice. This, combined with the hostname, will determine the location used for the certificate store management and inventory. +Supports Custom Alias | Forbidden | Determines if an individual entry within a store can have a custom Alias. +Private Keys | Required | This determines if Keyfactor can send the private key associated with a certificate to the store. Required because IIS certificates without private keys would be useless. +PFX Password Style | Default or Custom | "Default" - PFX password is randomly generated, "Custom" - PFX password may be specified when the enrollment job is created (Requires the *Allow Custom Password* application setting to be enabled.) -![](images/screen1-a.gif) +![](images/IISUCertStoreAdv.png) **Custom Fields:** -- **SPN With Port** – Defaults to false but some customers need for remote PowerShell Access +Custom fields operate at the certificate store level and are used to control how the orchestrator connects to the remote +target server containing the certificate store to be managed -Parameter Name|Display Name|Parameter Type|Default Value|Required|Description +Name|Display Name|Type|Default Value / Options|Required|Description ---|---|---|---|---|--- -spnwithport|SPN With Port?|Boolean|false|No|An SPN is the name by which a client uniquely identifies an instance of a service -WinRm Protocol|WinRm Protocol|Multiple Choice|http|Yes|Protocol that WinRM Runs on -WinRm Port|WinRm Port|String|5985|Yes|Port that WinRM Runs on -ServerUsername|Server Username|Secret||No|The username to log into the Server -ServerPassword|Server Password|Secret||No|The password that matches the username to log into the Server -ServerUseSsl|Use SSL|Bool|True|Yes|Determine whether the server uses SSL or not +WinRm Protocol|WinRm Protocol|Multiple Choice| https,http |Yes|Protocol that target server WinRM listener is using +WinRm Port|WinRm Port|String|5986|Yes| Port that target server WinRM listener is using. Typically 5985 for HTTP and 5986 for HTTPS +spnwithport|SPN With Port|Bool|false|No|Internally set the -IncludePortInSPN option when creating the remote PowerShell connection. Needed for some Kerberos configurations. +ServerUsername|Server Username|Secret||No|The username to log into the target server (This field is automatically created). Check the No Value Checkbox when using GMSA Accounts. +ServerPassword|Server Password|Secret||No|The password that matches the username to log into the target server (This field is automatically created). Check the No Value Checkbox when using GMSA Accounts. +ServerUseSsl|Use SSL|Bool|true|Yes|Determine whether the server uses SSL or not (This field is automatically created) + +*Note that some of the Names in the first column above have spaces and some do not, it is important to configure the Name field exactly as above.* + ![](images/IISUCustomFields.png) **Entry Parameters:** -This section must be configured with binding fields. The parameters will be populated with the appropriate data when creating a new certificate store.
- -- **Site Name** – Required (Adding an entry, Removing an entry, Reenrolling an entry). The site name for the web site being bound to – i.e. "Default Web Site" -- **IP Address** – Required (Adding an entry, Removing an entry, Reenrolling an entry). The IP address for the web site being bound to. Default is "\*" for all IP Addresses. -- **Port** – Required (Adding an entry, Removing an entry, Reenrolling an entry). The port for the web site being bound to. Default is "443". -- **Host Name** – Optional. The host name for the web site being bound to. -- **Protocol** - Required (Adding an entry, Removing an entry, Reenrolling an entry) - - https - - http -- **Sni Flag** – Optional. Set the SNI flag associated with the binding being created. Default is "0". Acceptable values are: - - 0 - No SNI - - 1 - SNI Enabled - - 2 - Non SNI Binding - - 3 - SNI Binding -- **Provider Name** - Optional. Name of the Windows cryptographic provider to use when generating and storing the private key for the certificate being enrolled by a reenrollment job. If not specified, defaults to 'Microsoft Strong Cryptographic Provider'. This value would typically be changed when leveraging a Hardware Security Module (HSM). The specified cryptographic provider must be available on the target server being managed. The list of installed cryptographic providers can be obtained by running 'certutil -csplist' in a command shell on the target Server. -- **SAN** - Optional. Specifies Subject Alternative Name (SAN) to be used when performing reenrollment jobs. Certificate templates generally require a SAN that matches the subject of the certificate (per RFC 2818). Format is a list of = entries separated by ampersands. Examples: 'dns=www.mysite.com' for a single SAN or 'dns=www.mysite.com&dns=www.mysite2.com' for multiple SANs. - -Parameter Name|Parameter Type|Default Value|Required When ----|---|---|--- -Port|String|443|Adding Entry, Removing Entry, Reenrolling and Entry -IPAddress|String|*|Adding Entry, Reenrolling an Entry -HostName |String|| -SiteName |String|Default Web Site|Adding Entry, Removing Entry, Reenrolling an Entry -SniFlag |String|0 - No SNI| -Protocol |Multiple Choice|https|Adding Entry, Removing Entry, Reenrolling an Entry -ProviderName |String|| -SAN |String||Reenrolling an Entry (if the CA follows RFC 2818 specifications) +Entry parameters are inventoried and maintained for each entry within a certificate store. +They are typically used to support binding of a certificate to a resource. + +Name|Display Name| Type|Default Value|Required When|Description +---|---|---|---|---|--- +SiteName | IIS Site Name|String|Default Web Site|Adding, Removing, Reenrolling | IIS web site to bind certificate to +IPAddress | IP Address | String | * | Adding, Removing, Reenrolling | IP address to bind certificate to (use '*' for all IP addresses) +Port | Port | String | 443 || Adding, Removing, Reenrolling|IP port for bind certificate to +HostName | Host Name | String |||| Host name (host header) to bind certificate to, leave blank for all host names +SniFlag | SNI Support | Multiple Choice | 0 - No SNI||Type of SNI for binding
(Multiple choice configuration should be entered as "0 - No SNI,1 - SNI Enabled,2 - Non SNI Binding,3 - SNI Binding") +Protocol | Protocol | Multiple Choice | https| Adding, Removing, Reenrolling|Protocol to bind to (always "https").
(Multiple choice configuration should be "https") +ProviderName | Crypto Provider Name | String ||| Name of the Windows cryptographic provider to use during reenrollment jobs when generating and storing the private keys. If not specified, defaults to 'Microsoft Strong Cryptographic Provider'. This value would typically be specified when leveraging a Hardware Security Module (HSM). The specified cryptographic provider must be available on the target server being managed. The list of installed cryptographic providers can be obtained by running 'certutil -csplist' on the target Server. +SAN | SAN | String || Reenrolling | Specifies Subject Alternative Name (SAN) to be used when performing reenrollment jobs. Certificate templates generally require a SAN that matches the subject of the certificate (per RFC 2818). Format is a list of = entries separated by ampersands. Examples: 'dns=www.mysite.com' for a single SAN or 'dns=www.mysite.com&dns=www.mysite2.com' for multiple SANs. Can be made optional if RFC 2818 is disabled on the CA. + +None of the above entry parameters have the "Depends On" field set. ![](images/IISUEntryParams.png) @@ -201,53 +204,60 @@ Click Save to save the Certificate Store Type. **Basic Settings:** -CONFIG ELEMENT | DESCRIPTION -------------------|------------------ -Name |A descriptive name for the extension. Example: WinCert -Short Name |The short name that identifies the registered functionality of the orchestrator. Must be WinCert. -Custom Capability|Store type name orchestrator will register with. Check the box and enter WinCert. -Job Types |Inventory (Checked), check the additional checkboxes: Add, Remove, and Reenrollment. -General Settings|Needs Server - Checked
Blueprint Allowed - Unchecked
Uses PowerShell - Unchecked -Requires Store Password |Determines if a store password is required when configuring an individual store. This must be unchecked. -Supports Entry Password |Determined if an individual entry within a store can have a password. This must be unchecked. +CONFIG ELEMENT | VALUE | DESCRIPTION +--|--|-- +Name | Windows Certificate | Display name for the store type (may be customized) +Short Name| WinCert | Short display name for the store type +Custom Capability | WinCert | Store type name orchestrator will register with. Check the box to allow entry of value +Supported Job Types | Inventory, Add, Remove, Reenrollment | Job types the extension supports +Needs Server | Checked | Determines if a target server name is required when creating store +Blueprint Allowed | Unchecked | Determines if store type may be included in an Orchestrator blueprint +Uses PowerShell | Unchecked | Determines if underlying implementation is PowerShell +Requires Store Password | Unchecked | Determines if a store password is required when configuring an individual store. +Supports Entry Password | Unchecked | Determines if an individual entry within a store can have a password. ![](images/WinCertBasic.png) **Advanced Settings:** -CONFIG ELEMENT | DESCRIPTION -------------------|------------------ -Store Path Type |Select Freeform. Allows users to type in a valid certificate store. -Supports Custom Alias |Determines if an individual entry within a store can have a custom Alias. This must be Forbidden. -Private Keys |This determines if Keyfactor can send the private key associated with a certificate to the store. This is required since IIS will need the private key material to establish TLS connections. -PFX Password Style |This determines how the platform generate passwords to protect a PFX enrollment job that is delivered to the store. This can be either Default (system generated) or Custom (user determined). +CONFIG ELEMENT | VALUE | DESCRIPTION +--|--|-- +Store Path Type | Freeform | Allows users to type in a valid certificate store. +Supports Custom Alias | Forbidden | Determines if an individual entry within a store can have a custom Alias. +Private Keys | Required | This determines if Keyfactor can send the private key associated with a certificate to the store. Required because IIS certificates without private keys would be useless. +PFX Password Style | Default or Custom | "Default" - PFX password is randomly generated, "Custom" - PFX password may be specified when the enrollment job is created (Requires the *Allow Custom Password* application setting to be enabled.) ![](images/WinCertAdvanced.png) **Custom Fields:** -- **SPN With Port** – Defaults to false but some customers need for remote PowerShell Access +Custom fields operate at the certificate store level and are used to control how the orchestrator connects to the remote target server containing the certificate store to be managed -Parameter Name|Display Name|Parameter Type|Default Value|Required|Description +Name|Display Name|Type|Default Value / Options|Required|Description ---|---|---|---|---|--- -spnwithport|SPN With Port?|Boolean|false|No|An SPN is the name by which a client uniquely identifies an instance of a service -WinRm Protocol|WinRm Protocol|Multiple Choice|http|Yes|Protocol that WinRM Runs on -WinRm Port|WinRm Port|String|5985|Yes|Port that WinRM Runs on -ServerUsername|Server Username|Secret||No|The username to log into the Server -ServerPassword|Server Password|Secret||No|The password that matches the username to log into the Server -ServerUseSsl|Use SSL|Bool|True|Yes|Determine whether the server uses SSL or not +WinRm Protocol|WinRm Protocol|Multiple Choice| https,http |Yes|Protocol that target server WinRM listener is using +WinRm Port|WinRm Port|String|5986|Yes| Port that target server WinRM listener is using. Typically 5985 for HTTP and 5986 for HTTPS +spnwithport|SPN With Port|Bool|false|No|Internally set the -IncludePortInSPN option when creating the remote PowerShell connection. Needed for some Kerberos configurations. +ServerUsername|Server Username|Secret||No|The username to log into the target server (This field is automatically created) +ServerPassword|Server Password|Secret||No|The password that matches the username to log into the target server (This field is automatically created) +ServerUseSsl|Use SSL|Bool|True|Yes|Determine whether the server uses SSL or not (This field is automatically created) + +*Note that some of the Names in the first column above have spaces and some do not, it is important to configure the Name field exactly as above.* ![](images/WinCertCustom.png) **Entry Parameters:** -- **Provider Name** - Optional. Name of the Windows cryptographic provider to use when generating and storing the private key for the certificate being enrolled by a reenrollment job. If not specified, defaults to 'Microsoft Strong Cryptographic Provider'. This value would typically be changed when leveraging a Hardware Security Module (HSM). The specified cryptographic provider must be available on the target server being managed. The list of installed cryptographic providers can be obtained by running 'certutil -csplist' in a command shell on the target Server. -- **SAN** - Optional. Specifies Subject Alternative Name (SAN) to be used when performing reenrollment jobs. Certificate templates generally require a SAN that matches the subject of the certificate (per RFC 2818). Format is a list of = entries separated by ampersands. Examples: 'dns=www.mysite.com' for a single SAN or 'dns=www.mysite.com&dns=www.mysite2.com' for multiple SANs. -Parameter Name|Parameter Type|Default Value|Required When ----|---|---|--- -ProviderName |String|| -SAN |String||Reenrolling an Entry (if the CA follows RFC 2818 specifications) +Entry parameters are inventoried and maintained for each entry within a certificate store. +They are typically used to support binding of a certificate to a resource. +For the WinCert store type they are used to control how reenrollment jobs are performed. + +Name|Display Name| Type|Default Value|Required When|Description +---|---|---|---|---|--- +ProviderName | Crypto Provider Name | String ||| Name of the Windows cryptographic provider to use during reenrollment jobs when generating and storing the private keys. If not specified, defaults to 'Microsoft Strong Cryptographic Provider'. This value would typically be specified when leveraging a Hardware Security Module (HSM). The specified cryptographic provider must be available on the target server being managed. The list of installed cryptographic providers can be obtained by running 'certutil -csplist' on the target Server. +SAN | SAN | String || Reenrolling | Specifies Subject Alternative Name (SAN) to be used when performing reenrollment jobs. Certificate templates generally require a SAN that matches the subject of the certificate (per RFC 2818). Format is a list of = entries separated by ampersands. Examples: 'dns=www.mysite.com' for a single SAN or 'dns=www.mysite.com&dns=www.mysite2.com' for multiple SANs. Can be made optional if RFC 2818 is disabled on the CA. +None of the above entry parameters have the "Depends On" field set. ![](images/WinCertEntryParams.png) @@ -268,19 +278,18 @@ In Keyfactor Command, navigate to Certificate Stores from the Locations Menu. C #### STORE CONFIGURATION CONFIG ELEMENT |DESCRIPTION ----------------|--------------- -Category |Select the IISU from the dropdown. This is the name of the Certificate Store Type you previously create. -Container |This is a logical grouping of like stores. This configuration is optional and does not impact the functionality of the store. -Client Machine |The hostname of the server to be managed. The Change Credentials option must be clicked to provide a username and password. This account will be used to manage the remote server via PowerShell. -Credentials |Local or domain admin account that has permissions to manage iis (Has to be admin) -Store Path |Select My or WebHosting from the dropdown. -Orchestrator |This is the orchestrator server registered with the appropriate capabilities to manage this certificate store type. -SPN with Port?| Defaulted to False -WinRm Protocol|Select either http or https -WinRm Port |Port to run WinRm on Default for http is 5985 -Server Username|Username to log into the IIS Server -Server Password|Password for the username required to log into the IIS Server -Use SSL|Determines whether SSL is used or not -Inventory Schedule |The interval that the system will use to report on what certificates are currently in the store. +Category | Select IIS Bound Certificate or the customized certificate store display name from above. +Container | Optional container to associate certificate store with. +Client Machine | Hostname of the Windows Server containing the certificate store to be managed. If this value is 'localhost', a local PowerShell runspace executing in the context of the Orchestrator service account will be used to access the certificate store and perform IIS binding operations. If this value is a hostname, a WinRM session will be established using the credentials specified in the Server Username and Server Password fields. +Store Path | Windows certificate store to manage. Choose "My" for the Personal Store or "WebHosting" for the Web Hosting Store. +Orchestrator | Select an approved orchestrator capable of managing IIS Bound Certificates (one that has declared the IISU capability) +WinRm Protocol | Protocol to use when establishing the WinRM session. (Listener on Client Machine must be configured for selected protocol.) +WinRm Port | Port WinRM listener is configured for (HTTPS default is 5986) +SPN with Port | Typically False. Needed in some Kerberos configurations. +Server Username | Account to use when establishing the WinRM session to the Client Machine. Account needs to be an administrator or have been granted rights to manage IIS configuration and manipulate the local machine certificate store. If no account is specified, the security context of the Orchestrator service account will be used. +Server Password | Password to use when establishing the WinRM session to the Client Machine +Use SSL | Ignored for this certificate store type. Transport encryption is determined by the WinRM Protocol Setting +Inventory Schedule | The interval that the system will use to report on what certificates are currently in the store. ![](images/IISUAddCertStore.png) @@ -296,25 +305,27 @@ In Keyfactor Command, navigate to Certificate Stores from the Locations Menu. C #### STORE CONFIGURATION CONFIG ELEMENT |DESCRIPTION ----------------|--------------- -Category |The type of certificate store to be configured. Select category based on the display name configured above for WinCert. -Container |This is a logical grouping of like stores. This configuration is optional and does not impact the functionality of the store. -Client Machine |The hostname of the server to be managed. The Change Credentials option must be clicked to provide a username and password. This account will be used to manage the remote server via PowerShell. -Store Path |Enter the specific name of the certificate store path you want to use. -Orchestrator |This is the orchestrator server registered with the appropriate capabilities to manage this certificate store type. -SPN with Port?|Defaults to False -WinRm Protocol|Select http or https -WinRm Port |Port to run WinRm on Default for http is 5985 -Server Username|Username to log into the IIS Server -Server Password|Password for the username required to log into the IIS Server -Use SSL|Determines whether SSL is used or not -Inventory Schedule |The interval that the system will use to report on what certificates are currently in the store. - -![](images/WinCertStore.png) +Category | Select Windows Certificate or the customized certificate store display name from above. +Container | Optional container to associate certificate store with. +Client Machine | Hostname of the Windows Server containing the certificate store to be managed. If this value is 'localhost', a local PowerShell runspace executing in the context of the Orchestrator service account will be used to access the certificate store. If this value is a hostname, a WinRM session will be established using the credentials specified in the Server Username and Server Password fields. +Store Path | Windows certificate store to manage. Store must exist in the Local Machine store on the target server. +Orchestrator | Select an approved orchestrator capable of managing Windows Certificates (one that has declared the WinCert capability) +WinRm Protocol | Protocol to use when establishing the WinRM session. (Listener on Client Machine must be configured for selected protocol.) +WinRm Port | Port WinRM listener is configured for (HTTPS default is 5986) +SPN with Port | Typically False. Needed in some Kerberos configurations. +Server Username | Account to use when establishing the WinRM session to the Client Machine. Account needs to be an admin or have been granted rights to manipulate the local machine certificate store. If no account is specified, the security context of the Orchestrator service account will be used. +Server Password | Password to use when establishing the WinRM session to the Client Machine +Use SSL | Ignored for this certificate store type. Transport encryption is determined by the WinRM Protocol Setting +Inventory Schedule | The interval that the system will use to report on what certificates are currently in the store. + +![](images/WinCertAddCertStore.png)
## Test Cases +
+IISU Case Number|Case Name|Enrollment Params|Expected Results|Passed|Screenshot ----|------------------------|------------------------------------|--------------|----------------|------------------------- @@ -325,16 +336,14 @@ Case Number|Case Name|Enrollment Params|Expected Results|Passed|Screenshot 5 |New Cert Enrollment New Host Name|**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.162`
**Host Name:** www.newhostname.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|New Binding Created With different host on Same Port and IP Address|True|![](images/TestCase5Results.gif) 6 |New Cert Enrollment Same Site New Port |**Site Name:** FirstSite
**Port:** 4443
**IP Address:**`192.168.58.162`
**Host Name:** www.newhostname.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|New Binding on different port will be created with new cert enrolled|True|![](images/TestCase6Results.gif) 7 |Remove Cert and Binding From Test Case 6|**Site Name:** FirstSite
**Port:** 4443
**IP Address:**`192.168.58.162`
**Host Name:** www.newhostname.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert and Binding From Test Case 6 Removed|True|![](images/TestCase7Results.gif) -8 |Renew Same Cert on 2 Different Sites|`SITE 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsite.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`SITE 2`
**First Site**
**Site Name:** SecondSite
**Port:** 443
**IP Address:**`*`
**Host Name:** cstiis04.cstpki.int
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both sites because it has the same thrumbprint|True|![](images/TestCase8Site1.gif)![](images/TestCase8Site2.gif) -9 |Renew Same Cert on Same Site Same Binding Settings Different Hostname|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding2.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thrumbprint|True|![](images/TestCase9Binding1.gif)![](images/TestCase9Binding2.gif) -10 |Renew Single Cert on Same Site Same Binding Settings Different Hostname Different Certs|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding2.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on only one binding because the other binding does not match thrumbprint|True|![](images/TestCase10Binding1.gif)![](images/TestCase10Binding2.gif) -11 |Renew Same Cert on Same Site Same Binding Settings Different IPs|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.160`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thrumbprint|True|![](images/TestCase11Binding1.gif)![](images/TestCase11Binding2.gif) -12 |Renew Same Cert on Same Site Same Binding Settings Different Ports|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 543
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thrumbprint|True|![](images/TestCase12Binding1.gif)![](images/TestCase12Binding2.gif) +8 |Renew Same Cert on 2 Different Sites|`SITE 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsite.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`SITE 2`
**First Site**
**Site Name:** SecondSite
**Port:** 443
**IP Address:**`*`
**Host Name:** cstiis04.cstpki.int
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both sites because it has the same thumbprint|True|![](images/TestCase8Site1.gif)![](images/TestCase8Site2.gif) +9 |Renew Same Cert on Same Site Same Binding Settings Different Hostname|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding2.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thumbprint|True|![](images/TestCase9Binding1.gif)![](images/TestCase9Binding2.gif) +10 |Renew Single Cert on Same Site Same Binding Settings Different Hostname Different Certs|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding2.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on only one binding because the other binding does not match thumbprint|True|![](images/TestCase10Binding1.gif)![](images/TestCase10Binding2.gif) +11 |Renew Same Cert on Same Site Same Binding Settings Different IPs|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.160`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thumbprint|True|![](images/TestCase11Binding1.gif)![](images/TestCase11Binding2.gif) +12 |Renew Same Cert on Same Site Same Binding Settings Different Ports|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 543
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thumbprint|True|![](images/TestCase12Binding1.gif)![](images/TestCase12Binding2.gif) 13 |ReEnrollment to Fortanix HSM|**Subject Name:** cn=www.mysite.com
**Port:** 433
**IP Address:**`*`
**Host Name:** mysite.command.local
**Site Name:**Default Web Site
**Sni Flag:** 0 - No SNI
**Protocol:** https
**Provider Name:** Fortanix KMS CNG Provider
**SAN:** dns=www.mysite.com&dns=mynewsite.com|Cert will be generated with keys stored in Fortanix HSM and the cert will be bound to the supplied site.|true|![](images/ReEnrollment1a.png)![](images/ReEnrollment1b.png) 14 |New Cert Enrollment To New Binding With Pam Creds|**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsite.com
**Sni Flag:** 0 - No SNI
**Protocol:** https|New Binding Created with Enrollment Params specified creds pulled from Pam Provider|True|![](images/TestCase1Results.gif) 15 |New Cert Enrollment Default Site No HostName|**Site Name:** Default Web Site
**Port:** 443
**IP Address:**`*`
**Host Name:**
**Sni Flag:** 0 - No SNI
**Protocol:** https|New Binding Installed with no HostName|True|![](images/TestCase15Results.gif) - - - - + +
diff --git a/WinCertTestConsole/Inventory.json b/WinCertTestConsole/Inventory.json new file mode 100644 index 0000000..1d7f961 --- /dev/null +++ b/WinCertTestConsole/Inventory.json @@ -0,0 +1,29 @@ +{ + "LastInventory": [ + { + "Alias": "479D92068614E33B3CB84123AF76F1C40DF4B6F6", + "PrivateKeyEntry": true, + "Thumbprints": [ + "479D92068614E33B3CB84123AF76F1C40DF4B6F6" + ] + } + ], + "CertificateStoreDetails": { + "ClientMachine": "iisbindingstest.command.local", + "StorePath": "My", + "StorePassword": "", + "Properties": "{\"spnwithport\":\"false\",\"WinRm Protocol\":\"https\",\"WinRm Port\":\"5986\",\"ServerUsername\":null,\"ServerPassword\":null,\"ServerUseSsl\":\"true\"}", + "Type": 104 + }, + "JobCancelled": false, + "ServerError": null, + "JobHistoryId": 26010, + "RequestStatus": 1, + "ServerUsername": null, + "ServerPassword": null, + "UseSSL": true, + "JobProperties": null, + "JobTypeId": "00000000-0000-0000-0000-000000000000", + "JobId": "e92f7350-251c-4c0a-9e5d-9b3fdb745ca9", + "Capability": "CertStores.IISU.Inventory" +} \ No newline at end of file diff --git a/WinCertTestConsole/KeyfactorClient.cs b/WinCertTestConsole/KeyfactorClient.cs new file mode 100644 index 0000000..e304eac --- /dev/null +++ b/WinCertTestConsole/KeyfactorClient.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using RestSharp; + +namespace WinCertTestConsole +{ + public class KeyfactorClient + { + public async Task EnrollCertificate(string commonName) + { + var options = new RestClientOptions("https://bhillkf10.kfdelivery.com"); + var client = new RestClient(options); + var request = new RestRequest("/KeyfactorAPI/Enrollment/PFX", Method.Post); + request.AddHeader("X-Keyfactor-Requested-With", "APIClient"); + request.AddHeader("x-certificateformat", "PFX"); + request.AddHeader("Authorization", "Basic SomeBasicAuthToken"); + request.AddHeader("Content-Type", "application/json"); + var enrollRequest = new KeyfactorEnrollmentRequest + { + CustomFriendlyName = "2 Year Web Server", + Password = "sldfklsdfsldjfk", + PopulateMissingValuesFromAD = false, + Subject = $"CN={commonName}", + IncludeChain = true, + RenewalCertificateId = 0, + CertificateAuthority = "SomeMachine\\SomeCA", + Timestamp = DateTime.Now, + Template = "2YearTestWebServer" + }; + SANs sans = new SANs(); + List dnsList = new List { $"{commonName}" }; + sans.DNS = dnsList; + enrollRequest.SANs = sans; + request.AddBody(enrollRequest); + var response = await client.ExecuteAsync(request); + return response.Data; + + } + + } +} diff --git a/WinCertTestConsole/KeyfactorEnrollmentRequest.cs b/WinCertTestConsole/KeyfactorEnrollmentRequest.cs new file mode 100644 index 0000000..a32c6c7 --- /dev/null +++ b/WinCertTestConsole/KeyfactorEnrollmentRequest.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; + +namespace WinCertTestConsole +{ + public class KeyfactorEnrollmentRequest + { + public string CustomFriendlyName { get; set; } + public string Password { get; set; } + public bool PopulateMissingValuesFromAD { get; set; } + public string Subject { get; set; } + public bool IncludeChain { get; set; } + public int RenewalCertificateId { get; set; } + public string CertificateAuthority { get; set; } + public DateTime Timestamp { get; set; } + public string Template { get; set; } + public SANs SANs { get; set; } + } + + public class SANs + { + public List DNS { get; set; } + } +} diff --git a/WinCertTestConsole/KeyfactorEnrollmentResult.cs b/WinCertTestConsole/KeyfactorEnrollmentResult.cs new file mode 100644 index 0000000..0b02dd1 --- /dev/null +++ b/WinCertTestConsole/KeyfactorEnrollmentResult.cs @@ -0,0 +1,27 @@ +namespace WinCertTestConsole +{ + // Root myDeserializedClass = JsonConvert.DeserializeObject(myJsonResponse); + public class CertificateInformation + { + public string SerialNumber { get; set; } + public string IssuerDN { get; set; } + public string Thumbprint { get; set; } + public int KeyfactorId { get; set; } + public string Pkcs12Blob { get; set; } + public object Password { get; set; } + public int KeyfactorRequestId { get; set; } + public string RequestDisposition { get; set; } + public string DispositionMessage { get; set; } + public object EnrollmentContext { get; set; } + } + + public class Metadata + { + } + + public class KeyfactorEnrollmentResult + { + public CertificateInformation CertificateInformation { get; set; } + public Metadata Metadata { get; set; } + } +} diff --git a/WinCertTestConsole/Management.json b/WinCertTestConsole/Management.json new file mode 100644 index 0000000..eddd671 --- /dev/null +++ b/WinCertTestConsole/Management.json @@ -0,0 +1,38 @@ +{ + "LastInventory": [], + "CertificateStoreDetails": { + "ClientMachine": "ClientMachineGoesHere", + "StorePath": "StorePathGoesHere", + "StorePassword": null, + "Properties": "{\"spnwithport\":\"false\",\"WinRm Protocol\":\"ProtocolGoesHere\",\"WinRm Port\":\"WinRmPortGoesHere\",\"ServerUsername\":\"UserNameGoesHere\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\"}", + "Type": 104 + }, + "OperationType": 2, + "Overwrite": false, + "JobCertificate": { + "Thumbprint": null, + "Contents": "CertificateContentGoesHere", + "Alias": "", + "PrivateKeyPassword": "sldfklsdfsldjfk" + }, + "JobCancelled": false, + "ServerError": null, + "JobHistoryId": 26009, + "RequestStatus": 1, + "ServerUsername": "UserNameGoesHere", + "ServerPassword": "PasswordGoesHere", + "UseSSL": true, + "JobProperties": { + "Port": "IISPortGoesHere", + "IPAddress": "IPAddressGoesHere", + "HostName": null, + "SiteName": "SiteNameGoesHere", + "SniFlag": "SniFlagGoesHere", + "Protocol": "ProtocolGoesHere", + "ProviderName": null, + "SAN": null + }, + "JobTypeId": "00000000-0000-0000-0000-000000000000", + "JobId": "5f5addc3-afc9-4789-a0fe-04c6e623c233", + "Capability": "CertStores.IISU.Management" +} \ No newline at end of file diff --git a/WinCertTestConsole/ManagementRemove.json b/WinCertTestConsole/ManagementRemove.json new file mode 100644 index 0000000..82abc9f --- /dev/null +++ b/WinCertTestConsole/ManagementRemove.json @@ -0,0 +1,38 @@ +{ + "LastInventory": [], + "CertificateStoreDetails": { + "ClientMachine": "ClientMachineGoesHere", + "StorePath": "StorePathGoesHere", + "StorePassword": null, + "Properties": "{\"spnwithport\":\"false\",\"WinRm Protocol\":\"ProtocolGoesHere\",\"WinRm Port\":\"WinRmPortGoesHere\",\"ServerUsername\":\"UserNameGoesHere\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\"}", + "Type": 104 + }, + "OperationType": 3, + "Overwrite": false, + "JobCertificate": { + "Thumbprint": null, + "Contents": "", + "Alias": "D263D275D35E881C2AAFAC6AAC1E59AE384DB486", + "PrivateKeyPassword": null + }, + "JobCancelled": false, + "ServerError": null, + "JobHistoryId": 26019, + "RequestStatus": 1, + "ServerUsername": null, + "ServerPassword": null, + "UseSSL": true, + "JobProperties": { + "Port": "IISPortGoesHere", + "IPAddress": "IPAddressGoesHere", + "HostName": null, + "SiteName": "SiteNameGoesHere", + "SniFlag": "SniFlagGoesHere", + "Protocol": "ProtocolGoesHere", + "ProviderName": null, + "SAN": null + }, + "JobTypeId": "00000000-0000-0000-0000-000000000000", + "JobId": "c53f1ad8-b712-49f6-a019-41aa75dba385", + "Capability": "CertStores.IISU.Management" +} \ No newline at end of file diff --git a/WinCertTestConsole/Program.cs b/WinCertTestConsole/Program.cs index 6a8085f..ece5574 100644 --- a/WinCertTestConsole/Program.cs +++ b/WinCertTestConsole/Program.cs @@ -1,128 +1,221 @@ -using Keyfactor.Orchestrators.Extensions; -//using Keyfactor.Extensions.Orchestrator.WindowsCertStore.Win; -//using Keyfactor.Extensions.Orchestrator.WindowsCertStore.WinIIS; -using Keyfactor.Extensions.Orchestrator.WindowsCertStore; -using System; -using System.Collections.Generic; -using Newtonsoft.Json; -using Moq; -using Keyfactor.Orchestrators.Extensions.Interfaces; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace WinCertTestConsole -{ - internal class Program - { - static void Main(string[] args) - { - Console.WriteLine("Please Select (I)IS cert store or (W)indows cert store"); - var certStoreType = Console.ReadLine().ToUpper().Substring(0,1); - - Console.WriteLine("Please Select (I)nventory or (M)anagement"); - var input = Console.ReadLine(); - - switch (input.ToUpper().Substring(0,1)) - { - case "R": // Done testing - { - //using var myRunspace = PSHelper.GetClientPSRunspace("http", "localhost", "5985", false, "kfadmin", "Wh5G2Tc6VBYjSMpC"); - //myRunspace.Open(); - //List myCerts = Keyfactor.Extensions.Orchestrator.WindowsCertStore.PowerShellUtilities.CertificateStore.GetCertificatesFromStore(myRunspace, "My"); - - //Console.WriteLine($"Number of certs found: {myCerts.Count}"); - //Console.ReadKey(); - - //List inventory = Keyfactor.Extensions.Orchestrator.WindowsCertStore.PowerShellUtilities.CertificateStore.GetIISBoundCertificates(myRunspace,"My"); - //myRunspace.Close(); - break; - } - case "I": - { - - //Mock invSecretResolver = new Mock(); - //invSecretResolver.Setup(m => m.Resolve(It.IsAny())).Returns(() => "LUFRPT0xbXlnVU9OL2d1N05zY0NPbDJPaEtzWDhtVWM9RWUzVTk4YmZPajhTRkRtcTNmTnEzNERHVzdRTWZNWmQxNlBFNXl0UDBnOXVDWGU1bFN6NS9FSklKNFduNGV6dA=="); - - //var inv = new Inventory(invSecretResolver.Object); - - //var invJobConfig = GetInventoryJobConfiguration(); - //if (certStoreType == "I") - //{ - // var inv = new Keyfactor.Extensions.Orchestrator.WindowsCertStore.WinIIS.Inventory(); - // SubmitInventoryUpdate sui = GetItems; - // inv.ProcessJob(invJobConfig, sui); - //} - //else if(certStoreType=="W") - //{ - // var inv = new Keyfactor.Extensions.Orchestrator.WindowsCertStore.Win.Inventory(); - // SubmitInventoryUpdate sui = GetItems; - // inv.ProcessJob(invJobConfig, sui); - //} - break; - } - case "M": - { - //Console.WriteLine("Select Management (A)dd or (R)emove:"); - //var mgmtInput = Console.ReadLine(); - - //switch (mgmtInput.ToUpper().Substring(0,1)) - //{ - // case "A": - // { - // Console.WriteLine("Enter Private Key Password ikdj3huXRhtZ, Leave Blank if no Private Key"); - // var privateKeyPwd = Console.ReadLine(); - // Console.WriteLine("Overwrite? Enter true or false"); - // var overWrite = Console.ReadLine(); - // Console.WriteLine("Alias Enter Alias Name"); - // var alias = Console.ReadLine(); - // Console.WriteLine("Trusted Root? Enter true or false"); - // var trustedRoot = Console.ReadLine(); - - // Mock mgmtSecretResolver = new Mock(); - // mgmtSecretResolver.Setup(m => m.Resolve(It.IsAny())).Returns(() => "LUFRPT0xbXlnVU9OL2d1N05zY0NPbDJPaEtzWDhtVWM9RWUzVTk4YmZPajhTRkRtcTNmTnEzNERHVzdRTWZNWmQxNlBFNXl0UDBnOXVDWGU1bFN6NS9FSklKNFduNGV6dA=="); - // var mgmt = new Keyfactor.Extensions.Orchestrator.WindowsCertStore.Win.Management(mgmtSecretResolver.Object); - - // var jobConfiguration = GetJobConfiguration(privateKeyPwd, overWrite, trustedRoot, alias); - // var result = mgmt.ProcessJob(jobConfiguration); - - // if (result.Result == Keyfactor.Orchestrators.Common.Enums.OrchestratorJobStatusJobResult.Success) - // { - // Console.WriteLine("Add Success"); - // } - // break; - // } - // case "R": - // { - // break; - // } - //} - break; - } - } - } - - public static bool GetItems(IEnumerable items) - { - return true; - } - - public static InventoryJobConfiguration GetInventoryJobConfiguration() - { - var jobConfigString = "{\"LastInventory\":[],\"CertificateStoreDetails\":{\"ClientMachine\":\"localhost\",\"StorePath\":\"My\",\"StorePassword\":\"\",\"Properties\":\"{\\\"CustField1\\\":\\\"\\\",\\\"ServerUsername\\\":\\\"kfadmin\\\",\\\"ServerPassword\\\":\\\"Wh5G2Tc6VBYjSMpC\\\",\\\"ServerUseSsl\\\":\\\"true\\\"}\",\"Type\":103},\"JobCancelled\":false,\"ServerError\":null,\"JobHistoryId\":3357,\"RequestStatus\":1,\"ServerUsername\":\"kfadmin\",\"ServerPassword\":\"Wh5G2Tc6VBYjSMpC\",\"UseSSL\":true,\"JobProperties\":null,\"JobTypeId\":\"00000000-0000-0000-0000-000000000000\",\"JobId\":\"27eb30f5-f151-4077-acb5-cbc2cc489f7f\",\"Capability\":\"CertStores.Win.Inventory\"}"; - var result = JsonConvert.DeserializeObject(jobConfigString); - - return result; - } - - public static ManagementJobConfiguration GetJobConfiguration(string privateKeyPwd, string overWrite, string trustedRoot, string alias) - { - //var privateKeyConfig = $"{{\"LastInventory\":[],\"CertificateStoreDetails\":{{\"ClientMachine\":\"keyfactorpa.eastus2.cloudapp.azure.com\",\"StorePath\":\"public\",\"StorePassword\":null,\"Properties\":\"{{}}\",\"Type\":5109}},\"OperationType\":2,\"Overwrite\":{overWrite},\"JobCertificate\":{{\"Thumbprint\":null,\"Contents\":\"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\",\"Alias\":\"{alias}\",\"PrivateKeyPassword\":\"{privateKeyPwd}\"}},\"JobCancelled\":false,\"ServerError\":null,\"JobHistoryId\":298380,\"RequestStatus\":1,\"ServerUsername\":\"bhill\",\"ServerPassword\":\"LUFRPT0xbXlnVU9OL2d1N05zY0NPbDJPaEtzWDhtVWM9RWUzVTk4YmZPajhTRkRtcTNmTnEzNERHVzdRTWZNWmQxNlBFNXl0UDBnOXVDWGU1bFN6NS9FSklKNFduNGV6dA==\",\"UseSSL\":true,\"JobProperties\":{{\"Trusted Root\":{trustedRoot}}},\"JobTypeId\":\"00000000-0000-0000-0000-000000000000\",\"JobId\":\"d9e6e40b-f9cf-4974-a8c3-822d2c4f394f\",\"Capability\":\"CertStores.PaloAlto.Management\"}}"; - //var noPrivateKeyConfig = $"{{\"LastInventory\":[],\"CertificateStoreDetails\":{{\"ClientMachine\":\"keyfactorpa.eastus2.cloudapp.azure.com\",\"StorePath\":\"public\",\"StorePassword\":null,\"Properties\":\"{{}}\",\"Type\":5109}},\"OperationType\":2,\"Overwrite\":{overWrite},\"JobCertificate\":{{\"Thumbprint\":null,\"Contents\":\"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\",\"Alias\":\"{alias}\",\"PrivateKeyPassword\":null}},\"JobCancelled\":false,\"ServerError\":null,\"JobHistoryId\":298404,\"RequestStatus\":1,\"ServerUsername\":\"bhill\",\"ServerPassword\":\"LUFRPT0xbXlnVU9OL2d1N05zY0NPbDJPaEtzWDhtVWM9RWUzVTk4YmZPajhTRkRtcTNmTnEzNERHVzdRTWZNWmQxNlBFNXl0UDBnOXVDWGU1bFN6NS9FSklKNFduNGV6dA==\",\"UseSSL\":true,\"JobProperties\":{{\"Trusted Root\":{trustedRoot}}},\"JobTypeId\":\"00000000-0000-0000-0000-000000000000\",\"JobId\":\"36a048c2-f051-407d-9f31-a1ec6ab7d913\",\"Capability\":\"CertStores.PaloAlto.Management\"}}"; - var privateKeyConfig = $"{{\"LastInventory\":[],\"CertificateStoreDetails\":{{\"ClientMachine\":\"localhost\",\"StorePath\":\"My\",\"StorePassword\":null,\"Properties\":\"{{\\\"CustField1\\\":\\\"\\\",\\\"ServerUsername\\\":\\\"kfadmin\\\",\\\"ServerPassword\\\":\\\"Wh5G2Tc6VBYjSMpC\\\",\\\"ServerUseSsl\\\":\\\"true\\\"}}\",\"Type\":103}},\"OperationType\":2,\"Overwrite\":{overWrite},\"JobCertificate\":{{\"Thumbprint\":null,\"Contents\":\"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\",\"Alias\":\"{alias}\",\"PrivateKeyPassword\":\"{privateKeyPwd}\"}},\"JobCancelled\":false,\"ServerError\":null,\"JobHistoryId\":5028,\"RequestStatus\":1,\"ServerUsername\":\"kfadmin\",\"ServerPassword\":\"Wh5G2Tc6VBYjSMpC\",\"UseSSL\":true,\"JobProperties\":{{\"EntryParam1\":null}},\"JobTypeId\":\"00000000-0000-0000-0000-000000000000\",\"JobId\":\"8abad458-5f69-4ca4-b76a-47134649d6d1\",\"Capability\":\"CertStores.Win.Management\"}}"; - - //var jobConfigString = privateKeyPwd.Length > 0 ? privateKeyConfig : noPrivateKeyConfig; - - var result = JsonConvert.DeserializeObject(privateKeyConfig); - return result; - } - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Keyfactor.Extensions.Orchestrator.WindowsCertStore.IISU; +using Keyfactor.Orchestrators.Extensions; +using Keyfactor.Orchestrators.Extensions.Interfaces; +using Moq; +using Newtonsoft.Json; + +namespace WinCertTestConsole +{ + internal class Program + { + public static string UserName { get; set; } + public static string Password { get; set; } + public static string CaseName { get; set; } + public static string CertAlias { get; set; } + public static string ClientMachine { get; set; } + public static string StorePath { get; set; } + public static string Overwrite { get; set; } + public static string Renewal { get; set; } + public static string Domain { get; set; } + public static string SniCert { get; set; } + public static string CertificateContent { get; set; } + public static string Protocol { get; set; } + public static string SiteName { get; set; } + public static string HostName { get; set; } + public static string Port { get; set; } + public static string WinRmPort { get; set; } + public static string IpAddress { get; set; } + public static string IsSetupCert { get; set; } + public static Dictionary Arguments { get; set; } + public static string[] Args { get; set; } + +#pragma warning disable 1998 + private static async Task Main(string[] args) +#pragma warning restore 1998 + { + Args = args; + Arguments = new Dictionary(); + Thread.Sleep(10000); + foreach (var argument in args) + { + var splitted = argument.Split('='); + + if (splitted.Length == 2) Arguments[splitted[0]] = splitted[1]; + } + + if (args.Length > 0) + { + CaseName = Arguments["-casename"]; + UserName = Arguments["-user"]; + Password = Arguments["-password"]; + StorePath = Arguments["-storepath"]; + ClientMachine = Arguments["-clientmachine"]; + WinRmPort = Arguments["-winrmport"]; + } + + // Display message to user to provide parameters. + Console.WriteLine("Running"); + + switch (CaseName) + { + case "Inventory": + Console.WriteLine("Running Inventory"); + InventoryJobConfiguration invJobConfig; + invJobConfig = GetInventoryJobConfiguration(); + Console.WriteLine("Got Inventory Config"); + SubmitInventoryUpdate sui = GetItems; + var secretResolver = new Mock(); + secretResolver.Setup(m => m.Resolve(It.Is(s => s == invJobConfig.ServerUsername))) + .Returns(() => invJobConfig.ServerUsername); + secretResolver.Setup(m => m.Resolve(It.Is(s => s == invJobConfig.ServerPassword))) + .Returns(() => invJobConfig.ServerPassword); + var inv = new Inventory(secretResolver.Object); + Console.WriteLine("Created Inventory Object With Constructor"); + var invResponse = inv.ProcessJob(invJobConfig, sui); + Console.WriteLine("Back From Inventory"); + Console.Write(JsonConvert.SerializeObject(invResponse)); + Console.ReadLine(); + break; + + case "Management": + Console.WriteLine("Select Management Type Add or Remove"); + string mgmtType; + mgmtType = args.Length == 0 ? Console.ReadLine() : Arguments["-managementtype"]; + + if (mgmtType?.ToUpper() == "ADD") + ProcessManagementJob("Management"); + else if (mgmtType?.ToUpper() == "REMOVE") ProcessManagementJob("Remove"); + + break; + } + } + + private static void ProcessManagementJob(string jobType) + { + if (Args.Length > 0) + { + IpAddress = Arguments["-ipaddress"]; + Port = Arguments["-iisport"]; + Overwrite = Arguments["-overwrite"]; + Renewal = Arguments["-isrenew"]; + HostName = Arguments["-hostname"]; + SiteName = Arguments["-sitename"]; + SniCert = Arguments["-snicert"]; + Protocol = Arguments["-protocol"]; + Domain = Arguments["-domain"]; + IsSetupCert = Arguments["-setupcert"]; + } + + Console.WriteLine($"Start Generated Cert in KF API for {jobType}"); + var client = new KeyfactorClient(); + var kfResult = client.EnrollCertificate($"{Domain}").Result; + CertificateContent = kfResult.CertificateInformation.Pkcs12Blob; + Console.WriteLine($"End Generated Cert in KF API for {jobType}"); + + var isRenewal = Renewal.ToUpper() == "TRUE"; + var isSetup = IsSetupCert.ToUpper() == "TRUE"; + + ManagementJobConfiguration jobConfiguration; + + if (!isSetup) + { + jobConfiguration = jobType.ToUpper() == "REMOVE" + ? GetRemoveJobConfiguration() + : GetManagementJobConfiguration("Management"); + + if (isRenewal) + { + var setupConfiguration = GetManagementJobConfiguration("RenewalSetup"); + var renewalThumbprint = setupConfiguration.JobCertificate.Thumbprint; + jobConfiguration.JobProperties.Add("RenewalThumbprint", renewalThumbprint); + } + } + else + { + jobConfiguration = GetManagementJobConfiguration("RenewalSetup"); + } + + + var mgmtSecretResolver = new Mock(); + mgmtSecretResolver + .Setup(m => m.Resolve(It.Is(s => s == jobConfiguration.ServerUsername))) + .Returns(() => jobConfiguration.ServerUsername); + mgmtSecretResolver + .Setup(m => m.Resolve(It.Is(s => s == jobConfiguration.ServerPassword))) + .Returns(() => jobConfiguration.ServerPassword); + var mgmt = new Management(mgmtSecretResolver.Object); + var result = mgmt.ProcessJob(jobConfiguration); + Console.Write(JsonConvert.SerializeObject(result)); + Console.ReadLine(); + } + + public static bool GetItems(IEnumerable items) + { + return true; + } + + + public static InventoryJobConfiguration GetInventoryJobConfiguration() + { + var fileContent = File.ReadAllText("Inventory.json").Replace("UserNameGoesHere", UserName) + .Replace("PasswordGoesHere", Password).Replace("StorePathGoesHere", StorePath) + .Replace("ClientMachineGoesHere", ClientMachine); + var result = + JsonConvert.DeserializeObject(fileContent); + return result; + } + + private static ManagementJobConfiguration GetConfigurationFromFile(string fileName) + { + var hostNameReplaceString = "\"HostName\": null"; + if (!string.IsNullOrEmpty(HostName)) + hostNameReplaceString = $"\"HostName\": \"{HostName}\""; + + var overWriteReplaceString = "\"Overwrite\": false"; + if (Overwrite.ToUpper() == "TRUE") overWriteReplaceString = "\"Overwrite\": true"; + + var replaceDict = new Dictionary + { + {"UserNameGoesHere", UserName}, + {"PasswordGoesHere", Password}, + {"StorePathGoesHere", StorePath}, + {"AliasGoesHere", CertAlias}, + {"ClientMachineGoesHere", ClientMachine}, + {"WinRmPortGoesHere", WinRmPort}, + {"IPAddressGoesHere", IpAddress}, + {"SiteNameGoesHere", SiteName}, + {"ProtocolGoesHere", Protocol}, + {"SniFlagGoesHere", SniCert}, + {"IISPortGoesHere", Port}, + {"PortGoesHere", Port}, + {"HostNameGoesHere", HostName}, + {"CertificateContentGoesHere", CertificateContent}, + {"\"HostName\": null", hostNameReplaceString}, + {"\"Overwrite\": false", overWriteReplaceString} + }; + + + var fileContent = File.ReadAllText($"{fileName}.json"); + foreach (var replaceString in replaceDict) + fileContent = fileContent.Replace(replaceString.Key, replaceString.Value); + + var result = JsonConvert.DeserializeObject(fileContent); + return result; + } + + public static ManagementJobConfiguration GetManagementJobConfiguration(string fileName) + { + return GetConfigurationFromFile(fileName); + } + + public static ManagementJobConfiguration GetRemoveJobConfiguration() + { + return GetConfigurationFromFile("ManagementRemove"); + } + } +} \ No newline at end of file diff --git a/WinCertTestConsole/RenewalSetup.json b/WinCertTestConsole/RenewalSetup.json new file mode 100644 index 0000000..f4bcf26 --- /dev/null +++ b/WinCertTestConsole/RenewalSetup.json @@ -0,0 +1,38 @@ +{ + "LastInventory": [], + "CertificateStoreDetails": { + "ClientMachine": "ClientMachineGoesHere", + "StorePath": "StorePathGoesHere", + "StorePassword": null, + "Properties": "{\"spnwithport\":\"false\",\"WinRm Protocol\":\"ProtocolGoesHere\",\"WinRm Port\":\"WinRmPortGoesHere\",\"ServerUsername\":\"ServerUsername\",\"ServerPassword\":\"PasswordGoesHere\",\"ServerUseSsl\":\"true\"}", + "Type": 104 + }, + "OperationType": 2, + "Overwrite": false, + "JobCertificate": { + "Thumbprint": "CD35329B95E46D9FF3C1C9EF253E512B5CE1FBCB", + "Contents": "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", + "Alias": "", + "PrivateKeyPassword": "sldfklsdfsldjfk" + }, + "JobCancelled": false, + "ServerError": null, + "JobHistoryId": 26009, + "RequestStatus": 1, + "ServerUsername": "UserNameGoesHere", + "ServerPassword": "PasswordGoesHere", + "UseSSL": true, + "JobProperties": { + "Port": "IISPortGoesHere", + "IPAddress": "IPAddressGoesHere", + "HostName": null, + "SiteName": "SiteNameGoesHere", + "SniFlag": "SniFlagGoesHere", + "Protocol": "ProtocolGoesHere", + "ProviderName": null, + "SAN": null + }, + "JobTypeId": "00000000-0000-0000-0000-000000000000", + "JobId": "5f5addc3-afc9-4789-a0fe-04c6e623c233", + "Capability": "CertStores.IISU.Management" +} \ No newline at end of file diff --git a/WinCertTestConsole/RunTest.bat b/WinCertTestConsole/RunTest.bat new file mode 100644 index 0000000..e3646a8 --- /dev/null +++ b/WinCertTestConsole/RunTest.bat @@ -0,0 +1,397 @@ +@echo off + +cd C:\Users\SomePathToBinaries +set ClientMachine=SomeIISMachine +set user=SomeUser +Set password=SomePasssword +set storepath=My + +echo *********************************** +echo Starting Management Test Cases +echo *********************************** +set casename=Management + +goto SNI + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC1 %mgt% new Cert To New Binding. Should do the %mgt%, add the binding and add the cert to the binding +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=* -winrmport=5986 -hostname= -sitename=FirstSite -domain=www.fromtesttool.com -snicert="0 - No SNI" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=false + + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC2 %mgt% /update Cert On Existing Binding. Should do the %mgt%, and update the cert on the binding to the new cert +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=* -winrmport=5986 -hostname= -sitename=FirstSite -domain=www.fromtesttool2.com -snicert="0 - No SNI" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=false + + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC3 %mgt% /update Cert set SNI. Should do the %mgt%, the cert on the new binding to and Set SNI +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=* -winrmport=5986 -hostname=www.snitest.com -sitename=FirstSite -domain=www.fromtesttool2sni.com -iisport=443 -snicert="1 - SNI Enabled" -protocol=https -overwrite=%overwrite% -setupcert=false + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC4 %mgt% new bind, new sni, new ip. Should do the %mgt%, of the cert on new binding set new IP and Set SNI +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=10.3.10.12 -winrmport=5986 -hostname=www.snitest.com -sitename=FirstSite -domain=www.fromtesttool2sni.com -iisport=443 -snicert="1 - SNI Enabled" -protocol=https -overwrite=%overwrite% -setupcert=false + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC5 %mgt% new bind, new sni, same ip. Should do the %mgt%, of the cert on new binding set same IP and Set SNI new host +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=10.3.10.12 -winrmport=5986 -hostname=www.tc5.com -sitename=FirstSite -domain=www.fromtesttool2sni.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=false + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC6 %mgt% new bind, same ip, same host, new port. Should do the %mgt%, of the cert on new binding b/c different port +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=10.3.10.12 -winrmport=5986 -hostname=www.tc5.com -sitename=FirstSite -domain=www.fromtesttool2sni.com -snicert="1 - SNI Enabled" -iisport=4443 -protocol=https -overwrite=%overwrite% -setupcert=false + +set cert=%random% +set casename=Management +set mgt=remove +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC7 %mgt% remove TC6 Cert. Should do the %mgt%, of the cert +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=10.3.10.12 -winrmport=5986 -hostname=www.tc5.com -sitename=FirstSite -domain=www.fromtesttool2sni.com -snicert="1 - SNI Enabled" -iisport=4443 -protocol=https -overwrite=%overwrite% -setupcert=false + +echo: +echo *********************************** +echo Starting Renewal Test Cases +echo *********************************** + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC8 Setup %mgt% renewal setup, installing Cert to Site 1 +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress= -winrmport=5986 -hostname=www.renewtest1.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=true + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC8 Setup %mgt% renewal setup, installing Cert to Site 2 +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress= -winrmport=5986 -hostname=www.renewtestsite1.com -sitename=SecondSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=true + + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC8 %mgt% renewal cert binded in TC8 and TC9 with another cert, should find all thumprints and replace +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=true -ipaddress= -winrmport=5986 -hostname=www.renewtestsite2.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=false + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC9 Setup %mgt% renewal setup, installing Cert to Site 1 +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress= -winrmport=5986 -hostname=www.firstsitebinding1.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=true + + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC9 Setup %mgt% renewal setup, installing Cert to Site 1 +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress= -winrmport=5986 -hostname=www.firstsitebinding2.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=true + + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC9 %mgt% renewal cert binded in TC9 with another cert, should find all thumprints and replace +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=true -ipaddress= -winrmport=5986 -hostname=www.renewtestcase9.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=false + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC10 Setup %mgt% renewal setup, installing Cert to Site 1 +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress= -winrmport=5986 -hostname=www.tc10a.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=true + + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC10 Setup %mgt% renewal setup, installing Cert to Site 1 +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress= -winrmport=5986 -hostname=www.tc10b.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=false + + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC10 %mgt% renewal cert binded in TC10 with another cert, should find all thumprints and replace +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=true -ipaddress= -winrmport=5986 -hostname=www.tc10b.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=false + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC11 Setup %mgt% renewal setup, installing Cert to Site 1 +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=192.168.58.162 -winrmport=5986 -hostname=www.tc11a.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=true + + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC11 Setup %mgt% renewal setup, installing Cert to Site 1 +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=192.168.58.160 -winrmport=5986 -hostname=www.tc11a.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=true + + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC11 %mgt% renewal cert binded in TC11 with another cert, should find all thumprints and replace +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=true -ipaddress= -winrmport=5986 -hostname=www.tc11b.com -sitename=FirstSite -domain=www.renewthis11b.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=false + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC12 Setup %mgt% renewal setup, installing Cert to Site 1 +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=192.168.58.161 -winrmport=5986 -hostname=www.tc11a.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=true + + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC12 Setup %mgt% renewal setup, installing Cert to Site 1 +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress=192.168.58.161 -winrmport=5986 -hostname=www.tc11a.com -sitename=FirstSite -domain=www.renewthis.com -snicert="1 - SNI Enabled" -iisport=4423 -protocol=https -overwrite=%overwrite% -setupcert=true + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC12 %mgt% renewal cert binded in TC12 with another cert, should find all thumprints and replace +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=true -ipaddress= -winrmport=5986 -hostname=www.tc11b.com -sitename=FirstSite -domain=www.renewthis11b.com -snicert="1 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=false + +:SNI + +set cert=%random% +set casename=Management +set mgt=add +set trusted=false +set overwrite=false + +echo ************************************************************************************************************************ +echo TC15 %mgt% Default Web Site Blank Host Name +echo ************************************************************************************************************************ +echo overwrite: %overwrite% +echo trusted: %trusted% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%ClientMachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -managementtype=%mgt% -isrenew=false -ipaddress= -winrmport=5986 -hostname= -sitename=Default Web Site -domain=www.renewthis15.com -snicert="0 - SNI Enabled" -iisport=443 -protocol=https -overwrite=%overwrite% -setupcert=false + +echo: +echo *********************************** +echo Starting Inventory Test Cases +echo *********************************** + + +set casename=Inventory +echo: +echo ************************************************************************* +echo TC22 Inventory Panorama Certificates from Trusted Root and Cert Locations +echo ************************************************************************* +echo overwrite: %overwrite% +echo trusted: %trusted% +echo store path: %storepath% +echo group name: %devicegroup% +echo cert name: %cert% + +WinCertTestConsole.exe -clientmachine=%clientmachine% -casename=%casename% -user=%user% -password=%password% -storepath=%storepath% -devicegroup=%devicegroup% -managementtype=%mgt% + +@pause diff --git a/WinCertTestConsole/WinCertTestConsole.csproj b/WinCertTestConsole/WinCertTestConsole.csproj index c0395b3..319c554 100644 --- a/WinCertTestConsole/WinCertTestConsole.csproj +++ b/WinCertTestConsole/WinCertTestConsole.csproj @@ -2,17 +2,33 @@ Exe - netcoreapp3.1 + net6.0 + + + + Always + + + Always + + + Always + + + Always + + +
diff --git a/WindowsCertStore.sln b/WindowsCertStore.sln index e63867e..28117ce 100644 --- a/WindowsCertStore.sln +++ b/WindowsCertStore.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.2.32616.157 +VisualStudioVersion = 17.5.33627.172 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WindowsCertStore", "IISU\WindowsCertStore.csproj", "{33FBC5A1-3466-4F10-B9A6-7186F804A65A}" EndProject diff --git a/images/AddCertStore.png b/images/AddCertStore.png deleted file mode 100644 index 2d18d0e..0000000 Binary files a/images/AddCertStore.png and /dev/null differ diff --git a/images/CertStoreType-c.png b/images/CertStoreType-c.png deleted file mode 100644 index c308691..0000000 Binary files a/images/CertStoreType-c.png and /dev/null differ diff --git a/images/CertStoreType.png b/images/CertStoreType.png deleted file mode 100644 index b44d7a6..0000000 Binary files a/images/CertStoreType.png and /dev/null differ diff --git a/images/IISCertStore.png b/images/IISCertStore.png deleted file mode 100644 index a4be6ad..0000000 Binary files a/images/IISCertStore.png and /dev/null differ diff --git a/images/IISUAddCertStore.png b/images/IISUAddCertStore.png index def6510..3855927 100644 Binary files a/images/IISUAddCertStore.png and b/images/IISUAddCertStore.png differ diff --git a/images/IISUCertStoreAdv.png b/images/IISUCertStoreAdv.png new file mode 100644 index 0000000..07cfd94 Binary files /dev/null and b/images/IISUCertStoreAdv.png differ diff --git a/images/IISUCertStoreBasic.png b/images/IISUCertStoreBasic.png index 54e9cbc..28c2eb3 100644 Binary files a/images/IISUCertStoreBasic.png and b/images/IISUCertStoreBasic.png differ diff --git a/images/IISUCustomFields.png b/images/IISUCustomFields.png index 7d38af7..4be01a5 100644 Binary files a/images/IISUCustomFields.png and b/images/IISUCustomFields.png differ diff --git a/images/IISUEntryParams.png b/images/IISUEntryParams.png index a05f36f..0b3a5c3 100644 Binary files a/images/IISUEntryParams.png and b/images/IISUEntryParams.png differ diff --git a/images/Screen1.png b/images/Screen1.png deleted file mode 100644 index e2740ec..0000000 Binary files a/images/Screen1.png and /dev/null differ diff --git a/images/Screen2.png b/images/Screen2.png deleted file mode 100644 index 762f071..0000000 Binary files a/images/Screen2.png and /dev/null differ diff --git a/images/WinCertAddCertStore.png b/images/WinCertAddCertStore.png new file mode 100644 index 0000000..81e24e5 Binary files /dev/null and b/images/WinCertAddCertStore.png differ diff --git a/images/WinCertAdvanced.png b/images/WinCertAdvanced.png index 5175a95..feef117 100644 Binary files a/images/WinCertAdvanced.png and b/images/WinCertAdvanced.png differ diff --git a/images/WinCertBasic.png b/images/WinCertBasic.png index 3b28ac6..58f954a 100644 Binary files a/images/WinCertBasic.png and b/images/WinCertBasic.png differ diff --git a/images/WinCertCustom.png b/images/WinCertCustom.png index 193f6c9..83018f0 100644 Binary files a/images/WinCertCustom.png and b/images/WinCertCustom.png differ diff --git a/images/WinCertEntryParams.png b/images/WinCertEntryParams.png index 8506dac..0eb8c90 100644 Binary files a/images/WinCertEntryParams.png and b/images/WinCertEntryParams.png differ diff --git a/images/WinCertStore.png b/images/WinCertStore.png deleted file mode 100644 index d9e9ffe..0000000 Binary files a/images/WinCertStore.png and /dev/null differ diff --git a/images/screen1-a.gif b/images/screen1-a.gif deleted file mode 100644 index b482318..0000000 Binary files a/images/screen1-a.gif and /dev/null differ diff --git a/images/screen1-b.gif b/images/screen1-b.gif deleted file mode 100644 index b1768f0..0000000 Binary files a/images/screen1-b.gif and /dev/null differ diff --git a/images/screen1-c.gif b/images/screen1-c.gif deleted file mode 100644 index c22c84e..0000000 Binary files a/images/screen1-c.gif and /dev/null differ diff --git a/images/screen1.gif b/images/screen1.gif deleted file mode 100644 index 05f1b4b..0000000 Binary files a/images/screen1.gif and /dev/null differ diff --git a/images/screen2-a.gif b/images/screen2-a.gif deleted file mode 100644 index e70529a..0000000 Binary files a/images/screen2-a.gif and /dev/null differ diff --git a/images/screen2.gif b/images/screen2.gif deleted file mode 100644 index 6b1796e..0000000 Binary files a/images/screen2.gif and /dev/null differ diff --git a/images/screen3.gif b/images/screen3.gif deleted file mode 100644 index e3a8912..0000000 Binary files a/images/screen3.gif and /dev/null differ diff --git a/images/screen4.gif b/images/screen4.gif deleted file mode 100644 index f8fa31d..0000000 Binary files a/images/screen4.gif and /dev/null differ diff --git a/images/screen5.gif b/images/screen5.gif deleted file mode 100644 index b8a7ddf..0000000 Binary files a/images/screen5.gif and /dev/null differ diff --git a/images/screen6.gif b/images/screen6.gif deleted file mode 100644 index 5b09732..0000000 Binary files a/images/screen6.gif and /dev/null differ diff --git a/images/screen7.gif b/images/screen7.gif deleted file mode 100644 index 56a894d..0000000 Binary files a/images/screen7.gif and /dev/null differ diff --git a/images/screen8.gif b/images/screen8.gif deleted file mode 100644 index 41562f1..0000000 Binary files a/images/screen8.gif and /dev/null differ diff --git a/images/screen9.gif b/images/screen9.gif deleted file mode 100644 index 0a90f66..0000000 Binary files a/images/screen9.gif and /dev/null differ diff --git a/integration-manifest.json b/integration-manifest.json index effd81d..7c2f2c8 100644 --- a/integration-manifest.json +++ b/integration-manifest.json @@ -1,10 +1,10 @@ { "$schema": "https://keyfactor.github.io/integration-manifest-schema.json", "integration_type": "orchestrator", - "name": "IIS Orchestrator", + "name": "WinCertStore Orchestrator", "status": "production", "link_github": true, - "description": "The IIS Orchestrator treats the certificates bound (actively in use) on a Microsoft Internet Information Server (IIS) as a Keyfactor certificate store. Inventory and Management functions are supported. The orchestrator replaces the IIS orchestrator that ships with Keyfactor Command (which did not support binding.)", + "description": "The Windows Certificate Store Orchestrator Extension implements two certificate store types. 1) “WinCert” which manages certificates in a Windows local machine store, and 2) “IISU” which manages certificates and their bindings in a Windows local machine store that are bound to Internet Information Server (IIS) websites. These extensions replace the now deprecated “IIS” cert store type that ships with Keyfactor Command. The “IISU” extension also replaces the “IISBin” certificate store type from prior versions of this repository. This orchestrator extension is in the process of being renamed from “IIS Orchestrator” as it now supports certificates that are not in use by IIS.", "about": { "orchestrator": { "UOFramework": "10.1", diff --git a/readme-src/readme-pam-support.md b/readme-src/readme-pam-support.md index c4730c0..03aa5f9 100644 --- a/readme-src/readme-pam-support.md +++ b/readme-src/readme-pam-support.md @@ -1,5 +1,5 @@ |Name|Description| |----|-----------| -|Server UserName|The user id that will be used to authenticate into the server hosting the store| +|Server Username|The user id that will be used to authenticate into the server hosting the store| |Server Password|The password that will be used to authenticate into the server hosting the store| diff --git a/readme_source.md b/readme_source.md index c166c26..7d6b600 100644 --- a/readme_source.md +++ b/readme_source.md @@ -9,7 +9,7 @@ The returned list will contain the actual certificate store name to be used when By default, most certificates are stored in the “Personal” (My) and “Web Hosting” (WebHosting) stores. -This agent implements four job types: Inventory, Management Add/Remove, and ReEnrollment. +This extension implements four job types: Inventory, Management Add/Remove, and ReEnrollment. WinRM is used to remotely manage the certificate stores and IIS bindings. WinRM must be properly configured to allow the orchestrator on the server to manage the certificates. Setting up WinRM is not in the scope of this document. @@ -19,85 +19,82 @@ In version 2.0 of the IIS Orchestrator, the certificate store type has been rena 1. Delete existing IIS stores. Delete the IISBin store type. Create the new IISU store type. Recreate the IIS stores using the new IISU store type. 1. Convert existing IISBin certificate stores to IISU certificate stores. There is not currently a way to do this via the Keyfactor API, so direct updates to the underlying Keyfactor SQL database is required. A SQL script (IIS-Conversion.sql) is available in the repository to do this. Hosted customers, which do not have access to the underlying database, will need to work Keyfactor support to run the conversion. On-premises customers can run the script themselves, but are strongly encouraged to ensure that a SQL backup is taken prior running the script (and also be confident that they have a tested database restoration process.) -**Note: There is an additional certificate store type of “IIS” that ships with the Keyfactor platform. Migration of certificate stores from the “IIS” type to either the “IISBin” or “IISU” types is not currently supported.** +**Note: There is an additional (and deprecated) certificate store type of “IIS” that ships with the Keyfactor platform. Migration of certificate stores from the “IIS” type to either the “IISBin” or “IISU” types is not currently supported.** + +**Note: If Looking to use GMSA Accounts to run the Service Kefyactor Command 10.2 or greater is required for No Value checkbox to work** ## Creating New Certificate Store Types -Currently this orchestrator handles two extensions: IISU for IIS servers with bound certificates and WinCert for general Windows Certificates. Below describes how each of these certificate store types are created and configured. +Currently this orchestrator handles two extensions: IISU for IIS servers with bound certificates and WinCert for general Windows Certificates. +Below describes how each of these certificate store types are created and configured.
IISU Extension -**In Keyfactor Command create a new Certificate Store Type similar to the one below:** +**In Keyfactor Command create a new Certificate Store Type as specified below:** **Basic Settings:** -CONFIG ELEMENT | DESCRIPTION -------------------|------------------ -Name |A descriptive name for the extension. Example: IISU -Short Name |The short name that identifies the registered functionality of the orchestrator. Must be IISU. -Custom Capability|Store type name orchestrator will register with. Check the box and enter IISU. -Job Types |Inventory (Checked), check the additional checkboxes: Add, Remove, and Reenrollment. -General Settings|Needs Server - Checked
Blueprint Allowed - Unchecked
Uses PowerShell - Unchecked -Requires Store Password |Determines if a store password is required when configuring an individual store. This must be unchecked. -Supports Entry Password |Determined if an individual entry within a store can have a password. This must be unchecked. +CONFIG ELEMENT | VALUE | DESCRIPTION +--|--|-- +Name | IIS Bound Certificate | Display name for the store type (may be customized) +Short Name| IISU | Short display name for the store type +Custom Capability | IISU | Store type name orchestrator will register with. Check the box to allow entry of value +Supported Job Types | Inventory, Add, Remove, Reenrollment | Job types the extension supports +Needs Server | Checked | Determines if a target server name is required when creating store +Blueprint Allowed | Unchecked | Determines if store type may be included in an Orchestrator blueprint +Uses PowerShell | Unchecked | Determines if underlying implementation is PowerShell +Requires Store Password | Unchecked | Determines if a store password is required when configuring an individual store. +Supports Entry Password | Unchecked | Determines if an individual entry within a store can have a password. ![](images/IISUCertStoreBasic.png) **Advanced Settings:** -CONFIG ELEMENT | DESCRIPTION -------------------|------------------ -Store Path Type |Determines what restrictions are applied to the store path field when configuring a new store. Select Multiple Choice. -Store Path Value|This must be a comma separated list of options to select from for the Store Path. This, combined with the hostname, will determine the location used for the certificate store management and inventory. Must be My, WebHosting -Supports Custom Alias |Determines if an individual entry within a store can have a custom Alias. This must be Forbidden. -Private Keys |This determines if Keyfactor can send the private key associated with a certificate to the store. This is required since IIS will need the private key material to establish TLS connections. -PFX Password Style |This determines how the platform generate passwords to protect a PFX enrollment job that is delivered to the store. This can be either Default (system generated) or Custom (user determined). +CONFIG ELEMENT | VALUE | DESCRIPTION +--|--|-- +Store Path Type | Multiple Choice | Determines what restrictions are applied to the store path field when configuring a new store. +Store Path Value | My,WebHosting | Comma separated list of options configure multiple choice. This, combined with the hostname, will determine the location used for the certificate store management and inventory. +Supports Custom Alias | Forbidden | Determines if an individual entry within a store can have a custom Alias. +Private Keys | Required | This determines if Keyfactor can send the private key associated with a certificate to the store. Required because IIS certificates without private keys would be useless. +PFX Password Style | Default or Custom | "Default" - PFX password is randomly generated, "Custom" - PFX password may be specified when the enrollment job is created (Requires the *Allow Custom Password* application setting to be enabled.) -![](images/screen1-a.gif) +![](images/IISUCertStoreAdv.png) **Custom Fields:** -- **SPN With Port** – Defaults to false but some customers need for remote PowerShell Access +Custom fields operate at the certificate store level and are used to control how the orchestrator connects to the remote +target server containing the certificate store to be managed -Parameter Name|Display Name|Parameter Type|Default Value|Required|Description +Name|Display Name|Type|Default Value / Options|Required|Description ---|---|---|---|---|--- -spnwithport|SPN With Port?|Boolean|false|No|An SPN is the name by which a client uniquely identifies an instance of a service -WinRm Protocol|WinRm Protocol|Multiple Choice|http|Yes|Protocol that WinRM Runs on -WinRm Port|WinRm Port|String|5985|Yes|Port that WinRM Runs on -ServerUsername|Server Username|Secret||No|The username to log into the Server -ServerPassword|Server Password|Secret||No|The password that matches the username to log into the Server -ServerUseSsl|Use SSL|Bool|True|Yes|Determine whether the server uses SSL or not +WinRm Protocol|WinRm Protocol|Multiple Choice| https,http |Yes|Protocol that target server WinRM listener is using +WinRm Port|WinRm Port|String|5986|Yes| Port that target server WinRM listener is using. Typically 5985 for HTTP and 5986 for HTTPS +spnwithport|SPN With Port|Bool|false|No|Internally set the -IncludePortInSPN option when creating the remote PowerShell connection. Needed for some Kerberos configurations. +ServerUsername|Server Username|Secret||No|The username to log into the target server (This field is automatically created). Check the No Value Checkbox when using GMSA Accounts. +ServerPassword|Server Password|Secret||No|The password that matches the username to log into the target server (This field is automatically created). Check the No Value Checkbox when using GMSA Accounts. +ServerUseSsl|Use SSL|Bool|true|Yes|Determine whether the server uses SSL or not (This field is automatically created) + +*Note that some of the Names in the first column above have spaces and some do not, it is important to configure the Name field exactly as above.* + ![](images/IISUCustomFields.png) **Entry Parameters:** -This section must be configured with binding fields. The parameters will be populated with the appropriate data when creating a new certificate store.
- -- **Site Name** – Required (Adding an entry, Removing an entry, Reenrolling an entry). The site name for the web site being bound to – i.e. "Default Web Site" -- **IP Address** – Required (Adding an entry, Removing an entry, Reenrolling an entry). The IP address for the web site being bound to. Default is "\*" for all IP Addresses. -- **Port** – Required (Adding an entry, Removing an entry, Reenrolling an entry). The port for the web site being bound to. Default is "443". -- **Host Name** – Optional. The host name for the web site being bound to. -- **Protocol** - Required (Adding an entry, Removing an entry, Reenrolling an entry) - - https - - http -- **Sni Flag** – Optional. Set the SNI flag associated with the binding being created. Default is "0". Acceptable values are: - - 0 - No SNI - - 1 - SNI Enabled - - 2 - Non SNI Binding - - 3 - SNI Binding -- **Provider Name** - Optional. Name of the Windows cryptographic provider to use when generating and storing the private key for the certificate being enrolled by a reenrollment job. If not specified, defaults to 'Microsoft Strong Cryptographic Provider'. This value would typically be changed when leveraging a Hardware Security Module (HSM). The specified cryptographic provider must be available on the target server being managed. The list of installed cryptographic providers can be obtained by running 'certutil -csplist' in a command shell on the target Server. -- **SAN** - Optional. Specifies Subject Alternative Name (SAN) to be used when performing reenrollment jobs. Certificate templates generally require a SAN that matches the subject of the certificate (per RFC 2818). Format is a list of = entries separated by ampersands. Examples: 'dns=www.mysite.com' for a single SAN or 'dns=www.mysite.com&dns=www.mysite2.com' for multiple SANs. - -Parameter Name|Parameter Type|Default Value|Required When ----|---|---|--- -Port|String|443|Adding Entry, Removing Entry, Reenrolling and Entry -IPAddress|String|*|Adding Entry, Reenrolling an Entry -HostName |String|| -SiteName |String|Default Web Site|Adding Entry, Removing Entry, Reenrolling an Entry -SniFlag |String|0 - No SNI| -Protocol |Multiple Choice|https|Adding Entry, Removing Entry, Reenrolling an Entry -ProviderName |String|| -SAN |String||Reenrolling an Entry (if the CA follows RFC 2818 specifications) +Entry parameters are inventoried and maintained for each entry within a certificate store. +They are typically used to support binding of a certificate to a resource. + +Name|Display Name| Type|Default Value|Required When|Description +---|---|---|---|---|--- +SiteName | IIS Site Name|String|Default Web Site|Adding, Removing, Reenrolling | IIS web site to bind certificate to +IPAddress | IP Address | String | * | Adding, Removing, Reenrolling | IP address to bind certificate to (use '*' for all IP addresses) +Port | Port | String | 443 || Adding, Removing, Reenrolling|IP port for bind certificate to +HostName | Host Name | String |||| Host name (host header) to bind certificate to, leave blank for all host names +SniFlag | SNI Support | Multiple Choice | 0 - No SNI||Type of SNI for binding
(Multiple choice configuration should be entered as "0 - No SNI,1 - SNI Enabled,2 - Non SNI Binding,3 - SNI Binding") +Protocol | Protocol | Multiple Choice | https| Adding, Removing, Reenrolling|Protocol to bind to (always "https").
(Multiple choice configuration should be "https") +ProviderName | Crypto Provider Name | String ||| Name of the Windows cryptographic provider to use during reenrollment jobs when generating and storing the private keys. If not specified, defaults to 'Microsoft Strong Cryptographic Provider'. This value would typically be specified when leveraging a Hardware Security Module (HSM). The specified cryptographic provider must be available on the target server being managed. The list of installed cryptographic providers can be obtained by running 'certutil -csplist' on the target Server. +SAN | SAN | String || Reenrolling | Specifies Subject Alternative Name (SAN) to be used when performing reenrollment jobs. Certificate templates generally require a SAN that matches the subject of the certificate (per RFC 2818). Format is a list of = entries separated by ampersands. Examples: 'dns=www.mysite.com' for a single SAN or 'dns=www.mysite.com&dns=www.mysite2.com' for multiple SANs. Can be made optional if RFC 2818 is disabled on the CA. + +None of the above entry parameters have the "Depends On" field set. ![](images/IISUEntryParams.png) @@ -112,53 +109,60 @@ Click Save to save the Certificate Store Type. **Basic Settings:** -CONFIG ELEMENT | DESCRIPTION -------------------|------------------ -Name |A descriptive name for the extension. Example: WinCert -Short Name |The short name that identifies the registered functionality of the orchestrator. Must be WinCert. -Custom Capability|Store type name orchestrator will register with. Check the box and enter WinCert. -Job Types |Inventory (Checked), check the additional checkboxes: Add, Remove, and Reenrollment. -General Settings|Needs Server - Checked
Blueprint Allowed - Unchecked
Uses PowerShell - Unchecked -Requires Store Password |Determines if a store password is required when configuring an individual store. This must be unchecked. -Supports Entry Password |Determined if an individual entry within a store can have a password. This must be unchecked. +CONFIG ELEMENT | VALUE | DESCRIPTION +--|--|-- +Name | Windows Certificate | Display name for the store type (may be customized) +Short Name| WinCert | Short display name for the store type +Custom Capability | WinCert | Store type name orchestrator will register with. Check the box to allow entry of value +Supported Job Types | Inventory, Add, Remove, Reenrollment | Job types the extension supports +Needs Server | Checked | Determines if a target server name is required when creating store +Blueprint Allowed | Unchecked | Determines if store type may be included in an Orchestrator blueprint +Uses PowerShell | Unchecked | Determines if underlying implementation is PowerShell +Requires Store Password | Unchecked | Determines if a store password is required when configuring an individual store. +Supports Entry Password | Unchecked | Determines if an individual entry within a store can have a password. ![](images/WinCertBasic.png) **Advanced Settings:** -CONFIG ELEMENT | DESCRIPTION -------------------|------------------ -Store Path Type |Select Freeform. Allows users to type in a valid certificate store. -Supports Custom Alias |Determines if an individual entry within a store can have a custom Alias. This must be Forbidden. -Private Keys |This determines if Keyfactor can send the private key associated with a certificate to the store. This is required since IIS will need the private key material to establish TLS connections. -PFX Password Style |This determines how the platform generate passwords to protect a PFX enrollment job that is delivered to the store. This can be either Default (system generated) or Custom (user determined). +CONFIG ELEMENT | VALUE | DESCRIPTION +--|--|-- +Store Path Type | Freeform | Allows users to type in a valid certificate store. +Supports Custom Alias | Forbidden | Determines if an individual entry within a store can have a custom Alias. +Private Keys | Required | This determines if Keyfactor can send the private key associated with a certificate to the store. Required because IIS certificates without private keys would be useless. +PFX Password Style | Default or Custom | "Default" - PFX password is randomly generated, "Custom" - PFX password may be specified when the enrollment job is created (Requires the *Allow Custom Password* application setting to be enabled.) ![](images/WinCertAdvanced.png) **Custom Fields:** -- **SPN With Port** – Defaults to false but some customers need for remote PowerShell Access +Custom fields operate at the certificate store level and are used to control how the orchestrator connects to the remote target server containing the certificate store to be managed -Parameter Name|Display Name|Parameter Type|Default Value|Required|Description +Name|Display Name|Type|Default Value / Options|Required|Description ---|---|---|---|---|--- -spnwithport|SPN With Port?|Boolean|false|No|An SPN is the name by which a client uniquely identifies an instance of a service -WinRm Protocol|WinRm Protocol|Multiple Choice|http|Yes|Protocol that WinRM Runs on -WinRm Port|WinRm Port|String|5985|Yes|Port that WinRM Runs on -ServerUsername|Server Username|Secret||No|The username to log into the Server -ServerPassword|Server Password|Secret||No|The password that matches the username to log into the Server -ServerUseSsl|Use SSL|Bool|True|Yes|Determine whether the server uses SSL or not +WinRm Protocol|WinRm Protocol|Multiple Choice| https,http |Yes|Protocol that target server WinRM listener is using +WinRm Port|WinRm Port|String|5986|Yes| Port that target server WinRM listener is using. Typically 5985 for HTTP and 5986 for HTTPS +spnwithport|SPN With Port|Bool|false|No|Internally set the -IncludePortInSPN option when creating the remote PowerShell connection. Needed for some Kerberos configurations. +ServerUsername|Server Username|Secret||No|The username to log into the target server (This field is automatically created) +ServerPassword|Server Password|Secret||No|The password that matches the username to log into the target server (This field is automatically created) +ServerUseSsl|Use SSL|Bool|True|Yes|Determine whether the server uses SSL or not (This field is automatically created) + +*Note that some of the Names in the first column above have spaces and some do not, it is important to configure the Name field exactly as above.* ![](images/WinCertCustom.png) **Entry Parameters:** -- **Provider Name** - Optional. Name of the Windows cryptographic provider to use when generating and storing the private key for the certificate being enrolled by a reenrollment job. If not specified, defaults to 'Microsoft Strong Cryptographic Provider'. This value would typically be changed when leveraging a Hardware Security Module (HSM). The specified cryptographic provider must be available on the target server being managed. The list of installed cryptographic providers can be obtained by running 'certutil -csplist' in a command shell on the target Server. -- **SAN** - Optional. Specifies Subject Alternative Name (SAN) to be used when performing reenrollment jobs. Certificate templates generally require a SAN that matches the subject of the certificate (per RFC 2818). Format is a list of = entries separated by ampersands. Examples: 'dns=www.mysite.com' for a single SAN or 'dns=www.mysite.com&dns=www.mysite2.com' for multiple SANs. -Parameter Name|Parameter Type|Default Value|Required When ----|---|---|--- -ProviderName |String|| -SAN |String||Reenrolling an Entry (if the CA follows RFC 2818 specifications) +Entry parameters are inventoried and maintained for each entry within a certificate store. +They are typically used to support binding of a certificate to a resource. +For the WinCert store type they are used to control how reenrollment jobs are performed. +Name|Display Name| Type|Default Value|Required When|Description +---|---|---|---|---|--- +ProviderName | Crypto Provider Name | String ||| Name of the Windows cryptographic provider to use during reenrollment jobs when generating and storing the private keys. If not specified, defaults to 'Microsoft Strong Cryptographic Provider'. This value would typically be specified when leveraging a Hardware Security Module (HSM). The specified cryptographic provider must be available on the target server being managed. The list of installed cryptographic providers can be obtained by running 'certutil -csplist' on the target Server. +SAN | SAN | String || Reenrolling | Specifies Subject Alternative Name (SAN) to be used when performing reenrollment jobs. Certificate templates generally require a SAN that matches the subject of the certificate (per RFC 2818). Format is a list of = entries separated by ampersands. Examples: 'dns=www.mysite.com' for a single SAN or 'dns=www.mysite.com&dns=www.mysite2.com' for multiple SANs. Can be made optional if RFC 2818 is disabled on the CA. + +None of the above entry parameters have the "Depends On" field set. ![](images/WinCertEntryParams.png) @@ -179,19 +183,18 @@ In Keyfactor Command, navigate to Certificate Stores from the Locations Menu. C #### STORE CONFIGURATION CONFIG ELEMENT |DESCRIPTION ----------------|--------------- -Category |Select the IISU from the dropdown. This is the name of the Certificate Store Type you previously create. -Container |This is a logical grouping of like stores. This configuration is optional and does not impact the functionality of the store. -Client Machine |The hostname of the server to be managed. The Change Credentials option must be clicked to provide a username and password. This account will be used to manage the remote server via PowerShell. -Credentials |Local or domain admin account that has permissions to manage iis (Has to be admin) -Store Path |Select My or WebHosting from the dropdown. -Orchestrator |This is the orchestrator server registered with the appropriate capabilities to manage this certificate store type. -SPN with Port?| Defaulted to False -WinRm Protocol|Select either http or https -WinRm Port |Port to run WinRm on Default for http is 5985 -Server Username|Username to log into the IIS Server -Server Password|Password for the username required to log into the IIS Server -Use SSL|Determines whether SSL is used or not -Inventory Schedule |The interval that the system will use to report on what certificates are currently in the store. +Category | Select IIS Bound Certificate or the customized certificate store display name from above. +Container | Optional container to associate certificate store with. +Client Machine | Hostname of the Windows Server containing the certificate store to be managed. If this value is 'localhost', a local PowerShell runspace executing in the context of the Orchestrator service account will be used to access the certificate store and perform IIS binding operations. If this value is a hostname, a WinRM session will be established using the credentials specified in the Server Username and Server Password fields. +Store Path | Windows certificate store to manage. Choose "My" for the Personal Store or "WebHosting" for the Web Hosting Store. +Orchestrator | Select an approved orchestrator capable of managing IIS Bound Certificates (one that has declared the IISU capability) +WinRm Protocol | Protocol to use when establishing the WinRM session. (Listener on Client Machine must be configured for selected protocol.) +WinRm Port | Port WinRM listener is configured for (HTTPS default is 5986) +SPN with Port | Typically False. Needed in some Kerberos configurations. +Server Username | Account to use when establishing the WinRM session to the Client Machine. Account needs to be an administrator or have been granted rights to manage IIS configuration and manipulate the local machine certificate store. If no account is specified, the security context of the Orchestrator service account will be used. +Server Password | Password to use when establishing the WinRM session to the Client Machine +Use SSL | Ignored for this certificate store type. Transport encryption is determined by the WinRM Protocol Setting +Inventory Schedule | The interval that the system will use to report on what certificates are currently in the store. ![](images/IISUAddCertStore.png) @@ -207,25 +210,27 @@ In Keyfactor Command, navigate to Certificate Stores from the Locations Menu. C #### STORE CONFIGURATION CONFIG ELEMENT |DESCRIPTION ----------------|--------------- -Category |The type of certificate store to be configured. Select category based on the display name configured above for WinCert. -Container |This is a logical grouping of like stores. This configuration is optional and does not impact the functionality of the store. -Client Machine |The hostname of the server to be managed. The Change Credentials option must be clicked to provide a username and password. This account will be used to manage the remote server via PowerShell. -Store Path |Enter the specific name of the certificate store path you want to use. -Orchestrator |This is the orchestrator server registered with the appropriate capabilities to manage this certificate store type. -SPN with Port?|Defaults to False -WinRm Protocol|Select http or https -WinRm Port |Port to run WinRm on Default for http is 5985 -Server Username|Username to log into the IIS Server -Server Password|Password for the username required to log into the IIS Server -Use SSL|Determines whether SSL is used or not -Inventory Schedule |The interval that the system will use to report on what certificates are currently in the store. - -![](images/WinCertStore.png) +Category | Select Windows Certificate or the customized certificate store display name from above. +Container | Optional container to associate certificate store with. +Client Machine | Hostname of the Windows Server containing the certificate store to be managed. If this value is 'localhost', a local PowerShell runspace executing in the context of the Orchestrator service account will be used to access the certificate store. If this value is a hostname, a WinRM session will be established using the credentials specified in the Server Username and Server Password fields. +Store Path | Windows certificate store to manage. Store must exist in the Local Machine store on the target server. +Orchestrator | Select an approved orchestrator capable of managing Windows Certificates (one that has declared the WinCert capability) +WinRm Protocol | Protocol to use when establishing the WinRM session. (Listener on Client Machine must be configured for selected protocol.) +WinRm Port | Port WinRM listener is configured for (HTTPS default is 5986) +SPN with Port | Typically False. Needed in some Kerberos configurations. +Server Username | Account to use when establishing the WinRM session to the Client Machine. Account needs to be an admin or have been granted rights to manipulate the local machine certificate store. If no account is specified, the security context of the Orchestrator service account will be used. +Server Password | Password to use when establishing the WinRM session to the Client Machine +Use SSL | Ignored for this certificate store type. Transport encryption is determined by the WinRM Protocol Setting +Inventory Schedule | The interval that the system will use to report on what certificates are currently in the store. + +![](images/WinCertAddCertStore.png)
## Test Cases +
+IISU Case Number|Case Name|Enrollment Params|Expected Results|Passed|Screenshot ----|------------------------|------------------------------------|--------------|----------------|------------------------- @@ -236,15 +241,13 @@ Case Number|Case Name|Enrollment Params|Expected Results|Passed|Screenshot 5 |New Cert Enrollment New Host Name|**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.162`
**Host Name:** www.newhostname.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|New Binding Created With different host on Same Port and IP Address|True|![](images/TestCase5Results.gif) 6 |New Cert Enrollment Same Site New Port |**Site Name:** FirstSite
**Port:** 4443
**IP Address:**`192.168.58.162`
**Host Name:** www.newhostname.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|New Binding on different port will be created with new cert enrolled|True|![](images/TestCase6Results.gif) 7 |Remove Cert and Binding From Test Case 6|**Site Name:** FirstSite
**Port:** 4443
**IP Address:**`192.168.58.162`
**Host Name:** www.newhostname.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert and Binding From Test Case 6 Removed|True|![](images/TestCase7Results.gif) -8 |Renew Same Cert on 2 Different Sites|`SITE 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsite.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`SITE 2`
**First Site**
**Site Name:** SecondSite
**Port:** 443
**IP Address:**`*`
**Host Name:** cstiis04.cstpki.int
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both sites because it has the same thrumbprint|True|![](images/TestCase8Site1.gif)![](images/TestCase8Site2.gif) -9 |Renew Same Cert on Same Site Same Binding Settings Different Hostname|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding2.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thrumbprint|True|![](images/TestCase9Binding1.gif)![](images/TestCase9Binding2.gif) -10 |Renew Single Cert on Same Site Same Binding Settings Different Hostname Different Certs|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding2.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on only one binding because the other binding does not match thrumbprint|True|![](images/TestCase10Binding1.gif)![](images/TestCase10Binding2.gif) -11 |Renew Same Cert on Same Site Same Binding Settings Different IPs|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.160`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thrumbprint|True|![](images/TestCase11Binding1.gif)![](images/TestCase11Binding2.gif) -12 |Renew Same Cert on Same Site Same Binding Settings Different Ports|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 543
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thrumbprint|True|![](images/TestCase12Binding1.gif)![](images/TestCase12Binding2.gif) +8 |Renew Same Cert on 2 Different Sites|`SITE 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsite.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`SITE 2`
**First Site**
**Site Name:** SecondSite
**Port:** 443
**IP Address:**`*`
**Host Name:** cstiis04.cstpki.int
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both sites because it has the same thumbprint|True|![](images/TestCase8Site1.gif)![](images/TestCase8Site2.gif) +9 |Renew Same Cert on Same Site Same Binding Settings Different Hostname|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding2.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thumbprint|True|![](images/TestCase9Binding1.gif)![](images/TestCase9Binding2.gif) +10 |Renew Single Cert on Same Site Same Binding Settings Different Hostname Different Certs|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsitebinding2.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on only one binding because the other binding does not match thumbprint|True|![](images/TestCase10Binding1.gif)![](images/TestCase10Binding2.gif) +11 |Renew Same Cert on Same Site Same Binding Settings Different IPs|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.160`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thumbprint|True|![](images/TestCase11Binding1.gif)![](images/TestCase11Binding2.gif) +12 |Renew Same Cert on Same Site Same Binding Settings Different Ports|`BINDING 1`
**Site Name:** FirstSite
**Port:** 443
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https
`BINDING 2`
**Site Name:** FirstSite
**Port:** 543
**IP Address:**`192.168.58.162`
**Host Name:** www.firstsitebinding1.com
**Sni Flag:** 1 - SNI Enabled
**Protocol:** https|Cert will be renewed on both bindings because it has the same thumbprint|True|![](images/TestCase12Binding1.gif)![](images/TestCase12Binding2.gif) 13 |ReEnrollment to Fortanix HSM|**Subject Name:** cn=www.mysite.com
**Port:** 433
**IP Address:**`*`
**Host Name:** mysite.command.local
**Site Name:**Default Web Site
**Sni Flag:** 0 - No SNI
**Protocol:** https
**Provider Name:** Fortanix KMS CNG Provider
**SAN:** dns=www.mysite.com&dns=mynewsite.com|Cert will be generated with keys stored in Fortanix HSM and the cert will be bound to the supplied site.|true|![](images/ReEnrollment1a.png)![](images/ReEnrollment1b.png) 14 |New Cert Enrollment To New Binding With Pam Creds|**Site Name:** FirstSite
**Port:** 443
**IP Address:**`*`
**Host Name:** www.firstsite.com
**Sni Flag:** 0 - No SNI
**Protocol:** https|New Binding Created with Enrollment Params specified creds pulled from Pam Provider|True|![](images/TestCase1Results.gif) 15 |New Cert Enrollment Default Site No HostName|**Site Name:** Default Web Site
**Port:** 443
**IP Address:**`*`
**Host Name:**
**Sni Flag:** 0 - No SNI
**Protocol:** https|New Binding Installed with no HostName|True|![](images/TestCase15Results.gif) - - - - + +