27 #include "../util/random.hpp" 28 #include "../util/config-file.hpp" 32 #ifdef NDN_CXX_HAVE_OSX_SECURITY 34 #endif // NDN_CXX_HAVE_OSX_SECURITY 53 #if defined(NDN_CXX_HAVE_OSX_SECURITY) and defined(NDN_CXX_WITH_OSX_KEYCHAIN) 56 const std::string DEFAULT_TPM_SCHEME =
"tpm-file";
57 #endif // defined(NDN_CXX_HAVE_OSX_SECURITY) and defined(NDN_CXX_WITH_OSX_KEYCHAIN) 66 #ifdef NDN_CXX_HAVE_OSX_SECURITY 68 #endif // NDN_CXX_HAVE_OSX_SECURITY 76 : canonicalName(canonicalName)
87 static std::map<std::string, PibFactory>&
90 static std::map<std::string, PibFactory> pibFactories;
94 static std::map<std::string, TpmFactory>&
97 static std::map<std::string, TpmFactory> tpmFactories;
103 std::initializer_list<std::string> aliases,
106 for (
const std::string& alias : aliases) {
112 KeyChain::registerTpmImpl(
const std::string& canonicalName,
113 std::initializer_list<std::string> aliases,
116 for (
const std::string& alias : aliases) {
126 std::string pibLocator;
127 std::string tpmLocator;
129 if (getenv(
"NDN_CLIENT_PIB") !=
nullptr) {
130 pibLocator = getenv(
"NDN_CLIENT_PIB");
133 if (getenv(
"NDN_CLIENT_TPM") !=
nullptr) {
134 tpmLocator = getenv(
"NDN_CLIENT_TPM");
137 if (pibLocator.empty() || tpmLocator.empty()) {
141 if (pibLocator.empty()) {
142 pibLocator = parsed.get<std::string>(
"pib",
"");
145 if (tpmLocator.empty()) {
146 tpmLocator = parsed.get<std::string>(
"tpm",
"");
150 initialize(pibLocator, tpmLocator,
false);
154 const std::string& tpmName,
160 initialize(pibName, tpmName, allowReset);
167 static inline std::tuple<std::string, std::string>
170 size_t pos = uri.find(
':');
171 if (pos != std::string::npos) {
172 return std::make_tuple(uri.substr(0, pos),
173 uri.substr(pos + 1));
176 return std::make_tuple(uri,
"");
183 std::string defaultPibLocator = DEFAULT_PIB_SCHEME +
":";
184 return defaultPibLocator;
187 static inline std::tuple<std::string, std::string>
190 std::string pibScheme, pibLocation;
191 std::tie(pibScheme, pibLocation) =
parseUri(pibLocator);
193 if (pibScheme.empty()) {
199 BOOST_THROW_EXCEPTION(
KeyChain::Error(
"PIB scheme '" + pibScheme +
"' is not supported"));
201 pibScheme = pibFactory->second.canonicalName;
203 return std::make_tuple(pibScheme, pibLocation);
206 unique_ptr<SecPublicInfo>
211 std::string pibScheme, pibLocation;
215 return pibFactory->second.create(pibLocation);
221 std::string defaultTpmLocator = DEFAULT_TPM_SCHEME +
":";
222 return defaultTpmLocator;
225 static inline std::tuple<std::string, std::string>
228 std::string tpmScheme, tpmLocation;
229 std::tie(tpmScheme, tpmLocation) =
parseUri(tpmLocator);
231 if (tpmScheme.empty()) {
236 BOOST_THROW_EXCEPTION(
KeyChain::Error(
"TPM scheme '" + tpmScheme +
"' is not supported"));
238 tpmScheme = tpmFactory->second.canonicalName;
240 return std::make_tuple(tpmScheme, tpmLocation);
248 std::string tpmScheme, tpmLocation;
252 return tpmFactory->second.create(tpmLocation);
256 KeyChain::initialize(
const std::string& pibLocator,
257 const std::string& tpmLocator,
261 std::string pibScheme, pibLocation;
263 std::string canonicalPibLocator = pibScheme +
":" + pibLocation;
269 std::string tpmScheme, tpmLocation;
271 std::string canonicalTpmLocator = tpmScheme +
":" + tpmLocation;
276 !m_pib->getTpmLocator().empty() && m_pib->getTpmLocator() != canonicalTpmLocator)
278 BOOST_THROW_EXCEPTION(
MismatchError(
"TPM locator supplied does not match TPM locator in PIB: " 279 + m_pib->getTpmLocator() +
" != " + canonicalTpmLocator));
289 m_pib->setTpmLocator(canonicalTpmLocator);
295 m_pib->addIdentity(identityName);
299 keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
301 shared_ptr<v1::PublicKey> key = m_pib->getPublicKey(keyName);
303 if (key->getKeyType() != params.
getKeyType()) {
304 keyName = generateKeyPair(identityName,
true, params);
305 m_pib->setDefaultKeyNameForIdentity(keyName);
309 keyName = generateKeyPair(identityName,
true, params);
310 m_pib->setDefaultKeyNameForIdentity(keyName);
315 certName = m_pib->getDefaultCertificateNameForKey(keyName);
318 shared_ptr<v1::IdentityCertificate> selfCert =
selfSign(keyName);
319 m_pib->addCertificateAsIdentityDefault(*selfCert);
320 certName = selfCert->getName();
330 return generateKeyPair(identityName, isKsk, params);
337 return generateKeyPair(identityName, isKsk, params);
345 Name keyName = generateKeyPair(identityName, isKsk, params);
347 m_pib->setDefaultKeyNameForIdentity(keyName);
357 Name keyName = generateKeyPair(identityName, isKsk, params);
359 m_pib->setDefaultKeyNameForIdentity(keyName);
365 shared_ptr<v1::IdentityCertificate>
367 const Name& signingIdentity,
370 const std::vector<v1::CertificateSubjectDescription>& subjectDescription,
371 const Name& certPrefix)
373 shared_ptr<v1::PublicKey> publicKey;
375 publicKey = m_pib->getPublicKey(keyName);
383 subjectDescription, certPrefix);
386 shared_ptr<v1::IdentityCertificate>
389 const Name& signingIdentity,
392 const std::vector<v1::CertificateSubjectDescription>& subjectDescription,
393 const Name& certPrefix)
395 if (keyName.
size() < 1)
398 std::string keyIdPrefix = keyName.
get(-1).
toUri().substr(0, 4);
399 if (keyIdPrefix !=
"ksk-" && keyIdPrefix !=
"dsk-")
407 certName.
append(signingIdentity)
421 if (certPrefix.
isPrefixOf(keyName) && certPrefix != keyName)
422 certName.
append(certPrefix)
431 auto certificate = make_shared<v1::IdentityCertificate>();
432 certificate->setName(certName);
433 certificate->setNotBefore(notBefore);
434 certificate->setNotAfter(notAfter);
435 certificate->setPublicKeyInfo(publicKey);
437 if (subjectDescription.empty()) {
439 certificate->addSubjectDescription(subjectName);
442 std::vector<v1::CertificateSubjectDescription>::const_iterator sdIt = subjectDescription.begin();
443 std::vector<v1::CertificateSubjectDescription>::const_iterator sdEnd = subjectDescription.end();
444 for(; sdIt != sdEnd; sdIt++)
445 certificate->addSubjectDescription(*sdIt);
448 certificate->encode();
453 std::tuple<Name, SignatureInfo>
454 KeyChain::prepareSignatureInfo(
const SigningInfo& params)
458 shared_ptr<v1::IdentityCertificate> signingCert;
462 if (m_pib->getDefaultCertificate() ==
nullptr)
463 setDefaultCertificateInternal();
465 signingCert = m_pib->getDefaultCertificate();
469 Name signingCertName;
471 signingCertName = m_pib->getDefaultCertificateNameForIdentity(params.
getSignerName());
477 signingCert = m_pib->getCertificate(signingCertName);
482 Name signingCertName;
484 signingCertName = m_pib->getDefaultCertificateNameForKey(params.
getSignerName());
487 BOOST_THROW_EXCEPTION(
Error(
"signing certificate does not exist"));
490 signingCert = m_pib->getCertificate(signingCertName);
496 if (signingCert ==
nullptr)
497 BOOST_THROW_EXCEPTION(
Error(
"signing certificate does not exist"));
506 BOOST_THROW_EXCEPTION(
Error(
"Unrecognized signer type"));
513 return std::make_tuple(signingCert->getPublicKeyName(), sigInfo);
519 signImpl(data, params);
525 signImpl(interest, params);
533 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
540 shared_ptr<v1::IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
542 if (certificate ==
nullptr) {
549 sig.
setValue(m_tpm->signInTpm(buffer, bufferLength,
550 certificate->getPublicKeyName(),
556 shared_ptr<v1::IdentityCertificate>
559 shared_ptr<v1::PublicKey> pubKey;
561 pubKey = m_pib->getPublicKey(keyName);
567 auto certificate = make_shared<v1::IdentityCertificate>();
572 certificate->setName(certificateName);
575 certificate->setPublicKeyInfo(*pubKey);
578 certificate->encode();
592 BOOST_THROW_EXCEPTION(
SecTpm::Error(
"Private key does not exist"));
602 shared_ptr<SecuredBag>
605 if (!m_pib->doesIdentityExist(identity))
608 Name keyName = m_pib->getDefaultKeyNameForIdentity(identity);
612 pkcs5 = m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, passwordStr);
618 shared_ptr<v1::IdentityCertificate> cert;
620 cert = m_pib->getCertificate(m_pib->getDefaultCertificateNameForKey(keyName));
624 m_pib->addCertificateAsIdentityDefault(*cert);
628 return shared_ptr<SecuredBag>(
new SecuredBag(*cert, pkcs5));
639 m_pib->addIdentity(identity);
642 m_tpm->importPrivateKeyPkcs5IntoTpm(keyName,
643 securedBag.
getKey()->buf(),
644 securedBag.
getKey()->size(),
647 shared_ptr<v1::PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.
toUri());
649 m_pib->addKey(keyName, *pubKey);
650 m_pib->setDefaultKeyNameForIdentity(keyName);
653 m_pib->addCertificateAsIdentityDefault(securedBag.
getCertificate());
661 keyType = m_pib->getPublicKeyType(m_pib->getDefaultKeyNameForIdentity(identityName));
670 return defaultRsaParams;
674 return defaultEcdsaParams;
680 BOOST_THROW_EXCEPTION(
Error(
"Unsupported key type"));
685 KeyChain::setDefaultCertificateInternal()
687 m_pib->refreshDefaultCertificate();
689 if (m_pib->getDefaultCertificate() ==
nullptr) {
690 Name defaultIdentity;
692 defaultIdentity = m_pib->getDefaultIdentity();
696 defaultIdentity.
append(
"tmp-identity")
697 .
append(reinterpret_cast<uint8_t*>(&random), 4);
700 m_pib->setDefaultIdentity(defaultIdentity);
701 m_pib->refreshDefaultCertificate();
706 KeyChain::generateKeyPair(
const Name& identityName,
bool isKsk,
const KeyParams& params)
708 Name keyName = m_pib->getNewKeyName(identityName, isKsk);
710 m_tpm->generateKeyPairInTpm(keyName.
toUri(), params);
712 shared_ptr<v1::PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.
toUri());
713 m_pib->addKey(keyName, *pubKey);
719 KeyChain::signPacketWrapper(
Data& data,
const Signature& signature,
727 Block sigValue = pureSign(encoder.buf(), encoder.size(), keyName, digestAlgorithm);
737 if (timestamp <= m_lastTimestamp) {
738 timestamp = m_lastTimestamp + time::milliseconds(1);
753 signedName.
append(sigValue);
758 KeyChain::pureSign(
const uint8_t* buf,
size_t size,
764 return m_tpm->signInTpm(buf, size, keyName, digestAlgorithm);
787 if (timestamp <= m_lastTimestamp)
788 timestamp = m_lastTimestamp + time::milliseconds(1);
801 signedName.
append(sigValue);
808 m_pib->deleteCertificateInfo(certificateName);
814 m_pib->deletePublicKeyInfo(keyName);
815 m_tpm->deleteKeyPairInTpm(keyName);
821 std::vector<Name> keyNames;
822 m_pib->getAllKeyNamesOfIdentity(identity, keyNames,
true);
823 m_pib->getAllKeyNamesOfIdentity(identity, keyNames,
false);
825 m_pib->deleteIdentityInfo(identity);
827 for (
const auto& keyName : keyNames)
828 m_tpm->deleteKeyPairInTpm(keyName);
840 BOOST_THROW_EXCEPTION(
Error(
"Unsupported key types"));
Factory< KeyChain::PibCreateFunc > PibFactory
static const RsaKeyParams DEFAULT_KEY_PARAMS
static std::tuple< std::string, std::string > getCanonicalTpmLocator(const std::string &tpmLocator)
static Component fromNumber(uint64_t number)
Create a component encoded as nonNegativeInteger.
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix (PartialName) of the name, containing first nComponents components.
static Name certificateNameToPublicKeyName(const Name &certificateName)
Get the public key name from the full certificate name.
static std::map< std::string, PibFactory > & getPibFactories()
Copyright (c) 2011-2015 Regents of the University of California.
void setSignatureType(tlv::SignatureTypeValue type)
Set SignatureType.
function< unique_ptr< SecPublicInfo >const std::string &)> PibCreateFunc
std::string toUri() const
Encode this name as a URI.
const SignatureInfo & getSignatureInfo() const
SimplePublicKeyParams< RsaKeyParamsInfo > RsaKeyParams
RsaKeyParams carries parameters for RSA key.
Data & setSignature(const Signature &signature)
Set the signature to a copy of the given signature.
const Component & get(ssize_t i) const
Get the component at the given index.
void importIdentity(const SecuredBag &securedBag, const std::string &passwordStr)
import an identity.
const std::string DEFAULT_TPM_SCHEME
static unique_ptr< SecPublicInfo > createPib(const std::string &pibLocator)
Create a PIB according to pibLocator.
const Name & getName() const
Get name of the Data packet.
DigestAlgorithm getDigestAlgorithm() const
Represent a SHA256 digest.
void signByIdentity(T &packet, const Name &identityName)
Sign packet using the default certificate of a particular identity.
const Name & getPublicKeyName() const
Error thrown when the supplied TPM locator to KeyChain constructor does not match the locator stored ...
shared_ptr< v1::IdentityCertificate > selfSign(const Name &keyName)
Generate a self-signed certificate for a public key.
Class representing a wire element of NDN-TLV packet format.
represents an Interest packet
#define NDN_CXX_KEYCHAIN_REGISTER_PIB(PibType,...)
Register SecPib class in ndn-cxx KeyChain.
use sha256 digest, no signer needs to be specified
void sign(Data &data, const SigningInfo ¶ms=DEFAULT_SIGNING_INFO)
Sign data according to the supplied signing information.
static time_point now() noexcept
const Oid ATTRIBUTE_NAME("2.5.4.41")
Signing parameters passed to KeyChain.
shared_ptr< SecuredBag > exportIdentity(const Name &identity, const std::string &passwordStr)
export an identity.
Factory< KeyChain::TpmCreateFunc > TpmFactory
const Name & getSignerName() const
void setKeyLocator(const KeyLocator &keyLocator)
Set KeyLocator.
uint32_t generateWord32()
Generate a non-cryptographically-secure random integer in the range [0, 2^32)
PublicKey & getPublicKeyInfo()
Name generateEcdsaKeyPairAsDefault(const Name &identityName, bool isKsk=false, uint32_t keySize=256)
Generate a pair of ECDSA keys for the specified identity and set it as default key for the identity...
static std::tuple< std::string, std::string > getCanonicalPibLocator(const std::string &pibLocator)
static const SigningInfo DEFAULT_SIGNING_INFO
EncodingImpl< EncoderTag > EncodingBuffer
void setValue(const Block &value)
Get SignatureValue from a block.
Interest & setName(const Name &name)
boost::property_tree::ptree Parsed
no signer is specified, use default setting or follow the trust schema
const Block & getInfo() const
Get SignatureInfo in the wire format.
Name createIdentity(const Name &identityName, const KeyParams ¶ms=DEFAULT_KEY_PARAMS)
Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed ce...
SigningInfo signingByIdentity(const Name &identity)
function< unique_ptr< SecTpm >const std::string &)> TpmCreateFunc
void toUri(std::ostream &os) const
Write *this to the output stream, escaping characters according to the NDN URI Scheme.
static std::string getDefaultTpmLocator()
Get default TPM locator.
A CertificateSubjectDescription represents the SubjectDescription entry in a Certificate.
Name abstraction to represent an absolute name.
KeyType getKeyType() const
bool isPrefixOf(const Name &name) const
Check if the N components of this name are the same as the first N components of the given name...
signer is a certificate, use it directly
Factory(const std::string &canonicalName, const T &create)
SigningInfo signingWithSha256()
void deleteIdentity(const Name &identity)
delete an identity.
signer is a key, use its default certificate
size_t size() const
Get the number of components.
Name generateRsaKeyPair(const Name &identityName, bool isKsk=false, uint32_t keySize=2048)
Generate a pair of RSA keys for the specified identity.
static tlv::SignatureTypeValue getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm)
KeyChain()
Constructor to create KeyChain with default PIB and TPM.
uint64_t generateWord64()
Generate a non-cryptographically-secure random integer in the range [0, 2^64)
static unique_ptr< SecTpm > createTpm(const std::string &tpmLocator)
Create a TPM according to tpmLocator.
static std::string getDefaultPibLocator()
Get default PIB locator.
const std::string DEFAULT_PIB_SCHEME
#define NDN_CXX_KEYCHAIN_REGISTER_TPM(TpmType,...)
Register SecTpm class in ndn-cxx KeyChain.
System configuration file for NDN platform.
void encode()
Encode subblocks into wire buffer.
milliseconds toUnixTimestamp(const system_clock::TimePoint &point)
Convert system_clock::TimePoint to UNIX timestamp.
static std::tuple< std::string, std::string > parseUri(const std::string &uri)
Name & append(const uint8_t *value, size_t valueLength)
Append a new component, copying from value of length valueLength.
ConstBufferPtr computeSha256Digest(const uint8_t *data, size_t dataLength)
Compute the sha-256 digest of data.
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
Base class of key parameters.
signer is an identity, use its default key and default certificate
Name generateEcdsaKeyPair(const Name &identityName, bool isKsk=false, uint32_t keySize=256)
Generate a pair of ECDSA keys for the specified identity.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
static const Name DEFAULT_PREFIX
void signWithSha256(Data &data)
Set Sha256 weak signature for data.
const Signature & getSignature() const
shared_ptr< const Buffer > ConstBufferPtr
const KeyParams & getDefaultKeyParamsForIdentity(const Name &identityName) const
Get default key parameters for the specified identity.
ConstBufferPtr getKey() const
SimplePublicKeyParams is a template for public keys with only one parameter: size.
shared_ptr< v1::IdentityCertificate > prepareUnsignedIdentityCertificate(const Name &keyName, const Name &signingIdentity, const time::system_clock::TimePoint ¬Before, const time::system_clock::TimePoint ¬After, const std::vector< security::v1::CertificateSubjectDescription > &subjectDescription, const Name &certPrefix=DEFAULT_PREFIX)
prepare an unsigned identity certificate
Name generateRsaKeyPairAsDefault(const Name &identityName, bool isKsk=false, uint32_t keySize=2048)
Generate a pair of RSA keys for the specified identity and set it as default key for the identity...
static const Name DIGEST_SHA256_IDENTITY
A localhost identity which indicates that signature is generated using SHA-256.
KeyType getKeyType() const
void deleteKey(const Name &keyName)
delete a key.
const Parsed & getParsedConfiguration() const
const v1::IdentityCertificate & getCertificate() const
PartialName getSubName(ssize_t iStartComponent, size_t nComponents=npos) const
Extract a sub-name (PartialName) of nComponents components starting from iStartComponent.
void deleteCertificate(const Name &certificateName)
delete a certificate.
duration< boost::int_least32_t, boost::ratio< 86400 > > days
Name & appendVersion(uint64_t version)
Append version using NDN naming conventions.
static std::map< std::string, TpmFactory > & getTpmFactories()
const Name & getName() const
std::string canonicalName
SignerType getSignerType() const
A Signature is storage for the signature-related information (info and value) in a Data packet...