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) {
129 std::string pibLocator = parsed.get<std::string>(
"pib",
"");
130 std::string tpmLocator = parsed.get<std::string>(
"tpm",
"");
132 initialize(pibLocator, tpmLocator,
false);
136 const std::string& tpmName,
142 initialize(pibName, tpmName, allowReset);
149 static inline std::tuple<std::string, std::string>
152 size_t pos = uri.find(
':');
153 if (pos != std::string::npos) {
154 return std::make_tuple(uri.substr(0, pos),
155 uri.substr(pos + 1));
158 return std::make_tuple(uri,
"");
165 std::string defaultPibLocator = DEFAULT_PIB_SCHEME +
":";
166 return defaultPibLocator;
169 static inline std::tuple<std::string, std::string>
172 std::string pibScheme, pibLocation;
173 std::tie(pibScheme, pibLocation) =
parseUri(pibLocator);
175 if (pibScheme.empty()) {
181 BOOST_THROW_EXCEPTION(
KeyChain::Error(
"PIB scheme '" + pibScheme +
"' is not supported"));
183 pibScheme = pibFactory->second.canonicalName;
185 return std::make_tuple(pibScheme, pibLocation);
188 unique_ptr<SecPublicInfo>
193 std::string pibScheme, pibLocation;
197 return pibFactory->second.create(pibLocation);
203 std::string defaultTpmLocator = DEFAULT_TPM_SCHEME +
":";
204 return defaultTpmLocator;
207 static inline std::tuple<std::string, std::string>
210 std::string tpmScheme, tpmLocation;
211 std::tie(tpmScheme, tpmLocation) =
parseUri(tpmLocator);
213 if (tpmScheme.empty()) {
218 BOOST_THROW_EXCEPTION(
KeyChain::Error(
"TPM scheme '" + tpmScheme +
"' is not supported"));
220 tpmScheme = tpmFactory->second.canonicalName;
222 return std::make_tuple(tpmScheme, tpmLocation);
230 std::string tpmScheme, tpmLocation;
234 return tpmFactory->second.create(tpmLocation);
238 KeyChain::initialize(
const std::string& pibLocator,
239 const std::string& tpmLocator,
243 std::string pibScheme, pibLocation;
245 std::string canonicalPibLocator = pibScheme +
":" + pibLocation;
251 std::string tpmScheme, tpmLocation;
253 std::string canonicalTpmLocator = tpmScheme +
":" + tpmLocation;
258 !m_pib->getTpmLocator().empty() && m_pib->getTpmLocator() != canonicalTpmLocator)
260 BOOST_THROW_EXCEPTION(
MismatchError(
"TPM locator supplied does not match TPM locator in PIB: " 261 + m_pib->getTpmLocator() +
" != " + canonicalTpmLocator));
271 m_pib->setTpmLocator(canonicalTpmLocator);
277 m_pib->addIdentity(identityName);
281 keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
283 shared_ptr<PublicKey> key = m_pib->getPublicKey(keyName);
285 if (key->getKeyType() != params.
getKeyType()) {
286 keyName = generateKeyPair(identityName,
true, params);
287 m_pib->setDefaultKeyNameForIdentity(keyName);
291 keyName = generateKeyPair(identityName,
true, params);
292 m_pib->setDefaultKeyNameForIdentity(keyName);
297 certName = m_pib->getDefaultCertificateNameForKey(keyName);
300 shared_ptr<IdentityCertificate> selfCert =
selfSign(keyName);
301 m_pib->addCertificateAsIdentityDefault(*selfCert);
302 certName = selfCert->getName();
312 return generateKeyPair(identityName, isKsk, params);
319 return generateKeyPair(identityName, isKsk, params);
327 Name keyName = generateKeyPair(identityName, isKsk, params);
329 m_pib->setDefaultKeyNameForIdentity(keyName);
339 Name keyName = generateKeyPair(identityName, isKsk, params);
341 m_pib->setDefaultKeyNameForIdentity(keyName);
347 shared_ptr<IdentityCertificate>
349 const Name& signingIdentity,
352 const std::vector<CertificateSubjectDescription>& subjectDescription,
353 const Name& certPrefix)
355 shared_ptr<PublicKey> publicKey;
357 publicKey = m_pib->getPublicKey(keyName);
365 subjectDescription, certPrefix);
368 shared_ptr<IdentityCertificate>
371 const Name& signingIdentity,
374 const std::vector<CertificateSubjectDescription>& subjectDescription,
375 const Name& certPrefix)
377 if (keyName.
size() < 1)
380 std::string keyIdPrefix = keyName.
get(-1).
toUri().substr(0, 4);
381 if (keyIdPrefix !=
"ksk-" && keyIdPrefix !=
"dsk-")
389 certName.
append(signingIdentity)
403 if (certPrefix.
isPrefixOf(keyName) && certPrefix != keyName)
404 certName.
append(certPrefix)
413 auto certificate = make_shared<IdentityCertificate>();
414 certificate->setName(certName);
415 certificate->setNotBefore(notBefore);
416 certificate->setNotAfter(notAfter);
417 certificate->setPublicKeyInfo(publicKey);
419 if (subjectDescription.empty()) {
421 certificate->addSubjectDescription(subjectName);
424 std::vector<CertificateSubjectDescription>::const_iterator sdIt =
425 subjectDescription.begin();
426 std::vector<CertificateSubjectDescription>::const_iterator sdEnd =
427 subjectDescription.end();
428 for(; sdIt != sdEnd; sdIt++)
429 certificate->addSubjectDescription(*sdIt);
432 certificate->encode();
437 std::tuple<Name, SignatureInfo>
438 KeyChain::prepareSignatureInfo(
const SigningInfo& params)
442 shared_ptr<IdentityCertificate> signingCert;
446 if (m_pib->getDefaultCertificate() ==
nullptr)
447 setDefaultCertificateInternal();
449 signingCert = m_pib->getDefaultCertificate();
453 Name signingCertName;
455 signingCertName = m_pib->getDefaultCertificateNameForIdentity(params.
getSignerName());
461 signingCert = m_pib->getCertificate(signingCertName);
466 Name signingCertName;
468 signingCertName = m_pib->getDefaultCertificateNameForKey(params.
getSignerName());
471 BOOST_THROW_EXCEPTION(
Error(
"signing certificate does not exist"));
474 signingCert = m_pib->getCertificate(signingCertName);
480 if (signingCert ==
nullptr)
481 BOOST_THROW_EXCEPTION(
Error(
"signing certificate does not exist"));
490 BOOST_THROW_EXCEPTION(
Error(
"Unrecognized signer type"));
497 return std::make_tuple(signingCert->getPublicKeyName(), sigInfo);
503 signImpl(data, params);
509 signImpl(interest, params);
517 std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
524 shared_ptr<IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
526 if (certificate ==
nullptr) {
533 sig.
setValue(m_tpm->signInTpm(buffer, bufferLength,
534 certificate->getPublicKeyName(),
540 shared_ptr<IdentityCertificate>
543 shared_ptr<PublicKey> pubKey;
545 pubKey = m_pib->getPublicKey(keyName);
551 auto certificate = make_shared<IdentityCertificate>();
556 certificate->setName(certificateName);
559 certificate->setPublicKeyInfo(*pubKey);
562 certificate->encode();
575 BOOST_THROW_EXCEPTION(
SecTpm::Error(
"Private key does not exist"));
585 shared_ptr<SecuredBag>
588 if (!m_pib->doesIdentityExist(identity))
591 Name keyName = m_pib->getDefaultKeyNameForIdentity(identity);
595 pkcs5 = m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, passwordStr);
601 shared_ptr<IdentityCertificate> cert;
603 cert = m_pib->getCertificate(m_pib->getDefaultCertificateNameForKey(keyName));
607 m_pib->addCertificateAsIdentityDefault(*cert);
611 return shared_ptr<SecuredBag>(
new SecuredBag(*cert, pkcs5));
622 m_pib->addIdentity(identity);
625 m_tpm->importPrivateKeyPkcs5IntoTpm(keyName,
626 securedBag.
getKey()->buf(),
627 securedBag.
getKey()->size(),
630 shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.
toUri());
632 m_pib->addKey(keyName, *pubKey);
633 m_pib->setDefaultKeyNameForIdentity(keyName);
636 m_pib->addCertificateAsIdentityDefault(securedBag.
getCertificate());
644 keyType = m_pib->getPublicKeyType(m_pib->getDefaultKeyNameForIdentity(identityName));
653 return defaultRsaParams;
657 return defaultEcdsaParams;
663 BOOST_THROW_EXCEPTION(
Error(
"Unsupported key type"));
668 KeyChain::setDefaultCertificateInternal()
670 m_pib->refreshDefaultCertificate();
672 if (m_pib->getDefaultCertificate() ==
nullptr) {
673 Name defaultIdentity;
675 defaultIdentity = m_pib->getDefaultIdentity();
679 defaultIdentity.
append(
"tmp-identity")
680 .
append(reinterpret_cast<uint8_t*>(&random), 4);
683 m_pib->setDefaultIdentity(defaultIdentity);
684 m_pib->refreshDefaultCertificate();
689 KeyChain::generateKeyPair(
const Name& identityName,
bool isKsk,
const KeyParams& params)
691 Name keyName = m_pib->getNewKeyName(identityName, isKsk);
693 m_tpm->generateKeyPairInTpm(keyName.
toUri(), params);
695 shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.
toUri());
696 m_pib->addKey(keyName, *pubKey);
702 KeyChain::signPacketWrapper(
Data& data,
const Signature& signature,
710 Block sigValue = pureSign(encoder.buf(), encoder.size(), keyName, digestAlgorithm);
720 if (timestamp <= m_lastTimestamp) {
721 timestamp = m_lastTimestamp + time::milliseconds(1);
736 signedName.
append(sigValue);
741 KeyChain::pureSign(
const uint8_t* buf,
size_t size,
747 return m_tpm->signInTpm(buf, size, keyName, digestAlgorithm);
770 if (timestamp <= m_lastTimestamp)
771 timestamp = m_lastTimestamp + time::milliseconds(1);
784 signedName.
append(sigValue);
791 m_pib->deleteCertificateInfo(certificateName);
797 m_pib->deletePublicKeyInfo(keyName);
798 m_tpm->deleteKeyPairInTpm(keyName);
804 std::vector<Name> keyNames;
805 m_pib->getAllKeyNamesOfIdentity(identity, keyNames,
true);
806 m_pib->getAllKeyNamesOfIdentity(identity, keyNames,
false);
808 m_pib->deleteIdentityInfo(identity);
810 for (
const auto& keyName : keyNames)
811 m_tpm->deleteKeyPairInTpm(keyName);
823 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.
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::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.
A CertificateSubjectDescription represents the SubjectDescription entry in a Certificate.
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.
static Name certificateNameToPublicKeyName(const Name &certificateName)
Get the public key name from the full certificate name.
Error thrown when the supplied TPM locator to KeyChain constructor does not match the locator stored ...
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 Name & getPublicKeyName() const
Signing parameters passed to KeyChain.
shared_ptr< SecuredBag > exportIdentity(const Name &identity, const std::string &passwordStr)
export an identity.
PublicKey & getPublicKeyInfo()
const OID ATTRIBUTE_NAME("2.5.4.41")
Factory< KeyChain::TpmCreateFunc > TpmFactory
const Name & getSignerName() const
void setKeyLocator(const KeyLocator &keyLocator)
Set KeyLocator.
uint32_t generateWord32()
Generate a cryptographically non-secure random integer from the range [0, 2^32)
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.
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()
const IdentityCertificate & getCertificate() const
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 cryptographically non-secure random integer from 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.
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.
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
shared_ptr< IdentityCertificate > selfSign(const Name &keyName)
Generate a self-signed certificate for a public key.
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
ConstBufferPtr sha256(const uint8_t *data, size_t dataLength)
Compute the sha-256 digest of data.
const KeyParams & getDefaultKeyParamsForIdentity(const Name &identityName) const
Get default key parameters for the specified identity.
SimplePublicKeyParams is a template for public keys with only one parameter: size.
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.
void deleteKey(const Name &keyName)
delete a key.
const Parsed & getParsedConfiguration() const
PartialName getSubName(ssize_t iStartComponent, size_t nComponents=npos) const
Extract a sub-name (PartialName) of nComponents components starting from iStartComponent.
ConstBufferPtr getKey() const
KeyType getKeyType() const
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...