001 /**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.apache.geronimo.util.asn1;
020
021 import java.io.ByteArrayOutputStream;
022 import java.io.EOFException;
023 import java.io.IOException;
024 import java.io.InputStream;
025 import java.util.Vector;
026
027 /**
028 * @deprecated use ASN1InputStream
029 */
030 public class BERInputStream
031 extends DERInputStream
032 {
033 private DERObject END_OF_STREAM = new DERObject() {
034 void encode(
035 DEROutputStream out)
036 throws IOException
037 {
038 throw new IOException("Eeek!");
039 }
040 public int hashCode()
041 {
042 return 0;
043 }
044 public boolean equals(
045 Object o)
046 {
047 return o == this;
048 }
049 };
050 public BERInputStream(
051 InputStream is)
052 {
053 super(is);
054 }
055
056 /**
057 * read a string of bytes representing an indefinite length object.
058 */
059 private byte[] readIndefiniteLengthFully()
060 throws IOException
061 {
062 ByteArrayOutputStream bOut = new ByteArrayOutputStream();
063 int b, b1;
064
065 b1 = read();
066
067 while ((b = read()) >= 0)
068 {
069 if (b1 == 0 && b == 0)
070 {
071 break;
072 }
073
074 bOut.write(b1);
075 b1 = b;
076 }
077
078 return bOut.toByteArray();
079 }
080
081 private BERConstructedOctetString buildConstructedOctetString()
082 throws IOException
083 {
084 Vector octs = new Vector();
085
086 for (;;)
087 {
088 DERObject o = readObject();
089
090 if (o == END_OF_STREAM)
091 {
092 break;
093 }
094
095 octs.addElement(o);
096 }
097
098 return new BERConstructedOctetString(octs);
099 }
100
101 public DERObject readObject()
102 throws IOException
103 {
104 int tag = read();
105 if (tag == -1)
106 {
107 throw new EOFException();
108 }
109
110 int length = readLength();
111
112 if (length < 0) // indefinite length method
113 {
114 switch (tag)
115 {
116 case NULL:
117 return null;
118 case SEQUENCE | CONSTRUCTED:
119 BERConstructedSequence seq = new BERConstructedSequence();
120
121 for (;;)
122 {
123 DERObject obj = readObject();
124
125 if (obj == END_OF_STREAM)
126 {
127 break;
128 }
129
130 seq.addObject(obj);
131 }
132 return seq;
133 case OCTET_STRING | CONSTRUCTED:
134 return buildConstructedOctetString();
135 case SET | CONSTRUCTED:
136 ASN1EncodableVector v = new ASN1EncodableVector();
137
138 for (;;)
139 {
140 DERObject obj = readObject();
141
142 if (obj == END_OF_STREAM)
143 {
144 break;
145 }
146
147 v.add(obj);
148 }
149 return new BERSet(v);
150 default:
151 //
152 // with tagged object tag number is bottom 5 bits
153 //
154 if ((tag & TAGGED) != 0)
155 {
156 if ((tag & 0x1f) == 0x1f)
157 {
158 throw new IOException("unsupported high tag encountered");
159 }
160
161 //
162 // simple type - implicit... return an octet string
163 //
164 if ((tag & CONSTRUCTED) == 0)
165 {
166 byte[] bytes = readIndefiniteLengthFully();
167
168 return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
169 }
170
171 //
172 // either constructed or explicitly tagged
173 //
174 DERObject dObj = readObject();
175
176 if (dObj == END_OF_STREAM) // empty tag!
177 {
178 return new DERTaggedObject(tag & 0x1f);
179 }
180
181 DERObject next = readObject();
182
183 //
184 // explicitly tagged (probably!) - if it isn't we'd have to
185 // tell from the context
186 //
187 if (next == END_OF_STREAM)
188 {
189 return new BERTaggedObject(tag & 0x1f, dObj);
190 }
191
192 //
193 // another implicit object, we'll create a sequence...
194 //
195 seq = new BERConstructedSequence();
196
197 seq.addObject(dObj);
198
199 do
200 {
201 seq.addObject(next);
202 next = readObject();
203 }
204 while (next != END_OF_STREAM);
205
206 return new BERTaggedObject(false, tag & 0x1f, seq);
207 }
208
209 throw new IOException("unknown BER object encountered");
210 }
211 }
212 else
213 {
214 if (tag == 0 && length == 0) // end of contents marker.
215 {
216 return END_OF_STREAM;
217 }
218
219 byte[] bytes = new byte[length];
220
221 readFully(bytes);
222
223 return buildObject(tag, bytes);
224 }
225 }
226 }