summary refs log tree commit diff
path: root/crypto/src/openpgp/PgpOnePassSignature.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/openpgp/PgpOnePassSignature.cs')
-rw-r--r--crypto/src/openpgp/PgpOnePassSignature.cs179
1 files changed, 179 insertions, 0 deletions
diff --git a/crypto/src/openpgp/PgpOnePassSignature.cs b/crypto/src/openpgp/PgpOnePassSignature.cs
new file mode 100644
index 000000000..68fc5994d
--- /dev/null
+++ b/crypto/src/openpgp/PgpOnePassSignature.cs
@@ -0,0 +1,179 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Security;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp
+{
+	/// <remarks>A one pass signature object.</remarks>
+    public class PgpOnePassSignature
+    {
+        private OnePassSignaturePacket sigPack;
+        private int signatureType;
+		private ISigner sig;
+		private byte lastb;
+
+		internal PgpOnePassSignature(
+            BcpgInputStream bcpgInput)
+            : this((OnePassSignaturePacket) bcpgInput.ReadPacket())
+        {
+        }
+
+		internal PgpOnePassSignature(
+            OnePassSignaturePacket sigPack)
+        {
+            this.sigPack = sigPack;
+            this.signatureType = sigPack.SignatureType;
+        }
+
+		/// <summary>Initialise the signature object for verification.</summary>
+        public void InitVerify(
+            PgpPublicKey pubKey)
+        {
+			lastb = 0;
+
+			try
+			{
+				sig = SignerUtilities.GetSigner(
+					PgpUtilities.GetSignatureName(sigPack.KeyAlgorithm, sigPack.HashAlgorithm));
+			}
+			catch (Exception e)
+			{
+				throw new PgpException("can't set up signature object.",  e);
+			}
+
+			try
+            {
+                sig.Init(false, pubKey.GetKey());
+            }
+			catch (InvalidKeyException e)
+            {
+                throw new PgpException("invalid key.", e);
+            }
+        }
+
+		public void Update(
+            byte b)
+        {
+			if (signatureType == PgpSignature.CanonicalTextDocument)
+			{
+				doCanonicalUpdateByte(b);
+			}
+			else
+			{
+				sig.Update(b);
+			}
+        }
+
+		private void doCanonicalUpdateByte(
+			byte b)
+		{
+			if (b == '\r')
+			{
+				doUpdateCRLF();
+			}
+			else if (b == '\n')
+			{
+				if (lastb != '\r')
+				{
+					doUpdateCRLF();
+				}
+			}
+			else
+			{
+				sig.Update(b);
+			}
+
+			lastb = b;
+		}
+
+		private void doUpdateCRLF()
+		{
+			sig.Update((byte)'\r');
+			sig.Update((byte)'\n');
+		}
+
+		public void Update(
+            byte[] bytes)
+        {
+            if (signatureType == PgpSignature.CanonicalTextDocument)
+            {
+                for (int i = 0; i != bytes.Length; i++)
+                {
+                    doCanonicalUpdateByte(bytes[i]);
+                }
+            }
+            else
+            {
+                sig.BlockUpdate(bytes, 0, bytes.Length);
+            }
+        }
+
+        public void Update(
+            byte[]  bytes,
+            int     off,
+            int     length)
+        {
+            if (signatureType == PgpSignature.CanonicalTextDocument)
+            {
+                int finish = off + length;
+
+                for (int i = off; i != finish; i++)
+                {
+                    doCanonicalUpdateByte(bytes[i]);
+                }
+            }
+            else
+            {
+                sig.BlockUpdate(bytes, off, length);
+            }
+        }
+
+		/// <summary>Verify the calculated signature against the passed in PgpSignature.</summary>
+        public bool Verify(
+            PgpSignature pgpSig)
+        {
+            byte[] trailer = pgpSig.GetSignatureTrailer();
+
+			sig.BlockUpdate(trailer, 0, trailer.Length);
+
+			return sig.VerifySignature(pgpSig.GetSignature());
+        }
+
+        public long KeyId
+        {
+			get { return sigPack.KeyId; }
+        }
+
+		public int SignatureType
+        {
+            get { return sigPack.SignatureType; }
+        }
+
+		public HashAlgorithmTag HashAlgorithm
+		{
+			get { return sigPack.HashAlgorithm; }
+		}
+
+		public PublicKeyAlgorithmTag KeyAlgorithm
+		{
+			get { return sigPack.KeyAlgorithm; }
+		}
+
+		public byte[] GetEncoded()
+        {
+            MemoryStream bOut = new MemoryStream();
+
+            Encode(bOut);
+
+            return bOut.ToArray();
+        }
+
+		public void Encode(
+            Stream outStr)
+        {
+            BcpgOutputStream.Wrap(outStr).WritePacket(sigPack);
+        }
+    }
+}