From bd5efd74a96ea9e7ccad0577bc4d94df25109f99 Mon Sep 17 00:00:00 2001 From: mdw Date: Fri, 23 Feb 2001 09:04:17 +0000 Subject: [PATCH] Add new hash functions. Provide full help for subcommands. Run the hash function over parts of the header in a canonical order. --- dsig.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 34 deletions(-) diff --git a/dsig.c b/dsig.c index a34cca2..c5eb5af 100644 --- a/dsig.c +++ b/dsig.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: dsig.c,v 1.6 2000/12/06 20:33:27 mdw Exp $ + * $Id: dsig.c,v 1.7 2001/02/23 09:04:17 mdw Exp $ * * Verify signatures on distribuitions of files * @@ -30,6 +30,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: dsig.c,v $ + * Revision 1.7 2001/02/23 09:04:17 mdw + * Add new hash functions. Provide full help for subcommands. Run the + * hash function over parts of the header in a canonical order. + * * Revision 1.6 2000/12/06 20:33:27 mdw * Make flags be macros rather than enumerations, to ensure that they're * unsigned. @@ -79,6 +83,7 @@ #include "rsa.h" #include "pkcs1.h" +#include "md2.h" #include "md4.h" #include "md5.h" #include "rmd128.h" @@ -86,6 +91,9 @@ #include "rmd256.h" #include "rmd320.h" #include "sha.h" +#include "sha256.h" +#include "sha384.h" +#include "sha512.h" #include "tiger.h" /*----- Digital signature algorithm ---------------------------------------*/ @@ -199,7 +207,8 @@ typedef struct sig { } sig; static const gchash *hashtab[] = { - &rmd160, &tiger, &sha, &rmd128, &rmd256, &rmd320, &md5, &md4, 0 }; + &rmd160, &tiger, &sha, &sha256, &sha384, &sha512, + &rmd128, &rmd256, &rmd320, &md5, &md4, &md2, 0 }; static sig sigtab[] = { { "dsa", "dsig-dsa", dsasign, dsaverify }, { "rsa", "dsig-rsa", rsasign, rsaverify }, @@ -1013,6 +1022,8 @@ static int sign(int argc, char *argv[]) ofile, strerror(errno)); } + h = gch->init(); + /* --- Emit the start of the output --- */ binit(&b); b.tag = T_IDENT; @@ -1020,20 +1031,19 @@ static int sign(int argc, char *argv[]) bemit(&b, ofp, 0, f & f_bin); breset(&b); b.tag = T_SIGALG; DPUTS(&b.d, s->name); - bemit(&b, ofp, 0, f & f_bin); + bemit(&b, ofp, h, f & f_bin); breset(&b); b.tag = T_HASHALG; DPUTS(&b.d, gch->name); - bemit(&b, ofp, 0, f & f_bin); + bemit(&b, ofp, h, f & f_bin); breset(&b); b.tag = T_KEYID; b.k = k->id; - bemit(&b, ofp, 0, f & f_bin); + bemit(&b, ofp, h, f & f_bin); /* --- Start hashing, and emit the datestamps and things --- */ { time_t now = time(0); - h = gch->init(); breset(&b); b.tag = T_DATE; b.t = now; bemit(&b, ofp, h, f & f_bin); if (exp == KEXP_EXPIRE) exp = now + 86400 * 28; @@ -1252,11 +1262,25 @@ static int verify(int argc, char *argv[]) /* --- Initialize the hash function and start reading hashed packets --- */ h = gch->init(); + if (!k) { if (verb) puts("FAIL no keyid packet found"); exit(EXIT_FAILURE); } + + { + block bb; + binit(&bb); + breset(&bb); bb.tag = T_SIGALG; DPUTS(&bb.d, s->name); + bemit(&bb, 0, h, 0); + breset(&bb); bb.tag = T_HASHALG; DPUTS(&bb.d, gch->name); + bemit(&bb, 0, h, 0); + breset(&bb); bb.tag = T_KEYID; bb.k = k->id; + bemit(&bb, 0, h, 0); + bdestroy(&bb); + } + for (;;) { switch (e) { case T_COMMENT: @@ -1362,6 +1386,7 @@ done: typedef struct cmd { const char *name; int (*func)(int /*argc*/, char */*argv*/[]); + const char *usage; const char *help; } cmd; @@ -1370,13 +1395,64 @@ static cmd cmdtab[] = { /* "manifest [-0] [-o output]" }, */ { "sign", sign, "sign [-options]\n\ - [-0v] [-a alg] [-h hash] [-t keytype] [-i keyid]\n\ - [-e expire] [-f file] [-o output]" }, + [-0bqv] [-a alg] [-h hash] [-t keytype] [-i keyid]\n\ + [-e expire] [-f file] [-o output]", "\ +Options:\n\ +\n\ +-0, --null Read null-terminated filenames from stdin.\n\ +-b, --binary Produce a binary output file.\n\ +-q, --quiet Produce fewer messages while working.\n\ +-v, --verbose Produce more messages while working.\n\ +-a, --algorithm=SIGALG Use the SIGALG signature algorithm.\n\ +-h, --hash=HASHASL Use the HASHALG message digest algorithm.\n\ +-c, --comment=COMMENT Include COMMENT in the output file.\n\ +-f, --file=FILE Read filenames to hash from FILE.\n\ +-o, --output=FILE Write the signed result to FILE.\n\ +-t, --keytype=TYPE Use a key with type TYPE to do the signing.\n\ +-i, --keyid=ID Use the key with the given ID to do the signing.\n\ +-e, --expire=TIME The signature should expire after TIME.\n\ +" }, { "verify", verify, - "verify [-qv] [file]" }, + "verify [-qv] [file]", "\ +Options:\n\ +\n\ +-q, --quiet Produce fewer messages while working.\n\ +-v, --verbose Produce more messages while working.\n\ +" }, { 0, 0, 0 } }; +/* --- @findcmd@ --- * + * + * Arguments: @const char *name@ = a command name + * + * Returns: Pointer to the command structure. + * + * Use: Looks up a command by name. If the command isn't found, an + * error is reported and the program is terminated. + */ + +static cmd *findcmd(const char *name) +{ + cmd *c, *chosen = 0; + size_t sz = strlen(name); + + for (c = cmdtab; c->name; c++) { + if (strncmp(name, c->name, sz) == 0) { + if (c->name[sz] == 0) { + chosen = c; + break; + } else if (chosen) + die(EXIT_FAILURE, "ambiguous command name `%s'", name); + else + chosen = c; + } + } + if (!chosen) + die(EXIT_FAILURE, "unknown command name `%s'", name); + return (chosen); +} + static void version(FILE *fp) { pquis(fp, "$, Catacomb version " VERSION "\n"); @@ -1387,17 +1463,27 @@ static void usage(FILE *fp) pquis(fp, "Usage: $ [-k keyring] command [args]\n"); } -static void help(FILE *fp) +static void help(FILE *fp, char **argv) { cmd *c; - version(fp); - fputc('\n', fp); - usage(fp); - fputs("\n\ + + if (*argv) { + c = findcmd(*argv); + fprintf(fp, "Usage: %s [-k keyring] %s\n", QUIS, c->usage); + if (c->help) { + fputc('\n', fp); + fputs(c->help, fp); + } + } else { + version(fp); + fputc('\n', fp); + usage(fp); + fputs("\n\ Create and verify signatures on lists of files.\n\ \n", fp); - for (c = cmdtab; c->name; c++) - fprintf(fp, "%s\n", c->help); + for (c = cmdtab; c->name; c++) + fprintf(fp, "%s\n", c->usage); + } } /* --- @main@ --- * @@ -1414,8 +1500,6 @@ Create and verify signatures on lists of files.\n\ int main(int argc, char *argv[]) { unsigned f = 0; - cmd *c = 0, *cc = 0; - size_t n; #define f_bogus 1u @@ -1441,7 +1525,7 @@ int main(int argc, char *argv[]) break; switch (i) { case 'h': - help(stdout); + help(stdout, argv + optind); exit(0); break; case 'v': @@ -1470,21 +1554,7 @@ int main(int argc, char *argv[]) /* --- Dispatch to the correct subcommand handler --- */ - n = strlen(argv[0]); - for (c = cmdtab; c->name; c++) { - if (strncmp(argv[0], c->name, n) == 0) { - if (c->name[n] == 0) { - cc = c; - break; - } else if (cc) - die(EXIT_FAILURE, "ambiguous command name `%s'", argv[0]); - else - cc = c; - } - } - if (!cc) - die(EXIT_FAILURE, "unknown command `%s'", argv[0]); - return (cc->func(argc, argv)); + return (findcmd(argv[0])->func(argc, argv)); #undef f_bogus } -- 2.11.0