diff --git a/SslStoreCaProxy.slnx b/SslStoreCaProxy.slnx
new file mode 100644
index 0000000..ba17d13
--- /dev/null
+++ b/SslStoreCaProxy.slnx
@@ -0,0 +1,3 @@
+
+
+
diff --git a/SslStoreCaProxy/RequestManager.cs b/SslStoreCaProxy/RequestManager.cs
index fbbdbe4..30718f8 100644
--- a/SslStoreCaProxy/RequestManager.cs
+++ b/SslStoreCaProxy/RequestManager.cs
@@ -142,6 +142,15 @@ public DownloadCertificateRequest GetCertificateRequest(string customOrderId)
};
}
+ public DownloadCertificateRequest GetCertificateRequestBySslStoreId(string theSslStoreOrderId)
+ {
+ return new DownloadCertificateRequest
+ {
+ AuthRequest = GetAuthRequest(),
+ TheSslStoreOrderId = theSslStoreOrderId
+ };
+ }
+
public RevokeOrderRequest GetRevokeOrderRequest(string customOrderId)
{
return new RevokeOrderRequest
@@ -151,6 +160,15 @@ public RevokeOrderRequest GetRevokeOrderRequest(string customOrderId)
};
}
+ public RevokeOrderRequest GetRevokeOrderRequestBySslStoreId(string theSslStoreOrderId)
+ {
+ return new RevokeOrderRequest
+ {
+ AuthRequest = GetAuthRequest(),
+ TheSslStoreOrderId = theSslStoreOrderId
+ };
+ }
+
public int GetClientPageSize(IAnyCAPluginConfigProvider config)
{
if (config.CAConnectionData.ContainsKey(Constants.PageSize))
@@ -198,7 +216,7 @@ public int MapReturnStatus(string sslStoreStatus)
case "Cancelled":
return (int)EndEntityStatus.REVOKED;
default:
- return (int)EndEntityStatus.FAILED;
+ return (int)EndEntityStatus.NEW;
}
}
diff --git a/SslStoreCaProxy/SslStoreCaProxy.cs b/SslStoreCaProxy/SslStoreCaProxy.cs
index dce2725..04bd232 100644
--- a/SslStoreCaProxy/SslStoreCaProxy.cs
+++ b/SslStoreCaProxy/SslStoreCaProxy.cs
@@ -129,7 +129,16 @@ public Dictionary GetTemplateParameterAnnotations()
public async Task Revoke(string caRequestId, string hexSerialNumber, uint revocationReason)
{
_logger.MethodEntry();
- var revokeOrderRequest = _requestManager.GetRevokeOrderRequest(caRequestId);
+ var sslStoreOrderId = ParseSslStoreOrderId(caRequestId);
+ RevokeOrderRequest revokeOrderRequest;
+ if (sslStoreOrderId != null)
+ {
+ revokeOrderRequest = _requestManager.GetRevokeOrderRequestBySslStoreId(sslStoreOrderId);
+ }
+ else
+ {
+ revokeOrderRequest = _requestManager.GetRevokeOrderRequest(caRequestId);
+ }
_logger.LogTrace($"Revoke Request JSON {JsonConvert.SerializeObject(revokeOrderRequest)}");
try
{
@@ -240,9 +249,20 @@ public async Task Enroll(string csr, string subject, Dictionar
_logger.LogTrace($"Prior Cert Serial Number: {sn}");
var caRequestId = await _certDataReader.GetRequestIDBySerialNumber(sn);
- _logger.LogTrace($"Prior CA Request ID (CustomOrderId): {caRequestId}");
+ _logger.LogTrace($"Prior CA Request ID: {caRequestId}");
- var orderStatusRequest = _requestManager.GetOrderStatusRequest(caRequestId);
+ var priorSslStoreOrderId = ParseSslStoreOrderId(caRequestId);
+ OrderStatusRequest orderStatusRequest;
+ if (priorSslStoreOrderId != null)
+ {
+ _logger.LogTrace($"Parsed TheSSLStoreOrderID: {priorSslStoreOrderId}");
+ orderStatusRequest = _requestManager.GetOrderStatusRequestBySslStoreId(priorSslStoreOrderId);
+ }
+ else
+ {
+ _logger.LogTrace($"Legacy GUID format, querying by CustomOrderId: {caRequestId}");
+ orderStatusRequest = _requestManager.GetOrderStatusRequest(caRequestId);
+ }
_logger.LogTrace($"orderStatusRequest JSON {JsonConvert.SerializeObject(orderStatusRequest)}");
var orderStatusResponse = await client.SubmitOrderStatusRequestAsync(orderStatusRequest);
@@ -290,6 +310,36 @@ public async Task Enroll(string csr, string subject, Dictionar
}
}
+ ///
+ /// Builds a composite CARequestID in the format "{TheSSLStoreOrderID}-{PartnerOrderID}".
+ /// This ensures uniqueness across reissues (same order, different PartnerOrderID).
+ ///
+ private static string BuildCompositeRequestId(string theSslStoreOrderId, string partnerOrderId)
+ {
+ return $"{theSslStoreOrderId}-{partnerOrderId}";
+ }
+
+ ///
+ /// Parses the TheSSLStoreOrderID from a CARequestID. Supports both composite format
+ /// ("{TheSSLStoreOrderID}-{PartnerOrderID}") and legacy GUID format (falls back to
+ /// treating the whole string as a CustomOrderId for backward compatibility).
+ ///
+ private static string ParseSslStoreOrderId(string caRequestId)
+ {
+ if (string.IsNullOrEmpty(caRequestId)) return caRequestId;
+
+ var dashIndex = caRequestId.IndexOf('-');
+ // Composite IDs have a numeric TheSSLStoreOrderID before the first dash.
+ // Legacy GUIDs have hex chars before the first dash so we check for digits only.
+ if (dashIndex > 0 && caRequestId.Substring(0, dashIndex).All(char.IsDigit))
+ {
+ return caRequestId.Substring(0, dashIndex);
+ }
+
+ // Legacy GUID format — return as-is for backward compatibility
+ return null;
+ }
+
private EnrollmentResult GetEnrollmentResult(INewOrderResponse newOrderResponse)
{
if (newOrderResponse != null && newOrderResponse.AuthResponse.IsError)
@@ -304,16 +354,16 @@ private EnrollmentResult GetEnrollmentResult(INewOrderResponse newOrderResponse)
var majorStatus = newOrderResponse?.OrderStatus?.MajorStatus;
var status = _requestManager.MapReturnStatus(majorStatus);
- var orderId = newOrderResponse?.CustomOrderId;
+ var compositeId = BuildCompositeRequestId(newOrderResponse?.TheSslStoreOrderId, newOrderResponse?.PartnerOrderId);
- _logger.LogTrace($"Order {orderId} status: {majorStatus} -> mapped to {status}");
+ _logger.LogTrace($"Order {compositeId} (SSLStoreOrderId: {newOrderResponse?.TheSslStoreOrderId}, PartnerOrderId: {newOrderResponse?.PartnerOrderId}) status: {majorStatus} -> mapped to {status}");
_logger.MethodExit();
return new EnrollmentResult
{
- CARequestID = orderId,
+ CARequestID = compositeId,
Status = status,
- StatusMessage = $"Order Successfully Created With Order Number {orderId}"
+ StatusMessage = $"Order Successfully Created With Order Number {compositeId}"
};
}
@@ -322,8 +372,19 @@ public async Task GetSingleRecord(string caRequestId)
_logger.MethodEntry();
var client = new SslStoreClient(Config);
- var orderStatusRequest = _requestManager.GetOrderStatusRequest(caRequestId);
- _logger.LogTrace($"orderStatusRequest JSON {JsonConvert.SerializeObject(orderStatusRequest)}");
+ var sslStoreOrderId = ParseSslStoreOrderId(caRequestId);
+
+ OrderStatusRequest orderStatusRequest;
+ if (sslStoreOrderId != null)
+ {
+ _logger.LogTrace($"Parsed TheSSLStoreOrderID: {sslStoreOrderId} from CARequestID: {caRequestId}");
+ orderStatusRequest = _requestManager.GetOrderStatusRequestBySslStoreId(sslStoreOrderId);
+ }
+ else
+ {
+ _logger.LogTrace($"Legacy GUID format, querying by CustomOrderId: {caRequestId}");
+ orderStatusRequest = _requestManager.GetOrderStatusRequest(caRequestId);
+ }
var orderStatusResponse = await client.SubmitOrderStatusRequestAsync(orderStatusRequest);
_logger.LogTrace($"orderStatusResponse JSON {JsonConvert.SerializeObject(orderStatusResponse)}");
@@ -333,7 +394,7 @@ public async Task GetSingleRecord(string caRequestId)
if (certStatus == (int)EndEntityStatus.GENERATED)
{
- var downloadCertificateRequest = _requestManager.GetCertificateRequest(caRequestId);
+ var downloadCertificateRequest = _requestManager.GetCertificateRequestBySslStoreId(sslStoreOrderId ?? orderStatusResponse.TheSslStoreOrderId);
var certResponse = await client.SubmitDownloadCertificateAsync(downloadCertificateRequest);
if (!certResponse.AuthResponse.IsError)
{
@@ -379,19 +440,21 @@ public async Task Synchronize(BlockingCollection blockin
var orderStatusRequest = _requestManager.GetOrderStatusRequestBySslStoreId(currentResponseItem?.TheSslStoreOrderId);
var orderStatusResponse = await client.SubmitOrderStatusRequestAsync(orderStatusRequest);
- var customOrderId = orderStatusResponse.CustomOrderId;
- if (string.IsNullOrEmpty(customOrderId))
+ var theSslStoreOrderId = orderStatusResponse.TheSslStoreOrderId;
+ var partnerOrderId = orderStatusResponse.PartnerOrderId;
+ if (string.IsNullOrEmpty(theSslStoreOrderId) || string.IsNullOrEmpty(partnerOrderId))
{
- _logger.LogTrace($"Order {currentResponseItem?.TheSslStoreOrderId} has no CustomOrderId, skipping");
+ _logger.LogTrace($"Order {currentResponseItem?.TheSslStoreOrderId} missing required IDs, skipping");
continue;
}
+ var compositeId = BuildCompositeRequestId(theSslStoreOrderId, partnerOrderId);
var fileContent = "";
var certStatus = _requestManager.MapReturnStatus(orderStatusResponse.OrderStatus.MajorStatus);
if (certStatus == (int)EndEntityStatus.GENERATED)
{
- var downloadCertificateRequest = _requestManager.GetCertificateRequest(customOrderId);
+ var downloadCertificateRequest = _requestManager.GetCertificateRequestBySslStoreId(theSslStoreOrderId);
var certResponse = await client.SubmitDownloadCertificateAsync(downloadCertificateRequest);
if (!certResponse.AuthResponse.IsError)
{
@@ -400,13 +463,13 @@ public async Task Synchronize(BlockingCollection blockin
fileContent = Convert.ToBase64String(endEntityCert.RawData);
}
}
-
+
if ((certStatus == (int)EndEntityStatus.GENERATED && fileContent.Length > 0) ||
certStatus == (int)EndEntityStatus.REVOKED)
{
blockingBuffer.Add(new AnyCAPluginCertificate
{
- CARequestID = customOrderId,
+ CARequestID = compositeId,
Certificate = fileContent,
Status = certStatus,
ProductID = $"{orderStatusResponse.ProductCode}"
diff --git a/integration-manifest.json b/integration-manifest.json
index 4f22c79..86be3f5 100644
--- a/integration-manifest.json
+++ b/integration-manifest.json
@@ -7,8 +7,8 @@
"status": "production",
"integration_type": "anyca-plugin",
"support_level": "kf-supported",
- "link_github": true,
- "update_catalog": true,
+ "link_github": false,
+ "update_catalog": false,
"gateway_framework": "25.5",
"about": {
"carest": {