Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## [Unreleased]

### Added

- Operation GetInstalledCertificateIds, UC M03 ([#262](https://github.com/matth-x/MicroOcpp/pull/262))
- Operation DeleteCertificate, UC M04 ([#262](https://github.com/matth-x/MicroOcpp/pull/262))
- Operation InstallCertificate, UC M05 ([#262](https://github.com/matth-x/MicroOcpp/pull/262))

## [1.1.0] - 2024-02-27

### Fixed

- Allow `nullptr` as parameter for `mocpp_set_console_out` ([#224](https://github.com/matth-x/MicroOcpp/issues/224))
Expand Down
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

cmake_minimum_required(VERSION 3.15)

set(CMAKE_CXX_STANDARD 11)

set(MO_SRC
src/MicroOcpp/Core/Configuration.cpp
Expand All @@ -30,11 +31,13 @@ set(MO_SRC
src/MicroOcpp/Operations/ClearChargingProfile.cpp
src/MicroOcpp/Operations/CustomOperation.cpp
src/MicroOcpp/Operations/DataTransfer.cpp
src/MicroOcpp/Operations/DeleteCertificate.cpp
src/MicroOcpp/Operations/DiagnosticsStatusNotification.cpp
src/MicroOcpp/Operations/FirmwareStatusNotification.cpp
src/MicroOcpp/Operations/GetCompositeSchedule.cpp
src/MicroOcpp/Operations/GetConfiguration.cpp
src/MicroOcpp/Operations/GetDiagnostics.cpp
src/MicroOcpp/Operations/GetInstalledCertificateIds.cpp
src/MicroOcpp/Operations/GetLocalListVersion.cpp
src/MicroOcpp/Operations/Heartbeat.cpp
src/MicroOcpp/Operations/MeterValues.cpp
Expand All @@ -48,6 +51,7 @@ set(MO_SRC
src/MicroOcpp/Operations/StatusNotification.cpp
src/MicroOcpp/Operations/StopTransaction.cpp
src/MicroOcpp/Operations/TriggerMessage.cpp
src/MicroOcpp/Operations/InstallCertificate.cpp
src/MicroOcpp/Operations/UnlockConnector.cpp
src/MicroOcpp/Operations/UpdateFirmware.cpp
src/MicroOcpp/Platform.cpp
Expand All @@ -57,6 +61,10 @@ set(MO_SRC
src/MicroOcpp/Model/Authorization/AuthorizationList.cpp
src/MicroOcpp/Model/Authorization/AuthorizationService.cpp
src/MicroOcpp/Model/Boot/BootService.cpp
src/MicroOcpp/Model/Certificates/Certificate.cpp
src/MicroOcpp/Model/Certificates/Certificate_c.cpp
src/MicroOcpp/Model/Certificates/CertificateMbedTLS.cpp
src/MicroOcpp/Model/Certificates/CertificateService.cpp
src/MicroOcpp/Model/ConnectorBase/ConnectorsCommon.cpp
src/MicroOcpp/Model/ConnectorBase/Connector.cpp
src/MicroOcpp/Model/ConnectorBase/Notification.cpp
Expand Down Expand Up @@ -127,6 +135,7 @@ set(MO_SRC_UNIT
tests/Configuration.cpp
tests/Reservation.cpp
tests/LocalAuthList.cpp
#tests/Certificates.cpp # add if MbedTLS is available
)

add_executable(mo_unit_tests
Expand All @@ -135,6 +144,14 @@ add_executable(mo_unit_tests
./tests/catch2/catchMain.cpp
)

# add MbedTLS for testing (TODO integrate properly into build system)
#add_subdirectory(lib/mbedtls)
#target_link_libraries(mo_unit_tests PUBLIC
# mbedtls
# mbedcrypto
# mbedx509
#)

target_include_directories(mo_unit_tests PUBLIC
"./tests/catch2"
"./tests/helpers"
Expand All @@ -153,6 +170,7 @@ target_compile_definitions(mo_unit_tests PUBLIC
MO_FILENAME_PREFIX="./mo_store/"
MO_LocalAuthListMaxLength=8
MO_SendLocalListMaxLength=4
#MO_ENABLE_MBEDTLS=1
)

target_compile_options(mo_unit_tests PUBLIC
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ If compiled with the Arduino integration:

- [Links2004/arduinoWebSockets](https://github.com/Links2004/arduinoWebSockets) (version `2.4.1`)

If using the built-in certificate store (to enable, set build flag `MO_ENABLE_MBEDTLS=1`):

- [Mbed-TLS/mbedtls](https://github.com/Mbed-TLS/mbedtls) (version `2.28.1`)

In case you use PlatformIO, you can copy all dependencies from `platformio.ini` into your own configuration file. Alternatively, you can install the full library with dependencies by adding `matth-x/MicroOcpp@1.0.0` in the PIO library manager.

## OCPP 2.0.1 and ISO 15118
Expand Down
19 changes: 18 additions & 1 deletion src/MicroOcpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include <MicroOcpp/Model/Reservation/ReservationService.h>
#include <MicroOcpp/Model/Boot/BootService.h>
#include <MicroOcpp/Model/Reset/ResetService.h>
#include <MicroOcpp/Model/Certificates/CertificateService.h>
#include <MicroOcpp/Model/Certificates/CertificateMbedTLS.h> //default CertStore implementation depends on MbedTLS
#include <MicroOcpp/Core/SimpleRequestFactory.h>
#include <MicroOcpp/Core/OperationRegistry.h>
#include <MicroOcpp/Core/FilesystemAdapter.h>
Expand Down Expand Up @@ -199,7 +201,7 @@ ChargerCredentials::ChargerCredentials(const char *cpModel, const char *cpVendor
}
}

void mocpp_initialize(Connection& connection, const char *bootNotificationCredentials, std::shared_ptr<FilesystemAdapter> fs, bool autoRecover) {
void mocpp_initialize(Connection& connection, const char *bootNotificationCredentials, std::shared_ptr<FilesystemAdapter> fs, bool autoRecover, std::unique_ptr<CertificateStore> certStore) {
if (context) {
MO_DBG_WARN("already initialized. To reinit, call mocpp_deinitialize() before");
return;
Expand Down Expand Up @@ -257,6 +259,21 @@ void mocpp_initialize(Connection& connection, const char *bootNotificationCreden
model.setResetService(std::unique_ptr<ResetService>(
new ResetService(*context)));

std::unique_ptr<CertificateStore> certStoreUse;
if (certStore) {
certStoreUse = std::move(certStore);
}
#if MO_ENABLE_MBEDTLS
else {
certStoreUse = makeCertificateStoreMbedTLS(filesystem);
}
#endif

if (certStoreUse) {
model.setCertificateService(std::unique_ptr<CertificateService>(
new CertificateService(*context, std::move(certStoreUse))));
}

#if !defined(MO_CUSTOM_UPDATER) && !defined(MO_CUSTOM_WS)
model.setFirmwareService(std::unique_ptr<FirmwareService>(
EspWiFi::makeFirmwareService(*context))); //instantiate FW service + ESP installation routine
Expand Down
4 changes: 3 additions & 1 deletion src/MicroOcpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <MicroOcpp/Model/Transactions/Transaction.h>
#include <MicroOcpp/Model/ConnectorBase/Notification.h>
#include <MicroOcpp/Model/ConnectorBase/ChargePointErrorData.h>
#include <MicroOcpp/Model/Certificates/Certificate.h>

using MicroOcpp::OnReceiveConfListener;
using MicroOcpp::OnReceiveReqListener;
Expand Down Expand Up @@ -93,7 +94,8 @@ void mocpp_initialize(
const char *bootNotificationCredentials = ChargerCredentials("Demo Charger", "My Company Ltd."), //e.g. '{"chargePointModel":"Demo Charger","chargePointVendor":"My Company Ltd."}' (refer to OCPP 1.6 Specification - Edition 2 p. 60)
std::shared_ptr<MicroOcpp::FilesystemAdapter> filesystem =
MicroOcpp::makeDefaultFilesystemAdapter(MicroOcpp::FilesystemOpt::Use_Mount_FormatOnFail), //If this library should format the flash if necessary. Find further options in ConfigurationOptions.h
bool autoRecover = false); //automatically sanitize the local data store when the lib detects recurring crashes. Not recommended during development
bool autoRecover = false, //automatically sanitize the local data store when the lib detects recurring crashes. Not recommended during development
std::unique_ptr<MicroOcpp::CertificateStore> certStore = nullptr); //optionally use custom Cert Store (default depends on MbedTLS)

/*
* Stop the OCPP library and release allocated resources.
Expand Down
40 changes: 40 additions & 0 deletions src/MicroOcpp/Model/Certificates/Certificate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <MicroOcpp/Model/Certificates/Certificate.h>

#include <string.h>

#include <MicroOcpp/Debug.h>

using namespace MicroOcpp;

const char *CertificateHash::getHashAlgorithmCStr() {
switch(hashAlgorithm) {
case HashAlgorithmEnumType::SHA256:
return "SHA256";
case HashAlgorithmEnumType::SHA384:
return "SHA384";
case HashAlgorithmEnumType::SHA512:
return "SHA512";
}

MO_DBG_ERR("internal error");
return "";
}

const char *CertificateHash::getIssuerNameHash() {
return issuerNameHash;
}

const char *CertificateHash::getIssuerKeyHash() {
return issuerKeyHash;
}

const char *CertificateHash::getSerialNumber() {
return serialNumber;
}

bool CertificateHash::equals(const CertificateHash& other) {
return hashAlgorithm == other.hashAlgorithm &&
!strncmp(serialNumber, other.serialNumber, sizeof(serialNumber)) &&
!strncmp(issuerNameHash, other.issuerNameHash, sizeof(issuerNameHash)) &&
!strncmp(issuerKeyHash, other.issuerKeyHash, sizeof(issuerKeyHash));
}
105 changes: 105 additions & 0 deletions src/MicroOcpp/Model/Certificates/Certificate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#ifndef MO_CERTIFICATE_H
#define MO_CERTIFICATE_H

#include <vector>
#include <stdint.h>

namespace MicroOcpp {

#define MO_MAX_CERT_SIZE 5500 //limit of field `certificate` in InstallCertificateRequest, not counting terminating '\0'. See OCPP 2.0.1 part 2 Data Type 1.30.1

/*
* See OCPP 2.0.1 part 2 Data Type 3.36
*/
enum class GetCertificateIdType : uint8_t {
V2GRootCertificate,
MORootCertificate,
CSMSRootCertificate,
V2GCertificateChain,
ManufacturerRootCertificate
};

/*
* See OCPP 2.0.1 part 2 Data Type 3.40
*/
enum class GetInstalledCertificateStatus : uint8_t {
Accepted,
NotFound
};

/*
* See OCPP 2.0.1 part 2 Data Type 3.45
*/
enum class InstallCertificateType : uint8_t {
V2GRootCertificate,
MORootCertificate,
CSMSRootCertificate,
ManufacturerRootCertificate
};

/*
* See OCPP 2.0.1 part 2 Data Type 3.28
*/
enum class InstallCertificateStatus : uint8_t {
Accepted,
Rejected,
Failed
};

/*
* See OCPP 2.0.1 part 2 Data Type 3.28
*/
enum class DeleteCertificateStatus : uint8_t {
Accepted,
Failed,
NotFound
};

/*
* See OCPP 2.0.1 part 2 Data Type 3.42
*/
enum class HashAlgorithmEnumType : uint8_t {
SHA256,
SHA384,
SHA512
};

/*
* See OCPP 2.0.1 part 2 Data Type 2.6
*/
struct CertificateHash {
HashAlgorithmEnumType hashAlgorithm;
char issuerNameHash [128 + 1];
char issuerKeyHash [128 + 1];
char serialNumber [40 + 1];

const char *getHashAlgorithmCStr();
const char *getIssuerNameHash();
const char *getIssuerKeyHash();
const char *getSerialNumber();

bool equals(const CertificateHash& other);
};

/*
* See OCPP 2.0.1 part 2 Data Type 2.5
*/
struct CertificateChainHash {
GetCertificateIdType certificateType;
CertificateHash certificateHashData;
std::vector<CertificateHash> childCertificateHashData;
};

/*
* Interface which allows MicroOcpp to interact with the certificates managed by the local TLS library
*/
class CertificateStore {
public:
virtual GetInstalledCertificateStatus getCertificateIds(GetCertificateIdType certificateType, std::vector<CertificateChainHash>& out) = 0;
virtual DeleteCertificateStatus deleteCertificate(const CertificateHash& hash) = 0;
virtual InstallCertificateStatus installCertificate(InstallCertificateType certificateType, const char *certificate) = 0;
};

} //namespace MicroOcpp

#endif
Loading