<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

CmsEnvelopedDataStreamGenerator

using Org.BouncyCastle.Asn1; 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.IO; using System; using System.Collections.Generic; using System.IO; namespace Org.BouncyCastle.Cms { public class CmsEnvelopedDataStreamGenerator : CmsEnvelopedGenerator { private class CmsEnvelopedDataOutputStream : BaseOutputStream { private readonly CmsEnvelopedGenerator _outer; private readonly CipherStream _out; private readonly BerSequenceGenerator _cGen; private readonly BerSequenceGenerator _envGen; private readonly BerSequenceGenerator _eiGen; private readonly BerOctetStringGenerator _octGen; public CmsEnvelopedDataOutputStream(CmsEnvelopedGenerator outer, CipherStream outStream, BerSequenceGenerator cGen, BerSequenceGenerator envGen, BerSequenceGenerator eiGen, BerOctetStringGenerator octGen) { _outer = outer; _out = outStream; _cGen = cGen; _envGen = envGen; _eiGen = eiGen; _octGen = octGen; } public override void Write(byte[] buffer, int offset, int count) { _out.Write(buffer, offset, count); } public override void Write(ReadOnlySpan<byte> buffer) { _out.Write(buffer); } public override void WriteByte(byte value) { _out.WriteByte(value); } protected override void Dispose(bool disposing) { if (disposing) { _out.Dispose(); _octGen.Dispose(); _eiGen.Dispose(); if (_outer.unprotectedAttributeGenerator != null) { Asn1Set obj = BerSet.FromCollection(_outer.unprotectedAttributeGenerator.GetAttributes(new Dictionary<CmsAttributeTableParameter, object>())); _envGen.AddObject(new DerTaggedObject(false, 1, obj)); } _envGen.Dispose(); _cGen.Dispose(); } base.Dispose(disposing); } } private object _originatorInfo; private object _unprotectedAttributes; private int _bufferSize; private bool _berEncodeRecipientSet; public CmsEnvelopedDataStreamGenerator() { } public CmsEnvelopedDataStreamGenerator(SecureRandom random) : base(random) { } public void SetBufferSize(int bufferSize) { _bufferSize = bufferSize; } public void SetBerEncodeRecipients(bool berEncodeRecipientSet) { _berEncodeRecipientSet = berEncodeRecipientSet; } private Stream Open(Stream outStream, string encryptionOid, CipherKeyGenerator keyGen) { byte[] array = keyGen.GenerateKey(); KeyParameter keyParameter = ParameterUtilities.CreateKeyParameter(encryptionOid, array); Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, array); ICipherParameters cipherParameters; AlgorithmIdentifier algorithmIdentifier = GetAlgorithmIdentifier(encryptionOid, keyParameter, asn1Params, out cipherParameters); Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(recipientInfoGenerators.Count); foreach (RecipientInfoGenerator recipientInfoGenerator in recipientInfoGenerators) { try { asn1EncodableVector.Add(recipientInfoGenerator.Generate(keyParameter, m_random)); } catch (InvalidKeyException innerException) { throw new CmsException("key inappropriate for algorithm.", innerException); } catch (GeneralSecurityException innerException2) { throw new CmsException("error making encrypted content.", innerException2); } } return Open(outStream, algorithmIdentifier, cipherParameters, asn1EncodableVector); } private Stream Open(Stream outStream, AlgorithmIdentifier encAlgID, ICipherParameters cipherParameters, Asn1EncodableVector recipientInfos) { try { BerSequenceGenerator berSequenceGenerator = new BerSequenceGenerator(outStream); berSequenceGenerator.AddObject(CmsObjectIdentifiers.EnvelopedData); BerSequenceGenerator berSequenceGenerator2 = new BerSequenceGenerator(berSequenceGenerator.GetRawOutputStream(), 0, true); DerInteger obj = (_originatorInfo != null || _unprotectedAttributes != null) ? DerInteger.Two : DerInteger.Zero; berSequenceGenerator2.AddObject(obj); Stream rawOutputStream = berSequenceGenerator2.GetRawOutputStream(); using (Asn1Generator asn1Generator = _berEncodeRecipientSet ? ((Asn1Generator)new BerSetGenerator(rawOutputStream)) : ((Asn1Generator)new DerSetGenerator(rawOutputStream))) { foreach (Asn1Encodable recipientInfo in recipientInfos) { asn1Generator.AddObject(recipientInfo); } } BerSequenceGenerator berSequenceGenerator3 = new BerSequenceGenerator(rawOutputStream); berSequenceGenerator3.AddObject(CmsObjectIdentifiers.Data); berSequenceGenerator3.AddObject(encAlgID); BerOctetStringGenerator berOctetStringGenerator = new BerOctetStringGenerator(berSequenceGenerator3.GetRawOutputStream(), 0, false); Stream octetOutputStream = berOctetStringGenerator.GetOctetOutputStream(_bufferSize); IBufferedCipher cipher = CipherUtilities.GetCipher(encAlgID.Algorithm); cipher.Init(true, new ParametersWithRandom(cipherParameters, m_random)); CipherStream outStream2 = new CipherStream(octetOutputStream, null, cipher); return new CmsEnvelopedDataOutputStream(this, outStream2, berSequenceGenerator, berSequenceGenerator2, berSequenceGenerator3, berOctetStringGenerator); } catch (SecurityUtilityException innerException) { throw new CmsException("couldn't create cipher.", innerException); } catch (InvalidKeyException innerException2) { throw new CmsException("key invalid in message.", innerException2); } catch (IOException innerException3) { throw new CmsException("exception decoding algorithm parameters.", innerException3); } } public Stream Open(Stream outStream, string encryptionOid) { CipherKeyGenerator keyGenerator = GeneratorUtilities.GetKeyGenerator(encryptionOid); keyGenerator.Init(new KeyGenerationParameters(m_random, keyGenerator.DefaultStrength)); return Open(outStream, encryptionOid, keyGenerator); } public Stream Open(Stream outStream, string encryptionOid, int keySize) { CipherKeyGenerator keyGenerator = GeneratorUtilities.GetKeyGenerator(encryptionOid); keyGenerator.Init(new KeyGenerationParameters(m_random, keySize)); return Open(outStream, encryptionOid, keyGenerator); } } }