Skip to content

Commit 94a8523

Browse files
authored
Merge pull request #149 from c-jimenez/fix/base64_encode_decode
Fix base64 encode/decode + signature check during signed firmware update procedure
2 parents 3f00c0a + 65894e9 commit 94a8523

File tree

3 files changed

+44
-21
lines changed

3 files changed

+44
-21
lines changed

examples/common/DefaultChargePointEventsHandler.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,9 +691,13 @@ ocpp::types::UpdateFirmwareStatusEnumType DefaultChargePointEventsHandler::check
691691
if (!ca_certificates.empty())
692692
{
693693
// Check signing certificate
694-
if (signing_certificate.verify(ca_certificates))
694+
for (const auto& cer : ca_certificates)
695695
{
696-
ret = UpdateFirmwareStatusEnumType::Accepted;
696+
if (signing_certificate.verify(cer.certificateChain()))
697+
{
698+
ret = UpdateFirmwareStatusEnumType::Accepted;
699+
break;
700+
}
697701
}
698702
}
699703
else

src/tools/x509/Base64.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ std::string encode(const void* data, size_t size)
3535
if (data && (size != 0))
3636
{
3737
// Prepare buffer at the maximum data length
38-
b64_str.resize((4u * size) / 3u + 10u);
38+
b64_str.resize((4u * (size + 2u)) / 3u);
3939

4040
// Encode data
4141
int encoded_size = EVP_EncodeBlock(
4242
reinterpret_cast<unsigned char*>(&b64_str[0]), reinterpret_cast<const unsigned char*>(data), static_cast<int>(size));
4343
if (encoded_size >= 0)
4444
{
4545
// Resize output
46-
b64_str.resize(static_cast<unsigned int>(encoded_size));
46+
b64_str.resize(static_cast<size_t>(encoded_size));
4747
}
4848
else
4949
{
@@ -63,15 +63,23 @@ std::vector<uint8_t> decode(const std::string& b64_str)
6363
if (b64_str.size() != 0)
6464
{
6565
// Prepare buffer at the maximum data length
66-
data.resize((3u * b64_str.size()) / 4u + 10u);
66+
data.resize((3u * b64_str.size()) / 4u);
6767

6868
// Decode data
6969
int decoded_size =
7070
EVP_DecodeBlock(&data[0], reinterpret_cast<const unsigned char*>(b64_str.c_str()), static_cast<int>(b64_str.size()));
7171
if (decoded_size >= 0)
7272
{
7373
// Resize output
74-
data.resize(static_cast<unsigned int>(decoded_size));
74+
if (b64_str[b64_str.size() - 1u] == '=')
75+
{
76+
decoded_size--;
77+
}
78+
if (b64_str[b64_str.size() - 2u] == '=')
79+
{
80+
decoded_size--;
81+
}
82+
data.resize(static_cast<size_t>(decoded_size));
7583
}
7684
else
7785
{

tests/tools/test_x509.cpp

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -723,21 +723,32 @@ TEST_SUITE("Base64")
723723
{
724724
TEST_CASE("Encode/Decode nominal")
725725
{
726-
// Data to encode
727-
const std::string input_data =
728-
"This string could have been some binary data but it is way more easier to do it with human readable data instead :) !";
729-
730-
// Expected result
731-
const std::string expected_result = "VGhpcyBzdHJpbmcgY291bGQgaGF2ZSBiZWVuIHNvbWUgYmluYXJ5IGRhdGEgYnV0IGl0IGlzIHdheSBtb3JlIGVhc2llci"
732-
"B0byBkbyBpdCB3aXRoIGh1bWFuIHJlYWRhYmxlIGRhdGEgaW5zdGVhZCA6KSAh";
733-
734-
// Check encoding
735-
CHECK_EQ(ocpp::x509::base64::encode(input_data.c_str(), input_data.size()), expected_result);
736-
737-
// Check decoding
738-
std::vector<uint8_t> decoded_data = ocpp::x509::base64::decode(expected_result);
739-
std::string decoded_data_str(reinterpret_cast<char*>(&decoded_data[0]), decoded_data.size());
740-
CHECK_EQ(decoded_data_str, input_data);
726+
// input_vector1 = defghijklmnopqrssrqponmlkjihgfed
727+
// input_vector2 = FGHIJKLMNOPQRSTU
728+
// input_vector3 = 012345678901
729+
std::vector<uint8_t> input_vector1 = {100u, 101u, 102u, 103u, 104u, 105u, 106u, 107u, 108u, 109u, 110u,
730+
111u, 112u, 113u, 114u, 115u, 115u, 114u, 113u, 112u, 111u, 110u,
731+
109u, 108u, 107u, 106u, 105u, 104u, 103u, 102u, 101u, 100u};
732+
std::vector<uint8_t> input_vector2 = {70u, 71u, 72u, 73u, 74u, 75u, 76u, 77u, 78u, 79u, 80u, 81u, 82u, 83u, 84u, 85u};
733+
std::vector<uint8_t> input_vector3 = {48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 57u, 48u, 49u};
734+
735+
// Encode with 1 trailing '='
736+
auto encoded_vector1 = ocpp::x509::base64::encode(input_vector1.data(), input_vector1.size());
737+
CHECK_EQ(encoded_vector1, "ZGVmZ2hpamtsbW5vcHFyc3NycXBvbm1sa2ppaGdmZWQ=");
738+
auto decoded_vector1 = ocpp::x509::base64::decode(encoded_vector1);
739+
CHECK_EQ(decoded_vector1, input_vector1);
740+
741+
// Encode with 2 trailing '='
742+
auto encoded_vector2 = ocpp::x509::base64::encode(input_vector2.data(), input_vector2.size());
743+
CHECK_EQ(encoded_vector2, "RkdISUpLTE1OT1BRUlNUVQ==");
744+
auto decoded_vector2 = ocpp::x509::base64::decode(encoded_vector2);
745+
CHECK_EQ(decoded_vector2, input_vector2);
746+
747+
// Encode without trailing '='
748+
auto encoded_vector3 = ocpp::x509::base64::encode(input_vector3.data(), input_vector3.size());
749+
CHECK_EQ(encoded_vector3, "MDEyMzQ1Njc4OTAx");
750+
auto decoded_vector3 = ocpp::x509::base64::decode(encoded_vector3);
751+
CHECK_EQ(decoded_vector3, input_vector3);
741752
}
742753

743754
TEST_CASE("Encode/Decode limits")

0 commit comments

Comments
 (0)