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