summary refs log tree commit diff
path: root/crypto/test/src/cms
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/test/src/cms')
-rw-r--r--crypto/test/src/cms/test/AllTests.cs35
-rw-r--r--crypto/test/src/cms/test/AuthenticatedDataStreamTest.cs113
-rw-r--r--crypto/test/src/cms/test/AuthenticatedDataTest.cs320
-rw-r--r--crypto/test/src/cms/test/CMSSampleMessages.cs147
-rw-r--r--crypto/test/src/cms/test/CMSTestUtil.cs480
-rw-r--r--crypto/test/src/cms/test/CompressedDataStreamTest.cs116
-rw-r--r--crypto/test/src/cms/test/CompressedDataTest.cs117
-rw-r--r--crypto/test/src/cms/test/EnvelopedDataStreamTest.cs537
-rw-r--r--crypto/test/src/cms/test/EnvelopedDataTest.cs866
-rw-r--r--crypto/test/src/cms/test/MiscDataStreamTest.cs221
-rw-r--r--crypto/test/src/cms/test/Rfc4134Test.cs344
-rw-r--r--crypto/test/src/cms/test/SignedDataStreamTest.cs1215
-rw-r--r--crypto/test/src/cms/test/SignedDataTest.cs1480
13 files changed, 5991 insertions, 0 deletions
diff --git a/crypto/test/src/cms/test/AllTests.cs b/crypto/test/src/cms/test/AllTests.cs
new file mode 100644
index 000000000..1ce3b7c8d
--- /dev/null
+++ b/crypto/test/src/cms/test/AllTests.cs
@@ -0,0 +1,35 @@
+using System;
+
+using NUnit.Core;
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Cms.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("CMS Tests");
+
+			suite.Add(new CompressedDataTest());
+            suite.Add(new CompressedDataStreamTest());
+			suite.Add(new EnvelopedDataTest());
+			suite.Add(new EnvelopedDataStreamTest());
+			suite.Add(new Rfc4134Test());
+			suite.Add(new SignedDataTest());
+			suite.Add(new SignedDataStreamTest());
+
+			return suite;
+        }
+    }
+}
diff --git a/crypto/test/src/cms/test/AuthenticatedDataStreamTest.cs b/crypto/test/src/cms/test/AuthenticatedDataStreamTest.cs
new file mode 100644
index 000000000..89a2174b7
--- /dev/null
+++ b/crypto/test/src/cms/test/AuthenticatedDataStreamTest.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.X509;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	[TestFixture]
+	public class AuthenticatedDataStreamTest
+	{
+		private const string SignDN = "O=Bouncy Castle, C=AU";
+
+		private static AsymmetricCipherKeyPair signKP;
+//		private static X509Certificate signCert;
+		//signCert = CmsTestUtil.MakeCertificate(_signKP, SignDN, _signKP, SignDN);
+
+//		private const string OrigDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU";
+
+//		private static AsymmetricCipherKeyPair origKP;
+		//origKP = CmsTestUtil.MakeKeyPair();
+//		private static X509Certificate origCert;
+		//origCert = CmsTestUtil.MakeCertificate(_origKP, OrigDN, _signKP, SignDN);
+
+		private const string ReciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
+
+		private static AsymmetricCipherKeyPair reciKP;
+		private static X509Certificate reciCert;
+
+		private static AsymmetricCipherKeyPair origECKP;
+		private static AsymmetricCipherKeyPair reciECKP;
+		private static X509Certificate reciECCert;
+
+		private static AsymmetricCipherKeyPair SignKP
+		{
+			get { return signKP == null ? (signKP = CmsTestUtil.MakeKeyPair()) : signKP; }
+		}
+
+		private static AsymmetricCipherKeyPair ReciKP
+		{
+			get { return reciKP == null ? (reciKP = CmsTestUtil.MakeKeyPair()) : reciKP; }
+		}
+
+		private static X509Certificate ReciCert
+		{
+			get { return reciCert == null ? (reciCert = CmsTestUtil.MakeCertificate(ReciKP, ReciDN, SignKP, SignDN)) : reciCert; }
+		}
+
+		private static AsymmetricCipherKeyPair OrigECKP
+		{
+			get { return origECKP == null ? (origECKP = CmsTestUtil.MakeECDsaKeyPair()) : origECKP; }
+		}
+
+		private static AsymmetricCipherKeyPair ReciECKP
+		{
+			get { return reciECKP == null ? (reciECKP = CmsTestUtil.MakeECDsaKeyPair()) : reciECKP; }
+		}
+
+		private static X509Certificate ReciECCert
+		{
+			get { return reciECCert == null ? (reciECCert = CmsTestUtil.MakeCertificate(ReciECKP, ReciDN, SignKP, SignDN)) : reciECCert; }
+		}
+
+		[Test]
+		public void TestKeyTransDESede()
+		{
+			tryKeyTrans(CmsAuthenticatedDataGenerator.DesEde3Cbc);
+		}
+
+		private void tryKeyTrans(
+			string macAlg)
+		{
+			byte[] data = Encoding.ASCII.GetBytes("Eric H. Echidna");
+
+			CmsAuthenticatedDataStreamGenerator adGen = new CmsAuthenticatedDataStreamGenerator();
+
+			adGen.AddKeyTransRecipient(ReciCert);
+
+			MemoryStream bOut = new MemoryStream();
+			Stream aOut = adGen.Open(bOut, macAlg);
+			aOut.Write(data, 0, data.Length);
+			aOut.Close();
+
+			CmsAuthenticatedDataParser ad = new CmsAuthenticatedDataParser(bOut.ToArray());
+
+			RecipientInformationStore recipients = ad.GetRecipientInfos();
+
+			Assert.AreEqual(ad.MacAlgOid, macAlg);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);
+
+				byte[] recData = recipient.GetContent(ReciKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+				Assert.IsTrue(Arrays.AreEqual(ad.GetMac(), recipient.GetMac()));
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/crypto/test/src/cms/test/AuthenticatedDataTest.cs b/crypto/test/src/cms/test/AuthenticatedDataTest.cs
new file mode 100644
index 000000000..0ad34a95b
--- /dev/null
+++ b/crypto/test/src/cms/test/AuthenticatedDataTest.cs
@@ -0,0 +1,320 @@
+using System;
+using System.Collections;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.X509;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	[TestFixture]
+	public class AuthenticatedDataTest
+	{
+		private const string SignDN = "O=Bouncy Castle, C=AU";
+
+		private static AsymmetricCipherKeyPair signKP;
+//		private static X509Certificate signCert;
+		//signCert = CmsTestUtil.MakeCertificate(_signKP, SignDN, _signKP, SignDN);
+
+//		private const string OrigDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU";
+
+//		private static AsymmetricCipherKeyPair origKP;
+		//origKP = CmsTestUtil.MakeKeyPair();
+//		private static X509Certificate origCert;
+		//origCert = CmsTestUtil.MakeCertificate(_origKP, OrigDN, _signKP, SignDN);
+
+		private const string ReciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
+
+		private static AsymmetricCipherKeyPair reciKP;
+		private static X509Certificate reciCert;
+
+		private static AsymmetricCipherKeyPair origECKP;
+		private static AsymmetricCipherKeyPair reciECKP;
+		private static X509Certificate reciECCert;
+
+		private static AsymmetricCipherKeyPair SignKP
+		{
+			get { return signKP == null ? (signKP = CmsTestUtil.MakeKeyPair()) : signKP; }
+		}
+
+		private static AsymmetricCipherKeyPair ReciKP
+		{
+			get { return reciKP == null ? (reciKP = CmsTestUtil.MakeKeyPair()) : reciKP; }
+		}
+
+		private static X509Certificate ReciCert
+		{
+			get { return reciCert == null ? (reciCert = CmsTestUtil.MakeCertificate(ReciKP, ReciDN, SignKP, SignDN)) : reciCert; }
+		}
+
+		private static AsymmetricCipherKeyPair OrigECKP
+		{
+			get { return origECKP == null ? (origECKP = CmsTestUtil.MakeECDsaKeyPair()) : origECKP; }
+		}
+
+		private static AsymmetricCipherKeyPair ReciECKP
+		{
+			get { return reciECKP == null ? (reciECKP = CmsTestUtil.MakeECDsaKeyPair()) : reciECKP; }
+		}
+
+		private static X509Certificate ReciECCert
+		{
+			get { return reciECCert == null ? (reciECCert = CmsTestUtil.MakeCertificate(ReciECKP, ReciDN, SignKP, SignDN)) : reciECCert; }
+		}
+		
+//		private static string          _signDN;
+//		private static KeyPair _signKP;
+//		private static X509Certificate _signCert;
+//	
+//		private static string          _origDN;
+//		private static KeyPair         _origKP;
+//		private static X509Certificate _origCert;
+//	
+//		private static string          _reciDN;
+//		private static KeyPair         _reciKP;
+//		private static X509Certificate _reciCert;
+//	
+//		private static KeyPair         _origEcKP;
+//		private static KeyPair         _reciEcKP;
+//		private static X509Certificate _reciEcCert;
+//	
+//		private static bool         _initialised = false;
+//	
+//		public bool DEBUG = true;
+//	
+//		private static void init()
+//		{
+//			if (!_initialised)
+//			{
+//			_initialised = true;
+//			
+//			_signDN   = "O=Bouncy Castle, C=AU";
+//			_signKP   = CmsTestUtil.makeKeyPair();
+//			_signCert = CmsTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN);
+//			
+//			_origDN   = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU";
+//			_origKP   = CmsTestUtil.makeKeyPair();
+//			_origCert = CmsTestUtil.makeCertificate(_origKP, _origDN, _signKP, _signDN);
+//			
+//			_reciDN   = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
+//			_reciKP   = CmsTestUtil.makeKeyPair();
+//			_reciCert = CmsTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN);
+//			
+//			_origEcKP = CmsTestUtil.makeEcDsaKeyPair();
+//			_reciEcKP = CmsTestUtil.makeEcDsaKeyPair();
+//			_reciEcCert = CmsTestUtil.makeCertificate(_reciEcKP, _reciDN, _signKP, _signDN);
+//			}
+//		}
+//	
+//		public void setUp()
+//		{
+//			init();
+//		}
+//		
+//		public AuthenticatedDataTest(string name)
+//		{
+//		super(name);
+//		}
+//		
+//		public static void main(string args[])
+//		{
+//		junit.textui.TestRunner.run(AuthenticatedDataTest.class);
+//		}
+//		
+//		public static Test suite()
+//		throws Exception
+//		{
+//		init();
+//		
+//		return new CMSTestSetup(new TestSuite(AuthenticatedDataTest.class));
+//		}
+
+		[Test]
+		public void TestKeyTransDESede()
+		{
+			tryKeyTrans(CmsAuthenticatedDataGenerator.DesEde3Cbc);
+		}
+		
+		[Test]
+		public void TestKEKDESede()
+		{
+			tryKekAlgorithm(CmsTestUtil.MakeDesEde192Key(), new DerObjectIdentifier("1.2.840.113549.1.9.16.3.6"));
+		}
+		
+		[Test]
+		public void TestPasswordAES256()
+		{
+			passwordTest(CmsAuthenticatedDataGenerator.Aes256Cbc);
+		}
+		
+		[Test]
+		public void TestECKeyAgree()
+		{
+			byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");
+
+			CmsAuthenticatedDataGenerator adGen = new CmsAuthenticatedDataGenerator();
+
+			adGen.AddKeyAgreementRecipient(CmsAuthenticatedDataGenerator.ECDHSha1Kdf, OrigECKP.Private, OrigECKP.Public, ReciECCert, CmsAuthenticatedDataGenerator.Aes128Wrap);
+
+			CmsAuthenticatedData ad = adGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsAuthenticatedDataGenerator.DesEde3Cbc);
+
+			RecipientInformationStore recipients = ad.GetRecipientInfos();
+
+			Assert.AreEqual(CmsAuthenticatedDataGenerator.DesEde3Cbc, ad.MacAlgOid);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				byte[] recData = recipient.GetContent(ReciECKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+				Assert.IsTrue(Arrays.AreEqual(ad.GetMac(), recipient.GetMac()));
+			}
+		}
+		
+		[Test]
+		public void TestEncoding()
+		{
+			byte[] data = Encoding.ASCII.GetBytes("Eric H. Echidna");
+
+			CmsAuthenticatedDataGenerator adGen = new CmsAuthenticatedDataGenerator();
+
+			adGen.AddKeyTransRecipient(ReciCert);
+
+			CmsAuthenticatedData ad = adGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsAuthenticatedDataGenerator.DesEde3Cbc);
+
+			ad = new CmsAuthenticatedData(ad.GetEncoded());
+
+			RecipientInformationStore recipients = ad.GetRecipientInfos();
+
+			Assert.AreEqual(CmsAuthenticatedDataGenerator.DesEde3Cbc, ad.MacAlgOid);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);
+
+				byte[] recData = recipient.GetContent(ReciKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+				Assert.IsTrue(Arrays.AreEqual(ad.GetMac(), recipient.GetMac()));
+			}
+		}
+
+		private void tryKeyTrans(string macAlg)
+		{
+			byte[] data = Encoding.ASCII.GetBytes("Eric H. Echidna");
+
+			CmsAuthenticatedDataGenerator adGen = new CmsAuthenticatedDataGenerator();
+
+			adGen.AddKeyTransRecipient(ReciCert);
+
+			CmsAuthenticatedData ad = adGen.Generate(
+				new CmsProcessableByteArray(data),
+				macAlg);
+
+			RecipientInformationStore recipients = ad.GetRecipientInfos();
+
+			Assert.AreEqual(ad.MacAlgOid, macAlg);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);
+
+				byte[] recData = recipient.GetContent(ReciKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+				Assert.IsTrue(Arrays.AreEqual(ad.GetMac(), recipient.GetMac()));
+			}
+		}
+		
+		private void tryKekAlgorithm(KeyParameter kek, DerObjectIdentifier algOid)
+		{
+			byte[] data = Encoding.ASCII.GetBytes("Eric H. Echidna");
+
+			CmsAuthenticatedDataGenerator adGen = new CmsAuthenticatedDataGenerator();
+
+			byte[] kekId = new byte[] { 1, 2, 3, 4, 5 };
+
+			// FIXME Will this work for macs?
+			string keyAlgorithm = ParameterUtilities.GetCanonicalAlgorithmName(algOid.Id);
+
+			adGen.AddKekRecipient(keyAlgorithm, kek, kekId);
+
+			CmsAuthenticatedData ad = adGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsAuthenticatedDataGenerator.DesEde3Cbc);
+
+			RecipientInformationStore recipients = ad.GetRecipientInfos();
+
+			Assert.AreEqual(CmsAuthenticatedDataGenerator.DesEde3Cbc, ad.MacAlgOid);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, algOid.Id);
+
+				byte[] recData = recipient.GetContent(kek);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+				Assert.IsTrue(Arrays.AreEqual(ad.GetMac(), recipient.GetMac()));
+			}
+		}
+		
+		private void passwordTest(string algorithm)
+		{
+			byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");
+
+			CmsAuthenticatedDataGenerator adGen = new CmsAuthenticatedDataGenerator();
+
+			adGen.AddPasswordRecipient(new Pkcs5Scheme2PbeKey("password".ToCharArray(), new byte[20], 5), algorithm);
+		
+			CmsAuthenticatedData ad = adGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsAuthenticatedDataGenerator.DesEde3Cbc);
+
+			RecipientInformationStore recipients = ad.GetRecipientInfos();
+
+			Assert.AreEqual(CmsAuthenticatedDataGenerator.DesEde3Cbc, ad.MacAlgOid);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (PasswordRecipientInformation recipient in c)
+			{
+				CmsPbeKey key = new Pkcs5Scheme2PbeKey("password".ToCharArray(), recipient.KeyDerivationAlgorithm);
+
+				byte[] recData = recipient.GetContent(key);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+				Assert.IsTrue(Arrays.AreEqual(ad.GetMac(), recipient.GetMac()));
+			}
+		}
+	}
+}
diff --git a/crypto/test/src/cms/test/CMSSampleMessages.cs b/crypto/test/src/cms/test/CMSSampleMessages.cs
new file mode 100644
index 000000000..ae4f60fd1
--- /dev/null
+++ b/crypto/test/src/cms/test/CMSSampleMessages.cs
@@ -0,0 +1,147 @@
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	internal class CmsSampleMessages
+	{
+		internal static readonly byte[] originatorMessage = Base64.Decode(
+			  "MIIYGgYJKoZIhvcNAQcDoIIYCzCCGAcCAQKgggRJoIIERTCCBEEwggIpAgkA"
+			+ "xS/+IvjTL8YwDQYJKoZIhvcNAQEFBQAwaTELMAkGA1UEBhMCVVMxGDAWBgNV"
+			+ "BAoTD1UuUy4gR292ZXJubWVudDESMBAGA1UECxMJSFNQRDEyTGFiMQ8wDQYD"
+			+ "VQQLEwZBZ2VudHMxGzAZBgNVBAMTEkhTUEQxMiBMYWIgQ0EgUm9vdDAeFw0w"
+			+ "NzA1MTQxNzEzMzRaFw0wODA1MTMxNzEzMzRaMFwxCzAJBgNVBAYTAlVTMRgw"
+			+ "FgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxEjAQBgNVBAsTCUhTUEQxMkxhYjEP"
+			+ "MA0GA1UECxMGQWdlbnRzMQ4wDAYDVQQDEwV1c2VyMTCCASIwDQYJKoZIhvcN"
+			+ "AQEBBQADggEPADCCAQoCggEBALC54HvfpSE3yq/EkpNCkUEV6a6Df3q4k8EM"
+			+ "dlg0nQSf2FgYh1GMiztw8SVjrF80l4+Hg5/FW2XN2kpVQBap/H5ziPYXenbi"
+			+ "VLJHCF9LVyYDOS7xGfRtQ+ZhFUcECtaCLJsR7HIiFyKZWGg0c3bFZvFkdZqT"
+			+ "8MMwjhcIVE1BptMqcGriqqMQAUKYmOguAOzMCTGAOxqBXYFmR68WtggVNMMc"
+			+ "5qU6S/4OxeCmaNSPG5p7pA1o4Cnv4aJF1mAPedVPQpAS4Lu2K9nNhRkug0yd"
+			+ "6nPaxgQudk5YxlreNOPKiAHApk9RhGVepGchJCFP2aIPu9tkIiSe3omezSZu"
+			+ "Sy/3F5UCAwEAATANBgkqhkiG9w0BAQUFAAOCAgEAGDxqVI4aR4XNfbk2MtXF"
+			+ "agNYZOswn85X84um9gG323qjYhroW0QDuy3CwtUwhH866mpnJyhJvKx3b8UE"
+			+ "7pZInoNEz1UVn+wgJVXMmaG5mfp3X6z0xDAEaKmDMJXl66wlFGG1iveGgcEi"
+			+ "oMkrxFJKvu/FXywzPvz2pXD9LQapogOQpVsvg/hed//wijDG94UBkhbHTZ53"
+			+ "6ODKuHGmooO6bgqJxKcVyLwQAq/lXGtLqODK9BDicfUzuhLWA0si7Y1daehj"
+			+ "fjgAqFGirqRtPDdk1jywoMJdDCQqocNqNGuu/+9ZoRNtY7XFbiN7h4s4KTkw"
+			+ "YqCph8g+RZYJVZJDw/+qc5ymYZiufbImA08D7x7IzqX9eeuAqKCebkxcK0Dz"
+			+ "eh/wT7Ff8csw0xqkkEbi5sTORogPexKGo9T1P4j/UbOyCHaIwFQVE67kYJqZ"
+			+ "U3BB7mGNE/dKru7jC7Aadorpj7P/EQ8sfoq5wC9r3wfFB1f5znN9ZfXd3zSU"
+			+ "Gxne2PGl3Ry4DhrhWGy/HqB+StPSkLPJL1RNtKkywtaJG1QBnrMnLNsV7T0R"
+			+ "mIDn69NkDkc59LAuB7yxwBmhYA7c7cHckdX3bE7zgN6yYdiyLyXr+ZQl+3J8"
+			+ "bBPN/IVSs5Wr1kK9RDrFX8MdP95LZxHlgMATwAqoEPe5r2tvvGBoajoIA2Tw"
+			+ "71QxggGSMIIBjgIBADB2MGkxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMu"
+			+ "IEdvdmVybm1lbnQxEjAQBgNVBAsTCUhTUEQxMkxhYjEPMA0GA1UECxMGQWdl"
+			+ "bnRzMRswGQYDVQQDExJIU1BEMTIgTGFiIENBIFJvb3QCCQDFL/4i+NMvyTAN"
+			+ "BgkqhkiG9w0BAQEFAASCAQCGpoi8DBLf6I2fwqVp9MPA5M0QNRnC34AMoc7N"
+			+ "/JGKM5dWcGNpN83yL9QmOfjgyxzwJ3L3e3hYdoXp9MNelzG5ssyyKw4NxRgM"
+			+ "C1aRPWx1R1aKee/NAgvBjN3FyDN3Pl4ACz2EMrDMmilR0zmSJkDBVbGjxNzs"
+			+ "ZPxtsBlHeLRky/K/ZrTy5jIheFcKt/0dNJiMsFh+677OlRhDihdLzYeV4RK1"
+			+ "5Iy1j18ls5rJMYh1fmZOx9T6wvlpw84IjFHzUcIxIBg8t1cUkncXbg1r+rxm"
+			+ "zIaalAKdYp58oMpjy9wV6E1mxgAM/lvE/jwiYP4/a6TsXTLDPNIxe9RZVdhA"
+			+ "GCPvMIISHQYJKoZIhvcNAQcBMBQGCCqGSIb3DQMHBAgQBLQIaeQQMYCCEfgv"
+			+ "FBzVKLnlRNCjs2JE/G8jBI8aduv6YQTYTt0ePh9JEHTmSi7ISbCDdAf5baKN"
+			+ "mzVGQJj87Srz3YyEmUcozxscWnWgVWpUbx0GJkjz6LqyGLQ3VnqUDG80xnXo"
+			+ "nQY5q4ko6avyMIDZ+zzI2fs9ChAlBjZ41Qb0FnwDPZBH3N43q+puVWesE4wj"
+			+ "LGftt63T4k2D/qMdg7fVfHkAsXPJIxkvR4vUrGEvxTl9e24146wYgCXe+66T"
+			+ "UcAMViNCMr8UiFQFQYSmuPcSTHgQHqEaBwYys6X+fe61yE16mUazs32yVH2v"
+			+ "Cyf1mG4/GAaSmqR/BIU7y7trGd+g/KaT1Kp76e+Rys9G/oakoeIH3Hkgdhmc"
+			+ "pFBPklIlgA57EocK5n84tFRv9n9cmsbOfy0EjEa6vU4ImMPZQS4iyhLCWD1u"
+			+ "tQziu5FyHSb9COveUPuGY2iTrOWG34rHIagNndXi1OuAIGQrLjbntHmogqxb"
+			+ "zkB+yojr+WBwY1efb8X+WQ2L+us9v31qNGA0wyfg4AC5FZur90rBxBq59UPz"
+			+ "JAVRD6NP5FRPdxuvHclDoGBoiMr9NXO3Uv0tJuYADHlWMQnUGoPEL7UxzuPJ"
+			+ "VAWuHpGiywzOcWMiFEiDSIZrv4RViIVIRhEtm2bO7Ta/AGTfvJcyb6ySexc1"
+			+ "aR5TWYOjqv1NaGAVQ1vPyqazH+g17y5wnBRj2c3nSMwksn/nC60e4ax+/yaE"
+			+ "Ls9Qou9a0L2IyQgDlvhBA4CcRGcHklhlzAovGBX2gWG31CK05doZhH7bRIrj"
+			+ "8h1XOF2izffrfWb6LcDcZptw5BQWT5XeyoKD4eNZfJ4ww+dMw4+0MkXPZEn6"
+			+ "Fqg+jam9ZioqXiw5Y6bdzxawefe6gvxeca3f53KDXEm4qFaVuDgyjNZhEmyB"
+			+ "gmsWRKokQ5DDlj1PfVlO4g2Uee4zbvmr7Yx6tGnnxm6o5i/COwvvRSXp8Oj7"
+			+ "Zej0ZA+1zenNRAGXwuTKrbQ9ZZYRi4LCXluuVmy8vocGm8bnuqulMyz5hsUi"
+			+ "QMAl1knunhaT+/kQOLRwEdJUgfq8ME14XsTNiVq26W8n+9AsYHoFzJhFoCfe"
+			+ "i2wngAs1MMnw1erfnhWibkFZDlG9/5OPBZ3ZzJfgMEdT5Fs+hJxrw7UqNMkb"
+			+ "EoH+3HpzEXfcGqCL6RfdbS0hu85v1CrZv0veK8qI+rQnoqXp+xmBRiSCyWNR"
+			+ "ITepXcJsi6vWYX0nvNNbBjTsFqi78BSVRpg/zOFRvw1gX1TtTXQLcEdalKgf"
+			+ "tEo+An3f3GugB3CFw38IM4JwCB06vXTRQAoK4PM4uNYVXEgSPq4vg9UuHZ3n"
+			+ "V5l96emGLK55N5FO6FvlHFft/7elEFglbnSzSQnzVyj36Z6P7x/Q3td5SY4J"
+			+ "VAJWvR/X4Fe2G6ebIZdNSJef9UyuNPee0Fi1iJUL8L4qO61ijkjYdE3bBcGm"
+			+ "61eWj8NgxtELVgRyXq1vNgMOFlVAwkf2ZNDgNRUM49UnIFTNKnTaeAVB9pW2"
+			+ "DGrZER8LA8ABctAdElECceoMVRUG1uFdAicrEbBHcWJkTdjBPjumE4bE6HUm"
+			+ "vbpNBC4wyoPS6CSvNut/re7I4wgZwho6C6GRUuwraxJZlS+jwEvC+F4Bzlf5"
+			+ "aPygECgVaNmSGP1E/vyN2aF8CLo4NL/5o9GG8DWg9O5GdNSislr4r6ciEjCr"
+			+ "0a6rk47QDn4rDQy8iu/YkZz9u8/GJCAinWQzAvV8byhZxc81CfKj9xYTclDX"
+			+ "AB75blJvUQIP4U7gpWxLB/1sdN2V5f9jw+xTLSpoJ7r/tIeBygF6rFe402Sd"
+			+ "840SLi8ZSufAVeHUoNNDYkA/c1b6k5FaxDtN22tYQi4y3Hs7k03mGhvvLC0l"
+			+ "05fMmvtasFaW5Bupqw8E2a7wHSLmRAXrPvnrblSL/wajptKPJWDJ+oH/9d9k"
+			+ "NkC4EFBpcMEfIDky4PoCtfKQBFa5LT1WDQGfcCnrC9SDfUfhfRLBOpoFmUaT"
+			+ "O0xc0vI/jmDRsoBy9d42ebyGMg5uD6tTOIvszEirpMy5SYPPa64zhHcN+Pzs"
+			+ "db+J6fthc3aVIoob9jdv/aRUH3gDwltSnaLUIc7CWcuHSCGyM/zQPiAzkw0z"
+			+ "x6ii5fdKXsmnQn88E+YqiJTPH0fG+kkhokAGU76bQMn7fJyBeVHhF2hqSr/0"
+			+ "4zCIjgq1Zb+d9sEuRZWF+/XsGl2gwk4vgHTwM+XfU7edQssUR6kyD6wkw7EU"
+			+ "6HaRrflymAHTEvdAB+PaREQbyej7/2lY41qmA9df2I5Izb60NxmMFj9F4M4V"
+			+ "bLJOVNX5fuc8vaIhPG82hIiqe05cnBfRhtmcUUb1WDHVH3klRkti+fHrnbAW"
+			+ "TpWd5m6Wi3VssopaUozWgYVgW9M+Zr5ZUAN9H0Kb4CatxG5YFkD0MCZShGl/"
+			+ "lSc1SUxho6YakBB+5HxCI853/sQ3RMgSrMk+8ftalM2+BrT+V9wMK2O+wM5W"
+			+ "ujrAcM85sQ4OqSZfJ7MmKT8+pcIsRRocmlM/cxUf5hKXfXrmCR5mkf9jxF8B"
+			+ "J1JOwhkD8zQP7sPUcOWEcT8ctOKPygtz6tWWQDW8ciiYULYyJA6ydGrrn6T+"
+			+ "fQj8M2VsM1y4YK9dMfJUeaiP+m4BeoOjs0vqz6pBI6J3lrNz31DaNO6SApUL"
+			+ "4cOx8EZMg498TG0zmQ87yVw4mGmL3JpWBZH89HiNEY5eJ0zEIS3lMaOADRMf"
+			+ "kX8B5YHadeTuAEjXsGtFIlSf1xo45kwCxIfUcikdfu2rb+Bh251Im0oq/XTj"
+			+ "XPeviXasfas6VsMHsmTrqynFdP8THnrmHLCoeAMvgpjirXfIdR7tULJcFJtr"
+			+ "0lZLZfdZgbTsbn9GMQKwMkAAjJLfJq42usvzf4ShC7IRtvOEVAMrebaaK1YF"
+			+ "rtV5z1WNo3VRFonakKj85nXLOAdCNe6T3zESebexJKFn8e/6+shp9IDIRmWr"
+			+ "hiWut6KPFiSgAgfqpeIt9fuHiYeIK8DqISA7QUdAZrgPe8GlctvKkQLvjNW0"
+			+ "srglx9CQuDqZC6C1BLaIs3sE//yLvEd06vDFjDa0WGKWjM/Uo29af/tlL1kC"
+			+ "vDQtDPi8OPIebK8OwI2uNDZ+cnHhv3gZXCdbKkRZc1W+mrU7rUk1Fa0ViVmc"
+			+ "zhVGX22fDXbIrs9zJ+sA+3Towrx2XmMZ+PDkVBxHFE2bk+GABM62BW9YZoX4"
+			+ "R4U+n7E8Ec0sI8srcxEZYX8LWHh1XSU0yEHYjkIWDQUUSGpsbgqnjXJcnTdk"
+			+ "KK5PLk4sthLYwT4o1Gg4lRpc4dn26bIQcpGdY5PEknItDt6IBSc6bYYYoQrl"
+			+ "PIufY67haoc//d5y1LpCi5vc0wTcvbdoVepLrxVAn4MPsejbfIFJ01N0qKgv"
+			+ "fGWVxmRGtGXHe3iNLsMrvSE2FkORSc4sgjC42hfxHTEVmhTnzOplxTsN/MzE"
+			+ "S7ESv/c0rIen+zwXgtiFnTg1VPHcaT4z0DtLBMNjqYNoyDrIHUrWguFeV7/i"
+			+ "RSP7SiztMmlfKhrxlQpaNNm/XvKa1OpKbVStHMgOdpMaaCp8WaX++wb9lG6V"
+			+ "3PqBeVSCuFm1xq6KAERLUdF4XsdXNM/uUhYZX7cGIqRS3vSDJB1EfrZTpUY5"
+			+ "xGllybE/P2gufnG5EMpC2FHx4iW4pWMkYhIpzKv1Tkxe3K6ISs4wEs4n/AtL"
+			+ "hupMGZE9hDJ0LV0nRvRbY8YCRXoBaj6/qF1QED7CG4hx16yrkLAR7Th5rbH7"
+			+ "GFEzNSq1HI0IssDIimD2ZN9Cf++uH6ZpP2JZeJ/gEqGi17ovtnuklx6dtu0l"
+			+ "KL0pQjCyAoQFEFSaVJ1m4oOQJyb58lsG4gOPaPvOw1ruiJ2obt4228VR1pA8"
+			+ "Vm9A41E4pk/vA+VFJ/tSmkB5s2gmBBVcA8mU8iIyzMmliTNHeg53EYAytF5M"
+			+ "X2rA7Ct8ApqbrYSSBTUPC+MEBV7UajamWB6UaSUj575MhEnzm0xl/lFqU6ZF"
+			+ "6w0rdey/KvTiotErOS1q8RcY2dcs9Mz8Dm/8IMBcGfny0i/KLtz0OUOLFg3P"
+			+ "/VrPBt7f+YfDqLVc8AujhrxAH/hwYauJ+Q6HSVTSJI7aXB9xtdsijzMZCmnE"
+			+ "1oKRBkACSWD9BGvS3hpv/VqaHWU4B2dnv2oyrIkdkgQu2OtlFxpcOkqwexIj"
+			+ "ssxxOCmT6dpB8JNehjLDU8WXhtFJVFuR84V7KlyeG/s8TaZgCW6uLLVmpteE"
+			+ "J15bnM9jRTW/FZiHwsjy9kVbvaAT+bbIjn5u7qdGsgAQHdeKy191ONvHIttZ"
+			+ "l/qnvrygLImaTOcuMMzU/0ECNlk0QiU0YbfS/RGH2LtRzk8x3FLFVXRiNtrD"
+			+ "uJuwzlP4RufuoZfJsi0rFOuxNFQ/cZEq1q7TCzqP+saRoSLFK1iRE/Ei06pS"
+			+ "JH+cwHMxk3u7k4+HxF72uK9XHIgY6G6WfZTklH2w2VrsLLZLmJ9SO6Zpyt48"
+			+ "KcwvEcxYoZxp1gfPYDCMHeb7oi/gRj9FjnBaNf2dW3a1RqVo5y0QeSfSH4k8"
+			+ "YWX6k+Yh803ZmoIb//TEbfkbXe8XOIffbMSUuIozCQY/Rt9wAHesMWfgTuB5"
+			+ "LSoa8R+mR5lIS/P1ANHdgNrh+XRFrNFeD0dCw6bdYWUXMVaZbCE8Z8pXQ0LO"
+			+ "ItiPuI+w/izD/lXdKXWJJmN/bq2RJRo4WFEDe6sJH9G2Poe/T4xwTm4kX2uA"
+			+ "IZkYy7bZcez8a0bFJzcsJxUbBPRq93J0fXzpvQsszbVZh94VSc9nkH4FnAxT"
+			+ "Kk2bLcsXANJlw3cFO9jOygrXh6R2fyHX0E8WExb2Q7lG68wU1BJVupT8rZ0Y"
+			+ "oRY6WBYG0LuZb+4VAQuI0/Are3BznsgkqudCjf+JUhu1Yefh2hblWuMPNEWb"
+			+ "mOorerNiIzkrt5tjXyBj0g8w/pL//BIlkW5JerMtKTPMfZSroHw9wuAuqHqF"
+			+ "2sMjsW/Lbr5b8SIdIgo3vrS6EM9MGkATfSZz4z+ZWG3EB6QqcMXCZ4N2/WWl"
+			+ "EPKsIqY/509NZRzqOavcMXkOryRJ7GQpmotNbbalI6r6swRoEQ2IzK5XPCC1"
+			+ "iv52YpcRaV9BDpNNByk4l3ddOiEc4dsOkHjaLNvj6Vo1pG/C1Z8VXRRY909D"
+			+ "nH2+PfUL684WZ6kIPeLfqr7N3ZbNxZAVozVG+WXwBlLFT7L+axeGHOhHdH/g"
+			+ "SVMSmWdRX4eNuofmpsU8f3A9aCnPGDxPnB4WKnAGw34TYZrtZ9mHcjYPsq1q"
+			+ "zY6brfZD4T7tktjAlRL2PYZ15MfWVXVH1xoyjeWImTi0o4nyuy/M0HukDfwY"
+			+ "l6nW77TMRiH54wdQqIZUxa32dNNhjcNslRlpOf6td3FbELqhTiaptRSuKjs9"
+			+ "8evbDFK7rb7n6RSSzAwb3oU8pwr4dM8ArTVc0EqnvdSCs1tx46ckIK3AFgcd"
+			+ "opmNq+Qa7qhN5Zgds3cLPIQiyDThhYGPaIgyn4j/dZb1Qwa2U7urijJrBqeS"
+			+ "/kJ2rEXV9v+OX9yTYKypM05A2gOK/ESPbx24C/HmmGm/yBXBx3pABvKt41Dh"
+			+ "b0syB4hYrsq0RriovGemBrNgy4tiJB5BDI9VpWFC/7LR0quFFOrxxm7YvH2h"
+			+ "GkR0oUc/socA80WZx9TegdiBg9TVPbe0gZmoeQc6XLfscBol0QdZWSmLqFxf"
+			+ "TFN7ksaVAUPXA9phBg/k51YmrwNvx4D/A1bBQRtQmq2N4R0j3uMkynubBEfb"
+			+ "9qvQNXpdygouzKUyrN/w+7clilaq2P+R9i7rriZ1waHyjfvAdeBzQQ/pVmgh"
+			+ "o8EiL/TZpIZ71sTYv28scY+V7yYgBA5S/Y4bdmvzSSoMoK8yH/LcBFJOZLQd"
+			+ "YPt7uKWSwQN8iVDA6ZcsYoKuAUw3ziiRaf+GN58ihLB/y/sGmAmX2XwLsPSZ"
+			+ "uQIF/gT8yXjxoyWDLXl3MUgfx+pGg5vBwAtk9a2elEQR9C3a8PPsOy3N9Jh3"
+			+ "xY/A1gJ/rjuubwrb0Sd2LinzPg5uVuKR1jeMSCEebgoyBj8/t8HvknBqJkpl"
+			+ "tjZ6AxGiQ8+v5jRBzYSyiTQfPMxWzdBKqUePdJcLPITf/XitegQnikgAN6bh"
+			+ "kYMS2G9kXJH2CgDm9z3svmu/0Oz2XWEpVHlOjknghPlTaLRqgWoQbK5dkuiV"
+			+ "k9HhGwwsgiR+");
+	}
+}
diff --git a/crypto/test/src/cms/test/CMSTestUtil.cs b/crypto/test/src/cms/test/CMSTestUtil.cs
new file mode 100644
index 000000000..ef7f9169f
--- /dev/null
+++ b/crypto/test/src/cms/test/CMSTestUtil.cs
@@ -0,0 +1,480 @@
+using System;
+using System.IO;
+using System.Text;
+
+using Org.BouncyCastle.Asn1.CryptoPro;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.X509.Extension;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	public class CmsTestUtil
+	{
+		public static SecureRandom rand;
+		private static IAsymmetricCipherKeyPairGenerator kpg;
+		private static IAsymmetricCipherKeyPairGenerator gostKpg;
+		private static IAsymmetricCipherKeyPairGenerator dsaKpg;
+		private static IAsymmetricCipherKeyPairGenerator ecGostKpg;
+		private static IAsymmetricCipherKeyPairGenerator ecDsaKpg;
+		public static CipherKeyGenerator aes192kg;
+		public static CipherKeyGenerator desede128kg;
+		public static CipherKeyGenerator desede192kg;
+		public static CipherKeyGenerator rc240kg;
+		public static CipherKeyGenerator rc264kg;
+		public static CipherKeyGenerator rc2128kg;
+		public static CipherKeyGenerator aesKg;
+		public static CipherKeyGenerator seedKg;
+		public static CipherKeyGenerator camelliaKg;
+		public static BigInteger serialNumber;
+
+		private static readonly byte[] attrCert = Base64.Decode(
+			  "MIIHQDCCBqkCAQEwgZChgY2kgYowgYcxHDAaBgkqhkiG9w0BCQEWDW1sb3JjaEB2"
+			+ "dC5lZHUxHjAcBgNVBAMTFU1hcmt1cyBMb3JjaCAobWxvcmNoKTEbMBkGA1UECxMS"
+			+ "VmlyZ2luaWEgVGVjaCBVc2VyMRAwDgYDVQQLEwdDbGFzcyAyMQswCQYDVQQKEwJ2"
+			+ "dDELMAkGA1UEBhMCVVMwgYmkgYYwgYMxGzAZBgkqhkiG9w0BCQEWDHNzaGFoQHZ0"
+			+ "LmVkdTEbMBkGA1UEAxMSU3VtaXQgU2hhaCAoc3NoYWgpMRswGQYDVQQLExJWaXJn"
+			+ "aW5pYSBUZWNoIFVzZXIxEDAOBgNVBAsTB0NsYXNzIDExCzAJBgNVBAoTAnZ0MQsw"
+			+ "CQYDVQQGEwJVUzANBgkqhkiG9w0BAQQFAAIBBTAiGA8yMDAzMDcxODE2MDgwMloY"
+			+ "DzIwMDMwNzI1MTYwODAyWjCCBU0wggVJBgorBgEEAbRoCAEBMYIFORaCBTU8UnVs"
+			+ "ZSBSdWxlSWQ9IkZpbGUtUHJpdmlsZWdlLVJ1bGUiIEVmZmVjdD0iUGVybWl0Ij4K"
+			+ "IDxUYXJnZXQ+CiAgPFN1YmplY3RzPgogICA8U3ViamVjdD4KICAgIDxTdWJqZWN0"
+			+ "TWF0Y2ggTWF0Y2hJZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5j"
+			+ "dGlvbjpzdHJpbmctZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlw"
+			+ "ZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjc3RyaW5nIj4KICAg"
+			+ "ICAgIENOPU1hcmt1cyBMb3JjaDwvQXR0cmlidXRlVmFsdWU+CiAgICAgPFN1Ympl"
+			+ "Y3RBdHRyaWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFt"
+			+ "ZXM6dGM6eGFjbWw6MS4wOnN1YmplY3Q6c3ViamVjdC1pZCIgRGF0YVR5cGU9Imh0"
+			+ "dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hI3N0cmluZyIgLz4gCiAgICA8"
+			+ "L1N1YmplY3RNYXRjaD4KICAgPC9TdWJqZWN0PgogIDwvU3ViamVjdHM+CiAgPFJl"
+			+ "c291cmNlcz4KICAgPFJlc291cmNlPgogICAgPFJlc291cmNlTWF0Y2ggTWF0Y2hJ"
+			+ "ZD0idXJuOm9hc2lzOm5hbWVzOnRjOnhhY21sOjEuMDpmdW5jdGlvbjpzdHJpbmct"
+			+ "ZXF1YWwiPgogICAgIDxBdHRyaWJ1dGVWYWx1ZSBEYXRhVHlwZT0iaHR0cDovL3d3"
+			+ "dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIj4KICAgICAgaHR0cDovL3p1"
+			+ "bmkuY3MudnQuZWR1PC9BdHRyaWJ1dGVWYWx1ZT4KICAgICA8UmVzb3VyY2VBdHRy"
+			+ "aWJ1dGVEZXNpZ25hdG9yIEF0dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6"
+			+ "eGFjbWw6MS4wOnJlc291cmNlOnJlc291cmNlLWlkIiBEYXRhVHlwZT0iaHR0cDov"
+			+ "L3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEjYW55VVJJIiAvPiAKICAgIDwvUmVz"
+			+ "b3VyY2VNYXRjaD4KICAgPC9SZXNvdXJjZT4KICA8L1Jlc291cmNlcz4KICA8QWN0"
+			+ "aW9ucz4KICAgPEFjdGlvbj4KICAgIDxBY3Rpb25NYXRjaCBNYXRjaElkPSJ1cm46"
+			+ "b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmZ1bmN0aW9uOnN0cmluZy1lcXVhbCI+"
+			+ "CiAgICAgPEF0dHJpYnV0ZVZhbHVlIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9y"
+			+ "Zy8yMDAxL1hNTFNjaGVtYSNzdHJpbmciPgpEZWxlZ2F0ZSBBY2Nlc3MgICAgIDwv"
+			+ "QXR0cmlidXRlVmFsdWU+CgkgIDxBY3Rpb25BdHRyaWJ1dGVEZXNpZ25hdG9yIEF0"
+			+ "dHJpYnV0ZUlkPSJ1cm46b2FzaXM6bmFtZXM6dGM6eGFjbWw6MS4wOmFjdGlvbjph"
+			+ "Y3Rpb24taWQiIERhdGFUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNj"
+			+ "aGVtYSNzdHJpbmciIC8+IAogICAgPC9BY3Rpb25NYXRjaD4KICAgPC9BY3Rpb24+"
+			+ "CiAgPC9BY3Rpb25zPgogPC9UYXJnZXQ+CjwvUnVsZT4KMA0GCSqGSIb3DQEBBAUA"
+			+ "A4GBAGiJSM48XsY90HlYxGmGVSmNR6ZW2As+bot3KAfiCIkUIOAqhcphBS23egTr"
+			+ "6asYwy151HshbPNYz+Cgeqs45KkVzh7bL/0e1r8sDVIaaGIkjHK3CqBABnfSayr3"
+			+ "Rd1yBoDdEv8Qb+3eEPH6ab9021AsLEnJ6LWTmybbOpMNZ3tv");
+
+		private static IAsymmetricCipherKeyPairGenerator Kpg
+		{
+			get
+			{
+				if (kpg == null)
+				{
+					kpg = GeneratorUtilities.GetKeyPairGenerator("RSA");
+					kpg.Init(new RsaKeyGenerationParameters(
+						BigInteger.ValueOf(17), rand, 1024, 25));
+				}
+
+				return kpg;
+			}
+		}
+
+		private static IAsymmetricCipherKeyPairGenerator GostKpg
+		{
+			get
+			{
+				if (gostKpg == null)
+				{
+					gostKpg = GeneratorUtilities.GetKeyPairGenerator("GOST3410");
+					gostKpg.Init(
+						new Gost3410KeyGenerationParameters(
+							rand,
+							CryptoProObjectIdentifiers.GostR3410x94CryptoProA));
+				}
+
+				return gostKpg;
+			}
+		}
+
+		private static IAsymmetricCipherKeyPairGenerator DsaKpg
+		{
+			get
+			{
+				if (dsaKpg == null)
+				{
+					DsaParameters dsaSpec = new DsaParameters(
+						new BigInteger("7434410770759874867539421675728577177024889699586189000788950934679315164676852047058354758883833299702695428196962057871264685291775577130504050839126673"),
+						new BigInteger("1138656671590261728308283492178581223478058193247"),
+						new BigInteger("4182906737723181805517018315469082619513954319976782448649747742951189003482834321192692620856488639629011570381138542789803819092529658402611668375788410"));
+					dsaKpg = GeneratorUtilities.GetKeyPairGenerator("DSA");
+					dsaKpg.Init(new DsaKeyGenerationParameters(rand, dsaSpec));
+				}
+
+				return dsaKpg;
+			}
+		}
+
+		private static IAsymmetricCipherKeyPairGenerator ECGostKpg
+		{
+			get
+			{
+				if (ecGostKpg == null)
+				{
+					ecGostKpg = GeneratorUtilities.GetKeyPairGenerator("ECGOST3410");
+					ecGostKpg.Init(
+						new ECKeyGenerationParameters(
+							CryptoProObjectIdentifiers.GostR3410x2001CryptoProA,
+							new SecureRandom()));
+				}
+
+				return ecGostKpg;
+			}
+		}
+
+		private static IAsymmetricCipherKeyPairGenerator ECDsaKpg
+		{
+			get
+			{
+				if (ecDsaKpg == null)
+				{
+					ecDsaKpg = GeneratorUtilities.GetKeyPairGenerator("ECDSA");
+					ecDsaKpg.Init(new KeyGenerationParameters(rand, 239));
+				}
+
+				return ecDsaKpg;
+			}
+		}
+
+		static CmsTestUtil()
+		{
+		    try
+		    {
+		        rand = new SecureRandom();
+
+				aes192kg = GeneratorUtilities.GetKeyGenerator("AES");
+				aes192kg.Init(new KeyGenerationParameters(rand, 192));
+
+		        desede128kg = GeneratorUtilities.GetKeyGenerator("DESEDE");
+				desede128kg.Init(new KeyGenerationParameters(rand, 112));
+
+				desede192kg = GeneratorUtilities.GetKeyGenerator("DESEDE");
+				desede192kg.Init(new KeyGenerationParameters(rand, 168));
+
+				rc240kg = GeneratorUtilities.GetKeyGenerator("RC2");
+				rc240kg.Init(new KeyGenerationParameters(rand, 40));
+
+				rc264kg = GeneratorUtilities.GetKeyGenerator("RC2");
+				rc264kg.Init(new KeyGenerationParameters(rand, 64));
+
+				rc2128kg = GeneratorUtilities.GetKeyGenerator("RC2");
+				rc2128kg.Init(new KeyGenerationParameters(rand, 128));
+
+				aesKg = GeneratorUtilities.GetKeyGenerator("AES");
+
+				seedKg = GeneratorUtilities.GetKeyGenerator("SEED");
+
+				camelliaKg = GeneratorUtilities.GetKeyGenerator("Camellia");
+
+				serialNumber = BigInteger.One;
+		    }
+		    catch (Exception ex)
+		    {
+		        throw new Exception(ex.ToString());
+		    }
+		}
+
+		public static string DumpBase64(
+			byte[] data)
+		{
+			StringBuilder buf = new StringBuilder();
+
+			data = Base64.Encode(data);
+
+			for (int i = 0; i < data.Length; i += 64)
+			{
+				if (i + 64 < data.Length)
+				{
+					buf.Append(Encoding.Default.GetString(data, i, 64));
+				}
+				else
+				{
+					buf.Append(Encoding.Default.GetString(data, i, data.Length - i));
+				}
+				buf.Append('\n');
+			}
+
+			return buf.ToString();
+		}
+
+		public static IX509AttributeCertificate GetAttributeCertificate()
+		{
+//			X509StreamParser parser = X509StreamParser.GetInstance("AttributeCertificate");
+//			parser.Init(CmsTestUtil.attrCert);
+//			return (X509AttributeCertificate) parser.Read();
+
+			return new X509AttrCertParser().ReadAttrCert(attrCert);
+		}
+
+		public static AsymmetricCipherKeyPair MakeKeyPair()
+		{
+			return Kpg.GenerateKeyPair();
+		}
+
+		public static AsymmetricCipherKeyPair MakeGostKeyPair()
+		{
+			return GostKpg.GenerateKeyPair();
+		}
+
+		public static AsymmetricCipherKeyPair MakeDsaKeyPair()
+		{
+			return DsaKpg.GenerateKeyPair();
+		}
+
+		public static AsymmetricCipherKeyPair MakeECGostKeyPair()
+		{
+			return ECGostKpg.GenerateKeyPair();
+		}
+
+		public static AsymmetricCipherKeyPair MakeECDsaKeyPair()
+		{
+			return ECDsaKpg.GenerateKeyPair();
+		}
+
+		public static KeyParameter MakeDesEde128Key()
+		{
+			return ParameterUtilities.CreateKeyParameter("DESEDE", desede128kg.GenerateKey());
+		}
+
+		public static KeyParameter MakeAes192Key()
+		{
+			return ParameterUtilities.CreateKeyParameter("AES", aes192kg.GenerateKey());
+		}
+
+		public static KeyParameter MakeDesEde192Key()
+		{
+			return ParameterUtilities.CreateKeyParameter("DESEDE", desede192kg.GenerateKey());
+		}
+
+		public static KeyParameter MakeRC240Key()
+		{
+			return ParameterUtilities.CreateKeyParameter("RC2", rc240kg.GenerateKey());
+		}
+
+		public static KeyParameter MakeRC264Key()
+		{
+			return ParameterUtilities.CreateKeyParameter("RC2", rc264kg.GenerateKey());
+		}
+
+		public static KeyParameter MakeRC2128Key()
+		{
+			return ParameterUtilities.CreateKeyParameter("RC2", rc2128kg.GenerateKey());
+		}
+
+		public static KeyParameter MakeSeedKey()
+		{
+			return ParameterUtilities.CreateKeyParameter("SEED", seedKg.GenerateKey());
+		}
+
+		public static KeyParameter MakeAesKey(
+			int keySize)
+		{
+			aesKg.Init(new KeyGenerationParameters(rand, keySize));
+
+			return ParameterUtilities.CreateKeyParameter("AES", aesKg.GenerateKey());
+		}
+
+		public static KeyParameter MakeCamelliaKey(
+			int keySize)
+		{
+			camelliaKg.Init(new KeyGenerationParameters(rand, keySize));
+
+			return ParameterUtilities.CreateKeyParameter("CAMELLIA", camelliaKg.GenerateKey());
+		}
+
+		public static X509Certificate MakeCertificate(AsymmetricCipherKeyPair _subKP,
+			string _subDN, AsymmetricCipherKeyPair _issKP, string _issDN)
+		{
+			return MakeCertificate(_subKP, _subDN, _issKP, _issDN, false);
+		}
+
+		public static X509Certificate MakeCACertificate(AsymmetricCipherKeyPair _subKP,
+			string _subDN, AsymmetricCipherKeyPair _issKP, string _issDN)
+		{
+			return MakeCertificate(_subKP, _subDN, _issKP, _issDN, true);
+		}
+
+		public static X509Certificate MakeV1Certificate(AsymmetricCipherKeyPair subKP,
+			string _subDN, AsymmetricCipherKeyPair issKP, string _issDN)
+		{
+			AsymmetricKeyParameter subPub = subKP.Public;
+			AsymmetricKeyParameter issPriv = issKP.Private;
+			AsymmetricKeyParameter issPub = issKP.Public;
+
+			X509V1CertificateGenerator v1CertGen = new X509V1CertificateGenerator();
+
+			v1CertGen.Reset();
+			v1CertGen.SetSerialNumber(AllocateSerialNumber());
+			v1CertGen.SetIssuerDN(new X509Name(_issDN));
+			v1CertGen.SetNotBefore(DateTime.UtcNow);
+			v1CertGen.SetNotAfter(DateTime.UtcNow.AddDays(100));
+			v1CertGen.SetSubjectDN(new X509Name(_subDN));
+			v1CertGen.SetPublicKey(subPub);
+
+			if (issPub is RsaKeyParameters)
+			{
+				v1CertGen.SetSignatureAlgorithm("SHA1WithRSA");
+			}
+			else if (issPub is DsaPublicKeyParameters)
+			{
+				v1CertGen.SetSignatureAlgorithm("SHA1withDSA");
+			}
+			else if (issPub is ECPublicKeyParameters)
+			{
+				ECPublicKeyParameters ecPub = (ECPublicKeyParameters)issPub;
+				if (ecPub.AlgorithmName == "ECGOST3410")
+				{
+					v1CertGen.SetSignatureAlgorithm("GOST3411withECGOST3410");
+				}
+				else
+				{
+					v1CertGen.SetSignatureAlgorithm("SHA1withECDSA");
+				}	
+			}
+			else
+			{
+				v1CertGen.SetSignatureAlgorithm("GOST3411WithGOST3410");
+			}
+
+			X509Certificate _cert = v1CertGen.Generate(issPriv);
+
+			_cert.CheckValidity(DateTime.UtcNow);
+			_cert.Verify(issPub);
+
+			return _cert;
+		}
+
+		public static X509Certificate MakeCertificate(
+			AsymmetricCipherKeyPair subKP, string _subDN,
+			AsymmetricCipherKeyPair issKP, string _issDN, bool _ca)
+		{
+			AsymmetricKeyParameter subPub = subKP.Public;
+			AsymmetricKeyParameter issPriv = issKP.Private;
+			AsymmetricKeyParameter issPub = issKP.Public;
+
+			X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
+
+			v3CertGen.Reset();
+			v3CertGen.SetSerialNumber(AllocateSerialNumber());
+			v3CertGen.SetIssuerDN(new X509Name(_issDN));
+			v3CertGen.SetNotBefore(DateTime.UtcNow);
+			v3CertGen.SetNotAfter(DateTime.UtcNow.AddDays(100));
+			v3CertGen.SetSubjectDN(new X509Name(_subDN));
+			v3CertGen.SetPublicKey(subPub);
+
+			if (issPub is RsaKeyParameters)
+			{
+				v3CertGen.SetSignatureAlgorithm("SHA1WithRSA");
+			}
+			else if (issPub is ECPublicKeyParameters)
+			{
+				ECPublicKeyParameters ecPub = (ECPublicKeyParameters) issPub;
+				if (ecPub.AlgorithmName == "ECGOST3410")
+				{
+					v3CertGen.SetSignatureAlgorithm("GOST3411withECGOST3410");
+				}
+				else
+				{
+					v3CertGen.SetSignatureAlgorithm("SHA1withECDSA");
+				}
+			}
+			else
+			{
+				v3CertGen.SetSignatureAlgorithm("GOST3411WithGOST3410");
+			}
+
+			v3CertGen.AddExtension(
+				X509Extensions.SubjectKeyIdentifier,
+				false,
+				CreateSubjectKeyId(subPub));
+
+			v3CertGen.AddExtension(
+				X509Extensions.AuthorityKeyIdentifier,
+				false,
+				CreateAuthorityKeyId(issPub));
+
+			v3CertGen.AddExtension(
+				X509Extensions.BasicConstraints,
+				false,
+				new BasicConstraints(_ca));
+
+			X509Certificate _cert = v3CertGen.Generate(issPriv);
+
+			_cert.CheckValidity();
+			_cert.Verify(issPub);
+
+			return _cert;
+		}
+
+		public static X509Crl MakeCrl(
+			AsymmetricCipherKeyPair pair)
+		{
+			X509V2CrlGenerator crlGen = new X509V2CrlGenerator();
+			DateTime now = DateTime.UtcNow;
+
+			crlGen.SetIssuerDN(new X509Name("CN=Test CA"));
+
+			crlGen.SetThisUpdate(now);
+			crlGen.SetNextUpdate(now.AddSeconds(100));
+			crlGen.SetSignatureAlgorithm("SHA256WithRSAEncryption");
+
+			crlGen.AddCrlEntry(BigInteger.One, now, CrlReason.PrivilegeWithdrawn);
+
+			crlGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pair.Public));
+
+			return crlGen.Generate(pair.Private);
+		}
+
+		/*
+		*
+		*  INTERNAL METHODS
+		*
+		*/
+		private static AuthorityKeyIdentifier CreateAuthorityKeyId(
+			AsymmetricKeyParameter _pubKey)
+		{
+			SubjectPublicKeyInfo _info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(_pubKey);
+			return new AuthorityKeyIdentifier(_info);
+		}
+
+		internal static SubjectKeyIdentifier CreateSubjectKeyId(
+			AsymmetricKeyParameter _pubKey)
+		{
+			SubjectPublicKeyInfo _info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(_pubKey);
+			return new SubjectKeyIdentifier(_info);
+		}
+
+		private static BigInteger AllocateSerialNumber()
+		{
+			BigInteger _tmp = serialNumber;
+			serialNumber = serialNumber.Add(BigInteger.One);
+			return _tmp;
+		}
+
+		public static byte[] StreamToByteArray(
+			Stream inStream)
+		{
+			return Streams.ReadAll(inStream);
+		}
+	}
+}
diff --git a/crypto/test/src/cms/test/CompressedDataStreamTest.cs b/crypto/test/src/cms/test/CompressedDataStreamTest.cs
new file mode 100644
index 000000000..48a6c56ee
--- /dev/null
+++ b/crypto/test/src/cms/test/CompressedDataStreamTest.cs
@@ -0,0 +1,116 @@
+using System;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	[TestFixture]
+	public class CompressedDataStreamTest
+	{
+		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");
+
+		private static readonly byte[] uncompData = Base64.Decode(
+			  "Q29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9FREktWDEyOyBuYW1lPUdyb3VwMi54MTINCkNvbnRl"
+			+ "bnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJpbmFyeQ0KQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5l"
+			+ "OyBmaWxlbmFtZT1Hcm91cDIueDEyDQoNCklTQSowMCpzc3Nzc3Nzc3NzKjAwKnJycnJycnJycnIqW"
+			+ "loqQ1lDTE9ORSAgICAgICAgKlpaKlBBUlRORVIgICAgICAgICo5NjEwMDcqMjAxMypVKjAwMjAwKj"
+			+ "AwMDAwMDAwMSowKlQqKg1HUypQTypTMVMxUzFTMVMxUzFTMVMqUjFSMVIxUjFSMVIxUjFSKjk2MTA"
+			+ "wNyoyMDEzKjAwMDAwMDAwNCpYKjAwMzA1MA1TVCo4NTAqMDAwMDQwMDAxDUJFRyowMCpCRSoyYSo0"
+			+ "MzMyNDIzNHY1NTIzKjk2MTAwNyoyM3RjNHZ5MjR2MmgzdmgzdmgqWloqSUVMKjA5KlJFKjA5DUNVU"
+			+ "ioxMSpUUk4qNTY1Nio2NSo1NjYqSU1GKjAwNio5NjEwMDcNUkVGKjZBKjQzM3IxYzNyMzRyMzRjMz"
+			+ "MxMnFjdGdjNTQqUmVmZXJlbmNlIE51bWJlcg1QRVIqQUEqSGFucyBHdXR0ZW4qQ1AqMS4zMjIuMzI"
+			+ "zLjQ0NDQqKioqKnJnZzRlZ3Y0dDQNVEFYKjR0Z3RidDR0cjR0cipHTCpnaGdoKioqKioqKioqRypD"
+			+ "DUZPQipUUCpDQSpVU0EqMDIqRE9NKkNDKlJlZ3VsYXIgTG9jYXRpb25zIHBlciBUZXJtcw1DVFAqR"
+			+ "EUqQzA0KjQ1MyoyNTAwMCpEOSpTRUwqMjMyMTQqMjM0MzI0MjM0MjMqRVMqNDIyNDM0MjMNU0FDKk"
+			+ "EqQjAwMCpBRSozNTQ1KjM0NDIzMDANQ1VSKjExKjc2Nyo3NzY3KjY1DVBPMSoxMTEtYWFhKjEwMDA"
+			+ "wMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioq"
+			+ "KioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzN"
+			+ "HE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMD"
+			+ "AwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKio"
+			+ "qKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRx"
+			+ "NmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwM"
+			+ "CpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKi"
+			+ "oqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZ"
+			+ "mMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAq"
+			+ "QVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqK"
+			+ "kExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2Zj"
+			+ "M1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkF"
+			+ "TKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipB"
+			+ "MSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzN"
+			+ "TM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNQ1RUKjENU0UqMjIqMDAwMDQwMDAxDU"
+			+ "dFKjEqMDAwMDAwMDA0DUlFQSoxKjAwMDAwMDAwMQ0=");
+
+		[Test]
+		public void TestWorkingData()
+		{
+			CmsCompressedDataParser ed = new CmsCompressedDataParser(compData);
+
+			Assert.IsTrue(Arrays.AreEqual(uncompData, CmsTestUtil.StreamToByteArray(ed.GetContent().ContentStream)));
+		}
+
+		[Test]
+		public void TestEach()
+		{
+			byte[] testData = Encoding.ASCII.GetBytes("Hello world!");
+
+			CmsCompressedDataStreamGenerator gen = new CmsCompressedDataStreamGenerator();
+			MemoryStream bOut = new MemoryStream();
+
+			Stream cOut = gen.Open(bOut, CmsCompressedDataStreamGenerator.ZLib);
+
+			cOut.Write(testData, 0, testData.Length);
+
+			cOut.Close();
+
+			CmsCompressedDataParser ed = new CmsCompressedDataParser(bOut.ToArray());
+
+			Assert.IsTrue(Arrays.AreEqual(testData, CmsTestUtil.StreamToByteArray(ed.GetContent().ContentStream)));
+		}
+
+		[Test]
+		public void Test1000()
+		{
+			byte[] testData = new byte[10000];
+			SecureRandom rand = new SecureRandom();
+
+			rand.SetSeed(0);
+
+			for (int i = 0; i != 10; i++)
+			{
+				CmsCompressedDataStreamGenerator gen = new CmsCompressedDataStreamGenerator();
+				MemoryStream bOut = new MemoryStream();
+
+				Stream cOut = gen.Open(bOut, CmsCompressedDataStreamGenerator.ZLib);
+
+				rand.NextBytes(testData);
+
+				cOut.Write(testData, 0, testData.Length);
+
+				cOut.Close();
+
+				CmsCompressedDataParser ed = new CmsCompressedDataParser(bOut.ToArray());
+
+				Assert.IsTrue(Arrays.AreEqual(testData, CmsTestUtil.StreamToByteArray(ed.GetContent().ContentStream)));
+			}
+		}
+	}
+}
diff --git a/crypto/test/src/cms/test/CompressedDataTest.cs b/crypto/test/src/cms/test/CompressedDataTest.cs
new file mode 100644
index 000000000..6df85d9fd
--- /dev/null
+++ b/crypto/test/src/cms/test/CompressedDataTest.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	[TestFixture]
+	public class CompressedDataTest
+	{
+		private static readonly byte[] TEST_DATA = Encoding.ASCII.GetBytes("Hello world!");
+
+		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");
+
+		private static readonly byte[] uncompData = Base64.Decode(
+			  "Q29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9FREktWDEyOyBuYW1lPUdyb3VwMi54MTINCkNvbnRl"
+			+ "bnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJpbmFyeQ0KQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5l"
+			+ "OyBmaWxlbmFtZT1Hcm91cDIueDEyDQoNCklTQSowMCpzc3Nzc3Nzc3NzKjAwKnJycnJycnJycnIqW"
+			+ "loqQ1lDTE9ORSAgICAgICAgKlpaKlBBUlRORVIgICAgICAgICo5NjEwMDcqMjAxMypVKjAwMjAwKj"
+			+ "AwMDAwMDAwMSowKlQqKg1HUypQTypTMVMxUzFTMVMxUzFTMVMqUjFSMVIxUjFSMVIxUjFSKjk2MTA"
+			+ "wNyoyMDEzKjAwMDAwMDAwNCpYKjAwMzA1MA1TVCo4NTAqMDAwMDQwMDAxDUJFRyowMCpCRSoyYSo0"
+			+ "MzMyNDIzNHY1NTIzKjk2MTAwNyoyM3RjNHZ5MjR2MmgzdmgzdmgqWloqSUVMKjA5KlJFKjA5DUNVU"
+			+ "ioxMSpUUk4qNTY1Nio2NSo1NjYqSU1GKjAwNio5NjEwMDcNUkVGKjZBKjQzM3IxYzNyMzRyMzRjMz"
+			+ "MxMnFjdGdjNTQqUmVmZXJlbmNlIE51bWJlcg1QRVIqQUEqSGFucyBHdXR0ZW4qQ1AqMS4zMjIuMzI"
+			+ "zLjQ0NDQqKioqKnJnZzRlZ3Y0dDQNVEFYKjR0Z3RidDR0cjR0cipHTCpnaGdoKioqKioqKioqRypD"
+			+ "DUZPQipUUCpDQSpVU0EqMDIqRE9NKkNDKlJlZ3VsYXIgTG9jYXRpb25zIHBlciBUZXJtcw1DVFAqR"
+			+ "EUqQzA0KjQ1MyoyNTAwMCpEOSpTRUwqMjMyMTQqMjM0MzI0MjM0MjMqRVMqNDIyNDM0MjMNU0FDKk"
+			+ "EqQjAwMCpBRSozNTQ1KjM0NDIzMDANQ1VSKjExKjc2Nyo3NzY3KjY1DVBPMSoxMTEtYWFhKjEwMDA"
+			+ "wMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioq"
+			+ "KioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzN"
+			+ "HE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMD"
+			+ "AwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKio"
+			+ "qKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRx"
+			+ "NmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwM"
+			+ "CpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2ZjM1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKi"
+			+ "oqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkFTKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZ"
+			+ "mMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipBMSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAq"
+			+ "QVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzNTM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqK"
+			+ "kExKnl0cmgNUE8xKjExMS1hYWEqMTAwMDAwMCpBUyo5MC4wMCpCRCpBSyoyMzQyMzV2MzUzNHE2Zj"
+			+ "M1MzR2NDM1MzQ1M3ZxM3EzMioqKioqKioqKioqQTEqeXRyaA1QTzEqMTExLWFhYSoxMDAwMDAwKkF"
+			+ "TKjkwLjAwKkJEKkFLKjIzNDIzNXYzNTM0cTZmMzUzNHY0MzUzNDUzdnEzcTMyKioqKioqKioqKipB"
+			+ "MSp5dHJoDVBPMSoxMTEtYWFhKjEwMDAwMDAqQVMqOTAuMDAqQkQqQUsqMjM0MjM1djM1MzRxNmYzN"
+			+ "TM0djQzNTM0NTN2cTNxMzIqKioqKioqKioqKkExKnl0cmgNQ1RUKjENU0UqMjIqMDAwMDQwMDAxDU"
+			+ "dFKjEqMDAwMDAwMDA0DUlFQSoxKjAwMDAwMDAwMQ0=");
+
+		[Test]
+		public void TestWorkingData()
+		{
+			CmsCompressedData ed = new CmsCompressedData(compData);
+
+			Assert.IsTrue(Arrays.AreEqual(uncompData, ed.GetContent()));
+		}
+
+		[Test]
+		public void TestEach()
+		{
+			CmsCompressedData cd = GetStdData();
+
+			Assert.IsTrue(Arrays.AreEqual(TEST_DATA, cd.GetContent()));
+		}
+
+		[Test]
+		public void TestLimitUnder()
+		{
+			CmsCompressedData cd = GetStdData();
+
+			try
+			{
+				cd.GetContent(TEST_DATA.Length / 2);
+			}
+			catch (CmsException e)
+			{
+				Assert.IsTrue(e.InnerException is StreamOverflowException);
+			}
+		}
+
+		[Test]
+		public void TestLimitOver()
+		{
+			CmsCompressedData cd = GetStdData();
+
+			Assert.IsTrue(Arrays.AreEqual(TEST_DATA, cd.GetContent(TEST_DATA.Length * 2)));
+		}
+
+		[Test]
+		public void TestLimitEqual()
+		{
+			CmsCompressedData cd = GetStdData();
+
+			Assert.IsTrue(Arrays.AreEqual(TEST_DATA, cd.GetContent(TEST_DATA.Length)));
+		}
+
+		private CmsCompressedData GetStdData()
+		{
+			CmsProcessableByteArray testData = new CmsProcessableByteArray(TEST_DATA);
+			CmsCompressedDataGenerator gen = new CmsCompressedDataGenerator();
+			return gen.Generate(testData, CmsCompressedDataGenerator.ZLib);
+		}
+	}
+}
diff --git a/crypto/test/src/cms/test/EnvelopedDataStreamTest.cs b/crypto/test/src/cms/test/EnvelopedDataStreamTest.cs
new file mode 100644
index 000000000..8512f6622
--- /dev/null
+++ b/crypto/test/src/cms/test/EnvelopedDataStreamTest.cs
@@ -0,0 +1,537 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+using Org.BouncyCastle.X509;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	[TestFixture]
+	public class EnvelopedDataStreamTest
+	{
+		private const int BufferSize = 4000;
+
+		private const string SignDN = "O=Bouncy Castle, C=AU";
+		private static AsymmetricCipherKeyPair signKP;
+//		private static X509Certificate signCert;
+		//signCert = CmsTestUtil.MakeCertificate(_signKP, SignDN, _signKP, SignDN);
+
+//		private const string OrigDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU";
+//		private static AsymmetricCipherKeyPair origKP;
+		//origKP   = CmsTestUtil.MakeKeyPair();
+//		private static X509Certificate origCert;
+		//origCert = CmsTestUtil.MakeCertificate(origKP, OrigDN, _signKP, SignDN);
+
+		private const string ReciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
+		private static AsymmetricCipherKeyPair reciKP;
+		private static X509Certificate reciCert;
+
+		private static AsymmetricCipherKeyPair origECKP;
+		private static AsymmetricCipherKeyPair reciECKP;
+		private static X509Certificate reciECCert;
+
+		private static AsymmetricCipherKeyPair SignKP
+		{
+			get { return signKP == null ? (signKP   = CmsTestUtil.MakeKeyPair()) : signKP; }
+		}
+
+		private static AsymmetricCipherKeyPair ReciKP
+		{
+			get { return reciKP == null ? (reciKP   = CmsTestUtil.MakeKeyPair()) : reciKP; }
+		}
+
+		private static X509Certificate ReciCert
+		{
+			get { return reciCert == null ? (reciCert = CmsTestUtil.MakeCertificate(ReciKP, ReciDN, SignKP, SignDN)) : reciCert;}
+		}
+
+		private static AsymmetricCipherKeyPair OrigECKP
+		{
+			get { return origECKP == null ? (origECKP = CmsTestUtil.MakeECDsaKeyPair()) : origECKP; }
+		}
+
+		private static AsymmetricCipherKeyPair ReciECKP
+		{
+			get { return reciECKP == null ? (reciECKP = CmsTestUtil.MakeECDsaKeyPair()) : reciECKP; }
+		}
+
+		private static X509Certificate ReciECCert
+		{
+			get { return reciECCert == null ? (reciECCert = CmsTestUtil.MakeCertificate(ReciECKP, ReciDN, SignKP, SignDN)) : reciECCert;}
+		}
+
+		[Test]
+		public void TestWorkingData()
+		{
+			byte[] keyData = Base64.Decode(
+				"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKrAz/SQKrcQ" +
+				"nj9IxHIfKDbuXsMqUpI06s2gps6fp7RDNvtUDDMOciWGFhD45YSy8GO0mPx3" +
+				"Nkc7vKBqX4TLcqLUz7kXGOHGOwiPZoNF+9jBMPNROe/B0My0PkWg9tuq+nxN" +
+				"64oD47+JvDwrpNOS5wsYavXeAW8Anv9ZzHLU7KwZAgMBAAECgYA/fqdVt+5K" +
+				"WKGfwr1Z+oAHvSf7xtchiw/tGtosZ24DOCNP3fcTXUHQ9kVqVkNyzt9ZFCT3" +
+				"bJUAdBQ2SpfuV4DusVeQZVzcROKeA09nPkxBpTefWbSDQGhb+eZq9L8JDRSW" +
+				"HyYqs+MBoUpLw7GKtZiJkZyY6CsYkAnQ+uYVWq/TIQJBAP5zafO4HUV/w4KD" +
+				"VJi+ua+GYF1Sg1t/dYL1kXO9GP1p75YAmtm6LdnOCas7wj70/G1YlPGkOP0V" +
+				"GFzeG5KAmAUCQQCryvKU9nwWA+kypcQT9Yr1P4vGS0APYoBThnZq7jEPc5Cm" +
+				"ZI82yseSxSeea0+8KQbZ5mvh1p3qImDLEH/iNSQFAkAghS+tboKPN10NeSt+" +
+				"uiGRRWNbiggv0YJ7Uldcq3ZeLQPp7/naiekCRUsHD4Qr97OrZf7jQ1HlRqTu" +
+				"eZScjMLhAkBNUMZCQnhwFAyEzdPkQ7LpU1MdyEopYmRssuxijZao5JLqQAGw" +
+				"YCzXokGFa7hz72b09F4DQurJL/WuDlvvu4jdAkEAxwT9lylvfSfEQw4/qQgZ" +
+				"MFB26gqB6Gqs1pHIZCzdliKx5BO3VDeUGfXMI8yOkbXoWbYx5xPid/+N8R//" +
+				"+sxLBw==");
+
+			byte[] envData = Base64.Decode(
+				"MIAGCSqGSIb3DQEHA6CAMIACAQAxgcQwgcECAQAwKjAlMRYwFAYDVQQKEw1C" +
+				"b3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVQIBHjANBgkqhkiG9w0BAQEFAASB" +
+				"gDmnaDZ0vDJNlaUSYyEXsgbaUH+itNTjCOgv77QTX2ImXj+kTctM19PQF2I1" +
+				"0/NL0fjakvCgBTHKmk13a7jqB6cX3bysenHNrglHsgNGgeXQ7ggAq5fV/JQQ" +
+				"T7rSxEtuwpbuHQnoVUZahOHVKy/a0uLr9iIh1A3y+yZTZaG505ZJMIAGCSqG" +
+				"SIb3DQEHATAdBglghkgBZQMEAQIEENmkYNbDXiZxJWtq82qIRZKggAQgkOGr" +
+				"1JcTsADStez1eY4+rO4DtyBIyUYQ3pilnbirfPkAAAAAAAAAAAAA");
+
+
+			CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(envData);
+
+			RecipientInformationStore recipients = ep.GetRecipientInfos();
+
+			Assert.AreEqual(ep.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			ICollection c = recipients.GetRecipients();
+
+//            PKCS8EncodedKeySpec	keySpec = new PKCS8EncodedKeySpec(keyData);
+//            KeyFactory			keyFact = KeyFactory.GetInstance("RSA");
+//            Key					priKey = keyFact.generatePrivate(keySpec);
+			AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(keyData);
+            byte[] data = Hex.Decode("57616c6c6157616c6c6157617368696e67746f6e");
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);
+
+				CmsTypedStream recData = recipient.GetContentStream(priKey);
+
+				byte[] compare = CmsTestUtil.StreamToByteArray(recData.ContentStream);
+				Assert.IsTrue(Arrays.AreEqual(data, compare));
+			}
+		}
+
+		private void VerifyData(
+			byte[]	encodedBytes,
+			string	expectedOid,
+			byte[]	expectedData)
+		{
+			CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(encodedBytes);
+			RecipientInformationStore recipients = ep.GetRecipientInfos();
+
+			Assert.AreEqual(ep.EncryptionAlgOid, expectedOid);
+
+			ICollection c = recipients.GetRecipients();
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);
+
+				CmsTypedStream recData = recipient.GetContentStream(ReciKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(expectedData, CmsTestUtil.StreamToByteArray(
+					recData.ContentStream)));
+			}
+		}
+
+		[Test]
+		public void TestKeyTransAes128BufferedStream()
+		{
+			byte[] data = new byte[2000];
+			for (int i = 0; i != 2000; i++)
+			{
+				data[i] = (byte)(i & 0xff);
+			}
+
+			//
+			// unbuffered
+			//
+			CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			MemoryStream bOut = new MemoryStream();
+
+			Stream outStream = edGen.Open(
+				bOut, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			for (int i = 0; i != 2000; i++)
+			{
+				outStream.WriteByte(data[i]);
+			}
+
+			outStream.Close();
+
+			VerifyData(bOut.ToArray(), CmsEnvelopedDataGenerator.Aes128Cbc, data);
+
+			int unbufferedLength = bOut.ToArray().Length;
+
+			//
+			// Using buffered output - should be == to unbuffered
+			//
+			edGen = new CmsEnvelopedDataStreamGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			bOut.SetLength(0);
+
+			outStream = edGen.Open(bOut, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			Streams.PipeAll(new MemoryStream(data, false), outStream);
+			outStream.Close();
+
+			VerifyData(bOut.ToArray(), CmsEnvelopedDataGenerator.Aes128Cbc, data);
+
+			Assert.AreEqual(unbufferedLength, bOut.ToArray().Length);
+		}
+
+		[Test]
+		public void TestKeyTransAes128Buffered()
+		{
+			byte[] data = new byte[2000];
+			for (int i = 0; i != 2000; i++)
+			{
+				data[i] = (byte)(i & 0xff);
+			}
+
+			//
+			// unbuffered
+			//
+			CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			MemoryStream  bOut = new MemoryStream();
+
+			Stream outStream = edGen.Open(
+				bOut, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			for (int i = 0; i != 2000; i++)
+			{
+				outStream.WriteByte(data[i]);
+			}
+
+			outStream.Close();
+
+			VerifyData(bOut.ToArray(), CmsEnvelopedDataGenerator.Aes128Cbc, data);
+
+			int unbufferedLength = bOut.ToArray().Length;
+
+			//
+			// buffered - less than default of 1000
+			//
+			edGen = new CmsEnvelopedDataStreamGenerator();
+
+			edGen.SetBufferSize(300);
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			bOut.SetLength(0);
+
+			outStream = edGen.Open(bOut, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			for (int i = 0; i != 2000; i++)
+			{
+				outStream.WriteByte(data[i]);
+			}
+
+			outStream.Close();
+
+			VerifyData(bOut.ToArray(), CmsEnvelopedDataGenerator.Aes128Cbc, data);
+
+			Assert.IsTrue(unbufferedLength < bOut.ToArray().Length);
+		}
+
+		[Test]
+		public void TestKeyTransAes128Der()
+		{
+			byte[] data = new byte[2000];
+			for (int i = 0; i != 2000; i++)
+			{
+				data[i] = (byte)(i & 0xff);
+			}
+
+			CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			MemoryStream bOut = new MemoryStream();
+
+			Stream outStream = edGen.Open(
+				bOut, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			for (int i = 0; i != 2000; i++)
+			{
+				outStream.WriteByte(data[i]);
+			}
+
+			outStream.Close();
+
+			// convert to DER
+			byte[] derEncodedBytes = Asn1Object.FromByteArray(bOut.ToArray()).GetDerEncoded();
+
+			VerifyData(derEncodedBytes, CmsEnvelopedDataGenerator.Aes128Cbc, data);
+		}
+
+		[Test]
+		public void TestKeyTransAes128Throughput()
+		{
+			byte[] data = new byte[40001];
+			for (int i = 0; i != data.Length; i++)
+			{
+				data[i] = (byte)(i & 0xff);
+			}
+
+			//
+			// buffered
+			//
+			CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator();
+
+			edGen.SetBufferSize(BufferSize);
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			MemoryStream bOut = new MemoryStream();
+
+			Stream outStream = edGen.Open(bOut, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			for (int i = 0; i != data.Length; i++)
+			{
+				outStream.WriteByte(data[i]);
+			}
+
+			outStream.Close();
+
+			CmsEnvelopedDataParser		ep = new CmsEnvelopedDataParser(bOut.ToArray());
+			RecipientInformationStore	recipients = ep.GetRecipientInfos();
+			ICollection					c = recipients.GetRecipients();
+
+			IEnumerator e = c.GetEnumerator();
+
+			if (e.MoveNext())
+			{
+				RecipientInformation recipient = (RecipientInformation) e.Current;
+
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);
+
+				CmsTypedStream recData = recipient.GetContentStream(ReciKP.Private);
+
+				Stream dataStream = recData.ContentStream;
+				MemoryStream dataOut = new MemoryStream();
+				int len;
+				byte[] buf = new byte[BufferSize];
+				int count = 0;
+
+				while (count != 10 && (len = dataStream.Read(buf, 0, buf.Length)) > 0)
+				{
+					Assert.AreEqual(buf.Length, len);
+
+					dataOut.Write(buf, 0, buf.Length);
+					count++;
+				}
+
+				len = dataStream.Read(buf, 0, buf.Length);
+				dataOut.Write(buf, 0, len);
+
+				Assert.IsTrue(Arrays.AreEqual(data, dataOut.ToArray()));
+			}
+			else
+			{
+				Assert.Fail("recipient not found.");
+			}
+		}
+
+		[Test]
+		public void TestKeyTransAes128()
+		{
+			byte[] data = Encoding.Default.GetBytes("WallaWallaWashington");
+
+			CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			MemoryStream bOut = new MemoryStream();
+
+			Stream outStream = edGen.Open(
+				bOut, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			outStream.Write(data, 0, data.Length);
+
+			outStream.Close();
+
+			CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(bOut.ToArray());
+
+			RecipientInformationStore recipients = ep.GetRecipientInfos();
+
+			Assert.AreEqual(ep.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			ICollection c = recipients.GetRecipients();
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);
+
+				CmsTypedStream recData = recipient.GetContentStream(ReciKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(data, CmsTestUtil.StreamToByteArray(recData.ContentStream)));
+			}
+
+			ep.Close();
+		}
+
+		[Test]
+		public void TestAesKek()
+		{
+			byte[] data = Encoding.Default.GetBytes("WallaWallaWashington");
+			KeyParameter kek = CmsTestUtil.MakeAes192Key();
+
+			CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator();
+
+			byte[] kekId = new byte[] { 1, 2, 3, 4, 5 };
+
+			edGen.AddKekRecipient("AES192", kek, kekId);
+
+			MemoryStream  bOut = new MemoryStream();
+
+			Stream outStream = edGen.Open(
+				bOut,
+				CmsEnvelopedDataGenerator.DesEde3Cbc);
+			outStream.Write(data, 0, data.Length);
+
+			outStream.Close();
+
+			CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(bOut.ToArray());
+
+			RecipientInformationStore recipients = ep.GetRecipientInfos();
+
+			Assert.AreEqual(ep.EncryptionAlgOid, CmsEnvelopedDataGenerator.DesEde3Cbc);
+
+			ICollection c = recipients.GetRecipients();
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, "2.16.840.1.101.3.4.1.25");
+
+				CmsTypedStream recData = recipient.GetContentStream(kek);
+
+				Assert.IsTrue(Arrays.AreEqual(data, CmsTestUtil.StreamToByteArray(recData.ContentStream)));
+			}
+
+			ep.Close();
+		}
+
+		[Test]
+		public void TestTwoAesKek()
+		{
+			byte[] data = Encoding.Default.GetBytes("WallaWallaWashington");
+			KeyParameter kek1 = CmsTestUtil.MakeAes192Key();
+			KeyParameter kek2 = CmsTestUtil.MakeAes192Key();
+
+			CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator();
+
+			byte[]  kekId1 = new byte[] { 1, 2, 3, 4, 5 };
+			byte[]  kekId2 = new byte[] { 5, 4, 3, 2, 1 };
+
+			edGen.AddKekRecipient("AES192", kek1, kekId1);
+			edGen.AddKekRecipient("AES192", kek2, kekId2);
+
+			MemoryStream bOut = new MemoryStream();
+
+			Stream outStream = edGen.Open(
+				bOut,
+				CmsEnvelopedDataGenerator.DesEde3Cbc);
+			outStream.Write(data, 0, data.Length);
+
+			outStream.Close();
+
+			CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(bOut.ToArray());
+
+			RecipientInformationStore recipients = ep.GetRecipientInfos();
+
+			Assert.AreEqual(ep.EncryptionAlgOid, CmsEnvelopedDataGenerator.DesEde3Cbc);
+
+			RecipientID recSel = new RecipientID();
+
+			recSel.KeyIdentifier = kekId2;
+
+			RecipientInformation recipient = recipients.GetFirstRecipient(recSel);
+
+			Assert.AreEqual(recipient.KeyEncryptionAlgOid, "2.16.840.1.101.3.4.1.25");
+
+			CmsTypedStream recData = recipient.GetContentStream(kek2);
+
+			Assert.IsTrue(Arrays.AreEqual(data, CmsTestUtil.StreamToByteArray(recData.ContentStream)));
+
+			ep.Close();
+		}
+
+		[Test]
+		public void TestECKeyAgree()
+		{
+			byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");
+
+			CmsEnvelopedDataStreamGenerator edGen = new CmsEnvelopedDataStreamGenerator();
+
+			edGen.AddKeyAgreementRecipient(
+				CmsEnvelopedDataGenerator.ECDHSha1Kdf,
+				OrigECKP.Private,
+				OrigECKP.Public,
+				ReciECCert,
+				CmsEnvelopedDataGenerator.Aes128Wrap);
+
+			MemoryStream bOut = new MemoryStream();
+
+			Stream outStr = edGen.Open(bOut, CmsEnvelopedDataGenerator.Aes128Cbc);
+			outStr.Write(data, 0, data.Length);
+
+			outStr.Close();
+
+			CmsEnvelopedDataParser ep = new CmsEnvelopedDataParser(bOut.ToArray());
+
+			RecipientInformationStore recipients = ep.GetRecipientInfos();
+
+			Assert.AreEqual(ep.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			RecipientID recSel = new RecipientID();
+
+//			recSel.SetIssuer(PrincipalUtilities.GetIssuerX509Principal(ReciECCert).GetEncoded());
+			recSel.Issuer = PrincipalUtilities.GetIssuerX509Principal(ReciECCert);
+			recSel.SerialNumber = ReciECCert.SerialNumber;
+
+			RecipientInformation recipient = recipients.GetFirstRecipient(recSel);
+
+			CmsTypedStream recData = recipient.GetContentStream(ReciECKP.Private);
+
+			Assert.IsTrue(Arrays.AreEqual(data, CmsTestUtil.StreamToByteArray(recData.ContentStream)));
+
+			ep.Close();
+		}
+
+		[Test]
+		public void TestOriginatorInfo()
+		{
+			CmsEnvelopedDataParser env = new CmsEnvelopedDataParser(CmsSampleMessages.originatorMessage);
+
+			env.GetRecipientInfos();
+
+			Assert.AreEqual(CmsEnvelopedDataGenerator.DesEde3Cbc, env.EncryptionAlgOid);
+		}
+	}
+}
diff --git a/crypto/test/src/cms/test/EnvelopedDataTest.cs b/crypto/test/src/cms/test/EnvelopedDataTest.cs
new file mode 100644
index 000000000..be588ef42
--- /dev/null
+++ b/crypto/test/src/cms/test/EnvelopedDataTest.cs
@@ -0,0 +1,866 @@
+using System;
+using System.Collections;
+using System.Text;
+
+using NUnit.Framework;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Kisa;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Ntt;
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.X509;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	[TestFixture]
+	public class EnvelopedDataTest
+	{
+		private const string SignDN = "O=Bouncy Castle, C=AU";
+
+		private static AsymmetricCipherKeyPair signKP;
+//		private static X509Certificate signCert;
+		//signCert = CmsTestUtil.MakeCertificate(_signKP, SignDN, _signKP, SignDN);
+
+//		private const string OrigDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU";
+
+//		private static AsymmetricCipherKeyPair origKP;
+		//origKP = CmsTestUtil.MakeKeyPair();
+//		private static X509Certificate origCert;
+		//origCert = CmsTestUtil.MakeCertificate(_origKP, OrigDN, _signKP, SignDN);
+
+		private const string ReciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
+		private const string ReciDN2 = "CN=Fred, OU=Sales, O=Bouncy Castle, C=AU";
+
+		private static AsymmetricCipherKeyPair reciKP;
+		private static X509Certificate reciCert;
+
+		private static AsymmetricCipherKeyPair origECKP;
+		private static AsymmetricCipherKeyPair reciECKP;
+		private static X509Certificate reciECCert;
+		private static AsymmetricCipherKeyPair reciECKP2;
+		private static X509Certificate reciECCert2;
+
+		private static AsymmetricCipherKeyPair SignKP
+		{
+			get { return signKP == null ? (signKP = CmsTestUtil.MakeKeyPair()) : signKP; }
+		}
+
+		private static AsymmetricCipherKeyPair ReciKP
+		{
+			get { return reciKP == null ? (reciKP = CmsTestUtil.MakeKeyPair()) : reciKP; }
+		}
+
+		private static X509Certificate ReciCert
+		{
+			get { return reciCert == null ? (reciCert = CmsTestUtil.MakeCertificate(ReciKP, ReciDN, SignKP, SignDN)) : reciCert; }
+		}
+
+		private static AsymmetricCipherKeyPair OrigECKP
+		{
+			get { return origECKP == null ? (origECKP = CmsTestUtil.MakeECDsaKeyPair()) : origECKP; }
+		}
+
+		private static AsymmetricCipherKeyPair ReciECKP
+		{
+			get { return reciECKP == null ? (reciECKP = CmsTestUtil.MakeECDsaKeyPair()) : reciECKP; }
+		}
+
+		private static X509Certificate ReciECCert
+		{
+			get { return reciECCert == null ? (reciECCert = CmsTestUtil.MakeCertificate(ReciECKP, ReciDN, SignKP, SignDN)) : reciECCert; }
+		}
+
+		private static AsymmetricCipherKeyPair ReciECKP2
+		{
+			get { return reciECKP2 == null ? (reciECKP2 = CmsTestUtil.MakeECDsaKeyPair()) : reciECKP2; }
+		}
+
+		private static X509Certificate ReciECCert2
+		{
+			get { return reciECCert2 == null ? (reciECCert2 = CmsTestUtil.MakeCertificate(ReciECKP2, ReciDN2, SignKP, SignDN)) : reciECCert2; }
+		}
+
+		private static readonly byte[] oldKEK = Base64.Decode(
+			"MIAGCSqGSIb3DQEHA6CAMIACAQIxQaI/MD0CAQQwBwQFAQIDBAUwDQYJYIZIAWUDBAEFBQAEI"
+			+ "Fi2eHTPM4bQSjP4DUeDzJZLpfemW2gF1SPq7ZPHJi1mMIAGCSqGSIb3DQEHATAUBggqhkiG9w"
+			+ "0DBwQImtdGyUdGGt6ggAQYk9X9z01YFBkU7IlS3wmsKpm/zpZClTceAAAAAAAAAAAAAA==");
+
+		private static readonly byte[] ecKeyAgreeMsgAES256 = Base64.Decode(
+			"MIAGCSqGSIb3DQEHA6CAMIACAQIxgcShgcECAQOgQ6FBMAsGByqGSM49AgEF"
+			+ "AAMyAAPdXlSTpub+qqno9hUGkUDl+S3/ABhPziIB5yGU4678tgOgU5CiKG9Z"
+			+ "kfnabIJ3nZYwGgYJK4EFEIZIPwACMA0GCWCGSAFlAwQBLQUAMFswWTAtMCgx"
+			+ "EzARBgNVBAMTCkFkbWluLU1EU0UxETAPBgNVBAoTCDRCQ1QtMklEAgEBBCi/"
+			+ "rJRLbFwEVW6PcLLmojjW9lI/xGD7CfZzXrqXFw8iHaf3hTRau1gYMIAGCSqG"
+			+ "SIb3DQEHATAdBglghkgBZQMEASoEEMtCnKKPwccmyrbgeSIlA3qggAQQDLw8"
+			+ "pNJR97bPpj6baG99bQQQwhEDsoj5Xg1oOxojHVcYzAAAAAAAAAAAAAA=");
+
+		private static readonly byte[] ecKeyAgreeMsgAES128 = Base64.Decode(
+			"MIAGCSqGSIb3DQEHA6CAMIACAQIxgbShgbECAQOgQ6FBMAsGByqGSM49AgEF"
+			+ "AAMyAAL01JLEgKvKh5rbxI/hOxs/9WEezMIsAbUaZM4l5tn3CzXAN505nr5d"
+			+ "LhrcurMK+tAwGgYJK4EFEIZIPwACMA0GCWCGSAFlAwQBBQUAMEswSTAtMCgx"
+			+ "EzARBgNVBAMTCkFkbWluLU1EU0UxETAPBgNVBAoTCDRCQ1QtMklEAgEBBBhi"
+			+ "FLjc5g6aqDT3f8LomljOwl1WTrplUT8wgAYJKoZIhvcNAQcBMB0GCWCGSAFl"
+			+ "AwQBAgQQzXjms16Y69S/rB0EbHqRMaCABBAFmc/QdVW6LTKdEy97kaZzBBBa"
+			+ "fQuviUS03NycpojELx0bAAAAAAAAAAAAAA==");
+
+		private static readonly byte[] ecKeyAgreeMsgDESEDE = Base64.Decode(
+			"MIAGCSqGSIb3DQEHA6CAMIACAQIxgcahgcMCAQOgQ6FBMAsGByqGSM49AgEF"
+			+ "AAMyAALIici6Nx1WN5f0ThH2A8ht9ovm0thpC5JK54t73E1RDzCifePaoQo0"
+			+ "xd6sUqoyGaYwHAYJK4EFEIZIPwACMA8GCyqGSIb3DQEJEAMGBQAwWzBZMC0w"
+			+ "KDETMBEGA1UEAxMKQWRtaW4tTURTRTERMA8GA1UEChMINEJDVC0ySUQCAQEE"
+			+ "KJuqZQ1NB1vXrKPOnb4TCpYOsdm6GscWdwAAZlm2EHMp444j0s55J9wwgAYJ"
+			+ "KoZIhvcNAQcBMBQGCCqGSIb3DQMHBAjwnsDMsafCrKCABBjyPvqFOVMKxxut"
+			+ "VfTx4fQlNGJN8S2ATRgECMcTQ/dsmeViAAAAAAAAAAAAAA==");
+
+		private static readonly byte[] ecMqvKeyAgreeMsgAes128 = Base64.Decode(
+			  "MIAGCSqGSIb3DQEHA6CAMIACAQIxgf2hgfoCAQOgQ6FBMAsGByqGSM49AgEF"
+			+ "AAMyAAPDKU+0H58tsjpoYmYCInMr/FayvCCkupebgsnpaGEB7qS9vzcNVUj6"
+			+ "mrnmiC2grpmhRwRFMEMwQTALBgcqhkjOPQIBBQADMgACZpD13z9c7DzRWx6S"
+			+ "0xdbq3S+EJ7vWO+YcHVjTD8NcQDcZcWASW899l1PkL936zsuMBoGCSuBBRCG"
+			+ "SD8AEDANBglghkgBZQMEAQUFADBLMEkwLTAoMRMwEQYDVQQDEwpBZG1pbi1N"
+			+ "RFNFMREwDwYDVQQKEwg0QkNULTJJRAIBAQQYFq58L71nyMK/70w3nc6zkkRy"
+			+ "RL7DHmpZMIAGCSqGSIb3DQEHATAdBglghkgBZQMEAQIEEDzRUpreBsZXWHBe"
+			+ "onxOtSmggAQQ7csAZXwT1lHUqoazoy8bhAQQq+9Zjj8iGdOWgyebbfj67QAA"
+			+ "AAAAAAAAAAA=");
+
+		private static readonly byte[] ecKeyAgreeKey = Base64.Decode(
+			"MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDC8vp7xVTbKSgYVU5Wc"
+			+ "hGkWbzaj+yUFETIWP1Dt7+WSpq3ikSPdl7PpHPqnPVZfoIWhZANiAgSYHTgxf+Dd"
+			+ "Tt84dUvuSKkFy3RhjxJmjwIscK6zbEUzKhcPQG2GHzXhWK5x1kov0I74XpGhVkya"
+			+ "ElH5K6SaOXiXAzcyNGggTOk4+ZFnz5Xl0pBje3zKxPhYu0SnCw7Pcqw=");
+
+		private static readonly byte[] bobPrivRsaEncrypt = Base64.Decode(
+			"MIIChQIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKnhZ5g/OdVf"
+			+ "8qCTQV6meYmFyDVdmpFb+x0B2hlwJhcPvaUi0DWFbXqYZhRBXM+3twg7CcmR"
+			+ "uBlpN235ZR572akzJKN/O7uvRgGGNjQyywcDWVL8hYsxBLjMGAgUSOZPHPtd"
+			+ "YMTgXB9T039T2GkB8QX4enDRvoPGXzjPHCyqaqfrAgMBAAECgYBnzUhMmg2P"
+			+ "mMIbZf8ig5xt8KYGHbztpwOIlPIcaw+LNd4Ogngwy+e6alatd8brUXlweQqg"
+			+ "9P5F4Kmy9Bnah5jWMIR05PxZbMHGd9ypkdB8MKCixQheIXFD/A0HPfD6bRSe"
+			+ "TmPwF1h5HEuYHD09sBvf+iU7o8AsmAX2EAnYh9sDGQJBANDDIsbeopkYdo+N"
+			+ "vKZ11mY/1I1FUox29XLE6/BGmvE+XKpVC5va3Wtt+Pw7PAhDk7Vb/s7q/WiE"
+			+ "I2Kv8zHCueUCQQDQUfweIrdb7bWOAcjXq/JY1PeClPNTqBlFy2bKKBlf4hAr"
+			+ "84/sajB0+E0R9KfEILVHIdxJAfkKICnwJAiEYH2PAkA0umTJSChXdNdVUN5q"
+			+ "SO8bKlocSHseIVnDYDubl6nA7xhmqU5iUjiEzuUJiEiUacUgFJlaV/4jbOSn"
+			+ "I3vQgLeFAkEAni+zN5r7CwZdV+EJBqRd2ZCWBgVfJAZAcpw6iIWchw+dYhKI"
+			+ "FmioNRobQ+g4wJhprwMKSDIETukPj3d9NDAlBwJAVxhn1grStavCunrnVNqc"
+			+ "BU+B1O8BiR4yPWnLMcRSyFRVJQA7HCp8JlDV6abXd8vPFfXuC9WN7rOvTKF8"
+			+ "Y0ZB9qANMAsGA1UdDzEEAwIAEA==");
+
+		private static readonly byte[] rfc4134ex5_1 = Base64.Decode(
+			"MIIBHgYJKoZIhvcNAQcDoIIBDzCCAQsCAQAxgcAwgb0CAQAwJjASMRAwDgYD"
+			+ "VQQDEwdDYXJsUlNBAhBGNGvHgABWvBHTbi7NXXHQMA0GCSqGSIb3DQEBAQUA"
+			+ "BIGAC3EN5nGIiJi2lsGPcP2iJ97a4e8kbKQz36zg6Z2i0yx6zYC4mZ7mX7FB"
+			+ "s3IWg+f6KgCLx3M1eCbWx8+MDFbbpXadCDgO8/nUkUNYeNxJtuzubGgzoyEd"
+			+ "8Ch4H/dd9gdzTd+taTEgS0ipdSJuNnkVY4/M652jKKHRLFf02hosdR8wQwYJ"
+			+ "KoZIhvcNAQcBMBQGCCqGSIb3DQMHBAgtaMXpRwZRNYAgDsiSf8Z9P43LrY4O"
+			+ "xUk660cu1lXeCSFOSOpOJ7FuVyU=");
+
+		private static readonly byte[] rfc4134ex5_2 = Base64.Decode(
+			"MIIBZQYJKoZIhvcNAQcDoIIBVjCCAVICAQIxggEAMIG9AgEAMCYwEjEQMA4G"
+			+ "A1UEAxMHQ2FybFJTQQIQRjRrx4AAVrwR024uzV1x0DANBgkqhkiG9w0BAQEF"
+			+ "AASBgJQmQojGi7Z4IP+CVypBmNFoCDoEp87khtgyff2N4SmqD3RxPx+8hbLQ"
+			+ "t9i3YcMwcap+aiOkyqjMalT03VUC0XBOGv+HYI3HBZm/aFzxoq+YOXAWs5xl"
+			+ "GerZwTOc9j6AYlK4qXvnztR5SQ8TBjlzytm4V7zg+TGrnGVNQBNw47Ewoj4C"
+			+ "AQQwDQQLTWFpbExpc3RSQzIwEAYLKoZIhvcNAQkQAwcCAToEGHcUr5MSJ/g9"
+			+ "HnJVHsQ6X56VcwYb+OfojTBJBgkqhkiG9w0BBwEwGgYIKoZIhvcNAwIwDgIC"
+			+ "AKAECJwE0hkuKlWhgCBeKNXhojuej3org9Lt7n+wWxOhnky5V50vSpoYRfRR"
+			+ "yw==");
+
+		[Test]
+		public void TestKeyTrans()
+		{
+			byte[] data = Encoding.ASCII.GetBytes("WallaWallaWashington");
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsEnvelopedDataGenerator.DesEde3Cbc);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+
+			Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.DesEde3Cbc);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);
+
+				byte[] recData = recipient.GetContent(ReciKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		[Test]
+		public void TestKeyTransRC4()
+		{
+			byte[] data = Encoding.ASCII.GetBytes("WallaWallaBouncyCastle");
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				"1.2.840.113549.3.4"); // RC4 OID
+
+			RecipientInformationStore  recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual(ed.EncryptionAlgOid, "1.2.840.113549.3.4");
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				byte[] recData = recipient.GetContent(ReciKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		[Test]
+		public void TestKeyTrans128RC4()
+		{
+			byte[] data = Encoding.ASCII.GetBytes("WallaWallaBouncyCastle");
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				"1.2.840.113549.3.4", 128);  // RC4 OID
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual(ed.EncryptionAlgOid, "1.2.840.113549.3.4");
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				byte[] recData = recipient.GetContent(ReciKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		[Test]
+		public void TestKeyTransOdes()
+		{
+			byte[] data = Encoding.ASCII.GetBytes("WallaWallaBouncyCastle");
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				OiwObjectIdentifiers.DesCbc.Id);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual(ed.EncryptionAlgOid, OiwObjectIdentifiers.DesCbc.Id);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				byte[] recData = recipient.GetContent(ReciKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		[Test]
+		public void TestKeyTransSmallAes()
+		{
+			byte[] data = new byte[] { 0, 1, 2, 3 };
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual(ed.EncryptionAlgOid,
+				CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				byte[] recData = recipient.GetContent(ReciKP.Private);
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		[Test]
+		public void TestKeyTransCast5()
+		{
+			TryKeyTrans(CmsEnvelopedDataGenerator.Cast5Cbc,
+				new DerObjectIdentifier(CmsEnvelopedDataGenerator.Cast5Cbc),
+				typeof(Asn1Sequence));
+		}
+
+		[Test]
+		public void TestKeyTransAes128()
+		{
+			TryKeyTrans(CmsEnvelopedDataGenerator.Aes128Cbc,
+				NistObjectIdentifiers.IdAes128Cbc,
+				typeof(DerOctetString));
+		}
+
+		[Test]
+		public void TestKeyTransAes192()
+		{
+			TryKeyTrans(CmsEnvelopedDataGenerator.Aes192Cbc,
+				NistObjectIdentifiers.IdAes192Cbc,
+				typeof(DerOctetString));
+		}
+
+		[Test]
+		public void TestKeyTransAes256()
+		{
+			TryKeyTrans(CmsEnvelopedDataGenerator.Aes256Cbc,
+				NistObjectIdentifiers.IdAes256Cbc,
+				typeof(DerOctetString));
+		}
+
+		[Test]
+		public void TestKeyTransSeed()
+		{
+			TryKeyTrans(CmsEnvelopedDataGenerator.SeedCbc,
+				KisaObjectIdentifiers.IdSeedCbc,
+				typeof(DerOctetString));
+		}
+
+		public void TestKeyTransCamellia128()
+		{
+			TryKeyTrans(CmsEnvelopedDataGenerator.Camellia128Cbc,
+				NttObjectIdentifiers.IdCamellia128Cbc,
+				typeof(DerOctetString));
+		}
+
+		public void TestKeyTransCamellia192()
+		{
+			TryKeyTrans(CmsEnvelopedDataGenerator.Camellia192Cbc,
+				NttObjectIdentifiers.IdCamellia192Cbc,
+				typeof(DerOctetString));
+		}
+
+		public void TestKeyTransCamellia256()
+		{
+			TryKeyTrans(CmsEnvelopedDataGenerator.Camellia256Cbc,
+				NttObjectIdentifiers.IdCamellia256Cbc,
+				typeof(DerOctetString));
+		}
+
+		private void TryKeyTrans(
+			string				generatorOID,
+			DerObjectIdentifier	checkOID,
+			Type				asn1Params)
+		{
+			byte[] data = Encoding.ASCII.GetBytes("WallaWallaWashington");
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			edGen.AddKeyTransRecipient(ReciCert);
+
+			CmsEnvelopedData ed = edGen.Generate(new CmsProcessableByteArray(data), generatorOID);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual(checkOID.Id, ed.EncryptionAlgOid);
+
+			if (asn1Params != null)
+			{
+				Assert.IsTrue(asn1Params.IsInstanceOfType(ed.EncryptionAlgorithmID.Parameters));
+			}
+
+			ArrayList c = new ArrayList(recipients.GetRecipients());
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);
+
+				byte[] recData = recipient.GetContent(ReciKP.Private);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		[Test]
+		public void TestErroneousKek()
+		{
+			byte[] data = Encoding.ASCII.GetBytes("WallaWallaWashington");
+			KeyParameter kek = ParameterUtilities.CreateKeyParameter(
+				"AES",
+				new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 });
+
+			CmsEnvelopedData ed = new CmsEnvelopedData(oldKEK);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.DesEde3Cbc);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(recipient.KeyEncryptionAlgOid, NistObjectIdentifiers.IdAes128Wrap.Id);
+
+				byte[] recData = recipient.GetContent(kek);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		[Test]
+		public void TestDesKek()
+		{
+			TryKekAlgorithm(CmsTestUtil.MakeDesEde192Key(), new DerObjectIdentifier("1.2.840.113549.1.9.16.3.6"));
+		}
+
+		[Test]
+		public void TestRC2128Kek()
+		{
+			TryKekAlgorithm(CmsTestUtil.MakeRC2128Key(), new DerObjectIdentifier("1.2.840.113549.1.9.16.3.7"));
+		}
+
+		[Test]
+		public void TestAes128Kek()
+		{
+			TryKekAlgorithm(CmsTestUtil.MakeAesKey(128), NistObjectIdentifiers.IdAes128Wrap);
+		}
+
+		[Test]
+		public void TestAes192Kek()
+		{
+			TryKekAlgorithm(CmsTestUtil.MakeAesKey(192), NistObjectIdentifiers.IdAes192Wrap);
+		}
+
+		[Test]
+		public void TestAes256Kek()
+		{
+			TryKekAlgorithm(CmsTestUtil.MakeAesKey(256), NistObjectIdentifiers.IdAes256Wrap);
+		}
+
+		[Test]
+		public void TestSeed128Kek()
+		{
+			TryKekAlgorithm(CmsTestUtil.MakeSeedKey(), KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap);
+		}
+
+		[Test]
+		public void TestCamellia128Kek()
+		{
+			TryKekAlgorithm(CmsTestUtil.MakeCamelliaKey(128), NttObjectIdentifiers.IdCamellia128Wrap);
+		}
+
+		[Test]
+		public void TestCamellia192Kek()
+		{
+			TryKekAlgorithm(CmsTestUtil.MakeCamelliaKey(192), NttObjectIdentifiers.IdCamellia192Wrap);
+		}
+
+		[Test]
+		public void TestCamellia256Kek()
+		{
+			TryKekAlgorithm(CmsTestUtil.MakeCamelliaKey(256), NttObjectIdentifiers.IdCamellia256Wrap);
+		}
+
+		private void TryKekAlgorithm(
+			KeyParameter		kek,
+			DerObjectIdentifier	algOid)
+		{
+			byte[] data = Encoding.ASCII.GetBytes("WallaWallaWashington");
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			byte[] kekId = new byte[] { 1, 2, 3, 4, 5 };
+
+			string keyAlgorithm = ParameterUtilities.GetCanonicalAlgorithmName(algOid.Id);
+
+			edGen.AddKekRecipient(keyAlgorithm, kek, kekId);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsEnvelopedDataGenerator.DesEde3Cbc);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.DesEde3Cbc);
+
+			ArrayList c = new ArrayList(recipients.GetRecipients());
+
+			Assert.IsTrue(c.Count > 0);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual(algOid.Id, recipient.KeyEncryptionAlgOid);
+
+				byte[] recData = recipient.GetContent(kek);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		[Test]
+		public void TestECKeyAgree()
+		{
+			byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			edGen.AddKeyAgreementRecipient(
+				CmsEnvelopedDataGenerator.ECDHSha1Kdf,
+				OrigECKP.Private,
+				OrigECKP.Public,
+				ReciECCert,
+				CmsEnvelopedDataGenerator.Aes128Wrap);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			ConfirmDataReceived(recipients, data, ReciECCert, ReciECKP.Private);
+			ConfirmNumberRecipients(recipients, 1);
+		}
+
+		[Test]
+		public void TestECMqvKeyAgree()
+		{
+			byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			edGen.AddKeyAgreementRecipient(
+				CmsEnvelopedDataGenerator.ECMqvSha1Kdf,
+				OrigECKP.Private,
+				OrigECKP.Public,
+				ReciECCert,
+				CmsEnvelopedDataGenerator.Aes128Wrap);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			ConfirmDataReceived(recipients, data, ReciECCert, ReciECKP.Private);
+			ConfirmNumberRecipients(recipients, 1);
+		}
+
+		[Test]
+		public void TestECMqvKeyAgreeMultiple()
+		{
+			byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			ArrayList recipientCerts = new ArrayList();
+			recipientCerts.Add(ReciECCert);
+			recipientCerts.Add(ReciECCert2);
+
+			edGen.AddKeyAgreementRecipients(
+				CmsEnvelopedDataGenerator.ECMqvSha1Kdf,
+				OrigECKP.Private,
+				OrigECKP.Public,
+				recipientCerts,
+				CmsEnvelopedDataGenerator.Aes128Wrap);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			ConfirmDataReceived(recipients, data, ReciECCert, ReciECKP.Private);
+			ConfirmDataReceived(recipients, data, ReciECCert2, ReciECKP2.Private);
+			ConfirmNumberRecipients(recipients, 2);
+		}
+
+		private static void ConfirmDataReceived(RecipientInformationStore recipients,
+			byte[] expectedData, X509Certificate reciCert, AsymmetricKeyParameter reciPrivKey)
+		{
+			RecipientID rid = new RecipientID();
+			rid.Issuer = PrincipalUtilities.GetIssuerX509Principal(reciCert);
+			rid.SerialNumber = reciCert.SerialNumber;
+
+			RecipientInformation recipient = recipients[rid];
+			Assert.IsNotNull(recipient);
+
+			byte[] actualData = recipient.GetContent(reciPrivKey);
+			Assert.IsTrue(Arrays.AreEqual(expectedData, actualData));
+		}
+
+		private static void ConfirmNumberRecipients(RecipientInformationStore recipients, int count)
+		{
+			Assert.AreEqual(count, recipients.GetRecipients().Count);
+		}
+
+		[Test]
+		public void TestECKeyAgreeVectors()
+		{
+			AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(ecKeyAgreeKey);
+
+			VerifyECKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.42", ecKeyAgreeMsgAES256);
+			VerifyECKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.2", ecKeyAgreeMsgAES128);
+			VerifyECKeyAgreeVectors(privKey, "1.2.840.113549.3.7", ecKeyAgreeMsgDESEDE);
+		}
+
+		[Test]
+		public void TestECMqvKeyAgreeVectors()
+		{
+			AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(ecKeyAgreeKey);
+
+			VerifyECMqvKeyAgreeVectors(privKey, "2.16.840.1.101.3.4.1.2", ecMqvKeyAgreeMsgAes128);
+		}
+
+		[Test]
+		public void TestPasswordAes256()
+		{
+			PasswordTest(CmsEnvelopedDataGenerator.Aes256Cbc);
+			PasswordUtf8Test(CmsEnvelopedDataGenerator.Aes256Cbc);
+		}
+
+		[Test]
+		public void TestPasswordDesEde()
+		{
+			PasswordTest(CmsEnvelopedDataGenerator.DesEde3Cbc);
+			PasswordUtf8Test(CmsEnvelopedDataGenerator.DesEde3Cbc);
+		}
+
+		[Test]
+		public void TestRfc4134Ex5_1()
+		{
+			byte[] data = Hex.Decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e");
+
+//			KeyFactory kFact = KeyFactory.GetInstance("RSA");
+//			Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt));
+			AsymmetricKeyParameter key = PrivateKeyFactory.CreateKey(bobPrivRsaEncrypt);
+
+			CmsEnvelopedData ed = new CmsEnvelopedData(rfc4134ex5_1);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual("1.2.840.113549.3.7", ed.EncryptionAlgOid);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				byte[] recData = recipient.GetContent(key);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		[Test]
+		public void TestRfc4134Ex5_2()
+		{
+			byte[] data = Hex.Decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e");
+
+//			KeyFactory kFact = KeyFactory.GetInstance("RSA");
+//			Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt));
+			AsymmetricKeyParameter key = PrivateKeyFactory.CreateKey(bobPrivRsaEncrypt);
+
+			CmsEnvelopedData ed = new CmsEnvelopedData(rfc4134ex5_2);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual("1.2.840.113549.3.2", ed.EncryptionAlgOid);
+
+			ICollection c = recipients.GetRecipients();
+			IEnumerator e = c.GetEnumerator();
+
+			if (e.MoveNext())
+			{
+				do
+				{
+					RecipientInformation recipient = (RecipientInformation) e.Current;
+
+					if (recipient is KeyTransRecipientInformation)
+					{
+						byte[] recData = recipient.GetContent(key);
+
+						Assert.IsTrue(Arrays.AreEqual(data, recData));
+					}
+				}
+				while (e.MoveNext());
+			}
+			else
+			{
+				Assert.Fail("no recipient found");
+			}
+		}
+
+		[Test]
+		public void TestOriginatorInfo()
+		{
+			CmsEnvelopedData env = new CmsEnvelopedData(CmsSampleMessages.originatorMessage);
+
+			RecipientInformationStore  recipients = env.GetRecipientInfos();
+
+			Assert.AreEqual(CmsEnvelopedDataGenerator.DesEde3Cbc, env.EncryptionAlgOid);
+		}
+
+		private void PasswordTest(
+			string algorithm)
+		{
+			byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			edGen.AddPasswordRecipient(new Pkcs5Scheme2PbeKey("password".ToCharArray(), new byte[20], 5), algorithm);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (PasswordRecipientInformation recipient in c)
+			{
+				CmsPbeKey key = new Pkcs5Scheme2PbeKey("password".ToCharArray(), recipient.KeyDerivationAlgorithm);
+
+				byte[] recData = recipient.GetContent(key);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		private void PasswordUtf8Test(
+			string algorithm)
+		{
+			byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");
+
+			CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+			edGen.AddPasswordRecipient(
+				new Pkcs5Scheme2Utf8PbeKey("abc\u5639\u563b".ToCharArray(), new byte[20], 5),
+				algorithm);
+
+			CmsEnvelopedData ed = edGen.Generate(
+				new CmsProcessableByteArray(data),
+				CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (PasswordRecipientInformation recipient in c)
+			{
+				CmsPbeKey key = new Pkcs5Scheme2Utf8PbeKey(
+					"abc\u5639\u563b".ToCharArray(), recipient.KeyDerivationAlgorithm);
+
+				byte[] recData = recipient.GetContent(key);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		private void VerifyECKeyAgreeVectors(
+			AsymmetricKeyParameter	privKey,
+			string					wrapAlg,
+			byte[]					message)
+		{
+			byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");
+
+			CmsEnvelopedData ed = new CmsEnvelopedData(message);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			Assert.AreEqual(wrapAlg, ed.EncryptionAlgOid);
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual("1.3.133.16.840.63.0.2", recipient.KeyEncryptionAlgOid);
+
+				byte[] recData = recipient.GetContent(privKey);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+
+		private void VerifyECMqvKeyAgreeVectors(
+			AsymmetricKeyParameter	privKey,
+			string					wrapAlg,
+			byte[]					message)
+		{
+			byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");
+
+			CmsEnvelopedData ed = new CmsEnvelopedData(message);
+
+			RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+			ICollection c = recipients.GetRecipients();
+
+			Assert.AreEqual(wrapAlg, ed.EncryptionAlgOid);
+			Assert.AreEqual(1, c.Count);
+
+			foreach (RecipientInformation recipient in c)
+			{
+				Assert.AreEqual("1.3.133.16.840.63.0.16", recipient.KeyEncryptionAlgOid);
+
+				byte[] recData = recipient.GetContent(privKey);
+
+				Assert.IsTrue(Arrays.AreEqual(data, recData));
+			}
+		}
+	}
+}
diff --git a/crypto/test/src/cms/test/MiscDataStreamTest.cs b/crypto/test/src/cms/test/MiscDataStreamTest.cs
new file mode 100644
index 000000000..f958d058f
--- /dev/null
+++ b/crypto/test/src/cms/test/MiscDataStreamTest.cs
@@ -0,0 +1,221 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.X509.Store;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	[TestFixture]
+	public class MiscDataStreamTest
+	{
+		private const string TestMessage = "Hello World!";
+		private const string SignDN = "O=Bouncy Castle, C=AU";
+		private static AsymmetricCipherKeyPair signKP;
+		private static X509Certificate signCert;
+
+		private const string OrigDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU";
+		private static AsymmetricCipherKeyPair origKP;
+		private static X509Certificate origCert;
+
+		private const string ReciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
+		//		private static AsymmetricCipherKeyPair reciKP;
+		//		private static X509Certificate reciCert;
+
+		private static AsymmetricCipherKeyPair origDsaKP;
+		private static X509Certificate origDsaCert;
+
+		private static X509Crl signCrl;
+		private static X509Crl origCrl;
+
+		private static AsymmetricCipherKeyPair SignKP
+		{
+			get { return signKP == null ? (signKP = CmsTestUtil.MakeKeyPair()) : signKP; }
+		}
+
+		private static AsymmetricCipherKeyPair OrigKP
+		{
+			get { return origKP == null ? (origKP = CmsTestUtil.MakeKeyPair()) : origKP; }
+		}
+
+		//		private static AsymmetricCipherKeyPair ReciKP
+		//		{
+		//			get { return reciKP == null ? (reciKP = CmsTestUtil.MakeKeyPair()) : reciKP; }
+		//		}
+
+		private static AsymmetricCipherKeyPair OrigDsaKP
+		{
+			get { return origDsaKP == null ? (origDsaKP = CmsTestUtil.MakeDsaKeyPair()) : origDsaKP; }
+		}
+
+		private static X509Certificate SignCert
+		{
+			get { return signCert == null ? (signCert = CmsTestUtil.MakeCertificate(SignKP, SignDN, SignKP, SignDN)) : signCert; }
+		}
+
+		private static X509Certificate OrigCert
+		{
+			get { return origCert == null ? (origCert = CmsTestUtil.MakeCertificate(OrigKP, OrigDN, SignKP, SignDN)) : origCert; }
+		}
+
+		//		private static X509Certificate ReciCert
+		//		{
+		//			get { return reciCert == null ? (reciCert = CmsTestUtil.MakeCertificate(ReciKP, ReciDN, SignKP, SignDN)) : reciCert; }
+		//		}
+
+		private static X509Certificate OrigDsaCert
+		{
+			get { return origDsaCert == null ? (origDsaCert = CmsTestUtil.MakeCertificate(OrigDsaKP, OrigDN, SignKP, SignDN)) : origDsaCert; }
+		}
+
+		private static X509Crl SignCrl
+		{
+			get { return signCrl == null ? (signCrl = CmsTestUtil.MakeCrl(SignKP)) : signCrl; }
+		}
+
+		private static X509Crl OrigCrl
+		{
+			get { return origCrl == null ? (origCrl = CmsTestUtil.MakeCrl(OrigKP)) : origCrl; }
+		}
+
+		private void VerifySignatures(
+			CmsSignedDataParser	sp,
+			byte[]				contentDigest)
+		{
+			IX509Store certStore = sp.GetCertificates("Collection");
+			SignerInformationStore signers = sp.GetSignerInfos();
+
+			foreach (SignerInformation signer in signers.GetSigners())
+			{
+				ICollection certCollection = certStore.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate	cert = (X509Certificate) certEnum.Current;
+
+				Assert.IsTrue(signer.Verify(cert));
+
+				if (contentDigest != null)
+				{
+					Assert.IsTrue(Arrays.AreEqual(contentDigest, signer.GetContentDigest()));
+				}
+			}
+		}
+
+		private void VerifySignatures(
+			CmsSignedDataParser sp)
+		{
+			VerifySignatures(sp, null);
+		}
+
+		private void VerifyEncodedData(
+			MemoryStream bOut)
+		{
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+
+			sp.Close();
+		}
+
+		private void CheckSigParseable(byte[] sig)
+		{
+			CmsSignedDataParser sp = new CmsSignedDataParser(sig);
+			sp.Version.ToString();
+			CmsTypedStream sc = sp.GetSignedContent();
+			if (sc != null)
+			{
+				sc.Drain();
+			}
+			sp.GetAttributeCertificates("Collection");
+			sp.GetCertificates("Collection");
+			sp.GetCrls("Collection");
+			sp.GetSignerInfos();
+			sp.Close();
+		}
+
+		[Test]
+		public void TestSha1WithRsa()
+		{
+			IList certList = new ArrayList();
+			IList crlList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			crlList.Add(SignCrl);
+			crlList.Add(OrigCrl);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+			IX509Store x509Crls = X509StoreFactory.Create(
+				"CRL/Collection",
+				new X509CollectionStoreParameters(crlList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+			gen.AddCrls(x509Crls);
+
+			Stream sigOut = gen.Open(bOut);
+
+			CmsCompressedDataStreamGenerator cGen = new CmsCompressedDataStreamGenerator();
+
+			Stream cOut = cGen.Open(sigOut, CmsCompressedDataStreamGenerator.ZLib);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			cOut.Write(testBytes, 0, testBytes.Length);
+
+			cOut.Close();
+
+			sigOut.Close();
+
+			CheckSigParseable(bOut.ToArray());
+
+			// generate compressed stream
+			MemoryStream cDataOut = new MemoryStream();
+		    
+			cOut = cGen.Open(cDataOut, CmsCompressedDataStreamGenerator.ZLib);
+
+			cOut.Write(testBytes, 0, testBytes.Length);
+
+			cOut.Close();
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(
+				new CmsTypedStream(new MemoryStream(cDataOut.ToArray(), false)), bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			//
+			// compute expected content digest
+			//
+			IDigest md = DigestUtilities.GetDigest("SHA1");
+			byte[] cDataOutBytes = cDataOut.ToArray();
+			md.BlockUpdate(cDataOutBytes, 0, cDataOutBytes.Length);
+			byte[] hash = DigestUtilities.DoFinal(md);
+
+			VerifySignatures(sp, hash);
+		}
+	}
+}
diff --git a/crypto/test/src/cms/test/Rfc4134Test.cs b/crypto/test/src/cms/test/Rfc4134Test.cs
new file mode 100644
index 000000000..3bfbd1358
--- /dev/null
+++ b/crypto/test/src/cms/test/Rfc4134Test.cs
@@ -0,0 +1,344 @@
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.X509.Store;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	[TestFixture]
+	public class Rfc4134Test
+	{
+		private static readonly byte[] exContent = GetRfc4134Data("ExContent.bin");
+		private static readonly byte[] sha1 = Hex.Decode("406aec085279ba6e16022d9e0629c0229687dd48");
+
+		[Test]
+		public void Test4_1()
+		{
+			byte[] data = GetRfc4134Data("4.1.bin");
+			CmsSignedData signedData = new CmsSignedData(data);
+
+			VerifySignatures(signedData);
+
+			CmsSignedDataParser parser = new CmsSignedDataParser(data);
+
+			VerifySignatures(parser);
+		}
+
+		[Test]
+		public void Test4_2()
+		{
+			byte[] data = GetRfc4134Data("4.2.bin");
+			CmsSignedData signedData = new CmsSignedData(data);
+
+			VerifySignatures(signedData);
+
+			CmsSignedDataParser parser = new CmsSignedDataParser(data);
+
+			VerifySignatures(parser);
+		}
+
+		[Test]
+		public void Test4_3()
+		{
+			CmsProcessableByteArray unencap = new CmsProcessableByteArray(exContent);
+			byte[] data = GetRfc4134Data("4.3.bin");
+			CmsSignedData signedData = new CmsSignedData(unencap, data);
+
+			VerifySignatures(signedData, sha1);
+
+			CmsSignedDataParser parser = new CmsSignedDataParser(
+				new CmsTypedStream(unencap.GetInputStream()), data);
+
+			VerifySignatures(parser);
+		}
+
+		[Test]
+		public void Test4_4()
+		{
+			byte[] data = GetRfc4134Data("4.4.bin");
+			byte[] counterSigCert = GetRfc4134Data("AliceRSASignByCarl.cer");
+			CmsSignedData signedData = new CmsSignedData(data);
+
+			VerifySignatures(signedData, sha1);
+
+			VerifySignerInfo4_4(GetFirstSignerInfo(signedData.GetSignerInfos()), counterSigCert);
+
+			CmsSignedDataParser parser = new CmsSignedDataParser(data);
+
+			VerifySignatures(parser);
+
+			VerifySignerInfo4_4(GetFirstSignerInfo(parser.GetSignerInfos()), counterSigCert);
+		}
+
+		[Test]
+		public void Test4_5()
+		{
+			byte[] data = GetRfc4134Data("4.5.bin");
+			CmsSignedData signedData = new CmsSignedData(data);
+
+			VerifySignatures(signedData);
+
+			CmsSignedDataParser parser = new CmsSignedDataParser(data);
+
+			VerifySignatures(parser);
+		}
+
+		[Test]
+		public void Test4_6()
+		{
+			byte[] data = GetRfc4134Data("4.6.bin");
+			CmsSignedData signedData = new CmsSignedData(data);
+
+			VerifySignatures(signedData);
+
+			CmsSignedDataParser parser = new CmsSignedDataParser(data);
+
+			VerifySignatures(parser);
+		}
+		
+		[Test]
+		public void Test4_7()
+		{
+			byte[] data = GetRfc4134Data("4.7.bin");
+			CmsSignedData signedData = new CmsSignedData(data);
+
+			VerifySignatures(signedData);
+
+			CmsSignedDataParser parser = new CmsSignedDataParser(data);
+
+			VerifySignatures(parser);
+		}
+
+		[Test]
+		public void Test5_1()
+		{
+			byte[] data = GetRfc4134Data("5.1.bin");
+			CmsEnvelopedData envelopedData = new CmsEnvelopedData(data);
+
+			VerifyEnvelopedData(envelopedData, CmsEnvelopedDataGenerator.DesEde3Cbc);
+
+			CmsEnvelopedDataParser envelopedParser = new CmsEnvelopedDataParser(data);
+
+			VerifyEnvelopedData(envelopedParser, CmsEnvelopedDataGenerator.DesEde3Cbc);
+		}
+
+		[Test]
+		public void Test5_2()
+		{
+			byte[] data = GetRfc4134Data("5.2.bin");
+			CmsEnvelopedData envelopedData = new CmsEnvelopedData(data);
+
+			VerifyEnvelopedData(envelopedData, CmsEnvelopedDataGenerator.RC2Cbc);
+
+			CmsEnvelopedDataParser envelopedParser = new CmsEnvelopedDataParser(data);
+
+			VerifyEnvelopedData(envelopedParser, CmsEnvelopedDataGenerator.RC2Cbc);
+		}
+
+		private void VerifyEnvelopedData(CmsEnvelopedData envelopedData, string symAlgorithmOID)
+		{
+			byte[] privKeyData = GetRfc4134Data("BobPrivRSAEncrypt.pri");
+			AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privKeyData);
+			Assert.IsTrue(privKey.IsPrivate);
+			Assert.IsTrue(privKey is RsaKeyParameters);
+
+			RecipientInformationStore recipients = envelopedData.GetRecipientInfos();
+
+			Assert.AreEqual(envelopedData.EncryptionAlgOid, symAlgorithmOID);
+
+			ArrayList c = new ArrayList(recipients.GetRecipients());
+			Assert.LessOrEqual(1, c.Count);
+			Assert.GreaterOrEqual(2, c.Count);
+
+			VerifyRecipient((RecipientInformation)c[0], privKey);
+
+			if (c.Count == 2)
+			{
+				RecipientInformation recInfo = (RecipientInformation)c[1];
+
+				Assert.AreEqual(PkcsObjectIdentifiers.IdAlgCmsRC2Wrap.Id, recInfo.KeyEncryptionAlgOid);
+			}
+		}
+
+		private void VerifyEnvelopedData(CmsEnvelopedDataParser envelopedParser, string symAlgorithmOID)
+		{
+			byte[] privKeyData = GetRfc4134Data("BobPrivRSAEncrypt.pri");
+			AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privKeyData);
+			Assert.IsTrue(privKey.IsPrivate);
+			Assert.IsTrue(privKey is RsaKeyParameters);
+
+			RecipientInformationStore recipients = envelopedParser.GetRecipientInfos();
+
+			Assert.AreEqual(envelopedParser.EncryptionAlgOid, symAlgorithmOID);
+
+			ArrayList c = new ArrayList(recipients.GetRecipients());
+			Assert.LessOrEqual(1, c.Count);
+			Assert.GreaterOrEqual(2, c.Count);
+
+			VerifyRecipient((RecipientInformation)c[0], privKey);
+
+			if (c.Count == 2)
+			{
+				RecipientInformation recInfo = (RecipientInformation)c[1];
+
+				Assert.AreEqual(PkcsObjectIdentifiers.IdAlgCmsRC2Wrap.Id, recInfo.KeyEncryptionAlgOid);
+			}
+		}
+
+		private void VerifyRecipient(RecipientInformation recipient, AsymmetricKeyParameter privKey)
+		{
+			Assert.IsTrue(privKey.IsPrivate);
+
+			Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);
+
+			byte[] recData = recipient.GetContent(privKey);
+
+			Assert.IsTrue(Arrays.AreEqual(exContent, recData));
+		}
+
+		private void VerifySignerInfo4_4(SignerInformation signerInfo, byte[] counterSigCert)
+		{
+			VerifyCounterSignature(signerInfo, counterSigCert);
+
+			VerifyContentHint(signerInfo);
+		}
+
+		private SignerInformation GetFirstSignerInfo(SignerInformationStore store)
+		{
+			IEnumerator e = store.GetSigners().GetEnumerator();
+			e.MoveNext();
+			return (SignerInformation)e.Current;
+		}
+
+		private void VerifyCounterSignature(SignerInformation signInfo, byte[] certificate)
+		{
+			SignerInformation csi = GetFirstSignerInfo(signInfo.GetCounterSignatures());
+
+			X509Certificate cert = new X509CertificateParser().ReadCertificate(certificate);
+
+			Assert.IsTrue(csi.Verify(cert));
+		}
+
+		private void VerifyContentHint(SignerInformation signInfo)
+		{
+			Asn1.Cms.AttributeTable attrTable = signInfo.UnsignedAttributes;
+
+			Asn1.Cms.Attribute attr = attrTable[CmsAttributes.ContentHint];
+
+			Assert.AreEqual(1, attr.AttrValues.Count);
+		
+			Asn1EncodableVector v = new Asn1EncodableVector(
+				new DerUtf8String("Content Hints Description Buffer"),
+				CmsObjectIdentifiers.Data);
+
+			Assert.IsTrue(attr.AttrValues[0].Equals(new DerSequence(v)));
+		}
+
+		private void VerifySignatures(CmsSignedData s, byte[] contentDigest)
+		{
+			IX509Store x509Certs = s.GetCertificates("Collection");
+			IX509Store x509Crls = s.GetCrls("Collection");
+			SignerInformationStore signers = s.GetSignerInfos();
+
+			foreach (SignerInformation signer in signers.GetSigners())
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				VerifySigner(signer, cert);
+
+				if (contentDigest != null)
+				{
+					Assert.IsTrue(Arrays.AreEqual(contentDigest, signer.GetContentDigest()));
+				}
+			}
+
+			ICollection certColl = x509Certs.GetMatches(null);
+			ICollection crlColl = x509Crls.GetMatches(null);
+
+			Assert.AreEqual(certColl.Count, s.GetCertificates("Collection").GetMatches(null).Count);
+			Assert.AreEqual(crlColl.Count, s.GetCrls("Collection").GetMatches(null).Count);
+		}
+
+		private void VerifySignatures(CmsSignedData s)
+		{
+			VerifySignatures(s, null);
+		}
+
+		private void VerifySignatures(CmsSignedDataParser sp)
+		{
+	        CmsTypedStream sc = sp.GetSignedContent();
+	        if (sc != null)
+	        {
+	            sc.Drain();
+	        }
+			
+			IX509Store x509Certs = sp.GetCertificates("Collection");
+			SignerInformationStore signers = sp.GetSignerInfos();
+
+			foreach (SignerInformation signer in signers.GetSigners())
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate)certEnum.Current;
+
+				VerifySigner(signer, cert);
+			}
+		}
+
+		private void VerifySigner(SignerInformation signer, X509Certificate cert)
+		{
+			if (cert.GetPublicKey() is DsaPublicKeyParameters)
+			{
+				DsaPublicKeyParameters key = (DsaPublicKeyParameters)cert.GetPublicKey();
+
+				if (key.Parameters == null)
+				{
+					Assert.IsTrue(signer.Verify(GetInheritedKey(key)));
+				}
+				else
+				{
+					Assert.IsTrue(signer.Verify(cert));
+				}
+			}
+			else
+			{
+				Assert.IsTrue(signer.Verify(cert));
+			}
+		}
+
+		private DsaPublicKeyParameters GetInheritedKey(DsaPublicKeyParameters dsaPubKey)
+		{
+			X509Certificate cert = new X509CertificateParser().ReadCertificate(
+				GetRfc4134Data("CarlDSSSelf.cer"));
+
+			DsaParameters dsaParams = ((DsaPublicKeyParameters)cert.GetPublicKey()).Parameters;
+
+			return new DsaPublicKeyParameters(dsaPubKey.Y, dsaParams);
+		}
+
+		private static byte[] GetRfc4134Data(string name)
+		{
+			return Streams.ReadAll(SimpleTest.GetTestDataAsStream("rfc4134." + name));
+		}
+	}
+}
diff --git a/crypto/test/src/cms/test/SignedDataStreamTest.cs b/crypto/test/src/cms/test/SignedDataStreamTest.cs
new file mode 100644
index 000000000..29b0db8f4
--- /dev/null
+++ b/crypto/test/src/cms/test/SignedDataStreamTest.cs
@@ -0,0 +1,1215 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.X509.Store;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	[TestFixture]
+	public class SignedDataStreamTest
+	{
+		private const string TestMessage = "Hello World!";
+		private const string SignDN = "O=Bouncy Castle, C=AU";
+		private static AsymmetricCipherKeyPair signKP;
+		private static X509Certificate signCert;
+
+		private const string OrigDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU";
+		private static AsymmetricCipherKeyPair origKP;
+		private static X509Certificate origCert;
+
+		private const string ReciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
+//		private static AsymmetricCipherKeyPair reciKP;
+//		private static X509Certificate reciCert;
+
+		private static AsymmetricCipherKeyPair origDsaKP;
+		private static X509Certificate origDsaCert;
+
+		private static X509Crl signCrl;
+		private static X509Crl origCrl;
+
+		private static AsymmetricCipherKeyPair SignKP
+		{
+			get { return signKP == null ? (signKP = CmsTestUtil.MakeKeyPair()) : signKP; }
+		}
+
+		private static AsymmetricCipherKeyPair OrigKP
+		{
+			get { return origKP == null ? (origKP = CmsTestUtil.MakeKeyPair()) : origKP; }
+		}
+
+//		private static AsymmetricCipherKeyPair ReciKP
+//		{
+//			get { return reciKP == null ? (reciKP = CmsTestUtil.MakeKeyPair()) : reciKP; }
+//		}
+
+		private static AsymmetricCipherKeyPair OrigDsaKP
+		{
+			get { return origDsaKP == null ? (origDsaKP = CmsTestUtil.MakeDsaKeyPair()) : origDsaKP; }
+		}
+
+		private static X509Certificate SignCert
+		{
+			get { return signCert == null ? (signCert = CmsTestUtil.MakeCertificate(SignKP, SignDN, SignKP, SignDN)) : signCert; }
+		}
+
+		private static X509Certificate OrigCert
+		{
+			get { return origCert == null ? (origCert = CmsTestUtil.MakeCertificate(OrigKP, OrigDN, SignKP, SignDN)) : origCert; }
+		}
+
+//		private static X509Certificate ReciCert
+//		{
+//			get { return reciCert == null ? (reciCert = CmsTestUtil.MakeCertificate(ReciKP, ReciDN, SignKP, SignDN)) : reciCert; }
+//		}
+
+		private static X509Certificate OrigDsaCert
+		{
+			get { return origDsaCert == null ? (origDsaCert = CmsTestUtil.MakeCertificate(OrigDsaKP, OrigDN, SignKP, SignDN)) : origDsaCert; }
+		}
+
+		private static X509Crl SignCrl
+		{
+			get { return signCrl == null ? (signCrl = CmsTestUtil.MakeCrl(SignKP)) : signCrl; }
+		}
+
+		private static X509Crl OrigCrl
+		{
+			get { return origCrl == null ? (origCrl = CmsTestUtil.MakeCrl(OrigKP)) : origCrl; }
+		}
+
+		private void VerifySignatures(
+			CmsSignedDataParser	sp,
+			byte[]				contentDigest)
+		{
+			IX509Store certStore = sp.GetCertificates("Collection");
+			SignerInformationStore signers = sp.GetSignerInfos();
+
+			foreach (SignerInformation signer in signers.GetSigners())
+			{
+				ICollection certCollection = certStore.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate	cert = (X509Certificate) certEnum.Current;
+
+				Assert.IsTrue(signer.Verify(cert));
+
+				if (contentDigest != null)
+				{
+					Assert.IsTrue(Arrays.AreEqual(contentDigest, signer.GetContentDigest()));
+				}
+			}
+		}
+
+		private void VerifySignatures(
+			CmsSignedDataParser sp)
+		{
+			VerifySignatures(sp, null);
+		}
+
+		private void VerifyEncodedData(
+			MemoryStream bOut)
+		{
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+
+			sp.Close();
+		}
+
+	    private void CheckSigParseable(byte[] sig)
+	    {
+	        CmsSignedDataParser sp = new CmsSignedDataParser(sig);
+	        sp.Version.ToString();
+	        CmsTypedStream sc = sp.GetSignedContent();
+	        if (sc != null)
+	        {
+	            sc.Drain();
+	        }
+	        sp.GetAttributeCertificates("Collection");
+	        sp.GetCertificates("Collection");
+	        sp.GetCrls("Collection");
+	        sp.GetSignerInfos();
+	        sp.Close();
+	    }
+
+		[Test]
+		public void TestEarlyInvalidKeyException()
+		{
+			try
+			{
+				CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+				gen.AddSigner(OrigKP.Private, OrigCert,
+					"DSA", // DOESN'T MATCH KEY ALG
+					CmsSignedDataStreamGenerator.DigestSha1);
+
+				Assert.Fail("Expected InvalidKeyException in AddSigner");
+			}
+			catch (InvalidKeyException)
+			{
+				// Ignore
+			}
+		}
+
+		[Test]
+		public void TestEarlyNoSuchAlgorithmException()
+		{
+			try
+			{
+				CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+				gen.AddSigner(OrigKP.Private, OrigCert,
+					CmsSignedDataStreamGenerator.DigestSha1, // BAD OID!
+					CmsSignedDataStreamGenerator.DigestSha1);
+
+				Assert.Fail("Expected NoSuchAlgorithmException in AddSigner");
+			}
+			catch (SecurityUtilityException)
+			{
+				// Ignore
+			}
+		}
+
+		[Test]
+		public void TestSha1EncapsulatedSignature()
+		{
+			byte[]  encapSigData = Base64.Decode(
+				"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"
+				+ "n7MsJMoKN3Kd2Vzh6s10PFgeAAAAAAAA");
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(encapSigData);
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+		}
+
+//		[Test]
+//		public void TestSha1WithRsaNoAttributes()
+//		{
+//			IList certList = new ArrayList();
+//			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes(TestMessage));
+//
+//			certList.Add(OrigCert);
+//			certList.Add(SignCert);
+//
+//			IX509Store x509Certs = X509StoreFactory.Create(
+//				"Certificate/Collection",
+//				new X509CollectionStoreParameters(certList));
+//
+//			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+//
+//			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+//
+//			gen.AddCertificates(x509Certs);
+//
+//			CmsSignedData s = gen.Generate(CmsSignedDataGenerator.Data, msg, false, false);
+//
+//			CmsSignedDataParser sp = new CmsSignedDataParser(
+//				new CmsTypedStream(new MemoryStream(Encoding.ASCII.GetBytes(TestMessage), false)), s.GetEncoded());
+//
+//			sp.GetSignedContent().Drain();
+//
+//			//
+//			// compute expected content digest
+//			//
+//			IDigest md = DigestUtilities.GetDigest("SHA1");
+//
+//			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+//			md.BlockUpdate(testBytes, 0, testBytes.Length);
+//			byte[] hash = DigestUtilities.DoFinal(md);
+//
+//			VerifySignatures(sp, hash);
+//		}
+
+//		[Test]
+//		public void TestDsaNoAttributes()
+//		{
+//			IList certList = new ArrayList();
+//			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes(TestMessage));
+//
+//			certList.Add(OrigDsaCert);
+//			certList.Add(SignCert);
+//
+//			IX509Store x509Certs = X509StoreFactory.Create(
+//				"Certificate/Collection",
+//				new X509CollectionStoreParameters(certList));
+//
+//			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+//
+//			gen.AddSigner(OrigDsaKP.Private, OrigDsaCert, CmsSignedDataGenerator.DigestSha1);
+//
+//			gen.AddCertificates(x509Certs);
+//
+//			CmsSignedData s = gen.Generate(CmsSignedDataGenerator.Data, msg, false, false);
+//
+//			CmsSignedDataParser sp = new CmsSignedDataParser(
+//				new CmsTypedStream(
+//				new MemoryStream(Encoding.ASCII.GetBytes(TestMessage), false)),
+//				s.GetEncoded());
+//
+//			sp.GetSignedContent().Drain();
+//
+//			//
+//			// compute expected content digest
+//			//
+//			IDigest md = DigestUtilities.GetDigest("SHA1");
+//
+//			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+//			md.BlockUpdate(testBytes, 0, testBytes.Length);
+//			byte[] hash = DigestUtilities.DoFinal(md);
+//
+//			VerifySignatures(sp, hash);
+//		}
+
+		[Test]
+		public void TestSha1WithRsa()
+		{
+			IList certList = new ArrayList();
+			IList crlList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			crlList.Add(SignCrl);
+			crlList.Add(OrigCrl);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+			IX509Store x509Crls = X509StoreFactory.Create(
+				"CRL/Collection",
+				new X509CollectionStoreParameters(crlList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+			gen.AddCrls(x509Crls);
+
+			Stream sigOut = gen.Open(bOut);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CheckSigParseable(bOut.ToArray());
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(
+				new CmsTypedStream(new MemoryStream(testBytes, false)), bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			//
+			// compute expected content digest
+			//
+			IDigest md = DigestUtilities.GetDigest("SHA1");
+			md.BlockUpdate(testBytes, 0, testBytes.Length);
+			byte[] hash = DigestUtilities.DoFinal(md);
+
+			VerifySignatures(sp, hash);
+
+			//
+			// try using existing signer
+			//
+			gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigners(sp.GetSignerInfos());
+
+			gen.AddCertificates(sp.GetCertificates("Collection"));
+			gen.AddCrls(sp.GetCrls("Collection"));
+
+			bOut.SetLength(0);
+
+			sigOut = gen.Open(bOut, true);
+
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			VerifyEncodedData(bOut);
+
+			//
+			// look for the CRLs
+			//
+			ArrayList col = new ArrayList(x509Crls.GetMatches(null));
+
+			Assert.AreEqual(2, col.Count);
+			Assert.IsTrue(col.Contains(SignCrl));
+			Assert.IsTrue(col.Contains(OrigCrl));
+		}
+
+		[Test]
+		public void TestSha1WithRsaNonData()
+		{
+			IList certList = new ArrayList();
+			IList crlList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			crlList.Add(SignCrl);
+			crlList.Add(OrigCrl);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+			IX509Store x509Crls = X509StoreFactory.Create(
+				"CRL/Collection",
+				new X509CollectionStoreParameters(crlList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+			gen.AddCrls(x509Crls);
+
+			Stream sigOut = gen.Open(bOut, "1.2.3.4", true);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			CmsTypedStream stream = sp.GetSignedContent();
+
+			Assert.AreEqual("1.2.3.4", stream.ContentType);
+
+			stream.Drain();
+
+			//
+			// compute expected content digest
+			//
+			IDigest md = DigestUtilities.GetDigest("SHA1");
+			md.BlockUpdate(testBytes, 0, testBytes.Length);
+			byte[] hash = DigestUtilities.DoFinal(md);
+
+			VerifySignatures(sp, hash);
+		}
+
+		[Test]
+		public void TestSha1AndMD5WithRsa()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddDigests(CmsSignedDataStreamGenerator.DigestSha1,
+				CmsSignedDataStreamGenerator.DigestMD5);
+
+			Stream sigOut = gen.Open(bOut);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			gen.AddCertificates(x509Certs);
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestMD5);
+
+			sigOut.Close();
+
+			CheckSigParseable(bOut.ToArray());
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(
+				new CmsTypedStream(new MemoryStream(testBytes, false)), bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+		}
+
+		[Test]
+		public void TestSha1WithRsaEncapsulatedBufferedStream()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			//
+			// find unbuffered length
+			//
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut, true);
+
+			for (int i = 0; i != 2000; i++)
+			{
+				sigOut.WriteByte((byte)(i & 0xff));
+			}
+
+			sigOut.Close();
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+
+			int unbufferedLength = bOut.ToArray().Length;
+
+			//
+			// find buffered length with buffered stream - should be equal
+			//
+			bOut.SetLength(0);
+
+			gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			sigOut = gen.Open(bOut, true);
+
+			byte[] data = new byte[2000];
+			for (int i = 0; i != 2000; i++)
+			{
+				data[i] = (byte)(i & 0xff);
+			}
+
+			Streams.PipeAll(new MemoryStream(data, false), sigOut);
+			sigOut.Close();
+
+			VerifyEncodedData(bOut);
+
+			Assert.AreEqual(unbufferedLength, bOut.ToArray().Length);
+		}
+
+		[Test]
+		public void TestSha1WithRsaEncapsulatedBuffered()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			//
+			// find unbuffered length
+			//
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut, true);
+
+			for (int i = 0; i != 2000; i++)
+			{
+				sigOut.WriteByte((byte)(i & 0xff));
+			}
+
+			sigOut.Close();
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+
+			int unbufferedLength = bOut.ToArray().Length;
+
+			//
+			// find buffered length - buffer size less than default
+			//
+			bOut.SetLength(0);
+
+			gen = new CmsSignedDataStreamGenerator();
+
+			gen.SetBufferSize(300);
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			sigOut = gen.Open(bOut, true);
+
+			for (int i = 0; i != 2000; i++)
+			{
+				sigOut.WriteByte((byte)(i & 0xff));
+			}
+
+			sigOut.Close();
+
+			VerifyEncodedData(bOut);
+
+			Assert.IsTrue(unbufferedLength < bOut.ToArray().Length);
+		}
+
+		[Test]
+		public void TestSha1WithRsaEncapsulated()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut, true);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+
+			byte[] contentDigest = (byte[])gen.GetGeneratedDigests()[CmsSignedGenerator.DigestSha1];
+
+			ArrayList signers = new ArrayList(sp.GetSignerInfos().GetSigners());
+
+			AttributeTable table = ((SignerInformation) signers[0]).SignedAttributes;
+			Asn1.Cms.Attribute hash = table[CmsAttributes.MessageDigest];
+
+			Assert.IsTrue(Arrays.AreEqual(contentDigest, ((Asn1OctetString)hash.AttrValues[0]).GetOctets()));
+
+			//
+			// try using existing signer
+			//
+			gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigners(sp.GetSignerInfos());
+
+			gen.AddCertificates(sp.GetCertificates("Collection"));
+			gen.AddCrls(sp.GetCrls("Collection"));
+
+			bOut.SetLength(0);
+
+			sigOut = gen.Open(bOut, true);
+
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CmsSignedData sd = new CmsSignedData(
+				new CmsProcessableByteArray(testBytes), bOut.ToArray());
+
+			Assert.AreEqual(1, sd.GetSignerInfos().GetSigners().Count);
+
+			VerifyEncodedData(bOut);
+		}
+
+		private static readonly DerObjectIdentifier dummyOid1 = new DerObjectIdentifier("1.2.3");
+		private static readonly DerObjectIdentifier dummyOid2 = new DerObjectIdentifier("1.2.3.4");
+
+		private class SignedGenAttributeTableGenerator
+			: DefaultSignedAttributeTableGenerator
+		{
+			public override AttributeTable GetAttributes(
+				IDictionary parameters)
+			{
+				IDictionary table = createStandardAttributeTable(parameters);
+
+				DerOctetString val = new DerOctetString((byte[])parameters[CmsAttributeTableParameter.Digest]);
+				Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(dummyOid1, new DerSet(val));
+
+				table[attr.AttrType] = attr;
+
+				return new AttributeTable(table);
+			}
+		};
+
+		private class UnsignedGenAttributeTableGenerator
+			: CmsAttributeTableGenerator
+		{
+			public AttributeTable GetAttributes(
+				IDictionary parameters)
+			{
+				DerOctetString val = new DerOctetString((byte[])parameters[CmsAttributeTableParameter.Signature]);
+				Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(dummyOid2, new DerSet(val));
+
+				return new AttributeTable(new DerSet(attr));
+			}
+		};
+
+		[Test]
+	    public void TestSha1WithRsaEncapsulatedSubjectKeyID()
+	    {
+	        IList certList = new ArrayList();
+	        MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+	        gen.AddSigner(OrigKP.Private,
+				CmsTestUtil.CreateSubjectKeyId(OrigCert.GetPublicKey()).GetKeyIdentifier(),
+				CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut, true);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+
+			byte[] contentDigest = (byte[])gen.GetGeneratedDigests()[CmsSignedGenerator.DigestSha1];
+
+			ArrayList signers = new ArrayList(sp.GetSignerInfos().GetSigners());
+
+			AttributeTable table = ((SignerInformation) signers[0]).SignedAttributes;
+			Asn1.Cms.Attribute hash = table[CmsAttributes.MessageDigest];
+
+			Assert.IsTrue(Arrays.AreEqual(contentDigest, ((Asn1OctetString)hash.AttrValues[0]).GetOctets()));
+
+			//
+			// try using existing signer
+			//
+			gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigners(sp.GetSignerInfos());
+
+//			gen.AddCertificatesAndCRLs(sp.getCertificatesAndCRLs("Collection", "BC"));
+			gen.AddCertificates(sp.GetCertificates("Collection"));
+
+			bOut.SetLength(0);
+
+			sigOut = gen.Open(bOut, true);
+
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CmsSignedData sd = new CmsSignedData(new CmsProcessableByteArray(testBytes), bOut.ToArray());
+
+			Assert.AreEqual(1, sd.GetSignerInfos().GetSigners().Count);
+
+	        VerifyEncodedData(bOut);
+	    }
+
+		[Test]
+		public void TestAttributeGenerators()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			CmsAttributeTableGenerator signedGen = new SignedGenAttributeTableGenerator();
+			CmsAttributeTableGenerator unsignedGen = new UnsignedGenAttributeTableGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert,
+				CmsSignedDataStreamGenerator.DigestSha1, signedGen, unsignedGen);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut, true);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+
+			//
+			// check attributes
+			//
+			SignerInformationStore signers = sp.GetSignerInfos();
+
+			foreach (SignerInformation signer in signers.GetSigners())
+			{
+				checkAttribute(signer.GetContentDigest(), signer.SignedAttributes[dummyOid1]);
+				checkAttribute(signer.GetSignature(), signer.UnsignedAttributes[dummyOid2]);
+			}
+		}
+
+		private void checkAttribute(
+			byte[]				expected,
+			Asn1.Cms.Attribute	attr)
+		{
+			DerOctetString value = (DerOctetString)attr.AttrValues[0];
+
+			Assert.AreEqual(new DerOctetString(expected), value);
+		}
+
+		[Test]
+		public void TestWithAttributeCertificate()
+		{
+			IList certList = new ArrayList();
+
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			IX509AttributeCertificate attrCert = CmsTestUtil.GetAttributeCertificate();
+
+			ArrayList attrCerts = new ArrayList();
+			attrCerts.Add(attrCert);
+			IX509Store store = X509StoreFactory.Create(
+				"AttributeCertificate/Collection",
+				new X509CollectionStoreParameters(attrCerts));
+
+			gen.AddAttributeCertificates(store);
+
+			MemoryStream bOut = new MemoryStream();
+
+			Stream sigOut = gen.Open(bOut, true);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			Assert.AreEqual(4, sp.Version);
+
+			store = sp.GetAttributeCertificates("Collection");
+
+			ArrayList coll = new ArrayList(store.GetMatches(null));
+
+			Assert.AreEqual(1, coll.Count);
+
+			Assert.IsTrue(coll.Contains(attrCert));
+		}
+
+		[Test]
+		public void TestSignerStoreReplacement()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+			byte[] data = Encoding.ASCII.GetBytes(TestMessage);
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut, false);
+
+			sigOut.Write(data, 0, data.Length);
+
+			sigOut.Close();
+
+			CheckSigParseable(bOut.ToArray());
+
+			//
+			// create new Signer
+			//
+			MemoryStream original = new MemoryStream(bOut.ToArray(), false);
+
+			bOut.SetLength(0);
+
+			gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha224);
+
+			gen.AddCertificates(x509Certs);
+
+			sigOut = gen.Open(bOut);
+
+			sigOut.Write(data, 0, data.Length);
+
+			sigOut.Close();
+
+			CheckSigParseable(bOut.ToArray());
+
+			CmsSignedData sd = new CmsSignedData(bOut.ToArray());
+
+			//
+			// replace signer
+			//
+			MemoryStream newOut = new MemoryStream();
+
+			CmsSignedDataParser.ReplaceSigners(original, sd.GetSignerInfos(), newOut);
+
+			sd = new CmsSignedData(new CmsProcessableByteArray(data), newOut.ToArray());
+
+			IEnumerator signerEnum = sd.GetSignerInfos().GetSigners().GetEnumerator();
+			signerEnum.MoveNext();
+			SignerInformation signer = (SignerInformation) signerEnum.Current;
+
+			Assert.AreEqual(signer.DigestAlgOid, CmsSignedDataStreamGenerator.DigestSha224);
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(new CmsTypedStream(
+				new MemoryStream(data, false)), newOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+		}
+
+		[Test]
+		public void TestEncapsulatedSignerStoreReplacement()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut, true);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			//
+			// create new Signer
+			//
+			MemoryStream  original = new MemoryStream(bOut.ToArray(), false);
+
+			bOut.SetLength(0);
+
+			gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha224);
+
+			gen.AddCertificates(x509Certs);
+
+			sigOut = gen.Open(bOut, true);
+
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CmsSignedData sd = new CmsSignedData(bOut.ToArray());
+
+			//
+			// replace signer
+			//
+			MemoryStream newOut = new MemoryStream();
+
+			CmsSignedDataParser.ReplaceSigners(original, sd.GetSignerInfos(), newOut);
+
+			sd = new CmsSignedData(newOut.ToArray());
+
+			IEnumerator signerEnum = sd.GetSignerInfos().GetSigners().GetEnumerator();
+			signerEnum.MoveNext();
+			SignerInformation signer = (SignerInformation) signerEnum.Current;
+
+			Assert.AreEqual(signer.DigestAlgOid, CmsSignedDataStreamGenerator.DigestSha224);
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(newOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+		}
+
+		[Test]
+		public void TestCertStoreReplacement()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+			byte[] data = Encoding.ASCII.GetBytes(TestMessage);
+
+			certList.Add(OrigDsaCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut);
+
+			sigOut.Write(data, 0, data.Length);
+
+			sigOut.Close();
+
+			CheckSigParseable(bOut.ToArray());
+
+			//
+			// create new certstore with the right certificates
+			//
+			certList = new ArrayList();
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			//
+			// replace certs
+			//
+			MemoryStream original = new MemoryStream(bOut.ToArray(), false);
+			MemoryStream newOut = new MemoryStream();
+
+			CmsSignedDataParser.ReplaceCertificatesAndCrls(original, x509Certs, null, null, newOut);
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(new CmsTypedStream(new MemoryStream(data, false)), newOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+		}
+
+		[Test]
+		public void TestEncapsulatedCertStoreReplacement()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigDsaCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut, true);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			//
+			// create new certstore with the right certificates
+			//
+			certList = new ArrayList();
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			//
+			// replace certs
+			//
+			MemoryStream original = new MemoryStream(bOut.ToArray(), false);
+			MemoryStream newOut = new MemoryStream();
+
+			CmsSignedDataParser.ReplaceCertificatesAndCrls(original, x509Certs, null, null, newOut);
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(newOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+		}
+
+		[Test]
+		public void TestCertOrdering1()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut, true);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+			x509Certs = sp.GetCertificates("Collection");
+			ArrayList a = new ArrayList(x509Certs.GetMatches(null));
+
+			Assert.AreEqual(2, a.Count);
+			Assert.AreEqual(OrigCert, a[0]);
+			Assert.AreEqual(SignCert, a[1]);
+		}
+
+		[Test]
+		public void TestCertOrdering2()
+		{
+			IList certList = new ArrayList();
+			MemoryStream bOut = new MemoryStream();
+
+			certList.Add(SignCert);
+			certList.Add(OrigCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			Stream sigOut = gen.Open(bOut, true);
+
+			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
+			sigOut.Write(testBytes, 0, testBytes.Length);
+
+			sigOut.Close();
+
+			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());
+
+			sp.GetSignedContent().Drain();
+			x509Certs = sp.GetCertificates("Collection");
+			ArrayList a = new ArrayList(x509Certs.GetMatches(null));
+
+			Assert.AreEqual(2, a.Count);
+			Assert.AreEqual(SignCert, a[0]);
+			Assert.AreEqual(OrigCert, a[1]);
+		}
+	}
+}
diff --git a/crypto/test/src/cms/test/SignedDataTest.cs b/crypto/test/src/cms/test/SignedDataTest.cs
new file mode 100644
index 000000000..96f00eadc
--- /dev/null
+++ b/crypto/test/src/cms/test/SignedDataTest.cs
@@ -0,0 +1,1480 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Cms;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Pkcs;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Test;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.X509.Store;
+
+namespace Org.BouncyCastle.Cms.Tests
+{
+	[TestFixture]
+	public class SignedDataTest
+	{
+		private const string OrigDN = "O=Bouncy Castle, C=AU";
+		private static AsymmetricCipherKeyPair origKP;
+		private static X509Certificate origCert;
+
+		private const string SignDN = "CN=Bob, OU=Sales, O=Bouncy Castle, C=AU";
+		private static AsymmetricCipherKeyPair signKP;
+		private static X509Certificate signCert;
+
+		private const string ReciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
+//		private static AsymmetricCipherKeyPair reciKP;
+//		private static X509Certificate reciCert;
+
+		private static X509Crl signCrl;
+
+		private static AsymmetricCipherKeyPair signGostKP;
+		private static X509Certificate signGostCert;
+
+		private static AsymmetricCipherKeyPair signDsaKP;
+		private static X509Certificate signDsaCert;
+
+		private static AsymmetricCipherKeyPair signECGostKP;
+		private static X509Certificate signECGostCert;
+
+		private static AsymmetricCipherKeyPair signECDsaKP;
+		private static X509Certificate signECDsaCert;
+
+		private static AsymmetricCipherKeyPair OrigKP
+		{
+			get { return origKP == null ? (origKP = CmsTestUtil.MakeKeyPair()) : origKP; }
+		}
+
+		private static AsymmetricCipherKeyPair SignKP
+		{
+			get { return signKP == null ? (signKP = CmsTestUtil.MakeKeyPair()) : signKP; }
+		}
+
+//		private static AsymmetricCipherKeyPair ReciKP
+//		{
+//			get { return reciKP == null ? (reciKP = CmsTestUtil.MakeKeyPair()) : reciKP; }
+//		}
+
+		private static AsymmetricCipherKeyPair SignGostKP
+		{
+			get { return signGostKP == null ? (signGostKP = CmsTestUtil.MakeGostKeyPair()) : signGostKP; }
+		}
+
+		private static AsymmetricCipherKeyPair SignDsaKP
+		{
+			get { return signDsaKP == null ? (signDsaKP = CmsTestUtil.MakeDsaKeyPair()) : signDsaKP; }
+		}
+
+		private static AsymmetricCipherKeyPair SignECGostKP
+		{
+			get { return signECGostKP == null ? (signECGostKP = CmsTestUtil.MakeECGostKeyPair()) : signECGostKP; }
+		}
+
+		private static AsymmetricCipherKeyPair SignECDsaKP
+		{
+			get { return signECDsaKP == null ? (signECDsaKP = CmsTestUtil.MakeECDsaKeyPair()) : signECDsaKP; }
+		}
+
+		private static X509Certificate OrigCert
+		{
+			get { return origCert == null ? (origCert = CmsTestUtil.MakeCertificate(OrigKP, OrigDN, OrigKP, OrigDN)) : origCert; }
+		}
+
+		private static X509Certificate SignCert
+		{
+			get { return signCert == null ? (signCert = CmsTestUtil.MakeCertificate(SignKP, SignDN, OrigKP, OrigDN)) : signCert; }
+		}
+
+//		private static X509Certificate ReciCert
+//		{
+//			get { return reciCert == null ? (reciCert = CmsTestUtil.MakeCertificate(ReciKP, ReciDN, SignKP, SignDN)) : reciCert; }
+//		}
+
+		private static X509Crl SignCrl
+		{
+			get { return signCrl == null ? (signCrl = CmsTestUtil.MakeCrl(SignKP)) : signCrl; }
+		}
+
+		private static X509Certificate SignGostCert
+		{
+			get { return signGostCert == null ? (signGostCert = CmsTestUtil.MakeCertificate(SignGostKP, SignDN, OrigKP, OrigDN)) : signGostCert; }
+		}
+
+		private static X509Certificate SignECGostCert
+		{
+			get { return signECGostCert == null ? (signECGostCert = CmsTestUtil.MakeCertificate(SignECGostKP, SignDN, OrigKP, OrigDN)) : signECGostCert; }
+		}
+
+		private static X509Certificate SignDsaCert
+		{
+			get { return signDsaCert == null ? (signDsaCert = CmsTestUtil.MakeCertificate(SignDsaKP, SignDN, OrigKP, OrigDN)) : signDsaCert; }
+		}
+
+		private static X509Certificate SignECDsaCert
+		{
+			get { return signECDsaCert == null ? (signECDsaCert = CmsTestUtil.MakeCertificate(SignECDsaKP, SignDN, OrigKP, OrigDN)) : signECDsaCert; }
+		}
+
+		private static readonly byte[] disorderedMessage = Base64.Decode(
+			"SU9fc3RkaW5fdXNlZABfX2xpYmNfc3RhcnRfbWFpbgBnZXRob3N0aWQAX19n"
+			+ "bW9uX3M=");
+
+		private static readonly byte[] disorderedSet = Base64.Decode(
+			"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"
+			+ "JyQFn5msmhPQT/6XSGOlrWRoFummXN9lQzAjCj1sgTcmoLCVQ5s5WpCAOXFw"
+			+ "VWu16qndz3sPItn3jJ0F3Kh3w79NglvPAgUAwAAAATAKBgYrJAMDAQIFAAOB"
+			+ "gQBpSRdnDb6AcNVaXSmGo6+kVPIBhot1LzJOGaPyDNpGXxd7LV4tMBF1U7gr"
+			+ "4k1g9BO6YiMWvw9uiTZmn0CfV8+k4fWEuG/nmafRoGIuay2f+ILuT+C0rnp1"
+			+ "4FgMsEhuVNJJAmb12QV0PZII+UneyhAneZuQQzVUkTcVgYxogxdSOzCCAlUw"
+			+ "ggHBoAMCAQICBACdekowCgYGKyQDAwECBQAwbzELMAkGA1UEBhMCREUxPTA7"
+			+ "BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlr"
+			+ "YXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNlItQ2Eg"
+			+ "MTpQTjAiGA8yMDAxMDIwMTEzNDcwN1oYDzIwMDUwMzIyMDg1NTUxWjBvMQsw"
+			+ "CQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1"
+			+ "ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEw"
+			+ "EQYDVQQDFAo1Ui1DQSAxOlBOMIGhMA0GCSqGSIb3DQEBAQUAA4GPADCBiwKB"
+			+ "gQCKHkFTJx8GmoqFTxEOxpK9XkC3NZ5dBEKiUv0Ife3QMqeGMoCUnyJxwW0k"
+			+ "2/53duHxtv2yHSZpFKjrjvE/uGwdOMqBMTjMzkFg19e9JPv061wyADOucOIa"
+			+ "NAgha/zFt9XUyrHF21knKCvDNExv2MYIAagkTKajLMAw0bu1J0FadQIFAMAA"
+			+ "AAEwCgYGKyQDAwECBQADgYEAV1yTi+2gyB7sUhn4PXmi/tmBxAfe5oBjDW8m"
+			+ "gxtfudxKGZ6l/FUPNcrSc5oqBYxKWtLmf3XX87LcblYsch617jtNTkMzhx9e"
+			+ "qxiD02ufcrxz2EVt0Akdqiz8mdVeqp3oLcNU/IttpSrcA91CAnoUXtDZYwb/"
+			+ "gdQ4FI9l3+qo/0UwggJVMIIBwaADAgECAgQAxIymMAoGBiskAwMBAgUAMG8x"
+			+ "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm"
+			+ "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB"
+			+ "MTARBgNVBAMUCjZSLUNhIDE6UE4wIhgPMjAwMTEwMTUxMzMxNThaGA8yMDA1"
+			+ "MDYwMTA5NTIxN1owbzELMAkGA1UEBhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVy"
+			+ "dW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11bmlrYXRpb24gdW5kIFBvc3Qx"
+			+ "ITAMBgcCggYBCgcUEwExMBEGA1UEAxQKN1ItQ0EgMTpQTjCBoTANBgkqhkiG"
+			+ "9w0BAQEFAAOBjwAwgYsCgYEAiokD/j6lEP4FexF356OpU5teUpGGfUKjIrFX"
+			+ "BHc79G0TUzgVxqMoN1PWnWktQvKo8ETaugxLkP9/zfX3aAQzDW4Zki6x6GDq"
+			+ "fy09Agk+RJvhfbbIzRkV4sBBco0n73x7TfG/9NTgVr/96U+I+z/1j30aboM6"
+			+ "9OkLEhjxAr0/GbsCBQDAAAABMAoGBiskAwMBAgUAA4GBAHWRqRixt+EuqHhR"
+			+ "K1kIxKGZL2vZuakYV0R24Gv/0ZR52FE4ECr+I49o8FP1qiGSwnXB0SwjuH2S"
+			+ "iGiSJi+iH/MeY85IHwW1P5e+bOMvEOFhZhQXQixOD7totIoFtdyaj1XGYRef"
+			+ "0f2cPOjNJorXHGV8wuBk+/j++sxbd/Net3FtMIICVTCCAcGgAwIBAgIEAMSM"
+			+ "pzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp"
+			+ "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z"
+			+ "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo3Ui1DQSAxOlBOMCIYDzIwMDEx"
+			+ "MDE1MTMzNDE0WhgPMjAwNTA2MDEwOTUyMTdaMG8xCzAJBgNVBAYTAkRFMT0w"
+			+ "OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5p"
+			+ "a2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjZSLUNh"
+			+ "IDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGLAoGBAIOiqxUkzVyqnvth"
+			+ "ihnltsE5m1Xn5TZKeR/2MQPStc5hJ+V4yptEtIx+Fn5rOoqT5VEVWhcE35wd"
+			+ "bPvgJyQFn5msmhPQT/6XSGOlrWRoFummXN9lQzAjCj1sgTcmoLCVQ5s5WpCA"
+			+ "OXFwVWu16qndz3sPItn3jJ0F3Kh3w79NglvPAgUAwAAAATAKBgYrJAMDAQIF"
+			+ "AAOBgQBi5W96UVDoNIRkCncqr1LLG9vF9SGBIkvFpLDIIbcvp+CXhlvsdCJl"
+			+ "0pt2QEPSDl4cmpOet+CxJTdTuMeBNXxhb7Dvualog69w/+K2JbPhZYxuVFZs"
+			+ "Zh5BkPn2FnbNu3YbJhE60aIkikr72J4XZsI5DxpZCGh6xyV/YPRdKSljFjCC"
+			+ "AlQwggHAoAMCAQICAwyDqzAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9"
+			+ "MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVu"
+			+ "aWthdGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo1Ui1D"
+			+ "QSAxOlBOMCIYDzIwMDAwMzIyMDk0MTI3WhgPMjAwNDAxMjExNjA0NTNaMG8x"
+			+ "CzAJBgNVBAYTAkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBm"
+			+ "yHVyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMB"
+			+ "MTARBgNVBAMUCjRSLUNBIDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGL"
+			+ "AoGBAI8x26tmrFJanlm100B7KGlRemCD1R93PwdnG7svRyf5ZxOsdGrDszNg"
+			+ "xg6ouO8ZHQMT3NC2dH8TvO65Js+8bIyTm51azF6clEg0qeWNMKiiXbBXa+ph"
+			+ "hTkGbXiLYvACZ6/MTJMJ1lcrjpRF7BXtYeYMcEF6znD4pxOqrtbf9z5hAgUA"
+			+ "wAAAATAKBgYrJAMDAQIFAAOBgQB99BjSKlGPbMLQAgXlvA9jUsDNhpnVm3a1"
+			+ "YkfxSqS/dbQlYkbOKvCxkPGA9NBxisBM8l1zFynVjJoy++aysRmcnLY/sHaz"
+			+ "23BF2iU7WERy18H3lMBfYB6sXkfYiZtvQZcWaO48m73ZBySuiV3iXpb2wgs/"
+			+ "Cs20iqroAWxwq/W/9jCCAlMwggG/oAMCAQICBDsFZ9UwCgYGKyQDAwECBQAw"
+			+ "bzELMAkGA1UEBhMCREUxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNFItQ0Eg"
+			+ "MTpQTjE9MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxl"
+			+ "a29tbXVuaWthdGlvbiB1bmQgUG9zdDAiGA8xOTk5MDEyMTE3MzUzNFoYDzIw"
+			+ "MDQwMTIxMTYwMDAyWjBvMQswCQYDVQQGEwJERTE9MDsGA1UEChQ0UmVndWxp"
+			+ "ZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWthdGlvbiB1bmQgUG9z"
+			+ "dDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAozUi1DQSAxOlBOMIGfMA0GCSqG"
+			+ "SIb3DQEBAQUAA4GNADCBiQKBgI4B557mbKQg/AqWBXNJhaT/6lwV93HUl4U8"
+			+ "u35udLq2+u9phns1WZkdM3gDfEpL002PeLfHr1ID/96dDYf04lAXQfombils"
+			+ "of1C1k32xOvxjlcrDOuPEMxz9/HDAQZA5MjmmYHAIulGI8Qg4Tc7ERRtg/hd"
+			+ "0QX0/zoOeXoDSEOBAgTAAAABMAoGBiskAwMBAgUAA4GBAIyzwfT3keHI/n2P"
+			+ "LrarRJv96mCohmDZNpUQdZTVjGu5VQjVJwk3hpagU0o/t/FkdzAjOdfEw8Ql"
+			+ "3WXhfIbNLv1YafMm2eWSdeYbLcbB5yJ1od+SYyf9+tm7cwfDAcr22jNRBqx8"
+			+ "wkWKtKDjWKkevaSdy99sAI8jebHtWz7jzydKMIID9TCCA16gAwIBAgICbMcw"
+			+ "DQYJKoZIhvcNAQEFBQAwSzELMAkGA1UEBhMCREUxEjAQBgNVBAoUCVNpZ250"
+			+ "cnVzdDEoMAwGBwKCBgEKBxQTATEwGAYDVQQDFBFDQSBTSUdOVFJVU1QgMTpQ"
+			+ "TjAeFw0wNDA3MzAxMzAyNDZaFw0wNzA3MzAxMzAyNDZaMDwxETAPBgNVBAMM"
+			+ "CFlhY29tOlBOMQ4wDAYDVQRBDAVZYWNvbTELMAkGA1UEBhMCREUxCjAIBgNV"
+			+ "BAUTATEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIWzLlYLQApocXIp"
+			+ "pgCCpkkOUVLgcLYKeOd6/bXAnI2dTHQqT2bv7qzfUnYvOqiNgYdF13pOYtKg"
+			+ "XwXMTNFL4ZOI6GoBdNs9TQiZ7KEWnqnr2945HYx7UpgTBclbOK/wGHuCdcwO"
+			+ "x7juZs1ZQPFG0Lv8RoiV9s6HP7POqh1sO0P/AgMBAAGjggH1MIIB8TCBnAYD"
+			+ "VR0jBIGUMIGRgBQcZzNghfnXoXRm8h1+VITC5caNRqFzpHEwbzELMAkGA1UE"
+			+ "BhMCREUxPTA7BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVs"
+			+ "ZWtvbW11bmlrYXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UE"
+			+ "AxQKNVItQ0EgMTpQToIEALs8rjAdBgNVHQ4EFgQU2e5KAzkVuKaM9I5heXkz"
+			+ "bcAIuR8wDgYDVR0PAQH/BAQDAgZAMBIGA1UdIAQLMAkwBwYFKyQIAQEwfwYD"
+			+ "VR0fBHgwdjB0oCygKoYobGRhcDovL2Rpci5zaWdudHJ1c3QuZGUvbz1TaWdu"
+			+ "dHJ1c3QsYz1kZaJEpEIwQDEdMBsGA1UEAxMUQ1JMU2lnblNpZ250cnVzdDE6"
+			+ "UE4xEjAQBgNVBAoTCVNpZ250cnVzdDELMAkGA1UEBhMCREUwYgYIKwYBBQUH"
+			+ "AQEEVjBUMFIGCCsGAQUFBzABhkZodHRwOi8vZGlyLnNpZ250cnVzdC5kZS9T"
+			+ "aWdudHJ1c3QvT0NTUC9zZXJ2bGV0L2h0dHBHYXRld2F5LlBvc3RIYW5kbGVy"
+			+ "MBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwDgYHAoIGAQoMAAQDAQH/MA0G"
+			+ "CSqGSIb3DQEBBQUAA4GBAHn1m3GcoyD5GBkKUY/OdtD6Sj38LYqYCF+qDbJR"
+			+ "6pqUBjY2wsvXepUppEler+stH8mwpDDSJXrJyuzf7xroDs4dkLl+Rs2x+2tg"
+			+ "BjU+ABkBDMsym2WpwgA8LCdymmXmjdv9tULxY+ec2pjSEzql6nEZNEfrU8nt"
+			+ "ZCSCavgqW4TtMYIBejCCAXYCAQEwUTBLMQswCQYDVQQGEwJERTESMBAGA1UE"
+			+ "ChQJU2lnbnRydXN0MSgwDAYHAoIGAQoHFBMBMTAYBgNVBAMUEUNBIFNJR05U"
+			+ "UlVTVCAxOlBOAgJsxzAJBgUrDgMCGgUAoIGAMBgGCSqGSIb3DQEJAzELBgkq"
+			+ "hkiG9w0BBwEwIwYJKoZIhvcNAQkEMRYEFIYfhPoyfGzkLWWSSLjaHb4HQmaK"
+			+ "MBwGCSqGSIb3DQEJBTEPFw0wNTAzMjQwNzM4MzVaMCEGBSskCAYFMRgWFi92"
+			+ "YXIvZmlsZXMvdG1wXzEvdGVzdDEwDQYJKoZIhvcNAQEFBQAEgYA2IvA8lhVz"
+			+ "VD5e/itUxbFboKxeKnqJ5n/KuO/uBCl1N14+7Z2vtw1sfkIG+bJdp3OY2Cmn"
+			+ "mrQcwsN99Vjal4cXVj8t+DJzFG9tK9dSLvD3q9zT/GQ0kJXfimLVwCa4NaSf"
+			+ "Qsu4xtG0Rav6bCcnzabAkKuNNvKtH8amSRzk870DBg==");
+
+		private static readonly byte[] xtraCounterSig = Base64.Decode(
+			  "MIIR/AYJKoZIhvcNAQcCoIIR7TCCEekCAQExCzAJBgUrDgMCGgUAMBoGCSqG"
+			+ "SIb3DQEHAaANBAtIZWxsbyB3b3JsZKCCDnkwggTPMIIDt6ADAgECAgRDnYD3"
+			+ "MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5U"
+			+ "ZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmlj"
+			+ "YXRpb24gQXV0aG9yaXR5MB4XDTA4MDkxMjExNDMxMloXDTEwMDkxMjExNDMx"
+			+ "MlowgdgxCzAJBgNVBAYTAklUMSIwIAYDVQQKDBlJbnRlc2EgUy5wLkEuLzA1"
+			+ "MjYyODkwMDE0MSowKAYDVQQLDCFCdXNpbmVzcyBDb2xsYWJvcmF0aW9uICYg"
+			+ "U2VjdXJpdHkxHjAcBgNVBAMMFU1BU1NJTUlMSUFOTyBaSUNDQVJESTERMA8G"
+			+ "A1UEBAwIWklDQ0FSREkxFTATBgNVBCoMDE1BU1NJTUlMSUFOTzEcMBoGA1UE"
+			+ "BRMTSVQ6WkNDTVNNNzZIMTRMMjE5WTERMA8GA1UELhMIMDAwMDI1ODUwgaAw"
+			+ "DQYJKoZIhvcNAQEBBQADgY4AMIGKAoGBALeJTjmyFgx1SIP6c2AuB/kuyHo5"
+			+ "j/prKELTALsFDimre/Hxr3wOSet1TdQfFzU8Lu+EJqgfV9cV+cI1yeH1rZs7"
+			+ "lei7L3tX/VR565IywnguX5xwvteASgWZr537Fkws50bvTEMyYOj1Tf3FZvZU"
+			+ "z4n4OD39KI4mfR9i1eEVIxR3AgQAizpNo4IBoTCCAZ0wHQYDVR0RBBYwFIES"
+			+ "emljY2FyZGlAaW50ZXNhLml0MC8GCCsGAQUFBwEDBCMwITAIBgYEAI5GAQEw"
+			+ "CwYGBACORgEDAgEUMAgGBgQAjkYBBDBZBgNVHSAEUjBQME4GBgQAizABATBE"
+			+ "MEIGCCsGAQUFBwIBFjZodHRwOi8vZS10cnVzdGNvbS5pbnRlc2EuaXQvY2Ff"
+			+ "cHViYmxpY2EvQ1BTX0lOVEVTQS5odG0wDgYDVR0PAQH/BAQDAgZAMIGDBgNV"
+			+ "HSMEfDB6gBQZCQOW0bjFWBt+EORuxPagEgkQqKFcpFowWDELMAkGA1UEBhMC"
+			+ "SVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJbi5U"
+			+ "ZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHmCBDzRARMwOwYDVR0f"
+			+ "BDQwMjAwoC6gLIYqaHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L0NSTC9J"
+			+ "TlRFU0EuY3JsMB0GA1UdDgQWBBTf5ItL8KmQh541Dxt7YxcWI1254TANBgkq"
+			+ "hkiG9w0BAQUFAAOCAQEAgW+uL1CVWQepbC/wfCmR6PN37Sueb4xiKQj2mTD5"
+			+ "UZ5KQjpivy/Hbuf0NrfKNiDEhAvoHSPC31ebGiKuTMFNyZPHfPEUnyYGSxea"
+			+ "2w837aXJFr6utPNQGBRi89kH90sZDlXtOSrZI+AzJJn5QK3F9gjcayU2NZXQ"
+			+ "MJgRwYmFyn2w4jtox+CwXPQ9E5XgxiMZ4WDL03cWVXDLX00EOJwnDDMUNTRI"
+			+ "m9Zv+4SKTNlfFbi9UTBqWBySkDzAelsfB2U61oqc2h1xKmCtkGMmN9iZT+Qz"
+			+ "ZC/vaaT+hLEBFGAH2gwFrYc4/jTBKyBYeU1vsAxsibIoTs1Apgl6MH75qPDL"
+			+ "BzCCBM8wggO3oAMCAQICBEOdgPcwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE"
+			+ "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ"
+			+ "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwOTEy"
+			+ "MTE0MzEyWhcNMTAwOTEyMTE0MzEyWjCB2DELMAkGA1UEBhMCSVQxIjAgBgNV"
+			+ "BAoMGUludGVzYSBTLnAuQS4vMDUyNjI4OTAwMTQxKjAoBgNVBAsMIUJ1c2lu"
+			+ "ZXNzIENvbGxhYm9yYXRpb24gJiBTZWN1cml0eTEeMBwGA1UEAwwVTUFTU0lN"
+			+ "SUxJQU5PIFpJQ0NBUkRJMREwDwYDVQQEDAhaSUNDQVJESTEVMBMGA1UEKgwM"
+			+ "TUFTU0lNSUxJQU5PMRwwGgYDVQQFExNJVDpaQ0NNU003NkgxNEwyMTlZMREw"
+			+ "DwYDVQQuEwgwMDAwMjU4NTCBoDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEA"
+			+ "t4lOObIWDHVIg/pzYC4H+S7IejmP+msoQtMAuwUOKat78fGvfA5J63VN1B8X"
+			+ "NTwu74QmqB9X1xX5wjXJ4fWtmzuV6Lsve1f9VHnrkjLCeC5fnHC+14BKBZmv"
+			+ "nfsWTCznRu9MQzJg6PVN/cVm9lTPifg4Pf0ojiZ9H2LV4RUjFHcCBACLOk2j"
+			+ "ggGhMIIBnTAdBgNVHREEFjAUgRJ6aWNjYXJkaUBpbnRlc2EuaXQwLwYIKwYB"
+			+ "BQUHAQMEIzAhMAgGBgQAjkYBATALBgYEAI5GAQMCARQwCAYGBACORgEEMFkG"
+			+ "A1UdIARSMFAwTgYGBACLMAEBMEQwQgYIKwYBBQUHAgEWNmh0dHA6Ly9lLXRy"
+			+ "dXN0Y29tLmludGVzYS5pdC9jYV9wdWJibGljYS9DUFNfSU5URVNBLmh0bTAO"
+			+ "BgNVHQ8BAf8EBAMCBkAwgYMGA1UdIwR8MHqAFBkJA5bRuMVYG34Q5G7E9qAS"
+			+ "CRCooVykWjBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5BLiBT"
+			+ "LnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9uIEF1"
+			+ "dGhvcml0eYIEPNEBEzA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vZS10cnVz"
+			+ "dGNvbS5pbnRlc2EuaXQvQ1JML0lOVEVTQS5jcmwwHQYDVR0OBBYEFN/ki0vw"
+			+ "qZCHnjUPG3tjFxYjXbnhMA0GCSqGSIb3DQEBBQUAA4IBAQCBb64vUJVZB6ls"
+			+ "L/B8KZHo83ftK55vjGIpCPaZMPlRnkpCOmK/L8du5/Q2t8o2IMSEC+gdI8Lf"
+			+ "V5saIq5MwU3Jk8d88RSfJgZLF5rbDzftpckWvq6081AYFGLz2Qf3SxkOVe05"
+			+ "Ktkj4DMkmflArcX2CNxrJTY1ldAwmBHBiYXKfbDiO2jH4LBc9D0TleDGIxnh"
+			+ "YMvTdxZVcMtfTQQ4nCcMMxQ1NEib1m/7hIpM2V8VuL1RMGpYHJKQPMB6Wx8H"
+			+ "ZTrWipzaHXEqYK2QYyY32JlP5DNkL+9ppP6EsQEUYAfaDAWthzj+NMErIFh5"
+			+ "TW+wDGyJsihOzUCmCXowfvmo8MsHMIIEzzCCA7egAwIBAgIEQ52A9zANBgkq"
+			+ "hkiG9w0BAQUFADBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4uVGUuUy5B"
+			+ "LiBTLnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0aW9u"
+			+ "IEF1dGhvcml0eTAeFw0wODA5MTIxMTQzMTJaFw0xMDA5MTIxMTQzMTJaMIHY"
+			+ "MQswCQYDVQQGEwJJVDEiMCAGA1UECgwZSW50ZXNhIFMucC5BLi8wNTI2Mjg5"
+			+ "MDAxNDEqMCgGA1UECwwhQnVzaW5lc3MgQ29sbGFib3JhdGlvbiAmIFNlY3Vy"
+			+ "aXR5MR4wHAYDVQQDDBVNQVNTSU1JTElBTk8gWklDQ0FSREkxETAPBgNVBAQM"
+			+ "CFpJQ0NBUkRJMRUwEwYDVQQqDAxNQVNTSU1JTElBTk8xHDAaBgNVBAUTE0lU"
+			+ "OlpDQ01TTTc2SDE0TDIxOVkxETAPBgNVBC4TCDAwMDAyNTg1MIGgMA0GCSqG"
+			+ "SIb3DQEBAQUAA4GOADCBigKBgQC3iU45shYMdUiD+nNgLgf5Lsh6OY/6ayhC"
+			+ "0wC7BQ4pq3vx8a98DknrdU3UHxc1PC7vhCaoH1fXFfnCNcnh9a2bO5Xouy97"
+			+ "V/1UeeuSMsJ4Ll+ccL7XgEoFma+d+xZMLOdG70xDMmDo9U39xWb2VM+J+Dg9"
+			+ "/SiOJn0fYtXhFSMUdwIEAIs6TaOCAaEwggGdMB0GA1UdEQQWMBSBEnppY2Nh"
+			+ "cmRpQGludGVzYS5pdDAvBggrBgEFBQcBAwQjMCEwCAYGBACORgEBMAsGBgQA"
+			+ "jkYBAwIBFDAIBgYEAI5GAQQwWQYDVR0gBFIwUDBOBgYEAIswAQEwRDBCBggr"
+			+ "BgEFBQcCARY2aHR0cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0L2NhX3B1YmJs"
+			+ "aWNhL0NQU19JTlRFU0EuaHRtMA4GA1UdDwEB/wQEAwIGQDCBgwYDVR0jBHww"
+			+ "eoAUGQkDltG4xVgbfhDkbsT2oBIJEKihXKRaMFgxCzAJBgNVBAYTAklUMRow"
+			+ "GAYDVQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5B"
+			+ "LiAtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ80QETMDsGA1UdHwQ0MDIw"
+			+ "MKAuoCyGKmh0dHA6Ly9lLXRydXN0Y29tLmludGVzYS5pdC9DUkwvSU5URVNB"
+			+ "LmNybDAdBgNVHQ4EFgQU3+SLS/CpkIeeNQ8be2MXFiNdueEwDQYJKoZIhvcN"
+			+ "AQEFBQADggEBAIFvri9QlVkHqWwv8Hwpkejzd+0rnm+MYikI9pkw+VGeSkI6"
+			+ "Yr8vx27n9Da3yjYgxIQL6B0jwt9XmxoirkzBTcmTx3zxFJ8mBksXmtsPN+2l"
+			+ "yRa+rrTzUBgUYvPZB/dLGQ5V7Tkq2SPgMySZ+UCtxfYI3GslNjWV0DCYEcGJ"
+			+ "hcp9sOI7aMfgsFz0PROV4MYjGeFgy9N3FlVwy19NBDicJwwzFDU0SJvWb/uE"
+			+ "ikzZXxW4vVEwalgckpA8wHpbHwdlOtaKnNodcSpgrZBjJjfYmU/kM2Qv72mk"
+			+ "/oSxARRgB9oMBa2HOP40wSsgWHlNb7AMbImyKE7NQKYJejB++ajwywcxggM8"
+			+ "MIIDOAIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYDVQQKExFJbi5UZS5TLkEu"
+			+ "IFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAtIENlcnRpZmljYXRpb24g"
+			+ "QXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYB+"
+			+ "lH2cwLqc91mP8prvgSV+RRzk13dJdZvdoVjgQoFrPhBiZCNIEoHvIhMMA/sM"
+			+ "X6euSRZk7EjD24FasCEGYyd0mJVLEy6TSPmuW+wWz/28w3a6IWXBGrbb/ild"
+			+ "/CJMkPgLPGgOVD1WDwiNKwfasiQSFtySf5DPn3jFevdLeMmEY6GCAjIwggEV"
+			+ "BgkqhkiG9w0BCQYxggEGMIIBAgIBATBgMFgxCzAJBgNVBAYTAklUMRowGAYD"
+			+ "VQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAt"
+			+ "IENlcnRpZmljYXRpb24gQXV0aG9yaXR5AgRDnYD3MAkGBSsOAwIaBQAwDQYJ"
+			+ "KoZIhvcNAQEBBQAEgYBHlOULfT5GDigIvxP0qZOy8VbpntmzaPF55VV4buKV"
+			+ "35J+uHp98gXKp0LrHM69V5IRKuyuQzHHFBqsXxsRI9o6KoOfgliD9Xc+BeMg"
+			+ "dKzQhBhBYoFREq8hQM0nSbqDNHYAQyNHMzUA/ZQUO5dlFuH8Dw3iDYAhNtfd"
+			+ "PrlchKJthDCCARUGCSqGSIb3DQEJBjGCAQYwggECAgEBMGAwWDELMAkGA1UE"
+			+ "BhMCSVQxGjAYBgNVBAoTEUluLlRlLlMuQS4gUy5wLkEuMS0wKwYDVQQDEyRJ"
+			+ "bi5UZS5TLkEuIC0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkCBEOdgPcwCQYF"
+			+ "Kw4DAhoFADANBgkqhkiG9w0BAQEFAASBgEeU5Qt9PkYOKAi/E/Spk7LxVume"
+			+ "2bNo8XnlVXhu4pXfkn64en3yBcqnQusczr1XkhEq7K5DMccUGqxfGxEj2joq"
+			+ "g5+CWIP1dz4F4yB0rNCEGEFigVESryFAzSdJuoM0dgBDI0czNQD9lBQ7l2UW"
+			+ "4fwPDeINgCE2190+uVyEom2E");
+
+		private void VerifySignatures(
+			CmsSignedData	s,
+			byte[]			contentDigest)
+		{
+			IX509Store x509Certs = s.GetCertificates("Collection");
+
+			SignerInformationStore signers = s.GetSignerInfos();
+			ICollection c = signers.GetSigners();
+
+			foreach (SignerInformation signer in c)
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				Assert.IsTrue(signer.Verify(cert));
+
+				if (contentDigest != null)
+				{
+					Assert.IsTrue(Arrays.AreEqual(contentDigest, signer.GetContentDigest()));
+				}
+			}
+		}
+
+		private void VerifySignatures(
+			CmsSignedData s)
+		{
+			VerifySignatures(s, null);
+		}
+
+		[Test]
+		public void TestDetachedVerification()
+		{
+			byte[] data = Encoding.ASCII.GetBytes("Hello World!");
+			CmsProcessable msg = new CmsProcessableByteArray(data);
+
+			IList certList = new ArrayList();
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestMD5);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData s = gen.Generate(msg);
+
+			IDictionary hashes = new Hashtable();
+			hashes.Add(CmsSignedDataGenerator.DigestSha1, CalculateHash("SHA1", data));
+			hashes.Add(CmsSignedDataGenerator.DigestMD5, CalculateHash("MD5", data));
+
+			s = new CmsSignedData(hashes, s.GetEncoded());
+
+			VerifySignatures(s, null);
+		}
+
+		private byte[] CalculateHash(
+			string	digestName,
+			byte[]	data)
+		{
+			IDigest digest = DigestUtilities.GetDigest(digestName);
+			digest.BlockUpdate(data, 0, data.Length);
+			return DigestUtilities.DoFinal(digest);
+		}
+
+		[Test]
+		public void TestSha1AndMD5WithRsaEncapsulatedRepeated()
+		{
+			IList certList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello World!"));
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestMD5);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData s = gen.Generate(msg, true);
+
+			s = new CmsSignedData(ContentInfo.GetInstance(Asn1Object.FromByteArray(s.GetEncoded())));
+
+			x509Certs = s.GetCertificates("Collection");
+
+			SignerInformationStore signers = s.GetSignerInfos();
+
+			Assert.AreEqual(2, signers.Count);
+
+			SignerID sid = null;
+			ICollection c = signers.GetSigners();
+
+			foreach (SignerInformation signer in c)
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				sid = signer.SignerID;
+
+				Assert.IsTrue(signer.Verify(cert));
+
+				//
+				// check content digest
+				//
+
+				byte[] contentDigest = (byte[])gen.GetGeneratedDigests()[signer.DigestAlgOid];
+
+				AttributeTable table = signer.SignedAttributes;
+				Asn1.Cms.Attribute hash = table[CmsAttributes.MessageDigest];
+
+				Assert.IsTrue(Arrays.AreEqual(contentDigest, ((Asn1OctetString)hash.AttrValues[0]).GetOctets()));
+			}
+
+			c = signers.GetSigners(sid);
+
+			Assert.AreEqual(2, c.Count);
+
+			//
+			// try using existing signer
+			//
+
+			gen = new CmsSignedDataGenerator();
+
+			gen.AddSigners(s.GetSignerInfos());
+
+			gen.AddCertificates(s.GetCertificates("Collection"));
+			gen.AddCrls(s.GetCrls("Collection"));
+
+			s = gen.Generate(msg, true);
+
+			s = new CmsSignedData(ContentInfo.GetInstance(Asn1Object.FromByteArray(s.GetEncoded())));
+
+			x509Certs = s.GetCertificates("Collection");
+
+			signers = s.GetSignerInfos();
+			c = signers.GetSigners();
+
+			Assert.AreEqual(2, c.Count);
+
+			foreach (SignerInformation signer in c)
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				Assert.AreEqual(true, signer.Verify(cert));
+			}
+
+			CheckSignerStoreReplacement(s, signers);
+		}
+
+		// NB: C# build doesn't support "no attributes" version of CmsSignedDataGenerator.Generate
+//		[Test]
+//		public void TestSha1WithRsaNoAttributes()
+//		{
+//			IList certList = new ArrayList();
+//			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello world!"));
+//
+//			certList.Add(OrigCert);
+//			certList.Add(SignCert);
+//
+//			IX509Store x509Certs = X509StoreFactory.Create(
+//				"Certificate/Collection",
+//				new X509CollectionStoreParameters(certList));
+//
+//			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+//
+//			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+//
+//			gen.AddCertificates(x509Certs);
+//
+//			CmsSignedData s = gen.Generate(CmsSignedDataGenerator.Data, msg, false, false);
+//
+//			//
+//			// compute expected content digest
+//			//
+//			IDigest md = DigestUtilities.GetDigest("SHA1");
+//
+//			byte[] testBytes = Encoding.ASCII.GetBytes("Hello world!");
+//			md.BlockUpdate(testBytes, 0, testBytes.Length);
+//			byte[] hash = DigestUtilities.DoFinal(md);
+//
+//			VerifySignatures(s, hash);
+//		}
+
+		[Test]
+		public void TestSha1WithRsaAndAttributeTable()
+		{
+			byte[] testBytes = Encoding.ASCII.GetBytes("Hello world!");
+
+			IList certList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(testBytes);
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			IDigest md = DigestUtilities.GetDigest("SHA1");
+			md.BlockUpdate(testBytes, 0, testBytes.Length);
+			byte[] hash = DigestUtilities.DoFinal(md);
+
+			Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(CmsAttributes.MessageDigest,
+				new DerSet(new DerOctetString(hash)));
+
+			Asn1EncodableVector v = new Asn1EncodableVector(attr);
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1,
+				new AttributeTable(v), null);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData s = gen.Generate(CmsSignedDataGenerator.Data, null, false);
+
+			//
+			// the signature is detached, so need to add msg before passing on
+			//
+			s = new CmsSignedData(msg, s.GetEncoded());
+
+			//
+			// compute expected content digest
+			//
+			VerifySignatures(s, hash);
+		}
+
+		[Test]
+		public void TestSha1WithRsaEncapsulated()
+		{
+			EncapsulatedTest(SignKP, SignCert, CmsSignedDataGenerator.DigestSha1);
+		}
+
+		[Test]
+		public void TestSha1WithRsaEncapsulatedSubjectKeyID()
+		{
+			SubjectKeyIDTest(SignKP, SignCert, CmsSignedDataGenerator.DigestSha1);
+		}
+
+		[Test]
+		public void TestSha1WithRsaPss()
+		{
+			rsaPssTest("SHA1", CmsSignedDataGenerator.DigestSha1);
+		}
+
+		[Test]
+		public void TestSha224WithRsaPss()
+		{
+			rsaPssTest("SHA224", CmsSignedDataGenerator.DigestSha224);
+		}
+
+		[Test]
+		public void TestSha256WithRsaPss()
+		{
+			rsaPssTest("SHA256", CmsSignedDataGenerator.DigestSha256);
+		}
+
+		[Test]
+		public void TestSha384WithRsaPss()
+		{
+			rsaPssTest("SHA384", CmsSignedDataGenerator.DigestSha384);
+		}
+
+		[Test]
+		public void TestSha224WithRsaEncapsulated()
+		{
+			EncapsulatedTest(SignKP, SignCert, CmsSignedDataGenerator.DigestSha224);
+		}
+
+		[Test]
+		public void TestSha256WithRsaEncapsulated()
+		{
+			EncapsulatedTest(SignKP, SignCert, CmsSignedDataGenerator.DigestSha256);
+		}
+
+		[Test]
+		public void TestRipeMD128WithRsaEncapsulated()
+		{
+			EncapsulatedTest(SignKP, SignCert, CmsSignedDataGenerator.DigestRipeMD128);
+		}
+
+		[Test]
+		public void TestRipeMD160WithRsaEncapsulated()
+		{
+			EncapsulatedTest(SignKP, SignCert, CmsSignedDataGenerator.DigestRipeMD160);
+		}
+
+		[Test]
+		public void TestRipeMD256WithRsaEncapsulated()
+		{
+			EncapsulatedTest(SignKP, SignCert, CmsSignedDataGenerator.DigestRipeMD256);
+		}
+
+		[Test]
+		public void TestECDsaEncapsulated()
+		{
+			EncapsulatedTest(SignECDsaKP, SignECDsaCert, CmsSignedDataGenerator.DigestSha1);
+		}
+
+		[Test]
+		public void TestECDsaEncapsulatedSubjectKeyID()
+		{
+			SubjectKeyIDTest(SignECDsaKP, SignECDsaCert, CmsSignedDataGenerator.DigestSha1);
+		}
+
+		[Test]
+		public void TestECDsaSha224Encapsulated()
+		{
+			EncapsulatedTest(SignECDsaKP, SignECDsaCert, CmsSignedDataGenerator.DigestSha224);
+		}
+
+		[Test]
+		public void TestECDsaSha256Encapsulated()
+		{
+			EncapsulatedTest(SignECDsaKP, SignECDsaCert, CmsSignedDataGenerator.DigestSha256);
+		}
+
+		[Test]
+		public void TestECDsaSha384Encapsulated()
+		{
+			EncapsulatedTest(SignECDsaKP, SignECDsaCert, CmsSignedDataGenerator.DigestSha384);
+		}
+
+		[Test]
+		public void TestECDsaSha512Encapsulated()
+		{
+			EncapsulatedTest(SignECDsaKP, SignECDsaCert, CmsSignedDataGenerator.DigestSha512);
+		}
+
+		[Test]
+		public void TestECDsaSha512EncapsulatedWithKeyFactoryAsEC()
+		{
+//			X509EncodedKeySpec  pubSpec = new X509EncodedKeySpec(_signEcDsaKP.getPublic().getEncoded());
+			byte[] pubEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(SignECDsaKP.Public).GetDerEncoded();
+//			PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(_signEcDsaKP.Private.getEncoded());
+			byte[] privEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(SignECDsaKP.Private).GetDerEncoded();
+//			KeyFactory          keyFact = KeyFactory.GetInstance("EC", "BC");
+//			KeyPair             kp = new KeyPair(keyFact.generatePublic(pubSpec), keyFact.generatePrivate(privSpec));
+			AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(
+                PublicKeyFactory.CreateKey(pubEnc),
+				PrivateKeyFactory.CreateKey(privEnc));
+
+			EncapsulatedTest(kp, SignECDsaCert, CmsSignedDataGenerator.DigestSha512);
+		}
+
+		[Test]
+		public void TestDsaEncapsulated()
+		{
+			EncapsulatedTest(SignDsaKP, SignDsaCert, CmsSignedDataGenerator.DigestSha1);
+		}
+
+		[Test]
+		public void TestDsaEncapsulatedSubjectKeyID()
+		{
+			SubjectKeyIDTest(SignDsaKP, SignDsaCert, CmsSignedDataGenerator.DigestSha1);
+		}
+
+		[Test]
+		public void TestGost3411WithGost3410Encapsulated()
+		{
+			EncapsulatedTest(SignGostKP, SignGostCert, CmsSignedDataGenerator.DigestGost3411);
+		}
+
+		[Test]
+		public void TestGost3411WithECGost3410Encapsulated()
+		{
+			EncapsulatedTest(SignECGostKP, SignECGostCert, CmsSignedDataGenerator.DigestGost3411);
+		}
+
+		[Test]
+		public void TestSha1WithRsaCounterSignature()
+		{
+			IList certList = new ArrayList();
+			IList crlList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello World!"));
+
+			certList.Add(SignCert);
+			certList.Add(OrigCert);
+
+			crlList.Add(SignCrl);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+			IX509Store x509Crls = X509StoreFactory.Create(
+				"CRL/Collection",
+				new X509CollectionStoreParameters(crlList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(SignKP.Private, SignCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+			gen.AddCrls(x509Crls);
+
+			CmsSignedData s = gen.Generate(msg, true);
+			SignerInformation origSigner = (SignerInformation) new ArrayList(s.GetSignerInfos().GetSigners())[0];
+			SignerInformationStore counterSigners1 = gen.GenerateCounterSigners(origSigner);
+			SignerInformationStore counterSigners2 = gen.GenerateCounterSigners(origSigner);
+
+			SignerInformation signer1 = SignerInformation.AddCounterSigners(origSigner, counterSigners1);
+			SignerInformation signer2 = SignerInformation.AddCounterSigners(signer1, counterSigners2);
+
+			SignerInformationStore cs = signer2.GetCounterSignatures();
+			ICollection csSigners = cs.GetSigners();
+			Assert.AreEqual(2, csSigners.Count);
+
+			foreach (SignerInformation cSigner in csSigners)
+			{
+				ICollection certCollection = x509Certs.GetMatches(cSigner.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				Assert.IsNull(cSigner.SignedAttributes[Asn1.Pkcs.PkcsObjectIdentifiers.Pkcs9AtContentType]);
+				Assert.IsTrue(cSigner.Verify(cert));
+			}
+		}
+
+		private void rsaPssTest(
+			string	digestName,
+			string	digestOID)
+		{
+			IList certList = new ArrayList();
+			byte[] msgBytes = Encoding.ASCII.GetBytes("Hello World!");
+			CmsProcessable msg = new CmsProcessableByteArray(msgBytes);
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.EncryptionRsaPss, digestOID);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData s = gen.Generate(CmsSignedDataGenerator.Data, msg, false);
+
+			//
+			// compute expected content digest
+			//
+			IDigest md = DigestUtilities.GetDigest(digestName);
+			md.BlockUpdate(msgBytes, 0, msgBytes.Length);
+			byte[] expectedDigest = DigestUtilities.DoFinal(md);
+
+			VerifySignatures(s, expectedDigest);
+		}
+
+		private void SubjectKeyIDTest(
+			AsymmetricCipherKeyPair	signaturePair,
+			X509Certificate			signatureCert,
+			string					digestAlgorithm)
+		{
+			IList certList = new ArrayList();
+			IList crlList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello World!"));
+
+			certList.Add(signatureCert);
+			certList.Add(OrigCert);
+
+			crlList.Add(SignCrl);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+			IX509Store x509Crls = X509StoreFactory.Create(
+				"CRL/Collection",
+				new X509CollectionStoreParameters(crlList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(signaturePair.Private,
+				CmsTestUtil.CreateSubjectKeyId(signatureCert.GetPublicKey()).GetKeyIdentifier(),
+				digestAlgorithm);
+
+			gen.AddCertificates(x509Certs);
+			gen.AddCrls(x509Crls);
+
+			CmsSignedData s = gen.Generate(msg, true);
+
+			Assert.AreEqual(3, s.Version);
+
+			MemoryStream bIn = new MemoryStream(s.GetEncoded(), false);
+			Asn1InputStream aIn = new Asn1InputStream(bIn);
+
+			s = new CmsSignedData(ContentInfo.GetInstance(aIn.ReadObject()));
+
+			x509Certs = s.GetCertificates("Collection");
+			x509Crls = s.GetCrls("Collection");
+
+			SignerInformationStore signers = s.GetSignerInfos();
+
+			foreach (SignerInformation signer in signers.GetSigners())
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				Assert.IsTrue(signer.Verify(cert));
+			}
+
+			//
+			// check for CRLs
+			//
+			ArrayList crls = new ArrayList(x509Crls.GetMatches(null));
+
+			Assert.AreEqual(1, crls.Count);
+
+			Assert.IsTrue(crls.Contains(SignCrl));
+
+			//
+			// try using existing signer
+			//
+
+			gen = new CmsSignedDataGenerator();
+
+			gen.AddSigners(s.GetSignerInfos());
+
+			gen.AddCertificates(s.GetCertificates("Collection"));
+			gen.AddCrls(s.GetCrls("Collection"));
+
+			s = gen.Generate(msg, true);
+
+			bIn = new MemoryStream(s.GetEncoded(), false);
+			aIn = new Asn1InputStream(bIn);
+
+			s = new CmsSignedData(ContentInfo.GetInstance(aIn.ReadObject()));
+
+			x509Certs = s.GetCertificates("Collection");
+			x509Crls = s.GetCrls("Collection");
+
+			signers = s.GetSignerInfos();
+
+			foreach (SignerInformation signer in signers.GetSigners())
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				Assert.IsTrue(signer.Verify(cert));
+			}
+
+			CheckSignerStoreReplacement(s, signers);
+		}
+
+		private void EncapsulatedTest(
+			AsymmetricCipherKeyPair	signaturePair,
+			X509Certificate			signatureCert,
+			string					digestAlgorithm)
+		{
+			IList certList = new ArrayList();
+			IList crlList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello World!"));
+
+			certList.Add(signatureCert);
+			certList.Add(OrigCert);
+
+			crlList.Add(SignCrl);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+			IX509Store x509Crls = X509StoreFactory.Create(
+				"CRL/Collection",
+				new X509CollectionStoreParameters(crlList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(signaturePair.Private, signatureCert, digestAlgorithm);
+
+			gen.AddCertificates(x509Certs);
+			gen.AddCrls(x509Crls);
+
+			CmsSignedData s = gen.Generate(msg, true);
+
+			s = new CmsSignedData(ContentInfo.GetInstance(Asn1Object.FromByteArray(s.GetEncoded())));
+
+			x509Certs = s.GetCertificates("Collection");
+			x509Crls = s.GetCrls("Collection");
+
+			SignerInformationStore signers = s.GetSignerInfos();
+			ICollection c = signers.GetSigners();
+
+			foreach (SignerInformation signer in c)
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				Assert.IsTrue(signer.Verify(cert));
+			}
+
+			//
+			// check for CRLs
+			//
+			ArrayList crls = new ArrayList(x509Crls.GetMatches(null));
+
+			Assert.AreEqual(1, crls.Count);
+
+			Assert.IsTrue(crls.Contains(SignCrl));
+
+			//
+			// try using existing signer
+			//
+
+			gen = new CmsSignedDataGenerator();
+
+			gen.AddSigners(s.GetSignerInfos());
+
+			gen.AddCertificates(s.GetCertificates("Collection"));
+			gen.AddCrls(s.GetCrls("Collection"));
+
+			s = gen.Generate(msg, true);
+
+			s = new CmsSignedData(ContentInfo.GetInstance(Asn1Object.FromByteArray(s.GetEncoded())));
+
+			x509Certs = s.GetCertificates("Collection");
+			x509Crls = s.GetCrls("Collection");
+
+			signers = s.GetSignerInfos();
+			c = signers.GetSigners();
+
+			foreach (SignerInformation signer in c)
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				Assert.IsTrue(signer.Verify(cert));
+			}
+
+			CheckSignerStoreReplacement(s, signers);
+		}
+
+		//
+		// signerInformation store replacement test.
+		//
+		private void CheckSignerStoreReplacement(
+			CmsSignedData orig,
+			SignerInformationStore signers)
+		{
+			CmsSignedData s = CmsSignedData.ReplaceSigners(orig, signers);
+
+			IX509Store x509Certs = s.GetCertificates("Collection");
+
+			signers = s.GetSignerInfos();
+			ICollection c = signers.GetSigners();
+
+			foreach (SignerInformation signer in c)
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				Assert.IsTrue(signer.Verify(cert));
+			}
+		}
+
+		[Test]
+		public void TestUnsortedAttributes()
+		{
+			CmsSignedData s = new CmsSignedData(new CmsProcessableByteArray(disorderedMessage), disorderedSet);
+
+			IX509Store x509Certs = s.GetCertificates("Collection");
+
+			SignerInformationStore	signers = s.GetSignerInfos();
+			ICollection				c = signers.GetSigners();
+
+			foreach (SignerInformation signer in c)
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate) certEnum.Current;
+
+				Assert.IsTrue(signer.Verify(cert));
+			}
+		}
+
+		[Test]
+		public void TestNullContentWithSigner()
+		{
+			IList certList = new ArrayList();
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData s = gen.Generate(null, false);
+
+			s = new CmsSignedData(ContentInfo.GetInstance(Asn1Object.FromByteArray(s.GetEncoded())));
+
+			VerifySignatures(s);
+		}
+
+		[Test]
+		public void TestWithAttributeCertificate()
+		{
+			IList certList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello World!"));
+
+			certList.Add(SignDsaCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			IX509AttributeCertificate attrCert = CmsTestUtil.GetAttributeCertificate();
+
+			ArrayList attrCerts = new ArrayList();
+			attrCerts.Add(attrCert);
+
+			IX509Store store = X509StoreFactory.Create(
+				"AttributeCertificate/Collection",
+				new X509CollectionStoreParameters(attrCerts));
+
+			gen.AddAttributeCertificates(store);
+
+			CmsSignedData sd = gen.Generate(msg);
+
+			Assert.AreEqual(4, sd.Version);
+
+			store = sd.GetAttributeCertificates("Collection");
+
+			ArrayList coll = new ArrayList(store.GetMatches(null));
+
+			Assert.AreEqual(1, coll.Count);
+
+			Assert.IsTrue(coll.Contains(attrCert));
+
+			//
+			// create new certstore
+			//
+			certList = new ArrayList();
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			//
+			// replace certs
+			//
+			sd = CmsSignedData.ReplaceCertificatesAndCrls(sd, x509Certs, null, null);
+
+			VerifySignatures(sd);
+		}
+
+		[Test]
+		public void TestCertStoreReplacement()
+		{
+			IList certList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello World!"));
+
+			certList.Add(SignDsaCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData sd = gen.Generate(msg);
+
+			//
+			// create new certstore
+			//
+			certList = new ArrayList();
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			//
+			// replace certs
+			//
+			sd = CmsSignedData.ReplaceCertificatesAndCrls(sd, x509Certs, null, null);
+
+			VerifySignatures(sd);
+		}
+
+		[Test]
+		public void TestEncapsulatedCertStoreReplacement()
+		{
+			IList certList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello World!"));
+
+			certList.Add(SignDsaCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData sd = gen.Generate(msg, true);
+
+			//
+			// create new certstore
+			//
+			certList = new ArrayList();
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			//
+			// replace certs
+			//
+			sd = CmsSignedData.ReplaceCertificatesAndCrls(sd, x509Certs, null, null);
+
+			VerifySignatures(sd);
+		}
+
+		[Test]
+		public void TestCertOrdering1()
+		{
+			IList certList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello World!"));
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+			certList.Add(SignDsaCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData sd = gen.Generate(msg, true);
+
+			x509Certs = sd.GetCertificates("Collection");
+			ArrayList a = new ArrayList(x509Certs.GetMatches(null));
+
+			Assert.AreEqual(3, a.Count);
+			Assert.AreEqual(OrigCert, a[0]);
+			Assert.AreEqual(SignCert, a[1]);
+			Assert.AreEqual(SignDsaCert, a[2]);
+		}
+
+		[Test]
+		public void TestCertOrdering2()
+		{
+			IList certList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello World!"));
+
+			certList.Add(SignCert);
+			certList.Add(SignDsaCert);
+			certList.Add(OrigCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+	
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData sd = gen.Generate(msg, true);
+
+			x509Certs = sd.GetCertificates("Collection");
+			ArrayList a = new ArrayList(x509Certs.GetMatches(null));
+
+			Assert.AreEqual(3, a.Count);
+			Assert.AreEqual(SignCert, a[0]);
+			Assert.AreEqual(SignDsaCert, a[1]);
+			Assert.AreEqual(OrigCert, a[2]);
+		}
+
+		[Test]
+		public void TestSignerStoreReplacement()
+		{
+			IList certList = new ArrayList();
+			CmsProcessable msg = new CmsProcessableByteArray(Encoding.ASCII.GetBytes("Hello World!"));
+
+			certList.Add(OrigCert);
+			certList.Add(SignCert);
+
+			IX509Store x509Certs = X509StoreFactory.Create(
+				"Certificate/Collection",
+				new X509CollectionStoreParameters(certList));
+
+			CmsSignedDataGenerator gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData original = gen.Generate(msg, true);
+
+			//
+			// create new Signer
+			//
+			gen = new CmsSignedDataGenerator();
+
+			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha224);
+
+			gen.AddCertificates(x509Certs);
+
+			CmsSignedData newSD = gen.Generate(msg, true);
+
+			//
+			// replace signer
+			//
+			CmsSignedData sd = CmsSignedData.ReplaceSigners(original, newSD.GetSignerInfos());
+
+			IEnumerator signerEnum = sd.GetSignerInfos().GetSigners().GetEnumerator();
+			signerEnum.MoveNext();
+			SignerInformation signer = (SignerInformation) signerEnum.Current;
+
+			Assert.AreEqual(CmsSignedDataGenerator.DigestSha224, signer.DigestAlgOid);
+
+			// we use a parser here as it requires the digests to be correct in the digest set, if it
+			// isn't we'll get a NullPointerException
+			CmsSignedDataParser sp = new CmsSignedDataParser(sd.GetEncoded());
+
+			sp.GetSignedContent().Drain();
+
+			VerifySignatures(sp);
+		}
+
+		[Test]
+		public void TestEncapsulatedSamples()
+		{
+			doTestSample("PSSSignDataSHA1Enc.sig");
+			doTestSample("PSSSignDataSHA256Enc.sig");
+			doTestSample("PSSSignDataSHA512Enc.sig");
+		}
+
+		[Test]
+		public void TestSamples()
+		{
+			doTestSample("PSSSignData.data", "PSSSignDataSHA1.sig");
+			doTestSample("PSSSignData.data", "PSSSignDataSHA256.sig");
+			doTestSample("PSSSignData.data", "PSSSignDataSHA512.sig");
+		}
+
+		[Test]
+		public void TestCounterSig()
+		{
+			CmsSignedData sig = new CmsSignedData(GetInput("counterSig.p7m"));
+
+			SignerInformationStore ss = sig.GetSignerInfos();
+			ArrayList signers = new ArrayList(ss.GetSigners());
+
+			SignerInformationStore cs = ((SignerInformation)signers[0]).GetCounterSignatures();
+			ArrayList csSigners = new ArrayList(cs.GetSigners());
+			Assert.AreEqual(1, csSigners.Count);
+
+			foreach (SignerInformation cSigner in csSigners)
+			{
+				ArrayList certCollection = new ArrayList(
+					sig.GetCertificates("Collection").GetMatches(cSigner.SignerID));
+
+				X509Certificate cert = (X509Certificate)certCollection[0];
+
+				Assert.IsNull(cSigner.SignedAttributes[Asn1.Pkcs.PkcsObjectIdentifiers.Pkcs9AtContentType]);
+				Assert.IsTrue(cSigner.Verify(cert));
+			}
+
+			VerifySignatures(sig);
+		}
+
+		private void doTestSample(
+			string sigName)
+		{
+			CmsSignedData sig = new CmsSignedData(GetInput(sigName));
+			VerifySignatures(sig);
+		}
+
+		private void doTestSample(
+			string	messageName,
+			string	sigName)
+		{
+			CmsSignedData sig = new CmsSignedData(
+				new CmsProcessableByteArray(GetInput(messageName)),
+				GetInput(sigName));
+
+			VerifySignatures(sig);
+		}
+
+		private byte[] GetInput(
+			string name)
+		{
+			return Streams.ReadAll(SimpleTest.GetTestDataAsStream("cms.sigs." + name));
+		}
+
+		[Test]
+		public void TestForMultipleCounterSignatures()
+		{
+			CmsSignedData sd = new CmsSignedData(xtraCounterSig);
+
+			foreach (SignerInformation sigI in sd.GetSignerInfos().GetSigners())
+			{
+				SignerInformationStore counter = sigI.GetCounterSignatures();
+				IList sigs = new ArrayList(counter.GetSigners());
+
+				Assert.AreEqual(2, sigs.Count);
+			}
+		}
+
+		private void VerifySignatures(
+			CmsSignedDataParser sp)
+		{
+			IX509Store x509Certs = sp.GetCertificates("Collection");
+			SignerInformationStore signers = sp.GetSignerInfos();
+
+			foreach (SignerInformation signer in signers.GetSigners())
+			{
+				ICollection certCollection = x509Certs.GetMatches(signer.SignerID);
+
+				IEnumerator certEnum = certCollection.GetEnumerator();
+				certEnum.MoveNext();
+				X509Certificate cert = (X509Certificate)certEnum.Current;
+
+				Assert.IsTrue(signer.Verify(cert));
+			}
+		}
+	}
+}