Skip to content

Commit

Permalink
Interface updates
Browse files Browse the repository at this point in the history
Signed-off-by: AssemblyJohn <[email protected]>
  • Loading branch information
AssemblyJohn committed May 2, 2024
1 parent 85b10f1 commit b56760f
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 59 deletions.
3 changes: 2 additions & 1 deletion include/evse_security/crypto/interface/crypto_supplier.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ class AbstractCryptoSupplier {
const std::vector<std::uint8_t>& data);

/// @brief Generates a certificate signing request with the provided parameters
static bool x509_generate_csr(const CertificateSigningRequestInfo& generation_info, std::string& out_csr);
static CertificateSignRequestResult 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::uint8_t>& out_digest);
Expand Down
14 changes: 14 additions & 0 deletions include/evse_security/crypto/interface/crypto_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ enum class KeyValidationResult {
Unknown, // Unknown error, not related to provider validation
};

enum class CertificateSignRequestResult {
Valid,
KeyGenerationError, // Error when generating the key, maybe invalid key type
VersioningError, // The version could not be set
PubkeyError, // The public key could not be attached
ExtensionsError, // The extensions could not be appended
SigningError, // The CSR could not be signed, maybe key or signing algo invalid
Unknown, // Any other error
};

struct KeyGenerationInfo {
CryptoKeyType key_type;

Expand Down Expand Up @@ -77,4 +87,8 @@ using KeyHandle_ptr = std::unique_ptr<KeyHandle>;
// Transforms a duration of days into seconds
using days_to_seconds = std::chrono::duration<std::int64_t, std::ratio<86400>>;

namespace conversions {
std::string get_certificate_sign_request_result_to_string(CertificateSignRequestResult e);
}

} // namespace evse_security
3 changes: 2 additions & 1 deletion include/evse_security/crypto/openssl/openssl_supplier.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class OpenSSLSupplier : public AbstractCryptoSupplier {
static bool x509_verify_signature(X509Handle* handle, const std::vector<std::uint8_t>& signature,
const std::vector<std::uint8_t>& data);

static bool x509_generate_csr(const CertificateSigningRequestInfo& csr_info, std::string& out_csr);
static CertificateSignRequestResult x509_generate_csr(const CertificateSigningRequestInfo& csr_info,
std::string& out_csr);

public:
static bool digest_file_sha256(const fs::path& path, std::vector<std::uint8_t>& out_digest);
Expand Down
25 changes: 18 additions & 7 deletions include/evse_security/evse_security.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,20 +165,23 @@ class EvseSecurity {
/// @param organization
/// @param common
/// @param use_tpm If the TPM should be used for the CSR request
/// @return the PEM formatted certificate signing request
std::string generate_certificate_signing_request(LeafCertificateType certificate_type, const std::string& country,
const std::string& organization, const std::string& common,
bool use_tpm);
/// @return the status and an optional PEM formatted certificate signing request string
GetCertificateSignRequestResult generate_certificate_signing_request(LeafCertificateType certificate_type,
const std::string& country,
const std::string& organization,
const std::string& common, bool use_tpm);

/// @brief Generates a certificate signing request for the given \p certificate_type , \p country , \p organization
/// and \p common without using the TPM
/// @param certificate_type
/// @param country
/// @param organization
/// @param common
/// @return the PEM formatted certificate signing request
std::string generate_certificate_signing_request(LeafCertificateType certificate_type, const std::string& country,
const std::string& organization, const std::string& common);
/// @return the status and an optional PEM formatted certificate signing request string
GetCertificateSignRequestResult generate_certificate_signing_request(LeafCertificateType certificate_type,
const std::string& country,
const std::string& organization,
const std::string& common);

/// @brief Searches the filesystem on the specified directories for the given \p certificate_type and retrieves the
/// most recent certificate that is already valid and the respective key. If no certificate is present or no key is
Expand All @@ -203,6 +206,9 @@ class EvseSecurity {
/// @return CA certificate file
std::string get_verify_file(CaCertificateType certificate_type);

/// @brief An extension of 'get_verify_file' with error handling included
GetCertificateInfoResult get_ca_certificate_info(CaCertificateType certificate_type);

/// @brief Gets the expiry day count for the leaf certificate of the given \p certificate_type
/// @param certificate_type
/// @return day count until the leaf certificate expires
Expand Down Expand Up @@ -248,9 +254,14 @@ class EvseSecurity {
LeafCertificateType certificate_type);
GetCertificateInfoResult get_leaf_certificate_info_internal(LeafCertificateType certificate_type,
EncodingFormat encoding, bool include_ocsp = false);
GetCertificateInfoResult get_ca_certificate_info_internal(CaCertificateType certificate_type);
std::optional<fs::path> retrieve_ocsp_cache_internal(const CertificateHashData& certificate_hash_data);
bool is_ca_certificate_installed_internal(CaCertificateType certificate_type);

GetCertificateSignRequestResult
generate_certificate_signing_request_internal(LeafCertificateType certificate_type,
const CertificateSigningRequestInfo& info);

/// @brief Determines if the total filesize of certificates is > than the max_filesystem_usage bytes
bool is_filesystem_full();

Expand Down
13 changes: 13 additions & 0 deletions include/evse_security/evse_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ enum class GetCertificateInfoStatus {
PrivateKeyNotFound,
};

enum class GetCertificateSignRequestStatus {
Accepted,
InvalidRequestedType, ///< Requested a CSR for non CSMS/V2G leafs
KeyGenError, ///< The key could not be generated with the requested/default parameters
GenerationError, ///< Any other error when creating the CSR
};

// types of evse_security

struct CertificateHashData {
Expand Down Expand Up @@ -148,6 +155,12 @@ struct GetCertificateInfoResult {
GetCertificateInfoStatus status;

Check notice on line 155 in include/evse_security/evse_types.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

include/evse_security/evse_types.hpp#L155

struct member 'GetCertificateInfoResult::status' is never used.
std::optional<CertificateInfo> info;
};

struct GetCertificateSignRequestResult {
GetCertificateSignRequestStatus status;

Check notice on line 160 in include/evse_security/evse_types.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

include/evse_security/evse_types.hpp#L160

struct member 'GetCertificateSignRequestResult::status' is never used.
std::optional<std::string> csr;
};

namespace conversions {
std::string encoding_format_to_string(EncodingFormat e);
std::string ca_certificate_type_to_string(CaCertificateType e);
Expand Down
1 change: 1 addition & 0 deletions lib/evse_security/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ target_sources(evse_security
utils/evse_filesystem.cpp

crypto/interface/crypto_supplier.cpp
crypto/interface/crypto_types.cpp
crypto/openssl/openssl_supplier.cpp
crypto/openssl/openssl_tpm.cpp
)
Expand Down
4 changes: 3 additions & 1 deletion lib/evse_security/certificate/x509_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ bool X509Wrapper::operator==(const X509Wrapper& other) const {
}

void X509Wrapper::update_validity() {
CryptoSupplier::x509_get_validity(get(), valid_in, valid_to);
if (false == CryptoSupplier::x509_get_validity(get(), valid_in, valid_to)) {
EVLOG_error << "Could not update validity for certificate: " << get_common_name();
}
}

bool X509Wrapper::is_child(const X509Wrapper& parent) const {
Expand Down
5 changes: 3 additions & 2 deletions lib/evse_security/crypto/interface/crypto_supplier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ bool AbstractCryptoSupplier::x509_verify_signature(X509Handle* handle, const std
default_crypto_supplier_usage_error() return false;
}

bool AbstractCryptoSupplier::x509_generate_csr(const CertificateSigningRequestInfo& csr_info, std::string& out_csr) {
default_crypto_supplier_usage_error() return false;
CertificateSignRequestResult AbstractCryptoSupplier::x509_generate_csr(const CertificateSigningRequestInfo& csr_info,
std::string& out_csr) {
default_crypto_supplier_usage_error() return CertificateSignRequestResult::Unknown;
}

bool AbstractCryptoSupplier::digest_file_sha256(const fs::path& path, std::vector<std::uint8_t>& out_digest) {
Expand Down
32 changes: 32 additions & 0 deletions lib/evse_security/crypto/interface/crypto_types.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest

#include <evse_security/crypto/interface/crypto_types.hpp>

namespace evse_security {

namespace conversions {

std::string get_certificate_sign_request_result_to_string(CertificateSignRequestResult e) {

switch (e) {
case CertificateSignRequestResult::Valid:
return "Valid";
case CertificateSignRequestResult::KeyGenerationError:
return "KeyGenerationError";
case CertificateSignRequestResult::VersioningError:
return "VersioningError";
case CertificateSignRequestResult::PubkeyError:
return "PubkeyError";
case CertificateSignRequestResult::ExtensionsError:
return "ExtensionsError";
case CertificateSignRequestResult::SigningError:
return "SigningError";
}

throw std::out_of_range("No known string conversion for provided enum of type CertificateSignRequestResult");
}

} // namespace conversions

} // namespace evse_security
17 changes: 10 additions & 7 deletions lib/evse_security/crypto/openssl/openssl_supplier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,8 @@ bool OpenSSLSupplier::x509_verify_signature(X509Handle* handle, const std::vecto
}
}

bool OpenSSLSupplier::x509_generate_csr(const CertificateSigningRequestInfo& csr_info, std::string& out_csr) {
CertificateSignRequestResult OpenSSLSupplier::x509_generate_csr(const CertificateSigningRequestInfo& csr_info,
std::string& out_csr) {

KeyHandle_ptr gen_key;
EVP_PKEY_CTX_ptr ctx;
Expand All @@ -734,7 +735,7 @@ bool OpenSSLSupplier::x509_generate_csr(const CertificateSigningRequestInfo& csr
}

if (false == s_generate_key(csr_info.key_info, gen_key, ctx)) {
return false;
return CertificateSignRequestResult::KeyGenerationError;
}

EVP_PKEY* key = get(gen_key.get());
Expand All @@ -747,13 +748,13 @@ bool OpenSSLSupplier::x509_generate_csr(const CertificateSigningRequestInfo& csr

if (false == X509_REQ_set_version(x509_req_ptr.get(), n_version)) {
EVLOG_error << "Failed to set csr version!";
return false;
return CertificateSignRequestResult::VersioningError;
}

// set public key of x509 req
if (false == X509_REQ_set_pubkey(x509_req_ptr.get(), key)) {
EVLOG_error << "Failed to set csr pubkey!";
return false;
return CertificateSignRequestResult::PubkeyError;
}

X509_NAME* x509Name = X509_REQ_get_subject_name(x509_req_ptr.get());
Expand Down Expand Up @@ -794,9 +795,10 @@ bool OpenSSLSupplier::x509_generate_csr(const CertificateSigningRequestInfo& csr
X509_EXTENSION_free(ext_basic_constraints);
X509_EXTENSION_free(ext_san);
sk_X509_EXTENSION_free(extensions);

if (!result) {
EVLOG_error << "Failed to add csr extensions!";
return false;
return CertificateSignRequestResult::ExtensionsError;
}

// sign the certificate with the private key
Expand All @@ -806,7 +808,7 @@ bool OpenSSLSupplier::x509_generate_csr(const CertificateSigningRequestInfo& csr

if (x509_signed == false) {
EVLOG_error << "Failed to sign csr!";
return false;
return CertificateSignRequestResult::SigningError;
}

// write csr
Expand All @@ -817,7 +819,8 @@ bool OpenSSLSupplier::x509_generate_csr(const CertificateSigningRequestInfo& csr
BIO_get_mem_ptr(bio.get(), &mem_csr);

out_csr = std::string(mem_csr->data, mem_csr->length);
return true;

return CertificateSignRequestResult::Valid;
}

bool OpenSSLSupplier::digest_file_sha256(const fs::path& path, std::vector<std::uint8_t>& out_digest) {
Expand Down
Loading

0 comments on commit b56760f

Please sign in to comment.