DEREnumerated.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1e62c1185bee05facc25d1d725434f517261d308bChris Lattnerpackage org.bouncycastle.asn1;
2e62c1185bee05facc25d1d725434f517261d308bChris Lattner
3e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport java.io.IOException;
4e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport java.math.BigInteger;
5e62c1185bee05facc25d1d725434f517261d308bChris Lattner
6e62c1185bee05facc25d1d725434f517261d308bChris Lattnerimport org.bouncycastle.util.Arrays;
7e62c1185bee05facc25d1d725434f517261d308bChris Lattner
8e62c1185bee05facc25d1d725434f517261d308bChris Lattnerpublic class DEREnumerated
9e62c1185bee05facc25d1d725434f517261d308bChris Lattner    extends ASN1Primitive
10e62c1185bee05facc25d1d725434f517261d308bChris Lattner{
11e62c1185bee05facc25d1d725434f517261d308bChris Lattner    byte[]      bytes;
12e62c1185bee05facc25d1d725434f517261d308bChris Lattner
13b5b3c6fc0147b2e59b45f7f2882c7c615bb765aeChris Lattner    /**
14028936ada14335bb04f377d46a6261dc4c66dafdJohn Criswell     * return an integer from the passed in object
15e62c1185bee05facc25d1d725434f517261d308bChris Lattner     *
16e62c1185bee05facc25d1d725434f517261d308bChris Lattner     * @exception IllegalArgumentException if the object cannot be converted.
17e62c1185bee05facc25d1d725434f517261d308bChris Lattner     */
18e62c1185bee05facc25d1d725434f517261d308bChris Lattner    public static ASN1Enumerated getInstance(
19e62c1185bee05facc25d1d725434f517261d308bChris Lattner        Object  obj)
20e62c1185bee05facc25d1d725434f517261d308bChris Lattner    {
21e62c1185bee05facc25d1d725434f517261d308bChris Lattner        if (obj == null || obj instanceof ASN1Enumerated)
22e62c1185bee05facc25d1d725434f517261d308bChris Lattner        {
23b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner            return (ASN1Enumerated)obj;
24b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner        }
25a1651900e1772b05afd2280308e9acc5a58cefb8Chris Lattner
26b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner        if (obj instanceof DEREnumerated)
27e62c1185bee05facc25d1d725434f517261d308bChris Lattner        {
28e62c1185bee05facc25d1d725434f517261d308bChris Lattner            return new ASN1Enumerated(((DEREnumerated)obj).getValue());
29e62c1185bee05facc25d1d725434f517261d308bChris Lattner        }
30e62c1185bee05facc25d1d725434f517261d308bChris Lattner
31e62c1185bee05facc25d1d725434f517261d308bChris Lattner        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
32e62c1185bee05facc25d1d725434f517261d308bChris Lattner    }
33e62c1185bee05facc25d1d725434f517261d308bChris Lattner
34e62c1185bee05facc25d1d725434f517261d308bChris Lattner    /**
35e62c1185bee05facc25d1d725434f517261d308bChris Lattner     * return an Enumerated from a tagged object.
36e62c1185bee05facc25d1d725434f517261d308bChris Lattner     *
37e62c1185bee05facc25d1d725434f517261d308bChris Lattner     * @param obj the tagged object holding the object we want
38e62c1185bee05facc25d1d725434f517261d308bChris Lattner     * @param explicit true if the object is meant to be explicitly
39e62c1185bee05facc25d1d725434f517261d308bChris Lattner     *              tagged false otherwise.
40e62c1185bee05facc25d1d725434f517261d308bChris Lattner     * @exception IllegalArgumentException if the tagged object cannot
41e62c1185bee05facc25d1d725434f517261d308bChris Lattner     *               be converted.
42e62c1185bee05facc25d1d725434f517261d308bChris Lattner     */
43e62c1185bee05facc25d1d725434f517261d308bChris Lattner    public static DEREnumerated getInstance(
44b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner        ASN1TaggedObject obj,
45b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner        boolean          explicit)
46b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner    {
47b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner        ASN1Primitive o = obj.getObject();
48b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner
49b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner        if (explicit || o instanceof DEREnumerated)
50b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner        {
51e62c1185bee05facc25d1d725434f517261d308bChris Lattner            return getInstance(o);
52e62c1185bee05facc25d1d725434f517261d308bChris Lattner        }
53e62c1185bee05facc25d1d725434f517261d308bChris Lattner        else
54e62c1185bee05facc25d1d725434f517261d308bChris Lattner        {
55e62c1185bee05facc25d1d725434f517261d308bChris Lattner            return fromOctetString(((ASN1OctetString)o).getOctets());
56e62c1185bee05facc25d1d725434f517261d308bChris Lattner        }
57e62c1185bee05facc25d1d725434f517261d308bChris Lattner    }
58e62c1185bee05facc25d1d725434f517261d308bChris Lattner
59e62c1185bee05facc25d1d725434f517261d308bChris Lattner    public DEREnumerated(
60e62c1185bee05facc25d1d725434f517261d308bChris Lattner        int         value)
6107278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner    {
6207278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner        bytes = BigInteger.valueOf(value).toByteArray();
6307278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner    }
64e62c1185bee05facc25d1d725434f517261d308bChris Lattner
65e62c1185bee05facc25d1d725434f517261d308bChris Lattner    public DEREnumerated(
66e62c1185bee05facc25d1d725434f517261d308bChris Lattner        BigInteger   value)
67e62c1185bee05facc25d1d725434f517261d308bChris Lattner    {
68e62c1185bee05facc25d1d725434f517261d308bChris Lattner        bytes = value.toByteArray();
69b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner    }
707331ab9d56cb7007b1f5c92c90cd0d18a0af1fe3Chris Lattner
71e62c1185bee05facc25d1d725434f517261d308bChris Lattner    public DEREnumerated(
72e62c1185bee05facc25d1d725434f517261d308bChris Lattner        byte[]   bytes)
73e62c1185bee05facc25d1d725434f517261d308bChris Lattner    {
74e62c1185bee05facc25d1d725434f517261d308bChris Lattner        this.bytes = bytes;
7507278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner    }
7607278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner
7707278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner    public BigInteger getValue()
78e62c1185bee05facc25d1d725434f517261d308bChris Lattner    {
79e62c1185bee05facc25d1d725434f517261d308bChris Lattner        return new BigInteger(bytes);
80e62c1185bee05facc25d1d725434f517261d308bChris Lattner    }
81e62c1185bee05facc25d1d725434f517261d308bChris Lattner
82e62c1185bee05facc25d1d725434f517261d308bChris Lattner    boolean isConstructed()
83e62c1185bee05facc25d1d725434f517261d308bChris Lattner    {
84e62c1185bee05facc25d1d725434f517261d308bChris Lattner        return false;
85e62c1185bee05facc25d1d725434f517261d308bChris Lattner    }
86e62c1185bee05facc25d1d725434f517261d308bChris Lattner
87e62c1185bee05facc25d1d725434f517261d308bChris Lattner    int encodedLength()
88e62c1185bee05facc25d1d725434f517261d308bChris Lattner    {
89b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner        return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
90e62c1185bee05facc25d1d725434f517261d308bChris Lattner    }
91e62c1185bee05facc25d1d725434f517261d308bChris Lattner
92e62c1185bee05facc25d1d725434f517261d308bChris Lattner    void encode(
93e62c1185bee05facc25d1d725434f517261d308bChris Lattner        ASN1OutputStream out)
9407278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner        throws IOException
9507278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner    {
9607278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner        out.writeEncoded(BERTags.ENUMERATED, bytes);
97e62c1185bee05facc25d1d725434f517261d308bChris Lattner    }
98e62c1185bee05facc25d1d725434f517261d308bChris Lattner
99e62c1185bee05facc25d1d725434f517261d308bChris Lattner    boolean asn1Equals(
100e62c1185bee05facc25d1d725434f517261d308bChris Lattner        ASN1Primitive  o)
101b45b3b3cd14faaf5a3ea5226af7e1e3cd653e6cbChris Lattner    {
102e62c1185bee05facc25d1d725434f517261d308bChris Lattner        if (!(o instanceof DEREnumerated))
103e62c1185bee05facc25d1d725434f517261d308bChris Lattner        {
104e62c1185bee05facc25d1d725434f517261d308bChris Lattner            return false;
105e62c1185bee05facc25d1d725434f517261d308bChris Lattner        }
10607278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner
10707278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner        DEREnumerated other = (DEREnumerated)o;
108e62c1185bee05facc25d1d725434f517261d308bChris Lattner
109e62c1185bee05facc25d1d725434f517261d308bChris Lattner        return Arrays.areEqual(this.bytes, other.bytes);
110e62c1185bee05facc25d1d725434f517261d308bChris Lattner    }
111f1b36f9a71eb267f04b7bd3a32aca9bc69f71e97Chris Lattner
112e62c1185bee05facc25d1d725434f517261d308bChris Lattner    public int hashCode()
113e62c1185bee05facc25d1d725434f517261d308bChris Lattner    {
114e62c1185bee05facc25d1d725434f517261d308bChris Lattner        return Arrays.hashCode(bytes);
11507278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner    }
11607278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner
11707278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner    private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
118e62c1185bee05facc25d1d725434f517261d308bChris Lattner
119e62c1185bee05facc25d1d725434f517261d308bChris Lattner    static ASN1Enumerated fromOctetString(byte[] enc)
120e62c1185bee05facc25d1d725434f517261d308bChris Lattner    {
121e62c1185bee05facc25d1d725434f517261d308bChris Lattner        if (enc.length > 1)
122f1b36f9a71eb267f04b7bd3a32aca9bc69f71e97Chris Lattner        {
123f1b36f9a71eb267f04b7bd3a32aca9bc69f71e97Chris Lattner            return new ASN1Enumerated(Arrays.clone(enc));
124f1b36f9a71eb267f04b7bd3a32aca9bc69f71e97Chris Lattner        }
125f1b36f9a71eb267f04b7bd3a32aca9bc69f71e97Chris Lattner
126f1b36f9a71eb267f04b7bd3a32aca9bc69f71e97Chris Lattner        if (enc.length == 0)
127e62c1185bee05facc25d1d725434f517261d308bChris Lattner        {
128e62c1185bee05facc25d1d725434f517261d308bChris Lattner            throw new IllegalArgumentException("ENUMERATED has zero length");
129f1b36f9a71eb267f04b7bd3a32aca9bc69f71e97Chris Lattner        }
130e62c1185bee05facc25d1d725434f517261d308bChris Lattner        int value = enc[0] & 0xff;
131e62c1185bee05facc25d1d725434f517261d308bChris Lattner
132e62c1185bee05facc25d1d725434f517261d308bChris Lattner        if (value >= cache.length)
133e62c1185bee05facc25d1d725434f517261d308bChris Lattner        {
13407278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner            return new ASN1Enumerated(Arrays.clone(enc));
13507278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner        }
13607278e48dc27d8ac64b5ff7ed6361536c2f38ea1Chris Lattner
137e62c1185bee05facc25d1d725434f517261d308bChris Lattner        ASN1Enumerated possibleMatch = cache[value];
138e62c1185bee05facc25d1d725434f517261d308bChris Lattner
139e62c1185bee05facc25d1d725434f517261d308bChris Lattner        if (possibleMatch == null)
140e62c1185bee05facc25d1d725434f517261d308bChris Lattner        {
141e62c1185bee05facc25d1d725434f517261d308bChris Lattner            possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc));
142a1651900e1772b05afd2280308e9acc5a58cefb8Chris Lattner        }
143a1651900e1772b05afd2280308e9acc5a58cefb8Chris Lattner
144e62c1185bee05facc25d1d725434f517261d308bChris Lattner        return possibleMatch;
145ce3d64025b32d10dbaf9c77f5b1b56a09bc88f82Chris Lattner    }
146ce3d64025b32d10dbaf9c77f5b1b56a09bc88f82Chris Lattner}
147e62c1185bee05facc25d1d725434f517261d308bChris Lattner