diff options
author | David Hook <dgh@bouncycastle.org> | 2019-01-18 12:37:12 +1100 |
---|---|---|
committer | David Hook <dgh@bouncycastle.org> | 2019-01-18 12:37:12 +1100 |
commit | 714e5ef11e2ea6f0aa6cdd0dcb9987d8a7faea54 (patch) | |
tree | 097500cf6c166f4c3abda5fa0b4eeaed228128f3 | |
parent | Missing file from last commit. (diff) | |
download | BouncyCastle.NET-ed25519-714e5ef11e2ea6f0aa6cdd0dcb9987d8a7faea54.tar.xz |
added use of IKeyWrapper for managing CMS KeyTransRecipient
-rw-r--r-- | crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs | 2 | ||||
-rw-r--r-- | crypto/src/cms/EnvelopedDataHelper.cs | 6 | ||||
-rw-r--r-- | crypto/src/cms/KeyTransRecipientInfoGenerator.cs | 174 | ||||
-rw-r--r-- | crypto/src/crmf/EncryptedValueBuilder.cs | 1 | ||||
-rw-r--r-- | crypto/src/crypto/operators/Asn1CipherBuilder.cs | 100 | ||||
-rw-r--r-- | crypto/src/crypto/operators/Asn1KeyWrapper.cs | 48 | ||||
-rw-r--r-- | crypto/src/crypto/operators/CmsContentEncryptorBuilder.cs | 101 | ||||
-rw-r--r-- | crypto/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs | 36 | ||||
-rw-r--r-- | crypto/src/crypto/util/AlgorithmIdentifierFactory.cs | 2 | ||||
-rw-r--r-- | crypto/src/crypto/util/CipherFactory.cs (renamed from crypto/src/crypto/operators/CipherFactory.cs) | 11 | ||||
-rw-r--r-- | crypto/src/crypto/util/CipherKeyGeneratorFactory.cs | 10 |
11 files changed, 311 insertions, 180 deletions
diff --git a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs index 615091f7c..a991585f6 100644 --- a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs +++ b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs @@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Asn1.Pkcs public static readonly DerObjectIdentifier DesEde3Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".7"); public static readonly DerObjectIdentifier RC2Cbc = new DerObjectIdentifier(EncryptionAlgorithm + ".2"); - public static readonly DerObjectIdentifier Rc4 = new DerObjectIdentifier(EncryptionAlgorithm + ".4"); + public static readonly DerObjectIdentifier rc4 = new DerObjectIdentifier(EncryptionAlgorithm + ".4"); // // object identifiers for digests diff --git a/crypto/src/cms/EnvelopedDataHelper.cs b/crypto/src/cms/EnvelopedDataHelper.cs index 89ec79691..fe5bc2a97 100644 --- a/crypto/src/cms/EnvelopedDataHelper.cs +++ b/crypto/src/cms/EnvelopedDataHelper.cs @@ -12,10 +12,11 @@ using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Crypto.Utilites; namespace Org.BouncyCastle.Cms { - public class EnvelopedDataHelper + internal class EnvelopedDataHelper { private static readonly IDictionary BaseCipherNames = Platform.CreateHashtable(); private static readonly IDictionary MacAlgNames = Platform.CreateHashtable(); @@ -90,7 +91,6 @@ namespace Org.BouncyCastle.Cms public AlgorithmIdentifier GenerateEncryptionAlgID(DerObjectIdentifier encryptionOID, KeyParameter encKey, SecureRandom random) - { return AlgorithmIdentifierFactory.GenerateEncryptionAlgID(encryptionOID, encKey.GetKey().Length * 8, random); } @@ -120,4 +120,4 @@ namespace Org.BouncyCastle.Cms return creator.Invoke(); } } -} \ No newline at end of file +} diff --git a/crypto/src/cms/KeyTransRecipientInfoGenerator.cs b/crypto/src/cms/KeyTransRecipientInfoGenerator.cs index a1d8fbfa8..b18d18153 100644 --- a/crypto/src/cms/KeyTransRecipientInfoGenerator.cs +++ b/crypto/src/cms/KeyTransRecipientInfoGenerator.cs @@ -11,77 +11,109 @@ 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; + public class KeyTransRecipientInfoGenerator : RecipientInfoGenerator + { + private static readonly CmsEnvelopedHelper Helper = CmsEnvelopedHelper.Instance; + + private TbsCertificateStructure recipientTbsCert; + private AsymmetricKeyParameter recipientPublicKey; + private Asn1OctetString subjectKeyIdentifier; + + // Derived fields + private SubjectPublicKeyInfo info; + private IssuerAndSerialNumber issuerAndSerialNumber; + private SecureRandom random; + + internal KeyTransRecipientInfoGenerator() + { + } + + protected KeyTransRecipientInfoGenerator(IssuerAndSerialNumber issuerAndSerialNumber) + { + this.issuerAndSerialNumber = issuerAndSerialNumber; + } + + protected KeyTransRecipientInfoGenerator(byte[] subjectKeyIdentifier) + { + this.subjectKeyIdentifier = new DerOctetString(subjectKeyIdentifier); + } + + 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 = this.AlgorithmDetails; + + this.random = random; + + IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionAlgorithm.Algorithm.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))); + } + + protected virtual AlgorithmIdentifier AlgorithmDetails + { + get + { + return info.AlgorithmID; + } + } + + protected virtual byte[] GenerateWrappedKey(KeyParameter contentEncryptionKey) + { + byte[] keyBytes = contentEncryptionKey.GetKey(); + AlgorithmIdentifier keyEncryptionAlgorithm = info.AlgorithmID; IWrapper keyWrapper = Helper.CreateWrapper(keyEncryptionAlgorithm.Algorithm.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))); - } - } + keyWrapper.Init(true, new ParametersWithRandom(recipientPublicKey, random)); + return keyWrapper.Wrap(keyBytes, 0, keyBytes.Length); + } + } } diff --git a/crypto/src/crmf/EncryptedValueBuilder.cs b/crypto/src/crmf/EncryptedValueBuilder.cs index 28d5b52b4..b8076c0e9 100644 --- a/crypto/src/crmf/EncryptedValueBuilder.cs +++ b/crypto/src/crmf/EncryptedValueBuilder.cs @@ -110,6 +110,7 @@ namespace Org.BouncyCastle.Crmf { throw new CrmfException("cannot wrap key: " + e.Message, e); } + } private EncryptedValue encryptData(byte[] data) diff --git a/crypto/src/crypto/operators/Asn1CipherBuilder.cs b/crypto/src/crypto/operators/Asn1CipherBuilder.cs new file mode 100644 index 000000000..adb4507a3 --- /dev/null +++ b/crypto/src/crypto/operators/Asn1CipherBuilder.cs @@ -0,0 +1,100 @@ +using System.Collections; +using System.IO; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto.IO; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Crypto.Utilities; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public class Asn1CipherBuilderWithKey:ICipherBuilderWithKey + { + + private readonly KeyParameter encKey; + private AlgorithmIdentifier algorithmIdentifier; + + + public Asn1CipherBuilderWithKey(DerObjectIdentifier encryptionOID, int keySize, SecureRandom random) + { + if (random == null) + { + random= new SecureRandom(); + } + CipherKeyGenerator keyGen = CipherKeyGeneratorFactory.CreateKeyGenerator(encryptionOID, random); + + encKey = new KeyParameter(keyGen.GenerateKey()); + algorithmIdentifier = AlgorithmIdentifierFactory.GenerateEncryptionAlgID(encryptionOID, encKey.GetKey().Length * 8, random); + } + + + public object AlgorithmDetails + { + get { return algorithmIdentifier; } + } + public int GetMaxOutputSize(int inputLen) + { + throw new System.NotImplementedException(); + } + + public ICipher BuildCipher(Stream stream) + { + + object cipher = EnvelopedDataHelper.CreateContentCipher(true, encKey, algorithmIdentifier); + + // + // BufferedBlockCipher + // IStreamCipher + // + + if (cipher is IStreamCipher) + { + cipher = new BufferedStreamCipher((IStreamCipher)cipher); + } + + if (stream == null) + { + stream = new MemoryStream(); + } + + return new BufferedCipherWrapper((IBufferedCipher)cipher,stream); + } + + public ICipherParameters Key + { + get { return encKey; } + } + } + + public class BufferedCipherWrapper : ICipher + { + private readonly IBufferedCipher bufferedCipher; + private readonly CipherStream stream; + + public BufferedCipherWrapper(IBufferedCipher bufferedCipher, Stream source) + { + this.bufferedCipher = bufferedCipher; + stream = new CipherStream(source, bufferedCipher, bufferedCipher); + } + + public int GetMaxOutputSize(int inputLen) + { + return bufferedCipher.GetOutputSize(inputLen); + } + + public int GetUpdateOutputSize(int inputLen) + { + return bufferedCipher.GetUpdateOutputSize(inputLen); + } + + public Stream Stream + { + get { return stream; } + } + } +} diff --git a/crypto/src/crypto/operators/Asn1KeyWrapper.cs b/crypto/src/crypto/operators/Asn1KeyWrapper.cs new file mode 100644 index 000000000..8cd5cf8fe --- /dev/null +++ b/crypto/src/crypto/operators/Asn1KeyWrapper.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public class Asn1KeyWrapper : IKeyWrapper + { + private X509Certificate cert; + private string algorithm; + + public Asn1KeyWrapper(string algorithm, X509Certificate cert) + { + this.algorithm = algorithm; + this.cert = cert; + } + + public object AlgorithmDetails + { + get + { + throw new NotImplementedException(); + } + } + + public IBlockResult Wrap(byte[] keyData) + { + throw new NotImplementedException(); + } + } + + public class Asn1KeyUnwrapper: IKeyUnwrapper + { + public object AlgorithmDetails + { + get + { + throw new NotImplementedException(); + } + } + + public IBlockResult Unwrap(byte[] cipherText, int offset, int length) + { + throw new NotImplementedException(); + } + } +} diff --git a/crypto/src/crypto/operators/CmsContentEncryptorBuilder.cs b/crypto/src/crypto/operators/CmsContentEncryptorBuilder.cs index f7ddf4db6..da9e32f9e 100644 --- a/crypto/src/crypto/operators/CmsContentEncryptorBuilder.cs +++ b/crypto/src/crypto/operators/CmsContentEncryptorBuilder.cs @@ -9,8 +9,10 @@ using Org.BouncyCastle.Crypto.IO; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; -namespace Org.BouncyCastle.Crypto.Operators +namespace Org.BouncyCastle.Operators { public class CmsContentEncryptorBuilder { @@ -55,101 +57,8 @@ namespace Org.BouncyCastle.Crypto.Operators } public ICipherBuilderWithKey Build() - { - return new DefaultCipherBuilderWithKey(encryptionOID,keySize,random,new EnvelopedDataHelper()); - } - - } - - public class DefaultCipherBuilderWithKey:ICipherBuilderWithKey - { - - private readonly KeyParameter encKey; - private AlgorithmIdentifier algorithmIdentifier; - - - - - public DefaultCipherBuilderWithKey(DerObjectIdentifier encryptionOID, int keySize, SecureRandom random,EnvelopedDataHelper helper) - { - if (random == null) - { - random= new SecureRandom(); - } - - CipherKeyGenerator keyGen = helper.CreateKeyGenerator(encryptionOID, random); - encKey = new KeyParameter(keyGen.GenerateKey()); - algorithmIdentifier = helper.GenerateEncryptionAlgID(encryptionOID, encKey, random); - // cipher = EnvelopedDataHelper.CreateContentCipher(true, encKey, algorithmIdentifier); - } - - - public object AlgorithmDetails - { - get { return algorithmIdentifier; } - } - public int GetMaxOutputSize(int inputLen) - { - throw new System.NotImplementedException(); - } - - public ICipher BuildCipher(Stream stream) - { - - object cipher = EnvelopedDataHelper.CreateContentCipher(true, encKey, algorithmIdentifier); - - // - // BufferedBlockCipher - // IStreamCipher - // - - if (cipher is IStreamCipher) - { - cipher = new BufferedStreamCipher((IStreamCipher)cipher); - } - - if (stream == null) - { - stream = new MemoryStream(); - } - - return new BufferedCipherWrapper((IBufferedCipher)cipher,stream); - } - - public ICipherParameters Key { - get { return encKey; } + return new Asn1CipherBuilderWithKey(encryptionOID,keySize,random); } } - - public class BufferedCipherWrapper : ICipher - { - private readonly IBufferedCipher bufferedCipher; - private readonly CipherStream stream; - - public BufferedCipherWrapper(IBufferedCipher bufferedCipher, Stream source) - { - this.bufferedCipher = bufferedCipher; - stream = new CipherStream(source, bufferedCipher, bufferedCipher); - } - - public int GetMaxOutputSize(int inputLen) - { - return bufferedCipher.GetOutputSize(inputLen); - } - - public int GetUpdateOutputSize(int inputLen) - { - return bufferedCipher.GetUpdateOutputSize(inputLen); - } - - public Stream Stream - { - get { return stream; } - } - } - - - - -} \ No newline at end of file +} diff --git a/crypto/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs b/crypto/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs new file mode 100644 index 000000000..048014f22 --- /dev/null +++ b/crypto/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs @@ -0,0 +1,36 @@ +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Cms; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.X509; + +namespace Org.BouncyCastle.Operators +{ + public class CmsKeyTransRecipientInfoGenerator: KeyTransRecipientInfoGenerator + { + private IKeyWrapper keyWrapper; + + public CmsKeyTransRecipientInfoGenerator(X509Certificate recipCert, IKeyWrapper keyWrapper): base(new Asn1.Cms.IssuerAndSerialNumber(recipCert.IssuerDN, new DerInteger(recipCert.SerialNumber))) + { + this.keyWrapper = keyWrapper; + } + + public CmsKeyTransRecipientInfoGenerator(byte[] subjectKeyID, IKeyWrapper keyWrapper) : base(subjectKeyID) + { + this.keyWrapper = keyWrapper; + } + + protected override AlgorithmIdentifier AlgorithmDetails + { + get + { + return (AlgorithmIdentifier)keyWrapper.AlgorithmDetails; + } + } + + protected override byte[] GenerateWrappedKey(Crypto.Parameters.KeyParameter contentKey) + { + return keyWrapper.Wrap(contentKey.GetKey()).Collect(); + } + } +} diff --git a/crypto/src/crypto/util/AlgorithmIdentifierFactory.cs b/crypto/src/crypto/util/AlgorithmIdentifierFactory.cs index 73458f0ea..20eac84ce 100644 --- a/crypto/src/crypto/util/AlgorithmIdentifierFactory.cs +++ b/crypto/src/crypto/util/AlgorithmIdentifierFactory.cs @@ -82,7 +82,7 @@ namespace Org.BouncyCastle.Crypto.Utilities return new AlgorithmIdentifier(encryptionOID, cbcParams); } - else if (encryptionOID.Equals(PkcsObjectIdentifiers.Rc4)) + else if (encryptionOID.Equals(PkcsObjectIdentifiers.rc4)) { return new AlgorithmIdentifier(encryptionOID, DerNull.Instance); } diff --git a/crypto/src/crypto/operators/CipherFactory.cs b/crypto/src/crypto/util/CipherFactory.cs index 11a9faef9..0a4010b42 100644 --- a/crypto/src/crypto/operators/CipherFactory.cs +++ b/crypto/src/crypto/util/CipherFactory.cs @@ -13,10 +13,15 @@ using Org.BouncyCastle.Crypto.Paddings; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; -namespace Org.BouncyCastle.Crypto.Operators +namespace Org.BouncyCastle.Crypto.Utilites { public class CipherFactory { + private CipherFactory() + { + + } + private static readonly short[] rc2Ekb = { 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, @@ -42,7 +47,7 @@ namespace Org.BouncyCastle.Crypto.Operators { DerObjectIdentifier encAlg = encryptionAlgID.Algorithm; - if (encAlg.Equals(PkcsObjectIdentifiers.Rc4)) + if (encAlg.Equals(PkcsObjectIdentifiers.rc4)) { IStreamCipher cipher = new RC4Engine(); @@ -143,4 +148,4 @@ namespace Org.BouncyCastle.Crypto.Operators } } -} \ No newline at end of file +} diff --git a/crypto/src/crypto/util/CipherKeyGeneratorFactory.cs b/crypto/src/crypto/util/CipherKeyGeneratorFactory.cs index 7a24a01a8..f714c40fd 100644 --- a/crypto/src/crypto/util/CipherKeyGeneratorFactory.cs +++ b/crypto/src/crypto/util/CipherKeyGeneratorFactory.cs @@ -12,6 +12,10 @@ namespace Org.BouncyCastle.Crypto.Utilities { public class CipherKeyGeneratorFactory { + private CipherKeyGeneratorFactory() + { + + } /** * Create a key generator for the passed in Object Identifier. @@ -22,7 +26,6 @@ namespace Org.BouncyCastle.Crypto.Utilities * @throws IllegalArgumentException if the algorithm cannot be identified. */ public static CipherKeyGenerator CreateKeyGenerator(DerObjectIdentifier algorithm, SecureRandom random) - { if (NistObjectIdentifiers.IdAes128Cbc.Equals(algorithm)) { @@ -72,7 +75,7 @@ namespace Org.BouncyCastle.Crypto.Utilities return keyGen; } - else if (PkcsObjectIdentifiers.Rc4.Equals(algorithm)) + else if (PkcsObjectIdentifiers.rc4.Equals(algorithm)) { return createCipherKeyGenerator(random, 128); } @@ -86,9 +89,6 @@ namespace Org.BouncyCastle.Crypto.Utilities } } - - - private static CipherKeyGenerator createCipherKeyGenerator(SecureRandom random, int keySize) { CipherKeyGenerator keyGen = new CipherKeyGenerator(); |