Skip to content

Commit c3fd20e

Browse files
authored
Merge 75e8166 into a7c3110
2 parents a7c3110 + 75e8166 commit c3fd20e

File tree

7 files changed

+99
-13
lines changed

7 files changed

+99
-13
lines changed

cscglobal-caplugin/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
v1.1.0
2+
- Support for custom fields in enrollment
3+
- Support for returning CNAME tokens from enrollment call
4+
5+
v1.0.1
6+
- Fixed issue with SANs not being read correctly.
7+
8+
v1.0
9+
- Initial Release.

cscglobal-caplugin/CSCGlobalCAPlugin.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,15 +203,17 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
203203
}
204204

205205
string uUId;
206-
switch (enrollmentType)
206+
var customFields = await CscGlobalClient.SubmitGetCustomFields();
207+
208+
switch (enrollmentType)
207209
{
208210
case EnrollmentType.New:
209211
Logger.LogTrace("Entering New Enrollment");
210212
//If they renewed an expired cert it gets here and this will not be supported
211213
IRegistrationResponse enrollmentResponse;
212214
if (!productInfo.ProductParameters.ContainsKey("PriorCertSN"))
213215
{
214-
enrollmentRequest = _requestManager.GetRegistrationRequest(productInfo, csr, san);
216+
enrollmentRequest = _requestManager.GetRegistrationRequest(productInfo, csr, san, customFields);
215217
Logger.LogTrace($"Enrollment Request JSON: {JsonConvert.SerializeObject(enrollmentRequest)}");
216218
enrollmentResponse =
217219
Task.Run(async () => await CscGlobalClient.SubmitRegistrationAsync(enrollmentRequest))
@@ -253,7 +255,7 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
253255
uUId = await _certificateDataReader.GetRequestIDBySerialNumber(
254256
productInfo.ProductParameters["PriorCertSN"]);
255257
Logger.LogTrace($"Renew uUId: {uUId}");
256-
renewRequest = _requestManager.GetRenewalRequest(productInfo, uUId, csr, san);
258+
renewRequest = _requestManager.GetRenewalRequest(productInfo, uUId, csr, san, customFields);
257259
Logger.LogTrace($"Renewal Request JSON: {JsonConvert.SerializeObject(renewRequest)}");
258260
var renewResponse = Task.Run(async () => await CscGlobalClient.SubmitRenewalAsync(renewRequest))
259261
.Result;
@@ -278,7 +280,7 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
278280
productInfo.ProductParameters["PriorCertSN"]);
279281
uUId = requestid.Substring(0, 36); //uUId is a GUID
280282
Logger.LogTrace($"Reissue uUId: {uUId}");
281-
reissueRequest = _requestManager.GetReissueRequest(productInfo, uUId, csr, san);
283+
reissueRequest = _requestManager.GetReissueRequest(productInfo, uUId, csr, san, customFields);
282284
Logger.LogTrace($"Reissue JSON: {JsonConvert.SerializeObject(reissueRequest)}");
283285
var reissueResponse = Task.Run(async () => await CscGlobalClient.SubmitReissueAsync(reissueRequest))
284286
.Result;

cscglobal-caplugin/Client/CscGlobalClient.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,17 @@ public async Task<CertificateResponse> SubmitGetCertificateAsync(string certific
134134
}
135135
}
136136

137+
public async Task<List<GetCustomField>> SubmitGetCustomFields()
138+
{
139+
using (var resp = await RestClient.GetAsync($"/dbs/api/v2/admin/customfields"))
140+
{
141+
resp.EnsureSuccessStatusCode();
142+
var getCustomFieldsResponse =
143+
JsonConvert.DeserializeObject<GetCustomFields>(await resp.Content.ReadAsStringAsync());
144+
return getCustomFieldsResponse.CustomFields;
145+
}
146+
}
147+
137148
public async Task<RevokeResponse> SubmitRevokeCertificateAsync(string uuId)
138149
{
139150
using (var resp = await RestClient.PutAsync($"/dbs/api/v2/tls/revoke/{uuId}", new StringContent("")))
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2021 Keyfactor
2+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
3+
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4+
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
6+
// and limitations under the License.
7+
using Keyfactor.Extensions.CAPlugin.CSCGlobal.Interfaces;
8+
using Newtonsoft.Json;
9+
10+
namespace Keyfactor.Extensions.CAPlugin.CSCGlobal.Client.Models;
11+
12+
public class GetCustomField : IGetCustomField
13+
{
14+
[JsonProperty("label")] public string Label { get; set; }
15+
[JsonProperty("mandatory")] public bool Mandatory { get; set; }
16+
}
17+
18+
public class GetCustomFields
19+
{
20+
[JsonProperty("customFields")] public List<GetCustomField> CustomFields { get; set; }
21+
}

cscglobal-caplugin/Interfaces/ICscGlobalClient.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Task<ReissueResponse> SubmitReissueAsync(
2121

2222
Task<CertificateResponse> SubmitGetCertificateAsync(string certificateId);
2323

24+
Task<List<GetCustomField>> SubmitGetCustomFields();
25+
2426
Task<CertificateListResponse> SubmitCertificateListRequestAsync();
2527

2628
Task<RevokeResponse> SubmitRevokeCertificateAsync(string uuId);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2021 Keyfactor
2+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
3+
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4+
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
6+
// and limitations under the License.
7+
namespace Keyfactor.Extensions.CAPlugin.CSCGlobal.Interfaces;
8+
9+
public interface IGetCustomField
10+
{
11+
string Label { get; set; }
12+
bool Mandatory { get; set; }
13+
}

cscglobal-caplugin/RequestManager.cs

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,34 @@
1212
using Keyfactor.PKI;
1313
using Keyfactor.PKI.Enums.EJBCA;
1414

15+
using Org.BouncyCastle.Bcpg;
16+
1517
namespace Keyfactor.Extensions.CAPlugin.CSCGlobal;
1618

1719
public class RequestManager
1820
{
1921
public static Func<string, string> Pemify = ss =>
2022
ss.Length <= 64 ? ss : ss.Substring(0, 64) + "\n" + Pemify(ss.Substring(64));
2123

22-
private List<CustomField> GetCustomFields(EnrollmentProductInfo productInfo)
24+
private List<CustomField> GetCustomFields(EnrollmentProductInfo productInfo, List<GetCustomField> customFields)
2325
{
2426
var customFieldList = new List<CustomField>();
27+
foreach (var field in customFields)
28+
{
29+
if (productInfo.ProductParameters.ContainsKey(field.Label))
30+
{
31+
var newField = new CustomField
32+
{
33+
Name = field.Label,
34+
Value = productInfo.ProductParameters[field.Label]
35+
};
36+
customFieldList.Add(newField);
37+
}
38+
else if (field.Mandatory)
39+
{
40+
throw new Exception($"Custom field {field.Label} is marked as mandatory, but was not supplied in the request.");
41+
}
42+
}
2543
return customFieldList;
2644
}
2745

@@ -55,12 +73,22 @@ public EnrollmentResult
5573
StatusMessage = registrationResponse.RegistrationError.Description
5674
};
5775

58-
return new EnrollmentResult
76+
Dictionary<string, string> cnames = new Dictionary<string, string>();
77+
if (registrationResponse.Result.DcvDetails != null && registrationResponse.Result.DcvDetails.Count > 0)
78+
{
79+
foreach (var dcv in registrationResponse.Result.DcvDetails)
80+
{
81+
cnames.Add(dcv.CName.Name, dcv.CName.Value);
82+
}
83+
}
84+
85+
return new EnrollmentResult
5986
{
6087
Status = (int)EndEntityStatus.EXTERNALVALIDATION, //success
6188
CARequestID = registrationResponse.Result.Status.Uuid,
6289
StatusMessage =
63-
$"Order Successfully Created With Order Number {registrationResponse.Result.CommonName}"
90+
$"Order Successfully Created With Order Number {registrationResponse.Result.CommonName}",
91+
EnrollmentContext = (cnames.Count > 0) ? cnames : null
6492
};
6593
}
6694

@@ -116,7 +144,7 @@ public DomainControlValidation GetDomainControlValidation(string methodType, str
116144
}
117145

118146
public RegistrationRequest GetRegistrationRequest(EnrollmentProductInfo productInfo, string csr,
119-
Dictionary<string, string[]> sans)
147+
Dictionary<string, string[]> sans, List<GetCustomField> customFields)
120148
{
121149
//var cert = "-----BEGIN CERTIFICATE REQUEST-----\r\n";
122150
var cert = Pemify(csr);
@@ -144,7 +172,7 @@ public RegistrationRequest GetRegistrationRequest(EnrollmentProductInfo productI
144172
OrganizationContact = productInfo.ProductParameters["Organization Contact"],
145173
BusinessUnit = productInfo.ProductParameters["Business Unit"],
146174
ShowPrice = true, //User should not have to fill this out
147-
CustomFields = GetCustomFields(productInfo),
175+
CustomFields = GetCustomFields(productInfo, customFields),
148176
SubjectAlternativeNames = certificateType == "2" ? GetSubjectAlternativeNames(productInfo, sans) : null,
149177
EvCertificateDetails = certificateType == "3" ? GetEvCertificateDetails(productInfo) : null
150178
};
@@ -190,7 +218,7 @@ public Notifications GetNotifications(EnrollmentProductInfo productInfo)
190218
}
191219

192220
public RenewalRequest GetRenewalRequest(EnrollmentProductInfo productInfo, string uUId, string csr,
193-
Dictionary<string, string[]> sans)
221+
Dictionary<string, string[]> sans, List<GetCustomField> customFields)
194222
{
195223
//var cert = "-----BEGIN CERTIFICATE REQUEST-----\r\n";
196224
var cert = Pemify(csr);
@@ -219,7 +247,7 @@ public RenewalRequest GetRenewalRequest(EnrollmentProductInfo productInfo, strin
219247
BusinessUnit = productInfo.ProductParameters["Business Unit"],
220248
ShowPrice = true,
221249
SubjectAlternativeNames = certificateType == "2" ? GetSubjectAlternativeNames(productInfo, sans) : null,
222-
CustomFields = GetCustomFields(productInfo),
250+
CustomFields = GetCustomFields(productInfo, customFields),
223251
EvCertificateDetails = certificateType == "3" ? GetEvCertificateDetails(productInfo) : null
224252
};
225253
}
@@ -248,7 +276,7 @@ private List<SubjectAlternativeName> GetSubjectAlternativeNames(EnrollmentProduc
248276
}
249277

250278
public ReissueRequest GetReissueRequest(EnrollmentProductInfo productInfo, string uUId, string csr,
251-
Dictionary<string, string[]> sans)
279+
Dictionary<string, string[]> sans, List<GetCustomField> customFields)
252280
{
253281
//var cert = "-----BEGIN CERTIFICATE REQUEST-----\r\n";
254282
var cert = Pemify(csr);
@@ -277,7 +305,7 @@ public ReissueRequest GetReissueRequest(EnrollmentProductInfo productInfo, strin
277305
BusinessUnit = productInfo.ProductParameters["Business Unit"],
278306
ShowPrice = true,
279307
SubjectAlternativeNames = certificateType == "2" ? GetSubjectAlternativeNames(productInfo, sans) : null,
280-
CustomFields = GetCustomFields(productInfo),
308+
CustomFields = GetCustomFields(productInfo, customFields),
281309
EvCertificateDetails = certificateType == "3" ? GetEvCertificateDetails(productInfo) : null
282310
};
283311
}

0 commit comments

Comments
 (0)