stabilizaiton work - projects rework for maintenanceability and ui livening
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace StellaOps.AuditPack.Services;
|
||||
|
||||
public sealed partial class AuditBundleSigner
|
||||
{
|
||||
/// <summary>
|
||||
/// Signs a manifest with DSSE envelope.
|
||||
/// </summary>
|
||||
public async Task<AuditBundleSigningResult> SignAsync(
|
||||
AuditBundleSigningRequest request,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
ArgumentNullException.ThrowIfNull(request.ManifestBytes);
|
||||
|
||||
try
|
||||
{
|
||||
AsymmetricAlgorithm key;
|
||||
string keyId;
|
||||
string algorithm;
|
||||
|
||||
if (!string.IsNullOrEmpty(request.KeyFilePath))
|
||||
{
|
||||
(key, keyId, algorithm) = await LoadKeyFromFileAsync(
|
||||
request.KeyFilePath,
|
||||
request.KeyPassword,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
|
||||
key = ecdsa;
|
||||
keyId = $"ephemeral:{ComputeKeyId(ecdsa)}";
|
||||
algorithm = "ES256";
|
||||
}
|
||||
|
||||
using (key)
|
||||
{
|
||||
var pae = CreatePae(PayloadType, request.ManifestBytes);
|
||||
|
||||
byte[] signature;
|
||||
if (key is ECDsa ecdsa)
|
||||
{
|
||||
signature = ecdsa.SignData(pae, HashAlgorithmName.SHA256);
|
||||
}
|
||||
else if (key is RSA rsa)
|
||||
{
|
||||
signature = rsa.SignData(pae, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||
algorithm = "RS256";
|
||||
}
|
||||
else
|
||||
{
|
||||
return AuditBundleSigningResult.Failed($"Unsupported key type: {key.GetType().Name}");
|
||||
}
|
||||
|
||||
var envelope = new DsseEnvelope
|
||||
{
|
||||
PayloadType = PayloadType,
|
||||
Payload = Convert.ToBase64String(request.ManifestBytes),
|
||||
Signatures =
|
||||
[
|
||||
new DsseSignature
|
||||
{
|
||||
KeyId = keyId,
|
||||
Sig = Convert.ToBase64String(signature)
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var envelopeBytes = JsonSerializer.SerializeToUtf8Bytes(envelope, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true
|
||||
});
|
||||
|
||||
var payloadDigest = ComputeSha256(request.ManifestBytes);
|
||||
|
||||
return new AuditBundleSigningResult
|
||||
{
|
||||
Success = true,
|
||||
Envelope = envelopeBytes,
|
||||
KeyId = keyId,
|
||||
Algorithm = algorithm,
|
||||
PayloadDigest = payloadDigest
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return AuditBundleSigningResult.Failed($"Signing failed: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user