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 }