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) {