diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-10-12 15:49:54 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2015-10-12 15:49:54 +0700 |
commit | 06ba713c9b19102310675a6c58e07c68d8efb3c7 (patch) | |
tree | 2d4e747d988f74abca2a5513713e4ff0e8ed8e69 /crypto/test/src | |
parent | Add new file entries (diff) | |
download | BouncyCastle.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.cs | 4 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/PGPSignatureTest.cs | 2 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/PgpECDHTest.cs | 280 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/PgpECDsaTest.cs | 205 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/PgpECMessageTest.cs | 196 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/PgpKeyRingTest.cs | 34 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/PgpParsingTest.cs | 40 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/PgpUnicodeTest.cs | 137 | ||||
-rw-r--r-- | crypto/test/src/openpgp/test/RegressionTest.cs | 4 |
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( |