summary refs log tree commit diff
path: root/crypto/src/cms/CMSSignedDataStreamGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/cms/CMSSignedDataStreamGenerator.cs')
-rw-r--r--crypto/src/cms/CMSSignedDataStreamGenerator.cs154
1 files changed, 61 insertions, 93 deletions
diff --git a/crypto/src/cms/CMSSignedDataStreamGenerator.cs b/crypto/src/cms/CMSSignedDataStreamGenerator.cs
index 959bde10f..81f6f5068 100644
--- a/crypto/src/cms/CMSSignedDataStreamGenerator.cs
+++ b/crypto/src/cms/CMSSignedDataStreamGenerator.cs
@@ -7,9 +7,8 @@ using Org.BouncyCastle.Asn1.Cms;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Crypto.IO;
-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;
 
@@ -38,9 +37,8 @@ namespace Org.BouncyCastle.Cms
     public class CmsSignedDataStreamGenerator
         : CmsSignedGenerator
     {
-		private readonly IList<DigestAndSignerInfoGeneratorHolder> _signerInfs =
-			new List<DigestAndSignerInfoGeneratorHolder>();
-		private readonly HashSet<string> _messageDigestOids = new HashSet<string>();
+		private readonly List<SignerInfoGeneratorImpl> m_signerInfoGens = new List<SignerInfoGeneratorImpl>();
+		private readonly HashSet<DerObjectIdentifier> m_messageDigestOids = new HashSet<DerObjectIdentifier>();
 		private readonly IDictionary<string, IDigest> m_messageDigests =
 			new Dictionary<string, IDigest>(StringComparer.OrdinalIgnoreCase);
 		private readonly IDictionary<string, byte[]> m_messageHashes =
@@ -48,30 +46,13 @@ namespace Org.BouncyCastle.Cms
 		private bool _messageDigestsLocked;
         private int _bufferSize;
 
-		private class DigestAndSignerInfoGeneratorHolder
-		{
-			internal readonly ISignerInfoGenerator	signerInf;
-			internal readonly string				digestOID;
-
-			internal DigestAndSignerInfoGeneratorHolder(ISignerInfoGenerator signerInf, string digestOID)
-			{
-				this.signerInf = signerInf;
-				this.digestOID = digestOID;
-			}
-
-			internal AlgorithmIdentifier DigestAlgorithm
-			{
-				get { return new AlgorithmIdentifier(new DerObjectIdentifier(this.digestOID), DerNull.Instance); }
-			}
-		}
-
-		private class SignerInfoGeneratorImpl : ISignerInfoGenerator
+		private class SignerInfoGeneratorImpl
         {
 			private readonly CmsSignedDataStreamGenerator outer;
 
 			private readonly SignerIdentifier			_signerIdentifier;
-			private readonly string						_digestOID;
-			private readonly string						_encOID;
+			internal readonly DerObjectIdentifier m_digestOid;
+			private readonly DerObjectIdentifier m_encOid;
 			private readonly CmsAttributeTableGenerator	_sAttr;
 			private readonly CmsAttributeTableGenerator	_unsAttr;
 			private readonly string						_encName;
@@ -81,21 +62,21 @@ namespace Org.BouncyCastle.Cms
 				CmsSignedDataStreamGenerator	outer,
 				AsymmetricKeyParameter			key,
 				SignerIdentifier				signerIdentifier,
-				string							digestOID,
-				string							encOID,
+				DerObjectIdentifier digestOid,
+                DerObjectIdentifier encOid,
 				CmsAttributeTableGenerator		sAttr,
 				CmsAttributeTableGenerator		unsAttr)
 			{
 				this.outer = outer;
 
 				_signerIdentifier = signerIdentifier;
-				_digestOID = digestOID;
-				_encOID = encOID;
+				m_digestOid = digestOid;
+				m_encOid = encOid;
 				_sAttr = sAttr;
 				_unsAttr = unsAttr;
-				_encName = CmsSignedHelper.GetEncryptionAlgName(_encOID);
+				_encName = CmsSignedHelper.GetEncryptionAlgName(m_encOid);
 
-				string digestName = CmsSignedHelper.GetDigestAlgName(_digestOID);
+				string digestName = CmsSignedHelper.GetDigestAlgName(digestOid);
 				string signatureName = digestName + "with" + _encName;
 
 				if (_sAttr != null)
@@ -136,18 +117,15 @@ namespace Org.BouncyCastle.Cms
                 }
             }
 
-			public SignerInfo Generate(DerObjectIdentifier contentType, AlgorithmIdentifier digestAlgorithm,
-        		byte[] calculatedDigest)
+			internal SignerInfo Generate(DerObjectIdentifier contentType, byte[] calculatedDigest)
 			{
-				try
-				{
-					string digestName = CmsSignedHelper.GetDigestAlgName(_digestOID);
-					string signatureName = digestName + "with" + _encName;
+                // TODO AlgorithmIdentifier noParams handling (configure an IDigestAlgorithmFinder)
+                var digestAlgorithm = new AlgorithmIdentifier(m_digestOid, DerNull.Instance);
 
-//					AlgorithmIdentifier digAlgId = DigestAlgorithmID;
-//
-//					byte[] hash = (byte[])outer._messageHashes[Helper.GetDigestAlgName(this._digestOID)];
-//					outer._digests[_digestOID] = hash.Clone();
+                try
+                {
+					string digestName = CmsSignedHelper.GetDigestAlgName(m_digestOid);
+					string signatureName = digestName + "with" + _encName;
 
 					byte[] bytesToSign = calculatedDigest;
 
@@ -165,8 +143,7 @@ namespace Org.BouncyCastle.Cms
 					{
 						var parameters = outer.GetBaseParameters(contentType, digestAlgorithm, calculatedDigest);
 
-//						Asn1.Cms.AttributeTable signed = _sAttr.GetAttributes(Collections.unmodifiableMap(parameters));
-						Asn1.Cms.AttributeTable signed = _sAttr.GetAttributes(parameters);
+						Asn1.Cms.AttributeTable signed = _sAttr.GetAttributes(CollectionUtilities.ReadOnly(parameters));
 
                         if (contentType == null) //counter signature
                         {
@@ -200,8 +177,7 @@ namespace Org.BouncyCastle.Cms
 						var parameters = outer.GetBaseParameters(contentType, digestAlgorithm, calculatedDigest);
 						parameters[CmsAttributeTableParameter.Signature] = sigBytes.Clone();
 
-//						Asn1.Cms.AttributeTable unsigned = _unsAttr.getAttributes(Collections.unmodifiableMap(parameters));
-						Asn1.Cms.AttributeTable unsigned = _unsAttr.GetAttributes(parameters);
+						Asn1.Cms.AttributeTable unsigned = _unsAttr.GetAttributes(CollectionUtilities.ReadOnly(parameters));
 
 						unsignedAttr = outer.GetAttributeSet(unsigned);
 					}
@@ -209,7 +185,7 @@ namespace Org.BouncyCastle.Cms
 					// TODO[RSAPSS] Need the ability to specify non-default parameters
 					Asn1Encodable sigX509Parameters = SignerUtilities.GetDefaultX509Parameters(signatureName);
 					AlgorithmIdentifier digestEncryptionAlgorithm = CmsSignedHelper.GetEncAlgorithmIdentifier(
-						new DerObjectIdentifier(_encOID), sigX509Parameters);
+						m_encOid, sigX509Parameters);
 
 					return new SignerInfo(_signerIdentifier, digestAlgorithm,
 						signedAttr, digestEncryptionAlgorithm, new DerOctetString(sigBytes), unsignedAttr);
@@ -250,7 +226,7 @@ namespace Org.BouncyCastle.Cms
 		{
 			foreach (string digestOid in digestOids)
 			{
-				ConfigureDigest(digestOid);
+				ConfigureDigest(new DerObjectIdentifier(digestOid));
 			}
 		}
 
@@ -258,23 +234,19 @@ namespace Org.BouncyCastle.Cms
 		{
 			foreach (string digestOid in digestOids)
 			{
-				ConfigureDigest(digestOid);
+				ConfigureDigest(new DerObjectIdentifier(digestOid));
 			}
 		}
 
-		/**
+        /**
         * add a signer - no attributes other than the default ones will be
         * provided here.
         * @throws NoSuchAlgorithmException
         * @throws InvalidKeyException
         */
-        public void AddSigner(
-            AsymmetricKeyParameter	privateKey,
-            X509Certificate			cert,
-            string					digestOid)
+        public void AddSigner(AsymmetricKeyParameter privateKey, X509Certificate cert, string digestOid)
         {
-			AddSigner(privateKey, cert, digestOid,
-				new DefaultSignedAttributeTableGenerator(), null);
+            AddSigner(privateKey, cert, digestOid, new DefaultSignedAttributeTableGenerator(), null);
 		}
 
 		/**
@@ -339,7 +311,7 @@ namespace Org.BouncyCastle.Cms
 			CmsAttributeTableGenerator  signedAttrGenerator,
 			CmsAttributeTableGenerator  unsignedAttrGenerator)
 		{
-			AddSigner(privateKey, cert, CmsSignedHelper.GetEncOid(privateKey, digestOid), digestOid,
+			AddSigner(privateKey, cert, CmsSignedHelper.GetEncOid(privateKey, digestOid)?.Id, digestOid,
 				signedAttrGenerator, unsignedAttrGenerator);
         }
 
@@ -351,8 +323,8 @@ namespace Org.BouncyCastle.Cms
 			CmsAttributeTableGenerator  signedAttrGenerator,
 			CmsAttributeTableGenerator  unsignedAttrGenerator)
 		{
-			DoAddSigner(privateKey, GetSignerIdentifier(cert), encryptionOid, digestOid,
-				signedAttrGenerator, unsignedAttrGenerator);
+			DoAddSigner(privateKey, GetSignerIdentifier(cert), new DerObjectIdentifier(encryptionOid),
+				new DerObjectIdentifier(digestOid), signedAttrGenerator, unsignedAttrGenerator);
 		}
 
 		/**
@@ -412,8 +384,8 @@ namespace Org.BouncyCastle.Cms
 			CmsAttributeTableGenerator	signedAttrGenerator,
 			CmsAttributeTableGenerator	unsignedAttrGenerator)
 		{
-			AddSigner(privateKey, subjectKeyID, CmsSignedHelper.GetEncOid(privateKey, digestOid),
-				digestOid, signedAttrGenerator, unsignedAttrGenerator);
+			AddSigner(privateKey, subjectKeyID, CmsSignedHelper.GetEncOid(privateKey, digestOid)?.Id, digestOid,
+				signedAttrGenerator, unsignedAttrGenerator);
 		}
 
 		public void AddSigner(
@@ -424,24 +396,24 @@ namespace Org.BouncyCastle.Cms
 			CmsAttributeTableGenerator	signedAttrGenerator,
 			CmsAttributeTableGenerator	unsignedAttrGenerator)
 		{
-			DoAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), encryptionOid, digestOid,
-				signedAttrGenerator, unsignedAttrGenerator);
+			DoAddSigner(privateKey, GetSignerIdentifier(subjectKeyID), new DerObjectIdentifier(encryptionOid),
+				new DerObjectIdentifier(digestOid), signedAttrGenerator, unsignedAttrGenerator);
 		}
 
 		private void DoAddSigner(
 			AsymmetricKeyParameter		privateKey,
 			SignerIdentifier			signerIdentifier,
-			string						encryptionOid,
-			string						digestOid,
+            DerObjectIdentifier encryptionOid,
+			DerObjectIdentifier digestOid,
 			CmsAttributeTableGenerator	signedAttrGenerator,
 			CmsAttributeTableGenerator	unsignedAttrGenerator)
 		{
 			ConfigureDigest(digestOid);
 
-			SignerInfoGeneratorImpl signerInf = new SignerInfoGeneratorImpl(this, privateKey,
+			SignerInfoGeneratorImpl signerInfoGen = new SignerInfoGeneratorImpl(this, privateKey,
 				signerIdentifier, digestOid, encryptionOid, signedAttrGenerator, unsignedAttrGenerator);
 
-			_signerInfs.Add(new DigestAndSignerInfoGeneratorHolder(signerInf, digestOid));
+			m_signerInfoGens.Add(signerInfoGen);
 		}
 
 		internal override void AddSignerCallback(
@@ -451,7 +423,7 @@ namespace Org.BouncyCastle.Cms
 			// NB: Would need to call FixAlgID on the DigestAlgorithmID
 
 			// For precalculated signers, just need to register the algorithm, not configure a digest
-            RegisterDigestOid(si.DigestAlgorithmID.Algorithm.Id);
+            RegisterDigestOid(si.DigestAlgorithmID.Algorithm);
 		}
 
 		/**
@@ -554,11 +526,12 @@ namespace Org.BouncyCastle.Cms
 
             sigGen.AddObject(CalculateVersion(contentTypeOid));
 
-			Asn1EncodableVector digestAlgs = new Asn1EncodableVector(_messageDigestOids.Count);
+			Asn1EncodableVector digestAlgs = new Asn1EncodableVector(m_messageDigestOids.Count);
 
-			foreach (string digestOid in _messageDigestOids)
+			foreach (var messageDigestOid in m_messageDigestOids)
             {
-				digestAlgs.Add(new AlgorithmIdentifier(new DerObjectIdentifier(digestOid), DerNull.Instance));
+                // TODO AlgorithmIdentifier noParams handling (configure an IDigestAlgorithmFinder)
+                digestAlgs.Add(new AlgorithmIdentifier(messageDigestOid, DerNull.Instance));
             }
 
             DerSet.FromVector(digestAlgs).EncodeTo(sigGen.GetRawOutputStream());
@@ -585,21 +558,19 @@ namespace Org.BouncyCastle.Cms
 			return new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen, octGen);
         }
 
-		private void RegisterDigestOid(
-			string digestOid)
-		{
-       		if (_messageDigestsLocked)
-       		{
-       			if (!_messageDigestOids.Contains(digestOid))
-					throw new InvalidOperationException("Cannot register new digest OIDs after the data stream is opened");
-       		}
-       		else
-       		{
-				_messageDigestOids.Add(digestOid);
-       		}
-		}
+        private void RegisterDigestOid(DerObjectIdentifier digestOid)
+        {
+            if (!_messageDigestsLocked)
+            {
+                m_messageDigestOids.Add(digestOid);
+            }
+            else if (!m_messageDigestOids.Contains(digestOid))
+            {
+                throw new InvalidOperationException("Cannot register new digest OIDs after the data stream is opened");
+            }
+        }
 
-		private void ConfigureDigest(string digestOid)
+        private void ConfigureDigest(DerObjectIdentifier digestOid)
 		{
        		RegisterDigestOid(digestOid);
 
@@ -859,17 +830,14 @@ namespace Org.BouncyCastle.Cms
                 //
                 // add the generated SignerInfo objects
                 //
+                foreach (SignerInfoGeneratorImpl signerInfoGen in outer.m_signerInfoGens)
                 {
-                    foreach (DigestAndSignerInfoGeneratorHolder holder in outer._signerInfs)
-                    {
-                        AlgorithmIdentifier digestAlgorithm = holder.DigestAlgorithm;
+					var digestOid = signerInfoGen.m_digestOid;
+                    string digestName = CmsSignedHelper.GetDigestAlgName(digestOid);
+                    byte[] calculatedDigest = outer.m_messageHashes[digestName];
+                    outer.m_digests[digestOid] = (byte[])calculatedDigest.Clone();
 
-                        byte[] calculatedDigest = outer.m_messageHashes[
-                            CmsSignedHelper.GetDigestAlgName(holder.digestOID)];
-                        outer.m_digests[holder.digestOID] = (byte[])calculatedDigest.Clone();
-
-                        signerInfos.Add(holder.signerInf.Generate(_contentOID, digestAlgorithm, calculatedDigest));
-                    }
+                    signerInfos.Add(signerInfoGen.Generate(_contentOID, calculatedDigest));
                 }
 
                 //