2003/02/12 06:21:04
[org.ibex.core.git] / src / org / bouncycastle / asn1 / x509 / X509Extensions.java
1 package org.bouncycastle.asn1.x509;
2
3 import java.io.*;
4 import java.util.*;
5
6 import org.bouncycastle.asn1.*;
7
8 public class X509Extensions
9     implements DEREncodable
10 {
11     /**
12      * Subject Key Identifier 
13      */
14     public static final DERObjectIdentifier SubjectKeyIdentifier = new DERObjectIdentifier("2.5.29.14");
15
16     /**
17      * Key Usage 
18      */
19     public static final DERObjectIdentifier KeyUsage = new DERObjectIdentifier("2.5.29.15");
20
21     /**
22      * Private Key Usage Period 
23      */
24     public static final DERObjectIdentifier PrivateKeyUsagePeriod = new DERObjectIdentifier("2.5.29.16");
25
26     /**
27      * Subject Alternative Name 
28      */
29     public static final DERObjectIdentifier SubjectAlternativeName = new DERObjectIdentifier("2.5.29.17");
30
31     /**
32      * Issuer Alternative Name 
33      */
34     public static final DERObjectIdentifier IssuerAlternativeName = new DERObjectIdentifier("2.5.29.18");
35
36     /**
37      * Basic Constraints 
38      */
39     public static final DERObjectIdentifier BasicConstraints = new DERObjectIdentifier("2.5.29.19");
40
41     /**
42      * CRL Number 
43      */
44     public static final DERObjectIdentifier CRLNumber = new DERObjectIdentifier("2.5.29.20");
45
46     /**
47      * Reason code 
48      */
49     public static final DERObjectIdentifier ReasonCode = new DERObjectIdentifier("2.5.29.21");
50
51     /**
52      * Hold Instruction Code 
53      */
54     public static final DERObjectIdentifier InstructionCode = new DERObjectIdentifier("2.5.29.23");
55
56     /**
57      * Invalidity Date 
58      */
59     public static final DERObjectIdentifier InvalidityDate = new DERObjectIdentifier("2.5.29.24");
60
61     /**
62      * Delta CRL indicator 
63      */
64     public static final DERObjectIdentifier DeltaCRLIndicator = new DERObjectIdentifier("2.5.29.27");
65
66     /**
67      * Issuing Distribution Point 
68      */
69     public static final DERObjectIdentifier IssuingDistributionPoint = new DERObjectIdentifier("2.5.29.28");
70
71     /**
72      * Certificate Issuer 
73      */
74     public static final DERObjectIdentifier CertificateIssuer = new DERObjectIdentifier("2.5.29.29");
75
76     /**
77      * Name Constraints 
78      */
79     public static final DERObjectIdentifier NameConstraints = new DERObjectIdentifier("2.5.29.30");
80
81     /**
82      * CRL Distribution Points 
83      */
84     public static final DERObjectIdentifier CRLDistributionPoints = new DERObjectIdentifier("2.5.29.31");
85
86     /**
87      * Certificate Policies 
88      */
89     public static final DERObjectIdentifier CertificatePolicies = new DERObjectIdentifier("2.5.29.32");
90
91     /**
92      * Policy Mappings 
93      */
94     public static final DERObjectIdentifier PolicyMappings = new DERObjectIdentifier("2.5.29.33");
95
96     /**
97      * Authority Key Identifier 
98      */
99     public static final DERObjectIdentifier AuthorityKeyIdentifier = new DERObjectIdentifier("2.5.29.35");
100
101     /**
102      * Policy Constraints 
103      */
104     public static final DERObjectIdentifier PolicyConstraints = new DERObjectIdentifier("2.5.29.36");
105
106     /**
107      * Extended Key Usage 
108      */
109     public static final DERObjectIdentifier ExtendedKeyUsage = new DERObjectIdentifier("2.5.29.37");
110
111     private Hashtable               extensions = new Hashtable();
112     private Vector                  ordering = new Vector();
113
114     public static X509Extensions getInstance(
115         ASN1TaggedObject obj,
116         boolean          explicit)
117     {
118         return getInstance(ASN1Sequence.getInstance(obj, explicit));
119     }
120
121     public static X509Extensions getInstance(
122         Object  obj)
123     {
124         if (obj == null || obj instanceof X509Extensions)
125         {
126             return (X509Extensions)obj;
127         }
128
129         if (obj instanceof ASN1Sequence)
130         {
131             return new X509Extensions((ASN1Sequence)obj);
132         }
133
134         if (obj instanceof ASN1TaggedObject)
135         {
136             return getInstance(((ASN1TaggedObject)obj).getObject());
137         }
138
139         throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
140     }
141
142     /**
143      * Constructor from DERConstructedSequence.
144      *
145      * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString)
146      */
147     public X509Extensions(
148         ASN1Sequence  seq)
149     {
150         Enumeration e = seq.getObjects();
151
152         while (e.hasMoreElements())
153         {
154             ASN1Sequence            s = (ASN1Sequence)e.nextElement();
155             Enumeration             e1 = s.getObjects();
156
157             if (s.size() == 3)
158             {
159                 extensions.put(s.getObjectAt(0), new X509Extension((DERBoolean)s.getObjectAt(1), (DEROctetString)s.getObjectAt(2)));
160             }
161             else
162             {
163                 extensions.put(s.getObjectAt(0), new X509Extension(false, (DEROctetString)s.getObjectAt(1)));
164             }
165
166             ordering.addElement(s.getObjectAt(0));
167         }
168     }
169
170     /**
171      * constructor from a table of extensions.
172      * <p>
173      * it's is assumed the table contains OID/String pairs.
174      */
175     public X509Extensions(
176         Hashtable  extensions)
177     {
178         this(null, extensions);
179     }
180
181     /**
182      * constructor from a table of extensions with ordering
183      * <p>
184      * it's is assumed the table contains OID/String pairs.
185      */
186     public X509Extensions(
187         Vector      ordering,
188         Hashtable   extensions)
189     {
190         Enumeration e;
191
192         if (ordering == null)
193         {
194             e = extensions.keys();
195         }
196         else
197         {
198             e = ordering.elements();
199         }
200
201         while (e.hasMoreElements())
202         {
203             this.ordering.addElement(e.nextElement()); 
204         }
205
206         e = this.ordering.elements();
207
208         while (e.hasMoreElements())
209         {
210             DERObjectIdentifier     oid = (DERObjectIdentifier)e.nextElement();
211             X509Extension           ext = (X509Extension)extensions.get(oid);
212
213             this.extensions.put(oid, ext);
214         }
215     }
216
217     /**
218      * return an Enumeration of the extension field's object ids.
219      */
220     public Enumeration oids()
221     {
222         return ordering.elements();
223     }
224
225     /**
226      * return the extension represented by the object identifier
227      * passed in.
228      *
229      * @return the extension if it's present, null otherwise.
230      */
231     public X509Extension getExtension(
232         DERObjectIdentifier oid)
233     {
234         return (X509Extension)extensions.get(oid);
235     }
236
237     public DERObject getDERObject()
238     {
239         DEREncodableVector      vec = new DEREncodableVector();
240         Enumeration             e = ordering.elements();
241
242         while (e.hasMoreElements())
243         {
244             DERObjectIdentifier     oid = (DERObjectIdentifier)e.nextElement();
245             X509Extension           ext = (X509Extension)extensions.get(oid);
246             DEREncodableVector      v = new DEREncodableVector();
247
248             v.add(oid);
249
250             if (ext.isCritical())
251             {
252                 v.add(new DERBoolean(true));
253             }
254
255             v.add(ext.getValue());
256
257             vec.add(new DERSequence(v));
258         }
259
260         return new DERSequence(vec);
261     }
262
263     public int hashCode()
264     {
265         Enumeration     e = extensions.keys();
266         int             hashCode = 0;
267
268         while (e.hasMoreElements())
269         {
270             Object  o = e.nextElement();
271
272             hashCode ^= o.hashCode();
273             hashCode ^= extensions.get(o).hashCode();
274         }
275
276         return hashCode;
277     }
278
279     public boolean equals(
280         Object o)
281     {
282         if (o == null || !(o instanceof X509Extensions))
283         {
284             return false;
285         }
286
287         X509Extensions  other = (X509Extensions)o;
288
289         Enumeration     e1 = extensions.keys();
290         Enumeration     e2 = other.extensions.keys();
291
292         while (e1.hasMoreElements() && e2.hasMoreElements())
293         {
294             Object  o1 = e1.nextElement();
295             Object  o2 = e2.nextElement();
296             
297             if (!o1.equals(o2))
298             {
299                 return false;
300             }
301         }
302
303         if (e1.hasMoreElements() || e2.hasMoreElements())
304         {
305             return false;
306         }
307
308         return true;
309     }
310 }