complete basic verification method

master
Arne Schroeder 2019-09-07 13:31:55 +02:00
parent c08b34ddbf
commit 35777ad309
2 changed files with 52 additions and 5 deletions

View File

@ -18,16 +18,21 @@ public:
std::string generateHashList(const std::string &app); std::string generateHashList(const std::string &app);
std::string generateFileHash(const std::string &filepath); std::string generateFileHash(const std::string &filepath);
bool checkHashList(const std::string &hashList, const std::string &appPath);
bool verifyFileHash(const std::string &filePath, const std::string &hash);
void signHashList(std::string &hashList); void signHashList(std::string &hashList);
bool verifyHashList(const std::string &signedHashList); bool verifyHashList(const std::string &signedHashList, std::string &hashList);
static const int KEY_SIZE; static const int KEY_SIZE;
static const std::string HASH_FILE; static const std::string HASH_FILE;
static const std::string KEY_FILE; static const std::string KEY_FILE;
static const std::string SIGNATURE_MARKER; static const std::string SIGNATURE_MARKER;
static const std::string HASH_FILE_DIVIDER;
private: private:
CryptoPP::RSA::PublicKey m_publicKey; CryptoPP::RSA::PublicKey m_publicKey;
CryptoPP::RSA::PrivateKey m_privateKey; CryptoPP::RSA::PrivateKey m_privateKey;
bool extractHashAndFile(const std::string &line, std::string &hash,
std::string &filename);
}; };

View File

@ -14,6 +14,7 @@ const int IntegretyCheck::KEY_SIZE = 2048;
const std::string IntegretyCheck::HASH_FILE = "hashlist.sha256"; const std::string IntegretyCheck::HASH_FILE = "hashlist.sha256";
const std::string IntegretyCheck::KEY_FILE = "appKey.pub"; const std::string IntegretyCheck::KEY_FILE = "appKey.pub";
const std::string IntegretyCheck::SIGNATURE_MARKER = "### signature ###\n"; const std::string IntegretyCheck::SIGNATURE_MARKER = "### signature ###\n";
const std::string IntegretyCheck::HASH_FILE_DIVIDER = " *";
std::string string_to_hex(const std::string &input) { std::string string_to_hex(const std::string &input) {
static const char *const lut = "0123456789ABCDEF"; static const char *const lut = "0123456789ABCDEF";
@ -81,8 +82,8 @@ std::string IntegretyCheck::generateHashList(const std::string &app) {
std::string filepath = f.path().string(); std::string filepath = f.path().string();
filepath.erase(0, p.size()); filepath.erase(0, p.size());
// write hash line to file // write hash line to file
hashlist << generateFileHash(f.path().string()) << " *" << filepath hashlist << generateFileHash(f.path().string()) << HASH_FILE_DIVIDER
<< std::endl; << filepath << std::endl;
} }
} }
return hashlist.str(); return hashlist.str();
@ -102,6 +103,45 @@ std::string IntegretyCheck::generateFileHash(const std::string &filepath) {
std::string((char *)abDigest, CryptoPP::SHA256::DIGESTSIZE)); std::string((char *)abDigest, CryptoPP::SHA256::DIGESTSIZE));
} }
bool IntegretyCheck::extractHashAndFile(const std::string &line,
std::string &hash,
std::string &filename) {
size_t divider = line.find(HASH_FILE_DIVIDER);
bool result = false;
if (divider != std::string::npos) {
hash = line.substr(0, divider);
filename = line.substr(divider + HASH_FILE_DIVIDER.size());
result = true;
} else {
std::cerr << "ERROR: malformated hash line '" << line << "'" << std::endl;
}
return result;
}
bool IntegretyCheck::checkHashList(const std::string &hashList,
const std::string &appPath) {
std::stringstream ss(hashList);
std::string line, hash, filename;
bool result = true;
fs::path p(appPath);
while (std::getline(ss, line, '\n')) {
if (extractHashAndFile(line, hash, filename)) {
bool check = verifyFileHash((p / filename).string(), hash);
result &= check;
if (!check) {
std::cerr << "ERROR: Checksum does not match on '" << filename << "'!"
<< std::endl;
}
}
}
return result;
}
bool IntegretyCheck::verifyFileHash(const std::string &filePath,
const std::string &hash) {
return (generateFileHash(filePath) == hash);
}
void IntegretyCheck::signHashList(std::string &hashList) { void IntegretyCheck::signHashList(std::string &hashList) {
CryptoPP::AutoSeededRandomPool rng; CryptoPP::AutoSeededRandomPool rng;
@ -125,14 +165,16 @@ void IntegretyCheck::signHashList(std::string &hashList) {
hashList.append(strHexSignature); hashList.append(strHexSignature);
} }
bool IntegretyCheck::verifyHashList(const std::string &signedHashList) { bool IntegretyCheck::verifyHashList(const std::string &signedHashList,
std::string &hashList) {
size_t startSig = signedHashList.find(SIGNATURE_MARKER); size_t startSig = signedHashList.find(SIGNATURE_MARKER);
if (startSig == std::string::npos) { if (startSig == std::string::npos) {
std::cerr << "ERROR: no signature marker found!" << std::endl;
return false; return false;
} }
// extract hash list // extract hash list
std::string hashList = signedHashList.substr(0, startSig); hashList = signedHashList.substr(0, startSig);
// extract base64 encoded signature // extract base64 encoded signature
std::string base64Signature = std::string base64Signature =