1 package org.bouncycastle.asn1; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.EOFException; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.util.Vector; 8 9 /** 10 * @deprecated use ASN1InputStream 11 */ 12 public class BERInputStream 13 extends DERInputStream 14 { 15 private DERObject END_OF_STREAM = new DERObject() 16 { 17 void encode( 18 DEROutputStream out) 19 throws IOException 20 { 21 throw new IOException("Eeek!"); 22 } 23 public int hashCode() 24 { 25 return 0; 26 } 27 public boolean equals( 28 Object o) 29 { 30 return o == this; 31 } 32 }; 33 public BERInputStream( 34 InputStream is) 35 { 36 super(is); 37 } 38 39 /** 40 * read a string of bytes representing an indefinite length object. 41 */ 42 private byte[] readIndefiniteLengthFully() 43 throws IOException 44 { 45 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 46 int b, b1; 47 48 b1 = read(); 49 50 while ((b = read()) >= 0) 51 { 52 if (b1 == 0 && b == 0) 53 { 54 break; 55 } 56 57 bOut.write(b1); 58 b1 = b; 59 } 60 61 return bOut.toByteArray(); 62 } 63 64 private BERConstructedOctetString buildConstructedOctetString() 65 throws IOException 66 { 67 Vector octs = new Vector(); 68 69 for (;;) 70 { 71 DERObject o = readObject(); 72 73 if (o == END_OF_STREAM) 74 { 75 break; 76 } 77 78 octs.addElement(o); 79 } 80 81 return new BERConstructedOctetString(octs); 82 } 83 84 public DERObject readObject() 85 throws IOException 86 { 87 int tag = read(); 88 if (tag == -1) 89 { 90 throw new EOFException(); 91 } 92 93 int length = readLength(); 94 95 if (length < 0) // indefinite length method 96 { 97 switch (tag) 98 { 99 case NULL: 100 return null; 101 case SEQUENCE | CONSTRUCTED: 102 BERConstructedSequence seq = new BERConstructedSequence(); 103 104 for (;;) 105 { 106 DERObject obj = readObject(); 107 108 if (obj == END_OF_STREAM) 109 { 110 break; 111 } 112 113 seq.addObject(obj); 114 } 115 return seq; 116 case OCTET_STRING | CONSTRUCTED: 117 return buildConstructedOctetString(); 118 case SET | CONSTRUCTED: 119 ASN1EncodableVector v = new ASN1EncodableVector(); 120 121 for (;;) 122 { 123 DERObject obj = readObject(); 124 125 if (obj == END_OF_STREAM) 126 { 127 break; 128 } 129 130 v.add(obj); 131 } 132 return new BERSet(v); 133 default: 134 // 135 // with tagged object tag number is bottom 5 bits 136 // 137 if ((tag & TAGGED) != 0) 138 { 139 if ((tag & 0x1f) == 0x1f) 140 { 141 throw new IOException("unsupported high tag encountered"); 142 } 143 144 // 145 // simple type - implicit... return an octet string 146 // 147 if ((tag & CONSTRUCTED) == 0) 148 { 149 byte[] bytes = readIndefiniteLengthFully(); 150 151 return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes)); 152 } 153 154 // 155 // either constructed or explicitly tagged 156 // 157 DERObject dObj = readObject(); 158 159 if (dObj == END_OF_STREAM) // empty tag! 160 { 161 return new DERTaggedObject(tag & 0x1f); 162 } 163 164 DERObject next = readObject(); 165 166 // 167 // explicitly tagged (probably!) - if it isn't we'd have to 168 // tell from the context 169 // 170 if (next == END_OF_STREAM) 171 { 172 return new BERTaggedObject(tag & 0x1f, dObj); 173 } 174 175 // 176 // another implicit object, we'll create a sequence... 177 // 178 seq = new BERConstructedSequence(); 179 180 seq.addObject(dObj); 181 182 do 183 { 184 seq.addObject(next); 185 next = readObject(); 186 } 187 while (next != END_OF_STREAM); 188 189 return new BERTaggedObject(false, tag & 0x1f, seq); 190 } 191 192 throw new IOException("unknown BER object encountered"); 193 } 194 } 195 else 196 { 197 if (tag == 0 && length == 0) // end of contents marker. 198 { 199 return END_OF_STREAM; 200 } 201 202 byte[] bytes = new byte[length]; 203 204 readFully(bytes); 205 206 return buildObject(tag, bytes); 207 } 208 } 209 } 210