Add support for generating MD5 checksums, partially derived from the

FreeBSD md5(1) program.  MD5 checksums may be generated by using the
"-m" flag to cksum, or by invoking this program as "md5".
This commit is contained in:
thorpej 1997-01-30 01:10:32 +00:00
parent 2fb6cfc85c
commit 0941c04d45
5 changed files with 276 additions and 17 deletions

View File

@ -1,9 +1,11 @@
# $NetBSD: Makefile,v 1.6 1995/09/02 05:45:13 jtc Exp $
# $NetBSD: Makefile,v 1.7 1997/01/30 01:10:32 thorpej Exp $
# @(#)Makefile 8.2 (Berkeley) 4/28/95
PROG= cksum
SRCS= cksum.c crc.c print.c sum1.c sum2.c
SRCS= cksum.c crc.c md5.c print.c sum1.c sum2.c
LINKS= ${BINDIR}/cksum ${BINDIR}/sum
LINKS+= ${BINDIR}/cksum ${BINDIR}/md5
MLINKS= cksum.1 sum.1
MLINKS+=cksum.1 md5.1
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
.\" $NetBSD: cksum.1,v 1.8 1995/09/02 05:45:15 jtc Exp $
.\" $NetBSD: cksum.1,v 1.9 1997/01/30 01:10:33 thorpej Exp $
.\"
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -44,10 +44,19 @@
.Nd display file checksums and block counts
.Sh SYNOPSIS
.Nm cksum
.Op Fl o Ar \&1 No \&| Ar \&2
.Oo Fl m \&|
.Oo Fl o Ar \&1 No \&| Ar \&2
.Oc
.Oc
.Op Ar file ...
.Nm sum
.Op Ar file ...
.Nm md5
.Op Fl p
.Op Fl t
.Op Fl x
.Op Fl s Ar string
.Op Ar file ...
.Sh DESCRIPTION
The
.Nm cksum
@ -67,8 +76,27 @@ utility, except that it defaults to using historic algorithm 1, as
described below.
It is provided for compatibility only.
.Pp
The
.Nm md5
utility takes as input a message of arbitrary length and produces
as output a 128-bit
.Dq fingerprint
or
.Dq message digest
of the input. It is conjectured that it is computationally infeasible
to product two messages having the same message digest, or to produce
any message having a given prespecified target message digest. The
MD5 algorithm is intended for digital signature applications, where
a large file must be
.Dq compressed
in a secure manner before being encrypted with a private (secret)
key under a public-key encryption system such as
.Pa RSA .
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl m
Use the MD5 algorithm rather than the default one.
.It Fl o
Use historic algorithms instead of the (superior) default one.
.Pp
@ -107,6 +135,19 @@ for algorithm 2.
Partial blocks are rounded up.
.El
.Pp
The following options apply only when using the MD5 algorithm:
.Bl -tag -width indent
.It Fl o Ar string
Print the MD5 checksum of the given string
.Ar string .
.It Fl p
Echo input from standard input to standard output, and append an MD5 checksum.
.It Fl t
Run a built-in MD5 time trial.
.It Fl x
Run a built-in MD5 test script.
.El
.Pp
The default
.Tn CRC
used is based on the polynomial used for

View File

@ -1,6 +1,7 @@
/* $NetBSD: cksum.c,v 1.7 1995/09/02 05:45:18 jtc Exp $ */
/* $NetBSD: cksum.c,v 1.8 1997/01/30 01:10:34 thorpej Exp $ */
/*-
* Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
@ -46,7 +47,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)cksum.c 8.2 (Berkeley) 4/28/95";
#endif
static char rcsid[] = "$NetBSD: cksum.c,v 1.7 1995/09/02 05:45:18 jtc Exp $";
static char rcsid[] = "$NetBSD: cksum.c,v 1.8 1997/01/30 01:10:34 thorpej Exp $";
#endif /* not lint */
#include <sys/cdefs.h>
@ -55,6 +56,7 @@ static char rcsid[] = "$NetBSD: cksum.c,v 1.7 1995/09/02 05:45:18 jtc Exp $";
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <md5.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -62,6 +64,8 @@ static char rcsid[] = "$NetBSD: cksum.c,v 1.7 1995/09/02 05:45:18 jtc Exp $";
#include "extern.h"
int md5_digest_file __P((char *));
void requiremd5 __P((const char *));
void usage __P((void));
int
@ -69,14 +73,19 @@ main(argc, argv)
int argc;
char **argv;
{
register int ch, fd, rval;
register int ch, fd, rval, domd5, dosum, pflag, nomd5stdin;
u_int32_t len, val;
char *fn;
int (*cfncn) __P((int, u_int32_t *, u_int32_t *));
void (*pfncn) __P((char *, u_int32_t, u_int32_t));
extern char *__progname;
if (!strcmp(__progname, "sum")) {
dosum = domd5 = pflag = nomd5stdin = 0;
if (!strcmp(__progname, "md5"))
domd5 = 1;
else if (!strcmp(__progname, "sum")) {
dosum = 1;
cfncn = csum1;
pfncn = psum1;
} else {
@ -84,9 +93,20 @@ main(argc, argv)
pfncn = pcrc;
}
while ((ch = getopt(argc, argv, "o:")) != -1)
while ((ch = getopt(argc, argv, "mo:ps:tx")) != -1)
switch(ch) {
case 'm':
if (dosum) {
warnx("sum mutually exclusive with md5");
usage();
}
domd5 = 1;
break;
case 'o':
if (domd5) {
warnx("md5 mutually exclusive with sum");
usage();
}
if (!strcmp(optarg, "1")) {
cfncn = csum1;
pfncn = psum1;
@ -98,6 +118,29 @@ main(argc, argv)
usage();
}
break;
case 'p':
if (!domd5)
requiremd5("-p");
pflag = 1;
break;
case 's':
if (!domd5)
requiremd5("-s");
nomd5stdin = 1;
MDString(optarg);
break;
case 't':
if (!domd5)
requiremd5("-t");
MDTimeTrial();
nomd5stdin = 1;
break;
case 'x':
if (!domd5)
requiremd5("-x");
MDTestSuite();
nomd5stdin = 1;
break;
case '?':
default:
usage();
@ -111,26 +154,62 @@ main(argc, argv)
do {
if (*argv) {
fn = *argv++;
if (domd5) {
if (md5_digest_file(fn)) {
warn("%s", fn);
rval = 1;
}
continue;
}
if ((fd = open(fn, O_RDONLY, 0)) < 0) {
warn("%s", fn);
rval = 1;
continue;
}
} else if (domd5 && !nomd5stdin)
MDFilter(pflag);
if (!domd5) {
if (cfncn(fd, &val, &len)) {
warn("%s", fn ? fn : "stdin");
rval = 1;
} else
pfncn(fn, val, len);
(void)close(fd);
}
if (cfncn(fd, &val, &len)) {
warn("%s", fn ? fn : "stdin");
rval = 1;
} else
pfncn(fn, val, len);
(void)close(fd);
} while (*argv);
exit(rval);
}
int
md5_digest_file(fn)
char *fn;
{
char buf[33], *cp;
cp = MD5File(fn, buf);
if (cp == NULL)
return (1);
printf("MD5 (%s) = %s\n", fn, cp);
return (0);
}
void
requiremd5(flg)
const char *flg;
{
warnx("%s flag requires `md5' or -m", flg);
usage();
}
void
usage()
{
(void)fprintf(stderr, "usage: cksum [-o 1 | 2] [file ...]\n");
(void)fprintf(stderr, "usage: cksum [-m | [-o 1 | 2]] [file ...]\n");
(void)fprintf(stderr, " sum [file ...]\n");
(void)fprintf(stderr,
" md5 [-p | -t | -x | -s string] [file ...]\n");
exit(1);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.5 1995/03/26 05:15:19 glass Exp $ */
/* $NetBSD: extern.h,v 1.6 1997/01/30 01:10:35 thorpej Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -44,4 +44,10 @@ void psum1 __P((char *, u_int32_t, u_int32_t));
void psum2 __P((char *, u_int32_t, u_int32_t));
int csum1 __P((int, u_int32_t *, u_int32_t *));
int csum2 __P((int, u_int32_t *, u_int32_t *));
int md5 __P((int, u_int32_t *, u_int32_t *));
void MDString __P((const char *));
void MDTimeTrial __P((void));
void MDTestSuite __P((void));
void MDFilter __P((int));
__END_DECLS

131
usr.bin/cksum/md5.c Normal file
View File

@ -0,0 +1,131 @@
/* $NetBSD: md5.c,v 1.1 1997/01/30 01:10:35 thorpej Exp $ */
/*
* MDDRIVER.C - test driver for MD2, MD4 and MD5
*/
/*
* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
* rights reserved.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
*/
#include <sys/types.h>
#include <err.h>
#include <md5.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
/*
* Length of test block, number of test blocks.
*/
#define TEST_BLOCK_LEN 1000
#define TEST_BLOCK_COUNT 1000
/*
* Digests a string and prints the result.
*/
void
MDString(string)
const char *string;
{
unsigned int len = strlen(string);
char buf[33];
printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf));
}
/*
* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks.
*/
void
MDTimeTrial()
{
MD5_CTX context;
time_t endTime, startTime;
unsigned char block[TEST_BLOCK_LEN];
unsigned int i;
char *p, buf[33];
printf("MD5 time trial. Digesting %d %d-byte blocks ...",
TEST_BLOCK_LEN, TEST_BLOCK_COUNT);
fflush(stdout);
/* Initialize block */
for (i = 0; i < TEST_BLOCK_LEN; i++)
block[i] = (unsigned char) (i & 0xff);
/* Start timer */
time(&startTime);
/* Digest blocks */
MD5Init(&context);
for (i = 0; i < TEST_BLOCK_COUNT; i++)
MD5Update(&context, block, TEST_BLOCK_LEN);
p = MD5End(&context,buf);
/* Stop timer */
time(&endTime);
printf(" done\n");
printf("Digest = %s\n", p);
printf("Time = %ld seconds\n", (long) (endTime - startTime));
/*
* Be careful that endTime-startTime is not zero.
* (Bug fix from Ric * Anderson, ric@Artisoft.COM.)
*/
printf("Speed = %ld bytes/second\n",
(long) TEST_BLOCK_LEN * (long) TEST_BLOCK_COUNT /
((endTime - startTime) != 0 ? (endTime - startTime) : 1));
}
/*
* Digests a reference suite of strings and prints the results.
*/
void
MDTestSuite()
{
printf("MD5 test suite:\n");
MDString("");
MDString("a");
MDString("abc");
MDString("message digest");
MDString("abcdefghijklmnopqrstuvwxyz");
MDString
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
MDString
("1234567890123456789012345678901234567890\
1234567890123456789012345678901234567890");
}
/*
* Digests the standard input and prints the result.
*/
void
MDFilter(pipe)
int pipe;
{
MD5_CTX context;
int len;
unsigned char buffer[BUFSIZ], digest[16];
char buf[33];
MD5Init(&context);
while (len = fread(buffer, 1, BUFSIZ, stdin)) {
if (pipe && (len != fwrite(buffer, 1, len, stdout)))
err(1, "stdout");
MD5Update(&context, buffer, len);
}
printf("%s\n", MD5End(&context,buf));
}