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(
1624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable  obj)
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
1664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.data = obj.toASN1Primitive().getEncoded(ASN1Encoding.DER);
167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.padBits = 0;
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (IOException e)
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("Error processing object : " + e.toString());
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public byte[] getBytes()
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return data;
178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int getPadBits()
181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return padBits;
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the value of the bit string as an int (truncating if necessary)
188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int intValue()
190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int value = 0;
192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 0; i != data.length && i != 4; i++)
194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            value |= (data[i] & 0xff) << (8 * i);
196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return value;
199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
2004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    boolean isConstructed()
2024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return false;
2044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
2054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    int encodedLength()
2074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
2094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
2104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    void encode(
2124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1OutputStream  out)
213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException
214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  bytes = new byte[getBytes().length + 1];
216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        bytes[0] = (byte)getPadBits();
218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1);
219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
2204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        out.writeEncoded(BERTags.BIT_STRING, bytes);
221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int hashCode()
224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
225c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return padBits ^ Arrays.hashCode(data);
226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
227c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
228c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    protected boolean asn1Equals(
2294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Primitive  o)
230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (!(o instanceof DERBitString))
232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
236c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        DERBitString other = (DERBitString)o;
237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
238c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return this.padBits == other.padBits
239c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            && Arrays.areEqual(this.data, other.data);
240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getString()
243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        StringBuffer          buf = new StringBuffer("#");
245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1OutputStream      aOut = new ASN1OutputStream(bOut);
247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            aOut.writeObject(this);
251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (IOException e)
253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam           throw new RuntimeException("internal error encoding BitString");
255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]    string = bOut.toByteArray();
258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 0; i != string.length; i++)
260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
261c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(table[(string[i] >>> 4) & 0xf]);
262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(table[string[i] & 0xf]);
263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return buf.toString();
266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String toString()
269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return getString();
271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
2726e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2736e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    static DERBitString fromOctetString(byte[] bytes)
2746e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    {
2756e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        if (bytes.length < 1)
2766e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        {
2776e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            throw new IllegalArgumentException("truncated BIT STRING detected");
2786e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        }
2796e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2806e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        int padBits = bytes[0];
2816e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        byte[] data = new byte[bytes.length - 1];
2826e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2836e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        if (data.length != 0)
2846e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        {
2856e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
2866e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        }
2876e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2886e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        return new DERBitString(data, padBits);
2896e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    }
2904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    static DERBitString fromInputStream(int length, InputStream stream)
2924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException
2934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (length < 1)
2954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            throw new IllegalArgumentException("truncated BIT STRING detected");
2974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int padBits = stream.read();
3004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[] data = new byte[length - 1];
3014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (data.length != 0)
3034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (Streams.readFully(stream, data) != data.length)
3054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
3064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                throw new EOFException("EOF encountered in middle of BIT STRING");
3074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
3084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return new DERBitString(data, padBits);
3114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
313