diff --git a/README.md b/README.md
index 0250f2c..31c22e0 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
-
+
diff --git a/cscglobal-caplugin.Tests/CSCGlobalCAPluginTests.cs b/cscglobal-caplugin.Tests/CSCGlobalCAPluginTests.cs
index 4ae771b..1676e26 100644
--- a/cscglobal-caplugin.Tests/CSCGlobalCAPluginTests.cs
+++ b/cscglobal-caplugin.Tests/CSCGlobalCAPluginTests.cs
@@ -633,6 +633,10 @@ public async Task Enroll_RenewOrReissue_NullExpirationDate_FallsBackToGetSingleR
var result = await plugin.Enroll("csr", "CN=test", new Dictionary(), productInfo,
RequestFormat.PKCS10, EnrollmentType.RenewOrReissue);
+ Assert.Equal((int)EndEntityStatus.EXTERNALVALIDATION, result!.Status);
+ mockClient.Verify(c => c.SubmitReissueAsync(It.IsAny()), Times.Once);
+ }
+
[Fact]
public void GetProductIds_ReturnsCanonicalAndLegacyNames()
{
@@ -1165,17 +1169,6 @@ public void GetTemplateParameterAnnotations_ContainsExpectedKeys()
Assert.Contains(EnrollmentConfigConstants.AdditionalSansCommaSeparatedDcvEmails, annotations.Keys);
}
- [Fact]
- public void GetProductIds_ReturnsFullList()
- {
- var plugin = MakePlugin();
- var ids = plugin.GetProductIds();
-
- Assert.Equal(10, ids.Count);
- Assert.Contains("CSC TrustedSecure OV", ids);
- Assert.Contains("CSC TrustedSecure DV Wildcard, Multiple Names", ids);
- }
-
// ---------------------------------------------------------------------
// GetEndEntityCertificate
// ---------------------------------------------------------------------
diff --git a/cscglobal-caplugin.Tests/RequestManagerTests.cs b/cscglobal-caplugin.Tests/RequestManagerTests.cs
index ad82f3d..c3f2bc5 100644
--- a/cscglobal-caplugin.Tests/RequestManagerTests.cs
+++ b/cscglobal-caplugin.Tests/RequestManagerTests.cs
@@ -384,8 +384,8 @@ public void MapReturnStatus_MapsExpectedStatus(string? cscStatus, int expected)
[InlineData("CSC TrustedSecure UC Certificate", "2", true, false)]
[InlineData("CSC TrustedSecure EV Certificate", "3", false, true)]
[InlineData("CSC TrustedSecure Domain Validated SSL", "4", false, false)]
- [InlineData("CSC TrustedSecure Domain Validated Wildcard SSL", "5", false, false)]
- [InlineData("CSC TrustedSecure Domain Validated UC Certificate", "6", true, false)]
+ [InlineData("CSC Trusted Secure Domain Validated Wildcard SSL", "5", false, false)]
+ [InlineData("CSC Trusted Secure Domain Validated UC Certificate", "6", true, false)]
public void GetRegistrationRequest_RoutesCertificateTypeAndOptionalSections(
string productId, string expectedType, bool expectSans, bool expectEv)
{
@@ -684,7 +684,7 @@ public void GetRenewalRequest_LegacyProductName_ResolvesCertificateTypeAndSans()
// A Certificate Template in Command created before the 1.2.0 rename still carries the
// old product name; renewals against it must resolve the same as the canonical name.
var sans = new Dictionary { ["dnsname"] = new[] { "www.example.com" } };
- var productInfo = ProductInfo("CSC TrustedSecure Domain Validated UC Certificate", new Dictionary
+ var productInfo = ProductInfo("CSC Trusted Secure Domain Validated UC Certificate", new Dictionary
{
["Domain Control Validation Method"] = "CNAME"
});
diff --git a/cscglobal-caplugin/RequestManager.cs b/cscglobal-caplugin/RequestManager.cs
index 0c485ff..1829e5e 100644
--- a/cscglobal-caplugin/RequestManager.cs
+++ b/cscglobal-caplugin/RequestManager.cs
@@ -23,6 +23,13 @@ public class RequestManager
public static Func Pemify = ss =>
ss.Length <= 64 ? ss : ss.Substring(0, 64) + "\n" + Pemify(ss.Substring(64));
+ // Certificate type codes (see ProductIdToCodeMap below) that carry multiple names
+ // and therefore need SubjectAlternativeNames populated on the registration request.
+ private static readonly HashSet MultiNameCertificateTypes = new() { "2", "6", "7", "8", "9" };
+
+ // Certificate type codes that require EvCertificateDetails (Organization Country, etc.).
+ private static readonly HashSet EvCertificateTypes = new() { "3", "7" };
+
private static string GetOptionalParam(EnrollmentProductInfo productInfo, string key)
{
return productInfo.ProductParameters != null &&
@@ -322,6 +329,22 @@ public RegistrationRequest GetRegistrationRequest(EnrollmentProductInfo productI
};
}
+ // Maps each canonical (1.2.0+) product ID to the numeric certificate type code CSC's API
+ // expects on enrollment. Order matches ProductIDs.productIds in Constants.cs.
+ private static readonly Dictionary ProductIdToCodeMap = new(StringComparer.OrdinalIgnoreCase)
+ {
+ ["CSC TrustedSecure OV"] = "0",
+ ["CSC TrustedSecure OV Wildcard"] = "1",
+ ["CSC TrustedSecure OV, Multiple Names"] = "2",
+ ["CSC TrustedSecure EV"] = "3",
+ ["CSC TrustedSecure DV"] = "4",
+ ["CSC TrustedSecure DV Wildcard"] = "5",
+ ["CSC TrustedSecure DV, Multiple Names"] = "6",
+ ["CSC TrustedSecure EV, Multiple Names"] = "7",
+ ["CSC TrustedSecure OV Wildcard, Multiple Names"] = "8",
+ ["CSC TrustedSecure DV Wildcard, Multiple Names"] = "9"
+ };
+
private string GetCertificateType(string productId)
{
if (productId != null && ProductIDs.legacyProductIdAliases.TryGetValue(productId, out var canonicalProductId))
@@ -329,6 +352,14 @@ private string GetCertificateType(string productId)
productId = canonicalProductId;
}
+ if (productId != null && ProductIdToCodeMap.TryGetValue(productId, out var code))
+ {
+ return code;
+ }
+
+ return "-1";
+ }
+
public Notifications GetNotifications(EnrollmentProductInfo productInfo)
{
var notificationEmails = GetOptionalParam(productInfo, "Notification Email(s) Comma Separated");