1#include <vanetza/asn1/asn1c_wrapper.hpp>
2#include <vanetza/asn1/security_profile.hpp>
3#include VANETZA_ASN1_SECURITY_HEADER(Certificate.h)
4#include VANETZA_ASN1_SECURITY_HEADER(EtsiTs103097Data.h)
5#include <vanetza/common/byte_buffer.hpp>
6#include <vanetza/common/byte_buffer_sink.hpp>
7#include <vanetza/net/packet.hpp>
8#include <vanetza/security/backend.hpp>
9#include <vanetza/security/v3/asn1_conversions.hpp>
10#include <vanetza/security/v3/secured_message.hpp>
12#include <boost/iostreams/stream.hpp>
13#include <boost/optional/optional.hpp>
14#include <boost/variant/static_visitor.hpp>
29const asn1::SignedData* get_signed_data(
const asn1::EtsiTs103097Data* data)
31 if (data && data->content && data->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData) {
32 return data->content->choice.signedData;
38const asn1::HeaderInfo* get_header_info(
const asn1::EtsiTs103097Data* data)
40 const asn1::SignedData* signed_data = get_signed_data(data);
42 return &signed_data->tbsData->headerInfo;
48HashedId8 make_hashed_id8(
const asn1::HashedId8& asn)
51 std::copy_n(asn.buf, std::min(asn.size, result.size()), result.data());
55ByteBuffer copy_octets(
const OCTET_STRING_t& octets)
57 ByteBuffer buffer(octets.size);
58 std::memcpy(buffer.data(), octets.buf, octets.size);
62ByteBuffer get_x_coordinate(
const asn1::EccP256CurvePoint& point)
64 switch (point.present) {
65 case Vanetza_Security_EccP256CurvePoint_PR_compressed_y_0:
66 return copy_octets(point.choice.compressed_y_0);
68 case Vanetza_Security_EccP256CurvePoint_PR_compressed_y_1:
69 return copy_octets(point.choice.compressed_y_1);
71 case Vanetza_Security_EccP256CurvePoint_PR_x_only:
72 return copy_octets(point.choice.x_only);
74 case Vanetza_Security_EccP256CurvePoint_PR_uncompressedP256:
75 return copy_octets(point.choice.uncompressedP256.x);
83ByteBuffer get_x_coordinate(
const asn1::EccP384CurvePoint& point)
85 switch (point.present) {
86 case Vanetza_Security_EccP384CurvePoint_PR_compressed_y_0:
87 return copy_octets(point.choice.compressed_y_0);
89 case Vanetza_Security_EccP384CurvePoint_PR_compressed_y_1:
90 return copy_octets(point.choice.compressed_y_1);
92 case Vanetza_Security_EccP384CurvePoint_PR_x_only:
93 return copy_octets(point.choice.x_only);
95 case Vanetza_Security_EccP384CurvePoint_PR_uncompressedP384:
96 return copy_octets(point.choice.uncompressedP384.x);
109 secured_message->protocolVersion = 3;
110 secured_message->content = asn1::allocate<asn1::Ieee1609Dot2Content>();
111 secured_message->content->present = Vanetza_Security_Ieee1609Dot2Content_PR_signedData;
112 secured_message->content->choice.signedData = asn1::allocate<asn1::SignedData>();
113 secured_message->content->choice.signedData->tbsData = asn1::allocate<asn1::ToBeSignedData>();
114 secured_message->content->choice.signedData->tbsData->payload = asn1::allocate<asn1::SignedDataPayload>();
115 secured_message->content->choice.signedData->tbsData->payload->data = asn1::allocate<asn1::Ieee1609Dot2Data>();
116 secured_message->content->choice.signedData->tbsData->payload->data->protocolVersion = 3;
117 secured_message->content->choice.signedData->tbsData->payload->data->content = asn1::allocate<asn1::Ieee1609Dot2Content>();
118 secured_message->content->choice.signedData->tbsData->payload->data->content->present = Vanetza_Security_Ieee1609Dot2Content_PR_unsecuredData;
119 return secured_message;
125 secured_message->protocolVersion = 3;
126 secured_message->content = asn1::allocate<asn1::Ieee1609Dot2Content>();
127 secured_message->content->present = Vanetza_Security_Ieee1609Dot2Content_PR_signedData;
128 secured_message->content->choice.signedData = asn1::allocate<asn1::SignedData>();
129 secured_message->content->choice.signedData->tbsData = asn1::allocate<asn1::ToBeSignedData>();
130 secured_message->content->choice.signedData->tbsData->payload = asn1::allocate<asn1::SignedDataPayload>();
131 secured_message->content->choice.signedData->tbsData->payload->extDataHash = asn1::allocate<asn1::HashedData>();
132 secured_message->content->choice.signedData->tbsData->payload->extDataHash->present = Vanetza_Security_HashedData_PR_sha256HashedData;
133 return secured_message;
139 secured_message->protocolVersion = 3;
140 secured_message->content = asn1::allocate<asn1::Ieee1609Dot2Content>();
141 secured_message->content->present = Vanetza_Security_Ieee1609Dot2Content_PR_encryptedData;
142 return secured_message;
146 asn1::asn1c_oer_wrapper<asn1::EtsiTs103097Data>(asn_DEF_Vanetza_Security_EtsiTs103097Data)
152 return m_struct->protocolVersion;
157 return get_certificate_id(signer_identifier());
163 const asn1::SignedData* signed_data = get_signed_data(m_struct);
164 if (signed_data && signed_data->tbsData) {
165 aid = signed_data->tbsData->headerInfo.psid;
172 if (m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData) {
173 asn1::SignedData* signed_data = m_struct->content->choice.signedData;
174 if (signed_data && signed_data->tbsData) {
175 signed_data->tbsData->headerInfo.psid = its_aid;
182 if (m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData) {
183 if (m_struct->content->choice.signedData->tbsData->headerInfo.generationTime ==
nullptr) {
184 m_struct->content->choice.signedData->tbsData->headerInfo.generationTime = asn1::allocate<asn1::Time64>();
186 asn_uint642INTEGER(m_struct->content->choice.signedData->tbsData->headerInfo.generationTime, time);
190void SecuredMessage::set_generation_location(
const asn1::ThreeDLocation& location)
192 if (m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData) {
193 if (m_struct->content->choice.signedData->tbsData->headerInfo.generationLocation ==
nullptr) {
194 m_struct->content->choice.signedData->tbsData->headerInfo.generationLocation = asn1::allocate<asn1::ThreeDLocation>();
196 m_struct->content->choice.signedData->tbsData->headerInfo.generationLocation->latitude = location.latitude;
197 m_struct->content->choice.signedData->tbsData->headerInfo.generationLocation->longitude = location.longitude;
198 m_struct->content->choice.signedData->tbsData->headerInfo.generationLocation->elevation = location.elevation;
202std::list<HashedId3>
SecuredMessage::get_inline_p2pcd_request()
const
204 std::list<HashedId3> requests;
205 if (m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData) {
206 const asn1::SequenceOfHashedId3* inline_p2pcd_request = m_struct->content->choice.signedData->tbsData->headerInfo.inlineP2pcdRequest;
207 if (inline_p2pcd_request) {
208 for (
int i = 0; i < inline_p2pcd_request->list.count; i++) {
209 HashedId3 new_elem = truncate(convert(*inline_p2pcd_request->list.array[i]));
210 requests.push_back(new_elem);
217void SecuredMessage::set_inline_p2pcd_request(std::list<HashedId3> requests)
219 if (m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData) {
220 assert(m_struct->content->choice.signedData);
221 assert(m_struct->content->choice.signedData->tbsData);
223 if (m_struct->content->choice.signedData->tbsData->headerInfo.inlineP2pcdRequest) {
224 asn1::reset(m_struct->content->choice.signedData->tbsData->headerInfo.inlineP2pcdRequest);
227 for (HashedId3 request : requests) {
228 this->add_inline_p2pcd_request(request);
233void SecuredMessage::add_inline_p2pcd_request(HashedId3 unknown_certificate_digest)
235 if (m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData) {
236 if (m_struct->content->choice.signedData->tbsData->headerInfo.inlineP2pcdRequest ==
nullptr) {
237 m_struct->content->choice.signedData->tbsData->headerInfo.inlineP2pcdRequest = asn1::allocate<asn1::SequenceOfHashedId3>();
239 Vanetza_Security_HashedId3_t* asn_digest = OCTET_STRING_new_fromBuf(&asn_DEF_Vanetza_Security_HashedId3,
240 reinterpret_cast<
char*>(unknown_certificate_digest.data()), unknown_certificate_digest.size());
241 ASN_SEQUENCE_ADD(m_struct->content->choice.signedData->tbsData->headerInfo.inlineP2pcdRequest, asn_digest);
247 if (m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData) {
248 asn1::SignedData* signed_data = m_struct->content->choice.signedData;
251 asn1::reset(signed_data->signature);
254 signed_data->signature.present = Vanetza_Security_Signature_PR_ecdsaNistP256Signature;
257 signed_data->signature.choice.ecdsaNistP256Signature.rSig.present = Vanetza_Security_EccP256CurvePoint_PR_x_only;
258 std::vector<uint8_t> dummy_r(32, 0);
260 assign(&signed_data->signature.choice.ecdsaNistP256Signature.rSig.choice.x_only, dummy_r);
263 std::vector<uint8_t> dummy_s(32, 0);
264 assign(&signed_data->signature.choice.ecdsaNistP256Signature.sSig, dummy_s);
271 if (m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData) {
272 asn1::SignedData* signed_data = m_struct->content->choice.signedData;
275 asn1::reset(signed_data->signature);
278 switch (signature.type)
280 case vanetza::security::KeyType::NistP256:
281 signed_data->signature.present = Vanetza_Security_Signature_PR_ecdsaNistP256Signature;
285 signed_data->signature.choice.ecdsaNistP256Signature.rSig.present = Vanetza_Security_EccP256CurvePoint_PR_x_only;
286 assign(&signed_data->signature.choice.ecdsaNistP256Signature.rSig.choice.x_only, signature.r);
287 assign(&signed_data->signature.choice.ecdsaNistP256Signature.sSig, signature.s);
289 case vanetza::security::KeyType::BrainpoolP256r1 :
290 signed_data->signature.present = Vanetza_Security_Signature_PR_ecdsaBrainpoolP256r1Signature;
292 signed_data->signature.choice.ecdsaBrainpoolP256r1Signature.rSig.present = Vanetza_Security_EccP256CurvePoint_PR_x_only;
293 assign(&signed_data->signature.choice.ecdsaBrainpoolP256r1Signature.rSig.choice.x_only, signature.r);
294 assign(&signed_data->signature.choice.ecdsaBrainpoolP256r1Signature.sSig, signature.s);
296 case vanetza::security::KeyType::BrainpoolP384r1 :
297 signed_data->signature.present = Vanetza_Security_Signature_PR_ecdsaBrainpoolP384r1Signature;
299 signed_data->signature.choice.ecdsaBrainpoolP384r1Signature.rSig.present = Vanetza_Security_EccP384CurvePoint_PR_x_only;
300 assign(&signed_data->signature.choice.ecdsaBrainpoolP384r1Signature.rSig.choice.x_only, signature.r);
301 assign(&signed_data->signature.choice.ecdsaBrainpoolP384r1Signature.sSig, signature.s);
304 this->set_dummy_signature();
311void SecuredMessage::set_signature(
const SomeEcdsaSignature& signature)
313 struct signature_visitor :
public boost::static_visitor<asn1::Signature>
317 asn1::Signature final_signature = {};
318 final_signature.present = Vanetza_Security_Signature_PR_ecdsaNistP256Signature;
319 assign(&final_signature.choice.ecdsaNistP256Signature.sSig, signature.s);
320 final_signature.choice.ecdsaNistP256Signature.rSig = to_asn1(signature.R);
321 return final_signature;
326 return this->operator()(signature.get());
330 asn1::reset(m_struct->content->choice.signedData->signature);
331 m_struct->content->choice.signedData->signature = boost::apply_visitor(signature_visitor(), signature);
337 switch (m_struct->content->present) {
338 case Vanetza_Security_Ieee1609Dot2Content_PR_unsecuredData:
339 buffer = get_payload(&m_struct->content->choice.unsecuredData);
341 case Vanetza_Security_Ieee1609Dot2Content_PR_signedData:
342 buffer = get_payload(m_struct->content->choice.signedData);
354 switch (m_struct->content->present) {
355 case Vanetza_Security_Ieee1609Dot2Content_PR_unsecuredData:
356 vanetza::security::v3::set_payload(&m_struct->content->choice.unsecuredData, payload);
358 case Vanetza_Security_Ieee1609Dot2Content_PR_signedData:
359 vanetza::security::v3::set_payload(&m_struct->content->choice.signedData->tbsData->payload->data->content->choice.unsecuredData, payload);
367void SecuredMessage::set_external_payload_hash(
const Sha256Digest& hash)
369 assert(m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData);
370 asn1::HashedData* hashed_data = m_struct->content->choice.signedData->tbsData->payload->extDataHash;
371 asn1::reset(hashed_data);
372 hashed_data->present = Vanetza_Security_HashedData_PR_sha256HashedData;
373 OCTET_STRING_fromBuf(&hashed_data->choice.sha256HashedData,
reinterpret_cast<
const char*>(hash.data()), hash.size());
378 HashAlgorithm algo = HashAlgorithm::Unspecified;
380 const asn1::SignedData* signed_data = get_signed_data(m_struct);
382 switch (signed_data->hashId) {
383 case Vanetza_Security_HashAlgorithm_sha256:
384 algo = HashAlgorithm::SHA256;
386 case Vanetza_Security_HashAlgorithm_sha384:
387 algo = HashAlgorithm::SHA384;
399 assert(m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData);
401 case HashAlgorithm::SHA256:
402 m_struct->content->choice.signedData->hashId = Vanetza_Security_HashAlgorithm_sha256;
404 case HashAlgorithm::SHA384:
405 m_struct->content->choice.signedData->hashId = Vanetza_Security_HashAlgorithm_sha384;
408 m_struct->content->choice.signedData->hashId = -1;
414 assert(m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData);
415 asn1::SignerIdentifier* signer = &m_struct->content->choice.signedData->signer;
417 signer->present = Vanetza_Security_SignerIdentifier_PR_self;
420void SecuredMessage::set_signer_identifier(
const HashedId8& digest)
422 assert(m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData);
423 asn1::SignerIdentifier* signer = &m_struct->content->choice.signedData->signer;
425 signer->present = Vanetza_Security_SignerIdentifier_PR_digest;
426 OCTET_STRING_fromBuf(&signer->choice.digest,
reinterpret_cast<
const char*>(digest.data()), digest.size());
431 assert(m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData);
432 asn1::SignerIdentifier* signer = &m_struct->content->choice.signedData->signer;
434 signer->present = Vanetza_Security_SignerIdentifier_PR_certificate;
435 ASN_SEQUENCE_ADD(&signer->choice.certificate, asn1::copy(asn_DEF_Vanetza_Security_EtsiTs103097Certificate, cert.content()));
438void SecuredMessage::get_aes_ccm_ciphertext(ByteBuffer &ccm_ciphertext, std::array<uint8_t, 12> &nonce)
const
440 assert(m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_encryptedData);
442 const asn1::SymmetricCiphertext &symmetric_ciphertext = m_struct->content->choice.encryptedData.ciphertext;
443 assert(symmetric_ciphertext.present == Vanetza_Security_SymmetricCiphertext_PR_aes128ccm);
445 const asn1::AesCcmCiphertext &aes_ccm_ciphertext = symmetric_ciphertext.choice.aes128ccm;
446 ccm_ciphertext = copy_octets(aes_ccm_ciphertext.ccmCiphertext);
447 std::memcpy(nonce.data(), aes_ccm_ciphertext.nonce.buf, nonce.size());
450void SecuredMessage::set_aes_ccm_ciphertext(
const ByteBuffer &ccm_ciphertext,
const std::array<uint8_t, 12> &nonce)
452 assert(m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_encryptedData);
454 asn1::SymmetricCiphertext &symmetric_ciphertext = m_struct->content->choice.encryptedData.ciphertext;
455 CHOICE_variant_set_presence(&asn_DEF_Vanetza_Security_SymmetricCiphertext, &symmetric_ciphertext, Vanetza_Security_SymmetricCiphertext_PR_aes128ccm);
457 asn1::AesCcmCiphertext &aes_ccm_ciphertext = symmetric_ciphertext.choice.aes128ccm;
458 OCTET_STRING_fromBuf(&aes_ccm_ciphertext.ccmCiphertext,
reinterpret_cast<
const char *>(ccm_ciphertext.data()), ccm_ciphertext.size());
459 OCTET_STRING_fromBuf(&aes_ccm_ciphertext.nonce,
reinterpret_cast<
const char *>(nonce.data()), nonce.size());
462void SecuredMessage::set_cert_recip_info(
const HashedId8& recipient_id,
463 const std::array<uint8_t, 16>& ecies_ciphertext,
464 const std::array<uint8_t, 16>& ecies_tag,
467 assert(m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_encryptedData);
470 auto cert_recip_info = asn1::make_unique<asn1::RecipientInfo>();
471 CHOICE_variant_set_presence(&asn_DEF_Vanetza_Security_RecipientInfo, cert_recip_info.get(), Vanetza_Security_RecipientInfo_PR_certRecipInfo);
473 asn1::PKRecipientInfo &pk_recip_info = cert_recip_info->choice.certRecipInfo;
475 OCTET_STRING_fromBuf(&pk_recip_info.recipientId,
reinterpret_cast<
const char *>(recipient_id.data()), recipient_id.size());
477 asn1::EncryptedDataEncryptionKey &enc_data_enc_key = pk_recip_info.encKey;
478 asn1::EciesP256EncryptedKey *ecies_enc_key =
nullptr;
479 if (ecies_pub_key.type == KeyType::NistP256) {
480 enc_data_enc_key.present = Vanetza_Security_EncryptedDataEncryptionKey_PR_eciesNistP256;
481 ecies_enc_key = &enc_data_enc_key.choice.eciesNistP256;
482 }
else if (ecies_pub_key.type == KeyType::BrainpoolP256r1) {
483 enc_data_enc_key.present = Vanetza_Security_EncryptedDataEncryptionKey_PR_eciesBrainpoolP256r1;
484 ecies_enc_key = &enc_data_enc_key.choice.eciesBrainpoolP256r1;
486 throw std::invalid_argument(
"Unsupported EC curve");
490 OCTET_STRING_fromBuf(&ecies_enc_key->c,
reinterpret_cast<
const char *>(ecies_ciphertext.data()), ecies_ciphertext.size());
491 OCTET_STRING_fromBuf(&ecies_enc_key->t,
reinterpret_cast<
const char *>(ecies_tag.data()), ecies_tag.size());
494 ecies_enc_key->v = to_asn1(make_ecc_point(ecies_pub_key));
496 ASN_SEQUENCE_ADD(&m_struct->content->choice.encryptedData.recipients.list, cert_recip_info.release());
499bool SecuredMessage::check_psk_match(
const std::array<uint8_t, 16>& psk)
const
501 assert(m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_encryptedData);
504 asn1::
asn1c_oer_wrapper<asn1::SymmetricEncryptionKey> psk_key(asn_DEF_Vanetza_Security_SymmetricEncryptionKey);
505 asn1::SymmetricEncryptionKey *psk_key_ptr = &(*psk_key);
506 CHOICE_variant_set_presence(
507 &asn_DEF_Vanetza_Security_SymmetricEncryptionKey,
509 Vanetza_Security_SymmetricEncryptionKey_PR_aes128Ccm);
510 OCTET_STRING_fromBuf(&psk_key_ptr->choice.aes128Ccm,
reinterpret_cast<
const char *>(psk.data()), psk.size());
512 ByteBuffer bytes = psk_key.encode();
513 Sha256Digest psk_digest = calculate_sha256_digest(bytes.data(), bytes.size());
514 HashedId8 psk_id = create_hashed_id8(psk_digest);
517 const auto &recipient_list = m_struct->content->choice.encryptedData.recipients.list;
519 for (
int i = 0; i < recipient_list.count; i++) {
520 const asn1::RecipientInfo &recipient_info = *recipient_list.array[i];
521 if (recipient_info.present != Vanetza_Security_RecipientInfo_PR_pskRecipInfo) {
525 HashedId8 message_psk_id;
526 std::memcpy(message_psk_id.data(), recipient_info.choice.pskRecipInfo.buf, message_psk_id.size());
527 if (psk_id == message_psk_id) {
537 return m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_signedData;
542 return m_struct->content->present == Vanetza_Security_Ieee1609Dot2Content_PR_encryptedData;
547 boost::optional<Time64> gen_time;
548 auto header_info = get_header_info(m_struct);
551 if (asn_INTEGER2umax(header_info->generationTime, &tmp) == 0) {
560 const asn1::SignedData* signed_data = get_signed_data(m_struct);
562 const asn1::Signature& asn = signed_data->signature;
566 case Vanetza_Security_Signature_PR_ecdsaNistP256Signature:
567 sig.type = KeyType::NistP256;
568 sig.r = get_x_coordinate(asn.choice.ecdsaNistP256Signature.rSig);
569 sig.s = copy_octets(asn.choice.ecdsaNistP256Signature.sSig);
571 case Vanetza_Security_Signature_PR_ecdsaBrainpoolP256r1Signature:
572 sig.type = KeyType::BrainpoolP256r1;
573 sig.r = get_x_coordinate(asn.choice.ecdsaBrainpoolP256r1Signature.rSig);
574 sig.s = copy_octets(asn.choice.ecdsaBrainpoolP256r1Signature.sSig);
576 case Vanetza_Security_Signature_PR_ecdsaBrainpoolP384r1Signature:
577 sig.type = KeyType::BrainpoolP384r1;
578 sig.r = get_x_coordinate(asn.choice.ecdsaBrainpoolP384r1Signature.rSig);
579 sig.s = copy_octets(asn.choice.ecdsaBrainpoolP384r1Signature.sSig);
592 const asn1::SignedData* signed_data = get_signed_data(m_struct);
594 if (signed_data->signer.present == Vanetza_Security_SignerIdentifier_PR_digest) {
595 const asn1::HashedId8* digest = &signed_data->signer.choice.digest;
597 }
else if (signed_data->signer.present == Vanetza_Security_SignerIdentifier_PR_certificate) {
598 const asn1::SequenceOfCertificate& certificates = signed_data->signer.choice.certificate;
600 if (certificates.list.count == 1) {
601 const asn1::Certificate* cert = certificates.list.array[0];
607 return static_cast<asn1::HashedId8*>(
nullptr);
612 const asn1::SignedData* signed_data = get_signed_data(m_struct);
614 return asn1::encode_oer(asn_DEF_Vanetza_Security_ToBeSignedData, signed_data->tbsData);
616 return ByteBuffer {};
622 const asn1::SignedData* signed_data = get_signed_data(m_struct);
623 if (signed_data && signed_data->tbsData) {
624 if (signed_data->tbsData->headerInfo.requestedCertificate) {
625 ASN_STRUCT_FREE(asn_DEF_Vanetza_Security_Certificate, signed_data->tbsData->headerInfo.requestedCertificate);
627 signed_data->tbsData->headerInfo.requestedCertificate =
628 static_cast<Vanetza_Security_Certificate*>(asn1::copy(asn_DEF_Vanetza_Security_Certificate, cert.content()));
634 return message.size();
639 ByteBuffer buffer = msg.encode();
640 ar.save_binary(buffer.data(), buffer.size());
645 std::size_t len = ar.remaining_bytes();
649 ar.load_binary(buffer.data(), len);
650 return msg.decode(buffer) ? len : 0;
653ByteBuffer get_payload(
const asn1::Opaque* unsecured)
656 buffer.reserve(unsecured->size);
657 std::copy_n(unsecured->buf, unsecured->size, std::back_inserter(buffer));
661ByteBuffer convert_to_payload(vanetza::DownPacket packet)
666 boost::iostreams::stream_buffer<byte_buffer_sink> stream(sink);
669 serialize(ar, packet);
675void set_payload(asn1::Opaque* unsecured,
const ByteBuffer& buffer)
677 OCTET_STRING_fromBuf(unsecured,
reinterpret_cast<
const char*>(buffer.data()), buffer.size());
680ByteBuffer get_payload(
const asn1::SignedData* signed_data)
683 if (signed_data->tbsData && signed_data->tbsData->payload) {
684 const asn1::SignedDataPayload* signed_payload = signed_data->tbsData->payload;
685 if (signed_payload->data && signed_payload->data->content) {
686 const asn1::Ieee1609Dot2Content* content = signed_payload->data->content;
687 if (content->present == Vanetza_Security_Ieee1609Dot2Content_PR_unsecuredData) {
688 buffer = get_payload(&content->choice.unsecuredData);
695boost::optional<HashedId8> get_certificate_id(
const SecuredMessage::SignerIdentifier& identifier)
697 using result_type = boost::optional<HashedId8>;
698 struct cert_id_visitor :
public boost::static_visitor<result_type> {
699 result_type operator()(
const asn1::HashedId8* digest)
const
701 return digest ? make_hashed_id8(*digest) : result_type { };
704 result_type operator()(
const asn1::Certificate* cert)
const
706 return cert ? calculate_digest(*cert) : result_type { };
709 return boost::apply_visitor(cert_id_visitor(), identifier);
712bool contains_certificate(
const SecuredMessage::SignerIdentifier& identifier)
714 struct visitor :
public boost::static_visitor<
bool> {
715 bool operator()(
const asn1::HashedId8*)
const
720 bool operator()(
const asn1::Certificate*)
const
725 return boost::apply_visitor(visitor(), identifier);
728const asn1::Certificate* get_certificate(
const SecuredMessage::SignerIdentifier& identifier)
730 struct visitor :
public boost::static_visitor<
const asn1::Certificate*> {
731 const asn1::Certificate* operator()(
const asn1::HashedId8*)
const
736 const asn1::Certificate* operator()(
const asn1::Certificate* cert)
const
741 return boost::apply_visitor(visitor(), identifier);
EcdsaSignature specified in TS 103 097 v1.2.1, section 4.2.9.