1 package org.bouncycastle.asn1;
2
3 import java.math.BigInteger;
4 import java.io.*;
5 import java.util.*;
6
7 public class BERInputStream
8 extends DERInputStream
9 {
10 private DERObject END_OF_STREAM = new DERObject() {
11 void encode(
12 DEROutputStream out)
13 throws IOException
14 {
15 throw new IOException("Eeek!");
16 }
17
18 };
19 public BERInputStream(
20 InputStream is)
21 {
22 super(is);
23 }
24
25
28 private byte[] readIndefiniteLengthFully()
29 throws IOException
30 {
31 ByteArrayOutputStream bOut = new ByteArrayOutputStream();
32 intint b, b1;
33
34 b1 = read();
35
36 while ((b = read()) >= 0)
37 {
38 if (b1 == 0 && b == 0)
39 {
40 break;
41 }
42
43 bOut.write(b1);
44 b1 = b;
45 }
46
47 return bOut.toByteArray();
48 }
49
50 private BERConstructedOctetString buildConstructedOctetString()
51 throws IOException
52 {
53 Vector octs = new Vector();
54
55 for (;;)
56 {
57 DERObject o = readObject();
58
59 if (o == END_OF_STREAM)
60 {
61 break;
62 }
63
64 octs.addElement(o);
65 }
66
67 return new BERConstructedOctetString(octs);
68 }
69
70 public DERObject readObject()
71 throws IOException
72 {
73 int tag = read();
74 if (tag == -1)
75 {
76 throw new EOFException();
77 }
78
79 int length = readLength();
80
81 if (length < 0)
82 {
83 switch (tag)
84 {
85 case NULL:
86 return null;
87 case SEQUENCE | CONSTRUCTED:
88 BERConstructedSequence seq = new BERConstructedSequence();
89
90 for (;;)
91 {
92 DERObject obj = readObject();
93
94 if (obj == END_OF_STREAM)
95 {
96 break;
97 }
98
99 seq.addObject(obj);
100 }
101 return seq;
102 case OCTET_STRING | CONSTRUCTED:
103 return buildConstructedOctetString();
104 case SET | CONSTRUCTED:
105 DEREncodableVector v = new DEREncodableVector();
106
107 for (;;)
108 {
109 DERObject obj = readObject();
110
111 if (obj == END_OF_STREAM)
112 {
113 break;
114 }
115
116 v.add(obj);
117 }
118 return new BERSet(v);
119 default:
120
121
122
123 if ((tag & TAGGED) != 0)
124 {
125 if ((tag & 0x1f) == 0x1f)
126 {
127 throw new IOException("unsupported high tag encountered");
128 }
129
130
131
132
133 if ((tag & CONSTRUCTED) == 0)
134 {
135 byte[] bytes = readIndefiniteLengthFully();
136
137 return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
138 }
139
140
141
142
143 DERObject dObj = readObject();
144
145 if (dObj == END_OF_STREAM)
146 {
147 return new DERTaggedObject(tag & 0x1f);
148 }
149
150 DERObject next = readObject();
151
152
153
154
155
156 if (next == END_OF_STREAM)
157 {
158 return new BERTaggedObject(tag & 0x1f, dObj);
159 }
160
161
162
163
164 seq = new BERConstructedSequence();
165
166 seq.addObject(dObj);
167
168 do
169 {
170 seq.addObject(next);
171 next = readObject();
172 }
173 while (next != END_OF_STREAM);
174
175 return new BERTaggedObject(false, tag & 0x1f, seq);
176 }
177
178 throw new IOException("unknown BER object encountered");
179 }
180 }
181 else
182 {
183 if (tag == 0 && length == 0)
184 {
185 return END_OF_STREAM;
186 }
187
188 byte[] bytes = new byte[length];
189
190 readFully(bytes);
191
192 return buildObject(tag, bytes);
193 }
194 }
195 }
196