From 6c7a86e0b73074b2a42ea129acc831ace01d41a5 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 4 Jun 2019 13:53:00 +0700 Subject: Port LinkedCertificate from bc-java --- crypto/src/asn1/Asn1EncodableVector.cs | 8 +++ crypto/src/asn1/bc/BCObjectIdentifiers.cs | 11 +++- crypto/src/asn1/bc/LinkedCertificate.cs | 100 ++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 crypto/src/asn1/bc/LinkedCertificate.cs (limited to 'crypto/src/asn1') diff --git a/crypto/src/asn1/Asn1EncodableVector.cs b/crypto/src/asn1/Asn1EncodableVector.cs index 49532fe57..8a97e8b4f 100644 --- a/crypto/src/asn1/Asn1EncodableVector.cs +++ b/crypto/src/asn1/Asn1EncodableVector.cs @@ -61,6 +61,14 @@ namespace Org.BouncyCastle.Asn1 } } + public void AddOptionalTagged(bool isExplicit, int tagNo, Asn1Encodable obj) + { + if (null != obj) + { + v.Add(new DerTaggedObject(isExplicit, tagNo, obj)); + } + } + public Asn1Encodable this[ int index] { diff --git a/crypto/src/asn1/bc/BCObjectIdentifiers.cs b/crypto/src/asn1/bc/BCObjectIdentifiers.cs index 1e2448853..0ffd65dfc 100644 --- a/crypto/src/asn1/bc/BCObjectIdentifiers.cs +++ b/crypto/src/asn1/bc/BCObjectIdentifiers.cs @@ -101,5 +101,14 @@ namespace Org.BouncyCastle.Asn1.BC * NewHope */ public static readonly DerObjectIdentifier newHope = bc_exch.Branch("1"); + + /** + * X.509 extension(4) values + *

+ * 1.3.6.1.4.1.22554.4 + */ + public static readonly DerObjectIdentifier bc_ext = bc.Branch("4"); + + public static readonly DerObjectIdentifier linkedCertificate = bc_ext.Branch("1"); } -} \ No newline at end of file +} diff --git a/crypto/src/asn1/bc/LinkedCertificate.cs b/crypto/src/asn1/bc/LinkedCertificate.cs new file mode 100644 index 000000000..c8d05d8f5 --- /dev/null +++ b/crypto/src/asn1/bc/LinkedCertificate.cs @@ -0,0 +1,100 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.BC +{ + /** + * Extension to tie an alternate certificate to the containing certificate. + *

+     *     LinkedCertificate := SEQUENCE {
+     *         digest        DigestInfo,                   -- digest of PQC certificate
+     *         certLocation  GeneralName,                  -- location of PQC certificate
+     *         certIssuer    [0] Name OPTIONAL,            -- issuer of PQC cert (if different from current certificate)
+     *         cACerts       [1] GeneralNames OPTIONAL,    -- CA certificates for PQC cert (one of more locations)
+     * }
+     * 
+ */ + public class LinkedCertificate + : Asn1Encodable + { + private readonly DigestInfo mDigest; + private readonly GeneralName mCertLocation; + + private X509Name mCertIssuer; + private GeneralNames mCACerts; + + public LinkedCertificate(DigestInfo digest, GeneralName certLocation) + : this(digest, certLocation, null, null) + { + } + + public LinkedCertificate(DigestInfo digest, GeneralName certLocation, X509Name certIssuer, GeneralNames caCerts) + { + this.mDigest = digest; + this.mCertLocation = certLocation; + this.mCertIssuer = certIssuer; + this.mCACerts = caCerts; + } + + private LinkedCertificate(Asn1Sequence seq) + { + this.mDigest = DigestInfo.GetInstance(seq[0]); + this.mCertLocation = GeneralName.GetInstance(seq[1]); + + for (int i = 2; i < seq.Count; ++i) + { + Asn1TaggedObject tagged = Asn1TaggedObject.GetInstance(seq[i]); + + switch (tagged.TagNo) + { + case 0: + this.mCertIssuer = X509Name.GetInstance(tagged, false); + break; + case 1: + this.mCACerts = GeneralNames.GetInstance(tagged, false); + break; + default: + throw new ArgumentException("unknown tag in tagged field"); + } + } + } + + public static LinkedCertificate GetInstance(object obj) + { + if (obj is LinkedCertificate) + return (LinkedCertificate)obj; + if (obj != null) + return new LinkedCertificate(Asn1Sequence.GetInstance(obj)); + return null; + } + + public virtual DigestInfo Digest + { + get { return mDigest; } + } + + public virtual GeneralName CertLocation + { + get { return mCertLocation; } + } + + public virtual X509Name CertIssuer + { + get { return mCertIssuer; } + } + + public virtual GeneralNames CACerts + { + get { return mCACerts; } + } + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(mDigest, mCertLocation); + v.AddOptionalTagged(false, 0, mCertIssuer); + v.AddOptionalTagged(false, 1, mCACerts); + return new DerSequence(v); + } + } +} -- cgit 1.4.1