mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-07 18:08:53 +00:00
c7355b19aa
Summary: Pull Request resolved: https://github.com/facebook/osquery/pull/5452 As suggested in another diff, this diff updates the language we use to describe the osquery licensing terms. We are changing all instances of //This source code is licensed as defined on the LICENSE file found in the root directory of this source tree.// to //This source code is licensed in accordance with the terms specified in the LICENSE file found in the root directory of this source tree.// We accomplish this with a codemod: $ codemod -md xplat/osquery/oss --extensions cpp,h,in,py,sh,mm,ps1 "(.\s+)This source code is licensed as defined on the LICENSE file found in the(.*)root directory of this source tree\." "\1This source code is licensed in accordance with the terms specified in\2the LICENSE file found in the root directory of this source tree." Reviewed By: fmanco Differential Revision: D14131290 fbshipit-source-id: 52c90da342263e2a80f5a678ecd760c19cf7513e
142 lines
4.1 KiB
C++
142 lines
4.1 KiB
C++
/**
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed in accordance with the terms specified in
|
|
* the LICENSE file found in the root directory of this source tree.
|
|
*/
|
|
|
|
#include <algorithm>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <openssl/md5.h>
|
|
#include <openssl/sha.h>
|
|
|
|
#include <osquery/filesystem/filesystem.h>
|
|
#include <osquery/hashing/hashing.h>
|
|
#include <osquery/utils/info/platform_type.h>
|
|
#include <osquery/utils/status/status.h>
|
|
|
|
namespace osquery {
|
|
|
|
/// The buffer read size from file IO to hashing structures.
|
|
const size_t kHashChunkSize{4096};
|
|
|
|
Hash::~Hash() {
|
|
if (ctx_ != nullptr) {
|
|
free(ctx_);
|
|
}
|
|
}
|
|
|
|
Hash::Hash(HashType algorithm) : algorithm_(algorithm) {
|
|
if (algorithm_ == HASH_TYPE_MD5) {
|
|
length_ = MD5_DIGEST_LENGTH;
|
|
ctx_ = static_cast<MD5_CTX*>(malloc(sizeof(MD5_CTX)));
|
|
MD5_Init(static_cast<MD5_CTX*>(ctx_));
|
|
} else if (algorithm_ == HASH_TYPE_SHA1) {
|
|
length_ = SHA_DIGEST_LENGTH;
|
|
ctx_ = static_cast<SHA_CTX*>(malloc(sizeof(SHA_CTX)));
|
|
SHA1_Init(static_cast<SHA_CTX*>(ctx_));
|
|
} else if (algorithm_ == HASH_TYPE_SHA256) {
|
|
length_ = SHA256_DIGEST_LENGTH;
|
|
ctx_ = static_cast<SHA256_CTX*>(malloc(sizeof(SHA256_CTX)));
|
|
SHA256_Init(static_cast<SHA256_CTX*>(ctx_));
|
|
} else {
|
|
throw std::domain_error("Unknown hash function");
|
|
}
|
|
}
|
|
|
|
void Hash::update(const void* buffer, size_t size) {
|
|
if (algorithm_ == HASH_TYPE_MD5) {
|
|
MD5_Update(static_cast<MD5_CTX*>(ctx_), buffer, size);
|
|
} else if (algorithm_ == HASH_TYPE_SHA1) {
|
|
SHA1_Update(static_cast<SHA_CTX*>(ctx_), buffer, size);
|
|
} else if (algorithm_ == HASH_TYPE_SHA256) {
|
|
SHA256_Update(static_cast<SHA256_CTX*>(ctx_), buffer, size);
|
|
}
|
|
}
|
|
|
|
std::string Hash::digest() {
|
|
std::vector<unsigned char> hash;
|
|
hash.assign(length_, '\0');
|
|
|
|
if (algorithm_ == HASH_TYPE_MD5) {
|
|
MD5_Final(hash.data(), static_cast<MD5_CTX*>(ctx_));
|
|
} else if (algorithm_ == HASH_TYPE_SHA1) {
|
|
SHA1_Final(hash.data(), static_cast<SHA_CTX*>(ctx_));
|
|
} else if (algorithm_ == HASH_TYPE_SHA256) {
|
|
SHA256_Final(hash.data(), static_cast<SHA256_CTX*>(ctx_));
|
|
}
|
|
|
|
// The hash value is only relevant as a hex digest.
|
|
std::stringstream digest;
|
|
for (size_t i = 0; i < length_; i++) {
|
|
digest << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
|
|
}
|
|
|
|
return digest.str();
|
|
}
|
|
|
|
std::string hashFromBuffer(HashType hash_type,
|
|
const void* buffer,
|
|
size_t size) {
|
|
Hash hash(hash_type);
|
|
hash.update(buffer, size);
|
|
return hash.digest();
|
|
}
|
|
|
|
MultiHashes hashMultiFromFile(int mask, const std::string& path) {
|
|
std::map<HashType, std::shared_ptr<Hash>> hashes = {
|
|
{HASH_TYPE_MD5, std::make_shared<Hash>(HASH_TYPE_MD5)},
|
|
{HASH_TYPE_SHA1, std::make_shared<Hash>(HASH_TYPE_SHA1)},
|
|
{HASH_TYPE_SHA256, std::make_shared<Hash>(HASH_TYPE_SHA256)},
|
|
};
|
|
|
|
auto blocking = isPlatform(PlatformType::TYPE_WINDOWS);
|
|
auto s = readFile(path,
|
|
0,
|
|
kHashChunkSize,
|
|
false,
|
|
true,
|
|
([&hashes, &mask](std::string& buffer, size_t size) {
|
|
for (auto& hash : hashes) {
|
|
if (mask & hash.first) {
|
|
hash.second->update(&buffer[0], size);
|
|
}
|
|
}
|
|
}),
|
|
blocking);
|
|
|
|
MultiHashes mh = {};
|
|
if (!s.ok()) {
|
|
return mh;
|
|
}
|
|
|
|
mh.mask = mask;
|
|
if (mask & HASH_TYPE_MD5) {
|
|
mh.md5 = hashes.at(HASH_TYPE_MD5)->digest();
|
|
}
|
|
if (mask & HASH_TYPE_SHA1) {
|
|
mh.sha1 = hashes.at(HASH_TYPE_SHA1)->digest();
|
|
}
|
|
if (mask & HASH_TYPE_SHA256) {
|
|
mh.sha256 = hashes.at(HASH_TYPE_SHA256)->digest();
|
|
}
|
|
return mh;
|
|
}
|
|
|
|
std::string hashFromFile(HashType hash_type, const std::string& path) {
|
|
auto hashes = hashMultiFromFile(hash_type, path);
|
|
if (hash_type == HASH_TYPE_MD5) {
|
|
return hashes.md5;
|
|
} else if (hash_type == HASH_TYPE_SHA1) {
|
|
return hashes.sha1;
|
|
} else {
|
|
return hashes.sha256;
|
|
}
|
|
}
|
|
} // namespace osquery
|