92 lines
3.1 KiB
C#
92 lines
3.1 KiB
C#
using StellaOps.Cryptography;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace StellaOps.Cryptography.Plugin.PqSoft;
|
|
|
|
public sealed partial class PqSoftCryptoProvider
|
|
{
|
|
public ICryptoSigner GetSigner(string algorithmId, CryptoKeyReference keyReference)
|
|
{
|
|
EnsureAllowed();
|
|
ArgumentNullException.ThrowIfNull(keyReference);
|
|
|
|
if (!SupportedAlgorithms.Contains(algorithmId))
|
|
{
|
|
throw new InvalidOperationException($"Signing algorithm '{algorithmId}' is not supported by provider '{Name}'.");
|
|
}
|
|
|
|
if (!_entries.TryGetValue(keyReference.KeyId, out var entry))
|
|
{
|
|
throw new KeyNotFoundException($"Signing key '{keyReference.KeyId}' is not registered with provider '{Name}'.");
|
|
}
|
|
|
|
if (!string.Equals(entry.AlgorithmId, algorithmId, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
throw new InvalidOperationException($"Signing key '{keyReference.KeyId}' is registered for algorithm '{entry.AlgorithmId}', not '{algorithmId}'.");
|
|
}
|
|
|
|
return entry.CreateSigner();
|
|
}
|
|
|
|
public void UpsertSigningKey(CryptoSigningKey signingKey)
|
|
{
|
|
EnsureAllowed();
|
|
ArgumentNullException.ThrowIfNull(signingKey);
|
|
|
|
var normalizedAlg = Normalize(signingKey.AlgorithmId);
|
|
if (!SupportedAlgorithms.Contains(normalizedAlg))
|
|
{
|
|
throw new InvalidOperationException($"Signing algorithm '{normalizedAlg}' is not supported by provider '{Name}'.");
|
|
}
|
|
|
|
if (signingKey.PrivateKey.IsEmpty)
|
|
{
|
|
throw new InvalidOperationException("PQ provider requires raw private key bytes.");
|
|
}
|
|
|
|
var entry = normalizedAlg switch
|
|
{
|
|
SignatureAlgorithms.Dilithium3 => CreateDilithiumEntry(signingKey),
|
|
SignatureAlgorithms.Falcon512 => CreateFalconEntry(signingKey),
|
|
_ => throw new InvalidOperationException($"Unsupported PQ algorithm '{normalizedAlg}'.")
|
|
};
|
|
|
|
_entries.AddOrUpdate(signingKey.Reference.KeyId, entry, (_, _) => entry);
|
|
}
|
|
|
|
public bool RemoveSigningKey(string keyId)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(keyId))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return _entries.TryRemove(keyId, out _);
|
|
}
|
|
|
|
public IReadOnlyCollection<CryptoSigningKey> GetSigningKeys()
|
|
=> _entries.Values.Select(static e => e.Descriptor).ToArray();
|
|
|
|
public IEnumerable<CryptoProviderKeyDescriptor> DescribeKeys()
|
|
{
|
|
foreach (var entry in _entries.Values)
|
|
{
|
|
yield return new CryptoProviderKeyDescriptor(
|
|
Name,
|
|
entry.Descriptor.Reference.KeyId,
|
|
entry.AlgorithmId,
|
|
new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
["provider"] = Name,
|
|
["algorithm"] = entry.AlgorithmId,
|
|
["certified"] = "false",
|
|
["simulation"] = "software"
|
|
});
|
|
}
|
|
}
|
|
|
|
private static string Normalize(string algorithmId) => algorithmId.ToUpperInvariant();
|
|
}
|