summary refs log tree commit diff
path: root/crypto/src/cms/CMSSignedGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/cms/CMSSignedGenerator.cs')
-rw-r--r--crypto/src/cms/CMSSignedGenerator.cs261
1 files changed, 261 insertions, 0 deletions
diff --git a/crypto/src/cms/CMSSignedGenerator.cs b/crypto/src/cms/CMSSignedGenerator.cs
new file mode 100644
index 000000000..f272c830e
--- /dev/null
+++ b/crypto/src/cms/CMSSignedGenerator.cs
@@ -0,0 +1,261 @@
+using System;
+using System.Collections;
+using System.IO;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.CryptoPro;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.TeleTrust;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.X509.Store;
+
+namespace Org.BouncyCastle.Cms
+{
+    public class CmsSignedGenerator
+    {
+        /**
+        * Default type for the signed data.
+        */
+        public static readonly string Data = CmsObjectIdentifiers.Data.Id;
+
+		public static readonly string DigestSha1 = OiwObjectIdentifiers.IdSha1.Id;
+        public static readonly string DigestSha224 = NistObjectIdentifiers.IdSha224.Id;
+        public static readonly string DigestSha256 = NistObjectIdentifiers.IdSha256.Id;
+        public static readonly string DigestSha384 = NistObjectIdentifiers.IdSha384.Id;
+        public static readonly string DigestSha512 = NistObjectIdentifiers.IdSha512.Id;
+        public static readonly string DigestMD5 = PkcsObjectIdentifiers.MD5.Id;
+        public static readonly string DigestGost3411 = CryptoProObjectIdentifiers.GostR3411.Id;
+		public static readonly string DigestRipeMD128 = TeleTrusTObjectIdentifiers.RipeMD128.Id;
+		public static readonly string DigestRipeMD160 = TeleTrusTObjectIdentifiers.RipeMD160.Id;
+		public static readonly string DigestRipeMD256 = TeleTrusTObjectIdentifiers.RipeMD256.Id;
+
+		public static readonly string EncryptionRsa = PkcsObjectIdentifiers.RsaEncryption.Id;
+        public static readonly string EncryptionDsa = X9ObjectIdentifiers.IdDsaWithSha1.Id;
+        public static readonly string EncryptionECDsa = X9ObjectIdentifiers.ECDsaWithSha1.Id;
+        public static readonly string EncryptionRsaPss = PkcsObjectIdentifiers.IdRsassaPss.Id;
+        public static readonly string EncryptionGost3410 = CryptoProObjectIdentifiers.GostR3410x94.Id;
+        public static readonly string EncryptionECGost3410 = CryptoProObjectIdentifiers.GostR3410x2001.Id;
+
+		private static readonly string EncryptionECDsaWithSha1 = X9ObjectIdentifiers.ECDsaWithSha1.Id;
+		private static readonly string EncryptionECDsaWithSha224 = X9ObjectIdentifiers.ECDsaWithSha224.Id;
+		private static readonly string EncryptionECDsaWithSha256 = X9ObjectIdentifiers.ECDsaWithSha256.Id;
+		private static readonly string EncryptionECDsaWithSha384 = X9ObjectIdentifiers.ECDsaWithSha384.Id;
+		private static readonly string EncryptionECDsaWithSha512 = X9ObjectIdentifiers.ECDsaWithSha512.Id;
+
+		private static readonly ISet noParams = new HashSet();
+		private static readonly IDictionary ecAlgorithms = Platform.CreateHashtable();
+
+		static CmsSignedGenerator()
+		{
+			noParams.Add(EncryptionDsa);
+//			noParams.Add(EncryptionECDsa);
+			noParams.Add(EncryptionECDsaWithSha1);
+			noParams.Add(EncryptionECDsaWithSha224);
+			noParams.Add(EncryptionECDsaWithSha256);
+			noParams.Add(EncryptionECDsaWithSha384);
+			noParams.Add(EncryptionECDsaWithSha512);
+
+			ecAlgorithms.Add(DigestSha1, EncryptionECDsaWithSha1);
+			ecAlgorithms.Add(DigestSha224, EncryptionECDsaWithSha224);
+			ecAlgorithms.Add(DigestSha256, EncryptionECDsaWithSha256);
+			ecAlgorithms.Add(DigestSha384, EncryptionECDsaWithSha384);
+			ecAlgorithms.Add(DigestSha512, EncryptionECDsaWithSha512);
+		}
+
+		internal IList _certs = Platform.CreateArrayList();
+        internal IList _crls = Platform.CreateArrayList();
+		internal IList _signers = Platform.CreateArrayList();
+		internal IDictionary _digests = Platform.CreateHashtable();
+
+		protected readonly SecureRandom rand;
+
+		protected CmsSignedGenerator()
+			: this(new SecureRandom())
+		{
+		}
+
+		/// <summary>Constructor allowing specific source of randomness</summary>
+		/// <param name="rand">Instance of <c>SecureRandom</c> to use.</param>
+		protected CmsSignedGenerator(
+			SecureRandom rand)
+		{
+			this.rand = rand;
+		}
+
+		protected string GetEncOid(
+            AsymmetricKeyParameter	key,
+            string					digestOID)
+        {
+            string encOID = null;
+
+			if (key is RsaKeyParameters)
+			{
+				if (!((RsaKeyParameters) key).IsPrivate)
+					throw new ArgumentException("Expected RSA private key");
+
+				encOID = EncryptionRsa;
+			}
+			else if (key is DsaPrivateKeyParameters)
+			{
+				if (!digestOID.Equals(DigestSha1))
+					throw new ArgumentException("can't mix DSA with anything but SHA1");
+
+				encOID = EncryptionDsa;
+			}
+			else if (key is ECPrivateKeyParameters)
+			{
+				ECPrivateKeyParameters ecPrivKey = (ECPrivateKeyParameters) key;
+				string algName = ecPrivKey.AlgorithmName;
+
+				if (algName == "ECGOST3410")
+				{
+					encOID = EncryptionECGost3410;
+				}
+				else
+				{
+					// TODO Should we insist on algName being one of "EC" or "ECDSA", as Java does?
+					encOID = (string) ecAlgorithms[digestOID];
+
+					if (encOID == null)
+						throw new ArgumentException("can't mix ECDSA with anything but SHA family digests");
+				}
+			}
+			else if (key is Gost3410PrivateKeyParameters)
+			{
+				encOID = EncryptionGost3410;
+			}
+			else
+			{
+				throw new ArgumentException("Unknown algorithm in CmsSignedGenerator.GetEncOid");
+			}
+
+			return encOID;
+        }
+
+		internal static AlgorithmIdentifier GetEncAlgorithmIdentifier(
+			DerObjectIdentifier	encOid,
+			Asn1Encodable		sigX509Parameters)
+		{
+			if (noParams.Contains(encOid.Id))
+			{
+				return new AlgorithmIdentifier(encOid);
+			}
+
+			return new AlgorithmIdentifier(encOid, sigX509Parameters);
+		}
+
+		internal protected virtual IDictionary GetBaseParameters(
+			DerObjectIdentifier	contentType,
+			AlgorithmIdentifier	digAlgId,
+			byte[]				hash)
+		{
+			IDictionary param = Platform.CreateHashtable();
+
+            if (contentType != null)
+            {
+                param[CmsAttributeTableParameter.ContentType] = contentType;
+            }
+
+			param[CmsAttributeTableParameter.DigestAlgorithmIdentifier] = digAlgId;
+            param[CmsAttributeTableParameter.Digest] = hash.Clone();
+
+            return param;
+		}
+
+		internal protected virtual Asn1Set GetAttributeSet(
+            Asn1.Cms.AttributeTable attr)
+        {
+			return attr == null
+				?	null
+				:	new DerSet(attr.ToAsn1EncodableVector());
+        }
+
+		public void AddCertificates(
+			IX509Store certStore)
+		{
+            CollectionUtilities.AddRange(_certs, CmsUtilities.GetCertificatesFromStore(certStore));
+        }
+
+		public void AddCrls(
+			IX509Store crlStore)
+		{
+            CollectionUtilities.AddRange(_crls, CmsUtilities.GetCrlsFromStore(crlStore));
+		}
+
+		/**
+		* Add the attribute certificates contained in the passed in store to the
+		* generator.
+		*
+		* @param store a store of Version 2 attribute certificates
+		* @throws CmsException if an error occurse processing the store.
+		*/
+		public void AddAttributeCertificates(
+			IX509Store store)
+		{
+			try
+			{
+				foreach (IX509AttributeCertificate attrCert in store.GetMatches(null))
+				{
+					_certs.Add(new DerTaggedObject(false, 2,
+						AttributeCertificate.GetInstance(Asn1Object.FromByteArray(attrCert.GetEncoded()))));
+				}
+			}
+			catch (Exception e)
+			{
+				throw new CmsException("error processing attribute certs", e);
+			}
+		}
+
+		/**
+		 * Add a store of precalculated signers to the generator.
+		 *
+		 * @param signerStore store of signers
+		 */
+		public void AddSigners(
+			SignerInformationStore signerStore)
+		{
+			foreach (SignerInformation o in signerStore.GetSigners())
+			{
+				_signers.Add(o);
+				AddSignerCallback(o);
+			}
+		}
+
+		/**
+		 * Return a map of oids and byte arrays representing the digests calculated on the content during
+		 * the last generate.
+		 *
+		 * @return a map of oids (as String objects) and byte[] representing digests.
+		 */
+		public IDictionary GetGeneratedDigests()
+		{
+			return Platform.CreateHashtable(_digests);
+		}
+
+		internal virtual void AddSignerCallback(
+			SignerInformation si)
+		{
+		}
+
+		internal static SignerIdentifier GetSignerIdentifier(X509Certificate cert)
+		{
+			return new SignerIdentifier(CmsUtilities.GetIssuerAndSerialNumber(cert));
+		}
+
+		internal static SignerIdentifier GetSignerIdentifier(byte[] subjectKeyIdentifier)
+		{
+			return new SignerIdentifier(new DerOctetString(subjectKeyIdentifier));    
+		}
+	}
+}