docs consolidation and others
This commit is contained in:
@@ -11,25 +11,27 @@ public sealed class EcdsaP256Signer : IContentSigner
|
||||
{
|
||||
private readonly ECDsa _ecdsa;
|
||||
private readonly string _keyId;
|
||||
private readonly TimeProvider _timeProvider;
|
||||
private bool _disposed;
|
||||
|
||||
public string KeyId => _keyId;
|
||||
public SignatureProfile Profile => SignatureProfile.EcdsaP256;
|
||||
public string Algorithm => "ES256";
|
||||
|
||||
public EcdsaP256Signer(string keyId, ECDsa ecdsa)
|
||||
public EcdsaP256Signer(string keyId, ECDsa ecdsa, TimeProvider? timeProvider = null)
|
||||
{
|
||||
_keyId = keyId ?? throw new ArgumentNullException(nameof(keyId));
|
||||
_ecdsa = ecdsa ?? throw new ArgumentNullException(nameof(ecdsa));
|
||||
_timeProvider = timeProvider ?? TimeProvider.System;
|
||||
|
||||
if (_ecdsa.KeySize != 256)
|
||||
throw new ArgumentException("ECDSA key must be P-256 (256 bits)", nameof(ecdsa));
|
||||
}
|
||||
|
||||
public static EcdsaP256Signer Generate(string keyId)
|
||||
public static EcdsaP256Signer Generate(string keyId, TimeProvider? timeProvider = null)
|
||||
{
|
||||
var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
|
||||
return new EcdsaP256Signer(keyId, ecdsa);
|
||||
return new EcdsaP256Signer(keyId, ecdsa, timeProvider);
|
||||
}
|
||||
|
||||
public Task<SignatureResult> SignAsync(ReadOnlyMemory<byte> payload, CancellationToken ct = default)
|
||||
@@ -45,7 +47,7 @@ public sealed class EcdsaP256Signer : IContentSigner
|
||||
Profile = Profile,
|
||||
Algorithm = Algorithm,
|
||||
Signature = signature,
|
||||
SignedAt = DateTimeOffset.UtcNow
|
||||
SignedAt = _timeProvider.GetUtcNow()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ public sealed class Ed25519Signer : IContentSigner
|
||||
private readonly byte[] _privateKey;
|
||||
private readonly byte[] _publicKey;
|
||||
private readonly string _keyId;
|
||||
private readonly TimeProvider _timeProvider;
|
||||
private bool _disposed;
|
||||
|
||||
public string KeyId => _keyId;
|
||||
@@ -25,8 +26,9 @@ public sealed class Ed25519Signer : IContentSigner
|
||||
/// </summary>
|
||||
/// <param name="keyId">Key identifier</param>
|
||||
/// <param name="privateKey">32-byte Ed25519 private key</param>
|
||||
/// <param name="timeProvider">Time provider for deterministic timestamps</param>
|
||||
/// <exception cref="ArgumentException">If key is not 32 bytes</exception>
|
||||
public Ed25519Signer(string keyId, byte[] privateKey)
|
||||
public Ed25519Signer(string keyId, byte[] privateKey, TimeProvider? timeProvider = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(keyId))
|
||||
throw new ArgumentException("Key ID required", nameof(keyId));
|
||||
@@ -35,6 +37,7 @@ public sealed class Ed25519Signer : IContentSigner
|
||||
throw new ArgumentException("Ed25519 private key must be 32 bytes", nameof(privateKey));
|
||||
|
||||
_keyId = keyId;
|
||||
_timeProvider = timeProvider ?? TimeProvider.System;
|
||||
_privateKey = new byte[32];
|
||||
Array.Copy(privateKey, _privateKey, 32);
|
||||
|
||||
@@ -46,11 +49,12 @@ public sealed class Ed25519Signer : IContentSigner
|
||||
/// Generate new Ed25519 key pair.
|
||||
/// </summary>
|
||||
/// <param name="keyId">Key identifier</param>
|
||||
/// <param name="timeProvider">Time provider for deterministic timestamps</param>
|
||||
/// <returns>New Ed25519 signer with generated key</returns>
|
||||
public static Ed25519Signer Generate(string keyId)
|
||||
public static Ed25519Signer Generate(string keyId, TimeProvider? timeProvider = null)
|
||||
{
|
||||
var keyPair = PublicKeyAuth.GenerateKeyPair();
|
||||
return new Ed25519Signer(keyId, keyPair.PrivateKey);
|
||||
return new Ed25519Signer(keyId, keyPair.PrivateKey, timeProvider);
|
||||
}
|
||||
|
||||
public Task<SignatureResult> SignAsync(ReadOnlyMemory<byte> payload, CancellationToken ct = default)
|
||||
@@ -67,7 +71,7 @@ public sealed class Ed25519Signer : IContentSigner
|
||||
Profile = Profile,
|
||||
Algorithm = Algorithm,
|
||||
Signature = signature,
|
||||
SignedAt = DateTimeOffset.UtcNow
|
||||
SignedAt = _timeProvider.GetUtcNow()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,9 @@ public sealed record SignatureResult
|
||||
|
||||
/// <summary>
|
||||
/// UTC timestamp when signature was created.
|
||||
/// Callers must provide this value - no default to ensure determinism.
|
||||
/// </summary>
|
||||
public DateTimeOffset SignedAt { get; init; } = DateTimeOffset.UtcNow;
|
||||
public required DateTimeOffset SignedAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional metadata (e.g., certificate chain for eIDAS, KMS request ID).
|
||||
|
||||
@@ -12,19 +12,23 @@ public sealed class MultiProfileSigner : IDisposable
|
||||
{
|
||||
private readonly IReadOnlyList<IContentSigner> _signers;
|
||||
private readonly ILogger<MultiProfileSigner> _logger;
|
||||
private readonly TimeProvider _timeProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Create a multi-profile signer.
|
||||
/// </summary>
|
||||
/// <param name="signers">Collection of signers to use</param>
|
||||
/// <param name="logger">Logger for diagnostics</param>
|
||||
/// <param name="timeProvider">Time provider for deterministic timestamps</param>
|
||||
/// <exception cref="ArgumentException">If no signers provided</exception>
|
||||
public MultiProfileSigner(
|
||||
IEnumerable<IContentSigner> signers,
|
||||
ILogger<MultiProfileSigner> logger)
|
||||
ILogger<MultiProfileSigner> logger,
|
||||
TimeProvider? timeProvider = null)
|
||||
{
|
||||
_signers = signers?.ToList() ?? throw new ArgumentNullException(nameof(signers));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_timeProvider = timeProvider ?? TimeProvider.System;
|
||||
|
||||
if (_signers.Count == 0)
|
||||
{
|
||||
@@ -70,7 +74,7 @@ public sealed class MultiProfileSigner : IDisposable
|
||||
return new MultiSignatureResult
|
||||
{
|
||||
Signatures = results.ToList(),
|
||||
SignedAt = DateTimeOffset.UtcNow
|
||||
SignedAt = _timeProvider.GetUtcNow()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user