Skip to content

Commit

Permalink
Added more test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
0xg0nz0 committed Apr 1, 2024
1 parent 16a5d39 commit e16efa6
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 3 deletions.
2 changes: 1 addition & 1 deletion sdk/net/crypto/crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ iggy::crypto::LocalCertificateStore::LocalCertificateStore(const std::optional<s
} else if (!std::filesystem::is_directory(certDirAbs)) {
throw std::invalid_argument(fmt::format("certificate directory is not a valid directory: {}", certDirAbs.string()));
}
this->certDir = certDir;
this->certDir = certDirAbs;
}

const std::vector<uint8_t> iggy::crypto::LocalCertificateStore::getCertificate(const std::string certPath) const {
Expand Down
11 changes: 9 additions & 2 deletions sdk/net/crypto/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,22 @@ class CRL : public RevocationMethod {
class OCSP : public RevocationMethod {
private:
const std::optional<ada::url> ocspOverrideUrl;
const bool staplingEnabled;

public:
explicit OCSP(const std::optional<ada::url> ocspOverrideUrl = std::nullopt)
: ocspOverrideUrl(ocspOverrideUrl) {}
explicit OCSP(const std::optional<ada::url> ocspOverrideUrl = std::nullopt, const bool staplingEnabled = true)
: ocspOverrideUrl(ocspOverrideUrl)
, staplingEnabled(staplingEnabled) {}

/**
* @brief If specified (default: not), an HTTP URL used to check the status of certificates.
*/
const std::optional<ada::url> getOcspOverrideUrl() const { return this->ocspOverrideUrl; }

/**
* @brief If enabled, servers will cache OCSP verification checks to improve performance.
*/
const bool isStaplingEnabled() const { return this->staplingEnabled; }
};

/**
Expand Down
2 changes: 2 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ if(BUILD_TESTS)
iggy_cpp_test

client_test.cc
crypto_test.cc
iggy_protocol_provider_test.cc
model_test.cc
ssl_test.cc
unit_testutils.cc
)
target_compile_features(iggy_cpp_test PRIVATE cxx_std_17)
target_include_directories(iggy_cpp_test PRIVATE
Expand Down
34 changes: 34 additions & 0 deletions tests/crypto_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "../sdk/net/crypto/crypto.h"
#include "unit_testutils.h"

TEST_CASE_METHOD(iggy::testutil::SelfSignedCertificate, "certificate loading", UT_TAG) {
auto tmpDir = std::filesystem::temp_directory_path();
iggy::crypto::CertificateStore* cs = new iggy::crypto::LocalCertificateStore(tmpDir);
auto cert = cs->getCertificate(getCertificatePath().filename());
REQUIRE(cert.size() > 0);
delete cs;
}

TEST_CASE_METHOD(iggy::testutil::SelfSignedCertificate, "private key loading", UT_TAG) {
auto tmpDir = std::filesystem::temp_directory_path();
iggy::crypto::KeyStore* ks = new iggy::crypto::LocalKeyStore(tmpDir);
auto pk = ks->getPrivateKey(getKeyPath().filename());
REQUIRE(pk.size() > 0);
delete ks;
}

TEST_CASE("revocation methods", UT_TAG) {
SECTION("default CRL configuration") {
iggy::crypto::CRL crl;

REQUIRE(!crl.getCrlPath().has_value());
REQUIRE(!crl.getCrlUrl().has_value());
}

SECTION("default OCSP configuration") {
iggy::crypto::OCSP ocsp;

REQUIRE(!ocsp.getOcspOverrideUrl().has_value());
REQUIRE(ocsp.isStaplingEnabled());
}
}
41 changes: 41 additions & 0 deletions tests/unit_testutils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include "unit_testutils.h"
#include <fmt/format.h>
#include <iostream>
#include <reproc++/drain.hpp>
#include <reproc++/reproc.hpp>
#include <stdexcept>
#include <vector>

iggy::testutil::SelfSignedCertificate::SelfSignedCertificate() {
std::vector<std::string> arguments = {"openssl", "req",
"-x509", "-newkey",
"rsa:2048", "-nodes",
"-keyout", this->keyPath.string(),
"-out", this->certificatePath.string(),
"-days", "365",
"-subj", "/CN=localhost"};
reproc::options options;
options.redirect.discard = true;
reproc::process process;

std::string output;
reproc::sink::string sink(output);
auto err = process.start(arguments, options);
if (err) {
throw std::runtime_error(fmt::format("Failed to run OpenSSL: {}", err.message()));
}
err = reproc::drain(process, sink, reproc::sink::null);
if (err) {
throw std::runtime_error(fmt::format("Failed to read OpenSSL output: {}", err.message()));
}
std::cout << output << std::flush;
}

iggy::testutil::SelfSignedCertificate::~SelfSignedCertificate() {
std::filesystem::remove(this->certificatePath);
std::filesystem::remove(this->keyPath);
}

std::filesystem::path iggy::testutil::SelfSignedCertificate::generateRandomTempPath(std::string baseName) {
return std::filesystem::temp_directory_path() / (std::to_string(std::rand()) + baseName);
}
22 changes: 22 additions & 0 deletions tests/unit_testutils.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
#pragma once

#include <catch.hpp>
#include <filesystem>
#include <string>

const char UT_TAG[] = "[Unit Tests]";

namespace iggy {
namespace testutil {
/**
* @brief A helper class for generating self-signed certificates for testing purposes using OpenSSL CLI.
*/
class SelfSignedCertificate {
private:
std::filesystem::path certificatePath = generateRandomTempPath("cert.pem");
std::filesystem::path keyPath = generateRandomTempPath("key.pem");

static std::filesystem::path generateRandomTempPath(std::string baseName);

public:
SelfSignedCertificate();
~SelfSignedCertificate();
std::filesystem::path getCertificatePath() { return this->certificatePath; }
std::filesystem::path getKeyPath() { return this->keyPath; }
};
} // namespace testutil
} // namespace iggy

0 comments on commit e16efa6

Please sign in to comment.