From anders@totem.fix.no  Sun Jul 15 04:40:42 2001
Return-Path: <anders@totem.fix.no>
Received: from totem.fix.no (totem.fix.no [213.142.66.130])
	by hub.freebsd.org (Postfix) with ESMTP id 42A5837B405
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 15 Jul 2001 04:40:41 -0700 (PDT)
	(envelope-from anders@totem.fix.no)
Received: by totem.fix.no (Postfix, from userid 1000)
	id 3C1763C8E; Sun, 15 Jul 2001 13:40:40 +0200 (CEST)
Message-Id: <20010715114040.3C1763C8E@totem.fix.no>
Date: Sun, 15 Jul 2001 13:40:40 +0200 (CEST)
From: Anders Nordby <anders@fix.no>
Reply-To: Anders Nordby <anders@fix.no>
To: FreeBSD-gnats-submit@freebsd.org
Subject: We need more simple message digesting tools
X-Send-Pr-Version: 3.2

>Number:         28988
>Category:       bin
>Synopsis:       We need more simple message digesting tools
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 15 04:50:02 PDT 2001
>Closed-Date:    Sat Jul 12 23:23:23 PDT 2003
>Last-Modified:  Sat Jul 12 23:23:23 PDT 2003
>Originator:     Anders Nordby
>Release:        FreeBSD 4.3-STABLE i386
>Organization:
Fluxpod Information eXchange
>Environment:

5.0-20010618-CURRENT

>Description:

Add tools for generating 160 bit SHA1 and RMD-160 digests.

Obtained from OpenBSD. I'm sorry to break Ruslan's WARNS= 2, but I haven't
been able to remove all warnings (yet). Suggestions are very welcome.

Patches are relative to 5.0-20010618-CURRENT (snapshot from
current.freebsd.org). Files added: sha1.1 and rmd160.1.

Yes, I know openssl dgst -whatnot can do this. But the md5 program is heavily
used, and thereby I think we should have sha1 and rmd160 too.

>How-To-Repeat:

	<Code/input/activities to reproduce the problem (multiple lines)>

>Fix:

In src/sbin:

diff -Nur md5.old/Makefile md5/Makefile
--- md5.old/Makefile	Tue May 22 12:33:43 2001
+++ md5/Makefile	Sun Jul 15 11:52:52 2001
@@ -6,6 +6,9 @@
 LDADD+=	-lmd
 DPADD+= ${LIBMD}
 
-WARNS=	2
+MAN=	md5.1 sha1.1 rmd160.1
+
+LINKS=	${BINDIR}/md5 ${BINDIR}/sha1 \
+	${BINDIR}/md5 ${BINDIR}/rmd160
 
 .include <bsd.prog.mk>
diff -Nur md5.old/md5.1 md5/md5.1
--- md5.old/md5.1	Tue Feb 13 10:52:50 2001
+++ md5/md5.1	Sun Jul 15 12:10:57 2001
@@ -54,6 +54,8 @@
 .El
 .Sh SEE ALSO
 .Xr cksum 1
+.Xr sha1 1
+.Xr rmd160 1
 .Rs
 .%A R. Rivest
 .%T The MD5 Message-Digest Algorithm
diff -Nur md5.old/md5.c md5/md5.c
--- md5.old/md5.c	Tue May 22 12:33:43 2001
+++ md5/md5.c	Sun Jul 15 12:34:25 2001
@@ -26,9 +26,13 @@
 #include <err.h>
 #include <md5.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <time.h>
 #include <unistd.h>
 #include <string.h>
+#include <md5.h>
+#include <sha.h>
+#include <ripemd.h>
 
 /*
  * Length of test block, number of test blocks.
@@ -39,32 +43,78 @@
 int qflag;
 int rflag;
 
-static void MDString(const char *);
-static void MDTimeTrial(void);
-static void MDTestSuite(void);
-static void MDFilter(int);
+extern char *__progname;
+
+static void MDString __P((const char *));
+static void MDTimeTrial __P((void *));
+static void MDTestSuite __P((void));
+static void MDFilter __P((int, void *));
 static void usage(void);
 
-/* Main driver.
+int main __P((int, char *[]));
+
+/*
+ * Globals for indirection...
+ */
+void (*MDInit)();
+void (*MDUpdate)();
+char * (*MDEnd)();
+char * (*MDFile)();
+char * (*MDData)();
+char *MDType;
 
-Arguments (may be any combination):
-  -sstring - digests string
-  -t       - runs time trial
-  -x       - runs test script
-  filename - digests file
-  (none)   - digests standard input
+/* Main driver.
+ *
+ * Arguments (may be any combination):
+ *  -sstring - digests string
+ *  -t       - runs time trial
+ *  -x       - runs test script
+ *  filename - digests file
+ *  (none)   - digests standard input
  */
 int
 main(int argc, char *argv[])
 {
 	int     ch;
 	char   *p;
-	char	buf[33];
+	char	buf[41];
+	void *context;
+
+	/* What were we called as?  Default to md5 */
+	if (strcmp(__progname, "sha1") == 0) {
+		MDType = "SHA1";
+		MDInit = SHA1_Init;
+		MDUpdate = SHA1_Update;
+		MDEnd = SHA1_End;
+		MDFile = SHA1_File;
+		MDData = SHA1_Data;
+		if ((context = malloc(sizeof(SHA1_CTX))) == NULL)
+			err(1, "malloc");
+	} else if (strcmp(__progname, "rmd160") == 0) {
+		MDType = "RMD160";
+		MDInit = RIPEMD160_Init;
+		MDUpdate = RIPEMD160_Update;
+		MDEnd = RIPEMD160_End;
+		MDFile = RIPEMD160_File;
+		MDData = RIPEMD160_Data;
+		if ((context = malloc(sizeof(RIPEMD160_CTX))) == NULL)
+			err(1, "malloc");
+	} else {
+		MDType = "MD5";
+		MDInit = MD5Init;
+		MDUpdate = MD5Update;
+		MDEnd = MD5End;
+		MDFile = MD5File;
+		MDData = MD5Data;
+		if ((context = malloc(sizeof(MD5_CTX))) == NULL)
+			err(1, "malloc");
+	}
+	
 
 	while ((ch = getopt(argc, argv, "ps:qrtx")) != -1)
 		switch (ch) {
 		case 'p':
-			MDFilter(1);
+			MDFilter(1, context);
 			break;
 		case 'q':
 			qflag = 1;
@@ -76,7 +126,7 @@
 			MDString(optarg);
 			break;
 		case 't':
-			MDTimeTrial();
+			MDTimeTrial(context);
 			break;
 		case 'x':
 			MDTestSuite();
@@ -89,7 +139,7 @@
 
 	if (*argv) {
 		do {
-			p = MD5File(*argv, buf);
+			p = MDFile(*argv, buf);
 			if (!p)
 				warn("%s", *argv);
 			else
@@ -98,10 +148,11 @@
 				else if (rflag)
 					printf("%s %s\n", p, *argv);
 				else
-					printf("MD5 (%s) = %s\n", *argv, p);
+					(void)printf("%s (%s) = %s\n", MDType,
+					*argv, p);
 		} while (*++argv);
 	} else
-		MDFilter(0);
+		MDFilter(0, context);
 
 	return (0);
 }
@@ -109,32 +160,33 @@
  * Digests a string and prints the result.
  */
 static void
-MDString(const char *string)
+MDString(string)
+	const char *string;
 {
 	size_t len = strlen(string);
-	char buf[33];
+	char buf[41];
 
 	if (qflag)
-		printf("%s\n", MD5Data(string, len, buf));
+		(void)printf("%s (\"%s\") = %s\n", MDType, string,
+			MDData(string, len, buf));
 	else if (rflag)
-		printf("%s \"%s\"\n", MD5Data(string, len, buf), string);
+		printf("%s \"%s\"\n", MDData(string, len, buf), string);
 	else
-		printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, len, buf));
+		printf("MD5 (\"%s\") = %s\n", string, MDData(string, len, buf));
 }
 /*
  * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks.
  */
 static void
-MDTimeTrial(void)
+MDTimeTrial(context)
+	void *context;
 {
-	MD5_CTX context;
 	time_t  endTime, startTime;
 	unsigned char block[TEST_BLOCK_LEN];
 	unsigned int i;
-	char   *p, buf[33];
+	char   *p, buf[41];
 
-	printf
-	    ("MD5 time trial. Digesting %d %d-byte blocks ...",
+	(void)printf("%s time trial. Digesting %d %d-byte blocks ...", MDType,
 	    TEST_BLOCK_COUNT, TEST_BLOCK_LEN);
 	fflush(stdout);
 
@@ -146,22 +198,23 @@
 	time(&startTime);
 
 	/* Digest blocks */
-	MD5Init(&context);
+	MDInit(context);
 	for (i = 0; i < TEST_BLOCK_COUNT; i++)
-		MD5Update(&context, block, TEST_BLOCK_LEN);
-	p = MD5End(&context,buf);
+		MDUpdate(context, block, TEST_BLOCK_LEN);
+	p = MDEnd(context,buf);
 
 	/* Stop timer */
 	time(&endTime);
 
-	printf(" done\n");
-	printf("Digest = %s", p);
-	printf("\nTime = %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));
+	(void)printf(" done\nDigest = %s", p);
+	(void)printf("\nTime = %ld seconds\n", (long) (endTime - startTime));
+	/*
+	 *  Be careful that endTime-startTime is not zero. (Bug fix from Ric
+	 * Anderson, ric@Artisoft.COM.)
+	 */
+	(void)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.
@@ -170,7 +223,7 @@
 MDTestSuite(void)
 {
 
-	printf("MD5 test suite:\n");
+	(void)printf("%s test suite:\n", MDType);
 
 	MDString("");
 	MDString("a");
@@ -182,26 +235,28 @@
 	MDString
 	    ("1234567890123456789012345678901234567890\
 1234567890123456789012345678901234567890");
+	MDString("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
 }
 
 /*
  * Digests the standard input and prints the result.
  */
 static void
-MDFilter(int tee)
+MDFilter(tee, context)
+	int tee;
+	void *context;
 {
-	MD5_CTX context;
 	unsigned int len;
 	unsigned char buffer[BUFSIZ];
-	char buf[33];
+	char buf[41];
 
-	MD5Init(&context);
+	MDInit(context);
 	while ((len = fread(buffer, 1, BUFSIZ, stdin))) {
 		if (tee && len != fwrite(buffer, 1, len, stdout))
 			err(1, "stdout");
-		MD5Update(&context, buffer, len);
+		MDUpdate(context, buffer, len);
 	}
-	printf("%s\n", MD5End(&context,buf));
+	(void)printf("%s\n", MDEnd(context,buf));
 }
 
 static void
diff -Nur md5.old/rmd160.1 md5/rmd160.1
--- md5.old/rmd160.1	Thu Jan  1 01:00:00 1970
+++ md5/rmd160.1	Sun Jul 15 12:10:15 2001
@@ -0,0 +1,66 @@
+.\" $FreeBSD$
+.Dd July 15, 2001
+.Dt RMD160 1
+.Os
+.Sh NAME
+.Nm rmd160
+.Nd calculate a message-digest fingerprint (checksum) for a file
+.Sh SYNOPSIS
+.Nm
+.Op Fl pqrtx
+.Op Fl s Ar string
+.Op Ar
+.Sh DESCRIPTION
+.Nm Rmd160
+takes as input a message of arbitrary length and produces
+as output a 160-bit
+.Dq fingerprint
+or
+.Dq message digest
+of the input.  It is conjectured that it is computationally infeasible to
+produce two messages having the same message digest, or to produce any
+message having a given prespecified target message digest.
+The RMD-160 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
+.Pq secret
+key under a public-key cryptosystem such as
+.Em RSA .
+.Pp
+The following four options may be used in any combination and must
+precede any files named on the command line.  The RMD-160
+sum of each file listed on the command line is printed after the options
+are processed.
+.Bl -tag -width indent
+.It Fl s Ar string
+Print a checksum of the given
+.Ar string .
+.It Fl p
+Echo stdin to stdout and appends the RMD160 sum to stdout.
+.It Fl q
+Quiet mode - only the RMD160 sum is printed out.  Overrides the
+.Fl r
+option.
+.It Fl r
+Reverses the format of the output.  This helps with visual diffs.  Does nothing
+when combined with the 
+.Fl ptx
+options.
+.It Fl t
+Run a built-in time trial.
+.It Fl x
+Run a built-in test script.
+.El
+.Sh SEE ALSO
+.Xr cksum 1
+.Xr md5 1
+.Xr sha1 1
+.Rs
+.Pp
+RMD-160 is part of the ISO draft standard "ISO/IEC DIS 10118-3" on dedicated
+hash functions.
+.Re
+.Sh ACKNOWLEDGMENTS
+This program is placed in the public domain for free general use by
+RSA Data Security.
diff -Nur md5.old/sha1.1 md5/sha1.1
--- md5.old/sha1.1	Thu Jan  1 01:00:00 1970
+++ md5/sha1.1	Sun Jul 15 12:05:09 2001
@@ -0,0 +1,65 @@
+.\" $FreeBSD$
+.Dd July 15, 2001
+.Dt SHA1 1
+.Os
+.Sh NAME
+.Nm sha1
+.Nd calculate a message-digest fingerprint (checksum) for a file
+.Sh SYNOPSIS
+.Nm
+.Op Fl pqrtx
+.Op Fl s Ar string
+.Op Ar
+.Sh DESCRIPTION
+.Nm Sha1
+takes as input a message of arbitrary length and produces
+as output a 160-bit
+.Dq fingerprint
+or
+.Dq message digest
+of the input.  It is conjectured that it is computationally infeasible to
+produce two messages having the same message digest, or to produce any
+message having a given prespecified target message digest.
+The SHA1 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
+.Pq secret
+key under a public-key cryptosystem such as
+.Em RSA .
+.Pp
+The following four options may be used in any combination and must
+precede any files named on the command line.  The SHA1
+sum of each file listed on the command line is printed after the options
+are processed.
+.Bl -tag -width indent
+.It Fl s Ar string
+Print a checksum of the given
+.Ar string .
+.It Fl p
+Echo stdin to stdout and appends the SHA1 sum to stdout.
+.It Fl q
+Quiet mode - only the SHA1 sum is printed out.  Overrides the
+.Fl r
+option.
+.It Fl r
+Reverses the format of the output.  This helps with visual diffs.  Does nothing
+when combined with the 
+.Fl ptx
+options.
+.It Fl t
+Run a built-in time trial.
+.It Fl x
+Run a built-in test script.
+.El
+.Sh SEE ALSO
+.Xr cksum 1
+.Xr md5 1
+.Xr rmd160 1
+.Rs
+.Re
+.Pp
+NIST FIPS PUB 180-1 describes the SHA-1 message-digest algorithm in detail.
+.Sh ACKNOWLEDGMENTS
+This program is placed in the public domain for free general use by
+RSA Data Security.
>Release-Note:
>Audit-Trail:

From: Dima Dorfman <dima@unixfreak.org>
To: Anders Nordby <anders@fix.no>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/28988: We need more simple message digesting tools 
Date: Sun, 15 Jul 2001 05:26:22 -0700

 Anders Nordby <anders@fix.no> writes:
 > >Description:
 > 
 > Add tools for generating 160 bit SHA1 and RMD-160 digests.
 > 
 > Obtained from OpenBSD. I'm sorry to break Ruslan's WARNS= 2, but I haven't
 > been able to remove all warnings (yet). Suggestions are very welcome.
 > 
 > Patches are relative to 5.0-20010618-CURRENT (snapshot from
 > current.freebsd.org). Files added: sha1.1 and rmd160.1.
 > 
 > Yes, I know openssl dgst -whatnot can do this. But the md5 program is heavily
 > used, and thereby I think we should have sha1 and rmd160 too.
 
 Used by whom, and why aren't they using openssl(1)?  The latter is
 more portable and more up-to-date.  I think md5(1) should be removed
 in favor of OpenSSL; certainly we shouldn't be adding new
 functionality to it to encourage its use.  The only thing in the way
 of replacng md5(1) with oppenssl(1) completely is that openssl(1)'s
 output is a little different with regards to spacing.  At the very
 least that will break the ports collection, but the latter should be
 adjusted to use openssl(1), anyway.

From: Anders Nordby <anders@fix.no>
To: Dima Dorfman <dima@unixfreak.org>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/28988: We need more simple message digesting tools
Date: Mon, 16 Jul 2001 19:57:13 +0200

 On Sun, Jul 15, 2001 at 05:26:22AM -0700, Dima Dorfman wrote:
 >> Yes, I know openssl dgst -whatnot can do this. But the md5 program is heavily
 >> used, and thereby I think we should have sha1 and rmd160 too.
 > Used by whom, and why aren't they using openssl(1)?
 
 MD5 checksums are quite heavily used in FreeBSD, and AFAIK most people
 use the md5 program for generating MD5 fingerprints of files. At least,
 I do, and I haven't heard about anyone using openssl(1) for it in
 FreeBSD until recently. :-)
 
 > The latter is more portable and more up-to-date.
 
 More portable? md5(1) is just a frontend for libmd. If I make md5(1) use
 libcrypto instead, would that be better? And speaking of up-to-date,
 libmd must be the real issue here. It's the library that provides the
 actual message-digest fingerprinting code, and is based on SSLeay. We
 shouldn't be dragging old SSLeay code around when we have OpenSSL in the
 base system.
 
 > I think md5(1) should
 > be removed in favor of OpenSSL; certainly we shouldn't be adding new 
 > functionality to it to encourage its use. The only thing in the way of
 > replacng md5(1) with oppenssl(1) completely is that openssl(1)'s
 > output is a little different with regards to spacing.
 
 I don't see why we need to remove md5(1). It can be improved, and it's
 already an easy to use tool which can support rmd160 and sha1 too.
 
 Regards,
 
 -- 
 Anders.

From: Dima Dorfman <dima@unixfreak.org>
To: Anders Nordby <anders@fix.no>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/28988: We need more simple message digesting tools 
Date: Mon, 16 Jul 2001 22:20:00 -0700

 Anders Nordby <anders@fix.no> writes:
 > On Sun, Jul 15, 2001 at 05:26:22AM -0700, Dima Dorfman wrote:
 > >> Yes, I know openssl dgst -whatnot can do this. But the md5 program is heavily
 > >> used, and thereby I think we should have sha1 and rmd160 too.
 > > Used by whom, and why aren't they using openssl(1)?
 > 
 > MD5 checksums are quite heavily used in FreeBSD, and AFAIK most people
 > use the md5 program for generating MD5 fingerprints of files. At least,
 > I do, and I haven't heard about anyone using openssl(1) for it in
 > FreeBSD until recently. :-)
 > 
 > > The latter is more portable and more up-to-date.
 > 
 > More portable?
 
 That too.
 
 > md5(1) is just a frontend for libmd. If I make md5(1) use
 > libcrypto instead, would that be better?
 
 Why?  What's wrong with:
 
 	ln -s /usr/bin/openssl md5
 
 works for sha, sha1, ripemd160, and a few other algorithms.  The only
 thing wrong with it is that openssl doesn't support some of the
 options md5(1) does, and has a slightly different output format.

From: Anders Nordby <anders@fix.no>
To: Dima Dorfman <dima@unixfreak.org>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/28988: We need more simple message digesting tools
Date: Thu, 19 Jul 2001 13:28:57 +0200

 On Mon, Jul 16, 2001 at 10:20:00PM -0700, Dima Dorfman wrote:
 >> md5(1) is just a frontend for libmd. If I make md5(1) use
 >> libcrypto instead, would that be better?
 > Why?  What's wrong with:
 > 
 > 	ln -s /usr/bin/openssl md5
 
 The fact that md5 dgst -sha1 does not make sence, and that md5(1) is
 expected to output differently and have other options.
 
 > works for sha, sha1, ripemd160, and a few other algorithms.  The only
 > thing wrong with it is that openssl doesn't support some of the
 > options md5(1) does, and has a slightly different output format.
 
 Is there a problem with having both md5/rmd160/sha1(1) and openssl(1)?
 As long as we have libmd and they all work/are correct, I think not.
 
 Regards,
 
 -- 
 Anders.

From: Dima Dorfman <dima@unixfreak.org>
To: Anders Nordby <anders@fix.no>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/28988: We need more simple message digesting tools 
Date: Thu, 19 Jul 2001 04:38:17 -0700

 Anders Nordby <anders@fix.no> writes:
 > On Mon, Jul 16, 2001 at 10:20:00PM -0700, Dima Dorfman wrote:
 > >> md5(1) is just a frontend for libmd. If I make md5(1) use
 > >> libcrypto instead, would that be better?
 > > Why?  What's wrong with:
 > > 
 > > 	ln -s /usr/bin/openssl md5
 > 
 > The fact that md5 dgst -sha1 does not make sence, and that md5(1) is
 > expected to output differently
 
 The output is a problem; I agree.
 
 > and have other options.
 
 This is not.  Options can be added.  IIRC, the only non-debug option
 that's missing is -s.
 
 > > works for sha, sha1, ripemd160, and a few other algorithms.  The only
 > > thing wrong with it is that openssl doesn't support some of the
 > > options md5(1) does, and has a slightly different output format.
 > 
 > Is there a problem with having both md5/rmd160/sha1(1) and openssl(1)?
 > As long as we have libmd and they all work/are correct, I think not.
 
 It'd be nice to minimize code duplication in the tree.  If openssl(1)
 didn't have a different format and had -s, we'd be all set.  The
 latter shouldn't be too difficult to add.  The former might be a
 problem, but it's solvable.  Perhaps we can convince the OpenSSL folks
 to add our format around an #ifdef or something.

From: Peter Pentchev <roam@orbitel.bg>
To: Anders Nordby <anders@fix.no>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/28988: We need more simple message digesting tools
Date: Thu, 19 Jul 2001 17:05:00 +0300

 On Thu, Jul 19, 2001 at 04:30:30AM -0700, Anders Nordby wrote:
 > The following reply was made to PR bin/28988; it has been noted by GNATS.
 > 
 > From: Anders Nordby <anders@fix.no>
 > To: Dima Dorfman <dima@unixfreak.org>
 > Cc: FreeBSD-gnats-submit@freebsd.org
 > Subject: Re: bin/28988: We need more simple message digesting tools
 > Date: Thu, 19 Jul 2001 13:28:57 +0200
 > 
 >  On Mon, Jul 16, 2001 at 10:20:00PM -0700, Dima Dorfman wrote:
 >  >> md5(1) is just a frontend for libmd. If I make md5(1) use
 >  >> libcrypto instead, would that be better?
 >  > Why?  What's wrong with:
 >  > 
 >  > 	ln -s /usr/bin/openssl md5
 >  
 >  The fact that md5 dgst -sha1 does not make sence, and that md5(1) is
 >  expected to output differently and have other options.
 
 It doesn't work, either.  If openssl is invoked with an algorithm name,
 it accepts only filenames, not commands/options.  Thus, it preserves
 md5(1)'s syntax (at least in this respect).
 
 
 [roam@edge:p1 /usr/src]$ ln -s /usr/bin/openssl /usr/tmp/md5
 [roam@edge:p1 /usr/src]$ /usr/tmp/md5 /etc/passwd
 MD5(/etc/passwd)= dbcf40cb4677824638143626b514ad4e
 [roam@edge:p1 /usr/src]$ /usr/tmp/md5 dgst -sha1 /etc/passwd
 dgst: No such file or directory
 -sha1: No such file or directory
 MD5(/etc/passwd)= dbcf40cb4677824638143626b514ad4e
 [roam@edge:p1 /usr/src]$
 
 >  > works for sha, sha1, ripemd160, and a few other algorithms.  The only
 >  > thing wrong with it is that openssl doesn't support some of the
 >  > options md5(1) does, and has a slightly different output format.
 >  
 >  Is there a problem with having both md5/rmd160/sha1(1) and openssl(1)?
 >  As long as we have libmd and they all work/are correct, I think not.
 
 I think that there is an idea to remove libmd, since it only duplicates
 libcrypto functionality.  Thus, the notion of using openssl(1) as md5(1).
 
 (And before phk jumps at me, yes, I know that libmd was introduced waay
 before libcrypto made it into the source tree, and yes, I know that they
 have slightly different functionality - actually I even contributed some
 of that difference, remember? :P  .. and no, I'm not the one advocating
 libmd replacement with libcrypto, just stating that some people are :)
 
 G'luck,
 Peter
 
 -- 
 Hey, out there - is it *you* reading me, or is it someone else?

From: Dima Dorfman <dima@unixfreak.org>
To: Peter Pentchev <roam@orbitel.bg>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/28988: We need more simple message digesting tools 
Date: Thu, 19 Jul 2001 08:05:49 -0700

 Peter Pentchev <roam@orbitel.bg> writes:
 > The following reply was made to PR bin/28988; it has been noted by GNATS.
 > 
 > From: Peter Pentchev <roam@orbitel.bg>
 > To: Anders Nordby <anders@fix.no>
 > Cc: freebsd-gnats-submit@FreeBSD.org
 > Subject: Re: bin/28988: We need more simple message digesting tools
 > Date: Thu, 19 Jul 2001 17:05:00 +0300
 > 
 >  On Thu, Jul 19, 2001 at 04:30:30AM -0700, Anders Nordby wrote:
 >  > The following reply was made to PR bin/28988; it has been noted by GNATS.
 >  > 
 >  > From: Anders Nordby <anders@fix.no>
 >  > To: Dima Dorfman <dima@unixfreak.org>
 >  > Cc: FreeBSD-gnats-submit@freebsd.org
 >  > Subject: Re: bin/28988: We need more simple message digesting tools
 >  > Date: Thu, 19 Jul 2001 13:28:57 +0200
 >  > 
 >  >  On Mon, Jul 16, 2001 at 10:20:00PM -0700, Dima Dorfman wrote:
 >  >  >> md5(1) is just a frontend for libmd. If I make md5(1) use
 >  >  >> libcrypto instead, would that be better?
 >  >  > Why?  What's wrong with:
 >  >  > 
 >  >  > 	ln -s /usr/bin/openssl md5
 >  >  
 >  >  The fact that md5 dgst -sha1 does not make sence, and that md5(1) is
 >  >  expected to output differently and have other options.
 >  
 >  It doesn't work, either.  If openssl is invoked with an algorithm name,
 >  it accepts only filenames, not commands/options.  Thus, it preserves
 >  md5(1)'s syntax (at least in this respect).
 >  
 >  
 >  [roam@edge:p1 /usr/src]$ ln -s /usr/bin/openssl /usr/tmp/md5
 >  [roam@edge:p1 /usr/src]$ /usr/tmp/md5 /etc/passwd
 >  MD5(/etc/passwd)= dbcf40cb4677824638143626b514ad4e
 >  [roam@edge:p1 /usr/src]$ /usr/tmp/md5 dgst -sha1 /etc/passwd
 >  dgst: No such file or directory
 >  -sha1: No such file or directory
 >  MD5(/etc/passwd)= dbcf40cb4677824638143626b514ad4e
 >  [roam@edge:p1 /usr/src]$
 
 Actually, it does accept arguments.  Just not the same way openssl(1)
 does.  'dgst' is the actual program name inside OpenSSL; you can think
 of 'openssl md5' as being a symlink to 'openssl dgst md5'.  When you
 make a real symlink called 'md5' to /usr/bin/openssl, you're actually
 making a symlink to the 'dgst' program, which is embedded inside
 openssl(1).  You can't run other embedded programs, but you can switch
 algorithms.  Observe:
 
 	dima@hornet% ln -s /usr/bin/openssl md5
 	dima@hornet% ./md5 /HORNET
 	MD5(/HORNET)= e3823deaea6ac04928da26c118a36149
 	dima@hornet% ./md5 -sha1 /HORNET
 	SHA1(/HORNET)= 01539871ab3ece58b874bf47be652508a1e11649
 
 That said, I fail to see why this is a problem.
 
 >  (And before phk jumps at me, yes, I know that libmd was introduced waay
 >  before libcrypto made it into the source tree, and yes, I know that they
 >  have slightly different functionality - actually I even contributed some
 >  of that difference, remember? :P  .. and no, I'm not the one advocating
 >  libmd replacement with libcrypto, just stating that some people are :)
 
 I don't know if you think I'm one of these people, but I really have
 no opinion on libmd.  As long as things are using it, I have no
 problem with it staying.  However, new things probably shouldn't be
 implemented using it.  In this case, openssl(1) is almost the perfect
 fit: what we need is *already* implemented.  Besides, when the XYZ
 hash becomes popular, chances are OpenSSL will implement it quickly;
 then, for us to have an xyz(1), all we'd have to do is create another
 symlink.  This is certainly better than implementing XYZ in libmd.

From: Mark Peek <mark@whistle.com>
To: freebsd-gnats-submit@freebsd.org
Cc:  
Subject: Re: bin/28988: We need more simple message digesting tools
Date: Thu, 19 Jul 2001 08:32:25 -0700

 At 11:00 AM -0700 7/16/01, Anders Nordby wrote:
 >The following reply was made to PR bin/28988; it has been noted by GNATS.
 >
 >From: Anders Nordby <anders@fix.no>
 >To: Dima Dorfman <dima@unixfreak.org>
 >Cc: FreeBSD-gnats-submit@freebsd.org
 >Subject: Re: bin/28988: We need more simple message digesting tools
 >Date: Mon, 16 Jul 2001 19:57:13 +0200
 >
 >  On Sun, Jul 15, 2001 at 05:26:22AM -0700, Dima Dorfman wrote:
 >  >> Yes, I know openssl dgst -whatnot can do this. But the md5 
 >program is heavily
 >  >> used, and thereby I think we should have sha1 and rmd160 too.
 >  > Used by whom, and why aren't they using openssl(1)?
 >
 >  MD5 checksums are quite heavily used in FreeBSD, and AFAIK most people
 >  use the md5 program for generating MD5 fingerprints of files. At least,
 >  I do, and I haven't heard about anyone using openssl(1) for it in
 >  FreeBSD until recently. :-)
 >
 >  > The latter is more portable and more up-to-date.
 >
 >  More portable? md5(1) is just a frontend for libmd. If I make md5(1) use
 >  libcrypto instead, would that be better? And speaking of up-to-date,
 >  libmd must be the real issue here. It's the library that provides the
 >  actual message-digest fingerprinting code, and is based on SSLeay. We
 >  shouldn't be dragging old SSLeay code around when we have OpenSSL in the
 >  base system.
 
 
 Over the weekend, I had worked up these patches to md(1) to use 
 openssl instead of libmd. I was concerned about maintaining 
 compatibility with the existing md in terms of features/options and 
 size/location. As has been stated, openssl(1) doesn't have the same 
 options and is way too big (dynamically linked!) to put into /sbin.
 
 # ls -l /sbin/md5 /usr/bin/openssl
 -r-xr-xr-x  1 root  wheel   56460 Jul  8 11:36 /sbin/md5
 -r-xr-xr-x  1 root  wheel  256892 Jul  8 11:38 /usr/bin/openssl
 # file /sbin/md5 /usr/bin/openssl
 /sbin/md5:        ELF 32-bit LSB executable, Intel 80386, version 1 
 (FreeBSD), statically linked, stripped
 /usr/bin/openssl: ELF 32-bit LSB executable, Intel 80386, version 1 
 (FreeBSD), dynamically linked (uses shared libs), stripped
 
 The patch below is a quick rewrite of md5.c to use libcrypto instead 
 of libmd. The size is comparable and libcrypto provides a nice speed 
 increase.
 
 Mark
 
 -----------------------
 [/sbin/md5 is the old version and ./md5 is the new version]
 
 # ls -l ./md5 /sbin/md5
 -rwxr-xr-x  1 root  wheel  57204 Jul 15 13:57 ./md5
 -r-xr-xr-x  1 root  wheel  56460 Jul  8 11:36 /sbin/md5
 # file ./md5 /sbin/md5
 ./md5:     ELF 32-bit LSB executable, Intel 80386, version 1 
 (FreeBSD), statically linked, stripped
 /sbin/md5: ELF 32-bit LSB executable, Intel 80386, version 1 
 (FreeBSD), statically linked, stripped
 
 # /sbin/md5 -t ; /sbin/md5 -x ; /sbin/md5 -r md5.c Makefile
 MD5 time trial. Digesting 100000 10000-byte blocks ... done
 Digest = 766a2bb5d24bddae466c572bcabca3ee
 Time = 16 seconds
 Speed = 62500000 bytes/second
 MD5 test suite:
 MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
 MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
 MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
 MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
 MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
 MD5 
 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = 
 d174ab98d277d9f5a5611c2c9f419d9f
 MD5 
 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") 
 = 57edf4a22be3c955ac49da2e2107b67a
 2a741f9d5f4134df912f3a60a69d471f md5.c
 1fc6656efb78f623fdacab2f871c8a82 Makefile
 
 # ./md5 -t ; ./md5 -x ; ./md5 -r md5.c Makefile
 MD5 time trial. Digesting 100000 10000-byte blocks ... done
 Digest = 766a2bb5d24bddae466c572bcabca3ee
 Time = 10 seconds
 Speed = 100000000 bytes/second
 MD5 test suite:
 MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
 MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
 MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
 MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
 MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
 MD5 
 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = 
 d174ab98d277d9f5a5611c2c9f419d9f
 MD5 
 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") 
 = 57edf4a22be3c955ac49da2e2107b67a
 2a741f9d5f4134df912f3a60a69d471f md5.c
 1fc6656efb78f623fdacab2f871c8a82 Makefile
 
 
 
 Index: sbin/md5/Makefile
 ===================================================================
 RCS file: /cvs/freebsd/src/sbin/md5/Makefile,v
 retrieving revision 1.6
 diff -u -r1.6 Makefile
 --- sbin/md5/Makefile	2001/06/22 21:38:28	1.6
 +++ sbin/md5/Makefile	2001/07/15 21:03:23
 @@ -3,7 +3,7 @@
 
   PROG=	md5
 
 -LDADD+=	-lmd
 +LDADD+=	-lcrypto
   DPADD+= ${LIBMD}
 
   WARNS?=	2
 Index: sbin/md5/md5.c
 ===================================================================
 RCS file: /cvs/freebsd/src/sbin/md5/md5.c,v
 retrieving revision 1.25
 diff -u -r1.25 md5.c
 --- sbin/md5/md5.c	2001/06/29 06:21:57	1.25
 +++ sbin/md5/md5.c	2001/07/15 21:03:23
 @@ -24,13 +24,15 @@
 
   #include <sys/types.h>
   #include <err.h>
 -#include <md5.h>
 +#include <openssl/md5.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <time.h>
   #include <unistd.h>
 
 +#define DIGESTSIZE	16
 +#define HEXSIZE		(DIGESTSIZE * 2 + 1)
   /*
    * Length of test block, number of test blocks.
    */
 @@ -44,6 +46,8 @@
   static void MDTimeTrial(void);
   static void MDTestSuite(void);
   static void MDFilter(int);
 +static char *MDFile(char *, char *);
 +static char *Convert2Hex(unsigned char *, char *);
   static void usage(void);
 
   /* Main driver.
 @@ -60,7 +64,7 @@
   {
   	int     ch;
   	char   *p;
 -	char	buf[33];
 +	char	buf[HEXSIZE];
 
   	while ((ch = getopt(argc, argv, "pqrs:tx")) != -1)
   		switch (ch) {
 @@ -90,7 +94,7 @@
 
   	if (*argv) {
   		do {
 -			p = MD5File(*argv, buf);
 +			p = MDFile(*argv, buf);
   			if (!p)
   				warn("%s", *argv);
   			else
 @@ -113,15 +117,19 @@
   MDString(const char *string)
   {
   	size_t len = strlen(string);
 -	char buf[33];
 +	char digest[DIGESTSIZE];
 +	char buf[HEXSIZE];
 
 +	Convert2Hex(MD5(string, len, digest), buf);
 +
   	if (qflag)
 -		printf("%s\n", MD5Data(string, len, buf));
 +		printf("%s\n", buf);
   	else if (rflag)
 -		printf("%s \"%s\"\n", MD5Data(string, len, buf), string);
 +		printf("%s \"%s\"\n", buf, string);
   	else
 -		printf("MD5 (\"%s\") = %s\n", string, MD5Data(string, 
 len, buf));
 +		printf("MD5 (\"%s\") = %s\n", string, buf);
   }
 +
   /*
    * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks.
    */
 @@ -132,7 +140,8 @@
   	time_t  endTime, startTime;
   	unsigned char block[TEST_BLOCK_LEN];
   	unsigned int i;
 -	char   *p, buf[33];
 +	unsigned char digest[DIGESTSIZE];
 +	char    buf[HEXSIZE];
 
   	printf
   	    ("MD5 time trial. Digesting %d %d-byte blocks ...",
 @@ -147,16 +156,17 @@
   	time(&startTime);
 
   	/* Digest blocks */
 -	MD5Init(&context);
 +	MD5_Init(&context);
   	for (i = 0; i < TEST_BLOCK_COUNT; i++)
 -		MD5Update(&context, block, TEST_BLOCK_LEN);
 -	p = MD5End(&context,buf);
 +		MD5_Update(&context, block, TEST_BLOCK_LEN);
 +	MD5_Final(digest, &context);
 +	Convert2Hex(digest, buf);
 
   	/* Stop timer */
   	time(&endTime);
 
   	printf(" done\n");
 -	printf("Digest = %s", p);
 +	printf("Digest = %s", buf);
   	printf("\nTime = %ld seconds\n", (long) (endTime - startTime));
   	/* Be careful that endTime-startTime is not zero. (Bug fix from Ric
   	 * Anderson, ric@Artisoft.COM.) */
 @@ -194,15 +204,63 @@
   	MD5_CTX context;
   	unsigned int len;
   	unsigned char buffer[BUFSIZ];
 -	char buf[33];
 +	unsigned char digest[DIGESTSIZE];
 +	char buf[HEXSIZE];
 
 -	MD5Init(&context);
 +	MD5_Init(&context);
   	while ((len = fread(buffer, 1, BUFSIZ, stdin))) {
   		if (tee && len != fwrite(buffer, 1, len, stdout))
   			err(1, "stdout");
 -		MD5Update(&context, buffer, len);
 +		MD5_Update(&context, buffer, len);
 +	}
 +	MD5_Final(digest, &context);
 +	Convert2Hex(digest, buf);
 +
 +	printf("%s\n", buf);
 +}
 +
 +/*
 + * Digests the file and returns the hex string result.
 + */
 +static char *
 +MDFile(char *filename, char *buf)
 +{
 +	MD5_CTX context;
 +	unsigned int len;
 +	unsigned char buffer[BUFSIZ];
 +	unsigned char digest[DIGESTSIZE];
 +	FILE *fp;
 +
 +	if ((fp = fopen(filename, "r")) == NULL) {
 +		return NULL;
 +	}
 +	MD5_Init(&context);
 +	while ((len = fread(buffer, 1, BUFSIZ, fp))) {
 +		MD5_Update(&context, buffer, len);
 +	}
 +
 +	MD5_Final(digest, &context);
 +	Convert2Hex(digest, buf);
 +
 +	return buf;
 +}
 +
 +/*
 + * Convert a digest string into an ascii hex string.
 + */
 +static char *
 +Convert2Hex(unsigned char *digest, char *buf)
 +{
 +        static const char hex[]="0123456789abcdef";
 +	int i;
 +
 +	for (i = 0; i < DIGESTSIZE; i++) {
 +		buf[i+i] = hex[digest[i] >> 4];
 +		buf[i+i+1] = hex[digest[i] & 0x0f];
   	}
 -	printf("%s\n", MD5End(&context,buf));
 +	buf[i+i] = '\0';
 +
 +	return buf;
   }
 
   static void

From: Will Andrews <will@physics.purdue.edu>
To: Dima Dorfman <dima@unixfreak.org>
Cc: FreeBSD GNATS DB <FreeBSD-gnats-submit@FreeBSD.org>
Subject: Re: bin/28988: We need more simple message digesting tools
Date: Thu, 19 Jul 2001 12:28:10 -0500

 On Mon, Jul 16, 2001 at 10:30:01PM -0700, Dima Dorfman (dima@unixfreak.org) wrote:
 >  Why?  What's wrong with:
 >  
 >  	ln -s /usr/bin/openssl md5
 >  
 >  works for sha, sha1, ripemd160, and a few other algorithms.  The only
 >  thing wrong with it is that openssl doesn't support some of the
 >  options md5(1) does, and has a slightly different output format.
 
 The output thing is not a problem -- one can always pipe to
 sed(1) to solve it.
 
 -- 
 wca
State-Changed-From-To: open->closed 
State-Changed-By: kris 
State-Changed-When: Sat Jul 12 23:22:45 PDT 2003 
State-Changed-Why:  
Thanks for the submission, but as you note openssl already 
has this capability.  Duplicating code would not be a good 
idea. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=28988 
>Unformatted:
