From 6025b6016517c6d898d8957d1d7e03ba71431912 Mon Sep 17 00:00:00 2001 From: tknall Date: Fri, 1 Dec 2006 12:20:24 +0000 Subject: Initial import of release 2.2. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@4 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../java/com/lowagie/bc/asn1/DERInputStream.java | 258 +++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 src/main/java/com/lowagie/bc/asn1/DERInputStream.java (limited to 'src/main/java/com/lowagie/bc/asn1/DERInputStream.java') diff --git a/src/main/java/com/lowagie/bc/asn1/DERInputStream.java b/src/main/java/com/lowagie/bc/asn1/DERInputStream.java new file mode 100644 index 0000000..3148a3f --- /dev/null +++ b/src/main/java/com/lowagie/bc/asn1/DERInputStream.java @@ -0,0 +1,258 @@ +package com.lowagie.bc.asn1; + +import java.io.ByteArrayInputStream; +import java.io.EOFException; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Don't use this class. It will eventually disappear, use ASN1InputStream. + *
+ * This class is scheduled for removal. + */ +public class DERInputStream + extends FilterInputStream implements DERTags +{ + public DERInputStream( + InputStream is) + { + super(is); + } + + protected int readLength() + throws IOException + { + int length = read(); + if (length < 0) + { + throw new IOException("EOF found when length expected"); + } + + if (length == 0x80) + { + return -1; // indefinite-length encoding + } + + if (length > 127) + { + int size = length & 0x7f; + + length = 0; + for (int i = 0; i < size; i++) + { + int next = read(); + + if (next < 0) + { + throw new IOException("EOF found reading length"); + } + + length = (length << 8) + next; + } + } + + return length; + } + + protected void readFully( + byte[] bytes) + throws IOException + { + int left = bytes.length; + + if (left == 0) + { + return; + } + + while (left > 0) + { + int l = read(bytes, bytes.length - left, left); + + if (l < 0) + { + throw new EOFException("unexpected end of stream"); + } + + left -= l; + } + } + + /** + * build an object given its tag and a byte stream to construct it + * from. + */ + protected DERObject buildObject( + int tag, + byte[] bytes) + throws IOException + { + switch (tag) + { + case NULL: + return null; + case SEQUENCE | CONSTRUCTED: + ByteArrayInputStream bIn = new ByteArrayInputStream(bytes); + BERInputStream dIn = new BERInputStream(bIn); + DERConstructedSequence seq = new DERConstructedSequence(); + + try + { + for (;;) + { + DERObject obj = dIn.readObject(); + + seq.addObject(obj); + } + } + catch (EOFException ex) + { + return seq; + } + case SET | CONSTRUCTED: + bIn = new ByteArrayInputStream(bytes); + dIn = new BERInputStream(bIn); + + ASN1EncodableVector v = new ASN1EncodableVector(); + + try + { + for (;;) + { + DERObject obj = dIn.readObject(); + + v.add(obj); + } + } + catch (EOFException ex) + { + return new DERConstructedSet(v); + } + case BOOLEAN: + return new DERBoolean(bytes); + case INTEGER: + return new DERInteger(bytes); + case ENUMERATED: + return new DEREnumerated(bytes); + case OBJECT_IDENTIFIER: + return new DERObjectIdentifier(bytes); + case BIT_STRING: + int padBits = bytes[0]; + byte[] data = new byte[bytes.length - 1]; + + System.arraycopy(bytes, 1, data, 0, bytes.length - 1); + + return new DERBitString(data, padBits); + case UTF8_STRING: + return new DERUTF8String(bytes); + case PRINTABLE_STRING: + return new DERPrintableString(bytes); + case IA5_STRING: + return new DERIA5String(bytes); + case T61_STRING: + return new DERT61String(bytes); + case VISIBLE_STRING: + return new DERVisibleString(bytes); + case UNIVERSAL_STRING: + return new DERUniversalString(bytes); + case GENERAL_STRING: + return new DERGeneralString(bytes); + case BMP_STRING: + return new DERBMPString(bytes); + case OCTET_STRING: + return new DEROctetString(bytes); + case UTC_TIME: + return new DERUTCTime(bytes); + case GENERALIZED_TIME: + return new DERGeneralizedTime(bytes); + default: + // + // with tagged object tag number is bottom 5 bits + // + if ((tag & TAGGED) != 0) + { + if ((tag & 0x1f) == 0x1f) + { + throw new IOException("unsupported high tag encountered"); + } + + if (bytes.length == 0) // empty tag! + { + if ((tag & CONSTRUCTED) == 0) + { + return new DERTaggedObject(false, tag & 0x1f, new DERNull()); + } + else + { + return new DERTaggedObject(false, tag & 0x1f, new DERConstructedSequence()); + } + } + + // + // simple type - implicit... return an octet string + // + if ((tag & CONSTRUCTED) == 0) + { + return new DERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes)); + } + + bIn = new ByteArrayInputStream(bytes); + dIn = new BERInputStream(bIn); + + DEREncodable dObj = dIn.readObject(); + + // + // explicitly tagged (probably!) - if it isn't we'd have to + // tell from the context + // + if (dIn.available() == 0) + { + return new DERTaggedObject(tag & 0x1f, dObj); + } + + // + // another implicit object, we'll create a sequence... + // + seq = new DERConstructedSequence(); + + seq.addObject(dObj); + + try + { + for (;;) + { + dObj = dIn.readObject(); + + seq.addObject(dObj); + } + } + catch (EOFException ex) + { + // ignore -- + } + + return new DERTaggedObject(false, tag & 0x1f, seq); + } + + return new DERUnknownTag(tag, bytes); + } + } + + public DERObject readObject() + throws IOException + { + int tag = read(); + if (tag == -1) + { + throw new EOFException(); + } + + int length = readLength(); + byte[] bytes = new byte[length]; + + readFully(bytes); + + return buildObject(tag, bytes); + } +} -- cgit v1.2.3