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 }