Skip to content

Commit 9db8bbb

Browse files
CARequestId Fix
1 parent 8fd65d2 commit 9db8bbb

File tree

1 file changed

+16
-20
lines changed

1 file changed

+16
-20
lines changed

AcmeCaPlugin/AcmeCaPlugin.cs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Org.BouncyCastle.Asn1.Pkcs;
1414
using Org.BouncyCastle.Asn1.X509;
1515
using Org.BouncyCastle.Pkcs;
16+
using System.Security.Cryptography;
1617
using System;
1718
using System.Collections.Generic;
1819
using System.Linq;
@@ -301,6 +302,9 @@ public async Task<EnrollmentResult> Enroll(
301302
_logger.LogInformation("Order created. OrderUrl: {OrderUrl}, Status: {Status}",
302303
order.OrderUrl, order.Payload?.Status);
303304

305+
// Extract order identifier BEFORE finalization to ensure we use the original order URL
306+
var orderIdentifier = ExtractOrderIdentifier(order.OrderUrl);
307+
304308
// Store pending order immediately
305309
var accountId = accountDetails.Kid.Split('/').Last();
306310

@@ -310,9 +314,6 @@ public async Task<EnrollmentResult> Enroll(
310314
// Finalize with original CSR bytes
311315
order = await acmeClient.FinalizeOrderAsync(order, csrBytes);
312316

313-
// Extract order identifier (path only) for database storage
314-
var orderIdentifier = ExtractOrderIdentifier(order.OrderUrl);
315-
316317
// If order is valid immediately, download cert
317318
if (order.Payload?.Status == "valid" && !string.IsNullOrEmpty(order.Payload.Certificate))
318319
{
@@ -361,30 +362,25 @@ public async Task<EnrollmentResult> Enroll(
361362

362363

363364
/// <summary>
364-
/// Extracts the order path from the full ACME order URL for use as a unique identifier.
365-
/// This removes the scheme, host, and port, keeping only the path portion.
365+
/// Generates a fixed-length SHA256 hash of the ACME order URL for database storage.
366+
/// Produces a consistent 40-char hex string regardless of URL length or ACME CA format.
367+
/// The full order URL is logged separately during enrollment for traceability.
366368
/// </summary>
367-
/// <param name="orderUrl">Full order URL (e.g., https://dv.acme-v02.api.pki.goog/order/ABC123)</param>
368-
/// <returns>Order path without leading slash (e.g., "order/ABC123")</returns>
369-
/// <example>
370-
/// Input: "https://dv.acme-v02.api.pki.goog/order/IlYl06mPl5VcAQpx3pzR6w"
371-
/// Output: "order/IlYl06mPl5VcAQpx3pzR6w"
372-
/// </example>
373369
private static string ExtractOrderIdentifier(string orderUrl)
374370
{
375371
if (string.IsNullOrWhiteSpace(orderUrl))
376372
return orderUrl;
377373

378-
try
374+
using (var sha256 = SHA256.Create())
379375
{
380-
var uri = new Uri(orderUrl);
381-
// Remove leading slash and return the path
382-
return uri.AbsolutePath.TrimStart('/');
383-
}
384-
catch (Exception)
385-
{
386-
// If URL parsing fails, return the original (shouldn't happen with valid ACME URLs)
387-
return orderUrl;
376+
var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(orderUrl));
377+
// Take first 20 bytes (40 hex chars) — fits in DB column and is collision-safe
378+
var sb = new StringBuilder(40);
379+
for (int i = 0; i < 20; i++)
380+
{
381+
sb.Append(hashBytes[i].ToString("x2"));
382+
}
383+
return sb.ToString();
388384
}
389385
}
390386

0 commit comments

Comments
 (0)