| package org.bouncycastle.asn1; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| |
| public class BERTaggedObjectParser |
| implements ASN1TaggedObjectParser |
| { |
| private int _baseTag; |
| private int _tagNumber; |
| private InputStream _contentStream; |
| |
| private boolean _indefiniteLength; |
| |
| protected BERTaggedObjectParser( |
| int baseTag, |
| int tagNumber, |
| InputStream contentStream) |
| { |
| _baseTag = baseTag; |
| _tagNumber = tagNumber; |
| _contentStream = contentStream; |
| _indefiniteLength = contentStream instanceof IndefiniteLengthInputStream; |
| } |
| |
| public boolean isConstructed() |
| { |
| return (_baseTag & DERTags.CONSTRUCTED) != 0; |
| } |
| |
| public int getTagNo() |
| { |
| return _tagNumber; |
| } |
| |
| public DEREncodable getObjectParser( |
| int tag, |
| boolean isExplicit) |
| throws IOException |
| { |
| if (isExplicit) |
| { |
| return new ASN1StreamParser(_contentStream).readObject(); |
| } |
| |
| switch (tag) |
| { |
| case DERTags.SET: |
| if (_indefiniteLength) |
| { |
| return new BERSetParser(new ASN1StreamParser(_contentStream)); |
| } |
| else |
| { |
| return new DERSetParser(new ASN1StreamParser(_contentStream)); |
| } |
| case DERTags.SEQUENCE: |
| if (_indefiniteLength) |
| { |
| return new BERSequenceParser(new ASN1StreamParser(_contentStream)); |
| } |
| else |
| { |
| return new DERSequenceParser(new ASN1StreamParser(_contentStream)); |
| } |
| case DERTags.OCTET_STRING: |
| // TODO Is the handling of definite length constructed encodings correct? |
| if (_indefiniteLength || this.isConstructed()) |
| { |
| return new BEROctetStringParser(new ASN1StreamParser(_contentStream)); |
| } |
| else |
| { |
| return new DEROctetStringParser((DefiniteLengthInputStream)_contentStream); |
| } |
| } |
| |
| throw new RuntimeException("implicit tagging not implemented"); |
| } |
| |
| private ASN1EncodableVector rLoadVector(InputStream in) |
| { |
| try |
| { |
| return new ASN1StreamParser(in).readVector(); |
| } |
| catch (IOException e) |
| { |
| throw new ASN1ParsingException(e.getMessage(), e); |
| } |
| } |
| |
| public DERObject getDERObject() |
| { |
| if (_indefiniteLength) |
| { |
| ASN1EncodableVector v = rLoadVector(_contentStream); |
| |
| return v.size() == 1 |
| ? new BERTaggedObject(true, _tagNumber, v.get(0)) |
| : new BERTaggedObject(false, _tagNumber, BERFactory.createSequence(v)); |
| } |
| |
| if (this.isConstructed()) |
| { |
| ASN1EncodableVector v = rLoadVector(_contentStream); |
| |
| return v.size() == 1 |
| ? new DERTaggedObject(true, _tagNumber, v.get(0)) |
| : new DERTaggedObject(false, _tagNumber, DERFactory.createSequence(v)); |
| } |
| |
| try |
| { |
| DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_contentStream; |
| return new DERTaggedObject(false, _tagNumber, new DEROctetString(defIn.toByteArray())); |
| } |
| catch (IOException e) |
| { |
| throw new IllegalStateException(e.getMessage()); |
| } |
| } |
| } |