Skip to content

Commit 16324be

Browse files
authored
Merge pull request #45 from c-jimenez/dev/security_firmware_update
Dev/security firmware update
2 parents 761a210 + 2212ac4 commit 16324be

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+2467
-237
lines changed

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ As of this version :
3939

4040
* All the messages defined in the OCPP 1.6 edition 2 protocol have been implemented except GetCompositeSchedule for Charge Point role
4141
* All the configuration keys defined in the OCPP 1.6 edition 2 protocol have been implemented for the Charge Point role
42-
* Most of Charge Point and Central System behavior related to the OCPP 1.6 security whitepaper edition 2 has been implemented (work in progress, see [OCPP security extensions](#ocpp-security-extensions))
42+
* All the messages defined in the OCPP 1.6 security whitepaper edition 2 have been implemented
4343

4444
The user application will have to implement some callbacks to provide the data needed by **Open OCPP** or to handle OCPP events (boot notification, remote start/stop notifications, meter values...).
4545

@@ -123,12 +123,13 @@ In the "Owner" column, "S" means that the configuration key behavior is handled
123123
| ChargingScheduleMaxPeriods | S | None |
124124
| ConnectorSwitch3to1PhaseSupported | S | None |
125125
| MaxChargingProfilesInstalled | S | None |
126-
| AdditionalRootCertificateCheck | U/S | Not implemented yet : implemented behavior is the same as if AdditionalRootCertificateCheck = False |
126+
| AdditionalRootCertificateCheck | U/S | If internal certificate management is enabled, the stack handle this parameter (implemented behavior for now is the always the one corresponding to AdditionalRootCertificateCheck = False), otherwise it must be the user application |
127127
| AuthorizationKey | S | None |
128128
| CertificateSignedMaxChainSize | S | None |
129129
| CertificateStoreMaxLength | U/S | If internal certificate management is enabled, the stack handle this parameter, otherwise it must be the user application |
130130
| CpoName | S | None |
131131
| SecurityProfile | S | None |
132+
| SupportedFileTransferProtocols | U | None |
132133

133134
### OCPP security extensions
134135

@@ -145,6 +146,8 @@ In Charge Point role, the stack will automatically disconnect and then reconnect
145146
* **AuthorizationKey**
146147
* **Security Profile**
147148

149+
**Restriction** : The automatic fallback to old connection parameters if the connection fails after switching to a new security is not implemented yet.
150+
148151
#### Security events
149152

150153
**Open OCPP** support the whole use cases of security events and logging.
@@ -177,6 +180,14 @@ If **InternalCertificateManagementEnabled** is set to **false**, the actual stor
177180

178181
If **InternalCertificateManagementEnabled** is set to **true**, the storage of certificates and their keys is fully handled by **Open OCPP**. The user application just has to provide a passphrase using the **TlsClientCertificatePrivateKeyPassphrase** configuration key to securily encrypt the certicates' private keys using AES-256-CBC algorithm. **Open OCPP** will automatically use the installed corresponding certificates depending on the configured Security Profile and the certificates validity dates.
179182

183+
**Restriction** : The automatic fallback to old certificate if the connection fails after installing new certificate is not implemented yet.
184+
185+
#### Signed firmware update
186+
187+
**Open OCPP** support this feature for both Charge Point and Central System roles.
188+
189+
**Open OCPP** provides helper classes based on OpenSSL to ease private keys, certificate and certificate requests usage : generation, signature, verification. They can be used in the user application callbacks. These helpers can be found in the ocpp::tools::x509 namespace and are widely used in the **Open OCPP** source code and examples.
190+
180191
### Internal configuration keys
181192

182193
The behavior and the configuration of the **Open OCPP** stack can be modified through configuration keys. Some are specific to an OCPP role and some are common.

examples/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22

33
All the examples are licensed under the MIT licence so that code can be used and modified at will without having to contribute back.
44

5-
The following examples are available :
5+
The following examples are available for OCPP 1.6 standard :
6+
67
* [Quick start Central System example](./quick_start_centralsystem/README.md)
78
* [Quick start Charge Point example](./quick_start_chargepoint/README.md)
89
* [Remote Charge Point example](./remote_chargepoint/README.md)
10+
11+
The following examples are available for OCPP 1.6 security extensions :
12+
13+
* [Security Central System example](./security_centralsystem/README.md)
914
* [Security Charge Point example](./security_chargepoint/README.md)
1015

1116
How to run the examples:
17+
1218
* Customize the *config.ini* file of the selected example with the URL of the Central System and the other connection parameters has well has the OCPP configuration keys
1319
* Run the example using the **-w** option to specify the path of the configuration file

examples/common/DefaultCentralSystemEventsHandler.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ void DefaultCentralSystemEventsHandler::ChargePointRequestHandler::securityEvent
321321
<< " - message = " << message << endl;
322322
}
323323

324-
/** @copydoc bool IChargePointRequestHandler::signCertificate(const ocpp::x509::CertificateRequest& certificate_request) */
324+
/** @copydoc bool IChargePointRequestHandler::signCertificate(const ocpp::x509::CertificateRequest&) */
325325
bool DefaultCentralSystemEventsHandler::ChargePointRequestHandler::signCertificate(
326326
const ocpp::x509::CertificateRequest& certificate_request)
327327
{
@@ -403,3 +403,13 @@ bool DefaultCentralSystemEventsHandler::ChargePointRequestHandler::signCertifica
403403
}
404404
return ret;
405405
}
406+
407+
/** @copydoc void IChargePointRequestHandler::signedFirmwareUpdateStatusNotification(ocpp::types::FirmwareStatusEnumType,
408+
const ocpp::types::Optional<int>&) */
409+
void DefaultCentralSystemEventsHandler::ChargePointRequestHandler::signedFirmwareUpdateStatusNotification(
410+
ocpp::types::FirmwareStatusEnumType status, const ocpp::types::Optional<int>& request_id)
411+
{
412+
cout << "[" << m_chargepoint->identifier()
413+
<< "] - Signed firmware update status notification : status = " << FirmwareStatusEnumTypeHelper.toString(status)
414+
<< " - request_id = " << (request_id.isSet() ? std::to_string(request_id) : "not set");
415+
}

examples/common/DefaultCentralSystemEventsHandler.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,14 @@ class DefaultCentralSystemEventsHandler : public ocpp::centralsystem::ICentralSy
169169
const ocpp::types::DateTime& timestamp,
170170
const std::string& message) override;
171171

172-
/** @copydoc bool IChargePointRequestHandler::signCertificate(const ocpp::x509::CertificateRequest& certificate_request) */
172+
/** @copydoc bool IChargePointRequestHandler::signCertificate(const ocpp::x509::CertificateRequest&) */
173173
bool signCertificate(const ocpp::x509::CertificateRequest& certificate_request) override;
174174

175+
/** @copydoc void IChargePointRequestHandler::signedFirmwareUpdateStatusNotification(ocpp::types::FirmwareStatusEnumType,
176+
const ocpp::types::Optional<int>&) */
177+
void signedFirmwareUpdateStatusNotification(ocpp::types::FirmwareStatusEnumType status,
178+
const ocpp::types::Optional<int>& request_id) override;
179+
175180
protected:
176181
/** @brief Get the serial number of the charge point */
177182
virtual std::string getChargePointSerialNumber(const std::string& chargepoint_id)

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 */

examples/common/config/OcppConfig.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ static const map<string, int> CONFIGURATION_VALUES = {
9999
{"CertificateStoreMaxLength", PARAM_READ | PARAM_OCPP},
100100
{"CpoName", PARAM_READ | PARAM_WRITE | PARAM_OCPP},
101101
{"SecurityProfile", PARAM_READ_WRITE | PARAM_OCPP},
102+
{"SupportedFileTransferProtocols", PARAM_READ | PARAM_OCPP},
102103

103104
///
104105
/// Charge point configuration

examples/common/config/OcppConfig.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ class OcppConfig : public ocpp::config::IOcppConfig
259259
Default, when no security profile is yet configured: 0. */
260260
unsigned int securityProfile() const override { return getUInt("SecurityProfile"); }
261261

262+
/** @brief Comma separated list of supported file transfer protocols for upload AND download
263+
Allowed values : FTP, FTPS, HTTP, HTTPS, SFTP */
264+
std::string supportedFileTransferProtocols() const override { return getString("SupportedFileTransferProtocols"); }
265+
262266
private:
263267
/** @brief Configuration file */
264268
ocpp::helpers::IniFile& m_config;

examples/quick_start_chargepoint/config/quick_start_chargepoint.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,4 @@ CertificateSignedMaxChainSize=10000
9191
CertificateStoreMaxLength=50
9292
CpoName=SteVe
9393
SecurityProfile=0
94+
SupportedFileTransferProtocols=FTP,FTPS,HTTP,HTTPS

examples/remote_chargepoint/config/remote_chargepoint.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,4 @@ CertificateSignedMaxChainSize=10000
9191
CertificateStoreMaxLength=50
9292
CpoName=SteVe
9393
SecurityProfile=0
94+
SupportedFileTransferProtocols=FTP,FTPS,HTTP,HTTPS

0 commit comments

Comments
 (0)