Skip to content

Commit cb3bd57

Browse files
authored
Release 2.4 to main (#103)
* Initial changes for creating and importing pfx files to accept specific csps. * Added ReEnrollment jobs to WinSQL * Added additional exception handling for SQL Management jobs. Updated the manifest for SQL Reenrollment. * Changed 'MaxAllowed' back to '5' and documented what that value represents. Cleaned up some old code. * Modified how runspaces are created for local machines access . Added code to get the last exit code from certutil to accurately report errors * Added error trapping when attepting to get the last exit code from a remote machine. Microsoft does not allow you to retrieve information from remote computers due to security and architecture. * Added store path and addstore for certs with no private keys * AB#58570 Added additional error trapping and logging. Also modified the certutil logic to use -addstore when no password was provided when adding a certificate.
1 parent 5e12d12 commit cb3bd57

26 files changed

+774
-165
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
2.4.1
2+
* Modified the CertUtil logic to use the -addstore argument when no password is sent with the certificate information.
3+
* Added additional error trapping and trace logs
4+
5+
2.4.0
6+
* Changed the way certificates are added to cert stores. CertUtil is now used to import the PFX certificate into the associated store. The CSP is now considered when maintaining certificates, empty CSP values will result in using the machines default CSP.
7+
* Added the Crypto Service Provider and SAN Entry Parameters to be used on Inventory queries, Adding and ReEnrollments for the WinCert, WinSQL and IISU extensions.
8+
* Changed how Client Machine Names are handled when a 'localhost' connection is desiered. The new naming convention is: {machineName}|localmachine. This will eliminate the issue of unqiue naming conflicts.
9+
* Updated the manifest.json to now include WinSQL ReEnrollment.
10+
* Updated the integration-manifest.json file for new fields in cert store types.
11+
12+
2.3.2
13+
* Changed the Open Cert Store access level from a '5' to 'MaxAllowed'
14+
115
2.3.1
216
* Added additional error trapping for WinRM connections to allow actual error on failure.
317

IISU/Certificate.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
// limitations under the License.
1414

1515
using System;
16+
using System.Linq;
17+
using System.Text.RegularExpressions;
1618

1719
namespace Keyfactor.Extensions.Orchestrator.WindowsCertStore
1820
{
@@ -22,5 +24,35 @@ public class Certificate
2224
public byte[] RawData { get; set; }
2325
public bool HasPrivateKey { get; set; }
2426
public string CertificateData => Convert.ToBase64String(RawData);
27+
public string CryptoServiceProvider { get; set; }
28+
public string SAN { get; set; }
29+
30+
public class Utilities
31+
{
32+
public static string FormatSAN(string san)
33+
{
34+
// Use regular expression to extract key-value pairs
35+
var regex = new Regex(@"(?<key>DNS Name|Email|IP Address)=(?<value>[^=,\s]+)");
36+
var matches = regex.Matches(san);
37+
38+
// Format matches into the desired format
39+
string result = string.Join("&", matches.Cast<Match>()
40+
.Select(m => $"{NormalizeKey(m.Groups["key"].Value)}={m.Groups["value"].Value}"));
41+
42+
return result;
43+
}
44+
45+
private static string NormalizeKey(string key)
46+
{
47+
return key.ToLower() switch
48+
{
49+
"dns name" => "dns",
50+
"email" => "email",
51+
"ip address" => "ip",
52+
_ => key.ToLower() // For other types, keep them as-is
53+
};
54+
}
55+
56+
}
2557
}
2658
}

IISU/CertificateStore.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ public void RemoveCertificate(string thumbprint)
4141
{
4242
using var ps = PowerShell.Create();
4343
ps.Runspace = RunSpace;
44+
45+
// Open with value of 5 means: Open existing only (4) + Open ReadWrite (1)
4446
var removeScript = $@"
4547
$ErrorActionPreference = 'Stop'
4648
$certStore = New-Object System.Security.Cryptography.X509Certificates.X509Store('{StorePath}','LocalMachine')
47-
$certStore.Open('MaxAllowed')
49+
$certStore.Open(5)
4850
$certToRemove = $certStore.Certificates.Find(0,'{thumbprint}',$false)
4951
if($certToRemove.Count -gt 0) {{
5052
$certStore.Remove($certToRemove[0])

IISU/ClientPSCertStoreInventory.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,37 @@ public List<Certificate> GetCertificatesFromStore(Runspace runSpace, string stor
4646
$certs = $certStore.Certificates
4747
$certStore.Close()
4848
$certStore.Dispose()
49-
foreach ( $cert in $certs){{
50-
$cert | Select-Object -Property Thumbprint, RawData, HasPrivateKey
49+
$certs | ForEach-Object {{
50+
$certDetails = @{{
51+
Subject = $_.Subject
52+
Thumbprint = $_.Thumbprint
53+
HasPrivateKey = $_.HasPrivateKey
54+
RawData = $_.RawData
55+
san = $_.Extensions | Where-Object {{ $_.Oid.FriendlyName -eq ""Subject Alternative Name"" }} | ForEach-Object {{ $_.Format($false) }}
56+
}}
57+
58+
if ($_.HasPrivateKey) {{
59+
$certDetails.CSP = $_.PrivateKey.CspKeyContainerInfo.ProviderName
60+
}}
61+
62+
New-Object PSObject -Property $certDetails
5163
}}";
5264

5365
ps.AddScript(certStoreScript);
5466

5567
var certs = ps.Invoke();
5668

5769
foreach (var c in certs)
70+
{
5871
myCertificates.Add(new Certificate
5972
{
6073
Thumbprint = $"{c.Properties["Thumbprint"]?.Value}",
6174
HasPrivateKey = bool.Parse($"{c.Properties["HasPrivateKey"]?.Value}"),
62-
RawData = (byte[])c.Properties["RawData"]?.Value
75+
RawData = (byte[])c.Properties["RawData"]?.Value,
76+
CryptoServiceProvider = $"{c.Properties["CSP"]?.Value }",
77+
SAN = Certificate.Utilities.FormatSAN($"{c.Properties["san"]?.Value}")
6378
});
79+
}
6480

6581
return myCertificates;
6682
}

0 commit comments

Comments
 (0)