Skip to content

Commit

Permalink
Port sync CA filter from DCOM gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
dgaley committed Apr 19, 2024
1 parent 33ab07c commit ac791a7
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 9 deletions.
12 changes: 11 additions & 1 deletion digicert-certcentral-anycagateway/API/ListCertificateOrders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ namespace Keyfactor.Extensions.CAGateway.DigiCert.API
{
public class ListCertificateOrdersRequest : CertCentralBaseRequest
{
public ListCertificateOrdersRequest()
public ListCertificateOrdersRequest(bool ignoreExpired = false)
{
this.Resource = "services/v2/order/certificate";
this.Method = "GET";
this.limit = 1000;
this.offset = 0;
this.ignoreExpired = ignoreExpired;
}

[JsonProperty("limit")]
Expand All @@ -26,13 +27,22 @@ public ListCertificateOrdersRequest()
[JsonProperty("offset")]
public int offset { get; set; }

public bool ignoreExpired { get; set; }
public int expiredWindow { get; set; } = 0;

public new string BuildParameters()
{
StringBuilder sbParamters = new StringBuilder();

sbParamters.Append("limit=").Append(this.limit.ToString());
sbParamters.Append("&offset=").Append(HttpUtility.UrlEncode(this.offset.ToString()));

if (ignoreExpired)
{
DateTime cutoffDate = DateTime.Today.AddDays(-1 - expiredWindow);
sbParamters.Append("&filters[valid_till]=>").Append(cutoffDate.ToString("yyyy-MM-dd"));
}

return sbParamters.ToString();
}
}
Expand Down
5 changes: 4 additions & 1 deletion digicert-certcentral-anycagateway/API/OrderCertificate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace Keyfactor.Extensions.CAGateway.DigiCert.API
{
public class OrderRequest : CertCentralBaseRequest
public class OrderRequest : CertCentralBaseRequest
{
public OrderRequest(CertCentralCertType certType)
{
Expand Down Expand Up @@ -57,6 +57,9 @@ public OrderRequest(CertCentralCertType certType)
[JsonProperty("custom_fields")]
public List<MetadataField> CustomFields { get; set; }

[JsonProperty("skip_approval")]
public bool SkipApproval { get; set; }

public void SetOrganization(int? organizationId)
{
if (organizationId.HasValue)
Expand Down
50 changes: 45 additions & 5 deletions digicert-certcentral-anycagateway/CertCentralCAConnector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar

_logger.LogTrace("Making request to Enroll");

orderRequest.SkipApproval = true;

switch (enrollmentType)
{
case EnrollmentType.New:
Expand Down Expand Up @@ -426,7 +428,14 @@ public async Task<AnyCAPluginCertificate> GetSingleRecord(string caRequestID)
CertificateChainResponse certificateChainResponse = client.GetCertificateChain(new CertificateChainRequest(certId));
if (certificateChainResponse.Status == CertCentralBaseResponse.StatusType.SUCCESS)
{
certificate = certificateChainResponse.Intermediates[0].PEM;
if (certificateChainResponse.Intermediates.Count > 0)
{
certificate = certificateChainResponse.Intermediates[0].PEM;
}
else
{
throw new Exception($"No PEM certificate returned for certificate {certId} in order {orderId}. This could be due to a certificate that provisioned via an alternative method, such as a physical token.");
}
}
else
{
Expand Down Expand Up @@ -553,10 +562,12 @@ public async Task<int> Revoke(string caRequestID, string hexSerialNumber, uint r
RevokeCertificateResponse revokeResponse;
if (_config.RevokeCertificateOnly.HasValue && _config.RevokeCertificateOnly.Value)
{
_logger.LogInformation($"Attempting to revoke certificate with CA Request Id {caRequestID} and serial number {hexSerialNumber}. RevokeCertificateOnly is true, so revoking single certificate.");
revokeResponse = client.RevokeCertificate(new RevokeCertificateRequest(certId) { comments = Conversions.RevokeReasonToString(revocationReason) });
}
else
{
_logger.LogInformation($"Attempting to revoke certificate with CA Request Id {caRequestID} and serial number {hexSerialNumber}. RevokeCertificateOnly is false, so revoking the entire order.");
revokeResponse = client.RevokeCertificate(new RevokeCertificateByOrderRequest(orderResponse.id) { comments = Conversions.RevokeReasonToString(revocationReason) });
}

Expand Down Expand Up @@ -606,12 +617,27 @@ public async Task Synchronize(BlockingCollection<AnyCAPluginCertificate> blockin
List<string> skippedOrders = new List<string>();
int certCount = 0;

string syncCAstring = string.Join(",", _config.SyncCAFilter ?? new List<string>());
_logger.LogTrace($"Sync CAs: {syncCAstring}");
List<string> caList = _config.SyncCAFilter ?? new List<string>();
caList.ForEach(c => c.ToUpper());


if (fullSync)
{
bool ignoreExpired = false; int expiredWindow = 0;
if (_config.FilterExpiredOrders.HasValue && _config.FilterExpiredOrders.Value)
{
ignoreExpired = true;
if (_config.SyncExpirationDays.HasValue)
{
expiredWindow = _config.SyncExpirationDays.Value;
}
}
long time = DateTime.Now.Ticks;
long starttime = time;
_logger.LogDebug($"SYNC: Starting sync at time {time}");
ListCertificateOrdersResponse ordersResponse = client.ListAllCertificateOrders();
ListCertificateOrdersResponse ordersResponse = client.ListAllCertificateOrders(ignoreExpired, expiredWindow);
if (ordersResponse.Status == CertCentralBaseResponse.StatusType.ERROR)
{
Error error = ordersResponse.Errors[0];
Expand All @@ -629,7 +655,11 @@ public async Task Synchronize(BlockingCollection<AnyCAPluginCertificate> blockin
cancelToken.ThrowIfCancellationRequested();
string caReqId = orderDetails.id + "-" + orderDetails.certificate.id;
_logger.LogDebug($"SYNC: Retrieving certs for order id {orderDetails.id}");
orderCerts = GetAllConnectorCertsForOrder(caReqId);
orderCerts = GetAllConnectorCertsForOrder(caReqId, caList);
if (orderCerts == null || orderCerts.Count == 0)
{
continue;
}
_logger.LogDebug($"SYNC: Retrieved {orderCerts.Count} certs at time {DateTime.Now.Ticks}");
}
catch
Expand Down Expand Up @@ -668,7 +698,11 @@ public async Task Synchronize(BlockingCollection<AnyCAPluginCertificate> blockin
{
cancelToken.ThrowIfCancellationRequested();
string caReqId = order.order_id + "-" + order.certificate_id;
orderCerts = GetAllConnectorCertsForOrder(caReqId);
orderCerts = GetAllConnectorCertsForOrder(caReqId, caList);
if (orderCerts == null || orderCerts.Count > 0)
{
continue;
}
}
catch
{
Expand Down Expand Up @@ -1209,7 +1243,7 @@ string FormatSyncDate(DateTime? syncTime)
/// </summary>
/// <param name="caRequestID"></param>
/// <returns></returns>
private List<AnyCAPluginCertificate> GetAllConnectorCertsForOrder(string caRequestID)
private List<AnyCAPluginCertificate> GetAllConnectorCertsForOrder(string caRequestID, List<string> caFilterIds)
{
_logger.MethodEntry(LogLevel.Trace);
// Split ca request id into order and cert id
Expand All @@ -1222,6 +1256,12 @@ private List<AnyCAPluginCertificate> GetAllConnectorCertsForOrder(string caReque
CertCentralClient client = CertCentralClientUtilities.BuildCertCentralClient(_config);
ViewCertificateOrderResponse orderResponse = client.ViewCertificateOrder(new ViewCertificateOrderRequest((uint)orderId));

if (caFilterIds != null && caFilterIds.Count > 0 && !caFilterIds.Contains(orderResponse.certificate.ca_cert.Id.ToUpper()))
{
_logger.LogTrace($"Found order ID {orderId} that does not match SyncCAFilter. CA ID: {orderResponse.certificate.ca_cert.Id} Skipping...");
return null;
}

var orderCerts = GetAllCertsForOrder(orderId);

List<AnyCAPluginCertificate> certList = new List<AnyCAPluginCertificate>();
Expand Down
8 changes: 8 additions & 0 deletions digicert-certcentral-anycagateway/CertCentralConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@ namespace Keyfactor.Extensions.CAGateway.DigiCert
{
public class CertCentralConfig
{

public CertCentralConfig()
{
SyncCAFilter = new List<string>();
}
public string APIKey { get; set; }
public string Region { get; set; } = "US";
public int? DivisionId { get; set; }
public bool? RevokeCertificateOnly { get; set; }
public bool Enabled { get; set; } = true;
public List<string> SyncCAFilter { get; set; }
public bool? FilterExpiredOrders { get; set; }
public int? SyncExpirationDays { get; set; }
}
}
6 changes: 4 additions & 2 deletions digicert-certcentral-anycagateway/Client/CertCentralClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ public DownloadCertificateByFormatResponse DownloadCertificateByFormat(DownloadC
return dlCertificateRequestResponse;
}

public ListCertificateOrdersResponse ListAllCertificateOrders()
public ListCertificateOrdersResponse ListAllCertificateOrders(bool ignoreExpired = false, int expiredWindow = 0)
{
int batch = 1000;
ListCertificateOrdersResponse totalResponse = new ListCertificateOrdersResponse();
Expand All @@ -483,7 +483,9 @@ public ListCertificateOrdersResponse ListAllCertificateOrders()
ListCertificateOrdersRequest request = new ListCertificateOrdersRequest()
{
limit = batch,
offset = totalResponse.orders.Count
offset = totalResponse.orders.Count,
ignoreExpired = ignoreExpired,
expiredWindow = expiredWindow
};

CertCentralResponse response = Request(request, request.BuildParameters());
Expand Down

0 comments on commit ac791a7

Please sign in to comment.