View Javadoc

1   /**
2    *
3    *  Licensed to the Apache Software Foundation (ASF) under one or more
4    *  contributor license agreements.  See the NOTICE file distributed with
5    *  this work for additional information regarding copyright ownership.
6    *  The ASF licenses this file to You under the Apache License, Version 2.0
7    *  (the "License"); you may not use this file except in compliance with
8    *  the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  
19  package org.apache.geronimo.util.asn1.x509;
20  
21  import java.util.Enumeration;
22  import java.util.Hashtable;
23  import java.util.Vector;
24  
25  import org.apache.geronimo.util.asn1.ASN1Encodable;
26  import org.apache.geronimo.util.asn1.ASN1EncodableVector;
27  import org.apache.geronimo.util.asn1.ASN1OctetString;
28  import org.apache.geronimo.util.asn1.ASN1Sequence;
29  import org.apache.geronimo.util.asn1.ASN1TaggedObject;
30  import org.apache.geronimo.util.asn1.DERBoolean;
31  import org.apache.geronimo.util.asn1.DERObject;
32  import org.apache.geronimo.util.asn1.DERObjectIdentifier;
33  import org.apache.geronimo.util.asn1.DERSequence;
34  
35  public class X509Extensions
36      extends ASN1Encodable
37  {
38      /**
39       * Subject Directory Attributes
40       */
41      public static final DERObjectIdentifier SubjectDirectoryAttributes = new DERObjectIdentifier("2.5.29.9");
42  
43      /**
44       * Subject Key Identifier
45       */
46      public static final DERObjectIdentifier SubjectKeyIdentifier = new DERObjectIdentifier("2.5.29.14");
47  
48      /**
49       * Key Usage
50       */
51      public static final DERObjectIdentifier KeyUsage = new DERObjectIdentifier("2.5.29.15");
52  
53      /**
54       * Private Key Usage Period
55       */
56      public static final DERObjectIdentifier PrivateKeyUsagePeriod = new DERObjectIdentifier("2.5.29.16");
57  
58      /**
59       * Subject Alternative Name
60       */
61      public static final DERObjectIdentifier SubjectAlternativeName = new DERObjectIdentifier("2.5.29.17");
62  
63      /**
64       * Issuer Alternative Name
65       */
66      public static final DERObjectIdentifier IssuerAlternativeName = new DERObjectIdentifier("2.5.29.18");
67  
68      /**
69       * Basic Constraints
70       */
71      public static final DERObjectIdentifier BasicConstraints = new DERObjectIdentifier("2.5.29.19");
72  
73      /**
74       * CRL Number
75       */
76      public static final DERObjectIdentifier CRLNumber = new DERObjectIdentifier("2.5.29.20");
77  
78      /**
79       * Reason code
80       */
81      public static final DERObjectIdentifier ReasonCode = new DERObjectIdentifier("2.5.29.21");
82  
83      /**
84       * Hold Instruction Code
85       */
86      public static final DERObjectIdentifier InstructionCode = new DERObjectIdentifier("2.5.29.23");
87  
88      /**
89       * Invalidity Date
90       */
91      public static final DERObjectIdentifier InvalidityDate = new DERObjectIdentifier("2.5.29.24");
92  
93      /**
94       * Delta CRL indicator
95       */
96      public static final DERObjectIdentifier DeltaCRLIndicator = new DERObjectIdentifier("2.5.29.27");
97  
98      /**
99       * Issuing Distribution Point
100      */
101     public static final DERObjectIdentifier IssuingDistributionPoint = new DERObjectIdentifier("2.5.29.28");
102 
103     /**
104      * Certificate Issuer
105      */
106     public static final DERObjectIdentifier CertificateIssuer = new DERObjectIdentifier("2.5.29.29");
107 
108     /**
109      * Name Constraints
110      */
111     public static final DERObjectIdentifier NameConstraints = new DERObjectIdentifier("2.5.29.30");
112 
113     /**
114      * CRL Distribution Points
115      */
116     public static final DERObjectIdentifier CRLDistributionPoints = new DERObjectIdentifier("2.5.29.31");
117 
118     /**
119      * Certificate Policies
120      */
121     public static final DERObjectIdentifier CertificatePolicies = new DERObjectIdentifier("2.5.29.32");
122 
123     /**
124      * Policy Mappings
125      */
126     public static final DERObjectIdentifier PolicyMappings = new DERObjectIdentifier("2.5.29.33");
127 
128     /**
129      * Authority Key Identifier
130      */
131     public static final DERObjectIdentifier AuthorityKeyIdentifier = new DERObjectIdentifier("2.5.29.35");
132 
133     /**
134      * Policy Constraints
135      */
136     public static final DERObjectIdentifier PolicyConstraints = new DERObjectIdentifier("2.5.29.36");
137 
138     /**
139      * Extended Key Usage
140      */
141     public static final DERObjectIdentifier ExtendedKeyUsage = new DERObjectIdentifier("2.5.29.37");
142 
143     /**
144      * Freshest CRL
145      */
146     public static final DERObjectIdentifier FreshestCRL = new DERObjectIdentifier("2.5.29.46");
147 
148     /**
149      * Inhibit Any Policy
150      */
151     public static final DERObjectIdentifier InhibitAnyPolicy = new DERObjectIdentifier("2.5.29.54");
152 
153     /**
154      * Authority Info Access
155      */
156     public static final DERObjectIdentifier AuthorityInfoAccess= new DERObjectIdentifier("1.3.6.1.5.5.7.1.1");
157 
158     /**
159      * Subject Info Access
160      */
161     public static final DERObjectIdentifier SubjectInfoAccess= new DERObjectIdentifier("1.3.6.1.5.5.7.1.11");
162 
163     private Hashtable               extensions = new Hashtable();
164     private Vector                  ordering = new Vector();
165 
166     public static X509Extensions getInstance(
167         ASN1TaggedObject obj,
168         boolean          explicit)
169     {
170         return getInstance(ASN1Sequence.getInstance(obj, explicit));
171     }
172 
173     public static X509Extensions getInstance(
174         Object  obj)
175     {
176         if (obj == null || obj instanceof X509Extensions)
177         {
178             return (X509Extensions)obj;
179         }
180 
181         if (obj instanceof ASN1Sequence)
182         {
183             return new X509Extensions((ASN1Sequence)obj);
184         }
185 
186         if (obj instanceof ASN1TaggedObject)
187         {
188             return getInstance(((ASN1TaggedObject)obj).getObject());
189         }
190 
191         throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
192     }
193 
194     /**
195      * Constructor from ASN1Sequence.
196      *
197      * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString)
198      */
199     public X509Extensions(
200         ASN1Sequence  seq)
201     {
202         Enumeration e = seq.getObjects();
203 
204         while (e.hasMoreElements())
205         {
206             ASN1Sequence            s = (ASN1Sequence)e.nextElement();
207 
208             if (s.size() == 3)
209             {
210                 extensions.put(s.getObjectAt(0), new X509Extension((DERBoolean)s.getObjectAt(1), (ASN1OctetString)s.getObjectAt(2)));
211             }
212             else
213             {
214                 extensions.put(s.getObjectAt(0), new X509Extension(false, (ASN1OctetString)s.getObjectAt(1)));
215             }
216 
217             ordering.addElement(s.getObjectAt(0));
218         }
219     }
220 
221     /**
222      * constructor from a table of extensions.
223      * <p>
224      * it's is assumed the table contains OID/String pairs.
225      */
226     public X509Extensions(
227         Hashtable  extensions)
228     {
229         this(null, extensions);
230     }
231 
232     /**
233      * Constructor from a table of extensions with ordering.
234      * <p>
235      * It's is assumed the table contains OID/String pairs.
236      */
237     public X509Extensions(
238         Vector      ordering,
239         Hashtable   extensions)
240     {
241         Enumeration e;
242 
243         if (ordering == null)
244         {
245             e = extensions.keys();
246         }
247         else
248         {
249             e = ordering.elements();
250         }
251 
252         while (e.hasMoreElements())
253         {
254             this.ordering.addElement(e.nextElement());
255         }
256 
257         e = this.ordering.elements();
258 
259         while (e.hasMoreElements())
260         {
261             DERObjectIdentifier     oid = (DERObjectIdentifier)e.nextElement();
262             X509Extension           ext = (X509Extension)extensions.get(oid);
263 
264             this.extensions.put(oid, ext);
265         }
266     }
267 
268     /**
269      * Constructor from two vectors
270      *
271      * @param objectIDs a vector of the object identifiers.
272      * @param values a vector of the extension values.
273      */
274     public X509Extensions(
275         Vector      objectIDs,
276         Vector      values)
277     {
278         Enumeration e = objectIDs.elements();
279 
280         while (e.hasMoreElements())
281         {
282             this.ordering.addElement(e.nextElement());
283         }
284 
285         int count = 0;
286 
287         e = this.ordering.elements();
288 
289         while (e.hasMoreElements())
290         {
291             DERObjectIdentifier     oid = (DERObjectIdentifier)e.nextElement();
292             X509Extension           ext = (X509Extension)values.elementAt(count);
293 
294             this.extensions.put(oid, ext);
295             count++;
296         }
297     }
298 
299     /**
300      * return an Enumeration of the extension field's object ids.
301      */
302     public Enumeration oids()
303     {
304         return ordering.elements();
305     }
306 
307     /**
308      * return the extension represented by the object identifier
309      * passed in.
310      *
311      * @return the extension if it's present, null otherwise.
312      */
313     public X509Extension getExtension(
314         DERObjectIdentifier oid)
315     {
316         return (X509Extension)extensions.get(oid);
317     }
318 
319     /**
320      * <pre>
321      *     Extensions        ::=   SEQUENCE SIZE (1..MAX) OF Extension
322      *
323      *     Extension         ::=   SEQUENCE {
324      *        extnId            EXTENSION.&id ({ExtensionSet}),
325      *        critical          BOOLEAN DEFAULT FALSE,
326      *        extnValue         OCTET STRING }
327      * </pre>
328      */
329     public DERObject toASN1Object()
330     {
331         ASN1EncodableVector     vec = new ASN1EncodableVector();
332         Enumeration             e = ordering.elements();
333 
334         while (e.hasMoreElements())
335         {
336             DERObjectIdentifier     oid = (DERObjectIdentifier)e.nextElement();
337             X509Extension           ext = (X509Extension)extensions.get(oid);
338             ASN1EncodableVector     v = new ASN1EncodableVector();
339 
340             v.add(oid);
341 
342             if (ext.isCritical())
343             {
344                 v.add(new DERBoolean(true));
345             }
346 
347             v.add(ext.getValue());
348 
349             vec.add(new DERSequence(v));
350         }
351 
352         return new DERSequence(vec);
353     }
354 
355     public int hashCode()
356     {
357         Enumeration     e = extensions.keys();
358         int             hashCode = 0;
359 
360         while (e.hasMoreElements())
361         {
362             Object  o = e.nextElement();
363 
364             hashCode ^= o.hashCode();
365             hashCode ^= extensions.get(o).hashCode();
366         }
367 
368         return hashCode;
369     }
370 
371     public boolean equals(
372         Object o)
373     {
374         if (o == null || !(o instanceof X509Extensions))
375         {
376             return false;
377         }
378 
379         X509Extensions  other = (X509Extensions)o;
380 
381         Enumeration     e1 = extensions.keys();
382         Enumeration     e2 = other.extensions.keys();
383 
384         while (e1.hasMoreElements() && e2.hasMoreElements())
385         {
386             Object  o1 = e1.nextElement();
387             Object  o2 = e2.nextElement();
388 
389             if (!o1.equals(o2))
390             {
391                 return false;
392             }
393         }
394 
395         if (e1.hasMoreElements() || e2.hasMoreElements())
396         {
397             return false;
398         }
399 
400         return true;
401     }
402 }