예제 #1
0
        public ExportCertificateDialog(X509Certificate certificate2, IServiceProvider serviceProvider, CertificatesFeature feature)
            : base(serviceProvider)
        {
            InitializeComponent();

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(txtPath, "TextChanged")
                .Merge(Observable.FromEventPattern <EventArgs>(txtPassword, "TextChanged"))
                .Merge(Observable.FromEventPattern <EventArgs>(txtConfirm, "TextChanged"))
                .Sample(TimeSpan.FromSeconds(0.5))
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                btnOK.Enabled = !string.IsNullOrWhiteSpace(txtPath.Text) &&
                                !string.IsNullOrWhiteSpace(txtPassword.Text) &&
                                !string.IsNullOrWhiteSpace(txtConfirm.Text) &&
                                txtPassword.Text == txtConfirm.Text;
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnBrowse, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                DialogHelper.ShowSaveFileDialog(txtPath, "*.pfx|*.pfx|*.*|*.*", null);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                File.WriteAllBytes(txtPath.Text, certificate2.Export(X509ContentType.Pfx, txtPassword.Text));
                DialogResult = DialogResult.OK;
            }));

            container.Add(
                Observable.FromEventPattern <CancelEventArgs>(this, "HelpButtonClicked")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(EnvironmentVariableTarget =>
            {
                feature.ShowHelp();
            }));
        }
예제 #2
0
        public SelfCertificateDialog(IServiceProvider serviceProvider, CertificatesFeature feature)
            : base(serviceProvider)
        {
            InitializeComponent();
            cbStore.SelectedIndex   = 0;
            cbLength.SelectedIndex  = 3;
            cbHashing.SelectedIndex = 1;
            txtCommonName.Text      = Environment.MachineName;
            dtpFrom.Value           = DateTime.Now;
            dtpTo.Value             = dtpFrom.Value.AddYears(1);

            if (Environment.OSVersion.Version < Version.Parse("6.2"))
            {
                // IMPORTANT: WebHosting store is available since Windows 8.
                cbStore.Enabled = false;
            }

            if (!Helper.IsRunningOnMono())
            {
                NativeMethods.TryAddShieldToButton(btnOK);
            }

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(txtName, "TextChanged")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                btnOK.Enabled = !string.IsNullOrWhiteSpace(txtName.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                var names = txtCommonName.Text;
                if (string.IsNullOrWhiteSpace(names))
                {
                    ShowMessage("DNS names cannot be empty.", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    return;
                }

                var dnsNames = names.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(item => item.Trim()).ToArray();
                if (dnsNames.Length == 0)
                {
                    ShowMessage("DNS names cannot be empty.", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    return;
                }

                // Generate certificate
                string defaultIssuer  = string.Format("CN={0}", dnsNames[0]);
                string defaultSubject = defaultIssuer;
                byte[] sn             = Guid.NewGuid().ToByteArray();
                string subject        = defaultSubject;
                string issuer         = defaultIssuer;
                DateTime notBefore    = dtpFrom.Value;
                DateTime notAfter     = dtpTo.Value;

                RSA issuerKey  = new RSACryptoServiceProvider(int.Parse(cbLength.Text));
                RSA subjectKey = null;

                CspParameters subjectParams   = new CspParameters();
                CspParameters issuerParams    = new CspParameters();
                BasicConstraintsExtension bce = new BasicConstraintsExtension
                {
                    PathLenConstraint    = BasicConstraintsExtension.NoPathLengthConstraint,
                    CertificateAuthority = true
                };
                ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension();
                eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
                SubjectAltNameExtension alt = null;
                string p12File = Path.GetTempFileName();
                string p12pwd  = "test";

                // serial number MUST be positive
                if ((sn[0] & 0x80) == 0x80)
                {
                    sn[0] -= 0x80;
                }

                if (subject != defaultSubject)
                {
                    issuer    = subject;
                    issuerKey = null;
                }
                else
                {
                    subject    = issuer;
                    subjectKey = issuerKey;
                }

                if (subject == null)
                {
                    throw new Exception("Missing Subject Name");
                }

                X509CertificateBuilder cb = new X509CertificateBuilder(3);
                cb.SerialNumber           = sn;
                cb.IssuerName             = issuer;
                cb.NotBefore        = notBefore;
                cb.NotAfter         = notAfter;
                cb.SubjectName      = subject;
                cb.SubjectPublicKey = subjectKey;
                // extensions
                if (bce != null)
                {
                    cb.Extensions.Add(bce);
                }
                if (eku != null)
                {
                    cb.Extensions.Add(eku);
                }
                if (alt != null)
                {
                    cb.Extensions.Add(alt);
                }

                IDigest digest = new Sha1Digest();
                byte[] resBuf  = new byte[digest.GetDigestSize()];
                var spki       = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(DotNetUtilities.GetRsaPublicKey(issuerKey));
                byte[] bytes   = spki.PublicKeyData.GetBytes();
                digest.BlockUpdate(bytes, 0, bytes.Length);
                digest.DoFinal(resBuf, 0);

                cb.Extensions.Add(new SubjectKeyIdentifierExtension {
                    Identifier = resBuf
                });
                cb.Extensions.Add(new AuthorityKeyIdentifierExtension {
                    Identifier = resBuf
                });
                if (cbGenerate.Checked)
                {
                    SubjectAltNameExtension subjectAltNameExtension = new SubjectAltNameExtension(
                        new string[0],
                        dnsNames,
                        new string[0],
                        new string[0])
                    {
                        Critical = false
                    };
                    cb.Extensions.Add(subjectAltNameExtension);
                }

                // signature
                string hashName = cbHashing.SelectedIndex == 0 ? "SHA1" : "SHA256";
                cb.Hash         = hashName;
                byte[] rawcert  = null;
                try
                {
                    rawcert = cb.Sign(issuerKey);
                }
                catch (Exception ex)
                {
                    RollbarLocator.RollbarInstance.Error(ex);
                    ShowError(ex, "Certificate generation error", false);
                    return;
                }

                PKCS12 p12   = new PKCS12();
                p12.Password = p12pwd;

                ArrayList list = new ArrayList();
                // we use a fixed array to avoid endianess issues
                // (in case some tools requires the ID to be 1).
                list.Add(new byte[] { 1, 0, 0, 0 });
                Hashtable attributes = new Hashtable(1);
                attributes.Add(PKCS9.localKeyId, list);

                p12.AddCertificate(new X509Certificate(rawcert), attributes);
                p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
                p12.SaveToFile(p12File);

                Item = new X509Certificate2(p12File, p12pwd)
                {
                    FriendlyName = txtName.Text
                };
                Store = cbStore.SelectedIndex == 0 ? "Personal" : "WebHosting";

                try
                {
                    using (var process = new Process())
                    {
                        // add certificate
                        var start       = process.StartInfo;
                        start.Verb      = "runas";
                        start.FileName  = "cmd";
                        start.Arguments = string.Format("/c \"\"{4}\" /f:\"{0}\" /p:{1} /n:\"{2}\" /s:{3}\"",
                                                        p12File,
                                                        p12pwd,
                                                        txtName.Text,
                                                        cbStore.SelectedIndex == 0 ? "MY" : "WebHosting",
                                                        Path.Combine(Environment.CurrentDirectory, "certificateinstaller.exe"));
                        start.CreateNoWindow = true;
                        start.WindowStyle    = ProcessWindowStyle.Hidden;
                        process.Start();
                        process.WaitForExit();
                        File.Delete(p12File);
                        if (process.ExitCode == 0)
                        {
                            DialogResult = DialogResult.OK;
                        }
                        else
                        {
                            ShowMessage(process.ExitCode.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                        }
                    }
                }
                catch (Win32Exception ex)
                {
                    // elevation is cancelled.
                    if (ex.NativeErrorCode != Microsoft.Web.Administration.NativeMethods.ErrorCancelled)
                    {
                        RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                            { "native", ex.NativeErrorCode }
                        });
                        // throw;
                    }
                }
                catch (Exception ex)
                {
                    RollbarLocator.RollbarInstance.Error(ex);
                }
            }));

            container.Add(
                Observable.FromEventPattern <CancelEventArgs>(this, "HelpButtonClicked")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(EnvironmentVariableTarget =>
            {
                feature.ShowHelp();
            }));
        }
        public ImportCertificateDialog(IServiceProvider serviceProvider, CertificatesFeature feature)
            : base(serviceProvider)
        {
            InitializeComponent();
            cbStore.SelectedIndex = 0;
            if (Environment.OSVersion.Version < Version.Parse("6.2"))
            {
                // IMPORTANT: WebHosting store is available since Windows 8.
                cbStore.Enabled = false;
            }

            if (!Helper.IsRunningOnMono())
            {
                JexusManager.NativeMethods.TryAddShieldToButton(btnOK);
            }

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnBrowse, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                DialogHelper.ShowOpenFileDialog(txtFile, ".pfx|*.pfx|*.*|*.*", null);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(txtFile, "TextChanged")
                .Sample(TimeSpan.FromSeconds(1))
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                btnOK.Enabled = !string.IsNullOrWhiteSpace(txtFile.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                try
                {
                    // Load your certificate from file
                    Item = new X509Certificate2(txtFile.Text, txtPassword.Text, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet)
                    {
                        FriendlyName = txtName.Text
                    };
                    Store       = cbStore.SelectedIndex == 0 ? "Personal" : "WebHosting";
                    var service = (IConfigurationService)GetService(typeof(IConfigurationService));
                    if (service.ServerManager.Mode == WorkingMode.Jexus)
                    {
                        var server = (JexusServerManager)service.Server;
                        // Public Key;
                        StringBuilder publicBuilder = new StringBuilder();
                        publicBuilder.AppendLine("-----BEGIN CERTIFICATE-----");
                        publicBuilder.AppendLine(Convert.ToBase64String(Item.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks));
                        publicBuilder.AppendLine("-----END CERTIFICATE-----");
                        var file = AsyncHelper.RunSync(() => server.SaveCertificateAsync(publicBuilder.ToString()));
                        server.SetCertificate(file);
                        // Private Key
                        RSACryptoServiceProvider rsa    = (RSACryptoServiceProvider)Item.PrivateKey;
                        MemoryStream memoryStream       = new MemoryStream();
                        TextWriter streamWriter         = new StreamWriter(memoryStream);
                        PemWriter pemWriter             = new PemWriter(streamWriter);
                        AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetRsaKeyPair(rsa);
                        pemWriter.WriteObject(keyPair.Private);
                        streamWriter.Flush();
                        string output     = Encoding.ASCII.GetString(memoryStream.GetBuffer()).Trim();
                        int indexOfFooter = output.IndexOf("-----END RSA PRIVATE KEY-----", StringComparison.Ordinal);
                        memoryStream.Close();
                        streamWriter.Close();
                        string key  = output.Substring(0, indexOfFooter + 29);
                        var keyFile = AsyncHelper.RunSync(() => server.SaveKeyAsync(key));
                        server.SetKeyFile(keyFile);
                        service.ServerManager.CommitChanges();
                    }
                    else
                    {
                        try
                        {
                            using (var process = new Process())
                            {
                                // add certificate
                                var start             = process.StartInfo;
                                start.Verb            = "runas";
                                start.UseShellExecute = true;
                                start.FileName        = "cmd";
                                start.Arguments       = $"/c \"\"{CertificateInstallerLocator.FileName}\" /f:\"{txtFile.Text}\" /p:{txtPassword.Text} /n:\"{Item.FriendlyName}\" /s:{(cbStore.SelectedIndex == 0 ? "MY" : "WebHosting")}\"";
                                start.CreateNoWindow  = true;
                                start.WindowStyle     = ProcessWindowStyle.Hidden;
                                process.Start();
                                process.WaitForExit();
                                if (process.ExitCode == 0)
                                {
                                    DialogResult = DialogResult.OK;
                                }
                                else
                                {
                                    MessageBox.Show(process.ExitCode.ToString());
                                }
                            }
                        }
                        catch (Win32Exception ex)
                        {
                            // elevation is cancelled.
                            if (ex.NativeErrorCode != NativeMethods.ErrorCancelled)
                            {
                                RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                                    { "native", ex.NativeErrorCode }
                                });
                                // throw;
                            }
                        }
                        catch (Exception ex)
                        {
                            RollbarLocator.RollbarInstance.Error(ex);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ShowError(ex, string.Empty, false);
                }
            }));

            container.Add(
                Observable.FromEventPattern <CancelEventArgs>(this, "HelpButtonClicked")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(EnvironmentVariableTarget =>
            {
                feature.ShowHelp();
            }));
        }
예제 #4
0
        public CompleteRequestDialog(IServiceProvider serviceProvider, CertificatesFeature feature)
            : base(serviceProvider)
        {
            InitializeComponent();
            cbStore.SelectedIndex = 0;
            if (Environment.OSVersion.Version < Version.Parse("6.2"))
            {
                // IMPORTANT: WebHosting store is available since Windows 8.
                cbStore.Enabled = false;
            }

            if (!Helper.IsRunningOnMono())
            {
                NativeMethods.TryAddShieldToButton(btnOK);
            }

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(txtName, "TextChanged")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                btnOK.Enabled = !string.IsNullOrWhiteSpace(txtName.Text) &&
                                !string.IsNullOrWhiteSpace(txtPath.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                if (!File.Exists(txtPath.Text))
                {
                    ShowMessage(
                        string.Format(
                            "There was an error while performing this operation.{0}{0}Details:{0}{0}Could not find file '{1}'.",
                            Environment.NewLine,
                            txtPath.Text),
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error,
                        MessageBoxDefaultButton.Button1);
                    return;
                }

                var p12File = DialogHelper.GetTempFileName();
                var p12pwd  = "test";
                try
                {
                    // TODO: check administrator permission.
                    var x509     = new X509Certificate2(txtPath.Text);
                    var filename = DialogHelper.GetPrivateKeyFile(x509.Subject);
                    if (!File.Exists(filename))
                    {
                        ShowMessage(
                            string.Format(
                                "There was an error while performing this operation.{0}{0}Details:{0}{0}Could not find private key for '{1}'.",
                                Environment.NewLine,
                                txtPath.Text),
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error,
                            MessageBoxDefaultButton.Button1);
                        return;
                    }

                    x509.PrivateKey   = PrivateKey.CreateFromFile(filename).RSA;
                    x509.FriendlyName = txtName.Text;
                    var raw           = x509.Export(X509ContentType.Pfx, p12pwd);
                    File.WriteAllBytes(p12File, raw);
                    Item = x509;
                }
                catch (Exception ex)
                {
                    ShowError(ex, string.Empty, false);
                    return;
                }

                Store = cbStore.SelectedIndex == 0 ? "Personal" : "WebHosting";

                try
                {
                    // add certificate
                    using (var process = new Process())
                    {
                        var start       = process.StartInfo;
                        start.Verb      = "runas";
                        start.FileName  = "cmd";
                        start.Arguments = string.Format("/c \"\"{4}\" /f:\"{0}\" /p:{1} /n:\"{2}\" /s:{3}\"",
                                                        p12File,
                                                        p12pwd,
                                                        txtName.Text,
                                                        cbStore.SelectedIndex == 0 ? "MY" : "WebHosting",
                                                        Path.Combine(Environment.CurrentDirectory, "certificateinstaller.exe"));
                        start.CreateNoWindow = true;
                        start.WindowStyle    = ProcessWindowStyle.Hidden;
                        process.Start();
                        process.WaitForExit();
                        File.Delete(p12File);
                        if (process.ExitCode == 0)
                        {
                            DialogResult = DialogResult.OK;
                        }
                        else
                        {
                            MessageBox.Show(process.ExitCode.ToString());
                        }
                    }
                }
                catch (Win32Exception ex)
                {
                    // elevation is cancelled.
                    if (ex.NativeErrorCode != Microsoft.Web.Administration.NativeMethods.ErrorCancelled)
                    {
                        RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                            { "native", ex.NativeErrorCode }
                        });
                        // throw;
                    }
                }
                catch (Exception ex)
                {
                    RollbarLocator.RollbarInstance.Error(ex);
                }
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnBrowse, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                DialogHelper.ShowOpenFileDialog(txtPath, "*.cer|*.cer|*.*|*.*");
            }));

            container.Add(
                Observable.FromEventPattern <CancelEventArgs>(this, "HelpButtonClicked")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(EnvironmentVariableTarget =>
            {
                feature.ShowHelp();
            }));
        }
 protected override bool ShowHelp()
 {
     _feature.ShowHelp();
     return(true);
 }
예제 #6
0
        public SelfCertificateDialog(IServiceProvider serviceProvider, CertificatesFeature feature)
            : base(serviceProvider)
        {
            InitializeComponent();
            cbStore.SelectedIndex   = 0;
            cbLength.SelectedIndex  = 3;
            cbHashing.SelectedIndex = 1;
            txtCommonName.Text      = Environment.MachineName;
            dtpFrom.Value           = DateTime.Now;
            dtpTo.Value             = dtpFrom.Value.AddYears(1);

            if (Environment.OSVersion.Version < Version.Parse("6.2"))
            {
                // IMPORTANT: WebHosting store is available since Windows 8.
                cbStore.Enabled = false;
            }

            if (!Helper.IsRunningOnMono())
            {
                NativeMethods.TryAddShieldToButton(btnOK);
            }

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(txtName, "TextChanged")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                btnOK.Enabled = !string.IsNullOrWhiteSpace(txtName.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                var names = txtCommonName.Text;
                if (string.IsNullOrWhiteSpace(names))
                {
                    ShowMessage("DNS names cannot be empty.", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    return;
                }

                var dnsNames = names.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(item => item.Trim()).ToArray();
                if (dnsNames.Length == 0)
                {
                    ShowMessage("DNS names cannot be empty.", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    return;
                }

                // Generate certificate
                string defaultIssuer  = string.Format("CN={0}", dnsNames[0]);
                string defaultSubject = defaultIssuer;

                string subject = defaultSubject;
                string issuer  = defaultIssuer;

                if (subject == null)
                {
                    throw new Exception("Missing Subject Name");
                }

                DateTime notBefore = dtpFrom.Value;
                DateTime notAfter  = dtpTo.Value;

                var random = new SecureRandom(new CryptoApiRandomGenerator());
                var kpgen  = new RsaKeyPairGenerator();
                kpgen.Init(new KeyGenerationParameters(random, int.Parse(cbLength.Text)));
                var cerKp = kpgen.GenerateKeyPair();

                X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

                var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);
                certGen.SetSerialNumber(serialNumber);
                certGen.SetIssuerDN(new X509Name(issuer));
                certGen.SetNotBefore(notBefore);
                certGen.SetNotAfter(notAfter);
                if (dnsNames.Length == 1)
                {
                    certGen.SetSubjectDN(new X509Name(subject));
                }

                certGen.SetPublicKey(cerKp.Public);
                certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));

                var keyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(cerKp.Public);
                certGen.AddExtension(X509Extensions.SubjectKeyIdentifier, true, new SubjectKeyIdentifier(keyInfo));
                certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, true, new AuthorityKeyIdentifier(keyInfo));
                certGen.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));

                if (cbGenerate.Checked)
                {
                    var subjectAlternativeNames = new List <Asn1Encodable>();
                    foreach (var item in dnsNames)
                    {
                        subjectAlternativeNames.Add(new GeneralName(GeneralName.DnsName, item));
                    }
                    var subjectAlternativeNamesExtension = new DerSequence(subjectAlternativeNames.ToArray());
                    certGen.AddExtension(X509Extensions.SubjectAlternativeName, true, subjectAlternativeNamesExtension);
                }

                string hashName = cbHashing.SelectedIndex == 0 ? "SHA1WithRSA" : "SHA256WithRSA";
                var factory     = new Asn1SignatureFactory(hashName, cerKp.Private, random);

                string p12File = Path.GetTempFileName();
                string p12pwd  = "test";

                try
                {
                    Org.BouncyCastle.X509.X509Certificate x509 = certGen.Generate(factory);
                    var store            = new Pkcs12Store();
                    var certificateEntry = new X509CertificateEntry(x509);
                    var friendlyName     = txtName.Text;
                    store.SetCertificateEntry(friendlyName, certificateEntry);
                    store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(cerKp.Private), new[] { certificateEntry });
                    var stream = new MemoryStream();
                    store.Save(stream, p12pwd.ToCharArray(), random);
                    File.WriteAllBytes(p12File, stream.ToArray());

                    Item = new X509Certificate2(p12File, p12pwd)
                    {
                        FriendlyName = friendlyName
                    };
                    Store = cbStore.SelectedIndex == 0 ? "Personal" : "WebHosting";

                    try
                    {
                        using (var process = new Process())
                        {
                            // add certificate
                            var start             = process.StartInfo;
                            start.Verb            = "runas";
                            start.UseShellExecute = true;
                            start.FileName        = "cmd";
                            start.Arguments       = $"/c \"\"{CertificateInstallerLocator.FileName}\" /f:\"{p12File}\" /p:{p12pwd} /n:\"{txtName.Text}\" /s:{(cbStore.SelectedIndex == 0 ? "MY" : "WebHosting")}\"";
                            start.CreateNoWindow  = true;
                            start.WindowStyle     = ProcessWindowStyle.Hidden;
                            process.Start();
                            process.WaitForExit();
                            File.Delete(p12File);
                            if (process.ExitCode == 0)
                            {
                                DialogResult = DialogResult.OK;
                            }
                            else
                            {
                                ShowMessage(process.ExitCode.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                            }
                        }
                    }
                    catch (Win32Exception ex)
                    {
                        // elevation is cancelled.
                        if (ex.NativeErrorCode != Microsoft.Web.Administration.NativeMethods.ErrorCancelled)
                        {
                            RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                                { "native", ex.NativeErrorCode }
                            });
                            // throw;
                        }
                    }
                    catch (Exception ex)
                    {
                        RollbarLocator.RollbarInstance.Error(ex);
                    }
                }
                catch (Exception ex)
                {
                    RollbarLocator.RollbarInstance.Error(ex);
                    ShowError(ex, "Certificate generation error", false);
                    return;
                }
            }));

            container.Add(
                Observable.FromEventPattern <CancelEventArgs>(this, "HelpButtonClicked")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(EnvironmentVariableTarget =>
            {
                feature.ShowHelp();
            }));
        }