ExtendedPKIXParameters.java revision 028ab6e01e3b911024b9b9243e9a0f4ac377c0fa
1package org.bouncycastle.x509;
2
3import org.bouncycastle.util.Selector;
4import org.bouncycastle.util.Store;
5
6import java.security.InvalidAlgorithmParameterException;
7import java.security.cert.CertSelector;
8import java.security.cert.CertStore;
9import java.security.cert.PKIXParameters;
10import java.security.cert.TrustAnchor;
11import java.security.cert.X509CertSelector;
12import java.util.ArrayList;
13import java.util.Collections;
14import java.util.HashSet;
15import java.util.Iterator;
16import java.util.List;
17import java.util.Set;
18
19/**
20 * This class extends the PKIXParameters with a validity model parameter.
21 *
22 * @deprecated use PKIXExtendedParameters
23 */
24public class ExtendedPKIXParameters
25    extends PKIXParameters
26{
27
28    private List stores;
29
30    private Selector selector;
31
32    private boolean additionalLocationsEnabled;
33
34    private List additionalStores;
35
36    private Set trustedACIssuers;
37
38    private Set necessaryACAttributes;
39
40    private Set prohibitedACAttributes;
41
42    private Set attrCertCheckers;
43
44    /**
45     * Creates an instance of <code>PKIXParameters</code> with the specified
46     * <code>Set</code> of most-trusted CAs. Each element of the set is a
47     * {@link TrustAnchor TrustAnchor}.
48     * <p>
49     *     Note that the <code>Set</code>
50     * is copied to protect against subsequent modifications.
51     * </p>
52     *
53     * @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
54     * @throws InvalidAlgorithmParameterException if the specified
55     *             <code>Set</code> is empty.
56     * @throws NullPointerException if the specified <code>Set</code> is
57     *             <code>null</code>
58     * @throws ClassCastException if any of the elements in the <code>Set</code>
59     *             is not of type <code>java.security.cert.TrustAnchor</code>
60     */
61    public ExtendedPKIXParameters(Set trustAnchors)
62        throws InvalidAlgorithmParameterException
63    {
64        super(trustAnchors);
65        stores = new ArrayList();
66        additionalStores = new ArrayList();
67        trustedACIssuers = new HashSet();
68        necessaryACAttributes = new HashSet();
69        prohibitedACAttributes = new HashSet();
70        attrCertCheckers = new HashSet();
71    }
72
73    /**
74     * Returns an instance with the parameters of a given
75     * <code>PKIXParameters</code> object.
76     *
77     * @param pkixParams The given <code>PKIXParameters</code>
78     * @return an extended PKIX params object
79     */
80    public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams)
81    {
82        ExtendedPKIXParameters params;
83        try
84        {
85            params = new ExtendedPKIXParameters(pkixParams.getTrustAnchors());
86        }
87        catch (Exception e)
88        {
89            // cannot happen
90            throw new RuntimeException(e.getMessage());
91        }
92        params.setParams(pkixParams);
93        return params;
94    }
95
96    /**
97     * Method to support <code>clone()</code> under J2ME.
98     * <code>super.clone()</code> does not exist and fields are not copied.
99     *
100     * @param params Parameters to set. If this are
101     *            <code>ExtendedPKIXParameters</code> they are copied to.
102     */
103    protected void setParams(PKIXParameters params)
104    {
105        setDate(params.getDate());
106        setCertPathCheckers(params.getCertPathCheckers());
107        setCertStores(params.getCertStores());
108        setAnyPolicyInhibited(params.isAnyPolicyInhibited());
109        setExplicitPolicyRequired(params.isExplicitPolicyRequired());
110        setPolicyMappingInhibited(params.isPolicyMappingInhibited());
111        setRevocationEnabled(params.isRevocationEnabled());
112        setInitialPolicies(params.getInitialPolicies());
113        setPolicyQualifiersRejected(params.getPolicyQualifiersRejected());
114        setSigProvider(params.getSigProvider());
115        setTargetCertConstraints(params.getTargetCertConstraints());
116        try
117        {
118            setTrustAnchors(params.getTrustAnchors());
119        }
120        catch (Exception e)
121        {
122            // cannot happen
123            throw new RuntimeException(e.getMessage());
124        }
125        if (params instanceof ExtendedPKIXParameters)
126        {
127            ExtendedPKIXParameters _params = (ExtendedPKIXParameters) params;
128            validityModel = _params.validityModel;
129            useDeltas = _params.useDeltas;
130            additionalLocationsEnabled = _params.additionalLocationsEnabled;
131            selector = _params.selector == null ? null
132                : (Selector) _params.selector.clone();
133            stores = new ArrayList(_params.stores);
134            additionalStores = new ArrayList(_params.additionalStores);
135            trustedACIssuers = new HashSet(_params.trustedACIssuers);
136            prohibitedACAttributes = new HashSet(_params.prohibitedACAttributes);
137            necessaryACAttributes = new HashSet(_params.necessaryACAttributes);
138            attrCertCheckers = new HashSet(_params.attrCertCheckers);
139        }
140    }
141
142    /**
143     * This is the default PKIX validity model. Actually there are two variants
144     * of this: The PKIX model and the modified PKIX model. The PKIX model
145     * verifies that all involved certificates must have been valid at the
146     * current time. The modified PKIX model verifies that all involved
147     * certificates were valid at the signing time. Both are indirectly choosen
148     * with the {@link PKIXParameters#setDate(java.util.Date)} method, so this
149     * methods sets the Date when <em>all</em> certificates must have been
150     * valid.
151     */
152    public static final int PKIX_VALIDITY_MODEL = 0;
153
154    /**
155     * This model uses the following validity model. Each certificate must have
156     * been valid at the moment where is was used. That means the end
157     * certificate must have been valid at the time the signature was done. The
158     * CA certificate which signed the end certificate must have been valid,
159     * when the end certificate was signed. The CA (or Root CA) certificate must
160     * have been valid, when the CA certificate was signed and so on. So the
161     * {@link PKIXParameters#setDate(java.util.Date)} method sets the time, when
162     * the <em>end certificate</em> must have been valid.
163     * <p>
164     * It is used e.g.
165     * in the German signature law.
166     * </p>
167     */
168    public static final int CHAIN_VALIDITY_MODEL = 1;
169
170    private int validityModel = PKIX_VALIDITY_MODEL;
171
172    private boolean useDeltas = false;
173
174    /**
175     * Defaults to <code>false</code>.
176     *
177     * @return Returns if delta CRLs should be used.
178     */
179    public boolean isUseDeltasEnabled()
180    {
181        return useDeltas;
182    }
183
184    /**
185     * Sets if delta CRLs should be used for checking the revocation status.
186     *
187     * @param useDeltas <code>true</code> if delta CRLs should be used.
188     */
189    public void setUseDeltasEnabled(boolean useDeltas)
190    {
191        this.useDeltas = useDeltas;
192    }
193
194    /**
195     * @return Returns the validity model.
196     * @see #CHAIN_VALIDITY_MODEL
197     * @see #PKIX_VALIDITY_MODEL
198     */
199    public int getValidityModel()
200    {
201        return validityModel;
202    }
203
204    /**
205     * Sets the Java CertStore to this extended PKIX parameters.
206     *
207     * @throws ClassCastException if an element of <code>stores</code> is not
208     *             a <code>CertStore</code>.
209     */
210    public void setCertStores(List stores)
211    {
212        if (stores != null)
213        {
214            Iterator it = stores.iterator();
215            while (it.hasNext())
216            {
217                addCertStore((CertStore)it.next());
218            }
219        }
220    }
221
222    /**
223     * Sets the Bouncy Castle Stores for finding CRLs, certificates, attribute
224     * certificates or cross certificates.
225     * <p>
226     * The <code>List</code> is cloned.
227     *
228     * @param stores A list of stores to use.
229     * @see #getStores
230     * @throws ClassCastException if an element of <code>stores</code> is not
231     *             a {@link Store}.
232     */
233    public void setStores(List stores)
234    {
235        if (stores == null)
236        {
237            this.stores = new ArrayList();
238        }
239        else
240        {
241            for (Iterator i = stores.iterator(); i.hasNext();)
242            {
243                if (!(i.next() instanceof Store))
244                {
245                    throw new ClassCastException(
246                        "All elements of list must be "
247                            + "of type org.bouncycastle.util.Store.");
248                }
249            }
250            this.stores = new ArrayList(stores);
251        }
252    }
253
254    /**
255     * Adds a Bouncy Castle {@link Store} to find CRLs, certificates, attribute
256     * certificates or cross certificates.
257     * <p>
258     * This method should be used to add local stores, like collection based
259     * X.509 stores, if available. Local stores should be considered first,
260     * before trying to use additional (remote) locations, because they do not
261     * need possible additional network traffic.
262     * <p>
263     * If <code>store</code> is <code>null</code> it is ignored.
264     *
265     * @param store The store to add.
266     * @see #getStores
267     */
268    public void addStore(Store store)
269    {
270        if (store != null)
271        {
272            stores.add(store);
273        }
274    }
275
276    /**
277     * Adds an additional Bouncy Castle {@link Store} to find CRLs, certificates,
278     * attribute certificates or cross certificates.
279     * <p>
280     * You should not use this method. This method is used for adding additional
281     * X.509 stores, which are used to add (remote) locations, e.g. LDAP, found
282     * during X.509 object processing, e.g. in certificates or CRLs. This method
283     * is used in PKIX certification path processing.
284     * <p>
285     * If <code>store</code> is <code>null</code> it is ignored.
286     *
287     * @param store The store to add.
288     * @see #getStores()
289     * @deprectaed use addStore().
290     */
291    public void addAdditionalStore(Store store)
292    {
293        if (store != null)
294        {
295            additionalStores.add(store);
296        }
297    }
298
299    /**
300     * @deprecated
301     */
302    public void addAddionalStore(Store store)
303    {
304        addAdditionalStore(store);
305    }
306
307    /**
308     * Returns an immutable <code>List</code> of additional Bouncy Castle
309     * <code>Store</code>s used for finding CRLs, certificates, attribute
310     * certificates or cross certificates.
311     *
312     * @return an immutable <code>List</code> of additional Bouncy Castle
313     *         <code>Store</code>s. Never <code>null</code>.
314     *
315     * @see #addAdditionalStore(Store)
316     */
317    public List getAdditionalStores()
318    {
319        return Collections.unmodifiableList(additionalStores);
320    }
321
322    /**
323     * Returns an immutable <code>List</code> of Bouncy Castle
324     * <code>Store</code>s used for finding CRLs, certificates, attribute
325     * certificates or cross certificates.
326     *
327     * @return an immutable <code>List</code> of Bouncy Castle
328     *         <code>Store</code>s. Never <code>null</code>.
329     *
330     * @see #setStores(List)
331     */
332    public List getStores()
333    {
334        return Collections.unmodifiableList(new ArrayList(stores));
335    }
336
337    /**
338     * @param validityModel The validity model to set.
339     * @see #CHAIN_VALIDITY_MODEL
340     * @see #PKIX_VALIDITY_MODEL
341     */
342    public void setValidityModel(int validityModel)
343    {
344        this.validityModel = validityModel;
345    }
346
347    public Object clone()
348    {
349        ExtendedPKIXParameters params;
350        try
351        {
352            params = new ExtendedPKIXParameters(getTrustAnchors());
353        }
354        catch (Exception e)
355        {
356            // cannot happen
357            throw new RuntimeException(e.getMessage());
358        }
359        params.setParams(this);
360        return params;
361    }
362
363    /**
364     * Returns if additional {@link X509Store}s for locations like LDAP found
365     * in certificates or CRLs should be used.
366     *
367     * @return Returns <code>true</code> if additional stores are used.
368     */
369    public boolean isAdditionalLocationsEnabled()
370    {
371        return additionalLocationsEnabled;
372    }
373
374    /**
375     * Sets if additional {@link X509Store}s for locations like LDAP found in
376     * certificates or CRLs should be used.
377     *
378     * @param enabled <code>true</code> if additional stores are used.
379     */
380    public void setAdditionalLocationsEnabled(boolean enabled)
381    {
382        additionalLocationsEnabled = enabled;
383    }
384
385    /**
386     * Returns the required constraints on the target certificate or attribute
387     * certificate. The constraints are returned as an instance of
388     * <code>Selector</code>. If <code>null</code>, no constraints are
389     * defined.
390     *
391     * <p>
392     * The target certificate in a PKIX path may be a certificate or an
393     * attribute certificate.
394     * <p>
395     * Note that the <code>Selector</code> returned is cloned to protect
396     * against subsequent modifications.
397     *
398     * @return a <code>Selector</code> specifying the constraints on the
399     *         target certificate or attribute certificate (or <code>null</code>)
400     * @see #setTargetConstraints
401     * @see X509CertStoreSelector
402     * @see X509AttributeCertStoreSelector
403     */
404    public Selector getTargetConstraints()
405    {
406        if (selector != null)
407        {
408            return (Selector) selector.clone();
409        }
410        else
411        {
412            return null;
413        }
414    }
415
416    /**
417     * Sets the required constraints on the target certificate or attribute
418     * certificate. The constraints are specified as an instance of
419     * <code>Selector</code>. If <code>null</code>, no constraints are
420     * defined.
421     * <p>
422     * The target certificate in a PKIX path may be a certificate or an
423     * attribute certificate.
424     * <p>
425     * Note that the <code>Selector</code> specified is cloned to protect
426     * against subsequent modifications.
427     *
428     * @param selector a <code>Selector</code> specifying the constraints on
429     *            the target certificate or attribute certificate (or
430     *            <code>null</code>)
431     * @see #getTargetConstraints
432     * @see X509CertStoreSelector
433     * @see X509AttributeCertStoreSelector
434     */
435    public void setTargetConstraints(Selector selector)
436    {
437        if (selector != null)
438        {
439            this.selector = (Selector) selector.clone();
440        }
441        else
442        {
443            this.selector = null;
444        }
445    }
446
447    /**
448     * Sets the required constraints on the target certificate. The constraints
449     * are specified as an instance of <code>X509CertSelector</code>. If
450     * <code>null</code>, no constraints are defined.
451     *
452     * <p>
453     * This method wraps the given <code>X509CertSelector</code> into a
454     * <code>X509CertStoreSelector</code>.
455     * <p>
456     * Note that the <code>X509CertSelector</code> specified is cloned to
457     * protect against subsequent modifications.
458     *
459     * @param selector a <code>X509CertSelector</code> specifying the
460     *            constraints on the target certificate (or <code>null</code>)
461     * @see #getTargetCertConstraints
462     * @see X509CertStoreSelector
463     */
464    public void setTargetCertConstraints(CertSelector selector)
465    {
466        super.setTargetCertConstraints(selector);
467        if (selector != null)
468        {
469            this.selector = X509CertStoreSelector
470                .getInstance((X509CertSelector) selector);
471        }
472        else
473        {
474            this.selector = null;
475        }
476    }
477
478    /**
479     * Returns the trusted attribute certificate issuers. If attribute
480     * certificates is verified the trusted AC issuers must be set.
481     * <p>
482     * The returned <code>Set</code> consists of <code>TrustAnchor</code>s.
483     * <p>
484     * The returned <code>Set</code> is immutable. Never <code>null</code>
485     *
486     * @return Returns an immutable set of the trusted AC issuers.
487     */
488    public Set getTrustedACIssuers()
489    {
490        return Collections.unmodifiableSet(trustedACIssuers);
491    }
492
493    /**
494     * Sets the trusted attribute certificate issuers. If attribute certificates
495     * is verified the trusted AC issuers must be set.
496     * <p>
497     * The <code>trustedACIssuers</code> must be a <code>Set</code> of
498     * <code>TrustAnchor</code>
499     * <p>
500     * The given set is cloned.
501     *
502     * @param trustedACIssuers The trusted AC issuers to set. Is never
503     *            <code>null</code>.
504     * @throws ClassCastException if an element of <code>stores</code> is not
505     *             a <code>TrustAnchor</code>.
506     */
507    public void setTrustedACIssuers(Set trustedACIssuers)
508    {
509        if (trustedACIssuers == null)
510        {
511            this.trustedACIssuers.clear();
512            return;
513        }
514        for (Iterator it = trustedACIssuers.iterator(); it.hasNext();)
515        {
516            if (!(it.next() instanceof TrustAnchor))
517            {
518                throw new ClassCastException("All elements of set must be "
519                    + "of type " + TrustAnchor.class.getName() + ".");
520            }
521        }
522        this.trustedACIssuers.clear();
523        this.trustedACIssuers.addAll(trustedACIssuers);
524    }
525
526    /**
527     * Returns the neccessary attributes which must be contained in an attribute
528     * certificate.
529     * <p>
530     * The returned <code>Set</code> is immutable and contains
531     * <code>String</code>s with the OIDs.
532     *
533     * @return Returns the necessary AC attributes.
534     */
535    public Set getNecessaryACAttributes()
536    {
537        return Collections.unmodifiableSet(necessaryACAttributes);
538    }
539
540    /**
541     * Sets the neccessary which must be contained in an attribute certificate.
542     * <p>
543     * The <code>Set</code> must contain <code>String</code>s with the
544     * OIDs.
545     * <p>
546     * The set is cloned.
547     *
548     * @param necessaryACAttributes The necessary AC attributes to set.
549     * @throws ClassCastException if an element of
550     *             <code>necessaryACAttributes</code> is not a
551     *             <code>String</code>.
552     */
553    public void setNecessaryACAttributes(Set necessaryACAttributes)
554    {
555        if (necessaryACAttributes == null)
556        {
557            this.necessaryACAttributes.clear();
558            return;
559        }
560        for (Iterator it = necessaryACAttributes.iterator(); it.hasNext();)
561        {
562            if (!(it.next() instanceof String))
563            {
564                throw new ClassCastException("All elements of set must be "
565                    + "of type String.");
566            }
567        }
568        this.necessaryACAttributes.clear();
569        this.necessaryACAttributes.addAll(necessaryACAttributes);
570    }
571
572    /**
573     * Returns the attribute certificates which are not allowed.
574     * <p>
575     * The returned <code>Set</code> is immutable and contains
576     * <code>String</code>s with the OIDs.
577     *
578     * @return Returns the prohibited AC attributes. Is never <code>null</code>.
579     */
580    public Set getProhibitedACAttributes()
581    {
582        return Collections.unmodifiableSet(prohibitedACAttributes);
583    }
584
585    /**
586     * Sets the attribute certificates which are not allowed.
587     * <p>
588     * The <code>Set</code> must contain <code>String</code>s with the
589     * OIDs.
590     * <p>
591     * The set is cloned.
592     *
593     * @param prohibitedACAttributes The prohibited AC attributes to set.
594     * @throws ClassCastException if an element of
595     *             <code>prohibitedACAttributes</code> is not a
596     *             <code>String</code>.
597     */
598    public void setProhibitedACAttributes(Set prohibitedACAttributes)
599    {
600        if (prohibitedACAttributes == null)
601        {
602            this.prohibitedACAttributes.clear();
603            return;
604        }
605        for (Iterator it = prohibitedACAttributes.iterator(); it.hasNext();)
606        {
607            if (!(it.next() instanceof String))
608            {
609                throw new ClassCastException("All elements of set must be "
610                    + "of type String.");
611            }
612        }
613        this.prohibitedACAttributes.clear();
614        this.prohibitedACAttributes.addAll(prohibitedACAttributes);
615    }
616
617    /**
618     * Returns the attribute certificate checker. The returned set contains
619     * {@link PKIXAttrCertChecker}s and is immutable.
620     *
621     * @return Returns the attribute certificate checker. Is never
622     *         <code>null</code>.
623     */
624    public Set getAttrCertCheckers()
625    {
626        return Collections.unmodifiableSet(attrCertCheckers);
627    }
628
629    /**
630     * Sets the attribute certificate checkers.
631     * <p>
632     * All elements in the <code>Set</code> must a {@link PKIXAttrCertChecker}.
633     * <p>
634     * The given set is cloned.
635     *
636     * @param attrCertCheckers The attribute certificate checkers to set. Is
637     *            never <code>null</code>.
638     * @throws ClassCastException if an element of <code>attrCertCheckers</code>
639     *             is not a <code>PKIXAttrCertChecker</code>.
640     */
641    public void setAttrCertCheckers(Set attrCertCheckers)
642    {
643        if (attrCertCheckers == null)
644        {
645            this.attrCertCheckers.clear();
646            return;
647        }
648        for (Iterator it = attrCertCheckers.iterator(); it.hasNext();)
649        {
650            if (!(it.next() instanceof PKIXAttrCertChecker))
651            {
652                throw new ClassCastException("All elements of set must be "
653                    + "of type " + PKIXAttrCertChecker.class.getName() + ".");
654            }
655        }
656        this.attrCertCheckers.clear();
657        this.attrCertCheckers.addAll(attrCertCheckers);
658    }
659
660}
661