1package org.bouncycastle.asn1.x509;
2
3import java.util.Enumeration;
4import java.util.Hashtable;
5import java.util.Vector;
6
7import org.bouncycastle.asn1.ASN1EncodableVector;
8import org.bouncycastle.asn1.ASN1Object;
9import org.bouncycastle.asn1.ASN1ObjectIdentifier;
10import org.bouncycastle.asn1.ASN1OctetString;
11import org.bouncycastle.asn1.ASN1Primitive;
12import org.bouncycastle.asn1.ASN1Sequence;
13import org.bouncycastle.asn1.ASN1TaggedObject;
14import org.bouncycastle.asn1.DERBoolean;
15import org.bouncycastle.asn1.DERObjectIdentifier;
16import org.bouncycastle.asn1.DERSequence;
17
18/**
19 * @deprecated use Extensions
20 */
21public class X509Extensions
22    extends ASN1Object
23{
24    /**
25     * Subject Directory Attributes
26     * @deprecated use X509Extension value.
27     */
28    public static final ASN1ObjectIdentifier SubjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9");
29
30    /**
31     * Subject Key Identifier
32     *  @deprecated use X509Extension value.
33     */
34    public static final ASN1ObjectIdentifier SubjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14");
35
36    /**
37     * Key Usage
38     *  @deprecated use X509Extension value.
39     */
40    public static final ASN1ObjectIdentifier KeyUsage = new ASN1ObjectIdentifier("2.5.29.15");
41
42    /**
43     * Private Key Usage Period
44     *  @deprecated use X509Extension value.
45     */
46    public static final ASN1ObjectIdentifier PrivateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16");
47
48    /**
49     * Subject Alternative Name
50     *  @deprecated use X509Extension value.
51     */
52    public static final ASN1ObjectIdentifier SubjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17");
53
54    /**
55     * Issuer Alternative Name
56     *  @deprecated use X509Extension value.
57     */
58    public static final ASN1ObjectIdentifier IssuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18");
59
60    /**
61     * Basic Constraints
62     *  @deprecated use X509Extension value.
63     */
64    public static final ASN1ObjectIdentifier BasicConstraints = new ASN1ObjectIdentifier("2.5.29.19");
65
66    /**
67     * CRL Number
68     *  @deprecated use X509Extension value.
69     */
70    public static final ASN1ObjectIdentifier CRLNumber = new ASN1ObjectIdentifier("2.5.29.20");
71
72    /**
73     * Reason code
74     *  @deprecated use X509Extension value.
75     */
76    public static final ASN1ObjectIdentifier ReasonCode = new ASN1ObjectIdentifier("2.5.29.21");
77
78    /**
79     * Hold Instruction Code
80     *  @deprecated use X509Extension value.
81     */
82    public static final ASN1ObjectIdentifier InstructionCode = new ASN1ObjectIdentifier("2.5.29.23");
83
84    /**
85     * Invalidity Date
86     *  @deprecated use X509Extension value.
87     */
88    public static final ASN1ObjectIdentifier InvalidityDate = new ASN1ObjectIdentifier("2.5.29.24");
89
90    /**
91     * Delta CRL indicator
92     *  @deprecated use X509Extension value.
93     */
94    public static final ASN1ObjectIdentifier DeltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27");
95
96    /**
97     * Issuing Distribution Point
98     *  @deprecated use X509Extension value.
99     */
100    public static final ASN1ObjectIdentifier IssuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28");
101
102    /**
103     * Certificate Issuer
104     *  @deprecated use X509Extension value.
105     */
106    public static final ASN1ObjectIdentifier CertificateIssuer = new ASN1ObjectIdentifier("2.5.29.29");
107
108    /**
109     * Name Constraints
110     *  @deprecated use X509Extension value.
111     */
112    public static final ASN1ObjectIdentifier NameConstraints = new ASN1ObjectIdentifier("2.5.29.30");
113
114    /**
115     * CRL Distribution Points
116     *  @deprecated use X509Extension value.
117     */
118    public static final ASN1ObjectIdentifier CRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31");
119
120    /**
121     * Certificate Policies
122     *  @deprecated use X509Extension value.
123     */
124    public static final ASN1ObjectIdentifier CertificatePolicies = new ASN1ObjectIdentifier("2.5.29.32");
125
126    /**
127     * Policy Mappings
128     *  @deprecated use X509Extension value.
129     */
130    public static final ASN1ObjectIdentifier PolicyMappings = new ASN1ObjectIdentifier("2.5.29.33");
131
132    /**
133     * Authority Key Identifier
134     *  @deprecated use X509Extension value.
135     */
136    public static final ASN1ObjectIdentifier AuthorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35");
137
138    /**
139     * Policy Constraints
140     *  @deprecated use X509Extension value.
141     */
142    public static final ASN1ObjectIdentifier PolicyConstraints = new ASN1ObjectIdentifier("2.5.29.36");
143
144    /**
145     * Extended Key Usage
146     *  @deprecated use X509Extension value.
147     */
148    public static final ASN1ObjectIdentifier ExtendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37");
149
150    /**
151     * Freshest CRL
152     *  @deprecated use X509Extension value.
153     */
154    public static final ASN1ObjectIdentifier FreshestCRL = new ASN1ObjectIdentifier("2.5.29.46");
155
156    /**
157     * Inhibit Any Policy
158     *  @deprecated use X509Extension value.
159     */
160    public static final ASN1ObjectIdentifier InhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54");
161
162    /**
163     * Authority Info Access
164     *  @deprecated use X509Extension value.
165     */
166    public static final ASN1ObjectIdentifier AuthorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1");
167
168    /**
169     * Subject Info Access
170     *  @deprecated use X509Extension value.
171     */
172    public static final ASN1ObjectIdentifier SubjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11");
173
174    /**
175     * Logo Type
176     *  @deprecated use X509Extension value.
177     */
178    public static final ASN1ObjectIdentifier LogoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12");
179
180    /**
181     * BiometricInfo
182     *  @deprecated use X509Extension value.
183     */
184    public static final ASN1ObjectIdentifier BiometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2");
185
186    /**
187     * QCStatements
188     *  @deprecated use X509Extension value.
189     */
190    public static final ASN1ObjectIdentifier QCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3");
191
192    /**
193     * Audit identity extension in attribute certificates.
194     *  @deprecated use X509Extension value.
195     */
196    public static final ASN1ObjectIdentifier AuditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4");
197
198    /**
199     * NoRevAvail extension in attribute certificates.
200     *  @deprecated use X509Extension value.
201     */
202    public static final ASN1ObjectIdentifier NoRevAvail = new ASN1ObjectIdentifier("2.5.29.56");
203
204    /**
205     * TargetInformation extension in attribute certificates.
206     *  @deprecated use X509Extension value.
207     */
208    public static final ASN1ObjectIdentifier TargetInformation = new ASN1ObjectIdentifier("2.5.29.55");
209
210    private Hashtable               extensions = new Hashtable();
211    private Vector                  ordering = new Vector();
212
213    public static X509Extensions getInstance(
214        ASN1TaggedObject obj,
215        boolean          explicit)
216    {
217        return getInstance(ASN1Sequence.getInstance(obj, explicit));
218    }
219
220    public static X509Extensions getInstance(
221        Object  obj)
222    {
223        if (obj == null || obj instanceof X509Extensions)
224        {
225            return (X509Extensions)obj;
226        }
227
228        if (obj instanceof ASN1Sequence)
229        {
230            return new X509Extensions((ASN1Sequence)obj);
231        }
232
233        if (obj instanceof Extensions)
234        {
235            return new X509Extensions((ASN1Sequence)((Extensions)obj).toASN1Primitive());
236        }
237
238        if (obj instanceof ASN1TaggedObject)
239        {
240            return getInstance(((ASN1TaggedObject)obj).getObject());
241        }
242
243        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
244    }
245
246    /**
247     * Constructor from ASN1Sequence.
248     *
249     * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString)
250     */
251    public X509Extensions(
252        ASN1Sequence  seq)
253    {
254        Enumeration e = seq.getObjects();
255
256        while (e.hasMoreElements())
257        {
258            ASN1Sequence            s = ASN1Sequence.getInstance(e.nextElement());
259
260            if (s.size() == 3)
261            {
262                extensions.put(s.getObjectAt(0), new X509Extension(DERBoolean.getInstance(s.getObjectAt(1)), ASN1OctetString.getInstance(s.getObjectAt(2))));
263            }
264            else if (s.size() == 2)
265            {
266                extensions.put(s.getObjectAt(0), new X509Extension(false, ASN1OctetString.getInstance(s.getObjectAt(1))));
267            }
268            else
269            {
270                throw new IllegalArgumentException("Bad sequence size: " + s.size());
271            }
272
273            ordering.addElement(s.getObjectAt(0));
274        }
275    }
276
277    /**
278     * constructor from a table of extensions.
279     * <p>
280     * it's is assumed the table contains OID/String pairs.
281     */
282    public X509Extensions(
283        Hashtable  extensions)
284    {
285        this(null, extensions);
286    }
287
288    /**
289     * Constructor from a table of extensions with ordering.
290     * <p>
291     * It's is assumed the table contains OID/String pairs.
292     */
293    public X509Extensions(
294        Vector      ordering,
295        Hashtable   extensions)
296    {
297        Enumeration e;
298
299        if (ordering == null)
300        {
301            e = extensions.keys();
302        }
303        else
304        {
305            e = ordering.elements();
306        }
307
308        while (e.hasMoreElements())
309        {
310            this.ordering.addElement(ASN1ObjectIdentifier.getInstance(e.nextElement()));
311        }
312
313        e = this.ordering.elements();
314
315        while (e.hasMoreElements())
316        {
317            ASN1ObjectIdentifier     oid = ASN1ObjectIdentifier.getInstance(e.nextElement());
318            X509Extension           ext = (X509Extension)extensions.get(oid);
319
320            this.extensions.put(oid, ext);
321        }
322    }
323
324    /**
325     * Constructor from two vectors
326     *
327     * @param objectIDs a vector of the object identifiers.
328     * @param values a vector of the extension values.
329     */
330    public X509Extensions(
331        Vector      objectIDs,
332        Vector      values)
333    {
334        Enumeration e = objectIDs.elements();
335
336        while (e.hasMoreElements())
337        {
338            this.ordering.addElement(e.nextElement());
339        }
340
341        int count = 0;
342
343        e = this.ordering.elements();
344
345        while (e.hasMoreElements())
346        {
347            ASN1ObjectIdentifier     oid = (ASN1ObjectIdentifier)e.nextElement();
348            X509Extension           ext = (X509Extension)values.elementAt(count);
349
350            this.extensions.put(oid, ext);
351            count++;
352        }
353    }
354
355    /**
356     * return an Enumeration of the extension field's object ids.
357     */
358    public Enumeration oids()
359    {
360        return ordering.elements();
361    }
362
363    /**
364     * return the extension represented by the object identifier
365     * passed in.
366     *
367     * @return the extension if it's present, null otherwise.
368     */
369    public X509Extension getExtension(
370        DERObjectIdentifier oid)
371    {
372        return (X509Extension)extensions.get(oid);
373    }
374
375    /**
376     * @deprecated
377     * @param oid
378     * @return
379     */
380    public X509Extension getExtension(
381        ASN1ObjectIdentifier oid)
382    {
383        return (X509Extension)extensions.get(oid);
384    }
385
386    /**
387     * <pre>
388     *     Extensions        ::=   SEQUENCE SIZE (1..MAX) OF Extension
389     *
390     *     Extension         ::=   SEQUENCE {
391     *        extnId            EXTENSION.&amp;id ({ExtensionSet}),
392     *        critical          BOOLEAN DEFAULT FALSE,
393     *        extnValue         OCTET STRING }
394     * </pre>
395     */
396    public ASN1Primitive toASN1Primitive()
397    {
398        ASN1EncodableVector     vec = new ASN1EncodableVector();
399        Enumeration             e = ordering.elements();
400
401        while (e.hasMoreElements())
402        {
403            ASN1ObjectIdentifier    oid = (ASN1ObjectIdentifier)e.nextElement();
404            X509Extension           ext = (X509Extension)extensions.get(oid);
405            ASN1EncodableVector     v = new ASN1EncodableVector();
406
407            v.add(oid);
408
409            if (ext.isCritical())
410            {
411                // BEGIN android-changed
412                v.add(DERBoolean.TRUE);
413                // END android-changed
414            }
415
416            v.add(ext.getValue());
417
418            vec.add(new DERSequence(v));
419        }
420
421        return new DERSequence(vec);
422    }
423
424    public boolean equivalent(
425        X509Extensions other)
426    {
427        if (extensions.size() != other.extensions.size())
428        {
429            return false;
430        }
431
432        Enumeration     e1 = extensions.keys();
433
434        while (e1.hasMoreElements())
435        {
436            Object  key = e1.nextElement();
437
438            if (!extensions.get(key).equals(other.extensions.get(key)))
439            {
440                return false;
441            }
442        }
443
444        return true;
445    }
446
447    public ASN1ObjectIdentifier[] getExtensionOIDs()
448    {
449        return toOidArray(ordering);
450    }
451
452    public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs()
453    {
454        return getExtensionOIDs(false);
455    }
456
457    public ASN1ObjectIdentifier[] getCriticalExtensionOIDs()
458    {
459        return getExtensionOIDs(true);
460    }
461
462    private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical)
463    {
464        Vector oidVec = new Vector();
465
466        for (int i = 0; i != ordering.size(); i++)
467        {
468            Object oid = ordering.elementAt(i);
469
470            if (((X509Extension)extensions.get(oid)).isCritical() == isCritical)
471            {
472                oidVec.addElement(oid);
473            }
474        }
475
476        return toOidArray(oidVec);
477    }
478
479    private ASN1ObjectIdentifier[] toOidArray(Vector oidVec)
480    {
481        ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()];
482
483        for (int i = 0; i != oids.length; i++)
484        {
485            oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i);
486        }
487        return oids;
488    }
489}
490