generated from EVerest/everest-template
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from EVerest/refactor/header_dependency_manage…
…ment Refactor for libevse
- Loading branch information
Showing
27 changed files
with
1,680 additions
and
1,106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Copyright Pionix GmbH and Contributors to EVerest | ||
#pragma once | ||
|
||
#include <queue> | ||
|
||
#include <evse_security/certificate/x509_wrapper.hpp> | ||
|
||
namespace evse_security { | ||
|
||
class NoCertificateFound : public std::runtime_error { | ||
public: | ||
using std::runtime_error::runtime_error; | ||
}; | ||
|
||
struct X509Node { | ||
X509Wrapper certificate; | ||
CertificateHashData hash; | ||
|
||
X509Wrapper issuer; | ||
std::vector<X509Node> children; | ||
}; | ||
|
||
/// @brief Utility class that is able to build a immutable certificate hierarchy | ||
/// with a list of self-signed root certificates and their respective sub-certificates | ||
class X509CertificateHierarchy { | ||
public: | ||
const std::vector<X509Node>& get_hierarchy() const { | ||
return hierarchy; | ||
} | ||
|
||
/// @brief Checks if the provided certificate is a self-signed root CA certificate | ||
/// contained in our hierarchy | ||
bool is_root(const X509Wrapper& certificate) const; | ||
|
||
/// @brief Collects all the descendants of the provided certificate | ||
/// @param top Certificate that issued the descendants | ||
std::vector<X509Wrapper> collect_descendants(const X509Wrapper& top); | ||
|
||
/// @brief obtains the hash data of the certificate, finding its issuer if needed | ||
CertificateHashData get_certificate_hash(const X509Wrapper& certificate); | ||
|
||
/// @brief returns true if we contain a certificate with the following hash | ||
bool contains_certificate_hash(const CertificateHashData& hash); | ||
|
||
/// @brief Searches for the provided hash, throwing a NoCertificateFound if not found | ||
X509Wrapper find_certificate(const CertificateHashData& hash); | ||
|
||
public: | ||
std::string to_debug_string(); | ||
|
||
/// @brief Breadth-first iteration through all the hierarchy of | ||
/// certificates. Will break when the function returns false | ||
template <typename function> void for_each(function func) { | ||
std::queue<std::reference_wrapper<X509Node>> queue; | ||
for (auto& root : hierarchy) { | ||
// Process roots | ||
if (!func(root)) | ||
return; | ||
|
||
for (auto& child : root.children) { | ||
queue.push(child); | ||
} | ||
} | ||
|
||
while (!queue.empty()) { | ||
X509Node& top = queue.front(); | ||
queue.pop(); | ||
|
||
// Process node | ||
if (!func(top)) | ||
return; | ||
|
||
for (auto& child : top.children) { | ||
queue.push(child); | ||
} | ||
} | ||
} | ||
|
||
public: | ||
/// @brief Depth-first descendant iteration | ||
template <typename function> static void for_each_descendant(function func, const X509Node& node, int depth = 0) { | ||
if (node.children.empty()) | ||
return; | ||
|
||
for (const auto& child : node.children) { | ||
func(child, depth); | ||
|
||
if (!child.children.empty()) { | ||
for_each_descendant(func, child, (depth + 1)); | ||
} | ||
} | ||
} | ||
|
||
public: | ||
/// @brief Builds a proper certificate hierarchy from the provided certificates. The | ||
/// hierarchy can be incomplete, in case orphan certificates are present in the list | ||
static X509CertificateHierarchy build_hierarchy(std::vector<X509Wrapper>& certificates); | ||
|
||
private: | ||
/// @brief Attempts to add to the hierarchy the provided certificate | ||
/// @return True if we found within our hierarchy any certificate that | ||
/// owns the provided certificate, false otherwise | ||
bool try_add_to_hierarchy(X509Wrapper&& certificate); | ||
|
||
private: | ||
std::vector<X509Node> hierarchy; | ||
}; | ||
|
||
} // namespace evse_security |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Copyright Pionix GmbH and Contributors to EVerest | ||
#pragma once | ||
|
||
#include <evse_security/crypto/interface/crypto_supplier.hpp> | ||
|
||
// Include other required suppliers here | ||
#ifdef LIBEVSE_CRYPTO_SUPPLIER_OPENSSL | ||
#include <evse_security/crypto/openssl/openssl_supplier.hpp> | ||
namespace evse_security { | ||
typedef OpenSSLSupplier CryptoSupplier; // Define others with the same 'CryptoSupplier' name | ||
} | ||
#endif |
70 changes: 70 additions & 0 deletions
70
include/evse_security/crypto/interface/crypto_supplier.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Copyright Pionix GmbH and Contributors to EVerest | ||
#pragma once | ||
|
||
#include <optional> | ||
#include <stdexcept> | ||
#include <vector> | ||
|
||
#include <evse_security/crypto/interface/crypto_types.hpp> | ||
#include <evse_security/evse_types.hpp> | ||
#include <evse_security/utils/evse_filesystem_types.hpp> | ||
|
||
namespace evse_security { | ||
|
||
/// @brief All cryptography suppliers must conform to this class. Do not | ||
/// use this class directly, just include the evse_crypto.hpp | ||
class AbstractCryptoSupplier { | ||
public: | ||
/// @brief Loads all certificates from the string data that can contain multiple cetifs | ||
static std::vector<X509Handle_ptr> load_certificates(const std::string& data, const EncodingFormat encoding); | ||
|
||
public: // X509 certificate utilities | ||
static std::string x509_to_string(X509Handle* handle); | ||
static std::string x509_get_responder_url(X509Handle* handle); | ||
static std::string x509_get_key_hash(X509Handle* handle); | ||
static std::string x509_get_serial_number(X509Handle* handle); | ||
static std::string x509_get_issuer_name_hash(X509Handle* handle); | ||
static std::string x509_get_common_name(X509Handle* handle); | ||
|
||
/// @brief Returns the time validity for a certificate | ||
/// @param out_valid_in Valid in amount of seconds. A negative value is in the past, a positive one is in the future | ||
/// (not yet valid) | ||
/// @param out_valid_to Valid amount of seconds. A negative value is in the past (expired), a positive one is in the | ||
/// future | ||
static void x509_get_validity(X509Handle* handle, std::int64_t& out_valid_in, std::int64_t& out_valid_to); | ||
|
||
static bool x509_is_selfsigned(X509Handle* handle); | ||
static bool x509_is_child(X509Handle* child, X509Handle* parent); | ||
static bool x509_is_equal(X509Handle* a, X509Handle* b); | ||
|
||
static X509Handle_ptr x509_duplicate_unique(X509Handle* handle); | ||
|
||
/// @brief Verifies the provided target against the certificate chain | ||
/// @param target Target to verify | ||
/// @param parents Parents chain, until the root | ||
/// @param dir_path Optional directory path that can be used for certificate store lookup | ||
/// @param file_path Optional certificate file path that can be used for certificate store lookup | ||
/// @return | ||
static CertificateValidationError x509_verify_certificate_chain(X509Handle* target, | ||
const std::vector<X509Handle*>& parents, | ||
const std::optional<fs::path> dir_path, | ||
const std::optional<fs::path> file_path); | ||
|
||
/// @brief Checks if the private key is consistent with the provided handle | ||
static bool x509_check_private_key(X509Handle* handle, std::string private_key, | ||
std::optional<std::string> password); | ||
|
||
/// @brief Verifies the signature with the certificate handle public key against the data | ||
static bool x509_verify_signature(X509Handle* handle, const std::vector<std::byte>& signature, | ||
const std::vector<std::byte>& data); | ||
|
||
/// @brief Generates a certificate signing request with the provided parameters | ||
static bool x509_generate_csr(const CertificateSigningRequestInfo& generation_info, std::string& out_csr); | ||
|
||
public: // Digesting/decoding utils | ||
static bool digest_file_sha256(const fs::path& path, std::vector<std::byte>& out_digest); | ||
static bool decode_base64_signature(const std::string& signature, std::vector<std::byte>& out_decoded); | ||
}; | ||
|
||
} // namespace evse_security |
Oops, something went wrong.