34 #ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
36 #endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
44 #include <boost/lexical_cast.hpp>
59 #if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
61 #endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
70 std::string KeyChain::s_defaultPibLocator;
71 std::string KeyChain::s_defaultTpmLocator;
73 KeyChain::PibFactories&
74 KeyChain::getPibFactories()
76 static PibFactories pibFactories;
80 KeyChain::TpmFactories&
81 KeyChain::getTpmFactories()
83 static TpmFactories tpmFactories;
88 KeyChain::getDefaultPibScheme()
94 KeyChain::getDefaultTpmScheme()
96 #if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
100 #endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
104 KeyChain::getDefaultPibLocator()
106 if (!s_defaultPibLocator.empty())
107 return s_defaultPibLocator;
109 if (getenv(
"NDN_CLIENT_PIB") !=
nullptr) {
110 s_defaultPibLocator = getenv(
"NDN_CLIENT_PIB");
114 s_defaultPibLocator = config.getParsedConfiguration().get<std::string>(
"pib", getDefaultPibScheme() +
":");
117 std::string pibScheme, pibLocation;
118 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(s_defaultPibLocator);
119 s_defaultPibLocator = pibScheme +
":" + pibLocation;
121 return s_defaultPibLocator;
125 KeyChain::getDefaultTpmLocator()
127 if (!s_defaultTpmLocator.empty())
128 return s_defaultTpmLocator;
130 if (getenv(
"NDN_CLIENT_TPM") !=
nullptr) {
131 s_defaultTpmLocator = getenv(
"NDN_CLIENT_TPM");
135 s_defaultTpmLocator = config.getParsedConfiguration().get<std::string>(
"tpm", getDefaultTpmScheme() +
":");
138 std::string tpmScheme, tpmLocation;
139 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(s_defaultTpmLocator);
140 s_defaultTpmLocator = tpmScheme +
":" + tpmLocation;
142 return s_defaultTpmLocator;
165 :
KeyChain(getDefaultPibLocator(), getDefaultTpmLocator(), true)
172 std::string pibScheme, pibLocation;
173 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
174 std::string canonicalPibLocator = pibScheme +
":" + pibLocation;
177 m_pib = createPib(canonicalPibLocator);
178 std::string oldTpmLocator;
180 oldTpmLocator = m_pib->getTpmLocator();
187 std::string tpmScheme, tpmLocation;
188 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
189 std::string canonicalTpmLocator = tpmScheme +
":" + tpmLocation;
191 if (canonicalPibLocator == getDefaultPibLocator()) {
193 if (!oldTpmLocator.empty() && oldTpmLocator != getDefaultTpmLocator()) {
195 canonicalTpmLocator = getDefaultTpmLocator();
200 if (!oldTpmLocator.empty() && oldTpmLocator != canonicalTpmLocator) {
205 oldTpmLocator +
" != " + canonicalTpmLocator));
212 m_tpm = createTpm(canonicalTpmLocator);
213 m_pib->setTpmLocator(canonicalTpmLocator);
223 Identity id = m_pib->addIdentity(identityName);
227 key =
id.getDefaultKey();
247 BOOST_ASSERT(
static_cast<bool>(identity));
251 for (
const auto& key : identity.
getKeys()) {
252 m_tpm->deleteKey(key.getName());
255 m_pib->removeIdentity(identityName);
261 BOOST_ASSERT(
static_cast<bool>(identity));
263 m_pib->setDefaultIdentity(identity.
getName());
269 BOOST_ASSERT(
static_cast<bool>(identity));
272 Name keyName = m_tpm->createKey(identity.
getName(), params);
276 Key key = identity.addKey(pubKey->data(), pubKey->size(), keyName);
287 return m_tpm->createKey(prefix, params);
293 BOOST_ASSERT(
static_cast<bool>(identity));
294 BOOST_ASSERT(
static_cast<bool>(key));
299 "does not match key `" + keyName.
toUri() +
"`"));
303 m_tpm->deleteKey(keyName);
309 BOOST_ASSERT(
static_cast<bool>(identity));
310 BOOST_ASSERT(
static_cast<bool>(key));
322 BOOST_ASSERT(
static_cast<bool>(key));
328 "does not match certificate `" + certificate.
getName().
toUri() +
"`"));
330 key.addCertificate(certificate);
336 BOOST_ASSERT(
static_cast<bool>(key));
339 NDN_THROW(std::invalid_argument(
"Wrong certificate name `" + certificateName.
toUri() +
"`"));
348 BOOST_ASSERT(
static_cast<bool>(key));
362 encryptedKey = m_tpm->exportPrivateKey(keyName, pw, pwLen);
368 return make_shared<SafeBag>(certificate, *encryptedKey);
380 if (m_tpm->hasKey(keyName)) {
385 Identity existingId = m_pib->getIdentity(identity);
386 existingId.
getKey(keyName);
394 m_tpm->importPrivateKey(keyName,
403 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
408 catch (
const std::runtime_error&) {
409 m_tpm->deleteKey(keyName);
412 bool isVerified =
false;
416 publicKey.loadPkcs8(publicKeyBits.data(), publicKeyBits.size());
418 sigBits->data(), sigBits->size())
422 m_tpm->deleteKey(keyName);
424 "and private key `" + keyName.
toUri() +
"` do not match"));
427 Identity id = m_pib->addIdentity(identity);
429 key.addCertificate(cert);
435 if (m_tpm->hasKey(keyName)) {
440 m_tpm->importPrivateKey(keyName,
std::move(key));
454 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
471 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
480 signedName.
append(sigValue);
489 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
496 static inline std::tuple<std::string, std::string>
499 size_t pos = uri.find(
':');
500 if (pos != std::string::npos) {
501 return std::make_tuple(uri.substr(0, pos), uri.substr(pos + 1));
504 return std::make_tuple(uri,
"");
508 std::tuple<std::string, std::string>
509 KeyChain::parseAndCheckPibLocator(
const std::string& pibLocator)
511 std::string pibScheme, pibLocation;
514 if (pibScheme.empty()) {
515 pibScheme = getDefaultPibScheme();
518 auto pibFactory = getPibFactories().find(pibScheme);
519 if (pibFactory == getPibFactories().end()) {
523 return std::make_tuple(pibScheme, pibLocation);
527 KeyChain::createPib(
const std::string& pibLocator)
529 std::string pibScheme, pibLocation;
530 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
531 auto pibFactory = getPibFactories().find(pibScheme);
532 BOOST_ASSERT(pibFactory != getPibFactories().end());
533 return unique_ptr<Pib>(
new Pib(pibScheme, pibLocation, pibFactory->second(pibLocation)));
536 std::tuple<std::string, std::string>
537 KeyChain::parseAndCheckTpmLocator(
const std::string& tpmLocator)
539 std::string tpmScheme, tpmLocation;
542 if (tpmScheme.empty()) {
543 tpmScheme = getDefaultTpmScheme();
545 auto tpmFactory = getTpmFactories().find(tpmScheme);
546 if (tpmFactory == getTpmFactories().end()) {
547 NDN_THROW(KeyChain::Error(
"TPM scheme `" + tpmScheme +
"` is not supported"));
550 return std::make_tuple(tpmScheme, tpmLocation);
554 KeyChain::createTpm(
const std::string& tpmLocator)
556 std::string tpmScheme, tpmLocation;
557 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
558 auto tpmFactory = getTpmFactories().find(tpmScheme);
559 BOOST_ASSERT(tpmFactory != getTpmFactories().end());
560 return unique_ptr<Tpm>(
new Tpm(tpmScheme, tpmLocation, tpmFactory->second(tpmLocation)));
566 KeyChain::selfSign(Key& key)
568 Certificate certificate;
571 Name certificateName = key.getName();
575 certificate.setName(certificateName);
579 certificate.setFreshnessPeriod(1_h);
582 certificate.setContent(key.getPublicKey().data(), key.getPublicKey().size());
591 sign(certificate, SigningInfo(key).setSignatureInfo(signatureInfo));
593 key.addCertificate(certificate);
597 std::tuple<Name, SignatureInfo>
598 KeyChain::prepareSignatureInfo(
const SigningInfo& params)
601 pib::Identity identity;
604 switch (params.getSignerType()) {
607 identity = m_pib->getDefaultIdentity();
609 catch (
const Pib::Error&) {
617 identity = params.getPibIdentity();
620 identity = m_pib->getIdentity(params.getSignerName());
622 catch (
const Pib::Error&) {
624 params.getSignerName().toUri() +
"` does not exist"));
630 key = params.getPibKey();
634 key = m_pib->getIdentity(identityName).getKey(params.getSignerName());
636 catch (
const Pib::Error&) {
638 params.getSignerName().toUri() +
"` does not exist"));
647 identity = m_pib->getIdentity(identityName);
648 key = identity.getKey(keyName);
650 catch (
const Pib::Error&) {
652 params.getSignerName().toUri() +
"` does not exist"));
662 const Name& keyName = params.getSignerName();
663 if (!m_tpm->hasKey(keyName)) {
664 m_tpm->importPrivateKey(keyName, params.getHmacKey());
666 sigInfo.setSignatureType(getSignatureType(
KeyType::HMAC, params.getDigestAlgorithm()));
667 sigInfo.setKeyLocator(keyName);
669 return std::make_tuple(keyName, sigInfo);
672 NDN_THROW(InvalidSigningInfoError(
"Unrecognized signer type " +
673 boost::lexical_cast<std::string>(params.getSignerType())));
679 NDN_THROW(InvalidSigningInfoError(
"Cannot determine signing parameters"));
682 key = identity.getDefaultKey();
684 catch (
const Pib::Error&) {
685 NDN_THROW_NESTED(InvalidSigningInfoError(
"Signing identity `" + identity.getName().toUri() +
686 "` does not have a default certificate"));
692 sigInfo.setSignatureType(getSignatureType(key.getKeyType(), params.getDigestAlgorithm()));
693 sigInfo.setKeyLocator(key.getName());
696 return std::make_tuple(key.getName(), sigInfo);
720 NDN_THROW(Error(
"Unsupported key type " + boost::lexical_cast<std::string>(keyType)));