mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Windows PuTTYgen: configurable PPK save parameters.
The GUI key generator doesn't need a --reencrypt option, because you can already just click Load and then Save without changing anything in between. But it does need a dialog box with all the fiddly Argon2 settings in it, plus a setting to go back to PPK v2.
This commit is contained in:
parent
117cee8ea6
commit
c10aff8a47
13
windows/puttygen-rc.h
Normal file
13
windows/puttygen-rc.h
Normal file
@ -0,0 +1,13 @@
|
||||
#define IDC_PPKVER_STATIC 100
|
||||
#define IDC_PPKVER_2 101
|
||||
#define IDC_PPKVER_3 102
|
||||
#define IDC_ARGON2_MEM_STATIC 103
|
||||
#define IDC_ARGON2_MEM 104
|
||||
#define IDC_ARGON2_MEM_STATIC2 105
|
||||
#define IDC_PPK_AUTO_STATIC 106
|
||||
#define IDC_PPK_AUTO_YES 107
|
||||
#define IDC_PPK_AUTO_NO 108
|
||||
#define IDC_ARGON2_TIME_STATIC 109
|
||||
#define IDC_ARGON2_TIME 110
|
||||
#define IDC_ARGON2_PARALLEL_STATIC 111
|
||||
#define IDC_ARGON2_PARALLEL 112
|
@ -8,6 +8,7 @@
|
||||
#define APPDESC "PuTTY SSH key generation utility"
|
||||
|
||||
#include "winhelp.rc2"
|
||||
#include "puttygen-rc.h"
|
||||
|
||||
200 ICON "puttygen.ico"
|
||||
|
||||
@ -53,6 +54,31 @@ BEGIN
|
||||
EDITTEXT 1000, 10, 10, 306, 200, ES_READONLY | ES_MULTILINE | ES_LEFT, WS_EX_STATICEDGE
|
||||
END
|
||||
|
||||
215 DIALOG DISCARDABLE 0, 0, 240, 84
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "PuTTYgen: Private Key File Parameters"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "PPK file version:", IDC_PPKVER_STATIC, 5, 6, 115, 8
|
||||
AUTORADIOBUTTON "2", IDC_PPKVER_2, 120, 5, 30, 10, WS_GROUP
|
||||
AUTORADIOBUTTON "3", IDC_PPKVER_3, 150, 5, 30, 10
|
||||
LTEXT "Memory to use for password hash:", IDC_ARGON2_MEM_STATIC,
|
||||
5, 22, 115, 8
|
||||
EDITTEXT IDC_ARGON2_MEM, 120, 20, 40, 12
|
||||
LTEXT "Kb", IDC_ARGON2_MEM_STATIC2,
|
||||
170, 22, 20, 8
|
||||
LTEXT "Time to use for password hash:", IDC_ARGON2_TIME_STATIC,
|
||||
5, 36, 115, 8
|
||||
EDITTEXT IDC_ARGON2_TIME, 120, 34, 40, 12
|
||||
AUTORADIOBUTTON "ms", IDC_PPK_AUTO_YES, 170, 35, 20, 10, WS_GROUP
|
||||
AUTORADIOBUTTON "passes", IDC_PPK_AUTO_NO, 200, 35, 40, 10
|
||||
LTEXT "Parallelism for password hash:", IDC_ARGON2_PARALLEL_STATIC,
|
||||
5, 50, 115, 8
|
||||
EDITTEXT IDC_ARGON2_PARALLEL, 120, 48, 60, 12
|
||||
DEFPUSHBUTTON "O&K", IDOK, 70, 66, 40, 14
|
||||
PUSHBUTTON "&Cancel", IDCANCEL, 130, 66, 40, 14
|
||||
END
|
||||
|
||||
#include "version.rc2"
|
||||
|
||||
#ifndef NO_MANIFESTS
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "sshkeygen.h"
|
||||
#include "licence.h"
|
||||
#include "winsecur.h"
|
||||
#include "puttygen-rc.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
|
||||
@ -260,6 +261,144 @@ static INT_PTR CALLBACK PassphraseProc(HWND hwnd, UINT msg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void try_get_dlg_item_uint32(HWND hwnd, int id, uint32_t *out)
|
||||
{
|
||||
char buf[128];
|
||||
if (!GetDlgItemText(hwnd, id, buf, sizeof(buf)))
|
||||
return;
|
||||
|
||||
if (!*buf)
|
||||
return;
|
||||
|
||||
char *end;
|
||||
unsigned long val = strtoul(buf, &end, 10);
|
||||
if (*end)
|
||||
return;
|
||||
|
||||
if ((val >> 16) >> 16)
|
||||
return;
|
||||
|
||||
*out = val;
|
||||
}
|
||||
|
||||
static ppk_save_parameters save_params;
|
||||
|
||||
struct PPKParams {
|
||||
ppk_save_parameters params;
|
||||
uint32_t time_passes, time_ms;
|
||||
};
|
||||
|
||||
/*
|
||||
* Dialog-box function for the passphrase box.
|
||||
*/
|
||||
static INT_PTR CALLBACK PPKParamsProc(HWND hwnd, UINT msg,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct PPKParams *pp;
|
||||
char *buf;
|
||||
|
||||
if (msg == WM_INITDIALOG) {
|
||||
pp = (struct PPKParams *)lParam;
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pp);
|
||||
} else {
|
||||
pp = (struct PPKParams *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
}
|
||||
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG:
|
||||
SetForegroundWindow(hwnd);
|
||||
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||
|
||||
/*
|
||||
* Centre the window.
|
||||
*/
|
||||
{ /* centre the window */
|
||||
RECT rs, rd;
|
||||
HWND hw;
|
||||
|
||||
hw = GetDesktopWindow();
|
||||
if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
|
||||
MoveWindow(hwnd,
|
||||
(rs.right + rs.left + rd.left - rd.right) / 2,
|
||||
(rs.bottom + rs.top + rd.top - rd.bottom) / 2,
|
||||
rd.right - rd.left, rd.bottom - rd.top, true);
|
||||
}
|
||||
|
||||
CheckRadioButton(hwnd, IDC_PPKVER_2, IDC_PPKVER_3,
|
||||
IDC_PPKVER_2 + (pp->params.fmt_version - 2));
|
||||
|
||||
buf = dupprintf("%"PRIu32, pp->params.argon2_mem);
|
||||
SetDlgItemText(hwnd, IDC_ARGON2_MEM, buf);
|
||||
sfree(buf);
|
||||
|
||||
if (pp->params.argon2_passes_auto) {
|
||||
CheckRadioButton(hwnd, IDC_PPK_AUTO_YES, IDC_PPK_AUTO_NO,
|
||||
IDC_PPK_AUTO_YES);
|
||||
buf = dupprintf("%"PRIu32, pp->time_ms);
|
||||
SetDlgItemText(hwnd, IDC_ARGON2_TIME, buf);
|
||||
sfree(buf);
|
||||
} else {
|
||||
CheckRadioButton(hwnd, IDC_PPK_AUTO_YES, IDC_PPK_AUTO_NO,
|
||||
IDC_PPK_AUTO_NO);
|
||||
buf = dupprintf("%"PRIu32, pp->time_passes);
|
||||
SetDlgItemText(hwnd, IDC_ARGON2_TIME, buf);
|
||||
sfree(buf);
|
||||
}
|
||||
|
||||
buf = dupprintf("%"PRIu32, pp->params.argon2_parallelism);
|
||||
SetDlgItemText(hwnd, IDC_ARGON2_PARALLEL, buf);
|
||||
sfree(buf);
|
||||
|
||||
return 0;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
EndDialog(hwnd, 1);
|
||||
return 0;
|
||||
case IDCANCEL:
|
||||
EndDialog(hwnd, 0);
|
||||
return 0;
|
||||
case IDC_PPKVER_2:
|
||||
pp->params.fmt_version = 2;
|
||||
return 0;
|
||||
case IDC_PPKVER_3:
|
||||
pp->params.fmt_version = 3;
|
||||
return 0;
|
||||
case IDC_ARGON2_MEM:
|
||||
try_get_dlg_item_uint32(hwnd, IDC_ARGON2_MEM,
|
||||
&pp->params.argon2_mem);
|
||||
return 0;
|
||||
case IDC_PPK_AUTO_YES:
|
||||
pp->params.argon2_passes_auto = true;
|
||||
buf = dupprintf("%"PRIu32, pp->time_ms);
|
||||
SetDlgItemText(hwnd, IDC_ARGON2_TIME, buf);
|
||||
sfree(buf);
|
||||
return 0;
|
||||
case IDC_PPK_AUTO_NO:
|
||||
pp->params.argon2_passes_auto = false;
|
||||
buf = dupprintf("%"PRIu32, pp->time_passes);
|
||||
SetDlgItemText(hwnd, IDC_ARGON2_TIME, buf);
|
||||
sfree(buf);
|
||||
return 0;
|
||||
case IDC_ARGON2_TIME:
|
||||
try_get_dlg_item_uint32(hwnd, IDC_ARGON2_TIME,
|
||||
pp->params.argon2_passes_auto ?
|
||||
&pp->time_ms : &pp->time_passes);
|
||||
return 0;
|
||||
case IDC_ARGON2_PARALLEL:
|
||||
try_get_dlg_item_uint32(hwnd, IDC_ARGON2_PARALLEL,
|
||||
&pp->params.argon2_parallelism);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
case WM_CLOSE:
|
||||
EndDialog(hwnd, 0);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prompt for a key file. Assumes the filename buffer is of size
|
||||
* FILENAME_MAX.
|
||||
@ -529,6 +668,7 @@ enum {
|
||||
IDC_KEYSSH2ECDSA, IDC_KEYSSH2EDDSA,
|
||||
IDC_PRIMEGEN_PROB, IDC_PRIMEGEN_MAURER_SIMPLE, IDC_PRIMEGEN_MAURER_COMPLEX,
|
||||
IDC_RSA_STRONG,
|
||||
IDC_PPK_PARAMS,
|
||||
IDC_BITSSTATIC, IDC_BITS,
|
||||
IDC_ECCURVESTATIC, IDC_ECCURVE,
|
||||
IDC_EDCURVESTATIC, IDC_EDCURVE,
|
||||
@ -1006,6 +1146,9 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
||||
AppendMenu(menu1, MF_SEPARATOR, 0, 0);
|
||||
AppendMenu(menu1, MF_ENABLED, IDC_RSA_STRONG,
|
||||
"Use \"strong\" primes as RSA key factors");
|
||||
AppendMenu(menu1, MF_SEPARATOR, 0, 0);
|
||||
AppendMenu(menu1, MF_ENABLED, IDC_PPK_PARAMS,
|
||||
"Parameters for saving key files...");
|
||||
AppendMenu(menu, MF_POPUP | MF_ENABLED, (UINT_PTR) menu1, "&Key");
|
||||
state->keymenu = menu1;
|
||||
|
||||
@ -1214,6 +1357,28 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
||||
ui_set_rsa_strong(hwnd, state, !state->rsa_strong);
|
||||
break;
|
||||
}
|
||||
case IDC_PPK_PARAMS: {
|
||||
struct PPKParams pp[1];
|
||||
pp->params = save_params;
|
||||
if (pp->params.argon2_passes_auto) {
|
||||
pp->time_ms = pp->params.argon2_milliseconds;
|
||||
pp->time_passes = 13;
|
||||
} else {
|
||||
pp->time_ms = 100;
|
||||
pp->time_passes = pp->params.argon2_passes;
|
||||
}
|
||||
int dlgret = DialogBoxParam(hinst, MAKEINTRESOURCE(215),
|
||||
NULL, PPKParamsProc, (LPARAM)pp);
|
||||
if (dlgret) {
|
||||
if (pp->params.argon2_passes_auto) {
|
||||
pp->params.argon2_milliseconds = pp->time_ms;
|
||||
} else {
|
||||
pp->params.argon2_passes = pp->time_passes;
|
||||
}
|
||||
save_params = pp->params;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IDC_QUIT:
|
||||
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
||||
break;
|
||||
@ -1469,7 +1634,7 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
||||
else
|
||||
ret = ppk_save_f(fn, &state->ssh2key,
|
||||
*passphrase ? passphrase : NULL,
|
||||
&ppk_save_default_parameters);
|
||||
&save_params);
|
||||
filename_free(fn);
|
||||
} else {
|
||||
Filename *fn = filename_from_str(filename);
|
||||
@ -1748,6 +1913,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
}
|
||||
}
|
||||
|
||||
save_params = ppk_save_default_parameters;
|
||||
|
||||
random_setup_special();
|
||||
ret = DialogBox(hinst, MAKEINTRESOURCE(201), NULL, MainDlgProc) != IDOK;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user