From cdcfee48b9720d589a4e2cd43725e8229ca336f9 Mon Sep 17 00:00:00 2001 From: bigbiff bigbiff Date: Wed, 27 Feb 2013 21:11:26 -0500 Subject: use md5.c for computation of md5sums create a framework for computing digests and reading digests in TWRP add space for backwards compatibility with bb md5sum Change-Id: Ia18e3f430eed5eba22e5052d39b9b8d88ecd4536 --- Android.mk | 1 + digest/md5.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++ digest/md5.h | 29 ++++++ partition.cpp | 10 +- partitionmanager.cpp | 37 +++++--- twinstall.cpp | 11 ++- twrp-functions.cpp | 58 +++--------- twrp-functions.hpp | 2 +- twrpDigest.cpp | 112 ++++++++++++++++++++++ twrpDigest.hpp | 35 +++++++ 10 files changed, 488 insertions(+), 64 deletions(-) create mode 100644 digest/md5.c create mode 100644 digest/md5.h create mode 100644 twrpDigest.cpp create mode 100644 twrpDigest.hpp diff --git a/Android.mk b/Android.mk index 199aba43b..72fa98c28 100644 --- a/Android.mk +++ b/Android.mk @@ -27,6 +27,7 @@ LOCAL_SRC_FILES := \ verifier.cpp \ fixPermissions.cpp \ twrpTar.cpp \ + twrpDigest.cpp \ adb_install.cpp LOCAL_SRC_FILES += \ diff --git a/digest/md5.c b/digest/md5.c new file mode 100644 index 000000000..488d16ef6 --- /dev/null +++ b/digest/md5.c @@ -0,0 +1,257 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ +#include /* for memcpy() */ + +#include "md5.h" + +#if !defined(WORDS_BIGENDIAN) +#define byteReverse(buf, len) /* Nothing */ +#else +void byteReverse(unsigned char *buf, unsigned longs); + +#ifndef ASM_MD5 +/* + * Note: this code is harmless on little-endian machines. + */ +void byteReverse(unsigned char *buf, unsigned longs) +{ + uint32_t t; + do { + t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32_t *) buf = t; + buf += 4; + } while (--longs); +} +#endif +#endif + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + uint32_t t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void MD5Final(unsigned char digest[MD5LENGTH], struct MD5Context *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform. + * Use memcpy to avoid aliasing problems. On most systems, + * this will be optimized away to the same code. + */ + memcpy(&ctx->in[14 * sizeof(uint32_t)], &ctx->bits[0], 4); + memcpy(&ctx->in[15 * sizeof(uint32_t)], &ctx->bits[1], 4); + + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, MD5LENGTH); + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ +} + +#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void MD5Transform(uint32_t buf[4], uint32_t const in[16]) +{ + register uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif + diff --git a/digest/md5.h b/digest/md5.h new file mode 100644 index 000000000..d997e379d --- /dev/null +++ b/digest/md5.h @@ -0,0 +1,29 @@ +#ifndef MD5_H +#define MD5_H + +#ifdef HAVE_STDINT_H +#include +#else +typedef unsigned int uint32_t; +#endif + +#define MD5LENGTH 16 + +struct MD5Context { + uint32_t buf[4]; + uint32_t bits[2]; + unsigned char in[64]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, unsigned char const *buf, + unsigned len); +void MD5Final(unsigned char digest[MD5LENGTH], struct MD5Context *context); +void MD5Transform(uint32_t buf[4], uint32_t const in[16]); + +/* + * This is needed to make RSAREF happy on some MS-DOS compilers. + */ +typedef struct MD5Context MD5_CTX; + +#endif /* !MD5_H */ diff --git a/partition.cpp b/partition.cpp index e158e0ab8..346c298b2 100644 --- a/partition.cpp +++ b/partition.cpp @@ -41,6 +41,7 @@ #include "partitions.hpp" #include "data.hpp" #include "twrp-functions.hpp" +#include "twrpDigest.hpp" #include "twrpTar.hpp" extern "C" { #include "mtdutils/mtdutils.h" @@ -943,13 +944,15 @@ bool TWPartition::Check_MD5(string restore_folder) { string Full_Filename; char split_filename[512]; int index = 0; + twrpDigest md5sum; Full_Filename = restore_folder + "/" + Backup_FileName; if (!TWFunc::Path_Exists(Full_Filename)) { // This is a split archive, we presume sprintf(split_filename, "%s%03i", Full_Filename.c_str(), index); while (index < 1000 && TWFunc::Path_Exists(split_filename)) { - if (TWFunc::Check_MD5(split_filename) == 0) { + md5sum.setfn(split_filename); + if (md5sum.verify_md5digest() != 0) { LOGE("MD5 failed to match on '%s'.\n", split_filename); return false; } @@ -959,7 +962,8 @@ bool TWPartition::Check_MD5(string restore_folder) { return true; } else { // Single file archive - if (TWFunc::Check_MD5(Full_Filename) == 0) { + md5sum.setfn(Full_Filename); + if (md5sum.verify_md5digest() != 0) { LOGE("MD5 failed to match on '%s'.\n", split_filename); return false; } else @@ -1269,7 +1273,7 @@ bool TWPartition::Backup_Tar(string backup_folder) { unsigned long long total_bsize = 0, file_size; twrpTar tar; vector files; - + if (!Mount(true)) return false; diff --git a/partitionmanager.cpp b/partitionmanager.cpp index 895d3617f..9beb2575f 100644 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -40,6 +40,7 @@ #include "data.hpp" #include "twrp-functions.hpp" #include "fixPermissions.hpp" +#include "twrpDigest.hpp" #ifdef TW_INCLUDE_CRYPTO #ifdef TW_INCLUDE_JB_CRYPTO @@ -477,6 +478,7 @@ bool TWPartitionManager::Make_MD5(bool generate_md5, string Backup_Folder, strin string command; string Full_File = Backup_Folder + Backup_Filename; string result; + twrpDigest md5sum; if (!generate_md5) return true; @@ -485,30 +487,39 @@ bool TWPartitionManager::Make_MD5(bool generate_md5, string Backup_Folder, strin ui_print(" * Generating md5...\n"); if (TWFunc::Path_Exists(Full_File)) { - command = "cd '" + Backup_Folder + "' && md5sum '" + Backup_Filename + "' > '" + Backup_Filename + ".md5'"; - if (TWFunc::Exec_Cmd(command, result) == 0) { - ui_print(" * MD5 Created.\n"); - return true; - } else { + md5sum.setfn(Backup_Folder + Backup_Filename); + if (md5sum.computeMD5() == 0) + if (md5sum.write_md5digest() == 0) + ui_print(" * MD5 Created.\n"); + else + return -1; + else ui_print(" * MD5 Error!\n"); - return false; - } } else { char filename[512]; int index = 0; + string strfn; sprintf(filename, "%s%03i", Full_File.c_str(), index); + strfn = filename; + ostringstream intToStr; + ostringstream fn; while (TWFunc::Path_Exists(filename) == true) { - ostringstream intToStr; intToStr << index; - ostringstream fn; fn << setw(3) << setfill('0') << intToStr.str(); - command = "cd '" + Backup_Folder + "' && md5sum '" + Backup_Filename + fn.str() + "' > '" + Backup_Filename + fn.str() + ".md5'"; - if (TWFunc::Exec_Cmd(command, result) != 0) { - ui_print(" * MD5 Error.\n"); - return false; + md5sum.setfn(strfn); + if (md5sum.computeMD5() == 0) { + if (md5sum.write_md5digest() != 0) + { + ui_print(" * MD5 Error.\n"); + return false; + } + } + else { + return -1; } index++; sprintf(filename, "%s%03i", Full_File.c_str(), index); + strfn = filename; } if (index == 0) { LOGE("Backup file: '%s' not found!\n", filename); diff --git a/twinstall.cpp b/twinstall.cpp index 40d715564..e1133c01e 100644 --- a/twinstall.cpp +++ b/twinstall.cpp @@ -39,6 +39,7 @@ #include "variables.h" #include "data.hpp" #include "partitions.hpp" +#include "twrpDigest.hpp" #include "twrp-functions.hpp" extern RecoveryUI* ui; @@ -261,7 +262,8 @@ exit: extern "C" int TWinstall_zip(const char* path, int* wipe_cache) { int err, zip_verify, md5_return; - + twrpDigest md5sum; + string strpath = path; ui_print("Installing '%s'...\n", path); if (!PartitionManager.Mount_By_Path(path, 0)) { @@ -270,14 +272,15 @@ extern "C" int TWinstall_zip(const char* path, int* wipe_cache) { } ui_print("Checking for MD5 file...\n"); - md5_return = TWFunc::Check_MD5(path); - if (md5_return == 0) { + md5sum.setfn(strpath); + md5_return = md5sum.verify_md5digest(); + if (md5_return == -2) { // MD5 did not match. LOGE("Zip MD5 does not match.\nUnable to install zip.\n"); return INSTALL_CORRUPT; } else if (md5_return == -1) { ui_print("Skipping MD5 check: no MD5 file found.\n"); - } else if (md5_return == 1) + } else if (md5_return == 0) ui_print("Zip MD5 matched.\n"); // MD5 found and matched. DataManager::GetValue(TW_SIGNED_ZIP_VERIFY_VAR, zip_verify); diff --git a/twrp-functions.cpp b/twrp-functions.cpp index a90be5a6d..76ee93a1e 100644 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -49,48 +49,6 @@ int TWFunc::Exec_Cmd(string cmd, string &result) { return ret; } -/* Checks md5 for a path - Return values: - -1 : MD5 does not exist - 0 : Failed - 1 : Success */ -int TWFunc::Check_MD5(string File) { - int ret; - string Command, DirPath, MD5_File, Sline, Filename, MD5_File_Filename, OK; - char line[255]; - size_t pos; - string result; - - MD5_File = File + ".md5"; - if (Path_Exists(MD5_File)) { - DirPath = Get_Path(File); - MD5_File = Get_Filename(MD5_File); - Command = "cd '" + DirPath + "' && /sbin/busybox md5sum -c '" + MD5_File + "'"; - Exec_Cmd(Command, result); - pos = result.find(":"); - if (pos != string::npos) { - Filename = Get_Filename(File); - MD5_File_Filename = result.substr(0, pos); - OK = result.substr(pos + 2, result.size() - pos - 2); - if (Filename == MD5_File_Filename && (OK == "OK" || OK == "OK\n")) { - //MD5 is good, return 1 - ret = 1; - } else { - // MD5 is bad, return 0 - ret = 0; - } - } else { - // MD5 is bad, return 0 - ret = 0; - } - } else { - //No md5 file, return -1 - ret = -1; - } - - return ret; -} - // Returns "file.name" from a full /path/to/file.name string TWFunc::Get_Filename(string Path) { size_t pos = Path.find_last_of("/"); @@ -482,10 +440,24 @@ unsigned int TWFunc::Get_D_Type_From_Stat(string Path) { } int TWFunc::read_file(string fn, string& results) { + ifstream file; + file.open(fn.c_str(), ios::in); + if (file.is_open()) { + file >> results; + file.close(); + return 0; + } + LOGI("Cannot find file %s\n", fn.c_str()); + return -1; +} + +int TWFunc::read_file(string fn, vector& results) { ifstream file; + string line; file.open(fn.c_str(), ios::in); if (file.is_open()) { - file >> results; + while (getline(file, line)) + results.push_back(line); file.close(); return 0; } diff --git a/twrp-functions.hpp b/twrp-functions.hpp index 421962281..042c56722 100644 --- a/twrp-functions.hpp +++ b/twrp-functions.hpp @@ -19,7 +19,6 @@ typedef enum class TWFunc { public: - static int Check_MD5(string File); static string Get_Root_Path(string Path); // Trims any trailing folders or filenames from the path, also adds a leading / if not present static string Get_Path(string Path); // Trims everything after the last / in the string static string Get_Filename(string Path); // Trims the path off of a filename @@ -41,6 +40,7 @@ public: static int copy_file(string src, string dst, int mode); //copy file from src to dst with mode permissions static unsigned int Get_D_Type_From_Stat(string Path); // Returns a dirent dt_type value using stat instead of dirent static timespec timespec_diff(timespec& start, timespec& end); // Return a diff for 2 times + static int read_file(string fn, vector& results); //read from file static int read_file(string fn, string& results); //read from file static int write_file(string fn, string& line); //write from file static int drop_caches(void); //drop linux cache memory diff --git a/twrpDigest.cpp b/twrpDigest.cpp new file mode 100644 index 000000000..16cda3d68 --- /dev/null +++ b/twrpDigest.cpp @@ -0,0 +1,112 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see . +*/ + +extern "C" { + #include "digest/md5.h" + #include "libcrecovery/common.h" +} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "data.hpp" +#include "variables.h" +#include "twrp-functions.hpp" +#include "twrpDigest.hpp" + +using namespace std; + +void twrpDigest::setfn(string fn) { + md5fn = fn; +} + +int twrpDigest::computeMD5(void) { + string line; + struct MD5Context md5c; + FILE *file; + int len; + unsigned char buf[1024]; + MD5Init(&md5c); + file = fopen(md5fn.c_str(), "rb"); + if (file == NULL) + return -1; + while ((len = fread(buf, 1, sizeof(buf), file)) > 0) { + MD5Update(&md5c, buf, len); + } + MD5Final(md5sum ,&md5c); + return 0; +} + +int twrpDigest::write_md5digest(void) { + int i; + string md5string, md5file; + char hex[3]; + md5file = md5fn + ".md5"; + + for (i = 0; i < 16; ++i) { + snprintf(hex, 3 ,"%02x", md5sum[i]); + md5string += hex; + } + md5string += " "; + md5string += basename((char*) md5fn.c_str()); + md5string += + "\n"; + TWFunc::write_file(md5file, md5string); + return 0; +} + +int twrpDigest::read_md5digest(void) { + string md5file = md5fn + ".md5"; + if (TWFunc::read_file(md5file, lines) != 0) + return -1; + return 0; +} + +int twrpDigest::verify_md5digest(void) { + string buf; + char hex[3]; + int i; + string md5string; + + if (read_md5digest() != 0) + return -1; + stringstream ss(lines.at(0)); + vector tokens; + while (ss >> buf) + tokens.push_back(buf); + computeMD5(); + for (i = 0; i < 16; ++i) { + snprintf(hex, 3, "%02x", md5sum[i]); + md5string += hex; + } + if (tokens.at(0) != md5string) + return -2; + return 0; +} diff --git a/twrpDigest.hpp b/twrpDigest.hpp new file mode 100644 index 000000000..80828fca5 --- /dev/null +++ b/twrpDigest.hpp @@ -0,0 +1,35 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see . +*/ +extern "C" { + #include "digest/md5.h" +} +using namespace std; + +class twrpDigest { + public: + void setfn(string fn); + void setdir(string dir); + int computeMD5(void); + int verify_md5digest(void); + int write_md5digest(void); + private: + int read_md5digest(void); + string md5fn; + vector lines; + unsigned char md5sum[MD5LENGTH]; +}; -- cgit v1.2.3