'  
'   Rebex Sample Code License
' 
'   Copyright 2026, 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.
' 

Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Data
Imports System.IO
Imports Rebex.Net
Imports System.Collections.Generic

'' <summary>
'' Summary description for Form1.
'' </summary>
Public Class MainForm
    Inherits System.Windows.Forms.Form

    Private Class SupportedAlgorithm
        Public Sub New(ByVal alg As SshHostKeyAlgorithm, ByVal radioText As String, ByVal keySizes As Integer(), ByVal defaultIndex As Integer)
            Me.New(New SshHostKeyAlgorithm() {alg}, radioText, keySizes, defaultIndex)
        End Sub

        Public Sub New(ByVal alg As SshHostKeyAlgorithm(), ByVal radioText As String, ByVal keySizes As Integer(), ByVal defaultIndex As Integer)
            If (alg.Length > 1 AndAlso alg.Length <> keySizes.Length) Then
                Throw New ArgumentException()
            End If

            Algorithms = alg
            Me.DefaultIndex = defaultIndex
            Me.RadioText = radioText
            Me.KeySizes = keySizes
        End Sub

        Public ReadOnly Algorithms As SshHostKeyAlgorithm()
        Public ReadOnly DefaultIndex As Integer
        Public ReadOnly KeySizes As Integer()
        Public ReadOnly RadioText As String

        Public Function KeySizesTable() As System.Data.DataTable
            Dim table As DataTable = New DataTable()
            table.Columns.Add("value", GetType(Integer))
            table.Columns.Add("display", GetType(String))

            For Each keySize As Integer In KeySizes
                Dim row As DataRow = table.NewRow()
                row("value") = keySize
                row("display") = keySize.ToString()
                table.Rows.Add(row)
            Next
            Return table
        End Function

        Public Function AlgorithmForKeySize(ByVal keySize As Integer) As SshHostKeyAlgorithm
            Return Algorithms(Math.Min(Algorithms.Length - 1, Array.IndexOf(KeySizes, keySize)))
        End Function

    End Class

    Private _initialized As Boolean

    Private ReadOnly _algToRb As Dictionary(Of SshHostKeyAlgorithm, RadioButton)
    Private ReadOnly _rbToAlg As Dictionary(Of RadioButton, SupportedAlgorithm)
    Private _privateKey As SshPrivateKey

    Private ReadOnly _supportedAlgorithms As SupportedAlgorithm() = New SupportedAlgorithm() _
        {
            New SupportedAlgorithm(SshHostKeyAlgorithm.RSA, "RSA", New Integer() {1024, 2048, 4096}, 1),
            New SupportedAlgorithm(SshHostKeyAlgorithm.DSS, "DSA", New Integer() {1024}, 0),
            New SupportedAlgorithm(SshHostKeyAlgorithm.ED25519, "ED25519", New Integer() {256}, 0),
            New SupportedAlgorithm(New SshHostKeyAlgorithm() {SshHostKeyAlgorithm.ECDsaNistP256, SshHostKeyAlgorithm.ECDsaNistP384, SshHostKeyAlgorithm.ECDsaNistP521},
                "ECDSA", New Integer() {256, 384, 521}, 0)
        }

    Public Sub New()
        _initialized = False
        ' 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(Of RadioButton, SupportedAlgorithm)()
        _algToRb = New Dictionary(Of SshHostKeyAlgorithm, RadioButton)()

        ' populate mapping dictionaries above
        For Each ctrl As Control In groupBox1.Controls
            Dim rb As RadioButton = TryCast(ctrl, RadioButton)
            If (rb Is Nothing) Then Continue For
            For Each suppAlg As SupportedAlgorithm In _supportedAlgorithms
                If (suppAlg.RadioText = rb.Text) Then
                    _rbToAlg(rb) = suppAlg
                    For Each alg As SshHostKeyAlgorithm In suppAlg.Algorithms
                        _algToRb(alg) = rb
                    Next
                End If
            Next
        Next
        _initialized = True
    End Sub

    Public Shared Function GetAlgorithmId(ByVal algorithm As SshHostKeyAlgorithm) As String
        Select Case (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"
            Case Else
                Return Nothing
        End Select
    End Function

    Private ReadOnly Property SelectedAlgorithm() As SupportedAlgorithm
        Get
            For Each ctrl As Control In groupBox1.Controls
                Dim rb As RadioButton = TryCast(ctrl, RadioButton)
                If (rb Is Nothing OrElse rb.Checked = False) Then Continue For
                Return _rbToAlg(rb)

            Next

            Throw New InvalidOperationException()
        End Get
    End Property

#Region "Windows Form Designer generated code"

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

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

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Private WithEvents tbFingerprint2 As System.Windows.Forms.TextBox
    Private WithEvents Label7 As System.Windows.Forms.Label
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.groupBox1 = New System.Windows.Forms.GroupBox()
        Me.btnGenerate = New System.Windows.Forms.Button()
        Me.cbBits = New System.Windows.Forms.ComboBox()
        Me.label2 = New System.Windows.Forms.Label()
        Me.rbDSA = New System.Windows.Forms.RadioButton()
        Me.rbRSA = New System.Windows.Forms.RadioButton()
        Me.label1 = New System.Windows.Forms.Label()
        Me.groupBox2 = New System.Windows.Forms.GroupBox()
        Me.tbFingerprint2 = New System.Windows.Forms.TextBox()
        Me.Label7 = New System.Windows.Forms.Label()
        Me.btnLoad = New System.Windows.Forms.Button()
        Me.btnSavePrivKey = New System.Windows.Forms.Button()
        Me.btnSavePubKey = New System.Windows.Forms.Button()
        Me.tbFingerprint = New System.Windows.Forms.TextBox()
        Me.label4 = New System.Windows.Forms.Label()
        Me.tbOpenSsh = New System.Windows.Forms.TextBox()
        Me.label3 = New System.Windows.Forms.Label()
        Me.label5 = New System.Windows.Forms.Label()
        Me.label6 = New System.Windows.Forms.Label()
        Me.tbPassphrase = New System.Windows.Forms.TextBox()
        Me.tbConfirmPassphrase = New System.Windows.Forms.TextBox()
        Me.btnQuit = New System.Windows.Forms.Button()
        Me.btnAbout = New System.Windows.Forms.Button()
        Me.saveFileDialog = New System.Windows.Forms.SaveFileDialog()
        Me.openFileDialog = New System.Windows.Forms.OpenFileDialog()
        Me.rbECDSA = New System.Windows.Forms.RadioButton()
        Me.rbED25519 = New System.Windows.Forms.RadioButton()
        Me.groupBox1.SuspendLayout()
        Me.groupBox2.SuspendLayout()
        Me.SuspendLayout()
        '
        'groupBox1
        '
        Me.groupBox1.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
            Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.groupBox1.Controls.Add(Me.rbECDSA)
        Me.groupBox1.Controls.Add(Me.rbED25519)
        Me.groupBox1.Controls.Add(Me.btnGenerate)
        Me.groupBox1.Controls.Add(Me.cbBits)
        Me.groupBox1.Controls.Add(Me.label2)
        Me.groupBox1.Controls.Add(Me.rbDSA)
        Me.groupBox1.Controls.Add(Me.rbRSA)
        Me.groupBox1.Controls.Add(Me.label1)
        Me.groupBox1.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.groupBox1.Location = New System.Drawing.Point(8, 8)
        Me.groupBox1.Name = "groupBox1"
        Me.groupBox1.Size = New System.Drawing.Size(412, 72)
        Me.groupBox1.TabIndex = 0
        Me.groupBox1.TabStop = False
        Me.groupBox1.Text = "Options"
        '
        'btnGenerate
        '
        Me.btnGenerate.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.btnGenerate.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.btnGenerate.Location = New System.Drawing.Point(328, 40)
        Me.btnGenerate.Name = "btnGenerate"
        Me.btnGenerate.Size = New System.Drawing.Size(75, 23)
        Me.btnGenerate.TabIndex = 5
        Me.btnGenerate.Text = "&Generate"
        '
        'cbBits
        '
        Me.cbBits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cbBits.Items.AddRange(New Object() {"1024", "2048", "4096"})
        Me.cbBits.Location = New System.Drawing.Point(136, 40)
        Me.cbBits.Name = "cbBits"
        Me.cbBits.Size = New System.Drawing.Size(96, 21)
        Me.cbBits.TabIndex = 4
        '
        'label2
        '
        Me.label2.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.label2.Location = New System.Drawing.Point(8, 44)
        Me.label2.Name = "label2"
        Me.label2.Size = New System.Drawing.Size(120, 23)
        Me.label2.TabIndex = 3
        Me.label2.Text = "Key size / curve:"
        Me.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight
        '
        'rbDSA
        '
        Me.rbDSA.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.rbDSA.Location = New System.Drawing.Point(195, 16)
        Me.rbDSA.Name = "rbDSA"
        Me.rbDSA.Size = New System.Drawing.Size(64, 24)
        Me.rbDSA.TabIndex = 2
        Me.rbDSA.Text = "DSA"
        '
        'rbRSA
        '
        Me.rbRSA.Checked = True
        Me.rbRSA.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.rbRSA.Location = New System.Drawing.Point(136, 16)
        Me.rbRSA.Name = "rbRSA"
        Me.rbRSA.Size = New System.Drawing.Size(64, 24)
        Me.rbRSA.TabIndex = 1
        Me.rbRSA.TabStop = True
        Me.rbRSA.Text = "RSA"
        '
        'label1
        '
        Me.label1.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.label1.Location = New System.Drawing.Point(8, 18)
        Me.label1.Name = "label1"
        Me.label1.Size = New System.Drawing.Size(120, 23)
        Me.label1.TabIndex = 0
        Me.label1.Text = "Key algorithm:"
        Me.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight
        '
        'groupBox2
        '
        Me.groupBox2.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
            Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.groupBox2.Controls.Add(Me.tbFingerprint2)
        Me.groupBox2.Controls.Add(Me.Label7)
        Me.groupBox2.Controls.Add(Me.btnLoad)
        Me.groupBox2.Controls.Add(Me.btnSavePrivKey)
        Me.groupBox2.Controls.Add(Me.btnSavePubKey)
        Me.groupBox2.Controls.Add(Me.tbFingerprint)
        Me.groupBox2.Controls.Add(Me.label4)
        Me.groupBox2.Controls.Add(Me.tbOpenSsh)
        Me.groupBox2.Controls.Add(Me.label3)
        Me.groupBox2.Controls.Add(Me.label5)
        Me.groupBox2.Controls.Add(Me.label6)
        Me.groupBox2.Controls.Add(Me.tbPassphrase)
        Me.groupBox2.Controls.Add(Me.tbConfirmPassphrase)
        Me.groupBox2.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.groupBox2.Location = New System.Drawing.Point(8, 88)
        Me.groupBox2.Name = "groupBox2"
        Me.groupBox2.Size = New System.Drawing.Size(412, 264)
        Me.groupBox2.TabIndex = 1
        Me.groupBox2.TabStop = False
        Me.groupBox2.Text = "Key"
        '
        'tbFingerprint2
        '
        Me.tbFingerprint2.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
            Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.tbFingerprint2.Location = New System.Drawing.Point(120, 160)
        Me.tbFingerprint2.Name = "tbFingerprint2"
        Me.tbFingerprint2.ReadOnly = True
        Me.tbFingerprint2.Size = New System.Drawing.Size(284, 20)
        Me.tbFingerprint2.TabIndex = 12
        '
        'Label7
        '
        Me.Label7.Location = New System.Drawing.Point(8, 160)
        Me.Label7.Name = "Label7"
        Me.Label7.Size = New System.Drawing.Size(112, 23)
        Me.Label7.TabIndex = 11
        Me.Label7.Text = "SHA-256 Fingerprint:"
        '
        'btnLoad
        '
        Me.btnLoad.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.btnLoad.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.btnLoad.Location = New System.Drawing.Point(8, 232)
        Me.btnLoad.Name = "btnLoad"
        Me.btnLoad.Size = New System.Drawing.Size(75, 23)
        Me.btnLoad.TabIndex = 8
        Me.btnLoad.Text = "&Load..."
        '
        'btnSavePrivKey
        '
        Me.btnSavePrivKey.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.btnSavePrivKey.Enabled = False
        Me.btnSavePrivKey.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.btnSavePrivKey.Location = New System.Drawing.Point(288, 232)
        Me.btnSavePrivKey.Name = "btnSavePrivKey"
        Me.btnSavePrivKey.Size = New System.Drawing.Size(115, 23)
        Me.btnSavePrivKey.TabIndex = 10
        Me.btnSavePrivKey.Text = "&Save private key..."
        '
        'btnSavePubKey
        '
        Me.btnSavePubKey.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.btnSavePubKey.Enabled = False
        Me.btnSavePubKey.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.btnSavePubKey.Location = New System.Drawing.Point(168, 232)
        Me.btnSavePubKey.Name = "btnSavePubKey"
        Me.btnSavePubKey.Size = New System.Drawing.Size(115, 23)
        Me.btnSavePubKey.TabIndex = 9
        Me.btnSavePubKey.Text = "&Save public key..."
        '
        'tbFingerprint
        '
        Me.tbFingerprint.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
            Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.tbFingerprint.Location = New System.Drawing.Point(120, 136)
        Me.tbFingerprint.Name = "tbFingerprint"
        Me.tbFingerprint.ReadOnly = True
        Me.tbFingerprint.Size = New System.Drawing.Size(284, 20)
        Me.tbFingerprint.TabIndex = 3
        '
        'label4
        '
        Me.label4.Location = New System.Drawing.Point(8, 136)
        Me.label4.Name = "label4"
        Me.label4.Size = New System.Drawing.Size(112, 23)
        Me.label4.TabIndex = 2
        Me.label4.Text = "MD5 Fingerprint:"
        '
        'tbOpenSsh
        '
        Me.tbOpenSsh.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
            Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.tbOpenSsh.Location = New System.Drawing.Point(8, 40)
        Me.tbOpenSsh.Multiline = True
        Me.tbOpenSsh.Name = "tbOpenSsh"
        Me.tbOpenSsh.ReadOnly = True
        Me.tbOpenSsh.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
        Me.tbOpenSsh.Size = New System.Drawing.Size(396, 88)
        Me.tbOpenSsh.TabIndex = 1
        '
        'label3
        '
        Me.label3.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
            Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.label3.Location = New System.Drawing.Point(8, 16)
        Me.label3.Name = "label3"
        Me.label3.Size = New System.Drawing.Size(396, 23)
        Me.label3.TabIndex = 0
        Me.label3.Text = "You can add this into OpenSSH's authorized_keys file:"
        '
        'label5
        '
        Me.label5.Location = New System.Drawing.Point(8, 184)
        Me.label5.Name = "label5"
        Me.label5.Size = New System.Drawing.Size(112, 23)
        Me.label5.TabIndex = 4
        Me.label5.Text = "Passphrase:"
        '
        'label6
        '
        Me.label6.Location = New System.Drawing.Point(8, 208)
        Me.label6.Name = "label6"
        Me.label6.Size = New System.Drawing.Size(112, 23)
        Me.label6.TabIndex = 6
        Me.label6.Text = "Confirm passphrase:"
        '
        'tbPassphrase
        '
        Me.tbPassphrase.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
            Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.tbPassphrase.Location = New System.Drawing.Point(120, 184)
        Me.tbPassphrase.Name = "tbPassphrase"
        Me.tbPassphrase.PasswordChar = Global.Microsoft.VisualBasic.ChrW(42)
        Me.tbPassphrase.Size = New System.Drawing.Size(284, 20)
        Me.tbPassphrase.TabIndex = 5
        '
        'tbConfirmPassphrase
        '
        Me.tbConfirmPassphrase.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
            Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.tbConfirmPassphrase.Location = New System.Drawing.Point(120, 208)
        Me.tbConfirmPassphrase.Name = "tbConfirmPassphrase"
        Me.tbConfirmPassphrase.PasswordChar = Global.Microsoft.VisualBasic.ChrW(42)
        Me.tbConfirmPassphrase.Size = New System.Drawing.Size(284, 20)
        Me.tbConfirmPassphrase.TabIndex = 7
        '
        'btnQuit
        '
        Me.btnQuit.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.btnQuit.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.btnQuit.Location = New System.Drawing.Point(344, 360)
        Me.btnQuit.Name = "btnQuit"
        Me.btnQuit.Size = New System.Drawing.Size(75, 23)
        Me.btnQuit.TabIndex = 3
        Me.btnQuit.Text = "&Quit"
        '
        'btnAbout
        '
        Me.btnAbout.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.btnAbout.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.btnAbout.Location = New System.Drawing.Point(8, 360)
        Me.btnAbout.Name = "btnAbout"
        Me.btnAbout.Size = New System.Drawing.Size(75, 23)
        Me.btnAbout.TabIndex = 2
        Me.btnAbout.Text = "About..."
        '
        'openFileDialog
        '
        Me.openFileDialog.Filter = "Privacy Enhanced Mail Certificate (*.pem)|*.pem"
        '
        'rbECDSA
        '
        Me.rbECDSA.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.rbECDSA.Location = New System.Drawing.Point(336, 16)
        Me.rbECDSA.Name = "rbECDSA"
        Me.rbECDSA.Size = New System.Drawing.Size(64, 24)
        Me.rbECDSA.TabIndex = 9
        Me.rbECDSA.Text = "ECDSA"
        '
        'rbED25519
        '
        Me.rbED25519.FlatStyle = System.Windows.Forms.FlatStyle.System
        Me.rbED25519.Location = New System.Drawing.Point(253, 16)
        Me.rbED25519.Name = "rbED25519"
        Me.rbED25519.Size = New System.Drawing.Size(64, 24)
        Me.rbED25519.TabIndex = 8
        Me.rbED25519.Text = "ED25519"
        '
        'MainForm
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(426, 392)
        Me.Controls.Add(Me.btnAbout)
        Me.Controls.Add(Me.btnQuit)
        Me.Controls.Add(Me.groupBox2)
        Me.Controls.Add(Me.groupBox1)
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
        Me.MaximizeBox = False
        Me.Name = "MainForm"
        Me.Text = "Rebex SSH Key Generator"
        Me.groupBox1.ResumeLayout(False)
        Me.groupBox2.ResumeLayout(False)
        Me.groupBox2.PerformLayout()
        Me.ResumeLayout(False)

    End Sub
#End Region

    Private Sub btnQuit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnQuit.Click
        Close()
    End Sub 'btnQuit_Click


    Private Sub AlgoRbCheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles rbDSA.CheckedChanged, rbRSA.CheckedChanged, rbED25519.CheckedChanged, rbECDSA.CheckedChanged
        If Not _initialized Then Return

        Dim salg As SupportedAlgorithm = SelectedAlgorithm
        cbBits.DataSource = salg.KeySizesTable()
        cbBits.SelectedIndex = salg.DefaultIndex
    End Sub 'rbRSA_CheckedChanged


    Private Sub btnAbout_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAbout.Click
        Dim about As New AboutForm
        about.ShowDialog()
    End Sub 'btnAbout_Click


    Private Sub btnGenerate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGenerate.Click
        Try
            Cursor.Current = Cursors.WaitCursor

            Dim selected As SupportedAlgorithm = SelectedAlgorithm
            Dim keySize As Integer = CInt(cbBits.SelectedValue)

            Dim algorithm As SshHostKeyAlgorithm = 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
        End Try
    End Sub 'btnGenerate_Click


    Private Sub ConstructOpenSSHString(ByVal publicKeyAlgorithm As String)
        ' construct the OpenSSH-style public key string 

        'get the raw form of SSH public key 
        Dim rawPublicKey As Byte() = _privateKey.GetPublicKey()

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

        ' and display it 
        tbOpenSsh.Text = sshPublicKey
    End Sub 'ConstructOpenSSHString


    Private Sub btnSavePrivKey_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSavePrivKey.Click
        If tbPassphrase.Text <> tbConfirmPassphrase.Text Then
            MessageBox.Show("Given passphrases do not match.", "Passphrases", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return
        End If

        Dim password As String
        If tbPassphrase.Text = "" Then
            If MessageBox.Show("Are you sure you want to save this key without a passphrase?", "Passphrase", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning) <> DialogResult.Yes Then
                Return
            End If
            password = Nothing
        Else
            password = tbPassphrase.Text
        End If

        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 Then
            ' get private key format
            Dim format As SshPrivateKeyFormat
            Select Case saveFileDialog.FilterIndex
                Case 1
                    format = SshPrivateKeyFormat.Pkcs8
                Case 2
                    format = SshPrivateKeyFormat.Putty
                Case 3
                    format = SshPrivateKeyFormat.OpenSsh
                Case 4
                    format = SshPrivateKeyFormat.NewOpenSsh
                Case Else
                    format = SshPrivateKeyFormat.Pkcs8
            End Select

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

            MessageBox.Show("The private key was successfuly saved.", " Private key", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub 'btnSavePrivKey_Click


    Private Sub btnSavePubKey_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSavePubKey.Click
        saveFileDialog.FileName = ""
        saveFileDialog.Filter = "Public Key (*.pub)|*.pub"
        saveFileDialog.DefaultExt = "pub"
        If saveFileDialog.ShowDialog() = DialogResult.OK Then
            ' save the public key 
            _privateKey.SavePublicKey(saveFileDialog.FileName)
            MessageBox.Show("The public key was successfuly saved.", "Public key", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub 'btnSavePubKey_Click


    Private Sub btnLoad_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnLoad.Click
        openFileDialog.FileName = ""
        openFileDialog.Filter = "Private Key Files (*.pri,*.ppk)|*.pri;*.ppk|All Files (*.*)|*.*"
        If openFileDialog.ShowDialog() = DialogResult.OK Then
            Try
                Dim pp As New PassphraseDialog
                If pp.ShowDialog() = DialogResult.OK Then
                    _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
                End If
            Catch ex As Exception
                MessageBox.Show(String.Format("Unable to load the key." + ControlChars.Lf + "{0}", ex.Message), "Loading failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Return
            End Try

            MessageBox.Show("Key was successfuly loaded.", "Loading successful", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub 'btnLoad_Click
End Class 'MainForm
