package org.bouncycastle.asn1;
-import java.math.BigInteger;
import java.io.*;
import java.util.*;
public class BERInputStream
extends DERInputStream
{
- private DERObject END_OF_STREAM = new DERObject() {
- void encode(
- DEROutputStream out)
- throws IOException
- {
- throw new IOException("Eeek!");
- }
-
- };
+ private DERObject END_OF_STREAM = new DERObject() {
+ void encode(
+ DEROutputStream out)
+ throws IOException
+ {
+ throw new IOException("Eeek!");
+ }
+
+ };
public BERInputStream(
InputStream is)
{
while ((b = read()) >= 0)
{
- if (b1 == 0 && b == 0)
- {
- break;
- }
+ if (b1 == 0 && b == 0)
+ {
+ break;
+ }
bOut.write(b1);
b1 = b;
return bOut.toByteArray();
}
- private BERConstructedOctetString buildConstructedOctetString(
- DEROctetString o1,
- DEROctetString o2)
- throws IOException
- {
+ private BERConstructedOctetString buildConstructedOctetString()
+ throws IOException
+ {
Vector octs = new Vector();
- if (o1 != null)
- {
- octs.addElement(o1);
- octs.addElement(o2);
- }
-
- for (;;)
- {
- DERObject o = readObject();
+ for (;;)
+ {
+ DERObject o = readObject();
- if (o == END_OF_STREAM)
- {
- break;
- }
+ if (o == END_OF_STREAM)
+ {
+ break;
+ }
octs.addElement(o);
- }
+ }
- return new BERConstructedOctetString(octs);
- }
+ return new BERConstructedOctetString(octs);
+ }
public DERObject readObject()
throws IOException
if (length < 0) // indefinite length method
{
- byte[] bytes;
-
switch (tag)
{
case NULL:
case SEQUENCE | CONSTRUCTED:
BERConstructedSequence seq = new BERConstructedSequence();
- for (;;)
- {
- DERObject obj = readObject();
-
- if (obj == END_OF_STREAM)
- {
- break;
- }
-
- seq.addObject(obj);
- }
- return seq;
+ for (;;)
+ {
+ DERObject obj = readObject();
+
+ if (obj == END_OF_STREAM)
+ {
+ break;
+ }
+
+ seq.addObject(obj);
+ }
+ return seq;
case OCTET_STRING | CONSTRUCTED:
- return buildConstructedOctetString(null, null);
+ return buildConstructedOctetString();
+ case SET | CONSTRUCTED:
+ DEREncodableVector v = new DEREncodableVector();
+
+ for (;;)
+ {
+ DERObject obj = readObject();
+
+ if (obj == END_OF_STREAM)
+ {
+ break;
+ }
+
+ v.add(obj);
+ }
+ return new BERSet(v);
default:
- if ((tag & (TAGGED | CONSTRUCTED)) != 0)
+ //
+ // with tagged object tag number is bottom 5 bits
+ //
+ if ((tag & TAGGED) != 0)
{
- // with tagged object tag number is bottom 4 bits
- BERTaggedObject tagObj = new BERTaggedObject(tag & 0x0f, readObject());
- DERObject o = readObject();
-
- if (o == END_OF_STREAM)
- {
- return tagObj;
- }
- else if (o instanceof DEROctetString
- && tagObj.getObject() instanceof DEROctetString)
- {
- //
- // it's an implicit object - mark it as so...
- //
- tagObj = new BERTaggedObject(false, tag & 0x0f,
- buildConstructedOctetString((DEROctetString)tagObj.getObject(), (DEROctetString)o));
-
- return tagObj;
- }
-
- throw new IOException("truncated tagged object");
+ if ((tag & 0x1f) == 0x1f)
+ {
+ throw new IOException("unsupported high tag encountered");
+ }
+
+ //
+ // simple type - implicit... return an octet string
+ //
+ if ((tag & CONSTRUCTED) == 0)
+ {
+ byte[] bytes = readIndefiniteLengthFully();
+
+ return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
+ }
+
+ //
+ // either constructed or explicitly tagged
+ //
+ DERObject dObj = readObject();
+
+ if (dObj == END_OF_STREAM) // empty tag!
+ {
+ return new DERTaggedObject(tag & 0x1f);
+ }
+
+ DERObject next = readObject();
+
+ //
+ // explicitly tagged (probably!) - if it isn't we'd have to
+ // tell from the context
+ //
+ if (next == END_OF_STREAM)
+ {
+ return new BERTaggedObject(tag & 0x1f, dObj);
+ }
+
+ //
+ // another implicit object, we'll create a sequence...
+ //
+ seq = new BERConstructedSequence();
+
+ seq.addObject(dObj);
+
+ do
+ {
+ seq.addObject(next);
+ next = readObject();
+ }
+ while (next != END_OF_STREAM);
+
+ return new BERTaggedObject(false, tag & 0x1f, seq);
}
-
- bytes = readIndefiniteLengthFully();
- return buildObject(tag, bytes);
+ throw new IOException("unknown BER object encountered");
}
}
else
readFully(bytes);
- return buildObject(tag, bytes);
+ return buildObject(tag, bytes);
}
}
}