#include "system.h" #include #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; }