X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/5c3f75ec49019d160806489824fc76652a2ef444..67a452f7a9d69723741b064f08d70462bc8f00e7:/dsig.c diff --git a/dsig.c b/dsig.c index 2aeb9ef..c379e94 100644 --- a/dsig.c +++ b/dsig.c @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: dsig.c,v 1.12 2004/04/17 09:58:37 mdw Exp $ + * $Id$ * * Verify signatures on distribuitions of files * * (c) 2000 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of Catacomb. * @@ -15,12 +15,12 @@ * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * Catacomb is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. - * + * * You should have received a copy of the GNU Library General Public * License along with Catacomb; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, @@ -485,8 +485,13 @@ static void blob(block *b, dstr *d) case T_DATE: case T_EXPIRE: DENSURE(d, 8); - STORE32(d->buf + d->len, ((b->t & ~MASK32) >> 16) >> 16); - STORE32(d->buf + d->len + 4, b->t); + if (b->t == KEXP_FOREVER) { + STORE32(d->buf + d->len, 0xffffffff); + STORE32(d->buf + d->len + 4, 0xffffffff); + } else { + STORE32(d->buf + d->len, ((b->t & ~MASK32) >> 16) >> 16); + STORE32(d->buf + d->len + 4, b->t); + } d->len += 8; break; case T_KEYID: @@ -580,30 +585,13 @@ static void bemit(block *b, FILE *fp, ghash *h, unsigned bin) if (fp && !bin) bwrite(b, fp); } - + /*----- Static variables --------------------------------------------------*/ static const char *keyring = "keyring"; /*----- Other shared functions --------------------------------------------*/ -/* --- @keyreport@ --- * - * - * Arguments: @const char *file@ = filename containing the error - * @int line@ = line number in file - * @const char *err@ = error text message - * @void *p@ = unimportant pointer - * - * Returns: --- - * - * Use: Reports errors during the opening of a key file. - */ - -static void keyreport(const char *file, int line, const char *err, void *p) -{ - moan("error in keyring `%s' at line `%s': %s", file, line, err); -} - /* --- @fhash@ --- * * * Arguments: @const gchash *c@ = pointer to hash class @@ -657,7 +645,7 @@ static void fhex(FILE *fp, const void *p, size_t sz) if (!sz) break; } -} +} /*----- Signature generation ----------------------------------------------*/ @@ -666,6 +654,7 @@ static int sign(int argc, char *argv[]) #define f_raw 1u #define f_bin 2u #define f_bogus 4u +#define f_nocheck 8u unsigned f = 0; const char *ki = "dsig"; @@ -694,9 +683,10 @@ static int sign(int argc, char *argv[]) { "output", OPTF_ARGREQ, 0, 'o' }, { "key", OPTF_ARGREQ, 0, 'k' }, { "expire", OPTF_ARGREQ, 0, 'e' }, + { "nocheck", OPTF_ARGREQ, 0, 'C' }, { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "+0vqb" "c:" "f:o:" "k:e:", opts, 0, 0, 0); + int i = mdwopt(argc, argv, "+0vqbC" "c:" "f:o:" "k:e:", opts, 0, 0, 0); if (i < 0) break; switch (i) { @@ -713,6 +703,9 @@ static int sign(int argc, char *argv[]) if (verb > 0) verb--; break; + case 'C': + f |= f_nocheck; + break; case 'c': c = optarg; break; @@ -737,11 +730,11 @@ static int sign(int argc, char *argv[]) } } if (optind != argc || (f & f_bogus)) - die(EXIT_FAILURE, "Usage: sign [-options]"); + die(EXIT_FAILURE, "Usage: sign [-OPTIONS]"); /* --- Locate the signing key --- */ - if (key_open(&kf, keyring, KOPEN_WRITE, keyreport, 0)) + if (key_open(&kf, keyring, KOPEN_WRITE, key_moan, 0)) die(EXIT_FAILURE, "couldn't open keyring `%s'", keyring); if ((k = key_bytag(&kf, ki)) == 0) die(EXIT_FAILURE, "couldn't find key `%s'", ki); @@ -754,7 +747,7 @@ static int sign(int argc, char *argv[]) /* --- Check the key --- */ - if ((err = s->ops->check(s)) != 0) + if (!(f & f_nocheck) && (err = s->ops->check(s)) != 0) moan("key `%s' fails check: %s", d.buf, err); /* --- Open files --- */ @@ -778,7 +771,7 @@ static int sign(int argc, char *argv[]) binit(&b); b.tag = T_IDENT; dstr_putf(&b.d, "%s, Catacomb version " VERSION, QUIS); bemit(&b, ofp, 0, f & f_bin); - + breset(&b); b.tag = T_KEYID; b.k = k->id; bemit(&b, ofp, 0, f & f_bin); @@ -876,6 +869,7 @@ static int sign(int argc, char *argv[]) #undef f_raw #undef f_bin #undef f_bogus +#undef f_nocheck } /*----- Signature verification --------------------------------------------*/ @@ -885,6 +879,7 @@ static int verify(int argc, char *argv[]) #define f_bogus 1u #define f_bin 2u #define f_ok 4u +#define f_nocheck 8u unsigned f = 0; unsigned verb = 1; @@ -903,9 +898,10 @@ static int verify(int argc, char *argv[]) static struct option opts[] = { { "verbose", 0, 0, 'v' }, { "quiet", 0, 0, 'q' }, + { "nocheck", 0, 0, 'C' }, { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "+vq", opts, 0, 0, 0); + int i = mdwopt(argc, argv, "+vqC", opts, 0, 0, 0); if (i < 0) break; switch (i) { @@ -916,6 +912,9 @@ static int verify(int argc, char *argv[]) if (verb) verb--; break; + case 'C': + f |= f_nocheck; + break; default: f |= f_bogus; break; @@ -924,11 +923,11 @@ static int verify(int argc, char *argv[]) argc -= optind; argv += optind; if ((f & f_bogus) || argc > 1) - die(EXIT_FAILURE, "Usage: verify [-qv] [file]"); + die(EXIT_FAILURE, "Usage: verify [-qvC] [FILE]"); /* --- Open the key file, and start reading the input file --- */ - if (key_open(&kf, keyring, KOPEN_READ, keyreport, 0)) + if (key_open(&kf, keyring, KOPEN_READ, key_moan, 0)) die(EXIT_FAILURE, "couldn't open keyring `%s'\n", keyring); if (argc < 1) fp = stdin; @@ -991,7 +990,7 @@ static int verify(int argc, char *argv[]) } s = getsig(k, "dsig", 0); - if (verb && (err = s->ops->check(s)) != 0) + if (!(f & f_nocheck) && verb && (err = s->ops->check(s)) != 0) printf("WARN public key fails check: %s", err); for (;;) { @@ -1011,7 +1010,7 @@ static int verify(int argc, char *argv[]) break; case T_EXPIRE: { time_t now = time(0); - if (b.t < now) { + if (b.t != KEXP_FOREVER && b.t < now) { if (verb > 1) puts("BAD signature has expired"); f |= f_bogus; @@ -1084,20 +1083,34 @@ done: #undef f_bogus #undef f_bin #undef f_ok +#undef f_nocheck } /*----- Main code ---------------------------------------------------------*/ -typedef struct cmd { - const char *name; - int (*func)(int /*argc*/, char */*argv*/[]); - const char *usage; - const char *help; -} cmd; +#define LISTS(LI) \ + LI("Lists", list, \ + listtab[i].name, listtab[i].name) \ + LI("Signature schemes", sig, \ + sigtab[i].name, sigtab[i].name) \ + LI("Hash functions", hash, \ + ghashtab[i], ghashtab[i]->name) + +MAKELISTTAB(listtab, LISTS) + +int cmd_show(int argc, char *argv[]) +{ + return (displaylists(listtab, argv + 1)); +} + +static int cmd_help(int, char **); static cmd cmdtab[] = { + { "help", cmd_help, "help [COMMAND...]" }, + { "show", cmd_show, "show [ITEM...]" }, { "sign", sign, - "sign [-0bqv] [-c comment] [-k tag] [-e expire] [-f file] [-o output]", + "sign [-0bqvC] [-c COMMENT] [-k TAG] [-e EXPIRE]\n\t\ +[-f FILE] [-o OUTPUT]", "\ Options:\n\ \n\ @@ -1105,6 +1118,7 @@ Options:\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\ +-C, --nocheck Don't check the private key.\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\ @@ -1112,77 +1126,46 @@ Options:\n\ -e, --expire=TIME The signature should expire after TIME.\n\ " }, { "verify", verify, - "verify [-qv] [file]", "\ + "verify [-qvC] [FILE]", "\ Options:\n\ \n\ -q, --quiet Produce fewer messages while working.\n\ -v, --verbose Produce more messages while working.\n\ +-C, --nocheck Don't check the public key.\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) +static int cmd_help(int argc, char **argv) { - 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); + sc_help(cmdtab, stdout, argv + 1); + return (0); } -static void version(FILE *fp) +void version(FILE *fp) { pquis(fp, "$, Catacomb version " VERSION "\n"); } static void usage(FILE *fp) { - pquis(fp, "Usage: $ [-k keyring] command [args]\n"); + pquis(fp, "Usage: $ [-k KEYRING] COMMAND [ARGS]\n"); } -static void help(FILE *fp, char **argv) +void help_global(FILE *fp) { - cmd *c; - - 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\ + 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->usage); - } +\n\ +Global command-line options:\n\ +\n\ +-h, --help [COMMAND...] Show this help message, or help for COMMANDs.\n\ +-v, --version Show program version number.\n\ +-u, --usage Show a terse usage message.\n\ +\n\ +-k, --keyring=FILE Read keys from FILE.\n", + fp); } /* --- @main@ --- * @@ -1224,7 +1207,7 @@ int main(int argc, char *argv[]) break; switch (i) { case 'h': - help(stdout, argv + optind); + sc_help(cmdtab, stdout, argv + optind); exit(0); break; case 'v': @@ -1253,7 +1236,7 @@ int main(int argc, char *argv[]) /* --- Dispatch to the correct subcommand handler --- */ - return (findcmd(argv[0])->func(argc, argv)); + return (findcmd(cmdtab, argv[0])->cmd(argc, argv)); #undef f_bogus }