mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +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"
|
#define APPDESC "PuTTY SSH key generation utility"
|
||||||
|
|
||||||
#include "winhelp.rc2"
|
#include "winhelp.rc2"
|
||||||
|
#include "puttygen-rc.h"
|
||||||
|
|
||||||
200 ICON "puttygen.ico"
|
200 ICON "puttygen.ico"
|
||||||
|
|
||||||
@ -53,6 +54,31 @@ BEGIN
|
|||||||
EDITTEXT 1000, 10, 10, 306, 200, ES_READONLY | ES_MULTILINE | ES_LEFT, WS_EX_STATICEDGE
|
EDITTEXT 1000, 10, 10, 306, 200, ES_READONLY | ES_MULTILINE | ES_LEFT, WS_EX_STATICEDGE
|
||||||
END
|
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"
|
#include "version.rc2"
|
||||||
|
|
||||||
#ifndef NO_MANIFESTS
|
#ifndef NO_MANIFESTS
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "sshkeygen.h"
|
#include "sshkeygen.h"
|
||||||
#include "licence.h"
|
#include "licence.h"
|
||||||
#include "winsecur.h"
|
#include "winsecur.h"
|
||||||
|
#include "puttygen-rc.h"
|
||||||
|
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
|
|
||||||
@ -260,6 +261,144 @@ static INT_PTR CALLBACK PassphraseProc(HWND hwnd, UINT msg,
|
|||||||
return 0;
|
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
|
* Prompt for a key file. Assumes the filename buffer is of size
|
||||||
* FILENAME_MAX.
|
* FILENAME_MAX.
|
||||||
@ -529,6 +668,7 @@ enum {
|
|||||||
IDC_KEYSSH2ECDSA, IDC_KEYSSH2EDDSA,
|
IDC_KEYSSH2ECDSA, IDC_KEYSSH2EDDSA,
|
||||||
IDC_PRIMEGEN_PROB, IDC_PRIMEGEN_MAURER_SIMPLE, IDC_PRIMEGEN_MAURER_COMPLEX,
|
IDC_PRIMEGEN_PROB, IDC_PRIMEGEN_MAURER_SIMPLE, IDC_PRIMEGEN_MAURER_COMPLEX,
|
||||||
IDC_RSA_STRONG,
|
IDC_RSA_STRONG,
|
||||||
|
IDC_PPK_PARAMS,
|
||||||
IDC_BITSSTATIC, IDC_BITS,
|
IDC_BITSSTATIC, IDC_BITS,
|
||||||
IDC_ECCURVESTATIC, IDC_ECCURVE,
|
IDC_ECCURVESTATIC, IDC_ECCURVE,
|
||||||
IDC_EDCURVESTATIC, IDC_EDCURVE,
|
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_SEPARATOR, 0, 0);
|
||||||
AppendMenu(menu1, MF_ENABLED, IDC_RSA_STRONG,
|
AppendMenu(menu1, MF_ENABLED, IDC_RSA_STRONG,
|
||||||
"Use \"strong\" primes as RSA key factors");
|
"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");
|
AppendMenu(menu, MF_POPUP | MF_ENABLED, (UINT_PTR) menu1, "&Key");
|
||||||
state->keymenu = menu1;
|
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);
|
ui_set_rsa_strong(hwnd, state, !state->rsa_strong);
|
||||||
break;
|
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:
|
case IDC_QUIT:
|
||||||
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
||||||
break;
|
break;
|
||||||
@ -1469,7 +1634,7 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
|||||||
else
|
else
|
||||||
ret = ppk_save_f(fn, &state->ssh2key,
|
ret = ppk_save_f(fn, &state->ssh2key,
|
||||||
*passphrase ? passphrase : NULL,
|
*passphrase ? passphrase : NULL,
|
||||||
&ppk_save_default_parameters);
|
&save_params);
|
||||||
filename_free(fn);
|
filename_free(fn);
|
||||||
} else {
|
} else {
|
||||||
Filename *fn = filename_from_str(filename);
|
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();
|
random_setup_special();
|
||||||
ret = DialogBox(hinst, MAKEINTRESOURCE(201), NULL, MainDlgProc) != IDOK;
|
ret = DialogBox(hinst, MAKEINTRESOURCE(201), NULL, MainDlgProc) != IDOK;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user