Skip to content

Commit 9c00853

Browse files
leefine02leefine02
authored andcommitted
1 parent d97f980 commit 9c00853

File tree

7 files changed

+180
-187
lines changed

7 files changed

+180
-187
lines changed

RemoteFile/InventoryBase.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@
88
using System;
99
using System.Collections.Generic;
1010
using System.Linq;
11-
using System.Security.Cryptography.X509Certificates;
1211

1312
using Keyfactor.Orchestrators.Extensions;
1413
using Keyfactor.Orchestrators.Common.Enums;
1514
using Keyfactor.Logging;
1615
using Keyfactor.Extensions.Orchestrator.RemoteFile.Models;
16+
using Keyfactor.PKI.Extensions;
1717

1818
using Microsoft.Extensions.Logging;
1919
using Newtonsoft.Json;
20+
using Org.BouncyCastle.Pkcs;
21+
using System.Security.Cryptography.X509Certificates;
22+
using Keyfactor.PKI.X509;
2023

2124
namespace Keyfactor.Extensions.Orchestrator.RemoteFile
2225
{
@@ -41,29 +44,29 @@ public JobResult ProcessJob(InventoryJobConfiguration config, SubmitInventoryUpd
4144
certificateStore.Initialize(SudoImpersonatedUser, UseShellCommands);
4245
certificateStore.LoadCertificateStore(certificateStoreSerializer, true);
4346

44-
List<X509Certificate2Collection> collections = certificateStore.GetCertificateChains();
47+
List<X509CertificateEntryCollection> collection = certificateStore.GetCertificateChains();
4548

4649
logger.LogDebug($"Format returned certificates BEGIN");
47-
foreach (X509Certificate2Collection collection in collections)
50+
foreach (X509CertificateEntryCollection entry in collection)
4851
{
49-
if (collection.Count == 0)
52+
if (entry.CertificateChain?.Count > 1)
5053
continue;
5154

52-
X509Certificate2Ext issuedCertificate = (X509Certificate2Ext)collection[0];
55+
X509CertificateEntry issuedCertificate = entry.CertificateChain[0];
5356

5457
List<string> certChain = new List<string>();
55-
foreach (X509Certificate2 certificate in collection)
58+
foreach (X509CertificateEntry certificateEntry in entry.CertificateChain)
5659
{
57-
certChain.Add(Convert.ToBase64String(certificate.Export(X509ContentType.Cert)));
58-
logger.LogDebug(Convert.ToBase64String(certificate.Export(X509ContentType.Cert)));
60+
CertificateConverter converter = CertificateConverterFactory.FromBouncyCastleCertificate(certificateEntry.Certificate);
61+
certChain.Add(converter.ToPEM(false));
5962
}
60-
63+
6164
inventoryItems.Add(new CurrentInventoryItem()
6265
{
6366
ItemStatus = OrchestratorInventoryItemStatus.Unknown,
64-
Alias = string.IsNullOrEmpty(issuedCertificate.FriendlyNameExt) ? issuedCertificate.Thumbprint : issuedCertificate.FriendlyNameExt,
65-
PrivateKeyEntry = issuedCertificate.HasPrivateKey,
66-
UseChainLevel = collection.Count > 1,
67+
Alias = string.IsNullOrEmpty(entry.Alias) ? BouncyCastleX509Extensions.Thumbprint(issuedCertificate.Certificate) : entry.Alias,
68+
PrivateKeyEntry = entry.HasPrivateKey,
69+
UseChainLevel = entry.CertificateChain.Count > 1,
6770
Certificates = certChain.ToArray()
6871
});
6972
}

RemoteFile/ManagementBase.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@
66
// and limitations under the License.
77

88
using System;
9-
using System.Collections.Generic;
10-
using System.Security.Cryptography.X509Certificates;
119

1210
using Keyfactor.Logging;
1311
using Keyfactor.Orchestrators.Extensions;
1412
using Keyfactor.Orchestrators.Common.Enums;
13+
using Keyfactor.PKI.Extensions;
14+
15+
using Org.BouncyCastle.X509;
1516

1617
using Microsoft.Extensions.Logging;
1718

1819
using Newtonsoft.Json;
20+
using Org.BouncyCastle.Pkcs;
21+
using System.IO;
1922

2023
namespace Keyfactor.Extensions.Orchestrator.RemoteFile
2124
{
@@ -28,7 +31,7 @@ public abstract class ManagementBase : RemoteFileJobTypeBase, IManagementJobExte
2831
public JobResult ProcessJob(ManagementJobConfiguration config)
2932
{
3033
ILogger logger = LogHandler.GetClassLogger(this.GetType());
31-
34+
3235
ICertificateStoreSerializer certificateStoreSerializer = GetCertificateStoreSerializer(config.CertificateStoreDetails.Properties);
3336

3437
try
@@ -52,7 +55,17 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
5255
throw new RemoteFileException($"Certificate store {config.CertificateStoreDetails.StorePath} does not exist on server {config.CertificateStoreDetails.ClientMachine}.");
5356
}
5457
certificateStore.LoadCertificateStore(certificateStoreSerializer, false);
55-
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, RemoveRootCertificate);
58+
59+
using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(config.JobCertificate.Contents)))
60+
{
61+
Pkcs12StoreBuilder storeBuilder = new Pkcs12StoreBuilder();
62+
Pkcs12Store store = storeBuilder.Build();
63+
64+
store.Load(ms, config.JobCertificate.PrivateKeyPassword.ToCharArray());
65+
66+
store.Aliases[0]
67+
}
68+
certificateStore.AddCertificate((config.JobCertificate.Alias ?? new X509Certificate(), config.JobCertificate.Contents, config.Overwrite, config.JobCertificate.PrivateKeyPassword, RemoveRootCertificate);
5669
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, StorePassword, certificateStore.RemoteHandler));
5770

5871
logger.LogDebug($"END add Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");

RemoteFile/Models/SerializedStoreInfo.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
66
// and limitations under the License.
77

8-
using System.Security.Cryptography.X509Certificates;
9-
108
namespace Keyfactor.Extensions.Orchestrator.RemoteFile.Models
119
{
1210
internal class SerializedStoreInfo
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
// Copyright 2021 Keyfactor
1+
// Copyright 2021 Keyfactor
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
33
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
44
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
55
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
66
// and limitations under the License.
77

8-
using System.Security.Cryptography.X509Certificates;
8+
using Org.BouncyCastle.Pkcs;
9+
using System.Collections.Generic;
910

1011
namespace Keyfactor.Extensions.Orchestrator.RemoteFile.Models
1112
{
12-
class X509Certificate2Ext : X509Certificate2
13+
internal class X509CertificateEntryCollection
1314
{
14-
public string FriendlyNameExt { get; set; }
15+
public string Alias { get; set; }
1516

16-
public new bool HasPrivateKey { get; set; }
17+
public bool HasPrivateKey { get; set; }
1718

18-
public X509Certificate2Ext(byte[] bytes): base(bytes) { }
19+
public List<X509CertificateEntry> CertificateChain { get; set; }
1920
}
20-
}
21+
}

RemoteFile/ReenrollmentBase.cs

Lines changed: 68 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,13 @@
77

88
using System;
99
using System.Collections.Generic;
10-
using System.Security.Cryptography.X509Certificates;
1110

1211
using Keyfactor.Logging;
1312
using Keyfactor.Orchestrators.Extensions;
1413
using Keyfactor.Orchestrators.Common.Enums;
15-
using Keyfactor.PKI.PEM;
1614

1715
using Microsoft.Extensions.Logging;
1816

19-
using Newtonsoft.Json;
20-
using System.Security.Cryptography;
21-
2217
namespace Keyfactor.Extensions.Orchestrator.RemoteFile
2318
{
2419
public abstract class ReenrollmentBase : RemoteFileJobTypeBase
@@ -46,74 +41,74 @@ public JobResult ProcessJobToDo(ReenrollmentJobConfiguration config, SubmitReenr
4641
{
4742
ILogger logger = LogHandler.GetClassLogger(this.GetType());
4843

49-
ICertificateStoreSerializer certificateStoreSerializer = GetCertificateStoreSerializer(config.CertificateStoreDetails.Properties);
50-
51-
try
52-
{
53-
SetJobProperties(config, config.CertificateStoreDetails, logger);
54-
55-
string alias = "abcd";
56-
string sans = "reenroll2.Keyfactor.com&reenroll1.keyfactor.com&reenroll3.Keyfactor.com";
57-
bool overwrite = true;
58-
59-
// validate parameters
60-
string KeyTypes = string.Join(",", Enum.GetNames(typeof(SupportedKeyTypeEnum)));
61-
if (!Enum.TryParse(KeyType.ToUpper(), out SupportedKeyTypeEnum KeyTypeEnum))
62-
{
63-
throw new RemoteFileException($"Unsupported KeyType value {KeyType}. Supported types are {KeyTypes}.");
64-
}
65-
66-
ApplicationSettings.FileTransferProtocolEnum fileTransferProtocol = ApplicationSettings.FileTransferProtocol;
67-
68-
certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, UserName, UserPassword, config.CertificateStoreDetails.StorePath, StorePassword, fileTransferProtocol, SSHPort, IncludePortInSPN);
69-
certificateStore.Initialize(SudoImpersonatedUser, UseShellCommands);
70-
71-
PathFile storePathFile = RemoteCertificateStore.SplitStorePathFile(config.CertificateStoreDetails.StorePath);
72-
73-
if (!certificateStore.DoesStoreExist())
74-
{
75-
throw new RemoteFileException($"Certificate store {config.CertificateStoreDetails.StorePath} does not exist on server {config.CertificateStoreDetails.ClientMachine}.");
76-
}
77-
78-
// generate CSR and call back to enroll certificate
79-
string csr = string.Empty;
80-
string pemPrivateKey = string.Empty;
81-
if (CreateCSROnDevice)
82-
{
83-
csr = certificateStore.GenerateCSROnDevice(SubjectText, KeyTypeEnum, KeySize, new List<string>(sans.Split('&', StringSplitOptions.RemoveEmptyEntries)), out pemPrivateKey);
84-
}
85-
else
86-
{
87-
csr = certificateStore.GenerateCSR(SubjectText, KeyTypeEnum, KeySize, new List<string>(sans.Split('&', StringSplitOptions.RemoveEmptyEntries)));
88-
}
89-
90-
X509Certificate2 cert = submitReenrollment.Invoke(csr);
91-
if (cert == null || String.IsNullOrEmpty(pemPrivateKey))
92-
throw new RemoteFileException("Enrollment of CSR failed. Please check Keyfactor Command logs for more information on potential enrollment errors.");
93-
94-
AsymmetricAlgorithm alg = KeyTypeEnum == SupportedKeyTypeEnum.RSA ? RSA.Create() : ECDsa.Create();
95-
alg.ImportEncryptedPkcs8PrivateKey(string.Empty, Keyfactor.PKI.PEM.PemUtilities.PEMToDER(pemPrivateKey), out _);
96-
cert = KeyTypeEnum == SupportedKeyTypeEnum.RSA ? cert.CopyWithPrivateKey((RSA)alg) : cert.CopyWithPrivateKey((ECDsa)alg);
97-
98-
// save certificate
99-
certificateStore.LoadCertificateStore(certificateStoreSerializer, false);
100-
certificateStore.AddCertificate((alias ?? cert.Thumbprint), Convert.ToBase64String(cert.Export(X509ContentType.Pfx)), overwrite, null, RemoveRootCertificate);
101-
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, StorePassword, certificateStore.RemoteHandler));
102-
103-
logger.LogDebug($"END add Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");
104-
}
105-
106-
catch (Exception ex)
107-
{
108-
string errorMessage = $"Exception for {config.Capability}: {RemoteFileException.FlattenExceptionMessages(ex, string.Empty)} for job id {config.JobId}";
109-
logger.LogError(errorMessage);
110-
return new JobResult() { Result = OrchestratorJobStatusJobResult.Failure, JobHistoryId = config.JobHistoryId, FailureMessage = $"Site {config.CertificateStoreDetails.StorePath} on server {config.CertificateStoreDetails.ClientMachine}: {errorMessage}" };
111-
}
112-
finally
113-
{
114-
if (certificateStore.RemoteHandler != null)
115-
certificateStore.Terminate();
116-
}
44+
//ICertificateStoreSerializer certificateStoreSerializer = GetCertificateStoreSerializer(config.CertificateStoreDetails.Properties);
45+
46+
//try
47+
//{
48+
// SetJobProperties(config, config.CertificateStoreDetails, logger);
49+
50+
// string alias = "abcd";
51+
// string sans = "reenroll2.Keyfactor.com&reenroll1.keyfactor.com&reenroll3.Keyfactor.com";
52+
// bool overwrite = true;
53+
54+
// // validate parameters
55+
// string KeyTypes = string.Join(",", Enum.GetNames(typeof(SupportedKeyTypeEnum)));
56+
// if (!Enum.TryParse(KeyType.ToUpper(), out SupportedKeyTypeEnum KeyTypeEnum))
57+
// {
58+
// throw new RemoteFileException($"Unsupported KeyType value {KeyType}. Supported types are {KeyTypes}.");
59+
// }
60+
61+
// ApplicationSettings.FileTransferProtocolEnum fileTransferProtocol = ApplicationSettings.FileTransferProtocol;
62+
63+
// certificateStore = new RemoteCertificateStore(config.CertificateStoreDetails.ClientMachine, UserName, UserPassword, config.CertificateStoreDetails.StorePath, StorePassword, fileTransferProtocol, SSHPort, IncludePortInSPN);
64+
// certificateStore.Initialize(SudoImpersonatedUser, UseShellCommands);
65+
66+
// PathFile storePathFile = RemoteCertificateStore.SplitStorePathFile(config.CertificateStoreDetails.StorePath);
67+
68+
// if (!certificateStore.DoesStoreExist())
69+
// {
70+
// throw new RemoteFileException($"Certificate store {config.CertificateStoreDetails.StorePath} does not exist on server {config.CertificateStoreDetails.ClientMachine}.");
71+
// }
72+
73+
// // generate CSR and call back to enroll certificate
74+
// string csr = string.Empty;
75+
// string pemPrivateKey = string.Empty;
76+
// if (CreateCSROnDevice)
77+
// {
78+
// csr = certificateStore.GenerateCSROnDevice(SubjectText, KeyTypeEnum, KeySize, new List<string>(sans.Split('&', StringSplitOptions.RemoveEmptyEntries)), out pemPrivateKey);
79+
// }
80+
// else
81+
// {
82+
// csr = certificateStore.GenerateCSR(SubjectText, KeyTypeEnum, KeySize, new List<string>(sans.Split('&', StringSplitOptions.RemoveEmptyEntries)));
83+
// }
84+
85+
// X509Certificate2 cert = submitReenrollment.Invoke(csr);
86+
// if (cert == null || String.IsNullOrEmpty(pemPrivateKey))
87+
// throw new RemoteFileException("Enrollment of CSR failed. Please check Keyfactor Command logs for more information on potential enrollment errors.");
88+
89+
// AsymmetricAlgorithm alg = KeyTypeEnum == SupportedKeyTypeEnum.RSA ? RSA.Create() : ECDsa.Create();
90+
// alg.ImportEncryptedPkcs8PrivateKey(string.Empty, Keyfactor.PKI.PEM.PemUtilities.PEMToDER(pemPrivateKey), out _);
91+
// cert = KeyTypeEnum == SupportedKeyTypeEnum.RSA ? cert.CopyWithPrivateKey((RSA)alg) : cert.CopyWithPrivateKey((ECDsa)alg);
92+
93+
// // save certificate
94+
// certificateStore.LoadCertificateStore(certificateStoreSerializer, false);
95+
// certificateStore.AddCertificate((alias ?? cert.Thumbprint), Convert.ToBase64String(cert.Export(X509ContentType.Pfx)), overwrite, null, RemoveRootCertificate);
96+
// certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, StorePassword, certificateStore.RemoteHandler));
97+
98+
// logger.LogDebug($"END add Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");
99+
//}
100+
101+
//catch (Exception ex)
102+
//{
103+
// string errorMessage = $"Exception for {config.Capability}: {RemoteFileException.FlattenExceptionMessages(ex, string.Empty)} for job id {config.JobId}";
104+
// logger.LogError(errorMessage);
105+
// return new JobResult() { Result = OrchestratorJobStatusJobResult.Failure, JobHistoryId = config.JobHistoryId, FailureMessage = $"Site {config.CertificateStoreDetails.StorePath} on server {config.CertificateStoreDetails.ClientMachine}: {errorMessage}" };
106+
//}
107+
//finally
108+
//{
109+
// if (certificateStore.RemoteHandler != null)
110+
// certificateStore.Terminate();
111+
//}
117112

118113
logger.LogDebug($"...End {config.Capability} job for job id {config.JobId}");
119114
return new JobResult() { Result = OrchestratorJobStatusJobResult.Success, JobHistoryId = config.JobHistoryId };

0 commit comments

Comments
 (0)