diff options
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java')
-rw-r--r-- | bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java new file mode 100644 index 0000000..9c68433 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java @@ -0,0 +1,313 @@ +package org.bouncycastle.jcajce; + +import java.math.BigInteger; +import java.security.cert.CRL; +import java.security.cert.CRLSelector; +import java.security.cert.CertStore; +import java.security.cert.CertStoreException; +import java.security.cert.X509CRL; +import java.security.cert.X509CRLSelector; +import java.security.cert.X509Certificate; +import java.util.Collection; + +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Selector; + +/** + * This class is a Selector implementation for X.509 certificate revocation + * lists. + * + * @see org.bouncycastle.util.Selector + */ +public class PKIXCRLStoreSelector<T extends CRL> + implements Selector<T> +{ + public static class Builder + { + private final CRLSelector baseSelector; + + private boolean deltaCRLIndicator = false; + private boolean completeCRLEnabled = false; + private BigInteger maxBaseCRLNumber = null; + private byte[] issuingDistributionPoint = null; + private boolean issuingDistributionPointEnabled = false; + + public Builder(CRLSelector certSelector) + { + this.baseSelector = (CRLSelector)certSelector.clone(); + } + + + /** + * 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 Builder setCompleteCRLEnabled(boolean completeCRLEnabled) + { + this.completeCRLEnabled = completeCRLEnabled; + + return this; + } + + /** + * 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 Builder setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator) + { + this.deltaCRLIndicator = deltaCRLIndicator; + + return this; + } + + /** + * 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; + } + + /** + * 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 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); + } + + public PKIXCRLStoreSelector<? extends CRL> build() + { + return new PKIXCRLStoreSelector(this); + } + } + + private final CRLSelector baseSelector; + private final boolean deltaCRLIndicator; + private final boolean completeCRLEnabled; + private final BigInteger maxBaseCRLNumber; + private final byte[] issuingDistributionPoint; + private final boolean issuingDistributionPointEnabled; + + private PKIXCRLStoreSelector(Builder baseBuilder) + { + this.baseSelector = baseBuilder.baseSelector; + this.deltaCRLIndicator = baseBuilder.deltaCRLIndicator; + this.completeCRLEnabled = baseBuilder.completeCRLEnabled; + this.maxBaseCRLNumber = baseBuilder.maxBaseCRLNumber; + this.issuingDistributionPoint = baseBuilder.issuingDistributionPoint; + this.issuingDistributionPointEnabled = baseBuilder.issuingDistributionPointEnabled; + } + + + /** + * 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; + } + + + + public boolean match(CRL obj) + { + if (!(obj instanceof X509CRL)) + { + return baseSelector.match(obj); + } + + X509CRL crl = (X509CRL)obj; + ASN1Integer dci = null; + try + { + byte[] bytes = crl + .getExtensionValue(Extension.deltaCRLIndicator.getId()); + if (bytes != null) + { + dci = ASN1Integer.getInstance(ASN1OctetString.getInstance(bytes).getOctets()); + } + } + 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(Extension.issuingDistributionPoint + .getId()); + if (issuingDistributionPoint == null) + { + if (idp != null) + { + return false; + } + } + else + { + if (!Arrays.areEqual(idp, issuingDistributionPoint)) + { + return false; + } + } + + } + return baseSelector.match(obj); + } + + /** + * 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; + } + + public Object clone() + { + return this; + } + + /** + * 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; + } + + /** + * Get the maximum base CRL number. Defaults to <code>null</code>. + * + * @return Returns the maximum base CRL number. + */ + public BigInteger getMaxBaseCRLNumber() + { + return 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 Builder.setIssuingDistributionPointEnabled(boolean)}. + * + * @return Returns the issuing distribution point. + */ + public byte[] getIssuingDistributionPoint() + { + return Arrays.clone(issuingDistributionPoint); + } + + public X509Certificate getCertificateChecking() + { + return ((X509CRLSelector)baseSelector).getCertificateChecking(); + } + + public static Collection<? extends CRL> getCRLs(final PKIXCRLStoreSelector selector, CertStore certStore) + throws CertStoreException + { + return certStore.getCRLs(new CRLSelector() + { + public boolean match(CRL crl) + { + return selector.match(crl); + } + + public Object clone() + { + return this; + } + }); + } +} |