00001 #include "system.h"
00002 #include <gcrypt.h>
00003 #include "rpmio_internal.h"
00004 #include "popt.h"
00005 #include "debug.h"
00006
00007 static pgpHashAlgo hashalgo = PGPHASHALGO_MD5;
00008 static rpmDigestFlags flags = RPMDIGEST_NONE;
00009 extern int _rpmio_debug;
00010
00011 static int fips = 0;
00012 static int gcrypt = 0;
00013
00014 const char * FIPSAdigest = "a9993e364706816aba3e25717850c26c9cd0d89d";
00015 const char * FIPSBdigest = "84983e441c3bd26ebaae4aa1f95129e5e54670f1";
00016 const char * FIPSCdigest = "34aa973cd4c4daa4f61eeb2bdbad27316534016f";
00017
00018 static struct poptOption optionsTable[] = {
00019 { "md5", '\0', POPT_ARG_VAL, &hashalgo, PGPHASHALGO_MD5, NULL, NULL },
00020 { "sha1",'\0', POPT_ARG_VAL, &hashalgo, PGPHASHALGO_SHA1, NULL, NULL },
00021 #ifdef DYING
00022 { "reverse",'\0', POPT_BIT_SET, &flags, RPMDIGEST_REVERSE, NULL, NULL },
00023 #endif
00024 { "fipsa",'\0', POPT_ARG_VAL, &fips, 1, NULL, NULL },
00025 { "fipsb",'\0', POPT_ARG_VAL, &fips, 2, NULL, NULL },
00026 { "fipsc",'\0', POPT_ARG_VAL, &fips, 3, NULL, NULL },
00027 { "gcrypt",'\0', POPT_ARG_VAL, &gcrypt, 1, NULL, NULL },
00028 { "debug",'d', POPT_ARG_VAL, &_rpmio_debug, -1, NULL, NULL },
00029 POPT_AUTOHELP
00030 POPT_TABLEEND
00031 };
00032
00033 #define SHA1_CMD "/usr/bin/sha1sum"
00034 #define MD5_CMD "/usr/bin/md5sum"
00035
00036 int
00037 main(int argc, const char *argv[])
00038 {
00039 poptContext optCon;
00040 const char ** args;
00041 const char * ifn;
00042 const char * ofn = "/dev/null";
00043 DIGEST_CTX ctx = NULL;
00044 GcryMDHd gcry = NULL;
00045 const char * idigest;
00046 const char * odigest;
00047 const char * sdigest;
00048 const char * digest;
00049 size_t digestlen;
00050 int asAscii = 1;
00051 int reverse = 0;
00052 int rc;
00053 char appendix;
00054 int i;
00055
00056 optCon = poptGetContext(argv[0], argc, argv, optionsTable, 0);
00057 while ((rc = poptGetNextOpt(optCon)) > 0)
00058 ;
00059
00060 if (fips) {
00061 struct rpmsw_s begin, end;
00062 if (gcrypt)
00063 gcry = gcry_md_open(GCRY_MD_SHA1, 0);
00064
00065 (void) rpmswNow(&begin);
00066
00067 if (gcrypt)
00068 gcry_md_reset(gcry);
00069 else
00070 ctx = rpmDigestInit(PGPHASHALGO_SHA1, flags);
00071 ifn = NULL;
00072 appendix = ' ';
00073 sdigest = NULL;
00074 switch (fips) {
00075 case 1:
00076 ifn = "abc";
00077 if (gcrypt)
00078 gcry_md_write (gcry, ifn, strlen(ifn));
00079 else
00080 rpmDigestUpdate(ctx, ifn, strlen(ifn));
00081 sdigest = FIPSAdigest;
00082 appendix = 'A';
00083 break;
00084 case 2:
00085 ifn = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
00086 if (gcrypt)
00087 gcry_md_write (gcry, ifn, strlen(ifn));
00088 else
00089 rpmDigestUpdate(ctx, ifn, strlen(ifn));
00090 sdigest = FIPSBdigest;
00091 appendix = 'B';
00092 break;
00093 case 3:
00094 ifn = "aaaaaaaaaaa ...";
00095 for (i = 0; i < 1000000; i++) {
00096 if (gcrypt)
00097 gcry_md_write (gcry, ifn, 1);
00098 else
00099 rpmDigestUpdate(ctx, ifn, 1);
00100 }
00101 sdigest = FIPSCdigest;
00102 appendix = 'C';
00103 break;
00104 }
00105 if (ifn == NULL)
00106 return 1;
00107 if (gcrypt) {
00108 const unsigned char * s = gcry_md_read (gcry, 0);
00109 char * t;
00110
00111 gcry_md_close(gcry);
00112 digestlen = 2*20;
00113 digest = t = xcalloc(1, digestlen+1);
00114 for (i = 0; i < digestlen; i += 2) {
00115 static const char hex[] = "0123456789abcdef";
00116 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
00117 *t++ = hex[ (unsigned)((*s++ ) & 0x0f) ];
00118 }
00119 *t = '\0';
00120 } else
00121 rpmDigestFinal(ctx, (void **)&digest, &digestlen, asAscii);
00122 (void) rpmswNow(&end);
00123
00124 if (digest) {
00125 fprintf(stdout, "%s %s\n", digest, ifn);
00126 fflush(stdout);
00127 free((void *)digest);
00128 }
00129 if (sdigest) {
00130 fprintf(stdout, "%s FIPS PUB 180-1 Appendix %c\n", sdigest,
00131 appendix);
00132 fflush(stdout);
00133 }
00134 fprintf(stderr, "*** time %lu usecs\n", (unsigned long)rpmswDiff(&end, &begin));
00135 return 0;
00136 }
00137
00138 args = poptGetArgs(optCon);
00139 rc = 0;
00140 if (args)
00141 while ((ifn = *args++) != NULL) {
00142 FD_t ifd;
00143 FD_t ofd;
00144 unsigned char buf[BUFSIZ];
00145 ssize_t nb;
00146
00147 sdigest = NULL;
00148 { char *se;
00149 FILE * sfp;
00150
00151 se = buf;
00152 *se = '\0';
00153 se = stpcpy(se, ((hashalgo == PGPHASHALGO_SHA1) ? SHA1_CMD : MD5_CMD));
00154 *se++ = ' ';
00155 se = stpcpy(se, ifn);
00156 if ((sfp = popen(buf, "r")) != NULL) {
00157 fgets(buf, sizeof(buf), sfp);
00158 if ((se = strchr(buf, ' ')) != NULL)
00159 *se = '\0';
00160 sdigest = xstrdup(buf);
00161 pclose(sfp);
00162 }
00163 }
00164
00165 ifd = Fopen(ifn, "r.ufdio");
00166 if (ifd == NULL || Ferror(ifd)) {
00167 fprintf(stderr, _("cannot open %s: %s\n"), ifn, Fstrerror(ifd));
00168 if (ifd) Fclose(ifd);
00169 rc++;
00170 continue;
00171 }
00172 idigest = NULL;
00173 fdInitDigest(ifd, hashalgo, reverse);
00174
00175 ofd = Fopen(ofn, "w.ufdio");
00176 if (ofd == NULL || Ferror(ofd)) {
00177 fprintf(stderr, _("cannot open %s: %s\n"), ofn, Fstrerror(ofd));
00178 if (ifd) Fclose(ifd);
00179 if (ofd) Fclose(ofd);
00180 rc++;
00181 continue;
00182 }
00183 odigest = NULL;
00184 fdInitDigest(ofd, hashalgo, reverse);
00185
00186 ctx = rpmDigestInit(hashalgo, flags);
00187
00188 while ((nb = Fread(buf, 1, sizeof(buf), ifd)) > 0) {
00189 rpmDigestUpdate(ctx, buf, nb);
00190 (void) Fwrite(buf, 1, nb, ofd);
00191 }
00192
00193 fdFiniDigest(ifd, hashalgo, (void **)&idigest, NULL, asAscii);
00194 Fclose(ifd);
00195
00196 Fflush(ofd);
00197 fdFiniDigest(ofd, hashalgo, (void **)&odigest, NULL, asAscii);
00198 Fclose(ofd);
00199
00200 rpmDigestFinal(ctx, (void **)&digest, &digestlen, asAscii);
00201
00202 if (digest) {
00203 fprintf(stdout, "%s %s\n", digest, ifn);
00204 fflush(stdout);
00205 free((void *)digest);
00206 }
00207 if (idigest) {
00208 fprintf(stdout, "%s in %s\n", idigest, ifn);
00209 fflush(stdout);
00210 free((void *)idigest);
00211 }
00212 if (odigest) {
00213 fprintf(stdout, "%s out %s\n", odigest, ofn);
00214 fflush(stdout);
00215 free((void *)odigest);
00216 }
00217 if (sdigest) {
00218 fprintf(stdout, "%s cmd %s\n", sdigest, ifn);
00219 fflush(stdout);
00220 free((void *)sdigest);
00221 }
00222 }
00223 return rc;
00224 }