using System;
using System.Collections.Generic;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.X509.Extension;
namespace Org.BouncyCastle.X509.Store
{
/**
* This class is an Selector like implementation to select
* attribute certificates from a given set of criteria.
*
* @see org.bouncycastle.x509.X509AttributeCertificate
* @see org.bouncycastle.x509.X509Store
*/
public class X509AttrCertStoreSelector
: ISelector
{
// TODO: name constraints???
private X509V2AttributeCertificate attributeCert;
private DateTime? attributeCertificateValid;
private AttributeCertificateHolder holder;
private AttributeCertificateIssuer issuer;
private BigInteger serialNumber;
private ISet targetNames = new HashSet();
private ISet targetGroups = new HashSet();
public X509AttrCertStoreSelector()
{
}
private X509AttrCertStoreSelector(
X509AttrCertStoreSelector o)
{
this.attributeCert = o.attributeCert;
this.attributeCertificateValid = o.attributeCertificateValid;
this.holder = o.holder;
this.issuer = o.issuer;
this.serialNumber = o.serialNumber;
this.targetGroups = new HashSet(o.targetGroups);
this.targetNames = new HashSet(o.targetNames);
}
///
/// Decides if the given attribute certificate should be selected.
///
/// The attribute certificate to be checked.
/// true if the object matches this selector.
public bool Match(X509V2AttributeCertificate attrCert)
{
if (attrCert == null)
return false;
if (this.attributeCert != null && !this.attributeCert.Equals(attrCert))
return false;
if (serialNumber != null && !attrCert.SerialNumber.Equals(serialNumber))
return false;
if (holder != null && !attrCert.Holder.Equals(holder))
return false;
if (issuer != null && !attrCert.Issuer.Equals(issuer))
return false;
if (attributeCertificateValid != null && !attrCert.IsValid(attributeCertificateValid.Value))
return false;
if (targetNames.Count > 0 || targetGroups.Count > 0)
{
Asn1OctetString targetInfoExt = attrCert.GetExtensionValue(X509Extensions.TargetInformation);
if (targetInfoExt != null)
{
TargetInformation targetinfo;
try
{
targetinfo = TargetInformation.GetInstance(
X509ExtensionUtilities.FromExtensionValue(targetInfoExt));
}
catch (Exception)
{
return false;
}
Targets[] targetss = targetinfo.GetTargetsObjects();
if (targetNames.Count > 0)
{
bool found = false;
for (int i = 0; i < targetss.Length && !found; i++)
{
Target[] targets = targetss[i].GetTargets();
for (int j = 0; j < targets.Length; j++)
{
GeneralName targetName = targets[j].TargetName;
if (targetName != null && targetNames.Contains(targetName))
{
found = true;
break;
}
}
}
if (!found)
return false;
}
if (targetGroups.Count > 0)
{
bool found = false;
for (int i = 0; i < targetss.Length && !found; i++)
{
Target[] targets = targetss[i].GetTargets();
for (int j = 0; j < targets.Length; j++)
{
GeneralName targetGroup = targets[j].TargetGroup;
if (targetGroup != null && targetGroups.Contains(targetGroup))
{
found = true;
break;
}
}
}
if (!found)
return false;
}
}
}
return true;
}
public object Clone()
{
return new X509AttrCertStoreSelector(this);
}
/// The attribute certificate which must be matched.
/// If null is given, any will do.
public X509V2AttributeCertificate AttributeCert
{
get { return attributeCert; }
set { this.attributeCert = value; }
}
/// The criteria for validity
/// If null is given any will do.
public DateTime? AttributeCertificateValid
{
get { return attributeCertificateValid; }
set { this.attributeCertificateValid = value; }
}
/// The holder.
/// If null is given any will do.
public AttributeCertificateHolder Holder
{
get { return holder; }
set { this.holder = value; }
}
/// The issuer.
/// If null is given any will do.
public AttributeCertificateIssuer Issuer
{
get { return issuer; }
set { this.issuer = value; }
}
/// The serial number.
/// If null is given any will do.
public BigInteger SerialNumber
{
get { return serialNumber; }
set { this.serialNumber = value; }
}
/**
* Adds a target name criterion for the attribute certificate to the target
* information extension criteria. The X509AttributeCertificate
* must contain at least one of the specified target names.
*
* Each attribute certificate may contain a target information extension
* limiting the servers where this attribute certificate can be used. If
* this extension is not present, the attribute certificate is not targeted
* and may be accepted by any server.
*
*
* @param name The name as a GeneralName (not null)
*/
public void AddTargetName(GeneralName name)
{
targetNames.Add(name);
}
/**
* Adds a target name criterion for the attribute certificate to the target
* information extension criteria. The X509AttributeCertificate
* must contain at least one of the specified target names.
*
* Each attribute certificate may contain a target information extension
* limiting the servers where this attribute certificate can be used. If
* this extension is not present, the attribute certificate is not targeted
* and may be accepted by any server.
*
*
* @param name a byte array containing the name in ASN.1 DER encoded form of a GeneralName
* @throws IOException if a parsing error occurs.
*/
public void AddTargetName(byte[] name)
{
AddTargetName(GeneralName.GetInstance(Asn1Object.FromByteArray(name)));
}
/**
* Adds a collection with target names criteria. If null is
* given any will do.
*
* The collection consists of either GeneralName objects or byte[] arrays representing
* DER encoded GeneralName structures.
*
*
* @param names A collection of target names.
* @throws IOException if a parsing error occurs.
* @see #AddTargetName(byte[])
* @see #AddTargetName(GeneralName)
*/
public void SetTargetNames(IEnumerable