X509CertStoreSelector
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.X509.Extension;
using System;
using System.Collections.Generic;
namespace Org.BouncyCastle.X509.Store
{
public class X509CertStoreSelector : ISelector<X509Certificate>, ICloneable
{
private byte[] ;
private int m_basicConstraints = -1;
private X509Certificate m_certificate;
private DateTime? m_certificateValid;
private ISet<DerObjectIdentifier> m_extendedKeyUsage;
private bool m_ignoreX509NameOrdering;
private X509Name m_issuer;
private bool[] m_keyUsage;
private bool m_matchAllSubjectAltNames = true;
private ISet<DerObjectIdentifier> m_policy;
private DateTime? m_privateKeyValid;
private BigInteger m_serialNumber;
private X509Name m_subject;
private ISet<GeneralName> m_subjectAlternativeNames;
private byte[] m_subjectKeyIdentifier;
private SubjectPublicKeyInfo m_subjectPublicKey;
private DerObjectIdentifier m_subjectPublicKeyAlgID;
public byte[] AuthorityKeyIdentifier {
get {
return Arrays.Clone(m_authorityKeyIdentifier);
}
set {
m_authorityKeyIdentifier = Arrays.Clone(value);
}
}
public int BasicConstraints {
get {
return m_basicConstraints;
}
set {
m_basicConstraints = CheckBasicConstraints(value);
}
}
public X509Certificate Certificate {
get {
return m_certificate;
}
set {
m_certificate = value;
}
}
public DateTime? CertificateValid {
get {
return m_certificateValid;
}
set {
m_certificateValid = value;
}
}
public ISet<DerObjectIdentifier> ExtendedKeyUsage {
get {
return CopySet(m_extendedKeyUsage);
}
set {
m_extendedKeyUsage = CopySet(value);
}
}
public bool IgnoreX509NameOrdering {
get {
return m_ignoreX509NameOrdering;
}
set {
m_ignoreX509NameOrdering = value;
}
}
public X509Name Issuer {
get {
return m_issuer;
}
set {
m_issuer = value;
}
}
public bool[] KeyUsage {
get {
return Arrays.Clone(m_keyUsage);
}
set {
m_keyUsage = Arrays.Clone(value);
}
}
public bool MatchAllSubjectAltNames {
get {
return m_matchAllSubjectAltNames;
}
set {
m_matchAllSubjectAltNames = value;
}
}
public ISet<DerObjectIdentifier> Policy {
get {
return CopySet(m_policy);
}
set {
m_policy = CopySet(value);
}
}
public DateTime? PrivateKeyValid {
get {
return m_privateKeyValid;
}
set {
m_privateKeyValid = value;
}
}
public BigInteger SerialNumber {
get {
return m_serialNumber;
}
set {
m_serialNumber = value;
}
}
public X509Name Subject {
get {
return m_subject;
}
set {
m_subject = value;
}
}
public ISet<GeneralName> SubjectAlternativeNames {
get {
return CopySet(m_subjectAlternativeNames);
}
set {
m_subjectAlternativeNames = CopySet(value);
}
}
public byte[] SubjectKeyIdentifier {
get {
return Arrays.Clone(m_subjectKeyIdentifier);
}
set {
m_subjectKeyIdentifier = Arrays.Clone(value);
}
}
public SubjectPublicKeyInfo SubjectPublicKey {
get {
return m_subjectPublicKey;
}
set {
m_subjectPublicKey = value;
}
}
public DerObjectIdentifier SubjectPublicKeyAlgID {
get {
return m_subjectPublicKeyAlgID;
}
set {
m_subjectPublicKeyAlgID = value;
}
}
public X509CertStoreSelector()
{
}
public X509CertStoreSelector(X509CertStoreSelector o)
{
m_authorityKeyIdentifier = o.m_authorityKeyIdentifier;
m_basicConstraints = o.m_basicConstraints;
m_certificate = o.m_certificate;
m_certificateValid = o.m_certificateValid;
m_extendedKeyUsage = o.m_extendedKeyUsage;
m_ignoreX509NameOrdering = o.m_ignoreX509NameOrdering;
m_issuer = o.m_issuer;
m_keyUsage = o.m_keyUsage;
m_matchAllSubjectAltNames = o.m_matchAllSubjectAltNames;
m_policy = o.m_policy;
m_privateKeyValid = o.m_privateKeyValid;
m_serialNumber = o.m_serialNumber;
m_subject = o.m_subject;
m_subjectAlternativeNames = o.m_subjectAlternativeNames;
m_subjectKeyIdentifier = o.m_subjectKeyIdentifier;
m_subjectPublicKey = o.m_subjectPublicKey;
m_subjectPublicKeyAlgID = o.m_subjectPublicKeyAlgID;
}
public virtual object Clone()
{
return new X509CertStoreSelector(this);
}
public virtual bool Match(X509Certificate c)
{
if (c == null)
return false;
if (m_certificate != null && !m_certificate.Equals(c))
return false;
if (m_serialNumber != null && !m_serialNumber.Equals(c.SerialNumber))
return false;
if (m_issuer != null && !m_issuer.Equivalent(c.IssuerDN, !m_ignoreX509NameOrdering))
return false;
if (m_subject != null && !m_subject.Equivalent(c.SubjectDN, !m_ignoreX509NameOrdering))
return false;
if (m_certificateValid.HasValue && !c.IsValid(m_certificateValid.Value))
return false;
if (m_subjectPublicKey != null && !m_subjectPublicKey.Equals(c.SubjectPublicKeyInfo))
return false;
if (m_basicConstraints != -1 && !MatchBasicConstraints(c))
return false;
if (m_keyUsage != null && !MatchKeyUsage(c))
return false;
if (!CollectionUtilities.IsNullOrEmpty(m_extendedKeyUsage) && !MatchExtendedKeyUsage(c))
return false;
if (!MatchExtension(m_subjectKeyIdentifier, c, X509Extensions.SubjectKeyIdentifier))
return false;
if (!MatchExtension(m_authorityKeyIdentifier, c, X509Extensions.AuthorityKeyIdentifier))
return false;
if (m_privateKeyValid.HasValue && !MatchPrivateKeyValid(c))
return false;
if (m_subjectPublicKeyAlgID != null && !m_subjectPublicKeyAlgID.Equals(c.SubjectPublicKeyInfo.Algorithm))
return false;
if (m_policy != null && !MatchPolicy(c))
return false;
if (!CollectionUtilities.IsNullOrEmpty(m_subjectAlternativeNames) && !MatchSubjectAlternativeNames(c))
return false;
return true;
}
protected internal int GetHashCodeOfSubjectKeyIdentifier()
{
return Arrays.GetHashCode(m_subjectKeyIdentifier);
}
protected internal bool MatchesIssuer(X509CertStoreSelector other)
{
return IssuersMatch(m_issuer, other.m_issuer);
}
protected internal bool MatchesSerialNumber(X509CertStoreSelector other)
{
return object.Equals(m_serialNumber, other.m_serialNumber);
}
protected internal bool MatchesSubjectKeyIdentifier(X509CertStoreSelector other)
{
return Arrays.AreEqual(m_subjectKeyIdentifier, other.m_subjectKeyIdentifier);
}
private bool MatchBasicConstraints(X509Certificate c)
{
int basicConstraints = c.GetBasicConstraints();
if (m_basicConstraints == -2)
return basicConstraints == -1;
return basicConstraints >= m_basicConstraints;
}
private bool MatchExtendedKeyUsage(X509Certificate c)
{
IList<DerObjectIdentifier> extendedKeyUsage = c.GetExtendedKeyUsage();
if (extendedKeyUsage != null && !extendedKeyUsage.Contains(KeyPurposeID.AnyExtendedKeyUsage)) {
foreach (DerObjectIdentifier item in m_extendedKeyUsage) {
if (!extendedKeyUsage.Contains(item))
return false;
}
}
return true;
}
private bool MatchKeyUsage(X509Certificate c)
{
bool[] keyUsage = c.GetKeyUsage();
if (keyUsage != null) {
for (int i = 0; i < m_keyUsage.Length; i++) {
if (m_keyUsage[i] && (i >= keyUsage.Length || !keyUsage[i]))
return false;
}
}
return true;
}
private bool MatchPolicy(X509Certificate c)
{
Asn1Sequence extension = c.GetExtension(X509Extensions.CertificatePolicies, Asn1Sequence.GetInstance);
if (extension == null || extension.Count < 1)
return false;
if (m_policy.Count >= 1)
return PoliciesIntersect(m_policy, extension);
return true;
}
private bool MatchPrivateKeyValid(X509Certificate c)
{
PrivateKeyUsagePeriod extension = c.GetExtension(X509Extensions.PrivateKeyUsagePeriod, PrivateKeyUsagePeriod.GetInstance);
if (extension != null) {
DateTime dateTime = m_privateKeyValid.Value;
DateTime value = dateTime.ToUniversalTime();
Asn1GeneralizedTime notBefore = extension.NotBefore;
if (notBefore != null) {
dateTime = notBefore.ToDateTime();
if (dateTime.ToUniversalTime().CompareTo(value) > 0)
return false;
}
Asn1GeneralizedTime notAfter = extension.NotAfter;
if (notAfter != null) {
dateTime = notAfter.ToDateTime();
if (dateTime.ToUniversalTime().CompareTo(value) < 0)
return false;
}
}
return true;
}
private bool MatchSubjectAlternativeNames(X509Certificate c)
{
GeneralNames subjectAlternativeNameExtension = c.GetSubjectAlternativeNameExtension();
if (subjectAlternativeNameExtension == null)
return false;
GeneralName[] names = subjectAlternativeNameExtension.GetNames();
foreach (GeneralName subjectAlternativeName in m_subjectAlternativeNames) {
bool flag = ContainsGeneralName(names, subjectAlternativeName);
if (flag != m_matchAllSubjectAltNames)
return flag;
}
return m_matchAllSubjectAltNames;
}
private static int CheckBasicConstraints(int basicConstraints)
{
if (basicConstraints < -2)
throw new ArgumentException("can't be less than -2", "basicConstraints");
return basicConstraints;
}
private static bool ContainsGeneralName(GeneralName[] names, GeneralName name)
{
return Array.IndexOf(names, name) >= 0;
}
private static ISet<T> CopySet<T>(ISet<T> s)
{
if (s != null)
return new HashSet<T>((IEnumerable<T>)s);
return null;
}
private static bool IssuersMatch(X509Name a, X509Name b)
{
return a?.Equivalent(b, true) ?? (b == null);
}
private static bool MatchExtension(byte[] b, X509Certificate c, DerObjectIdentifier oid)
{
if (b == null)
return true;
Asn1OctetString extensionValue = c.GetExtensionValue(oid);
if (extensionValue == null)
return false;
return Arrays.AreEqual(b, extensionValue.GetOctets());
}
private static bool PoliciesIntersect(ISet<DerObjectIdentifier> policy, Asn1Sequence certificatePolicies)
{
foreach (Asn1Encodable certificatePolicy in certificatePolicies) {
PolicyInformation instance = PolicyInformation.GetInstance(certificatePolicy);
if (policy.Contains(instance.PolicyIdentifier))
return true;
}
return false;
}
}
}