KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > maverick > crypto > asn1 > DERInputStream


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.maverick.crypto.asn1;
21
22 import java.io.ByteArrayInputStream JavaDoc;
23 import java.io.EOFException JavaDoc;
24 import java.io.FilterInputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27
28 /**
29  * Don't use this class. It will eventually disappear, use ASN1InputStream.
30  * <br>
31  * This class is scheduled for removal.
32  */

33 public class DERInputStream
34     extends FilterInputStream JavaDoc implements DERTags
35 {
36     public DERInputStream(
37         InputStream JavaDoc is)
38     {
39         super(is);
40     }
41
42     protected int readLength()
43         throws IOException JavaDoc
44     {
45         int length = read();
46         if (length < 0)
47         {
48             throw new IOException JavaDoc("EOF found when length expected");
49         }
50
51         if (length == 0x80)
52         {
53             return -1; // indefinite-length encoding
54
}
55
56         if (length > 127)
57         {
58             int size = length & 0x7f;
59
60             length = 0;
61             for (int i = 0; i < size; i++)
62             {
63                 int next = read();
64
65                 if (next < 0)
66                 {
67                     throw new IOException JavaDoc("EOF found reading length");
68                 }
69
70                 length = (length << 8) + next;
71             }
72         }
73
74         return length;
75     }
76
77     protected void readFully(
78         byte[] bytes)
79         throws IOException JavaDoc
80     {
81         int left = bytes.length;
82
83         if (left == 0)
84         {
85             return;
86         }
87
88         while (left > 0)
89         {
90             int l = read(bytes, bytes.length - left, left);
91
92             if (l < 0)
93             {
94                 throw new EOFException JavaDoc("unexpected end of stream");
95             }
96
97             left -= l;
98         }
99     }
100
101     /**
102      * build an object given its tag and a byte stream to construct it
103      * from.
104      */

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