summary refs log tree commit diff
path: root/crypto/test/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2015-10-12 15:49:54 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2015-10-12 15:49:54 +0700
commit06ba713c9b19102310675a6c58e07c68d8efb3c7 (patch)
tree2d4e747d988f74abca2a5513713e4ff0e8ed8e69 /crypto/test/src
parentAdd new file entries (diff)
downloadBouncyCastle.NET-ed25519-06ba713c9b19102310675a6c58e07c68d8efb3c7.tar.xz
Port of latest PGP tests and supporting code changes
Diffstat (limited to 'crypto/test/src')
-rw-r--r--crypto/test/src/openpgp/examples/PublicKeyRingDump.cs4
-rw-r--r--crypto/test/src/openpgp/test/PGPSignatureTest.cs2
-rw-r--r--crypto/test/src/openpgp/test/PgpECDHTest.cs280
-rw-r--r--crypto/test/src/openpgp/test/PgpECDsaTest.cs205
-rw-r--r--crypto/test/src/openpgp/test/PgpECMessageTest.cs196
-rw-r--r--crypto/test/src/openpgp/test/PgpKeyRingTest.cs34
-rw-r--r--crypto/test/src/openpgp/test/PgpParsingTest.cs40
-rw-r--r--crypto/test/src/openpgp/test/PgpUnicodeTest.cs137
-rw-r--r--crypto/test/src/openpgp/test/RegressionTest.cs4
9 files changed, 899 insertions, 3 deletions
diff --git a/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs b/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs
index bb6108f2d..cbf553795 100644
--- a/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs
+++ b/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs
@@ -35,8 +35,8 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
                     return "ElGamalEncrypt";
                 case PublicKeyAlgorithmTag.Dsa:
                     return "DSA";
-                case PublicKeyAlgorithmTag.EC:
-                    return "EC";
+                case PublicKeyAlgorithmTag.ECDH:
+                    return "ECDH";
                 case PublicKeyAlgorithmTag.ECDsa:
                     return "ECDSA";
                 case PublicKeyAlgorithmTag.ElGamalGeneral:
diff --git a/crypto/test/src/openpgp/test/PGPSignatureTest.cs b/crypto/test/src/openpgp/test/PGPSignatureTest.cs
index 0d8235307..40fee7a5f 100644
--- a/crypto/test/src/openpgp/test/PGPSignatureTest.cs
+++ b/crypto/test/src/openpgp/test/PGPSignatureTest.cs
@@ -698,7 +698,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
 
         private void checkValue(byte[] flag, int val)
         {
-            KeyFlags f = new KeyFlags(true, flag);
+            KeyFlags f = new KeyFlags(true, false, flag);
 
             if (f.Flags != val)
             {
diff --git a/crypto/test/src/openpgp/test/PgpECDHTest.cs b/crypto/test/src/openpgp/test/PgpECDHTest.cs
new file mode 100644
index 000000000..b7c500bd0
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PgpECDHTest.cs
@@ -0,0 +1,280 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Sec;
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+    [TestFixture]
+    public class PgpECDHTest
+        : SimpleTest
+    {
+        private static readonly byte[] testPubKey =
+            Base64.Decode(
+                "mFIEUb4GwBMIKoZIzj0DAQcCAwS8p3TFaRAx58qCG63W+UNthXBPSJDnVDPTb/sT" +
+                "iXePaAZ/Gh1GKXTq7k6ab/67MMeVFp/EdySumqdWLtvceFKstFBUZXN0IEVDRFNB" +
+                "LUVDREggKEtleSBhbmQgc3Via2V5IGFyZSAyNTYgYml0cyBsb25nKSA8dGVzdC5l" +
+                "Y2RzYS5lY2RoQGV4YW1wbGUuY29tPoh6BBMTCAAiBQJRvgbAAhsDBgsJCAcDAgYV" +
+                "CAIJCgsEFgIDAQIeAQIXgAAKCRD3wDlWjFo9U5O2AQDi89NO6JbaIObC63jMMWsi" +
+                "AaQHrBCPkDZLibgNv73DLgD/faouH4YZJs+cONQBPVnP1baG1NpWR5ppN3JULFcr" +
+                "hcq4VgRRvgbAEggqhkjOPQMBBwIDBLtY8Nmfz0zSEa8C1snTOWN+VcT8pXPwgJRy" +
+                "z6kSP4nPt1xj1lPKj5zwPXKWxMkPO9ocqhKdg2mOh6/rc1ObIoMDAQgHiGEEGBMI" +
+                "AAkFAlG+BsACGwwACgkQ98A5VoxaPVN8cgEAj4dMNMNwRSg2ZBWunqUAHqIedVbS" +
+                "dmwmbysD192L3z4A/ReXEa0gtv8OFWjuALD1ovEK8TpDORLUb6IuUb5jUIzY");
+
+        private static readonly byte[] testPrivKey =
+            Base64.Decode(
+                "lKUEUb4GwBMIKoZIzj0DAQcCAwS8p3TFaRAx58qCG63W+UNthXBPSJDnVDPTb/sT" +
+                "iXePaAZ/Gh1GKXTq7k6ab/67MMeVFp/EdySumqdWLtvceFKs/gcDAo11YYCae/K2" +
+                "1uKGJ/uU4b4QHYnPIsAdYpuo5HIdoAOL/WwduRa8C6vSFrtMJLDqPK3BUpMz3CXN" +
+                "GyMhjuaHKP5MPbBZkIfgUGZO5qvU9+i0UFRlc3QgRUNEU0EtRUNESCAoS2V5IGFu" +
+                "ZCBzdWJrZXkgYXJlIDI1NiBiaXRzIGxvbmcpIDx0ZXN0LmVjZHNhLmVjZGhAZXhh" +
+                "bXBsZS5jb20+iHoEExMIACIFAlG+BsACGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4B" +
+                "AheAAAoJEPfAOVaMWj1Tk7YBAOLz007oltog5sLreMwxayIBpAesEI+QNkuJuA2/" +
+                "vcMuAP99qi4fhhkmz5w41AE9Wc/VtobU2lZHmmk3clQsVyuFyg==");
+
+        private static readonly byte[] testMessage =
+            Base64.Decode(
+                "hH4Dp5+FdoujIBwSAgMErx4BSvgXY3irwthgxU8zPoAoR+8rhmxdpwbw6ZJAO2GX" +
+                "azWJ85JNcobHKDeGeUq6wkTFu+g6yG99gIX8J5xJAjBRhyCRcaFgwbdDV4orWTe3" +
+                "iewiT8qs4BQ23e0c8t+thdKoK4thMsCJy7wSKqY0sJTSVAELroNbCOi2lcO15YmW" +
+                "6HiuFH7VKWcxPUBjXwf5+Z3uOKEp28tBgNyDrdbr1BbqlgYzIKq/pe9zUbUXfitn" +
+                "vFc6HcGhvmRQreQ+Yw1x3x0HJeoPwg==");
+
+        private void Generate()
+        {
+            SecureRandom random = SecureRandom.GetInstance("SHA1PRNG");
+
+            //
+            // Generate a master key
+            //
+            IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("ECDSA");
+            keyGen.Init(new ECKeyGenerationParameters(SecObjectIdentifiers.SecP256r1, random));
+
+            AsymmetricCipherKeyPair kpSign = keyGen.GenerateKeyPair();
+
+            PgpKeyPair ecdsaKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ECDsa, kpSign, DateTime.UtcNow);
+
+            //
+            // Generate an encryption key
+            //
+            keyGen = GeneratorUtilities.GetKeyPairGenerator("ECDH");
+            keyGen.Init(new ECKeyGenerationParameters(SecObjectIdentifiers.SecP256r1, random));
+
+            AsymmetricCipherKeyPair kpEnc = keyGen.GenerateKeyPair();
+
+            PgpKeyPair ecdhKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ECDH, kpEnc, DateTime.UtcNow);
+
+            //
+            // Generate a key ring
+            //
+            char[] passPhrase = "test".ToCharArray();
+            PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification, ecdsaKeyPair,
+                "test@bouncycastle.org", SymmetricKeyAlgorithmTag.Aes256, passPhrase, true, null, null, random);
+            keyRingGen.AddSubKey(ecdhKeyPair);
+
+            PgpPublicKeyRing pubRing = keyRingGen.GeneratePublicKeyRing();
+
+            // TODO: add check of KdfParameters
+            DoBasicKeyRingCheck(pubRing);
+
+            PgpSecretKeyRing secRing = keyRingGen.GenerateSecretKeyRing();
+
+            PgpPublicKeyRing pubRingEnc = new PgpPublicKeyRing(pubRing.GetEncoded());
+            if (!Arrays.AreEqual(pubRing.GetEncoded(), pubRingEnc.GetEncoded()))
+            {
+                Fail("public key ring encoding failed");
+            }
+
+            PgpSecretKeyRing secRingEnc = new PgpSecretKeyRing(secRing.GetEncoded());
+            if (!Arrays.AreEqual(secRing.GetEncoded(), secRingEnc.GetEncoded()))
+            {
+                Fail("secret key ring encoding failed");
+            }
+
+            PgpPrivateKey pgpPrivKey = secRing.GetSecretKey().ExtractPrivateKey(passPhrase);
+        }
+
+        private void TestDecrypt(PgpSecretKeyRing secretKeyRing)
+        {
+            PgpObjectFactory pgpF = new PgpObjectFactory(testMessage);
+
+            PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject();
+
+            PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0];
+
+            PgpSecretKey secretKey = secretKeyRing.GetSecretKey(); // secretKeyRing.GetSecretKey(encP.KeyId);
+
+    //        PgpPrivateKey pgpPrivKey = secretKey.extractPrivateKey(new JcePBESecretKeyEncryptorBuilder());
+
+    //        clear = encP.getDataStream(pgpPrivKey, "BC");
+    //
+    //        bOut.reset();
+    //
+    //        while ((ch = clear.read()) >= 0)
+    //        {
+    //            bOut.write(ch);
+    //        }
+    //
+    //        out = bOut.toByteArray();
+    //
+    //        if (!AreEqual(out, text))
+    //        {
+    //            fail("wrong plain text in Generated packet");
+    //        }
+        }
+
+        private void EncryptDecryptTest()
+        {
+            SecureRandom random = SecureRandom.GetInstance("SHA1PRNG");
+
+            byte[] text = Encoding.ASCII.GetBytes("hello world!");
+
+            IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("ECDH");
+            keyGen.Init(new ECKeyGenerationParameters(SecObjectIdentifiers.SecP256r1, random));
+
+            AsymmetricCipherKeyPair kpEnc = keyGen.GenerateKeyPair();
+
+            PgpKeyPair ecdhKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ECDH, kpEnc, DateTime.UtcNow);
+
+            PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();
+            MemoryStream ldOut = new MemoryStream();
+            Stream pOut = lData.Open(ldOut, PgpLiteralDataGenerator.Utf8, PgpLiteralData.Console, text.Length, DateTime.UtcNow);
+
+            pOut.Write(text, 0, text.Length);
+
+            pOut.Close();
+
+            byte[] data = ldOut.ToArray();
+
+            MemoryStream cbOut = new MemoryStream();
+
+            PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, random);
+            cPk.AddMethod(ecdhKeyPair.PublicKey);
+
+            Stream cOut = cPk.Open(new UncloseableStream(cbOut), data.Length);
+
+            cOut.Write(data, 0, data.Length);
+
+            cOut.Close();
+
+            PgpObjectFactory pgpF = new PgpObjectFactory(cbOut.ToArray());
+
+            PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject();
+
+            PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0];
+
+            Stream clear = encP.GetDataStream(ecdhKeyPair.PrivateKey);
+
+            pgpF = new PgpObjectFactory(clear);
+
+            PgpLiteralData ld = (PgpLiteralData)pgpF.NextPgpObject();
+
+            clear = ld.GetInputStream();
+            MemoryStream bOut = new MemoryStream();
+
+            int ch;
+            while ((ch = clear.ReadByte()) >= 0)
+            {
+                bOut.WriteByte((byte)ch);
+            }
+
+            byte[] output = bOut.ToArray();
+
+            if (!AreEqual(output, text))
+            {
+                Fail("wrong plain text in Generated packet");
+            }
+        }
+
+        public override void PerformTest()
+        {
+            //
+            // Read the public key
+            //
+            PgpPublicKeyRing pubKeyRing = new PgpPublicKeyRing(testPubKey);
+
+            DoBasicKeyRingCheck(pubKeyRing);
+
+            //
+            // Read the private key
+            //
+            PgpSecretKeyRing secretKeyRing = new PgpSecretKeyRing(testPrivKey);
+
+            TestDecrypt(secretKeyRing);
+
+            EncryptDecryptTest();
+
+            Generate();
+        }
+
+        private void DoBasicKeyRingCheck(PgpPublicKeyRing pubKeyRing)
+        {
+            foreach (PgpPublicKey pubKey in pubKeyRing.GetPublicKeys())
+            {
+                if (pubKey.IsMasterKey)
+                {
+                    if (pubKey.IsEncryptionKey)
+                    {
+                        Fail("master key showed as encryption key!");
+                    }
+                }
+                else
+                {
+                    if (!pubKey.IsEncryptionKey)
+                    {
+                        Fail("sub key not encryption key!");
+                    }
+
+                    foreach (PgpSignature certification in pubKeyRing.GetPublicKey().GetSignatures())
+                    {
+                        certification.InitVerify(pubKeyRing.GetPublicKey());
+
+                        if (!certification.VerifyCertification((string)First(pubKeyRing.GetPublicKey().GetUserIds()), pubKeyRing.GetPublicKey()))
+                        {
+                            Fail("subkey certification does not verify");
+                        }
+                    }
+                }
+            }
+        }
+
+        private static object First(IEnumerable e)
+        {
+            IEnumerator n = e.GetEnumerator();
+            Assert.IsTrue(n.MoveNext());
+            return n.Current;
+        }
+
+        public override string Name
+        {
+            get { return "PgpECDHTest"; }
+        }
+
+        public static void Main(
+            string[] args)
+        {
+            RunTest(new PgpECDHTest());
+        }
+
+        [Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/test/PgpECDsaTest.cs b/crypto/test/src/openpgp/test/PgpECDsaTest.cs
new file mode 100644
index 000000000..6259ef627
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PgpECDsaTest.cs
@@ -0,0 +1,205 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Sec;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+    [TestFixture]
+    public class PgpECDsaTest
+        : SimpleTest
+    {
+        private static readonly byte[] testPubKey =
+            Base64.Decode(
+                "mFIEUb4HqBMIKoZIzj0DAQcCAwSQynmjwsGJHYJakAEVYxrm3tt/1h8g9Uksx32J" +
+                "zG/ZH4RwaD0PbjzEe5EVBmCwSErRZxt/5AxXa0TEHWjya8FetDVFQ0RTQSAoS2V5" +
+                "IGlzIDI1NiBiaXRzIGxvbmcpIDx0ZXN0LmVjZHNhQGV4YW1wbGUuY29tPoh6BBMT" +
+                "CAAiBQJRvgeoAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRDqO46kgPLi" +
+                "vN1hAP4n0UApR36ziS5D8KUt7wEpBujQE4G3+efATJ+DMmY/SgEA+wbdDynFf/V8" +
+                "pQs0+FtCYQ9schzIur+peRvol7OrNnc=");
+
+        private static readonly byte[] testPrivKey =
+            Base64.Decode(
+                "lKUEUb4HqBMIKoZIzj0DAQcCAwSQynmjwsGJHYJakAEVYxrm3tt/1h8g9Uksx32J" +
+                "zG/ZH4RwaD0PbjzEe5EVBmCwSErRZxt/5AxXa0TEHWjya8Fe/gcDAqTWSUiFpEno" +
+                "1n8izmLaWTy8GYw5/lK4R2t6D347YGgTtIiXfoNPOcosmU+3OibyTm2hc/WyG4fL" +
+                "a0nxFtj02j0Bt/Fw0N4VCKJwKL/QJT+0NUVDRFNBIChLZXkgaXMgMjU2IGJpdHMg" +
+                "bG9uZykgPHRlc3QuZWNkc2FAZXhhbXBsZS5jb20+iHoEExMIACIFAlG+B6gCGwMG" +
+                "CwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOo7jqSA8uK83WEA/ifRQClHfrOJ" +
+                "LkPwpS3vASkG6NATgbf558BMn4MyZj9KAQD7Bt0PKcV/9XylCzT4W0JhD2xyHMi6" +
+                "v6l5G+iXs6s2dw==");
+
+        private static readonly char[] testPasswd = "test".ToCharArray();
+
+        private static readonly byte[] sExprKey =
+            Base64.Decode(
+                "KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOmVjYyg1OmN1cnZlMTU6YnJh"
+                    + "aW5wb29sUDM4NHIxKSgxOnE5NzoEi29XCqkugtlRvONnpAVMQgfecL+Gk86O"
+                    + "t8LnUizfHG2TqRrtqlMg1DdU8Z8dJWmhJG84IUOURCyjt8nE4BeeCfRIbTU5"
+                    + "7CB13OqveBdNIRfK45UQnxHLO2MPVXf4GMdtKSg5OnByb3RlY3RlZDI1Om9w"
+                    + "ZW5wZ3AtczJrMy1zaGExLWFlcy1jYmMoKDQ6c2hhMTg6itLEzGV4Cfg4OjEy"
+                    + "OTA1NDcyKTE2OgxmufENKFTZUB72+X7AwkgpMTEyOvMWNLZgaGdlTN8XCxa6"
+                    + "8ia0Xqqb9RvHgTh+iBf0RgY5Tx5hqO9fHOi76LTBMfxs9VC4f1rTketjEUKR"
+                    + "f5amKb8lrJ67kKEsny4oRtP9ejkNzcvHFqRdxmHyL10ui8M8rJN9OU8ArqWf"
+                    + "g22dTcKu02cpKDEyOnByb3RlY3RlZC1hdDE1OjIwMTQwNjA4VDE2MDg1MCkp"
+                    + "KQ==");
+
+        private void GenerateAndSign()
+        {
+            SecureRandom random = SecureRandom.GetInstance("SHA1PRNG");
+
+            IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("ECDSA");
+            keyGen.Init(new ECKeyGenerationParameters(SecObjectIdentifiers.SecP256r1, random));
+
+            AsymmetricCipherKeyPair kpSign = keyGen.GenerateKeyPair();
+
+            PgpKeyPair ecdsaKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ECDsa, kpSign, DateTime.UtcNow);
+
+            byte[] msg = Encoding.ASCII.GetBytes("hello world!");
+
+            //
+            // try a signature
+            //
+            PgpSignatureGenerator signGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.ECDsa, HashAlgorithmTag.Sha256);
+            signGen.InitSign(PgpSignature.BinaryDocument, ecdsaKeyPair.PrivateKey);
+
+            signGen.Update(msg);
+
+            PgpSignature sig = signGen.Generate();
+
+            sig.InitVerify(ecdsaKeyPair.PublicKey);
+            sig.Update(msg);
+
+            if (!sig.Verify())
+            {
+                Fail("signature failed to verify!");
+            }
+
+            //
+            // generate a key ring
+            //
+            char[] passPhrase = "test".ToCharArray();
+            PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification, ecdsaKeyPair,
+                "test@bouncycastle.org", SymmetricKeyAlgorithmTag.Aes256, passPhrase, true, null, null, random);
+
+            PgpPublicKeyRing pubRing = keyRingGen.GeneratePublicKeyRing();
+            PgpSecretKeyRing secRing = keyRingGen.GenerateSecretKeyRing();
+
+            PgpPublicKeyRing pubRingEnc = new PgpPublicKeyRing(pubRing.GetEncoded());
+            if (!Arrays.AreEqual(pubRing.GetEncoded(), pubRingEnc.GetEncoded()))
+            {
+                Fail("public key ring encoding failed");
+            }
+
+            PgpSecretKeyRing secRingEnc = new PgpSecretKeyRing(secRing.GetEncoded());
+            if (!Arrays.AreEqual(secRing.GetEncoded(), secRingEnc.GetEncoded()))
+            {
+                Fail("secret key ring encoding failed");
+            }
+
+
+            //
+            // try a signature using encoded key
+            //
+            signGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.ECDsa, HashAlgorithmTag.Sha256);
+            signGen.InitSign(PgpSignature.BinaryDocument, secRing.GetSecretKey().ExtractPrivateKey(passPhrase));
+            signGen.Update(msg);
+
+            sig = signGen.Generate();
+            sig.InitVerify(secRing.GetSecretKey().PublicKey);
+            sig.Update(msg);
+
+            if (!sig.Verify())
+            {
+                Fail("re-encoded signature failed to verify!");
+            }
+        }
+
+        public override void PerformTest()
+        {
+            //
+            // Read the public key
+            //
+            PgpPublicKeyRing pubKeyRing = new PgpPublicKeyRing(testPubKey);
+            foreach (PgpSignature certification in pubKeyRing.GetPublicKey().GetSignatures())
+            {
+                certification.InitVerify(pubKeyRing.GetPublicKey());
+
+                if (!certification.VerifyCertification((string)First(pubKeyRing.GetPublicKey().GetUserIds()), pubKeyRing.GetPublicKey()))
+                {
+                    Fail("self certification does not verify");
+                }
+            }
+
+            if (pubKeyRing.GetPublicKey().BitStrength != 256)
+            {
+                Fail("incorrect bit strength returned");
+            }
+
+            //
+            // Read the private key
+            //
+            PgpSecretKeyRing secretKeyRing = new PgpSecretKeyRing(testPrivKey);
+
+            PgpPrivateKey privKey = secretKeyRing.GetSecretKey().ExtractPrivateKey(testPasswd);
+
+            GenerateAndSign();
+
+            //
+            // sExpr
+            //
+            byte[] msg = Encoding.ASCII.GetBytes("hello world!");
+
+            PgpSecretKey key = PgpSecretKey.ParseSecretKeyFromSExpr(new MemoryStream(sExprKey, false), "test".ToCharArray());
+
+            PgpSignatureGenerator signGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.ECDsa, HashAlgorithmTag.Sha256);
+            signGen.InitSign(PgpSignature.BinaryDocument, key.ExtractPrivateKey(null));
+            signGen.Update(msg);
+
+            PgpSignature sig = signGen.Generate();
+            sig.InitVerify(key.PublicKey);
+            sig.Update(msg);
+
+            if (!sig.Verify())
+            {
+                Fail("signature failed to verify!");
+            }
+        }
+
+        private static object First(IEnumerable e)
+        {
+            IEnumerator n = e.GetEnumerator();
+            Assert.IsTrue(n.MoveNext());
+            return n.Current;
+        }
+
+        public override string Name
+        {
+            get { return "PgpECDsaTest"; }
+        }
+
+        public static void Main(
+            string[] args)
+        {
+            RunTest(new PgpECDsaTest());
+        }
+
+        [Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/test/PgpECMessageTest.cs b/crypto/test/src/openpgp/test/PgpECMessageTest.cs
new file mode 100644
index 000000000..ac8283721
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PgpECMessageTest.cs
@@ -0,0 +1,196 @@
+using System;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+    [TestFixture]
+    public class PgpECMessageTest
+        : SimpleTest
+    {
+        private static readonly byte[] testPubKey =
+            Base64.Decode(
+                "mFIEU5SAxhMIKoZIzj0DAQcCAwRqnFLCB8EEZkAELNqznk8yQau/f1PACUTU/Qe9\n" +
+                    "jlybc22bO55BdvZdFoa3RmNQHhR980/KeVwCQ3cPpe6OQJFAtD9OSVNUIFAtMjU2\n" +
+                    "IChHZW5lcmF0ZWQgYnkgR1BHIDIuMSBiZXRhKSA8bmlzdC1wLTI1NkBleGFtcGxl\n" +
+                    "LmNvbT6IeQQTEwgAIQUCU5SAxgIbAwYLCQgHAwIGFQgCCQoLAxYCAQIeAQIXgAAK\n" +
+                    "CRA2iYNe+deDntxvAP90U2BUL2YcxrJYnsK783VIPM5U5/2IhH7azbRfaHiLZgEA\n" +
+                    "1/BVNxRG/Q07gPSdEGagRZcrzPxMQPLjBL4T7Nq5eSG4VgRTlIDqEggqhkjOPQMB\n" +
+                    "BwIDBJlWEj5qR12xbmp5dkjEkV+PRSfk37NKnw8axSJkyDTsFNZLIugMLX/zTn3r\n" +
+                    "rOamvHUdXNbLy1s8PeyrztMcOnwDAQgHiGEEGBMIAAkFAlOUgOoCGwwACgkQNomD\n" +
+                    "XvnXg556SQD+MCXRkYgLPd0NWWbCKl5wYk4NwWRvOCDFGk7eYoRTKaYBAIkt3J86\n" +
+                    "Bn0zCzsphjrIUlGPXhLSX/2aJQDuuK3zzLmn");
+
+        private static readonly byte[] sExprKeySub =
+            Base64.Decode(
+                "KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOmVjYyg1OmN1cnZlMTA6TklT"
+                 + "VCBQLTI1NikoMTpxNjU6BJlWEj5qR12xbmp5dkjEkV+PRSfk37NKnw8axSJk"
+                 + "yDTsFNZLIugMLX/zTn3rrOamvHUdXNbLy1s8PeyrztMcOnwpKDk6cHJvdGVj"
+                 + "dGVkMjU6b3BlbnBncC1zMmszLXNoYTEtYWVzLWNiYygoNDpzaGExODpu2e7w"
+                 + "pW4L5jg6MTI5MDU0NzIpMTY6ohIkbi1P1O7QX1zgPd7Ejik5NjrCoM9qBxzy"
+                 + "LVJJMVRGlsjltF9/CeLnRPN1sjeiQrP1vAlZMPiOpYTmGDVRcZhdkCRO06MY"
+                 + "UTLDZK1wsxELVD0s9irpbskcOnXwqtXbIqhoK4B+9pnkR0h5gi0xPIGSTtYp"
+                 + "KDEyOnByb3RlY3RlZC1hdDE1OjIwMTQwNjA4VDE1MjgxMCkpKQ==");
+
+        private static readonly byte[] sExprKeyMaster =
+            Base64.Decode(
+                "KDIxOnByb3RlY3RlZC1wcml2YXRlLWtleSgzOmVjYyg1OmN1cnZlMTA6TklT"
+              + "VCBQLTI1NikoMTpxNjU6BGqcUsIHwQRmQAQs2rOeTzJBq79/U8AJRNT9B72O"
+              + "XJtzbZs7nkF29l0WhrdGY1AeFH3zT8p5XAJDdw+l7o5AkUApKDk6cHJvdGVj"
+              + "dGVkMjU6b3BlbnBncC1zMmszLXNoYTEtYWVzLWNiYygoNDpzaGExODr4PqHT"
+              + "9W4lpTg6MTI5MDU0NzIpMTY6VsooQy9aGsuMpiObZk4y1ik5NjoCArOSmSsJ"
+              + "IYUzxkRwy/HyDYPqjAqrNrh3m8lQco6k64Pf4SDda/0gKjkum7zYDEzBEvXI"
+              + "+ZodAST6z3IDkPHL7LUy5qp2LdG73xLRFjfsqOsZgP+nwoOSUiC7N4AWJPAp"
+              + "KDEyOnByb3RlY3RlZC1hdDE1OjIwMTQwNjA4VDE1MjcwOSkpKQ==");
+
+        private static readonly byte[] encMessage =
+            Base64.Decode("hH4DrQCblwYU61MSAgMEVXjgPW2hvIhUMQ2qlAQlAliZKbyujaYfLnwZTeGvu+pt\n"+
+                "gJXt+JJ8zWoENxLAp+Nb3PxJW4CjvkXQ2dEmmvkhBzAhDer86XJBrQLBQUL+6EmE\n"+
+                "l+/3Yzt+cPEyEn32BSpkt31F2yGncoefCUDgj9tKiFXSRwGhjRno0qzB3CfRWzDu\n"+
+                "eelwwtRcxnvXNc44TuHRf4PgZ3d4dDU69bWQswdQ5UTP/Bjjo92yMLtJ3HtBuym+\n"+
+                "NazbQUh4M+SP");
+
+        private static readonly byte[] signedEncMessage =
+            Base64.Decode("hH4DrQCblwYU61MSAgMEC/jpqjgnqotzKWNWJ3bhOxmmChghrV2PLQbQqtHtVvbj\n" +
+                "zyLpaPgeqLslMAjsdy8rlANCjlweZhtP1DmvHiYgjDAA54eptpLMtbULaQOoRcsZ\n" +
+                "ZnMqhx9s5phAohNFGC+DnVU/IwxDOnI+ya54LOoXUrrSsgEKDTlAmYr4/oDmLTXt\n" +
+                "TaLgk0T9nBxGe8WbLwhPRBIyq6NX151aQ+pOobajrRiLwg/CwUsbAZ50bBPn2JjX\n" +
+                "wgBhBjyAn7D6bZ4hMl3YSluSiFkJhxZcYSydtIAlX35q4D/pJjT4mPT/y7ypytCU\n" +
+                "0wWo53O6NCSeM/EpeFw8RRh8fe+m33qpA6T5sR3Alg4ZukiIxLa36k6Cv5KTHmB3\n" +
+                "6lKZcgQDHNIKStV1bW4Cva1aXXQ=");
+
+        private void DoTestMasterKey()
+        {
+            PgpSecretKey key = PgpSecretKey.ParseSecretKeyFromSExpr(new MemoryStream(sExprKeyMaster, false),
+                "test".ToCharArray());
+
+            byte[] msg = Encoding.UTF8.GetBytes("hello world!");
+
+            PgpSignatureGenerator signGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.ECDsa, HashAlgorithmTag.Sha256);
+            signGen.InitSign(PgpSignature.BinaryDocument, key.ExtractPrivateKey(null));
+            signGen.Update(msg);
+            PgpSignature sig = signGen.Generate();
+
+            PgpPublicKey publicKey = new PgpPublicKeyRing(testPubKey).GetPublicKey();
+            sig.InitVerify(publicKey);
+            sig.Update(msg);
+
+            if (!sig.Verify())
+            {
+                Fail("signature failed to verify!");
+            }
+        }
+
+        private void DoTestEncMessage()
+        {
+            PgpObjectFactory pgpFact = new PgpObjectFactory(encMessage);
+
+            PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpFact.NextPgpObject();
+
+            PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0];
+
+            PgpPublicKey publicKey = new PgpPublicKeyRing(testPubKey).GetPublicKey(encP.KeyId);
+
+            PgpSecretKey secretKey = PgpSecretKey.ParseSecretKeyFromSExpr(new MemoryStream(sExprKeySub, false),
+                "test".ToCharArray(), publicKey);
+
+            Stream clear = encP.GetDataStream(secretKey.ExtractPrivateKey(null));
+
+            PgpObjectFactory plainFact = new PgpObjectFactory(clear);
+
+            PgpCompressedData cData = (PgpCompressedData)plainFact.NextPgpObject();
+
+            PgpObjectFactory compFact = new PgpObjectFactory(cData.GetDataStream());
+
+            PgpLiteralData lData = (PgpLiteralData)compFact.NextPgpObject();
+
+            if (!"test.txt".Equals(lData.FileName))
+            {
+                Fail("wrong file name detected");
+            }
+        }
+
+        private void DoTestSignedEncMessage()
+        {
+            PgpObjectFactory pgpFact = new PgpObjectFactory(signedEncMessage);
+
+            PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpFact.NextPgpObject();
+
+            PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0];
+
+            PgpPublicKeyRing publicKeyRing = new PgpPublicKeyRing(testPubKey);
+
+            PgpPublicKey publicKey = publicKeyRing.GetPublicKey(encP.KeyId);
+
+            PgpSecretKey secretKey = PgpSecretKey.ParseSecretKeyFromSExpr(new MemoryStream(sExprKeySub, false),
+                "test".ToCharArray(), publicKey);
+
+            Stream clear = encP.GetDataStream(secretKey.ExtractPrivateKey(null));
+
+            PgpObjectFactory plainFact = new PgpObjectFactory(clear);
+
+            PgpCompressedData cData = (PgpCompressedData)plainFact.NextPgpObject();
+
+            PgpObjectFactory compFact = new PgpObjectFactory(cData.GetDataStream());
+
+            PgpOnePassSignatureList sList = (PgpOnePassSignatureList)compFact.NextPgpObject();
+
+            PgpOnePassSignature ops = sList[0];
+
+            PgpLiteralData lData  = (PgpLiteralData)compFact.NextPgpObject();
+
+            if (!"test.txt".Equals(lData.FileName))
+            {
+                Fail("wrong file name detected");
+            }
+
+            Stream dIn = lData .GetInputStream();
+
+            ops.InitVerify(publicKeyRing.GetPublicKey(ops.KeyId));
+
+            int ch;
+            while ((ch = dIn.ReadByte()) >= 0)
+            {
+                ops.Update((byte)ch);
+            }
+
+            PgpSignatureList p3 = (PgpSignatureList)compFact.NextPgpObject();
+
+            if (!ops.Verify(p3[0]))
+            {
+                Fail("Failed signature check");
+            }
+        }
+
+        public override void PerformTest()
+        {
+            DoTestMasterKey();
+            DoTestEncMessage();
+            DoTestSignedEncMessage();
+        }
+
+        public override string Name
+        {
+            get { return "PgpECMessageTest"; }
+        }
+
+        public static void Main(
+            string[] args)
+        {
+            RunTest(new PgpECMessageTest());
+        }
+
+        [Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
index 2ac2f0c97..9896c1ef6 100644
--- a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
+++ b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
@@ -2145,6 +2145,40 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             PublicKeyRingWithX509Test();
             SecretKeyRingWithPersonalCertificateTest();
             InsertMasterTest();
+            LongSubPacketsTest();
+        }
+
+        private void LongSubPacketsTest()
+        {
+            Stream fIn = SimpleTest.GetTestDataAsStream("openpgp.longSigSubPack.asc");
+            Stream bIn = new BufferedStream(fIn);
+            PgpPublicKeyRing pkr = new PgpPublicKeyRing(PgpUtilities.GetDecoderStream(bIn));
+            bIn.Close();
+
+            PgpPublicKey masterpk = pkr.GetPublicKey();
+
+            // Check userids
+            foreach (string uid in masterpk.GetUserIds())
+            {
+                CheckUidSig(masterpk, uid);
+            }
+        }
+
+        private void CheckUidSig(PgpPublicKey pk, string uid)
+        {
+            foreach (PgpSignature sig in pk.GetSignaturesForId(uid))
+            {
+                if (!IsGoodUidSignature(sig, pk, uid))
+                {
+                    Fail("Bad self-signature found for '" + uid + "'");
+                }
+            }
+        }
+
+        private static bool IsGoodUidSignature(PgpSignature sig, PgpPublicKey masterpk, string uid)
+        {
+            sig.InitVerify(masterpk);
+            return sig.VerifyCertification(uid, masterpk);
         }
 
         public override string Name
diff --git a/crypto/test/src/openpgp/test/PgpParsingTest.cs b/crypto/test/src/openpgp/test/PgpParsingTest.cs
new file mode 100644
index 000000000..78fca7570
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PgpParsingTest.cs
@@ -0,0 +1,40 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+	[TestFixture]
+	public class PgpParsingTest
+		: SimpleTest
+	{
+		public override void PerformTest()
+		{
+            Stream fIn = SimpleTest.GetTestDataAsStream("openpgp.bigpub.asc");
+            Stream keyIn = PgpUtilities.GetDecoderStream(fIn);
+            PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(keyIn);
+		}
+
+        public override string Name
+		{
+			get { return "PgpParsingTest"; }
+		}
+
+        public static void Main(
+			string[] args)
+		{
+			RunTest(new PgpParsingTest());
+		}
+
+        [Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/openpgp/test/PgpUnicodeTest.cs b/crypto/test/src/openpgp/test/PgpUnicodeTest.cs
new file mode 100644
index 000000000..ce1df8980
--- /dev/null
+++ b/crypto/test/src/openpgp/test/PgpUnicodeTest.cs
@@ -0,0 +1,137 @@
+using System;
+using System.IO;
+using System.Text;
+
+using NUnit.Core;
+using NUnit.Framework;
+
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
+{
+    [TestFixture]
+    public class PgpUnicodeTest
+    {
+        private void DoTestKey(BigInteger keyId, string passphrase)
+        {
+            PgpSecretKeyRingBundle secretKeyRing = LoadSecretKeyCollection("secring.gpg");
+
+            PgpSecretKeyRing secretKey = secretKeyRing.GetSecretKeyRing(keyId.LongValue);
+            Assert.NotNull(secretKey, "Could not locate secret keyring with Id=" + keyId.ToString(16));
+
+            PgpSecretKey key = secretKey.GetSecretKey();
+            Assert.NotNull(key, "Could not locate secret key!");
+
+            try
+            {
+                PgpPrivateKey privateKey = key.ExtractPrivateKey(passphrase.ToCharArray());
+
+                Assert.IsTrue(privateKey.KeyId == keyId.LongValue);
+            }
+            catch (PgpException e)
+            {
+                throw new PgpException("Password incorrect!", e);
+            }
+
+            // all fine!
+        }
+
+        [Test]
+        public void TestUmlautPassphrase()
+        {
+
+            try
+            {
+                BigInteger keyId = new BigInteger("362961283C48132B9F14C5C3EC87272EFCB986D2", 16);
+
+                string passphrase = Encoding.Unicode.GetString(Encoding.Unicode.GetBytes("Händle"));
+
+ //             FileInputStream passwordFile = new FileInputStream("testdata/passphrase_for_test.txt");
+ //             byte[] password = new byte[passwordFile.available()];
+ //             passwordFile.read(password);
+ //             passwordFile.close();
+ //             String passphrase = new String(password);            
+
+                DoTestKey(keyId, passphrase);
+
+                // all fine!
+
+            }
+            catch (Exception e)
+            {
+                Console.Error.WriteLine(e.StackTrace);
+                Assert.Fail(e.Message);
+            }
+        }
+
+        [Test]
+        public void TestAsciiPassphrase()
+        {
+
+            try
+            {
+                BigInteger keyId = new BigInteger("A392B7310C64026022405257AA2AAAC7CB417459", 16);
+
+                string passphrase = "Admin123";
+
+                DoTestKey(keyId, passphrase);
+
+                // all fine!
+            }
+            catch (Exception e)
+            {
+                Console.Error.WriteLine(e.StackTrace);
+                Assert.Fail(e.Message);
+            }
+        }
+
+        [Test]
+        public void TestCyrillicPassphrase()
+        {
+
+            try
+            {
+                BigInteger keyId = new BigInteger("B7773AF32BE4EC1806B1BACC4680E7F3960C44E7", 16);
+
+                // XXX The password text file must not have the UTF-8 BOM !
+                // Ref: http://stackoverflow.com/questions/2223882/whats-different-between-utf-8-and-utf-8-without-bom
+
+                Stream passwordFile = SimpleTest.GetTestDataAsStream("openpgp.unicode.passphrase_cyr.txt");
+                TextReader reader = new StreamReader(passwordFile, Encoding.UTF8);
+                string passphrase = reader.ReadLine();
+                passwordFile.Close();
+
+                DoTestKey(keyId, passphrase);
+
+                // all fine!
+            }
+            catch (Exception e)
+            {
+                Console.Error.WriteLine(e.StackTrace);
+                Assert.Fail(e.Message);
+            }
+        }
+
+        private PgpSecretKeyRingBundle LoadSecretKeyCollection(string keyName)
+        {
+            return new PgpSecretKeyRingBundle(SimpleTest.GetTestDataAsStream("openpgp.unicode." + keyName));
+        }
+
+        public static void Main(string[] args)
+        {
+            Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty);
+        }
+
+        [Suite]
+        public static TestSuite Suite
+        {
+            get
+            {
+                TestSuite suite = new TestSuite("Unicode Password Tests");
+                suite.Add(new PgpUnicodeTest());
+                return suite;
+            }
+        }
+    }
+}
diff --git a/crypto/test/src/openpgp/test/RegressionTest.cs b/crypto/test/src/openpgp/test/RegressionTest.cs
index e8a3685c6..c784a19c8 100644
--- a/crypto/test/src/openpgp/test/RegressionTest.cs
+++ b/crypto/test/src/openpgp/test/RegressionTest.cs
@@ -20,6 +20,10 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
             new PgpClearSignedSignatureTest(),
             new PgpCompressionTest(),
             new PGPNoPrivateKeyTest(),
+            new PgpECDHTest(),
+            new PgpECDsaTest(),
+            new PgpECMessageTest(),
+            new PgpParsingTest(),
         };
 
         public static void Main(