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: */package org.apache.geronimo.crypto.asn1;
017:
018: import java.io.ByteArrayOutputStream;
019: import java.io.EOFException;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.util.Vector;
023:
024: /**
025: * @deprecated use ASN1InputStream
026: */
027: public class BERInputStream extends DERInputStream {
028: private DERObject END_OF_STREAM = new DERObject() {
029: void encode(DEROutputStream out) throws IOException {
030: throw new IOException("Eeek!");
031: }
032:
033: public int hashCode() {
034: return 0;
035: }
036:
037: public boolean equals(Object o) {
038: return o == this ;
039: }
040: };
041:
042: public BERInputStream(InputStream is) {
043: super (is);
044: }
045:
046: /**
047: * read a string of bytes representing an indefinite length object.
048: */
049: private byte[] readIndefiniteLengthFully() throws IOException {
050: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
051: int b, b1;
052:
053: b1 = read();
054:
055: while ((b = read()) >= 0) {
056: if (b1 == 0 && b == 0) {
057: break;
058: }
059:
060: bOut.write(b1);
061: b1 = b;
062: }
063:
064: return bOut.toByteArray();
065: }
066:
067: private BERConstructedOctetString buildConstructedOctetString()
068: throws IOException {
069: Vector octs = new Vector();
070:
071: for (;;) {
072: DERObject o = readObject();
073:
074: if (o == END_OF_STREAM) {
075: break;
076: }
077:
078: octs.addElement(o);
079: }
080:
081: return new BERConstructedOctetString(octs);
082: }
083:
084: public DERObject readObject() throws IOException {
085: int tag = read();
086: if (tag == -1) {
087: throw new EOFException();
088: }
089:
090: int length = readLength();
091:
092: if (length < 0) // indefinite length method
093: {
094: switch (tag) {
095: case NULL:
096: return null;
097: case SEQUENCE | CONSTRUCTED:
098: BERConstructedSequence seq = new BERConstructedSequence();
099:
100: for (;;) {
101: DERObject obj = readObject();
102:
103: if (obj == END_OF_STREAM) {
104: break;
105: }
106:
107: seq.addObject(obj);
108: }
109: return seq;
110: case OCTET_STRING | CONSTRUCTED:
111: return buildConstructedOctetString();
112: case SET | CONSTRUCTED:
113: ASN1EncodableVector v = new ASN1EncodableVector();
114:
115: for (;;) {
116: DERObject obj = readObject();
117:
118: if (obj == END_OF_STREAM) {
119: break;
120: }
121:
122: v.add(obj);
123: }
124: return new BERSet(v);
125: default:
126: //
127: // with tagged object tag number is bottom 5 bits
128: //
129: if ((tag & TAGGED) != 0) {
130: if ((tag & 0x1f) == 0x1f) {
131: throw new IOException(
132: "unsupported high tag encountered");
133: }
134:
135: //
136: // simple type - implicit... return an octet string
137: //
138: if ((tag & CONSTRUCTED) == 0) {
139: byte[] bytes = readIndefiniteLengthFully();
140:
141: return new BERTaggedObject(false, tag & 0x1f,
142: new DEROctetString(bytes));
143: }
144:
145: //
146: // either constructed or explicitly tagged
147: //
148: DERObject dObj = readObject();
149:
150: if (dObj == END_OF_STREAM) // empty tag!
151: {
152: return new DERTaggedObject(tag & 0x1f);
153: }
154:
155: DERObject next = readObject();
156:
157: //
158: // explicitly tagged (probably!) - if it isn't we'd have to
159: // tell from the context
160: //
161: if (next == END_OF_STREAM) {
162: return new BERTaggedObject(tag & 0x1f, dObj);
163: }
164:
165: //
166: // another implicit object, we'll create a sequence...
167: //
168: seq = new BERConstructedSequence();
169:
170: seq.addObject(dObj);
171:
172: do {
173: seq.addObject(next);
174: next = readObject();
175: } while (next != END_OF_STREAM);
176:
177: return new BERTaggedObject(false, tag & 0x1f, seq);
178: }
179:
180: throw new IOException("unknown BER object encountered");
181: }
182: } else {
183: if (tag == 0 && length == 0) // end of contents marker.
184: {
185: return END_OF_STREAM;
186: }
187:
188: byte[] bytes = new byte[length];
189:
190: readFully(bytes);
191:
192: return buildObject(tag, bytes);
193: }
194: }
195: }
|