34 #ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS 36 #endif // NDN_CXX_HAVE_OSX_FRAMEWORKS 46 #include <boost/lexical_cast.hpp> 61 #if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 63 #endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 73 std::string KeyChain::s_defaultPibLocator;
74 std::string KeyChain::s_defaultTpmLocator;
76 KeyChain::PibFactories&
77 KeyChain::getPibFactories()
79 static PibFactories pibFactories;
83 KeyChain::TpmFactories&
84 KeyChain::getTpmFactories()
86 static TpmFactories tpmFactories;
91 KeyChain::getDefaultPibScheme()
97 KeyChain::getDefaultTpmScheme()
99 #if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 103 #endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN) 107 KeyChain::getDefaultPibLocator()
109 if (!s_defaultPibLocator.empty())
110 return s_defaultPibLocator;
112 if (getenv(
"NDN_CLIENT_PIB") !=
nullptr) {
113 s_defaultPibLocator = getenv(
"NDN_CLIENT_PIB");
117 s_defaultPibLocator = config.
getParsedConfiguration().get<std::string>(
"pib", getDefaultPibScheme() +
":");
120 std::string pibScheme, pibLocation;
121 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(s_defaultPibLocator);
122 s_defaultPibLocator = pibScheme +
":" + pibLocation;
124 return s_defaultPibLocator;
128 KeyChain::getDefaultTpmLocator()
130 if (!s_defaultTpmLocator.empty())
131 return s_defaultTpmLocator;
133 if (getenv(
"NDN_CLIENT_TPM") !=
nullptr) {
134 s_defaultTpmLocator = getenv(
"NDN_CLIENT_TPM");
138 s_defaultTpmLocator = config.
getParsedConfiguration().get<std::string>(
"tpm", getDefaultTpmScheme() +
":");
141 std::string tpmScheme, tpmLocation;
142 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(s_defaultTpmLocator);
143 s_defaultTpmLocator = tpmScheme +
":" + tpmLocation;
145 return s_defaultTpmLocator;
149 KeyChain::getDefaultKeyParams()
158 :
KeyChain(getDefaultPibLocator(), getDefaultTpmLocator(), true)
165 std::string pibScheme, pibLocation;
166 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
167 std::string canonicalPibLocator = pibScheme +
":" + pibLocation;
170 m_pib = createPib(canonicalPibLocator);
171 std::string oldTpmLocator;
173 oldTpmLocator = m_pib->getTpmLocator();
180 std::string tpmScheme, tpmLocation;
181 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
182 std::string canonicalTpmLocator = tpmScheme +
":" + tpmLocation;
184 if (canonicalPibLocator == getDefaultPibLocator()) {
186 if (!oldTpmLocator.empty() && oldTpmLocator != getDefaultTpmLocator()) {
188 canonicalTpmLocator = getDefaultTpmLocator();
193 if (!oldTpmLocator.empty() && oldTpmLocator != canonicalTpmLocator) {
198 oldTpmLocator +
" != " + canonicalTpmLocator));
205 m_tpm = createTpm(canonicalTpmLocator);
206 m_pib->setTpmLocator(canonicalTpmLocator);
216 Identity id = m_pib->addIdentity(identityName);
220 key =
id.getDefaultKey();
240 BOOST_ASSERT(static_cast<bool>(identity));
244 for (
const auto& key : identity.
getKeys()) {
245 m_tpm->deleteKey(key.getName());
248 m_pib->removeIdentity(identityName);
254 BOOST_ASSERT(static_cast<bool>(identity));
256 m_pib->setDefaultIdentity(identity.
getName());
262 BOOST_ASSERT(static_cast<bool>(identity));
265 Name keyName = m_tpm->createKey(identity.
getName(), params);
268 Key key = identity.addKey(*m_tpm->getPublicKey(keyName), keyName);
279 return m_tpm->createKey(prefix, params);
285 BOOST_ASSERT(static_cast<bool>(identity));
286 BOOST_ASSERT(static_cast<bool>(key));
291 "does not match key `" + keyName.
toUri() +
"`"));
295 m_tpm->deleteKey(keyName);
301 BOOST_ASSERT(static_cast<bool>(identity));
302 BOOST_ASSERT(static_cast<bool>(key));
314 BOOST_ASSERT(static_cast<bool>(key));
316 const auto& certContent = certificate.
getContent();
317 if (certContent.value_size() == 0) {
322 !std::equal(certContent.value_begin(), certContent.value_end(), key.
getPublicKey().begin())) {
324 "does not match certificate `" + certificate.
getName().
toUri() +
"`"));
327 key.addCertificate(certificate);
333 BOOST_ASSERT(static_cast<bool>(key));
336 NDN_THROW(std::invalid_argument(
"Wrong certificate name `" + certificateName.
toUri() +
"`"));
345 BOOST_ASSERT(static_cast<bool>(key));
359 encryptedKey = m_tpm->exportPrivateKey(keyName, pw, pwLen);
365 return make_shared<SafeBag>(certificate, *encryptedKey);
377 if (m_tpm->hasKey(keyName)) {
382 Identity existingId = m_pib->getIdentity(identity);
383 existingId.
getKey(keyName);
391 m_tpm->importPrivateKey(keyName, safeBag.
getEncryptedKey(), pw, pwLen);
398 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
403 catch (
const std::runtime_error&) {
404 m_tpm->deleteKey(keyName);
407 bool isVerified =
false;
411 publicKey.loadPkcs8(publicKeyBits);
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);
429 if (m_tpm->hasKey(keyName)) {
434 m_tpm->importPrivateKey(keyName,
std::move(key));
448 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
464 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
478 signedName.
append(sigInfoBlock);
483 signedName.
append(sigValue);
506 NDN_THROW_NESTED(std::invalid_argument(
"Certificate request contains invalid public key"));
514 static inline std::tuple<std::string, std::string>
517 size_t pos = uri.find(
':');
518 if (pos != std::string::npos) {
519 return std::make_tuple(uri.substr(0, pos), uri.substr(pos + 1));
522 return std::make_tuple(uri,
"");
526 std::tuple<std::string, std::string>
527 KeyChain::parseAndCheckPibLocator(
const std::string& pibLocator)
529 std::string pibScheme, pibLocation;
532 if (pibScheme.empty()) {
533 pibScheme = getDefaultPibScheme();
536 auto pibFactory = getPibFactories().find(pibScheme);
537 if (pibFactory == getPibFactories().end()) {
538 NDN_THROW(Error(
"PIB scheme `" + pibScheme +
"` is not supported"));
541 return std::make_tuple(pibScheme, pibLocation);
545 KeyChain::createPib(
const std::string& pibLocator)
547 std::string pibScheme, pibLocation;
548 std::tie(pibScheme, pibLocation) = parseAndCheckPibLocator(pibLocator);
549 auto pibFactory = getPibFactories().find(pibScheme);
550 BOOST_ASSERT(pibFactory != getPibFactories().end());
551 return unique_ptr<Pib>(
new Pib(pibScheme, pibLocation, pibFactory->second(pibLocation)));
554 std::tuple<std::string, std::string>
555 KeyChain::parseAndCheckTpmLocator(
const std::string& tpmLocator)
557 std::string tpmScheme, tpmLocation;
560 if (tpmScheme.empty()) {
561 tpmScheme = getDefaultTpmScheme();
564 auto tpmFactory = getTpmFactories().find(tpmScheme);
565 if (tpmFactory == getTpmFactories().end()) {
566 NDN_THROW(Error(
"TPM scheme `" + tpmScheme +
"` is not supported"));
569 return std::make_tuple(tpmScheme, tpmLocation);
573 KeyChain::createTpm(
const std::string& tpmLocator)
575 std::string tpmScheme, tpmLocation;
576 std::tie(tpmScheme, tpmLocation) = parseAndCheckTpmLocator(tpmLocator);
577 auto tpmFactory = getTpmFactories().find(tpmScheme);
578 BOOST_ASSERT(tpmFactory != getTpmFactories().end());
579 return unique_ptr<Tpm>(
new Tpm(tpmScheme, tpmLocation, tpmFactory->second(tpmLocation)));
594 NDN_THROW(std::invalid_argument(
"FreshnessPeriod is not positive"));
620 KeyChain::selfSign(
Key& key)
629 key.addCertificate(cert);
633 std::tuple<Name, SignatureInfo>
634 KeyChain::prepareSignatureInfo(
const SigningInfo& params)
640 identity = m_pib->getDefaultIdentity();
643 return prepareSignatureInfoSha256(params);
645 return prepareSignatureInfoWithIdentity(params, identity);
652 identity = m_pib->getIdentity(identityName);
656 identityName.toUri() +
"` does not exist"));
660 NDN_THROW(InvalidSigningInfoError(
"Cannot determine signing parameters"));
662 return prepareSignatureInfoWithIdentity(params, identity);
670 key = m_pib->
getIdentity(identityName).getKey(keyName);
674 keyName.
toUri() +
"` does not exist"));
678 NDN_THROW(InvalidSigningInfoError(
"Cannot determine signing parameters"));
680 return prepareSignatureInfoWithKey(params, key);
688 key = m_pib->
getIdentity(identityName).getKey(keyName);
692 certName.toUri() +
"` does not exist"));
694 return prepareSignatureInfoWithKey(params, key, certName);
697 return prepareSignatureInfoSha256(params);
700 return prepareSignatureInfoHmac(params);
703 NDN_THROW(InvalidSigningInfoError(
"Unrecognized signer type " +
707 std::tuple<Name, SignatureInfo>
708 KeyChain::prepareSignatureInfoSha256(
const SigningInfo& params)
717 std::tuple<Name, SignatureInfo>
718 KeyChain::prepareSignatureInfoHmac(
const SigningInfo& params)
721 if (!m_tpm->hasKey(keyName)) {
722 m_tpm->importPrivateKey(keyName, params.
getHmacKey());
730 return std::make_tuple(keyName, sigInfo);
733 std::tuple<Name, SignatureInfo>
742 "` does not have a default key"));
744 return prepareSignatureInfoWithKey(params, key);
747 std::tuple<Name, SignatureInfo>
748 KeyChain::prepareSignatureInfoWithKey(
const SigningInfo& params,
const pib::Key& key, optional<Name> certName)
752 if (!sigInfo.hasKeyLocator()) {
763 sigInfo.setKeyLocator(klName);
768 return std::make_tuple(key.
getName(), sigInfo);
782 auto signature = m_tpm->sign(bufs, keyName, digestAlgorithm);
784 NDN_THROW(InvalidSigningInfoError(
"TPM signing failed for key `" + keyName.
toUri() +
"` " 785 "(e.g., PIB contains info about the key, but TPM is missing " 786 "the corresponding private key)"));
803 NDN_THROW(Error(
"Unsupported key type " + boost::lexical_cast<std::string>(keyType)));
#define NDN_THROW_NESTED(e)
SigningInfo signingByKey(const Name &keyName)
void deleteKey(const Identity &identity, const Key &key)
Delete a key key of identity.
Sign Interest using Packet Specification v0.3 semantics.
Key getKey(const Name &keyName) const
Get a key with id keyName.
Data & setContentType(uint32_t type)
Copyright (c) 2011-2015 Regents of the University of California.
Represents an NDN certificate following the version 2.0 format.
represents a semantic error
Buffer getPublicKey() const
Get public key bits (in PKCS#8 format)
Represents a SignatureInfo or InterestSignatureInfo TLV element.
const Key & setDefaultKey(const Name &keyName) const
Set an existing key with name keyName as the default key.
The interface of signing key management.
const SignatureInfo & getSignatureInfo() const
SimpleSymmetricKeyParams is a template for symmetric keys with only one parameter: size...
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.
std::string to_string(const T &val)
optional< uint64_t > version
Certificate name version component.
span< const uint8_t > getPublicKey() const
Get public key bits.
Key createKey(const Identity &identity, const KeyParams ¶ms=getDefaultKeyParams())
Create a new key for identity.
Name getIdentity() const
Get identity name.
static ValidityPeriod makeRelative(time::seconds validFrom, time::seconds validUntil, const time::system_clock::TimePoint &now=time::system_clock::now())
Construct ValidityPeriod relative to a timepoint.
Data & setName(const Name &name)
Set name.
DigestAlgorithm getDigestAlgorithm() const
KeyType getKeyType() const
Get key type.
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.
Data & setContent(const Block &block)
Set Content from a Block.
SignatureInfo & setValidityPeriod(optional< security::ValidityPeriod > validityPeriod)
Append or replace ValidityPeriod.
const Key & getPibKey() const
void sign(Data &data, const SigningInfo ¶ms=SigningInfo())
Sign a Data packet according to the supplied signing information.
InputBuffers extractSignedRanges() const
Extract ranges of Interest covered by the signature in Packet Specification v0.3. ...
NDN_CXX_KEYCHAIN_REGISTER_PIB_BACKEND(PibSqlite3)
Represents a TLV element of the NDN packet format.
Error indicating that the supplied TPM locator does not match the locator stored in PIB...
Represents an Interest packet.
Use a SHA-256 digest only, no signer needs to be specified.
shared_ptr< transform::PrivateKey > getHmacKey() const
span< const uint8_t > getEncryptedKey() const
Get the private key in PKCS #8 format from safe bag.
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.
Name & appendVersion(const optional< uint64_t > &version=nullopt)
Append a version component.
HMAC key, supports sign/verify operations.
Identity createIdentity(const Name &identityName, const KeyParams ¶ms=getDefaultKeyParams())
Create an identity identityName.
const Certificate & setDefaultCertificate(const Name &certName) const
Set an existing certificate with certName as the default certificate.
void importSafeBag(const SafeBag &safeBag, const char *pw, size_t pwLen)
Import a certificate and its corresponding private key from a SafeBag.
const Name & getSignerName() const
KeyType
The type of a cryptographic key.
static const std::string & getScheme()
Pib backend implementation based on SQLite3 database.
Interest & setSignatureValue(ConstBufferPtr value)
Set the InterestSignatureValue.
Certificate makeCertificate(const pib::Key &publicKey, const SigningInfo ¶ms=SigningInfo(), const MakeCertificateOptions &opts={})
Create and sign a certificate packet.
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.
Data & setSignatureInfo(const SignatureInfo &info)
Set SignatureInfo.
A frontend handle of a key instance.
static const std::string & getScheme()
No signer is specified, use default setting or follow the trust schema.
static const std::string & getScheme()
SignedInterestFormat getSignedInterestFormat() const
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.
NDN_CXX_KEYCHAIN_REGISTER_TPM_BACKEND(DummyTpm)
Elliptic Curve key (e.g. for ECDSA), supports sign/verify operations.
optional< ValidityPeriod > validity
Certificate ValidityPeriod.
const Name & getName() const noexcept
Get name.
static const Name & getDigestSha256Identity()
A localhost identity to indicate that the signature is generated using SHA-256.
Use the SHA-256 hash of the public key as 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)
Name createHmacKey(const Name &prefix=SigningInfo::getHmacIdentity(), const HmacKeyParams ¶ms=HmacKeyParams())
Create a new HMAC key.
const name::Component SELF("self")
void importPrivateKey(const Name &keyName, shared_ptr< transform::PrivateKey > key)
Import a private key into the TPM.
SignatureTypeValue
SignatureType values.
Options to KeyChain::makeCertificate() .
SignatureInfo & setSignatureType(tlv::SignatureTypeValue type)
Set SignatureType.
Signer is a key, use its default certificate.
size_t wireEncode(EncodingImpl< TAG > &encoder, Type type=Type::Data) const
Fast encoding or block size estimation.
An in-memory implementation of Pib.
SigningInfo & setSignatureInfo(const SignatureInfo &signatureInfo)
Set a semi-prepared SignatureInfo.
Interest & setSignatureInfo(const SignatureInfo &info)
Set the InterestSignatureInfo.
const Identity & getPibIdentity() const
span< const uint8_t > value_bytes() const noexcept
Return a read-only view of TLV-VALUE as a contiguous range of bytes.
Represents a name component.
const Key & getDefaultKey() const
Get the default key for this Identity.
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)
shared_ptr< Buffer > buf()
Flush written data to the stream and return shared pointer to the underlying buffer.
System configuration file for NDN platform.
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 noexcept
Get the Content element.
SignatureInfo & setKeyLocator(optional< KeyLocator > keyLocator)
Set KeyLocator.
const Name & getName() const noexcept
const Name & getName() const
Get the name of the identity.
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Prepend wire encoding to encoder.
Base class for key parameters.
void toUri(std::ostream &os, name::UriFormat format=name::UriFormat::DEFAULT) const
Write URI representation of the name to the output stream.
Signer is an identity, use its default key and default certificate.
A frontend handle of an Identity.
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
implements an output stream that constructs ndn::Buffer
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.
time::milliseconds freshnessPeriod
Certificate packet FreshnessPeriod.
void removeCertificate(const Name &certName) const
Remove a certificate with certName.
const Parsed & getParsedConfiguration() const
const Name & getIdentity() const
Get the name of the belonging identity.
name::Component issuerId
Certificate name IssuerId component.
EncodingImpl< EncoderTag > EncodingBuffer
const Certificate & getDefaultCertificate() const
Get the default certificate for this Key.
SignerType getSignerType() const
shared_ptr< const Buffer > ConstBufferPtr
Interest & setName(const Name &name)
Set the Interest's name.
Name extractIdentityFromCertName(const Name &certName)
Extract identity namespace from the certificate name certName.