Vanetza
 
Loading...
Searching...
No Matches
certificate.cpp
1#include <vanetza/security/sha.hpp>
2#include <vanetza/security/v3/certificate.hpp>
3#include <boost/optional/optional.hpp>
4#include <cstring>
5
6namespace vanetza
7{
8namespace security
9{
10namespace v3
11{
12
13namespace
14{
15bool copy_curve_point(PublicKey& to, const EccP256CurvePoint_t& from);
16bool copy_curve_point(PublicKey& to, const EccP384CurvePoint_t& from);
17ByteBuffer fetch_octets(const OCTET_STRING_t& octets);
18}
19
20Certificate::Certificate() :
21 asn1::asn1c_oer_wrapper<EtsiTs103097Certificate_t>(asn_DEF_EtsiTs103097Certificate)
22{
23}
24
25boost::optional<HashedId8> calculate_hash(const EtsiTs103097Certificate_t& cert)
26{
27 VerificationKeyIndicator_t indicator = cert.toBeSigned.verifyKeyIndicator;
28 if (indicator.present != VerificationKeyIndicator_PR_verificationKey) {
29 return boost::none;
30 }
31
32 ByteBuffer buffer = asn1::encode_oer(asn_DEF_EtsiTs103097Certificate, &cert);
33 switch (indicator.choice.verificationKey.present)
34 {
35 case PublicVerificationKey_PR_ecdsaNistP256:
36 case PublicVerificationKey_PR_ecdsaBrainpoolP256r1:
37 return create_hashed_id8(calculate_sha256_digest(buffer.data(), buffer.size()));
38 break;
39 case PublicVerificationKey_PR_ecdsaBrainpoolP384r1:
40 return create_hashed_id8(calculate_sha384_digest(buffer.data(), buffer.size()));
41 break;
42 default:
43 return boost::none;
44 break;
45 }
46}
47
48boost::optional<PublicKey> get_public_key(const EtsiTs103097Certificate_t& cert)
49{
50 VerificationKeyIndicator_t indicator = cert.toBeSigned.verifyKeyIndicator;
51 if (indicator.present != VerificationKeyIndicator_PR_verificationKey) {
52 return boost::none;
53 }
54
55 const PublicVerificationKey_t& input = cert.toBeSigned.verifyKeyIndicator.choice.verificationKey;
56 PublicKey output;
57 switch (input.present) {
58 case PublicVerificationKey_PR_ecdsaNistP256:
59 output.type = KeyType::NistP256;
60 if (copy_curve_point(output, input.choice.ecdsaNistP256)) {
61 return output;
62 } else {
63 return boost::none;
64 }
65 break;
66 case PublicVerificationKey_PR_ecdsaBrainpoolP256r1:
67 output.type = KeyType::BrainpoolP256r1;
68 if (copy_curve_point(output, input.choice.ecdsaBrainpoolP256r1)) {
69 return output;
70 } else {
71 return boost::none;
72 }
73 break;
74 case PublicVerificationKey_PR_ecdsaBrainpoolP384r1:
75 output.type = KeyType::BrainpoolP384r1;
76 if (copy_curve_point(output, input.choice.ecdsaBrainpoolP384r1)) {
77 return output;
78 } else {
79 return boost::none;
80 }
81 break;
82 default:
83 return boost::none;
84 break;
85 }
86}
87
88ByteBuffer get_app_permissions(const EtsiTs103097Certificate_t& cert, ItsAid aid)
89{
90 ByteBuffer perms;
91 const SequenceOfPsidSsp_t* seq = cert.toBeSigned.appPermissions;
92 if (seq) {
93 for (int i = 0; i < seq->list.count; ++i) {
94 if (seq->list.array[i]->psid == aid && seq->list.array[i]->ssp != nullptr) {
95 const ServiceSpecificPermissions_t& ssp = *seq->list.array[i]->ssp;
96 if (ssp.present == ServiceSpecificPermissions_PR_bitmapSsp) {
97 const BitmapSsp_t& bitmap = ssp.choice.bitmapSsp;
98 perms.assign(bitmap.buf, bitmap.buf + bitmap.size);
99 break;
100 }
101 }
102 }
103 }
104 return perms;
105}
106
107namespace
108{
109
110bool copy_curve_point(PublicKey& to, const EccP256CurvePoint_t& from)
111{
112 bool copied = true;
113 switch (from.present) {
114 case EccP256CurvePoint_PR_compressed_y_0:
115 to.compression = KeyCompression::Y0;
116 to.x = fetch_octets(from.choice.compressed_y_0);
117 break;
118 case EccP256CurvePoint_PR_compressed_y_1:
119 to.compression = KeyCompression::Y1;
120 to.x = fetch_octets(from.choice.compressed_y_1);
121 break;
122 case EccP256CurvePoint_PR_uncompressedP256:
123 to.compression = KeyCompression::NoCompression;
124 to.x = fetch_octets(from.choice.uncompressedP256.x);
125 to.y = fetch_octets(from.choice.uncompressedP256.y);
126 break;
127 default:
128 copied = false;
129 break;
130 }
131
132 return copied;
133}
134
135bool copy_curve_point(PublicKey& to, const EccP384CurvePoint_t& from)
136{
137 bool copied = true;
138 switch (from.present) {
139 case EccP384CurvePoint_PR_compressed_y_0:
140 to.compression = KeyCompression::Y0;
141 to.x = fetch_octets(from.choice.compressed_y_0);
142 break;
143 case EccP384CurvePoint_PR_compressed_y_1:
144 to.compression = KeyCompression::Y1;
145 to.x = fetch_octets(from.choice.compressed_y_1);
146 break;
147 case EccP384CurvePoint_PR_uncompressedP384:
148 to.compression = KeyCompression::NoCompression;
149 to.x = fetch_octets(from.choice.uncompressedP384.x);
150 to.y = fetch_octets(from.choice.uncompressedP384.y);
151 break;
152 default:
153 copied = false;
154 break;
155 }
156
157 return copied;
158}
159
160ByteBuffer fetch_octets(const OCTET_STRING_t& octets)
161{
162 ByteBuffer buffer(octets.size);
163 std::memcpy(buffer.data(), octets.buf, octets.size);
164 return buffer;
165}
166
167} // namespace
168
169} // namespace v3
170} // namespace security
171} // namespace vanetza