1 package com.lowagie.bc.asn1; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.ByteArrayOutputStream; 5 import java.io.EOFException; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.util.Vector; 9 10 16 public class ASN1InputStream 17 extends DERInputStream 18 { 19 private DERObject END_OF_STREAM = new DERObject() { 20 void encode( 21 DEROutputStream out) 22 throws IOException 23 { 24 throw new IOException("Eeek!"); 25 } 26 27 }; 28 boolean eofFound = false; 29 30 public ASN1InputStream( 31 InputStream is) 32 { 33 super(is); 34 } 35 36 protected int readLength() 37 throws IOException 38 { 39 int length = read(); 40 if (length < 0) 41 { 42 throw new IOException("EOF found when length expected"); 43 } 44 45 if (length == 0x80) 46 { 47 return -1; } 49 50 if (length > 127) 51 { 52 int size = length & 0x7f; 53 54 length = 0; 55 for (int i = 0; i < size; i++) 56 { 57 int next = read(); 58 59 if (next < 0) 60 { 61 throw new IOException("EOF found reading length"); 62 } 63 64 length = (length << 8) + next; 65 } 66 } 67 68 return length; 69 } 70 71 protected void readFully( 72 byte[] bytes) 73 throws IOException 74 { 75 int left = bytes.length; 76 int len; 77 78 if (left == 0) 79 { 80 return; 81 } 82 83 while ((len = read(bytes, bytes.length - left, left)) > 0) 84 { 85 if ((left -= len) == 0) 86 { 87 return; 88 } 89 } 90 91 if (left != 0) 92 { 93 throw new EOFException("EOF encountered in middle of object"); 94 } 95 } 96 97 101 protected DERObject buildObject( 102 int tag, 103 byte[] bytes) 104 throws IOException 105 { 106 if ((tag & APPLICATION) != 0) 107 { 108 return new DERApplicationSpecific(tag, bytes); 109 } 110 111 switch (tag) 112 { 113 case NULL: 114 return new DERNull(); 115 case SEQUENCE | CONSTRUCTED: 116 ByteArrayInputStream bIn = new ByteArrayInputStream(bytes); 117 ASN1InputStream aIn = new ASN1InputStream(bIn); 118 ASN1EncodableVector v = new ASN1EncodableVector(); 119 120 DERObject obj = aIn.readObject(); 121 122 while (obj != null) 123 { 124 v.add(obj); 125 obj = aIn.readObject(); 126 } 127 128 return new DERSequence(v); 129 case SET | CONSTRUCTED: 130 bIn = new ByteArrayInputStream(bytes); 131 aIn = new ASN1InputStream(bIn); 132 v = new ASN1EncodableVector(); 133 134 obj = aIn.readObject(); 135 136 while (obj != null) 137 { 138 v.add(obj); 139 obj = aIn.readObject(); 140 } 141 142 return new DERSet(v); 143 case BOOLEAN: 144 return new DERBoolean(bytes); 145 case INTEGER: 146 return new DERInteger(bytes); 147 case ENUMERATED: 148 return new DEREnumerated(bytes); 149 case OBJECT_IDENTIFIER: 150 return new DERObjectIdentifier(bytes); 151 case BIT_STRING: 152 int padBits = bytes[0]; 153 byte[] data = new byte[bytes.length - 1]; 154 155 System.arraycopy(bytes, 1, data, 0, bytes.length - 1); 156 157 return new DERBitString(data, padBits); 158 case UTF8_STRING: 159 return new DERUTF8String(bytes); 160 case PRINTABLE_STRING: 161 return new DERPrintableString(bytes); 162 case IA5_STRING: 163 return new DERIA5String(bytes); 164 case T61_STRING: 165 return new DERT61String(bytes); 166 case VISIBLE_STRING: 167 return new DERVisibleString(bytes); 168 case GENERAL_STRING: 169 return new DERGeneralString(bytes); 170 case UNIVERSAL_STRING: 171 return new DERUniversalString(bytes); 172 case BMP_STRING: 173 return new DERBMPString(bytes); 174 case OCTET_STRING: 175 return new DEROctetString(bytes); 176 case UTC_TIME: 177 return new DERUTCTime(bytes); 178 case GENERALIZED_TIME: 179 return new DERGeneralizedTime(bytes); 180 default: 181 if ((tag & TAGGED) != 0) 185 { 186 int tagNo = tag & 0x1f; 187 188 if (tagNo == 0x1f) 189 { 190 int idx = 0; 191 192 tagNo = 0; 193 194 while ((bytes[idx] & 0x80) != 0) 195 { 196 tagNo |= (bytes[idx++] & 0x7f); 197 tagNo <<= 7; 198 } 199 200 tagNo |= (bytes[idx] & 0x7f); 201 202 byte[] tmp = bytes; 203 204 bytes = new byte[tmp.length - (idx + 1)]; 205 System.arraycopy(tmp, idx + 1, bytes, 0, bytes.length); 206 } 207 208 if (bytes.length == 0) { 210 if ((tag & CONSTRUCTED) == 0) 211 { 212 return new DERTaggedObject(false, tagNo, new DERNull()); 213 } 214 else 215 { 216 return new DERTaggedObject(false, tagNo, new DERSequence()); 217 } 218 } 219 220 if ((tag & CONSTRUCTED) == 0) 224 { 225 return new DERTaggedObject(false, tagNo, new DEROctetString(bytes)); 226 } 227 228 bIn = new ByteArrayInputStream(bytes); 229 aIn = new ASN1InputStream(bIn); 230 231 DEREncodable dObj = aIn.readObject(); 232 233 if (aIn.available() == 0) 238 { 239 return new DERTaggedObject(tagNo, dObj); 240 } 241 242 v = new ASN1EncodableVector(); 246 247 while (dObj != null) 248 { 249 v.add(dObj); 250 dObj = aIn.readObject(); 251 } 252 253 return new DERTaggedObject(false, tagNo, new DERSequence(v)); 254 } 255 256 return new DERUnknownTag(tag, bytes); 257 } 258 } 259 260 263 private byte[] readIndefiniteLengthFully() 264 throws IOException 265 { 266 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 267 int b, b1; 268 269 b1 = read(); 270 271 while ((b = read()) >= 0) 272 { 273 if (b1 == 0 && b == 0) 274 { 275 break; 276 } 277 278 bOut.write(b1); 279 b1 = b; 280 } 281 282 return bOut.toByteArray(); 283 } 284 285 private BERConstructedOctetString buildConstructedOctetString() 286 throws IOException 287 { 288 Vector octs = new Vector(); 289 290 for (;;) 291 { 292 DERObject o = readObject(); 293 294 if (o == END_OF_STREAM) 295 { 296 break; 297 } 298 299 octs.addElement(o); 300 } 301 302 return new BERConstructedOctetString(octs); 303 } 304 305 public DERObject readObject() 306 throws IOException 307 { 308 int tag = read(); 309 if (tag == -1) 310 { 311 if (eofFound) 312 { 313 throw new EOFException("attempt to read past end of file."); 314 } 315 316 eofFound = true; 317 318 return null; 319 } 320 321 int length = readLength(); 322 323 if (length < 0) { 325 switch (tag) 326 { 327 case NULL: 328 return new BERNull(); 329 case SEQUENCE | CONSTRUCTED: 330 ASN1EncodableVector v = new ASN1EncodableVector(); 331 332 for (;;) 333 { 334 DERObject obj = readObject(); 335 336 if (obj == END_OF_STREAM) 337 { 338 break; 339 } 340 341 v.add(obj); 342 } 343 return new BERSequence(v); 344 case SET | CONSTRUCTED: 345 v = new ASN1EncodableVector(); 346 347 for (;;) 348 { 349 DERObject obj = readObject(); 350 351 if (obj == END_OF_STREAM) 352 { 353 break; 354 } 355 356 v.add(obj); 357 } 358 return new BERSet(v); 359 case OCTET_STRING | CONSTRUCTED: 360 return buildConstructedOctetString(); 361 default: 362 if ((tag & TAGGED) != 0) 366 { 367 int tagNo = tag & 0x1f; 368 369 if (tagNo == 0x1f) 370 { 371 int b = read(); 372 373 tagNo = 0; 374 375 while ((b >= 0) && ((b & 0x80) != 0)) 376 { 377 tagNo |= (b & 0x7f); 378 tagNo <<= 7; 379 b = read(); 380 } 381 382 tagNo |= (b & 0x7f); 383 } 384 385 if ((tag & CONSTRUCTED) == 0) 389 { 390 byte[] bytes = readIndefiniteLengthFully(); 391 392 return new BERTaggedObject(false, tagNo, new DEROctetString(bytes)); 393 } 394 395 DERObject dObj = readObject(); 399 400 if (dObj == END_OF_STREAM) { 402 return new DERTaggedObject(tagNo); 403 } 404 405 DERObject next = readObject(); 406 407 if (next == END_OF_STREAM) 412 { 413 return new BERTaggedObject(tagNo, dObj); 414 } 415 416 v = new ASN1EncodableVector(); 420 421 v.add(dObj); 422 423 do 424 { 425 v.add(next); 426 next = readObject(); 427 } 428 while (next != END_OF_STREAM); 429 430 return new BERTaggedObject(false, tagNo, new BERSequence(v)); 431 } 432 433 throw new IOException("unknown BER object encountered"); 434 } 435 } 436 else 437 { 438 if (tag == 0 && length == 0) { 440 return END_OF_STREAM; 441 } 442 443 byte[] bytes = new byte[length]; 444 445 readFully(bytes); 446 447 return buildObject(tag, bytes); 448 } 449 } 450 } 451 | Popular Tags |