diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt index 583f88282..f6349c26c 100644 --- a/config/CMakeLists.txt +++ b/config/CMakeLists.txt @@ -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 diff --git a/config/config-sil-ocpp-pnc.yaml b/config/config-sil-ocpp-pnc.yaml index bfc4eb956..5c117a6d4 100644 --- a/config/config-sil-ocpp-pnc.yaml +++ b/config/config-sil-ocpp-pnc.yaml @@ -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: diff --git a/config/config-sil-ocpp201-pnc.yaml b/config/config-sil-ocpp201-pnc.yaml new file mode 100644 index 000000000..9fd745110 --- /dev/null +++ b/config/config-sil-ocpp201-pnc.yaml @@ -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: {} diff --git a/dependencies.yaml b/dependencies.yaml index 54aa66164..37993d941 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -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: @@ -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: diff --git a/interfaces/evse_security.yaml b/interfaces/evse_security.yaml index 40feba778..353d2142e 100644 --- a/interfaces/evse_security.yaml +++ b/interfaces/evse_security.yaml @@ -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: diff --git a/lib/staging/ocpp/evse_security_ocpp.cpp b/lib/staging/ocpp/evse_security_ocpp.cpp index 27fcf5409..e8b942d2c 100644 --- a/lib/staging/ocpp/evse_security_ocpp.cpp +++ b/lib/staging/ocpp/evse_security_ocpp.cpp @@ -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))); } @@ -53,16 +52,28 @@ EvseSecurity::get_installed_certificates(const std::vector EvseSecurity::get_ocsp_request_data() { +std::vector EvseSecurity::get_v2g_ocsp_request_data() { std::vector 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 EvseSecurity::get_mo_ocsp_request_data(const std::string& certificate_chain) { + std::vector 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); @@ -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"); @@ -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: diff --git a/lib/staging/ocpp/evse_security_ocpp.hpp b/lib/staging/ocpp/evse_security_ocpp.hpp index b1882e6b0..2c4d9d150 100644 --- a/lib/staging/ocpp/evse_security_ocpp.hpp +++ b/lib/staging/ocpp/evse_security_ocpp.hpp @@ -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 get_installed_certificates(const std::vector& certificate_types) override; - std::vector get_ocsp_request_data() override; + std::vector get_v2g_ocsp_request_data() override; + std::vector 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; @@ -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); @@ -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); @@ -70,4 +71,4 @@ types::evse_security::KeyPair from_ocpp(ocpp::KeyPair other); }; // namespace conversions -#endif // EVEREST_SECURITY_OCPP_HPP \ No newline at end of file +#endif // EVEREST_SECURITY_OCPP_HPP diff --git a/modules/EvseSecurity/conversions.cpp b/modules/EvseSecurity/conversions.cpp index f2417ad7f..eba1adaaf 100644 --- a/modules/EvseSecurity/conversions.cpp +++ b/modules/EvseSecurity/conversions.cpp @@ -45,6 +45,8 @@ evse_security::LeafCertificateType from_everest(types::evse_security::LeafCertif return evse_security::LeafCertificateType::V2G; case types::evse_security::LeafCertificateType::MF: return evse_security::LeafCertificateType::MF; + case types::evse_security::LeafCertificateType::MO: + return evse_security::LeafCertificateType::MO; default: throw std::runtime_error( "Could not convert types::evse_security::LeafCertificateType to evse_security::LeafCertificateType"); @@ -231,6 +233,8 @@ types::evse_security::LeafCertificateType to_everest(evse_security::LeafCertific return types::evse_security::LeafCertificateType::V2G; case evse_security::LeafCertificateType::MF: return types::evse_security::LeafCertificateType::MF; + case evse_security::LeafCertificateType::MO: + return types::evse_security::LeafCertificateType::MO; default: throw std::runtime_error( "Could not convert evse_security::LeafCertificateType to types::evse_security::LeafCertificateType"); @@ -422,4 +426,4 @@ types::evse_security::KeyPair to_everest(evse_security::KeyPair other) { } // namespace conversions -} // namespace module \ No newline at end of file +} // namespace module diff --git a/modules/EvseSecurity/main/evse_securityImpl.cpp b/modules/EvseSecurity/main/evse_securityImpl.cpp index 579a5d98b..cd6572464 100644 --- a/modules/EvseSecurity/main/evse_securityImpl.cpp +++ b/modules/EvseSecurity/main/evse_securityImpl.cpp @@ -63,8 +63,13 @@ types::evse_security::GetInstalledCertificatesResult evse_securityImpl::handle_g return conversions::to_everest(this->evse_security->get_installed_certificates(_certificate_types)); } -types::evse_security::OCSPRequestDataList evse_securityImpl::handle_get_ocsp_request_data() { - return conversions::to_everest(this->evse_security->get_ocsp_request_data()); +types::evse_security::OCSPRequestDataList evse_securityImpl::handle_get_v2g_ocsp_request_data() { + return conversions::to_everest(this->evse_security->get_v2g_ocsp_request_data()); +} + +types::evse_security::OCSPRequestDataList +evse_securityImpl::handle_get_mo_ocsp_request_data(std::string& certificate_chain) { + return conversions::to_everest(this->evse_security->get_mo_ocsp_request_data(certificate_chain)); } void evse_securityImpl::handle_update_ocsp_cache(types::evse_security::CertificateHashData& certificate_hash_data, diff --git a/modules/EvseSecurity/main/evse_securityImpl.hpp b/modules/EvseSecurity/main/evse_securityImpl.hpp index cccfb15be..139bd26a2 100644 --- a/modules/EvseSecurity/main/evse_securityImpl.hpp +++ b/modules/EvseSecurity/main/evse_securityImpl.hpp @@ -47,7 +47,9 @@ class evse_securityImpl : public evse_securityImplBase { types::evse_security::LeafCertificateType& certificate_type) override; virtual types::evse_security::GetInstalledCertificatesResult handle_get_installed_certificates(std::vector& certificate_types) override; - virtual types::evse_security::OCSPRequestDataList handle_get_ocsp_request_data() override; + virtual types::evse_security::OCSPRequestDataList handle_get_v2g_ocsp_request_data() override; + virtual types::evse_security::OCSPRequestDataList + handle_get_mo_ocsp_request_data(std::string& certificate_chain) override; virtual void handle_update_ocsp_cache(types::evse_security::CertificateHashData& certificate_hash_data, std::string& ocsp_response) override; virtual bool handle_is_ca_certificate_installed(types::evse_security::CaCertificateType& certificate_type) override; diff --git a/modules/EvseV2G/iso_server.cpp b/modules/EvseV2G/iso_server.cpp index 9850754e7..af4e2ca7b 100644 --- a/modules/EvseV2G/iso_server.cpp +++ b/modules/EvseV2G/iso_server.cpp @@ -1220,11 +1220,37 @@ static enum v2g_event handle_iso_payment_details(struct v2g_connection* conn) { } } + // initialize contract cert chain to retrieve ocsp request data std::string contract_cert_chain_pem = ""; + // Save the certificate chain in a variable in PEM format to publish it + mbedtls_x509_crt* crt = &conn->ctx->session.contract.crt; + unsigned char* base64Buffer = NULL; + size_t olen; + + while (crt != nullptr && crt->version != 0) { + mbedtls_base64_encode(NULL, 0, &olen, crt->raw.p, crt->raw.len); + base64Buffer = static_cast(malloc(olen)); + if ((base64Buffer == NULL) || + ((mbedtls_base64_encode(base64Buffer, olen, &olen, crt->raw.p, crt->raw.len)) != 0)) { + dlog(DLOG_LEVEL_ERROR, "Unable to encode certificate chain"); + break; + } + contract_cert_chain_pem.append("-----BEGIN CERTIFICATE-----\n"); + contract_cert_chain_pem.append(std::string(reinterpret_cast(base64Buffer), olen)); + contract_cert_chain_pem.append("\n-----END CERTIFICATE-----\n"); + + free(base64Buffer); + crt = crt->next; + } + + std::optional> iso15118_certificate_hash_data; + /* Only if certificate chain verification should be done locally by the EVSE */ if (conn->ctx->session.verify_contract_cert_chain == true) { - std::string v2g_root_cert_path = conn->ctx->certs_path + "/ca/v2g/V2G_ROOT_CA.pem"; - std::string mo_root_cert_path = conn->ctx->certs_path + "/ca/mo/MO_ROOT_CA.pem"; + std::string v2g_root_cert_path = + conn->ctx->r_security->call_get_verify_file(types::evse_security::CaCertificateType::V2G); + std::string mo_root_cert_path = + conn->ctx->r_security->call_get_verify_file(types::evse_security::CaCertificateType::MO); mbedtls_x509_crt contract_root_crt; mbedtls_x509_crt_init(&contract_root_crt); uint32_t flags; @@ -1259,27 +1285,10 @@ static enum v2g_event handle_iso_payment_details(struct v2g_connection* conn) { } dlog(DLOG_LEVEL_INFO, "Validation of the contract certificate was successful!"); - } else { - // Save the certificate chain in a variable in PEM format to publish it - mbedtls_x509_crt* crt = &conn->ctx->session.contract.crt; - unsigned char* base64Buffer = NULL; - size_t olen; - - while (crt != nullptr && crt->version != 0) { - mbedtls_base64_encode(NULL, 0, &olen, crt->raw.p, crt->raw.len); - base64Buffer = static_cast(malloc(olen)); - if ((base64Buffer == NULL) || - ((mbedtls_base64_encode(base64Buffer, olen, &olen, crt->raw.p, crt->raw.len)) != 0)) { - dlog(DLOG_LEVEL_ERROR, "Unable to encode certificate chain"); - break; - } - contract_cert_chain_pem.append("-----BEGIN CERTIFICATE-----\n"); - contract_cert_chain_pem.append(std::string(reinterpret_cast(base64Buffer), olen)); - contract_cert_chain_pem.append("\n-----END CERTIFICATE-----\n"); - free(base64Buffer); - crt = crt->next; - } + // contract chain ocsp data can only be retrieved if the MO root is present and the chain could be verified + const auto ocsp_response = conn->ctx->r_security->call_get_mo_ocsp_request_data(contract_cert_chain_pem); + iso15118_certificate_hash_data = convert_to_certificate_hash_data_info_vector(ocsp_response); } generate_random_data(&conn->ctx->session.gen_challenge, GEN_CHALLENGE_SIZE); @@ -1292,9 +1301,8 @@ static enum v2g_event handle_iso_payment_details(struct v2g_connection* conn) { types::authorization::ProvidedIdToken ProvidedIdToken; ProvidedIdToken.id_token = {std::string(cert_emaid), types::authorization::IdTokenType::eMAID}; ProvidedIdToken.authorization_type = types::authorization::AuthorizationType::PlugAndCharge; - if (contract_cert_chain_pem.empty() == false) { - ProvidedIdToken.certificate = contract_cert_chain_pem; - } + ProvidedIdToken.iso15118CertificateHashData = iso15118_certificate_hash_data; + ProvidedIdToken.certificate = contract_cert_chain_pem; conn->ctx->p_charger->publish_Require_Auth_PnC(ProvidedIdToken); } else { diff --git a/modules/EvseV2G/tools.cpp b/modules/EvseV2G/tools.cpp index 6d8f4691f..f94db476d 100644 --- a/modules/EvseV2G/tools.cpp +++ b/modules/EvseV2G/tools.cpp @@ -341,3 +341,36 @@ std::string convert_to_hex_str(const uint8_t* data, int len) { return string_stream.str(); } + +types::iso15118_charger::HashAlgorithm +convert_to_hash_algorithm(const types::evse_security::HashAlgorithm hash_algorithm) { + switch (hash_algorithm) { + case types::evse_security::HashAlgorithm::SHA256: + return types::iso15118_charger::HashAlgorithm::SHA256; + case types::evse_security::HashAlgorithm::SHA384: + return types::iso15118_charger::HashAlgorithm::SHA384; + case types::evse_security::HashAlgorithm::SHA512: + return types::iso15118_charger::HashAlgorithm::SHA512; + default: + throw std::runtime_error( + "Could not convert types::evse_security::HashAlgorithm to types::iso15118_charger::HashAlgorithm"); + } +} + +std::vector +convert_to_certificate_hash_data_info_vector(const types::evse_security::OCSPRequestDataList& ocsp_request_data_list) { + std::vector certificate_hash_data_info_vec; + for (const auto& ocsp_request_data : ocsp_request_data_list.ocsp_request_data_list) { + if (ocsp_request_data.responder_url.has_value() and ocsp_request_data.certificate_hash_data.has_value()) { + types::iso15118_charger::CertificateHashDataInfo certificate_hash_data; + certificate_hash_data.hashAlgorithm = + convert_to_hash_algorithm(ocsp_request_data.certificate_hash_data.value().hash_algorithm); + certificate_hash_data.issuerNameHash = ocsp_request_data.certificate_hash_data.value().issuer_name_hash; + certificate_hash_data.issuerKeyHash = ocsp_request_data.certificate_hash_data.value().issuer_key_hash; + certificate_hash_data.serialNumber = ocsp_request_data.certificate_hash_data.value().serial_number; + certificate_hash_data.responderURL = ocsp_request_data.responder_url.value(); + certificate_hash_data_info_vec.push_back(certificate_hash_data); + } + } + return certificate_hash_data_info_vec; +} diff --git a/modules/EvseV2G/tools.hpp b/modules/EvseV2G/tools.hpp index 5e74d90b6..b9365e233 100644 --- a/modules/EvseV2G/tools.hpp +++ b/modules/EvseV2G/tools.hpp @@ -4,6 +4,8 @@ #ifndef TOOLS_H #define TOOLS_H +#include +#include #include #include #include @@ -12,6 +14,7 @@ #include #include #include +#include #define MAX_FILE_NAME_LENGTH 100 #define MAX_PKI_CA_LENGTH 4 /* leaf up to root certificate */ @@ -117,4 +120,20 @@ uint8_t get_dir_numbered_file_names(char file_names[MAX_PKI_CA_LENGTH][MAX_FILE_ */ std::string convert_to_hex_str(const uint8_t* data, int len); +/** + * \brief convert the given \p hash_algorithm to type types::iso15118_charger::HashAlgorithm + * \param hash_algorithm + * \return types::iso15118_charger::HashAlgorithm + */ +types::iso15118_charger::HashAlgorithm +convert_to_hash_algorithm(const types::evse_security::HashAlgorithm hash_algorithm); + +/** + * \brief convert the given \p ocsp_request_data_list to std::vector + * \param ocsp_request_data_list + * \return std::vector + */ +std::vector +convert_to_certificate_hash_data_info_vector(const types::evse_security::OCSPRequestDataList& ocsp_request_data_list); + #endif /* TOOLS_H */ diff --git a/modules/OCPP201/OCPP201.cpp b/modules/OCPP201/OCPP201.cpp index 391d9a7c4..c610a337b 100644 --- a/modules/OCPP201/OCPP201.cpp +++ b/modules/OCPP201/OCPP201.cpp @@ -491,14 +491,8 @@ void OCPP201::ready() { evse->subscribe_iso15118_certificate_request( [this, evse_id](const types::iso15118_charger::Request_Exi_Stream_Schema& certificate_request) { - // transform request forward to libocpp - ocpp::v201::Get15118EVCertificateRequest ocpp_request; - ocpp_request.exiRequest = certificate_request.exiRequest; - ocpp_request.iso15118SchemaVersion = certificate_request.iso15118SchemaVersion; - ocpp_request.action = - conversions::to_ocpp_certificate_action_enum(certificate_request.certificateAction); - - auto ocpp_response = this->charge_point->on_get_15118_ev_certificate_request(ocpp_request); + auto ocpp_response = this->charge_point->on_get_15118_ev_certificate_request( + conversions::to_ocpp_get_15118_certificate_request(certificate_request)); EVLOG_debug << "Received response from get_15118_ev_certificate_request: " << ocpp_response; // transform response, inject action, send to associated EvseManager const auto everest_response_status = diff --git a/modules/OCPP201/conversions.cpp b/modules/OCPP201/conversions.cpp index df5b9d959..f9c89f917 100644 --- a/modules/OCPP201/conversions.cpp +++ b/modules/OCPP201/conversions.cpp @@ -753,6 +753,15 @@ ocpp::v201::AttributeEnum to_ocpp_attribute_enum(const types::ocpp::AttributeEnu } } +ocpp::v201::Get15118EVCertificateRequest +to_ocpp_get_15118_certificate_request(const types::iso15118_charger::Request_Exi_Stream_Schema& request) { + ocpp::v201::Get15118EVCertificateRequest _request; + _request.iso15118SchemaVersion = request.iso15118SchemaVersion; + _request.exiRequest = request.exiRequest; + _request.action = conversions::to_ocpp_certificate_action_enum(request.certificateAction); + return _request; +} + types::system::UploadLogsRequest to_everest_upload_logs_request(const ocpp::v201::GetLogRequest& request) { types::system::UploadLogsRequest _request; _request.location = request.log.remoteLocation.get(); diff --git a/modules/OCPP201/conversions.hpp b/modules/OCPP201/conversions.hpp index e6ba21e2d..2e3646c73 100644 --- a/modules/OCPP201/conversions.hpp +++ b/modules/OCPP201/conversions.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -105,6 +106,11 @@ ocpp::v201::EVSE to_ocpp_evse(const types::ocpp::EVSE& evse); /// \brief Converts a given types::ocpp::AttributeEnum to ocpp::v201::AttributeEnum ocpp::v201::AttributeEnum to_ocpp_attribute_enum(const types::ocpp::AttributeEnum attribute_enum); +/// \brief Converts a given types::types::iso15118_charger::Request_Exi_Stream_Schema to +/// ocpp::v201::Get15118EVCertificateRequest +ocpp::v201::Get15118EVCertificateRequest +to_ocpp_get_15118_certificate_request(const types::iso15118_charger::Request_Exi_Stream_Schema& request); + /// \brief Converts a given ocpp::v201::ReasonEnum \p stop_reason to a types::evse_manager::StopTransactionReason. types::evse_manager::StopTransactionReason to_everest_stop_transaction_reason(const ocpp::v201::ReasonEnum& stop_reason); diff --git a/types/evse_security.yaml b/types/evse_security.yaml index ad9821e47..7709aca3b 100644 --- a/types/evse_security.yaml +++ b/types/evse_security.yaml @@ -21,6 +21,7 @@ types: - CSMS - V2G - MF + - MO CertificateType: description: Enum specifies certificate type of leaf and CA certificates type: string