<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />

DeltaCertificateTool

public class DeltaCertificateTool
General tool for handling the extension described in: https://datatracker.ietf.org/doc/draft-bonnell-lamps-chameleon-certs/
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using System; namespace Org.BouncyCastle.X509 { public class DeltaCertificateTool { public static Org.BouncyCastle.Asn1.X509.Extension CreateDeltaCertificateExtension(bool isCritical, X509CertificateStructure deltaCert) { DeltaCertificateDescriptor deltaCertificateDescriptor = new DeltaCertificateDescriptor(deltaCert.SerialNumber, deltaCert.SignatureAlgorithm, deltaCert.Issuer, deltaCert.Validity, deltaCert.Subject, deltaCert.SubjectPublicKeyInfo, deltaCert.Extensions, deltaCert.Signature); DerObjectIdentifier dRAFT_DeltaCertificateDescriptor = X509Extensions.DRAFT_DeltaCertificateDescriptor; DerBoolean instance = DerBoolean.GetInstance(isCritical); DerOctetString extnValue = DerOctetString.WithContents(deltaCertificateDescriptor.GetEncoded("DER")); return new Org.BouncyCastle.Asn1.X509.Extension(dRAFT_DeltaCertificateDescriptor, instance, extnValue); } public static Org.BouncyCastle.Asn1.X509.Extension CreateDeltaCertificateExtension(bool isCritical, X509Certificate deltaCert) { return CreateDeltaCertificateExtension(isCritical, deltaCert.CertificateStructure); } public static X509CertificateStructure ExtractDeltaCertificate(TbsCertificateStructure baseTbsCert) { X509Extensions extensions = baseTbsCert.Extensions; X509Extension extension = extensions.GetExtension(X509Extensions.DRAFT_DeltaCertificateDescriptor); if (extension == null) throw new InvalidOperationException("no deltaCertificateDescriptor present"); DeltaCertificateDescriptor instance = DeltaCertificateDescriptor.GetInstance(extension.GetParsedValue()); DerInteger versionNumber = baseTbsCert.VersionNumber; DerInteger serialNumber = instance.SerialNumber; AlgorithmIdentifier algorithmIdentifier = instance.Signature ?? baseTbsCert.Signature; X509Name issuer = instance.Issuer ?? baseTbsCert.Issuer; Validity validity = instance.Validity ?? baseTbsCert.Validity; X509Name subject = instance.Subject ?? baseTbsCert.Subject; SubjectPublicKeyInfo subjectPublicKeyInfo = instance.SubjectPublicKeyInfo; X509Extensions extensions2 = ExtractDeltaExtensions(instance.Extensions, extensions); return new X509CertificateStructure(new TbsCertificateStructure(versionNumber, serialNumber, algorithmIdentifier, issuer, validity, subject, subjectPublicKeyInfo, null, null, extensions2), algorithmIdentifier, instance.SignatureValue); } public static X509Certificate ExtractDeltaCertificate(X509Certificate baseCert) { return new X509Certificate(ExtractDeltaCertificate(baseCert.TbsCertificate)); } public static DeltaCertificateDescriptor TrimDeltaCertificateDescriptor(DeltaCertificateDescriptor descriptor, TbsCertificateStructure tbsCertificate, X509Extensions tbsExtensions) { DerInteger serialNumber = descriptor.SerialNumber; AlgorithmIdentifier algorithmIdentifier = descriptor.Signature; if (algorithmIdentifier != null && algorithmIdentifier.Equals(tbsCertificate.Signature)) algorithmIdentifier = null; X509Name x509Name = descriptor.Issuer; if (x509Name != null && x509Name.Equals(tbsCertificate.Issuer)) x509Name = null; Validity validity = descriptor.Validity; if (validity != null && validity.Equals(tbsCertificate.Validity)) validity = null; X509Name x509Name2 = descriptor.Subject; if (x509Name2 != null && x509Name2.Equals(tbsCertificate.Subject)) x509Name2 = null; SubjectPublicKeyInfo subjectPublicKeyInfo = descriptor.SubjectPublicKeyInfo; X509Extensions x509Extensions = descriptor.Extensions; if (x509Extensions != null) { X509ExtensionsGenerator x509ExtensionsGenerator = new X509ExtensionsGenerator(); foreach (DerObjectIdentifier extensionOid in tbsExtensions.ExtensionOids) { if (!X509Extensions.DRAFT_DeltaCertificateDescriptor.Equals(extensionOid)) { X509Extension extension = x509Extensions.GetExtension(extensionOid); if (extension != null && !extension.Equals(tbsExtensions.GetExtension(extensionOid))) x509ExtensionsGenerator.AddExtension(extensionOid, extension); } } x509Extensions = (x509ExtensionsGenerator.IsEmpty ? null : x509ExtensionsGenerator.Generate()); } DerBitString signatureValue = descriptor.SignatureValue; return new DeltaCertificateDescriptor(serialNumber, algorithmIdentifier, x509Name, validity, x509Name2, subjectPublicKeyInfo, x509Extensions, signatureValue); } private static X509Extensions ExtractDeltaExtensions(X509Extensions descriptorExtensions, X509Extensions baseExtensions) { X509ExtensionsGenerator x509ExtensionsGenerator = new X509ExtensionsGenerator(); foreach (DerObjectIdentifier extensionOid in baseExtensions.ExtensionOids) { if (!X509Extensions.DRAFT_DeltaCertificateDescriptor.Equals(extensionOid)) x509ExtensionsGenerator.AddExtension(extensionOid, baseExtensions.GetExtension(extensionOid)); } if (descriptorExtensions != null) { foreach (DerObjectIdentifier extensionOid2 in descriptorExtensions.ExtensionOids) { x509ExtensionsGenerator.ReplaceExtension(extensionOid2, descriptorExtensions.GetExtension(extensionOid2)); } } if (!x509ExtensionsGenerator.IsEmpty) return x509ExtensionsGenerator.Generate(); return null; } } }