Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,12 @@

### 2.4.1
* Fix for missing parameter errors

### 2.5.0
* Fix for checking if product is a DV cert to ignore organization checks
* Performance enhancements to reduce API calls
* Added null checks/error handling to catch bad certs on sync
* Improved rate limiting handling based on DigiCert guidance
* Improved handling of API error responses
* Fixes for sync filtering
* Incremental sync fix
42 changes: 33 additions & 9 deletions digicert-certcentral-caplugin/CertCentralCAPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,21 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
CertCentralClient client = CertCentralClientUtilities.BuildCertCentralClient(_config);
int? organizationId = null;
// DV certs have no organization, so only do the org check if its a non-DV cert
if (!string.Equals(productInfo.ProductID, CertCentralConstants.ProductTypes.DV_SSL_CERT, StringComparison.OrdinalIgnoreCase))

// Get product ID details.
CertificateTypeDetailsRequest detailsRequest = new CertificateTypeDetailsRequest(productInfo.ProductID);

// For pulling product ID details, we use the Connection-level Division ID rather than the template-level one.
detailsRequest.ContainerId = null;
if (_config.DivisionId.HasValue)
{
detailsRequest.ContainerId = _config.DivisionId.Value;
}

CertificateTypeDetailsResponse details = client.GetCertificateTypeDetails(detailsRequest);

// Only do org check if the product type is NOT the group dv_ssl_certificate (https://dev.digicert.com/certcentral-apis/services-api/glossary.html#product-identifiers)
if (!string.Equals(details.GroupName, CertCentralConstants.ProductTypes.DV_SSL_CERT, StringComparison.OrdinalIgnoreCase))
{
if (organization == null)
{
Expand Down Expand Up @@ -585,7 +599,7 @@ public async Task<AnyCAPluginCertificate> GetSingleRecord(string caRequestID)
CertCentralClient client = CertCentralClientUtilities.BuildCertCentralClient(_config);
ViewCertificateOrderResponse orderResponse = client.ViewCertificateOrder(new ViewCertificateOrderRequest((uint)orderId));

var orderCerts = GetAllCertsForOrder(orderId);
var orderCerts = GetAllCertsForOrder(orderId, orderResponse);

StatusOrder certToCheck = orderCerts.Where(c => c.certificate_id == certIdInt).First();

Expand Down Expand Up @@ -873,7 +887,7 @@ public async Task Synchronize(BlockingCollection<AnyCAPluginCertificate> blockin
_logger.LogTrace($"Sync CAs: {syncCAstring}");
List<string> caList = _config.SyncCAs;

caList.ForEach(c => c.ToUpper());
caList = caList.Select(c => c?.Trim().ToUpper()).Where(c => !string.IsNullOrEmpty(c)).ToList();

List<string> divFilters = new List<string>();
if (!string.IsNullOrEmpty(_config.SyncDivisionFilter))
Expand Down Expand Up @@ -969,7 +983,7 @@ public async Task Synchronize(BlockingCollection<AnyCAPluginCertificate> blockin
cancelToken.ThrowIfCancellationRequested();
string caReqId = order.order_id + "-" + order.certificate_id;
orderCerts = GetAllConnectorCertsForOrder(caReqId, caList, divFilters, productFilters);
if (orderCerts == null || orderCerts.Count > 0)
if (orderCerts == null || orderCerts.Count == 0)
{
continue;
}
Expand Down Expand Up @@ -1699,9 +1713,10 @@ private List<AnyCAPluginCertificate> GetAllConnectorCertsForOrder(string caReque
if (productIds != null && productIds.Count > 0 && !productIds.Contains(orderResponse.product.name_id.ToString()))
{
_logger.LogTrace($"Found order ID {orderId} that does not match Product filter. Product ID: {orderResponse.product.name_id.ToString()} Skipping...");
return null;
}

var orderCerts = GetAllCertsForOrder(orderId);
var orderCerts = GetAllCertsForOrder(orderId, orderResponse);

List<AnyCAPluginCertificate> certList = new List<AnyCAPluginCertificate>();
List<string> pemList = new List<string>();
Expand All @@ -1719,6 +1734,10 @@ private List<AnyCAPluginCertificate> GetAllConnectorCertsForOrder(string caReque
CertificateChainResponse certificateChainResponse = client.GetCertificateChain(new CertificateChainRequest($"{cert.certificate_id}"));
if (certificateChainResponse.Status == CertCentralBaseResponse.StatusType.SUCCESS)
{
if (certificateChainResponse.Intermediates == null || certificateChainResponse.Intermediates.Count == 0)
{
throw new Exception($"DigiCert returned an empty certificate chain for certificate {cert.certificate_id} on order {orderId}.");
}
certificate = certificateChainResponse.Intermediates[0].PEM;
}
else
Expand All @@ -1727,12 +1746,15 @@ private List<AnyCAPluginCertificate> GetAllConnectorCertsForOrder(string caReque
}
}
//Another check for duplicate PEMs to get arround issue with DigiCert API returning incorrect data sometimes on reissued/duplicate certs
if (pemList.Contains(certificate))
if (certificate != null && pemList.Contains(certificate))
{
_logger.LogWarning($"Found duplicate PEM for ID {caReqId}. Skipping...");
continue;
}
pemList.Add(certificate);
if (certificate != null)
{
pemList.Add(certificate);
}
var connCert = new AnyCAPluginCertificate
{
CARequestID = caReqId,
Expand All @@ -1757,10 +1779,12 @@ private List<AnyCAPluginCertificate> GetAllConnectorCertsForOrder(string caReque
/// <param name="orderId"></param>
/// <returns></returns>
/// <exception cref="COMException"></exception>
private List<StatusOrder> GetAllCertsForOrder(int orderId)
private List<StatusOrder> GetAllCertsForOrder(int orderId, ViewCertificateOrderResponse existingOrderResponse = null)
{
CertCentralClient client = CertCentralClientUtilities.BuildCertCentralClient(_config);
ViewCertificateOrderResponse orderResponse = client.ViewCertificateOrder(new ViewCertificateOrderRequest((uint)orderId));

// If the caller provides an existing order response, reuse that to save the API call.
ViewCertificateOrderResponse orderResponse = existingOrderResponse ?? client.ViewCertificateOrder(new ViewCertificateOrderRequest((uint)orderId));
if (orderResponse.Status == CertCentralBaseResponse.StatusType.ERROR)
{
string errorMessage = String.Format("Request {0} was not found in CertCentral database or is not valid", orderId);
Expand Down
Loading
Loading