Skip to content

Commit

Permalink
Integrate cryptopp and implement iso checksum verification (#24)
Browse files Browse the repository at this point in the history
* Integrate cryptopp and implement iso checksum verification

Signed-off-by: lbgracioso <[email protected]>

* Change map to unordered_map, remove 'using namespaces' and make 'output' lowercase instead of 'isoHash'

Signed-off-by: lbgracioso <[email protected]>

* Use 'make_unique' instead of 'new'

Signed-off-by: lbgracioso <[email protected]>

* Implement unit tests

Signed-off-by: lbgracioso <[email protected]>

* Transfer tests from test/diskImage.cpp to src/diskImage.cpp

Signed-off-by: lbgracioso <[email protected]>

* Add context on the need of .release()

Signed-off-by: Vinícius Ferrão <[email protected]>

---------

Signed-off-by: lbgracioso <[email protected]>
Signed-off-by: Vinícius Ferrão <[email protected]>
Co-authored-by: Vinícius Ferrão <[email protected]>
  • Loading branch information
lbgracioso and viniciusferrao authored Jan 4, 2024
1 parent 392b81d commit 7e6c551
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 6 deletions.
8 changes: 8 additions & 0 deletions Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ function(cloysterhpc_setup_dependencies)
endif()
endif()

if(NOT TARGET cryptopp::cryptopp)
if (cloysterhpc_ENABLE_CONAN)
CPMFindPackage(NAME cryptopp)
else()
CPMAddPackage("gh:cryptopp/[email protected]")
endif()
endif()

# Packages only available with CPM
#if(NOT TARGET tools::tools)
# CPMAddPackage("gh:lefticus/tools#update_build_system")
Expand Down
3 changes: 2 additions & 1 deletion cmake/CommonLibraries.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ set(COMMON_LIBS
SimpleIni::SimpleIni
resolv
${STDC++FS}
doctest::doctest)
doctest::doctest
cryptopp::cryptopp)
1 change: 1 addition & 0 deletions conanfile.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ boost/1.82.0
magic_enum/0.9.2
gsl-lite/0.40.0
doctest/2.4.11
cryptopp/8.7.0

[layout]
cmake_layout
Expand Down
7 changes: 4 additions & 3 deletions include/cloysterhpc/diskImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ class DiskImage {
private:
std::filesystem::path m_path;
static constexpr auto m_knownImageFilename { std::to_array<const char*>(
{ "rhel-8.5-x86_64-dvd.iso", "OracleLinux-R8-U5-x86_64-dvd.iso",
"Rocky-8.5-x86_64-dvd1.iso" }) };
bool isKnownImage();
{ "rhel-8.8-x86_64-dvd.iso", "OracleLinux-R8-U8-x86_64-dvd.iso",
"Rocky-8.8-x86_64-dvd1.iso", "AlmaLinux-8.8-x86_64-dvd.iso" }) };

public:
const std::filesystem::path& getPath() const;
void setPath(const std::filesystem::path& path);
bool isKnownImage(const std::filesystem::path& path);
bool hasVerifiedChecksum(const std::filesystem::path& path);
};

#endif // CLOYSTERHPC_DISKIMAGE_H_
94 changes: 92 additions & 2 deletions src/diskImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include "cloysterhpc/os.h"
#include "cloysterhpc/services/log.h"
#include <cloysterhpc/diskImage.h>
#include <cryptopp/files.h>
#include <cryptopp/hex.h>
#include <cryptopp/sha.h>

const std::filesystem::path& DiskImage::getPath() const { return m_path; }

Expand All @@ -12,14 +17,99 @@ void DiskImage::setPath(const std::filesystem::path& path)
if (path.extension() != ".iso")
throw std::runtime_error("Disk Image must have ISO extension");

// Verify checksum only if the image is known.
if (isKnownImage(path)) {
if (!hasVerifiedChecksum(path))
throw std::runtime_error("Disk Image checksum isn't valid");
}

m_path = path;
}

bool DiskImage::isKnownImage()
bool DiskImage::isKnownImage(const std::filesystem::path& path)
{
for (const auto& image : m_knownImageFilename)
if (m_path.filename() == image)
if (path.filename().string() == image) {
LOG_TRACE("Disk image is recognized");
return true;
}

LOG_TRACE("Disk image is unknown. Maybe you're using a custom image or "
"changed the default name?");
return false;
}

bool DiskImage::hasVerifiedChecksum(const std::filesystem::path& path)
{
if (!isKnownImage(path)) {
LOG_TRACE("Disk image is unknown. Can't verify checksum");
return false;
}

LOG_TRACE("Verifying disk image checksum... This may take a while");

std::unordered_map<std::string, std::string> hash_map = {
{ "rhel-8.8-x86_64-dvd.iso",
"517abcc67ee3b7212f57e180f5d30be3e8269e7a99e127a3399b7935c7e00a0"
"9" },
{ "OracleLinux-R8-U8-x86_64-dvd.iso",
"cae39116245ff7c3c86d5305d9c11430ce5c4e512987563435ac59c37a082d7"
"e" },
{ "Rocky-8.8-x86_64-dvd1.iso",
"7b8bdfe189cf24ae5c2d6a88f7a0b5f3012d23f9332c47943d538b4bc03a370"
"4" },
{ "AlmaLinux-8.8-x86_64-dvd.iso",
"635b30b967b509a32a1a3d81401db9861922acb396d065922b39405a43a04a3"
"1" },
};

CryptoPP::SHA256 hash;
std::string isoHash = hash_map.find(path.filename().string())->second;
std::string output;
auto sink = std::make_unique<CryptoPP::StringSink>(output);
auto encoder = std::make_unique<CryptoPP::HexEncoder>(sink.get());
auto filter = std::make_unique<CryptoPP::HashFilter>(hash, encoder.get());

CryptoPP::FileSource(path.string().c_str(), true, filter.get(), true);
transform(output.begin(), output.end(), output.begin(), ::tolower);

/* Those release() methods are needed to address the following issue:
* https://github.com/weidai11/cryptopp/issues/1002
* https://stackoverflow.com/questions/21057393/what-does-double-free-mean
*/
sink.release();
encoder.release();
filter.release();

if (output == isoHash) {
LOG_TRACE("Checksum - The disk image is valid");
return true;
}

LOG_TRACE("Checksum - The disk image is invalid. Maybe you're using a "
"custom image?");
return false;
}

#ifdef BUILD_TESTING
#include <doctest/doctest.h>
#else
#define DOCTEST_CONFIG_DISABLE
#include <doctest/doctest.h>
#endif

TEST_SUITE("Disk image test suite")
{
DiskImage diskImage;
const auto path = std::filesystem::current_path() / "/sample/checksum.iso";

TEST_CASE("Verify if is unknown image")
{
REQUIRE_FALSE(diskImage.isKnownImage(path));
}

TEST_CASE("Verify invalid checksum")
{
REQUIRE_FALSE(diskImage.hasVerifiedChecksum(path));
}
}
1 change: 1 addition & 0 deletions test/sample/checksum.iso
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Please DO NOT MODIFY this file

0 comments on commit 7e6c551

Please sign in to comment.