| package org.bouncycastle.x509; |
| |
| import java.io.IOException; |
| import java.math.BigInteger; |
| import java.security.cert.CRL; |
| import java.security.cert.X509CRL; |
| import java.security.cert.X509CRLSelector; |
| |
| import org.bouncycastle.asn1.ASN1Integer; |
| import org.bouncycastle.asn1.x509.X509Extensions; |
| import org.bouncycastle.util.Arrays; |
| import org.bouncycastle.util.Selector; |
| import org.bouncycastle.x509.extension.X509ExtensionUtil; |
| |
| /** |
| * This class is a Selector implementation for X.509 certificate revocation |
| * lists. |
| * |
| * @see org.bouncycastle.util.Selector |
| * @see org.bouncycastle.x509.X509Store |
| * @see org.bouncycastle.jce.provider.X509StoreCRLCollection |
| */ |
| public class X509CRLStoreSelector |
| extends X509CRLSelector |
| implements Selector |
| { |
| private boolean deltaCRLIndicator = false; |
| |
| private boolean completeCRLEnabled = false; |
| |
| private BigInteger maxBaseCRLNumber = null; |
| |
| private byte[] issuingDistributionPoint = null; |
| |
| private boolean issuingDistributionPointEnabled = false; |
| |
| private X509AttributeCertificate attrCertChecking; |
| |
| /** |
| * Returns if the issuing distribution point criteria should be applied. |
| * Defaults to <code>false</code>. |
| * <p> |
| * You may also set the issuing distribution point criteria if not a missing |
| * issuing distribution point should be assumed. |
| * |
| * @return Returns if the issuing distribution point check is enabled. |
| */ |
| public boolean isIssuingDistributionPointEnabled() |
| { |
| return issuingDistributionPointEnabled; |
| } |
| |
| /** |
| * Enables or disables the issuing distribution point check. |
| * |
| * @param issuingDistributionPointEnabled <code>true</code> to enable the |
| * issuing distribution point check. |
| */ |
| public void setIssuingDistributionPointEnabled( |
| boolean issuingDistributionPointEnabled) |
| { |
| this.issuingDistributionPointEnabled = issuingDistributionPointEnabled; |
| } |
| |
| /** |
| * Sets the attribute certificate being checked. This is not a criterion. |
| * Rather, it is optional information that may help a {@link X509Store} find |
| * CRLs that would be relevant when checking revocation for the specified |
| * attribute certificate. If <code>null</code> is specified, then no such |
| * optional information is provided. |
| * |
| * @param attrCert the <code>X509AttributeCertificate</code> being checked (or |
| * <code>null</code>) |
| * @see #getAttrCertificateChecking() |
| */ |
| public void setAttrCertificateChecking(X509AttributeCertificate attrCert) |
| { |
| attrCertChecking = attrCert; |
| } |
| |
| /** |
| * Returns the attribute certificate being checked. |
| * |
| * @return Returns the attribute certificate being checked. |
| * @see #setAttrCertificateChecking(X509AttributeCertificate) |
| */ |
| public X509AttributeCertificate getAttrCertificateChecking() |
| { |
| return attrCertChecking; |
| } |
| |
| public boolean match(Object obj) |
| { |
| if (!(obj instanceof X509CRL)) |
| { |
| return false; |
| } |
| X509CRL crl = (X509CRL)obj; |
| ASN1Integer dci = null; |
| try |
| { |
| byte[] bytes = crl |
| .getExtensionValue(X509Extensions.DeltaCRLIndicator.getId()); |
| if (bytes != null) |
| { |
| dci = ASN1Integer.getInstance(X509ExtensionUtil |
| .fromExtensionValue(bytes)); |
| } |
| } |
| catch (Exception e) |
| { |
| return false; |
| } |
| if (isDeltaCRLIndicatorEnabled()) |
| { |
| if (dci == null) |
| { |
| return false; |
| } |
| } |
| if (isCompleteCRLEnabled()) |
| { |
| if (dci != null) |
| { |
| return false; |
| } |
| } |
| if (dci != null) |
| { |
| |
| if (maxBaseCRLNumber != null) |
| { |
| if (dci.getPositiveValue().compareTo(maxBaseCRLNumber) == 1) |
| { |
| return false; |
| } |
| } |
| } |
| if (issuingDistributionPointEnabled) |
| { |
| byte[] idp = crl |
| .getExtensionValue(X509Extensions.IssuingDistributionPoint |
| .getId()); |
| if (issuingDistributionPoint == null) |
| { |
| if (idp != null) |
| { |
| return false; |
| } |
| } |
| else |
| { |
| if (!Arrays.areEqual(idp, issuingDistributionPoint)) |
| { |
| return false; |
| } |
| } |
| |
| } |
| return super.match((X509CRL)obj); |
| } |
| |
| public boolean match(CRL crl) |
| { |
| return match((Object)crl); |
| } |
| |
| /** |
| * Returns if this selector must match CRLs with the delta CRL indicator |
| * extension set. Defaults to <code>false</code>. |
| * |
| * @return Returns <code>true</code> if only CRLs with the delta CRL |
| * indicator extension are selected. |
| */ |
| public boolean isDeltaCRLIndicatorEnabled() |
| { |
| return deltaCRLIndicator; |
| } |
| |
| /** |
| * If this is set to <code>true</code> the CRL reported contains the delta |
| * CRL indicator CRL extension. |
| * <p> |
| * {@link #setCompleteCRLEnabled(boolean)} and |
| * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. |
| * |
| * @param deltaCRLIndicator <code>true</code> if the delta CRL indicator |
| * extension must be in the CRL. |
| */ |
| public void setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator) |
| { |
| this.deltaCRLIndicator = deltaCRLIndicator; |
| } |
| |
| /** |
| * Returns an instance of this from a <code>X509CRLSelector</code>. |
| * |
| * @param selector A <code>X509CRLSelector</code> instance. |
| * @return An instance of an <code>X509CRLStoreSelector</code>. |
| * @exception IllegalArgumentException if selector is null or creation |
| * fails. |
| */ |
| public static X509CRLStoreSelector getInstance(X509CRLSelector selector) |
| { |
| if (selector == null) |
| { |
| throw new IllegalArgumentException( |
| "cannot create from null selector"); |
| } |
| X509CRLStoreSelector cs = new X509CRLStoreSelector(); |
| cs.setCertificateChecking(selector.getCertificateChecking()); |
| cs.setDateAndTime(selector.getDateAndTime()); |
| try |
| { |
| cs.setIssuerNames(selector.getIssuerNames()); |
| } |
| catch (IOException e) |
| { |
| // cannot happen |
| throw new IllegalArgumentException(e.getMessage()); |
| } |
| cs.setIssuers(selector.getIssuers()); |
| cs.setMaxCRLNumber(selector.getMaxCRL()); |
| cs.setMinCRLNumber(selector.getMinCRL()); |
| return cs; |
| } |
| |
| public Object clone() |
| { |
| X509CRLStoreSelector sel = X509CRLStoreSelector.getInstance(this); |
| sel.deltaCRLIndicator = deltaCRLIndicator; |
| sel.completeCRLEnabled = completeCRLEnabled; |
| sel.maxBaseCRLNumber = maxBaseCRLNumber; |
| sel.attrCertChecking = attrCertChecking; |
| sel.issuingDistributionPointEnabled = issuingDistributionPointEnabled; |
| sel.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); |
| return sel; |
| } |
| |
| /** |
| * If <code>true</code> only complete CRLs are returned. Defaults to |
| * <code>false</code>. |
| * |
| * @return <code>true</code> if only complete CRLs are returned. |
| */ |
| public boolean isCompleteCRLEnabled() |
| { |
| return completeCRLEnabled; |
| } |
| |
| /** |
| * If set to <code>true</code> only complete CRLs are returned. |
| * <p> |
| * {@link #setCompleteCRLEnabled(boolean)} and |
| * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other. |
| * |
| * @param completeCRLEnabled <code>true</code> if only complete CRLs |
| * should be returned. |
| */ |
| public void setCompleteCRLEnabled(boolean completeCRLEnabled) |
| { |
| this.completeCRLEnabled = completeCRLEnabled; |
| } |
| |
| /** |
| * Get the maximum base CRL number. Defaults to <code>null</code>. |
| * |
| * @return Returns the maximum base CRL number. |
| * @see #setMaxBaseCRLNumber(BigInteger) |
| */ |
| public BigInteger getMaxBaseCRLNumber() |
| { |
| return maxBaseCRLNumber; |
| } |
| |
| /** |
| * Sets the maximum base CRL number. Setting to <code>null</code> disables |
| * this cheack. |
| * <p> |
| * This is only meaningful for delta CRLs. Complete CRLs must have a CRL |
| * number which is greater or equal than the base number of the |
| * corresponding CRL. |
| * |
| * @param maxBaseCRLNumber The maximum base CRL number to set. |
| */ |
| public void setMaxBaseCRLNumber(BigInteger maxBaseCRLNumber) |
| { |
| this.maxBaseCRLNumber = maxBaseCRLNumber; |
| } |
| |
| /** |
| * Returns the issuing distribution point. Defaults to <code>null</code>, |
| * which is a missing issuing distribution point extension. |
| * <p> |
| * The internal byte array is cloned before it is returned. |
| * <p> |
| * The criteria must be enable with |
| * {@link #setIssuingDistributionPointEnabled(boolean)}. |
| * |
| * @return Returns the issuing distribution point. |
| * @see #setIssuingDistributionPoint(byte[]) |
| */ |
| public byte[] getIssuingDistributionPoint() |
| { |
| return Arrays.clone(issuingDistributionPoint); |
| } |
| |
| /** |
| * Sets the issuing distribution point. |
| * <p> |
| * The issuing distribution point extension is a CRL extension which |
| * identifies the scope and the distribution point of a CRL. The scope |
| * contains among others information about revocation reasons contained in |
| * the CRL. Delta CRLs and complete CRLs must have matching issuing |
| * distribution points. |
| * <p> |
| * The byte array is cloned to protect against subsequent modifications. |
| * <p> |
| * You must also enable or disable this criteria with |
| * {@link #setIssuingDistributionPointEnabled(boolean)}. |
| * |
| * @param issuingDistributionPoint The issuing distribution point to set. |
| * This is the DER encoded OCTET STRING extension value. |
| * @see #getIssuingDistributionPoint() |
| */ |
| public void setIssuingDistributionPoint(byte[] issuingDistributionPoint) |
| { |
| this.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint); |
| } |
| } |