blob: d0fd486b7ced1e55fa6c706e32e90e7af1f3a14e [file] [log] [blame]
Yingdi Yufe4733a2015-10-22 14:24:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2017 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
22#include "key-chain.hpp"
23
24#include "../../util/config-file.hpp"
25
26#include "../pib/pib-sqlite3.hpp"
27#include "../pib/pib-memory.hpp"
28
29#ifdef NDN_CXX_HAVE_OSX_SECURITY
30#include "../tpm/back-end-osx.hpp"
31#endif // NDN_CXX_HAVE_OSX_SECURITY
32
33#include "../tpm/back-end-file.hpp"
34#include "../tpm/back-end-mem.hpp"
35
36#include "../transform/bool-sink.hpp"
37#include "../transform/buffer-source.hpp"
38#include "../transform/private-key.hpp"
39#include "../transform/verifier-filter.hpp"
40#include "../../encoding/buffer-stream.hpp"
41#include "../../util/crypto.hpp"
42
43#include <boost/lexical_cast.hpp>
44
45namespace ndn {
46namespace security {
47
48// When static library is used, not everything is compiled into the resulting binary.
49// Therefore, the following standard PIB and TPMs need to be registered here.
50// http://stackoverflow.com/q/9459980/2150331
51
52/////////
53// PIB //
54/////////
55namespace pib {
56NDN_CXX_V2_KEYCHAIN_REGISTER_PIB_BACKEND(PibSqlite3);
57NDN_CXX_V2_KEYCHAIN_REGISTER_PIB_BACKEND(PibMemory);
58} // namespace pib
59
60/////////
61// TPM //
62/////////
63namespace tpm {
64#if defined(NDN_CXX_HAVE_OSX_SECURITY) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
65NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(BackEndOsx);
66#endif // defined(NDN_CXX_HAVE_OSX_SECURITY) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
67
68NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(BackEndFile);
69NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(BackEndMem);
70} // namespace tpm
71
72namespace v2 {
73
74std::string KeyChain::s_defaultPibLocator;
75std::string KeyChain::s_defaultTpmLocator;
76
77KeyChain::PibFactories&
78KeyChain::getPibFactories()
79{
80 static PibFactories pibFactories;
81 return pibFactories;
82}
83
84KeyChain::TpmFactories&
85KeyChain::getTpmFactories()
86{
87 static TpmFactories tpmFactories;
88 return tpmFactories;
89}
90
91const std::string&
92KeyChain::getDefaultPibScheme()
93{
94 return pib::PibSqlite3::getScheme();;
95}
96
97const std::string&
98KeyChain::getDefaultTpmScheme()
99{
100#if defined(NDN_CXX_HAVE_OSX_SECURITY) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
101 return tpm::BackEndOsx::getScheme();;
102#else
103 return tpm::BackEndFile::getScheme();
104#endif // defined(NDN_CXX_HAVE_OSX_SECURITY) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
105}
106
107const std::string&
108KeyChain::getDefaultPibLocator()
109{
110 if (!s_defaultPibLocator.empty())
111 return s_defaultPibLocator;
112
113 if (getenv("NDN_CLIENT_PIB") != nullptr) {
114 s_defaultPibLocator = getenv("NDN_CLIENT_PIB");
115 }
116 else {
117 ConfigFile config;
118 s_defaultPibLocator = config.getParsedConfiguration().get<std::string>("pib", getDefaultPibScheme() + ":");
119 }
120
121 return s_defaultPibLocator;
122}
123
124const std::string&
125KeyChain::getDefaultTpmLocator()
126{
127 if (!s_defaultTpmLocator.empty())
128 return s_defaultTpmLocator;
129
130 if (getenv("NDN_CLIENT_TPM") != nullptr) {
131 s_defaultTpmLocator = getenv("NDN_CLIENT_TPM");
132 }
133 else {
134 ConfigFile config;
135 s_defaultTpmLocator = config.getParsedConfiguration().get<std::string>("tpm", getDefaultTpmScheme() + ":");
136 }
137
138 return s_defaultTpmLocator;
139}
140
141
142// Other defaults
143
144const SigningInfo&
145KeyChain::getDefaultSigningInfo()
146{
147 static SigningInfo signingInfo;
148 return signingInfo;
149}
150
151const KeyParams&
152KeyChain::getDefaultKeyParams()
153{
154 static EcdsaKeyParams keyParams;
155 return keyParams;
156}
157
158//
159
160KeyChain::KeyChain()
161 : KeyChain(getDefaultPibLocator(), getDefaultTpmLocator(), true)
162{
163}
164
165KeyChain::KeyChain(const std::string& pibLocator, const std::string& tpmLocator, bool allowReset)
166{
167 // PIB Locator
168 std::string pibScheme, pibLocation;
169 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
170 std::string canonicalPibLocator = pibScheme + ":" + pibLocation;
171
172 // Create PIB
173 m_pib = createPib(canonicalPibLocator);
174 std::string oldTpmLocator;
175 try {
176 oldTpmLocator = m_pib->getTpmLocator();
177 }
178 catch (const Pib::Error&) {
179 // TPM locator is not set in PIB yet.
180 }
181
182 // TPM Locator
183 std::string tpmScheme, tpmLocation;
184 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
185 std::string canonicalTpmLocator = tpmScheme + ":" + tpmLocation;
186
187 if (canonicalPibLocator == getDefaultPibLocator()) {
188 // Default PIB must use default TPM
189 if (!oldTpmLocator.empty() && oldTpmLocator != getDefaultTpmLocator()) {
190 m_pib->reset();
191 canonicalTpmLocator = getDefaultTpmLocator();
192 }
193 }
194 else {
195 // non-default PIB check consistency
196 if (!oldTpmLocator.empty() && oldTpmLocator != canonicalTpmLocator) {
197 if (allowReset)
198 m_pib->reset();
199 else
200 BOOST_THROW_EXCEPTION(LocatorMismatchError("TPM locator supplied does not match TPM locator in PIB: " +
201 oldTpmLocator + " != " + canonicalTpmLocator));
202 }
203 }
204
205 // note that key mismatch may still happen if the TPM locator is initially set to a
206 // wrong one or if the PIB was shared by more than one TPMs before. This is due to the
207 // old PIB does not have TPM info, new pib should not have this problem.
208 m_tpm = createTpm(canonicalTpmLocator);
209 m_pib->setTpmLocator(canonicalTpmLocator);
210}
211
212KeyChain::~KeyChain() = default;
213
214// public: management
215
216Identity
217KeyChain::createIdentity(const Name& identityName, const KeyParams& params)
218{
219 Identity id = m_pib->addIdentity(identityName);
220
221 Key key;
222 try {
223 key = id.getDefaultKey();
224 }
225 catch (const Pib::Error&) {
226 key = createKey(id, params);
227 }
228
229 try {
230 key.getDefaultCertificate();
231 }
232 catch (const Pib::Error&) {
233 selfSign(key);
234 }
235
236 return id;
237}
238
239void
240KeyChain::deleteIdentity(const Identity& identity)
241{
242 BOOST_ASSERT(static_cast<bool>(identity));
243
244 Name identityName = identity.getName();
245
246 for (const auto& key : identity.getKeys()) {
247 m_tpm->deleteKey(key.getName());
248 }
249
250 m_pib->removeIdentity(identityName);
251}
252
253void
254KeyChain::setDefaultIdentity(const Identity& identity)
255{
256 BOOST_ASSERT(static_cast<bool>(identity));
257
258 m_pib->setDefaultIdentity(identity.getName());
259}
260
261Key
262KeyChain::createKey(const Identity& identity, const KeyParams& params)
263{
264 BOOST_ASSERT(static_cast<bool>(identity));
265
266 // create key in TPM
267 Name keyName = m_tpm->createKey(identity.getName(), params);
268
269 // set up key info in PIB
270 ConstBufferPtr pubKey = m_tpm->getPublicKey(keyName);
271 Key key = identity.addKey(pubKey->buf(), pubKey->size(), keyName);
272 selfSign(key);
273
274 return key;
275}
276
277void
278KeyChain::deleteKey(const Identity& identity, const Key& key)
279{
280 BOOST_ASSERT(static_cast<bool>(identity));
281 BOOST_ASSERT(static_cast<bool>(key));
282
283 Name keyName = key.getName();
284 if (identity.getName() != key.getIdentity()) {
285 BOOST_THROW_EXCEPTION(std::invalid_argument("Identity `" + identity.getName().toUri() + "` "
286 "does match key `" + keyName.toUri() + "`"));
287 }
288
289 identity.removeKey(keyName);
290 m_tpm->deleteKey(keyName);
291}
292
293void
294KeyChain::setDefaultKey(const Identity& identity, const Key& key)
295{
296 BOOST_ASSERT(static_cast<bool>(identity));
297 BOOST_ASSERT(static_cast<bool>(key));
298
299 if (identity.getName() != key.getIdentity())
300 BOOST_THROW_EXCEPTION(std::invalid_argument("Identity `" + identity.getName().toUri() + "` "
301 "does match key `" + key.getName().toUri() + "`"));
302
303 identity.setDefaultKey(key.getName());
304}
305
306void
307KeyChain::addCertificate(const Key& key, const Certificate& certificate)
308{
309 BOOST_ASSERT(static_cast<bool>(key));
310
311 if (key.getName() != certificate.getKeyName() ||
312 !std::equal(certificate.getContent().value_begin(), certificate.getContent().value_end(),
313 key.getPublicKey().begin()))
314 BOOST_THROW_EXCEPTION(std::invalid_argument("Key `" + key.getName().toUri() + "` "
315 "does match certificate `" + certificate.getName().toUri() + "`"));
316
317 key.addCertificate(certificate);
318}
319
320void
321KeyChain::deleteCertificate(const Key& key, const Name& certificateName)
322{
323 BOOST_ASSERT(static_cast<bool>(key));
324
325 if (!Certificate::isValidName(certificateName)) {
326 BOOST_THROW_EXCEPTION(std::invalid_argument("Wrong certificate name `" + certificateName.toUri() + "`"));
327 }
328
329 key.removeCertificate(certificateName);
330}
331
332void
333KeyChain::setDefaultCertificate(const Key& key, const Certificate& cert)
334{
335 BOOST_ASSERT(static_cast<bool>(key));
336
337 try {
338 addCertificate(key, cert);
339 }
340 catch (const Pib::Error&) { // force to overwrite the existing certificates
341 key.removeCertificate(cert.getName());
342 addCertificate(key, cert);
343 }
344 key.setDefaultCertificate(cert.getName());
345}
346
347shared_ptr<SafeBag>
348KeyChain::exportSafeBag(const Certificate& certificate, const char* pw, size_t pwLen)
349{
350 Name identity = certificate.getIdentity();
351 Name keyName = certificate.getKeyName();
352
353 ConstBufferPtr encryptedKey;
354 try {
355 encryptedKey = m_tpm->exportPrivateKey(keyName, pw, pwLen);
356 }
357 catch (const tpm::BackEnd::Error&) {
358 BOOST_THROW_EXCEPTION(Error("Private `" + keyName.toUri() + "` key does not exist"));
359 }
360
361 return make_shared<SafeBag>(certificate, *encryptedKey);
362}
363
364void
365KeyChain::importSafeBag(const SafeBag& safeBag, const char* pw, size_t pwLen)
366{
367 Data certData = safeBag.getCertificate();
368 Certificate cert(std::move(certData));
369 Name identity = cert.getIdentity();
370 Name keyName = cert.getKeyName();
371 const Buffer publicKeyBits = cert.getPublicKey();
372
373 if (m_tpm->hasKey(keyName)) {
374 BOOST_THROW_EXCEPTION(Error("Private key `" + keyName.toUri() + "` already exists"));
375 }
376
377 try {
378 Identity existingId = m_pib->getIdentity(identity);
379 existingId.getKey(keyName);
380 BOOST_THROW_EXCEPTION(Error("Public key `" + keyName.toUri() + "` already exists"));
381 }
382 catch (const Pib::Error&) {
383 // Either identity or key doesn't exist. OK to import.
384 }
385
386 try {
387 m_tpm->importPrivateKey(keyName,
388 safeBag.getEncryptedKeyBag().buf(), safeBag.getEncryptedKeyBag().size(),
389 pw, pwLen);
390 }
391 catch (const std::runtime_error&) {
392 BOOST_THROW_EXCEPTION(Error("Fail to import private key `" + keyName.toUri() + "`"));
393 }
394
395 // check the consistency of private key and certificate
396 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
397 ConstBufferPtr sigBits;
398 try {
399 sigBits = m_tpm->sign(content, 4, keyName, DigestAlgorithm::SHA256);
400 }
401 catch (const std::runtime_error&) {
402 m_tpm->deleteKey(keyName);
403 BOOST_THROW_EXCEPTION(Error("Invalid private key `" + keyName.toUri() + "`"));
404 }
405 bool isVerified = false;
406 {
407 using namespace transform;
408 PublicKey publicKey;
409 publicKey.loadPkcs8(publicKeyBits.buf(), publicKeyBits.size());
410 bufferSource(content, sizeof(content)) >> verifierFilter(DigestAlgorithm::SHA256, publicKey,
411 sigBits->buf(), sigBits->size())
412 >> boolSink(isVerified);
413 }
414 if (!isVerified) {
415 m_tpm->deleteKey(keyName);
416 BOOST_THROW_EXCEPTION(Error("Certificate `" + cert.getName().toUri() + "` "
417 "and private key `" + keyName.toUri() + "` do not match"));
418 }
419
420 Identity id = m_pib->addIdentity(identity);
421 Key key = id.addKey(cert.getPublicKey().buf(), cert.getPublicKey().size(), keyName);
422 key.addCertificate(cert);
423}
424
425
426// public: signing
427
428void
429KeyChain::sign(Data& data, const SigningInfo& params)
430{
431 Name keyName;
432 SignatureInfo sigInfo;
433 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
434
435 data.setSignature(Signature(sigInfo));
436
437 EncodingBuffer encoder;
438 data.wireEncode(encoder, true);
439
440 Block sigValue = sign(encoder.buf(), encoder.size(), keyName, params.getDigestAlgorithm());
441
442 data.wireEncode(encoder, sigValue);
443}
444
445void
446KeyChain::sign(Interest& interest, const SigningInfo& params)
447{
448 Name keyName;
449 SignatureInfo sigInfo;
450 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
451
452 Name signedName = interest.getName();
453 signedName.append(sigInfo.wireEncode()); // signatureInfo
454
455 Block sigValue = sign(signedName.wireEncode().value(), signedName.wireEncode().value_size(),
456 keyName, params.getDigestAlgorithm());
457
458 sigValue.encode();
459 signedName.append(sigValue); // signatureValue
460 interest.setName(signedName);
461}
462
463Block
464KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const SigningInfo& params)
465{
466 Name keyName;
467 SignatureInfo sigInfo;
468 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
469
470 return sign(buffer, bufferLength, keyName, params.getDigestAlgorithm());
471}
472
473// public: PIB/TPM creation helpers
474
475static inline std::tuple<std::string/*type*/, std::string/*location*/>
476parseLocatorUri(const std::string& uri)
477{
478 size_t pos = uri.find(':');
479 if (pos != std::string::npos) {
480 return std::make_tuple(uri.substr(0, pos), uri.substr(pos + 1));
481 }
482 else {
483 return std::make_tuple(uri, "");
484 }
485}
486
487std::tuple<std::string/*type*/, std::string/*location*/>
488KeyChain::parseAndCheckPibLocator(const std::string& pibLocator)
489{
490 std::string pibScheme, pibLocation;
491 std::tie(pibScheme, pibLocation) = parseLocatorUri(pibLocator);
492
493 if (pibScheme.empty()) {
494 pibScheme = getDefaultPibScheme();
495 }
496
497 auto pibFactory = getPibFactories().find(pibScheme);
498 if (pibFactory == getPibFactories().end()) {
499 BOOST_THROW_EXCEPTION(KeyChain::Error("PIB scheme `" + pibScheme + "` is not supported"));
500 }
501
502 return std::make_tuple(pibScheme, pibLocation);
503}
504
505unique_ptr<Pib>
506KeyChain::createPib(const std::string& pibLocator)
507{
508 std::string pibScheme, pibLocation;
509 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
510 auto pibFactory = getPibFactories().find(pibScheme);
511 BOOST_ASSERT(pibFactory != getPibFactories().end());
512 return unique_ptr<Pib>(new Pib(pibScheme, pibLocation, pibFactory->second(pibLocation)));
513}
514
515std::tuple<std::string/*type*/, std::string/*location*/>
516KeyChain::parseAndCheckTpmLocator(const std::string& tpmLocator)
517{
518 std::string tpmScheme, tpmLocation;
519 std::tie(tpmScheme, tpmLocation) = parseLocatorUri(tpmLocator);
520
521 if (tpmScheme.empty()) {
522 tpmScheme = getDefaultTpmScheme();
523 }
524 auto tpmFactory = getTpmFactories().find(tpmScheme);
525 if (tpmFactory == getTpmFactories().end()) {
526 BOOST_THROW_EXCEPTION(KeyChain::Error("TPM scheme `" + tpmScheme + "` is not supported"));
527 }
528
529 return std::make_tuple(tpmScheme, tpmLocation);
530}
531
532unique_ptr<Tpm>
533KeyChain::createTpm(const std::string& tpmLocator)
534{
535 std::string tpmScheme, tpmLocation;
536 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
537 auto tpmFactory = getTpmFactories().find(tpmScheme);
538 BOOST_ASSERT(tpmFactory != getTpmFactories().end());
539 return unique_ptr<Tpm>(new Tpm(tpmScheme, tpmLocation, tpmFactory->second(tpmLocation)));
540}
541
542// private: signing
543
544Certificate
545KeyChain::selfSign(Key& key)
546{
547 Certificate certificate;
548
549 // set name
550 Name certificateName = key.getName();
551 certificateName
552 .append("self")
553 .appendVersion();
554 certificate.setName(certificateName);
555
556 // set metainfo
557 certificate.setContentType(tlv::ContentType_Key);
558 certificate.setFreshnessPeriod(time::hours(1));
559
560 // set content
561 certificate.setContent(key.getPublicKey().buf(), key.getPublicKey().size());
562
563 // set signature-info
564 SignatureInfo sigInfo;
565 sigInfo.setKeyLocator(key.getName());
566 sigInfo.setSignatureType(getSignatureType(key.getKeyType(), DigestAlgorithm::SHA256));
567 sigInfo.setValidityPeriod(ValidityPeriod(time::system_clock::now(),
568 time::system_clock::now() + time::days(1000 * 3365)));
569 certificate.setSignature(Signature(sigInfo));
570
571 EncodingBuffer encoder;
572 certificate.wireEncode(encoder, true);
573 Block sigValue = sign(encoder.buf(), encoder.size(), key.getName(), DigestAlgorithm::SHA256);
574 certificate.wireEncode(encoder, sigValue);
575
576 key.addCertificate(certificate);
577 return certificate;
578}
579
580std::tuple<Name, SignatureInfo>
581KeyChain::prepareSignatureInfo(const SigningInfo& params)
582{
583 SignatureInfo sigInfo = params.getSignatureInfo();
584
585 Name identityName;
586 name::Component keyId;
587 Name certificateName;
588
589 pib::Identity identity;
590 pib::Key key;
591
592 switch (params.getSignerType()) {
593 case SigningInfo::SIGNER_TYPE_NULL: {
594 try {
595 identity = m_pib->getDefaultIdentity();
596 }
597 catch (const Pib::Error&) { // no default identity, use sha256 for signing.
598 sigInfo.setSignatureType(tlv::DigestSha256);
599 return std::make_tuple(SigningInfo::getDigestSha256Identity(), sigInfo);
600 }
601 break;
602 }
603 case SigningInfo::SIGNER_TYPE_ID: {
604 try {
605 identity = m_pib->getIdentity(params.getSignerName());
606 }
607 catch (const Pib::Error&) {
608 BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing identity `" +
609 params.getSignerName().toUri() + "` does not exist"));
610 }
611 break;
612 }
613 case SigningInfo::SIGNER_TYPE_KEY: {
614 Name identityName = extractIdentityFromKeyName(params.getSignerName());
615
616 try {
617 identity = m_pib->getIdentity(identityName);
618 key = identity.getKey(params.getSignerName());
619 identity = Identity(); // we will use the PIB key instance, so reset identity;
620 }
621 catch (const Pib::Error&) {
622 BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing key `" +
623 params.getSignerName().toUri() + "` does not exist"));
624 }
625 break;
626 }
627 case SigningInfo::SIGNER_TYPE_CERT: {
628 Name identityName = extractIdentityFromCertName(params.getSignerName());
629 Name keyName = extractKeyNameFromCertName(params.getSignerName());
630
631 try {
632 identity = m_pib->getIdentity(identityName);
633 key = identity.getKey(keyName);
634 }
635 catch (const Pib::Error&) {
636 BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing certificate `" +
637 params.getSignerName().toUri() + "` does not exist"));
638 }
639
640 break;
641 }
642 case SigningInfo::SIGNER_TYPE_SHA256: {
643 sigInfo.setSignatureType(tlv::DigestSha256);
644 return std::make_tuple(SigningInfo::getDigestSha256Identity(), sigInfo);
645 }
Alexander Afanasyevd6d78aa2017-01-02 18:14:23 -0800646 case SigningInfo::SIGNER_TYPE_PIB_ID: {
647 identity = params.getPibIdentity();
648 if (!identity)
649 BOOST_THROW_EXCEPTION(InvalidSigningInfoError("PIB Identity is invalid"));
650 break;
651 }
652 case SigningInfo::SIGNER_TYPE_PIB_KEY: {
653 key = params.getPibKey();
654 if (!key)
655 BOOST_THROW_EXCEPTION(InvalidSigningInfoError("PIB Key is invalid"));
656 break;
657 }
Yingdi Yufe4733a2015-10-22 14:24:12 -0700658 default: {
659 BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Unrecognized signer type " +
660 boost::lexical_cast<std::string>(params.getSignerType())));
661 }
662 }
663
664 if (!identity && !key) {
665 BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Cannot determine signing parameters"));
666 }
667
668 if (identity && !key) {
669 try {
670 key = identity.getDefaultKey();
671 }
672 catch (const Pib::Error&) {
673 BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Signing identity `" + identity.getName().toUri() +
674 "` does not have default certificate"));
675 }
676 }
677
678 BOOST_ASSERT(key);
679
680 sigInfo.setSignatureType(getSignatureType(key.getKeyType(), params.getDigestAlgorithm()));
681 sigInfo.setKeyLocator(KeyLocator(key.getName()));
682 return std::make_tuple(key.getName(), sigInfo);
683}
684
685Block
686KeyChain::sign(const uint8_t* buf, size_t size,
687 const Name& keyName, DigestAlgorithm digestAlgorithm) const
688{
689 if (keyName == SigningInfo::getDigestSha256Identity())
690 return Block(tlv::SignatureValue, crypto::sha256(buf, size));
691
692 return Block(tlv::SignatureValue, m_tpm->sign(buf, size, keyName, digestAlgorithm));
693}
694
695tlv::SignatureTypeValue
696KeyChain::getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm)
697{
698 switch (keyType) {
699 case KeyType::RSA:
700 return tlv::SignatureSha256WithRsa;
701 case KeyType::EC:
702 return tlv::SignatureSha256WithEcdsa;
703 default:
704 BOOST_THROW_EXCEPTION(Error("Unsupported key types"));
705 }
706}
707
708} // namespace v2
709} // namespace security
710} // namespace ndn