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