123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789 |
- /*
- * cgtest.c: stub file to compile cmdgen.c in self-test mode
- */
- /*
- * Before we #include cmdgen.c, we override some function names for
- * test purposes. We do this via #define, so that when we link against
- * modules containing the original versions, we don't get a link-time
- * symbol clash:
- *
- * - Calls to get_random_data() are replaced with the diagnostic
- * function below, in order to avoid depleting the test system's
- * /dev/random unnecessarily.
- *
- * - Calls to console_get_userpass_input() are replaced with the
- * diagnostic function below, so that I can run tests in an
- * automated manner and provide their interactive passphrase
- * inputs.
- *
- * - The main() defined by cmdgen.c is renamed to cmdgen_main(); in
- * this file I define another main() which calls the former
- * repeatedly to run tests.
- */
- #define get_random_data get_random_data_diagnostic
- #define console_get_userpass_input console_get_userpass_input_diagnostic
- #define main cmdgen_main
- #define ppk_save_default_parameters ppk_save_cgtest_parameters
- #include "cmdgen.c"
- #undef get_random_data
- #undef console_get_userpass_input
- #undef main
- static bool cgtest_verbose = false;
- const struct ppk_save_parameters ppk_save_cgtest_parameters = {
- /* Replacement set of key derivation parameters that make this
- * test suite run a bit faster and also add determinism: we don't
- * try to auto-scale the number of passes (in case it gets
- * different answers twice in the test suite when we were
- * expecting two key files to compare equal), and we specify a
- * passphrase salt. */
- .fmt_version = 3,
- .argon2_flavour = Argon2id,
- .argon2_mem = 16,
- .argon2_passes_auto = false,
- .argon2_passes = 2,
- .argon2_parallelism = 1,
- .salt = (const uint8_t *)"SameSaltEachTime",
- .saltlen = 16,
- };
- /*
- * Define the special versions of get_random_data and
- * console_get_userpass_input that we need for this test rig.
- */
- char *get_random_data_diagnostic(int len, const char *device)
- {
- char *buf = snewn(len, char);
- memset(buf, 'x', len);
- return buf;
- }
- static int nprompts, promptsgot;
- static const char *prompts[3];
- SeatPromptResult console_get_userpass_input_diagnostic(prompts_t *p)
- {
- size_t i;
- SeatPromptResult ret = SPR_OK;
- for (i = 0; i < p->n_prompts; i++) {
- if (promptsgot < nprompts) {
- prompt_set_result(p->prompts[i], prompts[promptsgot++]);
- if (cgtest_verbose)
- printf(" prompt \"%s\": response \"%s\"\n",
- p->prompts[i]->prompt, p->prompts[i]->result->s);
- } else {
- promptsgot++; /* track number of requests anyway */
- ret = SPR_SW_ABORT("preloaded prompt unavailable in cgtest");
- if (cgtest_verbose)
- printf(" prompt \"%s\": no response preloaded\n",
- p->prompts[i]->prompt);
- }
- }
- return ret;
- }
- #include <stdarg.h>
- static int passes, fails;
- void setup_passphrases(char *first, ...)
- {
- va_list ap;
- char *next;
- nprompts = 0;
- if (first) {
- prompts[nprompts++] = first;
- va_start(ap, first);
- while ((next = va_arg(ap, char *)) != NULL) {
- assert(nprompts < lenof(prompts));
- prompts[nprompts++] = next;
- }
- va_end(ap);
- }
- }
- void test(int retval, ...)
- {
- va_list ap;
- int i, argc, ret;
- char **argv;
- argc = 0;
- va_start(ap, retval);
- while (va_arg(ap, char *) != NULL)
- argc++;
- va_end(ap);
- argv = snewn(argc+1, char *);
- va_start(ap, retval);
- for (i = 0; i <= argc; i++)
- argv[i] = va_arg(ap, char *);
- va_end(ap);
- promptsgot = 0;
- if (cgtest_verbose) {
- printf("run:");
- for (int i = 0; i < argc; i++) {
- static const char okchars[] =
- "0123456789abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ%+,-./:=[]^_";
- const char *arg = argv[i];
- printf(" ");
- if (arg[strspn(arg, okchars)]) {
- printf("'");
- for (const char *c = argv[i]; *c; c++) {
- if (*c == '\'') {
- printf("'\\''");
- } else {
- putchar(*c);
- }
- }
- printf("'");
- } else {
- fputs(arg, stdout);
- }
- }
- printf("\n");
- }
- ret = cmdgen_main(argc, argv);
- random_clear();
- if (ret != retval) {
- printf("FAILED retval (exp %d got %d):", retval, ret);
- for (i = 0; i < argc; i++)
- printf(" %s", argv[i]);
- printf("\n");
- fails++;
- } else if (promptsgot != nprompts) {
- printf("FAILED nprompts (exp %d got %d):", nprompts, promptsgot);
- for (i = 0; i < argc; i++)
- printf(" %s", argv[i]);
- printf("\n");
- fails++;
- } else {
- passes++;
- }
- sfree(argv);
- }
- PRINTF_LIKE(3, 4) void filecmp(char *file1, char *file2, char *fmt, ...)
- {
- /*
- * Ideally I should do file comparison myself, to maximise the
- * portability of this test suite once this application begins
- * running on non-Unix platforms. For the moment, though,
- * calling Unix diff is perfectly adequate.
- */
- char *buf;
- int ret;
- buf = dupprintf("diff -q '%s' '%s'", file1, file2);
- ret = system(buf);
- sfree(buf);
- if (ret) {
- va_list ap;
- printf("FAILED diff (ret=%d): ", ret);
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
- printf("\n");
- fails++;
- } else
- passes++;
- }
- /*
- * General-purpose flags word
- */
- #define CGT_FLAGS(X) \
- X(CGT_TYPE_KNOWN_EARLY) \
- X(CGT_OPENSSH) \
- X(CGT_SSHCOM) \
- X(CGT_SSH_KEYGEN) \
- X(CGT_ED25519) \
- /* end of list */
- #define FLAG_SHIFTS(name) name ## _shift,
- enum { CGT_FLAGS(FLAG_SHIFTS) CGT_dummy_shift };
- #define FLAG_VALUES(name) name = 1 << name ## _shift,
- enum { CGT_FLAGS(FLAG_VALUES) CGT_dummy_flag };
- char *cleanup_fp(char *s, unsigned flags)
- {
- ptrlen pl = ptrlen_from_asciz(s);
- static const char separators[] = " \n\t";
- /* Skip initial key type word if we find one */
- if (ptrlen_startswith(pl, PTRLEN_LITERAL("ssh-"), NULL) ||
- ptrlen_startswith(pl, PTRLEN_LITERAL("ecdsa-"), NULL))
- ptrlen_get_word(&pl, separators);
- /* Expect two words giving the key length and the hash */
- ptrlen bits = ptrlen_get_word(&pl, separators);
- ptrlen hash = ptrlen_get_word(&pl, separators);
- if (flags & CGT_SSH_KEYGEN) {
- /* Strip "MD5:" prefix if it's present, and do nothing if it isn't */
- ptrlen_startswith(hash, PTRLEN_LITERAL("MD5:"), &hash);
- if (flags & CGT_ED25519) {
- /* OpenSSH ssh-keygen lists ed25519 keys as 256 bits, not 255 */
- if (ptrlen_eq_string(bits, "256"))
- bits = PTRLEN_LITERAL("255");
- }
- }
- return dupprintf("%.*s %.*s", PTRLEN_PRINTF(bits), PTRLEN_PRINTF(hash));
- }
- char *get_line(char *filename)
- {
- FILE *fp;
- char *line;
- fp = fopen(filename, "r");
- if (!fp)
- return NULL;
- line = fgetline(fp);
- fclose(fp);
- return line;
- }
- char *get_fp(char *filename, unsigned flags)
- {
- char *orig = get_line(filename);
- if (!orig)
- return NULL;
- char *toret = cleanup_fp(orig, flags);
- sfree(orig);
- return toret;
- }
- PRINTF_LIKE(3, 4) void check_fp(char *filename, char *fp, char *fmt, ...)
- {
- char *newfp;
- if (!fp)
- return;
- newfp = get_fp(filename, 0);
- if (!strcmp(fp, newfp)) {
- passes++;
- } else {
- va_list ap;
- printf("FAILED check_fp ['%s' != '%s']: ", newfp, fp);
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
- printf("\n");
- fails++;
- }
- sfree(newfp);
- }
- static const struct cgtest_keytype {
- const char *name;
- unsigned flags;
- } cgtest_keytypes[] = {
- { "rsa1", CGT_TYPE_KNOWN_EARLY },
- { "dsa", CGT_OPENSSH | CGT_SSHCOM },
- { "rsa", CGT_OPENSSH | CGT_SSHCOM },
- { "ecdsa", CGT_OPENSSH },
- { "ed25519", CGT_OPENSSH | CGT_ED25519 },
- };
- int main(int argc, char **argv)
- {
- int i;
- int active[lenof(cgtest_keytypes)], active_value;
- bool remove_files = true;
- active_value = 0;
- for (i = 0; i < lenof(cgtest_keytypes); i++)
- active[i] = active_value;
- while (--argc > 0) {
- ptrlen arg = ptrlen_from_asciz(*++argv);
- if (ptrlen_eq_string(arg, "-v") ||
- ptrlen_eq_string(arg, "--verbose")) {
- cgtest_verbose = true;
- } else if (ptrlen_eq_string(arg, "--keep")) {
- remove_files = false;
- } else if (ptrlen_eq_string(arg, "--help")) {
- printf("usage: cgtest [options] [key types]\n");
- printf("options: -v, --verbose "
- "print more output during tests\n");
- printf(" --keep "
- "do not delete the temporary output files\n");
- printf(" --help "
- "display this help text\n");
- printf("key types: ");
- for (i = 0; i < lenof(cgtest_keytypes); i++)
- printf("%s%s", i ? ", " : "", cgtest_keytypes[i].name);
- printf("\n");
- return 0;
- } else if (!ptrlen_startswith(arg, PTRLEN_LITERAL("-"), NULL)) {
- for (i = 0; i < lenof(cgtest_keytypes); i++)
- if (ptrlen_eq_string(arg, cgtest_keytypes[i].name))
- break;
- if (i == lenof(cgtest_keytypes)) {
- fprintf(stderr, "cgtest: unrecognised key type '%.*s'\n",
- PTRLEN_PRINTF(arg));
- return 1;
- }
- active_value = 1; /* disables all keys not explicitly enabled */
- active[i] = active_value;
- } else {
- fprintf(stderr, "cgtest: unrecognised option '%.*s'\n",
- PTRLEN_PRINTF(arg));
- return 1;
- }
- }
- passes = fails = 0;
- for (i = 0; i < lenof(cgtest_keytypes); i++) {
- if (active[i] != active_value)
- continue;
- const struct cgtest_keytype *keytype = &cgtest_keytypes[i];
- bool supports_openssh = keytype->flags & CGT_OPENSSH;
- bool supports_sshcom = keytype->flags & CGT_SSHCOM;
- bool type_known_early = keytype->flags & CGT_TYPE_KNOWN_EARLY;
- char filename[128], osfilename[128], scfilename[128];
- char pubfilename[128], tmpfilename1[128], tmpfilename2[128];
- char *fps[SSH_N_FPTYPES];
- sprintf(filename, "test-%s.ppk", keytype->name);
- sprintf(pubfilename, "test-%s.pub", keytype->name);
- sprintf(osfilename, "test-%s.os", keytype->name);
- sprintf(scfilename, "test-%s.sc", keytype->name);
- sprintf(tmpfilename1, "test-%s.tmp1", keytype->name);
- sprintf(tmpfilename2, "test-%s.tmp2", keytype->name);
- /*
- * Create an encrypted key.
- */
- setup_passphrases("sponge", "sponge", NULL);
- test(0, "puttygen", "-t", keytype->name, "-o", filename, NULL);
- /*
- * List the public key in OpenSSH format.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", "-L", filename, "-o", pubfilename, NULL);
- for (FingerprintType fptype = 0; fptype < SSH_N_FPTYPES; fptype++) {
- const char *fpname = (fptype == SSH_FPTYPE_MD5 ? "md5" : "sha256");
- char *cmdbuf;
- char *fp = NULL;
- cmdbuf = dupprintf("ssh-keygen -E %s -l -f '%s' > '%s'",
- fpname, pubfilename, tmpfilename1);
- if (cgtest_verbose)
- printf("OpenSSH %s fp check: %s\n", fpname, cmdbuf);
- if (system(cmdbuf) ||
- (fp = get_fp(tmpfilename1,
- CGT_SSH_KEYGEN | keytype->flags)) == NULL) {
- printf("UNABLE to test fingerprint matching against "
- "OpenSSH\n");
- }
- sfree(cmdbuf);
- if (fp && cgtest_verbose) {
- char *line = get_line(tmpfilename1);
- printf("OpenSSH %s fp: %s\n", fpname, line);
- printf("Cleaned up: %s\n", fp);
- sfree(line);
- }
- fps[fptype] = fp;
- }
- /*
- * List the public key in IETF/ssh.com format.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", "-p", filename, NULL);
- /*
- * List the fingerprint of the key.
- */
- setup_passphrases(NULL);
- for (FingerprintType fptype = 0; fptype < SSH_N_FPTYPES; fptype++) {
- const char *fpname = (fptype == SSH_FPTYPE_MD5 ? "md5" : "sha256");
- test(0, "puttygen", "-E", fpname, "-l", filename,
- "-o", tmpfilename1, NULL);
- if (!fps[fptype]) {
- /*
- * If we can't test fingerprints against OpenSSH, we
- * can at the very least test equality of all the
- * fingerprints we generate of this key throughout
- * testing.
- */
- fps[fptype] = get_fp(tmpfilename1, 0);
- } else {
- check_fp(tmpfilename1, fps[fptype], "%s initial %s fp",
- keytype->name, fpname);
- }
- }
- /*
- * Change the comment of the key; this _does_ require a
- * passphrase owing to the tamperproofing.
- *
- * NOTE: In SSH-1, this only requires a passphrase because
- * of inadequacies of the loading and saving mechanisms. In
- * _principle_, it should be perfectly possible to modify
- * the comment on an SSH-1 key without requiring a
- * passphrase; the only reason I can't do it is because my
- * loading and saving mechanisms don't include a method of
- * loading all the key data without also trying to decrypt
- * the private section.
- *
- * I don't consider this to be a problem worth solving,
- * because (a) to fix it would probably end up bloating
- * PuTTY proper, and (b) SSH-1 is on the way out anyway so
- * it shouldn't be highly significant. If it seriously
- * bothers anyone then perhaps I _might_ be persuadable.
- */
- setup_passphrases("sponge", NULL);
- test(0, "puttygen", "-C", "new-comment", filename, NULL);
- /*
- * Change the passphrase to nothing.
- */
- setup_passphrases("sponge", "", "", NULL);
- test(0, "puttygen", "-P", filename, NULL);
- /*
- * Change the comment of the key again; this time we expect no
- * passphrase to be required.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", "-C", "new-comment-2", filename, NULL);
- /*
- * Export the private key into OpenSSH format; no passphrase
- * should be required since the key is currently unencrypted.
- */
- setup_passphrases(NULL);
- test(supports_openssh ? 0 : 1,
- "puttygen", "-O", "private-openssh", "-o", osfilename,
- filename, NULL);
- if (supports_openssh) {
- /*
- * List the fingerprint of the OpenSSH-formatted key.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", "-l", osfilename, "-o", tmpfilename1, NULL);
- check_fp(tmpfilename1, fps[SSH_FPTYPE_DEFAULT],
- "%s openssh clear fp", keytype->name);
- /*
- * List the public half of the OpenSSH-formatted key in
- * OpenSSH format.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", "-L", osfilename, NULL);
- /*
- * List the public half of the OpenSSH-formatted key in
- * IETF/ssh.com format.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", "-p", osfilename, NULL);
- }
- /*
- * Export the private key into ssh.com format; no passphrase
- * should be required since the key is currently unencrypted.
- */
- setup_passphrases(NULL);
- test(supports_sshcom ? 0 : 1,
- "puttygen", "-O", "private-sshcom",
- "-o", scfilename, filename, NULL);
- if (supports_sshcom) {
- /*
- * List the fingerprint of the ssh.com-formatted key.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", "-l", scfilename, "-o", tmpfilename1, NULL);
- check_fp(tmpfilename1, fps[SSH_FPTYPE_DEFAULT],
- "%s ssh.com clear fp", keytype->name);
- /*
- * List the public half of the ssh.com-formatted key in
- * OpenSSH format.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", "-L", scfilename, NULL);
- /*
- * List the public half of the ssh.com-formatted key in
- * IETF/ssh.com format.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", "-p", scfilename, NULL);
- }
- if (supports_openssh && supports_sshcom) {
- /*
- * Convert from OpenSSH into ssh.com.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", osfilename, "-o", tmpfilename1,
- "-O", "private-sshcom", NULL);
- /*
- * Convert from ssh.com back into a PuTTY key,
- * supplying the same comment as we had before we
- * started to ensure the comparison works.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", tmpfilename1, "-C", "new-comment-2",
- "-o", tmpfilename2, NULL);
- /*
- * See if the PuTTY key thus generated is the same as
- * the original.
- */
- filecmp(filename, tmpfilename2,
- "p->o->s->p clear %s", keytype->name);
- /*
- * Convert from ssh.com to OpenSSH.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", scfilename, "-o", tmpfilename1,
- "-O", "private-openssh", NULL);
- /*
- * Convert from OpenSSH back into a PuTTY key,
- * supplying the same comment as we had before we
- * started to ensure the comparison works.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", tmpfilename1, "-C", "new-comment-2",
- "-o", tmpfilename2, NULL);
- /*
- * See if the PuTTY key thus generated is the same as
- * the original.
- */
- filecmp(filename, tmpfilename2,
- "p->s->o->p clear %s", keytype->name);
- /*
- * Finally, do a round-trip conversion between PuTTY
- * and ssh.com without involving OpenSSH, to test that
- * the key comment is preserved in that case.
- */
- setup_passphrases(NULL);
- test(0, "puttygen", "-O", "private-sshcom", "-o", tmpfilename1,
- filename, NULL);
- setup_passphrases(NULL);
- test(0, "puttygen", tmpfilename1, "-o", tmpfilename2, NULL);
- filecmp(filename, tmpfilename2,
- "p->s->p clear %s", keytype->name);
- }
- /*
- * Check that mismatched passphrases cause an error.
- */
- setup_passphrases("sponge2", "sponge3", NULL);
- test(1, "puttygen", "-P", filename, NULL);
- /*
- * Put a passphrase back on.
- */
- setup_passphrases("sponge2", "sponge2", NULL);
- test(0, "puttygen", "-P", filename, NULL);
- /*
- * Export the private key into OpenSSH format, this time
- * while encrypted.
- */
- if (!supports_openssh && type_known_early) {
- /* We'll know far enough in advance that this combination
- * is going to fail that we never ask for the passphrase */
- setup_passphrases(NULL);
- } else {
- setup_passphrases("sponge2", NULL);
- }
- test(supports_openssh ? 0 : 1,
- "puttygen", "-O", "private-openssh", "-o", osfilename,
- filename, NULL);
- if (supports_openssh) {
- /*
- * List the fingerprint of the OpenSSH-formatted key.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", "-l", osfilename, "-o", tmpfilename1, NULL);
- check_fp(tmpfilename1, fps[SSH_FPTYPE_DEFAULT],
- "%s openssh encrypted fp", keytype->name);
- /*
- * List the public half of the OpenSSH-formatted key in
- * OpenSSH format.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", "-L", osfilename, NULL);
- /*
- * List the public half of the OpenSSH-formatted key in
- * IETF/ssh.com format.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", "-p", osfilename, NULL);
- }
- /*
- * Export the private key into ssh.com format, this time
- * while encrypted. For RSA1 keys, this should give an
- * error.
- */
- if (!supports_sshcom && type_known_early) {
- /* We'll know far enough in advance that this combination
- * is going to fail that we never ask for the passphrase */
- setup_passphrases(NULL);
- } else {
- setup_passphrases("sponge2", NULL);
- }
- test(supports_sshcom ? 0 : 1,
- "puttygen", "-O", "private-sshcom", "-o", scfilename,
- filename, NULL);
- if (supports_sshcom) {
- /*
- * List the fingerprint of the ssh.com-formatted key.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", "-l", scfilename, "-o", tmpfilename1, NULL);
- check_fp(tmpfilename1, fps[SSH_FPTYPE_DEFAULT],
- "%s ssh.com encrypted fp", keytype->name);
- /*
- * List the public half of the ssh.com-formatted key in
- * OpenSSH format.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", "-L", scfilename, NULL);
- /*
- * List the public half of the ssh.com-formatted key in
- * IETF/ssh.com format.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", "-p", scfilename, NULL);
- }
- if (supports_openssh && supports_sshcom) {
- /*
- * Convert from OpenSSH into ssh.com.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", osfilename, "-o", tmpfilename1,
- "-O", "private-sshcom", NULL);
- /*
- * Convert from ssh.com back into a PuTTY key,
- * supplying the same comment as we had before we
- * started to ensure the comparison works.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", tmpfilename1, "-C", "new-comment-2",
- "-o", tmpfilename2, NULL);
- /*
- * See if the PuTTY key thus generated is the same as
- * the original.
- */
- filecmp(filename, tmpfilename2,
- "p->o->s->p encrypted %s", keytype->name);
- /*
- * Convert from ssh.com to OpenSSH.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", scfilename, "-o", tmpfilename1,
- "-O", "private-openssh", NULL);
- /*
- * Convert from OpenSSH back into a PuTTY key,
- * supplying the same comment as we had before we
- * started to ensure the comparison works.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", tmpfilename1, "-C", "new-comment-2",
- "-o", tmpfilename2, NULL);
- /*
- * See if the PuTTY key thus generated is the same as
- * the original.
- */
- filecmp(filename, tmpfilename2,
- "p->s->o->p encrypted %s", keytype->name);
- /*
- * Finally, do a round-trip conversion between PuTTY
- * and ssh.com without involving OpenSSH, to test that
- * the key comment is preserved in that case.
- */
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", "-O", "private-sshcom", "-o", tmpfilename1,
- filename, NULL);
- setup_passphrases("sponge2", NULL);
- test(0, "puttygen", tmpfilename1, "-o", tmpfilename2, NULL);
- filecmp(filename, tmpfilename2,
- "p->s->p encrypted %s", keytype->name);
- }
- /*
- * Load with the wrong passphrase.
- */
- setup_passphrases("sponge8", NULL);
- test(1, "puttygen", "-C", "spurious-new-comment", filename, NULL);
- /*
- * Load a totally bogus file.
- */
- setup_passphrases(NULL);
- test(1, "puttygen", "-C", "spurious-new-comment", pubfilename, NULL);
- for (FingerprintType fptype = 0; fptype < SSH_N_FPTYPES; fptype++)
- sfree(fps[fptype]);
- if (remove_files) {
- remove(filename);
- remove(pubfilename);
- remove(osfilename);
- remove(scfilename);
- remove(tmpfilename1);
- remove(tmpfilename2);
- }
- }
- printf("%d passes, %d fails\n", passes, fails);
- return fails == 0 ? 0 : 1;
- }
|