ndn-cxx: NDN C++ Library 0.9.0-33-g832ea91d
Loading...
Searching...
No Matches
key-chain.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013-2024 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
25
26#include "ndn-cxx/security/pib/impl/pib-memory.hpp"
27#include "ndn-cxx/security/pib/impl/pib-sqlite3.hpp"
28
29#include "ndn-cxx/security/tpm/impl/back-end-file.hpp"
30#include "ndn-cxx/security/tpm/impl/back-end-mem.hpp"
31#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
32#include "ndn-cxx/security/tpm/impl/back-end-osx.hpp"
33#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
34
40
45
46#include <boost/lexical_cast.hpp>
47#include <cstdlib> // for std::getenv()
48
49namespace ndn::security {
50
52
53// When static library is used, not everything is compiled into the resulting binary.
54// Therefore, the following standard PIB and TPMs need to be registered here.
55// http://stackoverflow.com/q/9459980/2150331
56
57namespace pib {
60} // namespace pib
61
62namespace tpm {
63#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
65#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
68} // namespace tpm
69
70const name::Component SELF{"self"};
71
72KeyChain::PibFactories&
73KeyChain::getPibFactories()
74{
75 static PibFactories pibFactories;
76 return pibFactories;
77}
78
79KeyChain::TpmFactories&
80KeyChain::getTpmFactories()
81{
82 static TpmFactories tpmFactories;
83 return tpmFactories;
84}
85
86static const auto&
87getDefaultPibScheme()
88{
89 return pib::PibSqlite3::getScheme();
90}
91
92static const auto&
93getDefaultTpmScheme()
94{
95#ifdef NDN_CXX_WITH_OSX_KEYCHAIN
96 return tpm::BackEndOsx::getScheme();
97#else
98 return tpm::BackEndFile::getScheme();
99#endif // NDN_CXX_WITH_OSX_KEYCHAIN
100}
101
102const KeyParams&
104{
105 static EcKeyParams keyParams;
106 return keyParams;
107}
108
109//
110
111class KeyChain::Locator
112{
113public:
114 [[nodiscard]] bool
115 empty() const noexcept
116 {
117 return scheme.empty();
118 }
119
120 [[nodiscard]] std::string
121 canonical() const
122 {
123 return scheme + ':' + location;
124 }
125
126 friend bool
127 operator==(const Locator& lhs, const Locator& rhs) noexcept
128 {
129 return lhs.scheme == rhs.scheme && lhs.location == rhs.location;
130 }
131
132public:
133 std::string scheme;
134 std::string location;
135};
136
137KeyChain::Locator KeyChain::s_defaultPibLocator;
138KeyChain::Locator KeyChain::s_defaultTpmLocator;
139
140//
141
143 : KeyChain(getDefaultPibLocator(), getDefaultTpmLocator(), true)
144{
145}
146
147KeyChain::KeyChain(const std::string& pibLocator, const std::string& tpmLocator, bool allowReset)
148 : KeyChain(parseAndCheckPibLocator(pibLocator),
149 parseAndCheckTpmLocator(tpmLocator),
150 allowReset)
151{
152}
153
154KeyChain::KeyChain(Locator pibLocator, Locator tpmLocator, bool allowReset)
155{
156 // Create PIB
157 auto pibFactory = getPibFactories().find(pibLocator.scheme);
158 BOOST_ASSERT(pibFactory != getPibFactories().end());
159 m_pib.reset(new Pib(pibLocator.canonical(), pibFactory->second(pibLocator.location)));
160
161 // Figure out the TPM Locator
162 std::string oldTpmLocator = m_pib->getTpmLocator();
163 if (pibLocator == getDefaultPibLocator()) {
164 // Default PIB must use default TPM
165 if (!oldTpmLocator.empty() && oldTpmLocator != getDefaultTpmLocator().canonical()) {
166 m_pib->reset();
167 tpmLocator = getDefaultTpmLocator();
168 }
169 }
170 else {
171 // non-default PIB check consistency
172 if (!oldTpmLocator.empty() && oldTpmLocator != tpmLocator.canonical()) {
173 if (allowReset)
174 m_pib->reset();
175 else
176 NDN_THROW(LocatorMismatchError("Supplied TPM locator (" + tpmLocator.canonical() +
177 ") does not match TPM locator in PIB (" + oldTpmLocator + ")"));
178 }
179 }
180 // Note that key mismatch may still happen if the TPM locator is initially set to a
181 // wrong one or if the PIB was shared by more than one TPMs before. This is due to the
182 // old PIB not having TPM info, the new PIB should not have this problem.
183
184 // Create TPM
185 auto tpmFactory = getTpmFactories().find(tpmLocator.scheme);
186 BOOST_ASSERT(tpmFactory != getTpmFactories().end());
187 m_tpm.reset(new Tpm(tpmLocator.canonical(), tpmFactory->second(tpmLocator.location)));
188
189 // Link PIB with TPM
190 m_pib->setTpmLocator(tpmLocator.canonical());
191}
192
193KeyChain::~KeyChain() = default;
194
195// public: management
196
197Identity
198KeyChain::createIdentity(const Name& identityName, const KeyParams& params)
199{
200 NDN_LOG_DEBUG("Requesting creation of identity " << identityName);
201 Identity id = m_pib->addIdentity(identityName);
202
203 Key key;
204 try {
205 key = id.getDefaultKey();
206 }
207 catch (const Pib::Error&) {
208 key = createKey(id, params);
209 }
210
211 try {
213 }
214 catch (const Pib::Error&) {
215 NDN_LOG_DEBUG("No default certificate for " << key << ", requesting self-signing");
216 selfSign(key);
217 }
218
219 return id;
220}
221
222void
224{
225 if (!identity) {
226 return;
227 }
228
229 Name identityName = identity.getName();
230 NDN_LOG_DEBUG("Requesting deletion of identity " << identityName);
231
232 for (const auto& key : identity.getKeys()) {
233 m_tpm->deleteKey(key.getName());
234 }
235
236 m_pib->removeIdentity(identityName);
237}
238
239void
241{
242 BOOST_ASSERT(identity);
243
244 m_pib->setDefaultIdentity(identity.getName());
245}
246
247Key
248KeyChain::createKey(const Identity& identity, const KeyParams& params)
249{
250 BOOST_ASSERT(identity);
251
252 // create key in TPM
253 Name keyName = m_tpm->createKey(identity.getName(), params);
254
255 // set up key info in PIB
256 Key key = identity.addKey(*m_tpm->getPublicKey(keyName), keyName);
257
258 NDN_LOG_DEBUG("Requesting self-signing for newly created key " << key);
259 selfSign(key);
260
261 return key;
262}
263
264Name
265KeyChain::createHmacKey(const Name& prefix, const HmacKeyParams& params)
266{
267 return m_tpm->createKey(prefix, params);
268}
269
270void
271KeyChain::deleteKey(const Identity& identity, const Key& key)
272{
273 BOOST_ASSERT(identity);
274 if (!key) {
275 return;
276 }
277
278 Name keyName = key.getName();
279 identity.removeKey(keyName);
280 m_tpm->deleteKey(keyName);
281}
282
283void
284KeyChain::setDefaultKey(const Identity& identity, const Key& key)
285{
286 BOOST_ASSERT(identity);
287 BOOST_ASSERT(key);
288
289 identity.setDefaultKey(key.getName());
290}
291
292void
293KeyChain::addCertificate(const Key& key, const Certificate& certificate)
294{
295 BOOST_ASSERT(key);
296
297 key.addCertificate(certificate);
298}
299
300void
301KeyChain::deleteCertificate(const Key& key, const Name& certName)
302{
303 BOOST_ASSERT(key);
304
305 key.removeCertificate(certName);
306}
307
308void
310{
311 BOOST_ASSERT(key);
312
313 key.setDefaultCertificate(cert);
314}
315
316shared_ptr<SafeBag>
317KeyChain::exportSafeBag(const Certificate& certificate, const char* pw, size_t pwLen)
318{
319 Name keyName = certificate.getKeyName();
320
321 ConstBufferPtr encryptedKey;
322 try {
323 encryptedKey = m_tpm->exportPrivateKey(keyName, pw, pwLen);
324 }
325 catch (const Tpm::Error&) {
326 NDN_THROW_NESTED(Error("Failed to export private key `" + keyName.toUri() + "`"));
327 }
328
329 return make_shared<SafeBag>(certificate, *encryptedKey);
330}
331
332void
333KeyChain::importSafeBag(const SafeBag& safeBag, const char* pw, size_t pwLen)
334{
335 Certificate cert(safeBag.getCertificate());
336 Name identity = cert.getIdentity();
337 Name keyName = cert.getKeyName();
338
339 // check if private key already exists
340 if (m_tpm->hasKey(keyName)) {
341 NDN_THROW(Error("Private key `" + keyName.toUri() + "` already exists"));
342 }
343
344 // check if public key already exists
345 try {
346 m_pib->getIdentity(identity).getKey(keyName);
347 NDN_THROW(Error("Public key `" + keyName.toUri() + "` already exists"));
348 }
349 catch (const Pib::Error&) {
350 // Either identity or key doesn't exist. OK to import.
351 }
352
353 try {
354 m_tpm->importPrivateKey(keyName, safeBag.getEncryptedKey(), pw, pwLen);
355 }
356 catch (const Tpm::Error&) {
357 NDN_THROW_NESTED(Error("Failed to import private key `" + keyName.toUri() + "`"));
358 }
359
360 // check the consistency of private key and certificate (sign/verify a random message)
361 const auto r = random::generateWord64();
362 const auto msg = make_span(reinterpret_cast<const uint8_t*>(&r), sizeof(r));
363 ConstBufferPtr sigBits;
364 try {
365 sigBits = m_tpm->sign({msg}, keyName, DigestAlgorithm::SHA256);
366 }
367 catch (const std::runtime_error&) {
368 m_tpm->deleteKey(keyName);
369 NDN_THROW(Error("Invalid private key `" + keyName.toUri() + "`"));
370 }
371 if (!verifySignature({msg}, *sigBits, cert.getPublicKey())) {
372 m_tpm->deleteKey(keyName);
373 NDN_THROW(Error("Certificate `" + cert.getName().toUri() + "` "
374 "and private key `" + keyName.toUri() + "` do not match"));
375 }
376
377 Identity id = m_pib->addIdentity(identity);
378 Key key = id.addKey(cert.getPublicKey(), keyName);
379 key.addCertificate(cert);
380}
381
382void
383KeyChain::importPrivateKey(const Name& keyName, shared_ptr<transform::PrivateKey> key)
384{
385 if (m_tpm->hasKey(keyName)) {
386 NDN_THROW(Error("Private key `" + keyName.toUri() + "` already exists"));
387 }
388
389 try {
390 m_tpm->importPrivateKey(keyName, std::move(key));
391 }
392 catch (const Tpm::Error&) {
393 NDN_THROW_NESTED(Error("Failed to import private key `" + keyName.toUri() + "`"));
394 }
395}
396
397// public: signing
398
399void
400KeyChain::sign(Data& data, const SigningInfo& params)
401{
402 auto [keyName, sigInfo] = prepareSignatureInfo(params);
403
404 data.setSignatureInfo(sigInfo);
405 EncodingBuffer encoder;
406 data.wireEncode(encoder, true);
407
408 auto sigValue = sign({encoder}, keyName, params.getDigestAlgorithm());
409 data.wireEncode(encoder, *sigValue);
410}
411
412void
413KeyChain::sign(Interest& interest, const SigningInfo& params)
414{
415 auto [keyName, sigInfo] = prepareSignatureInfo(params);
416
418 interest.setSignatureInfo(sigInfo);
419
420 // Extract function will throw if not all necessary elements are present in Interest
421 auto sigValue = sign(interest.extractSignedRanges(), keyName, params.getDigestAlgorithm());
422 interest.setSignatureValue(std::move(sigValue));
423 }
424 else {
425 Name signedName = interest.getName();
426
427 // We encode in Data format because this is the format used prior to Packet Specification v0.3
428 const auto& sigInfoBlock = sigInfo.wireEncode(SignatureInfo::Type::Data);
429 signedName.append(sigInfoBlock); // SignatureInfo
430
431 Block sigValue(tlv::SignatureValue,
432 sign({signedName.wireEncode().value_bytes()}, keyName, params.getDigestAlgorithm()));
433 sigValue.encode();
434 signedName.append(sigValue); // SignatureValue
435
436 interest.setName(signedName);
437 }
438}
439
441KeyChain::makeCertificate(const pib::Key& publicKey, const SigningInfo& params,
442 const MakeCertificateOptions& opts)
443{
444 return makeCertificate(publicKey.getName(), publicKey.getPublicKey(), params, opts);
445}
446
448KeyChain::makeCertificate(const Certificate& certRequest, const SigningInfo& params,
449 const MakeCertificateOptions& opts)
450{
451 auto pkcs8 = certRequest.getPublicKey();
452 try {
454 pub.loadPkcs8(pkcs8);
455 }
456 catch (const transform::PublicKey::Error&) {
457 NDN_THROW_NESTED(std::invalid_argument("Certificate request contains invalid public key"));
458 }
459
460 return makeCertificate(extractKeyNameFromCertName(certRequest.getName()), pkcs8, params, opts);
461}
462
463// private: PIB/TPM locator helpers
464
465static std::tuple<std::string/*scheme*/, std::string/*location*/>
466parseLocatorUri(const std::string& uri)
467{
468 if (auto pos = uri.find(':'); pos != std::string::npos) {
469 return {uri.substr(0, pos), uri.substr(pos + 1)};
470 }
471 else {
472 return {uri, ""};
473 }
474}
475
476KeyChain::Locator
477KeyChain::parseAndCheckPibLocator(const std::string& pibLocator)
478{
479 auto [pibScheme, pibLocation] = parseLocatorUri(pibLocator);
480 if (pibScheme.empty()) {
481 pibScheme = getDefaultPibScheme();
482 }
483
484 auto pibFactory = getPibFactories().find(pibScheme);
485 if (pibFactory == getPibFactories().end()) {
486 NDN_THROW(Error("PIB scheme `" + pibScheme + "` is not supported"));
487 }
488
489 return {pibScheme, pibLocation};
490}
491
492KeyChain::Locator
493KeyChain::parseAndCheckTpmLocator(const std::string& tpmLocator)
494{
495 auto [tpmScheme, tpmLocation] = parseLocatorUri(tpmLocator);
496 if (tpmScheme.empty()) {
497 tpmScheme = getDefaultTpmScheme();
498 }
499
500 auto tpmFactory = getTpmFactories().find(tpmScheme);
501 if (tpmFactory == getTpmFactories().end()) {
502 NDN_THROW(Error("TPM scheme `" + tpmScheme + "` is not supported"));
503 }
504
505 return {tpmScheme, tpmLocation};
506}
507
508const KeyChain::Locator&
509KeyChain::getDefaultPibLocator()
510{
511 if (!s_defaultPibLocator.empty())
512 return s_defaultPibLocator;
513
514 std::string input;
515 const char* pibEnv = std::getenv("NDN_CLIENT_PIB");
516 if (pibEnv != nullptr) {
517 input = pibEnv;
518 }
519 else {
520 ConfigFile config;
521 input = config.getParsedConfiguration().get<std::string>("pib", getDefaultPibScheme());
522 }
523
524 s_defaultPibLocator = parseAndCheckPibLocator(input);
525 BOOST_ASSERT(!s_defaultPibLocator.empty());
526 return s_defaultPibLocator;
527}
528
529const KeyChain::Locator&
530KeyChain::getDefaultTpmLocator()
531{
532 if (!s_defaultTpmLocator.empty())
533 return s_defaultTpmLocator;
534
535 std::string input;
536 const char* tpmEnv = std::getenv("NDN_CLIENT_TPM");
537 if (tpmEnv != nullptr) {
538 input = tpmEnv;
539 }
540 else {
541 ConfigFile config;
542 input = config.getParsedConfiguration().get<std::string>("tpm", getDefaultTpmScheme());
543 }
544
545 s_defaultTpmLocator = parseAndCheckTpmLocator(input);
546 BOOST_ASSERT(!s_defaultTpmLocator.empty());
547 return s_defaultTpmLocator;
548}
549
550#ifdef NDN_CXX_WITH_TESTS
551void
552KeyChain::resetDefaultLocators()
553{
554 s_defaultPibLocator = {};
555 s_defaultTpmLocator = {};
556}
557#endif
558
559// private: signing
560
561Certificate
562KeyChain::makeCertificate(const Name& keyName, span<const uint8_t> publicKey,
563 SigningInfo params, const MakeCertificateOptions& opts)
564{
565 if (opts.freshnessPeriod <= 0_ms) {
566 // We cannot rely on Certificate constructor to check this, because
567 // it throws Certificate::Error, not std::invalid_argument
568 NDN_THROW(std::invalid_argument("FreshnessPeriod is not positive"));
569 }
570
571 Name name(keyName);
572 name.append(opts.issuerId);
573 name.appendVersion(opts.version);
574
575 Data data;
576 data.setName(name);
577 data.setContentType(tlv::ContentType_Key);
578 data.setFreshnessPeriod(opts.freshnessPeriod);
579 data.setContent(publicKey);
580
581 auto sigInfo = params.getSignatureInfo();
582 // Call ValidityPeriod::makeRelative here instead of in MakeCertificateOptions struct
583 // because the caller may prepare MakeCertificateOptions first and call makeCertificate
584 // at a later time.
585 sigInfo.setValidityPeriod(opts.validity.value_or(ValidityPeriod::makeRelative(-1_s, 365_days)));
586 params.setSignatureInfo(sigInfo);
587
588 sign(data, params);
589 // let Certificate constructor double-check correctness of this function
590 return Certificate(std::move(data));
591}
592
593Certificate
594KeyChain::selfSign(Key& key)
595{
596 MakeCertificateOptions opts;
597 opts.issuerId = SELF;
598 // Note time::system_clock::max() or other NotAfter date results in incorrect encoded value
599 // because of overflow during conversion to boost::posix_time::ptime (bug #3915, bug #5176).
600 opts.validity = ValidityPeriod::makeRelative(-1_s, 20 * 365_days);
601 auto cert = makeCertificate(key, signingByKey(key), opts);
602
603 key.addCertificate(cert);
604 return cert;
605}
606
607std::tuple<Name, SignatureInfo>
608KeyChain::prepareSignatureInfo(const SigningInfo& params)
609{
610 switch (params.getSignerType()) {
612 pib::Identity identity;
613 try {
614 identity = m_pib->getDefaultIdentity();
615 }
616 catch (const Pib::Error&) { // no default identity, use sha256 for signing.
617 return prepareSignatureInfoSha256(params);
618 }
619 return prepareSignatureInfoWithIdentity(params, identity);
620 }
622 auto identity = params.getPibIdentity();
623 if (!identity) {
624 auto identityName = params.getSignerName();
625 try {
626 identity = m_pib->getIdentity(identityName);
627 }
628 catch (const Pib::Error&) {
629 NDN_THROW_NESTED(InvalidSigningInfoError("Signing identity `" +
630 identityName.toUri() + "` does not exist"));
631 }
632 }
633 if (!identity) {
634 NDN_THROW(InvalidSigningInfoError("Cannot determine signing parameters"));
635 }
636 return prepareSignatureInfoWithIdentity(params, identity);
637 }
639 auto key = params.getPibKey();
640 if (!key) {
641 auto keyName = params.getSignerName();
642 auto identityName = extractIdentityFromKeyName(keyName);
643 try {
644 key = m_pib->getIdentity(identityName).getKey(keyName);
645 }
646 catch (const Pib::Error&) {
647 NDN_THROW_NESTED(InvalidSigningInfoError("Signing key `" +
648 keyName.toUri() + "` does not exist"));
649 }
650 }
651 if (!key) {
652 NDN_THROW(InvalidSigningInfoError("Cannot determine signing parameters"));
653 }
654 return prepareSignatureInfoWithKey(params, key);
655 }
657 auto certName = params.getSignerName();
658 auto keyName = extractKeyNameFromCertName(certName);
659 auto identityName = extractIdentityFromCertName(certName);
660 pib::Key key;
661 try {
662 key = m_pib->getIdentity(identityName).getKey(keyName);
663 }
664 catch (const Pib::Error&) {
665 NDN_THROW_NESTED(InvalidSigningInfoError("Signing certificate `" +
666 certName.toUri() + "` does not exist"));
667 }
668 return prepareSignatureInfoWithKey(params, key, certName);
669 }
671 return prepareSignatureInfoSha256(params);
672 }
674 return prepareSignatureInfoHmac(params, *m_tpm);
675 }
676 }
677 NDN_THROW(InvalidSigningInfoError("Unrecognized signer type " +
678 to_string(params.getSignerType())));
679}
680
681std::tuple<Name, SignatureInfo>
682KeyChain::prepareSignatureInfoSha256(const SigningInfo& params)
683{
684 auto sigInfo = params.getSignatureInfo();
685 sigInfo.setSignatureType(tlv::DigestSha256);
686
687 NDN_LOG_TRACE("Prepared signature info: " << sigInfo);
688 return {SigningInfo::getDigestSha256Identity(), sigInfo};
689}
690
691std::tuple<Name, SignatureInfo>
692KeyChain::prepareSignatureInfoHmac(const SigningInfo& params, Tpm& tpm)
693{
694 const Name& keyName = params.getSignerName();
695 if (!tpm.hasKey(keyName)) {
696 tpm.importPrivateKey(keyName, params.getHmacKey());
697 }
698
699 auto sigInfo = params.getSignatureInfo();
700 sigInfo.setSignatureType(getSignatureType(KeyType::HMAC, params.getDigestAlgorithm()));
701 sigInfo.setKeyLocator(keyName);
702
703 NDN_LOG_TRACE("Prepared signature info: " << sigInfo);
704 return {keyName, sigInfo};
705}
706
707std::tuple<Name, SignatureInfo>
708KeyChain::prepareSignatureInfoWithIdentity(const SigningInfo& params, const pib::Identity& identity)
709{
710 pib::Key key;
711 try {
712 key = identity.getDefaultKey();
713 }
714 catch (const Pib::Error&) {
715 NDN_THROW_NESTED(InvalidSigningInfoError("Signing identity `" + identity.getName().toUri() +
716 "` does not have a default key"));
717 }
718 return prepareSignatureInfoWithKey(params, key);
719}
720
721std::tuple<Name, SignatureInfo>
722KeyChain::prepareSignatureInfoWithKey(const SigningInfo& params, const pib::Key& key,
723 const std::optional<Name>& certName)
724{
725 auto sigInfo = params.getSignatureInfo();
726 sigInfo.setSignatureType(getSignatureType(key.getKeyType(), params.getDigestAlgorithm()));
727 if (!sigInfo.hasKeyLocator()) {
728 if (certName) {
729 sigInfo.setKeyLocator(certName);
730 }
731 else {
732 Name klName = key.getName();
733 try {
734 klName = key.getDefaultCertificate().getName();
735 }
736 catch (const Pib::Error&) {
737 }
738 sigInfo.setKeyLocator(klName);
739 }
740 }
741
742 NDN_LOG_TRACE("Prepared signature info: " << sigInfo);
743 return {key.getName(), sigInfo};
744}
745
747KeyChain::sign(const InputBuffers& bufs, const Name& keyName, DigestAlgorithm digestAlgorithm) const
748{
749 using namespace transform;
750
751 if (keyName == SigningInfo::getDigestSha256Identity()) {
752 OBufferStream os;
754 return os.buf();
755 }
756
757 auto signature = m_tpm->sign(bufs, keyName, digestAlgorithm);
758 if (!signature) {
759 NDN_THROW(InvalidSigningInfoError("TPM signing failed for key `" + keyName.toUri() + "` "
760 "(e.g., PIB contains info about the key, but TPM is missing "
761 "the corresponding private key)"));
762 }
763
764 return signature;
765}
766
768KeyChain::getSignatureType(KeyType keyType, DigestAlgorithm)
769{
770 switch (keyType) {
771 case KeyType::RSA:
773 case KeyType::EC:
775 case KeyType::HMAC:
777 default:
778 NDN_THROW(Error("Unsupported key type " + boost::lexical_cast<std::string>(keyType)));
779 }
780}
781
782} // namespace ndn::security
Represents a TLV element of the NDN packet format.
Definition block.hpp:45
void encode()
Encode sub-elements into TLV-VALUE.
Definition block.cpp:353
Represents a Data packet.
Definition data.hpp:39
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Prepend wire encoding to encoder.
Definition data.cpp:39
const Name & getName() const noexcept
Get the Data name.
Definition data.hpp:137
Data & setSignatureInfo(const SignatureInfo &info)
Set the SignatureInfo element.
Definition data.cpp:295
Represents an Interest packet.
Definition interest.hpp:50
Interest & setSignatureValue(span< const uint8_t > value)
Set InterestSignatureValue by copying from a contiguous sequence of bytes.
Definition interest.cpp:641
InputBuffers extractSignedRanges() const
Extract ranges of Interest covered by the signature.
Definition interest.cpp:657
const Name & getName() const noexcept
Get the Interest name.
Definition interest.hpp:179
Interest & setName(const Name &name)
Set the Interest name.
Definition interest.cpp:354
Interest & setSignatureInfo(const SignatureInfo &info)
Set the InterestSignatureInfo element.
Definition interest.cpp:562
Base class for key parameters.
Represents an absolute name.
Definition name.hpp:45
Name & append(const Component &component)
Append a name component.
Definition name.hpp:308
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Prepend wire encoding to encoder.
Definition name.cpp:92
void toUri(std::ostream &os, name::UriFormat format=name::UriFormat::DEFAULT) const
Write URI representation of the name to the output stream.
Definition name.cpp:324
SimplePublicKeyParams is a template for public keys with only one parameter: size.
SimpleSymmetricKeyParams is a template for symmetric keys with only one parameter: size.
Represents a name component.
Represents an NDN certificate.
Name getKeyName() const
Get key name.
span< const uint8_t > getPublicKey() const noexcept
Return the public key as a DER-encoded SubjectPublicKeyInfo structure, i.e., exactly as it appears in...
Name getIdentity() const
Get identity name.
The main interface for signing key management.
Definition key-chain.hpp:87
void sign(Data &data, const SigningInfo &params=SigningInfo())
Sign a Data packet according to the supplied signing information.
void setDefaultCertificate(const Key &key, const Certificate &cert)
Set cert as the default certificate of key.
void addCertificate(const Key &key, const Certificate &cert)
Add a certificate cert for key.
void importPrivateKey(const Name &keyName, shared_ptr< transform::PrivateKey > key)
Import a private key into the TPM.
void importSafeBag(const SafeBag &safeBag, const char *pw, size_t pwLen)
Import a certificate and its corresponding private key from a SafeBag.
static const KeyParams & getDefaultKeyParams()
shared_ptr< SafeBag > exportSafeBag(const Certificate &certificate, const char *pw, size_t pwLen)
Export a certificate and its corresponding private key.
void deleteIdentity(const Identity &identity)
Delete identity from this KeyChain.
Key createKey(const Identity &identity, const KeyParams &params=getDefaultKeyParams())
Create a new key for identity.
void setDefaultIdentity(const Identity &identity)
Set identity as the default identity.
void setDefaultKey(const Identity &identity, const Key &key)
Set key as the default key of identity.
Name createHmacKey(const Name &prefix=SigningInfo::getHmacIdentity(), const HmacKeyParams &params=HmacKeyParams())
Create a new HMAC key.
KeyChain()
Constructor to create KeyChain with default PIB and TPM.
Certificate makeCertificate(const pib::Key &publicKey, const SigningInfo &params=SigningInfo(), const MakeCertificateOptions &opts={})
Create and sign a certificate packet.
Identity createIdentity(const Name &identityName, const KeyParams &params=getDefaultKeyParams())
Create an identity identityName.
void deleteKey(const Identity &identity, const Key &key)
Delete key from identity.
void deleteCertificate(const Key &key, const Name &certName)
Delete a certificate with name certName from key.
A secured container for sensitive information (certificate, private key)
Definition safe-bag.hpp:38
const Data & getCertificate() const
Get the certificate data packet from safe bag.
Definition safe-bag.hpp:83
span< const uint8_t > getEncryptedKey() const
Get the private key in PKCS #8 format from safe bag.
Definition safe-bag.hpp:92
Signing parameters passed to KeyChain.
static const Name & getDigestSha256Identity()
A localhost identity to indicate that the signature is generated using SHA-256.
@ SIGNER_TYPE_CERT
Signer is a certificate, use it directly.
@ SIGNER_TYPE_SHA256
Use a SHA-256 digest only, no signer needs to be specified.
@ SIGNER_TYPE_HMAC
Signer is a HMAC key.
@ SIGNER_TYPE_NULL
No signer is specified, use default setting or follow the trust schema.
@ SIGNER_TYPE_ID
Signer is an identity, use its default key and default certificate.
@ SIGNER_TYPE_KEY
Signer is a key, use its default certificate.
SignedInterestFormat getSignedInterestFormat() const
Get the signed Interest format.
DigestAlgorithm getDigestAlgorithm() const
Get the digest algorithm for signing operations.
static ValidityPeriod makeRelative(time::seconds validFrom, time::seconds validUntil, const time::system_clock::time_point &now=time::system_clock::now())
Construct ValidityPeriod relative to a timepoint.
Frontend handle for an identity in the PIB.
Definition identity.hpp:44
const KeyContainer & getKeys() const
Return all the keys of this identity.
Definition identity.cpp:59
const Name & getName() const
Return the name of the identity.
Definition identity.cpp:35
Frontend handle for a key in the PIB.
Definition key.hpp:45
const Certificate & getDefaultCertificate() const
Return the default certificate for this key.
Definition key.cpp:96
span< const uint8_t > getPublicKey() const
Return the raw public key bits.
Definition key.cpp:54
const Name & getName() const
Return the name of the key.
Definition key.cpp:36
Represents a semantic error.
Definition pib.hpp:56
Frontend to the Public Information Base.
Definition pib.hpp:52
Abstraction of a public key in crypto transformations.
void loadPkcs8(span< const uint8_t > buf)
Load the public key in PKCS#8 format from a buffer buf.
#define NDN_THROW_NESTED(e)
Definition exception.hpp:65
#define NDN_THROW(e)
Definition exception.hpp:56
#define NDN_CXX_KEYCHAIN_REGISTER_PIB_BACKEND(PibType)
Register Pib backend class in KeyChain.
#define NDN_CXX_KEYCHAIN_REGISTER_TPM_BACKEND(TpmType)
Register Tpm backend class in KeyChain.
#define NDN_LOG_DEBUG(expression)
Log at DEBUG level.
Definition logger.hpp:260
#define NDN_LOG_TRACE(expression)
Log at TRACE level.
Definition logger.hpp:255
#define NDN_LOG_INIT(name)
Define a non-member log module.
Definition logger.hpp:169
std::string to_string(const errinfo_stacktrace &x)
Definition exception.cpp:30
uint64_t generateWord64()
Generate a non-cryptographically-secure random integer in the range [0, 2^64).
Definition random.cpp:75
unique_ptr< Transform > digestFilter(DigestAlgorithm algo)
unique_ptr< Sink > streamSink(std::ostream &os)
Contains the ndn-cxx security framework.
Name extractIdentityFromKeyName(const Name &keyName)
Extract identity namespace from the key name keyName.
Definition key.cpp:141
SigningInfo signingByKey(const Name &keyName)
Return a SigningInfo for signing with a key.
bool verifySignature(const InputBuffers &blobs, span< const uint8_t > sig, const transform::PublicKey &key)
Verify blobs using key against sig.
const name::Component SELF
Definition key-chain.cpp:70
Name extractIdentityFromCertName(const Name &certName)
Extract identity namespace from the certificate name certName.
@ V03
Sign Interest using Packet Specification v0.3 semantics.
Name extractKeyNameFromCertName(const Name &certName)
Extract key name from the certificate name certName.
@ Name
Definition tlv.hpp:71
@ Data
Definition tlv.hpp:69
@ SignatureValue
Definition tlv.hpp:95
@ ContentType_Key
public key, certificate
Definition tlv.hpp:147
SignatureTypeValue
SignatureType values.
Definition tlv.hpp:127
@ SignatureSha256WithRsa
Definition tlv.hpp:129
@ DigestSha256
Definition tlv.hpp:128
@ SignatureHmacWithSha256
Definition tlv.hpp:131
@ SignatureSha256WithEcdsa
Definition tlv.hpp:130
Definition data.cpp:25
KeyType
The type of a cryptographic key.
@ EC
Elliptic Curve key (e.g. for ECDSA), supports sign/verify operations.
@ RSA
RSA key, supports sign/verify and encrypt/decrypt operations.
@ HMAC
HMAC key, supports sign/verify operations.
std::shared_ptr< const Buffer > ConstBufferPtr
Definition buffer.hpp:140
Options to KeyChain::makeCertificate().
Definition key-chain.hpp:42
InputBuffers bufs