summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2007-03-27 13:12:42 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2007-03-27 13:12:42 +0000
commit71c0f132bf0399a168fea0e56e09df4caf6de600 (patch)
treeec4c36cdece0aec94fd1701f446b622bff548b31
parentff184747802715e4e338d270610d089573eabca4 (diff)
Add base64 support to cksum and friends. Output encoding can
be set globally or on a per-algorithm basis when using multiple hash functions. OK espie@ simon@ deraadt@; man help from jmc@
-rw-r--r--bin/md5/cksum.137
-rw-r--r--bin/md5/md5.16
-rw-r--r--bin/md5/md5.c315
-rw-r--r--bin/md5/rmd160.16
-rw-r--r--bin/md5/sha1.16
5 files changed, 262 insertions, 108 deletions
diff --git a/bin/md5/cksum.1 b/bin/md5/cksum.1
index 75fa75d6d28..4bcdcb04626 100644
--- a/bin/md5/cksum.1
+++ b/bin/md5/cksum.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: cksum.1,v 1.13 2007/03/20 12:06:48 thib Exp $
+.\" $OpenBSD: cksum.1,v 1.14 2007/03/27 13:12:41 millert Exp $
.\"
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -42,7 +42,7 @@
.Sh SYNOPSIS
.Nm cksum
.Bk -words
-.Op Fl pqrtx
+.Op Fl bpqrtx
.Op Fl a Ar algorithms
.Op Fl c Op Ar checklist ...
.Op Fl o Ar 1 | 2
@@ -111,8 +111,39 @@ Multiple algorithms may be specified, separated by a comma or whitespace.
Additionally, multiple
.Fl a
options may be specified on the command line.
-If an algorithm is repeated, only the first instance is used.
Case is ignored when matching algorithms.
+The output format may be specified on a per-algorithm basis
+by using a single-character suffix, e.g.\&
+.Dq sha256b .
+If the algorithm has a
+.Sq b
+suffix, the checksum will be output in base64 format.
+If the algorithm has an
+.Sq x
+suffix, the checksum will be output in hex format.
+If an algorithm with the same output format is repeated,
+only the first instance is used.
+Note that output format suffixes are not supported
+for the
+.Ar cksum ,
+.Ar sum
+and
+.Ar sysvsum
+algorithms.
+.It Fl b
+Output checksums in base64 notation, not hexadecimal by
+default.
+A
+.Sq b
+or
+.Sq x
+suffix on the algorithm will override this default.
+This option is ignored for the
+.Ar cksum ,
+.Ar sum
+and
+.Ar sysvsum
+algorithms, which do not use hexadecimal output.
.It Fl c Op Ar checklist ...
Compares all checksums contained in the file
.Ar checklist
diff --git a/bin/md5/md5.1 b/bin/md5/md5.1
index 86734d07cba..ef13ac1ce63 100644
--- a/bin/md5/md5.1
+++ b/bin/md5/md5.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: md5.1,v 1.24 2006/11/19 17:09:15 jmc Exp $
+.\" $OpenBSD: md5.1,v 1.25 2007/03/27 13:12:41 millert Exp $
.\"
.\" Copyright (c) 2003, 2004, 2006 Todd C. Miller <Todd.Miller@courtesan.com>
.\"
@@ -26,7 +26,7 @@
.Nd calculate a message-digest fingerprint (checksum) for a file
.Sh SYNOPSIS
.Nm md5
-.Op Fl pqrtx
+.Op Fl bpqrtx
.Op Fl c Op Ar checklist ...
.Op Fl s Ar string
.Op Ar
@@ -53,6 +53,8 @@ such as
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl b
+Output checksums in base64 notation, not hexidecimal.
.It Xo
.Fl c
.Op Ar checklist ...
diff --git a/bin/md5/md5.c b/bin/md5/md5.c
index 8cd344b1756..13a0d6c7315 100644
--- a/bin/md5/md5.c
+++ b/bin/md5/md5.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: md5.c,v 1.40 2007/03/20 12:06:48 thib Exp $ */
+/* $OpenBSD: md5.c,v 1.41 2007/03/27 13:12:41 millert Exp $ */
/*
* Copyright (c) 2001,2003,2005-2006 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -21,9 +21,12 @@
*/
#include <sys/param.h>
+#include <sys/queue.h>
+#include <netinet/in.h>
#include <ctype.h>
#include <err.h>
#include <fcntl.h>
+#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -37,8 +40,8 @@
#include <sha2.h>
#include <crc.h>
-#define STYLE_HASH 0
-#define STYLE_CKSUM 1
+#define STYLE_NORMAL 0
+#define STYLE_REVERSE 1
#define STYLE_TERSE 2
#define MAX_DIGEST_LEN 128
@@ -57,147 +60,211 @@ union ANY_CTX {
};
/* Default print style for hash and chksum functions. */
-int style_hash = STYLE_HASH;
-int style_cksum = STYLE_CKSUM;
+int style_hash = STYLE_NORMAL;
+int style_cksum = STYLE_REVERSE;
#define NHASHES 10
-struct hash_functions {
+struct hash_function {
const char *name;
size_t digestlen;
int *style;
+ int base64;
void *ctx; /* XXX - only used by digest_file() */
void (*init)(void *);
void (*update)(void *, const unsigned char *, unsigned int);
+ void (*final)(unsigned char *, void *);
char * (*end)(void *, char *);
+ TAILQ_ENTRY(hash_function) tailq;
} functions[NHASHES + 1] = {
{
"CKSUM",
- CKSUM_DIGEST_LENGTH * 2,
+ CKSUM_DIGEST_LENGTH,
&style_cksum,
+ -1,
NULL,
(void (*)(void *))CKSUM_Init,
(void (*)(void *, const unsigned char *, unsigned int))CKSUM_Update,
+ (void (*)(unsigned char *, void *))CKSUM_Final,
(char *(*)(void *, char *))CKSUM_End
}, {
"SUM",
- SUM_DIGEST_LENGTH * 2,
+ SUM_DIGEST_LENGTH,
&style_cksum,
+ -1,
NULL,
(void (*)(void *))SUM_Init,
(void (*)(void *, const unsigned char *, unsigned int))SUM_Update,
+ (void (*)(unsigned char *, void *))SUM_Final,
(char *(*)(void *, char *))SUM_End
}, {
"SYSVSUM",
- SYSVSUM_DIGEST_LENGTH * 2,
+ SYSVSUM_DIGEST_LENGTH,
&style_cksum,
+ -1,
NULL,
(void (*)(void *))SYSVSUM_Init,
(void (*)(void *, const unsigned char *, unsigned int))SYSVSUM_Update,
+ (void (*)(unsigned char *, void *))SYSVSUM_Final,
(char *(*)(void *, char *))SYSVSUM_End
}, {
"MD4",
- MD5_DIGEST_LENGTH * 2,
+ MD5_DIGEST_LENGTH,
&style_hash,
+ 0,
NULL,
(void (*)(void *))MD4Init,
(void (*)(void *, const unsigned char *, unsigned int))MD4Update,
+ (void (*)(unsigned char *, void *))MD4Final,
(char *(*)(void *, char *))MD4End
}, {
"MD5",
- MD5_DIGEST_LENGTH * 2,
+ MD5_DIGEST_LENGTH,
&style_hash,
+ 0,
NULL,
(void (*)(void *))MD5Init,
(void (*)(void *, const unsigned char *, unsigned int))MD5Update,
+ (void (*)(unsigned char *, void *))MD5Final,
(char *(*)(void *, char *))MD5End
}, {
"RMD160",
- RMD160_DIGEST_LENGTH * 2,
+ RMD160_DIGEST_LENGTH,
&style_hash,
+ 0,
NULL,
(void (*)(void *))RMD160Init,
(void (*)(void *, const unsigned char *, unsigned int))RMD160Update,
+ (void (*)(unsigned char *, void *))RMD160Final,
(char *(*)(void *, char *))RMD160End
}, {
"SHA1",
- SHA1_DIGEST_LENGTH * 2,
+ SHA1_DIGEST_LENGTH,
&style_hash,
+ 0,
NULL,
(void (*)(void *))SHA1Init,
(void (*)(void *, const unsigned char *, unsigned int))SHA1Update,
+ (void (*)(unsigned char *, void *))SHA1Final,
(char *(*)(void *, char *))SHA1End
}, {
"SHA256",
- SHA256_DIGEST_LENGTH * 2,
+ SHA256_DIGEST_LENGTH,
&style_hash,
+ 0,
NULL,
(void (*)(void *))SHA256_Init,
(void (*)(void *, const unsigned char *, unsigned int))SHA256_Update,
+ (void (*)(unsigned char *, void *))SHA256_Final,
(char *(*)(void *, char *))SHA256_End
}, {
"SHA384",
- SHA384_DIGEST_LENGTH * 2,
+ SHA384_DIGEST_LENGTH,
&style_hash,
+ 0,
NULL,
(void (*)(void *))SHA384_Init,
(void (*)(void *, const unsigned char *, unsigned int))SHA384_Update,
+ (void (*)(unsigned char *, void *))SHA384_Final,
(char *(*)(void *, char *))SHA384_End
}, {
"SHA512",
- SHA512_DIGEST_LENGTH * 2,
+ SHA512_DIGEST_LENGTH,
&style_hash,
+ 0,
NULL,
(void (*)(void *))SHA512_Init,
(void (*)(void *, const unsigned char *, unsigned int))SHA512_Update,
+ (void (*)(unsigned char *, void *))SHA512_Final,
(char *(*)(void *, char *))SHA512_End
}, {
NULL,
}
};
+TAILQ_HEAD(hash_list, hash_function);
+
+void digest_end(const struct hash_function *, void *, char *, size_t, int);
+void digest_file(const char *, struct hash_list *, int);
+int digest_filelist(const char *, struct hash_function *);
+void digest_print(const struct hash_function *, const char *, const char *);
+void digest_printstr(const struct hash_function *, const char *, const char *);
+void digest_string(char *, struct hash_list *);
+void digest_test(struct hash_list *);
+void digest_time(struct hash_list *);
+void hash_insert(struct hash_list *, struct hash_function *, int);
void usage(void) __attribute__((__noreturn__));
-void digest_file(const char *, struct hash_functions **, int);
-int digest_filelist(const char *, struct hash_functions *);
-void digest_print(const struct hash_functions *, const char *, const char *);
-void digest_printstr(const struct hash_functions *, const char *, const char *);
-void digest_string(char *, struct hash_functions **);
-void digest_test(struct hash_functions **);
-void digest_time(struct hash_functions **);
extern char *__progname;
int qflag = 0;
+#define OPTSTRING "a:bco:pqrs:tx"
+
int
main(int argc, char **argv)
{
- struct hash_functions *hf, *hashes[NHASHES + 1];
- int fl, i, error;
- int cflag, pflag, rflag, tflag, xflag;
+ struct hash_function *hf, *hftmp;
+ struct hash_list hl;
+ size_t len;
char *cp, *input_string;
+ int fl, error, base64;
+ int bflag, cflag, pflag, rflag, tflag, xflag;
+ TAILQ_INIT(&hl);
input_string = NULL;
- error = cflag = pflag = qflag = rflag = tflag = xflag = 0;
- memset(hashes, 0, sizeof(hashes));
- while ((fl = getopt(argc, argv, "a:co:pqrs:tx")) != -1) {
+ error = bflag = cflag = pflag = qflag = rflag = tflag = xflag = 0;
+
+ /* Check for -b option early since it changes behavior. */
+ while ((fl = getopt(argc, argv, OPTSTRING)) != -1) {
+ if (fl == 'b')
+ bflag = 1;
+ }
+ optind = 1;
+ optreset = 1;
+ while ((fl = getopt(argc, argv, "a:bco:pqrs:tx")) != -1) {
switch (fl) {
case 'a':
while ((cp = strsep(&optarg, " \t,")) != NULL) {
if (*cp == '\0')
continue;
- for (hf = functions; hf->name != NULL; hf++)
- if (strcasecmp(hf->name, cp) == 0)
- break;
+ base64 = -1;
+ for (hf = functions; hf->name != NULL; hf++) {
+ len = strlen(hf->name);
+ if (strncasecmp(cp, hf->name, len) != 0)
+ continue;
+ if (cp[len] == '\0') {
+ if (hf->base64 != -1)
+ base64 = bflag;
+ break; /* exact match */
+ }
+ if (cp[len + 1] == '\0' &&
+ (cp[len] == 'b' || cp[len] == 'x')) {
+ base64 =
+ cp[len] == 'b' ? 1 : 0;
+ break; /* match w/ suffix */
+ }
+ }
if (hf->name == NULL) {
warnx("unknown algorithm \"%s\"", cp);
usage();
}
- for (i = 0; i < NHASHES && hashes[i] != hf; i++)
- if (hashes[i] == NULL) {
- hashes[i] = hf;
+ if (hf->base64 == -1 && base64 != -1) {
+ warnx("%s doesn't support %s",
+ hf->name, base64 ? "base64" : "hex");
+ usage();
+ }
+ /* Check for dupes. */
+ TAILQ_FOREACH(hftmp, &hl, tailq) {
+ if (hftmp->base64 == base64 &&
+ strcmp(hf->name, hftmp->name) == 0)
break;
- }
+ }
+ if (hftmp == TAILQ_END(&hl))
+ hash_insert(&hl, hf, base64);
}
break;
+ case 'b':
+ /* has already been parsed */
+ break;
case 'c':
cflag = 1;
break;
@@ -210,12 +277,13 @@ main(int argc, char **argv)
warnx("illegal argument to -o option");
usage();
}
- for (i = 0; i < NHASHES && hashes[i] != hf; i++) {
- if (hashes[i] == NULL) {
- hashes[i] = hf;
+ /* Check for dupes. */
+ TAILQ_FOREACH(hftmp, &hl, tailq) {
+ if (strcmp(hf->name, hftmp->name) == 0)
break;
- }
}
+ if (hftmp == TAILQ_END(&hl))
+ hash_insert(&hl, hf, 0);
break;
case 'p':
pflag = 1;
@@ -247,76 +315,107 @@ main(int argc, char **argv)
if (fl > 1 || (fl && argc && cflag == 0) || (rflag && qflag))
usage();
if (cflag != 0) {
- if (hashes[1] != NULL)
+ if (TAILQ_FIRST(&hl) != TAILQ_LAST(&hl, hash_list))
errx(1, "only a single algorithm may be specified "
"in -c mode");
}
/* No algorithm specified, check the name we were called as. */
- if (hashes[0] == NULL) {
+ if (TAILQ_EMPTY(&hl)) {
for (hf = functions; hf->name != NULL; hf++) {
- if (strcasecmp(hf->name, __progname) == 0) {
- hashes[0] = hf;
+ if (strcasecmp(hf->name, __progname) == 0)
break;
- }
}
- if (hashes[0] == NULL)
- hashes[0] = &functions[0]; /* default to cksum */
+ if (hf->name == NULL)
+ hf = &functions[0]; /* default to cksum */
+ hash_insert(&hl, hf, bflag);
}
if (rflag)
- style_hash = STYLE_CKSUM; /* reverse print */
+ style_hash = STYLE_REVERSE;
if (qflag) {
style_hash = STYLE_TERSE;
style_cksum = STYLE_TERSE;
}
if (tflag)
- digest_time(hashes);
+ digest_time(&hl);
else if (xflag)
- digest_test(hashes);
+ digest_test(&hl);
else if (input_string)
- digest_string(input_string, hashes);
+ digest_string(input_string, &hl);
else if (cflag) {
if (argc == 0)
- error = digest_filelist("-", hashes[0]);
+ error = digest_filelist("-", TAILQ_FIRST(&hl));
else
while (argc--)
- error += digest_filelist(*argv++, hashes[0]);
+ error += digest_filelist(*argv++,
+ TAILQ_FIRST(&hl));
} else if (pflag || argc == 0)
- digest_file("-", hashes, pflag);
+ digest_file("-", &hl, pflag);
else
while (argc--)
- digest_file(*argv++, hashes, 0);
+ digest_file(*argv++, &hl, 0);
return(error ? EXIT_FAILURE : EXIT_SUCCESS);
}
void
-digest_string(char *string, struct hash_functions **hashes)
+hash_insert(struct hash_list *hl, struct hash_function *hf, int base64)
{
- struct hash_functions *hf;
+ struct hash_function *hftmp;
+
+ hftmp = malloc(sizeof(*hftmp));
+ if (hftmp == NULL)
+ err(1, NULL);
+ *hftmp = *hf;
+ hftmp->base64 = base64;
+ TAILQ_INSERT_TAIL(hl, hftmp, tailq);
+}
+
+void
+digest_end(const struct hash_function *hf, void *ctx, char *buf, size_t bsize,
+ int base64)
+{
+ u_char *digest;
+
+ if (base64 == 1) {
+ if ((digest = malloc(hf->digestlen)) == NULL)
+ err(1, NULL);
+ hf->final(digest, ctx);
+ if (b64_ntop(digest, hf->digestlen, buf, bsize) == -1)
+ errx(1, "error encoding base64");
+ memset(digest, 0, sizeof(digest));
+ } else {
+ hf->end(ctx, buf);
+ }
+}
+
+void
+digest_string(char *string, struct hash_list *hl)
+{
+ struct hash_function *hf;
char digest[MAX_DIGEST_LEN + 1];
union ANY_CTX context;
- while (*hashes != NULL) {
- hf = *hashes++;
+ TAILQ_FOREACH(hf, hl, tailq) {
hf->init(&context);
hf->update(&context, string, (unsigned int)strlen(string));
- (void)hf->end(&context, digest);
+ digest_end(hf, &context, digest, sizeof(digest),
+ hf->base64);
digest_printstr(hf, string, digest);
}
}
void
-digest_print(const struct hash_functions *hf, const char *what,
+digest_print(const struct hash_function *hf, const char *what,
const char *digest)
{
switch (*hf->style) {
- case STYLE_HASH:
+ case STYLE_NORMAL:
(void)printf("%s (%s) = %s\n", hf->name, what, digest);
break;
- case STYLE_CKSUM:
+ case STYLE_REVERSE:
(void)printf("%s %s\n", digest, what);
break;
case STYLE_TERSE:
@@ -326,14 +425,14 @@ digest_print(const struct hash_functions *hf, const char *what,
}
void
-digest_printstr(const struct hash_functions *hf, const char *what,
+digest_printstr(const struct hash_function *hf, const char *what,
const char *digest)
{
switch (*hf->style) {
- case STYLE_HASH:
+ case STYLE_NORMAL:
(void)printf("%s (\"%s\") = %s\n", hf->name, what, digest);
break;
- case STYLE_CKSUM:
+ case STYLE_REVERSE:
(void)printf("%s %s\n", digest, what);
break;
case STYLE_TERSE:
@@ -343,9 +442,9 @@ digest_printstr(const struct hash_functions *hf, const char *what,
}
void
-digest_file(const char *file, struct hash_functions **hashes, int echo)
+digest_file(const char *file, struct hash_list *hl, int echo)
{
- struct hash_functions **hfp;
+ struct hash_function *hf;
int fd;
ssize_t nread;
u_char data[BUFSIZ];
@@ -361,16 +460,16 @@ digest_file(const char *file, struct hash_functions **hashes, int echo)
if (echo)
fflush(stdout);
- for (hfp = hashes; *hfp != NULL; hfp++) {
- if (((*hfp)->ctx = malloc(sizeof(union ANY_CTX))) == NULL)
+ TAILQ_FOREACH(hf, hl, tailq) {
+ if ((hf->ctx = malloc(sizeof(union ANY_CTX))) == NULL)
err(1, NULL);
- (*hfp)->init((*hfp)->ctx);
+ hf->init(hf->ctx);
}
while ((nread = read(fd, data, sizeof(data))) > 0) {
if (echo)
write(STDOUT_FILENO, data, (size_t)nread);
- for (hfp = hashes; *hfp != NULL; hfp++)
- (*hfp)->update((*hfp)->ctx, data, (unsigned int)nread);
+ TAILQ_FOREACH(hf, hl, tailq)
+ hf->update(hf->ctx, data, (unsigned int)nread);
}
if (nread == -1) {
warn("%s: read error", file);
@@ -380,13 +479,14 @@ digest_file(const char *file, struct hash_functions **hashes, int echo)
}
if (fd != STDIN_FILENO)
close(fd);
- for (hfp = hashes; *hfp != NULL; hfp++) {
- (void)(*hfp)->end((*hfp)->ctx, digest);
- free((*hfp)->ctx);
+ TAILQ_FOREACH(hf, hl, tailq) {
+ digest_end(hf, hf->ctx, digest, sizeof(digest), hf->base64);
+ free(hf->ctx);
+ hf->ctx = NULL;
if (fd == STDIN_FILENO)
(void)puts(digest);
else
- digest_print(*hfp, file, digest);
+ digest_print(hf, file, digest);
}
}
@@ -397,9 +497,9 @@ digest_file(const char *file, struct hash_functions **hashes, int echo)
* Print out the result of each comparison.
*/
int
-digest_filelist(const char *file, struct hash_functions *defhash)
+digest_filelist(const char *file, struct hash_function *defhash)
{
- int fd, found, error;
+ int fd, found, base64, error;
size_t algorithm_max, algorithm_min;
const char *algorithm;
char *filename, *checksum, *buf, *p;
@@ -410,7 +510,7 @@ digest_filelist(const char *file, struct hash_functions *defhash)
size_t len;
u_char data[BUFSIZ];
union ANY_CTX context;
- struct hash_functions *hf;
+ struct hash_function *hf;
if (strcmp(file, "-") == 0) {
fp = stdin;
@@ -426,7 +526,7 @@ digest_filelist(const char *file, struct hash_functions *defhash)
algorithm_min = MIN(algorithm_min, len);
}
- error = found = 0;
+ base64 = error = found = 0;
while ((buf = fgetln(fp, &len))) {
if (buf[len - 1] == '\n')
buf[len - 1] = '\0';
@@ -476,9 +576,22 @@ digest_filelist(const char *file, struct hash_functions *defhash)
if (strcasecmp(algorithm, hf->name) == 0)
break;
}
- if (hf->name == NULL ||
- strlen(checksum) != hf->digestlen)
+ if (hf->name == NULL || *checksum == '\0')
continue;
+ /*
+ * Check the length to see if this could be
+ * a valid checksum. If hex, it will be 2x the
+ * size of the binary data. For base64, we have
+ * to check both with and without the '=' padding.
+ */
+ len = strlen(checksum);
+ if (len != hf->digestlen * 2) {
+ size_t len2 = (8 * hf->digestlen + 5) / 6;
+ if (len != len2 &&
+ (len != len2 + 1 || checksum[len - 1] != '='))
+ continue;
+ base64 = 1;
+ }
} else {
/* could be GNU form */
if ((hf = defhash) == NULL)
@@ -487,7 +600,7 @@ digest_filelist(const char *file, struct hash_functions *defhash)
checksum = buf;
if ((p = strchr(checksum, ' ')) == NULL)
continue;
- if (*hf->style == STYLE_CKSUM) {
+ if (*hf->style & STYLE_REVERSE) {
if ((p = strchr(p + 1, ' ')) == NULL)
continue;
}
@@ -520,9 +633,14 @@ digest_filelist(const char *file, struct hash_functions *defhash)
continue;
}
close(fd);
- (void)hf->end(&context, digest);
-
- if (strcasecmp(checksum, digest) == 0) {
+ digest_end(hf, &context, digest, sizeof(digest), base64);
+
+ if (base64) {
+ len = strlen(digest) - 1; /* remove padding '=' */
+ error = strncmp(checksum, digest, len);
+ } else
+ error = strcasecmp(checksum, digest);
+ if (error == 0) {
if (qflag == 0)
(void)printf("(%s) %s: OK\n", algorithm, filename);
} else {
@@ -543,9 +661,9 @@ digest_filelist(const char *file, struct hash_functions *defhash)
#define TEST_BLOCK_COUNT 10000
void
-digest_time(struct hash_functions **hashes)
+digest_time(struct hash_list *hl)
{
- struct hash_functions *hf;
+ struct hash_function *hf;
struct timeval start, stop, res;
union ANY_CTX context;
u_int i;
@@ -553,8 +671,7 @@ digest_time(struct hash_functions **hashes)
char digest[MAX_DIGEST_LEN + 1];
double elapsed;
- while (*hashes != NULL) {
- hf = *hashes++;
+ TAILQ_FOREACH(hf, hl, tailq) {
(void)printf("%s time trial. Processing %d %d-byte blocks...",
hf->name, TEST_BLOCK_COUNT, TEST_BLOCK_LEN);
fflush(stdout);
@@ -567,7 +684,7 @@ digest_time(struct hash_functions **hashes)
hf->init(&context);
for (i = 0; i < TEST_BLOCK_COUNT; i++)
hf->update(&context, data, TEST_BLOCK_LEN);
- (void)hf->end(&context, digest);
+ digest_end(hf, &context, digest, sizeof(digest), hf->base64);
gettimeofday(&stop, NULL);
timersub(&stop, &start, &res);
elapsed = res.tv_sec + res.tv_usec / 1000000.0;
@@ -580,9 +697,9 @@ digest_time(struct hash_functions **hashes)
}
void
-digest_test(struct hash_functions **hashes)
+digest_test(struct hash_list *hl)
{
- struct hash_functions *hf;
+ struct hash_function *hf;
union ANY_CTX context;
int i;
char digest[MAX_DIGEST_LEN + 1];
@@ -600,15 +717,15 @@ digest_test(struct hash_functions **hashes)
"012345678901234567890",
};
- while (*hashes != NULL) {
- hf = *hashes++;
+ TAILQ_FOREACH(hf, hl, tailq) {
(void)printf("%s test suite:\n", hf->name);
for (i = 0; i < 8; i++) {
hf->init(&context);
hf->update((void *)&context, test_strings[i],
(unsigned int)strlen(test_strings[i]));
- (void)hf->end(&context, digest);
+ digest_end(hf, &context, digest, sizeof(digest),
+ hf->base64);
digest_printstr(hf, test_strings[i], digest);
}
@@ -618,7 +735,7 @@ digest_test(struct hash_functions **hashes)
for (i = 0; i < 1000; i++)
hf->update(&context, buf,
(unsigned int)sizeof(buf));
- (void)hf->end(&context, digest);
+ digest_end(hf, &context, digest, sizeof(digest), hf->base64);
digest_print(hf, "one million 'a' characters",
digest);
}
@@ -627,7 +744,7 @@ digest_test(struct hash_functions **hashes)
void
usage(void)
{
- fprintf(stderr, "usage: %s [-pqrtx] [-c [checklist ...]] "
+ fprintf(stderr, "usage: %s [-bpqrtx] [-c [checklist ...]] "
"[-s string] [file ...]\n", __progname);
if (strcmp(__progname, "cksum") == 0)
fprintf(stderr, " [-a algorithms]] [-o 1 | 2]\n");
diff --git a/bin/md5/rmd160.1 b/bin/md5/rmd160.1
index bbf4b403529..1809f489761 100644
--- a/bin/md5/rmd160.1
+++ b/bin/md5/rmd160.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: rmd160.1,v 1.20 2006/11/17 21:13:16 jmc Exp $
+.\" $OpenBSD: rmd160.1,v 1.21 2007/03/27 13:12:41 millert Exp $
.\"
.\" Copyright (c) 2003, 2004, 2006 Todd C. Miller <Todd.Miller@courtesan.com>
.\"
@@ -26,7 +26,7 @@
.Nd calculate a message-digest fingerprint (checksum) for a file
.Sh SYNOPSIS
.Nm rmd160
-.Op Fl pqrtx
+.Op Fl bpqrtx
.Op Fl c Op Ar checklist ...
.Op Fl s Ar string
.Op Ar
@@ -48,6 +48,8 @@ such as
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl b
+Output checksums in base64 notation, not hexidecimal.
.It Xo
.Fl c
.Op Ar checklist ...
diff --git a/bin/md5/sha1.1 b/bin/md5/sha1.1
index 0ea2c4d6ff1..d3a209ac657 100644
--- a/bin/md5/sha1.1
+++ b/bin/md5/sha1.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sha1.1,v 1.22 2006/11/17 21:13:16 jmc Exp $
+.\" $OpenBSD: sha1.1,v 1.23 2007/03/27 13:12:41 millert Exp $
.\"
.\" Copyright (c) 2003, 2004, 2006 Todd C. Miller <Todd.Miller@courtesan.com>
.\"
@@ -26,7 +26,7 @@
.Nd calculate a message-digest fingerprint (checksum) for a file
.Sh SYNOPSIS
.Nm sha1
-.Op Fl pqrtx
+.Op Fl bpqrtx
.Op Fl c Op Ar checklist ...
.Op Fl s Ar string
.Op Ar
@@ -48,6 +48,8 @@ such as
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl b
+Output checksums in base64 notation, not hexidecimal.
.It Xo
.Fl c
.Op Ar checklist ...