summary refs log tree commit diff
path: root/Crypto/src/cms/KeyTransRecipientInfoGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/cms/KeyTransRecipientInfoGenerator.cs')
-rw-r--r--Crypto/src/cms/KeyTransRecipientInfoGenerator.cs87
1 files changed, 87 insertions, 0 deletions
diff --git a/Crypto/src/cms/KeyTransRecipientInfoGenerator.cs b/Crypto/src/cms/KeyTransRecipientInfoGenerator.cs
new file mode 100644
index 000000000..0992e6da6
--- /dev/null
+++ b/Crypto/src/cms/KeyTransRecipientInfoGenerator.cs
@@ -0,0 +1,87 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.X509;
+
+namespace Org.BouncyCastle.Cms
+{
+	internal class KeyTransRecipientInfoGenerator : RecipientInfoGenerator
+	{
+		private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance;
+
+		private TbsCertificateStructure	recipientTbsCert;
+		private AsymmetricKeyParameter	recipientPublicKey;
+		private Asn1OctetString			subjectKeyIdentifier;
+
+		// Derived fields
+		private SubjectPublicKeyInfo info;
+
+		internal KeyTransRecipientInfoGenerator()
+		{
+		}
+
+		internal X509Certificate RecipientCert
+		{
+			set
+			{
+				this.recipientTbsCert = CmsUtilities.GetTbsCertificateStructure(value);
+				this.recipientPublicKey = value.GetPublicKey();
+				this.info = recipientTbsCert.SubjectPublicKeyInfo;
+			}
+		}
+		
+		internal AsymmetricKeyParameter RecipientPublicKey
+		{
+			set
+			{
+				this.recipientPublicKey = value;
+
+				try
+				{
+					info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(
+						recipientPublicKey);
+				}
+				catch (IOException)
+				{
+					throw new ArgumentException("can't extract key algorithm from this key");
+				}
+			}
+		}
+		
+		internal Asn1OctetString SubjectKeyIdentifier
+		{
+			set { this.subjectKeyIdentifier = value; }
+		}
+
+		public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
+		{
+			byte[] keyBytes = contentEncryptionKey.GetKey();
+			AlgorithmIdentifier keyEncryptionAlgorithm = info.AlgorithmID;
+
+			IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionAlgorithm.ObjectID.Id);
+			keyWrapper.Init(true, new ParametersWithRandom(recipientPublicKey, random));
+			byte[] encryptedKeyBytes = keyWrapper.Wrap(keyBytes, 0, keyBytes.Length);
+
+			RecipientIdentifier recipId;
+			if (recipientTbsCert != null)
+			{
+				IssuerAndSerialNumber issuerAndSerial = new IssuerAndSerialNumber(
+					recipientTbsCert.Issuer, recipientTbsCert.SerialNumber.Value);
+				recipId = new RecipientIdentifier(issuerAndSerial);
+			}
+			else
+			{
+				recipId = new RecipientIdentifier(subjectKeyIdentifier);
+			}
+
+			return new RecipientInfo(new KeyTransRecipientInfo(recipId, keyEncryptionAlgorithm,
+				new DerOctetString(encryptedKeyBytes)));
+		}
+	}
+}