summary refs log tree commit diff
path: root/crypto/test/src/asn1
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/test/src/asn1')
-rw-r--r--crypto/test/src/asn1/test/ASN1SequenceParserTest.cs359
-rw-r--r--crypto/test/src/asn1/test/ASN1UnitTest.cs88
-rw-r--r--crypto/test/src/asn1/test/AdditionalInformationSyntaxUnitTest.cs77
-rw-r--r--crypto/test/src/asn1/test/AdmissionSyntaxUnitTest.cs99
-rw-r--r--crypto/test/src/asn1/test/AdmissionsUnitTest.cs90
-rw-r--r--crypto/test/src/asn1/test/AllTests.cs32
-rw-r--r--crypto/test/src/asn1/test/AttributeTableUnitTest.cs151
-rw-r--r--crypto/test/src/asn1/test/BiometricDataUnitTest.cs133
-rw-r--r--crypto/test/src/asn1/test/BitStringConstantTester.cs25
-rw-r--r--crypto/test/src/asn1/test/BitStringTest.cs82
-rw-r--r--crypto/test/src/asn1/test/CMSTest.cs306
-rw-r--r--crypto/test/src/asn1/test/CertHashUnitTest.cs93
-rw-r--r--crypto/test/src/asn1/test/CertificateTest.cs395
-rw-r--r--crypto/test/src/asn1/test/CommitmentTypeIndicationUnitTest.cs107
-rw-r--r--crypto/test/src/asn1/test/CommitmentTypeQualifierUnitTest.cs107
-rw-r--r--crypto/test/src/asn1/test/ContentHintsUnitTest.cs93
-rw-r--r--crypto/test/src/asn1/test/CscaMasterListTest.cs57
-rw-r--r--crypto/test/src/asn1/test/DERApplicationSpecificTest.cs88
-rw-r--r--crypto/test/src/asn1/test/DERUTF8StringTest.cs113
-rw-r--r--crypto/test/src/asn1/test/DataGroupHashUnitTest.cs106
-rw-r--r--crypto/test/src/asn1/test/DeclarationOfMajorityUnitTest.cs97
-rw-r--r--crypto/test/src/asn1/test/EncryptedPrivateKeyInfoTest.cs152
-rw-r--r--crypto/test/src/asn1/test/EqualsAndHashCodeTest.cs94
-rw-r--r--crypto/test/src/asn1/test/EssCertIDv2UnitTest.cs46
-rw-r--r--crypto/test/src/asn1/test/GeneralNameTest.cs116
-rw-r--r--crypto/test/src/asn1/test/GeneralizedTimeTest.cs193
-rw-r--r--crypto/test/src/asn1/test/GenerationTest.cs325
-rw-r--r--crypto/test/src/asn1/test/InputStreamTest.cs85
-rw-r--r--crypto/test/src/asn1/test/Iso4217CurrencyCodeUnitTest.cs156
-rw-r--r--crypto/test/src/asn1/test/IssuingDistributionPointTest.cs133
-rw-r--r--crypto/test/src/asn1/test/KeyUsageTest.cs49
-rw-r--r--crypto/test/src/asn1/test/LDSSecurityObjectUnitTest.cs208
-rw-r--r--crypto/test/src/asn1/test/MiscTest.cs100
-rw-r--r--crypto/test/src/asn1/test/MonetaryLimitUnitTest.cs93
-rw-r--r--crypto/test/src/asn1/test/MonetaryValueUnitTest.cs99
-rw-r--r--crypto/test/src/asn1/test/NameOrPseudonymUnitTest.cs114
-rw-r--r--crypto/test/src/asn1/test/NamingAuthorityUnitTest.cs106
-rw-r--r--crypto/test/src/asn1/test/NetscapeCertTypeTest.cs45
-rw-r--r--crypto/test/src/asn1/test/OCSPTest.cs183
-rw-r--r--crypto/test/src/asn1/test/OIDTest.cs149
-rw-r--r--crypto/test/src/asn1/test/OctetStringTest.cs186
-rw-r--r--crypto/test/src/asn1/test/OtherCertIDUnitTest.cs100
-rw-r--r--crypto/test/src/asn1/test/OtherSigningCertificateUnitTest.cs94
-rw-r--r--crypto/test/src/asn1/test/PKCS10Test.cs95
-rw-r--r--crypto/test/src/asn1/test/PKCS12Test.cs210
-rw-r--r--crypto/test/src/asn1/test/PKIFailureInfoTest.cs76
-rw-r--r--crypto/test/src/asn1/test/ParseTest.cs303
-rw-r--r--crypto/test/src/asn1/test/ParsingTest.cs104
-rw-r--r--crypto/test/src/asn1/test/PersonalDataUnitTest.cs127
-rw-r--r--crypto/test/src/asn1/test/ProcurationSyntaxUnitTest.cs111
-rw-r--r--crypto/test/src/asn1/test/ProfessionInfoUnitTest.cs121
-rw-r--r--crypto/test/src/asn1/test/QCStatementUnitTest.cs108
-rw-r--r--crypto/test/src/asn1/test/ReasonFlagsTest.cs46
-rw-r--r--crypto/test/src/asn1/test/RegressionTest.cs85
-rw-r--r--crypto/test/src/asn1/test/RequestedCertificateUnitTest.cs117
-rw-r--r--crypto/test/src/asn1/test/RestrictionUnitTest.cs78
-rw-r--r--crypto/test/src/asn1/test/SMIMETest.cs90
-rw-r--r--crypto/test/src/asn1/test/SemanticsInformationUnitTest.cs138
-rw-r--r--crypto/test/src/asn1/test/SetTest.cs117
-rw-r--r--crypto/test/src/asn1/test/SignerLocationUnitTest.cs195
-rw-r--r--crypto/test/src/asn1/test/StringTest.cs105
-rw-r--r--crypto/test/src/asn1/test/SubjectKeyIdentifierTest.cs61
-rw-r--r--crypto/test/src/asn1/test/TagTest.cs115
-rw-r--r--crypto/test/src/asn1/test/TargetInformationTest.cs58
-rw-r--r--crypto/test/src/asn1/test/TimeTest.cs28
-rw-r--r--crypto/test/src/asn1/test/TypeOfBiometricDataUnitTest.cs152
-rw-r--r--crypto/test/src/asn1/test/UTCTimeTest.cs122
-rw-r--r--crypto/test/src/asn1/test/X509ExtensionsTest.cs117
-rw-r--r--crypto/test/src/asn1/test/X509NameTest.cs674
-rw-r--r--crypto/test/src/asn1/test/X9Test.cs181
70 files changed, 9258 insertions, 0 deletions
diff --git a/crypto/test/src/asn1/test/ASN1SequenceParserTest.cs b/crypto/test/src/asn1/test/ASN1SequenceParserTest.cs
new file mode 100644
index 000000000..030da04cb
--- /dev/null
+++ b/crypto/test/src/asn1/test/ASN1SequenceParserTest.cs
@@ -0,0 +1,359 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+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 Asn1SequenceParserTest
+    {
+        private static readonly byte[] seqData = Hex.Decode("3006020100060129");
+        private static readonly byte[] nestedSeqData = Hex.Decode("300b0201000601293003020101");
+        private static readonly byte[] expTagSeqData = Hex.Decode("a1083006020100060129");
+        private static readonly byte[] implTagSeqData = Hex.Decode("a106020100060129");
+        private static readonly byte[] nestedSeqExpTagData = Hex.Decode("300d020100060129a1053003020101");
+        private static readonly byte[] nestedSeqImpTagData = Hex.Decode("300b020100060129a103020101");
+
+		private static readonly byte[] berSeqData = Hex.Decode("30800201000601290000");
+        private static readonly byte[] berDerNestedSeqData = Hex.Decode("308002010006012930030201010000");
+        private static readonly byte[] berNestedSeqData = Hex.Decode("3080020100060129308002010100000000");
+        private static readonly byte[] berExpTagSeqData = Hex.Decode("a180308002010006012900000000");
+		private static readonly byte[] berSeqWithDERNullData = Hex.Decode("308005000201000601290000");
+
+		[Test]
+		public void TestDerWriting()
+        {
+            MemoryStream bOut = new MemoryStream();
+            DerSequenceGenerator seqGen = new DerSequenceGenerator(bOut);
+
+			seqGen.AddObject(new DerInteger(BigInteger.Zero));
+
+			seqGen.AddObject(new DerObjectIdentifier("1.1"));
+
+			seqGen.Close();
+
+			Assert.IsTrue(Arrays.AreEqual(seqData, bOut.ToArray()), "basic DER writing test failed.");
+        }
+
+		[Test]
+		public void TestNestedDerWriting()
+        {
+            MemoryStream bOut = new MemoryStream();
+            DerSequenceGenerator seqGen1 = new DerSequenceGenerator(bOut);
+
+			seqGen1.AddObject(new DerInteger(BigInteger.Zero));
+
+			seqGen1.AddObject(new DerObjectIdentifier("1.1"));
+
+			DerSequenceGenerator seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream());
+
+			seqGen2.AddObject(new DerInteger(BigInteger.One));
+
+			seqGen2.Close();
+
+			seqGen1.Close();
+
+			Assert.IsTrue(Arrays.AreEqual(nestedSeqData, bOut.ToArray()), "nested DER writing test failed.");
+        }
+
+		[Test]
+		public void TestDerExplicitTaggedSequenceWriting()
+        {
+            MemoryStream bOut = new MemoryStream();
+            DerSequenceGenerator seqGen = new DerSequenceGenerator(bOut, 1, true);
+
+            seqGen.AddObject(new DerInteger(BigInteger.Zero));
+
+            seqGen.AddObject(new DerObjectIdentifier("1.1"));
+
+            seqGen.Close();
+
+            Assert.IsTrue(Arrays.AreEqual(expTagSeqData, bOut.ToArray()), "explicit tag writing test failed.");
+        }
+
+		[Test]
+		public void TestDerImplicitTaggedSequenceWriting()
+        {
+            MemoryStream bOut = new MemoryStream();
+            DerSequenceGenerator seqGen = new DerSequenceGenerator(bOut, 1, false);
+
+			seqGen.AddObject(new DerInteger(BigInteger.Zero));
+
+			seqGen.AddObject(new DerObjectIdentifier("1.1"));
+
+			seqGen.Close();
+
+			Assert.IsTrue(Arrays.AreEqual(implTagSeqData, bOut.ToArray()), "implicit tag writing test failed.");
+        }
+
+		[Test]
+		public void TestNestedExplicitTagDerWriting()
+        {
+            MemoryStream bOut = new MemoryStream();
+            DerSequenceGenerator  seqGen1 = new DerSequenceGenerator(bOut);
+
+            seqGen1.AddObject(new DerInteger(BigInteger.Zero));
+
+            seqGen1.AddObject(new DerObjectIdentifier("1.1"));
+
+            DerSequenceGenerator seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream(), 1, true);
+
+            seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1)));
+
+            seqGen2.Close();
+
+            seqGen1.Close();
+
+            Assert.IsTrue(Arrays.AreEqual(nestedSeqExpTagData, bOut.ToArray()), "nested explicit tagged DER writing test failed.");
+        }
+
+		[Test]
+		public void TestNestedImplicitTagDerWriting()
+        {
+            MemoryStream bOut = new MemoryStream();
+            DerSequenceGenerator seqGen1 = new DerSequenceGenerator(bOut);
+
+			seqGen1.AddObject(new DerInteger(BigInteger.Zero));
+
+			seqGen1.AddObject(new DerObjectIdentifier("1.1"));
+
+			DerSequenceGenerator seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream(), 1, false);
+
+			seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1)));
+
+			seqGen2.Close();
+
+			seqGen1.Close();
+
+			Assert.IsTrue(Arrays.AreEqual(nestedSeqImpTagData, bOut.ToArray()), "nested implicit tagged DER writing test failed.");
+        }
+
+		[Test]
+		public void TestBerWriting()
+        {
+            MemoryStream bOut = new MemoryStream();
+            BerSequenceGenerator seqGen = new BerSequenceGenerator(bOut);
+
+			seqGen.AddObject(new DerInteger(BigInteger.Zero));
+
+			seqGen.AddObject(new DerObjectIdentifier("1.1"));
+
+			seqGen.Close();
+
+			Assert.IsTrue(Arrays.AreEqual(berSeqData, bOut.ToArray()), "basic BER writing test failed.");
+        }
+
+		[Test]
+		public void TestNestedBerDerWriting()
+        {
+            MemoryStream bOut = new MemoryStream();
+            BerSequenceGenerator seqGen1 = new BerSequenceGenerator(bOut);
+
+			seqGen1.AddObject(new DerInteger(BigInteger.Zero));
+
+			seqGen1.AddObject(new DerObjectIdentifier("1.1"));
+
+			DerSequenceGenerator seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream());
+
+			seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1)));
+
+			seqGen2.Close();
+
+			seqGen1.Close();
+
+			Assert.IsTrue(Arrays.AreEqual(berDerNestedSeqData, bOut.ToArray()), "nested BER/DER writing test failed.");
+        }
+
+		[Test]
+		public void TestNestedBerWriting()
+        {
+            MemoryStream bOut = new MemoryStream();
+            BerSequenceGenerator seqGen1 = new BerSequenceGenerator(bOut);
+
+			seqGen1.AddObject(new DerInteger(BigInteger.Zero));
+
+			seqGen1.AddObject(new DerObjectIdentifier("1.1"));
+
+			BerSequenceGenerator seqGen2 = new BerSequenceGenerator(seqGen1.GetRawOutputStream());
+
+			seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1)));
+
+			seqGen2.Close();
+
+			seqGen1.Close();
+
+			Assert.IsTrue(Arrays.AreEqual(berNestedSeqData, bOut.ToArray()), "nested BER writing test failed.");
+        }
+
+		[Test]
+		public void TestDerReading()
+        {
+            Asn1StreamParser aIn = new Asn1StreamParser(seqData);
+
+			Asn1SequenceParser seq = (Asn1SequenceParser)aIn.ReadObject();
+            int count = 0;
+
+			Assert.IsNotNull(seq, "null sequence returned");
+
+			object o;
+			while ((o = seq.ReadObject()) != null)
+            {
+                switch (count)
+                {
+                    case 0:
+                        Assert.IsTrue(o is DerInteger);
+                        break;
+                    case 1:
+                        Assert.IsTrue(o is DerObjectIdentifier);
+                        break;
+                }
+                count++;
+            }
+
+			Assert.AreEqual(2, count, "wrong number of objects in sequence");
+        }
+
+		private void doTestNestedReading(
+            byte[] data)
+        {
+            Asn1StreamParser aIn = new Asn1StreamParser(data);
+
+			Asn1SequenceParser seq = (Asn1SequenceParser) aIn.ReadObject();
+            object o = null;
+            int count = 0;
+
+			Assert.IsNotNull(seq, "null sequence returned");
+
+			while ((o = seq.ReadObject()) != null)
+            {
+                switch (count)
+                {
+                    case 0:
+                        Assert.IsTrue(o is DerInteger);
+                        break;
+                    case 1:
+                        Assert.IsTrue(o is DerObjectIdentifier);
+                        break;
+                    case 2:
+                        Assert.IsTrue(o is Asn1SequenceParser);
+
+						Asn1SequenceParser s = (Asn1SequenceParser)o;
+
+						// NB: Must exhaust the nested parser
+						while (s.ReadObject() != null)
+						{
+							// Ignore
+						}
+
+						break;
+                }
+                count++;
+            }
+
+			Assert.AreEqual(3, count, "wrong number of objects in sequence");
+        }
+
+		[Test]
+		public void TestNestedDerReading()
+        {
+            doTestNestedReading(nestedSeqData);
+        }
+
+		[Test]
+		public void TestBerReading()
+        {
+            Asn1StreamParser aIn = new Asn1StreamParser(berSeqData);
+
+			Asn1SequenceParser seq = (Asn1SequenceParser) aIn.ReadObject();
+            object o = null;
+            int count = 0;
+
+			Assert.IsNotNull(seq, "null sequence returned");
+
+			while ((o = seq.ReadObject()) != null)
+            {
+                switch (count)
+                {
+                    case 0:
+                        Assert.IsTrue(o is DerInteger);
+                        break;
+                    case 1:
+                        Assert.IsTrue(o is DerObjectIdentifier);
+                        break;
+                }
+                count++;
+            }
+
+			Assert.AreEqual(2, count, "wrong number of objects in sequence");
+        }
+
+		[Test]
+		public void TestNestedBerDerReading()
+        {
+            doTestNestedReading(berDerNestedSeqData);
+        }
+
+		[Test]
+		public void TestNestedBerReading()
+        {
+            doTestNestedReading(berNestedSeqData);
+        }
+
+		[Test]
+		public void TestBerExplicitTaggedSequenceWriting()
+        {
+            MemoryStream bOut = new MemoryStream();
+            BerSequenceGenerator seqGen = new BerSequenceGenerator(bOut, 1, true);
+
+			seqGen.AddObject(new DerInteger(BigInteger.Zero));
+
+			seqGen.AddObject(new DerObjectIdentifier("1.1"));
+
+			seqGen.Close();
+
+			Assert.IsTrue(Arrays.AreEqual(berExpTagSeqData, bOut.ToArray()), "explicit BER tag writing test failed.");
+        }
+
+		[Test]
+		public void TestSequenceWithDerNullReading()
+		{
+			doTestParseWithNull(berSeqWithDERNullData);
+		}
+
+		private void doTestParseWithNull(
+			byte[] data)
+		{
+			Asn1StreamParser aIn = new Asn1StreamParser(data);
+			Asn1SequenceParser seq = (Asn1SequenceParser) aIn.ReadObject();
+			object o;
+			int count = 0;
+
+			Assert.IsNotNull(seq, "null sequence returned");
+
+			while ((o = seq.ReadObject()) != null)
+			{
+				switch (count)
+				{
+					case 0:
+						Assert.IsTrue(o is Asn1Null);
+						break;
+					case 1:
+						Assert.IsTrue(o is DerInteger);
+						break;
+					case 2:
+						Assert.IsTrue(o is DerObjectIdentifier);
+						break;
+				}
+				count++;
+			}
+
+			Assert.AreEqual(3, count, "wrong number of objects in sequence");
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/ASN1UnitTest.cs b/crypto/test/src/asn1/test/ASN1UnitTest.cs
new file mode 100644
index 000000000..88492bede
--- /dev/null
+++ b/crypto/test/src/asn1/test/ASN1UnitTest.cs
@@ -0,0 +1,88 @@
+using System;
+
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	public abstract class Asn1UnitTest
+		: SimpleTest
+	{
+		protected void checkMandatoryField(string name, Asn1Encodable expected, Asn1Encodable present)
+		{
+			if (!expected.Equals(present))
+			{
+				Fail(name + " field doesn't match.");
+			}
+		}
+
+		protected void checkMandatoryField(string name, string expected, string present)
+		{
+			if (!expected.Equals(present))
+			{
+				Fail(name + " field doesn't match.");
+			}
+		}
+
+		protected void checkMandatoryField(string name, byte[] expected, byte[] present)
+		{
+			if (!AreEqual(expected, present))
+			{
+				Fail(name + " field doesn't match.");
+			}
+		}
+
+		protected void checkMandatoryField(string name, int expected, int present)
+		{
+			if (expected != present)
+			{
+				Fail(name + " field doesn't match.");
+			}
+		}
+
+		protected void checkOptionalField(string name, Asn1Encodable expected, Asn1Encodable present)
+		{
+			if (expected != null)
+			{
+				if (!expected.Equals(present))
+				{
+					Fail(name + " field doesn't match.");
+				}
+			}
+			else if (present != null)
+			{
+				Fail(name + " field found when none expected.");
+			}
+		}
+
+		protected void checkOptionalField(string name, string expected, string present)
+		{
+			if (expected != null)
+			{
+				if (!expected.Equals(present))
+				{
+					Fail(name + " field doesn't match.");
+				}
+			}
+			else if (present != null)
+			{
+				Fail(name + " field found when none expected.");
+			}
+		}
+
+		protected void checkOptionalField(string name, BigInteger expected, BigInteger present)
+		{
+			if (expected != null)
+			{
+				if (!expected.Equals(present))
+				{
+					Fail(name + " field doesn't match.");
+				}
+			}
+			else if (present != null)
+			{
+				Fail(name + " field found when none expected.");
+			}
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/AdditionalInformationSyntaxUnitTest.cs b/crypto/test/src/asn1/test/AdditionalInformationSyntaxUnitTest.cs
new file mode 100644
index 000000000..ac4ff9809
--- /dev/null
+++ b/crypto/test/src/asn1/test/AdditionalInformationSyntaxUnitTest.cs
@@ -0,0 +1,77 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.IsisMtt.X509;
+using Org.BouncyCastle.Asn1.X500;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class AdditionalInformationSyntaxUnitTest
+		: Asn1UnitTest
+	{
+		public override string Name
+		{
+			get { return "AdditionalInformationSyntax"; }
+		}
+
+		public override void PerformTest()
+		{
+			AdditionalInformationSyntax syntax = new AdditionalInformationSyntax("hello world");
+
+			checkConstruction(syntax, new DirectoryString("hello world"));
+
+			try
+			{
+				AdditionalInformationSyntax.GetInstance(new Object());
+
+				Fail("GetInstance() failed to detect bad object.");
+			}
+			catch (ArgumentException)
+			{
+				// expected
+			}
+		}
+
+		private void checkConstruction(
+			AdditionalInformationSyntax syntax,
+			DirectoryString information)
+		{
+			checkValues(syntax, information);
+
+			syntax = AdditionalInformationSyntax.GetInstance(syntax);
+
+			checkValues(syntax, information);
+
+			Asn1InputStream aIn = new Asn1InputStream(syntax.ToAsn1Object().GetEncoded());
+
+			IAsn1String info = (IAsn1String) aIn.ReadObject();
+
+			syntax = AdditionalInformationSyntax.GetInstance(info);
+
+			checkValues(syntax, information);
+		}
+
+		private void checkValues(
+			AdditionalInformationSyntax syntax,
+			DirectoryString information)
+		{
+			checkMandatoryField("information", information, syntax.Information);
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new AdditionalInformationSyntaxUnitTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/AdmissionSyntaxUnitTest.cs b/crypto/test/src/asn1/test/AdmissionSyntaxUnitTest.cs
new file mode 100644
index 000000000..59464d212
--- /dev/null
+++ b/crypto/test/src/asn1/test/AdmissionSyntaxUnitTest.cs
@@ -0,0 +1,99 @@
+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 AdmissionSyntaxUnitTest
+		: Asn1UnitTest
+	{
+		public override string Name
+		{
+			get { return "AdmissionSyntax"; }
+		}
+
+		public override void PerformTest()
+		{
+			GeneralName name = new GeneralName(new X509Name("CN=hello world"));
+			Asn1Sequence admissions = new DerSequence(
+				new Admissions(name,
+				new NamingAuthority(new DerObjectIdentifier("1.2.3"), "url", new DirectoryString("fred")),
+				new ProfessionInfo[0]));
+			AdmissionSyntax syntax = new AdmissionSyntax(name, admissions);
+
+			checkConstruction(syntax, name, admissions);
+
+			syntax = AdmissionSyntax.GetInstance(null);
+
+			if (syntax != null)
+			{
+				Fail("null GetInstance() failed.");
+			}
+
+			try
+			{
+				AdmissionSyntax.GetInstance(new Object());
+
+				Fail("GetInstance() failed to detect bad object.");
+			}
+			catch (ArgumentException)
+			{
+				// expected
+			}
+		}
+
+		private void checkConstruction(
+			AdmissionSyntax	syntax,
+			GeneralName		authority,
+			Asn1Sequence	admissions)
+		{
+			checkValues(syntax, authority, admissions);
+
+			syntax = AdmissionSyntax.GetInstance(syntax);
+
+			checkValues(syntax, authority, admissions);
+
+			Asn1InputStream aIn = new Asn1InputStream(syntax.ToAsn1Object().GetEncoded());
+
+			Asn1Sequence info = (Asn1Sequence) aIn.ReadObject();
+
+			syntax = AdmissionSyntax.GetInstance(info);
+
+			checkValues(syntax, authority, admissions);
+		}
+
+		private void checkValues(
+			AdmissionSyntax syntax,
+			GeneralName     authority,
+			Asn1Sequence    admissions)
+		{
+			checkMandatoryField("admissionAuthority", authority, syntax.AdmissionAuthority);
+
+			Admissions[] adm = syntax.GetContentsOfAdmissions();
+
+			if (adm.Length != 1 || !adm[0].Equals(admissions[0]))
+			{
+				Fail("admissions check failed");
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new AdmissionSyntaxUnitTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/AdmissionsUnitTest.cs b/crypto/test/src/asn1/test/AdmissionsUnitTest.cs
new file mode 100644
index 000000000..edefeb830
--- /dev/null
+++ b/crypto/test/src/asn1/test/AdmissionsUnitTest.cs
@@ -0,0 +1,90 @@
+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 AdmissionsUnitTest
+		: Asn1UnitTest
+	{
+		public override string Name
+		{
+			get { return "Admissions"; }
+		}
+
+		public override void PerformTest()
+		{
+			GeneralName name = new GeneralName(new X509Name("CN=hello world"));
+			NamingAuthority auth = new NamingAuthority(new DerObjectIdentifier("1.2.3"), "url", new DirectoryString("fred"));
+			Admissions admissions = new Admissions(name, auth, new ProfessionInfo[0]);
+
+			checkConstruction(admissions, name, auth);
+
+			admissions = Admissions.GetInstance(null);
+
+			if (admissions != null)
+			{
+				Fail("null GetInstance() failed.");
+			}
+
+			try
+			{
+				Admissions.GetInstance(new Object());
+
+				Fail("GetInstance() failed to detect bad object.");
+			}
+			catch (ArgumentException)
+			{
+				// expected
+			}
+		}
+
+		private void checkConstruction(
+			Admissions      admissions,
+			GeneralName     name,
+			NamingAuthority auth)
+		{
+			checkValues(admissions, name, auth);
+
+			admissions = Admissions.GetInstance(admissions);
+
+			checkValues(admissions, name, auth);
+
+			Asn1InputStream aIn = new Asn1InputStream(admissions.ToAsn1Object().GetEncoded());
+
+			Asn1Sequence info = (Asn1Sequence)aIn.ReadObject();
+
+			admissions = Admissions.GetInstance(info);
+
+			checkValues(admissions, name, auth);
+		}
+
+		private void checkValues(
+			Admissions		admissions,
+			GeneralName		name,
+			NamingAuthority	auth)
+		{
+			checkMandatoryField("admissionAuthority", name, admissions.AdmissionAuthority);
+			checkMandatoryField("namingAuthority", auth, admissions.NamingAuthority);
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new AdmissionsUnitTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/AllTests.cs b/crypto/test/src/asn1/test/AllTests.cs
new file mode 100644
index 000000000..a1ae8fd48
--- /dev/null
+++ b/crypto/test/src/asn1/test/AllTests.cs
@@ -0,0 +1,32 @@
+using System;
+
+using NUnit.Core;
+using NUnit.Framework;
+
+namespace Org.BouncyCastle.Asn1.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("ASN.1 tests");
+
+			suite.Add(new AllTests());
+
+			// TODO Add these tests to RegressionTest list
+			suite.Add(new Asn1SequenceParserTest());
+			suite.Add(new OctetStringTest());
+			suite.Add(new ParseTest());
+			suite.Add(new TimeTest());
+
+			return suite;
+        }
+    }
+}
diff --git a/crypto/test/src/asn1/test/AttributeTableUnitTest.cs b/crypto/test/src/asn1/test/AttributeTableUnitTest.cs
new file mode 100644
index 000000000..5dcf349cc
--- /dev/null
+++ b/crypto/test/src/asn1/test/AttributeTableUnitTest.cs
@@ -0,0 +1,151 @@
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Asn1Cms = Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+    [TestFixture]
+    public class AttributeTableUnitTest
+        : SimpleTest
+    {
+        private static readonly DerObjectIdentifier type1 = new DerObjectIdentifier("1.1.1");
+        private static readonly DerObjectIdentifier type2 = new DerObjectIdentifier("1.1.2");
+        private static readonly DerObjectIdentifier type3 = new DerObjectIdentifier("1.1.3");
+
+		public override string Name
+		{
+			get { return "AttributeTable"; }
+		}
+
+		public override void PerformTest()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(
+				new Asn1Cms.Attribute(type1, new DerSet(type1)),
+				new Asn1Cms.Attribute(type2, new DerSet(type2)));
+
+			Asn1Cms.AttributeTable table = new Asn1Cms.AttributeTable(v);
+
+			Asn1Cms.Attribute a = table[type1];
+            if (a == null)
+            {
+                Fail("type1 attribute not found.");
+            }
+            if (!a.AttrValues.Equals(new DerSet(type1)))
+            {
+                Fail("wrong value retrieved for type1!");
+            }
+
+			a = table[type2];
+            if (a == null)
+            {
+                Fail("type2 attribute not found.");
+            }
+            if (!a.AttrValues.Equals(new DerSet(type2)))
+            {
+                Fail("wrong value retrieved for type2!");
+            }
+
+			a = table[type3];
+            if (a != null)
+            {
+                Fail("type3 attribute found when none expected.");
+            }
+
+			Asn1EncodableVector vec = table.GetAll(type1);
+            if (vec.Count != 1)
+            {
+                Fail("wrong vector size for type1.");
+            }
+
+			vec = table.GetAll(type3);
+            if (vec.Count != 0)
+            {
+                Fail("wrong vector size for type3.");
+            }
+
+			vec = table.ToAsn1EncodableVector();
+            if (vec.Count != 2)
+            {
+                Fail("wrong vector size for single.");
+            }
+
+            IDictionary t = table.ToDictionary();
+
+			if (t.Count != 2)
+            {
+                Fail("hashtable wrong size.");
+            }
+
+            // multiple
+
+			v = new Asn1EncodableVector(
+				new Asn1Cms.Attribute(type1, new DerSet(type1)),
+				new Asn1Cms.Attribute(type1, new DerSet(type2)),
+				new Asn1Cms.Attribute(type1, new DerSet(type3)),
+				new Asn1Cms.Attribute(type2, new DerSet(type2)));
+
+			table = new Asn1Cms.AttributeTable(v);
+
+			a = table[type1];
+            if (!a.AttrValues.Equals(new DerSet(type1)))
+            {
+                Fail("wrong value retrieved for type1 multi Get!");
+            }
+
+			vec = table.GetAll(type1);
+            if (vec.Count != 3)
+            {
+                Fail("wrong vector size for multiple type1.");
+            }
+
+			a = (Asn1Cms.Attribute)vec[0];
+            if (!a.AttrValues.Equals(new DerSet(type1)))
+            {
+                Fail("wrong value retrieved for type1(0)!");
+            }
+
+            a = (Asn1Cms.Attribute)vec[1];
+            if (!a.AttrValues.Equals(new DerSet(type2)))
+            {
+                Fail("wrong value retrieved for type1(1)!");
+            }
+
+            a = (Asn1Cms.Attribute)vec[2];
+            if (!a.AttrValues.Equals(new DerSet(type3)))
+            {
+                Fail("wrong value retrieved for type1(2)!");
+            }
+
+            vec = table.GetAll(type2);
+            if (vec.Count != 1)
+            {
+                Fail("wrong vector size for multiple type2.");
+            }
+
+            vec = table.ToAsn1EncodableVector();
+            if (vec.Count != 4)
+            {
+                Fail("wrong vector size for multiple.");
+            }
+        }
+
+        public static void Main(
+            string[] args)
+        {
+            RunTest(new AttributeTableUnitTest());
+        }
+
+        [Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/asn1/test/BiometricDataUnitTest.cs b/crypto/test/src/asn1/test/BiometricDataUnitTest.cs
new file mode 100644
index 000000000..a542f71af
--- /dev/null
+++ b/crypto/test/src/asn1/test/BiometricDataUnitTest.cs
@@ -0,0 +1,133 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Asn1.X509.Qualified;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+    [TestFixture]
+    public class BiometricDataUnitTest
+        : SimpleTest
+    {
+        public override string Name
+        {
+			get { return "BiometricData"; }
+        }
+
+		private byte[] GenerateHash()
+        {
+            Random rand = new Random();
+            byte[] bytes = new byte[20];
+            rand.NextBytes(bytes);
+            return bytes;
+        }
+
+		public override void PerformTest()
+        {
+            TypeOfBiometricData dataType = new TypeOfBiometricData(TypeOfBiometricData.HandwrittenSignature);
+            AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
+            Asn1OctetString     dataHash = new DerOctetString(GenerateHash());
+            BiometricData       bd = new BiometricData(dataType, hashAlgorithm, dataHash);
+
+            CheckConstruction(bd, dataType, hashAlgorithm, dataHash, null);
+
+            DerIA5String dataUri = new DerIA5String("http://test");
+
+            bd = new BiometricData(dataType, hashAlgorithm, dataHash, dataUri);
+
+            CheckConstruction(bd, dataType, hashAlgorithm, dataHash, dataUri);
+
+            bd = BiometricData.GetInstance(null);
+
+            if (bd != null)
+            {
+                Fail("null GetInstance() failed.");
+            }
+
+            try
+            {
+                BiometricData.GetInstance(new object());
+
+                Fail("GetInstance() failed to detect bad object.");
+            }
+            catch (ArgumentException)
+            {
+                // expected
+            }
+        }
+
+        private void CheckConstruction(
+            BiometricData bd,
+            TypeOfBiometricData dataType,
+            AlgorithmIdentifier hashAlgorithm,
+            Asn1OctetString dataHash,
+            DerIA5String dataUri)
+        {
+            CheckValues(bd, dataType, hashAlgorithm, dataHash, dataUri);
+
+            bd = BiometricData.GetInstance(bd);
+
+            CheckValues(bd, dataType, hashAlgorithm, dataHash, dataUri);
+
+			Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(bd.ToAsn1Object().GetEncoded());
+
+			bd = BiometricData.GetInstance(seq);
+
+			CheckValues(bd, dataType, hashAlgorithm, dataHash, dataUri);
+        }
+
+        private void CheckValues(
+            BiometricData       bd,
+            TypeOfBiometricData dataType,
+            AlgorithmIdentifier algID,
+            Asn1OctetString     dataHash,
+            DerIA5String        sourceDataURI)
+        {
+            if (!bd.TypeOfBiometricData.Equals(dataType))
+            {
+                Fail("types don't match.");
+            }
+
+            if (!bd.HashAlgorithm.Equals(algID))
+            {
+                Fail("hash algorithms don't match.");
+            }
+
+            if (!bd.BiometricDataHash.Equals(dataHash))
+            {
+                Fail("hash algorithms don't match.");
+            }
+
+            if (sourceDataURI != null)
+            {
+                if (!bd.SourceDataUri.Equals(sourceDataURI))
+                {
+                    Fail("data uris don't match.");
+                }
+            }
+            else if (bd.SourceDataUri != null)
+            {
+                Fail("data uri found when none expected.");
+            }
+        }
+
+		public static void Main(
+            string[] args)
+        {
+            RunTest(new BiometricDataUnitTest());
+        }
+
+		[Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/asn1/test/BitStringConstantTester.cs b/crypto/test/src/asn1/test/BitStringConstantTester.cs
new file mode 100644
index 000000000..bb966d3e4
--- /dev/null
+++ b/crypto/test/src/asn1/test/BitStringConstantTester.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	public class BitStringConstantTester
+	{
+		private static readonly int[] bits =
+		{
+			1 << 7, 1 << 6, 1 << 5, 1 << 4, 1 << 3, 1 << 2, 1 << 1, 1 << 0,
+			1 << 15, 1 << 14, 1 << 13, 1 << 12, 1 << 11, 1 << 10, 1 << 9, 1 << 8,
+			1 << 23, 1 << 22, 1 << 21, 1 << 20, 1 << 19, 1 << 18, 1 << 17, 1 << 16,
+			1 << 31, 1 << 30, 1 << 29, 1 << 28, 1 << 27, 1 << 26, 1 << 25, 1 << 24
+		};
+
+		public static void testFlagValueCorrect(
+			int bitNo,
+			int value)
+		{
+			if (bits[bitNo] != value)
+			{
+				throw new ArgumentException("bit value " + bitNo + " wrong");
+			}
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/BitStringTest.cs b/crypto/test/src/asn1/test/BitStringTest.cs
new file mode 100644
index 000000000..3a2dc3156
--- /dev/null
+++ b/crypto/test/src/asn1/test/BitStringTest.cs
@@ -0,0 +1,82 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+    [TestFixture]
+    public class BitStringTest
+        : ITest
+    {
+        public ITestResult Perform()
+        {
+            KeyUsage k = new KeyUsage(KeyUsage.DigitalSignature);
+            if ((k.GetBytes()[0] != (byte)KeyUsage.DigitalSignature) || (k.PadBits != 7))
+            {
+                return new SimpleTestResult(false, Name + ": failed digitalSignature");
+            }
+
+            k = new KeyUsage(KeyUsage.NonRepudiation);
+            if ((k.GetBytes()[0] != (byte)KeyUsage.NonRepudiation) || (k.PadBits != 6))
+            {
+                return new SimpleTestResult(false, Name + ": failed nonRepudiation");
+            }
+
+            k = new KeyUsage(KeyUsage.KeyEncipherment);
+            if ((k.GetBytes()[0] != (byte)KeyUsage.KeyEncipherment) || (k.PadBits != 5))
+            {
+                return new SimpleTestResult(false, Name + ": failed keyEncipherment");
+            }
+
+            k = new KeyUsage(KeyUsage.CrlSign);
+            if ((k.GetBytes()[0] != (byte)KeyUsage.CrlSign)  || (k.PadBits != 1))
+            {
+                return new SimpleTestResult(false, Name + ": failed cRLSign");
+            }
+
+            k = new KeyUsage(KeyUsage.DecipherOnly);
+            if ((k.GetBytes()[1] != (byte)(KeyUsage.DecipherOnly >> 8))  || (k.PadBits != 7))
+            {
+                return new SimpleTestResult(false, Name + ": failed decipherOnly");
+            }
+
+			// test for zero length bit string
+			try
+			{
+				Asn1Object.FromByteArray(new DerBitString(new byte[0], 0).GetEncoded());
+			}
+			catch (IOException e)
+			{
+				return new SimpleTestResult(false, Name + ": " + e);
+			}
+
+            return new SimpleTestResult(true, Name + ": Okay");
+        }
+
+        public string Name
+        {
+			get { return "BitString"; }
+        }
+
+		public static void Main(
+            string[] args)
+        {
+            ITest test = new BitStringTest();
+            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/CMSTest.cs b/crypto/test/src/asn1/test/CMSTest.cs
new file mode 100644
index 000000000..1afb363af
--- /dev/null
+++ b/crypto/test/src/asn1/test/CMSTest.cs
@@ -0,0 +1,306 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class CmsTest
+		: ITest
+	{
+		//
+		// compressed data object
+		//
+		private static readonly byte[] compData = Base64.Decode(
+			"MIAGCyqGSIb3DQEJEAEJoIAwgAIBADANBgsqhkiG9w0BCRADCDCABgkqhkiG9w0BBwGggCSABIIC"
+			+ "Hnic7ZRdb9owFIbvK/k/5PqVYPFXGK12YYyboVFASSp1vQtZGiLRACZE49/XHoUW7S/0tXP8Efux"
+			+ "fU5ivWnasml72XFb3gb5druui7ytN803M570nii7C5r8tfwR281hy/p/KSM3+jzH5s3+pbQ90xSb"
+			+ "P3VT3QbLusnt8WPIuN5vN/vaA2+DulnXTXkXvNTr8j8ouZmkCmGI/UW+ZS/C8zP0bz2dz0zwLt+1"
+			+ "UEk2M8mlaxjRMByAhZTj0RGYg4TvogiRASROsZgjpVcJCb1KV6QzQeDJ1XkoQ5Jm+C5PbOHZZGRi"
+			+ "v+ORAcshOGeCcdFJyfgFxdtCdEcmOrbinc/+BBMzRThEYpwl+jEBpciSGWQkI0TSlREmD/eOHb2D"
+			+ "SGLuESm/iKUFt1y4XHBO2a5oq0IKJKWLS9kUZTA7vC5LSxYmgVL46SIWxIfWBQd6AdrnjLmH94UT"
+			+ "vGxVibLqRCtIpp4g2qpdtqK1LiOeolpVK5wVQ5P7+QjZAlrh0cePYTx/gNZuB9Vhndtgujl9T/tg"
+			+ "W9ogK+3rnmg3YWygnTuF5GDS+Q/jIVLnCcYZFc6Kk/+c80wKwZjwdZIqDYWRH68MuBQSXLgXYXj2"
+			+ "3CAaYOBNJMliTl0X7eV5DnoKIFSKYdj3cRpD/cK/JWTHJRe76MUXnfBW8m7Hd5zhQ4ri2NrVF/WL"
+			+ "+kV1/3AGSlJ32bFPd2BsQD8uSzIx6lObkjdz95c0AAAAAAAAAAAAAAAA");
+
+		//
+		// enveloped data
+		//
+		private static readonly byte[] envDataKeyTrns = Base64.Decode(
+			  "MIAGCSqGSIb3DQEHA6CAMIACAQAxgcQwgcECAQAwKjAlMRYwFAYDVQQKEw1Cb3Vu"
+			+ "Y3kgQ2FzdGxlMQswCQYDVQQGEwJBVQIBCjANBgkqhkiG9w0BAQEFAASBgC5vdGrB"
+			+ "itQSGwifLf3KwPILjaB4WEXgT/IIO1KDzrsbItCJsMA0Smq2y0zptxT0pSRL6JRg"
+			+ "NMxLk1ySnrIrvGiEPLMR1zjxlT8yQ6VLX+kEoK43ztd1aaLw0oBfrcXcLN7BEpZ1"
+			+ "TIdjlBfXIOx1S88WY1MiYqJJFc3LMwRUaTEDMIAGCSqGSIb3DQEHATAdBglghkgB"
+			+ "ZQMEARYEEAfxLMWeaBOTTZQwUq0Y5FuggAQgwOJhL04rjSZCBCSOv5i5XpFfGsOd"
+			+ "YSHSqwntGpFqCx4AAAAAAAAAAAAA");
+
+		private static readonly byte[] envDataKEK = Base64.Decode(
+			  "MIAGCSqGSIb3DQEHA6CAMIACAQIxUqJQAgEEMAcEBQECAwQFMBAGCyqGSIb3DQEJE"
+			+ "AMHAgE6BDC7G/HyUPilIrin2Yeajqmj795VoLWETRnZAAFcAiQdoQWyz+oCh6WY/H"
+			+ "jHHi+0y+cwgAYJKoZIhvcNAQcBMBQGCCqGSIb3DQMHBAiY3eDBBbF6naCABBiNdzJb"
+			+ "/v6+UZB3XXKipxFDUpz9GyjzB+gAAAAAAAAAAAAA");
+
+		private static readonly byte[] envDataNestedNDEF = Base64.Decode(
+			  "MIAGCSqGSIb3DQEHA6CAMIACAQAxge8wgewCAQAwgZUwgY8xKDAmBgNVBAoMH1RoZSBMZWdpb24g"
+			+ "b2YgdGhlIEJvdW5jeSBDYXN0bGUxLzAtBgkqhkiG9w0BCQEWIGZlZWRiYWNrLWNyeXB0b0Bib3Vu"
+			+ "Y3ljYXN0bGUub3JnMREwDwYDVQQIDAhWaWN0b3JpYTESMBAGA1UEBwwJTWVsYm91cm5lMQswCQYD"
+			+ "VQQGEwJBVQIBATANBgkqhkiG9w0BAQEFAARABIXMd8xiTyWDKO/LQfvdGYTPW3I9oSQWwtm4OIaN"
+			+ "VINpfY2lfwTvbmE6VXiLKeALC0dMBV8z7DEM9hE0HVmvLDCABgkqhkiG9w0BBwEwHQYJYIZIAWUD"
+			+ "BAECBBB32ko6WrVxDTqwUYEpV6IUoIAEggKgS6RowrhNlmWWI13zxD/lryxkZ5oWXPUfNiUxYX/P"
+			+ "r5iscW3s8VKJKUpJ4W5SNA7JGL4l/5LmSnJ4Qu/xzxcoH4r4vmt75EDE9p2Ob2Xi1NuSFAZubJFc"
+			+ "Zlnp4e05UHKikmoaz0PbiAi277sLQlK2FcVsntTYVT00y8+IwuuQu0ATVqkXC+VhfjV/sK6vQZnw"
+			+ "2rQKedZhLB7B4dUkmxCujb/UAq4lgSpLMXg2P6wMimTczXyQxRiZxPeI4ByCENjkafXbfcJft2eD"
+			+ "gv1DEDdYM5WrW9Z75b4lmJiOJ/xxDniHCvum7KGXzpK1d1mqTlpzPC2xoz08/MO4lRf5Mb0bYdq6"
+			+ "CjMaYqVwGsYryp/2ayX+d8H+JphEG+V9Eg8uPcDoibwhDI4KkoyGHstPw5bxcy7vVFt7LXUdNjJc"
+			+ "K1wxaUKEXDGKt9Vj93FnBTLMX0Pc9HpueV5o1ipX34dn/P3HZB9XK8ScbrE38B1VnIgylStnhVFO"
+			+ "Cj9s7qSVqI2L+xYHJRHsxaMumIRnmRuOqdXDfIo28EZAnFtQ/b9BziMGVvAW5+A8h8s2oazhSmK2"
+			+ "23ftV7uv98ScgE8fCd3PwT1kKJM83ThTYyBzokvMfPYCCvsonMV+kTWXhWcwjYTS4ukrpR452ZdW"
+			+ "l3aJqDnzobt5FK4T8OGciOj+1PxYFZyRmCuafm2Dx6o7Et2Tu/T5HYvhdY9jHyqtDl2PXH4CTnVi"
+			+ "gA1YOAArjPVmsZVwAM3Ml46uyXXhcsXwQ1X0Tv4D+PSa/id4UQ2cObOw8Cj1eW2GB8iJIZVqkZaU"
+			+ "XBexqgWYOIoxjqODSeoZKiBsTK3c+oOUBqBDueY1i55swE2o6dDt95FluX6iyr/q4w2wLt3upY1J"
+			+ "YL+TuvZxAKviuAczMS1bAAAAAAAAAAAAAA==");
+
+		//
+		// signed data
+		//
+		private static readonly byte[] signedData = Base64.Decode(
+			  "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"
+			+ "a+fEv4J8wQ8Xwvk0C8iMAAAAAAAA");
+
+		private static void Touch(object o)
+		{
+		}
+
+		private ITestResult CompressionTest()
+		{
+			try
+			{
+				ContentInfo info = ContentInfo.GetInstance(
+					Asn1Object.FromByteArray(compData));
+				CompressedData data = CompressedData.GetInstance(info.Content);
+
+				data = new CompressedData(data.CompressionAlgorithmIdentifier, data.EncapContentInfo);
+				info = new ContentInfo(CmsObjectIdentifiers.CompressedData, data);
+
+				if (!Arrays.AreEqual(info.GetEncoded(), compData))
+				{
+					return new SimpleTestResult(false, Name + ": CMS compression failed to re-encode");
+				}
+
+				return new SimpleTestResult(true, Name + ": Okay");
+			}
+			catch (Exception e)
+			{
+				return new SimpleTestResult(false, Name + ": CMS compression failed - " + e.ToString(), e);
+			}
+		}
+
+		private ITestResult EnvelopedTest()
+		{
+			try
+			{
+				// Key trans
+				ContentInfo info = ContentInfo.GetInstance(
+					Asn1Object.FromByteArray(envDataKeyTrns));
+				EnvelopedData envData = EnvelopedData.GetInstance(info.Content);
+				Asn1Set s = envData.RecipientInfos;
+
+				if (s.Count != 1)
+				{
+					return new SimpleTestResult(false, Name + ": CMS KeyTrans enveloped, wrong number of recipients");
+				}
+
+				RecipientInfo recip = RecipientInfo.GetInstance(s[0]);
+
+				if (recip.Info is KeyTransRecipientInfo)
+				{
+					KeyTransRecipientInfo inf = KeyTransRecipientInfo.GetInstance(recip.Info);
+
+					inf = new KeyTransRecipientInfo(inf.RecipientIdentifier, inf.KeyEncryptionAlgorithm, inf.EncryptedKey);
+
+					s = new DerSet(new RecipientInfo(inf));
+				}
+				else
+				{
+					return new SimpleTestResult(false, Name + ": CMS KeyTrans enveloped, wrong recipient type");
+				}
+
+				envData = new EnvelopedData(envData.OriginatorInfo, s, envData.EncryptedContentInfo, envData.UnprotectedAttrs);
+				info = new ContentInfo(CmsObjectIdentifiers.EnvelopedData, envData);
+
+				if (!Arrays.AreEqual(info.GetEncoded(), envDataKeyTrns))
+				{
+					return new SimpleTestResult(false, Name + ": CMS KeyTrans enveloped failed to re-encode");
+				}
+
+
+				// KEK
+				info = ContentInfo.GetInstance(
+					Asn1Object.FromByteArray(envDataKEK));
+				envData = EnvelopedData.GetInstance(info.Content);
+				s = envData.RecipientInfos;
+
+				if (s.Count != 1)
+				{
+					return new SimpleTestResult(false, Name + ": CMS KEK enveloped, wrong number of recipients");
+				}
+
+				recip = RecipientInfo.GetInstance(s[0]);
+
+				if (recip.Info is KekRecipientInfo)
+				{
+					KekRecipientInfo inf = KekRecipientInfo.GetInstance(recip.Info);
+
+					inf = new KekRecipientInfo(inf.KekID, inf.KeyEncryptionAlgorithm, inf.EncryptedKey);
+
+					s = new DerSet(new RecipientInfo(inf));
+				}
+				else
+				{
+					return new SimpleTestResult(false, Name + ": CMS KEK enveloped, wrong recipient type");
+				}
+
+				envData = new EnvelopedData(envData.OriginatorInfo, s, envData.EncryptedContentInfo, envData.UnprotectedAttrs);
+				info = new ContentInfo(CmsObjectIdentifiers.EnvelopedData, envData);
+
+				if (!Arrays.AreEqual(info.GetEncoded(), envDataKEK))
+				{
+					return new SimpleTestResult(false, Name + ": CMS KEK enveloped failed to re-encode");
+				}
+
+				// Nested NDEF problem
+				Asn1StreamParser asn1In = new Asn1StreamParser(new MemoryStream(envDataNestedNDEF, false));
+				ContentInfoParser ci = new ContentInfoParser((Asn1SequenceParser)asn1In.ReadObject());
+				EnvelopedDataParser ed = new EnvelopedDataParser((Asn1SequenceParser)ci
+					.GetContent(Asn1Tags.Sequence));
+				Touch(ed.Version);
+				ed.GetOriginatorInfo();
+				ed.GetRecipientInfos().ToAsn1Object();
+				EncryptedContentInfoParser eci = ed.GetEncryptedContentInfo();
+				Touch(eci.ContentType);
+				Touch(eci.ContentEncryptionAlgorithm);
+
+				Stream dataIn = ((Asn1OctetStringParser)eci.GetEncryptedContent(Asn1Tags.OctetString))
+					.GetOctetStream();
+				Streams.Drain(dataIn);
+				dataIn.Close();
+
+				// Test data doesn't have unprotected attrs, bug was being thrown by this call
+				Asn1SetParser upa = ed.GetUnprotectedAttrs();
+				if (upa != null)
+				{
+					upa.ToAsn1Object();
+				}
+
+				return new SimpleTestResult(true, Name + ": Okay");
+			}
+			catch (Exception e)
+			{
+				return new SimpleTestResult(false, Name + ": CMS enveloped failed - " + e.ToString(), e);
+			}
+		}
+
+		private ITestResult SignedTest()
+		{
+			try
+			{
+				ContentInfo info = ContentInfo.GetInstance(
+					Asn1Object.FromByteArray(signedData));
+				SignedData sData = SignedData.GetInstance(info.Content);
+
+				sData = new SignedData(sData.DigestAlgorithms, sData.EncapContentInfo, sData.Certificates, sData.CRLs, sData.SignerInfos);
+				info = new ContentInfo(CmsObjectIdentifiers.SignedData, sData);
+
+				if (!Arrays.AreEqual(info.GetEncoded(), signedData))
+				{
+					return new SimpleTestResult(false, Name + ": CMS signed failed to re-encode");
+				}
+
+				return new SimpleTestResult(true, Name + ": Okay");
+			}
+			catch (Exception e)
+			{
+				return new SimpleTestResult(false, Name + ": CMS signed failed - " + e.ToString(), e);
+			}
+		}
+
+		public ITestResult Perform()
+		{
+			ITestResult res = CompressionTest();
+
+			if (!res.IsSuccessful())
+			{
+				return res;
+			}
+
+			res = EnvelopedTest();
+			if (!res.IsSuccessful())
+			{
+				return res;
+			}
+
+			return SignedTest();
+		}
+
+		public string Name
+		{
+			get { return "CMS"; }
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			ITest test = new CmsTest();
+			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/CertHashUnitTest.cs b/crypto/test/src/asn1/test/CertHashUnitTest.cs
new file mode 100644
index 000000000..1e271a9c0
--- /dev/null
+++ b/crypto/test/src/asn1/test/CertHashUnitTest.cs
@@ -0,0 +1,93 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.IsisMtt.Ocsp;
+using Org.BouncyCastle.Asn1.IsisMtt.X509;
+using Org.BouncyCastle.Asn1.X500;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class CertHashUnitTest
+		: Asn1UnitTest
+	{
+		public override string Name
+		{
+			get { return "CertHash"; }
+		}
+
+		public override void PerformTest()
+		{
+			AlgorithmIdentifier algId = new AlgorithmIdentifier(new DerObjectIdentifier("1.2.2.3"));
+			byte[] digest = new byte[20];
+
+			CertHash certID = new CertHash(algId, digest);
+
+			checkConstruction(certID, algId, digest);
+
+			certID = CertHash.GetInstance(null);
+
+			if (certID != null)
+			{
+				Fail("null GetInstance() failed.");
+			}
+
+			try
+			{
+				CertHash.GetInstance(new Object());
+
+				Fail("GetInstance() failed to detect bad object.");
+			}
+			catch (ArgumentException)
+			{
+				// expected
+			}
+		}
+
+		private void checkConstruction(
+			CertHash			certHash,
+			AlgorithmIdentifier	algId,
+			byte[]				digest)
+		{
+			checkValues(certHash, algId, digest);
+
+			certHash = CertHash.GetInstance(certHash);
+
+			checkValues(certHash, algId, digest);
+
+			Asn1InputStream aIn = new Asn1InputStream(certHash.ToAsn1Object().GetEncoded());
+
+			Asn1Sequence seq = (Asn1Sequence) aIn.ReadObject();
+
+			certHash = CertHash.GetInstance(seq);
+
+			checkValues(certHash, algId, digest);
+		}
+
+		private void checkValues(
+			CertHash certHash,
+			AlgorithmIdentifier algId,
+			byte[] digest)
+		{
+			checkMandatoryField("algorithmHash", algId, certHash.HashAlgorithm);
+
+			checkMandatoryField("certificateHash", digest, certHash.CertificateHash);
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new CertHashUnitTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/CertificateTest.cs b/crypto/test/src/asn1/test/CertificateTest.cs
new file mode 100644
index 000000000..532e81aba
--- /dev/null
+++ b/crypto/test/src/asn1/test/CertificateTest.cs
@@ -0,0 +1,395 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Utilities;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class CertificateTest
+		: SimpleTest
+	{
+		//
+		// server.crt
+		//
+		private static readonly byte[] cert1 = Base64.Decode(
+			"MIIDXjCCAsegAwIBAgIBBzANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx"
+			+ "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY"
+			+ "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB"
+			+ "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ"
+			+ "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU2MjFaFw0wMTA2"
+			+ "MDIwNzU2MjFaMIG4MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW"
+			+ "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM"
+			+ "dGQxFzAVBgNVBAsTDldlYnNlcnZlciBUZWFtMR0wGwYDVQQDExR3d3cyLmNvbm5l"
+			+ "Y3Q0LmNvbS5hdTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQGNvbm5lY3Q0LmNv"
+			+ "bS5hdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArvDxclKAhyv7Q/Wmr2re"
+			+ "Gw4XL9Cnh9e+6VgWy2AWNy/MVeXdlxzd7QAuc1eOWQkGQEiLPy5XQtTY+sBUJ3AO"
+			+ "Rvd2fEVJIcjf29ey7bYua9J/vz5MG2KYo9/WCHIwqD9mmG9g0xLcfwq/s8ZJBswE"
+			+ "7sb85VU+h94PTvsWOsWuKaECAwEAAaN3MHUwJAYDVR0RBB0wG4EZd2VibWFzdGVy"
+			+ "QGNvbm5lY3Q0LmNvbS5hdTA6BglghkgBhvhCAQ0ELRYrbW9kX3NzbCBnZW5lcmF0"
+			+ "ZWQgY3VzdG9tIHNlcnZlciBjZXJ0aWZpY2F0ZTARBglghkgBhvhCAQEEBAMCBkAw"
+			+ "DQYJKoZIhvcNAQEEBQADgYEAotccfKpwSsIxM1Hae8DR7M/Rw8dg/RqOWx45HNVL"
+			+ "iBS4/3N/TO195yeQKbfmzbAA2jbPVvIvGgTxPgO1MP4ZgvgRhasaa0qCJCkWvpM4"
+			+ "yQf33vOiYQbpv4rTwzU8AmRlBG45WdjyNIigGV+oRc61aKCTnLq7zB8N3z1TF/bF"
+			+ "5/8=");
+
+		//
+		// ca.crt
+		//
+		private static readonly byte[] cert2 = Base64.Decode(
+			"MIIDbDCCAtWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtzELMAkGA1UEBhMCQVUx"
+			+ "ETAPBgNVBAgTCFZpY3RvcmlhMRgwFgYDVQQHEw9Tb3V0aCBNZWxib3VybmUxGjAY"
+			+ "BgNVBAoTEUNvbm5lY3QgNCBQdHkgTHRkMR4wHAYDVQQLExVDZXJ0aWZpY2F0ZSBB"
+			+ "dXRob3JpdHkxFTATBgNVBAMTDENvbm5lY3QgNCBDQTEoMCYGCSqGSIb3DQEJARYZ"
+			+ "d2VibWFzdGVyQGNvbm5lY3Q0LmNvbS5hdTAeFw0wMDA2MDIwNzU1MzNaFw0wMTA2"
+			+ "MDIwNzU1MzNaMIG3MQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExGDAW"
+			+ "BgNVBAcTD1NvdXRoIE1lbGJvdXJuZTEaMBgGA1UEChMRQ29ubmVjdCA0IFB0eSBM"
+			+ "dGQxHjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEVMBMGA1UEAxMMQ29u"
+			+ "bmVjdCA0IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0ZXJAY29ubmVjdDQuY29t"
+			+ "LmF1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgs5ptNG6Qv1ZpCDuUNGmv"
+			+ "rhjqMDPd3ri8JzZNRiiFlBA4e6/ReaO1U8ASewDeQMH6i9R6degFdQRLngbuJP0s"
+			+ "xcEE+SksEWNvygfzLwV9J/q+TQDyJYK52utb++lS0b48A1KPLwEsyL6kOAgelbur"
+			+ "ukwxowprKUIV7Knf1ajetQIDAQABo4GFMIGCMCQGA1UdEQQdMBuBGXdlYm1hc3Rl"
+			+ "ckBjb25uZWN0NC5jb20uYXUwDwYDVR0TBAgwBgEB/wIBADA2BglghkgBhvhCAQ0E"
+			+ "KRYnbW9kX3NzbCBnZW5lcmF0ZWQgY3VzdG9tIENBIGNlcnRpZmljYXRlMBEGCWCG"
+			+ "SAGG+EIBAQQEAwICBDANBgkqhkiG9w0BAQQFAAOBgQCsGvfdghH8pPhlwm1r3pQk"
+			+ "msnLAVIBb01EhbXm2861iXZfWqGQjrGAaA0ZpXNk9oo110yxoqEoSJSzniZa7Xtz"
+			+ "soTwNUpE0SLHvWf/SlKdFWlzXA+vOZbzEv4UmjeelekTm7lc01EEa5QRVzOxHFtQ"
+			+ "DhkaJ8VqOMajkQFma2r9iA==");
+
+		//
+		// testx509.pem
+		//
+		private static readonly byte[] cert3 = Base64.Decode(
+			"MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV"
+			+ "BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz"
+			+ "MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM"
+			+ "RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF"
+			+ "AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO"
+			+ "/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE"
+			+ "Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ"
+			+ "zl9HYIMxATFyqSiD9jsx");
+
+		//
+		// v3-cert1.pem
+		//
+		private static readonly byte[] cert4 = Base64.Decode(
+			"MIICjTCCAfigAwIBAgIEMaYgRzALBgkqhkiG9w0BAQQwRTELMAkGA1UEBhMCVVMx"
+			+ "NjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFuZCBTcGFjZSBBZG1pbmlz"
+			+ "dHJhdGlvbjAmFxE5NjA1MjgxMzQ5MDUrMDgwMBcROTgwNTI4MTM0OTA1KzA4MDAw"
+			+ "ZzELMAkGA1UEBhMCVVMxNjA0BgNVBAoTLU5hdGlvbmFsIEFlcm9uYXV0aWNzIGFu"
+			+ "ZCBTcGFjZSBBZG1pbmlzdHJhdGlvbjEgMAkGA1UEBRMCMTYwEwYDVQQDEwxTdGV2"
+			+ "ZSBTY2hvY2gwWDALBgkqhkiG9w0BAQEDSQAwRgJBALrAwyYdgxmzNP/ts0Uyf6Bp"
+			+ "miJYktU/w4NG67ULaN4B5CnEz7k57s9o3YY3LecETgQ5iQHmkwlYDTL2fTgVfw0C"
+			+ "AQOjgaswgagwZAYDVR0ZAQH/BFowWDBWMFQxCzAJBgNVBAYTAlVTMTYwNAYDVQQK"
+			+ "Ey1OYXRpb25hbCBBZXJvbmF1dGljcyBhbmQgU3BhY2UgQWRtaW5pc3RyYXRpb24x"
+			+ "DTALBgNVBAMTBENSTDEwFwYDVR0BAQH/BA0wC4AJODMyOTcwODEwMBgGA1UdAgQR"
+			+ "MA8ECTgzMjk3MDgyM4ACBSAwDQYDVR0KBAYwBAMCBkAwCwYJKoZIhvcNAQEEA4GB"
+			+ "AH2y1VCEw/A4zaXzSYZJTTUi3uawbbFiS2yxHvgf28+8Js0OHXk1H1w2d6qOHH21"
+			+ "X82tZXd/0JtG0g1T9usFFBDvYK8O0ebgz/P5ELJnBL2+atObEuJy1ZZ0pBDWINR3"
+			+ "WkDNLCGiTkCKp0F5EWIrVDwh54NNevkCQRZita+z4IBO");
+
+		//
+		// v3-cert2.pem
+		//
+		private static readonly byte[] cert5 = Base64.Decode(
+			"MIICiTCCAfKgAwIBAgIEMeZfHzANBgkqhkiG9w0BAQQFADB9MQswCQYDVQQGEwJD"
+			+ "YTEPMA0GA1UEBxMGTmVwZWFuMR4wHAYDVQQLExVObyBMaWFiaWxpdHkgQWNjZXB0"
+			+ "ZWQxHzAdBgNVBAoTFkZvciBEZW1vIFB1cnBvc2VzIE9ubHkxHDAaBgNVBAMTE0Vu"
+			+ "dHJ1c3QgRGVtbyBXZWIgQ0EwHhcNOTYwNzEyMTQyMDE1WhcNOTYxMDEyMTQyMDE1"
+			+ "WjB0MSQwIgYJKoZIhvcNAQkBExVjb29rZUBpc3NsLmF0bC5ocC5jb20xCzAJBgNV"
+			+ "BAYTAlVTMScwJQYDVQQLEx5IZXdsZXR0IFBhY2thcmQgQ29tcGFueSAoSVNTTCkx"
+			+ "FjAUBgNVBAMTDVBhdWwgQS4gQ29va2UwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA"
+			+ "6ceSq9a9AU6g+zBwaL/yVmW1/9EE8s5you1mgjHnj0wAILuoB3L6rm6jmFRy7QZT"
+			+ "G43IhVZdDua4e+5/n1ZslwIDAQABo2MwYTARBglghkgBhvhCAQEEBAMCB4AwTAYJ"
+			+ "YIZIAYb4QgENBD8WPVRoaXMgY2VydGlmaWNhdGUgaXMgb25seSBpbnRlbmRlZCBm"
+			+ "b3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlcy4wDQYJKoZIhvcNAQEEBQADgYEAi8qc"
+			+ "F3zfFqy1sV8NhjwLVwOKuSfhR/Z8mbIEUeSTlnH3QbYt3HWZQ+vXI8mvtZoBc2Fz"
+			+ "lexKeIkAZXCesqGbs6z6nCt16P6tmdfbZF3I3AWzLquPcOXjPf4HgstkyvVBn0Ap"
+			+ "jAFN418KF/Cx4qyHB4cjdvLrRjjQLnb2+ibo7QU=");
+
+		private static readonly byte[] cert6 = Base64.Decode(
+			"MIIEDjCCAvagAwIBAgIEFAAq2jANBgkqhkiG9w0BAQUFADBLMSowKAYDVQQDEyFT"
+			+ "dW4gTWljcm9zeXN0ZW1zIEluYyBDQSAoQ2xhc3MgQikxHTAbBgNVBAoTFFN1biBN"
+			+ "aWNyb3N5c3RlbXMgSW5jMB4XDTA0MDIyOTAwNDMzNFoXDTA5MDMwMTAwNDMzNFow"
+			+ "NzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxFjAUBgNVBAMTDXN0b3Jl"
+			+ "LnN1bi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAP9ErzFT7MPg2bVV"
+			+ "LNmHTgN4kmiRNlPpuLGWS7EDIXYBbLeSSOCp/e1ANcOGnsuf0WIq9ejd/CPyEfh4"
+			+ "sWoVvQzpOfHZ/Jyei29PEuxzWT+4kQmCx3+sLK25lAnDFsz1KiFmB6Y3GJ/JSjpp"
+			+ "L0Yy1R9YlIc82I8gSw44y5JDABW5AgMBAAGjggGQMIIBjDAOBgNVHQ8BAf8EBAMC"
+			+ "BaAwHQYDVR0OBBYEFG1WB3PApZM7OPPVWJ31UrERaoKWMEcGA1UdIARAMD4wPAYL"
+			+ "YIZIAYb3AIN9k18wLTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5zdW4uY29tL3Br"
+			+ "aS9jcHMuaHRtbDCBhQYDVR0fBH4wfDB6oCegJYYjaHR0cDovL3d3dy5zdW4uY29t"
+			+ "L3BraS9wa2lzbWljYS5jcmyiT6RNMEsxKjAoBgNVBAMTIVN1biBNaWNyb3N5c3Rl"
+			+ "bXMgSW5jIENBIChDbGFzcyBCKTEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJ"
+			+ "bmMwHwYDVR0jBBgwFoAUT7ZnqR/EEBSgG6h1wdYMI5RiiWswVAYIKwYBBQUHAQEE"
+			+ "SDBGMB0GCCsGAQUFBzABhhFodHRwOi8vdmEuc3VuLmNvbTAlBggrBgEFBQcwAYYZ"
+			+ "aHR0cDovL3ZhLmNlbnRyYWwuc3VuLmNvbTATBgNVHSUEDDAKBggrBgEFBQcDATAN"
+			+ "BgkqhkiG9w0BAQUFAAOCAQEAq3byQgyU24tBpR07iQK7agm1zQyzDQ6itdbji0ln"
+			+ "T7fOd5Pnp99iig8ovwWliNtXKAmgtJY60jWz7nEuk38AioZJhS+RPWIWX/+2PRV7"
+			+ "s2aWTzM3n43BypD+jU2qF9c9kDWP/NW9K9IcrS7SfU/2MZVmiCMD/9FEL+CWndwE"
+			+ "JJQ/oenXm44BFISI/NjV7fMckN8EayPvgtzQkD5KnEiggOD6HOrwTDFR+tmAEJ0K"
+			+ "ZttQNwOzCOcEdxXTg6qBHUbONdL7bjTT5NzV+JR/bnfiCqHzdnGwfbHzhmrnXw8j"
+			+ "QCVXcfBfL9++nmpNNRlnJMRdYGeCY6OAfh/PRo8/fXak1Q==");
+
+		private static readonly byte[] cert7 = Base64.Decode(
+			"MIIFJDCCBAygAwIBAgIKEcJZuwAAAAAABzANBgkqhkiG9w0BAQUFADAPMQ0wCwYD"
+			+ "VQQDEwRNU0NBMB4XDTA0MDUyMjE2MTM1OFoXDTA1MDUyMjE2MjM1OFowaTEbMBkG"
+			+ "CSqGSIb3DQEJCBMMMTkyLjE2OC4xLjMzMScwJQYJKoZIhvcNAQkCExhwaXhmaXJl"
+			+ "d2FsbC5jaXNjb3BpeC5jb20xITAfBgNVBAMTGHBpeGZpcmV3YWxsLmNpc2NvcGl4"
+			+ "LmNvbTB8MA0GCSqGSIb3DQEBAQUAA2sAMGgCYQCbcsY7vrjweXZiFQdhUafEjJV+"
+			+ "HRy5UKmuCy0237ffmYrN+XNLw0h90cdCSK6KPZebd2E2Bc2UmTikc/FY8meBT3/E"
+			+ "O/Osmywzi++Ur8/IrDvtuR1zd0c/xEPnV1ZRezkCAwEAAaOCAs4wggLKMAsGA1Ud"
+			+ "DwQEAwIFoDAdBgNVHQ4EFgQUzJBSxkQiN9TKvhTMQ1/Aq4gZnHswHwYDVR0jBBgw"
+			+ "FoAUMsxzXVh+5UKMNpwNHmqSfcRYfJ4wgfcGA1UdHwSB7zCB7DCB6aCB5qCB44aB"
+			+ "r2xkYXA6Ly8vQ049TVNDQSxDTj1NQVVELENOPUNEUCxDTj1QdWJsaWMlMjBLZXkl"
+			+ "MjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPWludCxE"
+			+ "Qz1wcmltZWtleSxEQz1zZT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/"
+			+ "b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnSGL2h0dHA6Ly9tYXVkLmlu"
+			+ "dC5wcmltZWtleS5zZS9DZXJ0RW5yb2xsL01TQ0EuY3JsMIIBEAYIKwYBBQUHAQEE"
+			+ "ggECMIH/MIGqBggrBgEFBQcwAoaBnWxkYXA6Ly8vQ049TVNDQSxDTj1BSUEsQ049"
+			+ "UHVibGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJh"
+			+ "dGlvbixEQz1pbnQsREM9cHJpbWVrZXksREM9c2U/Y0FDZXJ0aWZpY2F0ZT9iYXNl"
+			+ "P29iamVjdENsYXNzPWNlcnRpZmljYXRpb25BdXRob3JpdHkwUAYIKwYBBQUHMAKG"
+			+ "RGh0dHA6Ly9tYXVkLmludC5wcmltZWtleS5zZS9DZXJ0RW5yb2xsL01BVUQuaW50"
+			+ "LnByaW1la2V5LnNlX01TQ0EuY3J0MCwGA1UdEQEB/wQiMCCCGHBpeGZpcmV3YWxs"
+			+ "LmNpc2NvcGl4LmNvbYcEwKgBITA/BgkrBgEEAYI3FAIEMh4wAEkAUABTAEUAQwBJ"
+			+ "AG4AdABlAHIAbQBlAGQAaQBhAHQAZQBPAGYAZgBsAGkAbgBlMA0GCSqGSIb3DQEB"
+			+ "BQUAA4IBAQCa0asiPbObLJjpSz6ndJ7y4KOWMiuuBc/VQBnLr7RBCF3ZlZ6z1+e6"
+			+ "dmv8se/z11NgateKfxw69IhLCriA960HEgX9Z61MiVG+DrCFpbQyp8+hPFHoqCZN"
+			+ "b7upc8k2OtJW6KPaP9k0DW52YQDIky4Vb2rZeC4AMCorWN+KlndHhr1HFA14HxwA"
+			+ "4Mka0FM6HNWnBV2UmTjBZMDr/OrGH1jLYIceAaZK0X2R+/DWXeeqIga8jwP5empq"
+			+ "JetYnkXdtTbEh3xL0BX+mZl8vDI+/PGcwox/7YjFmyFWphRMxk9CZ3rF2/FQWMJP"
+			+ "YqQpKiQOmQg5NAhcwffLAuVjVVibPYqi");
+
+		private static readonly byte[] cert8 = Base64.Decode(
+			"MIIB0zCCATwCAQEwbqBsMGekZTBjMQswCQYDVQQGEwJERTELMAkGA1UECBMCQlkx"
+			+ "EzARBgNVBAcTClJlZ2Vuc2J1cmcxEDAOBgNVBAoTB0FDIFRlc3QxCzAJBgNVBAsT"
+			+ "AkNBMRMwEQYDVQQDEwpBQyBUZXN0IENBAgEBoHYwdKRyMHAxCzAJBgNVBAYTAkRF"
+			+ "MQswCQYDVQQIEwJCWTETMBEGA1UEBxMKUmVnZW5zYnVyZzESMBAGA1UEChMJQUMg"
+			+ "SXNzdWVyMRowGAYDVQQLExFBQyBJc3N1ZXIgc2VjdGlvbjEPMA0GA1UEAxMGQUMg"
+			+ "TWFuMA0GCSqGSIb3DQEBBQUAAgEBMCIYDzIwMDQxMTI2MTI1MjUxWhgPMjAwNDEy"
+			+ "MzEyMzAwMDBaMBkwFwYDVRhIMRAwDoEMREFVMTIzNDU2Nzg5MA0GCSqGSIb3DQEB"
+			+ "BQUAA4GBABd4Odx3yEMGL/BvItuT1RafNR2uuWuZbajg0pD6bshUsl+WCIfRiEkq"
+			+ "lHMkpI7WqAZikdnAEQ5jQsVWEuVejWxR6gjejKxc0fb9qpIui7/GoI5Eh6dmG20e"
+			+ "xbwJL3+6YYFrZwxR8cC5rPvWrblUR5XKJy+Zp/H5+t9iANnL1L8J");
+
+		private static readonly string[] subjects =
+		{
+			"C=AU,ST=Victoria,L=South Melbourne,O=Connect 4 Pty Ltd,OU=Webserver Team,CN=www2.connect4.com.au,E=webmaster@connect4.com.au",
+			"C=AU,ST=Victoria,L=South Melbourne,O=Connect 4 Pty Ltd,OU=Certificate Authority,CN=Connect 4 CA,E=webmaster@connect4.com.au",
+			"C=AU,ST=QLD,CN=SSLeay/rsa test cert",
+			"C=US,O=National Aeronautics and Space Administration,SERIALNUMBER=16+CN=Steve Schoch",
+			"E=cooke@issl.atl.hp.com,C=US,OU=Hewlett Packard Company (ISSL),CN=Paul A. Cooke",
+			"O=Sun Microsystems Inc,CN=store.sun.com",
+			"unstructuredAddress=192.168.1.33,unstructuredName=pixfirewall.ciscopix.com,CN=pixfirewall.ciscopix.com"
+		};
+
+		public override string Name
+		{
+			get { return "Certificate"; }
+		}
+
+		public void CheckCertificate(
+			int		id,
+			byte[]	cert)
+		{
+			Asn1Object seq = Asn1Object.FromByteArray(cert);
+			string dump = Asn1Dump.DumpAsString(seq);
+
+			X509CertificateStructure obj = X509CertificateStructure.GetInstance(seq);
+			TbsCertificateStructure tbsCert = obj.TbsCertificate;
+
+			if (!tbsCert.Subject.ToString().Equals(subjects[id - 1]))
+			{
+				Fail("failed subject test for certificate id " + id
+					+ " got " + tbsCert.Subject.ToString());
+			}
+
+			if (tbsCert.Version == 3)
+			{
+				X509Extensions ext = tbsCert.Extensions;
+				if (ext != null)
+				{
+					foreach (DerObjectIdentifier oid in ext.ExtensionOids)
+					{
+						X509Extension extVal = ext.GetExtension(oid);
+						Asn1Object extObj = Asn1Object.FromByteArray(extVal.Value.GetOctets());
+
+						if (oid.Equals(X509Extensions.SubjectKeyIdentifier))
+						{
+							SubjectKeyIdentifier.GetInstance(extObj);
+						}
+						else if (oid.Equals(X509Extensions.KeyUsage))
+						{
+							KeyUsage.GetInstance(extObj);
+						}
+						else if (oid.Equals(X509Extensions.ExtendedKeyUsage))
+						{
+							ExtendedKeyUsage ku = ExtendedKeyUsage.GetInstance(extObj);
+
+							Asn1Sequence sq = (Asn1Sequence)ku.ToAsn1Object();
+							for (int i = 0; i != sq.Count; i++)
+							{
+								KeyPurposeID.GetInstance(sq[i]);
+							}
+						}
+						else if (oid.Equals(X509Extensions.SubjectAlternativeName))
+						{
+							GeneralNames gn = GeneralNames.GetInstance(extObj);
+
+							Asn1Sequence sq = (Asn1Sequence)gn.ToAsn1Object();
+							for (int i = 0; i != sq.Count; i++)
+							{
+								GeneralName.GetInstance(sq[i]);
+							}
+						}
+						else if (oid.Equals(X509Extensions.IssuerAlternativeName))
+						{
+							GeneralNames gn = GeneralNames.GetInstance(extObj);
+
+							Asn1Sequence sq = (Asn1Sequence)gn.ToAsn1Object();
+							for (int i = 0; i != sq.Count; i++)
+							{
+								GeneralName.GetInstance(sq[i]);
+							}
+						}
+						else if (oid.Equals(X509Extensions.CrlDistributionPoints))
+						{
+							CrlDistPoint p = CrlDistPoint.GetInstance(extObj);
+
+							DistributionPoint[] points = p.GetDistributionPoints();
+							for (int i = 0; i != points.Length; i++)
+							{
+								// do nothing
+							}
+						}
+						else if (oid.Equals(X509Extensions.CertificatePolicies))
+						{
+							Asn1Sequence cp = (Asn1Sequence) extObj;
+
+							for (int i = 0; i != cp.Count; i++)
+							{
+								PolicyInformation.GetInstance(cp[i]);
+							}
+						}
+						else if (oid.Equals(X509Extensions.AuthorityKeyIdentifier))
+						{
+							AuthorityKeyIdentifier.GetInstance(extObj);
+						}
+						else if (oid.Equals(X509Extensions.BasicConstraints))
+						{
+							BasicConstraints.GetInstance(extObj);
+						}
+						else
+						{
+							//Console.WriteLine(oid.Id);
+						}
+					}
+				}
+			}
+		}
+
+		public void CheckAttributeCertificate(
+			int		id,
+			byte[]	cert)
+		{
+			Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(cert);
+			string dump = Asn1Dump.DumpAsString(seq);
+
+			AttributeCertificate obj = AttributeCertificate.GetInstance(seq);
+			AttributeCertificateInfo acInfo = obj.ACInfo;
+
+			// Version
+			if (!(acInfo.Version.Equals(new DerInteger(1)))
+				&& (!(acInfo.Version.Equals(new DerInteger(2)))))
+			{
+				Fail("failed AC Version test for id " + id);
+			}
+
+			// Holder
+			Holder h = acInfo.Holder;
+			if (h == null)
+			{
+				Fail("failed AC Holder test, it's null, for id " + id);
+			}
+
+			// Issuer
+			AttCertIssuer aci = acInfo.Issuer;
+			if (aci == null)
+			{
+				Fail("failed AC Issuer test, it's null, for id " + id);
+			}
+
+			// Signature
+			AlgorithmIdentifier sig = acInfo.Signature;
+			if (sig == null)
+			{
+				Fail("failed AC Signature test for id " + id);
+			}
+
+			// Serial
+			DerInteger serial = acInfo.SerialNumber;
+
+			// Validity
+			AttCertValidityPeriod validity = acInfo.AttrCertValidityPeriod;
+			if (validity == null)
+			{
+				Fail("failed AC AttCertValidityPeriod test for id " + id);
+			}
+
+			// Attributes
+			Asn1Sequence attribSeq = acInfo.Attributes;
+			AttributeX509[] att = new AttributeX509[attribSeq.Count];
+			for (int i = 0; i < attribSeq.Count; i++)
+			{
+				att[i] = AttributeX509.GetInstance(attribSeq[i]);
+			}
+
+			// IssuerUniqueId
+			// TODO, how to best test?
+
+			// X509 Extensions
+			X509Extensions ext = acInfo.Extensions;
+			if (ext != null)
+			{
+				foreach (DerObjectIdentifier oid in ext.ExtensionOids)
+				{
+					X509Extension extVal = ext.GetExtension(oid);
+				}
+			}
+		}
+
+		public override void PerformTest()
+		{
+			CheckCertificate(1, cert1);
+			CheckCertificate(2, cert2);
+			CheckCertificate(3, cert3);
+			CheckCertificate(4, cert4);
+			CheckCertificate(5, cert5);
+			CheckCertificate(6, cert6);
+			CheckCertificate(7, cert7);
+			CheckAttributeCertificate(8, cert8);
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new CertificateTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/CommitmentTypeIndicationUnitTest.cs b/crypto/test/src/asn1/test/CommitmentTypeIndicationUnitTest.cs
new file mode 100644
index 000000000..20c2d18e3
--- /dev/null
+++ b/crypto/test/src/asn1/test/CommitmentTypeIndicationUnitTest.cs
@@ -0,0 +1,107 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Esf;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+    [TestFixture]
+    public class CommitmentTypeIndicationUnitTest
+        : SimpleTest
+    {
+        public override string Name
+        {
+			get { return "CommitmentTypeIndication"; }
+        }
+
+		public override void PerformTest()
+        {
+            CommitmentTypeIndication cti = new CommitmentTypeIndication(CommitmentTypeIdentifier.ProofOfOrigin);
+
+            CheckConstruction(cti, CommitmentTypeIdentifier.ProofOfOrigin, null);
+
+            Asn1Sequence qualifier = new DerSequence(new DerObjectIdentifier("1.2"));
+
+            cti = new CommitmentTypeIndication(CommitmentTypeIdentifier.ProofOfOrigin, qualifier);
+
+            CheckConstruction(cti, CommitmentTypeIdentifier.ProofOfOrigin, qualifier);
+
+            cti = CommitmentTypeIndication.GetInstance(null);
+
+            if (cti != null)
+            {
+                Fail("null GetInstance() failed.");
+            }
+
+            try
+            {
+                CommitmentTypeIndication.GetInstance(new object());
+
+                Fail("GetInstance() failed to detect bad object.");
+            }
+            catch (ArgumentException)
+            {
+                // expected
+            }
+        }
+
+        private void CheckConstruction(
+            CommitmentTypeIndication mv,
+            DerObjectIdentifier commitmenttTypeId,
+            Asn1Encodable qualifier)
+        {
+            CheckStatement(mv, commitmenttTypeId, qualifier);
+
+			mv = CommitmentTypeIndication.GetInstance(mv);
+
+			CheckStatement(mv, commitmenttTypeId, qualifier);
+
+			Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(
+				mv.ToAsn1Object().GetEncoded());
+
+			mv = CommitmentTypeIndication.GetInstance(seq);
+
+			CheckStatement(mv, commitmenttTypeId, qualifier);
+        }
+
+		private void CheckStatement(
+            CommitmentTypeIndication cti,
+            DerObjectIdentifier     commitmentTypeId,
+            Asn1Encodable           qualifier)
+        {
+            if (!cti.CommitmentTypeID.Equals(commitmentTypeId))
+            {
+                Fail("commitmentTypeIds don't match.");
+            }
+
+            if (qualifier != null)
+            {
+                if (!cti.CommitmentTypeQualifier.Equals(qualifier))
+                {
+                    Fail("qualifiers don't match.");
+                }
+            }
+            else if (cti.CommitmentTypeQualifier != null)
+            {
+                Fail("qualifier found when none expected.");
+            }
+        }
+
+        public static void Main(
+            string[]    args)
+        {
+            RunTest(new CommitmentTypeIndicationUnitTest());
+        }
+
+        [Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/asn1/test/CommitmentTypeQualifierUnitTest.cs b/crypto/test/src/asn1/test/CommitmentTypeQualifierUnitTest.cs
new file mode 100644
index 000000000..192ac52f6
--- /dev/null
+++ b/crypto/test/src/asn1/test/CommitmentTypeQualifierUnitTest.cs
@@ -0,0 +1,107 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Esf;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+    [TestFixture]
+    public class CommitmentTypeQualifierUnitTest
+        : SimpleTest
+    {
+        public override string Name
+        {
+			get { return "CommitmentTypeQualifier"; }
+        }
+
+		public override void PerformTest()
+        {
+            CommitmentTypeQualifier ctq = new CommitmentTypeQualifier(CommitmentTypeIdentifier.ProofOfOrigin);
+
+            CheckConstruction(ctq, CommitmentTypeIdentifier.ProofOfOrigin, null);
+
+            Asn1Encodable info = new DerObjectIdentifier("1.2");
+
+            ctq = new CommitmentTypeQualifier(CommitmentTypeIdentifier.ProofOfOrigin, info);
+
+            CheckConstruction(ctq, CommitmentTypeIdentifier.ProofOfOrigin, info);
+
+            ctq = CommitmentTypeQualifier.GetInstance(null);
+
+            if (ctq != null)
+            {
+                Fail("null GetInstance() failed.");
+            }
+
+            try
+            {
+                CommitmentTypeQualifier.GetInstance(new object());
+
+                Fail("GetInstance() failed to detect bad object.");
+            }
+            catch (ArgumentException)
+            {
+                // expected
+            }
+        }
+
+        private void CheckConstruction(
+            CommitmentTypeQualifier mv,
+            DerObjectIdentifier commitmenttTypeId,
+            Asn1Encodable qualifier)
+        {
+            CheckStatement(mv, commitmenttTypeId, qualifier);
+
+			mv = CommitmentTypeQualifier.GetInstance(mv);
+
+			CheckStatement(mv, commitmenttTypeId, qualifier);
+
+			Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(
+				mv.ToAsn1Object().GetEncoded());
+
+			mv = CommitmentTypeQualifier.GetInstance(seq);
+
+			CheckStatement(mv, commitmenttTypeId, qualifier);
+        }
+
+		private void CheckStatement(
+            CommitmentTypeQualifier ctq,
+            DerObjectIdentifier     commitmentTypeId,
+            Asn1Encodable           qualifier)
+        {
+            if (!ctq.CommitmentTypeIdentifier.Equals(commitmentTypeId))
+            {
+                Fail("commitmentTypeIds don't match.");
+            }
+
+            if (qualifier != null)
+            {
+                if (!ctq.Qualifier.Equals(qualifier))
+                {
+                    Fail("qualifiers don't match.");
+                }
+            }
+            else if (ctq.Qualifier != null)
+            {
+                Fail("qualifier found when none expected.");
+            }
+        }
+
+        public static void Main(
+            string[] args)
+        {
+            RunTest(new CommitmentTypeQualifierUnitTest());
+        }
+
+        [Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/asn1/test/ContentHintsUnitTest.cs b/crypto/test/src/asn1/test/ContentHintsUnitTest.cs
new file mode 100644
index 000000000..d7453c27e
--- /dev/null
+++ b/crypto/test/src/asn1/test/ContentHintsUnitTest.cs
@@ -0,0 +1,93 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Ess;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class ContentHintsUnitTest
+		: Asn1UnitTest
+	{
+		public override string Name
+		{
+			get { return "ContentHints"; }
+		}
+
+		public override void PerformTest()
+		{
+			DerUtf8String contentDescription = new DerUtf8String("Description");
+			DerObjectIdentifier contentType = new DerObjectIdentifier("1.2.2.3");
+
+			ContentHints hints = new ContentHints(contentType);
+
+			checkConstruction(hints, contentType, null);
+
+			hints = new ContentHints(contentType, contentDescription);
+
+			checkConstruction(hints, contentType, contentDescription);
+
+			hints = ContentHints.GetInstance(null);
+
+			if (hints != null)
+			{
+				Fail("null GetInstance() failed.");
+			}
+
+			try
+			{
+				ContentHints.GetInstance(new Object());
+
+				Fail("GetInstance() failed to detect bad object.");
+			}
+			catch (ArgumentException)
+			{
+				// expected
+			}
+		}
+
+		private void checkConstruction(
+			ContentHints		hints,
+			DerObjectIdentifier	contentType,
+			DerUtf8String		description)
+		{
+			checkValues(hints, contentType, description);
+
+			hints = ContentHints.GetInstance(hints);
+
+			checkValues(hints, contentType, description);
+
+			Asn1InputStream aIn = new Asn1InputStream(hints.ToAsn1Object().GetEncoded());
+
+			Asn1Sequence seq = (Asn1Sequence) aIn.ReadObject();
+
+			hints = ContentHints.GetInstance(seq);
+
+			checkValues(hints, contentType, description);
+		}
+
+		private void checkValues(
+			ContentHints		hints,
+			DerObjectIdentifier	contentType,
+			DerUtf8String		description)
+		{
+			checkMandatoryField("contentType", contentType, hints.ContentType);
+			checkOptionalField("description", description, hints.ContentDescription);
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new ContentHintsUnitTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/CscaMasterListTest.cs b/crypto/test/src/asn1/test/CscaMasterListTest.cs
new file mode 100644
index 000000000..814e98b2a
--- /dev/null
+++ b/crypto/test/src/asn1/test/CscaMasterListTest.cs
@@ -0,0 +1,57 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Icao;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+    [TestFixture]
+    public class CscaMasterListTest
+        : SimpleTest
+    {
+		public override string Name
+		{
+			get { return "CscaMasterList"; }
+		}
+
+		public override void PerformTest() 
+		{
+			byte[] input = GetInput("masterlist-content.data");
+			CscaMasterList parsedList = CscaMasterList.GetInstance(Asn1Object.FromByteArray(input));
+
+			if (parsedList.GetCertStructs().Length != 3)
+			{
+				Fail("Cert structure parsing failed: incorrect length");
+			}
+
+			byte[] output = parsedList.GetEncoded();
+			if (!AreEqual(input, output))
+			{
+				Fail("Encoding failed after parse");
+			}
+		}
+
+		private byte[] GetInput(string name)
+		{
+			return Streams.ReadAll(SimpleTest.GetTestDataAsStream("asn1." + name));
+		}
+
+		public static void Main(
+            string[] args)
+        {
+            RunTest(new CscaMasterListTest());
+        }
+
+		[Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+        }
+	}
+}
diff --git a/crypto/test/src/asn1/test/DERApplicationSpecificTest.cs b/crypto/test/src/asn1/test/DERApplicationSpecificTest.cs
new file mode 100644
index 000000000..a61ae87e8
--- /dev/null
+++ b/crypto/test/src/asn1/test/DERApplicationSpecificTest.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class DerApplicationSpecificTest
+		: SimpleTest
+	{
+		private static readonly byte[] impData = Hex.Decode("430109");
+
+		private static readonly byte[] certData = Hex.Decode(
+			  "7F218201897F4E8201495F290100420E44454356434145504153533030317F49"
+			+ "81FD060A04007F00070202020202811CD7C134AA264366862A18302575D1D787"
+			+ "B09F075797DA89F57EC8C0FF821C68A5E62CA9CE6C1C299803A6C1530B514E18"
+			+ "2AD8B0042A59CAD29F43831C2580F63CCFE44138870713B1A92369E33E2135D2"
+			+ "66DBB372386C400B8439040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C"
+			+ "1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D376"
+			+ "1402CD851CD7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A793"
+			+ "9F863904393EE8E06DB6C7F528F8B4260B49AA93309824D92CDB1807E5437EE2"
+			+ "E26E29B73A7111530FA86B350037CB9415E153704394463797139E148701015F"
+			+ "200E44454356434145504153533030317F4C0E060904007F0007030102015301"
+			+ "C15F25060007000400015F24060009000400015F37384CCF25C59F3612EEE188"
+			+ "75F6C5F2E2D21F0395683B532A26E4C189B71EFE659C3F26E0EB9AEAE9986310"
+			+ "7F9B0DADA16414FFA204516AEE2B");
+
+		public override string Name
+		{
+			get { return "DerApplicationSpecific"; }
+		}
+
+		public override void PerformTest()
+		{
+			DerInteger val = new DerInteger(9);
+
+			DerApplicationSpecific tagged = new DerApplicationSpecific(false, 3, val);
+
+			if (!AreEqual(impData, tagged.GetEncoded()))
+			{
+				Fail("implicit encoding failed");
+			}
+
+			DerInteger recVal = (DerInteger) tagged.GetObject(Asn1Tags.Integer);
+
+			if (!val.Equals(recVal))
+			{
+				Fail("implicit read back failed");
+			}
+
+			DerApplicationSpecific certObj = (DerApplicationSpecific)
+				Asn1Object.FromByteArray(certData);
+
+			if (!certObj.IsConstructed() || certObj.ApplicationTag != 33)
+			{
+				Fail("parsing of certificate data failed");
+			}
+
+			byte[] encoded = certObj.GetDerEncoded();
+
+			if (!Arrays.AreEqual(certData, encoded))
+			{
+				Console.WriteLine(Encoding.ASCII.GetString(certData, 0, certData.Length).Substring(0, 20));
+				Console.WriteLine(Encoding.ASCII.GetString(encoded, 0, encoded.Length).Substring(0, 20));
+				Fail("re-encoding of certificate data failed");
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new DerApplicationSpecificTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/DERUTF8StringTest.cs b/crypto/test/src/asn1/test/DERUTF8StringTest.cs
new file mode 100644
index 000000000..be4dace79
--- /dev/null
+++ b/crypto/test/src/asn1/test/DERUTF8StringTest.cs
@@ -0,0 +1,113 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class DerUtf8StringTest
+		: ITest
+	{
+		/**
+			* Unicode code point U+10400 coded as surrogate in two native Java UTF-16
+			* code units
+			*/
+		private readonly static char[] glyph1_utf16 = { (char)0xd801, (char)0xdc00 };
+
+		/**
+		 * U+10400 coded in UTF-8
+		 */
+		private readonly static byte[] glyph1_utf8 = { (byte)0xF0, (byte)0x90, (byte)0x90, (byte)0x80 };
+
+		/**
+		 * Unicode code point U+6771 in native Java UTF-16
+		 */
+		private readonly static char[] glyph2_utf16 = { (char)0x6771 };
+
+		/**
+		 * U+6771 coded in UTF-8
+		 */
+		private readonly static byte[] glyph2_utf8 = { (byte)0xE6, (byte)0x9D, (byte)0xB1 };
+
+		/**
+		 * Unicode code point U+00DF in native Java UTF-16
+		 */
+		private readonly static char[] glyph3_utf16 = { (char)0x00DF };
+
+		/**
+		 * U+00DF coded in UTF-8
+		 */
+		private readonly static byte[] glyph3_utf8 = { (byte)0xC3, (byte)0x9f };
+
+		/**
+		 * Unicode code point U+0041 in native Java UTF-16
+		 */
+		private readonly static char[] glyph4_utf16 = { (char)0x0041 };
+
+		/**
+		 * U+0041 coded in UTF-8
+		 */
+		private readonly static byte[] glyph4_utf8 = { 0x41 };
+
+		private readonly static byte[][] glyphs_utf8 = { glyph1_utf8, glyph2_utf8, glyph3_utf8, glyph4_utf8 };
+
+		private readonly static char[][] glyphs_utf16 = { glyph1_utf16, glyph2_utf16, glyph3_utf16, glyph4_utf16 };
+
+		public ITestResult Perform()
+		{
+			try
+			{
+				for (int i = 0; i < glyphs_utf16.Length; i++)
+				{
+					string s = new string(glyphs_utf16[i]);
+					byte[] b1 = new DerUtf8String(s).GetEncoded();
+					byte[] temp = new byte[b1.Length - 2];
+					Array.Copy(b1, 2, temp, 0, b1.Length - 2);
+					byte[] b2 = new DerUtf8String(new DerOctetString(temp).GetOctets()).GetEncoded();
+					if (!Arrays.AreEqual(b1, b2))
+					{
+						return new SimpleTestResult(false, Name + ": failed UTF-8 encoding and decoding");
+					}
+					if (!Arrays.AreEqual(temp, glyphs_utf8[i]))
+					{
+						return new SimpleTestResult(false, Name + ": failed UTF-8 encoding and decoding");
+					}
+				}
+			}
+			catch (Exception e)
+			{
+				return new SimpleTestResult(false, Name + ": failed with Exception " + e.Message);
+			}
+
+			return new SimpleTestResult(true, Name + ": Okay");
+		}
+
+		public string Name
+		{
+			get
+			{
+				return "DERUTF8String";
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			DerUtf8StringTest test = new DerUtf8StringTest();
+			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/DataGroupHashUnitTest.cs b/crypto/test/src/asn1/test/DataGroupHashUnitTest.cs
new file mode 100644
index 000000000..dcebf4670
--- /dev/null
+++ b/crypto/test/src/asn1/test/DataGroupHashUnitTest.cs
@@ -0,0 +1,106 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Icao;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+    [TestFixture]
+    public class DataGroupHashUnitTest
+        : SimpleTest
+    {
+        public override string Name
+        {
+			get { return "DataGroupHash"; }
+        }
+
+		private byte[] GenerateHash()
+        {
+            Random rand = new Random();
+            byte[] bytes = new byte[20];
+			rand.NextBytes(bytes);
+			return bytes;
+        }
+
+		public override void PerformTest()
+        {
+            int dataGroupNumber = 1;
+            Asn1OctetString dataHash = new DerOctetString(GenerateHash());
+            DataGroupHash dg = new DataGroupHash(dataGroupNumber, dataHash);
+
+            CheckConstruction(dg, dataGroupNumber, dataHash);
+
+			try
+			{
+				DataGroupHash.GetInstance(null);
+			}
+			catch (Exception)
+			{
+				Fail("GetInstance() failed to handle null.");
+			}
+
+			try
+            {
+                DataGroupHash.GetInstance(new object());
+
+				Fail("GetInstance() failed to detect bad object.");
+            }
+            catch (ArgumentException)
+            {
+                // expected
+            }
+        }
+
+		private void CheckConstruction(
+            DataGroupHash dg,
+            int dataGroupNumber,
+            Asn1OctetString     dataGroupHashValue)
+        {
+            CheckValues(dg, dataGroupNumber, dataGroupHashValue);
+
+			dg = DataGroupHash.GetInstance(dg);
+
+			CheckValues(dg, dataGroupNumber, dataGroupHashValue);
+
+			Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(
+				dg.ToAsn1Object().GetEncoded());
+
+			dg = DataGroupHash.GetInstance(seq);
+
+			CheckValues(dg, dataGroupNumber, dataGroupHashValue);
+        }
+
+		private void CheckValues(
+            DataGroupHash	dg,
+            int				dataGroupNumber,
+            Asn1OctetString	dataGroupHashValue)
+        {
+            if (dg.DataGroupNumber != dataGroupNumber)
+            {
+                Fail("group number don't match.");
+            }
+
+			if (!dg.DataGroupHashValue.Equals(dataGroupHashValue))
+            {
+                Fail("hash value don't match.");
+            }
+        }
+
+		public static void Main(
+            string[] args)
+        {
+            RunTest(new DataGroupHashUnitTest());
+        }
+
+		[Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/asn1/test/DeclarationOfMajorityUnitTest.cs b/crypto/test/src/asn1/test/DeclarationOfMajorityUnitTest.cs
new file mode 100644
index 000000000..bd1fb5a9e
--- /dev/null
+++ b/crypto/test/src/asn1/test/DeclarationOfMajorityUnitTest.cs
@@ -0,0 +1,97 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.IsisMtt.X509;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class DeclarationOfMajorityUnitTest
+		: Asn1UnitTest
+	{
+		public override string Name
+		{
+			get { return "DeclarationOfMajority"; }
+		}
+
+		public override void PerformTest()
+		{
+			DerGeneralizedTime dateOfBirth = new DerGeneralizedTime("20070315173729Z");
+			DeclarationOfMajority decl = new DeclarationOfMajority(dateOfBirth);
+
+			checkConstruction(decl, DeclarationOfMajority.Choice.DateOfBirth, dateOfBirth, -1);
+
+			decl = new DeclarationOfMajority(6);
+
+			checkConstruction(decl, DeclarationOfMajority.Choice.NotYoungerThan, null, 6);
+
+			decl = DeclarationOfMajority.GetInstance(null);
+
+			if (decl != null)
+			{
+				Fail("null GetInstance() failed.");
+			}
+
+			try
+			{
+				DeclarationOfMajority.GetInstance(new Object());
+
+				Fail("GetInstance() failed to detect bad object.");
+			}
+			catch (ArgumentException)
+			{
+				// expected
+			}
+		}
+
+		private void checkConstruction(
+			DeclarationOfMajority			decl,
+			DeclarationOfMajority.Choice	type,
+			DerGeneralizedTime				dateOfBirth,
+			int								notYoungerThan)
+		{
+			checkValues(decl, type, dateOfBirth, notYoungerThan);
+
+			decl = DeclarationOfMajority.GetInstance(decl);
+
+			checkValues(decl, type, dateOfBirth, notYoungerThan);
+
+			Asn1InputStream aIn = new Asn1InputStream(decl.ToAsn1Object().GetEncoded());
+
+			DerTaggedObject info = (DerTaggedObject) aIn.ReadObject();
+
+			decl = DeclarationOfMajority.GetInstance(info);
+
+			checkValues(decl, type, dateOfBirth, notYoungerThan);
+		}
+
+		private void checkValues(
+			DeclarationOfMajority			decl,
+			DeclarationOfMajority.Choice	type,
+			DerGeneralizedTime				dateOfBirth,
+			int								notYoungerThan)
+		{
+			checkMandatoryField("type", (int) type, (int) decl.Type);
+			checkOptionalField("dateOfBirth", dateOfBirth, decl.DateOfBirth);
+			if (notYoungerThan != -1 && notYoungerThan != decl.NotYoungerThan)
+			{
+				Fail("notYoungerThan mismatch");
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new DeclarationOfMajorityUnitTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/EncryptedPrivateKeyInfoTest.cs b/crypto/test/src/asn1/test/EncryptedPrivateKeyInfoTest.cs
new file mode 100644
index 000000000..a84df59cc
--- /dev/null
+++ b/crypto/test/src/asn1/test/EncryptedPrivateKeyInfoTest.cs
@@ -0,0 +1,152 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.Utilities;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+    /**
+     * Test the reading and writing of EncryptedPrivateKeyInfo objects using
+     * the test vectors provided at
+     * <a href="http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html">
+     * RSA's Pkcs5 Page</a>.
+     * <br/>
+     * 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(
+            "MIIXqAYJKoZIhvcNAQcDoIIXmTCCF5UCAQAxggG1MIIBsQIBADCBmDCBkDEL"
+            + "MAkGA1UEBhMCVVMxETAPBgNVBAgTCE1pY2hpZ2FuMQ0wCwYDVQQHEwRUcm95"
+            + "MQwwCgYDVQQKEwNFRFMxGTAXBgNVBAsTEEVMSVQgRW5naW5lZXJpbmcxJDAi"
+            + "BgkqhkiG9w0BCQEWFUVsaXQuU2VydmljZXNAZWRzLmNvbTEQMA4GA1UEAxMH"
+            + "RURTRUxJVAIDD6FBMA0GCSqGSIb3DQEBAQUABIIBAGh04C2SyEnH9J2Va18w"
+            + "3vdp5L7immD5h5CDZFgdgHln5QBzT7hodXMVHmyGnycsWnAjYqpsil96H3xQ"
+            + "A6+9a7yB6TYSLTNv8zhL2qU3IrfdmUJyxxfsFJlWFO1MlRmu9xEAW5CeauXs"
+            + "RurQCT+C5tLc5uytbvw0Jqbz+Qp1+eaRbfvyhWFGkO/BYZ89hVL9Yl1sg/Ls"
+            + "mA5jwTj2AvHkAwis+F33ZhYlto2QDvbPsUa0cldnX8+1Pz4QzKMHmfUbFD2D"
+            + "ngaYN1tDlmezCsYFQmNx1th1SaQtTefvPr+qaqRsm8KEXlWbJQXmIfdyi0zY"
+            + "qiwztEtO81hXZYkKqc5fKMMwghXVBgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcE"
+            + "CEq3cLLWVds9gIIVsAAik3al6Nn5pr7r0mSy9Ki3vEeCBcV9EzEG44BvNHNA"
+            + "WyEsqQsdSxuF7h1/DJAMuZFwCbGflaRGx/1L94zrmtpeuH501lzPMvvZCmpj"
+            + "KrOF8e1B4MVQ5TfQTdUVyRnbcDa6E4V1ZZIdAI7BgDeJttS4+L6btquXfxUg"
+            + "ttPYQkevF7MdShYNnfLkY4vUMDOp3+iVzrOlq0elM95dfSA7OdBavgDJbz/7"
+            + "mro3AFTytnWjGz8TUos+oUujTk9/kHOn4cEAIm0hHrNhPS5qoj3QnNduNrad"
+            + "rLpGtcYyNlHIsYCsvPMxwoHmIw+r9xQQRjjzmVYzidn+cNOt0FmLs6YE8ds4"
+            + "wvHRO9S69TgKPHRgk2bihgHqII9lF9qIzfG40YwJLHzGoEwVO1O0+wn8j2EP"
+            + "O9I/Q3vreCH+5VbpUD2NGTwsMwZ3YlUesurLwse/YICxmgdN5Ro4DeQJSa9M"
+            + "iJnRFYWRq+58cKgr+L11mNc9nApZBShlpPP7pdNqWOafStIEjo+dsY/J+iyS"
+            + "6WLlUvNt/12qF4NAgZMb3FvRQ9PrMe87lqSRnHcpLWHcFjuKbMKCBvcdWGWI"
+            + "R7JR8UNzUvoLGGAUI9Ck+yTq4QtfgtL5MLmdBGxSKzgs44Mmek+LnrFx+e9n"
+            + "pkrdDf2gM/m7E50FnLYqzUjctKYGLNYpXQorq9MJx6TB20CHXcqOOoQqesXa"
+            + "9jL9PIOtBQy1Ow5Bh4SP07nTFWFSMI/Wt4ZvNvWJj3ecA9KjMOA9EXWUDS/H"
+            + "k9iCb2EEMo7fe5mhoyxMxPO+EIa1sEC9A1+rDACKPQCHOLI0uPmsdo0AEECC"
+            + "QLgOQkcwQlkHexOyHiOOtBxehtGZ1eBQQZ+31DF+RRU6WvS6grg58eS4gGOQ"
+            + "bd7CS9yYebvAQkz61J8KprWdtZuG1gBGma12wKMuQuC6RuWlKsj+rPMvaQCt"
+            + "8mucGbkElPGZVhdyD8/BvpSCNbgRwb6iSiw4EECovu4P4GFJaMGUYEuCA711"
+            + "itEieYc1QqS6ULjb3LFL/RcwSw0fGdjnt6B2nHckC2VsYKU1NwU7j0R1Omb4"
+            + "y5AvSgpuWjTXWnHnE9Ey0B+KP5ERZA+jJGiwYz48ynYlvQFSbBm4I6nh/DuI"
+            + "dWB2dLNxWuhdfzafBGtEHhLHzjW3WQwwRZsKesgHLrrj9hBUObodl1uvqvZN"
+            + "AjMOj8DrqbGOhAClj1t4S1Zk1ZekuMjsuoxEL+/lgtbT+056ES0k3A/LnpRb"
+            + "uxA1ZBr26Im+GVFzEcsV0hB4vNujSwStTTZH5jX5rMyi085yJfnikcLYUn9N"
+            + "apl+srhpIZlDJPw7IHaw8tsqXKDxF7MozIXo8B45CKv5Am+BMrIemCMX/ehu"
+            + "PODICl98Ur8tNAn1L+m0nj7H3c8HW2vNuBLEI3SEHHgm2Ij3IY5pyyeVUaWC"
+            + "pumhy8Ru5dj3fZcfKgYuJBQxWMf+UqPsf4iUK3923pouJ1cQ8XU8gOXIRrtX"
+            + "e41d/yR+UAZXSig6SITLw+wLtvitSvtxvjcUSUOI9CYTovKyuz1PQKiaLsV5"
+            + "4CoJhMQ5uRlVFS3H829I2d2gLRpSp6pNWeIZO2NMBxPYf2qcSHyHqQjR7xP2"
+            + "ZTg7U3OO6dZHORfXxzAnW2ExavBIYQmZh1gLn5jSS4wXFPXyvnJAsF4s5wed"
+            + "YHsyAqM/ek0n2Oo/zAh7UcP2vcb9FOoeRK8qC9HjTciS6WbjskRN0ft4T69G"
+            + "+1RsH8/edBxo2LZeA48BSCXDXOlBZJBsOptzYJD8HSZONPnef0jn23lk0fkU"
+            + "C3BjJu2ubFChctRvJniTko4klpidkHwuJgrTnL4er8rG3RfiiEHn/d5era15"
+            + "E1cekdVYWqwQOObOd4v+0gZSJgI48TBc5Qdy8F6wIU38DR2pn/5uNthNDgXk"
+            + "NcV9a2gOE3DoLe8CEIPMihqYMPY8NuSp97eHB2YhKpjP7qX9TUMoOdE2Iat2"
+            + "klNxadJt6JTFeiBPL6R9RHAD5sVBrkrl0S+oYtgF92f9WHVwAXU7zP6IgM4x"
+            + "hhzeJT07yyIp44mKd//F+7ntbgQjZ/iLbHh0mtOlUmzkFsDR0UNSXEQoourZ"
+            + "EY4A62HXj0DMqEQbik6QwEF7FKuwZX2opdOyVKH9MzJxNfDLd5dc8wAc8bCX"
+            + "jcCx5/GzHx2S5DndWQEVhp2hOQYuoJS3r6QCYFaHtDPKnFHS2PBFyFWL+2UK"
+            + "c0WsvVaHYqYKnksmxse9I9oU75kx5O05DZCThPX6h8J8MHRuxU9tcuuleIUQ"
+            + "XY8On+JeEtLSUZgp+Z7ITLuagf6yuKQpaR396MlDii/449/dvBiXAXeduyO1"
+            + "QzSkQCh37fdasqGL3mP0ssMcxM/qpOwQsx3gMtwiHQRi1oQE1QHb8qZHDE4m"
+            + "I5afQJ9O/H/m/EVlGUSn2yYOsPlZrWuI3BBZKoRzRq1lZOQDtOh18BE3tWmX"
+            + "viGIAxajam0i2Ce3h2U7vNwtiePRNEgPmQ7RwTTv0U6X8qqkjeYskiF4Cv9G"
+            + "nrB0WreC19ih5psEWLIkCYKTr+OhQuRrtv7RcyUi9QSneh7BjcvRjlGB6joA"
+            + "F6J4Y6ENAA/nzOZJ699VkljTi59bbNJYlONpQhOeRTu8M/wExkIJz7yR9DTY"
+            + "bY4/JdbdHNFf5DSDmYAHaFLmdnnfuRy+tC9CGGJvlcLVv5LMFJQGt2Wi15p8"
+            + "lctx7sL6yNCi7OakWbEOCvGPOxY7ejnvOjVK/Krx1T+dAXNUqrsDZmvmakOP"
+            + "We+P4Di1GqcyLVOTP8wNCkuAUoN0JFoBHy336/Xnae91KlY4DciPMpEOIpPN"
+            + "oB+3h6CozV7IWX5Wh3rhfC25nyGJshIBUS6cMXAsswQI8rOylMlGaekNcSU4"
+            + "gNKNDZAK5jNkS0Z/ziIrElSvMNTfYbnx3gCkY0pV18uadmchXihVT11Bt77O"
+            + "8KCKHycR39WYFIRO09wvGv6P42CRBFTdQbWFtkSwRiH8l6x39Z7pIkDFxokT"
+            + "Dp6Htkj3ywfQXNbFgRXZUXqgD1gZVFDFx920hcJnuu65CKz6pEL6X0XUwNPg"
+            + "vtraA2nj4wjVB/y+Cxc+1FgzeELB4CAmWO1OfRVLjYe7WEe/X5DPT6p8HBkB"
+            + "5mWuv+iQ3e37e1Lrsjt2frRYQWoOSP5Lv7c8tZiNfuIp07IYnJKBWZLTqNf9"
+            + "60uiY93ssE0gr3mfYOj+fSbbjy6NgAenT7NRZmFCjFwAfmapIV0hJoqnquaN"
+            + "jj5KKOP72hp+Zr9l8cEcvIhG/BbkY3kYbx3JJ9lnujBVr69PphHQTdw67CNB"
+            + "mDkH7y3bvZ+YaDY0vdKOJif9YwW2qoALXKgVBu1T2BONbCTIUTOzrKhWEvW8"
+            + "D6x03JsWrMMqOKeoyomf1iMt4dIOjp7yGl/lQ3iserzzLsAzR699W2+PWrAT"
+            + "5vLgklJPX/Fb3Tojbsc074lBq669WZe3xzlj85hFcBmoLPPyBE91BLhEwlGC"
+            + "+lWmwFOENLFGZE0mGoRN+KYxwqfA2N6H8TWoz6m0oPUW4uQvy9sGtYTSyQO9"
+            + "6ZwVNT3ndlFrP5p2atdEFVc5aO5FsK8/Fenwez06B2wv9cE9QTVpFrnJkKtF"
+            + "SaPCZkignj64XN7cHbk7Ys6nC3WIrTCcj1UOyp5ihuMS9eL9vosYADsmrR6M"
+            + "uqqeqHsf2+6U1sO1JBkDYtLzoaILTJoqg9/eH7cTA0T0mEfxVos9kAzk5nVN"
+            + "nVOKFrCGVIbOStpYlWP6wyykIKVkssfO6D42D5Im0zmgUwgNEkB+Vxvs8bEs"
+            + "l1wPuB2YPRDCEvwM3A5d5vTKhPtKMECIcDxpdwkD5RmLt+iaYN6oSFzyeeU0"
+            + "YvXBQzq8gfpqJu/lP8cFsjEJ0qCKdDHVTAAeWE6s5XpIzXt5cEWa5JK7Us+I"
+            + "VbSmri4z0sVwSpuopXmhLqLlNWLGXRDyTjZSGGJbguczXCq5XJ2E3E4WGYd6"
+            + "mUWhnP5H7gfW7ILOUN8HLbwOWon8A6xZlMQssL/1PaP3nL8ukvOqzbIBCZQY"
+            + "nrIYGowGKDU83zhO6IOgO8RIVQBJsdjXbN0FyV/sFCs5Sf5WyPlXw/dUAXIA"
+            + "cQiVKM3GiVeAg/q8f5nfrr8+OD4TGMVtUVYujfJocDEtdjxBuyFz3aUaKj0F"
+            + "r9DM3ozAxgWcEvl2CUqJLPHH+AWn5kM7bDyQ2sTIUf5M6hdeick09hwrmXRF"
+            + "NdIoUpn7rZORh0h2VX3XytLj2ERmvv/jPVC97VKU916n1QeMJLprjIsp7GsH"
+            + "KieC1RCKEfg4i9uHoIyHo/VgnKrnTOGX/ksj2ArMhviUJ0yjDDx5jo/k5wLn"
+            + "Rew2+bhiQdghRSriUMkubFh7TN901yl1kF2BBP5PHbpgfTP6R7qfl8ZEwzzO"
+            + "elHe7t7SvI7ff5LkwDvUXSEIrHPGajYvBNZsgro+4Sx5rmaE0QSXACG228OQ"
+            + "Qaju8qWqA2UaPhcHSPHO/u7ad/r8kHceu0dYnSFNe1p5v9Tjux0Yn6y1c+xf"
+            + "V1cu3plCwzW3Byw14PH9ATmi8KJpZQaJOqTxn+zD9TvOa93blK/9b5KDY1QM"
+            + "1s70+VOq0lEMI6Ch3QhFbXaslpgMUJLgvEa5fz3GhmD6+BRHkqjjwlLdwmyR"
+            + "qbr4v6o+vnJKucoUmzvDT8ZH9nH2WCtiiEtQaLNU2vsJ4kZvEy0CEajOrqUF"
+            + "d8qgEAHgh9it5oiyGBB2X/52notXWOi6OMKgWlxxKHPTJDvEVcQ4zZUverII"
+            + "4vYrveRXdiDodggfrafziDrA/0eEKWpcZj7fDBYjUBazwjrsn5VIWfwP2AUE"
+            + "wNn+xR81/so8Nl7EDBeoRXttyH7stbZYdRnkPK025CQug9RLzfhEAgjdgQYw"
+            + "uG+z0IuyctJW1Q1E8YSOpWEFcOK5okQkLFUfB63sO1M2LS0dDHzmdZriCfIE"
+            + "F+9aPMzojaHg3OQmZD7MiIjioV6w43bzVmtMRG22weZIYH/Sh3lDRZn13AS9"
+            + "YV6L7hbFtKKYrie79SldtYazYT8FTSNml/+Qv2TvYTjVwYwHpm7t479u+MLh"
+            + "LxMRVsVeJeSxjgufHmiLk7yYJajNyS2j9Kx/fmXmJbWZNcerrfLP+q+b594Y"
+            + "1TGWr8E6ZTh9I1gU2JR7WYl/hB2/eT6sgSYHTPyGSxTEvEHP242lmjkiHY94"
+            + "CfiTMDu281gIsnAskl05aeCBkj2M5S0BWCxy7bpVAVFf5nhf74EFIBOtHaJl"
+            + "/8psz1kGVF3TzgYHkZXpUjVX/mJX8FG0R8HN7g/xK73HSvqeamr4qVz3Kmm/"
+            + "kMtYRbZre7E1D10qh/ksNYnOkYBcG4P2JyjZ5q+8CQNungz2/b0Glg5LztNz"
+            + "hUgG27xDOUraJXjkkZl/GOh0eTqhfLHXC/TfyoEAQOPcA59MKqvroFC5Js0Q"
+            + "sTgqm2lWzaLNz+PEXpJHuSifHFXaYIkLUJs+8X5711+0M03y8iP4jZeEOrjI"
+            + "l9t3ZYbazwsI3hBIke2hGprw4m3ZmSvQ22g+N6+hnitnDALMsZThesjb6aJd"
+            + "XOwhjLkWRD4nQN594o6ZRrfv4bFEPTp4ev8l6diouKlXSFFnVqz7AZw3Pe53"
+            + "BvIsoh66zHBpZhauPV/s/uLb5x6Z8sU2OK6AoJ7b8R9V/AT7zvonBi/XQNw3"
+            + "nwkwGnTS9Mh7PFnGHLJWTKKlYXrSpNviR1vPxqHMO6b+Lki10d/YMY0vHQrY"
+            + "P6oSVkA6RIKsepHWo11+rV838+2NRrdedCe91foUmOs+eoWQnwmTy2CTZmQ5"
+            + "b7/TTcau9ewimZAqI+MtDWcmWoZfgibZmnIITGcduNOJDRn+aLt9dz+zr1qA"
+            + "HxlLXCOyBPdtfx6eo4Jon+fVte37i3HmxHk+8ZGMMSS9hJbLQEkA59b4E+7L"
+            + "GI3JZjvEkhizB4n/aFeG7KT7K3x072DMbHLZ7VgsXQ1VDDmcZmizFwgyNqKy"
+            + "hKCKxU+I2O10IMtiZUpEzV1Pw7hD5Kv/eFCsJFPXOJ2j3KP6qPtX5IYki1qH"
+            + "Juo5C5uGKtqNc6OzkXsvNUfBz5sJkEYl0WfitSSo4ARyshFUNh2hGxNxUVKM"
+            + "2opOcuHSxBgwUSmVprym50C305zdHulBXv3mLzGjvRstE9qfkQ8qVJYLQEkL"
+            + "1Yn7E92ex71YsC8JhNNMy0/YZwMkiFrqyaFd/LrblWpBbGumhe4reCJ4K3mk"
+            + "lFGEsICcMoe+zU1+QuLlz/bQ+UtvClHUe8hTyIjfY04Fwo2vbdSc1U/SHho5"
+            + "thQy+lOZ/HijzCmfWK3aTqYMdwCUTCsoxri2N8vyD/K2kbMLQWUfUlBQfDOK"
+            + "VrksBoSfcluNVaO56uEUw3enPhhJghfNlJnpr5gUcrAMES53DfkjNr0dCsfM"
+            + "JOY2ZfQEwwYey1c4W1MNNMoegSTg4aXzjVc0xDgKa7RGbtRmVNbOxIhUNAVi"
+            + "thQV3Qujoz1ehDt2GyLpjGjHSpQo3WlIU4OUqJaQfF6EH+3khFqUmp1LT7Iq"
+            + "zH3ydYsoCDjvdXSSEY3hLcZVijUJqoaNWBLb/LF8OG5qTjsM2gLgy2vgO/lM"
+            + "NsqkHnWTtDimoaRRjZBlYLhdzf6QlfLi7RPmmRriiAOM0nXmylF5xBPHQLoz"
+            + "LO9lXYIfNbVJVqQsV43z52MvEQCqPNpGqjB+Au/PZalYHbosiVOQLgTB9hTI"
+            + "sGutSXXeLnf5rftCFvWyL3n5DgURzDFLibrbyVGGKAk166bK1RyVP9XZJonr"
+            + "hPYELk4KawCysJJSmC0E8sSsuXpfd6PPDru6nCV1EdXKR7DybS7NVHCktiPR"
+            + "4B4y8O/AgfJX8sb6LuxmjaINtUKEJ1+O88Gb69uy6b/Kpu2ri/SUBaNNw4Sn"
+            + "/tuaD+jxroL7RlZmt9ME/saNKn9OmLuggd6IUKAL4Ifsx9i7+JKcYuP8Cjdf"
+            + "Rx6U6H4qkEwwYGXnZYqF3jxplyOfqA2Vpvp4rnf8mST6dRLKk49IhKGTzwZr"
+            + "4za/RZhyl6lyoRAFDrVs1b+tj6RYZk0QnK3dLiN1MFYojLyz5Uvi5KlSyFw9"
+            + "trsvXyfyWdyRmJqo1fT7OUe0ImJW2RN3v/qs1k+EXizgb7DW4Rc2goDsCGrZ"
+            + "ZdMwuAdpRnyg9WNtmWwp4XXeb66u3hJHr4RwMd5oyKFB1GsmzZF7aOhSIb2B"
+            + "t3coNXo/Y+WpEj9fD7/snq7I1lS2+3Jrnna1048O7N4b5S4b5TtEcCBILP1C"
+            + "SRvaHyZhBtJpoH6UyimKfabXi08ksrcHmbs1+HRvn+3pl0bHcdeBIQS/wjk1"
+            + "TVEDtaP+K9zkJxaExtoa45QvqowxtcKtMftNoznF45LvwriXEDV9jCXvKMcO"
+            + "nxG5aQ//fbnn4j4q1wsKXxn61wuLUW5Nrg9fIhX7nTNAAooETO7bMUeOWjig"
+            + "2S1nscmtwaV+Sumyz/XUhvWynwE0AXveLrA8Gxfx");
+
+        private static readonly byte[] derExpTest = Base64.Decode(
+            "MIIS6AYJKoZIhvcNAQcDoIIS2TCCEtUCAQAxggG1MIIBsQIBADCBmDCBkDEL"
+            + "MAkGA1UEBhMCVVMxETAPBgNVBAgTCE1pY2hpZ2FuMQ0wCwYDVQQHEwRUcm95"
+            + "MQwwCgYDVQQKEwNFRFMxGTAXBgNVBAsTEEVMSVQgRW5naW5lZXJpbmcxJDAi"
+            + "BgkqhkiG9w0BCQEWFUVsaXQuU2VydmljZXNAZWRzLmNvbTEQMA4GA1UEAxMH"
+            + "RURTRUxJVAIDD6FBMA0GCSqGSIb3DQEBAQUABIIBAGsRYK/jP1YujirddAMl"
+            + "ATysfLCwd0eZhENohVqLiMleH25Dnwf+tBaH4a9hyW+7VrWw/LC6ILPVbKpo"
+            + "oLBAOical40cw6C3zulajc4gM3AlE2KEeAWtI+bgPMXhumqiWDb4byX/APYk"
+            + "53Gk7WXF6Xs4hj3tmrHSJxCUOsTdHKUJYvOqjwKGARPQDjP0EUbVJezeAwBA"
+            + "RMlJ/qBVLBj2UW28n5oJZm3oaSaU93Uc6GPVIk43IWrmEUcWVPiMfUtUCwcX"
+            + "tRNtHuQ9os++rmdNBiuB5p+vtUeA45KWnTUtkwJXvrzE6Sf9AUH/p8uOvvZJ"
+            + "3yt9LhPxcZukGIVvcQnBxLswghEVBgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcE"
+            + "CGObmTycubs2gIIQ8AKUC8ciGPxa3sFJ1EPeX/nRwYGNAarlpVnG+07NITL2"
+            + "pUzqZSgsYh5JiKd8TptQBZNdebzNmCvjrVv5s9PaescGcypL7FNVPEubh0w/"
+            + "8h9rTACqUpF5yRgfcgpAGeK29F1hyZ1WaIH43avUCaDnrZcOKB7wc1ats1aQ"
+            + "TSDLImyFn4KjSo5k0Ec/xSoWnfg391vebp8eOsyHZhFMffFtKQMaayZNHJ7Q"
+            + "BzG3r/ysUbkgI5x+0bX0QfZjEIs7yuV5Wt8DxMTueCm3RQ+HkR4lNdTBkM4V"
+            + "qozCqC1SjcAF5YHB0WFkGouEPGgTlmyvLqR2xerEXVZn9YwSnT48kOde3oGt"
+            + "EAYyg0yHbNbL0sp6LDM7upRmrgWwxf0BR6lP4wyWdv/XSLatEB7twSNiPBJ4"
+            + "PJ+QagK08yQJ84UB7YpMTudKsaUs7zW76eA7KkW3TndfDYGdhbmZ5wxNl+5x"
+            + "yPZc/jcQHW7vplMfWglUVxnzibNW12th0QXSB57Mzk8v1Rvc/HLGvAOJZG/S"
+            + "N12FZOxbUrMIHGi3kXsmfWznVyq92X4P9tuDDD7sxkSGsyUAm/UJIZ3KsXhV"
+            + "QeaRHVTVDxtJtnbYxBupy1FDBO6AhVrp16Blvnip9cPn/aLfxDoFHzmsZmEg"
+            + "IcOFqpT1fW+KN6i/JxLD3mn3gKzzdL1/8F36A2GxhCbefQFp0MfIovlnMLFv"
+            + "mrINwMP8a9VnP8gIV5oW5CxmmMUPHuGkXrfg+69iVACaC2sTq6KGebhtg9OC"
+            + "8vZhmu7+Eescst694pYa3b8Sbr5bTFXV68mMMjuRnhvF2NZgF+O0jzU+sFps"
+            + "o7s1rUloCBk1clJUJ/r+j9vbhVahCeJQw62JAqjZu4R1JYAzON3S7jWU5zJ7"
+            + "pWYPSAQkLYUz3FmRRS2Yv65mXDNHqR9vqkHTIphwA9CLMKC2rIONxSVB57q1"
+            + "Npa/TFkVdXnw+cmYjyFWiWeDP7Mw0Kwy7tO008UrBY0rKQU466RI5ezDqYPc"
+            + "Lm73dUH2EjUYmKUi8zCtXpzgfTYVa/DmkbVUL9ThHMVRq1OpT2nctE7kpXZk"
+            + "OsZjEZHZX4MCrSOlc10ZW7MJIRreWMs70n7JX7MISU+8fK6JKOuaQNG8XcQp"
+            + "5IrCTIH8vmN2rVt4UT8zgm640FtO3jWUxScvxCtUJJ49hGCwK+HwDDpO6fLw"
+            + "LFuybey+6hnAbtaDyqgsgDh2KN8GSkQT9wixqwQPWsMQ4h0xQixf4IMdFOjP"
+            + "ciwp3ul8KAp/q70i0xldWGqcDjUasx6WHKc++rFjVJjoVvijKgEhlod5wJIw"
+            + "BqQVMKRsXle07NS1MOB+CRTVW6mwBEhDDERL+ym2GT2Q4uSDzoolmLq2y5vL"
+            + "+RfDHuh3W0UeC3Q5D2bJclgMsVjgfQUN19iD+lPFp2xvLTaNWi5fYDn4uuJL"
+            + "lgVDXIMmM8I+Z2hlTXTM1Pldz2/UFe3QXTbYnjP6kfd7Bo2Webhhgs/YmSR2"
+            + "XPuA42tWNAAjlK77lETWodxi3UC7XELjZ9xoGPRbxjOklXXvev9v5Vo+vcmN"
+            + "0KrLXhLdkyHRSm81SRsWoadCTSyT8ibv66P00GOt+OlIUOt0YKSUkULQfPvC"
+            + "EgMpeTm1/9l8n9bJ6td5fpJFDqLDm+FpJX6T2sWevV/Tyt6aoDPuET5iHBHW"
+            + "PoHxKl8YPRHBf+nRWoh45QMGQWNSrJRDlO8oYOhdznh4wxLn3DXEfDr0Z7Kd"
+            + "gEg6xr1XCobBn6Gi7wWXp5FDTaRF41t7fH8VxPwwDa8Yfu3vsgB6q426kjAj"
+            + "Q77wx1QFIg8gOYopTOgqze1i4h1U8ehP9btznDD6OR8+hPsVKoXYGp8Ukkc7"
+            + "JBA0o8l9O2DSGh0StsD94UhdYzn+ri7ozkXFy2SHFT2/saC34NHLoIF0v/aw"
+            + "L9G506Dtz6xXOACZ4brCG+NNnPLIcGblXIrYTy4+sm0KSdsl6BGzYh9uc8tu"
+            + "tfCh+iDuhT0n+nfnvdCmPwonONFb53Is1+dz5sisILfjB7OPRW4ngyfjgfHm"
+            + "oxxHDC/N01uoJIdmQRIisLi2nLhG+si8+Puz0SyPaB820VuV2mp77Y2osTAB"
+            + "0hTDv/sU0DQjqcuepYPUMvMs3SlkEmaEzNSiu7xOOBQYB8FoK4PeOXDIW6n2"
+            + "0hv6iS17hcZ+8GdhwC4x2Swkxt99ikRM0AxWrh1lCk5BagVN5xG79c/ZQ1M7"
+            + "a0k3WTzYF1Y4d6QPNOYeOBP9+G7/a2o3hGXDRRXnFpO7gQtlXy9A15RfvsWH"
+            + "O+UuFsOTtuiiZk1qRgWW5nkSCPCl2rP1Z7bwr3VD7o6VYhNCSdjuFfxwgNbW"
+            + "x8t35dBn6xLkc6QcBs2SZaRxvPTSAfjON++Ke0iK5w3mec0Br4QSNB1B0Aza"
+            + "w3t3AleqPyJC6IP1OQl5bi+PA+h3YZthwQmcwgXgW9bWxNDqUjUPZfsnNNDX"
+            + "MU9ANDLjITxvwr3F3ZSfJyeeDdbhr3EJUTtnzzWC6157EL9dt0jdPO35V0w4"
+            + "iUyZIW1FcYlCJp6t6Sy9n3TmxeLbq2xML4hncJBClaDMOp2QfabJ0XEYrD8F"
+            + "jq+aDM0NEUHng+Gt9WNqnjc8GzNlhxTNm3eQ6gyM/9Ip154GhH6c9hsmkMy5"
+            + "DlMjGFpFnsSTNFka2+DOzumWUiXLGbe4M3RePl1N4MLwXrkR2llguQynyoqF"
+            + "Ptat2Ky5yW2q9+IQHY49NJTlsCpunE5HFkAK9rY/4lM4/Q7hVunP6U4a0Kbu"
+            + "beFuOQMKQlBZvcplnYBefXD79uarY/q7ui6nFHlqND5mlXMknMrsQk3papfp"
+            + "OpMS4T07rCTLek0ODtb5KsHdIF76NZXevko4+d/xbv7HLCUYd8xuOuqf+y4I"
+            + "VJiT1FmYtZd9w+ubfHrOfHxY+SBtN6fs02WAccZqBXUYzZEijRbN2YUv1OnG"
+            + "rfYe4EcfOu/Sa+wLbB7msYpLfvUfEO3iseKf4LXZkgtF5P610PBZR8edeSgr"
+            + "YZW+J0K78PRAl5nEi1mvzBxi9DyNf6iQ9mWLyyCmr9p9HGE+aCMKVCn9jfZH"
+            + "WeBDAJNYDcUh5NEckqJtbEc2S1FJM7yZBWLQUt3NCQvj+nvQT45osZ3BJvFg"
+            + "IcGJ0CysoblVz4fCLybrYxby9HP89WMLHqdqsIeVX8IJ3x84SqLPuzrqf9FT"
+            + "ZVYLo0F2oBjAzjT7obt9+NJc/psOMCg+OGQkAfwj3VNvaqkkQsVxSiozgxrC"
+            + "7KaTXuAL6eKKspman96kz4QVk9P0usUPii+LFnW4XYc0RNfgJVO6BgJT7pLX"
+            + "NWwv/izMIMNAqSiWfzHHRVkhq4f1TMSF91auXOSICpJb3QQ4XFh52Mgl8+zs"
+            + "fobsb0geyb49WqFrZhUu+X+8LfQztppGmiUpFL+8EW0aPHbfaf4y9J1/Wthy"
+            + "c28Yqu62j/ljXq4Qa21uaEkoxzH1wPKCoKM9TXJtZJ39Yl9cf119Qy4M6QsB"
+            + "6oMXExlMjqIMCCWaLXLRiqbc2Y7rZHgEr08msibdoYHbSkEl8U+Kii2p6Vdx"
+            + "zyiEIz4CadrFbrAzxmrR/+3u8JuBdq0K3KNR0WWx73BU+G0rgBX56GnP7Ixy"
+            + "fuvkRb4YfJUF4PkDa50BGVhybPrIhoFteT6bSh6LQtBm9c4Kop8Svx3ZbqOT"
+            + "kgQDa0n+O0iR7x3fvNZ0Wz4YJrKGnVOPCqJSlSsnX6v2JScmaNdrSwkMTnUf"
+            + "F9450Hasd88+skC4jVAv3WAB03Gz1MtiGDhdUKFnHnU9HeHUnh38peCFEfnK"
+            + "WihakVQNfc72YoFVZHeJI5fJAW8P7xGTZ95ysyirtirxt2zkRVJa5p7semOw"
+            + "bL/lBC1bp4J6xHF/NHY8NQjvuhqkDyNlh3dRpIBVBu6Z04hRhLFW6IBxcCCv"
+            + "pjfoxJoox9yxKQKpr3J6MiZKBlndZRbSogO/wYwFeh7HhUzMNM1xIy3jWVVC"
+            + "CrzWp+Q1uxnL74SwrMP/EcZh+jZO4CYWk6guUMhTo1kbW03BZfyAqbPM+X+e"
+            + "ZqMZljydH8AWgl0MZd2IAfajDxI03/6XZSgzq24n+J7wKMYWS3WzB98OIwr+"
+            + "oKoQ7aKwaaT/KtR8ggUVYsCLs4ScFY24MnjUvMm+gQcVyeX74UlqR30Aipnf"
+            + "qzDRVcAUMMNcs0fuqePcrZ/yxPo+P135YClPDo9J8bwNpioUY8g+BQxjEQTj"
+            + "py3i2rAoX+Z5fcGjnZQVPMog0niIvLPRJ1Xl7yzPW0SevhlnMo6uDYDjWgQ2"
+            + "TLeTehRCiSd3z7ZunYR3kvJIw1Kzo4YjdO3l3WNf3RQvxPmJcSKzeqKVxWxU"
+            + "QBMIC/dIzmRDcY787qjAlKDZOdDp7qBKIqnfodWolxBA0KhvE61eYabZqUCT"
+            + "G2HJaQE1SvOdL9KM4ORFlxE3/dqv8ttBJ6N1qKk423CJjajZHYTwf1dCfj8T"
+            + "VAE/A3INTc6vg02tfkig+7ebmbeXJRH93KveEo2Wi1xQDsWNA+3DVzsMyTqV"
+            + "+AgfSjjwKouXAznhpgNc5QjmD2I6RyTf+hngftve18ZmVhtlW5+K6qi62M7o"
+            + "aM83KweH1QgCS12/p2tMEAfz//pPbod2NrFDxnmozhp2ZnD04wC+6HGz6bX/"
+            + "h8x2PDaXrpuqnZREFEYzUDKQqxdglXj5oE/chBR8+eBfYSS4JW3TBkW6RfwM"
+            + "KOBBOOv8pe3Sfq/bg7OLq5bn0jKwulqP50bysZJNlQUG/KqJagKRx60fnTqB"
+            + "7gZRebvtqgn3JQU3fRCm8ikmGz9XHruoPlrUQJitWIt4AWFxjyl3oj+suLJn"
+            + "7sK62KwsqAztLV7ztoC9dxldJF34ykok1XQ2cMT+uSrD6ghYZrmrG5QDkiKW"
+            + "tOQCUvVh/CorZNlON2rt67UvueMoW+ua25K4pLKDW316c2hGZRf/jmCpRSdb"
+            + "Xr3RDaRFIK6JpmEiFMMOEnk9yf4rChnS6MHrun7vPkf82w6Q0VxoR8NRdFyW"
+            + "3mETtm2mmG5zPFMMD8uM0BYJ/mlJ2zUcD4P3hWZ8NRiU5y1kazvrC6v7NijV"
+            + "o459AKOasZUj1rDMlXDLPloTHT2ViURHh/8GKqFHi2PDhIjPYUlLR5IrPRAl"
+            + "3m6DLZ7/tvZ1hHEu9lUMMcjrt7EJ3ujS/RRkuxhrM9BFlwzpa2VK8eckuCHm"
+            + "j89UH5Nn7TvH964K67hp3TeV5DKV6WTJmtIoZKCxSi6FFzMlky73gHZM4Vur"
+            + "eccwycFHu+8o+tQqbIAVXaJvdDstHpluUCMtb2SzVmI0bxABXp5XrkOOCg8g"
+            + "EDZz1I7rKLFcyERSifhsnXaC5E99BY0DJ/7v668ZR3bE5cU7Pmo/YmJctK3n"
+            + "m8cThrYDXJNbUi0c5vrAs36ZQECn7BY/bdDDk2NPgi36UfePI8XsbezcyrUR"
+            + "ZZwT+uQ5LOB931NjD5GOMEb96cjmECONcRjB0uD7DoTiVeS3QoWmf7Yz4g0p"
+            + "v9894YWQgOl+CvmTERO4dxd7X5wJsM3Y0acGPwneDF+HtQrIpJlslm2DivEv"
+            + "sikc6DtAQrnVRSNDr67HPPeIpgzThbxH3bm5UjvnP/zcGV1W8Nzk/OBQWi0l"
+            + "fQM9DccS6P/DW3XPSD1+fDtUK5dfH8DFf8wwgnxeVwi/1hCBq9+33XPwiVpz"
+            + "489DnjGhHqq7BdHjTIqAZvNm8UPQfXRpeexbkFZx1mJvS7so54Cs58/hHgQN"
+            + "GHJh4AUCLEt0v7Hc3CMy38ovLr3Q8eZsyNGKO5GvGNa7EffGjzOKxgqtMwT2"
+            + "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
+{
+	/// <remarks>Set sorting test example.</remarks>
+	[TestFixture]
+	public class SetTest
+		: SimpleTest
+	{
+		public override string Name
+		{
+			get { return "Set"; }
+		}
+
+		private void checkSortedSet(
+			int		attempt,
+			Asn1Set	s)
+		{
+			if (s[0] is DerBoolean
+				&& s[1] is DerInteger
+				&& s[2] is DerBitString
+				&& s[3] is DerOctetString)
+			{
+				return;
+			}
+
+			Fail("sorting failed on attempt: " + attempt);
+		}
+
+		public override void PerformTest()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector();
+			byte[] data = new byte[10];
+
+			v.Add(new DerOctetString(data));
+			v.Add(new DerBitString(data));
+			v.Add(new DerInteger(100));
+			v.Add(DerBoolean.True);
+
+			checkSortedSet(0, new DerSet(v));
+
+			v = new Asn1EncodableVector();
+			v.Add(new DerInteger(100));
+			v.Add(DerBoolean.True);
+			v.Add(new DerOctetString(data));
+			v.Add(new DerBitString(data));
+
+			checkSortedSet(1, new DerSet(v));
+
+			v = new Asn1EncodableVector();
+			v.Add(DerBoolean.True);
+			v.Add(new DerOctetString(data));
+			v.Add(new DerBitString(data));
+			v.Add(new DerInteger(100));
+
+
+			checkSortedSet(2, new DerSet(v));
+
+			v = new Asn1EncodableVector();
+			v.Add(new DerBitString(data));
+			v.Add(new DerOctetString(data));
+			v.Add(new DerInteger(100));
+			v.Add(DerBoolean.True);
+
+			checkSortedSet(3, new DerSet(v));
+
+			v = new Asn1EncodableVector();
+			v.Add(new DerOctetString(data));
+			v.Add(new DerBitString(data));
+			v.Add(new DerInteger(100));
+			v.Add(DerBoolean.True);
+
+			Asn1Set s = new BerSet(v);
+
+			if (!(s[0] is DerOctetString))
+			{
+				Fail("BER set sort order changed.");
+			}
+
+			// create an implicitly tagged "set" without sorting
+			Asn1TaggedObject tag = new DerTaggedObject(false, 1, new DerSequence(v));
+			s = Asn1Set.GetInstance(tag, false);
+
+			if (s[0] is DerBoolean)
+			{
+				Fail("sorted when shouldn't be.");
+			}
+
+			// equality test
+			v = new Asn1EncodableVector();
+
+			v.Add(DerBoolean.True);
+			v.Add(DerBoolean.True);
+			v.Add(DerBoolean.True);
+
+			s = new DerSet(v);
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new SetTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+		    string resultText = Perform().ToString();
+
+		    Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/SignerLocationUnitTest.cs b/crypto/test/src/asn1/test/SignerLocationUnitTest.cs
new file mode 100644
index 000000000..bf20f1fda
--- /dev/null
+++ b/crypto/test/src/asn1/test/SignerLocationUnitTest.cs
@@ -0,0 +1,195 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Esf;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+    [TestFixture]
+    public class SignerLocationUnitTest
+        : SimpleTest
+    {
+        public override string Name
+        {
+			get { return "SignerLocation"; }
+        }
+
+		public override void PerformTest()
+        {
+            DerUtf8String countryName = new DerUtf8String("Australia");
+
+            SignerLocation sl = new SignerLocation(countryName, null, null);
+
+            CheckConstruction(sl, countryName, null, null);
+
+            DerUtf8String localityName = new DerUtf8String("Melbourne");
+
+            sl = new SignerLocation(null, localityName, null);
+
+			CheckConstruction(sl, null, localityName, null);
+
+			sl = new SignerLocation(countryName, localityName, null);
+
+			CheckConstruction(sl, countryName, localityName, null);
+
+			Asn1Sequence postalAddress = new DerSequence(
+				new DerUtf8String("line 1"),
+				new DerUtf8String("line 2"));
+
+            sl = new SignerLocation(null, null, postalAddress);
+
+            CheckConstruction(sl, null, null, postalAddress);
+
+            sl = new SignerLocation(countryName, null, postalAddress);
+
+            CheckConstruction(sl, countryName, null, postalAddress);
+
+            sl = new SignerLocation(countryName, localityName, postalAddress);
+
+            CheckConstruction(sl, countryName, localityName, postalAddress);
+
+            sl = SignerLocation.GetInstance(null);
+
+            if (sl != null)
+            {
+                Fail("null GetInstance() failed.");
+            }
+
+            try
+            {
+                SignerLocation.GetInstance(new object());
+
+                Fail("GetInstance() failed to detect bad object.");
+            }
+            catch (ArgumentException)
+            {
+                // expected
+            }
+
+            //
+            // out of range postal address
+            //
+			postalAddress = new DerSequence(
+				new DerUtf8String("line 1"),
+				new DerUtf8String("line 2"),
+				new DerUtf8String("line 3"),
+				new DerUtf8String("line 4"),
+				new DerUtf8String("line 5"),
+				new DerUtf8String("line 6"),
+				new DerUtf8String("line 7"));
+
+			try
+            {
+                new SignerLocation(null, null, postalAddress);
+
+                Fail("constructor failed to detect bad postalAddress.");
+            }
+            catch (ArgumentException)
+            {
+                // expected
+            }
+
+            try
+            {
+                new SignerLocation(new DerSequence(new DerTaggedObject(2, postalAddress)));
+
+                Fail("sequence constructor failed to detect bad postalAddress.");
+            }
+            catch (ArgumentException)
+            {
+                // expected
+            }
+
+            try
+            {
+                new SignerLocation(new DerSequence(new DerTaggedObject(5, postalAddress)));
+
+                Fail("sequence constructor failed to detect bad tag.");
+            }
+            catch (ArgumentException)
+            {
+                // expected
+            }
+        }
+
+		private void CheckConstruction(
+            SignerLocation sl,
+            DerUtf8String  countryName,
+            DerUtf8String  localityName,
+            Asn1Sequence   postalAddress)
+        {
+            CheckValues(sl, countryName, localityName, postalAddress);
+
+			sl = SignerLocation.GetInstance(sl);
+
+			CheckValues(sl, countryName, localityName, postalAddress);
+
+			Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(
+				sl.ToAsn1Object().GetEncoded());
+
+			sl = SignerLocation.GetInstance(seq);
+
+			CheckValues(sl, countryName, localityName, postalAddress);
+        }
+
+		private void CheckValues(
+            SignerLocation sl,
+            DerUtf8String  countryName,
+            DerUtf8String  localityName,
+            Asn1Sequence   postalAddress)
+        {
+            if (countryName != null)
+            {
+                if (!countryName.Equals(sl.CountryName))
+                {
+                    Fail("countryNames don't match.");
+                }
+            }
+            else if (sl.CountryName != null)
+            {
+                Fail("countryName found when none expected.");
+            }
+
+            if (localityName != null)
+            {
+                if (!localityName.Equals(sl.LocalityName))
+                {
+                    Fail("localityNames don't match.");
+                }
+            }
+            else if (sl.LocalityName != null)
+            {
+                Fail("localityName found when none expected.");
+            }
+
+            if (postalAddress != null)
+            {
+                if (!postalAddress.Equals(sl.PostalAddress))
+                {
+                    Fail("postalAddresses don't match.");
+                }
+            }
+            else if (sl.PostalAddress != null)
+            {
+                Fail("postalAddress found when none expected.");
+            }
+        }
+
+		public static void Main(
+			string[] args)
+        {
+            RunTest(new SignerLocationUnitTest());
+        }
+
+        [Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/asn1/test/StringTest.cs b/crypto/test/src/asn1/test/StringTest.cs
new file mode 100644
index 000000000..acfd380b2
--- /dev/null
+++ b/crypto/test/src/asn1/test/StringTest.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	/**
+	* X.690 test example
+	*/
+	[TestFixture]
+	public class StringTest
+		: SimpleTest
+	{
+		public override string Name
+		{
+			get { return "String"; }
+		}
+
+		public override void PerformTest()
+		{
+			DerBitString bs = new DerBitString(
+				new byte[] { (byte)0x01,(byte)0x23,(byte)0x45,(byte)0x67,(byte)0x89,(byte)0xab,(byte)0xcd,(byte)0xef });
+
+			if (!bs.GetString().Equals("#0309000123456789ABCDEF"))
+			{
+				Fail("DerBitString.GetString() result incorrect");
+			}
+
+			if (!bs.ToString().Equals("#0309000123456789ABCDEF"))
+			{
+				Fail("DerBitString.ToString() result incorrect");
+			}
+
+			bs = new DerBitString(
+				new byte[] { (byte)0xfe,(byte)0xdc,(byte)0xba,(byte)0x98,(byte)0x76,(byte)0x54,(byte)0x32,(byte)0x10 });
+
+			if (!bs.GetString().Equals("#030900FEDCBA9876543210"))
+			{
+				Fail("DerBitString.GetString() result incorrect");
+			}
+
+			if (!bs.ToString().Equals("#030900FEDCBA9876543210"))
+			{
+				Fail("DerBitString.ToString() result incorrect");
+			}
+
+			DerUniversalString us = new DerUniversalString(
+				new byte[] { (byte)0x01,(byte)0x23,(byte)0x45,(byte)0x67,(byte)0x89,(byte)0xab,(byte)0xcd,(byte)0xef });
+
+			if (!us.GetString().Equals("#1C080123456789ABCDEF"))
+			{
+				Fail("DerUniversalString.GetString() result incorrect");
+			}
+
+			if (!us.ToString().Equals("#1C080123456789ABCDEF"))
+			{
+				Fail("DerUniversalString.ToString() result incorrect");
+			}
+
+			us = new DerUniversalString(
+				new byte[] { (byte)0xfe,(byte)0xdc,(byte)0xba,(byte)0x98,(byte)0x76,(byte)0x54,(byte)0x32,(byte)0x10 });
+
+			if (!us.GetString().Equals("#1C08FEDCBA9876543210"))
+			{
+				Fail("DerUniversalString.GetString() result incorrect");
+			}
+
+			if (!us.ToString().Equals("#1C08FEDCBA9876543210"))
+			{
+				Fail("DerUniversalString.ToString() result incorrect");
+			}
+
+			byte[] t61Bytes = new byte[] { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8 };
+			string t61String = Encoding.GetEncoding("iso-8859-1").GetString(t61Bytes, 0, t61Bytes.Length);
+			DerT61String t61 = new DerT61String(t61Bytes);
+
+			if (!t61.GetString().Equals(t61String))
+			{
+				Fail("DerT61String.GetString() result incorrect");
+			}
+
+			if (!t61.ToString().Equals(t61String))
+			{
+				Fail("DerT61String.ToString() result incorrect");
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new StringTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/SubjectKeyIdentifierTest.cs b/crypto/test/src/asn1/test/SubjectKeyIdentifierTest.cs
new file mode 100644
index 000000000..127c47a3a
--- /dev/null
+++ b/crypto/test/src/asn1/test/SubjectKeyIdentifierTest.cs
@@ -0,0 +1,61 @@
+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 SubjectKeyIdentifierTest
+		: SimpleTest
+	{
+		private static byte[] pubKeyInfo = Base64.Decode(
+			"MFgwCwYJKoZIhvcNAQEBA0kAMEYCQQC6wMMmHYMZszT/7bNFMn+gaZoiWJLVP8ODRuu1C2jeAe" +
+			"QpxM+5Oe7PaN2GNy3nBE4EOYkB5pMJWA0y9n04FX8NAgED");
+
+		private static byte[] shaID = Hex.Decode("d8128a06d6c2feb0865994a2936e7b75b836a021");
+		private static byte[] shaTruncID = Hex.Decode("436e7b75b836a021");
+
+		public override string Name
+		{
+			get { return "SubjectKeyIdentifier"; }
+		}
+
+		public override void PerformTest()
+		{
+			SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.GetInstance(
+				Asn1Object.FromByteArray(pubKeyInfo));
+			SubjectKeyIdentifier ski = SubjectKeyIdentifier.CreateSha1KeyIdentifier(pubInfo);
+
+			if (!Arrays.AreEqual(shaID, ski.GetKeyIdentifier()))
+			{
+				Fail("SHA-1 ID does not match");
+			}
+
+			ski = SubjectKeyIdentifier.CreateTruncatedSha1KeyIdentifier(pubInfo);
+
+			if (!Arrays.AreEqual(shaTruncID, ski.GetKeyIdentifier()))
+			{
+				Fail("truncated SHA-1 ID does not match");
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new SubjectKeyIdentifierTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/TagTest.cs b/crypto/test/src/asn1/test/TagTest.cs
new file mode 100644
index 000000000..c5fce6dbc
--- /dev/null
+++ b/crypto/test/src/asn1/test/TagTest.cs
@@ -0,0 +1,115 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	/**
+	* X.690 test example
+	*/
+	[TestFixture]
+	public class TagTest
+		: SimpleTest
+	{
+		private static readonly byte[] longTagged = Base64.Decode(
+			  "ZSRzIp8gEEZFRENCQTk4NzY1NDMyMTCfIQwyMDA2MDQwMTEyMzSUCCAFERVz"
+			+ "A4kCAHEXGBkalAggBRcYGRqUCCAFZS6QAkRFkQlURUNITklLRVKSBQECAwQF"
+			+ "kxAREhMUFRYXGBkalAggBREVcwOJAgBxFxgZGpQIIAUXGBkalAggBWUukAJE"
+			+ "RZEJVEVDSE5JS0VSkgUBAgMEBZMQERITFBUWFxgZGpQIIAURFXMDiQIAcRcY"
+			+ "GRqUCCAFFxgZGpQIIAVlLpACREWRCVRFQ0hOSUtFUpIFAQIDBAWTEBESExQV"
+			+ "FhcYGRqUCCAFERVzA4kCAHEXGBkalAggBRcYGRqUCCAFFxgZGpQIIAUXGBka"
+			+ "lAg=");
+
+		private static readonly byte[] longAppSpecificTag = Hex.Decode("5F610101");
+
+		public override string Name
+		{
+			get { return "Tag"; }
+		}
+
+		public override void PerformTest()
+		{
+			DerApplicationSpecific app = (DerApplicationSpecific)
+				Asn1Object.FromByteArray(longTagged);
+
+			app = (DerApplicationSpecific) Asn1Object.FromByteArray(app.GetContents());
+
+			Asn1InputStream aIn = new Asn1InputStream(app.GetContents());
+
+			Asn1TaggedObject tagged = (Asn1TaggedObject) aIn.ReadObject();
+
+			if (tagged.TagNo != 32)
+			{
+				Fail("unexpected tag value found - not 32");
+			}
+
+			tagged = (Asn1TaggedObject) Asn1Object.FromByteArray(tagged.GetEncoded());
+
+			if (tagged.TagNo != 32)
+			{
+				Fail("unexpected tag value found on recode - not 32");
+			}
+
+			tagged = (Asn1TaggedObject) aIn.ReadObject();
+
+			if (tagged.TagNo != 33)
+			{
+				Fail("unexpected tag value found - not 33");
+			}
+
+			tagged = (Asn1TaggedObject) Asn1Object.FromByteArray(tagged.GetEncoded());
+
+			if (tagged.TagNo != 33)
+			{
+				Fail("unexpected tag value found on recode - not 33");
+			}
+
+			aIn = new Asn1InputStream(longAppSpecificTag);
+
+			app = (DerApplicationSpecific)aIn.ReadObject();
+
+			if (app.ApplicationTag != 97)
+			{
+				Fail("incorrect tag number read");
+			}
+
+			app = (DerApplicationSpecific)Asn1Object.FromByteArray(app.GetEncoded());
+
+			if (app.ApplicationTag != 97)
+			{
+				Fail("incorrect tag number read on recode");
+			}
+
+			SecureRandom sr = new SecureRandom();
+			for (int i = 0; i < 100; ++i)
+			{
+				int testTag = (sr.NextInt() & int.MaxValue) >> sr.Next(26);
+				app = new DerApplicationSpecific(testTag, new byte[]{ 1 });
+				app = (DerApplicationSpecific)Asn1Object.FromByteArray(app.GetEncoded());
+
+				if (app.ApplicationTag != testTag)
+				{
+					Fail("incorrect tag number read on recode (random test value: " + testTag + ")");
+				}
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new TagTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/TargetInformationTest.cs b/crypto/test/src/asn1/test/TargetInformationTest.cs
new file mode 100644
index 000000000..7fa04cd01
--- /dev/null
+++ b/crypto/test/src/asn1/test/TargetInformationTest.cs
@@ -0,0 +1,58 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class TargetInformationTest
+		: SimpleTest
+	{
+		public override string Name
+		{
+			get { return "TargetInformation"; }
+		}
+
+		public override void PerformTest()
+		{
+			Target[] targets = new Target[2];
+			Target targetName = new Target(Target.Choice.Name, new GeneralName(GeneralName.DnsName, "www.test.com"));
+			Target targetGroup = new Target(Target.Choice.Group, new GeneralName(GeneralName.DirectoryName, "o=Test, ou=Test"));
+			targets[0] = targetName;
+			targets[1] = targetGroup;
+			Targets targetss = new Targets(targets);
+			TargetInformation targetInformation1 = new TargetInformation(targetss);
+			// use an Target array
+			TargetInformation targetInformation2 = new TargetInformation(targets);
+			// targetInformation1 and targetInformation2 must have same
+			// encoding.
+			if (!targetInformation1.Equals(targetInformation2))
+			{
+				Fail("targetInformation1 and targetInformation2 should have the same encoding.");
+			}
+			TargetInformation targetInformation3 = TargetInformation.GetInstance(targetInformation1.ToAsn1Object());
+			TargetInformation targetInformation4 = TargetInformation.GetInstance(targetInformation2.ToAsn1Object());
+			if (!targetInformation3.Equals(targetInformation4))
+			{
+				Fail("targetInformation3 and targetInformation4 should have the same encoding.");
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new TargetInformationTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/TimeTest.cs b/crypto/test/src/asn1/test/TimeTest.cs
new file mode 100644
index 000000000..6f6bd6f2c
--- /dev/null
+++ b/crypto/test/src/asn1/test/TimeTest.cs
@@ -0,0 +1,28 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class TimeTest
+	{
+		[Test]
+		public void CheckCmsTimeVsX509Time()
+		{
+			DateTime now = DateTime.UtcNow;
+
+			// Time classes only have a resolution of seconds
+			now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
+
+			Org.BouncyCastle.Asn1.Cms.Time cmsTime = new Org.BouncyCastle.Asn1.Cms.Time(now);
+			Org.BouncyCastle.Asn1.X509.Time x509Time = new Org.BouncyCastle.Asn1.X509.Time(now);
+
+//			Assert.AreEqual(cmsTime.Date, x509Time.ToDateTime());
+			Assert.AreEqual(now, cmsTime.Date);
+			Assert.AreEqual(now, x509Time.ToDateTime());
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/TypeOfBiometricDataUnitTest.cs b/crypto/test/src/asn1/test/TypeOfBiometricDataUnitTest.cs
new file mode 100644
index 000000000..a59415c31
--- /dev/null
+++ b/crypto/test/src/asn1/test/TypeOfBiometricDataUnitTest.cs
@@ -0,0 +1,152 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509.Qualified;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+    [TestFixture]
+    public class TypeOfBiometricDataUnitTest
+        : SimpleTest
+    {
+        public override string Name
+        {
+			get { return "TypeOfBiometricData"; }
+        }
+
+		public override void PerformTest()
+        {
+            //
+            // predefined
+            //
+            CheckPredefinedType(TypeOfBiometricData.Picture);
+
+            CheckPredefinedType(TypeOfBiometricData.HandwrittenSignature);
+
+			//
+            // non-predefined
+            //
+            DerObjectIdentifier localType = new DerObjectIdentifier("1.1");
+
+			TypeOfBiometricData type = new TypeOfBiometricData(localType);
+
+			CheckNonPredefined(type, localType);
+
+            type = TypeOfBiometricData.GetInstance(type);
+
+            CheckNonPredefined(type, localType);
+
+            Asn1Object obj = type.ToAsn1Object();
+
+            type = TypeOfBiometricData.GetInstance(obj);
+
+            CheckNonPredefined(type, localType);
+
+            type = TypeOfBiometricData.GetInstance(null);
+
+            if (type != null)
+            {
+                Fail("null GetInstance() failed.");
+            }
+
+            try
+            {
+                TypeOfBiometricData.GetInstance(new object());
+
+                Fail("GetInstance() failed to detect bad object.");
+            }
+            catch (ArgumentException)
+            {
+                // expected
+            }
+
+            try
+            {
+                new TypeOfBiometricData(100);
+
+                Fail("constructor failed to detect bad predefined type.");
+            }
+            catch (ArgumentException)
+            {
+                // expected
+            }
+
+			// Call Equals to avoid unreachable code warning
+            if (!Equals(TypeOfBiometricData.Picture, 0))
+            {
+                Fail("predefined picture should be 0");
+            }
+
+			// Call Equals to avoid unreachable code warning
+			if (!Equals(TypeOfBiometricData.HandwrittenSignature, 1))
+			{
+                Fail("predefined handwritten signature should be 1");
+            }
+        }
+
+		private void CheckPredefinedType(
+            int predefinedType)
+        {
+            TypeOfBiometricData type = new TypeOfBiometricData(predefinedType);
+
+            CheckPredefined(type, predefinedType);
+
+            type = TypeOfBiometricData.GetInstance(type);
+
+			CheckPredefined(type, predefinedType);
+
+			Asn1Object obj = Asn1Object.FromByteArray(type.ToAsn1Object().GetEncoded());
+
+			type = TypeOfBiometricData.GetInstance(obj);
+
+			CheckPredefined(type, predefinedType);
+        }
+
+		private void CheckPredefined(
+            TypeOfBiometricData	type,
+            int					val)
+        {
+            if (!type.IsPredefined)
+            {
+                Fail("predefined type expected but not found.");
+            }
+
+			if (type.PredefinedBiometricType != val)
+            {
+                Fail("predefined type does not match.");
+            }
+        }
+
+		private void CheckNonPredefined(
+            TypeOfBiometricData type,
+            DerObjectIdentifier val)
+        {
+            if (type.IsPredefined)
+            {
+                Fail("predefined type found when not expected.");
+            }
+
+			if (!type.BiometricDataOid.Equals(val))
+            {
+                Fail("data oid does not match.");
+            }
+        }
+
+		public static void Main(
+            string[] args)
+        {
+            RunTest(new TypeOfBiometricDataUnitTest());
+        }
+
+		[Test]
+        public void TestFunction()
+        {
+            string resultText = Perform().ToString();
+
+            Assert.AreEqual(Name + ": Okay", resultText);
+        }
+    }
+}
diff --git a/crypto/test/src/asn1/test/UTCTimeTest.cs b/crypto/test/src/asn1/test/UTCTimeTest.cs
new file mode 100644
index 000000000..07abbc911
--- /dev/null
+++ b/crypto/test/src/asn1/test/UTCTimeTest.cs
@@ -0,0 +1,122 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	/**
+	* X.690 test example
+	*/
+	[TestFixture]
+	public class UtcTimeTest
+		: SimpleTest
+	{
+		private static readonly string[] input =
+		{
+			"020122122220Z",
+			"020122122220-1000",
+			"020122122220+1000",
+			"020122122220+00",
+			"0201221222Z",
+			"0201221222-1000",
+			"0201221222+1000",
+			"0201221222+00",
+			"550122122220Z",
+			"5501221222Z"
+		};
+
+		private static readonly string[] output =
+		{
+			"20020122122220GMT+00:00",
+			"20020122122220GMT-10:00",
+			"20020122122220GMT+10:00",
+			"20020122122220GMT+00:00",
+			"20020122122200GMT+00:00",
+			"20020122122200GMT-10:00",
+			"20020122122200GMT+10:00",
+			"20020122122200GMT+00:00",
+			"19550122122220GMT+00:00",
+			"19550122122200GMT+00:00"
+		};
+
+		private static readonly string[] zOutput1 =
+		{
+			"20020122122220Z",
+			"20020122222220Z",
+			"20020122022220Z",
+			"20020122122220Z",
+			"20020122122200Z",
+			"20020122222200Z",
+			"20020122022200Z",
+			"20020122122200Z",
+			"19550122122220Z",
+			"19550122122200Z"
+		};
+
+		private static readonly string[] zOutput2 =
+		{
+			"20020122122220Z",
+			"20020122222220Z",
+			"20020122022220Z",
+			"20020122122220Z",
+			"20020122122200Z",
+			"20020122222200Z",
+			"20020122022200Z",
+			"20020122122200Z",
+			"19550122122220Z",
+			"19550122122200Z"
+		};
+
+		public override string Name
+		{
+			get { return "UTCTime"; }
+		}
+
+		public override void PerformTest()
+		{
+//			SimpleDateFormat yyyyF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
+//			SimpleDateFormat yyF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
+
+//			yyyyF.setTimeZone(new SimpleTimeZone(0,"Z"));
+//			yyF.setTimeZone(new SimpleTimeZone(0,"Z"));
+
+			for (int i = 0; i != input.Length; i++)
+			{
+				DerUtcTime t = new DerUtcTime(input[i]);
+
+				if (!t.AdjustedTimeString.Equals(output[i]))
+				{
+					Fail("failed conversion test " + i);
+				}
+
+//				if (!yyyyF.format(t.getAdjustedDate()).Equals(zOutput1[i]))
+				if (!t.ToAdjustedDateTime().ToString(@"yyyyMMddHHmmss\Z").Equals(zOutput1[i]))
+				{
+					Fail("failed date conversion test " + i);
+				}
+
+//				if (!yyF.format(t.getDate()).Equals(zOutput2[i]))
+				if (!t.ToDateTime().ToString(@"yyyyMMddHHmmss\Z").Equals(zOutput2[i]))
+				{
+					Fail("failed date shortened conversion test " + i);
+				}
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new UtcTimeTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/X509ExtensionsTest.cs b/crypto/test/src/asn1/test/X509ExtensionsTest.cs
new file mode 100644
index 000000000..f1efd3a9b
--- /dev/null
+++ b/crypto/test/src/asn1/test/X509ExtensionsTest.cs
@@ -0,0 +1,117 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class X509ExtensionsTest
+		: SimpleTest
+	{
+		private static readonly DerObjectIdentifier Oid1 = new DerObjectIdentifier("1.2.1");
+		private static readonly DerObjectIdentifier Oid2 = new DerObjectIdentifier("1.2.2");
+		private static readonly DerObjectIdentifier Oid3 = new DerObjectIdentifier("1.2.3");
+
+		public override string Name
+		{
+			get { return "X509Extensions"; }
+		}
+
+		public override void PerformTest()
+		{
+			X509ExtensionsGenerator gen = new X509ExtensionsGenerator();
+
+			gen.AddExtension(Oid1, true, new byte[20]);
+			gen.AddExtension(Oid2, true, new byte[20]);
+
+			X509Extensions ext1 = gen.Generate();
+			X509Extensions ext2 = gen.Generate();
+
+			if (!ext1.Equals(ext2))
+			{
+				Fail("Equals test failed");
+			}
+
+			gen.Reset();
+
+			gen.AddExtension(Oid2, true, new byte[20]);
+			gen.AddExtension(Oid1, true, new byte[20]);
+
+			ext2 = gen.Generate();
+
+			if (ext1.Equals(ext2))
+			{
+				Fail("inequality test failed");
+			}
+
+			if (!ext1.Equivalent(ext2))
+			{
+				Fail("equivalence true failed");
+			}
+
+			gen.Reset();
+
+			gen.AddExtension(Oid1, true, new byte[22]);
+			gen.AddExtension(Oid2, true, new byte[20]);
+
+			ext2 = gen.Generate();
+
+			if (ext1.Equals(ext2))
+			{
+				Fail("inequality 1 failed");
+			}
+
+			if (ext1.Equivalent(ext2))
+			{
+				Fail("non-equivalence 1 failed");
+			}
+
+			gen.Reset();
+
+			gen.AddExtension(Oid3, true, new byte[20]);
+			gen.AddExtension(Oid2, true, new byte[20]);
+
+			ext2 = gen.Generate();
+
+			if (ext1.Equals(ext2))
+			{
+				Fail("inequality 2 failed");
+			}
+
+			if (ext1.Equivalent(ext2))
+			{
+				Fail("non-equivalence 2 failed");
+			}
+
+			try
+			{
+				gen.AddExtension(Oid2, true, new byte[20]);
+				Fail("repeated oid");
+			}
+			catch (ArgumentException e)
+			{
+				if (!e.Message.Equals("extension 1.2.2 already added"))
+				{
+					Fail("wrong exception on repeated oid: " + e.Message);
+				}
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new X509ExtensionsTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/asn1/test/X509NameTest.cs b/crypto/test/src/asn1/test/X509NameTest.cs
new file mode 100644
index 000000000..7a0832c3e
--- /dev/null
+++ b/crypto/test/src/asn1/test/X509NameTest.cs
@@ -0,0 +1,674 @@
+using System;
+using System.Collections;
+using System.IO;
+
+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 X509NameTest
+		: SimpleTest
+	{
+		private static readonly string[] subjects =
+		{
+			"C=AU,ST=Victoria,L=South Melbourne,O=Connect 4 Pty Ltd,OU=Webserver Team,CN=www2.connect4.com.au,E=webmaster@connect4.com.au",
+			"C=AU,ST=Victoria,L=South Melbourne,O=Connect 4 Pty Ltd,OU=Certificate Authority,CN=Connect 4 CA,E=webmaster@connect4.com.au",
+			"C=AU,ST=QLD,CN=SSLeay/rsa test cert",
+			"C=US,O=National Aeronautics and Space Administration,SERIALNUMBER=16+CN=Steve Schoch",
+			"E=cooke@issl.atl.hp.com,C=US,OU=Hewlett Packard Company (ISSL),CN=Paul A. Cooke",
+			"O=Sun Microsystems Inc,CN=store.sun.com",
+			"unstructuredAddress=192.168.1.33,unstructuredName=pixfirewall.ciscopix.com,CN=pixfirewall.ciscopix.com"
+		};
+
+		public override string Name
+		{
+			get { return "X509Name"; }
+		}
+
+		private static X509Name FromBytes(
+			byte[] bytes)
+		{
+			return X509Name.GetInstance(Asn1Object.FromByteArray(bytes));
+		}
+
+		private IAsn1Convertible createEntryValue(
+			DerObjectIdentifier	oid,
+			string				value)
+		{
+			IDictionary attrs = new Hashtable();
+			attrs.Add(oid, value);
+
+			IList ord = new ArrayList();
+			ord.Add(oid);
+
+			X509Name name = new X509Name(ord, attrs);
+
+			Asn1Sequence seq = (Asn1Sequence)name.ToAsn1Object();
+			Asn1Set set = (Asn1Set)seq[0];
+			seq = (Asn1Sequence)set[0];
+
+			return seq[1];
+		}
+
+		private IAsn1Convertible createEntryValueFromString(
+			DerObjectIdentifier	oid,
+			string				val)
+		{
+			IDictionary attrs = new Hashtable();
+			attrs.Add(oid, val);
+
+			IList ord = new ArrayList(attrs.Keys);
+
+			X509Name name = new X509Name(new X509Name(ord, attrs).ToString());
+
+			Asn1Sequence seq = (Asn1Sequence) name.ToAsn1Object();
+			Asn1Set asn1Set = (Asn1Set) seq[0];
+			seq = (Asn1Sequence) asn1Set[0];
+
+			return seq[1];
+		}
+
+		private void doTestEncodingPrintableString(
+			DerObjectIdentifier	oid,
+			string				value)
+		{
+			IAsn1Convertible converted = createEntryValue(oid, value);
+			if (!(converted is DerPrintableString))
+			{
+				Fail("encoding for " + oid + " not printable string");
+			}
+		}
+
+		private void doTestEncodingIA5String(
+			DerObjectIdentifier oid,
+			string				value)
+		{
+			IAsn1Convertible converted = createEntryValue(oid, value);
+			if (!(converted is DerIA5String))
+			{
+				Fail("encoding for " + oid + " not IA5String");
+			}
+		}
+
+		private void doTestEncodingGeneralizedTime(
+			DerObjectIdentifier	oid,
+			string				val)
+		{
+			IAsn1Convertible converted = createEntryValue(oid, val);
+			if (!(converted is DerGeneralizedTime))
+			{
+				Fail("encoding for " + oid + " not GeneralizedTime");
+			}
+			converted = createEntryValueFromString(oid, val);
+			if (!(converted is DerGeneralizedTime))
+			{
+				Fail("encoding for " + oid + " not GeneralizedTime");
+			}
+		}
+
+		public override void PerformTest()
+		{
+			doTestEncodingPrintableString(X509Name.C, "AU");
+			doTestEncodingPrintableString(X509Name.SerialNumber, "123456");
+			doTestEncodingPrintableString(X509Name.DnQualifier, "123456");
+			doTestEncodingIA5String(X509Name.EmailAddress, "test@test.com");
+			doTestEncodingIA5String(X509Name.DC, "test");
+			// correct encoding
+			doTestEncodingGeneralizedTime(X509Name.DateOfBirth, "#180F32303032303132323132323232305A");
+			// compatability encoding
+			doTestEncodingGeneralizedTime(X509Name.DateOfBirth, "20020122122220Z");
+
+			//
+			// composite
+			//
+			IDictionary attrs = new Hashtable();
+			attrs.Add(X509Name.C, "AU");
+			attrs.Add(X509Name.O, "The Legion of the Bouncy Castle");
+			attrs.Add(X509Name.L, "Melbourne");
+			attrs.Add(X509Name.ST, "Victoria");
+			attrs.Add(X509Name.E, "feedback-crypto@bouncycastle.org");
+
+			IList order = new ArrayList();
+			order.Add(X509Name.C);
+			order.Add(X509Name.O);
+			order.Add(X509Name.L);
+			order.Add(X509Name.ST);
+			order.Add(X509Name.E);
+
+			X509Name name1 = new X509Name(order, attrs);
+
+			if (!name1.Equivalent(name1))
+			{
+				Fail("Failed same object test");
+			}
+
+			if (!name1.Equivalent(name1, true))
+			{
+				Fail("Failed same object test - in Order");
+			}
+
+			X509Name name2 = new X509Name(order, attrs);
+
+			if (!name1.Equivalent(name2))
+			{
+				Fail("Failed same name test");
+			}
+
+			if (!name1.Equivalent(name2, true))
+			{
+				Fail("Failed same name test - in Order");
+			}
+
+			if (name1.GetHashCode() != name2.GetHashCode())
+			{
+				Fail("Failed same name test - in Order");
+			}
+
+			IList ord1 = new ArrayList();
+
+			ord1.Add(X509Name.C);
+			ord1.Add(X509Name.O);
+			ord1.Add(X509Name.L);
+			ord1.Add(X509Name.ST);
+			ord1.Add(X509Name.E);
+
+			IList ord2 = new ArrayList();
+
+			ord2.Add(X509Name.E);
+			ord2.Add(X509Name.ST);
+			ord2.Add(X509Name.L);
+			ord2.Add(X509Name.O);
+			ord2.Add(X509Name.C);
+
+			name1 = new X509Name(ord1, attrs);
+			name2 = new X509Name(ord2, attrs);
+
+			if (!name1.Equivalent(name2))
+			{
+				Fail("Failed reverse name test");
+			}
+
+			// FIXME Sort out X509Name hashcode problem
+//			if (name1.GetHashCode() != name2.GetHashCode())
+//			{
+//				Fail("Failed reverse name test GetHashCode");
+//			}
+
+			if (name1.Equivalent(name2, true))
+			{
+				Fail("Failed reverse name test - in Order");
+			}
+
+			if (!name1.Equivalent(name2, false))
+			{
+				Fail("Failed reverse name test - in Order false");
+			}
+
+			IList oids = name1.GetOidList();
+			if (!CompareVectors(oids, ord1))
+			{
+				Fail("oid comparison test");
+			}
+
+			IList val1 = new ArrayList();
+
+			val1.Add("AU");
+			val1.Add("The Legion of the Bouncy Castle");
+			val1.Add("Melbourne");
+			val1.Add("Victoria");
+			val1.Add("feedback-crypto@bouncycastle.org");
+
+			name1 = new X509Name(ord1, val1);
+
+			IList values = name1.GetValueList();
+			if (!CompareVectors(values, val1))
+			{
+				Fail("value comparison test");
+			}
+
+			ord2 = new ArrayList();
+
+			ord2.Add(X509Name.ST);
+			ord2.Add(X509Name.ST);
+			ord2.Add(X509Name.L);
+			ord2.Add(X509Name.O);
+			ord2.Add(X509Name.C);
+
+			name1 = new X509Name(ord1, attrs);
+			name2 = new X509Name(ord2, attrs);
+
+			if (name1.Equivalent(name2))
+			{
+				Fail("Failed different name test");
+			}
+
+			ord2 = new ArrayList();
+
+			ord2.Add(X509Name.ST);
+			ord2.Add(X509Name.L);
+			ord2.Add(X509Name.O);
+			ord2.Add(X509Name.C);
+
+			name1 = new X509Name(ord1, attrs);
+			name2 = new X509Name(ord2, attrs);
+
+			if (name1.Equivalent(name2))
+			{
+				Fail("Failed subset name test");
+			}
+
+
+			compositeTest();
+
+
+			//
+			// getValues test
+			//
+			ArrayList v1 = name1.GetValues(X509Name.O);
+
+			if (v1.Count != 1 || !v1[0].Equals("The Legion of the Bouncy Castle"))
+			{
+				Fail("O test failed");
+			}
+
+			ArrayList v2 = name1.GetValues(X509Name.L);
+
+			if (v2.Count != 1 || !v2[0].Equals("Melbourne"))
+			{
+				Fail("L test failed");
+			}
+
+			//
+			// general subjects test
+			//
+			for (int i = 0; i != subjects.Length; i++)
+			{
+				X509Name name = new X509Name(subjects[i]);
+				byte[] encodedName = name.GetEncoded();
+				name = X509Name.GetInstance(Asn1Object.FromByteArray(encodedName));
+
+				if (!name.ToString().Equals(subjects[i]))
+				{
+					Fail("Failed regeneration test " + i);
+				}
+			}
+
+			//
+			// sort test
+			//
+			X509Name unsorted = new X509Name("SERIALNUMBER=BBB + CN=AA");
+
+			if (!FromBytes(unsorted.GetEncoded()).ToString().Equals("CN=AA+SERIALNUMBER=BBB"))
+			{
+				Fail("Failed sort test 1");
+			}
+
+			unsorted = new X509Name("CN=AA + SERIALNUMBER=BBB");
+
+			if (!FromBytes(unsorted.GetEncoded()).ToString().Equals("CN=AA+SERIALNUMBER=BBB"))
+			{
+				Fail("Failed sort test 2");
+			}
+
+			unsorted = new X509Name("SERIALNUMBER=B + CN=AA");
+
+			if (!FromBytes(unsorted.GetEncoded()).ToString().Equals("SERIALNUMBER=B+CN=AA"))
+			{
+				Fail("Failed sort test 3");
+			}
+
+			unsorted = new X509Name("CN=AA + SERIALNUMBER=B");
+
+			if (!FromBytes(unsorted.GetEncoded()).ToString().Equals("SERIALNUMBER=B+CN=AA"))
+			{
+				Fail("Failed sort test 4");
+			}
+
+			//
+			// equality tests
+			//
+			equalityTest(new X509Name("CN=The     Legion"), new X509Name("CN=The Legion"));
+			equalityTest(new X509Name("CN=   The Legion"), new X509Name("CN=The Legion"));
+			equalityTest(new X509Name("CN=The Legion   "), new X509Name("CN=The Legion"));
+			equalityTest(new X509Name("CN=  The     Legion "), new X509Name("CN=The Legion"));
+			equalityTest(new X509Name("CN=  the     legion "), new X509Name("CN=The Legion"));
+
+			// # test
+
+			X509Name n1 = new X509Name("SERIALNUMBER=8,O=ABC,CN=ABC Class 3 CA,C=LT");
+			X509Name n2 = new X509Name("2.5.4.5=8,O=ABC,CN=ABC Class 3 CA,C=LT");
+			X509Name n3 = new X509Name("2.5.4.5=#130138,O=ABC,CN=ABC Class 3 CA,C=LT");
+
+			equalityTest(n1, n2);
+			equalityTest(n2, n3);
+			equalityTest(n3, n1);
+
+			n1 = new X509Name(true, "2.5.4.5=#130138,CN=SSC Class 3 CA,O=UAB Skaitmeninio sertifikavimo centras,C=LT");
+			n2 = new X509Name(true, "SERIALNUMBER=#130138,CN=SSC Class 3 CA,O=UAB Skaitmeninio sertifikavimo centras,C=LT");
+			n3 = X509Name.GetInstance(Asn1Object.FromByteArray(Hex.Decode("3063310b3009060355040613024c54312f302d060355040a1326"
+				+ "55414220536b6169746d656e696e696f20736572746966696b6176696d6f2063656e74726173311730150603550403130e53534320436c6173732033204341310a30080603550405130138")));
+
+			equalityTest(n1, n2);
+			equalityTest(n2, n3);
+			equalityTest(n3, n1);
+
+			n1 = new X509Name("SERIALNUMBER=8,O=XX,CN=ABC Class 3 CA,C=LT");
+			n2 = new X509Name("2.5.4.5=8,O=,CN=ABC Class 3 CA,C=LT");
+
+			if (n1.Equivalent(n2))
+			{
+				Fail("empty inequality check failed");
+			}
+
+			n1 = new X509Name("SERIALNUMBER=8,O=,CN=ABC Class 3 CA,C=LT");
+			n2 = new X509Name("2.5.4.5=8,O=,CN=ABC Class 3 CA,C=LT");
+
+			equalityTest(n1, n2);
+
+			//
+			// inequality to sequences
+			//
+			name1 = new X509Name("CN=The Legion");
+
+			if (name1.Equals(DerSequence.Empty))
+			{
+				Fail("inequality test with sequence");
+			}
+
+			if (name1.Equals(new DerSequence(DerSet.Empty)))
+			{
+				Fail("inequality test with sequence and set");
+			}
+
+			Asn1EncodableVector v = new Asn1EncodableVector(
+				new DerObjectIdentifier("1.1"),
+				new DerObjectIdentifier("1.1"));
+
+			if (name1.Equals(new DerSequence(new DerSet(new DerSet(v)))))
+			{
+				Fail("inequality test with sequence and bad set");
+			}
+
+//			if (name1.Equals(new DerSequence(new DerSet(new DerSet(v))), true))
+//			{
+//				Fail("inequality test with sequence and bad set");
+//			}
+			try
+			{
+				X509Name.GetInstance(new DerSequence(new DerSet(new DerSet(v))));
+				Fail("GetInstance should reject bad sequence");
+			}
+			catch (ArgumentException)
+			{
+				//expected
+			}
+
+			if (name1.Equals(new DerSequence(new DerSet(DerSequence.Empty))))
+			{
+				Fail("inequality test with sequence and short sequence");
+			}
+
+//			if (name1.Equals(new DerSequence(new DerSet(DerSequence.Empty)), true))
+//			{
+//				Fail("inequality test with sequence and short sequence");
+//			}
+			try
+			{
+				X509Name.GetInstance(new DerSequence(new DerSet(DerSequence.Empty)));
+				Fail("GetInstance should reject short sequence");
+			}
+			catch (ArgumentException)
+			{
+				//expected
+			}
+
+			v = new Asn1EncodableVector(
+				new DerObjectIdentifier("1.1"),
+				DerSequence.Empty);
+
+			if (name1.Equals(new DerSequence(new DerSet(new DerSequence(v)))))
+			{
+				Fail("inequality test with sequence and bad sequence");
+			}
+
+			if (name1.Equivalent(null))
+			{
+				Fail("inequality test with null");
+			}
+
+			if (name1.Equivalent(null, true))
+			{
+				Fail("inequality test with null");
+			}
+
+			//
+			// this is contrived but it checks sorting of sets with equal elements
+			//
+			unsorted = new X509Name("CN=AA + CN=AA + CN=AA");
+
+			//
+			// tagging test - only works if CHOICE implemented
+			//
+			/*
+			ASN1TaggedObject tag = new DERTaggedObject(false, 1, new X509Name("CN=AA"));
+
+			if (!tag.isExplicit())
+			{
+				Fail("failed to explicitly tag CHOICE object");
+			}
+
+			X509Name name = X509Name.getInstance(tag, false);
+
+			if (!name.equals(new X509Name("CN=AA")))
+			{
+				Fail("failed to recover tagged name");
+			}
+			*/
+
+			DerUtf8String testString = new DerUtf8String("The Legion of the Bouncy Castle");
+			byte[] encodedBytes = testString.GetEncoded();
+			string hexEncodedString = "#" + Hex.ToHexString(encodedBytes);
+
+			DerUtf8String converted = (DerUtf8String)
+				new X509DefaultEntryConverter().GetConvertedValue(
+				X509Name.L , hexEncodedString);
+
+			if (!converted.Equals(testString))
+			{
+				Fail("Failed X509DefaultEntryConverter test");
+			}
+
+			//
+			// try escaped.
+			//
+			converted = (DerUtf8String) new X509DefaultEntryConverter().GetConvertedValue(
+				X509Name.L , "\\" + hexEncodedString);
+
+			if (!converted.Equals(new DerUtf8String(hexEncodedString)))
+			{
+				Fail("Failed X509DefaultEntryConverter test got " + converted + " expected: " + hexEncodedString);
+			}
+
+			//
+			// try a weird value
+			//
+			X509Name n = new X509Name("CN=\\#nothex#string");
+
+			if (!n.ToString().Equals("CN=\\#nothex#string"))
+			{
+				Fail("# string not properly escaped.");
+			}
+
+			ArrayList vls = n.GetValues(X509Name.CN);
+			if (vls.Count != 1 || !vls[0].Equals("#nothex#string"))
+			{
+				Fail("Escaped # not reduced properly");
+			}
+
+			n = new X509Name("CN=\"a+b\"");
+
+			vls = n.GetValues(X509Name.CN);
+			if (vls.Count != 1 || !vls[0].Equals("a+b"))
+			{
+				Fail("Escaped + not reduced properly");
+			}
+
+			n = new X509Name("CN=a\\+b");
+
+			vls = n.GetValues(X509Name.CN);
+			if (vls.Count != 1 || !vls[0].Equals("a+b"))
+			{
+				Fail("Escaped + not reduced properly");
+			}
+
+			if (!n.ToString().Equals("CN=a\\+b"))
+			{
+				Fail("+ in string not properly escaped.");
+			}
+
+			n = new X509Name("CN=a\\=b");
+
+			vls = n.GetValues(X509Name.CN);
+			if (vls.Count != 1 || !vls[0].Equals("a=b"))
+			{
+				Fail("Escaped = not reduced properly");
+			}
+
+			if (!n.ToString().Equals("CN=a\\=b"))
+			{
+				Fail("= in string not properly escaped.");
+			}
+
+	        n = new X509Name("TELEPHONENUMBER=\"+61999999999\"");
+
+	        vls = n.GetValues(X509Name.TelephoneNumber);
+	        if (vls.Count != 1 || !vls[0].Equals("+61999999999"))
+	        {
+	            Fail("telephonenumber escaped + not reduced properly");
+	        }
+
+	        n = new X509Name("TELEPHONENUMBER=\\+61999999999");
+
+	        vls = n.GetValues(X509Name.TelephoneNumber);
+	        if (vls.Count != 1 || !vls[0].Equals("+61999999999"))
+	        {
+	            Fail("telephonenumber escaped + not reduced properly");
+	        }
+
+	        n = new X509Name(@"TELEPHONENUMBER=\+61999999999");
+
+	        vls = n.GetValues(X509Name.TelephoneNumber);
+	        if (vls.Count != 1 || !vls[0].Equals("+61999999999"))
+	        {
+	            Fail("telephonenumber escaped + not reduced properly");
+	        }
+		}
+
+		private void compositeTest()
+		{
+			//
+			// composite test
+			//
+			byte[] enc = Hex.Decode("305e310b300906035504061302415531283026060355040a0c1f546865204c6567696f6e206f662074686520426f756e637920436173746c653125301006035504070c094d656c626f75726e653011060355040b0c0a4173636f742056616c65");
+			X509Name n = X509Name.GetInstance(Asn1Object.FromByteArray(enc));
+
+			if (!n.ToString().Equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne+OU=Ascot Vale"))
+			{
+				Fail("Failed composite to string test got: " + n.ToString());
+			}
+
+            IDictionary symbols = X509Name.DefaultSymbols;
+			if (!n.ToString(true, symbols).Equals("L=Melbourne+OU=Ascot Vale,O=The Legion of the Bouncy Castle,C=AU"))
+			{
+                Fail("Failed composite to string test got: " + n.ToString(true, symbols));
+			}
+
+			n = new X509Name(true, "L=Melbourne+OU=Ascot Vale,O=The Legion of the Bouncy Castle,C=AU");
+			if (!n.ToString().Equals("C=AU,O=The Legion of the Bouncy Castle,L=Melbourne+OU=Ascot Vale"))
+			{
+				Fail("Failed composite to string reversal test got: " + n.ToString());
+			}
+
+			n = new X509Name("C=AU, O=The Legion of the Bouncy Castle, L=Melbourne + OU=Ascot Vale");
+
+			MemoryStream bOut = new MemoryStream();
+			Asn1OutputStream aOut = new Asn1OutputStream(bOut);
+
+			aOut.WriteObject(n);
+
+			byte[] enc2 = bOut.ToArray();
+
+			if (!Arrays.AreEqual(enc, enc2))
+			{
+				Fail("Failed composite string to encoding test");
+			}
+
+			//
+			// dud name test - handle empty DN without barfing.
+			//
+			n = new X509Name("C=CH,O=,OU=dummy,CN=mail@dummy.com");
+
+			n = X509Name.GetInstance(Asn1Object.FromByteArray(n.GetEncoded()));
+		}
+
+		private void equalityTest(
+			X509Name	x509Name,
+			X509Name	x509Name1)
+		{
+			if (!x509Name.Equivalent(x509Name1))
+			{
+				Fail("equality test failed for " + x509Name + " : " + x509Name1);
+			}
+
+			// FIXME Sort out X509Name hashcode problem
+//			if (x509Name.GetHashCode() != x509Name1.GetHashCode())
+//			{
+//				Fail("GetHashCode test failed for " + x509Name + " : " + x509Name1);
+//			}
+
+			if (!x509Name.Equivalent(x509Name1, true))
+			{
+				Fail("equality test failed for " + x509Name + " : " + x509Name1);
+			}
+		}
+
+		private bool CompareVectors(
+			IList	one,
+			IList	two)
+		{
+			if (one.Count != two.Count)
+				return false;
+
+			for (int i = 0; i < one.Count; ++i)
+			{
+				if (!one[i].Equals(two[i]))
+					return false;
+			}
+
+			return true;
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			ITest test = new X509NameTest();
+			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/X9Test.cs b/crypto/test/src/asn1/test/X9Test.cs
new file mode 100644
index 000000000..540cddb47
--- /dev/null
+++ b/crypto/test/src/asn1/test/X9Test.cs
@@ -0,0 +1,181 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.Sec;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Asn1.Tests
+{
+	[TestFixture]
+	public class X9Test
+		: SimpleTest
+	{
+		private static readonly byte[] namedPub = Base64.Decode("MBowEwYHKoZIzj0CAQYIKoZIzj0DAQEDAwADAQ==");
+		private static readonly byte[] expPub = Base64.Decode(
+			  "MIHfMIHXBgcqhkjOPQIBMIHLAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAA"
+			+ "AAAH///////zBXBB5///////////////9///////+AAAAAAAB///////wEHiVXBfoqMGZUsfTL"
+			+ "A9anUKMMJQEC1JiHF9m6FattPgMVAH1zdBaP/jRxtgqFdoahlHXTv6L/BB8DZ2iujhi7ks/PAF"
+			+ "yUmqLG2UhT0OZgu/hUsclQX+laAh5///////////////9///+XXetBs6YFfDxDIUZSZVECAQED"
+			+ "AwADAQ==");
+
+		private static readonly byte[] namedPriv = Base64.Decode("MCICAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQEECDAGAgEBBAEK");
+		private static readonly byte[] expPriv = Base64.Decode(
+			  "MIHnAgEAMIHXBgcqhkjOPQIBMIHLAgEBMCkGByqGSM49AQECHn///////////////3///////4"
+			+ "AAAAAAAH///////zBXBB5///////////////9///////+AAAAAAAB///////wEHiVXBfoqMGZU"
+			+ "sfTLA9anUKMMJQEC1JiHF9m6FattPgMVAH1zdBaP/jRxtgqFdoahlHXTv6L/BB8DZ2iujhi7ks"
+			+ "/PAFyUmqLG2UhT0OZgu/hUsclQX+laAh5///////////////9///+XXetBs6YFfDxDIUZSZVEC"
+			+ "AQEECDAGAgEBBAEU");
+
+		private void EncodePublicKey()
+		{
+			X9ECParameters ecP = X962NamedCurves.GetByOid(X9ObjectIdentifiers.Prime239v3);
+
+			if (X9IntegerConverter.GetByteLength(ecP.Curve) != 30)
+			{
+				Fail("wrong byte length reported for curve");
+			}
+
+			if (ecP.Curve.FieldSize != 239)
+			{
+				Fail("wrong field size reported for curve");
+			}
+
+			//
+			// named curve
+			//
+			X962Parameters _params = new X962Parameters(X9ObjectIdentifiers.Prime192v1);
+
+			X9ECPoint pPoint = new X9ECPoint(
+				new FpPoint(ecP.Curve, new FpFieldElement(BigInteger.Two, BigInteger.One),
+				new FpFieldElement(BigInteger.ValueOf(4), BigInteger.ValueOf(3)),
+				true));
+
+			Asn1OctetString p = (Asn1OctetString) pPoint.ToAsn1Object();
+
+			if (p == null)
+			{
+				Fail("failed to convert to ASN.1");
+			}
+
+			SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, _params), p.GetOctets());
+
+			if (!Arrays.AreEqual(info.GetEncoded(), namedPub))
+			{
+				Fail("failed public named generation");
+			}
+
+			Asn1Object o = Asn1Object.FromByteArray(namedPub);
+
+			if (!info.Equals(o))
+			{
+				Fail("failed public named equality");
+			}
+
+			//
+			// explicit curve parameters
+			//
+			_params = new X962Parameters(ecP);
+
+			info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, _params), p.GetOctets());
+
+			if (!Arrays.AreEqual(info.GetEncoded(), expPub))
+			{
+				Fail("failed public explicit generation");
+			}
+
+			o = Asn1Object.FromByteArray(expPub);
+
+			if (!info.Equals(o))
+			{
+				Fail("failed public explicit equality");
+			}
+		}
+
+		private void EncodePrivateKey()
+		{
+			X9ECParameters ecP = X962NamedCurves.GetByOid(X9ObjectIdentifiers.Prime239v3);
+
+			//
+			// named curve
+			//
+			X962Parameters _params = new X962Parameters(X9ObjectIdentifiers.Prime192v1);
+
+			X9ECPoint pPoint = new X9ECPoint(
+				new FpPoint(ecP.Curve, new FpFieldElement(BigInteger.Two, BigInteger.One),
+				new FpFieldElement(BigInteger.ValueOf(4), BigInteger.ValueOf(3)),
+				true));
+
+			Asn1OctetString p = (Asn1OctetString) pPoint.ToAsn1Object();
+
+			if (p == null)
+				Fail("failed to convert to ASN.1");
+
+			PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, _params), new ECPrivateKeyStructure(BigInteger.Ten).ToAsn1Object());
+
+			if (!Arrays.AreEqual(info.GetEncoded(), namedPriv))
+			{
+				Fail("failed private named generation");
+			}
+
+			Asn1Object o = Asn1Object.FromByteArray(namedPriv);
+
+			if (!info.Equals(o))
+			{
+				Fail("failed private named equality");
+			}
+
+			//
+			// explicit curve parameters
+			//
+			_params = new X962Parameters(ecP);
+
+			info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, _params), new ECPrivateKeyStructure(BigInteger.ValueOf(20)).ToAsn1Object());
+
+			if (!Arrays.AreEqual(info.GetEncoded(), expPriv))
+			{
+				Fail("failed private explicit generation");
+			}
+
+			o = Asn1Object.FromByteArray(expPriv);
+
+			if (!info.Equals(o))
+			{
+				Fail("failed private explicit equality");
+			}
+		}
+
+		public override void PerformTest()
+		{
+			EncodePublicKey();
+			EncodePrivateKey();
+		}
+
+		public override string Name
+		{
+			get { return "X9"; }
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new X9Test());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}