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

X509AttrCertParser

public class X509AttrCertParser
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities.IO; using System; using System.Collections.Generic; using System.IO; namespace Org.BouncyCastle.X509 { public class X509AttrCertParser { private static readonly PemParser PemAttrCertParser = new PemParser("ATTRIBUTE CERTIFICATE"); private Asn1Set sData; private int sDataObjectCount; private Stream currentStream; private X509V2AttributeCertificate ReadDerCertificate(Asn1InputStream dIn) { Asn1Sequence asn1Sequence = (Asn1Sequence)dIn.ReadObject(); if (asn1Sequence.Count > 1 && asn1Sequence[0] is DerObjectIdentifier && asn1Sequence[0].Equals(PkcsObjectIdentifiers.SignedData)) { sData = SignedData.GetInstance(Asn1Sequence.GetInstance((Asn1TaggedObject)asn1Sequence[1], true)).Certificates; return GetCertificate(); } return new X509V2AttributeCertificate(AttributeCertificate.GetInstance(asn1Sequence)); } private X509V2AttributeCertificate GetCertificate() { if (sData != null) { while (sDataObjectCount < sData.Count) { Asn1TaggedObject asn1TaggedObject = sData[sDataObjectCount++].ToAsn1Object() as Asn1TaggedObject; if (asn1TaggedObject != null && asn1TaggedObject.TagNo == 2) return new X509V2AttributeCertificate(AttributeCertificate.GetInstance(Asn1Sequence.GetInstance(asn1TaggedObject, false))); } } return null; } private X509V2AttributeCertificate ReadPemCertificate(Stream inStream) { Asn1Sequence asn1Sequence = PemAttrCertParser.ReadPemObject(inStream); if (asn1Sequence != null) return new X509V2AttributeCertificate(AttributeCertificate.GetInstance(asn1Sequence)); return null; } public X509V2AttributeCertificate ReadAttrCert(byte[] input) { return ReadAttrCert(new MemoryStream(input, false)); } public IList<X509V2AttributeCertificate> ReadAttrCerts(byte[] input) { return ReadAttrCerts(new MemoryStream(input, false)); } public X509V2AttributeCertificate ReadAttrCert(Stream inStream) { if (inStream == null) throw new ArgumentNullException("inStream"); if (inStream.CanRead) { if (currentStream == null) { currentStream = inStream; sData = null; sDataObjectCount = 0; } else if (currentStream != inStream) { currentStream = inStream; sData = null; sDataObjectCount = 0; } try { if (sData == null) { int num = inStream.ReadByte(); if (num >= 0) { if (inStream.CanSeek) inStream.Seek(-1, SeekOrigin.Current); else { PushbackStream pushbackStream = new PushbackStream(inStream); pushbackStream.Unread(num); inStream = pushbackStream; } if (num == 48) return ReadDerCertificate(new Asn1InputStream(inStream)); return ReadPemCertificate(inStream); } return null; } if (sDataObjectCount == sData.Count) { sData = null; sDataObjectCount = 0; return null; } return GetCertificate(); } catch (CertificateException) { throw; } catch (Exception ex2) { throw new CertificateException(ex2.ToString()); } } throw new ArgumentException("inStream must be read-able", "inStream"); } public IList<X509V2AttributeCertificate> ReadAttrCerts(Stream inStream) { List<X509V2AttributeCertificate> list = new List<X509V2AttributeCertificate>(); X509V2AttributeCertificate item; while ((item = ReadAttrCert(inStream)) != null) { list.Add(item); } return list; } } }