--- a/src/utils/md5.cpp
+++ b/src/utils/md5.cpp
@@ -27,7 +27,7 @@
* This code is the same as the code published by RSA Inc. It has been
* edited for clarity and style only.
*/
-
+#ifndef TEST_MD5
#include <string.h>
#include "md5.h"
@@ -316,3 +316,129 @@
/* Zeroize sensitive information. */
memset ((void *)x, 0, sizeof (x));
}
+
+/*************** Convenience / utilities */
+void MD5Final(string &digest, MD5_CTX *context)
+{
+ unsigned char d[16];
+ MD5Final (d, context);
+ digest.assign((const char *)d, 16);
+}
+
+string& MD5String(const string& data, string& digest)
+{
+ MD5_CTX ctx;
+ MD5Init(&ctx);
+ MD5Update(&ctx, (const unsigned char*)data.c_str(), data.length());
+ MD5Final(digest, &ctx);
+ return digest;
+}
+
+string& MD5HexPrint(const string& digest, string &out)
+{
+ out.erase();
+ out.reserve(33);
+ static const char hex[]="0123456789abcdef";
+ const unsigned char *hash = (const unsigned char *)digest.c_str();
+ for (int i = 0; i < 16; i++) {
+ out.append(1, hex[hash[i] >> 4]);
+ out.append(1, hex[hash[i] & 0x0f]);
+ }
+ return out;
+}
+string& MD5HexScan(const string& xdigest, string& digest)
+{
+ digest.erase();
+ if (xdigest.length() != 32) {
+ return digest;
+ }
+ for (unsigned int i = 0; i < 16; i++) {
+ unsigned int val;
+ if (sscanf(xdigest.c_str() + 2*i, "%2x", &val) != 1) {
+ digest.erase();
+ return digest;
+ }
+ digest.append(1, (unsigned char)val);
+ }
+ return digest;
+}
+
+#include "readfile.h"
+class FileScanMd5 : public FileScanDo {
+public:
+ FileScanMd5(string& d) : digest(d) {}
+ virtual bool init(unsigned int size, string *reason)
+ {
+ MD5Init(&ctx);
+ return true;
+ }
+ virtual bool data(const char *buf, int cnt, string* reason)
+ {
+ MD5Update(&ctx, (const unsigned char*)buf, cnt);
+ return true;
+ }
+ string &digest;
+ MD5_CTX ctx;
+};
+bool MD5File(const string& filename, string &digest, string *reason)
+{
+ FileScanMd5 md5er(digest);
+ if (!file_scan(filename, &md5er, reason))
+ return false;
+ // We happen to know that digest and md5er.digest are the same object
+ MD5Final(md5er.digest, &md5er.ctx);
+ return true;
+}
+#else
+
+// Test driver
+#include <stdlib.h>
+
+#include <string>
+#include <iostream>
+#include "md5.h"
+
+using namespace std;
+
+static const char *thisprog;
+static char usage [] =
+"trmd5 filename\n\n"
+;
+static void
+Usage(void)
+{
+ fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
+ exit(1);
+}
+
+int main(int argc, const char **argv)
+{
+ thisprog = argv[0];
+ argc--; argv++;
+
+ if (argc != 1)
+ Usage();
+ string filename = *argv++;argc--;
+
+ string reason, digest;
+ if (!MD5File(filename, digest, &reason)) {
+ cerr << reason << endl;
+ exit(1);
+ } else {
+ string hex;
+ cout << "MD5 (" << filename << ") = " << MD5HexPrint(digest, hex) << endl;
+
+ string digest1;
+ MD5HexScan(hex, digest1);
+ if (digest1.compare(digest)) {
+ cout << "MD5HexScan Failure" << endl;
+ cout << MD5HexPrint(digest, hex) << " " << digest.length() << " -> "
+ << MD5HexPrint(digest1, hex) << " " << digest1.length() << endl;
+ exit(1);
+ }
+
+ }
+ exit(0);
+}
+
+#endif