Skip to content

Commit

Permalink
added dependency to libevse-security and used this for implementation…
Browse files Browse the repository at this point in the history
… of evse_security interface. This internal evse_security_impl is used of no external implementation is given in the ChargePoint constructor

Signed-off-by: pietfried <[email protected]>
  • Loading branch information
Pietfried committed Sep 1, 2023
1 parent 2e53477 commit 563697c
Show file tree
Hide file tree
Showing 19 changed files with 573 additions and 45 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.14)

project(ocpp
VERSION 0.8.7
VERSION 0.8.8
DESCRIPTION "A C++ implementation of the Open Charge Point Protocol"
LANGUAGES CXX
)
Expand Down Expand Up @@ -40,6 +40,7 @@ else()
find_package(fsm REQUIRED)
find_package(everest-timer REQUIRED)
find_package(everest-log REQUIRED)
find_package(everest-evse_security REQUIRED)
endif()

# library code
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ This is defined in libocpp/include/ocpp/v16/charge_point.hpp and takes the follo

- message_log_path: this points to the directory in which libocpp can put OCPP communication logfiles for debugging purposes. This behavior can be controlled by the "LogMessages" (set to true by default) and "LogMessagesFormat" (set to ["log", "html", "session_logging"] by default, "console" and "console_detailed" are also available) configuration keys in the "Internal" section of the config file. Please note that this is intended for debugging purposes only as it logs all communication, including authentication messages.

- certs_path: this points to the directory where certificates used by libocpp are located, these are used for the "Improved security for OCPP 1.6-J" whitepaper (e.g. Security Profile 3 TLS with Client Side Certificates) as well as for Plug & Charge.
- evse_security: this is a pointer to an implementation of the [evse_security](include/ocpp/common/evse_security.hpp) interface. This allows you to include your custom implementation of the security related operations according to this interface. If you set this value to nullptr, the internal implementation of the security related operations of libocpp will be used. In this case you need to specify the parameter security_configuration

- security_configuration: this parameter should only be set in case the evse_security parameter is nullptr. It specifies the file paths that are required to set up the internal evse_security implementation. Note that you need to specify bundle files for the CA certificates and directories for the certificates and keys

The directory layout expected is as follows
```bash
Expand Down
3 changes: 3 additions & 0 deletions dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ date:
websocketpp:
git: https://github.com/zaphoyd/websocketpp.git
git_tag: 0.8.2
libevse-security:
git: [email protected]:EVerest/libevse-security.git
git_tag: main
11 changes: 8 additions & 3 deletions include/ocpp/common/charging_station_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

#include <boost/shared_ptr.hpp>

#include <ocpp/common/message_queue.hpp>
#include <ocpp/common/evse_security.hpp>
#include <ocpp/common/evse_security_impl.hpp>
#include <ocpp/common/message_queue.hpp>
#include <ocpp/common/websocket/websocket.hpp>

namespace ocpp {
Expand Down Expand Up @@ -38,8 +39,12 @@ class ChargingStationBase {

public:
/// \brief Constructor for ChargingStationBase
/// \param evse_security Pointer to evse_security that manages security related operations
ChargingStationBase(const std::shared_ptr<EvseSecurity> evse_security);
/// \param evse_security Pointer to evse_security that manages security related operations; if nullptr
/// security_configuration must be set
/// \param security_configuration specifies the file paths that are required to set up the internal evse_security
/// implementation
explicit ChargingStationBase(const std::shared_ptr<EvseSecurity> evse_security,
const std::optional<SecurityConfiguration> security_configuration = std::nullopt);
virtual ~ChargingStationBase(){};
};

Expand Down
84 changes: 84 additions & 0 deletions include/ocpp/common/evse_security_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
#ifndef OCPP_COMMON_EVSE_SECURITY_IMPL
#define OCPP_COMMON_EVSE_SECURITY_IMPL

#include <filesystem>
#include <optional>

#include <evse_security.hpp>
#include <ocpp/common/evse_security.hpp>

namespace ocpp {

struct SecurityConfiguration {
std::filesystem::path csms_ca_bundle;
std::filesystem::path mf_ca_bundle;
std::filesystem::path mo_ca_bundle;
std::filesystem::path v2g_ca_bundle;
std::filesystem::path csms_leaf_cert_directory;
std::filesystem::path csms_leaf_key_directory;
std::filesystem::path secc_leaf_cert_directory;
std::filesystem::path secc_leaf_key_directory;
std::optional<std::string> private_key_password;
};

class EvseSecurityImpl : public EvseSecurity {

private:
std::unique_ptr<evse_security::EvseSecurity> evse_security;

public:
explicit EvseSecurityImpl(const SecurityConfiguration& file_paths);
InstallCertificateResult install_ca_certificate(const std::string& certificate,
const CaCertificateType& certificate_type) override;
DeleteCertificateResult delete_certificate(const CertificateHashDataType& certificate_hash_data) override;
InstallCertificateResult update_leaf_certificate(const std::string& certificate_chain,
const CertificateSigningUseEnum& certificate_type) override;
InstallCertificateResult verify_certificate(const std::string& certificate_chain,
const CertificateSigningUseEnum& certificate_type) override;
std::vector<CertificateHashDataChain>
get_installed_certificates(const std::vector<CertificateType>& certificate_types) override;
std::vector<OCSPRequestData> get_ocsp_request_data() override;
void update_ocsp_cache(const CertificateHashDataType& certificate_hash_data,
const std::string& ocsp_response) override;
bool is_ca_certificate_installed(const CaCertificateType& certificate_type) override;
std::string generate_certificate_signing_request(const CertificateSigningUseEnum& certificate_type,
const std::string& country, const std::string& organization,
const std::string& common) override;
std::optional<KeyPair> get_key_pair(const CertificateSigningUseEnum& certificate_type) override;
std::string get_verify_file(const CaCertificateType& certificate_type) override;
int get_leaf_expiry_days_count(const CertificateSigningUseEnum& certificate_type) override;
};

namespace conversions {

CaCertificateType to_ocpp(evse_security::CaCertificateType other);
CertificateSigningUseEnum to_ocpp(evse_security::LeafCertificateType other);
CertificateType to_ocpp(evse_security::CertificateType other);
HashAlgorithmEnumType to_ocpp(evse_security::HashAlgorithm other);
InstallCertificateResult to_ocpp(evse_security::InstallCertificateResult other);
DeleteCertificateResult to_ocpp(evse_security::DeleteCertificateResult other);

CertificateHashDataType to_ocpp(evse_security::CertificateHashData other);
CertificateHashDataChain to_ocpp(evse_security::CertificateHashDataChain other);
OCSPRequestData to_ocpp(evse_security::OCSPRequestData other);
KeyPair to_ocpp(evse_security::KeyPair other);

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

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

}; // namespace conversions

} // namespace ocpp

#endif
3 changes: 1 addition & 2 deletions include/ocpp/common/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,7 @@ void from_json(const json& j, CertificateHashDataType& k);
/// \returns an output stream with the CertificateHashDataType written to
std::ostream& operator<<(std::ostream& os, const CertificateHashDataType& k);

enum class CertificateType
{
enum class CertificateType {
V2GRootCertificate,
MORootCertificate,
CSMSRootCertificate,
Expand Down
6 changes: 3 additions & 3 deletions include/ocpp/common/websocket/websocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#ifndef OCPP_WEBSOCKET_HPP
#define OCPP_WEBSOCKET_HPP

#include <ocpp/common/ocpp_logging.hpp>
#include <ocpp/common/evse_security.hpp>
#include <ocpp/common/ocpp_logging.hpp>
#include <ocpp/common/websocket/websocket_plain.hpp>
#include <ocpp/common/websocket/websocket_tls.hpp>

Expand All @@ -22,8 +22,8 @@ class Websocket {

public:
/// \brief Creates a new Websocket object with the provided \p connection_options
explicit Websocket(const WebsocketConnectionOptions& connection_options, std::shared_ptr<EvseSecurity> evse_security,
std::shared_ptr<MessageLogging> logging);
explicit Websocket(const WebsocketConnectionOptions& connection_options,
std::shared_ptr<EvseSecurity> evse_security, std::shared_ptr<MessageLogging> logging);
~Websocket();

/// \brief connect to a websocket (TLS or non-TLS depending on the central system uri in the configuration).
Expand Down
9 changes: 7 additions & 2 deletions include/ocpp/v16/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <ocpp/common/cistring.hpp>
#include <ocpp/common/evse_security.hpp>
#include <ocpp/common/evse_security_impl.hpp>
#include <ocpp/v16/ocpp_types.hpp>
#include <ocpp/v16/types.hpp>

Expand Down Expand Up @@ -54,11 +55,15 @@ class ChargePoint {
/// "LogMessagesFormat" (set to ["log", "html", "session_logging"] by default, "console" and "console_detailed" are
/// also available) configuration keys in the "Internal" section of the config file. Please note that this is
/// intended for debugging purposes only as it logs all communication, including authentication messages.
/// \param evse_security Pointer to evse_security that manages security related operations
/// \param evse_security Pointer to evse_security that manages security related operations; if nullptr
/// security_configuration must be set
/// \param security_configuration specifies the file paths that are required to set up the internal evse_security
/// implementation
explicit ChargePoint(const std::string& config, const std::filesystem::path& share_path,
const std::filesystem::path& user_config_path, const std::filesystem::path& database_path,
const std::filesystem::path& sql_init_path, const std::filesystem::path& message_log_path,
const std::shared_ptr<EvseSecurity> evse_security);
const std::shared_ptr<EvseSecurity> evse_security,
const std::optional<SecurityConfiguration> security_configuration = std::nullopt);

~ChargePoint();

Expand Down
8 changes: 6 additions & 2 deletions include/ocpp/v16/charge_point_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,11 +314,15 @@ class ChargePointImpl : ocpp::ChargingStationBase {
/// \param certs_path this points to the directory where certificates used by libocpp are located, these are used
/// for the "Improved security for OCPP 1.6-J" whitepaper (eg. Security Profile 3 TLS with Client Side Certificates)
/// as well as for Plug & Charge.
/// \param evse_security Pointer to evse_security that manages security related operations
/// \param evse_security Pointer to evse_security that manages security related operations; if nullptr
/// security_configuration must be set
/// \param security_configuration specifies the file paths that are required to set up the internal evse_security
/// implementation
explicit ChargePointImpl(const std::string& config, const std::filesystem::path& share_path,
const std::filesystem::path& user_config_path, const std::filesystem::path& database_path,
const std::filesystem::path& sql_init_path, const std::filesystem::path& message_log_path,
const std::shared_ptr<EvseSecurity> evse_security);
const std::shared_ptr<EvseSecurity> evse_security,
const std::optional<SecurityConfiguration> security_configuration);

~ChargePointImpl() {
}
Expand Down
8 changes: 6 additions & 2 deletions include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,13 +272,17 @@ class ChargePoint : ocpp::ChargingStationBase {
/// \param ocpp_main_path Path where utility files for OCPP are read and written to
/// \param core_database_path Path to directory where core database is located
/// \param message_log_path Path to where logfiles are written to
/// \param evse_security Pointer to evse_security that manages security related operations
/// \param evse_security Pointer to evse_security that manages security related operations; if nullptr
/// security_configuration must be set
/// \param callbacks Callbacks that will be registered for ChargePoint
/// \param security_configuration specifies the file paths that are required to set up the internal evse_security
/// implementation
ChargePoint(const std::map<int32_t, int32_t>& evse_connector_structure,
const std::string& device_model_storage_address, const std::string& ocpp_main_path,
const std::string& core_database_path, const std::string& sql_init_path,
const std::string& message_log_path, const std::shared_ptr<EvseSecurity> evse_security,
const Callbacks& callbacks);
const Callbacks& callbacks,
const std::optional<SecurityConfiguration> security_configuration = std::nullopt);

/// \brief Starts the ChargePoint, initializes and connects to the Websocket endpoint
/// \param bootreason Optional bootreason (default: PowerUp).
Expand Down
2 changes: 2 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ target_sources(ocpp
ocpp/common/schemas.cpp
ocpp/common/types.cpp
ocpp/common/utils.cpp
ocpp/common/evse_security_impl.cpp
ocpp/v16/charge_point.cpp
ocpp/v16/database_handler.cpp
ocpp/v16/charge_point_impl.cpp
Expand Down Expand Up @@ -79,6 +80,7 @@ target_link_libraries(ocpp
everest::timer
websocketpp::websocketpp
nlohmann_json_schema_validator
everest::evse_security
PRIVATE
OpenSSL::SSL
OpenSSL::Crypto
Expand Down
13 changes: 12 additions & 1 deletion lib/ocpp/common/charging_station_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,19 @@
#include <ocpp/common/charging_station_base.hpp>

namespace ocpp {
ChargingStationBase::ChargingStationBase(const std::shared_ptr<EvseSecurity> evse_security) : evse_security(evse_security),
ChargingStationBase::ChargingStationBase(const std::shared_ptr<EvseSecurity> evse_security,
const std::optional<SecurityConfiguration> security_configuration) :
uuid_generator(boost::uuids::random_generator()) {

if (evse_security != nullptr) {
this->evse_security = evse_security;
} else {
if (!security_configuration.has_value()) {
throw std::runtime_error("No implementation of EvseSecurity interface and no SecurityConfiguration "
"provided to chargepoint constructor. One of options must be set");
}
this->evse_security = std::make_shared<EvseSecurityImpl>(security_configuration.value());
}
this->work = boost::make_shared<boost::asio::io_service::work>(this->io_service);
this->io_service_thread = std::thread([this]() { this->io_service.run(); });
}
Expand Down
Loading

0 comments on commit 563697c

Please sign in to comment.