diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2013-06-28 15:26:06 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2013-06-28 15:26:06 +0700 |
commit | 44288db4414158ac9b98a507b15e81d0d3c66ca6 (patch) | |
tree | aa5ef88948ebb68ed6c8df81eb5da889641a9b50 /crypto/test/src/cms | |
parent | Set up text/binary handling for existing file types (diff) | |
download | BouncyCastle.NET-ed25519-44288db4414158ac9b98a507b15e81d0d3c66ca6.tar.xz |
Initial import of old CVS repository
Diffstat (limited to 'crypto/test/src/cms')
-rw-r--r-- | crypto/test/src/cms/test/AllTests.cs | 35 | ||||
-rw-r--r-- | crypto/test/src/cms/test/AuthenticatedDataStreamTest.cs | 113 | ||||
-rw-r--r-- | crypto/test/src/cms/test/AuthenticatedDataTest.cs | 320 | ||||
-rw-r--r-- | crypto/test/src/cms/test/CMSSampleMessages.cs | 147 | ||||
-rw-r--r-- | crypto/test/src/cms/test/CMSTestUtil.cs | 480 | ||||
-rw-r--r-- | crypto/test/src/cms/test/CompressedDataStreamTest.cs | 116 | ||||
-rw-r--r-- | crypto/test/src/cms/test/CompressedDataTest.cs | 117 | ||||
-rw-r--r-- | crypto/test/src/cms/test/EnvelopedDataStreamTest.cs | 537 | ||||
-rw-r--r-- | crypto/test/src/cms/test/EnvelopedDataTest.cs | 866 | ||||
-rw-r--r-- | crypto/test/src/cms/test/MiscDataStreamTest.cs | 221 | ||||
-rw-r--r-- | crypto/test/src/cms/test/Rfc4134Test.cs | 344 | ||||
-rw-r--r-- | crypto/test/src/cms/test/SignedDataStreamTest.cs | 1215 | ||||
-rw-r--r-- | crypto/test/src/cms/test/SignedDataTest.cs | 1480 |
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( + "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" + + "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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" + + "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)); + } + } + } +} |