180 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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;
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 this.sig = SignerUtilities.GetSigner(
 | |
| 					PgpUtilities.GetSignatureName(sigPack.KeyAlgorithm, sigPack.HashAlgorithm));
 | |
|             }
 | |
|             catch (Exception e)
 | |
|             {
 | |
|                 throw new PgpException("can't set up signature object.",  e);
 | |
|             }
 | |
|         }
 | |
| 
 | |
| 		/// <summary>Initialise the signature object for verification.</summary>
 | |
|         public void InitVerify(
 | |
|             PgpPublicKey pubKey)
 | |
|         {
 | |
| 			lastb = 0;
 | |
| 
 | |
| 			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);
 | |
|         }
 | |
|     }
 | |
| }
 |