Files
git.stella-ops.org/src/__Libraries/StellaOps.Cryptography.Plugin.EIDAS/EidasCryptoProvider.cs
2026-02-04 19:59:20 +02:00

93 lines
3.1 KiB
C#

// SPDX-License-Identifier: BUSL-1.1
// Sprint: SPRINT_4100_0006_0002 - eIDAS Crypto Plugin
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Cryptography;
using StellaOps.Cryptography.Plugin.EIDAS.Configuration;
namespace StellaOps.Cryptography.Plugin.EIDAS;
/// <summary>
/// eIDAS-compliant crypto provider for European digital signatures.
/// Supports QES (Qualified), AES (Advanced), and AdES (Standard) signature levels
/// per Regulation (EU) No 910/2014.
/// </summary>
public class EidasCryptoProvider : ICryptoProvider
{
public string Name => "eidas";
private readonly ILogger<EidasCryptoProvider> _logger;
private readonly EidasOptions _options;
private readonly TrustServiceProviderClient _tspClient;
private readonly LocalEidasProvider _localProvider;
private readonly Dictionary<string, CryptoSigningKey> _signingKeys = new();
public EidasCryptoProvider(
ILogger<EidasCryptoProvider> logger,
IOptions<EidasOptions> options,
TrustServiceProviderClient tspClient,
LocalEidasProvider localProvider)
{
_logger = logger;
_options = options.Value;
_tspClient = tspClient;
_localProvider = localProvider;
}
public bool Supports(CryptoCapability capability, string algorithmId)
{
// eIDAS provider supports signing and verification only
if (capability is not (CryptoCapability.Signing or CryptoCapability.Verification))
{
return false;
}
// Supported algorithms: ECDSA-P256/384/521, RSA-PSS-2048/4096, EdDSA-Ed25519/448
return algorithmId switch
{
"ECDSA-P256" or "ECDSA-P384" or "ECDSA-P521" => true,
"RSA-PSS-2048" or "RSA-PSS-4096" => true,
"EdDSA-Ed25519" or "EdDSA-Ed448" => true,
_ => false
};
}
public IPasswordHasher GetPasswordHasher(string algorithmId)
{
throw new NotSupportedException("eIDAS plugin does not support password hashing");
}
public ICryptoHasher GetHasher(string algorithmId)
{
throw new NotSupportedException("eIDAS plugin does not support content hashing - use BouncyCastle provider");
}
public ICryptoSigner GetSigner(string algorithmId, CryptoKeyReference keyReference)
{
// Return an eIDAS signer that routes to TSP or local provider
return new EidasSigner(_logger, _options, _tspClient, _localProvider, algorithmId, keyReference);
}
public void UpsertSigningKey(CryptoSigningKey signingKey)
{
_signingKeys[signingKey.Reference.KeyId] = signingKey;
_logger.LogInformation("eIDAS signing key upserted: keyId={KeyId}", signingKey.Reference.KeyId);
}
public bool RemoveSigningKey(string keyId)
{
var removed = _signingKeys.Remove(keyId);
if (removed)
{
_logger.LogInformation("eIDAS signing key removed: keyId={KeyId}", keyId);
}
return removed;
}
public IReadOnlyCollection<CryptoSigningKey> GetSigningKeys()
{
return _signingKeys.Values.ToList().AsReadOnly();
}
}