using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Date;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Extension;
namespace Org.BouncyCastle.X509.Store
{
public class X509CrlStoreSelector
: IX509Selector
{
// TODO Missing criteria?
private X509Certificate certificateChecking;
private DateTimeObject dateAndTime;
private ICollection issuers;
private BigInteger maxCrlNumber;
private BigInteger minCrlNumber;
private IX509AttributeCertificate attrCertChecking;
private bool completeCrlEnabled;
private bool deltaCrlIndicatorEnabled;
private byte[] issuingDistributionPoint;
private bool issuingDistributionPointEnabled;
private BigInteger maxBaseCrlNumber;
public X509CrlStoreSelector()
{
}
public X509CrlStoreSelector(
X509CrlStoreSelector o)
{
this.certificateChecking = o.CertificateChecking;
this.dateAndTime = o.DateAndTime;
this.issuers = o.Issuers;
this.maxCrlNumber = o.MaxCrlNumber;
this.minCrlNumber = o.MinCrlNumber;
this.deltaCrlIndicatorEnabled = o.DeltaCrlIndicatorEnabled;
this.completeCrlEnabled = o.CompleteCrlEnabled;
this.maxBaseCrlNumber = o.MaxBaseCrlNumber;
this.attrCertChecking = o.AttrCertChecking;
this.issuingDistributionPointEnabled = o.IssuingDistributionPointEnabled;
this.issuingDistributionPoint = o.IssuingDistributionPoint;
}
public virtual object Clone()
{
return new X509CrlStoreSelector(this);
}
public X509Certificate CertificateChecking
{
get { return certificateChecking; }
set { certificateChecking = value; }
}
public DateTimeObject DateAndTime
{
get { return dateAndTime; }
set { dateAndTime = value; }
}
/// ICollection
of X509Name
objects
/// null
is specified, then no such
* optional information is provided.
*
* @param attrCert the IX509AttributeCertificate
being checked (or
* null
)
* @see #getAttrCertificateChecking()
*/
public IX509AttributeCertificate AttrCertChecking
{
get { return attrCertChecking; }
set { this.attrCertChecking = value; }
}
/**
* If true
only complete CRLs are returned. Defaults to
* false
.
*
* @return true
if only complete CRLs are returned.
*/
public bool CompleteCrlEnabled
{
get { return completeCrlEnabled; }
set { this.completeCrlEnabled = value; }
}
/**
* 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 bool DeltaCrlIndicatorEnabled
{
get { return deltaCrlIndicatorEnabled; }
set { this.deltaCrlIndicatorEnabled = value; }
}
/**
* 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(bool)}.
* * @param issuingDistributionPoint The issuing distribution point to set. * This is the DER encoded OCTET STRING extension value. * @see #getIssuingDistributionPoint() */ public byte[] IssuingDistributionPoint { get { return Arrays.Clone(issuingDistributionPoint); } set { this.issuingDistributionPoint = Arrays.Clone(value); } } /** * Whether the issuing distribution point criteria should be applied. * Defaults tofalse
.
* * 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 bool IssuingDistributionPointEnabled { get { return issuingDistributionPointEnabled; } set { this.issuingDistributionPointEnabled = value; } } /** * The maximum base CRL number. Defaults tonull
.
*
* @return Returns the maximum base CRL number.
* @see #setMaxBaseCRLNumber(BigInteger)
*/
public BigInteger MaxBaseCrlNumber
{
get { return maxBaseCrlNumber; }
set { this.maxBaseCrlNumber = value; }
}
public virtual bool Match(
object obj)
{
X509Crl c = obj as X509Crl;
if (c == null)
return false;
if (dateAndTime != null)
{
DateTime dt = dateAndTime.Value;
DateTime tu = c.ThisUpdate;
DateTimeObject nu = c.NextUpdate;
if (dt.CompareTo(tu) < 0 || nu == null || dt.CompareTo(nu.Value) >= 0)
return false;
}
if (issuers != null)
{
X509Name i = c.IssuerDN;
bool found = false;
foreach (X509Name issuer in issuers)
{
if (issuer.Equivalent(i, true))
{
found = true;
break;
}
}
if (!found)
return false;
}
if (maxCrlNumber != null || minCrlNumber != null)
{
Asn1OctetString extVal = c.GetExtensionValue(X509Extensions.CrlNumber);
if (extVal == null)
return false;
BigInteger cn = CrlNumber.GetInstance(
X509ExtensionUtilities.FromExtensionValue(extVal)).PositiveValue;
if (maxCrlNumber != null && cn.CompareTo(maxCrlNumber) > 0)
return false;
if (minCrlNumber != null && cn.CompareTo(minCrlNumber) < 0)
return false;
}
DerInteger dci = null;
try
{
Asn1OctetString bytes = c.GetExtensionValue(X509Extensions.DeltaCrlIndicator);
if (bytes != null)
{
dci = DerInteger.GetInstance(X509ExtensionUtilities.FromExtensionValue(bytes));
}
}
catch (Exception)
{
return false;
}
if (dci == null)
{
if (DeltaCrlIndicatorEnabled)
return false;
}
else
{
if (CompleteCrlEnabled)
return false;
if (maxBaseCrlNumber != null && dci.PositiveValue.CompareTo(maxBaseCrlNumber) > 0)
return false;
}
if (issuingDistributionPointEnabled)
{
Asn1OctetString idp = c.GetExtensionValue(X509Extensions.IssuingDistributionPoint);
if (issuingDistributionPoint == null)
{
if (idp != null)
return false;
}
else
{
if (!Arrays.AreEqual(idp.GetOctets(), issuingDistributionPoint))
return false;
}
}
return true;
}
}
}