001package org.apache.commons.ssl.org.bouncycastle.asn1.x509;
002
003import java.util.Enumeration;
004import java.util.Hashtable;
005import java.util.Vector;
006
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Boolean;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1ObjectIdentifier;
011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString;
012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
013import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
014import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
015import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
016
017/**
018 * @deprecated use Extensions
019 */
020public class X509Extensions
021    extends ASN1Object
022{
023    /**
024     * Subject Directory Attributes
025     * @deprecated use X509Extension value.
026     */
027    public static final ASN1ObjectIdentifier SubjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9");
028    
029    /**
030     * Subject Key Identifier
031     *  @deprecated use X509Extension value.
032     */
033    public static final ASN1ObjectIdentifier SubjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14");
034
035    /**
036     * Key Usage
037     *  @deprecated use X509Extension value.
038     */
039    public static final ASN1ObjectIdentifier KeyUsage = new ASN1ObjectIdentifier("2.5.29.15");
040
041    /**
042     * Private Key Usage Period
043     *  @deprecated use X509Extension value.
044     */
045    public static final ASN1ObjectIdentifier PrivateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16");
046
047    /**
048     * Subject Alternative Name
049     *  @deprecated use X509Extension value.
050     */
051    public static final ASN1ObjectIdentifier SubjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17");
052
053    /**
054     * Issuer Alternative Name
055     *  @deprecated use X509Extension value.
056     */
057    public static final ASN1ObjectIdentifier IssuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18");
058
059    /**
060     * Basic Constraints
061     *  @deprecated use X509Extension value.
062     */
063    public static final ASN1ObjectIdentifier BasicConstraints = new ASN1ObjectIdentifier("2.5.29.19");
064
065    /**
066     * CRL Number
067     *  @deprecated use X509Extension value.
068     */
069    public static final ASN1ObjectIdentifier CRLNumber = new ASN1ObjectIdentifier("2.5.29.20");
070
071    /**
072     * Reason code
073     *  @deprecated use X509Extension value.
074     */
075    public static final ASN1ObjectIdentifier ReasonCode = new ASN1ObjectIdentifier("2.5.29.21");
076
077    /**
078     * Hold Instruction Code
079     *  @deprecated use X509Extension value.
080     */
081    public static final ASN1ObjectIdentifier InstructionCode = new ASN1ObjectIdentifier("2.5.29.23");
082
083    /**
084     * Invalidity Date
085     *  @deprecated use X509Extension value.
086     */
087    public static final ASN1ObjectIdentifier InvalidityDate = new ASN1ObjectIdentifier("2.5.29.24");
088
089    /**
090     * Delta CRL indicator
091     *  @deprecated use X509Extension value.
092     */
093    public static final ASN1ObjectIdentifier DeltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27");
094
095    /**
096     * Issuing Distribution Point
097     *  @deprecated use X509Extension value.
098     */
099    public static final ASN1ObjectIdentifier IssuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28");
100
101    /**
102     * Certificate Issuer
103     *  @deprecated use X509Extension value.
104     */
105    public static final ASN1ObjectIdentifier CertificateIssuer = new ASN1ObjectIdentifier("2.5.29.29");
106
107    /**
108     * Name Constraints
109     *  @deprecated use X509Extension value.
110     */
111    public static final ASN1ObjectIdentifier NameConstraints = new ASN1ObjectIdentifier("2.5.29.30");
112
113    /**
114     * CRL Distribution Points
115     *  @deprecated use X509Extension value.
116     */
117    public static final ASN1ObjectIdentifier CRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31");
118
119    /**
120     * Certificate Policies
121     *  @deprecated use X509Extension value.
122     */
123    public static final ASN1ObjectIdentifier CertificatePolicies = new ASN1ObjectIdentifier("2.5.29.32");
124
125    /**
126     * Policy Mappings
127     *  @deprecated use X509Extension value.
128     */
129    public static final ASN1ObjectIdentifier PolicyMappings = new ASN1ObjectIdentifier("2.5.29.33");
130
131    /**
132     * Authority Key Identifier
133     *  @deprecated use X509Extension value.
134     */
135    public static final ASN1ObjectIdentifier AuthorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35");
136
137    /**
138     * Policy Constraints
139     *  @deprecated use X509Extension value.
140     */
141    public static final ASN1ObjectIdentifier PolicyConstraints = new ASN1ObjectIdentifier("2.5.29.36");
142
143    /**
144     * Extended Key Usage
145     *  @deprecated use X509Extension value.
146     */
147    public static final ASN1ObjectIdentifier ExtendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37");
148
149    /**
150     * Freshest CRL
151     *  @deprecated use X509Extension value.
152     */
153    public static final ASN1ObjectIdentifier FreshestCRL = new ASN1ObjectIdentifier("2.5.29.46");
154     
155    /**
156     * Inhibit Any Policy
157     *  @deprecated use X509Extension value.
158     */
159    public static final ASN1ObjectIdentifier InhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54");
160
161    /**
162     * Authority Info Access
163     *  @deprecated use X509Extension value.
164     */
165    public static final ASN1ObjectIdentifier AuthorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1");
166
167    /**
168     * Subject Info Access
169     *  @deprecated use X509Extension value.
170     */
171    public static final ASN1ObjectIdentifier SubjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11");
172    
173    /**
174     * Logo Type
175     *  @deprecated use X509Extension value.
176     */
177    public static final ASN1ObjectIdentifier LogoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12");
178
179    /**
180     * BiometricInfo
181     *  @deprecated use X509Extension value.
182     */
183    public static final ASN1ObjectIdentifier BiometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2");
184    
185    /**
186     * QCStatements
187     *  @deprecated use X509Extension value.
188     */
189    public static final ASN1ObjectIdentifier QCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3");
190
191    /**
192     * Audit identity extension in attribute certificates.
193     *  @deprecated use X509Extension value.
194     */
195    public static final ASN1ObjectIdentifier AuditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4");
196    
197    /**
198     * NoRevAvail extension in attribute certificates.
199     *  @deprecated use X509Extension value.
200     */
201    public static final ASN1ObjectIdentifier NoRevAvail = new ASN1ObjectIdentifier("2.5.29.56");
202
203    /**
204     * TargetInformation extension in attribute certificates.
205     *  @deprecated use X509Extension value.
206     */
207    public static final ASN1ObjectIdentifier TargetInformation = new ASN1ObjectIdentifier("2.5.29.55");
208    
209    private Hashtable               extensions = new Hashtable();
210    private Vector                  ordering = new Vector();
211
212    public static X509Extensions getInstance(
213        ASN1TaggedObject obj,
214        boolean          explicit)
215    {
216        return getInstance(ASN1Sequence.getInstance(obj, explicit));
217    }
218
219    public static X509Extensions getInstance(
220        Object  obj)
221    {
222        if (obj == null || obj instanceof X509Extensions)
223        {
224            return (X509Extensions)obj;
225        }
226
227        if (obj instanceof ASN1Sequence)
228        {
229            return new X509Extensions((ASN1Sequence)obj);
230        }
231
232        if (obj instanceof Extensions)
233        {
234            return new X509Extensions((ASN1Sequence)((Extensions)obj).toASN1Primitive());
235        }
236
237        if (obj instanceof ASN1TaggedObject)
238        {
239            return getInstance(((ASN1TaggedObject)obj).getObject());
240        }
241
242        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
243    }
244
245    /**
246     * Constructor from ASN1Sequence.
247     *
248     * the extensions are a list of constructed sequences, either with (OID, OctetString) or (OID, Boolean, OctetString)
249     */
250    public X509Extensions(
251        ASN1Sequence  seq)
252    {
253        Enumeration e = seq.getObjects();
254
255        while (e.hasMoreElements())
256        {
257            ASN1Sequence            s = ASN1Sequence.getInstance(e.nextElement());
258
259            if (s.size() == 3)
260            {
261                extensions.put(s.getObjectAt(0), new X509Extension(ASN1Boolean.getInstance(s.getObjectAt(1)), ASN1OctetString.getInstance(s.getObjectAt(2))));
262            }
263            else if (s.size() == 2)
264            {
265                extensions.put(s.getObjectAt(0), new X509Extension(false, ASN1OctetString.getInstance(s.getObjectAt(1))));
266            }
267            else
268            {
269                throw new IllegalArgumentException("Bad sequence size: " + s.size());
270            }
271
272            ordering.addElement(s.getObjectAt(0));
273        }
274    }
275
276    /**
277     * constructor from a table of extensions.
278     * <p>
279     * it's is assumed the table contains OID/String pairs.
280     */
281    public X509Extensions(
282        Hashtable  extensions)
283    {
284        this(null, extensions);
285    }
286
287    /**
288     * Constructor from a table of extensions with ordering.
289     * <p>
290     * It's is assumed the table contains OID/String pairs.
291     * @deprecated use Extensions
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     * @deprecated use Extensions
330     */
331    public X509Extensions(
332        Vector      objectIDs,
333        Vector      values)
334    {
335        Enumeration e = objectIDs.elements();
336
337        while (e.hasMoreElements())
338        {
339            this.ordering.addElement(e.nextElement()); 
340        }
341
342        int count = 0;
343        
344        e = this.ordering.elements();
345
346        while (e.hasMoreElements())
347        {
348            ASN1ObjectIdentifier     oid = (ASN1ObjectIdentifier)e.nextElement();
349            X509Extension           ext = (X509Extension)values.elementAt(count);
350
351            this.extensions.put(oid, ext);
352            count++;
353        }
354    }
355    
356    /**
357     * return an Enumeration of the extension field's object ids.
358     */
359    public Enumeration oids()
360    {
361        return ordering.elements();
362    }
363
364    /**
365     * return the extension represented by the object identifier
366     * passed in.
367     *
368     * @return the extension if it's present, null otherwise.
369     */
370    public X509Extension getExtension(
371        ASN1ObjectIdentifier oid)
372    {
373        return (X509Extension)extensions.get(oid);
374    }
375
376    /**
377     * <pre>
378     *     Extensions        ::=   SEQUENCE SIZE (1..MAX) OF Extension
379     *
380     *     Extension         ::=   SEQUENCE {
381     *        extnId            EXTENSION.&amp;id ({ExtensionSet}),
382     *        critical          BOOLEAN DEFAULT FALSE,
383     *        extnValue         OCTET STRING }
384     * </pre>
385     */
386    public ASN1Primitive toASN1Primitive()
387    {
388        ASN1EncodableVector     vec = new ASN1EncodableVector();
389        Enumeration             e = ordering.elements();
390
391        while (e.hasMoreElements())
392        {
393            ASN1ObjectIdentifier    oid = (ASN1ObjectIdentifier)e.nextElement();
394            X509Extension           ext = (X509Extension)extensions.get(oid);
395            ASN1EncodableVector     v = new ASN1EncodableVector();
396
397            v.add(oid);
398
399            if (ext.isCritical())
400            {
401                v.add(ASN1Boolean.TRUE);
402            }
403
404            v.add(ext.getValue());
405
406            vec.add(new DERSequence(v));
407        }
408
409        return new DERSequence(vec);
410    }
411
412    public boolean equivalent(
413        X509Extensions other)
414    {
415        if (extensions.size() != other.extensions.size())
416        {
417            return false;
418        }
419
420        Enumeration     e1 = extensions.keys();
421
422        while (e1.hasMoreElements())
423        {
424            Object  key = e1.nextElement();
425
426            if (!extensions.get(key).equals(other.extensions.get(key)))
427            {
428                return false;
429            }
430        }
431
432        return true;
433    }
434
435    public ASN1ObjectIdentifier[] getExtensionOIDs()
436    {
437        return toOidArray(ordering);
438    }
439    
440    public ASN1ObjectIdentifier[] getNonCriticalExtensionOIDs()
441    {
442        return getExtensionOIDs(false);
443    }
444
445    public ASN1ObjectIdentifier[] getCriticalExtensionOIDs()
446    {
447        return getExtensionOIDs(true);
448    }
449
450    private ASN1ObjectIdentifier[] getExtensionOIDs(boolean isCritical)
451    {
452        Vector oidVec = new Vector();
453
454        for (int i = 0; i != ordering.size(); i++)
455        {
456            Object oid = ordering.elementAt(i);
457
458            if (((X509Extension)extensions.get(oid)).isCritical() == isCritical)
459            {
460                oidVec.addElement(oid);
461            }
462        }
463
464        return toOidArray(oidVec);
465    }
466
467    private ASN1ObjectIdentifier[] toOidArray(Vector oidVec)
468    {
469        ASN1ObjectIdentifier[] oids = new ASN1ObjectIdentifier[oidVec.size()];
470
471        for (int i = 0; i != oids.length; i++)
472        {
473            oids[i] = (ASN1ObjectIdentifier)oidVec.elementAt(i);
474        }
475        return oids;
476    }
477}