<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

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[] m_authorityKeyIdentifier; 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; } } }