Vanetza
 
Loading...
Searching...
No Matches
signature.cpp
1#include <vanetza/security/exception.hpp>
2#include <vanetza/security/v2/signature.hpp>
3#include <boost/iostreams/stream.hpp>
4#include <cassert>
5
6namespace vanetza
7{
8namespace security
9{
10namespace v2
11{
12
13PublicKeyAlgorithm get_type(const Signature& sig)
14{
15 struct Signature_visitor : public boost::static_visitor<PublicKeyAlgorithm>
16 {
17 PublicKeyAlgorithm operator()(const EcdsaSignature& sig)
18 {
19 return PublicKeyAlgorithm::ECDSA_NISTP256_With_SHA256;
20 }
21
22 PublicKeyAlgorithm operator()(const EcdsaSignatureFuture& sig)
23 {
24 return PublicKeyAlgorithm::ECDSA_NISTP256_With_SHA256;
25 }
26 };
27 Signature_visitor visit;
28 return boost::apply_visitor(visit, sig.some_ecdsa);
29}
30
31size_t get_size(const EcdsaSignature& sig)
32{
33 size_t size = sig.s.size();
34 size += get_size(sig.R);
35 return size;
36}
37
38size_t get_size(const EcdsaSignatureFuture& sig)
39{
40 return sig.size();
41}
42
43size_t get_size(const Signature& sig)
44{
45 size_t size = sizeof(PublicKeyAlgorithm);
46 struct Signature_visitor : public boost::static_visitor<size_t>
47 {
48 size_t operator()(const EcdsaSignature& sig)
49 {
50 return get_size(sig);
51 }
52
53 size_t operator()(const EcdsaSignatureFuture& sig)
54 {
55 return get_size(sig);
56 }
57 };
58 Signature_visitor visit;
59 size += boost::apply_visitor(visit, sig.some_ecdsa);
60 return size;
61}
62
63void serialize(OutputArchive& ar, const Signature& sig)
64{
65 struct signature_visitor : public boost::static_visitor<>
66 {
67 signature_visitor(OutputArchive& ar) : m_archive(ar) {}
68
69 void operator()(const EcdsaSignature& sig)
70 {
71 serialize(m_archive, sig);
72 }
73
74 void operator()(const EcdsaSignatureFuture& sig)
75 {
76 serialize(m_archive, sig);
77 }
78
79 OutputArchive& m_archive;
80 };
81
82 PublicKeyAlgorithm algo = get_type(sig);
83 serialize(ar, algo);
84 signature_visitor visitor(ar);
85 boost::apply_visitor(visitor, sig.some_ecdsa);
86}
87
88void serialize(OutputArchive& ar, const EcdsaSignature& sig)
89{
90 const PublicKeyAlgorithm algo = PublicKeyAlgorithm::ECDSA_NISTP256_With_SHA256;
91 assert(field_size(algo) == sig.s.size());
92
93 serialize(ar, sig.R, algo);
94 for (auto& byte : sig.s) {
95 ar << byte;
96 }
97}
98
99void serialize(OutputArchive& ar, const EcdsaSignatureFuture& sig)
100{
101 auto& ecdsa = sig.get();
102 serialize(ar, ecdsa);
103}
104
105size_t deserialize(InputArchive& ar, EcdsaSignature& sig, const PublicKeyAlgorithm& algo)
106{
107 EccPoint point;
108 ByteBuffer buf;
109 deserialize(ar, point, algo);
110 for (size_t i = 0; i < field_size(algo); i++) {
111 uint8_t byte;
112 ar >> byte;
113 buf.push_back(byte);
114 }
115 sig.R = point;
116 sig.s = buf;
117 return get_size(sig);
118}
119
120size_t deserialize(InputArchive& ar, Signature& sig)
121{
122 PublicKeyAlgorithm algo;
123 size_t size = 0;
124 deserialize(ar, algo);
125 size += sizeof(algo);
126 switch (algo) {
127 case PublicKeyAlgorithm::ECDSA_NISTP256_With_SHA256: {
128 EcdsaSignature signature;
129 size += deserialize(ar, signature, algo);
130 sig = signature;
131 break;
132 }
133 default:
134 throw deserialization_error("Unknown PublicKeyAlgorithm");
135 }
136 return size;
137}
138
139boost::optional<EcdsaSignature> extract_ecdsa_signature(const Signature& sig)
140{
141 struct signature_visitor : public boost::static_visitor<const EcdsaSignature*>
142 {
143 const EcdsaSignature* operator()(const EcdsaSignature& sig)
144 {
145 return &sig;
146 }
147
148 const EcdsaSignature* operator()(const EcdsaSignatureFuture& sig)
149 {
150 return &sig.get();
151 }
152 };
153
154 signature_visitor visitor;
155 const EcdsaSignature* ecdsa = boost::apply_visitor(visitor, sig.some_ecdsa);
156 return boost::optional<EcdsaSignature>(ecdsa != nullptr, *ecdsa);
157}
158
159} // namespace v2
160} // namespace security
161} // namespace vanetza