1 package com.lowagie.bc.asn1; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.EOFException; 5 import java.io.FilterInputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 9 14 public class DERInputStream 15 extends FilterInputStream implements DERTags 16 { 17 public DERInputStream( 18 InputStream is) 19 { 20 super(is); 21 } 22 23 protected int readLength() 24 throws IOException 25 { 26 int length = read(); 27 if (length < 0) 28 { 29 throw new IOException("EOF found when length expected"); 30 } 31 32 if (length == 0x80) 33 { 34 return -1; } 36 37 if (length > 127) 38 { 39 int size = length & 0x7f; 40 41 length = 0; 42 for (int i = 0; i < size; i++) 43 { 44 int next = read(); 45 46 if (next < 0) 47 { 48 throw new IOException("EOF found reading length"); 49 } 50 51 length = (length << 8) + next; 52 } 53 } 54 55 return length; 56 } 57 58 protected void readFully( 59 byte[] bytes) 60 throws IOException 61 { 62 int left = bytes.length; 63 64 if (left == 0) 65 { 66 return; 67 } 68 69 while (left > 0) 70 { 71 int l = read(bytes, bytes.length - left, left); 72 73 if (l < 0) 74 { 75 throw new EOFException("unexpected end of stream"); 76 } 77 78 left -= l; 79 } 80 } 81 82 86 protected DERObject buildObject( 87 int tag, 88 byte[] bytes) 89 throws IOException 90 { 91 switch (tag) 92 { 93 case NULL: 94 return null; 95 case SEQUENCE | CONSTRUCTED: 96 ByteArrayInputStream bIn = new ByteArrayInputStream(bytes); 97 BERInputStream dIn = new BERInputStream(bIn); 98 DERConstructedSequence seq = new DERConstructedSequence(); 99 100 try 101 { 102 for (;;) 103 { 104 DERObject obj = dIn.readObject(); 105 106 seq.addObject(obj); 107 } 108 } 109 catch (EOFException ex) 110 { 111 return seq; 112 } 113 case SET | CONSTRUCTED: 114 bIn = new ByteArrayInputStream(bytes); 115 dIn = new BERInputStream(bIn); 116 117 ASN1EncodableVector v = new ASN1EncodableVector(); 118 119 try 120 { 121 for (;;) 122 { 123 DERObject obj = dIn.readObject(); 124 125 v.add(obj); 126 } 127 } 128 catch (EOFException ex) 129 { 130 return new DERConstructedSet(v); 131 } 132 case BOOLEAN: 133 return new DERBoolean(bytes); 134 case INTEGER: 135 return new DERInteger(bytes); 136 case ENUMERATED: 137 return new DEREnumerated(bytes); 138 case OBJECT_IDENTIFIER: 139 return new DERObjectIdentifier(bytes); 140 case BIT_STRING: 141 int padBits = bytes[0]; 142 byte[] data = new byte[bytes.length - 1]; 143 144 System.arraycopy(bytes, 1, data, 0, bytes.length - 1); 145 146 return new DERBitString(data, padBits); 147 case UTF8_STRING: 148 return new DERUTF8String(bytes); 149 case PRINTABLE_STRING: 150 return new DERPrintableString(bytes); 151 case IA5_STRING: 152 return new DERIA5String(bytes); 153 case T61_STRING: 154 return new DERT61String(bytes); 155 case VISIBLE_STRING: 156 return new DERVisibleString(bytes); 157 case UNIVERSAL_STRING: 158 return new DERUniversalString(bytes); 159 case GENERAL_STRING: 160 return new DERGeneralString(bytes); 161 case BMP_STRING: 162 return new DERBMPString(bytes); 163 case OCTET_STRING: 164 return new DEROctetString(bytes); 165 case UTC_TIME: 166 return new DERUTCTime(bytes); 167 case GENERALIZED_TIME: 168 return new DERGeneralizedTime(bytes); 169 default: 170 if ((tag & TAGGED) != 0) 174 { 175 if ((tag & 0x1f) == 0x1f) 176 { 177 throw new IOException("unsupported high tag encountered"); 178 } 179 180 if (bytes.length == 0) { 182 if ((tag & CONSTRUCTED) == 0) 183 { 184 return new DERTaggedObject(false, tag & 0x1f, new DERNull()); 185 } 186 else 187 { 188 return new DERTaggedObject(false, tag & 0x1f, new DERConstructedSequence()); 189 } 190 } 191 192 if ((tag & CONSTRUCTED) == 0) 196 { 197 return new DERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes)); 198 } 199 200 bIn = new ByteArrayInputStream(bytes); 201 dIn = new BERInputStream(bIn); 202 203 DEREncodable dObj = dIn.readObject(); 204 205 if (dIn.available() == 0) 210 { 211 return new DERTaggedObject(tag & 0x1f, dObj); 212 } 213 214 seq = new DERConstructedSequence(); 218 219 seq.addObject(dObj); 220 221 try 222 { 223 for (;;) 224 { 225 dObj = dIn.readObject(); 226 227 seq.addObject(dObj); 228 } 229 } 230 catch (EOFException ex) 231 { 232 } 234 235 return new DERTaggedObject(false, tag & 0x1f, seq); 236 } 237 238 return new DERUnknownTag(tag, bytes); 239 } 240 } 241 242 public DERObject readObject() 243 throws IOException 244 { 245 int tag = read(); 246 if (tag == -1) 247 { 248 throw new EOFException(); 249 } 250 251 int length = readLength(); 252 byte[] bytes = new byte[length]; 253 254 readFully(bytes); 255 256 return buildObject(tag, bytes); 257 } 258 } 259 | Popular Tags |