diff --git a/CHANGELOG.md b/CHANGELOG.md
index ce9e0e70..aa79eb0f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+v2.7.0
+- Modified RFJKS store type support java keystores of both PKCS12 and JKS
+- Added support for OpenSSH private keys for SSH authentication
+- Bug fix for orchestrators installed on Windows 2016
+- Bug Fix: Supplied Linux user needing password reset could cause orchestrator locking.
+- Bug Fix: Not supplying group for Linux File Owner on Store Creation caused the supplied owner to erroneously be used as the group for the newly create certificate store file.
+- Updgraded Nuget packages for BouncyCastle and Renci.SSH.Net
+
v2.6.0
- Added ability for Linux installed universal orchestrator to manage stores as an "agent" (stores reside on same server as universal orchestrator) without the need to have SSH enabled.
- Added ability for Linux installed universal orchestrator to manage certificate stores on Windows servers by using SSH to communicate between the Linux UO server and the Windows machines hosting the certificate stores.
diff --git a/README.md b/README.md
index 8fa8fae8..1ef294cf 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ The Universal Orchestrator is the successor to the Windows Orchestrator. This Or
## Support for Remote File
-Remote File
+Remote File is supported by Keyfactor for Keyfactor customers. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com
###### To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab.
@@ -118,7 +118,7 @@ Use cases supported:
RFJKS
-The RFJKS store type can be used to manage java keystores of type JKS. **PLEASE NOTE:** Java keystores of type PKCS12 **_cannot_** be managed by the RFJKS type. You **_must_** use RFPkcs12.
+The RFJKS store type can be used to manage java keystores of types JKS or PKCS12. If creating a new java keystore and adding a certificate all via Keyfactor Command, the created java keystore will be of type PKCS12, as java keystores of type JKS have been deprecated as of JDK 9.
Use cases supported:
1. One-to-many trust entries - A trust entry is considered single certificate without a private key in a certificate store. Each trust entry is identified with a custom alias.
@@ -219,7 +219,10 @@ The version number of a the Remote File Orchestrator Extension can be verified b
2. When orchestrating management of local or external certificate stores, the Remote File Orchestrator Extension makes use of SFTP and/or SCP to transfer files to and from the orchestrated server. SFTP/SCP cannot make use of sudo, so all folders containing certificate stores will need to allow SFTP/SCP file transfer for the user assigned to the certificate store/discovery job. If this is not possible, set the values in the config.json apprpriately to use an alternative upload/download folder that does allow SFTP/SCP file transfer. If the certificate store/discovery job is configured for local (agent) access, the account running the Keyfactor Universal Orchestrator service must have access to read/write to the certificate store location, OR the config.json file must be set up to use the alternative upload/download file.
-3. SSH Key Authentication: When creating a Keyfactor certificate store for the remote file orchestrator extension, you may supply either a user id and password for the certificate store credentials (directly or through one of Keyfactor Command's PAM integrations), or supply a user id and SSH private key. Both PKCS#1 (BEGIN RSA PRIVATE KEY) and PKCS#8 (BEGIN PRIVATE KEY) formats are supported for the SSH private key. If using the normal Keyfactor Command credentials dialog without PAM integration, just copy and paste the full SSH private key into the Password textbox. SSH Key Authentication is not available when running locally as an agent.
+3. SSH Key Authentication: When creating a Keyfactor certificate store for the remote file orchestrator extension, you may supply either a user id and password for the certificate store credentials (directly or through one of Keyfactor Command's PAM integrations), or supply a user id and SSH private key. If using the normal Keyfactor Command credentials dialog without PAM integration, just copy and paste the full SSH private key into the Password textbox. SSH Key Authentication is not available when running locally as an agent. The following private key formats are supported:
+- PKCS#1 (BEGIN RSA PRIVATE KEY)
+- PKCS#8 (BEGIN PRIVATE KEY)
+- ECDSA OPENSSH (BEGIN OPENSSH PRIVATE KEY)
Please reference [Configuration File Setup](#configuration-file-setup) for more information on setting up the config.json file and [Certificate Stores and Discovery Jobs](#certificate-stores-and-discovery-jobs) for more information on the items above.
@@ -328,7 +331,7 @@ The Remote File Orchestrator Extension uses a JSON configuration file. It is lo
DefaultOwnerOnStoreCreation (Applicable for Linux hosted certificate stores only)
-* When a Management job is run to remotely create the physical certificate store on a remote server, by default the file owner and group will be set to the user name associated with the Keyfactor certificate store. Setting DefaultOwnerOnStoreCreation to an alternative valid Linux user name will set that as the owner/group instead. If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please make sure that the user associated with the certificate store will have valid permissions to chown the certificate store file to this alernative owner. The optional "Linux File Owner on Store Creation" custom parameter setting for a specific certificate store can override this value for a specific store. See the [Creating Certificate Store Types](#creating-certificate-store-types) section for more information on creating RemoteFile certificate store types.
+* When a Management job is run to remotely create the physical certificate store on a remote server, by default the file owner and group will be set to the user name associated with the Keyfactor certificate store. Setting DefaultOwnerOnStoreCreation to an alternate valid Linux user name will set that as the owner instead. The owner AND group may be supplied by adding a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Supplying only the ownerId will set that value as the file owner. The group name will default to how the Linux "install" command handles assigning the group. The optional "Linux File Owner on Store Creation" custom parameter setting for a specific certificate store can override this value for a specific store. See the [Creating Certificate Store Types](#creating-certificate-store-types) section for more information on creating RemoteFile certificate store types.
* Allowed values - Any valid user id that the destination Linux server will recognize
* Default Value - blank (the ID associated with the Keyfactor certificate store will be used).
@@ -364,7 +367,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- Entry Parameters Tab:
@@ -398,7 +401,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- Entry Parameters Tab:
@@ -432,7 +435,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- **Name:** IsTrustStore, **Display Name:** Trust Store, **Type:** Bool, **Default Value:** false. This custom field is **not required**. Default value if not present is 'false'. If 'true', this store will be identified as a trust store. Any certificates attempting to be added via a Management-Add job that contain a private key will raise an error with an accompanying message. Multiple certificates may be added to the store in this use case. If set to 'false', this store can only contain a single certificate with chain and private key. Management-Add jobs attempting to add a certificate without a private key to a store marked as IsTrustStore = 'false' will raise an error with an accompanying message.
- **Name:** IncludesChain, **Display Name:** Store Includes Chain, **Type:** Bool, **Default Value:** false. This custom field is **not required**. Default value if not present is 'false'. If 'true' the full certificate chain, if sent by Keyfactor Command, will be stored in the file. The order of appearance is always assumed to be 1) end entity certificate, 2) issuing CA certificate, and 3) root certificate. If additional CA tiers are applicable, the order will be end entity certificate up to the root CA certificate. if set to 'false', only the end entity certificate and private key will be stored in this store. This setting is only valid when IsTrustStore = false.
@@ -471,7 +474,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- **Name:** SeparatePrivateKeyFilePath, **Display Name:** Separate Private Key File Location, **Type:** String, **Default Value:** empty. This custom field is **not required**. If empty, or not provided, it will be assumed that there is no private key associated with this DER store. If the full path AND file name is entered here, that location will be used to store the private key as an external file in DER format.
@@ -506,7 +509,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- Entry Parameters Tab:
@@ -540,7 +543,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- **Name:** WorkFolder, **Display Name:** Work Folder, **Type:** String, **Default Value:** empty. This custom field is **required**. This required field should contain the path on the managed server where temporary work files can be created during Inventory and Management jobs. These files will be removed at the end of each job Please make sure that user id you have assigned to this certificate store will have access to create, modify, and delete files from this folder.
diff --git a/RemoteFile/ApplicationSettings.cs b/RemoteFile/ApplicationSettings.cs
index 2b65a871..ee3caf7a 100644
--- a/RemoteFile/ApplicationSettings.cs
+++ b/RemoteFile/ApplicationSettings.cs
@@ -38,6 +38,8 @@ public enum FileTransferProtocolEnum
public static string DefaultLinuxPermissionsOnStoreCreation { get { return configuration.ContainsKey("DefaultLinuxPermissionsOnStoreCreation") ? configuration["DefaultLinuxPermissionsOnStoreCreation"] : DEFAULT_LINUX_PERMISSION_SETTING; } }
public static string DefaultOwnerOnStoreCreation { get { return configuration.ContainsKey("DefaultOwnerOnStoreCreation") ? configuration["DefaultOwnerOnStoreCreation"] : DEFAULT_OWNER_SETTING; } }
public static string DefaultSudoImpersonatedUser { get { return configuration.ContainsKey("DefaultSudoImpersonatedUser") ? configuration["DefaultSudoImpersonatedUser"] : DEFAULT_SUDO_IMPERSONATION_SETTING; } }
+ public static bool CreateCSROnDevice { get { return configuration.ContainsKey("CreateCSROnDevice") ? configuration["CreateCSROnDevice"]?.ToUpper() == "Y" : false; } }
+ public static string TempFilePathForODKG { get { return configuration.ContainsKey("TempFilePathForODKG") ? configuration["TempFilePathForODKG"] : string.Empty; } }
public static FileTransferProtocolEnum FileTransferProtocol
{
get
diff --git a/RemoteFile/Discovery.cs b/RemoteFile/Discovery.cs
index 42df0c7c..42e78e7e 100644
--- a/RemoteFile/Discovery.cs
+++ b/RemoteFile/Discovery.cs
@@ -22,7 +22,7 @@ namespace Keyfactor.Extensions.Orchestrator.RemoteFile
public class Discovery: IDiscoveryJobExtension
{
public IPAMSecretResolver _resolver;
- public string ExtensionName => "";
+ public string ExtensionName => "Keyfactor.Extensions.Orchestrator.RemoteFile.Discovery";
public Discovery(IPAMSecretResolver resolver)
{
diff --git a/RemoteFile/External References/Renci.SshNet.dll b/RemoteFile/External References/Renci.SshNet.dll
deleted file mode 100644
index d54ea22d..00000000
Binary files a/RemoteFile/External References/Renci.SshNet.dll and /dev/null differ
diff --git a/RemoteFile/External References/SshNet.Security.Cryptography.dll b/RemoteFile/External References/SshNet.Security.Cryptography.dll
deleted file mode 100644
index 2761fd1d..00000000
Binary files a/RemoteFile/External References/SshNet.Security.Cryptography.dll and /dev/null differ
diff --git a/RemoteFile/ImplementedStoreTypes/DER/Reenrollment.cs b/RemoteFile/ImplementedStoreTypes/DER/Reenrollment.cs
new file mode 100644
index 00000000..6659e5d0
--- /dev/null
+++ b/RemoteFile/ImplementedStoreTypes/DER/Reenrollment.cs
@@ -0,0 +1,24 @@
+// Copyright 2021 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.Orchestrators.Extensions.Interfaces;
+
+namespace Keyfactor.Extensions.Orchestrator.RemoteFile.DER
+{
+ public class Reenrollment : ReenrollmentBase
+ {
+ internal override ICertificateStoreSerializer GetCertificateStoreSerializer(string storeProperties)
+ {
+ return new DERCertificateStoreSerializer(storeProperties);
+ }
+
+ public Reenrollment(IPAMSecretResolver resolver)
+ {
+ _resolver = resolver;
+ }
+ }
+}
diff --git a/RemoteFile/ImplementedStoreTypes/JKS/JKSCertificateStoreSerializer.cs b/RemoteFile/ImplementedStoreTypes/JKS/JKSCertificateStoreSerializer.cs
index c285ea9a..164ecc13 100644
--- a/RemoteFile/ImplementedStoreTypes/JKS/JKSCertificateStoreSerializer.cs
+++ b/RemoteFile/ImplementedStoreTypes/JKS/JKSCertificateStoreSerializer.cs
@@ -9,6 +9,7 @@
using System.Collections.Generic;
using Keyfactor.Extensions.Orchestrator.RemoteFile.RemoteHandlers;
using Keyfactor.Extensions.Orchestrator.RemoteFile.Models;
+using Keyfactor.Extensions.Orchestrator.RemoteFile.PKCS12;
using Keyfactor.Logging;
@@ -30,6 +31,8 @@ public JKSCertificateStoreSerializer(string storeProperties)
logger = LogHandler.GetClassLogger(this.GetType());
}
+ private bool IsTypeJKS { get; set; }
+
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContents, string storePath, string storePassword, IRemoteHandler remoteHandler, bool isInventory)
{
logger.MethodEntry(LogLevel.Debug);
@@ -38,42 +41,58 @@ public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContents, strin
Pkcs12Store pkcs12Store = storeBuilder.Build();
Pkcs12Store pkcs12StoreNew = storeBuilder.Build();
- JksStore jksStore = new JksStore();
-
using (MemoryStream ms = new MemoryStream(storeContents))
{
- jksStore.Load(ms, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
+ IsTypeJKS = new JksStore().Probe(ms);
}
- foreach (string alias in jksStore.Aliases)
+ if (IsTypeJKS)
{
- if (jksStore.IsKeyEntry(alias))
+ logger.LogDebug("Store is of type JKS");
+ JksStore jksStore = new JksStore();
+
+ using (MemoryStream ms = new MemoryStream(storeContents))
{
- AsymmetricKeyParameter keyParam = jksStore.GetKey(alias, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
- AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(keyParam);
+ ms.Position = 0;
+ jksStore.Load(ms, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
+ }
- X509Certificate[] certificateChain = jksStore.GetCertificateChain(alias);
- List certificateChainEntries = new List();
- foreach (X509Certificate certificate in certificateChain)
+ foreach (string alias in jksStore.Aliases)
+ {
+ if (jksStore.IsKeyEntry(alias))
{
- certificateChainEntries.Add(new X509CertificateEntry(certificate));
- }
+ AsymmetricKeyParameter keyParam = jksStore.GetKey(alias, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
+ AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(keyParam);
- pkcs12Store.SetKeyEntry(alias, keyEntry, certificateChainEntries.ToArray());
- }
- else
- {
- pkcs12Store.SetCertificateEntry(alias, new X509CertificateEntry(jksStore.GetCertificate(alias)));
+ X509Certificate[] certificateChain = jksStore.GetCertificateChain(alias);
+ List certificateChainEntries = new List();
+ foreach (X509Certificate certificate in certificateChain)
+ {
+ certificateChainEntries.Add(new X509CertificateEntry(certificate));
+ }
+
+ pkcs12Store.SetKeyEntry(alias, keyEntry, certificateChainEntries.ToArray());
+ }
+ else
+ {
+ pkcs12Store.SetCertificateEntry(alias, new X509CertificateEntry(jksStore.GetCertificate(alias)));
+ }
}
- }
- // Second Pkcs12Store necessary because of an obscure BC bug where creating a Pkcs12Store without .Load (code above using "Set" methods only) does not set all internal hashtables necessary to avoid an error later
- // when processing store.
- MemoryStream ms2 = new MemoryStream();
- pkcs12Store.Save(ms2, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
- ms2.Position = 0;
+ // Second Pkcs12Store necessary because of an obscure BC bug where creating a Pkcs12Store without .Load (code above using "Set" methods only) does not set all internal hashtables necessary to avoid an error later
+ // when processing store.
+ MemoryStream ms2 = new MemoryStream();
+ pkcs12Store.Save(ms2, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
+ ms2.Position = 0;
- pkcs12StoreNew.Load(ms2, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
+ pkcs12StoreNew.Load(ms2, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
+ }
+ else
+ {
+ logger.LogDebug("Store is of type PKCS12");
+ PKCS12CertificateStoreSerializer pkcs12Serializer = new PKCS12CertificateStoreSerializer(string.Empty);
+ pkcs12StoreNew = pkcs12Serializer.DeserializeRemoteCertificateStore(storeContents, storePath, storePassword, remoteHandler, isInventory);
+ }
logger.MethodExit(LogLevel.Debug);
return pkcs12StoreNew;
@@ -83,39 +102,50 @@ public List SerializeRemoteCertificateStore(Pkcs12Store cer
{
logger.MethodEntry(LogLevel.Debug);
- JksStore jksStore = new JksStore();
+ List storeInfo = new List();
- foreach (string alias in certificateStore.Aliases)
+ if (IsTypeJKS)
{
- if (certificateStore.IsKeyEntry(alias))
+ JksStore jksStore = new JksStore();
+
+ foreach (string alias in certificateStore.Aliases)
{
- AsymmetricKeyEntry keyEntry = certificateStore.GetKey(alias);
- X509CertificateEntry[] certificateChain = certificateStore.GetCertificateChain(alias);
+ if (certificateStore.IsKeyEntry(alias))
+ {
+ AsymmetricKeyEntry keyEntry = certificateStore.GetKey(alias);
+ X509CertificateEntry[] certificateChain = certificateStore.GetCertificateChain(alias);
- List certificates = new List();
- foreach (X509CertificateEntry certificateEntry in certificateChain)
+ List certificates = new List();
+ foreach (X509CertificateEntry certificateEntry in certificateChain)
+ {
+ certificates.Add(certificateEntry.Certificate);
+ }
+
+ jksStore.SetKeyEntry(alias, keyEntry.Key, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray(), certificates.ToArray());
+ }
+ else
{
- certificates.Add(certificateEntry.Certificate);
+ jksStore.SetCertificateEntry(alias, certificateStore.GetCertificate(alias).Certificate);
}
-
- jksStore.SetKeyEntry(alias, keyEntry.Key, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray(), certificates.ToArray());
}
- else
+
+ using (MemoryStream outStream = new MemoryStream())
{
- jksStore.SetCertificateEntry(alias, certificateStore.GetCertificate(alias).Certificate);
+ jksStore.Save(outStream, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
+
+ storeInfo.Add(new SerializedStoreInfo() { FilePath = storePath + storeFileName, Contents = outStream.ToArray() });
+
+ logger.MethodExit(LogLevel.Debug);
+ return storeInfo;
}
}
-
- using (MemoryStream outStream = new MemoryStream())
+ else
{
- jksStore.Save(outStream, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
-
- List storeInfo = new List();
- storeInfo.Add(new SerializedStoreInfo() { FilePath = storePath + storeFileName, Contents = outStream.ToArray() });
-
- logger.MethodExit(LogLevel.Debug);
- return storeInfo;
+ PKCS12CertificateStoreSerializer pkcs12Serializer = new PKCS12CertificateStoreSerializer(string.Empty);
+ storeInfo = pkcs12Serializer.SerializeRemoteCertificateStore(certificateStore, storePath, storeFileName, storePassword, remoteHandler);
}
+
+ return storeInfo;
}
public string GetPrivateKeyPath()
diff --git a/RemoteFile/ImplementedStoreTypes/JKS/Reenrollment.cs b/RemoteFile/ImplementedStoreTypes/JKS/Reenrollment.cs
new file mode 100644
index 00000000..99c913f9
--- /dev/null
+++ b/RemoteFile/ImplementedStoreTypes/JKS/Reenrollment.cs
@@ -0,0 +1,24 @@
+// Copyright 2021 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.Orchestrators.Extensions.Interfaces;
+
+namespace Keyfactor.Extensions.Orchestrator.RemoteFile.JKS
+{
+ public class Reenrollment : ReenrollmentBase
+ {
+ internal override ICertificateStoreSerializer GetCertificateStoreSerializer(string storeProperties)
+ {
+ return new JKSCertificateStoreSerializer(storeProperties);
+ }
+
+ public Reenrollment(IPAMSecretResolver resolver)
+ {
+ _resolver = resolver;
+ }
+ }
+}
diff --git a/RemoteFile/ImplementedStoreTypes/KDB/Reenrollment.cs b/RemoteFile/ImplementedStoreTypes/KDB/Reenrollment.cs
new file mode 100644
index 00000000..28a43606
--- /dev/null
+++ b/RemoteFile/ImplementedStoreTypes/KDB/Reenrollment.cs
@@ -0,0 +1,24 @@
+// Copyright 2021 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.Orchestrators.Extensions.Interfaces;
+
+namespace Keyfactor.Extensions.Orchestrator.RemoteFile.KDB
+{
+ public class Reenrollment : ReenrollmentBase
+ {
+ internal override ICertificateStoreSerializer GetCertificateStoreSerializer(string storeProperties)
+ {
+ return new KDBCertificateStoreSerializer(storeProperties);
+ }
+
+ public Reenrollment(IPAMSecretResolver resolver)
+ {
+ _resolver = resolver;
+ }
+ }
+}
diff --git a/RemoteFile/ImplementedStoreTypes/OraWlt/Reenrollment.cs b/RemoteFile/ImplementedStoreTypes/OraWlt/Reenrollment.cs
new file mode 100644
index 00000000..230211a6
--- /dev/null
+++ b/RemoteFile/ImplementedStoreTypes/OraWlt/Reenrollment.cs
@@ -0,0 +1,25 @@
+// Copyright 2021 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.Extensions.Orchestrator.RemoteFile.KDB;
+using Keyfactor.Orchestrators.Extensions.Interfaces;
+
+namespace Keyfactor.Extensions.Orchestrator.RemoteFile.OraWlt
+{
+ public class Reenrollment : ReenrollmentBase
+ {
+ internal override ICertificateStoreSerializer GetCertificateStoreSerializer(string storeProperties)
+ {
+ return new OraWltCertificateStoreSerializer(storeProperties);
+ }
+
+ public Reenrollment(IPAMSecretResolver resolver)
+ {
+ _resolver = resolver;
+ }
+ }
+}
diff --git a/RemoteFile/ImplementedStoreTypes/PEM/Reenrollment.cs b/RemoteFile/ImplementedStoreTypes/PEM/Reenrollment.cs
new file mode 100644
index 00000000..143913de
--- /dev/null
+++ b/RemoteFile/ImplementedStoreTypes/PEM/Reenrollment.cs
@@ -0,0 +1,25 @@
+// Copyright 2021 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.Extensions.Orchestrator.RemoteFile.PEM;
+using Keyfactor.Orchestrators.Extensions.Interfaces;
+
+namespace Keyfactor.Extensions.Orchestrator.RemoteFile.PEM
+{
+ public class Reenrollment : ReenrollmentBase
+ {
+ internal override ICertificateStoreSerializer GetCertificateStoreSerializer(string storeProperties)
+ {
+ return new PEMCertificateStoreSerializer(storeProperties);
+ }
+
+ public Reenrollment(IPAMSecretResolver resolver)
+ {
+ _resolver = resolver;
+ }
+ }
+}
diff --git a/RemoteFile/ImplementedStoreTypes/PKCS12/Reenrollment.cs b/RemoteFile/ImplementedStoreTypes/PKCS12/Reenrollment.cs
new file mode 100644
index 00000000..d9f4d404
--- /dev/null
+++ b/RemoteFile/ImplementedStoreTypes/PKCS12/Reenrollment.cs
@@ -0,0 +1,24 @@
+// Copyright 2021 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.Orchestrators.Extensions.Interfaces;
+
+namespace Keyfactor.Extensions.Orchestrator.RemoteFile.PKCS12
+{
+ public class Reenrollment : ReenrollmentBase
+ {
+ internal override ICertificateStoreSerializer GetCertificateStoreSerializer(string storeProperties)
+ {
+ return new PKCS12CertificateStoreSerializer(storeProperties);
+ }
+
+ public Reenrollment(IPAMSecretResolver resolver)
+ {
+ _resolver = resolver;
+ }
+ }
+}
diff --git a/RemoteFile/InventoryBase.cs b/RemoteFile/InventoryBase.cs
index 3931e777..7d6aa2f3 100644
--- a/RemoteFile/InventoryBase.cs
+++ b/RemoteFile/InventoryBase.cs
@@ -21,7 +21,7 @@ namespace Keyfactor.Extensions.Orchestrator.RemoteFile
{
public abstract class InventoryBase : RemoteFileJobTypeBase, IInventoryJobExtension
{
- public string ExtensionName => string.Empty;
+ public string ExtensionName => "Keyfactor.Extensions.Orchestrator.RemoteFile.Inventory";
RemoteCertificateStore certificateStore = new RemoteCertificateStore();
diff --git a/RemoteFile/ManagementBase.cs b/RemoteFile/ManagementBase.cs
index a6c213c7..175452bd 100644
--- a/RemoteFile/ManagementBase.cs
+++ b/RemoteFile/ManagementBase.cs
@@ -8,7 +8,6 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
-using System.Threading;
using Keyfactor.Logging;
using Keyfactor.Orchestrators.Extensions;
@@ -22,9 +21,7 @@ namespace Keyfactor.Extensions.Orchestrator.RemoteFile
{
public abstract class ManagementBase : RemoteFileJobTypeBase, IManagementJobExtension
{
- static Mutex mutex = new Mutex(false, "ModifyStore");
-
- public string ExtensionName => "";
+ public string ExtensionName => "Keyfactor.Extensions.Orchestrator.RemoteFile.Management";
internal RemoteCertificateStore certificateStore = new RemoteCertificateStore();
@@ -44,8 +41,6 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
try
{
- mutex.WaitOne();
-
string userName = PAMUtilities.ResolvePAMField(_resolver, logger, "Server User Name", config.ServerUsername);
string userPassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Server Password", config.ServerPassword);
string storePassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Store Password", config.CertificateStoreDetails.StorePassword);
@@ -73,7 +68,7 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
throw new RemoteFileException($"Certificate store {config.CertificateStoreDetails.StorePath} does not exist on server {config.CertificateStoreDetails.ClientMachine}.");
}
certificateStore.LoadCertificateStore(certificateStoreSerializer, config.CertificateStoreDetails.Properties, false);
- certificateStore.AddCertificate((config.JobCertificate.Alias ?? new X509Certificate2(Convert.FromBase64String(config.JobCertificate.Contents), config.JobCertificate.PrivateKeyPassword).Thumbprint), config.JobCertificate.Contents, config.Overwrite, config.JobCertificate.PrivateKeyPassword);
+ certificateStore.AddCertificate((config.JobCertificate.Alias ?? new X509Certificate2(Convert.FromBase64String(config.JobCertificate.Contents), config.JobCertificate.PrivateKeyPassword, X509KeyStorageFlags.EphemeralKeySet).Thumbprint), config.JobCertificate.Contents, config.Overwrite, config.JobCertificate.PrivateKeyPassword);
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, storePassword, certificateStore.RemoteHandler));
logger.LogDebug($"END add Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");
@@ -118,8 +113,6 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
}
finally
{
- mutex.ReleaseMutex();
-
if (certificateStore.RemoteHandler != null)
certificateStore.Terminate();
}
diff --git a/RemoteFile/ReenrollmentBase.cs b/RemoteFile/ReenrollmentBase.cs
new file mode 100644
index 00000000..ed7ca86b
--- /dev/null
+++ b/RemoteFile/ReenrollmentBase.cs
@@ -0,0 +1,144 @@
+// Copyright 2021 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.Collections.Generic;
+using System.Security.Cryptography.X509Certificates;
+
+using Keyfactor.Logging;
+using Keyfactor.Orchestrators.Extensions;
+using Keyfactor.Orchestrators.Common.Enums;
+using Keyfactor.PKI.PEM;
+
+using Microsoft.Extensions.Logging;
+
+using Newtonsoft.Json;
+using System.Security.Cryptography;
+
+namespace Keyfactor.Extensions.Orchestrator.RemoteFile
+{
+ public abstract class ReenrollmentBase : RemoteFileJobTypeBase
+ {
+ public string ExtensionName => "Keyfactor.Extensions.Orchestrator.RemoteFile";
+
+ internal RemoteCertificateStore certificateStore = new RemoteCertificateStore();
+
+ internal enum SupportedKeyTypeEnum
+ {
+ RSA,
+ ECC
+ }
+
+ //TODO:
+ // 1) Set SANs, Alias and Overwrite "for real" once product figures out how to pass that
+ // 2) Add "CreateCSROnDevice" (Y/N) to config.json
+ // 3) Add "TempFilePathForODKG" (string) to config.json
+ // 4) Add Reenrollment to manifest.json for all store types
+ // 5) Rename ProcessJobToDo to ProcessJob
+ // 6) Modify ReenrollmentBase to implement IReenrollmentJobExtension
+ // 6) Update README. Remember to explain the differences between ODKG and OOKG
+
+ public JobResult ProcessJobToDo(ReenrollmentJobConfiguration config, SubmitReenrollmentCSR submitReenrollment)
+ {
+ ILogger logger = LogHandler.GetClassLogger(this.GetType());
+ logger.LogDebug($"Begin {config.Capability} for job id {config.JobId}...");
+ logger.LogDebug($"Server: {config.CertificateStoreDetails.ClientMachine}");
+ logger.LogDebug($"Store Path: {config.CertificateStoreDetails.StorePath}");
+
+ logger.LogDebug($"Job Properties:");
+ foreach (KeyValuePair keyValue in config.JobProperties == null ? new Dictionary() : config.JobProperties)
+ {
+ logger.LogDebug($" {keyValue.Key}: {keyValue.Value}");
+ }
+
+ ICertificateStoreSerializer certificateStoreSerializer = GetCertificateStoreSerializer(config.CertificateStoreDetails.Properties);
+
+ try
+ {
+ string userName = PAMUtilities.ResolvePAMField(_resolver, logger, "Server User Name", config.ServerUsername);
+ string userPassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Server Password", config.ServerPassword);
+ string storePassword = PAMUtilities.ResolvePAMField(_resolver, logger, "Store Password", config.CertificateStoreDetails.StorePassword);
+
+ ApplicationSettings.Initialize(this.GetType().Assembly.Location);
+ dynamic properties = JsonConvert.DeserializeObject(config.CertificateStoreDetails.Properties.ToString());
+ string sudoImpersonatedUser = properties.SudoImpersonatedUser == null || string.IsNullOrEmpty(properties.SudoImpersonatedUser.Value) ?
+ ApplicationSettings.DefaultSudoImpersonatedUser :
+ properties.SudoImpersonatedUser.Value;
+ bool createCSROnDevice = properties.CreateCSROnDevice == null || string.IsNullOrEmpty(properties.CreateCSROnDevice.Value) ?
+ ApplicationSettings.CreateCSROnDevice :
+ Convert.ToBoolean(properties.CreateCSROnDevice.Value);
+
+ string keyType = !config.JobProperties.ContainsKey("keyType") || config.JobProperties["keyType"] == null || string.IsNullOrEmpty(config.JobProperties["keyType"].ToString()) ? string.Empty : config.JobProperties["keyType"].ToString();
+ int keySize = !config.JobProperties.ContainsKey("keySize") || config.JobProperties["keySize"] == null || string.IsNullOrEmpty(config.JobProperties["keySize"].ToString()) ? 2048 : Convert.ToInt32(config.JobProperties["keySize"]);
+ string subjectText = !config.JobProperties.ContainsKey("subjectText") || config.JobProperties["subjectText"] == null || config.JobProperties["subjectText"] == null || string.IsNullOrEmpty(config.JobProperties["subjectText"].ToString()) ? string.Empty : config.JobProperties["subjectText"].ToString();
+
+ string alias = "abcd";
+ string sans = "reenroll2.Keyfactor.com&reenroll1.keyfactor.com&reenroll3.Keyfactor.com";
+ bool overwrite = true;
+
+ // validate parameters
+ string keyTypes = string.Join(",", Enum.GetNames(typeof(SupportedKeyTypeEnum)));
+ if (!Enum.TryParse(keyType.ToUpper(), out SupportedKeyTypeEnum keyTypeEnum))
+ {
+ throw new RemoteFileException($"Unsupported KeyType value {keyType}. Supported types are {keyTypes}.");
+ }
+
+ certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, userName, userPassword, config.CertificateStoreDetails.StorePath, storePassword, config.JobProperties);
+ certificateStore.Initialize(sudoImpersonatedUser);
+
+ PathFile storePathFile = RemoteCertificateStore.SplitStorePathFile(config.CertificateStoreDetails.StorePath);
+
+ if (!certificateStore.DoesStoreExist())
+ {
+ throw new RemoteFileException($"Certificate store {config.CertificateStoreDetails.StorePath} does not exist on server {config.CertificateStoreDetails.ClientMachine}.");
+ }
+
+ // generate CSR and call back to enroll certificate
+ string csr = string.Empty;
+ string pemPrivateKey = string.Empty;
+ if (createCSROnDevice)
+ {
+ csr = certificateStore.GenerateCSROnDevice(subjectText, keyTypeEnum, keySize, new List(sans.Split('&', StringSplitOptions.RemoveEmptyEntries)), out pemPrivateKey);
+ }
+ else
+ {
+ csr = certificateStore.GenerateCSR(subjectText, keyTypeEnum, keySize, new List(sans.Split('&', StringSplitOptions.RemoveEmptyEntries)));
+ }
+
+ X509Certificate2 cert = submitReenrollment.Invoke(csr);
+ if (cert == null || String.IsNullOrEmpty(pemPrivateKey))
+ throw new RemoteFileException("Enrollment of CSR failed. Please check Keyfactor Command logs for more information on potential enrollment errors.");
+
+ AsymmetricAlgorithm alg = keyTypeEnum == SupportedKeyTypeEnum.RSA ? RSA.Create() : ECDsa.Create();
+ alg.ImportEncryptedPkcs8PrivateKey(string.Empty, Keyfactor.PKI.PEM.PemUtilities.PEMToDER(pemPrivateKey), out _);
+ cert = keyTypeEnum == SupportedKeyTypeEnum.RSA ? cert.CopyWithPrivateKey((RSA)alg) : cert.CopyWithPrivateKey((ECDsa)alg);
+
+ // save certificate
+ certificateStore.LoadCertificateStore(certificateStoreSerializer, config.CertificateStoreDetails.Properties, false);
+ certificateStore.AddCertificate((alias ?? cert.Thumbprint), Convert.ToBase64String(cert.Export(X509ContentType.Pfx)), overwrite, null);
+ certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, storePassword, certificateStore.RemoteHandler));
+
+ logger.LogDebug($"END add Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");
+ }
+
+ catch (Exception ex)
+ {
+ string errorMessage = $"Exception for {config.Capability}: {RemoteFileException.FlattenExceptionMessages(ex, string.Empty)} for job id {config.JobId}";
+ logger.LogError(errorMessage);
+ return new JobResult() { Result = OrchestratorJobStatusJobResult.Failure, JobHistoryId = config.JobHistoryId, FailureMessage = $"Site {config.CertificateStoreDetails.StorePath} on server {config.CertificateStoreDetails.ClientMachine}: {errorMessage}" };
+ }
+ finally
+ {
+ if (certificateStore.RemoteHandler != null)
+ certificateStore.Terminate();
+ }
+
+ logger.LogDebug($"...End {config.Capability} job for job id {config.JobId}");
+ return new JobResult() { Result = OrchestratorJobStatusJobResult.Success, JobHistoryId = config.JobHistoryId };
+ }
+ }
+}
diff --git a/RemoteFile/RemoteCertificateStore.cs b/RemoteFile/RemoteCertificateStore.cs
index 3e23edd6..3a8dd180 100644
--- a/RemoteFile/RemoteCertificateStore.cs
+++ b/RemoteFile/RemoteCertificateStore.cs
@@ -22,6 +22,13 @@
using Keyfactor.Extensions.Orchestrator.RemoteFile.Models;
using Keyfactor.Logging;
using System.Runtime.InteropServices;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Prng;
+using Org.BouncyCastle.Crypto;
+using static Keyfactor.Extensions.Orchestrator.RemoteFile.ReenrollmentBase;
namespace Keyfactor.Extensions.Orchestrator.RemoteFile
{
@@ -248,7 +255,7 @@ internal void AddCertificate(string alias, string certificateEntry, bool overwri
Pkcs12Store newEntry = storeBuilder.Build();
- X509Certificate2 cert = new X509Certificate2(newCertBytes, pfxPassword, X509KeyStorageFlags.Exportable);
+ X509Certificate2 cert = new X509Certificate2(newCertBytes, pfxPassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.EphemeralKeySet);
byte[] binaryCert = cert.Export(X509ContentType.Pkcs12, pfxPassword);
using (MemoryStream ms = new MemoryStream(string.IsNullOrEmpty(pfxPassword) ? binaryCert : newCertBytes))
@@ -336,6 +343,106 @@ internal static PathFile SplitStorePathFile(string pathFileName)
}
}
+ internal string GenerateCSR(string subjectText, SupportedKeyTypeEnum keyType, int keySize, List sans)
+ {
+ IAsymmetricCipherKeyPairGenerator keyPairGenerator = null;
+ string algorithm = string.Empty;
+ switch (keyType)
+ {
+ case SupportedKeyTypeEnum.RSA:
+ keyPairGenerator = new RsaKeyPairGenerator();
+ algorithm = "SHA256withRSA";
+ break;
+ case SupportedKeyTypeEnum.ECC:
+ keyPairGenerator = new ECKeyPairGenerator();
+ algorithm = "SHA256withECDSA";
+ if (keySize == 384) algorithm = "SHA384withECDSA";
+ if (keySize == 521) algorithm = "SHA512withECDSA";
+ break;
+ }
+
+ var keyGenParams = new KeyGenerationParameters(new Org.BouncyCastle.Security.SecureRandom(new CryptoApiRandomGenerator()), keySize);
+ keyPairGenerator.Init(keyGenParams);
+ var keyPair = keyPairGenerator.GenerateKeyPair();
+
+ var subject = new X509Name(subjectText);
+
+ // Add SAN entries
+ var subAltNameList = new List();
+ sans.ForEach(san => subAltNameList.Add(new GeneralName(GeneralName.DnsName, san.Trim())));
+ var generalSubAltNames = new GeneralNames(subAltNameList.ToArray());
+
+ var extensionsGenerator = new X509ExtensionsGenerator();
+ extensionsGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, generalSubAltNames);
+ var attributeSet = new DerSet(new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(extensionsGenerator.Generate())));
+
+ Pkcs10CertificationRequest csr = new Pkcs10CertificationRequest(algorithm, subject, keyPair.Public, (DerSet)attributeSet, keyPair.Private);
+
+ // encode the CSR as base64
+ var encodedCsr = Convert.ToBase64String(csr.GetEncoded());
+ return encodedCsr;
+ }
+
+ internal string GenerateCSROnDevice(string subjectText, SupportedKeyTypeEnum keyType, int keySize, List sans, out string privateKey)
+ {
+ string path = ApplicationSettings.TempFilePathForODKG;
+ if (path.Substring(path.Length - 1, 1) != "/") path += "/";
+ string fileName = Guid.NewGuid().ToString();
+
+ X500DistinguishedName dn = new X500DistinguishedName(subjectText);
+ string opensslSubject = dn.Format(true).Replace("S=","ST=");
+ opensslSubject = opensslSubject.Replace(System.Environment.NewLine, "/");
+ opensslSubject = "/" + opensslSubject.Substring(0, opensslSubject.Length - 1);
+
+ string cmd = $"openssl req -new -newkey REPLACE -nodes -keyout {path}{fileName}.key -out {path}{fileName}.csr -subj '{opensslSubject}'";
+ switch (keyType)
+ {
+ case SupportedKeyTypeEnum.RSA:
+ cmd = cmd.Replace("REPLACE", $"rsa:{keySize.ToString()}");
+ break;
+ case SupportedKeyTypeEnum.ECC:
+ string algName = "prime256v1";
+ switch (keySize)
+ {
+ case 384:
+ algName = "secp384r1";
+ break;
+ case 521:
+ algName = "secp521r1";
+ break;
+ }
+ cmd = cmd.Replace("REPLACE", $"ec:<(openssl ecparam -name {algName})");
+ break;
+ }
+
+ string csr = string.Empty;
+ privateKey = string.Empty;
+ try
+ {
+ try
+ {
+ RemoteHandler.RunCommand(cmd, null, ApplicationSettings.UseSudo, null);
+ }
+ catch (Exception ex)
+ {
+ if (!ex.Message.Contains("----"))
+ throw;
+ }
+
+ privateKey = Encoding.UTF8.GetString(RemoteHandler.DownloadCertificateFile(path + fileName + ".key"));
+ csr = Encoding.UTF8.GetString(RemoteHandler.DownloadCertificateFile(path + fileName + ".csr"));
+ }
+ finally
+ {
+ if (RemoteHandler.DoesFileExist(path + fileName + ".key"))
+ RemoteHandler.RemoveCertificateFile(path, fileName + ".key");
+ if (RemoteHandler.DoesFileExist(path + fileName + ".csr"))
+ RemoteHandler.RemoveCertificateFile(path, fileName + ".csr");
+ }
+
+ return csr;
+ }
+
internal void Initialize(string sudoImpersonatedUser)
{
logger.MethodEntry(LogLevel.Debug);
diff --git a/RemoteFile/RemoteFile.csproj b/RemoteFile/RemoteFile.csproj
index 1ee2cf4e..c2fd7c0b 100644
--- a/RemoteFile/RemoteFile.csproj
+++ b/RemoteFile/RemoteFile.csproj
@@ -6,30 +6,19 @@
true
-
- none
-
-
-
- none
-
-
-
+
-
-
-
-
+
diff --git a/RemoteFile/RemoteHandlers/SSHHandler.cs b/RemoteFile/RemoteHandlers/SSHHandler.cs
index 64668815..dd084048 100644
--- a/RemoteFile/RemoteHandlers/SSHHandler.cs
+++ b/RemoteFile/RemoteHandlers/SSHHandler.cs
@@ -47,7 +47,7 @@ internal SSHHandler(string server, string serverLogin, string serverPassword, bo
try
{
- using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(FormatRSAPrivateKey(serverPassword))))
+ using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(FormatPrivateKey(serverPassword))))
{
privateKeyFile = new PrivateKeyFile(ms);
}
@@ -76,6 +76,9 @@ public override void Initialize()
{
sshClient = new SshClient(Connection);
sshClient.Connect();
+
+ //method call below necessary to check edge condition where password for user id has expired. SCP (and possibly SFTP) download hangs in that scenario
+ CheckConnection();
}
catch (Exception ex)
{
@@ -146,7 +149,7 @@ public override string RunCommand(string commandText, object[] arguments, bool w
catch (Exception ex)
{
_logger.LogError($"Exception during RunCommand...{RemoteFileException.FlattenExceptionMessages(ex, ex.Message)}");
- throw ex;
+ throw;
}
}
@@ -328,18 +331,18 @@ public override void CreateEmptyStoreFile(string path, string linuxFilePermissio
{
_logger.MethodEntry(LogLevel.Debug);
string[] linuxGroupOwner = linuxFileOwner.Split(":");
- string linuxFileGroup = linuxFileOwner;
+ string linuxFileGroup = String.Empty;
if (linuxGroupOwner.Length == 2)
{
linuxFileOwner = linuxGroupOwner[0];
- linuxFileGroup = linuxGroupOwner[1];
+ linuxFileGroup = $"-g {linuxGroupOwner[1]}";
}
if (IsStoreServerLinux)
{
AreLinuxPermissionsValid(linuxFilePermissions);
- RunCommand($"install -m {linuxFilePermissions} -o {linuxFileOwner} -g {linuxFileGroup} /dev/null {path}", null, ApplicationSettings.UseSudo, null);
+ RunCommand($"install -m {linuxFilePermissions} -o {linuxFileOwner} {linuxFileGroup} /dev/null {path}", null, ApplicationSettings.UseSudo, null);
}
else
RunCommand($@"Out-File -FilePath ""{path}""", null, false, null);
@@ -397,12 +400,14 @@ private void SplitStorePathFile(string pathFileName, out string path, out string
_logger.MethodEntry(LogLevel.Debug);
}
- private string FormatRSAPrivateKey(string privateKey)
+ private string FormatPrivateKey(string privateKey)
{
_logger.MethodEntry(LogLevel.Debug);
_logger.MethodExit(LogLevel.Debug);
+
+ String keyType = privateKey.Contains("OPENSSH PRIVATE KEY") ? "OPENSSH" : "RSA";
- return privateKey.Replace(" RSA PRIVATE ", "^^^").Replace(" ", System.Environment.NewLine).Replace("^^^", " RSA PRIVATE ") + System.Environment.NewLine;
+ return privateKey.Replace($" {keyType} PRIVATE ", "^^^").Replace(" ", System.Environment.NewLine).Replace("^^^", $" {keyType} PRIVATE ") + System.Environment.NewLine;
}
private string ConvertToPKCS1(string privateKey)
@@ -431,5 +436,18 @@ private string FormatFTPPath(string path, bool addLeadingSlashForWindows)
return rtnPath;
}
+
+ private void CheckConnection()
+ {
+ try
+ {
+ RunCommand("echo", null, ApplicationSettings.UseSudo, null);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(RemoteFileException.FlattenExceptionMessages(ex, "Error validating server connection."));
+ throw;
+ }
+ }
}
}
diff --git a/RemoteFile/config.json b/RemoteFile/config.json
index 3e638d79..bd69b8a5 100644
--- a/RemoteFile/config.json
+++ b/RemoteFile/config.json
@@ -6,5 +6,5 @@
"SeparateUploadFilePath": "",
"FileTransferProtocol": "SCP",
"DefaultLinuxPermissionsOnStoreCreation": "600",
- "DefaultOwnerOnStoreCreation": ""
+ "DefaultOwnerOnStoreCreation": "",
}
\ No newline at end of file
diff --git a/integration-manifest.json b/integration-manifest.json
index bb423a33..52cb941f 100644
--- a/integration-manifest.json
+++ b/integration-manifest.json
@@ -5,6 +5,7 @@
"status": "production",
"link_github": true,
"update_catalog": true,
+ "support_level": "kf-supported",
"release_dir": "RemoteFile/bin/Release",
"description": "The Remote File Orchestrator allows for the remote management of file-based certificate stores. Discovery, Inventory, and Management functions are supported. The orchestrator performs operations by first converting the certificate store into a BouncyCastle PKCS12Store.",
"about": {
diff --git a/readme_source.md b/readme_source.md
index b77ef7da..a84bf82d 100644
--- a/readme_source.md
+++ b/readme_source.md
@@ -17,7 +17,7 @@ Use cases supported:
RFJKS
-The RFJKS store type can be used to manage java keystores of type JKS. **PLEASE NOTE:** Java keystores of type PKCS12 **_cannot_** be managed by the RFJKS type. You **_must_** use RFPkcs12.
+The RFJKS store type can be used to manage java keystores of types JKS or PKCS12. If creating a new java keystore and adding a certificate all via Keyfactor Command, the created java keystore will be of type PKCS12, as java keystores of type JKS have been deprecated as of JDK 9.
Use cases supported:
1. One-to-many trust entries - A trust entry is considered single certificate without a private key in a certificate store. Each trust entry is identified with a custom alias.
@@ -118,7 +118,10 @@ The version number of a the Remote File Orchestrator Extension can be verified b
2. When orchestrating management of local or external certificate stores, the Remote File Orchestrator Extension makes use of SFTP and/or SCP to transfer files to and from the orchestrated server. SFTP/SCP cannot make use of sudo, so all folders containing certificate stores will need to allow SFTP/SCP file transfer for the user assigned to the certificate store/discovery job. If this is not possible, set the values in the config.json apprpriately to use an alternative upload/download folder that does allow SFTP/SCP file transfer. If the certificate store/discovery job is configured for local (agent) access, the account running the Keyfactor Universal Orchestrator service must have access to read/write to the certificate store location, OR the config.json file must be set up to use the alternative upload/download file.
-3. SSH Key Authentication: When creating a Keyfactor certificate store for the remote file orchestrator extension, you may supply either a user id and password for the certificate store credentials (directly or through one of Keyfactor Command's PAM integrations), or supply a user id and SSH private key. Both PKCS#1 (BEGIN RSA PRIVATE KEY) and PKCS#8 (BEGIN PRIVATE KEY) formats are supported for the SSH private key. If using the normal Keyfactor Command credentials dialog without PAM integration, just copy and paste the full SSH private key into the Password textbox. SSH Key Authentication is not available when running locally as an agent.
+3. SSH Key Authentication: When creating a Keyfactor certificate store for the remote file orchestrator extension, you may supply either a user id and password for the certificate store credentials (directly or through one of Keyfactor Command's PAM integrations), or supply a user id and SSH private key. If using the normal Keyfactor Command credentials dialog without PAM integration, just copy and paste the full SSH private key into the Password textbox. SSH Key Authentication is not available when running locally as an agent. The following private key formats are supported:
+- PKCS#1 (BEGIN RSA PRIVATE KEY)
+- PKCS#8 (BEGIN PRIVATE KEY)
+- ECDSA OPENSSH (BEGIN OPENSSH PRIVATE KEY)
Please reference [Configuration File Setup](#configuration-file-setup) for more information on setting up the config.json file and [Certificate Stores and Discovery Jobs](#certificate-stores-and-discovery-jobs) for more information on the items above.
@@ -227,7 +230,7 @@ The Remote File Orchestrator Extension uses a JSON configuration file. It is lo
DefaultOwnerOnStoreCreation (Applicable for Linux hosted certificate stores only)
-* When a Management job is run to remotely create the physical certificate store on a remote server, by default the file owner and group will be set to the user name associated with the Keyfactor certificate store. Setting DefaultOwnerOnStoreCreation to an alternative valid Linux user name will set that as the owner/group instead. If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please make sure that the user associated with the certificate store will have valid permissions to chown the certificate store file to this alernative owner. The optional "Linux File Owner on Store Creation" custom parameter setting for a specific certificate store can override this value for a specific store. See the [Creating Certificate Store Types](#creating-certificate-store-types) section for more information on creating RemoteFile certificate store types.
+* When a Management job is run to remotely create the physical certificate store on a remote server, by default the file owner and group will be set to the user name associated with the Keyfactor certificate store. Setting DefaultOwnerOnStoreCreation to an alternate valid Linux user name will set that as the owner instead. The owner AND group may be supplied by adding a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Supplying only the ownerId will set that value as the file owner. The group name will default to how the Linux "install" command handles assigning the group. The optional "Linux File Owner on Store Creation" custom parameter setting for a specific certificate store can override this value for a specific store. See the [Creating Certificate Store Types](#creating-certificate-store-types) section for more information on creating RemoteFile certificate store types.
* Allowed values - Any valid user id that the destination Linux server will recognize
* Default Value - blank (the ID associated with the Keyfactor certificate store will be used).
@@ -263,7 +266,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- Entry Parameters Tab:
@@ -297,7 +300,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- Entry Parameters Tab:
@@ -331,7 +334,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- **Name:** IsTrustStore, **Display Name:** Trust Store, **Type:** Bool, **Default Value:** false. This custom field is **not required**. Default value if not present is 'false'. If 'true', this store will be identified as a trust store. Any certificates attempting to be added via a Management-Add job that contain a private key will raise an error with an accompanying message. Multiple certificates may be added to the store in this use case. If set to 'false', this store can only contain a single certificate with chain and private key. Management-Add jobs attempting to add a certificate without a private key to a store marked as IsTrustStore = 'false' will raise an error with an accompanying message.
- **Name:** IncludesChain, **Display Name:** Store Includes Chain, **Type:** Bool, **Default Value:** false. This custom field is **not required**. Default value if not present is 'false'. If 'true' the full certificate chain, if sent by Keyfactor Command, will be stored in the file. The order of appearance is always assumed to be 1) end entity certificate, 2) issuing CA certificate, and 3) root certificate. If additional CA tiers are applicable, the order will be end entity certificate up to the root CA certificate. if set to 'false', only the end entity certificate and private key will be stored in this store. This setting is only valid when IsTrustStore = false.
@@ -370,7 +373,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- **Name:** SeparatePrivateKeyFilePath, **Display Name:** Separate Private Key File Location, **Type:** String, **Default Value:** empty. This custom field is **not required**. If empty, or not provided, it will be assumed that there is no private key associated with this DER store. If the full path AND file name is entered here, that location will be used to store the private key as an external file in DER format.
@@ -405,7 +408,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- Entry Parameters Tab:
@@ -439,7 +442,7 @@ Below are the various certificate store types that the RemoteFile Orchestator Ex
- Custom Fields Tab:
- **Name:** LinuxFilePermissionsOnStoreCreation, **Display Name:** Linux File Permissions on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultLinuxPermissionsOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, must be 3 digits all between 0-7. This represents the Linux file permissions that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y".
- - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner/group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group and owner need to be different values, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. Please confirm that the user name associated with this Keyfactor certificate store has valid permissions to chown the certificate file to this owner.
+ - **Name:** LinuxFileOwnerOnStoreCreation, **Display Name:** Linux File Owner on Store Creation, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultOwnerOnStoreCreation setting in config.json (see Configuration File Setup section above). This value, applicable to certificate stores hosted on Linux orchestrated servers only, represents the alternate Linux file owner:group that will be set for this certificate store if created via a Management Create job or a Management Add job where the config.json option CreateStoreOnAddIsMissing is set to "Y". If the group needs to be set as well, use a ":" as a delimitter between the owner and group values, such as ownerId:groupId. If the group is NOT supplied, the group value will be set per normal behavior of the Linux "Install" command.
- **Name:** SudoImpersonatedUser, **Display Name:** Sudo Impersonated User Id, **Type:** String, **Default Value:** none. This custom field is **not required**. If not present, value reverts back to the DefaultSudoImpersonatedUser setting in config.json (see Configuration File Setup section above). Used in conjunction with UseSudo="Y", this optional setting can be used to set an alternate user id you wish to impersonate with sudo. If this option does not exist or is empty, and nothing is set for DefaultSudoImpersonatedUser in your config.json, the default user of "root" will be used. Any user id used here must have permissions to SCP/SFTP files to/from each certificate store location OR the SeparateUploadFilePath (see Configuration File Setup section above) as well as permissions to execute the commands listed in the "Security Considerations" section above.
- **Name:** WorkFolder, **Display Name:** Work Folder, **Type:** String, **Default Value:** empty. This custom field is **required**. This required field should contain the path on the managed server where temporary work files can be created during Inventory and Management jobs. These files will be removed at the end of each job Please make sure that user id you have assigned to this certificate store will have access to create, modify, and delete files from this folder.