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