#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) #pragma warning disable using System; using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters; using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math; using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security; namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers { public class DsaDigestSigner : ISigner { private readonly IDsa dsa; private readonly IDigest digest; private readonly IDsaEncoding encoding; private bool forSigning; public DsaDigestSigner(IDsa dsa, IDigest digest) : this(dsa, digest, StandardDsaEncoding.Instance) { } public DsaDigestSigner(IDsa dsa, IDigest digest, IDsaEncoding encoding) { this.dsa = dsa; this.digest = digest; this.encoding = encoding; } public virtual string AlgorithmName { get { return digest.AlgorithmName + "with" + dsa.AlgorithmName; } } public virtual void Init(bool forSigning, ICipherParameters parameters) { this.forSigning = forSigning; AsymmetricKeyParameter k; if (parameters is ParametersWithRandom withRandom) { k = (AsymmetricKeyParameter)withRandom.Parameters; } else { k = (AsymmetricKeyParameter)parameters; } if (forSigning && !k.IsPrivate) throw new InvalidKeyException("Signing Requires Private Key."); if (!forSigning && k.IsPrivate) throw new InvalidKeyException("Verification Requires Public Key."); Reset(); dsa.Init(forSigning, parameters); } public virtual void Update(byte input) { digest.Update(input); } public virtual void BlockUpdate(byte[] input, int inOff, int inLen) { digest.BlockUpdate(input, inOff, inLen); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER public virtual void BlockUpdate(ReadOnlySpan input) { digest.BlockUpdate(input); } #endif public virtual byte[] GenerateSignature() { if (!forSigning) throw new InvalidOperationException("DSADigestSigner not initialised for signature generation."); byte[] hash = new byte[digest.GetDigestSize()]; digest.DoFinal(hash, 0); BigInteger[] sig = dsa.GenerateSignature(hash); try { return encoding.Encode(GetOrder(), sig[0], sig[1]); } catch (Exception) { throw new InvalidOperationException("unable to encode signature"); } } public virtual bool VerifySignature(byte[] signature) { if (forSigning) throw new InvalidOperationException("DSADigestSigner not initialised for verification"); byte[] hash = new byte[digest.GetDigestSize()]; digest.DoFinal(hash, 0); try { BigInteger[] sig = encoding.Decode(GetOrder(), signature); return dsa.VerifySignature(hash, sig[0], sig[1]); } catch (Exception) { return false; } } public virtual void Reset() { digest.Reset(); } protected virtual BigInteger GetOrder() { return dsa.Order; } } } #pragma warning restore #endif