summary refs log tree commit diff
path: root/crypto/src/asn1/Asn1InputStream.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/asn1/Asn1InputStream.cs')
-rw-r--r--crypto/src/asn1/Asn1InputStream.cs43
1 files changed, 33 insertions, 10 deletions
diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs
index 33db1e6d7..e250fe500 100644
--- a/crypto/src/asn1/Asn1InputStream.cs
+++ b/crypto/src/asn1/Asn1InputStream.cs
@@ -19,6 +19,7 @@ namespace Org.BouncyCastle.Asn1
         : FilterStream
     {
         private readonly int limit;
+        private readonly bool m_leaveOpen;
 
         internal byte[][] tmpBuffers;
 
@@ -36,11 +37,6 @@ namespace Org.BouncyCastle.Asn1
             return int.MaxValue;
         }
 
-        public Asn1InputStream(Stream input)
-            : this(input, FindLimit(input))
-        {
-        }
-
         /**
          * Create an ASN1InputStream based on the input byte array. The length of DER objects in
          * the stream is automatically limited to the length of the input array.
@@ -52,6 +48,11 @@ namespace Org.BouncyCastle.Asn1
         {
         }
 
+        public Asn1InputStream(Stream input)
+            : this(input, FindLimit(input))
+        {
+        }
+
         /**
          * Create an ASN1InputStream where no DER object will be longer than limit.
          *
@@ -59,22 +60,41 @@ namespace Org.BouncyCastle.Asn1
          * @param limit maximum size of a DER encoded object.
          */
         public Asn1InputStream(Stream input, int limit)
-            : this(input, limit, new byte[16][])
+            : this(input, limit, false)
+        {
+        }
+
+        public Asn1InputStream(Stream input, int limit, bool leaveOpen)
+            : this(input, limit, leaveOpen, new byte[16][])
         {
         }
 
-        internal Asn1InputStream(Stream input, int limit, byte[][] tmpBuffers)
+        internal Asn1InputStream(Stream input, int limit, bool leaveOpen, byte[][] tmpBuffers)
             : base(input)
         {
+            if (!input.CanRead)
+                throw new ArgumentException("Expected stream to be readable", nameof(input));
+
             this.limit = limit;
+            m_leaveOpen = leaveOpen;
             this.tmpBuffers = tmpBuffers;
         }
 
         protected override void Dispose(bool disposing)
         {
-            tmpBuffers = null;
+            if (disposing)
+            {
+                tmpBuffers = null;
+            }
 
-            base.Dispose(disposing);
+            if (m_leaveOpen)
+            {
+                base.Detach(disposing);
+            }
+            else
+            {
+                base.Dispose(disposing);
+            }
         }
 
         /**
@@ -146,7 +166,10 @@ namespace Org.BouncyCastle.Asn1
             if (remaining < 1)
                 return new Asn1EncodableVector(0);
 
-            return new Asn1InputStream(defIn, remaining, tmpBuffers).ReadVector();
+            using (var sub = new Asn1InputStream(defIn, remaining, leaveOpen: true, tmpBuffers))
+            {
+                return sub.ReadVector();
+            }
         }
 
         internal virtual Asn1Sequence CreateDLSequence(DefiniteLengthInputStream defIn)