Vanetza
Loading...
Searching...
No Matches
hybrid_certificate_validator.cpp
1#include <vanetza/security/pqc/hybrid_certificate_validator.hpp>
2#include <vanetza/security/pqc/hybrid_certificate.hpp>
3#include <vanetza/security/backend.hpp>
4#include <vanetza/security/v3/certificate.hpp>
5#include <vanetza/security/v3/issuer_lookup.hpp>
6#include <vanetza/security/v3/trust_store.hpp>
7
8namespace vanetza
9{
10namespace security
11{
12namespace pqc
13{
14
16 const v3::CertificateView& certificate, ItsAid aid) -> Verdict
17{
18 const Verdict policy_verdict = m_policy_validator.valid_for_signing(certificate, aid);
19 if (policy_verdict != Verdict::Valid) {
20 return policy_verdict;
21 }
22 if (!m_issuer_lookup || !m_trust_store || !m_ecc_backend ||
23 (m_verification_policy != VerificationPolicy::ClassicalOnly && !m_pqc_backend)) {
24 return Verdict::Misconfiguration;
25 }
26 return chain_is_authentic(certificate) ? Verdict::Valid : Verdict::Untrusted;
27}
28
29void HybridCertificateValidator::use_runtime(const Runtime* runtime)
30{
31 m_policy_validator.use_runtime(runtime);
32}
33
34void HybridCertificateValidator::use_position_provider(PositionProvider* provider)
35{
36 m_policy_validator.use_position_provider(provider);
37}
38
39void HybridCertificateValidator::use_issuer_lookup(const v3::IssuerLookup* lookup)
40{
41 m_issuer_lookup = lookup;
42 m_policy_validator.use_issuer_lookup(lookup);
43}
44
45void HybridCertificateValidator::use_location_checker(const v3::LocationChecker* checker)
46{
47 m_policy_validator.use_location_checker(checker);
48}
49
50void HybridCertificateValidator::use_revocation_lookup(const v3::RevocationLookup* lookup)
51{
52 m_policy_validator.use_revocation_lookup(lookup);
53}
54
55void HybridCertificateValidator::use_trust_store(const v3::TrustStore* store)
56{
57 m_trust_store = store;
58 m_policy_validator.use_trust_store(store);
59}
60
61void HybridCertificateValidator::use_backends(
62 ::vanetza::security::Backend* ecc, Backend* pqc_backend)
63{
64 m_ecc_backend = ecc;
65 m_pqc_backend = pqc_backend;
66}
67
68void HybridCertificateValidator::use_verification_policy(VerificationPolicy policy)
69{
70 m_verification_policy = policy;
71}
72
73void HybridCertificateValidator::disable_time_checks(bool disable)
74{
75 m_policy_validator.disable_time_checks(disable);
76}
77
78void HybridCertificateValidator::disable_location_checks(bool disable)
79{
80 m_policy_validator.disable_location_checks(disable);
81}
82
83void HybridCertificateValidator::disable_chain_consistency_checks(bool disable)
84{
85 m_policy_validator.disable_chain_consistency_checks(disable);
86}
87
88void HybridCertificateValidator::disable_region_consistency_checks(bool disable)
89{
90 m_policy_validator.disable_region_consistency_checks(disable);
91}
92
93bool HybridCertificateValidator::alternative_signature_is_accepted(
94 const v3::CertificateView& subject, const v3::CertificateView* issuer) const
95{
96 if (m_verification_policy == VerificationPolicy::ClassicalOnly) {
97 return true;
98 }
99
100 const auto state = alternative_material_state(subject);
101 if (state == MaterialState::Inconsistent) {
102 return false;
103 }
104 if (state == MaterialState::None) {
105 return m_verification_policy == VerificationPolicy::HybridIfPresent;
106 }
107
108 return m_pqc_backend && verify_alternative_certificate(
109 subject, issuer, *m_ecc_backend, *m_pqc_backend);
110}
111
112bool HybridCertificateValidator::chain_is_authentic(
113 const v3::CertificateView& signing_certificate) const
114{
115 constexpr int maximum_chain_depth = 8;
116 const v3::CertificateView* subject = &signing_certificate;
117
118 for (int depth = 0; depth < maximum_chain_depth; ++depth) {
119 if (subject->issuer_is_self()) {
120 const auto root_digest = subject->calculate_digest();
121 if (!root_digest || m_trust_store->lookup(*root_digest).empty()) {
122 return false;
123 }
124 return verify_primary_certificate(*subject, nullptr, *m_ecc_backend) &&
125 alternative_signature_is_accepted(*subject, nullptr);
126 }
127
128 const auto expected_issuer_digest = subject->issuer_digest();
129 if (!expected_issuer_digest) {
130 return false;
131 }
132 const v3::Certificate* issuer = m_issuer_lookup->find_issuer(*expected_issuer_digest);
133 if (!issuer) {
134 return false;
135 }
136 const auto actual_issuer_digest = issuer->calculate_digest();
137 if (!actual_issuer_digest || *actual_issuer_digest != *expected_issuer_digest) {
138 return false;
139 }
140
141 if (!verify_primary_certificate(*subject, issuer, *m_ecc_backend) ||
142 !alternative_signature_is_accepted(*subject, issuer)) {
143 return false;
144 }
145 subject = issuer;
146 }
147
148 return false;
149}
150
151} // namespace pqc
152} // namespace security
153} // namespace vanetza
Verdict valid_for_signing(const v3::CertificateView &, ItsAid) override
boost::optional< HashedId8 > calculate_digest() const
boost::optional< HashedId8 > issuer_digest() const
Verdict valid_for_signing(const CertificateView &, ItsAid) override
virtual const Certificate * find_issuer(const HashedId8 &digest) const =0