=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/signify/signify.c,v retrieving revision 1.84 retrieving revision 1.85 diff -c -r1.84 -r1.85 *** src/usr.bin/signify/signify.c 2014/05/15 13:14:15 1.84 --- src/usr.bin/signify/signify.c 2014/05/16 16:18:33 1.85 *************** *** 1,4 **** ! /* $OpenBSD: signify.c,v 1.84 2014/05/15 13:14:15 espie Exp $ */ /* * Copyright (c) 2013 Ted Unangst * --- 1,4 ---- ! /* $OpenBSD: signify.c,v 1.85 2014/05/16 16:18:33 espie Exp $ */ /* * Copyright (c) 2013 Ted Unangst * *************** *** 31,36 **** --- 31,41 ---- #include #include "crypto_api.h" + #ifndef VERIFY_ONLY + #include + #include + #include + #endif #define SIGBYTES crypto_sign_ed25519_BYTES #define SECRETBYTES crypto_sign_ed25519_SECRETKEYBYTES *************** *** 538,551 **** char algo[32]; }; static void ! recodehash(char *hash) { uint8_t data[HASHBUFSIZE / 2]; int i, rv; ! if (strlen(hash)+1 == SHA256_DIGEST_STRING_LENGTH || ! strlen(hash)+1 == SHA512_DIGEST_STRING_LENGTH) return; if ((rv = b64_pton(hash, data, sizeof(data))) == -1) errx(1, "invalid base64 encoding"); --- 543,570 ---- char algo[32]; }; + static void * + ecalloc(size_t s1, size_t s2, void *data) + { + void *p = calloc(s1, s2); + if (!p) + err(1, "calloc"); + return p; + } + static void ! efree(void *p, void *data) { + free(p); + } + + static void + recodehash(char *hash, size_t len) + { uint8_t data[HASHBUFSIZE / 2]; int i, rv; ! if (strlen(hash) == len) return; if ((rv = b64_pton(hash, data, sizeof(data))) == -1) errx(1, "invalid base64 encoding"); *************** *** 553,645 **** snprintf(hash + i * 2, HASHBUFSIZE - i * 2, "%2.2x", data[i]); } static void verifychecksums(char *msg, int argc, char **argv, int quiet) { ! char buf[1024]; char *line, *endline; ! struct checksum *checksums = NULL, *c = NULL; ! int nchecksums = 0, checksumspace = 0; ! int i, j, rv, uselist, count, hasfailed; ! int *failures; line = msg; while (line && *line) { - if (nchecksums == checksumspace) { - checksumspace = 2 * (nchecksums + 1); - if (!(checksums = reallocarray(checksums, - checksumspace, sizeof(*checksums)))) - err(1, "realloc"); - } - c = &checksums[nchecksums++]; if ((endline = strchr(line, '\n'))) *endline++ = '\0'; ! rv = sscanf(line, "%31s %1023s = %223s", ! c->algo, buf, c->hash); ! if (rv != 3 || buf[0] != '(' || buf[strlen(buf) - 1] != ')') errx(1, "unable to parse checksum line %s", line); ! recodehash(c->hash); ! buf[strlen(buf) - 1] = 0; ! strlcpy(c->file, buf + 1, sizeof(c->file)); line = endline; ! } ! ! if (argc) { ! uselist = 0; ! count = argc; ! } else { ! uselist = 1; ! count = nchecksums; ! } ! if (!(failures = calloc(count, sizeof(*failures)))) ! err(1, "calloc"); ! for (i = 0; i < count; i++) { ! if (uselist) { ! c = &checksums[i]; } else { ! for (j = 0; j < nchecksums; j++) { ! c = &checksums[j]; ! if (strcmp(c->file, argv[i]) == 0) ! break; } - if (j == nchecksums) { - failures[i] = 1; - continue; - } } ! if (strcmp(c->algo, "SHA256") == 0) { ! if (!SHA256File(c->file, buf)) { ! failures[i] = 1; ! continue; } ! } else if (strcmp(c->algo, "SHA512") == 0) { ! if (!SHA512File(c->file, buf)) { ! failures[i] = 1; ! continue; ! } ! } else { ! errx(1, "can't handle algorithm %s", c->algo); ! } ! if (strcmp(c->hash, buf) != 0) { ! failures[i] = 1; ! continue; ! } ! if (!quiet) ! printf("%s: OK\n", c->file); } - hasfailed = 0; - for (i = 0; i < count; i++) { - if (failures[i]) { - fprintf(stderr, "%s: FAIL\n", - uselist ? checksums[i].file : argv[i]); - hasfailed = 1; - } - } if (hasfailed) exit(1); - free(checksums); - free(failures); } static void --- 572,663 ---- snprintf(hash + i * 2, HASHBUFSIZE - i * 2, "%2.2x", data[i]); } + static int + verifychecksum(struct checksum *c, int quiet) + { + char buf[HASHBUFSIZE]; + if (strcmp(c->algo, "SHA256") == 0) { + recodehash(c->hash, SHA256_DIGEST_STRING_LENGTH-1); + if (!SHA256File(c->file, buf)) + return 0; + } else if (strcmp(c->algo, "SHA512") == 0) { + recodehash(c->hash, SHA512_DIGEST_STRING_LENGTH-1); + if (!SHA512File(c->file, buf)) + return 0; + } else { + errx(1, "can't handle algorithm %s", c->algo); + } + if (strcmp(c->hash, buf) != 0) { + return 0; + } + if (!quiet) + printf("%s: OK\n", c->file); + return 1; + } + static void verifychecksums(char *msg, int argc, char **argv, int quiet) { ! ! struct ohash_info info = { 0, NULL, ecalloc, efree, NULL }; ! struct ohash myh; ! unsigned int i; ! struct checksum c; char *line, *endline; ! int hasfailed = 0; ! int rv; ! const char *e; ! unsigned int slot; + + if (argc) { + ohash_init(&myh, 6, &info); + for (i = 0; i < argc; i++) { + slot = ohash_qlookup(&myh, argv[i]); + e = ohash_find(&myh, slot); + if (e == NULL) + ohash_insert(&myh, slot, argv[i]); + } + } + line = msg; while (line && *line) { if ((endline = strchr(line, '\n'))) *endline++ = '\0'; ! rv = sscanf(line, "%31s (%1023s = %223s", ! c.algo, c.file, c.hash); ! if (rv != 3 || c.file[0] == 0 || c.file[strlen(c.file)-1] != ')') errx(1, "unable to parse checksum line %s", line); ! c.file[strlen(c.file) - 1] = 0; line = endline; ! if (argc) { ! slot = ohash_qlookup(&myh, c.file); ! e = ohash_find(&myh, slot); ! if (e != NULL) { ! if (verifychecksum(&c, quiet)) ! ohash_remove(&myh, slot); ! } } else { ! if (!verifychecksum(&c, quiet)) { ! fprintf(stderr, "%s: FAIL\n", c.file); ! hasfailed = 1; } } + } ! if (argc) { ! for (i = 0; i < argc; i++) { ! slot = ohash_qlookup(&myh, argv[i]); ! e = ohash_find(&myh, slot); ! if (e != NULL) { ! fprintf(stderr, "%s: FAIL\n", argv[i]); ! hasfailed = 1; } ! } ! ohash_delete(&myh); } if (hasfailed) exit(1); } static void