001: package org.bouncycastle.asn1;
002:
003: import java.io.IOException;
004: import java.io.InputStream;
005:
006: public class BERTaggedObjectParser implements ASN1TaggedObjectParser {
007: private int _baseTag;
008: private int _tagNumber;
009: private InputStream _contentStream;
010:
011: private boolean _indefiniteLength;
012:
013: protected BERTaggedObjectParser(int baseTag, int tagNumber,
014: InputStream contentStream) {
015: _baseTag = baseTag;
016: _tagNumber = tagNumber;
017: _contentStream = contentStream;
018: _indefiniteLength = contentStream instanceof IndefiniteLengthInputStream;
019: }
020:
021: public boolean isConstructed() {
022: return (_baseTag & DERTags.CONSTRUCTED) != 0;
023: }
024:
025: public int getTagNo() {
026: return _tagNumber;
027: }
028:
029: public DEREncodable getObjectParser(int tag, boolean isExplicit)
030: throws IOException {
031: if (isExplicit) {
032: return new ASN1StreamParser(_contentStream).readObject();
033: } else {
034: switch (tag) {
035: case DERTags.SET:
036: if (_indefiniteLength) {
037: return new BERSetParser(new ASN1ObjectParser(
038: _baseTag, _tagNumber, _contentStream));
039: } else {
040: return new DERSet(loadVector(_contentStream))
041: .parser();
042: }
043: case DERTags.SEQUENCE:
044: if (_indefiniteLength) {
045: return new BERSequenceParser(new ASN1ObjectParser(
046: _baseTag, _tagNumber, _contentStream));
047: } else {
048: return new DERSequence(loadVector(_contentStream))
049: .parser();
050: }
051: case DERTags.OCTET_STRING:
052: if (_indefiniteLength || this .isConstructed()) {
053: return new BEROctetStringParser(
054: new ASN1ObjectParser(_baseTag, _tagNumber,
055: _contentStream));
056: } else {
057: return new DEROctetString(
058: ((DefiniteLengthInputStream) _contentStream)
059: .toByteArray()).parser();
060: }
061: }
062: }
063:
064: throw new RuntimeException("implicit tagging not implemented");
065: }
066:
067: private ASN1EncodableVector loadVector(InputStream in)
068: throws IOException {
069: ASN1StreamParser aIn = new ASN1StreamParser(in);
070: ASN1EncodableVector v = new ASN1EncodableVector();
071: DEREncodable obj = aIn.readObject();
072:
073: while (obj != null) {
074: v.add(obj.getDERObject());
075: obj = aIn.readObject();
076: }
077:
078: return v;
079: }
080:
081: private ASN1EncodableVector rLoadVector(InputStream in) {
082: try {
083: return loadVector(in);
084: } catch (IOException e) {
085: throw new IllegalStateException(e.getMessage());
086: }
087: }
088:
089: public DERObject getDERObject() {
090: if (_indefiniteLength) {
091: ASN1EncodableVector v = rLoadVector(_contentStream);
092:
093: if (v.size() > 1) {
094: return new BERTaggedObject(false, _tagNumber,
095: new BERSequence(v));
096: } else if (v.size() == 1) {
097: return new BERTaggedObject(true, _tagNumber, v.get(0));
098: } else {
099: return new BERTaggedObject(false, _tagNumber,
100: new BERSequence());
101: }
102: } else {
103: if (this .isConstructed()) {
104: ASN1EncodableVector v = rLoadVector(_contentStream);
105:
106: if (v.size() == 1) {
107: return new DERTaggedObject(true, _tagNumber, v
108: .get(0));
109: }
110:
111: return new DERTaggedObject(false, _tagNumber,
112: new DERSequence(v));
113: }
114:
115: try {
116: return new DERTaggedObject(
117: false,
118: _tagNumber,
119: new DEROctetString(
120: ((DefiniteLengthInputStream) _contentStream)
121: .toByteArray()));
122: } catch (IOException e) {
123: throw new IllegalStateException(e.getMessage());
124: }
125: }
126:
127: }
128: }
|