diff --git a/crypto/src/asn1/ASN1Generator.cs b/crypto/src/asn1/ASN1Generator.cs
index cd2d06e72..28fffc6ab 100644
--- a/crypto/src/asn1/ASN1Generator.cs
+++ b/crypto/src/asn1/ASN1Generator.cs
@@ -1,20 +1,23 @@
+using System;
using System.IO;
namespace Org.BouncyCastle.Asn1
{
public abstract class Asn1Generator
+ : IDisposable
{
- private Stream _out;
+ private Stream m_outStream;
- protected Asn1Generator(
- Stream outStream)
+ protected Asn1Generator(Stream outStream)
{
- _out = outStream;
+ m_outStream = outStream ?? throw new ArgumentNullException(nameof(outStream));
}
- protected Stream Out
+ protected abstract void Finish();
+
+ protected Stream OutStream
{
- get { return _out; }
+ get { return m_outStream ?? throw new InvalidOperationException(); }
}
public abstract void AddObject(Asn1Encodable obj);
@@ -23,6 +26,26 @@ namespace Org.BouncyCastle.Asn1
public abstract Stream GetRawOutputStream();
- public abstract void Close();
+ #region IDisposable
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (m_outStream != null)
+ {
+ Finish();
+ m_outStream = null;
+ }
+ }
+ }
+
+ #endregion
}
}
diff --git a/crypto/src/asn1/BERGenerator.cs b/crypto/src/asn1/BERGenerator.cs
index e43d9f80c..073c36a30 100644
--- a/crypto/src/asn1/BERGenerator.cs
+++ b/crypto/src/asn1/BERGenerator.cs
@@ -1,3 +1,4 @@
+using System;
using System.IO;
using Org.BouncyCastle.Utilities.IO;
@@ -7,20 +8,16 @@ namespace Org.BouncyCastle.Asn1
public abstract class BerGenerator
: Asn1Generator
{
- private bool _tagged = false;
- private bool _isExplicit;
- private int _tagNo;
+ private bool _tagged = false;
+ private bool _isExplicit;
+ private int _tagNo;
- protected BerGenerator(
- Stream outStream)
+ protected BerGenerator(Stream outStream)
: base(outStream)
{
}
- protected BerGenerator(
- Stream outStream,
- int tagNo,
- bool isExplicit)
+ protected BerGenerator(Stream outStream, int tagNo, bool isExplicit)
: base(outStream)
{
_tagged = true;
@@ -28,35 +25,33 @@ namespace Org.BouncyCastle.Asn1
_tagNo = tagNo;
}
- public override void AddObject(Asn1Encodable obj)
+ protected override void Finish()
+ {
+ WriteBerEnd();
+ }
+
+ public override void AddObject(Asn1Encodable obj)
{
- obj.EncodeTo(Out);
+ obj.EncodeTo(OutStream);
}
public override void AddObject(Asn1Object obj)
{
- obj.EncodeTo(Out);
+ obj.EncodeTo(OutStream);
}
public override Stream GetRawOutputStream()
{
- return Out;
+ return OutStream;
}
- public override void Close()
- {
- WriteBerEnd();
- }
-
- private void WriteHdr(
- int tag)
+ private void WriteHdr(int tag)
{
- Out.WriteByte((byte) tag);
- Out.WriteByte(0x80);
+ OutStream.WriteByte((byte)tag);
+ OutStream.WriteByte(0x80);
}
- protected void WriteBerHeader(
- int tag)
+ protected void WriteBerHeader(int tag)
{
if (_tagged)
{
@@ -85,22 +80,33 @@ namespace Org.BouncyCastle.Asn1
}
}
- protected void WriteBerBody(
- Stream contentStream)
+ protected void WriteBerBody(Stream contentStream)
{
- Streams.PipeAll(contentStream, Out);
+ Streams.PipeAll(contentStream, OutStream);
}
protected void WriteBerEnd()
{
- Out.WriteByte(0x00);
- Out.WriteByte(0x00);
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ Span<byte> data = stackalloc byte[4]{ 0x00, 0x00, 0x00, 0x00 };
+ if (_tagged && _isExplicit) // write extra end for tag header
+ {
+ OutStream.Write(data[..4]);
+ }
+ else
+ {
+ OutStream.Write(data[..2]);
+ }
+#else
+ OutStream.WriteByte(0x00);
+ OutStream.WriteByte(0x00);
if (_tagged && _isExplicit) // write extra end for tag header
{
- Out.WriteByte(0x00);
- Out.WriteByte(0x00);
+ OutStream.WriteByte(0x00);
+ OutStream.WriteByte(0x00);
}
+#endif
}
}
}
diff --git a/crypto/src/asn1/BEROctetStringGenerator.cs b/crypto/src/asn1/BEROctetStringGenerator.cs
index b07576e7d..5472802a2 100644
--- a/crypto/src/asn1/BEROctetStringGenerator.cs
+++ b/crypto/src/asn1/BEROctetStringGenerator.cs
@@ -8,38 +8,39 @@ namespace Org.BouncyCastle.Asn1
public class BerOctetStringGenerator
: BerGenerator
{
- public BerOctetStringGenerator(Stream outStream)
- : base(outStream)
- {
- WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString);
- }
+ public BerOctetStringGenerator(Stream outStream)
+ : base(outStream)
+ {
+ WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString);
+ }
- public BerOctetStringGenerator(
- Stream outStream,
- int tagNo,
- bool isExplicit)
- : base(outStream, tagNo, isExplicit)
- {
- WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString);
- }
+ public BerOctetStringGenerator(Stream outStream, int tagNo, bool isExplicit)
+ : base(outStream, tagNo, isExplicit)
+ {
+ WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString);
+ }
+ /// <remarks>The caller is responsible for disposing the returned <see cref="Stream"/> before disposing
+ /// this generator.</remarks>
public Stream GetOctetOutputStream()
{
return GetOctetOutputStream(new byte[1000]); // limit for CER encoding.
}
- public Stream GetOctetOutputStream(
- int bufSize)
+ /// <remarks>The caller is responsible for disposing the returned <see cref="Stream"/> before disposing
+ /// this generator.</remarks>
+ public Stream GetOctetOutputStream(int bufSize)
{
- return bufSize < 1
- ? GetOctetOutputStream()
- : GetOctetOutputStream(new byte[bufSize]);
- }
+ return bufSize < 1
+ ? GetOctetOutputStream()
+ : GetOctetOutputStream(new byte[bufSize]);
+ }
- public Stream GetOctetOutputStream(
- byte[] buf)
+ /// <remarks>The caller is responsible for disposing the returned <see cref="Stream"/> before disposing
+ /// this generator.</remarks>
+ public Stream GetOctetOutputStream(byte[] buf)
{
- return new BufferedBerOctetStream(this, buf);
+ return new BufferedBerOctetStream(GetRawOutputStream(), buf);
}
private class BufferedBerOctetStream
@@ -47,17 +48,13 @@ namespace Org.BouncyCastle.Asn1
{
private byte[] _buf;
private int _off;
- private readonly BerOctetStringGenerator _gen;
private readonly Asn1OutputStream _derOut;
- internal BufferedBerOctetStream(
- BerOctetStringGenerator gen,
- byte[] buf)
+ internal BufferedBerOctetStream(Stream outStream, byte[] buf)
{
- _gen = gen;
_buf = buf;
_off = 0;
- _derOut = Asn1OutputStream.Create(_gen.Out, Asn1Encodable.Der);
+ _derOut = Asn1OutputStream.Create(outStream, Asn1Encodable.Der);
}
public override void Write(byte[] buffer, int offset, int count)
@@ -145,11 +142,10 @@ namespace Org.BouncyCastle.Asn1
if (_off != 0)
{
DerOctetString.Encode(_derOut, _buf, 0, _off);
+ _off = 0;
}
_derOut.FlushInternal();
-
- _gen.WriteBerEnd();
}
base.Dispose(disposing);
}
diff --git a/crypto/src/asn1/DERGenerator.cs b/crypto/src/asn1/DERGenerator.cs
index 387a2c5f8..4bdc60972 100644
--- a/crypto/src/asn1/DERGenerator.cs
+++ b/crypto/src/asn1/DERGenerator.cs
@@ -11,16 +11,12 @@ namespace Org.BouncyCastle.Asn1
private bool _isExplicit;
private int _tagNo;
- protected DerGenerator(
- Stream outStream)
+ protected DerGenerator(Stream outStream)
: base(outStream)
{
}
- protected DerGenerator(
- Stream outStream,
- int tagNo,
- bool isExplicit)
+ protected DerGenerator(Stream outStream, int tagNo, bool isExplicit)
: base(outStream)
{
_tagged = true;
@@ -28,80 +24,70 @@ namespace Org.BouncyCastle.Asn1
_tagNo = tagNo;
}
- private static void WriteLength(
- Stream outStr,
- int length)
+ internal void WriteDerEncoded(int tag, byte[] bytes)
{
- if (length > 127)
+ if (_tagged)
{
- int size = 1;
- int val = length;
+ int tagNum = _tagNo | Asn1Tags.ContextSpecific;
- while ((val >>= 8) != 0)
+ if (_isExplicit)
{
- size++;
+ int newTag = _tagNo | Asn1Tags.Constructed | Asn1Tags.ContextSpecific;
+ MemoryStream bOut = new MemoryStream();
+ WriteDerEncoded(bOut, tag, bytes);
+ WriteDerEncoded(OutStream, newTag, bOut.ToArray());
}
-
- outStr.WriteByte((byte)(size | 0x80));
-
- for (int i = (size - 1) * 8; i >= 0; i -= 8)
+ else
{
- outStr.WriteByte((byte)(length >> i));
+ if ((tag & Asn1Tags.Constructed) != 0)
+ {
+ tagNum |= Asn1Tags.Constructed;
+ }
+
+ WriteDerEncoded(OutStream, tagNum, bytes);
}
}
else
{
- outStr.WriteByte((byte)length);
+ WriteDerEncoded(OutStream, tag, bytes);
}
}
- internal static void WriteDerEncoded(
- Stream outStream,
- int tag,
- byte[] bytes)
+ internal static void WriteDerEncoded(Stream outStream, int tag, byte[] bytes)
{
- outStream.WriteByte((byte) tag);
+ outStream.WriteByte((byte)tag);
WriteLength(outStream, bytes.Length);
outStream.Write(bytes, 0, bytes.Length);
}
- internal void WriteDerEncoded(
- int tag,
- byte[] bytes)
+ internal static void WriteDerEncoded(Stream outStream, int tag, Stream inStream)
{
- if (_tagged)
+ WriteDerEncoded(outStream, tag, Streams.ReadAll(inStream));
+ }
+
+ private static void WriteLength(Stream outStream, int length)
+ {
+ if (length > 127)
{
- int tagNum = _tagNo | Asn1Tags.ContextSpecific;
+ int size = 1;
+ int val = length;
- if (_isExplicit)
+ while ((val >>= 8) != 0)
{
- int newTag = _tagNo | Asn1Tags.Constructed | Asn1Tags.ContextSpecific;
- MemoryStream bOut = new MemoryStream();
- WriteDerEncoded(bOut, tag, bytes);
- WriteDerEncoded(Out, newTag, bOut.ToArray());
+ size++;
}
- else
- {
- if ((tag & Asn1Tags.Constructed) != 0)
- {
- tagNum |= Asn1Tags.Constructed;
- }
- WriteDerEncoded(Out, tagNum, bytes);
+ outStream.WriteByte((byte)(size | 0x80));
+
+ for (int i = (size - 1) * 8; i >= 0; i -= 8)
+ {
+ outStream.WriteByte((byte)(length >> i));
}
}
else
{
- WriteDerEncoded(Out, tag, bytes);
+ outStream.WriteByte((byte)length);
}
}
-
- internal static void WriteDerEncoded(
- Stream outStr,
- int tag,
- Stream inStr)
- {
- WriteDerEncoded(outStr, tag, Streams.ReadAll(inStr));
- }
}
}
diff --git a/crypto/src/asn1/DERSequenceGenerator.cs b/crypto/src/asn1/DERSequenceGenerator.cs
index 12c978508..be240a86c 100644
--- a/crypto/src/asn1/DERSequenceGenerator.cs
+++ b/crypto/src/asn1/DERSequenceGenerator.cs
@@ -7,21 +7,22 @@ namespace Org.BouncyCastle.Asn1
{
private readonly MemoryStream _bOut = new MemoryStream();
- public DerSequenceGenerator(
- Stream outStream)
+ public DerSequenceGenerator(Stream outStream)
: base(outStream)
{
}
- public DerSequenceGenerator(
- Stream outStream,
- int tagNo,
- bool isExplicit)
+ public DerSequenceGenerator(Stream outStream, int tagNo, bool isExplicit)
: base(outStream, tagNo, isExplicit)
{
}
- public override void AddObject(Asn1Encodable obj)
+ protected override void Finish()
+ {
+ WriteDerEncoded(Asn1Tags.Constructed | Asn1Tags.Sequence, _bOut.ToArray());
+ }
+
+ public override void AddObject(Asn1Encodable obj)
{
obj.EncodeTo(_bOut, Asn1Encodable.Der);
}
@@ -35,10 +36,5 @@ namespace Org.BouncyCastle.Asn1
{
return _bOut;
}
-
- public override void Close()
- {
- WriteDerEncoded(Asn1Tags.Constructed | Asn1Tags.Sequence, _bOut.ToArray());
- }
}
}
diff --git a/crypto/src/asn1/DERSetGenerator.cs b/crypto/src/asn1/DERSetGenerator.cs
index 677241798..642744951 100644
--- a/crypto/src/asn1/DERSetGenerator.cs
+++ b/crypto/src/asn1/DERSetGenerator.cs
@@ -7,21 +7,22 @@ namespace Org.BouncyCastle.Asn1
{
private readonly MemoryStream _bOut = new MemoryStream();
- public DerSetGenerator(
- Stream outStream)
+ public DerSetGenerator(Stream outStream)
: base(outStream)
{
}
- public DerSetGenerator(
- Stream outStream,
- int tagNo,
- bool isExplicit)
+ public DerSetGenerator(Stream outStream, int tagNo, bool isExplicit)
: base(outStream, tagNo, isExplicit)
{
}
- public override void AddObject(Asn1Encodable obj)
+ protected override void Finish()
+ {
+ WriteDerEncoded(Asn1Tags.Constructed | Asn1Tags.Set, _bOut.ToArray());
+ }
+
+ public override void AddObject(Asn1Encodable obj)
{
obj.EncodeTo(_bOut, Asn1Encodable.Der);
}
@@ -35,10 +36,5 @@ namespace Org.BouncyCastle.Asn1
{
return _bOut;
}
-
- public override void Close()
- {
- WriteDerEncoded(Asn1Tags.Constructed | Asn1Tags.Set, _bOut.ToArray());
- }
}
}
diff --git a/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs b/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs
index fd2c743bb..054a9c45e 100644
--- a/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs
+++ b/crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs
@@ -140,31 +140,30 @@ namespace Org.BouncyCastle.Cms
authGen.AddObject(new DerInteger(AuthenticatedData.CalculateVersion(null)));
Stream authRaw = authGen.GetRawOutputStream();
- Asn1Generator recipGen = _berEncodeRecipientSet
- ? (Asn1Generator) new BerSetGenerator(authRaw)
- : new DerSetGenerator(authRaw);
-
- foreach (Asn1Encodable ae in recipientInfos)
+ using (var recipGen = _berEncodeRecipientSet
+ ? (Asn1Generator)new BerSetGenerator(authRaw)
+ : new DerSetGenerator(authRaw))
{
- recipGen.AddObject(ae);
- }
-
- recipGen.Close();
+ foreach (Asn1Encodable ae in recipientInfos)
+ {
+ recipGen.AddObject(ae);
+ }
+ }
authGen.AddObject(macAlgId);
BerSequenceGenerator eiGen = new BerSequenceGenerator(authRaw);
eiGen.AddObject(CmsObjectIdentifiers.Data);
- Stream octetOutputStream = CmsUtilities.CreateBerOctetOutputStream(
- eiGen.GetRawOutputStream(), 0, true, _bufferSize);
+ BerOctetStringGenerator octGen = new BerOctetStringGenerator(eiGen.GetRawOutputStream(), 0, true);
+ Stream octetOutputStream = octGen.GetOctetOutputStream(_bufferSize);
IMac mac = MacUtilities.GetMac(macAlgId.Algorithm);
// TODO Confirm no ParametersWithRandom needed
mac.Init(cipherParameters);
Stream mOut = new TeeOutputStream(octetOutputStream, new MacSink(mac));
- return new CmsAuthenticatedDataOutputStream(mOut, mac, cGen, authGen, eiGen);
+ return new CmsAuthenticatedDataOutputStream(mOut, mac, cGen, authGen, eiGen, octGen);
}
catch (SecurityUtilityException e)
{
@@ -214,23 +213,26 @@ namespace Org.BouncyCastle.Cms
{
private readonly Stream macStream;
private readonly IMac mac;
- private readonly BerSequenceGenerator cGen;
+ private readonly BerSequenceGenerator cGen;
private readonly BerSequenceGenerator authGen;
private readonly BerSequenceGenerator eiGen;
+ private readonly BerOctetStringGenerator octGen;
- public CmsAuthenticatedDataOutputStream(
+ public CmsAuthenticatedDataOutputStream(
Stream macStream,
IMac mac,
- BerSequenceGenerator cGen,
+ BerSequenceGenerator cGen,
BerSequenceGenerator authGen,
- BerSequenceGenerator eiGen)
- {
+ BerSequenceGenerator eiGen,
+ BerOctetStringGenerator octGen)
+ {
this.macStream = macStream;
this.mac = mac;
this.cGen = cGen;
this.authGen = authGen;
this.eiGen = eiGen;
- }
+ this.octGen = octGen;
+ }
public override void Write(byte[] buffer, int offset, int count)
{
@@ -255,17 +257,18 @@ namespace Org.BouncyCastle.Cms
{
macStream.Dispose();
- // TODO Parent context(s) should really be be closed explicitly
+ // TODO Parent context(s) should really be be closed explicitly
- eiGen.Close();
+ octGen.Dispose();
+ eiGen.Dispose();
// [TODO] auth attributes go here
byte[] macOctets = MacUtilities.DoFinal(mac);
authGen.AddObject(new DerOctetString(macOctets));
// [TODO] unauth attributes go here
- authGen.Close();
- cGen.Close();
+ authGen.Dispose();
+ cGen.Dispose();
}
base.Dispose(disposing);
}
diff --git a/crypto/src/cms/CMSCompressedDataStreamGenerator.cs b/crypto/src/cms/CMSCompressedDataStreamGenerator.cs
index 64a978c6d..f992a8269 100644
--- a/crypto/src/cms/CMSCompressedDataStreamGenerator.cs
+++ b/crypto/src/cms/CMSCompressedDataStreamGenerator.cs
@@ -87,11 +87,11 @@ namespace Org.BouncyCastle.Cms
eiGen.AddObject(new DerObjectIdentifier(contentOid));
- Stream octetStream = CmsUtilities.CreateBerOctetOutputStream(
- eiGen.GetRawOutputStream(), 0, true, _bufferSize);
+ BerOctetStringGenerator octGen = new BerOctetStringGenerator(eiGen.GetRawOutputStream(), 0, true);
+ Stream octetStream = octGen.GetOctetOutputStream(_bufferSize);
- return new CmsCompressedOutputStream(
- Utilities.IO.Compression.ZLib.CompressOutput(octetStream, -1), sGen, cGen, eiGen);
+ return new CmsCompressedOutputStream(
+ Utilities.IO.Compression.ZLib.CompressOutput(octetStream, -1), sGen, cGen, eiGen, octGen);
}
private class CmsCompressedOutputStream
@@ -101,17 +101,20 @@ namespace Org.BouncyCastle.Cms
private BerSequenceGenerator _sGen;
private BerSequenceGenerator _cGen;
private BerSequenceGenerator _eiGen;
+ private BerOctetStringGenerator _octGen;
- internal CmsCompressedOutputStream(
+ internal CmsCompressedOutputStream(
Stream outStream,
BerSequenceGenerator sGen,
BerSequenceGenerator cGen,
- BerSequenceGenerator eiGen)
+ BerSequenceGenerator eiGen,
+ BerOctetStringGenerator octGen)
{
_out = outStream;
_sGen = sGen;
_cGen = cGen;
_eiGen = eiGen;
+ _octGen = octGen;
}
public override void Write(byte[] buffer, int offset, int count)
@@ -137,11 +140,12 @@ namespace Org.BouncyCastle.Cms
{
_out.Dispose();
- // TODO Parent context(s) should really be be closed explicitly
+ // TODO Parent context(s) should really be be closed explicitly
- _eiGen.Close();
- _cGen.Close();
- _sGen.Close();
+ _octGen.Dispose();
+ _eiGen.Dispose();
+ _cGen.Dispose();
+ _sGen.Dispose();
}
base.Dispose(disposing);
}
diff --git a/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs b/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs
index cfd3dde10..64d501a41 100644
--- a/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs
+++ b/crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs
@@ -142,29 +142,28 @@ namespace Org.BouncyCastle.Cms
envGen.AddObject(this.Version);
Stream envRaw = envGen.GetRawOutputStream();
- Asn1Generator recipGen = _berEncodeRecipientSet
- ? (Asn1Generator) new BerSetGenerator(envRaw)
- : new DerSetGenerator(envRaw);
-
- foreach (Asn1Encodable ae in recipientInfos)
+ using (var recipGen = _berEncodeRecipientSet
+ ? (Asn1Generator)new BerSetGenerator(envRaw)
+ : new DerSetGenerator(envRaw))
{
- recipGen.AddObject(ae);
- }
-
- recipGen.Close();
+ foreach (Asn1Encodable ae in recipientInfos)
+ {
+ recipGen.AddObject(ae);
+ }
+ }
BerSequenceGenerator eiGen = new BerSequenceGenerator(envRaw);
eiGen.AddObject(CmsObjectIdentifiers.Data);
eiGen.AddObject(encAlgID);
- Stream octetOutputStream = CmsUtilities.CreateBerOctetOutputStream(
- eiGen.GetRawOutputStream(), 0, false, _bufferSize);
+ BerOctetStringGenerator octGen = new BerOctetStringGenerator(eiGen.GetRawOutputStream(), 0, false);
+ Stream octetOutputStream = octGen.GetOctetOutputStream(_bufferSize);
IBufferedCipher cipher = CipherUtilities.GetCipher(encAlgID.Algorithm);
cipher.Init(true, new ParametersWithRandom(cipherParameters, m_random));
CipherStream cOut = new CipherStream(octetOutputStream, null, cipher);
- return new CmsEnvelopedDataOutputStream(this, cOut, cGen, envGen, eiGen);
+ return new CmsEnvelopedDataOutputStream(this, cOut, cGen, envGen, eiGen, octGen);
}
catch (SecurityUtilityException e)
{
@@ -220,19 +219,22 @@ namespace Org.BouncyCastle.Cms
private readonly BerSequenceGenerator _cGen;
private readonly BerSequenceGenerator _envGen;
private readonly BerSequenceGenerator _eiGen;
+ private readonly BerOctetStringGenerator _octGen;
- public CmsEnvelopedDataOutputStream(
+ public CmsEnvelopedDataOutputStream(
CmsEnvelopedGenerator outer,
CipherStream outStream,
BerSequenceGenerator cGen,
BerSequenceGenerator envGen,
- BerSequenceGenerator eiGen)
+ 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)
@@ -258,9 +260,10 @@ namespace Org.BouncyCastle.Cms
{
_out.Dispose();
- // TODO Parent context(s) should really be closed explicitly
+ // TODO Parent context(s) should really be closed explicitly
- _eiGen.Close();
+ _octGen.Dispose();
+ _eiGen.Dispose();
if (_outer.unprotectedAttributeGenerator != null)
{
@@ -272,8 +275,8 @@ namespace Org.BouncyCastle.Cms
_envGen.AddObject(new DerTaggedObject(false, 1, unprotectedAttrs));
}
- _envGen.Close();
- _cGen.Close();
+ _envGen.Dispose();
+ _cGen.Dispose();
}
base.Dispose(disposing);
}
diff --git a/crypto/src/cms/CMSSignedDataStreamGenerator.cs b/crypto/src/cms/CMSSignedDataStreamGenerator.cs
index a4e960ba6..33b661761 100644
--- a/crypto/src/cms/CMSSignedDataStreamGenerator.cs
+++ b/crypto/src/cms/CMSSignedDataStreamGenerator.cs
@@ -570,18 +570,23 @@ namespace Org.BouncyCastle.Cms
BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream());
eiGen.AddObject(contentTypeOid);
- // If encapsulating, add the data as an octet string in the sequence
- Stream encapStream = encapsulate
- ? CmsUtilities.CreateBerOctetOutputStream(eiGen.GetRawOutputStream(), 0, true, _bufferSize)
- : null;
+ BerOctetStringGenerator octGen = null;
+ Stream encapStream = null;
- // Also send the data to 'dataOutputStream' if necessary
- Stream teeStream = GetSafeTeeOutputStream(dataOutputStream, encapStream);
+ // If encapsulating, add the data as an octet string in the sequence
+ if (encapsulate)
+ {
+ octGen = new BerOctetStringGenerator(eiGen.GetRawOutputStream(), 0, true);
+ encapStream = octGen.GetOctetOutputStream(_bufferSize);
+ }
+
+ // Also send the data to 'dataOutputStream' if necessary
+ Stream teeStream = GetSafeTeeOutputStream(dataOutputStream, encapStream);
// Let all the digests see the data as it is written
Stream digStream = AttachDigestsToOutputStream(m_messageDigests.Values, teeStream);
- return new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen);
+ return new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen, octGen);
}
private void RegisterDigestOid(
@@ -761,14 +766,16 @@ namespace Org.BouncyCastle.Cms
private BerSequenceGenerator _sGen;
private BerSequenceGenerator _sigGen;
private BerSequenceGenerator _eiGen;
+ private BerOctetStringGenerator _octGen;
- public CmsSignedDataOutputStream(
+ public CmsSignedDataOutputStream(
CmsSignedDataStreamGenerator outer,
Stream outStream,
string contentOID,
BerSequenceGenerator sGen,
BerSequenceGenerator sigGen,
- BerSequenceGenerator eiGen)
+ BerSequenceGenerator eiGen,
+ BerOctetStringGenerator octGen)
{
this.outer = outer;
@@ -777,6 +784,7 @@ namespace Org.BouncyCastle.Cms
_sGen = sGen;
_sigGen = sigGen;
_eiGen = eiGen;
+ _octGen = octGen;
}
public override void Write(byte[] buffer, int offset, int count)
@@ -811,7 +819,10 @@ namespace Org.BouncyCastle.Cms
// TODO Parent context(s) should really be be closed explicitly
- _eiGen.Close();
+ // Only for encapsulation
+ _octGen?.Dispose();
+
+ _eiGen.Dispose();
outer.m_digests.Clear(); // clear the current preserved digest state
@@ -896,8 +907,8 @@ namespace Org.BouncyCastle.Cms
WriteToGenerator(_sigGen, new DerSet(signerInfos));
- _sigGen.Close();
- _sGen.Close();
+ _sigGen.Dispose();
+ _sGen.Dispose();
}
private static void WriteToGenerator(Asn1Generator ag, Asn1Encodable ae)
diff --git a/crypto/src/cms/CMSUtils.cs b/crypto/src/cms/CMSUtils.cs
index 1a1577c4e..99258c995 100644
--- a/crypto/src/cms/CMSUtils.cs
+++ b/crypto/src/cms/CMSUtils.cs
@@ -176,12 +176,6 @@ namespace Org.BouncyCastle.Cms
return new DerSet(v);
}
- internal static Stream CreateBerOctetOutputStream(Stream s, int tagNo, bool isExplicit, int bufferSize)
- {
- BerOctetStringGenerator octGen = new BerOctetStringGenerator(s, tagNo, isExplicit);
- return octGen.GetOctetOutputStream(bufferSize);
- }
-
internal static TbsCertificateStructure GetTbsCertificateStructure(X509Certificate cert)
{
return TbsCertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetTbsCertificate()));
|