esp8266ndn
NDN Arduino library for ESP8266 and more
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ec.hpp
Go to the documentation of this file.
1#ifndef NDNPH_KEYCHAIN_EC_HPP
2#define NDNPH_KEYCHAIN_EC_HPP
3
4#include "../port/ec/port.hpp"
5#include "certificate.hpp"
6#include "keychain.hpp"
7
8namespace ndnph {
9namespace ec {
10namespace detail {
11
12using namespace ndnph::detail;
13
14using PvtLen = port::Ec::Curve::PvtLen;
15using PubLen = port::Ec::Curve::PubLen;
16
18inline tlv::Value
20 static const uint8_t bytes[] = {
21 0x30, 0x59, // SEQUENCE
22 0x30, 0x13, // . SEQUENCE
23 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, // .. OID ecPublicKey
24 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, // .. OID prime256v1
25 0x03, 0x42, 0x00 // . BIT STRING
26 };
27 static const tlv::Value value(bytes, sizeof(bytes));
28 return value;
29}
30
32inline tlv::Value
34 static const tlv::Value value(getSpkiHeader().begin() + 4, 9);
35 return value;
36}
37
42inline const uint8_t*
44 if (!certificate::isCertificate(data)) {
45 return nullptr;
46 }
47
48 auto content = data.getContent();
49 if (content.size() < PubLen::value) {
50 return nullptr;
51 }
52
53 auto oid = getOid();
54 auto found = std::search(content.begin(), content.end(), oid.begin(), oid.end());
55 if (found == content.end()) {
56 return nullptr;
57 }
58
59 return content.end() - PubLen::value;
60}
61
62} // namespace detail
63
65class EcPublicKey : public detail::NamedPublicKey<SigType::Sha256WithEcdsa> {
66public:
68
70 explicit operator bool() const {
71 return m_key != nullptr;
72 }
73
80 bool import(const Name& name, const uint8_t raw[KeyLen::value]) {
81 if (!certificate::isKeyName(name)) {
82 return false;
83 }
84
85 m_key.reset(new port::Ec::PublicKey());
86 if (!m_key->import(raw)) {
87 m_key.reset();
88 return false;
89 }
90
91 setName(name);
92 std::copy_n(raw, sizeof(m_raw), m_raw);
93 return true;
94 }
95
102 bool import(Region& region, const Data& data) {
103 const uint8_t* raw = detail::findPublicKeyInCertificate(data);
104 if (raw == nullptr) {
105 return false;
106 }
107
108 Name name = certificate::toKeyName(region, data.getName());
109 if (!name) {
110 return false;
111 }
112
113 return import(name, raw);
114 }
115
126 template<typename Signer>
127 Data::Signed buildCertificate(Region& region, const Name& name, const ValidityPeriod& validity,
128 const Signer& signer) const {
129 return detail::buildCertificate(region, name, validity, signer, [&](Data& data) {
130 auto spkiHdr = detail::getSpkiHeader();
131 size_t spkiLen = spkiHdr.size() + KeyLen::value;
132 uint8_t* spki = region.alloc(spkiLen);
133 if (spki == nullptr) {
134 return false;
135 }
136
137 auto pos = std::copy_n(spkiHdr.begin(), spkiHdr.size(), spki);
138 std::copy_n(m_raw, KeyLen::value, pos);
139 data.setContent(tlv::Value(spki, spkiLen));
140 return true;
141 });
142 }
143
153 template<typename Signer>
154 Data::Signed selfSign(Region& region, const ValidityPeriod& validity,
155 const Signer& signer) const {
157 return buildCertificate(region, certName, validity, signer);
158 }
159
165 bool verify(std::initializer_list<tlv::Value> chunks, const uint8_t* sig,
166 size_t sigLen) const final {
167 if (m_key == nullptr) {
168 return false;
169 }
170 uint8_t digest[NDNPH_SHA256_LEN];
171 return detail::computeDigest(chunks, digest) && m_key->verify(digest, sig, sigLen);
172 }
173
174private:
175 std::unique_ptr<port::Ec::PublicKey> m_key;
176 uint8_t m_raw[KeyLen::value];
177};
178
180class EcPrivateKey : public detail::NamedPrivateKey<SigType::Sha256WithEcdsa> {
181public:
183 using MaxSigLen = port::Ec::Curve::MaxSigLen;
184
186 explicit operator bool() const {
187 return m_key != nullptr;
188 }
189
194 bool import(const Name& name, const uint8_t raw[KeyLen::value]) {
195 if (!certificate::isKeyName(name)) {
196 return false;
197 }
198
199 m_key.reset(new port::Ec::PrivateKey());
200 if (!m_key->import(raw)) {
201 m_key.reset();
202 return false;
203 }
204
205 setName(name);
206 return true;
207 }
208
209 size_t getMaxSigLen() const final {
210 return MaxSigLen::value;
211 }
212
213 ssize_t sign(std::initializer_list<tlv::Value> chunks, uint8_t* sig) const final {
214 if (m_key == nullptr) {
215 return -1;
216 }
217 uint8_t digest[NDNPH_SHA256_LEN];
218 if (!detail::computeDigest(chunks, digest)) {
219 return -1;
220 }
221 return m_key->sign(digest, sig);
222 }
223
224private:
225 std::unique_ptr<port::Ec::PrivateKey> m_key;
226};
227
232inline bool
233generateRaw(uint8_t pvt[EcPrivateKey::KeyLen::value], uint8_t pub[EcPublicKey::KeyLen::value]) {
234 return port::Ec::generateKey(pvt, pub);
235}
236
237namespace detail {
238
240struct StoredKeyPair {
241 uint8_t pvt[PvtLen::value];
242 uint8_t pub[PubLen::value];
243};
244
245inline bool
246generate(Region& region, const Name& name, EcPrivateKey& pvt, EcPublicKey& pub, KeyChain* keyChain,
247 const char* id) {
248 Name keyName = certificate::toKeyName(region, name, true);
249 if (!keyName) {
250 return false;
251 }
252
253 ScopedEncoder encoder(region);
254 encoder.prepend(keyName);
255 auto stored = reinterpret_cast<StoredKeyPair*>(encoder.prependRoom(sizeof(StoredKeyPair)));
256 bool ok = stored != nullptr && generateRaw(stored->pvt, stored->pub) &&
257 pvt.import(keyName, stored->pvt) && pub.import(keyName, stored->pub);
258
259 if (keyChain != nullptr) {
260 ok = ok && keyChain->keys.set(id, tlv::Value(encoder));
261 }
262 return ok;
263}
264
265} // namespace detail
266
275inline bool
276generate(Region& region, const Name& name, EcPrivateKey& pvt, EcPublicKey& pub) {
277 return detail::generate(region, name, pvt, pub, nullptr, nullptr);
278}
279
290inline bool
291generate(Region& region, const Name& name, EcPrivateKey& pvt, EcPublicKey& pub, KeyChain& keyChain,
292 const char* id) {
293 return detail::generate(region, name, pvt, pub, &keyChain, id);
294}
295
300inline bool
301load(KeyChain& keyChain, const char* id, Region& region, EcPrivateKey& pvt, EcPublicKey& pub) {
302 tlv::Value storedObject = keyChain.keys.get(id, region);
303 if (storedObject.size() < sizeof(detail::StoredKeyPair)) {
304 return false;
305 }
306 auto stored = reinterpret_cast<const detail::StoredKeyPair*>(storedObject.begin());
307 Name name;
308 Decoder decoder(storedObject.begin() + sizeof(detail::StoredKeyPair),
309 storedObject.size() - sizeof(detail::StoredKeyPair));
310 return decoder.decode(name) && pvt.import(name, stored->pvt) && pub.import(name, stored->pub);
311}
312
318inline bool
319isCertificate(const Data& data) {
320 return detail::findPublicKeyInCertificate(data) != nullptr;
321}
322
323} // namespace ec
324
327
328} // namespace ndnph
329
330#endif // NDNPH_KEYCHAIN_EC_HPP
Data packet.
Definition data.hpp:136
void setContent(tlv::Value v)
Definition data.hpp:176
tlv::Value getContent() const
Definition data.hpp:172
TLV decoder.
Definition decoder.hpp:10
bool decode(T &target) const
Decode first TLV into target object.
Definition decoder.hpp:158
File based key and certificate store.
Definition keychain.hpp:36
KeyChainKeys keys
Definition keychain.hpp:51
tlv::Value get(const char *key, Region &region)
Retrieve a value.
Definition kv.hpp:38
bool set(const char *key, tlv::Value value)
Store a value.
Definition kv.hpp:69
Name.
Definition name.hpp:14
Region-based memory allocator thats owns memory of NDNph objects.
Definition region.hpp:9
uint8_t * alloc(size_t size)
Allocate a buffer with no alignment requirement.
Definition region.hpp:27
Encoder that auto-discards upon destruction.
Definition encoder.hpp:198
ValidityPeriod of a certificate.
Definition validity-period.hpp:37
void setName(const Name &v)
Assign KeyLocator name.
Definition helper.hpp:40
const Name & getName() const
Retrieve KeyLocator name.
Definition helper.hpp:35
Definition helper.hpp:64
Definition helper.hpp:54
Definition data.hpp:42
EC private key.
Definition ec.hpp:180
bool import(const Name &name, const uint8_t raw[KeyLen::value])
Import a private key from raw key bits.
Definition ec.hpp:194
detail::PvtLen KeyLen
Definition ec.hpp:182
ssize_t sign(std::initializer_list< tlv::Value > chunks, uint8_t *sig) const final
Perform signing.
Definition ec.hpp:213
size_t getMaxSigLen() const final
Definition ec.hpp:209
port::Ec::Curve::MaxSigLen MaxSigLen
Definition ec.hpp:183
EC public key.
Definition ec.hpp:65
Data::Signed buildCertificate(Region &region, const Name &name, const ValidityPeriod &validity, const Signer &signer) const
Generate certificate of this public key.
Definition ec.hpp:127
bool verify(std::initializer_list< tlv::Value > chunks, const uint8_t *sig, size_t sigLen) const final
Perform verification.
Definition ec.hpp:165
detail::PubLen KeyLen
Definition ec.hpp:67
bool import(const Name &name, const uint8_t raw[KeyLen::value])
Import from raw key bits.
Definition ec.hpp:80
Data::Signed selfSign(Region &region, const ValidityPeriod &validity, const Signer &signer) const
Generate self-signed certificate of this public key.
Definition ec.hpp:154
Definition mbed.hpp:82
Definition mbed.hpp:55
static bool generateKey(uint8_t *pvt, uint8_t *pub)
Definition mbed.hpp:125
A sequence of bytes, usually TLV-VALUE.
Definition value.hpp:11
const uint8_t * begin() const
Definition value.hpp:38
size_t size() const
Definition value.hpp:46
#define NDNPH_SHA256_LEN
SHA256 digest length.
Definition common.hpp:34
bool isCertificate(const Data &data)
Determine if the Data packet is a certificate.
Definition certificate.hpp:170
bool isKeyName(const Name &name)
Determine if the input is a key name.
Definition certificate.hpp:37
Component getIssuerSelf()
Return 'self' component as self-signed issuerId.
Definition certificate.hpp:29
Name toKeyName(Region &region, const Name &input, bool mustCopy=false)
Convert to key name.
Definition certificate.hpp:82
Name makeCertName(Region &region, const Name &input, const Component &issuerId, const Component &version)
Construct certificate name with specified issuerId and version.
Definition certificate.hpp:149
Definition input-iterator-pointer-proxy.hpp:5
Data::Signed buildCertificate(Region &region, const Name &name, const ValidityPeriod &validity, const Signer &signer, const Modify &modify)
Definition certificate.hpp:207
bool computeDigest(std::initializer_list< tlv::Value > chunks, uint8_t digest[NDNPH_SHA256_LEN])
Definition helper.hpp:15
port::Ec::Curve::PvtLen PvtLen
Definition ec.hpp:14
const uint8_t * findPublicKeyInCertificate(const Data &data)
Extract raw public key from a certificate.
Definition ec.hpp:43
port::Ec::Curve::PubLen PubLen
Definition ec.hpp:15
tlv::Value getSpkiHeader()
Return EC P-256 SPKI except the key.
Definition ec.hpp:19
tlv::Value getOid()
Return '1.2.840.10045.2.1 ecPublicKey' OID bytes.
Definition ec.hpp:33
bool generateRaw(uint8_t pvt[EcPrivateKey::KeyLen::value], uint8_t pub[EcPublicKey::KeyLen::value])
Generate key pair in raw format.
Definition ec.hpp:233
bool generate(Region &region, const Name &name, EcPrivateKey &pvt, EcPublicKey &pub)
Generate key pair.
Definition ec.hpp:276
bool isCertificate(const Data &data)
Determine if the Data packet is a certificate that contains an EC public key.
Definition ec.hpp:319
bool load(KeyChain &keyChain, const char *id, Region &region, EcPrivateKey &pvt, EcPublicKey &pub)
Load key pair from KeyChain.
Definition ec.hpp:301
Definition fs.hpp:33