Skip to content

Commit 68cd353

Browse files
committed
[chargepoint] Fix AuthorizationKey handling (store received hexadecimal string but use bytes representation on connect)
1 parent 242d700 commit 68cd353

File tree

6 files changed

+121
-16
lines changed

6 files changed

+121
-16
lines changed

.vscode/launch.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,26 @@
3838
"target": "${workspaceRoot}/build_gcc_native/tests/chargepoint/smartcharging/test_smartcharging_setpoint",
3939
"cwd": "${workspaceRoot}",
4040
"valuesFormatting": "parseText"
41+
},
42+
{
43+
"type": "cppdbg",
44+
"request": "attach",
45+
"name": "Join process",
46+
"program": "${workspaceRoot}/bin/gcc_native/quick_start_chargepoint",
47+
"processId": "${command:pickProcess}",
48+
"MIMode": "gdb",
49+
"setupCommands": [
50+
{
51+
"description": "Activer l'impression en mode Pretty pour gdb",
52+
"text": "-enable-pretty-printing",
53+
"ignoreFailures": true
54+
},
55+
{
56+
"description": "Définir la version désassemblage sur Intel",
57+
"text": "-gdb-set disassembly-flavor intel",
58+
"ignoreFailures": true
59+
}
60+
]
4161
}
4262
]
4363
}

examples/security_centralsystem/CentralSystemEventsHandler.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ SOFTWARE.
2525
#include "CentralSystemEventsHandler.h"
2626
#include "ChargePointDatabase.h"
2727

28+
#include <array>
2829
#include <iostream>
2930
#include <random>
3031
#include <sstream>
@@ -99,7 +100,8 @@ bool CentralSystemEventsHandler::checkCredentials(const std::string& chargepoint
99100
{
100101
bool ret = false;
101102

102-
cout << "Check credentials for [" << chargepoint_id << "] : " << password << endl;
103+
std::string hex_encoded_password = ocpp::helpers::toHexString(password);
104+
cout << "Check credentials for [" << chargepoint_id << "] : " << hex_encoded_password << endl;
103105

104106
// HTTP Basic Authentication is for Charge Points configured with Security Profile 1 or 2 only
105107

@@ -111,7 +113,7 @@ bool CentralSystemEventsHandler::checkCredentials(const std::string& chargepoint
111113
{
112114
if ((security_profile == 1u) || (security_profile == 2u))
113115
{
114-
ret = (password == authent_key);
116+
ret = (hex_encoded_password == authent_key);
115117
}
116118
else
117119
{
@@ -257,14 +259,18 @@ ocpp::types::RegistrationStatus CentralSystemEventsHandler::ChargePointRequestHa
257259
}
258260
else
259261
{
260-
// Generate an authent key for the charge point : minimal 16 bytes, max : 20 bytes
261-
std::stringstream ss_authent_key;
262-
ss_authent_key << std::hex;
263-
for (int i = 0; i < 5; i++)
262+
// Generate an authent key for the charge point : minimal 8 bytes, max : 20 bytes
263+
std::mt19937 rand_gen;
264+
std::uniform_int_distribution<unsigned int> rand_distrib;
265+
std::random_device rd;
266+
rand_gen.seed(rd());
267+
268+
std::array<uint8_t, 17u> authent_key_bytes;
269+
for (auto& val : authent_key_bytes)
264270
{
265-
ss_authent_key << std::setfill('0') << std::setw(4) << std::rand();
271+
val = static_cast<uint8_t>(rand_distrib(rand_gen));
266272
}
267-
m_authent_key = ss_authent_key.str();
273+
m_authent_key = ocpp::helpers::toHexString(authent_key_bytes);
268274

269275
// Add the charge point to the database
270276
m_chargepoint_db.addChargePoint(this->proxy()->identifier(), serial_number, vendor, model, 0, m_authent_key);

src/chargepoint/ChargePoint.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,8 +1164,10 @@ bool ChargePoint::doConnect()
11641164
std::string authorization_key = m_ocpp_config.authorizationKey();
11651165
if (!authorization_key.empty() && (security_profile <= 2))
11661166
{
1167-
credentials.user = m_stack_config.chargePointIdentifier();
1168-
credentials.password = authorization_key;
1167+
auto authentication_key = ocpp::helpers::fromHexString(authorization_key);
1168+
credentials.user = m_stack_config.chargePointIdentifier();
1169+
credentials.password = std::string(reinterpret_cast<const char*>(authentication_key.data()), authorization_key.size());
1170+
credentials.password.resize(authentication_key.size());
11691171
}
11701172
if (security_profile != 1)
11711173
{

src/chargepoint/security/SecurityManager.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -669,15 +669,16 @@ bool SecurityManager::handleMessage(const ocpp::messages::InstallCertificateReq&
669669
ocpp::types::ConfigurationStatus SecurityManager::checkAuthorizationKeyParameter(const std::string& key, const std::string& value)
670670
{
671671
(void)key;
672-
ConfigurationStatus ret = ConfigurationStatus::Accepted;
672+
ConfigurationStatus ret = ConfigurationStatus::Rejected;
673673

674-
// Authorization key length for security profiles 1 and 2 must be between 32 and 40 bytes
675-
unsigned int security_profile = m_ocpp_config.securityProfile();
676-
if ((security_profile == 1) || (security_profile == 2))
674+
// Authorization key length for security profiles 1 and 2 must be between 16 and 40 bytes
675+
// and must be a valid hexadecimal representation
676+
if ((value.size() >= 16u) && (value.size() <= 40u))
677677
{
678-
if ((value.size() < 32u) || (value.size() > 40u))
678+
auto key_bytes = ocpp::helpers::fromHexString(value);
679+
if (key_bytes.size() == (value.size() / 2u))
679680
{
680-
ret = ConfigurationStatus::Rejected;
681+
ret = ConfigurationStatus::Accepted;
681682
}
682683
}
683684

src/tools/helpers/StringHelpers.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ along with OpenOCPP. If not, see <http://www.gnu.org/licenses/>.
1818

1919
#include "StringHelpers.h"
2020

21+
#include <iomanip>
22+
#include <sstream>
23+
2124
namespace ocpp
2225
{
2326
namespace helpers
@@ -114,5 +117,50 @@ bool endsWith(const std::string& str, const std::string& substr)
114117
return ret;
115118
}
116119

120+
/** @brief Helper function to convert a buffer to an hexadecimal string representation */
121+
std::string toHexString(const void* buffer, size_t size)
122+
{
123+
std::stringstream ss;
124+
const uint8_t* data = reinterpret_cast<const uint8_t*>(buffer);
125+
if (data)
126+
{
127+
ss << std::hex;
128+
for (size_t i = 0; i < size; i++)
129+
{
130+
ss << std::setw(2) << std::setfill('0') << static_cast<int>(data[i]) << "";
131+
}
132+
}
133+
return ss.str();
134+
}
135+
136+
/** @brief Helper function to convert an hexadecimal string representation into an array of bytes */
137+
std::vector<uint8_t> fromHexString(const std::string& hex_string)
138+
{
139+
std::vector<uint8_t> ret;
140+
if ((hex_string.size() & 1) == 0)
141+
{
142+
try
143+
{
144+
for (size_t i = 0; i < hex_string.size(); i += 2u)
145+
{
146+
std::string ss = hex_string.substr(i, 2u);
147+
for (const auto& c : ss)
148+
{
149+
if (!((c >= '0') && (c <= '9')) && !((c >= 'a') && (c <= 'f')) && !((c >= 'A') && (c <= 'F')))
150+
{
151+
throw std::out_of_range(ss);
152+
}
153+
}
154+
ret.push_back(static_cast<uint8_t>(std::stoul(ss, nullptr, 16)));
155+
}
156+
}
157+
catch (...)
158+
{
159+
ret.clear();
160+
}
161+
}
162+
return ret;
163+
}
164+
117165
} // namespace helpers
118166
} // namespace ocpp

src/tools/helpers/StringHelpers.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ along with OpenOCPP. If not, see <http://www.gnu.org/licenses/>.
1919
#ifndef OPENOCPP_STRING_H
2020
#define OPENOCPP_STRING_H
2121

22+
#include <cstdint>
2223
#include <string>
2324
#include <vector>
25+
2426
namespace ocpp
2527
{
2628
namespace helpers
@@ -87,6 +89,32 @@ bool startsWith(const std::string& str, const std::string& substr);
8789
*/
8890
bool endsWith(const std::string& str, const std::string& substr);
8991

92+
/**
93+
* @brief Helper function to convert a buffer to an hexadecimal string representation
94+
* @param buffer Buffer to convert
95+
* @param size Size of the buffer in bytes
96+
* @return Buffer contents as an hexadecimal string
97+
*/
98+
std::string toHexString(const void* buffer, size_t size);
99+
100+
/**
101+
* @brief Helper function to convert a ContiguousContainer to an hexadecimal string representation
102+
* @param cont container to convert
103+
* @return Container contents as an hexadecimal string
104+
*/
105+
template <typename ContiguousContainer>
106+
std::string toHexString(const ContiguousContainer& cont)
107+
{
108+
return toHexString(&cont[0], cont.size() * sizeof(cont[0]));
109+
}
110+
111+
/**
112+
* @brief Helper function to convert an hexadecimal string representation into an array of bytes
113+
* @param hex_string Hexadecimal string to convert
114+
* @return Corresponding array of bytes, empty if the input string is invalid
115+
*/
116+
std::vector<uint8_t> fromHexString(const std::string& hex_string);
117+
90118
} // namespace helpers
91119
} // namespace ocpp
92120

0 commit comments

Comments
 (0)