KickJava   Java API By Example, From Geeks To Geeks.

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


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.ByteArrayOutputStream JavaDoc;
23 import java.io.EOFException JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.util.Vector JavaDoc;
27
28 public class BERInputStream
29     extends DERInputStream
30 {
31     private DERObject END_OF_STREAM = new DERObject() {
32                                         void encode(
33                                             DEROutputStream out)
34                                         throws IOException JavaDoc
35                                         {
36                                             throw new IOException JavaDoc("Eeek!");
37                                         }
38
39                                     };
40     public BERInputStream(
41         InputStream JavaDoc is)
42     {
43         super(is);
44     }
45
46     /**
47      * read a string of bytes representing an indefinite length object.
48      */

49     private byte[] readIndefiniteLengthFully()
50         throws IOException JavaDoc
51     {
52         ByteArrayOutputStream JavaDoc bOut = new ByteArrayOutputStream JavaDoc();
53         int b, b1;
54
55         b1 = read();
56
57         while ((b = read()) >= 0)
58         {
59             if (b1 == 0 && b == 0)
60             {
61                 break;
62             }
63
64             bOut.write(b1);
65             b1 = b;
66         }
67
68         return bOut.toByteArray();
69     }
70
71     private BERConstructedOctetString buildConstructedOctetString()
72         throws IOException JavaDoc
73     {
74         Vector JavaDoc octs = new Vector JavaDoc();
75
76         for (;;)
77         {
78             DERObject o = readObject();
79
80             if (o == END_OF_STREAM)
81             {
82                 break;
83             }
84
85             octs.addElement(o);
86         }
87
88         return new BERConstructedOctetString(octs);
89     }
90
91     public DERObject readObject()
92         throws IOException JavaDoc
93     {
94         int tag = read();
95         if (tag == -1)
96         {
97             throw new EOFException JavaDoc();
98         }
99
100         int length = readLength();
101
102         if (length < 0) // indefinite length method
103
{
104             switch (tag)
105             {
106             case NULL:
107                 return null;
108             case SEQUENCE | CONSTRUCTED:
109                 BERConstructedSequence seq = new BERConstructedSequence();
110
111                 for (;;)
112                 {
113                     DERObject obj = readObject();
114
115                     if (obj == END_OF_STREAM)
116                     {
117                         break;
118                     }
119
120                     seq.addObject(obj);
121                 }
122                 return seq;
123             case OCTET_STRING | CONSTRUCTED:
124                 return buildConstructedOctetString();
125             case SET | CONSTRUCTED:
126                 ASN1EncodableVector v = new ASN1EncodableVector();
127
128                 for (;;)
129                 {
130                     DERObject obj = readObject();
131
132                     if (obj == END_OF_STREAM)
133                     {
134                         break;
135                     }
136
137                     v.add(obj);
138                 }
139                 return new BERSet(v);
140             default:
141                 //
142
// with tagged object tag number is bottom 5 bits
143
//
144
if ((tag & TAGGED) != 0)
145                 {
146                     if ((tag & 0x1f) == 0x1f)
147                     {
148                         throw new IOException JavaDoc("unsupported high tag encountered");
149                     }
150
151                     //
152
// simple type - implicit... return an octet string
153
//
154
if ((tag & CONSTRUCTED) == 0)
155                     {
156                         byte[] bytes = readIndefiniteLengthFully();
157
158                         return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
159                     }
160
161                     //
162
// either constructed or explicitly tagged
163
//
164
DERObject dObj = readObject();
165
166                     if (dObj == END_OF_STREAM) // empty tag!
167
{
168                         return new DERTaggedObject(tag & 0x1f);
169                     }
170
171                     DERObject next = readObject();
172
173                     //
174
// explicitly tagged (probably!) - if it isn't we'd have to
175
// tell from the context
176
//
177
if (next == END_OF_STREAM)
178                     {
179                         return new BERTaggedObject(tag & 0x1f, dObj);
180                     }
181
182                     //
183
// another implicit object, we'll create a sequence...
184
//
185
seq = new BERConstructedSequence();
186
187                     seq.addObject(dObj);
188
189                     do
190                     {
191                         seq.addObject(next);
192                         next = readObject();
193                     }
194                     while (next != END_OF_STREAM);
195
196                     return new BERTaggedObject(false, tag & 0x1f, seq);
197                 }
198
199                 throw new IOException JavaDoc("unknown BER object encountered");
200             }
201         }
202         else
203         {
204             if (tag == 0 && length == 0) // end of contents marker.
205
{
206                 return END_OF_STREAM;
207             }
208
209             byte[] bytes = new byte[length];
210
211             readFully(bytes);
212
213             return buildObject(tag, bytes);
214         }
215     }
216 }
217
Popular Tags