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> 60 #if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 62 #endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 72 std::string KeyChain::s_defaultPibLocator;
73 std::string KeyChain::s_defaultTpmLocator;
75 KeyChain::PibFactories&
76 KeyChain::getPibFactories()
78 static PibFactories pibFactories;
82 KeyChain::TpmFactories&
83 KeyChain::getTpmFactories()
85 static TpmFactories tpmFactories;
90 KeyChain::getDefaultPibScheme()
96 KeyChain::getDefaultTpmScheme()
98 #if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 102 #endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 106 KeyChain::getDefaultPibLocator()
108 if (!s_defaultPibLocator.empty())
109 return s_defaultPibLocator;
111 if (getenv(
"NDN_CLIENT_PIB") !=
nullptr) {
112 s_defaultPibLocator = getenv(
"NDN_CLIENT_PIB");
116 s_defaultPibLocator = config.getParsedConfiguration().get<std::string>(
"pib", getDefaultPibScheme() +
":");
119 return s_defaultPibLocator;
123 KeyChain::getDefaultTpmLocator()
125 if (!s_defaultTpmLocator.empty())
126 return s_defaultTpmLocator;
128 if (getenv(
"NDN_CLIENT_TPM") !=
nullptr) {
129 s_defaultTpmLocator = getenv(
"NDN_CLIENT_TPM");
133 s_defaultTpmLocator = config.getParsedConfiguration().get<std::string>(
"tpm", getDefaultTpmScheme() +
":");
136 return s_defaultTpmLocator;
159 :
KeyChain(getDefaultPibLocator(), getDefaultTpmLocator(), true)
166 std::string pibScheme, pibLocation;
167 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
168 std::string canonicalPibLocator = pibScheme +
":" + pibLocation;
171 m_pib = createPib(canonicalPibLocator);
172 std::string oldTpmLocator;
174 oldTpmLocator = m_pib->getTpmLocator();
181 std::string tpmScheme, tpmLocation;
182 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
183 std::string canonicalTpmLocator = tpmScheme +
":" + tpmLocation;
185 if (canonicalPibLocator == getDefaultPibLocator()) {
187 if (!oldTpmLocator.empty() && oldTpmLocator != getDefaultTpmLocator()) {
189 canonicalTpmLocator = getDefaultTpmLocator();
194 if (!oldTpmLocator.empty() && oldTpmLocator != canonicalTpmLocator) {
198 BOOST_THROW_EXCEPTION(
LocatorMismatchError(
"TPM locator supplied does not match TPM locator in PIB: " +
199 oldTpmLocator +
" != " + canonicalTpmLocator));
206 m_tpm = createTpm(canonicalTpmLocator);
207 m_pib->setTpmLocator(canonicalTpmLocator);
217 Identity id = m_pib->addIdentity(identityName);
221 key =
id.getDefaultKey();
241 BOOST_ASSERT(static_cast<bool>(identity));
245 for (
const auto& key : identity.
getKeys()) {
246 m_tpm->deleteKey(key.getName());
249 m_pib->removeIdentity(identityName);
255 BOOST_ASSERT(static_cast<bool>(identity));
257 m_pib->setDefaultIdentity(identity.
getName());
263 BOOST_ASSERT(static_cast<bool>(identity));
266 Name keyName = m_tpm->createKey(identity.
getName(), params);
270 Key key = identity.addKey(pubKey->data(), pubKey->size(), keyName);
281 BOOST_ASSERT(static_cast<bool>(identity));
282 BOOST_ASSERT(static_cast<bool>(key));
286 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Identity `" + identity.
getName().
toUri() +
"` " 287 "does not match key `" + keyName.
toUri() +
"`"));
291 m_tpm->deleteKey(keyName);
297 BOOST_ASSERT(static_cast<bool>(identity));
298 BOOST_ASSERT(static_cast<bool>(key));
301 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Identity `" + identity.
getName().
toUri() +
"` " 310 BOOST_ASSERT(static_cast<bool>(key));
315 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Key `" + key.
getName().
toUri() +
"` " 316 "does not match certificate `" + certificate.
getName().
toUri() +
"`"));
318 key.addCertificate(certificate);
324 BOOST_ASSERT(static_cast<bool>(key));
327 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Wrong certificate name `" + certificateName.
toUri() +
"`"));
336 BOOST_ASSERT(static_cast<bool>(key));
350 encryptedKey = m_tpm->exportPrivateKey(keyName, pw, pwLen);
353 BOOST_THROW_EXCEPTION(
Error(
"Failed to export private key `" + keyName.
toUri() +
"`: " + e.what()));
356 return make_shared<SafeBag>(certificate, *encryptedKey);
368 if (m_tpm->hasKey(keyName)) {
369 BOOST_THROW_EXCEPTION(
Error(
"Private key `" + keyName.
toUri() +
"` already exists"));
373 Identity existingId = m_pib->getIdentity(identity);
374 existingId.
getKey(keyName);
375 BOOST_THROW_EXCEPTION(
Error(
"Public key `" + keyName.
toUri() +
"` already exists"));
382 m_tpm->importPrivateKey(keyName,
387 BOOST_THROW_EXCEPTION(
Error(
"Failed to import private key `" + keyName.
toUri() +
"`: " + e.what()));
391 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
396 catch (
const std::runtime_error&) {
397 m_tpm->deleteKey(keyName);
398 BOOST_THROW_EXCEPTION(
Error(
"Invalid private key `" + keyName.
toUri() +
"`"));
400 bool isVerified =
false;
404 publicKey.
loadPkcs8(publicKeyBits.data(), publicKeyBits.size());
406 sigBits->data(), sigBits->size())
410 m_tpm->deleteKey(keyName);
412 "and private key `" + keyName.
toUri() +
"` do not match"));
415 Identity id = m_pib->addIdentity(identity);
417 key.addCertificate(cert);
427 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
444 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
453 signedName.
append(sigValue);
462 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
469 static inline std::tuple<std::string, std::string>
472 size_t pos = uri.find(
':');
473 if (pos != std::string::npos) {
474 return std::make_tuple(uri.substr(0, pos), uri.substr(pos + 1));
477 return std::make_tuple(uri,
"");
481 std::tuple<std::string, std::string>
482 KeyChain::parseAndCheckPibLocator(
const std::string& pibLocator)
484 std::string pibScheme, pibLocation;
487 if (pibScheme.empty()) {
488 pibScheme = getDefaultPibScheme();
491 auto pibFactory = getPibFactories().find(pibScheme);
492 if (pibFactory == getPibFactories().end()) {
493 BOOST_THROW_EXCEPTION(
KeyChain::Error(
"PIB scheme `" + pibScheme +
"` is not supported"));
496 return std::make_tuple(pibScheme, pibLocation);
500 KeyChain::createPib(
const std::string& pibLocator)
502 std::string pibScheme, pibLocation;
503 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
504 auto pibFactory = getPibFactories().find(pibScheme);
505 BOOST_ASSERT(pibFactory != getPibFactories().end());
506 return unique_ptr<Pib>(
new Pib(pibScheme, pibLocation, pibFactory->second(pibLocation)));
509 std::tuple<std::string, std::string>
510 KeyChain::parseAndCheckTpmLocator(
const std::string& tpmLocator)
512 std::string tpmScheme, tpmLocation;
515 if (tpmScheme.empty()) {
516 tpmScheme = getDefaultTpmScheme();
518 auto tpmFactory = getTpmFactories().find(tpmScheme);
519 if (tpmFactory == getTpmFactories().end()) {
520 BOOST_THROW_EXCEPTION(KeyChain::Error(
"TPM scheme `" + tpmScheme +
"` is not supported"));
523 return std::make_tuple(tpmScheme, tpmLocation);
527 KeyChain::createTpm(
const std::string& tpmLocator)
529 std::string tpmScheme, tpmLocation;
530 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
531 auto tpmFactory = getTpmFactories().find(tpmScheme);
532 BOOST_ASSERT(tpmFactory != getTpmFactories().end());
533 return unique_ptr<Tpm>(
new Tpm(tpmScheme, tpmLocation, tpmFactory->second(tpmLocation)));
539 KeyChain::selfSign(Key& key)
541 Certificate certificate;
544 Name certificateName = key.getName();
548 certificate.setName(certificateName);
552 certificate.setFreshnessPeriod(1_h);
555 certificate.setContent(key.getPublicKey().data(), key.getPublicKey().size());
564 sign(certificate, SigningInfo(key).setSignatureInfo(signatureInfo));
566 key.addCertificate(certificate);
570 std::tuple<Name, SignatureInfo>
571 KeyChain::prepareSignatureInfo(
const SigningInfo& params)
577 Name certificateName;
579 pib::Identity identity;
582 switch (params.getSignerType()) {
585 identity = m_pib->getDefaultIdentity();
587 catch (
const Pib::Error&) {
594 identity = params.getPibIdentity();
597 identity = m_pib->getIdentity(params.getSignerName());
599 catch (
const Pib::Error&) {
600 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing identity `" +
601 params.getSignerName().toUri() +
"` does not exist"));
607 key = params.getPibKey();
612 identity = m_pib->getIdentity(identityName);
613 key = identity.getKey(params.getSignerName());
614 identity = Identity();
616 catch (
const Pib::Error&) {
617 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing key `" +
618 params.getSignerName().toUri() +
"` does not exist"));
628 identity = m_pib->getIdentity(identityName);
629 key = identity.getKey(keyName);
631 catch (
const Pib::Error&) {
632 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing certificate `" +
633 params.getSignerName().toUri() +
"` does not exist"));
643 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Unrecognized signer type " +
644 boost::lexical_cast<std::string>(params.getSignerType())));
648 if (!identity && !key) {
649 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Cannot determine signing parameters"));
652 if (identity && !key) {
654 key = identity.getDefaultKey();
656 catch (
const Pib::Error&) {
657 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing identity `" + identity.getName().toUri() +
658 "` does not have a default certificate"));
664 sigInfo.setSignatureType(getSignatureType(key.getKeyType(), params.getDigestAlgorithm()));
665 sigInfo.setKeyLocator(
KeyLocator(key.getName()));
668 return std::make_tuple(key.getName(), sigInfo);
690 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.
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()
#define NDN_LOG_INIT(name)
declare a log module
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.
#define NDN_LOG_DEBUG(expression)
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
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.
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.
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
Fast encoding or block size estimation.
indicates content is a public key
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_TRACE(expression)
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.