X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/4bedc99bbbc9f88129cee9a084fc58cee8237942..16efd15b675c87d22a4fd9fb12d7bb26f2a36031:/dsig.c diff --git a/dsig.c b/dsig.c index 9818367..a34cca2 100644 --- a/dsig.c +++ b/dsig.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: dsig.c,v 1.1 2000/06/17 10:54:29 mdw Exp $ + * $Id: dsig.c,v 1.6 2000/12/06 20:33:27 mdw Exp $ * * Verify signatures on distribuitions of files * @@ -30,6 +30,22 @@ /*----- Revision history --------------------------------------------------* * * $Log: dsig.c,v $ + * Revision 1.6 2000/12/06 20:33:27 mdw + * Make flags be macros rather than enumerations, to ensure that they're + * unsigned. + * + * Revision 1.5 2000/10/08 12:12:09 mdw + * Shut up some warnings. + * + * Revision 1.4 2000/08/04 23:23:44 mdw + * Various fixes. + * + * Revision 1.3 2000/07/15 20:53:23 mdw + * More hash functions. Bug fix in getstring. + * + * Revision 1.2 2000/07/01 11:27:22 mdw + * Use new PKCS#1 padding functions rather than rolling by hand. + * * Revision 1.1 2000/06/17 10:54:29 mdw * Program to generate and verify signatures on multiple files. * @@ -52,17 +68,25 @@ #include #include -#include "dsa.h" #include "getdate.h" #include "grand.h" #include "ghash.h" #include "key.h" #include "key-data.h" -#include "md5.h" #include "noise.h" -#include "rmd160.h" + +#include "dsa.h" #include "rsa.h" +#include "pkcs1.h" + +#include "md4.h" +#include "md5.h" +#include "rmd128.h" +#include "rmd160.h" +#include "rmd256.h" +#include "rmd320.h" #include "sha.h" +#include "tiger.h" /*----- Digital signature algorithm ---------------------------------------*/ @@ -81,8 +105,10 @@ static int dsasign(key *k, const void *m, size_t msz, dstr *d) return (e); } sz = mp_octets(dp.dp.q); + if (sz < msz) + die(EXIT_FAILURE, "hash function too wide for this signing key"); DENSURE(d, sz * 2); - p = d->buf + d->len; + p = (octet *)d->buf + d->len; rand_get(RAND_GLOBAL, p, sz); dsa_sign(&dp.dp, dp.x, m, msz, p, sz, p, sz, p + sz, sz); d->len += sz * 2; @@ -97,6 +123,7 @@ static int dsaverify(key *k, const void *m, size_t msz, key_packstruct ks[DSA_PUBFETCHSZ]; key_packdef *kp; size_t sz; + const octet *p = s; int e; kp = key_fetchinit(dsa_pubfetch, ks, &dp); @@ -105,7 +132,7 @@ static int dsaverify(key *k, const void *m, size_t msz, return (e); } sz = ssz / 2; - e = dsa_verify(&dp.dp, dp.y, m, msz, s, sz, s + sz, sz); + e = dsa_verify(&dp.dp, dp.y, m, msz, p, sz, p + sz, sz); key_fetchdone(kp); return (e); } @@ -115,11 +142,10 @@ static int dsaverify(key *k, const void *m, size_t msz, static int rsasign(key *k, const void *m, size_t msz, dstr *d) { rsa_priv rp; + rsa_privctx rpc; + pkcs1 pk = { 0, 0, 0 }; key_packstruct ks[RSA_PRIVFETCHSZ]; key_packdef *kp; - octet *p; - size_t sz; - mp *x; int e; kp = key_fetchinit(rsa_privfetch, ks, &rp); @@ -127,22 +153,10 @@ static int rsasign(key *k, const void *m, size_t msz, dstr *d) key_fetchdone(kp); return (e); } - sz = mp_octets(rp.n); - if (sz < msz + 11) - die(EXIT_FAILURE, "key too small (help!)"); - DENSURE(d, sz); - p = d->buf + d->len; - memcpy(p + sz - msz, m, msz); - p[0] = 0; - p[1] = 1; - memset(p + 2, 0xff, sz - msz - 3); - p[sz - msz - 1] = 0; - memcpy(p + sz - msz, m, msz); - x = mp_loadb(MP_NEW, p, sz); - x = rsa_decrypt(&rp, x, x, &rand_global); - mp_storeb(x, p, sz); - d->len += sz; - mp_drop(x); + rsa_privcreate(&rpc, &rp, &rand_global); + if (rsa_sign(&rpc, m, msz, d, pkcs1_sigencode, &pk) < 0) + die(EXIT_FAILURE, "internal error in rsasign (key too small?)"); + rsa_privdestroy(&rpc); key_fetchdone(kp); return (0); } @@ -151,41 +165,26 @@ static int rsaverify(key *k, const void *m, size_t msz, const void *s, size_t ssz) { rsa_pub rp; + rsa_pubctx rpc; + pkcs1 pk = { 0, 0, 0 }; key_packstruct ks[RSA_PUBFETCHSZ]; key_packdef *kp; - octet *p; - size_t sz; - mp *x; - mpmont mm; int ok = 0; + dstr d = DSTR_INIT; int e; - int i; kp = key_fetchinit(rsa_pubfetch, ks, &rp); if ((e = key_fetch(kp, k)) != 0) { key_fetchdone(kp); return (e); } - x = mp_loadb(MP_NEW, s, ssz); - mpmont_create(&mm, rp.n); - x = mpmont_exp(&mm, x, x, rp.e); - mpmont_destroy(&mm); - sz = mp_octets(rp.n); - p = xmalloc(sz); - mp_storeb(x, p, sz); - mp_drop(x); + rsa_pubcreate(&rpc, &rp); + if (rsa_verify(&rpc, s, ssz, &d, pkcs1_sigdecode, &pk) > 0 && + msz == d.len && memcmp(d.buf, m, msz) == 0) + ok = 1; + dstr_destroy(&d); + rsa_pubdestroy(&rpc); key_fetchdone(kp); - if (msz + 11 >= sz || p[0] != 0 || p[1] != 1 || p[sz - msz - 1] != 0) - goto done; - for (i = 2; i < sz - msz - 1; i++) { - if (p[i] != 0xff) - goto done; - } - if (memcmp(m, p + sz - msz, msz) != 0) - goto done; - ok = 1; -done: - free(p); return (ok); } @@ -199,7 +198,8 @@ typedef struct sig { const void */*s*/, size_t /*ssz*/); } sig; -static const gchash *hashtab[] = { &rmd160, &sha, &md5, 0 }; +static const gchash *hashtab[] = { + &rmd160, &tiger, &sha, &rmd128, &rmd256, &rmd320, &md5, &md4, 0 }; static sig sigtab[] = { { "dsa", "dsig-dsa", dsasign, dsaverify }, { "rsa", "dsig-rsa", rsasign, rsaverify }, @@ -357,7 +357,7 @@ static int getstring(FILE *fp, dstr *d, unsigned raw) again: ch = getc(fp); - while (isspace((unsigned char)ch)) + while (isspace(ch)) ch = getc(fp); if (ch == '#') { do ch = getc(fp); while (ch != '\n' && ch != EOF); @@ -389,7 +389,7 @@ again: if (ch == EOF) break; switch (ch) { - case 'a': ch = '\n'; break; + case 'a': ch = '\a'; break; case 'b': ch = '\b'; break; case 'f': ch = '\f'; break; case 'n': ch = '\n'; break; @@ -398,6 +398,7 @@ again: case 'v': ch = '\v'; break; } DPUTC(d, ch); + ch = getc(fp); continue; } @@ -823,14 +824,14 @@ static void keyreport(const char *file, int line, const char *err, void *p) * * Arguments: @const gchash *c@ = pointer to hash class * @const char *file@ = file to hash - * @octet *b@ = pointer to output buffer + * @void *b@ = pointer to output buffer * * Returns: Zero if it worked, or nonzero for a system error. * * Use: Hashes a file. */ -static int fhash(const gchash *c, const char *file, octet *b) +static int fhash(const gchash *c, const char *file, void *b) { FILE *fp = fopen(file, "rb"); ghash *h = c->init(); @@ -879,11 +880,9 @@ static void fhex(FILE *fp, const void *p, size_t sz) static int sign(int argc, char *argv[]) { - enum { - f_raw = 1, - f_bin = 2, - f_bogus = 4 - }; +#define f_raw 1u +#define f_bin 2u +#define f_bogus 4u unsigned f = 0; const char *kt = 0; @@ -1121,17 +1120,19 @@ static int sign(int argc, char *argv[]) if (f & f_bogus) die(EXIT_FAILURE, "error(s) occurred while creating signature"); return (EXIT_SUCCESS); + +#undef f_raw +#undef f_bin +#undef f_bogus } /*----- Signature verification --------------------------------------------*/ static int verify(int argc, char *argv[]) { - enum { - f_bogus = 1, - f_bin = 2, - f_ok = 4 - }; +#define f_bogus 1u +#define f_bin 2u +#define f_ok 4u unsigned f = 0; unsigned verb = 1; @@ -1140,7 +1141,7 @@ static int verify(int argc, char *argv[]) sig *s = sigtab; const gchash *gch = &rmd160; dstr d = DSTR_INIT; - ghash *h; + ghash *h = 0; FILE *fp; block b; int e; @@ -1350,6 +1351,10 @@ done: puts("OK signature verified"); } return (f & f_bogus ? EXIT_FAILURE : EXIT_SUCCESS); + +#undef f_bogus +#undef f_bin +#undef f_ok } /*----- Main code ---------------------------------------------------------*/ @@ -1412,9 +1417,7 @@ int main(int argc, char *argv[]) cmd *c = 0, *cc = 0; size_t n; - enum { - f_bogus = 1 - }; +#define f_bogus 1u /* --- Initialize the library --- */ @@ -1482,6 +1485,8 @@ int main(int argc, char *argv[]) if (!cc) die(EXIT_FAILURE, "unknown command `%s'", argv[0]); return (cc->func(argc, argv)); + +#undef f_bogus } /*----- That's all, folks -------------------------------------------------*/