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