diff -Nur bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
--- bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java	2019-12-25 16:41:28.246642457 +0800
+++ bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java	2019-12-25 16:42:45.727085573 +0800
@@ -139,7 +139,7 @@
     {
         boolean isConstructed = (tag & CONSTRUCTED) != 0;
 
-        DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length);
+        DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length, limit);
 
         if ((tag & APPLICATION) != 0)
         {
diff -Nur bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java
--- bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java	2019-12-25 16:41:28.246642457 +0800
+++ bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java	2019-12-25 16:43:14.097247799 +0800
@@ -168,7 +168,7 @@
         }
         else
         {
-            DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length);
+            DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit);
 
             if ((tag & BERTags.APPLICATION) != 0)
             {
diff -Nur bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java
--- bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java	2019-12-25 16:41:28.246642457 +0800
+++ bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/DefiniteLengthInputStream.java	2019-12-25 16:45:17.287952074 +0800
@@ -19,9 +19,10 @@
 
     DefiniteLengthInputStream(
         InputStream in,
-        int         length)
+        int         length,
+        int         limit)
     {
-        super(in, length);
+        super(in, limit, length);
 
         if (length < 0)
         {
@@ -97,6 +98,12 @@
             return EMPTY_BYTES;
         }
 
+        //make sure it's safe to do this!
+        if (_remaining >= this.getLimit())
+        {
+           throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + this.getLimit());
+        }
+
         byte[] bytes = new byte[_remaining];
         if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
         {
diff -Nur bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/IndefiniteLengthInputStream.java bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/IndefiniteLengthInputStream.java
--- bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/IndefiniteLengthInputStream.java	2019-12-25 16:41:28.246642457 +0800
+++ bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/IndefiniteLengthInputStream.java	2019-12-25 16:45:50.298140750 +0800
@@ -17,7 +17,7 @@
         int         limit)
         throws IOException
     {
-        super(in, limit);
+        super(in, limit, limit);
 
         _b1 = in.read();
         _b2 = in.read();
diff -Nur bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/LimitedInputStream.java bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/LimitedInputStream.java
--- bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/LimitedInputStream.java	2019-12-25 16:41:28.256642514 +0800
+++ bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/LimitedInputStream.java	2019-12-25 16:47:41.218774610 +0800
@@ -10,19 +10,27 @@
 {
     protected final InputStream _in;
     private int _limit;
+    private int _length;
 
     LimitedInputStream(
         InputStream in,
-        int         limit)
+        int         limit,
+        int         length)
     {
         this._in = in;
         this._limit = limit;
+        this._length = length;
+    }
+
+    int getLimit()
+    {
+       return _limit;
     }
 
     int getRemaining()
     {
         // TODO: maybe one day this can become more accurate
-        return _limit;
+        return _length;
     }
     
     protected void setParentEofDetect(boolean on)
diff -Nur bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/StreamUtil.java bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/StreamUtil.java
--- bc-java-r1rv61.org/core/src/main/java/org/bouncycastle/asn1/StreamUtil.java	2019-12-25 16:41:28.256642514 +0800
+++ bc-java-r1rv61/core/src/main/java/org/bouncycastle/asn1/StreamUtil.java	2019-12-25 16:48:49.509164763 +0800
@@ -11,7 +11,7 @@
     private static final long  MAX_MEMORY = Runtime.getRuntime().maxMemory();
 
     /**
-     * Find out possible longest length...
+     * Find out possible longest length, capped by available memory.
      *
      * @param in input stream of interest
      * @return length calculation or MAX_VALUE.
@@ -20,7 +20,7 @@
     {
         if (in instanceof LimitedInputStream)
         {
-            return ((LimitedInputStream)in).getRemaining();
+            return ((LimitedInputStream)in).getLimit();
         }
         else if (in instanceof ASN1InputStream)
         {
