Skip to content

Commit 635d22f

Browse files
bhillkeyfactorKeyfactorindroraclaude
authored
Feature/86120 revocation reason 0 (#9)
* feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Merge 1.0.1 to main (#4) * feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * release: 1.0.1 --------- Co-authored-by: Brian Hill <76450501+bhillkeyfactor@users.noreply.github.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Merge 1.0.2 to main (#7) * feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * release: 1.0.1 * release 1.0.2 * feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Merge 1.0.1 to main (#4) * feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * release: 1.0.1 --------- Co-authored-by: Brian Hill <76450501+bhillkeyfactor@users.noreply.github.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Hydrant Failed Status Issues and Logging * fixed changelog * Add .NET 10 target framework support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Change FlowLogger from LogTrace to LogDebug/LogWarning The Keyfactor gateway framework sets the Microsoft.Extensions.Logging minimum level above Trace, causing all LogTrace calls to be silently dropped before reaching NLog. Flow diagram and step logging now uses LogDebug (visible), and failure steps use LogWarning for visibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Revert FlowLogger back to LogTrace LogTrace works in the CSC Global plugin with the same gateway framework, so the MEL minimum level is not the issue. Reverting to match the established pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fixed package vulns --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> Co-authored-by: Morgan Gangwere <470584+indrora@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Brian Hill <76450501+bhillkeyfactor@users.noreply.github.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fixed revoke reason * Revert "Fixed revoke reason" This reverts commit 2569ae1. * ADO 86120: Add support for revocation reason 0 (Unspecified) HydrantID now supports CRL revocation reason 0 (Unspecified) following the CAB change. The plugin previously rejected this reason in RequestManager.GetMapRevokeReasons with RevokeReasonNotSupportedException. - Add Unspecified = 0 to the RevocationReasons enum - Map keyfactorRevokeReason == 0 to RevocationReasons.Unspecified - Update the unsupported-reason error message to list reason 0 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Restore missing closing brace for switch in GetMapRevokeReasons The release-1.0 merge dropped the closing } of the switch block. * masked senstive config data * change log --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> Co-authored-by: Morgan Gangwere <470584+indrora@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7ab81f8 commit 635d22f

5 files changed

Lines changed: 45 additions & 3 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,5 @@ ASALocalRun/
330330
.mfractor/
331331
.claude/settings.local.json
332332
sample change.txt
333+
.claude/settings.json
334+

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# v1.0.3
2+
* Added support for revocation reason 0 (Unspecified) now that HydrantId accepts it
3+
* Fixed sensitive credentials (HydrantIdAuthId, HydrantIdAuthKey) being written to trace logs in plain text; raw config JSON is now masked before logging
4+
15
# v1.0.2
26
* Fixed revocation status handling - failed revocations no longer incorrectly set certificate status to FAILED; certificate retains its current active status
37
* Added FlowLogger utility for structured flow diagrams across all public plugin methods

HydrantCAProxy/Client/Models/Enums/RevocationReasons.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace Keyfactor.HydrantId.Client.Models.Enums
1616
[JsonConverter(typeof(StringEnumConverter))]
1717
public enum RevocationReasons
1818
{
19+
[EnumMember(Value = "0")] Unspecified = 0,
1920
[EnumMember(Value = "1")] KeyCompromise = 1,
2021
[EnumMember(Value = "3")] AffiliationChanged = 3,
2122
[EnumMember(Value = "4")] Superseded = 4,

HydrantCAProxy/HydrantIdCAPlugin.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public void Initialize(IAnyCAPluginConfigProvider configProvider, ICertificateDa
5252
certDataReader = certificateDataReader;
5353
Config = configProvider;
5454
var rawData = JsonConvert.SerializeObject(configProvider.CAConnectionData);
55-
_logger.LogTrace("Initialize: raw config JSON: {Json}", rawData);
55+
_logger.LogTrace("Initialize: config JSON (sensitive keys masked): {Json}", MaskConfigForLog(rawData));
5656
_config = JsonConvert.DeserializeObject<HydrantIdCAPluginConfig.Config>(rawData);
5757
});
5858

@@ -78,6 +78,38 @@ public void Initialize(IAnyCAPluginConfigProvider configProvider, ICertificateDa
7878
}
7979
}
8080

81+
private static readonly HashSet<string> _sensitiveConfigKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
82+
{
83+
HydrantIdCAPluginConfig.ConfigConstants.HydrantIdAuthId,
84+
HydrantIdCAPluginConfig.ConfigConstants.HydrantIdAuthKey
85+
};
86+
87+
private static string MaskConfigForLog(string rawJson)
88+
{
89+
if (string.IsNullOrEmpty(rawJson)) return rawJson;
90+
try
91+
{
92+
var token = Newtonsoft.Json.Linq.JToken.Parse(rawJson);
93+
if (token is Newtonsoft.Json.Linq.JObject obj)
94+
{
95+
foreach (var prop in obj.Properties())
96+
{
97+
if (_sensitiveConfigKeys.Contains(prop.Name) &&
98+
prop.Value.Type != Newtonsoft.Json.Linq.JTokenType.Null)
99+
{
100+
prop.Value = "***REDACTED***";
101+
}
102+
}
103+
return obj.ToString(Newtonsoft.Json.Formatting.None);
104+
}
105+
return token.ToString(Newtonsoft.Json.Formatting.None);
106+
}
107+
catch
108+
{
109+
return "***REDACTED***";
110+
}
111+
}
112+
81113
private static List<string> CheckRequiredValues(Dictionary<string, object> connectionInfo, params string[] args)
82114
{
83115
List<string> errors = new List<string>();
@@ -135,7 +167,7 @@ public Task ValidateCAConnectionInfo(Dictionary<string, object> connectionInfo)
135167

136168
_logger.LogDebug("Validating HydrantId CA Connection properties");
137169
var rawData = JsonConvert.SerializeObject(connectionInfo);
138-
_logger.LogTrace("ValidateCAConnectionInfo: raw connectionInfo JSON: {Json}", rawData);
170+
_logger.LogTrace("ValidateCAConnectionInfo: connectionInfo JSON (sensitive keys masked): {Json}", MaskConfigForLog(rawData));
139171

140172
_config = JsonConvert.DeserializeObject<HydrantIdCAPluginConfig.Config>(rawData);
141173

HydrantCAProxy/RequestManager.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ public RevocationReasons GetMapRevokeReasons(uint keyfactorRevokeReason)
7878
RevocationReasons returnStatus;
7979
switch (keyfactorRevokeReason)
8080
{
81+
case 0:
82+
returnStatus = RevocationReasons.Unspecified;
83+
break;
8184
case 1:
8285
returnStatus = RevocationReasons.KeyCompromise;
8386
break;
@@ -92,7 +95,7 @@ public RevocationReasons GetMapRevokeReasons(uint keyfactorRevokeReason)
9295
break;
9396
default:
9497
Log.LogError("GetMapRevokeReasons: unsupported revoke reason {Reason}", keyfactorRevokeReason);
95-
throw new RevokeReasonNotSupportedException($"Revoke reason {keyfactorRevokeReason} is not supported. Supported values: 1 (KeyCompromise), 3 (AffiliationChanged), 4 (Superseded), 5 (CessationOfOperation).");
98+
throw new RevokeReasonNotSupportedException($"Revoke reason {keyfactorRevokeReason} is not supported. Supported values: 0 (Unspecified), 1 (KeyCompromise), 3 (AffiliationChanged), 4 (Superseded), 5 (CessationOfOperation).");
9699
}
97100

98101
Log.LogTrace("GetMapRevokeReasons: {Input} -> {Mapped}", keyfactorRevokeReason, returnStatus);

0 commit comments

Comments
 (0)