private void ProcessSymmetricKeyDataForElGamal(IPgpPrivateKey privateKey, IBufferedCipher cipher, IList <IBigInteger> symmetricKeyData)
        {
            var k    = (ElGamalPrivateKeyParameters)privateKey.Key;
            var size = (k.Parameters.P.BitLength + 7) / 8;

            var bi = symmetricKeyData[0].ToByteArray();

            var diff = bi.Length - size;

            if (diff >= 0)
            {
                cipher.ProcessBytes(bi, diff, size);
            }
            else
            {
                var zeros = new byte[-diff];
                cipher.ProcessBytes(zeros);
                cipher.ProcessBytes(bi);
            }

            bi = symmetricKeyData[1].ToByteArray();

            diff = bi.Length - size;
            if (diff >= 0)
            {
                cipher.ProcessBytes(bi, diff, size);
            }
            else
            {
                var zeros = new byte[-diff];
                cipher.ProcessBytes(zeros);
                cipher.ProcessBytes(bi);
            }
        }
Example #2
0
        /// <summary>Initialise the generator for signing.</summary>
        public void InitSign(
            int sigType,
            IPgpPrivateKey key,
            SecureRandom random)
        {
            this.privKey       = key;
            this.signatureType = sigType;

            try
            {
                ICipherParameters cp = key.Key;
                if (random != null)
                {
                    cp = new ParametersWithRandom(key.Key, random);
                }

                sig.Init(true, cp);
            }
            catch (InvalidKeyException e)
            {
                throw new PgpException("invalid key.", e);
            }

            dig.Reset();
            lastb = 0;
        }
        private void generateTest(
            string message,
            string type)
        {
            IPgpSecretKey                  pgpSecKey  = ReadSecretKey(new MemoryStream(secretKey));
            IPgpPrivateKey                 pgpPrivKey = pgpSecKey.ExtractPrivateKey("".ToCharArray());
            PgpSignatureGenerator          sGen       = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, HashAlgorithmTag.Sha256);
            PgpSignatureSubpacketGenerator spGen      = new PgpSignatureSubpacketGenerator();

            sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey);

            IEnumerator it = pgpSecKey.PublicKey.GetUserIds().GetEnumerator();

            if (it.MoveNext())
            {
                spGen.SetSignerUserId(false, (string)it.Current);
                sGen.SetHashedSubpackets(spGen.Generate());
            }

            MemoryStream        bOut = new MemoryStream();
            ArmoredOutputStream aOut = new ArmoredOutputStream(bOut);
            MemoryStream        bIn  = new MemoryStream(Encoding.ASCII.GetBytes(message), false);

            aOut.BeginClearText(HashAlgorithmTag.Sha256);

            //
            // note the last \n m_in the file is ignored
            //
            MemoryStream lineOut   = new MemoryStream();
            int          lookAhead = ReadInputLine(lineOut, bIn);

            ProcessLine(aOut, sGen, lineOut.ToArray());

            if (lookAhead != -1)
            {
                do
                {
                    lookAhead = ReadInputLine(lineOut, lookAhead, bIn);

                    sGen.Update((byte)'\r');
                    sGen.Update((byte)'\n');

                    ProcessLine(aOut, sGen, lineOut.ToArray());
                }while (lookAhead != -1);
            }

            aOut.EndClearText();

            BcpgOutputStream bcpgOut = new BcpgOutputStream(aOut);

            sGen.Generate().Encode(bcpgOut);

            aOut.Close();

            byte[] bs = bOut.ToArray();
            messageTest(Encoding.ASCII.GetString(bs, 0, bs.Length), type);
        }
Example #4
0
        private void doTestSigV3(
            PublicKeyAlgorithmTag encAlgorithm,
            HashAlgorithmTag hashAlgorithm,
            IPgpPublicKey pubKey,
            IPgpPrivateKey privKey)
        {
            byte[] bytes = generateV3BinarySig(privKey, encAlgorithm, hashAlgorithm);

            verifySignature(bytes, hashAlgorithm, pubKey, TEST_DATA);
        }
        private byte[] ProcessSymmetricKeyDataForEcdh(IPgpPrivateKey privKey, IList <IBigInteger> symmetricKeyData)
        {
            var encSymKey    = symmetricKeyData[1].ToByteArrayUnsigned();
            var privateKey   = (ECDHPrivateKeyParameters)privKey.Key;
            var publicKey    = privateKey.PublicKeyParameters;
            var ephemeralKey = ECDHPublicKeyParameters.Create(symmetricKeyData[0], publicKey.PublicKeyParamSet, publicKey.HashAlgorithm, publicKey.SymmetricKeyAlgorithm);

            var engine = new RFC6637ECDHEngine();

            engine.InitForDecryption(privateKey, ephemeralKey);
            return(engine.ProcessBlock(encSymKey, 0, encSymKey.Length));
        }
        private byte[] FetchSymmetricKeyData(IPgpPrivateKey privKey)
        {
            byte[] plain;
            var    keyD = _keyData.GetEncSessionKey();

            if (_keyData.Algorithm == PublicKeyAlgorithmTag.Ecdh)
            {
                plain = this.ProcessSymmetricKeyDataForEcdh(privKey, keyD);
            }
            else
            {
                var c1 = GetKeyCipher(_keyData.Algorithm);
                try
                {
                    c1.Init(false, privKey.Key);
                }
                catch (InvalidKeyException e)
                {
                    throw new PgpException("error setting asymmetric cipher", e);
                }

                switch (_keyData.Algorithm)
                {
                case PublicKeyAlgorithmTag.RsaGeneral:
                case PublicKeyAlgorithmTag.RsaEncrypt:
                    this.ProcessSymmetricKeyDataForRsa(c1, keyD);
                    break;

                default:
                    this.ProcessSymmetricKeyDataForElGamal(privKey, c1, keyD);
                    break;
                }

                try
                {
                    plain = c1.DoFinal();
                }
                catch (Exception e)
                {
                    throw new PgpException("exception decrypting secret key", e);
                }
            }

            if (!ConfirmCheckSum(plain))
            {
                throw new PgpKeyValidationException("key checksum failed");
            }

            return(plain);
        }
Example #7
0
        private void doTestTextSig(
            PublicKeyAlgorithmTag encAlgorithm,
            HashAlgorithmTag hashAlgorithm,
            IPgpPublicKey pubKey,
            IPgpPrivateKey privKey,
            byte[]                                  data,
            byte[]                                  canonicalData)
        {
            PgpSignatureGenerator sGen   = new PgpSignatureGenerator(encAlgorithm, HashAlgorithmTag.Sha1);
            MemoryStream          bOut   = new MemoryStream();
            MemoryStream          testIn = new MemoryStream(data, false);
            DateTime creationTime        = DateTime.UtcNow;

            sGen.InitSign(PgpSignature.CanonicalTextDocument, privKey);
            sGen.GenerateOnePassVersion(false).Encode(bOut);

            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
            Stream lOut = lGen.Open(
                new UncloseableStream(bOut),
                PgpLiteralData.Text,
                "_CONSOLE",
                data.Length * 2,
                creationTime);

            int ch;

            while ((ch = testIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte)ch);
                sGen.Update((byte)ch);
            }

            lOut.Write(data, 0, data.Length);
            sGen.Update(data);

            lGen.Close();

            PgpSignature sig = sGen.Generate();

            if (sig.CreationTime == DateTimeUtilities.UnixMsToDateTime(0))
            {
                Fail("creation time not set in v4 signature");
            }

            sig.Encode(bOut);

            verifySignature(bOut.ToArray(), hashAlgorithm, pubKey, canonicalData);
        }
Example #8
0
        private static byte[] SignPublicKey(
            IPgpSecretKey secretKey,
            string secretKeyPass,
            IPgpPublicKey keyToBeSigned,
            string notationName,
            string notationValue,
            bool armor)
        {
            Stream os = new MemoryStream();

            if (armor)
            {
                os = new ArmoredOutputStream(os);
            }

            IPgpPrivateKey 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());
        }
Example #9
0
        private static void CreateSignature(
            string fileName,
            Stream keyIn,
            Stream outputStream,
            char[]  pass,
            bool armor)
        {
            if (armor)
            {
                outputStream = new ArmoredOutputStream(outputStream);
            }

            IPgpSecretKey         pgpSec     = PgpExampleUtilities.ReadSecretKey(keyIn);
            IPgpPrivateKey        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();
            }
        }
Example #10
0
        private void doTestSig(
            PublicKeyAlgorithmTag encAlgorithm,
            HashAlgorithmTag hashAlgorithm,
            IPgpPublicKey pubKey,
            IPgpPrivateKey privKey)
        {
            MemoryStream          bOut   = new MemoryStream();
            MemoryStream          testIn = new MemoryStream(TEST_DATA, false);
            PgpSignatureGenerator sGen   = new PgpSignatureGenerator(encAlgorithm, hashAlgorithm);

            sGen.InitSign(PgpSignature.BinaryDocument, privKey);
            sGen.GenerateOnePassVersion(false).Encode(bOut);

            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
            Stream lOut = lGen.Open(
                new UncloseableStream(bOut),
                PgpLiteralData.Binary,
                "_CONSOLE",
                TEST_DATA.Length * 2,
                DateTime.UtcNow);

            int ch;

            while ((ch = testIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte)ch);
                sGen.Update((byte)ch);
            }

            lOut.Write(TEST_DATA, 0, TEST_DATA.Length);
            sGen.Update(TEST_DATA);

            lGen.Close();

            sGen.Generate().Encode(bOut);

            verifySignature(bOut.ToArray(), hashAlgorithm, pubKey, TEST_DATA);
        }
        /**
         * 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);
            }

            IPgpSecretKey         pgpSec     = PgpExampleUtilities.ReadSecretKey(keyIn);
            IPgpPrivateKey        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();
            }
        }
        /*
         * 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;
            }

            IPgpSecretKey                  pgpSecKey  = PgpExampleUtilities.ReadSecretKey(keyIn);
            IPgpPrivateKey                 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();
        }
        /// <summary>Initialise the generator for signing.</summary>
        public void InitSign(int sigType, IPgpPrivateKey key, ISecureRandom random)
        {
            _privKey = key;
            _signatureType = sigType;

            try
            {
                ICipherParameters cp = key.Key;
                if (random != null)
                {
                    cp = new ParametersWithRandom(key.Key, random);
                }

                _sig.Init(true, cp);
            }
            catch (InvalidKeyException e)
            {
                throw new PgpException("invalid key.", e);
            }

            _dig.Reset();
            _lastb = 0;
        }
 /// <summary>Initialise the generator for signing.</summary>
 public void InitSign(int sigType, IPgpPrivateKey key)
 {
     InitSign(sigType, key, null);
 }
        public override void PerformTest()
        {
            //
            // Read the public key
            //
            PgpObjectFactory pgpFact = new PgpObjectFactory(testPubKeyRing);
            PgpPublicKeyRing pgpPub  = (PgpPublicKeyRing)pgpFact.NextPgpObject();

            var pubKey = pgpPub.GetPublicKey();

            if (pubKey.BitStrength != 1024)
            {
                Fail("failed - key strength reported incorrectly.");
            }

            //
            // Read the private key
            //
            PgpSecretKeyRing sKey       = new PgpSecretKeyRing(testPrivKeyRing);
            IPgpSecretKey    secretKey  = sKey.GetSecretKey();
            IPgpPrivateKey   pgpPrivKey = secretKey.ExtractPrivateKey(pass);

            //
            // signature generation
            //
            const string data = "hello world!";

            byte[]                dataBytes = Encoding.ASCII.GetBytes(data);
            MemoryStream          bOut      = new MemoryStream();
            MemoryStream          testIn    = new MemoryStream(dataBytes, false);
            PgpSignatureGenerator sGen      = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa,
                                                                        HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);

            PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(
                CompressionAlgorithmTag.Zip);

            BcpgOutputStream bcOut = new BcpgOutputStream(
                cGen.Open(new UncloseableStream(bOut)));

            sGen.GenerateOnePassVersion(false).Encode(bcOut);

            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();

            DateTime testDateTime = new DateTime(1973, 7, 27);
            Stream   lOut         = lGen.Open(
                new UncloseableStream(bcOut),
                PgpLiteralData.Binary,
                "_CONSOLE",
                dataBytes.Length,
                testDateTime);

            int ch;

            while ((ch = testIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte)ch);
                sGen.Update((byte)ch);
            }

            lGen.Close();

            sGen.Generate().Encode(bcOut);

            cGen.Close();

            //
            // verify Generated signature
            //
            pgpFact = new PgpObjectFactory(bOut.ToArray());

            PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject();

            pgpFact = new PgpObjectFactory(c1.GetDataStream());

            PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();

            PgpOnePassSignature ops = p1[0];

            PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject();

            if (!p2.ModificationTime.Equals(testDateTime))
            {
                Fail("Modification time not preserved");
            }

            Stream dIn = p2.GetInputStream();

            ops.InitVerify(pubKey);

            while ((ch = dIn.ReadByte()) >= 0)
            {
                ops.Update((byte)ch);
            }

            PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();

            if (!ops.Verify(p3[0]))
            {
                Fail("Failed Generated signature check");
            }

            //
            // test encryption
            //

            //
            // find a key sutiable for encryption
            //
            long pgpKeyID = 0;
            IAsymmetricKeyParameter pKey = null;

            foreach (PgpPublicKey pgpKey in pgpPub.GetPublicKeys())
            {
                if (pgpKey.Algorithm == PublicKeyAlgorithmTag.ElGamalEncrypt ||
                    pgpKey.Algorithm == PublicKeyAlgorithmTag.ElGamalGeneral)
                {
                    pKey     = pgpKey.GetKey();
                    pgpKeyID = pgpKey.KeyId;
                    if (pgpKey.BitStrength != 1024)
                    {
                        Fail("failed - key strength reported incorrectly.");
                    }

                    //
                    // verify the key
                    //
                }
            }

            IBufferedCipher c = CipherUtilities.GetCipher("ElGamal/None/PKCS1Padding");

            c.Init(true, pKey);

            byte[] inBytes  = Encoding.ASCII.GetBytes("hello world");
            byte[] outBytes = c.DoFinal(inBytes);

            pgpPrivKey = sKey.GetSecretKey(pgpKeyID).ExtractPrivateKey(pass);

            c.Init(false, pgpPrivKey.Key);

            outBytes = c.DoFinal(outBytes);

            if (!Arrays.AreEqual(inBytes, outBytes))
            {
                Fail("decryption failed.");
            }

            //
            // encrypted message
            //
            byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o',
                            (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l',(byte)'d',  (byte)'!', (byte)'\n' };

            PgpObjectFactory pgpF = new PgpObjectFactory(encMessage);

            PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject();

            PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0];

            Stream clear = encP.GetDataStream(pgpPrivKey);

            pgpFact = new PgpObjectFactory(clear);

            c1 = (PgpCompressedData)pgpFact.NextPgpObject();

            pgpFact = new PgpObjectFactory(c1.GetDataStream());

            PgpLiteralData ld = (PgpLiteralData)pgpFact.NextPgpObject();

            if (!ld.FileName.Equals("test.txt"))
            {
                throw new Exception("wrong filename in packet");
            }

            Stream inLd = ld.GetDataStream();

            byte[] bytes = Streams.ReadAll(inLd);

            if (!Arrays.AreEqual(bytes, text))
            {
                Fail("wrong plain text in decrypted packet");
            }

            //
            // signed and encrypted message
            //
            pgpF = new PgpObjectFactory(signedAndEncMessage);

            encList = (PgpEncryptedDataList)pgpF.NextPgpObject();

            encP = (PgpPublicKeyEncryptedData)encList[0];

            clear = encP.GetDataStream(pgpPrivKey);

            pgpFact = new PgpObjectFactory(clear);

            c1 = (PgpCompressedData)pgpFact.NextPgpObject();

            pgpFact = new PgpObjectFactory(c1.GetDataStream());

            p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();

            ops = p1[0];

            ld = (PgpLiteralData)pgpFact.NextPgpObject();

            bOut = new MemoryStream();

            if (!ld.FileName.Equals("test.txt"))
            {
                throw new Exception("wrong filename in packet");
            }

            inLd = ld.GetDataStream();

            //
            // note: we use the DSA public key here.
            //
            ops.InitVerify(pgpPub.GetPublicKey());

            while ((ch = inLd.ReadByte()) >= 0)
            {
                ops.Update((byte)ch);
                bOut.WriteByte((byte)ch);
            }

            p3 = (PgpSignatureList)pgpFact.NextPgpObject();

            if (!ops.Verify(p3[0]))
            {
                Fail("Failed signature check");
            }

            if (!Arrays.AreEqual(bOut.ToArray(), text))
            {
                Fail("wrong plain text in decrypted packet");
            }

            //
            // encrypt
            //
            MemoryStream cbOut            = new MemoryStream();
            PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(
                SymmetricKeyAlgorithmTag.TripleDes, random);
            IPgpPublicKey puK = sKey.GetSecretKey(pgpKeyID).PublicKey;

            cPk.AddMethod(puK);

            Stream cOut = cPk.Open(new UncloseableStream(cbOut), bOut.ToArray().Length);

            cOut.Write(text, 0, text.Length);

            cOut.Close();

            pgpF = new PgpObjectFactory(cbOut.ToArray());

            encList = (PgpEncryptedDataList)pgpF.NextPgpObject();

            encP = (PgpPublicKeyEncryptedData)encList[0];

            pgpPrivKey = sKey.GetSecretKey(pgpKeyID).ExtractPrivateKey(pass);

            clear    = encP.GetDataStream(pgpPrivKey);
            outBytes = Streams.ReadAll(clear);

            if (!Arrays.AreEqual(outBytes, text))
            {
                Fail("wrong plain text in Generated packet");
            }

            //
            // use of PgpKeyPair
            //
            IBigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16);
            IBigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);

            ElGamalParameters elParams = new ElGamalParameters(p, g);

            IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL");

            kpg.Init(new ElGamalKeyGenerationParameters(random, elParams));

            IAsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();

            PgpKeyPair pgpKp = new PgpKeyPair(PublicKeyAlgorithmTag.ElGamalGeneral,
                                              kp.Public, kp.Private, DateTime.UtcNow);

            PgpPublicKey  k1 = pgpKp.PublicKey;
            PgpPrivateKey k2 = pgpKp.PrivateKey;



            // Test bug with ElGamal P size != 0 mod 8 (don't use these sizes at home!)
            for (int pSize = 257; pSize < 264; ++pSize)
            {
                // Generate some parameters of the given size
                ElGamalParametersGenerator epg = new ElGamalParametersGenerator();
                epg.Init(pSize, 2, random);

                elParams = epg.GenerateParameters();

                kpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL");
                kpg.Init(new ElGamalKeyGenerationParameters(random, elParams));


                // Run a short encrypt/decrypt test with random key for the given parameters
                kp = kpg.GenerateKeyPair();

                PgpKeyPair elGamalKeyPair = new PgpKeyPair(
                    PublicKeyAlgorithmTag.ElGamalGeneral, kp, DateTime.UtcNow);

                cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, random);

                puK = elGamalKeyPair.PublicKey;

                cPk.AddMethod(puK);

                cbOut = new MemoryStream();

                cOut = cPk.Open(new UncloseableStream(cbOut), text.Length);

                cOut.Write(text, 0, text.Length);

                cOut.Close();

                pgpF = new PgpObjectFactory(cbOut.ToArray());

                encList = (PgpEncryptedDataList)pgpF.NextPgpObject();

                encP = (PgpPublicKeyEncryptedData)encList[0];

                pgpPrivKey = elGamalKeyPair.PrivateKey;

                // Note: This is where an exception would be expected if the P size causes problems
                clear = encP.GetDataStream(pgpPrivKey);
                byte[] decText = Streams.ReadAll(clear);

                if (!Arrays.AreEqual(text, decText))
                {
                    Fail("decrypted message incorrect");
                }
            }


            // check sub key encoding

            foreach (PgpPublicKey pgpKey in pgpPub.GetPublicKeys())
            {
                if (!pgpKey.IsMasterKey)
                {
                    byte[] kEnc = pgpKey.GetEncoded();

                    PgpObjectFactory objF = new PgpObjectFactory(kEnc);

                    // TODO Make PgpPublicKey a PgpObject or return a PgpPublicKeyRing
//					PgpPublicKey k = (PgpPublicKey)objF.NextPgpObject();
//
//					pKey = k.GetKey();
//					pgpKeyID = k.KeyId;
//					if (k.BitStrength != 1024)
//					{
//						Fail("failed - key strength reported incorrectly.");
//					}
//
//					if (objF.NextPgpObject() != null)
//					{
//						Fail("failed - stream not fully parsed.");
//					}
                }
            }
        }
        /**
         * Generated signature test
         *
         * @param sKey
         * @param pgpPrivKey
         * @return test result
         */
        public void GenerateTest(
            PgpSecretKeyRing sKey,
            IPgpPublicKey pgpPubKey,
            IPgpPrivateKey pgpPrivKey)
        {
            string       data = "hello world!";
            MemoryStream bOut = new MemoryStream();

            byte[]       dataBytes = Encoding.ASCII.GetBytes(data);
            MemoryStream testIn    = new MemoryStream(dataBytes, false);

            PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);

            PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();

            IEnumerator enumerator = sKey.GetSecretKey().PublicKey.GetUserIds().GetEnumerator();

            enumerator.MoveNext();
            string primaryUserId = (string)enumerator.Current;

            spGen.SetSignerUserId(true, primaryUserId);

            sGen.SetHashedSubpackets(spGen.Generate());

            PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(
                CompressionAlgorithmTag.Zip);

            BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut)));

            sGen.GenerateOnePassVersion(false).Encode(bcOut);

            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();

            DateTime testDateTime = new DateTime(1973, 7, 27);
            Stream   lOut         = lGen.Open(
                new UncloseableStream(bcOut),
                PgpLiteralData.Binary,
                "_CONSOLE",
                dataBytes.Length,
                testDateTime);

            int ch;

            while ((ch = testIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte)ch);
                sGen.Update((byte)ch);
            }

            lGen.Close();

            sGen.Generate().Encode(bcOut);

            cGen.Close();

            PgpObjectFactory  pgpFact = new PgpObjectFactory(bOut.ToArray());
            PgpCompressedData c1      = (PgpCompressedData)pgpFact.NextPgpObject();

            pgpFact = new PgpObjectFactory(c1.GetDataStream());

            PgpOnePassSignatureList p1  = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
            PgpOnePassSignature     ops = p1[0];

            PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject();

            if (!p2.ModificationTime.Equals(testDateTime))
            {
                Fail("Modification time not preserved");
            }

            Stream dIn = p2.GetInputStream();

            ops.InitVerify(pgpPubKey);

            while ((ch = dIn.ReadByte()) >= 0)
            {
                ops.Update((byte)ch);
            }

            PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();

            if (!ops.Verify(p3[0]))
            {
                Fail("Failed generated signature check");
            }
        }
        private byte[] FetchSymmetricKeyData(IPgpPrivateKey privKey)
        {
            byte[] plain;
            var keyD = _keyData.GetEncSessionKey();
            if (_keyData.Algorithm == PublicKeyAlgorithmTag.Ecdh)
            {
                plain = this.ProcessSymmetricKeyDataForEcdh(privKey, keyD);
            }
            else
            {
                var c1 = GetKeyCipher(_keyData.Algorithm);
                try
                {
                    c1.Init(false, privKey.Key);
                }
                catch (InvalidKeyException e)
                {
                    throw new PgpException("error setting asymmetric cipher", e);
                }

                switch (_keyData.Algorithm)
                {
                    case PublicKeyAlgorithmTag.RsaGeneral:
                    case PublicKeyAlgorithmTag.RsaEncrypt:
                        this.ProcessSymmetricKeyDataForRsa(c1, keyD);
                        break;
                    default:
                        this.ProcessSymmetricKeyDataForElGamal(privKey, c1, keyD);
                        break;
                }

                try
                {
                    plain = c1.DoFinal();
                }
                catch (Exception e)
                {
                    throw new PgpException("exception decrypting secret key", e);
                }
            }

            if (!ConfirmCheckSum(plain))
                throw new PgpKeyValidationException("key checksum failed");

            return plain;
        }
        /// <summary>
        /// Return the algorithm code for the symmetric algorithm used to encrypt the data.
        /// </summary>
        /// <param name="privKey">The priv key.</param>
        /// <returns></returns>
        public SymmetricKeyAlgorithmTag GetSymmetricAlgorithm(IPgpPrivateKey privKey)
        {
            var plain = FetchSymmetricKeyData(privKey);

            return((SymmetricKeyAlgorithmTag)plain[0]);
        }
        private void ProcessSymmetricKeyDataForElGamal(IPgpPrivateKey privateKey, IBufferedCipher cipher, IList<IBigInteger> symmetricKeyData)
        {
            var k = (ElGamalPrivateKeyParameters)privateKey.Key;
            var size = (k.Parameters.P.BitLength + 7) / 8;

            var bi = symmetricKeyData[0].ToByteArray();

            var diff = bi.Length - size;
            if (diff >= 0)
            {
                cipher.ProcessBytes(bi, diff, size);
            }
            else
            {
                var zeros = new byte[-diff];
                cipher.ProcessBytes(zeros);
                cipher.ProcessBytes(bi);
            }

            bi = symmetricKeyData[1].ToByteArray();

            diff = bi.Length - size;
            if (diff >= 0)
            {
                cipher.ProcessBytes(bi, diff, size);
            }
            else
            {
                var zeros = new byte[-diff];
                cipher.ProcessBytes(zeros);
                cipher.ProcessBytes(bi);
            }
        }
 /// <summary>
 /// Return the decrypted data stream for the packet.
 /// </summary>
 /// <param name="privKey">The priv key.</param>
 /// <returns></returns>
 /// <exception cref="PgpException">
 /// exception creating cipher
 /// or
 /// Exception starting decryption
 /// </exception>
 /// <exception cref="System.IO.EndOfStreamException">
 /// unexpected end of stream.
 /// or
 /// unexpected end of stream.
 /// </exception>
 public Stream GetDataStream(IPgpPrivateKey privKey)
 {
     SymmetricKeyAlgorithmTag encryptionAlgorithm;
     return this.GetDataStream(privKey, out encryptionAlgorithm);
 }
Example #21
0
        /**
         * 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
                //
                IPgpPrivateKey            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);
                }
            }
        }
        /// <summary>
        /// Gets the data stream.
        /// </summary>
        /// <param name="privKey">The priv key.</param>
        /// <param name="encryptionAlgorithm">The encryption algorithm.</param>
        /// <returns></returns>
        /// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException">
        /// exception creating cipher
        /// or
        /// Exception starting decryption
        /// </exception>
        /// <exception cref="System.IO.EndOfStreamException">
        /// unexpected end of stream.
        /// or
        /// unexpected end of stream.
        /// </exception>
        public Stream GetDataStream(IPgpPrivateKey privKey, out SymmetricKeyAlgorithmTag encryptionAlgorithm)
        {
            var plain = this.FetchSymmetricKeyData(privKey);

            encryptionAlgorithm = (SymmetricKeyAlgorithmTag)plain[0];

            IBufferedCipher c2;
            var             cipherName = PgpUtilities.GetSymmetricCipherName(encryptionAlgorithm);
            var             cName      = cipherName;

            try
            {
                if (EncData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c2 = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c2 == null)
            {
                return(EncData.GetInputStream());
            }

            try
            {
                var key = ParameterUtilities.CreateKeyParameter(cipherName, plain, 1, plain.Length - 3);
                var iv  = new byte[c2.GetBlockSize()];

                c2.Init(false, new ParametersWithIV(key, iv));

                this.EncStream = BcpgInputStream.Wrap(new CipherStream(EncData.GetInputStream(), c2, null));
                if (this.EncData is SymmetricEncIntegrityPacket)
                {
                    this.TruncStream = new TruncatedStream(this.EncStream);

                    var digest = DigestUtilities.GetDigest(PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1));
                    EncStream = new DigestStream(TruncStream, digest, null);
                }

                if (Streams.ReadFully(EncStream, iv, 0, iv.Length) < iv.Length)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                var v1 = this.EncStream.ReadByte();
                var v2 = this.EncStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                // Note: the oracle attack on the "quick check" bytes is deemed
                // a security risk for typical public key encryption usages,
                // therefore we do not perform the check.

                //				bool repeatCheckPassed =
                //					iv[iv.Length - 2] == (byte)v1
                //					&&	iv[iv.Length - 1] == (byte)v2;
                //
                //				// Note: some versions of PGP appear to produce 0 for the extra
                //				// bytes rather than repeating the two previous bytes
                //				bool zeroesCheckPassed =
                //					v1 == 0
                //					&&	v2 == 0;
                //
                //				if (!repeatCheckPassed && !zeroesCheckPassed)
                //				{
                //					throw new PgpDataValidationException("quick check failed.");
                //				}

                return(this.EncStream);
            }
            catch (PgpException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
        }
        /// <summary>
        /// Return the decrypted data stream for the packet.
        /// </summary>
        /// <param name="privKey">The priv key.</param>
        /// <returns></returns>
        /// <exception cref="PgpException">
        /// exception creating cipher
        /// or
        /// Exception starting decryption
        /// </exception>
        /// <exception cref="System.IO.EndOfStreamException">
        /// unexpected end of stream.
        /// or
        /// unexpected end of stream.
        /// </exception>
        public Stream GetDataStream(IPgpPrivateKey privKey)
        {
            SymmetricKeyAlgorithmTag encryptionAlgorithm;

            return(this.GetDataStream(privKey, out encryptionAlgorithm));
        }
        private void doTestTextSigV3(
			PublicKeyAlgorithmTag	encAlgorithm,
			HashAlgorithmTag		hashAlgorithm,
			IPgpPublicKey			pubKey,
			IPgpPrivateKey			privKey,
			byte[]					data,
			byte[]					canonicalData)
        {
            PgpV3SignatureGenerator sGen = new PgpV3SignatureGenerator(encAlgorithm, HashAlgorithmTag.Sha1);
            MemoryStream bOut = new MemoryStream();
            MemoryStream testIn = new MemoryStream(data, false);

            sGen.InitSign(PgpSignature.CanonicalTextDocument, privKey);
            sGen.GenerateOnePassVersion(false).Encode(bOut);

            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
            Stream lOut = lGen.Open(
                new UncloseableStream(bOut),
                PgpLiteralData.Text,
                "_CONSOLE",
                data.Length * 2,
                DateTime.UtcNow);

            int ch;
            while ((ch = testIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte)ch);
                sGen.Update((byte)ch);
            }

            lOut.Write(data, 0, data.Length);
            sGen.Update(data);

            lGen.Close();

            PgpSignature sig = sGen.Generate();

            if (sig.CreationTime == DateTimeUtilities.UnixMsToDateTime(0))
            {
                Fail("creation time not set in v3 signature");
            }

            sig.Encode(bOut);

            verifySignature(bOut.ToArray(), hashAlgorithm, pubKey, canonicalData);
        }
        private byte[] ProcessSymmetricKeyDataForEcdh(IPgpPrivateKey privKey, IList<IBigInteger> symmetricKeyData)
        {
            var encSymKey = symmetricKeyData[1].ToByteArrayUnsigned();
            var privateKey = (ECDHPrivateKeyParameters)privKey.Key;
            var publicKey = privateKey.PublicKeyParameters;
            var ephemeralKey = ECDHPublicKeyParameters.Create(symmetricKeyData[0], publicKey.PublicKeyParamSet, publicKey.HashAlgorithm, publicKey.SymmetricKeyAlgorithm);

            var engine = new RFC6637ECDHEngine();
            engine.InitForDecryption(privateKey, ephemeralKey);
            return engine.ProcessBlock(encSymKey, 0, encSymKey.Length);
        }
        /// <summary>
        /// Return the algorithm code for the symmetric algorithm used to encrypt the data.
        /// </summary>
        /// <param name="privKey">The priv key.</param>
        /// <returns></returns>
        public SymmetricKeyAlgorithmTag GetSymmetricAlgorithm(IPgpPrivateKey privKey)
        {
            var plain = FetchSymmetricKeyData(privKey);

            return (SymmetricKeyAlgorithmTag)plain[0];
        }
Example #27
0
        public override void PerformTest()
        {
            //
            // RSA tests
            //
            PgpSecretKeyRing pgpPriv    = new PgpSecretKeyRing(rsaKeyRing);
            IPgpSecretKey    secretKey  = pgpPriv.GetSecretKey();
            IPgpPrivateKey   pgpPrivKey = secretKey.ExtractPrivateKey(rsaPass);

            try
            {
                doTestSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);

                Fail("RSA wrong key test failed.");
            }
            catch (PgpException)
            {
                // expected
            }

            try
            {
                doTestSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);

                Fail("RSA V3 wrong key test failed.");
            }
            catch (PgpException)
            {
                // expected
            }

            //
            // certifications
            //
            PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.KeyRevocation, pgpPrivKey);

            PgpSignature sig = sGen.GenerateCertification(secretKey.PublicKey);

            sig.InitVerify(secretKey.PublicKey);

            if (!sig.VerifyCertification(secretKey.PublicKey))
            {
                Fail("revocation verification failed.");
            }

            PgpSecretKeyRing pgpDSAPriv    = new PgpSecretKeyRing(dsaKeyRing);
            IPgpSecretKey    secretDSAKey  = pgpDSAPriv.GetSecretKey();
            IPgpPrivateKey   pgpPrivDSAKey = secretDSAKey.ExtractPrivateKey(dsaPass);

            sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.SubkeyBinding, pgpPrivDSAKey);

            PgpSignatureSubpacketGenerator unhashedGen = new PgpSignatureSubpacketGenerator();
            PgpSignatureSubpacketGenerator hashedGen   = new PgpSignatureSubpacketGenerator();

            hashedGen.SetSignatureExpirationTime(false, TEST_EXPIRATION_TIME);
            hashedGen.SetSignerUserId(true, TEST_USER_ID);
            hashedGen.SetPreferredCompressionAlgorithms(false, PREFERRED_COMPRESSION_ALGORITHMS);
            hashedGen.SetPreferredHashAlgorithms(false, PREFERRED_HASH_ALGORITHMS);
            hashedGen.SetPreferredSymmetricAlgorithms(false, PREFERRED_SYMMETRIC_ALGORITHMS);

            sGen.SetHashedSubpackets(hashedGen.Generate());
            sGen.SetUnhashedSubpackets(unhashedGen.Generate());

            sig = sGen.GenerateCertification(secretDSAKey.PublicKey, secretKey.PublicKey);

            byte[] sigBytes = sig.GetEncoded();

            PgpObjectFactory f = new PgpObjectFactory(sigBytes);

            sig = ((PgpSignatureList)f.NextPgpObject())[0];

            sig.InitVerify(secretDSAKey.PublicKey);

            if (!sig.VerifyCertification(secretDSAKey.PublicKey, secretKey.PublicKey))
            {
                Fail("subkey binding verification failed.");
            }

            var hashedPcks   = sig.GetHashedSubPackets();
            var unhashedPcks = sig.GetUnhashedSubPackets();

            if (hashedPcks.Count != 6)
            {
                Fail("wrong number of hashed packets found.");
            }

            if (unhashedPcks.Count != 1)
            {
                Fail("wrong number of unhashed packets found.");
            }

            if (!hashedPcks.GetSignerUserId().Equals(TEST_USER_ID))
            {
                Fail("test userid not matching");
            }

            if (hashedPcks.GetSignatureExpirationTime() != TEST_EXPIRATION_TIME)
            {
                Fail("test signature expiration time not matching");
            }

            if (unhashedPcks.GetIssuerKeyId() != secretDSAKey.KeyId)
            {
                Fail("wrong issuer key ID found in certification");
            }

            int[] prefAlgs = hashedPcks.GetPreferredCompressionAlgorithms();
            preferredAlgorithmCheck("compression", PREFERRED_COMPRESSION_ALGORITHMS, prefAlgs);

            prefAlgs = hashedPcks.GetPreferredHashAlgorithms();
            preferredAlgorithmCheck("hash", PREFERRED_HASH_ALGORITHMS, prefAlgs);

            prefAlgs = hashedPcks.GetPreferredSymmetricAlgorithms();
            preferredAlgorithmCheck("symmetric", PREFERRED_SYMMETRIC_ALGORITHMS, prefAlgs);

            SignatureSubpacketTag[] criticalHashed = hashedPcks.GetCriticalTags();

            if (criticalHashed.Length != 1)
            {
                Fail("wrong number of critical packets found.");
            }

            if (criticalHashed[0] != SignatureSubpacketTag.SignerUserId)
            {
                Fail("wrong critical packet found in tag list.");
            }

            //
            // no packets passed
            //
            sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.SubkeyBinding, pgpPrivDSAKey);

            sGen.SetHashedSubpackets(null);
            sGen.SetUnhashedSubpackets(null);

            sig = sGen.GenerateCertification(TEST_USER_ID, secretKey.PublicKey);

            sig.InitVerify(secretDSAKey.PublicKey);

            if (!sig.VerifyCertification(TEST_USER_ID, secretKey.PublicKey))
            {
                Fail("subkey binding verification failed.");
            }

            hashedPcks = sig.GetHashedSubPackets();

            if (hashedPcks.Count != 1)
            {
                Fail("found wrong number of hashed packets");
            }

            unhashedPcks = sig.GetUnhashedSubPackets();

            if (unhashedPcks.Count != 1)
            {
                Fail("found wrong number of unhashed packets");
            }

            try
            {
                sig.VerifyCertification(secretKey.PublicKey);

                Fail("failed to detect non-key signature.");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            //
            // override hash packets
            //
            sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.SubkeyBinding, pgpPrivDSAKey);

            hashedGen = new PgpSignatureSubpacketGenerator();

            DateTime creationTime = new DateTime(1973, 7, 27);

            hashedGen.SetSignatureCreationTime(false, creationTime);

            sGen.SetHashedSubpackets(hashedGen.Generate());

            sGen.SetUnhashedSubpackets(null);

            sig = sGen.GenerateCertification(TEST_USER_ID, secretKey.PublicKey);

            sig.InitVerify(secretDSAKey.PublicKey);

            if (!sig.VerifyCertification(TEST_USER_ID, secretKey.PublicKey))
            {
                Fail("subkey binding verification failed.");
            }

            hashedPcks = sig.GetHashedSubPackets();

            if (hashedPcks.Count != 1)
            {
                Fail("found wrong number of hashed packets in override test");
            }

            if (!hashedPcks.HasSubpacket(SignatureSubpacketTag.CreationTime))
            {
                Fail("hasSubpacket test for creation time failed");
            }

            DateTime sigCreationTime = hashedPcks.GetSignatureCreationTime();

            if (!sigCreationTime.Equals(creationTime))
            {
                Fail("creation of overridden date failed.");
            }

            prefAlgs = hashedPcks.GetPreferredCompressionAlgorithms();
            preferredAlgorithmCheck("compression", NO_PREFERENCES, prefAlgs);

            prefAlgs = hashedPcks.GetPreferredHashAlgorithms();
            preferredAlgorithmCheck("hash", NO_PREFERENCES, prefAlgs);

            prefAlgs = hashedPcks.GetPreferredSymmetricAlgorithms();
            preferredAlgorithmCheck("symmetric", NO_PREFERENCES, prefAlgs);

            if (hashedPcks.GetKeyExpirationTime() != 0)
            {
                Fail("unexpected key expiration time found");
            }

            if (hashedPcks.GetSignatureExpirationTime() != 0)
            {
                Fail("unexpected signature expiration time found");
            }

            if (hashedPcks.GetSignerUserId() != null)
            {
                Fail("unexpected signer user ID found");
            }

            criticalHashed = hashedPcks.GetCriticalTags();

            if (criticalHashed.Length != 0)
            {
                Fail("critical packets found when none expected");
            }

            unhashedPcks = sig.GetUnhashedSubPackets();

            if (unhashedPcks.Count != 1)
            {
                Fail("found wrong number of unhashed packets in override test");
            }

            //
            // general signatures
            //
            doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha256, secretKey.PublicKey, pgpPrivKey);
            doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha384, secretKey.PublicKey, pgpPrivKey);
            doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha512, secretKey.PublicKey, pgpPrivKey);
            doTestSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);
            doTestTextSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
            doTestTextSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);
            doTestTextSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
            doTestTextSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);

            //
            // DSA Tests
            //
            pgpPriv    = new PgpSecretKeyRing(dsaKeyRing);
            secretKey  = pgpPriv.GetSecretKey();
            pgpPrivKey = secretKey.ExtractPrivateKey(dsaPass);

            try
            {
                doTestSig(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);

                Fail("DSA wrong key test failed.");
            }
            catch (PgpException)
            {
                // expected
            }

            try
            {
                doTestSigV3(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);

                Fail("DSA V3 wrong key test failed.");
            }
            catch (PgpException)
            {
                // expected
            }

            doTestSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);
            doTestSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey);
            doTestTextSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
            doTestTextSig(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);
            doTestTextSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
            doTestTextSigV3(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1, secretKey.PublicKey, pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);

            // special cases
            //
            doTestMissingSubpackets(nullPacketsSubKeyBinding);

            doTestMissingSubpackets(generateV3BinarySig(pgpPrivKey, PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1));

            // keyflags
            doTestKeyFlagsValues();
        }
        /**
        * Generated signature test
        *
        * @param sKey
        * @param pgpPrivKey
        * @return test result
        */
        public void GenerateTest(
            PgpSecretKeyRing sKey,
            IPgpPublicKey     pgpPubKey,
            IPgpPrivateKey    pgpPrivKey)
        {
            string data = "hello world!";
            MemoryStream bOut = new MemoryStream();

            byte[] dataBytes = Encoding.ASCII.GetBytes(data);
            MemoryStream testIn = new MemoryStream(dataBytes, false);

            PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);

            PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();

            IEnumerator enumerator = sKey.GetSecretKey().PublicKey.GetUserIds().GetEnumerator();
            enumerator.MoveNext();
            string primaryUserId = (string) enumerator.Current;

            spGen.SetSignerUserId(true, primaryUserId);

            sGen.SetHashedSubpackets(spGen.Generate());

            PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(
                CompressionAlgorithmTag.Zip);

            BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut)));

            sGen.GenerateOnePassVersion(false).Encode(bcOut);

            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();

            DateTime testDateTime = new DateTime(1973, 7, 27);
            Stream lOut = lGen.Open(
                new UncloseableStream(bcOut),
                PgpLiteralData.Binary,
                "_CONSOLE",
                dataBytes.Length,
                testDateTime);

            int ch;
            while ((ch = testIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte) ch);
                sGen.Update((byte)ch);
            }

            lGen.Close();

            sGen.Generate().Encode(bcOut);

            cGen.Close();

            PgpObjectFactory pgpFact = new PgpObjectFactory(bOut.ToArray());
            PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject();

            pgpFact = new PgpObjectFactory(c1.GetDataStream());

            PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();
            PgpOnePassSignature ops = p1[0];

            PgpLiteralData p2 = (PgpLiteralData) pgpFact.NextPgpObject();
            if (!p2.ModificationTime.Equals(testDateTime))
            {
                Fail("Modification time not preserved");
            }

            Stream dIn = p2.GetInputStream();

            ops.InitVerify(pgpPubKey);

            while ((ch = dIn.ReadByte()) >= 0)
            {
                ops.Update((byte) ch);
            }

            PgpSignatureList p3 = (PgpSignatureList) pgpFact.NextPgpObject();

            if (!ops.Verify(p3[0]))
            {
                Fail("Failed generated signature check");
            }
        }
        public override void PerformTest()
        {
            //
            // Read the public key
            //
            PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey);

            var pubKey = pgpPub.GetPublicKey();

            //
            // Read the private key
            //
            PgpSecretKeyRing sKey       = new PgpSecretKeyRing(testPrivKey);
            IPgpSecretKey    secretKey  = sKey.GetSecretKey();
            IPgpPrivateKey   pgpPrivKey = secretKey.ExtractPrivateKey(pass);

            //
            // test signature message
            //
            PgpObjectFactory  pgpFact = new PgpObjectFactory(sig1);
            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();

            ops.InitVerify(pubKey);

            int ch;

            while ((ch = dIn.ReadByte()) >= 0)
            {
                ops.Update((byte)ch);
            }

            PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();

            if (!ops.Verify(p3[0]))
            {
                Fail("Failed signature check");
            }

            //
            // signature generation
            //
            GenerateTest(sKey, pubKey, pgpPrivKey);

            //
            // signature generation - canonical text
            //
            const string data = "hello world!";

            byte[]                dataBytes = Encoding.ASCII.GetBytes(data);
            MemoryStream          bOut      = new MemoryStream();
            MemoryStream          testIn    = new MemoryStream(dataBytes, false);
            PgpSignatureGenerator sGen      = new PgpSignatureGenerator(
                PublicKeyAlgorithmTag.Dsa, HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey);

            PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(
                CompressionAlgorithmTag.Zip);

            BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut)));

            sGen.GenerateOnePassVersion(false).Encode(bcOut);

            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
            DateTime testDateTime        = new DateTime(1973, 7, 27);
            Stream   lOut = lGen.Open(
                new UncloseableStream(bcOut),
                PgpLiteralData.Text,
                "_CONSOLE",
                dataBytes.Length,
                testDateTime);

            while ((ch = testIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte)ch);
                sGen.Update((byte)ch);
            }

            lGen.Close();

            sGen.Generate().Encode(bcOut);

            cGen.Close();

            //
            // verify Generated signature - canconical text
            //
            pgpFact = new PgpObjectFactory(bOut.ToArray());

            c1 = (PgpCompressedData)pgpFact.NextPgpObject();

            pgpFact = new PgpObjectFactory(c1.GetDataStream());

            p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();

            ops = p1[0];

            p2 = (PgpLiteralData)pgpFact.NextPgpObject();
            if (!p2.ModificationTime.Equals(testDateTime))
            {
                Fail("Modification time not preserved");
            }

            dIn = p2.GetInputStream();

            ops.InitVerify(pubKey);

            while ((ch = dIn.ReadByte()) >= 0)
            {
                ops.Update((byte)ch);
            }

            p3 = (PgpSignatureList)pgpFact.NextPgpObject();

            if (!ops.Verify(p3[0]))
            {
                Fail("Failed generated signature check");
            }

            //
            // Read the public key with user attributes
            //
            pgpPub = new PgpPublicKeyRing(testPubWithUserAttr);

            pubKey = pgpPub.GetPublicKey();

            int count = 0;

            foreach (PgpUserAttributeSubpacketVector attributes in pubKey.GetUserAttributes())
            {
                int sigCount = 0;
                foreach (object sigs in pubKey.GetSignaturesForUserAttribute(attributes))
                {
                    if (sigs == null)
                    {
                        Fail("null signature found");
                    }

                    sigCount++;
                }

                if (sigCount != 1)
                {
                    Fail("Failed user attributes signature check");
                }

                count++;
            }

            if (count != 1)
            {
                Fail("Failed user attributes check");
            }

            byte[] pgpPubBytes = pgpPub.GetEncoded();
            pgpPub = new PgpPublicKeyRing(pgpPubBytes);
            pubKey = pgpPub.GetPublicKey();
            count  = 0;

            foreach (object ua in pubKey.GetUserAttributes())
            {
                if (ua == null)
                {
                    Fail("null user attribute found");
                }

                count++;
            }

            if (count != 1)
            {
                Fail("Failed user attributes reread");
            }

            //
            // reading test extra data - key with edge condition for DSA key password.
            //
            char[] passPhrase = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

            sKey       = new PgpSecretKeyRing(testPrivKey2);
            pgpPrivKey = sKey.GetSecretKey().ExtractPrivateKey(passPhrase);

            //
            // reading test - aes256 encrypted passphrase.
            //
            sKey       = new PgpSecretKeyRing(aesSecretKey);
            pgpPrivKey = sKey.GetSecretKey().ExtractPrivateKey(pass);

            //
            // reading test - twofish encrypted passphrase.
            //
            sKey       = new PgpSecretKeyRing(twofishSecretKey);
            pgpPrivKey = sKey.GetSecretKey().ExtractPrivateKey(pass);

            //
            // use of PgpKeyPair
            //
            DsaParametersGenerator pGen = new DsaParametersGenerator();

            pGen.Init(512, 80, new SecureRandom()); // TODO Is the certainty okay?
            DsaParameters dsaParams = pGen.GenerateParameters();
            DsaKeyGenerationParameters        kgp = new DsaKeyGenerationParameters(new SecureRandom(), dsaParams);
            IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("DSA");

            kpg.Init(kgp);


            IAsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();

            PgpKeyPair pgpKp = new PgpKeyPair(PublicKeyAlgorithmTag.Dsa,
                                              kp.Public, kp.Private, DateTime.UtcNow);

            PgpPublicKey  k1 = pgpKp.PublicKey;
            PgpPrivateKey k2 = pgpKp.PrivateKey;
        }
 /// <summary>Initialise the generator for signing.</summary>
 public void InitSign(int sigType, IPgpPrivateKey key)
 {
     InitSign(sigType, key, null);
 }
        private void doTestSigV3(
			PublicKeyAlgorithmTag	encAlgorithm,
			HashAlgorithmTag		hashAlgorithm,
			IPgpPublicKey			pubKey,
			IPgpPrivateKey			privKey)
        {
            byte[] bytes = generateV3BinarySig(privKey, encAlgorithm, hashAlgorithm);

            verifySignature(bytes, hashAlgorithm, pubKey, TEST_DATA);
        }
        /// <summary>
        /// Gets the data stream.
        /// </summary>
        /// <param name="privKey">The priv key.</param>
        /// <param name="encryptionAlgorithm">The encryption algorithm.</param>
        /// <returns></returns>
        /// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException">
        /// exception creating cipher
        /// or
        /// Exception starting decryption
        /// </exception>
        /// <exception cref="System.IO.EndOfStreamException">
        /// unexpected end of stream.
        /// or
        /// unexpected end of stream.
        /// </exception>
        public Stream GetDataStream(IPgpPrivateKey privKey, out SymmetricKeyAlgorithmTag encryptionAlgorithm)
        {
            var plain = this.FetchSymmetricKeyData(privKey);

            encryptionAlgorithm = (SymmetricKeyAlgorithmTag)plain[0];

            IBufferedCipher c2;
            var cipherName = PgpUtilities.GetSymmetricCipherName(encryptionAlgorithm);
            var cName = cipherName;

            try
            {
                if (EncData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c2 = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c2 == null)
                return EncData.GetInputStream();

            try
            {
                var key = ParameterUtilities.CreateKeyParameter(cipherName, plain, 1, plain.Length - 3);
                var iv = new byte[c2.GetBlockSize()];

                c2.Init(false, new ParametersWithIV(key, iv));

                this.EncStream = BcpgInputStream.Wrap(new CipherStream(EncData.GetInputStream(), c2, null));
                if (this.EncData is SymmetricEncIntegrityPacket)
                {
                    this.TruncStream = new TruncatedStream(this.EncStream);

                    var digest = DigestUtilities.GetDigest(PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1));
                    EncStream = new DigestStream(TruncStream, digest, null);
                }

                if (Streams.ReadFully(EncStream, iv, 0, iv.Length) < iv.Length)
                    throw new EndOfStreamException("unexpected end of stream.");

                var v1 = this.EncStream.ReadByte();
                var v2 = this.EncStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                    throw new EndOfStreamException("unexpected end of stream.");

                // Note: the oracle attack on the "quick check" bytes is deemed
                // a security risk for typical public key encryption usages,
                // therefore we do not perform the check.

                //				bool repeatCheckPassed =
                //					iv[iv.Length - 2] == (byte)v1
                //					&&	iv[iv.Length - 1] == (byte)v2;
                //
                //				// Note: some versions of PGP appear to produce 0 for the extra
                //				// bytes rather than repeating the two previous bytes
                //				bool zeroesCheckPassed =
                //					v1 == 0
                //					&&	v2 == 0;
                //
                //				if (!repeatCheckPassed && !zeroesCheckPassed)
                //				{
                //					throw new PgpDataValidationException("quick check failed.");
                //				}

                return this.EncStream;
            }
            catch (PgpException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
        }
        private byte[] generateV3BinarySig(
			IPgpPrivateKey			privKey,
			PublicKeyAlgorithmTag	encAlgorithm,
			HashAlgorithmTag		hashAlgorithm)
        {
            MemoryStream bOut = new MemoryStream();
            MemoryStream testIn = new MemoryStream(TEST_DATA, false);
            PgpV3SignatureGenerator sGen = new PgpV3SignatureGenerator(encAlgorithm, hashAlgorithm);

            sGen.InitSign(PgpSignature.BinaryDocument, privKey);
            sGen.GenerateOnePassVersion(false).Encode(bOut);

            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
            Stream lOut = lGen.Open(
                new UncloseableStream(bOut),
                PgpLiteralData.Binary,
                "_CONSOLE",
                TEST_DATA.Length * 2,
                DateTime.UtcNow);

            int ch;
            while ((ch = testIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte)ch);
                sGen.Update((byte)ch);
            }

            lOut.Write(TEST_DATA, 0, TEST_DATA.Length);
            sGen.Update(TEST_DATA);

            lGen.Close();

            sGen.Generate().Encode(bOut);

            return bOut.ToArray();
        }
        private void PerformTestSig(
            HashAlgorithmTag	hashAlgorithm,
            IPgpPublicKey		pubKey,
            IPgpPrivateKey		privKey)
        {
            const string data = "hello world!";
            byte[] dataBytes = Encoding.ASCII.GetBytes(data);

            MemoryStream bOut = new UncloseableMemoryStream();
            MemoryStream testIn = new MemoryStream(dataBytes, false);
            PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, hashAlgorithm);

            sGen.InitSign(PgpSignature.BinaryDocument, privKey);

            PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);

            BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut)));

            sGen.GenerateOnePassVersion(false).Encode(bcOut);

            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
            DateTime testDateTime = new DateTime(1973, 7, 27);
            Stream lOut = lGen.Open(
                new UncloseableStream(bcOut),
                PgpLiteralData.Binary,
                "_CONSOLE",
                dataBytes.Length,
                testDateTime);

            // TODO Need a stream object to automatically call Update?
            // (via ISigner implementation of PgpSignatureGenerator)
            int ch;
            while ((ch = testIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte)ch);
                sGen.Update((byte)ch);
            }

            lOut.Close();

            sGen.Generate().Encode(bcOut);

            bcOut.Close();

            //
            // verify generated signature
            //
            PgpObjectFactory pgpFact = new PgpObjectFactory(bOut.ToArray());

            PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject();

            pgpFact = new PgpObjectFactory(c1.GetDataStream());

            PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject();

            PgpOnePassSignature ops = p1[0];

            PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject();
            if (!p2.ModificationTime.Equals(testDateTime))
            {
                Fail("Modification time not preserved");
            }

            Stream dIn = p2.GetInputStream();

            ops.InitVerify(pubKey);

            // TODO Need a stream object to automatically call Update?
            // (via ISigner implementation of PgpSignatureGenerator)
            while ((ch = dIn.ReadByte()) >= 0)
            {
                ops.Update((byte)ch);
            }

            PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();

            if (!ops.Verify(p3[0]))
            {
                Fail("Failed generated signature check - " + hashAlgorithm);
            }
        }