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