Skip to content

Commit d4399b3

Browse files
leefine02leefine02
authored andcommitted
1 parent c7b59c5 commit d4399b3

File tree

4 files changed

+39
-65
lines changed

4 files changed

+39
-65
lines changed

RemoteFile.UnitTests/RemoteFile.UnitTests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
<ItemGroup>
1212
<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />
13+
<PackageReference Include="Keyfactor.Logging" Version="1.2.0" />
14+
<PackageReference Include="Keyfactor.PKI" Version="8.1.1" />
1315
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
1416
<PackageReference Include="xunit" Version="2.4.1" />
1517
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">

RemoteFile/ImplementedStoreTypes/PEM/PEMCertificateStoreSerializer.cs

Lines changed: 33 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,28 @@
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;
9-
using System.Collections.Generic;
10-
using System.Text;
11-
using System.IO;
12-
13-
using Newtonsoft.Json;
14-
8+
using Keyfactor.Extensions.Orchestrator.RemoteFile.Models;
9+
using Keyfactor.Extensions.Orchestrator.RemoteFile.RemoteHandlers;
1510
using Keyfactor.Logging;
16-
using Keyfactor.PKI.PrivateKeys;
17-
using Keyfactor.PKI.X509;
11+
using Keyfactor.PKI.CryptographicObjects.Formatters;
12+
using Keyfactor.PKI.Extensions;
1813
using Keyfactor.PKI.PEM;
19-
using Keyfactor.Extensions.Orchestrator.RemoteFile.RemoteHandlers;
20-
using Keyfactor.Extensions.Orchestrator.RemoteFile.Models;
21-
14+
using Keyfactor.PKI.PrivateKeys;
2215
using Microsoft.Extensions.Logging;
23-
24-
using Org.BouncyCastle.Math;
16+
using Newtonsoft.Json;
17+
using Org.BouncyCastle.Asn1.X9;
2518
using Org.BouncyCastle.Crypto;
19+
using Org.BouncyCastle.Crypto.Parameters;
20+
using Org.BouncyCastle.Math;
21+
using Org.BouncyCastle.OpenSsl;
2622
using Org.BouncyCastle.Pkcs;
2723
using Org.BouncyCastle.X509;
24+
using System;
25+
using System.Collections.Generic;
26+
using System.IO;
27+
using System.Linq;
2828
using System.Security.Cryptography;
29-
using Org.BouncyCastle.OpenSsl;
30-
using Org.BouncyCastle.Crypto.Parameters;
31-
using Org.BouncyCastle.Asn1.X9;
29+
using System.Text;
3230

3331
namespace Keyfactor.Extensions.Orchestrator.RemoteFile.PEM
3432
{
@@ -37,8 +35,6 @@ class PEMCertificateStoreSerializer : ICertificateStoreSerializer
3735
string[] PrivateKeyDelimetersPkcs8 = new string[] { "-----BEGIN PRIVATE KEY-----", "-----BEGIN ENCRYPTED PRIVATE KEY-----" };
3836
string[] PrivateKeyDelimetersRSA = new string[] { "-----BEGIN RSA PRIVATE KEY-----" };
3937
string[] PrivateKeyDelimetersEC = new string[] { "-----BEGIN EC PRIVATE KEY-----" };
40-
string CertDelimBeg = "-----BEGIN CERTIFICATE-----";
41-
string CertDelimEnd = "-----END CERTIFICATE-----";
4238

4339
private enum PrivateKeyTypeEnum
4440
{
@@ -74,15 +70,15 @@ public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContentBytes, s
7470
{
7571
foreach(X509CertificateEntry certificate in certificates)
7672
{
77-
store.SetCertificateEntry(CertificateConverterFactory.FromBouncyCastleCertificate(certificate.Certificate).ToX509Certificate2().Thumbprint, certificate);
73+
store.SetCertificateEntry(certificate.Certificate.Thumbprint(), certificate);
7874
}
7975
}
8076
else
8177
{
8278
PrivateKeyTypeEnum privateKeyType;
8379
AsymmetricKeyEntry keyEntry = GetPrivateKey(storeContents, storePassword ?? string.Empty, remoteHandler, out privateKeyType);
8480

85-
store.SetKeyEntry(CertificateConverterFactory.FromBouncyCastleCertificate(certificates[0].Certificate).ToX509Certificate2().Thumbprint, keyEntry, certificates);
81+
store.SetKeyEntry(certificates[0].Certificate.Thumbprint(), keyEntry, certificates);
8682
}
8783

8884
// 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
@@ -113,8 +109,7 @@ public List<SerializedStoreInfo> SerializeRemoteCertificateStore(Pkcs12Store cer
113109
if (certificateStore.IsKeyEntry(alias))
114110
throw new RemoteFileException("Cannot add a certificate with a private key to a PEM trust store.");
115111

116-
CertificateConverter certConverter = CertificateConverterFactory.FromBouncyCastleCertificate(certificateStore.GetCertificate(alias).Certificate);
117-
pemString += certConverter.ToPEM(true);
112+
pemString += CryptographicObjectFormatter.PEM.Format(certificateStore.GetCertificate(alias).Certificate, false);
118113
}
119114
}
120115
else
@@ -140,44 +135,29 @@ public List<SerializedStoreInfo> SerializeRemoteCertificateStore(Pkcs12Store cer
140135
throw new RemoteFileException("No private key found. Private key must be present to add entry to a non-Trust PEM certificate store.");
141136

142137
X509CertificateEntry[] chainEntries = certificateStore.GetCertificateChain(alias);
143-
CertificateConverter certConverter = CertificateConverterFactory.FromBouncyCastleCertificate(chainEntries[0].Certificate);
138+
X509Certificate endCertificate = chainEntries[0].Certificate;
144139

145140
AsymmetricKeyParameter privateKey = certificateStore.GetKey(alias).Key;
146-
AsymmetricKeyParameter publicKey = chainEntries[0].Certificate.GetPublicKey();
141+
PrivateKeyConverter keyConverter = PrivateKeyConverterFactory.FromBCPrivateKeyAndCert(privateKey, endCertificate);
147142

148-
if (privateKeyType == PrivateKeyTypeEnum.PKCS8)
149-
{
150-
PrivateKeyConverter keyConverter = PrivateKeyConverterFactory.FromBCKeyPair(privateKey, publicKey, false);
143+
keyString = CryptographicObjectFormatter.PEM.Format(keyConverter, storePassword);
144+
pemString = string.IsNullOrEmpty(SeparatePrivateKeyFilePath)
145+
? CryptographicObjectFormatter.PEM.Format(endCertificate, keyConverter, storePassword, false)
146+
: CryptographicObjectFormatter.PEM.Format(endCertificate, false);
151147

152-
byte[] privateKeyBytes = string.IsNullOrEmpty(storePassword) ? keyConverter.ToPkcs8BlobUnencrypted() : keyConverter.ToPkcs8Blob(storePassword);
153-
keyString = PemUtilities.DERToPEM(privateKeyBytes, string.IsNullOrEmpty(storePassword) ? PemUtilities.PemObjectType.PrivateKey : PemUtilities.PemObjectType.EncryptedPrivateKey);
154-
}
155-
else
148+
if (!IncludesChain)
156149
{
157-
TextWriter textWriter = new StringWriter();
158-
PemWriter pemWriter = new PemWriter(textWriter);
159-
pemWriter.WriteObject(privateKey);
160-
pemWriter.Writer.Flush();
161-
162-
keyString = textWriter.ToString();
150+
continue;
163151
}
164152

165-
pemString = certConverter.ToPEM(true);
166-
if (string.IsNullOrEmpty(SeparatePrivateKeyFilePath))
167-
pemString += keyString;
168-
169-
if (IncludesChain)
153+
for (int i = 1; i < chainEntries.Length; i++)
170154
{
171-
for (int i = 1; i < chainEntries.Length; i++)
172-
{
173-
CertificateConverter chainConverter = CertificateConverterFactory.FromBouncyCastleCertificate(chainEntries[i].Certificate);
174-
pemString += chainConverter.ToPEM(true);
175-
}
155+
pemString += CryptographicObjectFormatter.PEM.Format(chainEntries[i].Certificate, false);
176156
}
177157
}
178158
}
179159

180-
storeInfo.Add(new SerializedStoreInfo() { FilePath = storePath+storeFileName, Contents = Encoding.ASCII.GetBytes(pemString) });
160+
storeInfo.Add(new SerializedStoreInfo() { FilePath = storePath + storeFileName, Contents = Encoding.ASCII.GetBytes(pemString) });
181161
if (!string.IsNullOrEmpty(SeparatePrivateKeyFilePath))
182162
storeInfo.Add(new SerializedStoreInfo() { FilePath = SeparatePrivateKeyFilePath, Contents = Encoding.ASCII.GetBytes(keyString) });
183163

@@ -215,18 +195,10 @@ private X509CertificateEntry[] GetCertificates(string certificates)
215195

216196
try
217197
{
218-
while (certificates.Contains(CertDelimBeg))
219-
{
220-
int certStart = certificates.IndexOf(CertDelimBeg);
221-
int certLength = certificates.IndexOf(CertDelimEnd) + CertDelimEnd.Length - certStart;
222-
string certificate = certificates.Substring(certStart, certLength);
223-
224-
CertificateConverter c2 = CertificateConverterFactory.FromPEM(Encoding.ASCII.GetBytes(certificate.Replace(CertDelimBeg, string.Empty).Replace(CertDelimEnd, string.Empty)));
225-
X509Certificate bcCert = c2.ToBouncyCastleCertificate();
226-
certificateEntries.Add(new X509CertificateEntry(bcCert));
227-
228-
certificates = certificates.Substring(certStart + certLength - 1);
229-
}
198+
IEnumerable<string> pemCertificates = PemUtilities.SplitCollection(certificates);
199+
certificateEntries.AddRange(pemCertificates.Select(cert =>
200+
new X509CertificateEntry(new X509Certificate(CryptographicObjectFormatter.DER.Format(cert))))
201+
);
230202
}
231203
catch (Exception ex)
232204
{

RemoteFile/ManagementBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
5252
throw new RemoteFileException($"Certificate store {config.CertificateStoreDetails.StorePath} does not exist on server {config.CertificateStoreDetails.ClientMachine}.");
5353
}
5454
certificateStore.LoadCertificateStore(certificateStoreSerializer, false);
55-
certificateStore.AddCertificate((config.JobCertificate.Alias ?? new X509Certificate(), config.JobCertificate.Contents, config.Overwrite, config.JobCertificate.PrivateKeyPassword, RemoveRootCertificate);
55+
certificateStore.AddCertificate(config.JobCertificate.Alias ?? GetThumbprint(config.JobCertificate, logger), config.JobCertificate.Contents, config.Overwrite, config.JobCertificate.PrivateKeyPassword, RemoveRootCertificate);
5656
certificateStore.SaveCertificateStore(certificateStoreSerializer.SerializeRemoteCertificateStore(certificateStore.GetCertificateStore(), storePathFile.Path, storePathFile.File, StorePassword, certificateStore.RemoteHandler));
5757

5858
logger.LogDebug($"END add Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");
@@ -82,7 +82,7 @@ public JobResult ProcessJob(ManagementJobConfiguration config)
8282
}
8383
else
8484
{
85-
CreateStore(certificateStoreSerializer, config);
85+
CreateStore(certificateStoreSerializer, config, logger);
8686
}
8787
logger.LogDebug($"END create Operation for {config.CertificateStoreDetails.StorePath} on {config.CertificateStoreDetails.ClientMachine}.");
8888
break;

RemoteFile/RemoteFile.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
<ItemGroup>
1111
<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />
1212
<PackageReference Include="CliWrap" Version="3.6.6" />
13-
<PackageReference Include="Keyfactor.Logging" Version="1.1.1" />
13+
<PackageReference Include="Keyfactor.Logging" Version="1.2.0" />
1414
<PackageReference Include="Keyfactor.Orchestrators.IOrchestratorJobExtensions" Version="0.7.0" />
15-
<PackageReference Include="Keyfactor.PKI" Version="5.0.0" />
15+
<PackageReference Include="Keyfactor.PKI" Version="8.1.1" />
1616
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.2.12" Condition="'$(TargetFramework)' == 'net6.0'" />
1717
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.4.5" Condition="'$(TargetFramework)' == 'net8.0'" />
1818
<PackageReference Include="SSH.NET" Version="2024.0.0" />

0 commit comments

Comments
 (0)