summary refs log tree commit diff
path: root/crypto/src/cms
diff options
context:
space:
mode:
authorMW <megan@cryptoworkshop.com>2019-01-17 16:16:20 +1100
committerMW <megan@cryptoworkshop.com>2019-01-17 16:16:20 +1100
commit3d578b981aad94eaee07fa444dd11f9323026e94 (patch)
treed64141ae1163cafb69a4e3fc26ab90b538d98ef6 /crypto/src/cms
parentMissing from previous commit (diff)
downloadBouncyCastle.NET-ed25519-3d578b981aad94eaee07fa444dd11f9323026e94.tar.xz
CMS ArchiveControl
Diffstat (limited to 'crypto/src/cms')
-rw-r--r--crypto/src/cms/CMSEnvelopedDataGenerator.cs71
-rw-r--r--crypto/src/cms/CMSEnvelopedGenerator.cs10
-rw-r--r--crypto/src/cms/CMSProcessableByteArray.cs17
-rw-r--r--crypto/src/cms/EnvelopedDataHelper.cs123
-rw-r--r--crypto/src/cms/RecipientInfoGenerator.cs2
5 files changed, 220 insertions, 3 deletions
diff --git a/crypto/src/cms/CMSEnvelopedDataGenerator.cs b/crypto/src/cms/CMSEnvelopedDataGenerator.cs
index d260e998a..8ba41161e 100644
--- a/crypto/src/cms/CMSEnvelopedDataGenerator.cs
+++ b/crypto/src/cms/CMSEnvelopedDataGenerator.cs
@@ -144,7 +144,7 @@ namespace Org.BouncyCastle.Cms
             try
             {
 				CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator(encryptionOid);
-
+               
 				keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength));
 
 				return Generate(content, encryptionOid, keyGen);
@@ -155,6 +155,75 @@ namespace Org.BouncyCastle.Cms
             }
         }
 
+
+        public CmsEnvelopedData Generate(CmsProcessable content, ICipherBuilderWithKey cipherBuilder)
+        {
+            AlgorithmIdentifier encAlgId = null;
+            KeyParameter encKey;
+            Asn1OctetString encContent;
+
+            try
+            {
+                encKey = (KeyParameter) cipherBuilder.Key;
+
+                MemoryStream collector = new MemoryStream();
+                Stream bOut = cipherBuilder.BuildCipher(collector).Stream;            
+                content.Write(bOut);  
+                Platform.Dispose(bOut);                            
+                encContent = new BerOctetString(collector.ToArray());
+            }
+            catch (SecurityUtilityException e)
+            {
+                throw new CmsException("couldn't create cipher.", e);
+            }
+            catch (InvalidKeyException e)
+            {
+                throw new CmsException("key invalid in message.", e);
+            }
+            catch (IOException e)
+            {
+                throw new CmsException("exception decoding algorithm parameters.", e);
+            }
+
+
+            Asn1EncodableVector recipientInfos = new Asn1EncodableVector();
+
+            foreach (RecipientInfoGenerator rig in recipientInfoGenerators)
+            {
+                try
+                {
+                    recipientInfos.Add(rig.Generate(encKey, rand));
+                }
+                catch (InvalidKeyException e)
+                {
+                    throw new CmsException("key inappropriate for algorithm.", e);
+                }
+                catch (GeneralSecurityException e)
+                {
+                    throw new CmsException("error making encrypted content.", e);
+                }
+            }
+
+            EncryptedContentInfo eci = new EncryptedContentInfo(
+                CmsObjectIdentifiers.Data,
+                (AlgorithmIdentifier) cipherBuilder.AlgorithmDetails,
+                encContent);
+
+            Asn1Set unprotectedAttrSet = null;
+            if (unprotectedAttributeGenerator != null)
+            {
+                Asn1.Cms.AttributeTable attrTable = unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable());
+
+                unprotectedAttrSet = new BerSet(attrTable.ToAsn1EncodableVector());
+            }
+
+            ContentInfo contentInfo = new ContentInfo(
+                CmsObjectIdentifiers.EnvelopedData,
+                new EnvelopedData(null, new DerSet(recipientInfos), eci, unprotectedAttrSet));
+
+            return new CmsEnvelopedData(contentInfo);
+        }
+
 		/// <summary>Generate an enveloped object that contains an CMS Enveloped Data object.</summary>
         public CmsEnvelopedData Generate(
             CmsProcessable  content,
diff --git a/crypto/src/cms/CMSEnvelopedGenerator.cs b/crypto/src/cms/CMSEnvelopedGenerator.cs
index f92ae3824..ed7e1edee 100644
--- a/crypto/src/cms/CMSEnvelopedGenerator.cs
+++ b/crypto/src/cms/CMSEnvelopedGenerator.cs
@@ -263,6 +263,16 @@ namespace Org.BouncyCastle.Cms
 			recipientInfoGenerators.Add(karig);
 		}
 
+        /// <summary>
+        /// Add a generator to produce the recipient info required.
+        /// </summary>
+        /// <param name="recipientInfoGenerator">a generator of a recipient info object.</param>
+	    public void AddRecipientInfoGenerator(RecipientInfoGenerator recipientInfoGenerator)
+	    {
+	        recipientInfoGenerators.Add(recipientInfoGenerator);
+	    }
+
+
         protected internal virtual AlgorithmIdentifier GetAlgorithmIdentifier(
 			string					encryptionOid,
 			KeyParameter			encKey,
diff --git a/crypto/src/cms/CMSProcessableByteArray.cs b/crypto/src/cms/CMSProcessableByteArray.cs
index a6ab9b6a2..b09935dd8 100644
--- a/crypto/src/cms/CMSProcessableByteArray.cs
+++ b/crypto/src/cms/CMSProcessableByteArray.cs
@@ -1,5 +1,7 @@
 using System;
 using System.IO;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
 
 namespace Org.BouncyCastle.Cms
 {
@@ -9,13 +11,26 @@ namespace Org.BouncyCastle.Cms
 	public class CmsProcessableByteArray
 		: CmsProcessable, CmsReadable
 	{
+	    private readonly DerObjectIdentifier type;
 		private readonly byte[] bytes;
 
         public CmsProcessableByteArray(byte[] bytes)
-		{
+        {
+            type = CmsObjectIdentifiers.Data;
 			this.bytes = bytes;
 		}
 
+	    public CmsProcessableByteArray(DerObjectIdentifier type, byte[] bytes)
+	    {
+	        this.bytes = bytes;
+	        this.type = type;
+	    }
+
+	    public DerObjectIdentifier Type
+	    {
+	        get { return type; }
+	    }
+
         public virtual Stream GetInputStream()
 		{
 			return new MemoryStream(bytes, false);
diff --git a/crypto/src/cms/EnvelopedDataHelper.cs b/crypto/src/cms/EnvelopedDataHelper.cs
new file mode 100644
index 000000000..89ec79691
--- /dev/null
+++ b/crypto/src/cms/EnvelopedDataHelper.cs
@@ -0,0 +1,123 @@
+using System.Collections;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.Operators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Crypto.Utilities;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Cms
+{
+    public class EnvelopedDataHelper
+    {
+        private static readonly IDictionary BaseCipherNames = Platform.CreateHashtable();
+        private static readonly IDictionary MacAlgNames = Platform.CreateHashtable();
+
+        private static readonly IDictionary prfs = Platform.CreateHashtable();
+
+
+        public delegate IDigest DigestCreator();
+
+        static EnvelopedDataHelper()
+        {
+            prfs.Add(PkcsObjectIdentifiers.IdHmacWithSha1, new DigestProvider(delegate () { return new Sha1Digest(); }));
+            prfs.Add(PkcsObjectIdentifiers.IdHmacWithSha224, new DigestProvider(delegate () { return new Sha224Digest(); }));
+            prfs.Add(PkcsObjectIdentifiers.IdHmacWithSha256, new DigestProvider(delegate () { return new Sha256Digest(); }));
+            prfs.Add(PkcsObjectIdentifiers.IdHmacWithSha384, new DigestProvider(delegate () { return new Sha384Digest(); }));
+            prfs.Add(PkcsObjectIdentifiers.IdHmacWithSha512, new DigestProvider(delegate () { return new Sha512Digest(); }));
+
+
+            BaseCipherNames.Add(PkcsObjectIdentifiers.DesEde3Cbc, "DESEDE");
+            BaseCipherNames.Add(NistObjectIdentifiers.IdAes128Cbc, "AES");
+            BaseCipherNames.Add(NistObjectIdentifiers.IdAes192Cbc, "AES");
+            BaseCipherNames.Add(NistObjectIdentifiers.IdAes256Cbc, "AES");
+
+            MacAlgNames.Add(PkcsObjectIdentifiers.DesEde3Cbc, "DESEDEMac");
+            MacAlgNames.Add(NistObjectIdentifiers.IdAes128Cbc, "AESMac");
+            MacAlgNames.Add(NistObjectIdentifiers.IdAes192Cbc, "AESMac");
+            MacAlgNames.Add(NistObjectIdentifiers.IdAes256Cbc, "AESMac");
+            MacAlgNames.Add(PkcsObjectIdentifiers.RC2Cbc, "RC2Mac");
+        }
+
+        static IDigest GetPrf(AlgorithmIdentifier algID)
+        {
+            return ((DigestCreator)prfs[algID]).Invoke();
+        }
+
+
+        static IWrapper CreateRFC3211Wrapper(DerObjectIdentifier algorithm)
+
+        {
+            if (NistObjectIdentifiers.IdAes128Cbc.Equals(algorithm)
+        || NistObjectIdentifiers.IdAes192Cbc.Equals(algorithm)
+        || NistObjectIdentifiers.IdAes256Cbc.Equals(algorithm))
+            {
+                return new Rfc3211WrapEngine(new AesEngine());
+            }
+            else if (PkcsObjectIdentifiers.DesEde3Cbc.Equals(algorithm))
+            {
+                return new Rfc3211WrapEngine(new DesEdeEngine());
+            }
+            else if (OiwObjectIdentifiers.DesCbc.Equals(algorithm))
+            {
+                return new Rfc3211WrapEngine(new DesEngine());
+            }
+            else if (PkcsObjectIdentifiers.RC2Cbc.Equals(algorithm))
+            {
+                return new Rfc3211WrapEngine(new RC2Engine());
+            }
+            else
+            {
+                throw new CmsException("cannot recognise wrapper: " + algorithm);
+            }
+        }
+
+
+
+       public static object CreateContentCipher(bool forEncryption, ICipherParameters encKey,
+            AlgorithmIdentifier encryptionAlgID)
+
+        {
+            return CipherFactory.CreateContentCipher(forEncryption, encKey, encryptionAlgID);
+        }
+
+
+        public AlgorithmIdentifier GenerateEncryptionAlgID(DerObjectIdentifier encryptionOID, KeyParameter encKey, SecureRandom random)
+
+        {
+            return AlgorithmIdentifierFactory.GenerateEncryptionAlgID(encryptionOID, encKey.GetKey().Length * 8, random);
+        }
+
+       public  CipherKeyGenerator CreateKeyGenerator(DerObjectIdentifier algorithm, SecureRandom random)
+
+        {
+            return CipherKeyGeneratorFactory.CreateKeyGenerator(algorithm, random);
+        }
+
+
+    }
+
+    // This exists because we can't directly put a delegate in a map as it is
+    // not an object.
+    internal class DigestProvider
+    {
+        private readonly EnvelopedDataHelper.DigestCreator creator;
+
+        public DigestProvider(EnvelopedDataHelper.DigestCreator creator)
+        {
+            this.creator = creator;
+        }
+
+        public IDigest Create()
+        {
+            return creator.Invoke();
+        }
+    }
+}
\ No newline at end of file
diff --git a/crypto/src/cms/RecipientInfoGenerator.cs b/crypto/src/cms/RecipientInfoGenerator.cs
index c41db6122..75f5dcc33 100644
--- a/crypto/src/cms/RecipientInfoGenerator.cs
+++ b/crypto/src/cms/RecipientInfoGenerator.cs
@@ -6,7 +6,7 @@ using Org.BouncyCastle.Security;
 
 namespace Org.BouncyCastle.Cms
 {
-	interface RecipientInfoGenerator
+	public interface RecipientInfoGenerator
 	{
 		/// <summary>
 		/// Generate a RecipientInfo object for the given key.