1#include <vanetza/asn1/security/Certificate.h>
2#include <vanetza/security/sha.hpp>
3#include <vanetza/security/v3/asn1_conversions.hpp>
4#include <vanetza/security/v3/certificate.hpp>
5#include <vanetza/security/v3/distance.hpp>
6#include <boost/optional/optional.hpp>
19bool copy_curve_point(PublicKey& to,
const asn1::EccP256CurvePoint& from);
20bool copy_curve_point(PublicKey& to,
const asn1::EccP384CurvePoint& from);
21ByteBuffer fetch_octets(
const OCTET_STRING_t& octets);
22ByteBuffer get_x_coordinate(
const asn1::EccP256CurvePoint& point);
23ByteBuffer get_x_coordinate(
const asn1::EccP384CurvePoint& point);
25bool is_compressed(
const Vanetza_Security_EccP256CurvePoint& point);
26bool is_compressed(
const Vanetza_Security_EccP384CurvePoint& point);
27bool is_signature_x_only(
const Vanetza_Security_Signature_t& sig);
28bool compress(Vanetza_Security_EccP256CurvePoint&);
29bool compress(Vanetza_Security_EccP384CurvePoint&);
30bool make_x_only(Vanetza_Security_EccP256CurvePoint&);
31bool make_x_only(Vanetza_Security_EccP384CurvePoint&);
32bool make_signature_x_only(Vanetza_Security_Signature_t& sig);
36CertificateView::CertificateView(
const asn1::EtsiTs103097Certificate* cert) :
41Certificate::Certificate() :
42 Wrapper(asn_DEF_Vanetza_Security_EtsiTs103097Certificate),
43 CertificateView { content() }
45 assert(CertificateView::m_cert == Wrapper::m_struct);
48Certificate::Certificate(
const asn1::EtsiTs103097Certificate& cert) :
49 Wrapper(asn_DEF_Vanetza_Security_EtsiTs103097Certificate, &cert),
50 CertificateView { content() }
52 assert(CertificateView::m_cert == Wrapper::m_struct);
55Certificate::Certificate(
const Certificate& other) :
56 Wrapper(other), CertificateView(content())
58 assert(CertificateView::m_cert == Wrapper::m_struct);
61Certificate& Certificate::operator=(
const Certificate& other)
63 Wrapper::operator=(other);
64 CertificateView::m_cert = content();
65 assert(CertificateView::m_cert == Wrapper::m_struct);
69Certificate::Certificate(Certificate&& other) :
70 Wrapper(
std::move(other)), CertificateView(content())
72 assert(CertificateView::m_cert == Wrapper::m_struct);
75Certificate& Certificate::operator=(Certificate&& other)
77 Wrapper::operator=(std::move(other));
78 CertificateView::m_cert = content();
79 assert(CertificateView::m_cert == Wrapper::m_struct);
85 return m_cert ? v3::calculate_digest(*m_cert) : boost::none;
90 return m_cert ? v3::get_verification_key_type(*m_cert) : KeyType::Unspecified;
95 return m_cert ? lc ? lc->valid_at_location(*m_cert, location) : false :
false;
100 return m_cert ? v3::valid_at_timepoint(*m_cert, timepoint) :
false;
103bool valid_at_timepoint(
const asn1::EtsiTs103097Certificate& cert,
const Clock::time_point& timepoint)
105 const asn1::ValidityPeriod& validity = cert.toBeSigned.validityPeriod;
106 Clock::time_point start { std::chrono::seconds(validity.start) };
107 Clock::time_point end = start;
109 switch (validity.duration.present)
111 case Vanetza_Security_Duration_PR_microseconds:
112 end += std::chrono::microseconds(validity.duration.choice.microseconds);
114 case Vanetza_Security_Duration_PR_milliseconds:
115 end += std::chrono::milliseconds(validity.duration.choice.milliseconds);
117 case Vanetza_Security_Duration_PR_seconds:
118 end += std::chrono::seconds(validity.duration.choice.seconds);
120 case Vanetza_Security_Duration_PR_minutes:
121 end += std::chrono::minutes(validity.duration.choice.minutes);
123 case Vanetza_Security_Duration_PR_hours:
124 end += std::chrono::hours(validity.duration.choice.hours);
126 case Vanetza_Security_Duration_PR_sixtyHours:
127 end += std::chrono::hours(60) * validity.duration.choice.sixtyHours;
129 case Vanetza_Security_Duration_PR_years:
131 end += std::chrono::seconds(31556952) * validity.duration.choice.years;
138 return timepoint >= start && timepoint < end;
143 return m_cert ? v3::valid_for_application(*m_cert, aid) :
false;
146bool valid_for_application(
const asn1::EtsiTs103097Certificate& cert, ItsAid aid)
148 const asn1::SequenceOfPsidSsp* permissions = cert.toBeSigned.appPermissions;
150 for (
int i = 0; i < permissions->list.count; ++i) {
151 if (permissions->list.array[i]->psid == aid) {
163 boost::optional<HashedId8> digest;
164 if (m_cert !=
nullptr) {
165 switch (m_cert->issuer.present)
167 case Vanetza_Security_IssuerIdentifier_PR_sha256AndDigest:
168 digest = create_hashed_id8(m_cert->issuer.choice.sha256AndDigest);
170 case Vanetza_Security_IssuerIdentifier_PR_sha384AndDigest:
171 digest = create_hashed_id8(m_cert->issuer.choice.sha384AndDigest);
182 return m_cert->issuer.present == Vanetza_Security_IssuerIdentifier_PR_self;
187 return m_cert ? m_cert->toBeSigned.region != nullptr :
false;
192 return m_cert && m_cert->toBeSigned.certIssuePermissions !=
nullptr;
197 return m_cert && m_cert->toBeSigned.certIssuePermissions ==
nullptr && m_cert->toBeSigned.appPermissions !=
nullptr;
202 return m_cert ? v3::is_canonical(*m_cert) :
false;
208 start_and_end.start_validity = Time32(m_cert->toBeSigned.validityPeriod.start);
210 switch (m_cert->toBeSigned.validityPeriod.duration.present)
212 case Vanetza_Security_Duration_PR_NOTHING:
214 case Vanetza_Security_Duration_PR_microseconds:
215 duration += (int)m_cert->toBeSigned.validityPeriod.duration.choice.microseconds/1000000;
217 case Vanetza_Security_Duration_PR_milliseconds:
218 duration += (int)m_cert->toBeSigned.validityPeriod.duration.choice.milliseconds/1000;
220 case Vanetza_Security_Duration_PR_seconds:
221 duration += (int)m_cert->toBeSigned.validityPeriod.duration.choice.seconds;
223 case Vanetza_Security_Duration_PR_minutes:
224 duration += (int)m_cert->toBeSigned.validityPeriod.duration.choice.minutes*60;
226 case Vanetza_Security_Duration_PR_hours:
227 duration += (int)m_cert->toBeSigned.validityPeriod.duration.choice.hours*60*60;
229 case Vanetza_Security_Duration_PR_sixtyHours:
230 duration += (int)m_cert->toBeSigned.validityPeriod.duration.choice.sixtyHours*60*60*60;
232 case Vanetza_Security_Duration_PR_years:
233 duration += (int)m_cert->toBeSigned.validityPeriod.duration.choice.years*60*60*24*365;
238 start_and_end.end_validity = start_and_end.start_validity + duration;
239 return start_and_end;
242bool is_canonical(
const asn1::EtsiTs103097Certificate& cert)
244 bool compressed_point =
true;
245 const Vanetza_Security_VerificationKeyIndicator& indicator = cert.toBeSigned.verifyKeyIndicator;
246 if (indicator.present == Vanetza_Security_VerificationKeyIndicator_PR_verificationKey) {
247 const Vanetza_Security_PublicVerificationKey& pubkey = indicator.choice.verificationKey;
248 switch (pubkey.present) {
249 case Vanetza_Security_PublicVerificationKey_PR_ecdsaNistP256:
250 compressed_point = is_compressed(pubkey.choice.ecdsaNistP256);
252 case Vanetza_Security_PublicVerificationKey_PR_ecdsaBrainpoolP256r1:
253 compressed_point = is_compressed(pubkey.choice.ecdsaBrainpoolP256r1);
255 case Vanetza_Security_PublicVerificationKey_PR_ecdsaBrainpoolP384r1:
256 compressed_point = is_compressed(pubkey.choice.ecdsaBrainpoolP384r1);
261 }
else if (indicator.present == Vanetza_Security_VerificationKeyIndicator_PR_reconstructionValue) {
262 compressed_point = is_compressed(indicator.choice.reconstructionValue);
265 if (!compressed_point) {
267 }
else if (cert.signature && !is_signature_x_only(*cert.signature)) {
276 return m_cert ? asn1::encode_oer(asn_DEF_Vanetza_Security_EtsiTs103097Certificate, m_cert) : ByteBuffer {};
279ByteBuffer Certificate::encode()
const
281 return Wrapper::encode();
286 return m_cert ? v3::canonicalize(*m_cert) : boost::none;
289boost::optional<Certificate> canonicalize(
const asn1::EtsiTs103097Certificate& cert)
294 if (canonical->toBeSigned.verifyKeyIndicator.present == Vanetza_Security_VerificationKeyIndicator_PR_verificationKey) {
295 Vanetza_Security_PublicVerificationKey& pubkey = canonical->toBeSigned.verifyKeyIndicator.choice.verificationKey;
296 switch (pubkey.present) {
297 case Vanetza_Security_PublicVerificationKey_PR_ecdsaNistP256:
298 success &= compress(pubkey.choice.ecdsaNistP256);
300 case Vanetza_Security_PublicVerificationKey_PR_ecdsaBrainpoolP256r1:
301 success &= compress(pubkey.choice.ecdsaBrainpoolP256r1);
303 case Vanetza_Security_PublicVerificationKey_PR_ecdsaBrainpoolP384r1:
304 success &= compress(pubkey.choice.ecdsaBrainpoolP384r1);
309 }
else if (canonical->toBeSigned.verifyKeyIndicator.present == Vanetza_Security_VerificationKeyIndicator_PR_reconstructionValue) {
310 success &= compress(canonical->toBeSigned.verifyKeyIndicator.choice.reconstructionValue);
313 if (canonical->toBeSigned.encryptionKey) {
314 Vanetza_Security_BasePublicEncryptionKey& pubkey = canonical->toBeSigned.encryptionKey->publicKey;
315 switch (pubkey.present) {
316 case Vanetza_Security_BasePublicEncryptionKey_PR_eciesNistP256:
317 success &= compress(pubkey.choice.eciesNistP256);
319 case Vanetza_Security_BasePublicEncryptionKey_PR_eciesBrainpoolP256r1:
320 success &= compress(pubkey.choice.eciesBrainpoolP256r1);
327 if (canonical->signature) {
328 success &= make_signature_x_only(*canonical->signature);
332 assert(is_canonical(*canonical));
339boost::optional<HashedId8> calculate_digest_internal(
const asn1::EtsiTs103097Certificate& cert, KeyType key_type)
341 boost::optional<HashedId8> digest;
344 ByteBuffer buffer = asn1::encode_oer(asn_DEF_Vanetza_Security_EtsiTs103097Certificate, &cert);
348 case KeyType::NistP256:
349 case KeyType::BrainpoolP256r1:
350 digest = create_hashed_id8(calculate_sha256_digest(buffer.data(), buffer.size()));
352 case KeyType::BrainpoolP384r1:
353 digest = create_hashed_id8(calculate_sha384_digest(buffer.data(), buffer.size()));
358 }
catch (
const std::exception&) {
365boost::optional<HashedId8> calculate_digest(
const asn1::EtsiTs103097Certificate& cert)
367 boost::optional<HashedId8> digest;
368 auto key_type = get_verification_key_type(cert);
369 if (key_type != KeyType::Unspecified) {
370 if (is_canonical(cert)) {
371 digest = calculate_digest_internal(cert, key_type);
373 auto maybe_canonical_cert = canonicalize(cert);
374 if (maybe_canonical_cert) {
375 digest = calculate_digest_internal(*maybe_canonical_cert.value(), key_type);
382KeyType get_verification_key_type(
const asn1::EtsiTs103097Certificate& cert)
384 KeyType key_type = KeyType::Unspecified;
386 if (cert.toBeSigned.verifyKeyIndicator.present == Vanetza_Security_VerificationKeyIndicator_PR_verificationKey)
388 switch (cert.toBeSigned.verifyKeyIndicator.choice.verificationKey.present)
390 case Vanetza_Security_PublicVerificationKey_PR_ecdsaNistP256:
391 key_type = KeyType::NistP256;
393 case Vanetza_Security_PublicVerificationKey_PR_ecdsaBrainpoolP256r1:
394 key_type = KeyType::BrainpoolP256r1;
396 case Vanetza_Security_PublicVerificationKey_PR_ecdsaBrainpoolP384r1:
397 key_type = KeyType::BrainpoolP384r1;
407boost::optional<PublicKey> get_public_key(
const asn1::EtsiTs103097Certificate& cert)
409 asn1::VerificationKeyIndicator indicator = cert.toBeSigned.verifyKeyIndicator;
410 if (indicator.present != Vanetza_Security_VerificationKeyIndicator_PR_verificationKey) {
414 const asn1::PublicVerificationKey& input = cert.toBeSigned.verifyKeyIndicator.choice.verificationKey;
416 switch (input.present) {
417 case Vanetza_Security_PublicVerificationKey_PR_ecdsaNistP256:
418 output.type = KeyType::NistP256;
419 if (copy_curve_point(output, input.choice.ecdsaNistP256)) {
425 case Vanetza_Security_PublicVerificationKey_PR_ecdsaBrainpoolP256r1:
426 output.type = KeyType::BrainpoolP256r1;
427 if (copy_curve_point(output, input.choice.ecdsaBrainpoolP256r1)) {
433 case Vanetza_Security_PublicVerificationKey_PR_ecdsaBrainpoolP384r1:
434 output.type = KeyType::BrainpoolP384r1;
435 if (copy_curve_point(output, input.choice.ecdsaBrainpoolP384r1)) {
447boost::optional<PublicKey> get_public_encryption_key(
const asn1::EtsiTs103097Certificate& cert)
449 const asn1::PublicEncryptionKey* enc_key = cert.toBeSigned.encryptionKey;
450 if (!enc_key || enc_key->supportedSymmAlg != Vanetza_Security_SymmAlgorithm_aes128Ccm) {
455 switch (enc_key->publicKey.present) {
456 case Vanetza_Security_BasePublicEncryptionKey_PR_eciesNistP256:
457 output.type = KeyType::NistP256;
458 if (copy_curve_point(output, enc_key->publicKey.choice.eciesNistP256)) {
464 case Vanetza_Security_BasePublicEncryptionKey_PR_eciesBrainpoolP256r1:
465 output.type = KeyType::BrainpoolP256r1;
466 if (copy_curve_point(output, enc_key->publicKey.choice.eciesBrainpoolP256r1)) {
478boost::optional<Signature> get_signature(
const asn1::EtsiTs103097Certificate& cert)
480 if (!cert.signature) {
484 const asn1::Signature* asn = cert.signature;
486 switch (asn->present) {
487 case Vanetza_Security_Signature_PR_ecdsaNistP256Signature:
488 sig.type = KeyType::NistP256;
489 sig.r = get_x_coordinate(asn->choice.ecdsaNistP256Signature.rSig);
490 sig.s = fetch_octets(asn->choice.ecdsaNistP256Signature.sSig);
492 case Vanetza_Security_Signature_PR_ecdsaBrainpoolP256r1Signature:
493 sig.type = KeyType::BrainpoolP256r1;
494 sig.r = get_x_coordinate(asn->choice.ecdsaBrainpoolP256r1Signature.rSig);
495 sig.s = fetch_octets(asn->choice.ecdsaBrainpoolP256r1Signature.sSig);
497 case Vanetza_Security_Signature_PR_ecdsaBrainpoolP384r1Signature:
498 sig.type = KeyType::BrainpoolP384r1;
499 sig.r = get_x_coordinate(asn->choice.ecdsaBrainpoolP384r1Signature.rSig);
500 sig.s = fetch_octets(asn->choice.ecdsaBrainpoolP384r1Signature.sSig);
509std::list<ItsAid> get_aids(
const asn1::EtsiTs103097Certificate& cert)
511 std::list<ItsAid> aids;
512 const asn1::SequenceOfPsidSsp* seq = cert.toBeSigned.appPermissions;
514 for (
int i = 0; i < seq->list.count; ++i) {
515 aids.push_back(seq->list.array[i]->psid);
521ByteBuffer get_app_permissions(
const asn1::EtsiTs103097Certificate& cert, ItsAid aid)
524 const asn1::SequenceOfPsidSsp* seq = cert.toBeSigned.appPermissions;
526 for (
int i = 0; i < seq->list.count; ++i) {
527 if (seq->list.array[i]->psid == aid && seq->list.array[i]->ssp !=
nullptr) {
528 const asn1::ServiceSpecificPermissions& ssp = *seq->list.array[i]->ssp;
529 if (ssp.present == Vanetza_Security_ServiceSpecificPermissions_PR_bitmapSsp) {
530 const asn1::BitmapSsp& bitmap = ssp.choice.bitmapSsp;
531 perms.assign(bitmap.buf, bitmap.buf + bitmap.size);
540void add_psid_group_permission(asn1::PsidGroupPermissions* group_permission, ItsAid aid,
const ByteBuffer& ssp,
const ByteBuffer& bitmask)
542 auto psid_range_scr = asn1::allocate<asn1::PsidSspRange>();
543 psid_range_scr->psid = aid;
544 psid_range_scr->sspRange = asn1::allocate<asn1::SspRange>();
545 psid_range_scr->sspRange->present = Vanetza_Security_SspRange_PR_bitmapSspRange;
546 OCTET_STRING_fromBuf(
547 &psid_range_scr->sspRange->choice.bitmapSspRange.sspValue,
548 reinterpret_cast<const char*
>(ssp.data()),
551 OCTET_STRING_fromBuf(
552 &psid_range_scr->sspRange->choice.bitmapSspRange.sspBitmask,
553 reinterpret_cast<const char*
>(bitmask.data()),
556 ASN_SEQUENCE_ADD(&group_permission->subjectPermissions.choice.Explicit, psid_range_scr);
559void add_app_permissions(Certificate& cert, ItsAid aid)
561 asn1::SequenceOfPsidSsp* seq = cert->toBeSigned.appPermissions;
563 seq = asn1::allocate<asn1::SequenceOfPsidSsp>();
564 cert->toBeSigned.appPermissions = seq;
567 auto psid_ptr = asn1::allocate<asn1::PsidSsp>();
568 psid_ptr->psid = aid;
569 ASN_SEQUENCE_ADD(seq, psid_ptr);
572void Certificate::add_permission(ItsAid aid,
const ByteBuffer& ssp)
574 asn1::SequenceOfPsidSsp* seq = m_struct->toBeSigned.appPermissions;
576 seq = asn1::allocate<asn1::SequenceOfPsidSsp>();
577 m_struct->toBeSigned.appPermissions = seq;
580 auto psid_ptr = asn1::allocate<asn1::PsidSsp>();
581 psid_ptr->psid = aid;
582 psid_ptr->ssp = asn1::allocate<asn1::ServiceSpecificPermissions>();
583 psid_ptr->ssp->present = Vanetza_Security_ServiceSpecificPermissions_PR_opaque;
584 OCTET_STRING_fromBuf(
585 &(psid_ptr->ssp->choice.opaque),
586 reinterpret_cast<const char *
>(ssp.data()),
589 ASN_SEQUENCE_ADD(seq, psid_ptr);
593void Certificate::add_cert_permission(asn1::PsidGroupPermissions* group_permission)
595 asn1::SequenceOfPsidGroupPermissions* seq = m_struct->toBeSigned.certIssuePermissions;
597 seq = asn1::allocate<asn1::SequenceOfPsidGroupPermissions>();
598 m_struct->toBeSigned.certIssuePermissions = seq;
600 ASN_SEQUENCE_ADD(seq, group_permission);
603void Certificate::set_signature(
const SomeEcdsaSignature& signature)
605 struct ecc_point_visitor :
public boost::static_visitor<asn1::EccP256CurvePoint>
607 asn1::EccP256CurvePoint operator()(
const X_Coordinate_Only& x_only)
const
609 auto to_return = asn1::allocate<asn1::EccP256CurvePoint>();
610 to_return->present = Vanetza_Security_EccP256CurvePoint_PR_x_only;
611 OCTET_STRING_fromBuf(
612 &(to_return->choice.x_only),
613 reinterpret_cast<const char*
>(x_only.x.data()),
619 asn1::EccP256CurvePoint operator()(
const Compressed_Lsb_Y_0& y0)
const
621 auto to_return = asn1::allocate<asn1::EccP256CurvePoint>();
622 to_return->present = Vanetza_Security_EccP256CurvePoint_PR_compressed_y_0;
623 OCTET_STRING_fromBuf(
624 &(to_return->choice.compressed_y_0),
625 reinterpret_cast<const char*
>(y0.x.data()),
631 asn1::EccP256CurvePoint operator()(
const Compressed_Lsb_Y_1& y1)
const
633 auto to_return = asn1::allocate<asn1::EccP256CurvePoint>();
634 to_return->present = Vanetza_Security_EccP256CurvePoint_PR_compressed_y_1;
635 OCTET_STRING_fromBuf(
636 &(to_return->choice.compressed_y_1),
637 reinterpret_cast<const char*
>(y1.x.data()),
643 asn1::EccP256CurvePoint operator()(
const Uncompressed& unc)
const
645 auto to_return = asn1::allocate<asn1::EccP256CurvePoint>();
646 to_return->present = Vanetza_Security_EccP256CurvePoint_PR_uncompressedP256;
647 OCTET_STRING_fromBuf(
648 &(to_return->choice.uncompressedP256.x),
649 reinterpret_cast<const char*
>(unc.x.data()),
652 OCTET_STRING_fromBuf(
653 &(to_return->choice.uncompressedP256.y),
654 reinterpret_cast<const char*
>(unc.y.data()),
661 struct signature_visitor :
public boost::static_visitor<asn1::Signature*>
663 asn1::Signature* operator()(
const EcdsaSignature& signature)
const
665 auto final_signature = asn1::allocate<asn1::Signature>();
666 final_signature->present = Vanetza_Security_Signature_PR_ecdsaNistP256Signature;
667 OCTET_STRING_fromBuf(
668 &(final_signature->choice.ecdsaNistP256Signature.sSig),
669 reinterpret_cast<const char*
>(signature.s.data()),
672 final_signature->choice.ecdsaNistP256Signature.rSig = boost::apply_visitor(
676 return final_signature;
679 asn1::Signature* operator()(
const EcdsaSignatureFuture& signature)
const
681 return this->operator()(signature.get());
685 m_struct->signature = boost::apply_visitor(signature_visitor(), signature);
688Certificate fake_certificate()
691 certi->issuer.present = Vanetza_Security_IssuerIdentifier_PR_self;
692 certi->toBeSigned.id.present = Vanetza_Security_CertificateId_PR_none;
693 std::vector<uint8_t> craciId(3, 0);
694 OCTET_STRING_fromBuf(
695 &certi->toBeSigned.cracaId,
696 reinterpret_cast<const char*
>(craciId.data()),
700 certi->toBeSigned.crlSeries = 0;
701 certi->toBeSigned.validityPeriod.start = 0;
702 certi->toBeSigned.validityPeriod.duration.present = Vanetza_Security_Duration_PR_minutes;
703 certi->toBeSigned.validityPeriod.duration.choice.minutes = 10080;
704 certi->toBeSigned.verifyKeyIndicator.present = Vanetza_Security_VerificationKeyIndicator_PR_verificationKey;
705 certi->toBeSigned.verifyKeyIndicator.choice.verificationKey.present = Vanetza_Security_PublicVerificationKey_PR_ecdsaNistP256;
706 certi->toBeSigned.verifyKeyIndicator.choice.verificationKey.choice.ecdsaNistP256.present = Vanetza_Security_EccP256CurvePoint_PR_x_only;
707 std::vector<uint8_t> dummy_r(32, 0);
709 OCTET_STRING_fromBuf(
710 &certi->toBeSigned.verifyKeyIndicator.choice.verificationKey.choice.ecdsaNistP256.choice.x_only,
711 reinterpret_cast<const char*
>(dummy_r.data()),
714 certi.add_permission(aid::CA, ByteBuffer({ 1, 0, 0 }));
718void serialize(OutputArchive& ar,
const Certificate& certificate)
720 ByteBuffer buffer = certificate.encode();
721 ar.save_binary(buffer.data(), buffer.size());
727bool copy_curve_point(PublicKey& to,
const asn1::EccP256CurvePoint& from)
730 switch (from.present) {
731 case Vanetza_Security_EccP256CurvePoint_PR_compressed_y_0:
732 to.compression = KeyCompression::Y0;
733 to.x = fetch_octets(from.choice.compressed_y_0);
735 case Vanetza_Security_EccP256CurvePoint_PR_compressed_y_1:
736 to.compression = KeyCompression::Y1;
737 to.x = fetch_octets(from.choice.compressed_y_1);
739 case Vanetza_Security_EccP256CurvePoint_PR_uncompressedP256:
740 to.compression = KeyCompression::NoCompression;
741 to.x = fetch_octets(from.choice.uncompressedP256.x);
742 to.y = fetch_octets(from.choice.uncompressedP256.y);
752bool copy_curve_point(PublicKey& to,
const asn1::EccP384CurvePoint& from)
755 switch (from.present) {
756 case Vanetza_Security_EccP384CurvePoint_PR_compressed_y_0:
757 to.compression = KeyCompression::Y0;
758 to.x = fetch_octets(from.choice.compressed_y_0);
760 case Vanetza_Security_EccP384CurvePoint_PR_compressed_y_1:
761 to.compression = KeyCompression::Y1;
762 to.x = fetch_octets(from.choice.compressed_y_1);
764 case Vanetza_Security_EccP384CurvePoint_PR_uncompressedP384:
765 to.compression = KeyCompression::NoCompression;
766 to.x = fetch_octets(from.choice.uncompressedP384.x);
767 to.y = fetch_octets(from.choice.uncompressedP384.y);
777ByteBuffer fetch_octets(
const OCTET_STRING_t& octets)
779 ByteBuffer buffer(octets.size);
780 std::memcpy(buffer.data(), octets.buf, octets.size);
784ByteBuffer get_x_coordinate(
const asn1::EccP256CurvePoint& point)
786 switch (point.present) {
787 case Vanetza_Security_EccP256CurvePoint_PR_compressed_y_0:
788 return fetch_octets(point.choice.compressed_y_0);
789 case Vanetza_Security_EccP256CurvePoint_PR_compressed_y_1:
790 return fetch_octets(point.choice.compressed_y_1);
791 case Vanetza_Security_EccP256CurvePoint_PR_x_only:
792 return fetch_octets(point.choice.x_only);
793 case Vanetza_Security_EccP256CurvePoint_PR_uncompressedP256:
794 return fetch_octets(point.choice.uncompressedP256.x);
796 return ByteBuffer {};
800ByteBuffer get_x_coordinate(
const asn1::EccP384CurvePoint& point)
802 switch (point.present) {
803 case Vanetza_Security_EccP384CurvePoint_PR_compressed_y_0:
804 return fetch_octets(point.choice.compressed_y_0);
805 case Vanetza_Security_EccP384CurvePoint_PR_compressed_y_1:
806 return fetch_octets(point.choice.compressed_y_1);
807 case Vanetza_Security_EccP384CurvePoint_PR_x_only:
808 return fetch_octets(point.choice.x_only);
809 case Vanetza_Security_EccP384CurvePoint_PR_uncompressedP384:
810 return fetch_octets(point.choice.uncompressedP384.x);
812 return ByteBuffer {};
816bool is_compressed(
const Vanetza_Security_EccP256CurvePoint& point)
818 switch (point.present) {
819 case Vanetza_Security_EccP256CurvePoint_PR_compressed_y_0:
820 case Vanetza_Security_EccP256CurvePoint_PR_compressed_y_1:
827bool is_compressed(
const Vanetza_Security_EccP384CurvePoint& point)
829 switch (point.present) {
830 case Vanetza_Security_EccP384CurvePoint_PR_compressed_y_0:
831 case Vanetza_Security_EccP384CurvePoint_PR_compressed_y_1:
838bool is_signature_x_only(
const Vanetza_Security_Signature_t& sig)
840 switch (sig.present) {
841 case Vanetza_Security_Signature_PR_ecdsaNistP256Signature:
842 return sig.choice.ecdsaNistP256Signature.rSig.present == Vanetza_Security_EccP256CurvePoint_PR_x_only;
843 case Vanetza_Security_Signature_PR_ecdsaBrainpoolP256r1Signature:
844 return sig.choice.ecdsaBrainpoolP256r1Signature.rSig.present == Vanetza_Security_EccP256CurvePoint_PR_x_only;
845 case Vanetza_Security_Signature_PR_ecdsaBrainpoolP384r1Signature:
846 return sig.choice.ecdsaBrainpoolP384r1Signature.rSig.present == Vanetza_Security_EccP384CurvePoint_PR_x_only;
852bool compress(Vanetza_Security_EccP256CurvePoint& point)
854 if (point.present == Vanetza_Security_EccP256CurvePoint_PR_uncompressedP256) {
855 auto& unc = point.choice.uncompressedP256;
856 if (unc.y.size > 0 && unc.y.buf[unc.y.size - 1] & 0x01) {
857 assert(&point.choice.uncompressedP256.x == &point.choice.compressed_y_1);
858 point.present = Vanetza_Security_EccP256CurvePoint_PR_compressed_y_1;
860 assert(&point.choice.uncompressedP256.x == &point.choice.compressed_y_0);
861 point.present = Vanetza_Security_EccP256CurvePoint_PR_compressed_y_0;
864 }
else if (point.present == Vanetza_Security_EccP256CurvePoint_PR_compressed_y_0 || point.present == Vanetza_Security_EccP256CurvePoint_PR_compressed_y_1) {
871bool compress(Vanetza_Security_EccP384CurvePoint& point)
873 if (point.present == Vanetza_Security_EccP384CurvePoint_PR_uncompressedP384) {
874 auto& unc = point.choice.uncompressedP384;
875 if (unc.y.size > 0 && unc.y.buf[unc.y.size - 1] & 0x01) {
876 assert(&point.choice.uncompressedP384.x == &point.choice.compressed_y_1);
877 point.present = Vanetza_Security_EccP384CurvePoint_PR_compressed_y_1;
879 assert(&point.choice.uncompressedP384.x == &point.choice.compressed_y_0);
880 point.present = Vanetza_Security_EccP384CurvePoint_PR_compressed_y_0;
883 }
else if (point.present == Vanetza_Security_EccP384CurvePoint_PR_compressed_y_0 || point.present == Vanetza_Security_EccP384CurvePoint_PR_compressed_y_1) {
890bool make_x_only(Vanetza_Security_EccP256CurvePoint& point)
892 if (point.present == Vanetza_Security_EccP256CurvePoint_PR_uncompressedP256) {
893 assert(&point.choice.uncompressedP256.x == &point.choice.x_only);
894 point.present = Vanetza_Security_EccP256CurvePoint_PR_x_only;
896 }
else if (point.present == Vanetza_Security_EccP256CurvePoint_PR_x_only) {
903bool make_x_only(Vanetza_Security_EccP384CurvePoint& point)
905 if (point.present == Vanetza_Security_EccP384CurvePoint_PR_uncompressedP384) {
906 assert(&point.choice.uncompressedP384.x == &point.choice.x_only);
907 point.present = Vanetza_Security_EccP384CurvePoint_PR_x_only;
909 }
else if (point.present == Vanetza_Security_EccP384CurvePoint_PR_x_only) {
916bool make_signature_x_only(Vanetza_Security_Signature& sig)
918 switch (sig.present) {
919 case Vanetza_Security_Signature_PR_ecdsaNistP256Signature:
920 return make_x_only(sig.choice.ecdsaNistP256Signature.rSig);
922 case Vanetza_Security_Signature_PR_ecdsaBrainpoolP256r1Signature:
923 return make_x_only(sig.choice.ecdsaBrainpoolP256r1Signature.rSig);
925 case Vanetza_Security_Signature_PR_ecdsaBrainpoolP384r1Signature:
926 return make_x_only(sig.choice.ecdsaBrainpoolP384r1Signature.rSig);
ByteBuffer encode() const
boost::optional< Certificate > canonicalize() const
bool valid_at_timepoint(const Clock::time_point &time_point) const
StartAndEndValidity get_start_and_end_validity() const
bool is_at_certificate() const
bool is_ca_certificate() const
bool issuer_is_self() const
bool valid_for_application(ItsAid aid) const
boost::optional< HashedId8 > calculate_digest() const
bool valid_at_location(const PositionFix &location, const LocationChecker *lc) const
bool has_region_restriction() const
boost::optional< HashedId8 > issuer_digest() const
KeyType get_verification_key_type() const
bool is_canonical() const