Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ Fix for JSON serialization of revocation
1.1.0
Add support for using the cert upload feature to upload auth certs
Switch to .NET 8

1.1.1
Allow for manual specification of enrollment term length
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ In addition, for the admin account you plan to use, make sure it has the API adm
* **MultiDomain** - This flag lets Keyfactor know if the certificate can contain multiple domain names. Depending on the setting, the SAN entries of the request will change to support Sectigo requirements.
* **Organization** - If the organization name is provided here, the Sectigo gateway will use that organization name in requests instead of whatever is in the O= field in the request subject.
* **Department** - If your Sectigo account is using department-level products, put the appropriate department name here. Previously, this was alternatively supplied in the OU= subject field, which is now deprecated.
* **Lifetime** - OPTIONAL: The term length (in days) to use for enrollment. If not provided, the default is the first value available in the profile definition in your Sectigo account.



Expand Down
4 changes: 4 additions & 0 deletions integration-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@
{
"name": "Department",
"description": "If your Sectigo account is using department-level products, put the appropriate department name here. Previously, this was alternatively supplied in the OU= subject field, which is now deprecated."
},
{
"name": "Lifetime",
"description": "OPTIONAL: The term length (in days) to use for enrollment. If not provided, the default is the first value available in the profile definition in your Sectigo account."
}
]
}
Expand Down
1 change: 1 addition & 0 deletions sectigo-scm-caplugin/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class Config
public const string MULTIDOMAIN = "MultiDomain";
public const string ORGANIZATION = "Organization";
public const string DEPARTMENT = "Department";
public const string LIFETIME = "Lifetime";
}

//headers for API client
Expand Down
33 changes: 30 additions & 3 deletions sectigo-scm-caplugin/SectigoCAPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,26 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
_logger.LogTrace($"Found {enrollmentProfile.name} profile for enroll request");
}

int termLength;
var profileTerms = Task.Run(async () => await GetProfileTerms(int.Parse(productInfo.ProductID))).Result;
if (!string.IsNullOrEmpty(productInfo.ProductParameters[Constants.Config.LIFETIME]))
{
var tempTerm = int.Parse(productInfo.ProductParameters[Constants.Config.LIFETIME]);
if (profileTerms.Contains(tempTerm))
{
termLength = tempTerm;
}
else
{
_logger.LogError($"Specified term length of {tempTerm} does not match available terms for product ID {productInfo.ProductID}. Available terms are {string.Join(",", profileTerms)}");
throw new Exception($"Specified term length of {tempTerm} does not match available terms for product ID {productInfo.ProductID}");
}
}
else
{
termLength = profileTerms[0];
}

int sslId;
string priorSn = string.Empty;
Certificate newCert = null;
Expand All @@ -216,7 +236,7 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
{
csr = csr,
orgId = requestOrgId,
term = Task.Run(async () => await GetProfileTerm(int.Parse(productInfo.ProductID))).Result,
term = termLength,
certType = enrollmentProfile.id,
//External requestor is expected to be an email. Use config to pull the enrollment field or send blank
//sectigo will default to the account (API account) making the request.
Expand Down Expand Up @@ -431,6 +451,13 @@ public Dictionary<string, PropertyConfigInfo> GetTemplateParameterAnnotations()
Hidden = false,
DefaultValue = "",
Type = "String"
},
[Constants.Config.LIFETIME] = new PropertyConfigInfo()
{
Comments = "OPTIONAL: The term length (in days) to use for enrollment. If not provided, the default is the first value available in the profile definition in your Sectigo account.",
Hidden = false,
DefaultValue = "",
Type = "String"
}
};
}
Expand Down Expand Up @@ -674,11 +701,11 @@ private async Task<Organization> GetOrganizationAsync(string orgName)
return orgList.Organizations.Where(x => x.name.ToLower().Equals(orgName.ToLower())).FirstOrDefault();
}

private async Task<int> GetProfileTerm(int profileId)
private async Task<List<int>> GetProfileTerms(int profileId)
{
var client = SectigoClient.InitializeClient(_config, _certificateResolver);
var profileList = await client.ListSslProfiles();
return profileList.SslProfiles.Where(x => x.id == profileId).FirstOrDefault().terms[0];
return profileList.SslProfiles.Where(x => x.id == profileId).FirstOrDefault().terms.ToList();
}

private async Task<Profile> GetProfile(int profileId)
Expand Down