1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.ByteArrayOutputStream; 44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.EOFException; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 64c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.InputStream; 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 86e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport org.bouncycastle.util.Arrays; 94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.util.io.Streams; 106e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class DERBitString 124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom extends ASN1Primitive 134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom implements ASN1String 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] data; 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected int padBits; 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return the correct number of pad bits for a bit string defined in 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * a 32 bit constant 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static protected int getPadBits( 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int bitString) 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int val = 0; 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 3; i >= 0; i--) 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // this may look a little odd, but if it isn't done like this pre jdk1.2 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // JVM's break! 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (i != 0) 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if ((bitString >> (i * 8)) != 0) 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam val = (bitString >> (i * 8)) & 0xFF; 39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (bitString != 0) 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam val = bitString & 0xFF; 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (val == 0) 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return 7; 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int bits = 1; 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (((val <<= 1) & 0xFF) != 0) 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bits++; 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return 8 - bits; 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return the correct number of bytes for a bit string defined in 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * a 32 bit constant 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static protected byte[] getBytes(int bitString) 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int bytes = 4; 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 3; i >= 1; i--) 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if ((bitString & (0xFF << (i * 8))) != 0) 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes--; 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] result = new byte[bytes]; 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i < bytes; i++) 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam result[i] = (byte) ((bitString >> (i * 8)) & 0xFF); 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return result; 91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return a Bit String from the passed in object 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the object cannot be converted. 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static DERBitString getInstance( 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Object obj) 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj == null || obj instanceof DERBitString) 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (DERBitString)obj; 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return a Bit String from a tagged object. 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param obj the tagged object holding the object we want 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param explicit true if the object is meant to be explicitly 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * tagged false otherwise. 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the tagged object cannot 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * be converted. 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static DERBitString getInstance( 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1TaggedObject obj, 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean explicit) 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive o = obj.getObject(); 1236e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 1246e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (explicit || o instanceof DERBitString) 1256e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 1266e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return getInstance(o); 1276e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 1286e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else 1296e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 1306e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return fromOctetString(((ASN1OctetString)o).getOctets()); 1316e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected DERBitString( 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte data, 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int padBits) 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.data = new byte[1]; 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.data[0] = data; 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.padBits = padBits; 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param data the octets making up the bit string. 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param padBits the number of extra bits at the end of the string. 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERBitString( 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] data, 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int padBits) 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.data = data; 152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.padBits = padBits; 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERBitString( 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] data) 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this(data, 0); 159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERBitString( 16270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom int value) 163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 16470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom this.data = getBytes(value); 16570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom this.padBits = getPadBits(value); 16670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 16770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom 16870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom public DERBitString( 16970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom ASN1Encodable obj) 17070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom throws IOException 17170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 17270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom this.data = obj.toASN1Primitive().getEncoded(ASN1Encoding.DER); 17370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom this.padBits = 0; 174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public byte[] getBytes() 177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return data; 179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int getPadBits() 182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return padBits; 184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @return the value of the bit string as an int (truncating if necessary) 189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int intValue() 191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int value = 0; 193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != data.length && i != 4; i++) 195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam value |= (data[i] & 0xff) << (8 * i); 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return value; 200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 2014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 2024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean isConstructed() 2034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 2044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return false; 2054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 2064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 2074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int encodedLength() 2084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 2094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1; 2104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 2114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam void encode( 2134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1OutputStream out) 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] bytes = new byte[getBytes().length + 1]; 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bytes[0] = (byte)getPadBits(); 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1); 220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 2214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeEncoded(BERTags.BIT_STRING, bytes); 222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int hashCode() 225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 226c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return padBits ^ Arrays.hashCode(data); 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 228c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 229c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom protected boolean asn1Equals( 2304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive o) 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!(o instanceof DERBitString)) 233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return false; 235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 237c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom DERBitString other = (DERBitString)o; 238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 239c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return this.padBits == other.padBits 240c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom && Arrays.areEqual(this.data, other.data); 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String getString() 244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam StringBuffer buf = new StringBuffer("#"); 246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1OutputStream aOut = new ASN1OutputStream(bOut); 248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam aOut.writeObject(this); 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IOException e) 254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new RuntimeException("internal error encoding BitString"); 256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] string = bOut.toByteArray(); 259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != string.length; i++) 261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 262c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom buf.append(table[(string[i] >>> 4) & 0xf]); 263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam buf.append(table[string[i] & 0xf]); 264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return buf.toString(); 267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String toString() 270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return getString(); 272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 2736e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2746e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom static DERBitString fromOctetString(byte[] bytes) 2756e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2766e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (bytes.length < 1) 2776e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2786e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom throw new IllegalArgumentException("truncated BIT STRING detected"); 2796e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 2806e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2816e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom int padBits = bytes[0]; 2826e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom byte[] data = new byte[bytes.length - 1]; 2836e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2846e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (data.length != 0) 2856e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 2866e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom System.arraycopy(bytes, 1, data, 0, bytes.length - 1); 2876e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 2886e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 2896e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new DERBitString(data, padBits); 2906e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 2914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 2924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom static DERBitString fromInputStream(int length, InputStream stream) 2934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throws IOException 2944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 2954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (length < 1) 2964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 2974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throw new IllegalArgumentException("truncated BIT STRING detected"); 2984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 2994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int padBits = stream.read(); 3014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom byte[] data = new byte[length - 1]; 3024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (data.length != 0) 3044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (Streams.readFully(stream, data) != data.length) 3064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 3074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom throw new EOFException("EOF encountered in middle of BIT STRING"); 3084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 3104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 3114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return new DERBitString(data, padBits); 3124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 314