Skip to content

Commit f55be6f

Browse files
fixed field issues
1 parent 73e8456 commit f55be6f

5 files changed

Lines changed: 80 additions & 52 deletions

File tree

SslStoreCaProxy/Interfaces/IRequestManager.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
using System.Collections.Generic;
12
using Keyfactor.AnyGateway.Extensions;
23
using Keyfactor.AnyGateway.SslStore.Client.Models;
34

45
namespace Keyfactor.AnyGateway.SslStore.Interfaces
56
{
67
public interface IRequestManager
78
{
8-
NewOrderRequest GetEnrollmentRequest(string csr, EnrollmentProductInfo productInfo,
9-
IAnyCAPluginConfigProvider configProvider, bool isRenewalOrder);
9+
NewOrderRequest GetEnrollmentRequest(string csr, string subject, Dictionary<string, string[]> san,
10+
EnrollmentProductInfo productInfo, IAnyCAPluginConfigProvider configProvider, bool isRenewalOrder);
1011

1112
AuthRequest GetAuthRequest();
1213
ReIssueRequest GetReIssueRequest(INewOrderResponse orderData, string csr, bool isRenewal);

SslStoreCaProxy/ProductDefinitions.cs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ private static List<EnrollmentField> LegacyFullFields(List<string> validity)
102102
DropdownField("Signature Hash Algorithm", SignatureHashAlgorithms),
103103
DropdownField("Web Server Type", WebServerTypes),
104104
TextField("Server Count"),
105-
DropdownField("Validity Period (In Months)", validity),
105+
TextField("Validity Period (In Days)"),
106106
TextField("Organization Name"),
107107
TextField("Organization Address"),
108108
TextField("Organization Region"),
@@ -115,7 +115,7 @@ private static List<EnrollmentField> LegacyFullFields(List<string> validity)
115115
// Group 1b: Legacy Full + DNS Names + Jurisdiction (38 fields) - digi_quickssl_md
116116
private static List<EnrollmentField> LegacyFullDnsJurisdictionFields(List<string> validity)
117117
{
118-
var fields = new List<EnrollmentField> { TextField("DNS Names Comma Separated") };
118+
var fields = new List<EnrollmentField>();
119119
fields.AddRange(LegacyFullFields(validity));
120120
// Insert Jurisdiction Country before Organization Phone (at the end)
121121
fields.Insert(fields.Count - 1, DropdownField("Organization Jurisdiction Country", CountryCodes));
@@ -127,8 +127,8 @@ private static List<EnrollmentField> EoMinimalFields()
127127
{
128128
return new List<EnrollmentField>
129129
{
130-
TextField("DNS Names Comma Separated"),
131-
DropdownField("Validity Period (In Months)", ValidityDigicert),
130+
131+
TextField("Validity Period (In Days)"),
132132
DropdownField("Organization ID", new List<string>())
133133
};
134134
}
@@ -140,7 +140,7 @@ private static List<EnrollmentField> SectigoOvFields()
140140
{
141141
TextField("Admin Contact - Email"),
142142
TextField("Approver Email"),
143-
DropdownField("Validity Period (In Months)", ValidityStandard),
143+
TextField("Validity Period (In Days)"),
144144
TextField("Organization Name"),
145145
TextField("Organization Address"),
146146
TextField("Organization State/Province"),
@@ -155,13 +155,13 @@ private static List<EnrollmentField> DigiCertOvFlexFields()
155155
{
156156
return new List<EnrollmentField>
157157
{
158-
TextField("DNS Names Comma Separated"),
158+
159159
TextField("Admin Contact - First Name"),
160160
TextField("Admin Contact - Last Name"),
161161
TextField("Admin Contact - Phone"),
162162
TextField("Admin Contact - Email"),
163163
TextField("Approver Email"),
164-
DropdownField("Validity Period (In Months)", ValidityDigicert),
164+
TextField("Validity Period (In Days)"),
165165
TextField("Organization Name"),
166166
TextField("Organization Address"),
167167
TextField("Organization City"),
@@ -179,7 +179,7 @@ private static List<EnrollmentField> DvMinimalFields()
179179
{
180180
TextField("Admin Contact - Email"),
181181
TextField("Approver Email"),
182-
DropdownField("Validity Period (In Months)", ValidityStandard)
182+
TextField("Validity Period (In Days)")
183183
};
184184
}
185185

@@ -188,14 +188,14 @@ private static List<EnrollmentField> DigiCertEvFlexFields(string regionFieldName
188188
{
189189
return new List<EnrollmentField>
190190
{
191-
TextField("DNS Names Comma Separated"),
191+
192192
TextField("Admin Contact - First Name"),
193193
TextField("Admin Contact - Last Name"),
194194
TextField("Admin Contact - Phone"),
195195
TextField("Admin Contact - Email"),
196196
TextField("Admin Contact - Title"),
197197
TextField("Approver Email"),
198-
DropdownField("Validity Period (In Months)", ValidityDigicert),
198+
TextField("Validity Period (In Days)"),
199199
TextField("Organization Name"),
200200
TextField("Organization Address"),
201201
TextField("Organization City"),
@@ -211,10 +211,10 @@ private static List<EnrollmentField> DvMdcFields()
211211
{
212212
return new List<EnrollmentField>
213213
{
214-
TextField("DNS Names Comma Separated"),
214+
215215
TextField("Admin Contact - Email"),
216216
TextField("Approver Email"),
217-
DropdownField("Validity Period (In Months)", ValidityStandard)
217+
TextField("Validity Period (In Days)")
218218
};
219219
}
220220

@@ -225,7 +225,7 @@ private static List<EnrollmentField> DigiCertDvRapidSslFields()
225225
{
226226
TextField("Technical Contact - Email"),
227227
TextField("Approver Email"),
228-
DropdownField("Validity Period (In Months)", ValidityDigicert)
228+
TextField("Validity Period (In Days)")
229229
};
230230
}
231231

@@ -234,10 +234,10 @@ private static List<EnrollmentField> DigiCertDvGeoTrustFields()
234234
{
235235
return new List<EnrollmentField>
236236
{
237-
TextField("DNS Names Comma Separated"),
237+
238238
TextField("Technical Contact - Email"),
239239
TextField("Approver Email"),
240-
DropdownField("Validity Period (In Months)", ValidityDigicert)
240+
TextField("Validity Period (In Days)")
241241
};
242242
}
243243

@@ -248,7 +248,7 @@ private static List<EnrollmentField> EvJurisdictionFields()
248248
{
249249
TextField("Admin Contact - Email"),
250250
TextField("Approver Email"),
251-
DropdownField("Validity Period (In Months)", ValidityStandard),
251+
TextField("Validity Period (In Days)"),
252252
TextField("Organization Name"),
253253
TextField("Organization Address"),
254254
TextField("Organization State/Province"),
@@ -264,10 +264,10 @@ private static List<EnrollmentField> EvMdcJurisdictionFields()
264264
{
265265
return new List<EnrollmentField>
266266
{
267-
TextField("DNS Names Comma Separated"),
267+
268268
TextField("Admin Contact - Email"),
269269
TextField("Approver Email"),
270-
DropdownField("Validity Period (In Months)", ValidityStandard),
270+
TextField("Validity Period (In Days)"),
271271
TextField("Organization Name"),
272272
TextField("Organization Address"),
273273
TextField("Organization State/Province"),
@@ -283,10 +283,10 @@ private static List<EnrollmentField> EvMdcJurisdictionAltFields()
283283
{
284284
return new List<EnrollmentField>
285285
{
286-
TextField("DNS Names Comma Separated"),
286+
287287
TextField("Admin Contact - Email"),
288288
TextField("Approver Email"),
289-
DropdownField("Validity Period (In Months)", ValidityStandard),
289+
TextField("Validity Period (In Days)"),
290290
TextField("Organization Name"),
291291
TextField("Organization Address"),
292292
TextField("Organization State/Province"),
@@ -302,10 +302,10 @@ private static List<EnrollmentField> OvMdcFields()
302302
{
303303
return new List<EnrollmentField>
304304
{
305-
TextField("DNS Names Comma Separated"),
305+
306306
TextField("Admin Contact - Email"),
307307
TextField("Approver Email"),
308-
DropdownField("Validity Period (In Months)", ValidityStandard),
308+
TextField("Validity Period (In Days)"),
309309
TextField("Organization Name"),
310310
TextField("Organization Address"),
311311
TextField("Organization State/Province"),
@@ -322,7 +322,7 @@ private static List<EnrollmentField> EnterpriseProOvFields()
322322
{
323323
TextField("Admin Contact - First Name"),
324324
TextField("Approver Email"),
325-
DropdownField("Validity Period (In Months)", ValidityStandard),
325+
TextField("Validity Period (In Days)"),
326326
TextField("Organization Name"),
327327
TextField("Organization Address"),
328328
TextField("Organization State/Province"),

SslStoreCaProxy/RequestManager.cs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ public RequestManager(SslStoreCaProxy sslStoreCaProxy)
2828
_sslStoreCaProxy = sslStoreCaProxy;
2929
}
3030

31-
public NewOrderRequest GetEnrollmentRequest(string csr, EnrollmentProductInfo productInfo,
32-
IAnyCAPluginConfigProvider configProvider, bool isRenewalOrder)
31+
public NewOrderRequest GetEnrollmentRequest(string csr, string subject, Dictionary<string, string[]> san,
32+
EnrollmentProductInfo productInfo, IAnyCAPluginConfigProvider configProvider, bool isRenewalOrder)
3333
{
3434
var pemCsr = ConvertCsrToPem(csr);
3535

@@ -41,7 +41,7 @@ public NewOrderRequest GetEnrollmentRequest(string csr, EnrollmentProductInfo pr
4141
MissingMemberHandling = MissingMemberHandling.Ignore
4242
};
4343
var request = BuildNewOrderRequest(productInfo,
44-
JsonConvert.DeserializeObject<TemplateNewOrderRequest>(sampleRequest, settings), pemCsr, isRenewalOrder);
44+
JsonConvert.DeserializeObject<TemplateNewOrderRequest>(sampleRequest, settings), pemCsr, subject, san, isRenewalOrder);
4545

4646
return request;
4747
}
@@ -251,11 +251,21 @@ public TechnicalContact GetTechnicalContact(INewOrderResponse productInfo)
251251
}
252252

253253
private NewOrderRequest BuildNewOrderRequest(EnrollmentProductInfo productInfo,
254-
TemplateNewOrderRequest newOrderRequest, string csr, bool isRenewal)
254+
TemplateNewOrderRequest newOrderRequest, string csr, string subject, Dictionary<string, string[]> san, bool isRenewal)
255255
{
256256
var customOrderId = Guid.NewGuid().ToString();
257257
productInfo.ProductParameters.Add("CustomOrderId", customOrderId);
258258

259+
// Extract domain name from CSR subject CN
260+
var domainName = subject?.Split(',')
261+
.Select(p => p.Trim())
262+
.Where(p => p.StartsWith("CN=", StringComparison.OrdinalIgnoreCase))
263+
.Select(p => p.Substring(3))
264+
.FirstOrDefault() ?? "";
265+
266+
// Extract DNS SANs from Keyfactor san parameter
267+
var dnsNames = san != null && san.ContainsKey("dns") ? san["dns"] : Array.Empty<string>();
268+
259269
var request =
260270
new JObject(
261271
new JObject(
@@ -289,12 +299,12 @@ private NewOrderRequest BuildNewOrderRequest(EnrollmentProductInfo productInfo,
289299
CreatePropertyFromTemplate(
290300
"$.OrganizationInfo.OrganizationAddress.LocalityName", productInfo,
291301
newOrderRequest))))),
292-
CreatePropertyFromTemplate("$.ValidityPeriod", productInfo, newOrderRequest),
302+
new JProperty("ValidityPeriod", ConvertDaysToMonths(productInfo)),
293303
new JProperty("ServerCount", 1),
294304
new JProperty("CSR", csr),
295-
CreatePropertyFromTemplate("$.DomainName", productInfo, newOrderRequest),
305+
new JProperty("DomainName", domainName),
296306
new JProperty("WebServerType", "Other"),
297-
CreatePropertyFromTemplate("$.DNSNames", productInfo, newOrderRequest, true),
307+
new JProperty("DNSNames", new JArray(dnsNames)),
298308
new JProperty("isCUOrder", false),
299309
CreatePropertyFromTemplate("$.AutoWWW", productInfo, newOrderRequest),
300310
new JProperty("IsRenewalOrder", isRenewal),
@@ -395,6 +405,21 @@ private JProperty CreatePropertyFromTemplate(string propertyPath, EnrollmentProd
395405
return new JProperty(propertyPath.Substring(propertyPath.LastIndexOf('.') + 1), null);
396406
}
397407

408+
private long ConvertDaysToMonths(EnrollmentProductInfo productInfo)
409+
{
410+
if (productInfo.ProductParameters.ContainsKey("Validity Period (In Days)") &&
411+
long.TryParse(productInfo.ProductParameters["Validity Period (In Days)"], out var days))
412+
{
413+
// Convert days to months, rounding up so short-lived certs (e.g. 90 days) get at least 1 month
414+
var months = (long)Math.Ceiling(days / 30.0);
415+
_logger.LogTrace($"Validity conversion: {days} days -> {months} months");
416+
return months;
417+
}
418+
419+
_logger.LogWarning("Validity Period (In Days) not found or invalid, defaulting to 12 months");
420+
return 12;
421+
}
422+
398423
private string ExtractOrgId(string organization)
399424
{
400425
if (organization != null)

SslStoreCaProxy/SslStoreCAPluginConfig.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,25 +71,18 @@ public static Dictionary<string, PropertyConfigInfo> GetTemplateParameterAnnotat
7171
{
7272
return new Dictionary<string, PropertyConfigInfo>()
7373
{
74-
["DNS Names Comma Separated"] = new PropertyConfigInfo()
75-
{
76-
Comments = "Comma-separated list of DNS names (SANs) for the certificate.",
77-
Hidden = false,
78-
DefaultValue = "",
79-
Type = "String"
80-
},
8174
["Approver Email"] = new PropertyConfigInfo()
8275
{
8376
Comments = "Comma-separated approver email address(es) for domain validation.",
8477
Hidden = false,
8578
DefaultValue = "",
8679
Type = "String"
8780
},
88-
["Validity Period (In Months)"] = new PropertyConfigInfo()
81+
["Validity Period (In Days)"] = new PropertyConfigInfo()
8982
{
90-
Comments = "Certificate validity period in months (e.g. 12, 24, 36, 48, 60, 72).",
83+
Comments = "Certificate validity period in days (e.g. 90, 365, 730).",
9184
Hidden = false,
92-
DefaultValue = "12",
85+
DefaultValue = "365",
9386
Type = "String"
9487
},
9588
["Admin Contact - First Name"] = new PropertyConfigInfo()

SslStoreCaProxy/SslStoreCaProxy.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -167,24 +167,33 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
167167

168168
if (!productInfo.ProductParameters.ContainsKey("PriorCertSN"))
169169
{
170-
string[] arrayProducts = Array.Empty<string>();
171-
string[] arrayApproverEmails = Array.Empty<string>();
170+
// Extract domain name from CSR subject and SANs from the Keyfactor san parameter
171+
var domainName = subject?.Split(',')
172+
.Select(p => p.Trim())
173+
.Where(p => p.StartsWith("CN=", StringComparison.OrdinalIgnoreCase))
174+
.Select(p => p.Substring(3))
175+
.FirstOrDefault() ?? "";
176+
_logger.LogTrace($"Domain Name from subject: {domainName}");
172177

173-
if (productInfo.ProductParameters.ContainsKey("DNS Names Comma Separated"))
174-
{
175-
_logger.LogTrace($"DNS Comma Separated {productInfo.ProductParameters["DNS Names Comma Separated"]}");
176-
arrayProducts = productInfo.ProductParameters["DNS Names Comma Separated"].Split(new char[] { ',' });
177-
}
178+
var dnsNames = san != null && san.ContainsKey("dns") ? san["dns"] : Array.Empty<string>();
179+
_logger.LogTrace($"DNS Names from SAN: {string.Join(",", dnsNames)}");
180+
181+
string[] arrayApproverEmails = Array.Empty<string>();
178182
if (productInfo.ProductParameters.ContainsKey("Approver Email"))
179183
{
180184
_logger.LogTrace($"Approver Email {productInfo.ProductParameters["Approver Email"]}");
181185
arrayApproverEmails = productInfo.ProductParameters["Approver Email"].Split(new char[] { ',' });
182186
}
183187

188+
// Validate approver emails against all domains (CN + SANs)
189+
var allDomains = new List<string>();
190+
if (!string.IsNullOrEmpty(domainName)) allDomains.Add(domainName);
191+
allDomains.AddRange(dnsNames.Where(d => !string.Equals(d, domainName, StringComparison.OrdinalIgnoreCase)));
192+
184193
var count = 1;
185-
foreach (var product in arrayProducts)
194+
foreach (var domain in allDomains)
186195
{
187-
var emailApproverRequest = _requestManager.GetEmailApproverListRequest(productInfo.ProductID, product);
196+
var emailApproverRequest = _requestManager.GetEmailApproverListRequest(productInfo.ProductID, domain);
188197
_logger.LogTrace($"Email Approver Request JSON {JsonConvert.SerializeObject(emailApproverRequest)}");
189198

190199
var emailApproverResponse = await client.SubmitEmailApproverRequestAsync(emailApproverRequest);
@@ -204,7 +213,7 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
204213
count++;
205214
}
206215

207-
var enrollmentRequest = _requestManager.GetEnrollmentRequest(csr, productInfo, Config, false);
216+
var enrollmentRequest = _requestManager.GetEnrollmentRequest(csr, subject, san, productInfo, Config, false);
208217
_logger.LogTrace($"enrollmentRequest JSON {JsonConvert.SerializeObject(enrollmentRequest)}");
209218

210219
enrollmentResponse = await client.SubmitNewOrderRequestAsync(enrollmentRequest);

0 commit comments

Comments
 (0)