24 #include "../../util/config-file.hpp" 25 #include "../../util/logger.hpp" 26 #include "../../util/sha256.hpp" 28 #include "../pib/pib-sqlite3.hpp" 29 #include "../pib/pib-memory.hpp" 31 #ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS 32 #include "../tpm/back-end-osx.hpp" 33 #endif // NDN_CXX_HAVE_OSX_FRAMEWORKS 35 #include "../tpm/back-end-file.hpp" 36 #include "../tpm/back-end-mem.hpp" 38 #include "../transform/bool-sink.hpp" 39 #include "../transform/buffer-source.hpp" 40 #include "../transform/private-key.hpp" 41 #include "../transform/public-key.hpp" 42 #include "../transform/verifier-filter.hpp" 43 #include "../../encoding/buffer-stream.hpp" 45 #include <boost/lexical_cast.hpp> 66 #if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 68 #endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 78 std::string KeyChain::s_defaultPibLocator;
79 std::string KeyChain::s_defaultTpmLocator;
81 KeyChain::PibFactories&
82 KeyChain::getPibFactories()
84 static PibFactories pibFactories;
88 KeyChain::TpmFactories&
89 KeyChain::getTpmFactories()
91 static TpmFactories tpmFactories;
96 KeyChain::getDefaultPibScheme()
102 KeyChain::getDefaultTpmScheme()
104 #if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 108 #endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 112 KeyChain::getDefaultPibLocator()
114 if (!s_defaultPibLocator.empty())
115 return s_defaultPibLocator;
117 if (getenv(
"NDN_CLIENT_PIB") !=
nullptr) {
118 s_defaultPibLocator = getenv(
"NDN_CLIENT_PIB");
122 s_defaultPibLocator = config.
getParsedConfiguration().get<std::string>(
"pib", getDefaultPibScheme() +
":");
125 return s_defaultPibLocator;
129 KeyChain::getDefaultTpmLocator()
131 if (!s_defaultTpmLocator.empty())
132 return s_defaultTpmLocator;
134 if (getenv(
"NDN_CLIENT_TPM") !=
nullptr) {
135 s_defaultTpmLocator = getenv(
"NDN_CLIENT_TPM");
139 s_defaultTpmLocator = config.
getParsedConfiguration().get<std::string>(
"tpm", getDefaultTpmScheme() +
":");
142 return s_defaultTpmLocator;
149 KeyChain::getDefaultSigningInfo()
156 KeyChain::getDefaultKeyParams()
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();
182 catch (
const Pib::Error&) {
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) {
204 BOOST_THROW_EXCEPTION(
LocatorMismatchError(
"TPM locator supplied does not match TPM locator in PIB: " +
205 oldTpmLocator +
" != " + canonicalTpmLocator));
212 m_tpm = createTpm(canonicalTpmLocator);
213 m_pib->setTpmLocator(canonicalTpmLocator);
223 Identity
id = m_pib->addIdentity(identityName);
227 key =
id.getDefaultKey();
229 catch (
const Pib::Error&) {
234 key.getDefaultCertificate();
236 catch (
const Pib::Error&) {
237 NDN_LOG_DEBUG(
"No default cert for " << key.getName() <<
", requesting self-signing");
247 BOOST_ASSERT(static_cast<bool>(identity));
249 Name identityName = identity.getName();
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);
278 NDN_LOG_DEBUG(
"Requesting self-signing for newly created key " << key.getName());
287 BOOST_ASSERT(static_cast<bool>(identity));
288 BOOST_ASSERT(static_cast<bool>(key));
290 Name keyName = key.getName();
291 if (identity.getName() != key.getIdentity()) {
292 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Identity `" + identity.getName().toUri() +
"` " 293 "does not match key `" + keyName.
toUri() +
"`"));
296 identity.removeKey(keyName);
297 m_tpm->deleteKey(keyName);
303 BOOST_ASSERT(static_cast<bool>(identity));
304 BOOST_ASSERT(static_cast<bool>(key));
306 if (identity.getName() != key.getIdentity())
307 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Identity `" + identity.getName().toUri() +
"` " 308 "does not match key `" + key.getName().toUri() +
"`"));
310 identity.setDefaultKey(key.getName());
316 BOOST_ASSERT(static_cast<bool>(key));
318 if (key.getName() != certificate.
getKeyName() ||
320 key.getPublicKey().begin()))
321 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Key `" + key.getName().toUri() +
"` " 322 "does not match certificate `" + certificate.
getName().
toUri() +
"`"));
324 key.addCertificate(certificate);
330 BOOST_ASSERT(static_cast<bool>(key));
333 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Wrong certificate name `" + certificateName.
toUri() +
"`"));
336 key.removeCertificate(certificateName);
342 BOOST_ASSERT(static_cast<bool>(key));
345 key.setDefaultCertificate(cert.
getName());
356 encryptedKey = m_tpm->exportPrivateKey(keyName, pw, pwLen);
359 BOOST_THROW_EXCEPTION(
Error(
"Private `" + keyName.
toUri() +
"` key does not exist"));
362 return make_shared<SafeBag>(certificate, *encryptedKey);
374 if (m_tpm->hasKey(keyName)) {
375 BOOST_THROW_EXCEPTION(
Error(
"Private key `" + keyName.
toUri() +
"` already exists"));
379 Identity existingId = m_pib->getIdentity(identity);
380 existingId.getKey(keyName);
381 BOOST_THROW_EXCEPTION(
Error(
"Public key `" + keyName.
toUri() +
"` already exists"));
383 catch (
const Pib::Error&) {
388 m_tpm->importPrivateKey(keyName,
392 catch (
const std::runtime_error&) {
393 BOOST_THROW_EXCEPTION(
Error(
"Fail to import private key `" + keyName.
toUri() +
"`"));
397 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
402 catch (
const std::runtime_error&) {
403 m_tpm->deleteKey(keyName);
404 BOOST_THROW_EXCEPTION(
Error(
"Invalid private key `" + keyName.
toUri() +
"`"));
406 bool isVerified =
false;
410 publicKey.loadPkcs8(publicKeyBits.data(), publicKeyBits.size());
412 sigBits->data(), sigBits->size())
416 m_tpm->deleteKey(keyName);
418 "and private key `" + keyName.
toUri() +
"` do not match"));
421 Identity
id = m_pib->addIdentity(identity);
423 key.addCertificate(cert);
434 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
451 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
460 signedName.
append(sigValue);
469 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
476 static inline std::tuple<std::string, std::string>
479 size_t pos = uri.find(
':');
480 if (pos != std::string::npos) {
481 return std::make_tuple(uri.substr(0, pos), uri.substr(pos + 1));
484 return std::make_tuple(uri,
"");
488 std::tuple<std::string, std::string>
489 KeyChain::parseAndCheckPibLocator(
const std::string& pibLocator)
491 std::string pibScheme, pibLocation;
494 if (pibScheme.empty()) {
495 pibScheme = getDefaultPibScheme();
498 auto pibFactory = getPibFactories().find(pibScheme);
499 if (pibFactory == getPibFactories().end()) {
500 BOOST_THROW_EXCEPTION(
KeyChain::Error(
"PIB scheme `" + pibScheme +
"` is not supported"));
503 return std::make_tuple(pibScheme, pibLocation);
507 KeyChain::createPib(
const std::string& pibLocator)
509 std::string pibScheme, pibLocation;
510 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
511 auto pibFactory = getPibFactories().find(pibScheme);
512 BOOST_ASSERT(pibFactory != getPibFactories().end());
513 return unique_ptr<Pib>(
new Pib(pibScheme, pibLocation, pibFactory->second(pibLocation)));
516 std::tuple<std::string, std::string>
517 KeyChain::parseAndCheckTpmLocator(
const std::string& tpmLocator)
519 std::string tpmScheme, tpmLocation;
522 if (tpmScheme.empty()) {
523 tpmScheme = getDefaultTpmScheme();
525 auto tpmFactory = getTpmFactories().find(tpmScheme);
526 if (tpmFactory == getTpmFactories().end()) {
527 BOOST_THROW_EXCEPTION(
KeyChain::Error(
"TPM scheme `" + tpmScheme +
"` is not supported"));
530 return std::make_tuple(tpmScheme, tpmLocation);
534 KeyChain::createTpm(
const std::string& tpmLocator)
536 std::string tpmScheme, tpmLocation;
537 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
538 auto tpmFactory = getTpmFactories().find(tpmScheme);
539 BOOST_ASSERT(tpmFactory != getTpmFactories().end());
540 return unique_ptr<Tpm>(
new Tpm(tpmScheme, tpmLocation, tpmFactory->second(tpmLocation)));
546 KeyChain::selfSign(Key& key)
551 Name certificateName = key.getName();
555 certificate.
setName(certificateName);
562 certificate.
setContent(key.getPublicKey().data(), key.getPublicKey().size());
573 key.addCertificate(certificate);
577 std::tuple<Name, SignatureInfo>
578 KeyChain::prepareSignatureInfo(
const SigningInfo& params)
584 Name certificateName;
592 identity = m_pib->getDefaultIdentity();
594 catch (
const Pib::Error&) {
606 catch (
const Pib::Error&) {
607 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing identity `" +
619 identity = m_pib->getIdentity(identityName);
621 identity = Identity();
623 catch (
const Pib::Error&) {
624 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing key `" +
635 identity = m_pib->getIdentity(identityName);
636 key = identity.
getKey(keyName);
638 catch (
const Pib::Error&) {
639 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing certificate `" +
650 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Unrecognized signer type " +
655 if (!identity && !key) {
656 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Cannot determine signing parameters"));
659 if (identity && !key) {
663 catch (
const Pib::Error&) {
664 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing identity `" + identity.
getName().
toUri() +
665 "` does not have default certificate"));
675 return std::make_tuple(key.
getName(), sigInfo);
697 BOOST_THROW_EXCEPTION(Error(
"Unsupported key types"));
void deleteKey(const Identity &identity, const Key &key)
Delete a key key of identity.
Data & setContentType(uint32_t type)
const Name & getName() const
const Name & getName() const
Get key name.
Copyright (c) 2011-2015 Regents of the University of California.
void setSignatureType(tlv::SignatureTypeValue type)
Set SignatureType.
const Key & getDefaultKey() const
Get the default key for this Identity.
The certificate following the certificate format naming convention.
Name getKeyName() const
Get key name.
Represents a SignatureInfo TLV element.
The interface of signing key management.
void addCertificate(const Key &key, const Certificate &certificate)
Add a certificate certificate for key.
Key createKey(const Identity &identity, const KeyParams ¶ms=getDefaultKeyParams())
Create a key for identity according to params.
Data & setSignature(const Signature &signature)
Set Signature.
Data & setName(const Name &name)
Set name.
const Name & getSignerName() const
Name extractKeyNameFromCertName(const Name &certName)
Extract key name from the certificate name certName.
static std::tuple< std::string, std::string > parseLocatorUri(const std::string &uri)
Name & appendVersion(uint64_t version)
Append a version component.
RSA key, supports sign/verify and encrypt/decrypt operations.
const Parsed & getParsedConfiguration() const
KeyChain()
Constructor to create KeyChain with default PIB and TPM.
Data & setContent(const Block &block)
Set Content from a block.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Represents a TLV element of NDN packet format.
Error indicating that the supplied TPM locator does not match the locator stored in PIB...
represents an Interest packet
use sha256 digest, no signer needs to be specified
static time_point now() noexcept
Name & append(const Component &component)
Append a component.
Buffer::const_iterator value_begin() const
Get begin iterator of TLV-VALUE.
Buffer::const_iterator value_end() const
Get end iterator of TLV-VALUE.
Signing parameters passed to KeyChain.
void deleteCertificate(const Key &key, const Name &certificateName)
delete a certificate with name certificateName of key.
Data & setFreshnessPeriod(const time::milliseconds &freshnessPeriod)
Catch-all error for security policy errors that don't fit in other categories.
Identity createIdentity(const Name &identityName, const KeyParams ¶ms=getDefaultKeyParams())
Create an identity identityName.
void importSafeBag(const SafeBag &safeBag, const char *pw, size_t pwLen)
Import a pair of certificate and its corresponding private key encapsulated in a SafeBag.
KeyType
The type of a cryptographic key.
static const std::string & getScheme()
void setKeyLocator(const KeyLocator &keyLocator)
Set KeyLocator.
std::string toUri() const
Get URI representation of the name.
#define NDN_LOG_INIT(name)
declare a log module
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
shared_ptr< SafeBag > exportSafeBag(const Certificate &certificate, const char *pw, size_t pwLen)
Export a certificate and its corresponding private key.
const Identity & getPibIdentity() const
#define NDN_LOG_DEBUG(expression)
A frontend handle of a key instance.
static const std::string & getScheme()
Interest & setName(const Name &name)
no signer is specified, use default setting or follow the trust schema
NDN_CXX_V2_KEYCHAIN_REGISTER_PIB_BACKEND(PibSqlite3)
static const std::string & getScheme()
void setDefaultCertificate(const Key &key, const Certificate &certificate)
Set cert as the default certificate of key.
KeyType getKeyType() const
Get key type.
const SignatureInfo & getSignatureInfo() const
void setDefaultIdentity(const Identity &identity)
Set identity as the default identity.
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE DigestAlgorithm digestAlgorithm
Elliptic Curve key (e.g. for ECDSA), supports sign/verify operations.
static const Name & getDigestSha256Identity()
A localhost identity to indicate that the signature is generated using SHA-256.
void setValidityPeriod(const security::ValidityPeriod &validityPeriod)
Set ValidityPeriod.
Use the SHA256 hash of the public key as the key id.
Name getIdentity() const
Get identity name.
Represents an absolute name.
signer is a certificate, use it directly
Key getKey(const Name &keyName) const
Get a key with id keyName.
Buffer getPublicKey() const
Get public key bits (in PKCS#8 format)
signer is a key, use its default certificate
const Buffer & getEncryptedKeyBag() const
Get the private key in PKCS#8 from safe bag.
void sign(Data &data, const SigningInfo ¶ms=getDefaultSigningInfo())
Sign data according to the supplied signing information.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
const Name & getName() const
Get name.
Component holds a read-only name component value.
void deleteIdentity(const Identity &identity)
delete identity.
static bool isValidName(const Name &certName)
Check if the specified name follows the naming convention for the certificate.
a secured container for sensitive information(certificate, private key)
System configuration file for NDN platform.
void setDefaultKey(const Identity &identity, const Key &key)
Set key as the default key of identity.
void encode()
Encode sub elements into TLV-VALUE.
const Block & getContent() const
Get Content.
NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(DummyTpm)
const Name & getName() const
Get the name of the identity.
const Data & getCertificate() const
Get the certificate data packet from safe bag.
indicates content is a public key
Base class of key parameters.
signer is an identity, use its default key and default certificate
A frontend handle of an Identity.
ConstBufferPtr computeDigest()
Finalize and return the digest based on all previously supplied inputs.
const Key & getPibKey() const
#define NDN_LOG_TRACE(expression)
Represents a Data packet.
SimplePublicKeyParams is a template for public keys with only one parameter: size.
DigestAlgorithm getDigestAlgorithm() const
Name extractIdentityFromKeyName(const Name &keyName)
Extract identity namespace from the key name keyName.
General-purpose automatically managed/resized buffer.
EncodingImpl< EncoderTag > EncodingBuffer
SignerType getSignerType() const
duration< boost::int_least32_t, boost::ratio< 86400 > > days
Holds SignatureInfo and SignatureValue in a Data packet.
shared_ptr< const Buffer > ConstBufferPtr
Name extractIdentityFromCertName(const Name &certName)
Extract identity namespace from the certificate name certName.