docs consolidation and others

This commit is contained in:
master
2026-01-06 19:02:21 +02:00
parent d7bdca6d97
commit 4789027317
849 changed files with 16551 additions and 66770 deletions

View File

@@ -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()
});
}

View File

@@ -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()
});
}

View File

@@ -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).

View File

@@ -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()
};
}