X509ExtensionsGenerator
using Org.BouncyCastle.Utilities.Collections;
using System;
using System.Collections.Generic;
namespace Org.BouncyCastle.Asn1.X509
{
public class X509ExtensionsGenerator
{
private Dictionary<DerObjectIdentifier, X509Extension> m_extensions = new Dictionary<DerObjectIdentifier, X509Extension>();
private List<DerObjectIdentifier> m_ordering = new List<DerObjectIdentifier>();
private static readonly HashSet<DerObjectIdentifier> m_dupsAllowed = new HashSet<DerObjectIdentifier> {
X509Extensions.SubjectAlternativeName,
X509Extensions.IssuerAlternativeName,
X509Extensions.SubjectDirectoryAttributes,
X509Extensions.CertificateIssuer
};
public bool IsEmpty => m_ordering.Count < 1;
public void AddExtension(DerObjectIdentifier oid, bool critical, IAsn1Convertible extValue)
{
AddExtension(oid, critical, extValue.ToAsn1Object());
}
public void AddExtension(DerObjectIdentifier oid, bool critical, Asn1Encodable extValue)
{
if (m_extensions.TryGetValue(oid, out X509Extension value))
ImplAddExtensionDup(value, oid, critical, extValue.GetEncoded("DER"));
else
ImplAddExtension(oid, new X509Extension(critical, new DerOctetString(extValue)));
}
public void AddExtension(DerObjectIdentifier oid, bool critical, byte[] extValue)
{
if (m_extensions.TryGetValue(oid, out X509Extension value))
ImplAddExtensionDup(value, oid, critical, extValue);
else
ImplAddExtension(oid, new X509Extension(critical, DerOctetString.FromContents(extValue)));
}
public void AddExtension(DerObjectIdentifier oid, X509Extension x509Extension)
{
if (HasExtension(oid))
throw new ArgumentException("extension " + oid?.ToString() + " already added");
ImplAddExtension(oid, x509Extension);
}
public void AddExtension(Extension extension)
{
AddExtension(extension.ExtnID, extension.GetX509Extension());
}
public void AddExtensions(X509Extensions extensions)
{
DerObjectIdentifier[] extensionOids = extensions.GetExtensionOids();
foreach (DerObjectIdentifier oid in extensionOids) {
X509Extension extension = extensions.GetExtension(oid);
AddExtension(oid, extension.critical, extension.Value.GetOctets());
}
}
public X509Extensions Generate()
{
return new X509Extensions(m_ordering, m_extensions);
}
public X509Extension GetExtension(DerObjectIdentifier oid)
{
return CollectionUtilities.GetValueOrNull(m_extensions, oid);
}
public bool HasExtension(DerObjectIdentifier oid)
{
return m_extensions.ContainsKey(oid);
}
public void RemoveExtension(DerObjectIdentifier oid)
{
if (!HasExtension(oid))
throw new InvalidOperationException("extension " + oid?.ToString() + " not present");
m_ordering.Remove(oid);
m_extensions.Remove(oid);
}
public void ReplaceExtension(DerObjectIdentifier oid, bool critical, IAsn1Convertible extValue)
{
ReplaceExtension(oid, critical, extValue.ToAsn1Object());
}
public void ReplaceExtension(DerObjectIdentifier oid, bool critical, Asn1Encodable extValue)
{
ReplaceExtension(oid, new X509Extension(critical, new DerOctetString(extValue)));
}
public void ReplaceExtension(DerObjectIdentifier oid, bool critical, byte[] extValue)
{
ReplaceExtension(oid, new X509Extension(critical, DerOctetString.FromContents(extValue)));
}
public void ReplaceExtension(DerObjectIdentifier oid, X509Extension x509Extension)
{
if (!HasExtension(oid))
throw new InvalidOperationException("extension " + oid?.ToString() + " not present");
m_extensions[oid] = x509Extension;
}
public void ReplaceExtension(Extension extension)
{
ReplaceExtension(extension.ExtnID, extension.GetX509Extension());
}
public void Reset()
{
m_extensions = new Dictionary<DerObjectIdentifier, X509Extension>();
m_ordering = new List<DerObjectIdentifier>();
}
private void ImplAddExtension(DerObjectIdentifier oid, X509Extension x509Extension)
{
m_ordering.Add(oid);
m_extensions.Add(oid, x509Extension);
}
private void ImplAddExtensionDup(X509Extension existingExtension, DerObjectIdentifier oid, bool critical, byte[] extValue)
{
if (!m_dupsAllowed.Contains(oid))
throw new ArgumentException("extension " + oid?.ToString() + " already added");
Asn1Sequence instance = Asn1Sequence.GetInstance(existingExtension.Value.GetOctets());
Asn1Sequence instance2 = Asn1Sequence.GetInstance(extValue);
DerSequence obj = DerSequence.Concatenate(instance, instance2);
m_extensions[oid] = new X509Extension(existingExtension.IsCritical | critical, new DerOctetString(obj));
}
}
}