1 19 20 package com.maverick.crypto.asn1; 21 22 import java.io.ByteArrayOutputStream ; 23 import java.io.EOFException ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.util.Vector ; 27 28 public class BERInputStream 29 extends DERInputStream 30 { 31 private DERObject END_OF_STREAM = new DERObject() { 32 void encode( 33 DEROutputStream out) 34 throws IOException 35 { 36 throw new IOException ("Eeek!"); 37 } 38 39 }; 40 public BERInputStream( 41 InputStream is) 42 { 43 super(is); 44 } 45 46 49 private byte[] readIndefiniteLengthFully() 50 throws IOException 51 { 52 ByteArrayOutputStream bOut = new ByteArrayOutputStream (); 53 int b, b1; 54 55 b1 = read(); 56 57 while ((b = read()) >= 0) 58 { 59 if (b1 == 0 && b == 0) 60 { 61 break; 62 } 63 64 bOut.write(b1); 65 b1 = b; 66 } 67 68 return bOut.toByteArray(); 69 } 70 71 private BERConstructedOctetString buildConstructedOctetString() 72 throws IOException 73 { 74 Vector octs = new Vector (); 75 76 for (;;) 77 { 78 DERObject o = readObject(); 79 80 if (o == END_OF_STREAM) 81 { 82 break; 83 } 84 85 octs.addElement(o); 86 } 87 88 return new BERConstructedOctetString(octs); 89 } 90 91 public DERObject readObject() 92 throws IOException 93 { 94 int tag = read(); 95 if (tag == -1) 96 { 97 throw new EOFException (); 98 } 99 100 int length = readLength(); 101 102 if (length < 0) { 104 switch (tag) 105 { 106 case NULL: 107 return null; 108 case SEQUENCE | CONSTRUCTED: 109 BERConstructedSequence seq = new BERConstructedSequence(); 110 111 for (;;) 112 { 113 DERObject obj = readObject(); 114 115 if (obj == END_OF_STREAM) 116 { 117 break; 118 } 119 120 seq.addObject(obj); 121 } 122 return seq; 123 case OCTET_STRING | CONSTRUCTED: 124 return buildConstructedOctetString(); 125 case SET | CONSTRUCTED: 126 ASN1EncodableVector v = new ASN1EncodableVector(); 127 128 for (;;) 129 { 130 DERObject obj = readObject(); 131 132 if (obj == END_OF_STREAM) 133 { 134 break; 135 } 136 137 v.add(obj); 138 } 139 return new BERSet(v); 140 default: 141 if ((tag & TAGGED) != 0) 145 { 146 if ((tag & 0x1f) == 0x1f) 147 { 148 throw new IOException ("unsupported high tag encountered"); 149 } 150 151 if ((tag & CONSTRUCTED) == 0) 155 { 156 byte[] bytes = readIndefiniteLengthFully(); 157 158 return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes)); 159 } 160 161 DERObject dObj = readObject(); 165 166 if (dObj == END_OF_STREAM) { 168 return new DERTaggedObject(tag & 0x1f); 169 } 170 171 DERObject next = readObject(); 172 173 if (next == END_OF_STREAM) 178 { 179 return new BERTaggedObject(tag & 0x1f, dObj); 180 } 181 182 seq = new BERConstructedSequence(); 186 187 seq.addObject(dObj); 188 189 do 190 { 191 seq.addObject(next); 192 next = readObject(); 193 } 194 while (next != END_OF_STREAM); 195 196 return new BERTaggedObject(false, tag & 0x1f, seq); 197 } 198 199 throw new IOException ("unknown BER object encountered"); 200 } 201 } 202 else 203 { 204 if (tag == 0 && length == 0) { 206 return END_OF_STREAM; 207 } 208 209 byte[] bytes = new byte[length]; 210 211 readFully(bytes); 212 213 return buildObject(tag, bytes); 214 } 215 } 216 } 217 | Popular Tags |