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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,5 @@ ASALocalRun/
.mfractor/
.claude/settings.local.json
sample change.txt
.claude/settings.json

4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v1.0.3
* Added support for revocation reason 0 (Unspecified) now that HydrantId accepts it
* Fixed sensitive credentials (HydrantIdAuthId, HydrantIdAuthKey) being written to trace logs in plain text; raw config JSON is now masked before logging

# v1.0.2
* Fixed revocation status handling - failed revocations no longer incorrectly set certificate status to FAILED; certificate retains its current active status
* Added FlowLogger utility for structured flow diagrams across all public plugin methods
Expand Down
1 change: 1 addition & 0 deletions HydrantCAProxy/Client/Models/Enums/RevocationReasons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Keyfactor.HydrantId.Client.Models.Enums
[JsonConverter(typeof(StringEnumConverter))]
public enum RevocationReasons
{
[EnumMember(Value = "0")] Unspecified = 0,
[EnumMember(Value = "1")] KeyCompromise = 1,
[EnumMember(Value = "3")] AffiliationChanged = 3,
[EnumMember(Value = "4")] Superseded = 4,
Expand Down
36 changes: 34 additions & 2 deletions HydrantCAProxy/HydrantIdCAPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
certDataReader = certificateDataReader;
Config = configProvider;
var rawData = JsonConvert.SerializeObject(configProvider.CAConnectionData);
_logger.LogTrace("Initialize: raw config JSON: {Json}", rawData);
_logger.LogTrace("Initialize: config JSON (sensitive keys masked): {Json}", MaskConfigForLog(rawData));
_config = JsonConvert.DeserializeObject<HydrantIdCAPluginConfig.Config>(rawData);
});

Expand All @@ -78,6 +78,38 @@
}
}

private static readonly HashSet<string> _sensitiveConfigKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
HydrantIdCAPluginConfig.ConfigConstants.HydrantIdAuthId,
HydrantIdCAPluginConfig.ConfigConstants.HydrantIdAuthKey
};

private static string MaskConfigForLog(string rawJson)
{
if (string.IsNullOrEmpty(rawJson)) return rawJson;
try
{
var token = Newtonsoft.Json.Linq.JToken.Parse(rawJson);
if (token is Newtonsoft.Json.Linq.JObject obj)
{
foreach (var prop in obj.Properties())
{
if (_sensitiveConfigKeys.Contains(prop.Name) &&
prop.Value.Type != Newtonsoft.Json.Linq.JTokenType.Null)
{
prop.Value = "***REDACTED***";
}
}
return obj.ToString(Newtonsoft.Json.Formatting.None);
}
return token.ToString(Newtonsoft.Json.Formatting.None);
}
catch
{
return "***REDACTED***";
}
}

private static List<string> CheckRequiredValues(Dictionary<string, object> connectionInfo, params string[] args)
{
List<string> errors = new List<string>();
Expand Down Expand Up @@ -135,7 +167,7 @@

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

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

Expand Down Expand Up @@ -385,7 +417,7 @@
{
cleanCert = $"-----BEGIN CERTIFICATE-----\n{cleanCert}\n-----END CERTIFICATE-----";
}
col.Import(Encoding.UTF8.GetBytes(cleanCert));

Check warning on line 420 in HydrantCAProxy/HydrantIdCAPlugin.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-generate-readme-workflow / Use private doctool action in public repository

'X509Certificate2Collection.Import(byte[])' is obsolete: 'Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates.' (https://aka.ms/dotnet-warnings/SYSLIB0057)

Check warning on line 420 in HydrantCAProxy/HydrantIdCAPlugin.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-generate-readme-workflow / Use private doctool action in public repository

'X509Certificate2Collection.Import(byte[])' is obsolete: 'Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates.' (https://aka.ms/dotnet-warnings/SYSLIB0057)

Check warning on line 420 in HydrantCAProxy/HydrantIdCAPlugin.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

'X509Certificate2Collection.Import(byte[])' is obsolete: 'Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates.' (https://aka.ms/dotnet-warnings/SYSLIB0057)

Check warning on line 420 in HydrantCAProxy/HydrantIdCAPlugin.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

'X509Certificate2Collection.Import(byte[])' is obsolete: 'Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates.' (https://aka.ms/dotnet-warnings/SYSLIB0057)

Check warning on line 420 in HydrantCAProxy/HydrantIdCAPlugin.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

'X509Certificate2Collection.Import(byte[])' is obsolete: 'Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates.' (https://aka.ms/dotnet-warnings/SYSLIB0057)
}
catch (Exception ex)
{
Expand Down Expand Up @@ -554,7 +586,7 @@
};
}

var previousX509 = new X509Certificate2(Encoding.ASCII.GetBytes(previousCert.Certificate));

Check warning on line 589 in HydrantCAProxy/HydrantIdCAPlugin.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-generate-readme-workflow / Use private doctool action in public repository

'X509Certificate2.X509Certificate2(byte[])' is obsolete: 'Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates.' (https://aka.ms/dotnet-warnings/SYSLIB0057)

Check warning on line 589 in HydrantCAProxy/HydrantIdCAPlugin.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-generate-readme-workflow / Use private doctool action in public repository

'X509Certificate2.X509Certificate2(byte[])' is obsolete: 'Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates.' (https://aka.ms/dotnet-warnings/SYSLIB0057)

Check warning on line 589 in HydrantCAProxy/HydrantIdCAPlugin.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

'X509Certificate2.X509Certificate2(byte[])' is obsolete: 'Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates.' (https://aka.ms/dotnet-warnings/SYSLIB0057)

Check warning on line 589 in HydrantCAProxy/HydrantIdCAPlugin.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

'X509Certificate2.X509Certificate2(byte[])' is obsolete: 'Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates.' (https://aka.ms/dotnet-warnings/SYSLIB0057)

Check warning on line 589 in HydrantCAProxy/HydrantIdCAPlugin.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

'X509Certificate2.X509Certificate2(byte[])' is obsolete: 'Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates.' (https://aka.ms/dotnet-warnings/SYSLIB0057)
var expiration = previousX509.NotAfter;
var now = DateTime.UtcNow;

Expand Down
5 changes: 4 additions & 1 deletion HydrantCAProxy/RequestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ public RevocationReasons GetMapRevokeReasons(uint keyfactorRevokeReason)
RevocationReasons returnStatus;
switch (keyfactorRevokeReason)
{
case 0:
returnStatus = RevocationReasons.Unspecified;
break;
case 1:
returnStatus = RevocationReasons.KeyCompromise;
break;
Expand All @@ -92,7 +95,7 @@ public RevocationReasons GetMapRevokeReasons(uint keyfactorRevokeReason)
break;
default:
Log.LogError("GetMapRevokeReasons: unsupported revoke reason {Reason}", keyfactorRevokeReason);
throw new RevokeReasonNotSupportedException($"Revoke reason {keyfactorRevokeReason} is not supported. Supported values: 1 (KeyCompromise), 3 (AffiliationChanged), 4 (Superseded), 5 (CessationOfOperation).");
throw new RevokeReasonNotSupportedException($"Revoke reason {keyfactorRevokeReason} is not supported. Supported values: 0 (Unspecified), 1 (KeyCompromise), 3 (AffiliationChanged), 4 (Superseded), 5 (CessationOfOperation).");
}

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