diff --git a/README.md b/README.md index 0250f2c..31c22e0 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

-Integration Status: pilot +Integration Status: production Release Issues GitHub Downloads (all assets, all releases) 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");