blob: 63ed8ab010e54d0ddf315778f99142e8327c233d [file] [log] [blame]
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.Extension;
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(Extension.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(Extension.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);
}
}