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);
}
}
}