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