001: package org.bouncycastle.asn1;
002:
003: import java.io.ByteArrayOutputStream;
004: import java.io.EOFException;
005: import java.io.IOException;
006: import java.io.InputStream;
007: import java.util.Vector;
008:
009: /**
010: * @deprecated use ASN1InputStream
011: */
012: public class BERInputStream extends DERInputStream {
013: private static final DERObject END_OF_STREAM = new DERObject() {
014: void encode(DEROutputStream out) throws IOException {
015: throw new IOException("Eeek!");
016: }
017:
018: public int hashCode() {
019: return 0;
020: }
021:
022: public boolean equals(Object o) {
023: return o == this ;
024: }
025: };
026:
027: public BERInputStream(InputStream is) {
028: super (is);
029: }
030:
031: /**
032: * read a string of bytes representing an indefinite length object.
033: */
034: private byte[] readIndefiniteLengthFully() throws IOException {
035: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
036: int b, b1;
037:
038: b1 = read();
039:
040: while ((b = read()) >= 0) {
041: if (b1 == 0 && b == 0) {
042: break;
043: }
044:
045: bOut.write(b1);
046: b1 = b;
047: }
048:
049: return bOut.toByteArray();
050: }
051:
052: private BERConstructedOctetString buildConstructedOctetString()
053: throws IOException {
054: Vector octs = new Vector();
055:
056: for (;;) {
057: DERObject o = readObject();
058:
059: if (o == END_OF_STREAM) {
060: break;
061: }
062:
063: octs.addElement(o);
064: }
065:
066: return new BERConstructedOctetString(octs);
067: }
068:
069: public DERObject readObject() throws IOException {
070: int tag = read();
071: if (tag == -1) {
072: throw new EOFException();
073: }
074:
075: int length = readLength();
076:
077: if (length < 0) // indefinite length method
078: {
079: switch (tag) {
080: case NULL:
081: return null;
082: case SEQUENCE | CONSTRUCTED:
083: BERConstructedSequence seq = new BERConstructedSequence();
084:
085: for (;;) {
086: DERObject obj = readObject();
087:
088: if (obj == END_OF_STREAM) {
089: break;
090: }
091:
092: seq.addObject(obj);
093: }
094: return seq;
095: case OCTET_STRING | CONSTRUCTED:
096: return buildConstructedOctetString();
097: case SET | CONSTRUCTED:
098: ASN1EncodableVector v = new ASN1EncodableVector();
099:
100: for (;;) {
101: DERObject obj = readObject();
102:
103: if (obj == END_OF_STREAM) {
104: break;
105: }
106:
107: v.add(obj);
108: }
109: return new BERSet(v);
110: default:
111: //
112: // with tagged object tag number is bottom 5 bits
113: //
114: if ((tag & TAGGED) != 0) {
115: if ((tag & 0x1f) == 0x1f) {
116: throw new IOException(
117: "unsupported high tag encountered");
118: }
119:
120: //
121: // simple type - implicit... return an octet string
122: //
123: if ((tag & CONSTRUCTED) == 0) {
124: byte[] bytes = readIndefiniteLengthFully();
125:
126: return new BERTaggedObject(false, tag & 0x1f,
127: new DEROctetString(bytes));
128: }
129:
130: //
131: // either constructed or explicitly tagged
132: //
133: DERObject dObj = readObject();
134:
135: if (dObj == END_OF_STREAM) // empty tag!
136: {
137: return new DERTaggedObject(tag & 0x1f);
138: }
139:
140: DERObject next = readObject();
141:
142: //
143: // explicitly tagged (probably!) - if it isn't we'd have to
144: // tell from the context
145: //
146: if (next == END_OF_STREAM) {
147: return new BERTaggedObject(tag & 0x1f, dObj);
148: }
149:
150: //
151: // another implicit object, we'll create a sequence...
152: //
153: seq = new BERConstructedSequence();
154:
155: seq.addObject(dObj);
156:
157: do {
158: seq.addObject(next);
159: next = readObject();
160: } while (next != END_OF_STREAM);
161:
162: return new BERTaggedObject(false, tag & 0x1f, seq);
163: }
164:
165: throw new IOException("unknown BER object encountered");
166: }
167: } else {
168: if (tag == 0 && length == 0) // end of contents marker.
169: {
170: return END_OF_STREAM;
171: }
172:
173: byte[] bytes = new byte[length];
174:
175: readFully(bytes);
176:
177: return buildObject(tag, bytes);
178: }
179: }
180: }
|