1#include <vanetza/security/public_key.hpp>
2#include <boost/algorithm/hex.hpp>
11std::string canonical_hexstring(
const PublicKey& key)
13 const std::size_t expected_length = key_length(key.type);
14 if (expected_length == 0 || key.x.size() != expected_length) {
19 switch (key.compression) {
20 case KeyCompression::NoCompression:
21 if (key.y.size() != expected_length) {
24 input.push_back(*key.y.rbegin() % 2 == 0 ? 0x02 : 0x03);
26 case KeyCompression::Y0:
27 input.push_back(0x02);
29 case KeyCompression::Y1:
30 input.push_back(0x03);
35 std::copy(key.x.begin(), key.x.end(), std::back_inserter(input));
36 return boost::algorithm::hex(input);
39ByteBuffer encode_subject_public_key_info(
const PublicKey& key)
41 const std::size_t expected_length = key_length(key.type);
42 if (expected_length == 0 || key.x.size() != expected_length) {
47 static const uint8_t oid_ec_public_key[] = {
48 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01
51 static const uint8_t oid_secp256r1[] = {
52 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07
55 static const uint8_t oid_brainpoolP256r1[] = {
56 0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07
59 static const uint8_t oid_brainpoolP384r1[] = {
60 0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B
63 const uint8_t* named_curve_oid =
nullptr;
64 std::size_t named_curve_oid_size = 0;
66 case KeyType::NistP256:
67 named_curve_oid = oid_secp256r1;
68 named_curve_oid_size =
sizeof(oid_secp256r1);
70 case KeyType::BrainpoolP256r1:
71 named_curve_oid = oid_brainpoolP256r1;
72 named_curve_oid_size =
sizeof(oid_brainpoolP256r1);
74 case KeyType::BrainpoolP384r1:
75 named_curve_oid = oid_brainpoolP384r1;
76 named_curve_oid_size =
sizeof(oid_brainpoolP384r1);
82 uint8_t ec_point_prefix = 0;
83 std::size_t ec_point_size = 0;
84 switch (key.compression) {
85 case KeyCompression::NoCompression:
86 if (key.y.size() != expected_length) {
89 ec_point_prefix = 0x04;
90 ec_point_size = 1 + 2 * expected_length;
92 case KeyCompression::Y0:
93 ec_point_prefix = 0x02;
94 ec_point_size = 1 + expected_length;
96 case KeyCompression::Y1:
97 ec_point_prefix = 0x03;
98 ec_point_size = 1 + expected_length;
104 const std::size_t algo_content_size =
sizeof(oid_ec_public_key) + named_curve_oid_size;
105 const std::size_t bit_string_content_size = 1 + ec_point_size;
106 const std::size_t spki_content_size = 2 + algo_content_size + 2 + bit_string_content_size;
109 result.reserve(2 + spki_content_size);
111 result.push_back(0x30);
112 result.push_back(
static_cast<uint8_t>(spki_content_size));
114 result.push_back(0x30);
115 result.push_back(
static_cast<uint8_t>(algo_content_size));
116 result.insert(result.end(), oid_ec_public_key, oid_ec_public_key +
sizeof(oid_ec_public_key));
117 result.insert(result.end(), named_curve_oid, named_curve_oid + named_curve_oid_size);
119 result.push_back(0x03);
120 result.push_back(
static_cast<uint8_t>(bit_string_content_size));
121 result.push_back(0x00);
122 result.push_back(ec_point_prefix);
123 result.insert(result.end(), key.x.begin(), key.x.end());
124 if (key.compression == KeyCompression::NoCompression) {
125 result.insert(result.end(), key.y.begin(), key.y.end());