25 #include "../signing-helpers.hpp" 27 #include "../../util/config-file.hpp" 28 #include "../../util/sha256.hpp" 32 #ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS 33 #include "sec-tpm-osx.hpp" 34 #endif // NDN_CXX_HAVE_OSX_FRAMEWORKS 53 #if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) and defined(NDN_CXX_WITH_OSX_KEYCHAIN) 56 const std::string DEFAULT_TPM_SCHEME =
"tpm-file";
57 #endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) and defined(NDN_CXX_WITH_OSX_KEYCHAIN) 66 #ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS 68 #endif // NDN_CXX_HAVE_OSX_FRAMEWORKS 75 Factory(
const std::string& canonicalName,
const T& create)
76 : canonicalName(canonicalName)
81 std::string 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;
102 KeyChain::registerPibImpl(
const std::string& canonicalName,
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<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<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 m_pib->setDefaultKeyNameForIdentity(keyName);
355 m_pib->setDefaultKeyNameForIdentity(keyName);
361 shared_ptr<IdentityCertificate>
363 const Name& signingIdentity,
366 const std::vector<CertificateSubjectDescription>& subjectDescription,
367 const Name& certPrefix)
369 shared_ptr<PublicKey> publicKey;
371 publicKey = m_pib->getPublicKey(keyName);
379 subjectDescription, certPrefix);
382 shared_ptr<IdentityCertificate>
385 const Name& signingIdentity,
388 const std::vector<CertificateSubjectDescription>& subjectDescription,
389 const Name& certPrefix)
391 if (keyName.
size() < 1)
394 std::string keyIdPrefix = keyName.
get(-1).
toUri().substr(0, 4);
395 if (keyIdPrefix !=
"ksk-" && keyIdPrefix !=
"dsk-")
403 certName.
append(signingIdentity)
417 if (certPrefix.
isPrefixOf(keyName) && certPrefix != keyName)
418 certName.
append(certPrefix)
427 auto certificate = make_shared<IdentityCertificate>();
428 certificate->setName(certName);
429 certificate->setNotBefore(notBefore);
430 certificate->setNotAfter(notAfter);
431 certificate->setPublicKeyInfo(publicKey);
433 if (subjectDescription.empty()) {
435 certificate->addSubjectDescription(subjectName);
438 std::vector<CertificateSubjectDescription>::const_iterator sdIt = subjectDescription.begin();
439 std::vector<CertificateSubjectDescription>::const_iterator sdEnd = subjectDescription.end();
440 for(; sdIt != sdEnd; sdIt++)
441 certificate->addSubjectDescription(*sdIt);
444 certificate->encode();
449 std::tuple<Name, SignatureInfo>
450 KeyChain::prepareSignatureInfo(
const SigningInfo& params)
454 shared_ptr<IdentityCertificate> signingCert;
458 if (m_pib->getDefaultCertificate() ==
nullptr)
459 setDefaultCertificateInternal();
461 signingCert = m_pib->getDefaultCertificate();
465 Name signingCertName;
467 signingCertName = m_pib->getDefaultCertificateNameForIdentity(params.
getSignerName());
473 signingCert = m_pib->getCertificate(signingCertName);
478 Name signingCertName;
480 signingCertName = m_pib->getDefaultCertificateNameForKey(params.
getSignerName());
483 BOOST_THROW_EXCEPTION(
Error(
"signing certificate does not exist"));
486 signingCert = m_pib->getCertificate(signingCertName);
492 if (signingCert ==
nullptr)
493 BOOST_THROW_EXCEPTION(
Error(
"signing certificate does not exist"));
502 BOOST_THROW_EXCEPTION(
Error(
"Unrecognized signer type"));
509 return std::make_tuple(signingCert->getPublicKeyName(), sigInfo);
515 signImpl(data, params);
521 signImpl(interest, params);
529 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
536 shared_ptr<IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
538 if (certificate ==
nullptr) {
545 sig.
setValue(m_tpm->signInTpm(buffer, bufferLength,
546 certificate->getPublicKeyName(),
552 shared_ptr<IdentityCertificate>
555 shared_ptr<PublicKey> pubKey;
557 pubKey = m_pib->getPublicKey(keyName);
563 auto certificate = make_shared<IdentityCertificate>();
568 certificate->setName(certificateName);
571 certificate->setPublicKeyInfo(*pubKey);
574 certificate->encode();
588 BOOST_THROW_EXCEPTION(
SecTpm::Error(
"Private key does not exist"));
598 shared_ptr<SecuredBag>
601 if (!m_pib->doesIdentityExist(identity))
604 Name keyName = m_pib->getDefaultKeyNameForIdentity(identity);
608 pkcs5 = m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, passwordStr);
614 shared_ptr<IdentityCertificate> cert;
616 cert = m_pib->getCertificate(m_pib->getDefaultCertificateNameForKey(keyName));
620 m_pib->addCertificateAsIdentityDefault(*cert);
624 return shared_ptr<SecuredBag>(
new SecuredBag(*cert, pkcs5));
635 m_pib->addIdentity(identity);
638 m_tpm->importPrivateKeyPkcs5IntoTpm(keyName,
639 securedBag.
getKey()->buf(),
640 securedBag.
getKey()->size(),
643 shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.
toUri());
645 m_pib->addKey(keyName, *pubKey);
646 m_pib->setDefaultKeyNameForIdentity(keyName);
649 m_pib->addCertificateAsIdentityDefault(securedBag.
getCertificate());
657 keyType = m_pib->getPublicKeyType(m_pib->getDefaultKeyNameForIdentity(identityName));
666 return defaultRsaParams;
670 return defaultEcParams;
676 BOOST_THROW_EXCEPTION(
Error(
"Unsupported key type"));
681 KeyChain::setDefaultCertificateInternal()
683 m_pib->refreshDefaultCertificate();
685 if (m_pib->getDefaultCertificate() ==
nullptr) {
686 Name defaultIdentity;
688 defaultIdentity = m_pib->getDefaultIdentity();
692 defaultIdentity.
append(
"tmp-identity")
693 .
append(reinterpret_cast<uint8_t*>(&random), 4);
696 m_pib->setDefaultIdentity(defaultIdentity);
697 m_pib->refreshDefaultCertificate();
702 KeyChain::generateKeyPair(
const Name& identityName,
bool isKsk,
const KeyParams& params)
704 Name keyName = m_pib->getNewKeyName(identityName, isKsk);
706 m_tpm->generateKeyPairInTpm(keyName.
toUri(), params);
708 shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.
toUri());
709 m_pib->addKey(keyName, *pubKey);
715 KeyChain::signPacketWrapper(
Data& data,
const Signature& signature,
723 Block sigValue = pureSign(encoder.buf(), encoder.size(), keyName, digestAlgorithm);
733 if (timestamp <= m_lastTimestamp) {
734 timestamp = m_lastTimestamp + time::milliseconds(1);
749 signedName.
append(sigValue);
754 KeyChain::pureSign(
const uint8_t* buf,
size_t size,
760 return m_tpm->signInTpm(buf, size, keyName, digestAlgorithm);
783 if (timestamp <= m_lastTimestamp)
784 timestamp = m_lastTimestamp + time::milliseconds(1);
797 signedName.
append(sigValue);
804 m_pib->deleteCertificateInfo(certificateName);
810 m_pib->deletePublicKeyInfo(keyName);
811 m_tpm->deleteKeyPairInTpm(keyName);
817 std::vector<Name> keyNames;
818 m_pib->getAllKeyNamesOfIdentity(identity, keyNames,
true);
819 m_pib->getAllKeyNamesOfIdentity(identity, keyNames,
false);
821 m_pib->deleteIdentityInfo(identity);
823 for (
const auto& keyName : keyNames)
824 m_tpm->deleteKeyPairInTpm(keyName);
836 BOOST_THROW_EXCEPTION(
Error(
"Unsupported key types"));
static Component fromNumber(uint64_t number)
Create a component encoded as nonNegativeInteger.
void deleteIdentity(const Name &identity)
delete an identity.
static Name certificateNameToPublicKeyName(const Name &certificateName)
Get the public key name from the full certificate name.
const Name & getName() const
Copyright (c) 2013-2017 Regents of the University of California.
void setSignatureType(tlv::SignatureTypeValue type)
Set SignatureType.
static unique_ptr< SecTpm > createTpm(const std::string &tpmLocator)
Create a TPM according to tpmLocator.
Represents a SignatureInfo TLV element.
SimplePublicKeyParams< RsaKeyParamsInfo > RsaKeyParams
RsaKeyParams carries parameters for RSA key.
Data & setSignature(const Signature &signature)
Set Signature.
static std::map< std::string, TpmFactory > & getTpmFactories()
static std::map< std::string, PibFactory > & getPibFactories()
KeyType getKeyType() const
const Name & getSignerName() const
const std::string DEFAULT_PIB_SCHEME
Name & appendVersion(uint64_t version)
Append a version component.
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...
static tlv::SignatureTypeValue getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm)
Represents a signature of DigestSha256 type.
const Parsed & getParsedConfiguration() const
Factory< KeyChain::TpmCreateFunc > TpmFactory
const Signature & getSignature() const
Get Signature.
static const Name DEFAULT_PREFIX
Name generateEcKeyPair(const Name &identityName, bool isKsk=false, uint32_t keySize=256)
Generate a pair of EC keys for the specified identity.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Represents a TLV element of NDN packet format.
void sign(Data &data, const SigningInfo ¶ms=DEFAULT_SIGNING_INFO)
Sign data according to the supplied signing information.
represents an Interest packet
use sha256 digest, no signer needs to be specified
void signByIdentity(T &packet, const Name &identityName)
Sign packet using the default certificate of a particular identity.
static time_point now() noexcept
ConstBufferPtr getKey() const
const Oid ATTRIBUTE_NAME("2.5.4.41")
Name & append(const Component &component)
Append a component.
Factory< KeyChain::PibCreateFunc > PibFactory
Signing parameters passed to KeyChain.
const KeyParams & getDefaultKeyParamsForIdentity(const Name &identityName) const
Get default key parameters for the specified identity.
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...
void setKeyLocator(const KeyLocator &keyLocator)
Set KeyLocator.
std::string toUri() const
Get URI representation of the name.
KeyType getKeyType() const
uint32_t generateWord32()
Generate a non-cryptographically-secure random integer in the range [0, 2^32)
shared_ptr< IdentityCertificate > prepareUnsignedIdentityCertificate(const Name &keyName, const Name &signingIdentity, const time::system_clock::TimePoint ¬Before, const time::system_clock::TimePoint ¬After, const std::vector< CertificateSubjectDescription > &subjectDescription, const Name &certPrefix=DEFAULT_PREFIX)
prepare an unsigned identity certificate
static std::tuple< std::string, std::string > getCanonicalPibLocator(const std::string &pibLocator)
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
PublicKey & getPublicKeyInfo()
void signWithSha256(Data &data)
Set Sha256 weak signature for data.
void setValue(const Block &value)
Set SignatureValue.
shared_ptr< SecuredBag > exportIdentity(const Name &identity, const std::string &passwordStr)
export an identity.
Interest & setName(const Name &name)
boost::property_tree::ptree Parsed
no signer is specified, use default setting or follow the trust schema
void toUri(std::ostream &os) const
Write *this to the output stream, escaping characters according to the NDN URI Scheme.
const SignatureInfo & getSignatureInfo() const
A CertificateSubjectDescription represents the SubjectDescription entry in a Certificate.
#define NDN_CXX_V1_KEYCHAIN_REGISTER_PIB(PibType,...)
Register SecPib class in ndn-cxx KeyChain.
void importIdentity(const SecuredBag &securedBag, const std::string &passwordStr)
import an identity.
Name generateRsaKeyPair(const Name &identityName, bool isKsk=false, uint32_t keySize=2048)
Generate a pair of RSA keys for the specified identity.
size_t size() const
Get number of components.
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.
bool isPrefixOf(const Name &other) const
Check if this name is a prefix of another name.
signer is a certificate, use it directly
const IdentityCertificate & getCertificate() const
SigningInfo signingWithSha256()
signer is a key, use its default certificate
static const RsaKeyParams DEFAULT_KEY_PARAMS
static std::string getDefaultPibLocator()
Get default PIB locator.
uint64_t generateWord64()
Generate a non-cryptographically-secure random integer in the range [0, 2^64)
const Name & getName() const
Get name.
SigningInfo signingByIdentity(const Name &identityName)
static std::tuple< std::string, std::string > parseUri(const std::string &uri)
Name generateEcKeyPairAsDefault(const Name &identityName, bool isKsk=false, uint32_t keySize=256)
Generate a pair of EC keys for the specified identity and set it as default key for the identity...
void deleteCertificate(const Name &certificateName)
delete a certificate.
const Block & getInfo() const
Get SignatureInfo as wire format.
System configuration file for NDN platform.
void encode()
Encode sub elements into TLV-VALUE.
KeyChain()
Constructor to create KeyChain with default PIB and TPM.
milliseconds toUnixTimestamp(const system_clock::TimePoint &point)
Convert system_clock::TimePoint to UNIX timestamp.
Error thrown when the supplied TPM locator to KeyChain constructor does not match the locator stored ...
Base class of key parameters.
signer is an identity, use its default key and default certificate
PartialName getSubName(ssize_t iStartComponent, size_t nComponents=npos) const
Extract some components as a sub-name (PartialName)
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix of the name.
ConstBufferPtr computeDigest()
Finalize and return the digest based on all previously supplied inputs.
#define NDN_CXX_V1_KEYCHAIN_REGISTER_TPM(TpmType,...)
Register SecTpm class in ndn-cxx KeyChain.
static const SigningInfo DEFAULT_SIGNING_INFO
shared_ptr< IdentityCertificate > selfSign(const Name &keyName)
Generate a self-signed certificate for a public key.
shared_ptr< const Buffer > ConstBufferPtr
void deleteKey(const Name &keyName)
delete a key.
Represents a Data packet.
SimplePublicKeyParams is a template for public keys with only one parameter: size.
DigestAlgorithm getDigestAlgorithm() const
const std::string DEFAULT_TPM_SCHEME
function< unique_ptr< SecTpm >const std::string &)> TpmCreateFunc
function< unique_ptr< SecPublicInfo >const std::string &)> PibCreateFunc
const Name & getPublicKeyName() const
const Component & get(ssize_t i) const
Get the component at the given index.
static std::tuple< std::string, std::string > getCanonicalTpmLocator(const std::string &tpmLocator)
EncodingImpl< EncoderTag > EncodingBuffer
SignerType getSignerType() const
static unique_ptr< SecPublicInfo > createPib(const std::string &pibLocator)
Create a PIB according to pibLocator.
static std::string getDefaultTpmLocator()
Get default TPM locator.
duration< boost::int_least32_t, boost::ratio< 86400 > > days
Holds SignatureInfo and SignatureValue in a Data packet.