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