Skip to content

Commit

Permalink
Added support for:
Browse files Browse the repository at this point in the history
- libwebsockets for tpm/secprofile 2/3
- TPM with hardware generated key
- config for TPM usage
- cmake for compile-time libwebsockets usage

Signed-off-by: AssemblyJohn <[email protected]>
  • Loading branch information
AssemblyJohn authored and AssemblyJohn committed Dec 20, 2023
1 parent 7865283 commit cbb2cf1
Show file tree
Hide file tree
Showing 12 changed files with 1,070 additions and 1 deletion.
3 changes: 2 additions & 1 deletion config/v16/config-docker.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"ChargePointModel": "Yeti",
"ChargePointVendor": "Pionix",
"FirmwareVersion": "0.1",
"AllowChargingProfileWithoutStartSchedule": true
"AllowChargingProfileWithoutStartSchedule": true,
"UseTPM" : false
},
"Core": {
"AuthorizeRemoteTxRequests": false,
Expand Down
5 changes: 5 additions & 0 deletions config/v16/profile_schemas/Internal.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@
"TLS_AES_128_GCM_SHA256"
]
},
"UseTPM": {
"type": "boolean",
"readOnly": true,
"default": false
},
"RetryBackoffRandomRange": {
"$comment": "maximum value for the random part of the websocket reconnect back-off time",
"type": "integer",
Expand Down
4 changes: 4 additions & 0 deletions dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ websocketpp:
libevse-security:
git: https://github.com/EVerest/libevse-security.git
git_tag: v0.3.0
libwebsockets:
git: https://github.com/warmcat/libwebsockets.git
git_tag: v4.3.3

1 change: 1 addition & 0 deletions include/ocpp/common/websocket/websocket_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct WebsocketConnectionOptions {
std::optional<bool> additional_root_certificate_check;
std::optional<std::string> hostName;
bool verify_csms_common_name;
bool use_tpm_tls;

Check notice on line 38 in include/ocpp/common/websocket/websocket_base.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

include/ocpp/common/websocket/websocket_base.hpp#L38

struct member 'WebsocketConnectionOptions::use_tpm_tls' is never used.
};

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

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

#include <queue>
namespace ocpp {

struct ConnectionData;
struct WebsocketMessage;

/// \brief Experimental libwebsockets TLS connection
class WebsocketTlsTPM final : public WebsocketBase {
public:
/// \brief Creates a new Websocket object with the providede \p connection_options
explicit WebsocketTlsTPM(const WebsocketConnectionOptions& connection_options,
std::shared_ptr<EvseSecurity> evse_security);

~WebsocketTlsTPM();

void set_connection_options(const WebsocketConnectionOptions& connection_options) override;

/// \brief connect to a TLS websocket
/// \returns true if the websocket is initialized and a connection attempt is made
bool connect() override;

/// \brief Reconnects the websocket using the delay, a reason for this reconnect can be provided with the
/// \param reason parameter
/// \param delay delay of the reconnect attempt
void reconnect(std::error_code reason, long delay) override;

/// \brief closes the websocket
void close(websocketpp::close::status::value code, const std::string& reason) override;

/// \brief send a \p message over the websocket
/// \returns true if the message was sent successfully
bool send(const std::string& message) override;

/// \brief send a websocket ping
void ping() override;

public:
int process_callback(void* wsi_ptr, int callback_reason, void* user, void* in, size_t len);

private:
void tls_init();
void client_loop();
void recv_loop();

/// \brief Called when a TLS websocket connection is established, calls the connected callback
void on_conn_connected();

/// \brief Called when a TLS websocket connection is closed
void on_conn_close();

/// \brief Called when a TLS websocket connection fails to be established
void on_conn_fail();

/// \brief When the connection can send data
void on_writable();

/// \brief Called when a message is received over the TLS websocket, calls the message callback
void on_message(void* msg, size_t len);

void request_write();

void poll_message(const std::shared_ptr<WebsocketMessage>& msg, bool wait_sendaf);

private:
std::shared_ptr<EvseSecurity> evse_security;

// Connection related data
std::unique_ptr<Everest::SteadyTimer> reconnect_timer_tpm;
std::unique_ptr<std::thread> websocket_thread;
std::shared_ptr<ConnectionData> conn_data;
std::condition_variable conn_cv;

std::mutex queue_mutex;
std::queue<std::shared_ptr<WebsocketMessage>> message_queue;

Check notice on line 82 in include/ocpp/common/websocket/websocket_tls_tpm.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

include/ocpp/common/websocket/websocket_tls_tpm.hpp#L82

class member 'WebsocketTlsTPM::message_queue' is never used.
std::condition_variable msg_send_cv;

std::unique_ptr<std::thread> recv_message_thread;
std::mutex recv_mutex;
std::queue<std::string> recv_message_queue;

Check notice on line 87 in include/ocpp/common/websocket/websocket_tls_tpm.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

include/ocpp/common/websocket/websocket_tls_tpm.hpp#L87

class member 'WebsocketTlsTPM::recv_message_queue' is never used.
std::condition_variable recv_message_cv;
};

} // namespace ocpp
#endif // OCPP_WEBSOCKET_HPP
8 changes: 8 additions & 0 deletions include/ocpp/common/websocket/websocket_uri.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ class Uri {
return this->chargepoint_id;
}

std::string get_path() {
return this->path_without_chargepoint_id;
}

uint16_t get_port() {
return this->port;
}

std::string string() {
auto uri = get_websocketpp_uri();
return uri.str();
Expand Down
1 change: 1 addition & 0 deletions include/ocpp/v16/charge_point_configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class ChargePointConfiguration {
KeyValue getUseSslDefaultVerifyPathsKeyValue();
bool getVerifyCsmsCommonName();
KeyValue getVerifyCsmsCommonNameKeyValue();
bool getUseTPM();

int32_t getRetryBackoffRandomRange();
void setRetryBackoffRandomRange(int32_t retry_backoff_random_range);
Expand Down
13 changes: 13 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ add_subdirectory(ocpp/v16/messages)
add_subdirectory(ocpp/v201/messages)

option(LIBOCPP_USE_BOOST_FILESYSTEM "Usage of boost/filesystem.hpp instead of std::filesystem" OFF)
option(LIBOCPP_ENABLE_LIBWEBSOCKETS "Usage of libwebsockets instead of websockets++" OFF)

target_include_directories(ocpp
PUBLIC
Expand Down Expand Up @@ -103,6 +104,18 @@ target_link_libraries(ocpp
date::date-tz
)

if(LIBOCPP_ENABLE_LIBWEBSOCKETS)
find_package(libwebsockets REQUIRED)
target_link_libraries(ocpp
PUBLIC
websockets
)
target_compile_definitions(log
PRIVATE
LIBOCPP_ENABLE_LIBWEBSOCKETS
)
endif()

if(LIBOCPP_USE_BOOST_FILESYSTEM)
find_package(Boost REQUIRED COMPONENTS filesystem)
target_link_libraries(ocpp
Expand Down
7 changes: 7 additions & 0 deletions lib/ocpp/common/websocket/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ target_sources(ocpp
websocket_tls.cpp
websocket.cpp
)

if(LIBOCPP_ENABLE_LIBWEBSOCKETS)
target_sources(ocpp
PRIVATE
websocket_tls_tpm.cpp
)
endif()
9 changes: 9 additions & 0 deletions lib/ocpp/common/websocket/websocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <ocpp/common/websocket/websocket.hpp>
#include <ocpp/v16/types.hpp>

#ifdef LIBOCPP_ENABLE_LIBWEBSOCKETS
#include <ocpp/common/websocket/websocket_tls_tpm.hpp>
#endif

#include <boost/algorithm/string.hpp>

using json = nlohmann::json;
Expand All @@ -14,11 +18,16 @@ namespace ocpp {
Websocket::Websocket(const WebsocketConnectionOptions& connection_options, std::shared_ptr<EvseSecurity> evse_security,
std::shared_ptr<MessageLogging> logging) :
logging(logging) {

#ifdef LIBOCPP_ENABLE_LIBWEBSOCKETS
this->websocket = std::make_unique<WebsocketTlsTPM>(connection_options, evse_security);
#else
if (connection_options.security_profile <= 1) {
this->websocket = std::make_unique<WebsocketPlain>(connection_options);
} else if (connection_options.security_profile >= 2) {
this->websocket = std::make_unique<WebsocketTLS>(connection_options, evse_security);
}
#endif
}

Websocket::~Websocket() {
Expand Down
Loading

0 comments on commit cbb2cf1

Please sign in to comment.