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) 71 std::string KeyChain::s_defaultPibLocator;
72 std::string KeyChain::s_defaultTpmLocator;
74 KeyChain::PibFactories&
75 KeyChain::getPibFactories()
77 static PibFactories pibFactories;
81 KeyChain::TpmFactories&
82 KeyChain::getTpmFactories()
84 static TpmFactories tpmFactories;
89 KeyChain::getDefaultPibScheme()
95 KeyChain::getDefaultTpmScheme()
97 #if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 101 #endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 105 KeyChain::getDefaultPibLocator()
107 if (!s_defaultPibLocator.empty())
108 return s_defaultPibLocator;
110 if (getenv(
"NDN_CLIENT_PIB") !=
nullptr) {
111 s_defaultPibLocator = getenv(
"NDN_CLIENT_PIB");
115 s_defaultPibLocator = config.getParsedConfiguration().get<std::string>(
"pib", getDefaultPibScheme() +
":");
118 std::string pibScheme, pibLocation;
119 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(s_defaultPibLocator);
120 s_defaultPibLocator = pibScheme +
":" + pibLocation;
122 return s_defaultPibLocator;
126 KeyChain::getDefaultTpmLocator()
128 if (!s_defaultTpmLocator.empty())
129 return s_defaultTpmLocator;
131 if (getenv(
"NDN_CLIENT_TPM") !=
nullptr) {
132 s_defaultTpmLocator = getenv(
"NDN_CLIENT_TPM");
136 s_defaultTpmLocator = config.getParsedConfiguration().get<std::string>(
"tpm", getDefaultTpmScheme() +
":");
139 std::string tpmScheme, tpmLocation;
140 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(s_defaultTpmLocator);
141 s_defaultTpmLocator = tpmScheme +
":" + tpmLocation;
143 return s_defaultTpmLocator;
166 :
KeyChain(getDefaultPibLocator(), getDefaultTpmLocator(), true)
173 std::string pibScheme, pibLocation;
174 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
175 std::string canonicalPibLocator = pibScheme +
":" + pibLocation;
178 m_pib = createPib(canonicalPibLocator);
179 std::string oldTpmLocator;
181 oldTpmLocator = m_pib->getTpmLocator();
188 std::string tpmScheme, tpmLocation;
189 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
190 std::string canonicalTpmLocator = tpmScheme +
":" + tpmLocation;
192 if (canonicalPibLocator == getDefaultPibLocator()) {
194 if (!oldTpmLocator.empty() && oldTpmLocator != getDefaultTpmLocator()) {
196 canonicalTpmLocator = getDefaultTpmLocator();
201 if (!oldTpmLocator.empty() && oldTpmLocator != canonicalTpmLocator) {
205 BOOST_THROW_EXCEPTION(
LocatorMismatchError(
"TPM locator supplied does not match TPM locator in PIB: " +
206 oldTpmLocator +
" != " + canonicalTpmLocator));
213 m_tpm = createTpm(canonicalTpmLocator);
214 m_pib->setTpmLocator(canonicalTpmLocator);
224 Identity id = m_pib->addIdentity(identityName);
228 key =
id.getDefaultKey();
248 BOOST_ASSERT(static_cast<bool>(identity));
252 for (
const auto& key : identity.
getKeys()) {
253 m_tpm->deleteKey(key.getName());
256 m_pib->removeIdentity(identityName);
262 BOOST_ASSERT(static_cast<bool>(identity));
264 m_pib->setDefaultIdentity(identity.
getName());
270 BOOST_ASSERT(static_cast<bool>(identity));
273 Name keyName = m_tpm->createKey(identity.
getName(), params);
277 Key key = identity.addKey(pubKey->data(), pubKey->size(), keyName);
288 BOOST_ASSERT(static_cast<bool>(identity));
289 BOOST_ASSERT(static_cast<bool>(key));
293 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Identity `" + identity.
getName().
toUri() +
"` " 294 "does not match key `" + keyName.
toUri() +
"`"));
298 m_tpm->deleteKey(keyName);
304 BOOST_ASSERT(static_cast<bool>(identity));
305 BOOST_ASSERT(static_cast<bool>(key));
308 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Identity `" + identity.
getName().
toUri() +
"` " 317 BOOST_ASSERT(static_cast<bool>(key));
322 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Key `" + key.
getName().
toUri() +
"` " 323 "does not match certificate `" + certificate.
getName().
toUri() +
"`"));
325 key.addCertificate(certificate);
331 BOOST_ASSERT(static_cast<bool>(key));
334 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Wrong certificate name `" + certificateName.
toUri() +
"`"));
343 BOOST_ASSERT(static_cast<bool>(key));
357 encryptedKey = m_tpm->exportPrivateKey(keyName, pw, pwLen);
360 BOOST_THROW_EXCEPTION(
Error(
"Failed to export private key `" + keyName.
toUri() +
"`: " + e.what()));
363 return make_shared<SafeBag>(certificate, *encryptedKey);
375 if (m_tpm->hasKey(keyName)) {
376 BOOST_THROW_EXCEPTION(
Error(
"Private key `" + keyName.
toUri() +
"` already exists"));
380 Identity existingId = m_pib->getIdentity(identity);
381 existingId.
getKey(keyName);
382 BOOST_THROW_EXCEPTION(
Error(
"Public key `" + keyName.
toUri() +
"` already exists"));
389 m_tpm->importPrivateKey(keyName,
394 BOOST_THROW_EXCEPTION(
Error(
"Failed to import private key `" + keyName.
toUri() +
"`: " + e.what()));
398 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
403 catch (
const std::runtime_error&) {
404 m_tpm->deleteKey(keyName);
405 BOOST_THROW_EXCEPTION(
Error(
"Invalid private key `" + keyName.
toUri() +
"`"));
407 bool isVerified =
false;
411 publicKey.
loadPkcs8(publicKeyBits.data(), publicKeyBits.size());
413 sigBits->data(), sigBits->size())
417 m_tpm->deleteKey(keyName);
419 "and private key `" + keyName.
toUri() +
"` do not match"));
422 Identity id = m_pib->addIdentity(identity);
424 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)
548 Certificate certificate;
551 Name certificateName = key.getName();
555 certificate.setName(certificateName);
559 certificate.setFreshnessPeriod(1_h);
562 certificate.setContent(key.getPublicKey().data(), key.getPublicKey().size());
571 sign(certificate, SigningInfo(key).setSignatureInfo(signatureInfo));
573 key.addCertificate(certificate);
577 std::tuple<Name, SignatureInfo>
578 KeyChain::prepareSignatureInfo(
const SigningInfo& params)
584 Name certificateName;
586 pib::Identity identity;
589 switch (params.getSignerType()) {
592 identity = m_pib->getDefaultIdentity();
594 catch (
const Pib::Error&) {
601 identity = params.getPibIdentity();
604 identity = m_pib->getIdentity(params.getSignerName());
606 catch (
const Pib::Error&) {
607 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing identity `" +
608 params.getSignerName().toUri() +
"` does not exist"));
614 key = params.getPibKey();
619 identity = m_pib->getIdentity(identityName);
620 key = identity.getKey(params.getSignerName());
621 identity = Identity();
623 catch (
const Pib::Error&) {
624 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing key `" +
625 params.getSignerName().toUri() +
"` does not exist"));
635 identity = m_pib->getIdentity(identityName);
636 key = identity.getKey(keyName);
638 catch (
const Pib::Error&) {
639 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing certificate `" +
640 params.getSignerName().toUri() +
"` does not exist"));
650 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Unrecognized signer type " +
651 boost::lexical_cast<std::string>(params.getSignerType())));
655 if (!identity && !key) {
656 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Cannot determine signing parameters"));
659 if (identity && !key) {
661 key = identity.getDefaultKey();
663 catch (
const Pib::Error&) {
664 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing identity `" + identity.getName().toUri() +
665 "` does not have a default certificate"));
671 sigInfo.setSignatureType(getSignatureType(key.getKeyType(), params.getDigestAlgorithm()));
672 sigInfo.setKeyLocator(
KeyLocator(key.getName()));
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.
Key getKey(const Name &keyName) const
Get a key with id keyName.
Copyright (c) 2011-2015 Regents of the University of California.
std::string toUri() const
Get URI representation of the name.
The certificate following the certificate format naming convention.
represents a semantic error
const Name & getName() const
Get name.
Buffer getPublicKey() const
Get public key bits (in PKCS#8 format)
Represents a SignatureInfo TLV element.
const Key & setDefaultKey(const Name &keyName) const
Set an existing key with keyName as the default key.
The interface of signing key management.
void removeKey(const Name &keyName) const
Remove a key with keyName.
void addCertificate(const Key &key, const Certificate &certificate)
Add a certificate certificate for key.
const Block & getContent() const
Get Content.
Key createKey(const Identity &identity, const KeyParams ¶ms=getDefaultKeyParams())
Create a key for identity according to params.
NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(BackEndFile)
Name getIdentity() const
Get identity name.
Data & setSignature(const Signature &signature)
Set Signature.
DigestAlgorithm getDigestAlgorithm() 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)
RSA key, supports sign/verify and encrypt/decrypt operations.
#define NDN_LOG_DEBUG(expression)
KeyChain()
Constructor to create KeyChain with default PIB and TPM.
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.
Signing parameters passed to KeyChain.
void deleteCertificate(const Key &key, const Name &certificateName)
delete a certificate with name certificateName of key.
const Buffer & getEncryptedKeyBag() const
Get the private key in PKCS#8 from safe bag.
Buffer::const_iterator value_begin() const
Get begin iterator of TLV-VALUE.
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()
size_t wireEncode(EncodingImpl< TAG > &encoder) 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 Data & getCertificate() const
Get the certificate data packet from safe bag.
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.
void setDefaultIdentity(const Identity &identity)
Set identity as the default identity.
Name getKeyName() const
Get key name.
Buffer::const_iterator value_end() const
Get end iterator of TLV-VALUE.
static const SigningInfo & getDefaultSigningInfo()
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.
Use the SHA256 hash of the public key as the key id.
Represents an absolute name.
const Name & getName() const
Get key name.
signer is a certificate, use it directly
#define NDN_LOG_TRACE(expression)
SignatureTypeValue
SignatureType values.
signer is a key, use its default certificate
void sign(Data &data, const SigningInfo ¶ms=getDefaultSigningInfo())
Sign data according to the supplied signing information.
const v2::Certificate & setDefaultCertificate(const Name &certName) const
Set an existing certificate with certName as the default certificate.
Represents a name component.
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.
static const KeyParams & getDefaultKeyParams()
a secured container for sensitive information(certificate, private key)
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 Name & getName() const
Get the name of the identity.
const v2::Certificate & getDefaultCertificate() const
Get the default certificate for this Key.
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Prepend wire encoding to encoder in NDN Packet Format v0.2.
Base class of key parameters.
signer is an identity, use its default key and default certificate
const Buffer & getPublicKey() const
Get public key bits.
A frontend handle of an Identity.
ConstBufferPtr computeDigest()
Finalize and return the digest based on all previously supplied inputs.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
const KeyContainer & getKeys() const
Get all keys for this identity.
#define NDN_LOG_INIT(name)
declare a log module
Represents a Data packet.
SimplePublicKeyParams is a template for public keys with only one parameter: size.
Name extractIdentityFromKeyName(const Name &keyName)
Extract identity namespace from the key name keyName.
General-purpose automatically managed/resized buffer.
void removeCertificate(const Name &certName) const
Remove a certificate with certName.
const Name & getIdentity() const
Get the name of the belonging identity.
EncodingImpl< EncoderTag > EncodingBuffer
const Name & getName() const
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.