• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.asn1;
2 
3 import java.io.IOException;
4 import java.math.BigInteger;
5 
6 import org.bouncycastle.util.Arrays;
7 
8 /**
9  * Class representing the ASN.1 ENUMERATED type.
10  */
11 public class ASN1Enumerated
12     extends ASN1Primitive
13 {
14     private final byte[] bytes;
15 
16     /**
17      * return an enumerated from the passed in object
18      *
19      * @param obj an ASN1Enumerated or an object that can be converted into one.
20      * @exception IllegalArgumentException if the object cannot be converted.
21      * @return an ASN1Enumerated instance, or null.
22      */
getInstance( Object obj)23     public static ASN1Enumerated getInstance(
24         Object  obj)
25     {
26         if (obj == null || obj instanceof ASN1Enumerated)
27         {
28             return (ASN1Enumerated)obj;
29         }
30 
31         if (obj instanceof byte[])
32         {
33             try
34             {
35                 return (ASN1Enumerated)fromByteArray((byte[])obj);
36             }
37             catch (Exception e)
38             {
39                 throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
40             }
41         }
42 
43         throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
44     }
45 
46     /**
47      * return an Enumerated from a tagged object.
48      *
49      * @param obj the tagged object holding the object we want
50      * @param explicit true if the object is meant to be explicitly
51      *              tagged false otherwise.
52      * @exception IllegalArgumentException if the tagged object cannot
53      *               be converted.
54      * @return an ASN1Enumerated instance, or null.
55      */
getInstance( ASN1TaggedObject obj, boolean explicit)56     public static ASN1Enumerated getInstance(
57         ASN1TaggedObject obj,
58         boolean          explicit)
59     {
60         ASN1Primitive o = obj.getObject();
61 
62         if (explicit || o instanceof ASN1Enumerated)
63         {
64             return getInstance(o);
65         }
66         else
67         {
68             return fromOctetString(((ASN1OctetString)o).getOctets());
69         }
70     }
71 
72     /**
73      * Constructor from int.
74      *
75      * @param value the value of this enumerated.
76      */
ASN1Enumerated( int value)77     public ASN1Enumerated(
78         int         value)
79     {
80         bytes = BigInteger.valueOf(value).toByteArray();
81     }
82 
83     /**
84      * Constructor from BigInteger
85      *
86      * @param value the value of this enumerated.
87      */
ASN1Enumerated( BigInteger value)88     public ASN1Enumerated(
89         BigInteger   value)
90     {
91         bytes = value.toByteArray();
92     }
93 
94     /**
95      * Constructor from encoded BigInteger.
96      *
97      * @param bytes the value of this enumerated as an encoded BigInteger (signed).
98      */
ASN1Enumerated( byte[] bytes)99     public ASN1Enumerated(
100         byte[]   bytes)
101     {
102         if (bytes.length > 1)
103         {
104             if (bytes[0] == 0 && (bytes[1] & 0x80) == 0)
105             {
106                 throw new IllegalArgumentException("malformed enumerated");
107             }
108             if (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0)
109             {
110                 throw new IllegalArgumentException("malformed enumerated");
111             }
112         }
113         this.bytes = Arrays.clone(bytes);
114     }
115 
getValue()116     public BigInteger getValue()
117     {
118         return new BigInteger(bytes);
119     }
120 
isConstructed()121     boolean isConstructed()
122     {
123         return false;
124     }
125 
encodedLength()126     int encodedLength()
127     {
128         return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
129     }
130 
encode( ASN1OutputStream out)131     void encode(
132         ASN1OutputStream out)
133         throws IOException
134     {
135         out.writeEncoded(BERTags.ENUMERATED, bytes);
136     }
137 
asn1Equals( ASN1Primitive o)138     boolean asn1Equals(
139         ASN1Primitive  o)
140     {
141         if (!(o instanceof ASN1Enumerated))
142         {
143             return false;
144         }
145 
146         ASN1Enumerated other = (ASN1Enumerated)o;
147 
148         return Arrays.areEqual(this.bytes, other.bytes);
149     }
150 
hashCode()151     public int hashCode()
152     {
153         return Arrays.hashCode(bytes);
154     }
155 
156     private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
157 
fromOctetString(byte[] enc)158     static ASN1Enumerated fromOctetString(byte[] enc)
159     {
160         if (enc.length > 1)
161         {
162             return new ASN1Enumerated(enc);
163         }
164 
165         if (enc.length == 0)
166         {
167             throw new IllegalArgumentException("ENUMERATED has zero length");
168         }
169         int value = enc[0] & 0xff;
170 
171         if (value >= cache.length)
172         {
173             return new ASN1Enumerated(Arrays.clone(enc));
174         }
175 
176         ASN1Enumerated possibleMatch = cache[value];
177 
178         if (possibleMatch == null)
179         {
180             possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc));
181         }
182 
183         return possibleMatch;
184     }
185 }
186