From ec23584a31ca9e2d879b76641036b96e46e8e446 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sun, 28 Sep 2014 18:55:57 +0700 Subject: Port of GenericSIgner fix from Java --- crypto/src/crypto/signers/GenericSigner.cs | 229 +++++++++++++++-------------- 1 file changed, 115 insertions(+), 114 deletions(-) (limited to 'crypto/src') diff --git a/crypto/src/crypto/signers/GenericSigner.cs b/crypto/src/crypto/signers/GenericSigner.cs index 1a53eee2b..5035b454d 100644 --- a/crypto/src/crypto/signers/GenericSigner.cs +++ b/crypto/src/crypto/signers/GenericSigner.cs @@ -6,124 +6,125 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Signers { - public class GenericSigner - : ISigner - { - private readonly IAsymmetricBlockCipher engine; - private readonly IDigest digest; - private bool forSigning; - - public GenericSigner( - IAsymmetricBlockCipher engine, - IDigest digest) - { - this.engine = engine; - this.digest = digest; - } - - public string AlgorithmName - { - get { return "Generic(" + engine.AlgorithmName + "/" + digest.AlgorithmName + ")"; } - } - - /** - * initialise the signer for signing or verification. - * - * @param forSigning - * true if for signing, false otherwise - * @param parameters - * necessary parameters. - */ - public void Init( - bool forSigning, - ICipherParameters parameters) - { - this.forSigning = forSigning; - AsymmetricKeyParameter k; - - if (parameters is ParametersWithRandom) - { - k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; - } - else - { - k = (AsymmetricKeyParameter)parameters; - } + public class GenericSigner + : ISigner + { + private readonly IAsymmetricBlockCipher engine; + private readonly IDigest digest; + private bool forSigning; + + public GenericSigner( + IAsymmetricBlockCipher engine, + IDigest digest) + { + this.engine = engine; + this.digest = digest; + } + + public string AlgorithmName + { + get { return "Generic(" + engine.AlgorithmName + "/" + digest.AlgorithmName + ")"; } + } + + /** + * initialise the signer for signing or verification. + * + * @param forSigning + * true if for signing, false otherwise + * @param parameters + * necessary parameters. + */ + public void Init(bool forSigning, ICipherParameters parameters) + { + this.forSigning = forSigning; + + AsymmetricKeyParameter k; + if (parameters is ParametersWithRandom) + { + k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).Parameters; + } + else + { + k = (AsymmetricKeyParameter)parameters; + } if (forSigning && !k.IsPrivate) throw new InvalidKeyException("Signing requires private key."); - if (!forSigning && k.IsPrivate) + if (!forSigning && k.IsPrivate) throw new InvalidKeyException("Verification requires public key."); - Reset(); - - engine.Init(forSigning, parameters); - } - - /** - * update the internal digest with the byte b - */ - public void Update( - byte input) - { - digest.Update(input); - } - - /** - * update the internal digest with the byte array in - */ - public void BlockUpdate( - byte[] input, - int inOff, - int length) - { - digest.BlockUpdate(input, inOff, length); - } - - /** - * Generate a signature for the message we've been loaded with using the key - * we were initialised with. - */ - public byte[] GenerateSignature() - { - if (!forSigning) - throw new InvalidOperationException("GenericSigner not initialised for signature generation."); - - byte[] hash = new byte[digest.GetDigestSize()]; - digest.DoFinal(hash, 0); - - return engine.ProcessBlock(hash, 0, hash.Length); - } - - /** - * return true if the internal state represents the signature described in - * the passed in array. - */ - public bool VerifySignature( - byte[] signature) - { - if (forSigning) - throw new InvalidOperationException("GenericSigner not initialised for verification"); - - byte[] hash = new byte[digest.GetDigestSize()]; - digest.DoFinal(hash, 0); - - try - { - byte[] sig = engine.ProcessBlock(signature, 0, signature.Length); - - return Arrays.ConstantTimeAreEqual(sig, hash); - } - catch (Exception) - { - return false; - } - } - - public void Reset() - { - digest.Reset(); - } - } + Reset(); + + engine.Init(forSigning, parameters); + } + + /** + * update the internal digest with the byte b + */ + public void Update(byte input) + { + digest.Update(input); + } + + /** + * update the internal digest with the byte array in + */ + public void BlockUpdate(byte[] input, int inOff, int length) + { + digest.BlockUpdate(input, inOff, length); + } + + /** + * Generate a signature for the message we've been loaded with using the key + * we were initialised with. + */ + public byte[] GenerateSignature() + { + if (!forSigning) + throw new InvalidOperationException("GenericSigner not initialised for signature generation."); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + return engine.ProcessBlock(hash, 0, hash.Length); + } + + /** + * return true if the internal state represents the signature described in + * the passed in array. + */ + public bool VerifySignature(byte[] signature) + { + if (forSigning) + throw new InvalidOperationException("GenericSigner not initialised for verification"); + + byte[] hash = new byte[digest.GetDigestSize()]; + digest.DoFinal(hash, 0); + + try + { + byte[] sig = engine.ProcessBlock(signature, 0, signature.Length); + + // Extend with leading zeroes to match the digest size, if necessary. + if (sig.Length < hash.Length) + { + byte[] tmp = new byte[hash.Length]; + Array.Copy(sig, 0, tmp, tmp.Length - sig.Length, sig.Length); + sig = tmp; + } + + return Arrays.ConstantTimeAreEqual(sig, hash); + } + catch (Exception) + { + return false; + } + } + + public void Reset() + { + digest.Reset(); + } + } } -- cgit 1.4.1