diff options
Diffstat (limited to 'core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1InputStream.java')
-rw-r--r-- | core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1InputStream.java | 466 |
1 files changed, 0 insertions, 466 deletions
diff --git a/core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1InputStream.java b/core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1InputStream.java deleted file mode 100644 index 7c156266..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1InputStream.java +++ /dev/null @@ -1,466 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.ByteArrayInputStream; -import java.io.EOFException; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.bouncycastle.util.io.Streams; - -/** - * a general purpose ASN.1 decoder - note: this class differs from the - * others in that it returns null after it has read the last object in - * the stream. If an ASN.1 NULL is encountered a DER/BER Null object is - * returned. - */ -public class ASN1InputStream - extends FilterInputStream - implements BERTags -{ - private int limit; - private boolean lazyEvaluate; - - private byte[][] tmpBuffers; - - public ASN1InputStream( - InputStream is) - { - this(is, StreamUtil.findLimit(is)); - } - - /** - * 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. - * - * @param input array containing ASN.1 encoded data. - */ - public ASN1InputStream( - byte[] input) - { - this(new ByteArrayInputStream(input), input.length); - } - - /** - * 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. - * - * @param input array containing ASN.1 encoded data. - * @param lazyEvaluate true if parsing inside constructed objects can be delayed. - */ - public ASN1InputStream( - byte[] input, - boolean lazyEvaluate) - { - this(new ByteArrayInputStream(input), input.length, lazyEvaluate); - } - - /** - * Create an ASN1InputStream where no DER object will be longer than limit. - * - * @param input stream containing ASN.1 encoded data. - * @param limit maximum size of a DER encoded object. - */ - public ASN1InputStream( - InputStream input, - int limit) - { - this(input, limit, false); - } - - /** - * Create an ASN1InputStream where no DER object will be longer than limit, and constructed - * objects such as sequences will be parsed lazily. - * - * @param input stream containing ASN.1 encoded data. - * @param lazyEvaluate true if parsing inside constructed objects can be delayed. - */ - public ASN1InputStream( - InputStream input, - boolean lazyEvaluate) - { - this(input, StreamUtil.findLimit(input), lazyEvaluate); - } - - /** - * Create an ASN1InputStream where no DER object will be longer than limit, and constructed - * objects such as sequences will be parsed lazily. - * - * @param input stream containing ASN.1 encoded data. - * @param limit maximum size of a DER encoded object. - * @param lazyEvaluate true if parsing inside constructed objects can be delayed. - */ - public ASN1InputStream( - InputStream input, - int limit, - boolean lazyEvaluate) - { - super(input); - this.limit = limit; - this.lazyEvaluate = lazyEvaluate; - this.tmpBuffers = new byte[11][]; - } - - int getLimit() - { - return limit; - } - - protected int readLength() - throws IOException - { - return readLength(this, limit); - } - - protected void readFully( - byte[] bytes) - throws IOException - { - if (Streams.readFully(this, bytes) != bytes.length) - { - throw new EOFException("EOF encountered in middle of object"); - } - } - - /** - * build an object given its tag and the number of bytes to construct it from. - */ - protected ASN1Primitive buildObject( - int tag, - int tagNo, - int length) - throws IOException - { - boolean isConstructed = (tag & CONSTRUCTED) != 0; - - DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length); - - if ((tag & APPLICATION) != 0) - { - return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray()); - } - - if ((tag & TAGGED) != 0) - { - return new ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo); - } - - if (isConstructed) - { - // TODO There are other tags that may be constructed (e.g. BIT_STRING) - switch (tagNo) - { - case OCTET_STRING: - // - // yes, people actually do this... - // - ASN1EncodableVector v = buildDEREncodableVector(defIn); - ASN1OctetString[] strings = new ASN1OctetString[v.size()]; - - for (int i = 0; i != strings.length; i++) - { - strings[i] = (ASN1OctetString)v.get(i); - } - - return new BEROctetString(strings); - case SEQUENCE: - if (lazyEvaluate) - { - return new LazyEncodedSequence(defIn.toByteArray()); - } - else - { - return DERFactory.createSequence(buildDEREncodableVector(defIn)); - } - case SET: - return DERFactory.createSet(buildDEREncodableVector(defIn)); - case EXTERNAL: - return new DERExternal(buildDEREncodableVector(defIn)); - default: - throw new IOException("unknown tag " + tagNo + " encountered"); - } - } - - return createPrimitiveDERObject(tagNo, defIn, tmpBuffers); - } - - ASN1EncodableVector buildEncodableVector() - throws IOException - { - ASN1EncodableVector v = new ASN1EncodableVector(); - ASN1Primitive o; - - while ((o = readObject()) != null) - { - v.add(o); - } - - return v; - } - - ASN1EncodableVector buildDEREncodableVector( - DefiniteLengthInputStream dIn) throws IOException - { - return new ASN1InputStream(dIn).buildEncodableVector(); - } - - public ASN1Primitive readObject() - throws IOException - { - int tag = read(); - if (tag <= 0) - { - if (tag == 0) - { - throw new IOException("unexpected end-of-contents marker"); - } - - return null; - } - - // - // calculate tag number - // - int tagNo = readTagNumber(this, tag); - - boolean isConstructed = (tag & CONSTRUCTED) != 0; - - // - // calculate length - // - int length = readLength(); - - if (length < 0) // indefinite length method - { - if (!isConstructed) - { - throw new IOException("indefinite length primitive encoding encountered"); - } - - IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit); - ASN1StreamParser sp = new ASN1StreamParser(indIn, limit); - - if ((tag & APPLICATION) != 0) - { - return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject(); - } - - if ((tag & TAGGED) != 0) - { - return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject(); - } - - // TODO There are other tags that may be constructed (e.g. BIT_STRING) - switch (tagNo) - { - case OCTET_STRING: - return new BEROctetStringParser(sp).getLoadedObject(); - case SEQUENCE: - return new BERSequenceParser(sp).getLoadedObject(); - case SET: - return new BERSetParser(sp).getLoadedObject(); - case EXTERNAL: - return new DERExternalParser(sp).getLoadedObject(); - default: - throw new IOException("unknown BER object encountered"); - } - } - else - { - try - { - return buildObject(tag, tagNo, length); - } - catch (IllegalArgumentException e) - { - throw new ASN1Exception("corrupted stream detected", e); - } - } - } - - static int readTagNumber(InputStream s, int tag) - throws IOException - { - int tagNo = tag & 0x1f; - - // - // with tagged object tag number is bottom 5 bits, or stored at the start of the content - // - if (tagNo == 0x1f) - { - tagNo = 0; - - int b = s.read(); - - // X.690-0207 8.1.2.4.2 - // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." - if ((b & 0x7f) == 0) // Note: -1 will pass - { - throw new IOException("corrupted stream - invalid high tag number found"); - } - - while ((b >= 0) && ((b & 0x80) != 0)) - { - tagNo |= (b & 0x7f); - tagNo <<= 7; - b = s.read(); - } - - if (b < 0) - { - throw new EOFException("EOF found inside tag value."); - } - - tagNo |= (b & 0x7f); - } - - return tagNo; - } - - static int readLength(InputStream s, int limit) - throws IOException - { - int length = s.read(); - if (length < 0) - { - throw new EOFException("EOF found when length expected"); - } - - if (length == 0x80) - { - return -1; // indefinite-length encoding - } - - if (length > 127) - { - int size = length & 0x7f; - - // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here - if (size > 4) - { - throw new IOException("DER length more than 4 bytes: " + size); - } - - length = 0; - for (int i = 0; i < size; i++) - { - int next = s.read(); - - if (next < 0) - { - throw new EOFException("EOF found reading length"); - } - - length = (length << 8) + next; - } - - if (length < 0) - { - throw new IOException("corrupted stream - negative length found"); - } - - if (length >= limit) // after all we must have read at least 1 byte - { - throw new IOException("corrupted stream - out of bounds length found"); - } - } - - return length; - } - - private static byte[] getBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers) - throws IOException - { - int len = defIn.getRemaining(); - if (defIn.getRemaining() < tmpBuffers.length) - { - byte[] buf = tmpBuffers[len]; - - if (buf == null) - { - buf = tmpBuffers[len] = new byte[len]; - } - - Streams.readFully(defIn, buf); - - return buf; - } - else - { - return defIn.toByteArray(); - } - } - - private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn) - throws IOException - { - int len = defIn.getRemaining() / 2; - char[] buf = new char[len]; - int totalRead = 0; - while (totalRead < len) - { - int ch1 = defIn.read(); - if (ch1 < 0) - { - break; - } - int ch2 = defIn.read(); - if (ch2 < 0) - { - break; - } - buf[totalRead++] = (char)((ch1 << 8) | (ch2 & 0xff)); - } - - return buf; - } - - static ASN1Primitive createPrimitiveDERObject( - int tagNo, - DefiniteLengthInputStream defIn, - byte[][] tmpBuffers) - throws IOException - { - switch (tagNo) - { - case BIT_STRING: - return DERBitString.fromInputStream(defIn.getRemaining(), defIn); - case BMP_STRING: - return new DERBMPString(getBMPCharBuffer(defIn)); - case BOOLEAN: - return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers)); - case ENUMERATED: - return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers)); - case GENERALIZED_TIME: - return new ASN1GeneralizedTime(defIn.toByteArray()); - case GENERAL_STRING: - return new DERGeneralString(defIn.toByteArray()); - case IA5_STRING: - return new DERIA5String(defIn.toByteArray()); - case INTEGER: - return new ASN1Integer(defIn.toByteArray(), false); - case NULL: - return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?) - case NUMERIC_STRING: - return new DERNumericString(defIn.toByteArray()); - case OBJECT_IDENTIFIER: - return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers)); - case OCTET_STRING: - return new DEROctetString(defIn.toByteArray()); - case PRINTABLE_STRING: - return new DERPrintableString(defIn.toByteArray()); - case T61_STRING: - return new DERT61String(defIn.toByteArray()); - case UNIVERSAL_STRING: - return new DERUniversalString(defIn.toByteArray()); - case UTC_TIME: - return new ASN1UTCTime(defIn.toByteArray()); - case UTF8_STRING: - return new DERUTF8String(defIn.toByteArray()); - case VISIBLE_STRING: - return new DERVisibleString(defIn.toByteArray()); - default: - throw new IOException("unknown tag " + tagNo + " encountered"); - } - } -} |