summary refs log tree commit diff
path: root/crypto/test/src/openpgp/examples
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/test/src/openpgp/examples')
-rw-r--r--crypto/test/src/openpgp/examples/ByteArrayHandler.cs195
-rw-r--r--crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs375
-rw-r--r--crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs167
-rw-r--r--crypto/test/src/openpgp/examples/DirectKeySignature.cs140
-rw-r--r--crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs134
-rw-r--r--crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs259
-rw-r--r--crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs267
-rw-r--r--crypto/test/src/openpgp/examples/PbeFileProcessor.cs183
-rw-r--r--crypto/test/src/openpgp/examples/PgpExampleUtilities.cs123
-rw-r--r--crypto/test/src/openpgp/examples/PublicKeyRingDump.cs98
-rw-r--r--crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs115
-rw-r--r--crypto/test/src/openpgp/examples/SignedFileProcessor.cs188
-rw-r--r--crypto/test/src/openpgp/examples/test/AllTests.cs403
13 files changed, 2647 insertions, 0 deletions
diff --git a/crypto/test/src/openpgp/examples/ByteArrayHandler.cs b/crypto/test/src/openpgp/examples/ByteArrayHandler.cs
new file mode 100644
index 000000000..676db8766
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/ByteArrayHandler.cs
@@ -0,0 +1,195 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * Simple routine to encrypt and decrypt using a passphrase.
+    * This service routine provides the basic PGP services between
+    * byte arrays.
+    *
+    * Note: this code plays no attention to -Console in the file name
+    * the specification of "_CONSOLE" in the filename.
+    * It also expects that a single pass phrase will have been used.
+    *
+    */
+    public sealed class ByteArrayHandler
+    {
+        private ByteArrayHandler()
+        {
+        }
+
+        /**
+        * decrypt the passed in message stream
+        *
+        * @param encrypted  The message to be decrypted.
+        * @param passPhrase Pass phrase (key)
+        *
+        * @return Clear text as a byte array.  I18N considerations are
+        *         not handled by this routine
+        * @exception IOException
+        * @exception PgpException
+        */
+        public static byte[] Decrypt(
+            byte[] encrypted,
+            char[] passPhrase)
+        {
+            Stream inputStream = new MemoryStream(encrypted);
+
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+            PgpObjectFactory pgpF = new PgpObjectFactory(inputStream);
+            PgpEncryptedDataList enc = null;
+            PgpObject o = pgpF.NextPgpObject();
+
+			//
+            // the first object might be a PGP marker packet.
+            //
+            if (o is PgpEncryptedDataList)
+            {
+                enc = (PgpEncryptedDataList) o;
+            }
+            else
+            {
+                enc = (PgpEncryptedDataList) pgpF.NextPgpObject();
+            }
+
+            PgpPbeEncryptedData pbe = (PgpPbeEncryptedData)enc[0];
+
+            Stream clear = pbe.GetDataStream(passPhrase);
+
+            PgpObjectFactory pgpFact = new PgpObjectFactory(clear);
+
+            PgpCompressedData cData = (PgpCompressedData) pgpFact.NextPgpObject();
+
+            pgpFact = new PgpObjectFactory(cData.GetDataStream());
+
+            PgpLiteralData ld = (PgpLiteralData) pgpFact.NextPgpObject();
+
+            Stream unc = ld.GetInputStream();
+
+			return Streams.ReadAll(unc);
+        }
+
+        /**
+        * Simple PGP encryptor between byte[].
+        *
+        * @param clearData  The test to be encrypted
+        * @param passPhrase The pass phrase (key).  This method assumes that the
+        *                   key is a simple pass phrase, and does not yet support
+        *                   RSA or more sophisiticated keying.
+        * @param fileName   File name. This is used in the Literal Data Packet (tag 11)
+        *                   which is really inly important if the data is to be
+        *                   related to a file to be recovered later.  Because this
+        *                   routine does not know the source of the information, the
+        *                   caller can set something here for file name use that
+        *                   will be carried.  If this routine is being used to
+        *                   encrypt SOAP MIME bodies, for example, use the file name from the
+        *                   MIME type, if applicable. Or anything else appropriate.
+        *
+        * @param armor
+        *
+        * @return encrypted data.
+        * @exception IOException
+        * @exception PgpException
+        */
+        public static byte[] Encrypt(
+            byte[]						clearData,
+            char[]						passPhrase,
+            string						fileName,
+            SymmetricKeyAlgorithmTag	algorithm,
+            bool						armor)
+        {
+            if (fileName == null)
+            {
+                fileName = PgpLiteralData.Console;
+            }
+
+			byte[] compressedData = Compress(clearData, fileName, CompressionAlgorithmTag.Zip);
+
+			MemoryStream bOut = new MemoryStream();
+
+			Stream output = bOut;
+			if (armor)
+			{
+				output = new ArmoredOutputStream(output);
+			}
+
+			PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(algorithm, new SecureRandom());
+            encGen.AddMethod(passPhrase);
+
+			Stream encOut = encGen.Open(output, compressedData.Length);
+
+			encOut.Write(compressedData, 0, compressedData.Length);
+			encOut.Close();
+			
+			if (armor)
+			{
+				output.Close();
+			}
+
+			return bOut.ToArray();
+        }
+
+		private static byte[] Compress(byte[] clearData, string fileName, CompressionAlgorithmTag algorithm)
+		{
+            MemoryStream bOut = new MemoryStream();
+
+            PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(algorithm);
+            Stream cos = comData.Open(bOut); // open it with the final destination
+            PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
+
+            // we want to Generate compressed data. This might be a user option later,
+            // in which case we would pass in bOut.
+            Stream pOut = lData.Open(
+				cos,					// the compressed output stream
+                PgpLiteralData.Binary,
+                fileName,				// "filename" to store
+                clearData.Length,		// length of clear data
+                DateTime.UtcNow			// current time
+            );
+
+			pOut.Write(clearData, 0, clearData.Length);
+			pOut.Close();
+
+			comData.Close();
+
+			return bOut.ToArray();
+		}
+
+		private static string GetAsciiString(byte[] bs)
+		{
+			return Encoding.ASCII.GetString(bs, 0, bs.Length);
+		}
+
+        public static void Main(
+			string[] args)
+        {
+            string passPhrase = "Dick Beck";
+            char[] passArray = passPhrase.ToCharArray();
+
+            byte[] original = Encoding.ASCII.GetBytes("Hello world");
+            Console.WriteLine("Starting PGP test");
+            byte[] encrypted = Encrypt(original, passArray, "iway", SymmetricKeyAlgorithmTag.Cast5, true);
+
+            Console.WriteLine("\nencrypted data = '"+Hex.ToHexString(encrypted)+"'");
+            byte[] decrypted= Decrypt(encrypted,passArray);
+
+            Console.WriteLine("\ndecrypted data = '"+GetAsciiString(decrypted)+"'");
+
+            encrypted = Encrypt(original, passArray, "iway", SymmetricKeyAlgorithmTag.Aes256, false);
+
+            Console.WriteLine("\nencrypted data = '"+Hex.ToHexString(encrypted)+"'");
+            decrypted= Decrypt(encrypted, passArray);
+
+            Console.WriteLine("\ndecrypted data = '"+GetAsciiString(decrypted)+"'");
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs b/crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs
new file mode 100644
index 000000000..14fa37269
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/ClearSignedFileProcessor.cs
@@ -0,0 +1,375 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that creates clear signed files and verifies them.
+    * <p>
+    * To sign a file: ClearSignedFileProcessor -s fileName secretKey passPhrase.
+	* </p>
+    * <p>
+    * To decrypt: ClearSignedFileProcessor -v fileName signatureFile publicKeyFile.
+	* </p>
+    */
+    public sealed class ClearSignedFileProcessor
+    {
+        private ClearSignedFileProcessor()
+        {
+        }
+
+		private static int ReadInputLine(
+			MemoryStream	bOut,
+			Stream			fIn)
+		{
+			bOut.SetLength(0);
+
+			int lookAhead = -1;
+			int ch;
+
+			while ((ch = fIn.ReadByte()) >= 0)
+			{
+				bOut.WriteByte((byte) ch);
+				if (ch == '\r' || ch == '\n')
+				{
+					lookAhead = ReadPassedEol(bOut, ch, fIn);
+					break;
+				}
+			}
+
+			return lookAhead;
+		}
+
+		private static int ReadInputLine(
+			MemoryStream	bOut,
+			int				lookAhead,
+			Stream			fIn)
+		{
+			bOut.SetLength(0);
+
+			int ch = lookAhead;
+
+			do
+			{
+				bOut.WriteByte((byte) ch);
+				if (ch == '\r' || ch == '\n')
+				{
+					lookAhead = ReadPassedEol(bOut, ch, fIn);
+					break;
+				}
+			}
+			while ((ch = fIn.ReadByte()) >= 0);
+
+			if (ch < 0)
+			{
+				lookAhead = -1;
+			}
+
+			return lookAhead;
+		}
+
+		private static int ReadPassedEol(
+			MemoryStream	bOut,
+			int				lastCh,
+			Stream			fIn)
+		{
+			int lookAhead = fIn.ReadByte();
+
+			if (lastCh == '\r' && lookAhead == '\n')
+			{
+				bOut.WriteByte((byte) lookAhead);
+				lookAhead = fIn.ReadByte();
+			}
+
+			return lookAhead;
+		}
+
+		/*
+		* verify a clear text signed file
+		*/
+        private static void VerifyFile(
+            Stream	inputStream,
+            Stream	keyIn,
+			string	resultName)
+        {
+			ArmoredInputStream aIn = new ArmoredInputStream(inputStream);
+			Stream outStr = File.Create(resultName);
+
+			//
+			// write out signed section using the local line separator.
+			// note: trailing white space needs to be removed from the end of
+			// each line RFC 4880 Section 7.1
+			//
+			MemoryStream lineOut = new MemoryStream();
+			int lookAhead = ReadInputLine(lineOut, aIn);
+			byte[] lineSep = LineSeparator;
+
+			if (lookAhead != -1 && aIn.IsClearText())
+			{
+				byte[] line = lineOut.ToArray();
+				outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line));
+				outStr.Write(lineSep, 0, lineSep.Length);
+
+				while (lookAhead != -1 && aIn.IsClearText())
+				{
+					lookAhead = ReadInputLine(lineOut, lookAhead, aIn);
+                
+					line = lineOut.ToArray();
+					outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line));
+					outStr.Write(lineSep, 0, lineSep.Length);
+				}
+			}
+
+			outStr.Close();
+
+			PgpPublicKeyRingBundle pgpRings = new PgpPublicKeyRingBundle(keyIn);
+
+			PgpObjectFactory pgpFact = new PgpObjectFactory(aIn);
+			PgpSignatureList p3 = (PgpSignatureList) pgpFact.NextPgpObject();
+			PgpSignature sig = p3[0];
+
+			sig.InitVerify(pgpRings.GetPublicKey(sig.KeyId));
+
+			//
+			// read the input, making sure we ignore the last newline.
+			//
+			Stream sigIn = File.OpenRead(resultName);
+
+			lookAhead = ReadInputLine(lineOut, sigIn);
+
+			ProcessLine(sig, lineOut.ToArray());
+
+			if (lookAhead != -1)
+			{
+				do
+				{
+					lookAhead = ReadInputLine(lineOut, lookAhead, sigIn);
+
+					sig.Update((byte) '\r');
+					sig.Update((byte) '\n');
+
+					ProcessLine(sig, lineOut.ToArray());
+				}
+				while (lookAhead != -1);
+			}
+
+			sigIn.Close();
+
+			if (sig.Verify())
+            {
+                Console.WriteLine("signature verified.");
+            }
+            else
+            {
+                Console.WriteLine("signature verification failed.");
+            }
+        }
+
+		private static byte[] LineSeparator
+		{
+			get { return Encoding.ASCII.GetBytes(SimpleTest.NewLine); }
+		}
+
+        /*
+        * create a clear text signed file.
+        */
+        private static void SignFile(
+            string	fileName,
+            Stream	keyIn,
+            Stream	outputStream,
+            char[]	pass,
+			string	digestName)
+        {
+			HashAlgorithmTag digest;
+
+			if (digestName.Equals("SHA256"))
+			{
+				digest = HashAlgorithmTag.Sha256;
+			}
+			else if (digestName.Equals("SHA384"))
+			{
+				digest = HashAlgorithmTag.Sha384;
+			}
+			else if (digestName.Equals("SHA512"))
+			{
+				digest = HashAlgorithmTag.Sha512;
+			}
+			else if (digestName.Equals("MD5"))
+			{
+				digest = HashAlgorithmTag.MD5;
+			}
+			else if (digestName.Equals("RIPEMD160"))
+			{
+				digest = HashAlgorithmTag.RipeMD160;
+			}
+			else
+			{
+				digest = HashAlgorithmTag.Sha1;
+			}
+
+			PgpSecretKey                    pgpSecKey = PgpExampleUtilities.ReadSecretKey(keyIn);
+            PgpPrivateKey                   pgpPrivKey = pgpSecKey.ExtractPrivateKey(pass);
+            PgpSignatureGenerator           sGen = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, digest);
+            PgpSignatureSubpacketGenerator  spGen = new PgpSignatureSubpacketGenerator();
+
+			sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey);
+
+			IEnumerator enumerator = pgpSecKey.PublicKey.GetUserIds().GetEnumerator();
+            if (enumerator.MoveNext())
+            {
+                spGen.SetSignerUserId(false, (string) enumerator.Current);
+                sGen.SetHashedSubpackets(spGen.Generate());
+            }
+
+            Stream fIn = File.OpenRead(fileName);
+			ArmoredOutputStream aOut = new ArmoredOutputStream(outputStream);
+
+			aOut.BeginClearText(digest);
+
+			//
+			// note the last \n/\r/\r\n in the file is ignored
+			//
+			MemoryStream lineOut = new MemoryStream();
+			int lookAhead = ReadInputLine(lineOut, fIn);
+
+			ProcessLine(aOut, sGen, lineOut.ToArray());
+
+			if (lookAhead != -1)
+			{
+				do
+				{
+					lookAhead = ReadInputLine(lineOut, lookAhead, fIn);
+
+					sGen.Update((byte) '\r');
+					sGen.Update((byte) '\n');
+
+					ProcessLine(aOut, sGen, lineOut.ToArray());
+				}
+				while (lookAhead != -1);
+			}
+
+			fIn.Close();
+
+			aOut.EndClearText();
+
+			BcpgOutputStream bOut = new BcpgOutputStream(aOut);
+
+            sGen.Generate().Encode(bOut);
+
+            aOut.Close();
+        }
+
+		private static void ProcessLine(
+			PgpSignature	sig,
+			byte[]			line)
+		{
+			// note: trailing white space needs to be removed from the end of
+			// each line for signature calculation RFC 4880 Section 7.1
+			int length = GetLengthWithoutWhiteSpace(line);
+			if (length > 0)
+			{
+				sig.Update(line, 0, length);
+			}
+		}
+
+		private static void ProcessLine(
+			Stream					aOut,
+			PgpSignatureGenerator	sGen,
+			byte[]					line)
+		{
+			int length = GetLengthWithoutWhiteSpace(line);
+			if (length > 0)
+			{
+				sGen.Update(line, 0, length);
+			}
+
+			aOut.Write(line, 0, line.Length);
+		}
+
+		private static int GetLengthWithoutSeparatorOrTrailingWhitespace(byte[] line)
+		{
+			int end = line.Length - 1;
+
+			while (end >= 0 && IsWhiteSpace(line[end]))
+			{
+				end--;
+			}
+
+			return end + 1;
+		}
+
+		private static bool IsLineEnding(
+			byte b)
+		{
+			return b == '\r' || b == '\n';
+		}
+
+		private static int GetLengthWithoutWhiteSpace(
+			byte[] line)
+		{
+			int end = line.Length - 1;
+
+			while (end >= 0 && IsWhiteSpace(line[end]))
+			{
+				end--;
+			}
+
+			return end + 1;
+		}
+
+		private static bool IsWhiteSpace(
+			byte b)
+		{
+			return IsLineEnding(b) || b == '\t' || b == ' ';
+		}
+
+		public static int Main(
+            string[] args)
+        {
+            if (args[0].Equals("-s"))
+            {
+				Stream fis = File.OpenRead(args[2]);
+				Stream fos = File.Create(args[1] + ".asc");
+
+				Stream keyIn = PgpUtilities.GetDecoderStream(fis);
+
+				string digestName = (args.Length == 4)
+					?	"SHA1"
+					:	args[4];
+
+				SignFile(args[1], keyIn, fos, args[3].ToCharArray(), digestName);
+
+				fis.Close();
+				fos.Close();
+            }
+            else if (args[0].Equals("-v"))
+            {
+				if (args[1].IndexOf(".asc") < 0)
+				{
+					Console.Error.WriteLine("file needs to end in \".asc\"");
+					return 1;
+				}
+
+				Stream fin = File.OpenRead(args[1]);
+				Stream fis = File.OpenRead(args[2]);
+
+				Stream keyIn = PgpUtilities.GetDecoderStream(fis);
+
+				VerifyFile(fin, keyIn, args[1].Substring(0, args[1].Length - 4));
+
+				fin.Close();
+				fis.Close();
+            }
+            else
+            {
+                Console.Error.WriteLine("usage: ClearSignedFileProcessor [-s file keyfile passPhrase]|[-v sigFile keyFile]");
+            }
+			return 0;
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs b/crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs
new file mode 100644
index 000000000..c4959844d
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs
@@ -0,0 +1,167 @@
+using System;
+using System.Collections;
+using System.IO;
+
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that creates seperate signatures for files and verifies them.
+    * <p>
+    * To sign a file: DetachedSignatureProcessor -s [-a] fileName secretKey passPhrase.<br/>
+    * If -a is specified the output file will be "ascii-armored".</p>
+    * <p>
+    * To decrypt: DetachedSignatureProcessor -v  fileName signatureFile publicKeyFile.</p>
+    * <p>
+    * Note: this example will silently overwrite files.
+    * It also expects that a single pass phrase
+    * will have been used.</p>
+    */
+    public sealed class DetachedSignatureProcessor
+    {
+        private DetachedSignatureProcessor()
+        {
+        }
+
+		private static void VerifySignature(
+			string	fileName,
+			string	inputFileName,
+			string	keyFileName)
+		{
+			using (Stream input = File.OpenRead(inputFileName),
+				keyIn = File.OpenRead(keyFileName))
+			{
+				VerifySignature(fileName, input, keyIn);
+			}
+		}
+
+		/**
+        * verify the signature in in against the file fileName.
+        */
+        private static void VerifySignature(
+            string	fileName,
+            Stream	inputStream,
+            Stream	keyIn)
+        {
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+            PgpObjectFactory pgpFact = new PgpObjectFactory(inputStream);
+            PgpSignatureList p3 = null;
+            PgpObject o = pgpFact.NextPgpObject();
+            if (o is PgpCompressedData)
+            {
+                PgpCompressedData c1 = (PgpCompressedData)o;
+                pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+                p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+            }
+            else
+            {
+                p3 = (PgpSignatureList)o;
+            }
+
+            PgpPublicKeyRingBundle pgpPubRingCollection = new PgpPublicKeyRingBundle(
+				PgpUtilities.GetDecoderStream(keyIn));
+            Stream dIn = File.OpenRead(fileName);
+            PgpSignature sig = p3[0];
+            PgpPublicKey key = pgpPubRingCollection.GetPublicKey(sig.KeyId);
+            sig.InitVerify(key);
+
+			int ch;
+            while ((ch = dIn.ReadByte()) >= 0)
+            {
+                sig.Update((byte)ch);
+            }
+
+			dIn.Close();
+
+			if (sig.Verify())
+            {
+                Console.WriteLine("signature verified.");
+            }
+            else
+            {
+                Console.WriteLine("signature verification failed.");
+            }
+        }
+
+		private static void CreateSignature(
+			string	inputFileName,
+			string	keyFileName,
+			string	outputFileName,
+			char[]	pass,
+			bool	armor)
+		{
+			using (Stream keyIn = File.OpenRead(keyFileName),
+				output = File.OpenRead(outputFileName))
+			{
+				CreateSignature(inputFileName, keyIn, output, pass, armor);
+			}
+		}
+
+		private static void CreateSignature(
+			string	fileName,
+			Stream	keyIn,
+			Stream	outputStream,
+			char[]	pass,
+			bool	armor)
+        {
+            if (armor)
+            {
+                outputStream = new ArmoredOutputStream(outputStream);
+            }
+
+            PgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn);
+            PgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass);
+            PgpSignatureGenerator sGen = new PgpSignatureGenerator(
+				pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
+
+			BcpgOutputStream bOut = new BcpgOutputStream(outputStream);
+
+			Stream fIn = File.OpenRead(fileName);
+
+            int ch;
+            while ((ch = fIn.ReadByte()) >= 0)
+            {
+                sGen.Update((byte)ch);
+            }
+
+			fIn.Close();
+
+			sGen.Generate().Encode(bOut);
+
+			if (armor)
+			{
+				outputStream.Close();
+			}
+        }
+
+		public static void Main(
+            string[] args)
+        {
+            if (args[0].Equals("-s"))
+            {
+                if (args[1].Equals("-a"))
+                {
+					CreateSignature(args[2], args[3], args[2] + ".asc", args[4].ToCharArray(), true);
+                }
+                else
+                {
+					CreateSignature(args[1], args[2], args[1] + ".bpg", args[3].ToCharArray(), false);
+                }
+            }
+            else if (args[0].Equals("-v"))
+            {
+				VerifySignature(args[1], args[2], args[3]);
+			}
+            else
+            {
+                Console.Error.WriteLine("usage: DetachedSignatureProcessor [-s [-a] file keyfile passPhrase]|[-v file sigFile keyFile]");
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/DirectKeySignature.cs b/crypto/test/src/openpgp/examples/DirectKeySignature.cs
new file mode 100644
index 000000000..a6bf8e755
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/DirectKeySignature.cs
@@ -0,0 +1,140 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Bcpg;
+using Org.BouncyCastle.Bcpg.Sig;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+	/**
+	* A simple utility class that directly signs a public key and writes the signed key to "SignedKey.asc" in 
+	* the current working directory.
+	* <p>
+	* To sign a key: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue.<br/>
+	* </p><p>
+	* To display a NotationData packet from a publicKey previously signed: DirectKeySignature signedPublicKeyFile.<br/>
+	* </p><p>
+	* <b>Note</b>: this example will silently overwrite files, nor does it pay any attention to
+	* the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
+	* will have been used.
+	* </p>
+	*/
+	public class DirectKeySignature
+	{
+		public static void Main(
+			string[] args)
+		{
+			if (args.Length == 1)
+			{
+				Stream fis = File.OpenRead(args[0]);
+
+				PgpPublicKeyRing ring = new PgpPublicKeyRing(
+					PgpUtilities.GetDecoderStream(fis));
+				PgpPublicKey key = ring.GetPublicKey();
+
+				// iterate through all direct key signautures and look for NotationData subpackets
+				foreach (PgpSignature sig in key.GetSignaturesOfType(PgpSignature.DirectKey))
+				{
+					Console.WriteLine("Signature date is: "
+						+ sig.GetHashedSubPackets().GetSignatureCreationTime());
+
+					NotationData[] data = sig.GetHashedSubPackets().GetNotationDataOccurences();
+
+					for (int i = 0; i < data.Length; i++)
+					{
+						Console.WriteLine("Found Notaion named '" + data[i].GetNotationName()
+							+"' with content '" + data[i].GetNotationValue() + "'.");
+					}
+				}
+
+				fis.Close();
+			}
+			else if (args.Length == 5)
+			{
+				Stream secFis = File.OpenRead(args[0]);
+				Stream pubFis = File.OpenRead(args[2]);
+
+				// gather command line arguments
+				PgpSecretKeyRing secRing = new PgpSecretKeyRing(
+					PgpUtilities.GetDecoderStream(secFis));
+				String secretKeyPass = args[1];
+				PgpPublicKeyRing ring = new PgpPublicKeyRing(
+					PgpUtilities.GetDecoderStream(pubFis));
+				String notationName = args[3];
+				String notationValue = args[4];
+
+				// create the signed keyRing
+				PgpPublicKeyRing sRing = null;
+				sRing = new PgpPublicKeyRing(
+					new MemoryStream(
+						SignPublicKey(secRing.GetSecretKey(), secretKeyPass,
+							ring.GetPublicKey(), notationName, notationValue, true),
+						false));
+				ring = sRing;
+
+				secFis.Close();
+				pubFis.Close();
+
+				Stream fos = File.Create("SignedKey.asc");
+
+				// write the created keyRing to file
+				ArmoredOutputStream aOut = new ArmoredOutputStream(fos);
+				sRing.Encode(aOut);
+				aOut.Close();
+
+				// Note: ArmoredOutputStream.Close() leaves underlying stream open
+				fos.Close();
+			}
+			else
+			{
+				Console.Error.WriteLine("usage: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue");
+				Console.Error.WriteLine("or: DirectKeySignature signedPublicKeyFile");
+			}
+		}
+
+		private static byte[] SignPublicKey(
+			PgpSecretKey	secretKey,
+			string			secretKeyPass,
+			PgpPublicKey	keyToBeSigned,
+			string			notationName,
+			string			notationValue,
+			bool			armor)
+		{
+			Stream os = new MemoryStream();
+			if (armor)
+			{
+				os = new ArmoredOutputStream(os);
+			}
+
+			PgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey(
+				secretKeyPass.ToCharArray());
+
+			PgpSignatureGenerator sGen = new PgpSignatureGenerator(
+				secretKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
+
+			sGen.InitSign(PgpSignature.DirectKey, pgpPrivKey);
+
+			BcpgOutputStream bOut = new BcpgOutputStream(os);
+
+			sGen.GenerateOnePassVersion(false).Encode(bOut);
+
+			PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
+
+			bool isHumanReadable = true;
+
+			spGen.SetNotationData(true, isHumanReadable, notationName, notationValue);
+
+			PgpSignatureSubpacketVector packetVector = spGen.Generate();
+			sGen.SetHashedSubpackets(packetVector);
+
+			bOut.Flush();
+
+			if (armor)
+			{
+				os.Close();
+			}
+
+			return PgpPublicKey.AddCertification(keyToBeSigned, sGen.Generate()).GetEncoded();
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs b/crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs
new file mode 100644
index 000000000..6040351a3
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs
@@ -0,0 +1,134 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that Generates a public/secret keyring containing a DSA signing
+    * key and an El Gamal key for encryption.
+    * <p>
+    * usage: DSAElGamalKeyRingGenerator [-a] identity passPhrase</p>
+    * <p>
+    * Where identity is the name to be associated with the public key. The keys are placed
+    * in the files pub.[asc|bpg] and secret.[asc|bpg].</p>
+    * <p>
+    * <b>Note</b>: this example encrypts the secret key using AES_256, many PGP products still
+    * do not support this, if you are having problems importing keys try changing the algorithm
+    * id to PgpEncryptedData.Cast5. CAST5 is more widelysupported.</p>
+    */
+    public sealed class DsaElGamalKeyRingGenerator
+    {
+        private DsaElGamalKeyRingGenerator()
+        {
+        }
+
+		private static void ExportKeyPair(
+            Stream					secretOut,
+            Stream					publicOut,
+            AsymmetricCipherKeyPair	dsaKp,
+            AsymmetricCipherKeyPair	elgKp,
+            string					identity,
+            char[]					passPhrase,
+            bool					armor)
+        {
+            if (armor)
+            {
+                secretOut = new ArmoredOutputStream(secretOut);
+            }
+
+			PgpKeyPair dsaKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.Dsa, dsaKp, DateTime.UtcNow);
+            PgpKeyPair elgKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ElGamalEncrypt, elgKp, DateTime.UtcNow);
+
+			PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification, dsaKeyPair,
+				identity, SymmetricKeyAlgorithmTag.Aes256, passPhrase, true, null, null, new SecureRandom());
+
+			keyRingGen.AddSubKey(elgKeyPair);
+
+			keyRingGen.GenerateSecretKeyRing().Encode(secretOut);
+
+			if (armor)
+            {
+				secretOut.Close();
+				publicOut = new ArmoredOutputStream(publicOut);
+            }
+
+			keyRingGen.GeneratePublicKeyRing().Encode(publicOut);
+
+			if (armor)
+			{
+				publicOut.Close();
+			}
+        }
+
+		public static int Main(
+            string[] args)
+        {
+            if (args.Length < 2)
+            {
+                Console.WriteLine("DsaElGamalKeyRingGenerator [-a] identity passPhrase");
+                return 0;
+            }
+
+			IAsymmetricCipherKeyPairGenerator dsaKpg = GeneratorUtilities.GetKeyPairGenerator("DSA");
+            DsaParametersGenerator pGen = new DsaParametersGenerator();
+            pGen.Init(1024, 80, new SecureRandom());
+            DsaParameters dsaParams = pGen.GenerateParameters();
+            DsaKeyGenerationParameters kgp = new DsaKeyGenerationParameters(new SecureRandom(), dsaParams);
+            dsaKpg.Init(kgp);
+
+
+			//
+            // this takes a while as the key generator has to Generate some DSA parameters
+            // before it Generates the key.
+            //
+            AsymmetricCipherKeyPair dsaKp = dsaKpg.GenerateKeyPair();
+
+
+			IAsymmetricCipherKeyPairGenerator elgKpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL");
+
+			BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16);
+            BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
+
+			ElGamalParameters elParams = new ElGamalParameters(p, g);
+            ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(new SecureRandom(), elParams);
+            elgKpg.Init(elKgp);
+
+			//
+            // this is quicker because we are using preGenerated parameters.
+            //
+            AsymmetricCipherKeyPair elgKp = elgKpg.GenerateKeyPair();
+
+			Stream out1, out2;
+			if (args[0].Equals("-a"))
+            {
+                if (args.Length < 3)
+                {
+                    Console.WriteLine("DSAElGamalKeyRingGenerator [-a] identity passPhrase");
+                    return 0;
+                }
+
+				out1 = File.Create("secret.asc");
+                out2 = File.Create("pub.asc");
+
+				ExportKeyPair(out1, out2, dsaKp, elgKp, args[1], args[2].ToCharArray(), true);
+            }
+            else
+            {
+                out1 = File.Create("secret.bpg");
+                out2 = File.Create("pub.bpg");
+
+				ExportKeyPair(out1, out2, dsaKp, elgKp, args[0], args[1].ToCharArray(), false);
+            }
+			out1.Close();
+			out2.Close();
+			return 0;
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs b/crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs
new file mode 100644
index 000000000..c77408b1f
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs
@@ -0,0 +1,259 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that encrypts/decrypts public key based
+    * encryption files.
+    * <p>
+    * To encrypt a file: KeyBasedFileProcessor -e [-a|-ai] fileName publicKeyFile.<br/>
+    * If -a is specified the output file will be "ascii-armored".
+    * If -i is specified the output file will be have integrity checking added.</p>
+    * <p>
+    * To decrypt: KeyBasedFileProcessor -d fileName secretKeyFile passPhrase.</p>
+    * <p>
+	* Note 1: this example will silently overwrite files, nor does it pay any attention to
+	* the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
+	* will have been used.</p>
+	* <p>
+	* Note 2: if an empty file name has been specified in the literal data object contained in the
+	* encrypted packet a file with the name filename.out will be generated in the current working directory.</p>
+    */
+    public sealed class KeyBasedFileProcessor
+    {
+        private KeyBasedFileProcessor()
+        {
+        }
+
+		private static void DecryptFile(
+			string	inputFileName,
+			string	keyFileName,
+			char[]	passwd,
+			string	defaultFileName)
+		{
+			using (Stream input = File.OpenRead(inputFileName),
+			       keyIn = File.OpenRead(keyFileName))
+			{
+				DecryptFile(input, keyIn, passwd, defaultFileName);
+			}
+		}
+
+		/**
+		 * decrypt the passed in message stream
+		 */
+		private static void DecryptFile(
+			Stream	inputStream,
+			Stream	keyIn,
+			char[]	passwd,
+			string	defaultFileName)
+		{
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+            try
+            {
+                PgpObjectFactory pgpF = new PgpObjectFactory(inputStream);
+                PgpEncryptedDataList enc;
+
+                PgpObject o = pgpF.NextPgpObject();
+                //
+                // the first object might be a PGP marker packet.
+                //
+                if (o is PgpEncryptedDataList)
+                {
+                    enc = (PgpEncryptedDataList)o;
+                }
+                else
+                {
+                    enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
+                }
+
+                //
+                // find the secret key
+                //
+                PgpPrivateKey sKey = null;
+                PgpPublicKeyEncryptedData pbe = null;
+				PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
+					PgpUtilities.GetDecoderStream(keyIn));
+
+				foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
+                {
+                    sKey = PgpExampleUtilities.FindSecretKey(pgpSec, pked.KeyId, passwd);
+
+                    if (sKey != null)
+                    {
+                        pbe = pked;
+                        break;
+                    }
+                }
+
+				if (sKey == null)
+                {
+                    throw new ArgumentException("secret key for message not found.");
+                }
+
+                Stream clear = pbe.GetDataStream(sKey);
+
+                PgpObjectFactory plainFact = new PgpObjectFactory(clear);
+
+                PgpObject message = plainFact.NextPgpObject();
+
+                if (message is PgpCompressedData)
+                {
+                    PgpCompressedData cData = (PgpCompressedData)message;
+                    PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream());
+
+                    message = pgpFact.NextPgpObject();
+                }
+
+                if (message is PgpLiteralData)
+                {
+                    PgpLiteralData ld = (PgpLiteralData)message;
+
+					string outFileName = ld.FileName;
+					if (outFileName.Length == 0)
+					{
+						outFileName = defaultFileName;
+					}
+
+					Stream fOut = File.Create(outFileName);
+					Stream unc = ld.GetInputStream();
+					Streams.PipeAll(unc, fOut);
+					fOut.Close();
+                }
+                else if (message is PgpOnePassSignatureList)
+                {
+                    throw new PgpException("encrypted message contains a signed message - not literal data.");
+                }
+                else
+                {
+                    throw new PgpException("message is not a simple encrypted file - type unknown.");
+                }
+
+                if (pbe.IsIntegrityProtected())
+                {
+                    if (!pbe.Verify())
+                    {
+                        Console.Error.WriteLine("message failed integrity check");
+                    }
+                    else
+                    {
+                        Console.Error.WriteLine("message integrity check passed");
+                    }
+                }
+                else
+                {
+                    Console.Error.WriteLine("no message integrity check");
+                }
+            }
+            catch (PgpException e)
+            {
+                Console.Error.WriteLine(e);
+
+                Exception underlyingException = e.InnerException;
+                if (underlyingException != null)
+                {
+                    Console.Error.WriteLine(underlyingException.Message);
+                    Console.Error.WriteLine(underlyingException.StackTrace);
+                }
+            }
+        }
+		
+		private static void EncryptFile(
+			string	outputFileName,
+			string	inputFileName,
+			string	encKeyFileName,
+			bool	armor,
+			bool	withIntegrityCheck)
+		{
+			PgpPublicKey encKey = PgpExampleUtilities.ReadPublicKey(encKeyFileName);
+
+			using (Stream output = File.Create(outputFileName))
+			{
+				EncryptFile(output, inputFileName, encKey, armor, withIntegrityCheck);
+			}
+		}
+
+        private static void EncryptFile(
+            Stream			outputStream,
+            string			fileName,
+            PgpPublicKey	encKey,
+            bool			armor,
+            bool			withIntegrityCheck)
+        {
+            if (armor)
+            {
+                outputStream = new ArmoredOutputStream(outputStream);
+            }
+
+            try
+            {
+            	byte[] bytes = PgpExampleUtilities.CompressFile(fileName, CompressionAlgorithmTag.Zip);
+
+				PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(
+					SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
+				encGen.AddMethod(encKey);
+
+				Stream cOut = encGen.Open(outputStream, bytes.Length);
+
+				cOut.Write(bytes, 0, bytes.Length);
+				cOut.Close();
+
+				if (armor)
+				{
+					outputStream.Close();
+				}
+            }
+            catch (PgpException e)
+            {
+                Console.Error.WriteLine(e);
+
+                Exception underlyingException = e.InnerException;
+                if (underlyingException != null)
+                {
+                    Console.Error.WriteLine(underlyingException.Message);
+                    Console.Error.WriteLine(underlyingException.StackTrace);
+                }
+            }
+        }
+
+        public static void Main(
+            string[] args)
+        {
+            if (args.Length == 0)
+            {
+                Console.Error.WriteLine("usage: KeyBasedFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
+                return;
+            }
+
+            if (args[0].Equals("-e"))
+            {
+                if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia"))
+                {
+					EncryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].IndexOf('i') > 0));
+                }
+                else if (args[1].Equals("-i"))
+                {
+					EncryptFile(args[2] + ".bpg", args[2], args[3], false, true);
+                }
+                else
+                {
+					EncryptFile(args[1] + ".bpg", args[1], args[2], false, false);
+                }
+            }
+            else if (args[0].Equals("-d"))
+            {
+				DecryptFile(args[1], args[2], args[3].ToCharArray(), new FileInfo(args[1]).Name + ".out");
+            }
+            else
+            {
+                Console.Error.WriteLine("usage: KeyBasedFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs b/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs
new file mode 100644
index 000000000..7fb00a3b7
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs
@@ -0,0 +1,267 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that encrypts/decrypts public key based
+    * encryption large files.
+    * <p>
+    * To encrypt a file: KeyBasedLargeFileProcessor -e [-a|-ai] fileName publicKeyFile.<br/>
+    * If -a is specified the output file will be "ascii-armored".
+    * If -i is specified the output file will be have integrity checking added.</p>
+    * <p>
+    * To decrypt: KeyBasedLargeFileProcessor -d fileName secretKeyFile passPhrase.</p>
+    * <p>
+    * Note 1: this example will silently overwrite files, nor does it pay any attention to
+    * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
+    * will have been used.</p>
+    * <p>
+    * Note 2: this example Generates partial packets to encode the file, the output it Generates
+    * will not be readable by older PGP products or products that don't support partial packet
+    * encoding.</p>
+	* <p>
+	* Note 3: if an empty file name has been specified in the literal data object contained in the
+	* encrypted packet a file with the name filename.out will be generated in the current working directory.</p>
+    */
+    public sealed class KeyBasedLargeFileProcessor
+    {
+        private KeyBasedLargeFileProcessor()
+        {
+        }
+
+		private static void DecryptFile(
+			string	inputFileName,
+			string	keyFileName,
+			char[]	passwd,
+			string	defaultFileName)
+		{
+			using (Stream input = File.OpenRead(inputFileName),
+			       keyIn = File.OpenRead(keyFileName))
+			{
+				DecryptFile(input, keyIn, passwd, defaultFileName);
+			}
+		}
+
+		/**
+        * decrypt the passed in message stream
+        */
+        private static void DecryptFile(
+            Stream	inputStream,
+            Stream	keyIn,
+			char[]	passwd,
+			string	defaultFileName)
+		{
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+            try
+            {
+                PgpObjectFactory        pgpF = new PgpObjectFactory(inputStream);
+                PgpEncryptedDataList    enc;
+
+                PgpObject o = pgpF.NextPgpObject();
+                //
+                // the first object might be a PGP marker packet.
+                //
+                if (o is PgpEncryptedDataList)
+                {
+                    enc = (PgpEncryptedDataList)o;
+                }
+                else
+                {
+                    enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
+                }
+
+                //
+                // find the secret key
+                //
+                PgpPrivateKey sKey = null;
+                PgpPublicKeyEncryptedData pbe = null;
+				PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
+					PgpUtilities.GetDecoderStream(keyIn));
+
+				foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
+                {
+                    sKey = PgpExampleUtilities.FindSecretKey(pgpSec, pked.KeyId, passwd);
+
+                    if (sKey != null)
+                    {
+                        pbe = pked;
+                        break;
+                    }
+                }
+
+                if (sKey == null)
+                {
+                    throw new ArgumentException("secret key for message not found.");
+                }
+
+                Stream clear = pbe.GetDataStream(sKey);
+
+                PgpObjectFactory plainFact = new PgpObjectFactory(clear);
+
+                PgpCompressedData cData = (PgpCompressedData) plainFact.NextPgpObject();
+
+                PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream());
+
+                PgpObject message = pgpFact.NextPgpObject();
+
+                if (message is PgpLiteralData)
+                {
+                    PgpLiteralData ld = (PgpLiteralData)message;
+
+					string outFileName = ld.FileName;
+					if (outFileName.Length == 0)
+					{
+						outFileName = defaultFileName;
+					}
+
+					Stream fOut = File.Create(outFileName);
+                    Stream unc = ld.GetInputStream();
+					Streams.PipeAll(unc, fOut);
+					fOut.Close();
+                }
+                else if (message is PgpOnePassSignatureList)
+                {
+                    throw new PgpException("encrypted message contains a signed message - not literal data.");
+                }
+                else
+                {
+                    throw new PgpException("message is not a simple encrypted file - type unknown.");
+                }
+
+                if (pbe.IsIntegrityProtected())
+                {
+                    if (!pbe.Verify())
+                    {
+                        Console.Error.WriteLine("message failed integrity check");
+                    }
+                    else
+                    {
+                        Console.Error.WriteLine("message integrity check passed");
+                    }
+                }
+                else
+                {
+                    Console.Error.WriteLine("no message integrity check");
+                }
+            }
+            catch (PgpException e)
+            {
+                Console.Error.WriteLine(e);
+
+                Exception underlyingException = e.InnerException;
+                if (underlyingException != null)
+                {
+                    Console.Error.WriteLine(underlyingException.Message);
+                    Console.Error.WriteLine(underlyingException.StackTrace);
+                }
+            }
+        }
+
+		private static void EncryptFile(
+			string	outputFileName,
+			string	inputFileName,
+			string	encKeyFileName,
+			bool	armor,
+			bool	withIntegrityCheck)
+		{
+			PgpPublicKey encKey = PgpExampleUtilities.ReadPublicKey(encKeyFileName);
+
+			using (Stream output = File.Create(outputFileName))
+			{
+				EncryptFile(output, inputFileName, encKey, armor, withIntegrityCheck);
+			}
+		}
+
+        private static void EncryptFile(
+            Stream			outputStream,
+            string			fileName,
+            PgpPublicKey	encKey,
+            bool			armor,
+            bool			withIntegrityCheck)
+        {
+            if (armor)
+            {
+                outputStream = new ArmoredOutputStream(outputStream);
+            }
+
+            try
+            {
+                PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
+
+                cPk.AddMethod(encKey);
+
+                Stream cOut = cPk.Open(outputStream, new byte[1 << 16]);
+
+                PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(
+					CompressionAlgorithmTag.Zip);
+
+				PgpUtilities.WriteFileToLiteralData(
+					comData.Open(cOut),
+					PgpLiteralData.Binary,
+					new FileInfo(fileName),
+					new byte[1 << 16]);
+
+				comData.Close();
+
+				cOut.Close();
+
+				if (armor)
+				{
+					outputStream.Close();
+				}
+            }
+            catch (PgpException e)
+            {
+                Console.Error.WriteLine(e);
+
+                Exception underlyingException = e.InnerException;
+                if (underlyingException != null)
+                {
+                    Console.Error.WriteLine(underlyingException.Message);
+                    Console.Error.WriteLine(underlyingException.StackTrace);
+                }
+            }
+        }
+
+        public static void Main(
+            string[] args)
+        {
+            if (args.Length == 0)
+            {
+                Console.Error.WriteLine("usage: KeyBasedLargeFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
+                return;
+            }
+
+            if (args[0].Equals("-e"))
+            {
+                if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia"))
+                {
+					EncryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].IndexOf('i') > 0));
+                }
+                else if (args[1].Equals("-i"))
+                {
+					EncryptFile(args[2] + ".bpg", args[2], args[3], false, true);
+                }
+                else
+                {
+					EncryptFile(args[1] + ".bpg", args[1], args[2], false, false);
+                }
+            }
+            else if (args[0].Equals("-d"))
+            {
+				DecryptFile(args[1], args[2], args[3].ToCharArray(), new FileInfo(args[1]).Name + ".out");
+            }
+            else
+            {
+                Console.Error.WriteLine("usage: KeyBasedLargeFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/PbeFileProcessor.cs b/crypto/test/src/openpgp/examples/PbeFileProcessor.cs
new file mode 100644
index 000000000..66b1cc4ed
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/PbeFileProcessor.cs
@@ -0,0 +1,183 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.IO;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that encrypts/decrypts password based
+    * encryption files.
+    * <p>
+    * To encrypt a file: PBEFileProcessor -e [-ai] fileName passPhrase.<br/>
+    * If -a is specified the output file will be "ascii-armored".<br/>
+    * If -i is specified the output file will be "integrity protected".</p>
+    * <p>
+    * To decrypt: PBEFileProcessor -d fileName passPhrase.</p>
+    * <p>
+    * Note: this example will silently overwrite files, nor does it pay any attention to
+    * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
+    * will have been used.</p>
+    */
+    public sealed class PbeFileProcessor
+    {
+        private PbeFileProcessor() {}
+
+		private static void DecryptFile(string inputFileName, char[] passPhrase)
+		{
+			using (Stream input = File.OpenRead(inputFileName))
+			{
+				DecryptFile(input, passPhrase);
+			}
+		}
+
+        /**
+        * decrypt the passed in message stream
+        */
+        private static void DecryptFile(
+            Stream	inputStream,
+            char[]	passPhrase)
+        {
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+			PgpObjectFactory pgpF = new PgpObjectFactory(inputStream);
+            PgpObject o = pgpF.NextPgpObject();
+
+            //
+            // the first object might be a PGP marker packet.
+            //
+			PgpEncryptedDataList enc = o as PgpEncryptedDataList;
+            if (enc == null)
+            {
+                enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
+            }
+
+            PgpPbeEncryptedData pbe = (PgpPbeEncryptedData)enc[0];
+
+            Stream clear = pbe.GetDataStream(passPhrase);
+
+            PgpObjectFactory pgpFact = new PgpObjectFactory(clear);
+
+			//
+			// if we're trying to read a file generated by someone other than us
+			// the data might not be compressed, so we check the return type from
+			// the factory and behave accordingly.
+			//
+			o = pgpFact.NextPgpObject();
+			if (o is PgpCompressedData)
+			{
+				PgpCompressedData cData = (PgpCompressedData) o;
+				pgpFact = new PgpObjectFactory(cData.GetDataStream());
+				o = pgpFact.NextPgpObject();
+			}
+
+			PgpLiteralData ld = (PgpLiteralData) o;
+			Stream unc = ld.GetInputStream();
+            Stream fOut = File.Create(ld.FileName);
+			Streams.PipeAll(unc, fOut);
+			fOut.Close();
+
+			if (pbe.IsIntegrityProtected())
+            {
+                if (!pbe.Verify())
+                {
+                    Console.Error.WriteLine("message failed integrity check");
+                }
+                else
+                {
+                    Console.Error.WriteLine("message integrity check passed");
+                }
+            }
+            else
+            {
+                Console.Error.WriteLine("no message integrity check");
+            }
+        }
+
+		private static void EncryptFile(
+			string	outputFileName,
+			string	inputFileName,
+			char[]	passPhrase,
+			bool	armor,
+			bool	withIntegrityCheck)
+		{
+			using (Stream output = File.Create(outputFileName))
+			{
+				EncryptFile(output, inputFileName, passPhrase, armor, withIntegrityCheck);
+			}
+		}
+
+        private static void EncryptFile(
+            Stream	outputStream,
+            string	fileName,
+            char[]	passPhrase,
+            bool	armor,
+            bool	withIntegrityCheck)
+        {
+            if (armor)
+            {
+                outputStream = new ArmoredOutputStream(outputStream);
+            }
+
+			try
+            {
+				byte[] compressedData = PgpExampleUtilities.CompressFile(fileName, CompressionAlgorithmTag.Zip);
+
+				PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(
+					SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
+				encGen.AddMethod(passPhrase);
+
+				Stream encOut = encGen.Open(outputStream, compressedData.Length);
+
+	            encOut.Write(compressedData, 0, compressedData.Length);
+				encOut.Close();
+
+				if (armor)
+				{
+					outputStream.Close();
+				}
+            }
+            catch (PgpException e)
+            {
+                Console.Error.WriteLine(e);
+
+                Exception underlyingException = e.InnerException;
+                if (underlyingException != null)
+                {
+                    Console.Error.WriteLine(underlyingException.Message);
+                    Console.Error.WriteLine(underlyingException.StackTrace);
+                }
+            }
+        }
+
+		public static void Main(
+			string[] args)
+        {
+            if (args[0].Equals("-e"))
+            {
+                if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia"))
+                {
+					EncryptFile(args[2] + ".asc", args[2], args[3].ToCharArray(), true, (args[1].IndexOf('i') > 0));
+                }
+                else if (args[1].Equals("-i"))
+                {
+					EncryptFile(args[2] + ".bpg", args[2], args[3].ToCharArray(), false, true);
+                }
+                else
+                {
+					EncryptFile(args[1] + ".bpg", args[1], args[2].ToCharArray(), false, false);
+                }
+            }
+            else if (args[0].Equals("-d"))
+            {
+				DecryptFile(args[1], args[2].ToCharArray());
+            }
+            else
+            {
+                Console.Error.WriteLine("usage: PbeFileProcessor -e [-ai]|-d file passPhrase");
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/PgpExampleUtilities.cs b/crypto/test/src/openpgp/examples/PgpExampleUtilities.cs
new file mode 100644
index 000000000..fd371d7af
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/PgpExampleUtilities.cs
@@ -0,0 +1,123 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+	internal class PgpExampleUtilities
+	{
+		internal static byte[] CompressFile(string fileName, CompressionAlgorithmTag algorithm)
+		{
+			MemoryStream bOut = new MemoryStream();
+			PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(algorithm);
+			PgpUtilities.WriteFileToLiteralData(comData.Open(bOut), PgpLiteralData.Binary,
+				new FileInfo(fileName));
+			comData.Close();
+			return bOut.ToArray();
+		}
+
+		/**
+		 * Search a secret key ring collection for a secret key corresponding to keyID if it
+		 * exists.
+		 * 
+		 * @param pgpSec a secret key ring collection.
+		 * @param keyID keyID we want.
+		 * @param pass passphrase to decrypt secret key with.
+		 * @return
+		 * @throws PGPException
+		 * @throws NoSuchProviderException
+		 */
+		internal static PgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyID, char[] pass)
+		{
+			PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyID);
+
+			if (pgpSecKey == null)
+			{
+				return null;
+			}
+
+			return pgpSecKey.ExtractPrivateKey(pass);
+		}
+
+		internal static PgpPublicKey ReadPublicKey(string fileName)
+		{
+			using (Stream keyIn = File.OpenRead(fileName))
+			{
+				return ReadPublicKey(keyIn);
+			}
+		}
+
+		/**
+		 * A simple routine that opens a key ring file and loads the first available key
+		 * suitable for encryption.
+		 * 
+		 * @param input
+		 * @return
+		 * @throws IOException
+		 * @throws PGPException
+		 */
+		internal static PgpPublicKey ReadPublicKey(Stream input)
+		{
+			PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle(
+				PgpUtilities.GetDecoderStream(input));
+
+			//
+			// we just loop through the collection till we find a key suitable for encryption, in the real
+			// world you would probably want to be a bit smarter about this.
+			//
+
+			foreach (PgpPublicKeyRing keyRing in pgpPub.GetKeyRings())
+			{
+				foreach (PgpPublicKey key in keyRing.GetPublicKeys())
+				{
+					if (key.IsEncryptionKey)
+					{
+						return key;
+					}
+				}
+			}
+
+			throw new ArgumentException("Can't find encryption key in key ring.");
+		}
+
+		internal static PgpSecretKey ReadSecretKey(string fileName)
+		{
+			using (Stream keyIn = File.OpenRead(fileName))
+			{
+				return ReadSecretKey(keyIn);
+			}
+		}
+
+		/**
+		 * A simple routine that opens a key ring file and loads the first available key
+		 * suitable for signature generation.
+		 * 
+		 * @param input stream to read the secret key ring collection from.
+		 * @return a secret key.
+		 * @throws IOException on a problem with using the input stream.
+		 * @throws PGPException if there is an issue parsing the input stream.
+		 */
+		internal static PgpSecretKey ReadSecretKey(Stream input)
+		{
+			PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
+				PgpUtilities.GetDecoderStream(input));
+
+			//
+			// we just loop through the collection till we find a key suitable for encryption, in the real
+			// world you would probably want to be a bit smarter about this.
+			//
+
+			foreach (PgpSecretKeyRing keyRing in pgpSec.GetKeyRings())
+			{
+				foreach (PgpSecretKey key in keyRing.GetSecretKeys())
+				{
+					if (key.IsSigningKey)
+					{
+						return key;
+					}
+				}
+			}
+
+			throw new ArgumentException("Can't find signing key in key ring.");
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs b/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs
new file mode 100644
index 000000000..bb6108f2d
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Asn1.Utilities;
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * Basic class which just lists the contents of the public key file passed
+    * as an argument. If the file contains more than one "key ring" they are
+    * listed in the order found.
+    */
+    public sealed class PublicKeyRingDump
+    {
+        private PublicKeyRingDump()
+        {
+        }
+
+        public static string GetAlgorithm(
+            PublicKeyAlgorithmTag algId)
+        {
+            switch (algId)
+            {
+                case PublicKeyAlgorithmTag.RsaGeneral:
+                    return "RsaGeneral";
+                case PublicKeyAlgorithmTag.RsaEncrypt:
+                    return "RsaEncrypt";
+                case PublicKeyAlgorithmTag.RsaSign:
+                    return "RsaSign";
+                case PublicKeyAlgorithmTag.ElGamalEncrypt:
+                    return "ElGamalEncrypt";
+                case PublicKeyAlgorithmTag.Dsa:
+                    return "DSA";
+                case PublicKeyAlgorithmTag.EC:
+                    return "EC";
+                case PublicKeyAlgorithmTag.ECDsa:
+                    return "ECDSA";
+                case PublicKeyAlgorithmTag.ElGamalGeneral:
+                    return "ElGamalGeneral";
+                case PublicKeyAlgorithmTag.DiffieHellman:
+                    return "DiffieHellman";
+            }
+
+            return "unknown";
+        }
+
+		public static void Main(
+			string[] args)
+        {
+			Stream fs = File.OpenRead(args[0]);
+
+			//
+            // Read the public key rings
+            //
+            PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(
+                PgpUtilities.GetDecoderStream(fs));
+
+			fs.Close();
+
+			foreach (PgpPublicKeyRing pgpPub in pubRings.GetKeyRings())
+            {
+                try
+                {
+					//PgpPublicKey pubKey =
+					pgpPub.GetPublicKey();
+                }
+                catch (Exception e)
+                {
+                    Console.Error.WriteLine(e.Message);
+                    Console.Error.WriteLine(e.StackTrace);
+                    continue;
+                }
+
+				bool first = true;
+
+				foreach (PgpPublicKey pgpKey in pgpPub.GetPublicKeys())
+                {
+                    if (first)
+                    {
+                        Console.WriteLine("Key ID: " +  pgpKey.KeyId.ToString("X"));
+                        first = false;
+                    }
+                    else
+                    {
+                        Console.WriteLine("Key ID: " + pgpKey.KeyId.ToString("X") + " (subkey)");
+                    }
+
+					Console.WriteLine("            Algorithm: " + GetAlgorithm(pgpKey.Algorithm));
+                    Console.WriteLine("            Fingerprint: " + Hex.ToHexString(pgpKey.GetFingerprint()));
+                }
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs b/crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs
new file mode 100644
index 000000000..284118b99
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs
@@ -0,0 +1,115 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Security;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that Generates a RSA PgpPublicKey/PgpSecretKey pair.
+    * <p>
+    * usage: RsaKeyRingGenerator [-a] identity passPhrase</p>
+    * <p>
+    * Where identity is the name to be associated with the public key. The keys are placed
+    * in the files pub.[asc|bpg] and secret.[asc|bpg].</p>
+    */
+    public sealed class RsaKeyRingGenerator
+    {
+        private RsaKeyRingGenerator()
+        {
+        }
+
+		private static void ExportKeyPair(
+            Stream                   secretOut,
+            Stream                   publicOut,
+            AsymmetricKeyParameter   publicKey,
+            AsymmetricKeyParameter   privateKey,
+            string                   identity,
+            char[]                   passPhrase,
+            bool                     armor)
+        {
+			if (armor)
+			{
+				secretOut = new ArmoredOutputStream(secretOut);
+			}
+
+			PgpSecretKey secretKey = new PgpSecretKey(
+                PgpSignature.DefaultCertification,
+                PublicKeyAlgorithmTag.RsaGeneral,
+                publicKey,
+                privateKey,
+                DateTime.UtcNow,
+                identity,
+                SymmetricKeyAlgorithmTag.Cast5,
+                passPhrase,
+                null,
+                null,
+                new SecureRandom()
+                );
+
+            secretKey.Encode(secretOut);
+
+			if (armor)
+            {
+				secretOut.Close();
+				publicOut = new ArmoredOutputStream(publicOut);
+            }
+
+            PgpPublicKey key = secretKey.PublicKey;
+
+            key.Encode(publicOut);
+
+			if (armor)
+			{
+				publicOut.Close();
+			}
+        }
+
+		public static int Main(
+			string[] args)
+        {
+            IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("RSA");
+
+            kpg.Init(new RsaKeyGenerationParameters(
+				BigInteger.ValueOf(0x10001), new SecureRandom(), 1024, 25));
+
+            AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();
+
+            if (args.Length < 2)
+            {
+                Console.WriteLine("RsaKeyPairGenerator [-a] identity passPhrase");
+                return 0;
+            }
+
+			Stream out1, out2;
+            if (args[0].Equals("-a"))
+            {
+                if (args.Length < 3)
+                {
+                    Console.WriteLine("RsaKeyPairGenerator [-a] identity passPhrase");
+					return 0;
+				}
+
+				out1 = File.Create("secret.asc");
+                out2 = File.Create("pub.asc");
+
+                ExportKeyPair(out1, out2, kp.Public, kp.Private, args[1], args[2].ToCharArray(), true);
+            }
+            else
+            {
+                out1 = File.Create("secret.bpg");
+                out2 = File.Create("pub.bpg");
+
+                ExportKeyPair(out1, out2, kp.Public, kp.Private, args[0], args[1].ToCharArray(), false);
+            }
+			out1.Close();
+			out2.Close();
+			return 0;
+		}
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/SignedFileProcessor.cs b/crypto/test/src/openpgp/examples/SignedFileProcessor.cs
new file mode 100644
index 000000000..1ad0d102b
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/SignedFileProcessor.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Collections;
+using System.IO;
+
+
+using Org.BouncyCastle.Bcpg.OpenPgp;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
+{
+    /**
+    * A simple utility class that signs and verifies files.
+    * <p>
+    * To sign a file: SignedFileProcessor -s [-a] fileName secretKey passPhrase.<br/>
+    * If -a is specified the output file will be "ascii-armored".</p>
+    * <p>
+    * To decrypt: SignedFileProcessor -v fileName publicKeyFile.</p>
+    * <p>
+    * <b>Note</b>: this example will silently overwrite files, nor does it pay any attention to
+    * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
+    * will have been used.</p>
+    * <p>
+    * <b>Note</b>: the example also makes use of PGP compression. If you are having difficulty Getting it
+    * to interoperate with other PGP programs try removing the use of compression first.</p>
+    */
+    public sealed class SignedFileProcessor
+    {
+        private SignedFileProcessor() {}
+
+		/**
+        * verify the passed in file as being correctly signed.
+        */
+        private static void VerifyFile(
+            Stream	inputStream,
+            Stream	keyIn)
+        {
+            inputStream = PgpUtilities.GetDecoderStream(inputStream);
+
+            PgpObjectFactory			pgpFact = new PgpObjectFactory(inputStream);
+            PgpCompressedData			c1 = (PgpCompressedData) pgpFact.NextPgpObject();
+            pgpFact = new PgpObjectFactory(c1.GetDataStream());
+
+            PgpOnePassSignatureList		p1 = (PgpOnePassSignatureList) pgpFact.NextPgpObject();
+            PgpOnePassSignature			ops = p1[0];
+
+            PgpLiteralData				p2 = (PgpLiteralData) pgpFact.NextPgpObject();
+            Stream						dIn = p2.GetInputStream();
+            PgpPublicKeyRingBundle		pgpRing = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(keyIn));
+            PgpPublicKey				key = pgpRing.GetPublicKey(ops.KeyId);
+            Stream						fos = File.Create(p2.FileName);
+
+			ops.InitVerify(key);
+
+			int ch;
+			while ((ch = dIn.ReadByte()) >= 0)
+            {
+                ops.Update((byte)ch);
+                fos.WriteByte((byte) ch);
+            }
+            fos.Close();
+
+            PgpSignatureList	p3 = (PgpSignatureList)pgpFact.NextPgpObject();
+			PgpSignature		firstSig = p3[0];
+            if (ops.Verify(firstSig))
+            {
+                Console.Out.WriteLine("signature verified.");
+            }
+            else
+            {
+                Console.Out.WriteLine("signature verification failed.");
+            }
+        }
+
+        /**
+        * Generate an encapsulated signed file.
+        *
+        * @param fileName
+        * @param keyIn
+        * @param outputStream
+        * @param pass
+        * @param armor
+        */
+        private static void SignFile(
+            string	fileName,
+            Stream	keyIn,
+            Stream	outputStream,
+            char[]	pass,
+            bool	armor,
+			bool	compress)
+        {
+            if (armor)
+            {
+                outputStream = new ArmoredOutputStream(outputStream);
+            }
+
+            PgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn);
+            PgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass);
+            PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
+
+            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
+            foreach (string userId in pgpSec.PublicKey.GetUserIds())
+            {
+                PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
+                spGen.SetSignerUserId(false, userId);
+                sGen.SetHashedSubpackets(spGen.Generate());
+                // Just the first one!
+                break;
+            }
+
+            Stream cOut = outputStream;
+			PgpCompressedDataGenerator cGen = null;
+			if (compress)
+			{
+				cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.ZLib);
+
+				cOut = cGen.Open(cOut);
+			}
+
+			BcpgOutputStream bOut = new BcpgOutputStream(cOut);
+
+            sGen.GenerateOnePassVersion(false).Encode(bOut);
+
+            FileInfo					file = new FileInfo(fileName);
+            PgpLiteralDataGenerator     lGen = new PgpLiteralDataGenerator();
+            Stream						lOut = lGen.Open(bOut, PgpLiteralData.Binary, file);
+            FileStream					fIn = file.OpenRead();
+            int                         ch = 0;
+
+			while ((ch = fIn.ReadByte()) >= 0)
+            {
+                lOut.WriteByte((byte) ch);
+                sGen.Update((byte)ch);
+            }
+
+			fIn.Close();
+			lGen.Close();
+
+			sGen.Generate().Encode(bOut);
+
+			if (cGen != null)
+			{
+				cGen.Close();
+			}
+
+			if (armor)
+			{
+				outputStream.Close();
+			}
+        }
+
+		public static void Main(
+            string[] args)
+        {
+			// TODO provide command-line option to determine whether to use compression in SignFile
+            if (args[0].Equals("-s"))
+            {
+				Stream keyIn, fos;
+                if (args[1].Equals("-a"))
+                {
+                    keyIn = File.OpenRead(args[3]);
+                    fos = File.Create(args[2] + ".asc");
+
+					SignFile(args[2], keyIn, fos, args[4].ToCharArray(), true, true);
+                }
+                else
+                {
+                    keyIn = File.OpenRead(args[2]);
+                    fos = File.Create(args[1] + ".bpg");
+
+					SignFile(args[1], keyIn, fos, args[3].ToCharArray(), false, true);
+                }
+				keyIn.Close();
+				fos.Close();
+            }
+            else if (args[0].Equals("-v"))
+            {
+				using (Stream fis = File.OpenRead(args[1]),
+                	keyIn = File.OpenRead(args[2]))
+				{
+					VerifyFile(fis, keyIn);
+				}
+			}
+            else
+            {
+                Console.Error.WriteLine("usage: SignedFileProcessor -v|-s [-a] file keyfile [passPhrase]");
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/examples/test/AllTests.cs b/crypto/test/src/openpgp/examples/test/AllTests.cs
new file mode 100644
index 000000000..180d2fa80
--- /dev/null
+++ b/crypto/test/src/openpgp/examples/test/AllTests.cs
@@ -0,0 +1,403 @@
+using System;
+using System.IO;
+
+using NUnit.Core;
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples.Tests
+{
+	[TestFixture]
+	public class AllTests
+	{
+		private static readonly byte[] clearSignedPublicKey = Base64.Decode(
+			  "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+"
+			+ "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1"
+			+ "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO"
+			+ "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7"
+			+ "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4"
+			+ "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp"
+			+ "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD"
+			+ "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR"
+			+ "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch"
+			+ "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg"
+			+ "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r"
+			+ "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1"
+			+ "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz"
+			+ "oztls8tuWA0OGHba9XfX9rfgorACAAM=");
+
+		private static readonly string crOnlyMessage =
+			"\r"
+			+ " hello world!\r"
+			+ "\r"
+			+ "- dash\r";
+
+		private static readonly string nlOnlyMessage =
+			"\n"
+			+ " hello world!\n"
+			+ "\n"
+			+ "- dash\n";
+
+		private static readonly string crNlMessage =
+			"\r\n"
+			+ " hello world!\r\n"
+			+ "\r\n"
+			+ "- dash\r\n";
+
+		private static readonly string crNlMessageTrailingWhiteSpace =
+			"\r\n"
+			+ " hello world! \t\r\n"
+			+ "\r\n"
+			+ "\r\n";
+
+		private static readonly string crOnlySignedMessage =
+			"-----BEGIN PGP SIGNED MESSAGE-----\r"
+			+ "Hash: SHA256\r"
+			+ "\r"
+			+ "\r"
+			+ " hello world!\r"
+			+ "\r"
+			+ "- - dash\r"
+			+ "-----BEGIN PGP SIGNATURE-----\r"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r"
+			+ "\r"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r"
+			+ "=84Nd\r"
+			+ "-----END PGP SIGNATURE-----\r";
+
+		private static readonly string nlOnlySignedMessage =
+			"-----BEGIN PGP SIGNED MESSAGE-----\n"
+			+ "Hash: SHA256\n"
+			+ "\n"
+			+ "\n"
+			+ " hello world!\n"
+			+ "\n"
+			+ "- - dash\n"
+			+ "-----BEGIN PGP SIGNATURE-----\n"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\n"
+			+ "\n"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n"
+			+ "=84Nd\n"
+			+ "-----END PGP SIGNATURE-----\n";
+
+		private static readonly string crNlSignedMessage =
+			"-----BEGIN PGP SIGNED MESSAGE-----\r\n"
+			+ "Hash: SHA256\r\n"
+			+ "\r\n"
+			+ "\r\n"
+			+ " hello world!\r\n"
+			+ "\r\n"
+			+ "- - dash\r\n"
+			+ "-----BEGIN PGP SIGNATURE-----\r\n"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n"
+			+ "\r\n"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n"
+			+ "=84Nd\r"
+			+ "-----END PGP SIGNATURE-----\r\n";
+
+		private static readonly string crNlSignedMessageTrailingWhiteSpace =
+			"-----BEGIN PGP SIGNED MESSAGE-----\r\n"
+			+ "Hash: SHA256\r\n"
+			+ "\r\n"
+			+ "\r\n"
+			+ " hello world! \t\r\n"
+			+ "\r\n"
+			+ "- - dash\r\n"
+			+ "-----BEGIN PGP SIGNATURE-----\r\n"
+			+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n"
+			+ "\r\n"
+			+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n"
+			+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n"
+			+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n"
+			+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n"
+			+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n"
+			+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n"
+			+ "=84Nd\r"
+			+ "-----END PGP SIGNATURE-----\r\n";
+
+		private TextWriter _oldOut;
+		private TextWriter _oldErr;
+
+		private MemoryStream _currentOut;
+		private MemoryStream _currentErr;
+
+		[SetUp]
+		public void SetUp()
+		{
+			_oldOut = Console.Out;
+			_oldErr = Console.Error;
+			_currentOut = new MemoryStream();
+			_currentErr = new MemoryStream();
+
+			Console.SetOut(new StreamWriter(_currentOut));
+			Console.SetError(new StreamWriter(_currentErr));
+		}
+
+		[TearDown]
+		public void TearDown()
+		{
+			Console.SetOut(_oldOut);
+			Console.SetError(_oldErr);
+		}
+
+		[Test]
+		public void TestRsaKeyGeneration() 
+		{
+			RsaKeyRingGenerator.Main(new string[] { "test", "password" });
+
+			CreateSmallTestInput();
+			CreateLargeTestInput();
+
+			CheckSigning("bpg");
+			CheckKeyBasedEncryption("bpg");
+			CheckLargeKeyBasedEncryption("bpg");
+
+			RsaKeyRingGenerator.Main(new string[] { "-a", "test", "password" });
+
+			CheckSigning("asc");
+			CheckKeyBasedEncryption("asc");
+			CheckLargeKeyBasedEncryption("asc");
+		}
+
+		[Test]
+		public void TestDsaElGamalKeyGeneration() 
+		{
+			DsaElGamalKeyRingGenerator.Main(new string[] { "test", "password" });
+
+			CreateSmallTestInput();
+			CreateLargeTestInput();
+
+			CheckSigning("bpg");
+			CheckKeyBasedEncryption("bpg");
+			CheckLargeKeyBasedEncryption("bpg");
+
+			DsaElGamalKeyRingGenerator.Main(new string[] { "-a", "test", "password" });
+
+			CheckSigning("asc");
+			CheckKeyBasedEncryption("asc");
+			CheckLargeKeyBasedEncryption("asc");
+		}
+
+		[Test]
+		public void TestPbeEncryption() 
+		{
+			Console.Error.Flush();
+			_currentErr.SetLength(0);
+
+			PbeFileProcessor.Main(new string[] { "-e", "test.txt", "password" });
+
+			PbeFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("no message integrity check", GetLine(_currentErr));
+
+			PbeFileProcessor.Main(new string[] { "-e", "-i", "test.txt", "password" });
+
+			PbeFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+
+			PbeFileProcessor.Main(new string[] { "-e", "-ai", "test.txt", "password" });
+
+			PbeFileProcessor.Main(new string[] { "-d", "test.txt.asc", "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+		}
+
+		[Test]
+		public void TestClearSigned()
+		{
+			CreateTestFile(clearSignedPublicKey, "pub.bpg");
+
+			CheckClearSignedVerify(nlOnlySignedMessage);
+			CheckClearSignedVerify(crOnlySignedMessage);
+			CheckClearSignedVerify(crNlSignedMessage);
+			CheckClearSignedVerify(crNlSignedMessageTrailingWhiteSpace);
+
+			ClearSignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub.bpg" });
+
+			RsaKeyRingGenerator.Main(new string[] { "test", "password" });
+
+			CheckClearSigned(crOnlyMessage);
+			CheckClearSigned(nlOnlyMessage);
+			CheckClearSigned(crNlMessage);
+			CheckClearSigned(crNlMessageTrailingWhiteSpace);
+		}
+
+		[Test]
+		public void TestClearSignedBogusInput()
+		{
+			CreateTestFile(clearSignedPublicKey, "test.txt");
+
+			ClearSignedFileProcessor.Main(new String[] { "-s", "test.txt", "secret.bpg", "password" });
+		}
+
+		private void CheckClearSignedVerify(
+			string message)
+		{
+			CreateTestData(message, "test.txt.asc");
+
+			ClearSignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub.bpg" });
+		}
+
+		private void CheckClearSigned(
+			string message)
+		{
+			CreateTestData(message, "test.txt");
+
+			ClearSignedFileProcessor.Main(new string[] { "-s", "test.txt", "secret.bpg", "password" });
+			ClearSignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub.bpg" });
+		}
+
+		private void CheckSigning(
+			string type) 
+		{
+			Console.Out.Flush();
+			_currentOut.SetLength(0);
+
+			SignedFileProcessor.Main(new string[] { "-s", "test.txt", "secret." + type, "password" });
+			SignedFileProcessor.Main(new string[] { "-v", "test.txt.bpg", "pub." + type });
+
+			Console.Out.Flush();
+			Assert.AreEqual("signature verified.", GetLine(_currentOut));
+
+			SignedFileProcessor.Main(new string[] { "-s", "-a", "test.txt", "secret." + type, "password" });
+			SignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub." + type });
+
+			Console.Out.Flush();
+			Assert.AreEqual("signature verified.", GetLine(_currentOut));
+		}
+
+		private void CheckKeyBasedEncryption(
+			string type) 
+		{
+			Console.Error.Flush();
+			_currentErr.SetLength(0);
+
+			KeyBasedFileProcessor.Main(new string[] { "-e", "test.txt", "pub." + type });
+			KeyBasedFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("no message integrity check", GetLine(_currentErr));
+
+			KeyBasedFileProcessor.Main(new string[] { "-e", "-i", "test.txt", "pub." + type });
+			KeyBasedFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+
+			KeyBasedFileProcessor.Main(new string[] { "-e", "-ai", "test.txt", "pub." + type });
+			KeyBasedFileProcessor.Main(new string[] { "-d", "test.txt.asc", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+		}
+
+		private void CheckLargeKeyBasedEncryption(
+			string type) 
+		{
+			Console.Error.Flush();
+			_currentErr.SetLength(0);
+
+			KeyBasedLargeFileProcessor.Main(new string[] { "-e", "large.txt", "pub." + type });
+			KeyBasedLargeFileProcessor.Main(new string[] { "-d", "large.txt.bpg", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("no message integrity check", GetLine(_currentErr));
+
+			KeyBasedLargeFileProcessor.Main(new string[] { "-e", "-i", "large.txt", "pub." + type });
+			KeyBasedLargeFileProcessor.Main(new string[] { "-d", "large.txt.bpg", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+
+			KeyBasedLargeFileProcessor.Main(new string[] { "-e", "-ai", "large.txt", "pub." + type });
+			KeyBasedLargeFileProcessor.Main(new string[] { "-d", "large.txt.asc", "secret." + type, "password" });
+
+			Console.Error.Flush();
+			Assert.AreEqual("message integrity check passed", GetLine(_currentErr));
+		}
+
+		private void CreateSmallTestInput() 
+		{
+			TextWriter bfOut = new StreamWriter(File.Create("test.txt"));
+			bfOut.WriteLine("hello world!");
+			bfOut.Close();
+		}
+
+		private void CreateLargeTestInput() 
+		{
+			TextWriter bfOut = new StreamWriter(File.Create("large.txt"));
+
+			for (int i = 1; i <= 2000; i++)
+			{
+				bfOut.WriteLine("hello to planet " + i + "!");
+			}
+
+			bfOut.Close();
+		}
+
+		private void CreateTestData(
+			string	testData,
+			string	name)
+		{
+			TextWriter bfOut = new StreamWriter(File.Create(name));
+			bfOut.Write(testData);
+			bfOut.Close();
+		}
+
+		private void CreateTestFile(
+			byte[]	keyData,
+			string	name)
+		{
+			FileStream fOut = File.Create(name);
+			fOut.Write(keyData, 0, keyData.Length);
+			fOut.Close();
+		}
+
+		private string GetLine(
+			MemoryStream outStr) 
+		{
+			byte[] b = outStr.ToArray();
+			TextReader bRd = new StreamReader(new MemoryStream(b, false));
+			outStr.SetLength(0);
+			return bRd.ReadLine();
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			//junit.textui.TestRunner.run(suite());
+			EventListener el = new NullListener();
+			suite().Run(el);
+		}
+
+		public static TestSuite suite()
+		{
+			TestSuite suite = new TestSuite("OpenPGP Example Tests");
+
+			suite.Add(new AllTests());
+
+			return suite;
+		}
+
+	}
+}