NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: 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  ConfigFile config;
127  const ConfigFile::Parsed& parsed = config.getParsedConfiguration();
128 
129  std::string pibLocator = parsed.get<std::string>("pib", "");
130  std::string tpmLocator = parsed.get<std::string>("tpm", "");
131 
132  initialize(pibLocator, tpmLocator, false);
133 }
134 
135 KeyChain::KeyChain(const std::string& pibName,
136  const std::string& tpmName,
137  bool allowReset)
138  : m_pib(nullptr)
139  , m_tpm(nullptr)
140  , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
141 {
142  initialize(pibName, tpmName, allowReset);
143 }
144 
146 {
147 }
148 
149 static inline std::tuple<std::string/*type*/, std::string/*location*/>
150 parseUri(const std::string& uri)
151 {
152  size_t pos = uri.find(':');
153  if (pos != std::string::npos) {
154  return std::make_tuple(uri.substr(0, pos),
155  uri.substr(pos + 1));
156  }
157  else {
158  return std::make_tuple(uri, "");
159  }
160 }
161 
162 std::string
164 {
165  std::string defaultPibLocator = DEFAULT_PIB_SCHEME + ":";
166  return defaultPibLocator;
167 }
168 
169 static inline std::tuple<std::string/*type*/, std::string/*location*/>
170 getCanonicalPibLocator(const std::string& pibLocator)
171 {
172  std::string pibScheme, pibLocation;
173  std::tie(pibScheme, pibLocation) = parseUri(pibLocator);
174 
175  if (pibScheme.empty()) {
176  pibScheme = DEFAULT_PIB_SCHEME;
177  }
178 
179  auto pibFactory = getPibFactories().find(pibScheme);
180  if (pibFactory == getPibFactories().end()) {
181  BOOST_THROW_EXCEPTION(KeyChain::Error("PIB scheme '" + pibScheme + "' is not supported"));
182  }
183  pibScheme = pibFactory->second.canonicalName;
184 
185  return std::make_tuple(pibScheme, pibLocation);
186 }
187 
188 unique_ptr<SecPublicInfo>
189 KeyChain::createPib(const std::string& pibLocator)
190 {
191  BOOST_ASSERT(!getPibFactories().empty());
192 
193  std::string pibScheme, pibLocation;
194  std::tie(pibScheme, pibLocation) = getCanonicalPibLocator(pibLocator);
195  auto pibFactory = getPibFactories().find(pibScheme);
196  BOOST_ASSERT(pibFactory != getPibFactories().end());
197  return pibFactory->second.create(pibLocation);
198 }
199 
200 std::string
202 {
203  std::string defaultTpmLocator = DEFAULT_TPM_SCHEME + ":";
204  return defaultTpmLocator;
205 }
206 
207 static inline std::tuple<std::string/*type*/, std::string/*location*/>
208 getCanonicalTpmLocator(const std::string& tpmLocator)
209 {
210  std::string tpmScheme, tpmLocation;
211  std::tie(tpmScheme, tpmLocation) = parseUri(tpmLocator);
212 
213  if (tpmScheme.empty()) {
214  tpmScheme = DEFAULT_TPM_SCHEME;
215  }
216  auto tpmFactory = getTpmFactories().find(tpmScheme);
217  if (tpmFactory == getTpmFactories().end()) {
218  BOOST_THROW_EXCEPTION(KeyChain::Error("TPM scheme '" + tpmScheme + "' is not supported"));
219  }
220  tpmScheme = tpmFactory->second.canonicalName;
221 
222  return std::make_tuple(tpmScheme, tpmLocation);
223 }
224 
225 unique_ptr<SecTpm>
226 KeyChain::createTpm(const std::string& tpmLocator)
227 {
228  BOOST_ASSERT(!getTpmFactories().empty());
229 
230  std::string tpmScheme, tpmLocation;
231  std::tie(tpmScheme, tpmLocation) = getCanonicalTpmLocator(tpmLocator);
232  auto tpmFactory = getTpmFactories().find(tpmScheme);
233  BOOST_ASSERT(tpmFactory != getTpmFactories().end());
234  return tpmFactory->second.create(tpmLocation);
235 }
236 
237 void
238 KeyChain::initialize(const std::string& pibLocator,
239  const std::string& tpmLocator,
240  bool allowReset)
241 {
242  // PIB Locator
243  std::string pibScheme, pibLocation;
244  std::tie(pibScheme, pibLocation) = getCanonicalPibLocator(pibLocator);
245  std::string canonicalPibLocator = pibScheme + ":" + pibLocation;
246 
247  // Create PIB
248  m_pib = createPib(canonicalPibLocator);
249 
250  // TPM Locator
251  std::string tpmScheme, tpmLocation;
252  std::tie(tpmScheme, tpmLocation) = getCanonicalTpmLocator(tpmLocator);
253  std::string canonicalTpmLocator = tpmScheme + ":" + tpmLocation;
254 
255  // Create TPM, checking that it matches to the previously associated one
256  try {
257  if (!allowReset &&
258  !m_pib->getTpmLocator().empty() && m_pib->getTpmLocator() != canonicalTpmLocator)
259  // Tpm mismatch, but we do not want to reset PIB
260  BOOST_THROW_EXCEPTION(MismatchError("TPM locator supplied does not match TPM locator in PIB: "
261  + m_pib->getTpmLocator() + " != " + canonicalTpmLocator));
262  }
263  catch (const SecPublicInfo::Error&) {
264  // TPM locator is not set in PIB yet.
265  }
266 
267  // note that key mismatch may still happen if the TPM locator is initially set to a
268  // wrong one or if the PIB was shared by more than one TPMs before. This is due to the
269  // old PIB does not have TPM info, new pib should not have this problem.
270  m_tpm = createTpm(canonicalTpmLocator);
271  m_pib->setTpmLocator(canonicalTpmLocator);
272 }
273 
274 Name
275 KeyChain::createIdentity(const Name& identityName, const KeyParams& params)
276 {
277  m_pib->addIdentity(identityName);
278 
279  Name keyName;
280  try {
281  keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
282 
283  shared_ptr<PublicKey> key = m_pib->getPublicKey(keyName);
284 
285  if (key->getKeyType() != params.getKeyType()) {
286  keyName = generateKeyPair(identityName, true, params);
287  m_pib->setDefaultKeyNameForIdentity(keyName);
288  }
289  }
290  catch (const SecPublicInfo::Error& e) {
291  keyName = generateKeyPair(identityName, true, params);
292  m_pib->setDefaultKeyNameForIdentity(keyName);
293  }
294 
295  Name certName;
296  try {
297  certName = m_pib->getDefaultCertificateNameForKey(keyName);
298  }
299  catch (const SecPublicInfo::Error& e) {
300  shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
301  m_pib->addCertificateAsIdentityDefault(*selfCert);
302  certName = selfCert->getName();
303  }
304 
305  return certName;
306 }
307 
308 Name
309 KeyChain::generateRsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
310 {
311  RsaKeyParams params(keySize);
312  return generateKeyPair(identityName, isKsk, params);
313 }
314 
315 Name
316 KeyChain::generateEcdsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
317 {
318  EcdsaKeyParams params(keySize);
319  return generateKeyPair(identityName, isKsk, params);
320 }
321 
322 Name
323 KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
324 {
325  RsaKeyParams params(keySize);
326 
327  Name keyName = generateKeyPair(identityName, isKsk, params);
328 
329  m_pib->setDefaultKeyNameForIdentity(keyName);
330 
331  return keyName;
332 }
333 
334 Name
335 KeyChain::generateEcdsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
336 {
337  EcdsaKeyParams params(keySize);
338 
339  Name keyName = generateKeyPair(identityName, isKsk, params);
340 
341  m_pib->setDefaultKeyNameForIdentity(keyName);
342 
343  return keyName;
344 }
345 
346 
347 shared_ptr<IdentityCertificate>
349  const Name& signingIdentity,
350  const time::system_clock::TimePoint& notBefore,
351  const time::system_clock::TimePoint& notAfter,
352  const std::vector<CertificateSubjectDescription>& subjectDescription,
353  const Name& certPrefix)
354 {
355  shared_ptr<PublicKey> publicKey;
356  try {
357  publicKey = m_pib->getPublicKey(keyName);
358  }
359  catch (const SecPublicInfo::Error& e) {
360  return nullptr;
361  }
362 
363  return prepareUnsignedIdentityCertificate(keyName, *publicKey, signingIdentity,
364  notBefore, notAfter,
365  subjectDescription, certPrefix);
366 }
367 
368 shared_ptr<IdentityCertificate>
370  const PublicKey& publicKey,
371  const Name& signingIdentity,
372  const time::system_clock::TimePoint& notBefore,
373  const time::system_clock::TimePoint& notAfter,
374  const std::vector<CertificateSubjectDescription>& subjectDescription,
375  const Name& certPrefix)
376 {
377  if (keyName.size() < 1)
378  return nullptr;
379 
380  std::string keyIdPrefix = keyName.get(-1).toUri().substr(0, 4);
381  if (keyIdPrefix != "ksk-" && keyIdPrefix != "dsk-")
382  return nullptr;
383 
384  Name certName;
385 
386  if (certPrefix == KeyChain::DEFAULT_PREFIX) {
387  // No certificate prefix hint, infer the prefix
388  if (signingIdentity.isPrefixOf(keyName))
389  certName.append(signingIdentity)
390  .append("KEY")
391  .append(keyName.getSubName(signingIdentity.size()))
392  .append("ID-CERT")
393  .appendVersion();
394  else
395  certName.append(keyName.getPrefix(-1))
396  .append("KEY")
397  .append(keyName.get(-1))
398  .append("ID-CERT")
399  .appendVersion();
400  }
401  else {
402  // cert prefix hint is supplied, determine the cert name.
403  if (certPrefix.isPrefixOf(keyName) && certPrefix != keyName)
404  certName.append(certPrefix)
405  .append("KEY")
406  .append(keyName.getSubName(certPrefix.size()))
407  .append("ID-CERT")
408  .appendVersion();
409  else
410  return nullptr;
411  }
412 
413  auto certificate = make_shared<IdentityCertificate>();
414  certificate->setName(certName);
415  certificate->setNotBefore(notBefore);
416  certificate->setNotAfter(notAfter);
417  certificate->setPublicKeyInfo(publicKey);
418 
419  if (subjectDescription.empty()) {
421  certificate->addSubjectDescription(subjectName);
422  }
423  else {
424  std::vector<CertificateSubjectDescription>::const_iterator sdIt =
425  subjectDescription.begin();
426  std::vector<CertificateSubjectDescription>::const_iterator sdEnd =
427  subjectDescription.end();
428  for(; sdIt != sdEnd; sdIt++)
429  certificate->addSubjectDescription(*sdIt);
430  }
431 
432  certificate->encode();
433 
434  return certificate;
435 }
436 
437 std::tuple<Name, SignatureInfo>
438 KeyChain::prepareSignatureInfo(const SigningInfo& params)
439 {
440  SignatureInfo sigInfo = params.getSignatureInfo();
441 
442  shared_ptr<IdentityCertificate> signingCert;
443 
444  switch (params.getSignerType()) {
446  if (m_pib->getDefaultCertificate() == nullptr)
447  setDefaultCertificateInternal();
448 
449  signingCert = m_pib->getDefaultCertificate();
450  break;
451  }
453  Name signingCertName;
454  try {
455  signingCertName = m_pib->getDefaultCertificateNameForIdentity(params.getSignerName());
456  }
457  catch (const SecPublicInfo::Error&) {
458  signingCertName = createIdentity(params.getSignerName(), getDefaultKeyParamsForIdentity(params.getSignerName()));
459  }
460 
461  signingCert = m_pib->getCertificate(signingCertName);
462 
463  break;
464  }
466  Name signingCertName;
467  try {
468  signingCertName = m_pib->getDefaultCertificateNameForKey(params.getSignerName());
469  }
470  catch (const SecPublicInfo::Error&) {
471  BOOST_THROW_EXCEPTION(Error("signing certificate does not exist"));
472  }
473 
474  signingCert = m_pib->getCertificate(signingCertName);
475 
476  break;
477  }
479  signingCert = m_pib->getCertificate(params.getSignerName());
480  if (signingCert == nullptr)
481  BOOST_THROW_EXCEPTION(Error("signing certificate does not exist"));
482 
483  break;
484  }
487  return std::make_tuple(DIGEST_SHA256_IDENTITY, sigInfo);
488  }
489  default:
490  BOOST_THROW_EXCEPTION(Error("Unrecognized signer type"));
491  }
492 
493  sigInfo.setSignatureType(getSignatureType(signingCert->getPublicKeyInfo().getKeyType(),
494  params.getDigestAlgorithm()));
495  sigInfo.setKeyLocator(KeyLocator(signingCert->getName().getPrefix(-1)));
496 
497  return std::make_tuple(signingCert->getPublicKeyName(), sigInfo);
498 }
499 
500 void
501 KeyChain::sign(Data& data, const SigningInfo& params)
502 {
503  signImpl(data, params);
504 }
505 
506 void
507 KeyChain::sign(Interest& interest, const SigningInfo& params)
508 {
509  signImpl(interest, params);
510 }
511 
512 Block
513 KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const SigningInfo& params)
514 {
515  Name keyName;
516  SignatureInfo sigInfo;
517  std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
518  return pureSign(buffer, bufferLength, keyName, DIGEST_ALGORITHM_SHA256);
519 }
520 
521 Signature
522 KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
523 {
524  shared_ptr<IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
525 
526  if (certificate == nullptr) {
527  BOOST_THROW_EXCEPTION(SecPublicInfo::Error("certificate does not exist"));
528  }
529 
530  Signature sig;
531 
532  // For temporary usage, we support SHA256 only, but will support more.
533  sig.setValue(m_tpm->signInTpm(buffer, bufferLength,
534  certificate->getPublicKeyName(),
536 
537  return sig;
538 }
539 
540 shared_ptr<IdentityCertificate>
541 KeyChain::selfSign(const Name& keyName)
542 {
543  shared_ptr<PublicKey> pubKey;
544  try {
545  pubKey = m_pib->getPublicKey(keyName); // may throw an exception.
546  }
547  catch (const SecPublicInfo::Error&) {
548  return nullptr;
549  }
550 
551  auto certificate = make_shared<IdentityCertificate>();
552 
553  Name certificateName = keyName.getPrefix(-1);
554  certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
555 
556  certificate->setName(certificateName);
557  certificate->setNotBefore(time::system_clock::now());
558  certificate->setNotAfter(time::system_clock::now() + time::days(7300)); // ~20 years
559  certificate->setPublicKeyInfo(*pubKey);
560  certificate->addSubjectDescription(CertificateSubjectDescription(oid::ATTRIBUTE_NAME,
561  keyName.toUri()));
562  certificate->encode();
563 
564  certificate->setSignature(Signature(SignatureInfo()));
565 
566  selfSign(*certificate);
567  return certificate;
568 }
569 
570 void
572 {
573  Name keyName = cert.getPublicKeyName();
574  if (!m_tpm->doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
575  BOOST_THROW_EXCEPTION(SecTpm::Error("Private key does not exist"));
576 
577  SignatureInfo sigInfo(cert.getSignature().getInfo());
578  sigInfo.setKeyLocator(KeyLocator(cert.getName().getPrefix(-1)));
579  sigInfo.setSignatureType(getSignatureType(cert.getPublicKeyInfo().getKeyType(),
581 
582  signPacketWrapper(cert, Signature(sigInfo), keyName, DIGEST_ALGORITHM_SHA256);
583 }
584 
585 shared_ptr<SecuredBag>
586 KeyChain::exportIdentity(const Name& identity, const std::string& passwordStr)
587 {
588  if (!m_pib->doesIdentityExist(identity))
589  BOOST_THROW_EXCEPTION(SecPublicInfo::Error("Identity does not exist"));
590 
591  Name keyName = m_pib->getDefaultKeyNameForIdentity(identity);
592 
593  ConstBufferPtr pkcs5;
594  try {
595  pkcs5 = m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, passwordStr);
596  }
597  catch (const SecTpm::Error& e) {
598  BOOST_THROW_EXCEPTION(SecPublicInfo::Error("Fail to export PKCS5 of private key"));
599  }
600 
601  shared_ptr<IdentityCertificate> cert;
602  try {
603  cert = m_pib->getCertificate(m_pib->getDefaultCertificateNameForKey(keyName));
604  }
605  catch (const SecPublicInfo::Error& e) {
606  cert = selfSign(keyName);
607  m_pib->addCertificateAsIdentityDefault(*cert);
608  }
609 
610  // make_shared on OSX 10.9 has some strange problem here
611  return shared_ptr<SecuredBag>(new SecuredBag(*cert, pkcs5));
612 }
613 
614 void
615 KeyChain::importIdentity(const SecuredBag& securedBag, const std::string& passwordStr)
616 {
617  Name certificateName = securedBag.getCertificate().getName();
619  Name identity = keyName.getPrefix(-1);
620 
621  // Add identity
622  m_pib->addIdentity(identity);
623 
624  // Add key
625  m_tpm->importPrivateKeyPkcs5IntoTpm(keyName,
626  securedBag.getKey()->buf(),
627  securedBag.getKey()->size(),
628  passwordStr);
629 
630  shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
631  // HACK! We should set key type according to the pkcs8 info.
632  m_pib->addKey(keyName, *pubKey);
633  m_pib->setDefaultKeyNameForIdentity(keyName);
634 
635  // Add cert
636  m_pib->addCertificateAsIdentityDefault(securedBag.getCertificate());
637 }
638 
639 const KeyParams&
641 {
642  KeyType keyType = KEY_TYPE_NULL;
643  try {
644  keyType = m_pib->getPublicKeyType(m_pib->getDefaultKeyNameForIdentity(identityName));
645  }
646  catch (const SecPublicInfo::Error& e) { // @TODO Switch to Pib::Error
647  return DEFAULT_KEY_PARAMS;
648  }
649 
650  switch (keyType) {
651  case KEY_TYPE_RSA: {
652  static RsaKeyParams defaultRsaParams;
653  return defaultRsaParams;
654  }
655  case KEY_TYPE_ECDSA: {
656  static EcdsaKeyParams defaultEcdsaParams;
657  return defaultEcdsaParams;
658  }
659  case KEY_TYPE_NULL: {
660  return DEFAULT_KEY_PARAMS;
661  }
662  default:
663  BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
664  }
665 }
666 
667 void
668 KeyChain::setDefaultCertificateInternal()
669 {
670  m_pib->refreshDefaultCertificate();
671 
672  if (m_pib->getDefaultCertificate() == nullptr) {
673  Name defaultIdentity;
674  try {
675  defaultIdentity = m_pib->getDefaultIdentity();
676  }
677  catch (const SecPublicInfo::Error& e) {
678  uint32_t random = random::generateWord32();
679  defaultIdentity.append("tmp-identity")
680  .append(reinterpret_cast<uint8_t*>(&random), 4);
681  }
682  createIdentity(defaultIdentity);
683  m_pib->setDefaultIdentity(defaultIdentity);
684  m_pib->refreshDefaultCertificate();
685  }
686 }
687 
688 Name
689 KeyChain::generateKeyPair(const Name& identityName, bool isKsk, const KeyParams& params)
690 {
691  Name keyName = m_pib->getNewKeyName(identityName, isKsk);
692 
693  m_tpm->generateKeyPairInTpm(keyName.toUri(), params);
694 
695  shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
696  m_pib->addKey(keyName, *pubKey);
697 
698  return keyName;
699 }
700 
701 void
702 KeyChain::signPacketWrapper(Data& data, const Signature& signature,
703  const Name& keyName, DigestAlgorithm digestAlgorithm)
704 {
705  data.setSignature(signature);
706 
707  EncodingBuffer encoder;
708  data.wireEncode(encoder, true);
709 
710  Block sigValue = pureSign(encoder.buf(), encoder.size(), keyName, digestAlgorithm);
711 
712  data.wireEncode(encoder, sigValue);
713 }
714 
715 void
716 KeyChain::signPacketWrapper(Interest& interest, const Signature& signature,
717  const Name& keyName, DigestAlgorithm digestAlgorithm)
718 {
719  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
720  if (timestamp <= m_lastTimestamp) {
721  timestamp = m_lastTimestamp + time::milliseconds(1);
722  }
723 
724  Name signedName = interest.getName();
725  signedName
726  .append(name::Component::fromNumber(timestamp.count())) // timestamp
728  .append(signature.getInfo()); // signatureInfo
729 
730  Block sigValue = pureSign(signedName.wireEncode().value(),
731  signedName.wireEncode().value_size(),
732  keyName,
733  digestAlgorithm);
734 
735  sigValue.encode();
736  signedName.append(sigValue); // signatureValue
737  interest.setName(signedName);
738 }
739 
740 Block
741 KeyChain::pureSign(const uint8_t* buf, size_t size,
742  const Name& keyName, DigestAlgorithm digestAlgorithm) const
743 {
744  if (keyName == DIGEST_SHA256_IDENTITY)
745  return Block(tlv::SignatureValue, crypto::sha256(buf, size));
746 
747  return m_tpm->signInTpm(buf, size, keyName, digestAlgorithm);
748 }
749 
750 Signature
751 KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
752 {
753  Signature sig;
754  sig.setValue(sign(buffer, bufferLength, signingByIdentity(identityName)));
755  return sig;
756 }
757 
758 void
760 {
761  return sign(data, signingWithSha256());
762 }
763 
764 void
766 {
767  DigestSha256 sig;
768 
769  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
770  if (timestamp <= m_lastTimestamp)
771  timestamp = m_lastTimestamp + time::milliseconds(1);
772 
773  Name signedName = interest.getName();
774  signedName
775  .append(name::Component::fromNumber(timestamp.count())) // timestamp
777  .append(sig.getInfo()); // signatureInfo
778 
779  Block sigValue(tlv::SignatureValue,
780  crypto::sha256(signedName.wireEncode().value(),
781  signedName.wireEncode().value_size()));
782 
783  sigValue.encode();
784  signedName.append(sigValue); // signatureValue
785  interest.setName(signedName);
786 }
787 
788 void
789 KeyChain::deleteCertificate(const Name& certificateName)
790 {
791  m_pib->deleteCertificateInfo(certificateName);
792 }
793 
794 void
795 KeyChain::deleteKey(const Name& keyName)
796 {
797  m_pib->deletePublicKeyInfo(keyName);
798  m_tpm->deleteKeyPairInTpm(keyName);
799 }
800 
801 void
803 {
804  std::vector<Name> keyNames;
805  m_pib->getAllKeyNamesOfIdentity(identity, keyNames, true);
806  m_pib->getAllKeyNamesOfIdentity(identity, keyNames, false);
807 
808  m_pib->deleteIdentityInfo(identity);
809 
810  for (const auto& keyName : keyNames)
811  m_tpm->deleteKeyPairInTpm(keyName);
812 }
813 
816 {
817  switch (keyType) {
818  case KEY_TYPE_RSA:
820  case KEY_TYPE_ECDSA:
822  default:
823  BOOST_THROW_EXCEPTION(Error("Unsupported key types"));
824  }
825 
826 }
827 
828 } // namespace security
829 } // namespace ndn
Factory< KeyChain::PibCreateFunc > PibFactory
Definition: key-chain.cpp:84
static const RsaKeyParams DEFAULT_KEY_PARAMS
Definition: key-chain.hpp:882
static std::tuple< std::string, std::string > getCanonicalTpmLocator(const std::string &tpmLocator)
Definition: key-chain.cpp:208
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:249
shared_ptr< IdentityCertificate > prepareUnsignedIdentityCertificate(const Name &keyName, const Name &signingIdentity, const time::system_clock::TimePoint &notBefore, const time::system_clock::TimePoint &notAfter, const std::vector< CertificateSubjectDescription > &subjectDescription, const Name &certPrefix=DEFAULT_PREFIX)
prepare an unsigned identity certificate
Definition: key-chain.cpp:348
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:75
std::string toUri() const
Encode this name as a URI.
Definition: name.cpp:183
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:419
A CertificateSubjectDescription represents the SubjectDescription entry in a Certificate.
void importIdentity(const SecuredBag &securedBag, const std::string &passwordStr)
import an identity.
Definition: key-chain.cpp:615
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:189
const Name & getName() const
Get name of the Data packet.
Definition: data.hpp:360
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:913
static Name certificateNameToPublicKeyName(const Name &certificateName)
Get the public key name from the full certificate name.
Error thrown when the supplied TPM locator to KeyChain constructor does not match the locator stored ...
Definition: key-chain.hpp:65
Class representing a wire element of NDN-TLV packet format.
Definition: block.hpp:43
represents an Interest packet
Definition: interest.hpp:45
#define NDN_CXX_KEYCHAIN_REGISTER_PIB(PibType,...)
Register SecPib class in ndn-cxx KeyChain.
Definition: key-chain.hpp:942
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:501
static time_point now() noexcept
Definition: time.cpp:45
const Name & getPublicKeyName() const
Signing parameters passed to KeyChain.
shared_ptr< SecuredBag > exportIdentity(const Name &identity, const std::string &passwordStr)
export an identity.
Definition: key-chain.cpp:586
PublicKey & getPublicKeyInfo()
const OID ATTRIBUTE_NAME("2.5.4.41")
Definition: oid.hpp:105
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 cryptographically non-secure random integer from the range [0, 2^32)
Definition: random.cpp:73
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:335
static std::tuple< std::string, std::string > getCanonicalPibLocator(const std::string &pibLocator)
Definition: key-chain.cpp:170
static const SigningInfo DEFAULT_SIGNING_INFO
Definition: key-chain.hpp:873
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:224
boost::property_tree::ptree Parsed
Definition: config-file.hpp:48
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:275
SigningInfo signingByIdentity(const Name &identity)
function< unique_ptr< SecTpm >const std::string &)> TpmCreateFunc
Definition: key-chain.hpp:76
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:201
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:320
signer is a certificate, use it directly
Factory(const std::string &canonicalName, const T &create)
Definition: key-chain.cpp:75
SigningInfo signingWithSha256()
const IdentityCertificate & getCertificate() const
Definition: secured-bag.hpp:61
void deleteIdentity(const Name &identity)
delete an identity.
Definition: key-chain.cpp:802
signer is a key, use its default certificate
size_t size() const
Get the number of components.
Definition: name.hpp:408
time_point TimePoint
Definition: time.hpp:78
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:309
static tlv::SignatureTypeValue getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm)
Definition: key-chain.cpp:815
KeyChain()
Constructor to create KeyChain with default PIB and TPM.
Definition: key-chain.cpp:121
uint64_t generateWord64()
Generate a cryptographically non-secure random integer from range [0, 2^64)
Definition: random.cpp:80
static unique_ptr< SecTpm > createTpm(const std::string &tpmLocator)
Create a TPM according to tpmLocator.
Definition: key-chain.cpp:226
static std::string getDefaultPibLocator()
Get default PIB locator.
Definition: key-chain.cpp:163
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:958
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:150
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:148
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
Definition: data.cpp:52
shared_ptr< IdentityCertificate > selfSign(const Name &keyName)
Generate a self-signed certificate for a public key.
Definition: key-chain.cpp:541
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:316
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:69
static const Name DEFAULT_PREFIX
Definition: key-chain.hpp:872
void signWithSha256(Data &data)
Set Sha256 weak signature for data.
Definition: key-chain.cpp:759
const Signature & getSignature() const
Definition: data.hpp:390
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:33
ConstBufferPtr sha256(const uint8_t *data, size_t dataLength)
Compute the sha-256 digest of data.
Definition: crypto.cpp:51
const KeyParams & getDefaultKeyParamsForIdentity(const Name &identityName) const
Get default key parameters for the specified identity.
Definition: key-chain.cpp:640
represents a Data packet
Definition: data.hpp:39
SimplePublicKeyParams is a template for public keys with only one parameter: size.
Definition: key-params.hpp:110
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:323
static const Name DIGEST_SHA256_IDENTITY
A localhost identity which indicates that signature is generated using SHA-256.
Definition: key-chain.hpp:879
void deleteKey(const Name &keyName)
delete a key.
Definition: key-chain.cpp:795
const Parsed & getParsedConfiguration() const
PartialName getSubName(ssize_t iStartComponent, size_t nComponents=npos) const
Extract a sub-name (PartialName) of nComponents components starting from iStartComponent.
Definition: name.cpp:274
ConstBufferPtr getKey() const
Definition: secured-bag.hpp:67
KeyType getKeyType() const
Definition: public-key.hpp:83
void deleteCertificate(const Name &certificateName)
delete a certificate.
Definition: key-chain.cpp:789
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:218
static std::map< std::string, TpmFactory > & getTpmFactories()
Definition: key-chain.cpp:95
const Name & getName() const
Definition: interest.hpp:218
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