From: Hubert Feurstein <h.feurstein@xxxxxxxxx> Signed-off-by: Hubert Feurstein <h.feurstein@xxxxxxxxx> [EB]: reworked based on Sascha's comments and tested with md5sum Signed-off-by: Eric Bénard <eric@xxxxxxxxxx> --- commands/digest.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 110 insertions(+), 10 deletions(-) diff --git a/commands/digest.c b/commands/digest.c index 092fda2..2a982e5 100644 --- a/commands/digest.c +++ b/commands/digest.c @@ -23,26 +23,99 @@ #include <fcntl.h> #include <errno.h> #include <xfuncs.h> +#include <libfile.h> #include <malloc.h> #include <digest.h> +#include <linux/ctype.h> +#include <getopt.h> + +static inline unsigned char parse_hexchar(char c) +{ + if (!isxdigit(c)) + return 0; + + return isdigit(c) ? (c - '0') : ((islower(c) ? toupper(c) : c) - 'A' + 0xA); +} + +static inline unsigned char parse_hexbyte(const char *p) +{ + return (parse_hexchar(*p) << 4) | parse_hexchar(*(p + 1)); +} + +static unsigned char *parse_hash(int hash_len, const char *hexstr) +{ + int i; + unsigned char *p; + + p = calloc(hash_len, sizeof(unsigned char)); + if (!p) { + perror("calloc"); + return NULL; + } + + for (i = 0; i < hash_len; i++) + p[i] = parse_hexbyte(&hexstr[i * 2]); + + return p; +} static int do_digest(char *algorithm, int argc, char *argv[]) { struct digest *d; int ret = 0; int i; - unsigned char *hash; + unsigned char *hash = NULL; + int opt; + unsigned char *verify_hash = NULL; + int verify = 0; + int min_argc = 2; + int len = 0; + ssize_t bufsz; d = digest_get_by_name(algorithm); BUG_ON(!d); - if (argc < 2) - return COMMAND_ERROR_USAGE; + while ((opt = getopt(argc, argv, "v:V:")) > 0) { + switch (opt) { + case 'v': + verify++; + free(verify_hash); + hash = xstrdup(optarg); + len = strlen(hash); + break; + case 'V': + verify++; + free(verify_hash); + hash = read_file(optarg, &bufsz); + len = bufsz; + break; + default: + ret = COMMAND_ERROR_USAGE; + goto out; + } + + if (verify == 1 && (d->length * 2) <= len && hash != NULL) { + min_argc += 2; + verify_hash = parse_hash(d->length, hash); + if (!verify_hash) + return -ENOMEM; + free(hash); + } else + return COMMAND_ERROR_USAGE; + } + + if (argc < min_argc) { + ret = COMMAND_ERROR_USAGE; + goto out; + } + + argv += min_argc - 2; hash = calloc(d->length, sizeof(unsigned char)); if (!hash) { perror("calloc"); - return COMMAND_ERROR_USAGE; + ret = -ENOMEM; + goto out; } argv++; @@ -60,17 +133,32 @@ static int do_digest(char *algorithm, int argc, char *argv[]) if (digest_file_window(d, filename, hash, start, size) < 0) { ret = 1; } else { - for (i = 0; i < d->length; i++) + for (i = 0; i < d->length; i++) { printf("%02x", hash[i]); + if (verify > 0 && hash[i] != verify_hash[i]) + verify = -1; + } - printf(" %s\t0x%08llx ... 0x%08llx\n", + printf(" %s\t0x%08llx ... 0x%08llx", filename, start, start + size); + + if (verify < 0) { + printf(" ** ERROR ** "); + ret = 1; + } + + printf("\n"); + + if (verify) + break; } argv++; } +out: free(hash); + free(verify_hash); return ret; } @@ -84,12 +172,15 @@ static int do_md5(int argc, char *argv[]) BAREBOX_CMD_HELP_START(md5sum) BAREBOX_CMD_HELP_TEXT("Calculate a MD5 digest over a FILE or a memory area.") +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT ("-v hash", "verify") +BAREBOX_CMD_HELP_OPT ("-V hash-file", "verify hash file") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(md5sum) .cmd = do_md5, BAREBOX_CMD_DESC("calculate MD5 checksum") - BAREBOX_CMD_OPTS("FILE|AREA...") + BAREBOX_CMD_OPTS("[-vV] FILE|AREA...") BAREBOX_CMD_GROUP(CMD_GRP_FILE) BAREBOX_CMD_HELP(cmd_md5sum_help) BAREBOX_CMD_END @@ -105,12 +196,15 @@ static int do_sha1(int argc, char *argv[]) BAREBOX_CMD_HELP_START(sha1sum) BAREBOX_CMD_HELP_TEXT("Calculate a SHA1 digest over a FILE or a memory area.") +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT ("-v hash", "verify") +BAREBOX_CMD_HELP_OPT ("-V hash-file", "verify hash file") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(sha1sum) .cmd = do_sha1, BAREBOX_CMD_DESC("calculate SHA1 digest") - BAREBOX_CMD_OPTS("FILE|AREA") + BAREBOX_CMD_OPTS("[-vV] FILE|AREA") BAREBOX_CMD_GROUP(CMD_GRP_FILE) BAREBOX_CMD_HELP(cmd_sha1sum_help) BAREBOX_CMD_END @@ -126,12 +220,15 @@ static int do_sha224(int argc, char *argv[]) BAREBOX_CMD_HELP_START(sha224sum) BAREBOX_CMD_HELP_TEXT("Calculate a SHA224 digest over a FILE or a memory area.") +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT ("-v hash", "verify") +BAREBOX_CMD_HELP_OPT ("-V hash-file", "verify hash file") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(sha224sum) .cmd = do_sha224, BAREBOX_CMD_DESC("calculate SHA224 digest") - BAREBOX_CMD_OPTS("FILE|AREA") + BAREBOX_CMD_OPTS("[-vV] FILE|AREA") BAREBOX_CMD_GROUP(CMD_GRP_FILE) BAREBOX_CMD_HELP(cmd_sha224sum_help) BAREBOX_CMD_END @@ -147,12 +244,15 @@ static int do_sha256(int argc, char *argv[]) BAREBOX_CMD_HELP_START(sha256sum) BAREBOX_CMD_HELP_TEXT("Calculate a SHA256 digest over a FILE or a memory area.") +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT ("-v hash", "verify") +BAREBOX_CMD_HELP_OPT ("-V hash-file", "verify hash file") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(sha256sum) .cmd = do_sha256, BAREBOX_CMD_DESC("calculate SHA256 digest") - BAREBOX_CMD_OPTS("FILE|AREA") + BAREBOX_CMD_OPTS("[-vV] FILE|AREA") BAREBOX_CMD_GROUP(CMD_GRP_FILE) BAREBOX_CMD_HELP(cmd_sha256sum_help) BAREBOX_CMD_END -- 1.9.3 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox