From 300045bd4f42e86bec6a867eebcfeb673911a6f9 Mon Sep 17 00:00:00 2001
From: Dave Galey <89407235+dgaley@users.noreply.github.com>
Date: Mon, 26 Oct 2026 00:32:42 -0400
Subject: [PATCH 1/5] Renew (#10)
* Change CARequestID to OrderId-CertId to make it easier to link externalvalidation certs when they are finally pickd up.
* Allow for configuration of duration
* Update generated docs
* add renew/reissue support
* changelog
---------
Co-authored-by: Keyfactor
---
CHANGELOG.md | 7 ++
README.md | 1 +
integration-manifest.json | 4 +
nameshield-caplugin/Constants.cs | 1 +
nameshield-caplugin/Models/Certificate.cs | 17 ++++
nameshield-caplugin/Models/Order.cs | 3 +
nameshield-caplugin/NameshieldCAPlugin.cs | 98 ++++++++++++++++---
.../nameshield-caplugin.csproj | 2 +-
8 files changed, 116 insertions(+), 17 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e69de29..76301ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -0,0 +1,7 @@
+1.0.0
+* Initial Release
+
+1.1.0
+* Added support for renew/reissue
+* Made CARequestID more consistent for pending/external validation certs
+* Allow for the specifying of custom lifetimes for certs, and comparing the provided value to the allowed values
\ No newline at end of file
diff --git a/README.md b/README.md
index 0bfb158..2448b0a 100644
--- a/README.md
+++ b/README.md
@@ -99,6 +99,7 @@ TODO Requirements is a required section
* **OrganizationId** - If you know your organization's ID in nameshield, you can supply that here and that will be used as the organization regardless of what values exist in the request or the Organization field
* **Organization** - If OrganizationId is empty, and an organization name is provided here, the Nameshield gateway will use that name to do organization lookups when enrolling. If neither OrganizationId nor Organization is supplied, the gateway will use whatever is in the O= field of the request subject.
+ * **Lifetime** - REQUIRED:The lifetime of the certificate to be issued. This should be a string in the format recognized by Nameshield (e.g. 1 year, etc.)
diff --git a/integration-manifest.json b/integration-manifest.json
index 3511222..0c297bf 100644
--- a/integration-manifest.json
+++ b/integration-manifest.json
@@ -34,6 +34,10 @@
{
"name": "Organization",
"description": "If OrganizationId is empty, and an organization name is provided here, the Nameshield gateway will use that name to do organization lookups when enrolling. If neither OrganizationId nor Organization is supplied, the gateway will use whatever is in the O= field of the request subject."
+ },
+ {
+ "name": "Lifetime",
+ "description": "REQUIRED:The lifetime of the certificate to be issued. This should be a string in the format recognized by Nameshield (e.g. 1 year, etc.)"
}
]
}
diff --git a/nameshield-caplugin/Constants.cs b/nameshield-caplugin/Constants.cs
index 0df6a51..3d8db08 100644
--- a/nameshield-caplugin/Constants.cs
+++ b/nameshield-caplugin/Constants.cs
@@ -20,6 +20,7 @@ public class Template
{
public const string ORGANIZATION_ID = "OrganizationId";
public const string ORGANIZATION = "Organization";
+ public const string LIFETIME = "Lifetime";
}
}
}
diff --git a/nameshield-caplugin/Models/Certificate.cs b/nameshield-caplugin/Models/Certificate.cs
index fe8b22b..7564225 100644
--- a/nameshield-caplugin/Models/Certificate.cs
+++ b/nameshield-caplugin/Models/Certificate.cs
@@ -44,6 +44,9 @@ public class Certificate
[JsonPropertyName("attributes")]
[JsonProperty("attributes")]
public CertificateAttributes Attributes { get; set; }
+ [JsonPropertyName("relationships")]
+ [JsonProperty("relationships")]
+ public CertificateRelationships Relationships { get; set; }
}
public class CertificateAttributes
@@ -60,4 +63,18 @@ public class CertificateAttributes
[JsonProperty("pem")]
public string Pem { get; set; }
}
+
+ public class CertificateRelationships
+ {
+ [JsonPropertyName("current-order")]
+ [JsonProperty("current-order")]
+ public CertOrderRelationship Order { get; set; }
+ }
+
+ public class CertOrderRelationship
+ {
+ [JsonPropertyName("data")]
+ [JsonProperty("data")]
+ public RelationshipData Data { get; set; }
+ }
}
diff --git a/nameshield-caplugin/Models/Order.cs b/nameshield-caplugin/Models/Order.cs
index aff4d17..88d816d 100644
--- a/nameshield-caplugin/Models/Order.cs
+++ b/nameshield-caplugin/Models/Order.cs
@@ -36,6 +36,9 @@ public class OrderAttributes
[JsonPropertyName("status")]
[JsonProperty("status")]
public string Status { get; set; }
+ [JsonPropertyName("can_renew_at")]
+ [JsonProperty("can_renew_at")]
+ public string CanRenewAt { get; set; }
}
public class OrderRelationships
diff --git a/nameshield-caplugin/NameshieldCAPlugin.cs b/nameshield-caplugin/NameshieldCAPlugin.cs
index cd7714b..d33cfd2 100644
--- a/nameshield-caplugin/NameshieldCAPlugin.cs
+++ b/nameshield-caplugin/NameshieldCAPlugin.cs
@@ -1,6 +1,7 @@
using Keyfactor.AnyGateway.Extensions;
using Keyfactor.Extensions.CAPlugin.Nameshield.API;
using Keyfactor.Extensions.CAPlugin.Nameshield.Client;
+using Keyfactor.Extensions.CAPlugin.Nameshield.Models;
using Keyfactor.Logging;
using Keyfactor.PKI.Enums.EJBCA;
@@ -36,7 +37,7 @@ public void Initialize(IAnyCAPluginConfigProvider configProvider, ICertificateDa
_config = JsonConvert.DeserializeObject(rawConfig);
}
- public async Task Enroll(string csr, string subject, Dictionary san, EnrollmentProductInfo productInfo, RequestFormat requestFormat, EnrollmentType enrollmnentType)
+ public async Task Enroll(string csr, string subject, Dictionary san, EnrollmentProductInfo productInfo, RequestFormat requestFormat, EnrollmentType enrollmentType)
{
_logger.MethodEntry(LogLevel.Debug);
NameshieldClient client = NameshieldClient.InitializeClient(_config);
@@ -93,12 +94,42 @@ public async Task Enroll(string csr, string subject, Dictionar
{
throw new Exception($"No organization provided in attributes or subject that matches an organization in the Nameshield account");
}
+ var lifetime = productInfo.ProductParameters[Constants.Config.Template.LIFETIME];
+
+ string orderAction = "create";
+
+ // Determine if we should do a renew or a reissue
+ if (enrollmentType == EnrollmentType.RenewOrReissue)
+ {
+ string priorCertSnString = productInfo.ProductParameters["PriorCertSN"];
+ var priorCertReqID = await _certificateDataReader.GetRequestIDBySerialNumber(priorCertSnString);
+ if (string.IsNullOrEmpty(priorCertReqID))
+ {
+ throw new Exception($"Cannot find prior certificate with serial number {priorCertSnString}.");
+ }
+
+ string orderId = priorCertReqID.Split('-')[0];
+
+ var orderResponse = Task.Run(async () => await client.GetOrderDetails(orderId)).Result;
+ if (orderResponse.Order.Attributes.CanRenewAt != null)
+ {
+ DateTime canRenewDT = DateTime.Parse(orderResponse.Order.Attributes.CanRenewAt);
+ if (canRenewDT < DateTime.UtcNow)
+ {
+ orderAction = "renew";
+ }
+ else
+ {
+ orderAction = "reissue";
+ }
+ }
+ }
CertificateRequest request = new CertificateRequest();
request.data.type = "order";
- request.data.attributes.action = "create";
+ request.data.attributes.action = orderAction;
request.data.attributes.csr = csr;
- request.data.attributes.duration = "1 year";
+ request.data.attributes.duration = lifetime;
request.data.relationships.product.data.type = "product";
request.data.relationships.product.data.id = productId;
request.data.relationships.organization.data.type = "organization";
@@ -135,11 +166,12 @@ public async Task Enroll(string csr, string subject, Dictionar
}
_logger.LogTrace($"Certificate enrolled successfully");
- var cert = GetSingleRecord(response.Order.Relationships.Certificate.Data.id).Result;
-
+ var reqId = $"{response.Order.Id}-{response.Order.Relationships.Certificate.Data.id}";
+ var cert = GetSingleRecord(reqId).Result;
+
return new EnrollmentResult
{
- CARequestID = cert.CARequestID,
+ CARequestID = reqId,
Certificate = cert.Certificate,
Status = cert.Status,
StatusMessage = $"Successfully enrolled for certificate {subject}"
@@ -191,11 +223,17 @@ public List GetProductIds()
public async Task GetSingleRecord(string caRequestID)
{
NameshieldClient client = NameshieldClient.InitializeClient(_config);
+ var idParts = caRequestID.Split('-').ToList();
+ if (idParts.Count == 1)
+ {
+ _logger.LogWarning($"Order {caRequestID} is still awaiting delivery.");
+ throw new Exception($"Unable to retrieve certificate for order {caRequestID} as it is still awaiting delivery. The certificate will be picked up by a future sync once it is issued.");
+ }
+ string certId = idParts[1];
+ var cert = Task.Run(async () => await client.GetCertificate(certId)).Result;
+ var certProduct = Task.Run(async () => await client.GetCertificateProduct(certId)).Result;
- var cert = Task.Run(async () => await client.GetCertificate(caRequestID)).Result;
- var certProduct = Task.Run(async () => await client.GetCertificateProduct(caRequestID)).Result;
-
- int status = ConvertToKeyfactorStatus(cert.Certificate.Attributes.Status, caRequestID);
+ int status = ConvertToKeyfactorStatus(cert.Certificate.Attributes.Status, certId);
return new AnyCAPluginCertificate()
{
@@ -224,6 +262,13 @@ public Dictionary GetTemplateParameterAnnotations()
Hidden = false,
DefaultValue = "",
Type = "String"
+ },
+ [Constants.Config.Template.LIFETIME] = new PropertyConfigInfo()
+ {
+ Comments = "REQUIRED:The lifetime of the certificate to be issued. This should be a string in the format recognized by Nameshield (e.g. 1 year, etc.)",
+ Hidden = false,
+ DefaultValue = "1 year",
+ Type = "String"
}
};
}
@@ -271,11 +316,13 @@ public async Task Synchronize(BlockingCollection blockin
foreach (var cert in certs.Certificates)
{
+ var certObj = Task.Run(async () => await client.GetCertificate(cert.Id)).Result;
var certProduct = Task.Run(async () => await client.GetCertificateProduct(cert.Id)).Result;
int status = ConvertToKeyfactorStatus(cert.Attributes.Status, cert.Id);
var newCert = new AnyCAPluginCertificate()
{
- CARequestID = cert.Id,
+ CARequestID = $"{certObj.Certificate.Relationships.Order.Data.id}-{cert.Id}",
+ OldCARequestID = certObj.Certificate.Relationships.Order.Data.id,
ProductID = certProduct.CertificateProduct.Attributes.Name,
Status = status,
Certificate = cert.Attributes.Pem,
@@ -310,20 +357,39 @@ public async Task ValidateProductInfo(EnrollmentProductInfo productInfo, Diction
var productList = Task.Run(async () => await localClient.ListProducts()).Result;
- bool foundProduct = false;
+ Product foundProduct = null;
foreach (var product in productList.Products)
{
if (string.Equals(product.Attributes.Name, productInfo.ProductID, StringComparison.OrdinalIgnoreCase))
{
- foundProduct = true;
+ foundProduct = product;
break;
}
}
- if (!foundProduct)
+ if (foundProduct == null)
{
throw new Exception($"Product ID {productInfo.ProductID} was not found in the list of valid products.");
}
+ string lifetime = productInfo.ProductParameters[Constants.Config.Template.LIFETIME];
+ if (string.IsNullOrEmpty(lifetime))
+ {
+ throw new Exception($"Product ID {productInfo.ProductID} is missing a required lifetime value");
+ }
+
+ bool allowedDuration = false;
+ foreach (var duration in foundProduct.Attributes.Durations)
+ {
+ if (string.Equals(duration, lifetime, StringComparison.OrdinalIgnoreCase))
+ {
+ allowedDuration = true;
+ break;
+ }
+ }
+ if (!allowedDuration)
+ {
+ throw new Exception($"Product ID {productInfo.ProductID} has an invalid lifetime value {lifetime}. Valid values for this product are: {string.Join(',', foundProduct.Attributes.Durations)}");
+ }
}
private static string ValidateConfigurationKey(Dictionary connectionInfo, string key)
@@ -336,7 +402,7 @@ private static string ValidateConfigurationKey(Dictionary connec
return string.Empty;
}
- private static int ConvertToKeyfactorStatus(string status, string sslId)
+ private static int ConvertToKeyfactorStatus(string status, string certId)
{
switch (status.ToUpper())
{
@@ -353,7 +419,7 @@ private static int ConvertToKeyfactorStatus(string status, string sslId)
return (int)EndEntityStatus.REVOKED;
default:
- throw new Exception($"Request ID {sslId} has unknown status {status}");
+ throw new Exception($"Request ID {certId} has unknown status {status}");
}
}
diff --git a/nameshield-caplugin/nameshield-caplugin.csproj b/nameshield-caplugin/nameshield-caplugin.csproj
index 054f6a7..6ef77c8 100644
--- a/nameshield-caplugin/nameshield-caplugin.csproj
+++ b/nameshield-caplugin/nameshield-caplugin.csproj
@@ -17,7 +17,7 @@
-
+
From d6dd2a079ce2e35a1582aa0e73cd862f5440c32c Mon Sep 17 00:00:00 2001
From: Dave Galey <89407235+dgaley@users.noreply.github.com>
Date: Mon, 26 Oct 2026 00:34:33 -0400
Subject: [PATCH 2/5] Update starter workflow version
Updated the starter workflow version from v3 to v5 and removed APPROVE_README_PUSH secret.
---
.github/workflows/keyfactor-bootstrap-workflow-v3.yml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.github/workflows/keyfactor-bootstrap-workflow-v3.yml b/.github/workflows/keyfactor-bootstrap-workflow-v3.yml
index 64919a4..45eec87 100644
--- a/.github/workflows/keyfactor-bootstrap-workflow-v3.yml
+++ b/.github/workflows/keyfactor-bootstrap-workflow-v3.yml
@@ -11,10 +11,9 @@ on:
jobs:
call-starter-workflow:
- uses: keyfactor/actions/.github/workflows/starter.yml@v3
+ uses: keyfactor/actions/.github/workflows/starter.yml@v5
secrets:
token: ${{ secrets.V2BUILDTOKEN}}
- APPROVE_README_PUSH: ${{ secrets.APPROVE_README_PUSH}}
gpg_key: ${{ secrets.KF_GPG_PRIVATE_KEY }}
gpg_pass: ${{ secrets.KF_GPG_PASSPHRASE }}
scan_token: ${{ secrets.SAST_TOKEN }}
From 117cc73cb268d077fdb7a081874678a6682a2e2a Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Mon, 26 Oct 2026 04:35:05 +0000
Subject: [PATCH 3/5] docs: auto-generate README and documentation [skip ci]
---
README.md | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/README.md b/README.md
index 2448b0a..05d397b 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
Support
-
+
·
Requirements
@@ -33,7 +33,6 @@
-
The Nameshield AnyCA Gateway REST plugin extends the capabilities of Nameshield CA to Keyfactor Command via the Keyfactor AnyCA Gateway REST. The plugin represents a fully featured AnyCA REST Plugin with the following capabilies:
* SSL Certificate Synchronization
* All Sync jobs are currently treated as a full sync
@@ -46,7 +45,7 @@ The Nameshield AnyCA Gateway REST plugin extends the capabilities of Nameshield
The Nameshield AnyCA Gateway REST plugin is compatible with the Keyfactor AnyCA Gateway REST 24.2.0 and later.
## Support
-The Nameshield AnyCA Gateway REST plugin is open source and community supported, meaning that there is **no SLA** applicable.
+The Nameshield AnyCA Gateway REST plugin is open source and community supported, meaning that there is **no SLA** applicable.
> To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab.
@@ -60,16 +59,15 @@ TODO Requirements is a required section
2. On the server hosting the AnyCA Gateway REST, download and unzip the latest [Nameshield AnyCA Gateway REST plugin](https://github.com/Keyfactor/nameshield-caplugin/releases/latest) from GitHub.
-3. Copy the unzipped directory (usually called `net6.0` or `net8.0`) to the Extensions directory:
+3. Copy the unzipped directory (usually called `net6.0`) to the Extensions directory:
```shell
Depending on your AnyCA Gateway REST version, copy the unzipped directory to one of the following locations:
Program Files\Keyfactor\AnyCA Gateway\AnyGatewayREST\net6.0\Extensions
- Program Files\Keyfactor\AnyCA Gateway\AnyGatewayREST\net8.0\Extensions
```
- > The directory containing the Nameshield AnyCA Gateway REST plugin DLLs (`net6.0` or `net8.0`) can be named anything, as long as it is unique within the `Extensions` directory.
+ > The directory containing the Nameshield AnyCA Gateway REST plugin DLLs (`net6.0`) can be named anything, as long as it is unique within the `Extensions` directory.
4. Restart the AnyCA Gateway REST service.
@@ -87,9 +85,9 @@ TODO Requirements is a required section
Populate using the configuration fields collected in the [requirements](#requirements) section.
- * **ApiUrl** - The base URL to send API requests to. Standard URLs are https://api.nameshield.net/ for production environment, and https://ote-api.nameshield.net/ for test and development
- * **ApiToken** - The Bearer token to use to authenticate to the Nameshield API
- * **Enabled** - Flag to Enable or Disable gateway functionality. Diabling is primarily used to allow creation of the CA prior to configuration information being available.
+ * **ApiUrl** - The base URL to send API requests to. Standard URLs are https://api.nameshield.net/ for production environment, and https://ote-api.nameshield.net/ for test and development
+ * **ApiToken** - The Bearer token to use to authenticate to the Nameshield API
+ * **Enabled** - Flag to Enable or Disable gateway functionality. Diabling is primarily used to allow creation of the CA prior to configuration information being available.
2. When defining templates, use the product names as the ProductID (e.g. Digicert Secure Site EV) as opposed to the ID (e.g. ABC012)
@@ -97,11 +95,9 @@ TODO Requirements is a required section
4. In Keyfactor Command (v12.3+), for each imported Certificate Template, follow the [official documentation](https://software.keyfactor.com/Core-OnPrem/Current/Content/ReferenceGuide/Configuring%20Template%20Options.htm) to define enrollment fields for each of the following parameters:
- * **OrganizationId** - If you know your organization's ID in nameshield, you can supply that here and that will be used as the organization regardless of what values exist in the request or the Organization field
- * **Organization** - If OrganizationId is empty, and an organization name is provided here, the Nameshield gateway will use that name to do organization lookups when enrolling. If neither OrganizationId nor Organization is supplied, the gateway will use whatever is in the O= field of the request subject.
- * **Lifetime** - REQUIRED:The lifetime of the certificate to be issued. This should be a string in the format recognized by Nameshield (e.g. 1 year, etc.)
-
-
+ * **OrganizationId** - If you know your organization's ID in nameshield, you can supply that here and that will be used as the organization regardless of what values exist in the request or the Organization field
+ * **Organization** - If OrganizationId is empty, and an organization name is provided here, the Nameshield gateway will use that name to do organization lookups when enrolling. If neither OrganizationId nor Organization is supplied, the gateway will use whatever is in the O= field of the request subject.
+ * **Lifetime** - REQUIRED:The lifetime of the certificate to be issued. This should be a string in the format recognized by Nameshield (e.g. 1 year, etc.)
## License
@@ -109,4 +105,4 @@ Apache License 2.0, see [LICENSE](LICENSE).
## Related Integrations
-See all [Keyfactor Any CA Gateways (REST)](https://github.com/orgs/Keyfactor/repositories?q=anycagateway).
\ No newline at end of file
+See all [Keyfactor Any CA Gateways (REST)](https://github.com/orgs/Keyfactor/repositories?q=anycagateway).
From 7962006ee0c169e047b3fc7e6eca9fa16048307a Mon Sep 17 00:00:00 2001
From: Dave Galey <89407235+dgaley@users.noreply.github.com>
Date: Mon, 26 Oct 2026 13:33:08 -0400
Subject: [PATCH 4/5] Renew (#13)
* Change CARequestID to OrderId-CertId to make it easier to link externalvalidation certs when they are finally pickd up.
* Allow for configuration of duration
* Update generated docs
* add renew/reissue support
* changelog
* supply previous cert ID for renew/reissue calls
* docs: auto-generate README and documentation [skip ci]
---------
Co-authored-by: Keyfactor
Co-authored-by: github-actions[bot]
---
nameshield-caplugin/API/RequestCertificate.cs | 5 +++
nameshield-caplugin/NameshieldCAPlugin.cs | 35 ++++++++++++++++++-
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/nameshield-caplugin/API/RequestCertificate.cs b/nameshield-caplugin/API/RequestCertificate.cs
index 3825962..fc23e82 100644
--- a/nameshield-caplugin/API/RequestCertificate.cs
+++ b/nameshield-caplugin/API/RequestCertificate.cs
@@ -28,6 +28,8 @@ public CertificateRequest()
data.relationships.product.data = new RelationshipData();
data.relationships.organization = new CertRequestRel();
data.relationships.organization.data = new RelationshipData();
+ data.relationships.certificate = new CertRequestRel();
+ data.relationships.certificate.data = new RelationshipData();
}
public string GetOrderData()
@@ -81,6 +83,9 @@ public class CertificateRequestRelationships
[JsonPropertyName("organization")]
[JsonProperty("organization")]
public CertRequestRel organization { get; set; }
+ [JsonPropertyName("certificate")]
+ [JsonProperty("certificate")]
+ public CertRequestRel certificate { get; set; }
}
public class CertRequestRel
diff --git a/nameshield-caplugin/NameshieldCAPlugin.cs b/nameshield-caplugin/NameshieldCAPlugin.cs
index d33cfd2..4cbcdb0 100644
--- a/nameshield-caplugin/NameshieldCAPlugin.cs
+++ b/nameshield-caplugin/NameshieldCAPlugin.cs
@@ -127,7 +127,7 @@ public async Task Enroll(string csr, string subject, Dictionar
CertificateRequest request = new CertificateRequest();
request.data.type = "order";
- request.data.attributes.action = orderAction;
+
request.data.attributes.csr = csr;
request.data.attributes.duration = lifetime;
request.data.relationships.product.data.type = "product";
@@ -135,6 +135,39 @@ public async Task Enroll(string csr, string subject, Dictionar
request.data.relationships.organization.data.type = "organization";
request.data.relationships.organization.data.id = orgId;
+ string orderAction = "create";
+ // Determine if we should do a renew or a reissue
+ if (enrollmentType == EnrollmentType.RenewOrReissue)
+ {
+ string priorCertSnString = productInfo.ProductParameters["PriorCertSN"];
+ var priorCertReqID = await _certificateDataReader.GetRequestIDBySerialNumber(priorCertSnString);
+ if (string.IsNullOrEmpty(priorCertReqID))
+ {
+ throw new Exception($"Cannot find prior certificate with serial number {priorCertSnString}.");
+ }
+
+ string orderId = priorCertReqID.Split('-')[0];
+
+ var orderResponse = Task.Run(async () => await client.GetOrderDetails(orderId)).Result;
+ if (orderResponse.Order.Attributes.CanRenewAt != null)
+ {
+ DateTime canRenewDT = DateTime.Parse(orderResponse.Order.Attributes.CanRenewAt);
+ if (canRenewDT < DateTime.UtcNow)
+ {
+ orderAction = "renew";
+ }
+ else
+ {
+ orderAction = "reissue";
+ }
+ }
+
+ request.data.relationships.certificate.data.type = "certificate";
+ request.data.relationships.certificate.data.id = priorCertReqID.Split('-')[1];
+ }
+
+ request.data.attributes.action = orderAction;
+
var response = Task.Run(async () => await client.RequestCertificate(request)).Result;
var status = response.Order.Attributes.Status;
From dcd6c5229f3bf4667b36c778d998740f786acbeb Mon Sep 17 00:00:00 2001
From: David Galey
Date: Mon, 26 Oct 2026 13:42:23 -0400
Subject: [PATCH 5/5] remove duplicate code from merge
---
nameshield-caplugin/NameshieldCAPlugin.cs | 29 -----------------------
1 file changed, 29 deletions(-)
diff --git a/nameshield-caplugin/NameshieldCAPlugin.cs b/nameshield-caplugin/NameshieldCAPlugin.cs
index 4cbcdb0..ec5b3e5 100644
--- a/nameshield-caplugin/NameshieldCAPlugin.cs
+++ b/nameshield-caplugin/NameshieldCAPlugin.cs
@@ -96,35 +96,6 @@ public async Task Enroll(string csr, string subject, Dictionar
}
var lifetime = productInfo.ProductParameters[Constants.Config.Template.LIFETIME];
- string orderAction = "create";
-
- // Determine if we should do a renew or a reissue
- if (enrollmentType == EnrollmentType.RenewOrReissue)
- {
- string priorCertSnString = productInfo.ProductParameters["PriorCertSN"];
- var priorCertReqID = await _certificateDataReader.GetRequestIDBySerialNumber(priorCertSnString);
- if (string.IsNullOrEmpty(priorCertReqID))
- {
- throw new Exception($"Cannot find prior certificate with serial number {priorCertSnString}.");
- }
-
- string orderId = priorCertReqID.Split('-')[0];
-
- var orderResponse = Task.Run(async () => await client.GetOrderDetails(orderId)).Result;
- if (orderResponse.Order.Attributes.CanRenewAt != null)
- {
- DateTime canRenewDT = DateTime.Parse(orderResponse.Order.Attributes.CanRenewAt);
- if (canRenewDT < DateTime.UtcNow)
- {
- orderAction = "renew";
- }
- else
- {
- orderAction = "reissue";
- }
- }
- }
-
CertificateRequest request = new CertificateRequest();
request.data.type = "order";