Imports ComponentPro.Net

Namespace SshKeyGen
	Partial Public Class KeyGen
		Inherits Form
		Private ReadOnly _rsaKeySizes() As Integer = {512, 1024, 2048, 4096}
		Private ReadOnly _dsaKeySizes() As Integer = {512, 1024}
		Private _privateKey As SecureShellPrivateKey

		Public Sub New()
			InitializeComponent()
			cbxKeySize.DataSource = _rsaKeySizes
		End Sub

		Private Sub btnLoad_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnLoad.Click
			If openDialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
				Try
					Dim pp As New PasswordPrompt()
					If pp.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
						_privateKey = New SecureShellPrivateKey(openDialog.FileName, pp.Password)
						rbtSshRsa.Enabled = (_privateKey.KeyAlgorithm = SecureShellHostKeyAlgorithm.RSA)

						txtFingerprint.Text = _privateKey.Fingerprint.ToString()

						BuildSshPublicKey(_privateKey.KeyAlgorithm)

						txtPassphrase.Text = ""
						txtConfirmPassphrase.Text = ""

						btnSavePrivate.Enabled = True
						btnSavePublic.Enabled = True
					End If
				Catch ex As Exception
					MessageBox.Show(String.Format("Unable to load the key file." & vbLf & "{0}", ex.Message), "Loading failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
					Return
				End Try

				MessageBox.Show("Key file has been loaded successfuly.", "SSH Key Gen", MessageBoxButtons.OK, MessageBoxIcon.Information)
			End If
		End Sub

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

				Dim algorithm As SecureShellHostKeyAlgorithm

				If rbtSshRsa.Checked Then
					algorithm = SecureShellHostKeyAlgorithm.RSA
				Else
					algorithm = SecureShellHostKeyAlgorithm.DSS
				End If

				Dim keySize As Integer = CInt(Fix(cbxKeySize.SelectedValue))

				' generate private key 
				_privateKey = SecureShellPrivateKey.Create(algorithm, keySize)

				' fingerprint
				txtFingerprint.Text = _privateKey.Fingerprint.ToString()

				BuildSshPublicKey(algorithm)

				btnSavePrivate.Enabled = True
				btnSavePublic.Enabled = True
			Finally
				Cursor.Current = Cursors.Default
			End Try
		End Sub

		Private Sub btnSavePublic_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSavePublic.Click
			saveDialog.Filter = "Public Certificate (*.pub)|*.pub"
			saveDialog.DefaultExt = "pub"

			If saveDialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
				' save the public key 
				_privateKey.SavePublicKey(saveDialog.FileName)
				MessageBox.Show("The public key has been saved successfuly.", "SSH Key Gen", MessageBoxButtons.OK, MessageBoxIcon.Information)
			End If
		End Sub

		Private Sub btnSavePrivate_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSavePrivate.Click
			If txtPassphrase.Text <> txtConfirmPassphrase.Text Then
				MessageBox.Show("Passphrases do not match.", "SSH Key Gen", MessageBoxButtons.OK, MessageBoxIcon.Error)
				Return
			End If

			If txtPassphrase.Text = "" Then
				If MessageBox.Show("Are you sure you want to save this key without a passphrase?", "SSH Key Gen", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning) <> System.Windows.Forms.DialogResult.Yes Then
					Return
				End If
			End If

			saveDialog.Filter = "Private Key (*.pri)|*.pri"
			saveDialog.DefaultExt = "pem"
			If saveDialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
				' save the private key 
				_privateKey.Save(saveDialog.FileName, txtPassphrase.Text, Nothing)
				MessageBox.Show("The private key has been saved successfuly.", " SSH Key Gen", MessageBoxButtons.OK, MessageBoxIcon.Information)
			End If
		End Sub

		Private Sub btnClose_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnClose.Click
			Me.Close()
		End Sub

		Private Sub BuildSshPublicKey(ByVal algorithm As SecureShellHostKeyAlgorithm)
			' Get the raw data of SSH public key.
			Dim rawPublicKey() As Byte = _privateKey.GetPublicKey()

			Dim publicKeyAlgorithm As String
			Select Case algorithm
				Case SecureShellHostKeyAlgorithm.RSA
					publicKeyAlgorithm = "ssh-rsa"
				Case SecureShellHostKeyAlgorithm.DSS
					publicKeyAlgorithm = "ssh-dss"
				Case Else
					Throw New ApplicationException("Unsupported algorithm.")
			End Select

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

			' Show it.
			txtSsh.Text = sshPublicKey
		End Sub

		Private Sub rbtSshRsa_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs) Handles rbtSshRsa.CheckedChanged
			If rbtSshRsa.Checked Then
				cbxKeySize.DataSource = _rsaKeySizes
			Else
				cbxKeySize.DataSource = _dsaKeySizes
			End If

			If cbxKeySize.Items.Count > 0 Then
				cbxKeySize.SelectedIndex = 0
			End If
		End Sub

		Private Sub rbtSshDsa_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs) Handles rbtSshDsa.CheckedChanged
			If rbtSshRsa.Checked Then
				cbxKeySize.DataSource = _rsaKeySizes
			Else
				cbxKeySize.DataSource = _dsaKeySizes
			End If

			If cbxKeySize.Items.Count > 0 Then
				cbxKeySize.SelectedIndex = 0
			End If
		End Sub
	End Class
End Namespace