org.bouncycastle.jcajce.PKIXCRLStoreSelector Maven / Gradle / Ivy
Show all versions of bcprov-debug-jdk15to18 Show documentation
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
implements Selector
{
/**
* Builder for a PKIXCRLStoreSelector.
*/
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;
/**
* Constructor initializing a builder with a CertSelector.
*
* @param crlSelector the CertSelector to copy the match details from.
*/
public Builder(CRLSelector crlSelector)
{
this.baseSelector = (CRLSelector)crlSelector.clone();
}
/**
* If set to true
only complete CRLs are returned.
*
* {@link #setCompleteCRLEnabled(boolean)} and
* {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other.
*
* @param completeCRLEnabled true
if only complete CRLs
* should be returned.
*/
public Builder setCompleteCRLEnabled(boolean completeCRLEnabled)
{
this.completeCRLEnabled = completeCRLEnabled;
return this;
}
/**
* If this is set to true
the CRL reported contains the delta
* CRL indicator CRL extension.
*
* {@link #setCompleteCRLEnabled(boolean)} and
* {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other.
*
* @param deltaCRLIndicator true
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 null
disables
* this cheack.
*
* 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 true
to enable the
* issuing distribution point check.
*/
public void setIssuingDistributionPointEnabled(
boolean issuingDistributionPointEnabled)
{
this.issuingDistributionPointEnabled = issuingDistributionPointEnabled;
}
/**
* Sets the issuing distribution point.
*
* 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.
*
* The byte array is cloned to protect against subsequent modifications.
*
* 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);
}
/**
* Build a selector.
*
* @return a new PKIXCRLStoreSelector
*/
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 false
.
*
* 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 false
.
*
* @return Returns true
if only CRLs with the delta CRL
* indicator extension are selected.
*/
public boolean isDeltaCRLIndicatorEnabled()
{
return deltaCRLIndicator;
}
public Object clone()
{
return this;
}
/**
* If true
only complete CRLs are returned. Defaults to
* false
.
*
* @return true
if only complete CRLs are returned.
*/
public boolean isCompleteCRLEnabled()
{
return completeCRLEnabled;
}
/**
* Get the maximum base CRL number. Defaults to null
.
*
* @return Returns the maximum base CRL number.
*/
public BigInteger getMaxBaseCRLNumber()
{
return maxBaseCRLNumber;
}
/**
* Returns the issuing distribution point. Defaults to null
,
* which is a missing issuing distribution point extension.
*
* The internal byte array is cloned before it is returned.
*
* 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()
{
if (baseSelector instanceof X509CRLSelector)
{
return ((X509CRLSelector)baseSelector).getCertificateChecking();
}
return null;
}
public static Collection extends CRL> getCRLs(final PKIXCRLStoreSelector selector, CertStore certStore)
throws CertStoreException
{
return certStore.getCRLs(new SelectorClone(selector));
}
private static class SelectorClone
extends X509CRLSelector
{
private final PKIXCRLStoreSelector selector;
SelectorClone(PKIXCRLStoreSelector selector)
{
this.selector = selector;
if (selector.baseSelector instanceof X509CRLSelector)
{
X509CRLSelector baseSelector = (X509CRLSelector)selector.baseSelector;
this.setCertificateChecking(baseSelector.getCertificateChecking());
this.setDateAndTime(baseSelector.getDateAndTime());
this.setIssuers(baseSelector.getIssuers());
this.setMinCRLNumber(baseSelector.getMinCRL());
this.setMaxCRLNumber(baseSelector.getMaxCRL());
}
}
public boolean match(CRL crl)
{
return (selector == null) ? (crl != null) : selector.match(crl);
}
}
}