Skip to content

Commit 1f51e8a

Browse files
authored
Merge pull request #52 from Keyfactor/smartcardeku
Smartcardeku
2 parents 56f8d13 + 2926f4f commit 1f51e8a

5 files changed

Lines changed: 64 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,10 @@
2323
* Remove caching of product ID lookups from DigiCert account
2424

2525
### 2.2.0
26-
* Add support for duplicating certs
26+
* Add support for duplicating certs
27+
28+
### 2.2.1
29+
* Properly mark 'needs_approval' status as Pending rather than Failed
30+
31+
### 2.3.0
32+
* Add configuration flag to support adding KDC/SmartCardLogon EKU to ssl cert requests

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ An API Key within your Digicert account that has the necessary permissions to en
106106
* **Organization-Name** - OPTIONAL: For requests that will not have a subject (such as ACME) you can use this field to provide the organization name. Value supplied here will override any CSR values, so do not include this field if you want the organization from the CSR to be used.
107107
* **RenewalWindowDays** - OPTIONAL: The number of days from certificate expiration that the gateway should do a renewal rather than a reissue. If not provided, default is 90.
108108
* **CertType** - OPTIONAL: The type of cert to enroll for. Valid values are 'ssl' and 'client'. The value provided here must be consistant with the ProductID. If not provided, default is 'ssl'. Ignored for secure_email_* product types.
109-
* **IncludeClientAuthEKU** - OPTIONAL for SSL certs, ignored otherwise. If set to 'true', SSL certs enrolled under this template will have the Client Authentication EKU added to the request. NOTE: This feature is currently planned to be removed by DigiCert in May 2026.
109+
* **IncludeClientAuthEKU** - OPTIONAL for SSL certs, ignored otherwise. If set to 'true', SSL certs enrolled under this template will have the Client Authentication EKU added to the request. NOTE: This feature is currently planned to be removed by DigiCert in March 2027.
110+
* **IncludeKDCSmartCardLogonEKU** - OPTIONAL for SSL certs, ignored otherwise. If set to 'true', SSL certs enrolled under this template will have the KDC/SmartCardLogon EKU added to the request.
110111
* **EnrollDivisionId** - OPTIONAL: The division (container) ID to use for enrollments against this template.
111112
* **CommonNameIndicator** - Required for secure_email_sponsor and secure_email_organization products, ignored otherwise. Defines the source of the common name. Valid values are: email_address, given_name_surname, pseudonym, organization_name
112113
* **ProfileType** - Optional for secure_email_* types, ignored otherwise. Valid values are: strict, multipurpose. Use 'multipurpose' if your cert includes any additional EKUs such as client auth. Default if not provided is dependent on product configuration within Digicert portal.

digicert-certcentral-caplugin/CertCentralCAPlugin.cs

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Keyfactor.Extensions.CAPlugin.DigiCert.Client;
66
using Keyfactor.Extensions.CAPlugin.DigiCert.Models;
77
using Keyfactor.Logging;
8+
using Keyfactor.PKI;
89
using Keyfactor.PKI.Enums;
910
using Keyfactor.PKI.Enums.EJBCA;
1011

@@ -126,12 +127,15 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
126127
string commonName = null, organization = null, orgUnit = null;
127128
try
128129
{
129-
subjectParsed = new X509Name(subject);
130+
subjectParsed = new X509Name(true, PKIConstants.X509.OIDLookup, subject);
130131
commonName = subjectParsed.GetValueList(X509Name.CN).Cast<string>().LastOrDefault();
131132
organization = subjectParsed.GetValueList(X509Name.O).Cast<string>().LastOrDefault();
132133
orgUnit = subjectParsed.GetValueList(X509Name.OU).Cast<string>().LastOrDefault();
133134
}
134-
catch (Exception) { }
135+
catch (Exception exc)
136+
{
137+
_logger.LogInformation($"Error while parsing subject. This might be expected. Error message: {exc.Message}");
138+
}
135139

136140
if (commonName == null)
137141
{
@@ -295,10 +299,23 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
295299
string priorCertSnString = null;
296300
string priorCertReqID = null;
297301

298-
if (typeOfCert.Equals("ssl") && Convert.ToBoolean(productInfo.ProductParameters[CertCentralConstants.Config.INCLUDE_CLIENT_AUTH]))
302+
if (typeOfCert.Equals("ssl"))
299303
{
300-
orderRequest.Certificate.ProfileOption = "server_client_auth_eku";
301-
_logger.LogWarning($"{CertCentralConstants.Config.INCLUDE_CLIENT_AUTH}: Ability to include client auth EKU in SSL certs is currently planned to cease in May 2026. Make sure any workflows that depend on this feature are updated before then to avoid interruptions.");
304+
bool clientAuth = Convert.ToBoolean(productInfo.ProductParameters[CertCentralConstants.Config.INCLUDE_CLIENT_AUTH]);
305+
bool kdc = Convert.ToBoolean(productInfo.ProductParameters[CertCentralConstants.Config.INCLUDE_KDC]);
306+
if (clientAuth && kdc)
307+
{
308+
throw new Exception($"Cannot enroll for cert with both Client Auth and KDC/SmartCardLogon EKU set to 'true'");
309+
}
310+
if (clientAuth)
311+
{
312+
orderRequest.Certificate.ProfileOption = "server_client_auth_eku";
313+
_logger.LogWarning($"{CertCentralConstants.Config.INCLUDE_CLIENT_AUTH}: Ability to include client auth EKU in SSL certs is currently planned to cease in March 2027. Make sure any workflows that depend on this feature are updated before then to avoid interruptions.");
314+
}
315+
else if (kdc)
316+
{
317+
orderRequest.Certificate.ProfileOption = "kdc_smart_card";
318+
}
302319
}
303320

304321
bool dupe = false;
@@ -616,7 +633,14 @@ public Dictionary<string, PropertyConfigInfo> GetTemplateParameterAnnotations()
616633
},
617634
[CertCentralConstants.Config.INCLUDE_CLIENT_AUTH] = new PropertyConfigInfo()
618635
{
619-
Comments = "OPTIONAL for SSL certs, ignored otherwise. If set to 'true', SSL certs enrolled under this template will have the Client Authentication EKU added to the request. NOTE: This feature is currently planned to be removed by DigiCert in May 2026.",
636+
Comments = "OPTIONAL for SSL certs, ignored otherwise. If set to 'true', SSL certs enrolled under this template will have the Client Authentication EKU added to the request. NOTE: This feature is currently planned to be removed by DigiCert in March 2027.",
637+
Hidden = false,
638+
DefaultValue = false,
639+
Type = "Boolean"
640+
},
641+
[CertCentralConstants.Config.INCLUDE_KDC] = new PropertyConfigInfo()
642+
{
643+
Comments = "OPTIONAL for SSL certs, ignored otherwise. If set to 'true', SSL certs enrolled under this template will have the KDC/SmartCardLogon EKU added to the request.",
620644
Hidden = false,
621645
DefaultValue = false,
622646
Type = "Boolean"
@@ -1064,9 +1088,9 @@ public async Task ValidateProductInfo(EnrollmentProductInfo productInfo, Diction
10641088
CertificateTypeDetailsRequest detailsRequest = new CertificateTypeDetailsRequest(product.NameId);
10651089

10661090
detailsRequest.ContainerId = null;
1067-
if (connectionInfo.ContainsKey(CertCentralConstants.Config.DIVISION_ID))
1091+
if (productInfo.ProductParameters.ContainsKey(CertCentralConstants.Config.ENROLL_DIVISION_ID))
10681092
{
1069-
string div = connectionInfo[CertCentralConstants.Config.DIVISION_ID].ToString();
1093+
string div = productInfo.ProductParameters[CertCentralConstants.Config.ENROLL_DIVISION_ID].ToString();
10701094
if (!string.IsNullOrWhiteSpace(div))
10711095
{
10721096
if (int.TryParse($"{div}", out int divId))
@@ -1088,15 +1112,30 @@ public async Task ValidateProductInfo(EnrollmentProductInfo productInfo, Diction
10881112

10891113
if (!Constants.ProductTypes.SMIME_CERT.Contains(productInfo.ProductID, StringComparer.OrdinalIgnoreCase))
10901114
{
1091-
if (connectionInfo.ContainsKey(CertCentralConstants.Config.CERT_TYPE))
1115+
if (productInfo.ProductParameters.ContainsKey(CertCentralConstants.Config.CERT_TYPE))
10921116
{
1093-
var typeOfCert = (string)connectionInfo[CertCentralConstants.Config.CERT_TYPE];
1117+
var typeOfCert = (string)productInfo.ProductParameters[CertCentralConstants.Config.CERT_TYPE];
10941118
if (!(typeOfCert.Equals("ssl") || typeOfCert.Equals("client")))
10951119
{
10961120
throw new AnyCAValidationException("Invalid Cert Type specified. Valid options are 'ssl' or 'client'");
10971121
}
10981122
}
10991123
}
1124+
1125+
bool clientAuth = false, kdc = false;
1126+
if (productInfo.ProductParameters.ContainsKey(CertCentralConstants.Config.INCLUDE_CLIENT_AUTH))
1127+
{
1128+
clientAuth = Convert.ToBoolean(productInfo.ProductParameters[CertCentralConstants.Config.INCLUDE_CLIENT_AUTH]);
1129+
}
1130+
if (productInfo.ProductParameters.ContainsKey(CertCentralConstants.Config.INCLUDE_KDC))
1131+
{
1132+
kdc = Convert.ToBoolean(productInfo.ProductParameters[CertCentralConstants.Config.INCLUDE_KDC]);
1133+
}
1134+
if (clientAuth && kdc)
1135+
{
1136+
throw new AnyCAValidationException($"Unable to use both {CertCentralConstants.Config.INCLUDE_CLIENT_AUTH} and {CertCentralConstants.Config.INCLUDE_KDC} in the same certificate.");
1137+
}
1138+
11001139
_logger.MethodExit(LogLevel.Trace);
11011140
}
11021141

digicert-certcentral-caplugin/Constants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class Config
3434
public const string SYNC_EXPIRATION_DAYS = "SyncExpirationDays";
3535
public const string CERT_TYPE = "CertType";
3636
public const string INCLUDE_CLIENT_AUTH = "IncludeClientAuthEKU";
37+
public const string INCLUDE_KDC = "IncludeKDCSmartCardLogonEKU";
3738
public const string ENROLL_DIVISION_ID = "EnrollDivisionId";
3839
public const string COMMON_NAME_INDICATOR = "CommonNameIndicator";
3940
public const string PROFILE_TYPE = "ProfileType";

integration-manifest.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@
7474
},
7575
{
7676
"name": "IncludeClientAuthEKU",
77-
"description": "OPTIONAL for SSL certs, ignored otherwise. If set to 'true', SSL certs enrolled under this template will have the Client Authentication EKU added to the request. NOTE: This feature is currently planned to be removed by DigiCert in May 2026."
77+
"description": "OPTIONAL for SSL certs, ignored otherwise. If set to 'true', SSL certs enrolled under this template will have the Client Authentication EKU added to the request. NOTE: This feature is currently planned to be removed by DigiCert in March 2027."
78+
},
79+
{
80+
"name": "IncludeKDCSmartCardLogonEKU",
81+
"description": "OPTIONAL for SSL certs, ignored otherwise. If set to 'true', SSL certs enrolled under this template will have the KDC/SmartCardLogon EKU added to the request."
7882
},
7983
{
8084
"name": "EnrollDivisionId",

0 commit comments

Comments
 (0)