225 lines
5.4 KiB
C
225 lines
5.4 KiB
C
#include "system.h"
|
|
#include <gcrypt.h>
|
|
#include "rpmio_internal.h"
|
|
#include "popt.h"
|
|
#include "debug.h"
|
|
|
|
static pgpHashAlgo hashalgo = PGPHASHALGO_MD5;
|
|
static rpmDigestFlags flags = RPMDIGEST_NONE;
|
|
extern int _rpmio_debug;
|
|
|
|
static int fips = 0;
|
|
static int gcrypt = 0;
|
|
|
|
const char * FIPSAdigest = "a9993e364706816aba3e25717850c26c9cd0d89d";
|
|
const char * FIPSBdigest = "84983e441c3bd26ebaae4aa1f95129e5e54670f1";
|
|
const char * FIPSCdigest = "34aa973cd4c4daa4f61eeb2bdbad27316534016f";
|
|
|
|
static struct poptOption optionsTable[] = {
|
|
{ "md5", '\0', POPT_ARG_VAL, &hashalgo, PGPHASHALGO_MD5, NULL, NULL },
|
|
{ "sha1",'\0', POPT_ARG_VAL, &hashalgo, PGPHASHALGO_SHA1, NULL, NULL },
|
|
#ifdef DYING
|
|
{ "reverse",'\0', POPT_BIT_SET, &flags, RPMDIGEST_REVERSE, NULL, NULL },
|
|
#endif
|
|
{ "fipsa",'\0', POPT_ARG_VAL, &fips, 1, NULL, NULL },
|
|
{ "fipsb",'\0', POPT_ARG_VAL, &fips, 2, NULL, NULL },
|
|
{ "fipsc",'\0', POPT_ARG_VAL, &fips, 3, NULL, NULL },
|
|
{ "gcrypt",'\0', POPT_ARG_VAL, &gcrypt, 1, NULL, NULL },
|
|
{ "debug",'d', POPT_ARG_VAL, &_rpmio_debug, -1, NULL, NULL },
|
|
POPT_AUTOHELP
|
|
POPT_TABLEEND
|
|
};
|
|
|
|
#define SHA1_CMD "/usr/bin/sha1sum"
|
|
#define MD5_CMD "/usr/bin/md5sum"
|
|
|
|
int
|
|
main(int argc, const char *argv[])
|
|
{
|
|
poptContext optCon;
|
|
const char ** args;
|
|
const char * ifn;
|
|
const char * ofn = "/dev/null";
|
|
DIGEST_CTX ctx = NULL;
|
|
GcryMDHd gcry = NULL;
|
|
const char * idigest;
|
|
const char * odigest;
|
|
const char * sdigest;
|
|
const char * digest;
|
|
size_t digestlen;
|
|
int asAscii = 1;
|
|
int reverse = 0;
|
|
int rc;
|
|
char appendix;
|
|
int i;
|
|
|
|
optCon = poptGetContext(argv[0], argc, argv, optionsTable, 0);
|
|
while ((rc = poptGetNextOpt(optCon)) > 0)
|
|
;
|
|
|
|
if (fips) {
|
|
struct rpmsw_s begin, end;
|
|
if (gcrypt)
|
|
gcry = gcry_md_open(GCRY_MD_SHA1, 0);
|
|
|
|
(void) rpmswNow(&begin);
|
|
|
|
if (gcrypt)
|
|
gcry_md_reset(gcry);
|
|
else
|
|
ctx = rpmDigestInit(PGPHASHALGO_SHA1, flags);
|
|
ifn = NULL;
|
|
appendix = ' ';
|
|
sdigest = NULL;
|
|
switch (fips) {
|
|
case 1:
|
|
ifn = "abc";
|
|
if (gcrypt)
|
|
gcry_md_write (gcry, ifn, strlen(ifn));
|
|
else
|
|
rpmDigestUpdate(ctx, ifn, strlen(ifn));
|
|
sdigest = FIPSAdigest;
|
|
appendix = 'A';
|
|
break;
|
|
case 2:
|
|
ifn = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
|
if (gcrypt)
|
|
gcry_md_write (gcry, ifn, strlen(ifn));
|
|
else
|
|
rpmDigestUpdate(ctx, ifn, strlen(ifn));
|
|
sdigest = FIPSBdigest;
|
|
appendix = 'B';
|
|
break;
|
|
case 3:
|
|
ifn = "aaaaaaaaaaa ...";
|
|
for (i = 0; i < 1000000; i++) {
|
|
if (gcrypt)
|
|
gcry_md_write (gcry, ifn, 1);
|
|
else
|
|
rpmDigestUpdate(ctx, ifn, 1);
|
|
}
|
|
sdigest = FIPSCdigest;
|
|
appendix = 'C';
|
|
break;
|
|
}
|
|
if (ifn == NULL)
|
|
return 1;
|
|
if (gcrypt) {
|
|
const unsigned char * s = gcry_md_read (gcry, 0);
|
|
char * t;
|
|
|
|
gcry_md_close(gcry);
|
|
digestlen = 2*20;
|
|
digest = t = xcalloc(1, digestlen+1);
|
|
for (i = 0; i < digestlen; i += 2) {
|
|
static const char hex[] = "0123456789abcdef";
|
|
*t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
|
|
*t++ = hex[ (unsigned)((*s++ ) & 0x0f) ];
|
|
}
|
|
*t = '\0';
|
|
} else
|
|
rpmDigestFinal(ctx, (void **)&digest, &digestlen, asAscii);
|
|
(void) rpmswNow(&end);
|
|
|
|
if (digest) {
|
|
fprintf(stdout, "%s %s\n", digest, ifn);
|
|
fflush(stdout);
|
|
free((void *)digest);
|
|
}
|
|
if (sdigest) {
|
|
fprintf(stdout, "%s FIPS PUB 180-1 Appendix %c\n", sdigest,
|
|
appendix);
|
|
fflush(stdout);
|
|
}
|
|
fprintf(stderr, "*** time %lu usecs\n", (unsigned long)rpmswDiff(&end, &begin));
|
|
return 0;
|
|
}
|
|
|
|
args = poptGetArgs(optCon);
|
|
rc = 0;
|
|
if (args)
|
|
while ((ifn = *args++) != NULL) {
|
|
FD_t ifd;
|
|
FD_t ofd;
|
|
unsigned char buf[BUFSIZ];
|
|
ssize_t nb;
|
|
|
|
sdigest = NULL;
|
|
{ char *se;
|
|
FILE * sfp;
|
|
|
|
se = buf;
|
|
*se = '\0';
|
|
se = stpcpy(se, ((hashalgo == PGPHASHALGO_SHA1) ? SHA1_CMD : MD5_CMD));
|
|
*se++ = ' ';
|
|
se = stpcpy(se, ifn);
|
|
if ((sfp = popen(buf, "r")) != NULL) {
|
|
fgets(buf, sizeof(buf), sfp);
|
|
if ((se = strchr(buf, ' ')) != NULL)
|
|
*se = '\0';
|
|
sdigest = xstrdup(buf);
|
|
pclose(sfp);
|
|
}
|
|
}
|
|
|
|
ifd = Fopen(ifn, "r.ufdio");
|
|
if (ifd == NULL || Ferror(ifd)) {
|
|
fprintf(stderr, _("cannot open %s: %s\n"), ifn, Fstrerror(ifd));
|
|
if (ifd) Fclose(ifd);
|
|
rc++;
|
|
continue;
|
|
}
|
|
idigest = NULL;
|
|
fdInitDigest(ifd, hashalgo, reverse);
|
|
|
|
ofd = Fopen(ofn, "w.ufdio");
|
|
if (ofd == NULL || Ferror(ofd)) {
|
|
fprintf(stderr, _("cannot open %s: %s\n"), ofn, Fstrerror(ofd));
|
|
if (ifd) Fclose(ifd);
|
|
if (ofd) Fclose(ofd);
|
|
rc++;
|
|
continue;
|
|
}
|
|
odigest = NULL;
|
|
fdInitDigest(ofd, hashalgo, reverse);
|
|
|
|
ctx = rpmDigestInit(hashalgo, flags);
|
|
|
|
while ((nb = Fread(buf, 1, sizeof(buf), ifd)) > 0) {
|
|
rpmDigestUpdate(ctx, buf, nb);
|
|
(void) Fwrite(buf, 1, nb, ofd);
|
|
}
|
|
|
|
fdFiniDigest(ifd, hashalgo, (void **)&idigest, NULL, asAscii);
|
|
Fclose(ifd);
|
|
|
|
Fflush(ofd);
|
|
fdFiniDigest(ofd, hashalgo, (void **)&odigest, NULL, asAscii);
|
|
Fclose(ofd);
|
|
|
|
rpmDigestFinal(ctx, (void **)&digest, &digestlen, asAscii);
|
|
|
|
if (digest) {
|
|
fprintf(stdout, "%s %s\n", digest, ifn);
|
|
fflush(stdout);
|
|
free((void *)digest);
|
|
}
|
|
if (idigest) {
|
|
fprintf(stdout, "%s in %s\n", idigest, ifn);
|
|
fflush(stdout);
|
|
free((void *)idigest);
|
|
}
|
|
if (odigest) {
|
|
fprintf(stdout, "%s out %s\n", odigest, ofn);
|
|
fflush(stdout);
|
|
free((void *)odigest);
|
|
}
|
|
if (sdigest) {
|
|
fprintf(stdout, "%s cmd %s\n", sdigest, ifn);
|
|
fflush(stdout);
|
|
free((void *)sdigest);
|
|
}
|
|
}
|
|
return rc;
|
|
}
|