Skip to content

Commit 3bc366f

Browse files
authored
Merge 2.7.0 to main (#60)
1 parent 379b747 commit 3bc366f

22 files changed

+541
-97
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
v2.7.0
2+
- Modified RFJKS store type support java keystores of both PKCS12 and JKS
3+
- Added support for OpenSSH private keys for SSH authentication
4+
- Bug fix for orchestrators installed on Windows 2016
5+
- Bug Fix: Supplied Linux user needing password reset could cause orchestrator locking.
6+
- 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.
7+
- Updgraded Nuget packages for BouncyCastle and Renci.SSH.Net
8+
19
v2.6.0
210
- 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.
311
- 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.

README.md

Lines changed: 13 additions & 10 deletions
Large diffs are not rendered by default.

RemoteFile/ApplicationSettings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public enum FileTransferProtocolEnum
3838
public static string DefaultLinuxPermissionsOnStoreCreation { get { return configuration.ContainsKey("DefaultLinuxPermissionsOnStoreCreation") ? configuration["DefaultLinuxPermissionsOnStoreCreation"] : DEFAULT_LINUX_PERMISSION_SETTING; } }
3939
public static string DefaultOwnerOnStoreCreation { get { return configuration.ContainsKey("DefaultOwnerOnStoreCreation") ? configuration["DefaultOwnerOnStoreCreation"] : DEFAULT_OWNER_SETTING; } }
4040
public static string DefaultSudoImpersonatedUser { get { return configuration.ContainsKey("DefaultSudoImpersonatedUser") ? configuration["DefaultSudoImpersonatedUser"] : DEFAULT_SUDO_IMPERSONATION_SETTING; } }
41+
public static bool CreateCSROnDevice { get { return configuration.ContainsKey("CreateCSROnDevice") ? configuration["CreateCSROnDevice"]?.ToUpper() == "Y" : false; } }
42+
public static string TempFilePathForODKG { get { return configuration.ContainsKey("TempFilePathForODKG") ? configuration["TempFilePathForODKG"] : string.Empty; } }
4143
public static FileTransferProtocolEnum FileTransferProtocol
4244
{
4345
get

RemoteFile/Discovery.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace Keyfactor.Extensions.Orchestrator.RemoteFile
2222
public class Discovery: IDiscoveryJobExtension
2323
{
2424
public IPAMSecretResolver _resolver;
25-
public string ExtensionName => "";
25+
public string ExtensionName => "Keyfactor.Extensions.Orchestrator.RemoteFile.Discovery";
2626

2727
public Discovery(IPAMSecretResolver resolver)
2828
{
-909 KB
Binary file not shown.
Binary file not shown.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2021 Keyfactor
2+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
3+
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4+
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
6+
// and limitations under the License.
7+
8+
using Keyfactor.Orchestrators.Extensions.Interfaces;
9+
10+
namespace Keyfactor.Extensions.Orchestrator.RemoteFile.DER
11+
{
12+
public class Reenrollment : ReenrollmentBase
13+
{
14+
internal override ICertificateStoreSerializer GetCertificateStoreSerializer(string storeProperties)
15+
{
16+
return new DERCertificateStoreSerializer(storeProperties);
17+
}
18+
19+
public Reenrollment(IPAMSecretResolver resolver)
20+
{
21+
_resolver = resolver;
22+
}
23+
}
24+
}

RemoteFile/ImplementedStoreTypes/JKS/JKSCertificateStoreSerializer.cs

Lines changed: 75 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Collections.Generic;
1010
using Keyfactor.Extensions.Orchestrator.RemoteFile.RemoteHandlers;
1111
using Keyfactor.Extensions.Orchestrator.RemoteFile.Models;
12+
using Keyfactor.Extensions.Orchestrator.RemoteFile.PKCS12;
1213

1314
using Keyfactor.Logging;
1415

@@ -30,6 +31,8 @@ public JKSCertificateStoreSerializer(string storeProperties)
3031
logger = LogHandler.GetClassLogger(this.GetType());
3132
}
3233

34+
private bool IsTypeJKS { get; set; }
35+
3336
public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContents, string storePath, string storePassword, IRemoteHandler remoteHandler, bool isInventory)
3437
{
3538
logger.MethodEntry(LogLevel.Debug);
@@ -38,42 +41,58 @@ public Pkcs12Store DeserializeRemoteCertificateStore(byte[] storeContents, strin
3841
Pkcs12Store pkcs12Store = storeBuilder.Build();
3942
Pkcs12Store pkcs12StoreNew = storeBuilder.Build();
4043

41-
JksStore jksStore = new JksStore();
42-
4344
using (MemoryStream ms = new MemoryStream(storeContents))
4445
{
45-
jksStore.Load(ms, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
46+
IsTypeJKS = new JksStore().Probe(ms);
4647
}
4748

48-
foreach (string alias in jksStore.Aliases)
49+
if (IsTypeJKS)
4950
{
50-
if (jksStore.IsKeyEntry(alias))
51+
logger.LogDebug("Store is of type JKS");
52+
JksStore jksStore = new JksStore();
53+
54+
using (MemoryStream ms = new MemoryStream(storeContents))
5155
{
52-
AsymmetricKeyParameter keyParam = jksStore.GetKey(alias, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
53-
AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(keyParam);
56+
ms.Position = 0;
57+
jksStore.Load(ms, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
58+
}
5459

55-
X509Certificate[] certificateChain = jksStore.GetCertificateChain(alias);
56-
List<X509CertificateEntry> certificateChainEntries = new List<X509CertificateEntry>();
57-
foreach (X509Certificate certificate in certificateChain)
60+
foreach (string alias in jksStore.Aliases)
61+
{
62+
if (jksStore.IsKeyEntry(alias))
5863
{
59-
certificateChainEntries.Add(new X509CertificateEntry(certificate));
60-
}
64+
AsymmetricKeyParameter keyParam = jksStore.GetKey(alias, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
65+
AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(keyParam);
6166

62-
pkcs12Store.SetKeyEntry(alias, keyEntry, certificateChainEntries.ToArray());
63-
}
64-
else
65-
{
66-
pkcs12Store.SetCertificateEntry(alias, new X509CertificateEntry(jksStore.GetCertificate(alias)));
67+
X509Certificate[] certificateChain = jksStore.GetCertificateChain(alias);
68+
List<X509CertificateEntry> certificateChainEntries = new List<X509CertificateEntry>();
69+
foreach (X509Certificate certificate in certificateChain)
70+
{
71+
certificateChainEntries.Add(new X509CertificateEntry(certificate));
72+
}
73+
74+
pkcs12Store.SetKeyEntry(alias, keyEntry, certificateChainEntries.ToArray());
75+
}
76+
else
77+
{
78+
pkcs12Store.SetCertificateEntry(alias, new X509CertificateEntry(jksStore.GetCertificate(alias)));
79+
}
6780
}
68-
}
6981

70-
// 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
71-
// when processing store.
72-
MemoryStream ms2 = new MemoryStream();
73-
pkcs12Store.Save(ms2, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
74-
ms2.Position = 0;
82+
// 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
83+
// when processing store.
84+
MemoryStream ms2 = new MemoryStream();
85+
pkcs12Store.Save(ms2, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
86+
ms2.Position = 0;
7587

76-
pkcs12StoreNew.Load(ms2, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
88+
pkcs12StoreNew.Load(ms2, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
89+
}
90+
else
91+
{
92+
logger.LogDebug("Store is of type PKCS12");
93+
PKCS12CertificateStoreSerializer pkcs12Serializer = new PKCS12CertificateStoreSerializer(string.Empty);
94+
pkcs12StoreNew = pkcs12Serializer.DeserializeRemoteCertificateStore(storeContents, storePath, storePassword, remoteHandler, isInventory);
95+
}
7796

7897
logger.MethodExit(LogLevel.Debug);
7998
return pkcs12StoreNew;
@@ -83,39 +102,50 @@ public List<SerializedStoreInfo> SerializeRemoteCertificateStore(Pkcs12Store cer
83102
{
84103
logger.MethodEntry(LogLevel.Debug);
85104

86-
JksStore jksStore = new JksStore();
105+
List<SerializedStoreInfo> storeInfo = new List<SerializedStoreInfo>();
87106

88-
foreach (string alias in certificateStore.Aliases)
107+
if (IsTypeJKS)
89108
{
90-
if (certificateStore.IsKeyEntry(alias))
109+
JksStore jksStore = new JksStore();
110+
111+
foreach (string alias in certificateStore.Aliases)
91112
{
92-
AsymmetricKeyEntry keyEntry = certificateStore.GetKey(alias);
93-
X509CertificateEntry[] certificateChain = certificateStore.GetCertificateChain(alias);
113+
if (certificateStore.IsKeyEntry(alias))
114+
{
115+
AsymmetricKeyEntry keyEntry = certificateStore.GetKey(alias);
116+
X509CertificateEntry[] certificateChain = certificateStore.GetCertificateChain(alias);
94117

95-
List<X509Certificate> certificates = new List<X509Certificate>();
96-
foreach (X509CertificateEntry certificateEntry in certificateChain)
118+
List<X509Certificate> certificates = new List<X509Certificate>();
119+
foreach (X509CertificateEntry certificateEntry in certificateChain)
120+
{
121+
certificates.Add(certificateEntry.Certificate);
122+
}
123+
124+
jksStore.SetKeyEntry(alias, keyEntry.Key, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray(), certificates.ToArray());
125+
}
126+
else
97127
{
98-
certificates.Add(certificateEntry.Certificate);
128+
jksStore.SetCertificateEntry(alias, certificateStore.GetCertificate(alias).Certificate);
99129
}
100-
101-
jksStore.SetKeyEntry(alias, keyEntry.Key, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray(), certificates.ToArray());
102130
}
103-
else
131+
132+
using (MemoryStream outStream = new MemoryStream())
104133
{
105-
jksStore.SetCertificateEntry(alias, certificateStore.GetCertificate(alias).Certificate);
134+
jksStore.Save(outStream, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
135+
136+
storeInfo.Add(new SerializedStoreInfo() { FilePath = storePath + storeFileName, Contents = outStream.ToArray() });
137+
138+
logger.MethodExit(LogLevel.Debug);
139+
return storeInfo;
106140
}
107141
}
108-
109-
using (MemoryStream outStream = new MemoryStream())
142+
else
110143
{
111-
jksStore.Save(outStream, string.IsNullOrEmpty(storePassword) ? new char[0] : storePassword.ToCharArray());
112-
113-
List<SerializedStoreInfo> storeInfo = new List<SerializedStoreInfo>();
114-
storeInfo.Add(new SerializedStoreInfo() { FilePath = storePath + storeFileName, Contents = outStream.ToArray() });
115-
116-
logger.MethodExit(LogLevel.Debug);
117-
return storeInfo;
144+
PKCS12CertificateStoreSerializer pkcs12Serializer = new PKCS12CertificateStoreSerializer(string.Empty);
145+
storeInfo = pkcs12Serializer.SerializeRemoteCertificateStore(certificateStore, storePath, storeFileName, storePassword, remoteHandler);
118146
}
147+
148+
return storeInfo;
119149
}
120150

121151
public string GetPrivateKeyPath()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2021 Keyfactor
2+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
3+
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4+
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
6+
// and limitations under the License.
7+
8+
using Keyfactor.Orchestrators.Extensions.Interfaces;
9+
10+
namespace Keyfactor.Extensions.Orchestrator.RemoteFile.JKS
11+
{
12+
public class Reenrollment : ReenrollmentBase
13+
{
14+
internal override ICertificateStoreSerializer GetCertificateStoreSerializer(string storeProperties)
15+
{
16+
return new JKSCertificateStoreSerializer(storeProperties);
17+
}
18+
19+
public Reenrollment(IPAMSecretResolver resolver)
20+
{
21+
_resolver = resolver;
22+
}
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2021 Keyfactor
2+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
3+
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4+
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
6+
// and limitations under the License.
7+
8+
using Keyfactor.Orchestrators.Extensions.Interfaces;
9+
10+
namespace Keyfactor.Extensions.Orchestrator.RemoteFile.KDB
11+
{
12+
public class Reenrollment : ReenrollmentBase
13+
{
14+
internal override ICertificateStoreSerializer GetCertificateStoreSerializer(string storeProperties)
15+
{
16+
return new KDBCertificateStoreSerializer(storeProperties);
17+
}
18+
19+
public Reenrollment(IPAMSecretResolver resolver)
20+
{
21+
_resolver = resolver;
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)