using System; using System.Collections; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; 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; private DerObjectIdentifier sigOID; private AlgorithmIdentifier sigAlgId; private string signatureAlgorithm; 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)); } /// /// Set the signature algorithm. This can be either a name or an OID, names /// are treated as case insensitive. /// /// The algorithm name. public void SetSignatureAlgorithm( string signatureAlgorithm) { this.signatureAlgorithm = signatureAlgorithm; try { sigOID = X509Utilities.GetAlgorithmOid(signatureAlgorithm); } catch (Exception) { throw new ArgumentException("Unknown signature type requested"); } sigAlgId = X509Utilities.GetSigAlgID(sigOID, signatureAlgorithm); acInfoGen.SetSignature(sigAlgId); } /// 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 Platform.CreateNotImplementedException("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 an X509 certificate, based on the current issuer and subject. /// public IX509AttributeCertificate Generate( AsymmetricKeyParameter publicKey) { return Generate(publicKey, null); } /// /// Generate an X509 certificate, based on the current issuer and subject, /// using the supplied source of randomness, if required. /// public IX509AttributeCertificate Generate( AsymmetricKeyParameter publicKey, SecureRandom random) { if (!extGenerator.IsEmpty) { acInfoGen.SetExtensions(extGenerator.Generate()); } AttributeCertificateInfo acInfo = acInfoGen.GenerateAttributeCertificateInfo(); Asn1EncodableVector v = new Asn1EncodableVector(); v.Add(acInfo, sigAlgId); try { v.Add(new DerBitString(X509Utilities.GetSignatureForObject(sigOID, signatureAlgorithm, publicKey, random, acInfo))); return new X509V2AttributeCertificate(AttributeCertificate.GetInstance(new DerSequence(v))); } catch (Exception e) { // TODO // throw new ExtCertificateEncodingException("constructed invalid certificate", e); throw new CertificateEncodingException("constructed invalid certificate", e); } } /// /// Allows enumeration of the signature names supported by the generator. /// public IEnumerable SignatureAlgNames { get { return X509Utilities.GetAlgNames(); } } } }