diff --git a/cmdgen.c b/cmdgen.c index c7f6edbf..79fd3733 100644 --- a/cmdgen.c +++ b/cmdgen.c @@ -150,6 +150,20 @@ void help(void) " proven numbers that have been proven to be prime\n" " proven-even also try harder for an even distribution\n" " --strong-rsa use \"strong\" primes as RSA key factors\n" + " --ppk-param =[,=,...]\n" + " specify parameters when writing PuTTY private key file " + "format:\n" + " version PPK format version (min 2, max 3, " + "default 3)\n" + " memory Kb of memory to use in password hash " + "(default 8192)\n" + " time approx milliseconds to hash for " + "(default 100)\n" + " passes exact number of hash passes to run " + "(alternative to 'time')\n" + " parallelism number of parallelisable threads in the " + "hash function\n" + " (default 1)\n" ); } @@ -227,6 +241,7 @@ int main(int argc, char **argv) int exit_status = 0; const PrimeGenerationPolicy *primegen = &primegen_probabilistic; bool strong_rsa = false; + ppk_save_parameters params = ppk_save_default_parameters; if (is_interactive()) progress_fp = stderr; @@ -366,6 +381,62 @@ int main(int argc, char **argv) strong_rsa = true; } else if (!strcmp(opt, "-reencrypt")) { reencrypt = true; + } else if (!strcmp(opt, "-ppk-param") || + !strcmp(opt, "-ppk-params")) { + if (!val && argc > 1) + --argc, val = *++argv; + if (!val) { + errs = true; + fprintf(stderr, "puttygen: option `-%s'" + " expects an argument\n", opt); + } else { + char *nextval; + for (; val; val = nextval) { + nextval = strchr(val, ','); + if (nextval) + *nextval++ = '\0'; + + char *optvalue = strchr(val, '='); + if (!optvalue) { + errs = true; + fprintf(stderr, "puttygen: PPK parameter " + "'%s' expected a value\n", val); + continue; + } + + *optvalue++ = '\0'; + char *end; + unsigned long n = strtoul(optvalue, &end, 0); + if (!*optvalue || *end) { + errs = true; + fprintf(stderr, "puttygen: value '%s' for " + "PPK parameter '%s': expected a " + "number\n", optvalue, val); + continue; + } + + if (!strcmp(val, "version")) { + params.fmt_version = n; + } else if (!strcmp(val, "memory") || + !strcmp(val, "mem")) { + params.argon2_mem = n; + } else if (!strcmp(val, "time")) { + params.argon2_passes_auto = true; + params.argon2_milliseconds = n; + } else if (!strcmp(val, "passes")) { + params.argon2_passes_auto = false; + params.argon2_milliseconds = n; + } else if (!strcmp(val, "parallelism") || + !strcmp(val, "parallel")) { + params.argon2_parallelism = n; + } else { + errs = true; + fprintf(stderr, "puttygen: unrecognised " + "PPK parameter '%s'\n", val); + continue; + } + } + } } else { errs = true; fprintf(stderr, @@ -1033,8 +1104,7 @@ int main(int argc, char **argv) } } else { assert(ssh2key); - ret = ppk_save_f(outfilename, ssh2key, new_passphrase, - &ppk_save_default_parameters); + ret = ppk_save_f(outfilename, ssh2key, new_passphrase, ¶ms); if (!ret) { fprintf(stderr, "puttygen: unable to save SSH-2 private key\n"); RETURN(1);