1 19 20 package com.maverick.crypto.asn1; 21 22 import java.io.ByteArrayOutputStream ; 23 import java.io.IOException ; 24 25 public class DERBitString 26 extends DERObject 27 implements DERString 28 { 29 private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 30 31 protected byte[] data; 32 protected int padBits; 33 34 38 static protected int getPadBits( 39 int bitString) 40 { 41 int val = 0; 42 for (int i = 3; i >= 0; i--) 43 { 44 if (i != 0) 49 { 50 if ((bitString >> (i * 8)) != 0) 51 { 52 val = (bitString >> (i * 8)) & 0xFF; 53 break; 54 } 55 } 56 else 57 { 58 if (bitString != 0) 59 { 60 val = bitString & 0xFF; 61 break; 62 } 63 } 64 } 65 66 if (val == 0) 67 { 68 return 7; 69 } 70 71 72 int bits = 1; 73 74 while (((val <<= 1) & 0xFF) != 0) 75 { 76 bits++; 77 } 78 79 return 8 - bits; 80 } 81 82 86 static protected byte[] getBytes(int bitString) 87 { 88 int bytes = 4; 89 for (int i = 3; i >= 1; i--) 90 { 91 if ((bitString & (0xFF << (i * 8))) != 0) 92 { 93 break; 94 } 95 bytes--; 96 } 97 98 byte[] result = new byte[bytes]; 99 for (int i = 0; i < bytes; i++) 100 { 101 result[i] = (byte) ((bitString >> (i * 8)) & 0xFF); 102 } 103 104 return result; 105 } 106 107 112 public static DERBitString getInstance( 113 Object obj) 114 { 115 if (obj == null || obj instanceof DERBitString) 116 { 117 return (DERBitString)obj; 118 } 119 120 if (obj instanceof ASN1OctetString) 121 { 122 byte[] bytes = ((ASN1OctetString)obj).getOctets(); 123 int padBits = bytes[0]; 124 byte[] data = new byte[bytes.length - 1]; 125 126 System.arraycopy(bytes, 1, data, 0, bytes.length - 1); 127 128 return new DERBitString(data, padBits); 129 } 130 131 if (obj instanceof ASN1TaggedObject) 132 { 133 return getInstance(((ASN1TaggedObject)obj).getObject()); 134 } 135 136 throw new IllegalArgumentException ("illegal object in getInstance: " + obj.getClass().getName()); 137 } 138 139 148 public static DERBitString getInstance( 149 ASN1TaggedObject obj, 150 boolean explicit) 151 { 152 return getInstance(obj.getObject()); 153 } 154 155 protected DERBitString( 156 byte data, 157 int padBits) 158 { 159 this.data = new byte[1]; 160 this.data[0] = data; 161 this.padBits = padBits; 162 } 163 164 168 public DERBitString( 169 byte[] data, 170 int padBits) 171 { 172 this.data = data; 173 this.padBits = padBits; 174 } 175 176 public DERBitString( 177 byte[] data) 178 { 179 this(data, 0); 180 } 181 182 public DERBitString( 183 DEREncodable obj) 184 { 185 try 186 { 187 ByteArrayOutputStream bOut = new ByteArrayOutputStream (); 188 DEROutputStream dOut = new DEROutputStream(bOut); 189 190 dOut.writeObject(obj); 191 dOut.close(); 192 193 this.data = bOut.toByteArray(); 194 this.padBits = 0; 195 } 196 catch (IOException e) 197 { 198 throw new IllegalArgumentException ("Error processing object : " + e.toString()); 199 } 200 } 201 202 public byte[] getBytes() 203 { 204 return data; 205 } 206 207 public int getPadBits() 208 { 209 return padBits; 210 } 211 212 void encode( 213 DEROutputStream out) 214 throws IOException 215 { 216 byte[] bytes = new byte[getBytes().length + 1]; 217 218 bytes[0] = (byte)getPadBits(); 219 System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1); 220 221 out.writeEncoded(BIT_STRING, bytes); 222 } 223 224 public int hashCode() 225 { 226 int value = 0; 227 228 for (int i = 0; i != data.length; i++) 229 { 230 value ^= (data[i] & 0xff) << (i % 4); 231 } 232 233 return value; 234 } 235 236 public boolean equals( 237 Object o) 238 { 239 if (o == null || !(o instanceof DERBitString)) 240 { 241 return false; 242 } 243 244 DERBitString other = (DERBitString)o; 245 246 if (data.length != other.data.length) 247 { 248 return false; 249 } 250 251 for (int i = 0; i != data.length; i++) 252 { 253 if (data[i] != other.data[i]) 254 { 255 return false; 256 } 257 } 258 259 return (padBits == other.padBits); 260 } 261 262 public String getString() 263 { 264 StringBuffer buf = new StringBuffer ("#"); 265 ByteArrayOutputStream bOut = new ByteArrayOutputStream (); 266 ASN1OutputStream aOut = new ASN1OutputStream(bOut); 267 268 try 269 { 270 aOut.writeObject(this); 271 } 272 catch (IOException e) 273 { 274 throw new RuntimeException ("internal error encoding BitString"); 275 } 276 277 byte[] string = bOut.toByteArray(); 278 279 for (int i = 0; i != string.length; i++) 280 { 281 buf.append(table[(string[i] >>> 4) % 0xf]); 282 buf.append(table[string[i] & 0xf]); 283 } 284 285 return buf.toString(); 286 } 287 } 288 | Popular Tags |