using System.Security.Cryptography; using System.Text.Json; using IdentityShroud.Core.Model; using IdentityShroud.Core.Services; namespace IdentityShroud.Core; public class SignatureProviderFactory(DekEncryptionService dekCryptor, IServiceProvider services) { public static void SelectAlgorithmAndKey(Realm realm, Client client, out JwtSigAlgName alg, out byte[] key) { throw new NotImplementedException(); } public IJwtSignatureProvider Create(JwtSigAlgName algorithm, byte[] keyData) { //realm.DefaultSignatureAlgorithm //realm.TokenSigningKeys //IJwtSignatureProvider? sigProvider = services.GetKeyedService(); throw new NotImplementedException(); } } public class RsaJwtSignatureProvider : IJwtSignatureProvider { private JwtSigAlgName _sigAlgName; private RealmSigningKeyId _keyId; private readonly RSA _rsa; public RsaJwtSignatureProvider(DekEncryptionService dekCryptor, RealmSigningKey privateKey, JwtSigAlgName sigAlgName) { _sigAlgName = sigAlgName; _keyId = privateKey.Id; byte[] key = dekCryptor.Decrypt(privateKey.Key); _rsa = RSA.Create(); _rsa.ImportPkcs8PrivateKey(key, out int _); } /* +-------------------+---------------------------------+ | "alg" Param Value | Digital Signature Algorithm | +-------------------+---------------------------------+ | RS256 | RSASSA-PKCS1-v1_5 using SHA-256 | | RS384 | RSASSA-PKCS1-v1_5 using SHA-384 | | RS512 | RSASSA-PKCS1-v1_5 using SHA-512 | +-------------------+---------------------------------+ */ public void WriteJwtHeaderFields(Utf8JsonWriter writer) { writer.WriteString("alg"u8, _sigAlgName.ToString()); writer.WriteString("kid"u8, _keyId.ToString()); } public int GetSignatureLength() { return _rsa.KeySize / 8; } public void CalculateSignature(ReadOnlySpan jwt, Span sig) { _rsa.SignData(jwt, sig, GetHashAlgorithmName(), RSASignaturePadding.Pkcs1); } public void Dispose() { _rsa.Dispose(); } private HashAlgorithmName GetHashAlgorithmName() => _sigAlgName.Name switch { "RS256" => HashAlgorithmName.SHA256, "RS384" => HashAlgorithmName.SHA384, "RS512" => HashAlgorithmName.SHA512, _ => throw new ArgumentException("Invalid algorithm for RsaJwtSignatureProvider") }; }