summary refs log tree commit diff
path: root/Crypto/src/crypto/signers/GenericSigner.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/crypto/signers/GenericSigner.cs')
-rw-r--r--Crypto/src/crypto/signers/GenericSigner.cs129
1 files changed, 129 insertions, 0 deletions
diff --git a/Crypto/src/crypto/signers/GenericSigner.cs b/Crypto/src/crypto/signers/GenericSigner.cs
new file mode 100644
index 000000000..1a53eee2b
--- /dev/null
+++ b/Crypto/src/crypto/signers/GenericSigner.cs
@@ -0,0 +1,129 @@
+using System;
+
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+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;
+			}
+
+            if (forSigning && !k.IsPrivate)
+                throw new InvalidKeyException("Signing requires private key.");
+
+			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();
+		}
+	}
+}