001: package org.bouncycastle.sasn1;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.EOFException;
005: import java.io.IOException;
006: import java.io.InputStream;
007:
008: /**
009: * @deprecated use org.bouncycastle.asn1.ASN1StreamParser
010: */
011: public class Asn1InputStream {
012: InputStream _in;
013: private int _limit;
014: private boolean _eofFound;
015:
016: public Asn1InputStream(InputStream in) {
017: this ._in = in;
018: this ._limit = Integer.MAX_VALUE;
019: }
020:
021: public Asn1InputStream(InputStream in, int limit) {
022: this ._in = in;
023: this ._limit = limit;
024: }
025:
026: public Asn1InputStream(byte[] encoding) {
027: this ._in = new ByteArrayInputStream(encoding);
028: this ._limit = encoding.length;
029: }
030:
031: InputStream getParentStream() {
032: return _in;
033: }
034:
035: private int readLength() throws IOException {
036: int length = _in.read();
037: if (length < 0) {
038: throw new IOException("EOF found when length expected");
039: }
040:
041: if (length == 0x80) {
042: return -1; // indefinite-length encoding
043: }
044:
045: if (length > 127) {
046: int size = length & 0x7f;
047:
048: if (size > 4) {
049: throw new IOException("DER length more than 4 bytes");
050: }
051:
052: length = 0;
053: for (int i = 0; i < size; i++) {
054: int next = _in.read();
055:
056: if (next < 0) {
057: throw new IOException("EOF found reading length");
058: }
059:
060: length = (length << 8) + next;
061: }
062:
063: if (length < 0) {
064: throw new IOException(
065: "corrupted steam - negative length found");
066: }
067:
068: if (length >= _limit) // after all we must have read at least 1 byte
069: {
070: throw new IOException(
071: "corrupted steam - out of bounds length found");
072: }
073: }
074:
075: return length;
076: }
077:
078: public Asn1Object readObject() throws IOException {
079: int tag = _in.read();
080: if (tag == -1) {
081: if (_eofFound) {
082: throw new EOFException(
083: "attempt to read past end of file.");
084: }
085:
086: _eofFound = true;
087:
088: return null;
089: }
090:
091: //
092: // turn of looking for "00" while we resolve the tag
093: //
094: if (_in instanceof IndefiniteLengthInputStream) {
095: ((IndefiniteLengthInputStream) _in).setEofOn00(false);
096: }
097:
098: //
099: // calculate tag number
100: //
101: int baseTagNo = tag & ~BerTag.CONSTRUCTED;
102: int tagNo = baseTagNo;
103:
104: if ((tag & BerTag.TAGGED) != 0) {
105: tagNo = tag & 0x1f;
106:
107: //
108: // with tagged object tag number is bottom 5 bits, or stored at the start of the content
109: //
110: if (tagNo == 0x1f) {
111: tagNo = 0;
112:
113: int b = _in.read();
114:
115: while ((b >= 0) && ((b & 0x80) != 0)) {
116: tagNo |= (b & 0x7f);
117: tagNo <<= 7;
118: b = _in.read();
119: }
120:
121: if (b < 0) {
122: _eofFound = true;
123:
124: throw new EOFException(
125: "EOF encountered inside tag value.");
126: }
127:
128: tagNo |= (b & 0x7f);
129: }
130: }
131:
132: //
133: // calculate length
134: //
135: int length = readLength();
136:
137: if (length < 0) // indefinite length
138: {
139: IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(
140: _in);
141:
142: switch (baseTagNo) {
143: case BerTag.NULL:
144: return new Asn1Null(tag);
145: case BerTag.OCTET_STRING:
146: return new BerOctetString(tag, indIn);
147: case BerTag.SEQUENCE:
148: return new BerSequence(tag, indIn);
149: case BerTag.SET:
150: return new BerSet(tag, indIn);
151: default:
152: return new Asn1TaggedObject(tag, tagNo, indIn);
153: }
154: } else {
155: DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(
156: _in, length);
157:
158: switch (baseTagNo) {
159: case BerTag.INTEGER:
160: return new Asn1Integer(tag, defIn.toByteArray());
161: case BerTag.NULL:
162: return new Asn1Null(tag);
163: case BerTag.OBJECT_IDENTIFIER:
164: return new Asn1ObjectIdentifier(tag, defIn
165: .toByteArray());
166: case BerTag.OCTET_STRING:
167: return new DerOctetString(tag, defIn.toByteArray());
168: case BerTag.SEQUENCE:
169: return new DerSequence(tag, defIn.toByteArray());
170: case BerTag.SET:
171: return new DerSet(tag, defIn.toByteArray());
172: default:
173: return new Asn1TaggedObject(tag, tagNo, defIn);
174: }
175: }
176: }
177: }
|