001 package org.apache.commons.ssl.asn1; 002 003 import java.io.ByteArrayOutputStream; 004 import java.io.EOFException; 005 import java.io.IOException; 006 import java.io.InputStream; 007 import java.util.Vector; 008 009 /** @deprecated use ASN1InputStream */ 010 public class BERInputStream 011 extends DERInputStream { 012 private static final DERObject END_OF_STREAM = new DERObject() { 013 void encode( 014 DEROutputStream out) 015 throws IOException { 016 throw new IOException("Eeek!"); 017 } 018 public int hashCode() { 019 return 0; 020 } 021 public boolean equals( 022 Object o) { 023 return o == this; 024 } 025 }; 026 public BERInputStream( 027 InputStream is) { 028 super(is); 029 } 030 031 /** read a string of bytes representing an indefinite length object. */ 032 private byte[] readIndefiniteLengthFully() 033 throws IOException { 034 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 035 int b, b1; 036 037 b1 = read(); 038 039 while ((b = read()) >= 0) { 040 if (b1 == 0 && b == 0) { 041 break; 042 } 043 044 bOut.write(b1); 045 b1 = b; 046 } 047 048 return bOut.toByteArray(); 049 } 050 051 private BERConstructedOctetString buildConstructedOctetString() 052 throws IOException { 053 Vector octs = new Vector(); 054 055 for (; ;) { 056 DERObject o = readObject(); 057 058 if (o == END_OF_STREAM) { 059 break; 060 } 061 062 octs.addElement(o); 063 } 064 065 return new BERConstructedOctetString(octs); 066 } 067 068 public DERObject readObject() 069 throws IOException { 070 int tag = read(); 071 if (tag == -1) { 072 throw new EOFException(); 073 } 074 075 int length = readLength(); 076 077 if (length < 0) // indefinite length method 078 { 079 switch (tag) { 080 case NULL: 081 return null; 082 case SEQUENCE | CONSTRUCTED: 083 BERConstructedSequence seq = new BERConstructedSequence(); 084 085 for (; ;) { 086 DERObject obj = readObject(); 087 088 if (obj == END_OF_STREAM) { 089 break; 090 } 091 092 seq.addObject(obj); 093 } 094 return seq; 095 case OCTET_STRING | CONSTRUCTED: 096 return buildConstructedOctetString(); 097 case SET | CONSTRUCTED: 098 ASN1EncodableVector v = new ASN1EncodableVector(); 099 100 for (; ;) { 101 DERObject obj = readObject(); 102 103 if (obj == END_OF_STREAM) { 104 break; 105 } 106 107 v.add(obj); 108 } 109 return new BERSet(v); 110 default: 111 // 112 // with tagged object tag number is bottom 5 bits 113 // 114 if ((tag & TAGGED) != 0) { 115 if ((tag & 0x1f) == 0x1f) { 116 throw new IOException("unsupported high tag encountered"); 117 } 118 119 // 120 // simple type - implicit... return an octet string 121 // 122 if ((tag & CONSTRUCTED) == 0) { 123 byte[] bytes = readIndefiniteLengthFully(); 124 125 return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes)); 126 } 127 128 // 129 // either constructed or explicitly tagged 130 // 131 DERObject dObj = readObject(); 132 133 if (dObj == END_OF_STREAM) // empty tag! 134 { 135 return new DERTaggedObject(tag & 0x1f); 136 } 137 138 DERObject next = readObject(); 139 140 // 141 // explicitly tagged (probably!) - if it isn't we'd have to 142 // tell from the context 143 // 144 if (next == END_OF_STREAM) { 145 return new BERTaggedObject(tag & 0x1f, dObj); 146 } 147 148 // 149 // another implicit object, we'll create a sequence... 150 // 151 seq = new BERConstructedSequence(); 152 153 seq.addObject(dObj); 154 155 do { 156 seq.addObject(next); 157 next = readObject(); 158 } 159 while (next != END_OF_STREAM); 160 161 return new BERTaggedObject(false, tag & 0x1f, seq); 162 } 163 164 throw new IOException("unknown BER object encountered"); 165 } 166 } else { 167 if (tag == 0 && length == 0) // end of contents marker. 168 { 169 return END_OF_STREAM; 170 } 171 172 byte[] bytes = new byte[length]; 173 174 readFully(bytes); 175 176 return buildObject(tag, bytes); 177 } 178 } 179 }