1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.ByteArrayOutputStream; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 66e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport org.bouncycastle.util.Arrays; 76e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class DERBitString 9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom extends ASN1Object 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam implements DERString 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] data; 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int padBits; 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return the correct number of pad bits for a bit string defined in 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * a 32 bit constant 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static protected int getPadBits( 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int bitString) 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int val = 0; 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 3; i >= 0; i--) 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // this may look a little odd, but if it isn't done like this pre jdk1.2 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // JVM's break! 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (i != 0) 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if ((bitString >> (i * 8)) != 0) 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam val = (bitString >> (i * 8)) & 0xFF; 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (bitString != 0) 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam val = bitString & 0xFF; 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (val == 0) 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return 7; 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int bits = 1; 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (((val <<= 1) & 0xFF) != 0) 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bits++; 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return 8 - bits; 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return the correct number of bytes for a bit string defined in 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * a 32 bit constant 68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static protected byte[] getBytes(int bitString) 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int bytes = 4; 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 3; i >= 1; i--) 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if ((bitString & (0xFF << (i * 8))) != 0) 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes--; 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] result = new byte[bytes]; 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i < bytes; i++) 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam result[i] = (byte) ((bitString >> (i * 8)) & 0xFF); 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return result; 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return a Bit String from the passed in object 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the object cannot be converted. 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static DERBitString getInstance( 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Object obj) 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj == null || obj instanceof DERBitString) 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (DERBitString)obj; 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return a Bit String from a tagged object. 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param obj the tagged object holding the object we want 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param explicit true if the object is meant to be explicitly 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * tagged false otherwise. 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the tagged object cannot 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * be converted. 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static DERBitString getInstance( 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1TaggedObject obj, 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean explicit) 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1196e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom DERObject o = obj.getObject(); 1206e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 1216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (explicit || o instanceof DERBitString) 1226e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 1236e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return getInstance(o); 1246e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 1256e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else 1266e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 1276e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return fromOctetString(((ASN1OctetString)o).getOctets()); 1286e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected DERBitString( 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte data, 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int padBits) 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.data = new byte[1]; 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.data[0] = data; 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.padBits = padBits; 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param data the octets making up the bit string. 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param padBits the number of extra bits at the end of the string. 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERBitString( 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] data, 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int padBits) 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.data = data; 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.padBits = padBits; 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERBitString( 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] data) 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this(data, 0); 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERBitString( 159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DEREncodable obj) 160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 163c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this.data = obj.getDERObject().getEncoded(ASN1Encodable.DER); 164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.padBits = 0; 165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IOException e) 167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("Error processing object : " + e.toString()); 169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public byte[] getBytes() 173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return data; 175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int getPadBits() 178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return padBits; 180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @return the value of the bit string as an int (truncating if necessary) 185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int intValue() 187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int value = 0; 189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != data.length && i != 4; i++) 191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam value |= (data[i] & 0xff) << (8 * i); 193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return value; 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam void encode( 199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DEROutputStream out) 200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] bytes = new byte[getBytes().length + 1]; 203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[0] = (byte)getPadBits(); 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1); 206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam out.writeEncoded(BIT_STRING, bytes); 208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int hashCode() 211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 212c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return padBits ^ Arrays.hashCode(data); 213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 214c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 215c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom protected boolean asn1Equals( 216c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom DERObject o) 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!(o instanceof DERBitString)) 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return false; 221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 223c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom DERBitString other = (DERBitString)o; 224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 225c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return this.padBits == other.padBits 226c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom && Arrays.areEqual(this.data, other.data); 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String getString() 230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam StringBuffer buf = new StringBuffer("#"); 232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1OutputStream aOut = new ASN1OutputStream(bOut); 234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam aOut.writeObject(this); 238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IOException e) 240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new RuntimeException("internal error encoding BitString"); 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] string = bOut.toByteArray(); 245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != string.length; i++) 247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 248c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom buf.append(table[(string[i] >>> 4) & 0xf]); 249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam buf.append(table[string[i] & 0xf]); 250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return buf.toString(); 253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String toString() 256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return getString(); 258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 2596e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2606e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom static DERBitString fromOctetString(byte[] bytes) 2616e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2626e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (bytes.length < 1) 2636e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2646e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom throw new IllegalArgumentException("truncated BIT STRING detected"); 2656e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 2666e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2676e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom int padBits = bytes[0]; 2686e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom byte[] data = new byte[bytes.length - 1]; 2696e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2706e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (data.length != 0) 2716e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2726e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom System.arraycopy(bytes, 1, data, 0, bytes.length - 1); 2736e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 2746e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2756e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new DERBitString(data, padBits); 2766e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 278