Skip to content

Commit

Permalink
Support for OCPP2.0.1 Plug&Charge (#588)
Browse files Browse the repository at this point in the history
Added support for OCPP2.0.1 Plug&Charge:
* Changed evse_security.yaml interface: Now two separate functions exist to get ocsp request data to be able to request the ocsp data for MO contract certificates
* LeafCertificateType enum was extended with the additional value: MO
* Refactored EvseSecurity and the lib/ocpp to address the required types/interface changes
* Added conversion function in OCPP201 module
* Changed EvseV2G module so that it always includes the OCSP request data of the contract certificate and optionally includes the certificate in the ProvidedIdToken
* Added P&C config for OCPP201
* only adding iso15118HashData to provided token if contract chain could successfully be validated against MO root

---------

Signed-off-by: pietfried <[email protected]>
Signed-off-by: AssemblyJohn <[email protected]>
Co-authored-by: AssemblyJohn <[email protected]>
  • Loading branch information
Pietfried and AssemblyJohn authored Mar 21, 2024
1 parent a8408d3 commit b1c9c4f
Show file tree
Hide file tree
Showing 17 changed files with 378 additions and 58 deletions.
1 change: 1 addition & 0 deletions config/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ generate_config_run_script(CONFIG sil-gen-pm)
generate_config_run_script(CONFIG sil-ocpp)
generate_config_run_script(CONFIG sil-ocpp-custom-extension)
generate_config_run_script(CONFIG sil-ocpp-pnc)
generate_config_run_script(CONFIG sil-ocpp201-pnc)
generate_config_run_script(CONFIG example)

# install configs
Expand Down
2 changes: 1 addition & 1 deletion config/config-sil-ocpp-pnc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ active_modules:
evse_security:
module: EvseSecurity
config_module:
private_key_password: "V2GCaPass2023Valencia"
private_key_password: "123456"
token_provider_1:
module: DummyTokenProviderManual
energy_manager:
Expand Down
192 changes: 192 additions & 0 deletions config/config-sil-ocpp201-pnc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
active_modules:
iso15118_charger:
module: EvseV2G
config_module:
device: auto
tls_security: allow
verify_contract_cert_chain: false
connections:
security:
- module_id: evse_security
implementation_id: main
iso15118_car:
module: PyEvJosev
config_module:
device: auto
supported_ISO15118_2: true
tls_active: true
is_cert_install_needed: true
evse_manager_1:
module: EvseManager
config_module:
connector_id: 1
three_phases: true
has_ventilation: true
country_code: DE
evse_id: "DE*PNX*00001"
session_logging: true
session_logging_xml: false
session_logging_path: /tmp/everest-logs
ac_hlc_enabled: true
ac_hlc_use_5percent: false
ac_enforce_hlc: false
connections:
bsp:
- module_id: yeti_driver_1
implementation_id: board_support
powermeter_grid_side:
- module_id: yeti_driver_1
implementation_id: powermeter
slac:
- module_id: slac
implementation_id: evse
hlc:
- module_id: iso15118_charger
implementation_id: charger
evse_manager_2:
module: EvseManager
config_module:
connector_id: 2
three_phases: true
has_ventilation: true
country_code: DE
evse_id: "2"
session_logging: true
session_logging_xml: false
session_logging_path: /tmp
ac_hlc_enabled: false
ac_hlc_use_5percent: false
ac_enforce_hlc: false
connections:
bsp:
- module_id: yeti_driver_2
implementation_id: board_support
powermeter_grid_side:
- module_id: yeti_driver_2
implementation_id: powermeter
slac:
- module_id: slac
implementation_id: evse
hlc:
- module_id: iso15118_charger
implementation_id: charger
yeti_driver_1:
module: JsYetiSimulator
config_module:
connector_id: 1
yeti_driver_2:
module: JsYetiSimulator
config_module:
connector_id: 2
slac:
module: JsSlacSimulator
car_simulator_1:
module: JsCarSimulator
config_module:
connector_id: 1
auto_enable: true
auto_exec: false
auto_exec_commands: sleep 1;iec_wait_pwr_ready;sleep 1;draw_power_regulated 16,3;sleep 30;unplug
connections:
simulation_control:
- module_id: yeti_driver_1
implementation_id: yeti_simulation_control
ev:
- module_id: iso15118_car
implementation_id: ev
slac:
- module_id: slac
implementation_id: ev
car_simulator_2:
module: JsCarSimulator
config_module:
connector_id: 2
auto_enable: true
auto_exec: false
connections:
simulation_control:
- module_id: yeti_driver_2
implementation_id: yeti_simulation_control
ev:
- module_id: iso15118_car
implementation_id: ev
slac:
- module_id: slac
implementation_id: ev
ocpp:
module: OCPP201
connections:
evse_manager:
- module_id: evse_manager_1
implementation_id: evse
- module_id: evse_manager_2
implementation_id: evse
auth:
- module_id: auth
implementation_id: main
system:
- module_id: system
implementation_id: main
security:
- module_id: evse_security
implementation_id: main
evse_security:
module: EvseSecurity
config_module:
private_key_password: "123456"
token_provider_1:
module: DummyTokenProviderManual
auth:
module: Auth
config_module:
connection_timeout: 120
selection_algorithm: PlugEvents
connections:
token_provider:
- module_id: token_provider_1
implementation_id: main
- module_id: ocpp
implementation_id: auth_provider
- module_id: evse_manager_1
implementation_id: token_provider
- module_id: evse_manager_2
implementation_id: token_provider
token_validator:
- module_id: ocpp
implementation_id: auth_validator
evse_manager:
- module_id: evse_manager_1
implementation_id: evse
- module_id: evse_manager_2
implementation_id: evse
energy_manager:
module: EnergyManager
connections:
energy_trunk:
- module_id: grid_connection_point
implementation_id: energy_grid
grid_connection_point:
module: EnergyNode
config_module:
fuse_limit_A: 40.0
phase_count: 3
connections:
price_information: []
energy_consumer:
- module_id: evse_manager_1
implementation_id: energy_grid
- module_id: evse_manager_2
implementation_id: energy_grid
powermeter:
- module_id: yeti_driver_1
implementation_id: powermeter
api:
module: API
connections:
evse_manager:
- module_id: evse_manager_1
implementation_id: evse
system:
module: System

x-module-layout: {}
4 changes: 2 additions & 2 deletions dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ libcurl:
# OCPP
libocpp:
git: https://github.com/EVerest/libocpp.git
git_tag: 86adda6
git_tag: 778e080
cmake_condition: "EVEREST_DEPENDENCY_ENABLED_LIBOCPP"
# Josev
Josev:
Expand Down Expand Up @@ -79,7 +79,7 @@ everest-utils:
# setting it here can be misleading since it does not affect the version being used
libevse-security:
git: https://github.com/EVerest/libevse-security.git
git_tag: v0.4.3
git_tag: bce1ba4
cmake_condition: "EVEREST_DEPENDENCY_ENABLED_LIBEVSE_SECURITY"
# unit testing
gtest:
Expand Down
22 changes: 19 additions & 3 deletions interfaces/evse_security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,26 @@ cmds:
description: Indicates the result of the command and optional certificate hash data
type: object
$ref: /evse_security#/GetInstalledCertificatesResult
get_ocsp_request_data:
description: Command to retrieve the OCSP request data of the V2G certificates
get_v2g_ocsp_request_data:
description: >-
Command to retrieve the OCSP request data of the V2G certificates. Contains OCSP data for each
certificate that is present in the chain (excluding the root).
result:
description: The OCSP request data of all V2G CA certificates including the Sub CAs (exluding the root)
type: object
$ref: /evse_security#/OCSPRequestDataList
get_mo_ocsp_request_data:
description: >-
Command to retrieve the OCSP request data of the given MO certificate chain. Contains OCSP data
for each certificate that is present in the chain (excluding the root)
arguments:
certificate_chain:
description: Certificate chain for which the OCSP data is retrieved
type: string
result:
description: The OCSP request data of all V2G CA certificates including Sub CAs
description: >-
The OCSP request data of the given certificate chain. Contains OCSP data for each
certificate in the given chain.
type: object
$ref: /evse_security#/OCSPRequestDataList
update_ocsp_cache:
Expand Down
47 changes: 38 additions & 9 deletions lib/staging/ocpp/evse_security_ocpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ EvseSecurity::update_leaf_certificate(const std::string& certificate_chain,
this->r_security.call_update_leaf_certificate(certificate_chain, conversions::from_ocpp(certificate_type)));
}

ocpp::CertificateValidationResult
EvseSecurity::verify_certificate(const std::string& certificate_chain,
const ocpp::CertificateSigningUseEnum& certificate_type) {
ocpp::CertificateValidationResult EvseSecurity::verify_certificate(const std::string& certificate_chain,
const ocpp::LeafCertificateType& certificate_type) {
return conversions::to_ocpp(
this->r_security.call_verify_certificate(certificate_chain, conversions::from_ocpp(certificate_type)));
}
Expand All @@ -53,16 +52,28 @@ EvseSecurity::get_installed_certificates(const std::vector<ocpp::CertificateType
return result;
}

std::vector<ocpp::OCSPRequestData> EvseSecurity::get_ocsp_request_data() {
std::vector<ocpp::OCSPRequestData> EvseSecurity::get_v2g_ocsp_request_data() {
std::vector<ocpp::OCSPRequestData> result;

const auto ocsp_request_data = this->r_security.call_get_ocsp_request_data();
const auto ocsp_request_data = this->r_security.call_get_v2g_ocsp_request_data();
for (const auto& ocsp_request_entry : ocsp_request_data.ocsp_request_data_list) {
result.push_back(conversions::to_ocpp(ocsp_request_entry));
}

return result;
}

std::vector<ocpp::OCSPRequestData> EvseSecurity::get_mo_ocsp_request_data(const std::string& certificate_chain) {
std::vector<ocpp::OCSPRequestData> result;

const auto ocsp_request_data = this->r_security.call_get_mo_ocsp_request_data(certificate_chain);
for (const auto& ocsp_request_entry : ocsp_request_data.ocsp_request_data_list) {
result.push_back(conversions::to_ocpp(ocsp_request_entry));
}

return result;
}

void EvseSecurity::update_ocsp_cache(const ocpp::CertificateHashDataType& certificate_hash_data,
const std::string& ocsp_response) {
this->r_security.call_update_ocsp_cache(conversions::from_ocpp(certificate_hash_data), ocsp_response);
Expand Down Expand Up @@ -123,14 +134,16 @@ ocpp::CaCertificateType to_ocpp(types::evse_security::CaCertificateType other) {
}
}

ocpp::CertificateSigningUseEnum to_ocpp(types::evse_security::LeafCertificateType other) {
ocpp::LeafCertificateType to_ocpp(types::evse_security::LeafCertificateType other) {
switch (other) {
case types::evse_security::LeafCertificateType::CSMS:
return ocpp::CertificateSigningUseEnum::ChargingStationCertificate;
return ocpp::LeafCertificateType::CSMS;
case types::evse_security::LeafCertificateType::V2G:
return ocpp::CertificateSigningUseEnum::V2GCertificate;
return ocpp::LeafCertificateType::V2G;
case types::evse_security::LeafCertificateType::MF:
return ocpp::CertificateSigningUseEnum::ManufacturerCertificate;
return ocpp::LeafCertificateType::MF;
case types::evse_security::LeafCertificateType::MO:
return ocpp::LeafCertificateType::MO;
default:
throw std::runtime_error(
"Could not convert types::evse_security::LeafCertificateType to ocpp::CertificateSigningUseEnum");
Expand Down Expand Up @@ -305,6 +318,22 @@ types::evse_security::LeafCertificateType from_ocpp(ocpp::CertificateSigningUseE
}
}

types::evse_security::LeafCertificateType from_ocpp(ocpp::LeafCertificateType other) {
switch (other) {
case ocpp::LeafCertificateType::CSMS:
return types::evse_security::LeafCertificateType::CSMS;
case ocpp::LeafCertificateType::V2G:
return types::evse_security::LeafCertificateType::V2G;
case ocpp::LeafCertificateType::MF:
return types::evse_security::LeafCertificateType::MF;
case ocpp::LeafCertificateType::MO:
return types::evse_security::LeafCertificateType::MO;
default:
throw std::runtime_error(
"Could not convert ocpp::CertificateSigningUseEnum to types::evse_security::LeafCertificateType");
}
}

types::evse_security::CertificateType from_ocpp(ocpp::CertificateType other) {
switch (other) {
case ocpp::CertificateType::V2GRootCertificate:
Expand Down
13 changes: 7 additions & 6 deletions lib/staging/ocpp/evse_security_ocpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ class EvseSecurity : public ocpp::EvseSecurity {
const ocpp::CaCertificateType& certificate_type) override;
ocpp::DeleteCertificateResult
delete_certificate(const ocpp::CertificateHashDataType& certificate_hash_data) override;
ocpp::CertificateValidationResult
verify_certificate(const std::string& certificate_chain,
const ocpp::CertificateSigningUseEnum& certificate_type) override;
ocpp::CertificateValidationResult verify_certificate(const std::string& certificate_chain,
const ocpp::LeafCertificateType& certificate_type) override;
ocpp::InstallCertificateResult
update_leaf_certificate(const std::string& certificate_chain,
const ocpp::CertificateSigningUseEnum& certificate_type) override;
std::vector<ocpp::CertificateHashDataChain>
get_installed_certificates(const std::vector<ocpp::CertificateType>& certificate_types) override;
std::vector<ocpp::OCSPRequestData> get_ocsp_request_data() override;
std::vector<ocpp::OCSPRequestData> get_v2g_ocsp_request_data() override;
std::vector<ocpp::OCSPRequestData> get_mo_ocsp_request_data(const std::string& certificate_chain) override;
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;
Expand All @@ -44,7 +44,7 @@ class EvseSecurity : public ocpp::EvseSecurity {
namespace conversions {

ocpp::CaCertificateType to_ocpp(types::evse_security::CaCertificateType other);
ocpp::CertificateSigningUseEnum to_ocpp(types::evse_security::LeafCertificateType other);
ocpp::LeafCertificateType to_ocpp(types::evse_security::LeafCertificateType other);
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);
Expand All @@ -58,6 +58,7 @@ ocpp::KeyPair to_ocpp(types::evse_security::KeyPair 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);
Expand All @@ -70,4 +71,4 @@ types::evse_security::KeyPair from_ocpp(ocpp::KeyPair other);

}; // namespace conversions

#endif // EVEREST_SECURITY_OCPP_HPP
#endif // EVEREST_SECURITY_OCPP_HPP
Loading

0 comments on commit b1c9c4f

Please sign in to comment.