Skip to content

Commit d2a84c1

Browse files
Fixed Multi-San Issue
1 parent b92e9bb commit d2a84c1

File tree

1 file changed

+45
-6
lines changed

1 file changed

+45
-6
lines changed

AcmeCaPlugin/AcmeCaPlugin.cs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,8 @@ public async Task<EnrollmentResult> Enroll(
248248
var acmeClient = new AcmeClient(_logger, config, httpClient, protocolClient.Directory,
249249
new Clients.Acme.Account(accountDetails, signer));
250250

251-
// Extract domain
252-
var cleanDomain = ExtractDomainFromSubject(subject);
253-
var identifiers = new List<Identifier>
254-
{
255-
new Identifier { Type = "dns", Value = cleanDomain }
256-
};
251+
// Extract all domains (CN + SANs) for the ACME order
252+
var identifiers = BuildIdentifiersFromSubjectAndSan(subject, san);
257253

258254
// Create order
259255
var order = await acmeClient.CreateOrderAsync(identifiers, null);
@@ -331,6 +327,49 @@ private static string ExtractDomainFromSubject(string subject)
331327
throw new ArgumentException($"Could not extract CN from subject: {subject}", nameof(subject));
332328
}
333329

330+
/// <summary>
331+
/// Builds ACME identifiers from subject CN and SANs.
332+
/// ACME orders must include all domains that will be in the CSR.
333+
/// </summary>
334+
/// <param name="subject">Subject string containing CN</param>
335+
/// <param name="san">Dictionary of SANs (key: type like "dns", value: array of names)</param>
336+
/// <returns>List of unique ACME identifiers for all domains</returns>
337+
private List<Identifier> BuildIdentifiersFromSubjectAndSan(string subject, Dictionary<string, string[]> san)
338+
{
339+
var domains = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
340+
341+
// Add the CN from subject
342+
var cnDomain = ExtractDomainFromSubject(subject);
343+
domains.Add(cnDomain);
344+
_logger.LogDebug("Added CN domain to identifiers: {Domain}", cnDomain);
345+
346+
// Add DNS SANs if present
347+
if (san != null)
348+
{
349+
// Check for "dns" key (case-insensitive)
350+
foreach (var kvp in san)
351+
{
352+
if (kvp.Key.Equals("dns", StringComparison.OrdinalIgnoreCase) && kvp.Value != null)
353+
{
354+
foreach (var dnsName in kvp.Value)
355+
{
356+
if (!string.IsNullOrWhiteSpace(dnsName))
357+
{
358+
domains.Add(dnsName.Trim());
359+
_logger.LogDebug("Added SAN domain to identifiers: {Domain}", dnsName.Trim());
360+
}
361+
}
362+
}
363+
}
364+
}
365+
366+
var identifiers = domains.Select(d => new Identifier { Type = "dns", Value = d }).ToList();
367+
_logger.LogInformation("Created ACME order with {Count} identifier(s): {Domains}",
368+
identifiers.Count, string.Join(", ", domains));
369+
370+
return identifiers;
371+
}
372+
334373
/// <summary>
335374
/// Processes ACME authorizations for domain validation
336375
/// Currently hardcoded to use DNS-01 challenge with Google DNS provider

0 commit comments

Comments
 (0)