diff options
Diffstat (limited to 'crypto/src/cms/KEKRecipientInfoGenerator.cs')
-rw-r--r-- | crypto/src/cms/KEKRecipientInfoGenerator.cs | 137 |
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"); + } + } + } +} |