X509Extensions
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using System;
using System.Collections.Generic;
namespace Org.BouncyCastle.Asn1.X509
{
public class X509Extensions : Asn1Encodable
{
public static readonly DerObjectIdentifier SubjectDirectoryAttributes = new DerObjectIdentifier("2.5.29.9");
public static readonly DerObjectIdentifier SubjectKeyIdentifier = new DerObjectIdentifier("2.5.29.14");
public static readonly DerObjectIdentifier KeyUsage = new DerObjectIdentifier("2.5.29.15");
public static readonly DerObjectIdentifier PrivateKeyUsagePeriod = new DerObjectIdentifier("2.5.29.16");
public static readonly DerObjectIdentifier SubjectAlternativeName = new DerObjectIdentifier("2.5.29.17");
public static readonly DerObjectIdentifier IssuerAlternativeName = new DerObjectIdentifier("2.5.29.18");
public static readonly DerObjectIdentifier BasicConstraints = new DerObjectIdentifier("2.5.29.19");
public static readonly DerObjectIdentifier CrlNumber = new DerObjectIdentifier("2.5.29.20");
public static readonly DerObjectIdentifier ReasonCode = new DerObjectIdentifier("2.5.29.21");
public static readonly DerObjectIdentifier InstructionCode = new DerObjectIdentifier("2.5.29.23");
public static readonly DerObjectIdentifier InvalidityDate = new DerObjectIdentifier("2.5.29.24");
public static readonly DerObjectIdentifier DeltaCrlIndicator = new DerObjectIdentifier("2.5.29.27");
public static readonly DerObjectIdentifier IssuingDistributionPoint = new DerObjectIdentifier("2.5.29.28");
public static readonly DerObjectIdentifier CertificateIssuer = new DerObjectIdentifier("2.5.29.29");
public static readonly DerObjectIdentifier NameConstraints = new DerObjectIdentifier("2.5.29.30");
public static readonly DerObjectIdentifier CrlDistributionPoints = new DerObjectIdentifier("2.5.29.31");
public static readonly DerObjectIdentifier CertificatePolicies = new DerObjectIdentifier("2.5.29.32");
public static readonly DerObjectIdentifier PolicyMappings = new DerObjectIdentifier("2.5.29.33");
public static readonly DerObjectIdentifier AuthorityKeyIdentifier = new DerObjectIdentifier("2.5.29.35");
public static readonly DerObjectIdentifier PolicyConstraints = new DerObjectIdentifier("2.5.29.36");
public static readonly DerObjectIdentifier ExtendedKeyUsage = new DerObjectIdentifier("2.5.29.37");
public static readonly DerObjectIdentifier FreshestCrl = new DerObjectIdentifier("2.5.29.46");
public static readonly DerObjectIdentifier InhibitAnyPolicy = new DerObjectIdentifier("2.5.29.54");
public static readonly DerObjectIdentifier AuthorityInfoAccess = X509ObjectIdentifiers.IdPE.Branch("1");
public static readonly DerObjectIdentifier BiometricInfo = X509ObjectIdentifiers.IdPE.Branch("2");
public static readonly DerObjectIdentifier QCStatements = X509ObjectIdentifiers.IdPE.Branch("3");
public static readonly DerObjectIdentifier AuditIdentity = X509ObjectIdentifiers.IdPE.Branch("4");
public static readonly DerObjectIdentifier SubjectInfoAccess = X509ObjectIdentifiers.IdPE.Branch("11");
public static readonly DerObjectIdentifier LogoType = X509ObjectIdentifiers.IdPE.Branch("12");
public static readonly DerObjectIdentifier NoRevAvail = new DerObjectIdentifier("2.5.29.56");
public static readonly DerObjectIdentifier TargetInformation = new DerObjectIdentifier("2.5.29.55");
public static readonly DerObjectIdentifier ExpiredCertsOnCrl = new DerObjectIdentifier("2.5.29.60");
public static readonly DerObjectIdentifier SubjectAltPublicKeyInfo = new DerObjectIdentifier("2.5.29.72");
public static readonly DerObjectIdentifier AltSignatureAlgorithm = new DerObjectIdentifier("2.5.29.73");
public static readonly DerObjectIdentifier AltSignatureValue = new DerObjectIdentifier("2.5.29.74");
public static readonly DerObjectIdentifier DRAFT_DeltaCertificateDescriptor = new DerObjectIdentifier("2.16.840.1.114027.80.6.1");
private readonly Dictionary<DerObjectIdentifier, X509Extension> m_extensions = new Dictionary<DerObjectIdentifier, X509Extension>();
private readonly List<DerObjectIdentifier> m_ordering;
public int Count => m_ordering.Count;
public IEnumerable<DerObjectIdentifier> ExtensionOids => CollectionUtilities.Proxy(m_ordering);
public static X509Extension GetExtension(X509Extensions extensions, DerObjectIdentifier oid)
{
return extensions?.GetExtension(oid);
}
public static Asn1Object GetExtensionParsedValue(X509Extensions extensions, DerObjectIdentifier oid)
{
return extensions?.GetExtensionParsedValue(oid);
}
public static Asn1OctetString GetExtensionValue(X509Extensions extensions, DerObjectIdentifier oid)
{
return extensions?.GetExtensionValue(oid);
}
public static X509Extensions GetInstance(object obj)
{
if (obj == null)
return null;
X509Extensions x509Extensions = obj as X509Extensions;
if (x509Extensions != null)
return x509Extensions;
Asn1Sequence asn1Sequence = obj as Asn1Sequence;
if (asn1Sequence != null)
return new X509Extensions(asn1Sequence);
Asn1TaggedObject asn1TaggedObject = obj as Asn1TaggedObject;
if (asn1TaggedObject != null)
return GetInstance(Asn1Utilities.CheckContextTagClass(asn1TaggedObject).GetBaseObject().ToAsn1Object());
throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj");
}
public static X509Extensions GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
return new X509Extensions(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
}
public static X509Extensions GetOptional(Asn1Encodable element)
{
if (element == null)
throw new ArgumentNullException("element");
X509Extensions x509Extensions = element as X509Extensions;
if (x509Extensions != null)
return x509Extensions;
Asn1Sequence optional = Asn1Sequence.GetOptional(element);
if (optional != null)
return new X509Extensions(optional);
return null;
}
public static X509Extensions GetTagged(Asn1TaggedObject taggedObject, bool declaredExplicit)
{
return new X509Extensions(Asn1Sequence.GetTagged(taggedObject, declaredExplicit));
}
private X509Extensions(Asn1Sequence seq)
{
m_ordering = new List<DerObjectIdentifier>();
foreach (Asn1Encodable item in seq) {
Asn1Sequence instance = Asn1Sequence.GetInstance(item);
if (instance.Count < 2 || instance.Count > 3)
throw new ArgumentException("Bad sequence size: " + instance.Count.ToString());
DerObjectIdentifier instance2 = DerObjectIdentifier.GetInstance(instance[0]);
bool critical = instance.Count == 3 && DerBoolean.GetInstance(instance[1]).IsTrue;
Asn1OctetString instance3 = Asn1OctetString.GetInstance(instance[instance.Count - 1]);
if (m_extensions.ContainsKey(instance2))
throw new ArgumentException("repeated extension found: " + instance2?.ToString());
m_extensions.Add(instance2, new X509Extension(critical, instance3));
m_ordering.Add(instance2);
}
}
public X509Extensions(IDictionary<DerObjectIdentifier, X509Extension> extensions)
: this(null, extensions)
{
}
public X509Extensions(IList<DerObjectIdentifier> ordering, IDictionary<DerObjectIdentifier, X509Extension> extensions)
{
if (ordering == null)
m_ordering = new List<DerObjectIdentifier>(extensions.Keys);
else
m_ordering = new List<DerObjectIdentifier>(ordering);
foreach (DerObjectIdentifier item in m_ordering) {
m_extensions.Add(item, extensions[item]);
}
}
public X509Extensions(IList<DerObjectIdentifier> oids, IList<X509Extension> values)
{
m_ordering = new List<DerObjectIdentifier>(oids);
int num = 0;
foreach (DerObjectIdentifier item in m_ordering) {
m_extensions.Add(item, values[num++]);
}
}
public X509Extension GetExtension(DerObjectIdentifier oid)
{
return CollectionUtilities.GetValueOrNull(m_extensions, oid);
}
public Asn1Object GetExtensionParsedValue(DerObjectIdentifier oid)
{
return GetExtension(oid)?.GetParsedValue();
}
public Asn1OctetString GetExtensionValue(DerObjectIdentifier oid)
{
return GetExtension(oid)?.Value;
}
public override Asn1Object ToAsn1Object()
{
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(m_ordering.Count);
foreach (DerObjectIdentifier item in m_ordering) {
X509Extension x509Extension = m_extensions[item];
if (x509Extension.IsCritical)
asn1EncodableVector.Add(new DerSequence(item, DerBoolean.True, x509Extension.Value));
else
asn1EncodableVector.Add(new DerSequence(item, x509Extension.Value));
}
return new DerSequence(asn1EncodableVector);
}
internal Asn1Sequence ToAsn1ObjectTrimmed()
{
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(m_ordering.Count - (m_extensions.ContainsKey(AltSignatureValue) ? 1 : 0));
foreach (DerObjectIdentifier item in m_ordering) {
if (!AltSignatureValue.Equals(item)) {
X509Extension x509Extension = m_extensions[item];
if (x509Extension.IsCritical)
asn1EncodableVector.Add(new DerSequence(item, DerBoolean.True, x509Extension.Value));
else
asn1EncodableVector.Add(new DerSequence(item, x509Extension.Value));
}
}
return new DerSequence(asn1EncodableVector);
}
public bool Equivalent(X509Extensions other)
{
if (m_extensions.Count != other.m_extensions.Count)
return false;
foreach (KeyValuePair<DerObjectIdentifier, X509Extension> extension in m_extensions) {
if (!extension.Value.Equals(other.GetExtension(extension.Key)))
return false;
}
return true;
}
public DerObjectIdentifier[] GetExtensionOids()
{
return m_ordering.ToArray();
}
public DerObjectIdentifier[] GetNonCriticalExtensionOids()
{
return GetExtensionOids(false);
}
public DerObjectIdentifier[] GetCriticalExtensionOids()
{
return GetExtensionOids(true);
}
public bool HasAnyCriticalExtensions()
{
foreach (DerObjectIdentifier item in m_ordering) {
if (m_extensions[item].IsCritical)
return true;
}
return false;
}
private DerObjectIdentifier[] GetExtensionOids(bool isCritical)
{
List<DerObjectIdentifier> list = new List<DerObjectIdentifier>();
foreach (DerObjectIdentifier item in m_ordering) {
if (m_extensions[item].IsCritical == isCritical)
list.Add(item);
}
return list.ToArray();
}
}
}