1 files changed, 137 insertions, 0 deletions
diff --git a/Crypto/src/cms/KEKRecipientInfoGenerator.cs b/Crypto/src/cms/KEKRecipientInfoGenerator.cs
new file mode 100644
index 000000000..a9bedade6
--- /dev/null
+++ b/Crypto/src/cms/KEKRecipientInfoGenerator.cs
@@ -0,0 +1,137 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.Kisa;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Ntt;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+
+namespace Org.BouncyCastle.Cms
+{
+ internal class KekRecipientInfoGenerator : RecipientInfoGenerator
+ {
+ private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance;
+
+ private KeyParameter keyEncryptionKey;
+ // TODO Can get this from keyEncryptionKey?
+ private string keyEncryptionKeyOID;
+ private KekIdentifier kekIdentifier;
+
+ // Derived
+ private AlgorithmIdentifier keyEncryptionAlgorithm;
+
+ internal KekRecipientInfoGenerator()
+ {
+ }
+
+ internal KekIdentifier KekIdentifier
+ {
+ set { this.kekIdentifier = value; }
+ }
+
+ internal KeyParameter KeyEncryptionKey
+ {
+ set
+ {
+ this.keyEncryptionKey = value;
+ this.keyEncryptionAlgorithm = DetermineKeyEncAlg(keyEncryptionKeyOID, keyEncryptionKey);
+ }
+ }
+
+ internal string KeyEncryptionKeyOID
+ {
+ set { this.keyEncryptionKeyOID = value; }
+ }
+
+ public RecipientInfo Generate(KeyParameter contentEncryptionKey, SecureRandom random)
+ {
+ byte[] keyBytes = contentEncryptionKey.GetKey();
+
+ IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionAlgorithm.ObjectID.Id);
+ keyWrapper.Init(true, new ParametersWithRandom(keyEncryptionKey, random));
+ Asn1OctetString encryptedKey = new DerOctetString(
+ keyWrapper.Wrap(keyBytes, 0, keyBytes.Length));
+
+ return new RecipientInfo(new KekRecipientInfo(kekIdentifier, keyEncryptionAlgorithm, encryptedKey));
+ }
+
+ private static AlgorithmIdentifier DetermineKeyEncAlg(
+ string algorithm, KeyParameter key)
+ {
+ if (algorithm.StartsWith("DES"))
+ {
+ return new AlgorithmIdentifier(
+ PkcsObjectIdentifiers.IdAlgCms3DesWrap,
+ DerNull.Instance);
+ }
+ else if (algorithm.StartsWith("RC2"))
+ {
+ return new AlgorithmIdentifier(
+ PkcsObjectIdentifiers.IdAlgCmsRC2Wrap,
+ new DerInteger(58));
+ }
+ else if (algorithm.StartsWith("AES"))
+ {
+ int length = key.GetKey().Length * 8;
+ DerObjectIdentifier wrapOid;
+
+ if (length == 128)
+ {
+ wrapOid = NistObjectIdentifiers.IdAes128Wrap;
+ }
+ else if (length == 192)
+ {
+ wrapOid = NistObjectIdentifiers.IdAes192Wrap;
+ }
+ else if (length == 256)
+ {
+ wrapOid = NistObjectIdentifiers.IdAes256Wrap;
+ }
+ else
+ {
+ throw new ArgumentException("illegal keysize in AES");
+ }
+
+ return new AlgorithmIdentifier(wrapOid); // parameters absent
+ }
+ else if (algorithm.StartsWith("SEED"))
+ {
+ // parameters absent
+ return new AlgorithmIdentifier(KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap);
+ }
+ else if (algorithm.StartsWith("CAMELLIA"))
+ {
+ int length = key.GetKey().Length * 8;
+ DerObjectIdentifier wrapOid;
+
+ if (length == 128)
+ {
+ wrapOid = NttObjectIdentifiers.IdCamellia128Wrap;
+ }
+ else if (length == 192)
+ {
+ wrapOid = NttObjectIdentifiers.IdCamellia192Wrap;
+ }
+ else if (length == 256)
+ {
+ wrapOid = NttObjectIdentifiers.IdCamellia256Wrap;
+ }
+ else
+ {
+ throw new ArgumentException("illegal keysize in Camellia");
+ }
+
+ return new AlgorithmIdentifier(wrapOid); // parameters must be absent
+ }
+ else
+ {
+ throw new ArgumentException("unknown algorithm");
+ }
+ }
+ }
+}
|