Files
Eric F d398a6ced2 Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1)
- OpenOCPP extracted (firmware OCPP 1.6J/2.0.1)
- ShapeShifter library installed (pip install -e)
- ShapeShifter specification extracted
- EVerest extracted

TODO updated with progress
2026-06-08 00:38:27 -04:00

175 lines
5.5 KiB
C++

// SPDX-License-Identifier: Apache-2.0
// Copyright 2024 Pionix GmbH and Contributors to EVerest
#ifndef EXTENSIONS_HELPERS_
#define EXTENSIONS_HELPERS_
#include <cstdint>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <string>
#ifdef UNIT_TEST
#include <iostream>
#endif
#include <everest/tls/openssl_util.hpp>
namespace tls {
using openssl::log_warning;
/**
* \brief update position and remaining by amount
* \param[inout] ptr the pointer to increment
* \param[inout] remaining the value to decrement
*/
constexpr void update_position(const std::uint8_t*& ptr, std::int32_t& remaining, std::size_t amount) {
ptr += amount;
remaining -= amount;
}
/**
* \brief update position and remaining by amount
* \param[inout] ptr the pointer to increment
* \param[inout] remaining the value to decrement
*/
constexpr void update_position(std::uint8_t*& ptr, std::int32_t& remaining, std::size_t amount) {
ptr += amount;
remaining -= amount;
}
/**
* \brief copy structure from data pointer
* \param[out] dest the destination structure
* \param[inout] ptr the pointer the start of the data, updated to point to the
* next byte (ptr += sizeof(dest))
* \param[inout] remaining updated with the remaining number of bytes
* (remaining -= sizeof(dest))
* \param[in] err_message to log on error
* \return true when structure populated from data
*/
template <typename T>
constexpr bool struct_copy(T& dest, const std::uint8_t*& ptr, std::int32_t& remaining, const std::string& err_message) {
bool bResult{false};
if (remaining < sizeof(T)) {
log_warning(err_message);
} else {
std::memcpy(&dest, ptr, sizeof(T));
update_position(ptr, remaining, sizeof(T));
bResult = true;
}
return bResult;
}
/**
* \brief copy structure to data pointer
* \param[out] ptr the destination pointer, updated to point to the
* next byte (ptr += sizeof(src))
* \param[inout] src the source structure
* \param[inout] remaining updated with the remaining number of bytes
* (remaining -= sizeof(src))
* \param[in] err_message to log on error
* \return true when ptr populated from structure
*/
template <typename T>
constexpr bool struct_copy(std::uint8_t*& ptr, const T& src, std::int32_t& remaining, const std::string& err_message) {
bool bResult{false};
if (remaining < sizeof(T)) {
log_warning(err_message);
} else {
std::memcpy(ptr, &src, sizeof(T));
update_position(ptr, remaining, sizeof(T));
bResult = true;
}
return bResult;
}
/**
* \brief copy DER to data pointer
* \param[out] ptr the destination pointer, updated to point to the
* next byte (ptr += src.size())
* \param[inout] src the DER source object
* \param[inout] remaining updated with the remaining number of bytes
* (remaining -= src.size())
* \param[in] err_message to log on error
* \return true when ptr populated from structure
*/
inline bool der_copy(std::uint8_t*& ptr, const openssl::DER& src, std::int32_t& remaining,
const std::string& err_message) {
bool bResult{false};
if (remaining < src.size()) {
log_warning(err_message + ' ' + std::to_string(remaining) + '/' + std::to_string(src.size()));
} else {
std::memcpy(ptr, src.get(), src.size());
update_position(ptr, remaining, src.size());
bResult = true;
}
return bResult;
}
/**
* \brief convert a big endian 3 byte (24 bit) unsigned value to uint32
* \param[in] ptr the pointer to the most significant byte
* \return the interpreted value
*/
constexpr std::uint32_t uint24(const std::uint8_t* ptr) {
return (static_cast<std::uint32_t>(ptr[0]) << 16U) | (static_cast<std::uint32_t>(ptr[1]) << 8U) |
static_cast<std::uint32_t>(ptr[2]);
}
/**
* \brief convert a uint32 to big endian 3 byte (24 bit) value
* \param[in] ptr the pointer to the most significant byte
* \param[in] value the 24 bit value
*/
constexpr void uint24(std::uint8_t* ptr, std::uint32_t value) {
ptr[0] = (value >> 16U) & 0xffU;
ptr[1] = (value >> 8U) & 0xffU;
ptr[2] = value & 0xffU;
}
/**
* \brief convert a big endian 2 byte (16 bit) unsigned value to uint16
* \param[in] ptr the pointer to the most significant byte
* \return the interpreted value
*/
constexpr std::uint16_t uint16(const std::uint8_t* ptr) {
return (static_cast<std::uint32_t>(ptr[0]) << 8U) | static_cast<std::uint32_t>(ptr[1]);
}
/**
* \brief convert a uint16 to big endian 2 byte (16 bit) value
* \param[in] ptr the pointer to the most significant byte
* \param[in] value the 16 bit value
*/
constexpr void uint16(std::uint8_t* ptr, std::uint32_t value) {
ptr[0] = (value >> 8U) & 0xffU;
ptr[1] = value & 0xffU;
}
template <typename T> std::string to_string(const T& digest) {
std::stringstream string_stream;
string_stream << std::hex;
for (const auto& c : digest) {
string_stream << std::setw(2) << std::setfill('0') << static_cast<int>(c);
}
return string_stream.str();
}
} // namespace tls
#ifdef UNIT_TEST
namespace tls::trusted_ca_keys {
struct trusted_ca_keys_t;
}
std::ostream& operator<<(std::ostream& out, const openssl::certificate_ptr& obj);
std::ostream& operator<<(std::ostream& out, const openssl::sha_1_digest_t& obj);
std::ostream& operator<<(std::ostream& out, const tls::trusted_ca_keys::trusted_ca_keys_t& obj);
std::ostream& operator<<(std::ostream& out, const openssl::DER& obj);
#endif
#endif // EXTENSIONS_HELPERS_