--- old/src/java.base/share/classes/sun/security/util/DerValue.java Wed Mar 15 19:20:52 2017 +++ new/src/java.base/share/classes/sun/security/util/DerValue.java Wed Mar 15 19:20:52 2017 @@ -1,5 +1,5 @@ -/* - * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. +/** + * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -225,6 +225,16 @@ data = init(stringTag, value); } + // Creates a DerValue from a tag and some DER-encoded data w/ additional + // arg to control whether DER checks are enforced. + DerValue(byte tag, byte[] data, boolean allowBER) { + this.tag = tag; + buffer = new DerInputBuffer(data.clone(), allowBER); + length = data.length; + this.data = new DerInputStream(buffer); + this.data.mark(Integer.MAX_VALUE); + } + /** * Creates a DerValue from a tag and some DER-encoded data. * @@ -232,11 +242,7 @@ * @param data the DER-encoded data */ public DerValue(byte tag, byte[] data) { - this.tag = tag; - buffer = new DerInputBuffer(data.clone()); - length = data.length; - this.data = new DerInputStream(buffer); - this.data.mark(Integer.MAX_VALUE); + this(tag, data, true); } /* @@ -243,9 +249,9 @@ * package private */ DerValue(DerInputBuffer in) throws IOException { + // XXX must also parse BER-encoded constructed // values such as sequences, sets... - tag = (byte)in.read(); byte lenByte = (byte)in.read(); length = DerInputStream.getLength(lenByte, in); @@ -260,7 +266,7 @@ dis.readFully(indefData, offset, readLen); dis.close(); DerIndefLenConverter derIn = new DerIndefLenConverter(); - inbuf = new DerInputBuffer(derIn.convert(indefData)); + inbuf = new DerInputBuffer(derIn.convert(indefData), in.allowBER); if (tag != inbuf.read()) throw new IOException ("Indefinite length encoding not supported"); @@ -282,6 +288,12 @@ } } + // Get an ASN.1/DER encoded datum from a buffer w/ additional + // arg to control whether DER checks are enforced. + DerValue(byte[] buf, boolean allowBER) throws IOException { + data = init(true, new ByteArrayInputStream(buf), allowBER); + } + /** * Get an ASN.1/DER encoded datum from a buffer. The * entire buffer must hold exactly one datum, including @@ -290,9 +302,16 @@ * @param buf buffer holding a single DER-encoded datum. */ public DerValue(byte[] buf) throws IOException { - data = init(true, new ByteArrayInputStream(buf)); + this(buf, true); } + // Get an ASN.1/DER encoded datum from part of a buffer w/ additional + // arg to control whether DER checks are enforced. + DerValue(byte[] buf, int offset, int len, boolean allowBER) + throws IOException { + data = init(true, new ByteArrayInputStream(buf, offset, len), allowBER); + } + /** * Get an ASN.1/DER encoded datum from part of a buffer. * That part of the buffer must hold exactly one datum, including @@ -303,9 +322,15 @@ * @param len how many bytes are in the encoded datum */ public DerValue(byte[] buf, int offset, int len) throws IOException { - data = init(true, new ByteArrayInputStream(buf, offset, len)); + this(buf, offset, len, true); } + // Get an ASN1/DER encoded datum from an input stream w/ additional + // arg to control whether DER checks are enforced. + DerValue(InputStream in, boolean allowBER) throws IOException { + data = init(false, in, allowBER); + } + /** * Get an ASN1/DER encoded datum from an input stream. The * stream may have additional data following the encoded datum. @@ -316,10 +341,11 @@ * which may be followed by additional data */ public DerValue(InputStream in) throws IOException { - data = init(false, in); + this(in, true); } - private DerInputStream init(byte stringTag, String value) throws IOException { + private DerInputStream init(byte stringTag, String value) + throws IOException { String enc = null; tag = stringTag; @@ -347,7 +373,7 @@ byte[] buf = value.getBytes(enc); length = buf.length; - buffer = new DerInputBuffer(buf); + buffer = new DerInputBuffer(buf, true); DerInputStream result = new DerInputStream(buffer); result.mark(Integer.MAX_VALUE); return result; @@ -356,8 +382,8 @@ /* * helper routine */ - private DerInputStream init(boolean fullyBuffered, InputStream in) - throws IOException { + private DerInputStream init(boolean fullyBuffered, InputStream in, + boolean allowBER) throws IOException { tag = (byte)in.read(); byte lenByte = (byte)in.read(); @@ -384,7 +410,7 @@ byte[] bytes = IOUtils.readFully(in, length, true); - buffer = new DerInputBuffer(bytes); + buffer = new DerInputBuffer(bytes, allowBER); return new DerInputStream(buffer); } @@ -479,7 +505,8 @@ if (buffer.read(bytes) != length) throw new IOException("short read on DerValue buffer"); if (isConstructed()) { - DerInputStream in = new DerInputStream(bytes); + DerInputStream in = new DerInputStream(bytes, 0, bytes.length, + buffer.allowBER); bytes = null; while (in.available() != 0) { bytes = append(bytes, in.getOctetString());