001: package org.bouncycastle.x509;
002:
003: import org.bouncycastle.asn1.DERInteger;
004: import org.bouncycastle.asn1.x509.X509Extensions;
005: import org.bouncycastle.util.Arrays;
006: import org.bouncycastle.util.Selector;
007: import org.bouncycastle.x509.extension.X509ExtensionUtil;
008:
009: import java.io.IOException;
010: import java.math.BigInteger;
011: import java.security.cert.CRL;
012: import java.security.cert.X509CRL;
013: import java.security.cert.X509CRLSelector;
014:
015: /**
016: * This class is a Selector implementation for X.509 certificate revocation
017: * lists.
018: *
019: * @see org.bouncycastle.util.Selector
020: * @see org.bouncycastle.x509.X509Store
021: * @see org.bouncycastle.jce.provider.X509StoreCRLCollection
022: */
023: public class X509CRLStoreSelector extends X509CRLSelector implements
024: Selector {
025: private boolean deltaCRLIndicator = false;
026:
027: private boolean completeCRLEnabled = false;
028:
029: private BigInteger maxBaseCRLNumber = null;
030:
031: private byte[] issuingDistributionPoint = null;
032:
033: private boolean issuingDistributionPointEnabled = false;
034:
035: private X509AttributeCertificate attrCertChecking;
036:
037: /**
038: * Returns if the issuing distribution point criteria should be applied.
039: * Defaults to <code>false</code>.
040: * <p>
041: * You may also set the issuing distribution point criteria if not a missing
042: * issuing distribution point should be assumed.
043: *
044: * @return Returns if the issuing distribution point check is enabled.
045: */
046: public boolean isIssuingDistributionPointEnabled() {
047: return issuingDistributionPointEnabled;
048: }
049:
050: /**
051: * Enables or disables the issuing distribution point check.
052: *
053: * @param issuingDistributionPointEnabled <code>true</code> to enable the
054: * issuing distribution point check.
055: */
056: public void setIssuingDistributionPointEnabled(
057: boolean issuingDistributionPointEnabled) {
058: this .issuingDistributionPointEnabled = issuingDistributionPointEnabled;
059: }
060:
061: /**
062: * Sets the attribute certificate being checked. This is not a criterion.
063: * Rather, it is optional information that may help a {@link X509Store} find
064: * CRLs that would be relevant when checking revocation for the specified
065: * attribute certificate. If <code>null</code> is specified, then no such
066: * optional information is provided.
067: *
068: * @param attrCert the <code>X509AttributeCertificate</code> being checked (or
069: * <code>null</code>)
070: * @see #getAttrCertificateChecking()
071: */
072: public void setAttrCertificateChecking(
073: X509AttributeCertificate attrCert) {
074: attrCertChecking = attrCert;
075: }
076:
077: /**
078: * Returns the attribute certificate being checked.
079: *
080: * @return Returns the attribute certificate being checked.
081: * @see #setAttrCertificateChecking(X509AttributeCertificate)
082: */
083: public X509AttributeCertificate getAttrCertificateChecking() {
084: return attrCertChecking;
085: }
086:
087: public boolean match(Object obj) {
088: if (!(obj instanceof X509CRL)) {
089: return false;
090: }
091: X509CRL crl = (X509CRL) obj;
092: DERInteger dci = null;
093: try {
094: byte[] bytes = crl
095: .getExtensionValue(X509Extensions.DeltaCRLIndicator
096: .getId());
097: if (bytes != null) {
098: dci = DERInteger.getInstance(X509ExtensionUtil
099: .fromExtensionValue(bytes));
100: }
101: } catch (Exception e) {
102: return false;
103: }
104: if (isDeltaCRLIndicatorEnabled()) {
105: if (dci == null) {
106: return false;
107: }
108: }
109: if (isCompleteCRLEnabled()) {
110: if (dci != null) {
111: return false;
112: }
113: }
114: if (dci != null) {
115:
116: if (maxBaseCRLNumber != null) {
117: if (dci.getPositiveValue().compareTo(maxBaseCRLNumber) == 1) {
118: return false;
119: }
120: }
121: }
122: if (issuingDistributionPointEnabled) {
123: byte[] idp = crl
124: .getExtensionValue(X509Extensions.IssuingDistributionPoint
125: .getId());
126: if (issuingDistributionPoint == null) {
127: if (idp != null) {
128: return false;
129: }
130: } else {
131: if (!Arrays.areEqual(idp, issuingDistributionPoint)) {
132: return false;
133: }
134: }
135:
136: }
137: return super .match((X509CRL) obj);
138: }
139:
140: public boolean match(CRL crl) {
141: return match((Object) crl);
142: }
143:
144: /**
145: * Returns if this selector must match CRLs with the delta CRL indicator
146: * extension set. Defaults to <code>false</code>.
147: *
148: * @return Returns <code>true</code> if only CRLs with the delta CRL
149: * indicator extension are selected.
150: */
151: public boolean isDeltaCRLIndicatorEnabled() {
152: return deltaCRLIndicator;
153: }
154:
155: /**
156: * If this is set to <code>true</code> the CRL reported contains the delta
157: * CRL indicator CRL extension.
158: * <p>
159: * {@link #setCompleteCRLEnabled(boolean)} and
160: * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other.
161: *
162: * @param deltaCRLIndicator <code>true</code> if the delta CRL indicator
163: * extension must be in the CRL.
164: */
165: public void setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator) {
166: this .deltaCRLIndicator = deltaCRLIndicator;
167: }
168:
169: /**
170: * Returns an instance of this from a <code>X509CRLSelector</code>.
171: *
172: * @param selector A <code>X509CRLSelector</code> instance.
173: * @return An instance of an <code>X509CRLStoreSelector</code>.
174: * @exception IllegalArgumentException if selector is null or creation
175: * fails.
176: */
177: public static X509CRLStoreSelector getInstance(
178: X509CRLSelector selector) {
179: if (selector == null) {
180: throw new IllegalArgumentException(
181: "cannot create from null selector");
182: }
183: X509CRLStoreSelector cs = new X509CRLStoreSelector();
184: cs.setCertificateChecking(selector.getCertificateChecking());
185: cs.setDateAndTime(selector.getDateAndTime());
186: try {
187: cs.setIssuerNames(selector.getIssuerNames());
188: } catch (IOException e) {
189: // cannot happen
190: throw new IllegalArgumentException(e.getMessage());
191: }
192: cs.setIssuers(selector.getIssuers());
193: cs.setMaxCRLNumber(selector.getMaxCRL());
194: cs.setMinCRLNumber(selector.getMinCRL());
195: return cs;
196: }
197:
198: public Object clone() {
199: X509CRLStoreSelector sel = X509CRLStoreSelector
200: .getInstance(this );
201: sel.deltaCRLIndicator = deltaCRLIndicator;
202: sel.completeCRLEnabled = completeCRLEnabled;
203: sel.maxBaseCRLNumber = maxBaseCRLNumber;
204: sel.attrCertChecking = attrCertChecking;
205: sel.issuingDistributionPointEnabled = issuingDistributionPointEnabled;
206: sel.issuingDistributionPoint = Arrays
207: .clone(issuingDistributionPoint);
208: return sel;
209: }
210:
211: /**
212: * If <code>true</code> only complete CRLs are returned. Defaults to
213: * <code>false</code>.
214: *
215: * @return <code>true</code> if only complete CRLs are returned.
216: */
217: public boolean isCompleteCRLEnabled() {
218: return completeCRLEnabled;
219: }
220:
221: /**
222: * If set to <code>true</code> only complete CRLs are returned.
223: * <p>
224: * {@link #setCompleteCRLEnabled(boolean)} and
225: * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other.
226: *
227: * @param completeCRLEnabled <code>true</code> if only complete CRLs
228: * should be returned.
229: */
230: public void setCompleteCRLEnabled(boolean completeCRLEnabled) {
231: this .completeCRLEnabled = completeCRLEnabled;
232: }
233:
234: /**
235: * Get the maximum base CRL number. Defaults to <code>null</code>.
236: *
237: * @return Returns the maximum base CRL number.
238: * @see #setMaxBaseCRLNumber(BigInteger)
239: */
240: public BigInteger getMaxBaseCRLNumber() {
241: return maxBaseCRLNumber;
242: }
243:
244: /**
245: * Sets the maximum base CRL number. Setting to <code>null</code> disables
246: * this cheack.
247: * <p>
248: * This is only meaningful for delta CRLs. Complete CRLs must have a CRL
249: * number which is greater or equal than the base number of the
250: * corresponding CRL.
251: *
252: * @param maxBaseCRLNumber The maximum base CRL number to set.
253: */
254: public void setMaxBaseCRLNumber(BigInteger maxBaseCRLNumber) {
255: this .maxBaseCRLNumber = maxBaseCRLNumber;
256: }
257:
258: /**
259: * Returns the issuing distribution point. Defaults to <code>null</code>,
260: * which is a missing issuing distribution point extension.
261: * <p>
262: * The internal byte array is cloned before it is returned.
263: * <p>
264: * The criteria must be enable with
265: * {@link #setIssuingDistributionPointEnabled(boolean)}.
266: *
267: * @return Returns the issuing distribution point.
268: * @see #setIssuingDistributionPoint(byte[])
269: */
270: public byte[] getIssuingDistributionPoint() {
271: return Arrays.clone(issuingDistributionPoint);
272: }
273:
274: /**
275: * Sets the issuing distribution point.
276: * <p>
277: * The issuing distribution point extension is a CRL extension which
278: * identifies the scope and the distribution point of a CRL. The scope
279: * contains among others information about revocation reasons contained in
280: * the CRL. Delta CRLs and complete CRLs must have matching issuing
281: * distribution points.
282: * <p>
283: * The byte array is cloned to protect against subsequent modifications.
284: * <p>
285: * You must also enable or disable this criteria with
286: * {@link #setIssuingDistributionPointEnabled(boolean)}.
287: *
288: * @param issuingDistributionPoint The issuing distribution point to set.
289: * This is the DER encoded OCTET STRING extension value.
290: * @see #getIssuingDistributionPoint()
291: */
292: public void setIssuingDistributionPoint(
293: byte[] issuingDistributionPoint) {
294: this.issuingDistributionPoint = Arrays
295: .clone(issuingDistributionPoint);
296: }
297: }
|