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
This commit is contained in:
Eric F
2026-06-08 00:38:27 -04:00
parent 468cfeaa50
commit d398a6ced2
7326 changed files with 1177561 additions and 7 deletions

View File

@@ -0,0 +1,452 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2024 Pionix GmbH and Contributors to EVerest
#include "extensions/trusted_ca_keys.hpp"
#include <everest/tls/openssl_util.hpp>
#include <everest/tls/tls.hpp>
#include <gtest/gtest.h>
#include <iterator>
#include <cstring>
#include <utility>
std::string to_string(const std::uint8_t* const ptr, const std::size_t len) {
std::stringstream string_stream;
string_stream << std::hex;
for (int idx = 0; idx < len; ++idx)
string_stream << std::setw(2) << std::setfill('0') << (int)ptr[idx];
return string_stream.str();
}
std::string to_string(const tls::OcspCache::digest_t& digest) {
return to_string(reinterpret_cast<const std::uint8_t*>(&digest), sizeof(digest));
}
namespace {
TEST(strdup, usage) {
// auto* r1 = strdup(nullptr); need to ensure non-nullptr
auto* r2 = strdup("");
auto* r3 = strdup("hello");
// free(r1);
free(r2);
free(r3);
free(nullptr);
}
TEST(string, use) {
// was hoping to use std::string for config, but ...
std::string empty;
std::string space{""};
std::string value{"something"};
EXPECT_TRUE(empty.empty());
// EXPECT_FALSE(space.empty()); was hoping it would be true
EXPECT_FALSE(value.empty());
// EXPECT_EQ(empty.c_str(), nullptr); was hoping it would be nullptr
EXPECT_NE(space.c_str(), nullptr);
EXPECT_NE(value.c_str(), nullptr);
}
TEST(ConfigItem, test) {
// tests reduced with new ConfigStore implementation
tls::ConfigItem i1;
tls::ConfigItem i2{nullptr};
tls::ConfigItem i3{"Hello"};
tls::ConfigItem i4 = nullptr;
tls::ConfigItem i5(nullptr);
tls::ConfigItem i6("Hello");
EXPECT_EQ(i1, nullptr);
EXPECT_EQ(i4, nullptr);
EXPECT_EQ(i5, nullptr);
EXPECT_EQ(i2, i5);
EXPECT_STREQ(i3, i6);
EXPECT_EQ(i1, i2);
EXPECT_NE(i1, i3);
EXPECT_EQ(i1, i5);
EXPECT_NE(i1, i6);
tls::ConfigItem j2{""};
auto j1(std::move(i3));
j2 = std::move(i6);
EXPECT_STREQ(i6, i3);
EXPECT_STREQ(j1, j2);
EXPECT_STREQ(j1, "Hello");
EXPECT_NE(j1, i6);
EXPECT_NE(j1, nullptr);
EXPECT_NE(j2, nullptr);
// EXPECT_EQ(i3, nullptr);
// EXPECT_EQ(i6, nullptr);
// EXPECT_EQ(i6, i3);
std::vector<tls::ConfigItem> j3 = {"one", "two", nullptr};
EXPECT_STREQ(j3[0], "one");
EXPECT_STREQ(j3[1], "two");
EXPECT_EQ(j3[2], nullptr);
const char* p = j1;
EXPECT_STREQ(p, "Hello");
j1 = "Goodbye";
EXPECT_STRNE(j1, "Hello");
j1 = j2;
EXPECT_STREQ(j1, j2);
}
TEST(ConfigItem, testB) {
tls::ConfigItem i1;
tls::ConfigItem i2{nullptr};
tls::ConfigItem i3{""};
tls::ConfigItem i4{"Hello"};
EXPECT_EQ(i1, nullptr);
EXPECT_EQ(i2, nullptr);
EXPECT_STREQ(i3, "");
EXPECT_STREQ(i4, "Hello");
EXPECT_STREQ("Hello", i4);
}
using namespace tls::trusted_ca_keys;
using namespace openssl;
TEST(OcspCache, initEmpty) {
tls::OcspCache cache;
tls::OcspCache::digest_t digest{};
auto res = cache.lookup(digest);
EXPECT_EQ(res.get(), nullptr);
}
TEST(OcspCache, init) {
tls::OcspCache cache;
auto chain = openssl::load_certificates("client_chain.pem");
std::vector<tls::OcspCache::ocsp_entry_t> entries;
tls::OcspCache::digest_t digest{};
for (const auto& cert : chain) {
ASSERT_TRUE(tls::OcspCache::digest(digest, cert.get()));
// std::cout << "digest: " << to_string(digest) << std::endl;
entries.emplace_back(digest, "ocsp_response.der");
}
EXPECT_TRUE(cache.load(entries));
// std::cout << "digest: " << to_string(digest) << std::endl;
auto res = cache.lookup(digest);
EXPECT_NE(res.get(), nullptr);
}
TEST(TrustedCaKeys, parseAudi) {
/*
* Audi
* 0069 trusted_authorities_list length
* 03 identifier_type cert_sha1_hash d8367e861f5807f8141fea572d676dbf58bb5f7c SHA1Hash
* 03 identifier_type cert_sha1_hash b491ddd08fafe72d9f6f9bafc68eb04da84cc09a SHA1Hash
* 03 identifier_type cert_sha1_hash 30aaaab25b1cc8a09a7b32652c33cc5a973c13f3 SHA1Hash
* 03 identifier_type cert_sha1_hash 700bf78ad58e0819dac6fcaead5ed20f7bb0554f SHA1Hash
* 03 identifier_type cert_sha1_hash 8c821f41604ed4c3431cf6d19f2ae107cf1f50e1 SHA1Hash
*/
using trusted_authority = tls::trusted_ca_keys::trusted_authority;
std::uint8_t extension[] = {
0x00, 0x69, 0x03, 0xd8, 0x36, 0x7e, 0x86, 0x1f, 0x58, 0x07, 0xf8, 0x14, 0x1f, 0xea, 0x57, 0x2d, 0x67, 0x6d,
0xbf, 0x58, 0xbb, 0x5f, 0x7c, 0x03, 0xb4, 0x91, 0xdd, 0xd0, 0x8f, 0xaf, 0xe7, 0x2d, 0x9f, 0x6f, 0x9b, 0xaf,
0xc6, 0x8e, 0xb0, 0x4d, 0xa8, 0x4c, 0xc0, 0x9a, 0x03, 0x30, 0xaa, 0xaa, 0xb2, 0x5b, 0x1c, 0xc8, 0xa0, 0x9a,
0x7b, 0x32, 0x65, 0x2c, 0x33, 0xcc, 0x5a, 0x97, 0x3c, 0x13, 0xf3, 0x03, 0x70, 0x0b, 0xf7, 0x8a, 0xd5, 0x8e,
0x08, 0x19, 0xda, 0xc6, 0xfc, 0xae, 0xad, 0x5e, 0xd2, 0x0f, 0x7b, 0xb0, 0x55, 0x4f, 0x03, 0x8c, 0x82, 0x1f,
0x41, 0x60, 0x4e, 0xd4, 0xc3, 0x43, 0x1c, 0xf6, 0xd1, 0x9f, 0x2a, 0xe1, 0x07, 0xcf, 0x1f, 0x50, 0xe1,
};
trusted_authority ext{&extension[0], sizeof(extension)};
auto res = tls::trusted_ca_keys::convert(ext);
EXPECT_EQ(res.cert_sha1_hash.size(), 5);
EXPECT_EQ(res.key_sha1_hash.size(), 0);
EXPECT_EQ(res.x509_name.size(), 0);
EXPECT_FALSE(res.pre_agreed);
}
TEST(TrustedCaKeys, parseBuzz) {
/*
* Buzz
* 002a trusted_authorities_list length
* 03 identifier_type cert_sha1_hash d8367e861f5807f8141fea572d676dbf58bb5f7c SHA1Hash
* 03 identifier_type cert_sha1_hash 8c821f41604ed4c3431cf6d19f2ae107cf1f50e1 SHA1Hash
*/
using trusted_authority = tls::trusted_ca_keys::trusted_authority;
std::uint8_t extension[] = {
0x00, 0x2a, 0x03, 0xd8, 0x36, 0x7e, 0x86, 0x1f, 0x58, 0x07, 0xf8, 0x14, 0x1f, 0xea, 0x57,
0x2d, 0x67, 0x6d, 0xbf, 0x58, 0xbb, 0x5f, 0x7c, 0x03, 0x8c, 0x82, 0x1f, 0x41, 0x60, 0x4e,
0xd4, 0xc3, 0x43, 0x1c, 0xf6, 0xd1, 0x9f, 0x2a, 0xe1, 0x07, 0xcf, 0x1f, 0x50, 0xe1,
};
trusted_authority ext{&extension[0], sizeof(extension)};
auto res = tls::trusted_ca_keys::convert(ext);
EXPECT_EQ(res.cert_sha1_hash.size(), 2);
EXPECT_EQ(res.key_sha1_hash.size(), 0);
EXPECT_EQ(res.x509_name.size(), 0);
EXPECT_FALSE(res.pre_agreed);
}
TEST(TrustedCaKeys, parseIoniq6) {
/*
* Ioniq 6 (invalid missing the size of trusted_authorities_list)
* 01 identifier_type key_sha1_hash 4cd7290bf592d2c1ba90f56e08946d4c8e99dc38 SHA1Hash
* 01 identifier_type key_sha1_hash 00fae3900795c888a4d4d7bd9fdffa60418ac19f SHA1Hash
*/
using trusted_authority = tls::trusted_ca_keys::trusted_authority;
std::uint8_t extension[] = {
0x00, 0x2a, 0x01, 0x4c, 0xd7, 0x29, 0x0b, 0xf5, 0x92, 0xd2, 0xc1, 0xba, 0x90, 0xf5, 0x6e,
0x08, 0x94, 0x6d, 0x4c, 0x8e, 0x99, 0xdc, 0x38, 0x01, 0x00, 0xfa, 0xe3, 0x90, 0x07, 0x95,
0xc8, 0x88, 0xa4, 0xd4, 0xd7, 0xbd, 0x9f, 0xdf, 0xfa, 0x60, 0x41, 0x8a, 0xc1, 0x9f,
};
trusted_authority ext{&extension[2], sizeof(extension) - 2};
auto res = tls::trusted_ca_keys::convert(ext);
EXPECT_EQ(res.cert_sha1_hash.size(), 0);
EXPECT_EQ(res.key_sha1_hash.size(), 0);
EXPECT_EQ(res.x509_name.size(), 0);
EXPECT_FALSE(res.pre_agreed);
ext = trusted_authority{&extension[0], sizeof(extension)};
res = tls::trusted_ca_keys::convert(ext);
EXPECT_EQ(res.cert_sha1_hash.size(), 0);
EXPECT_EQ(res.key_sha1_hash.size(), 2);
EXPECT_EQ(res.x509_name.size(), 0);
EXPECT_FALSE(res.pre_agreed);
}
TEST(TrustedCaKeys, generateBuzz) {
/*
* Buzz
* 002a trusted_authorities_list length
* 03 identifier_type cert_sha1_hash d8367e861f5807f8141fea572d676dbf58bb5f7c SHA1Hash
* 03 identifier_type cert_sha1_hash 8c821f41604ed4c3431cf6d19f2ae107cf1f50e1 SHA1Hash
*/
using trusted_ca_keys_t = tls::trusted_ca_keys::trusted_ca_keys_t;
openssl::sha_1_digest_t hash1 = {
0xd8, 0x36, 0x7e, 0x86, 0x1f, 0x58, 0x07, 0xf8, 0x14, 0x1f,
0xea, 0x57, 0x2d, 0x67, 0x6d, 0xbf, 0x58, 0xbb, 0x5f, 0x7c,
};
openssl::sha_1_digest_t hash2 = {
0x8c, 0x82, 0x1f, 0x41, 0x60, 0x4e, 0xd4, 0xc3, 0x43, 0x1c,
0xf6, 0xd1, 0x9f, 0x2a, 0xe1, 0x07, 0xcf, 0x1f, 0x50, 0xe1,
};
std::uint8_t extension[] = {
0x00, 0x2a, 0x03, 0xd8, 0x36, 0x7e, 0x86, 0x1f, 0x58, 0x07, 0xf8, 0x14, 0x1f, 0xea, 0x57,
0x2d, 0x67, 0x6d, 0xbf, 0x58, 0xbb, 0x5f, 0x7c, 0x03, 0x8c, 0x82, 0x1f, 0x41, 0x60, 0x4e,
0xd4, 0xc3, 0x43, 0x1c, 0xf6, 0xd1, 0x9f, 0x2a, 0xe1, 0x07, 0xcf, 0x1f, 0x50, 0xe1,
};
trusted_ca_keys_t tck;
tck.cert_sha1_hash.push_back(hash1);
tck.cert_sha1_hash.push_back(hash2);
auto res = tls::trusted_ca_keys::convert(tck);
EXPECT_EQ(res.size(), sizeof(extension));
EXPECT_EQ(std::memcmp(res.get(), &extension, sizeof(extension)), 0);
// std::cout << "A: " << to_string(std::get<TrustedAuthority_ptr>(res).get(), sizeof(extension)) << std::endl;
// std::cout << "B: " << to_string(&extension[0], sizeof(extension)) << std::endl;
}
TEST(TrustedCaKeys, CertChain) {
// match server certificate to trust anchors
auto server_root = openssl::load_certificates("server_root_cert.pem");
auto server_ca = openssl::load_certificates("server_ca_cert.pem");
auto server = openssl::load_certificates("server_cert.pem");
auto alt_server_root = openssl::load_certificates("alt_server_root_cert.pem");
auto alt_server_ca = openssl::load_certificates("alt_server_ca_cert.pem");
auto alt_server = openssl::load_certificates("alt_server_cert.pem");
openssl::certificate_list chain;
std::move(server_ca.begin(), server_ca.end(), std::back_inserter(chain));
std::move(alt_server_ca.begin(), alt_server_ca.end(), std::back_inserter(chain));
ASSERT_EQ(server_root.size(), 1);
ASSERT_EQ(alt_server_root.size(), 1);
EXPECT_EQ(openssl::verify_certificate(server[0].get(), server_root, chain), openssl::verify_result_t::Verified);
EXPECT_EQ(openssl::verify_certificate(alt_server[0].get(), alt_server_root, chain),
openssl::verify_result_t::Verified);
EXPECT_EQ(openssl::verify_certificate(server[0].get(), alt_server_root, chain),
openssl::verify_result_t::CertificateNotAllowed);
EXPECT_EQ(openssl::verify_certificate(alt_server[0].get(), server_root, chain),
openssl::verify_result_t::CertificateNotAllowed);
}
TEST(TrustedCaKeys, matchNone) {
trusted_ca_keys_t keys;
chain_t chain;
EXPECT_FALSE(match(keys, chain));
auto root = load_certificates("server_root_cert.pem");
const auto* root_cert = root[0].get();
sha_1_digest_t digest;
keys.x509_name.emplace_back(certificate_subject_der(root_cert));
EXPECT_TRUE(certificate_sha_1(digest, root_cert));
keys.cert_sha1_hash.push_back(digest);
EXPECT_TRUE(certificate_subject_public_key_sha_1(digest, root_cert));
keys.key_sha1_hash.push_back(digest);
EXPECT_FALSE(match(keys, chain));
auto alt_root = load_certificates("client_root_cert.pem");
chain.chain.trust_anchors = std::move(alt_root);
EXPECT_FALSE(match(keys, chain));
}
TEST(TrustedCaKeys, matchName) {
trusted_ca_keys_t keys;
chain_t chain;
auto root = load_certificates("server_root_cert.pem");
chain.chain.trust_anchors = std::move(root);
const auto* root_cert = chain.chain.trust_anchors[0].get();
keys.x509_name.emplace_back(certificate_subject_der(root_cert));
EXPECT_TRUE(match(keys, chain));
sha_1_digest_t digest;
EXPECT_TRUE(certificate_sha_1(digest, root_cert));
keys.cert_sha1_hash.push_back(digest);
EXPECT_TRUE(match(keys, chain));
EXPECT_TRUE(certificate_subject_public_key_sha_1(digest, root_cert));
keys.key_sha1_hash.push_back(digest);
EXPECT_TRUE(match(keys, chain));
}
TEST(TrustedCaKeys, matchCertHash) {
trusted_ca_keys_t keys;
chain_t chain;
auto root = load_certificates("server_root_cert.pem");
chain.chain.trust_anchors.emplace_back(std::move(root[0]));
root = load_certificates("client_root_cert.pem");
chain.chain.trust_anchors.emplace_back(std::move(root[0]));
ASSERT_EQ(chain.chain.trust_anchors.size(), 2);
const auto* server_root_cert = chain.chain.trust_anchors[0].get();
const auto* client_root_cert = chain.chain.trust_anchors[1].get();
sha_1_digest_t digest;
EXPECT_TRUE(certificate_sha_1(digest, client_root_cert));
keys.cert_sha1_hash.push_back(digest);
EXPECT_TRUE(match(keys, chain));
EXPECT_TRUE(certificate_sha_1(digest, server_root_cert));
keys.cert_sha1_hash.clear();
keys.cert_sha1_hash.push_back(digest);
EXPECT_TRUE(match(keys, chain));
}
TEST(TrustedCaKeys, matchKeyHash) {
trusted_ca_keys_t keys;
chain_t chain;
auto root = load_certificates("server_root_cert.pem");
chain.chain.trust_anchors.emplace_back(std::move(root[0]));
root = load_certificates("client_root_cert.pem");
chain.chain.trust_anchors.emplace_back(std::move(root[0]));
ASSERT_EQ(chain.chain.trust_anchors.size(), 2);
const auto* server_root_cert = chain.chain.trust_anchors[0].get();
const auto* client_root_cert = chain.chain.trust_anchors[1].get();
sha_1_digest_t digest;
EXPECT_TRUE(certificate_subject_public_key_sha_1(digest, client_root_cert));
keys.key_sha1_hash.push_back(digest);
EXPECT_TRUE(match(keys, chain));
EXPECT_TRUE(certificate_subject_public_key_sha_1(digest, server_root_cert));
keys.key_sha1_hash.clear();
keys.key_sha1_hash.push_back(digest);
EXPECT_TRUE(match(keys, chain));
}
TEST(TrustedCaKeys, selectNone) {
trusted_ca_keys_t keys;
chain_list chains;
EXPECT_EQ(select(keys, chains), nullptr);
chains.emplace_back();
auto root = load_certificates("server_root_cert.pem");
chains[0].chain.trust_anchors.emplace_back(std::move(root[0]));
EXPECT_EQ(select(keys, chains), nullptr);
chains.emplace_back();
root = load_certificates("alt_server_root_cert.pem");
chains[1].chain.trust_anchors.emplace_back(std::move(root[0]));
EXPECT_EQ(select(keys, chains), nullptr);
sha_1_digest_t digest;
root = load_certificates("client_root_cert.pem");
auto* client_root_cert = root[0].get();
EXPECT_TRUE(certificate_sha_1(digest, client_root_cert));
keys.cert_sha1_hash.push_back(digest);
EXPECT_TRUE(certificate_subject_public_key_sha_1(digest, client_root_cert));
keys.key_sha1_hash.push_back(digest);
}
TEST(TrustedCaKeys, select) {
trusted_ca_keys_t keys;
chain_list chains;
EXPECT_EQ(select(keys, chains), nullptr);
chains.emplace_back();
auto root = load_certificates("server_root_cert.pem");
chains[0].chain.trust_anchors.emplace_back(std::move(root[0]));
EXPECT_EQ(select(keys, chains), nullptr);
chains.emplace_back();
root = load_certificates("alt_server_root_cert.pem");
chains[1].chain.trust_anchors.emplace_back(std::move(root[0]));
EXPECT_EQ(select(keys, chains), nullptr);
sha_1_digest_t digest;
root = load_certificates("client_root_cert.pem");
auto* client_root_cert = root[0].get();
EXPECT_TRUE(certificate_sha_1(digest, client_root_cert));
keys.cert_sha1_hash.push_back(digest);
EXPECT_TRUE(certificate_subject_public_key_sha_1(digest, client_root_cert));
keys.key_sha1_hash.push_back(digest);
chains.emplace_back();
root = load_certificates("client_root_cert.pem");
chains[2].chain.trust_anchors.emplace_back(std::move(root[0]));
auto result = select(keys, chains);
EXPECT_NE(result, nullptr);
EXPECT_EQ(result, &chains[2]);
}
} // namespace