From 44288db4414158ac9b98a507b15e81d0d3c66ca6 Mon Sep 17 00:00:00 2001
From: Peter Dettman
+ * The program is command line driven, with the input
+ * and output files specified on the command line.
+ *
+ * The vectors are Base 64 encoded and encrypted using the password "password"
+ * (without quotes). They should all yield the same PrivateKeyInfo object.
+ */
+ [TestFixture]
+ public class EncryptedPrivateKeyInfoTest
+ : ITest
+ {
+ static byte[] sample1 = Base64.Decode(
+ "MIIBozA9BgkqhkiG9w0BBQ0wMDAbBgkqhkiG9w0BBQwwDgQIfWBDXwLp4K4CAggA"
+ + "MBEGBSsOAwIHBAiaCF/AvOgQ6QSCAWDWX4BdAzCRNSQSANSuNsT5X8mWYO27mr3Y"
+ + "9c9LoBVXGNmYWKA77MI4967f7SmjNcgXj3xNE/jmnVz6hhsjS8E5VPT3kfyVkpdZ"
+ + "0lr5e9Yk2m3JWpPU7++v5zBkZmC4V/MwV/XuIs6U+vykgzMgpxQg0oZKS9zgmiZo"
+ + "f/4dOCL0UtCDnyOSvqT7mCVIcMDIEKu8QbVlgZYBop08l60EuEU3gARUo8WsYQmO"
+ + "Dz/ldx0Z+znIT0SXVuOwc+RVItC5T/Qx+aijmmpt+9l14nmaGBrEkmuhmtdvU/4v"
+ + "aptewGRgmjOfD6cqK+zs0O5NrrJ3P/6ZSxXj91CQgrThGfOv72bUncXEMNtc8pks"
+ + "2jpHFjGMdKufnadAD7XuMgzkkaklEXZ4f5tU6heIIwr51g0GBEGF96gYPFnjnSQM"
+ + "75JE02Clo+DfcfXpcybPTwwFg2jd6JTTOfkdf6OdSlA/1XNK43FA");
+
+ static byte[] sample2 = Base64.Decode(
+ "MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIeFeOWl1jywYCAggA"
+ + "MBQGCCqGSIb3DQMHBAjUJ5eGBhQGtQSCAWBrHrRgqO8UUMLcWzZEtpk1l3mjxiF/"
+ + "koCMkHsFwowgyWhEbgIkTgbSViK54LVK8PskekcGNLph+rB6bGZ7pPbL5pbXASJ8"
+ + "+MkQcG3FZdlS4Ek9tTJDApj3O1UubZGFG4uvTlJJFbF1BOJ3MkY3XQ9Gl1qwv7j5"
+ + "6e103Da7Cq9+oIDKmznza78XXQYrUsPo8mJGjUxPskEYlzwvHjKubRnYm/K6RKhi"
+ + "5f4zX4BQ/Dt3H812ZjRXrsjAJP0KrD/jyD/jCT7zNBVPH1izBds+RwizyQAHwfNJ"
+ + "BFR78TH4cgzB619X47FDVOnT0LqQNVd0O3cSwnPrXE9XR3tPayE+iOB15llFSmi8"
+ + "z0ByOXldEpkezCn92Umk++suzIVj1qfsK+bv2phZWJPbLEIWPDRHUbYf76q5ArAr"
+ + "u4xtxT/hoK3krEs/IN3d70qjlUJ36SEw1UaZ82PWhakQbdtu39ZraMJB");
+
+ static byte[] sample3 = Base64.Decode(
+ "MIIBrjBIBgkqhkiG9w0BBQ0wOzAeBgkqhkiG9w0BBQwwEQQIrHyQPBZqWLUCAggA"
+ + "AgEQMBkGCCqGSIb3DQMCMA0CAToECEhbh7YZKiPSBIIBYCT1zp6o5jpFlIkgwPop"
+ + "7bW1+8ACr4exqzkeb3WflQ8cWJ4cURxzVdvxUnXeW1VJdaQZtjS/QHs5GhPTG/0f"
+ + "wtvnaPfwrIJ3FeGaZfcg2CrYhalOFmEb4xrE4KyoEQmUN8tb/Cg94uzd16BOPw21"
+ + "RDnE8bnPdIGY7TyL95kbkqH23mK53pi7h+xWIgduW+atIqDyyt55f7WMZcvDvlj6"
+ + "VpN/V0h+qxBHL274WA4dj6GYgeyUFpi60HdGCK7By2TBy8h1ZvKGjmB9h8jZvkx1"
+ + "MkbRumXxyFsowTZawyYvO8Um6lbfEDP9zIEUq0IV8RqH2MRyblsPNSikyYhxX/cz"
+ + "tdDxRKhilySbSBg5Kr8OfcwKp9bpinN96nmG4xr3Tch1bnVvqJzOQ5+Vva2WwVvH"
+ + "2JkWvYm5WaANg4Q6bRxu9vz7DuhbJjQdZbxFezIAgrJdSe92B00jO/0Kny1WjiVO"
+ + "6DA=");
+
+ public string Name
+ {
+ get { return "EncryptedPrivateKeyInfoTest"; }
+ }
+
+ private ITestResult DoTest(
+ int id,
+ byte[] sample)
+ {
+ EncryptedPrivateKeyInfo info;
+ try
+ {
+ info = EncryptedPrivateKeyInfo.GetInstance(Asn1Object.FromByteArray(sample));
+ }
+ catch (Exception e)
+ {
+ return new SimpleTestResult(false, Name + ": test " + id + " failed construction - exception "
+ + e.ToString());
+ }
+
+ byte[] bytes;
+ try
+ {
+ bytes = info.GetDerEncoded();
+ }
+ catch (Exception e)
+ {
+ return new SimpleTestResult(false,
+ Name + ": test " + id + " failed writing - exception " + e.ToString());
+ }
+
+ if (!Arrays.AreEqual(bytes, sample))
+ {
+ try
+ {
+ Asn1Object obj = Asn1Object.FromByteArray(bytes);
+
+ return new SimpleTestResult(false, Name + ": test " + id
+ + " length mismatch - expected " + sample.Length + SimpleTest.NewLine
+ + Asn1Dump.DumpAsString(info) + " got " + bytes.Length + SimpleTest.NewLine
+ + Asn1Dump.DumpAsString(obj));
+ }
+ catch (Exception e)
+ {
+ return new SimpleTestResult(false, Name + ": test " + id + " data mismatch - exception " + e.ToString());
+ }
+ }
+
+ return new SimpleTestResult(true, Name + ": test " + id + " Okay");
+ }
+
+ public ITestResult Perform()
+ {
+ ITestResult result = DoTest(0, sample1);
+ if (!result.IsSuccessful())
+ {
+ return result;
+ }
+
+ result = DoTest(1, sample2);
+ if (!result.IsSuccessful())
+ {
+ return result;
+ }
+
+ result = DoTest(2, sample3);
+ if (!result.IsSuccessful())
+ {
+ return result;
+ }
+
+ return new SimpleTestResult(true, Name + ": Okay");
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ ITest test = new EncryptedPrivateKeyInfoTest();
+ ITestResult result = test.Perform();
+
+ Console.WriteLine(result);
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/EqualsAndHashCodeTest.cs b/crypto/test/src/asn1/test/EqualsAndHashCodeTest.cs
new file mode 100644
index 000000000..21172f816
--- /dev/null
+++ b/crypto/test/src/asn1/test/EqualsAndHashCodeTest.cs
@@ -0,0 +1,94 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class EqualsAndHashCodeTest
+ : SimpleTest
+ {
+ public override void PerformTest()
+ {
+ byte[] data = { 0, 1, 0, 1, 0, 0, 1 };
+
+ Asn1Object[] values =
+ {
+ new BerOctetString(data),
+ new BerSequence(new DerPrintableString("hello world")),
+ new BerSet(new DerPrintableString("hello world")),
+ new BerTaggedObject(0, new DerPrintableString("hello world")),
+ new DerApplicationSpecific(0, data),
+ new DerBitString(data),
+ new DerBmpString("hello world"),
+ DerBoolean.True,
+ DerBoolean.False,
+ new DerEnumerated(100),
+ new DerGeneralizedTime("20070315173729Z"),
+ new DerGeneralString("hello world"),
+ new DerIA5String("hello"),
+ new DerInteger(1000),
+ DerNull.Instance,
+ new DerNumericString("123456"),
+ new DerObjectIdentifier("1.1.1.10000.1"),
+ new DerOctetString(data),
+ new DerPrintableString("hello world"),
+ new DerSequence(new DerPrintableString("hello world")),
+ new DerSet(new DerPrintableString("hello world")),
+ new DerT61String("hello world"),
+ new DerTaggedObject(0, new DerPrintableString("hello world")),
+ new DerUniversalString(data),
+ new DerUnknownTag(true, 500, data),
+ new DerUtcTime(new DateTime()),
+ new DerUtf8String("hello world"),
+ new DerVisibleString("hello world")
+ };
+
+ MemoryStream bOut = new MemoryStream();
+ Asn1OutputStream aOut = new Asn1OutputStream(bOut);
+
+ for (int i = 0; i != values.Length; i++)
+ {
+ aOut.WriteObject(values[i]);
+ }
+
+ Asn1InputStream aIn = new Asn1InputStream(bOut.ToArray());
+
+ for (int i = 0; i != values.Length; i++)
+ {
+ Asn1Object o = aIn.ReadObject();
+ if (!o.Equals(values[i]))
+ {
+ Fail("Failed equality test for " + o.GetType().Name);
+ }
+
+ if (o.GetHashCode() != values[i].GetHashCode())
+ {
+ Fail("Failed hashCode test for " + o.GetType().Name);
+ }
+ }
+ }
+
+ public override string Name
+ {
+ get { return "EqualsAndHashCode"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new EqualsAndHashCodeTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/EssCertIDv2UnitTest.cs b/crypto/test/src/asn1/test/EssCertIDv2UnitTest.cs
new file mode 100644
index 000000000..9aac777e1
--- /dev/null
+++ b/crypto/test/src/asn1/test/EssCertIDv2UnitTest.cs
@@ -0,0 +1,46 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Ess;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class EssCertIDv2UnitTest
+ : Asn1UnitTest
+ {
+ public override string Name
+ {
+ get { return "ESSCertIDv2"; }
+ }
+
+ public override void PerformTest()
+ {
+ // check GetInstance on default algorithm.
+ byte[] digest = new byte[32];
+ EssCertIDv2 essCertIdv2 = new EssCertIDv2(
+ new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256), digest);
+ Asn1Object asn1Object = essCertIdv2.ToAsn1Object();
+
+ EssCertIDv2.GetInstance(asn1Object);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new EssCertIDv2UnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/GeneralNameTest.cs b/crypto/test/src/asn1/test/GeneralNameTest.cs
new file mode 100644
index 000000000..e9c3b5861
--- /dev/null
+++ b/crypto/test/src/asn1/test/GeneralNameTest.cs
@@ -0,0 +1,116 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class GeneralNameTest
+ : SimpleTest
+ {
+ private static readonly byte[] ipv4 = Hex.Decode("87040a090800");
+ private static readonly byte[] ipv4WithMask = Hex.Decode("87080a090800ffffff00");
+
+ private static readonly byte[] ipv6a = Hex.Decode("871020010db885a308d313198a2e03707334");
+ private static readonly byte[] ipv6b = Hex.Decode("871020010db885a3000013198a2e03707334");
+ private static readonly byte[] ipv6c = Hex.Decode("871000000000000000000000000000000001");
+ private static readonly byte[] ipv6d = Hex.Decode("871020010db885a3000000008a2e03707334");
+ private static readonly byte[] ipv6e = Hex.Decode("871020010db885a3000000008a2e0a090800");
+ private static readonly byte[] ipv6f = Hex.Decode("872020010db885a3000000008a2e0a090800ffffffffffff00000000000000000000");
+ private static readonly byte[] ipv6g = Hex.Decode("872020010db885a3000000008a2e0a090800ffffffffffffffffffffffffffffffff");
+ private static readonly byte[] ipv6h = Hex.Decode("872020010db885a300000000000000000000ffffffffffff00000000000000000000");
+
+ public override string Name
+ {
+ get { return "GeneralName"; }
+ }
+
+ public override void PerformTest()
+ {
+ GeneralName nm = new GeneralName(GeneralName.IPAddress, "10.9.8.0");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv4))
+ {
+ Fail("ipv4 encoding failed");
+ }
+
+ nm = new GeneralName(GeneralName.IPAddress, "10.9.8.0/255.255.255.0");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv4WithMask))
+ {
+ Fail("ipv4 with netmask 1 encoding failed");
+ }
+
+ nm = new GeneralName(GeneralName.IPAddress, "10.9.8.0/24");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv4WithMask))
+ {
+ Fail("ipv4 with netmask 2 encoding failed");
+ }
+
+ nm = new GeneralName(GeneralName.IPAddress, "2001:0db8:85a3:08d3:1319:8a2e:0370:7334");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv6a))
+ {
+ Fail("ipv6 with netmask encoding failed");
+ }
+
+ nm = new GeneralName(GeneralName.IPAddress, "2001:0db8:85a3::1319:8a2e:0370:7334");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv6b))
+ {
+ Fail("ipv6b encoding failed");
+ }
+
+ nm = new GeneralName(GeneralName.IPAddress, "::1");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv6c))
+ {
+ Fail("ipv6c failed");
+ }
+
+ nm = new GeneralName(GeneralName.IPAddress, "2001:0db8:85a3::8a2e:0370:7334");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv6d))
+ {
+ Fail("ipv6d failed");
+ }
+
+ nm = new GeneralName(GeneralName.IPAddress, "2001:0db8:85a3::8a2e:10.9.8.0");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv6e))
+ {
+ Fail("ipv6e failed");
+ }
+
+ nm = new GeneralName(GeneralName.IPAddress, "2001:0db8:85a3::8a2e:10.9.8.0/ffff:ffff:ffff::0000");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv6f))
+ {
+ Fail("ipv6f failed");
+ }
+
+ nm = new GeneralName(GeneralName.IPAddress, "2001:0db8:85a3::8a2e:10.9.8.0/128");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv6g))
+ {
+ Fail("ipv6g failed");
+ }
+
+ nm = new GeneralName(GeneralName.IPAddress, "2001:0db8:85a3::/48");
+ if (!Arrays.AreEqual(nm.GetEncoded(), ipv6h))
+ {
+ Fail("ipv6h failed");
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new GeneralNameTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(resultText, Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/GeneralizedTimeTest.cs b/crypto/test/src/asn1/test/GeneralizedTimeTest.cs
new file mode 100644
index 000000000..b169cfea8
--- /dev/null
+++ b/crypto/test/src/asn1/test/GeneralizedTimeTest.cs
@@ -0,0 +1,193 @@
+using System;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ /**
+ * X.690 test example
+ */
+ public class GeneralizedTimeTest
+ : SimpleTest
+ {
+ private static readonly string[] input =
+ {
+ "20020122122220",
+ "20020122122220Z",
+ "20020122122220-1000",
+ "20020122122220+00",
+ "20020122122220.1",
+ "20020122122220.1Z",
+ "20020122122220.1-1000",
+ "20020122122220.1+00",
+ "20020122122220.01",
+ "20020122122220.01Z",
+ "20020122122220.01-1000",
+ "20020122122220.01+00",
+ "20020122122220.001",
+ "20020122122220.001Z",
+ "20020122122220.001-1000",
+ "20020122122220.001+00",
+ "20020122122220.0001",
+ "20020122122220.0001Z",
+ "20020122122220.0001-1000",
+ "20020122122220.0001+00",
+ "20020122122220.0001+1000"
+ };
+
+ private static readonly string[] output =
+ {
+ "20020122122220",
+ "20020122122220GMT+00:00",
+ "20020122122220GMT-10:00",
+ "20020122122220GMT+00:00",
+ "20020122122220.1",
+ "20020122122220.1GMT+00:00",
+ "20020122122220.1GMT-10:00",
+ "20020122122220.1GMT+00:00",
+ "20020122122220.01",
+ "20020122122220.01GMT+00:00",
+ "20020122122220.01GMT-10:00",
+ "20020122122220.01GMT+00:00",
+ "20020122122220.001",
+ "20020122122220.001GMT+00:00",
+ "20020122122220.001GMT-10:00",
+ "20020122122220.001GMT+00:00",
+ "20020122122220.0001",
+ "20020122122220.0001GMT+00:00",
+ "20020122122220.0001GMT-10:00",
+ "20020122122220.0001GMT+00:00",
+ "20020122122220.0001GMT+10:00"
+ };
+
+ private static readonly string[] zOutput =
+ {
+ "20020122122220Z",
+ "20020122122220Z",
+ "20020122222220Z",
+ "20020122122220Z",
+ "20020122122220Z",
+ "20020122122220Z",
+ "20020122222220Z",
+ "20020122122220Z",
+ "20020122122220Z",
+ "20020122122220Z",
+ "20020122222220Z",
+ "20020122122220Z",
+ "20020122122220Z",
+ "20020122122220Z",
+ "20020122222220Z",
+ "20020122122220Z",
+ "20020122122220Z",
+ "20020122122220Z",
+ "20020122222220Z",
+ "20020122122220Z",
+ "20020122022220Z"
+ };
+
+ private static readonly string[] mzOutput =
+ {
+ "20020122122220.000Z",
+ "20020122122220.000Z",
+ "20020122222220.000Z",
+ "20020122122220.000Z",
+ "20020122122220.100Z",
+ "20020122122220.100Z",
+ "20020122222220.100Z",
+ "20020122122220.100Z",
+ "20020122122220.010Z",
+ "20020122122220.010Z",
+ "20020122222220.010Z",
+ "20020122122220.010Z",
+ "20020122122220.001Z",
+ "20020122122220.001Z",
+ "20020122222220.001Z",
+ "20020122122220.001Z",
+ "20020122122220.000Z",
+ "20020122122220.000Z",
+ "20020122222220.000Z",
+ "20020122122220.000Z",
+ "20020122022220.000Z"
+ };
+
+ public override string Name
+ {
+ get { return "GeneralizedTime"; }
+ }
+
+ public override void PerformTest()
+ {
+ for (int i = 0; i != input.Length; i++)
+ {
+ DerGeneralizedTime t = new DerGeneralizedTime(input[i]);
+
+ if (output[i].IndexOf('G') > 0) // don't check local time the same way
+ {
+ if (!t.GetTime().Equals(output[i]))
+ {
+ Fail("failed conversion test");
+ }
+
+ if (!t.ToDateTime().ToString(@"yyyyMMddHHmmss\Z").Equals(zOutput[i]))
+ {
+ Fail("failed date conversion test");
+ }
+ }
+ else
+ {
+ string offset = CalculateGmtOffset(t.ToDateTime());
+ if (!t.GetTime().Equals(output[i] + offset))
+ {
+ Fail("failed conversion test");
+ }
+ }
+ }
+
+ for (int i = 0; i != input.Length; i++)
+ {
+ DerGeneralizedTime t = new DerGeneralizedTime(input[i]);
+
+ if (!t.ToDateTime().ToString(@"yyyyMMddHHmmss.fff\Z").Equals(mzOutput[i]))
+ {
+ Console.WriteLine("{0} != {1}", t.ToDateTime().ToString(@"yyyyMMddHHmmss.SSS\Z"), mzOutput[i]);
+
+ Fail("failed long date conversion test");
+ }
+ }
+ }
+
+ private string CalculateGmtOffset(
+ DateTime date)
+ {
+ char sign = '+';
+
+ // Note: GetUtcOffset incorporates Daylight Savings offset
+ TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset(date);
+ if (offset.CompareTo(TimeSpan.Zero) < 0)
+ {
+ sign = '-';
+ offset = offset.Duration();
+ }
+ int hours = offset.Hours;
+ int minutes = offset.Minutes;
+
+ return "GMT" + sign + Convert(hours) + ":" + Convert(minutes);
+ }
+
+ private string Convert(int time)
+ {
+ if (time < 10)
+ {
+ return "0" + time;
+ }
+
+ return time.ToString();
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new GeneralizedTimeTest());
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/GenerationTest.cs b/crypto/test/src/asn1/test/GenerationTest.cs
new file mode 100644
index 000000000..5acf8e149
--- /dev/null
+++ b/crypto/test/src/asn1/test/GenerationTest.cs
@@ -0,0 +1,325 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class GenerationTest
+ : SimpleTest
+ {
+ private static readonly byte[] v1Cert = Base64.Decode(
+ "MIGtAgEBMA0GCSqGSIb3DQEBBAUAMCUxCzAJBgNVBAMMAkFVMRYwFAYDVQQKDA1Cb"
+ + "3VuY3kgQ2FzdGxlMB4XDTcwMDEwMTAwMDAwMVoXDTcwMDEwMTAwMDAxMlowNjELMA"
+ + "kGA1UEAwwCQVUxFjAUBgNVBAoMDUJvdW5jeSBDYXN0bGUxDzANBgNVBAsMBlRlc3Q"
+ + "gMTAaMA0GCSqGSIb3DQEBAQUAAwkAMAYCAQECAQI=");
+
+ private static readonly byte[] v3Cert = Base64.Decode(
+ "MIIBSKADAgECAgECMA0GCSqGSIb3DQEBBAUAMCUxCzAJBgNVBAMMAkFVMRYwFAYD"
+ + "VQQKDA1Cb3VuY3kgQ2FzdGxlMB4XDTcwMDEwMTAwMDAwMVoXDTcwMDEwMTAwMDAw"
+ + "MlowNjELMAkGA1UEAwwCQVUxFjAUBgNVBAoMDUJvdW5jeSBDYXN0bGUxDzANBgNV"
+ + "BAsMBlRlc3QgMjAYMBAGBisOBwIBATAGAgEBAgECAwQAAgEDo4GVMIGSMGEGA1Ud"
+ + "IwEB/wRXMFWAFDZPdpHPzKi7o8EJokkQU2uqCHRRoTqkODA2MQswCQYDVQQDDAJB"
+ + "VTEWMBQGA1UECgwNQm91bmN5IENhc3RsZTEPMA0GA1UECwwGVGVzdCAyggECMCAG"
+ + "A1UdDgEB/wQWBBQ2T3aRz8you6PBCaJJEFNrqgh0UTALBgNVHQ8EBAMCBBA=");
+
+ private static readonly byte[] v3CertNullSubject = Base64.Decode(
+ "MIHGoAMCAQICAQIwDQYJKoZIhvcNAQEEBQAwJTELMAkGA1UEAwwCQVUxFjAUBgNVB"
+ + "AoMDUJvdW5jeSBDYXN0bGUwHhcNNzAwMTAxMDAwMDAxWhcNNzAwMTAxMDAwMDAyWj"
+ + "AAMBgwEAYGKw4HAgEBMAYCAQECAQIDBAACAQOjSjBIMEYGA1UdEQEB/wQ8MDqkODA"
+ + "2MQswCQYDVQQDDAJBVTEWMBQGA1UECgwNQm91bmN5IENhc3RsZTEPMA0GA1UECwwG"
+ + "VGVzdCAy");
+
+ private static readonly byte[] v2CertList = Base64.Decode(
+ "MIIBRQIBATANBgkqhkiG9w0BAQUFADAlMQswCQYDVQQDDAJBVTEWMBQGA1UECgwN"
+ + "Qm91bmN5IENhc3RsZRcNNzAwMTAxMDAwMDAwWhcNNzAwMTAxMDAwMDAyWjAkMCIC"
+ + "AQEXDTcwMDEwMTAwMDAwMVowDjAMBgNVHRUEBQoDAIAAoIHFMIHCMGEGA1UdIwEB"
+ + "/wRXMFWAFDZPdpHPzKi7o8EJokkQU2uqCHRRoTqkODA2MQswCQYDVQQDDAJBVTEW"
+ + "MBQGA1UECgwNQm91bmN5IENhc3RsZTEPMA0GA1UECwwGVGVzdCAyggECMEMGA1Ud"
+ + "EgQ8MDqkODA2MQswCQYDVQQDDAJBVTEWMBQGA1UECgwNQm91bmN5IENhc3RsZTEP"
+ + "MA0GA1UECwwGVGVzdCAzMAoGA1UdFAQDAgEBMAwGA1UdHAEB/wQCMAA=");
+
+ private void TbsV1CertGenerate()
+ {
+ V1TbsCertificateGenerator gen = new V1TbsCertificateGenerator();
+ DateTime startDate = new DateTime(1970, 1, 1, 0, 0, 1);
+ DateTime endDate = new DateTime(1970, 1, 1, 0, 0, 12);
+
+ gen.SetSerialNumber(new DerInteger(1));
+
+ gen.SetStartDate(new Time(startDate));
+ gen.SetEndDate(new Time(endDate));
+
+ gen.SetIssuer(new X509Name("CN=AU,O=Bouncy Castle"));
+ gen.SetSubject(new X509Name("CN=AU,O=Bouncy Castle,OU=Test 1"));
+
+ gen.SetSignature(new AlgorithmIdentifier(PkcsObjectIdentifiers.MD5WithRsaEncryption, DerNull.Instance));
+
+ SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance),
+ new RsaPublicKeyStructure(BigInteger.One, BigInteger.Two));
+
+ gen.SetSubjectPublicKeyInfo(info);
+
+ TbsCertificateStructure tbs = gen.GenerateTbsCertificate();
+
+ if (!Arrays.AreEqual(tbs.GetEncoded(), v1Cert))
+ {
+ Fail("failed v1 cert generation");
+ }
+
+ //
+ // read back test
+ //
+ Asn1InputStream aIn = new Asn1InputStream(v1Cert);
+ Asn1Object o = aIn.ReadObject();
+
+ if (!Arrays.AreEqual(o.GetEncoded(), v1Cert))
+ {
+ Fail("failed v1 cert read back test");
+ }
+ }
+
+ private AuthorityKeyIdentifier CreateAuthorityKeyId(
+ SubjectPublicKeyInfo info,
+ X509Name name,
+ int sNumber)
+ {
+ GeneralName genName = new GeneralName(name);
+
+ return new AuthorityKeyIdentifier(
+ info,
+ GeneralNames.GetInstance(new DerSequence(genName)),
+ BigInteger.ValueOf(sNumber));
+ }
+
+ private void TbsV3CertGenerate()
+ {
+ V3TbsCertificateGenerator gen = new V3TbsCertificateGenerator();
+ DateTime startDate = new DateTime(1970, 1, 1, 0, 0, 1);
+ DateTime endDate = new DateTime(1970, 1, 1, 0, 0, 2);
+
+ gen.SetSerialNumber(new DerInteger(2));
+
+ gen.SetStartDate(new Time(startDate));
+ gen.SetEndDate(new Time(endDate));
+
+ gen.SetIssuer(new X509Name("CN=AU,O=Bouncy Castle"));
+ gen.SetSubject(new X509Name("CN=AU,O=Bouncy Castle,OU=Test 2"));
+
+ gen.SetSignature(new AlgorithmIdentifier(PkcsObjectIdentifiers.MD5WithRsaEncryption, DerNull.Instance));
+
+ SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
+ new AlgorithmIdentifier(
+ OiwObjectIdentifiers.ElGamalAlgorithm,
+ new ElGamalParameter(BigInteger.One, BigInteger.Two)),
+ new DerInteger(3));
+
+ gen.SetSubjectPublicKeyInfo(info);
+
+ //
+ // add extensions
+ //
+ IList order = new ArrayList();
+ IDictionary extensions = new Hashtable();
+
+ order.Add(X509Extensions.AuthorityKeyIdentifier);
+ order.Add(X509Extensions.SubjectKeyIdentifier);
+ order.Add(X509Extensions.KeyUsage);
+
+ extensions.Add(X509Extensions.AuthorityKeyIdentifier, new X509Extension(true, new DerOctetString(CreateAuthorityKeyId(info, new X509Name("CN=AU,O=Bouncy Castle,OU=Test 2"), 2))));
+ extensions.Add(X509Extensions.SubjectKeyIdentifier, new X509Extension(true, new DerOctetString(new SubjectKeyIdentifier(info))));
+ extensions.Add(X509Extensions.KeyUsage, new X509Extension(false, new DerOctetString(new KeyUsage(KeyUsage.DataEncipherment))));
+
+ X509Extensions ex = new X509Extensions(order, extensions);
+
+ gen.SetExtensions(ex);
+
+ TbsCertificateStructure tbs = gen.GenerateTbsCertificate();
+
+ if (!Arrays.AreEqual(tbs.GetEncoded(), v3Cert))
+ {
+ Fail("failed v3 cert generation");
+ }
+
+ //
+ // read back test
+ //
+ Asn1Object o = Asn1Object.FromByteArray(v3Cert);
+
+ if (!Arrays.AreEqual(o.GetEncoded(), v3Cert))
+ {
+ Fail("failed v3 cert read back test");
+ }
+ }
+
+ private void TbsV3CertGenWithNullSubject()
+ {
+ V3TbsCertificateGenerator gen = new V3TbsCertificateGenerator();
+ DateTime startDate = new DateTime(1970, 1, 1, 0, 0, 1);
+ DateTime endDate = new DateTime(1970, 1, 1, 0, 0, 2);
+
+ gen.SetSerialNumber(new DerInteger(2));
+
+ gen.SetStartDate(new Time(startDate));
+ gen.SetEndDate(new Time(endDate));
+
+ gen.SetIssuer(new X509Name("CN=AU,O=Bouncy Castle"));
+
+ gen.SetSignature(new AlgorithmIdentifier(PkcsObjectIdentifiers.MD5WithRsaEncryption, DerNull.Instance));
+
+ SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
+ new AlgorithmIdentifier(OiwObjectIdentifiers.ElGamalAlgorithm,
+ new ElGamalParameter(BigInteger.One, BigInteger.Two)),
+ new DerInteger(3));
+
+ gen.SetSubjectPublicKeyInfo(info);
+
+ try
+ {
+ gen.GenerateTbsCertificate();
+ Fail("null subject not caught!");
+ }
+ catch (InvalidOperationException e)
+ {
+ if (!e.Message.Equals("not all mandatory fields set in V3 TBScertificate generator"))
+ {
+ Fail("unexpected exception", e);
+ }
+ }
+
+ //
+ // add extensions
+ //
+ IList order = new ArrayList();
+ IDictionary extensions = new Hashtable();
+
+ order.Add(X509Extensions.SubjectAlternativeName);
+
+ extensions.Add(
+ X509Extensions.SubjectAlternativeName,
+ new X509Extension(
+ true,
+ new DerOctetString(
+ new GeneralNames(
+ new GeneralName(
+ new X509Name("CN=AU,O=Bouncy Castle,OU=Test 2"))))));
+
+ X509Extensions ex = new X509Extensions(order, extensions);
+
+ gen.SetExtensions(ex);
+
+ TbsCertificateStructure tbs = gen.GenerateTbsCertificate();
+
+ if (!Arrays.AreEqual(tbs.GetEncoded(), v3CertNullSubject))
+ {
+ Fail("failed v3 null sub cert generation");
+ }
+
+ //
+ // read back test
+ //
+ Asn1Object o = Asn1Object.FromByteArray(v3CertNullSubject);
+
+ if (!Arrays.AreEqual(o.GetEncoded(), v3CertNullSubject))
+ {
+ Fail("failed v3 null sub cert read back test");
+ }
+ }
+
+ private void TbsV2CertListGenerate()
+ {
+ V2TbsCertListGenerator gen = new V2TbsCertListGenerator();
+
+ gen.SetIssuer(new X509Name("CN=AU,O=Bouncy Castle"));
+
+ gen.AddCrlEntry(new DerInteger(1), new Time(new DateTime(1970, 1, 1, 0, 0, 1)), ReasonFlags.AACompromise);
+
+ gen.SetNextUpdate(new Time(new DateTime(1970, 1, 1, 0, 0, 2)));
+
+ gen.SetThisUpdate(new Time(new DateTime(1970, 1, 1, 0, 0, 0, 500)));
+
+ gen.SetSignature(new AlgorithmIdentifier(PkcsObjectIdentifiers.Sha1WithRsaEncryption, DerNull.Instance));
+
+ //
+ // extensions
+ //
+ IList order = new ArrayList();
+ IDictionary extensions = new Hashtable();
+ SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
+ new AlgorithmIdentifier(
+ OiwObjectIdentifiers.ElGamalAlgorithm,
+ new ElGamalParameter(BigInteger.One, BigInteger.Two)),
+ new DerInteger(3));
+
+ order.Add(X509Extensions.AuthorityKeyIdentifier);
+ order.Add(X509Extensions.IssuerAlternativeName);
+ order.Add(X509Extensions.CrlNumber);
+ order.Add(X509Extensions.IssuingDistributionPoint);
+
+ extensions.Add(X509Extensions.AuthorityKeyIdentifier, new X509Extension(true, new DerOctetString(CreateAuthorityKeyId(info, new X509Name("CN=AU,O=Bouncy Castle,OU=Test 2"), 2))));
+ extensions.Add(X509Extensions.IssuerAlternativeName, new X509Extension(false, new DerOctetString(GeneralNames.GetInstance(new DerSequence(new GeneralName(new X509Name("CN=AU,O=Bouncy Castle,OU=Test 3")))))));
+ extensions.Add(X509Extensions.CrlNumber, new X509Extension(false, new DerOctetString(new DerInteger(1))));
+ extensions.Add(X509Extensions.IssuingDistributionPoint, new X509Extension(true, new DerOctetString(IssuingDistributionPoint.GetInstance(DerSequence.Empty))));
+
+ X509Extensions ex = new X509Extensions(order, extensions);
+
+ gen.SetExtensions(ex);
+
+ TbsCertificateList tbs = gen.GenerateTbsCertList();
+
+ if (!Arrays.AreEqual(tbs.GetEncoded(), v2CertList))
+ {
+ Fail("failed v2 cert list generation");
+ }
+
+ //
+ // read back test
+ //
+ Asn1InputStream aIn = new Asn1InputStream(v2CertList);
+ Asn1Object o = aIn.ReadObject();
+
+ if (!Arrays.AreEqual(o.GetEncoded(), v2CertList))
+ {
+ Fail("failed v2 cert list read back test");
+ }
+ }
+
+ public override void PerformTest()
+ {
+ TbsV1CertGenerate();
+ TbsV3CertGenerate();
+ TbsV3CertGenWithNullSubject();
+ TbsV2CertListGenerate();
+ }
+
+ public override string Name
+ {
+ get { return "Generation"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new GenerationTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(resultText, Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/InputStreamTest.cs b/crypto/test/src/asn1/test/InputStreamTest.cs
new file mode 100644
index 000000000..1d92759e0
--- /dev/null
+++ b/crypto/test/src/asn1/test/InputStreamTest.cs
@@ -0,0 +1,85 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class InputStreamTest
+ : SimpleTest
+ {
+ private static readonly byte[] outOfBoundsLength = new byte[] { (byte)0x30, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff };
+ private static readonly byte[] negativeLength = new byte[] { (byte)0x30, (byte)0x84, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff };
+ private static readonly byte[] outsideLimitLength = new byte[] { (byte)0x30, (byte)0x83, (byte)0x0f, (byte)0xff, (byte)0xff };
+
+ public override string Name
+ {
+ get { return "InputStream"; }
+ }
+
+ public override void PerformTest()
+ {
+ Asn1InputStream aIn = new Asn1InputStream(outOfBoundsLength);
+
+ try
+ {
+ aIn.ReadObject();
+ Fail("out of bounds length not detected.");
+ }
+ catch (IOException e)
+ {
+ if (!e.Message.StartsWith("DER length more than 4 bytes"))
+ {
+ Fail("wrong exception: " + e.Message);
+ }
+ }
+
+ aIn = new Asn1InputStream(negativeLength);
+
+ try
+ {
+ aIn.ReadObject();
+ Fail("negative length not detected.");
+ }
+ catch (IOException e)
+ {
+ if (!e.Message.Equals("Corrupted stream - negative length found"))
+ {
+ Fail("wrong exception: " + e.Message);
+ }
+ }
+
+ aIn = new Asn1InputStream(outsideLimitLength);
+
+ try
+ {
+ aIn.ReadObject();
+ Fail("outside limit length not detected.");
+ }
+ catch (IOException e)
+ {
+ if (!e.Message.Equals("Corrupted stream - out of bounds length found"))
+ {
+ Fail("wrong exception: " + e.Message);
+ }
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new InputStreamTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/Iso4217CurrencyCodeUnitTest.cs b/crypto/test/src/asn1/test/Iso4217CurrencyCodeUnitTest.cs
new file mode 100644
index 000000000..bb6076a93
--- /dev/null
+++ b/crypto/test/src/asn1/test/Iso4217CurrencyCodeUnitTest.cs
@@ -0,0 +1,156 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Asn1.X509.Qualified;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class Iso4217CurrencyCodeUnitTest
+ : SimpleTest
+ {
+ private const string AlphabeticCurrencyCode = "AUD";
+ private const int NUMERIC_CurrencyCode = 1;
+
+ public override string Name
+ {
+ get { return "Iso4217CurrencyCode"; }
+ }
+
+ public override void PerformTest()
+ {
+ //
+ // alphabetic
+ //
+ Iso4217CurrencyCode cc = new Iso4217CurrencyCode(AlphabeticCurrencyCode);
+
+ CheckNumeric(cc, AlphabeticCurrencyCode);
+
+ cc = Iso4217CurrencyCode.GetInstance(cc);
+
+ CheckNumeric(cc, AlphabeticCurrencyCode);
+
+ Asn1Object obj = cc.ToAsn1Object();
+
+ cc = Iso4217CurrencyCode.GetInstance(obj);
+
+ CheckNumeric(cc, AlphabeticCurrencyCode);
+
+ //
+ // numeric
+ //
+ cc = new Iso4217CurrencyCode(NUMERIC_CurrencyCode);
+
+ CheckNumeric(cc, NUMERIC_CurrencyCode);
+
+ cc = Iso4217CurrencyCode.GetInstance(cc);
+
+ CheckNumeric(cc, NUMERIC_CurrencyCode);
+
+ obj = cc.ToAsn1Object();
+
+ cc = Iso4217CurrencyCode.GetInstance(obj);
+
+ CheckNumeric(cc, NUMERIC_CurrencyCode);
+
+ cc = Iso4217CurrencyCode.GetInstance(null);
+
+ if (cc != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ Iso4217CurrencyCode.GetInstance(new object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ try
+ {
+ new Iso4217CurrencyCode("ABCD");
+
+ Fail("constructor failed to detect out of range currencycode.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ try
+ {
+ new Iso4217CurrencyCode(0);
+
+ Fail("constructor failed to detect out of range small numeric code.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ try
+ {
+ new Iso4217CurrencyCode(1000);
+
+ Fail("constructor failed to detect out of range large numeric code.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void CheckNumeric(
+ Iso4217CurrencyCode cc,
+ string code)
+ {
+ if (!cc.IsAlphabetic)
+ {
+ Fail("non-alphabetic code found when one expected.");
+ }
+
+ if (!cc.Alphabetic.Equals(code))
+ {
+ Fail("string codes don't match.");
+ }
+ }
+
+ private void CheckNumeric(
+ Iso4217CurrencyCode cc,
+ int code)
+ {
+ if (cc.IsAlphabetic)
+ {
+ Fail("alphabetic code found when one not expected.");
+ }
+
+ if (cc.Numeric != code)
+ {
+ Fail("numeric codes don't match.");
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new Iso4217CurrencyCodeUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/IssuingDistributionPointTest.cs b/crypto/test/src/asn1/test/IssuingDistributionPointTest.cs
new file mode 100644
index 000000000..b5f5c88bb
--- /dev/null
+++ b/crypto/test/src/asn1/test/IssuingDistributionPointTest.cs
@@ -0,0 +1,133 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class IssuingDistributionPointUnitTest
+ : SimpleTest
+ {
+ public override string Name
+ {
+ get { return "IssuingDistributionPoint"; }
+ }
+
+ public override void PerformTest()
+ {
+ DistributionPointName name = new DistributionPointName(
+ new GeneralNames(new GeneralName(new X509Name("cn=test"))));
+ ReasonFlags reasonFlags = new ReasonFlags(ReasonFlags.CACompromise);
+
+ checkPoint(6, name, true, true, reasonFlags, true, true);
+
+ checkPoint(2, name, false, false, reasonFlags, false, false);
+
+ checkPoint(0, null, false, false, null, false, false);
+
+ try
+ {
+ IssuingDistributionPoint.GetInstance(new object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkPoint(
+ int size,
+ DistributionPointName distributionPoint,
+ bool onlyContainsUserCerts,
+ bool onlyContainsCACerts,
+ ReasonFlags onlySomeReasons,
+ bool indirectCRL,
+ bool onlyContainsAttributeCerts)
+ {
+ IssuingDistributionPoint point = new IssuingDistributionPoint(distributionPoint, onlyContainsUserCerts, onlyContainsCACerts, onlySomeReasons, indirectCRL, onlyContainsAttributeCerts);
+
+ checkValues(point, distributionPoint, onlyContainsUserCerts, onlyContainsCACerts, onlySomeReasons, indirectCRL, onlyContainsAttributeCerts);
+
+ Asn1Sequence seq = Asn1Sequence.GetInstance(Asn1Object.FromByteArray(point.GetEncoded()));
+
+ if (seq.Count != size)
+ {
+ Fail("size mismatch");
+ }
+
+ point = IssuingDistributionPoint.GetInstance(seq);
+
+ checkValues(point, distributionPoint, onlyContainsUserCerts, onlyContainsCACerts, onlySomeReasons, indirectCRL, onlyContainsAttributeCerts);
+ }
+
+ private void checkValues(
+ IssuingDistributionPoint point,
+ DistributionPointName distributionPoint,
+ bool onlyContainsUserCerts,
+ bool onlyContainsCACerts,
+ ReasonFlags onlySomeReasons,
+ bool indirectCRL,
+ bool onlyContainsAttributeCerts)
+ {
+ if (point.OnlyContainsUserCerts != onlyContainsUserCerts)
+ {
+ Fail("mismatch on onlyContainsUserCerts");
+ }
+
+ if (point.OnlyContainsCACerts != onlyContainsCACerts)
+ {
+ Fail("mismatch on onlyContainsCACerts");
+ }
+
+ if (point.IsIndirectCrl != indirectCRL)
+ {
+ Fail("mismatch on indirectCRL");
+ }
+
+ if (point.OnlyContainsAttributeCerts != onlyContainsAttributeCerts)
+ {
+ Fail("mismatch on onlyContainsAttributeCerts");
+ }
+
+ if (!isEquiv(onlySomeReasons, point.OnlySomeReasons))
+ {
+ Fail("mismatch on onlySomeReasons");
+ }
+
+ if (!isEquiv(distributionPoint, point.DistributionPoint))
+ {
+ Fail("mismatch on distributionPoint");
+ }
+ }
+
+ private bool isEquiv(object o1, object o2)
+ {
+ if (o1 == null)
+ {
+ return o2 == null;
+ }
+
+ return o1.Equals(o2);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new IssuingDistributionPointUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/KeyUsageTest.cs b/crypto/test/src/asn1/test/KeyUsageTest.cs
new file mode 100644
index 000000000..d7ed3655d
--- /dev/null
+++ b/crypto/test/src/asn1/test/KeyUsageTest.cs
@@ -0,0 +1,49 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class KeyUsageTest
+ : SimpleTest
+ {
+ public override string Name
+ {
+ get
+ {
+ return "KeyUsage";
+ }
+ }
+
+ public override void PerformTest()
+ {
+ BitStringConstantTester.testFlagValueCorrect(0, KeyUsage.DigitalSignature);
+ BitStringConstantTester.testFlagValueCorrect(1, KeyUsage.NonRepudiation);
+ BitStringConstantTester.testFlagValueCorrect(2, KeyUsage.KeyEncipherment);
+ BitStringConstantTester.testFlagValueCorrect(3, KeyUsage.DataEncipherment);
+ BitStringConstantTester.testFlagValueCorrect(4, KeyUsage.KeyAgreement);
+ BitStringConstantTester.testFlagValueCorrect(5, KeyUsage.KeyCertSign);
+ BitStringConstantTester.testFlagValueCorrect(6, KeyUsage.CrlSign);
+ BitStringConstantTester.testFlagValueCorrect(7, KeyUsage.EncipherOnly);
+ BitStringConstantTester.testFlagValueCorrect(8, KeyUsage.DecipherOnly);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new KeyUsageTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/LDSSecurityObjectUnitTest.cs b/crypto/test/src/asn1/test/LDSSecurityObjectUnitTest.cs
new file mode 100644
index 000000000..042781632
--- /dev/null
+++ b/crypto/test/src/asn1/test/LDSSecurityObjectUnitTest.cs
@@ -0,0 +1,208 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Icao;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class LDSSecurityObjectUnitTest
+ : SimpleTest
+ {
+ public override string Name
+ {
+ get { return "LDSSecurityObject"; }
+ }
+
+ private byte[] GenerateHash()
+ {
+ Random rand = new Random();
+ byte[] bytes = new byte[20];
+ rand.NextBytes(bytes);
+ return bytes;
+ }
+
+ public override void PerformTest()
+ {
+ AlgorithmIdentifier algoId = new AlgorithmIdentifier("1.3.14.3.2.26");
+ DataGroupHash[] datas = new DataGroupHash[2];
+
+ datas[0] = new DataGroupHash(1, new DerOctetString(GenerateHash()));
+ datas[1] = new DataGroupHash(2, new DerOctetString(GenerateHash()));
+
+ LdsSecurityObject so = new LdsSecurityObject(algoId, datas);
+
+ CheckConstruction(so, algoId, datas);
+
+ LdsVersionInfo versionInfo = new LdsVersionInfo("Hello", "world");
+
+ so = new LdsSecurityObject(algoId, datas, versionInfo);
+
+ CheckConstruction(so, algoId, datas, versionInfo);
+
+ try
+ {
+ LdsSecurityObject.GetInstance(null);
+ }
+ catch (Exception)
+ {
+ Fail("GetInstance() failed to handle null.");
+ }
+
+ try
+ {
+ LdsSecurityObject.GetInstance(new object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ try
+ {
+ LdsSecurityObject.GetInstance(DerSequence.Empty);
+
+ Fail("constructor failed to detect empty sequence.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ try
+ {
+ new LdsSecurityObject(algoId, new DataGroupHash[1]);
+
+ Fail("constructor failed to detect small DataGroupHash array.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ try
+ {
+ new LdsSecurityObject(algoId, new DataGroupHash[LdsSecurityObject.UBDataGroups + 1]);
+
+ Fail("constructor failed to out of bounds DataGroupHash array.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void CheckConstruction(
+ LdsSecurityObject so,
+ AlgorithmIdentifier digestAlgorithmIdentifier,
+ DataGroupHash[] datagroupHash)
+ {
+ CheckStatement(so, digestAlgorithmIdentifier, datagroupHash, null);
+
+ so = LdsSecurityObject.GetInstance(so);
+
+ CheckStatement(so, digestAlgorithmIdentifier, datagroupHash, null);
+
+ Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(
+ so.ToAsn1Object().GetEncoded());
+
+ so = LdsSecurityObject.GetInstance(seq);
+
+ CheckStatement(so, digestAlgorithmIdentifier, datagroupHash, null);
+ }
+
+ private void CheckConstruction(
+ LdsSecurityObject so,
+ AlgorithmIdentifier digestAlgorithmIdentifier,
+ DataGroupHash[] datagroupHash,
+ LdsVersionInfo versionInfo)
+ {
+ if (!so.Version.Equals(BigInteger.One))
+ {
+ Fail("version number not 1");
+ }
+
+ CheckStatement(so, digestAlgorithmIdentifier, datagroupHash, versionInfo);
+
+ so = LdsSecurityObject.GetInstance(so);
+
+ CheckStatement(so, digestAlgorithmIdentifier, datagroupHash, versionInfo);
+
+ Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(
+ so.ToAsn1Object().GetEncoded());
+
+ so = LdsSecurityObject.GetInstance(seq);
+
+ CheckStatement(so, digestAlgorithmIdentifier, datagroupHash, versionInfo);
+ }
+
+ private void CheckStatement(
+ LdsSecurityObject so,
+ AlgorithmIdentifier digestAlgorithmIdentifier,
+ DataGroupHash[] datagroupHash,
+ LdsVersionInfo versionInfo)
+ {
+ if (digestAlgorithmIdentifier != null)
+ {
+ if (!so.DigestAlgorithmIdentifier.Equals(digestAlgorithmIdentifier))
+ {
+ Fail("ids don't match.");
+ }
+ }
+ else if (so.DigestAlgorithmIdentifier != null)
+ {
+ Fail("digest algorithm Id found when none expected.");
+ }
+
+ if (datagroupHash != null)
+ {
+ DataGroupHash[] datas = so.GetDatagroupHash();
+
+ for (int i = 0; i != datas.Length; i++)
+ {
+ if (!datagroupHash[i].Equals(datas[i]))
+ {
+ Fail("name registration authorities don't match.");
+ }
+ }
+ }
+ else if (so.GetDatagroupHash() != null)
+ {
+ Fail("data hash groups found when none expected.");
+ }
+
+ if (versionInfo != null)
+ {
+ if (!versionInfo.Equals(so.VersionInfo))
+ {
+ Fail("versionInfo doesn't match");
+ }
+ }
+ else if (so.VersionInfo != null)
+ {
+ Fail("version info found when none expected.");
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new LDSSecurityObjectUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/MiscTest.cs b/crypto/test/src/asn1/test/MiscTest.cs
new file mode 100644
index 000000000..44213c71d
--- /dev/null
+++ b/crypto/test/src/asn1/test/MiscTest.cs
@@ -0,0 +1,100 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Misc;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class MiscTest
+ : ITest
+ {
+ public ITestResult Perform()
+ {
+ byte[] testIv = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+ Asn1Encodable[] values =
+ {
+ new Cast5CbcParameters(testIv, 128),
+ new NetscapeCertType(NetscapeCertType.Smime),
+ new VerisignCzagExtension(new DerIA5String("hello")),
+#if INCLUDE_IDEA
+ new IdeaCbcPar(testIv),
+#endif
+ new NetscapeRevocationUrl(new DerIA5String("http://test"))
+ };
+
+#if INCLUDE_IDEA
+ byte[] data = Base64.Decode("MA4ECAECAwQFBgcIAgIAgAMCBSAWBWhlbGxvMAoECAECAwQFBgcIFgtodHRwOi8vdGVzdA==");
+#else
+ byte[] data = Base64.Decode("MA4ECAECAwQFBgcIAgIAgAMCBSAWBWhlbGxvFgtodHRwOi8vdGVzdA==");
+#endif
+
+ try
+ {
+ MemoryStream bOut = new MemoryStream();
+ Asn1OutputStream aOut = new Asn1OutputStream(bOut);
+
+ for (int i = 0; i != values.Length; i++)
+ {
+ aOut.WriteObject(values[i]);
+ }
+
+ if (!Arrays.AreEqual(bOut.ToArray(), data))
+ {
+ return new SimpleTestResult(false, Name + ": Failed data check");
+ }
+
+ Asn1InputStream aIn = new Asn1InputStream(bOut.ToArray());
+
+ for (int i = 0; i != values.Length; i++)
+ {
+ Asn1Object o = aIn.ReadObject();
+
+ if (!values[i].Equals(o))
+ {
+ return new SimpleTestResult(false, Name + ": Failed equality test for " + o);
+ }
+
+ if (o.GetHashCode() != values[i].GetHashCode())
+ {
+ return new SimpleTestResult(false, Name + ": Failed hashCode test for " + o);
+ }
+ }
+
+ return new SimpleTestResult(true, Name + ": Okay");
+ }
+ catch (Exception e)
+ {
+ return new SimpleTestResult(false, Name + ": Failed - exception " + e.ToString(), e);
+ }
+ }
+
+ public string Name
+ {
+ get { return "Misc"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ ITest test = new MiscTest();
+ ITestResult result = test.Perform();
+
+ Console.WriteLine(result);
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/MonetaryLimitUnitTest.cs b/crypto/test/src/asn1/test/MonetaryLimitUnitTest.cs
new file mode 100644
index 000000000..cdeb2eca5
--- /dev/null
+++ b/crypto/test/src/asn1/test/MonetaryLimitUnitTest.cs
@@ -0,0 +1,93 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.IsisMtt.X509;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class MonetaryLimitUnitTest
+ : Asn1UnitTest
+ {
+ public override string Name
+ {
+ get { return "MonetaryLimit"; }
+ }
+
+ public override void PerformTest()
+ {
+ string currency = "AUD";
+ int amount = 1;
+ int exponent = 2;
+
+ MonetaryLimit limit = new MonetaryLimit(currency, amount, exponent);
+
+ checkConstruction(limit, currency, amount, exponent);
+
+ limit = MonetaryLimit.GetInstance(null);
+
+ if (limit != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ MonetaryLimit.GetInstance(new Object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkConstruction(
+ MonetaryLimit limit,
+ string currency,
+ int amount,
+ int exponent)
+ {
+ checkValues(limit, currency, amount, exponent);
+
+ limit = MonetaryLimit.GetInstance(limit);
+
+ checkValues(limit, currency, amount, exponent);
+
+ Asn1InputStream aIn = new Asn1InputStream(limit.ToAsn1Object().GetEncoded());
+
+ Asn1Sequence seq = (Asn1Sequence) aIn.ReadObject();
+
+ limit = MonetaryLimit.GetInstance(seq);
+
+ checkValues(limit, currency, amount, exponent);
+ }
+
+ private void checkValues(
+ MonetaryLimit limit,
+ string currency,
+ int amount,
+ int exponent)
+ {
+ checkMandatoryField("currency", currency, limit.Currency);
+ checkMandatoryField("amount", amount, limit.Amount.IntValue);
+ checkMandatoryField("exponent", exponent, limit.Exponent.IntValue);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new MonetaryLimitUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/MonetaryValueUnitTest.cs b/crypto/test/src/asn1/test/MonetaryValueUnitTest.cs
new file mode 100644
index 000000000..c75d74505
--- /dev/null
+++ b/crypto/test/src/asn1/test/MonetaryValueUnitTest.cs
@@ -0,0 +1,99 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Asn1.X509.Qualified;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class MonetaryValueUnitTest
+ : SimpleTest
+ {
+ private const int TestAmount = 100;
+ private const int ZeroExponent = 0;
+
+ private const string CurrencyCode = "AUD";
+
+ public override string Name
+ {
+ get { return "MonetaryValue"; }
+ }
+
+ public override void PerformTest()
+ {
+ MonetaryValue mv = new MonetaryValue(new Iso4217CurrencyCode(CurrencyCode), TestAmount, ZeroExponent);
+
+ CheckValues(mv, TestAmount, ZeroExponent);
+
+ mv = MonetaryValue.GetInstance(mv);
+
+ CheckValues(mv, TestAmount, ZeroExponent);
+
+ Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(
+ mv.ToAsn1Object().GetEncoded());
+
+ mv = MonetaryValue.GetInstance(seq);
+
+ CheckValues(mv, TestAmount, ZeroExponent);
+
+ mv = MonetaryValue.GetInstance(null);
+
+ if (mv != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ MonetaryValue.GetInstance(new object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void CheckValues(
+ MonetaryValue mv,
+ int amount,
+ int exponent)
+ {
+ if (mv.Amount.IntValue != amount)
+ {
+ Fail("amounts don't match.");
+ }
+
+ if (mv.Exponent.IntValue != exponent)
+ {
+ Fail("exponents don't match.");
+ }
+
+ Iso4217CurrencyCode cc = mv.Currency;
+
+ if (!cc.Alphabetic.Equals(CurrencyCode))
+ {
+ Fail("currency code wrong");
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new MonetaryValueUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/NameOrPseudonymUnitTest.cs b/crypto/test/src/asn1/test/NameOrPseudonymUnitTest.cs
new file mode 100644
index 000000000..45f66613b
--- /dev/null
+++ b/crypto/test/src/asn1/test/NameOrPseudonymUnitTest.cs
@@ -0,0 +1,114 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.X500;
+using Org.BouncyCastle.Asn1.X509.SigI;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class NameOrPseudonymUnitTest
+ : Asn1UnitTest
+ {
+ public override string Name
+ {
+ get { return "NameOrPseudonym"; }
+ }
+
+ public override void PerformTest()
+ {
+ string pseudonym = "pseudonym";
+ DirectoryString surname = new DirectoryString("surname");
+ Asn1Sequence givenName = new DerSequence(new DirectoryString("givenName"));
+
+ NameOrPseudonym id = new NameOrPseudonym(pseudonym);
+
+ checkConstruction(id, pseudonym, null, null);
+
+ id = new NameOrPseudonym(surname, givenName);
+
+ checkConstruction(id, null, surname, givenName);
+
+ id = NameOrPseudonym.GetInstance(null);
+
+ if (id != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ NameOrPseudonym.GetInstance(new Object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkConstruction(
+ NameOrPseudonym id,
+ string pseudonym,
+ DirectoryString surname,
+ Asn1Sequence givenName)
+ {
+ checkValues(id, pseudonym, surname, givenName);
+
+ id = NameOrPseudonym.GetInstance(id);
+
+ checkValues(id, pseudonym, surname, givenName);
+
+ Asn1InputStream aIn = new Asn1InputStream(id.ToAsn1Object().GetEncoded());
+
+ if (surname != null)
+ {
+ Asn1Sequence seq = (Asn1Sequence) aIn.ReadObject();
+
+ id = NameOrPseudonym.GetInstance(seq);
+ }
+ else
+ {
+ IAsn1String s = (IAsn1String) aIn.ReadObject();
+
+ id = NameOrPseudonym.GetInstance(s);
+ }
+
+ checkValues(id, pseudonym, surname, givenName);
+ }
+
+ private void checkValues(
+ NameOrPseudonym id,
+ string pseudonym,
+ DirectoryString surname,
+ Asn1Sequence givenName)
+ {
+
+ if (surname != null)
+ {
+ checkMandatoryField("surname", surname, id.Surname);
+ checkMandatoryField("givenName", givenName, new DerSequence(id.GetGivenName()[0]));
+ }
+ else
+ {
+ checkOptionalField("pseudonym", new DirectoryString(pseudonym), id.Pseudonym);
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new NameOrPseudonymUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/NamingAuthorityUnitTest.cs b/crypto/test/src/asn1/test/NamingAuthorityUnitTest.cs
new file mode 100644
index 000000000..787b2c32d
--- /dev/null
+++ b/crypto/test/src/asn1/test/NamingAuthorityUnitTest.cs
@@ -0,0 +1,106 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.IsisMtt.X509;
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class NamingAuthorityUnitTest
+ : Asn1UnitTest
+ {
+ public override string Name
+ {
+ get { return "NamingAuthority"; }
+ }
+
+ public override void PerformTest()
+ {
+ DerObjectIdentifier namingAuthorityID = new DerObjectIdentifier("1.2.3");
+ string namingAuthorityURL = "url";
+ DirectoryString namingAuthorityText = new DirectoryString("text");
+
+ NamingAuthority auth = new NamingAuthority(namingAuthorityID, namingAuthorityURL, namingAuthorityText);
+
+ checkConstruction(auth, namingAuthorityID, namingAuthorityURL, namingAuthorityText);
+
+ auth = new NamingAuthority(null, namingAuthorityURL, namingAuthorityText);
+
+ checkConstruction(auth, null, namingAuthorityURL, namingAuthorityText);
+
+ auth = new NamingAuthority(namingAuthorityID, null, namingAuthorityText);
+
+ checkConstruction(auth, namingAuthorityID, null, namingAuthorityText);
+
+ auth = new NamingAuthority(namingAuthorityID, namingAuthorityURL, null);
+
+ checkConstruction(auth, namingAuthorityID, namingAuthorityURL, null);
+
+ auth = NamingAuthority.GetInstance(null);
+
+ if (auth != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ NamingAuthority.GetInstance(new Object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkConstruction(
+ NamingAuthority auth,
+ DerObjectIdentifier namingAuthorityID,
+ string namingAuthorityURL,
+ DirectoryString namingAuthorityText)
+ {
+ checkValues(auth, namingAuthorityID, namingAuthorityURL, namingAuthorityText);
+
+ auth = NamingAuthority.GetInstance(auth);
+
+ checkValues(auth, namingAuthorityID, namingAuthorityURL, namingAuthorityText);
+
+ Asn1InputStream aIn = new Asn1InputStream(auth.ToAsn1Object().GetEncoded());
+
+ Asn1Sequence seq = (Asn1Sequence) aIn.ReadObject();
+
+ auth = NamingAuthority.GetInstance(seq);
+
+ checkValues(auth, namingAuthorityID, namingAuthorityURL, namingAuthorityText);
+ }
+
+ private void checkValues(
+ NamingAuthority auth,
+ DerObjectIdentifier namingAuthorityId,
+ string namingAuthorityURL,
+ DirectoryString namingAuthorityText)
+ {
+ checkOptionalField("namingAuthorityId", namingAuthorityId, auth.NamingAuthorityID);
+ checkOptionalField("namingAuthorityURL", namingAuthorityURL, auth.NamingAuthorityUrl);
+ checkOptionalField("namingAuthorityText", namingAuthorityText, auth.NamingAuthorityText);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new NamingAuthorityUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/NetscapeCertTypeTest.cs b/crypto/test/src/asn1/test/NetscapeCertTypeTest.cs
new file mode 100644
index 000000000..8db5d990c
--- /dev/null
+++ b/crypto/test/src/asn1/test/NetscapeCertTypeTest.cs
@@ -0,0 +1,45 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Misc;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class NetscapeCertTypeTest
+ : SimpleTest
+ {
+ public override string Name
+ {
+ get { return "NetscapeCertType"; }
+ }
+
+ public override void PerformTest()
+ {
+ BitStringConstantTester.testFlagValueCorrect(0, NetscapeCertType.SslClient);
+ BitStringConstantTester.testFlagValueCorrect(1, NetscapeCertType.SslServer);
+ BitStringConstantTester.testFlagValueCorrect(2, NetscapeCertType.Smime);
+ BitStringConstantTester.testFlagValueCorrect(3, NetscapeCertType.ObjectSigning);
+ BitStringConstantTester.testFlagValueCorrect(4, NetscapeCertType.Reserved);
+ BitStringConstantTester.testFlagValueCorrect(5, NetscapeCertType.SslCA);
+ BitStringConstantTester.testFlagValueCorrect(6, NetscapeCertType.SmimeCA);
+ BitStringConstantTester.testFlagValueCorrect(7, NetscapeCertType.ObjectSigningCA);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new NetscapeCertTypeTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/OCSPTest.cs b/crypto/test/src/asn1/test/OCSPTest.cs
new file mode 100644
index 000000000..13f59d3d1
--- /dev/null
+++ b/crypto/test/src/asn1/test/OCSPTest.cs
@@ -0,0 +1,183 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Ocsp;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class OcspTest
+ : ITest
+ {
+ private static byte[] unsignedReq = Base64.Decode(
+ "MEIwQDA+MDwwOjAJBgUrDgMCGgUABBRDb9GODnq7lRhSkEqw4XX24huERwQUkY4j"
+ + "a6eKuDlkVP9hRgkEvIWqHPECAQE=");
+
+ private static byte[] signedReq = Base64.Decode(
+ "MIIC9jBAMD4wPDA6MAkGBSsOAwIaBQAEFENv0Y4OeruVGFKQSrDhdfbiG4RHBBTc"
+ + "Mr1fP+mZAxbF2ZdehWxn6mtAngIBAaCCArAwggKsMA0GCSqGSIb3DQEBBQUAA4GB"
+ + "AAzHBm4nL5AcRQB3Jkz7ScNeZF+GbRZ0p4kBDTnqi3IeESuso12yJhpqqyijdnj5"
+ + "gd4/GsSAgdluLHyYZ6wgozV7G9MDXCnFnG4PBUW05HaVX81JYAp+amVyU0NOgNrG"
+ + "90npVBsHb0o+UlkxNgMiEbSkp/TeGb6YURsYKhmwp7BgoIICFTCCAhEwggINMIIB"
+ + "dqADAgECAgEBMA0GCSqGSIb3DQEBBAUAMCUxFjAUBgNVBAoTDUJvdW5jeSBDYXN0"
+ + "bGUxCzAJBgNVBAYTAkFVMB4XDTA0MTAyNDEzNDc0M1oXDTA1MDIwMTEzNDc0M1ow"
+ + "JTEWMBQGA1UEChMNQm91bmN5IENhc3RsZTELMAkGA1UEBhMCQVUwgZ8wDQYJKoZI"
+ + "hvcNAQEBBQADgY0AMIGJAoGBAJBmLeIzthMHUeTkOeJ76iBxcMHY31o/i3a9VT12"
+ + "y2FcS/ejJmeUCMTdtwl5alOwXY66vF4DyT1VU/nJG3mHpSoqq7qrMXOIFGcXg1Wf"
+ + "oJRrQgTOLdQ6bod7i9ME/EjEJy70orh0nVS7NGcu0R5TjcbLde2J5zxjb/W9wqfy"
+ + "RovJAgMBAAGjTTBLMB0GA1UdDgQWBBTcMr1fP+mZAxbF2ZdehWxn6mtAnjAfBgNV"
+ + "HSMEGDAWgBTcMr1fP+mZAxbF2ZdehWxn6mtAnjAJBgNVHRMEAjAAMA0GCSqGSIb3"
+ + "DQEBBAUAA4GBAF/4EH1KkNrNxocJPIp7lThmG1KIVYESIadowMowrbok46ESofRF"
+ + "OIPku07W+e1Y1Y1KXLIiPMG3IGwrBrn04iLsbbBUiN37BcC/VyT4xKJ2MYscGjKL"
+ + "ua/9bU0lOyeTRAwqb8towWRd5lLYAI3RQ7dhStUTFp3Vqd803PJ/cpR6");
+
+ private static byte[] _response = Base64.Decode(
+ "MIIFnAoBAKCCBZUwggWRBgkrBgEFBQcwAQEEggWCMIIFfjCCARehgZ8wgZwx"
+ + "CzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEgcHJhZGVzaDESMBAGA1UE"
+ + "BxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAKBgNVBAsTA0FUQzEeMBwG"
+ + "A1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQwIgYJKoZIhvcNAQkBFhVv"
+ + "Y3NwQHRjcy1jYS50Y3MuY28uaW4YDzIwMDMwNDAyMTIzNDU4WjBiMGAwOjAJ"
+ + "BgUrDgMCGgUABBRs07IuoCWNmcEl1oHwIak1BPnX8QQUtGyl/iL9WJ1VxjxF"
+ + "j0hAwJ/s1AcCAQKhERgPMjAwMjA4MjkwNzA5MjZaGA8yMDAzMDQwMjEyMzQ1"
+ + "OFowDQYJKoZIhvcNAQEFBQADgYEAfbN0TCRFKdhsmvOdUoiJ+qvygGBzDxD/"
+ + "VWhXYA+16AphHLIWNABR3CgHB3zWtdy2j7DJmQ/R7qKj7dUhWLSqclAiPgFt"
+ + "QQ1YvSJAYfEIdyHkxv4NP0LSogxrumANcDyC9yt/W9yHjD2ICPBIqCsZLuLk"
+ + "OHYi5DlwWe9Zm9VFwCGgggPMMIIDyDCCA8QwggKsoAMCAQICAQYwDQYJKoZI"
+ + "hvcNAQEFBQAwgZQxFDASBgNVBAMTC1RDUy1DQSBPQ1NQMSYwJAYJKoZIhvcN"
+ + "AQkBFhd0Y3MtY2FAdGNzLWNhLnRjcy5jby5pbjEMMAoGA1UEChMDVENTMQww"
+ + "CgYDVQQLEwNBVEMxEjAQBgNVBAcTCUh5ZGVyYWJhZDEXMBUGA1UECBMOQW5k"
+ + "aHJhIHByYWRlc2gxCzAJBgNVBAYTAklOMB4XDTAyMDgyOTA3MTE0M1oXDTAz"
+ + "MDgyOTA3MTE0M1owgZwxCzAJBgNVBAYTAklOMRcwFQYDVQQIEw5BbmRocmEg"
+ + "cHJhZGVzaDESMBAGA1UEBxMJSHlkZXJhYmFkMQwwCgYDVQQKEwNUQ1MxDDAK"
+ + "BgNVBAsTA0FUQzEeMBwGA1UEAxMVVENTLUNBIE9DU1AgUmVzcG9uZGVyMSQw"
+ + "IgYJKoZIhvcNAQkBFhVvY3NwQHRjcy1jYS50Y3MuY28uaW4wgZ8wDQYJKoZI"
+ + "hvcNAQEBBQADgY0AMIGJAoGBAM+XWW4caMRv46D7L6Bv8iwtKgmQu0SAybmF"
+ + "RJiz12qXzdvTLt8C75OdgmUomxp0+gW/4XlTPUqOMQWv463aZRv9Ust4f8MH"
+ + "EJh4ekP/NS9+d8vEO3P40ntQkmSMcFmtA9E1koUtQ3MSJlcs441JjbgUaVnm"
+ + "jDmmniQnZY4bU3tVAgMBAAGjgZowgZcwDAYDVR0TAQH/BAIwADALBgNVHQ8E"
+ + "BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwkwNgYIKwYBBQUHAQEEKjAoMCYG"
+ + "CCsGAQUFBzABhhpodHRwOi8vMTcyLjE5LjQwLjExMDo3NzAwLzAtBgNVHR8E"
+ + "JjAkMCKgIKAehhxodHRwOi8vMTcyLjE5LjQwLjExMC9jcmwuY3JsMA0GCSqG"
+ + "SIb3DQEBBQUAA4IBAQB6FovM3B4VDDZ15o12gnADZsIk9fTAczLlcrmXLNN4"
+ + "PgmqgnwF0Ymj3bD5SavDOXxbA65AZJ7rBNAguLUo+xVkgxmoBH7R2sBxjTCc"
+ + "r07NEadxM3HQkt0aX5XYEl8eRoifwqYAI9h0ziZfTNes8elNfb3DoPPjqq6V"
+ + "mMg0f0iMS4W8LjNPorjRB+kIosa1deAGPhq0eJ8yr0/s2QR2/WFD5P4aXc8I"
+ + "KWleklnIImS3zqiPrq6tl2Bm8DZj7vXlTOwmraSQxUwzCKwYob1yGvNOUQTq"
+ + "pG6jxn7jgDawHU1+WjWQe4Q34/pWeGLysxTraMa+Ug9kPe+jy/qRX2xwvKBZ");
+
+ private ITestResult unSignedRequest()
+ {
+ try
+ {
+ OcspRequest req = OcspRequest.GetInstance(
+ Asn1Object.FromByteArray(unsignedReq));
+
+ if (!Arrays.AreEqual(req.GetEncoded(), unsignedReq))
+ {
+ return new SimpleTestResult(false, Name + ": Ocsp unsigned request failed to re-encode");
+ }
+
+ return new SimpleTestResult(true, Name + ": Okay");
+ }
+ catch (Exception e)
+ {
+ return new SimpleTestResult(false, Name + ": failed unsigned exception - " + e.ToString(), e);
+ }
+ }
+
+ private ITestResult SignedRequest()
+ {
+ try
+ {
+ OcspRequest req = OcspRequest.GetInstance(
+ Asn1Object.FromByteArray(signedReq));
+
+ if (!Arrays.AreEqual(req.GetEncoded(), signedReq))
+ {
+ return new SimpleTestResult(false, Name + ": Ocsp signed request failed to re-encode");
+ }
+
+ return new SimpleTestResult(true, Name + ": Okay");
+ }
+ catch (Exception e)
+ {
+ return new SimpleTestResult(false, Name + ": failed signed exception - " + e.ToString(), e);
+ }
+ }
+
+ private ITestResult Response()
+ {
+ try
+ {
+ OcspResponse resp = OcspResponse.GetInstance(
+ Asn1Object.FromByteArray(_response));
+ ResponseBytes rBytes = ResponseBytes.GetInstance(resp.ResponseBytes);
+
+ BasicOcspResponse bResp = BasicOcspResponse.GetInstance(
+ Asn1Object.FromByteArray(rBytes.Response.GetOctets()));
+
+ resp = new OcspResponse(
+ resp.ResponseStatus,
+ new ResponseBytes(
+ rBytes.ResponseType,
+ new DerOctetString(bResp.GetEncoded())));
+
+ if (!Arrays.AreEqual(resp.GetEncoded(), _response))
+ {
+ return new SimpleTestResult(false, Name + ": Ocsp response failed to re-encode");
+ }
+
+ return new SimpleTestResult(true, Name + ": Okay");
+ }
+ catch (Exception e)
+ {
+ return new SimpleTestResult(false, Name + ": failed response exception - " + e.ToString(), e);
+ }
+ }
+
+ public ITestResult Perform()
+ {
+ ITestResult res = unSignedRequest();
+
+ if (!res.IsSuccessful())
+ {
+ return res;
+ }
+
+ res = SignedRequest();
+ if (!res.IsSuccessful())
+ {
+ return res;
+ }
+
+ return Response();
+ }
+
+ public string Name
+ {
+ get { return "Ocsp"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ ITest test = new OcspTest();
+ ITestResult result = test.Perform();
+
+ Console.WriteLine(result);
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/OIDTest.cs b/crypto/test/src/asn1/test/OIDTest.cs
new file mode 100644
index 000000000..b0782db04
--- /dev/null
+++ b/crypto/test/src/asn1/test/OIDTest.cs
@@ -0,0 +1,149 @@
+using System;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ /**
+ * X.690 test example
+ */
+ [TestFixture]
+ public class OidTest
+ : SimpleTest
+ {
+ byte[] req1 = Hex.Decode("0603813403");
+ byte[] req2 = Hex.Decode("06082A36FFFFFFDD6311");
+
+ public override string Name
+ {
+ get { return "OID"; }
+ }
+
+ private void recodeCheck(
+ string oid,
+ byte[] enc)
+ {
+ DerObjectIdentifier o = new DerObjectIdentifier(oid);
+ DerObjectIdentifier encO = (DerObjectIdentifier) Asn1Object.FromByteArray(enc);
+
+ if (!o.Equals(encO))
+ {
+ Fail("oid ID didn't match", o, encO);
+ }
+
+ byte[] bytes = o.GetDerEncoded();
+
+ if (!Arrays.AreEqual(bytes, enc))
+ {
+ Fail("failed comparison test", Hex.ToHexString(enc), Hex.ToHexString(bytes));
+ }
+ }
+
+ private void validOidCheck(
+ string oid)
+ {
+ DerObjectIdentifier o = new DerObjectIdentifier(oid);
+ o = (DerObjectIdentifier) Asn1Object.FromByteArray(o.GetEncoded());
+
+ if (!o.Id.Equals(oid))
+ {
+ Fail("failed oid check: " + oid);
+ }
+ }
+
+ private void invalidOidCheck(
+ string oid)
+ {
+ try
+ {
+ new DerObjectIdentifier(oid);
+ Fail("failed to catch bad oid: " + oid);
+ }
+ catch (FormatException)
+ {
+ // expected
+ }
+ }
+
+ private void branchCheck(string stem, string branch)
+ {
+ string expected = stem + "." + branch;
+ string actual = new DerObjectIdentifier(stem).Branch(branch).Id;
+
+ if (expected != actual)
+ {
+ Fail("failed 'branch' check for " + stem + "/" + branch);
+ }
+ }
+
+ private void onCheck(String stem, String test, bool expected)
+ {
+ if (expected != new DerObjectIdentifier(test).On(new DerObjectIdentifier(stem)))
+ {
+ Fail("failed 'on' check for " + stem + "/" + test);
+ }
+ }
+
+ public override void PerformTest()
+ {
+ recodeCheck("2.100.3", req1);
+ recodeCheck("1.2.54.34359733987.17", req2);
+
+ validOidCheck(PkcsObjectIdentifiers.Pkcs9AtContentType.Id);
+ validOidCheck("0.1");
+ validOidCheck("1.1.127.32512.8323072.2130706432.545460846592.139637976727552.35747322042253312.9151314442816847872");
+ validOidCheck("1.2.123.12345678901.1.1.1");
+ validOidCheck("2.25.196556539987194312349856245628873852187.1");
+
+ invalidOidCheck("0");
+ invalidOidCheck("1");
+ invalidOidCheck("2");
+ invalidOidCheck("3.1");
+ invalidOidCheck("..1");
+ invalidOidCheck("192.168.1.1");
+ invalidOidCheck(".123452");
+ invalidOidCheck("1.");
+ invalidOidCheck("1.345.23.34..234");
+ invalidOidCheck("1.345.23.34.234.");
+ invalidOidCheck(".12.345.77.234");
+ invalidOidCheck(".12.345.77.234.");
+ invalidOidCheck("1.2.3.4.A.5");
+ invalidOidCheck("1,2");
+
+ branchCheck("1.1", "2.2");
+
+ onCheck("1.1", "1.1", false);
+ onCheck("1.1", "1.2", false);
+ onCheck("1.1", "1.2.1", false);
+ onCheck("1.1", "2.1", false);
+ onCheck("1.1", "1.11", false);
+ onCheck("1.12", "1.1.2", false);
+ onCheck("1.1", "1.1.1", true);
+ onCheck("1.1", "1.1.2", true);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ ITest test = new OidTest();
+ ITestResult result = test.Perform();
+
+ Console.WriteLine(result);
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/OctetStringTest.cs b/crypto/test/src/asn1/test/OctetStringTest.cs
new file mode 100644
index 000000000..8bae1b057
--- /dev/null
+++ b/crypto/test/src/asn1/test/OctetStringTest.cs
@@ -0,0 +1,186 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Cms;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class OctetStringTest
+ {
+ [Test]
+ public void TestReadingWriting()
+ {
+ MemoryStream bOut = new MemoryStream();
+ BerOctetStringGenerator octGen = new BerOctetStringGenerator(bOut);
+
+ Stream outStream = octGen.GetOctetOutputStream();
+
+ outStream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4);
+ outStream.Write(new byte[4], 0, 4);
+
+ outStream.Close();
+
+ Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray());
+
+ BerOctetStringParser s = (BerOctetStringParser)aIn.ReadObject();
+
+ Stream inStream = s.GetOctetStream();
+ int count = 0;
+
+ while (inStream.ReadByte() >= 0)
+ {
+ count++;
+ }
+
+ Assert.AreEqual(8, count);
+ }
+
+ [Test]
+ public void TestReadingWritingZeroInLength()
+ {
+ MemoryStream bOut = new MemoryStream();
+ BerOctetStringGenerator octGen = new BerOctetStringGenerator(bOut);
+
+ Stream outStream = octGen.GetOctetOutputStream();
+
+ outStream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4);
+ outStream.Write(new byte[512], 0, 512); // forces a zero to appear in length
+
+ outStream.Close();
+
+ Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray());
+
+ BerOctetStringParser s = (BerOctetStringParser)aIn.ReadObject();
+
+ Stream inStream = s.GetOctetStream();
+ int count = 0;
+
+ while (inStream.ReadByte() >= 0)
+ {
+ count++;
+ }
+
+ Assert.AreEqual(516, count);
+ }
+
+ [Test]
+ public void TestReadingWritingNested()
+ {
+ MemoryStream bOut = new MemoryStream();
+ BerSequenceGenerator sGen = new BerSequenceGenerator(bOut);
+ BerOctetStringGenerator octGen = new BerOctetStringGenerator(sGen.GetRawOutputStream());
+
+ Stream outStream = octGen.GetOctetOutputStream();
+
+ BerSequenceGenerator inSGen = new BerSequenceGenerator(outStream);
+
+ BerOctetStringGenerator inOctGen = new BerOctetStringGenerator(inSGen.GetRawOutputStream());
+
+ Stream inOut = inOctGen.GetOctetOutputStream();
+
+ inOut.Write(new byte[] { 1, 2, 3, 4 }, 0, 4);
+ inOut.Write(new byte[10], 0, 10);
+
+ inOut.Close();
+
+ inSGen.Close();
+
+ outStream.Close();
+
+ sGen.Close();
+
+ Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray());
+
+ BerSequenceParser sq = (BerSequenceParser)aIn.ReadObject();
+
+ BerOctetStringParser s = (BerOctetStringParser)sq.ReadObject();
+
+ Asn1StreamParser aIn2 = new Asn1StreamParser(s.GetOctetStream());
+
+ BerSequenceParser sq2 = (BerSequenceParser)aIn2.ReadObject();
+
+ BerOctetStringParser inS = (BerOctetStringParser)sq2.ReadObject();
+
+ Stream inStream = inS.GetOctetStream();
+ int count = 0;
+
+ while (inStream.ReadByte() >= 0)
+ {
+ count++;
+ }
+
+ Assert.AreEqual(14, count);
+ }
+
+ [Test]
+ public void TestNestedStructure()
+ {
+ MemoryStream bOut = new MemoryStream();
+
+ BerSequenceGenerator sGen = new BerSequenceGenerator(bOut);
+
+ sGen.AddObject(new DerObjectIdentifier(CmsObjectIdentifiers.CompressedData.Id));
+
+ BerSequenceGenerator cGen = new BerSequenceGenerator(sGen.GetRawOutputStream(), 0, true);
+
+ cGen.AddObject(new DerInteger(0));
+
+ //
+ // AlgorithmIdentifier
+ //
+ DerSequenceGenerator algGen = new DerSequenceGenerator(cGen.GetRawOutputStream());
+
+ algGen.AddObject(new DerObjectIdentifier("1.2"));
+
+ algGen.Close();
+
+ //
+ // Encapsulated ContentInfo
+ //
+ BerSequenceGenerator eiGen = new BerSequenceGenerator(cGen.GetRawOutputStream());
+
+ eiGen.AddObject(new DerObjectIdentifier("1.1"));
+
+ BerOctetStringGenerator octGen = new BerOctetStringGenerator(eiGen.GetRawOutputStream(), 0, true);
+
+ //
+ // output containing zeroes
+ //
+ Stream outStream = octGen.GetOctetOutputStream();
+
+ outStream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4);
+ outStream.Write(new byte[4], 0, 4);
+ outStream.Write(new byte[20], 0, 20);
+
+ outStream.Close();
+ eiGen.Close();
+ cGen.Close();
+ sGen.Close();
+
+ //
+ // reading back
+ //
+ Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray());
+
+ ContentInfoParser cp = new ContentInfoParser((Asn1SequenceParser)aIn.ReadObject());
+
+ CompressedDataParser comData = new CompressedDataParser((Asn1SequenceParser)cp.GetContent(Asn1Tags.Sequence));
+ ContentInfoParser content = comData.GetEncapContentInfo();
+
+ Asn1OctetStringParser bytes = (Asn1OctetStringParser)content.GetContent(Asn1Tags.OctetString);
+
+ Stream inStream = bytes.GetOctetStream();
+ int count = 0;
+
+ while (inStream.ReadByte() >= 0)
+ {
+ count++;
+ }
+
+ Assert.AreEqual(28, count);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/OtherCertIDUnitTest.cs b/crypto/test/src/asn1/test/OtherCertIDUnitTest.cs
new file mode 100644
index 000000000..a09c18e8a
--- /dev/null
+++ b/crypto/test/src/asn1/test/OtherCertIDUnitTest.cs
@@ -0,0 +1,100 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Esf;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class OtherCertIDUnitTest
+ : Asn1UnitTest
+ {
+ public override string Name
+ {
+ get { return "OtherCertID"; }
+ }
+
+ public override void PerformTest()
+ {
+ AlgorithmIdentifier algId = new AlgorithmIdentifier(new DerObjectIdentifier("1.2.2.3"));
+ byte[] digest = new byte[20];
+ OtherHash otherHash = new OtherHash(new OtherHashAlgAndValue(algId, digest));
+ IssuerSerial issuerSerial = new IssuerSerial(new GeneralNames(new GeneralName(new X509Name("CN=test"))), new DerInteger(1));
+
+ OtherCertID certID = new OtherCertID(otherHash);
+
+ checkConstruction(certID, algId, digest, null);
+
+ certID = new OtherCertID(otherHash, issuerSerial);
+
+ checkConstruction(certID, algId, digest, issuerSerial);
+
+ certID = OtherCertID.GetInstance(null);
+
+ if (certID != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ OtherCertID.GetInstance(new Object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkConstruction(
+ OtherCertID certID,
+ AlgorithmIdentifier algId,
+ byte[] digest,
+ IssuerSerial issuerSerial)
+ {
+ checkValues(certID, algId, digest, issuerSerial);
+
+ certID = OtherCertID.GetInstance(certID);
+
+ checkValues(certID, algId, digest, issuerSerial);
+
+ Asn1InputStream aIn = new Asn1InputStream(certID.ToAsn1Object().GetEncoded());
+
+ Asn1Sequence seq = (Asn1Sequence) aIn.ReadObject();
+
+ certID = OtherCertID.GetInstance(seq);
+
+ checkValues(certID, algId, digest, issuerSerial);
+ }
+
+ private void checkValues(
+ OtherCertID certID,
+ AlgorithmIdentifier algId,
+ byte[] digest,
+ IssuerSerial issuerSerial)
+ {
+ checkMandatoryField("hashAlgorithm", algId, certID.OtherCertHash.HashAlgorithm);
+ checkMandatoryField("hashValue", digest, certID.OtherCertHash.GetHashValue());
+
+ checkOptionalField("issuerSerial", issuerSerial, certID.IssuerSerial);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new OtherCertIDUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/OtherSigningCertificateUnitTest.cs b/crypto/test/src/asn1/test/OtherSigningCertificateUnitTest.cs
new file mode 100644
index 000000000..4410d8e4c
--- /dev/null
+++ b/crypto/test/src/asn1/test/OtherSigningCertificateUnitTest.cs
@@ -0,0 +1,94 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Esf;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class OtherSigningCertificateUnitTest
+ : Asn1UnitTest
+ {
+ public override string Name
+ {
+ get { return "OtherSigningCertificate"; }
+ }
+
+ public override void PerformTest()
+ {
+ AlgorithmIdentifier algId = new AlgorithmIdentifier(new DerObjectIdentifier("1.2.2.3"));
+ byte[] digest = new byte[20];
+ OtherHash otherHash = new OtherHash(
+ new OtherHashAlgAndValue(algId, digest));
+ OtherCertID otherCertID = new OtherCertID(otherHash);
+
+ OtherSigningCertificate otherCert = new OtherSigningCertificate(otherCertID);
+
+ checkConstruction(otherCert, otherCertID);
+
+ otherCert = OtherSigningCertificate.GetInstance(null);
+
+ if (otherCert != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ OtherCertID.GetInstance(new Object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkConstruction(
+ OtherSigningCertificate otherCert,
+ OtherCertID otherCertID)
+ {
+ checkValues(otherCert, otherCertID);
+
+ otherCert = OtherSigningCertificate.GetInstance(otherCert);
+
+ checkValues(otherCert, otherCertID);
+
+ Asn1InputStream aIn = new Asn1InputStream(otherCert.ToAsn1Object().GetEncoded());
+
+ Asn1Sequence seq = (Asn1Sequence) aIn.ReadObject();
+
+ otherCert = OtherSigningCertificate.GetInstance(seq);
+
+ checkValues(otherCert, otherCertID);
+ }
+
+ private void checkValues(
+ OtherSigningCertificate otherCert,
+ OtherCertID otherCertID)
+ {
+ if (otherCert.GetCerts().Length != 1)
+ {
+ Fail("GetCerts() length wrong");
+ }
+ checkMandatoryField("GetCerts()[0]", otherCertID, otherCert.GetCerts()[0]);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new OtherSigningCertificateUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/PKCS10Test.cs b/crypto/test/src/asn1/test/PKCS10Test.cs
new file mode 100644
index 000000000..28736b816
--- /dev/null
+++ b/crypto/test/src/asn1/test/PKCS10Test.cs
@@ -0,0 +1,95 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class Pkcs10Test
+ : ITest
+ {
+ byte[] req1 = Base64.Decode(
+ "MIHoMIGTAgEAMC4xDjAMBgNVBAMTBVRlc3QyMQ8wDQYDVQQKEwZBbmFUb20xCzAJBgNVBAYTAlNF"
+ + "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALlEt31Tzt2MlcOljvacJgzQVhmlMoqAOgqJ9Pgd3Gux"
+ + "Z7/WcIlgW4QCB7WZT21O1YoghwBhPDMcNGrHei9kHQkCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA0EA"
+ + "NDEI4ecNtJ3uHwGGlitNFq9WxcoZ0djbQJ5hABMotav6gtqlrwKXY2evaIrsNwkJtNdwwH18aQDU"
+ + "KCjOuBL38Q==");
+
+ byte[] req2 = Base64.Decode(
+ "MIIB6TCCAVICAQAwgagxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQH"
+ + "EwtTYW50YSBDbGFyYTEMMAoGA1UEChMDQUJCMVEwTwYDVQQLHEhQAAAAAAAAAG8AAAAAAAAAdwAA"
+ + "AAAAAABlAAAAAAAAAHIAAAAAAAAAIAAAAAAAAABUAAAAAAAAABxIAAAAAAAARAAAAAAAAAAxDTAL"
+ + "BgNVBAMTBGJsdWUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANETRZ+6occCOrFxNhfKIp4C"
+ + "mMkxwhBNb7TnnahpbM9O0r4hrBPcfYuL7u9YX/jN0YNUP+/CiT39HhSe/bikaBPDEyNsl988I8vX"
+ + "piEdgxYq/+LTgGHbjRsRYCkPtmzwBbuBldNF8bV7pu0v4UScSsExmGqqDlX1TbPU8KkPU1iTAgMB"
+ + "AAGgADANBgkqhkiG9w0BAQQFAAOBgQAFbrs9qUwh93CtETk7DeUD5HcdCnxauo1bck44snSV6MZV"
+ + "OCIGaYu1501kmhEvAtVVRr6SEHwimfQDDIjnrWwYsEr/DT6tkTZAbfRd3qUu3iKjT0H0vlUZp0hJ"
+ + "66mINtBM84uZFBfoXiWY8M3FuAnGmvy6ah/dYtJorTxLKiGkew==");
+
+ public string Name
+ {
+ get
+ {
+ return "Pkcs10";
+ }
+ }
+
+ public ITestResult BasicPkcs10Test(
+ string testName,
+ byte[] req)
+ {
+ try
+ {
+ CertificationRequest r = new CertificationRequest(
+ (Asn1Sequence)Asn1Object.FromByteArray(req));
+ byte[] bytes = r.GetDerEncoded();
+
+ if (!Arrays.AreEqual(bytes, req))
+ {
+ return new SimpleTestResult(false, Name + ": " + testName + " failed comparison test");
+ }
+ }
+ catch (Exception e)
+ {
+ return new SimpleTestResult(false, Name + ": Exception - " + testName + " " + e.ToString());
+ }
+
+ return new SimpleTestResult(true, Name + ": Okay");
+ }
+
+ public ITestResult Perform()
+ {
+ ITestResult res = BasicPkcs10Test("basic CR", req1);
+
+ if (!res.IsSuccessful())
+ {
+ return res;
+ }
+
+ return BasicPkcs10Test("Universal CR", req2);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ ITest test = new Pkcs10Test();
+ ITestResult result = test.Perform();
+
+ Console.WriteLine(result);
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/PKCS12Test.cs b/crypto/test/src/asn1/test/PKCS12Test.cs
new file mode 100644
index 000000000..c20fa8cc6
--- /dev/null
+++ b/crypto/test/src/asn1/test/PKCS12Test.cs
@@ -0,0 +1,210 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class Pkcs12Test
+ : SimpleTest
+ {
+ private static byte[] pkcs12 = Base64.Decode(
+ "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"
+ + "AgFkAAA=");
+
+ public override void PerformTest()
+ {
+ Asn1Sequence obj = (Asn1Sequence) Asn1Object.FromByteArray(pkcs12);
+
+ Pfx bag = new Pfx(obj);
+ ContentInfo info = bag.AuthSafe;
+ MacData mData = bag.MacData;
+ DigestInfo dInfo = mData.Mac;
+ AlgorithmIdentifier algId = dInfo.AlgorithmID;
+ byte[] salt = mData.GetSalt();
+ int itCount = mData.IterationCount.IntValue;
+
+ byte[] octets = ((Asn1OctetString) info.Content).GetOctets();
+ AuthenticatedSafe authSafe = new AuthenticatedSafe(
+ (Asn1Sequence) Asn1Object.FromByteArray(octets));
+ ContentInfo[] c = authSafe.GetContentInfo();
+
+ //
+ // private key section
+ //
+ if (!c[0].ContentType.Equals(PkcsObjectIdentifiers.Data))
+ {
+ Fail("Failed comparison data test");
+ }
+
+ octets = ((Asn1OctetString)c[0].Content).GetOctets();
+ Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(octets);
+
+ SafeBag b = new SafeBag((Asn1Sequence)seq[0]);
+ if (!b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
+ {
+ Fail("Failed comparison shroudedKeyBag test");
+ }
+
+ EncryptedPrivateKeyInfo encInfo = EncryptedPrivateKeyInfo.GetInstance(b.BagValue);
+
+ encInfo = new EncryptedPrivateKeyInfo(encInfo.EncryptionAlgorithm, encInfo.GetEncryptedData());
+
+ b = new SafeBag(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag, encInfo.ToAsn1Object(), b.BagAttributes);
+
+ byte[] encodedBytes = new DerSequence(b).GetEncoded();
+
+ c[0] = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(encodedBytes));
+
+ //
+ // certificates
+ //
+ if (!c[1].ContentType.Equals(PkcsObjectIdentifiers.EncryptedData))
+ {
+ Fail("Failed comparison encryptedData test");
+ }
+
+ EncryptedData eData = EncryptedData.GetInstance(c[1].Content);
+
+ c[1] = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, eData);
+
+ //
+ // create an octet stream to represent the BER encoding of authSafe
+ //
+ authSafe = new AuthenticatedSafe(c);
+
+ info = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(authSafe.GetEncoded()));
+
+ mData = new MacData(new DigestInfo(algId, dInfo.GetDigest()), salt, itCount);
+
+ bag = new Pfx(info, mData);
+
+ //
+ // comparison test
+ //
+ if (!Arrays.AreEqual(bag.GetEncoded(), pkcs12))
+ {
+ Fail("Failed comparison test");
+ }
+ }
+
+ public override string Name
+ {
+ get { return "Pkcs12"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new Pkcs12Test());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/PKIFailureInfoTest.cs b/crypto/test/src/asn1/test/PKIFailureInfoTest.cs
new file mode 100644
index 000000000..734dbbc14
--- /dev/null
+++ b/crypto/test/src/asn1/test/PKIFailureInfoTest.cs
@@ -0,0 +1,76 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cmp;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ /**
+ * PKIFailureInfoTest
+ */
+ [TestFixture]
+ public class PkiFailureInfoTest
+ : SimpleTest
+ {
+ // A correct hex encoded BAD_DATA_FORMAT PkiFailureInfo
+ private static readonly byte[] CORRECT_FAILURE_INFO = Base64.Decode("AwIANQ==");
+
+ public override string Name
+ {
+ get { return "PkiFailureInfo"; }
+ }
+
+ private void doTestEncoding()
+ {
+ DerBitString bitString = (DerBitString) Asn1Object.FromByteArray(CORRECT_FAILURE_INFO);
+ PkiFailureInfo correct = new PkiFailureInfo(bitString);
+
+ PkiFailureInfo bug = new PkiFailureInfo(PkiFailureInfo.BadRequest | PkiFailureInfo.BadTime | PkiFailureInfo.BadDataFormat | PkiFailureInfo.IncorrectData);
+
+ if (!Arrays.AreEqual(correct.GetDerEncoded(), bug.GetDerEncoded()))
+ {
+ Fail("encoding doesn't match");
+ }
+ }
+
+ public override void PerformTest()
+ {
+ BitStringConstantTester.testFlagValueCorrect(0, PkiFailureInfo.BadAlg);
+ BitStringConstantTester.testFlagValueCorrect(1, PkiFailureInfo.BadMessageCheck);
+ BitStringConstantTester.testFlagValueCorrect(2, PkiFailureInfo.BadRequest);
+ BitStringConstantTester.testFlagValueCorrect(3, PkiFailureInfo.BadTime);
+ BitStringConstantTester.testFlagValueCorrect(4, PkiFailureInfo.BadCertId);
+ BitStringConstantTester.testFlagValueCorrect(5, PkiFailureInfo.BadDataFormat);
+ BitStringConstantTester.testFlagValueCorrect(6, PkiFailureInfo.WrongAuthority);
+ BitStringConstantTester.testFlagValueCorrect(7, PkiFailureInfo.IncorrectData);
+ BitStringConstantTester.testFlagValueCorrect(8, PkiFailureInfo.MissingTimeStamp);
+ BitStringConstantTester.testFlagValueCorrect(9, PkiFailureInfo.BadPop);
+ BitStringConstantTester.testFlagValueCorrect(14, PkiFailureInfo.TimeNotAvailable);
+ BitStringConstantTester.testFlagValueCorrect(15, PkiFailureInfo.UnacceptedPolicy);
+ BitStringConstantTester.testFlagValueCorrect(16, PkiFailureInfo.UnacceptedExtension);
+ BitStringConstantTester.testFlagValueCorrect(17, PkiFailureInfo.AddInfoNotAvailable);
+ BitStringConstantTester.testFlagValueCorrect(25, PkiFailureInfo.SystemFailure);
+
+ doTestEncoding();
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new PkiFailureInfoTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/ParseTest.cs b/crypto/test/src/asn1/test/ParseTest.cs
new file mode 100644
index 000000000..c649fdb8d
--- /dev/null
+++ b/crypto/test/src/asn1/test/ParseTest.cs
@@ -0,0 +1,303 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class ParseTest
+ {
+ private static readonly byte[] classCastTest = Base64.Decode(
+ "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");
+
+ private static readonly byte[] derExpTest = Base64.Decode(
+ "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"
+ + "yv8TOTFCWnZEUTtVA9+2CpwfmuEjD2UQ4vxoM+o=");
+
+ private static readonly byte[] longTagged = Hex.Decode("9f1f023330");
+
+ [Test]
+ public void TestClassCast()
+ {
+ ParseEnveloped(classCastTest);
+ }
+
+ [Test]
+ public void TestDerExp()
+ {
+ ParseEnveloped(derExpTest);
+ }
+
+ [Test]
+ public void TestLongTag()
+ {
+ Asn1StreamParser aIn = new Asn1StreamParser(longTagged);
+ Asn1TaggedObjectParser tagged = (Asn1TaggedObjectParser)aIn.ReadObject();
+
+ Assert.AreEqual(31, tagged.TagNo);
+ }
+
+ private void ParseEnveloped(
+ byte[] data)
+ {
+ Asn1StreamParser aIn = new Asn1StreamParser(data);
+
+ ContentInfoParser cP = new ContentInfoParser((Asn1SequenceParser)aIn.ReadObject());
+
+ EnvelopedDataParser eP = new EnvelopedDataParser((Asn1SequenceParser)cP.GetContent(Asn1Tags.Sequence));
+
+ eP.GetRecipientInfos().ToAsn1Object(); // Must drain the parser!
+
+ EncryptedContentInfoParser ecP = eP.GetEncryptedContentInfo();
+
+ Asn1OctetStringParser content = (Asn1OctetStringParser)ecP.GetEncryptedContent(Asn1Tags.OctetString);
+
+ Streams.Drain(content.GetOctetStream());
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/ParsingTest.cs b/crypto/test/src/asn1/test/ParsingTest.cs
new file mode 100644
index 000000000..bb219e2fc
--- /dev/null
+++ b/crypto/test/src/asn1/test/ParsingTest.cs
@@ -0,0 +1,104 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ public class ParsingTest
+ : SimpleTest
+ {
+ private static readonly string[] streams = {
+ "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"
+ };
+
+ public override string Name
+ {
+ get { return "ParsingTest"; }
+ }
+
+ public override void PerformTest()
+ {
+ inputStreamTest();
+ parserTest();
+ }
+
+ private void parserTest()
+ {
+ foreach (string stream in streams)
+ {
+ Asn1StreamParser aIn = new Asn1StreamParser(Base64.Decode(stream));
+
+ try
+ {
+ Object obj;
+ while ((obj = aIn.ReadObject()) != null)
+ {
+ }
+
+ Fail("bad stream parsed successfully!");
+ }
+ catch (IOException)
+ {
+ // ignore
+ }
+ // Note: C# may throw these instead, since no InMemoryRepresentable support
+ catch (Asn1ParsingException)
+ {
+ // ignore
+ }
+ }
+ }
+
+ private void inputStreamTest()
+ {
+ foreach (string stream in streams)
+ {
+ Asn1InputStream aIn = new Asn1InputStream(Base64.Decode(stream));
+
+ try
+ {
+ Object obj;
+ while ((obj = aIn.ReadObject()) != null)
+ {
+ }
+
+ Fail("bad stream parsed successfully!");
+ }
+ catch (IOException)
+ {
+ // ignore
+ }
+ // Note: C# may throw these instead, since no InMemoryRepresentable support
+ catch (Asn1ParsingException)
+ {
+ // ignore
+ }
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new ParsingTest());
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/PersonalDataUnitTest.cs b/crypto/test/src/asn1/test/PersonalDataUnitTest.cs
new file mode 100644
index 000000000..f92e619cf
--- /dev/null
+++ b/crypto/test/src/asn1/test/PersonalDataUnitTest.cs
@@ -0,0 +1,127 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.X500;
+using Org.BouncyCastle.Asn1.X509.SigI;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class PersonalDataUnitTest
+ : Asn1UnitTest
+ {
+ public override string Name
+ {
+ get { return "PersonalData"; }
+ }
+
+ public override void PerformTest()
+ {
+ NameOrPseudonym nameOrPseudonym = new NameOrPseudonym("pseudonym");
+ BigInteger nameDistinguisher = BigInteger.ValueOf(10);
+ DerGeneralizedTime dateOfBirth= new DerGeneralizedTime("20070315173729Z");
+ DirectoryString placeOfBirth = new DirectoryString("placeOfBirth");
+ string gender = "M";
+ DirectoryString postalAddress = new DirectoryString("address");
+
+ PersonalData data = new PersonalData(nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, postalAddress);
+
+ checkConstruction(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, postalAddress);
+
+ data = new PersonalData(nameOrPseudonym, null, dateOfBirth, placeOfBirth, gender, postalAddress);
+
+ checkConstruction(data, nameOrPseudonym, null, dateOfBirth, placeOfBirth, gender, postalAddress);
+
+ data = new PersonalData(nameOrPseudonym, nameDistinguisher, null, placeOfBirth, gender, postalAddress);
+
+ checkConstruction(data, nameOrPseudonym, nameDistinguisher, null, placeOfBirth, gender, postalAddress);
+
+ data = new PersonalData(nameOrPseudonym, nameDistinguisher, dateOfBirth, null, gender, postalAddress);
+
+ checkConstruction(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, null, gender, postalAddress);
+
+ data = new PersonalData(nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, null, postalAddress);
+
+ checkConstruction(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, null, postalAddress);
+
+ data = new PersonalData(nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, null);
+
+ checkConstruction(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, null);
+
+ data = PersonalData.GetInstance(null);
+
+ if (data != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ PersonalData.GetInstance(new Object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkConstruction(
+ PersonalData data,
+ NameOrPseudonym nameOrPseudonym,
+ BigInteger nameDistinguisher,
+ DerGeneralizedTime dateOfBirth,
+ DirectoryString placeOfBirth,
+ string gender,
+ DirectoryString postalAddress)
+ {
+ checkValues(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, postalAddress);
+
+ data = PersonalData.GetInstance(data);
+
+ checkValues(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, postalAddress);
+
+ Asn1InputStream aIn = new Asn1InputStream(data.ToAsn1Object().GetEncoded());
+
+ Asn1Sequence seq = (Asn1Sequence) aIn.ReadObject();
+
+ data = PersonalData.GetInstance(seq);
+
+ checkValues(data, nameOrPseudonym, nameDistinguisher, dateOfBirth, placeOfBirth, gender, postalAddress);
+ }
+
+ private void checkValues(
+ PersonalData data,
+ NameOrPseudonym nameOrPseudonym,
+ BigInteger nameDistinguisher,
+ DerGeneralizedTime dateOfBirth,
+ DirectoryString placeOfBirth,
+ string gender,
+ DirectoryString postalAddress)
+ {
+ checkMandatoryField("nameOrPseudonym", nameOrPseudonym, data.NameOrPseudonym);
+ checkOptionalField("nameDistinguisher", nameDistinguisher, data.NameDistinguisher);
+ checkOptionalField("dateOfBirth", dateOfBirth, data.DateOfBirth);
+ checkOptionalField("placeOfBirth", placeOfBirth, data.PlaceOfBirth);
+ checkOptionalField("gender", gender, data.Gender);
+ checkOptionalField("postalAddress", postalAddress, data.PostalAddress);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new PersonalDataUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/ProcurationSyntaxUnitTest.cs b/crypto/test/src/asn1/test/ProcurationSyntaxUnitTest.cs
new file mode 100644
index 000000000..97d0e3eee
--- /dev/null
+++ b/crypto/test/src/asn1/test/ProcurationSyntaxUnitTest.cs
@@ -0,0 +1,111 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.IsisMtt.X509;
+using Org.BouncyCastle.Asn1.X500;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class ProcurationSyntaxUnitTest
+ : Asn1UnitTest
+ {
+ public override string Name
+ {
+ get { return "ProcurationSyntax"; }
+ }
+
+ public override void PerformTest()
+ {
+ string country = "AU";
+ DirectoryString typeOfSubstitution = new DirectoryString("substitution");
+ GeneralName thirdPerson = new GeneralName(new X509Name("CN=thirdPerson"));
+ IssuerSerial certRef = new IssuerSerial(new GeneralNames(new GeneralName(new X509Name("CN=test"))), new DerInteger(1));
+
+ ProcurationSyntax procuration = new ProcurationSyntax(country, typeOfSubstitution, thirdPerson);
+
+ checkConstruction(procuration, country, typeOfSubstitution, thirdPerson, null);
+
+ procuration = new ProcurationSyntax(country, typeOfSubstitution, certRef);
+
+ checkConstruction(procuration, country, typeOfSubstitution, null, certRef);
+
+ procuration = new ProcurationSyntax(null, typeOfSubstitution, certRef);
+
+ checkConstruction(procuration, null, typeOfSubstitution, null, certRef);
+
+ procuration = new ProcurationSyntax(country, null, certRef);
+
+ checkConstruction(procuration, country, null, null, certRef);
+
+ procuration = ProcurationSyntax.GetInstance(null);
+
+ if (procuration != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ ProcurationSyntax.GetInstance(new Object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkConstruction(
+ ProcurationSyntax procuration,
+ string country,
+ DirectoryString typeOfSubstitution,
+ GeneralName thirdPerson,
+ IssuerSerial certRef)
+ {
+ checkValues(procuration, country, typeOfSubstitution, thirdPerson, certRef);
+
+ procuration = ProcurationSyntax.GetInstance(procuration);
+
+ checkValues(procuration, country, typeOfSubstitution, thirdPerson, certRef);
+
+ Asn1InputStream aIn = new Asn1InputStream(procuration.ToAsn1Object().GetEncoded());
+
+ Asn1Sequence seq = (Asn1Sequence) aIn.ReadObject();
+
+ procuration = ProcurationSyntax.GetInstance(seq);
+
+ checkValues(procuration, country, typeOfSubstitution, thirdPerson, certRef);
+ }
+
+ private void checkValues(
+ ProcurationSyntax procuration,
+ string country,
+ DirectoryString typeOfSubstitution,
+ GeneralName thirdPerson,
+ IssuerSerial certRef)
+ {
+ checkOptionalField("country", country, procuration.Country);
+ checkOptionalField("typeOfSubstitution", typeOfSubstitution, procuration.TypeOfSubstitution);
+ checkOptionalField("thirdPerson", thirdPerson, procuration.ThirdPerson);
+ checkOptionalField("certRef", certRef, procuration.CertRef);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new ProcurationSyntaxUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/ProfessionInfoUnitTest.cs b/crypto/test/src/asn1/test/ProfessionInfoUnitTest.cs
new file mode 100644
index 000000000..6af2658ef
--- /dev/null
+++ b/crypto/test/src/asn1/test/ProfessionInfoUnitTest.cs
@@ -0,0 +1,121 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.IsisMtt.X509;
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class ProfessionInfoUnitTest
+ : Asn1UnitTest
+ {
+ public override string Name
+ {
+ get { return "ProfessionInfo"; }
+ }
+
+ public override void PerformTest()
+ {
+ NamingAuthority auth = new NamingAuthority(new DerObjectIdentifier("1.2.3"), "url", new DirectoryString("fred"));
+ DirectoryString[] professionItems = { new DirectoryString("substitution") };
+ DerObjectIdentifier[] professionOids = { new DerObjectIdentifier("1.2.3") };
+ string registrationNumber = "12345";
+ DerOctetString addProfInfo = new DerOctetString(new byte[20]);
+
+ ProfessionInfo info = new ProfessionInfo(auth, professionItems, professionOids, registrationNumber, addProfInfo);
+
+ checkConstruction(info, auth, professionItems, professionOids, registrationNumber, addProfInfo);
+
+ info = new ProfessionInfo(null, professionItems, professionOids, registrationNumber, addProfInfo);
+
+ checkConstruction(info, null, professionItems, professionOids, registrationNumber, addProfInfo);
+
+ info = new ProfessionInfo(auth, professionItems, null, registrationNumber, addProfInfo);
+
+ checkConstruction(info, auth, professionItems, null, registrationNumber, addProfInfo);
+
+ info = new ProfessionInfo(auth, professionItems, professionOids, null, addProfInfo);
+
+ checkConstruction(info, auth, professionItems, professionOids, null, addProfInfo);
+
+ info = new ProfessionInfo(auth, professionItems, professionOids, registrationNumber, null);
+
+ checkConstruction(info, auth, professionItems, professionOids, registrationNumber, null);
+
+ info = ProfessionInfo.GetInstance(null);
+
+ if (info != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ ProcurationSyntax.GetInstance(new Object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkConstruction(
+ ProfessionInfo profInfo,
+ NamingAuthority auth,
+ DirectoryString[] professionItems,
+ DerObjectIdentifier[] professionOids,
+ string registrationNumber,
+ DerOctetString addProfInfo)
+ {
+ checkValues(profInfo, auth, professionItems, professionOids, registrationNumber, addProfInfo);
+
+ profInfo = ProfessionInfo.GetInstance(profInfo);
+
+ checkValues(profInfo, auth, professionItems, professionOids, registrationNumber, addProfInfo);
+
+ Asn1InputStream aIn = new Asn1InputStream(profInfo.ToAsn1Object().GetEncoded());
+
+ Asn1Sequence seq = (Asn1Sequence) aIn.ReadObject();
+
+ profInfo = ProfessionInfo.GetInstance(seq);
+
+ checkValues(profInfo, auth, professionItems, professionOids, registrationNumber, addProfInfo);
+ }
+
+ private void checkValues(
+ ProfessionInfo profInfo,
+ NamingAuthority auth,
+ DirectoryString[] professionItems,
+ DerObjectIdentifier[] professionOids,
+ string registrationNumber,
+ DerOctetString addProfInfo)
+ {
+ checkOptionalField("auth", auth, profInfo.NamingAuthority);
+ checkMandatoryField("professionItems", professionItems[0], profInfo.GetProfessionItems()[0]);
+ if (professionOids != null)
+ {
+ checkOptionalField("professionOids", professionOids[0], profInfo.GetProfessionOids()[0]);
+ }
+ checkOptionalField("registrationNumber", registrationNumber, profInfo.RegistrationNumber);
+ checkOptionalField("addProfessionInfo", addProfInfo, profInfo.AddProfessionInfo);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new ProfessionInfoUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/QCStatementUnitTest.cs b/crypto/test/src/asn1/test/QCStatementUnitTest.cs
new file mode 100644
index 000000000..8d8ec9ec7
--- /dev/null
+++ b/crypto/test/src/asn1/test/QCStatementUnitTest.cs
@@ -0,0 +1,108 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Asn1.X509.Qualified;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class QCStatementUnitTest
+ : SimpleTest
+ {
+ public override string Name
+ {
+ get { return "QCStatement"; }
+ }
+
+ public override void PerformTest()
+ {
+ QCStatement mv = new QCStatement(Rfc3739QCObjectIdentifiers.IdQcsPkixQCSyntaxV1);
+
+ CheckConstruction(mv, Rfc3739QCObjectIdentifiers.IdQcsPkixQCSyntaxV1, null);
+
+ Asn1Encodable info = new SemanticsInformation(new DerObjectIdentifier("1.2"));
+
+ mv = new QCStatement(Rfc3739QCObjectIdentifiers.IdQcsPkixQCSyntaxV1, info);
+
+ CheckConstruction(mv, Rfc3739QCObjectIdentifiers.IdQcsPkixQCSyntaxV1, info);
+
+ mv = QCStatement.GetInstance(null);
+
+ if (mv != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ QCStatement.GetInstance(new object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void CheckConstruction(
+ QCStatement mv,
+ DerObjectIdentifier statementId,
+ Asn1Encodable statementInfo)
+ {
+ CheckStatement(mv, statementId, statementInfo);
+
+ mv = QCStatement.GetInstance(mv);
+
+ CheckStatement(mv, statementId, statementInfo);
+
+ Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(
+ mv.ToAsn1Object().GetEncoded());
+
+ mv = QCStatement.GetInstance(seq);
+
+ CheckStatement(mv, statementId, statementInfo);
+ }
+
+ private void CheckStatement(
+ QCStatement qcs,
+ DerObjectIdentifier statementId,
+ Asn1Encodable statementInfo)
+ {
+ if (!qcs.StatementId.Equals(statementId))
+ {
+ Fail("statementIds don't match.");
+ }
+
+ if (statementInfo != null)
+ {
+ if (!qcs.StatementInfo.Equals(statementInfo))
+ {
+ Fail("statementInfos don't match.");
+ }
+ }
+ else if (qcs.StatementInfo != null)
+ {
+ Fail("statementInfo found when none expected.");
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new QCStatementUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/ReasonFlagsTest.cs b/crypto/test/src/asn1/test/ReasonFlagsTest.cs
new file mode 100644
index 000000000..ef404b3e1
--- /dev/null
+++ b/crypto/test/src/asn1/test/ReasonFlagsTest.cs
@@ -0,0 +1,46 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class ReasonFlagsTest
+ : SimpleTest
+ {
+ public override string Name
+ {
+ get { return "ReasonFlags"; }
+ }
+
+ public override void PerformTest()
+ {
+ BitStringConstantTester.testFlagValueCorrect(0, ReasonFlags.Unused);
+ BitStringConstantTester.testFlagValueCorrect(1, ReasonFlags.KeyCompromise);
+ BitStringConstantTester.testFlagValueCorrect(2, ReasonFlags.CACompromise);
+ BitStringConstantTester.testFlagValueCorrect(3, ReasonFlags.AffiliationChanged);
+ BitStringConstantTester.testFlagValueCorrect(4, ReasonFlags.Superseded);
+ BitStringConstantTester.testFlagValueCorrect(5, ReasonFlags.CessationOfOperation);
+ BitStringConstantTester.testFlagValueCorrect(6, ReasonFlags.CertificateHold);
+ BitStringConstantTester.testFlagValueCorrect(7, ReasonFlags.PrivilegeWithdrawn);
+ BitStringConstantTester.testFlagValueCorrect(8, ReasonFlags.AACompromise);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new ReasonFlagsTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/RegressionTest.cs b/crypto/test/src/asn1/test/RegressionTest.cs
new file mode 100644
index 000000000..873ab4396
--- /dev/null
+++ b/crypto/test/src/asn1/test/RegressionTest.cs
@@ -0,0 +1,85 @@
+using System;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ public class RegressionTest
+ {
+ public static readonly ITest[] tests =
+ {
+ new AdditionalInformationSyntaxUnitTest(),
+ new AdmissionSyntaxUnitTest(),
+ new AdmissionsUnitTest(),
+ new AttributeTableUnitTest(),
+ new BiometricDataUnitTest(),
+ new BitStringTest(),
+ new CertHashUnitTest(),
+ new CertificateTest(),
+ new CmsTest(),
+ new CommitmentTypeIndicationUnitTest(),
+ new CommitmentTypeQualifierUnitTest(),
+ new ContentHintsUnitTest(),
+ new CscaMasterListTest(),
+ new DataGroupHashUnitTest(),
+ new DeclarationOfMajorityUnitTest(),
+ new DerApplicationSpecificTest(),
+ new DerUtf8StringTest(),
+ new EncryptedPrivateKeyInfoTest(),
+ new EqualsAndHashCodeTest(),
+ new EssCertIDv2UnitTest(),
+ new GeneralizedTimeTest(),
+ new GeneralNameTest(),
+ new GenerationTest(),
+ new InputStreamTest(),
+ new Iso4217CurrencyCodeUnitTest(),
+ new IssuingDistributionPointUnitTest(),
+ new KeyUsageTest(),
+ new LDSSecurityObjectUnitTest(),
+ new MiscTest(),
+ new MonetaryLimitUnitTest(),
+ new MonetaryValueUnitTest(),
+ new NameOrPseudonymUnitTest(),
+ new NamingAuthorityUnitTest(),
+ new NetscapeCertTypeTest(),
+ new OcspTest(),
+ new OidTest(),
+ new OtherCertIDUnitTest(),
+ new OtherSigningCertificateUnitTest(),
+ new ParsingTest(),
+ new PersonalDataUnitTest(),
+ new Pkcs10Test(),
+ new Pkcs12Test(),
+ new PkiFailureInfoTest(),
+ new ProcurationSyntaxUnitTest(),
+ new ProfessionInfoUnitTest(),
+ new QCStatementUnitTest(),
+ new ReasonFlagsTest(),
+ new RequestedCertificateUnitTest(),
+ new RestrictionUnitTest(),
+ new SemanticsInformationUnitTest(),
+ new SetTest(),
+ new SignerLocationUnitTest(),
+ new SmimeTest(),
+ new StringTest(),
+ new SubjectKeyIdentifierTest(),
+ new TagTest(),
+ new TargetInformationTest(),
+ new TypeOfBiometricDataUnitTest(),
+ new UtcTimeTest(),
+ new X509ExtensionsTest(),
+ new X509NameTest(),
+ new X9Test(),
+ };
+
+ public static void Main(
+ string[] args)
+ {
+ for (int i = 0; i != tests.Length; i++)
+ {
+ ITestResult result = tests[i].Perform();
+ Console.WriteLine(result);
+ }
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/RequestedCertificateUnitTest.cs b/crypto/test/src/asn1/test/RequestedCertificateUnitTest.cs
new file mode 100644
index 000000000..767504173
--- /dev/null
+++ b/crypto/test/src/asn1/test/RequestedCertificateUnitTest.cs
@@ -0,0 +1,117 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.IsisMtt.Ocsp;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class RequestedCertificateUnitTest
+ : Asn1UnitTest
+ {
+ private static readonly byte[] certBytes = Base64.Decode(
+ "MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV"
+ + "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz"
+ + "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM"
+ + "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF"
+ + "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO"
+ + "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE"
+ + "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ"
+ + "zl9HYIMxATFyqSiD9jsx");
+
+ public override string Name
+ {
+ get { return "RequestedCertificate"; }
+ }
+
+ public override void PerformTest()
+ {
+ RequestedCertificate.Choice type = RequestedCertificate.Choice.AttributeCertificate;
+ X509CertificateStructure cert = X509CertificateStructure.GetInstance(
+ Asn1Object.FromByteArray(certBytes));
+
+ byte[] certOctets = new byte[20];
+ RequestedCertificate requested = new RequestedCertificate(type, certOctets);
+
+ checkConstruction(requested, type, certOctets, null);
+
+ requested = new RequestedCertificate(cert);
+
+ checkConstruction(requested, RequestedCertificate.Choice.Certificate, null, cert);
+
+ requested = RequestedCertificate.GetInstance(null);
+
+ if (requested != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ RequestedCertificate.GetInstance(new object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkConstruction(
+ RequestedCertificate requested,
+ RequestedCertificate.Choice type,
+ byte[] certOctets,
+ X509CertificateStructure cert)
+ {
+ checkValues(requested, type, certOctets, cert);
+
+ requested = RequestedCertificate.GetInstance(requested);
+
+ checkValues(requested, type, certOctets, cert);
+
+ Asn1InputStream aIn = new Asn1InputStream(requested.ToAsn1Object().GetEncoded());
+
+ object obj = aIn.ReadObject();
+
+ requested = RequestedCertificate.GetInstance(obj);
+
+ checkValues(requested, type, certOctets, cert);
+ }
+
+ private void checkValues(
+ RequestedCertificate requested,
+ RequestedCertificate.Choice type,
+ byte[] certOctets,
+ X509CertificateStructure cert)
+ {
+ checkMandatoryField("certType", (int) type, (int) requested.Type);
+
+ if (requested.Type == RequestedCertificate.Choice.Certificate)
+ {
+ checkMandatoryField("certificate", cert.GetEncoded(), requested.GetCertificateBytes());
+ }
+ else
+ {
+ checkMandatoryField("certificateOctets", certOctets, requested.GetCertificateBytes());
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new RequestedCertificateUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/RestrictionUnitTest.cs b/crypto/test/src/asn1/test/RestrictionUnitTest.cs
new file mode 100644
index 000000000..5dd6438cb
--- /dev/null
+++ b/crypto/test/src/asn1/test/RestrictionUnitTest.cs
@@ -0,0 +1,78 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.IsisMtt.X509;
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class RestrictionUnitTest
+ : Asn1UnitTest
+ {
+ public override string Name
+ {
+ get { return "Restriction"; }
+ }
+
+ public override void PerformTest()
+ {
+ DirectoryString res = new DirectoryString("test");
+ Restriction restriction = new Restriction(res.GetString());
+
+ checkConstruction(restriction, res);
+
+ try
+ {
+ Restriction.GetInstance(new Object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void checkConstruction(
+ Restriction restriction,
+ DirectoryString res)
+ {
+ checkValues(restriction, res);
+
+ restriction = Restriction.GetInstance(restriction);
+
+ checkValues(restriction, res);
+
+ Asn1InputStream aIn = new Asn1InputStream(restriction.ToAsn1Object().GetEncoded());
+
+ IAsn1String str = (IAsn1String) aIn.ReadObject();
+
+ restriction = Restriction.GetInstance(str);
+
+ checkValues(restriction, res);
+ }
+
+ private void checkValues(
+ Restriction restriction,
+ DirectoryString res)
+ {
+ checkMandatoryField("restriction", res, restriction.RestrictionString);
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new RestrictionUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/SMIMETest.cs b/crypto/test/src/asn1/test/SMIMETest.cs
new file mode 100644
index 000000000..adb90e093
--- /dev/null
+++ b/crypto/test/src/asn1/test/SMIMETest.cs
@@ -0,0 +1,90 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.Smime;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class SmimeTest
+ : ITest
+ {
+ private static byte[] attrBytes = Base64.Decode("MDQGCSqGSIb3DQEJDzEnMCUwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMAcGBSsOAwIH");
+ private static byte[] prefBytes = Base64.Decode("MCwGCyqGSIb3DQEJEAILMR2hGwQIAAAAAAAAAAAYDzIwMDcwMzE1MTczNzI5Wg==");
+
+ public ITestResult Perform()
+ {
+ SmimeCapabilityVector caps = new SmimeCapabilityVector();
+
+ caps.AddCapability(SmimeCapability.DesEde3Cbc);
+ caps.AddCapability(SmimeCapability.RC2Cbc, 128);
+ caps.AddCapability(SmimeCapability.DesCbc);
+
+ SmimeCapabilitiesAttribute attr = new SmimeCapabilitiesAttribute(caps);
+
+ SmimeEncryptionKeyPreferenceAttribute pref = new SmimeEncryptionKeyPreferenceAttribute(
+ new RecipientKeyIdentifier(new DerOctetString(new byte[8]),
+ new DerGeneralizedTime("20070315173729Z"),
+ null));
+
+ try
+ {
+ if (!Arrays.AreEqual(attr.GetEncoded(), attrBytes))
+ {
+ return new SimpleTestResult(false, Name + ": Failed attr data check");
+ }
+
+ Asn1Object o = Asn1Object.FromByteArray(attrBytes);
+ if (!attr.Equals(o))
+ {
+ return new SimpleTestResult(false, Name + ": Failed equality test for attr");
+ }
+
+ if (!Arrays.AreEqual(pref.GetEncoded(), prefBytes))
+ {
+ return new SimpleTestResult(false, Name + ": Failed attr data check");
+ }
+
+ o = Asn1Object.FromByteArray(prefBytes);
+ if (!pref.Equals(o))
+ {
+ return new SimpleTestResult(false, Name + ": Failed equality test for pref");
+ }
+
+ return new SimpleTestResult(true, Name + ": Okay");
+ }
+ catch (Exception e)
+ {
+ return new SimpleTestResult(false, Name + ": Failed - exception " + e.ToString(), e);
+ }
+ }
+
+ public string Name
+ {
+ get { return "SMIME"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ ITest test = new SmimeTest();
+ ITestResult result = test.Perform();
+
+ Console.WriteLine(result);
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/SemanticsInformationUnitTest.cs b/crypto/test/src/asn1/test/SemanticsInformationUnitTest.cs
new file mode 100644
index 000000000..8f1f85f19
--- /dev/null
+++ b/crypto/test/src/asn1/test/SemanticsInformationUnitTest.cs
@@ -0,0 +1,138 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Asn1.X509.Qualified;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ [TestFixture]
+ public class SemanticsInformationUnitTest
+ : SimpleTest
+ {
+ public override string Name
+ {
+ get { return "SemanticsInformation"; }
+ }
+
+ public override void PerformTest()
+ {
+ DerObjectIdentifier statementId = new DerObjectIdentifier("1.1");
+ SemanticsInformation mv = new SemanticsInformation(statementId);
+
+ CheckConstruction(mv, statementId, null);
+
+ GeneralName[] names = new GeneralName[2];
+
+ names[0] = new GeneralName(GeneralName.Rfc822Name, "test@test.org");
+ names[1] = new GeneralName(new X509Name("cn=test"));
+
+ mv = new SemanticsInformation(statementId, names);
+
+ CheckConstruction(mv, statementId, names);
+
+ mv = new SemanticsInformation(names);
+
+ CheckConstruction(mv, null, names);
+
+ mv = SemanticsInformation.GetInstance(null);
+
+ if (mv != null)
+ {
+ Fail("null GetInstance() failed.");
+ }
+
+ try
+ {
+ SemanticsInformation.GetInstance(new object());
+
+ Fail("GetInstance() failed to detect bad object.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ try
+ {
+ new SemanticsInformation(DerSequence.Empty);
+
+ Fail("constructor failed to detect empty sequence.");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+ }
+
+ private void CheckConstruction(
+ SemanticsInformation mv,
+ DerObjectIdentifier semanticsIdentifier,
+ GeneralName[] names)
+ {
+ CheckStatement(mv, semanticsIdentifier, names);
+
+ mv = SemanticsInformation.GetInstance(mv);
+
+ CheckStatement(mv, semanticsIdentifier, names);
+
+ Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(mv.ToAsn1Object().GetEncoded());
+
+ mv = SemanticsInformation.GetInstance(seq);
+
+ CheckStatement(mv, semanticsIdentifier, names);
+ }
+
+ private void CheckStatement(
+ SemanticsInformation si,
+ DerObjectIdentifier id,
+ GeneralName[] names)
+ {
+ if (id != null)
+ {
+ if (!si.SemanticsIdentifier.Equals(id))
+ {
+ Fail("ids don't match.");
+ }
+ }
+ else if (si.SemanticsIdentifier != null)
+ {
+ Fail("statementId found when none expected.");
+ }
+
+ if (names != null)
+ {
+ GeneralName[] siNames = si.GetNameRegistrationAuthorities();
+
+ for (int i = 0; i != siNames.Length; i++)
+ {
+ if (!names[i].Equals(siNames[i]))
+ {
+ Fail("name registration authorities don't match.");
+ }
+ }
+ }
+ else if (si.GetNameRegistrationAuthorities() != null)
+ {
+ Fail("name registration authorities found when none expected.");
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new SemanticsInformationUnitTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/asn1/test/SetTest.cs b/crypto/test/src/asn1/test/SetTest.cs
new file mode 100644
index 000000000..57c46603d
--- /dev/null
+++ b/crypto/test/src/asn1/test/SetTest.cs
@@ -0,0 +1,117 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+ ///
+ * java org.bouncycastle.crypto.examples.DesExample infile outfile [keyfile]
+ *
+ * A new key is generated for each encryption, if key is not specified,
+ * then the example will assume encryption is required, and as output
+ * create deskey.dat in the current directory. This key is a hex
+ * encoded byte-stream that is used for the decryption. The output
+ * file is Hex encoded, 60 characters wide text file.
+ *
+ * When encrypting; + *
+ * When decrypting; + *
+ * This example shows how to use the light-weight API, DES and + * the filesystem for message encryption and decryption. + *
+ */ + public class DesExample + { + // Encrypting or decrypting ? + private bool encrypt = true; + + // To hold the initialised DESede cipher + private PaddedBufferedBlockCipher cipher = null; + + // The input stream of bytes to be processed for encryption + private Stream inStr = null; + + // The output stream of bytes to be procssed + private Stream outStr = null; + + // The key + private byte[] key = null; + + /* + * start the application + */ + public static int Main( + string[] args) + { + bool encrypt = true; + string infile = null; + string outfile = null; + string keyfile = null; + + if (args.Length < 2) + { +// Console.Error.WriteLine("Usage: java " + typeof(DesExample).Name + " infile outfile [keyfile]"); + Console.Error.WriteLine("Usage: " + typeof(DesExample).Name + " infile outfile [keyfile]"); + return 1; + } + + keyfile = "deskey.dat"; + infile = args[0]; + outfile = args[1]; + + if (args.Length > 2) + { + encrypt = false; + keyfile = args[2]; + } + + try + { + DesExample de = new DesExample(infile, outfile, keyfile, encrypt); + de.process(); + } + catch (Exception) + { + return 1; + } + + return 0; + } + + // Default constructor, used for the usage message + public DesExample() + { + } + + /* + * Constructor, that takes the arguments appropriate for + * processing the command line directives. + */ + public DesExample( + string infile, + string outfile, + string keyfile, + bool encrypt) + { + /* + * First, determine that infile & keyfile exist as appropriate. + * + * This will also create the BufferedInputStream as required + * for reading the input file. All input files are treated + * as if they are binary, even if they contain text, it's the + * bytes that are encrypted. + */ + this.encrypt = encrypt; + try + { + inStr = File.OpenRead(infile); + } + catch (FileNotFoundException e) + { + Console.Error.WriteLine("Input file not found ["+infile+"]"); + throw e; + } + + try + { + outStr = File.Create(outfile); + } + catch (IOException e) + { + Console.Error.WriteLine("Output file not created ["+outfile+"]"); + throw e; + } + + if (encrypt) + { + try + { + /* + * The process of creating a new key requires a + * number of steps. + * + * First, create the parameters for the key generator + * which are a secure random number generator, and + * the length of the key (in bits). + */ + SecureRandom sr = new SecureRandom(); + + KeyGenerationParameters kgp = new KeyGenerationParameters( + sr, + DesEdeParameters.DesEdeKeyLength * 8); + + /* + * Second, initialise the key generator with the parameters + */ + DesEdeKeyGenerator kg = new DesEdeKeyGenerator(); + kg.Init(kgp); + + /* + * Third, and finally, generate the key + */ + key = kg.GenerateKey(); + + /* + * We can now output the key to the file, but first + * hex Encode the key so that we can have a look + * at it with a text editor if we so desire + */ + using (Stream keystream = File.Create(keyfile)) + { + Hex.Encode(key, keystream); + } + } + catch (IOException e) + { + Console.Error.WriteLine("Could not decryption create key file "+ + "["+keyfile+"]"); + throw e; + } + } + else + { + try + { + // TODO This block is a bit dodgy + + // read the key, and Decode from hex encoding + Stream keystream = File.OpenRead(keyfile); +// int len = keystream.available(); + int len = (int) keystream.Length; + byte[] keyhex = new byte[len]; + keystream.Read(keyhex, 0, len); + key = Hex.Decode(keyhex); + } + catch (IOException e) + { + Console.Error.WriteLine("Decryption key file not found, " + + "or not valid ["+keyfile+"]"); + throw e; + } + } + } + + private void process() + { + /* + * Setup the DESede cipher engine, create a PaddedBufferedBlockCipher + * in CBC mode. + */ + cipher = new PaddedBufferedBlockCipher( + new CbcBlockCipher(new DesEdeEngine())); + + /* + * The input and output streams are currently set up + * appropriately, and the key bytes are ready to be + * used. + * + */ + + if (encrypt) + { + performEncrypt(key); + } + else + { + performDecrypt(key); + } + + // after processing clean up the files + try + { + inStr.Close(); + outStr.Flush(); + outStr.Close(); + } + catch (IOException) + { + } + } + + /* + * This method performs all the encryption and writes + * the cipher text to the buffered output stream created + * previously. + */ + private void performEncrypt(byte[] key) + { + // initialise the cipher with the key bytes, for encryption + cipher.Init(true, new KeyParameter(key)); + + /* + * Create some temporary byte arrays for use in + * encryption, make them a reasonable size so that + * we don't spend forever reading small chunks from + * a file. + * + * There is no particular reason for using getBlockSize() + * to determine the size of the input chunk. It just + * was a convenient number for the example. + */ + // int inBlockSize = cipher.getBlockSize() * 5; + int inBlockSize = 47; + int outBlockSize = cipher.GetOutputSize(inBlockSize); + + byte[] inblock = new byte[inBlockSize]; + byte[] outblock = new byte[outBlockSize]; + + /* + * now, read the file, and output the chunks + */ + try + { + int inL; + int outL; + while ((inL = inStr.Read(inblock, 0, inBlockSize)) > 0) + { + outL = cipher.ProcessBytes(inblock, 0, inL, outblock, 0); + + /* + * Before we write anything out, we need to make sure + * that we've got something to write out. + */ + if (outL > 0) + { + Hex.Encode(outblock, 0, outL, outStr); + outStr.WriteByte((byte)'\n'); + } + } + + try + { + /* + * Now, process the bytes that are still buffered + * within the cipher. + */ + outL = cipher.DoFinal(outblock, 0); + if (outL > 0) + { + Hex.Encode(outblock, 0, outL, outStr); + outStr.WriteByte((byte) '\n'); + } + } + catch (CryptoException) + { + + } + } + catch (IOException ioeread) + { + Console.Error.WriteLine(ioeread.StackTrace); + } + } + + /* + * This method performs all the decryption and writes + * the plain text to the buffered output stream created + * previously. + */ + private void performDecrypt(byte[] key) + { + // initialise the cipher for decryption + cipher.Init(false, new KeyParameter(key)); + + /* + * As the decryption is from our preformatted file, + * and we know that it's a hex encoded format, then + * we wrap the InputStream with a BufferedReader + * so that we can read it easily. + */ +// BufferedReader br = new BufferedReader(new StreamReader(inStr)); + StreamReader br = new StreamReader(inStr); // 'inStr' already buffered + + /* + * now, read the file, and output the chunks + */ + try + { + int outL; + byte[] inblock = null; + byte[] outblock = null; + string rv = null; + while ((rv = br.ReadLine()) != null) + { + inblock = Hex.Decode(rv); + outblock = new byte[cipher.GetOutputSize(inblock.Length)]; + + outL = cipher.ProcessBytes(inblock, 0, inblock.Length, outblock, 0); + /* + * Before we write anything out, we need to make sure + * that we've got something to write out. + */ + if (outL > 0) + { + outStr.Write(outblock, 0, outL); + } + } + + try + { + /* + * Now, process the bytes that are still buffered + * within the cipher. + */ + outL = cipher.DoFinal(outblock, 0); + if (outL > 0) + { + outStr.Write(outblock, 0, outL); + } + } + catch (CryptoException) + { + + } + } + catch (IOException ioeread) + { + Console.Error.WriteLine(ioeread.StackTrace); + } + } + + } +} diff --git a/crypto/test/src/crypto/io/test/AllTests.cs b/crypto/test/src/crypto/io/test/AllTests.cs new file mode 100644 index 000000000..0296a2dc0 --- /dev/null +++ b/crypto/test/src/crypto/io/test/AllTests.cs @@ -0,0 +1,27 @@ +using System; + +using NUnit.Core; +using NUnit.Framework; + +namespace Org.BouncyCastle.Crypto.IO.Tests +{ + public class AllTests + { + public static void Main( + string[] args) + { +// junit.textui.TestRunner.run(suite()); + EventListener el = new NullListener(); + suite().Run(el); + } + + public static TestSuite suite() + { + TestSuite suite = new TestSuite("IO tests"); + + suite.Add(new CipherStreamTest()); + + return suite; + } + } +} diff --git a/crypto/test/src/crypto/io/test/CipherStreamTest.cs b/crypto/test/src/crypto/io/test/CipherStreamTest.cs new file mode 100644 index 000000000..8f03c5770 --- /dev/null +++ b/crypto/test/src/crypto/io/test/CipherStreamTest.cs @@ -0,0 +1,166 @@ +using System; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.IO.Tests +{ + [TestFixture] + public class CipherStreamTest + { + private const string DATA = "This will be encrypted and then decrypted and checked for correctness"; + + [Test] + public void TestEncryptDecryptA() + { + byte[] dataBytes = Encoding.ASCII.GetBytes(DATA); + byte[] encryptedDataBytes = encryptOnWrite(dataBytes); + + byte[] decryptedDataBytes = decryptOnRead(encryptedDataBytes); + string decryptedData = Encoding.ASCII.GetString(decryptedDataBytes, 0, decryptedDataBytes.Length); + Assert.AreEqual(DATA, decryptedData); + } + + [Test] + public void TestEncryptDecryptB() + { + byte[] dataBytes = Encoding.ASCII.GetBytes(DATA); + byte[] encryptedDataBytes = encryptOnRead(dataBytes); + + byte[] decryptedDataBytes = decryptOnWrite(encryptedDataBytes); + string decryptedData = Encoding.ASCII.GetString(decryptedDataBytes, 0, decryptedDataBytes.Length); + Assert.AreEqual(DATA, decryptedData); + } + + [Test] + public void TestEncryptDecryptC() + { + byte[] dataBytes = Encoding.ASCII.GetBytes(DATA); + byte[] encryptedDataBytes = encryptOnWrite(dataBytes); + + byte[] decryptedDataBytes = decryptOnWrite(encryptedDataBytes); + string decryptedData = Encoding.ASCII.GetString(decryptedDataBytes, 0, decryptedDataBytes.Length); + Assert.AreEqual(DATA, decryptedData); + } + + [Test] + public void TestEncryptDecryptD() + { + byte[] dataBytes = Encoding.ASCII.GetBytes(DATA); + byte[] encryptedDataBytes = encryptOnRead(dataBytes); + + byte[] decryptedDataBytes = decryptOnRead(encryptedDataBytes); + string decryptedData = Encoding.ASCII.GetString(decryptedDataBytes, 0, decryptedDataBytes.Length); + Assert.AreEqual(DATA, decryptedData); + } + + private byte[] encryptOnWrite(byte[] dataBytes) + { + MemoryStream encryptedDataStream = new MemoryStream(); + IBufferedCipher outCipher = createCipher(true); + CipherStream outCipherStream = new CipherStream(encryptedDataStream, null, outCipher); + outCipherStream.Write(dataBytes, 0, dataBytes.Length); + Assert.AreEqual(0L, encryptedDataStream.Position % outCipher.GetBlockSize()); + + outCipherStream.Close(); + byte[] encryptedDataBytes = encryptedDataStream.ToArray(); + Assert.AreEqual(dataBytes.Length, encryptedDataBytes.Length); + + return encryptedDataBytes; + } + + private byte[] encryptOnRead(byte[] dataBytes) + { + MemoryStream dataStream = new MemoryStream(dataBytes, false); + MemoryStream encryptedDataStream = new MemoryStream(); + IBufferedCipher inCipher = createCipher(true); + CipherStream inCipherStream = new CipherStream(dataStream, inCipher, null); + + int ch; + while ((ch = inCipherStream.ReadByte()) >= 0) + { + encryptedDataStream.WriteByte((byte) ch); + } + + encryptedDataStream.Close(); + inCipherStream.Close(); + + byte[] encryptedDataBytes = encryptedDataStream.ToArray(); + Assert.AreEqual(dataBytes.Length, encryptedDataBytes.Length); + + return encryptedDataBytes; + } + + private byte[] decryptOnRead(byte[] encryptedDataBytes) + { + MemoryStream encryptedDataStream = new MemoryStream(encryptedDataBytes, false); + MemoryStream dataStream = new MemoryStream(); + IBufferedCipher inCipher = createCipher(false); + CipherStream inCipherStream = new CipherStream(encryptedDataStream, inCipher, null); + + int ch; + while ((ch = inCipherStream.ReadByte()) >= 0) + { + dataStream.WriteByte((byte) ch); + } + + inCipherStream.Close(); + dataStream.Close(); + + byte[] dataBytes = dataStream.ToArray(); + Assert.AreEqual(encryptedDataBytes.Length, dataBytes.Length); + + return dataBytes; + } + + private byte[] decryptOnWrite(byte[] encryptedDataBytes) + { + MemoryStream encryptedDataStream = new MemoryStream(encryptedDataBytes, false); + MemoryStream dataStream = new MemoryStream(); + IBufferedCipher outCipher = createCipher(false); + CipherStream outCipherStream = new CipherStream(dataStream, null, outCipher); + + int ch; + while ((ch = encryptedDataStream.ReadByte()) >= 0) + { + outCipherStream.WriteByte((byte) ch); + } + + outCipherStream.Close(); + encryptedDataStream.Close(); + + byte[] dataBytes = dataStream.ToArray(); + Assert.AreEqual(encryptedDataBytes.Length, dataBytes.Length); + + return dataBytes; + } + + private IBufferedCipher createCipher(bool forEncryption) + { +// IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CFB/NoPadding"); + + IBlockCipher blockCipher = new AesEngine(); + int bits = 8 * blockCipher.GetBlockSize(); // TODO Is this right? + blockCipher = new CfbBlockCipher(blockCipher, bits); + IBufferedCipher cipher = new BufferedBlockCipher(blockCipher); + +// SecureRandom random = new SecureRandom(); + byte[] keyBytes = new byte[32]; + //random.NextBytes(keyBytes); + KeyParameter key = new KeyParameter(keyBytes); + + byte[] iv = new byte[cipher.GetBlockSize()]; + //random.NextBytes(iv); + + cipher.Init(forEncryption, new ParametersWithIV(key, iv)); + + return cipher; + } + } +} diff --git a/crypto/test/src/crypto/test/AESFastTest.cs b/crypto/test/src/crypto/test/AESFastTest.cs new file mode 100644 index 000000000..5513a0e78 --- /dev/null +++ b/crypto/test/src/crypto/test/AESFastTest.cs @@ -0,0 +1,168 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Crypto.Tests +{ + /** + * Test vectors from the NIST standard tests and Brian Gladman's vector set + * + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + */ + [TestFixture] + public class AesFastTest + : CipherTest + { + static SimpleTest[] tests = + { + new BlockCipherVectorTest(0, new AesFastEngine(), + new KeyParameter(Hex.Decode("80000000000000000000000000000000")), + "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), + new BlockCipherVectorTest(1, new AesFastEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000080")), + "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), + new BlockCipherMonteCarloTest(2, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000000")), + "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), + new BlockCipherMonteCarloTest(3, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("5F060D3716B345C253F6749ABAC10917")), + "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), + new BlockCipherVectorTest(4, new AesFastEngine(), + new KeyParameter(Hex.Decode("000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), + new BlockCipherMonteCarloTest(5, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), + "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), + new BlockCipherVectorTest(6, new AesFastEngine(), + new KeyParameter(Hex.Decode("0000000000000000000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), + new BlockCipherMonteCarloTest(7, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), + "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), + new BlockCipherVectorTest(8, new AesFastEngine(), + new KeyParameter(Hex.Decode("80000000000000000000000000000000")), + "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), + new BlockCipherVectorTest(9, new AesFastEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000080")), + "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), + new BlockCipherMonteCarloTest(10, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000000")), + "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), + new BlockCipherMonteCarloTest(11, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("5F060D3716B345C253F6749ABAC10917")), + "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), + new BlockCipherVectorTest(12, new AesFastEngine(), + new KeyParameter(Hex.Decode("000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), + new BlockCipherMonteCarloTest(13, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), + "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), + new BlockCipherVectorTest(14, new AesFastEngine(), + new KeyParameter(Hex.Decode("0000000000000000000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), + new BlockCipherMonteCarloTest(15, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), + "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), + new BlockCipherVectorTest(16, new AesFastEngine(), + new KeyParameter(Hex.Decode("80000000000000000000000000000000")), + "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), + new BlockCipherVectorTest(17, new AesFastEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000080")), + "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), + new BlockCipherMonteCarloTest(18, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000000")), + "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), + new BlockCipherMonteCarloTest(19, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("5F060D3716B345C253F6749ABAC10917")), + "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), + new BlockCipherVectorTest(20, new AesFastEngine(), + new KeyParameter(Hex.Decode("000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), + new BlockCipherMonteCarloTest(21, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), + "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), + new BlockCipherVectorTest(22, new AesFastEngine(), + new KeyParameter(Hex.Decode("0000000000000000000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), + new BlockCipherMonteCarloTest(23, 10000, new AesFastEngine(), + new KeyParameter(Hex.Decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), + "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168") + }; + + private IBlockCipher _engine = new AesFastEngine(); + + public AesFastTest() + : base(tests, new AesFastEngine(), new KeyParameter(new byte[16])) + { + } + + public override string Name + { + get + { + return "AESFast"; + } + } + + public override void PerformTest() + { + base.PerformTest(); + + byte[] keyBytes = new byte[16]; + + _engine.Init(true, new KeyParameter(keyBytes)); + + // + // init tests + // + try + { + byte[] dudKey = new byte[6]; + + _engine.Init(true, new KeyParameter(dudKey)); + + Fail("failed key length check"); + } + catch (ArgumentException) + { + // expected + } + + try + { + byte[] iv = new byte[16]; + + _engine.Init(true, new ParametersWithIV(null, iv)); + + Fail("failed parameter check"); + } + catch (ArgumentException) + { + // expected + } + } + + public static void Main( + string[] args) + { + AesFastTest test = new AesFastTest(); + ITestResult result = test.Perform(); + + Console.WriteLine(result); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/crypto/test/AESLightTest.cs b/crypto/test/src/crypto/test/AESLightTest.cs new file mode 100644 index 000000000..0b5777ba1 --- /dev/null +++ b/crypto/test/src/crypto/test/AESLightTest.cs @@ -0,0 +1,168 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Crypto.Tests +{ + /** + * Test vectors from the NIST standard tests and Brian Gladman's vector set + * + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + */ + [TestFixture] + public class AesLightTest + : CipherTest + { + static SimpleTest[] tests = + { + new BlockCipherVectorTest(0, new AesLightEngine(), + new KeyParameter(Hex.Decode("80000000000000000000000000000000")), + "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), + new BlockCipherVectorTest(1, new AesLightEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000080")), + "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), + new BlockCipherMonteCarloTest(2, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000000")), + "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), + new BlockCipherMonteCarloTest(3, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("5F060D3716B345C253F6749ABAC10917")), + "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), + new BlockCipherVectorTest(4, new AesLightEngine(), + new KeyParameter(Hex.Decode("000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), + new BlockCipherMonteCarloTest(5, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), + "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), + new BlockCipherVectorTest(6, new AesLightEngine(), + new KeyParameter(Hex.Decode("0000000000000000000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), + new BlockCipherMonteCarloTest(7, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), + "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), + new BlockCipherVectorTest(8, new AesLightEngine(), + new KeyParameter(Hex.Decode("80000000000000000000000000000000")), + "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), + new BlockCipherVectorTest(9, new AesLightEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000080")), + "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), + new BlockCipherMonteCarloTest(10, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000000")), + "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), + new BlockCipherMonteCarloTest(11, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("5F060D3716B345C253F6749ABAC10917")), + "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), + new BlockCipherVectorTest(12, new AesLightEngine(), + new KeyParameter(Hex.Decode("000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), + new BlockCipherMonteCarloTest(13, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), + "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), + new BlockCipherVectorTest(14, new AesLightEngine(), + new KeyParameter(Hex.Decode("0000000000000000000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), + new BlockCipherMonteCarloTest(15, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), + "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168"), + new BlockCipherVectorTest(16, new AesLightEngine(), + new KeyParameter(Hex.Decode("80000000000000000000000000000000")), + "00000000000000000000000000000000", "0EDD33D3C621E546455BD8BA1418BEC8"), + new BlockCipherVectorTest(17, new AesLightEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000080")), + "00000000000000000000000000000000", "172AEAB3D507678ECAF455C12587ADB7"), + new BlockCipherMonteCarloTest(18, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("00000000000000000000000000000000")), + "00000000000000000000000000000000", "C34C052CC0DA8D73451AFE5F03BE297F"), + new BlockCipherMonteCarloTest(19, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("5F060D3716B345C253F6749ABAC10917")), + "355F697E8B868B65B25A04E18D782AFA", "ACC863637868E3E068D2FD6E3508454A"), + new BlockCipherVectorTest(20, new AesLightEngine(), + new KeyParameter(Hex.Decode("000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "6CD02513E8D4DC986B4AFE087A60BD0C"), + new BlockCipherMonteCarloTest(21, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114")), + "F3F6752AE8D7831138F041560631B114", "77BA00ED5412DFF27C8ED91F3C376172"), + new BlockCipherVectorTest(22, new AesLightEngine(), + new KeyParameter(Hex.Decode("0000000000000000000000000000000000000000000000000000000000000000")), + "80000000000000000000000000000000", "DDC6BF790C15760D8D9AEB6F9A75FD4E"), + new BlockCipherMonteCarloTest(23, 10000, new AesLightEngine(), + new KeyParameter(Hex.Decode("28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386")), + "C737317FE0846F132B23C8C2A672CE22", "E58B82BFBA53C0040DC610C642121168") + }; + + private IBlockCipher _engine = new AesLightEngine(); + + public AesLightTest() + : base(tests, new AesLightEngine(), new KeyParameter(new byte[16])) + { + } + + public override string Name + { + get + { + return "AESLight"; + } + } + + public override void PerformTest() + { + base.PerformTest(); + + byte[] keyBytes = new byte[16]; + + _engine.Init(true, new KeyParameter(keyBytes)); + + // + // init tests + // + try + { + byte[] dudKey = new byte[6]; + + _engine.Init(true, new KeyParameter(dudKey)); + + Fail("failed key length check"); + } + catch (ArgumentException) + { + // expected + } + + try + { + byte[] iv = new byte[16]; + + _engine.Init(true, new ParametersWithIV(null, iv)); + + Fail("failed parameter check"); + } + catch (ArgumentException) + { + // expected + } + } + + public static void Main( + string[] args) + { + AesLightTest test = new AesLightTest(); + ITestResult result = test.Perform(); + + Console.WriteLine(result); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/crypto/test/AESTest.cs b/crypto/test/src/crypto/test/AESTest.cs new file mode 100644 index 000000000..7b8fc34cf --- /dev/null +++ b/crypto/test/src/crypto/test/AESTest.cs @@ -0,0 +1,178 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Crypto.Tests +{ + ///+ * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf + * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf + *+ * See HCFamilyVecTest for a more exhaustive test based on the ecrypt vectors. + */ + public class HCFamilyTest + : SimpleTest + { + private static readonly byte[] MSG = new byte[64]; + + private static readonly string[][] HC128_VerifiedTest = new string[][] + { + new string[]{ + "Set 2, vector# 0", + "00000000000000000000000000000000", + "00000000000000000000000000000000", + "82001573A003FD3B7FD72FFB0EAF63AA" + + "C62F12DEB629DCA72785A66268EC758B" + + "1EDB36900560898178E0AD009ABF1F49" + + "1330DC1C246E3D6CB264F6900271D59C" + }, + new string[]{ + "Set 6, vector# 0", + "0053A6F94C9FF24598EB3E91E4378ADD", + "0D74DB42A91077DE45AC137AE148AF16", + "2E1ED12A8551C05AF41FF39D8F9DF933" + + "122B5235D48FC2A6F20037E69BDBBCE8" + + "05782EFC16C455A4B3FF06142317535E" + + "F876104C32445138CB26EBC2F88A684C" + }, + new string[]{ + "Set 6, vector# 1", + "0558ABFE51A4F74A9DF04396E93C8FE2", + "167DE44BB21980E74EB51C83EA51B81F", + "4F864BF3C96D0363B1903F0739189138" + + "F6ED2BC0AF583FEEA0CEA66BA7E06E63" + + "FB28BF8B3CA0031D24ABB511C57DD17B" + + "FC2861C32400072CB680DF2E58A5CECC" + }, + new string[]{ + "Set 6, vector# 2", + "0A5DB00356A9FC4FA2F5489BEE4194E7", + "1F86ED54BB2289F057BE258CF35AC128", + "82168AB0023B79AAF1E6B4D823855E14" + + "A7084378036A951B1CFEF35173875ED8" + + "6CB66AB8410491A08582BE40080C3102" + + "193BA567F9E95D096C3CC60927DD7901" + }, + new string[]{ + "Set 6, vector# 3", + "0F62B5085BAE0154A7FA4DA0F34699EC", + "288FF65DC42B92F960C72E95FC63CA31", + "1CD8AEDDFE52E217E835D0B7E84E2922" + + "D04B1ADBCA53C4522B1AA604C42856A9" + + "0AF83E2614BCE65C0AECABDD8975B557" + + "00D6A26D52FFF0888DA38F1DE20B77B7" + } + }; + + private static readonly string[][] HC256_VerifiedTest = new string[][] + { + new string[]{ + "Set 2, vector# 0", + "00000000000000000000000000000000", + "00000000000000000000000000000000", + "5B078985D8F6F30D42C5C02FA6B67951" + + "53F06534801F89F24E74248B720B4818" + + "CD9227ECEBCF4DBF8DBF6977E4AE14FA" + + "E8504C7BC8A9F3EA6C0106F5327E6981" + }, + new string[]{ + "Set 2, vector# 9", + "09090909090909090909090909090909", + "00000000000000000000000000000000", + "F5C2926651AEED9AF1A9C2F04C03D081" + + "2145B56AEA46EB283A25A4C9E3D8BEB4" + + "821B418F06F2B9DCDF1A85AB8C02CD14" + + "62E1BBCAEC9AB0E99AA6AFF918BA627C" + }, + new string[]{ + "Set 2, vector#135", + "87878787878787878787878787878787", + "00000000000000000000000000000000", + "CEC0C3852E3B98233EBCB975C10B1191" + + "3C69F2275EB97A1402EDF16C6FBE19BE" + + "79D65360445BCB63676E6553B609A065" + + "0155C3B22DD1975AC0F3F65063A2E16E" + }, + new string[]{ + "Set 6, vector# 0", + "0053A6F94C9FF24598EB3E91E4378ADD" + + "3083D6297CCF2275C81B6EC11467BA0D", + "0D74DB42A91077DE45AC137AE148AF16" + + "7DE44BB21980E74EB51C83EA51B81F86", + "23D9E70A45EB0127884D66D9F6F23C01" + + "D1F88AFD629270127247256C1FFF91E9" + + "1A797BD98ADD23AE15BEE6EEA3CEFDBF" + + "A3ED6D22D9C4F459DB10C40CDF4F4DFF" + }, + new string[]{ + "Set 6, vector# 1", + "0558ABFE51A4F74A9DF04396E93C8FE2" + + "3588DB2E81D4277ACD2073C6196CBF12", + "167DE44BB21980E74EB51C83EA51B81F" + + "86ED54BB2289F057BE258CF35AC1288F", + "C44B5262F2EAD9C018213127686DB742" + + "A72D3F2D61D18F0F4E7DE5B4F7ADABE0" + + "7E0C82033B139F02BAACB4E2F2D0BE30" + + "110C3A8A2B621523756692877C905DD0" + }, + new string[]{ + "Set 6, vector# 2", + "0A5DB00356A9FC4FA2F5489BEE4194E7" + + "3A8DE03386D92C7FD22578CB1E71C417", + "1F86ED54BB2289F057BE258CF35AC128" + + "8FF65DC42B92F960C72E95FC63CA3198", + "9D13AA06122F4F03AE60D507701F1ED0" + + "63D7530FF35EE76CAEDCBFB01D8A239E" + + "FA4A44B272DE9B4092E2AD56E87C3A60" + + "89F5A074D1F6E5B8FC6FABEE0C936F06" + }, + new string[]{ + "Set 6, vector# 3", + "0F62B5085BAE0154A7FA4DA0F34699EC" + + "3F92E5388BDE3184D72A7DD02376C91C", + "288FF65DC42B92F960C72E95FC63CA31" + + "98FF66CD349B0269D0379E056CD33AA1", + "C8632038DA61679C4685288B37D3E232" + + "7BC2D28C266B041FE0CA0D3CFEED8FD5" + + "753259BAB757168F85EA96ADABD823CA" + + "4684E918423E091565713FEDDE2CCFE0" + } + }; + + public override string Name + { + get { return "HC-128 and HC-256"; } + } + + public override void PerformTest() + { + IStreamCipher hc = new HC256Engine(); + + for (int i = 0; i != HC256_VerifiedTest.Length; i++) + { + string[] test = HC256_VerifiedTest[i]; + HCTest(hc, "HC-256 - " + test[0], Hex.Decode(test[1]), Hex.Decode(test[2]), Hex.Decode(test[3])); + } + + hc = new HC128Engine(); + + for (int i = 0; i != HC128_VerifiedTest.Length; i++) + { + string[] test = HC128_VerifiedTest[i]; + HCTest(hc, "HC-128 - " + test[0], Hex.Decode(test[1]), Hex.Decode(test[2]), Hex.Decode(test[3])); + } + } + + private void HCTest(IStreamCipher hc, string test, byte[] key, byte[] IV, byte[] expected) + { + KeyParameter kp = new KeyParameter(key); + ParametersWithIV ivp = new ParametersWithIV(kp, IV); + + hc.Init(true, ivp); + for (int i = 0; i < 64; i++) + { + if (hc.ReturnByte(MSG[i]) != expected[i]) + { + Fail(test + " failure at byte " + i); + } + } + } + + public static void Main(string[] args) + { + RunTest(new HCFamilyTest()); + } + } +} diff --git a/crypto/test/src/crypto/test/HCFamilyVecTest.cs b/crypto/test/src/crypto/test/HCFamilyVecTest.cs new file mode 100644 index 000000000..00b0ee75c --- /dev/null +++ b/crypto/test/src/crypto/test/HCFamilyVecTest.cs @@ -0,0 +1,184 @@ +using System; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Crypto.Tests +{ + /** + * HC-128 and HC-256 Tests. Based on the test vectors in the official reference + * papers, respectively: + * + * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf + * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf + */ + [TestFixture] + public class HCFamilyVecTest + : SimpleTest + { + private class PeekableLineReader + : StreamReader + { + public PeekableLineReader(Stream s) + : base(s) + { + peek = base.ReadLine(); + } + + public string PeekLine() + { + return peek; + } + + public override string ReadLine() + { + string tmp = peek; + peek = base.ReadLine(); + return tmp; + } + + private string peek; + } + + public override string Name + { + get { return "HC-128 and HC-256"; } + } + + public override void PerformTest() + { + RunTests(new HC128Engine(), "hc128/ecrypt_HC-128.txt"); + RunTests(new HC256Engine(), "hc256/ecrypt_HC-256_128K_128IV.txt"); + RunTests(new HC256Engine(), "hc256/ecrypt_HC-256_256K_128IV.txt"); + RunTests(new HC256Engine(), "hc256/ecrypt_HC-256_128K_256IV.txt"); + RunTests(new HC256Engine(), "hc256/ecrypt_HC-256_256K_256IV.txt"); + } + + private void RunTests(IStreamCipher hc, string fileName) + { + Stream resource = SimpleTest.GetTestDataAsStream( + "hc256." + fileName.Replace('/', '.')); + PeekableLineReader r = new PeekableLineReader(resource); + RunAllVectors(hc, fileName, r); + } + + private void RunAllVectors(IStreamCipher hc, string fileName, PeekableLineReader r) + { + for (;;) + { + string line = r.ReadLine(); + if (line == null) + break; + + line = line.Trim(); + + if (line.StartsWith("Set ")) + { + RunVector(hc, fileName, r, line.Replace(":", "")); + } + } + } + + private void RunVector(IStreamCipher hc, string fileName, PeekableLineReader r, string vectorName) + { +// Console.WriteLine(fileName + " => " + vectorName); + string hexKey = ReadBlock(r); + string hexIV = ReadBlock(r); + + ICipherParameters cp = new KeyParameter(Hex.Decode(hexKey)); + cp = new ParametersWithIV(cp, Hex.Decode(hexIV)); + hc.Init(true, cp); + + byte[] input = new byte[64]; + byte[] output = new byte[64]; + byte[] digest = new byte[64]; + int pos = 0; + + for (;;) + { + string line1 = r.PeekLine().Trim(); + int equalsPos = line1.IndexOf('='); + string lead = line1.Substring(0, equalsPos - 1); + + string hexData = ReadBlock(r); + byte[] data = Hex.Decode(hexData); + + if (lead.Equals("xor-digest")) + { + if (!Arrays.AreEqual(data, digest)) + { + Fail("Failed in " + fileName + " for test vector: " + vectorName + " at " + lead); +// Console.WriteLine(fileName + " => " + vectorName + " failed at " + lead); return; + } + break; + } + + int posA = lead.IndexOf('['); + int posB = lead.IndexOf(".."); + int posC = lead.IndexOf(']'); + int start = Int32.Parse(lead.Substring(posA + 1, posB - (posA + 1))); + int end = Int32.Parse(lead.Substring(posB + 2, posC - (posB + 2))); + + if (start % 64 != 0 || (end - start != 63)) + throw new InvalidOperationException(vectorName + ": " + lead + " not on 64 byte boundaries"); + + while (pos < end) + { + hc.ProcessBytes(input, 0, input.Length, output, 0); + xor(digest, output); + pos += 64; + } + + if (!Arrays.AreEqual(data, output)) + { + Fail("Failed in " + fileName + " for test vector: " + vectorName + " at " + lead); +// Console.WriteLine(fileName + " => " + vectorName + " failed at " + lead); return; + } + } + } + + private static string ReadBlock(PeekableLineReader r) + { + string first = r.ReadLine().Trim(); + string result = first.Substring(first.LastIndexOf(' ') + 1); + + for (;;) + { + string peek = r.PeekLine().Trim(); + if (peek.Length < 1 || peek.IndexOf('=') >= 0) + break; + result += r.ReadLine().Trim(); + } + + return result; + } + + private static void xor(byte[] digest, byte[] block) + { + for (int i = 0; i < digest.Length; ++i) + { + digest[i] ^= block[i]; + } + } + + public static void Main( + string[] args) + { + RunTest(new HCFamilyVecTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/crypto/test/IDEATest.cs b/crypto/test/src/crypto/test/IDEATest.cs new file mode 100644 index 000000000..6ae822271 --- /dev/null +++ b/crypto/test/src/crypto/test/IDEATest.cs @@ -0,0 +1,57 @@ +#if INCLUDE_IDEA + +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Crypto.Tests +{ + [TestFixture] + public class IdeaTest + : CipherTest + { + public override string Name + { + get { return "IDEA"; } + } + + internal static SimpleTest[] tests = new SimpleTest[] + { + new BlockCipherVectorTest(0, new IdeaEngine(), + new KeyParameter(Hex.Decode("00112233445566778899AABBCCDDEEFF")), + "000102030405060708090a0b0c0d0e0f", + "ed732271a7b39f475b4b2b6719f194bf"), + new BlockCipherVectorTest(0, new IdeaEngine(), + new KeyParameter(Hex.Decode("00112233445566778899AABBCCDDEEFF")), + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "b8bc6ed5c899265d2bcfad1fc6d4287d") + }; + + public IdeaTest() + : base(tests, new IdeaEngine(), new KeyParameter(new byte[32])) + { + } + + public static void Main( + string[] args) + { + ITest test = new IdeaTest(); + ITestResult result = test.Perform(); + Console.WriteLine(result); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} + +#endif diff --git a/crypto/test/src/crypto/test/ISAACTest.cs b/crypto/test/src/crypto/test/ISAACTest.cs new file mode 100644 index 000000000..1782bbc98 --- /dev/null +++ b/crypto/test/src/crypto/test/ISAACTest.cs @@ -0,0 +1,196 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Crypto.Tests +{ + /** + * ISAAC Test - see http://www.burtleburtle.net/bob/rand/isaacafa.html + */ + [TestFixture] + public class IsaacTest + : SimpleTest + { + byte[] outBase = Hex.Decode( + "f650e4c8e448e96d98db2fb4f5fad54f433f1afbedec154ad837048746ca4f9a" + + "5de3743e88381097f1d444eb823cedb66a83e1e04a5f6355c744243325890e2e" + + "7452e31957161df638a824f3002ed71329f5544951c08d83d78cb99ea0cc74f3" + + "8f651659cbc8b7c2f5f71c6912ad6419e5792e1b860536b809b3ce98d45d6d81" + + "f3b2612917e38f8529cf72ce349947b0c998f9ffb5e13dae32ae2a2bf7cf814c" + + "8ebfa303cf22e0640b923200eca4d58aef53cec4d0f7b37d9c411a2affdf8a80" + + "b40e27bcb4d2f97644b89b08f37c71d51a70e7e90bdb9c3060dc5207b3c3f24b" + + "d7386806229749b54e232cd091dabc65a70e11018b87437e5781414fcdbc62e2" + + "8107c9ff69d2e4ae3b18e752b143b6886f4e077295138769943c3c74afc17a97" + + "0fd439636a529b0bd8c58a6aa8bcc22d2db35dfea7a2f4026cb167db538e1f4e" + + "7275e2771d3b8e97ecc5dc9115e3a5b90369661430ab93ecac9fe69d7bc76811" + + "60eda8da28833522d5295ebc5adb60e7f7e1cdd097166d14b67ec13a210f3925" + + "64af0fef0d0286843aea3decb058bafbb8b0ccfcf2b5cc05e3a662d9814bc24c" + + "2364a1aa37c0ed052b36505c451e7ec85d2a542fe43d0fbb91c8d92560d4d5f8" + + "12a0594b9e8a51dacd49ebdb1b0dcdc1cd57c7f7e63444517ded386f2f36fa86" + + "a6d1210133bc405db388d96cdb6dbe96fe29661c13edc0cbcb0eee4a70cc94ae" + + "de11ed340606cf9f3a6ce38923d74f4ea37f63ff917bdec2d73f72d40e7e0e67" + + "3d77d9a213add9228891b3db01a9bd7056a001e3d51f093dcc033ce35ad0d3b0" + + "34105a8c6a123f57bd2e50247364944be89b1a3b21835c4d9f39e2d9d405ded8" + + "294d37e5bccaaeed35a124b56708a2bcb00960ba2a98121a4d8fae820bb3263f" + + "12595a196a1075890809e49421c171ec884d682514c8009bb0b84e7b03fb88f4" + + "28e7cb789388b13bdd2dc1d5848f520a07c28cd168a3935872c9137d127dd430" + + "c613f1578c2f0d55f7d3f39f309bfb788406b13746c0a6f53718d59708607f04" + + "76904b6d04db4e13cd7411a7b510ce0ebfc7f7ccb83f957afdfef62dc35e4580" + + "3ff1e5244112d96c02c9b944d5990dfbe7e265810d9c7e7e826dfa8966f1e0ab" + + "30bcc764eadebeaced35e5ee0c571a7de4f3a26af7f58f7badf6bc235d023e65" + + "1ed3ff4eec46b0b6d2a93b51e75b41c97e315aeb61119a5a53245b7933f6d7b1" + + "cae8deba50fc8194afa92a6dc87c80064188bfcd8bace62e78ffa5685597ec0f" + + "b4415f7d08294766ad56764309c36f903dde9f394a0a283c18080c8e080c79ec" + + "79ae4c10cb9e15637cdd662f62d31911a4ca0cf15cf824cd3b708f991e16614c" + + "b6b9d7665de87abb7229ea81d5b2d75056e6cd21fe1e42d596da2655c2b9aa36" + + "b8f6fd4a6a158d1001913fd3af7d1fb80b5e435f90c107576554abda7a68710f" + + "82ac484fd7e1c7be95c85eaa94a302f44d3cfbda786b29081010b27582d53d12" + + "21e2a51c3d1e9150b059261dd0638e1a31860f0581f2864dff4cfc350451516d" + + "bd086f26bc5654c165dfa427a82427f5582e3014b8d2486dc79a17499a1d7745" + + "8766bb541e04a7f73d3dff8ad5ec6bf4dbef7d9f36ec0ea31feb2e4f15cfcc5c" + + "d8c423fbd0ef3cc9eb244925ba5590c8a5f48ac433c5321c613b67b2479c3a22" + + "e21339cc10d210aa931dd7e2ef05ee06b82f2703a385cb2c5d67133c877eb7b4" + + "1e3437f75afb43ae53c078f394d904811d96458908063a85e13222281956b1e5" + + "31860f132e7b022f21182ca396f703ac46819e2e0d28fe523724d4dca0eabe6b" + + "c66699fdc6112fdd19c1e69c04d3658a4b55dd9931907d62f854b5224d678f26" + + "22ae0582eafed133e4a51d2184bd6dd6c1a513753f28ee63fb737b1a70a1660e" + + "8a8dfaa31be79937f7476978513c1764531ac6bf12c06908001cdb951a4b6a53" + + "d067fce512b2cfb69ddb477f740e006639ddf25acc8bfa2df1b20eaf64f2632c" + + "9783cdee63bfd4d80084cfe575f4e9e219b48fd06c48ddd87a36af9371865c4c" + + "9ce0199d867027d72cb7b77f84ef01da72f5972f040f7074df9afa29c921f94e" + + "75c08a3618c1ef9ad649a428c5b719378a30738ad97cd348858129a6239e3b0a" + + "bbb8abc480fac4c2ecfcf20bd9d711f9e2a4ef71b5fe87c0be8b06b2aafef5a7" + + "9c15db3b0aeb81654389a84a253b1d7a19047c797cdc78a2d20adf0356f55a71" + + "3e730fa8fd8650d8959e234eb7546681dad1b22a142a6e858ef4bce668235b9d" + + "85a13f8574096ae7a949bea229322d0dd568385882846526403dae086dd1943a" + + "e1279bff9e7e4f041c3a4524484525e481d4cc5fe24124c0037464c0bf1bd691" + + "26ceb003275ead3ac5bde90826414ff3a30519add7b43abe2ce5d3d588412761" + + "97ca2070e5fbb9c7276df0b4308f751f37a97df6c9cd808cfe4cb3803d469303" + + "aee19096c0d5d42a4e823ad3f5f9cc3b4286619c9ca45e1c66c97340891aec49" + + "45bae606c798f04752649d6cce86fdfc80c6e402d6ec2f2b27c822821fe26ce0" + + "92f57ea7de462f4d07497cae5a48755c721502dd6cbe7935836d80039ead7f70" + + "9ab3a42f4c8652d632e39273e8fa38601da4f25a0cd6ef8102503f7d8854a0a1" + + "9a30c4e88815715305efe29457c4c9252887d96fc1a71e3ce9f841632d0985de" + + "d21e796c6fb5ce5602614abfc3c7be2cb54fed6fa617a083c3142d8f6079e4ce" + + "ceffc1471d0cb81bdc153e5fe36ef5bbd531161a165b10157aa114ed3f7579b3" + + "f7f395f1bc6172c7a86f875e0e6c51b3cdfec2af73c0e762824c2009c5a87748" + + "94d401258aba3ffbd32be0608c17eff021e2547e07cffad905340e15f3310c92" + + "9d8d190886ba527ff943f672ef73fbf046d95ca5c54cd95b9d855e894bb5af29"); + + byte[] outFFFFFFFF = Hex.Decode( + "de3b3f3c19e0629c1fc8b7836695d523e7804edd86ff7ce9b106f52caebae9d9" + + "72f845d49ce17d7da44e49bae954aac0d0b1284b98a88eec1524fb6bc91a16b5" + + "1192ac5334131446ac2442de9ff3d5867b9b9148881ee30a6e87dd88e5d1f7cd" + + "98db31ff36f70d9850cfefaef42abb00ecc39ed308bf4b8030cdc2b6b7e42f0e" + + "908030dd282f96edacc888b3a986e109c129998f89baa1b5da8970b07a6ab012" + + "f10264f23c315c9c8e0c164955c68517b6a4f982b2626db70787f869ac6d551b" + + "e34931627c7058e965c502e18d2cd370e6db3b70d947d61aa9717cf8394f48c6" + + "3c796f3a154950846badb28b70d982f29bc670254e3e5e0f8e36b0a5f6da0a04" + + "6b235ed6a42988c012bde74d879fa8eb5d59f5f40ed5e76601c9847b3edb2690"); + + byte[] outFFFF0000 = Hex.Decode( + "26c54b1f8c4e3fc582e9e8180f7aba5380463dcf58b03cbeda0ecc8ba90ccff8" + + "5bd50896313d7efed44015faeac6964b241a7fb8a2e37127a7cbea0fd7c020f2" + + "406371b87ef5185089504751e5e44352eff63e00e5c28f5dff0616a9a3a00f1f" + + "4a1350e3a17be9abddfc2c94571450a0dc4c3c0c7c7f98e80c95f607d50c676a" + + "9a3006f9d279a79a4d66b2ab0c52930c9ee84bc09895e70fa041b1a3a2966f11" + + "6a47fd09705124b1f5c7ae055e54536e66584b1608f3612d81b72f109a385831" + + "121945b207b90ac72437a248f27a121c2801f4153a8699fb047e193f7ba69e1b" + + "b117869675d4c963e6070c2ca3d332ce830cb5e3d9ed2eee7faf0acc20fbe154" + + "188ae789e95bd5c1f459dbd150aab6eb833170257084bc5d44e9df09f5624f9d" + + "afecd0c9340ac8587f8625d343f7efd1cc8abcf7a6f90eabd4e8e2d906278d6e" + + "431fcade165c8c467887fbf5c26d341557b064b98c60dd40ab262dc046d69647" + + "56f3ddc1a07ae5f87be878b9334fcde40add68d2ca1dc05fb1670f998c7c4607" + + "9a6e48bdb330ad8d30b61b5cc8dc156f5733905931949783f89ac396b65aa4b8" + + "51f746b53ed8ea66130e1d75e8eab136e60450e3e600226bc8e17d03744ce94c" + + "0eec9234fea5f18eef65d81f2f10cfbc0b112b8cde17c32eb33ed81d7356eac3" + + "eb1cb9cefa6604c2d707949b6e5a83e60705bf6aae76dcc7d35d68ff149c1ac5" + + "424bb4a39e2f496f886637fce3db4ba4ad12c1a32d25e1606f6635ff636486f6" + + "714997b45477f38813c02afce4bebf196b813332f0decd567c745f441e736364"); + + byte[] out0000FFFF = Hex.Decode( + "bc31712f2a2f467a5abc737c57ce0f8d49d2f775eb850fc8f856daf19310fee2"+ + "5bab40e78403c9ef4ccd971418992faf4e85ca643fa6b482f30c4659066158a6"+ + "5bc3e620ba7ea5c34dd0eac5aabb2cf078d915fd1f8c437ed00423076c10f701"+ + "eefa7fc7c461aca5db8a87be29d925c4212d4adcfa71ff5b06af15c048aa0dfd"+ + "f0e645bc09fea200c430a88eb38c466ff358b836f1159656a078f6fc752f6db1"+ + "6680bb30fc771a6a785bbb2298e947d7b3500e557775962248bedf4e82c16e66"+ + "f39283ccb95e5399061056a11c4a280f00f7487888199487905273c7aa13012b"+ + "4849eca626cbf071c782e084f9fded57de92313e5f61a6e81117fb1115eff275"+ + "66fd5c755bb3b01bba69aeb8f1b1b1cc9709734be31b35bc707d372ba6fe70d1"+ + "e2c3b0e5e74a7058faff6b11d3a168f19fecc9fcb36b3e6a5f828c01c22ac0c2"+ + "5da2a3a9eec7e0ebbbf51472e430ed4cf1c7ab57ef9aea511e40250846d260b6"+ + "17a3fdeba16cf4afaf700144d3296b58b22a3c79ed96f3e2fc8d9e3c660ae153"+ + "8e0c285ccdc48b59117e80413bd0ad24c6a8d4f133fe1496f14351bb89904fa5"+ + "e10c4b8d50e0604578389c336a9ab3d292beb90ce640fc028e697cf54e021e2f"+ + "c0ca3fe0471fde5e5462f221739a74f5a13ae0621fe2a82e752bc294f63de48d"+ + "e85430af71307a30441b861ab5380e6a6dbe1251c9baa567da14e38e5a0ccddf"+ + "0127205c38fc3b77065e98101d219246103438d223ec7f8f533d4bb3a3d3407a"+ + "944910f11e8e5492e86de7a0471250eca32f0838b3db02fffe71898712af3261"); + + public override string Name + { + get { return "ISAAC"; } + } + + public override void PerformTest() + { + IsaacEngine engine = new IsaacEngine(); + + doTest(engine, Hex.Decode("00000000"), outBase); + doTest(engine, Hex.Decode("ffffffff"), outFFFFFFFF); + + byte[] k = new byte[256 * 4]; + for (int i = 0; i != k.Length; i++) + { + k[i] = (byte)((i % 4 == 0 || i % 4 == 1) ? 0xff : 0x00); + } + doTest(engine, k, outFFFF0000); + k = new byte[256 * 4]; + for (int i = 0; i != k.Length; i++) + { + k[i] = (byte)((i % 4 == 2 || i % 4 == 3) ? 0xff : 0x00); + } + doTest(engine, k, out0000FFFF); + } + + private void doTest( + IsaacEngine engine, + byte[] key, + byte[] output) + { + byte[] input = new byte[output.Length]; + byte[] enc = new byte[output.Length]; + engine.Init(true, new KeyParameter(key)); + engine.ProcessBytes(input, 0, input.Length, enc, 0); + if (!AreEqual(enc, output)) + { + Fail("ciphertext mismatch"); + } + engine.Init(false, new KeyParameter(key)); + engine.ProcessBytes(enc, 0, enc.Length, enc, 0); + if (!AreEqual(enc, input)) + { + Fail("plaintext mismatch"); + } + } + + public static void Main( + string[] args) + { + RunTest(new IsaacTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/crypto/test/ISO9796Test.cs b/crypto/test/src/crypto/test/ISO9796Test.cs new file mode 100644 index 000000000..562238bca --- /dev/null +++ b/crypto/test/src/crypto/test/ISO9796Test.cs @@ -0,0 +1,961 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Crypto.Tests +{ + ///
Fp
.
+ */
+ public class Fp
+ {
+ internal static readonly BigInteger q = new BigInteger("29");
+
+ internal static readonly BigInteger a = new BigInteger("4");
+
+ internal static readonly BigInteger b = new BigInteger("20");
+
+ internal static readonly FpCurve curve = new FpCurve(q, a, b);
+
+ internal static readonly FpPoint infinity = (FpPoint) curve.Infinity;
+
+ internal static readonly int[] pointSource = { 5, 22, 16, 27, 13, 6, 14, 6 };
+
+ internal static FpPoint[] p = new FpPoint[pointSource.Length / 2];
+
+ /**
+ * Creates the points on the curve with literature values.
+ */
+ internal static void createPoints()
+ {
+ for (int i = 0; i < pointSource.Length / 2; i++)
+ {
+ FpFieldElement x = new FpFieldElement(q, new BigInteger(
+ pointSource[2 * i].ToString()));
+ FpFieldElement y = new FpFieldElement(q, new BigInteger(
+ pointSource[2 * i + 1].ToString()));
+ p[i] = new FpPoint(curve, x, y);
+ }
+ }
+ }
+
+ /**
+ * Nested class containing sample literature values for F2m
.
+ */
+ public class F2m
+ {
+ // Irreducible polynomial for TPB z^4 + z + 1
+ internal const int m = 4;
+
+ internal const int k1 = 1;
+
+ // a = z^3
+ internal static readonly F2mFieldElement aTpb = new F2mFieldElement(m, k1,
+ new BigInteger("8", 16));
+
+ // b = z^3 + 1
+ internal static readonly F2mFieldElement bTpb = new F2mFieldElement(m, k1,
+ new BigInteger("9", 16));
+
+ internal static readonly F2mCurve curve = new F2mCurve(m, k1, aTpb
+ .ToBigInteger(), bTpb.ToBigInteger());
+
+ internal static readonly F2mPoint infinity = (F2mPoint) curve.Infinity;
+
+ internal static readonly string[] pointSource = { "2", "f", "c", "c", "1", "1", "b", "2" };
+
+ internal static F2mPoint[] p = new F2mPoint[pointSource.Length / 2];
+
+ /**
+ * Creates the points on the curve with literature values.
+ */
+ internal static void createPoints()
+ {
+ for (int i = 0; i < pointSource.Length / 2; i++)
+ {
+ F2mFieldElement x = new F2mFieldElement(m, k1,
+ new BigInteger(pointSource[2 * i], 16));
+ F2mFieldElement y = new F2mFieldElement(m, k1,
+ new BigInteger(pointSource[2 * i + 1], 16));
+ p[i] = new F2mPoint(curve, x, y);
+ }
+ }
+ }
+
+ [SetUp]
+ public void setUp()
+ {
+// fp = new ECPointTest.Fp();
+ Fp.createPoints();
+
+// f2m = new ECPointTest.F2m();
+ F2m.createPoints();
+ }
+
+ /**
+ * Tests, if inconsistent points can be created, i.e. points with exactly
+ * one null coordinate (not permitted).
+ */
+ [Test]
+ public void TestPointCreationConsistency()
+ {
+ try
+ {
+ FpPoint bad = new FpPoint(Fp.curve, new FpFieldElement(
+ Fp.q, new BigInteger("12")), null);
+ Assert.Fail();
+ }
+ catch (ArgumentException)
+ {
+ // Expected
+ }
+
+ try
+ {
+ FpPoint bad = new FpPoint(Fp.curve, null,
+ new FpFieldElement(Fp.q, new BigInteger("12")));
+ Assert.Fail();
+ }
+ catch (ArgumentException)
+ {
+ // Expected
+ }
+
+ try
+ {
+ F2mPoint bad = new F2mPoint(F2m.curve, new F2mFieldElement(
+ F2m.m, F2m.k1, new BigInteger("1011")), null);
+ Assert.Fail();
+ }
+ catch (ArgumentException)
+ {
+ // Expected
+ }
+
+ try
+ {
+ F2mPoint bad = new F2mPoint(F2m.curve, null,
+ new F2mFieldElement(F2m.m, F2m.k1,
+ new BigInteger("1011")));
+ Assert.Fail();
+ }
+ catch (ArgumentException)
+ {
+ // Expected
+ }
+ }
+
+ /**
+ * Tests ECPoint.add()
against literature values.
+ *
+ * @param p
+ * The array of literature values.
+ * @param infinity
+ * The point at infinity on the respective curve.
+ */
+ private void implTestAdd(ECPoint[] p, ECPoint infinity)
+ {
+ Assert.AreEqual(p[2], p[0].Add(p[1]), "p0 plus p1 does not equal p2");
+ Assert.AreEqual(p[2], p[1].Add(p[0]), "p1 plus p0 does not equal p2");
+ for (int i = 0; i < p.Length; i++)
+ {
+ Assert.AreEqual(p[i], p[i].Add(infinity), "Adding infinity failed");
+ Assert.AreEqual(p[i], infinity.Add(p[i]), "Adding to infinity failed");
+ }
+ }
+
+ /**
+ * Calls implTestAdd()
for Fp
and
+ * F2m
.
+ */
+ [Test]
+ public void TestAdd()
+ {
+ implTestAdd(Fp.p, Fp.infinity);
+ implTestAdd(F2m.p, F2m.infinity);
+ }
+
+ /**
+ * Tests ECPoint.twice()
against literature values.
+ *
+ * @param p
+ * The array of literature values.
+ */
+ private void implTestTwice(ECPoint[] p)
+ {
+ Assert.AreEqual(p[3], p[0].Twice(), "Twice incorrect");
+ Assert.AreEqual(p[3], p[0].Add(p[0]), "Add same point incorrect");
+ }
+
+ /**
+ * Calls implTestTwice()
for Fp
and
+ * F2m
.
+ */
+ [Test]
+ public void TestTwice()
+ {
+ implTestTwice(Fp.p);
+ implTestTwice(F2m.p);
+ }
+
+ /**
+ * Goes through all points on an elliptic curve and checks, if adding a
+ * point k
-times is the same as multiplying the point by
+ * k
, for all k
. Should be called for points
+ * on very small elliptic curves only.
+ *
+ * @param p
+ * The base point on the elliptic curve.
+ * @param infinity
+ * The point at infinity on the elliptic curve.
+ */
+ private void implTestAllPoints(ECPoint p, ECPoint infinity)
+ {
+ ECPoint adder = infinity;
+ ECPoint multiplier = infinity;
+ int i = 1;
+ do
+ {
+ adder = adder.Add(p);
+ multiplier = p.Multiply(new BigInteger(i.ToString()));
+ Assert.AreEqual(adder, multiplier,
+ "Results of add() and multiply() are inconsistent " + i);
+ i++;
+ }
+ while (!(adder.Equals(infinity)));
+ }
+
+ /**
+ * Calls implTestAllPoints()
for the small literature curves,
+ * both for Fp
and F2m
.
+ */
+ [Test]
+ public void TestAllPoints()
+ {
+ for (int i = 0; i < Fp.p.Length; i++)
+ {
+ implTestAllPoints(Fp.p[0], Fp.infinity);
+ }
+
+ for (int i = 0; i < F2m.p.Length; i++)
+ {
+ implTestAllPoints(F2m.p[0], F2m.infinity);
+ }
+ }
+
+ /**
+ * Simple shift-and-add multiplication. Serves as reference implementation
+ * to verify (possibly faster) implementations in
+ * {@link org.bouncycastle.math.ec.ECPoint ECPoint}.
+ *
+ * @param p
+ * The point to multiply.
+ * @param k
+ * The multiplier.
+ * @return The result of the point multiplication kP
.
+ */
+ private ECPoint multiply(ECPoint p, BigInteger k)
+ {
+ ECPoint q = p.Curve.Infinity;
+ int t = k.BitLength;
+ for (int i = 0; i < t; i++)
+ {
+ if (k.TestBit(i))
+ {
+ q = q.Add(p);
+ }
+ p = p.Twice();
+ }
+ return q;
+ }
+
+ /**
+ * Checks, if the point multiplication algorithm of the given point yields
+ * the same result as point multiplication done by the reference
+ * implementation given in multiply()
. This method chooses a
+ * random number by which the given point p
is multiplied.
+ *
+ * @param p
+ * The point to be multiplied.
+ * @param numBits
+ * The bitlength of the random number by which p
+ * is multiplied.
+ */
+ private void implTestMultiply(ECPoint p, int numBits)
+ {
+ BigInteger k = new BigInteger(numBits, secRand);
+ ECPoint reff = multiply(p, k);
+ ECPoint q = p.Multiply(k);
+ Assert.AreEqual(reff, q, "ECPoint.multiply is incorrect");
+ }
+
+ /**
+ * Checks, if the point multiplication algorithm of the given point yields
+ * the same result as point multiplication done by the reference
+ * implementation given in multiply()
. This method tests
+ * multiplication of p
by every number of bitlength
+ * numBits
or less.
+ *
+ * @param p
+ * The point to be multiplied.
+ * @param numBits
+ * Try every multiplier up to this bitlength
+ */
+ private void implTestMultiplyAll(ECPoint p, int numBits)
+ {
+ BigInteger bound = BigInteger.Two.Pow(numBits);
+ BigInteger k = BigInteger.Zero;
+
+ do
+ {
+ ECPoint reff = multiply(p, k);
+ ECPoint q = p.Multiply(k);
+ Assert.AreEqual(reff, q, "ECPoint.multiply is incorrect");
+ k = k.Add(BigInteger.One);
+ }
+ while (k.CompareTo(bound) < 0);
+ }
+
+ /**
+ * Tests ECPoint.add()
and ECPoint.subtract()
+ * for the given point and the given point at infinity.
+ *
+ * @param p
+ * The point on which the tests are performed.
+ * @param infinity
+ * The point at infinity on the same curve as p
.
+ */
+ private void implTestAddSubtract(ECPoint p, ECPoint infinity)
+ {
+ Assert.AreEqual(p.Twice(), p.Add(p), "Twice and Add inconsistent");
+ Assert.AreEqual(p, p.Twice().Subtract(p), "Twice p - p is not p");
+ Assert.AreEqual(infinity, p.Subtract(p), "p - p is not infinity");
+ Assert.AreEqual(p, p.Add(infinity), "p plus infinity is not p");
+ Assert.AreEqual(p, infinity.Add(p), "infinity plus p is not p");
+ Assert.AreEqual(infinity, infinity.Add(infinity), "infinity plus infinity is not infinity ");
+ }
+
+ /**
+ * Calls implTestAddSubtract()
for literature values, both
+ * for Fp
and F2m
.
+ */
+ [Test]
+ public void TestAddSubtractMultiplySimple()
+ {
+ for (int iFp = 0; iFp < Fp.pointSource.Length / 2; iFp++)
+ {
+ implTestAddSubtract(Fp.p[iFp], Fp.infinity);
+
+ // Could be any numBits, 6 is chosen at will
+ implTestMultiplyAll(Fp.p[iFp], 6);
+ implTestMultiplyAll(Fp.infinity, 6);
+ }
+
+ for (int iF2m = 0; iF2m < F2m.pointSource.Length / 2; iF2m++)
+ {
+ implTestAddSubtract(F2m.p[iF2m], F2m.infinity);
+
+ // Could be any numBits, 6 is chosen at will
+ implTestMultiplyAll(F2m.p[iF2m], 6);
+ implTestMultiplyAll(F2m.infinity, 6);
+ }
+ }
+
+ /**
+ * Test encoding with and without point compression.
+ *
+ * @param p
+ * The point to be encoded and decoded.
+ */
+ private void implTestEncoding(ECPoint p)
+ {
+ // Not Point Compression
+ ECPoint unCompP;
+
+ // Point compression
+ ECPoint compP;
+
+ if (p is FpPoint)
+ {
+ unCompP = new FpPoint(p.Curve, p.X, p.Y, false);
+ compP = new FpPoint(p.Curve, p.X, p.Y, true);
+ }
+ else
+ {
+ unCompP = new F2mPoint(p.Curve, p.X, p.Y, false);
+ compP = new F2mPoint(p.Curve, p.X, p.Y, true);
+ }
+
+ byte[] unCompBarr = unCompP.GetEncoded();
+ ECPoint decUnComp = p.Curve.DecodePoint(unCompBarr);
+ Assert.AreEqual(p, decUnComp, "Error decoding uncompressed point");
+
+ byte[] compBarr = compP.GetEncoded();
+ ECPoint decComp = p.Curve.DecodePoint(compBarr);
+ Assert.AreEqual(p, decComp, "Error decoding compressed point");
+ }
+
+ /**
+ * Calls implTestAddSubtract()
,
+ * implTestMultiply
and implTestEncoding
for
+ * the standard elliptic curves as given in SecNamedCurves
.
+ */
+ [Test]
+ public void TestAddSubtractMultiplyTwiceEncoding()
+ {
+ foreach (string name in SecNamedCurves.Names)
+ {
+ X9ECParameters x9ECParameters = SecNamedCurves.GetByName(name);
+
+ BigInteger n = x9ECParameters.N;
+
+ // The generator is multiplied by random b to get random q
+ BigInteger b = new BigInteger(n.BitLength, secRand);
+ ECPoint g = x9ECParameters.G;
+ ECPoint q = g.Multiply(b);
+
+ // Get point at infinity on the curve
+ ECPoint infinity = x9ECParameters.Curve.Infinity;
+
+ implTestAddSubtract(q, infinity);
+ implTestMultiply(q, n.BitLength);
+ implTestMultiply(infinity, n.BitLength);
+ implTestEncoding(q);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/crypto/test/src/math/ec/test/F2mProofer.cs b/crypto/test/src/math/ec/test/F2mProofer.cs
new file mode 100644
index 000000000..88e868c34
--- /dev/null
+++ b/crypto/test/src/math/ec/test/F2mProofer.cs
@@ -0,0 +1,201 @@
+// TODO Need a replacement for the Java properties class to finish this class
+
+//using System;
+//using System.IO;
+//using System.Text;
+//
+//using Org.BouncyCastle.Asn1.Sec;
+//using Org.BouncyCastle.Asn1.X9;
+//using Org.BouncyCastle.Math.EC;
+//using Org.BouncyCastle.Security;
+//
+//namespace Org.BouncyCastle.Math.EC.Tests
+//{
+// public class F2mProofer
+// {
+// private const int NUM_SAMPLES = 1000;
+//
+// private static readonly string PATH = "crypto/test/src/org/bouncycastle/math/ec/test/samples/";
+//
+// private static readonly string INPUT_FILE_NAME_PREFIX = "Input_";
+//
+// private static readonly string RESULT_FILE_NAME_PREFIX = "Output_";
+//
+// /**
+// * The standard curves on which the tests are done
+// */
+// public static readonly string[] Curves = { "sect163r2", "sect233r1",
+// "sect283r1", "sect409r1", "sect571r1" };
+//
+// private string pointToString(F2mPoint p)
+// {
+// F2mFieldElement x = (F2mFieldElement) p.X;
+// F2mFieldElement y = (F2mFieldElement) p.Y;
+//
+// int m = x.M;
+// int len = m / 2 + 5;
+//
+// StringBuilder sb = new StringBuilder(len);
+// sb.Append('(');
+// sb.Append(x.ToBigInteger().ToString(16));
+// sb.Append(", ");
+// sb.Append(y.ToBigInteger().ToString(16));
+// sb.Append(')');
+//
+// return sb.ToString();
+// }
+//
+// private void generateRandomInput(X9ECParameters x9ECParameters)
+// {
+// F2mPoint g = (F2mPoint) x9ECParameters.G;
+// int m = ((F2mFieldElement) g.X).M;
+//
+// SecureRandom secRand = new SecureRandom(); //SecureRandom.GetInstance("SHA1PRNG");
+// Properties inputProps = new Properties();
+// for (int i = 0; i < NUM_SAMPLES; i++)
+// {
+// BigInteger rand = new BigInteger(m, secRand);
+// inputProps.put(i.ToString(), rand.ToString(16));
+// }
+// string bits = m.ToString();
+// FileStream fos = File.Create(PATH
+// + INPUT_FILE_NAME_PREFIX + bits + ".properties");
+// inputProps.store(fos, "Input Samples of length" + bits);
+// fos.Close();
+// }
+//
+// private void multiplyPoints(X9ECParameters x9ECParameters,
+// string classPrefix)
+// {
+// F2mPoint g = (F2mPoint) x9ECParameters.G;
+// int m = ((F2mFieldElement) g.X).M;
+//
+// string inputFileName = PATH + INPUT_FILE_NAME_PREFIX + m
+// + ".properties";
+// Properties inputProps = new Properties();
+// FileStream fis = File.OpenRead(inputFileName);
+// inputProps.load(fis);
+// fis.Close();
+//
+// Properties outputProps = new Properties();
+//
+// for (int i = 0; i < NUM_SAMPLES; i++)
+// {
+// BigInteger rand = new BigInteger(inputProps.getProperty(Integer
+// .ToString(i)), 16);
+// F2mPoint result = (F2mPoint) g.Multiply(rand);
+// string resultStr = pointToString(result);
+// outputProps.setProperty(i.ToString(), resultStr);
+// }
+//
+// string outputFileName = PATH + RESULT_FILE_NAME_PREFIX + classPrefix
+// + "_" + m + ".properties";
+// FileStream fos = File.Create(outputFileName);
+// outputProps.store(fos, "Output Samples of length" + m);
+// fos.Close();
+// }
+//
+// private Properties loadResults(string classPrefix, int m)
+// {
+// FileStream fis = File.OpenRead(PATH
+// + RESULT_FILE_NAME_PREFIX + classPrefix + "_" + m + ".properties");
+// Properties res = new Properties();
+// res.load(fis);
+// fis.Close();
+// return res;
+// }
+//
+// private void compareResult(X9ECParameters x9ECParameters,
+// string classPrefix1, string classPrefix2)
+// {
+// F2mPoint g = (F2mPoint) x9ECParameters.G;
+// int m = ((F2mFieldElement) g.X).M;
+//
+// Properties res1 = loadResults(classPrefix1, m);
+// Properties res2 = loadResults(classPrefix2, m);
+//
+// Set keys = res1.keySet();
+// Iterator iter = keys.iterator();
+// while (iter.hasNext())
+// {
+// string key = (string) iter.next();
+// string result1 = res1.getProperty(key);
+// string result2 = res2.getProperty(key);
+// if (!(result1.Equals(result2)))
+// {
+// Console.Error.WriteLine("Difference found: m = " + m + ", "
+// + result1 + " does not equal " + result2);
+// }
+// }
+//
+// }
+//
+// private static void usage()
+// {
+// Console.Error.WriteLine("Usage: F2mProofer [-init | -Multiply + * To sign a file: ClearSignedFileProcessor -s fileName secretKey passPhrase. + *
+ *+ * To decrypt: ClearSignedFileProcessor -v fileName signatureFile publicKeyFile. + *
+ */ + public sealed class ClearSignedFileProcessor + { + private ClearSignedFileProcessor() + { + } + + private static int ReadInputLine( + MemoryStream bOut, + Stream fIn) + { + bOut.SetLength(0); + + int lookAhead = -1; + int ch; + + while ((ch = fIn.ReadByte()) >= 0) + { + bOut.WriteByte((byte) ch); + if (ch == '\r' || ch == '\n') + { + lookAhead = ReadPassedEol(bOut, ch, fIn); + break; + } + } + + return lookAhead; + } + + private static int ReadInputLine( + MemoryStream bOut, + int lookAhead, + Stream fIn) + { + bOut.SetLength(0); + + int ch = lookAhead; + + do + { + bOut.WriteByte((byte) ch); + if (ch == '\r' || ch == '\n') + { + lookAhead = ReadPassedEol(bOut, ch, fIn); + break; + } + } + while ((ch = fIn.ReadByte()) >= 0); + + if (ch < 0) + { + lookAhead = -1; + } + + return lookAhead; + } + + private static int ReadPassedEol( + MemoryStream bOut, + int lastCh, + Stream fIn) + { + int lookAhead = fIn.ReadByte(); + + if (lastCh == '\r' && lookAhead == '\n') + { + bOut.WriteByte((byte) lookAhead); + lookAhead = fIn.ReadByte(); + } + + return lookAhead; + } + + /* + * verify a clear text signed file + */ + private static void VerifyFile( + Stream inputStream, + Stream keyIn, + string resultName) + { + ArmoredInputStream aIn = new ArmoredInputStream(inputStream); + Stream outStr = File.Create(resultName); + + // + // write out signed section using the local line separator. + // note: trailing white space needs to be removed from the end of + // each line RFC 4880 Section 7.1 + // + MemoryStream lineOut = new MemoryStream(); + int lookAhead = ReadInputLine(lineOut, aIn); + byte[] lineSep = LineSeparator; + + if (lookAhead != -1 && aIn.IsClearText()) + { + byte[] line = lineOut.ToArray(); + outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line)); + outStr.Write(lineSep, 0, lineSep.Length); + + while (lookAhead != -1 && aIn.IsClearText()) + { + lookAhead = ReadInputLine(lineOut, lookAhead, aIn); + + line = lineOut.ToArray(); + outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line)); + outStr.Write(lineSep, 0, lineSep.Length); + } + } + + outStr.Close(); + + PgpPublicKeyRingBundle pgpRings = new PgpPublicKeyRingBundle(keyIn); + + PgpObjectFactory pgpFact = new PgpObjectFactory(aIn); + PgpSignatureList p3 = (PgpSignatureList) pgpFact.NextPgpObject(); + PgpSignature sig = p3[0]; + + sig.InitVerify(pgpRings.GetPublicKey(sig.KeyId)); + + // + // read the input, making sure we ignore the last newline. + // + Stream sigIn = File.OpenRead(resultName); + + lookAhead = ReadInputLine(lineOut, sigIn); + + ProcessLine(sig, lineOut.ToArray()); + + if (lookAhead != -1) + { + do + { + lookAhead = ReadInputLine(lineOut, lookAhead, sigIn); + + sig.Update((byte) '\r'); + sig.Update((byte) '\n'); + + ProcessLine(sig, lineOut.ToArray()); + } + while (lookAhead != -1); + } + + sigIn.Close(); + + if (sig.Verify()) + { + Console.WriteLine("signature verified."); + } + else + { + Console.WriteLine("signature verification failed."); + } + } + + private static byte[] LineSeparator + { + get { return Encoding.ASCII.GetBytes(SimpleTest.NewLine); } + } + + /* + * create a clear text signed file. + */ + private static void SignFile( + string fileName, + Stream keyIn, + Stream outputStream, + char[] pass, + string digestName) + { + HashAlgorithmTag digest; + + if (digestName.Equals("SHA256")) + { + digest = HashAlgorithmTag.Sha256; + } + else if (digestName.Equals("SHA384")) + { + digest = HashAlgorithmTag.Sha384; + } + else if (digestName.Equals("SHA512")) + { + digest = HashAlgorithmTag.Sha512; + } + else if (digestName.Equals("MD5")) + { + digest = HashAlgorithmTag.MD5; + } + else if (digestName.Equals("RIPEMD160")) + { + digest = HashAlgorithmTag.RipeMD160; + } + else + { + digest = HashAlgorithmTag.Sha1; + } + + PgpSecretKey pgpSecKey = PgpExampleUtilities.ReadSecretKey(keyIn); + PgpPrivateKey pgpPrivKey = pgpSecKey.ExtractPrivateKey(pass); + PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, digest); + PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); + + sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey); + + IEnumerator enumerator = pgpSecKey.PublicKey.GetUserIds().GetEnumerator(); + if (enumerator.MoveNext()) + { + spGen.SetSignerUserId(false, (string) enumerator.Current); + sGen.SetHashedSubpackets(spGen.Generate()); + } + + Stream fIn = File.OpenRead(fileName); + ArmoredOutputStream aOut = new ArmoredOutputStream(outputStream); + + aOut.BeginClearText(digest); + + // + // note the last \n/\r/\r\n in the file is ignored + // + MemoryStream lineOut = new MemoryStream(); + int lookAhead = ReadInputLine(lineOut, fIn); + + ProcessLine(aOut, sGen, lineOut.ToArray()); + + if (lookAhead != -1) + { + do + { + lookAhead = ReadInputLine(lineOut, lookAhead, fIn); + + sGen.Update((byte) '\r'); + sGen.Update((byte) '\n'); + + ProcessLine(aOut, sGen, lineOut.ToArray()); + } + while (lookAhead != -1); + } + + fIn.Close(); + + aOut.EndClearText(); + + BcpgOutputStream bOut = new BcpgOutputStream(aOut); + + sGen.Generate().Encode(bOut); + + aOut.Close(); + } + + private static void ProcessLine( + PgpSignature sig, + byte[] line) + { + // note: trailing white space needs to be removed from the end of + // each line for signature calculation RFC 4880 Section 7.1 + int length = GetLengthWithoutWhiteSpace(line); + if (length > 0) + { + sig.Update(line, 0, length); + } + } + + private static void ProcessLine( + Stream aOut, + PgpSignatureGenerator sGen, + byte[] line) + { + int length = GetLengthWithoutWhiteSpace(line); + if (length > 0) + { + sGen.Update(line, 0, length); + } + + aOut.Write(line, 0, line.Length); + } + + private static int GetLengthWithoutSeparatorOrTrailingWhitespace(byte[] line) + { + int end = line.Length - 1; + + while (end >= 0 && IsWhiteSpace(line[end])) + { + end--; + } + + return end + 1; + } + + private static bool IsLineEnding( + byte b) + { + return b == '\r' || b == '\n'; + } + + private static int GetLengthWithoutWhiteSpace( + byte[] line) + { + int end = line.Length - 1; + + while (end >= 0 && IsWhiteSpace(line[end])) + { + end--; + } + + return end + 1; + } + + private static bool IsWhiteSpace( + byte b) + { + return IsLineEnding(b) || b == '\t' || b == ' '; + } + + public static int Main( + string[] args) + { + if (args[0].Equals("-s")) + { + Stream fis = File.OpenRead(args[2]); + Stream fos = File.Create(args[1] + ".asc"); + + Stream keyIn = PgpUtilities.GetDecoderStream(fis); + + string digestName = (args.Length == 4) + ? "SHA1" + : args[4]; + + SignFile(args[1], keyIn, fos, args[3].ToCharArray(), digestName); + + fis.Close(); + fos.Close(); + } + else if (args[0].Equals("-v")) + { + if (args[1].IndexOf(".asc") < 0) + { + Console.Error.WriteLine("file needs to end in \".asc\""); + return 1; + } + + Stream fin = File.OpenRead(args[1]); + Stream fis = File.OpenRead(args[2]); + + Stream keyIn = PgpUtilities.GetDecoderStream(fis); + + VerifyFile(fin, keyIn, args[1].Substring(0, args[1].Length - 4)); + + fin.Close(); + fis.Close(); + } + else + { + Console.Error.WriteLine("usage: ClearSignedFileProcessor [-s file keyfile passPhrase]|[-v sigFile keyFile]"); + } + return 0; + } + } +} diff --git a/crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs b/crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs new file mode 100644 index 000000000..c4959844d --- /dev/null +++ b/crypto/test/src/openpgp/examples/DetachedSignatureProcessor.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections; +using System.IO; + + +using Org.BouncyCastle.Bcpg.OpenPgp; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + /** + * A simple utility class that creates seperate signatures for files and verifies them. + *
+ * To sign a file: DetachedSignatureProcessor -s [-a] fileName secretKey passPhrase.
+ * If -a is specified the output file will be "ascii-armored".
+ * To decrypt: DetachedSignatureProcessor -v fileName signatureFile publicKeyFile.
+ *+ * Note: this example will silently overwrite files. + * It also expects that a single pass phrase + * will have been used.
+ */ + public sealed class DetachedSignatureProcessor + { + private DetachedSignatureProcessor() + { + } + + private static void VerifySignature( + string fileName, + string inputFileName, + string keyFileName) + { + using (Stream input = File.OpenRead(inputFileName), + keyIn = File.OpenRead(keyFileName)) + { + VerifySignature(fileName, input, keyIn); + } + } + + /** + * verify the signature in in against the file fileName. + */ + private static void VerifySignature( + string fileName, + Stream inputStream, + Stream keyIn) + { + inputStream = PgpUtilities.GetDecoderStream(inputStream); + + PgpObjectFactory pgpFact = new PgpObjectFactory(inputStream); + PgpSignatureList p3 = null; + PgpObject o = pgpFact.NextPgpObject(); + if (o is PgpCompressedData) + { + PgpCompressedData c1 = (PgpCompressedData)o; + pgpFact = new PgpObjectFactory(c1.GetDataStream()); + + p3 = (PgpSignatureList)pgpFact.NextPgpObject(); + } + else + { + p3 = (PgpSignatureList)o; + } + + PgpPublicKeyRingBundle pgpPubRingCollection = new PgpPublicKeyRingBundle( + PgpUtilities.GetDecoderStream(keyIn)); + Stream dIn = File.OpenRead(fileName); + PgpSignature sig = p3[0]; + PgpPublicKey key = pgpPubRingCollection.GetPublicKey(sig.KeyId); + sig.InitVerify(key); + + int ch; + while ((ch = dIn.ReadByte()) >= 0) + { + sig.Update((byte)ch); + } + + dIn.Close(); + + if (sig.Verify()) + { + Console.WriteLine("signature verified."); + } + else + { + Console.WriteLine("signature verification failed."); + } + } + + private static void CreateSignature( + string inputFileName, + string keyFileName, + string outputFileName, + char[] pass, + bool armor) + { + using (Stream keyIn = File.OpenRead(keyFileName), + output = File.OpenRead(outputFileName)) + { + CreateSignature(inputFileName, keyIn, output, pass, armor); + } + } + + private static void CreateSignature( + string fileName, + Stream keyIn, + Stream outputStream, + char[] pass, + bool armor) + { + if (armor) + { + outputStream = new ArmoredOutputStream(outputStream); + } + + PgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn); + PgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass); + PgpSignatureGenerator sGen = new PgpSignatureGenerator( + pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1); + + sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); + + BcpgOutputStream bOut = new BcpgOutputStream(outputStream); + + Stream fIn = File.OpenRead(fileName); + + int ch; + while ((ch = fIn.ReadByte()) >= 0) + { + sGen.Update((byte)ch); + } + + fIn.Close(); + + sGen.Generate().Encode(bOut); + + if (armor) + { + outputStream.Close(); + } + } + + public static void Main( + string[] args) + { + if (args[0].Equals("-s")) + { + if (args[1].Equals("-a")) + { + CreateSignature(args[2], args[3], args[2] + ".asc", args[4].ToCharArray(), true); + } + else + { + CreateSignature(args[1], args[2], args[1] + ".bpg", args[3].ToCharArray(), false); + } + } + else if (args[0].Equals("-v")) + { + VerifySignature(args[1], args[2], args[3]); + } + else + { + Console.Error.WriteLine("usage: DetachedSignatureProcessor [-s [-a] file keyfile passPhrase]|[-v file sigFile keyFile]"); + } + } + } +} diff --git a/crypto/test/src/openpgp/examples/DirectKeySignature.cs b/crypto/test/src/openpgp/examples/DirectKeySignature.cs new file mode 100644 index 000000000..a6bf8e755 --- /dev/null +++ b/crypto/test/src/openpgp/examples/DirectKeySignature.cs @@ -0,0 +1,140 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Bcpg; +using Org.BouncyCastle.Bcpg.Sig; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + /** + * A simple utility class that directly signs a public key and writes the signed key to "SignedKey.asc" in + * the current working directory. + *
+ * To sign a key: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue.
+ *
+ * To display a NotationData packet from a publicKey previously signed: DirectKeySignature signedPublicKeyFile.
+ *
+ * Note: this example will silently overwrite files, nor does it pay any attention to + * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase + * will have been used. + *
+ */ + public class DirectKeySignature + { + public static void Main( + string[] args) + { + if (args.Length == 1) + { + Stream fis = File.OpenRead(args[0]); + + PgpPublicKeyRing ring = new PgpPublicKeyRing( + PgpUtilities.GetDecoderStream(fis)); + PgpPublicKey key = ring.GetPublicKey(); + + // iterate through all direct key signautures and look for NotationData subpackets + foreach (PgpSignature sig in key.GetSignaturesOfType(PgpSignature.DirectKey)) + { + Console.WriteLine("Signature date is: " + + sig.GetHashedSubPackets().GetSignatureCreationTime()); + + NotationData[] data = sig.GetHashedSubPackets().GetNotationDataOccurences(); + + for (int i = 0; i < data.Length; i++) + { + Console.WriteLine("Found Notaion named '" + data[i].GetNotationName() + +"' with content '" + data[i].GetNotationValue() + "'."); + } + } + + fis.Close(); + } + else if (args.Length == 5) + { + Stream secFis = File.OpenRead(args[0]); + Stream pubFis = File.OpenRead(args[2]); + + // gather command line arguments + PgpSecretKeyRing secRing = new PgpSecretKeyRing( + PgpUtilities.GetDecoderStream(secFis)); + String secretKeyPass = args[1]; + PgpPublicKeyRing ring = new PgpPublicKeyRing( + PgpUtilities.GetDecoderStream(pubFis)); + String notationName = args[3]; + String notationValue = args[4]; + + // create the signed keyRing + PgpPublicKeyRing sRing = null; + sRing = new PgpPublicKeyRing( + new MemoryStream( + SignPublicKey(secRing.GetSecretKey(), secretKeyPass, + ring.GetPublicKey(), notationName, notationValue, true), + false)); + ring = sRing; + + secFis.Close(); + pubFis.Close(); + + Stream fos = File.Create("SignedKey.asc"); + + // write the created keyRing to file + ArmoredOutputStream aOut = new ArmoredOutputStream(fos); + sRing.Encode(aOut); + aOut.Close(); + + // Note: ArmoredOutputStream.Close() leaves underlying stream open + fos.Close(); + } + else + { + Console.Error.WriteLine("usage: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue"); + Console.Error.WriteLine("or: DirectKeySignature signedPublicKeyFile"); + } + } + + private static byte[] SignPublicKey( + PgpSecretKey secretKey, + string secretKeyPass, + PgpPublicKey keyToBeSigned, + string notationName, + string notationValue, + bool armor) + { + Stream os = new MemoryStream(); + if (armor) + { + os = new ArmoredOutputStream(os); + } + + PgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey( + secretKeyPass.ToCharArray()); + + PgpSignatureGenerator sGen = new PgpSignatureGenerator( + secretKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1); + + sGen.InitSign(PgpSignature.DirectKey, pgpPrivKey); + + BcpgOutputStream bOut = new BcpgOutputStream(os); + + sGen.GenerateOnePassVersion(false).Encode(bOut); + + PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); + + bool isHumanReadable = true; + + spGen.SetNotationData(true, isHumanReadable, notationName, notationValue); + + PgpSignatureSubpacketVector packetVector = spGen.Generate(); + sGen.SetHashedSubpackets(packetVector); + + bOut.Flush(); + + if (armor) + { + os.Close(); + } + + return PgpPublicKey.AddCertification(keyToBeSigned, sGen.Generate()).GetEncoded(); + } + } +} diff --git a/crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs b/crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs new file mode 100644 index 000000000..6040351a3 --- /dev/null +++ b/crypto/test/src/openpgp/examples/DsaElGamalKeyRingGenerator.cs @@ -0,0 +1,134 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + /** + * A simple utility class that Generates a public/secret keyring containing a DSA signing + * key and an El Gamal key for encryption. + *+ * usage: DSAElGamalKeyRingGenerator [-a] identity passPhrase
+ *+ * Where identity is the name to be associated with the public key. The keys are placed + * in the files pub.[asc|bpg] and secret.[asc|bpg].
+ *+ * Note: this example encrypts the secret key using AES_256, many PGP products still + * do not support this, if you are having problems importing keys try changing the algorithm + * id to PgpEncryptedData.Cast5. CAST5 is more widelysupported.
+ */ + public sealed class DsaElGamalKeyRingGenerator + { + private DsaElGamalKeyRingGenerator() + { + } + + private static void ExportKeyPair( + Stream secretOut, + Stream publicOut, + AsymmetricCipherKeyPair dsaKp, + AsymmetricCipherKeyPair elgKp, + string identity, + char[] passPhrase, + bool armor) + { + if (armor) + { + secretOut = new ArmoredOutputStream(secretOut); + } + + PgpKeyPair dsaKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.Dsa, dsaKp, DateTime.UtcNow); + PgpKeyPair elgKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ElGamalEncrypt, elgKp, DateTime.UtcNow); + + PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification, dsaKeyPair, + identity, SymmetricKeyAlgorithmTag.Aes256, passPhrase, true, null, null, new SecureRandom()); + + keyRingGen.AddSubKey(elgKeyPair); + + keyRingGen.GenerateSecretKeyRing().Encode(secretOut); + + if (armor) + { + secretOut.Close(); + publicOut = new ArmoredOutputStream(publicOut); + } + + keyRingGen.GeneratePublicKeyRing().Encode(publicOut); + + if (armor) + { + publicOut.Close(); + } + } + + public static int Main( + string[] args) + { + if (args.Length < 2) + { + Console.WriteLine("DsaElGamalKeyRingGenerator [-a] identity passPhrase"); + return 0; + } + + IAsymmetricCipherKeyPairGenerator dsaKpg = GeneratorUtilities.GetKeyPairGenerator("DSA"); + DsaParametersGenerator pGen = new DsaParametersGenerator(); + pGen.Init(1024, 80, new SecureRandom()); + DsaParameters dsaParams = pGen.GenerateParameters(); + DsaKeyGenerationParameters kgp = new DsaKeyGenerationParameters(new SecureRandom(), dsaParams); + dsaKpg.Init(kgp); + + + // + // this takes a while as the key generator has to Generate some DSA parameters + // before it Generates the key. + // + AsymmetricCipherKeyPair dsaKp = dsaKpg.GenerateKeyPair(); + + + IAsymmetricCipherKeyPairGenerator elgKpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL"); + + BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); + BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); + + ElGamalParameters elParams = new ElGamalParameters(p, g); + ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(new SecureRandom(), elParams); + elgKpg.Init(elKgp); + + // + // this is quicker because we are using preGenerated parameters. + // + AsymmetricCipherKeyPair elgKp = elgKpg.GenerateKeyPair(); + + Stream out1, out2; + if (args[0].Equals("-a")) + { + if (args.Length < 3) + { + Console.WriteLine("DSAElGamalKeyRingGenerator [-a] identity passPhrase"); + return 0; + } + + out1 = File.Create("secret.asc"); + out2 = File.Create("pub.asc"); + + ExportKeyPair(out1, out2, dsaKp, elgKp, args[1], args[2].ToCharArray(), true); + } + else + { + out1 = File.Create("secret.bpg"); + out2 = File.Create("pub.bpg"); + + ExportKeyPair(out1, out2, dsaKp, elgKp, args[0], args[1].ToCharArray(), false); + } + out1.Close(); + out2.Close(); + return 0; + } + } +} diff --git a/crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs b/crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs new file mode 100644 index 000000000..c77408b1f --- /dev/null +++ b/crypto/test/src/openpgp/examples/KeyBasedFileProcessor.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + /** + * A simple utility class that encrypts/decrypts public key based + * encryption files. + *
+ * To encrypt a file: KeyBasedFileProcessor -e [-a|-ai] fileName publicKeyFile.
+ * If -a is specified the output file will be "ascii-armored".
+ * If -i is specified the output file will be have integrity checking added.
+ * To decrypt: KeyBasedFileProcessor -d fileName secretKeyFile passPhrase.
+ *+ * Note 1: this example will silently overwrite files, nor does it pay any attention to + * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase + * will have been used.
+ *+ * Note 2: if an empty file name has been specified in the literal data object contained in the + * encrypted packet a file with the name filename.out will be generated in the current working directory.
+ */ + public sealed class KeyBasedFileProcessor + { + private KeyBasedFileProcessor() + { + } + + private static void DecryptFile( + string inputFileName, + string keyFileName, + char[] passwd, + string defaultFileName) + { + using (Stream input = File.OpenRead(inputFileName), + keyIn = File.OpenRead(keyFileName)) + { + DecryptFile(input, keyIn, passwd, defaultFileName); + } + } + + /** + * decrypt the passed in message stream + */ + private static void DecryptFile( + Stream inputStream, + Stream keyIn, + char[] passwd, + string defaultFileName) + { + inputStream = PgpUtilities.GetDecoderStream(inputStream); + + try + { + PgpObjectFactory pgpF = new PgpObjectFactory(inputStream); + PgpEncryptedDataList enc; + + PgpObject o = pgpF.NextPgpObject(); + // + // the first object might be a PGP marker packet. + // + if (o is PgpEncryptedDataList) + { + enc = (PgpEncryptedDataList)o; + } + else + { + enc = (PgpEncryptedDataList)pgpF.NextPgpObject(); + } + + // + // find the secret key + // + PgpPrivateKey sKey = null; + PgpPublicKeyEncryptedData pbe = null; + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle( + PgpUtilities.GetDecoderStream(keyIn)); + + foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) + { + sKey = PgpExampleUtilities.FindSecretKey(pgpSec, pked.KeyId, passwd); + + if (sKey != null) + { + pbe = pked; + break; + } + } + + if (sKey == null) + { + throw new ArgumentException("secret key for message not found."); + } + + Stream clear = pbe.GetDataStream(sKey); + + PgpObjectFactory plainFact = new PgpObjectFactory(clear); + + PgpObject message = plainFact.NextPgpObject(); + + if (message is PgpCompressedData) + { + PgpCompressedData cData = (PgpCompressedData)message; + PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream()); + + message = pgpFact.NextPgpObject(); + } + + if (message is PgpLiteralData) + { + PgpLiteralData ld = (PgpLiteralData)message; + + string outFileName = ld.FileName; + if (outFileName.Length == 0) + { + outFileName = defaultFileName; + } + + Stream fOut = File.Create(outFileName); + Stream unc = ld.GetInputStream(); + Streams.PipeAll(unc, fOut); + fOut.Close(); + } + else if (message is PgpOnePassSignatureList) + { + throw new PgpException("encrypted message contains a signed message - not literal data."); + } + else + { + throw new PgpException("message is not a simple encrypted file - type unknown."); + } + + if (pbe.IsIntegrityProtected()) + { + if (!pbe.Verify()) + { + Console.Error.WriteLine("message failed integrity check"); + } + else + { + Console.Error.WriteLine("message integrity check passed"); + } + } + else + { + Console.Error.WriteLine("no message integrity check"); + } + } + catch (PgpException e) + { + Console.Error.WriteLine(e); + + Exception underlyingException = e.InnerException; + if (underlyingException != null) + { + Console.Error.WriteLine(underlyingException.Message); + Console.Error.WriteLine(underlyingException.StackTrace); + } + } + } + + private static void EncryptFile( + string outputFileName, + string inputFileName, + string encKeyFileName, + bool armor, + bool withIntegrityCheck) + { + PgpPublicKey encKey = PgpExampleUtilities.ReadPublicKey(encKeyFileName); + + using (Stream output = File.Create(outputFileName)) + { + EncryptFile(output, inputFileName, encKey, armor, withIntegrityCheck); + } + } + + private static void EncryptFile( + Stream outputStream, + string fileName, + PgpPublicKey encKey, + bool armor, + bool withIntegrityCheck) + { + if (armor) + { + outputStream = new ArmoredOutputStream(outputStream); + } + + try + { + byte[] bytes = PgpExampleUtilities.CompressFile(fileName, CompressionAlgorithmTag.Zip); + + PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom()); + encGen.AddMethod(encKey); + + Stream cOut = encGen.Open(outputStream, bytes.Length); + + cOut.Write(bytes, 0, bytes.Length); + cOut.Close(); + + if (armor) + { + outputStream.Close(); + } + } + catch (PgpException e) + { + Console.Error.WriteLine(e); + + Exception underlyingException = e.InnerException; + if (underlyingException != null) + { + Console.Error.WriteLine(underlyingException.Message); + Console.Error.WriteLine(underlyingException.StackTrace); + } + } + } + + public static void Main( + string[] args) + { + if (args.Length == 0) + { + Console.Error.WriteLine("usage: KeyBasedFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"); + return; + } + + if (args[0].Equals("-e")) + { + if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia")) + { + EncryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].IndexOf('i') > 0)); + } + else if (args[1].Equals("-i")) + { + EncryptFile(args[2] + ".bpg", args[2], args[3], false, true); + } + else + { + EncryptFile(args[1] + ".bpg", args[1], args[2], false, false); + } + } + else if (args[0].Equals("-d")) + { + DecryptFile(args[1], args[2], args[3].ToCharArray(), new FileInfo(args[1]).Name + ".out"); + } + else + { + Console.Error.WriteLine("usage: KeyBasedFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"); + } + } + } +} diff --git a/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs b/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs new file mode 100644 index 000000000..7fb00a3b7 --- /dev/null +++ b/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs @@ -0,0 +1,267 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + /** + * A simple utility class that encrypts/decrypts public key based + * encryption large files. + *
+ * To encrypt a file: KeyBasedLargeFileProcessor -e [-a|-ai] fileName publicKeyFile.
+ * If -a is specified the output file will be "ascii-armored".
+ * If -i is specified the output file will be have integrity checking added.
+ * To decrypt: KeyBasedLargeFileProcessor -d fileName secretKeyFile passPhrase.
+ *+ * Note 1: this example will silently overwrite files, nor does it pay any attention to + * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase + * will have been used.
+ *+ * Note 2: this example Generates partial packets to encode the file, the output it Generates + * will not be readable by older PGP products or products that don't support partial packet + * encoding.
+ *+ * Note 3: if an empty file name has been specified in the literal data object contained in the + * encrypted packet a file with the name filename.out will be generated in the current working directory.
+ */ + public sealed class KeyBasedLargeFileProcessor + { + private KeyBasedLargeFileProcessor() + { + } + + private static void DecryptFile( + string inputFileName, + string keyFileName, + char[] passwd, + string defaultFileName) + { + using (Stream input = File.OpenRead(inputFileName), + keyIn = File.OpenRead(keyFileName)) + { + DecryptFile(input, keyIn, passwd, defaultFileName); + } + } + + /** + * decrypt the passed in message stream + */ + private static void DecryptFile( + Stream inputStream, + Stream keyIn, + char[] passwd, + string defaultFileName) + { + inputStream = PgpUtilities.GetDecoderStream(inputStream); + + try + { + PgpObjectFactory pgpF = new PgpObjectFactory(inputStream); + PgpEncryptedDataList enc; + + PgpObject o = pgpF.NextPgpObject(); + // + // the first object might be a PGP marker packet. + // + if (o is PgpEncryptedDataList) + { + enc = (PgpEncryptedDataList)o; + } + else + { + enc = (PgpEncryptedDataList)pgpF.NextPgpObject(); + } + + // + // find the secret key + // + PgpPrivateKey sKey = null; + PgpPublicKeyEncryptedData pbe = null; + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle( + PgpUtilities.GetDecoderStream(keyIn)); + + foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) + { + sKey = PgpExampleUtilities.FindSecretKey(pgpSec, pked.KeyId, passwd); + + if (sKey != null) + { + pbe = pked; + break; + } + } + + if (sKey == null) + { + throw new ArgumentException("secret key for message not found."); + } + + Stream clear = pbe.GetDataStream(sKey); + + PgpObjectFactory plainFact = new PgpObjectFactory(clear); + + PgpCompressedData cData = (PgpCompressedData) plainFact.NextPgpObject(); + + PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream()); + + PgpObject message = pgpFact.NextPgpObject(); + + if (message is PgpLiteralData) + { + PgpLiteralData ld = (PgpLiteralData)message; + + string outFileName = ld.FileName; + if (outFileName.Length == 0) + { + outFileName = defaultFileName; + } + + Stream fOut = File.Create(outFileName); + Stream unc = ld.GetInputStream(); + Streams.PipeAll(unc, fOut); + fOut.Close(); + } + else if (message is PgpOnePassSignatureList) + { + throw new PgpException("encrypted message contains a signed message - not literal data."); + } + else + { + throw new PgpException("message is not a simple encrypted file - type unknown."); + } + + if (pbe.IsIntegrityProtected()) + { + if (!pbe.Verify()) + { + Console.Error.WriteLine("message failed integrity check"); + } + else + { + Console.Error.WriteLine("message integrity check passed"); + } + } + else + { + Console.Error.WriteLine("no message integrity check"); + } + } + catch (PgpException e) + { + Console.Error.WriteLine(e); + + Exception underlyingException = e.InnerException; + if (underlyingException != null) + { + Console.Error.WriteLine(underlyingException.Message); + Console.Error.WriteLine(underlyingException.StackTrace); + } + } + } + + private static void EncryptFile( + string outputFileName, + string inputFileName, + string encKeyFileName, + bool armor, + bool withIntegrityCheck) + { + PgpPublicKey encKey = PgpExampleUtilities.ReadPublicKey(encKeyFileName); + + using (Stream output = File.Create(outputFileName)) + { + EncryptFile(output, inputFileName, encKey, armor, withIntegrityCheck); + } + } + + private static void EncryptFile( + Stream outputStream, + string fileName, + PgpPublicKey encKey, + bool armor, + bool withIntegrityCheck) + { + if (armor) + { + outputStream = new ArmoredOutputStream(outputStream); + } + + try + { + PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom()); + + cPk.AddMethod(encKey); + + Stream cOut = cPk.Open(outputStream, new byte[1 << 16]); + + PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator( + CompressionAlgorithmTag.Zip); + + PgpUtilities.WriteFileToLiteralData( + comData.Open(cOut), + PgpLiteralData.Binary, + new FileInfo(fileName), + new byte[1 << 16]); + + comData.Close(); + + cOut.Close(); + + if (armor) + { + outputStream.Close(); + } + } + catch (PgpException e) + { + Console.Error.WriteLine(e); + + Exception underlyingException = e.InnerException; + if (underlyingException != null) + { + Console.Error.WriteLine(underlyingException.Message); + Console.Error.WriteLine(underlyingException.StackTrace); + } + } + } + + public static void Main( + string[] args) + { + if (args.Length == 0) + { + Console.Error.WriteLine("usage: KeyBasedLargeFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"); + return; + } + + if (args[0].Equals("-e")) + { + if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia")) + { + EncryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].IndexOf('i') > 0)); + } + else if (args[1].Equals("-i")) + { + EncryptFile(args[2] + ".bpg", args[2], args[3], false, true); + } + else + { + EncryptFile(args[1] + ".bpg", args[1], args[2], false, false); + } + } + else if (args[0].Equals("-d")) + { + DecryptFile(args[1], args[2], args[3].ToCharArray(), new FileInfo(args[1]).Name + ".out"); + } + else + { + Console.Error.WriteLine("usage: KeyBasedLargeFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"); + } + } + } +} diff --git a/crypto/test/src/openpgp/examples/PbeFileProcessor.cs b/crypto/test/src/openpgp/examples/PbeFileProcessor.cs new file mode 100644 index 000000000..66b1cc4ed --- /dev/null +++ b/crypto/test/src/openpgp/examples/PbeFileProcessor.cs @@ -0,0 +1,183 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + /** + * A simple utility class that encrypts/decrypts password based + * encryption files. + *
+ * To encrypt a file: PBEFileProcessor -e [-ai] fileName passPhrase.
+ * If -a is specified the output file will be "ascii-armored".
+ * If -i is specified the output file will be "integrity protected".
+ * To decrypt: PBEFileProcessor -d fileName passPhrase.
+ *+ * Note: this example will silently overwrite files, nor does it pay any attention to + * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase + * will have been used.
+ */ + public sealed class PbeFileProcessor + { + private PbeFileProcessor() {} + + private static void DecryptFile(string inputFileName, char[] passPhrase) + { + using (Stream input = File.OpenRead(inputFileName)) + { + DecryptFile(input, passPhrase); + } + } + + /** + * decrypt the passed in message stream + */ + private static void DecryptFile( + Stream inputStream, + char[] passPhrase) + { + inputStream = PgpUtilities.GetDecoderStream(inputStream); + + PgpObjectFactory pgpF = new PgpObjectFactory(inputStream); + PgpObject o = pgpF.NextPgpObject(); + + // + // the first object might be a PGP marker packet. + // + PgpEncryptedDataList enc = o as PgpEncryptedDataList; + if (enc == null) + { + enc = (PgpEncryptedDataList)pgpF.NextPgpObject(); + } + + PgpPbeEncryptedData pbe = (PgpPbeEncryptedData)enc[0]; + + Stream clear = pbe.GetDataStream(passPhrase); + + PgpObjectFactory pgpFact = new PgpObjectFactory(clear); + + // + // if we're trying to read a file generated by someone other than us + // the data might not be compressed, so we check the return type from + // the factory and behave accordingly. + // + o = pgpFact.NextPgpObject(); + if (o is PgpCompressedData) + { + PgpCompressedData cData = (PgpCompressedData) o; + pgpFact = new PgpObjectFactory(cData.GetDataStream()); + o = pgpFact.NextPgpObject(); + } + + PgpLiteralData ld = (PgpLiteralData) o; + Stream unc = ld.GetInputStream(); + Stream fOut = File.Create(ld.FileName); + Streams.PipeAll(unc, fOut); + fOut.Close(); + + if (pbe.IsIntegrityProtected()) + { + if (!pbe.Verify()) + { + Console.Error.WriteLine("message failed integrity check"); + } + else + { + Console.Error.WriteLine("message integrity check passed"); + } + } + else + { + Console.Error.WriteLine("no message integrity check"); + } + } + + private static void EncryptFile( + string outputFileName, + string inputFileName, + char[] passPhrase, + bool armor, + bool withIntegrityCheck) + { + using (Stream output = File.Create(outputFileName)) + { + EncryptFile(output, inputFileName, passPhrase, armor, withIntegrityCheck); + } + } + + private static void EncryptFile( + Stream outputStream, + string fileName, + char[] passPhrase, + bool armor, + bool withIntegrityCheck) + { + if (armor) + { + outputStream = new ArmoredOutputStream(outputStream); + } + + try + { + byte[] compressedData = PgpExampleUtilities.CompressFile(fileName, CompressionAlgorithmTag.Zip); + + PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom()); + encGen.AddMethod(passPhrase); + + Stream encOut = encGen.Open(outputStream, compressedData.Length); + + encOut.Write(compressedData, 0, compressedData.Length); + encOut.Close(); + + if (armor) + { + outputStream.Close(); + } + } + catch (PgpException e) + { + Console.Error.WriteLine(e); + + Exception underlyingException = e.InnerException; + if (underlyingException != null) + { + Console.Error.WriteLine(underlyingException.Message); + Console.Error.WriteLine(underlyingException.StackTrace); + } + } + } + + public static void Main( + string[] args) + { + if (args[0].Equals("-e")) + { + if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia")) + { + EncryptFile(args[2] + ".asc", args[2], args[3].ToCharArray(), true, (args[1].IndexOf('i') > 0)); + } + else if (args[1].Equals("-i")) + { + EncryptFile(args[2] + ".bpg", args[2], args[3].ToCharArray(), false, true); + } + else + { + EncryptFile(args[1] + ".bpg", args[1], args[2].ToCharArray(), false, false); + } + } + else if (args[0].Equals("-d")) + { + DecryptFile(args[1], args[2].ToCharArray()); + } + else + { + Console.Error.WriteLine("usage: PbeFileProcessor -e [-ai]|-d file passPhrase"); + } + } + } +} diff --git a/crypto/test/src/openpgp/examples/PgpExampleUtilities.cs b/crypto/test/src/openpgp/examples/PgpExampleUtilities.cs new file mode 100644 index 000000000..fd371d7af --- /dev/null +++ b/crypto/test/src/openpgp/examples/PgpExampleUtilities.cs @@ -0,0 +1,123 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + internal class PgpExampleUtilities + { + internal static byte[] CompressFile(string fileName, CompressionAlgorithmTag algorithm) + { + MemoryStream bOut = new MemoryStream(); + PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(algorithm); + PgpUtilities.WriteFileToLiteralData(comData.Open(bOut), PgpLiteralData.Binary, + new FileInfo(fileName)); + comData.Close(); + return bOut.ToArray(); + } + + /** + * Search a secret key ring collection for a secret key corresponding to keyID if it + * exists. + * + * @param pgpSec a secret key ring collection. + * @param keyID keyID we want. + * @param pass passphrase to decrypt secret key with. + * @return + * @throws PGPException + * @throws NoSuchProviderException + */ + internal static PgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyID, char[] pass) + { + PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyID); + + if (pgpSecKey == null) + { + return null; + } + + return pgpSecKey.ExtractPrivateKey(pass); + } + + internal static PgpPublicKey ReadPublicKey(string fileName) + { + using (Stream keyIn = File.OpenRead(fileName)) + { + return ReadPublicKey(keyIn); + } + } + + /** + * A simple routine that opens a key ring file and loads the first available key + * suitable for encryption. + * + * @param input + * @return + * @throws IOException + * @throws PGPException + */ + internal static PgpPublicKey ReadPublicKey(Stream input) + { + PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle( + PgpUtilities.GetDecoderStream(input)); + + // + // we just loop through the collection till we find a key suitable for encryption, in the real + // world you would probably want to be a bit smarter about this. + // + + foreach (PgpPublicKeyRing keyRing in pgpPub.GetKeyRings()) + { + foreach (PgpPublicKey key in keyRing.GetPublicKeys()) + { + if (key.IsEncryptionKey) + { + return key; + } + } + } + + throw new ArgumentException("Can't find encryption key in key ring."); + } + + internal static PgpSecretKey ReadSecretKey(string fileName) + { + using (Stream keyIn = File.OpenRead(fileName)) + { + return ReadSecretKey(keyIn); + } + } + + /** + * A simple routine that opens a key ring file and loads the first available key + * suitable for signature generation. + * + * @param input stream to read the secret key ring collection from. + * @return a secret key. + * @throws IOException on a problem with using the input stream. + * @throws PGPException if there is an issue parsing the input stream. + */ + internal static PgpSecretKey ReadSecretKey(Stream input) + { + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle( + PgpUtilities.GetDecoderStream(input)); + + // + // we just loop through the collection till we find a key suitable for encryption, in the real + // world you would probably want to be a bit smarter about this. + // + + foreach (PgpSecretKeyRing keyRing in pgpSec.GetKeyRings()) + { + foreach (PgpSecretKey key in keyRing.GetSecretKeys()) + { + if (key.IsSigningKey) + { + return key; + } + } + } + + throw new ArgumentException("Can't find signing key in key ring."); + } + } +} diff --git a/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs b/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs new file mode 100644 index 000000000..bb6108f2d --- /dev/null +++ b/crypto/test/src/openpgp/examples/PublicKeyRingDump.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Asn1.Utilities; + +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + /** + * Basic class which just lists the contents of the public key file passed + * as an argument. If the file contains more than one "key ring" they are + * listed in the order found. + */ + public sealed class PublicKeyRingDump + { + private PublicKeyRingDump() + { + } + + public static string GetAlgorithm( + PublicKeyAlgorithmTag algId) + { + switch (algId) + { + case PublicKeyAlgorithmTag.RsaGeneral: + return "RsaGeneral"; + case PublicKeyAlgorithmTag.RsaEncrypt: + return "RsaEncrypt"; + case PublicKeyAlgorithmTag.RsaSign: + return "RsaSign"; + case PublicKeyAlgorithmTag.ElGamalEncrypt: + return "ElGamalEncrypt"; + case PublicKeyAlgorithmTag.Dsa: + return "DSA"; + case PublicKeyAlgorithmTag.EC: + return "EC"; + case PublicKeyAlgorithmTag.ECDsa: + return "ECDSA"; + case PublicKeyAlgorithmTag.ElGamalGeneral: + return "ElGamalGeneral"; + case PublicKeyAlgorithmTag.DiffieHellman: + return "DiffieHellman"; + } + + return "unknown"; + } + + public static void Main( + string[] args) + { + Stream fs = File.OpenRead(args[0]); + + // + // Read the public key rings + // + PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle( + PgpUtilities.GetDecoderStream(fs)); + + fs.Close(); + + foreach (PgpPublicKeyRing pgpPub in pubRings.GetKeyRings()) + { + try + { + //PgpPublicKey pubKey = + pgpPub.GetPublicKey(); + } + catch (Exception e) + { + Console.Error.WriteLine(e.Message); + Console.Error.WriteLine(e.StackTrace); + continue; + } + + bool first = true; + + foreach (PgpPublicKey pgpKey in pgpPub.GetPublicKeys()) + { + if (first) + { + Console.WriteLine("Key ID: " + pgpKey.KeyId.ToString("X")); + first = false; + } + else + { + Console.WriteLine("Key ID: " + pgpKey.KeyId.ToString("X") + " (subkey)"); + } + + Console.WriteLine(" Algorithm: " + GetAlgorithm(pgpKey.Algorithm)); + Console.WriteLine(" Fingerprint: " + Hex.ToHexString(pgpKey.GetFingerprint())); + } + } + } + } +} diff --git a/crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs b/crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs new file mode 100644 index 000000000..284118b99 --- /dev/null +++ b/crypto/test/src/openpgp/examples/RsaKeyRingGenerator.cs @@ -0,0 +1,115 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + /** + * A simple utility class that Generates a RSA PgpPublicKey/PgpSecretKey pair. + *+ * usage: RsaKeyRingGenerator [-a] identity passPhrase
+ *+ * Where identity is the name to be associated with the public key. The keys are placed + * in the files pub.[asc|bpg] and secret.[asc|bpg].
+ */ + public sealed class RsaKeyRingGenerator + { + private RsaKeyRingGenerator() + { + } + + private static void ExportKeyPair( + Stream secretOut, + Stream publicOut, + AsymmetricKeyParameter publicKey, + AsymmetricKeyParameter privateKey, + string identity, + char[] passPhrase, + bool armor) + { + if (armor) + { + secretOut = new ArmoredOutputStream(secretOut); + } + + PgpSecretKey secretKey = new PgpSecretKey( + PgpSignature.DefaultCertification, + PublicKeyAlgorithmTag.RsaGeneral, + publicKey, + privateKey, + DateTime.UtcNow, + identity, + SymmetricKeyAlgorithmTag.Cast5, + passPhrase, + null, + null, + new SecureRandom() + ); + + secretKey.Encode(secretOut); + + if (armor) + { + secretOut.Close(); + publicOut = new ArmoredOutputStream(publicOut); + } + + PgpPublicKey key = secretKey.PublicKey; + + key.Encode(publicOut); + + if (armor) + { + publicOut.Close(); + } + } + + public static int Main( + string[] args) + { + IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("RSA"); + + kpg.Init(new RsaKeyGenerationParameters( + BigInteger.ValueOf(0x10001), new SecureRandom(), 1024, 25)); + + AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); + + if (args.Length < 2) + { + Console.WriteLine("RsaKeyPairGenerator [-a] identity passPhrase"); + return 0; + } + + Stream out1, out2; + if (args[0].Equals("-a")) + { + if (args.Length < 3) + { + Console.WriteLine("RsaKeyPairGenerator [-a] identity passPhrase"); + return 0; + } + + out1 = File.Create("secret.asc"); + out2 = File.Create("pub.asc"); + + ExportKeyPair(out1, out2, kp.Public, kp.Private, args[1], args[2].ToCharArray(), true); + } + else + { + out1 = File.Create("secret.bpg"); + out2 = File.Create("pub.bpg"); + + ExportKeyPair(out1, out2, kp.Public, kp.Private, args[0], args[1].ToCharArray(), false); + } + out1.Close(); + out2.Close(); + return 0; + } + } +} diff --git a/crypto/test/src/openpgp/examples/SignedFileProcessor.cs b/crypto/test/src/openpgp/examples/SignedFileProcessor.cs new file mode 100644 index 000000000..1ad0d102b --- /dev/null +++ b/crypto/test/src/openpgp/examples/SignedFileProcessor.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections; +using System.IO; + + +using Org.BouncyCastle.Bcpg.OpenPgp; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + /** + * A simple utility class that signs and verifies files. + *
+ * To sign a file: SignedFileProcessor -s [-a] fileName secretKey passPhrase.
+ * If -a is specified the output file will be "ascii-armored".
+ * To decrypt: SignedFileProcessor -v fileName publicKeyFile.
+ *+ * Note: this example will silently overwrite files, nor does it pay any attention to + * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase + * will have been used.
+ *+ * Note: the example also makes use of PGP compression. If you are having difficulty Getting it + * to interoperate with other PGP programs try removing the use of compression first.
+ */ + public sealed class SignedFileProcessor + { + private SignedFileProcessor() {} + + /** + * verify the passed in file as being correctly signed. + */ + private static void VerifyFile( + Stream inputStream, + Stream keyIn) + { + inputStream = PgpUtilities.GetDecoderStream(inputStream); + + PgpObjectFactory pgpFact = new PgpObjectFactory(inputStream); + PgpCompressedData c1 = (PgpCompressedData) pgpFact.NextPgpObject(); + pgpFact = new PgpObjectFactory(c1.GetDataStream()); + + PgpOnePassSignatureList p1 = (PgpOnePassSignatureList) pgpFact.NextPgpObject(); + PgpOnePassSignature ops = p1[0]; + + PgpLiteralData p2 = (PgpLiteralData) pgpFact.NextPgpObject(); + Stream dIn = p2.GetInputStream(); + PgpPublicKeyRingBundle pgpRing = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(keyIn)); + PgpPublicKey key = pgpRing.GetPublicKey(ops.KeyId); + Stream fos = File.Create(p2.FileName); + + ops.InitVerify(key); + + int ch; + while ((ch = dIn.ReadByte()) >= 0) + { + ops.Update((byte)ch); + fos.WriteByte((byte) ch); + } + fos.Close(); + + PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); + PgpSignature firstSig = p3[0]; + if (ops.Verify(firstSig)) + { + Console.Out.WriteLine("signature verified."); + } + else + { + Console.Out.WriteLine("signature verification failed."); + } + } + + /** + * Generate an encapsulated signed file. + * + * @param fileName + * @param keyIn + * @param outputStream + * @param pass + * @param armor + */ + private static void SignFile( + string fileName, + Stream keyIn, + Stream outputStream, + char[] pass, + bool armor, + bool compress) + { + if (armor) + { + outputStream = new ArmoredOutputStream(outputStream); + } + + PgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn); + PgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass); + PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1); + + sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); + foreach (string userId in pgpSec.PublicKey.GetUserIds()) + { + PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator(); + spGen.SetSignerUserId(false, userId); + sGen.SetHashedSubpackets(spGen.Generate()); + // Just the first one! + break; + } + + Stream cOut = outputStream; + PgpCompressedDataGenerator cGen = null; + if (compress) + { + cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.ZLib); + + cOut = cGen.Open(cOut); + } + + BcpgOutputStream bOut = new BcpgOutputStream(cOut); + + sGen.GenerateOnePassVersion(false).Encode(bOut); + + FileInfo file = new FileInfo(fileName); + PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); + Stream lOut = lGen.Open(bOut, PgpLiteralData.Binary, file); + FileStream fIn = file.OpenRead(); + int ch = 0; + + while ((ch = fIn.ReadByte()) >= 0) + { + lOut.WriteByte((byte) ch); + sGen.Update((byte)ch); + } + + fIn.Close(); + lGen.Close(); + + sGen.Generate().Encode(bOut); + + if (cGen != null) + { + cGen.Close(); + } + + if (armor) + { + outputStream.Close(); + } + } + + public static void Main( + string[] args) + { + // TODO provide command-line option to determine whether to use compression in SignFile + if (args[0].Equals("-s")) + { + Stream keyIn, fos; + if (args[1].Equals("-a")) + { + keyIn = File.OpenRead(args[3]); + fos = File.Create(args[2] + ".asc"); + + SignFile(args[2], keyIn, fos, args[4].ToCharArray(), true, true); + } + else + { + keyIn = File.OpenRead(args[2]); + fos = File.Create(args[1] + ".bpg"); + + SignFile(args[1], keyIn, fos, args[3].ToCharArray(), false, true); + } + keyIn.Close(); + fos.Close(); + } + else if (args[0].Equals("-v")) + { + using (Stream fis = File.OpenRead(args[1]), + keyIn = File.OpenRead(args[2])) + { + VerifyFile(fis, keyIn); + } + } + else + { + Console.Error.WriteLine("usage: SignedFileProcessor -v|-s [-a] file keyfile [passPhrase]"); + } + } + } +} diff --git a/crypto/test/src/openpgp/examples/test/AllTests.cs b/crypto/test/src/openpgp/examples/test/AllTests.cs new file mode 100644 index 000000000..180d2fa80 --- /dev/null +++ b/crypto/test/src/openpgp/examples/test/AllTests.cs @@ -0,0 +1,403 @@ +using System; +using System.IO; + +using NUnit.Core; +using NUnit.Framework; + +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples.Tests +{ + [TestFixture] + public class AllTests + { + private static readonly byte[] clearSignedPublicKey = Base64.Decode( + "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" + + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" + + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" + + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" + + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" + + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" + + "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD" + + "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR" + + "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch" + + "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg" + + "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r" + + "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1" + + "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz" + + "oztls8tuWA0OGHba9XfX9rfgorACAAM="); + + private static readonly string crOnlyMessage = + "\r" + + " hello world!\r" + + "\r" + + "- dash\r"; + + private static readonly string nlOnlyMessage = + "\n" + + " hello world!\n" + + "\n" + + "- dash\n"; + + private static readonly string crNlMessage = + "\r\n" + + " hello world!\r\n" + + "\r\n" + + "- dash\r\n"; + + private static readonly string crNlMessageTrailingWhiteSpace = + "\r\n" + + " hello world! \t\r\n" + + "\r\n" + + "\r\n"; + + private static readonly string crOnlySignedMessage = + "-----BEGIN PGP SIGNED MESSAGE-----\r" + + "Hash: SHA256\r" + + "\r" + + "\r" + + " hello world!\r" + + "\r" + + "- - dash\r" + + "-----BEGIN PGP SIGNATURE-----\r" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r" + + "\r" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r" + + "=84Nd\r" + + "-----END PGP SIGNATURE-----\r"; + + private static readonly string nlOnlySignedMessage = + "-----BEGIN PGP SIGNED MESSAGE-----\n" + + "Hash: SHA256\n" + + "\n" + + "\n" + + " hello world!\n" + + "\n" + + "- - dash\n" + + "-----BEGIN PGP SIGNATURE-----\n" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\n" + + "\n" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n" + + "=84Nd\n" + + "-----END PGP SIGNATURE-----\n"; + + private static readonly string crNlSignedMessage = + "-----BEGIN PGP SIGNED MESSAGE-----\r\n" + + "Hash: SHA256\r\n" + + "\r\n" + + "\r\n" + + " hello world!\r\n" + + "\r\n" + + "- - dash\r\n" + + "-----BEGIN PGP SIGNATURE-----\r\n" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" + + "\r\n" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" + + "=84Nd\r" + + "-----END PGP SIGNATURE-----\r\n"; + + private static readonly string crNlSignedMessageTrailingWhiteSpace = + "-----BEGIN PGP SIGNED MESSAGE-----\r\n" + + "Hash: SHA256\r\n" + + "\r\n" + + "\r\n" + + " hello world! \t\r\n" + + "\r\n" + + "- - dash\r\n" + + "-----BEGIN PGP SIGNATURE-----\r\n" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" + + "\r\n" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" + + "=84Nd\r" + + "-----END PGP SIGNATURE-----\r\n"; + + private TextWriter _oldOut; + private TextWriter _oldErr; + + private MemoryStream _currentOut; + private MemoryStream _currentErr; + + [SetUp] + public void SetUp() + { + _oldOut = Console.Out; + _oldErr = Console.Error; + _currentOut = new MemoryStream(); + _currentErr = new MemoryStream(); + + Console.SetOut(new StreamWriter(_currentOut)); + Console.SetError(new StreamWriter(_currentErr)); + } + + [TearDown] + public void TearDown() + { + Console.SetOut(_oldOut); + Console.SetError(_oldErr); + } + + [Test] + public void TestRsaKeyGeneration() + { + RsaKeyRingGenerator.Main(new string[] { "test", "password" }); + + CreateSmallTestInput(); + CreateLargeTestInput(); + + CheckSigning("bpg"); + CheckKeyBasedEncryption("bpg"); + CheckLargeKeyBasedEncryption("bpg"); + + RsaKeyRingGenerator.Main(new string[] { "-a", "test", "password" }); + + CheckSigning("asc"); + CheckKeyBasedEncryption("asc"); + CheckLargeKeyBasedEncryption("asc"); + } + + [Test] + public void TestDsaElGamalKeyGeneration() + { + DsaElGamalKeyRingGenerator.Main(new string[] { "test", "password" }); + + CreateSmallTestInput(); + CreateLargeTestInput(); + + CheckSigning("bpg"); + CheckKeyBasedEncryption("bpg"); + CheckLargeKeyBasedEncryption("bpg"); + + DsaElGamalKeyRingGenerator.Main(new string[] { "-a", "test", "password" }); + + CheckSigning("asc"); + CheckKeyBasedEncryption("asc"); + CheckLargeKeyBasedEncryption("asc"); + } + + [Test] + public void TestPbeEncryption() + { + Console.Error.Flush(); + _currentErr.SetLength(0); + + PbeFileProcessor.Main(new string[] { "-e", "test.txt", "password" }); + + PbeFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "password" }); + + Console.Error.Flush(); + Assert.AreEqual("no message integrity check", GetLine(_currentErr)); + + PbeFileProcessor.Main(new string[] { "-e", "-i", "test.txt", "password" }); + + PbeFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "password" }); + + Console.Error.Flush(); + Assert.AreEqual("message integrity check passed", GetLine(_currentErr)); + + PbeFileProcessor.Main(new string[] { "-e", "-ai", "test.txt", "password" }); + + PbeFileProcessor.Main(new string[] { "-d", "test.txt.asc", "password" }); + + Console.Error.Flush(); + Assert.AreEqual("message integrity check passed", GetLine(_currentErr)); + } + + [Test] + public void TestClearSigned() + { + CreateTestFile(clearSignedPublicKey, "pub.bpg"); + + CheckClearSignedVerify(nlOnlySignedMessage); + CheckClearSignedVerify(crOnlySignedMessage); + CheckClearSignedVerify(crNlSignedMessage); + CheckClearSignedVerify(crNlSignedMessageTrailingWhiteSpace); + + ClearSignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub.bpg" }); + + RsaKeyRingGenerator.Main(new string[] { "test", "password" }); + + CheckClearSigned(crOnlyMessage); + CheckClearSigned(nlOnlyMessage); + CheckClearSigned(crNlMessage); + CheckClearSigned(crNlMessageTrailingWhiteSpace); + } + + [Test] + public void TestClearSignedBogusInput() + { + CreateTestFile(clearSignedPublicKey, "test.txt"); + + ClearSignedFileProcessor.Main(new String[] { "-s", "test.txt", "secret.bpg", "password" }); + } + + private void CheckClearSignedVerify( + string message) + { + CreateTestData(message, "test.txt.asc"); + + ClearSignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub.bpg" }); + } + + private void CheckClearSigned( + string message) + { + CreateTestData(message, "test.txt"); + + ClearSignedFileProcessor.Main(new string[] { "-s", "test.txt", "secret.bpg", "password" }); + ClearSignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub.bpg" }); + } + + private void CheckSigning( + string type) + { + Console.Out.Flush(); + _currentOut.SetLength(0); + + SignedFileProcessor.Main(new string[] { "-s", "test.txt", "secret." + type, "password" }); + SignedFileProcessor.Main(new string[] { "-v", "test.txt.bpg", "pub." + type }); + + Console.Out.Flush(); + Assert.AreEqual("signature verified.", GetLine(_currentOut)); + + SignedFileProcessor.Main(new string[] { "-s", "-a", "test.txt", "secret." + type, "password" }); + SignedFileProcessor.Main(new string[] { "-v", "test.txt.asc", "pub." + type }); + + Console.Out.Flush(); + Assert.AreEqual("signature verified.", GetLine(_currentOut)); + } + + private void CheckKeyBasedEncryption( + string type) + { + Console.Error.Flush(); + _currentErr.SetLength(0); + + KeyBasedFileProcessor.Main(new string[] { "-e", "test.txt", "pub." + type }); + KeyBasedFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "secret." + type, "password" }); + + Console.Error.Flush(); + Assert.AreEqual("no message integrity check", GetLine(_currentErr)); + + KeyBasedFileProcessor.Main(new string[] { "-e", "-i", "test.txt", "pub." + type }); + KeyBasedFileProcessor.Main(new string[] { "-d", "test.txt.bpg", "secret." + type, "password" }); + + Console.Error.Flush(); + Assert.AreEqual("message integrity check passed", GetLine(_currentErr)); + + KeyBasedFileProcessor.Main(new string[] { "-e", "-ai", "test.txt", "pub." + type }); + KeyBasedFileProcessor.Main(new string[] { "-d", "test.txt.asc", "secret." + type, "password" }); + + Console.Error.Flush(); + Assert.AreEqual("message integrity check passed", GetLine(_currentErr)); + } + + private void CheckLargeKeyBasedEncryption( + string type) + { + Console.Error.Flush(); + _currentErr.SetLength(0); + + KeyBasedLargeFileProcessor.Main(new string[] { "-e", "large.txt", "pub." + type }); + KeyBasedLargeFileProcessor.Main(new string[] { "-d", "large.txt.bpg", "secret." + type, "password" }); + + Console.Error.Flush(); + Assert.AreEqual("no message integrity check", GetLine(_currentErr)); + + KeyBasedLargeFileProcessor.Main(new string[] { "-e", "-i", "large.txt", "pub." + type }); + KeyBasedLargeFileProcessor.Main(new string[] { "-d", "large.txt.bpg", "secret." + type, "password" }); + + Console.Error.Flush(); + Assert.AreEqual("message integrity check passed", GetLine(_currentErr)); + + KeyBasedLargeFileProcessor.Main(new string[] { "-e", "-ai", "large.txt", "pub." + type }); + KeyBasedLargeFileProcessor.Main(new string[] { "-d", "large.txt.asc", "secret." + type, "password" }); + + Console.Error.Flush(); + Assert.AreEqual("message integrity check passed", GetLine(_currentErr)); + } + + private void CreateSmallTestInput() + { + TextWriter bfOut = new StreamWriter(File.Create("test.txt")); + bfOut.WriteLine("hello world!"); + bfOut.Close(); + } + + private void CreateLargeTestInput() + { + TextWriter bfOut = new StreamWriter(File.Create("large.txt")); + + for (int i = 1; i <= 2000; i++) + { + bfOut.WriteLine("hello to planet " + i + "!"); + } + + bfOut.Close(); + } + + private void CreateTestData( + string testData, + string name) + { + TextWriter bfOut = new StreamWriter(File.Create(name)); + bfOut.Write(testData); + bfOut.Close(); + } + + private void CreateTestFile( + byte[] keyData, + string name) + { + FileStream fOut = File.Create(name); + fOut.Write(keyData, 0, keyData.Length); + fOut.Close(); + } + + private string GetLine( + MemoryStream outStr) + { + byte[] b = outStr.ToArray(); + TextReader bRd = new StreamReader(new MemoryStream(b, false)); + outStr.SetLength(0); + return bRd.ReadLine(); + } + + public static void Main( + string[] args) + { + //junit.textui.TestRunner.run(suite()); + EventListener el = new NullListener(); + suite().Run(el); + } + + public static TestSuite suite() + { + TestSuite suite = new TestSuite("OpenPGP Example Tests"); + + suite.Add(new AllTests()); + + return suite; + } + + } +} diff --git a/crypto/test/src/openpgp/test/DSA2Test.cs b/crypto/test/src/openpgp/test/DSA2Test.cs new file mode 100644 index 000000000..883ae317f --- /dev/null +++ b/crypto/test/src/openpgp/test/DSA2Test.cs @@ -0,0 +1,237 @@ +using System; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + /** + * GPG compatability test vectors + */ + [TestFixture] + public class Dsa2Test + //extends TestCase + { + [Test] + public void TestK1024H160() + { + doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-160-sign.gpg"); + } + + [Test] + public void TestK1024H224() + { + doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-224-sign.gpg"); + } + + [Test] + public void TestK1024H256() + { + doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-256-sign.gpg"); + } + + [Test] + public void TestK1024H384() + { + doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-384-sign.gpg"); + } + + [Test] + public void TestK1024H512() + { + doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-512-sign.gpg"); + } + + [Test] + public void TestK2048H224() + { + doSigVerifyTest("DSA-2048-224.pub", "dsa-2048-224-sign.gpg"); + } + + [Test] + public void TestK3072H256() + { + doSigVerifyTest("DSA-3072-256.pub", "dsa-3072-256-sign.gpg"); + } + + [Test] + public void TestK7680H384() + { + doSigVerifyTest("DSA-7680-384.pub", "dsa-7680-384-sign.gpg"); + } + + [Test] + public void TestK15360H512() + { + doSigVerifyTest("DSA-15360-512.pub", "dsa-15360-512-sign.gpg"); + } + + [Test] + public void TestGenerateK1024H224() + { + doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha224); + } + + [Test] + public void TestGenerateK1024H256() + { + doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha256); + } + + [Test] + public void TestGenerateK1024H384() + { + doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha384); + } + + [Test] + public void TestGenerateK1024H512() + { + doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", HashAlgorithmTag.Sha512); + } + + [Test] + public void TestGenerateK2048H256() + { + doSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", HashAlgorithmTag.Sha256); + } + + [Test] + public void TestGenerateK2048H512() + { + doSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", HashAlgorithmTag.Sha512); + } + + private void doSigGenerateTest( + string privateKeyFile, + string publicKeyFile, + HashAlgorithmTag digest) + { + PgpSecretKeyRing secRing = loadSecretKey(privateKeyFile); + PgpPublicKeyRing pubRing = loadPublicKey(publicKeyFile); + 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, digest); + + sGen.InitSign(PgpSignature.BinaryDocument, secRing.GetSecretKey().ExtractPrivateKey("test".ToCharArray())); + + BcpgOutputStream bcOut = new BcpgOutputStream(bOut); + + sGen.GenerateOnePassVersion(false).Encode(bcOut); + + PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); + +// Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); + DateTime testDate = new DateTime( + (DateTime.UtcNow.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond); + + Stream lOut = lGen.Open( + new UncloseableStream(bcOut), + PgpLiteralData.Binary, + "_CONSOLE", + dataBytes.Length, + testDate); + + int ch; + while ((ch = testIn.ReadByte()) >= 0) + { + lOut.WriteByte((byte)ch); + sGen.Update((byte)ch); + } + + lGen.Close(); + + sGen.Generate().Encode(bcOut); + + PgpObjectFactory pgpFact = new PgpObjectFactory(bOut.ToArray()); + PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); + PgpOnePassSignature ops = p1[0]; + + Assert.AreEqual(digest, ops.HashAlgorithm); + Assert.AreEqual(PublicKeyAlgorithmTag.Dsa, ops.KeyAlgorithm); + + PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject(); + if (!p2.ModificationTime.Equals(testDate)) + { + Assert.Fail("Modification time not preserved"); + } + + Stream dIn = p2.GetInputStream(); + + ops.InitVerify(pubRing.GetPublicKey()); + + while ((ch = dIn.ReadByte()) >= 0) + { + ops.Update((byte)ch); + } + + PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); + PgpSignature sig = p3[0]; + + Assert.AreEqual(digest, sig.HashAlgorithm); + Assert.AreEqual(PublicKeyAlgorithmTag.Dsa, sig.KeyAlgorithm); + + Assert.IsTrue(ops.Verify(sig)); + } + + private void doSigVerifyTest( + string publicKeyFile, + string sigFile) + { + PgpPublicKeyRing publicKey = loadPublicKey(publicKeyFile); + PgpObjectFactory pgpFact = loadSig(sigFile); + + 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(publicKey.GetPublicKey()); + + int ch; + while ((ch = dIn.ReadByte()) >= 0) + { + ops.Update((byte)ch); + } + + PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); + + Assert.IsTrue(ops.Verify(p3[0])); + } + + private PgpObjectFactory loadSig( + string sigName) + { + Stream fIn = SimpleTest.GetTestDataAsStream("openpgp.dsa.sigs." + sigName); + + return new PgpObjectFactory(fIn); + } + + private PgpPublicKeyRing loadPublicKey( + string keyName) + { + Stream fIn = SimpleTest.GetTestDataAsStream("openpgp.dsa.keys." + keyName); + + return new PgpPublicKeyRing(fIn); + } + + private PgpSecretKeyRing loadSecretKey( + string keyName) + { + Stream fIn = SimpleTest.GetTestDataAsStream("openpgp.dsa.keys." + keyName); + + return new PgpSecretKeyRing(fIn); + } + } +} diff --git a/crypto/test/src/openpgp/test/PGPArmoredTest.cs b/crypto/test/src/openpgp/test/PGPArmoredTest.cs new file mode 100644 index 000000000..aa13477ed --- /dev/null +++ b/crypto/test/src/openpgp/test/PGPArmoredTest.cs @@ -0,0 +1,265 @@ +using System; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpArmoredTest + : SimpleTest + { + private static readonly byte[] sample = Base64.Decode( + "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + + "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh" + + "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB" + + "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p" + + "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5" + + "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN" + + "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE" + + "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1" + + "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu" + + "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y" + + "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB" + + "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u" + + "ZJhfg0htdgAfIy8ppm05vLACAAA="); + + private static readonly byte[] marker = Hex.Decode("2d2d2d2d2d454e4420504750205055424c4943204b455920424c4f434b2d2d2d2d2d"); + + // Contains "Hello World!" as an armored message + // The 'blank line' after the headers contains (legal) whitespace - see RFC2440 6.2 + private static readonly string blankLineData = + "-----BEGIN PGP MESSAGE-----\n" + + "Version: BCPG v1.32\n" + + "Comment: A dummy message\n" + + " \t \t\n" + + "SGVsbG8gV29ybGQh\n" + + "=d9Xi\n" + + "-----END PGP MESSAGE-----\n"; + + private int markerCount( + byte[] data) + { + int ind = 0; + int matches = 0; + + while (ind < data.Length) + { + if (data[ind] == 0x2d) + { + int count = 0; + while (count < marker.Length) + { + if (data[ind + count] != marker[count]) + { + break; + } + count++; + } + + if (count == marker.Length) + { + matches++; + } + + // TODO Is this correct? + ind += count; + } + else + { + ind++; + } + } + + return matches; + } + + private void blankLineTest() + { + byte[] blankLineBytes = Encoding.ASCII.GetBytes(blankLineData); + MemoryStream bIn = new MemoryStream(blankLineBytes, false); + ArmoredInputStream aIn = new ArmoredInputStream(bIn, true); + + MemoryStream bOut = new MemoryStream(); + int c; + while ((c = aIn.ReadByte()) >= 0) + { + bOut.WriteByte((byte)c); + } + + byte[] expected = Encoding.ASCII.GetBytes("Hello World!"); + + if (!Arrays.AreEqual(expected, bOut.ToArray())) + { + Fail("Incorrect message retrieved in blank line test."); + } + } + + public override void PerformTest() + { + // + // test immediate close + // + MemoryStream bOut = new MemoryStream(); + ArmoredOutputStream aOut = new ArmoredOutputStream(bOut); + + aOut.Close(); + + byte[] data = bOut.ToArray(); + + if (data.Length != 0) + { + Fail("No data should have been written"); + } + + // + // multiple close + // + bOut = new MemoryStream(); + aOut = new ArmoredOutputStream(bOut); + + aOut.Write(sample, 0, sample.Length); + + aOut.Close(); + aOut.Close(); + + int mc = markerCount(bOut.ToArray()); + + if (mc < 1) + { + Fail("No end marker found"); + } + + if (mc > 1) + { + Fail("More than one end marker found"); + } + + // + // writing and reading single objects + // + bOut = new MemoryStream(); + aOut = new ArmoredOutputStream(bOut); + + aOut.Write(sample, 0, sample.Length); + + aOut.Close(); + + ArmoredInputStream aIn = new ArmoredInputStream( + new MemoryStream(bOut.ToArray(), false)); + + PgpObjectFactory fact = new PgpObjectFactory(aIn); + int count = 0; + + while (fact.NextPgpObject() != null) + { + count++; + } + + if (count != 1) + { + Fail("wrong number of objects found: " + count); + } + + // + // writing and reading multiple objects - in single block + // + bOut = new MemoryStream(); + aOut = new ArmoredOutputStream(bOut); + + aOut.Write(sample, 0, sample.Length); + aOut.Write(sample, 0, sample.Length); + + aOut.Close(); + + aIn = new ArmoredInputStream( + new MemoryStream(bOut.ToArray(), false)); + + fact = new PgpObjectFactory(aIn); + count = 0; + + while (fact.NextPgpObject() != null) + { + count++; + } + + if (count != 2) + { + Fail("wrong number of objects found: " + count); + } + + // + // writing and reading multiple objects - in single block + // + bOut = new MemoryStream(); + aOut = new ArmoredOutputStream(bOut); + + aOut.Write(sample, 0, sample.Length); + + aOut.Close(); // does not close underlying stream + + aOut = new ArmoredOutputStream(bOut); + + aOut.Write(sample, 0, sample.Length); + + aOut.Close(); + + aIn = new ArmoredInputStream( + new MemoryStream(bOut.ToArray(), false)); + + count = 0; + bool atLeastOne; + do + { + atLeastOne = false; + fact = new PgpObjectFactory(aIn); + + while (fact.NextPgpObject() != null) + { + atLeastOne = true; + count++; + } + } + while (atLeastOne); + + if (count != 2) + { + Fail("wrong number of objects found: " + count); + } + + blankLineTest(); + } + + public override string Name + { + get { return "PGPArmoredTest"; } + } + + public static void Main( + string[] args) + { + RunTest(new PgpArmoredTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs b/crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs new file mode 100644 index 000000000..668f8cce2 --- /dev/null +++ b/crypto/test/src/openpgp/test/PGPClearSignedSignatureTest.cs @@ -0,0 +1,445 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Utilities.Test; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpClearSignedSignatureTest + : SimpleTest + { + private static readonly byte[] publicKey = Base64.Decode( + "mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" + + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" + + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" + + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" + + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" + + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" + + "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD" + + "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR" + + "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch" + + "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg" + + "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r" + + "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1" + + "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz" + + "oztls8tuWA0OGHba9XfX9rfgorACAAM="); + + private static readonly byte[] secretKey = Base64.Decode( + "lQOWBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+" + + "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1" + + "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO" + + "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7" + + "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4" + + "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp" + + "AAf+JCJJeAXEcrTVHotsrRR5idzmg6RK/1MSQUijwPmP7ZGy1BmpAmYUfbxn" + + "B56GvXyFV3Pbj9PgyJZGS7cY+l0BF4ZqN9USiQtC9OEpCVT5LVMCFXC/lahC" + + "/O3EkjQy0CYK+GwyIXa+Flxcr460L/Hvw2ZEXJZ6/aPdiR+DU1l5h99Zw8V1" + + "Y625MpfwN6ufJfqE0HLoqIjlqCfi1iwcKAK2oVx2SwnT1W0NwUUXjagGhD2s" + + "VzJVpLqhlwmS0A+RE9Niqrf80/zwE7QNDF2DtHxmMHJ3RY/pfu5u1rrFg9YE" + + "lmS60mzOe31CaD8Li0k5YCJBPnmvM9mN3/DWWprSZZKtmQQA96C2/VJF5EWm" + + "+/Yxi5J06dG6Bkz311Ui4p2zHm9/4GvTPCIKNpGx9Zn47YFD3tIg3fIBVPOE" + + "ktG38pEPx++dSSFF9Ep5UgmYFNOKNUVq3yGpatBtCQBXb1LQLAMBJCJ5TQmk" + + "68hMOEaqjMHSOa18cS63INgA6okb/ueAKIHxYQcEAP9DaXu5n9dZQw7pshbN" + + "Nu/T5IP0/D/wqM+W5r+j4P1N7PgiAnfKA4JjKrUgl8PGnI2qM/Qu+g3qK++c" + + "F1ESHasnJPjvNvY+cfti06xnJVtCB/EBOA2UZkAr//Tqa76xEwYAWRBnO2Y+" + + "KIVOT+nMiBFkjPTrNAD6fSr1O4aOueBhBAC6aA35IfjC2h5MYk8+Z+S4io2o" + + "mRxUZ/dUuS+kITvWph2e4DT28Xpycpl2n1Pa5dCDO1lRqe/5JnaDYDKqxfmF" + + "5tTG8GR4d4nVawwLlifXH5Ll7t5NcukGNMCsGuQAHMy0QHuAaOvMdLs5kGHn" + + "8VxfKEVKhVrXsvJSwyXXSBtMtUcRtBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2" + + "BBMBAgAgBQJEIdvsAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ4M/I" + + "er3f9xagdAf/fbKWBjLQM8xR7JkRP4ri8YKOQPhK+VrddGUD59/wzVnvaGyl" + + "9MZE7TXFUeniQq5iXKnm22EQbYchv2Jcxyt2H9yptpzyh4tP6tEHl1C887p2" + + "J4qe7F2ATua9CzVGwXQSUbKtj2fgUZP5SsNp25guhPiZdtkf2sHMeiotmykF" + + "ErzqGMrvOAUThrO63GiYsRk4hF6rcQ01d+EUVpY/sBcCxgNyOiB7a84sDtrx" + + "nX5BTEZDTEj8LvuEyEV3TMUuAjx17Eyd+9JtKzwV4v3hlTaWOvGro9nPS7Ya" + + "PuG+RtufzXCUJPbPfTjTvtGOqvEzoztls8tuWA0OGHba9XfX9rfgorACAAA="); + + private static readonly string crOnlyMessage = + "\r" + + " hello world!\r" + + "\r" + + "- dash\r"; + + private static readonly string nlOnlyMessage = + "\n" + + " hello world!\n" + + "\n" + + "- dash\n"; + + private static readonly string crNlMessage = + "\r\n" + + " hello world!\r\n" + + "\r\n" + + "- dash\r\n"; + + private static readonly string crOnlySignedMessage = + "-----BEGIN PGP SIGNED MESSAGE-----\r" + + "Hash: SHA256\r" + + "\r" + + "\r" + + " hello world!\r" + + "\r" + + "- - dash\r" + + "-----BEGIN PGP SIGNATURE-----\r" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r" + + "\r" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r" + + "=84Nd\r" + + "-----END PGP SIGNATURE-----\r"; + + private static readonly string nlOnlySignedMessage = + "-----BEGIN PGP SIGNED MESSAGE-----\n" + + "Hash: SHA256\n" + + "\n" + + "\n" + + " hello world!\n" + + "\n" + + "- - dash\n" + + "-----BEGIN PGP SIGNATURE-----\n" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\n" + + "\n" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n" + + "=84Nd\n" + + "-----END PGP SIGNATURE-----\n"; + + private static readonly string crNlSignedMessage = + "-----BEGIN PGP SIGNED MESSAGE-----\r\n" + + "Hash: SHA256\r\n" + + "\r\n" + + "\r\n" + + " hello world!\r\n" + + "\r\n" + + "- - dash\r\n" + + "-----BEGIN PGP SIGNATURE-----\r\n" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" + + "\r\n" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" + + "=84Nd\r" + + "-----END PGP SIGNATURE-----\r\n"; + + private static readonly string crNlSignedMessageTrailingWhiteSpace = + "-----BEGIN PGP SIGNED MESSAGE-----\r\n" + + "Hash: SHA256\r\n" + + "\r\n" + + "\r\n" + + " hello world! \t\r\n" + + "\r\n" + + "- - dash\r\n" + + "-----BEGIN PGP SIGNATURE-----\r\n" + + "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n" + + "\r\n" + + "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n" + + "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n" + + "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n" + + "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n" + + "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n" + + "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n" + + "=84Nd\r" + + "-----END PGP SIGNATURE-----\r\n"; + + public override string Name + { + get { return "PGPClearSignedSignature"; } + } + + private void messageTest( + string message, + string type) + { + ArmoredInputStream aIn = new ArmoredInputStream( + new MemoryStream(Encoding.ASCII.GetBytes(message))); + + string[] headers = aIn.GetArmorHeaders(); + + if (headers == null || headers.Length != 1) + { + Fail("wrong number of headers found"); + } + + if (!"Hash: SHA256".Equals(headers[0])) + { + Fail("header value wrong: " + headers[0]); + } + + // + // read the input, making sure we ingore the last newline. + // + MemoryStream bOut = new MemoryStream(); + int ch; + + while ((ch = aIn.ReadByte()) >= 0 && aIn.IsClearText()) + { + bOut.WriteByte((byte)ch); + } + + PgpPublicKeyRingBundle pgpRings = new PgpPublicKeyRingBundle(publicKey); + + PgpObjectFactory pgpFact = new PgpObjectFactory(aIn); + PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); + PgpSignature sig = p3[0]; + + sig.InitVerify(pgpRings.GetPublicKey(sig.KeyId)); + + MemoryStream lineOut = new MemoryStream(); + Stream sigIn = new MemoryStream(bOut.ToArray(), false); + int lookAhead = ReadInputLine(lineOut, sigIn); + + ProcessLine(sig, lineOut.ToArray()); + + if (lookAhead != -1) + { + do + { + lookAhead = ReadInputLine(lineOut, lookAhead, sigIn); + + sig.Update((byte) '\r'); + sig.Update((byte) '\n'); + + ProcessLine(sig, lineOut.ToArray()); + } + while (lookAhead != -1); + } + + if (!sig.Verify()) + { + Fail("signature failed to verify m_in " + type); + } + } + + private PgpSecretKey ReadSecretKey( + Stream inputStream) + { + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(inputStream); + + // + // we just loop through the collection till we find a key suitable for encryption, in the real + // world you would probably want to be a bit smarter about this. + // + // + // iterate through the key rings. + // + foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings()) + { + foreach (PgpSecretKey k in kRing.GetSecretKeys()) + { + if (k.IsSigningKey) + { + return k; + } + } + } + + throw new ArgumentException("Can't find signing key in key ring."); + } + + private void generateTest( + string message, + string type) + { + PgpSecretKey pgpSecKey = ReadSecretKey(new MemoryStream(secretKey)); + PgpPrivateKey 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); + } + + private static int ReadInputLine( + MemoryStream bOut, + Stream fIn) + { + bOut.SetLength(0); + + int lookAhead = -1; + int ch; + + while ((ch = fIn.ReadByte()) >= 0) + { + bOut.WriteByte((byte) ch); + if (ch == '\r' || ch == '\n') + { + lookAhead = ReadPassedEol(bOut, ch, fIn); + break; + } + } + + return lookAhead; + } + + private static int ReadInputLine( + MemoryStream bOut, + int lookAhead, + Stream fIn) + { + bOut.SetLength(0); + + int ch = lookAhead; + + do + { + bOut.WriteByte((byte) ch); + if (ch == '\r' || ch == '\n') + { + lookAhead = ReadPassedEol(bOut, ch, fIn); + break; + } + } + while ((ch = fIn.ReadByte()) >= 0); + + return lookAhead; + } + + private static int ReadPassedEol( + MemoryStream bOut, + int lastCh, + Stream fIn) + { + int lookAhead = fIn.ReadByte(); + + if (lastCh == '\r' && lookAhead == '\n') + { + bOut.WriteByte((byte) lookAhead); + lookAhead = fIn.ReadByte(); + } + + return lookAhead; + } + + private static void ProcessLine( + PgpSignature sig, + byte[] line) + { + int length = GetLengthWithoutWhiteSpace(line); + if (length > 0) + { + sig.Update(line, 0, length); + } + } + + private static void ProcessLine( + Stream aOut, + PgpSignatureGenerator sGen, + byte[] line) + { + int length = GetLengthWithoutWhiteSpace(line); + if (length > 0) + { + sGen.Update(line, 0, length); + } + + aOut.Write(line, 0, line.Length); + } + + private static int GetLengthWithoutWhiteSpace( + byte[] line) + { + int end = line.Length - 1; + + while (end >= 0 && IsWhiteSpace(line[end])) + { + end--; + } + + return end + 1; + } + + private static bool IsWhiteSpace( + byte b) + { + return b == '\r' || b == '\n' || b == '\t' || b == ' '; + } + + public override void PerformTest() + { + messageTest(crOnlySignedMessage, "\\r"); + messageTest(nlOnlySignedMessage, "\\n"); + messageTest(crNlSignedMessage, "\\r\\n"); + messageTest(crNlSignedMessageTrailingWhiteSpace, "\\r\\n"); + + generateTest(nlOnlyMessage, "\\r"); + generateTest(crOnlyMessage, "\\n"); + generateTest(crNlMessage, "\\r\\n"); + } + + public static void Main( + string[] args) + { + RunTest(new PgpClearSignedSignatureTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/openpgp/test/PGPCompressionTest.cs b/crypto/test/src/openpgp/test/PGPCompressionTest.cs new file mode 100644 index 000000000..fdcf7222c --- /dev/null +++ b/crypto/test/src/openpgp/test/PGPCompressionTest.cs @@ -0,0 +1,117 @@ +using System; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Asn1.Utilities; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpCompressionTest + : SimpleTest + { + private static readonly byte[] Data = Encoding.ASCII.GetBytes("hello world! !dlrow olleh"); + + [Test] + public void TestUncompressed() + { + doTestCompression(CompressionAlgorithmTag.Uncompressed); + } + + [Test] + public void TestZip() + { + doTestCompression(CompressionAlgorithmTag.Zip); + } + + [Test] + public void TestZLib() + { + doTestCompression(CompressionAlgorithmTag.ZLib); + } + + [Test] + public void TestBZip2() + { + doTestCompression(CompressionAlgorithmTag.BZip2); + } + + public override void PerformTest() + { + doTestCompression(CompressionAlgorithmTag.Uncompressed); + doTestCompression(CompressionAlgorithmTag.Zip); + doTestCompression(CompressionAlgorithmTag.ZLib); + doTestCompression(CompressionAlgorithmTag.BZip2); + } + + private void doTestCompression( + CompressionAlgorithmTag type) + { + doTestCompression(type, true); + doTestCompression(type, false); + } + + private void doTestCompression( + CompressionAlgorithmTag type, + bool streamClose) + { + MemoryStream bOut = new MemoryStream(); + PgpCompressedDataGenerator cPacket = new PgpCompressedDataGenerator(type); + Stream os = cPacket.Open(new UncloseableStream(bOut), new byte[Data.Length - 1]); + os.Write(Data, 0, Data.Length); + + if (streamClose) + { + os.Close(); + } + else + { + cPacket.Close(); + } + + ValidateData(bOut.ToArray()); + + try + { + os.Close(); + cPacket.Close(); + } + catch (Exception) + { + Fail("Redundant Close() should be ignored"); + } + } + + private void ValidateData( + byte[] compressed) + { + PgpObjectFactory pgpFact = new PgpObjectFactory(compressed); + PgpCompressedData c1 = (PgpCompressedData) pgpFact.NextPgpObject(); + + Stream pIn = c1.GetDataStream(); + byte[] bytes = Streams.ReadAll(pIn); + pIn.Close(); + + if (!AreEqual(bytes, Data)) + { + Fail("compression test failed"); + } + } + + public override string Name + { + get { return "PGPCompressionTest"; } + } + + public static void Main( + string[] args) + { + RunTest(new PgpCompressionTest()); + } + } +} diff --git a/crypto/test/src/openpgp/test/PGPDSAElGamalTest.cs b/crypto/test/src/openpgp/test/PGPDSAElGamalTest.cs new file mode 100644 index 000000000..b86324954 --- /dev/null +++ b/crypto/test/src/openpgp/test/PGPDSAElGamalTest.cs @@ -0,0 +1,492 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpDsaElGamalTest + : SimpleTest + { + private static readonly byte[] testPubKeyRing = Base64.Decode( + "mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + + "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv" + + "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH" + + "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK" + + "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2" + + "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH" + + "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB" + + "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2" + + "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN" + + "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+" + + "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC" + + "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk" + + "JVCXP0/Szm05GB+WN+MOCT2wAgAA"); + + private static readonly byte[] testPrivKeyRing = Base64.Decode( + "lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba" + + "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX" + + "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8" + + "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc" + + "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi" + + "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH" + + "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t" + + "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc" + + "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf" + + "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r" + + "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF" + + "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn" + + "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn" + + "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r" + + "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj" + + "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya" + + "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF" + + "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq" + + "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk" + + "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs" + + "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs" + + "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA" + + "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg" + + "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA"); + + private static readonly byte[] encMessage = Base64.Decode( + "hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c" + + "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o" + + "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv" + + "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f" + + "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy" + + "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL" + + "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp" + + "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw=="); + + private static readonly byte[] signedAndEncMessage = Base64.Decode( + "hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn" + + "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy" + + "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C" + + "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T" + + "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum" + + "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK" + + "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3" + + "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm" + + "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht" + + "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM="); + + private static readonly char[] pass = "hello world".ToCharArray(); + + private static readonly SecureRandom random = new SecureRandom(); + + public override void PerformTest() + { + PgpPublicKey pubKey = null; + + // + // Read the public key + // + PgpObjectFactory pgpFact = new PgpObjectFactory(testPubKeyRing); + PgpPublicKeyRing pgpPub = (PgpPublicKeyRing)pgpFact.NextPgpObject(); + + pubKey = pgpPub.GetPublicKey(); + + if (pubKey.BitStrength != 1024) + { + Fail("failed - key strength reported incorrectly."); + } + + // + // Read the private key + // + PgpSecretKeyRing sKey = new PgpSecretKeyRing(testPrivKeyRing); + PgpSecretKey secretKey = sKey.GetSecretKey(); + PgpPrivateKey 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; + AsymmetricKeyParameter 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); + PgpPublicKey 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 + // + BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); + BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); + + ElGamalParameters elParams = new ElGamalParameters(p, g); + + IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("ELGAMAL"); + kpg.Init(new ElGamalKeyGenerationParameters(random, elParams)); + + AsymmetricCipherKeyPair 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."); +// } + } + } + } + + public override string Name + { + get { return "PGPDSAElGamalTest"; } + } + + public static void Main( + string[] args) + { + RunTest(new PgpDsaElGamalTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/openpgp/test/PGPDSATest.cs b/crypto/test/src/openpgp/test/PGPDSATest.cs new file mode 100644 index 000000000..7808ed6cd --- /dev/null +++ b/crypto/test/src/openpgp/test/PGPDSATest.cs @@ -0,0 +1,597 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpDsaTest + : SimpleTest + { + private static readonly byte[] testPubKey = Base64.Decode( + "mQGiBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbLQzRXJpYyBFY2hp" + + "ZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExEC" + + "ABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j9enEyjRDAlwAn2rrom0s" + + "MhufWK5vIRwg7gj5qsLEAJ4vnT5dPBVblofsG+pDoCVeJXGGng=="); + + private static readonly byte[] testPrivKey = Base64.Decode( + "lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC" + + "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu" + + "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh" + + "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j" + + "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD" + + "4nXkHg=="); + + private static readonly byte[] testPrivKey2 = Base64.Decode( + "lQHhBEAnoewRBADRvKgDhbV6pMzqYfUgBsLxSHzmycpuxGbjMrpyKHDOEemj" + + "iQb6TyyBKUoR28/pfshFP9R5urtKIT7wjVrDuOkxYkgRhNm+xmPXW2Lw3D++" + + "MQrC5VWe8ywBltz6T9msmChsaKo2hDhIiRI/mg9Q6rH9pJKtVGi4R7CgGxM2" + + "STQ5fwCgub38qGS1W2O4hUsa+3gva5gaNZUEAItegda4/H4t88XdWxW3D8pv" + + "RnFz26/ADdImVaQlBoumD15VmcgYoT1Djizey7X8vfV+pntudESzLbn3GHlI" + + "6C09seH4e8eYP63t7KU/qbUCDomlSswd1OgQ/RxfN86q765K2t3K1i3wDSxe" + + "EgSRyGKee0VNvOBFOFhuWt+patXaBADE1riNkUxg2P4lBNWwu8tEZRmsl/Ys" + + "DBIzXBshoMzZCvS5PnNXMW4G3SAaC9OC9jvKSx9IEWhKjfjs3QcWzXR28mcm" + + "5na0bTxeOMlaPPhBdkTCmFl0IITWlH/pFlR2ah9WYoWYhZEL2tqB82wByzxH" + + "SkSeD9V5oeSCdCcqiqkEmv4DAwLeNsQ2XGJVRmA4lld+CR5vRxpT/+/2xklp" + + "lxVf/nx0+thrHDpro3u/nINIIObk0gh59+zaEEe3APlHqbQVYWFhIGJiYiA8" + + "Y2NjQGRkZC5lZWU+iFoEExECABoFAkAnoewFCwcDAgEDFQIDAxYCAQIeAQIX" + + "gAAKCRA5nBpCS63az85BAKCbPfU8ATrFvkXhzGNGlc1BJo6DWQCgnK125xVK" + + "lWLpt6ZJJ7TXcx3nkm6wAgAAnQFXBEAnoe0QBACsQxPvaeBcv2TkbgU/5Wc/" + + "tO222dPE1mxFbXjGTKfb+6ge96iyD8kTRLrKCkEEeVBa8AZqMSoXUVN6tV8j" + + "/zD8Bc76o5iJ6wgpg3Mmy2GxInVfsfZN6/G3Y2ukmouz+CDNvQdUw8cTguIb" + + "QoV3XhQ03MLbfVmNcHsku9F4CuKNWwADBQP0DSSe8v5PXF9CSCXOIxBDcQ5x" + + "RKjyYOveqoH/4lbOV0YNUbIDZq4RaUdotpADuPREFmWf0zTB6KV/WIiag8XU" + + "WU9zdDvLKR483Bo6Do5pDBcN+NqfQ+ntGY9WJ7BSFnhQ3+07i1K+NsfFTRfv" + + "hf9X3MP75rCf7MxAIWHTabEmUf4DAwLeNsQ2XGJVRmA8DssBUCghogG9n8T3" + + "qfBeKsplGyCcF+JjPeQXkKQaoYGJ0aJz36qFP9d8DuWtT9soQcqIxVf6mTa8" + + "kN1594hGBBgRAgAGBQJAJ6HtAAoJEDmcGkJLrdrPpMkAnRyjQSKugz0YJqOB" + + "yGasMLQLxd2OAKCEIlhtCarlufVQNGZsuWxHVbU8crACAAA="); + + private static readonly byte[] sig1 = Base64.Decode( + "owGbwMvMwCR4VvnryyOnTJwZ10gncZSkFpfolVSU2Ltz78hIzcnJVyjPL8pJUeTq" + + "sGdmZQCJwpQLMq3ayTA/0Fj3xf4jbwPfK/H3zj55Z9L1n2k/GOapKJrvMZ4tLiCW" + + "GtP/XeDqX4fORDUA"); + + private static readonly byte[] sig1crc = Base64.Decode("OZa/"); + + private static readonly byte[] testPubWithUserAttr = Base64.Decode( + "mQGiBD2Rqv0RBADqKCkhVEtB/lEEr/9CubuHEy2oN/yU5j+2GXSdcNdVnRI/rwFy" + + "fHEQIk3uU7zHSUKFrC59yDm0sODYyjEdE3BVb0xvEJ5LE/OdndcIMXT1DungZ1vB" + + "zIK/3lr33W/PHixYxv9jduH3WrTehBpiKkgMZp8XloSFj2Cnw9LDyfqB7QCg/8K1" + + "o2k75NkOd9ZjnA9ye7Ri3bEEAKyr61Mo7viPWBK1joWAEsxG0OBWM+iSlG7kwh31" + + "8efgC/7Os6x4Y0jzs8mpcbBjeZtZjS9lRbfp7RinhF269xL0TZ3JxIdtaAV/6yDQ" + + "9NXfZY9dskN++HIR/5GCEEgq/qTJZt6ti5k7aV19ZFfO6wiK3NUy08wOrVsdOkVE" + + "w9IcBADaplhpcel3201uU3OCboogJtw81R5MJMZ4Y9cKL/ca2jGISn0nA7KrAw9v" + + "ShheSixGO4BV9JECkLEbtg7i+W/j/De6S+x2GLNcphuTP3UmgtKbhs0ItRqzW561" + + "s6gLkqi6aWmgaFLd8E1pMJcd9DSY95P13EYB9VJIUxFNUopzo7QcUmFsZiBIYXVz" + + "ZXIgPGhhdXNlckBhY20ub3JnPokAWAQQEQIAGAUCPZGq/QgLAwkIBwIBCgIZAQUb" + + "AwAAAAAKCRAqIBiOh4JvOKg4AJ9j14yygOqqzqiLKeaasIzqT8LCIgCggx14WuLO" + + "wOUTUswTaVKMFnU7tseJAJwEEAECAAYFAj2Rqx8ACgkQ9aWTKMpUDFV+9QP/RiWT" + + "5FAF5Rgb7beaApsgXsME+Pw7HEYFtqGa6VcXEpbcUXO6rjaXsgMgY90klWlWCF1T" + + "HOyKITvj2FdhE+0j8NQn4vaGpiTwORW/zMf/BZ0abdSWQybp10Yjs8gXw30UheO+" + + "F1E524MC+s2AeUi2hwHMiS+AVYd4WhxWHmWuBpTRypP/AAALTgEQAAEBAAAAAQAA" + + "AAABAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQ" + + "Dg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/" + + "2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7" + + "Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCABqAF0DASIAAhEBAxEB/8QAHwAAAQUB" + + "AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQID" + + "AAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0" + + "NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT" + + "lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl" + + "5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL" + + "/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB" + + "CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpj" + + "ZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3" + + "uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR" + + "AxEAPwD2aiiq9xcxWsRllcKqjOT06E/0oAsVm6jrmm6VGXvLuOPGflz8x+grzXxV" + + "8U51u5LXRgBGowZHXknnkc9OQcV51caneXdw9xPOXlckl2AJHY4J6cD1oA9J1z4p" + + "TRkrYQhRyQ0hIY5/2QRx7k9ulczN8SvEEshdZkX0UorDrznI759a5Mksckkknqec" + + "mkoA7WD4oavEoEttbTepYEZ+mCMVv6H8SLTULhbe/gFozAYkD5Unp3Ax/kV5XRQB" + + "9EAhgCDkHkEcgilryTwd4zn0m4WzvpTJZSMBuY5MfbueletKyugZWDKwyCOc/j3o" + + "AduyWLDeWB5Ynj8jSUUUAdFXn/xU15dO0RbGGYC5uWwUB6L1Jx+n413F1cJa2stz" + + "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" + + "7DGrzw=="); + + private static readonly byte[] aesSecretKey = Base64.Decode( + "lQHpBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" + + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" + + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" + + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" + + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" + + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" + + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" + + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" + + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" + + "jTxKmrLYnZz5w5qyVpvRyv4JAwKyWlhdblPudWBFXNkW5ydKn0AV2f51wEtj" + + "Zy0aLIeutVMSJf1ytLqjFqrnFe6pdJrHO3G00TE8OuFhftWosLGLbEGytDtF" + + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gQUVTMjU2KSA8ZXJpY0Bib3Vu" + + "Y3ljYXN0bGUub3JnPohZBBMRAgAZBQJAUnSGBAsHAwIDFQIDAxYCAQIeAQIX" + + "gAAKCRBYt1NnUiCgeFKaAKCiqtOO+NQES1gJW6XuOGmSkXt8bQCfcuW7SXZH" + + "zxK1FfdcG2HEDs3YEVawAgAA"); + + private static readonly byte[] aesPublicKey = Base64.Decode( + "mQGiBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN" + + "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj" + + "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA" + + "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo" + + "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5" + + "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN" + + "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X" + + "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF" + + "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV" + + "jTxKmrLYnZz5w5qyVpvRyrQ7RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" + + "IEFFUzI1NikgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ0" + + "hgQLBwMCAxUCAwMWAgECHgECF4AACgkQWLdTZ1IgoHhSmgCfU83BLBF2nCua" + + "zk2dXB9zO1l6XS8AnA07U4cq5W0GrKM6/kP9HWtPhgOFsAIAAA=="); + + private static readonly byte[] twofishSecretKey = Base64.Decode( + "lQHpBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" + + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" + + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" + + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" + + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" + + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" + + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" + + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" + + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" + + "KJs01YT3L6f0iIj03hCeV/4KAwLcGrxT3X0qR2CZyZYSVBdjXeNYKXuGBtOf" + + "ood26WOtwLw4+l9sHVoiXNv0LomkO58ndJRPGCeZWZEDMVrfkS7rcOlktDxF" + + "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gdHdvZmlzaCkgPGVyaWNAYm91" + + "bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ20gQLBwMCAxUCAwMWAgECHgEC" + + "F4AACgkQaCCMaHh9zR2+RQCghcQwlt4B4YmNxp2b3v6rP3E8M0kAn2Gspi4u" + + "A/ynoqnC1O8HNlbjPdlVsAIAAA=="); + + private static readonly byte[] twofishPublicKey = Base64.Decode( + "mQGiBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc" + + "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8" + + "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p" + + "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/" + + "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2" + + "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG" + + "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK" + + "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v" + + "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj" + + "KJs01YT3L6f0iIj03hCeV7Q8RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt" + + "IHR3b2Zpc2gpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkFAkBS" + + "dtIECwcDAgMVAgMDFgIBAh4BAheAAAoJEGggjGh4fc0dvkUAn2QGdNk8Wrrd" + + "+DvKECrO5+yoPRx3AJ91DhCMme6uMrQorKSDYxHlgc7iT7ACAAA="); + + private static readonly char[] pass = "hello world".ToCharArray(); + + /** + * Generated signature test + * + * @param sKey + * @param pgpPrivKey + * @return test result + */ + public void GenerateTest( + PgpSecretKeyRing sKey, + PgpPublicKey pgpPubKey, + PgpPrivateKey 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() + { + PgpPublicKey pubKey = null; + + // + // Read the public key + // + PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey); + + pubKey = pgpPub.GetPublicKey(); + + // + // Read the private key + // + PgpSecretKeyRing sKey = new PgpSecretKeyRing(testPrivKey); + PgpSecretKey secretKey = sKey.GetSecretKey(); + PgpPrivateKey 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); + + + AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); + + PgpKeyPair pgpKp = new PgpKeyPair(PublicKeyAlgorithmTag.Dsa, + kp.Public, kp.Private, DateTime.UtcNow); + + PgpPublicKey k1 = pgpKp.PublicKey; + PgpPrivateKey k2 = pgpKp.PrivateKey; + } + + public override string Name + { + get { return "PGPDSATest"; } + } + + public static void Main( + string[] args) + { + RunTest(new PgpDsaTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/openpgp/test/PGPPBETest.cs b/crypto/test/src/openpgp/test/PGPPBETest.cs new file mode 100644 index 000000000..621cef684 --- /dev/null +++ b/crypto/test/src/openpgp/test/PGPPBETest.cs @@ -0,0 +1,384 @@ +using System; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpPbeTest + : SimpleTest + { + private static readonly DateTime TestDateTime = new DateTime(2003, 8, 29, 23, 35, 11, 0); + + private static readonly byte[] enc1 = Base64.Decode( + "jA0EAwMC5M5wWBP2HBZgySvUwWFAmMRLn7dWiZN6AkQMvpE3b6qwN3SSun7zInw2" + + "hxxdgFzVGfbjuB8w"); +// private static readonly byte[] enc1crc = Base64.Decode("H66L"); + private static readonly char[] pass = "hello world".ToCharArray(); + + /** + * Message with both PBE and symmetric + */ + private static readonly byte[] testPBEAsym = Base64.Decode( + "hQIOA/ZlQEFWB5vuEAf/covEUaBve7NlWWdiO5NZubdtTHGElEXzG9hyBycp9At8" + + "nZGi27xOZtEGFQo7pfz4JySRc3O0s6w7PpjJSonFJyNSxuze2LuqRwFWBYYcbS8/" + + "7YcjB6PqutrT939OWsozfNqivI9/QyZCjBvFU89pp7dtUngiZ6MVv81ds2I+vcvk" + + "GlIFcxcE1XoCIB3EvbqWNaoOotgEPT60unnB2BeDV1KD3lDRouMIYHfZ3SzBwOOI" + + "6aK39sWnY5sAK7JjFvnDAMBdueOiI0Fy+gxbFD/zFDt4cWAVSAGTC4w371iqppmT" + + "25TM7zAtCgpiq5IsELPlUZZnXKmnYQ7OCeysF0eeVwf+OFB9fyvCEv/zVQocJCg8" + + "fWxfCBlIVFNeNQpeGygn/ZmRaILvB7IXDWP0oOw7/F2Ym66IdYYIp2HeEZv+jFwa" + + "l41w5W4BH/gtbwGjFQ6CvF/m+lfUv6ZZdzsMIeEOwhP5g7rXBxrbcnGBaU+PXbho" + + "gjDqaYzAWGlrmAd6aPSj51AGeYXkb2T1T/yoJ++M3GvhH4C4hvitamDkksh/qRnM" + + "M/s8Nku6z1+RXO3M6p5QC1nlAVqieU8esT43945eSoC77K8WyujDNbysDyUCUTzt" + + "p/aoQwe/HgkeOTJNelKR9y2W3xinZLFzep0SqpNI/e468yB/2/LGsykIyQa7JX6r" + + "BYwuBAIDAkOKfv5rK8v0YDfnN+eFqwhTcrfBj5rDH7hER6nW3lNWcMataUiHEaMg" + + "o6Q0OO1vptIGxW8jClTD4N1sCNwNu9vKny8dKYDDHbCjE06DNTv7XYVW3+JqTL5E" + + "BnidvGgOmA=="); + + /** + * decrypt the passed in message stream + */ + private byte[] DecryptMessage( + byte[] message) + { + PgpObjectFactory pgpF = new PgpObjectFactory(message); + PgpEncryptedDataList enc = (PgpEncryptedDataList) pgpF.NextPgpObject(); + PgpPbeEncryptedData pbe = (PgpPbeEncryptedData) enc[0]; + Stream clear = pbe.GetDataStream(pass); + + PgpObjectFactory pgpFact = new PgpObjectFactory(clear); + PgpCompressedData cData = (PgpCompressedData) pgpFact.NextPgpObject(); + pgpFact = new PgpObjectFactory(cData.GetDataStream()); + + PgpLiteralData ld = (PgpLiteralData) pgpFact.NextPgpObject(); + + if (!ld.FileName.Equals("test.txt") + && !ld.FileName.Equals("_CONSOLE")) + { + Fail("wrong filename in packet"); + } + + if (!ld.ModificationTime.Equals(TestDateTime)) + { + Fail("wrong modification time in packet: " + ld.ModificationTime + " vs " + TestDateTime); + } + + Stream unc = ld.GetInputStream(); + byte[] bytes = Streams.ReadAll(unc); + + if (pbe.IsIntegrityProtected() && !pbe.Verify()) + { + Fail("integrity check failed"); + } + + return bytes; + } + + private byte[] DecryptMessageBuffered( + byte[] message) + { + PgpObjectFactory pgpF = new PgpObjectFactory(message); + PgpEncryptedDataList enc = (PgpEncryptedDataList) pgpF.NextPgpObject(); + PgpPbeEncryptedData pbe = (PgpPbeEncryptedData) enc[0]; + + Stream clear = pbe.GetDataStream(pass); + + PgpObjectFactory pgpFact = new PgpObjectFactory(clear); + PgpCompressedData cData = (PgpCompressedData) pgpFact.NextPgpObject(); + + pgpFact = new PgpObjectFactory(cData.GetDataStream()); + + PgpLiteralData ld = (PgpLiteralData) pgpFact.NextPgpObject(); + + MemoryStream bOut = new MemoryStream(); + if (!ld.FileName.Equals("test.txt") + && !ld.FileName.Equals("_CONSOLE")) + { + Fail("wrong filename in packet"); + } + if (!ld.ModificationTime.Equals(TestDateTime)) + { + Fail("wrong modification time in packet: " + ld.ModificationTime.Ticks + " " + TestDateTime.Ticks); + } + + Stream unc = ld.GetInputStream(); + byte[] buf = new byte[1024]; + + int len; + while ((len = unc.Read(buf, 0, buf.Length)) > 0) + { + bOut.Write(buf, 0, len); + } + + if (pbe.IsIntegrityProtected() && !pbe.Verify()) + { + Fail("integrity check failed"); + } + + return bOut.ToArray(); + } + + public override void PerformTest() + { + byte[] data = DecryptMessage(enc1); + if (data[0] != 'h' || data[1] != 'e' || data[2] != 'l') + { + Fail("wrong plain text in packet"); + } + + // + // create a PBE encrypted message and read it back. + // + byte[] text = Encoding.ASCII.GetBytes("hello world!\n"); + + // + // encryption step - convert to literal data, compress, encode. + // + MemoryStream bOut = new UncloseableMemoryStream(); + + PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator( + CompressionAlgorithmTag.Zip); + + PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator(); + Stream comOut = comData.Open(new UncloseableStream(bOut)); + Stream ldOut = lData.Open( + new UncloseableStream(comOut), + PgpLiteralData.Binary, + PgpLiteralData.Console, + text.Length, + TestDateTime); + + ldOut.Write(text, 0, text.Length); + ldOut.Close(); + + comOut.Close(); + + // + // encrypt - with stream close + // + MemoryStream cbOut = new UncloseableMemoryStream(); + PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag.Cast5, new SecureRandom()); + + cPk.AddMethod(pass); + + byte[] bOutData = bOut.ToArray(); + Stream cOut = cPk.Open(new UncloseableStream(cbOut), bOutData.Length); + cOut.Write(bOutData, 0, bOutData.Length); + cOut.Close(); + + data = DecryptMessage(cbOut.ToArray()); + if (!Arrays.AreEqual(data, text)) + { + Fail("wrong plain text in generated packet"); + } + + // + // encrypt - with generator close + // + cbOut = new UncloseableMemoryStream(); + cPk = new PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag.Cast5, new SecureRandom()); + + cPk.AddMethod(pass); + + bOutData = bOut.ToArray(); + cOut = cPk.Open(new UncloseableStream(cbOut), bOutData.Length); + cOut.Write(bOutData, 0, bOutData.Length); + + cPk.Close(); + + data = DecryptMessage(cbOut.ToArray()); + + if (!AreEqual(data, text)) + { + Fail("wrong plain text in generated packet"); + } + + // + // encrypt - partial packet style. + // + SecureRandom rand = new SecureRandom(); + byte[] test = new byte[1233]; + + rand.NextBytes(test); + + bOut = new UncloseableMemoryStream(); + + comData = new PgpCompressedDataGenerator( + CompressionAlgorithmTag.Zip); + comOut = comData.Open(new UncloseableStream(bOut)); + + lData = new PgpLiteralDataGenerator(); + ldOut = lData.Open( + new UncloseableStream(comOut), + PgpLiteralData.Binary, + PgpLiteralData.Console, + TestDateTime, + new byte[16]); + + ldOut.Write(test, 0, test.Length); + lData.Close(); + + comData.Close(); + cbOut = new UncloseableMemoryStream(); + cPk = new PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag.Cast5, rand); + + cPk.AddMethod(pass); + + cOut = cPk.Open(new UncloseableStream(cbOut), new byte[16]); + { + byte[] tmp = bOut.ToArray(); + cOut.Write(tmp, 0, tmp.Length); + } + + cPk.Close(); + + data = DecryptMessage(cbOut.ToArray()); + if (!Arrays.AreEqual(data, test)) + { + Fail("wrong plain text in generated packet"); + } + + // + // with integrity packet + // + cbOut = new UncloseableMemoryStream(); + cPk = new PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag.Cast5, true, rand); + + cPk.AddMethod(pass); + + cOut = cPk.Open(new UncloseableStream(cbOut), new byte[16]); + bOutData = bOut.ToArray(); + cOut.Write(bOutData, 0, bOutData.Length); + cPk.Close(); + + data = DecryptMessage(cbOut.ToArray()); + if (!Arrays.AreEqual(data, test)) + { + Fail("wrong plain text in generated packet"); + } + + // + // decrypt with buffering + // + data = DecryptMessageBuffered(cbOut.ToArray()); + if (!AreEqual(data, test)) + { + Fail("wrong plain text in buffer generated packet"); + } + + // + // sample message + // + PgpObjectFactory pgpFact = new PgpObjectFactory(testPBEAsym); + + PgpEncryptedDataList enc = (PgpEncryptedDataList)pgpFact.NextPgpObject(); + + PgpPbeEncryptedData pbe = (PgpPbeEncryptedData) enc[1]; + + Stream clear = pbe.GetDataStream("password".ToCharArray()); + + pgpFact = new PgpObjectFactory(clear); + + PgpLiteralData ld = (PgpLiteralData) pgpFact.NextPgpObject(); + + Stream unc = ld.GetInputStream(); + byte[] bytes = Streams.ReadAll(unc); + + if (!AreEqual(bytes, Hex.Decode("5361742031302e30322e30370d0a"))) + { + Fail("data mismatch on combined PBE"); + } + + // + // with integrity packet - one byte message + // + byte[] msg = new byte[1]; + bOut = new MemoryStream(); + + comData = new PgpCompressedDataGenerator( + CompressionAlgorithmTag.Zip); + + lData = new PgpLiteralDataGenerator(); + comOut = comData.Open(new UncloseableStream(bOut)); + ldOut = lData.Open( + new UncloseableStream(comOut), + PgpLiteralData.Binary, + PgpLiteralData.Console, + msg.Length, + TestDateTime); + + ldOut.Write(msg, 0, msg.Length); + + ldOut.Close(); + + comOut.Close(); + + cbOut = new MemoryStream(); + cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, true, rand); + + cPk.AddMethod(pass); + + cOut = cPk.Open(new UncloseableStream(cbOut), new byte[16]); + + data = bOut.ToArray(); + cOut.Write(data, 0, data.Length); + + cOut.Close(); + + data = DecryptMessage(cbOut.ToArray()); + if (!AreEqual(data, msg)) + { + Fail("wrong plain text in generated packet"); + } + + // + // decrypt with buffering + // + data = DecryptMessageBuffered(cbOut.ToArray()); + if (!AreEqual(data, msg)) + { + Fail("wrong plain text in buffer generated packet"); + } + } + + private class UncloseableMemoryStream + : MemoryStream + { + public override void Close() + { + throw new Exception("Close() called on underlying stream"); + } + } + + public override string Name + { + get { return "PGPPBETest"; } + } + + public static void Main( + string[] args) + { + RunTest(new PgpPbeTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/openpgp/test/PGPPacketTest.cs b/crypto/test/src/openpgp/test/PGPPacketTest.cs new file mode 100644 index 000000000..b82f8526f --- /dev/null +++ b/crypto/test/src/openpgp/test/PGPPacketTest.cs @@ -0,0 +1,80 @@ +using System; +using System.IO; + +using NUnit.Framework; + +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpPacketTest + : SimpleTest + { + private static int MAX = 32000; + + private void ReadBackTest( + PgpLiteralDataGenerator generator) + { + Random rand = new Random(); + byte[] buf = new byte[MAX]; + + rand.NextBytes(buf); + + for (int i = 1; i != MAX; i++) + { + MemoryStream bOut = new MemoryStream(); + + Stream outputStream = generator.Open( + new UncloseableStream(bOut), + PgpLiteralData.Binary, + PgpLiteralData.Console, + i, + DateTime.UtcNow); + + outputStream.Write(buf, 0, i); + + generator.Close(); + + PgpObjectFactory fact = new PgpObjectFactory(bOut.ToArray()); + + PgpLiteralData data = (PgpLiteralData)fact.NextPgpObject(); + + Stream inputStream = data.GetInputStream(); + + for (int count = 0; count != i; count++) + { + if (inputStream.ReadByte() != (buf[count] & 0xff)) + { + Fail("failed readback test - length = " + i); + } + } + } + } + + public override void PerformTest() + { + ReadBackTest(new PgpLiteralDataGenerator(true)); + ReadBackTest(new PgpLiteralDataGenerator(false)); + } + + public override string Name + { + get { return "PGPPacketTest"; } + } + + public static void Main( + string[] args) + { + RunTest(new PgpPacketTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/openpgp/test/PGPRSATest.cs b/crypto/test/src/openpgp/test/PGPRSATest.cs new file mode 100644 index 000000000..f38aa002f --- /dev/null +++ b/crypto/test/src/openpgp/test/PGPRSATest.cs @@ -0,0 +1,1235 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Bcpg.Attr; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpRsaTest + : SimpleTest + { + private static readonly byte[] testPubKey = Base64.Decode( + "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F" + + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" + + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" + + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" + + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" + + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" + + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" + + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA=="); + + private static readonly byte[] testPrivKey = Base64.Decode( + "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP" + + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" + + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" + + "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990" + + "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw" + + "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw" + + "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb" + + "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY" + + "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF" + + "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO" + + "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0" + + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" + + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" + + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" + + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" + + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w="); + + private static readonly byte[] testPubKeyV3 = Base64.Decode( + "mQCNAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + + "wdi2fBUJAAURtApGSVhDSVRZX1FBiQCVAwUQP7O+UZ6Fwdi2fBUJAQFMwwQA" + + "qRnFsdg4xQnB8Y5d4cOpXkIn9AZgYS3cxtuSJB84vG2CgC39nfv4c+nlLkWP" + + "4puG+mZuJNgVoE84cuAF4I//1anKjlU7q1M6rFQnt5S4uxPyG3dFXmgyU1b4" + + "PBOnA0tIxjPzlIhJAMsPCGGA5+5M2JP0ad6RnzqzE3EENMX+GqY="); + + private static readonly byte[] testPrivKeyV3 = Base64.Decode( + "lQHfAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + + "wdi2fBUJAAURAXWwRBZQHNikA/f0ScLLjrXi4s0hgQecg+dkpDow94eu5+AR" + + "0DzZnfurpgfUJCNiDi5W/5c3Zj/xyrfMAgkbCgJ1m6FZqAQh7Mq73l7Kfu4/" + + "XIkyDF3tDgRuZNezB+JuElX10tV03xumHepp6M6CfhXqNJ15F33F99TA5hXY" + + "CPYD7SiSOpIhQkCOAgDAA63imxbpuKE2W7Y4I1BUHB7WQi8ZdkZd04njNTv+" + + "rFUuOPapQVfbWG0Vq8ld3YmJB4QWsa2mmqn+qToXbwufAgBpXkjvqK5yPiHF" + + "Px2QbFc1VqoCJB6PO5JRIqEiUZBFGdDlLxt3VSyqz7IZ/zEnxZq+tPCGGGSm" + + "/sAGiMvENcHVAfy0kTXU42TxEAYJyyNyqjXOobDJpEV1mKhFskRXt7tbMfOS" + + "Yf91oX8f6xw6O2Nal+hU8dS0Bmfmk5/enHmvRLHQocO0CkZJWENJVFlfUUE="); + + private static readonly byte[] sig1 = Base64.Decode( + "owGbwMvMwMRoGpHo9vfz52LGNTJJnBmpOTn5eiUVJfb23JvAHIXy/KKcFEWuToap" + + "zKwMIGG4Bqav0SwMy3yParsEKi2LMGI9xhh65sBxb05n5++ZLcWNJ/eLFKdWbm95" + + "tHbDV7GMwj/tUctUpFUXWPYFCLdNsDiVNuXbQvZtdXV/5xzY+9w1nCnijH9JoNiJ" + + "22n2jo0zo30/TZLo+jDl2vTzIvPeLEsPM3ZUE/1Ytqs4SG2TxIQbH7xf3uzcYXq2" + + "5Fw9AA=="); + +// private static readonly byte[] sig1crc = Base64.Decode("+3i0"); + + private static readonly byte[] subKey = Base64.Decode( + "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" + + "CphiUYWnsC0mQ+J15B4="); + + private static readonly byte[] enc1 = Base64.Decode( + "hIwDKwfQexPJboABA/4/7prhYYMORTiQ5avQKx0XYpCLujzGefYjnyuWZnx3Iev8" + + "Pmsguumm+OLLvtXhhkXQmkJRXbIg6Otj2ubPYWflRPgpJSgOrNOreOl5jeABOrtw" + + "bV6TJb9OTtZuB7cTQSCq2gmYiSZkluIiDjNs3R3mEanILbYzOQ3zKSggKpzlv9JQ" + + "AZUqTyDyJ6/OUbJF5fI5uiv76DCsw1zyMWotUIu5/X01q+AVP5Ly3STzI7xkWg/J" + + "APz4zUHism7kSYz2viAQaJx9/bNnH3AM6qm1Fuyikl4="); + +// private static readonly byte[] enc1crc = Base64.Decode("lv4o"); + +// private static readonly byte[] enc2 = Base64.Decode( +// "hIwDKwfQexPJboABBAC62jcJH8xKnKb1neDVmiovYON04+7VQ2v4BmeHwJrdag1g" +// + "Ya++6PeBlQ2Q9lSGBwLobVuJmQ7cOnPUJP727JeSGWlMyFtMbBSHekOaTenT5lj7" +// + "Zk7oRHxMp/hByzlMacIDzOn8LPSh515RHM57eDLCOwqnAxGQwk67GRl8f5dFH9JQ" +// + "Aa7xx8rjCqPbiIQW6t5LqCNvPZOiSCmftll6+se1XJhFEuq8WS4nXtPfTiJ3vib4" +// + "3soJdHzGB6AOs+BQ6aKmmNTVAxa5owhtSt1Z/6dfSSk="); + + private static readonly byte[] subPubKey = Base64.Decode( + "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"); + +// private static readonly byte[] subPubCrc = Base64.Decode("rikt"); + + private static readonly byte[] pgp8Key = Base64.Decode( + "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF" + + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" + + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" + + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" + + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" + + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" + + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" + + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" + + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" + + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" + + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" + + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" + + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" + + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" + + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" + + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" + + "AgAA"); + + private static readonly char[] pgp8Pass = "2002 Buffalo Sabres".ToCharArray(); + + private static readonly char[] pass = "hello world".ToCharArray(); + + private static readonly byte[] fingerprintKey = Base64.Decode( + "mQEPA0CiJdUAAAEIAMI+znDlPd2kQoEcnxqxLcRz56Z7ttFKHpnYp0UkljZdquVc" + + "By1jMfXGVV64xN1IvMcyenLXUE0IUeUBCQs6tHunFRAPSeCxJ3FdFe1B5MpqQG8A" + + "BnEpAds/hAUfRDZD5y/lolk1hjvFMrRh6WXckaA/QQ2t00NmTrJ1pYUpkw9tnVQb" + + "LUjWJhfZDBBcN0ADtATzgkugxMtcDxR6I5x8Ndn+IilqIm23kxGIcmMd/BHOec4c" + + "jRwJXXDb7u8tl+2knAf9cwhPHp3+Zy4uGSQPdzQnXOhBlA+4WDa0RROOevWgq8uq" + + "8/9Xp/OlTVL+OoIzjsI6mJP1Joa4qmqAnaHAmXcAEQEAAbQoQk9BM1JTS1kgPEJP" + + "QSBNb25pdG9yaW5nIEAgODg4LTI2OS01MjY2PokBFQMFEECiJdWqaoCdocCZdwEB" + + "0RsH/3HPxoUZ3G3K7T3jgOnJUckTSHWU3XspHzMVgqOxjTrcexi5IsAM5M+BulfW" + + "T2aO+Kqf5w8cKTKgW02DNpHUiPjHx0nzDE+Do95zbIErGeK+Twkc4O/aVsvU9GGO" + + "81VFI6WMvDQ4CUAUnAdk03MRrzI2nAuhn4NJ5LQS+uJrnqUJ4HmFAz6CQZQKd/kS" + + "Xgq+A6i7aI1LG80YxWa9ooQgaCrb9dwY/kPQ+yC22zQ3FExtv+Fv3VtAKTilO3vn" + + "BA4Y9uTHuObHfI+1yxUS2PrlRUX0m48ZjpIX+cEN3QblGBJudI/A1QSd6P0LZeBr" + + "7F1Z1aF7ZDo0KzgiAIBvgXkeTpw="); + +// private static readonly byte[] fingerprintCheck = Base64.Decode("CTv2"); + + private static readonly byte[] jpegImage = Base64.Decode( + "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"); + + private static readonly byte[] embeddedJPEGKey = Base64.Decode( + "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" + + "Qvmtc8X7lqK/zLRVkSSBItik2IIhsAIAAw=="); + + private void FingerPrintTest() + { + // + // version 3 + // + PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(fingerprintKey); + + PgpPublicKey pubKey = pgpPub.GetPublicKey(); + + if (!Arrays.AreEqual(pubKey.GetFingerprint(), Hex.Decode("4FFB9F0884266C715D1CEAC804A3BBFA"))) + { + Fail("version 3 fingerprint test failed"); + } + + // + // version 4 + // + pgpPub = new PgpPublicKeyRing(testPubKey); + + pubKey = pgpPub.GetPublicKey(); + + if (!Arrays.AreEqual(pubKey.GetFingerprint(), Hex.Decode("3062363c1046a01a751946bb35586146fdf3f373"))) + { + Fail("version 4 fingerprint test failed"); + } + } + + private void MixedTest( + PgpPrivateKey pgpPrivKey, + PgpPublicKey pgpPubKey) + { + byte[] text = Encoding.ASCII.GetBytes("hello world!\n"); + + // + // literal data + // + MemoryStream bOut = new MemoryStream(); + PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); + Stream lOut = lGen.Open( + bOut, + PgpLiteralData.Binary, + PgpLiteralData.Console, + text.Length, + DateTime.UtcNow); + + lOut.Write(text, 0, text.Length); + + lGen.Close(); + + byte[] bytes = bOut.ToArray(); + + PgpObjectFactory f = new PgpObjectFactory(bytes); + CheckLiteralData((PgpLiteralData)f.NextPgpObject(), text); + + MemoryStream bcOut = new MemoryStream(); + + PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag.Aes128, + true, + new SecureRandom()); + + encGen.AddMethod(pgpPubKey); + + encGen.AddMethod("password".ToCharArray()); + + Stream cOut = encGen.Open(bcOut, bytes.Length); + + cOut.Write(bytes, 0, bytes.Length); + + cOut.Close(); + + byte[] encData = bcOut.ToArray(); + + // + // asymmetric + // + PgpObjectFactory pgpF = new PgpObjectFactory(encData); + + PgpEncryptedDataList encList = (PgpEncryptedDataList) pgpF.NextPgpObject(); + + PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0]; + + Stream clear = encP.GetDataStream(pgpPrivKey); + + PgpObjectFactory pgpFact = new PgpObjectFactory(clear); + + CheckLiteralData((PgpLiteralData)pgpFact.NextPgpObject(), text); + + // + // PBE + // + pgpF = new PgpObjectFactory(encData); + + encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); + + PgpPbeEncryptedData encPbe = (PgpPbeEncryptedData) encList[1]; + + clear = encPbe.GetDataStream("password".ToCharArray()); + + pgpF = new PgpObjectFactory(clear); + + CheckLiteralData((PgpLiteralData) pgpF.NextPgpObject(), text); + } + + private void CheckLiteralData( + PgpLiteralData ld, + byte[] data) + { + if (!ld.FileName.Equals(PgpLiteralData.Console)) + throw new Exception("wrong filename in packet"); + + Stream inLd = ld.GetDataStream(); + byte[] bytes = Streams.ReadAll(inLd); + + if (!AreEqual(bytes, data)) + { + Fail("wrong plain text in decrypted packet"); + } + } + + private void ExistingEmbeddedJpegTest() + { + PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(embeddedJPEGKey); + + PgpPublicKey pubKey = pgpPub.GetPublicKey(); + + int count = 0; + foreach (PgpUserAttributeSubpacketVector attributes in pubKey.GetUserAttributes()) + { + int sigCount = 0; + foreach (PgpSignature sig in pubKey.GetSignaturesForUserAttribute(attributes)) + { + sig.InitVerify(pubKey); + + if (!sig.VerifyCertification(attributes, pubKey)) + { + Fail("signature failed verification"); + } + + sigCount++; + } + + if (sigCount != 1) + { + Fail("Failed user attributes signature check"); + } + count++; + } + + if (count != 1) + { + Fail("didn't find user attributes"); + } + } + + private void EmbeddedJpegTest() + { + PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey); + PgpSecretKeyRing pgpSec = new PgpSecretKeyRing(testPrivKey); + + PgpPublicKey pubKey = pgpPub.GetPublicKey(); + + PgpUserAttributeSubpacketVectorGenerator vGen = new PgpUserAttributeSubpacketVectorGenerator(); + + vGen.SetImageAttribute(ImageAttrib.Format.Jpeg, jpegImage); + + PgpUserAttributeSubpacketVector uVec = vGen.Generate(); + + PgpSignatureGenerator sGen = new PgpSignatureGenerator( + PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); + + sGen.InitSign(PgpSignature.PositiveCertification, pgpSec.GetSecretKey().ExtractPrivateKey(pass)); + + PgpSignature sig = sGen.GenerateCertification(uVec, pubKey); + + PgpPublicKey nKey = PgpPublicKey.AddCertification(pubKey, uVec, sig); + + int count = 0; + foreach (PgpUserAttributeSubpacketVector attributes in nKey.GetUserAttributes()) + { + int sigCount = 0; + foreach (PgpSignature s in nKey.GetSignaturesForUserAttribute(attributes)) + { + s.InitVerify(pubKey); + + if (!s.VerifyCertification(attributes, pubKey)) + { + Fail("added signature failed verification"); + } + + sigCount++; + } + + if (sigCount != 1) + { + Fail("Failed added user attributes signature check"); + } + count++; + } + + if (count != 1) + { + Fail("didn't find added user attributes"); + } + + nKey = PgpPublicKey.RemoveCertification(nKey, uVec); + + if (nKey.GetUserAttributes().GetEnumerator().MoveNext()) + { + Fail("found attributes where none expected"); + } + } + + public override void PerformTest() + { + // + // Read the public key + // + PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey); + + AsymmetricKeyParameter pubKey = pgpPub.GetPublicKey().GetKey(); + + IEnumerator enumerator = pgpPub.GetPublicKey().GetUserIds().GetEnumerator(); + enumerator.MoveNext(); + string uid = (string) enumerator.Current; + + + enumerator = pgpPub.GetPublicKey().GetSignaturesForId(uid).GetEnumerator(); + enumerator.MoveNext(); + PgpSignature sig = (PgpSignature) enumerator.Current; + + sig.InitVerify(pgpPub.GetPublicKey()); + + if (!sig.VerifyCertification(uid, pgpPub.GetPublicKey())) + { + Fail("failed to verify certification"); + } + + // + // write a public key + // + MemoryStream bOut = new UncloseableMemoryStream(); + BcpgOutputStream pOut = new BcpgOutputStream(bOut); + + pgpPub.Encode(pOut); + + if (!Arrays.AreEqual(bOut.ToArray(), testPubKey)) + { + Fail("public key rewrite failed"); + } + + // + // Read the public key + // + PgpPublicKeyRing pgpPubV3 = new PgpPublicKeyRing(testPubKeyV3); + AsymmetricKeyParameter pubKeyV3 = pgpPub.GetPublicKey().GetKey(); + + // + // write a V3 public key + // + bOut = new UncloseableMemoryStream(); + pOut = new BcpgOutputStream(bOut); + + pgpPubV3.Encode(pOut); + + // + // Read a v3 private key + // + char[] passP = "FIXCITY_QA".ToCharArray(); + +#if INCLUDE_IDEA + { + PgpSecretKeyRing pgpPriv2 = new PgpSecretKeyRing(testPrivKeyV3); + PgpSecretKey pgpPrivSecretKey = pgpPriv2.GetSecretKey(); + PgpPrivateKey pgpPrivKey2 = pgpPrivSecretKey.ExtractPrivateKey(passP); + + // + // write a v3 private key + // + bOut = new UncloseableMemoryStream(); + pOut = new BcpgOutputStream(bOut); + + pgpPriv2.Encode(pOut); + + byte[] result = bOut.ToArray(); + if (!Arrays.AreEqual(result, testPrivKeyV3)) + { + Fail("private key V3 rewrite failed"); + } + } +#endif + + // + // Read the private key + // + PgpSecretKeyRing pgpPriv = new PgpSecretKeyRing(testPrivKey); + PgpPrivateKey pgpPrivKey = pgpPriv.GetSecretKey().ExtractPrivateKey(pass); + + // + // write a private key + // + bOut = new UncloseableMemoryStream(); + pOut = new BcpgOutputStream(bOut); + + pgpPriv.Encode(pOut); + + if (!Arrays.AreEqual(bOut.ToArray(), testPrivKey)) + { + Fail("private key rewrite failed"); + } + + // + // test encryption + // + IBufferedCipher c = CipherUtilities.GetCipher("RSA"); + +// c.Init(Cipher.ENCRYPT_MODE, pubKey); + c.Init(true, pubKey); + + byte[] inBytes = Encoding.ASCII.GetBytes("hello world"); + byte[] outBytes = c.DoFinal(inBytes); + +// c.Init(Cipher.DECRYPT_MODE, pgpPrivKey.GetKey()); + c.Init(false, pgpPrivKey.Key); + + outBytes = c.DoFinal(outBytes); + + if (!Arrays.AreEqual(inBytes, outBytes)) + { + Fail("decryption failed."); + } + + // + // 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(pgpPub.GetPublicKey(ops.KeyId)); + + 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"); + } + + // + // encrypted message - read subkey + // + pgpPriv = new PgpSecretKeyRing(subKey); + + // + // encrypted message + // + byte[] text = Encoding.ASCII.GetBytes("hello world!\n"); + + PgpObjectFactory pgpF = new PgpObjectFactory(enc1); + + PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); + + PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0]; + + pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass); + + 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"); + } + + // + // encrypt - short message + // + byte[] shortText = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' }; + + MemoryStream cbOut = new UncloseableMemoryStream(); + PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, new SecureRandom()); + PgpPublicKey puK = pgpPriv.GetSecretKey(encP.KeyId).PublicKey; + + cPk.AddMethod(puK); + + Stream cOut = cPk.Open(new UncloseableStream(cbOut), shortText.Length); + + cOut.Write(shortText, 0, shortText.Length); + + cOut.Close(); + + pgpF = new PgpObjectFactory(cbOut.ToArray()); + + encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); + + encP = (PgpPublicKeyEncryptedData)encList[0]; + + pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass); + + if (encP.GetSymmetricAlgorithm(pgpPrivKey) != SymmetricKeyAlgorithmTag.Cast5) + { + Fail("symmetric algorithm mismatch"); + } + + clear = encP.GetDataStream(pgpPrivKey); + outBytes = Streams.ReadAll(clear); + + if (!Arrays.AreEqual(outBytes, shortText)) + { + Fail("wrong plain text in generated short text packet"); + } + + // + // encrypt + // + cbOut = new UncloseableMemoryStream(); + cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, new SecureRandom()); + puK = pgpPriv.GetSecretKey(encP.KeyId).PublicKey; + + cPk.AddMethod(puK); + + 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 = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass); + + clear = encP.GetDataStream(pgpPrivKey); + outBytes = Streams.ReadAll(clear); + + if (!Arrays.AreEqual(outBytes, text)) + { + Fail("wrong plain text in generated packet"); + } + + // + // read public key with sub key. + // + pgpF = new PgpObjectFactory(subPubKey); + object o; + while ((o = pgpFact.NextPgpObject()) != null) + { + // TODO Should something be tested here? + // Console.WriteLine(o); + } + + // + // key pair generation - CAST5 encryption + // + char[] passPhrase = "hello".ToCharArray(); + IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("RSA"); + RsaKeyGenerationParameters genParam = new RsaKeyGenerationParameters( + BigInteger.ValueOf(0x10001), new SecureRandom(), 1024, 25); + + kpg.Init(genParam); + + + AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); + + PgpSecretKey secretKey = new PgpSecretKey( + PgpSignature.DefaultCertification, + PublicKeyAlgorithmTag.RsaGeneral, + kp.Public, + kp.Private, + DateTime.UtcNow, + "fred", + SymmetricKeyAlgorithmTag.Cast5, + passPhrase, + null, + null, + new SecureRandom() + ); + + PgpPublicKey key = secretKey.PublicKey; + + + enumerator = key.GetUserIds().GetEnumerator(); + enumerator.MoveNext(); + uid = (string) enumerator.Current; + + + enumerator = key.GetSignaturesForId(uid).GetEnumerator(); + enumerator.MoveNext(); + sig = (PgpSignature) enumerator.Current; + + sig.InitVerify(key); + + if (!sig.VerifyCertification(uid, key)) + { + Fail("failed to verify certification"); + } + + pgpPrivKey = secretKey.ExtractPrivateKey(passPhrase); + + key = PgpPublicKey.RemoveCertification(key, uid, sig); + + if (key == null) + { + Fail("failed certification removal"); + } + + byte[] keyEnc = key.GetEncoded(); + + key = PgpPublicKey.AddCertification(key, uid, sig); + + keyEnc = key.GetEncoded(); + + PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); + + sGen.InitSign(PgpSignature.KeyRevocation, secretKey.ExtractPrivateKey(passPhrase)); + + sig = sGen.GenerateCertification(key); + + key = PgpPublicKey.AddCertification(key, sig); + + keyEnc = key.GetEncoded(); + + PgpPublicKeyRing tmpRing = new PgpPublicKeyRing(keyEnc); + + key = tmpRing.GetPublicKey(); + + IEnumerator sgEnum = key.GetSignaturesOfType(PgpSignature.KeyRevocation).GetEnumerator(); + sgEnum.MoveNext(); + sig = (PgpSignature) sgEnum.Current; + + sig.InitVerify(key); + + if (!sig.VerifyCertification(key)) + { + Fail("failed to verify revocation certification"); + } + + // + // use of PgpKeyPair + // + PgpKeyPair pgpKp = new PgpKeyPair(PublicKeyAlgorithmTag.RsaGeneral, + kp.Public, kp.Private, DateTime.UtcNow); + + PgpPublicKey k1 = pgpKp.PublicKey; + PgpPrivateKey k2 = pgpKp.PrivateKey; + + k1.GetEncoded(); + + MixedTest(k2, k1); + + // + // key pair generation - AES_256 encryption. + // + kp = kpg.GenerateKeyPair(); + + secretKey = new PgpSecretKey(PgpSignature.DefaultCertification, PublicKeyAlgorithmTag.RsaGeneral, kp.Public, kp.Private, DateTime.UtcNow, "fred", SymmetricKeyAlgorithmTag.Aes256, passPhrase, null, null, new SecureRandom()); + + secretKey.ExtractPrivateKey(passPhrase); + + secretKey.Encode(new UncloseableMemoryStream()); + + // + // secret key password changing. + // + const string newPass = "newPass"; + + secretKey = PgpSecretKey.CopyWithNewPassword(secretKey, passPhrase, newPass.ToCharArray(), secretKey.KeyEncryptionAlgorithm, new SecureRandom()); + + secretKey.ExtractPrivateKey(newPass.ToCharArray()); + + secretKey.Encode(new UncloseableMemoryStream()); + + key = secretKey.PublicKey; + + key.Encode(new UncloseableMemoryStream()); + + + enumerator = key.GetUserIds().GetEnumerator(); + enumerator.MoveNext(); + uid = (string) enumerator.Current; + + + enumerator = key.GetSignaturesForId(uid).GetEnumerator(); + enumerator.MoveNext(); + sig = (PgpSignature) enumerator.Current; + + sig.InitVerify(key); + + if (!sig.VerifyCertification(uid, key)) + { + Fail("failed to verify certification"); + } + + pgpPrivKey = secretKey.ExtractPrivateKey(newPass.ToCharArray()); + + // + // signature generation + // + const string data = "hello world!"; + byte[] dataBytes = Encoding.ASCII.GetBytes(data); + + bOut = new UncloseableMemoryStream(); + + MemoryStream testIn = new MemoryStream(dataBytes, false); + + sGen = new PgpSignatureGenerator( + PublicKeyAlgorithmTag.RsaGeneral, 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); + + // TODO Need a stream object to automatically call Update? + // (via ISigner implementation of PgpSignatureGenerator) + while ((ch = testIn.ReadByte()) >= 0) + { + lOut.WriteByte((byte)ch); + sGen.Update((byte)ch); + } + + lOut.Close(); + + sGen.Generate().Encode(bcOut); + + bcOut.Close(); + + // + // verify generated signature + // + 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(secretKey.PublicKey); + + // TODO Need a stream object to automatically call Update? + // (via ISigner implementation of PgpSignatureGenerator) + while ((ch = dIn.ReadByte()) >= 0) + { + ops.Update((byte)ch); + } + + p3 = (PgpSignatureList)pgpFact.NextPgpObject(); + + if (!ops.Verify(p3[0])) + { + Fail("Failed generated signature check"); + } + + // + // signature generation - version 3 + // + bOut = new UncloseableMemoryStream(); + + testIn = new MemoryStream(dataBytes); + PgpV3SignatureGenerator sGenV3 = new PgpV3SignatureGenerator( + PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); + + sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); + + cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip); + + bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut))); + + sGen.GenerateOnePassVersion(false).Encode(bcOut); + + lGen = new PgpLiteralDataGenerator(); + 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) + while ((ch = testIn.ReadByte()) >= 0) + { + lOut.WriteByte((byte) ch); + sGen.Update((byte)ch); + } + + lOut.Close(); + + sGen.Generate().Encode(bcOut); + + bcOut.Close(); + + // + // verify generated signature + // + 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(secretKey.PublicKey); + + // TODO Need a stream object to automatically call Update? + // (via ISigner implementation of PgpSignatureGenerator) + while ((ch = dIn.ReadByte()) >= 0) + { + ops.Update((byte)ch); + } + + p3 = (PgpSignatureList)pgpFact.NextPgpObject(); + + if (!ops.Verify(p3[0])) + { + Fail("Failed v3 generated signature check"); + } + + // + // extract PGP 8 private key + // + pgpPriv = new PgpSecretKeyRing(pgp8Key); + + secretKey = pgpPriv.GetSecretKey(); + + pgpPrivKey = secretKey.ExtractPrivateKey(pgp8Pass); + + // + // other sig tests + // + PerformTestSig(HashAlgorithmTag.Sha256, secretKey.PublicKey, pgpPrivKey); + PerformTestSig(HashAlgorithmTag.Sha384, secretKey.PublicKey, pgpPrivKey); + PerformTestSig(HashAlgorithmTag.Sha512, secretKey.PublicKey, pgpPrivKey); + FingerPrintTest(); + ExistingEmbeddedJpegTest(); + EmbeddedJpegTest(); + } + + private void PerformTestSig( + HashAlgorithmTag hashAlgorithm, + PgpPublicKey pubKey, + PgpPrivateKey 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); + } + } + + private class UncloseableMemoryStream + : MemoryStream + { + public override void Close() + { + throw new Exception("Close() called on underlying stream"); + } + } + + public override string Name + { + get { return "PGPRSATest"; } + } + + public static void Main( + string[] args) + { + RunTest(new PgpRsaTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/openpgp/test/PGPSignatureTest.cs b/crypto/test/src/openpgp/test/PGPSignatureTest.cs new file mode 100644 index 000000000..3aba2c302 --- /dev/null +++ b/crypto/test/src/openpgp/test/PGPSignatureTest.cs @@ -0,0 +1,761 @@ +using System; +using System.IO; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Bcpg.Sig; +using Org.BouncyCastle.Utilities.Date; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpSignatureTest + : SimpleTest + { + private const int[] NO_PREFERENCES = null; + private static readonly int[] PREFERRED_SYMMETRIC_ALGORITHMS + = new int[] { (int)SymmetricKeyAlgorithmTag.Aes128, (int)SymmetricKeyAlgorithmTag.TripleDes }; + private static readonly int[] PREFERRED_HASH_ALGORITHMS + = new int[] { (int)HashAlgorithmTag.Sha1, (int)HashAlgorithmTag.Sha256 }; + private static readonly int[] PREFERRED_COMPRESSION_ALGORITHMS + = new int[] { (int)CompressionAlgorithmTag.ZLib }; + + private const int TEST_EXPIRATION_TIME = 10000; + private const string TEST_USER_ID = "test user id"; + private static readonly byte[] TEST_DATA = Encoding.ASCII.GetBytes("hello world!\nhello world!\n"); + private static readonly byte[] TEST_DATA_WITH_CRLF = Encoding.ASCII.GetBytes("hello world!\r\nhello world!\r\n"); + + private static readonly byte[] dsaKeyRing = Base64.Decode( + "lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ" + + "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV" + + "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/" + + "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug" + + "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu" + + "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ" + + "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz" + + "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej" + + "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC" + + "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu" + + "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh" + + "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j" + + "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD" + + "4nXkHg=="); + + private static readonly char[] dsaPass = "hello world".ToCharArray(); + + private static readonly byte[] rsaKeyRing = Base64.Decode( + "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF" + + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" + + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" + + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" + + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" + + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" + + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" + + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" + + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" + + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" + + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" + + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" + + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" + + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" + + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" + + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" + + "AgAA"); + + private static readonly char[] rsaPass = "2002 Buffalo Sabres".ToCharArray(); + + private static readonly byte[] nullPacketsSubKeyBinding = Base64.Decode( + "iDYEGBECAAAAACp9AJ9PlJCrFpi+INwG7z61eku2Wg1HaQCgl33X5Egj+Kf7F9CXIWj2iFCvQDo="); + + public override void PerformTest() + { + // + // RSA tests + // + PgpSecretKeyRing pgpPriv = new PgpSecretKeyRing(rsaKeyRing); + PgpSecretKey secretKey = pgpPriv.GetSecretKey(); + PgpPrivateKey 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); + PgpSecretKey secretDSAKey = pgpDSAPriv.GetSecretKey(); + PgpPrivateKey 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."); + } + + PgpSignatureSubpacketVector hashedPcks = sig.GetHashedSubPackets(); + PgpSignatureSubpacketVector 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(); + } + + private void doTestKeyFlagsValues() + { + checkValue(KeyFlags.CertifyOther, 0x01); + checkValue(KeyFlags.SignData, 0x02); + checkValue(KeyFlags.EncryptComms, 0x04); + checkValue(KeyFlags.EncryptStorage, 0x08); + checkValue(KeyFlags.Split, 0x10); + checkValue(KeyFlags.Authentication, 0x20); + checkValue(KeyFlags.Shared, 0x80); + + // yes this actually happens + checkValue(new byte[] { 4, 0, 0, 0 }, 0x04); + checkValue(new byte[] { 4, 0, 0 }, 0x04); + checkValue(new byte[] { 4, 0 }, 0x04); + checkValue(new byte[] { 4 }, 0x04); + } + + private void checkValue(int flag, int val) + { + KeyFlags f = new KeyFlags(true, flag); + + if (f.Flags != val) + { + Fail("flag value mismatch"); + } + } + + private void checkValue(byte[] flag, int val) + { + KeyFlags f = new KeyFlags(true, flag); + + if (f.Flags != val) + { + Fail("flag value mismatch"); + } + } + + private void doTestMissingSubpackets(byte[] signature) + { + PgpObjectFactory f = new PgpObjectFactory(signature); + object obj = f.NextPgpObject(); + + while (!(obj is PgpSignatureList)) + { + obj = f.NextPgpObject(); + if (obj is PgpLiteralData) + { + Stream input = ((PgpLiteralData)obj).GetDataStream(); + Streams.Drain(input); + } + } + + PgpSignature sig = ((PgpSignatureList)obj)[0]; + + if (sig.Version > 3) + { + PgpSignatureSubpacketVector v = sig.GetHashedSubPackets(); + + if (v.GetKeyExpirationTime() != 0) + { + Fail("key expiration time not zero for missing subpackets"); + } + + if (!sig.HasSubpackets) + { + Fail("HasSubpackets property was false with packets"); + } + } + else + { + if (sig.GetHashedSubPackets() != null) + { + Fail("hashed sub packets found when none expected"); + } + + if (sig.GetUnhashedSubPackets() != null) + { + Fail("unhashed sub packets found when none expected"); + } + + if (sig.HasSubpackets) + { + Fail("HasSubpackets property was true with no packets"); + } + } + } + + private void preferredAlgorithmCheck( + string type, + int[] expected, + int[] prefAlgs) + { + if (expected == null) + { + if (prefAlgs != null) + { + Fail("preferences for " + type + " found when none expected"); + } + } + else + { + if (prefAlgs.Length != expected.Length) + { + Fail("wrong number of preferred " + type + " algorithms found"); + } + + for (int i = 0; i != expected.Length; i++) + { + if (expected[i] != prefAlgs[i]) + { + Fail("wrong algorithm found for " + type + ": expected " + expected[i] + " got " + prefAlgs); + } + } + } + } + + private void doTestSig( + PublicKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + PgpPublicKey pubKey, + PgpPrivateKey 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); + } + + private void doTestTextSig( + PublicKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + PgpPublicKey pubKey, + PgpPrivateKey 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); + } + + private void doTestSigV3( + PublicKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + PgpPublicKey pubKey, + PgpPrivateKey privKey) + { + byte[] bytes = generateV3BinarySig(privKey, encAlgorithm, hashAlgorithm); + + verifySignature(bytes, hashAlgorithm, pubKey, TEST_DATA); + } + + private byte[] generateV3BinarySig( + PgpPrivateKey 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 doTestTextSigV3( + PublicKeyAlgorithmTag encAlgorithm, + HashAlgorithmTag hashAlgorithm, + PgpPublicKey pubKey, + PgpPrivateKey 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 void verifySignature( + byte[] encodedSig, + HashAlgorithmTag hashAlgorithm, + PgpPublicKey pubKey, + byte[] original) + { + PgpObjectFactory pgpFact = new PgpObjectFactory(encodedSig); + 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(); + PgpSignature sig = p3[0]; + + DateTime creationTime = sig.CreationTime; + + // Check creationTime is recent + if (creationTime.CompareTo(DateTime.UtcNow) > 0 + || creationTime.CompareTo(DateTime.UtcNow.AddMinutes(-10)) < 0) + { + Fail("bad creation time in signature: " + creationTime); + } + + if (sig.KeyId != pubKey.KeyId) + { + Fail("key id mismatch in signature"); + } + + if (!ops.Verify(sig)) + { + Fail("Failed generated signature check - " + hashAlgorithm); + } + + sig.InitVerify(pubKey); + + for (int i = 0; i != original.Length; i++) + { + sig.Update(original[i]); + } + + sig.Update(original); + + if (!sig.Verify()) + { + Fail("Failed generated signature check against original data"); + } + } + + public override string Name + { + get { return "PGPSignatureTest"; } + } + + public static void Main( + string[] args) + { + RunTest(new PgpSignatureTest()); + } + + [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 new file mode 100644 index 000000000..b776a0d2a --- /dev/null +++ b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs @@ -0,0 +1,2163 @@ +using System; +using System.Collections; +using System.IO; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests +{ + [TestFixture] + public class PgpKeyRingTest + : SimpleTest + { + private static readonly byte[] pub1 = Base64.Decode( + "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + + "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh" + + "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB" + + "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p" + + "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5" + + "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN" + + "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE" + + "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1" + + "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu" + + "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y" + + "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB" + + "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u" + + "ZJhfg0htdgAfIy8ppm05vLACAAA="); + + private static readonly byte[] sec1 = Base64.Decode( + "lQHhBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + + "IIeLOTI5Dc4XKeV32a+bWv4CAwJ5KgazImo+sGBfMhDiBcBTqyDGhKHNgHic" + + "0Pky9FeRvfXTc2AO+jGmFPjcs8BnTWuDD0/jkQnRZpp1TrQidGVzdCAoVGVz" + + "dCBrZXkpIDx0ZXN0QHViaWNhbGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB" + + "4TOABgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEJh8Njfhe8KmGDcAn3XeXDMg" + + "BZgrZzFWU2IKtA/5LG2TAJ0Vf/jjyq0jZNZfGfoqGTvD2MAl0rACAACdAVgE" + + "QDzfARAEAJeUAPvUzJJbKcc55Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj4" + + "7UPAD/tQxwz8VAwJySx82ggNLxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j" + + "2BVqZAaX3q79a3eMiql1T0oEAGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOH" + + "AAQNBACD0mVMlAUgd7REYy/1mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWa" + + "Hz6CN1XptdwpDeSYEOFZ0PSuqH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85e" + + "fMBA9jUv/DeBOzRWMFG6sC6yk8NGG7Swea7EHKeQI40G3jgO/+xANtMyTP4C" + + "AwJ5KgazImo+sGBl2C7CFuI+5KM4ZhbtVie7l+OiTpr5JW2z5VgnV3EX9p04" + + "LcGKfQvD65+ELwli6yh8B2zGcipqTaYk3QoYNIhPBBgRAgAPBQJAPN8BAhsM" + + "BQkB4TOAAAoJEJh8Njfhe8KmG7kAniuRkaFFv1pdCBN8JJXpcorHmyouAJ9L" + + "xxmusffR6OI7WgD3XZ0AL8zUC7ACAAA="); + +// private static readonly char[] pass1 = "qwertzuiop".ToCharArray(); + + private static readonly byte[] pub2 = Base64.Decode( + "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"); + + private static readonly byte[] sec2 = Base64.Decode( + "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" + + "Nifs+ljmsAFn"); + + private static readonly char[] sec2pass1 = "sandhya".ToCharArray(); + private static readonly char[] sec2pass2 = "psai".ToCharArray(); + + private static readonly byte[] pub3 = Base64.Decode( + "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" + + "n3FaE6UZE9GMDmCIAjhI+0X9aH6CsAIAAw=="); + + private static readonly byte[] sec3 = Base64.Decode( + "lQHhBEB9BH0RBACtYQtE7tna6hgGyGLpq+ds3r2cLC0ISn5dNw7tm9vwiNVF" + + "JA2N37RRrifw4PvgelRSvLaX3M3ZBqC9s1Metg3v4FSlIRtSLWCNpHSvNw7i" + + "X8C2Xy9Hdlbh6Y/50o+iscojLRE14upfR1bIkcCZQGSyvGV52V2wBImUUZjV" + + "s2ZngwCg7mu852vK7+euz4WaL7ERVYtq9CMEAJ5swrljerDpz/RQ4Lhp6KER" + + "KyuI0PUttO57xINGshEINgYlZdGaZHRueHe7uKfI19mb0T4N3NJWaZ0wF+Cn" + + "rixsq0VrTUfiwfZeGluNG73aTCeY45fVXMGTTSYXzS8T0LW100Xn/0g9HRyA" + + "xUpuWo8IazxkMqHJis2uwriYKpAfA/9anvj5BS9p5pfPjp9dGM7GTMIYl5f2" + + "fcP57f+AW1TVR6IZiMJAvAdeWuLtwLnJiFpGlnFz273pfl+sAuqm1yNceImR" + + "2SDDP4+vtyycWy8nZhgEuhZx3W3cWMQz5WyNJSY1JJHh9TCQkCoN8E7XpVP4" + + "zEPboB2GzD93mfD8JLHP+/4DAwIvYrn+YqRaaGAu19XUj895g/GROyP8WEaU" + + "Bd/JNqWc4kE/0guetGnPzq7G3bLVwiKfFd4X7BrgHAo3mrQtVGVzdCBLZXkg" + + "KG5vIGNvbW1lbnQpIDx0ZXN0QGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkF" + + "AkB9BH0ECwcDAgMVAgMDFgIBAh4BAheAAAoJEKnMV8vjZQOpSRQAoKZy6YS1" + + "irF5/Q3JlWiwbkN6dEuLAJ9lldRLOlXsuQ5JW1+SLEc6K9ho4rACAADRwXPB" + + "cQEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQEASABIAAD//gAXQ3Jl" + + "YXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZ" + + "EhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sA" + + "QwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy" + + "MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAFAAUAwEiAAIRAQMRAf/EABoA" + + "AQACAwEAAAAAAAAAAAAAAAAEBQIDBgf/xAAoEAABAgUDBAEFAAAAAAAAAAAB" + + "AgMABBEhMQUSQQYTIiNhFFGBkcH/xAAXAQEAAwAAAAAAAAAAAAAAAAAEAgMF" + + "/8QAJBEAAQQAAwkAAAAAAAAAAAAAAQACERIEIfATMTJBUZGx0fH/2gAMAwEA" + + "AhEDEQA/APMuotJlJVxstqaPo22NlAUp+YsNO0qSUtBcMu6n6EtOHcfPAHHF" + + "I16++oajQtTA3DapK02HFR8UpE9pTbQWtKm2WG2rlxVyQTcfGbn7Qm0OIjL7" + + "7Wrs2NNm9lzTmmSxQ0PX4opSprk5tmESF6syggzGwOLG6gXgHFbZhBixk8Xl" + + "IDcOQLRKt+rX+3qC5ZLTQblpQlvwvxn9CMpZturVGkJHapQJphRH8hCLXbzr" + + "qpYsCx1zC5rtpJNuYQhASc0UAQv/2YhcBBMRAgAcBQJAfQV+AhsDBAsHAwID" + + "FQIDAxYCAQIeAQIXgAAKCRCpzFfL42UDqfa2AJ9hjtEeDTbTEAuuSbzhYFxN" + + "/qc0FACgsmzysdbBpuN65yK01tbEaeIMtqCwAgAAnQEUBEB9BH4QAwCqRuWO" + + "rxm5v/8WWBtPEUZnYuu3WYxefRKn6ON5ka5Ymp4AfKpKqKqn982tjlG13GVE" + + "P2ow11L4yQKGNm+VyVEapm7SpMD0SHg9vsJygAWrfMJnBYWSgE19W6o3ckUR" + + "sWsAAwYDAKDCSiSxC3Z5/POaCehw5iHs/vmVk5Wn831LSZEEwkSohNDbIEry" + + "ia/9tFXSt11AP4stJtZ0MH87/6JBbiIRD4JXcx+zfzchL7Teczr/06QMphSn" + + "sAENupbhLupfpR+BbP4DAwIvYrn+YqRaaGBjvFK1fbxCt7ZM4I2W/3BC0lCX" + + "m/NypKNspGflec8u96uUlA0fNCnxm6f9nbB0jpvoKi0g4iqAf+P2iEYEGBEC" + + "AAYFAkB9BH4ACgkQqcxXy+NlA6mtMgCgvccZA/Sg7BXVpxli47SYhxSHoM4A" + + "oNCOMplSnYTuh5ikKeBWtz36gC1psAIAAA=="); + + private static readonly char[] sec3pass1 = "123456".ToCharArray(); + + // + // GPG comment packets. + // + private static readonly byte[] sec4 = Base64.Decode( + "lQG7BD0PbK8RBAC0cW4Y2MZXmAmqYp5Txyw0kSQsFvwZKHNMFRv996IsN57URVF5" + + "BGMVPRBi9dNucWbjiSYpiYN13wE9IuLZsvVaQojV4XWGRDc+Rxz9ElsXnsYQ3mZU" + + "7H1bNQEofstChk4z+dlvPBN4GFahrIzn/CeVUn6Ut7dVdYbiTqviANqNXwCglfVA" + + "2OEePvqFnGxs1jhJyPSOnTED/RwRvsLH/k43mk6UEvOyN1RIpBXN+Ieqs7h1gFrQ" + + "kB+WMgeP5ZUsotTffVDSUS9UMxRQggVUW1Xml0geGwQsNfkr/ztWMs/T4xp1v5j+" + + "QyJx6OqNlkGdqOsoqkzJx0SQ1zBxdinFyyC4H95SDAb/RQOu5LQmxFG7quexztMs" + + "infEA/9cVc9+qCo92yRAaXRqKNVVQIQuPxeUsGMyVeJQvJBD4An8KTMCdjpF10Cp" + + "qA3t+n1S0zKr5WRUtvS6y60MOONO+EJWVWBNkx8HJDaIMNkfoqQoz3Krn7w6FE/v" + + "/5uwMd6jY3N3yJZn5nDZT9Yzv9Nx3j+BrY+henRlSU0c6xDc9QAAnjJYg0Z83VJG" + + "6HrBcgc4+4K6lHulCqH9JiM6RFNBX2ZhY3RvcjoAAK9hV206agp99GI6x5qE9+pU" + + "vs6O+Ich/SYjOkRTQV9mYWN0b3I6AACvYAfGn2FGrpBYbjnpTuFOHJMS/T5xg/0m" + + "IzpEU0FfZmFjdG9yOgAAr0dAQz6XxMwxWIn8xIZR/v2iN2L9C6O0EkZvbyBCYXIg" + + "PGJhekBxdXV4PohXBBMRAgAXBQI9D2yvBQsHCgMEAxUDAgMWAgECF4AACgkQUGLI" + + "YCIktfoGogCfZiXMJUKrScqozv5tMwzTTk2AaT8AniM5iRr0Du/Y08SL/NMhtF6H" + + "hJ89nO4EPQ9ssRADAI6Ggxj6ZBfoavuXd/ye99osW8HsNlbqhXObu5mCMNySX2wa" + + "HoWyRUEaUkI9eQw+MlHzIwzA32E7y2mU3OQBKdgLcBg4jxtcWVEg8ESKF9MpFXxl" + + "pExxWrr4DFBfCRcsTwAFEQL9G3OvwJuEZXgx2JSS41D3pG4/qiHYICVa0u3p/14i" + + "cq0kXajIk5ZJ6frCIAHIzuQ3n7jjzr05yR8s/qCrNbBA+nlkVNa/samk+jCzxxxa" + + "cR/Dbh2wkvTFuDFFETwQYLuZAADcDck4YGQAmHivVT2NNDCf/aTz0+CJWl+xRc2l" + + "Qw7D/SQjOkVMR19mYWN0b3I6AACbBnv9m5/bb/pjYAm2PtDp0CysQ9X9JCM6RUxH" + + "X2ZhY3RvcjoAAJsFyHnSmaWguTFf6lJ/j39LtUNtmf0kIzpFTEdfZmFjdG9yOgAA" + + "mwfwMD3LxmWtuCWBE9BptWMNH07Z/SQjOkVMR19mYWN0b3I6AACbBdhBrbSiM4UN" + + "y7khDW2Sk0e4v9mIRgQYEQIABgUCPQ9ssQAKCRBQYshgIiS1+jCMAJ9txwHnb1Kl" + + "6i/fSoDs8SkdM7w48wCdFvPEV0sSxE73073YhBgPZtMWbBo="); + + // + // PGP freeware version 7 + // + private static readonly byte[] pub5 = Base64.Decode( + "mQENBEBrBE4BCACjXVcNIFDQSofaIyZnALb2CRg+WY9uUqgHEEAOlPe03Cs5STM5" + + "HDlNmrh4TdFceJ46rxk1mQOjULES1YfHay8lCIzrD7FX4oj0r4DC14Fs1vXaSar2" + + "1szIpttOw3obL4A1e0p6N4jjsoG7N/pA0fEL0lSw92SoBrMbAheXRg4qNTZvdjOR" + + "grcuOuwgJRvPLtRXlhyLBoyhkd5mmrIDGv8QHJ/UjpeIcRXY9kn9oGXnEYcRbMaU" + + "VwXB4pLzWqz3ZejFI3lOxRWjm760puPOnGYlzSVBxlt2LgzUgSj1Mn+lIpWmAzsa" + + "xEiU4xUwEomQns72yYRZ6D3euNCibcte4SeXABEBAAG0KXBhbGFzaCBrYXNvZGhh" + + "biA8cGthc29kaGFuQHRpYWEtY3JlZi5vcmc+iQEuBBABAgAYBQJAawROCAsBAwkI" + + "BwIKAhkBBRsDAAAAAAoJEOfelumuiOrYqPEH+wYrdP5Tq5j+E5yN1pyCg1rwbSOt" + + "Dka0y0p7Oq/VIGLk692IWPItLEunnBXQtGBcWqklrvogvlhxtf16FgoyScfLJx1e" + + "1cJa+QQnVuH+VOESN6iS9Gp9lUfVOHv74mEMXw0l2Djfy/lnrkAMBatggyGnF9xF" + + "VXOLk1J2WVFm9KUE23o6qdB7RGkf31pN2eA7SWmkdJSkUH7o/QSFBI+UTRZ/IY5P" + + "ZIJpsdiIOqd9YMG/4RoSZuPqNRR6x7BSs8nQVR9bYs4PPlp4GfdRnOcRonoTeJCZ" + + "83RnsraWJnJTg34gRLBcqumhTuFKc8nuCNK98D6zkQESdcHLLTquCOaF5L+5AQ0E" + + "QGsETwEIAOVwNCTaDZvW4dowPbET1bI5UeYY8rAGLYsWSUfgaFv2srMiApyBVltf" + + "i6OLcPjcUCHDBjCv4pwx/C4qcHWb8av4xQIpqQXOpO9NxYE1eZnel/QB7DtH12ZO" + + "nrDNmHtaXlulcKNGe1i1utlFhgzfFx6rWkRL0ENmkTkaQmPY4gTGymJTUhBbsSRq" + + "2ivWqQA1TPwBuda73UgslIAHRd/SUaxjXoLpMbGOTeqzcKGjr5XMPTs7/YgBpWPP" + + "UxMlEQIiU3ia1bxpEhx05k97ceK6TSH2oCPQA7gumjxOSjKT+jEm+8jACVzymEmc" + + "XRy4D5Ztqkw/Z16pvNcu1DI5m6xHwr8AEQEAAYkBIgQYAQIADAUCQGsETwUbDAAA" + + "AAAKCRDn3pbprojq2EynB/4/cEOtKbI5UisUd3vkTzvWOcqWUqGqi5wjjioNtIM5" + + "pur2nFvhQE7SZ+PbAa87HRJU/4WcWMcoLkHD48JrQwHCHOLHSV5muYowb78X4Yh9" + + "epYtSJ0uUahcn4Gp48p4BkhgsPYXkxEImSYzAOWStv21/7WEMqItMYl89BV6Upm8" + + "HyTJx5MPTDbMR7X51hRg3OeQs6po3WTCWRzFIMyGm1rd/VK1L5ZDFPqO3S6YUJ0z" + + "cxecYruvfK0Wp7q834wE8Zkl/PQ3NhfEPL1ZiLr/L00Ty+77/FZqt8SHRCICzOfP" + + "OawcVGI+xHVXW6lijMpB5VaVIH8i2KdBMHXHtduIkPr9"); + + private static readonly byte[] sec5 = Base64.Decode( + "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"); + + private static readonly char[] sec5pass1 = "12345678".ToCharArray(); + + // + // Werner Koch "odd keys" + // + private static readonly byte[] pub6 = Base64.Decode( + "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" + + "L4Kb7TWkd/OHQScVBO8sTUz0+2g="); + +// private static readonly byte[] pub6check = Base64.Decode("62O9"); + + // + // revoked sub key + // + private static readonly byte[] pub7 = Base64.Decode( + "mQGiBEFOsIwRBADcjRx7nAs4RaWsQU6p8/ECLZD9sSeYc6CN6UDI96RKj0/hCzMs" + + "qlA0+9fzGZ7ZEJ34nuvDKlhKGC7co5eOiE0a9EijxgcrZU/LClZWa4YfyNg/ri6I" + + "yTyfOfrPQ33GNQt2iImDf3FKp7XKuY9nIxicGQEaW0kkuAmbV3oh0+9q8QCg/+fS" + + "epDEqEE/+nKONULGizKUjMED/RtL6RThRftZ9DOSdBytGYd48z35pca/qZ6HA36K" + + "PVQwi7V77VKQyKFLTOXPLnVyO85hyYB/Nv4DFHN+vcC7/49lfoyYMZlN+LarckHi" + + "NL154wmmzygB/KKysvWBLgkErEBCD0xBDd89iTQNlDtVQAWGORVffl6WWjOAkliG" + + "3dL6A/9A288HfFRnywqi3xddriV6wCPmStC3dkCS4vHk2ofS8uw4ZNoRlp1iEPna" + + "ai2Xa9DX1tkhaGk2k96MqqbBdGpbW8sMA9otJ9xdMjWEm/CgJUFUFQf3zaVy3mkM" + + "S2Lvb6P4Wc2l/diEEIyK8+PqJItSh0OVU3K9oM7ngHwVcalKILQVUkV2b2tlZCA8" + + "UmV2b2tlZEB0ZWQ+iQBOBBARAgAOBQJBTrCMBAsDAgECGQEACgkQvglkcFA/c63+" + + "QgCguh8rsJbPTtbhZcrqBi5Mo1bntLEAoPZQ0Kjmu2knRUpHBeUemHDB6zQeuQIN" + + "BEFOsIwQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz" + + "0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRP" + + "xfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvN" + + "ILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dD" + + "ox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMI" + + "PWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/93zriSvSHqsi1FeEmUBo431Jkh" + + "VerIzb6Plb1j6FIq+s3vyvx9K+dMvjotZqylWZj4GXpH+2xLJTjWkrGSfUZVI2Nk" + + "nyOFxUCKLLqaqVBFAQIjULfvQfGEWiGQKk9aRLkdG+D+8Y2N9zYoBXoQ9arvvS/t" + + "4mlOsiuaTe+BZ4x+BXTpF4b9sKZl7V8QP/TkoJWUdydkvxciHdWp7ssqyiKOFRhG" + + "818knDfFQ3cn2w/RnOb+7AF9wDncXDPYLfpPv9b2qZoLrXcyvlLffGDUdWs553ut" + + "1F5AprMURs8BGmY9BnjggfVubHdhTUoA4gVvrdaf+D9NwZAl0xK/5Y/oPuMZiQBG" + + "BBgRAgAGBQJBTrCMAAoJEL4JZHBQP3Ot09gAoMmLKloVDP+WhDXnsM5VikxysZ4+" + + "AKCrJAUO+lYAyPYwEwgK+bKmUGeKrIkARgQoEQIABgUCQU6wpQAKCRC+CWRwUD9z" + + "rQK4AJ98kKFxGU6yhHPr6jYBJPWemTNOXgCfeGB3ox4PXeS4DJDuLy9yllytOjo="); + +// private static readonly byte[] pub7check = Base64.Decode("f/YQ"); + + private static readonly byte[] pub8 = Base64.Decode( + "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" + + "9Uqz3fUvGoewAWA="); + + private static readonly byte[] sec8 = Base64.Decode( + "lQHpBEEcraYRBADFYj+uFOhHz5SdECvJ3Z03P47gzmWLQ5HH8fPYC9rrv7AgqFFX" + + "aWlJJVMLua9e6xoCiDWJs/n4BbZ/weL/11ELg6XqUnzFhYyz0H2KFsPgQ/b9lWLY" + + "MtcPMFy5jE33hv/ixHgYLFqoNaAIbg0lzYEW/otQ9IhRl16fO1Q/CQZZrQCg/9M2" + + "V2BTmm9RYog86CXJtjawRBcD/RIqU0zulxZ2Zt4javKVxrGIwW3iBU935ebmJEIK" + + "Y5EVkGKBOCvsApZ+RGzpYeR2uMsTnQi8RJgiAnjaoVPCdsVJE7uQ0h8XuJ5n5mJ2" + + "kLCFlF2hj5ViicZzse+crC12CGtgRe8z23ubLRcd6IUGhVutK8/b5knZ22vE14JD" + + "ykKdA/96ObzJQdiuuPsEWN799nUUCaYWPAoLAmiXuICSP4GEnxLbYHWo8zhMrVMT" + + "9Q5x3h8cszUz7Acu2BXjP1m96msUNoxPOZtt88NlaFz1Q/JSbQTsVOMd9b/IRN6S" + + "A/uU0BiKEMHXuT8HUHVPK49oCKhZrGFP3RT8HZxDKLmR/qrgZ/4JAwLXyWhb4pf4" + + "nmCmD0lDwoYvatLiR7UQVM2MamxClIiT0lCPN9C2AYIFgRWAJNS215Tjx7P/dh7e" + + "8sYfh5XEHErT3dMbsAGHtCFKaWEgWWl5dSA8eXlqaWFAbm93bWVkaWF0ZWNoLmNv" + + "bT6wAwP//4kAXQQQEQIAHQUCQRytpgcLCQgHAwIKAhkBBRsDAAAABR4BAAAAAAoJ" + + "EPT+Vvgr/2IUmWEAoJEyJ9B7CJfmjwVTT30UbdCctVRmAJ9akw6we6UYd82vF0FK" + + "QTlSuqHXKbABZ50CawRBHK2mEAgA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlL" + + "OCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N" + + "286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/" + + "RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2O" + + "u1WMuF040zT9fBdXQ6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqV" + + "DNmWn6vQClCbAkbTCD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwACAgf/crbApFLO" + + "QikN9lHbn62dDxuu/dNigNmjf/A3cX+vo8aPHTXnRDyDwQALRuqbitdbM6p1LFjG" + + "8g84Aabk/jL7zzjJLqPe8pxeK1Pu+P44NzalXAYMsOOsxGuixIrz3Jw8IrpH/mkP" + + "tG/iX0NaLZ+Au9eokdLb+6NR/a51r2qL3E0ycFciJ61HzZKKHi6d0VQ7CHozCz+j" + + "d5530Mh1qq/ZjYDDjfP+snpyNIZXcLtGR/3HzkBqNgDcvClLx3322AWKDa7pX8DX" + + "qiLr8znWhPRpH9kCTnSpRzhYGT25FRcvdj4/q/oUIET/Tp+BWW3BxAc7WgpgqEfn" + + "fa0Mv72Zbn91gf4JAwITijME9IlFBGAwH6YmBtWIlnDiRbsq/Pxozuhbnes831il" + + "KmdpUKXkiIfHY0MqrEWl3Dfn6PMJGTnhgqXMrDxx3uHrq0Jl2swRnAWIIO8gID7j" + + "uPetUqEviPiwAYeJAEwEGBECAAwFAkEcraYFGwwAAAAACgkQ9P5W+Cv/YhShrgCg" + + "+JW8m5nF3R/oZGuG87bXQBszkjMAoLhGPncuGKowJXMRVc70/8qwXQJLsAFn"); + + private static readonly char[] sec8pass = "qwertyui".ToCharArray(); + + private static readonly byte[] sec9 = Base64.Decode( + "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" + + "6neEEX/i1Q=="); + + public char[] sec9pass = "foo".ToCharArray(); + + // version 4 keys with expiry dates + private static readonly byte[] pub10 = Base64.Decode( + "mQGiBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" + + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" + + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" + + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" + + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" + + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" + + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" + + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" + + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHLQgdGVzdCBrZXkg" + + "KHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUCQqqJrQIbAwUJACTqAAYL" + + "CQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzLAJ42AeCRIBBjv8r8qw9y" + + "laNj2GZ1sACgiWYHVXMA6B1H9I1kS3YsCd3Oq7qwAgAAuM0EQqqJrhADAKWkix8l" + + "pJN7MMTXob4xFF1TvGll0UD1bDGOMMbes6aeXSbT9QXee/fH3GnijLY7wB+qTPv9" + + "ohubrSpnv3yen3CEBW6Q2YK+NlCskma42Py8YMV2idmYjtJi1ckvHFWt5wADBQL/" + + "fkB5Q5xSGgspMaTZmtmX3zG7ZDeZ0avP8e8mRL8UszCTpqs6vMZrXwyQLZPbtMYv" + + "PQpuRGEeKj0ysimwYRA5rrLQjnRER3nyuuEUUgc4j+aeRxPf9WVsJ/a1FCHtaAP1" + + "iE8EGBECAA8FAkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCfd66H7DL7kFGd" + + "IoS+NIp8JO+noxAAn25si4QAF7og8+4T5YQUuhIhx/NesAIAAA=="); + + private static readonly byte[] sec10 = Base64.Decode( + "lQHhBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" + + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" + + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" + + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" + + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" + + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" + + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" + + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" + + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHP4DAwLssmOjVC+d" + + "mWB783Lpzjb9evKzsxisTdx8/jHpUSS+r//6/Guyx3aA/zUw5bbftItW57mhuNNb" + + "JTu7WrQgdGVzdCBrZXkgKHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUC" + + "QqqJrQIbAwUJACTqAAYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzL" + + "AJ0cYPwKeoSReY14LqJtAjnkX7URHACgsRZWfpbalrSyDnq3TtZeGPUqGX+wAgAA" + + "nQEUBEKqia4QAwClpIsfJaSTezDE16G+MRRdU7xpZdFA9WwxjjDG3rOmnl0m0/UF" + + "3nv3x9xp4oy2O8Afqkz7/aIbm60qZ798np9whAVukNmCvjZQrJJmuNj8vGDFdonZ" + + "mI7SYtXJLxxVrecAAwUC/35AeUOcUhoLKTGk2ZrZl98xu2Q3mdGrz/HvJkS/FLMw" + + "k6arOrzGa18MkC2T27TGLz0KbkRhHio9MrIpsGEQOa6y0I50REd58rrhFFIHOI/m" + + "nkcT3/VlbCf2tRQh7WgD9f4DAwLssmOjVC+dmWDXVLRopzxbBGOvodp/LZoSDb56" + + "gNJjDMJ1aXqWW9qTAg1CFjBq73J3oFpVzInXZ8+Q8inxv7bnWiHbiE8EGBECAA8F" + + "AkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCgl2jw5hfk/JsyjulQqe1Nps1q" + + "Lx0AoMdnFMZmTMLHn8scUW2j9XO312tmsAIAAA=="); + +// private static readonly char[] sec10pass = "test".ToCharArray(); + + private static readonly byte[] subKeyBindingKey = Base64.Decode( + "mQGiBDWagYwRBAD7UcH4TAIp7tmUoHBNxVxCVz2ZrNo79M6fV63riOiH2uDxfIpr" + + "IrL0cM4ehEKoqlhngjDhX60eJrOw1nC5BpYZRnDnyDYT4wTWRguxObzGq9pqA1dM" + + "oPTJhkFZVIBgFY99/ULRqaUYIhFGgBtnwS70J8/L/PGVc3DmWRLMkTDjSQCg/5Nh" + + "MCjMK++MdYMcMl/ziaKRT6EEAOtw6PnU9afdohbpx9CK4UvCCEagfbnUtkSCQKSk" + + "6cUp6VsqyzY0pai/BwJ3h4apFMMMpVrtBAtchVgqo4xTr0Sve2j0k+ase6FSImiB" + + "g+AR7hvTUTcBjwtIExBc8TuCTqmn4GG8F7UMdl5Z0AZYj/FfAQYaRVZYP/pRVFNx" + + "Lw65BAC/Fi3qgiGCJFvXnHIckTfcAmZnKSEXWY9NJ4YQb4+/nH7Vsw0wR/ZObUHR" + + "bWgTc9Vw1uZIMe0XVj6Yk1dhGRehUnrm3mE7UJxu7pgkBCbFECFSlSSqP4MEJwZV" + + "09YP/msu50kjoxyoTpt+16uX/8B4at24GF1aTHBxwDLd8X0QWrQsTWVycmlsbCBM" + + "eW5jaCBDTEVBUiBzeXN0ZW0gREggPGNsZWFyQG1sLmNvbT6JAEsEEBECAAsFAjWa" + + "gYwECwMBAgAKCRDyAGjiP47/XanfAKCs6BPURWVQlGh635VgL+pdkUVNUwCdFcNa" + + "1isw+eAcopXPMj6ACOapepu5Ag0ENZqBlBAIAPZCV7cIfwgXcqK61qlC8wXo+VMR" + + "OU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf" + + "3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2g" + + "pXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPA" + + "Q/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQD" + + "GcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsAAgIH" + + "/RYtVo+HROZ6jrNjrATEwQm1fUQrk6n5+2dniN881lF0CNkB4NkHw1Xxz4Ejnu/0" + + "iLg8fkOAsmanOsKpOkRtqUnVpsVL5mLJpFEyCY5jbcfj+KY9/25bs0ga7kLHNZia" + + "zbCxJdF+W179z3nudQxRaXG/0XISIH7ziZbSVni69sKc1osk1+OoOMbSuZ86z535" + + "Pln4fXclkFE927HxfbWoO+60hkOLKh7x+8fC82b3x9vCETujEaxrscO2xS7/MYXP" + + "8t1ffriTDmhuIuQS2q4fLgeWdqrODrMhrD8Dq7e558gzp30ZCqpiS7EmKGczL7B8" + + "gXxbBCVSTxYMJheXt2xMXsuJAD8DBRg1moGU8gBo4j+O/10RAgWdAKCPhaFIXuC8" + + "/cdiNMxTDw9ug3De5QCfYXmDzRSFUu/nrCi8yz/l09wsnxo="); + +// private static readonly byte[] subKeyBindingCheckSum = Base64.Decode("3HU+"); + + // + // PGP8 with SHA1 checksum. + // + private static readonly byte[] rewrapKey = Base64.Decode( + "lQOWBEUPOQgBCADdjPTtl8oOwqJFA5WU8p7oDK5KRWfmXeXUZr+ZJipemY5RSvAM" + + "rxqsM47LKYbmXOJznXCQ8+PPa+VxXAsI1CXFHIFqrXSwvB/DUmb4Ec9EuvNd18Zl" + + "hJAybzmV2KMkaUp9oG/DUvxZJqkpUddNfwqZu0KKKZWF5gwW5Oy05VCpaJxQVXFS" + + "whdbRfwEENJiNx4RB3OlWhIjY2p+TgZfgQjiGB9i15R+37sV7TqzBUZF4WWcnIRQ" + + "DnpUfxHgxQ0wO/h/aooyRHSpIx5i4oNpMYq9FNIyakEx/Bomdbs5hW9dFxhrE8Es" + + "UViAYITgTsyROxmgGatGG09dcmVDJVYF4i7JAAYpAAf/VnVyUDs8HrxYTOIt4rYY" + + "jIHToBsV0IiLpA8fEA7k078L1MwSwERVVe6oHVTjeR4A9OxE52Vroh2eOLnF3ftf" + + "6QThVVZr+gr5qeG3yvQ36N7PXNEVOlkyBzGmFQNe4oCA+NR2iqnAIspnekVmwJV6" + + "xVvPCjWw/A7ZArDARpfthspwNcJAp4SWfoa2eKzvUTznTyqFu2PSS5fwQZUgOB0P" + + "Y2FNaKeqV8vEZu4SUWwLOqXBQIZXiaLvdKNgwFvUe3kSHdCNsrVzW7SYxFwaEog2" + + "o6YLKPVPqjlGX1cMOponGp+7n9nDYkQjtEsGSSMQkQRDAcBdSVJmLO07kFOQSOhL" + + "WQQA49BcgTZyhyH6TnDBMBHsGCYj43FnBigypGT9FrQHoWybfX47yZaZFROAaaMa" + + "U6man50YcYZPwzDzXHrK2MoGALY+DzB3mGeXVB45D/KYtlMHPLgntV9T5b14Scbc" + + "w1ES2OUtsSIUs0zelkoXqjLuKnSIYK3mMb67Au7AEp6LXM8EAPj2NypvC86VEnn+" + + "FH0QHvUwBpmDw0EZe25xQs0brvAG00uIbiZnTH66qsIfRhXV/gbKK9J5DTGIqQ15" + + "DuPpz7lcxg/n2+SmjQLNfXCnG8hmtBjhTe+udXAUrmIcfafXyu68SAtebgm1ga56" + + "zUfqsgN3FFuMUffLl3myjyGsg5DnA/oCFWL4WCNClOgL6A5VkNIUait8QtSdCACT" + + "Y7jdSOguSNXfln0QT5lTv+q1AjU7zjRl/LsFNmIJ5g2qdDyK937FOXM44FEEjZty" + + "/4P2dzYpThUI4QUohIj8Qi9f2pZQueC5ztH6rpqANv9geZKcciAeAbZ8Md0K2TEU" + + "RD3Lh+RSBzILtBtUZXN0IEtleSA8dGVzdEBleGFtcGxlLmNvbT6JATYEEwECACAF" + + "AkUPOQgCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRDYpknHeQaskD9NB/9W" + + "EbFuLaqZAl3yjLU5+vb75BdvcfL1lUs44LZVwobNp3/0XbZdY76xVPNZURtU4u3L" + + "sJfGlaF+EqZDE0Mqc+vs5SIb0OnCzNJ00KaUFraUtkByRV32T5ECHK0gMBjCs5RT" + + "I0vVv+Qmzl4+X1Y2bJ2mlpBejHIrOzrBD5NTJimTAzyfnNfipmbqL8p/cxXKKzS+" + + "OM++ZFNACj6lRM1W9GioXnivBRC88gFSQ4/GXc8yjcrMlKA27JxV+SZ9kRWwKH2f" + + "6o6mojUQxnHr+ZFKUpo6ocvTgBDlC57d8IpwJeZ2TvqD6EdA8rZ0YriVjxGMDrX1" + + "8esfw+iLchfEwXtBIRwS"); + + private static readonly char[] rewrapPass = "voltage123".ToCharArray(); + + private static readonly byte[] pubWithX509 = Base64.Decode( + "mQENBERabjABCACtmfyo6Nph9MQjv4nmCWjZrRYnhXbivomAdIwYkLZUj1bjqE+j" + + "uaLzjZV8xSI59odZvrmOiqlzOc4txitQ1OX7nRgbOJ7qku0dvwjtIn46+HQ+cAFn" + + "2mTi81RyXEpO2uiZXfsNTxUtMi+ZuFLufiMc2kdk27GZYWEuasdAPOaPJnA+wW6i" + + "ZHlt0NfXIGNz864gRwhD07fmBIr1dMFfATWxCbgMd/rH7Z/j4rvceHD2n9yrhPze" + + "YN7W4Nuhsr2w/Ft5Cm9xO7vXT/cpto45uxn8f7jERep6bnUwNOhH8G+6xLQgTLD0" + + "qFBGVSIneK3lobs6+xn6VaGN8W0tH3UOaxA1ABEBAAG0D0NOPXFhLWRlZXBzaWdo" + + "dIkFDgQQZAIFAQUCRFpuMAUDCWdU0gMF/3gCGwPELGQBAQQwggTkMIIDzKADAgEC" + + "AhBVUMV/M6rIiE+IzmnPheQWMA0GCSqGSIb3DQEBBQUAMG4xEzARBgoJkiaJk/Is" + + "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt" + + "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo" + + "dDAeFw0wNjA1MDQyMTEyMTZaFw0xMTA1MDQyMTIwMDJaMG4xEzARBgoJkiaJk/Is" + + "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt" + + "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo" + + "dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2Z/Kjo2mH0xCO/ieYJ" + + "aNmtFieFduK+iYB0jBiQtlSPVuOoT6O5ovONlXzFIjn2h1m+uY6KqXM5zi3GK1DU" + + "5fudGBs4nuqS7R2/CO0ifjr4dD5wAWfaZOLzVHJcSk7a6Jld+w1PFS0yL5m4Uu5+" + + "IxzaR2TbsZlhYS5qx0A85o8mcD7BbqJkeW3Q19cgY3PzriBHCEPTt+YEivV0wV8B" + + "NbEJuAx3+sftn+Piu9x4cPaf3KuE/N5g3tbg26GyvbD8W3kKb3E7u9dP9ym2jjm7" + + "Gfx/uMRF6npudTA06Efwb7rEtCBMsPSoUEZVIid4reWhuzr7GfpVoY3xbS0fdQ5r" + + "EDUCAwEAAaOCAXwwggF4MAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G" + + "A1UdDgQWBBSmFTRv5y65DHtTYae48zl0ExNWZzCCASUGA1UdHwSCARwwggEYMIIB" + + "FKCCARCgggEMhoHFbGRhcDovLy9DTj1xYS1kZWVwc2lnaHQsQ049cWEtd3VtYW4x" + + "LWRjLENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNl" + + "cyxDTj1Db25maWd1cmF0aW9uLERDPVdlYmZlLERDPXRtczAxLERDPXFhLERDPWNv" + + "bT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JM" + + "RGlzdHJpYnV0aW9uUG9pbnSGQmh0dHA6Ly9xYS13dW1hbjEtZGMud2ViZmUudG1z" + + "MDEucWEuY29tL0NlcnRFbnJvbGwvcWEtZGVlcHNpZ2h0LmNybDAQBgkrBgEEAYI3" + + "FQEEAwIBADANBgkqhkiG9w0BAQUFAAOCAQEAfuZCW3XlB7Eok35zQbvYt9rhAndT" + + "DNw3wPNI4ZzD1nXoYWnwhNNvWRpsOt4ExOSNdaHErfgDXAMyyg66Sro0TkAx8eAj" + + "fPQsyRAh0nm0glzFmJN6TdOZbj7hqGZjc4opQ6nZo8h/ULnaEwMIUW4gcSkZt0ww" + + "CuErl5NUrN3DpkREeCG/fVvQZ8ays3ibQ5ZCZnYBkLYq/i0r3NLW34WfYhjDY48J" + + "oQWtvFSAxvRfz2NGmqnrCHPQZxqlfdta97kDa4VQ0zSeBaC70gZkLmD1GJMxWoXW" + + "6tmEcgPY5SghInUf+L2u52V55MjyAFzVp7kTK2KY+p7qw35vzckrWkwu8AAAAAAA" + + "AQE="); + + private static readonly byte[] secWithPersonalCertificate = Base64.Decode( + "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" + + "cGdwbWltZQULBwgJAgIZAQUbAQAAAAUeAQAAAAIVAgAKCRDlTa3BE84gWVKW" + + "BACcoCFKvph9r9QiHT1Z3N4wZH36Uxqu/059EFALnBkEdVudX/p6S9mynGRk" + + "EfhmWFC1O6dMpnt+ZBEed/4XyFWVSLPwirML+6dxfXogdUsdFF1NCRHc3QGc" + + "txnNUT/zcZ9IRIQjUhp6RkIvJPHcyfTXKSbLviI+PxzHU2Padq8pV7ABZ7kA" + + "jQRIfg8tAQQAutJR/aRnfZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr" + + "5dg50wq3I4HOamRxUwHpdPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO" + + "8LUJ2VTbfPxoLFp539SQ0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0Ft" + + "JycAEQEAAbABj4kEzQQYAQIENwUCSMYtnAUJAeEzgMLFFAAAAAAAFwNleDUw" + + "OWNlcnRpZmljYXRlQHBncC5jb20wggNhMIICyqADAgECAgkA1AoCoRKJCgsw" + + "DQYJKoZIhvcNAQEFBQAwgakxCzAJBgNVBAYTAkNaMRcwFQYDVQQIEw5DemVj" + + "aCBSZXB1YmxpYzESMBAGA1UEChQJQSYmTCBzb2Z0MSAwHgYDVQQLExdJbnRl" + + "cm5hbCBEZXZlbG9wbWVudCBDQTEqMCgGA1UEAxQhQSYmTCBzb2Z0IEludGVy" + + "bmFsIERldmVsb3BtZW50IENBMR8wHQYJKoZIhvcNAQkBFhBrYWRsZWNAYWxz" + + "b2Z0LmN6MB4XDTA4MDcxNjE1MDkzM1oXDTA5MDcxNjE1MDkzM1owaTELMAkG" + + "A1UEBhMCQ1oxFzAVBgNVBAgTDkN6ZWNoIFJlcHVibGljMRIwEAYDVQQKFAlB" + + "JiZMIHNvZnQxFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5IeW5l" + + "ay1JbnRyYW5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAutJR/aRn" + + "fZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr5dg50wq3I4HOamRxUwHp" + + "dPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO8LUJ2VTbfPxoLFp539SQ" + + "0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0FtJycCAwEAAaOBzzCBzDAJ" + + "BgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD" + + "ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNaw7A6r10PtYZzAvr9CrSKeRYJgwHwYD" + + "VR0jBBgwFoAUmqSRM8rN3+T1+tkGiqef8S5suYgwGgYDVR0RBBMwEYEPaHlu" + + "ZWtAYWxzb2Z0LmN6MCgGA1UdHwQhMB8wHaAboBmGF2h0dHA6Ly9wZXRyazIv" + + "Y2EvY2EuY3JsMAsGA1UdDwQEAwIF4DANBgkqhkiG9w0BAQUFAAOBgQCUdOWd" + + "7mBLWj1/GSiYgfwgdTrgk/VZOJvMKBiiFyy1iFEzldz6Xx+mAexnFJKfZXZb" + + "EMEGWHfWPmgJzAtuTT0Jz6tUwDmeLH3MP4m8uOZtmyUJ2aq41kciV3rGxF0G" + + "BVlZ/bWTaOzHdm6cjylt6xxLt6MJzpPBA/9ZfybSBh1DaAUbDgAAAJ0gBBkB" + + "AgAGBQJIxi2bAAoJEAdYkEWLb2R2fJED/RK+JErZ98uGo3Z81cHkdP3rk8is" + + "DUL/PR3odBPFH2SIA5wrzklteLK/ZXmBUzcvxqHEgI1F7goXbsBgeTuGgZdx" + + "pINErxkNpcMl9FTldWKGiapKrhkZ+G8knDizF/Y7Lg6uGd2nKVxzutLXdHJZ" + + "pU89Q5nzq6aJFAZo5TBIcchQAAoJEOVNrcETziBZXvQD/1mvFqBfWqwXxoj3" + + "8fHUuFrE2pcp32y3ciO2i+uNVEkNDoaVVNw5eHQaXXWpllI/Pe6LnBl4vkyc" + + "n3pjONa4PKrePkEsCUhRbIySqXIHuNwZumDOlKzZHDpCUw72LaC6S6zwuoEf" + + "ucOcxTeGIUViANWXyTIKkHfo7HfigixJIL8nsAFn"); + + [Test] + public void PerformTest1() + { + PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(pub1); + + int count = 0; + + foreach (PgpPublicKeyRing pgpPub1 in pubRings.GetKeyRings()) + { + count++; + + int keyCount = 0; + byte[] bytes = pgpPub1.GetEncoded(); + + PgpPublicKeyRing pgpPub2 = new PgpPublicKeyRing(bytes); + + foreach (PgpPublicKey pubKey in pgpPub2.GetPublicKeys()) + { + keyCount++; + + foreach (PgpSignature sig in pubKey.GetSignatures()) + { + if (sig == null) + Fail("null signature found"); + } + } + + if (keyCount != 2) + { + Fail("wrong number of public keys"); + } + } + + if (count != 1) + { + Fail("wrong number of public keyrings"); + } + + // + // exact match + // + count = 0; + foreach (PgpPublicKeyRing pgpPub3 in pubRings.GetKeyRings("test (Test key)This tests both the PKCS12 key store.
+ */ + [TestFixture] + public class Pkcs12StoreTest + : SimpleTest + { + private static readonly char[] passwd = "hello world".ToCharArray(); + + // + // pkcs-12 pfx-pdu + // + private static readonly byte[] pkcs12 = Base64.Decode( + "MIACAQMwgAYJKoZIhvcNAQcBoIAkgAQBMAQBgAQBMAQBgAQBBgQBCQQJKoZI" + + "hvcNAQcBBAGgBAGABAEkBAGABAEEBAEBBAEwBAEEBAEDBAOCAzQEAQQEAQEE" + + "ATAEAQQEAQMEA4IDMAQBBAQBAQQBBgQBBAQBAQQBCwQBBAQBCwQLKoZIhvcN" + + "AQwKAQIEAQQEAQEEAaAEAQQEAQMEA4ICpQQBBAQBAQQBMAQBBAQBAwQDggKh" + + "BAEEBAEBBAEwBAEEBAEBBAEbBAEEBAEBBAEGBAEEBAEBBAEKBAEEBAEKBAoq" + + "hkiG9w0BDAEDBAEEBAEPBA8wDQQIoagiwNZPJR4CAQEEAQQEAQEEAQQEAQQE" + + "AQMEA4ICgAQBBAQDggKABIICgEPG0XlhMFyrs4ZWDrvEzl51ICfXd6K2ql2l" + + "nnxhszUbigtSj6x49VEx4PfOB9fQFeidc5L5An+nKp646NBMIY0UwXGs8BLQ" + + "au59jtOs987+l7QYIvl6fdGUIuLPhVSnZZDyqD+HQjU/0/ccKFHRif4tlEQq" + + "aErvZbFeH0pg4ijf1HfgX6gBJGRKdO+msa4qKGnZdHCSLZehyyxvxAmURetg" + + "yhtEl7RmedTB+4TDs7atekqxkNlD9tfwDUX6sb0IH6qbEA6P/DlVMdaD54Cl" + + "QDxRzOfIIjklZhv5OMFWtPK0aYPcqyxzLpw1qRAyoTVXpidkj/hpIpgCVBP/" + + "k5s2+WdGbLgA/4/zSrF6feRCE5llzM2IGxiHVq4oPzzngl3R+Fi5VCPDMcuW" + + "NRuIOzJA+RNV2NPOE/P3knThDnwiImq+rfxmvZ1u6T06s20RmWK6cxp7fTEw" + + "lQ9BOsv+mmyV8dr6cYJq4IlRzHdFOyEUBDwfHThyribNKKobO50xh2f93xYj" + + "Rn5UMOQBJIe3b7OKZt5HOIMrJSZO02IZgvImi9yQWi96PnWa419D1cAsLWvM" + + "xiN0HqZMbDFfxVM2BZmsxiexLhkHWKwLqfQDzRjJfmVww8fnXpWZhFXKyut9" + + "gMGEyCNoba4RU3QI/wHKWYaK74qtJpsucuLWBH6UcsHsCry6VZkwRxWwC0lb" + + "/F3Bm5UKHax5n9JHJ2amQm9zW3WJ0S5stpPObfmg5ArhbPY+pVOsTqBRlop1" + + "bYJLD/X8Qbs468Bwzej0FhoEU59ZxFrbjLSBsMUYrVrwD83JE9kEazMLVchc" + + "uCB9WT1g0hxYb7VA0BhOrWhL8F5ZH72RMCYLPI0EAQQEAQEEATEEAQQEAQEE" + + "AXgEAQQEAQEEATAEAQQEAQEEAVEEAQQEAQEEAQYEAQQEAQEEAQkEAQQEAQkE" + + "CSqGSIb3DQEJFAQBBAQBAQQBMQQBBAQBAQQBRAQBBAQBAQQBHgQBBAQBAQQB" + + "QgQBBAQBQgRCAEQAYQB2AGkAZAAgAEcALgAgAEgAbwBvAGsAJwBzACAAVgBl" + + "AHIAaQBTAGkAZwBuACwAIABJAG4AYwAuACAASQBEBAEEBAEBBAEwBAEEBAEB" + + "BAEjBAEEBAEBBAEGBAEEBAEBBAEJBAEEBAEJBAkqhkiG9w0BCRUEAQQEAQEE" + + "ATEEAQQEAQEEARYEAQQEAQEEAQQEAQQEAQEEARQEAQQEARQEFKEcMJ798oZL" + + "FkH0OnpbUBnrTLgWBAIAAAQCAAAEAgAABAEwBAGABAEGBAEJBAkqhkiG9w0B" + + "BwYEAaAEAYAEATAEAYAEAQIEAQEEAQAEATAEAYAEAQYEAQkECSqGSIb3DQEH" + + "AQQBMAQBGwQBBgQBCgQKKoZIhvcNAQwBBgQPMA0ECEE7euvmxxwYAgEBBAGg" + + "BAGABAEEBAEIBAgQIWDGlBWxnwQBBAQBCAQI2WsMhavhSCcEAQQEAQgECPol" + + "uHJy9bm/BAEEBAEQBBCiRxtllKXkJS2anKD2q3FHBAEEBAEIBAjKy6BRFysf" + + "7gQBBAQDggMwBIIDMJWRGu2ZLZild3oz7UBdpBDUVMOA6eSoWiRIfVTo4++l" + + "RUBm8TpmmGrVkV32PEoLkoV+reqlyWCvqqSjRzi3epQiVwPQ6PV+ccLqxDhV" + + "pGWDRQ5UttDBC2+u4fUQVZi2Z1i1g2tsk6SzB3MKUCrjoWKvaDUUwXo5k9Vz" + + "qSLWCLTZCjs3RaY+jg3NbLZYtfMDdYovhCU2jMYV9adJ8MxxmJRz+zPWAJph" + + "LH8hhfkKG+wJOSszqk9BqGZUa/mnZyzeQSMTEFga1ZB/kt2e8SZFWrTZEBgJ" + + "oszsL5MObbwMDowNurnZsnS+Mf7xi01LeG0VT1fjd6rn9BzVwuMwhoqyoCNo" + + "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"); + + private static readonly byte[] certUTF = Base64.Decode( + "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" + + "RgICCAA="); + + private static readonly byte[] pkcs12noFriendly = Base64.Decode( + "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" + + "tTy3wnQisALy9aYECKiM2gZrLi+fAAA="); + + private static readonly char[] noFriendlyPassword = "sschette12".ToCharArray(); + + private static readonly byte[] pkcs12StorageIssue = Base64.Decode( + "MIIO8QIBAzCCDrEGCSqGSIb3DQEHAaCCDqIEgg6eMIIOmjCCBBMGCSqGSIb3" + + "DQEHAaCCBAQEggQAMIID/DCCA/gGCyqGSIb3DQEMCgECoIICtjCCArIwHAYK" + + "KoZIhvcNAQwBAzAOBAgURJ+/5hA2pgICB9AEggKQYZ4POE8clgH9Bjd1XO8m" + + "sr6NiRBiA08CllHSOn2RzyAgHTa+cKaWrEVVJ9mCd9XveSUCoBF9E1C3jSl0" + + "XIqLNgYd6mWK9BpeMRImM/5crjy///K4ab9kymzkc5qc0pIpdCQCZ04YmtFP" + + "B80VCgyaoh2xoxqgjBCIgdSg5XdepdA5nXkG9EsQ1oVUyCykv20lKgKKRseG" + + "Jo23AX8YUYR7ANqP2gz9lvlX6RBczuoZ62ujopUexiQgt5SZx97sgo3o/b/C" + + "px17A2L4wLdeAYCMCsZhC2UeaqnZCHSsvnPZfRGiuSEGbV5gHLmXszLDaEdQ" + + "Bo873GTpKTTzBfRFzNCtYtZRqh2AUsInWZWQUcCeX6Ogwa0wTonkp18/tqsh" + + "Fj1fVpnsRmjJTTXFxkPtUw5GPJnDAM0t1xqV7kOjN76XnZrMyk2azQ1Mf3Hn" + + "sGpF+VRGH6JtxbM0Jm5zD9uHcmkSfNR3tP/+vHOB1mkIR9tD2cHvBg7pAlPD" + + "RfDVWynhS+UBNlQ0SEM/pgR7PytRSUoKc/hhe3N8VerF7VL3BwWfBLlZFYZH" + + "FvPQg4coxF7+We7nrSQfXvdVBP9Zf0PTdf3pbZelGCPVjOzbzY/o/cB23IwC" + + "ONxlY8SC1nJDXrPZ5sY51cg/qUqor056YqipRlI6I+FoTMmMDKPAiV1V5ibo" + + "DNQJkyv/CAbTX4+oFlxgddTwYcPZgd/GoGjiP9yBHHdRISatHwMcM06CzXJS" + + "s3MhzXWD4aNxvvSpXAngDLdlB7cm4ja2klmMzL7IuxzLXFQFFvYf7IF5I1pC" + + "YZOmTlJgp0efL9bHjuHFnh0S0lPtlGDOjJ/4YpWvSKDplcPiXhaFVjsUtclE" + + "oxCC5xppRm8QWS8xggEtMA0GCSsGAQQBgjcRAjEAMBMGCSqGSIb3DQEJFTEG" + + "BAQBAAAAMGkGCSsGAQQBgjcRATFcHloATQBpAGMAcgBvAHMAbwBmAHQAIABS" + + "AFMAQQAgAFMAQwBoAGEAbgBuAGUAbAAgAEMAcgB5AHAAdABvAGcAcgBhAHAA" + + "aABpAGMAIABQAHIAbwB2AGkAZABlAHIwgZsGCSqGSIb3DQEJFDGBjR6BigA3" + + "AGQAZQBmADUAYgA0ADMANgBjAGEAYgBkADAAMAAyAGQAZAAyADkAMAAzAGIA" + + "MQA2ADgANgBjADcAOQA0ADgAXwA0ADYAZgAyADYAZgBkADQALQA4ADEAMgBk" + + "AC0ANABlAGYAYgAtADgAMAA4ADgALQA0ADUAYQBiADkAMQA5ADEAMAA3AGMA" + + "YzCCCn8GCSqGSIb3DQEHBqCCCnAwggpsAgEAMIIKZQYJKoZIhvcNAQcBMBwG" + + "CiqGSIb3DQEMAQYwDgQIbr2xdnQ9inMCAgfQgIIKOHg9VKz+jlM+3abi3cp6" + + "/XMathxDSEJLrxJs6j5DAVX17S4sw1Q/1pptjdMdd8QtTfUB6JpfgJ5Kpn+h" + + "gZMf6M8wWue0U/RZN0D9w7o+2n+X3ItdEXu80eJVDOm7I2p8qiXtijbMbXRL" + + "Cup1lgfPM5uv2D63/hmWRXLeG8eySrJnKENngpM559V8TI2JcTUBy1ZP3kcH" + + "KbcJ/tVPnIIe4qguxfsTmDtAQviGvWUohbt+RGFmtqfgntK7o6b+S8uRSwEs" + + "fOU/pnVE9M1ugtNJZI/xeGJq6umZWXA/OrAcK7feWUwqRvfivDGQJEoggByd" + + "4/g92PhK1JGkwlCb1HdfhOOKKChowQ4zVvSOm+uBxARGhk2i5uW9I20I0vSJ" + + "px42O2VFVJweOchfp+wBtSHBKYP1ZXyXWMvOtULClosSeesbYMAwvyBfpYEz" + + "3rQt/1iZkqDmEisXk8X1aEKG1KSWaSPyb/+6glWikDm+YdQw3Khu7IZt1l/H" + + "qWGecccel+R9mT4YjRzHlahUYk4U+RNVasVpH1Kxz2j3CZqL+b3jQOwSAPd/" + + "hKI+S/pjIpBPfiC4WxORAzGZzY2j+a79B70h1DO1D9jGur3vJDbdmGBNgs6d" + + "nonE1B527SICcGeXY1MtnZCLOPvySih0AvOekbN9x2CJg+Hp9e7A3Fxni53/" + + "oMLr9wGRRDki72eXCXW98mU8VJofoWYS1/VBLXGf/f+tJ9J02PpzxleqPH9T" + + "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" + + "g141BQ=="); + + private static readonly char[] storagePassword = "pass".ToCharArray(); + + private static readonly byte[] pkcs12nopass = Base64.Decode( + "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" + + "j2CPp38YIFBEqvjsBAi8G+yhJe3A/wICCAA="); + + /** + * we generate a self signed certificate for the sake of testing - RSA + */ + public X509CertificateEntry CreateCert( + AsymmetricKeyParameter pubKey, + AsymmetricKeyParameter privKey, + string issuerEmail, + string subjectEmail) + { + // + // distinguished name table. + // + IDictionary issuerAttrs = new Hashtable(); + issuerAttrs.Add(X509Name.C, "AU"); + issuerAttrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); + issuerAttrs.Add(X509Name.L, "Melbourne"); + issuerAttrs.Add(X509Name.ST, "Victoria"); + issuerAttrs.Add(X509Name.EmailAddress, issuerEmail); + + IDictionary subjectAttrs = new Hashtable(); + subjectAttrs.Add(X509Name.C, "AU"); + subjectAttrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); + subjectAttrs.Add(X509Name.L, "Melbourne"); + subjectAttrs.Add(X509Name.ST, "Victoria"); + subjectAttrs.Add(X509Name.EmailAddress, subjectEmail); + + IList order = new ArrayList(); + order.Add(X509Name.C); + order.Add(X509Name.O); + order.Add(X509Name.L); + order.Add(X509Name.ST); + order.Add(X509Name.EmailAddress); + + // + // extensions + // + + // + // create the certificate - version 3 + // + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name(order, issuerAttrs)); + certGen.SetNotBefore(DateTime.UtcNow.AddDays(-30)); + certGen.SetNotAfter(DateTime.UtcNow.AddDays(30)); + certGen.SetSubjectDN(new X509Name(order, subjectAttrs)); + certGen.SetPublicKey(pubKey); + certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); + + return new X509CertificateEntry(certGen.Generate(privKey)); + } + + public void doTestPkcs12Store() + { + BigInteger mod = new BigInteger("bb1be8074e4787a8d77967f1575ef72dd7582f9b3347724413c021beafad8f32dba5168e280cbf284df722283dad2fd4abc750e3d6487c2942064e2d8d80641aa5866d1f6f1f83eec26b9b46fecb3b1c9856a303148a5cc899c642fb16f3d9d72f52526c751dc81622c420c82e2cfda70fe8d13f16cc7d6a613a5b2a2b5894d1", 16); + + MemoryStream stream = new MemoryStream(pkcs12, false); + Pkcs12Store store = new Pkcs12StoreBuilder().Build(); + store.Load(stream, passwd); + + string pName = null; + foreach (string n in store.Aliases) + { + if (store.IsKeyEntry(n)) + { + pName = n; + //break; + } + } + + AsymmetricKeyEntry key = store.GetKey(pName); + + if (!((RsaKeyParameters) key.Key).Modulus.Equals(mod)) + { + Fail("Modulus doesn't match."); + } + + X509CertificateEntry[] ch = store.GetCertificateChain(pName); + + if (ch.Length != 3) + { + Fail("chain was wrong length"); + } + + if (!ch[0].Certificate.SerialNumber.Equals(new BigInteger("96153094170511488342715101755496684211"))) + { + Fail("chain[0] wrong certificate."); + } + + if (!ch[1].Certificate.SerialNumber.Equals(new BigInteger("279751514312356623147411505294772931957"))) + { + Fail("chain[1] wrong certificate."); + } + + if (!ch[2].Certificate.SerialNumber.Equals(new BigInteger("11341398017"))) + { + Fail("chain[2] wrong certificate."); + } + + // + // save test + // + MemoryStream bOut = new MemoryStream(); + store.Save(bOut, passwd, new SecureRandom()); + + stream = new MemoryStream(bOut.ToArray(), false); + store.Load(stream, passwd); + + key = store.GetKey(pName); + + if (!((RsaKeyParameters)key.Key).Modulus.Equals(mod)) + { + Fail("Modulus doesn't match."); + } + + store.DeleteEntry(pName); + + if (store.GetKey(pName) != null) + { + Fail("Failed deletion test."); + } + + // + // cert chain test + // + store.SetCertificateEntry("testCert", ch[2]); + + if (store.GetCertificateChain("testCert") != null) + { + Fail("Failed null chain test."); + } + + // + // UTF 8 single cert test + // + stream = new MemoryStream(certUTF, false); + store.Load(stream, "user".ToCharArray()); + + if (store.GetCertificate("37") == null) + { + Fail("Failed to find UTF cert."); + } + + // + // try for a self generated certificate + // + RsaKeyParameters pubKey = new RsaKeyParameters( + false, + new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), + new BigInteger("11", 16)); + + RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( + new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), + new BigInteger("11", 16), + new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), + new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), + new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), + new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), + new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), + new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); + + X509CertificateEntry[] chain = new X509CertificateEntry[] { + CreateCert(pubKey, privKey, "issuer@bouncycastle.org", "subject@bouncycastle.org") + }; + + store = new Pkcs12StoreBuilder().Build(); + + store.SetKeyEntry("privateKey", new AsymmetricKeyEntry(privKey), chain); + + if (!store.ContainsAlias("privateKey") || !store.ContainsAlias("PRIVATEKEY")) + { + Fail("couldn't find alias privateKey"); + } + + if (store.IsCertificateEntry("privateKey")) + { + Fail("key identified as certificate entry"); + } + + if (!store.IsKeyEntry("privateKey") || !store.IsKeyEntry("PRIVATEKEY")) + { + Fail("key not identified as key entry"); + } + + if (!"privateKey".Equals(store.GetCertificateAlias(chain[0].Certificate))) + { + Fail("Did not return alias for key certificate privateKey"); + } + + MemoryStream store1Stream = new MemoryStream(); + store.Save(store1Stream, passwd, new SecureRandom()); + testNoExtraLocalKeyID(store1Stream.ToArray()); + + // + // no friendly name test + // + stream = new MemoryStream(pkcs12noFriendly, false); + store.Load(stream, noFriendlyPassword); + + pName = null; + + foreach (string n in store.Aliases) + { + if (store.IsKeyEntry(n)) + { + pName = n; + //break; + } + } + + ch = store.GetCertificateChain(pName); + + //for (int i = 0; i != ch.Length; i++) + //{ + // Console.WriteLine(ch[i]); + //} + + if (ch.Length != 1) + { + Fail("no cert found in pkcs12noFriendly"); + } + + // + // failure tests + // + ch = store.GetCertificateChain("dummy"); + + store.GetCertificateChain("DUMMY"); + + store.GetCertificate("dummy"); + + store.GetCertificate("DUMMY"); + + // + // storage test + // + stream = new MemoryStream(pkcs12StorageIssue, false); + store.Load(stream, storagePassword); + + pName = null; + + foreach (string n in store.Aliases) + { + if (store.IsKeyEntry(n)) + { + pName = n; + //break; + } + } + + ch = store.GetCertificateChain(pName); + if (ch.Length != 2) + { + Fail("Certificate chain wrong length"); + } + + store.Save(new MemoryStream(), storagePassword, new SecureRandom()); + + // + // basic certificate check + // + store.SetCertificateEntry("cert", ch[1]); + + if (!store.ContainsAlias("cert") || !store.ContainsAlias("CERT")) + { + Fail("couldn't find alias cert"); + } + + if (!store.IsCertificateEntry("cert") || !store.IsCertificateEntry("CERT")) + { + Fail("cert not identified as certificate entry"); + } + + if (store.IsKeyEntry("cert") || store.IsKeyEntry("CERT")) + { + Fail("cert identified as key entry"); + } + + if (!store.IsEntryOfType("cert", typeof(X509CertificateEntry))) + { + Fail("cert not identified as X509CertificateEntry"); + } + + if (!store.IsEntryOfType("CERT", typeof(X509CertificateEntry))) + { + Fail("CERT not identified as X509CertificateEntry"); + } + + if (store.IsEntryOfType("cert", typeof(AsymmetricKeyEntry))) + { + Fail("cert identified as key entry via AsymmetricKeyEntry"); + } + + if (!"cert".Equals(store.GetCertificateAlias(ch[1].Certificate))) + { + Fail("Did not return alias for certificate entry"); + } + + // + // test restoring of a certificate with private key originally as a ca certificate + // + store = new Pkcs12StoreBuilder().Build(); + + store.SetCertificateEntry("cert", ch[0]); + + if (!store.ContainsAlias("cert") || !store.ContainsAlias("CERT")) + { + Fail("restore: couldn't find alias cert"); + } + + if (!store.IsCertificateEntry("cert") || !store.IsCertificateEntry("CERT")) + { + Fail("restore: cert not identified as certificate entry"); + } + + if (store.IsKeyEntry("cert") || store.IsKeyEntry("CERT")) + { + Fail("restore: cert identified as key entry"); + } + + if (store.IsEntryOfType("cert", typeof(AsymmetricKeyEntry))) + { + Fail("restore: cert identified as key entry via AsymmetricKeyEntry"); + } + + if (store.IsEntryOfType("CERT", typeof(AsymmetricKeyEntry))) + { + Fail("restore: cert identified as key entry via AsymmetricKeyEntry"); + } + + if (!store.IsEntryOfType("cert", typeof(X509CertificateEntry))) + { + Fail("restore: cert not identified as X509CertificateEntry"); + } + + // + // test of reading incorrect zero-length encoding + // + stream = new MemoryStream(pkcs12nopass, false); + store.Load(stream, "".ToCharArray()); + } + + private void testSupportedTypes(AsymmetricKeyEntry privKey, X509CertificateEntry[] chain) + { + basicStoreTest(privKey, chain, + PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc, + PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc ); + basicStoreTest(privKey, chain, + PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc, + PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc ); + } + + private void basicStoreTest(AsymmetricKeyEntry privKey, X509CertificateEntry[] chain, + DerObjectIdentifier keyAlgorithm, DerObjectIdentifier certAlgorithm) + { + Pkcs12Store store = new Pkcs12StoreBuilder() + .SetKeyAlgorithm(keyAlgorithm) + .SetCertAlgorithm(certAlgorithm) + .Build(); + + store.SetKeyEntry("key", privKey, chain); + + MemoryStream bOut = new MemoryStream(); + + store.Save(bOut, passwd, new SecureRandom()); + + store.Load(new MemoryStream(bOut.ToArray(), false), passwd); + + AsymmetricKeyEntry k = store.GetKey("key"); + + if (!k.Equals(privKey)) + { + Fail("private key didn't match"); + } + + X509CertificateEntry[] c = store.GetCertificateChain("key"); + + if (c.Length != chain.Length || !c[0].Equals(chain[0])) + { + Fail("certificates didn't match"); + } + + // check attributes + Pkcs12Entry b1 = k; + Pkcs12Entry b2 = chain[0]; + + if (b1[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] != null) + { + DerBmpString name = (DerBmpString)b1[PkcsObjectIdentifiers.Pkcs9AtFriendlyName]; + + if (!name.Equals(new DerBmpString("key"))) + { + Fail("friendly name wrong"); + } + } + else + { + Fail("no friendly name found on key"); + } + + if (b1[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] != null) + { + Asn1OctetString id = (Asn1OctetString)b1[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID]; + + if (!id.Equals(b2[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID])) + { + Fail("local key id mismatch"); + } + } + else + { + Fail("no local key id found"); + } + + // + // check algorithm types. + // + Asn1InputStream aIn = new Asn1InputStream(bOut.ToArray()); + + Pfx pfx = new Pfx((Asn1Sequence)aIn.ReadObject()); + + ContentInfo cInfo = pfx.AuthSafe; + + Asn1OctetString auth = (Asn1OctetString)cInfo.Content; + + aIn = new Asn1InputStream(auth.GetOctets()); + Asn1Sequence s1 = (Asn1Sequence)aIn.ReadObject(); + + ContentInfo c1 = ContentInfo.GetInstance(s1[0]); + ContentInfo c2 = ContentInfo.GetInstance(s1[1]); + + aIn = new Asn1InputStream(((Asn1OctetString)c1.Content).GetOctets()); + + SafeBag sb = new SafeBag((Asn1Sequence)(((Asn1Sequence)aIn.ReadObject())[0])); + + EncryptedPrivateKeyInfo encInfo = EncryptedPrivateKeyInfo.GetInstance(sb.BagValue); + + // check the key encryption + if (!encInfo.EncryptionAlgorithm.ObjectID.Equals(keyAlgorithm)) + { + Fail("key encryption algorithm wrong"); + } + + // check the certificate encryption + EncryptedData cb = EncryptedData.GetInstance(c2.Content); + + if (!cb.EncryptionAlgorithm.ObjectID.Equals(certAlgorithm)) + { + Fail("cert encryption algorithm wrong"); + } + } + + private void testNoExtraLocalKeyID(byte[] store1data) + { + IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("RSA"); + kpg.Init(new RsaKeyGenerationParameters( + BigInteger.ValueOf(0x10001), new SecureRandom(), 512, 25)); + + AsymmetricCipherKeyPair newPair = kpg.GenerateKeyPair(); + + Pkcs12Store store1 = new Pkcs12StoreBuilder().Build(); + store1.Load(new MemoryStream(store1data, false), passwd); + + Pkcs12Store store2 = new Pkcs12StoreBuilder().Build(); + + AsymmetricKeyEntry k1 = store1.GetKey("privatekey"); + X509CertificateEntry[] chain1 = store1.GetCertificateChain("privatekey"); + + X509CertificateEntry[] chain2 = new X509CertificateEntry[chain1.Length + 1]; + + Array.Copy(chain1, 0, chain2, 1, chain1.Length); + + chain2[0] = CreateCert(newPair.Public, k1.Key, "subject@bouncycastle.org", "extra@bouncycaste.org"); + + if (chain1[0][PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) + { + Fail("localKeyID not found initially"); + } + + store2.SetKeyEntry("new", new AsymmetricKeyEntry(newPair.Private), chain2); + + MemoryStream bOut = new MemoryStream(); + + store2.Save(bOut, passwd, new SecureRandom()); + + store2.Load(new MemoryStream(bOut.ToArray(), false), passwd); + + chain2 = store2.GetCertificateChain("new"); + + if (chain2[1][PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] != null) + { + Fail("localKeyID found after save"); + } + } + + public override string Name + { + get { return "PKCS12Store"; } + } + + public override void PerformTest() + { + doTestPkcs12Store(); + } + + public static void Main( + string[] args) + { + RunTest(new Pkcs12StoreTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } +} diff --git a/crypto/test/src/security/test/SecureRandomTest.cs b/crypto/test/src/security/test/SecureRandomTest.cs new file mode 100644 index 000000000..12e4b9a47 --- /dev/null +++ b/crypto/test/src/security/test/SecureRandomTest.cs @@ -0,0 +1,150 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Prng; + +namespace Org.BouncyCastle.Security.Tests +{ + [TestFixture] + public class SecureRandomTest + { +#if !NETCF_1_0 + [Test] + public void TestCryptoApi() + { + SecureRandom random = new SecureRandom( + new CryptoApiRandomGenerator()); + + checkSecureRandom(random); + } +#endif + + [Test] + public void TestDefault() + { + SecureRandom random = new SecureRandom(); + + checkSecureRandom(random); + } + + [Test] + public void TestSha1Prng() + { + SecureRandom random = SecureRandom.GetInstance("SHA1PRNG"); + random.SetSeed(SecureRandom.GetSeed(20)); + + checkSecureRandom(random); + } + + [Test] + public void TestSha256Prng() + { + SecureRandom random = SecureRandom.GetInstance("SHA256PRNG"); + random.SetSeed(SecureRandom.GetSeed(32)); + + checkSecureRandom(random); + } + + [Test] + public void TestThreadedSeed() + { + SecureRandom random = new SecureRandom( + new ThreadedSeedGenerator().GenerateSeed(20, false)); + + checkSecureRandom(random); + } + + [Test] + public void TestVmpcPrng() + { + SecureRandom random = new SecureRandom(new VmpcRandomGenerator()); + random.SetSeed(SecureRandom.GetSeed(32)); + + checkSecureRandom(random); + } + + + private static void checkSecureRandom( + SecureRandom random) + { + // Note: This will periodically (< 1e-6 probability) give a false alarm. + // That's randomness for you! + Assert.IsTrue(runChiSquaredTests(random), "Chi2 test detected possible non-randomness"); + } + + private static bool runChiSquaredTests( + SecureRandom random) + { + int passes = 0; + + for (int tries = 0; tries < 100; ++tries) + { + double chi2 = measureChiSquared(random, 1000); + if (chi2 < 285.0) // 255 degrees of freedom in test => Q ~ 10.0% for 285 + ++passes; + } + + return passes > 75; + } + + private static double measureChiSquared( + SecureRandom random, + int rounds) + { + int[] counts = new int[256]; + + byte[] bs = new byte[256]; + for (int i = 0; i < rounds; ++i) + { + random.NextBytes(bs); + + for (int b = 0; b < 256; ++b) + { + ++counts[bs[b]]; + } + } + + byte mask = SecureRandom.GetSeed(1)[0]; + for (int i = 0; i < rounds; ++i) + { + random.NextBytes(bs); + + for (int b = 0; b < 256; ++b) + { + ++counts[bs[b] ^ mask]; + } + + ++mask; + } + + byte shift = SecureRandom.GetSeed(1)[0]; + for (int i = 0; i < rounds; ++i) + { + random.NextBytes(bs); + + for (int b = 0; b < 256; ++b) + { + ++counts[(byte)(bs[b] + shift)]; + } + + ++shift; + } + + int total = 3 * rounds; + + double chi2 = 0; + for (int k = 0; k < counts.Length; ++k) + { + double diff = ((double) counts[k]) - total; + double diff2 = diff * diff; + + chi2 += diff2; + } + + chi2 /= total; + + return chi2; + } + } +} diff --git a/crypto/test/src/security/test/TestDigestUtil.cs b/crypto/test/src/security/test/TestDigestUtil.cs new file mode 100644 index 000000000..0f169f931 --- /dev/null +++ b/crypto/test/src/security/test/TestDigestUtil.cs @@ -0,0 +1,63 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Digests; + +namespace Org.BouncyCastle.Security.Tests +{ + [TestFixture] + public class TestDigestUtilities + { + private static readonly byte[] TestBytes = new byte[100]; + + static TestDigestUtilities() + { + new SecureRandom().NextBytes(TestBytes); + } + + [Test] + public void TestAlgorithms() + { + CheckAlgorithm("GOST3411", new Gost3411Digest()); + CheckAlgorithm("MD2", new MD2Digest()); + CheckAlgorithm("MD4", new MD4Digest()); + CheckAlgorithm("MD5", new MD5Digest()); + CheckAlgorithm("RipeMD128", new RipeMD128Digest()); + CheckAlgorithm("RipeMD160", new RipeMD160Digest()); + CheckAlgorithm("RipeMD256", new RipeMD256Digest()); + CheckAlgorithm("RipeMD320", new RipeMD320Digest()); + CheckAlgorithm("SHA-1", new Sha1Digest()); + CheckAlgorithm("SHA-224", new Sha224Digest()); + CheckAlgorithm("SHA-256", new Sha256Digest()); + CheckAlgorithm("SHA-384", new Sha384Digest()); + CheckAlgorithm("SHA-512", new Sha512Digest()); + CheckAlgorithm("Tiger", new TigerDigest()); + CheckAlgorithm("Whirlpool", new WhirlpoolDigest()); + } + + private void CheckAlgorithm( + string name, + IDigest digest) + { + byte[] hash1 = MakeTestHash(digest); + byte[] hash2 = MakeTestHash(DigestUtilities.GetDigest(name)); + + Assert.AreEqual(hash1, hash2, name); + } + + private byte[] MakeTestHash( + IDigest digest) + { + for (int i = 0; i < digest.GetDigestSize(); ++i) + { + digest.Update((byte) i); + } + + digest.BlockUpdate(TestBytes, 0, TestBytes.Length); + + return DigestUtilities.DoFinal(digest); + } + } +} diff --git a/crypto/test/src/security/test/TestDotNetUtil.cs b/crypto/test/src/security/test/TestDotNetUtil.cs new file mode 100644 index 000000000..f880b388f --- /dev/null +++ b/crypto/test/src/security/test/TestDotNetUtil.cs @@ -0,0 +1,88 @@ +#if !(NETCF_1_0 || SILVERLIGHT) + +using System; +using System.Security.Cryptography; +using SystemX509 = System.Security.Cryptography.X509Certificates; +using System.Collections; + +using NUnit.Framework; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Security.Tests +{ + [TestFixture] + public class TestDotNetUtilities + { + [Test] + public void TestRsaInterop() + { + for (int i = 0; i < 100; ++i) + { + RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512); + RSAParameters rp = rsa.ExportParameters(true); + AsymmetricCipherKeyPair kp = DotNetUtilities.GetRsaKeyPair(rp); + + DotNetUtilities.ToRSA((RsaKeyParameters)kp.Public); + // TODO This method appears to not work for private keys (when no CRT info) + //DotNetUtilities.ToRSA((RsaKeyParameters)kp.Private); + DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)kp.Private); + } + } + + [Test] + public void TestX509CertificateConversion() + { + BigInteger DSAParaG = new BigInteger(Base64.Decode("AL0fxOTq10OHFbCf8YldyGembqEu08EDVzxyLL29Zn/t4It661YNol1rnhPIs+cirw+yf9zeCe+KL1IbZ/qIMZM=")); + BigInteger DSAParaP = new BigInteger(Base64.Decode("AM2b/UeQA+ovv3dL05wlDHEKJ+qhnJBsRT5OB9WuyRC830G79y0R8wuq8jyIYWCYcTn1TeqVPWqiTv6oAoiEeOs=")); + BigInteger DSAParaQ = new BigInteger(Base64.Decode("AIlJT7mcKL6SUBMmvm24zX1EvjNx")); + BigInteger DSAPublicY = new BigInteger(Base64.Decode("TtWy2GuT9yGBWOHi1/EpCDa/bWJCk2+yAdr56rAcqP0eHGkMnA9s9GJD2nGU8sFjNHm55swpn6JQb8q0agrCfw==")); + BigInteger DsaPrivateX = new BigInteger(Base64.Decode("MMpBAxNlv7eYfxLTZ2BItJeD31A=")); + + DsaParameters para = new DsaParameters(DSAParaP, DSAParaQ, DSAParaG); + DsaPrivateKeyParameters dsaPriv = new DsaPrivateKeyParameters(DsaPrivateX, para); + DsaPublicKeyParameters dsaPub = new DsaPublicKeyParameters(DSAPublicY, para); + + IDictionary attrs = new Hashtable(); + attrs[X509Name.C] = "AU"; + attrs[X509Name.O] = "The Legion of the Bouncy Castle"; + attrs[X509Name.L] = "Melbourne"; + attrs[X509Name.ST] = "Victoria"; + attrs[X509Name.E] = "feedback-crypto@bouncycastle.org"; + + IList ord = new ArrayList(attrs.Keys); + + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + + certGen.SetIssuerDN(new X509Name(ord, attrs)); + certGen.SetNotBefore(DateTime.UtcNow.AddDays(-1)); + certGen.SetNotAfter(DateTime.UtcNow.AddDays(1)); + certGen.SetSubjectDN(new X509Name(ord, attrs)); + certGen.SetPublicKey(dsaPub); + certGen.SetSignatureAlgorithm("SHA1WITHDSA"); + + X509Certificate cert = certGen.Generate(dsaPriv); + + cert.CheckValidity(); + cert.Verify(dsaPub); + + SystemX509.X509Certificate dotNetCert = DotNetUtilities.ToX509Certificate(cert); + + X509Certificate certCopy = DotNetUtilities.FromX509Certificate(dotNetCert); + + Assert.AreEqual(cert, certCopy); + + certCopy.CheckValidity(); + certCopy.Verify(dsaPub); + } + } +} + +#endif diff --git a/crypto/test/src/security/test/TestEncodings.cs b/crypto/test/src/security/test/TestEncodings.cs new file mode 100644 index 000000000..557d2dc51 --- /dev/null +++ b/crypto/test/src/security/test/TestEncodings.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Pkcs; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Security.Tests +{ + [TestFixture] + public class TestEncodings + { + [Test] + public void TestEC() + { + BigInteger ECParraGX = new BigInteger(Base64.Decode("D/qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqv")); + BigInteger ECParraGY = new BigInteger(Base64.Decode("AhQXGxb1olGRv6s1LPRfuatMF+cx3ZTGgzSE/Q5R")); + BigInteger ECParraH = new BigInteger(Base64.Decode("AQ==")); + BigInteger ECParraN = new BigInteger(Base64.Decode("f///////////////f///nl6an12QcfvRUiaIkJ0L")); + BigInteger ECPubQX = new BigInteger(Base64.Decode("HWWi17Yb+Bm3PYr/DMjLOYNFhyOwX1QY7ZvqqM+l")); + BigInteger ECPubQY = new BigInteger(Base64.Decode("JrlJfxu3WGhqwtL/55BOs/wsUeiDFsvXcGhB8DGx")); + BigInteger ECPrivD = new BigInteger(Base64.Decode("GYQmd/NF1B+He1iMkWt3by2Az6Eu07t0ynJ4YCAo")); + + FpCurve curve = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + + ECDomainParameters ecDomain = + new ECDomainParameters( + curve, + new FpPoint(curve, + curve.FromBigInteger(ECParraGX), + curve.FromBigInteger(ECParraGY)), + ECParraN); + + ECPublicKeyParameters ecPub = new ECPublicKeyParameters( + new FpPoint( + curve, + curve.FromBigInteger(ECPubQX), + curve.FromBigInteger(ECPubQY)), + ecDomain); + + ECPrivateKeyParameters ecPriv = new ECPrivateKeyParameters(ECPrivD, ecDomain); + + SubjectPublicKeyInfo subinfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(ecPub); + PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(ecPriv); + + ECPublicKeyParameters tecPub = (ECPublicKeyParameters)PublicKeyFactory.CreateKey(subinfo); + ECPrivateKeyParameters tecPriv = (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(privInfo); + + Assert.IsTrue(tecPub.Equals(ecPub), "EC: public key to info back to public key"); + Assert.IsTrue(tecPriv.Equals(ecPriv), "EC: private key to info back to private key"); + } + + [Test] + public void TestDH() + { + BigInteger DHParraP = new BigInteger(Base64.Decode("ALJCm1CUL6mOnyVqWTSV6Z2+DVSGOvgboOhmbyyxCrym59uVnXMmPjIgQTrmniFg7PvdcN7NNFwFmcZleULso1s=")); + BigInteger DHParraQ = new BigInteger(Base64.Decode("WSFNqEoX1MdPkrUsmkr0zt8GqkMdfA3QdDM3lliFXlNz7crOuZMfGRAgnXNPELB2fe64b2aaLgLM4zK8oXZRrQ==")); + BigInteger DHPubY = new BigInteger(Base64.Decode("AIki+8/zggCS2e488AsTNULI4LujdUeQQsZI949Dc9lKXZRmrPIC1h8NRoneHQEhpAe4Rhe0nhUOGZJekT5++SA=")); + BigInteger DHPrivX = new BigInteger(Base64.Decode("Apo67noMRO5eDWo/TtpRiBmKGw7ywh25shIu0Rs03krQmWKRbDPvdygWdJ5IpW6ZbKlCTAMhSxpz03YSeSEDmw==")); + + + DHParameters dhPara = new DHParameters(DHParraP, DHParraQ); + DHPublicKeyParameters dhPublic = new DHPublicKeyParameters(DHPubY, dhPara); + DHPrivateKeyParameters dhPrivate = new DHPrivateKeyParameters(DHPrivX, dhPara); + + SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(dhPublic); + PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(dhPrivate); + + DHPublicKeyParameters testPubKey = (DHPublicKeyParameters) PublicKeyFactory.CreateKey(pubInfo); + DHPrivateKeyParameters testPrivKey = (DHPrivateKeyParameters) PrivateKeyFactory.CreateKey(privInfo); + + Assert.IsFalse(!testPrivKey.Equals(dhPrivate), "DH: Private key to info back to key"); + Assert.IsFalse(!testPubKey.Equals(dhPublic), "DH: Public key to info back to key"); + + Assert.IsTrue(true, "Diffe Helman Test worked."); + + } + + [Test] + public void TestElGamal() + { + + BigInteger ELGamalParaG = new BigInteger(Base64.Decode("QAZPRcsH8kHVKS5065R1Xy6QtsPvDkmDZtPuq18EJkvLrCIZivE/m5puQp3/VKJrG7dKgz4NBGpONp3HT+Cn/g==")); + BigInteger ELGamalParaP = new BigInteger(Base64.Decode("AKXmAwgkudDLI/Yxk6wk3APn+mSjX5QSyDwpchmegSIi1ZNC0Jb+IbxjroKNhRTBKjtv4/JTXtJS6IqaZv9uKes=")); + BigInteger ELGamalPubY = new BigInteger(Base64.Decode("AJ/gXuZuCA2X044otNkzs8FI36XuFu1L/YHg5cEmDvICTigycRN2E1DnhP+CTqxEqgEqX8rBe5tuGDlkTLwgNqM=")); + BigInteger ELGamalPriv = new BigInteger(Base64.Decode("CqVr+K0TpuJKQnc76MjKhxrJzGr93jnuE3mTpth486Meymt8uWEVAQj1tGc9DTt14F9aV9WIT2oYYbvLJRcwow==")); + + + + ElGamalParameters elPara = new ElGamalParameters(ELGamalParaP, ELGamalParaG); + + ElGamalPrivateKeyParameters elPriv = new ElGamalPrivateKeyParameters(ELGamalPriv, elPara); + ElGamalPublicKeyParameters elPub = new ElGamalPublicKeyParameters(ELGamalPubY, elPara); + + SubjectPublicKeyInfo subInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(elPub); + PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(elPriv); + + ElGamalPrivateKeyParameters telPriv = (ElGamalPrivateKeyParameters)PrivateKeyFactory.CreateKey(privInfo); + ElGamalPublicKeyParameters telPub = (ElGamalPublicKeyParameters)PublicKeyFactory.CreateKey(subInfo); + + + // Console.WriteLine(telPriv.Equals(elPriv)); + + + + Assert.IsTrue(telPriv.Equals(elPriv), "ELGamal Private key to into back to private key."); + Assert.IsTrue(telPub.Equals(elPub), "ELGamal Public key to into back to private key."); + + Assert.IsTrue(true, "ELGamal Test worked."); + + } + + [Test] + public void TestRsa() + { + + BigInteger rsaPubMod = new BigInteger(Base64.Decode("AIASoe2PQb1IP7bTyC9usjHP7FvnUMVpKW49iuFtrw/dMpYlsMMoIU2jupfifDpdFxIktSB4P+6Ymg5WjvHKTIrvQ7SR4zV4jaPTu56Ys0pZ9EDA6gb3HLjtU+8Bb1mfWM+yjKxcPDuFjwEtjGlPHg1Vq+CA9HNcMSKNn2+tW6qt")); + BigInteger rsaPubExp = new BigInteger(Base64.Decode("EQ==")); + BigInteger rsaPrivMod = new BigInteger(Base64.Decode("AIASoe2PQb1IP7bTyC9usjHP7FvnUMVpKW49iuFtrw/dMpYlsMMoIU2jupfifDpdFxIktSB4P+6Ymg5WjvHKTIrvQ7SR4zV4jaPTu56Ys0pZ9EDA6gb3HLjtU+8Bb1mfWM+yjKxcPDuFjwEtjGlPHg1Vq+CA9HNcMSKNn2+tW6qt")); + BigInteger rsaPrivDP = new BigInteger(Base64.Decode("JXzfzG5v+HtLJIZqYMUefJfFLu8DPuJGaLD6lI3cZ0babWZ/oPGoJa5iHpX4Ul/7l3s1PFsuy1GhzCdOdlfRcQ==")); + BigInteger rsaPrivDQ = new BigInteger(Base64.Decode("YNdJhw3cn0gBoVmMIFRZzflPDNthBiWy/dUMSRfJCxoZjSnr1gysZHK01HteV1YYNGcwPdr3j4FbOfri5c6DUQ==")); + BigInteger rsaPrivExp = new BigInteger(Base64.Decode("DxFAOhDajr00rBjqX+7nyZ/9sHWRCCp9WEN5wCsFiWVRPtdB+NeLcou7mWXwf1Y+8xNgmmh//fPV45G2dsyBeZbXeJwB7bzx9NMEAfedchyOwjR8PYdjK3NpTLKtZlEJ6Jkh4QihrXpZMO4fKZWUm9bid3+lmiq43FwW+Hof8/E=")); + BigInteger rsaPrivP = new BigInteger(Base64.Decode("AJ9StyTVW+AL/1s7RBtFwZGFBgd3zctBqzzwKPda6LbtIFDznmwDCqAlIQH9X14X7UPLokCDhuAa76OnDXb1OiE=")); + BigInteger rsaPrivQ = new BigInteger(Base64.Decode("AM3JfD79dNJ5A3beScSzPtWxx/tSLi0QHFtkuhtSizeXdkv5FSba7lVzwEOGKHmW829bRoNxThDy4ds1IihW1w0=")); + BigInteger rsaPrivQinv = new BigInteger(Base64.Decode("Lt0g7wrsNsQxuDdB8q/rH8fSFeBXMGLtCIqfOec1j7FEIuYA/ACiRDgXkHa0WgN7nLXSjHoy630wC5Toq8vvUg==")); + RsaKeyParameters rsaPublic = new RsaKeyParameters(false, rsaPubMod, rsaPubExp); + RsaPrivateCrtKeyParameters rsaPrivate = new RsaPrivateCrtKeyParameters(rsaPrivMod, rsaPubExp, rsaPrivExp, rsaPrivP, rsaPrivQ, rsaPrivDP, rsaPrivDQ, rsaPrivQinv); + + SubjectPublicKeyInfo subInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(rsaPublic); + RsaKeyParameters testResult = (RsaKeyParameters)PublicKeyFactory.CreateKey(subInfo); + + // check RSA public key. + + Assert.IsFalse(!testResult.Equals(rsaPublic), "RSA: test failed on public key to info and back to public key."); + + PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(rsaPrivate); + testResult = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(privInfo); + + Assert.IsFalse(!testResult.Equals(rsaPrivate), "RSA: private key to info back to private key."); + + Assert.IsTrue(true, "RSATest worked."); + + } + + [Test] + public void TestDSA() + { + BigInteger DSAParaG = new BigInteger(Base64.Decode("AL0fxOTq10OHFbCf8YldyGembqEu08EDVzxyLL29Zn/t4It661YNol1rnhPIs+cirw+yf9zeCe+KL1IbZ/qIMZM=")); + BigInteger DSAParaP = new BigInteger(Base64.Decode("AM2b/UeQA+ovv3dL05wlDHEKJ+qhnJBsRT5OB9WuyRC830G79y0R8wuq8jyIYWCYcTn1TeqVPWqiTv6oAoiEeOs=")); + BigInteger DSAParaQ = new BigInteger(Base64.Decode("AIlJT7mcKL6SUBMmvm24zX1EvjNx")); + BigInteger DSAPublicY = new BigInteger(Base64.Decode("TtWy2GuT9yGBWOHi1/EpCDa/bWJCk2+yAdr56rAcqP0eHGkMnA9s9GJD2nGU8sFjNHm55swpn6JQb8q0agrCfw==")); + BigInteger DsaPrivateX = new BigInteger(Base64.Decode("MMpBAxNlv7eYfxLTZ2BItJeD31A=")); + + DsaParameters para = new DsaParameters(DSAParaP, DSAParaQ, DSAParaG); + DsaPrivateKeyParameters dsaPriv = new DsaPrivateKeyParameters(DsaPrivateX, para); + DsaPublicKeyParameters dsaPub = new DsaPublicKeyParameters(DSAPublicY, para); + + SubjectPublicKeyInfo subInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(dsaPub); + DsaKeyParameters testResult = (DsaKeyParameters)PublicKeyFactory.CreateKey(subInfo); + + // check RSA public key. + + Assert.IsFalse(!testResult.Equals(dsaPub), "DSA: test failed on public key to info and back to public key."); + + PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(dsaPriv); + testResult = (DsaPrivateKeyParameters)PrivateKeyFactory.CreateKey(privInfo); + + Assert.IsFalse(!testResult.Equals(dsaPriv), "DSA: private key to info back to private key."); + + Assert.IsTrue(true, "DSATest worked."); + + } + } +} diff --git a/crypto/test/src/security/test/TestParameterUtil.cs b/crypto/test/src/security/test/TestParameterUtil.cs new file mode 100644 index 000000000..fe494212a --- /dev/null +++ b/crypto/test/src/security/test/TestParameterUtil.cs @@ -0,0 +1,74 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Security.Tests +{ + [TestFixture] + public class TestParameterUtilities + { + [Test] + public void TestCreateKeyParameter() + { + SecureRandom random = new SecureRandom(); + + doTestCreateKeyParameter("AES", NistObjectIdentifiers.IdAes128Cbc, + 128, typeof(KeyParameter), random); + doTestCreateKeyParameter("DES", OiwObjectIdentifiers.DesCbc, + 64, typeof(DesParameters), random); + doTestCreateKeyParameter("DESEDE", PkcsObjectIdentifiers.DesEde3Cbc, + 192, typeof(DesEdeParameters), random); + doTestCreateKeyParameter("RC2", PkcsObjectIdentifiers.RC2Cbc, + 128, typeof(RC2Parameters), random); + } + + private void doTestCreateKeyParameter( + string algorithm, + DerObjectIdentifier oid, + int keyBits, + Type expectedType, + SecureRandom random) + { + int keyLength = keyBits / 8; + byte[] bytes = new byte[keyLength]; + random.NextBytes(bytes); + + KeyParameter key; + + key = ParameterUtilities.CreateKeyParameter(algorithm, bytes); + checkKeyParameter(key, expectedType, bytes); + + key = ParameterUtilities.CreateKeyParameter(oid, bytes); + checkKeyParameter(key, expectedType, bytes); + + bytes = new byte[keyLength * 2]; + random.NextBytes(bytes); + + int offset = random.Next(1, keyLength); + byte[] expected = new byte[keyLength]; + Array.Copy(bytes, offset, expected, 0, keyLength); + + key = ParameterUtilities.CreateKeyParameter(algorithm, bytes, offset, keyLength); + checkKeyParameter(key, expectedType, expected); + + key = ParameterUtilities.CreateKeyParameter(oid, bytes, offset, keyLength); + checkKeyParameter(key, expectedType, expected); + } + + private void checkKeyParameter( + KeyParameter key, + Type expectedType, + byte[] expectedBytes) + { + Assert.IsTrue(expectedType.IsInstanceOfType(key)); + Assert.IsTrue(Arrays.AreEqual(expectedBytes, key.GetKey())); + } + } +} diff --git a/crypto/test/src/security/test/TestSignerUtil.cs b/crypto/test/src/security/test/TestSignerUtil.cs new file mode 100644 index 000000000..c1140faf7 --- /dev/null +++ b/crypto/test/src/security/test/TestSignerUtil.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections; +using System.Text; + +using NUnit.Framework; + +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Crypto.Signers; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.Encoders; + +namespace Org.BouncyCastle.Security.Tests +{ + [TestFixture] + public class TestSignerUtilities + { + [Test] + public void TestAlgorithms() + { + // + // RSA parameters + // + BigInteger rsaMod = new BigInteger("a7295693155b1813bb84877fb45343556e0568043de5910872a3a518cc11e23e2db74eaf4545068c4e3d258a2718fbacdcc3eafa457695b957e88fbf110aed049a992d9c430232d02f3529c67a3419935ea9b569f85b1bcd37de6b899cd62697e843130ff0529d09c97d813cb15f293751ff56f943fbdabb63971cc7f4f6d5bff1594416b1f5907bde5a84a44f9802ef29b43bda1960f948f8afb8766c1ab80d32eec88ed66d0b65aebe44a6d0b3c5e0ab051aaa1b912fbcc17b8e751ddecc5365b6db6dab0020c3057db4013a51213a5798a3aab67985b0f4d88627a54a0f3f0285fbcb4afdfeb65cb153af66825656d43238b75503231500753f4e421e3c57", 16); + BigInteger rsaPubExp = new BigInteger("10001", 16); + + BigInteger rsaPrivExp = new BigInteger("65dad56ac7df7abb434e4cb5eeadb16093aa6da7f0033aad3815289b04757d32bfee6ade7749c8e4a323b5050a2fb9e2a99e23469e1ed4ba5bab54336af20a5bfccb8b3424cc6923db2ffca5787ed87aa87aa614cd04cedaebc8f623a2d2063017910f436dff18bb06f01758610787f8b258f0a8efd8bd7de30007c47b2a1031696c7d6523bc191d4d918927a7e0b09584ed205bd2ff4fc4382678df82353f7532b3bbb81d69e3f39070aed3fb64fce032a089e8e64955afa5213a6eb241231bd98d702fba725a9b205952fda186412d9e0d9344d2998c455ad8c2bae85ee672751466d5288304032b5b7e02f7e558c7af82c7fbf58eea0bb4ef0f001e6cd0a9", 16); + BigInteger rsaPrivP = new BigInteger("d4fd9ac3474fb83aaf832470643609659e511b322632b239b688f3cd2aad87527d6cf652fb9c9ca67940e84789444f2e99b0cb0cfabbd4de95396106c865f38e2fb7b82b231260a94df0e01756bf73ce0386868d9c41645560a81af2f53c18e4f7cdf3d51d80267372e6e0216afbf67f655c9450769cca494e4f6631b239ce1b", 16); + BigInteger rsaPrivQ = new BigInteger("c8eaa0e2a1b3a4412a702bccda93f4d150da60d736c99c7c566fdea4dd1b401cbc0d8c063daaf0b579953d36343aa18b33dbf8b9eae94452490cc905245f8f7b9e29b1a288bc66731a29e1dd1a45c9fd7f8238ff727adc49fff73991d0dc096206b9d3a08f61e7462e2b804d78cb8c5eccdb9b7fbd2ad6a8fea46c1053e1be75", 16); + BigInteger rsaPrivDP = new BigInteger("10edcb544421c0f9e123624d1099feeb35c72a8b34e008ac6fa6b90210a7543f293af4e5299c8c12eb464e70092805c7256e18e5823455ba0f504d36f5ccacac1b7cd5c58ff710f9c3f92646949d88fdd1e7ea5fed1081820bb9b0d2a8cd4b093fecfdb96dabd6e28c3a6f8c186dc86cddc89afd3e403e0fcf8a9e0bcb27af0b", 16); + BigInteger rsaPrivDQ = new BigInteger("97fc25484b5a415eaa63c03e6efa8dafe9a1c8b004d9ee6e80548fefd6f2ce44ee5cb117e77e70285798f57d137566ce8ea4503b13e0f1b5ed5ca6942537c4aa96b2a395782a4cb5b58d0936e0b0fa63b1192954d39ced176d71ef32c6f42c84e2e19f9d4dd999c2151b032b97bd22aa73fd8c5bcd15a2dca4046d5acc997021", 16); + BigInteger rsaPrivQinv = new BigInteger("4bb8064e1eff7e9efc3c4578fcedb59ca4aef0993a8312dfdcb1b3decf458aa6650d3d0866f143cbf0d3825e9381181170a0a1651eefcd7def786b8eb356555d9fa07c85b5f5cbdd74382f1129b5e36b4166b6cc9157923699708648212c484958351fdc9cf14f218dbe7fbf7cbd93a209a4681fe23ceb44bab67d66f45d1c9d", 16); + + RsaKeyParameters rsaPublic = new RsaKeyParameters(false, rsaMod, rsaPubExp); + RsaPrivateCrtKeyParameters rsaPrivate = new RsaPrivateCrtKeyParameters( + rsaMod, rsaPubExp, rsaPrivExp, rsaPrivP, rsaPrivQ, rsaPrivDP, rsaPrivDQ, rsaPrivQinv); + + // + // ECDSA parameters + // + BigInteger ECParraGX = new BigInteger(Base64.Decode("D/qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqv")); + BigInteger ECParraGY = new BigInteger(Base64.Decode("AhQXGxb1olGRv6s1LPRfuatMF+cx3ZTGgzSE/Q5R")); + BigInteger ECParraH = new BigInteger(Base64.Decode("AQ==")); + BigInteger ECParraN = new BigInteger(Base64.Decode("f///////////////f///nl6an12QcfvRUiaIkJ0L")); + BigInteger ECPubQX = new BigInteger(Base64.Decode("HWWi17Yb+Bm3PYr/DMjLOYNFhyOwX1QY7ZvqqM+l")); + BigInteger ECPubQY = new BigInteger(Base64.Decode("JrlJfxu3WGhqwtL/55BOs/wsUeiDFsvXcGhB8DGx")); + BigInteger ECPrivD = new BigInteger(Base64.Decode("GYQmd/NF1B+He1iMkWt3by2Az6Eu07t0ynJ4YCAo")); + + FpCurve curve = new FpCurve( + new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q + new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a + new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b + + ECDomainParameters ecDomain = new ECDomainParameters(curve, + new FpPoint(curve, + curve.FromBigInteger(ECParraGX), + curve.FromBigInteger(ECParraGY)), + ECParraN); + + ECPublicKeyParameters ecPub = new ECPublicKeyParameters( + new FpPoint(curve, + curve.FromBigInteger(ECPubQX), + curve.FromBigInteger(ECPubQY)), + ecDomain); + + ECPrivateKeyParameters ecPriv = new ECPrivateKeyParameters(ECPrivD, ecDomain); + + // + // DSA parameters + // + BigInteger DSAParaG = new BigInteger(Base64.Decode("AL0fxOTq10OHFbCf8YldyGembqEu08EDVzxyLL29Zn/t4It661YNol1rnhPIs+cirw+yf9zeCe+KL1IbZ/qIMZM=")); + BigInteger DSAParaP = new BigInteger(Base64.Decode("AM2b/UeQA+ovv3dL05wlDHEKJ+qhnJBsRT5OB9WuyRC830G79y0R8wuq8jyIYWCYcTn1TeqVPWqiTv6oAoiEeOs=")); + BigInteger DSAParaQ = new BigInteger(Base64.Decode("AIlJT7mcKL6SUBMmvm24zX1EvjNx")); + BigInteger DSAPublicY = new BigInteger(Base64.Decode("TtWy2GuT9yGBWOHi1/EpCDa/bWJCk2+yAdr56rAcqP0eHGkMnA9s9GJD2nGU8sFjNHm55swpn6JQb8q0agrCfw==")); + BigInteger DsaPrivateX = new BigInteger(Base64.Decode("MMpBAxNlv7eYfxLTZ2BItJeD31A=")); + + DsaParameters para = new DsaParameters(DSAParaP, DSAParaQ, DSAParaG); + DsaPrivateKeyParameters dsaPriv = new DsaPrivateKeyParameters(DsaPrivateX, para); + DsaPublicKeyParameters dsaPub = new DsaPublicKeyParameters(DSAPublicY, para); + + // + // ECGOST3410 parameters + // + IAsymmetricCipherKeyPairGenerator ecGostKpg = GeneratorUtilities.GetKeyPairGenerator("ECGOST3410"); + ecGostKpg.Init( + new ECKeyGenerationParameters( + CryptoProObjectIdentifiers.GostR3410x2001CryptoProA, + new SecureRandom())); + + AsymmetricCipherKeyPair ecGostPair = ecGostKpg.GenerateKeyPair(); + + // + // GOST3410 parameters + // + IAsymmetricCipherKeyPairGenerator gostKpg = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); + gostKpg.Init( + new Gost3410KeyGenerationParameters( + new SecureRandom(), + CryptoProObjectIdentifiers.GostR3410x94CryptoProA)); + + AsymmetricCipherKeyPair gostPair = gostKpg.GenerateKeyPair(); + + + + // + // signer loop + // + byte[] shortMsg = new byte[] { 1, 4, 5, 6, 8, 8, 4, 2, 1, 3 }; + byte[] longMsg = new byte[100]; + new SecureRandom().NextBytes(longMsg); + + foreach (string algorithm in SignerUtilities.Algorithms) + { + ISigner signer = SignerUtilities.GetSigner(algorithm); + + string upper = Platform.ToUpperInvariant(algorithm); + int withPos = upper.LastIndexOf("WITH"); + + string cipherName = withPos < 0 + ? upper + : upper.Substring(withPos + "WITH".Length); + + ICipherParameters signParams = null, verifyParams = null; + + if (cipherName == "RSA" || cipherName == "RSAANDMGF1") + { + signParams = rsaPrivate; + verifyParams = rsaPublic; + } + else if (cipherName == "ECDSA") + { + signParams = ecPriv; + verifyParams = ecPub; + } + else if (cipherName == "DSA") + { + signParams = dsaPriv; + verifyParams = dsaPub; + } + else if (cipherName == "ECGOST3410") + { + signParams = ecGostPair.Private; + verifyParams = ecGostPair.Public; + } + else if (cipherName == "GOST3410") + { + signParams = gostPair.Private; + verifyParams = gostPair.Public; + } + else + { + Assert.Fail("Unknown algorithm encountered: " + cipherName); + } + + signer.Init(true, signParams); + foreach (byte b in shortMsg) + { + signer.Update(b); + } + signer.BlockUpdate(longMsg, 0, longMsg.Length); + byte[] sig = signer.GenerateSignature(); + + signer.Init(false, verifyParams); + foreach (byte b in shortMsg) + { + signer.Update(b); + } + signer.BlockUpdate(longMsg, 0, longMsg.Length); + + Assert.IsTrue(signer.VerifySignature(sig), cipherName + " signer " + algorithm + " failed."); + } + } + } +} diff --git a/crypto/test/src/test/AESSICTest.cs b/crypto/test/src/test/AESSICTest.cs new file mode 100644 index 000000000..f8de35efd --- /dev/null +++ b/crypto/test/src/test/AESSICTest.cs @@ -0,0 +1,147 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Tests +{ + ///testName
must
+ * be included and excluded.
+ * @param testNameIsNotConstraint The names where testName
+ * must not be excluded and included.
+ * @param testNames1 Operand 1 of test names to use for union and
+ * intersection testing.
+ * @param testNames2 Operand 2 of test names to use for union and
+ * intersection testing.
+ * @param testUnion The union results.
+ * @param testInterSection The intersection results.
+ * @throws Exception If an unexpected exception occurs.
+ */
+ private void TestConstraints(
+ int nameType,
+ string testName,
+ string[] testNameIsConstraint,
+ string[] testNameIsNotConstraint,
+ string[] testNames1,
+ string[] testNames2,
+ string[][] testUnion,
+ string[] testInterSection)
+ {
+ for (int i = 0; i < testNameIsConstraint.Length; i++)
+ {
+ PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+ new GeneralName(nameType, testNameIsConstraint[i]))));
+ constraintValidator.checkPermitted(new GeneralName(nameType, testName));
+ }
+ for (int i = 0; i < testNameIsNotConstraint.Length; i++)
+ {
+ PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+ new GeneralName(nameType, testNameIsNotConstraint[i]))));
+ try
+ {
+ constraintValidator.checkPermitted(new GeneralName(nameType, testName));
+ Fail("not permitted name allowed: " + nameType);
+ }
+ catch (PkixNameConstraintValidatorException)
+ {
+ // expected
+ }
+ }
+ for (int i = 0; i < testNameIsConstraint.Length; i++)
+ {
+ PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.AddExcludedSubtree(new GeneralSubtree(new GeneralName(
+ nameType, testNameIsConstraint[i])));
+ try
+ {
+ constraintValidator.checkExcluded(new GeneralName(nameType, testName));
+ Fail("excluded name missed: " + nameType);
+ }
+ catch (PkixNameConstraintValidatorException)
+ {
+ // expected
+ }
+ }
+ for (int i = 0; i < testNameIsNotConstraint.Length; i++)
+ {
+ PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.AddExcludedSubtree(new GeneralSubtree(new GeneralName(
+ nameType, testNameIsNotConstraint[i])));
+ constraintValidator.checkExcluded(new GeneralName(nameType, testName));
+ }
+ for (int i = 0; i < testNames1.Length; i++)
+ {
+ PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.AddExcludedSubtree(new GeneralSubtree(new GeneralName(
+ nameType, testNames1[i])));
+ constraintValidator.AddExcludedSubtree(new GeneralSubtree(new GeneralName(
+ nameType, testNames2[i])));
+ PkixNameConstraintValidator constraints2 = new PkixNameConstraintValidator();
+ for (int j = 0; j < testUnion[i].Length; j++)
+ {
+ constraints2.AddExcludedSubtree(new GeneralSubtree(
+ new GeneralName(nameType, testUnion[i][j])));
+ }
+ if (!constraints2.Equals(constraintValidator))
+ {
+ Fail("union wrong: " + nameType);
+ }
+ constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+ new GeneralName(nameType, testNames1[i]))));
+ constraintValidator.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+ new GeneralName(nameType, testNames2[i]))));
+ constraints2 = new PkixNameConstraintValidator();
+ if (testInterSection[i] != null)
+ {
+ constraints2.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+ new GeneralName(nameType, testInterSection[i]))));
+ }
+ else
+ {
+ constraints2.IntersectEmptyPermittedSubtree(nameType);
+ }
+ if (!constraints2.Equals(constraintValidator))
+ {
+ Fail("intersection wrong: " + nameType);
+ }
+ }
+ }
+
+ /**
+ * Tests byte array based GeneralNames for inclusion or exclusion.
+ *
+ * @param nameType The {@link GeneralName} type to test.
+ * @param testName The name to test.
+ * @param testNameIsConstraint The names where testName
must
+ * be included and excluded.
+ * @param testNameIsNotConstraint The names where testName
+ * must not be excluded and included.
+ * @param testNames1 Operand 1 of test names to use for union and
+ * intersection testing.
+ * @param testNames2 Operand 2 of test names to use for union and
+ * intersection testing.
+ * @param testUnion The union results.
+ * @param testInterSection The intersection results.
+ * @throws Exception If an unexpected exception occurs.
+ */
+ private void TestConstraints(
+ int nameType,
+ byte[] testName,
+ byte[][] testNameIsConstraint,
+ byte[][] testNameIsNotConstraint,
+ byte[][] testNames1,
+ byte[][] testNames2,
+ byte[][][] testUnion,
+ byte[][] testInterSection)
+ {
+ for (int i = 0; i < testNameIsConstraint.Length; i++)
+ {
+ PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+ new GeneralName(nameType, new DerOctetString(
+ testNameIsConstraint[i])))));
+ constraintValidator.checkPermitted(new GeneralName(nameType,
+ new DerOctetString(testName)));
+ }
+ for (int i = 0; i < testNameIsNotConstraint.Length; i++)
+ {
+ PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+ new GeneralName(nameType, new DerOctetString(
+ testNameIsNotConstraint[i])))));
+ try
+ {
+ constraintValidator.checkPermitted(new GeneralName(nameType,
+ new DerOctetString(testName)));
+ Fail("not permitted name allowed: " + nameType);
+ }
+ catch (PkixNameConstraintValidatorException)
+ {
+ // expected
+ }
+ }
+ for (int i = 0; i < testNameIsConstraint.Length; i++)
+ {
+ PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.AddExcludedSubtree(new GeneralSubtree(new GeneralName(
+ nameType, new DerOctetString(testNameIsConstraint[i]))));
+ try
+ {
+ constraintValidator.checkExcluded(new GeneralName(nameType,
+ new DerOctetString(testName)));
+ Fail("excluded name missed: " + nameType);
+ }
+ catch (PkixNameConstraintValidatorException)
+ {
+ // expected
+ }
+ }
+ for (int i = 0; i < testNameIsNotConstraint.Length; i++)
+ {
+ PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.AddExcludedSubtree(new GeneralSubtree(new GeneralName(
+ nameType, new DerOctetString(testNameIsNotConstraint[i]))));
+ constraintValidator.checkExcluded(new GeneralName(nameType,
+ new DerOctetString(testName)));
+ }
+ for (int i = 0; i < testNames1.Length; i++)
+ {
+ PkixNameConstraintValidator constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.AddExcludedSubtree(new GeneralSubtree(new GeneralName(
+ nameType, new DerOctetString(testNames1[i]))));
+ constraintValidator.AddExcludedSubtree(new GeneralSubtree(new GeneralName(
+ nameType, new DerOctetString(testNames2[i]))));
+ PkixNameConstraintValidator constraints2 = new PkixNameConstraintValidator();
+ for (int j = 0; j < testUnion[i].Length; j++)
+ {
+ constraints2.AddExcludedSubtree(new GeneralSubtree(
+ new GeneralName(nameType, new DerOctetString(
+ testUnion[i][j]))));
+ }
+ if (!constraints2.Equals(constraintValidator))
+ {
+ Fail("union wrong: " + nameType);
+ }
+ constraintValidator = new PkixNameConstraintValidator();
+ constraintValidator.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+ new GeneralName(nameType, new DerOctetString(testNames1[i])))));
+ constraintValidator.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+ new GeneralName(nameType, new DerOctetString(testNames2[i])))));
+ constraints2 = new PkixNameConstraintValidator();
+ if (testInterSection[i] != null)
+ {
+ constraints2.IntersectPermittedSubtree(new DerSequence(new GeneralSubtree(
+ new GeneralName(nameType, new DerOctetString(
+ testInterSection[i])))));
+ }
+ else
+ {
+ constraints2.IntersectEmptyPermittedSubtree(nameType);
+ }
+
+ if (!constraints2.Equals(constraintValidator))
+ {
+ Fail("intersection wrong: " + nameType);
+ }
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new PkixNameConstraintsTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/test/PkixPolicyMappingTest.cs b/crypto/test/src/test/PkixPolicyMappingTest.cs
new file mode 100644
index 000000000..47e2c3120
--- /dev/null
+++ b/crypto/test/src/test/PkixPolicyMappingTest.cs
@@ -0,0 +1,419 @@
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Pkix;
+using Org.BouncyCastle.Utilities.Collections;
+using Org.BouncyCastle.Utilities.Test;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.X509.Store;
+
+namespace Org.BouncyCastle.Tests
+{
+ [TestFixture]
+ public class PkixPolicyMappingTest : SimpleTest
+ {
+ static X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
+
+ public override string Name
+ {
+ get { return "PkixPolicyMapping"; }
+ }
+
+ /**
+ * TrustAnchor's Cert
+ */
+ private X509Certificate CreateTrustCert(
+ AsymmetricKeyParameter pubKey,
+ AsymmetricKeyParameter privKey)
+ {
+ string issuer = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor";
+ string subject = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor";
+ v3CertGen.SetSerialNumber(BigInteger.ValueOf(10));
+ v3CertGen.SetIssuerDN(new X509Name(issuer));
+ v3CertGen.SetNotBefore(DateTime.UtcNow.AddDays(-30));
+ v3CertGen.SetNotAfter(DateTime.UtcNow.AddDays(30));
+ v3CertGen.SetSubjectDN(new X509Name(subject));
+ v3CertGen.SetPublicKey(pubKey);
+ v3CertGen.SetSignatureAlgorithm("SHA1WithRSAEncryption");
+ X509Certificate cert = v3CertGen.Generate(privKey);
+ return cert;
+ }
+
+ /**
+ * intermediate cert
+ */
+ private X509Certificate CreateIntmedCert(
+ AsymmetricKeyParameter pubKey,
+ AsymmetricKeyParameter caPrivKey,
+ AsymmetricKeyParameter caPubKey,
+ Asn1EncodableVector policies,
+ Hashtable policyMap)
+ {
+ string issuer = "C=JP, O=policyMappingAdditionalTest, OU=trustAnchor";
+ string subject = "C=JP, O=policyMappingAdditionalTest, OU=intmedCA";
+ v3CertGen.Reset();
+ v3CertGen.SetSerialNumber(BigInteger.ValueOf(20));
+ v3CertGen.SetIssuerDN(new X509Name(issuer));
+ v3CertGen.SetNotBefore(DateTime.UtcNow.AddDays(-30));
+ v3CertGen.SetNotAfter(DateTime.UtcNow.AddDays(30));
+ v3CertGen.SetSubjectDN(new X509Name(subject));
+ v3CertGen.SetPublicKey(pubKey);
+ v3CertGen.SetSignatureAlgorithm("SHA1WithRSAEncryption");
+ v3CertGen.AddExtension(X509Extensions.CertificatePolicies, true, new DerSequence(policies));
+ v3CertGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));
+ v3CertGen.AddExtension(X509Extensions.PolicyMappings, true, new PolicyMappings(policyMap));
+ X509Certificate cert = v3CertGen.Generate(caPrivKey);
+ return cert;
+ }
+
+ /**
+ * endEntity cert
+ */
+ private X509Certificate CreateEndEntityCert(
+ AsymmetricKeyParameter pubKey,
+ AsymmetricKeyParameter caPrivKey,
+ AsymmetricKeyParameter caPubKey,
+ Asn1EncodableVector policies)
+ {
+ string issuer = "C=JP, O=policyMappingAdditionalTest, OU=intMedCA";
+ string subject = "C=JP, O=policyMappingAdditionalTest, OU=endEntity";
+ v3CertGen.Reset();
+ v3CertGen.SetSerialNumber(BigInteger.ValueOf(20));
+ v3CertGen.SetIssuerDN(new X509Name(issuer));
+ v3CertGen.SetNotBefore(DateTime.UtcNow.AddDays(-30));
+ v3CertGen.SetNotAfter(DateTime.UtcNow.AddDays(30));
+ v3CertGen.SetSubjectDN(new X509Name(subject));
+ v3CertGen.SetPublicKey(pubKey);
+ v3CertGen.SetSignatureAlgorithm("SHA1WithRSAEncryption");
+ v3CertGen.AddExtension(X509Extensions.CertificatePolicies, true, new DerSequence(policies));
+ X509Certificate cert = v3CertGen.Generate(caPrivKey);
+ return cert;
+ }
+
+ private string TestPolicies(
+ int index,
+ X509Certificate trustCert,
+ X509Certificate intCert,
+ X509Certificate endCert,
+ ISet requirePolicies,
+ bool okay)
+ {
+ ISet trust = new HashSet();
+ trust.Add(new TrustAnchor(trustCert, null));
+ X509CertStoreSelector targetConstraints = new X509CertStoreSelector();
+ targetConstraints.Subject = endCert.SubjectDN;
+ PkixBuilderParameters pbParams = new PkixBuilderParameters(trust, targetConstraints);
+
+ ISet certs = new HashSet();
+ certs.Add(intCert);
+ certs.Add(endCert);
+
+ IX509Store store = X509StoreFactory.Create(
+ "CERTIFICATE/COLLECTION",
+ new X509CollectionStoreParameters(certs));
+ pbParams.AddStore(store);
+
+ pbParams.IsRevocationEnabled = false;
+ if (requirePolicies != null)
+ {
+ pbParams.IsExplicitPolicyRequired = true;
+ pbParams.SetInitialPolicies(requirePolicies);
+ }
+
+// CertPathBuilder cpb = CertPathBuilder.GetInstance("PKIX");
+ PkixCertPathBuilder cpb = new PkixCertPathBuilder();
+ PkixCertPathBuilderResult result = null;
+
+ try
+ {
+ result = (PkixCertPathBuilderResult)cpb.Build(pbParams);
+
+ if (!okay)
+ {
+ Fail(index + ": path validated when failure expected.");
+ }
+
+// if (result.getPolicyTree() != null)
+// {
+// Console.WriteLine("OK");
+// Console.WriteLine("policy: " + result.getPolicyTree());
+// }
+// else
+// {
+// Console.WriteLine("OK: policy tree = null");
+// }
+
+ return "";
+ }
+ catch (TestFailedException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ if (okay)
+ {
+ Fail(index + ": path failed to validate when success expected.");
+ }
+
+ Exception ee = e.InnerException;
+ if (ee != null)
+ {
+ return ee.Message;
+ }
+
+ return e.Message;
+ }
+ }
+
+ public override void PerformTest()
+ {
+ //
+ // personal keys
+ //
+ RsaPublicKeyStructure pubKeySpec = new RsaPublicKeyStructure(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ RsaPrivateCrtKeyParameters privKeySpec = new RsaPrivateCrtKeyParameters(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16),
+ new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+ new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+ new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+ new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+ new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+ new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+ //
+ // intermediate keys.
+ //
+ RsaPublicKeyStructure intPubKeySpec = new RsaPublicKeyStructure(
+ new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16),
+ new BigInteger("ffff", 16));
+
+
+ RsaPrivateCrtKeyParameters intPrivKeySpec = new RsaPrivateCrtKeyParameters(
+ new BigInteger("8de0d113c5e736969c8d2b047a243f8fe18edad64cde9e842d3669230ca486f7cfdde1f8eec54d1905fff04acc85e61093e180cadc6cea407f193d44bb0e9449b8dbb49784cd9e36260c39e06a947299978c6ed8300724e887198cfede20f3fbde658fa2bd078be946a392bd349f2b49c486e20c405588e306706c9017308e69", 16),
+ new BigInteger("ffff", 16),
+ new BigInteger("7deb1b194a85bcfd29cf871411468adbc987650903e3bacc8338c449ca7b32efd39ffc33bc84412fcd7df18d23ce9d7c25ea910b1ae9985373e0273b4dca7f2e0db3b7314056ac67fd277f8f89cf2fd73c34c6ca69f9ba477143d2b0e2445548aa0b4a8473095182631da46844c356f5e5c7522eb54b5a33f11d730ead9c0cff", 16),
+ new BigInteger("ef4cede573cea47f83699b814de4302edb60eefe426c52e17bd7870ec7c6b7a24fe55282ebb73775f369157726fcfb988def2b40350bdca9e5b418340288f649", 16),
+ new BigInteger("97c7737d1b9a0088c3c7b528539247fd2a1593e7e01cef18848755be82f4a45aa093276cb0cbf118cb41117540a78f3fc471ba5d69f0042274defc9161265721", 16),
+ new BigInteger("6c641094e24d172728b8da3c2777e69adfd0839085be7e38c7c4a2dd00b1ae969f2ec9d23e7e37090fcd449a40af0ed463fe1c612d6810d6b4f58b7bfa31eb5f", 16),
+ new BigInteger("70b7123e8e69dfa76feb1236d0a686144b00e9232ed52b73847e74ef3af71fb45ccb24261f40d27f98101e230cf27b977a5d5f1f15f6cf48d5cb1da2a3a3b87f", 16),
+ new BigInteger("e38f5750d97e270996a286df2e653fd26c242106436f5bab0f4c7a9e654ce02665d5a281f2c412456f2d1fa26586ef04a9adac9004ca7f913162cb28e13bf40d", 16));
+
+ //
+ // ca keys
+ //
+ RsaPublicKeyStructure caPubKeySpec = new RsaPublicKeyStructure(
+ new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16),
+ new BigInteger("11", 16));
+
+ RsaPrivateCrtKeyParameters caPrivKeySpec = new RsaPrivateCrtKeyParameters(
+ new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16),
+ new BigInteger("11", 16),
+ new BigInteger("92e08f83cc9920746989ca5034dcb384a094fb9c5a6288fcc4304424ab8f56388f72652d8fafc65a4b9020896f2cde297080f2a540e7b7ce5af0b3446e1258d1dd7f245cf54124b4c6e17da21b90a0ebd22605e6f45c9f136d7a13eaac1c0f7487de8bd6d924972408ebb58af71e76fd7b012a8d0e165f3ae2e5077a8648e619", 16),
+ new BigInteger("f75e80839b9b9379f1cf1128f321639757dba514642c206bbbd99f9a4846208b3e93fbbe5e0527cc59b1d4b929d9555853004c7c8b30ee6a213c3d1bb7415d03", 16),
+ new BigInteger("b892d9ebdbfc37e397256dd8a5d3123534d1f03726284743ddc6be3a709edb696fc40c7d902ed804c6eee730eee3d5b20bf6bd8d87a296813c87d3b3cc9d7947", 16),
+ new BigInteger("1d1a2d3ca8e52068b3094d501c9a842fec37f54db16e9a67070a8b3f53cc03d4257ad252a1a640eadd603724d7bf3737914b544ae332eedf4f34436cac25ceb5", 16),
+ new BigInteger("6c929e4e81672fef49d9c825163fec97c4b7ba7acb26c0824638ac22605d7201c94625770984f78a56e6e25904fe7db407099cad9b14588841b94f5ab498dded", 16),
+ new BigInteger("dae7651ee69ad1d081ec5e7188ae126f6004ff39556bde90e0b870962fa7b926d070686d8244fe5a9aa709a95686a104614834b0ada4b10f53197a5cb4c97339", 16));
+
+ //
+ // set up the keys
+ //
+ AsymmetricKeyParameter caPrivKey = caPrivKeySpec;
+ RsaKeyParameters caPubKey = new RsaKeyParameters(false, caPubKeySpec.Modulus, caPubKeySpec.PublicExponent);
+ AsymmetricKeyParameter intPrivKey = intPrivKeySpec;
+ RsaKeyParameters intPubKey = new RsaKeyParameters(false, intPubKeySpec.Modulus, intPubKeySpec.PublicExponent);
+ AsymmetricKeyParameter privKey = privKeySpec;
+ RsaKeyParameters pubKey = new RsaKeyParameters(false, pubKeySpec.Modulus, intPubKeySpec.PublicExponent);
+
+ X509Certificate trustCert = CreateTrustCert(caPubKey, caPrivKeySpec);
+ Asn1EncodableVector intPolicies = null;
+ Hashtable map = null;
+ Asn1EncodableVector policies = null;
+ ISet requirePolicies = null;
+ X509Certificate intCert = null;
+ X509Certificate endCert = null;
+
+ // valid test_00
+ intPolicies = new Asn1EncodableVector();
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.5.29.32.0")));
+ map = new Hashtable();
+ map["2.16.840.1.101.3.2.1.48.1"] = "2.16.840.1.101.3.2.1.48.2";
+ intCert = CreateIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map);
+
+ policies = new Asn1EncodableVector();
+ policies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.2")));
+ endCert = CreateEndEntityCert(pubKey, intPrivKey, intPubKey, policies);
+
+ requirePolicies = null;
+ string msg = TestPolicies(0, trustCert, intCert, endCert, requirePolicies, true);
+ CheckMessage(0, msg, "");
+
+ // test_01
+ intPolicies = new Asn1EncodableVector();
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.5.29.32.0")));
+ map = new Hashtable();
+ map["2.16.840.1.101.3.2.1.48.1"] = "2.16.840.1.101.3.2.1.48.2";
+ intCert = CreateIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map);
+
+ policies = new Asn1EncodableVector();
+ policies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.2")));
+ endCert = CreateEndEntityCert(pubKey, intPrivKey, intPubKey, policies);
+
+ requirePolicies = new HashSet();
+ requirePolicies.Add("2.16.840.1.101.3.2.1.48.1");
+ msg = TestPolicies(1, trustCert, intCert, endCert, requirePolicies, true);
+ CheckMessage(1, msg, "");
+
+ // test_02
+ intPolicies = new Asn1EncodableVector();
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.5.29.32.0")));
+ map = new Hashtable();
+ map["2.16.840.1.101.3.2.1.48.1"] = "2.16.840.1.101.3.2.1.48.2";
+ intCert = CreateIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map);
+
+ policies = new Asn1EncodableVector();
+ policies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.2")));
+ endCert = CreateEndEntityCert(pubKey, intPrivKey, intPubKey, policies);
+
+ requirePolicies = new HashSet();
+ requirePolicies.Add("2.5.29.32.0");
+ msg = TestPolicies(2, trustCert, intCert, endCert, requirePolicies, true);
+ CheckMessage(2, msg, "");
+
+ // test_03
+ intPolicies = new Asn1EncodableVector();
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.3")));
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.5.29.32.0")));
+ map = new Hashtable();
+ map["2.16.840.1.101.3.2.1.48.1"] = "2.16.840.1.101.3.2.1.48.2";
+ intCert = CreateIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map);
+
+ policies = new Asn1EncodableVector();
+ policies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.2")));
+ endCert = CreateEndEntityCert(pubKey, intPrivKey, intPubKey, policies);
+
+ requirePolicies = new HashSet();
+ requirePolicies.Add("2.16.840.1.101.3.2.1.48.1");
+ msg = TestPolicies(3, trustCert, intCert, endCert, requirePolicies, true);
+ CheckMessage(3, msg, "");
+
+ // test_04
+ intPolicies = new Asn1EncodableVector();
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.3")));
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.5.29.32.0")));
+ map = new Hashtable();
+ map["2.16.840.1.101.3.2.1.48.1"] = "2.16.840.1.101.3.2.1.48.2";
+ intCert = CreateIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map);
+
+ policies = new Asn1EncodableVector();
+ policies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.3")));
+ endCert = CreateEndEntityCert(pubKey, intPrivKey, intPubKey, policies);
+
+ requirePolicies = new HashSet();
+ requirePolicies.Add("2.16.840.1.101.3.2.1.48.3");
+ msg = TestPolicies(4, trustCert, intCert, endCert, requirePolicies, true);
+ CheckMessage(4, msg, "");
+
+ // test_05
+ intPolicies = new Asn1EncodableVector();
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.5.29.32.0")));
+ map = new Hashtable();
+ map["2.16.840.1.101.3.2.1.48.1"] = "2.16.840.1.101.3.2.1.48.2";
+ intCert = CreateIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map);
+
+ policies = new Asn1EncodableVector();
+ policies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.2")));
+ endCert = CreateEndEntityCert(pubKey, intPrivKey, intPubKey, policies);
+
+ requirePolicies = new HashSet();
+ requirePolicies.Add("2.16.840.1.101.3.2.1.48.2");
+ msg = TestPolicies(5, trustCert, intCert, endCert, requirePolicies, false);
+ CheckMessage(5, msg, "Path processing failed on policy.");
+
+ // test_06
+ intPolicies = new Asn1EncodableVector();
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.5.29.32.0")));
+ map = new Hashtable();
+ map["2.16.840.1.101.3.2.1.48.1"] = "2.16.840.1.101.3.2.1.48.2";
+ intCert = CreateIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map);
+
+ policies = new Asn1EncodableVector();
+ policies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.1")));
+ endCert = CreateEndEntityCert(pubKey, intPrivKey, intPubKey, policies);
+
+ requirePolicies = new HashSet();
+ requirePolicies.Add("2.16.840.1.101.3.2.1.48.1");
+ msg = TestPolicies(6, trustCert, intCert, endCert, requirePolicies, true);
+ CheckMessage(6, msg, "");
+
+ // test_07
+ intPolicies = new Asn1EncodableVector();
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.5.29.32.0")));
+ map = new Hashtable();
+ map["2.16.840.1.101.3.2.1.48.1"] = "2.16.840.1.101.3.2.1.48.2";
+ intCert = CreateIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map);
+
+ policies = new Asn1EncodableVector();
+ policies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.2")));
+ endCert = CreateEndEntityCert(pubKey, intPrivKey, intPubKey, policies);
+
+ requirePolicies = new HashSet();
+ requirePolicies.Add("2.16.840.1.101.3.2.1.48.3");
+ msg = TestPolicies(7, trustCert, intCert, endCert, requirePolicies, false);
+ CheckMessage(7, msg, "Path processing failed on policy.");
+
+ // test_08
+ intPolicies = new Asn1EncodableVector();
+ intPolicies.Add(new PolicyInformation(new DerObjectIdentifier("2.5.29.32.0")));
+ map = new Hashtable();
+ map["2.16.840.1.101.3.2.1.48.1"] = "2.16.840.1.101.3.2.1.48.2";
+ intCert = CreateIntmedCert(intPubKey, caPrivKey, caPubKey, intPolicies, map);
+
+ policies = new Asn1EncodableVector();
+ policies.Add(new PolicyInformation(new DerObjectIdentifier("2.16.840.1.101.3.2.1.48.3")));
+ endCert = CreateEndEntityCert(pubKey, intPrivKey, intPubKey, policies);
+
+ requirePolicies = new HashSet();
+ requirePolicies.Add("2.16.840.1.101.3.2.1.48.1");
+ msg = TestPolicies(8, trustCert, intCert, endCert, requirePolicies, false);
+ CheckMessage(8, msg, "Path processing failed on policy.");
+ }
+
+ private void CheckMessage(
+ int index,
+ string msg,
+ string expected)
+ {
+ if (!msg.Equals(expected))
+ {
+ Fail("test " + index + " failed got: " + msg + " expected: " + expected);
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new PkixPolicyMappingTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/test/PkixTest.cs b/crypto/test/src/test/PkixTest.cs
new file mode 100644
index 000000000..882319610
--- /dev/null
+++ b/crypto/test/src/test/PkixTest.cs
@@ -0,0 +1,248 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Tests
+{
+ [TestFixture]
+ public class PkixTest
+ : SimpleTest
+ {
+ /*
+ * The following certs and crls are described in:
+ * http://www.ietf.org/internet-drafts/draft-ietf-pkix-new-part1-08.txt
+ *
+ * This section contains four examples: three certificates and a CRL.
+ * The first two certificates and the CRL comprise a minimal
+ * certification path.
+ *
+ * Section C.1 contains an annotated hex dump of a "self-signed"
+ * certificate issued by a CA whose distinguished name is
+ * cn=us,o=gov,ou=nist. The certificate contains a DSA public key with
+ * parameters, and is signed by the corresponding DSA private key.
+ *
+ * Section C.2 contains an annotated hex dump of an end entity
+ * certificate. The end entity certificate contains a DSA public key,
+ * and is signed by the private key corresponding to the "self-signed"
+ * certificate in section C.1.
+ *
+ * Section C.3 contains a dump of an end entity certificate which
+ * contains an RSA public key and is signed with RSA and MD5. This
+ * certificate is not part of the minimal certification path.
+ *
+ * Section C.4 contains an annotated hex dump of a CRL. The CRL is
+ * issued by the CA whose distinguished name is cn=us,o=gov,ou=nist and
+ * the list of revoked certificates includes the end entity certificate
+ * presented in C.2.
+ */
+
+ /**
+ * C.1 Certificate
+ *
+ * This section contains an annotated hex dump of a 699 byte version 3
+ * certificate. The certificate contains the following information:
+ * (a) the serial number is 23 (17 hex);
+ * (b) the certificate is signed with DSA and the SHA-1 hash algorithm;
+ * (c) the issuer's distinguished name is OU=NIST; O=gov; C=US
+ * (d) and the subject's distinguished name is OU=NIST; O=gov; C=US
+ * (e) the certificate was issued on June 30, 1997 and will expire on
+ * December 31, 1997;
+ * (f) the certificate contains a 1024 bit DSA public key with
+ * parameters;
+ * (g) the certificate contains a subject key identifier extension
+ * generated using method (1) of section 4.2.1.2; and
+ * (h) the certificate is a CA certificate (as indicated through the
+ * basic constraints extension.)
+ */
+ static byte[] rootCertBin = Hex.Decode(
+ "308202bb3082027ba003020102020111300906072a8648ce380403302a310b30"
+ + "09060355040613025553310c300a060355040a1303676f76310d300b06035504"
+ + "0b13044e495354301e170d3937303633303030303030305a170d393731323331"
+ + "3030303030305a302a310b3009060355040613025553310c300a060355040a13"
+ + "03676f76310d300b060355040b13044e495354308201b83082012c06072a8648"
+ + "ce3804013082011f02818100b68b0f942b9acea525c6f2edfcfb9532ac011233"
+ + "b9e01cad909bbc48549ef394773c2c713555e6fe4f22cbd5d83e8993334dfcbd"
+ + "4f41643ea29870ec31b450deebf198280ac93e44b3fd22979683d018a3e3bd35"
+ + "5bffeea321726a7b96dab93f1e5a90af24d620f00d21a7d402b91afcac21fb9e"
+ + "949e4b42459e6ab24863fe43021500b20db0b101df0c6624fc1392ba55f77d57"
+ + "7481e5028181009abf46b1f53f443dc9a565fb91c08e47f10ac30147c2444236"
+ + "a99281de57c5e0688658007b1ff99b77a1c510a580917851513cf6fcfccc46c6"
+ + "817892843df4933d0c387e1a5b994eab1464f60c21224e28089c92b9669f40e8"
+ + "95f6d5312aef39a262c7b26d9e58c43aa81181846daff8b419b4c211aed0223b"
+ + "aa207fee1e57180381850002818100b59e1f490447d1dbf53addca0475e8dd75"
+ + "f69b8ab197d6596982d3034dfd3b365f4af2d14ec107f5d12ad378776356ea96"
+ + "614d420b7a1dfbab91a4cedeef77c8e5ef20aea62848afbe69c36aa530f2c2b9"
+ + "d9822b7dd9c4841fde0de854d71b992eb3d088f6d6639ba7e20e82d43b8a681b"
+ + "065631590b49eb99a5d581417bc955a3323030301d0603551d0e0416041486ca"
+ + "a5228162efad0a89bcad72412c2949f48656300f0603551d130101ff04053003"
+ + "0101ff300906072a8648ce380403032f00302c0214431bcf292545c04e52e77d"
+ + "d6fcb1664c83cf2d7702140b5b9a241198e8f3869004f608a9e18da5cc3ad4");
+
+
+ /**
+ * C.2 Certificate
+ *
+ * This section contains an annotated hex dump of a 730 byte version 3
+ * certificate. The certificate contains the following information:
+ * (a the serial number is 18 (12 hex);
+ * (b) the certificate is signed with DSA and the SHA-1 hash algorithm;
+ * (c) the issuer's distinguished name is OU=nist; O=gov; C=US
+ * (d) and the subject's distinguished name is CN=Tim Polk; OU=nist;
+ * O=gov; C=US
+ * (e) the certificate was valid from July 30, 1997 through December 1,
+ * 1997;
+ * (f) the certificate contains a 1024 bit DSA public key;
+ * (g) the certificate is an end entity certificate, as the basic
+ * constraints extension is not present;
+ * (h) the certificate contains an authority key identifier extension
+ * matching the subject key identifier of the certificate in Appendix
+ * C.1; and
+ * (i) the certificate includes one alternative name - an RFC 822
+ * address of "wpolk@nist.gov".
+ */
+ static byte[] userCert1Bin = Hex.Decode(
+ "308202da30820299a003020102020112300906072a8648ce380403302a310b30"
+ + "09060355040613025553310c300a060355040a1303676f76310d300b06035504"
+ + "0b13044e495354301e170d3937303733303030303030305a170d393731323031"
+ + "3030303030305a303d310b3009060355040613025553310c300a060355040a13"
+ + "03676f76310d300b060355040b13044e4953543111300f060355040313085469"
+ + "6d20506f6c6b308201b73082012c06072a8648ce3804013082011f02818100b6"
+ + "8b0f942b9acea525c6f2edfcfb9532ac011233b9e01cad909bbc48549ef39477"
+ + "3c2c713555e6fe4f22cbd5d83e8993334dfcbd4f41643ea29870ec31b450deeb"
+ + "f198280ac93e44b3fd22979683d018a3e3bd355bffeea321726a7b96dab93f1e"
+ + "5a90af24d620f00d21a7d402b91afcac21fb9e949e4b42459e6ab24863fe4302"
+ + "1500b20db0b101df0c6624fc1392ba55f77d577481e5028181009abf46b1f53f"
+ + "443dc9a565fb91c08e47f10ac30147c2444236a99281de57c5e0688658007b1f"
+ + "f99b77a1c510a580917851513cf6fcfccc46c6817892843df4933d0c387e1a5b"
+ + "994eab1464f60c21224e28089c92b9669f40e895f6d5312aef39a262c7b26d9e"
+ + "58c43aa81181846daff8b419b4c211aed0223baa207fee1e5718038184000281"
+ + "8030b675f77c2031ae38bb7e0d2baba09c4bdf20d524133ccd98e55f6cb7c1ba"
+ + "4abaa9958053f00d72dc3337f4010bf5041f9d2e1f62d8843a9b25095a2dc846"
+ + "8e2bd4f50d3bc72dc66cb998c1253a444e8eca9561357cce15315c23131ea205"
+ + "d17a241ccbd3720990ff9b9d28c0a10aec469f0db8d0dcd018a62b5ef98fb595"
+ + "bea33e303c30190603551d1104123010810e77706f6c6b406e6973742e676f76"
+ + "301f0603551d2304183016801486caa5228162efad0a89bcad72412c2949f486"
+ + "56300906072a8648ce380403033000302d02143697cbe3b42ce1bb61a9d3cc24"
+ + "cc22929ff4f587021500abc979afd2161ca9e368a91410b4a02eff225a73");
+
+ /**
+ * C.3 End Entity Certificate Using RSA
+ *
+ * This section contains an annotated hex dump of a 654 byte version 3
+ * certificate. The certificate contains the following information:
+ * (a) the serial number is 256;
+ * (b) the certificate is signed with RSA and the SHA-1 hash algorithm;
+ * (c) the issuer's distinguished name is OU=NIST; O=gov; C=US
+ * (d) and the subject's distinguished name is CN=Tim Polk; OU=NIST;
+ * O=gov; C=US
+ * (e) the certificate was issued on May 21, 1996 at 09:58:26 and
+ * expired on May 21, 1997 at 09:58:26;
+ * (f) the certificate contains a 1024 bit RSA public key;
+ * (g) the certificate is an end entity certificate (not a CA
+ * certificate);
+ * (h) the certificate includes an alternative subject name of
+ * "<http://www.itl.nist.gov/div893/staff/polk/index.html>" and an
+ * alternative issuer name of "<http://www.nist.gov/>" - both are URLs;
+ * (i) the certificate include an authority key identifier extension
+ * and a certificate policies extension psecifying the policy OID
+ * 2.16.840.1.101.3.2.1.48.9; and
+ * (j) the certificate includes a critical key usage extension
+ * specifying that the public key is intended for verification of
+ * digital signatures.
+ */
+ static byte[] userCert2Bin = Hex.Decode(
+ "3082028e308201f7a00302010202020100300d06092a864886f70d0101050500"
+ + "302a310b3009060355040613025553310c300a060355040b1303676f76310d30"
+ + "0b060355040a13044e495354301e170d3936303532313039353832365a170d39"
+ + "37303532313039353832365a303d310b3009060355040613025553310c300a06"
+ + "0355040b1303676f76310d300b060355040a13044e4953543111300f06035504"
+ + "03130854696d20506f6c6b30819f300d06092a864886f70d010101050003818d"
+ + "0030818902818100e16ae4033097023cf410f3b51e4d7f147bf6f5d078e9a48a"
+ + "f0a375ecedb656967f8899859af23e687787eb9ed19fc0b417dcab8923a41d7e"
+ + "16234c4fa84df531b87caae31a4909f44b26db2767308212014ae91ab6c10c53"
+ + "8b6cfc2f7a43ec33367e32b27bd5aacf0114c612ec13f22d147a8b215814134c"
+ + "46a39af21695ff230203010001a381af3081ac303f0603551d11043830368634"
+ + "687474703a2f2f7777772e69746c2e6e6973742e676f762f6469763839332f73"
+ + "746166662f706f6c6b2f696e6465782e68746d6c301f0603551d120418301686"
+ + "14687474703a2f2f7777772e6e6973742e676f762f301f0603551d2304183016"
+ + "80140868af8533c8394a7af882938e706a4a20842c3230170603551d20041030"
+ + "0e300c060a60864801650302013009300e0603551d0f0101ff04040302078030"
+ + "0d06092a864886f70d0101050500038181008e8e3656788bbfa13975172ee310"
+ + "dc832b6834521cf66c1d525e5420105e4ca940f94b729e82b961dceb32a5bdb1"
+ + "b148f99b01bbebaf9b83f6528cb06d7cd09a39543e6d206fcdd0debe275f204f"
+ + "b6ab0df5b7e1bab4dfdf3dd4f6ed01fb6ecb9859ac41fb489c1ff65b46e029e2"
+ + "76ecc43a0afc92c5c0d2a9c9d32952876533");
+
+ /**
+ * This section contains an annotated hex dump of a version 2 CRL with
+ * one extension (cRLNumber). The CRL was issued by OU=NIST; O=gov; C=US
+ * on August 7, 1997; the next scheduled issuance was September 7, 1997.
+ * The CRL includes one revoked certificates: serial number 18 (12 hex),
+ * which was revoked on July 31, 1997 due to keyCompromise. The CRL
+ * itself is number 18, and it was signed with DSA and SHA-1.
+ */
+ static byte[] crlBin = Hex.Decode(
+ "3081cb30818c020101300906072a8648ce380403302a310b3009060355040613025553310c300a060355040a1303676f76310d300b060355040b13044e495354170d3937303830373030303030305a170d3937303930373030303030305a30223020020112170d3937303733313030303030305a300c300a0603551d1504030a0101a00e300c300a0603551d14040302010c300906072a8648ce380403032f00302c0214224e9f43ba950634f2bb5e65dba68005c03a29470214591a57c982d7022114c3d40b321b9616b11f465a");
+
+ public override void PerformTest()
+ {
+ try
+ {
+ X509CertificateParser certParser = new X509CertificateParser();
+ X509CrlParser crlParser = new X509CrlParser();
+
+ X509Certificate rootCert = certParser.ReadCertificate(rootCertBin);
+ X509Certificate userCert1 = certParser.ReadCertificate(userCert1Bin);
+ X509Certificate userCert2 = certParser.ReadCertificate(userCert2Bin);
+
+ X509Crl crl = crlParser.ReadCrl(crlBin);
+
+ rootCert.Verify(rootCert.GetPublicKey());
+ userCert1.Verify(rootCert.GetPublicKey());
+
+ crl.Verify(rootCert.GetPublicKey());
+
+ if (!crl.IsRevoked(userCert1))
+ {
+ Fail(this.Name + ": usercert1 not revoked.");
+ }
+
+ if (crl.IsRevoked(userCert2))
+ {
+ Fail(this.Name + ": usercert2 revoked.");
+ }
+
+ }
+ catch (Exception e)
+ {
+ Fail(this.Name + ": exception - " + e.ToString());
+ }
+ }
+
+ public override String Name
+ {
+ get { return "PkixTest"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new PkixTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/test/RSATest.cs b/crypto/test/src/test/RSATest.cs
new file mode 100644
index 000000000..a765ff138
--- /dev/null
+++ b/crypto/test/src/test/RSATest.cs
@@ -0,0 +1,685 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.TeleTrust;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Tests
+{
+ [TestFixture]
+ public class RsaTest
+ : SimpleTest
+ {
+ /**
+ * a fake random number generator - we just want to make sure the random numbers
+ * aren't random so that we get the same output, while still getting to test the
+ * key generation facilities.
+ */
+ // TODO Use FixedSecureRandom instead?
+ private class MyFixedSecureRandom
+ : SecureRandom
+ {
+ byte[] seed =
+ {
+ (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59,
+ (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4,
+ (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde,
+ (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f
+ };
+
+ public override void NextBytes(
+ byte[] bytes)
+ {
+ int offset = 0;
+
+ while ((offset + seed.Length) < bytes.Length)
+ {
+ seed.CopyTo(bytes, offset);
+ offset += seed.Length;
+ }
+
+ Array.Copy(seed, 0, bytes, offset, bytes.Length - offset);
+ }
+ }
+
+ private static readonly byte[] seed =
+ {
+ (byte)0xaa, (byte)0xfd, (byte)0x12, (byte)0xf6, (byte)0x59,
+ (byte)0xca, (byte)0xe6, (byte)0x34, (byte)0x89, (byte)0xb4,
+ (byte)0x79, (byte)0xe5, (byte)0x07, (byte)0x6d, (byte)0xde,
+ (byte)0xc2, (byte)0xf0, (byte)0x6c, (byte)0xb5, (byte)0x8f
+ };
+
+ private RsaKeyParameters pubKeySpec = new RsaKeyParameters(
+ false,
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16));
+
+ private RsaPrivateCrtKeyParameters privKeySpec = new RsaPrivateCrtKeyParameters(
+ new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+ new BigInteger("11", 16),
+ new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+ new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+ new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+ new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+ new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+ new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+ private RsaKeyParameters isoPubKeySpec = new RsaKeyParameters(
+ false,
+ new BigInteger("0100000000000000000000000000000000bba2d15dbb303c8a21c5ebbcbae52b7125087920dd7cdf358ea119fd66fb064012ec8ce692f0a0b8e8321b041acd40b7", 16),
+ new BigInteger("03", 16));
+
+ private RsaKeyParameters isoPrivKeySpec = new RsaKeyParameters(
+ true,
+ new BigInteger("0100000000000000000000000000000000bba2d15dbb303c8a21c5ebbcbae52b7125087920dd7cdf358ea119fd66fb064012ec8ce692f0a0b8e8321b041acd40b7", 16),
+ new BigInteger("2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac9f0783a49dd5f6c5af651f4c9d0dc9281c96a3f16a85f9572d7cc3f2d0f25a9dbf1149e4cdc32273faadd3fda5dcda7", 16));
+
+ internal static RsaKeyParameters pub2048KeySpec = new RsaKeyParameters(
+ false,
+ new BigInteger("a7295693155b1813bb84877fb45343556e0568043de5910872a3a518cc11e23e2db74eaf4545068c4e3d258a2718fbacdcc3eafa457695b957e88fbf110aed049a992d9c430232d02f3529c67a3419935ea9b569f85b1bcd37de6b899cd62697e843130ff0529d09c97d813cb15f293751ff56f943fbdabb63971cc7f4f6d5bff1594416b1f5907bde5a84a44f9802ef29b43bda1960f948f8afb8766c1ab80d32eec88ed66d0b65aebe44a6d0b3c5e0ab051aaa1b912fbcc17b8e751ddecc5365b6db6dab0020c3057db4013a51213a5798a3aab67985b0f4d88627a54a0f3f0285fbcb4afdfeb65cb153af66825656d43238b75503231500753f4e421e3c57", 16),
+ new BigInteger("10001", 16));
+
+ internal static RsaPrivateCrtKeyParameters priv2048KeySpec = new RsaPrivateCrtKeyParameters(
+ new BigInteger("a7295693155b1813bb84877fb45343556e0568043de5910872a3a518cc11e23e2db74eaf4545068c4e3d258a2718fbacdcc3eafa457695b957e88fbf110aed049a992d9c430232d02f3529c67a3419935ea9b569f85b1bcd37de6b899cd62697e843130ff0529d09c97d813cb15f293751ff56f943fbdabb63971cc7f4f6d5bff1594416b1f5907bde5a84a44f9802ef29b43bda1960f948f8afb8766c1ab80d32eec88ed66d0b65aebe44a6d0b3c5e0ab051aaa1b912fbcc17b8e751ddecc5365b6db6dab0020c3057db4013a51213a5798a3aab67985b0f4d88627a54a0f3f0285fbcb4afdfeb65cb153af66825656d43238b75503231500753f4e421e3c57", 16),
+ new BigInteger("10001", 16),
+ new BigInteger("65dad56ac7df7abb434e4cb5eeadb16093aa6da7f0033aad3815289b04757d32bfee6ade7749c8e4a323b5050a2fb9e2a99e23469e1ed4ba5bab54336af20a5bfccb8b3424cc6923db2ffca5787ed87aa87aa614cd04cedaebc8f623a2d2063017910f436dff18bb06f01758610787f8b258f0a8efd8bd7de30007c47b2a1031696c7d6523bc191d4d918927a7e0b09584ed205bd2ff4fc4382678df82353f7532b3bbb81d69e3f39070aed3fb64fce032a089e8e64955afa5213a6eb241231bd98d702fba725a9b205952fda186412d9e0d9344d2998c455ad8c2bae85ee672751466d5288304032b5b7e02f7e558c7af82c7fbf58eea0bb4ef0f001e6cd0a9", 16),
+ new BigInteger("d4fd9ac3474fb83aaf832470643609659e511b322632b239b688f3cd2aad87527d6cf652fb9c9ca67940e84789444f2e99b0cb0cfabbd4de95396106c865f38e2fb7b82b231260a94df0e01756bf73ce0386868d9c41645560a81af2f53c18e4f7cdf3d51d80267372e6e0216afbf67f655c9450769cca494e4f6631b239ce1b", 16),
+ new BigInteger("c8eaa0e2a1b3a4412a702bccda93f4d150da60d736c99c7c566fdea4dd1b401cbc0d8c063daaf0b579953d36343aa18b33dbf8b9eae94452490cc905245f8f7b9e29b1a288bc66731a29e1dd1a45c9fd7f8238ff727adc49fff73991d0dc096206b9d3a08f61e7462e2b804d78cb8c5eccdb9b7fbd2ad6a8fea46c1053e1be75", 16),
+ new BigInteger("10edcb544421c0f9e123624d1099feeb35c72a8b34e008ac6fa6b90210a7543f293af4e5299c8c12eb464e70092805c7256e18e5823455ba0f504d36f5ccacac1b7cd5c58ff710f9c3f92646949d88fdd1e7ea5fed1081820bb9b0d2a8cd4b093fecfdb96dabd6e28c3a6f8c186dc86cddc89afd3e403e0fcf8a9e0bcb27af0b", 16),
+ new BigInteger("97fc25484b5a415eaa63c03e6efa8dafe9a1c8b004d9ee6e80548fefd6f2ce44ee5cb117e77e70285798f57d137566ce8ea4503b13e0f1b5ed5ca6942537c4aa96b2a395782a4cb5b58d0936e0b0fa63b1192954d39ced176d71ef32c6f42c84e2e19f9d4dd999c2151b032b97bd22aa73fd8c5bcd15a2dca4046d5acc997021", 16),
+ new BigInteger("4bb8064e1eff7e9efc3c4578fcedb59ca4aef0993a8312dfdcb1b3decf458aa6650d3d0866f143cbf0d3825e9381181170a0a1651eefcd7def786b8eb356555d9fa07c85b5f5cbdd74382f1129b5e36b4166b6cc9157923699708648212c484958351fdc9cf14f218dbe7fbf7cbd93a209a4681fe23ceb44bab67d66f45d1c9d", 16));
+
+ public override void PerformTest()
+ {
+ byte[] input = new byte[]
+ { (byte)0x54, (byte)0x85, (byte)0x9b, (byte)0x34, (byte)0x2c, (byte)0x49, (byte)0xea, (byte)0x2a };
+ byte[][] output = new byte[][]
+ {
+ Hex.Decode("8b427f781a2e59dd9def386f1956b996ee07f48c96880e65a368055ed8c0a8831669ef7250b40918b2b1d488547e72c84540e42bd07b03f14e226f04fbc2d929"),
+ Hex.Decode("2ec6e1a1711b6c7b8cd3f6a25db21ab8bb0a5f1d6df2ef375fa708a43997730ffc7c98856dbbe36edddcdd1b2d2a53867d8355af94fea3aeec128da908e08f4c"),
+ Hex.Decode("0850ac4e5a8118323200c8ed1e5aaa3d5e635172553ccac66a8e4153d35c79305c4440f11034ab147fccce21f18a50cf1c0099c08a577eb68237a91042278965"),
+ Hex.Decode("1c9649bdccb51056751fe43837f4eb43bada472accf26f65231666d5de7d11950d8379b3596dfdf75c6234274896fa8d18ad0865d3be2ac4d6687151abdf01e93941dcef18fa63186c9351d1506c89d09733c5ff4304208c812bdd21a50f56fde115e629e0e973721c9fcc87e89295a79853dee613962a0b2f2fc57163fd99057a3c776f13c20c26407eb8863998d7e53b543ba8d0a295a9a68d1a149833078c9809ad6a6dad7fc22a95ad615a73138c54c018f40d99bf8eeecd45f5be526f2d6b01aeb56381991c1ab31a2e756f15e052b9cd5638b2eff799795c5bae493307d5eb9f8c21d438de131fe505a4e7432547ab19224094f9e4be1968bd0793b79d"),
+ Hex.Decode("4c4afc0c24dddaedd4f9a3b23be30d35d8e005ffd36b3defc5d18acc830c3ed388ce20f43a00e614fd087c814197bc9fc2eff9ad4cc474a7a2ef3ed9c0f0a55eb23371e41ee8f2e2ed93ea3a06ca482589ab87e0d61dcffda5eea1241408e43ea1108726cdb87cc3aa5e9eaaa9f72507ca1352ac54a53920c94dccc768147933d8c50aefd9d1da10522a40133cd33dbc0524669e70f771a88d65c4716d471cd22b08b9f01f24e4e9fc7ffbcfa0e0a7aed47b345826399b26a73be112eb9c5e06fc6742fc3d0ef53d43896403c5105109cfc12e6deeaf4a48ba308e039774b9bdb31a9b9e133c81c321630cf0b4b2d1f90717b24c3268e1fea681ea9cdc709342"),
+ Hex.Decode("06b5b26bd13515f799e5e37ca43cace15cd82fd4bf36b25d285a6f0998d97c8cb0755a28f0ae66618b1cd03e27ac95eaaa4882bc6dc0078cd457d4f7de4154173a9c7a838cfc2ac2f74875df462aae0cfd341645dc51d9a01da9bdb01507f140fa8a016534379d838cc3b2a53ac33150af1b242fc88013cb8d914e66c8182864ee6de88ce2879d4c05dd125409620a96797c55c832fb2fb31d4310c190b8ed2c95fdfda2ed87f785002faaec3f35ec05cf70a3774ce185e4882df35719d582dd55ac31257344a9cba95189dcbea16e8c6cb7a235a0384bc83b6183ca8547e670fe33b1b91725ae0c250c9eca7b5ba78bd77145b70270bf8ac31653006c02ca9c"),
+ Hex.Decode("135f1be3d045526235bf9d5e43499d4ee1bfdf93370769ae56e85dbc339bc5b7ea3bee49717497ee8ac3f7cd6adb6fc0f17812390dcd65ac7b87fef7970d9ff9"),
+ Hex.Decode("03c05add1e030178c352face07cafc9447c8f369b8f95125c0d311c16b6da48ca2067104cce6cd21ae7b163cd18ffc13001aecebdc2eb02b9e92681f84033a98"),
+ Hex.Decode("00319bb9becb49f3ed1bca26d0fcf09b0b0a508e4d0bd43b350f959b72cd25b3af47d608fdcd248eada74fbe19990dbeb9bf0da4b4e1200243a14e5cab3f7e610c")
+ };
+ SecureRandom rand = new MyFixedSecureRandom();
+
+// KeyFactory fact = KeyFactory.GetInstance("RSA");
+//
+// PrivateKey privKey = fact.generatePrivate(privKeySpec);
+// PublicKey pubKey = fact.generatePublic(pubKeySpec);
+ AsymmetricKeyParameter privKey = privKeySpec;
+ AsymmetricKeyParameter pubKey = pubKeySpec;
+
+// PrivateKey priv2048Key = fact.generatePrivate(priv2048KeySpec);
+// PublicKey pub2048Key = fact.generatePublic(pub2048KeySpec);
+ AsymmetricKeyParameter priv2048Key = priv2048KeySpec;
+ AsymmetricKeyParameter pub2048Key = pub2048KeySpec;
+
+ //
+ // No Padding
+ //
+// Cipher c = Cipher.GetInstance("RSA");
+ IBufferedCipher c = CipherUtilities.GetCipher("RSA");
+
+// c.init(Cipher.ENCRYPT_MODE, pubKey, rand);
+ c.Init(true, pubKey);// new ParametersWithRandom(pubKey, rand));
+
+ byte[] outBytes = c.DoFinal(input);
+
+ if (!AreEqual(outBytes, output[0]))
+ {
+ Fail("NoPadding test failed on encrypt expected " + Hex.ToHexString(output[0]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+// c.init(Cipher.DECRYPT_MODE, privKey);
+ c.Init(false, privKey);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("NoPadding test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ //
+ // No Padding - incremental
+ //
+// c = Cipher.GetInstance("RSA");
+ c = CipherUtilities.GetCipher("RSA");
+
+// c.init(Cipher.ENCRYPT_MODE, pubKey, rand);
+ c.Init(true, pubKey);// new ParametersWithRandom(pubKey, rand));
+
+ c.ProcessBytes(input);
+
+ outBytes = c.DoFinal();
+
+ if (!AreEqual(outBytes, output[0]))
+ {
+ Fail("NoPadding test failed on encrypt expected " + Hex.ToHexString(output[0]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+// c.init(Cipher.DECRYPT_MODE, privKey);
+ c.Init(false, privKey);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("NoPadding test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ //
+ // No Padding - incremental - explicit use of NONE in mode.
+ //
+ c = CipherUtilities.GetCipher("RSA/NONE/NoPadding");
+
+// c.init(Cipher.ENCRYPT_MODE, pubKey, rand);
+ c.Init(true, pubKey);// new ParametersWithRandom(pubKey, rand));
+
+ c.ProcessBytes(input);
+
+ outBytes = c.DoFinal();
+
+ if (!AreEqual(outBytes, output[0]))
+ {
+ Fail("NoPadding test failed on encrypt expected " + Hex.ToHexString(output[0]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+// c.init(Cipher.DECRYPT_MODE, privKey);
+ c.Init(false, privKey);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("NoPadding test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ //
+ // No Padding - maximum.Length
+ //
+ c = CipherUtilities.GetCipher("RSA");
+
+ byte[] modBytes = ((RsaKeyParameters) pubKey).Modulus.ToByteArray();
+
+ byte[] maxInput = new byte[modBytes.Length - 1];
+
+ maxInput[0] |= 0x7f;
+
+ c.Init(true, pubKey);// new ParametersWithRandom(pubKey, rand));
+
+ outBytes = c.DoFinal(maxInput);
+
+ c.Init(false, privKey);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, maxInput))
+ {
+ Fail("NoPadding test failed on decrypt expected "
+ + Hex.ToHexString(maxInput) + " got "
+ + Hex.ToHexString(outBytes));
+ }
+
+ //
+ // PKCS1 V 1.5
+ //
+ c = CipherUtilities.GetCipher("RSA//PKCS1Padding");
+
+ c.Init(true, new ParametersWithRandom(pubKey, rand));
+
+ outBytes = c.DoFinal(input);
+
+ if (!AreEqual(outBytes, output[1]))
+ {
+ Fail("PKCS1 test failed on encrypt expected " + Hex.ToHexString(output[1]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ c.Init(false, privKey);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("PKCS1 test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ //
+ // PKCS1 V 1.5 - NONE
+ //
+ c = CipherUtilities.GetCipher("RSA/NONE/PKCS1Padding");
+
+ c.Init(true, new ParametersWithRandom(pubKey, rand));
+
+ outBytes = c.DoFinal(input);
+
+ if (!AreEqual(outBytes, output[1]))
+ {
+ Fail("PKCS1 test failed on encrypt expected " + Hex.ToHexString(output[1]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ c.Init(false, privKey);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("PKCS1 test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ //
+ // OAEP - SHA1
+ //
+ c = CipherUtilities.GetCipher("RSA/NONE/OAEPPadding");
+
+ c.Init(true, new ParametersWithRandom(pubKey, rand));
+
+ outBytes = c.DoFinal(input);
+
+ if (!AreEqual(outBytes, output[2]))
+ {
+ Fail("OAEP test failed on encrypt expected " + Hex.ToHexString(output[2]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ c = CipherUtilities.GetCipher("RSA/NONE/OAEPWithSHA1AndMGF1Padding");
+
+ c.Init(false, privKey);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("OAEP test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ // TODO
+// AlgorithmParameters oaepP = c.getParameters();
+ byte[] rop = new RsaesOaepParameters(
+ new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance)),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]))).GetEncoded();
+
+// if (!AreEqual(oaepP.getEncoded(), rop.getEncoded()))
+// {
+// Fail("OAEP test failed default sha-1 parameters");
+// }
+
+ //
+ // OAEP - SHA224
+ //
+ c = CipherUtilities.GetCipher("RSA/NONE/OAEPWithSHA224AndMGF1Padding");
+
+ c.Init(true, new ParametersWithRandom(pub2048Key, rand));
+
+ outBytes = c.DoFinal(input);
+
+ if (!AreEqual(outBytes, output[3]))
+ {
+ Fail("OAEP SHA-224 test failed on encrypt expected " + Hex.ToHexString(output[2]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ c.Init(false, priv2048Key);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("OAEP SHA-224 test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+// oaepP = c.getParameters();
+ rop = new RsaesOaepParameters(
+ new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance)),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]))).GetEncoded();
+
+// if (!AreEqual(oaepP.getEncoded(), rop.getEncoded())
+// {
+// Fail("OAEP test failed default sha-224 parameters");
+// }
+
+ //
+ // OAEP - SHA 256
+ //
+ c = CipherUtilities.GetCipher("RSA/NONE/OAEPWithSHA256AndMGF1Padding");
+
+ c.Init(true, new ParametersWithRandom(pub2048Key, rand));
+
+ outBytes = c.DoFinal(input);
+
+ if (!AreEqual(outBytes, output[4]))
+ {
+ Fail("OAEP SHA-256 test failed on encrypt expected " + Hex.ToHexString(output[2]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ c.Init(false, priv2048Key);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("OAEP SHA-256 test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+// oaepP = c.getParameters();
+ rop = new RsaesOaepParameters(
+ new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance)),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]))).GetEncoded();
+
+// if (!AreEqual(oaepP.getEncoded(), rop.getEncoded())
+// {
+// Fail("OAEP test failed default sha-256 parameters");
+// }
+
+ //
+ // OAEP - SHA 384
+ //
+ c = CipherUtilities.GetCipher("RSA/NONE/OAEPWithSHA384AndMGF1Padding");
+
+ c.Init(true, new ParametersWithRandom(pub2048Key, rand));
+
+ outBytes = c.DoFinal(input);
+
+ if (!AreEqual(outBytes, output[5]))
+ {
+ Fail("OAEP SHA-384 test failed on encrypt expected " + Hex.ToHexString(output[2]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ c.Init(false, priv2048Key);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("OAEP SHA-384 test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+// oaepP = c.getParameters();
+ rop = new RsaesOaepParameters(
+ new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance)),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]))).GetEncoded();
+
+// if (!AreEqual(oaepP.getEncoded(), rop.getEncoded())
+// {
+// Fail("OAEP test failed default sha-384 parameters");
+// }
+
+ //
+ // OAEP - MD5
+ //
+ c = CipherUtilities.GetCipher("RSA/NONE/OAEPWithMD5AndMGF1Padding");
+
+ c.Init(true, new ParametersWithRandom(pubKey, rand));
+
+ outBytes = c.DoFinal(input);
+
+ if (!AreEqual(outBytes, output[6]))
+ {
+ Fail("OAEP MD5 test failed on encrypt expected " + Hex.ToHexString(output[2]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ c.Init(false, privKey);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("OAEP MD5 test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+// oaepP = c.getParameters();
+ rop = new RsaesOaepParameters(
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.MD5, DerNull.Instance),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, new AlgorithmIdentifier(PkcsObjectIdentifiers.MD5, DerNull.Instance)),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]))).GetEncoded();
+
+// if (!AreEqual(oaepP.getEncoded(), rop.getEncoded())
+// {
+// Fail("OAEP test failed default md5 parameters");
+// }
+
+ //
+ // OAEP - SHA1 with default parameters
+ //
+ c = CipherUtilities.GetCipher("RSA/NONE/OAEPPadding");
+
+ // TODO
+// c.init(Cipher.ENCRYPT_MODE, pubKey, OAEPParameterSpec.DEFAULT, rand);
+//
+// outBytes = c.DoFinal(input);
+//
+// if (!AreEqual(outBytes, output[2]))
+// {
+// Fail("OAEP test failed on encrypt expected " + Encoding.ASCII.GetString(Hex.Encode(output[2])) + " got " + Encoding.ASCII.GetString(Hex.Encode(outBytes)));
+// }
+//
+// c = CipherUtilities.GetCipher("RSA/NONE/OAEPWithSHA1AndMGF1Padding");
+//
+// c.Init(false, privKey);
+//
+// outBytes = c.DoFinal(outBytes);
+//
+// if (!AreEqual(outBytes, input))
+// {
+// Fail("OAEP test failed on decrypt expected " + Encoding.ASCII.GetString(Hex.Encode(input)) + " got " + Encoding.ASCII.GetString(Hex.Encode(outBytes)));
+// }
+//
+// oaepP = c.getParameters();
+//
+// if (!AreEqual(oaepP.getEncoded(), new byte[] { 0x30, 0x00 }))
+// {
+// Fail("OAEP test failed default parameters");
+// }
+
+ //
+ // OAEP - SHA1 with specified string
+ //
+ c = CipherUtilities.GetCipher("RSA/NONE/OAEPPadding");
+
+ // TODO
+// c.init(Cipher.ENCRYPT_MODE, pubKey, new OAEPParameterSpec("SHA1", "MGF1", new MGF1ParameterSpec("SHA1"), new PSource.PSpecified(new byte[] { 1, 2, 3, 4, 5 })), rand);
+//
+// outBytes = c.DoFinal(input);
+//
+// oaepP = c.getParameters();
+ rop = new RsaesOaepParameters(
+ new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance)),
+ new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[] { 1, 2, 3, 4, 5 }))).GetEncoded();
+
+// if (!AreEqual(oaepP.getEncoded())
+// {
+// Fail("OAEP test failed changed sha-1 parameters");
+// }
+//
+// if (!AreEqual(outBytes, output[7]))
+// {
+// Fail("OAEP test failed on encrypt expected " + Encoding.ASCII.GetString(Hex.Encode(output[2])) + " got " + Encoding.ASCII.GetString(Hex.Encode(outBytes)));
+// }
+
+ c = CipherUtilities.GetCipher("RSA/NONE/OAEPWithSHA1AndMGF1Padding");
+
+ // TODO
+// c.init(Cipher.DECRYPT_MODE, privKey, oaepP);
+//
+// outBytes = c.DoFinal(outBytes);
+//
+// if (!AreEqual(outBytes, input))
+// {
+// Fail("OAEP test failed on decrypt expected " + Encoding.ASCII.GetString(Hex.Encode(input)) + " got " + Encoding.ASCII.GetString(Hex.Encode(outBytes)));
+// }
+
+ //
+ // iso9796-1
+ //
+ byte[] isoInput = Hex.Decode("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210");
+// PrivateKey isoPrivKey = fact.generatePrivate(isoPrivKeySpec);
+// PublicKey isoPubKey = fact.generatePublic(isoPubKeySpec);
+ AsymmetricKeyParameter isoPrivKey = isoPrivKeySpec;
+ AsymmetricKeyParameter isoPubKey = isoPubKeySpec;
+
+ c = CipherUtilities.GetCipher("RSA/NONE/ISO9796-1Padding");
+
+ c.Init(true, isoPrivKey);
+
+ outBytes = c.DoFinal(isoInput);
+
+ if (!AreEqual(outBytes, output[8]))
+ {
+ Fail("ISO9796-1 test failed on encrypt expected " + Hex.ToHexString(output[3]) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ c.Init(false, isoPubKey);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, isoInput))
+ {
+ Fail("ISO9796-1 test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ //
+ //
+ // generation with parameters test.
+ //
+ IAsymmetricCipherKeyPairGenerator keyPairGen = GeneratorUtilities.GetKeyPairGenerator("RSA");
+
+ //
+ // 768 bit RSA with e = 2^16-1
+ //
+ keyPairGen.Init(
+ new RsaKeyGenerationParameters(
+ BigInteger.ValueOf(0x10001),
+ new SecureRandom(),
+ 768,
+ 25));
+
+ AsymmetricCipherKeyPair kp = keyPairGen.GenerateKeyPair();
+
+ pubKey = kp.Public;
+ privKey = kp.Private;
+
+ c.Init(true, new ParametersWithRandom(pubKey, rand));
+
+ outBytes = c.DoFinal(input);
+
+ c.Init(false, privKey);
+
+ outBytes = c.DoFinal(outBytes);
+
+ if (!AreEqual(outBytes, input))
+ {
+ Fail("key generation test failed on decrypt expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(outBytes));
+ }
+
+ //
+ // comparison check
+ //
+// KeyFactory keyFact = KeyFactory.GetInstance("RSA");
+//
+// RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)keyFact.translateKey(privKey);
+ RsaPrivateCrtKeyParameters crtKey = (RsaPrivateCrtKeyParameters) privKey;
+
+ if (!privKey.Equals(crtKey))
+ {
+ Fail("private key equality check failed");
+ }
+
+// RSAPublicKey copyKey = (RSAPublicKey)keyFact.translateKey(pubKey);
+ RsaKeyParameters copyKey = (RsaKeyParameters) pubKey;
+
+ if (!pubKey.Equals(copyKey))
+ {
+ Fail("public key equality check failed");
+ }
+
+ SecureRandom random = new SecureRandom();
+ rawModeTest("SHA1withRSA", X509ObjectIdentifiers.IdSha1, priv2048Key, pub2048Key, random);
+ rawModeTest("MD5withRSA", PkcsObjectIdentifiers.MD5, priv2048Key, pub2048Key, random);
+ rawModeTest("RIPEMD128withRSA", TeleTrusTObjectIdentifiers.RipeMD128, priv2048Key, pub2048Key, random);
+ }
+
+ private void rawModeTest(string sigName, DerObjectIdentifier digestOID,
+ AsymmetricKeyParameter privKey, AsymmetricKeyParameter pubKey, SecureRandom random)
+ {
+ byte[] sampleMessage = new byte[1000 + random.Next() % 100];
+ random.NextBytes(sampleMessage);
+
+ ISigner normalSig = SignerUtilities.GetSigner(sigName);
+ normalSig.Init(true, privKey);
+ normalSig.BlockUpdate(sampleMessage, 0, sampleMessage.Length);
+ byte[] normalResult = normalSig.GenerateSignature();
+
+ byte[] hash = DigestUtilities.CalculateDigest(digestOID.Id, sampleMessage);
+ byte[] digInfo = derEncode(digestOID, hash);
+
+ ISigner rawSig = SignerUtilities.GetSigner("RSA");
+ rawSig.Init(true, privKey);
+ rawSig.BlockUpdate(digInfo, 0, digInfo.Length);
+ byte[] rawResult = rawSig.GenerateSignature();
+
+ if (!Arrays.AreEqual(normalResult, rawResult))
+ {
+ Fail("raw mode signature differs from normal one");
+ }
+
+ rawSig.Init(false, pubKey);
+ rawSig.BlockUpdate(digInfo, 0, digInfo.Length);
+
+ if (!rawSig.VerifySignature(rawResult))
+ {
+ Fail("raw mode signature verification failed");
+ }
+ }
+
+ private byte[] derEncode(DerObjectIdentifier oid, byte[] hash)
+ {
+ AlgorithmIdentifier algId = new AlgorithmIdentifier(oid, DerNull.Instance);
+ DigestInfo dInfo = new DigestInfo(algId, hash);
+
+ return dInfo.GetEncoded(Asn1Encodable.Der);
+ }
+
+ public override string Name
+ {
+ get { return "RSATest"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ ITest test = new RsaTest();
+ ITestResult result = test.Perform();
+
+ Console.WriteLine(result);
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/test/RegressionTest.cs b/crypto/test/src/test/RegressionTest.cs
new file mode 100644
index 000000000..0ffde72e4
--- /dev/null
+++ b/crypto/test/src/test/RegressionTest.cs
@@ -0,0 +1,80 @@
+using System;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Tests
+{
+ public class RegressionTest
+ {
+ // These tests were ported from org.bouncycastle.jce.provider.test in Java build
+ public static ITest[] tests = new ITest[]
+ {
+ new FipsDesTest(),
+ new DesEdeTest(),
+ new AesTest(),
+ new CamelliaTest(),
+ new SeedTest(),
+ new AesSicTest(),
+ new Gost28147Test(),
+ new PbeTest(),
+ new BlockCipherTest(),
+ new MacTest(),
+ new HMacTest(),
+// new SealedTest(),
+ new RsaTest(),
+ new DHTest(),
+ new DsaTest(),
+// new ImplicitlyCaTest(),
+ new ECNRTest(),
+ new ECDsa5Test(),
+ new Gost3410Test(),
+ new ElGamalTest(),
+ new IesTest(),
+ new SigTest(),
+ new AttrCertTest(),
+ new CertTest(),
+ new Pkcs10CertRequestTest(),
+ new EncryptedPrivateKeyInfoTest(), // Also in Org.BouncyCastle.Pkcs.Tests
+// new KeyStoreTest(),
+// new Pkcs12StoreTest(), // Already in Org.BouncyCastle.Pkcs.Tests
+ new DigestTest(),
+ new PssTest(),
+ new WrapTest(),
+// new DoFinalTest(),
+ new CipherStreamTest(),
+ new NamedCurveTest(),
+ new PkixTest(),
+// new NetscapeCertRequestTest(),
+ new X509StoreTest(),
+// new X509StreamParserTest(),
+ new X509CertificatePairTest(),
+ new CertPathTest(),
+// new CertStoreTest(),
+ new CertPathValidatorTest(),
+ new CertPathBuilderTest(),
+ new ECEncodingTest(),
+// new AlgorithmParametersTest(),
+ new NistCertPathTest(),
+ new PkixPolicyMappingTest(),
+// new SlotTwoTest(),
+ new PkixNameConstraintsTest(),
+ new NoekeonTest(),
+ new AttrCertSelectorTest(),
+// new SerialisationTest(),
+ new MqvTest(),
+ new CMacTest(),
+ new Crl5Test(),
+ };
+
+ public static void Main(
+ string[] args)
+ {
+ for (int i = 0; i != tests.Length; i++)
+ {
+ ITestResult result = tests[i].Perform();
+
+ Console.WriteLine(result);
+ }
+ }
+ }
+}
diff --git a/crypto/test/src/test/SEEDTest.cs b/crypto/test/src/test/SEEDTest.cs
new file mode 100644
index 000000000..2b380d5b7
--- /dev/null
+++ b/crypto/test/src/test/SEEDTest.cs
@@ -0,0 +1,190 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Kisa;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.IO;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Tests
+{
+ /// - * CMAC is analogous to OMAC1 - see also en.wikipedia.org/wiki/CMAC - *
- * CMAC is a NIST recomendation - see - * csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38B.pdf - *
- * CMAC/OMAC1 is a blockcipher-based message authentication code designed and - * analyzed by Tetsu Iwata and Kaoru Kurosawa. - *
- * CMAC/OMAC1 is a simple variant of the CBC MAC (Cipher Block Chaining Message - * Authentication Code). OMAC stands for One-Key CBC MAC. - *
- * It supports 128- or 64-bits block ciphers, with any key size, and returns - * a MAC with dimension less or equal to the block size of the underlying - * cipher. - *
- */ - public class CMac - : IMac - { - private const byte CONSTANT_128 = (byte)0x87; - private const byte CONSTANT_64 = (byte)0x1b; - - private byte[] ZEROES; - - private byte[] mac; - - private byte[] buf; - private int bufOff; - private IBlockCipher cipher; - - private int macSize; - - private byte[] L, Lu, Lu2; - - /** - * create a standard MAC based on a CBC block cipher (64 or 128 bit block). - * This will produce an authentication code the length of the block size - * of the cipher. - * - * @param cipher the cipher to be used as the basis of the MAC generation. - */ - public CMac( - IBlockCipher cipher) - : this(cipher, cipher.GetBlockSize() * 8) - { - } - - /** - * create a standard MAC based on a block cipher with the size of the - * MAC been given in bits. - * - * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), - * or 16 bits if being used as a data authenticator (FIPS Publication 113), - * and in general should be less than the size of the block cipher as it reduces - * the chance of an exhaustive attack (see Handbook of Applied Cryptography). - * - * @param cipher the cipher to be used as the basis of the MAC generation. - * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8 and @lt;= 128. - */ - public CMac( - IBlockCipher cipher, - int macSizeInBits) - { - if ((macSizeInBits % 8) != 0) - throw new ArgumentException("MAC size must be multiple of 8"); - - if (macSizeInBits > (cipher.GetBlockSize() * 8)) - { - throw new ArgumentException( - "MAC size must be less or equal to " - + (cipher.GetBlockSize() * 8)); - } - - if (cipher.GetBlockSize() != 8 && cipher.GetBlockSize() != 16) - { - throw new ArgumentException( - "Block size must be either 64 or 128 bits"); - } - - this.cipher = new CbcBlockCipher(cipher); - this.macSize = macSizeInBits / 8; - - mac = new byte[cipher.GetBlockSize()]; - - buf = new byte[cipher.GetBlockSize()]; - - ZEROES = new byte[cipher.GetBlockSize()]; - - bufOff = 0; - } - - public string AlgorithmName - { - get { return cipher.AlgorithmName; } - } - - private static byte[] doubleLu( - byte[] inBytes) - { - int FirstBit = (inBytes[0] & 0xFF) >> 7; - byte[] ret = new byte[inBytes.Length]; - for (int i = 0; i < inBytes.Length - 1; i++) - { - ret[i] = (byte)((inBytes[i] << 1) + ((inBytes[i + 1] & 0xFF) >> 7)); - } - ret[inBytes.Length - 1] = (byte)(inBytes[inBytes.Length - 1] << 1); - if (FirstBit == 1) - { - ret[inBytes.Length - 1] ^= inBytes.Length == 16 ? CONSTANT_128 : CONSTANT_64; - } - return ret; - } - - public void Init( - ICipherParameters parameters) - { - if (parameters != null) + /** + * CMAC - as specified at www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html + *+ * CMAC is analogous to OMAC1 - see also en.wikipedia.org/wiki/CMAC + *
+ * CMAC is a NIST recomendation - see + * csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38B.pdf + *
+ * CMAC/OMAC1 is a blockcipher-based message authentication code designed and + * analyzed by Tetsu Iwata and Kaoru Kurosawa. + *
+ * CMAC/OMAC1 is a simple variant of the CBC MAC (Cipher Block Chaining Message + * Authentication Code). OMAC stands for One-Key CBC MAC. + *
+ * It supports 128- or 64-bits block ciphers, with any key size, and returns + * a MAC with dimension less or equal to the block size of the underlying + * cipher. + *
+ */ + public class CMac + : IMac + { + private const byte CONSTANT_128 = (byte)0x87; + private const byte CONSTANT_64 = (byte)0x1b; + + private byte[] ZEROES; + + private byte[] mac; + + private byte[] buf; + private int bufOff; + private IBlockCipher cipher; + + private int macSize; + + private byte[] L, Lu, Lu2; + + /** + * create a standard MAC based on a CBC block cipher (64 or 128 bit block). + * This will produce an authentication code the length of the block size + * of the cipher. + * + * @param cipher the cipher to be used as the basis of the MAC generation. + */ + public CMac( + IBlockCipher cipher) + : this(cipher, cipher.GetBlockSize() * 8) + { + } + + /** + * create a standard MAC based on a block cipher with the size of the + * MAC been given in bits. + * + * Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), + * or 16 bits if being used as a data authenticator (FIPS Publication 113), + * and in general should be less than the size of the block cipher as it reduces + * the chance of an exhaustive attack (see Handbook of Applied Cryptography). + * + * @param cipher the cipher to be used as the basis of the MAC generation. + * @param macSizeInBits the size of the MAC in bits, must be a multiple of 8 and @lt;= 128. + */ + public CMac( + IBlockCipher cipher, + int macSizeInBits) + { + if ((macSizeInBits % 8) != 0) + throw new ArgumentException("MAC size must be multiple of 8"); + + if (macSizeInBits > (cipher.GetBlockSize() * 8)) + { + throw new ArgumentException( + "MAC size must be less or equal to " + + (cipher.GetBlockSize() * 8)); + } + + if (cipher.GetBlockSize() != 8 && cipher.GetBlockSize() != 16) + { + throw new ArgumentException( + "Block size must be either 64 or 128 bits"); + } + + this.cipher = new CbcBlockCipher(cipher); + this.macSize = macSizeInBits / 8; + + mac = new byte[cipher.GetBlockSize()]; + + buf = new byte[cipher.GetBlockSize()]; + + ZEROES = new byte[cipher.GetBlockSize()]; + + bufOff = 0; + } + + public string AlgorithmName + { + get { return cipher.AlgorithmName; } + } + + private static byte[] doubleLu( + byte[] inBytes) + { + int FirstBit = (inBytes[0] & 0xFF) >> 7; + byte[] ret = new byte[inBytes.Length]; + for (int i = 0; i < inBytes.Length - 1; i++) + { + ret[i] = (byte)((inBytes[i] << 1) + ((inBytes[i + 1] & 0xFF) >> 7)); + } + ret[inBytes.Length - 1] = (byte)(inBytes[inBytes.Length - 1] << 1); + if (FirstBit == 1) + { + ret[inBytes.Length - 1] ^= inBytes.Length == 16 ? CONSTANT_128 : CONSTANT_64; + } + return ret; + } + + public void Init( + ICipherParameters parameters) + { + if (parameters is KeyParameter) { cipher.Init(true, parameters); @@ -134,108 +135,113 @@ namespace Org.BouncyCastle.Crypto.Macs Lu = doubleLu(L); Lu2 = doubleLu(Lu); } + else if (parameters != null) + { + // CMAC mode does not permit IV to underlying CBC mode + throw new ArgumentException("CMac mode only permits key to be set.", "parameters"); + } Reset(); - } + } public int GetMacSize() - { - return macSize; - } - - public void Update( - byte input) - { - if (bufOff == buf.Length) - { - cipher.ProcessBlock(buf, 0, mac, 0); - bufOff = 0; - } - - buf[bufOff++] = input; - } - - public void BlockUpdate( - byte[] inBytes, - int inOff, - int len) - { - if (len < 0) - throw new ArgumentException("Can't have a negative input length!"); - - int blockSize = cipher.GetBlockSize(); - int gapLen = blockSize - bufOff; - - if (len > gapLen) - { - Array.Copy(inBytes, inOff, buf, bufOff, gapLen); - - cipher.ProcessBlock(buf, 0, mac, 0); - - bufOff = 0; - len -= gapLen; - inOff += gapLen; - - while (len > blockSize) - { - cipher.ProcessBlock(inBytes, inOff, mac, 0); - - len -= blockSize; - inOff += blockSize; - } - } - - Array.Copy(inBytes, inOff, buf, bufOff, len); - - bufOff += len; - } - - public int DoFinal( - byte[] outBytes, - int outOff) - { - int blockSize = cipher.GetBlockSize(); - - byte[] lu; - if (bufOff == blockSize) - { - lu = Lu; - } - else - { - new ISO7816d4Padding().AddPadding(buf, bufOff); - lu = Lu2; - } - - for (int i = 0; i < mac.Length; i++) - { - buf[i] ^= lu[i]; - } - - cipher.ProcessBlock(buf, 0, mac, 0); - - Array.Copy(mac, 0, outBytes, outOff, macSize); - - Reset(); - - return macSize; - } - - /** - * Reset the mac generator. - */ - public void Reset() - { - /* - * clean the buffer. - */ - Array.Clear(buf, 0, buf.Length); - bufOff = 0; - - /* - * Reset the underlying cipher. - */ - cipher.Reset(); - } - } + { + return macSize; + } + + public void Update( + byte input) + { + if (bufOff == buf.Length) + { + cipher.ProcessBlock(buf, 0, mac, 0); + bufOff = 0; + } + + buf[bufOff++] = input; + } + + public void BlockUpdate( + byte[] inBytes, + int inOff, + int len) + { + if (len < 0) + throw new ArgumentException("Can't have a negative input length!"); + + int blockSize = cipher.GetBlockSize(); + int gapLen = blockSize - bufOff; + + if (len > gapLen) + { + Array.Copy(inBytes, inOff, buf, bufOff, gapLen); + + cipher.ProcessBlock(buf, 0, mac, 0); + + bufOff = 0; + len -= gapLen; + inOff += gapLen; + + while (len > blockSize) + { + cipher.ProcessBlock(inBytes, inOff, mac, 0); + + len -= blockSize; + inOff += blockSize; + } + } + + Array.Copy(inBytes, inOff, buf, bufOff, len); + + bufOff += len; + } + + public int DoFinal( + byte[] outBytes, + int outOff) + { + int blockSize = cipher.GetBlockSize(); + + byte[] lu; + if (bufOff == blockSize) + { + lu = Lu; + } + else + { + new ISO7816d4Padding().AddPadding(buf, bufOff); + lu = Lu2; + } + + for (int i = 0; i < mac.Length; i++) + { + buf[i] ^= lu[i]; + } + + cipher.ProcessBlock(buf, 0, mac, 0); + + Array.Copy(mac, 0, outBytes, outOff, macSize); + + Reset(); + + return macSize; + } + + /** + * Reset the mac generator. + */ + public void Reset() + { + /* + * clean the buffer. + */ + Array.Clear(buf, 0, buf.Length); + bufOff = 0; + + /* + * Reset the underlying cipher. + */ + cipher.Reset(); + } + } } diff --git a/crypto/test/src/crypto/test/CMacTest.cs b/crypto/test/src/crypto/test/CMacTest.cs index 35f5735b9..d71b69f98 100644 --- a/crypto/test/src/crypto/test/CMacTest.cs +++ b/crypto/test/src/crypto/test/CMacTest.cs @@ -10,277 +10,293 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Crypto.Tests { - /** - * CMAC tester - Official Test Vectors. - */ - [TestFixture] - public class CMacTest - : SimpleTest - { - private static readonly byte[] keyBytes128 = Hex.Decode("2b7e151628aed2a6abf7158809cf4f3c"); - private static readonly byte[] keyBytes192 = Hex.Decode( - "8e73b0f7da0e6452c810f32b809079e5" - + "62f8ead2522c6b7b"); - private static readonly byte[] keyBytes256 = Hex.Decode( - "603deb1015ca71be2b73aef0857d7781" - + "1f352c073b6108d72d9810a30914dff4"); + /** + * CMAC tester - Official Test Vectors. + */ + [TestFixture] + public class CMacTest + : SimpleTest + { + private static readonly byte[] keyBytes128 = Hex.Decode("2b7e151628aed2a6abf7158809cf4f3c"); + private static readonly byte[] keyBytes192 = Hex.Decode( + "8e73b0f7da0e6452c810f32b809079e5" + + "62f8ead2522c6b7b"); + private static readonly byte[] keyBytes256 = Hex.Decode( + "603deb1015ca71be2b73aef0857d7781" + + "1f352c073b6108d72d9810a30914dff4"); - private static readonly byte[] input0 = Hex.Decode(""); - private static readonly byte[] input16 = Hex.Decode("6bc1bee22e409f96e93d7e117393172a"); - private static readonly byte[] input40 = Hex.Decode( - "6bc1bee22e409f96e93d7e117393172a" - + "ae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411"); - private static readonly byte[] input64 = Hex.Decode( - "6bc1bee22e409f96e93d7e117393172a" - + "ae2d8a571e03ac9c9eb76fac45af8e51" - + "30c81c46a35ce411e5fbc1191a0a52ef" - + "f69f2445df4f9b17ad2b417be66c3710"); + private static readonly byte[] input0 = Hex.Decode(""); + private static readonly byte[] input16 = Hex.Decode("6bc1bee22e409f96e93d7e117393172a"); + private static readonly byte[] input40 = Hex.Decode( + "6bc1bee22e409f96e93d7e117393172a" + + "ae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411"); + private static readonly byte[] input64 = Hex.Decode( + "6bc1bee22e409f96e93d7e117393172a" + + "ae2d8a571e03ac9c9eb76fac45af8e51" + + "30c81c46a35ce411e5fbc1191a0a52ef" + + "f69f2445df4f9b17ad2b417be66c3710"); - private static readonly byte[] output_k128_m0 = Hex.Decode("bb1d6929e95937287fa37d129b756746"); - private static readonly byte[] output_k128_m16 = Hex.Decode("070a16b46b4d4144f79bdd9dd04a287c"); - private static readonly byte[] output_k128_m40 = Hex.Decode("dfa66747de9ae63030ca32611497c827"); - private static readonly byte[] output_k128_m64 = Hex.Decode("51f0bebf7e3b9d92fc49741779363cfe"); + private static readonly byte[] output_k128_m0 = Hex.Decode("bb1d6929e95937287fa37d129b756746"); + private static readonly byte[] output_k128_m16 = Hex.Decode("070a16b46b4d4144f79bdd9dd04a287c"); + private static readonly byte[] output_k128_m40 = Hex.Decode("dfa66747de9ae63030ca32611497c827"); + private static readonly byte[] output_k128_m64 = Hex.Decode("51f0bebf7e3b9d92fc49741779363cfe"); - private static readonly byte[] output_k192_m0 = Hex.Decode("d17ddf46adaacde531cac483de7a9367"); - private static readonly byte[] output_k192_m16 = Hex.Decode("9e99a7bf31e710900662f65e617c5184"); - private static readonly byte[] output_k192_m40 = Hex.Decode("8a1de5be2eb31aad089a82e6ee908b0e"); - private static readonly byte[] output_k192_m64 = Hex.Decode("a1d5df0eed790f794d77589659f39a11"); + private static readonly byte[] output_k192_m0 = Hex.Decode("d17ddf46adaacde531cac483de7a9367"); + private static readonly byte[] output_k192_m16 = Hex.Decode("9e99a7bf31e710900662f65e617c5184"); + private static readonly byte[] output_k192_m40 = Hex.Decode("8a1de5be2eb31aad089a82e6ee908b0e"); + private static readonly byte[] output_k192_m64 = Hex.Decode("a1d5df0eed790f794d77589659f39a11"); - private static readonly byte[] output_k256_m0 = Hex.Decode("028962f61b7bf89efc6b551f4667d983"); - private static readonly byte[] output_k256_m16 = Hex.Decode("28a7023f452e8f82bd4bf28d8c37c35c"); - private static readonly byte[] output_k256_m40 = Hex.Decode("aaf3d8f1de5640c232f5b169b9c911e6"); - private static readonly byte[] output_k256_m64 = Hex.Decode("e1992190549f6ed5696a2c056c315410"); + private static readonly byte[] output_k256_m0 = Hex.Decode("028962f61b7bf89efc6b551f4667d983"); + private static readonly byte[] output_k256_m16 = Hex.Decode("28a7023f452e8f82bd4bf28d8c37c35c"); + private static readonly byte[] output_k256_m40 = Hex.Decode("aaf3d8f1de5640c232f5b169b9c911e6"); + private static readonly byte[] output_k256_m64 = Hex.Decode("e1992190549f6ed5696a2c056c315410"); - public CMacTest() - { - } + public CMacTest() + { + } - public override void PerformTest() - { - IBlockCipher cipher = new AesFastEngine(); - IMac mac = new CMac(cipher, 128); + public override void PerformTest() + { + IBlockCipher cipher = new AesFastEngine(); + IMac mac = new CMac(cipher, 128); - //128 bytes key + //128 bytes key - KeyParameter key = new KeyParameter(keyBytes128); + KeyParameter key = new KeyParameter(keyBytes128); - // 0 bytes message - 128 bytes key - mac.Init(key); + // 0 bytes message - 128 bytes key + mac.Init(key); - mac.BlockUpdate(input0, 0, input0.Length); + mac.BlockUpdate(input0, 0, input0.Length); - byte[] outBytes = new byte[16]; + byte[] outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k128_m0)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k128_m0) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k128_m0)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k128_m0) + " got " + + Hex.ToHexString(outBytes)); + } - // 16 bytes message - 128 bytes key - mac.Init(key); + // 16 bytes message - 128 bytes key + mac.Init(key); - mac.BlockUpdate(input16, 0, input16.Length); + mac.BlockUpdate(input16, 0, input16.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k128_m16)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k128_m16) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k128_m16)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k128_m16) + " got " + + Hex.ToHexString(outBytes)); + } - // 40 bytes message - 128 bytes key - mac.Init(key); + // 40 bytes message - 128 bytes key + mac.Init(key); - mac.BlockUpdate(input40, 0, input40.Length); + mac.BlockUpdate(input40, 0, input40.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k128_m40)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k128_m40) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k128_m40)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k128_m40) + " got " + + Hex.ToHexString(outBytes)); + } - // 64 bytes message - 128 bytes key - mac.Init(key); + // 64 bytes message - 128 bytes key + mac.Init(key); - mac.BlockUpdate(input64, 0, input64.Length); + mac.BlockUpdate(input64, 0, input64.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k128_m64)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k128_m64) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k128_m64)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k128_m64) + " got " + + Hex.ToHexString(outBytes)); + } - //192 bytes key - key = new KeyParameter(keyBytes192); + //192 bytes key + key = new KeyParameter(keyBytes192); - // 0 bytes message - 192 bytes key - mac.Init(key); + // 0 bytes message - 192 bytes key + mac.Init(key); - mac.BlockUpdate(input0, 0, input0.Length); + mac.BlockUpdate(input0, 0, input0.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k192_m0)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k192_m0) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k192_m0)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k192_m0) + " got " + + Hex.ToHexString(outBytes)); + } - // 16 bytes message - 192 bytes key - mac.Init(key); + // 16 bytes message - 192 bytes key + mac.Init(key); - mac.BlockUpdate(input16, 0, input16.Length); + mac.BlockUpdate(input16, 0, input16.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k192_m16)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k192_m16) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k192_m16)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k192_m16) + " got " + + Hex.ToHexString(outBytes)); + } - // 40 bytes message - 192 bytes key - mac.Init(key); + // 40 bytes message - 192 bytes key + mac.Init(key); - mac.BlockUpdate(input40, 0, input40.Length); + mac.BlockUpdate(input40, 0, input40.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k192_m40)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k192_m40) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k192_m40)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k192_m40) + " got " + + Hex.ToHexString(outBytes)); + } - // 64 bytes message - 192 bytes key - mac.Init(key); + // 64 bytes message - 192 bytes key + mac.Init(key); - mac.BlockUpdate(input64, 0, input64.Length); + mac.BlockUpdate(input64, 0, input64.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k192_m64)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k192_m64) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k192_m64)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k192_m64) + " got " + + Hex.ToHexString(outBytes)); + } - //256 bytes key + //256 bytes key - key = new KeyParameter(keyBytes256); + key = new KeyParameter(keyBytes256); - // 0 bytes message - 256 bytes key - mac.Init(key); + // 0 bytes message - 256 bytes key + mac.Init(key); - mac.BlockUpdate(input0, 0, input0.Length); + mac.BlockUpdate(input0, 0, input0.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k256_m0)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k256_m0) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k256_m0)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k256_m0) + " got " + + Hex.ToHexString(outBytes)); + } - // 16 bytes message - 256 bytes key - mac.Init(key); + // 16 bytes message - 256 bytes key + mac.Init(key); - mac.BlockUpdate(input16, 0, input16.Length); + mac.BlockUpdate(input16, 0, input16.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k256_m16)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k256_m16) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k256_m16)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k256_m16) + " got " + + Hex.ToHexString(outBytes)); + } - // 40 bytes message - 256 bytes key - mac.Init(key); + // 40 bytes message - 256 bytes key + mac.Init(key); - mac.BlockUpdate(input40, 0, input40.Length); + mac.BlockUpdate(input40, 0, input40.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k256_m40)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k256_m40) + " got " - + Hex.ToHexString(outBytes)); - } + if (!AreEqual(outBytes, output_k256_m40)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k256_m40) + " got " + + Hex.ToHexString(outBytes)); + } - // 64 bytes message - 256 bytes key - mac.Init(key); + // 64 bytes message - 256 bytes key + mac.Init(key); - mac.BlockUpdate(input64, 0, input64.Length); + mac.BlockUpdate(input64, 0, input64.Length); - outBytes = new byte[16]; + outBytes = new byte[16]; - mac.DoFinal(outBytes, 0); + mac.DoFinal(outBytes, 0); - if (!AreEqual(outBytes, output_k256_m64)) - { - Fail("Failed - expected " - + Hex.ToHexString(output_k256_m64) + " got " - + Hex.ToHexString(outBytes)); - } - } + if (!AreEqual(outBytes, output_k256_m64)) + { + Fail("Failed - expected " + + Hex.ToHexString(output_k256_m64) + " got " + + Hex.ToHexString(outBytes)); + } - public override string Name - { - get { return "CMac"; } - } + TestExceptions(); + } - public static void Main( - string[] args) - { - RunTest(new CMacTest()); - } + private void TestExceptions() + { + try + { + CMac mac = new CMac(new AesEngine()); + mac.Init(new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); + Fail("CMac does not accept IV"); + } + catch(ArgumentException) + { + // Expected + } + } - [Test] - public void TestFunction() - { - string resultText = Perform().ToString(); + public override string Name + { + get { return "CMac"; } + } - Assert.AreEqual(Name + ": Okay", resultText); - } - } + public static void Main( + string[] args) + { + RunTest(new CMacTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } } -- cgit 1.5.1 From 4e0d67b4ddcee08a49e8922159eebc6d11f2ae6d Mon Sep 17 00:00:00 2001 From: Tim Whittington+ * XSalsa20 requires a 256 bit key, and a 192 bit nonce. + */ + public class XSalsa20Engine + : Salsa20Engine + { + + public override string AlgorithmName + { + get { return "XSalsa20"; } + } + + protected override int NonceSize + { + get { return 24; } + } + + /** + * XSalsa20 key generation: process 256 bit input key and 128 bits of the input nonce + * using a core Salsa20 function without input addition to produce 256 bit working key + * and use that with the remaining 64 bits of nonce to initialize a standard Salsa20 engine state. + */ + protected override void SetKey(byte[] keyBytes, byte[] ivBytes) + { + if (keyBytes.Length != 32) + { + throw new ArgumentException(AlgorithmName + " requires a 256 bit key"); + } + + // Set key for HSalsa20 + base.SetKey(keyBytes, ivBytes); + + // Pack next 64 bits of IV into engine state instead of counter + engineState[8] = Pack.LE_To_UInt32(ivBytes, 8); + engineState[9] = Pack.LE_To_UInt32(ivBytes, 12); + + // Process engine state to generate Salsa20 key + uint[] hsalsa20Out = new uint[engineState.Length]; + SalsaCore(20, engineState, hsalsa20Out); + + // Set new key, removing addition in last round of salsaCore + engineState[1] = hsalsa20Out[0] - engineState[0]; + engineState[2] = hsalsa20Out[5] - engineState[5]; + engineState[3] = hsalsa20Out[10] - engineState[10]; + engineState[4] = hsalsa20Out[15] - engineState[15]; + + engineState[11] = hsalsa20Out[6] - engineState[6]; + engineState[12] = hsalsa20Out[7] - engineState[7]; + engineState[13] = hsalsa20Out[8] - engineState[8]; + engineState[14] = hsalsa20Out[9] - engineState[9]; + + // Last 64 bits of input IV + engineState[6] = Pack.LE_To_UInt32(ivBytes, 16); + engineState[7] = Pack.LE_To_UInt32(ivBytes, 20); + + // Counter reset + ResetCounter(); + } + + } +} + diff --git a/crypto/test/src/crypto/test/ChaChaTest.cs b/crypto/test/src/crypto/test/ChaChaTest.cs new file mode 100644 index 000000000..fea88ca85 --- /dev/null +++ b/crypto/test/src/crypto/test/ChaChaTest.cs @@ -0,0 +1,318 @@ +using System; + +using NUnit.Framework; + +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.Test; + +namespace Org.BouncyCastle.Crypto.Tests +{ + /** + * ChaCha Test + *
+ * Test cases generated using ref version of ChaCha20 in estreambench-20080905.
+ */
+ [TestFixture]
+ public class ChaChaTest
+ : SimpleTest
+ {
+ private static readonly byte[] zeroes = Hex.Decode(
+ "00000000000000000000000000000000"
+ + "00000000000000000000000000000000"
+ + "00000000000000000000000000000000"
+ + "00000000000000000000000000000000");
+
+ private static readonly string set1v0_0 =
+ "FBB87FBB8395E05DAA3B1D683C422046"
+ + "F913985C2AD9B23CFC06C1D8D04FF213"
+ + "D44A7A7CDB84929F915420A8A3DC58BF"
+ + "0F7ECB4B1F167BB1A5E6153FDAF4493D";
+
+ private static readonly string set1v0_192 =
+ "D9485D55B8B82D792ED1EEA8E93E9BC1"
+ + "E2834AD0D9B11F3477F6E106A2F6A5F2"
+ + "EA8244D5B925B8050EAB038F58D4DF57"
+ + "7FAFD1B89359DAE508B2B10CBD6B488E";
+
+ private static readonly string set1v0_256 =
+ "08661A35D6F02D3D9ACA8087F421F7C8"
+ + "A42579047D6955D937925BA21396DDD4"
+ + "74B1FC4ACCDCAA33025B4BCE817A4FBF"
+ + "3E5D07D151D7E6FE04934ED466BA4779";
+
+ private static readonly string set1v0_448 =
+ "A7E16DD38BA48CCB130E5BE9740CE359"
+ + "D631E91600F85C8A5D0785A612D1D987"
+ + "90780ACDDC26B69AB106CCF6D866411D"
+ + "10637483DBF08CC5591FD8B3C87A3AE0";
+
+ private static readonly string set1v9_0 =
+ "A276339F99316A913885A0A4BE870F06"
+ + "91E72B00F1B3F2239F714FE81E88E00C"
+ + "BBE52B4EBBE1EA15894E29658C4CB145"
+ + "E6F89EE4ABB045A78514482CE75AFB7C";
+
+ private static readonly string set1v9_192 =
+ "0DFB9BD4F87F68DE54FBC1C6428FDEB0"
+ + "63E997BE8490C9B7A4694025D6EBA2B1"
+ + "5FE429DB82A7CAE6AAB22918E8D00449"
+ + "6FB6291467B5AE81D4E85E81D8795EBB";
+
+ private static readonly string set1v9_256 =
+ "546F5BB315E7F71A46E56D4580F90889"
+ + "639A2BA528F757CF3B048738BA141AF3"
+ + "B31607CB21561BAD94721048930364F4"
+ + "B1227CFEB7CDECBA881FB44903550E68";
+
+ private static readonly string set1v9_448 =
+ "6F813586E76691305A0CF048C0D8586D"
+ + "C89460207D8B230CD172398AA33D19E9"
+ + "2D24883C3A9B0BB7CD8C6B2668DB142E"
+ + "37A97948A7A01498A21110297984CD20";
+
+ private static readonly string set6v0_0 =
+ "57459975BC46799394788DE80B928387"
+ + "862985A269B9E8E77801DE9D874B3F51"
+ + "AC4610B9F9BEE8CF8CACD8B5AD0BF17D"
+ + "3DDF23FD7424887EB3F81405BD498CC3";
+
+ private static readonly string set6v0_65472 =
+ "EF9AEC58ACE7DB427DF012B2B91A0C1E"
+ + "8E4759DCE9CDB00A2BD59207357BA06C"
+ + "E02D327C7719E83D6348A6104B081DB0"
+ + "3908E5186986AE41E3AE95298BB7B713";
+
+ private static readonly string set6v0_65536 =
+ "17EF5FF454D85ABBBA280F3A94F1D26E"
+ + "950C7D5B05C4BB3A78326E0DC5731F83"
+ + "84205C32DB867D1B476CE121A0D7074B"
+ + "AA7EE90525D15300F48EC0A6624BD0AF";
+
+ private static readonly string set6v1_0 =
+ "92A2508E2C4084567195F2A1005E552B"
+ + "4874EC0504A9CD5E4DAF739AB553D2E7"
+ + "83D79C5BA11E0653BEBB5C116651302E"
+ + "8D381CB728CA627B0B246E83942A2B99";
+
+ private static readonly string set6v1_65472 =
+ "E1974EC3063F7BD0CBA58B1CE34BC874"
+ + "67AAF5759B05EA46682A5D4306E5A76B"
+ + "D99A448DB8DE73AF97A73F5FBAE2C776"
+ + "35040464524CF14D7F08D4CE1220FD84";
+
+ private static readonly string set6v1_65536 =
+ "BE3436141CFD62D12FF7D852F80C1344"
+ + "81F152AD0235ECF8CA172C55CA8C031B"
+ + "2E785D773A988CA8D4BDA6FAE0E493AA"
+ + "71DCCC4C894D1F106CAC62A9FC0A9607";
+
+ // ChaCha12
+ private static readonly string chacha12_set1v0_0 =
+ "36CF0D56E9F7FBF287BC5460D95FBA94"
+ + "AA6CBF17D74E7C784DDCF7E0E882DDAE"
+ + "3B5A58243EF32B79A04575A8E2C2B73D"
+ + "C64A52AA15B9F88305A8F0CA0B5A1A25";
+
+ private static readonly string chacha12_set1v0_192 =
+ "83496792AB68FEC75ADB16D3044420A4"
+ + "A00A6E9ADC41C3A63DBBF317A8258C85"
+ + "A9BC08B4F76B413A4837324AEDF8BC2A"
+ + "67D53C9AB9E1C5BC5F379D48DF9AF730";
+
+ private static readonly string chacha12_set1v0_256 =
+ "BAA28ED593690FD760ADA07C95E3B888"
+ + "4B4B64E488CA7A2D9BDC262243AB9251"
+ + "394C5037E255F8BCCDCD31306C508FFB"
+ + "C9E0161380F7911FCB137D46D9269250";
+
+ private static readonly string chacha12_set1v0_448 =
+ "B7ECFB6AE0B51915762FE1FD03A14D0C"
+ + "9E54DA5DC76EB16EBA5313BC535DE63D"
+ + "C72D7F9F1874E301E99C8531819F4E37"
+ + "75793F6A5D19C717FA5C78A39EB804A6";
+
+ // ChaCha8
+ private static readonly string chacha8_set1v0_0 =
+ "BEB1E81E0F747E43EE51922B3E87FB38"
+ + "D0163907B4ED49336032AB78B67C2457"
+ + "9FE28F751BD3703E51D876C017FAA435"
+ + "89E63593E03355A7D57B2366F30047C5";
+
+ private static readonly string chacha8_set1v0_192 =
+ "33B8B7CA8F8E89F0095ACE75A379C651"
+ + "FD6BDD55703C90672E44C6BAB6AACDD8"
+ + "7C976A87FD264B906E749429284134C2"
+ + "38E3B88CF74A68245B860D119A8BDF43";
+
+ private static readonly string chacha8_set1v0_256 =
+ "F7CA95BF08688BD3BE8A27724210F9DC"
+ + "16F32AF974FBFB09E9F757C577A245AB"
+ + "F35F824B70A4C02CB4A8D7191FA8A5AD"
+ + "6A84568743844703D353B7F00A8601F4";
+
+ private static readonly string chacha8_set1v0_448 =
+ "7B4117E8BFFD595CD8482270B08920FB"
+ + "C9B97794E1809E07BB271BF07C861003"
+ + "4C38DBA6ECA04E5474F399A284CBF6E2"
+ + "7F70142E604D0977797DE5B58B6B25E0";
+
+ public override string Name
+ {
+ get { return "ChaCha"; }
+ }
+
+ public override void PerformTest()
+ {
+ chachaTest1(20, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+ set1v0_0, set1v0_192, set1v0_256, set1v0_448);
+ chachaTest1(20, new ParametersWithIV(new KeyParameter(Hex.Decode("00400000000000000000000000000000")), Hex.Decode("0000000000000000")),
+ set1v9_0, set1v9_192, set1v9_256, set1v9_448);
+ chachaTest1(12, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+ chacha12_set1v0_0, chacha12_set1v0_192, chacha12_set1v0_256, chacha12_set1v0_448);
+ chachaTest1(8, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+ chacha8_set1v0_0, chacha8_set1v0_192, chacha8_set1v0_256, chacha8_set1v0_448);
+ chachaTest2(new ParametersWithIV(new KeyParameter(Hex.Decode("0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D")), Hex.Decode("0D74DB42A91077DE")),
+ set6v0_0, set6v0_65472, set6v0_65536);
+ chachaTest2(new ParametersWithIV(new KeyParameter(Hex.Decode("0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12")), Hex.Decode("167DE44BB21980E7")),
+ set6v1_0, set6v1_65472, set6v1_65536);
+ reinitBug();
+ }
+
+ private void chachaTest1(
+ int rounds,
+ ICipherParameters parameters,
+ string v0,
+ string v192,
+ string v256,
+ string v448)
+ {
+ IStreamCipher salsa = new ChaChaEngine(rounds);
+ byte[] buf = new byte[64];
+
+ salsa.Init(true, parameters);
+
+ for (int i = 0; i != 7; i++)
+ {
+ salsa.ProcessBytes(zeroes, 0, 64, buf, 0);
+ switch (i)
+ {
+ case 0:
+ if (!AreEqual(buf, Hex.Decode(v0)))
+ {
+ mismatch("v0/" + rounds, v0, buf);
+ }
+ break;
+ case 3:
+ if (!AreEqual(buf, Hex.Decode(v192)))
+ {
+ mismatch("v192/" + rounds, v192, buf);
+ }
+ break;
+ case 4:
+ if (!AreEqual(buf, Hex.Decode(v256)))
+ {
+ mismatch("v256/" + rounds, v256, buf);
+ }
+ break;
+ default:
+ // ignore
+ break;
+ }
+ }
+
+ for (int i = 0; i != 64; i++)
+ {
+ buf[i] = salsa.ReturnByte(zeroes[i]);
+ }
+
+ if (!AreEqual(buf, Hex.Decode(v448)))
+ {
+ mismatch("v448", v448, buf);
+ }
+ }
+
+ private void chachaTest2(
+ ICipherParameters parameters,
+ string v0,
+ string v65472,
+ string v65536)
+ {
+ IStreamCipher salsa = new ChaChaEngine();
+ byte[] buf = new byte[64];
+
+ salsa.Init(true, parameters);
+
+ for (int i = 0; i != 1025; i++)
+ {
+ salsa.ProcessBytes(zeroes, 0, 64, buf, 0);
+ switch (i)
+ {
+ case 0:
+ if (!AreEqual(buf, Hex.Decode(v0)))
+ {
+ mismatch("v0", v0, buf);
+ }
+ break;
+ case 1023:
+ if (!AreEqual(buf, Hex.Decode(v65472)))
+ {
+ mismatch("v65472", v65472, buf);
+ }
+ break;
+ case 1024:
+ if (!AreEqual(buf, Hex.Decode(v65536)))
+ {
+ mismatch("v65536", v65536, buf);
+ }
+ break;
+ default:
+ // ignore
+ break;
+ }
+ }
+ }
+
+ private void mismatch(
+ string name,
+ string expected,
+ byte[] found)
+ {
+ Fail("mismatch on " + name, expected, Hex.ToHexString(found));
+ }
+
+ private void reinitBug()
+ {
+ KeyParameter key = new KeyParameter(Hex.Decode("80000000000000000000000000000000"));
+ ParametersWithIV parameters = new ParametersWithIV(key, Hex.Decode("0000000000000000"));
+
+ IStreamCipher chacha = new ChaChaEngine();
+
+ chacha.Init(true, parameters);
+
+ try
+ {
+ chacha.Init(true, key);
+ Fail("ChaCha should throw exception if no IV in Init");
+ }
+ catch (ArgumentException)
+ {
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new ChaChaTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
diff --git a/crypto/test/src/crypto/test/RegressionTest.cs b/crypto/test/src/crypto/test/RegressionTest.cs
index 687e9ee4f..3a21f3656 100644
--- a/crypto/test/src/crypto/test/RegressionTest.cs
+++ b/crypto/test/src/crypto/test/RegressionTest.cs
@@ -94,7 +94,9 @@ namespace Org.BouncyCastle.Crypto.Tests
new Rfc3211WrapTest(),
new SeedTest(),
new NaccacheSternTest(),
- new Salsa20Test(),
+ new Salsa20Test(),
+ new XSalsa20Test(),
+ new ChaChaTest(),
new CMacTest(),
new EaxTest(),
new GcmTest(),
diff --git a/crypto/test/src/crypto/test/Salsa20Test.cs b/crypto/test/src/crypto/test/Salsa20Test.cs
index 9e7549ae7..b4dc1ef2b 100644
--- a/crypto/test/src/crypto/test/Salsa20Test.cs
+++ b/crypto/test/src/crypto/test/Salsa20Test.cs
@@ -106,6 +106,58 @@ namespace Org.BouncyCastle.Crypto.Tests
+ "C945A6CC69A6A17367BC03431A86B3ED"
+ "04B0245B56379BF997E25800AD837D7D";
+ // Salsa20/12
+
+ private static readonly string salsa12_set1v0_0 =
+ "FC207DBFC76C5E1774961E7A5AAD0906"
+ + "9B2225AC1CE0FE7A0CE77003E7E5BDF8"
+ + "B31AF821000813E6C56B8C1771D6EE70"
+ + "39B2FBD0A68E8AD70A3944B677937897";
+
+ private static readonly string salsa12_set1v0_192 =
+ "4B62A4881FA1AF9560586510D5527ED4"
+ + "8A51ECAFA4DECEEBBDDC10E9918D44AB"
+ + "26B10C0A31ED242F146C72940C6E9C37"
+ + "53F641DA84E9F68B4F9E76B6C48CA5AC";
+
+ private static readonly string salsa12_set1v0_256 =
+ "F52383D9DEFB20810325F7AEC9EADE34"
+ + "D9D883FEE37E05F74BF40875B2D0BE79"
+ + "ED8886E5BFF556CEA8D1D9E86B1F68A9"
+ + "64598C34F177F8163E271B8D2FEB5996";
+
+ private static readonly string salsa12_set1v0_448 =
+ "A52ED8C37014B10EC0AA8E05B5CEEE12"
+ + "3A1017557FB3B15C53E6C5EA8300BF74"
+ + "264A73B5315DC821AD2CAB0F3BB2F152"
+ + "BDAEA3AEE97BA04B8E72A7B40DCC6BA4";
+
+ // Salsa20/8
+
+ private static readonly string salsa8_set1v0_0 =
+ "A9C9F888AB552A2D1BBFF9F36BEBEB33"
+ + "7A8B4B107C75B63BAE26CB9A235BBA9D"
+ + "784F38BEFC3ADF4CD3E266687EA7B9F0"
+ + "9BA650AE81EAC6063AE31FF12218DDC5";
+
+ private static readonly string salsa8_set1v0_192 =
+ "BB5B6BB2CC8B8A0222DCCC1753ED4AEB"
+ + "23377ACCBD5D4C0B69A8A03BB115EF71"
+ + "871BC10559080ACA7C68F0DEF32A80DD"
+ + "BAF497259BB76A3853A7183B51CC4B9F";
+
+ private static readonly string salsa8_set1v0_256 =
+ "4436CDC0BE39559F5E5A6B79FBDB2CAE"
+ + "4782910F27FFC2391E05CFC78D601AD8"
+ + "CD7D87B074169361D997D1BED9729C0D"
+ + "EB23418E0646B7997C06AA84E7640CE3";
+
+ private static readonly string salsa8_set1v0_448 =
+ "BEE85903BEA506B05FC04795836FAAAC"
+ + "7F93F785D473EB762576D96B4A65FFE4"
+ + "63B34AAE696777FC6351B67C3753B89B"
+ + "A6B197BD655D1D9CA86E067F4D770220";
+
public override string Name
{
get { return "Salsa20"; }
@@ -113,10 +165,14 @@ namespace Org.BouncyCastle.Crypto.Tests
public override void PerformTest()
{
- salsa20Test1(new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+ salsa20Test1(20, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
set1v0_0, set1v0_192, set1v0_256, set1v0_448);
- salsa20Test1(new ParametersWithIV(new KeyParameter(Hex.Decode("00400000000000000000000000000000")), Hex.Decode("0000000000000000")),
+ salsa20Test1(20, new ParametersWithIV(new KeyParameter(Hex.Decode("00400000000000000000000000000000")), Hex.Decode("0000000000000000")),
set1v9_0, set1v9_192, set1v9_256, set1v9_448);
+ salsa20Test1(12, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+ salsa12_set1v0_0, salsa12_set1v0_192, salsa12_set1v0_256, salsa12_set1v0_448);
+ salsa20Test1(8, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
+ salsa8_set1v0_0, salsa8_set1v0_192, salsa8_set1v0_256, salsa8_set1v0_448);
salsa20Test2(new ParametersWithIV(new KeyParameter(Hex.Decode("0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D")), Hex.Decode("0D74DB42A91077DE")),
set6v0_0, set6v0_65472, set6v0_65536);
salsa20Test2(new ParametersWithIV(new KeyParameter(Hex.Decode("0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12")), Hex.Decode("167DE44BB21980E7")),
@@ -125,13 +181,14 @@ namespace Org.BouncyCastle.Crypto.Tests
}
private void salsa20Test1(
+ int rounds,
ICipherParameters parameters,
string v0,
string v192,
string v256,
string v448)
{
- IStreamCipher salsa = new Salsa20Engine();
+ IStreamCipher salsa = new Salsa20Engine(rounds);
byte[] buf = new byte[64];
salsa.Init(true, parameters);
@@ -144,19 +201,19 @@ namespace Org.BouncyCastle.Crypto.Tests
case 0:
if (!AreEqual(buf, Hex.Decode(v0)))
{
- mismatch("v0", v0, buf);
+ mismatch("v0/" + rounds, v0, buf);
}
break;
case 3:
if (!AreEqual(buf, Hex.Decode(v192)))
{
- mismatch("v192", v192, buf);
+ mismatch("v192/" + rounds, v192, buf);
}
break;
case 4:
if (!AreEqual(buf, Hex.Decode(v256)))
{
- mismatch("v256", v256, buf);
+ mismatch("v256/" + rounds, v256, buf);
}
break;
default:
diff --git a/crypto/test/src/crypto/test/XSalsa20Test.cs b/crypto/test/src/crypto/test/XSalsa20Test.cs
new file mode 100644
index 000000000..74ed04e88
--- /dev/null
+++ b/crypto/test/src/crypto/test/XSalsa20Test.cs
@@ -0,0 +1,183 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Crypto.Tests
+{
+ /**
+ * XSalsa20 Test
+ */
+ [TestFixture]
+ public class XSalsa20Test
+ : SimpleTest
+ {
+ private class TestCase
+ {
+
+ private byte[] key;
+ private byte[] iv;
+ private byte[] plaintext;
+ private byte[] ciphertext;
+
+ public TestCase(String key, string iv, string plaintext, string ciphertext)
+ {
+ this.key = Hex.Decode(key);
+ this.iv = Hex.Decode(iv);
+ this.plaintext = Hex.Decode(plaintext);
+ this.ciphertext = Hex.Decode(ciphertext);
+ }
+
+ public byte[] Key
+ {
+ get { return key; }
+ }
+
+ public byte[] Iv
+ {
+ get { return iv; }
+ }
+
+ public byte[] Plaintext
+ {
+ get { return plaintext; }
+ }
+
+ public byte[] Ciphertext
+ {
+ get { return ciphertext; }
+ }
+ }
+
+ // Test cases generated by naclcrypto-20090308, as used by cryptopp
+ private static readonly TestCase[] TEST_CASES = new TestCase[] {
+ new TestCase(
+ "a6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff88030",
+ "9e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c",
+ "093c5e5585579625337bd3ab619d615760d8c5b224a85b1d0efe0eb8a7ee163abb0376529fcc09bab506c618e13ce777d82c3ae9d1a6f972d4160287cbfe60bf2130fc0a6ff6049d0a5c8a82f429231f008082e845d7e189d37f9ed2b464e6b919e6523a8c1210bd52a02a4c3fe406d3085f5068d1909eeeca6369abc981a42e87fe665583f0ab85ae71f6f84f528e6b397af86f6917d9754b7320dbdc2fea81496f2732f532ac78c4e9c6cfb18f8e9bdf74622eb126141416776971a84f94d156beaf67aecbf2ad412e76e66e8fad7633f5b6d7f3d64b5c6c69ce29003c6024465ae3b89be78e915d88b4b5621d",
+ "b2af688e7d8fc4b508c05cc39dd583d6714322c64d7f3e63147aede2d9534934b04ff6f337b031815cd094bdbc6d7a92077dce709412286822ef0737ee47f6b7ffa22f9d53f11dd2b0a3bb9fc01d9a88f9d53c26e9365c2c3c063bc4840bfc812e4b80463e69d179530b25c158f543191cff993106511aa036043bbc75866ab7e34afc57e2cce4934a5faae6eabe4f221770183dd060467827c27a354159a081275a291f69d946d6fe28ed0b9ce08206cf484925a51b9498dbde178ddd3ae91a8581b91682d860f840782f6eea49dbb9bd721501d2c67122dea3b7283848c5f13e0c0de876bd227a856e4de593a3"),
+ new TestCase(
+ "9e1da239d155f52ad37f75c7368a536668b051952923ad44f57e75ab588e475a",
+ "af06f17859dffa799891c4288f6635b5c5a45eee9017fd72",
+ "feac9d54fc8c115ae247d9a7e919dd76cfcbc72d32cae4944860817cbdfb8c04e6b1df76a16517cd33ccf1acda9206389e9e318f5966c093cfb3ec2d9ee2de856437ed581f552f26ac2907609df8c613b9e33d44bfc21ff79153e9ef81a9d66cc317857f752cc175fd8891fefebb7d041e6517c3162d197e2112837d3bc4104312ad35b75ea686e7c70d4ec04746b52ff09c421451459fb59f",
+ "2c261a2f4e61a62e1b27689916bf03453fcbc97bb2af6f329391ef063b5a219bf984d07d70f602d85f6db61474e9d9f5a2deecb4fcd90184d16f3b5b5e168ee03ea8c93f3933a22bc3d1a5ae8c2d8b02757c87c073409052a2a8a41e7f487e041f9a49a0997b540e18621cad3a24f0a56d9b19227929057ab3ba950f6274b121f193e32e06e5388781a1cb57317c0ba6305e910961d01002f0"),
+ new TestCase("d5c7f6797b7e7e9c1d7fd2610b2abf2bc5a7885fb3ff78092fb3abe8986d35e2",
+ "744e17312b27969d826444640e9c4a378ae334f185369c95",
+ "7758298c628eb3a4b6963c5445ef66971222be5d1a4ad839715d1188071739b77cc6e05d5410f963a64167629757",
+ "27b8cfe81416a76301fd1eec6a4d99675069b2da2776c360db1bdfea7c0aa613913e10f7a60fec04d11e65f2d64e"),
+ new TestCase(
+ "737d7811ce96472efed12258b78122f11deaec8759ccbd71eac6bbefa627785c",
+ "6fb2ee3dda6dbd12f1274f126701ec75c35c86607adb3edd",
+ "501325fb2645264864df11faa17bbd58312b77cad3d94ac8fb8542f0eb653ad73d7fce932bb874cb89ac39fc47f8267cf0f0c209f204b2d8578a3bdf461cb6a271a468bebaccd9685014ccbc9a73618c6a5e778a21cc8416c60ad24ddc417a130d53eda6dfbfe47d09170a7be1a708b7b5f3ad464310be36d9a2a95dc39e83d38667e842eb6411e8a23712297b165f690c2d7ca1b1346e3c1fccf5cafd4f8be0",
+ "6724c372d2e9074da5e27a6c54b2d703dc1d4c9b1f8d90f00c122e692ace7700eadca942544507f1375b6581d5a8fb39981c1c0e6e1ff2140b082e9ec016fce141d5199647d43b0b68bfd0fea5e00f468962c7384dd6129aea6a3fdfe75abb210ed5607cef8fa0e152833d5ac37d52e557b91098a322e76a45bbbcf4899e790618aa3f4c2e5e0fc3de93269a577d77a5502e8ea02f717b1dd2df1ec69d8b61ca"),
+ new TestCase(
+ "760158da09f89bbab2c99e6997f9523a95fcef10239bcca2573b7105f6898d34",
+ "43636b2cc346fc8b7c85a19bf507bdc3dafe953b88c69dba",
+ "d30a6d42dff49f0ed039a306bae9dec8d9e88366cc19e8c3642fd58fa0794ebf8029d949730339b0823a51f0f49f0d2c71f1051c1e0e2c86941f172789cdb1b0107413e70f982ff9761877bb526ef1c3eb1106a948d60ef21bd35d32cfd64f89b79ed63ecc5cca56246af736766f285d8e6b0da9cb1cd21020223ffacc5a32",
+ "c815b6b79b64f9369aec8dce8c753df8a50f2bc97c70ce2f014db33a65ac5816bac9e30ac08bdded308c65cb87e28e2e71b677dc25c5a6499c1553555daf1f55270a56959dffa0c66f24e0af00951ec4bb59ccc3a6c5f52e0981647e53e439313a52c40fa7004c855b6e6eb25b212a138e843a9ba46edb2a039ee82a263abe"),
+ new TestCase(
+ "27ba7e81e7edd4e71be53c07ce8e633138f287e155c7fa9e84c4ad804b7fa1b9",
+ "ea05f4ebcd2fb6b000da0612861ba54ff5c176fb601391aa",
+ "e09ff5d2cb050d69b2d42494bde5825238c756d6991d99d7a20d1ef0b83c371c89872690b2fc11d5369f4fc4971b6d3d6c078aef9b0f05c0e61ab89c025168054defeb03fef633858700c58b1262ce011300012673e893e44901dc18eee3105699c44c805897bdaf776af1833162a21a",
+ "a23e7ef93c5d0667c96d9e404dcbe6be62026fa98f7a3ff9ba5d458643a16a1cef7272dc6097a9b52f35983557c77a11b314b4f7d5dc2cca15ee47616f861873cbfed1d32372171a61e38e447f3cf362b3abbb2ed4170d89dcb28187b7bfd206a3e026f084a7e0ed63d319de6bc9afc0"),
+ new TestCase("6799d76e5ffb5b4920bc2768bafd3f8c16554e65efcf9a16f4683a7a06927c11",
+ "61ab951921e54ff06d9b77f313a4e49df7a057d5fd627989", "472766", "8fd7df"),
+ new TestCase(
+ "f68238c08365bb293d26980a606488d09c2f109edafa0bbae9937b5cc219a49c",
+ "5190b51e9b708624820b5abdf4e40fad1fb950ad1adc2d26",
+ "47ec6b1f73c4b7ff5274a0bfd7f45f864812c85a12fbcb3c2cf8a3e90cf66ccf2eacb521e748363c77f52eb426ae57a0c6c78f75af71284569e79d1a92f949a9d69c4efc0b69902f1e36d7562765543e2d3942d9f6ff5948d8a312cff72c1afd9ea3088aff7640bfd265f7a9946e606abc77bcedae6bddc75a0dba0bd917d73e3bd1268f727e0096345da1ed25cf553ea7a98fea6b6f285732de37431561ee1b3064887fbcbd71935e02",
+ "36160e88d3500529ba4edba17bc24d8cfaca9a0680b3b1fc97cf03f3675b7ac301c883a68c071bc54acdd3b63af4a2d72f985e51f9d60a4c7fd481af10b2fc75e252fdee7ea6b6453190617dcc6e2fe1cd56585fc2f0b0e97c5c3f8ad7eb4f31bc4890c03882aac24cc53acc1982296526690a220271c2f6e326750d3fbda5d5b63512c831f67830f59ac49aae330b3e0e02c9ea0091d19841f1b0e13d69c9fbfe8a12d6f30bb734d9d2"),
+ new TestCase(
+ "45b2bd0de4ed9293ec3e26c4840faaf64b7d619d51e9d7a2c7e36c83d584c3df",
+ "546c8c5d6be8f90952cab3f36d7c1957baaa7a59abe3d7e5",
+ "5007c8cd5b3c40e17d7fe423a87ae0ced86bec1c39dc07a25772f3e96dabd56cd3fd7319f6c9654925f2d87087a700e1b130da796895d1c9b9acd62b266144067d373ed51e787498b03c52faad16bb3826fa511b0ed2a19a8663f5ba2d6ea7c38e7212e9697d91486c49d8a000b9a1935d6a7ff7ef23e720a45855481440463b4ac8c4f6e7062adc1f1e1e25d3d65a31812f58a71160",
+ "8eacfba568898b10c0957a7d44100685e8763a71a69a8d16bc7b3f88085bb9a2f09642e4d09a9f0ad09d0aad66b22610c8bd02ff6679bb92c2c026a216bf425c6be35fb8dae7ff0c72b0efd6a18037c70eed0ca90062a49a3c97fdc90a8f9c2ea536bfdc41918a7582c9927fae47efaa3dc87967b7887dee1bf071734c7665901d9105dae2fdf66b4918e51d8f4a48c60d19fbfbbcba"),
+ new TestCase(
+ "fe559c9a282beb40814d016d6bfcb2c0c0d8bf077b1110b8703a3ce39d70e0e1",
+ "b076200cc7011259805e18b304092754002723ebec5d6200",
+ "6db65b9ec8b114a944137c821fd606be75478d928366d5284096cdef782fcff7e8f59cb8ffcda979757902c5ffa6bc477ceaa4cb5d5ea76f94d91e833f823a6bc78f1055dfa6a97bea8965c1cde67a668e001257334a585727d9e0f7c1a06e88d3d25a4e6d9096c968bf138e116a3ebeffd4bb4808adb1fd698164ba0a35c709a47f16f1f4435a2345a9194a00b95abd51851d505809a6077da9baca5831afff31578c487ee68f2767974a98a7e803aac788da98319c4ea8eaa3d394855651f484cef543f537e35158ee29",
+ "4dce9c8f97a028051b0727f34e1b9ef21f06f0760f36e71713204027902090ba2bb6b13436ee778d9f50530efbd7a32b0d41443f58ccaee781c7b716d3a96fdec0e3764ed7959f34c3941278591ea033b5cbadc0f1916032e9bebbd1a8395b83fb63b1454bd775bd20b3a2a96f951246ac14daf68166ba62f6cbff8bd121ac9498ff8852fd2be975df52b5daef3829d18eda42e715022dcbf930d0a789ee6a146c2c7088c35773c63c06b4af4559856ac199ced86863e4294707825337c5857970eb7fddeb263781309011"),
+ new TestCase(
+ "0ae10012d7e56614b03dcc89b14bae9242ffe630f3d7e35ce8bbb97bbc2c92c3",
+ "f96b025d6cf46a8a12ac2af1e2aef1fb83590adadaa5c5ea",
+ "ea0f354e96f12bc72bbaa3d12b4a8ed879b042f0689878f46b651cc4116d6f78409b11430b3aaa30b2076891e8e1fa528f2fd169ed93dc9f84e24409eec2101daf4d057be2492d11de640cbd7b355ad29fb70400fffd7cd6d425abeeb732a0eaa4330af4c656252c4173deab653eb85c58462d7ab0f35fd12b613d29d473d330310dc323d3c66348bbdbb68a326324657cae7b77a9e34358f2cec50c85609e73056856796e3be8d62b6e2fe9f953",
+ "e8abd48924b54e5b80866be7d4ebe5cf4274cafff08b39cb2d40a8f0b472398aedc776e0793812fbf1f60078635d2ed86b15efcdba60411ee23b07233592a44ec31b1013ce8964236675f8f183aef885e864f2a72edf4215b5338fa2b54653dfa1a8c55ce5d95cc605b9b311527f2e3463ffbec78a9d1d65dabad2f338769c9f43f133a791a11c7eca9af0b771a4ac32963dc8f631a2c11217ac6e1b9430c1aae1ceebe22703f429998a8fb8c641"),
+ new TestCase(
+ "082c539bc5b20f97d767cd3f229eda80b2adc4fe49c86329b5cd6250a9877450",
+ "845543502e8b64912d8f2c8d9fffb3c69365686587c08d0c",
+ "a96bb7e910281a6dfad7c8a9c370674f0ceec1ad8d4f0de32f9ae4a23ed329e3d6bc708f876640a229153ac0e7281a8188dd77695138f01cda5f41d5215fd5c6bdd46d982cb73b1efe2997970a9fdbdb1e768d7e5db712068d8ba1af6067b5753495e23e6e1963af012f9c7ce450bf2de619d3d59542fb55f3",
+ "835da74fc6de08cbda277a7966a07c8dcd627e7b17adde6d930b6581e3124b8baad096f693991fedb1572930601fc7709541839b8e3ffd5f033d2060d999c6c6e3048276613e648000acb5212cc632a916afce290e20ebdf612d08a6aa4c79a74b070d3f872a861f8dc6bb07614db515d363349d3a8e3336a3"),
+ new TestCase("3d02bff3375d403027356b94f514203737ee9a85d2052db3e4e5a217c259d18a",
+ "74216c95031895f48c1dba651555ebfa3ca326a755237025",
+ "0d4b0f54fd09ae39baa5fa4baccf2e6682e61b257e01f42b8f",
+ "16c4006c28365190411eb1593814cf15e74c22238f210afc3d"),
+ new TestCase(
+ "ad1a5c47688874e6663a0f3fa16fa7efb7ecadc175c468e5432914bdb480ffc6",
+ "e489eed440f1aae1fac8fb7a9825635454f8f8f1f52e2fcc",
+ "aa6c1e53580f03a9abb73bfdadedfecada4c6b0ebe020ef10db745e54ba861caf65f0e40dfc520203bb54d29e0a8f78f16b3f1aa525d6bfa33c54726e59988cfbec78056",
+ "02fe84ce81e178e7aabdd3ba925a766c3c24756eefae33942af75e8b464556b5997e616f3f2dfc7fce91848afd79912d9fb55201b5813a5a074d2c0d4292c1fd441807c5"),
+ new TestCase(
+ "053a02bedd6368c1fb8afc7a1b199f7f7ea2220c9a4b642a6850091c9d20ab9c",
+ "c713eea5c26dad75ad3f52451e003a9cb0d649f917c89dde",
+ "8f0a8a164760426567e388840276de3f95cb5e3fadc6ed3f3e4fe8bc169d9388804dcb94b6587dbb66cb0bd5f87b8e98b52af37ba290629b858e0e2aa7378047a26602",
+ "516710e59843e6fbd4f25d0d8ca0ec0d47d39d125e9dad987e0518d49107014cb0ae405e30c2eb3794750bca142ce95e290cf95abe15e822823e2e7d3ab21bc8fbd445"),
+ new TestCase(
+ "5b14ab0fbed4c58952548a6cb1e0000cf4481421f41288ea0aa84add9f7deb96",
+ "54bf52b911231b952ba1a6af8e45b1c5a29d97e2abad7c83",
+ "37fb44a675978b560ff9a4a87011d6f3ad2d37a2c3815b45a3c0e6d1b1d8b1784cd468927c2ee39e1dccd4765e1c3d676a335be1ccd6900a45f5d41a317648315d8a8c24adc64eb285f6aeba05b9029586353d303f17a807658b9ff790474e1737bd5fdc604aeff8dfcaf1427dcc3aacbb0256badcd183ed75a2dc52452f87d3c1ed2aa583472b0ab91cda20614e9b6fdbda3b49b098c95823cc72d8e5b717f2314b0324e9ce",
+ "ae6deb5d6ce43d4b09d0e6b1c0e9f46157bcd8ab50eaa3197ff9fa2bf7af649eb52c68544fd3adfe6b1eb316f1f23538d470c30dbfec7e57b60cbcd096c782e7736b669199c8253e70214cf2a098fda8eac5da79a9496a3aae754d03b17c6d70d1027f42bf7f95ce3d1d9c338854e158fcc803e4d6262fb639521e47116ef78a7a437ca9427ba645cd646832feab822a208278e45e93e118d780b988d65397eddfd7a819526e"),
+ new TestCase(
+ "d74636e3413a88d85f322ca80fb0bd650bd0bf0134e2329160b69609cd58a4b0",
+ "efb606aa1d9d9f0f465eaa7f8165f1ac09f5cb46fecf2a57",
+ "f85471b75f6ec81abac2799ec09e98e280b2ffd64ca285e5a0109cfb31ffab2d617b2c2952a2a8a788fc0da2af7f530758f74f1ab56391ab5ff2adbcc5be2d6c7f49fbe8118104c6ff9a23c6dfe52f57954e6a69dcee5db06f514f4a0a572a9a8525d961dae72269b987189d465df6107119c7fa790853e063cba0fab7800ca932e258880fd74c33c784675bedad0e7c09e9cc4d63dd5e9713d5d4a0196e6b562226ac31b4f57c04f90a181973737ddc7e80f364112a9fbb435ebdbcabf7d490ce52",
+ "b2b795fe6c1d4c83c1327e015a67d4465fd8e32813575cbab263e20ef05864d2dc17e0e4eb81436adfe9f638dcc1c8d78f6b0306baf938e5d2ab0b3e05e735cc6fff2d6e02e3d60484bea7c7a8e13e23197fea7b04d47d48f4a4e5944174539492800d3ef51e2ee5e4c8a0bdf050c2dd3dd74fce5e7e5c37364f7547a11480a3063b9a0a157b15b10a5a954de2731ced055aa2e2767f0891d4329c426f3808ee867bed0dc75b5922b7cfb895700fda016105a4c7b7f0bb90f029f6bbcb04ac36ac16") };
+
+ public override string Name
+ {
+ get { return "XSalsa20"; }
+ }
+
+ public override void PerformTest()
+ {
+ for (int i = 0; i < TEST_CASES.Length; i++)
+ {
+ performTest(i, TEST_CASES[i]);
+ }
+ }
+
+ private void performTest(int number, TestCase testCase)
+ {
+ byte[] plaintext = testCase.Plaintext;
+ byte[] output = new byte[plaintext.Length];
+
+ XSalsa20Engine engine = new XSalsa20Engine();
+ engine.Init(false, new ParametersWithIV(new KeyParameter(testCase.Key), testCase.Iv));
+
+ engine.ProcessBytes(testCase.Plaintext, 0, testCase.Plaintext.Length, output, 0);
+
+ if (!Arrays.AreEqual(testCase.Ciphertext, output))
+ {
+ Fail("mismatch on " + number, Hex.ToHexString(testCase.Ciphertext), Hex.ToHexString(output));
+ }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new XSalsa20Test());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+ }
+}
--
cgit 1.5.1
From ab670ffe1486ea52cd88a1a8234b201874460b4c Mon Sep 17 00:00:00 2001
From: Tim Whittington
+ * The exception extends ClassCastException to enable users to have a single handling case,
+ * only introducing specific handling of this one if required.
+ *
- * Test cases generated using ref version of ChaCha20 in estreambench-20080905.
- */
- [TestFixture]
- public class ChaChaTest
- : SimpleTest
- {
- private static readonly byte[] zeroes = Hex.Decode(
- "00000000000000000000000000000000"
- + "00000000000000000000000000000000"
- + "00000000000000000000000000000000"
- + "00000000000000000000000000000000");
-
- private static readonly string set1v0_0 =
- "FBB87FBB8395E05DAA3B1D683C422046"
- + "F913985C2AD9B23CFC06C1D8D04FF213"
- + "D44A7A7CDB84929F915420A8A3DC58BF"
- + "0F7ECB4B1F167BB1A5E6153FDAF4493D";
-
- private static readonly string set1v0_192 =
- "D9485D55B8B82D792ED1EEA8E93E9BC1"
- + "E2834AD0D9B11F3477F6E106A2F6A5F2"
- + "EA8244D5B925B8050EAB038F58D4DF57"
- + "7FAFD1B89359DAE508B2B10CBD6B488E";
-
- private static readonly string set1v0_256 =
- "08661A35D6F02D3D9ACA8087F421F7C8"
- + "A42579047D6955D937925BA21396DDD4"
- + "74B1FC4ACCDCAA33025B4BCE817A4FBF"
- + "3E5D07D151D7E6FE04934ED466BA4779";
-
- private static readonly string set1v0_448 =
- "A7E16DD38BA48CCB130E5BE9740CE359"
- + "D631E91600F85C8A5D0785A612D1D987"
- + "90780ACDDC26B69AB106CCF6D866411D"
- + "10637483DBF08CC5591FD8B3C87A3AE0";
-
- private static readonly string set1v9_0 =
- "A276339F99316A913885A0A4BE870F06"
- + "91E72B00F1B3F2239F714FE81E88E00C"
- + "BBE52B4EBBE1EA15894E29658C4CB145"
- + "E6F89EE4ABB045A78514482CE75AFB7C";
-
- private static readonly string set1v9_192 =
- "0DFB9BD4F87F68DE54FBC1C6428FDEB0"
- + "63E997BE8490C9B7A4694025D6EBA2B1"
- + "5FE429DB82A7CAE6AAB22918E8D00449"
- + "6FB6291467B5AE81D4E85E81D8795EBB";
-
- private static readonly string set1v9_256 =
- "546F5BB315E7F71A46E56D4580F90889"
- + "639A2BA528F757CF3B048738BA141AF3"
- + "B31607CB21561BAD94721048930364F4"
- + "B1227CFEB7CDECBA881FB44903550E68";
-
- private static readonly string set1v9_448 =
- "6F813586E76691305A0CF048C0D8586D"
- + "C89460207D8B230CD172398AA33D19E9"
- + "2D24883C3A9B0BB7CD8C6B2668DB142E"
- + "37A97948A7A01498A21110297984CD20";
-
- private static readonly string set6v0_0 =
- "57459975BC46799394788DE80B928387"
- + "862985A269B9E8E77801DE9D874B3F51"
- + "AC4610B9F9BEE8CF8CACD8B5AD0BF17D"
- + "3DDF23FD7424887EB3F81405BD498CC3";
-
- private static readonly string set6v0_65472 =
- "EF9AEC58ACE7DB427DF012B2B91A0C1E"
- + "8E4759DCE9CDB00A2BD59207357BA06C"
- + "E02D327C7719E83D6348A6104B081DB0"
- + "3908E5186986AE41E3AE95298BB7B713";
-
- private static readonly string set6v0_65536 =
- "17EF5FF454D85ABBBA280F3A94F1D26E"
- + "950C7D5B05C4BB3A78326E0DC5731F83"
- + "84205C32DB867D1B476CE121A0D7074B"
- + "AA7EE90525D15300F48EC0A6624BD0AF";
-
- private static readonly string set6v1_0 =
- "92A2508E2C4084567195F2A1005E552B"
- + "4874EC0504A9CD5E4DAF739AB553D2E7"
- + "83D79C5BA11E0653BEBB5C116651302E"
- + "8D381CB728CA627B0B246E83942A2B99";
-
- private static readonly string set6v1_65472 =
- "E1974EC3063F7BD0CBA58B1CE34BC874"
- + "67AAF5759B05EA46682A5D4306E5A76B"
- + "D99A448DB8DE73AF97A73F5FBAE2C776"
- + "35040464524CF14D7F08D4CE1220FD84";
-
- private static readonly string set6v1_65536 =
- "BE3436141CFD62D12FF7D852F80C1344"
- + "81F152AD0235ECF8CA172C55CA8C031B"
- + "2E785D773A988CA8D4BDA6FAE0E493AA"
- + "71DCCC4C894D1F106CAC62A9FC0A9607";
-
- // ChaCha12
- private static readonly string chacha12_set1v0_0 =
- "36CF0D56E9F7FBF287BC5460D95FBA94"
- + "AA6CBF17D74E7C784DDCF7E0E882DDAE"
- + "3B5A58243EF32B79A04575A8E2C2B73D"
- + "C64A52AA15B9F88305A8F0CA0B5A1A25";
-
- private static readonly string chacha12_set1v0_192 =
- "83496792AB68FEC75ADB16D3044420A4"
- + "A00A6E9ADC41C3A63DBBF317A8258C85"
- + "A9BC08B4F76B413A4837324AEDF8BC2A"
- + "67D53C9AB9E1C5BC5F379D48DF9AF730";
-
- private static readonly string chacha12_set1v0_256 =
- "BAA28ED593690FD760ADA07C95E3B888"
- + "4B4B64E488CA7A2D9BDC262243AB9251"
- + "394C5037E255F8BCCDCD31306C508FFB"
- + "C9E0161380F7911FCB137D46D9269250";
-
- private static readonly string chacha12_set1v0_448 =
- "B7ECFB6AE0B51915762FE1FD03A14D0C"
- + "9E54DA5DC76EB16EBA5313BC535DE63D"
- + "C72D7F9F1874E301E99C8531819F4E37"
- + "75793F6A5D19C717FA5C78A39EB804A6";
-
- // ChaCha8
- private static readonly string chacha8_set1v0_0 =
- "BEB1E81E0F747E43EE51922B3E87FB38"
- + "D0163907B4ED49336032AB78B67C2457"
- + "9FE28F751BD3703E51D876C017FAA435"
- + "89E63593E03355A7D57B2366F30047C5";
-
- private static readonly string chacha8_set1v0_192 =
- "33B8B7CA8F8E89F0095ACE75A379C651"
- + "FD6BDD55703C90672E44C6BAB6AACDD8"
- + "7C976A87FD264B906E749429284134C2"
- + "38E3B88CF74A68245B860D119A8BDF43";
-
- private static readonly string chacha8_set1v0_256 =
- "F7CA95BF08688BD3BE8A27724210F9DC"
- + "16F32AF974FBFB09E9F757C577A245AB"
- + "F35F824B70A4C02CB4A8D7191FA8A5AD"
- + "6A84568743844703D353B7F00A8601F4";
-
- private static readonly string chacha8_set1v0_448 =
- "7B4117E8BFFD595CD8482270B08920FB"
- + "C9B97794E1809E07BB271BF07C861003"
- + "4C38DBA6ECA04E5474F399A284CBF6E2"
- + "7F70142E604D0977797DE5B58B6B25E0";
-
- public override string Name
- {
- get { return "ChaCha"; }
- }
-
- public override void PerformTest()
- {
- chachaTest1(20, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
- set1v0_0, set1v0_192, set1v0_256, set1v0_448);
- chachaTest1(20, new ParametersWithIV(new KeyParameter(Hex.Decode("00400000000000000000000000000000")), Hex.Decode("0000000000000000")),
- set1v9_0, set1v9_192, set1v9_256, set1v9_448);
- chachaTest1(12, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
- chacha12_set1v0_0, chacha12_set1v0_192, chacha12_set1v0_256, chacha12_set1v0_448);
- chachaTest1(8, new ParametersWithIV(new KeyParameter(Hex.Decode("80000000000000000000000000000000")), Hex.Decode("0000000000000000")),
- chacha8_set1v0_0, chacha8_set1v0_192, chacha8_set1v0_256, chacha8_set1v0_448);
- chachaTest2(new ParametersWithIV(new KeyParameter(Hex.Decode("0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D")), Hex.Decode("0D74DB42A91077DE")),
- set6v0_0, set6v0_65472, set6v0_65536);
- chachaTest2(new ParametersWithIV(new KeyParameter(Hex.Decode("0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12")), Hex.Decode("167DE44BB21980E7")),
- set6v1_0, set6v1_65472, set6v1_65536);
- reinitBug();
- }
-
- private void chachaTest1(
- int rounds,
- ICipherParameters parameters,
- string v0,
- string v192,
- string v256,
- string v448)
- {
- IStreamCipher salsa = new ChaChaEngine(rounds);
- byte[] buf = new byte[64];
-
- salsa.Init(true, parameters);
-
- for (int i = 0; i != 7; i++)
- {
- salsa.ProcessBytes(zeroes, 0, 64, buf, 0);
- switch (i)
- {
- case 0:
- if (!AreEqual(buf, Hex.Decode(v0)))
- {
- mismatch("v0/" + rounds, v0, buf);
- }
- break;
- case 3:
- if (!AreEqual(buf, Hex.Decode(v192)))
- {
- mismatch("v192/" + rounds, v192, buf);
- }
- break;
- case 4:
- if (!AreEqual(buf, Hex.Decode(v256)))
- {
- mismatch("v256/" + rounds, v256, buf);
- }
- break;
- default:
- // ignore
- break;
- }
- }
-
- for (int i = 0; i != 64; i++)
- {
- buf[i] = salsa.ReturnByte(zeroes[i]);
- }
-
- if (!AreEqual(buf, Hex.Decode(v448)))
- {
- mismatch("v448", v448, buf);
- }
- }
-
- private void chachaTest2(
- ICipherParameters parameters,
- string v0,
- string v65472,
- string v65536)
- {
- IStreamCipher salsa = new ChaChaEngine();
- byte[] buf = new byte[64];
-
- salsa.Init(true, parameters);
-
- for (int i = 0; i != 1025; i++)
- {
- salsa.ProcessBytes(zeroes, 0, 64, buf, 0);
- switch (i)
- {
- case 0:
- if (!AreEqual(buf, Hex.Decode(v0)))
- {
- mismatch("v0", v0, buf);
- }
- break;
- case 1023:
- if (!AreEqual(buf, Hex.Decode(v65472)))
- {
- mismatch("v65472", v65472, buf);
- }
- break;
- case 1024:
- if (!AreEqual(buf, Hex.Decode(v65536)))
- {
- mismatch("v65536", v65536, buf);
- }
- break;
- default:
- // ignore
- break;
- }
- }
- }
-
- private void mismatch(
- string name,
- string expected,
- byte[] found)
- {
- Fail("mismatch on " + name, expected, Hex.ToHexString(found));
- }
-
- private void reinitBug()
- {
- KeyParameter key = new KeyParameter(Hex.Decode("80000000000000000000000000000000"));
- ParametersWithIV parameters = new ParametersWithIV(key, Hex.Decode("0000000000000000"));
-
- IStreamCipher chacha = new ChaChaEngine();
-
- chacha.Init(true, parameters);
-
- try
- {
- chacha.Init(true, key);
- Fail("ChaCha should throw exception if no IV in Init");
- }
- catch (ArgumentException)
- {
- }
- }
-
- public static void Main(
- string[] args)
- {
- RunTest(new ChaChaTest());
- }
-
- [Test]
- public void TestFunction()
- {
- string resultText = Perform().ToString();
-
- Assert.AreEqual(Name + ": Okay", resultText);
- }
- }
+ /**
+ * ChaCha Test
+ *
+ * Test cases generated using ref version of ChaCha20 in estreambench-20080905.
+ *
+ /// The {@code r} value has a specific format with some bits required to be cleared, resulting in an
+ /// effective 106 bit key.
+ /// A separately generated 256 bit key can be modified to fit the Poly1305 key format by using the
+ /// {@link #clamp(byte[])} method to clear the required bits.
+ /// k[0] ... k[15], r[0] ... r[15]
with the required bits in r
cleared
+ /// as per r
(second 16 bytes) portion of the key.
+ /// Specifically:
+ ///
+ ///
+ /// k[0] ... k[15], r[0] ... r[15]
+ public static void Clamp(byte[] key)
+ {
+ /*
+ * Key is k[0] ... k[15], r[0] ... r[15] as per poly1305_aes_clamp in ref impl.
+ */
+ if (key.Length != 32)
+ {
+ throw new ArgumentException("Poly1305 key must be 256 bits.");
+ }
+
+ /*
+ * r[3], r[7], r[11], r[15] have top four bits clear (i.e., are {0, 1, . . . , 15})
+ */
+ key[19] &= R_MASK_HIGH_4;
+ key[23] &= R_MASK_HIGH_4;
+ key[27] &= R_MASK_HIGH_4;
+ key[31] &= R_MASK_HIGH_4;
+
+ /*
+ * r[4], r[8], r[12] have bottom two bits clear (i.e., are in {0, 4, 8, . . . , 252}).
+ */
+ key[20] &= R_MASK_LOW_2;
+ key[24] &= R_MASK_LOW_2;
+ key[28] &= R_MASK_LOW_2;
+ }
+
+ /// k[0] ... k[15], r[0] ... r[15]
with the required bits in r
cleared
+ /// as per r
portion of the key.
+ /// 2 x block size state is retained by each cipher instance.
+ /// null
to use the current key.
+ /// the 2 word (128 bit) tweak, or null
to use the current tweak.
+ internal void Init(bool forEncryption, ulong[] key, ulong[] tweak)
+ {
+ this.forEncryption = forEncryption;
+ if (key != null)
+ {
+ SetKey(key);
+ }
+ if (tweak != null)
+ {
+ SetTweak(tweak);
+ }
+ }
+
+ private void SetKey(ulong[] key)
+ {
+ if (key.Length != this.blocksizeWords)
+ {
+ throw new ArgumentException("Threefish key must be same size as block (" + blocksizeWords
+ + " words)");
+ }
+
+ /*
+ * Full subkey schedule is deferred to execution to avoid per cipher overhead (10k for 512,
+ * 20k for 1024).
+ *
+ * Key and tweak word sequences are repeated, and static MOD17/MOD9/MOD5/MOD3 calculations
+ * used, to avoid expensive mod computations during cipher operation.
+ */
+
+ ulong knw = C_240;
+ for (int i = 0; i < blocksizeWords; i++)
+ {
+ kw[i] = key[i];
+ knw = knw ^ kw[i];
+ }
+ kw[blocksizeWords] = knw;
+ Array.Copy(kw, 0, kw, blocksizeWords + 1, blocksizeWords);
+ }
+
+ private void SetTweak(ulong[] tweak)
+ {
+ if (tweak.Length != TWEAK_SIZE_WORDS)
+ {
+ throw new ArgumentException("Tweak must be " + TWEAK_SIZE_WORDS + " words.");
+ }
+
+ /*
+ * Tweak schedule partially repeated to avoid mod computations during cipher operation
+ */
+ t[0] = tweak[0];
+ t[1] = tweak[1];
+ t[2] = t[0] ^ t[1];
+ t[3] = t[0];
+ t[4] = t[1];
+ }
+
+ public string AlgorithmName
+ {
+ get { return "Threefish-" + (blocksizeBytes * 8); }
+ }
+
+ public bool IsPartialBlockOkay
+ {
+ get { return false; }
+ }
+
+ public int GetBlockSize()
+ {
+ return blocksizeBytes;
+ }
+
+ public void Reset()
+ {
+ }
+
+ public int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
+ {
+ if ((outOff + blocksizeBytes) > outBytes.Length)
+ {
+ throw new DataLengthException("Output buffer too short");
+ }
+
+ if ((inOff + blocksizeBytes) > inBytes.Length)
+ {
+ throw new DataLengthException("Input buffer too short");
+ }
+
+ for (int i = 0; i < blocksizeBytes; i += 8)
+ {
+ currentBlock[i >> 3] = BytesToWord(inBytes, inOff + i);
+ }
+ ProcessBlock(this.currentBlock, this.currentBlock);
+ for (int i = 0; i < blocksizeBytes; i += 8)
+ {
+ WordToBytes(this.currentBlock[i >> 3], outBytes, outOff + i);
+ }
+
+ return blocksizeBytes;
+ }
+
+ /// null
to use the current key.null
to use the current tweak.null
to use no parameters.
+ public void Init(SkeinParameters parameters)
+ {
+ engine.Init(parameters);
+ }
+
+ public void Reset()
+ {
+ engine.Reset();
+ }
+
+ public void Update(byte inByte)
+ {
+ engine.Update(inByte);
+ }
+
+ public void BlockUpdate(byte[] inBytes, int inOff, int len)
+ {
+ engine.Update(inBytes, inOff, len);
+ }
+
+ public int DoFinal(byte[] outBytes, int outOff)
+ {
+ return engine.DoFinal(outBytes, outOff);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/crypto/src/crypto/digests/SkeinEngine.cs b/crypto/src/crypto/digests/SkeinEngine.cs
new file mode 100644
index 000000000..94529bcf6
--- /dev/null
+++ b/crypto/src/crypto/digests/SkeinEngine.cs
@@ -0,0 +1,803 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Digests
+{
+
+ ///
+ /// Initialising the engine with
+ ///
+ ///
+ /// Not implemented:
+ ///
+ ///
+ /// null
to use no parameters.
+ public void Init(SkeinParameters parameters)
+ {
+ this.chain = null;
+ this.key = null;
+ this.preMessageParameters = null;
+ this.postMessageParameters = null;
+
+ if (parameters != null)
+ {
+ byte[] key = parameters.GetKey();
+ if (key.Length < 16)
+ {
+ throw new ArgumentException("Skein key must be at least 128 bits.");
+ }
+ InitParams(parameters.GetParameters());
+ }
+ CreateInitialState();
+
+ // Initialise message block
+ UbiInit(PARAM_TYPE_MESSAGE);
+ }
+
+ private void InitParams(IDictionary parameters)
+ {
+ IEnumerator keys = parameters.Keys.GetEnumerator();
+ IList pre = Platform.CreateArrayList();
+ IList post = Platform.CreateArrayList();
+
+ while (keys.MoveNext())
+ {
+ int type = (int)keys.Current;
+ byte[] value = (byte[])parameters[type];
+
+ if (type == PARAM_TYPE_KEY)
+ {
+ this.key = value;
+ }
+ else if (type < PARAM_TYPE_MESSAGE)
+ {
+ pre.Add(new Parameter(type, value));
+ }
+ else
+ {
+ post.Add(new Parameter(type, value));
+ }
+ }
+ preMessageParameters = new Parameter[pre.Count];
+ pre.CopyTo(preMessageParameters, 0);
+ Array.Sort(preMessageParameters);
+
+ postMessageParameters = new Parameter[post.Count];
+ post.CopyTo(postMessageParameters, 0);
+ Array.Sort(postMessageParameters);
+ }
+
+ /**
+ * Calculate the initial (pre message block) chaining state.
+ */
+ private void CreateInitialState()
+ {
+ ulong[] precalc = (ulong[])INITIAL_STATES[VariantIdentifier(BlockSize, OutputSize)];
+ if ((key == null) && (precalc != null))
+ {
+ // Precalculated UBI(CFG)
+ chain = Arrays.Clone(precalc);
+ }
+ else
+ {
+ // Blank initial state
+ chain = new ulong[BlockSize / 8];
+
+ // Process key block
+ if (key != null)
+ {
+ UbiComplete(SkeinParameters.PARAM_TYPE_KEY, key);
+ }
+
+ // Process configuration block
+ UbiComplete(PARAM_TYPE_CONFIG, new Configuration(outputSizeBytes * 8).Bytes);
+ }
+
+ // Process additional pre-message parameters
+ if (preMessageParameters != null)
+ {
+ for (int i = 0; i < preMessageParameters.Length; i++)
+ {
+ Parameter param = preMessageParameters[i];
+ UbiComplete(param.Type, param.Value);
+ }
+ }
+ initialState = Arrays.Clone(chain);
+ }
+
+ /// null
to use no parameters.
+ public void Init(ICipherParameters parameters)
+ {
+ SkeinParameters skeinParameters;
+ if (parameters is SkeinParameters)
+ {
+ skeinParameters = (SkeinParameters)parameters;
+ }
+ else if (parameters is KeyParameter)
+ {
+ skeinParameters = new SkeinParameters.Builder().SetKey(((KeyParameter)parameters).GetKey()).Build();
+ }
+ else
+ {
+ throw new ArgumentException("Invalid parameter passed to Skein MAC init - "
+ + parameters.GetType().Name);
+ }
+ if (skeinParameters.GetKey() == null)
+ {
+ throw new ArgumentException("Skein MAC requires a key parameter.");
+ }
+ engine.Init(skeinParameters);
+ }
+
+ public int GetMacSize()
+ {
+ return engine.OutputSize;
+ }
+
+ public void Reset()
+ {
+ engine.Reset();
+ }
+
+ public void Update(byte inByte)
+ {
+ engine.Update(inByte);
+ }
+
+ public void BlockUpdate(byte[] input, int inOff, int len)
+ {
+ engine.Update(input, inOff, len);
+ }
+
+ public int DoFinal(byte[] output, int outOff)
+ {
+ return engine.DoFinal(output, outOff);
+ }
+
+ }
+}
diff --git a/crypto/src/crypto/parameters/SkeinParameters.cs b/crypto/src/crypto/parameters/SkeinParameters.cs
new file mode 100644
index 000000000..bbd25e0e0
--- /dev/null
+++ b/crypto/src/crypto/parameters/SkeinParameters.cs
@@ -0,0 +1,285 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Parameters
+{
+
+ ///
+ ///
+ /// null
if not
+ /// set.
+ /// null
if not set.
+ /// null
if not set.
+ /// null
if
+ /// not set.
+ /// YYYYMMDD email@address distinguisher
, encoded to a byte
+ /// sequence using UTF-8 encoding.
+ ///
* It can be found at ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/idea/ - *
+ * *- * Note 1: This algorithm is patented in the USA, Japan, and Europe including + * Note 1: This algorithm is patented in the USA, Japan, and Europe including * at least Austria, France, Germany, Italy, Netherlands, Spain, Sweden, Switzerland * and the United Kingdom. Non-commercial use is free, however any commercial * products are liable for royalties. Please see * www.mediacrypt.com for * further details. This announcement has been included at the request of * the patent holders. - *
- *- * Note 2: Due to the requests concerning the above, this algorithm is now only - * included in the extended assembly. It is not included in the default distributions. - *
+ * + *+ * Note 2: Due to the requests concerning the above, this algorithm is now only + * included in the extended assembly. It is not included in the default distributions. + *
*/ public class IdeaEngine - : IBlockCipher + : IBlockCipher { private const int BLOCK_SIZE = 8; private int[] workingKey; @@ -54,28 +52,28 @@ namespace Org.BouncyCastle.Crypto.Engines ICipherParameters parameters) { if (!(parameters is KeyParameter)) - throw new ArgumentException("invalid parameter passed to IDEA init - " + parameters.GetType().ToString()); + throw new ArgumentException("invalid parameter passed to IDEA init - " + parameters.GetType().ToString()); - workingKey = GenerateWorkingKey(forEncryption, - ((KeyParameter)parameters).GetKey()); + workingKey = GenerateWorkingKey(forEncryption, + ((KeyParameter)parameters).GetKey()); } - public string AlgorithmName + public string AlgorithmName { get { return "IDEA"; } } - public bool IsPartialBlockOkay - { - get { return false; } - } + public bool IsPartialBlockOkay + { + get { return false; } + } - public int GetBlockSize() + public int GetBlockSize() { return BLOCK_SIZE; } - public int ProcessBlock( + public int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -228,7 +226,7 @@ namespace Org.BouncyCastle.Crypto.Engines * Common Divisor algorithm. Zero and one are self inverse. ** i.e. x * MulInv(x) == 1 (modulo BASE) - *
+ * */ private int MulInv( int x) @@ -261,7 +259,7 @@ namespace Org.BouncyCastle.Crypto.Engines * Return the additive inverse of x. ** i.e. x + AddInv(x) == 0 - *
+ * */ int AddInv( int x) @@ -337,5 +335,3 @@ namespace Org.BouncyCastle.Crypto.Engines } } } - -#endif diff --git a/crypto/src/security/CipherUtilities.cs b/crypto/src/security/CipherUtilities.cs index cda769535..cdb711f69 100644 --- a/crypto/src/security/CipherUtilities.cs +++ b/crypto/src/security/CipherUtilities.cs @@ -389,11 +389,9 @@ namespace Org.BouncyCastle.Security case CipherAlgorithm.HC256: streamCipher = new HC256Engine(); break; -#if INCLUDE_IDEA case CipherAlgorithm.IDEA: blockCipher = new IdeaEngine(); break; -#endif case CipherAlgorithm.NOEKEON: blockCipher = new NoekeonEngine(); break; @@ -716,9 +714,7 @@ namespace Org.BouncyCastle.Security case CipherAlgorithm.DES: return new DesEngine(); case CipherAlgorithm.DESEDE: return new DesEdeEngine(); case CipherAlgorithm.GOST28147: return new Gost28147Engine(); -#if INCLUDE_IDEA case CipherAlgorithm.IDEA: return new IdeaEngine(); -#endif case CipherAlgorithm.NOEKEON: return new NoekeonEngine(); case CipherAlgorithm.RC2: return new RC2Engine(); case CipherAlgorithm.RC5: return new RC532Engine(); diff --git a/crypto/src/security/MacUtilities.cs b/crypto/src/security/MacUtilities.cs index 49162fb57..77d141411 100644 --- a/crypto/src/security/MacUtilities.cs +++ b/crypto/src/security/MacUtilities.cs @@ -185,7 +185,6 @@ namespace Org.BouncyCastle.Security { return new CfbBlockCipherMac(new SkipjackEngine()); } -#if INCLUDE_IDEA if (mechanism == "IDEAMAC") { return new CbcBlockCipherMac(new IdeaEngine()); @@ -194,7 +193,6 @@ namespace Org.BouncyCastle.Security { return new CfbBlockCipherMac(new IdeaEngine()); } -#endif if (mechanism == "RC2MAC") { return new CbcBlockCipherMac(new RC2Engine()); diff --git a/crypto/src/security/ParameterUtilities.cs b/crypto/src/security/ParameterUtilities.cs index bf448edff..b2d7c0dff 100644 --- a/crypto/src/security/ParameterUtilities.cs +++ b/crypto/src/security/ParameterUtilities.cs @@ -83,10 +83,8 @@ namespace Org.BouncyCastle.Security CryptoProObjectIdentifiers.GostR28147Cbc); AddAlgorithm("HC128"); AddAlgorithm("HC256"); -#if INCLUDE_IDEA AddAlgorithm("IDEA", "1.3.6.1.4.1.188.7.1.1.2"); -#endif AddAlgorithm("NOEKEON"); AddAlgorithm("RC2", PkcsObjectIdentifiers.RC2Cbc, @@ -234,12 +232,10 @@ namespace Org.BouncyCastle.Security { iv = Cast5CbcParameters.GetInstance(asn1Params).GetIV(); } -#if INCLUDE_IDEA else if (canonical == "IDEA") { iv = IdeaCbcPar.GetInstance(asn1Params).GetIV(); } -#endif else if (canonical == "RC2") { iv = RC2CbcParameter.GetInstance(asn1Params).GetIV(); @@ -288,10 +284,8 @@ namespace Org.BouncyCastle.Security if (canonical == "CAST5") return new Cast5CbcParameters(CreateIV(random, 8), 128); -#if INCLUDE_IDEA if (canonical == "IDEA") return new IdeaCbcPar(CreateIV(random, 8)); -#endif if (canonical == "RC2") return new RC2CbcParameter(CreateIV(random, 8)); diff --git a/crypto/test/src/asn1/test/MiscTest.cs b/crypto/test/src/asn1/test/MiscTest.cs index 44213c71d..42f5dbd01 100644 --- a/crypto/test/src/asn1/test/MiscTest.cs +++ b/crypto/test/src/asn1/test/MiscTest.cs @@ -10,91 +10,85 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Asn1.Tests { - [TestFixture] - public class MiscTest - : ITest - { - public ITestResult Perform() - { - byte[] testIv = { 1, 2, 3, 4, 5, 6, 7, 8 }; - - Asn1Encodable[] values = - { - new Cast5CbcParameters(testIv, 128), - new NetscapeCertType(NetscapeCertType.Smime), - new VerisignCzagExtension(new DerIA5String("hello")), -#if INCLUDE_IDEA - new IdeaCbcPar(testIv), -#endif - new NetscapeRevocationUrl(new DerIA5String("http://test")) - }; - -#if INCLUDE_IDEA - byte[] data = Base64.Decode("MA4ECAECAwQFBgcIAgIAgAMCBSAWBWhlbGxvMAoECAECAwQFBgcIFgtodHRwOi8vdGVzdA=="); -#else - byte[] data = Base64.Decode("MA4ECAECAwQFBgcIAgIAgAMCBSAWBWhlbGxvFgtodHRwOi8vdGVzdA=="); -#endif - - try - { - MemoryStream bOut = new MemoryStream(); - Asn1OutputStream aOut = new Asn1OutputStream(bOut); - - for (int i = 0; i != values.Length; i++) - { - aOut.WriteObject(values[i]); - } - - if (!Arrays.AreEqual(bOut.ToArray(), data)) - { - return new SimpleTestResult(false, Name + ": Failed data check"); - } - - Asn1InputStream aIn = new Asn1InputStream(bOut.ToArray()); - - for (int i = 0; i != values.Length; i++) - { - Asn1Object o = aIn.ReadObject(); - - if (!values[i].Equals(o)) - { - return new SimpleTestResult(false, Name + ": Failed equality test for " + o); - } - - if (o.GetHashCode() != values[i].GetHashCode()) - { - return new SimpleTestResult(false, Name + ": Failed hashCode test for " + o); - } - } - - return new SimpleTestResult(true, Name + ": Okay"); - } - catch (Exception e) - { - return new SimpleTestResult(false, Name + ": Failed - exception " + e.ToString(), e); - } - } - - public string Name - { - get { return "Misc"; } - } - - public static void Main( - string[] args) - { - ITest test = new MiscTest(); - ITestResult result = test.Perform(); - - Console.WriteLine(result); - } - - [Test] - public void TestFunction() - { - string resultText = Perform().ToString(); - - Assert.AreEqual(Name + ": Okay", resultText); - } - } + [TestFixture] + public class MiscTest + : ITest + { + public ITestResult Perform() + { + byte[] testIv = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + Asn1Encodable[] values = + { + new Cast5CbcParameters(testIv, 128), + new NetscapeCertType(NetscapeCertType.Smime), + new VerisignCzagExtension(new DerIA5String("hello")), + new IdeaCbcPar(testIv), + new NetscapeRevocationUrl(new DerIA5String("http://test")) + }; + + byte[] data = Base64.Decode("MA4ECAECAwQFBgcIAgIAgAMCBSAWBWhlbGxvMAoECAECAwQFBgcIFgtodHRwOi8vdGVzdA=="); + + try + { + MemoryStream bOut = new MemoryStream(); + Asn1OutputStream aOut = new Asn1OutputStream(bOut); + + for (int i = 0; i != values.Length; i++) + { + aOut.WriteObject(values[i]); + } + + if (!Arrays.AreEqual(bOut.ToArray(), data)) + { + return new SimpleTestResult(false, Name + ": Failed data check"); + } + + Asn1InputStream aIn = new Asn1InputStream(bOut.ToArray()); + + for (int i = 0; i != values.Length; i++) + { + Asn1Object o = aIn.ReadObject(); + + if (!values[i].Equals(o)) + { + return new SimpleTestResult(false, Name + ": Failed equality test for " + o); + } + + if (o.GetHashCode() != values[i].GetHashCode()) + { + return new SimpleTestResult(false, Name + ": Failed hashCode test for " + o); + } + } + + return new SimpleTestResult(true, Name + ": Okay"); + } + catch (Exception e) + { + return new SimpleTestResult(false, Name + ": Failed - exception " + e.ToString(), e); + } + } + + public string Name + { + get { return "Misc"; } + } + + public static void Main( + string[] args) + { + ITest test = new MiscTest(); + ITestResult result = test.Perform(); + + Console.WriteLine(result); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } } diff --git a/crypto/test/src/crypto/test/IDEATest.cs b/crypto/test/src/crypto/test/IDEATest.cs index 6ae822271..fbbd1ae17 100644 --- a/crypto/test/src/crypto/test/IDEATest.cs +++ b/crypto/test/src/crypto/test/IDEATest.cs @@ -1,5 +1,3 @@ -#if INCLUDE_IDEA - using System; using NUnit.Framework; @@ -13,31 +11,31 @@ namespace Org.BouncyCastle.Crypto.Tests { [TestFixture] public class IdeaTest - : CipherTest + : CipherTest { public override string Name { - get { return "IDEA"; } + get { return "IDEA"; } } - internal static SimpleTest[] tests = new SimpleTest[] - { - new BlockCipherVectorTest(0, new IdeaEngine(), - new KeyParameter(Hex.Decode("00112233445566778899AABBCCDDEEFF")), - "000102030405060708090a0b0c0d0e0f", - "ed732271a7b39f475b4b2b6719f194bf"), - new BlockCipherVectorTest(0, new IdeaEngine(), - new KeyParameter(Hex.Decode("00112233445566778899AABBCCDDEEFF")), - "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", - "b8bc6ed5c899265d2bcfad1fc6d4287d") - }; - - public IdeaTest() - : base(tests, new IdeaEngine(), new KeyParameter(new byte[32])) + internal static SimpleTest[] tests = new SimpleTest[] + { + new BlockCipherVectorTest(0, new IdeaEngine(), + new KeyParameter(Hex.Decode("00112233445566778899AABBCCDDEEFF")), + "000102030405060708090a0b0c0d0e0f", + "ed732271a7b39f475b4b2b6719f194bf"), + new BlockCipherVectorTest(0, new IdeaEngine(), + new KeyParameter(Hex.Decode("00112233445566778899AABBCCDDEEFF")), + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "b8bc6ed5c899265d2bcfad1fc6d4287d") + }; + + public IdeaTest() + : base(tests, new IdeaEngine(), new KeyParameter(new byte[32])) { } - public static void Main( + public static void Main( string[] args) { ITest test = new IdeaTest(); @@ -45,7 +43,7 @@ namespace Org.BouncyCastle.Crypto.Tests Console.WriteLine(result); } - [Test] + [Test] public void TestFunction() { string resultText = Perform().ToString(); @@ -53,5 +51,3 @@ namespace Org.BouncyCastle.Crypto.Tests } } } - -#endif diff --git a/crypto/test/src/crypto/test/RegressionTest.cs b/crypto/test/src/crypto/test/RegressionTest.cs index 0ac3624d8..5a13a1f96 100644 --- a/crypto/test/src/crypto/test/RegressionTest.cs +++ b/crypto/test/src/crypto/test/RegressionTest.cs @@ -42,9 +42,7 @@ namespace Org.BouncyCastle.Crypto.Tests new Cast5Test(), new Cast6Test(), new Gost28147Test(), -#if INCLUDE_IDEA new IdeaTest(), -#endif new RsaBlindedTest(), new RsaTest(), new ISO9796Test(), diff --git a/crypto/test/src/openpgp/test/PGPRSATest.cs b/crypto/test/src/openpgp/test/PGPRSATest.cs index f38aa002f..35f844483 100644 --- a/crypto/test/src/openpgp/test/PGPRSATest.cs +++ b/crypto/test/src/openpgp/test/PGPRSATest.cs @@ -22,121 +22,121 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests public class PgpRsaTest : SimpleTest { - private static readonly byte[] testPubKey = Base64.Decode( - "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F" - + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" - + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" - + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" - + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" - + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" - + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" - + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA=="); - - private static readonly byte[] testPrivKey = Base64.Decode( - "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP" - + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" - + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" - + "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990" - + "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw" - + "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw" - + "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb" - + "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY" - + "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF" - + "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO" - + "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0" - + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" - + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" - + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" - + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" - + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w="); - - private static readonly byte[] testPubKeyV3 = Base64.Decode( - "mQCNAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" - + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" - + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" - + "wdi2fBUJAAURtApGSVhDSVRZX1FBiQCVAwUQP7O+UZ6Fwdi2fBUJAQFMwwQA" - + "qRnFsdg4xQnB8Y5d4cOpXkIn9AZgYS3cxtuSJB84vG2CgC39nfv4c+nlLkWP" - + "4puG+mZuJNgVoE84cuAF4I//1anKjlU7q1M6rFQnt5S4uxPyG3dFXmgyU1b4" - + "PBOnA0tIxjPzlIhJAMsPCGGA5+5M2JP0ad6RnzqzE3EENMX+GqY="); - - private static readonly byte[] testPrivKeyV3 = Base64.Decode( - "lQHfAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" - + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" - + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" - + "wdi2fBUJAAURAXWwRBZQHNikA/f0ScLLjrXi4s0hgQecg+dkpDow94eu5+AR" - + "0DzZnfurpgfUJCNiDi5W/5c3Zj/xyrfMAgkbCgJ1m6FZqAQh7Mq73l7Kfu4/" - + "XIkyDF3tDgRuZNezB+JuElX10tV03xumHepp6M6CfhXqNJ15F33F99TA5hXY" - + "CPYD7SiSOpIhQkCOAgDAA63imxbpuKE2W7Y4I1BUHB7WQi8ZdkZd04njNTv+" - + "rFUuOPapQVfbWG0Vq8ld3YmJB4QWsa2mmqn+qToXbwufAgBpXkjvqK5yPiHF" - + "Px2QbFc1VqoCJB6PO5JRIqEiUZBFGdDlLxt3VSyqz7IZ/zEnxZq+tPCGGGSm" - + "/sAGiMvENcHVAfy0kTXU42TxEAYJyyNyqjXOobDJpEV1mKhFskRXt7tbMfOS" - + "Yf91oX8f6xw6O2Nal+hU8dS0Bmfmk5/enHmvRLHQocO0CkZJWENJVFlfUUE="); - - private static readonly byte[] sig1 = Base64.Decode( - "owGbwMvMwMRoGpHo9vfz52LGNTJJnBmpOTn5eiUVJfb23JvAHIXy/KKcFEWuToap" - + "zKwMIGG4Bqav0SwMy3yParsEKi2LMGI9xhh65sBxb05n5++ZLcWNJ/eLFKdWbm95" - + "tHbDV7GMwj/tUctUpFUXWPYFCLdNsDiVNuXbQvZtdXV/5xzY+9w1nCnijH9JoNiJ" - + "22n2jo0zo30/TZLo+jDl2vTzIvPeLEsPM3ZUE/1Ytqs4SG2TxIQbH7xf3uzcYXq2" - + "5Fw9AA=="); + private static readonly byte[] testPubKey = Base64.Decode( + "mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F" + + "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO" + + "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F" + + "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4" + + "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG" + + "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc" + + "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs" + + "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA=="); + + private static readonly byte[] testPrivKey = Base64.Decode( + "lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP" + + "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x" + + "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D" + + "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990" + + "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw" + + "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw" + + "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb" + + "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY" + + "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF" + + "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO" + + "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0" + + "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb" + + "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO" + + "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN" + + "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1" + + "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w="); + + private static readonly byte[] testPubKeyV3 = Base64.Decode( + "mQCNAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + + "wdi2fBUJAAURtApGSVhDSVRZX1FBiQCVAwUQP7O+UZ6Fwdi2fBUJAQFMwwQA" + + "qRnFsdg4xQnB8Y5d4cOpXkIn9AZgYS3cxtuSJB84vG2CgC39nfv4c+nlLkWP" + + "4puG+mZuJNgVoE84cuAF4I//1anKjlU7q1M6rFQnt5S4uxPyG3dFXmgyU1b4" + + "PBOnA0tIxjPzlIhJAMsPCGGA5+5M2JP0ad6RnzqzE3EENMX+GqY="); + + private static readonly byte[] testPrivKeyV3 = Base64.Decode( + "lQHfAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO" + + "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB" + + "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F" + + "wdi2fBUJAAURAXWwRBZQHNikA/f0ScLLjrXi4s0hgQecg+dkpDow94eu5+AR" + + "0DzZnfurpgfUJCNiDi5W/5c3Zj/xyrfMAgkbCgJ1m6FZqAQh7Mq73l7Kfu4/" + + "XIkyDF3tDgRuZNezB+JuElX10tV03xumHepp6M6CfhXqNJ15F33F99TA5hXY" + + "CPYD7SiSOpIhQkCOAgDAA63imxbpuKE2W7Y4I1BUHB7WQi8ZdkZd04njNTv+" + + "rFUuOPapQVfbWG0Vq8ld3YmJB4QWsa2mmqn+qToXbwufAgBpXkjvqK5yPiHF" + + "Px2QbFc1VqoCJB6PO5JRIqEiUZBFGdDlLxt3VSyqz7IZ/zEnxZq+tPCGGGSm" + + "/sAGiMvENcHVAfy0kTXU42TxEAYJyyNyqjXOobDJpEV1mKhFskRXt7tbMfOS" + + "Yf91oX8f6xw6O2Nal+hU8dS0Bmfmk5/enHmvRLHQocO0CkZJWENJVFlfUUE="); + + private static readonly byte[] sig1 = Base64.Decode( + "owGbwMvMwMRoGpHo9vfz52LGNTJJnBmpOTn5eiUVJfb23JvAHIXy/KKcFEWuToap" + + "zKwMIGG4Bqav0SwMy3yParsEKi2LMGI9xhh65sBxb05n5++ZLcWNJ/eLFKdWbm95" + + "tHbDV7GMwj/tUctUpFUXWPYFCLdNsDiVNuXbQvZtdXV/5xzY+9w1nCnijH9JoNiJ" + + "22n2jo0zo30/TZLo+jDl2vTzIvPeLEsPM3ZUE/1Ytqs4SG2TxIQbH7xf3uzcYXq2" + + "5Fw9AA=="); // private static readonly byte[] sig1crc = Base64.Decode("+3i0"); - private static readonly byte[] subKey = Base64.Decode( - "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" - + "CphiUYWnsC0mQ+J15B4="); - - private static readonly byte[] enc1 = Base64.Decode( - "hIwDKwfQexPJboABA/4/7prhYYMORTiQ5avQKx0XYpCLujzGefYjnyuWZnx3Iev8" - + "Pmsguumm+OLLvtXhhkXQmkJRXbIg6Otj2ubPYWflRPgpJSgOrNOreOl5jeABOrtw" - + "bV6TJb9OTtZuB7cTQSCq2gmYiSZkluIiDjNs3R3mEanILbYzOQ3zKSggKpzlv9JQ" - + "AZUqTyDyJ6/OUbJF5fI5uiv76DCsw1zyMWotUIu5/X01q+AVP5Ly3STzI7xkWg/J" - + "APz4zUHism7kSYz2viAQaJx9/bNnH3AM6qm1Fuyikl4="); + private static readonly byte[] subKey = Base64.Decode( + "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" + + "CphiUYWnsC0mQ+J15B4="); + + private static readonly byte[] enc1 = Base64.Decode( + "hIwDKwfQexPJboABA/4/7prhYYMORTiQ5avQKx0XYpCLujzGefYjnyuWZnx3Iev8" + + "Pmsguumm+OLLvtXhhkXQmkJRXbIg6Otj2ubPYWflRPgpJSgOrNOreOl5jeABOrtw" + + "bV6TJb9OTtZuB7cTQSCq2gmYiSZkluIiDjNs3R3mEanILbYzOQ3zKSggKpzlv9JQ" + + "AZUqTyDyJ6/OUbJF5fI5uiv76DCsw1zyMWotUIu5/X01q+AVP5Ly3STzI7xkWg/J" + + "APz4zUHism7kSYz2viAQaJx9/bNnH3AM6qm1Fuyikl4="); // private static readonly byte[] enc1crc = Base64.Decode("lv4o"); @@ -147,192 +147,192 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests // + "Aa7xx8rjCqPbiIQW6t5LqCNvPZOiSCmftll6+se1XJhFEuq8WS4nXtPfTiJ3vib4" // + "3soJdHzGB6AOs+BQ6aKmmNTVAxa5owhtSt1Z/6dfSSk="); - private static readonly byte[] subPubKey = Base64.Decode( + private static readonly byte[] subPubKey = Base64.Decode( "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"); + + "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"); // private static readonly byte[] subPubCrc = Base64.Decode("rikt"); - private static readonly byte[] pgp8Key = Base64.Decode( + private static readonly byte[] pgp8Key = Base64.Decode( "lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF" - + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" - + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" - + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" - + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" - + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" - + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" - + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" - + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" - + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" - + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" - + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" - + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" - + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" - + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" - + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" - + "AgAA"); - - private static readonly char[] pgp8Pass = "2002 Buffalo Sabres".ToCharArray(); - - private static readonly char[] pass = "hello world".ToCharArray(); - - private static readonly byte[] fingerprintKey = Base64.Decode( - "mQEPA0CiJdUAAAEIAMI+znDlPd2kQoEcnxqxLcRz56Z7ttFKHpnYp0UkljZdquVc" - + "By1jMfXGVV64xN1IvMcyenLXUE0IUeUBCQs6tHunFRAPSeCxJ3FdFe1B5MpqQG8A" - + "BnEpAds/hAUfRDZD5y/lolk1hjvFMrRh6WXckaA/QQ2t00NmTrJ1pYUpkw9tnVQb" - + "LUjWJhfZDBBcN0ADtATzgkugxMtcDxR6I5x8Ndn+IilqIm23kxGIcmMd/BHOec4c" - + "jRwJXXDb7u8tl+2knAf9cwhPHp3+Zy4uGSQPdzQnXOhBlA+4WDa0RROOevWgq8uq" - + "8/9Xp/OlTVL+OoIzjsI6mJP1Joa4qmqAnaHAmXcAEQEAAbQoQk9BM1JTS1kgPEJP" - + "QSBNb25pdG9yaW5nIEAgODg4LTI2OS01MjY2PokBFQMFEECiJdWqaoCdocCZdwEB" - + "0RsH/3HPxoUZ3G3K7T3jgOnJUckTSHWU3XspHzMVgqOxjTrcexi5IsAM5M+BulfW" - + "T2aO+Kqf5w8cKTKgW02DNpHUiPjHx0nzDE+Do95zbIErGeK+Twkc4O/aVsvU9GGO" - + "81VFI6WMvDQ4CUAUnAdk03MRrzI2nAuhn4NJ5LQS+uJrnqUJ4HmFAz6CQZQKd/kS" - + "Xgq+A6i7aI1LG80YxWa9ooQgaCrb9dwY/kPQ+yC22zQ3FExtv+Fv3VtAKTilO3vn" - + "BA4Y9uTHuObHfI+1yxUS2PrlRUX0m48ZjpIX+cEN3QblGBJudI/A1QSd6P0LZeBr" - + "7F1Z1aF7ZDo0KzgiAIBvgXkeTpw="); + + "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd" + + "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy" + + "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y" + + "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7" + + "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO" + + "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP" + + "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY" + + "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb" + + "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4" + + "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj" + + "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I" + + "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH" + + "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt" + + "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j" + + "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw" + + "AgAA"); + + private static readonly char[] pgp8Pass = "2002 Buffalo Sabres".ToCharArray(); + + private static readonly char[] pass = "hello world".ToCharArray(); + + private static readonly byte[] fingerprintKey = Base64.Decode( + "mQEPA0CiJdUAAAEIAMI+znDlPd2kQoEcnxqxLcRz56Z7ttFKHpnYp0UkljZdquVc" + + "By1jMfXGVV64xN1IvMcyenLXUE0IUeUBCQs6tHunFRAPSeCxJ3FdFe1B5MpqQG8A" + + "BnEpAds/hAUfRDZD5y/lolk1hjvFMrRh6WXckaA/QQ2t00NmTrJ1pYUpkw9tnVQb" + + "LUjWJhfZDBBcN0ADtATzgkugxMtcDxR6I5x8Ndn+IilqIm23kxGIcmMd/BHOec4c" + + "jRwJXXDb7u8tl+2knAf9cwhPHp3+Zy4uGSQPdzQnXOhBlA+4WDa0RROOevWgq8uq" + + "8/9Xp/OlTVL+OoIzjsI6mJP1Joa4qmqAnaHAmXcAEQEAAbQoQk9BM1JTS1kgPEJP" + + "QSBNb25pdG9yaW5nIEAgODg4LTI2OS01MjY2PokBFQMFEECiJdWqaoCdocCZdwEB" + + "0RsH/3HPxoUZ3G3K7T3jgOnJUckTSHWU3XspHzMVgqOxjTrcexi5IsAM5M+BulfW" + + "T2aO+Kqf5w8cKTKgW02DNpHUiPjHx0nzDE+Do95zbIErGeK+Twkc4O/aVsvU9GGO" + + "81VFI6WMvDQ4CUAUnAdk03MRrzI2nAuhn4NJ5LQS+uJrnqUJ4HmFAz6CQZQKd/kS" + + "Xgq+A6i7aI1LG80YxWa9ooQgaCrb9dwY/kPQ+yC22zQ3FExtv+Fv3VtAKTilO3vn" + + "BA4Y9uTHuObHfI+1yxUS2PrlRUX0m48ZjpIX+cEN3QblGBJudI/A1QSd6P0LZeBr" + + "7F1Z1aF7ZDo0KzgiAIBvgXkeTpw="); // private static readonly byte[] fingerprintCheck = Base64.Decode("CTv2"); - private static readonly byte[] jpegImage = Base64.Decode( - "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"); - - private static readonly byte[] embeddedJPEGKey = Base64.Decode( - "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" - + "Qvmtc8X7lqK/zLRVkSSBItik2IIhsAIAAw=="); - - private void FingerPrintTest() + private static readonly byte[] jpegImage = Base64.Decode( + "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"); + + private static readonly byte[] embeddedJPEGKey = Base64.Decode( + "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" + + "Qvmtc8X7lqK/zLRVkSSBItik2IIhsAIAAw=="); + + private void FingerPrintTest() { // // version 3 // PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(fingerprintKey); - PgpPublicKey pubKey = pgpPub.GetPublicKey(); + PgpPublicKey pubKey = pgpPub.GetPublicKey(); - if (!Arrays.AreEqual(pubKey.GetFingerprint(), Hex.Decode("4FFB9F0884266C715D1CEAC804A3BBFA"))) + if (!Arrays.AreEqual(pubKey.GetFingerprint(), Hex.Decode("4FFB9F0884266C715D1CEAC804A3BBFA"))) { Fail("version 3 fingerprint test failed"); } - // + // // version 4 // pgpPub = new PgpPublicKeyRing(testPubKey); @@ -345,202 +345,202 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests } } - private void MixedTest( - PgpPrivateKey pgpPrivKey, - PgpPublicKey pgpPubKey) - { - byte[] text = Encoding.ASCII.GetBytes("hello world!\n"); - - // - // literal data - // - MemoryStream bOut = new MemoryStream(); - PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); - Stream lOut = lGen.Open( - bOut, - PgpLiteralData.Binary, - PgpLiteralData.Console, - text.Length, - DateTime.UtcNow); - - lOut.Write(text, 0, text.Length); - - lGen.Close(); - - byte[] bytes = bOut.ToArray(); + private void MixedTest( + PgpPrivateKey pgpPrivKey, + PgpPublicKey pgpPubKey) + { + byte[] text = Encoding.ASCII.GetBytes("hello world!\n"); - PgpObjectFactory f = new PgpObjectFactory(bytes); - CheckLiteralData((PgpLiteralData)f.NextPgpObject(), text); + // + // literal data + // + MemoryStream bOut = new MemoryStream(); + PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); + Stream lOut = lGen.Open( + bOut, + PgpLiteralData.Binary, + PgpLiteralData.Console, + text.Length, + DateTime.UtcNow); - MemoryStream bcOut = new MemoryStream(); + lOut.Write(text, 0, text.Length); - PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator( - SymmetricKeyAlgorithmTag.Aes128, - true, - new SecureRandom()); + lGen.Close(); - encGen.AddMethod(pgpPubKey); + byte[] bytes = bOut.ToArray(); - encGen.AddMethod("password".ToCharArray()); + PgpObjectFactory f = new PgpObjectFactory(bytes); + CheckLiteralData((PgpLiteralData)f.NextPgpObject(), text); - Stream cOut = encGen.Open(bcOut, bytes.Length); + MemoryStream bcOut = new MemoryStream(); - cOut.Write(bytes, 0, bytes.Length); + PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator( + SymmetricKeyAlgorithmTag.Aes128, + true, + new SecureRandom()); - cOut.Close(); + encGen.AddMethod(pgpPubKey); - byte[] encData = bcOut.ToArray(); + encGen.AddMethod("password".ToCharArray()); - // - // asymmetric - // - PgpObjectFactory pgpF = new PgpObjectFactory(encData); + Stream cOut = encGen.Open(bcOut, bytes.Length); - PgpEncryptedDataList encList = (PgpEncryptedDataList) pgpF.NextPgpObject(); + cOut.Write(bytes, 0, bytes.Length); - PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0]; + cOut.Close(); - Stream clear = encP.GetDataStream(pgpPrivKey); + byte[] encData = bcOut.ToArray(); - PgpObjectFactory pgpFact = new PgpObjectFactory(clear); + // + // asymmetric + // + PgpObjectFactory pgpF = new PgpObjectFactory(encData); - CheckLiteralData((PgpLiteralData)pgpFact.NextPgpObject(), text); + PgpEncryptedDataList encList = (PgpEncryptedDataList) pgpF.NextPgpObject(); - // - // PBE - // - pgpF = new PgpObjectFactory(encData); + PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0]; - encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); + Stream clear = encP.GetDataStream(pgpPrivKey); - PgpPbeEncryptedData encPbe = (PgpPbeEncryptedData) encList[1]; + PgpObjectFactory pgpFact = new PgpObjectFactory(clear); - clear = encPbe.GetDataStream("password".ToCharArray()); + CheckLiteralData((PgpLiteralData)pgpFact.NextPgpObject(), text); - pgpF = new PgpObjectFactory(clear); + // + // PBE + // + pgpF = new PgpObjectFactory(encData); - CheckLiteralData((PgpLiteralData) pgpF.NextPgpObject(), text); - } + encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); - private void CheckLiteralData( - PgpLiteralData ld, - byte[] data) - { - if (!ld.FileName.Equals(PgpLiteralData.Console)) - throw new Exception("wrong filename in packet"); + PgpPbeEncryptedData encPbe = (PgpPbeEncryptedData) encList[1]; - Stream inLd = ld.GetDataStream(); - byte[] bytes = Streams.ReadAll(inLd); + clear = encPbe.GetDataStream("password".ToCharArray()); - if (!AreEqual(bytes, data)) - { - Fail("wrong plain text in decrypted packet"); - } - } + pgpF = new PgpObjectFactory(clear); - private void ExistingEmbeddedJpegTest() - { - PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(embeddedJPEGKey); + CheckLiteralData((PgpLiteralData) pgpF.NextPgpObject(), text); + } - PgpPublicKey pubKey = pgpPub.GetPublicKey(); + private void CheckLiteralData( + PgpLiteralData ld, + byte[] data) + { + if (!ld.FileName.Equals(PgpLiteralData.Console)) + throw new Exception("wrong filename in packet"); - int count = 0; - foreach (PgpUserAttributeSubpacketVector attributes in pubKey.GetUserAttributes()) - { - int sigCount = 0; - foreach (PgpSignature sig in pubKey.GetSignaturesForUserAttribute(attributes)) - { - sig.InitVerify(pubKey); + Stream inLd = ld.GetDataStream(); + byte[] bytes = Streams.ReadAll(inLd); - if (!sig.VerifyCertification(attributes, pubKey)) - { - Fail("signature failed verification"); - } + if (!AreEqual(bytes, data)) + { + Fail("wrong plain text in decrypted packet"); + } + } - sigCount++; - } + private void ExistingEmbeddedJpegTest() + { + PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(embeddedJPEGKey); - if (sigCount != 1) - { - Fail("Failed user attributes signature check"); - } - count++; - } + PgpPublicKey pubKey = pgpPub.GetPublicKey(); - if (count != 1) - { - Fail("didn't find user attributes"); - } - } + int count = 0; + foreach (PgpUserAttributeSubpacketVector attributes in pubKey.GetUserAttributes()) + { + int sigCount = 0; + foreach (PgpSignature sig in pubKey.GetSignaturesForUserAttribute(attributes)) + { + sig.InitVerify(pubKey); + + if (!sig.VerifyCertification(attributes, pubKey)) + { + Fail("signature failed verification"); + } + + sigCount++; + } + + if (sigCount != 1) + { + Fail("Failed user attributes signature check"); + } + count++; + } - private void EmbeddedJpegTest() - { - PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey); - PgpSecretKeyRing pgpSec = new PgpSecretKeyRing(testPrivKey); + if (count != 1) + { + Fail("didn't find user attributes"); + } + } - PgpPublicKey pubKey = pgpPub.GetPublicKey(); + private void EmbeddedJpegTest() + { + PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey); + PgpSecretKeyRing pgpSec = new PgpSecretKeyRing(testPrivKey); - PgpUserAttributeSubpacketVectorGenerator vGen = new PgpUserAttributeSubpacketVectorGenerator(); + PgpPublicKey pubKey = pgpPub.GetPublicKey(); - vGen.SetImageAttribute(ImageAttrib.Format.Jpeg, jpegImage); + PgpUserAttributeSubpacketVectorGenerator vGen = new PgpUserAttributeSubpacketVectorGenerator(); - PgpUserAttributeSubpacketVector uVec = vGen.Generate(); + vGen.SetImageAttribute(ImageAttrib.Format.Jpeg, jpegImage); - PgpSignatureGenerator sGen = new PgpSignatureGenerator( - PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); + PgpUserAttributeSubpacketVector uVec = vGen.Generate(); - sGen.InitSign(PgpSignature.PositiveCertification, pgpSec.GetSecretKey().ExtractPrivateKey(pass)); + PgpSignatureGenerator sGen = new PgpSignatureGenerator( + PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); - PgpSignature sig = sGen.GenerateCertification(uVec, pubKey); + sGen.InitSign(PgpSignature.PositiveCertification, pgpSec.GetSecretKey().ExtractPrivateKey(pass)); - PgpPublicKey nKey = PgpPublicKey.AddCertification(pubKey, uVec, sig); + PgpSignature sig = sGen.GenerateCertification(uVec, pubKey); - int count = 0; - foreach (PgpUserAttributeSubpacketVector attributes in nKey.GetUserAttributes()) - { - int sigCount = 0; - foreach (PgpSignature s in nKey.GetSignaturesForUserAttribute(attributes)) - { - s.InitVerify(pubKey); + PgpPublicKey nKey = PgpPublicKey.AddCertification(pubKey, uVec, sig); - if (!s.VerifyCertification(attributes, pubKey)) - { - Fail("added signature failed verification"); - } + int count = 0; + foreach (PgpUserAttributeSubpacketVector attributes in nKey.GetUserAttributes()) + { + int sigCount = 0; + foreach (PgpSignature s in nKey.GetSignaturesForUserAttribute(attributes)) + { + s.InitVerify(pubKey); + + if (!s.VerifyCertification(attributes, pubKey)) + { + Fail("added signature failed verification"); + } + + sigCount++; + } + + if (sigCount != 1) + { + Fail("Failed added user attributes signature check"); + } + count++; + } - sigCount++; - } + if (count != 1) + { + Fail("didn't find added user attributes"); + } - if (sigCount != 1) - { - Fail("Failed added user attributes signature check"); - } - count++; - } + nKey = PgpPublicKey.RemoveCertification(nKey, uVec); - if (count != 1) - { - Fail("didn't find added user attributes"); - } - - nKey = PgpPublicKey.RemoveCertification(nKey, uVec); - - if (nKey.GetUserAttributes().GetEnumerator().MoveNext()) - { - Fail("found attributes where none expected"); - } - } + if (nKey.GetUserAttributes().GetEnumerator().MoveNext()) + { + Fail("found attributes where none expected"); + } + } - public override void PerformTest() + public override void PerformTest() { // // Read the public key // PgpPublicKeyRing pgpPub = new PgpPublicKeyRing(testPubKey); - AsymmetricKeyParameter pubKey = pgpPub.GetPublicKey().GetKey(); + AsymmetricKeyParameter pubKey = pgpPub.GetPublicKey().GetKey(); - IEnumerator enumerator = pgpPub.GetPublicKey().GetUserIds().GetEnumerator(); + IEnumerator enumerator = pgpPub.GetPublicKey().GetUserIds().GetEnumerator(); enumerator.MoveNext(); string uid = (string) enumerator.Current; @@ -549,87 +549,85 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests enumerator.MoveNext(); PgpSignature sig = (PgpSignature) enumerator.Current; - sig.InitVerify(pgpPub.GetPublicKey()); + sig.InitVerify(pgpPub.GetPublicKey()); - if (!sig.VerifyCertification(uid, pgpPub.GetPublicKey())) + if (!sig.VerifyCertification(uid, pgpPub.GetPublicKey())) { Fail("failed to verify certification"); } - // + // // write a public key // MemoryStream bOut = new UncloseableMemoryStream(); BcpgOutputStream pOut = new BcpgOutputStream(bOut); - pgpPub.Encode(pOut); + pgpPub.Encode(pOut); - if (!Arrays.AreEqual(bOut.ToArray(), testPubKey)) + if (!Arrays.AreEqual(bOut.ToArray(), testPubKey)) { Fail("public key rewrite failed"); } - // + // // Read the public key // PgpPublicKeyRing pgpPubV3 = new PgpPublicKeyRing(testPubKeyV3); AsymmetricKeyParameter pubKeyV3 = pgpPub.GetPublicKey().GetKey(); - // + // // write a V3 public key // bOut = new UncloseableMemoryStream(); pOut = new BcpgOutputStream(bOut); - pgpPubV3.Encode(pOut); + pgpPubV3.Encode(pOut); - // + // // Read a v3 private key // char[] passP = "FIXCITY_QA".ToCharArray(); -#if INCLUDE_IDEA - { - PgpSecretKeyRing pgpPriv2 = new PgpSecretKeyRing(testPrivKeyV3); - PgpSecretKey pgpPrivSecretKey = pgpPriv2.GetSecretKey(); - PgpPrivateKey pgpPrivKey2 = pgpPrivSecretKey.ExtractPrivateKey(passP); - - // - // write a v3 private key - // - bOut = new UncloseableMemoryStream(); - pOut = new BcpgOutputStream(bOut); - - pgpPriv2.Encode(pOut); - - byte[] result = bOut.ToArray(); - if (!Arrays.AreEqual(result, testPrivKeyV3)) - { - Fail("private key V3 rewrite failed"); - } - } -#endif - - // + { + PgpSecretKeyRing pgpPriv2 = new PgpSecretKeyRing(testPrivKeyV3); + PgpSecretKey pgpPrivSecretKey = pgpPriv2.GetSecretKey(); + PgpPrivateKey pgpPrivKey2 = pgpPrivSecretKey.ExtractPrivateKey(passP); + + // + // write a v3 private key + // + bOut = new UncloseableMemoryStream(); + pOut = new BcpgOutputStream(bOut); + + pgpPriv2.Encode(pOut); + + byte[] result = bOut.ToArray(); + if (!Arrays.AreEqual(result, testPrivKeyV3)) + { + Fail("private key V3 rewrite failed"); + } + } + + // // Read the private key // PgpSecretKeyRing pgpPriv = new PgpSecretKeyRing(testPrivKey); PgpPrivateKey pgpPrivKey = pgpPriv.GetSecretKey().ExtractPrivateKey(pass); - // + // // write a private key // bOut = new UncloseableMemoryStream(); pOut = new BcpgOutputStream(bOut); - pgpPriv.Encode(pOut); + pgpPriv.Encode(pOut); - if (!Arrays.AreEqual(bOut.ToArray(), testPrivKey)) + if (!Arrays.AreEqual(bOut.ToArray(), testPrivKey)) { Fail("private key rewrite failed"); } - // + // // test encryption // IBufferedCipher c = CipherUtilities.GetCipher("RSA"); @@ -637,186 +635,186 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests // c.Init(Cipher.ENCRYPT_MODE, pubKey); c.Init(true, pubKey); - byte[] inBytes = Encoding.ASCII.GetBytes("hello world"); - byte[] outBytes = c.DoFinal(inBytes); + byte[] inBytes = Encoding.ASCII.GetBytes("hello world"); + byte[] outBytes = c.DoFinal(inBytes); // c.Init(Cipher.DECRYPT_MODE, pgpPrivKey.GetKey()); c.Init(false, pgpPrivKey.Key); outBytes = c.DoFinal(outBytes); - if (!Arrays.AreEqual(inBytes, outBytes)) + if (!Arrays.AreEqual(inBytes, outBytes)) { Fail("decryption failed."); } - // + // // test signature message // PgpObjectFactory pgpFact = new PgpObjectFactory(sig1); - PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject(); + PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject(); - pgpFact = new PgpObjectFactory(c1.GetDataStream()); + pgpFact = new PgpObjectFactory(c1.GetDataStream()); - PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); + PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); - PgpOnePassSignature ops = p1[0]; + PgpOnePassSignature ops = p1[0]; - PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject(); + PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject(); - Stream dIn = p2.GetInputStream(); + Stream dIn = p2.GetInputStream(); - ops.InitVerify(pgpPub.GetPublicKey(ops.KeyId)); + ops.InitVerify(pgpPub.GetPublicKey(ops.KeyId)); - int ch; - while ((ch = dIn.ReadByte()) >= 0) + int ch; + while ((ch = dIn.ReadByte()) >= 0) { ops.Update((byte)ch); } - PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); + PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); - if (!ops.Verify(p3[0])) + if (!ops.Verify(p3[0])) { Fail("Failed signature check"); } - // + // // encrypted message - read subkey // pgpPriv = new PgpSecretKeyRing(subKey); - // + // // encrypted message // - byte[] text = Encoding.ASCII.GetBytes("hello world!\n"); + byte[] text = Encoding.ASCII.GetBytes("hello world!\n"); - PgpObjectFactory pgpF = new PgpObjectFactory(enc1); + PgpObjectFactory pgpF = new PgpObjectFactory(enc1); - PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); + PgpEncryptedDataList encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); - PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0]; + PgpPublicKeyEncryptedData encP = (PgpPublicKeyEncryptedData)encList[0]; - pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass); + pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass); - Stream clear = encP.GetDataStream(pgpPrivKey); + Stream clear = encP.GetDataStream(pgpPrivKey); - pgpFact = new PgpObjectFactory(clear); + pgpFact = new PgpObjectFactory(clear); - c1 = (PgpCompressedData)pgpFact.NextPgpObject(); + c1 = (PgpCompressedData)pgpFact.NextPgpObject(); - pgpFact = new PgpObjectFactory(c1.GetDataStream()); + pgpFact = new PgpObjectFactory(c1.GetDataStream()); - PgpLiteralData ld = (PgpLiteralData)pgpFact.NextPgpObject(); + PgpLiteralData ld = (PgpLiteralData)pgpFact.NextPgpObject(); - if (!ld.FileName.Equals("test.txt")) + if (!ld.FileName.Equals("test.txt")) { throw new Exception("wrong filename in packet"); } - Stream inLd = ld.GetDataStream(); - byte[] bytes = Streams.ReadAll(inLd); + Stream inLd = ld.GetDataStream(); + byte[] bytes = Streams.ReadAll(inLd); - if (!Arrays.AreEqual(bytes, text)) + if (!Arrays.AreEqual(bytes, text)) { Fail("wrong plain text in decrypted packet"); } - // + // // encrypt - short message // byte[] shortText = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' }; - MemoryStream cbOut = new UncloseableMemoryStream(); + MemoryStream cbOut = new UncloseableMemoryStream(); PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, new SecureRandom()); PgpPublicKey puK = pgpPriv.GetSecretKey(encP.KeyId).PublicKey; - cPk.AddMethod(puK); + cPk.AddMethod(puK); - Stream cOut = cPk.Open(new UncloseableStream(cbOut), shortText.Length); + Stream cOut = cPk.Open(new UncloseableStream(cbOut), shortText.Length); - cOut.Write(shortText, 0, shortText.Length); + cOut.Write(shortText, 0, shortText.Length); - cOut.Close(); + cOut.Close(); - pgpF = new PgpObjectFactory(cbOut.ToArray()); + pgpF = new PgpObjectFactory(cbOut.ToArray()); - encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); + encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); - encP = (PgpPublicKeyEncryptedData)encList[0]; + encP = (PgpPublicKeyEncryptedData)encList[0]; - pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass); + pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass); - if (encP.GetSymmetricAlgorithm(pgpPrivKey) != SymmetricKeyAlgorithmTag.Cast5) - { - Fail("symmetric algorithm mismatch"); - } + if (encP.GetSymmetricAlgorithm(pgpPrivKey) != SymmetricKeyAlgorithmTag.Cast5) + { + Fail("symmetric algorithm mismatch"); + } - clear = encP.GetDataStream(pgpPrivKey); - outBytes = Streams.ReadAll(clear); + clear = encP.GetDataStream(pgpPrivKey); + outBytes = Streams.ReadAll(clear); - if (!Arrays.AreEqual(outBytes, shortText)) + if (!Arrays.AreEqual(outBytes, shortText)) { Fail("wrong plain text in generated short text packet"); } - // + // // encrypt // cbOut = new UncloseableMemoryStream(); cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, new SecureRandom()); puK = pgpPriv.GetSecretKey(encP.KeyId).PublicKey; - cPk.AddMethod(puK); + cPk.AddMethod(puK); - cOut = cPk.Open(new UncloseableStream(cbOut), text.Length); + cOut = cPk.Open(new UncloseableStream(cbOut), text.Length); - cOut.Write(text, 0, text.Length); + cOut.Write(text, 0, text.Length); - cOut.Close(); + cOut.Close(); - pgpF = new PgpObjectFactory(cbOut.ToArray()); + pgpF = new PgpObjectFactory(cbOut.ToArray()); - encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); + encList = (PgpEncryptedDataList)pgpF.NextPgpObject(); - encP = (PgpPublicKeyEncryptedData)encList[0]; + encP = (PgpPublicKeyEncryptedData)encList[0]; - pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass); + pgpPrivKey = pgpPriv.GetSecretKey(encP.KeyId).ExtractPrivateKey(pass); - clear = encP.GetDataStream(pgpPrivKey); - outBytes = Streams.ReadAll(clear); + clear = encP.GetDataStream(pgpPrivKey); + outBytes = Streams.ReadAll(clear); - if (!Arrays.AreEqual(outBytes, text)) + if (!Arrays.AreEqual(outBytes, text)) { Fail("wrong plain text in generated packet"); } - // + // // read public key with sub key. // pgpF = new PgpObjectFactory(subPubKey); object o; while ((o = pgpFact.NextPgpObject()) != null) { - // TODO Should something be tested here? + // TODO Should something be tested here? // Console.WriteLine(o); } - // + // // key pair generation - CAST5 encryption // char[] passPhrase = "hello".ToCharArray(); IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("RSA"); RsaKeyGenerationParameters genParam = new RsaKeyGenerationParameters( - BigInteger.ValueOf(0x10001), new SecureRandom(), 1024, 25); + BigInteger.ValueOf(0x10001), new SecureRandom(), 1024, 25); - kpg.Init(genParam); + kpg.Init(genParam); - AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); + AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); - PgpSecretKey secretKey = new PgpSecretKey( + PgpSecretKey secretKey = new PgpSecretKey( PgpSignature.DefaultCertification, PublicKeyAlgorithmTag.RsaGeneral, kp.Public, @@ -830,10 +828,10 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests new SecureRandom() ); - PgpPublicKey key = secretKey.PublicKey; + PgpPublicKey key = secretKey.PublicKey; - enumerator = key.GetUserIds().GetEnumerator(); + enumerator = key.GetUserIds().GetEnumerator(); enumerator.MoveNext(); uid = (string) enumerator.Current; @@ -860,212 +858,212 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests byte[] keyEnc = key.GetEncoded(); - key = PgpPublicKey.AddCertification(key, uid, sig); + key = PgpPublicKey.AddCertification(key, uid, sig); - keyEnc = key.GetEncoded(); + keyEnc = key.GetEncoded(); - PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); + PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); - sGen.InitSign(PgpSignature.KeyRevocation, secretKey.ExtractPrivateKey(passPhrase)); + sGen.InitSign(PgpSignature.KeyRevocation, secretKey.ExtractPrivateKey(passPhrase)); - sig = sGen.GenerateCertification(key); + sig = sGen.GenerateCertification(key); - key = PgpPublicKey.AddCertification(key, sig); + key = PgpPublicKey.AddCertification(key, sig); - keyEnc = key.GetEncoded(); + keyEnc = key.GetEncoded(); - PgpPublicKeyRing tmpRing = new PgpPublicKeyRing(keyEnc); + PgpPublicKeyRing tmpRing = new PgpPublicKeyRing(keyEnc); - key = tmpRing.GetPublicKey(); + key = tmpRing.GetPublicKey(); - IEnumerator sgEnum = key.GetSignaturesOfType(PgpSignature.KeyRevocation).GetEnumerator(); + IEnumerator sgEnum = key.GetSignaturesOfType(PgpSignature.KeyRevocation).GetEnumerator(); sgEnum.MoveNext(); sig = (PgpSignature) sgEnum.Current; - sig.InitVerify(key); + sig.InitVerify(key); - if (!sig.VerifyCertification(key)) + if (!sig.VerifyCertification(key)) { Fail("failed to verify revocation certification"); } - // + // // use of PgpKeyPair // PgpKeyPair pgpKp = new PgpKeyPair(PublicKeyAlgorithmTag.RsaGeneral, - kp.Public, kp.Private, DateTime.UtcNow); + kp.Public, kp.Private, DateTime.UtcNow); - PgpPublicKey k1 = pgpKp.PublicKey; + PgpPublicKey k1 = pgpKp.PublicKey; PgpPrivateKey k2 = pgpKp.PrivateKey; k1.GetEncoded(); - MixedTest(k2, k1); + MixedTest(k2, k1); - // + // // key pair generation - AES_256 encryption. // kp = kpg.GenerateKeyPair(); - secretKey = new PgpSecretKey(PgpSignature.DefaultCertification, PublicKeyAlgorithmTag.RsaGeneral, kp.Public, kp.Private, DateTime.UtcNow, "fred", SymmetricKeyAlgorithmTag.Aes256, passPhrase, null, null, new SecureRandom()); + secretKey = new PgpSecretKey(PgpSignature.DefaultCertification, PublicKeyAlgorithmTag.RsaGeneral, kp.Public, kp.Private, DateTime.UtcNow, "fred", SymmetricKeyAlgorithmTag.Aes256, passPhrase, null, null, new SecureRandom()); - secretKey.ExtractPrivateKey(passPhrase); + secretKey.ExtractPrivateKey(passPhrase); - secretKey.Encode(new UncloseableMemoryStream()); + secretKey.Encode(new UncloseableMemoryStream()); - // + // // secret key password changing. // const string newPass = "newPass"; - secretKey = PgpSecretKey.CopyWithNewPassword(secretKey, passPhrase, newPass.ToCharArray(), secretKey.KeyEncryptionAlgorithm, new SecureRandom()); + secretKey = PgpSecretKey.CopyWithNewPassword(secretKey, passPhrase, newPass.ToCharArray(), secretKey.KeyEncryptionAlgorithm, new SecureRandom()); - secretKey.ExtractPrivateKey(newPass.ToCharArray()); + secretKey.ExtractPrivateKey(newPass.ToCharArray()); - secretKey.Encode(new UncloseableMemoryStream()); + secretKey.Encode(new UncloseableMemoryStream()); - key = secretKey.PublicKey; + key = secretKey.PublicKey; - key.Encode(new UncloseableMemoryStream()); + key.Encode(new UncloseableMemoryStream()); - enumerator = key.GetUserIds().GetEnumerator(); + enumerator = key.GetUserIds().GetEnumerator(); enumerator.MoveNext(); uid = (string) enumerator.Current; - enumerator = key.GetSignaturesForId(uid).GetEnumerator(); + enumerator = key.GetSignaturesForId(uid).GetEnumerator(); enumerator.MoveNext(); sig = (PgpSignature) enumerator.Current; - sig.InitVerify(key); + sig.InitVerify(key); - if (!sig.VerifyCertification(uid, key)) + if (!sig.VerifyCertification(uid, key)) { Fail("failed to verify certification"); } - pgpPrivKey = secretKey.ExtractPrivateKey(newPass.ToCharArray()); + pgpPrivKey = secretKey.ExtractPrivateKey(newPass.ToCharArray()); - // + // // signature generation // const string data = "hello world!"; byte[] dataBytes = Encoding.ASCII.GetBytes(data); - bOut = new UncloseableMemoryStream(); + bOut = new UncloseableMemoryStream(); - MemoryStream testIn = new MemoryStream(dataBytes, false); + MemoryStream testIn = new MemoryStream(dataBytes, false); - sGen = new PgpSignatureGenerator( - PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); + sGen = new PgpSignatureGenerator( + PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); - sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); + sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); - PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator( - CompressionAlgorithmTag.Zip); + PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator( + CompressionAlgorithmTag.Zip); - BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut))); + BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut))); - sGen.GenerateOnePassVersion(false).Encode(bcOut); + sGen.GenerateOnePassVersion(false).Encode(bcOut); - PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); + PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); - DateTime testDateTime = new DateTime(1973, 7, 27); - Stream lOut = lGen.Open(new UncloseableStream(bcOut), PgpLiteralData.Binary, "_CONSOLE", + 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) - while ((ch = testIn.ReadByte()) >= 0) + // TODO Need a stream object to automatically call Update? + // (via ISigner implementation of PgpSignatureGenerator) + while ((ch = testIn.ReadByte()) >= 0) { lOut.WriteByte((byte)ch); sGen.Update((byte)ch); } - lOut.Close(); + lOut.Close(); - sGen.Generate().Encode(bcOut); + sGen.Generate().Encode(bcOut); - bcOut.Close(); + bcOut.Close(); - // + // // verify generated signature // pgpFact = new PgpObjectFactory(bOut.ToArray()); - c1 = (PgpCompressedData)pgpFact.NextPgpObject(); + c1 = (PgpCompressedData)pgpFact.NextPgpObject(); - pgpFact = new PgpObjectFactory(c1.GetDataStream()); + pgpFact = new PgpObjectFactory(c1.GetDataStream()); - p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); + p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); - ops = p1[0]; + ops = p1[0]; - p2 = (PgpLiteralData)pgpFact.NextPgpObject(); - if (!p2.ModificationTime.Equals(testDateTime)) - { - Fail("Modification time not preserved"); - } + p2 = (PgpLiteralData)pgpFact.NextPgpObject(); + if (!p2.ModificationTime.Equals(testDateTime)) + { + Fail("Modification time not preserved"); + } - dIn = p2.GetInputStream(); + dIn = p2.GetInputStream(); - ops.InitVerify(secretKey.PublicKey); + ops.InitVerify(secretKey.PublicKey); - // TODO Need a stream object to automatically call Update? - // (via ISigner implementation of PgpSignatureGenerator) - while ((ch = dIn.ReadByte()) >= 0) + // TODO Need a stream object to automatically call Update? + // (via ISigner implementation of PgpSignatureGenerator) + while ((ch = dIn.ReadByte()) >= 0) { ops.Update((byte)ch); } - p3 = (PgpSignatureList)pgpFact.NextPgpObject(); + p3 = (PgpSignatureList)pgpFact.NextPgpObject(); - if (!ops.Verify(p3[0])) + if (!ops.Verify(p3[0])) { Fail("Failed generated signature check"); } - // + // // signature generation - version 3 // bOut = new UncloseableMemoryStream(); - testIn = new MemoryStream(dataBytes); + testIn = new MemoryStream(dataBytes); PgpV3SignatureGenerator sGenV3 = new PgpV3SignatureGenerator( PublicKeyAlgorithmTag.RsaGeneral, HashAlgorithmTag.Sha1); - sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); + sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); - cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip); + cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip); - bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut))); + bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut))); - sGen.GenerateOnePassVersion(false).Encode(bcOut); + sGen.GenerateOnePassVersion(false).Encode(bcOut); - lGen = new PgpLiteralDataGenerator(); - lOut = lGen.Open( - new UncloseableStream(bcOut), - PgpLiteralData.Binary, - "_CONSOLE", - dataBytes.Length, - testDateTime); + lGen = new PgpLiteralDataGenerator(); + 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) - while ((ch = testIn.ReadByte()) >= 0) + // TODO Need a stream object to automatically call Update? + // (via ISigner implementation of PgpSignatureGenerator) + while ((ch = testIn.ReadByte()) >= 0) { lOut.WriteByte((byte) ch); sGen.Update((byte)ch); } - lOut.Close(); + lOut.Close(); - sGen.Generate().Encode(bcOut); + sGen.Generate().Encode(bcOut); - bcOut.Close(); + bcOut.Close(); - // + // // verify generated signature // pgpFact = new PgpObjectFactory(bOut.ToArray()); @@ -1079,18 +1077,18 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests ops = p1[0]; p2 = (PgpLiteralData)pgpFact.NextPgpObject(); - if (!p2.ModificationTime.Equals(testDateTime)) - { - Fail("Modification time not preserved"); - } + if (!p2.ModificationTime.Equals(testDateTime)) + { + Fail("Modification time not preserved"); + } dIn = p2.GetInputStream(); ops.InitVerify(secretKey.PublicKey); - // TODO Need a stream object to automatically call Update? - // (via ISigner implementation of PgpSignatureGenerator) - while ((ch = dIn.ReadByte()) >= 0) + // TODO Need a stream object to automatically call Update? + // (via ISigner implementation of PgpSignatureGenerator) + while ((ch = dIn.ReadByte()) >= 0) { ops.Update((byte)ch); } @@ -1102,27 +1100,27 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests Fail("Failed v3 generated signature check"); } - // + // // extract PGP 8 private key // pgpPriv = new PgpSecretKeyRing(pgp8Key); - secretKey = pgpPriv.GetSecretKey(); + secretKey = pgpPriv.GetSecretKey(); - pgpPrivKey = secretKey.ExtractPrivateKey(pgp8Pass); + pgpPrivKey = secretKey.ExtractPrivateKey(pgp8Pass); - // + // // other sig tests // PerformTestSig(HashAlgorithmTag.Sha256, secretKey.PublicKey, pgpPrivKey); - PerformTestSig(HashAlgorithmTag.Sha384, secretKey.PublicKey, pgpPrivKey); - PerformTestSig(HashAlgorithmTag.Sha512, secretKey.PublicKey, pgpPrivKey); - FingerPrintTest(); - ExistingEmbeddedJpegTest(); - EmbeddedJpegTest(); - } - - private void PerformTestSig( + PerformTestSig(HashAlgorithmTag.Sha384, secretKey.PublicKey, pgpPrivKey); + PerformTestSig(HashAlgorithmTag.Sha512, secretKey.PublicKey, pgpPrivKey); + FingerPrintTest(); + ExistingEmbeddedJpegTest(); + EmbeddedJpegTest(); + } + + private void PerformTestSig( HashAlgorithmTag hashAlgorithm, PgpPublicKey pubKey, PgpPrivateKey privKey) @@ -1130,101 +1128,101 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests const string data = "hello world!"; byte[] dataBytes = Encoding.ASCII.GetBytes(data); - MemoryStream bOut = new UncloseableMemoryStream(); + MemoryStream bOut = new UncloseableMemoryStream(); MemoryStream testIn = new MemoryStream(dataBytes, false); PgpSignatureGenerator sGen = new PgpSignatureGenerator(PublicKeyAlgorithmTag.RsaGeneral, hashAlgorithm); - sGen.InitSign(PgpSignature.BinaryDocument, privKey); + sGen.InitSign(PgpSignature.BinaryDocument, privKey); - PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip); + PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip); - BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut))); + BcpgOutputStream bcOut = new BcpgOutputStream(cGen.Open(new UncloseableStream(bOut))); - sGen.GenerateOnePassVersion(false).Encode(bcOut); + 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", + PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator(); + DateTime testDateTime = new DateTime(1973, 7, 27); + Stream lOut = lGen.Open( + new UncloseableStream(bcOut), + PgpLiteralData.Binary, + "_CONSOLE", dataBytes.Length, - testDateTime); + testDateTime); - // TODO Need a stream object to automatically call Update? - // (via ISigner implementation of PgpSignatureGenerator) - int ch; + // 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(); + lOut.Close(); - sGen.Generate().Encode(bcOut); + sGen.Generate().Encode(bcOut); - bcOut.Close(); + bcOut.Close(); - // + // // verify generated signature // PgpObjectFactory pgpFact = new PgpObjectFactory(bOut.ToArray()); - PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject(); + PgpCompressedData c1 = (PgpCompressedData)pgpFact.NextPgpObject(); - pgpFact = new PgpObjectFactory(c1.GetDataStream()); + pgpFact = new PgpObjectFactory(c1.GetDataStream()); - PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); + PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)pgpFact.NextPgpObject(); - PgpOnePassSignature ops = p1[0]; + PgpOnePassSignature ops = p1[0]; - PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject(); - if (!p2.ModificationTime.Equals(testDateTime)) - { - Fail("Modification time not preserved"); - } + PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject(); + if (!p2.ModificationTime.Equals(testDateTime)) + { + Fail("Modification time not preserved"); + } - Stream dIn = p2.GetInputStream(); + Stream dIn = p2.GetInputStream(); - ops.InitVerify(pubKey); + ops.InitVerify(pubKey); - // TODO Need a stream object to automatically call Update? - // (via ISigner implementation of PgpSignatureGenerator) - while ((ch = dIn.ReadByte()) >= 0) + // 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(); + PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject(); - if (!ops.Verify(p3[0])) + if (!ops.Verify(p3[0])) { Fail("Failed generated signature check - " + hashAlgorithm); } } - private class UncloseableMemoryStream - : MemoryStream - { - public override void Close() - { - throw new Exception("Close() called on underlying stream"); - } - } + private class UncloseableMemoryStream + : MemoryStream + { + public override void Close() + { + throw new Exception("Close() called on underlying stream"); + } + } - public override string Name + public override string Name { - get { return "PGPRSATest"; } + get { return "PGPRSATest"; } } - public static void Main( + public static void Main( string[] args) { RunTest(new PgpRsaTest()); } - [Test] + [Test] public void TestFunction() { string resultText = Perform().ToString(); diff --git a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs index b776a0d2a..2ac2f0c97 100644 --- a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs +++ b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs @@ -14,2150 +14,2148 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests { - [TestFixture] - public class PgpKeyRingTest - : SimpleTest - { - private static readonly byte[] pub1 = Base64.Decode( - "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" - + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" - + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" - + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" - + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" - + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" - + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" - + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" - + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" - + "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh" - + "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB" - + "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p" - + "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5" - + "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN" - + "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE" - + "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1" - + "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu" - + "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y" - + "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB" - + "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u" - + "ZJhfg0htdgAfIy8ppm05vLACAAA="); - - private static readonly byte[] sec1 = Base64.Decode( - "lQHhBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" - + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" - + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" - + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" - + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" - + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" - + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" - + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" - + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" - + "IIeLOTI5Dc4XKeV32a+bWv4CAwJ5KgazImo+sGBfMhDiBcBTqyDGhKHNgHic" - + "0Pky9FeRvfXTc2AO+jGmFPjcs8BnTWuDD0/jkQnRZpp1TrQidGVzdCAoVGVz" - + "dCBrZXkpIDx0ZXN0QHViaWNhbGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB" - + "4TOABgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEJh8Njfhe8KmGDcAn3XeXDMg" - + "BZgrZzFWU2IKtA/5LG2TAJ0Vf/jjyq0jZNZfGfoqGTvD2MAl0rACAACdAVgE" - + "QDzfARAEAJeUAPvUzJJbKcc55Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj4" - + "7UPAD/tQxwz8VAwJySx82ggNLxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j" - + "2BVqZAaX3q79a3eMiql1T0oEAGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOH" - + "AAQNBACD0mVMlAUgd7REYy/1mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWa" - + "Hz6CN1XptdwpDeSYEOFZ0PSuqH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85e" - + "fMBA9jUv/DeBOzRWMFG6sC6yk8NGG7Swea7EHKeQI40G3jgO/+xANtMyTP4C" - + "AwJ5KgazImo+sGBl2C7CFuI+5KM4ZhbtVie7l+OiTpr5JW2z5VgnV3EX9p04" - + "LcGKfQvD65+ELwli6yh8B2zGcipqTaYk3QoYNIhPBBgRAgAPBQJAPN8BAhsM" - + "BQkB4TOAAAoJEJh8Njfhe8KmG7kAniuRkaFFv1pdCBN8JJXpcorHmyouAJ9L" - + "xxmusffR6OI7WgD3XZ0AL8zUC7ACAAA="); + [TestFixture] + public class PgpKeyRingTest + : SimpleTest + { + private static readonly byte[] pub1 = Base64.Decode( + "mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + + "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh" + + "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB" + + "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p" + + "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5" + + "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN" + + "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE" + + "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1" + + "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu" + + "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y" + + "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB" + + "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u" + + "ZJhfg0htdgAfIy8ppm05vLACAAA="); + + private static readonly byte[] sec1 = Base64.Decode( + "lQHhBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn" + + "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg" + + "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf" + + "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ" + + "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G" + + "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ" + + "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG" + + "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP" + + "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif" + + "IIeLOTI5Dc4XKeV32a+bWv4CAwJ5KgazImo+sGBfMhDiBcBTqyDGhKHNgHic" + + "0Pky9FeRvfXTc2AO+jGmFPjcs8BnTWuDD0/jkQnRZpp1TrQidGVzdCAoVGVz" + + "dCBrZXkpIDx0ZXN0QHViaWNhbGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB" + + "4TOABgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEJh8Njfhe8KmGDcAn3XeXDMg" + + "BZgrZzFWU2IKtA/5LG2TAJ0Vf/jjyq0jZNZfGfoqGTvD2MAl0rACAACdAVgE" + + "QDzfARAEAJeUAPvUzJJbKcc55Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj4" + + "7UPAD/tQxwz8VAwJySx82ggNLxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j" + + "2BVqZAaX3q79a3eMiql1T0oEAGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOH" + + "AAQNBACD0mVMlAUgd7REYy/1mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWa" + + "Hz6CN1XptdwpDeSYEOFZ0PSuqH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85e" + + "fMBA9jUv/DeBOzRWMFG6sC6yk8NGG7Swea7EHKeQI40G3jgO/+xANtMyTP4C" + + "AwJ5KgazImo+sGBl2C7CFuI+5KM4ZhbtVie7l+OiTpr5JW2z5VgnV3EX9p04" + + "LcGKfQvD65+ELwli6yh8B2zGcipqTaYk3QoYNIhPBBgRAgAPBQJAPN8BAhsM" + + "BQkB4TOAAAoJEJh8Njfhe8KmG7kAniuRkaFFv1pdCBN8JJXpcorHmyouAJ9L" + + "xxmusffR6OI7WgD3XZ0AL8zUC7ACAAA="); // private static readonly char[] pass1 = "qwertzuiop".ToCharArray(); - private static readonly byte[] pub2 = Base64.Decode( - "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"); - - private static readonly byte[] sec2 = Base64.Decode( - "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" - + "Nifs+ljmsAFn"); - - private static readonly char[] sec2pass1 = "sandhya".ToCharArray(); - private static readonly char[] sec2pass2 = "psai".ToCharArray(); - - private static readonly byte[] pub3 = Base64.Decode( - "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" - + "n3FaE6UZE9GMDmCIAjhI+0X9aH6CsAIAAw=="); - - private static readonly byte[] sec3 = Base64.Decode( - "lQHhBEB9BH0RBACtYQtE7tna6hgGyGLpq+ds3r2cLC0ISn5dNw7tm9vwiNVF" - + "JA2N37RRrifw4PvgelRSvLaX3M3ZBqC9s1Metg3v4FSlIRtSLWCNpHSvNw7i" - + "X8C2Xy9Hdlbh6Y/50o+iscojLRE14upfR1bIkcCZQGSyvGV52V2wBImUUZjV" - + "s2ZngwCg7mu852vK7+euz4WaL7ERVYtq9CMEAJ5swrljerDpz/RQ4Lhp6KER" - + "KyuI0PUttO57xINGshEINgYlZdGaZHRueHe7uKfI19mb0T4N3NJWaZ0wF+Cn" - + "rixsq0VrTUfiwfZeGluNG73aTCeY45fVXMGTTSYXzS8T0LW100Xn/0g9HRyA" - + "xUpuWo8IazxkMqHJis2uwriYKpAfA/9anvj5BS9p5pfPjp9dGM7GTMIYl5f2" - + "fcP57f+AW1TVR6IZiMJAvAdeWuLtwLnJiFpGlnFz273pfl+sAuqm1yNceImR" - + "2SDDP4+vtyycWy8nZhgEuhZx3W3cWMQz5WyNJSY1JJHh9TCQkCoN8E7XpVP4" - + "zEPboB2GzD93mfD8JLHP+/4DAwIvYrn+YqRaaGAu19XUj895g/GROyP8WEaU" - + "Bd/JNqWc4kE/0guetGnPzq7G3bLVwiKfFd4X7BrgHAo3mrQtVGVzdCBLZXkg" - + "KG5vIGNvbW1lbnQpIDx0ZXN0QGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkF" - + "AkB9BH0ECwcDAgMVAgMDFgIBAh4BAheAAAoJEKnMV8vjZQOpSRQAoKZy6YS1" - + "irF5/Q3JlWiwbkN6dEuLAJ9lldRLOlXsuQ5JW1+SLEc6K9ho4rACAADRwXPB" - + "cQEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQEASABIAAD//gAXQ3Jl" - + "YXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZ" - + "EhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sA" - + "QwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy" - + "MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAFAAUAwEiAAIRAQMRAf/EABoA" - + "AQACAwEAAAAAAAAAAAAAAAAEBQIDBgf/xAAoEAABAgUDBAEFAAAAAAAAAAAB" - + "AgMABBEhMQUSQQYTIiNhFFGBkcH/xAAXAQEAAwAAAAAAAAAAAAAAAAAEAgMF" - + "/8QAJBEAAQQAAwkAAAAAAAAAAAAAAQACERIEIfATMTJBUZGx0fH/2gAMAwEA" - + "AhEDEQA/APMuotJlJVxstqaPo22NlAUp+YsNO0qSUtBcMu6n6EtOHcfPAHHF" - + "I16++oajQtTA3DapK02HFR8UpE9pTbQWtKm2WG2rlxVyQTcfGbn7Qm0OIjL7" - + "7Wrs2NNm9lzTmmSxQ0PX4opSprk5tmESF6syggzGwOLG6gXgHFbZhBixk8Xl" - + "IDcOQLRKt+rX+3qC5ZLTQblpQlvwvxn9CMpZturVGkJHapQJphRH8hCLXbzr" - + "qpYsCx1zC5rtpJNuYQhASc0UAQv/2YhcBBMRAgAcBQJAfQV+AhsDBAsHAwID" - + "FQIDAxYCAQIeAQIXgAAKCRCpzFfL42UDqfa2AJ9hjtEeDTbTEAuuSbzhYFxN" - + "/qc0FACgsmzysdbBpuN65yK01tbEaeIMtqCwAgAAnQEUBEB9BH4QAwCqRuWO" - + "rxm5v/8WWBtPEUZnYuu3WYxefRKn6ON5ka5Ymp4AfKpKqKqn982tjlG13GVE" - + "P2ow11L4yQKGNm+VyVEapm7SpMD0SHg9vsJygAWrfMJnBYWSgE19W6o3ckUR" - + "sWsAAwYDAKDCSiSxC3Z5/POaCehw5iHs/vmVk5Wn831LSZEEwkSohNDbIEry" - + "ia/9tFXSt11AP4stJtZ0MH87/6JBbiIRD4JXcx+zfzchL7Teczr/06QMphSn" - + "sAENupbhLupfpR+BbP4DAwIvYrn+YqRaaGBjvFK1fbxCt7ZM4I2W/3BC0lCX" - + "m/NypKNspGflec8u96uUlA0fNCnxm6f9nbB0jpvoKi0g4iqAf+P2iEYEGBEC" - + "AAYFAkB9BH4ACgkQqcxXy+NlA6mtMgCgvccZA/Sg7BXVpxli47SYhxSHoM4A" - + "oNCOMplSnYTuh5ikKeBWtz36gC1psAIAAA=="); - - private static readonly char[] sec3pass1 = "123456".ToCharArray(); - - // - // GPG comment packets. - // - private static readonly byte[] sec4 = Base64.Decode( - "lQG7BD0PbK8RBAC0cW4Y2MZXmAmqYp5Txyw0kSQsFvwZKHNMFRv996IsN57URVF5" - + "BGMVPRBi9dNucWbjiSYpiYN13wE9IuLZsvVaQojV4XWGRDc+Rxz9ElsXnsYQ3mZU" - + "7H1bNQEofstChk4z+dlvPBN4GFahrIzn/CeVUn6Ut7dVdYbiTqviANqNXwCglfVA" - + "2OEePvqFnGxs1jhJyPSOnTED/RwRvsLH/k43mk6UEvOyN1RIpBXN+Ieqs7h1gFrQ" - + "kB+WMgeP5ZUsotTffVDSUS9UMxRQggVUW1Xml0geGwQsNfkr/ztWMs/T4xp1v5j+" - + "QyJx6OqNlkGdqOsoqkzJx0SQ1zBxdinFyyC4H95SDAb/RQOu5LQmxFG7quexztMs" - + "infEA/9cVc9+qCo92yRAaXRqKNVVQIQuPxeUsGMyVeJQvJBD4An8KTMCdjpF10Cp" - + "qA3t+n1S0zKr5WRUtvS6y60MOONO+EJWVWBNkx8HJDaIMNkfoqQoz3Krn7w6FE/v" - + "/5uwMd6jY3N3yJZn5nDZT9Yzv9Nx3j+BrY+henRlSU0c6xDc9QAAnjJYg0Z83VJG" - + "6HrBcgc4+4K6lHulCqH9JiM6RFNBX2ZhY3RvcjoAAK9hV206agp99GI6x5qE9+pU" - + "vs6O+Ich/SYjOkRTQV9mYWN0b3I6AACvYAfGn2FGrpBYbjnpTuFOHJMS/T5xg/0m" - + "IzpEU0FfZmFjdG9yOgAAr0dAQz6XxMwxWIn8xIZR/v2iN2L9C6O0EkZvbyBCYXIg" - + "PGJhekBxdXV4PohXBBMRAgAXBQI9D2yvBQsHCgMEAxUDAgMWAgECF4AACgkQUGLI" - + "YCIktfoGogCfZiXMJUKrScqozv5tMwzTTk2AaT8AniM5iRr0Du/Y08SL/NMhtF6H" - + "hJ89nO4EPQ9ssRADAI6Ggxj6ZBfoavuXd/ye99osW8HsNlbqhXObu5mCMNySX2wa" - + "HoWyRUEaUkI9eQw+MlHzIwzA32E7y2mU3OQBKdgLcBg4jxtcWVEg8ESKF9MpFXxl" - + "pExxWrr4DFBfCRcsTwAFEQL9G3OvwJuEZXgx2JSS41D3pG4/qiHYICVa0u3p/14i" - + "cq0kXajIk5ZJ6frCIAHIzuQ3n7jjzr05yR8s/qCrNbBA+nlkVNa/samk+jCzxxxa" - + "cR/Dbh2wkvTFuDFFETwQYLuZAADcDck4YGQAmHivVT2NNDCf/aTz0+CJWl+xRc2l" - + "Qw7D/SQjOkVMR19mYWN0b3I6AACbBnv9m5/bb/pjYAm2PtDp0CysQ9X9JCM6RUxH" - + "X2ZhY3RvcjoAAJsFyHnSmaWguTFf6lJ/j39LtUNtmf0kIzpFTEdfZmFjdG9yOgAA" - + "mwfwMD3LxmWtuCWBE9BptWMNH07Z/SQjOkVMR19mYWN0b3I6AACbBdhBrbSiM4UN" - + "y7khDW2Sk0e4v9mIRgQYEQIABgUCPQ9ssQAKCRBQYshgIiS1+jCMAJ9txwHnb1Kl" - + "6i/fSoDs8SkdM7w48wCdFvPEV0sSxE73073YhBgPZtMWbBo="); - - // - // PGP freeware version 7 - // - private static readonly byte[] pub5 = Base64.Decode( - "mQENBEBrBE4BCACjXVcNIFDQSofaIyZnALb2CRg+WY9uUqgHEEAOlPe03Cs5STM5" - + "HDlNmrh4TdFceJ46rxk1mQOjULES1YfHay8lCIzrD7FX4oj0r4DC14Fs1vXaSar2" - + "1szIpttOw3obL4A1e0p6N4jjsoG7N/pA0fEL0lSw92SoBrMbAheXRg4qNTZvdjOR" - + "grcuOuwgJRvPLtRXlhyLBoyhkd5mmrIDGv8QHJ/UjpeIcRXY9kn9oGXnEYcRbMaU" - + "VwXB4pLzWqz3ZejFI3lOxRWjm760puPOnGYlzSVBxlt2LgzUgSj1Mn+lIpWmAzsa" - + "xEiU4xUwEomQns72yYRZ6D3euNCibcte4SeXABEBAAG0KXBhbGFzaCBrYXNvZGhh" - + "biA8cGthc29kaGFuQHRpYWEtY3JlZi5vcmc+iQEuBBABAgAYBQJAawROCAsBAwkI" - + "BwIKAhkBBRsDAAAAAAoJEOfelumuiOrYqPEH+wYrdP5Tq5j+E5yN1pyCg1rwbSOt" - + "Dka0y0p7Oq/VIGLk692IWPItLEunnBXQtGBcWqklrvogvlhxtf16FgoyScfLJx1e" - + "1cJa+QQnVuH+VOESN6iS9Gp9lUfVOHv74mEMXw0l2Djfy/lnrkAMBatggyGnF9xF" - + "VXOLk1J2WVFm9KUE23o6qdB7RGkf31pN2eA7SWmkdJSkUH7o/QSFBI+UTRZ/IY5P" - + "ZIJpsdiIOqd9YMG/4RoSZuPqNRR6x7BSs8nQVR9bYs4PPlp4GfdRnOcRonoTeJCZ" - + "83RnsraWJnJTg34gRLBcqumhTuFKc8nuCNK98D6zkQESdcHLLTquCOaF5L+5AQ0E" - + "QGsETwEIAOVwNCTaDZvW4dowPbET1bI5UeYY8rAGLYsWSUfgaFv2srMiApyBVltf" - + "i6OLcPjcUCHDBjCv4pwx/C4qcHWb8av4xQIpqQXOpO9NxYE1eZnel/QB7DtH12ZO" - + "nrDNmHtaXlulcKNGe1i1utlFhgzfFx6rWkRL0ENmkTkaQmPY4gTGymJTUhBbsSRq" - + "2ivWqQA1TPwBuda73UgslIAHRd/SUaxjXoLpMbGOTeqzcKGjr5XMPTs7/YgBpWPP" - + "UxMlEQIiU3ia1bxpEhx05k97ceK6TSH2oCPQA7gumjxOSjKT+jEm+8jACVzymEmc" - + "XRy4D5Ztqkw/Z16pvNcu1DI5m6xHwr8AEQEAAYkBIgQYAQIADAUCQGsETwUbDAAA" - + "AAAKCRDn3pbprojq2EynB/4/cEOtKbI5UisUd3vkTzvWOcqWUqGqi5wjjioNtIM5" - + "pur2nFvhQE7SZ+PbAa87HRJU/4WcWMcoLkHD48JrQwHCHOLHSV5muYowb78X4Yh9" - + "epYtSJ0uUahcn4Gp48p4BkhgsPYXkxEImSYzAOWStv21/7WEMqItMYl89BV6Upm8" - + "HyTJx5MPTDbMR7X51hRg3OeQs6po3WTCWRzFIMyGm1rd/VK1L5ZDFPqO3S6YUJ0z" - + "cxecYruvfK0Wp7q834wE8Zkl/PQ3NhfEPL1ZiLr/L00Ty+77/FZqt8SHRCICzOfP" - + "OawcVGI+xHVXW6lijMpB5VaVIH8i2KdBMHXHtduIkPr9"); - - private static readonly byte[] sec5 = Base64.Decode( - "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"); - - private static readonly char[] sec5pass1 = "12345678".ToCharArray(); - - // - // Werner Koch "odd keys" - // - private static readonly byte[] pub6 = Base64.Decode( - "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" - + "L4Kb7TWkd/OHQScVBO8sTUz0+2g="); + private static readonly byte[] pub2 = Base64.Decode( + "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"); + + private static readonly byte[] sec2 = Base64.Decode( + "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" + + "Nifs+ljmsAFn"); + + private static readonly char[] sec2pass1 = "sandhya".ToCharArray(); + private static readonly char[] sec2pass2 = "psai".ToCharArray(); + + private static readonly byte[] pub3 = Base64.Decode( + "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" + + "n3FaE6UZE9GMDmCIAjhI+0X9aH6CsAIAAw=="); + + private static readonly byte[] sec3 = Base64.Decode( + "lQHhBEB9BH0RBACtYQtE7tna6hgGyGLpq+ds3r2cLC0ISn5dNw7tm9vwiNVF" + + "JA2N37RRrifw4PvgelRSvLaX3M3ZBqC9s1Metg3v4FSlIRtSLWCNpHSvNw7i" + + "X8C2Xy9Hdlbh6Y/50o+iscojLRE14upfR1bIkcCZQGSyvGV52V2wBImUUZjV" + + "s2ZngwCg7mu852vK7+euz4WaL7ERVYtq9CMEAJ5swrljerDpz/RQ4Lhp6KER" + + "KyuI0PUttO57xINGshEINgYlZdGaZHRueHe7uKfI19mb0T4N3NJWaZ0wF+Cn" + + "rixsq0VrTUfiwfZeGluNG73aTCeY45fVXMGTTSYXzS8T0LW100Xn/0g9HRyA" + + "xUpuWo8IazxkMqHJis2uwriYKpAfA/9anvj5BS9p5pfPjp9dGM7GTMIYl5f2" + + "fcP57f+AW1TVR6IZiMJAvAdeWuLtwLnJiFpGlnFz273pfl+sAuqm1yNceImR" + + "2SDDP4+vtyycWy8nZhgEuhZx3W3cWMQz5WyNJSY1JJHh9TCQkCoN8E7XpVP4" + + "zEPboB2GzD93mfD8JLHP+/4DAwIvYrn+YqRaaGAu19XUj895g/GROyP8WEaU" + + "Bd/JNqWc4kE/0guetGnPzq7G3bLVwiKfFd4X7BrgHAo3mrQtVGVzdCBLZXkg" + + "KG5vIGNvbW1lbnQpIDx0ZXN0QGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkF" + + "AkB9BH0ECwcDAgMVAgMDFgIBAh4BAheAAAoJEKnMV8vjZQOpSRQAoKZy6YS1" + + "irF5/Q3JlWiwbkN6dEuLAJ9lldRLOlXsuQ5JW1+SLEc6K9ho4rACAADRwXPB" + + "cQEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQEASABIAAD//gAXQ3Jl" + + "YXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZ" + + "EhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sA" + + "QwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy" + + "MjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAFAAUAwEiAAIRAQMRAf/EABoA" + + "AQACAwEAAAAAAAAAAAAAAAAEBQIDBgf/xAAoEAABAgUDBAEFAAAAAAAAAAAB" + + "AgMABBEhMQUSQQYTIiNhFFGBkcH/xAAXAQEAAwAAAAAAAAAAAAAAAAAEAgMF" + + "/8QAJBEAAQQAAwkAAAAAAAAAAAAAAQACERIEIfATMTJBUZGx0fH/2gAMAwEA" + + "AhEDEQA/APMuotJlJVxstqaPo22NlAUp+YsNO0qSUtBcMu6n6EtOHcfPAHHF" + + "I16++oajQtTA3DapK02HFR8UpE9pTbQWtKm2WG2rlxVyQTcfGbn7Qm0OIjL7" + + "7Wrs2NNm9lzTmmSxQ0PX4opSprk5tmESF6syggzGwOLG6gXgHFbZhBixk8Xl" + + "IDcOQLRKt+rX+3qC5ZLTQblpQlvwvxn9CMpZturVGkJHapQJphRH8hCLXbzr" + + "qpYsCx1zC5rtpJNuYQhASc0UAQv/2YhcBBMRAgAcBQJAfQV+AhsDBAsHAwID" + + "FQIDAxYCAQIeAQIXgAAKCRCpzFfL42UDqfa2AJ9hjtEeDTbTEAuuSbzhYFxN" + + "/qc0FACgsmzysdbBpuN65yK01tbEaeIMtqCwAgAAnQEUBEB9BH4QAwCqRuWO" + + "rxm5v/8WWBtPEUZnYuu3WYxefRKn6ON5ka5Ymp4AfKpKqKqn982tjlG13GVE" + + "P2ow11L4yQKGNm+VyVEapm7SpMD0SHg9vsJygAWrfMJnBYWSgE19W6o3ckUR" + + "sWsAAwYDAKDCSiSxC3Z5/POaCehw5iHs/vmVk5Wn831LSZEEwkSohNDbIEry" + + "ia/9tFXSt11AP4stJtZ0MH87/6JBbiIRD4JXcx+zfzchL7Teczr/06QMphSn" + + "sAENupbhLupfpR+BbP4DAwIvYrn+YqRaaGBjvFK1fbxCt7ZM4I2W/3BC0lCX" + + "m/NypKNspGflec8u96uUlA0fNCnxm6f9nbB0jpvoKi0g4iqAf+P2iEYEGBEC" + + "AAYFAkB9BH4ACgkQqcxXy+NlA6mtMgCgvccZA/Sg7BXVpxli47SYhxSHoM4A" + + "oNCOMplSnYTuh5ikKeBWtz36gC1psAIAAA=="); + + private static readonly char[] sec3pass1 = "123456".ToCharArray(); + + // + // GPG comment packets. + // + private static readonly byte[] sec4 = Base64.Decode( + "lQG7BD0PbK8RBAC0cW4Y2MZXmAmqYp5Txyw0kSQsFvwZKHNMFRv996IsN57URVF5" + + "BGMVPRBi9dNucWbjiSYpiYN13wE9IuLZsvVaQojV4XWGRDc+Rxz9ElsXnsYQ3mZU" + + "7H1bNQEofstChk4z+dlvPBN4GFahrIzn/CeVUn6Ut7dVdYbiTqviANqNXwCglfVA" + + "2OEePvqFnGxs1jhJyPSOnTED/RwRvsLH/k43mk6UEvOyN1RIpBXN+Ieqs7h1gFrQ" + + "kB+WMgeP5ZUsotTffVDSUS9UMxRQggVUW1Xml0geGwQsNfkr/ztWMs/T4xp1v5j+" + + "QyJx6OqNlkGdqOsoqkzJx0SQ1zBxdinFyyC4H95SDAb/RQOu5LQmxFG7quexztMs" + + "infEA/9cVc9+qCo92yRAaXRqKNVVQIQuPxeUsGMyVeJQvJBD4An8KTMCdjpF10Cp" + + "qA3t+n1S0zKr5WRUtvS6y60MOONO+EJWVWBNkx8HJDaIMNkfoqQoz3Krn7w6FE/v" + + "/5uwMd6jY3N3yJZn5nDZT9Yzv9Nx3j+BrY+henRlSU0c6xDc9QAAnjJYg0Z83VJG" + + "6HrBcgc4+4K6lHulCqH9JiM6RFNBX2ZhY3RvcjoAAK9hV206agp99GI6x5qE9+pU" + + "vs6O+Ich/SYjOkRTQV9mYWN0b3I6AACvYAfGn2FGrpBYbjnpTuFOHJMS/T5xg/0m" + + "IzpEU0FfZmFjdG9yOgAAr0dAQz6XxMwxWIn8xIZR/v2iN2L9C6O0EkZvbyBCYXIg" + + "PGJhekBxdXV4PohXBBMRAgAXBQI9D2yvBQsHCgMEAxUDAgMWAgECF4AACgkQUGLI" + + "YCIktfoGogCfZiXMJUKrScqozv5tMwzTTk2AaT8AniM5iRr0Du/Y08SL/NMhtF6H" + + "hJ89nO4EPQ9ssRADAI6Ggxj6ZBfoavuXd/ye99osW8HsNlbqhXObu5mCMNySX2wa" + + "HoWyRUEaUkI9eQw+MlHzIwzA32E7y2mU3OQBKdgLcBg4jxtcWVEg8ESKF9MpFXxl" + + "pExxWrr4DFBfCRcsTwAFEQL9G3OvwJuEZXgx2JSS41D3pG4/qiHYICVa0u3p/14i" + + "cq0kXajIk5ZJ6frCIAHIzuQ3n7jjzr05yR8s/qCrNbBA+nlkVNa/samk+jCzxxxa" + + "cR/Dbh2wkvTFuDFFETwQYLuZAADcDck4YGQAmHivVT2NNDCf/aTz0+CJWl+xRc2l" + + "Qw7D/SQjOkVMR19mYWN0b3I6AACbBnv9m5/bb/pjYAm2PtDp0CysQ9X9JCM6RUxH" + + "X2ZhY3RvcjoAAJsFyHnSmaWguTFf6lJ/j39LtUNtmf0kIzpFTEdfZmFjdG9yOgAA" + + "mwfwMD3LxmWtuCWBE9BptWMNH07Z/SQjOkVMR19mYWN0b3I6AACbBdhBrbSiM4UN" + + "y7khDW2Sk0e4v9mIRgQYEQIABgUCPQ9ssQAKCRBQYshgIiS1+jCMAJ9txwHnb1Kl" + + "6i/fSoDs8SkdM7w48wCdFvPEV0sSxE73073YhBgPZtMWbBo="); + + // + // PGP freeware version 7 + // + private static readonly byte[] pub5 = Base64.Decode( + "mQENBEBrBE4BCACjXVcNIFDQSofaIyZnALb2CRg+WY9uUqgHEEAOlPe03Cs5STM5" + + "HDlNmrh4TdFceJ46rxk1mQOjULES1YfHay8lCIzrD7FX4oj0r4DC14Fs1vXaSar2" + + "1szIpttOw3obL4A1e0p6N4jjsoG7N/pA0fEL0lSw92SoBrMbAheXRg4qNTZvdjOR" + + "grcuOuwgJRvPLtRXlhyLBoyhkd5mmrIDGv8QHJ/UjpeIcRXY9kn9oGXnEYcRbMaU" + + "VwXB4pLzWqz3ZejFI3lOxRWjm760puPOnGYlzSVBxlt2LgzUgSj1Mn+lIpWmAzsa" + + "xEiU4xUwEomQns72yYRZ6D3euNCibcte4SeXABEBAAG0KXBhbGFzaCBrYXNvZGhh" + + "biA8cGthc29kaGFuQHRpYWEtY3JlZi5vcmc+iQEuBBABAgAYBQJAawROCAsBAwkI" + + "BwIKAhkBBRsDAAAAAAoJEOfelumuiOrYqPEH+wYrdP5Tq5j+E5yN1pyCg1rwbSOt" + + "Dka0y0p7Oq/VIGLk692IWPItLEunnBXQtGBcWqklrvogvlhxtf16FgoyScfLJx1e" + + "1cJa+QQnVuH+VOESN6iS9Gp9lUfVOHv74mEMXw0l2Djfy/lnrkAMBatggyGnF9xF" + + "VXOLk1J2WVFm9KUE23o6qdB7RGkf31pN2eA7SWmkdJSkUH7o/QSFBI+UTRZ/IY5P" + + "ZIJpsdiIOqd9YMG/4RoSZuPqNRR6x7BSs8nQVR9bYs4PPlp4GfdRnOcRonoTeJCZ" + + "83RnsraWJnJTg34gRLBcqumhTuFKc8nuCNK98D6zkQESdcHLLTquCOaF5L+5AQ0E" + + "QGsETwEIAOVwNCTaDZvW4dowPbET1bI5UeYY8rAGLYsWSUfgaFv2srMiApyBVltf" + + "i6OLcPjcUCHDBjCv4pwx/C4qcHWb8av4xQIpqQXOpO9NxYE1eZnel/QB7DtH12ZO" + + "nrDNmHtaXlulcKNGe1i1utlFhgzfFx6rWkRL0ENmkTkaQmPY4gTGymJTUhBbsSRq" + + "2ivWqQA1TPwBuda73UgslIAHRd/SUaxjXoLpMbGOTeqzcKGjr5XMPTs7/YgBpWPP" + + "UxMlEQIiU3ia1bxpEhx05k97ceK6TSH2oCPQA7gumjxOSjKT+jEm+8jACVzymEmc" + + "XRy4D5Ztqkw/Z16pvNcu1DI5m6xHwr8AEQEAAYkBIgQYAQIADAUCQGsETwUbDAAA" + + "AAAKCRDn3pbprojq2EynB/4/cEOtKbI5UisUd3vkTzvWOcqWUqGqi5wjjioNtIM5" + + "pur2nFvhQE7SZ+PbAa87HRJU/4WcWMcoLkHD48JrQwHCHOLHSV5muYowb78X4Yh9" + + "epYtSJ0uUahcn4Gp48p4BkhgsPYXkxEImSYzAOWStv21/7WEMqItMYl89BV6Upm8" + + "HyTJx5MPTDbMR7X51hRg3OeQs6po3WTCWRzFIMyGm1rd/VK1L5ZDFPqO3S6YUJ0z" + + "cxecYruvfK0Wp7q834wE8Zkl/PQ3NhfEPL1ZiLr/L00Ty+77/FZqt8SHRCICzOfP" + + "OawcVGI+xHVXW6lijMpB5VaVIH8i2KdBMHXHtduIkPr9"); + + private static readonly byte[] sec5 = Base64.Decode( + "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"); + + private static readonly char[] sec5pass1 = "12345678".ToCharArray(); + + // + // Werner Koch "odd keys" + // + private static readonly byte[] pub6 = Base64.Decode( + "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" + + "L4Kb7TWkd/OHQScVBO8sTUz0+2g="); // private static readonly byte[] pub6check = Base64.Decode("62O9"); - // - // revoked sub key - // - private static readonly byte[] pub7 = Base64.Decode( - "mQGiBEFOsIwRBADcjRx7nAs4RaWsQU6p8/ECLZD9sSeYc6CN6UDI96RKj0/hCzMs" - + "qlA0+9fzGZ7ZEJ34nuvDKlhKGC7co5eOiE0a9EijxgcrZU/LClZWa4YfyNg/ri6I" - + "yTyfOfrPQ33GNQt2iImDf3FKp7XKuY9nIxicGQEaW0kkuAmbV3oh0+9q8QCg/+fS" - + "epDEqEE/+nKONULGizKUjMED/RtL6RThRftZ9DOSdBytGYd48z35pca/qZ6HA36K" - + "PVQwi7V77VKQyKFLTOXPLnVyO85hyYB/Nv4DFHN+vcC7/49lfoyYMZlN+LarckHi" - + "NL154wmmzygB/KKysvWBLgkErEBCD0xBDd89iTQNlDtVQAWGORVffl6WWjOAkliG" - + "3dL6A/9A288HfFRnywqi3xddriV6wCPmStC3dkCS4vHk2ofS8uw4ZNoRlp1iEPna" - + "ai2Xa9DX1tkhaGk2k96MqqbBdGpbW8sMA9otJ9xdMjWEm/CgJUFUFQf3zaVy3mkM" - + "S2Lvb6P4Wc2l/diEEIyK8+PqJItSh0OVU3K9oM7ngHwVcalKILQVUkV2b2tlZCA8" - + "UmV2b2tlZEB0ZWQ+iQBOBBARAgAOBQJBTrCMBAsDAgECGQEACgkQvglkcFA/c63+" - + "QgCguh8rsJbPTtbhZcrqBi5Mo1bntLEAoPZQ0Kjmu2knRUpHBeUemHDB6zQeuQIN" - + "BEFOsIwQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz" - + "0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRP" - + "xfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvN" - + "ILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dD" - + "ox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMI" - + "PWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/93zriSvSHqsi1FeEmUBo431Jkh" - + "VerIzb6Plb1j6FIq+s3vyvx9K+dMvjotZqylWZj4GXpH+2xLJTjWkrGSfUZVI2Nk" - + "nyOFxUCKLLqaqVBFAQIjULfvQfGEWiGQKk9aRLkdG+D+8Y2N9zYoBXoQ9arvvS/t" - + "4mlOsiuaTe+BZ4x+BXTpF4b9sKZl7V8QP/TkoJWUdydkvxciHdWp7ssqyiKOFRhG" - + "818knDfFQ3cn2w/RnOb+7AF9wDncXDPYLfpPv9b2qZoLrXcyvlLffGDUdWs553ut" - + "1F5AprMURs8BGmY9BnjggfVubHdhTUoA4gVvrdaf+D9NwZAl0xK/5Y/oPuMZiQBG" - + "BBgRAgAGBQJBTrCMAAoJEL4JZHBQP3Ot09gAoMmLKloVDP+WhDXnsM5VikxysZ4+" - + "AKCrJAUO+lYAyPYwEwgK+bKmUGeKrIkARgQoEQIABgUCQU6wpQAKCRC+CWRwUD9z" - + "rQK4AJ98kKFxGU6yhHPr6jYBJPWemTNOXgCfeGB3ox4PXeS4DJDuLy9yllytOjo="); + // + // revoked sub key + // + private static readonly byte[] pub7 = Base64.Decode( + "mQGiBEFOsIwRBADcjRx7nAs4RaWsQU6p8/ECLZD9sSeYc6CN6UDI96RKj0/hCzMs" + + "qlA0+9fzGZ7ZEJ34nuvDKlhKGC7co5eOiE0a9EijxgcrZU/LClZWa4YfyNg/ri6I" + + "yTyfOfrPQ33GNQt2iImDf3FKp7XKuY9nIxicGQEaW0kkuAmbV3oh0+9q8QCg/+fS" + + "epDEqEE/+nKONULGizKUjMED/RtL6RThRftZ9DOSdBytGYd48z35pca/qZ6HA36K" + + "PVQwi7V77VKQyKFLTOXPLnVyO85hyYB/Nv4DFHN+vcC7/49lfoyYMZlN+LarckHi" + + "NL154wmmzygB/KKysvWBLgkErEBCD0xBDd89iTQNlDtVQAWGORVffl6WWjOAkliG" + + "3dL6A/9A288HfFRnywqi3xddriV6wCPmStC3dkCS4vHk2ofS8uw4ZNoRlp1iEPna" + + "ai2Xa9DX1tkhaGk2k96MqqbBdGpbW8sMA9otJ9xdMjWEm/CgJUFUFQf3zaVy3mkM" + + "S2Lvb6P4Wc2l/diEEIyK8+PqJItSh0OVU3K9oM7ngHwVcalKILQVUkV2b2tlZCA8" + + "UmV2b2tlZEB0ZWQ+iQBOBBARAgAOBQJBTrCMBAsDAgECGQEACgkQvglkcFA/c63+" + + "QgCguh8rsJbPTtbhZcrqBi5Mo1bntLEAoPZQ0Kjmu2knRUpHBeUemHDB6zQeuQIN" + + "BEFOsIwQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz" + + "0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRP" + + "xfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvN" + + "ILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dD" + + "ox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMI" + + "PWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/93zriSvSHqsi1FeEmUBo431Jkh" + + "VerIzb6Plb1j6FIq+s3vyvx9K+dMvjotZqylWZj4GXpH+2xLJTjWkrGSfUZVI2Nk" + + "nyOFxUCKLLqaqVBFAQIjULfvQfGEWiGQKk9aRLkdG+D+8Y2N9zYoBXoQ9arvvS/t" + + "4mlOsiuaTe+BZ4x+BXTpF4b9sKZl7V8QP/TkoJWUdydkvxciHdWp7ssqyiKOFRhG" + + "818knDfFQ3cn2w/RnOb+7AF9wDncXDPYLfpPv9b2qZoLrXcyvlLffGDUdWs553ut" + + "1F5AprMURs8BGmY9BnjggfVubHdhTUoA4gVvrdaf+D9NwZAl0xK/5Y/oPuMZiQBG" + + "BBgRAgAGBQJBTrCMAAoJEL4JZHBQP3Ot09gAoMmLKloVDP+WhDXnsM5VikxysZ4+" + + "AKCrJAUO+lYAyPYwEwgK+bKmUGeKrIkARgQoEQIABgUCQU6wpQAKCRC+CWRwUD9z" + + "rQK4AJ98kKFxGU6yhHPr6jYBJPWemTNOXgCfeGB3ox4PXeS4DJDuLy9yllytOjo="); // private static readonly byte[] pub7check = Base64.Decode("f/YQ"); - private static readonly byte[] pub8 = Base64.Decode( - "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" - + "9Uqz3fUvGoewAWA="); - - private static readonly byte[] sec8 = Base64.Decode( - "lQHpBEEcraYRBADFYj+uFOhHz5SdECvJ3Z03P47gzmWLQ5HH8fPYC9rrv7AgqFFX" - + "aWlJJVMLua9e6xoCiDWJs/n4BbZ/weL/11ELg6XqUnzFhYyz0H2KFsPgQ/b9lWLY" - + "MtcPMFy5jE33hv/ixHgYLFqoNaAIbg0lzYEW/otQ9IhRl16fO1Q/CQZZrQCg/9M2" - + "V2BTmm9RYog86CXJtjawRBcD/RIqU0zulxZ2Zt4javKVxrGIwW3iBU935ebmJEIK" - + "Y5EVkGKBOCvsApZ+RGzpYeR2uMsTnQi8RJgiAnjaoVPCdsVJE7uQ0h8XuJ5n5mJ2" - + "kLCFlF2hj5ViicZzse+crC12CGtgRe8z23ubLRcd6IUGhVutK8/b5knZ22vE14JD" - + "ykKdA/96ObzJQdiuuPsEWN799nUUCaYWPAoLAmiXuICSP4GEnxLbYHWo8zhMrVMT" - + "9Q5x3h8cszUz7Acu2BXjP1m96msUNoxPOZtt88NlaFz1Q/JSbQTsVOMd9b/IRN6S" - + "A/uU0BiKEMHXuT8HUHVPK49oCKhZrGFP3RT8HZxDKLmR/qrgZ/4JAwLXyWhb4pf4" - + "nmCmD0lDwoYvatLiR7UQVM2MamxClIiT0lCPN9C2AYIFgRWAJNS215Tjx7P/dh7e" - + "8sYfh5XEHErT3dMbsAGHtCFKaWEgWWl5dSA8eXlqaWFAbm93bWVkaWF0ZWNoLmNv" - + "bT6wAwP//4kAXQQQEQIAHQUCQRytpgcLCQgHAwIKAhkBBRsDAAAABR4BAAAAAAoJ" - + "EPT+Vvgr/2IUmWEAoJEyJ9B7CJfmjwVTT30UbdCctVRmAJ9akw6we6UYd82vF0FK" - + "QTlSuqHXKbABZ50CawRBHK2mEAgA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlL" - + "OCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N" - + "286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/" - + "RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2O" - + "u1WMuF040zT9fBdXQ6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqV" - + "DNmWn6vQClCbAkbTCD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwACAgf/crbApFLO" - + "QikN9lHbn62dDxuu/dNigNmjf/A3cX+vo8aPHTXnRDyDwQALRuqbitdbM6p1LFjG" - + "8g84Aabk/jL7zzjJLqPe8pxeK1Pu+P44NzalXAYMsOOsxGuixIrz3Jw8IrpH/mkP" - + "tG/iX0NaLZ+Au9eokdLb+6NR/a51r2qL3E0ycFciJ61HzZKKHi6d0VQ7CHozCz+j" - + "d5530Mh1qq/ZjYDDjfP+snpyNIZXcLtGR/3HzkBqNgDcvClLx3322AWKDa7pX8DX" - + "qiLr8znWhPRpH9kCTnSpRzhYGT25FRcvdj4/q/oUIET/Tp+BWW3BxAc7WgpgqEfn" - + "fa0Mv72Zbn91gf4JAwITijME9IlFBGAwH6YmBtWIlnDiRbsq/Pxozuhbnes831il" - + "KmdpUKXkiIfHY0MqrEWl3Dfn6PMJGTnhgqXMrDxx3uHrq0Jl2swRnAWIIO8gID7j" - + "uPetUqEviPiwAYeJAEwEGBECAAwFAkEcraYFGwwAAAAACgkQ9P5W+Cv/YhShrgCg" - + "+JW8m5nF3R/oZGuG87bXQBszkjMAoLhGPncuGKowJXMRVc70/8qwXQJLsAFn"); - - private static readonly char[] sec8pass = "qwertyui".ToCharArray(); - - private static readonly byte[] sec9 = Base64.Decode( - "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" - + "6neEEX/i1Q=="); - - public char[] sec9pass = "foo".ToCharArray(); - - // version 4 keys with expiry dates - private static readonly byte[] pub10 = Base64.Decode( - "mQGiBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" - + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" - + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" - + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" - + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" - + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" - + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" - + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" - + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHLQgdGVzdCBrZXkg" - + "KHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUCQqqJrQIbAwUJACTqAAYL" - + "CQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzLAJ42AeCRIBBjv8r8qw9y" - + "laNj2GZ1sACgiWYHVXMA6B1H9I1kS3YsCd3Oq7qwAgAAuM0EQqqJrhADAKWkix8l" - + "pJN7MMTXob4xFF1TvGll0UD1bDGOMMbes6aeXSbT9QXee/fH3GnijLY7wB+qTPv9" - + "ohubrSpnv3yen3CEBW6Q2YK+NlCskma42Py8YMV2idmYjtJi1ckvHFWt5wADBQL/" - + "fkB5Q5xSGgspMaTZmtmX3zG7ZDeZ0avP8e8mRL8UszCTpqs6vMZrXwyQLZPbtMYv" - + "PQpuRGEeKj0ysimwYRA5rrLQjnRER3nyuuEUUgc4j+aeRxPf9WVsJ/a1FCHtaAP1" - + "iE8EGBECAA8FAkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCfd66H7DL7kFGd" - + "IoS+NIp8JO+noxAAn25si4QAF7og8+4T5YQUuhIhx/NesAIAAA=="); - - private static readonly byte[] sec10 = Base64.Decode( - "lQHhBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" - + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" - + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" - + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" - + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" - + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" - + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" - + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" - + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHP4DAwLssmOjVC+d" - + "mWB783Lpzjb9evKzsxisTdx8/jHpUSS+r//6/Guyx3aA/zUw5bbftItW57mhuNNb" - + "JTu7WrQgdGVzdCBrZXkgKHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUC" - + "QqqJrQIbAwUJACTqAAYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzL" - + "AJ0cYPwKeoSReY14LqJtAjnkX7URHACgsRZWfpbalrSyDnq3TtZeGPUqGX+wAgAA" - + "nQEUBEKqia4QAwClpIsfJaSTezDE16G+MRRdU7xpZdFA9WwxjjDG3rOmnl0m0/UF" - + "3nv3x9xp4oy2O8Afqkz7/aIbm60qZ798np9whAVukNmCvjZQrJJmuNj8vGDFdonZ" - + "mI7SYtXJLxxVrecAAwUC/35AeUOcUhoLKTGk2ZrZl98xu2Q3mdGrz/HvJkS/FLMw" - + "k6arOrzGa18MkC2T27TGLz0KbkRhHio9MrIpsGEQOa6y0I50REd58rrhFFIHOI/m" - + "nkcT3/VlbCf2tRQh7WgD9f4DAwLssmOjVC+dmWDXVLRopzxbBGOvodp/LZoSDb56" - + "gNJjDMJ1aXqWW9qTAg1CFjBq73J3oFpVzInXZ8+Q8inxv7bnWiHbiE8EGBECAA8F" - + "AkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCgl2jw5hfk/JsyjulQqe1Nps1q" - + "Lx0AoMdnFMZmTMLHn8scUW2j9XO312tmsAIAAA=="); + private static readonly byte[] pub8 = Base64.Decode( + "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" + + "9Uqz3fUvGoewAWA="); + + private static readonly byte[] sec8 = Base64.Decode( + "lQHpBEEcraYRBADFYj+uFOhHz5SdECvJ3Z03P47gzmWLQ5HH8fPYC9rrv7AgqFFX" + + "aWlJJVMLua9e6xoCiDWJs/n4BbZ/weL/11ELg6XqUnzFhYyz0H2KFsPgQ/b9lWLY" + + "MtcPMFy5jE33hv/ixHgYLFqoNaAIbg0lzYEW/otQ9IhRl16fO1Q/CQZZrQCg/9M2" + + "V2BTmm9RYog86CXJtjawRBcD/RIqU0zulxZ2Zt4javKVxrGIwW3iBU935ebmJEIK" + + "Y5EVkGKBOCvsApZ+RGzpYeR2uMsTnQi8RJgiAnjaoVPCdsVJE7uQ0h8XuJ5n5mJ2" + + "kLCFlF2hj5ViicZzse+crC12CGtgRe8z23ubLRcd6IUGhVutK8/b5knZ22vE14JD" + + "ykKdA/96ObzJQdiuuPsEWN799nUUCaYWPAoLAmiXuICSP4GEnxLbYHWo8zhMrVMT" + + "9Q5x3h8cszUz7Acu2BXjP1m96msUNoxPOZtt88NlaFz1Q/JSbQTsVOMd9b/IRN6S" + + "A/uU0BiKEMHXuT8HUHVPK49oCKhZrGFP3RT8HZxDKLmR/qrgZ/4JAwLXyWhb4pf4" + + "nmCmD0lDwoYvatLiR7UQVM2MamxClIiT0lCPN9C2AYIFgRWAJNS215Tjx7P/dh7e" + + "8sYfh5XEHErT3dMbsAGHtCFKaWEgWWl5dSA8eXlqaWFAbm93bWVkaWF0ZWNoLmNv" + + "bT6wAwP//4kAXQQQEQIAHQUCQRytpgcLCQgHAwIKAhkBBRsDAAAABR4BAAAAAAoJ" + + "EPT+Vvgr/2IUmWEAoJEyJ9B7CJfmjwVTT30UbdCctVRmAJ9akw6we6UYd82vF0FK" + + "QTlSuqHXKbABZ50CawRBHK2mEAgA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlL" + + "OCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N" + + "286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/" + + "RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2O" + + "u1WMuF040zT9fBdXQ6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqV" + + "DNmWn6vQClCbAkbTCD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwACAgf/crbApFLO" + + "QikN9lHbn62dDxuu/dNigNmjf/A3cX+vo8aPHTXnRDyDwQALRuqbitdbM6p1LFjG" + + "8g84Aabk/jL7zzjJLqPe8pxeK1Pu+P44NzalXAYMsOOsxGuixIrz3Jw8IrpH/mkP" + + "tG/iX0NaLZ+Au9eokdLb+6NR/a51r2qL3E0ycFciJ61HzZKKHi6d0VQ7CHozCz+j" + + "d5530Mh1qq/ZjYDDjfP+snpyNIZXcLtGR/3HzkBqNgDcvClLx3322AWKDa7pX8DX" + + "qiLr8znWhPRpH9kCTnSpRzhYGT25FRcvdj4/q/oUIET/Tp+BWW3BxAc7WgpgqEfn" + + "fa0Mv72Zbn91gf4JAwITijME9IlFBGAwH6YmBtWIlnDiRbsq/Pxozuhbnes831il" + + "KmdpUKXkiIfHY0MqrEWl3Dfn6PMJGTnhgqXMrDxx3uHrq0Jl2swRnAWIIO8gID7j" + + "uPetUqEviPiwAYeJAEwEGBECAAwFAkEcraYFGwwAAAAACgkQ9P5W+Cv/YhShrgCg" + + "+JW8m5nF3R/oZGuG87bXQBszkjMAoLhGPncuGKowJXMRVc70/8qwXQJLsAFn"); + + private static readonly char[] sec8pass = "qwertyui".ToCharArray(); + + private static readonly byte[] sec9 = Base64.Decode( + "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" + + "6neEEX/i1Q=="); + + public char[] sec9pass = "foo".ToCharArray(); + + // version 4 keys with expiry dates + private static readonly byte[] pub10 = Base64.Decode( + "mQGiBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" + + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" + + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" + + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" + + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" + + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" + + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" + + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" + + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHLQgdGVzdCBrZXkg" + + "KHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUCQqqJrQIbAwUJACTqAAYL" + + "CQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzLAJ42AeCRIBBjv8r8qw9y" + + "laNj2GZ1sACgiWYHVXMA6B1H9I1kS3YsCd3Oq7qwAgAAuM0EQqqJrhADAKWkix8l" + + "pJN7MMTXob4xFF1TvGll0UD1bDGOMMbes6aeXSbT9QXee/fH3GnijLY7wB+qTPv9" + + "ohubrSpnv3yen3CEBW6Q2YK+NlCskma42Py8YMV2idmYjtJi1ckvHFWt5wADBQL/" + + "fkB5Q5xSGgspMaTZmtmX3zG7ZDeZ0avP8e8mRL8UszCTpqs6vMZrXwyQLZPbtMYv" + + "PQpuRGEeKj0ysimwYRA5rrLQjnRER3nyuuEUUgc4j+aeRxPf9WVsJ/a1FCHtaAP1" + + "iE8EGBECAA8FAkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCfd66H7DL7kFGd" + + "IoS+NIp8JO+noxAAn25si4QAF7og8+4T5YQUuhIhx/NesAIAAA=="); + + private static readonly byte[] sec10 = Base64.Decode( + "lQHhBEKqia0RBACc3hkufmscRSC4UvPZqMDsHm4+d/GXIr+3iNMSSEySJu8yk+k0" + + "Xs11C/K+n+v1rnn2jGGknv+1lDY6w75TIcTE6o6HGKeIDxsAm8P3MhoGU1GNPamA" + + "eTDeNybtrN/g6C65fCY9uI11hsUboYgQZ8ND22PB0VtvdOgq9D85qNUzxwCg1BbJ" + + "ycAKd4VqEvQ2Zglp3dCSrFMD/Ambq1kZqYa69sp3b9BPKuAgUgUPoytOArEej3Bk" + + "easAgAxNhWJy4GxigES3vk50rVi7w8XBuqbD1mQCzldF0HX0/A7PxLBv6od5uqqF" + + "HFxIyxg/KBZLd9ZOrsSaoUWH58jZq98X/sFtJtRi5VuJagMxCIJD4mLgtMv7Unlb" + + "/GrsA/9DEnObA/fNTgK70T+ZmPIS5tSt+bio30Aw4YGpPCGqpnm1u73b5kqX3U3B" + + "P+vGDvFuqZYpqQA8byAueH0MbaDHI4CFugvShXvgysJxN7ov7/8qsZZUMfK1t2Nr" + + "SAsPuKRbcY4gNKXIElKeXbyaET7vX7uAEKuxEwdYGFp/lNTkHP4DAwLssmOjVC+d" + + "mWB783Lpzjb9evKzsxisTdx8/jHpUSS+r//6/Guyx3aA/zUw5bbftItW57mhuNNb" + + "JTu7WrQgdGVzdCBrZXkgKHRlc3QpIDx0ZXN0QHRlc3QudGVzdD6IZAQTEQIAJAUC" + + "QqqJrQIbAwUJACTqAAYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDjDROQZRqIzDzL" + + "AJ0cYPwKeoSReY14LqJtAjnkX7URHACgsRZWfpbalrSyDnq3TtZeGPUqGX+wAgAA" + + "nQEUBEKqia4QAwClpIsfJaSTezDE16G+MRRdU7xpZdFA9WwxjjDG3rOmnl0m0/UF" + + "3nv3x9xp4oy2O8Afqkz7/aIbm60qZ798np9whAVukNmCvjZQrJJmuNj8vGDFdonZ" + + "mI7SYtXJLxxVrecAAwUC/35AeUOcUhoLKTGk2ZrZl98xu2Q3mdGrz/HvJkS/FLMw" + + "k6arOrzGa18MkC2T27TGLz0KbkRhHio9MrIpsGEQOa6y0I50REd58rrhFFIHOI/m" + + "nkcT3/VlbCf2tRQh7WgD9f4DAwLssmOjVC+dmWDXVLRopzxbBGOvodp/LZoSDb56" + + "gNJjDMJ1aXqWW9qTAg1CFjBq73J3oFpVzInXZ8+Q8inxv7bnWiHbiE8EGBECAA8F" + + "AkKqia4CGwwFCQAk6gAACgkQ4w0TkGUaiMzdqgCgl2jw5hfk/JsyjulQqe1Nps1q" + + "Lx0AoMdnFMZmTMLHn8scUW2j9XO312tmsAIAAA=="); // private static readonly char[] sec10pass = "test".ToCharArray(); - private static readonly byte[] subKeyBindingKey = Base64.Decode( - "mQGiBDWagYwRBAD7UcH4TAIp7tmUoHBNxVxCVz2ZrNo79M6fV63riOiH2uDxfIpr" - + "IrL0cM4ehEKoqlhngjDhX60eJrOw1nC5BpYZRnDnyDYT4wTWRguxObzGq9pqA1dM" - + "oPTJhkFZVIBgFY99/ULRqaUYIhFGgBtnwS70J8/L/PGVc3DmWRLMkTDjSQCg/5Nh" - + "MCjMK++MdYMcMl/ziaKRT6EEAOtw6PnU9afdohbpx9CK4UvCCEagfbnUtkSCQKSk" - + "6cUp6VsqyzY0pai/BwJ3h4apFMMMpVrtBAtchVgqo4xTr0Sve2j0k+ase6FSImiB" - + "g+AR7hvTUTcBjwtIExBc8TuCTqmn4GG8F7UMdl5Z0AZYj/FfAQYaRVZYP/pRVFNx" - + "Lw65BAC/Fi3qgiGCJFvXnHIckTfcAmZnKSEXWY9NJ4YQb4+/nH7Vsw0wR/ZObUHR" - + "bWgTc9Vw1uZIMe0XVj6Yk1dhGRehUnrm3mE7UJxu7pgkBCbFECFSlSSqP4MEJwZV" - + "09YP/msu50kjoxyoTpt+16uX/8B4at24GF1aTHBxwDLd8X0QWrQsTWVycmlsbCBM" - + "eW5jaCBDTEVBUiBzeXN0ZW0gREggPGNsZWFyQG1sLmNvbT6JAEsEEBECAAsFAjWa" - + "gYwECwMBAgAKCRDyAGjiP47/XanfAKCs6BPURWVQlGh635VgL+pdkUVNUwCdFcNa" - + "1isw+eAcopXPMj6ACOapepu5Ag0ENZqBlBAIAPZCV7cIfwgXcqK61qlC8wXo+VMR" - + "OU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf" - + "3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2g" - + "pXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPA" - + "Q/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQD" - + "GcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsAAgIH" - + "/RYtVo+HROZ6jrNjrATEwQm1fUQrk6n5+2dniN881lF0CNkB4NkHw1Xxz4Ejnu/0" - + "iLg8fkOAsmanOsKpOkRtqUnVpsVL5mLJpFEyCY5jbcfj+KY9/25bs0ga7kLHNZia" - + "zbCxJdF+W179z3nudQxRaXG/0XISIH7ziZbSVni69sKc1osk1+OoOMbSuZ86z535" - + "Pln4fXclkFE927HxfbWoO+60hkOLKh7x+8fC82b3x9vCETujEaxrscO2xS7/MYXP" - + "8t1ffriTDmhuIuQS2q4fLgeWdqrODrMhrD8Dq7e558gzp30ZCqpiS7EmKGczL7B8" - + "gXxbBCVSTxYMJheXt2xMXsuJAD8DBRg1moGU8gBo4j+O/10RAgWdAKCPhaFIXuC8" - + "/cdiNMxTDw9ug3De5QCfYXmDzRSFUu/nrCi8yz/l09wsnxo="); + private static readonly byte[] subKeyBindingKey = Base64.Decode( + "mQGiBDWagYwRBAD7UcH4TAIp7tmUoHBNxVxCVz2ZrNo79M6fV63riOiH2uDxfIpr" + + "IrL0cM4ehEKoqlhngjDhX60eJrOw1nC5BpYZRnDnyDYT4wTWRguxObzGq9pqA1dM" + + "oPTJhkFZVIBgFY99/ULRqaUYIhFGgBtnwS70J8/L/PGVc3DmWRLMkTDjSQCg/5Nh" + + "MCjMK++MdYMcMl/ziaKRT6EEAOtw6PnU9afdohbpx9CK4UvCCEagfbnUtkSCQKSk" + + "6cUp6VsqyzY0pai/BwJ3h4apFMMMpVrtBAtchVgqo4xTr0Sve2j0k+ase6FSImiB" + + "g+AR7hvTUTcBjwtIExBc8TuCTqmn4GG8F7UMdl5Z0AZYj/FfAQYaRVZYP/pRVFNx" + + "Lw65BAC/Fi3qgiGCJFvXnHIckTfcAmZnKSEXWY9NJ4YQb4+/nH7Vsw0wR/ZObUHR" + + "bWgTc9Vw1uZIMe0XVj6Yk1dhGRehUnrm3mE7UJxu7pgkBCbFECFSlSSqP4MEJwZV" + + "09YP/msu50kjoxyoTpt+16uX/8B4at24GF1aTHBxwDLd8X0QWrQsTWVycmlsbCBM" + + "eW5jaCBDTEVBUiBzeXN0ZW0gREggPGNsZWFyQG1sLmNvbT6JAEsEEBECAAsFAjWa" + + "gYwECwMBAgAKCRDyAGjiP47/XanfAKCs6BPURWVQlGh635VgL+pdkUVNUwCdFcNa" + + "1isw+eAcopXPMj6ACOapepu5Ag0ENZqBlBAIAPZCV7cIfwgXcqK61qlC8wXo+VMR" + + "OU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyDvWXpF9Sh01D49Vlf" + + "3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5u/2RXscBqtNbno2g" + + "pXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98iLMcfFstjvbzySPA" + + "Q/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlAGBGNfISnCnLWhsQD" + + "GcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqrol7DVekyCzsAAgIH" + + "/RYtVo+HROZ6jrNjrATEwQm1fUQrk6n5+2dniN881lF0CNkB4NkHw1Xxz4Ejnu/0" + + "iLg8fkOAsmanOsKpOkRtqUnVpsVL5mLJpFEyCY5jbcfj+KY9/25bs0ga7kLHNZia" + + "zbCxJdF+W179z3nudQxRaXG/0XISIH7ziZbSVni69sKc1osk1+OoOMbSuZ86z535" + + "Pln4fXclkFE927HxfbWoO+60hkOLKh7x+8fC82b3x9vCETujEaxrscO2xS7/MYXP" + + "8t1ffriTDmhuIuQS2q4fLgeWdqrODrMhrD8Dq7e558gzp30ZCqpiS7EmKGczL7B8" + + "gXxbBCVSTxYMJheXt2xMXsuJAD8DBRg1moGU8gBo4j+O/10RAgWdAKCPhaFIXuC8" + + "/cdiNMxTDw9ug3De5QCfYXmDzRSFUu/nrCi8yz/l09wsnxo="); // private static readonly byte[] subKeyBindingCheckSum = Base64.Decode("3HU+"); - // - // PGP8 with SHA1 checksum. - // - private static readonly byte[] rewrapKey = Base64.Decode( - "lQOWBEUPOQgBCADdjPTtl8oOwqJFA5WU8p7oDK5KRWfmXeXUZr+ZJipemY5RSvAM" - + "rxqsM47LKYbmXOJznXCQ8+PPa+VxXAsI1CXFHIFqrXSwvB/DUmb4Ec9EuvNd18Zl" - + "hJAybzmV2KMkaUp9oG/DUvxZJqkpUddNfwqZu0KKKZWF5gwW5Oy05VCpaJxQVXFS" - + "whdbRfwEENJiNx4RB3OlWhIjY2p+TgZfgQjiGB9i15R+37sV7TqzBUZF4WWcnIRQ" - + "DnpUfxHgxQ0wO/h/aooyRHSpIx5i4oNpMYq9FNIyakEx/Bomdbs5hW9dFxhrE8Es" - + "UViAYITgTsyROxmgGatGG09dcmVDJVYF4i7JAAYpAAf/VnVyUDs8HrxYTOIt4rYY" - + "jIHToBsV0IiLpA8fEA7k078L1MwSwERVVe6oHVTjeR4A9OxE52Vroh2eOLnF3ftf" - + "6QThVVZr+gr5qeG3yvQ36N7PXNEVOlkyBzGmFQNe4oCA+NR2iqnAIspnekVmwJV6" - + "xVvPCjWw/A7ZArDARpfthspwNcJAp4SWfoa2eKzvUTznTyqFu2PSS5fwQZUgOB0P" - + "Y2FNaKeqV8vEZu4SUWwLOqXBQIZXiaLvdKNgwFvUe3kSHdCNsrVzW7SYxFwaEog2" - + "o6YLKPVPqjlGX1cMOponGp+7n9nDYkQjtEsGSSMQkQRDAcBdSVJmLO07kFOQSOhL" - + "WQQA49BcgTZyhyH6TnDBMBHsGCYj43FnBigypGT9FrQHoWybfX47yZaZFROAaaMa" - + "U6man50YcYZPwzDzXHrK2MoGALY+DzB3mGeXVB45D/KYtlMHPLgntV9T5b14Scbc" - + "w1ES2OUtsSIUs0zelkoXqjLuKnSIYK3mMb67Au7AEp6LXM8EAPj2NypvC86VEnn+" - + "FH0QHvUwBpmDw0EZe25xQs0brvAG00uIbiZnTH66qsIfRhXV/gbKK9J5DTGIqQ15" - + "DuPpz7lcxg/n2+SmjQLNfXCnG8hmtBjhTe+udXAUrmIcfafXyu68SAtebgm1ga56" - + "zUfqsgN3FFuMUffLl3myjyGsg5DnA/oCFWL4WCNClOgL6A5VkNIUait8QtSdCACT" - + "Y7jdSOguSNXfln0QT5lTv+q1AjU7zjRl/LsFNmIJ5g2qdDyK937FOXM44FEEjZty" - + "/4P2dzYpThUI4QUohIj8Qi9f2pZQueC5ztH6rpqANv9geZKcciAeAbZ8Md0K2TEU" - + "RD3Lh+RSBzILtBtUZXN0IEtleSA8dGVzdEBleGFtcGxlLmNvbT6JATYEEwECACAF" - + "AkUPOQgCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRDYpknHeQaskD9NB/9W" - + "EbFuLaqZAl3yjLU5+vb75BdvcfL1lUs44LZVwobNp3/0XbZdY76xVPNZURtU4u3L" - + "sJfGlaF+EqZDE0Mqc+vs5SIb0OnCzNJ00KaUFraUtkByRV32T5ECHK0gMBjCs5RT" - + "I0vVv+Qmzl4+X1Y2bJ2mlpBejHIrOzrBD5NTJimTAzyfnNfipmbqL8p/cxXKKzS+" - + "OM++ZFNACj6lRM1W9GioXnivBRC88gFSQ4/GXc8yjcrMlKA27JxV+SZ9kRWwKH2f" - + "6o6mojUQxnHr+ZFKUpo6ocvTgBDlC57d8IpwJeZ2TvqD6EdA8rZ0YriVjxGMDrX1" - + "8esfw+iLchfEwXtBIRwS"); - - private static readonly char[] rewrapPass = "voltage123".ToCharArray(); - - private static readonly byte[] pubWithX509 = Base64.Decode( - "mQENBERabjABCACtmfyo6Nph9MQjv4nmCWjZrRYnhXbivomAdIwYkLZUj1bjqE+j" - + "uaLzjZV8xSI59odZvrmOiqlzOc4txitQ1OX7nRgbOJ7qku0dvwjtIn46+HQ+cAFn" - + "2mTi81RyXEpO2uiZXfsNTxUtMi+ZuFLufiMc2kdk27GZYWEuasdAPOaPJnA+wW6i" - + "ZHlt0NfXIGNz864gRwhD07fmBIr1dMFfATWxCbgMd/rH7Z/j4rvceHD2n9yrhPze" - + "YN7W4Nuhsr2w/Ft5Cm9xO7vXT/cpto45uxn8f7jERep6bnUwNOhH8G+6xLQgTLD0" - + "qFBGVSIneK3lobs6+xn6VaGN8W0tH3UOaxA1ABEBAAG0D0NOPXFhLWRlZXBzaWdo" - + "dIkFDgQQZAIFAQUCRFpuMAUDCWdU0gMF/3gCGwPELGQBAQQwggTkMIIDzKADAgEC" - + "AhBVUMV/M6rIiE+IzmnPheQWMA0GCSqGSIb3DQEBBQUAMG4xEzARBgoJkiaJk/Is" - + "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt" - + "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo" - + "dDAeFw0wNjA1MDQyMTEyMTZaFw0xMTA1MDQyMTIwMDJaMG4xEzARBgoJkiaJk/Is" - + "ZAEZFgNjb20xEjAQBgoJkiaJk/IsZAEZFgJxYTEVMBMGCgmSJomT8ixkARkWBXRt" - + "czAxMRUwEwYKCZImiZPyLGQBGRYFV2ViZmUxFTATBgNVBAMTDHFhLWRlZXBzaWdo" - + "dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2Z/Kjo2mH0xCO/ieYJ" - + "aNmtFieFduK+iYB0jBiQtlSPVuOoT6O5ovONlXzFIjn2h1m+uY6KqXM5zi3GK1DU" - + "5fudGBs4nuqS7R2/CO0ifjr4dD5wAWfaZOLzVHJcSk7a6Jld+w1PFS0yL5m4Uu5+" - + "IxzaR2TbsZlhYS5qx0A85o8mcD7BbqJkeW3Q19cgY3PzriBHCEPTt+YEivV0wV8B" - + "NbEJuAx3+sftn+Piu9x4cPaf3KuE/N5g3tbg26GyvbD8W3kKb3E7u9dP9ym2jjm7" - + "Gfx/uMRF6npudTA06Efwb7rEtCBMsPSoUEZVIid4reWhuzr7GfpVoY3xbS0fdQ5r" - + "EDUCAwEAAaOCAXwwggF4MAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G" - + "A1UdDgQWBBSmFTRv5y65DHtTYae48zl0ExNWZzCCASUGA1UdHwSCARwwggEYMIIB" - + "FKCCARCgggEMhoHFbGRhcDovLy9DTj1xYS1kZWVwc2lnaHQsQ049cWEtd3VtYW4x" - + "LWRjLENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNl" - + "cyxDTj1Db25maWd1cmF0aW9uLERDPVdlYmZlLERDPXRtczAxLERDPXFhLERDPWNv" - + "bT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JM" - + "RGlzdHJpYnV0aW9uUG9pbnSGQmh0dHA6Ly9xYS13dW1hbjEtZGMud2ViZmUudG1z" - + "MDEucWEuY29tL0NlcnRFbnJvbGwvcWEtZGVlcHNpZ2h0LmNybDAQBgkrBgEEAYI3" - + "FQEEAwIBADANBgkqhkiG9w0BAQUFAAOCAQEAfuZCW3XlB7Eok35zQbvYt9rhAndT" - + "DNw3wPNI4ZzD1nXoYWnwhNNvWRpsOt4ExOSNdaHErfgDXAMyyg66Sro0TkAx8eAj" - + "fPQsyRAh0nm0glzFmJN6TdOZbj7hqGZjc4opQ6nZo8h/ULnaEwMIUW4gcSkZt0ww" - + "CuErl5NUrN3DpkREeCG/fVvQZ8ays3ibQ5ZCZnYBkLYq/i0r3NLW34WfYhjDY48J" - + "oQWtvFSAxvRfz2NGmqnrCHPQZxqlfdta97kDa4VQ0zSeBaC70gZkLmD1GJMxWoXW" - + "6tmEcgPY5SghInUf+L2u52V55MjyAFzVp7kTK2KY+p7qw35vzckrWkwu8AAAAAAA" - + "AQE="); - - private static readonly byte[] secWithPersonalCertificate = Base64.Decode( - "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" - + "cGdwbWltZQULBwgJAgIZAQUbAQAAAAUeAQAAAAIVAgAKCRDlTa3BE84gWVKW" - + "BACcoCFKvph9r9QiHT1Z3N4wZH36Uxqu/059EFALnBkEdVudX/p6S9mynGRk" - + "EfhmWFC1O6dMpnt+ZBEed/4XyFWVSLPwirML+6dxfXogdUsdFF1NCRHc3QGc" - + "txnNUT/zcZ9IRIQjUhp6RkIvJPHcyfTXKSbLviI+PxzHU2Padq8pV7ABZ7kA" - + "jQRIfg8tAQQAutJR/aRnfZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr" - + "5dg50wq3I4HOamRxUwHpdPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO" - + "8LUJ2VTbfPxoLFp539SQ0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0Ft" - + "JycAEQEAAbABj4kEzQQYAQIENwUCSMYtnAUJAeEzgMLFFAAAAAAAFwNleDUw" - + "OWNlcnRpZmljYXRlQHBncC5jb20wggNhMIICyqADAgECAgkA1AoCoRKJCgsw" - + "DQYJKoZIhvcNAQEFBQAwgakxCzAJBgNVBAYTAkNaMRcwFQYDVQQIEw5DemVj" - + "aCBSZXB1YmxpYzESMBAGA1UEChQJQSYmTCBzb2Z0MSAwHgYDVQQLExdJbnRl" - + "cm5hbCBEZXZlbG9wbWVudCBDQTEqMCgGA1UEAxQhQSYmTCBzb2Z0IEludGVy" - + "bmFsIERldmVsb3BtZW50IENBMR8wHQYJKoZIhvcNAQkBFhBrYWRsZWNAYWxz" - + "b2Z0LmN6MB4XDTA4MDcxNjE1MDkzM1oXDTA5MDcxNjE1MDkzM1owaTELMAkG" - + "A1UEBhMCQ1oxFzAVBgNVBAgTDkN6ZWNoIFJlcHVibGljMRIwEAYDVQQKFAlB" - + "JiZMIHNvZnQxFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5IeW5l" - + "ay1JbnRyYW5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAutJR/aRn" - + "fZYwlVv+KlUDYjG8YQUfHpTxpnmVu7W6N0tNg/Xr5dg50wq3I4HOamRxUwHp" - + "dPkXyNF1szpDSRZmlM+VmiIvJDBnyH5YVlxT6+zO8LUJ2VTbfPxoLFp539SQ" - + "0oJOm7IGMAGO7c0n/QV0N3hKUfWgCyJ+sENDa0FtJycCAwEAAaOBzzCBzDAJ" - + "BgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD" - + "ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNaw7A6r10PtYZzAvr9CrSKeRYJgwHwYD" - + "VR0jBBgwFoAUmqSRM8rN3+T1+tkGiqef8S5suYgwGgYDVR0RBBMwEYEPaHlu" - + "ZWtAYWxzb2Z0LmN6MCgGA1UdHwQhMB8wHaAboBmGF2h0dHA6Ly9wZXRyazIv" - + "Y2EvY2EuY3JsMAsGA1UdDwQEAwIF4DANBgkqhkiG9w0BAQUFAAOBgQCUdOWd" - + "7mBLWj1/GSiYgfwgdTrgk/VZOJvMKBiiFyy1iFEzldz6Xx+mAexnFJKfZXZb" - + "EMEGWHfWPmgJzAtuTT0Jz6tUwDmeLH3MP4m8uOZtmyUJ2aq41kciV3rGxF0G" - + "BVlZ/bWTaOzHdm6cjylt6xxLt6MJzpPBA/9ZfybSBh1DaAUbDgAAAJ0gBBkB" - + "AgAGBQJIxi2bAAoJEAdYkEWLb2R2fJED/RK+JErZ98uGo3Z81cHkdP3rk8is" - + "DUL/PR3odBPFH2SIA5wrzklteLK/ZXmBUzcvxqHEgI1F7goXbsBgeTuGgZdx" - + "pINErxkNpcMl9FTldWKGiapKrhkZ+G8knDizF/Y7Lg6uGd2nKVxzutLXdHJZ" - + "pU89Q5nzq6aJFAZo5TBIcchQAAoJEOVNrcETziBZXvQD/1mvFqBfWqwXxoj3" - + "8fHUuFrE2pcp32y3ciO2i+uNVEkNDoaVVNw5eHQaXXWpllI/Pe6LnBl4vkyc" - + "n3pjONa4PKrePkEsCUhRbIySqXIHuNwZumDOlKzZHDpCUw72LaC6S6zwuoEf" - + "ucOcxTeGIUViANWXyTIKkHfo7HfigixJIL8nsAFn"); - - [Test] - public void PerformTest1() - { - PgpPublicKeyRingBundle pubRings = new PgpPublicKeyRingBundle(pub1); - - int count = 0; - - foreach (PgpPublicKeyRing pgpPub1 in pubRings.GetKeyRings()) - { - count++; - - int keyCount = 0; - byte[] bytes = pgpPub1.GetEncoded(); - - PgpPublicKeyRing pgpPub2 = new PgpPublicKeyRing(bytes); - - foreach (PgpPublicKey pubKey in pgpPub2.GetPublicKeys()) - { - keyCount++; - - foreach (PgpSignature sig in pubKey.GetSignatures()) - { - if (sig == null) - Fail("null signature found"); - } - } - - if (keyCount != 2) - { - Fail("wrong number of public keys"); - } - } - - if (count != 1) - { - Fail("wrong number of public keyrings"); - } - - // - // exact match - // - count = 0; - foreach (PgpPublicKeyRing pgpPub3 in pubRings.GetKeyRings("test (Test key)Fp
.
- */
- public class Fp
- {
- internal static readonly BigInteger q = new BigInteger("29");
-
- internal static readonly BigInteger a = new BigInteger("4");
-
- internal static readonly BigInteger b = new BigInteger("20");
-
- internal static readonly FpCurve curve = new FpCurve(q, a, b);
-
- internal static readonly FpPoint infinity = (FpPoint) curve.Infinity;
-
- internal static readonly int[] pointSource = { 5, 22, 16, 27, 13, 6, 14, 6 };
-
- internal static FpPoint[] p = new FpPoint[pointSource.Length / 2];
-
- /**
- * Creates the points on the curve with literature values.
- */
- internal static void createPoints()
- {
- for (int i = 0; i < pointSource.Length / 2; i++)
- {
- FpFieldElement x = new FpFieldElement(q, new BigInteger(
- pointSource[2 * i].ToString()));
- FpFieldElement y = new FpFieldElement(q, new BigInteger(
- pointSource[2 * i + 1].ToString()));
- p[i] = new FpPoint(curve, x, y);
- }
- }
- }
-
- /**
- * Nested class containing sample literature values for F2m
.
- */
- public class F2m
- {
- // Irreducible polynomial for TPB z^4 + z + 1
- internal const int m = 4;
-
- internal const int k1 = 1;
-
- // a = z^3
- internal static readonly F2mFieldElement aTpb = new F2mFieldElement(m, k1,
- new BigInteger("8", 16));
-
- // b = z^3 + 1
- internal static readonly F2mFieldElement bTpb = new F2mFieldElement(m, k1,
- new BigInteger("9", 16));
-
- internal static readonly F2mCurve curve = new F2mCurve(m, k1, aTpb
- .ToBigInteger(), bTpb.ToBigInteger());
-
- internal static readonly F2mPoint infinity = (F2mPoint) curve.Infinity;
-
- internal static readonly string[] pointSource = { "2", "f", "c", "c", "1", "1", "b", "2" };
-
- internal static F2mPoint[] p = new F2mPoint[pointSource.Length / 2];
-
- /**
- * Creates the points on the curve with literature values.
- */
- internal static void createPoints()
- {
- for (int i = 0; i < pointSource.Length / 2; i++)
- {
- F2mFieldElement x = new F2mFieldElement(m, k1,
- new BigInteger(pointSource[2 * i], 16));
- F2mFieldElement y = new F2mFieldElement(m, k1,
- new BigInteger(pointSource[2 * i + 1], 16));
- p[i] = new F2mPoint(curve, x, y);
- }
- }
- }
-
- [SetUp]
- public void setUp()
- {
+ /**
+ * Nested class containing sample literature values for Fp
.
+ */
+ public class Fp
+ {
+ internal static readonly BigInteger q = new BigInteger("29");
+
+ internal static readonly BigInteger a = new BigInteger("4");
+
+ internal static readonly BigInteger b = new BigInteger("20");
+
+ internal static readonly FpCurve curve = new FpCurve(q, a, b);
+
+ internal static readonly FpPoint infinity = (FpPoint) curve.Infinity;
+
+ internal static readonly int[] pointSource = { 5, 22, 16, 27, 13, 6, 14, 6 };
+
+ internal static ECPoint[] p = new ECPoint[pointSource.Length / 2];
+
+ /**
+ * Creates the points on the curve with literature values.
+ */
+ internal static void createPoints()
+ {
+ for (int i = 0; i < pointSource.Length / 2; i++)
+ {
+ p[i] = curve.CreatePoint(
+ new BigInteger(pointSource[2 * i].ToString()),
+ new BigInteger(pointSource[2 * i + 1].ToString()), false);
+ }
+ }
+ }
+
+ /**
+ * Nested class containing sample literature values for F2m
.
+ */
+ public class F2m
+ {
+ // Irreducible polynomial for TPB z^4 + z + 1
+ internal const int m = 4;
+
+ internal const int k1 = 1;
+
+ // a = z^3
+ internal static readonly F2mFieldElement aTpb = new F2mFieldElement(m, k1,
+ new BigInteger("8", 16));
+
+ // b = z^3 + 1
+ internal static readonly F2mFieldElement bTpb = new F2mFieldElement(m, k1,
+ new BigInteger("9", 16));
+
+ internal static readonly F2mCurve curve = new F2mCurve(m, k1, aTpb
+ .ToBigInteger(), bTpb.ToBigInteger());
+
+ internal static readonly F2mPoint infinity = (F2mPoint) curve.Infinity;
+
+ internal static readonly string[] pointSource = { "2", "f", "c", "c", "1", "1", "b", "2" };
+
+ internal static F2mPoint[] p = new F2mPoint[pointSource.Length / 2];
+
+ /**
+ * Creates the points on the curve with literature values.
+ */
+ internal static void createPoints()
+ {
+ for (int i = 0; i < pointSource.Length / 2; i++)
+ {
+ F2mFieldElement x = new F2mFieldElement(m, k1,
+ new BigInteger(pointSource[2 * i], 16));
+ F2mFieldElement y = new F2mFieldElement(m, k1,
+ new BigInteger(pointSource[2 * i + 1], 16));
+ p[i] = new F2mPoint(curve, x, y);
+ }
+ }
+ }
+
+ [SetUp]
+ public void setUp()
+ {
// fp = new ECPointTest.Fp();
- Fp.createPoints();
+ Fp.createPoints();
// f2m = new ECPointTest.F2m();
- F2m.createPoints();
- }
-
- /**
- * Tests, if inconsistent points can be created, i.e. points with exactly
- * one null coordinate (not permitted).
- */
- [Test]
- public void TestPointCreationConsistency()
- {
- try
- {
- FpPoint bad = new FpPoint(Fp.curve, new FpFieldElement(
- Fp.q, new BigInteger("12")), null);
- Assert.Fail();
- }
- catch (ArgumentException)
- {
- // Expected
- }
-
- try
- {
- FpPoint bad = new FpPoint(Fp.curve, null,
- new FpFieldElement(Fp.q, new BigInteger("12")));
- Assert.Fail();
- }
- catch (ArgumentException)
- {
- // Expected
- }
-
- try
- {
- F2mPoint bad = new F2mPoint(F2m.curve, new F2mFieldElement(
- F2m.m, F2m.k1, new BigInteger("1011")), null);
- Assert.Fail();
- }
- catch (ArgumentException)
- {
- // Expected
- }
-
- try
- {
- F2mPoint bad = new F2mPoint(F2m.curve, null,
- new F2mFieldElement(F2m.m, F2m.k1,
- new BigInteger("1011")));
- Assert.Fail();
- }
- catch (ArgumentException)
- {
- // Expected
- }
- }
-
- /**
- * Tests ECPoint.add()
against literature values.
- *
- * @param p
- * The array of literature values.
- * @param infinity
- * The point at infinity on the respective curve.
- */
- private void implTestAdd(ECPoint[] p, ECPoint infinity)
- {
- Assert.AreEqual(p[2], p[0].Add(p[1]), "p0 plus p1 does not equal p2");
- Assert.AreEqual(p[2], p[1].Add(p[0]), "p1 plus p0 does not equal p2");
- for (int i = 0; i < p.Length; i++)
- {
- Assert.AreEqual(p[i], p[i].Add(infinity), "Adding infinity failed");
- Assert.AreEqual(p[i], infinity.Add(p[i]), "Adding to infinity failed");
- }
- }
-
- /**
- * Calls implTestAdd()
for Fp
and
- * F2m
.
- */
- [Test]
- public void TestAdd()
- {
- implTestAdd(Fp.p, Fp.infinity);
- implTestAdd(F2m.p, F2m.infinity);
- }
-
- /**
- * Tests ECPoint.twice()
against literature values.
- *
- * @param p
- * The array of literature values.
- */
- private void implTestTwice(ECPoint[] p)
- {
- Assert.AreEqual(p[3], p[0].Twice(), "Twice incorrect");
- Assert.AreEqual(p[3], p[0].Add(p[0]), "Add same point incorrect");
- }
-
- /**
- * Calls implTestTwice()
for Fp
and
- * F2m
.
- */
- [Test]
- public void TestTwice()
- {
- implTestTwice(Fp.p);
- implTestTwice(F2m.p);
- }
-
- /**
- * Goes through all points on an elliptic curve and checks, if adding a
- * point k
-times is the same as multiplying the point by
- * k
, for all k
. Should be called for points
- * on very small elliptic curves only.
- *
- * @param p
- * The base point on the elliptic curve.
- * @param infinity
- * The point at infinity on the elliptic curve.
- */
- private void implTestAllPoints(ECPoint p, ECPoint infinity)
- {
- ECPoint adder = infinity;
- ECPoint multiplier = infinity;
- int i = 1;
- do
- {
- adder = adder.Add(p);
- multiplier = p.Multiply(new BigInteger(i.ToString()));
- Assert.AreEqual(adder, multiplier,
- "Results of add() and multiply() are inconsistent " + i);
- i++;
- }
- while (!(adder.Equals(infinity)));
- }
-
- /**
- * Calls implTestAllPoints()
for the small literature curves,
- * both for Fp
and F2m
.
- */
- [Test]
- public void TestAllPoints()
- {
- for (int i = 0; i < Fp.p.Length; i++)
- {
- implTestAllPoints(Fp.p[0], Fp.infinity);
- }
-
- for (int i = 0; i < F2m.p.Length; i++)
- {
- implTestAllPoints(F2m.p[0], F2m.infinity);
- }
- }
-
- /**
- * Simple shift-and-add multiplication. Serves as reference implementation
- * to verify (possibly faster) implementations in
- * {@link org.bouncycastle.math.ec.ECPoint ECPoint}.
- *
- * @param p
- * The point to multiply.
- * @param k
- * The multiplier.
- * @return The result of the point multiplication kP
.
- */
- private ECPoint multiply(ECPoint p, BigInteger k)
- {
- ECPoint q = p.Curve.Infinity;
- int t = k.BitLength;
- for (int i = 0; i < t; i++)
- {
- if (k.TestBit(i))
- {
- q = q.Add(p);
- }
- p = p.Twice();
- }
- return q;
- }
-
- /**
- * Checks, if the point multiplication algorithm of the given point yields
- * the same result as point multiplication done by the reference
- * implementation given in multiply()
. This method chooses a
- * random number by which the given point p
is multiplied.
- *
- * @param p
- * The point to be multiplied.
- * @param numBits
- * The bitlength of the random number by which p
- * is multiplied.
- */
- private void implTestMultiply(ECPoint p, int numBits)
- {
- BigInteger k = new BigInteger(numBits, secRand);
- ECPoint reff = multiply(p, k);
- ECPoint q = p.Multiply(k);
- Assert.AreEqual(reff, q, "ECPoint.multiply is incorrect");
- }
-
- /**
- * Checks, if the point multiplication algorithm of the given point yields
- * the same result as point multiplication done by the reference
- * implementation given in multiply()
. This method tests
- * multiplication of p
by every number of bitlength
- * numBits
or less.
- *
- * @param p
- * The point to be multiplied.
- * @param numBits
- * Try every multiplier up to this bitlength
- */
- private void implTestMultiplyAll(ECPoint p, int numBits)
- {
- BigInteger bound = BigInteger.Two.Pow(numBits);
- BigInteger k = BigInteger.Zero;
-
- do
- {
- ECPoint reff = multiply(p, k);
- ECPoint q = p.Multiply(k);
- Assert.AreEqual(reff, q, "ECPoint.multiply is incorrect");
- k = k.Add(BigInteger.One);
- }
- while (k.CompareTo(bound) < 0);
- }
-
- /**
- * Tests ECPoint.add()
and ECPoint.subtract()
- * for the given point and the given point at infinity.
- *
- * @param p
- * The point on which the tests are performed.
- * @param infinity
- * The point at infinity on the same curve as p
.
- */
- private void implTestAddSubtract(ECPoint p, ECPoint infinity)
- {
- Assert.AreEqual(p.Twice(), p.Add(p), "Twice and Add inconsistent");
- Assert.AreEqual(p, p.Twice().Subtract(p), "Twice p - p is not p");
- Assert.AreEqual(infinity, p.Subtract(p), "p - p is not infinity");
- Assert.AreEqual(p, p.Add(infinity), "p plus infinity is not p");
- Assert.AreEqual(p, infinity.Add(p), "infinity plus p is not p");
- Assert.AreEqual(infinity, infinity.Add(infinity), "infinity plus infinity is not infinity ");
- }
-
- /**
- * Calls implTestAddSubtract()
for literature values, both
- * for Fp
and F2m
.
- */
- [Test]
- public void TestAddSubtractMultiplySimple()
- {
- for (int iFp = 0; iFp < Fp.pointSource.Length / 2; iFp++)
- {
- implTestAddSubtract(Fp.p[iFp], Fp.infinity);
-
- // Could be any numBits, 6 is chosen at will
- implTestMultiplyAll(Fp.p[iFp], 6);
- implTestMultiplyAll(Fp.infinity, 6);
- }
-
- for (int iF2m = 0; iF2m < F2m.pointSource.Length / 2; iF2m++)
- {
- implTestAddSubtract(F2m.p[iF2m], F2m.infinity);
-
- // Could be any numBits, 6 is chosen at will
- implTestMultiplyAll(F2m.p[iF2m], 6);
- implTestMultiplyAll(F2m.infinity, 6);
- }
- }
-
- /**
- * Test encoding with and without point compression.
- *
- * @param p
- * The point to be encoded and decoded.
- */
- private void implTestEncoding(ECPoint p)
- {
- // Not Point Compression
- ECPoint unCompP;
-
- // Point compression
- ECPoint compP;
-
- if (p is FpPoint)
- {
- unCompP = new FpPoint(p.Curve, p.X, p.Y, false);
- compP = new FpPoint(p.Curve, p.X, p.Y, true);
- }
- else
- {
- unCompP = new F2mPoint(p.Curve, p.X, p.Y, false);
- compP = new F2mPoint(p.Curve, p.X, p.Y, true);
- }
-
- byte[] unCompBarr = unCompP.GetEncoded();
- ECPoint decUnComp = p.Curve.DecodePoint(unCompBarr);
- Assert.AreEqual(p, decUnComp, "Error decoding uncompressed point");
-
- byte[] compBarr = compP.GetEncoded();
- ECPoint decComp = p.Curve.DecodePoint(compBarr);
- Assert.AreEqual(p, decComp, "Error decoding compressed point");
- }
-
- /**
- * Calls implTestAddSubtract()
,
- * implTestMultiply
and implTestEncoding
for
- * the standard elliptic curves as given in SecNamedCurves
.
- */
- [Test]
- public void TestAddSubtractMultiplyTwiceEncoding()
- {
- foreach (string name in SecNamedCurves.Names)
- {
- X9ECParameters x9ECParameters = SecNamedCurves.GetByName(name);
-
- BigInteger n = x9ECParameters.N;
-
- // The generator is multiplied by random b to get random q
- BigInteger b = new BigInteger(n.BitLength, secRand);
- ECPoint g = x9ECParameters.G;
- ECPoint q = g.Multiply(b);
-
- // Get point at infinity on the curve
- ECPoint infinity = x9ECParameters.Curve.Infinity;
-
- implTestAddSubtract(q, infinity);
- implTestMultiply(q, n.BitLength);
- implTestMultiply(infinity, n.BitLength);
- implTestEncoding(q);
- }
- }
- }
+ F2m.createPoints();
+ }
+
+ /**
+ * Tests, if inconsistent points can be created, i.e. points with exactly
+ * one null coordinate (not permitted).
+ */
+ [Test]
+ public void TestPointCreationConsistency()
+ {
+ try
+ {
+ FpPoint bad = new FpPoint(Fp.curve, new FpFieldElement(
+ Fp.q, new BigInteger("12")), null);
+ Assert.Fail();
+ }
+ catch (ArgumentException)
+ {
+ // Expected
+ }
+
+ try
+ {
+ FpPoint bad = new FpPoint(Fp.curve, null,
+ new FpFieldElement(Fp.q, new BigInteger("12")));
+ Assert.Fail();
+ }
+ catch (ArgumentException)
+ {
+ // Expected
+ }
+
+ try
+ {
+ F2mPoint bad = new F2mPoint(F2m.curve, new F2mFieldElement(
+ F2m.m, F2m.k1, new BigInteger("1011")), null);
+ Assert.Fail();
+ }
+ catch (ArgumentException)
+ {
+ // Expected
+ }
+
+ try
+ {
+ F2mPoint bad = new F2mPoint(F2m.curve, null,
+ new F2mFieldElement(F2m.m, F2m.k1,
+ new BigInteger("1011")));
+ Assert.Fail();
+ }
+ catch (ArgumentException)
+ {
+ // Expected
+ }
+ }
+
+ /**
+ * Tests ECPoint.add()
against literature values.
+ *
+ * @param p
+ * The array of literature values.
+ * @param infinity
+ * The point at infinity on the respective curve.
+ */
+ private void implTestAdd(ECPoint[] p, ECPoint infinity)
+ {
+ Assert.AreEqual(p[2], p[0].Add(p[1]), "p0 plus p1 does not equal p2");
+ Assert.AreEqual(p[2], p[1].Add(p[0]), "p1 plus p0 does not equal p2");
+ for (int i = 0; i < p.Length; i++)
+ {
+ Assert.AreEqual(p[i], p[i].Add(infinity), "Adding infinity failed");
+ Assert.AreEqual(p[i], infinity.Add(p[i]), "Adding to infinity failed");
+ }
+ }
+
+ /**
+ * Calls implTestAdd()
for Fp
and
+ * F2m
.
+ */
+ [Test]
+ public void TestAdd()
+ {
+ implTestAdd(Fp.p, Fp.infinity);
+ implTestAdd(F2m.p, F2m.infinity);
+ }
+
+ /**
+ * Tests ECPoint.twice()
against literature values.
+ *
+ * @param p
+ * The array of literature values.
+ */
+ private void implTestTwice(ECPoint[] p)
+ {
+ Assert.AreEqual(p[3], p[0].Twice(), "Twice incorrect");
+ Assert.AreEqual(p[3], p[0].Add(p[0]), "Add same point incorrect");
+ }
+
+ /**
+ * Calls implTestTwice()
for Fp
and
+ * F2m
.
+ */
+ [Test]
+ public void TestTwice()
+ {
+ implTestTwice(Fp.p);
+ implTestTwice(F2m.p);
+ }
+
+ /**
+ * Goes through all points on an elliptic curve and checks, if adding a
+ * point k
-times is the same as multiplying the point by
+ * k
, for all k
. Should be called for points
+ * on very small elliptic curves only.
+ *
+ * @param p
+ * The base point on the elliptic curve.
+ * @param infinity
+ * The point at infinity on the elliptic curve.
+ */
+ private void implTestAllPoints(ECPoint p, ECPoint infinity)
+ {
+ ECPoint adder = infinity;
+ ECPoint multiplier = infinity;
+ int i = 1;
+ do
+ {
+ adder = adder.Add(p);
+ multiplier = p.Multiply(new BigInteger(i.ToString()));
+ Assert.AreEqual(adder, multiplier,
+ "Results of add() and multiply() are inconsistent " + i);
+ i++;
+ }
+ while (!(adder.Equals(infinity)));
+ }
+
+ /**
+ * Calls implTestAllPoints()
for the small literature curves,
+ * both for Fp
and F2m
.
+ */
+ [Test]
+ public void TestAllPoints()
+ {
+ for (int i = 0; i < Fp.p.Length; i++)
+ {
+ implTestAllPoints(Fp.p[0], Fp.infinity);
+ }
+
+ for (int i = 0; i < F2m.p.Length; i++)
+ {
+ implTestAllPoints(F2m.p[0], F2m.infinity);
+ }
+ }
+
+ /**
+ * Simple shift-and-add multiplication. Serves as reference implementation
+ * to verify (possibly faster) implementations in
+ * {@link org.bouncycastle.math.ec.ECPoint ECPoint}.
+ *
+ * @param p
+ * The point to multiply.
+ * @param k
+ * The multiplier.
+ * @return The result of the point multiplication kP
.
+ */
+ private ECPoint multiply(ECPoint p, BigInteger k)
+ {
+ ECPoint q = p.Curve.Infinity;
+ int t = k.BitLength;
+ for (int i = 0; i < t; i++)
+ {
+ if (k.TestBit(i))
+ {
+ q = q.Add(p);
+ }
+ p = p.Twice();
+ }
+ return q;
+ }
+
+ /**
+ * Checks, if the point multiplication algorithm of the given point yields
+ * the same result as point multiplication done by the reference
+ * implementation given in multiply()
. This method chooses a
+ * random number by which the given point p
is multiplied.
+ *
+ * @param p
+ * The point to be multiplied.
+ * @param numBits
+ * The bitlength of the random number by which p
+ * is multiplied.
+ */
+ private void implTestMultiply(ECPoint p, int numBits)
+ {
+ BigInteger k = new BigInteger(numBits, secRand);
+ ECPoint reff = multiply(p, k);
+ ECPoint q = p.Multiply(k);
+ Assert.AreEqual(reff, q, "ECPoint.multiply is incorrect");
+ }
+
+ /**
+ * Checks, if the point multiplication algorithm of the given point yields
+ * the same result as point multiplication done by the reference
+ * implementation given in multiply()
. This method tests
+ * multiplication of p
by every number of bitlength
+ * numBits
or less.
+ *
+ * @param p
+ * The point to be multiplied.
+ * @param numBits
+ * Try every multiplier up to this bitlength
+ */
+ private void implTestMultiplyAll(ECPoint p, int numBits)
+ {
+ BigInteger bound = BigInteger.Two.Pow(numBits);
+ BigInteger k = BigInteger.Zero;
+
+ do
+ {
+ ECPoint reff = multiply(p, k);
+ ECPoint q = p.Multiply(k);
+ Assert.AreEqual(reff, q, "ECPoint.multiply is incorrect");
+ k = k.Add(BigInteger.One);
+ }
+ while (k.CompareTo(bound) < 0);
+ }
+
+ /**
+ * Tests ECPoint.add()
and ECPoint.subtract()
+ * for the given point and the given point at infinity.
+ *
+ * @param p
+ * The point on which the tests are performed.
+ * @param infinity
+ * The point at infinity on the same curve as p
.
+ */
+ private void implTestAddSubtract(ECPoint p, ECPoint infinity)
+ {
+ Assert.AreEqual(p.Twice(), p.Add(p), "Twice and Add inconsistent");
+ Assert.AreEqual(p, p.Twice().Subtract(p), "Twice p - p is not p");
+ Assert.AreEqual(infinity, p.Subtract(p), "p - p is not infinity");
+ Assert.AreEqual(p, p.Add(infinity), "p plus infinity is not p");
+ Assert.AreEqual(p, infinity.Add(p), "infinity plus p is not p");
+ Assert.AreEqual(infinity, infinity.Add(infinity), "infinity plus infinity is not infinity ");
+ }
+
+ /**
+ * Calls implTestAddSubtract()
for literature values, both
+ * for Fp
and F2m
.
+ */
+ [Test]
+ public void TestAddSubtractMultiplySimple()
+ {
+ for (int iFp = 0; iFp < Fp.pointSource.Length / 2; iFp++)
+ {
+ implTestAddSubtract(Fp.p[iFp], Fp.infinity);
+
+ // Could be any numBits, 6 is chosen at will
+ implTestMultiplyAll(Fp.p[iFp], 6);
+ implTestMultiplyAll(Fp.infinity, 6);
+ }
+
+ for (int iF2m = 0; iF2m < F2m.pointSource.Length / 2; iF2m++)
+ {
+ implTestAddSubtract(F2m.p[iF2m], F2m.infinity);
+
+ // Could be any numBits, 6 is chosen at will
+ implTestMultiplyAll(F2m.p[iF2m], 6);
+ implTestMultiplyAll(F2m.infinity, 6);
+ }
+ }
+
+ /**
+ * Test encoding with and without point compression.
+ *
+ * @param p
+ * The point to be encoded and decoded.
+ */
+ private void implTestEncoding(ECPoint p)
+ {
+ // Not Point Compression
+ ECPoint unCompP;
+
+ // Point compression
+ ECPoint compP;
+
+ if (p is FpPoint)
+ {
+ unCompP = new FpPoint(p.Curve, p.X, p.Y, false);
+ compP = new FpPoint(p.Curve, p.X, p.Y, true);
+ }
+ else
+ {
+ unCompP = new F2mPoint(p.Curve, p.X, p.Y, false);
+ compP = new F2mPoint(p.Curve, p.X, p.Y, true);
+ }
+
+ byte[] unCompBarr = unCompP.GetEncoded();
+ ECPoint decUnComp = p.Curve.DecodePoint(unCompBarr);
+ Assert.AreEqual(p, decUnComp, "Error decoding uncompressed point");
+
+ byte[] compBarr = compP.GetEncoded();
+ ECPoint decComp = p.Curve.DecodePoint(compBarr);
+ Assert.AreEqual(p, decComp, "Error decoding compressed point");
+ }
+
+ /**
+ * Calls implTestAddSubtract()
,
+ * implTestMultiply
and implTestEncoding
for
+ * the standard elliptic curves as given in SecNamedCurves
.
+ */
+ [Test]
+ public void TestAddSubtractMultiplyTwiceEncoding()
+ {
+ foreach (string name in SecNamedCurves.Names)
+ {
+ X9ECParameters x9ECParameters = SecNamedCurves.GetByName(name);
+
+ BigInteger n = x9ECParameters.N;
+
+ // The generator is multiplied by random b to get random q
+ BigInteger b = new BigInteger(n.BitLength, secRand);
+ ECPoint g = x9ECParameters.G;
+ ECPoint q = g.Multiply(b);
+
+ // Get point at infinity on the curve
+ ECPoint infinity = x9ECParameters.Curve.Infinity;
+
+ implTestAddSubtract(q, infinity);
+ implTestMultiply(q, n.BitLength);
+ implTestMultiply(infinity, n.BitLength);
+ implTestEncoding(q);
+ }
+ }
+ }
}
\ No newline at end of file
--
cgit 1.5.1
From 7076b2f6992ac53997cfd73ca73ee825dc2b967c Mon Sep 17 00:00:00 2001
From: Peter Dettman - * In the case of PKCS7 objects the reader will return a CMS ContentInfo object. Keys and - * Certificates will be returned using the appropriate java.security type.
- */ - public class PemReader - : Org.BouncyCastle.Utilities.IO.Pem.PemReader - { + /** + * Class for reading OpenSSL PEM encoded streams containing + * X509 certificates, PKCS8 encoded keys and PKCS7 objects. + *+ * In the case of PKCS7 objects the reader will return a CMS ContentInfo object. Keys and + * Certificates will be returned using the appropriate java.security type.
+ */ + public class PemReader + : Org.BouncyCastle.Utilities.IO.Pem.PemReader + { // private static readonly IDictionary parsers = new Hashtable(); - static PemReader() - { + static PemReader() + { // parsers.Add("CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); // parsers.Add("NEW CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); // parsers.Add("CERTIFICATE", new X509CertificateParser(provider)); @@ -52,323 +52,323 @@ namespace Org.BouncyCastle.OpenSsl // parsers.Add("EC PRIVATE KEY", new ECDSAKeyPairParser(provider)); // parsers.Add("ENCRYPTED PRIVATE KEY", new EncryptedPrivateKeyParser(provider)); // parsers.Add("PRIVATE KEY", new PrivateKeyParser(provider)); - } - - private readonly IPasswordFinder pFinder; - - /** - * Create a new PemReader - * - * @param reader the Reader - */ - public PemReader( - TextReader reader) - : this(reader, null) - { - } - - /** - * Create a new PemReader with a password finder - * - * @param reader the Reader - * @param pFinder the password finder - */ - public PemReader( - TextReader reader, - IPasswordFinder pFinder) - : base(reader) - { - this.pFinder = pFinder; - } - - public object ReadObject() - { - PemObject obj = ReadPemObject(); - - if (obj == null) - return null; - - // TODO Follow Java build and map to parser objects? + } + + private readonly IPasswordFinder pFinder; + + /** + * Create a new PemReader + * + * @param reader the Reader + */ + public PemReader( + TextReader reader) + : this(reader, null) + { + } + + /** + * Create a new PemReader with a password finder + * + * @param reader the Reader + * @param pFinder the password finder + */ + public PemReader( + TextReader reader, + IPasswordFinder pFinder) + : base(reader) + { + this.pFinder = pFinder; + } + + public object ReadObject() + { + PemObject obj = ReadPemObject(); + + if (obj == null) + return null; + + // TODO Follow Java build and map to parser objects? // if (parsers.Contains(obj.Type)) // return ((PemObjectParser)parsers[obj.Type]).ParseObject(obj); - if (obj.Type.EndsWith("PRIVATE KEY")) - return ReadPrivateKey(obj); - - switch (obj.Type) - { - case "PUBLIC KEY": - return ReadPublicKey(obj); - case "RSA PUBLIC KEY": - return ReadRsaPublicKey(obj); - case "CERTIFICATE REQUEST": - case "NEW CERTIFICATE REQUEST": - return ReadCertificateRequest(obj); - case "CERTIFICATE": - case "X509 CERTIFICATE": - return ReadCertificate(obj); - case "PKCS7": - return ReadPkcs7(obj); - case "X509 CRL": - return ReadCrl(obj); - case "ATTRIBUTE CERTIFICATE": - return ReadAttributeCertificate(obj); - // TODO Add back in when tests done, and return type issue resolved - //case "EC PARAMETERS": - // return ReadECParameters(obj); - default: - throw new IOException("unrecognised object: " + obj.Type); - } - } - - private AsymmetricKeyParameter ReadRsaPublicKey(PemObject pemObject) - { - RsaPublicKeyStructure rsaPubStructure = RsaPublicKeyStructure.GetInstance( - Asn1Object.FromByteArray(pemObject.Content)); - - return new RsaKeyParameters( - false, // not private - rsaPubStructure.Modulus, - rsaPubStructure.PublicExponent); - } - - private AsymmetricKeyParameter ReadPublicKey(PemObject pemObject) - { - return PublicKeyFactory.CreateKey(pemObject.Content); - } - - /** - * Reads in a X509Certificate. - * - * @return the X509Certificate - * @throws IOException if an I/O error occured - */ - private X509Certificate ReadCertificate(PemObject pemObject) - { - try - { - return new X509CertificateParser().ReadCertificate(pemObject.Content); - } - catch (Exception e) - { - throw new PemException("problem parsing cert: " + e.ToString()); - } - } - - /** - * Reads in a X509CRL. - * - * @return the X509Certificate - * @throws IOException if an I/O error occured - */ - private X509Crl ReadCrl(PemObject pemObject) - { - try - { - return new X509CrlParser().ReadCrl(pemObject.Content); - } - catch (Exception e) - { - throw new PemException("problem parsing cert: " + e.ToString()); - } - } - - /** - * Reads in a PKCS10 certification request. - * - * @return the certificate request. - * @throws IOException if an I/O error occured - */ - private Pkcs10CertificationRequest ReadCertificateRequest(PemObject pemObject) - { - try - { - return new Pkcs10CertificationRequest(pemObject.Content); - } - catch (Exception e) - { - throw new PemException("problem parsing cert: " + e.ToString()); - } - } - - /** - * Reads in a X509 Attribute Certificate. - * - * @return the X509 Attribute Certificate - * @throws IOException if an I/O error occured - */ - private IX509AttributeCertificate ReadAttributeCertificate(PemObject pemObject) - { - return new X509V2AttributeCertificate(pemObject.Content); - } - - /** - * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS - * API. - * - * @return the X509Certificate - * @throws IOException if an I/O error occured - */ - // TODO Consider returning Asn1.Pkcs.ContentInfo - private Asn1.Cms.ContentInfo ReadPkcs7(PemObject pemObject) - { - try - { - return Asn1.Cms.ContentInfo.GetInstance( - Asn1Object.FromByteArray(pemObject.Content)); - } - catch (Exception e) - { - throw new PemException("problem parsing PKCS7 object: " + e.ToString()); - } - } - - /** - * Read a Key Pair - */ - private object ReadPrivateKey(PemObject pemObject) - { - // - // extract the key - // - Debug.Assert(pemObject.Type.EndsWith("PRIVATE KEY")); - - string type = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim(); - byte[] keyBytes = pemObject.Content; - - IDictionary fields = Platform.CreateHashtable(); - foreach (PemHeader header in pemObject.Headers) - { - fields[header.Name] = header.Value; - } - - string procType = (string) fields["Proc-Type"]; - - if (procType == "4,ENCRYPTED") - { - if (pFinder == null) - throw new PasswordException("No password finder specified, but a password is required"); - - char[] password = pFinder.GetPassword(); - - if (password == null) - throw new PasswordException("Password is null, but a password is required"); - - string dekInfo = (string) fields["DEK-Info"]; - string[] tknz = dekInfo.Split(','); - - string dekAlgName = tknz[0].Trim(); - byte[] iv = Hex.Decode(tknz[1].Trim()); - - keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv); - } - - try - { - AsymmetricKeyParameter pubSpec, privSpec; - Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(keyBytes); - - switch (type) - { - case "RSA": - { - if (seq.Count != 9) - throw new PemException("malformed sequence in RSA private key"); - - RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq); - - pubSpec = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent); - privSpec = new RsaPrivateCrtKeyParameters( - rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, - rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, - rsa.Coefficient); - - break; - } - - case "DSA": - { - if (seq.Count != 6) - throw new PemException("malformed sequence in DSA private key"); - - // TODO Create an ASN1 object somewhere for this? - //DerInteger v = (DerInteger)seq[0]; - DerInteger p = (DerInteger)seq[1]; - DerInteger q = (DerInteger)seq[2]; - DerInteger g = (DerInteger)seq[3]; - DerInteger y = (DerInteger)seq[4]; - DerInteger x = (DerInteger)seq[5]; - - DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value); - - privSpec = new DsaPrivateKeyParameters(x.Value, parameters); - pubSpec = new DsaPublicKeyParameters(y.Value, parameters); - - break; - } - - case "EC": - { - ECPrivateKeyStructure pKey = new ECPrivateKeyStructure(seq); - AlgorithmIdentifier algId = new AlgorithmIdentifier( - X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters()); - - PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object()); - - // TODO Are the keys returned here ECDSA, as Java version forces? - privSpec = PrivateKeyFactory.CreateKey(privInfo); - - DerBitString pubKey = pKey.GetPublicKey(); - if (pubKey != null) - { - SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pubKey.GetBytes()); - - // TODO Are the keys returned here ECDSA, as Java version forces? - pubSpec = PublicKeyFactory.CreateKey(pubInfo); - } - else - { - pubSpec = ECKeyPairGenerator.GetCorrespondingPublicKey( - (ECPrivateKeyParameters)privSpec); - } - - break; - } - - case "ENCRYPTED": - { - char[] password = pFinder.GetPassword(); - - if (password == null) - throw new PasswordException("Password is null, but a password is required"); - - return PrivateKeyFactory.DecryptKey(password, EncryptedPrivateKeyInfo.GetInstance(seq)); - } - - case "": - { - return PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq)); - } - - default: - throw new ArgumentException("Unknown key type: " + type, "type"); - } - - return new AsymmetricCipherKeyPair(pubSpec, privSpec); - } - catch (IOException e) - { - throw e; - } - catch (Exception e) - { - throw new PemException( - "problem creating " + type + " private key: " + e.ToString()); - } - } - - // TODO Add an equivalent class for ECNamedCurveParameterSpec? - //private ECNamedCurveParameterSpec ReadECParameters( + if (obj.Type.EndsWith("PRIVATE KEY")) + return ReadPrivateKey(obj); + + switch (obj.Type) + { + case "PUBLIC KEY": + return ReadPublicKey(obj); + case "RSA PUBLIC KEY": + return ReadRsaPublicKey(obj); + case "CERTIFICATE REQUEST": + case "NEW CERTIFICATE REQUEST": + return ReadCertificateRequest(obj); + case "CERTIFICATE": + case "X509 CERTIFICATE": + return ReadCertificate(obj); + case "PKCS7": + return ReadPkcs7(obj); + case "X509 CRL": + return ReadCrl(obj); + case "ATTRIBUTE CERTIFICATE": + return ReadAttributeCertificate(obj); + // TODO Add back in when tests done, and return type issue resolved + //case "EC PARAMETERS": + // return ReadECParameters(obj); + default: + throw new IOException("unrecognised object: " + obj.Type); + } + } + + private AsymmetricKeyParameter ReadRsaPublicKey(PemObject pemObject) + { + RsaPublicKeyStructure rsaPubStructure = RsaPublicKeyStructure.GetInstance( + Asn1Object.FromByteArray(pemObject.Content)); + + return new RsaKeyParameters( + false, // not private + rsaPubStructure.Modulus, + rsaPubStructure.PublicExponent); + } + + private AsymmetricKeyParameter ReadPublicKey(PemObject pemObject) + { + return PublicKeyFactory.CreateKey(pemObject.Content); + } + + /** + * Reads in a X509Certificate. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + private X509Certificate ReadCertificate(PemObject pemObject) + { + try + { + return new X509CertificateParser().ReadCertificate(pemObject.Content); + } + catch (Exception e) + { + throw new PemException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a X509CRL. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + private X509Crl ReadCrl(PemObject pemObject) + { + try + { + return new X509CrlParser().ReadCrl(pemObject.Content); + } + catch (Exception e) + { + throw new PemException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a PKCS10 certification request. + * + * @return the certificate request. + * @throws IOException if an I/O error occured + */ + private Pkcs10CertificationRequest ReadCertificateRequest(PemObject pemObject) + { + try + { + return new Pkcs10CertificationRequest(pemObject.Content); + } + catch (Exception e) + { + throw new PemException("problem parsing cert: " + e.ToString()); + } + } + + /** + * Reads in a X509 Attribute Certificate. + * + * @return the X509 Attribute Certificate + * @throws IOException if an I/O error occured + */ + private IX509AttributeCertificate ReadAttributeCertificate(PemObject pemObject) + { + return new X509V2AttributeCertificate(pemObject.Content); + } + + /** + * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS + * API. + * + * @return the X509Certificate + * @throws IOException if an I/O error occured + */ + // TODO Consider returning Asn1.Pkcs.ContentInfo + private Asn1.Cms.ContentInfo ReadPkcs7(PemObject pemObject) + { + try + { + return Asn1.Cms.ContentInfo.GetInstance( + Asn1Object.FromByteArray(pemObject.Content)); + } + catch (Exception e) + { + throw new PemException("problem parsing PKCS7 object: " + e.ToString()); + } + } + + /** + * Read a Key Pair + */ + private object ReadPrivateKey(PemObject pemObject) + { + // + // extract the key + // + Debug.Assert(pemObject.Type.EndsWith("PRIVATE KEY")); + + string type = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim(); + byte[] keyBytes = pemObject.Content; + + IDictionary fields = Platform.CreateHashtable(); + foreach (PemHeader header in pemObject.Headers) + { + fields[header.Name] = header.Value; + } + + string procType = (string) fields["Proc-Type"]; + + if (procType == "4,ENCRYPTED") + { + if (pFinder == null) + throw new PasswordException("No password finder specified, but a password is required"); + + char[] password = pFinder.GetPassword(); + + if (password == null) + throw new PasswordException("Password is null, but a password is required"); + + string dekInfo = (string) fields["DEK-Info"]; + string[] tknz = dekInfo.Split(','); + + string dekAlgName = tknz[0].Trim(); + byte[] iv = Hex.Decode(tknz[1].Trim()); + + keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv); + } + + try + { + AsymmetricKeyParameter pubSpec, privSpec; + Asn1Sequence seq = Asn1Sequence.GetInstance(keyBytes); + + switch (type) + { + case "RSA": + { + if (seq.Count != 9) + throw new PemException("malformed sequence in RSA private key"); + + RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq); + + pubSpec = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent); + privSpec = new RsaPrivateCrtKeyParameters( + rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, + rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, + rsa.Coefficient); + + break; + } + + case "DSA": + { + if (seq.Count != 6) + throw new PemException("malformed sequence in DSA private key"); + + // TODO Create an ASN1 object somewhere for this? + //DerInteger v = (DerInteger)seq[0]; + DerInteger p = (DerInteger)seq[1]; + DerInteger q = (DerInteger)seq[2]; + DerInteger g = (DerInteger)seq[3]; + DerInteger y = (DerInteger)seq[4]; + DerInteger x = (DerInteger)seq[5]; + + DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value); + + privSpec = new DsaPrivateKeyParameters(x.Value, parameters); + pubSpec = new DsaPublicKeyParameters(y.Value, parameters); + + break; + } + + case "EC": + { + ECPrivateKeyStructure pKey = new ECPrivateKeyStructure(seq); + AlgorithmIdentifier algId = new AlgorithmIdentifier( + X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters()); + + PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object()); + + // TODO Are the keys returned here ECDSA, as Java version forces? + privSpec = PrivateKeyFactory.CreateKey(privInfo); + + DerBitString pubKey = pKey.GetPublicKey(); + if (pubKey != null) + { + SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pubKey.GetBytes()); + + // TODO Are the keys returned here ECDSA, as Java version forces? + pubSpec = PublicKeyFactory.CreateKey(pubInfo); + } + else + { + pubSpec = ECKeyPairGenerator.GetCorrespondingPublicKey( + (ECPrivateKeyParameters)privSpec); + } + + break; + } + + case "ENCRYPTED": + { + char[] password = pFinder.GetPassword(); + + if (password == null) + throw new PasswordException("Password is null, but a password is required"); + + return PrivateKeyFactory.DecryptKey(password, EncryptedPrivateKeyInfo.GetInstance(seq)); + } + + case "": + { + return PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq)); + } + + default: + throw new ArgumentException("Unknown key type: " + type, "type"); + } + + return new AsymmetricCipherKeyPair(pubSpec, privSpec); + } + catch (IOException e) + { + throw e; + } + catch (Exception e) + { + throw new PemException( + "problem creating " + type + " private key: " + e.ToString()); + } + } + + // TODO Add an equivalent class for ECNamedCurveParameterSpec? + //private ECNamedCurveParameterSpec ReadECParameters( // private X9ECParameters ReadECParameters(PemObject pemObject) // { // DerObjectIdentifier oid = (DerObjectIdentifier)Asn1Object.FromByteArray(pemObject.Content); @@ -377,31 +377,31 @@ namespace Org.BouncyCastle.OpenSsl // return GetCurveParameters(oid.Id); // } - //private static ECDomainParameters GetCurveParameters( - private static X9ECParameters GetCurveParameters( - string name) - { - // TODO ECGost3410NamedCurves support (returns ECDomainParameters though) - X9ECParameters ecP = X962NamedCurves.GetByName(name); - - if (ecP == null) - { - ecP = SecNamedCurves.GetByName(name); - if (ecP == null) - { - ecP = NistNamedCurves.GetByName(name); - if (ecP == null) - { - ecP = TeleTrusTNamedCurves.GetByName(name); - - if (ecP == null) - throw new Exception("unknown curve name: " + name); - } - } - } - - //return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); - return ecP; - } - } + //private static ECDomainParameters GetCurveParameters( + private static X9ECParameters GetCurveParameters( + string name) + { + // TODO ECGost3410NamedCurves support (returns ECDomainParameters though) + X9ECParameters ecP = X962NamedCurves.GetByName(name); + + if (ecP == null) + { + ecP = SecNamedCurves.GetByName(name); + if (ecP == null) + { + ecP = NistNamedCurves.GetByName(name); + if (ecP == null) + { + ecP = TeleTrusTNamedCurves.GetByName(name); + + if (ecP == null) + throw new Exception("unknown curve name: " + name); + } + } + } + + //return new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed()); + return ecP; + } + } } diff --git a/crypto/test/src/openssl/test/ReaderTest.cs b/crypto/test/src/openssl/test/ReaderTest.cs index d27ed742f..e3990b562 100644 --- a/crypto/test/src/openssl/test/ReaderTest.cs +++ b/crypto/test/src/openssl/test/ReaderTest.cs @@ -13,44 +13,44 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.OpenSsl.Tests { - /** - * basic class for reading test.pem - the password is "secret" - */ - [TestFixture] - public class ReaderTest - : SimpleTest - { - private class Password - : IPasswordFinder - { - private readonly char[] password; - - public Password( - char[] word) - { - this.password = (char[]) word.Clone(); - } - - public char[] GetPassword() - { - return (char[]) password.Clone(); - } - } - - public override string Name - { - get { return "PEMReaderTest"; } - } - - public override void PerformTest() - { - IPasswordFinder pGet = new Password("secret".ToCharArray()); - PemReader pemRd = OpenPemResource("test.pem", pGet); - AsymmetricCipherKeyPair pair; - - object o; - while ((o = pemRd.ReadObject()) != null) - { + /** + * basic class for reading test.pem - the password is "secret" + */ + [TestFixture] + public class ReaderTest + : SimpleTest + { + private class Password + : IPasswordFinder + { + private readonly char[] password; + + public Password( + char[] word) + { + this.password = (char[]) word.Clone(); + } + + public char[] GetPassword() + { + return (char[]) password.Clone(); + } + } + + public override string Name + { + get { return "PEMReaderTest"; } + } + + public override void PerformTest() + { + IPasswordFinder pGet = new Password("secret".ToCharArray()); + PemReader pemRd = OpenPemResource("test.pem", pGet); + AsymmetricCipherKeyPair pair; + + object o; + while ((o = pemRd.ReadObject()) != null) + { // if (o is AsymmetricCipherKeyPair) // { // ackp = (AsymmetricCipherKeyPair)o; @@ -62,51 +62,51 @@ namespace Org.BouncyCastle.OpenSsl.Tests // { // Console.WriteLine(o.ToString()); // } - } - - // - // pkcs 7 data - // - pemRd = OpenPemResource("pkcs7.pem", null); - - ContentInfo d = (ContentInfo)pemRd.ReadObject(); - - if (!d.ContentType.Equals(CmsObjectIdentifiers.EnvelopedData)) - { - Fail("failed envelopedData check"); - } - - /* - { - // - // ECKey - // - pemRd = OpenPemResource("eckey.pem", null); - - // TODO Resolve return type issue with EC keys and fix PemReader to return parameters + } + + // + // pkcs 7 data + // + pemRd = OpenPemResource("pkcs7.pem", null); + + ContentInfo d = (ContentInfo)pemRd.ReadObject(); + + if (!d.ContentType.Equals(CmsObjectIdentifiers.EnvelopedData)) + { + Fail("failed envelopedData check"); + } + + /* + { + // + // ECKey + // + pemRd = OpenPemResource("eckey.pem", null); + + // TODO Resolve return type issue with EC keys and fix PemReader to return parameters // ECNamedCurveParameterSpec spec = (ECNamedCurveParameterSpec)pemRd.ReadObject(); - - pair = (AsymmetricCipherKeyPair)pemRd.ReadObject(); - ISigner sgr = SignerUtilities.GetSigner("ECDSA"); - - sgr.Init(true, pair.Private); - - byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; - - sgr.BlockUpdate(message, 0, message.Length); - - byte[] sigBytes = sgr.GenerateSignature(); - - sgr.Init(false, pair.Public); - - sgr.BlockUpdate(message, 0, message.Length); - - if (!sgr.VerifySignature(sigBytes)) - { - Fail("EC verification failed"); - } - - // TODO Resolve this issue with the algorithm name, study Java version + + pair = (AsymmetricCipherKeyPair)pemRd.ReadObject(); + ISigner sgr = SignerUtilities.GetSigner("ECDSA"); + + sgr.Init(true, pair.Private); + + byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; + + sgr.BlockUpdate(message, 0, message.Length); + + byte[] sigBytes = sgr.GenerateSignature(); + + sgr.Init(false, pair.Public); + + sgr.BlockUpdate(message, 0, message.Length); + + if (!sgr.VerifySignature(sigBytes)) + { + Fail("EC verification failed"); + } + + // TODO Resolve this issue with the algorithm name, study Java version // if (!((ECPublicKeyParameters) pair.Public).AlgorithmName.Equals("ECDSA")) // { // Fail("wrong algorithm name on public got: " + ((ECPublicKeyParameters) pair.Public).AlgorithmName); @@ -116,265 +116,264 @@ namespace Org.BouncyCastle.OpenSsl.Tests // { // Fail("wrong algorithm name on private got: " + ((ECPrivateKeyParameters) pair.Private).AlgorithmName); // } - } - */ + } + */ - // - // writer/parser test - // - IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); - kpGen.Init( - new RsaKeyGenerationParameters( - BigInteger.ValueOf(0x10001), - new SecureRandom(), - 768, - 25)); + // + // writer/parser test + // + IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA"); + kpGen.Init( + new RsaKeyGenerationParameters( + BigInteger.ValueOf(0x10001), + new SecureRandom(), + 768, + 25)); - pair = kpGen.GenerateKeyPair(); + pair = kpGen.GenerateKeyPair(); - keyPairTest("RSA", pair); + keyPairTest("RSA", pair); // kpGen = KeyPairGenerator.getInstance("DSA"); // kpGen.initialize(512, new SecureRandom()); - DsaParametersGenerator pGen = new DsaParametersGenerator(); - pGen.Init(512, 80, new SecureRandom()); - - kpGen = GeneratorUtilities.GetKeyPairGenerator("DSA"); - kpGen.Init( - new DsaKeyGenerationParameters( - new SecureRandom(), - pGen.GenerateParameters())); - - pair = kpGen.GenerateKeyPair(); - - keyPairTest("DSA", pair); - - // - // PKCS7 - // - MemoryStream bOut = new MemoryStream(); - PemWriter pWrt = new PemWriter(new StreamWriter(bOut)); - - pWrt.WriteObject(d); - pWrt.Writer.Close(); - - pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); - d = (ContentInfo)pemRd.ReadObject(); - - if (!d.ContentType.Equals(CmsObjectIdentifiers.EnvelopedData)) - { - Fail("failed envelopedData recode check"); - } - - - // OpenSSL test cases (as embedded resources) - doOpenSslDsaTest("unencrypted"); - doOpenSslRsaTest("unencrypted"); - - doOpenSslTests("aes128"); - doOpenSslTests("aes192"); - doOpenSslTests("aes256"); - doOpenSslTests("blowfish"); - doOpenSslTests("des1"); - doOpenSslTests("des2"); - doOpenSslTests("des3"); - doOpenSslTests("rc2_128"); - - doOpenSslDsaTest("rc2_40_cbc"); - doOpenSslRsaTest("rc2_40_cbc"); - doOpenSslDsaTest("rc2_64_cbc"); - doOpenSslRsaTest("rc2_64_cbc"); - - // TODO Figure out why exceptions differ for commented out cases - doDudPasswordTest("7fd98", 0, "Corrupted stream - out of bounds length found"); - doDudPasswordTest("ef677", 1, "Corrupted stream - out of bounds length found"); -// doDudPasswordTest("800ce", 2, "cannot recognise object in stream"); - doDudPasswordTest("b6cd8", 3, "DEF length 81 object truncated by 56"); - doDudPasswordTest("28ce09", 4, "DEF length 110 object truncated by 28"); - doDudPasswordTest("2ac3b9", 5, "DER length more than 4 bytes: 11"); - doDudPasswordTest("2cba96", 6, "DEF length 100 object truncated by 35"); - doDudPasswordTest("2e3354", 7, "DEF length 42 object truncated by 9"); - doDudPasswordTest("2f4142", 8, "DER length more than 4 bytes: 14"); - doDudPasswordTest("2fe9bb", 9, "DER length more than 4 bytes: 65"); - doDudPasswordTest("3ee7a8", 10, "DER length more than 4 bytes: 57"); - doDudPasswordTest("41af75", 11, "malformed sequence in DSA private key"); - doDudPasswordTest("1704a5", 12, "corrupted stream detected"); -// doDudPasswordTest("1c5822", 13, "corrupted stream detected"); -// doDudPasswordTest("5a3d16", 14, "corrupted stream detected"); - doDudPasswordTest("8d0c97", 15, "corrupted stream detected"); - doDudPasswordTest("bc0daf", 16, "corrupted stream detected"); - doDudPasswordTest("aaf9c4d",17, "Corrupted stream - out of bounds length found"); - - // encrypted private key test - pGet = new Password("password".ToCharArray()); - pemRd = OpenPemResource("enckey.pem", pGet); - - RsaPrivateCrtKeyParameters privKey = (RsaPrivateCrtKeyParameters)pemRd.ReadObject(); - - if (!privKey.PublicExponent.Equals(new BigInteger("10001", 16))) - { - Fail("decryption of private key data check failed"); - } - - // general PKCS8 test - pGet = new Password("password".ToCharArray()); - pemRd = OpenPemResource("pkcs8test.pem", pGet); - - while ((privKey = (RsaPrivateCrtKeyParameters)pemRd.ReadObject()) != null) - { - if (!privKey.PublicExponent.Equals(new BigInteger("10001", 16))) - { - Fail("decryption of private key data check failed"); - } - } - } - - private void keyPairTest( - string name, - AsymmetricCipherKeyPair pair) - { - MemoryStream bOut = new MemoryStream(); - PemWriter pWrt = new PemWriter(new StreamWriter(bOut)); - - pWrt.WriteObject(pair.Public); - pWrt.Writer.Close(); - - PemReader pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); - - AsymmetricKeyParameter pubK = (AsymmetricKeyParameter) pemRd.ReadObject(); - if (!pubK.Equals(pair.Public)) - { - Fail("Failed public key read: " + name); - } - - bOut = new MemoryStream(); - pWrt = new PemWriter(new StreamWriter(bOut)); - - pWrt.WriteObject(pair.Private); - pWrt.Writer.Close(); - - pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); - - AsymmetricCipherKeyPair kPair = (AsymmetricCipherKeyPair) pemRd.ReadObject(); - if (!kPair.Private.Equals(pair.Private)) - { - Fail("Failed private key read: " + name); - } - - if (!kPair.Public.Equals(pair.Public)) - { - Fail("Failed private key public read: " + name); - } - } - - private void doOpenSslTests( - string baseName) - { - doOpenSslDsaModesTest(baseName); - doOpenSslRsaModesTest(baseName); - } - - private void doOpenSslDsaModesTest( - string baseName) - { - doOpenSslDsaTest(baseName + "_cbc"); - doOpenSslDsaTest(baseName + "_cfb"); - doOpenSslDsaTest(baseName + "_ecb"); - doOpenSslDsaTest(baseName + "_ofb"); - } - - private void doOpenSslRsaModesTest( - string baseName) - { - doOpenSslRsaTest(baseName + "_cbc"); - doOpenSslRsaTest(baseName + "_cfb"); - doOpenSslRsaTest(baseName + "_ecb"); - doOpenSslRsaTest(baseName + "_ofb"); - } - - private void doOpenSslDsaTest( - string name) - { - string fileName = "dsa.openssl_dsa_" + name + ".pem"; - - doOpenSslTestFile(fileName, typeof(DsaPrivateKeyParameters)); - } - - private void doOpenSslRsaTest( - string name) - { - string fileName = "rsa.openssl_rsa_" + name + ".pem"; - - doOpenSslTestFile(fileName, typeof(RsaPrivateCrtKeyParameters)); - } - - private void doOpenSslTestFile( - string fileName, - Type expectedPrivKeyType) - { - PemReader pr = OpenPemResource(fileName, new Password("changeit".ToCharArray())); - AsymmetricCipherKeyPair kp = pr.ReadObject() as AsymmetricCipherKeyPair; - pr.Reader.Close(); - - if (kp == null) - { - Fail("Didn't find OpenSSL key"); - } - - if (!expectedPrivKeyType.IsInstanceOfType(kp.Private)) - { - Fail("Returned key not of correct type"); - } - } - - private void doDudPasswordTest(string password, int index, string message) - { - // illegal state exception check - in this case the wrong password will - // cause an underlying class cast exception. - try - { - IPasswordFinder pGet = new Password(password.ToCharArray()); - PemReader pemRd = OpenPemResource("test.pem", pGet); - - Object o; - while ((o = pemRd.ReadObject()) != null) - { - } - - Fail("issue not detected: " + index); - } - catch (IOException e) - { - if (e.Message.IndexOf(message) < 0) - { - Console.Error.WriteLine(message); - Console.Error.WriteLine(e.Message); - Fail("issue " + index + " exception thrown, but wrong message"); - } - } - } - - private static PemReader OpenPemResource( - string fileName, - IPasswordFinder pGet) - { - Stream data = GetTestDataAsStream("openssl." + fileName); - TextReader tr = new StreamReader(data); - return new PemReader(tr, pGet); - } - - public static void Main( - string[] args) - { - RunTest(new ReaderTest()); - } - - [Test] - public void TestFunction() - { - string resultText = Perform().ToString(); - - Assert.AreEqual(Name + ": Okay", resultText); - } - } + DsaParametersGenerator pGen = new DsaParametersGenerator(); + pGen.Init(512, 80, new SecureRandom()); + + kpGen = GeneratorUtilities.GetKeyPairGenerator("DSA"); + kpGen.Init( + new DsaKeyGenerationParameters( + new SecureRandom(), + pGen.GenerateParameters())); + + pair = kpGen.GenerateKeyPair(); + + keyPairTest("DSA", pair); + + // + // PKCS7 + // + MemoryStream bOut = new MemoryStream(); + PemWriter pWrt = new PemWriter(new StreamWriter(bOut)); + + pWrt.WriteObject(d); + pWrt.Writer.Close(); + + pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); + d = (ContentInfo)pemRd.ReadObject(); + + if (!d.ContentType.Equals(CmsObjectIdentifiers.EnvelopedData)) + { + Fail("failed envelopedData recode check"); + } + + + // OpenSSL test cases (as embedded resources) + doOpenSslDsaTest("unencrypted"); + doOpenSslRsaTest("unencrypted"); + + doOpenSslTests("aes128"); + doOpenSslTests("aes192"); + doOpenSslTests("aes256"); + doOpenSslTests("blowfish"); + doOpenSslTests("des1"); + doOpenSslTests("des2"); + doOpenSslTests("des3"); + doOpenSslTests("rc2_128"); + + doOpenSslDsaTest("rc2_40_cbc"); + doOpenSslRsaTest("rc2_40_cbc"); + doOpenSslDsaTest("rc2_64_cbc"); + doOpenSslRsaTest("rc2_64_cbc"); + + doDudPasswordTest("7fd98", 0, "Corrupted stream - out of bounds length found"); + doDudPasswordTest("ef677", 1, "Corrupted stream - out of bounds length found"); + doDudPasswordTest("800ce", 2, "unknown tag 26 encountered"); + doDudPasswordTest("b6cd8", 3, "DEF length 81 object truncated by 56"); + doDudPasswordTest("28ce09", 4, "DEF length 110 object truncated by 28"); + doDudPasswordTest("2ac3b9", 5, "DER length more than 4 bytes: 11"); + doDudPasswordTest("2cba96", 6, "DEF length 100 object truncated by 35"); + doDudPasswordTest("2e3354", 7, "DEF length 42 object truncated by 9"); + doDudPasswordTest("2f4142", 8, "DER length more than 4 bytes: 14"); + doDudPasswordTest("2fe9bb", 9, "DER length more than 4 bytes: 65"); + doDudPasswordTest("3ee7a8", 10, "DER length more than 4 bytes: 57"); + doDudPasswordTest("41af75", 11, "unknown tag 16 encountered"); + doDudPasswordTest("1704a5", 12, "corrupted stream detected"); + doDudPasswordTest("1c5822", 13, "Unknown object in GetInstance: Org.BouncyCastle.Asn1.DerUtf8String"); + doDudPasswordTest("5a3d16", 14, "corrupted stream detected"); + doDudPasswordTest("8d0c97", 15, "corrupted stream detected"); + doDudPasswordTest("bc0daf", 16, "corrupted stream detected"); + doDudPasswordTest("aaf9c4d",17, "Corrupted stream - out of bounds length found"); + + // encrypted private key test + pGet = new Password("password".ToCharArray()); + pemRd = OpenPemResource("enckey.pem", pGet); + + RsaPrivateCrtKeyParameters privKey = (RsaPrivateCrtKeyParameters)pemRd.ReadObject(); + + if (!privKey.PublicExponent.Equals(new BigInteger("10001", 16))) + { + Fail("decryption of private key data check failed"); + } + + // general PKCS8 test + pGet = new Password("password".ToCharArray()); + pemRd = OpenPemResource("pkcs8test.pem", pGet); + + while ((privKey = (RsaPrivateCrtKeyParameters)pemRd.ReadObject()) != null) + { + if (!privKey.PublicExponent.Equals(new BigInteger("10001", 16))) + { + Fail("decryption of private key data check failed"); + } + } + } + + private void keyPairTest( + string name, + AsymmetricCipherKeyPair pair) + { + MemoryStream bOut = new MemoryStream(); + PemWriter pWrt = new PemWriter(new StreamWriter(bOut)); + + pWrt.WriteObject(pair.Public); + pWrt.Writer.Close(); + + PemReader pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); + + AsymmetricKeyParameter pubK = (AsymmetricKeyParameter) pemRd.ReadObject(); + if (!pubK.Equals(pair.Public)) + { + Fail("Failed public key read: " + name); + } + + bOut = new MemoryStream(); + pWrt = new PemWriter(new StreamWriter(bOut)); + + pWrt.WriteObject(pair.Private); + pWrt.Writer.Close(); + + pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false))); + + AsymmetricCipherKeyPair kPair = (AsymmetricCipherKeyPair) pemRd.ReadObject(); + if (!kPair.Private.Equals(pair.Private)) + { + Fail("Failed private key read: " + name); + } + + if (!kPair.Public.Equals(pair.Public)) + { + Fail("Failed private key public read: " + name); + } + } + + private void doOpenSslTests( + string baseName) + { + doOpenSslDsaModesTest(baseName); + doOpenSslRsaModesTest(baseName); + } + + private void doOpenSslDsaModesTest( + string baseName) + { + doOpenSslDsaTest(baseName + "_cbc"); + doOpenSslDsaTest(baseName + "_cfb"); + doOpenSslDsaTest(baseName + "_ecb"); + doOpenSslDsaTest(baseName + "_ofb"); + } + + private void doOpenSslRsaModesTest( + string baseName) + { + doOpenSslRsaTest(baseName + "_cbc"); + doOpenSslRsaTest(baseName + "_cfb"); + doOpenSslRsaTest(baseName + "_ecb"); + doOpenSslRsaTest(baseName + "_ofb"); + } + + private void doOpenSslDsaTest( + string name) + { + string fileName = "dsa.openssl_dsa_" + name + ".pem"; + + doOpenSslTestFile(fileName, typeof(DsaPrivateKeyParameters)); + } + + private void doOpenSslRsaTest( + string name) + { + string fileName = "rsa.openssl_rsa_" + name + ".pem"; + + doOpenSslTestFile(fileName, typeof(RsaPrivateCrtKeyParameters)); + } + + private void doOpenSslTestFile( + string fileName, + Type expectedPrivKeyType) + { + PemReader pr = OpenPemResource(fileName, new Password("changeit".ToCharArray())); + AsymmetricCipherKeyPair kp = pr.ReadObject() as AsymmetricCipherKeyPair; + pr.Reader.Close(); + + if (kp == null) + { + Fail("Didn't find OpenSSL key"); + } + + if (!expectedPrivKeyType.IsInstanceOfType(kp.Private)) + { + Fail("Returned key not of correct type"); + } + } + + private void doDudPasswordTest(string password, int index, string message) + { + // illegal state exception check - in this case the wrong password will + // cause an underlying class cast exception. + try + { + IPasswordFinder pGet = new Password(password.ToCharArray()); + PemReader pemRd = OpenPemResource("test.pem", pGet); + + Object o; + while ((o = pemRd.ReadObject()) != null) + { + } + + Fail("issue not detected: " + index); + } + catch (IOException e) + { + if (e.Message.IndexOf(message) < 0) + { + Console.Error.WriteLine(message); + Console.Error.WriteLine(e.Message); + Fail("issue " + index + " exception thrown, but wrong message"); + } + } + } + + private static PemReader OpenPemResource( + string fileName, + IPasswordFinder pGet) + { + Stream data = GetTestDataAsStream("openssl." + fileName); + TextReader tr = new StreamReader(data); + return new PemReader(tr, pGet); + } + + public static void Main( + string[] args) + { + RunTest(new ReaderTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } } -- cgit 1.5.1 From 5abe3db293d6dfed650a26bb9c3f5c839ccf2aa5 Mon Sep 17 00:00:00 2001 From: Peter DettmanNote: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.
*/ @@ -195,31 +195,31 @@ namespace Org.BouncyCastle.Asn1.X509 * from back to front. */ // public static bool DefaultReverse = false; - public static bool DefaultReverse - { - get { return defaultReverse[0]; } - set { defaultReverse[0] = value; } - } + public static bool DefaultReverse + { + get { return defaultReverse[0]; } + set { defaultReverse[0] = value; } + } - private static readonly bool[] defaultReverse = { false }; + private static readonly bool[] defaultReverse = { false }; #if SILVERLIGHT - /** - * default look up table translating OID values into their common symbols following - * the convention in RFC 2253 with a few extras - */ - public static readonly IDictionary DefaultSymbols = Platform.CreateHashtable(); - - /** - * look up table translating OID values into their common symbols following the convention in RFC 2253 - */ - public static readonly IDictionary RFC2253Symbols = Platform.CreateHashtable(); - - /** - * look up table translating OID values into their common symbols following the convention in RFC 1779 - * - */ - public static readonly IDictionary RFC1779Symbols = Platform.CreateHashtable(); + /** + * default look up table translating OID values into their common symbols following + * the convention in RFC 2253 with a few extras + */ + public static readonly IDictionary DefaultSymbols = Platform.CreateHashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 2253 + */ + public static readonly IDictionary RFC2253Symbols = Platform.CreateHashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 1779 + * + */ + public static readonly IDictionary RFC1779Symbols = Platform.CreateHashtable(); /** * look up table translating common symbols into their OIDS. @@ -227,21 +227,21 @@ namespace Org.BouncyCastle.Asn1.X509 public static readonly IDictionary DefaultLookup = Platform.CreateHashtable(); #else /** - * default look up table translating OID values into their common symbols following - * the convention in RFC 2253 with a few extras - */ - public static readonly Hashtable DefaultSymbols = new Hashtable(); - - /** - * look up table translating OID values into their common symbols following the convention in RFC 2253 - */ - public static readonly Hashtable RFC2253Symbols = new Hashtable(); - - /** - * look up table translating OID values into their common symbols following the convention in RFC 1779 - * - */ - public static readonly Hashtable RFC1779Symbols = new Hashtable(); + * default look up table translating OID values into their common symbols following + * the convention in RFC 2253 with a few extras + */ + public static readonly Hashtable DefaultSymbols = new Hashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 2253 + */ + public static readonly Hashtable RFC2253Symbols = new Hashtable(); + + /** + * look up table translating OID values into their common symbols following the convention in RFC 1779 + * + */ + public static readonly Hashtable RFC1779Symbols = new Hashtable(); /** * look up table translating common symbols into their OIDS. @@ -262,26 +262,26 @@ namespace Org.BouncyCastle.Asn1.X509 DefaultSymbols.Add(EmailAddress, "E"); DefaultSymbols.Add(DC, "DC"); DefaultSymbols.Add(UID, "UID"); - DefaultSymbols.Add(Street, "STREET"); + DefaultSymbols.Add(Street, "STREET"); DefaultSymbols.Add(Surname, "SURNAME"); DefaultSymbols.Add(GivenName, "GIVENNAME"); DefaultSymbols.Add(Initials, "INITIALS"); DefaultSymbols.Add(Generation, "GENERATION"); DefaultSymbols.Add(UnstructuredAddress, "unstructuredAddress"); DefaultSymbols.Add(UnstructuredName, "unstructuredName"); - DefaultSymbols.Add(UniqueIdentifier, "UniqueIdentifier"); - DefaultSymbols.Add(DnQualifier, "DN"); - DefaultSymbols.Add(Pseudonym, "Pseudonym"); - DefaultSymbols.Add(PostalAddress, "PostalAddress"); - DefaultSymbols.Add(NameAtBirth, "NameAtBirth"); - DefaultSymbols.Add(CountryOfCitizenship, "CountryOfCitizenship"); - DefaultSymbols.Add(CountryOfResidence, "CountryOfResidence"); - DefaultSymbols.Add(Gender, "Gender"); - DefaultSymbols.Add(PlaceOfBirth, "PlaceOfBirth"); - DefaultSymbols.Add(DateOfBirth, "DateOfBirth"); - DefaultSymbols.Add(PostalCode, "PostalCode"); - DefaultSymbols.Add(BusinessCategory, "BusinessCategory"); - DefaultSymbols.Add(TelephoneNumber, "TelephoneNumber"); + DefaultSymbols.Add(UniqueIdentifier, "UniqueIdentifier"); + DefaultSymbols.Add(DnQualifier, "DN"); + DefaultSymbols.Add(Pseudonym, "Pseudonym"); + DefaultSymbols.Add(PostalAddress, "PostalAddress"); + DefaultSymbols.Add(NameAtBirth, "NameAtBirth"); + DefaultSymbols.Add(CountryOfCitizenship, "CountryOfCitizenship"); + DefaultSymbols.Add(CountryOfResidence, "CountryOfResidence"); + DefaultSymbols.Add(Gender, "Gender"); + DefaultSymbols.Add(PlaceOfBirth, "PlaceOfBirth"); + DefaultSymbols.Add(DateOfBirth, "DateOfBirth"); + DefaultSymbols.Add(PostalCode, "PostalCode"); + DefaultSymbols.Add(BusinessCategory, "BusinessCategory"); + DefaultSymbols.Add(TelephoneNumber, "TelephoneNumber"); RFC2253Symbols.Add(C, "C"); RFC2253Symbols.Add(O, "O"); @@ -289,28 +289,28 @@ namespace Org.BouncyCastle.Asn1.X509 RFC2253Symbols.Add(CN, "CN"); RFC2253Symbols.Add(L, "L"); RFC2253Symbols.Add(ST, "ST"); - RFC2253Symbols.Add(Street, "STREET"); - RFC2253Symbols.Add(DC, "DC"); + RFC2253Symbols.Add(Street, "STREET"); + RFC2253Symbols.Add(DC, "DC"); RFC2253Symbols.Add(UID, "UID"); - RFC1779Symbols.Add(C, "C"); - RFC1779Symbols.Add(O, "O"); - RFC1779Symbols.Add(OU, "OU"); - RFC1779Symbols.Add(CN, "CN"); - RFC1779Symbols.Add(L, "L"); - RFC1779Symbols.Add(ST, "ST"); - RFC1779Symbols.Add(Street, "STREET"); + RFC1779Symbols.Add(C, "C"); + RFC1779Symbols.Add(O, "O"); + RFC1779Symbols.Add(OU, "OU"); + RFC1779Symbols.Add(CN, "CN"); + RFC1779Symbols.Add(L, "L"); + RFC1779Symbols.Add(ST, "ST"); + RFC1779Symbols.Add(Street, "STREET"); - DefaultLookup.Add("c", C); + DefaultLookup.Add("c", C); DefaultLookup.Add("o", O); DefaultLookup.Add("t", T); DefaultLookup.Add("ou", OU); DefaultLookup.Add("cn", CN); DefaultLookup.Add("l", L); DefaultLookup.Add("st", ST); - DefaultLookup.Add("serialnumber", SerialNumber); - DefaultLookup.Add("street", Street); - DefaultLookup.Add("emailaddress", E); + DefaultLookup.Add("serialnumber", SerialNumber); + DefaultLookup.Add("street", Street); + DefaultLookup.Add("emailaddress", E); DefaultLookup.Add("dc", DC); DefaultLookup.Add("e", E); DefaultLookup.Add("uid", UID); @@ -320,29 +320,29 @@ namespace Org.BouncyCastle.Asn1.X509 DefaultLookup.Add("generation", Generation); DefaultLookup.Add("unstructuredaddress", UnstructuredAddress); DefaultLookup.Add("unstructuredname", UnstructuredName); - DefaultLookup.Add("uniqueidentifier", UniqueIdentifier); - DefaultLookup.Add("dn", DnQualifier); - DefaultLookup.Add("pseudonym", Pseudonym); - DefaultLookup.Add("postaladdress", PostalAddress); - DefaultLookup.Add("nameofbirth", NameAtBirth); - DefaultLookup.Add("countryofcitizenship", CountryOfCitizenship); - DefaultLookup.Add("countryofresidence", CountryOfResidence); - DefaultLookup.Add("gender", Gender); - DefaultLookup.Add("placeofbirth", PlaceOfBirth); - DefaultLookup.Add("dateofbirth", DateOfBirth); - DefaultLookup.Add("postalcode", PostalCode); - DefaultLookup.Add("businesscategory", BusinessCategory); - DefaultLookup.Add("telephonenumber", TelephoneNumber); - } + DefaultLookup.Add("uniqueidentifier", UniqueIdentifier); + DefaultLookup.Add("dn", DnQualifier); + DefaultLookup.Add("pseudonym", Pseudonym); + DefaultLookup.Add("postaladdress", PostalAddress); + DefaultLookup.Add("nameofbirth", NameAtBirth); + DefaultLookup.Add("countryofcitizenship", CountryOfCitizenship); + DefaultLookup.Add("countryofresidence", CountryOfResidence); + DefaultLookup.Add("gender", Gender); + DefaultLookup.Add("placeofbirth", PlaceOfBirth); + DefaultLookup.Add("dateofbirth", DateOfBirth); + DefaultLookup.Add("postalcode", PostalCode); + DefaultLookup.Add("businesscategory", BusinessCategory); + DefaultLookup.Add("telephonenumber", TelephoneNumber); + } private readonly IList ordering = Platform.CreateArrayList(); - private readonly X509NameEntryConverter converter; + private readonly X509NameEntryConverter converter; - private IList values = Platform.CreateArrayList(); + private IList values = Platform.CreateArrayList(); private IList added = Platform.CreateArrayList(); private Asn1Sequence seq; - /** + /** * Return a X509Name based on the passed in tagged object. * * @param obj tag object holding name. @@ -356,23 +356,23 @@ namespace Org.BouncyCastle.Asn1.X509 return GetInstance(Asn1Sequence.GetInstance(obj, explicitly)); } - public static X509Name GetInstance( + public static X509Name GetInstance( object obj) { if (obj == null || obj is X509Name) return (X509Name)obj; - if (obj != null) - return new X509Name(Asn1Sequence.GetInstance(obj)); + if (obj != null) + return new X509Name(Asn1Sequence.GetInstance(obj)); - throw new ArgumentException("null object in factory", "obj"); + throw new ArgumentException("null object in factory", "obj"); } - protected X509Name() - { - } + protected X509Name() + { + } - /** + /** * Constructor from Asn1Sequence * * the principal will be a list of constructed sets, each containing an (OID, string) pair. @@ -382,50 +382,40 @@ namespace Org.BouncyCastle.Asn1.X509 { this.seq = seq; - foreach (Asn1Encodable asn1Obj in seq) - { - Asn1Set asn1Set = Asn1Set.GetInstance(asn1Obj.ToAsn1Object()); + foreach (Asn1Encodable asn1Obj in seq) + { + Asn1Set asn1Set = Asn1Set.GetInstance(asn1Obj.ToAsn1Object()); - for (int i = 0; i < asn1Set.Count; i++) + for (int i = 0; i < asn1Set.Count; i++) { - Asn1Sequence s = Asn1Sequence.GetInstance(asn1Set[i].ToAsn1Object()); + Asn1Sequence s = Asn1Sequence.GetInstance(asn1Set[i].ToAsn1Object()); - if (s.Count != 2) - throw new ArgumentException("badly sized pair"); + if (s.Count != 2) + throw new ArgumentException("badly sized pair"); - ordering.Add(DerObjectIdentifier.GetInstance(s[0].ToAsn1Object())); + ordering.Add(DerObjectIdentifier.GetInstance(s[0].ToAsn1Object())); - Asn1Object derValue = s[1].ToAsn1Object(); - if (derValue is IAsn1String && !(derValue is DerUniversalString)) - { - string v = ((IAsn1String)derValue).GetString(); - if (v.StartsWith("#")) - { - v = "\\" + v; - } + Asn1Object derValue = s[1].ToAsn1Object(); + if (derValue is IAsn1String && !(derValue is DerUniversalString)) + { + string v = ((IAsn1String)derValue).GetString(); + if (v.StartsWith("#")) + { + v = "\\" + v; + } - values.Add(v); - } + values.Add(v); + } else { - values.Add("#" + Hex.ToHexString(derValue.GetEncoded())); + values.Add("#" + Hex.ToHexString(derValue.GetEncoded())); } - added.Add(i != 0); + added.Add(i != 0); } } } -#if !SILVERLIGHT - [Obsolete] - public X509Name( - ArrayList ordering, - Hashtable attributes) - : this(ordering, attributes, new X509DefaultEntryConverter()) - { - } -#endif - /** * Constructor from a table of attributes with ordering. *@@ -441,18 +431,7 @@ namespace Org.BouncyCastle.Asn1.X509 { } -#if !SILVERLIGHT - [Obsolete] - public X509Name( - ArrayList ordering, - Hashtable attributes, - X509NameEntryConverter converter) - : this((IList)ordering, (IDictionary)attributes, converter) - { - } -#endif - - /** + /** * Constructor from a table of attributes with ordering. *
* it's is assumed the table contains OID/string pairs, and the contents @@ -468,33 +447,23 @@ namespace Org.BouncyCastle.Asn1.X509 IDictionary attributes, X509NameEntryConverter converter) { - this.converter = converter; - - foreach (DerObjectIdentifier oid in ordering) - { - object attribute = attributes[oid]; - if (attribute == null) - { - throw new ArgumentException("No attribute for object id - " + oid + " - passed to distinguished name"); - } - - this.ordering.Add(oid); - this.added.Add(false); - this.values.Add(attribute); // copy the hash table - } - } + this.converter = converter; -#if !SILVERLIGHT - [Obsolete] - public X509Name( - ArrayList oids, - ArrayList values) - : this(oids, values, new X509DefaultEntryConverter()) - { + foreach (DerObjectIdentifier oid in ordering) + { + object attribute = attributes[oid]; + if (attribute == null) + { + throw new ArgumentException("No attribute for object id - " + oid + " - passed to distinguished name"); + } + + this.ordering.Add(oid); + this.added.Add(false); + this.values.Add(attribute); // copy the hash table + } } -#endif - /** + /** * Takes two vectors one of the oids and the other of the values. */ public X509Name( @@ -504,18 +473,7 @@ namespace Org.BouncyCastle.Asn1.X509 { } -#if !SILVERLIGHT - [Obsolete] - public X509Name( - ArrayList oids, - ArrayList values, - X509NameEntryConverter converter) - : this((IList)oids, (IList)values, converter) - { - } -#endif - - /** + /** * Takes two vectors one of the oids and the other of the values. *
* The passed in converter will be used to convert the strings into their @@ -528,12 +486,12 @@ namespace Org.BouncyCastle.Asn1.X509 { this.converter = converter; - if (oids.Count != values.Count) + if (oids.Count != values.Count) { throw new ArgumentException("'oids' must be same length as 'values'."); } - for (int i = 0; i < oids.Count; i++) + for (int i = 0; i < oids.Count; i++) { this.ordering.Add(oids[i]); this.values.Add(values[i]); @@ -547,7 +505,7 @@ namespace Org.BouncyCastle.Asn1.X509 // return s.StartsWith("#"); // } - /** + /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes. */ @@ -557,7 +515,7 @@ namespace Org.BouncyCastle.Asn1.X509 { } - /** + /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes with each * string value being converted to its associated ASN.1 type using the passed @@ -570,7 +528,7 @@ namespace Org.BouncyCastle.Asn1.X509 { } - /** + /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes. If reverse * is true, create the encoded version of the sequence starting from the @@ -583,7 +541,7 @@ namespace Org.BouncyCastle.Asn1.X509 { } - /** + /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes with each * string value being converted to its associated ASN.1 type using the passed @@ -598,18 +556,7 @@ namespace Org.BouncyCastle.Asn1.X509 { } -#if !SILVERLIGHT - [Obsolete] - public X509Name( - bool reverse, - Hashtable lookUp, - string dirName) - : this(reverse, lookUp, dirName, new X509DefaultEntryConverter()) - { - } -#endif - - /** + /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes. lookUp * should provide a table of lookups, indexed by lowercase only strings and @@ -630,7 +577,7 @@ namespace Org.BouncyCastle.Asn1.X509 { } - private DerObjectIdentifier DecodeOid( + private DerObjectIdentifier DecodeOid( string name, IDictionary lookUp) { @@ -643,16 +590,16 @@ namespace Org.BouncyCastle.Asn1.X509 return new DerObjectIdentifier(name); } - DerObjectIdentifier oid = (DerObjectIdentifier)lookUp[Platform.ToLowerInvariant(name)]; + DerObjectIdentifier oid = (DerObjectIdentifier)lookUp[Platform.ToLowerInvariant(name)]; if (oid == null) { throw new ArgumentException("Unknown object id - " + name + " - passed to distinguished name"); } - return oid; + return oid; } - /** + /** * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or * some such, converting it into an ordered set of name attributes. lookUp * should provide a table of lookups, indexed by lowercase only strings and @@ -674,30 +621,30 @@ namespace Org.BouncyCastle.Asn1.X509 this.converter = converter; X509NameTokenizer nTok = new X509NameTokenizer(dirName); - while (nTok.HasMoreTokens()) + while (nTok.HasMoreTokens()) { string token = nTok.NextToken(); int index = token.IndexOf('='); - if (index == -1) + if (index == -1) { throw new ArgumentException("badly formated directory string"); } - string name = token.Substring(0, index); + string name = token.Substring(0, index); string value = token.Substring(index + 1); DerObjectIdentifier oid = DecodeOid(name, lookUp); - if (value.IndexOf('+') > 0) + if (value.IndexOf('+') > 0) { X509NameTokenizer vTok = new X509NameTokenizer(value, '+'); - string v = vTok.NextToken(); + string v = vTok.NextToken(); - this.ordering.Add(oid); + this.ordering.Add(oid); this.values.Add(v); this.added.Add(false); - while (vTok.HasMoreTokens()) + while (vTok.HasMoreTokens()) { string sv = vTok.NextToken(); int ndx = sv.IndexOf('='); @@ -717,46 +664,35 @@ namespace Org.BouncyCastle.Asn1.X509 } } - if (reverse) + if (reverse) { // this.ordering.Reverse(); // this.values.Reverse(); // this.added.Reverse(); - IList o = Platform.CreateArrayList(); + IList o = Platform.CreateArrayList(); IList v = Platform.CreateArrayList(); IList a = Platform.CreateArrayList(); - int count = 1; - - for (int i = 0; i < this.ordering.Count; i++) - { - if (!((bool) this.added[i])) - { - count = 0; - } - - int index = count++; - - o.Insert(index, this.ordering[i]); - v.Insert(index, this.values[i]); - a.Insert(index, this.added[i]); - } - - this.ordering = o; - this.values = v; - this.added = a; - } - } + int count = 1; -#if !SILVERLIGHT - /** - * return an ArrayList of the oids in the name, in the order they were found. - */ - [Obsolete("Use 'GetOidList' instead")] - public ArrayList GetOids() - { - return new ArrayList(ordering); + for (int i = 0; i < this.ordering.Count; i++) + { + if (!((bool) this.added[i])) + { + count = 0; + } + + int index = count++; + + o.Insert(index, this.ordering[i]); + v.Insert(index, this.values[i]); + a.Insert(index, this.added[i]); + } + + this.ordering = o; + this.values = v; + this.added = a; + } } -#endif /** * return an IList of the oids in the name, in the order they were found. @@ -766,57 +702,25 @@ namespace Org.BouncyCastle.Asn1.X509 return Platform.CreateArrayList(ordering); } -#if !SILVERLIGHT - /** - * return an ArrayList of the values found in the name, in the order they - * were found. - */ - [Obsolete("Use 'GetValueList' instead")] - public ArrayList GetValues() - { - return new ArrayList(values); - } -#endif - /** * return an IList of the values found in the name, in the order they * were found. */ public IList GetValueList() { - return Platform.CreateArrayList(values); + return GetValueList(null); } -#if !SILVERLIGHT - /** - * return an ArrayList of the values found in the name, in the order they - * were found, with the DN label corresponding to passed in oid. - */ - public ArrayList GetValues( - DerObjectIdentifier oid) - { - ArrayList v = new ArrayList(); - DoGetValueList(oid, v); - return v; - } -#endif - - /** - * return an IList of the values found in the name, in the order they - * were found, with the DN label corresponding to passed in oid. - */ + /** + * return an IList of the values found in the name, in the order they + * were found, with the DN label corresponding to passed in oid. + */ public IList GetValueList(DerObjectIdentifier oid) { IList v = Platform.CreateArrayList(); - DoGetValueList(oid, v); - return v; - } - - private void DoGetValueList(DerObjectIdentifier oid, IList v) - { for (int i = 0; i != values.Count; i++) { - if (ordering[i].Equals(oid)) + if (null == oid || oid.Equals(ordering[i])) { string val = (string)values[i]; @@ -828,9 +732,10 @@ namespace Org.BouncyCastle.Asn1.X509 v.Add(val); } } + return v; } - public override Asn1Object ToAsn1Object() + public override Asn1Object ToAsn1Object() { if (seq == null) { @@ -838,12 +743,12 @@ namespace Org.BouncyCastle.Asn1.X509 Asn1EncodableVector sVec = new Asn1EncodableVector(); DerObjectIdentifier lstOid = null; - for (int i = 0; i != ordering.Count; i++) + for (int i = 0; i != ordering.Count; i++) { DerObjectIdentifier oid = (DerObjectIdentifier)ordering[i]; - string str = (string)values[i]; + string str = (string)values[i]; - if (lstOid == null + if (lstOid == null || ((bool)this.added[i])) { } @@ -853,211 +758,211 @@ namespace Org.BouncyCastle.Asn1.X509 sVec = new Asn1EncodableVector(); } - sVec.Add( - new DerSequence( - oid, - converter.GetConvertedValue(oid, str))); + sVec.Add( + new DerSequence( + oid, + converter.GetConvertedValue(oid, str))); - lstOid = oid; + lstOid = oid; } - vec.Add(new DerSet(sVec)); + vec.Add(new DerSet(sVec)); - seq = new DerSequence(vec); + seq = new DerSequence(vec); } return seq; } /// The X509Name object to test equivalency against. - /// If true, the order of elements must be the same, - /// as well as the values associated with each element. - public bool Equivalent( - X509Name other, - bool inOrder) - { - if (!inOrder) - return this.Equivalent(other); + /// If true, the order of elements must be the same, + /// as well as the values associated with each element. + public bool Equivalent( + X509Name other, + bool inOrder) + { + if (!inOrder) + return this.Equivalent(other); - if (other == null) - return false; + if (other == null) + return false; - if (other == this) - return true; + if (other == this) + return true; - int orderingSize = ordering.Count; + int orderingSize = ordering.Count; - if (orderingSize != other.ordering.Count) - return false; + if (orderingSize != other.ordering.Count) + return false; - for (int i = 0; i < orderingSize; i++) - { - DerObjectIdentifier oid = (DerObjectIdentifier) ordering[i]; - DerObjectIdentifier oOid = (DerObjectIdentifier) other.ordering[i]; + for (int i = 0; i < orderingSize; i++) + { + DerObjectIdentifier oid = (DerObjectIdentifier) ordering[i]; + DerObjectIdentifier oOid = (DerObjectIdentifier) other.ordering[i]; - if (!oid.Equals(oOid)) - return false; + if (!oid.Equals(oOid)) + return false; - string val = (string) values[i]; - string oVal = (string) other.values[i]; + string val = (string) values[i]; + string oVal = (string) other.values[i]; - if (!equivalentStrings(val, oVal)) - return false; - } + if (!equivalentStrings(val, oVal)) + return false; + } - return true; - } + return true; + } /** - * test for equivalence - note: case is ignored. - */ - public bool Equivalent( - X509Name other) - { - if (other == null) - return false; - - if (other == this) - return true; - - int orderingSize = ordering.Count; - - if (orderingSize != other.ordering.Count) - { - return false; - } - - bool[] indexes = new bool[orderingSize]; - int start, end, delta; - - if (ordering[0].Equals(other.ordering[0])) // guess forward - { - start = 0; - end = orderingSize; - delta = 1; - } - else // guess reversed - most common problem - { - start = orderingSize - 1; - end = -1; - delta = -1; - } - - for (int i = start; i != end; i += delta) - { - bool found = false; - DerObjectIdentifier oid = (DerObjectIdentifier)ordering[i]; - string value = (string)values[i]; - - for (int j = 0; j < orderingSize; j++) - { - if (indexes[j]) - { - continue; - } - - DerObjectIdentifier oOid = (DerObjectIdentifier)other.ordering[j]; - - if (oid.Equals(oOid)) - { - string oValue = (string)other.values[j]; - - if (equivalentStrings(value, oValue)) - { - indexes[j] = true; - found = true; - break; - } - } - } - - if (!found) - { - return false; - } - } - - return true; - } - - private static bool equivalentStrings( - string s1, - string s2) - { - string v1 = canonicalize(s1); - string v2 = canonicalize(s2); - - if (!v1.Equals(v2)) - { - v1 = stripInternalSpaces(v1); - v2 = stripInternalSpaces(v2); - - if (!v1.Equals(v2)) - { - return false; - } - } - - return true; - } - - private static string canonicalize( - string s) - { + * test for equivalence - note: case is ignored. + */ + public bool Equivalent( + X509Name other) + { + if (other == null) + return false; + + if (other == this) + return true; + + int orderingSize = ordering.Count; + + if (orderingSize != other.ordering.Count) + { + return false; + } + + bool[] indexes = new bool[orderingSize]; + int start, end, delta; + + if (ordering[0].Equals(other.ordering[0])) // guess forward + { + start = 0; + end = orderingSize; + delta = 1; + } + else // guess reversed - most common problem + { + start = orderingSize - 1; + end = -1; + delta = -1; + } + + for (int i = start; i != end; i += delta) + { + bool found = false; + DerObjectIdentifier oid = (DerObjectIdentifier)ordering[i]; + string value = (string)values[i]; + + for (int j = 0; j < orderingSize; j++) + { + if (indexes[j]) + { + continue; + } + + DerObjectIdentifier oOid = (DerObjectIdentifier)other.ordering[j]; + + if (oid.Equals(oOid)) + { + string oValue = (string)other.values[j]; + + if (equivalentStrings(value, oValue)) + { + indexes[j] = true; + found = true; + break; + } + } + } + + if (!found) + { + return false; + } + } + + return true; + } + + private static bool equivalentStrings( + string s1, + string s2) + { + string v1 = canonicalize(s1); + string v2 = canonicalize(s2); + + if (!v1.Equals(v2)) + { + v1 = stripInternalSpaces(v1); + v2 = stripInternalSpaces(v2); + + if (!v1.Equals(v2)) + { + return false; + } + } + + return true; + } + + private static string canonicalize( + string s) + { string v = Platform.ToLowerInvariant(s).Trim(); if (v.StartsWith("#")) - { - Asn1Object obj = decodeObject(v); - - if (obj is IAsn1String) - { - v = Platform.ToLowerInvariant(((IAsn1String)obj).GetString()).Trim(); - } - } - - return v; - } - - private static Asn1Object decodeObject( - string v) - { - try - { - return Asn1Object.FromByteArray(Hex.Decode(v.Substring(1))); - } - catch (IOException e) - { - throw new InvalidOperationException("unknown encoding in name: " + e.Message, e); - } - } - - private static string stripInternalSpaces( - string str) - { - StringBuilder res = new StringBuilder(); - - if (str.Length != 0) - { - char c1 = str[0]; - - res.Append(c1); - - for (int k = 1; k < str.Length; k++) - { - char c2 = str[k]; - if (!(c1 == ' ' && c2 == ' ')) - { - res.Append(c2); - } - c1 = c2; - } - } - - return res.ToString(); - } - - private void AppendValue( + { + Asn1Object obj = decodeObject(v); + + if (obj is IAsn1String) + { + v = Platform.ToLowerInvariant(((IAsn1String)obj).GetString()).Trim(); + } + } + + return v; + } + + private static Asn1Object decodeObject( + string v) + { + try + { + return Asn1Object.FromByteArray(Hex.Decode(v.Substring(1))); + } + catch (IOException e) + { + throw new InvalidOperationException("unknown encoding in name: " + e.Message, e); + } + } + + private static string stripInternalSpaces( + string str) + { + StringBuilder res = new StringBuilder(); + + if (str.Length != 0) + { + char c1 = str[0]; + + res.Append(c1); + + for (int k = 1; k < str.Length; k++) + { + char c2 = str[k]; + if (!(c1 == ' ' && c2 == ' ')) + { + res.Append(c2); + } + c1 = c2; + } + } + + return res.ToString(); + } + + private void AppendValue( StringBuilder buf, IDictionary oidSymbols, DerObjectIdentifier oid, @@ -1082,18 +987,18 @@ namespace Org.BouncyCastle.Asn1.X509 int end = buf.Length; - if (val.StartsWith("\\#")) - { - index += 2; - } + if (val.StartsWith("\\#")) + { + index += 2; + } - while (index != end) + while (index != end) { if ((buf[index] == ',') || (buf[index] == '"') || (buf[index] == '\\') || (buf[index] == '+') - || (buf[index] == '=') + || (buf[index] == '=') || (buf[index] == '<') || (buf[index] == '>') || (buf[index] == ';')) @@ -1106,16 +1011,6 @@ namespace Org.BouncyCastle.Asn1.X509 } } -#if !SILVERLIGHT - [Obsolete] - public string ToString( - bool reverse, - Hashtable oidSymbols) - { - return ToString(reverse, (IDictionary)oidSymbols); - } -#endif - /** * convert the structure to a string - if reverse is true the * oids and values are listed out starting with the last element @@ -1135,52 +1030,52 @@ namespace Org.BouncyCastle.Asn1.X509 #if SILVERLIGHT List