001: package org.bouncycastle.x509;
002:
003: import org.bouncycastle.jce.X509LDAPCertStoreParameters;
004: import org.bouncycastle.util.Selector;
005: import org.bouncycastle.util.Store;
006:
007: import java.security.InvalidAlgorithmParameterException;
008: import java.security.cert.CertSelector;
009: import java.security.cert.CertStore;
010: import java.security.cert.CollectionCertStoreParameters;
011: import java.security.cert.LDAPCertStoreParameters;
012: import java.security.cert.PKIXParameters;
013: import java.security.cert.TrustAnchor;
014: import java.security.cert.X509CertSelector;
015: import java.util.ArrayList;
016: import java.util.Collection;
017: import java.util.Collections;
018: import java.util.HashSet;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.Set;
022:
023: /**
024: * This class extends the PKIXParameters with a validity model parameter.
025: */
026: public class ExtendedPKIXParameters extends PKIXParameters {
027:
028: private List stores;
029:
030: private Selector selector;
031:
032: private boolean additionalLocationsEnabled;
033:
034: private List additionalStores;
035:
036: private Set trustedACIssuers;
037:
038: private Set necessaryACAttributes;
039:
040: private Set prohibitedACAttributes;
041:
042: private Set attrCertCheckers;
043:
044: /**
045: * Creates an instance of <code>PKIXParameters</code> with the specified
046: * <code>Set</code> of most-trusted CAs. Each element of the set is a
047: * {@link TrustAnchor TrustAnchor}. <p/> Note that the <code>Set</code>
048: * is copied to protect against subsequent modifications.
049: *
050: * @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
051: * @throws InvalidAlgorithmParameterException if the specified
052: * <code>Set</code> is empty.
053: * @throws NullPointerException if the specified <code>Set</code> is
054: * <code>null</code>
055: * @throws ClassCastException if any of the elements in the <code>Set</code>
056: * is not of type <code>java.security.cert.TrustAnchor</code>
057: */
058: public ExtendedPKIXParameters(Set trustAnchors)
059: throws InvalidAlgorithmParameterException {
060: super (trustAnchors);
061: stores = new ArrayList();
062: additionalStores = new ArrayList();
063: trustedACIssuers = new HashSet();
064: necessaryACAttributes = new HashSet();
065: prohibitedACAttributes = new HashSet();
066: attrCertCheckers = new HashSet();
067: }
068:
069: /**
070: * Returns an instance with the parameters of a given
071: * <code>PKIXParameters</code> object.
072: *
073: * @param pkixParams The given <code>PKIXParameters</code>
074: * @return an extended PKIX params object
075: */
076: public static ExtendedPKIXParameters getInstance(
077: PKIXParameters pkixParams) {
078: ExtendedPKIXParameters params;
079: try {
080: params = new ExtendedPKIXParameters(pkixParams
081: .getTrustAnchors());
082: } catch (Exception e) {
083: // cannot happen
084: throw new RuntimeException(e.getMessage());
085: }
086: params.setParams(pkixParams);
087: return params;
088: }
089:
090: /**
091: * Method to support <code>clone()</code> under J2ME.
092: * <code>super.clone()</code> does not exist and fields are not copied.
093: *
094: * @param params Parameters to set. If this are
095: * <code>ExtendedPKIXParameters</code> they are copied to.
096: */
097: protected void setParams(PKIXParameters params) {
098: setDate(params.getDate());
099: setCertPathCheckers(params.getCertPathCheckers());
100: setCertStores(params.getCertStores());
101: setAnyPolicyInhibited(params.isAnyPolicyInhibited());
102: setExplicitPolicyRequired(params.isExplicitPolicyRequired());
103: setPolicyMappingInhibited(params.isPolicyMappingInhibited());
104: setRevocationEnabled(params.isRevocationEnabled());
105: setInitialPolicies(params.getInitialPolicies());
106: setPolicyQualifiersRejected(params
107: .getPolicyQualifiersRejected());
108: setSigProvider(params.getSigProvider());
109: setTargetCertConstraints(params.getTargetCertConstraints());
110: try {
111: setTrustAnchors(params.getTrustAnchors());
112: } catch (Exception e) {
113: // cannot happen
114: throw new RuntimeException(e.getMessage());
115: }
116: if (params instanceof ExtendedPKIXParameters) {
117: ExtendedPKIXParameters _params = (ExtendedPKIXParameters) params;
118: validityModel = _params.validityModel;
119: useDeltas = _params.useDeltas;
120: additionalLocationsEnabled = _params.additionalLocationsEnabled;
121: selector = _params.selector == null ? null
122: : (Selector) _params.selector.clone();
123: stores = new ArrayList(_params.stores);
124: additionalStores = new ArrayList(_params.additionalStores);
125: trustedACIssuers = new HashSet(_params.trustedACIssuers);
126: prohibitedACAttributes = new HashSet(
127: _params.prohibitedACAttributes);
128: necessaryACAttributes = new HashSet(
129: _params.necessaryACAttributes);
130: attrCertCheckers = new HashSet(_params.attrCertCheckers);
131: }
132: }
133:
134: /**
135: * This is the default PKIX validity model. Actually there are two variants
136: * of this: The PKIX model and the modified PKIX model. The PKIX model
137: * verifies that all involved certificates must have been valid at the
138: * current time. The modified PKIX model verifies that all involved
139: * certificates were valid at the signing time. Both are indirectly choosen
140: * with the {@link PKIXParameters#setDate(java.util.Date)} method, so this
141: * methods sets the Date when <em>all</em> certificates must have been
142: * valid.
143: */
144: public static final int PKIX_VALIDITY_MODEL = 0;
145:
146: /**
147: * This model uses the following validity model. Each certificate must have
148: * been valid at the moment where is was used. That means the end
149: * certificate must have been valid at the time the signature was done. The
150: * CA certificate which signed the end certificate must have been valid,
151: * when the end certificate was signed. The CA (or Root CA) certificate must
152: * have been valid, when the CA certificate was signed and so on. So the
153: * {@link PKIXParameters#setDate(java.util.Date)} method sets the time, when
154: * the <em>end certificate</em> must have been valid. <p/> It is used e.g.
155: * in the German signature law.
156: */
157: public static final int CHAIN_VALIDITY_MODEL = 1;
158:
159: private int validityModel = PKIX_VALIDITY_MODEL;
160:
161: private boolean useDeltas;
162:
163: /**
164: * Defaults to <code>false</code>.
165: *
166: * @return Returns if delta CRLs should be used.
167: */
168: public boolean isUseDeltasEnabled() {
169: return useDeltas;
170: }
171:
172: /**
173: * Sets if delta CRLs should be used for checking the revocation status.
174: *
175: * @param useDeltas <code>true</code> if delta CRLs should be used.
176: */
177: public void setUseDeltasEnabled(boolean useDeltas) {
178: this .useDeltas = useDeltas;
179: }
180:
181: /**
182: * @return Returns the validity model.
183: * @see #CHAIN_VALIDITY_MODEL
184: * @see #PKIX_VALIDITY_MODEL
185: */
186: public int getValidityModel() {
187: return validityModel;
188: }
189:
190: /**
191: * Adds a Java CertStore to this extended PKIX parameters. If the store uses
192: * initialisation parameters of type
193: * <code>CollectionCertStoreParameters</code> or <code></code> the
194: * corresponding Bouncy Castle {@link Store} type is created additionally to
195: * it.
196: */
197: public void addCertStore(CertStore store) {
198: super .addCertStore(store);
199: if (store.getCertStoreParameters() instanceof CollectionCertStoreParameters) {
200: Collection coll = ((CollectionCertStoreParameters) store
201: .getCertStoreParameters()).getCollection();
202: X509CollectionStoreParameters params = new X509CollectionStoreParameters(
203: coll);
204: try {
205: stores.add(X509Store.getInstance(
206: "CERTIFICATE/COLLECTION", params, "BC"));
207: stores.add(X509Store.getInstance("CRL/COLLECTION",
208: params, "BC"));
209: } catch (Exception e) {
210: // cannot happen
211: throw new RuntimeException(e.getMessage());
212: }
213: }
214: if (store.getCertStoreParameters() instanceof LDAPCertStoreParameters
215: || store.getCertStoreParameters() instanceof X509LDAPCertStoreParameters) {
216: X509LDAPCertStoreParameters params;
217: if (store.getCertStoreParameters() instanceof X509LDAPCertStoreParameters) {
218: params = (X509LDAPCertStoreParameters) store
219: .getCertStoreParameters();
220: } else {
221: int port = ((LDAPCertStoreParameters) store
222: .getCertStoreParameters()).getPort();
223: String server = ((LDAPCertStoreParameters) store
224: .getCertStoreParameters()).getServerName();
225: params = new X509LDAPCertStoreParameters.Builder(
226: "ldap://" + server + ":" + port, null).build();
227: }
228: try {
229: stores.add(X509Store.getInstance("CERTIFICATE/LDAP",
230: params, "BC"));
231: stores.add(X509Store.getInstance("CRL/LDAP", params,
232: "BC"));
233: } catch (Exception e) {
234: // cannot happen
235: throw new RuntimeException(e.getMessage());
236: }
237: }
238:
239: }
240:
241: /**
242: * Sets the Java CertStore to this extended PKIX parameters. If the stores
243: * use initialisation parameters of type
244: * <code>CollectionCertStoreParameters</code> or <code></code> the
245: * corresponding Bouncy Castle {@link Store} types are created additionally
246: * to it.
247: *
248: * @throws ClassCastException if an element of <code>stores</code> is not
249: * a <code>CertStore</code>.
250: */
251: public void setCertStores(List stores) {
252: if (stores != null) {
253: Iterator it = stores.iterator();
254: while (it.hasNext()) {
255: addCertStore((CertStore) it.next());
256: }
257: }
258: }
259:
260: /**
261: * Sets the Bouncy Castle Stores for finding CRLs, certificates, attribute
262: * certificates or cross certificates.
263: * <p>
264: * The <code>List</code> is cloned.
265: *
266: * @param stores A list of stores to use.
267: * @see #getStores
268: * @throws ClassCastException if an element of <code>stores</code> is not
269: * a {@link Store}.
270: */
271: public void setStores(List stores) {
272: if (stores == null) {
273: this .stores = new ArrayList();
274: } else {
275: for (Iterator i = stores.iterator(); i.hasNext();) {
276: if (!(i.next() instanceof Store)) {
277: throw new ClassCastException(
278: "All elements of list must be "
279: + "of type org.bouncycastle.util.Store.");
280: }
281: }
282: this .stores = new ArrayList(stores);
283: }
284: }
285:
286: /**
287: * Adds a Bouncy Castle {@link Store} to find CRLs, certificates, attribute
288: * certificates or cross certificates.
289: * <p>
290: * This method should be used to add local stores, like collection based
291: * X.509 stores, if available. Local stores should be considered first,
292: * before trying to use additional (remote) locations, because they do not
293: * need possible additional network traffic.
294: * <p>
295: * If <code>store</code> is <code>null</code> it is ignored.
296: *
297: * @param store The store to add.
298: * @see #getStores
299: */
300: public void addStore(Store store) {
301: if (stores != null) {
302: stores.add(store);
303: }
304: }
305:
306: /**
307: * Adds a additional Bouncy Castle {@link Store} to find CRLs, certificates,
308: * attribute certificates or cross certificates.
309: * <p>
310: * You should not use this method. This method is used for adding additional
311: * X.509 stores, which are used to add (remote) locations, e.g. LDAP, found
312: * during X.509 object processing, e.g. in certificates or CRLs. This method
313: * is used in PKIX certification path processing.
314: * <p>
315: * If <code>store</code> is <code>null</code> it is ignored.
316: *
317: * @param store The store to add.
318: * @see #getStores()
319: */
320: public void addAddionalStore(Store store) {
321: if (store != null) {
322: additionalStores.add(store);
323: }
324: }
325:
326: /**
327: * Returns an immutable <code>List</code> of additional Bouncy Castle
328: * <code>Store</code>s used for finding CRLs, certificates, attribute
329: * certificates or cross certificates.
330: *
331: * @return an immutable <code>List</code> of additional Bouncy Castle
332: * <code>Store</code>s. Never <code>null</code>.
333: *
334: * @see #addAddionalStore(Store)
335: */
336: public List getAddionalStores() {
337: return Collections.unmodifiableList(additionalStores);
338: }
339:
340: /**
341: * Returns an immutable <code>List</code> of Bouncy Castle
342: * <code>Store</code>s used for finding CRLs, certificates, attribute
343: * certificates or cross certificates.
344: *
345: * @return an immutable <code>List</code> of Bouncy Castle
346: * <code>Store</code>s. Never <code>null</code>.
347: *
348: * @see #setStores(List)
349: */
350: public List getStores() {
351: return Collections.unmodifiableList(new ArrayList(stores));
352: }
353:
354: /**
355: * @param validityModel The validity model to set.
356: * @see #CHAIN_VALIDITY_MODEL
357: * @see #PKIX_VALIDITY_MODEL
358: */
359: public void setValidityModel(int validityModel) {
360: this .validityModel = validityModel;
361: }
362:
363: public Object clone() {
364: ExtendedPKIXParameters params;
365: try {
366: params = new ExtendedPKIXParameters(getTrustAnchors());
367: } catch (Exception e) {
368: // cannot happen
369: throw new RuntimeException(e.getMessage());
370: }
371: params.setParams(this );
372: return params;
373: }
374:
375: /**
376: * Returns if additional {@link X509Store}s for locations like LDAP found
377: * in certificates or CRLs should be used.
378: *
379: * @return Returns <code>true</code> if additional stores are used.
380: */
381: public boolean isAdditionalLocationsEnabled() {
382: return additionalLocationsEnabled;
383: }
384:
385: /**
386: * Sets if additional {@link X509Store}s for locations like LDAP found in
387: * certificates or CRLs should be used.
388: *
389: * @param enabled <code>true</code> if additional stores are used.
390: */
391: public void setAdditionalLocationsEnabled(boolean enabled) {
392: additionalLocationsEnabled = enabled;
393: }
394:
395: /**
396: * Returns the required constraints on the target certificate or attribute
397: * certificate. The constraints are returned as an instance of
398: * <code>Selector</code>. If <code>null</code>, no constraints are
399: * defined.
400: *
401: * <p>
402: * The target certificate in a PKIX path may be a certificate or an
403: * attribute certificate.
404: * <p>
405: * Note that the <code>Selector</code> returned is cloned to protect
406: * against subsequent modifications.
407: *
408: * @return a <code>Selector</code> specifying the constraints on the
409: * target certificate or attribute certificate (or <code>null</code>)
410: * @see #setTargetConstraints
411: * @see X509CertStoreSelector
412: * @see X509AttributeCertStoreSelector
413: */
414: public Selector getTargetConstraints() {
415: if (selector != null) {
416: return (Selector) selector.clone();
417: } else {
418: return null;
419: }
420: }
421:
422: /**
423: * Sets the required constraints on the target certificate or attribute
424: * certificate. The constraints are specified as an instance of
425: * <code>Selector</code>. If <code>null</code>, no constraints are
426: * defined.
427: * <p>
428: * The target certificate in a PKIX path may be a certificate or an
429: * attribute certificate.
430: * <p>
431: * Note that the <code>Selector</code> specified is cloned to protect
432: * against subsequent modifications.
433: *
434: * @param selector a <code>Selector</code> specifying the constraints on
435: * the target certificate or attribute certificate (or
436: * <code>null</code>)
437: * @see #getTargetConstraints
438: * @see X509CertStoreSelector
439: * @see X509AttributeCertStoreSelector
440: */
441: public void setTargetConstraints(Selector selector) {
442: if (selector != null) {
443: this .selector = (Selector) selector.clone();
444: } else {
445: this .selector = null;
446: }
447: }
448:
449: /**
450: * Sets the required constraints on the target certificate. The constraints
451: * are specified as an instance of <code>X509CertSelector</code>. If
452: * <code>null</code>, no constraints are defined.
453: *
454: * <p>
455: * This method wraps the given <code>X509CertSelector</code> into a
456: * <code>X509CertStoreSelector</code>.
457: * <p>
458: * Note that the <code>X509CertSelector</code> specified is cloned to
459: * protect against subsequent modifications.
460: *
461: * @param selector a <code>X509CertSelector</code> specifying the
462: * constraints on the target certificate (or <code>null</code>)
463: * @see #getTargetCertConstraints
464: * @see X509CertStoreSelector
465: */
466: public void setTargetCertConstraints(CertSelector selector) {
467: super .setTargetCertConstraints(selector);
468: if (selector != null) {
469: this .selector = X509CertStoreSelector
470: .getInstance((X509CertSelector) selector);
471: } else {
472: this .selector = null;
473: }
474: }
475:
476: /**
477: * Returns the trusted attribute certificate issuers. If attribute
478: * certificates is verified the trusted AC issuers must be set.
479: * <p>
480: * The returned <code>Set</code> consists of <code>TrustAnchor</code>s.
481: * <p>
482: * The returned <code>Set</code> is immutable. Never <code>null</code>
483: *
484: * @return Returns an immutable set of the trusted AC issuers.
485: */
486: public Set getTrustedACIssuers() {
487: return Collections.unmodifiableSet(trustedACIssuers);
488: }
489:
490: /**
491: * Sets the trusted attribute certificate issuers. If attribute certificates
492: * is verified the trusted AC issuers must be set.
493: * <p>
494: * The <code>trustedACIssuers</code> must be a <code>Set</code> of
495: * <code>TrustAnchor</code>
496: * <p>
497: * The given set is cloned.
498: *
499: * @param trustedACIssuers The trusted AC issuers to set. Is never
500: * <code>null</code>.
501: * @throws ClassCastException if an element of <code>stores</code> is not
502: * a <code>TrustAnchor</code>.
503: */
504: public void setTrustedACIssuers(Set trustedACIssuers) {
505: if (trustedACIssuers == null) {
506: trustedACIssuers.clear();
507: return;
508: }
509: for (Iterator it = trustedACIssuers.iterator(); it.hasNext();) {
510: if (!(it.next() instanceof TrustAnchor)) {
511: throw new ClassCastException(
512: "All elements of set must be " + "of type "
513: + TrustAnchor.class.getName() + ".");
514: }
515: }
516: this .trustedACIssuers.clear();
517: this .trustedACIssuers.addAll(trustedACIssuers);
518: }
519:
520: /**
521: * Returns the neccessary attributes which must be contained in an attribute
522: * certificate.
523: * <p>
524: * The returned <code>Set</code> is immutable and contains
525: * <code>String</code>s with the OIDs.
526: *
527: * @return Returns the necessary AC attributes.
528: */
529: public Set getNecessaryACAttributes() {
530: return Collections.unmodifiableSet(necessaryACAttributes);
531: }
532:
533: /**
534: * Sets the neccessary which must be contained in an attribute certificate.
535: * <p>
536: * The <code>Set</code> must contain <code>String</code>s with the
537: * OIDs.
538: * <p>
539: * The set is cloned.
540: *
541: * @param necessaryACAttributes The necessary AC attributes to set.
542: * @throws ClassCastException if an element of
543: * <code>necessaryACAttributes</code> is not a
544: * <code>String</code>.
545: */
546: public void setNecessaryACAttributes(Set necessaryACAttributes) {
547: if (necessaryACAttributes == null) {
548: this .necessaryACAttributes.clear();
549: return;
550: }
551: for (Iterator it = necessaryACAttributes.iterator(); it
552: .hasNext();) {
553: if (!(it.next() instanceof String)) {
554: throw new ClassCastException(
555: "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: return prohibitedACAttributes;
573: }
574:
575: /**
576: * Sets the attribute certificates which are not allowed.
577: * <p>
578: * The <code>Set</code> must contain <code>String</code>s with the
579: * OIDs.
580: * <p>
581: * The set is cloned.
582: *
583: * @param prohibitedACAttributes The prohibited AC attributes to set.
584: * @throws ClassCastException if an element of
585: * <code>prohibitedACAttributes</code> is not a
586: * <code>String</code>.
587: */
588: public void setProhibitedACAttributes(Set prohibitedACAttributes) {
589: if (prohibitedACAttributes == null) {
590: this .prohibitedACAttributes.clear();
591: return;
592: }
593: for (Iterator it = prohibitedACAttributes.iterator(); it
594: .hasNext();) {
595: if (!(it.next() instanceof String)) {
596: throw new ClassCastException(
597: "All elements of set must be "
598: + "of type String.");
599: }
600: }
601: this .prohibitedACAttributes.clear();
602: this .prohibitedACAttributes.addAll(prohibitedACAttributes);
603: }
604:
605: /**
606: * Returns the attribute certificate checker. The returned set contains
607: * {@link PKIXAttrCertChecker}s and is immutable.
608: *
609: * @return Returns the attribute certificate checker. Is never
610: * <code>null</code>.
611: */
612: public Set getAttrCertCheckers() {
613: return Collections.unmodifiableSet(attrCertCheckers);
614: }
615:
616: /**
617: * Sets the attribute certificate checkers.
618: * <p>
619: * All elements in the <code>Set</code> must a {@link PKIXAttrCertChecker}.
620: * <p>
621: * The given set is cloned.
622: *
623: * @param attrCertCheckers The attribute certificate checkers to set. Is
624: * never <code>null</code>.
625: * @throws ClassCastException if an element of <code>attrCertCheckers</code>
626: * is not a <code>PKIXAttrCertChecker</code>.
627: */
628: public void setAttrCertCheckers(Set attrCertCheckers) {
629: if (attrCertCheckers == null) {
630: this .attrCertCheckers.clear();
631: return;
632: }
633: for (Iterator it = attrCertCheckers.iterator(); it.hasNext();) {
634: if (!(it.next() instanceof PKIXAttrCertChecker)) {
635: throw new ClassCastException(
636: "All elements of set must be " + "of type "
637: + PKIXAttrCertChecker.class.getName()
638: + ".");
639: }
640: }
641: this.attrCertCheckers.clear();
642: this.attrCertCheckers.addAll(attrCertCheckers);
643: }
644:
645: }
|