Skip to content

Commit 84b604a

Browse files
mennodegraafMenno de GraafAssemblyJohn
authored
Add support for certificate links (#398)
* Add support for optional SECC leaf and CPO chain links * Add method for updating symlinks * Update symlinks after V2G certificate update * Config based symlinks update --------- Signed-off-by: Menno de Graaf <m.degraaf@alfen.com> Signed-off-by: AssemblyJohn <ioan.bogdann@gmail.com> Co-authored-by: Menno de Graaf <m.degraaf@alfen.com> Co-authored-by: AssemblyJohn <ioan.bogdann@gmail.com>
1 parent 4ae306a commit 84b604a

10 files changed

+54
-1
lines changed

config/v201/component_schemas/standardized/InternalCtrlr.json

+15
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,21 @@
471471
"default": "43200",
472472
"type": "integer"
473473
},
474+
"UpdateCertificateSymlinks": {
475+
"variable_name": "UpdateCertificateSymlinks",
476+
"characteristics": {
477+
"supportsMonitoring": false,
478+
"dataType": "boolean"
479+
},
480+
"attributes": [
481+
{
482+
"type": "Actual",
483+
"mutability": "ReadOnly"
484+
}
485+
],
486+
"default": "0",
487+
"type": "boolean"
488+
},
474489
"MessageQueueSizeThreshold": {
475490
"variable_name": "MessageQueueSizeThreshold",
476491
"characteristics": {

config/v201/config.json

+7
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,14 @@
265265
"attributes": {
266266
"Actual": "Enabled,Active,Available,Problem"
267267
}
268+
},
269+
"UpdateCertificateSymlinks": {
270+
"variable_name": "UpdateCertificateSymlinks",
271+
"attributes": {
272+
"Actual": "0"
273+
}
268274
}
275+
269276
}
270277
},
271278
{

dependencies.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ websocketpp:
3030
git_tag: 0.8.2
3131
libevse-security:
3232
git: https://github.com/EVerest/libevse-security.git
33-
git_tag: v0.4.1
33+
git_tag: 1604c8b
3434
libwebsockets:
3535
git: https://github.com/warmcat/libwebsockets.git
3636
git_tag: v4.3.3

include/ocpp/common/evse_security.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ class EvseSecurity {
9494
/// \return key pair of certificate and key if present, else std::nullopt
9595
virtual std::optional<KeyPair> get_key_pair(const CertificateSigningUseEnum& certificate_type) = 0;
9696

97+
/// \brief Updates the certificate and key links for the given \p certificate_type
98+
virtual bool update_certificate_links(const CertificateSigningUseEnum& certificate_type) = 0;
99+
97100
/// \brief Retrieves the PEM formatted CA bundle file for the given \p certificate_type
98101
/// \param certificate_type
99102
/// \return CA certificate file

include/ocpp/common/evse_security_impl.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ struct SecurityConfiguration {
2121
fs::path csms_leaf_key_directory;
2222
fs::path secc_leaf_cert_directory;
2323
fs::path secc_leaf_key_directory;
24+
fs::path secc_leaf_cert_link;
25+
fs::path secc_leaf_key_link;
26+
fs::path cpo_cert_chain_link;
2427
std::optional<std::string> private_key_password;
2528
};
2629

@@ -48,6 +51,7 @@ class EvseSecurityImpl : public EvseSecurity {
4851
const std::string& country, const std::string& organization,
4952
const std::string& common, bool use_tpm) override;
5053
std::optional<KeyPair> get_key_pair(const CertificateSigningUseEnum& certificate_type) override;
54+
bool update_certificate_links(const CertificateSigningUseEnum& certificate_type) override;
5155
std::string get_verify_file(const CaCertificateType& certificate_type) override;
5256
int get_leaf_expiry_days_count(const CertificateSigningUseEnum& certificate_type) override;
5357
};

include/ocpp/v201/ctrlr_component_variables.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ extern const ComponentVariable& CertSigningRepeatTimes;
176176
extern const ComponentVariable& CertSigningWaitMinimum;
177177
extern const RequiredComponentVariable& SecurityCtrlrIdentity;
178178
extern const ComponentVariable& MaxCertificateChainSize;
179+
extern const ComponentVariable& UpdateCertificateSymlinks;
179180
extern const RequiredComponentVariable& OrganizationName;
180181
extern const RequiredComponentVariable& SecurityProfile;
181182
extern const ComponentVariable& ACPhaseSwitchingSupported;

lib/ocpp/common/evse_security_impl.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ EvseSecurityImpl::EvseSecurityImpl(const SecurityConfiguration& security_configu
1616
file_paths.directories.secc_leaf_cert_directory = security_configuration.secc_leaf_cert_directory;
1717
file_paths.directories.secc_leaf_key_directory = security_configuration.secc_leaf_key_directory;
1818

19+
file_paths.links.secc_leaf_cert_link = security_configuration.secc_leaf_cert_link;
20+
file_paths.links.secc_leaf_key_link = security_configuration.secc_leaf_key_link;
21+
file_paths.links.cpo_cert_chain_link = security_configuration.cpo_cert_chain_link;
22+
1923
this->evse_security =
2024
std::make_unique<evse_security::EvseSecurity>(file_paths, security_configuration.private_key_password);
2125
}
@@ -98,6 +102,10 @@ std::optional<KeyPair> EvseSecurityImpl::get_key_pair(const CertificateSigningUs
98102
}
99103
}
100104

105+
bool EvseSecurityImpl::update_certificate_links(const CertificateSigningUseEnum& certificate_type) {
106+
return this->evse_security->update_certificate_links(conversions::from_ocpp(certificate_type));
107+
}
108+
101109
std::string EvseSecurityImpl::get_verify_file(const CaCertificateType& certificate_type) {
102110
return this->evse_security->get_verify_file(conversions::from_ocpp(certificate_type));
103111
}

lib/ocpp/v201/charge_point.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,13 @@ void ChargePoint::handle_certificate_signed_req(Call<CertificateSignedRequest> c
17631763
}
17641764
}
17651765

1766+
// Trigger a symlink update for V2G certificates
1767+
if ((cert_signing_use == ocpp::CertificateSigningUseEnum::V2GCertificate) and
1768+
this->device_model->get_optional_value<bool>(ControllerComponentVariables::UpdateCertificateSymlinks)
1769+
.value_or(false)) {
1770+
this->evse_security->update_certificate_links(cert_signing_use);
1771+
}
1772+
17661773
ocpp::CallResult<CertificateSignedResponse> call_result(response, call.uniqueId);
17671774
this->send<CertificateSignedResponse>(call_result);
17681775

lib/ocpp/v201/ctrlr_component_variables.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,13 @@ const ComponentVariable& MaxCertificateChainSize = {
989989
"MaxCertificateChainSize",
990990
}),
991991
};
992+
const ComponentVariable& UpdateCertificateSymlinks = {
993+
ControllerComponents::InternalCtrlr,
994+
std::nullopt,
995+
std::optional<Variable>({
996+
"UpdateCertificateSymlinks",
997+
}),
998+
};
992999
const RequiredComponentVariable& OrganizationName = {
9931000
ControllerComponents::SecurityCtrlr,
9941001
std::nullopt,

tests/evse_security_mock.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class EvseSecurityMock : public EvseSecurity {
2929
(const CertificateSigningUseEnum&, const std::string&, const std::string&, const std::string&, bool),
3030
(override));
3131
MOCK_METHOD(std::optional<KeyPair>, get_key_pair, (const CertificateSigningUseEnum&), (override));
32+
MOCK_METHOD(bool, update_certificate_links, (const CertificateSigningUseEnum&), (override));
3233
MOCK_METHOD(std::string, get_verify_file, (const CaCertificateType&), (override));
3334
MOCK_METHOD(int, get_leaf_expiry_days_count, (const CertificateSigningUseEnum&), (override));
3435
};

0 commit comments

Comments
 (0)