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