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 std::string pibScheme, pibLocation;
120 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(s_defaultPibLocator);
121 s_defaultPibLocator = pibScheme +
":" + pibLocation;
123 return s_defaultPibLocator;
127 KeyChain::getDefaultTpmLocator()
129 if (!s_defaultTpmLocator.empty())
130 return s_defaultTpmLocator;
132 if (getenv(
"NDN_CLIENT_TPM") !=
nullptr) {
133 s_defaultTpmLocator = getenv(
"NDN_CLIENT_TPM");
137 s_defaultTpmLocator = config.getParsedConfiguration().get<std::string>(
"tpm", getDefaultTpmScheme() +
":");
140 std::string tpmScheme, tpmLocation;
141 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(s_defaultTpmLocator);
142 s_defaultTpmLocator = tpmScheme +
":" + tpmLocation;
144 return s_defaultTpmLocator;
151 KeyChain::getDefaultSigningInfo()
158 KeyChain::getDefaultKeyParams()
167 :
KeyChain(getDefaultPibLocator(), getDefaultTpmLocator(), true)
174 std::string pibScheme, pibLocation;
175 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
176 std::string canonicalPibLocator = pibScheme +
":" + pibLocation;
179 m_pib = createPib(canonicalPibLocator);
180 std::string oldTpmLocator;
182 oldTpmLocator = m_pib->getTpmLocator();
184 catch (
const Pib::Error&) {
189 std::string tpmScheme, tpmLocation;
190 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
191 std::string canonicalTpmLocator = tpmScheme +
":" + tpmLocation;
193 if (canonicalPibLocator == getDefaultPibLocator()) {
195 if (!oldTpmLocator.empty() && oldTpmLocator != getDefaultTpmLocator()) {
197 canonicalTpmLocator = getDefaultTpmLocator();
202 if (!oldTpmLocator.empty() && oldTpmLocator != canonicalTpmLocator) {
206 BOOST_THROW_EXCEPTION(
LocatorMismatchError(
"TPM locator supplied does not match TPM locator in PIB: " +
207 oldTpmLocator +
" != " + canonicalTpmLocator));
214 m_tpm = createTpm(canonicalTpmLocator);
215 m_pib->setTpmLocator(canonicalTpmLocator);
225 Identity
id = m_pib->addIdentity(identityName);
229 key =
id.getDefaultKey();
231 catch (
const Pib::Error&) {
236 key.getDefaultCertificate();
238 catch (
const Pib::Error&) {
239 NDN_LOG_DEBUG(
"No default cert for " << key.getName() <<
", requesting self-signing");
249 BOOST_ASSERT(static_cast<bool>(identity));
251 Name identityName = identity.getName();
253 for (
const auto& key : identity.getKeys()) {
254 m_tpm->deleteKey(key.getName());
257 m_pib->removeIdentity(identityName);
263 BOOST_ASSERT(static_cast<bool>(identity));
265 m_pib->setDefaultIdentity(identity.getName());
271 BOOST_ASSERT(static_cast<bool>(identity));
274 Name keyName = m_tpm->createKey(identity.getName(), params);
278 Key key = identity.addKey(pubKey->data(), pubKey->size(), keyName);
280 NDN_LOG_DEBUG(
"Requesting self-signing for newly created key " << key.getName());
289 BOOST_ASSERT(static_cast<bool>(identity));
290 BOOST_ASSERT(static_cast<bool>(key));
292 Name keyName = key.getName();
293 if (identity.getName() != key.getIdentity()) {
294 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Identity `" + identity.getName().toUri() +
"` " 295 "does not match key `" + keyName.
toUri() +
"`"));
298 identity.removeKey(keyName);
299 m_tpm->deleteKey(keyName);
305 BOOST_ASSERT(static_cast<bool>(identity));
306 BOOST_ASSERT(static_cast<bool>(key));
308 if (identity.getName() != key.getIdentity())
309 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Identity `" + identity.getName().toUri() +
"` " 310 "does not match key `" + key.getName().toUri() +
"`"));
312 identity.setDefaultKey(key.getName());
318 BOOST_ASSERT(static_cast<bool>(key));
320 if (key.getName() != certificate.
getKeyName() ||
322 key.getPublicKey().begin()))
323 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Key `" + key.getName().toUri() +
"` " 324 "does not match certificate `" + certificate.
getName().
toUri() +
"`"));
326 key.addCertificate(certificate);
332 BOOST_ASSERT(static_cast<bool>(key));
335 BOOST_THROW_EXCEPTION(std::invalid_argument(
"Wrong certificate name `" + certificateName.
toUri() +
"`"));
338 key.removeCertificate(certificateName);
344 BOOST_ASSERT(static_cast<bool>(key));
347 key.setDefaultCertificate(cert.
getName());
358 encryptedKey = m_tpm->exportPrivateKey(keyName, pw, pwLen);
361 BOOST_THROW_EXCEPTION(
Error(
"Failed to export private key `" + keyName.
toUri() +
"`: " + e.what()));
364 return make_shared<SafeBag>(certificate, *encryptedKey);
376 if (m_tpm->hasKey(keyName)) {
377 BOOST_THROW_EXCEPTION(
Error(
"Private key `" + keyName.
toUri() +
"` already exists"));
381 Identity existingId = m_pib->getIdentity(identity);
382 existingId.getKey(keyName);
383 BOOST_THROW_EXCEPTION(
Error(
"Public key `" + keyName.
toUri() +
"` already exists"));
385 catch (
const Pib::Error&) {
390 m_tpm->importPrivateKey(keyName,
395 BOOST_THROW_EXCEPTION(
Error(
"Failed to import private key `" + keyName.
toUri() +
"`: " + e.what()));
399 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
404 catch (
const std::runtime_error&) {
405 m_tpm->deleteKey(keyName);
406 BOOST_THROW_EXCEPTION(
Error(
"Invalid private key `" + keyName.
toUri() +
"`"));
408 bool isVerified =
false;
412 publicKey.loadPkcs8(publicKeyBits.data(), publicKeyBits.size());
414 sigBits->data(), sigBits->size())
418 m_tpm->deleteKey(keyName);
420 "and private key `" + keyName.
toUri() +
"` do not match"));
423 Identity
id = m_pib->addIdentity(identity);
425 key.addCertificate(cert);
435 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
452 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
461 signedName.
append(sigValue);
470 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
477 static inline std::tuple<std::string, std::string>
480 size_t pos = uri.find(
':');
481 if (pos != std::string::npos) {
482 return std::make_tuple(uri.substr(0, pos), uri.substr(pos + 1));
485 return std::make_tuple(uri,
"");
489 std::tuple<std::string, std::string>
490 KeyChain::parseAndCheckPibLocator(
const std::string& pibLocator)
492 std::string pibScheme, pibLocation;
495 if (pibScheme.empty()) {
496 pibScheme = getDefaultPibScheme();
499 auto pibFactory = getPibFactories().find(pibScheme);
500 if (pibFactory == getPibFactories().end()) {
501 BOOST_THROW_EXCEPTION(
KeyChain::Error(
"PIB scheme `" + pibScheme +
"` is not supported"));
504 return std::make_tuple(pibScheme, pibLocation);
508 KeyChain::createPib(
const std::string& pibLocator)
510 std::string pibScheme, pibLocation;
511 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
512 auto pibFactory = getPibFactories().find(pibScheme);
513 BOOST_ASSERT(pibFactory != getPibFactories().end());
514 return unique_ptr<Pib>(
new Pib(pibScheme, pibLocation, pibFactory->second(pibLocation)));
517 std::tuple<std::string, std::string>
518 KeyChain::parseAndCheckTpmLocator(
const std::string& tpmLocator)
520 std::string tpmScheme, tpmLocation;
523 if (tpmScheme.empty()) {
524 tpmScheme = getDefaultTpmScheme();
526 auto tpmFactory = getTpmFactories().find(tpmScheme);
527 if (tpmFactory == getTpmFactories().end()) {
528 BOOST_THROW_EXCEPTION(
KeyChain::Error(
"TPM scheme `" + tpmScheme +
"` is not supported"));
531 return std::make_tuple(tpmScheme, tpmLocation);
535 KeyChain::createTpm(
const std::string& tpmLocator)
537 std::string tpmScheme, tpmLocation;
538 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
539 auto tpmFactory = getTpmFactories().find(tpmScheme);
540 BOOST_ASSERT(tpmFactory != getTpmFactories().end());
541 return unique_ptr<Tpm>(
new Tpm(tpmScheme, tpmLocation, tpmFactory->second(tpmLocation)));
547 KeyChain::selfSign(Key& key)
552 Name certificateName = key.getName();
556 certificate.
setName(certificateName);
563 certificate.
setContent(key.getPublicKey().data(), key.getPublicKey().size());
574 key.addCertificate(certificate);
578 std::tuple<Name, SignatureInfo>
579 KeyChain::prepareSignatureInfo(
const SigningInfo& params)
585 Name certificateName;
593 identity = m_pib->getDefaultIdentity();
595 catch (
const Pib::Error&) {
607 catch (
const Pib::Error&) {
608 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing identity `" +
620 identity = m_pib->getIdentity(identityName);
622 identity = Identity();
624 catch (
const Pib::Error&) {
625 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing key `" +
636 identity = m_pib->getIdentity(identityName);
637 key = identity.
getKey(keyName);
639 catch (
const Pib::Error&) {
640 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing certificate `" +
651 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Unrecognized signer type " +
656 if (!identity && !key) {
657 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Cannot determine signing parameters"));
660 if (identity && !key) {
664 catch (
const Pib::Error&) {
665 BOOST_THROW_EXCEPTION(InvalidSigningInfoError(
"Signing identity `" + identity.
getName().
toUri() +
666 "` does not have a default certificate"));
676 return std::make_tuple(key.
getName(), sigInfo);
698 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) 2013-2017 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.
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.
#define NDN_LOG_DEBUG(expression)
Log at DEBUG level.
use sha256 digest, no signer needs to be specified
#define NDN_LOG_INIT(name)
Define a non-member log module.
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.
#define NDN_CXX_V2_KEYCHAIN_REGISTER_PIB_BACKEND(PibType)
Register Pib backend class in KeyChain.
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.
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Prepend wire encoding to encoder in NDN Packet Format v0.2.
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
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
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.
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)
SignatureTypeValue
SignatureType values.
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.
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.
a secured container for sensitive information(certificate, private key)
Data & setFreshnessPeriod(time::milliseconds freshnessPeriod)
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.
const Name & getName() const
Get the name of the identity.
const Data & getCertificate() const
Get the certificate data packet from safe bag.
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)
Log at TRACE level.
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
#define NDN_CXX_V2_KEYCHAIN_REGISTER_TPM_BACKEND(TpmType)
Register Tpm backend class in KeyChain.
SignerType getSignerType() 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.