//  
//   Rebex Sample Code License
// 
//   Copyright 2025, REBEX CR s.r.o.
//   All rights reserved.
//   https://www.rebex.net/
// 
//   Permission to use, copy, modify, and/or distribute this software for any
//   purpose with or without fee is hereby granted.
// 
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
//   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
//   OTHER DEALINGS IN THE SOFTWARE.
// 

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Data;
using Rebex.Net;

namespace Rebex.Samples
{
    public class MainForm : System.Windows.Forms.Form
    {
        /// <summary>
        /// Contains definition of supported algorithms
        /// </summary>
        private class SupportedAlgorithm
        {
            public SupportedAlgorithm(SshHostKeyAlgorithm alg, string radioText, int[] keySizes, int defaultIndex)
                : this(new SshHostKeyAlgorithm[] {alg}, radioText, keySizes, defaultIndex)
            {
            }

            public SupportedAlgorithm(SshHostKeyAlgorithm[] alg, string radioText, int[] keySizes, int defaultIndex)
            {
                if (alg.Length > 1 && alg.Length != keySizes.Length)
                    throw new ArgumentException();

                Algorithms = alg;
                DefaultIndex = defaultIndex;
                RadioText = radioText;
                KeySizes = keySizes;
            }

            public readonly SshHostKeyAlgorithm[] Algorithms;
            public readonly int DefaultIndex;
            public readonly int[] KeySizes;
            public readonly string RadioText;

            public System.Data.DataTable KeySizesTable()
            {
                DataTable table = new DataTable();
                table.Columns.Add("value", typeof(int));
                table.Columns.Add("display", typeof(string));
                foreach (int keySize in KeySizes)
                {
                    DataRow row = table.NewRow();
                    row["value"] = keySize;
                    row["display"] = keySize.ToString();
                    table.Rows.Add(row);
                }
                return table;
            }

            public SshHostKeyAlgorithm AlgorithmForKeySize(int keySize)
            {
                return Algorithms[Math.Min(Algorithms.Length - 1, Array.IndexOf(KeySizes, keySize))];
            }
        }

        private readonly Dictionary<SshHostKeyAlgorithm, RadioButton> _algToRb;
        private readonly Dictionary<RadioButton, SupportedAlgorithm> _rbToAlg;

        private readonly SupportedAlgorithm[] _supportedAlgorithms = new SupportedAlgorithm[]
        {
            new SupportedAlgorithm(SshHostKeyAlgorithm.RSA, "RSA", new int[] {1024, 2048, 4096}, 1),
            new SupportedAlgorithm(SshHostKeyAlgorithm.DSS, "DSA", new int[] {1024}, 0),
            new SupportedAlgorithm(SshHostKeyAlgorithm.ED25519, "ED25519", new int[] {256}, 0),
            new SupportedAlgorithm(new SshHostKeyAlgorithm[] { SshHostKeyAlgorithm.ECDsaNistP256, SshHostKeyAlgorithm.ECDsaNistP384, SshHostKeyAlgorithm.ECDsaNistP521 }, 
                "ECDSA", new int[] { 256, 384, 521 }, 0), 
        };
        
        private SshPrivateKey _privateKey;

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.RadioButton rbRSA;
        private System.Windows.Forms.RadioButton rbDSA;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.ComboBox cbBits;
        private System.Windows.Forms.GroupBox groupBox2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.Button btnQuit;
        private System.Windows.Forms.Button btnAbout;
        private System.Windows.Forms.Button btnGenerate;
        private System.Windows.Forms.Button btnSavePrivKey;
        private System.Windows.Forms.Button btnSavePubKey;
        private System.Windows.Forms.Button btnLoad;
        private System.Windows.Forms.TextBox tbOpenSsh;
        private System.Windows.Forms.SaveFileDialog saveFileDialog;
        private System.Windows.Forms.TextBox tbPassphrase;
        private System.Windows.Forms.TextBox tbConfirmPassphrase;
        private System.Windows.Forms.OpenFileDialog openFileDialog;
        private System.Windows.Forms.Label label7;
        private System.Windows.Forms.TextBox tbFingerprint2;
        private RadioButton rbED25519;
        private RadioButton rbECDSA;
        private System.Windows.Forms.TextBox tbFingerprint;

        public MainForm()
        {
            // Required for Windows Form Designer support
            InitializeComponent();

            CheckForIllegalCrossThreadCalls = true;
            
            // bind cbBits
            cbBits.DataSource = _supportedAlgorithms[0].KeySizesTable();
            cbBits.ValueMember = "value";
            cbBits.DisplayMember = "display";
            cbBits.SelectedIndex = 1;

            _rbToAlg = new Dictionary<RadioButton, SupportedAlgorithm>();
            _algToRb = new Dictionary<SshHostKeyAlgorithm, RadioButton>();

            // populate mapping dictionaries above
            foreach (Control ctrl in groupBox1.Controls)
            {
                RadioButton rb = ctrl as RadioButton;
                if (rb == null) continue;
                foreach (SupportedAlgorithm suppAlg in _supportedAlgorithms)
                {
                    if (suppAlg.RadioText == rb.Text)
                    {
                        _rbToAlg[rb] = suppAlg;
                        foreach (SshHostKeyAlgorithm alg in suppAlg.Algorithms)
                        {
                            _algToRb[alg] = rb;
                        }
                    }
                }
            }
        }

        public static string GetAlgorithmId(SshHostKeyAlgorithm algorithm)
        {
            switch (algorithm)
            {
                case SshHostKeyAlgorithm.RSA:
                    return "ssh-rsa";
                case SshHostKeyAlgorithm.DSS:
                    return "ssh-dss";
                case SshHostKeyAlgorithm.ED25519:
                    return "ssh-ed25519";
                case SshHostKeyAlgorithm.ECDsaNistP256:
                    return "ecdsa-sha2-nistp256";
                case SshHostKeyAlgorithm.ECDsaNistP384:
                    return "ecdsa-sha2-nistp384";
                case SshHostKeyAlgorithm.ECDsaNistP521:
                    return "ecdsa-sha2-nistp521";
                default:
                    return null;
            }
        }

        private SupportedAlgorithm SelectedAlgorithm
        {
            get
            {
                foreach (Control ctrl in groupBox1.Controls)
                {
                    RadioButton rb = ctrl as RadioButton;
                    if (rb == null || rb.Checked == false) continue;
                    return _rbToAlg[rb];
                }

                throw new InvalidOperationException();
            }
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.rbECDSA = new System.Windows.Forms.RadioButton();
            this.rbED25519 = new System.Windows.Forms.RadioButton();
            this.btnGenerate = new System.Windows.Forms.Button();
            this.cbBits = new System.Windows.Forms.ComboBox();
            this.label2 = new System.Windows.Forms.Label();
            this.rbDSA = new System.Windows.Forms.RadioButton();
            this.rbRSA = new System.Windows.Forms.RadioButton();
            this.label1 = new System.Windows.Forms.Label();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.tbFingerprint2 = new System.Windows.Forms.TextBox();
            this.label7 = new System.Windows.Forms.Label();
            this.btnLoad = new System.Windows.Forms.Button();
            this.btnSavePrivKey = new System.Windows.Forms.Button();
            this.btnSavePubKey = new System.Windows.Forms.Button();
            this.tbFingerprint = new System.Windows.Forms.TextBox();
            this.label4 = new System.Windows.Forms.Label();
            this.tbOpenSsh = new System.Windows.Forms.TextBox();
            this.label3 = new System.Windows.Forms.Label();
            this.label5 = new System.Windows.Forms.Label();
            this.label6 = new System.Windows.Forms.Label();
            this.tbPassphrase = new System.Windows.Forms.TextBox();
            this.tbConfirmPassphrase = new System.Windows.Forms.TextBox();
            this.btnQuit = new System.Windows.Forms.Button();
            this.btnAbout = new System.Windows.Forms.Button();
            this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
            this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
            this.groupBox1.SuspendLayout();
            this.groupBox2.SuspendLayout();
            this.SuspendLayout();
            // 
            // groupBox1
            // 
            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBox1.Controls.Add(this.rbECDSA);
            this.groupBox1.Controls.Add(this.rbED25519);
            this.groupBox1.Controls.Add(this.btnGenerate);
            this.groupBox1.Controls.Add(this.cbBits);
            this.groupBox1.Controls.Add(this.label2);
            this.groupBox1.Controls.Add(this.rbDSA);
            this.groupBox1.Controls.Add(this.rbRSA);
            this.groupBox1.Controls.Add(this.label1);
            this.groupBox1.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.groupBox1.Location = new System.Drawing.Point(8, 8);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(412, 72);
            this.groupBox1.TabIndex = 0;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Options";
            // 
            // rbECDSA
            // 
            this.rbECDSA.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.rbECDSA.Location = new System.Drawing.Point(336, 16);
            this.rbECDSA.Name = "rbECDSA";
            this.rbECDSA.Size = new System.Drawing.Size(64, 24);
            this.rbECDSA.TabIndex = 7;
            this.rbECDSA.Text = "ECDSA";
            // 
            // rbED25519
            // 
            this.rbED25519.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.rbED25519.Location = new System.Drawing.Point(253, 16);
            this.rbED25519.Name = "rbED25519";
            this.rbED25519.Size = new System.Drawing.Size(64, 24);
            this.rbED25519.TabIndex = 6;
            this.rbED25519.Text = "ED25519";
            this.rbED25519.CheckedChanged += new System.EventHandler(this.AlgoRbCheckedChanged);
            // 
            // btnGenerate
            // 
            this.btnGenerate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.btnGenerate.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.btnGenerate.Location = new System.Drawing.Point(328, 40);
            this.btnGenerate.Name = "btnGenerate";
            this.btnGenerate.Size = new System.Drawing.Size(75, 23);
            this.btnGenerate.TabIndex = 5;
            this.btnGenerate.Text = "&Generate";
            this.btnGenerate.Click += new System.EventHandler(this.btnGenerate_Click);
            // 
            // cbBits
            // 
            this.cbBits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.cbBits.Items.AddRange(new object[] {
            "1024",
            "2048",
            "4096"});
            this.cbBits.Location = new System.Drawing.Point(136, 40);
            this.cbBits.Name = "cbBits";
            this.cbBits.Size = new System.Drawing.Size(96, 21);
            this.cbBits.TabIndex = 4;
            // 
            // label2
            // 
            this.label2.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.label2.Location = new System.Drawing.Point(8, 44);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(120, 23);
            this.label2.TabIndex = 3;
            this.label2.Text = "Key size / curve:";
            this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            // 
            // rbDSA
            // 
            this.rbDSA.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.rbDSA.Location = new System.Drawing.Point(195, 16);
            this.rbDSA.Name = "rbDSA";
            this.rbDSA.Size = new System.Drawing.Size(64, 24);
            this.rbDSA.TabIndex = 2;
            this.rbDSA.Text = "DSA";
            this.rbDSA.CheckedChanged += new System.EventHandler(this.AlgoRbCheckedChanged);
            // 
            // rbRSA
            // 
            this.rbRSA.Checked = true;
            this.rbRSA.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.rbRSA.Location = new System.Drawing.Point(136, 16);
            this.rbRSA.Name = "rbRSA";
            this.rbRSA.Size = new System.Drawing.Size(64, 24);
            this.rbRSA.TabIndex = 1;
            this.rbRSA.TabStop = true;
            this.rbRSA.Text = "RSA";
            this.rbRSA.CheckedChanged += new System.EventHandler(this.AlgoRbCheckedChanged);
            // 
            // label1
            // 
            this.label1.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.label1.Location = new System.Drawing.Point(8, 18);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(120, 23);
            this.label1.TabIndex = 0;
            this.label1.Text = "Key algorithm:";
            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            // 
            // groupBox2
            // 
            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBox2.Controls.Add(this.tbFingerprint2);
            this.groupBox2.Controls.Add(this.label7);
            this.groupBox2.Controls.Add(this.btnLoad);
            this.groupBox2.Controls.Add(this.btnSavePrivKey);
            this.groupBox2.Controls.Add(this.btnSavePubKey);
            this.groupBox2.Controls.Add(this.tbFingerprint);
            this.groupBox2.Controls.Add(this.label4);
            this.groupBox2.Controls.Add(this.tbOpenSsh);
            this.groupBox2.Controls.Add(this.label3);
            this.groupBox2.Controls.Add(this.label5);
            this.groupBox2.Controls.Add(this.label6);
            this.groupBox2.Controls.Add(this.tbPassphrase);
            this.groupBox2.Controls.Add(this.tbConfirmPassphrase);
            this.groupBox2.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.groupBox2.Location = new System.Drawing.Point(8, 88);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(412, 264);
            this.groupBox2.TabIndex = 1;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "Key";
            // 
            // tbFingerprint2
            // 
            this.tbFingerprint2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.tbFingerprint2.Location = new System.Drawing.Point(120, 160);
            this.tbFingerprint2.Name = "tbFingerprint2";
            this.tbFingerprint2.ReadOnly = true;
            this.tbFingerprint2.Size = new System.Drawing.Size(284, 20);
            this.tbFingerprint2.TabIndex = 12;
            // 
            // label7
            // 
            this.label7.Location = new System.Drawing.Point(8, 160);
            this.label7.Name = "label7";
            this.label7.Size = new System.Drawing.Size(112, 23);
            this.label7.TabIndex = 11;
            this.label7.Text = "SHA-256 Fingerprint:";
            // 
            // btnLoad
            // 
            this.btnLoad.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.btnLoad.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.btnLoad.Location = new System.Drawing.Point(8, 232);
            this.btnLoad.Name = "btnLoad";
            this.btnLoad.Size = new System.Drawing.Size(75, 23);
            this.btnLoad.TabIndex = 8;
            this.btnLoad.Text = "&Load...";
            this.btnLoad.Click += new System.EventHandler(this.btnLoad_Click);
            // 
            // btnSavePrivKey
            // 
            this.btnSavePrivKey.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.btnSavePrivKey.Enabled = false;
            this.btnSavePrivKey.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.btnSavePrivKey.Location = new System.Drawing.Point(288, 232);
            this.btnSavePrivKey.Name = "btnSavePrivKey";
            this.btnSavePrivKey.Size = new System.Drawing.Size(115, 23);
            this.btnSavePrivKey.TabIndex = 10;
            this.btnSavePrivKey.Text = "&Save private key...";
            this.btnSavePrivKey.Click += new System.EventHandler(this.btnSavePrivKey_Click);
            // 
            // btnSavePubKey
            // 
            this.btnSavePubKey.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.btnSavePubKey.Enabled = false;
            this.btnSavePubKey.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.btnSavePubKey.Location = new System.Drawing.Point(168, 232);
            this.btnSavePubKey.Name = "btnSavePubKey";
            this.btnSavePubKey.Size = new System.Drawing.Size(115, 23);
            this.btnSavePubKey.TabIndex = 9;
            this.btnSavePubKey.Text = "&Save public key...";
            this.btnSavePubKey.Click += new System.EventHandler(this.btnSavePubKey_Click);
            // 
            // tbFingerprint
            // 
            this.tbFingerprint.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.tbFingerprint.Location = new System.Drawing.Point(120, 136);
            this.tbFingerprint.Name = "tbFingerprint";
            this.tbFingerprint.ReadOnly = true;
            this.tbFingerprint.Size = new System.Drawing.Size(284, 20);
            this.tbFingerprint.TabIndex = 3;
            // 
            // label4
            // 
            this.label4.Location = new System.Drawing.Point(8, 136);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(112, 23);
            this.label4.TabIndex = 2;
            this.label4.Text = "MD5 Fingerprint:";
            // 
            // tbOpenSsh
            // 
            this.tbOpenSsh.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.tbOpenSsh.Location = new System.Drawing.Point(8, 40);
            this.tbOpenSsh.Multiline = true;
            this.tbOpenSsh.Name = "tbOpenSsh";
            this.tbOpenSsh.ReadOnly = true;
            this.tbOpenSsh.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.tbOpenSsh.Size = new System.Drawing.Size(396, 88);
            this.tbOpenSsh.TabIndex = 1;
            // 
            // label3
            // 
            this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.label3.Location = new System.Drawing.Point(8, 16);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(396, 23);
            this.label3.TabIndex = 0;
            this.label3.Text = "You can add this into OpenSSH\'s authorized_keys file:";
            // 
            // label5
            // 
            this.label5.Location = new System.Drawing.Point(8, 184);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(112, 23);
            this.label5.TabIndex = 4;
            this.label5.Text = "Passphrase:";
            // 
            // label6
            // 
            this.label6.Location = new System.Drawing.Point(8, 208);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(112, 23);
            this.label6.TabIndex = 6;
            this.label6.Text = "Confirm passphrase:";
            // 
            // tbPassphrase
            // 
            this.tbPassphrase.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.tbPassphrase.Location = new System.Drawing.Point(120, 184);
            this.tbPassphrase.Name = "tbPassphrase";
            this.tbPassphrase.PasswordChar = '*';
            this.tbPassphrase.Size = new System.Drawing.Size(284, 20);
            this.tbPassphrase.TabIndex = 5;
            // 
            // tbConfirmPassphrase
            // 
            this.tbConfirmPassphrase.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.tbConfirmPassphrase.Location = new System.Drawing.Point(120, 208);
            this.tbConfirmPassphrase.Name = "tbConfirmPassphrase";
            this.tbConfirmPassphrase.PasswordChar = '*';
            this.tbConfirmPassphrase.Size = new System.Drawing.Size(284, 20);
            this.tbConfirmPassphrase.TabIndex = 7;
            // 
            // btnQuit
            // 
            this.btnQuit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.btnQuit.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.btnQuit.Location = new System.Drawing.Point(344, 360);
            this.btnQuit.Name = "btnQuit";
            this.btnQuit.Size = new System.Drawing.Size(75, 23);
            this.btnQuit.TabIndex = 3;
            this.btnQuit.Text = "&Quit";
            this.btnQuit.Click += new System.EventHandler(this.btnQuit_Click);
            // 
            // btnAbout
            // 
            this.btnAbout.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.btnAbout.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.btnAbout.Location = new System.Drawing.Point(8, 360);
            this.btnAbout.Name = "btnAbout";
            this.btnAbout.Size = new System.Drawing.Size(75, 23);
            this.btnAbout.TabIndex = 2;
            this.btnAbout.Text = "About...";
            this.btnAbout.Click += new System.EventHandler(this.btnAbout_Click);
            // 
            // openFileDialog
            // 
            this.openFileDialog.Filter = "Privacy Enhanced Mail Certificate (*.pem)|*.pem";
            // 
            // MainForm
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(426, 392);
            this.Controls.Add(this.btnAbout);
            this.Controls.Add(this.btnQuit);
            this.Controls.Add(this.groupBox2);
            this.Controls.Add(this.groupBox1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.Name = "MainForm";
            this.Text = "Rebex SSH Key Generator";
            this.groupBox1.ResumeLayout(false);
            this.groupBox2.ResumeLayout(false);
            this.groupBox2.PerformLayout();
            this.ResumeLayout(false);

        }
        #endregion

        private void btnQuit_Click(object sender, System.EventArgs e)
        {
            Close();
        }

        private void AlgoRbCheckedChanged(object sender, EventArgs e)
        {
            SupportedAlgorithm salg = SelectedAlgorithm;
            cbBits.DataSource = salg.KeySizesTable();
            cbBits.SelectedIndex = salg.DefaultIndex;
        }

        private void btnAbout_Click(object sender, System.EventArgs e)
        {
            AboutForm about = new AboutForm();
            about.ShowDialog();
        }

        private void btnGenerate_Click(object sender, System.EventArgs e)
        {
            try
            {
                Cursor.Current = Cursors.WaitCursor;

                SupportedAlgorithm selected = SelectedAlgorithm;
                int keySize = (int)cbBits.SelectedValue;
                
                SshHostKeyAlgorithm algorithm = selected.AlgorithmForKeySize(keySize);
                
                // generate private key
                _privateKey = SshPrivateKey.Generate(algorithm, keySize);

                // fingerprints
                tbFingerprint.Text = _privateKey.Fingerprint.ToString(Rebex.Security.Certificates.SignatureHashAlgorithm.MD5);
                tbFingerprint2.Text = _privateKey.Fingerprint.ToString(Rebex.Security.Certificates.SignatureHashAlgorithm.SHA256, true);

                ConstructOpenSshString(GetAlgorithmId(algorithm));

                btnSavePrivKey.Enabled = true;
                btnSavePubKey.Enabled = true;
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void ConstructOpenSshString(string publicKeyAlgorithm)
        {
            // construct the OpenSSH-style public key string 

            // get the raw form of SSH public key 
            byte[] rawPublicKey = _privateKey.GetPublicKey();

            // the string to be added to OpenSSH's ~/.ssh/authorized_keys file 
            string sshPublicKey = string.Format("{0} {1} username@hostname",
                publicKeyAlgorithm,
                Convert.ToBase64String(rawPublicKey));

            // and display it 
            tbOpenSsh.Text = sshPublicKey;
        }

        private void btnSavePrivKey_Click(object sender, System.EventArgs e)
        {
            if (tbPassphrase.Text != tbConfirmPassphrase.Text)
            {
                MessageBox.Show("Given passphrases do not match.", "Passphrases", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            string password;
            if (tbPassphrase.Text == "")
            {
                if (MessageBox.Show(
                    "Are you sure you want to save this key without a passphrase?",
                    "Passphrase",
                    MessageBoxButtons.YesNoCancel,
                    MessageBoxIcon.Warning) != DialogResult.Yes)
                {
                    return;
                }

                password = null;
            }
            else
            {
                password = tbPassphrase.Text;
            }

            saveFileDialog.FileName = "";
            saveFileDialog.DefaultExt = "pri";
            saveFileDialog.Filter = "PKCS #8 Private Key (*.pri)|*.pri|PuTTY Private Key (*.ppk)|*.ppk|OpenSSH Private Key (*.pri)|*.pri|New OpenSSH Private Key (*.pri)|*.pri";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                // get private key format
                SshPrivateKeyFormat format;
                switch (saveFileDialog.FilterIndex)
                {
                    case 1: format = SshPrivateKeyFormat.Pkcs8; break;
                    case 2: format = SshPrivateKeyFormat.Putty; break;
                    case 3: format = SshPrivateKeyFormat.OpenSsh; break;
                    case 4: format = SshPrivateKeyFormat.NewOpenSsh; break;
                    default: format = SshPrivateKeyFormat.Pkcs8; break;
                }

                // save the private key				
                _privateKey.Save(saveFileDialog.FileName, password, format);

                MessageBox.Show("The private key was successfuly saved.", "Private key", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void btnSavePubKey_Click(object sender, System.EventArgs e)
        {
            saveFileDialog.FileName = "";
            saveFileDialog.Filter = "Public Key (*.pub)|*.pub";
            saveFileDialog.DefaultExt = "pub";

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                // save the public key 
                _privateKey.SavePublicKey(saveFileDialog.FileName);
                MessageBox.Show("The public key was successfuly saved.", "Public key", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void btnLoad_Click(object sender, System.EventArgs e)
        {
            openFileDialog.FileName = "";
            openFileDialog.Filter = "Private Key Files (*.pri,*.ppk)|*.pri;*.ppk|All Files (*.*)|*.*";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    PassphraseDialog pp = new PassphraseDialog();
                    if (pp.ShowDialog() == DialogResult.OK)
                    {
                        _privateKey = new SshPrivateKey(openFileDialog.FileName, pp.Passphrase);
                        _algToRb[_privateKey.KeyAlgorithm].Checked = true;
                        
                        tbFingerprint.Text = _privateKey.Fingerprint.ToString();
                        
                        ConstructOpenSshString(GetAlgorithmId(_privateKey.KeyAlgorithm));

                        tbPassphrase.Text = "";
                        tbConfirmPassphrase.Text = "";

                        btnSavePrivKey.Enabled = true;
                        btnSavePubKey.Enabled = true;
                    }
                    else
                    {
                        MessageBox.Show(string.Format("Loading of file '{0}' was canceled.", openFileDialog.FileName), "Loading canceled", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(string.Format("Unable to load the key.\n{0}", ex.Message), "Loading failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                MessageBox.Show("Key was successfuly loaded.", "Loading successful", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}
