Skip to content

Commit 7126605

Browse files
authored
Add new field (#40)
* Add new custom field
1 parent f5d4202 commit 7126605

15 files changed

+37
-18
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
v2.4.0
2-
- Do not require store password for PEM inventory
2+
- Add new optional custom parameter, IgnorePrivateKeyOnInventory, for RFPEM, which will allow inventorying RFPEM certificate stores where the store password is unknown. This will make the store INVENTORY ONLY. Once the store password is added, this option can be de-selected (set to False), inventory can be run again, and then renewing/removing the certificate will be allowed.
3+
- Bug fix: Discovery "Directories to Ignore" field not being used to filter results
34

45
v2.3.1
56
- Bug fix: Discovery - ignore /proc folder for Linux servers

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ Use cases supported:
292292
- **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.
293293
- **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 the private key for the certificate stored in this file will be inside the same file as the certificate. If the full path AND file name is put here, that location will be used to store the private key as an external file. This setting is only valid when IsTrustStore = false.
294294
- **Name:** IsRSAPrivateKey, **Display Name:** Is RSA Private Key, **Type:** Bool, **Default Value:** false. This custom field is **not required**. Default value if not present is 'false'. If 'true' it will be assumed that the private key for the certificate is a PKCS#1 RSA formatted private key (BEGIN RSA PRIVATE KEY). If 'false' (default), encrypted/non-encrypted PKCS#8 (BEGIN [ENCRYPTED] PRIVATE KEY) is assumed If set to 'true' the store password **must** be set to "no password", as PKCS#1 does not support encrypted keys. This setting is only valid when IsTrustStore = false.
295+
- **Name:** IgnorePrivateKeyOnInventory, **Display Name:** Ignore Private Key On Inventory, **Type:** Bool, **Default Value:** false. This custom field is **not required**. Default value if not present is 'false'. If 'true', inventory for this certificate store will be performed without accessing the certificate's private key or the store password. This will functionally make the store INVENTORY ONLY, as all certificates will be returned with "Private Key Entry" = false. Also, no certificate chain relationships will be maintained, and all certificates will be considered separate entries (basically a trust store). This may be useful in situations where the client does not know the store password at inventory run time, but would still like the certificates to be imported into Keyfactor Command. Once the correct store password is entered for the store, the client may de-select this option (change the value to False), schedule an inventory job, and then the appropriate private key entry and chain information should be properly stored in the Keyfactor Command location, allowing for renewal/removal of the certificate at a later time.
295296

296297
Entry Parameters Tab:
297298
- no additional entry parameters
@@ -401,7 +402,10 @@ Steps to create a new supported file based certificate store type:
401402
1. Clone this repository from GitHub
402403
2. Open the .net core solution in the IDE of your choice
403404
3. Under the ImplementationStoreTypes folder, create a new folder named for the new certificate store type
404-
4. Create a new class (with namespace of Keyfactor.Extensions.Orchestrator.RemoteFile.{NewType}) in the new folder that will implement ICertificateStoreSerializer. By convention, {StoreTypeName}CertificateSerializer would be a good choice for the class name. This interface requires you to implement two methods: DesrializeRemoteCertificateStore and SerializeRemoteCertificateStore. The first method will be called passing in a byte array containing the contents of file based store you are managing. The developer will need to convert that to an Org.BouncyCastle.Pkcs.Pkcs12Store class and return it. The second method takes in an Org.BouncyCastle.Pkcs.Pkcs12Store and converts it to a collection of custom file representations, List<SerializedStoreInfo>. This is where the majority of the development will be done.
405+
4. Create a new class (with namespace of Keyfactor.Extensions.Orchestrator.RemoteFile.{NewType}) in the new folder that will implement ICertificateStoreSerializer. By convention, {StoreTypeName}CertificateSerializer would be a good choice for the class name. This interface requires you to implement three methods:
406+
- DesrializeRemoteCertificateStore - This method takes in a byte array containing the contents of file based store you are managing. The developer will need to convert that to an Org.BouncyCastle.Pkcs.Pkcs12Store class and return it.
407+
- SerializeRemoteCertificateStore - This method takes in an Org.BouncyCastle.Pkcs.Pkcs12Store and converts it to a collection of custom file representations.
408+
- GetPrivateKeyPath - This method returns the location of the external private key file for single certificate stores. Currently this is only used for RFPEM, and all other implementations return NULL for this method. If this is not applicable to your implementation just return a NULL value for this method.
405409
5. Create an Inventory.cs class (with namespace of Keyfactor.Extensions.Orchestrator.RemoteFile.{NewType}) under the new folder and have it inherit InventoryBase. Override the internal GetCertificateStoreSerializer() method with a one line implementation returning a new instantiation of the class created in step 4.
406410
6. Create a Management.cs class (with namespace of Keyfactor.Extensions.Orchestrator.RemoteFile.{NewType}) under the new folder and have it inherit ManagementBase. Override the internal GetCertificateStoreSerializer() method with a one line implementation returning a new instantiation of the class created in step 4.
407411
7. Modify the manifest.json file to add three new sections (for Inventory, Management, and Discovery). Make sure for each, the "NewType" in Certstores.{NewType}.{Operation}, matches what you will use for the certificate store type short name in Keyfactor Command. On the "TypeFullName" line for all three sections, make sure the namespace matches what you used for your new classes. Note that the namespace for Discovery uses a common class for all supported types. Discovery is a common implementation for all supported store types.

RemoteFile/Discovery.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public JobResult ProcessJob(DiscoveryJobConfiguration config, SubmitDiscoveryUpd
6969
locations = certificateStore.FindStores(directoriesToSearch, extensionsToSearch, filesTosearch, includeSymLinks);
7070
foreach (string ignoredDir in ignoredDirs)
7171
{
72-
locations = locations.Where(p => !p.StartsWith(ignoredDir) || !p.ToLower().StartsWith("find:")).ToList();
72+
locations = locations.Where(p => !p.StartsWith(ignoredDir) && !p.ToLower().StartsWith("find:")).ToList();
7373
}
7474
}
7575
catch (Exception ex)

RemoteFile/ICertificateStoreSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace Keyfactor.Extensions.Orchestrator.RemoteFile
1414
{
1515
interface ICertificateStoreSerializer
1616
{
17-
Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContents, string storePath, string storePassword, IRemoteHandler remoteHandler, bool includePrivateKey);
17+
Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContents, string storePath, string storePassword, IRemoteHandler remoteHandler, bool isInventory);
1818

1919
List<SerializedStoreInfo> SerializeRemoteCertificateStore(Pkcs12Store certificateStore, string storePath, string storeFileName, string storePassword, IRemoteHandler remoteHandler);
2020

RemoteFile/ImplementedStoreTypes/DER/DERCertificateStoreSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public DERCertificateStoreSerializer(string storeProperties)
3838
LoadCustomProperties(storeProperties);
3939
}
4040

41-
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, string storePath, string storePassword, IRemoteHandler remoteHandler, bool includePrivateKey)
41+
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, string storePath, string storePassword, IRemoteHandler remoteHandler, bool isInventory)
4242
{
4343
logger.MethodEntry(LogLevel.Debug);
4444

RemoteFile/ImplementedStoreTypes/JKS/JKSCertificateStoreSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public JKSCertificateStoreSerializer(string storeProperties)
3030
logger = LogHandler.GetClassLogger(this.GetType());
3131
}
3232

33-
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContents, string storePath, string storePassword, IRemoteHandler remoteHandler, bool includePrivateKey)
33+
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContents, string storePath, string storePassword, IRemoteHandler remoteHandler, bool isInventory)
3434
{
3535
logger.MethodEntry(LogLevel.Debug);
3636

RemoteFile/ImplementedStoreTypes/KDB/KDBCertificateStoreSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public KDBCertificateStoreSerializer(string storeProperties)
2828
logger = LogHandler.GetClassLogger(this.GetType());
2929
}
3030

31-
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, string storePath, string storePassword, IRemoteHandler remoteHandler, bool includePrivateKey)
31+
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, string storePath, string storePassword, IRemoteHandler remoteHandler, bool isInventory)
3232
{
3333
logger.MethodEntry(LogLevel.Debug);
3434

RemoteFile/ImplementedStoreTypes/OraWlt/OraWltCertificateStoreSerializer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public OraWltCertificateStoreSerializer(string storeProperties)
3434
LoadCustomProperties(storeProperties);
3535
}
3636

37-
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, string storePath, string storePassword, IRemoteHandler remoteHandler, bool includePrivateKey)
37+
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, string storePath, string storePassword, IRemoteHandler remoteHandler, bool isInventory)
3838
{
3939
logger.MethodEntry(LogLevel.Debug);
4040

@@ -57,7 +57,7 @@ public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, s
5757
jksStore.Load(new MemoryStream(storeBytes), string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
5858

5959
JKSCertificateStoreSerializer serializer = new JKSCertificateStoreSerializer(String.Empty);
60-
store = serializer.DeserializeRemoteCertificateStore(storeBytes, $"{WorkFolder}{tempStoreFileJKS}", storePassword, remoteHandler, includePrivateKey);
60+
store = serializer.DeserializeRemoteCertificateStore(storeBytes, $"{WorkFolder}{tempStoreFileJKS}", storePassword, remoteHandler, isInventory);
6161
}
6262
catch (Exception ex)
6363
{

RemoteFile/ImplementedStoreTypes/PEM/PEMCertificateStoreSerializer.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class PEMCertificateStoreSerializer : ICertificateStoreSerializer
4040
private bool IncludesChain { get; set; }
4141
private string SeparatePrivateKeyFilePath { get; set; }
4242
private bool IsRSAPrivateKey { get; set; }
43+
private bool IgnorePrivateKeyOnInventory { get; set; }
4344

4445
private ILogger logger;
4546

@@ -49,7 +50,7 @@ public PEMCertificateStoreSerializer(string storeProperties)
4950
LoadCustomProperties(storeProperties);
5051
}
5152

52-
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, string storePath, string storePassword, IRemoteHandler remoteHandler, bool includePrivateKey)
53+
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, string storePath, string storePassword, IRemoteHandler remoteHandler, bool isInventory)
5354
{
5455
logger.MethodEntry(LogLevel.Debug);
5556

@@ -62,7 +63,7 @@ public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, s
6263
string storeContents = Encoding.ASCII.GetString(storeContentBytes);
6364
X509CertificateEntry[] certificates = GetCertificates(storeContents);
6465

65-
if (IsTrustStore || !includePrivateKey)
66+
if (IsTrustStore || (isInventory && IgnorePrivateKeyOnInventory))
6667
{
6768
foreach(X509CertificateEntry certificate in certificates)
6869
{
@@ -185,6 +186,7 @@ private void LoadCustomProperties(string storeProperties)
185186
IncludesChain = properties.IncludesChain == null || string.IsNullOrEmpty(properties.IncludesChain.Value) ? false : bool.Parse(properties.IncludesChain.Value);
186187
SeparatePrivateKeyFilePath = properties.SeparatePrivateKeyFilePath == null || string.IsNullOrEmpty(properties.SeparatePrivateKeyFilePath.Value) ? String.Empty : properties.SeparatePrivateKeyFilePath.Value;
187188
IsRSAPrivateKey = properties.IsRSAPrivateKey == null || string.IsNullOrEmpty(properties.IsRSAPrivateKey.Value) ? false : bool.Parse(properties.IsRSAPrivateKey.Value);
189+
IgnorePrivateKeyOnInventory = properties.IgnorePrivateKeyOnInventory == null || string.IsNullOrEmpty(properties.IgnorePrivateKeyOnInventory.Value) ? false : bool.Parse(properties.IgnorePrivateKeyOnInventory.Value);
188190

189191
logger.MethodExit(LogLevel.Debug);
190192
}

RemoteFile/ImplementedStoreTypes/PKCS12/PKCS12CertificateStoreSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public PKCS12CertificateStoreSerializer(string storeProperties)
2525
logger = LogHandler.GetClassLogger(this.GetType());
2626
}
2727

28-
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContents, string storePath, string storePassword, IRemoteHandler remoteHandler, bool includePrivateKey)
28+
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContents, string storePath, string storePassword, IRemoteHandler remoteHandler, bool isInventory)
2929
{
3030
Pkcs12StoreBuilder storeBuilder = new Pkcs12StoreBuilder();
3131
Pkcs12Store store = storeBuilder.Build();

0 commit comments

Comments
 (0)