Home | History | Annotate | Download | only in x509
      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      */
     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      */
     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      */
     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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    282     public void addAdditionalStore(Store store)
    283     {
    284         if (store != null)
    285         {
    286             additionalStores.add(store);
    287         }
    288     }
    289 
    290     /**
    291      * @deprecated
    292      */
    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      */
    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      */
    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      */
    333     public void setValidityModel(int validityModel)
    334     {
    335         this.validityModel = validityModel;
    336     }
    337 
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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