1 package org.bouncycastle.asn1;
3 import java.math.BigInteger;
7 public class BERInputStream
10 private DERObject END_OF_STREAM = new DERObject() {
15 throw new IOException("Eeek!");
19 public BERInputStream(
26 * read a string of bytes representing an indefinite length object.
28 private byte[] readIndefiniteLengthFully()
31 ByteArrayOutputStream bOut = new ByteArrayOutputStream();
36 while ((b = read()) >= 0)
38 if (b1 == 0 && b == 0)
47 return bOut.toByteArray();
50 private BERConstructedOctetString buildConstructedOctetString()
53 Vector octs = new Vector();
57 DERObject o = readObject();
59 if (o == END_OF_STREAM)
67 return new BERConstructedOctetString(octs);
70 public DERObject readObject()
76 throw new EOFException();
79 int length = readLength();
81 if (length < 0) // indefinite length method
87 case SEQUENCE | CONSTRUCTED:
88 BERConstructedSequence seq = new BERConstructedSequence();
92 DERObject obj = readObject();
94 if (obj == END_OF_STREAM)
102 case OCTET_STRING | CONSTRUCTED:
103 return buildConstructedOctetString();
104 case SET | CONSTRUCTED:
105 DEREncodableVector v = new DEREncodableVector();
109 DERObject obj = readObject();
111 if (obj == END_OF_STREAM)
118 return new BERSet(v);
121 // with tagged object tag number is bottom 5 bits
123 if ((tag & TAGGED) != 0)
125 if ((tag & 0x1f) == 0x1f)
127 throw new IOException("unsupported high tag encountered");
131 // simple type - implicit... return an octet string
133 if ((tag & CONSTRUCTED) == 0)
135 byte[] bytes = readIndefiniteLengthFully();
137 return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
141 // either constructed or explicitly tagged
143 DERObject dObj = readObject();
145 if (dObj == END_OF_STREAM) // empty tag!
147 return new DERTaggedObject(tag & 0x1f);
150 DERObject next = readObject();
153 // explicitly tagged (probably!) - if it isn't we'd have to
154 // tell from the context
156 if (next == END_OF_STREAM)
158 return new BERTaggedObject(tag & 0x1f, dObj);
162 // another implicit object, we'll create a sequence...
164 seq = new BERConstructedSequence();
173 while (next != END_OF_STREAM);
175 return new BERTaggedObject(false, tag & 0x1f, seq);
178 throw new IOException("unknown BER object encountered");
183 if (tag == 0 && length == 0) // end of contents marker.
185 return END_OF_STREAM;
188 byte[] bytes = new byte[length];
192 return buildObject(tag, bytes);