NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
key-chain.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
24 #include "key-chain.hpp"
25 #include "signing-helpers.hpp"
26 
27 #include "../util/random.hpp"
28 #include "../util/config-file.hpp"
29 
31 
32 #ifdef NDN_CXX_HAVE_OSX_SECURITY
33 #include "sec-tpm-osx.hpp"
34 #endif // NDN_CXX_HAVE_OSX_SECURITY
35 
36 #include "sec-tpm-file.hpp"
37 
38 namespace ndn {
39 namespace security {
40 
41 // Use a GUID as a magic number of KeyChain::DEFAULT_PREFIX identifier
42 const Name KeyChain::DEFAULT_PREFIX("/723821fd-f534-44b3-80d9-44bf5f58bbbb");
43 const Name KeyChain::DIGEST_SHA256_IDENTITY("/localhost/identity/digest-sha256");
44 
45 // Note: cannot use default constructor, as it depends on static variables which may or may not be
46 // initialized at this point
48 
50 
51 const std::string DEFAULT_PIB_SCHEME = "pib-sqlite3";
52 
53 #if defined(NDN_CXX_HAVE_OSX_SECURITY) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
54 const std::string DEFAULT_TPM_SCHEME = "tpm-osxkeychain";
55 #else
56 const std::string DEFAULT_TPM_SCHEME = "tpm-file";
57 #endif // defined(NDN_CXX_HAVE_OSX_SECURITY) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
58 
59 // When static library is used, not everything is compiled into the resulting binary.
60 // Therefore, the following standard PIB and TPMs need to be registered here.
61 // http://stackoverflow.com/q/9459980/2150331
62 //
63 // Also, cannot use Type::SCHEME, as its value may be uninitialized
65 
66 #ifdef NDN_CXX_HAVE_OSX_SECURITY
67 NDN_CXX_KEYCHAIN_REGISTER_TPM(SecTpmOsx, "tpm-osxkeychain", "osx-keychain");
68 #endif // NDN_CXX_HAVE_OSX_SECURITY
69 
71 
72 template<class T>
73 struct Factory
74 {
75  Factory(const std::string& canonicalName, const T& create)
76  : canonicalName(canonicalName)
77  , create(create)
78  {
79  }
80 
81  std::string canonicalName;
82  T create;
83 };
86 
87 static std::map<std::string, PibFactory>&
89 {
90  static std::map<std::string, PibFactory> pibFactories;
91  return pibFactories;
92 }
93 
94 static std::map<std::string, TpmFactory>&
96 {
97  static std::map<std::string, TpmFactory> tpmFactories;
98  return tpmFactories;
99 }
100 
101 void
102 KeyChain::registerPibImpl(const std::string& canonicalName,
103  std::initializer_list<std::string> aliases,
104  KeyChain::PibCreateFunc createFunc)
105 {
106  for (const std::string& alias : aliases) {
107  getPibFactories().insert(make_pair(alias, PibFactory(canonicalName, createFunc)));
108  }
109 }
110 
111 void
112 KeyChain::registerTpmImpl(const std::string& canonicalName,
113  std::initializer_list<std::string> aliases,
114  KeyChain::TpmCreateFunc createFunc)
115 {
116  for (const std::string& alias : aliases) {
117  getTpmFactories().insert(make_pair(alias, TpmFactory(canonicalName, createFunc)));
118  }
119 }
120 
122  : m_pib(nullptr)
123  , m_tpm(nullptr)
124  , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
125 {
126  std::string pibLocator;
127  std::string tpmLocator;
128 
129  if (getenv("NDN_CLIENT_PIB") != nullptr) {
130  pibLocator = getenv("NDN_CLIENT_PIB");
131  }
132 
133  if (getenv("NDN_CLIENT_TPM") != nullptr) {
134  tpmLocator = getenv("NDN_CLIENT_TPM");
135  }
136 
137  if (pibLocator.empty() || tpmLocator.empty()) {
138  ConfigFile config;
139  const ConfigFile::Parsed& parsed = config.getParsedConfiguration();
140 
141  if (pibLocator.empty()) {
142  pibLocator = parsed.get<std::string>("pib", "");
143  }
144 
145  if (tpmLocator.empty()) {
146  tpmLocator = parsed.get<std::string>("tpm", "");
147  }
148  }
149 
150  initialize(pibLocator, tpmLocator, false);
151 }
152 
153 KeyChain::KeyChain(const std::string& pibName,
154  const std::string& tpmName,
155  bool allowReset)
156  : m_pib(nullptr)
157  , m_tpm(nullptr)
158  , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
159 {
160  initialize(pibName, tpmName, allowReset);
161 }
162 
164 {
165 }
166 
167 static inline std::tuple<std::string/*type*/, std::string/*location*/>
168 parseUri(const std::string& uri)
169 {
170  size_t pos = uri.find(':');
171  if (pos != std::string::npos) {
172  return std::make_tuple(uri.substr(0, pos),
173  uri.substr(pos + 1));
174  }
175  else {
176  return std::make_tuple(uri, "");
177  }
178 }
179 
180 std::string
182 {
183  std::string defaultPibLocator = DEFAULT_PIB_SCHEME + ":";
184  return defaultPibLocator;
185 }
186 
187 static inline std::tuple<std::string/*type*/, std::string/*location*/>
188 getCanonicalPibLocator(const std::string& pibLocator)
189 {
190  std::string pibScheme, pibLocation;
191  std::tie(pibScheme, pibLocation) = parseUri(pibLocator);
192 
193  if (pibScheme.empty()) {
194  pibScheme = DEFAULT_PIB_SCHEME;
195  }
196 
197  auto pibFactory = getPibFactories().find(pibScheme);
198  if (pibFactory == getPibFactories().end()) {
199  BOOST_THROW_EXCEPTION(KeyChain::Error("PIB scheme '" + pibScheme + "' is not supported"));
200  }
201  pibScheme = pibFactory->second.canonicalName;
202 
203  return std::make_tuple(pibScheme, pibLocation);
204 }
205 
206 unique_ptr<SecPublicInfo>
207 KeyChain::createPib(const std::string& pibLocator)
208 {
209  BOOST_ASSERT(!getPibFactories().empty());
210 
211  std::string pibScheme, pibLocation;
212  std::tie(pibScheme, pibLocation) = getCanonicalPibLocator(pibLocator);
213  auto pibFactory = getPibFactories().find(pibScheme);
214  BOOST_ASSERT(pibFactory != getPibFactories().end());
215  return pibFactory->second.create(pibLocation);
216 }
217 
218 std::string
220 {
221  std::string defaultTpmLocator = DEFAULT_TPM_SCHEME + ":";
222  return defaultTpmLocator;
223 }
224 
225 static inline std::tuple<std::string/*type*/, std::string/*location*/>
226 getCanonicalTpmLocator(const std::string& tpmLocator)
227 {
228  std::string tpmScheme, tpmLocation;
229  std::tie(tpmScheme, tpmLocation) = parseUri(tpmLocator);
230 
231  if (tpmScheme.empty()) {
232  tpmScheme = DEFAULT_TPM_SCHEME;
233  }
234  auto tpmFactory = getTpmFactories().find(tpmScheme);
235  if (tpmFactory == getTpmFactories().end()) {
236  BOOST_THROW_EXCEPTION(KeyChain::Error("TPM scheme '" + tpmScheme + "' is not supported"));
237  }
238  tpmScheme = tpmFactory->second.canonicalName;
239 
240  return std::make_tuple(tpmScheme, tpmLocation);
241 }
242 
243 unique_ptr<SecTpm>
244 KeyChain::createTpm(const std::string& tpmLocator)
245 {
246  BOOST_ASSERT(!getTpmFactories().empty());
247 
248  std::string tpmScheme, tpmLocation;
249  std::tie(tpmScheme, tpmLocation) = getCanonicalTpmLocator(tpmLocator);
250  auto tpmFactory = getTpmFactories().find(tpmScheme);
251  BOOST_ASSERT(tpmFactory != getTpmFactories().end());
252  return tpmFactory->second.create(tpmLocation);
253 }
254 
255 void
256 KeyChain::initialize(const std::string& pibLocator,
257  const std::string& tpmLocator,
258  bool allowReset)
259 {
260  // PIB Locator
261  std::string pibScheme, pibLocation;
262  std::tie(pibScheme, pibLocation) = getCanonicalPibLocator(pibLocator);
263  std::string canonicalPibLocator = pibScheme + ":" + pibLocation;
264 
265  // Create PIB
266  m_pib = createPib(canonicalPibLocator);
267 
268  // TPM Locator
269  std::string tpmScheme, tpmLocation;
270  std::tie(tpmScheme, tpmLocation) = getCanonicalTpmLocator(tpmLocator);
271  std::string canonicalTpmLocator = tpmScheme + ":" + tpmLocation;
272 
273  // Create TPM, checking that it matches to the previously associated one
274  try {
275  if (!allowReset &&
276  !m_pib->getTpmLocator().empty() && m_pib->getTpmLocator() != canonicalTpmLocator)
277  // Tpm mismatch, but we do not want to reset PIB
278  BOOST_THROW_EXCEPTION(MismatchError("TPM locator supplied does not match TPM locator in PIB: "
279  + m_pib->getTpmLocator() + " != " + canonicalTpmLocator));
280  }
281  catch (const SecPublicInfo::Error&) {
282  // TPM locator is not set in PIB yet.
283  }
284 
285  // note that key mismatch may still happen if the TPM locator is initially set to a
286  // wrong one or if the PIB was shared by more than one TPMs before. This is due to the
287  // old PIB does not have TPM info, new pib should not have this problem.
288  m_tpm = createTpm(canonicalTpmLocator);
289  m_pib->setTpmLocator(canonicalTpmLocator);
290 }
291 
292 Name
293 KeyChain::createIdentity(const Name& identityName, const KeyParams& params)
294 {
295  m_pib->addIdentity(identityName);
296 
297  Name keyName;
298  try {
299  keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
300 
301  shared_ptr<v1::PublicKey> key = m_pib->getPublicKey(keyName);
302 
303  if (key->getKeyType() != params.getKeyType()) {
304  keyName = generateKeyPair(identityName, true, params);
305  m_pib->setDefaultKeyNameForIdentity(keyName);
306  }
307  }
308  catch (const SecPublicInfo::Error& e) {
309  keyName = generateKeyPair(identityName, true, params);
310  m_pib->setDefaultKeyNameForIdentity(keyName);
311  }
312 
313  Name certName;
314  try {
315  certName = m_pib->getDefaultCertificateNameForKey(keyName);
316  }
317  catch (const SecPublicInfo::Error& e) {
318  shared_ptr<v1::IdentityCertificate> selfCert = selfSign(keyName);
319  m_pib->addCertificateAsIdentityDefault(*selfCert);
320  certName = selfCert->getName();
321  }
322 
323  return certName;
324 }
325 
326 Name
327 KeyChain::generateRsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
328 {
329  RsaKeyParams params(keySize);
330  return generateKeyPair(identityName, isKsk, params);
331 }
332 
333 Name
334 KeyChain::generateEcdsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
335 {
336  EcdsaKeyParams params(keySize);
337  return generateKeyPair(identityName, isKsk, params);
338 }
339 
340 Name
341 KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
342 {
343  RsaKeyParams params(keySize);
344 
345  Name keyName = generateKeyPair(identityName, isKsk, params);
346 
347  m_pib->setDefaultKeyNameForIdentity(keyName);
348 
349  return keyName;
350 }
351 
352 Name
353 KeyChain::generateEcdsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
354 {
355  EcdsaKeyParams params(keySize);
356 
357  Name keyName = generateKeyPair(identityName, isKsk, params);
358 
359  m_pib->setDefaultKeyNameForIdentity(keyName);
360 
361  return keyName;
362 }
363 
364 
365 shared_ptr<v1::IdentityCertificate>
367  const Name& signingIdentity,
368  const time::system_clock::TimePoint& notBefore,
369  const time::system_clock::TimePoint& notAfter,
370  const std::vector<v1::CertificateSubjectDescription>& subjectDescription,
371  const Name& certPrefix)
372 {
373  shared_ptr<v1::PublicKey> publicKey;
374  try {
375  publicKey = m_pib->getPublicKey(keyName);
376  }
377  catch (const SecPublicInfo::Error& e) {
378  return nullptr;
379  }
380 
381  return prepareUnsignedIdentityCertificate(keyName, *publicKey, signingIdentity,
382  notBefore, notAfter,
383  subjectDescription, certPrefix);
384 }
385 
386 shared_ptr<v1::IdentityCertificate>
388  const v1::PublicKey& publicKey,
389  const Name& signingIdentity,
390  const time::system_clock::TimePoint& notBefore,
391  const time::system_clock::TimePoint& notAfter,
392  const std::vector<v1::CertificateSubjectDescription>& subjectDescription,
393  const Name& certPrefix)
394 {
395  if (keyName.size() < 1)
396  return nullptr;
397 
398  std::string keyIdPrefix = keyName.get(-1).toUri().substr(0, 4);
399  if (keyIdPrefix != "ksk-" && keyIdPrefix != "dsk-")
400  return nullptr;
401 
402  Name certName;
403 
404  if (certPrefix == KeyChain::DEFAULT_PREFIX) {
405  // No certificate prefix hint, infer the prefix
406  if (signingIdentity.isPrefixOf(keyName))
407  certName.append(signingIdentity)
408  .append("KEY")
409  .append(keyName.getSubName(signingIdentity.size()))
410  .append("ID-CERT")
411  .appendVersion();
412  else
413  certName.append(keyName.getPrefix(-1))
414  .append("KEY")
415  .append(keyName.get(-1))
416  .append("ID-CERT")
417  .appendVersion();
418  }
419  else {
420  // cert prefix hint is supplied, determine the cert name.
421  if (certPrefix.isPrefixOf(keyName) && certPrefix != keyName)
422  certName.append(certPrefix)
423  .append("KEY")
424  .append(keyName.getSubName(certPrefix.size()))
425  .append("ID-CERT")
426  .appendVersion();
427  else
428  return nullptr;
429  }
430 
431  auto certificate = make_shared<v1::IdentityCertificate>();
432  certificate->setName(certName);
433  certificate->setNotBefore(notBefore);
434  certificate->setNotAfter(notAfter);
435  certificate->setPublicKeyInfo(publicKey);
436 
437  if (subjectDescription.empty()) {
439  certificate->addSubjectDescription(subjectName);
440  }
441  else {
442  std::vector<v1::CertificateSubjectDescription>::const_iterator sdIt = subjectDescription.begin();
443  std::vector<v1::CertificateSubjectDescription>::const_iterator sdEnd = subjectDescription.end();
444  for(; sdIt != sdEnd; sdIt++)
445  certificate->addSubjectDescription(*sdIt);
446  }
447 
448  certificate->encode();
449 
450  return certificate;
451 }
452 
453 std::tuple<Name, SignatureInfo>
454 KeyChain::prepareSignatureInfo(const SigningInfo& params)
455 {
456  SignatureInfo sigInfo = params.getSignatureInfo();
457 
458  shared_ptr<v1::IdentityCertificate> signingCert;
459 
460  switch (params.getSignerType()) {
462  if (m_pib->getDefaultCertificate() == nullptr)
463  setDefaultCertificateInternal();
464 
465  signingCert = m_pib->getDefaultCertificate();
466  break;
467  }
469  Name signingCertName;
470  try {
471  signingCertName = m_pib->getDefaultCertificateNameForIdentity(params.getSignerName());
472  }
473  catch (const SecPublicInfo::Error&) {
474  signingCertName = createIdentity(params.getSignerName(), getDefaultKeyParamsForIdentity(params.getSignerName()));
475  }
476 
477  signingCert = m_pib->getCertificate(signingCertName);
478 
479  break;
480  }
482  Name signingCertName;
483  try {
484  signingCertName = m_pib->getDefaultCertificateNameForKey(params.getSignerName());
485  }
486  catch (const SecPublicInfo::Error&) {
487  BOOST_THROW_EXCEPTION(Error("signing certificate does not exist"));
488  }
489 
490  signingCert = m_pib->getCertificate(signingCertName);
491 
492  break;
493  }
495  signingCert = m_pib->getCertificate(params.getSignerName());
496  if (signingCert == nullptr)
497  BOOST_THROW_EXCEPTION(Error("signing certificate does not exist"));
498 
499  break;
500  }
503  return std::make_tuple(DIGEST_SHA256_IDENTITY, sigInfo);
504  }
505  default:
506  BOOST_THROW_EXCEPTION(Error("Unrecognized signer type"));
507  }
508 
509  sigInfo.setSignatureType(getSignatureType(signingCert->getPublicKeyInfo().getKeyType(),
510  params.getDigestAlgorithm()));
511  sigInfo.setKeyLocator(KeyLocator(signingCert->getName().getPrefix(-1)));
512 
513  return std::make_tuple(signingCert->getPublicKeyName(), sigInfo);
514 }
515 
516 void
517 KeyChain::sign(Data& data, const SigningInfo& params)
518 {
519  signImpl(data, params);
520 }
521 
522 void
523 KeyChain::sign(Interest& interest, const SigningInfo& params)
524 {
525  signImpl(interest, params);
526 }
527 
528 Block
529 KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const SigningInfo& params)
530 {
531  Name keyName;
532  SignatureInfo sigInfo;
533  std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
534  return pureSign(buffer, bufferLength, keyName, DigestAlgorithm::SHA256);
535 }
536 
537 Signature
538 KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
539 {
540  shared_ptr<v1::IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
541 
542  if (certificate == nullptr) {
543  BOOST_THROW_EXCEPTION(SecPublicInfo::Error("certificate does not exist"));
544  }
545 
546  Signature sig;
547 
548  // For temporary usage, we support SHA256 only, but will support more.
549  sig.setValue(m_tpm->signInTpm(buffer, bufferLength,
550  certificate->getPublicKeyName(),
552 
553  return sig;
554 }
555 
556 shared_ptr<v1::IdentityCertificate>
557 KeyChain::selfSign(const Name& keyName)
558 {
559  shared_ptr<v1::PublicKey> pubKey;
560  try {
561  pubKey = m_pib->getPublicKey(keyName); // may throw an exception.
562  }
563  catch (const SecPublicInfo::Error&) {
564  return nullptr;
565  }
566 
567  auto certificate = make_shared<v1::IdentityCertificate>();
568 
569  Name certificateName = keyName.getPrefix(-1);
570  certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
571 
572  certificate->setName(certificateName);
573  certificate->setNotBefore(time::system_clock::now());
574  certificate->setNotAfter(time::system_clock::now() + time::days(7300)); // ~20 years
575  certificate->setPublicKeyInfo(*pubKey);
576  certificate->addSubjectDescription(v1::CertificateSubjectDescription(oid::ATTRIBUTE_NAME,
577  keyName.toUri()));
578  certificate->encode();
579 
580  certificate->setSignature(Signature(SignatureInfo()));
581 
582  selfSign(*certificate);
583  return certificate;
584 }
585 
586 void
588 {
589  Name keyName = cert.getPublicKeyName();
590 
591  if (!m_tpm->doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
592  BOOST_THROW_EXCEPTION(SecTpm::Error("Private key does not exist"));
593 
594  SignatureInfo sigInfo(cert.getSignature().getInfo());
595  sigInfo.setKeyLocator(KeyLocator(cert.getName().getPrefix(-1)));
596  sigInfo.setSignatureType(getSignatureType(cert.getPublicKeyInfo().getKeyType(),
598 
599  signPacketWrapper(cert, Signature(sigInfo), keyName, DigestAlgorithm::SHA256);
600 }
601 
602 shared_ptr<SecuredBag>
603 KeyChain::exportIdentity(const Name& identity, const std::string& passwordStr)
604 {
605  if (!m_pib->doesIdentityExist(identity))
606  BOOST_THROW_EXCEPTION(SecPublicInfo::Error("Identity does not exist"));
607 
608  Name keyName = m_pib->getDefaultKeyNameForIdentity(identity);
609 
610  ConstBufferPtr pkcs5;
611  try {
612  pkcs5 = m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, passwordStr);
613  }
614  catch (const SecTpm::Error& e) {
615  BOOST_THROW_EXCEPTION(SecPublicInfo::Error("Fail to export PKCS5 of private key"));
616  }
617 
618  shared_ptr<v1::IdentityCertificate> cert;
619  try {
620  cert = m_pib->getCertificate(m_pib->getDefaultCertificateNameForKey(keyName));
621  }
622  catch (const SecPublicInfo::Error& e) {
623  cert = selfSign(keyName);
624  m_pib->addCertificateAsIdentityDefault(*cert);
625  }
626 
627  // make_shared on OSX 10.9 has some strange problem here
628  return shared_ptr<SecuredBag>(new SecuredBag(*cert, pkcs5));
629 }
630 
631 void
632 KeyChain::importIdentity(const SecuredBag& securedBag, const std::string& passwordStr)
633 {
634  Name certificateName = securedBag.getCertificate().getName();
636  Name identity = keyName.getPrefix(-1);
637 
638  // Add identity
639  m_pib->addIdentity(identity);
640 
641  // Add key
642  m_tpm->importPrivateKeyPkcs5IntoTpm(keyName,
643  securedBag.getKey()->buf(),
644  securedBag.getKey()->size(),
645  passwordStr);
646 
647  shared_ptr<v1::PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
648  // HACK! We should set key type according to the pkcs8 info.
649  m_pib->addKey(keyName, *pubKey);
650  m_pib->setDefaultKeyNameForIdentity(keyName);
651 
652  // Add cert
653  m_pib->addCertificateAsIdentityDefault(securedBag.getCertificate());
654 }
655 
656 const KeyParams&
658 {
659  KeyType keyType = KeyType::NONE;
660  try {
661  keyType = m_pib->getPublicKeyType(m_pib->getDefaultKeyNameForIdentity(identityName));
662  }
663  catch (const SecPublicInfo::Error& e) { // @TODO Switch to Pib::Error
664  return DEFAULT_KEY_PARAMS;
665  }
666 
667  switch (keyType) {
668  case KeyType::RSA: {
669  static RsaKeyParams defaultRsaParams;
670  return defaultRsaParams;
671  }
672  case KeyType::EC: {
673  static EcdsaKeyParams defaultEcdsaParams;
674  return defaultEcdsaParams;
675  }
676  case KeyType::NONE: {
677  return DEFAULT_KEY_PARAMS;
678  }
679  default:
680  BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
681  }
682 }
683 
684 void
685 KeyChain::setDefaultCertificateInternal()
686 {
687  m_pib->refreshDefaultCertificate();
688 
689  if (m_pib->getDefaultCertificate() == nullptr) {
690  Name defaultIdentity;
691  try {
692  defaultIdentity = m_pib->getDefaultIdentity();
693  }
694  catch (const SecPublicInfo::Error& e) {
695  uint32_t random = random::generateWord32();
696  defaultIdentity.append("tmp-identity")
697  .append(reinterpret_cast<uint8_t*>(&random), 4);
698  }
699  createIdentity(defaultIdentity);
700  m_pib->setDefaultIdentity(defaultIdentity);
701  m_pib->refreshDefaultCertificate();
702  }
703 }
704 
705 Name
706 KeyChain::generateKeyPair(const Name& identityName, bool isKsk, const KeyParams& params)
707 {
708  Name keyName = m_pib->getNewKeyName(identityName, isKsk);
709 
710  m_tpm->generateKeyPairInTpm(keyName.toUri(), params);
711 
712  shared_ptr<v1::PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
713  m_pib->addKey(keyName, *pubKey);
714 
715  return keyName;
716 }
717 
718 void
719 KeyChain::signPacketWrapper(Data& data, const Signature& signature,
720  const Name& keyName, DigestAlgorithm digestAlgorithm)
721 {
722  data.setSignature(signature);
723 
724  EncodingBuffer encoder;
725  data.wireEncode(encoder, true);
726 
727  Block sigValue = pureSign(encoder.buf(), encoder.size(), keyName, digestAlgorithm);
728 
729  data.wireEncode(encoder, sigValue);
730 }
731 
732 void
733 KeyChain::signPacketWrapper(Interest& interest, const Signature& signature,
734  const Name& keyName, DigestAlgorithm digestAlgorithm)
735 {
736  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
737  if (timestamp <= m_lastTimestamp) {
738  timestamp = m_lastTimestamp + time::milliseconds(1);
739  }
740 
741  Name signedName = interest.getName();
742  signedName
743  .append(name::Component::fromNumber(timestamp.count())) // timestamp
745  .append(signature.getInfo()); // signatureInfo
746 
747  Block sigValue = pureSign(signedName.wireEncode().value(),
748  signedName.wireEncode().value_size(),
749  keyName,
750  digestAlgorithm);
751 
752  sigValue.encode();
753  signedName.append(sigValue); // signatureValue
754  interest.setName(signedName);
755 }
756 
757 Block
758 KeyChain::pureSign(const uint8_t* buf, size_t size,
759  const Name& keyName, DigestAlgorithm digestAlgorithm) const
760 {
761  if (keyName == DIGEST_SHA256_IDENTITY)
763 
764  return m_tpm->signInTpm(buf, size, keyName, digestAlgorithm);
765 }
766 
767 Signature
768 KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
769 {
770  Signature sig;
771  sig.setValue(sign(buffer, bufferLength, signingByIdentity(identityName)));
772  return sig;
773 }
774 
775 void
777 {
778  return sign(data, signingWithSha256());
779 }
780 
781 void
783 {
784  DigestSha256 sig;
785 
786  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
787  if (timestamp <= m_lastTimestamp)
788  timestamp = m_lastTimestamp + time::milliseconds(1);
789 
790  Name signedName = interest.getName();
791  signedName
792  .append(name::Component::fromNumber(timestamp.count())) // timestamp
794  .append(sig.getInfo()); // signatureInfo
795 
796  Block sigValue(tlv::SignatureValue,
797  crypto::computeSha256Digest(signedName.wireEncode().value(),
798  signedName.wireEncode().value_size()));
799 
800  sigValue.encode();
801  signedName.append(sigValue); // signatureValue
802  interest.setName(signedName);
803 }
804 
805 void
806 KeyChain::deleteCertificate(const Name& certificateName)
807 {
808  m_pib->deleteCertificateInfo(certificateName);
809 }
810 
811 void
812 KeyChain::deleteKey(const Name& keyName)
813 {
814  m_pib->deletePublicKeyInfo(keyName);
815  m_tpm->deleteKeyPairInTpm(keyName);
816 }
817 
818 void
820 {
821  std::vector<Name> keyNames;
822  m_pib->getAllKeyNamesOfIdentity(identity, keyNames, true);
823  m_pib->getAllKeyNamesOfIdentity(identity, keyNames, false);
824 
825  m_pib->deleteIdentityInfo(identity);
826 
827  for (const auto& keyName : keyNames)
828  m_tpm->deleteKeyPairInTpm(keyName);
829 }
830 
833 {
834  switch (keyType) {
835  case KeyType::RSA:
837  case KeyType::EC:
839  default:
840  BOOST_THROW_EXCEPTION(Error("Unsupported key types"));
841  }
842 
843 }
844 
845 } // namespace security
846 } // namespace ndn
Factory< KeyChain::PibCreateFunc > PibFactory
Definition: key-chain.cpp:84
static const RsaKeyParams DEFAULT_KEY_PARAMS
Definition: key-chain.hpp:881
static std::tuple< std::string, std::string > getCanonicalTpmLocator(const std::string &tpmLocator)
Definition: key-chain.cpp:226
static Component fromNumber(uint64_t number)
Create a component encoded as nonNegativeInteger.
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix (PartialName) of the name, containing first nComponents components.
Definition: name.hpp:241
static Name certificateNameToPublicKeyName(const Name &certificateName)
Get the public key name from the full certificate name.
static std::map< std::string, PibFactory > & getPibFactories()
Definition: key-chain.cpp:88
Copyright (c) 2011-2015 Regents of the University of California.
void setSignatureType(tlv::SignatureTypeValue type)
Set SignatureType.
function< unique_ptr< SecPublicInfo >const std::string &)> PibCreateFunc
Definition: key-chain.hpp:74
std::string toUri() const
Encode this name as a URI.
Definition: name.cpp:171
const SignatureInfo & getSignatureInfo() const
SimplePublicKeyParams< RsaKeyParamsInfo > RsaKeyParams
RsaKeyParams carries parameters for RSA key.
Definition: key-params.hpp:158
Data & setSignature(const Signature &signature)
Set the signature to a copy of the given signature.
Definition: data.cpp:275
const Component & get(ssize_t i) const
Get the component at the given index.
Definition: name.hpp:411
void importIdentity(const SecuredBag &securedBag, const std::string &passwordStr)
import an identity.
Definition: key-chain.cpp:632
const std::string DEFAULT_TPM_SCHEME
Definition: key-chain.cpp:56
static unique_ptr< SecPublicInfo > createPib(const std::string &pibLocator)
Create a PIB according to pibLocator.
Definition: key-chain.cpp:207
const Name & getName() const
Get name of the Data packet.
Definition: data.hpp:318
DigestAlgorithm getDigestAlgorithm() const
Represent a SHA256 digest.
void signByIdentity(T &packet, const Name &identityName)
Sign packet using the default certificate of a particular identity.
Definition: key-chain.hpp:912
Error thrown when the supplied TPM locator to KeyChain constructor does not match the locator stored ...
Definition: key-chain.hpp:64
shared_ptr< v1::IdentityCertificate > selfSign(const Name &keyName)
Generate a self-signed certificate for a public key.
Definition: key-chain.cpp:557
Class representing a wire element of NDN-TLV packet format.
Definition: block.hpp:43
represents an Interest packet
Definition: interest.hpp:42
#define NDN_CXX_KEYCHAIN_REGISTER_PIB(PibType,...)
Register SecPib class in ndn-cxx KeyChain.
Definition: key-chain.hpp:941
use sha256 digest, no signer needs to be specified
void sign(Data &data, const SigningInfo &params=DEFAULT_SIGNING_INFO)
Sign data according to the supplied signing information.
Definition: key-chain.cpp:517
static time_point now() noexcept
Definition: time.cpp:45
const Oid ATTRIBUTE_NAME("2.5.4.41")
Definition: oid.hpp:105
Signing parameters passed to KeyChain.
shared_ptr< SecuredBag > exportIdentity(const Name &identity, const std::string &passwordStr)
export an identity.
Definition: key-chain.cpp:603
Factory< KeyChain::TpmCreateFunc > TpmFactory
Definition: key-chain.cpp:85
const Name & getSignerName() const
void setKeyLocator(const KeyLocator &keyLocator)
Set KeyLocator.
uint32_t generateWord32()
Generate a non-cryptographically-secure random integer in the range [0, 2^32)
Definition: random.cpp:63
Name generateEcdsaKeyPairAsDefault(const Name &identityName, bool isKsk=false, uint32_t keySize=256)
Generate a pair of ECDSA keys for the specified identity and set it as default key for the identity...
Definition: key-chain.cpp:353
static std::tuple< std::string, std::string > getCanonicalPibLocator(const std::string &pibLocator)
Definition: key-chain.cpp:188
static const SigningInfo DEFAULT_SIGNING_INFO
Definition: key-chain.hpp:872
EncodingImpl< EncoderTag > EncodingBuffer
void setValue(const Block &value)
Get SignatureValue from a block.
Definition: signature.cpp:50
Interest & setName(const Name &name)
Definition: interest.hpp:221
boost::property_tree::ptree Parsed
Definition: config-file.hpp:62
no signer is specified, use default setting or follow the trust schema
const Block & getInfo() const
Get SignatureInfo in the wire format.
Definition: signature.hpp:70
Name createIdentity(const Name &identityName, const KeyParams &params=DEFAULT_KEY_PARAMS)
Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed ce...
Definition: key-chain.cpp:293
SigningInfo signingByIdentity(const Name &identity)
function< unique_ptr< SecTpm >const std::string &)> TpmCreateFunc
Definition: key-chain.hpp:75
void toUri(std::ostream &os) const
Write *this to the output stream, escaping characters according to the NDN URI Scheme.
static std::string getDefaultTpmLocator()
Get default TPM locator.
Definition: key-chain.cpp:219
A CertificateSubjectDescription represents the SubjectDescription entry in a Certificate.
Name abstraction to represent an absolute name.
Definition: name.hpp:46
KeyType getKeyType() const
Definition: key-params.hpp:54
bool isPrefixOf(const Name &name) const
Check if the N components of this name are the same as the first N components of the given name...
Definition: name.cpp:308
signer is a certificate, use it directly
Factory(const std::string &canonicalName, const T &create)
Definition: key-chain.cpp:75
SigningInfo signingWithSha256()
void deleteIdentity(const Name &identity)
delete an identity.
Definition: key-chain.cpp:819
signer is a key, use its default certificate
size_t size() const
Get the number of components.
Definition: name.hpp:400
time_point TimePoint
Definition: time.hpp:90
Name generateRsaKeyPair(const Name &identityName, bool isKsk=false, uint32_t keySize=2048)
Generate a pair of RSA keys for the specified identity.
Definition: key-chain.cpp:327
static tlv::SignatureTypeValue getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm)
Definition: key-chain.cpp:832
KeyChain()
Constructor to create KeyChain with default PIB and TPM.
Definition: key-chain.cpp:121
uint64_t generateWord64()
Generate a non-cryptographically-secure random integer in the range [0, 2^64)
Definition: random.cpp:70
static unique_ptr< SecTpm > createTpm(const std::string &tpmLocator)
Create a TPM according to tpmLocator.
Definition: key-chain.cpp:244
static std::string getDefaultPibLocator()
Get default PIB locator.
Definition: key-chain.cpp:181
const std::string DEFAULT_PIB_SCHEME
Definition: key-chain.cpp:51
#define NDN_CXX_KEYCHAIN_REGISTER_TPM(TpmType,...)
Register SecTpm class in ndn-cxx KeyChain.
Definition: key-chain.hpp:957
System configuration file for NDN platform.
Definition: config-file.hpp:48
void encode()
Encode subblocks into wire buffer.
Definition: block.cpp:355
milliseconds toUnixTimestamp(const system_clock::TimePoint &point)
Convert system_clock::TimePoint to UNIX timestamp.
Definition: time.cpp:118
static std::tuple< std::string, std::string > parseUri(const std::string &uri)
Definition: key-chain.cpp:168
SignatureTypeValue
Definition: tlv.hpp:95
Name & append(const uint8_t *value, size_t valueLength)
Append a new component, copying from value of length valueLength.
Definition: name.hpp:140
ConstBufferPtr computeSha256Digest(const uint8_t *data, size_t dataLength)
Compute the sha-256 digest of data.
Definition: crypto.cpp:31
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
Definition: data.cpp:52
Base class of key parameters.
Definition: key-params.hpp:35
signer is an identity, use its default key and default certificate
Name generateEcdsaKeyPair(const Name &identityName, bool isKsk=false, uint32_t keySize=256)
Generate a pair of ECDSA keys for the specified identity.
Definition: key-chain.cpp:334
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:122
static const Name DEFAULT_PREFIX
Definition: key-chain.hpp:871
void signWithSha256(Data &data)
Set Sha256 weak signature for data.
Definition: key-chain.cpp:776
const Signature & getSignature() const
Definition: data.hpp:348
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:33
const KeyParams & getDefaultKeyParamsForIdentity(const Name &identityName) const
Get default key parameters for the specified identity.
Definition: key-chain.cpp:657
ConstBufferPtr getKey() const
Definition: secured-bag.hpp:68
represents a Data packet
Definition: data.hpp:37
SimplePublicKeyParams is a template for public keys with only one parameter: size.
Definition: key-params.hpp:110
shared_ptr< v1::IdentityCertificate > prepareUnsignedIdentityCertificate(const Name &keyName, const Name &signingIdentity, const time::system_clock::TimePoint &notBefore, const time::system_clock::TimePoint &notAfter, const std::vector< security::v1::CertificateSubjectDescription > &subjectDescription, const Name &certPrefix=DEFAULT_PREFIX)
prepare an unsigned identity certificate
Definition: key-chain.cpp:366
Name generateRsaKeyPairAsDefault(const Name &identityName, bool isKsk=false, uint32_t keySize=2048)
Generate a pair of RSA keys for the specified identity and set it as default key for the identity...
Definition: key-chain.cpp:341
static const Name DIGEST_SHA256_IDENTITY
A localhost identity which indicates that signature is generated using SHA-256.
Definition: key-chain.hpp:878
KeyType getKeyType() const
Definition: public-key.hpp:85
void deleteKey(const Name &keyName)
delete a key.
Definition: key-chain.cpp:812
const Parsed & getParsedConfiguration() const
const v1::IdentityCertificate & getCertificate() const
Definition: secured-bag.hpp:62
PartialName getSubName(ssize_t iStartComponent, size_t nComponents=npos) const
Extract a sub-name (PartialName) of nComponents components starting from iStartComponent.
Definition: name.cpp:262
void deleteCertificate(const Name &certificateName)
delete a certificate.
Definition: key-chain.cpp:806
duration< boost::int_least32_t, boost::ratio< 86400 > > days
Definition: time.hpp:35
Name & appendVersion(uint64_t version)
Append version using NDN naming conventions.
Definition: name.cpp:206
static std::map< std::string, TpmFactory > & getTpmFactories()
Definition: key-chain.cpp:95
const Name & getName() const
Definition: interest.hpp:215
std::string canonicalName
Definition: key-chain.cpp:81
SignerType getSignerType() const
A Signature is storage for the signature-related information (info and value) in a Data packet...
Definition: signature.hpp:33