1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 11:32:48 -05:00

Windows PuTTYgen: support cmdgen's key-type and PPK options.

This imports the following options from command-line PuTTYgen, which
all correspond to controls in Windows PuTTYgen's GUI, and let you set
the GUI controls to initial values of your choice:

  -t <key type>
  -b <bits>
  -E <fingerprint type>
  --primes <prime gen policy>
  --strong-rsa
  --ppk-param <KDF parameters or PPK version etc>

The idea is that if someone generates a lot of keys and has standard
non-default preferences, they can make a shortcut that passes those
preferences on the command line.
This commit is contained in:
Simon Tatham
2022-01-15 18:30:34 +00:00
parent dc183e1649
commit 11aa9ab8f3
2 changed files with 242 additions and 9 deletions

View File

@ -629,6 +629,15 @@ static DWORD WINAPI generate_key_thread(void *param)
return 0;
}
struct InitialParams {
int keybutton;
int primepolicybutton;
bool rsa_strong;
FingerprintType fptype;
int keybits;
int eccurve_index, edcurve_index;
};
struct MainDlgState {
bool generation_thread_exists;
bool key_exists;
@ -1393,15 +1402,16 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
cp.ypos = ymax;
endbox(&cp);
}
ui_set_key_type(hwnd, state, IDC_KEYSSH2RSA);
ui_set_primepolicy(hwnd, state, IDC_PRIMEGEN_PROB);
ui_set_rsa_strong(hwnd, state, false);
ui_set_fptype(hwnd, state, fptype_to_idc(SSH_FPTYPE_DEFAULT));
SetDlgItemInt(hwnd, IDC_BITS, DEFAULT_KEY_BITS, false);
struct InitialParams *params = (struct InitialParams *)lParam;
ui_set_key_type(hwnd, state, params->keybutton);
ui_set_primepolicy(hwnd, state, params->primepolicybutton);
ui_set_rsa_strong(hwnd, state, params->rsa_strong);
ui_set_fptype(hwnd, state, fptype_to_idc(params->fptype));
SetDlgItemInt(hwnd, IDC_BITS, params->keybits, false);
SendDlgItemMessage(hwnd, IDC_ECCURVE, CB_SETCURSEL,
DEFAULT_ECCURVE_INDEX, 0);
params->eccurve_index, 0);
SendDlgItemMessage(hwnd, IDC_EDCURVE, CB_SETCURSEL,
DEFAULT_EDCURVE_INDEX, 0);
params->edcurve_index, 0);
/*
* Initially, hide the progress bar and the key display,
@ -2013,6 +2023,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
int argc;
char **argv;
int ret;
struct InitialParams params[1];
dll_hijacking_protection();
@ -2024,6 +2035,16 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
*/
init_help();
params->keybutton = IDC_KEYSSH2RSA;
params->primepolicybutton = IDC_PRIMEGEN_PROB;
params->rsa_strong = false;
params->fptype = SSH_FPTYPE_DEFAULT;
params->keybits = DEFAULT_KEY_BITS;
params->eccurve_index = DEFAULT_ECCURVE_INDEX;
params->edcurve_index = DEFAULT_EDCURVE_INDEX;
save_params = ppk_save_default_parameters;
split_into_argv(cmdline, &argc, &argv, NULL);
int argbits = -1;
@ -2052,15 +2073,151 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
} else if (match_opt("-restrict-acl", "-restrict_acl",
"-restrictacl")) {
restrict_process_acl();
} else if (match_optval("-t")) {
if (!strcmp(val, "rsa") || !strcmp(val, "rsa2")) {
params->keybutton = IDC_KEYSSH2RSA;
} else if (!strcmp(val, "rsa1")) {
params->keybutton = IDC_KEYSSH1;
} else if (!strcmp(val, "dsa") || !strcmp(val, "dss")) {
params->keybutton = IDC_KEYSSH2DSA;
} else if (!strcmp(val, "ecdsa")) {
params->keybutton = IDC_KEYSSH2ECDSA;
} else if (!strcmp(val, "eddsa")) {
params->keybutton = IDC_KEYSSH2EDDSA;
} else if (!strcmp(val, "ed25519")) {
params->keybutton = IDC_KEYSSH2EDDSA;
argbits = 255;
} else if (!strcmp(val, "ed448")) {
params->keybutton = IDC_KEYSSH2EDDSA;
argbits = 448;
} else {
opt_error("unknown key type '%s'\n", val);
}
} else if (match_optval("-b")) {
argbits = atoi(val);
} else if (match_optval("-E")) {
if (!strcmp(val, "md5"))
params->fptype = SSH_FPTYPE_MD5;
else if (!strcmp(val, "sha256"))
params->fptype = SSH_FPTYPE_SHA256;
else
opt_error("unknown fingerprint type '%s'\n", val);
} else if (match_optval("-primes")) {
if (!strcmp(val, "probable") ||
!strcmp(val, "probabilistic")) {
params->primepolicybutton = IDC_PRIMEGEN_PROB;
} else if (!strcmp(val, "provable") ||
!strcmp(val, "proven") ||
!strcmp(val, "simple") ||
!strcmp(val, "maurer-simple")) {
params->primepolicybutton = IDC_PRIMEGEN_MAURER_SIMPLE;
} else if (!strcmp(val, "provable-even") ||
!strcmp(val, "proven-even") ||
!strcmp(val, "even") ||
!strcmp(val, "complex") ||
!strcmp(val, "maurer-complex")) {
params->primepolicybutton = IDC_PRIMEGEN_MAURER_COMPLEX;
} else {
opt_error("unrecognised prime-generation mode '%s'\n", val);
}
} else if (match_opt("-strong-rsa")) {
params->rsa_strong = true;
} else if (match_optval("-ppk-param", "-ppk-params")) {
char *nextval;
for (; val; val = nextval) {
nextval = strchr(val, ',');
if (nextval)
*nextval++ = '\0';
char *optvalue = strchr(val, '=');
if (!optvalue)
opt_error("PPK parameter '%s' expected a value\n", val);
*optvalue++ = '\0';
/* Non-numeric options */
if (!strcmp(val, "kdf")) {
if (!strcmp(optvalue, "Argon2id") ||
!strcmp(optvalue, "argon2id")) {
save_params.argon2_flavour = Argon2id;
} else if (!strcmp(optvalue, "Argon2i") ||
!strcmp(optvalue, "argon2i")) {
save_params.argon2_flavour = Argon2i;
} else if (!strcmp(optvalue, "Argon2d") ||
!strcmp(optvalue, "argon2d")) {
save_params.argon2_flavour = Argon2d;
} else {
opt_error("unrecognised kdf '%s'\n", optvalue);
}
continue;
}
char *end;
unsigned long n = strtoul(optvalue, &end, 0);
if (!*optvalue || *end)
opt_error("value '%s' for PPK parameter '%s': expected a "
"number\n", optvalue, val);
if (!strcmp(val, "version")) {
save_params.fmt_version = n;
} else if (!strcmp(val, "memory") ||
!strcmp(val, "mem")) {
save_params.argon2_mem = n;
} else if (!strcmp(val, "time")) {
save_params.argon2_passes_auto = true;
save_params.argon2_milliseconds = n;
} else if (!strcmp(val, "passes")) {
save_params.argon2_passes_auto = false;
save_params.argon2_passes = n;
} else if (!strcmp(val, "parallelism") ||
!strcmp(val, "parallel")) {
save_params.argon2_parallelism = n;
} else {
opt_error("unrecognised PPK parameter '%s'\n", val);
}
}
} else {
opt_error("unrecognised option '%s'\n", amo.argv[amo.index]);
}
}
save_params = ppk_save_default_parameters;
/* Translate argbits into eccurve_index and edcurve_index */
if (argbits > 0) {
switch (params->keybutton) {
case IDC_KEYSSH2RSA:
case IDC_KEYSSH1:
case IDC_KEYSSH2DSA:
params->keybits = argbits;
break;
case IDC_KEYSSH2ECDSA: {
bool found = false;
for (int j = 0; j < n_ec_nist_curve_lengths; j++)
if (argbits == ec_nist_curve_lengths[j]) {
params->eccurve_index = j;
found = true;
break;
}
if (!found)
opt_error("unsupported ECDSA bit length %d", argbits);
break;
}
case IDC_KEYSSH2EDDSA: {
bool found = false;
for (int j = 0; j < n_ec_ed_curve_lengths; j++)
if (argbits == ec_ed_curve_lengths[j]) {
params->edcurve_index = j;
found = true;
break;
}
if (!found)
opt_error("unsupported EDDSA bit length %d", argbits);
break;
}
}
}
random_setup_special();
ret = DialogBox(hinst, MAKEINTRESOURCE(201), NULL, MainDlgProc) != IDOK;
ret = DialogBoxParam(hinst, MAKEINTRESOURCE(201), NULL, MainDlgProc,
(LPARAM)params) != IDOK;
cleanup_exit(ret);
return ret; /* just in case optimiser complains */