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:
@ -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 */
|
||||
|
Reference in New Issue
Block a user