diff options
-rw-r--r-- | crypto/src/asn1/ASN1Generator.cs | 37 | ||||
-rw-r--r-- | crypto/src/asn1/BERGenerator.cs | 68 | ||||
-rw-r--r-- | crypto/src/asn1/BEROctetStringGenerator.cs | 56 | ||||
-rw-r--r-- | crypto/src/asn1/DERGenerator.cs | 88 | ||||
-rw-r--r-- | crypto/src/asn1/DERSequenceGenerator.cs | 20 | ||||
-rw-r--r-- | crypto/src/asn1/DERSetGenerator.cs | 20 | ||||
-rw-r--r-- | crypto/src/cms/CMSAuthenticatedDataStreamGenerator.cs | 47 | ||||
-rw-r--r-- | crypto/src/cms/CMSCompressedDataStreamGenerator.cs | 24 | ||||
-rw-r--r-- | crypto/src/cms/CMSEnvelopedDataStreamGenerator.cs | 39 | ||||
-rw-r--r-- | crypto/src/cms/CMSSignedDataStreamGenerator.cs | 35 | ||||
-rw-r--r-- | crypto/src/cms/CMSUtils.cs | 6 | ||||
-rw-r--r-- | crypto/test/src/asn1/test/ASN1SequenceParserTest.cs | 285 | ||||
-rw-r--r-- | crypto/test/src/asn1/test/OctetStringTest.cs | 168 |
13 files changed, 439 insertions, 454 deletions
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())); diff --git a/crypto/test/src/asn1/test/ASN1SequenceParserTest.cs b/crypto/test/src/asn1/test/ASN1SequenceParserTest.cs index 030da04cb..fd85a58fb 100644 --- a/crypto/test/src/asn1/test/ASN1SequenceParserTest.cs +++ b/crypto/test/src/asn1/test/ASN1SequenceParserTest.cs @@ -1,4 +1,3 @@ -using System; using System.IO; using NUnit.Framework; @@ -6,7 +5,6 @@ using NUnit.Framework; using Org.BouncyCastle.Math; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Encoders; -using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Asn1.Tests { @@ -30,13 +28,11 @@ namespace Org.BouncyCastle.Asn1.Tests public void TestDerWriting() { MemoryStream bOut = new MemoryStream(); - DerSequenceGenerator seqGen = new DerSequenceGenerator(bOut); - - seqGen.AddObject(new DerInteger(BigInteger.Zero)); - - seqGen.AddObject(new DerObjectIdentifier("1.1")); - - seqGen.Close(); + using (var seqGen = new DerSequenceGenerator(bOut)) + { + seqGen.AddObject(new DerInteger(BigInteger.Zero)); + seqGen.AddObject(new DerObjectIdentifier("1.1")); + } Assert.IsTrue(Arrays.AreEqual(seqData, bOut.ToArray()), "basic DER writing test failed."); } @@ -45,34 +41,29 @@ namespace Org.BouncyCastle.Asn1.Tests public void TestNestedDerWriting() { MemoryStream bOut = new MemoryStream(); - DerSequenceGenerator seqGen1 = new DerSequenceGenerator(bOut); - - seqGen1.AddObject(new DerInteger(BigInteger.Zero)); - - seqGen1.AddObject(new DerObjectIdentifier("1.1")); - - DerSequenceGenerator seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream()); - - seqGen2.AddObject(new DerInteger(BigInteger.One)); - - seqGen2.Close(); + using (var seqGen1 = new DerSequenceGenerator(bOut)) + { + seqGen1.AddObject(new DerInteger(BigInteger.Zero)); + seqGen1.AddObject(new DerObjectIdentifier("1.1")); - seqGen1.Close(); + using (var seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream())) + { + seqGen2.AddObject(new DerInteger(BigInteger.One)); + } + } - Assert.IsTrue(Arrays.AreEqual(nestedSeqData, bOut.ToArray()), "nested DER writing test failed."); + Assert.IsTrue(Arrays.AreEqual(nestedSeqData, bOut.ToArray()), "nested DER writing test failed."); } [Test] public void TestDerExplicitTaggedSequenceWriting() { MemoryStream bOut = new MemoryStream(); - DerSequenceGenerator seqGen = new DerSequenceGenerator(bOut, 1, true); - - seqGen.AddObject(new DerInteger(BigInteger.Zero)); - - seqGen.AddObject(new DerObjectIdentifier("1.1")); - - seqGen.Close(); + using (var seqGen = new DerSequenceGenerator(bOut, 1, true)) + { + seqGen.AddObject(new DerInteger(BigInteger.Zero)); + seqGen.AddObject(new DerObjectIdentifier("1.1")); + } Assert.IsTrue(Arrays.AreEqual(expTagSeqData, bOut.ToArray()), "explicit tag writing test failed."); } @@ -81,34 +72,29 @@ namespace Org.BouncyCastle.Asn1.Tests public void TestDerImplicitTaggedSequenceWriting() { MemoryStream bOut = new MemoryStream(); - DerSequenceGenerator seqGen = new DerSequenceGenerator(bOut, 1, false); - - seqGen.AddObject(new DerInteger(BigInteger.Zero)); - - seqGen.AddObject(new DerObjectIdentifier("1.1")); - - seqGen.Close(); + using (var seqGen = new DerSequenceGenerator(bOut, 1, false)) + { + seqGen.AddObject(new DerInteger(BigInteger.Zero)); + seqGen.AddObject(new DerObjectIdentifier("1.1")); + } - Assert.IsTrue(Arrays.AreEqual(implTagSeqData, bOut.ToArray()), "implicit tag writing test failed."); + Assert.IsTrue(Arrays.AreEqual(implTagSeqData, bOut.ToArray()), "implicit tag writing test failed."); } [Test] public void TestNestedExplicitTagDerWriting() { MemoryStream bOut = new MemoryStream(); - DerSequenceGenerator seqGen1 = new DerSequenceGenerator(bOut); - - seqGen1.AddObject(new DerInteger(BigInteger.Zero)); - - seqGen1.AddObject(new DerObjectIdentifier("1.1")); - - DerSequenceGenerator seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream(), 1, true); - - seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1))); - - seqGen2.Close(); + using (var seqGen1 = new DerSequenceGenerator(bOut)) + { + seqGen1.AddObject(new DerInteger(BigInteger.Zero)); + seqGen1.AddObject(new DerObjectIdentifier("1.1")); - seqGen1.Close(); + using (var seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream(), 1, true)) + { + seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1))); + } + } Assert.IsTrue(Arrays.AreEqual(nestedSeqExpTagData, bOut.ToArray()), "nested explicit tagged DER writing test failed."); } @@ -117,34 +103,29 @@ namespace Org.BouncyCastle.Asn1.Tests public void TestNestedImplicitTagDerWriting() { MemoryStream bOut = new MemoryStream(); - DerSequenceGenerator seqGen1 = new DerSequenceGenerator(bOut); - - seqGen1.AddObject(new DerInteger(BigInteger.Zero)); - - seqGen1.AddObject(new DerObjectIdentifier("1.1")); - - DerSequenceGenerator seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream(), 1, false); - - seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1))); - - seqGen2.Close(); + using (var seqGen1 = new DerSequenceGenerator(bOut)) + { + seqGen1.AddObject(new DerInteger(BigInteger.Zero)); + seqGen1.AddObject(new DerObjectIdentifier("1.1")); - seqGen1.Close(); + using (var seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream(), 1, false)) + { + seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1))); + } + } - Assert.IsTrue(Arrays.AreEqual(nestedSeqImpTagData, bOut.ToArray()), "nested implicit tagged DER writing test failed."); + Assert.IsTrue(Arrays.AreEqual(nestedSeqImpTagData, bOut.ToArray()), "nested implicit tagged DER writing test failed."); } [Test] public void TestBerWriting() { MemoryStream bOut = new MemoryStream(); - BerSequenceGenerator seqGen = new BerSequenceGenerator(bOut); - - seqGen.AddObject(new DerInteger(BigInteger.Zero)); - - seqGen.AddObject(new DerObjectIdentifier("1.1")); - - seqGen.Close(); + using (var seqGen = new BerSequenceGenerator(bOut)) + { + seqGen.AddObject(new DerInteger(BigInteger.Zero)); + seqGen.AddObject(new DerObjectIdentifier("1.1")); + } Assert.IsTrue(Arrays.AreEqual(berSeqData, bOut.ToArray()), "basic BER writing test failed."); } @@ -153,49 +134,42 @@ namespace Org.BouncyCastle.Asn1.Tests public void TestNestedBerDerWriting() { MemoryStream bOut = new MemoryStream(); - BerSequenceGenerator seqGen1 = new BerSequenceGenerator(bOut); - - seqGen1.AddObject(new DerInteger(BigInteger.Zero)); - - seqGen1.AddObject(new DerObjectIdentifier("1.1")); - - DerSequenceGenerator seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream()); - - seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1))); - - seqGen2.Close(); + using (var seqGen1 = new BerSequenceGenerator(bOut)) + { + seqGen1.AddObject(new DerInteger(BigInteger.Zero)); + seqGen1.AddObject(new DerObjectIdentifier("1.1")); - seqGen1.Close(); + using (var seqGen2 = new DerSequenceGenerator(seqGen1.GetRawOutputStream())) + { + seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1))); + } + } - Assert.IsTrue(Arrays.AreEqual(berDerNestedSeqData, bOut.ToArray()), "nested BER/DER writing test failed."); + Assert.IsTrue(Arrays.AreEqual(berDerNestedSeqData, bOut.ToArray()), "nested BER/DER writing test failed."); } [Test] public void TestNestedBerWriting() { MemoryStream bOut = new MemoryStream(); - BerSequenceGenerator seqGen1 = new BerSequenceGenerator(bOut); - - seqGen1.AddObject(new DerInteger(BigInteger.Zero)); - - seqGen1.AddObject(new DerObjectIdentifier("1.1")); - - BerSequenceGenerator seqGen2 = new BerSequenceGenerator(seqGen1.GetRawOutputStream()); - - seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1))); - - seqGen2.Close(); + using (var seqGen1 = new BerSequenceGenerator(bOut)) + { + seqGen1.AddObject(new DerInteger(BigInteger.Zero)); + seqGen1.AddObject(new DerObjectIdentifier("1.1")); - seqGen1.Close(); + using (var seqGen2 = new BerSequenceGenerator(seqGen1.GetRawOutputStream())) + { + seqGen2.AddObject(new DerInteger(BigInteger.ValueOf(1))); + } + } - Assert.IsTrue(Arrays.AreEqual(berNestedSeqData, bOut.ToArray()), "nested BER writing test failed."); + Assert.IsTrue(Arrays.AreEqual(berNestedSeqData, bOut.ToArray()), "nested BER writing test failed."); } [Test] public void TestDerReading() { Asn1StreamParser aIn = new Asn1StreamParser(seqData); - Asn1SequenceParser seq = (Asn1SequenceParser)aIn.ReadObject(); int count = 0; @@ -206,12 +180,12 @@ namespace Org.BouncyCastle.Asn1.Tests { switch (count) { - case 0: - Assert.IsTrue(o is DerInteger); - break; - case 1: - Assert.IsTrue(o is DerObjectIdentifier); - break; + case 0: + Assert.IsTrue(o is DerInteger); + break; + case 1: + Assert.IsTrue(o is DerObjectIdentifier); + break; } count++; } @@ -219,39 +193,38 @@ namespace Org.BouncyCastle.Asn1.Tests Assert.AreEqual(2, count, "wrong number of objects in sequence"); } - private void doTestNestedReading( + private void DoTestNestedReading( byte[] data) { Asn1StreamParser aIn = new Asn1StreamParser(data); - Asn1SequenceParser seq = (Asn1SequenceParser) aIn.ReadObject(); - object o = null; int count = 0; Assert.IsNotNull(seq, "null sequence returned"); - while ((o = seq.ReadObject()) != null) + object o; + while ((o = seq.ReadObject()) != null) { switch (count) { - case 0: - Assert.IsTrue(o is DerInteger); - break; - case 1: - Assert.IsTrue(o is DerObjectIdentifier); - break; - case 2: - Assert.IsTrue(o is Asn1SequenceParser); - - Asn1SequenceParser s = (Asn1SequenceParser)o; - - // NB: Must exhaust the nested parser - while (s.ReadObject() != null) - { - // Ignore - } - - break; + case 0: + Assert.IsTrue(o is DerInteger); + break; + case 1: + Assert.IsTrue(o is DerObjectIdentifier); + break; + case 2: + Assert.IsTrue(o is Asn1SequenceParser); + + Asn1SequenceParser s = (Asn1SequenceParser)o; + + // NB: Must exhaust the nested parser + while (s.ReadObject() != null) + { + // Ignore + } + + break; } count++; } @@ -262,30 +235,29 @@ namespace Org.BouncyCastle.Asn1.Tests [Test] public void TestNestedDerReading() { - doTestNestedReading(nestedSeqData); + DoTestNestedReading(nestedSeqData); } [Test] public void TestBerReading() { Asn1StreamParser aIn = new Asn1StreamParser(berSeqData); - Asn1SequenceParser seq = (Asn1SequenceParser) aIn.ReadObject(); - object o = null; int count = 0; Assert.IsNotNull(seq, "null sequence returned"); - while ((o = seq.ReadObject()) != null) + object o; + while ((o = seq.ReadObject()) != null) { switch (count) { - case 0: - Assert.IsTrue(o is DerInteger); - break; - case 1: - Assert.IsTrue(o is DerObjectIdentifier); - break; + case 0: + Assert.IsTrue(o is DerInteger); + break; + case 1: + Assert.IsTrue(o is DerObjectIdentifier); + break; } count++; } @@ -296,59 +268,56 @@ namespace Org.BouncyCastle.Asn1.Tests [Test] public void TestNestedBerDerReading() { - doTestNestedReading(berDerNestedSeqData); + DoTestNestedReading(berDerNestedSeqData); } [Test] public void TestNestedBerReading() { - doTestNestedReading(berNestedSeqData); + DoTestNestedReading(berNestedSeqData); } [Test] public void TestBerExplicitTaggedSequenceWriting() { MemoryStream bOut = new MemoryStream(); - BerSequenceGenerator seqGen = new BerSequenceGenerator(bOut, 1, true); - - seqGen.AddObject(new DerInteger(BigInteger.Zero)); - - seqGen.AddObject(new DerObjectIdentifier("1.1")); - - seqGen.Close(); + using (var seqGen = new BerSequenceGenerator(bOut, 1, true)) + { + seqGen.AddObject(new DerInteger(BigInteger.Zero)); + seqGen.AddObject(new DerObjectIdentifier("1.1")); + } - Assert.IsTrue(Arrays.AreEqual(berExpTagSeqData, bOut.ToArray()), "explicit BER tag writing test failed."); + Assert.IsTrue(Arrays.AreEqual(berExpTagSeqData, bOut.ToArray()), "explicit BER tag writing test failed."); } [Test] public void TestSequenceWithDerNullReading() { - doTestParseWithNull(berSeqWithDERNullData); + DoTestParseWithNull(berSeqWithDERNullData); } - private void doTestParseWithNull( - byte[] data) + private void DoTestParseWithNull(byte[] data) { Asn1StreamParser aIn = new Asn1StreamParser(data); Asn1SequenceParser seq = (Asn1SequenceParser) aIn.ReadObject(); - object o; int count = 0; Assert.IsNotNull(seq, "null sequence returned"); - while ((o = seq.ReadObject()) != null) + object o; + while ((o = seq.ReadObject()) != null) { switch (count) { - case 0: - Assert.IsTrue(o is Asn1Null); - break; - case 1: - Assert.IsTrue(o is DerInteger); - break; - case 2: - Assert.IsTrue(o is DerObjectIdentifier); - break; + case 0: + Assert.IsTrue(o is Asn1Null); + break; + case 1: + Assert.IsTrue(o is DerInteger); + break; + case 2: + Assert.IsTrue(o is DerObjectIdentifier); + break; } count++; } diff --git a/crypto/test/src/asn1/test/OctetStringTest.cs b/crypto/test/src/asn1/test/OctetStringTest.cs index 8bae1b057..959d16c32 100644 --- a/crypto/test/src/asn1/test/OctetStringTest.cs +++ b/crypto/test/src/asn1/test/OctetStringTest.cs @@ -14,16 +14,16 @@ namespace Org.BouncyCastle.Asn1.Tests public void TestReadingWriting() { MemoryStream bOut = new MemoryStream(); - BerOctetStringGenerator octGen = new BerOctetStringGenerator(bOut); + using (var octGen = new BerOctetStringGenerator(bOut)) + { + using (var outStream = octGen.GetOctetOutputStream()) + { + outStream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4); + outStream.Write(new byte[4], 0, 4); + } + } - Stream outStream = octGen.GetOctetOutputStream(); - - outStream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4); - outStream.Write(new byte[4], 0, 4); - - outStream.Close(); - - Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray()); + Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray()); BerOctetStringParser s = (BerOctetStringParser)aIn.ReadObject(); @@ -42,16 +42,16 @@ namespace Org.BouncyCastle.Asn1.Tests public void TestReadingWritingZeroInLength() { MemoryStream bOut = new MemoryStream(); - BerOctetStringGenerator octGen = new BerOctetStringGenerator(bOut); - - Stream outStream = octGen.GetOctetOutputStream(); + using (var octGen = new BerOctetStringGenerator(bOut)) + { + using (var outStream = octGen.GetOctetOutputStream()) + { + outStream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4); + outStream.Write(new byte[512], 0, 512); // forces a zero to appear in length + } + } - outStream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4); - outStream.Write(new byte[512], 0, 512); // forces a zero to appear in length - - outStream.Close(); - - Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray()); + Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray()); BerOctetStringParser s = (BerOctetStringParser)aIn.ReadObject(); @@ -70,29 +70,28 @@ namespace Org.BouncyCastle.Asn1.Tests public void TestReadingWritingNested() { MemoryStream bOut = new MemoryStream(); - BerSequenceGenerator sGen = new BerSequenceGenerator(bOut); - BerOctetStringGenerator octGen = new BerOctetStringGenerator(sGen.GetRawOutputStream()); - - Stream outStream = octGen.GetOctetOutputStream(); - - BerSequenceGenerator inSGen = new BerSequenceGenerator(outStream); - - BerOctetStringGenerator inOctGen = new BerOctetStringGenerator(inSGen.GetRawOutputStream()); - - Stream inOut = inOctGen.GetOctetOutputStream(); - - inOut.Write(new byte[] { 1, 2, 3, 4 }, 0, 4); - inOut.Write(new byte[10], 0, 10); - - inOut.Close(); - - inSGen.Close(); - - outStream.Close(); - - sGen.Close(); - - Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray()); + using (var sGen = new BerSequenceGenerator(bOut)) + { + using (var octGen = new BerOctetStringGenerator(sGen.GetRawOutputStream())) + { + using (var outStream = octGen.GetOctetOutputStream()) + { + using (var inSGen = new BerSequenceGenerator(outStream)) + { + using (var inOctGen = new BerOctetStringGenerator(inSGen.GetRawOutputStream())) + { + using (var inOut = inOctGen.GetOctetOutputStream()) + { + inOut.Write(new byte[] { 1, 2, 3, 4 }, 0, 4); + inOut.Write(new byte[10], 0, 10); + } + } + } + } + } + } + + Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray()); BerSequenceParser sq = (BerSequenceParser)aIn.ReadObject(); @@ -120,50 +119,49 @@ namespace Org.BouncyCastle.Asn1.Tests { MemoryStream bOut = new MemoryStream(); - BerSequenceGenerator sGen = new BerSequenceGenerator(bOut); - - sGen.AddObject(new DerObjectIdentifier(CmsObjectIdentifiers.CompressedData.Id)); - - BerSequenceGenerator cGen = new BerSequenceGenerator(sGen.GetRawOutputStream(), 0, true); - - cGen.AddObject(new DerInteger(0)); - - // - // AlgorithmIdentifier - // - DerSequenceGenerator algGen = new DerSequenceGenerator(cGen.GetRawOutputStream()); - - algGen.AddObject(new DerObjectIdentifier("1.2")); - - algGen.Close(); - - // - // Encapsulated ContentInfo - // - BerSequenceGenerator eiGen = new BerSequenceGenerator(cGen.GetRawOutputStream()); - - eiGen.AddObject(new DerObjectIdentifier("1.1")); - - BerOctetStringGenerator octGen = new BerOctetStringGenerator(eiGen.GetRawOutputStream(), 0, true); - - // - // output containing zeroes - // - Stream outStream = octGen.GetOctetOutputStream(); - - outStream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4); - outStream.Write(new byte[4], 0, 4); - outStream.Write(new byte[20], 0, 20); - - outStream.Close(); - eiGen.Close(); - cGen.Close(); - sGen.Close(); - - // - // reading back - // - Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray()); + using (var sGen = new BerSequenceGenerator(bOut)) + { + sGen.AddObject(new DerObjectIdentifier(CmsObjectIdentifiers.CompressedData.Id)); + + using (var cGen = new BerSequenceGenerator(sGen.GetRawOutputStream(), 0, true)) + { + cGen.AddObject(new DerInteger(0)); + + // + // AlgorithmIdentifier + // + using (var algGen = new DerSequenceGenerator(cGen.GetRawOutputStream())) + { + algGen.AddObject(new DerObjectIdentifier("1.2")); + } + + // + // Encapsulated ContentInfo + // + using (var eiGen = new BerSequenceGenerator(cGen.GetRawOutputStream())) + { + eiGen.AddObject(new DerObjectIdentifier("1.1")); + + using (var octGen = new BerOctetStringGenerator(eiGen.GetRawOutputStream(), 0, true)) + { + // + // output containing zeroes + // + using (var outStream = octGen.GetOctetOutputStream()) + { + outStream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4); + outStream.Write(new byte[4], 0, 4); + outStream.Write(new byte[20], 0, 20); + } + } + } + } + } + + // + // reading back + // + Asn1StreamParser aIn = new Asn1StreamParser(bOut.ToArray()); ContentInfoParser cp = new ContentInfoParser((Asn1SequenceParser)aIn.ReadObject()); |