Skip to content

Commit 7bb9ca7

Browse files
committed
allow for cert upload as well as store or filepath
1 parent 3fe1b2e commit 7bb9ca7

4 files changed

Lines changed: 24 additions & 80 deletions

File tree

sectigo-scm-caplugin/Client/SectigoClient.cs

Lines changed: 4 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Keyfactor.Extensions.CAPlugin.Sectigo.API;
1+
using Keyfactor.AnyGateway.Extensions;
2+
using Keyfactor.Extensions.CAPlugin.Sectigo.API;
23
using Keyfactor.Extensions.CAPlugin.Sectigo.Models;
34
using Keyfactor.Logging;
45

@@ -305,7 +306,7 @@ private static async Task<T> ProcessResponse<T>(HttpResponseMessage response)
305306
}
306307
}
307308

308-
public static SectigoClient InitializeClient(SectigoConfig config)
309+
public static SectigoClient InitializeClient(SectigoConfig config, ICertificateResolver certResolver)
309310
{
310311
Logger.MethodEntry(LogLevel.Debug);
311312

@@ -314,7 +315,7 @@ public static SectigoClient InitializeClient(SectigoConfig config)
314315
if (config.AuthenticationType.ToLower() == "certificate")
315316
{
316317
clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
317-
X509Certificate2 authCert = GetClientCertificate(config);
318+
X509Certificate2 authCert = certResolver.ResolveCertificate(config.Certificate);
318319
if (authCert == null)
319320
{
320321
Logger.MethodExit(LogLevel.Debug);
@@ -348,58 +349,6 @@ public static SectigoClient InitializeClient(SectigoConfig config)
348349
return new SectigoClient(restClient);
349350
}
350351

351-
private static X509Certificate2 GetClientCertificate(SectigoConfig config)
352-
{
353-
Logger.MethodEntry(LogLevel.Debug);
354-
//Dictionary<string, object> caConnectionCertificateDetail = config["ClientCertificate"] as Dictionary<string, object>;
355-
X509Certificate2 clientCert = null;
356-
357-
if (!string.IsNullOrEmpty(config.Certificate.Thumbprint))
358-
{
359-
StoreName sn;
360-
StoreLocation sl;
361-
string thumbprint = config.Certificate.Thumbprint;
362-
363-
if (String.IsNullOrEmpty(thumbprint) ||
364-
!Enum.TryParse(config.Certificate.StoreName, out sn) ||
365-
!Enum.TryParse(config.Certificate.StoreLocation, out sl))
366-
{
367-
throw new Exception("Unable to find client authentication certificate");
368-
}
369-
370-
X509Certificate2Collection foundCerts;
371-
using (X509Store currentStore = new X509Store(sn, sl))
372-
{
373-
Logger.LogTrace($"Search for client auth certificates with Thumprint {thumbprint} in the {sn}{sl} certificate store");
374-
375-
currentStore.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
376-
foundCerts = currentStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, true);
377-
Logger.LogTrace($"Found {foundCerts.Count} certificates in the {currentStore.Name} store");
378-
currentStore.Close();
379-
}
380-
if (foundCerts.Count > 1)
381-
{
382-
throw new Exception($"Multiple certificates with Thumprint {thumbprint} found in the {sn}{sl} certificate store");
383-
}
384-
if (foundCerts.Count > 0)
385-
clientCert = foundCerts[0];
386-
}
387-
else
388-
{
389-
// Cert is provided via pfx file instead of cert store
390-
try
391-
{
392-
X509Certificate2 cert = new X509Certificate2(config.Certificate.CertificatePath, config.Certificate.CertificatePassword);
393-
clientCert = cert;
394-
}
395-
catch (Exception ex)
396-
{
397-
throw new Exception($"Unable to open the client certificate file with the given password. Error: {ex.Message}");
398-
}
399-
}
400-
Logger.MethodExit(LogLevel.Debug);
401-
return clientCert;
402-
}
403352
#endregion
404353
}
405354
}

sectigo-scm-caplugin/SectigoCAPlugin.cs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ public class SectigoCAPlugin : IAnyCAPlugin
3333
private SectigoConfig _config;
3434
private readonly ILogger _logger;
3535
private ICertificateDataReader _certificateDataReader;
36+
private ICertificateResolver _certificateResolver;
3637

37-
public SectigoCAPlugin()
38+
public SectigoCAPlugin(ICertificateResolver certResolver)
3839
{
3940
_logger = LogHandler.GetClassLogger<SectigoCAPlugin>();
41+
_certificateResolver = certResolver;
4042
}
4143

4244
public void Initialize(IAnyCAPluginConfigProvider configProvider, ICertificateDataReader certificateDataReader)
@@ -88,7 +90,7 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
8890
department = productInfo.ProductParameters["Department"];
8991
_logger.LogTrace($"Department: {department}");
9092
}
91-
var client = SectigoClient.InitializeClient(_config);
93+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
9294
var fieldList = Task.Run(async () => await client.ListCustomFields()).Result;
9395
var allFields = fieldList.CustomFields?.Select(f => f);
9496

@@ -370,7 +372,7 @@ public async Task<AnyCAPluginCertificate> GetSingleRecord(string caRequestID)
370372
_logger.LogTrace($"Get Single Certificate Detail from Sectigo (sslId: {caRequestID})");
371373
int sslId = int.Parse(caRequestID.Split('-')[0]);
372374

373-
var client = SectigoClient.InitializeClient(_config);
375+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
374376
var singleCert = Task.Run(async () => await client.GetCertificate(sslId)).Result;
375377
_logger.LogTrace($"{singleCert.CommonName} ({singleCert.status}) retrieved from Sectigo.");
376378

@@ -446,7 +448,7 @@ public async Task Ping()
446448
try
447449
{
448450
_logger.LogDebug("Attempting to ping Sectigo API");
449-
var client = SectigoClient.InitializeClient(_config);
451+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
450452
_ = Task.Run(async () => await client.ListOrganizations()).Result;
451453
}
452454
catch (Exception ex)
@@ -462,7 +464,7 @@ public async Task<int> Revoke(string caRequestID, string hexSerialNumber, uint r
462464

463465
try
464466
{
465-
var client = SectigoClient.InitializeClient(_config);
467+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
466468
var response = Task.Run(async () => await client.RevokeSslCertificateById(int.Parse(caRequestID), (int)revocationReason, RevokeReasonToString(revocationReason))).Result;
467469

468470
_logger.MethodExit(LogLevel.Debug);
@@ -501,7 +503,7 @@ public async Task Synchronize(BlockingCollection<AnyCAPluginCertificate> blockin
501503
string[] filterProfileIds = _config.SyncFilterProfileId.Split(',');
502504
filter.Add("sslTypeId", filterProfileIds);
503505
}
504-
var client = SectigoClient.InitializeClient(_config);
506+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
505507
producerTask = client.CertificateListProducer(certsToAdd, newCancelToken.Token, _config.PageSize, filter);
506508

507509
foreach (Certificate certToAdd in certsToAdd.GetConsumingEnumerable())
@@ -654,7 +656,7 @@ public async Task ValidateProductInfo(EnrollmentProductInfo productInfo, Diction
654656
_logger.MethodEntry(LogLevel.Debug);
655657
string rawConfig = JsonConvert.SerializeObject(connectionInfo);
656658
var parsedConfig = JsonConvert.DeserializeObject<SectigoConfig>(rawConfig);
657-
SectigoClient localClient = SectigoClient.InitializeClient(parsedConfig);
659+
SectigoClient localClient = SectigoClient.InitializeClient(parsedConfig, _certificateResolver);
658660

659661
var profileList = Task.Run(async () => await localClient.ListSslProfiles()).Result;
660662
if (profileList.SslProfiles.Where(p => p.id == int.Parse(productInfo.ProductID)).Count() == 0)
@@ -667,28 +669,28 @@ public async Task ValidateProductInfo(EnrollmentProductInfo productInfo, Diction
667669

668670
private async Task<Organization> GetOrganizationAsync(string orgName)
669671
{
670-
var client = SectigoClient.InitializeClient(_config);
672+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
671673
var orgList = await client.ListOrganizations();
672674
return orgList.Organizations.Where(x => x.name.ToLower().Equals(orgName.ToLower())).FirstOrDefault();
673675
}
674676

675677
private async Task<int> GetProfileTerm(int profileId)
676678
{
677-
var client = SectigoClient.InitializeClient(_config);
679+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
678680
var profileList = await client.ListSslProfiles();
679681
return profileList.SslProfiles.Where(x => x.id == profileId).FirstOrDefault().terms[0];
680682
}
681683

682684
private async Task<Profile> GetProfile(int profileId)
683685
{
684-
var client = SectigoClient.InitializeClient(_config);
686+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
685687
var profileList = await client.ListSslProfiles();
686688
return profileList.SslProfiles.Where(x => x.id == profileId).FirstOrDefault();
687689
}
688690

689691
private async Task<List<int>> GetProfileIds()
690692
{
691-
var client = SectigoClient.InitializeClient(_config);
693+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
692694
var profileList = await client.ListSslProfiles();
693695
return profileList.SslProfiles.Select(x => x.id).ToList();
694696
}
@@ -730,7 +732,7 @@ private async Task<EnrollmentResult> PickUpEnrolledCertificate(int sslId, string
730732
while (retryCounter < _config.PickupRetries)
731733
{
732734
_logger.LogDebug($"Try number {retryCounter + 1} to pickup enrolled certificate");
733-
var client = SectigoClient.InitializeClient(_config);
735+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
734736
var certificate = Task.Run(async () => await client.PickupCertificate(sslId, subject)).Result;
735737
if (certificate != null && !String.IsNullOrEmpty(certificate.Subject))
736738
{
@@ -765,7 +767,7 @@ public X509Certificate2 PickupSingleCert(int sslId, string subject)
765767
while (retryCounter < _config.PickupRetries)
766768
{
767769
_logger.LogDebug($"Try number {retryCounter + 1} to pickup single certificate");
768-
var client = SectigoClient.InitializeClient(_config);
770+
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
769771
var certificate = Task.Run(async () => await client.PickupCertificate(sslId, subject)).Result;
770772
if (certificate != null && !String.IsNullOrEmpty(certificate.Subject))
771773
{

sectigo-scm-caplugin/SectigoConfig.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using Newtonsoft.Json;
1+
using Keyfactor.AnyGateway.Extensions;
2+
3+
using Newtonsoft.Json;
24

35
using System;
46
using System.Collections.Generic;
@@ -54,13 +56,4 @@ public SectigoConfig()
5456
[JsonProperty("ClientCertificate")]
5557
public ClientCertificate Certificate { get; set; }
5658
}
57-
58-
public class ClientCertificate
59-
{
60-
public string StoreName { get; set; }
61-
public string StoreLocation { get; set; }
62-
public string Thumbprint { get; set; }
63-
public string CertificatePath { get; set; }
64-
public string CertificatePassword { get; set; }
65-
}
6659
}

sectigo-scm-caplugin/sectigo-scm-caplugin.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<RootNamespace>Keyfactor.Extensions.CAPlugin.Sectigo</RootNamespace>
66
<ImplicitUsings>disable</ImplicitUsings>
77
<Nullable>disable</Nullable>
@@ -10,7 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="Keyfactor.AnyGateway.IAnyCAPlugin" Version="3.0.0" />
13+
<PackageReference Include="Keyfactor.AnyGateway.IAnyCAPlugin" Version="3.1.0" />
1414
<PackageReference Include="Keyfactor.Common" Version="2.5.0" />
1515
<PackageReference Include="Keyfactor.Logging" Version="1.1.1" />
1616
<PackageReference Include="Keyfactor.PKI" Version="5.5.0" />

0 commit comments

Comments
 (0)