using System; using System.Collections.Generic; using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.X509 { /// Class to produce an X.509 Version 2 AttributeCertificate. public class X509V2AttributeCertificateGenerator { private readonly X509ExtensionsGenerator extGenerator = new X509ExtensionsGenerator(); private V2AttributeCertificateInfoGenerator acInfoGen; public X509V2AttributeCertificateGenerator() { acInfoGen = new V2AttributeCertificateInfoGenerator(); } /// Reset the generator public void Reset() { acInfoGen = new V2AttributeCertificateInfoGenerator(); extGenerator.Reset(); } /// Set the Holder of this Attribute Certificate. public void SetHolder( AttributeCertificateHolder holder) { acInfoGen.SetHolder(holder.holder); } /// Set the issuer. public void SetIssuer( AttributeCertificateIssuer issuer) { acInfoGen.SetIssuer(AttCertIssuer.GetInstance(issuer.form)); } /// Set the serial number for the certificate. public void SetSerialNumber( BigInteger serialNumber) { acInfoGen.SetSerialNumber(new DerInteger(serialNumber)); } public void SetNotBefore( DateTime date) { acInfoGen.SetStartDate(new DerGeneralizedTime(date)); } public void SetNotAfter( DateTime date) { acInfoGen.SetEndDate(new DerGeneralizedTime(date)); } /// Add an attribute. public void AddAttribute( X509Attribute attribute) { acInfoGen.AddAttribute(AttributeX509.GetInstance(attribute.ToAsn1Object())); } public void SetIssuerUniqueId( bool[] iui) { // TODO convert bool array to bit string //acInfoGen.SetIssuerUniqueID(iui); throw new NotImplementedException("SetIssuerUniqueId()"); } /// Add a given extension field for the standard extensions tag. public void AddExtension( string oid, bool critical, Asn1Encodable extensionValue) { extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue); } /// /// Add a given extension field for the standard extensions tag. /// The value parameter becomes the contents of the octet string associated /// with the extension. /// public void AddExtension( string oid, bool critical, byte[] extensionValue) { extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue); } /// /// Generate a new using the provided . /// /// A signature factory with the necessary /// algorithm details. /// An . public X509V2AttributeCertificate Generate(ISignatureFactory signatureFactory) { var sigAlgID = (AlgorithmIdentifier)signatureFactory.AlgorithmDetails; acInfoGen.SetSignature(sigAlgID); if (!extGenerator.IsEmpty) { acInfoGen.SetExtensions(extGenerator.Generate()); } AttributeCertificateInfo acInfo = acInfoGen.GenerateAttributeCertificateInfo(); IStreamCalculator streamCalculator = signatureFactory.CreateCalculator(); using (Stream sigStream = streamCalculator.Stream) { acInfo.EncodeTo(sigStream, Asn1Encodable.Der); } var signature = streamCalculator.GetResult().Collect(); return new X509V2AttributeCertificate( new AttributeCertificate(acInfo, sigAlgID, new DerBitString(signature))); } /// /// Allows enumeration of the signature names supported by the generator. /// public IEnumerable SignatureAlgNames { get { return X509Utilities.GetAlgNames(); } } } }