home *** CD-ROM | disk | FTP | other *** search
- From: kent@sparky.imd.sterling.com (Kent Landfield)
- Newsgroups: comp.sources.misc
- Subject: v19i018: md4tools - MD4 netnews verification tools, Part02/02
- Message-ID: <1991May9.021107.28230@sparky.IMD.Sterling.COM>
- Date: 9 May 91 02:11:07 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: Kent Landfield <kent@sparky.imd.sterling.com>
- Posting-number: Volume 19, Issue 18
- Archive-name: md4tools/part02
-
- #! /bin/sh
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: Makefile TestArticle checkmd4.1 checkmd4.c hashmd4.1
- # hashmd4.c md4.h md4driver.c pipeit.c
- # Wrapped by kent@sparky on Tue May 7 23:23:54 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 2 (of 2)."'
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(1496 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X#
- X# Makefile for md4
- X#
- X
- XINSTALLDIR=/usr/local/bin
- XMAN_DIR=/usr/man/manl
- XMAN_SEC=l
- X
- XPROGS = md4 checkmd4 hashmd4
- X
- Xall: $(PROGS)
- X
- Xmd4: md4.o md4driver.o
- X $(CC) $(CFLAGS) -o $@ md4.o md4driver.o
- X
- Xcheckmd4: checkmd4.o pipeit.o
- X $(CC) $(CFLAGS) -o $@ checkmd4.o pipeit.o
- X
- Xhashmd4: hashmd4.o pipeit.o
- X $(CC) $(CFLAGS) -o $@ hashmd4.o pipeit.o
- X
- Xmd4.o: md4.c md4.h md4driver.c
- Xcheckmd4.o: checkmd4.c md4_def.h
- Xhashmd4: hashmd4.c md4_def.h
- Xpipeit.o: pipeit.c md4_def.h
- X
- Xclean:
- X rm -f md4driver.o md4.o
- X rm -f checkmd4.o hashmd4.o pipeit.o
- X
- Xclobber: clean
- X rm -f $(PROGS)
- X
- Xprint: print_md4 print_tools print_rfc
- X cprint README | lpr
- X cprint TestArticle | lpr
- X cprint Makefile | lpr
- X
- Xprint_tools:
- X cprint checkmd4.c | lpr
- X cprint hashmd4.c | lpr
- X cprint pipeit.c | lpr
- X cprint md4_def.h | lpr
- X psroff -man checkmd4.1
- X psroff -man hashmd4.1
- X
- Xprint_md4:
- X cprint md4.h | lpr
- X cprint md4.c | lpr
- X cprint md4driver.c | lpr
- X
- Xprint_rfc:
- X cprint rfc1186 | lpr
- X
- Xinstall: all
- X @echo Installing according to local convention
- X# strip md4 checkmd4 hashmd4
- X# cp md4 checkmd4 hashmd4 $(INSTALLDIR)
- X# chown bin $(INSTALLDIR)/md4
- X# chgrp bin $(INSTALLDIR)/md4
- X# chmod 755 $(INSTALLDIR)/md4
- X# chown bin $(INSTALLDIR)/checkmd4
- X# chgrp bin $(INSTALLDIR)/checkmd4
- X# chmod 755 $(INSTALLDIR)/checkmd4
- X# chown bin $(INSTALLDIR)/hashmd4
- X# chgrp bin $(INSTALLDIR)/hashmd4
- X# chmod 755 $(INSTALLDIR)/hashmd4
- X# cp checkmd4.1 $(MAN_DIR)/checkmd4.$(MAN_SEC)
- X# cp hashmd4.1 $(MAN_DIR)/hashmd4.$(MAN_SEC)
- X#
- END_OF_FILE
- if test 1496 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'TestArticle' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'TestArticle'\"
- else
- echo shar: Extracting \"'TestArticle'\" \(3146 characters\)
- sed "s/^X//" >'TestArticle' <<'END_OF_FILE'
- XPath: sparky!kent
- XFrom: kent@sparky.imd.sterling.com (Kent Landfield)
- XNewsgroups: sterling.test
- XSubject: This is a test of the MD4 fingerprint function
- XOrganization: Sterling Intelligence and Military Division
- XX-Md4-Signature: ea6ec5dcd12eb080587e12a6b4ceae23
- X
- XAs stated in RFC1186:
- X
- X This note describes the MD4 message digest algorithm. The algorithm
- X takes as input an input message of arbitrary length and produces as
- X output a 128-bit "fingerprint" or "message digest" of the input. It
- X is conjectured that it is computationally infeasible to produce two
- X messages having the same message digest, or to produce any message
- X having a given prespecified target message digest. The MD4 algorithm
- X is thus ideal for digital signature applications, where a large file
- X must be "compressed" in a secure manner before being signed with the
- X RSA public-key cryptosystem.
- X
- XMD4 can be used to apply a fingerprint on an article posted to USENET that,
- Xwhen run through a verification tool, will tell you whether an article has
- Xbeen corrupted. It does not detect or prevent complete replacement of the
- Xarticle. Think of MD4 as a super-strong checksum.
- X
- XThis package is an "assembled" set of tools that uses the MD4 Message
- XDigest Algorithm specified in RFC1186. There are three parts to the package.
- X
- Xmd4 - This is the heart of the tools. The code was taken from RFC1186,
- X "The MD4 Message Digest Algorithm" authored by Ronald L. Rivest.
- X
- XI *completely* and shamefully stole the MD4 code from the RFC and as such it
- Xmust be distributed under the terms specified in md4.c, md4.h and md4driver.c.
- XThanks to Ron for the code and to RSA Data Security, Inc. for giving me the
- Xpermission to post it.
- X
- Xhashmd4 - This program is used to apply an MD4 digest on a specified
- X USENET article. A new header is added to the article. The
- X header X-Md4-Signature: contains the value that will be checked
- X against to determine if the article is intact.
- X
- Xcheckmd4 - This is the program used to check whether the MD4 digest
- X of a USENET article indicates whether or not the article
- X has been tampered with.
- X
- XI would like to thank Rich Salz for posting snefru and giving me something
- Xto "hack".. :-) checkmd4 and hashmd4 look almost exactly like Rich's code
- Xfor good reason. They are... I did the bare minimum to get this working.
- XThat's all I had to do... :-) For those of you currently using hashnews
- Xand checknews, this (other than the names) should be a plug amd play...
- X
- XThere are manual pages for checkmd4 and for hashmd4 supplied. The actual
- XRFC1186 is supplied as a reference for MD4.
- X
- XCode that does not contain an explicit RSA copyright was derived from
- XRich Salz's code that was already in the public domain. Feel free to do
- Xwhat you want with those pieces.
- X
- XThis code needs a 32bit machine; good luck if you've only got 16 bits!
- X
- XStarting with this posting, I am going to be using hashmd4 on all my
- Xc.s.m articles. While I don't think that this is worth doing for most
- Xgeneral Usenix articles, I think it will be an interesting experiment for
- Xarchives.
- X
- XEnjoy!
- X -Kent+
- END_OF_FILE
- if test 3146 -ne `wc -c <'TestArticle'`; then
- echo shar: \"'TestArticle'\" unpacked with wrong size!
- fi
- # end of 'TestArticle'
- fi
- if test -f 'checkmd4.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'checkmd4.1'\"
- else
- echo shar: Extracting \"'checkmd4.1'\" \(1024 characters\)
- sed "s/^X//" >'checkmd4.1' <<'END_OF_FILE'
- X.TH CHECKMD4 1 LOCAL
- X.SH NAME
- Xcheckmd4 \- Check the MD4 hash code on a Usenet article
- X.SH SYNOPSIS
- X.B checkmd4
- X[
- X.B \-n
- X] [
- X.I input
- X]
- X.SH DESCRIPTION
- X.I Checkmd4
- Xreads a Usenet article from the named file, or standard input if no file
- Xis given.
- XIt filters out the headers and calls
- X.IR md4
- X(see RFC1186) to generate a one-way hash signature or "message digest" for
- Xthe article. It compares this with the value specified in the X-Md4-Signature:
- Xheader, and prints a message indicating whether they match or not.
- XTo suppress the message, use the ``\-s'' flag.
- X.PP
- XThe program will exit with status zero if the article is okay. An exit value
- Xof one is returned if the signatures don't match, or a two if no
- XX-Md4-Signature header can be found.
- X.SH WARNING
- X.I Checkmd4
- Xwill only prove if an article has been tampered with; it does not
- Xprovide any authentication.
- X.SH AUTHOR
- X.nf
- XOriginally written by Rich Salz <rsalz@bbn.com>
- XHacked by Kent Landfield <kent@sparky.imd.sterling.com>
- X.fi
- X.SH "SEE ALSO"
- Xhashmd4(1L), RFC1186.
- END_OF_FILE
- if test 1024 -ne `wc -c <'checkmd4.1'`; then
- echo shar: \"'checkmd4.1'\" unpacked with wrong size!
- fi
- # end of 'checkmd4.1'
- fi
- if test -f 'checkmd4.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'checkmd4.c'\"
- else
- echo shar: Extracting \"'checkmd4.c'\" \(2713 characters\)
- sed "s/^X//" >'checkmd4.c' <<'END_OF_FILE'
- X/*
- X** Verify a Usenet article with a MD4 hash header.
- X*/
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "md4_def.h"
- X
- X#ifndef isascii
- X#define isascii(c) (1)
- X#endif /* isascii */
- X
- Xextern char *optarg;
- Xextern int optind;
- X
- Xextern char *mktemp();
- Xextern char *Md4Close();
- Xextern char *strcpy();
- Xextern FILE *Md4Open();
- X
- X
- Xstatic void
- XUsage()
- X{
- X (void)fprintf(stderr, "Usage: checkhash [filename]\n");
- X exit(1);
- X}
- X
- X
- Xmain(ac, av)
- X int ac;
- X char *av[];
- X{
- X char *p;
- X char buff[BUFSIZ];
- X char Checksum[40];
- X FILE *Input;
- X FILE *Md4;
- X int i;
- X int Silent;
- X
- X /* Set defaults. */
- X Silent = FALSE;
- X
- X /* Parse JCL. */
- X while ((i = getopt(ac, av, "s")) != EOF)
- X switch (i) {
- X default:
- X Usage();
- X /* NOTREACHED */
- X case 's':
- X Silent = TRUE;
- X break;
- X }
- X
- X /* Get input. */
- X ac -= optind;
- X av += optind;
- X switch (ac) {
- X default:
- X Usage();
- X case 0:
- X Input = stdin;
- X break;
- X case 1:
- X if ((Input = fopen(av[0], "r")) == NULL) {
- X perror("No input");
- X (void)fprintf(stderr, "Can't open \"%s\" for reading.\n", av[0]);
- X exit(1);
- X }
- X break;
- X }
- X
- X /* Read headers, looking for the checksum. */
- X Checksum[0] = '\0';
- X while (fgets(buff, sizeof buff, Input)) {
- X if (buff[0] == '\n')
- X break;
- X if (buff[0] == HDRFIRSTCHAR
- X && strncmp(buff, CHECKSUMHDR, sizeof CHECKSUMHDR - 1) == 0) {
- X p = &buff[sizeof CHECKSUMHDR] + 1;
- X /* Right length, allowing for the newline? */
- X if (strlen(p) != HDRTEXTSIZE + 1) {
- X if (!Silent)
- X (void)printf("%d Wrong length:\n\t%s", strlen(p) ,buff);
- X continue;
- X }
- X (void)strcpy(Checksum, p);
- X Checksum[HDRTEXTSIZE] = '\0';
- X for (p = Checksum; *p; p++)
- X if (*p != ' ' && !(isascii(*p) && isxdigit(*p)))
- X break;
- X if (*p) {
- X if (!Silent)
- X (void)printf("Bad character '%c':\n\t%s", *p, buff);
- X /* Broke out before reaching the end, invalid header. */
- X Checksum[0] = '\0';
- X }
- X }
- X }
- X
- X if (Checksum[0] == '\0') {
- X if (!Silent)
- X (void)printf("No valid checksum header found.\n");
- X exit(2);
- X }
- X
- X /* Call up Md4. */
- X if ((Md4 = Md4Open()) == NULL) {
- X if (!Silent)
- X perror("Can't open pipe to md4");
- X exit(2);
- X }
- X
- X /* Send the rest of the article down the pipe. */
- X while (fgets(buff, sizeof buff, Input))
- X (void)fputs(buff, Md4);
- X (void)fclose(Input);
- X
- X if ((p = Md4Close()) == NULL) {
- X if (!Silent)
- X perror("Can't open tempfile");
- X exit(2);
- X }
- X
- X /* Compare them. */
- X if (strcmp(p, Checksum) == 0) {
- X if (!Silent)
- X (void)printf("Valid.\n");
- X exit(0);
- X }
- X if (!Silent) {
- X (void)printf("Invalid!\n");
- X (void)printf("Computed: %s\n", p);
- X (void)printf(" Posted: %s\n", Checksum);
- X }
- X exit(1);
- X}
- END_OF_FILE
- if test 2713 -ne `wc -c <'checkmd4.c'`; then
- echo shar: \"'checkmd4.c'\" unpacked with wrong size!
- fi
- # end of 'checkmd4.c'
- fi
- if test -f 'hashmd4.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'hashmd4.1'\"
- else
- echo shar: Extracting \"'hashmd4.1'\" \(1586 characters\)
- sed "s/^X//" >'hashmd4.1' <<'END_OF_FILE'
- X.TH HASHMD4 1 LOCAL
- X.SH NAME
- Xhashmd4 \- add a MD4 hash to a Usenet article
- X.SH SYNOPSIS
- X.B hashmd4
- X[
- X.B \-n
- X] [
- X.I input
- X]
- X.SH DESCRIPTION
- XThis program is used to apply an MD4 digest, or fingerprint, on an article
- Xintended to be posted to USENET.
- X.I Hashmd4
- Xadds the X-Md4-Signature: header to the article. The header contains
- Xthe article's MD4 signature value that will be checked by
- X.IR checkmd4
- Xto determine if the article is intact.
- X.I Hashmd4
- Xcalls
- X.IR md4
- X(See RFC1186) to generate a one-way hash signature for the article.
- X.PP
- XIf a file is named on the command line, then
- X.I hashmd4
- Xwill overwrite the named file after inserting the md4 hashcode.
- XIf no file is named, the program will read the article from standard
- Xinput, and write the new article on standard output; this makes it
- Xconvenient to do ``:%!hashmd4'' from
- X.IR vi (1)
- Xjust before exiting the editor with your article in it.
- X.PP
- XBy default,
- X.I hashmd4
- Xwill try to read the file ``.signature'' in your home directory and
- Xappend it to the article.
- XIt tries to simulate the actions of B2.11
- X.IR inews (8).
- XTo suppress this check (for example, if you append your own signature),
- Xuse the ``\-n'' flag.
- XThe header that hashmd4 puts on an article is of the form
- X.IP
- XX-Md4-Signature: value
- X.SH WARNING
- X.I Hashmd4
- Xusage will only prove if an article has or has no been tampered with. It
- Xdoes not provide any authentication.
- X.SH AUTHOR
- X.nf
- XOriginally written as hashnews for snefru by Rich Salz <rsalz@bbn.com>
- XHacked into hashmd4 by Kent Landfield <kent@sparky.imd.sterling.com>
- X.fi
- X.SH "SEE ALSO"
- Xcheckmd4(1L), RFC1186.
- END_OF_FILE
- if test 1586 -ne `wc -c <'hashmd4.1'`; then
- echo shar: \"'hashmd4.1'\" unpacked with wrong size!
- fi
- # end of 'hashmd4.1'
- fi
- if test -f 'hashmd4.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'hashmd4.c'\"
- else
- echo shar: Extracting \"'hashmd4.c'\" \(4909 characters\)
- sed "s/^X//" >'hashmd4.c' <<'END_OF_FILE'
- X/*
- X** Call MD4 on something about to be feed into INEWS. Then, rewrite
- X** the file to add the X-Md4-Signature header.
- X*/
- X#include <stdio.h>
- X#include <pwd.h>
- X#include "md4_def.h"
- X
- X#ifdef USE_STRCHR
- X#define IDX strchr
- X#else
- X#define IDX index
- X#endif /* USE_STRCHR */
- X
- X#ifndef SEEK_ABS
- X#define SEEK_ABS 0
- X#endif /* SEEK_ABS */
- X
- Xextern char *optarg;
- Xextern int optind;
- X
- Xextern char *getenv();
- Xextern char *IDX();
- Xextern char *mktemp();
- Xextern char *Md4Close();
- Xextern char *strcpy();
- Xextern FILE *Md4Open();
- Xextern long ftell();
- Xextern struct passwd *getpwuid();
- X#ifdef CHARPSPRINTF
- Xextern char *sprintf();
- X#endif /* CHARPSPRINTF */
- X
- Xstatic void
- XUsage()
- X{
- X (void)fprintf(stderr, "Usage: hashmd4 articlename\n");
- X exit(1);
- X}
- X
- X
- X/*
- X** Simulate what B2.11 inews does for appending signatures.
- X*/
- Xstatic int
- XAppendSignature(Md4)
- X FILE *Md4;
- X{
- X char *p;
- X char buff[256];
- X FILE *F;
- X int i;
- X struct passwd *pwd;
- X
- X if ((p = getenv("HOME")) == NULL
- X && (p = getenv("LOGDIR")) == NULL) {
- X if ((pwd = getpwuid(getuid())) == NULL)
- X return 0;
- X p = pwd->pw_dir;
- X }
- X (void)sprintf(buff, "%s/.signature", p);
- X if ((F = fopen(buff, "r")) == NULL)
- X return 0;
- X for (i = 0; fgets(buff, sizeof buff, F); i++)
- X if (IDX(buff, '\n') == NULL) {
- X i = 0;
- X break;
- X }
- X if (i > 5 || i == 0) {
- X (void)fclose(F);
- X return 0;
- X }
- X (void)fprintf(Md4, "-- \n");
- X rewind(F);
- X while (fgets(buff, sizeof buff, F))
- X (void)fputs(buff, Md4);
- X (void)fclose(F);
- X return i;
- X}
- X
- X
- Xmain(ac, av)
- X int ac;
- X char *av[];
- X{
- X int i;
- X int CheckSignature;
- X FILE *Input;
- X FILE *Md4;
- X FILE *Output;
- X FILE *Body;
- X char buff[BUFSIZ];
- X char *p;
- X char tempfile[20];
- X char bodyfile[20];
- X long cookie;
- X
- X /* Set defaults. */
- X CheckSignature = TRUE;
- X
- X /* Parse JCL. */
- X while ((i = getopt(ac, av, "n")) != EOF)
- X switch (i) {
- X default:
- X Usage();
- X case 'n':
- X CheckSignature = FALSE;
- X break;
- X }
- X
- X /* Get input. */
- X ac -= optind;
- X av += optind;
- X switch (ac) {
- X default:
- X Usage();
- X /* NOTREACHED */
- X case 0:
- X /* We're being piped into. Create a temp file to hold the
- X * article body. */
- X Input = stdin;
- X (void)strcpy(bodyfile, "/tmp/hashBXXXXXX");
- X (void)mktemp(bodyfile);
- X if ((Body = fopen(bodyfile, "w")) == NULL) {
- X perror("No temporary");
- X (void)fprintf(stderr, "Can't open \"%s\" for writing.\n",
- X bodyfile);
- X exit(1);
- X }
- X break;
- X case 1:
- X if ((Input = fopen(av[0], "r")) == NULL) {
- X perror("No input");
- X (void)fprintf(stderr, "Can't open \"%s\" for reading.\n", av[0]);
- X exit(1);
- X }
- X Body = NULL;
- X break;
- X }
- X
- X /* Get output file. */
- X (void)strcpy(tempfile, "/tmp/hashHXXXXXX");
- X (void)mktemp(tempfile);
- X if ((Output = fopen(tempfile, "w")) == NULL) {
- X perror("No output");
- X (void)fprintf(stderr, "Can't open \"%s\" for writing.\n", tempfile);
- X exit(1);
- X }
- X
- X /* Open stream to md4. */
- X if ((Md4 = Md4Open()) == NULL) {
- X perror("Can't open pipe to md4");
- X (void)fclose(Output);
- X (void)unlink(tempfile);
- X exit(1);
- X }
- X
- X /* Read article, skipping headers. */
- X while (fgets(buff, sizeof buff, Input)) {
- X if (buff[strlen(buff) - 1] != '\n')
- X (void)fprintf(stderr, "Warning, line truncated:\n%s\n",
- X buff);
- X if (buff[0] == '\n')
- X break;
- X (void)fputs(buff, Output);
- X }
- X
- X /* If not from stdin we can seek, so remember where the headers end. */
- X if (Body == NULL)
- X cookie = ftell(Input);
- X
- X /* Send rest of article to md4. */
- X while (fgets(buff, sizeof buff, Input)) {
- X if (buff[strlen(buff) - 1] != '\n')
- X (void)fprintf(stderr, "Warning, line truncated:\n%s\n",
- X buff);
- X (void)fputs(buff, Md4);
- X if (Body)
- X (void)fputs(buff, Body);
- X }
- X
- X /* Do the signature? */
- X if (CheckSignature) {
- X if ((i = AppendSignature(Md4)) == 0)
- X (void)fprintf(stderr, ".signature unreadable or too long...\n");
- X }
- X
- X (void)fclose(Input);
- X
- X /* Write the checksum. */
- X if (p = Md4Close())
- X (void)fprintf(Output, "%s: %s\n", CHECKSUMHDR, p);
- X else
- X (void)fprintf(stderr, "Md4 checksum lost!?\n");
- X
- X /* Send the article body. */
- X if (Body) {
- X (void)fclose(Body);
- X Input = fopen(bodyfile, "r");
- X }
- X else {
- X Input = fopen(av[0], "r");
- X (void)fseek(Input, cookie, SEEK_ABS);
- X }
- X (void)fputs("\n", Output);
- X while (fgets(buff, sizeof buff, Input))
- X (void)fputs(buff, Output);
- X (void)fclose(Output);
- X
- X if (Input == stdin)
- X /* Input is stdin, so send output to stdout. */
- X Output = stdout;
- X else if ((Output = fopen(av[0], "w")) == NULL) {
- X perror("Can't rewrite file");
- X (void)fprintf(stderr,
- X "Can't overwrite \"%s\", output is in \"%s\".\n",
- X av[0], tempfile);
- X exit(1);
- X }
- X
- X Input = fopen(tempfile, "r");
- X while (fgets(buff, sizeof buff, Input))
- X (void)fputs(buff, Output);
- X
- X if (Output != stdout);
- X (void)unlink(tempfile);
- X (void)fclose(Output);
- X exit(0);
- X}
- END_OF_FILE
- if test 4909 -ne `wc -c <'hashmd4.c'`; then
- echo shar: \"'hashmd4.c'\" unpacked with wrong size!
- fi
- # end of 'hashmd4.c'
- fi
- if test -f 'md4.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'md4.h'\"
- else
- echo shar: Extracting \"'md4.h'\" \(3266 characters\)
- sed "s/^X//" >'md4.h' <<'END_OF_FILE'
- X/*
- X*--------------------------------------------------------------------------*
- X* (C) Copyright 1990, RSA Data Security, Inc. All rights reserved. *
- X* License to copy and use this software is granted provided it is *
- X* identified as the "RSA Data Security, Inc. MD4 message digest algorithm" *
- X* in all material mentioning or referencing this software or function. *
- X* *
- X* License is also granted to make and use derivative works provided such *
- X* works are identified as "derived from the RSA Data Securitry, Inc. MD4 *
- X* message digest algorithm" in all material mentioning or referencing the *
- X* derived work. *
- X* *
- X* RSA Data Security, Inc. makes no representations concerning the *
- X* merchantability of this software or the suitability of the software *
- X* for any particular purpose. It is provided "as is" without express *
- X* or implied warranty of any kind. *
- X* *
- X* These notices must be retained in any copies of any part of this *
- X* documentation and/or software. *
- X*--------------------------------------------------------------------------*
- X** ********************************************************************
- X** md4.h -- Header file for implementation of **
- X** MD4 Message Digest Algorithm **
- X** Updated: 2/13/90 by Ronald L. Rivest **
- X** (C) 1990 RSA Data Security, Inc. **
- X** ********************************************************************
- X*/
- X
- X/* MDstruct is the data structure for a message digest computation.
- X*/
- Xtypedef struct {
- X unsigned int buffer[4]; /* Holds 4-word result of MD computation */
- X unsigned char count[8]; /* Number of bits processed so far */
- X unsigned int done; /* Nonzero means MD computation finished */
- X} MDstruct, *MDptr;
- X
- X/* MDbegin(MD)
- X** Input: MD -- an MDptr
- X** Initialize the MDstruct prepatory to doing a message digest
- X** computation.
- X*/
- Xextern void MDbegin();
- X
- X/* MDupdate(MD,X,count)
- X** Input: MD -- an MDptr
- X** X -- a pointer to an array of unsigned characters.
- X** count -- the number of bits of X to use (an unsigned int).
- X** Updates MD using the first "count" bits of X.
- X** The array pointed to by X is not modified.
- X** If count is not a multiple of 8, MDupdate uses high bits of
- X** last byte.
- X** This is the basic input routine for a user.
- X** The routine terminates the MD computation when count < 512, so
- X** every MD computation should end with one call to MDupdate with a
- X** count less than 512. Zero is OK for a count.
- X*/
- Xextern void MDupdate();
- X
- X/* MDprint(MD)
- X** Input: MD -- an MDptr
- X** Prints message digest buffer MD as 32 hexadecimal digits.
- X** Order is from low-order byte of buffer[0] to high-order byte
- X** of buffer[3].
- X** Each byte is printed with high-order hexadecimal digit first.
- X*/
- Xextern void MDprint();
- X
- X/*
- X** End of md4.h
- X*/
- END_OF_FILE
- if test 3266 -ne `wc -c <'md4.h'`; then
- echo shar: \"'md4.h'\" unpacked with wrong size!
- fi
- # end of 'md4.h'
- fi
- if test -f 'md4driver.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'md4driver.c'\"
- else
- echo shar: Extracting \"'md4driver.c'\" \(4915 characters\)
- sed "s/^X//" >'md4driver.c' <<'END_OF_FILE'
- X/*
- X*--------------------------------------------------------------------------*
- X* (C) Copyright 1990, RSA Data Security, Inc. All rights reserved. *
- X* License to copy and use this software is granted provided it is *
- X* identified as the "RSA Data Security, Inc. MD4 message digest algorithm" *
- X* in all material mentioning or referencing this software or function. *
- X* *
- X* License is also granted to make and use derivative works provided such *
- X* works are identified as "derived from the RSA Data Securitry, Inc. MD4 *
- X* message digest algorithm" in all material mentioning or referencing the *
- X* derived work. *
- X* *
- X* RSA Data Security, Inc. makes no representations concerning the *
- X* merchantability of this software or the suitability of the software *
- X* for any particular purpose. It is provided "as is" without express *
- X* or implied warranty of any kind. *
- X* *
- X* These notices must be retained in any copies of any part of this *
- X* documentation and/or software. *
- X*--------------------------------------------------------------------------*
- X** ********************************************************************
- X** md4driver.c -- sample routines to test **
- X** MD4 message digest algorithm. **
- X** Updated: 2/16/90 by Ronald L. Rivest **
- X** (C) 1990 RSA Data Security, Inc. **
- X** ********************************************************************
- X*/
- X
- X#include <stdio.h>
- X#include "md4.h"
- X
- X/* MDtimetrial()
- X** A time trial routine, to measure the speed of MD4.
- X** Measures speed for 1M blocks = 64M bytes.
- X*/
- XMDtimetrial()
- X{ unsigned int X[16];
- X MDstruct MD;
- X int i;
- X double t;
- X for (i=0;i<16;i++) X[i] = 0x01234567 + i;
- X printf
- X ("MD4 time trial. Processing 1 million 64-character blocks...\n");
- X clock();
- X MDbegin(&MD);
- X for (i=0;i<1000000;i++) MDupdate(&MD,X,512);
- X MDupdate(&MD,X,0);
- X t = (double) clock(); /* in microseconds */
- X MDprint(&MD); printf(" is digest of 64M byte test input.\n");
- X printf("Seconds to process test input: %g\n",t/1e6);
- X printf("Characters processed per second: %ld.\n",(int)(64e12/t));
- X}
- X
- X/* MDstring(s)
- X** Computes the message digest for string s.
- X** Prints out message digest, a space, the string (in quotes) and a
- X** carriage return.
- X*/
- XMDstring(s)
- Xunsigned char *s;
- X{ unsigned int i, len = strlen(s);
- X MDstruct MD;
- X MDbegin(&MD);
- X for (i=0;i+64<=len;i=i+64) MDupdate(&MD,s+i,512);
- X MDupdate(&MD,s+i,(len-i)*8);
- X MDprint(&MD);
- X printf(" \"%s\"\n",s);
- X}
- X
- X/* MDfile(filename)
- X** Computes the message digest for a specified file.
- X** Prints out message digest, a space, the file name, and a
- X** carriage return.
- X*/
- XMDfile(filename)
- Xchar *filename;
- X{ FILE *f = fopen(filename,"rb");
- X unsigned char X[64];
- X MDstruct MD;
- X int b;
- X if (f == NULL)
- X { printf("%s can't be opened.\n",filename); return; }
- X MDbegin(&MD);
- X while ((b=fread(X,1,64,f))!=0) MDupdate(&MD,X,b*8);
- X MDupdate(&MD,X,0);
- X MDprint(&MD);
- X printf(" %s\n",filename);
- X fclose(f);
- X}
- X
- X/* MDfilter()
- X** Writes the message digest of the data from stdin onto stdout,
- X** followed by a carriage return.
- X*/
- XMDfilter()
- X{ unsigned char X[64];
- X MDstruct MD;
- X int b;
- X MDbegin(&MD);
- X while ((b=fread(X,1,64,stdin))!=0) MDupdate(&MD,X,b*8);
- X MDupdate(&MD,X,0);
- X MDprint(&MD);
- X printf("\n");
- X}
- X
- X/* MDtestsuite()
- X** Run a standard suite of test data.
- X*/
- XMDtestsuite()
- X{
- X printf("MD4 test suite results:\n");
- X MDstring("");
- X MDstring("a");
- X MDstring("abc");
- X MDstring("message digest");
- X MDstring("abcdefghijklmnopqrstuvwxyz");
- X MDstring
- X ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
- X MDfile("foo"); /* Contents of file foo are "abc" */
- X}
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar *argv[];
- X{ int i;
- X /* For each command line argument in turn:
- X ** filename -- prints message digest and name of file
- X ** -sstring -- prints message digest and contents of string
- X ** -t -- prints time trial statistics for 64M bytes
- X ** -x -- execute a standard suite of test data
- X ** (no args) -- writes messages digest of stdin onto stdout
- X */
- X if (argc==1) MDfilter();
- X else
- X for (i=1;i<argc;i++)
- X if (argv[i][0]=='-' && argv[i][1]=='s') MDstring(argv[i]+2);
- X else if (strcmp(argv[i],"-t")==0) MDtimetrial();
- X else if (strcmp(argv[i],"-x")==0) MDtestsuite();
- X else MDfile(argv[i]);
- X}
- X
- X/*
- X** end of md4driver.c
- X*/
- END_OF_FILE
- if test 4915 -ne `wc -c <'md4driver.c'`; then
- echo shar: \"'md4driver.c'\" unpacked with wrong size!
- fi
- # end of 'md4driver.c'
- fi
- if test -f 'pipeit.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pipeit.c'\"
- else
- echo shar: Extracting \"'pipeit.c'\" \(1266 characters\)
- sed "s/^X//" >'pipeit.c' <<'END_OF_FILE'
- X/*
- X** Utility routines to interface to the MD4 program as a filter.
- X*/
- X#include <stdio.h>
- X#include "md4_def.h"
- X
- X#ifdef USE_STRCHR
- X#define RDX strrchr
- X#else
- X#define RDX rindex
- X#endif /* USE_STRCHR */
- X
- Xstatic char OutputFile[] = "/tmp/hashcodeXXXXXX";
- Xstatic char ChecksumBuffer[HDRTEXTSIZE + 2];
- Xstatic FILE *Stream;
- X
- Xextern char *RDX();
- Xextern char *mktemp();
- X#ifdef CHARPSPRINTF
- Xextern char *sprintf();
- X#endif /* CHARPSPRINTF */
- X
- X
- X/*
- X** Spawn a MD4 that has its output redirected.
- X*/
- XFILE *
- XMd4Open()
- X{
- X char buff[sizeof OutputFile + 20];
- X
- X /* Open stream to md4. */
- X (void)mktemp(OutputFile);
- X (void)sprintf(buff, "md4 >%s", OutputFile);
- X if ((Stream = popen(buff, "w")) == NULL)
- X (void)unlink(OutputFile);
- X return Stream;
- X}
- X
- X
- X/*
- X** Close the pipe and read in the Md4's output.
- X*/
- Xchar *
- XMd4Close()
- X{
- X FILE *F;
- X char *p;
- X
- X (void)pclose(Stream);
- X
- X /* Open the output file, read the one line. */
- X if ((F = fopen(OutputFile, "r")) == NULL)
- X return NULL;
- X p = fgets(ChecksumBuffer, sizeof ChecksumBuffer, F);
- X (void)fclose(F);
- X (void)unlink(OutputFile);
- X if (p == NULL)
- X return NULL;
- X
- X /* Kill the newline. */
- X if ((p = RDX(ChecksumBuffer, '\n')) == NULL)
- X return NULL;
- X *p = '\0';
- X return ChecksumBuffer;
- X}
- END_OF_FILE
- if test 1266 -ne `wc -c <'pipeit.c'`; then
- echo shar: \"'pipeit.c'\" unpacked with wrong size!
- fi
- # end of 'pipeit.c'
- fi
- echo shar: End of archive 2 \(of 2\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-