X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/c65df27983057ec76ed0e72bb370f9a5ae7dad28..cd6eca4375f46a35b93e2fea4b0428a23b451aa3:/dsig.c diff --git a/dsig.c b/dsig.c index c45d204..d09b675 100644 --- a/dsig.c +++ b/dsig.c @@ -7,7 +7,7 @@ * (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, @@ -29,6 +29,8 @@ /*----- Header files ------------------------------------------------------*/ +#define _FILE_OFFSET_BITS 64 + #include "config.h" #include @@ -585,33 +587,17 @@ 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 + * @unsigned f@ = flags * @const char *file@ = file to hash * @void *b@ = pointer to output buffer * @@ -620,9 +606,12 @@ static void keyreport(const char *file, int line, const char *err, void *p) * Use: Hashes a file. */ -static int fhash(const gchash *c, const char *file, void *b) +#define FHF_PROGRESS 256u + +static int fhash(const gchash *c, unsigned f, const char *file, void *b) { FILE *fp = fopen(file, "rb"); + fprogress ff; ghash *h = GH_INIT(c); char buf[4096]; size_t sz; @@ -630,10 +619,16 @@ static int fhash(const gchash *c, const char *file, void *b) if (!fp) return (-1); - while ((sz = fread(buf, 1, sizeof(buf), fp)) > 0) + if (f & FHF_PROGRESS) { + if (fprogress_init(&ff, file, fp)) return (-1); + } + while ((sz = fread(buf, 1, sizeof(buf), fp)) > 0) { GH_HASH(h, buf, sz); + if (f & FHF_PROGRESS) fprogress_update(&ff, sz); + } if (ferror(fp)) rc = -1; + if (f & FHF_PROGRESS) fprogress_done(&ff); GH_DONE(h, b); GH_DESTROY(h); fclose(fp); @@ -662,7 +657,7 @@ static void fhex(FILE *fp, const void *p, size_t sz) if (!sz) break; } -} +} /*----- Signature generation ----------------------------------------------*/ @@ -671,6 +666,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"; @@ -693,15 +689,17 @@ static int sign(int argc, char *argv[]) { "null", 0, 0, '0' }, { "binary", 0, 0, 'b' }, { "verbose", 0, 0, 'v' }, + { "progress", 0, 0, 'p' }, { "quiet", 0, 0, 'q' }, { "comment", OPTF_ARGREQ, 0, 'c' }, { "file", OPTF_ARGREQ, 0, 'f' }, { "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, "+0vpqbC" "c:" "f:o:" "k:e:", opts, 0, 0, 0); if (i < 0) break; switch (i) { @@ -714,10 +712,16 @@ static int sign(int argc, char *argv[]) case 'v': verb++; break; + case 'p': + f |= FHF_PROGRESS; + break; case 'q': if (verb > 0) verb--; break; + case 'C': + f |= f_nocheck; + break; case 'c': c = optarg; break; @@ -746,7 +750,7 @@ static int sign(int argc, char *argv[]) /* --- 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); @@ -759,7 +763,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 --- */ @@ -783,7 +787,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); @@ -823,7 +827,7 @@ static int sign(int argc, char *argv[]) break; b.tag = T_FILE; DENSURE(&b.b, GH_CLASS(s->h)->hashsz); - if (fhash(GH_CLASS(s->h), b.d.buf, b.b.buf)) { + if (fhash(GH_CLASS(s->h), f, b.d.buf, b.b.buf)) { moan("Error reading `%s': %s", b.d.buf, strerror(errno)); f |= f_bogus; } else { @@ -881,6 +885,7 @@ static int sign(int argc, char *argv[]) #undef f_raw #undef f_bin #undef f_bogus +#undef f_nocheck } /*----- Signature verification --------------------------------------------*/ @@ -890,6 +895,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; @@ -907,20 +913,28 @@ static int verify(int argc, char *argv[]) for (;;) { static struct option opts[] = { { "verbose", 0, 0, 'v' }, + { "progress", 0, 0, 'p' }, { "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, "+vpqC", opts, 0, 0, 0); if (i < 0) break; switch (i) { case 'v': verb++; break; + case 'p': + f |= FHF_PROGRESS; + break; case 'q': if (verb) verb--; break; + case 'C': + f |= f_nocheck; + break; default: f |= f_bogus; break; @@ -929,11 +943,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; @@ -996,7 +1010,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 (;;) { @@ -1031,7 +1045,7 @@ static int verify(int argc, char *argv[]) case T_FILE: DRESET(&d); DENSURE(&d, GH_CLASS(s->h)->hashsz); - if (fhash(GH_CLASS(s->h), b.d.buf, d.buf)) { + if (fhash(GH_CLASS(s->h), f, b.d.buf, d.buf)) { if (verb > 1) { printf("BAD error reading file `%s': %s\n", b.d.buf, strerror(errno)); @@ -1089,6 +1103,7 @@ done: #undef f_bogus #undef f_bin #undef f_ok +#undef f_nocheck } /*----- Main code ---------------------------------------------------------*/ @@ -1114,7 +1129,7 @@ static cmd cmdtab[] = { { "help", cmd_help, "help [COMMAND...]" }, { "show", cmd_show, "show [ITEM...]" }, { "sign", sign, - "sign [-0bqv] [-c COMMENT] [-k TAG] [-e EXPIRE]\n\t\ + "sign [-0bpqvC] [-c COMMENT] [-k TAG] [-e EXPIRE]\n\t\ [-f FILE] [-o OUTPUT]", "\ Options:\n\ @@ -1123,6 +1138,8 @@ 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\ +-p, --progress Show progress on large files.\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\ @@ -1130,11 +1147,13 @@ Options:\n\ -e, --expire=TIME The signature should expire after TIME.\n\ " }, { "verify", verify, - "verify [-qv] [FILE]", "\ + "verify [-pqvC] [FILE]", "\ Options:\n\ \n\ -q, --quiet Produce fewer messages while working.\n\ -v, --verbose Produce more messages while working.\n\ +-p, --progress Show progress on large files.\n\ +-C, --nocheck Don't check the public key.\n\ " }, { 0, 0, 0 } };