Skip to content

Commit 3b3d6a3

Browse files
committed
[charge point] Add implementation of SignedUpdateFirmware and SignedFirmwareStatusNotification
1 parent d258e0e commit 3b3d6a3

File tree

12 files changed

+443
-25
lines changed

12 files changed

+443
-25
lines changed

examples/common/DefaultChargePointEventsHandler.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,45 @@ bool DefaultChargePointEventsHandler::hasChargePointCertificateInstalled()
629629
return false;
630630
}
631631

632+
/** @copydoc ocpp::types::UpdateFirmwareStatusEnumType IChargePointEventsHandler::checkFirmwareSigningCertificate(
633+
* const ocpp::x509::Certificate&) */
634+
ocpp::types::UpdateFirmwareStatusEnumType DefaultChargePointEventsHandler::checkFirmwareSigningCertificate(
635+
const ocpp::x509::Certificate& signing_certificate)
636+
{
637+
UpdateFirmwareStatusEnumType ret = UpdateFirmwareStatusEnumType::InvalidCertificate;
638+
639+
cout << "Check of firmware signing certificate requested : subject = " << signing_certificate.subjectString()
640+
<< " - issuer = " << signing_certificate.issuerString() << endl;
641+
642+
// Load all installed Manufacturer CA certificates
643+
std::vector<Certificate> ca_certificates;
644+
for (auto const& dir_entry : std::filesystem::directory_iterator{m_working_dir})
645+
{
646+
if (!dir_entry.is_directory())
647+
{
648+
std::string filename = dir_entry.path().filename();
649+
if (ocpp::helpers::startsWith(filename, "fw_") && ocpp::helpers::endsWith(filename, ".pem"))
650+
{
651+
ca_certificates.emplace_back(dir_entry.path());
652+
}
653+
}
654+
}
655+
if (!ca_certificates.empty())
656+
{
657+
// Check signing certificate
658+
if (signing_certificate.verify(ca_certificates))
659+
{
660+
ret = UpdateFirmwareStatusEnumType::Accepted;
661+
}
662+
}
663+
else
664+
{
665+
cout << "No manufacturer CA installed" << endl;
666+
}
667+
668+
return ret;
669+
}
670+
632671
/** @brief Get the number of installed CA certificates */
633672
unsigned int DefaultChargePointEventsHandler::getNumberOfCaCertificateInstalled(bool manufacturer, bool central_system)
634673
{

examples/common/DefaultChargePointEventsHandler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ class DefaultChargePointEventsHandler : public ocpp::chargepoint::IChargePointEv
158158
/** @copydoc bool IChargePointEventsHandler::hasChargePointCertificateInstalled() */
159159
bool hasChargePointCertificateInstalled() override;
160160

161+
/** @copydoc ocpp::types::UpdateFirmwareStatusEnumType IChargePointEventsHandler::checkFirmwareSigningCertificate(
162+
* const ocpp::x509::Certificate&) */
163+
ocpp::types::UpdateFirmwareStatusEnumType checkFirmwareSigningCertificate(const ocpp::x509::Certificate& signing_certificate) override;
164+
161165
// API
162166

163167
/** @brief Indicate a pending remote start transaction */

src/chargepoint/ChargePoint.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ bool ChargePoint::start()
291291
m_data_transfer_manager =
292292
std::make_unique<DataTransferManager>(m_events_handler, m_messages_converter, *m_msg_dispatcher, *m_msg_sender);
293293
m_maintenance_manager = std::make_unique<MaintenanceManager>(m_stack_config,
294+
m_internal_config,
294295
m_events_handler,
295296
*m_worker_pool.get(),
296297
m_messages_converter,
@@ -645,19 +646,19 @@ bool ChargePoint::notifyFirmwareUpdateStatus(bool success)
645646

646647
// Security extensions
647648

648-
/** @copydoc bool IChargePoint::logSecurityEvent::logSecurityEvent(const std::string&, const std::string&, bool) */
649+
/** @copydoc bool IChargePoint::logSecurityEvent(const std::string&, const std::string&, bool) */
649650
bool ChargePoint::logSecurityEvent(const std::string& type, const std::string& message, bool critical)
650651
{
651652
return m_security_manager.logSecurityEvent(type, message, critical);
652653
}
653654

654-
/** @copydoc bool IChargePoint::ISecurityManager::clearSecurityEvents() */
655+
/** @copydoc bool IChargePoint::clearSecurityEvents() */
655656
bool ChargePoint::clearSecurityEvents()
656657
{
657658
return m_security_manager.clearSecurityEvents();
658659
}
659660

660-
/** @copydoc bool IChargePoint::ISecurityManager::signCertificate(const ocpp::x509::CertificateRequest&) */
661+
/** @copydoc bool IChargePoint::signCertificate(const ocpp::x509::CertificateRequest&) */
661662
bool ChargePoint::signCertificate(const ocpp::x509::CertificateRequest& csr)
662663
{
663664
bool ret = false;
@@ -688,7 +689,7 @@ bool ChargePoint::signCertificate(const ocpp::x509::CertificateRequest& csr)
688689
return ret;
689690
}
690691

691-
/** @copydoc bool IChargePoint::ISecurityManager::signCertificate() */
692+
/** @copydoc bool IChargePoint::signCertificate() */
692693
bool ChargePoint::signCertificate()
693694
{
694695
bool ret = false;
@@ -719,6 +720,30 @@ bool ChargePoint::signCertificate()
719720
return ret;
720721
}
721722

723+
/** @copydoc bool IChargePoint::notifySignedFirmwareUpdateStatus(ocpp::types::FirmwareStatusEnumType) */
724+
bool ChargePoint::notifySignedFirmwareUpdateStatus(ocpp::types::FirmwareStatusEnumType status)
725+
{
726+
bool ret = false;
727+
728+
if (m_status_manager)
729+
{
730+
if (m_status_manager->getRegistrationStatus() != RegistrationStatus::Rejected)
731+
{
732+
ret = m_maintenance_manager->notifySignedFirmwareUpdateStatus(status);
733+
}
734+
else
735+
{
736+
LOG_ERROR << "Charge Point has not been accepted by Central System";
737+
}
738+
}
739+
else
740+
{
741+
LOG_ERROR << "Stack is not started";
742+
}
743+
744+
return ret;
745+
}
746+
722747
/** @copydoc void RpcClient::IListener::rpcClientConnected() */
723748
void ChargePoint::rpcClientConnected()
724749
{
@@ -994,7 +1019,7 @@ bool ChargePoint::doConnect()
9941019
else
9951020
{
9961021
// Use internal certificates
997-
credentials.server_certificate_ca = m_security_manager.getCentralSystemCaCertificates();
1022+
credentials.server_certificate_ca = m_security_manager.getCaCertificates(CertificateUseEnumType::CentralSystemRootCertificate);
9981023
if (security_profile == 3)
9991024
{
10001025
std::string encrypted_private_key;

src/chargepoint/ChargePoint.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,18 +159,21 @@ class ChargePoint : public IChargePoint,
159159

160160
// Security extensions
161161

162-
/** @copydoc bool IChargePoint::logSecurityEvent::logSecurityEvent(const std::string&, const std::string&, bool) */
162+
/** @copydoc bool IChargePoint::logSecurityEvent(const std::string&, const std::string&, bool) */
163163
bool logSecurityEvent(const std::string& type, const std::string& message, bool critical) override;
164164

165-
/** @copydoc bool IChargePoint::ISecurityManager::clearSecurityEvents() */
165+
/** @copydoc bool IChargePoint::clearSecurityEvents() */
166166
bool clearSecurityEvents() override;
167167

168-
/** @copydoc bool IChargePoint::ISecurityManager::signCertificate(const ocpp::x509::CertificateRequest&) */
168+
/** @copydoc bool IChargePoint::signCertificate(const ocpp::x509::CertificateRequest&) */
169169
bool signCertificate(const ocpp::x509::CertificateRequest& csr) override;
170170

171-
/** @copydoc bool IChargePoint::ISecurityManager::signCertificate() */
171+
/** @copydoc bool IChargePoint::signCertificate() */
172172
bool signCertificate() override;
173173

174+
/** @copydoc bool IChargePoint::notifySignedFirmwareUpdateStatus(ocpp::types::FirmwareStatusEnumType) */
175+
bool notifySignedFirmwareUpdateStatus(ocpp::types::FirmwareStatusEnumType status) override;
176+
174177
// RpcClient::IListener interface
175178

176179
/** @copydoc void RpcClient::IListener::rpcClientConnected() */

src/chargepoint/config/InternalConfigKeys.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ static constexpr const char* LAST_CONNECTION_URL_KEY = "LastConnectionUrl";
4242
static constexpr const char* LAST_REGISTRATION_STATUS_KEY = "LastRegistrationStatus";
4343
/** @brief Configuration key : local list version */
4444
static constexpr const char* LOCAL_LIST_VERSION_KEY = "LocalListVersion";
45+
/** @brief Configuration key : signed firmware update request id */
46+
static constexpr const char* SIGNED_FW_UPDATE_ID_KEY = "SignedFirmwareUpdateId";
4547

4648
} // namespace chargepoint
4749
} // namespace ocpp

src/chargepoint/interface/IChargePoint.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,13 @@ class IChargePoint
246246
* @return true if the request has been sent and accepted, false otherwise
247247
*/
248248
virtual bool signCertificate() = 0;
249+
250+
/**
251+
* @brief Notify the end of a signed firmware update operation
252+
* @param status Installation status (see FirmwareStatusEnumType documentation)
253+
* @return true if the notification has been sent, false otherwise
254+
*/
255+
virtual bool notifySignedFirmwareUpdateStatus(ocpp::types::FirmwareStatusEnumType status) = 0;
249256
};
250257

251258
} // namespace chargepoint

src/chargepoint/interface/IChargePointEventsHandler.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,15 @@ class IChargePointEventsHandler
268268
* @return true if at least 1 certificate has been installed, false otherwise
269269
*/
270270
virtual bool hasChargePointCertificateInstalled() = 0;
271+
272+
/**
273+
* @brief Called to check the firmware signing certificate against installed Manufacturer CA certificates
274+
* (Not used if InternalCertificateManagementEnabled = true)
275+
* @param signing_certificate Certificate to check
276+
* @return Check status (see UpdateFirmwareStatusEnumType enum)
277+
*/
278+
virtual ocpp::types::UpdateFirmwareStatusEnumType checkFirmwareSigningCertificate(
279+
const ocpp::x509::Certificate& signing_certificate) = 0;
271280
};
272281

273282
} // namespace chargepoint

0 commit comments

Comments
 (0)