Skip to content

Commit

Permalink
Bugfix/66 graceful crash handling (#665)
Browse files Browse the repository at this point in the history
* Updated interfaces
* Format and fixes
* Updated interface usage for CSR generation
* Updated interface definition usage
* Comment updates
* Updated deps
* Updated interface for comments
* Updated bazel deps
* Removed unused evse_security interface function
---------

Signed-off-by: AssemblyJohn <[email protected]>
Co-authored-by: Piet Gömpel <[email protected]>
  • Loading branch information
AssemblyJohn and Pietfried authored May 10, 2024
1 parent 1e58e40 commit 888aecb
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 94 deletions.
4 changes: 2 additions & 2 deletions dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ libcurl:
# and would otherwise be overwritten by the version used there
libevse-security:
git: https://github.com/EVerest/libevse-security.git
git_tag: v0.6.0
git_tag: 6e702ef5df568c2f9929a3c3b97a09c0cb4c5b21
cmake_condition: "EVEREST_DEPENDENCY_ENABLED_LIBEVSE_SECURITY"

# OCPP
libocpp:
git: https://github.com/EVerest/libocpp.git
git_tag: v0.11.0
git_tag: 9deeb534c7f38981a422b53a6f0416bdb791b368
cmake_condition: "EVEREST_DEPENDENCY_ENABLED_LIBOCPP"
# Josev
Josev:
Expand Down
12 changes: 8 additions & 4 deletions interfaces/evse_security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ cmds:
$ref: /evse_security#/CertificateHashData
ocsp_response:
description: OCSPResponse class as defined in IETF RFC 6960. DER and then base64 encoded
type: string
type: string
is_ca_certificate_installed:
description: Command that indicates of the given CA certificate type is installed
arguments:
Expand Down Expand Up @@ -134,8 +134,9 @@ cmds:
type: boolean
result:
description: The certificate signing request in PEM format
type: string
get_key_pair:
type: object
$ref: /evse_security#/GetCertificateSignRequestResult
get_leaf_certificate_info:
description: Command to get the paths of the certificate and the respective key
arguments:
certificate_type:
Expand All @@ -146,10 +147,13 @@ cmds:
description: Specifies the encoding of the key
type: string
$ref: /evse_security#/EncodingFormat
include_ocsp:
description: Specifies whether per-certificate OCSP data is also requested
type: boolean
result:
description: The response to the requested command
type: object
$ref: /evse_security#/GetKeyPairResult
$ref: /evse_security#/GetCertificateInfoResult
get_verify_file:
description: Command to get the file path of a CA bundle that can be used for verification
arguments:
Expand Down
115 changes: 91 additions & 24 deletions lib/staging/ocpp/evse_security_ocpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,24 +83,36 @@ bool EvseSecurity::is_ca_certificate_installed(const ocpp::CaCertificateType& ce
return this->r_security.call_is_ca_certificate_installed(conversions::from_ocpp(certificate_type));
}

std::string EvseSecurity::generate_certificate_signing_request(const ocpp::CertificateSigningUseEnum& certificate_type,
const std::string& country,
const std::string& organization,
const std::string& common, bool use_tpm) {
return this->r_security.call_generate_certificate_signing_request(conversions::from_ocpp(certificate_type), country,
organization, common, use_tpm);
}

std::optional<ocpp::KeyPair> EvseSecurity::get_key_pair(const ocpp::CertificateSigningUseEnum& certificate_type) {
const auto key_pair_response = this->r_security.call_get_key_pair(conversions::from_ocpp(certificate_type),
types::evse_security::EncodingFormat::PEM);
if (key_pair_response.status == types::evse_security::GetKeyPairStatus::Accepted and
key_pair_response.key_pair.has_value()) {
const auto _key_pair = conversions::to_ocpp(key_pair_response.key_pair.value());
return _key_pair;
} else {
return std::nullopt;
ocpp::GetCertificateSignRequestResult
EvseSecurity::generate_certificate_signing_request(const ocpp::CertificateSigningUseEnum& certificate_type,
const std::string& country, const std::string& organization,
const std::string& common, bool use_tpm) {
auto csr_response = this->r_security.call_generate_certificate_signing_request(
conversions::from_ocpp(certificate_type), country, organization, common, use_tpm);

ocpp::GetCertificateSignRequestResult result;

result.status = conversions::to_ocpp(csr_response.status);
if (csr_response.csr.has_value()) {
result.csr = csr_response.csr;
}

return result;
}

ocpp::GetCertificateInfoResult
EvseSecurity::get_leaf_certificate_info(const ocpp::CertificateSigningUseEnum& certificate_type, bool include_ocsp) {
const auto info_response = this->r_security.call_get_leaf_certificate_info(
conversions::from_ocpp(certificate_type), types::evse_security::EncodingFormat::PEM, include_ocsp);

ocpp::GetCertificateInfoResult result;

result.status = conversions::to_ocpp(info_response.status);
if (info_response.info.has_value()) {
result.info = conversions::to_ocpp(info_response.info.value());
}

return result;
}

bool EvseSecurity::update_certificate_links(const ocpp::CertificateSigningUseEnum& certificate_type) {
Expand Down Expand Up @@ -221,13 +233,30 @@ ocpp::CertificateValidationResult to_ocpp(types::evse_security::CertificateValid
return ocpp::CertificateValidationResult::InvalidChain;
case types::evse_security::CertificateValidationResult::Unknown:
return ocpp::CertificateValidationResult::Unknown;
;
default:
throw std::runtime_error("Could not convert types::evse_security::CertificateValidationResult to "
"ocpp::CertificateValidationResult");
}
}

ocpp::GetCertificateInfoStatus to_ocpp(types::evse_security::GetCertificateInfoStatus other) {
switch (other) {
case types::evse_security::GetCertificateInfoStatus::Accepted:
return ocpp::GetCertificateInfoStatus::Accepted;
case types::evse_security::GetCertificateInfoStatus::Rejected:
return ocpp::GetCertificateInfoStatus::Rejected;
case types::evse_security::GetCertificateInfoStatus::NotFound:
return ocpp::GetCertificateInfoStatus::NotFound;
case types::evse_security::GetCertificateInfoStatus::NotFoundValid:
return ocpp::GetCertificateInfoStatus::NotFoundValid;
case types::evse_security::GetCertificateInfoStatus::PrivateKeyNotFound:
return ocpp::GetCertificateInfoStatus::PrivateKeyNotFound;
default:
throw std::runtime_error("Could not convert types::evse_security::GetCertificateInfoStatus to "
"ocpp::GetCertificateInfoStatus");
}
}

ocpp::DeleteCertificateResult to_ocpp(types::evse_security::DeleteCertificateResult other) {
switch (other) {
case types::evse_security::DeleteCertificateResult::Accepted:
Expand All @@ -242,6 +271,22 @@ ocpp::DeleteCertificateResult to_ocpp(types::evse_security::DeleteCertificateRes
}
}

ocpp::GetCertificateSignRequestStatus to_ocpp(types::evse_security::GetCertificateSignRequestStatus other) {
switch (other) {
case types::evse_security::GetCertificateSignRequestStatus::Accepted:
return ocpp::GetCertificateSignRequestStatus::Accepted;
case types::evse_security::GetCertificateSignRequestStatus::InvalidRequestedType:
return ocpp::GetCertificateSignRequestStatus::InvalidRequestedType;
case types::evse_security::GetCertificateSignRequestStatus::KeyGenError:
return ocpp::GetCertificateSignRequestStatus::KeyGenError;
case types::evse_security::GetCertificateSignRequestStatus::GenerationError:
return ocpp::GetCertificateSignRequestStatus::GenerationError;
default:
throw std::runtime_error("Could not convert types::evse_security::GetCertificateSignRequestStatus to "
"ocpp::GetCertificateSignRequestStatus");
}
}

ocpp::CertificateHashDataType to_ocpp(types::evse_security::CertificateHashData other) {
ocpp::CertificateHashDataType lhs;
lhs.hashAlgorithm = to_ocpp(other.hash_algorithm);
Expand Down Expand Up @@ -279,12 +324,31 @@ ocpp::OCSPRequestData to_ocpp(types::evse_security::OCSPRequestData other) {
return lhs;
}

ocpp::KeyPair to_ocpp(types::evse_security::KeyPair other) {
ocpp::KeyPair lhs;
ocpp::CertificateOCSP to_ocpp(types::evse_security::CertificateOCSP other) {
ocpp::CertificateOCSP lhs;
lhs.hash = to_ocpp(other.hash);

if (other.ocsp_path.has_value()) {
lhs.ocsp_path = other.ocsp_path.value();
}

return lhs;
}

ocpp::CertificateInfo to_ocpp(types::evse_security::CertificateInfo other) {
ocpp::CertificateInfo lhs;
lhs.certificate_path = other.certificate;
lhs.certificate_single_path = other.certificate_single;
lhs.key_path = other.key;
lhs.password = other.password;
lhs.certificate_count = other.certificate_count;

if (other.ocsp.has_value()) {
for (auto& ocsp_data : other.ocsp.value()) {
lhs.ocsp.push_back(to_ocpp(ocsp_data));
}
}

return lhs;
}

Expand Down Expand Up @@ -440,10 +504,13 @@ types::evse_security::OCSPRequestData from_ocpp(ocpp::OCSPRequestData other) {
return lhs;
}

types::evse_security::KeyPair from_ocpp(ocpp::KeyPair other) {
types::evse_security::KeyPair lhs;
lhs.key = other.certificate_path;
lhs.certificate = other.key_path;
types::evse_security::CertificateInfo from_ocpp(ocpp::CertificateInfo other) {
types::evse_security::CertificateInfo lhs;
lhs.certificate = other.certificate_path;
lhs.certificate_single = other.certificate_single_path;
lhs.certificate_count = other.certificate_count;
lhs.key = other.key_path;
lhs.password = other.password;
return lhs;
}

Expand Down
18 changes: 12 additions & 6 deletions lib/staging/ocpp/evse_security_ocpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ class EvseSecurity : public ocpp::EvseSecurity {
void update_ocsp_cache(const ocpp::CertificateHashDataType& certificate_hash_data,
const std::string& ocsp_response) override;
bool is_ca_certificate_installed(const ocpp::CaCertificateType& certificate_type) override;
std::string generate_certificate_signing_request(const ocpp::CertificateSigningUseEnum& certificate_type,
const std::string& country, const std::string& organization,
const std::string& common, bool use_tpm) override;
std::optional<ocpp::KeyPair> get_key_pair(const ocpp::CertificateSigningUseEnum& certificate_type) override;
ocpp::GetCertificateSignRequestResult
generate_certificate_signing_request(const ocpp::CertificateSigningUseEnum& certificate_type,
const std::string& country, const std::string& organization,
const std::string& common, bool use_tpm) override;
ocpp::GetCertificateInfoResult get_leaf_certificate_info(const ocpp::CertificateSigningUseEnum& certificate_type,
bool include_ocsp) override;
bool update_certificate_links(const ocpp::CertificateSigningUseEnum& certificate_type) override;
std::string get_verify_file(const ocpp::CaCertificateType& certificate_type) override;
int get_leaf_expiry_days_count(const ocpp::CertificateSigningUseEnum& certificate_type) override;
Expand All @@ -49,25 +51,29 @@ ocpp::CertificateType to_ocpp(types::evse_security::CertificateType other);
ocpp::HashAlgorithmEnumType to_ocpp(types::evse_security::HashAlgorithm other);
ocpp::InstallCertificateResult to_ocpp(types::evse_security::InstallCertificateResult other);
ocpp::CertificateValidationResult to_ocpp(types::evse_security::CertificateValidationResult other);
ocpp::GetCertificateInfoStatus to_ocpp(types::evse_security::GetCertificateInfoStatus other);
ocpp::GetCertificateSignRequestStatus to_ocpp(types::evse_security::GetCertificateSignRequestStatus other);
ocpp::DeleteCertificateResult to_ocpp(types::evse_security::DeleteCertificateResult other);

ocpp::CertificateHashDataType to_ocpp(types::evse_security::CertificateHashData other);
ocpp::CertificateHashDataChain to_ocpp(types::evse_security::CertificateHashDataChain other);
ocpp::OCSPRequestData to_ocpp(types::evse_security::OCSPRequestData other);
ocpp::KeyPair to_ocpp(types::evse_security::KeyPair other);
ocpp::CertificateOCSP to_ocpp(types::evse_security::CertificateOCSP other);
ocpp::CertificateInfo to_ocpp(types::evse_security::CertificateInfo other);

types::evse_security::CaCertificateType from_ocpp(ocpp::CaCertificateType other);
types::evse_security::LeafCertificateType from_ocpp(ocpp::CertificateSigningUseEnum other);
types::evse_security::LeafCertificateType from_ocpp(ocpp::LeafCertificateType other);
types::evse_security::CertificateType from_ocpp(ocpp::CertificateType other);
types::evse_security::HashAlgorithm from_ocpp(ocpp::HashAlgorithmEnumType other);
types::evse_security::InstallCertificateResult from_ocpp(ocpp::InstallCertificateResult other);
types::evse_security::GetCertificateSignRequestStatus from_ocpp(ocpp::GetCertificateSignRequestStatus other);
types::evse_security::DeleteCertificateResult from_ocpp(ocpp::DeleteCertificateResult other);

types::evse_security::CertificateHashData from_ocpp(ocpp::CertificateHashDataType other);
types::evse_security::CertificateHashDataChain from_ocpp(ocpp::CertificateHashDataChain other);
types::evse_security::OCSPRequestData from_ocpp(ocpp::OCSPRequestData other);
types::evse_security::KeyPair from_ocpp(ocpp::KeyPair other);
types::evse_security::CertificateInfo from_ocpp(ocpp::CertificateInfo other);

}; // namespace conversions

Expand Down
68 changes: 51 additions & 17 deletions modules/EvseSecurity/conversions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,29 @@ evse_security::OCSPRequestDataList from_everest(types::evse_security::OCSPReques
return lhs;
}

evse_security::KeyPair from_everest(types::evse_security::KeyPair other) {
evse_security::KeyPair lhs;
evse_security::CertificateOCSP from_everest(types::evse_security::CertificateOCSP other) {
evse_security::CertificateOCSP lhs;
lhs.hash = from_everest(other.hash);

if (other.ocsp_path.has_value()) {
lhs.ocsp_path = other.ocsp_path.value();
}

return lhs;
}

evse_security::CertificateInfo from_everest(types::evse_security::CertificateInfo other) {
evse_security::CertificateInfo lhs;
lhs.key = other.key;
lhs.certificate = other.certificate;
lhs.certificate_single = other.certificate_single;
lhs.certificate_count = other.certificate_count;
lhs.password = other.password;
if (other.ocsp.has_value()) {
for (auto& ocsp_data : other.ocsp.value()) {
lhs.ocsp.push_back(from_everest(ocsp_data));
}
}
return lhs;
}

Expand Down Expand Up @@ -346,21 +363,37 @@ types::evse_security::GetInstalledCertificatesStatus to_everest(evse_security::G
}
}

types::evse_security::GetKeyPairStatus to_everest(evse_security::GetKeyPairStatus other) {
types::evse_security::GetCertificateSignRequestStatus to_everest(evse_security::GetCertificateSignRequestStatus other) {
switch (other) {
case evse_security::GetCertificateSignRequestStatus::Accepted:
return types::evse_security::GetCertificateSignRequestStatus::Accepted;
case evse_security::GetCertificateSignRequestStatus::InvalidRequestedType:
return types::evse_security::GetCertificateSignRequestStatus::InvalidRequestedType;
case evse_security::GetCertificateSignRequestStatus::KeyGenError:
return types::evse_security::GetCertificateSignRequestStatus::KeyGenError;
case evse_security::GetCertificateSignRequestStatus::GenerationError:
return types::evse_security::GetCertificateSignRequestStatus::GenerationError;
default:
throw std::runtime_error("Could not convert evse_security::GetCertificateSignRequestStatus to "
"types::evse_security::GetCertificateSignRequestStatus");
}
}

types::evse_security::GetCertificateInfoStatus to_everest(evse_security::GetCertificateInfoStatus other) {
switch (other) {
case evse_security::GetKeyPairStatus::Accepted:
return types::evse_security::GetKeyPairStatus::Accepted;
case evse_security::GetKeyPairStatus::Rejected:
return types::evse_security::GetKeyPairStatus::Rejected;
case evse_security::GetKeyPairStatus::NotFound:
return types::evse_security::GetKeyPairStatus::NotFound;
case evse_security::GetKeyPairStatus::NotFoundValid:
return types::evse_security::GetKeyPairStatus::NotFoundValid;
case evse_security::GetKeyPairStatus::PrivateKeyNotFound:
return types::evse_security::GetKeyPairStatus::PrivateKeyNotFound;
case evse_security::GetCertificateInfoStatus::Accepted:
return types::evse_security::GetCertificateInfoStatus::Accepted;
case evse_security::GetCertificateInfoStatus::Rejected:
return types::evse_security::GetCertificateInfoStatus::Rejected;
case evse_security::GetCertificateInfoStatus::NotFound:
return types::evse_security::GetCertificateInfoStatus::NotFound;
case evse_security::GetCertificateInfoStatus::NotFoundValid:
return types::evse_security::GetCertificateInfoStatus::NotFoundValid;
case evse_security::GetCertificateInfoStatus::PrivateKeyNotFound:
return types::evse_security::GetCertificateInfoStatus::PrivateKeyNotFound;
default:
throw std::runtime_error("Could not convert evse_security::GetKeyPairStatus to "
"types::evse_security::GetKeyPairStatus");
throw std::runtime_error("Could not convert evse_security::GetCertificateInfoStatus to "
"types::evse_security::GetCertificateInfoStatus");
}
}

Expand Down Expand Up @@ -415,12 +448,13 @@ types::evse_security::OCSPRequestDataList to_everest(evse_security::OCSPRequestD
return lhs;
}

types::evse_security::KeyPair to_everest(evse_security::KeyPair other) {
types::evse_security::KeyPair lhs;
types::evse_security::CertificateInfo to_everest(evse_security::CertificateInfo other) {
types::evse_security::CertificateInfo lhs;
lhs.key = other.key;
lhs.certificate = other.certificate;
lhs.certificate_single = other.certificate_single;
lhs.password = other.password;
lhs.certificate_count = other.certificate_count;
return lhs;
}

Expand Down
7 changes: 4 additions & 3 deletions modules/EvseSecurity/conversions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ evse_security::CertificateHashDataChain from_everest(types::evse_security::Certi
evse_security::GetInstalledCertificatesResult from_everest(types::evse_security::GetInstalledCertificatesResult other);
evse_security::OCSPRequestData from_everest(types::evse_security::OCSPRequestData other);
evse_security::OCSPRequestDataList from_everest(types::evse_security::OCSPRequestDataList other);
evse_security::KeyPair from_everest(types::evse_security::KeyPair other);
evse_security::CertificateInfo from_everest(types::evse_security::CertificateInfo other);

types::evse_security::EncodingFormat to_everest(evse_security::EncodingFormat other);
types::evse_security::CaCertificateType to_everest(evse_security::CaCertificateType other);
Expand All @@ -35,14 +35,15 @@ types::evse_security::InstallCertificateResult to_everest(evse_security::Install
types::evse_security::CertificateValidationResult to_everest(evse_security::CertificateValidationResult other);
types::evse_security::DeleteCertificateResult to_everest(evse_security::DeleteCertificateResult other);
types::evse_security::GetInstalledCertificatesStatus to_everest(evse_security::GetInstalledCertificatesStatus other);
types::evse_security::GetKeyPairStatus to_everest(evse_security::GetKeyPairStatus other);
types::evse_security::GetCertificateSignRequestStatus to_everest(evse_security::GetCertificateSignRequestStatus other);
types::evse_security::GetCertificateInfoStatus to_everest(evse_security::GetCertificateInfoStatus other);

types::evse_security::CertificateHashData to_everest(evse_security::CertificateHashData other);
types::evse_security::CertificateHashDataChain to_everest(evse_security::CertificateHashDataChain other);
types::evse_security::GetInstalledCertificatesResult to_everest(evse_security::GetInstalledCertificatesResult other);
types::evse_security::OCSPRequestData to_everest(evse_security::OCSPRequestData other);
types::evse_security::OCSPRequestDataList to_everest(evse_security::OCSPRequestDataList other);
types::evse_security::KeyPair to_everest(evse_security::KeyPair other);
types::evse_security::CertificateInfo to_everest(evse_security::CertificateInfo other);

} // namespace conversions

Expand Down
Loading

0 comments on commit 888aecb

Please sign in to comment.