001 package org.apache.commons.ssl.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 /** @deprecated use ASN1InputStream */
010 public class BERInputStream
011 extends DERInputStream {
012 private static final DERObject END_OF_STREAM = new DERObject() {
013 void encode(
014 DEROutputStream out)
015 throws IOException {
016 throw new IOException("Eeek!");
017 }
018 public int hashCode() {
019 return 0;
020 }
021 public boolean equals(
022 Object o) {
023 return o == this;
024 }
025 };
026 public BERInputStream(
027 InputStream is) {
028 super(is);
029 }
030
031 /** read a string of bytes representing an indefinite length object. */
032 private byte[] readIndefiniteLengthFully()
033 throws IOException {
034 ByteArrayOutputStream bOut = new ByteArrayOutputStream();
035 int b, b1;
036
037 b1 = read();
038
039 while ((b = read()) >= 0) {
040 if (b1 == 0 && b == 0) {
041 break;
042 }
043
044 bOut.write(b1);
045 b1 = b;
046 }
047
048 return bOut.toByteArray();
049 }
050
051 private BERConstructedOctetString buildConstructedOctetString()
052 throws IOException {
053 Vector octs = new Vector();
054
055 for (; ;) {
056 DERObject o = readObject();
057
058 if (o == END_OF_STREAM) {
059 break;
060 }
061
062 octs.addElement(o);
063 }
064
065 return new BERConstructedOctetString(octs);
066 }
067
068 public DERObject readObject()
069 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("unsupported high tag encountered");
117 }
118
119 //
120 // simple type - implicit... return an octet string
121 //
122 if ((tag & CONSTRUCTED) == 0) {
123 byte[] bytes = readIndefiniteLengthFully();
124
125 return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
126 }
127
128 //
129 // either constructed or explicitly tagged
130 //
131 DERObject dObj = readObject();
132
133 if (dObj == END_OF_STREAM) // empty tag!
134 {
135 return new DERTaggedObject(tag & 0x1f);
136 }
137
138 DERObject next = readObject();
139
140 //
141 // explicitly tagged (probably!) - if it isn't we'd have to
142 // tell from the context
143 //
144 if (next == END_OF_STREAM) {
145 return new BERTaggedObject(tag & 0x1f, dObj);
146 }
147
148 //
149 // another implicit object, we'll create a sequence...
150 //
151 seq = new BERConstructedSequence();
152
153 seq.addObject(dObj);
154
155 do {
156 seq.addObject(next);
157 next = readObject();
158 }
159 while (next != END_OF_STREAM);
160
161 return new BERTaggedObject(false, tag & 0x1f, seq);
162 }
163
164 throw new IOException("unknown BER object encountered");
165 }
166 } else {
167 if (tag == 0 && length == 0) // end of contents marker.
168 {
169 return END_OF_STREAM;
170 }
171
172 byte[] bytes = new byte[length];
173
174 readFully(bytes);
175
176 return buildObject(tag, bytes);
177 }
178 }
179 }