KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > bc > asn1 > DERInputStream


1 package com.lowagie.bc.asn1;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.EOFException;
5 import java.io.FilterInputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8
9 /**
10  * Don't use this class. It will eventually disappear, use ASN1InputStream.
11  * <br>
12  * This class is scheduled for removal.
13  */

14 public class DERInputStream
15     extends FilterInputStream implements DERTags
16 {
17     public DERInputStream(
18         InputStream is)
19     {
20         super(is);
21     }
22
23     protected int readLength()
24         throws IOException
25     {
26         int length = read();
27         if (length < 0)
28         {
29             throw new IOException("EOF found when length expected");
30         }
31
32         if (length == 0x80)
33         {
34             return -1; // indefinite-length encoding
35
}
36
37         if (length > 127)
38         {
39             int size = length & 0x7f;
40
41             length = 0;
42             for (int i = 0; i < size; i++)
43             {
44                 int next = read();
45
46                 if (next < 0)
47                 {
48                     throw new IOException("EOF found reading length");
49                 }
50
51                 length = (length << 8) + next;
52             }
53         }
54
55         return length;
56     }
57
58     protected void readFully(
59         byte[] bytes)
60         throws IOException
61     {
62         int left = bytes.length;
63
64         if (left == 0)
65         {
66             return;
67         }
68
69         while (left > 0)
70         {
71             int l = read(bytes, bytes.length - left, left);
72             
73             if (l < 0)
74             {
75                 throw new EOFException("unexpected end of stream");
76             }
77             
78             left -= l;
79         }
80     }
81
82     /**
83      * build an object given its tag and a byte stream to construct it
84      * from.
85      */

86     protected DERObject buildObject(
87         int tag,
88         byte[] bytes)
89         throws IOException
90     {
91         switch (tag)
92         {
93         case NULL:
94             return null;
95         case SEQUENCE | CONSTRUCTED:
96             ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);
97             BERInputStream dIn = new BERInputStream(bIn);
98             DERConstructedSequence seq = new DERConstructedSequence();
99
100             try
101             {
102                 for (;;)
103                 {
104                     DERObject obj = dIn.readObject();
105
106                     seq.addObject(obj);
107                 }
108             }
109             catch (EOFException ex)
110             {
111                 return seq;
112             }
113         case SET | CONSTRUCTED:
114             bIn = new ByteArrayInputStream(bytes);
115             dIn = new BERInputStream(bIn);
116
117             ASN1EncodableVector v = new ASN1EncodableVector();
118
119             try
120             {
121                 for (;;)
122                 {
123                     DERObject obj = dIn.readObject();
124
125                     v.add(obj);
126                 }
127             }
128             catch (EOFException ex)
129             {
130                 return new DERConstructedSet(v);
131             }
132         case BOOLEAN:
133             return new DERBoolean(bytes);
134         case INTEGER:
135             return new DERInteger(bytes);
136         case ENUMERATED:
137             return new DEREnumerated(bytes);
138         case OBJECT_IDENTIFIER:
139             return new DERObjectIdentifier(bytes);
140         case BIT_STRING:
141             int padBits = bytes[0];
142             byte[] data = new byte[bytes.length - 1];
143
144             System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
145
146             return new DERBitString(data, padBits);
147         case UTF8_STRING:
148             return new DERUTF8String(bytes);
149         case PRINTABLE_STRING:
150             return new DERPrintableString(bytes);
151         case IA5_STRING:
152             return new DERIA5String(bytes);
153         case T61_STRING:
154             return new DERT61String(bytes);
155         case VISIBLE_STRING:
156             return new DERVisibleString(bytes);
157         case UNIVERSAL_STRING:
158             return new DERUniversalString(bytes);
159         case GENERAL_STRING:
160             return new DERGeneralString(bytes);
161         case BMP_STRING:
162             return new DERBMPString(bytes);
163         case OCTET_STRING:
164             return new DEROctetString(bytes);
165         case UTC_TIME:
166             return new DERUTCTime(bytes);
167         case GENERALIZED_TIME:
168             return new DERGeneralizedTime(bytes);
169         default:
170             //
171
// with tagged object tag number is bottom 5 bits
172
//
173
if ((tag & TAGGED) != 0)
174             {
175                 if ((tag & 0x1f) == 0x1f)
176                 {
177                     throw new IOException("unsupported high tag encountered");
178                 }
179
180                 if (bytes.length == 0) // empty tag!
181
{
182                     if ((tag & CONSTRUCTED) == 0)
183                     {
184                         return new DERTaggedObject(false, tag & 0x1f, new DERNull());
185                     }
186                     else
187                     {
188                         return new DERTaggedObject(false, tag & 0x1f, new DERConstructedSequence());
189                     }
190                 }
191
192                 //
193
// simple type - implicit... return an octet string
194
//
195
if ((tag & CONSTRUCTED) == 0)
196                 {
197                     return new DERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
198                 }
199
200                 bIn = new ByteArrayInputStream(bytes);
201                 dIn = new BERInputStream(bIn);
202
203                 DEREncodable dObj = dIn.readObject();
204
205                 //
206
// explicitly tagged (probably!) - if it isn't we'd have to
207
// tell from the context
208
//
209
if (dIn.available() == 0)
210                 {
211                     return new DERTaggedObject(tag & 0x1f, dObj);
212                 }
213
214                 //
215
// another implicit object, we'll create a sequence...
216
//
217
seq = new DERConstructedSequence();
218
219                 seq.addObject(dObj);
220
221                 try
222                 {
223                     for (;;)
224                     {
225                         dObj = dIn.readObject();
226
227                         seq.addObject(dObj);
228                     }
229                 }
230                 catch (EOFException ex)
231                 {
232                     // ignore --
233
}
234
235                 return new DERTaggedObject(false, tag & 0x1f, seq);
236             }
237
238             return new DERUnknownTag(tag, bytes);
239         }
240     }
241
242     public DERObject readObject()
243         throws IOException
244     {
245         int tag = read();
246         if (tag == -1)
247         {
248             throw new EOFException();
249         }
250
251         int length = readLength();
252         byte[] bytes = new byte[length];
253
254         readFully(bytes);
255
256         return buildObject(tag, bytes);
257     }
258 }
259
Popular Tags