Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/66 graceful crash handling #665

Merged
merged 15 commits into from
May 10, 2024
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: Specifies whether per-certificate OCSP data is also requested
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
Loading