summary refs log tree commit diff
path: root/crypto/src/asn1
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/asn1')
-rw-r--r--crypto/src/asn1/ASN1Generator.cs37
-rw-r--r--crypto/src/asn1/BERGenerator.cs68
-rw-r--r--crypto/src/asn1/BEROctetStringGenerator.cs56
-rw-r--r--crypto/src/asn1/DERGenerator.cs88
-rw-r--r--crypto/src/asn1/DERSequenceGenerator.cs20
-rw-r--r--crypto/src/asn1/DERSetGenerator.cs20
6 files changed, 146 insertions, 143 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());
-		}
 	}
 }