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.Utilities; namespace Org.BouncyCastle.X509 { /// /// Class to Generate X509V1 Certificates. /// public class X509V1CertificateGenerator { private V1TbsCertificateGenerator tbsGen; /// /// Default Constructor. /// public X509V1CertificateGenerator() { tbsGen = new V1TbsCertificateGenerator(); } /// /// Reset the generator. /// public void Reset() { tbsGen = new V1TbsCertificateGenerator(); } /// /// Set the certificate's serial number. /// /// Make serial numbers long, if you have no serial number policy make sure the number is at least 16 bytes of secure random data. /// You will be surprised how ugly a serial number collision can get. /// The serial number. public void SetSerialNumber( BigInteger serialNumber) { if (serialNumber.SignValue <= 0) { throw new ArgumentException("serial number must be a positive integer", "serialNumber"); } tbsGen.SetSerialNumber(new DerInteger(serialNumber)); } /// /// Set the issuer distinguished name. /// The issuer is the entity whose private key is used to sign the certificate. /// /// The issuers DN. public void SetIssuerDN( X509Name issuer) { tbsGen.SetIssuer(issuer); } /// /// Set the date that this certificate is to be valid from. /// /// public void SetNotBefore( DateTime date) { tbsGen.SetStartDate(new Time(date)); } /// /// Set the date after which this certificate will no longer be valid. /// /// public void SetNotAfter( DateTime date) { tbsGen.SetEndDate(new Time(date)); } /// /// Set the subject distinguished name. /// The subject describes the entity associated with the public key. /// /// public void SetSubjectDN( X509Name subject) { tbsGen.SetSubject(subject); } /// /// Set the public key that this certificate identifies. /// /// public void SetPublicKey( AsymmetricKeyParameter publicKey) { try { tbsGen.SetSubjectPublicKeyInfo( SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey)); } catch (Exception e) { throw new ArgumentException("unable to process key - " + e.ToString()); } } /// /// Generate a new X509Certificate using the passed in SignatureCalculator. /// /// A signature calculator factory with the necessary algorithm details. /// An X509Certificate. public X509Certificate Generate(ISignatureFactory signatureFactory) { tbsGen.SetSignature((AlgorithmIdentifier)signatureFactory.AlgorithmDetails); TbsCertificateStructure tbsCert = tbsGen.GenerateTbsCertificate(); IStreamCalculator streamCalculator = signatureFactory.CreateCalculator(); byte[] encoded = tbsCert.GetDerEncoded(); streamCalculator.Stream.Write(encoded, 0, encoded.Length); Platform.Dispose(streamCalculator.Stream); return GenerateJcaObject(tbsCert, (AlgorithmIdentifier)signatureFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect()); } private X509Certificate GenerateJcaObject( TbsCertificateStructure tbsCert, AlgorithmIdentifier sigAlg, byte[] signature) { return new X509Certificate( new X509CertificateStructure(tbsCert, sigAlg, new DerBitString(signature))); } /// /// Allows enumeration of the signature names supported by the generator. /// public IEnumerable SignatureAlgNames { get { return X509Utilities.GetAlgNames(); } } } }