Extensions.java revision a198e1ecc615e26a167d0f2dca9fa7e5fc62de10
1package org.bouncycastle.asn1.x509;
2
3import java.util.Enumeration;
4import java.util.Hashtable;
5import java.util.Vector;
6
7import org.bouncycastle.asn1.ASN1Encodable;
8import org.bouncycastle.asn1.ASN1EncodableVector;
9import org.bouncycastle.asn1.ASN1Object;
10import org.bouncycastle.asn1.ASN1ObjectIdentifier;
11import org.bouncycastle.asn1.ASN1Primitive;
12import org.bouncycastle.asn1.ASN1Sequence;
13import org.bouncycastle.asn1.ASN1TaggedObject;
14import org.bouncycastle.asn1.DERSequence;
15
16public class Extensions
17    extends ASN1Object
18{
19    private Hashtable extensions = new Hashtable();
20    private Vector ordering = new Vector();
21
22    public static Extensions getInstance(
23        ASN1TaggedObject obj,
24        boolean explicit)
25    {
26        return getInstance(ASN1Sequence.getInstance(obj, explicit));
27    }
28
29    public static Extensions getInstance(
30        Object obj)
31    {
32        if (obj instanceof Extensions)
33        {
34            return (Extensions)obj;
35        }
36        else if (obj != null)
37        {
38            return new Extensions(ASN1Sequence.getInstance(obj));
39        }
40
41        return null;
42    }
43
44    /**
45     * Constructor from ASN1Sequence.
46     * <p/>
47     * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString)
48     */
49    private Extensions(
50        ASN1Sequence seq)
51    {
52        Enumeration e = seq.getObjects();
53
54        while (e.hasMoreElements())
55        {
56            Extension ext = Extension.getInstance(e.nextElement());
57
58            extensions.put(ext.getExtnId(), ext);
59            ordering.addElement(ext.getExtnId());
60        }
61    }
62
63    /**
64     * Base Constructor
65     *
66     * @param extension a single extension.
67     */
68    public Extensions(
69        Extension extension)
70    {
71        this.ordering.addElement(extension.getExtnId());
72        this.extensions.put(extension.getExtnId(), extension);
73    }
74
75    /**
76     * Base Constructor
77     *
78     * @param extensions an array of extensions.
79     */
80    public Extensions(
81        Extension[] extensions)
82    {
83        for (int i = 0; i != extensions.length; i++)
84        {
85            Extension ext = extensions[i];
86
87            this.ordering.addElement(ext.getExtnId());
88            this.extensions.put(ext.getExtnId(), ext);
89        }
90    }
91
92    /**
93     * return an Enumeration of the extension field's object ids.
94     */
95    public Enumeration oids()
96    {
97        return ordering.elements();
98    }
99
100    /**
101     * return the extension represented by the object identifier
102     * passed in.
103     *
104     * @return the extension if it's present, null otherwise.
105     */
106    public Extension getExtension(
107        ASN1ObjectIdentifier oid)
108    {
109        return (Extension)extensions.get(oid);
110    }
111
112    /**
113     * return the parsed value of the extension represented by the object identifier
114     * passed in.
115     *
116     * @return the parsed value of the extension if it's present, null otherwise.
117     */
118    public ASN1Encodable getExtensionParsedValue(ASN1ObjectIdentifier oid)
119    {
120        Extension ext = this.getExtension(oid);
121
122        if (ext != null)
123        {
124            return ext.getParsedValue();
125        }
126
127        return null;
128    }
129
130    /**
131     * <pre>
132     *     Extensions        ::=   SEQUENCE SIZE (1..MAX) OF Extension
133     *
134     *     Extension         ::=   SEQUENCE {
135     *        extnId            EXTENSION.&amp;id ({ExtensionSet}),
136     *        critical          BOOLEAN DEFAULT FALSE,
137     *        extnValue         OCTET STRING }
138     * </pre>
139     */
140    public ASN1Primitive toASN1Primitive()
141    {
142        ASN1EncodableVector vec = new ASN1EncodableVector();
143        Enumeration e = ordering.elements();
144
145        while (e.hasMoreElements())
146        {
147            ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement();
148            Extension ext = (Extension)extensions.get(oid);
149
150            vec.add(ext);
151        }
152
153        return new DERSequence(vec);
154    }
155
156    public boolean equivalent(
157        Extensions other)
158    {
159        if (extensions.size() != other.extensions.size())
160        {
161            return false;
162        }
163
164        Enumeration e1 = extensions.keys();
165
166        while (e1.hasMoreElements())
167        {
168            Object key = e1.nextElement();
169
170            if (!extensions.get(key).equals(other.extensions.get(key)))
171            {
172                return false;
173            }
174        }
175
176        return true;
177    }
178
179    public ASN1ObjectIdentifier[] getExtensionOIDs()
180    {
181        return toOidArray(ordering);
182    }
183
184    public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs()
185    {
186        return getExtensionOIDs(false);
187    }
188
189    public ASN1ObjectIdentifier[] getCriticalExtensionOIDs()
190    {
191        return getExtensionOIDs(true);
192    }
193
194    private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical)
195    {
196        Vector oidVec = new Vector();
197
198        for (int i = 0; i != ordering.size(); i++)
199        {
200            Object oid = ordering.elementAt(i);
201
202            if (((Extension)extensions.get(oid)).isCritical() == isCritical)
203            {
204                oidVec.addElement(oid);
205            }
206        }
207
208        return toOidArray(oidVec);
209    }
210
211    private ASN1ObjectIdentifier[] toOidArray(Vector oidVec)
212    {
213        ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()];
214
215        for (int i = 0; i != oids.length; i++)
216        {
217            oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i);
218        }
219        return oids;
220    }
221}
222