public HttpResponseMessage Get(string smsNumber, string code)
        {
            RsaKeyPairGenerator r = new RsaKeyPairGenerator();
            r.Init(new Org.BouncyCastle.Crypto.KeyGenerationParameters(new Org.BouncyCastle.Security.SecureRandom(), 2048));

            AsymmetricCipherKeyPair keys = r.GenerateKeyPair();

            string publicKeyPath = Path.Combine(Path.GetTempPath(), "publicKey.key");

            if (File.Exists(publicKeyPath))
            {
                File.Delete(publicKeyPath);
            }

            using (TextWriter textWriter = new StreamWriter(publicKeyPath, false))
            {
                PemWriter pemWriter = new PemWriter(textWriter);
                pemWriter.WriteObject(keys.Public);
                pemWriter.Writer.Flush();
            }

            string certSubjectName = "UShadow_RSA";
            var certName = new X509Name("CN=" + certSubjectName);
            var serialNo = BigInteger.ProbablePrime(120, new Random());

            X509V3CertificateGenerator gen2 = new X509V3CertificateGenerator();
            gen2.SetSerialNumber(serialNo);
            gen2.SetSubjectDN(certName);
            gen2.SetIssuerDN(new X509Name(true, "CN=UShadow"));
            gen2.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(30, 0, 0, 0)));
            gen2.SetNotAfter(DateTime.Now.AddYears(2));
            gen2.SetSignatureAlgorithm("sha512WithRSA");

            gen2.SetPublicKey(keys.Public);

            Org.BouncyCastle.X509.X509Certificate newCert = gen2.Generate(keys.Private);

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            X509CertificateEntry certEntry = new X509CertificateEntry(newCert);
            store.SetCertificateEntry(newCert.SubjectDN.ToString(), certEntry);

            AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(keys.Private);
            store.SetKeyEntry(newCert.SubjectDN.ToString() + "_key", keyEntry, new X509CertificateEntry[] { certEntry });

            using (MemoryStream ms = new MemoryStream())
            {
                store.Save(ms, "Password".ToCharArray(), new SecureRandom());

                var resp = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new ByteArrayContent(ms.ToArray())
                };

                resp.Content.Headers.Add("Content-Type", "application/x-pkcs12");
                return resp;
            }
        }
        public void IssueClientFromCA()
        {
            // get CA
            string caCn = "MyCA CommonName";
            Stream caCertFile = File.OpenRead(string.Format(@"{0}\{1}", _certificatesDir, "MyCAFile.pfx"));
            char[] caPass = "******".ToCharArray();

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();
            store.Load(caCertFile, caPass);

            var caCert = store.GetCertificate(caCn).Certificate;
            var caPrivKey = store.GetKey(caCn).Key;

            var clientCert = GenerateDsaCertificateAsPkcs12(
                "My Client FriendlyName",
                "My Client SubjectName",
                "GT",
                new DateTime(2011, 9, 19),
                new DateTime(2014, 9, 18),
                "PFXPASS",
                caCert,
                caPrivKey);

            var saveAS = string.Format(@"{0}\{1}", _certificatesDir, "clientCertFile.pfx");
            File.WriteAllBytes(saveAS, clientCert);
        }
 public KeyStoreViewModel(SystemX509.StoreName storeName, SystemX509.StoreLocation storeLocation)
 {
     var storeBuilder = new Pkcs12StoreBuilder();
     _store = storeBuilder.Build();
     Name = String.Format("System KeyStore: [{0} : {1}]", storeLocation.ToString(), storeName.ToString());
     Load(storeName, storeLocation);
 }
 /// <summary>
 /// Loads the keystore from the <code>Repository.Instance.CertificatesKeyStore</code>
 /// You shud call <code>Repository.Instance.OpenExistingCertificateAuthority</code>
 /// before calling this.
 /// </summary>
 /// <param name="password">password for the keystore</param>
 public KeyStoreViewModel(char[] password, String path)
 {
     if (!Repository.Instance.OpenExistingCertificateAuthority(path, password))
     {
         throw new Exception("Unable to open KeyStore. Invalid keystore directory");
     }
     Name = Path.GetFileName(path);
     ReadOnlyKeyStore = false;
     _password = password;
     _listItems.Clear();
     var storeBuilder = new Pkcs12StoreBuilder();
     _store = storeBuilder.Build();
     _x509CertViewModel = new X509CertViewModel((alias, cert, keypair) =>
                                                    {
                                                        AddEntry(alias, cert, keypair);
                                                        ShowCertificateGenerator = false;
                                                    });
     Load();
 }
        private static byte[] GeneratePkcs12(AsymmetricCipherKeyPair keys, Org.BouncyCastle.X509.X509Certificate cert, string friendlyName, string password,
            Dictionary<string, Org.BouncyCastle.X509.X509Certificate> chain)
        {
            var chainCerts = new List<X509CertificateEntry>();

            // Create the PKCS12 store
            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            // Add a Certificate entry
            X509CertificateEntry certEntry = new X509CertificateEntry(cert);
            store.SetCertificateEntry(friendlyName, certEntry); // use DN as the Alias.
            //chainCerts.Add(certEntry);

            // Add chain entries
            var additionalCertsAsBytes = new List<byte[]>();
            if (chain != null && chain.Count > 0)
            {
                foreach (var additionalCert in chain)
                {
                    additionalCertsAsBytes.Add(additionalCert.Value.GetEncoded());
                }
            }

            if (chain != null && chain.Count > 0)
            {
                var addicionalCertsAsX09Chain = BuildCertificateChainBC(cert.GetEncoded(), additionalCertsAsBytes);

                foreach (var addCertAsX09 in addicionalCertsAsX09Chain)
                {
                    chainCerts.Add(new X509CertificateEntry(addCertAsX09));
                }
            }

            // Add a key entry
            AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(keys.Private);

            // no chain
            store.SetKeyEntry(friendlyName, keyEntry, new X509CertificateEntry[] { certEntry });

            using (var memoryStream = new MemoryStream())
            {
                store.Save(memoryStream, password.ToCharArray(), new SecureRandom());
                return memoryStream.ToArray();
            }
        }
        /// <summary>
        /// Static method used to create a certificate and return as a .net object
        /// </summary>
        public static X509Certificate2 Create(string name, DateTime start, DateTime end, string userPassword, bool addtoStore = false, string exportDirectory = null)
        {
            // generate a key pair using RSA
            var generator = new RsaKeyPairGenerator();
            // keys have to be a minimum of 2048 bits for Azure
            generator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048));
            AsymmetricCipherKeyPair cerKp = generator.GenerateKeyPair();
            // get a copy of the private key
            AsymmetricKeyParameter privateKey = cerKp.Private;

            // create the CN using the name passed in and create a unique serial number for the cert
            var certName = new X509Name("CN=" + name);
            BigInteger serialNo = BigInteger.ProbablePrime(120, new Random());

            // start the generator and set CN/DN and serial number and valid period
            var x509Generator = new X509V3CertificateGenerator();
            x509Generator.SetSerialNumber(serialNo);
            x509Generator.SetSubjectDN(certName);
            x509Generator.SetIssuerDN(certName);
            x509Generator.SetNotBefore(start);
            x509Generator.SetNotAfter(end);
            // add the server authentication key usage
            var keyUsage = new KeyUsage(KeyUsage.KeyEncipherment);
            x509Generator.AddExtension(X509Extensions.KeyUsage, false, keyUsage.ToAsn1Object());
            var extendedKeyUsage = new ExtendedKeyUsage(new[] {KeyPurposeID.IdKPServerAuth});
            x509Generator.AddExtension(X509Extensions.ExtendedKeyUsage, true, extendedKeyUsage.ToAsn1Object());
            // algorithm can only be SHA1 ??
            x509Generator.SetSignatureAlgorithm("sha1WithRSA");

            // Set the key pair
            x509Generator.SetPublicKey(cerKp.Public);
            X509Certificate certificate = x509Generator.Generate(cerKp.Private);

            // export the certificate bytes
            byte[] certStream = DotNetUtilities.ToX509Certificate(certificate).Export(X509ContentType.Pkcs12, userPassword);

            // build the key parameter and the certificate entry
            var keyEntry = new AsymmetricKeyEntry(privateKey);
            var entry = new X509CertificateEntry(certificate);
            // build the PKCS#12 store to encapsulate the certificate
            var builder = new Pkcs12StoreBuilder();
            builder.SetUseDerEncoding(true);
            builder.SetCertAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
            builder.SetKeyAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
            builder.Build();
            // create a memorystream to hold the output
            var stream = new MemoryStream(10000);
            // create the individual store and set two entries for cert and key
            var store = new Pkcs12Store();
            store.SetCertificateEntry("Created by Fluent Management", entry);
            store.SetKeyEntry("Created by Fluent Management", keyEntry, new[] { entry });
            store.Save(stream, userPassword.ToCharArray(), new SecureRandom());

             // Create the equivalent C# representation
            var cert = new X509Certificate2(stream.GetBuffer(), userPassword, X509KeyStorageFlags.Exportable);
            // set up the PEM writer too
            if (exportDirectory != null)
            {
                var textWriter = new StringWriter();
                var pemWriter = new PemWriter(textWriter);
                pemWriter.WriteObject(cerKp.Private, "DESEDE", userPassword.ToCharArray(), new SecureRandom());
                pemWriter.Writer.Flush();
                string privateKeyPem = textWriter.ToString();
                using (var writer = new StreamWriter(Path.Combine(exportDirectory, cert.Thumbprint + ".pem")))
                    {
                        writer.WriteLine(privateKeyPem);
                    }
                // also export the certs - first the .pfx
                byte[] privateKeyBytes = cert.Export(X509ContentType.Pfx, userPassword);
                using (var writer = new FileStream(Path.Combine(exportDirectory, cert.Thumbprint + ".pfx"), FileMode.OpenOrCreate, FileAccess.Write))
                {
                    writer.Write(privateKeyBytes, 0, privateKeyBytes.Length);
                }
                // also export the certs - then the .cer
                byte[] publicKeyBytes = cert.Export(X509ContentType.Cert);
                using (var writer = new FileStream(Path.Combine(exportDirectory, cert.Thumbprint + ".cer"), FileMode.OpenOrCreate, FileAccess.Write))
                {
                    writer.Write(publicKeyBytes, 0, publicKeyBytes.Length);
                }
            }

            // if specified then this add this certificate to the store
            if (addtoStore)
                AddToMyStore(cert);

            return cert;
        }
        /// <summary>
        /// Static method used to create a certificate and return as a .net object
        /// </summary>
        public static X509Certificate2 Create(string name, DateTime start, DateTime end, string userPassword,
                                              bool addtoStore = false)
        {
            // generate a key pair using RSA
            var generator = new RsaKeyPairGenerator();
            // keys have to be a minimum of 2048 bits for Azure
            generator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048));
            AsymmetricCipherKeyPair cerKp = generator.GenerateKeyPair();
            // get a copy of the private key
            AsymmetricKeyParameter privateKey = cerKp.Private;

            // create the CN using the name passed in and create a unique serial number for the cert
            var certName = new X509Name("CN=" + name);
            BigInteger serialNo = BigInteger.ProbablePrime(120, new Random());

            // start the generator and set CN/DN and serial number and valid period
            var x509Generator = new X509V3CertificateGenerator();
            x509Generator.SetSerialNumber(serialNo);
            x509Generator.SetSubjectDN(certName);
            x509Generator.SetIssuerDN(certName);
            x509Generator.SetNotBefore(start);
            x509Generator.SetNotAfter(end);
            // add the server authentication key usage
            var keyUsage = new KeyUsage(KeyUsage.KeyEncipherment);
            x509Generator.AddExtension(X509Extensions.KeyUsage, false, keyUsage.ToAsn1Object());
            var extendedKeyUsage = new ExtendedKeyUsage(new[] {KeyPurposeID.IdKPServerAuth});
            x509Generator.AddExtension(X509Extensions.ExtendedKeyUsage, true, extendedKeyUsage.ToAsn1Object());
            // algorithm can only be SHA1 ??
            x509Generator.SetSignatureAlgorithm("sha1WithRSA");
            // Set the key pair
            x509Generator.SetPublicKey(cerKp.Public);
            X509Certificate certificate = x509Generator.Generate(cerKp.Private);

            // export the certificate bytes
            byte[] certStream = DotNetUtilities.ToX509Certificate(certificate).Export(X509ContentType.Pkcs12,
                                                                                      userPassword);

            // build the key parameter and the certificate entry
            var keyEntry = new AsymmetricKeyEntry(privateKey);
            var entry = new X509CertificateEntry(certificate);
            // build the PKCS#12 store to encapsulate the certificate
            var builder = new Pkcs12StoreBuilder();
            builder.SetUseDerEncoding(true);
            builder.SetCertAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
            builder.SetKeyAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
            builder.Build();
            // create a memorystream to hold the output
            var stream = new MemoryStream(2000);
            // create the individual store and set two entries for cert and key
            var store = new Pkcs12Store();
            store.SetCertificateEntry("Elastacloud Test Certificate", entry);
            store.SetKeyEntry("Elastacloud Test Certificate", keyEntry, new[] {entry});
            store.Save(stream, userPassword.ToCharArray(), new SecureRandom());

            // Create the equivalent C# representation
            var cert = new X509Certificate2(stream.GetBuffer(), userPassword, X509KeyStorageFlags.Exportable);
            // if specified then this add this certificate to the store
            if (addtoStore)
                AddToMyStore(cert);

            return cert;
        }
        /// <summary>
        /// Creates a self signed application instance certificate.
        /// </summary>
        /// <param name="storeType">Type of certificate store (Directory) <see cref="CertificateStoreType"/>.</param>
        /// <param name="storePath">The store path (syntax depends on storeType).</param>
        /// <param name="password">The password to use to protect the certificate.</param>
        /// <param name="applicationUri">The application uri (created if not specified).</param>
        /// <param name="applicationName">Name of the application (optional if subjectName is specified).</param>
        /// <param name="subjectName">The subject used to create the certificate (optional if applicationName is specified).</param>
        /// <param name="domainNames">The domain names that can be used to access the server machine (defaults to local computer name if not specified).</param>
        /// <param name="keySize">Size of the key (1024, 2048 or 4096).</param>
        /// <param name="startTime">The start time.</param>
        /// <param name="lifetimeInMonths">The lifetime of the key in months.</param>
        /// <param name="hashSizeInBits">The hash size in bits.</param>
        /// <param name="isCA">if set to <c>true</c> then a CA certificate is created.</param>
        /// <param name="issuerCAKeyCert">The CA cert with the CA private key.</param>
        /// <returns>The certificate with a private key.</returns>
        public static X509Certificate2 CreateCertificate(
            string storeType,
            string storePath,
            string password,
            string applicationUri,
            string applicationName,
            string subjectName,
            IList<String> domainNames,
            ushort keySize,
            DateTime startTime,
            ushort lifetimeInMonths,
            ushort hashSizeInBits,
            bool isCA,
            X509Certificate2 issuerCAKeyCert)
        {
            if (!String.IsNullOrEmpty(storeType) &&
                storeType != CertificateStoreType.Directory)
            {
                throw new NotSupportedException("Cannot create a certificate for a non directory store.");
            }

            if (issuerCAKeyCert != null)
            {
                if (!issuerCAKeyCert.HasPrivateKey)
                {
                    throw new NotSupportedException("Cannot sign with a CA certificate without a private key.");
                }

                throw new NotSupportedException("Signing with an issuer CA certificate is currently unsupported.");
            }

            // set default values.
            SetSuitableDefaults(
                ref applicationUri,
                ref applicationName,
                ref subjectName,
                ref domainNames,
                ref keySize,
                ref lifetimeInMonths,
                isCA);

            // cert generators
            SecureRandom random = new SecureRandom();
            X509V3CertificateGenerator cg = new X509V3CertificateGenerator();

            // Serial Number
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
            cg.SetSerialNumber(serialNumber);

            // build name attributes
            var nameOids = new ArrayList();
            nameOids.Add(X509Name.DC);
            nameOids.Add(X509Name.CN);

            var nameValues = new ArrayList();
            nameValues.Add(domainNames[0]);
            nameValues.Add(applicationName);

            // self signed 
            X509Name subjectDN = new X509Name(nameOids, nameValues);
            X509Name issuerDN = subjectDN;
            cg.SetIssuerDN(issuerDN);
            cg.SetSubjectDN(subjectDN);

            // valid for
            cg.SetNotBefore(startTime);
            cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths));

            // Private/Public Key
            AsymmetricCipherKeyPair subjectKeyPair;
            var keyGenerationParameters = new KeyGenerationParameters(random, keySize);
            var keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);
            subjectKeyPair = keyPairGenerator.GenerateKeyPair();
            cg.SetPublicKey(subjectKeyPair.Public);

            // add extensions
            // Subject key identifier
            cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false,
                new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public)));

            // Basic constraints
            cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA));

            // Authority Key identifier
            var issuerKeyPair = subjectKeyPair;
            var issuerSerialNumber = serialNumber;
            cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false,
                new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public),
                    new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber));

            if (!isCA)
            {
                // Key usage 
                cg.AddExtension(X509Extensions.KeyUsage, true,
                    new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature |
                        KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment));

                // Extended Key usage
                cg.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                    new ExtendedKeyUsage(new List<DerObjectIdentifier>() {
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.1"), // server auth
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.2"), // client auth
                    }));

                // subject alternate name
                cg.AddExtension(X509Extensions.SubjectAlternativeName, false,
                    new GeneralNames(new GeneralName[] {
                    new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri),
                    new GeneralName(GeneralName.DnsName, domainNames[0])}));
            }
            else
            {
                // Key usage CA
                cg.AddExtension(X509Extensions.KeyUsage, true,
                    new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign));
            }

            // sign certificate
            ISignatureFactory signatureFactory = 
                new Asn1SignatureFactory((hashSizeInBits < 256) ? "SHA1WITHRSA" : "SHA256WITHRSA", subjectKeyPair.Private, random);
            Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory);

            // create pkcs12 store for cert and private key
            X509Certificate2 certificate = null;
            using (MemoryStream pfxData = new MemoryStream())
            {
                Pkcs12Store pkcsStore = new Pkcs12StoreBuilder().Build();
                X509CertificateEntry[] chain = new X509CertificateEntry[1];
                string passcode = "passcode";
                chain[0] = new X509CertificateEntry(x509);
                pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain);
                pkcsStore.Save(pfxData, passcode.ToCharArray(), random);

                // merge into X509Certificate2
                certificate = CreateCertificateFromPKCS12(pfxData.ToArray(), passcode);
            }

            Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint);

            // add cert to the store.
            if (!String.IsNullOrEmpty(storePath))
            {
                ICertificateStore store = null;
                if (storeType == CertificateStoreType.Directory)
                {
                    using (store = new DirectoryCertificateStore())
                    {
                        store.Open(storePath);
                        store.Add(certificate);
                        store.Close();
                    }
                }
            }

            // note: this cert has a private key!
            return certificate;
        }
		private void testNoExtraLocalKeyID(byte[] store1data)
		{
			IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("RSA");
			kpg.Init(new RsaKeyGenerationParameters(
				BigInteger.ValueOf(0x10001), new SecureRandom(), 512, 25));

			AsymmetricCipherKeyPair newPair =  kpg.GenerateKeyPair();

			Pkcs12Store store1 = new Pkcs12StoreBuilder().Build();
			store1.Load(new MemoryStream(store1data, false), passwd);

			Pkcs12Store store2 = new Pkcs12StoreBuilder().Build();

			AsymmetricKeyEntry k1 = store1.GetKey("privatekey");
			X509CertificateEntry[] chain1 = store1.GetCertificateChain("privatekey");

			X509CertificateEntry[] chain2 = new X509CertificateEntry[chain1.Length + 1];

			Array.Copy(chain1, 0, chain2, 1, chain1.Length);

			chain2[0] = CreateCert(newPair.Public, k1.Key, "*****@*****.**", "*****@*****.**");

			if (chain1[0][PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
			{
				Fail("localKeyID not found initially");
			}

			store2.SetKeyEntry("new", new AsymmetricKeyEntry(newPair.Private), chain2);

			MemoryStream bOut = new MemoryStream();

			store2.Save(bOut, passwd, new SecureRandom());

			store2.Load(new MemoryStream(bOut.ToArray(), false), passwd);

			chain2 = store2.GetCertificateChain("new");

			if (chain2[1][PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] != null)
			{
				Fail("localKeyID found after save");
			}
		}
		public static Org.BouncyCastle.X509.X509Certificate LoadBouncyCertFromPKCS12Store(string Filename)
		{
			Pkcs12Store Store = new Pkcs12StoreBuilder().Build();
			Store.Load(File.OpenRead(Filename), new char[0]);

			foreach (string Alias in Store.Aliases)
			{
				if (Store.IsCertificateEntry(Alias))
				{
					return Store.GetCertificate(Alias).Certificate;
				}
			}

			return null;
		}
		public static RSACryptoServiceProvider LoadKeyPairFromPKCS12Store(string Filename)
		{
			Pkcs12Store Store = new Pkcs12StoreBuilder().Build();
			Store.Load(File.OpenRead(Filename), new char[0]);

			foreach (string Alias in Store.Aliases)
			{
				if (Store.IsKeyEntry(Alias))
				{
					Console.WriteLine("Key with alias {0} is {1}", Alias, Store.GetKey(Alias).Key);
					return ConvertBouncyKeyPairToNET(Store.GetKey(Alias).Key as RsaPrivateCrtKeyParameters);
				}
			}

			return null;
		}
        //            throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, UnrecoverableKeyException
        private void keyStoreTest(
			IAsymmetricKeyParameter	sKey,
			IAsymmetricKeyParameter	vKey)
        {
            //
            // keystore test
            //
            //			KeyStore ks = KeyStore.GetInstance("JKS");
            //			ks.Load(null, null);
            Pkcs12StoreBuilder ksBuilder = new Pkcs12StoreBuilder();
            Pkcs12Store ks = ksBuilder.Build();

            //
            // create the certificate - version 3
            //
            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

            certGen.SetSerialNumber(BigInteger.One);
            certGen.SetIssuerDN(new X509Name("CN=Test"));
            certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50));
            certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50));
            certGen.SetSubjectDN(new X509Name("CN=Test"));
            certGen.SetPublicKey(vKey);
            certGen.SetSignatureAlgorithm("GOST3411withGOST3410");

            X509Certificate cert = certGen.Generate(sKey);
            X509CertificateEntry certEntry = new X509CertificateEntry(cert);

            //	        ks.SetKeyEntry("gost", sKey, "gost".ToCharArray(), new X509Certificate[] { cert });
            ks.SetKeyEntry("gost", new AsymmetricKeyEntry(sKey), new X509CertificateEntry[] { certEntry });

            MemoryStream bOut = new MemoryStream();

            ks.Save(bOut, "gost".ToCharArray(), new SecureRandom());

            //	        ks = KeyStore.getInstance("JKS");
            ks = ksBuilder.Build();

            ks.Load(new MemoryStream(bOut.ToArray(), false), "gost".ToCharArray());

            //	        IAsymmetricKeyParameter gKey = (AsymmetricKeyParameter)ks.GetKey("gost", "gost".ToCharArray());
            //	        AsymmetricKeyEntry gKeyEntry = (AsymmetricKeyEntry)
                ks.GetKey("gost");
        }
        /// <exception cref="Sharpen.KeyStoreException"></exception>
        public override IList<IDssPrivateKeyEntry> GetKeys()
        {
            if (keys != null)
                return keys;

            IList<IDssPrivateKeyEntry> list = new AList<IDssPrivateKeyEntry>();
            try
            {
                Pkcs12Store keyStore = new Pkcs12StoreBuilder().Build();
                FileInputStream input = new FileInputStream(pkcs12File);
                keyStore.Load(input, password);
                input.Close();

                foreach (string alias in keyStore.Aliases)
                {
                    if (keyStore.IsKeyEntry(alias)
                        && keyStore.GetKey(alias).Key.IsPrivate
                        && keyStore.GetCertificate(alias).Certificate.GetKeyUsage()[0] //0: DigitalSignature
                        )
                    {
                        X509CertificateEntry[] x = keyStore.GetCertificateChain(alias);
                        X509Certificate[] chain = new X509Certificate[x.Length];

                        for (int k = 0; k < x.Length; ++k)
                        {
                            chain[k] = x[k].Certificate;
                        }

                        AsymmetricKeyParameter privateKey = keyStore.GetKey(alias).Key;

                        list.AddItem(new KSPrivateKeyEntry(chain[0], chain, privateKey));
                    }
                }
            }
            catch (IOException iox)
            {
                if (iox.Message.Contains("password") || iox.Message.Contains("corrupted"))
                {
                    //"PKCS12 key store MAC invalid - wrong  or corrupted file."
                    throw new IOException("La contraseña es incorrecta, o el archivo está corrompido.", iox);
                }

                throw;
            }
            catch (NoSuchAlgorithmException e)
            {
                //throw new KeyStoreException("Can't initialize Sun PKCS#12 security " + "provider. Reason: "
                //     + e.InnerException.Message, e);
                throw;
            }
            catch (CertificateException e)
            {
                //throw new KeyStoreException("Can't initialize Sun PKCS#12 security " + "provider. Reason: "
                //     + e.InnerException.Message, e);
                throw;
            }
            /*catch (UnrecoverableEntryException e)
            {
                throw new KeyStoreException("Can't initialize Sun PKCS#12 security " + "provider. Reason: "
                     + e.InnerException.Message, e);
            }*/

            this.keys = list;

            return list;
        }
		public void doTestPkcs12Store()
		{
			BigInteger mod = new BigInteger("bb1be8074e4787a8d77967f1575ef72dd7582f9b3347724413c021beafad8f32dba5168e280cbf284df722283dad2fd4abc750e3d6487c2942064e2d8d80641aa5866d1f6f1f83eec26b9b46fecb3b1c9856a303148a5cc899c642fb16f3d9d72f52526c751dc81622c420c82e2cfda70fe8d13f16cc7d6a613a5b2a2b5894d1", 16);

			MemoryStream stream = new MemoryStream(pkcs12, false);
			Pkcs12Store store = new Pkcs12StoreBuilder().Build();
			store.Load(stream, passwd);

			string pName = null;
			foreach (string n in store.Aliases)
			{
				if (store.IsKeyEntry(n))
				{
					pName = n;
					//break;
				}
			}

			AsymmetricKeyEntry key = store.GetKey(pName);

			if (!((RsaKeyParameters) key.Key).Modulus.Equals(mod))
			{
				Fail("Modulus doesn't match.");
			}

			X509CertificateEntry[] ch = store.GetCertificateChain(pName);

			if (ch.Length != 3)
			{
				Fail("chain was wrong length");
			}

			if (!ch[0].Certificate.SerialNumber.Equals(new BigInteger("96153094170511488342715101755496684211")))
			{
				Fail("chain[0] wrong certificate.");
			}

			if (!ch[1].Certificate.SerialNumber.Equals(new BigInteger("279751514312356623147411505294772931957")))
			{
				Fail("chain[1] wrong certificate.");
			}

			if (!ch[2].Certificate.SerialNumber.Equals(new BigInteger("11341398017")))
			{
				Fail("chain[2] wrong certificate.");
			}

			//
			// save test
			//
			MemoryStream bOut = new MemoryStream();
			store.Save(bOut, passwd, new SecureRandom());

			stream = new MemoryStream(bOut.ToArray(), false);
			store.Load(stream, passwd);

			key = store.GetKey(pName);

			if (!((RsaKeyParameters)key.Key).Modulus.Equals(mod))
			{
				Fail("Modulus doesn't match.");
			}

			store.DeleteEntry(pName);

			if (store.GetKey(pName) != null)
			{
				Fail("Failed deletion test.");
			}

			//
			// cert chain test
			//
			store.SetCertificateEntry("testCert", ch[2]);

			if (store.GetCertificateChain("testCert") != null)
			{
				Fail("Failed null chain test.");
			}

			//
			// UTF 8 single cert test
			//
			stream = new MemoryStream(certUTF, false);
			store.Load(stream, "user".ToCharArray());

			if (store.GetCertificate("37") == null)
			{
				Fail("Failed to find UTF cert.");
			}

			//
			// try for a self generated certificate
			//
			RsaKeyParameters pubKey = new RsaKeyParameters(
				false,
				new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
				new BigInteger("11", 16));

			RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
				new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
				new BigInteger("11", 16),
				new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
				new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
				new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
				new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
				new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
				new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));

			X509CertificateEntry[] chain = new X509CertificateEntry[] {
				CreateCert(pubKey, privKey, "*****@*****.**", "*****@*****.**")
			};

			store = new Pkcs12StoreBuilder().Build();

			store.SetKeyEntry("privateKey", new AsymmetricKeyEntry(privKey), chain);

			if (!store.ContainsAlias("privateKey") || !store.ContainsAlias("PRIVATEKEY"))
			{
				Fail("couldn't find alias privateKey");
			}

			if (store.IsCertificateEntry("privateKey"))
			{
				Fail("key identified as certificate entry");
			}

			if (!store.IsKeyEntry("privateKey") || !store.IsKeyEntry("PRIVATEKEY"))
			{
				Fail("key not identified as key entry");
			}

			if (!"privateKey".Equals(store.GetCertificateAlias(chain[0].Certificate)))
			{
				Fail("Did not return alias for key certificate privateKey");
			}

			MemoryStream store1Stream = new MemoryStream();
			store.Save(store1Stream, passwd, new SecureRandom());
			testNoExtraLocalKeyID(store1Stream.ToArray());

			//
			// no friendly name test
			//
			stream = new MemoryStream(pkcs12noFriendly, false);
			store.Load(stream, noFriendlyPassword);

			pName = null;

			foreach (string n in store.Aliases)
			{
				if (store.IsKeyEntry(n))
				{
					pName = n;
					//break;
				}
			}

			ch = store.GetCertificateChain(pName);

			//for (int i = 0; i != ch.Length; i++)
			//{
			//	Console.WriteLine(ch[i]);
			//}

			if (ch.Length != 1)
			{
				Fail("no cert found in pkcs12noFriendly");
			}

			//
			// failure tests
			//
			ch = store.GetCertificateChain("dummy");

			store.GetCertificateChain("DUMMY");

			store.GetCertificate("dummy");

			store.GetCertificate("DUMMY");

			//
			// storage test
			//
			stream = new MemoryStream(pkcs12StorageIssue, false);
			store.Load(stream, storagePassword);

			pName = null;

			foreach (string n in store.Aliases)
			{
				if (store.IsKeyEntry(n))
				{
					pName = n;
					//break;
				}
			}

			ch = store.GetCertificateChain(pName);
			if (ch.Length != 2)
			{
				Fail("Certificate chain wrong length");
			}

			store.Save(new MemoryStream(), storagePassword, new SecureRandom());

			//
			// basic certificate check
			//
			store.SetCertificateEntry("cert", ch[1]);

			if (!store.ContainsAlias("cert") || !store.ContainsAlias("CERT"))
			{
				Fail("couldn't find alias cert");
			}

			if (!store.IsCertificateEntry("cert") || !store.IsCertificateEntry("CERT"))
			{
				Fail("cert not identified as certificate entry");
			}

			if (store.IsKeyEntry("cert") || store.IsKeyEntry("CERT"))
			{
				Fail("cert identified as key entry");
			}

			if (!store.IsEntryOfType("cert", typeof(X509CertificateEntry)))
			{
				Fail("cert not identified as X509CertificateEntry");
			}

			if (!store.IsEntryOfType("CERT", typeof(X509CertificateEntry)))
			{
				Fail("CERT not identified as X509CertificateEntry");
			}

			if (store.IsEntryOfType("cert", typeof(AsymmetricKeyEntry)))
			{
				Fail("cert identified as key entry via AsymmetricKeyEntry");
			}

			if (!"cert".Equals(store.GetCertificateAlias(ch[1].Certificate)))
			{
				Fail("Did not return alias for certificate entry");
			}

			//
			// test restoring of a certificate with private key originally as a ca certificate
			//
			store = new Pkcs12StoreBuilder().Build();

			store.SetCertificateEntry("cert", ch[0]);

			if (!store.ContainsAlias("cert") || !store.ContainsAlias("CERT"))
			{
				Fail("restore: couldn't find alias cert");
			}

			if (!store.IsCertificateEntry("cert") || !store.IsCertificateEntry("CERT"))
			{
				Fail("restore: cert not identified as certificate entry");
			}

			if (store.IsKeyEntry("cert") || store.IsKeyEntry("CERT"))
			{
				Fail("restore: cert identified as key entry");
			}

			if (store.IsEntryOfType("cert", typeof(AsymmetricKeyEntry)))
			{
				Fail("restore: cert identified as key entry via AsymmetricKeyEntry");
			}

			if (store.IsEntryOfType("CERT", typeof(AsymmetricKeyEntry)))
			{
				Fail("restore: cert identified as key entry via AsymmetricKeyEntry");
			}

			if (!store.IsEntryOfType("cert", typeof(X509CertificateEntry)))
			{
				Fail("restore: cert not identified as X509CertificateEntry");
			}

			//
			// test of reading incorrect zero-length encoding
			//
			stream = new MemoryStream(pkcs12nopass, false);
			store.Load(stream, "".ToCharArray());
		}
		/// <summary>
		/// Merges a certificate and private key into a single combined certificate
		/// </summary>
		public static X509Certificate2 CombineKeyAndCert(string CertificateFilename, string KeyFilename)
		{
			// Load the certificate
			string CertificatePassword = "";
			X509Certificate2 Cert = new X509Certificate2(CertificateFilename, CertificatePassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

			// Make sure we have a useful friendly name
			string FriendlyName = Cert.FriendlyName;
			if ((FriendlyName == "") || (FriendlyName == null))
			{
				FriendlyName = GetCommonNameFromCert(Cert);
			}

			// Create a PKCS#12 store with both the certificate and the private key in it
			Pkcs12Store Store = new Pkcs12StoreBuilder().Build();

			X509CertificateEntry[] CertChain = new X509CertificateEntry[1];
			Org.BouncyCastle.X509.X509Certificate BouncyCert = DotNetUtilities.FromX509Certificate(Cert);
			CertChain[0] = new X509CertificateEntry(BouncyCert);

			AsymmetricCipherKeyPair KeyPair = LoadKeyPairFromDiskBouncy(KeyFilename);

			Store.SetKeyEntry(FriendlyName, new AsymmetricKeyEntry(KeyPair.Private), CertChain);

			// Verify the public key from the key pair matches the certificate's public key
			AsymmetricKeyParameter CertPublicKey = BouncyCert.GetPublicKey();
			if (!(KeyPair.Public as RsaKeyParameters).Equals(CertPublicKey as RsaKeyParameters))
			{
				throw new InvalidDataException("The key pair provided does not match the certificate.  Make sure you provide the same key pair that was used to generate the original certificate signing request");
			}

			// Export the merged cert as a .p12
			string TempFileName = Path.GetTempFileName();

			string ReexportedPassword = "******";

			Stream OutStream = File.OpenWrite(TempFileName);
			Store.Save(OutStream, ReexportedPassword.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
			OutStream.Close();

			// Load it back in and delete the temporary file
			X509Certificate2 Result = new X509Certificate2(TempFileName, ReexportedPassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);
			FileOperations.DeleteFile(TempFileName);
			return Result;
		}
		private void basicStoreTest(AsymmetricKeyEntry privKey, X509CertificateEntry[] chain,
			DerObjectIdentifier keyAlgorithm, DerObjectIdentifier certAlgorithm)
		{
			Pkcs12Store store = new Pkcs12StoreBuilder()
				.SetKeyAlgorithm(keyAlgorithm)
				.SetCertAlgorithm(certAlgorithm)
				.Build();

			store.SetKeyEntry("key", privKey, chain);

			MemoryStream bOut = new MemoryStream();

			store.Save(bOut, passwd, new SecureRandom());

			store.Load(new MemoryStream(bOut.ToArray(), false), passwd);

			AsymmetricKeyEntry k = store.GetKey("key");

			if (!k.Equals(privKey))
			{
				Fail("private key didn't match");
			}

			X509CertificateEntry[] c = store.GetCertificateChain("key");

			if (c.Length != chain.Length || !c[0].Equals(chain[0]))
			{
				Fail("certificates didn't match");
			}

			// check attributes
			Pkcs12Entry b1 = k;
			Pkcs12Entry b2 = chain[0];

			if (b1[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] != null)
			{
				DerBmpString name = (DerBmpString)b1[PkcsObjectIdentifiers.Pkcs9AtFriendlyName];

				if (!name.Equals(new DerBmpString("key")))
				{
					Fail("friendly name wrong");
				}
			}
			else
			{
				Fail("no friendly name found on key");
			}

			if (b1[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] != null)
			{
				Asn1OctetString id = (Asn1OctetString)b1[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID];

				if (!id.Equals(b2[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID]))
				{
					Fail("local key id mismatch");
				}
			}
			else
			{
				Fail("no local key id found");
			}

			//
			// check algorithm types.
			//
			Asn1InputStream aIn = new Asn1InputStream(bOut.ToArray());

			Pfx pfx = new Pfx((Asn1Sequence)aIn.ReadObject());

			ContentInfo cInfo = pfx.AuthSafe;

			Asn1OctetString auth = (Asn1OctetString)cInfo.Content;

			aIn = new Asn1InputStream(auth.GetOctets());
			Asn1Sequence s1 = (Asn1Sequence)aIn.ReadObject();

			ContentInfo c1 = ContentInfo.GetInstance(s1[0]);
			ContentInfo c2 = ContentInfo.GetInstance(s1[1]);

			aIn = new Asn1InputStream(((Asn1OctetString)c1.Content).GetOctets());

			SafeBag sb = new SafeBag((Asn1Sequence)(((Asn1Sequence)aIn.ReadObject())[0]));

			EncryptedPrivateKeyInfo encInfo = EncryptedPrivateKeyInfo.GetInstance(sb.BagValue);

			// check the key encryption
            if (!encInfo.EncryptionAlgorithm.Algorithm.Equals(keyAlgorithm))
			{
				Fail("key encryption algorithm wrong");
			}

			// check the certificate encryption
			EncryptedData cb = EncryptedData.GetInstance(c2.Content);

            if (!cb.EncryptionAlgorithm.Algorithm.Equals(certAlgorithm))
			{
				Fail("cert encryption algorithm wrong");
			}
		}
        // Only the ctor should be calling with isAuthority = true
        // if isAuthority, value for isMachineCert doesn't matter
        private X509CertificateContainer CreateCertificate(bool isAuthority, bool isMachineCert, X509Certificate signingCertificate, CertificateCreationSettings certificateCreationSettings)
        {
            if (certificateCreationSettings == null)
            {
                if (isAuthority)
                {
                    certificateCreationSettings = new CertificateCreationSettings();
                }
                else
                {
                    throw new Exception("Parameter certificateCreationSettings cannot be null when isAuthority is false");
                }
            }

            // Set to default cert creation settings if not set
            if (certificateCreationSettings.ValidityNotBefore == default(DateTime))
            {
                certificateCreationSettings.ValidityNotBefore = _defaultValidityNotBefore;
            }
            if (certificateCreationSettings.ValidityNotAfter == default(DateTime))
            {
                certificateCreationSettings.ValidityNotAfter = _defaultValidityNotAfter;
            }

            string[] subjects = certificateCreationSettings.Subjects;
            if (!isAuthority ^ (signingCertificate != null))
            {
                throw new ArgumentException("Either isAuthority == true or signingCertificate is not null");
            }

            if (!isAuthority && (subjects == null || subjects.Length == 0))
            {
                throw new ArgumentException("If not creating an authority, must specify at least one Subject", "subjects");
            }

            if (!isAuthority && string.IsNullOrWhiteSpace(subjects[0]))
            {
                throw new ArgumentException("Certificate Subject must not be an empty string or only whitespace", "creationSettings.Subjects");
            }

            EnsureInitialized();

            _certGenerator.Reset();
            _certGenerator.SetSignatureAlgorithm(_signatureAlthorithm);

            X509Name authorityX509Name = CreateX509Name(_authorityCanonicalName);
            
            var keyPair = isAuthority ? _authorityKeyPair : _keyPairGenerator.GenerateKeyPair();
            if (isAuthority)
            {
                _certGenerator.SetIssuerDN(authorityX509Name);
                _certGenerator.SetSubjectDN(authorityX509Name);

                var authorityKeyIdentifier = new AuthorityKeyIdentifier(
                    SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(_authorityKeyPair.Public),
                    new GeneralNames(new GeneralName(authorityX509Name)),
                    new BigInteger(7, _random).Abs());

                _certGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, true, authorityKeyIdentifier);
                _certGenerator.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(X509KeyUsage.DigitalSignature | X509KeyUsage.KeyAgreement | X509KeyUsage.KeyCertSign | X509KeyUsage.KeyEncipherment | X509KeyUsage.CrlSign));

            }
            else
            {
                X509Name subjectName = CreateX509Name(subjects[0]);
                _certGenerator.SetIssuerDN(PrincipalUtilities.GetSubjectX509Principal(signingCertificate));
                _certGenerator.SetSubjectDN(subjectName);

                _certGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, true, new AuthorityKeyIdentifierStructure(_authorityKeyPair.Public));
                _certGenerator.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(X509KeyUsage.DigitalSignature | X509KeyUsage.KeyAgreement | X509KeyUsage.KeyEncipherment));

            }

            _certGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(keyPair.Public));

            _certGenerator.SetSerialNumber(new BigInteger(64 /*sizeInBits*/, _random).Abs());
            _certGenerator.SetNotBefore(certificateCreationSettings.ValidityNotBefore);
            _certGenerator.SetNotAfter(certificateCreationSettings.ValidityNotAfter);
            _certGenerator.SetPublicKey(keyPair.Public);

            _certGenerator.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(isAuthority));
            _certGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPClientAuth));

            if (!isAuthority)
            {
                if (isMachineCert)
                {
                    List<Asn1Encodable> subjectAlternativeNames = new List<Asn1Encodable>(); 
                    
                    // All endpoints should also be in the Subject Alt Names 
                    for (int i = 0; i < subjects.Length; i++)
                    {
                        if (!string.IsNullOrWhiteSpace(subjects[i]))
                        {
                            // Machine certs can have additional DNS names
                            subjectAlternativeNames.Add(new GeneralName(GeneralName.DnsName, subjects[i]));
                        }
                    }

                    _certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, true, new DerSequence(subjectAlternativeNames.ToArray()));
                }
                else
                {
                    if (subjects.Length > 1)
                    {
                        var subjectAlternativeNames = new Asn1EncodableVector();
                    
                        // Only add a SAN for the user if there are any
                        for (int i = 1; i < subjects.Length; i++)
                        {
                            if (!string.IsNullOrWhiteSpace(subjects[i]))
                            {
                                Asn1EncodableVector otherNames = new Asn1EncodableVector();
                                otherNames.Add(new DerObjectIdentifier(_upnObjectId));
                                otherNames.Add(new DerTaggedObject(true, 0, new DerUtf8String(subjects[i])));

                                Asn1Object genName = new DerTaggedObject(false, 0, new DerSequence(otherNames));

                                subjectAlternativeNames.Add(genName);
                            }
                        }
                        _certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, true, new DerSequence(subjectAlternativeNames));
                    }
                }
            }

            var crlDistributionPoints = new DistributionPoint[1] {
                new DistributionPoint(new DistributionPointName(
                    new GeneralNames(new GeneralName(GeneralName.UniformResourceIdentifier, _crlUri))), null, new GeneralNames(new GeneralName(authorityX509Name)))
                };
            var revocationListExtension = new CrlDistPoint(crlDistributionPoints);
            _certGenerator.AddExtension(X509Extensions.CrlDistributionPoints, false, revocationListExtension);

            X509Certificate cert = _certGenerator.Generate(_authorityKeyPair.Private, _random);
            if (certificateCreationSettings.IsValidCert)
            {
                EnsureCertificateValidity(cert);
            }

            // For now, given that we don't know what format to return it in, preserve the formats so we have 
            // the flexibility to do what we need to

            X509CertificateContainer container = new X509CertificateContainer(); 

            X509CertificateEntry[] chain = new X509CertificateEntry[1];
            chain[0] = new X509CertificateEntry(cert);

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();
            store.SetKeyEntry("", new AsymmetricKeyEntry(keyPair.Private), chain);

            using (MemoryStream stream = new MemoryStream())
            {
                store.Save(stream, _password.ToCharArray(), _random);
                container.Pfx = stream.ToArray(); 
            }

            X509Certificate2 outputCert;
            if (isAuthority)
            {
                // don't hand out the private key for the cert when it's the authority
                outputCert = new X509Certificate2(cert.GetEncoded()); 
            } 
            else
            {
                // Otherwise, allow encode with the private key. note that X509Certificate2.RawData will not provide the private key
                // you will have to re-export this cert if needed
                outputCert = new X509Certificate2(container.Pfx, _password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
            }

            container.Subject = subjects[0];
            container.InternalCertificate = cert;
            container.Certificate = outputCert;
            container.Thumbprint = outputCert.Thumbprint;

            Trace.WriteLine("[CertificateGenerator] generated a certificate:");
            Trace.WriteLine(string.Format("    {0} = {1}", "isAuthority", isAuthority));
            if (!isAuthority)
            {
                Trace.WriteLine(string.Format("    {0} = {1}", "Signed by", signingCertificate.SubjectDN));
                Trace.WriteLine(string.Format("    {0} = {1}", "Subject (CN) ", subjects[0]));
                Trace.WriteLine(string.Format("    {0} = {1}", "Alt names ", string.Join(", ", subjects)));
            }
            Trace.WriteLine(string.Format("    {0} = {1}", "HasPrivateKey:", outputCert.HasPrivateKey));
            Trace.WriteLine(string.Format("    {0} = {1}", "Thumbprint", outputCert.Thumbprint));

            return container;
        }
		private void doTestParams(
			byte[]	ecParameterEncoded,
			bool	compress)
		{
//			string keyStorePass = "******";
			Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(ecParameterEncoded);
			X9ECParameters x9 = new X9ECParameters(seq);
			AsymmetricCipherKeyPair kp = null;
			bool success = false;
			while (!success)
			{
				IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("ECDSA");
//				kpg.Init(new ECParameterSpec(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()));
				ECDomainParameters ecParams = new ECDomainParameters(
					x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
				kpg.Init(new ECKeyGenerationParameters(ecParams, new SecureRandom()));
				kp = kpg.GenerateKeyPair();
				// The very old Problem... we need a certificate chain to
				// save a private key...
				ECPublicKeyParameters pubKey = (ECPublicKeyParameters) kp.Public;

				if (!compress)
				{
					//pubKey.setPointFormat("UNCOMPRESSED");
					pubKey = SetPublicUncompressed(pubKey);
				}

				byte[] x = pubKey.Q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned();
				byte[] y = pubKey.Q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned();
				if (x.Length == y.Length)
				{
					success = true;
				}
			}

			// The very old Problem... we need a certificate chain to
			// save a private key...

			X509CertificateEntry[] chain = new X509CertificateEntry[] {
				new X509CertificateEntry(GenerateSelfSignedSoftECCert(kp, compress))
			};

//			KeyStore keyStore = KeyStore.getInstance("BKS");
//			keyStore.load(null, keyStorePass.ToCharArray());
			Pkcs12Store keyStore = new Pkcs12StoreBuilder().Build();

			keyStore.SetCertificateEntry("ECCert", chain[0]);

			ECPrivateKeyParameters privateECKey = (ECPrivateKeyParameters) kp.Private;
			keyStore.SetKeyEntry("ECPrivKey", new AsymmetricKeyEntry(privateECKey), chain);

			// Test ec sign / verify
			ECPublicKeyParameters pub = (ECPublicKeyParameters) kp.Public;
//			string oldPrivateKey = new string(Hex.encode(privateECKey.getEncoded()));
			byte[] oldPrivateKeyBytes = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateECKey).GetDerEncoded();
			string oldPrivateKey = Hex.ToHexString(oldPrivateKeyBytes);
//			string oldPublicKey = new string(Hex.encode(pub.getEncoded()));
			byte[] oldPublicKeyBytes = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub).GetDerEncoded();
			string oldPublicKey = Hex.ToHexString(oldPublicKeyBytes);
			ECPrivateKeyParameters newKey = (ECPrivateKeyParameters)
				keyStore.GetKey("ECPrivKey").Key;
			ECPublicKeyParameters newPubKey = (ECPublicKeyParameters)
				keyStore.GetCertificate("ECCert").Certificate.GetPublicKey();

			if (!compress)
			{
				// TODO Private key compression?
				//newKey.setPointFormat("UNCOMPRESSED");
				//newPubKey.setPointFormat("UNCOMPRESSED");
				newPubKey = SetPublicUncompressed(newPubKey);
			}

//			string newPrivateKey = new string(Hex.encode(newKey.getEncoded()));
			byte[] newPrivateKeyBytes = PrivateKeyInfoFactory.CreatePrivateKeyInfo(newKey).GetDerEncoded();
			string newPrivateKey = Hex.ToHexString(newPrivateKeyBytes);
//			string newPublicKey = new string(Hex.encode(newPubKey.getEncoded()));
			byte[] newPublicKeyBytes = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(newPubKey).GetDerEncoded();
			string newPublicKey = Hex.ToHexString(newPublicKeyBytes);

			if (!oldPrivateKey.Equals(newPrivateKey))
//			if (!privateECKey.Equals(newKey))
			{
				Fail("failed private key comparison");
			}

			if (!oldPublicKey.Equals(newPublicKey))
//			if (!pub.Equals(newPubKey))
			{
				Fail("failed public key comparison");
			}
		}
        private MSX509.X509Certificate2 CreateCertificate(X509Name name, X509Certificate certificate, AsymmetricKeyParameter privateKey)
        {
            var pkcs12Store = new Pkcs12StoreBuilder().Build();
            pkcs12Store.SetKeyEntry(GetFriendlyName(name), new AsymmetricKeyEntry(privateKey), new[] { new X509CertificateEntry(certificate) });
            var data = new MemoryStream();
            pkcs12Store.Save(data, pkcs12Password_.ToCharArray(), new SecureRandom(new CryptoApiRandomGenerator()));

            MSX509.X509KeyStorageFlags storage = MSX509.X509KeyStorageFlags.Exportable | MSX509.X509KeyStorageFlags.PersistKeySet |
                ((store_ == MSX509.StoreLocation.LocalMachine) ? MSX509.X509KeyStorageFlags.MachineKeySet : MSX509.X509KeyStorageFlags.UserKeySet);

            return new MSX509.X509Certificate2(data.ToArray(), pkcs12Password_, storage);
        }