security: Construct KeyChain from configuration file.
Change-Id: Iaddac24e2c4e199fdde83fa1d0067a87e18729c4
Refs: #1532
diff --git a/src/security/key-chain.hpp b/src/security/key-chain.hpp
index 69d5ffb..bb0f650 100644
--- a/src/security/key-chain.hpp
+++ b/src/security/key-chain.hpp
@@ -15,41 +15,57 @@
#ifndef NDN_SECURITY_KEY_CHAIN_HPP
#define NDN_SECURITY_KEY_CHAIN_HPP
-#include "identity-certificate.hpp"
-#include "public-key.hpp"
+#include "sec-public-info.hpp"
+#include "sec-tpm.hpp"
+#include "secured-bag.hpp"
#include "signature-sha256-with-rsa.hpp"
#include "signature-sha256.hpp"
-#include "secured-bag.hpp"
+
#include "../interest.hpp"
-#include "../util/random.hpp"
#include "../util/crypto.hpp"
-//PublicInfo
-#include "sec-public-info-sqlite3.hpp"
-#include "sec-public-info-memory.hpp"
-//TPM
-#include "sec-tpm-file.hpp"
-#include "sec-tpm-memory.hpp"
-
-#ifdef NDN_CXX_HAVE_OSX_SECURITY
-#include "sec-tpm-osx.hpp"
-#endif
-
namespace ndn {
-/**
- * @brief KeyChain is one of the main classes of the security library.
- *
- * The KeyChain class provides a set of interfaces of identity management and private key related
- * operations.
- */
-template<class Info, class Tpm>
-class KeyChainImpl : public Info, public Tpm
+template<class TypePib, class TypeTpm>
+class KeyChainTraits
{
- typedef SecPublicInfo::Error InfoError;
- typedef SecTpm::Error TpmError;
public:
+ typedef TypePib Pib;
+ typedef TypeTpm Tpm;
+};
+
+class KeyChain
+{
+public:
+ class Error : public std::runtime_error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : std::runtime_error(what)
+ {
+ }
+ };
+
+ KeyChain();
+
+ template<class KeyChainTraits>
+ KeyChain(KeyChainTraits traits);
+
+ KeyChain(const std::string& pibName,
+ const std::string& tpmName);
+
+ virtual
+ ~KeyChain()
+ {
+ if (m_pib != 0)
+ delete m_pib;
+
+ if (m_tpm != 0)
+ delete m_tpm;
+ }
+
/**
* @brief Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a
* self-signed certificate of the KSK.
@@ -57,35 +73,8 @@
* @param identityName The name of the identity.
* @return The name of the default certificate of the identity.
*/
- Name
- createIdentity(const Name& identityName)
- {
- Info::addIdentity(identityName);
-
- Name keyName;
- try
- {
- keyName = Info::getDefaultKeyNameForIdentity(identityName);
- }
- catch (InfoError& e)
- {
- keyName = generateRSAKeyPairAsDefault(identityName, true);
- }
-
- Name certName;
- try
- {
- certName = Info::getDefaultCertificateNameForKey(keyName);
- }
- catch (InfoError& e)
- {
- shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
- Info::addCertificateAsIdentityDefault(*selfCert);
- certName = selfCert->getName();
- }
-
- return certName;
- }
+ inline Name
+ createIdentity(const Name& identityName);
/**
* @brief Generate a pair of RSA keys for the specified identity.
@@ -95,11 +84,8 @@
* @param keySize The size of the key.
* @return The generated key name.
*/
- Name
- generateRSAKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048)
- {
- return generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
- }
+ inline Name
+ generateRsaKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048);
/**
* @brief Generate a pair of RSA keys for the specified identity and set it as default key for
@@ -110,15 +96,8 @@
* @param keySize The size of the key.
* @return The generated key name.
*/
- Name
- generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048)
- {
- Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
-
- Info::setDefaultKeyNameForIdentity(keyName);
-
- return keyName;
- }
+ inline Name
+ generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048);
/**
* @brief prepare an unsigned identity certificate
@@ -132,73 +111,10 @@
*/
shared_ptr<IdentityCertificate>
prepareUnsignedIdentityCertificate(const Name& keyName,
- const Name& signingIdentity,
- const time::system_clock::TimePoint& notBefore,
- const time::system_clock::TimePoint& notAfter,
- const std::vector<CertificateSubjectDescription>& subjectDescription)
-
- {
- if (keyName.size() < 1)
- return shared_ptr<IdentityCertificate>();
-
- std::string keyIdPrefix = keyName.get(-1).toEscapedString().substr(0, 4);
- if (keyIdPrefix != "ksk-" && keyIdPrefix != "dsk-")
- return shared_ptr<IdentityCertificate>();
-
- shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
- Name certName;
-
- if (signingIdentity.isPrefixOf(keyName))
- {
- certName.append(signingIdentity)
- .append("KEY")
- .append(keyName.getSubName(signingIdentity.size()))
- .append("ID-CERT")
- .appendVersion();
- }
- else
- {
- certName.append(keyName.getPrefix(-1))
- .append("KEY")
- .append(keyName.get(-1))
- .append("ID-CERT")
- .appendVersion();
- }
-
- certificate->setName(certName);
- certificate->setNotBefore(notBefore);
- certificate->setNotAfter(notAfter);
-
- shared_ptr<PublicKey> publicKey;
- try
- {
- publicKey = Info::getPublicKey(keyName);
- }
- catch (InfoError& e)
- {
- return shared_ptr<IdentityCertificate>();
- }
- certificate->setPublicKeyInfo(*publicKey);
-
- if (subjectDescription.empty())
- {
- CertificateSubjectDescription subDescryptName("2.5.4.41", keyName.getPrefix(-1).toUri());
- certificate->addSubjectDescription(subDescryptName);
- }
- else
- {
- std::vector<CertificateSubjectDescription>::const_iterator sdIt =
- subjectDescription.begin();
- std::vector<CertificateSubjectDescription>::const_iterator sdEnd =
- subjectDescription.end();
- for(; sdIt != sdEnd; sdIt++)
- certificate->addSubjectDescription(*sdIt);
- }
-
- certificate->encode();
-
- return certificate;
- }
+ const Name& signingIdentity,
+ const time::system_clock::TimePoint& notBefore,
+ const time::system_clock::TimePoint& notAfter,
+ const std::vector<CertificateSubjectDescription>& subjectDescription);
/**
* @brief Sign packet with default identity
@@ -211,33 +127,7 @@
*/
template<typename T>
void
- sign(T& packet)
- {
- if (!static_cast<bool>(Info::defaultCertificate()))
- {
- Info::refreshDefaultCertificate();
-
- if (!static_cast<bool>(Info::defaultCertificate()))
- {
- Name defaultIdentity;
- try
- {
- defaultIdentity = Info::getDefaultIdentity();
- }
- catch (InfoError& e)
- {
- uint32_t random = random::generateWord32();
- defaultIdentity.append("tmp-identity")
- .append(reinterpret_cast<uint8_t*>(&random), 4);
- }
- createIdentity(defaultIdentity);
- Info::setDefaultIdentity(defaultIdentity);
- Info::refreshDefaultCertificate();
- }
- }
-
- sign(packet, *Info::defaultCertificate());
- }
+ sign(T& packet);
/**
* @brief Sign packet with a particular certificate.
@@ -248,20 +138,7 @@
*/
template<typename T>
void
- sign(T& packet, const Name& certificateName)
- {
- if (!Info::doesCertificateExist(certificateName))
- throw InfoError("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
-
- SignatureSha256WithRsa signature;
- // implicit conversion should take care
- signature.setKeyLocator(certificateName.getPrefix(-1));
-
- // For temporary usage, we support RSA + SHA256 only, but will support more.
- signPacketWrapper(packet, signature,
- IdentityCertificate::certificateNameToPublicKeyName(certificateName),
- DIGEST_ALGORITHM_SHA256);
- }
+ sign(T& packet, const Name& certificateName);
/**
* @brief Sign the byte array using a particular certificate.
@@ -273,21 +150,7 @@
* @throws SecPublicInfo::Error if certificate does not exist.
*/
Signature
- sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
- {
- if (!Info::doesCertificateExist(certificateName))
- throw InfoError("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
-
- Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
-
- SignatureSha256WithRsa signature;
- // implicit conversion should take care
- signature.setKeyLocator(certificateName.getPrefix(-1));
-
- // For temporary usage, we support RSA + SHA256 only, but will support more.
- signature.setValue(Tpm::signInTpm(buffer, bufferLength, keyName, DIGEST_ALGORITHM_SHA256));
- return signature;
- }
+ sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName);
/**
* @brief Sign packet using the default certificate of a particular identity.
@@ -300,24 +163,7 @@
*/
template<typename T>
void
- signByIdentity(T& packet, const Name& identityName)
- {
- Name signingCertificateName;
- try
- {
- signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
- }
- catch (InfoError& e)
- {
- signingCertificateName = createIdentity(identityName);
- // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
- // is a fatal error.
- }
-
- // We either get or create the signing certificate, sign packet! (no exception unless fatal
- // error in TPM)
- sign(packet, signingCertificateName);
- }
+ signByIdentity(T& packet, const Name& identityName);
/**
* @brief Sign the byte array using the default certificate of a particular identity.
@@ -327,43 +173,16 @@
* @param identityName The identity name.
* @return The Signature.
*/
- Signature
- signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
- {
- Name signingCertificateName;
- try
- {
- signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
- }
- catch (InfoError& e)
- {
- signingCertificateName = createIdentity(identityName);
- // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
- // is a fatal error.
- }
-
- // We either get or create the signing certificate, sign data! (no exception unless fatal error
- // in TPM)
- return sign(buffer, bufferLength, signingCertificateName);
- }
+ inline Signature
+ signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName);
/**
* @brief Set Sha256 weak signature.
*
* @param data.
*/
- void
- signWithSha256(Data& data)
- {
- SignatureSha256 sig;
- data.setSignature(sig);
-
- Block sigValue(Tlv::SignatureValue,
- crypto::sha256(data.wireEncode().value(),
- data.wireEncode().value_size() -
- data.getSignature().getValue().size()));
- data.setSignatureValue(sigValue);
- }
+ inline void
+ signWithSha256(Data& data);
/**
* @brief Generate a self-signed certificate for a public key.
@@ -372,33 +191,7 @@
* @return The generated certificate, NULL if selfSign fails.
*/
shared_ptr<IdentityCertificate>
- selfSign(const Name& keyName)
- {
- shared_ptr<PublicKey> pubKey;
- try
- {
- pubKey = Info::getPublicKey(keyName); // may throw an exception.
- }
- catch (InfoError& e)
- {
- return shared_ptr<IdentityCertificate>();
- }
-
- shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
-
- Name certificateName = keyName.getPrefix(-1);
- certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
-
- certificate->setName(certificateName);
- certificate->setNotBefore(time::system_clock::now());
- certificate->setNotAfter(time::system_clock::now() + time::days(7300)/* ~20 years*/);
- certificate->setPublicKeyInfo(*pubKey);
- certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
- certificate->encode();
-
- selfSign(*certificate);
- return certificate;
- }
+ selfSign(const Name& keyName);
/**
* @brief Self-sign the supplied identity certificate.
@@ -407,18 +200,7 @@
* @throws SecTpm::Error if the private key does not exist.
*/
void
- selfSign (IdentityCertificate& cert)
- {
- Name keyName = IdentityCertificate::certificateNameToPublicKeyName(cert.getName());
- if (!Tpm::doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
- throw TpmError("private key does not exist!");
-
- SignatureSha256WithRsa signature;
- signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
-
- // For temporary usage, we support RSA + SHA256 only, but will support more.
- signPacketWrapper(cert, signature, keyName, DIGEST_ALGORITHM_SHA256);
- }
+ selfSign(IdentityCertificate& cert);
/**
* @brief delete a certificate.
@@ -428,21 +210,8 @@
*
* @param certificateName The certificate to be deleted.
*/
- void
- deleteCertificate (const Name& certificateName)
- {
- try
- {
- if (Info::getDefaultCertificateName() == certificateName)
- return;
- }
- catch (InfoError& e)
- {
- // Not a real error, just try to delete the certificate
- }
-
- Info::deleteCertificateInfo(certificateName);
- }
+ inline void
+ deleteCertificate(const Name& certificateName);
/**
* @brief delete a key.
@@ -452,22 +221,8 @@
*
* @param keyName The key to be deleted.
*/
- void
- deleteKey (const Name& keyName)
- {
- try
- {
- if (Info::getDefaultKeyNameForIdentity(Info::getDefaultIdentity()) == keyName)
- return;
- }
- catch (InfoError& e)
- {
- // Not a real error, just try to delete the key
- }
-
- Info::deletePublicKeyInfo(keyName);
- Tpm::deleteKeyPairInTpm(keyName);
- }
+ inline void
+ deleteKey(const Name& keyName);
/**
* @brief delete an identity.
@@ -477,29 +232,8 @@
*
* @param identity The identity to be deleted.
*/
- void
- deleteIdentity (const Name& identity)
- {
- try
- {
- if (Info::getDefaultIdentity() == identity)
- return;
- }
- catch (InfoError& e)
- {
- // Not a real error, just try to delete the identity
- }
-
- std::vector<Name> nameList;
- Info::getAllKeyNamesOfIdentity(identity, nameList, true);
- Info::getAllKeyNamesOfIdentity(identity, nameList, false);
-
- Info::deleteIdentityInfo(identity);
-
- std::vector<Name>::const_iterator it = nameList.begin();
- for(; it != nameList.end(); it++)
- Tpm::deleteKeyPairInTpm(*it);
- }
+ inline void
+ deleteIdentity(const Name& identity);
/**
* @brief export an identity.
@@ -507,42 +241,10 @@
* @param identity The identity to export.
* @param passwordStr The password to secure the private key.
* @return The encoded export data.
- * @throws InfoError if anything goes wrong in exporting.
+ * @throws SecPublicInfo::Error if anything goes wrong in exporting.
*/
shared_ptr<SecuredBag>
- exportIdentity(const Name& identity, const std::string& passwordStr)
- {
- if (!Info::doesIdentityExist(identity))
- throw InfoError("Identity does not exist!");
-
- Name keyName = Info::getDefaultKeyNameForIdentity(identity);
-
- ConstBufferPtr pkcs5;
- try
- {
- pkcs5 = Tpm::exportPrivateKeyPkcs5FromTpm(keyName, passwordStr);
- }
- catch (TpmError& e)
- {
- throw InfoError("Fail to export PKCS5 of private key");
- }
-
- shared_ptr<IdentityCertificate> cert;
- try
- {
- cert = Info::getCertificate(Info::getDefaultCertificateNameForKey(keyName));
- }
- catch (InfoError& e)
- {
- cert = selfSign(keyName);
- Info::addCertificateAsIdentityDefault(*cert);
- }
-
- shared_ptr<SecuredBag> secureBag = make_shared<SecuredBag>(boost::cref(*cert),
- boost::cref(pkcs5));
-
- return secureBag;
- }
+ exportIdentity(const Name& identity, const std::string& passwordStr);
/**
* @brief import an identity.
@@ -551,48 +253,349 @@
* @param passwordStr The password to secure the private key.
*/
void
- importIdentity(const SecuredBag& securedBag, const std::string& passwordStr)
+ importIdentity(const SecuredBag& securedBag, const std::string& passwordStr);
+
+ SecPublicInfo&
+ getPib()
{
- Name certificateName = securedBag.getCertificate().getName();
- Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
- Name identity = keyName.getPrefix(-1);
-
- // Add identity
- Info::addIdentity(identity);
-
- // Add key
- Tpm::importPrivateKeyPkcs5IntoTpm(keyName,
- securedBag.getKey()->buf(),
- securedBag.getKey()->size(),
- passwordStr);
-
- shared_ptr<PublicKey> pubKey = Tpm::getPublicKeyFromTpm(keyName.toUri());
- // HACK! We should set key type according to the pkcs8 info.
- Info::addPublicKey(keyName, KEY_TYPE_RSA, *pubKey);
- Info::setDefaultKeyNameForIdentity(keyName);
-
- // Add cert
- Info::addCertificateAsIdentityDefault(securedBag.getCertificate());
+ return *m_pib;
}
+ const SecPublicInfo&
+ getPib() const
+ {
+ return *m_pib;
+ }
+
+ SecTpm&
+ getTpm()
+ {
+ return *m_tpm;
+ }
+
+ const SecTpm&
+ getTpm() const
+ {
+ return *m_tpm;
+ }
+
+ /*******************************
+ * Wrapper of SecPublicInfo *
+ *******************************/
+ bool
+ doesIdentityExist(const Name& identityName) const
+ {
+ return m_pib->doesIdentityExist(identityName);
+ }
+
+ void
+ addIdentity(const Name& identityName)
+ {
+ return m_pib->addIdentity(identityName);
+ }
+
+ bool
+ doesPublicKeyExist(const Name& keyName) const
+ {
+ return m_pib->doesPublicKeyExist(keyName);
+ }
+
+ void
+ addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
+ {
+ return m_pib->addPublicKey(keyName, keyType, publicKeyDer);
+ }
+
+ shared_ptr<PublicKey>
+ getPublicKey(const Name& keyName) const
+ {
+ return m_pib->getPublicKey(keyName);
+ }
+
+ bool
+ doesCertificateExist(const Name& certificateName) const
+ {
+ return m_pib->doesCertificateExist(certificateName);
+ }
+
+ void
+ addCertificate(const IdentityCertificate& certificate)
+ {
+ return m_pib->addCertificate(certificate);
+ }
+
+ shared_ptr<IdentityCertificate>
+ getCertificate(const Name& certificateName) const
+ {
+ return m_pib->getCertificate(certificateName);
+ }
+
+ Name
+ getDefaultIdentity() const
+ {
+ return m_pib->getDefaultIdentity();
+ }
+
+ Name
+ getDefaultKeyNameForIdentity(const Name& identityName) const
+ {
+ return m_pib->getDefaultKeyNameForIdentity(identityName);
+ }
+
+ Name
+ getDefaultCertificateNameForKey(const Name& keyName) const
+ {
+ return m_pib->getDefaultCertificateNameForKey(keyName);
+ }
+
+ void
+ getAllIdentities(std::vector<Name>& nameList, bool isDefault) const
+ {
+ return m_pib->getAllIdentities(nameList, isDefault);
+ }
+
+ void
+ getAllKeyNames(std::vector<Name>& nameList, bool isDefault) const
+ {
+ return m_pib->getAllKeyNames(nameList, isDefault);
+ }
+
+ void
+ getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name>& nameList, bool isDefault) const
+ {
+ return m_pib->getAllKeyNamesOfIdentity(identity, nameList, isDefault);
+ }
+
+ void
+ getAllCertificateNames(std::vector<Name>& nameList, bool isDefault) const
+ {
+ return m_pib->getAllCertificateNames(nameList, isDefault);
+ }
+
+ void
+ getAllCertificateNamesOfKey(const Name& keyName,
+ std::vector<Name>& nameList,
+ bool isDefault) const
+ {
+ return m_pib->getAllCertificateNamesOfKey(keyName, nameList, isDefault);
+ }
+
+ void
+ deleteCertificateInfo(const Name& certificateName)
+ {
+ return m_pib->deleteCertificateInfo(certificateName);
+ }
+
+ void
+ deletePublicKeyInfo(const Name& keyName)
+ {
+ return m_pib->deletePublicKeyInfo(keyName);
+ }
+
+ void
+ deleteIdentityInfo(const Name& identity)
+ {
+ return m_pib->deleteIdentityInfo(identity);
+ }
+
+ void
+ setDefaultIdentity(const Name& identityName)
+ {
+ return m_pib->setDefaultIdentity(identityName);
+ }
+
+ void
+ setDefaultKeyNameForIdentity(const Name& keyName)
+ {
+ return m_pib->setDefaultKeyNameForIdentity(keyName);
+ }
+
+ void
+ setDefaultCertificateNameForKey(const Name& certificateName)
+ {
+ return m_pib->setDefaultCertificateNameForKey(certificateName);
+ }
+
+ Name
+ getNewKeyName(const Name& identityName, bool useKsk)
+ {
+ return m_pib->getNewKeyName(identityName, useKsk);
+ }
+
+ Name
+ getDefaultCertificateNameForIdentity(const Name& identityName) const
+ {
+ return m_pib->getDefaultCertificateNameForIdentity(identityName);
+ }
+
+ Name
+ getDefaultCertificateName() const
+ {
+ return m_pib->getDefaultCertificateName();
+ }
+
+ void
+ addCertificateAsKeyDefault(const IdentityCertificate& certificate)
+ {
+ return m_pib->addCertificateAsKeyDefault(certificate);
+ }
+
+ void
+ addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
+ {
+ return m_pib->addCertificateAsIdentityDefault(certificate);
+ }
+
+ void
+ addCertificateAsSystemDefault(const IdentityCertificate& certificate)
+ {
+ return m_pib->addCertificateAsSystemDefault(certificate);
+ }
+
+ shared_ptr<IdentityCertificate>
+ getDefaultCertificate() const
+ {
+ return m_pib->defaultCertificate();
+ }
+
+ void
+ refreshDefaultCertificate()
+ {
+ return m_pib->refreshDefaultCertificate();
+ }
+
+ /*******************************
+ * Wrapper of SecTpm *
+ *******************************/
+
+ void
+ setTpmPassword(const uint8_t* password, size_t passwordLength)
+ {
+ return m_tpm->setTpmPassword(password, passwordLength);
+ }
+
+ void
+ resetTpmPassword()
+ {
+ return m_tpm->resetTpmPassword();
+ }
+
+ void
+ setInTerminal(bool inTerminal)
+ {
+ return m_tpm->setInTerminal(inTerminal);
+ }
+
+ bool
+ getInTerminal() const
+ {
+ return m_tpm->getInTerminal();
+ }
+
+ bool
+ isLocked() const
+ {
+ return m_tpm->isLocked();
+ }
+
+ bool
+ unlockTpm(const char* password, size_t passwordLength, bool usePassword)
+ {
+ return m_tpm->unlockTpm(password, passwordLength, usePassword);
+ }
+
+ void
+ generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
+ {
+ return m_tpm->generateKeyPairInTpm(keyName, keyType, keySize);
+ }
+
+ void
+ deleteKeyPairInTpm(const Name& keyName)
+ {
+ return m_tpm->deleteKeyPairInTpm(keyName);
+ }
+
+ shared_ptr<PublicKey>
+ getPublicKeyFromTpm(const Name& keyName) const
+ {
+ return m_tpm->getPublicKeyFromTpm(keyName);
+ }
+
+ Block
+ signInTpm(const uint8_t* data, size_t dataLength,
+ const Name& keyName,
+ DigestAlgorithm digestAlgorithm)
+ {
+ return m_tpm->signInTpm(data, dataLength, keyName, digestAlgorithm);
+ }
+
+ ConstBufferPtr
+ decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
+ {
+ return m_tpm->decryptInTpm(data, dataLength, keyName, isSymmetric);
+ }
+
+ ConstBufferPtr
+ encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
+ {
+ return m_tpm->encryptInTpm(data, dataLength, keyName, isSymmetric);
+ }
+
+ void
+ generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize)
+ {
+ return m_tpm->generateSymmetricKeyInTpm(keyName, keyType, keySize);
+ }
+
+ bool
+ doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) const
+ {
+ return m_tpm->doesKeyExistInTpm(keyName, keyClass);
+ }
+
+ bool
+ generateRandomBlock(uint8_t* res, size_t size) const
+ {
+ return m_tpm->generateRandomBlock(res, size);
+ }
+
+ void
+ addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl)
+ {
+ return m_tpm->addAppToAcl(keyName, keyClass, appPath, acl);
+ }
+
+ ConstBufferPtr
+ exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password)
+ {
+ return m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, password);
+ }
+
+ bool
+ importPrivateKeyPkcs5IntoTpm(const Name& keyName,
+ const uint8_t* buf, size_t size,
+ const std::string& password)
+ {
+ return m_tpm->importPrivateKeyPkcs5IntoTpm(keyName, buf, size, password);
+ }
private:
/**
- * @brief sign a packet using a pariticular certificate.
+ * @brief Set default certificate if it is not initialized
+ */
+ void
+ setDefaultCertificateInternal();
+
+ /**
+ * @brief Sign a packet using a pariticular certificate.
*
* @param packet The packet to be signed.
* @param certificate The signing certificate.
*/
template<typename T>
void
- sign(T& packet, const IdentityCertificate& certificate)
- {
- SignatureSha256WithRsa signature;
- signature.setKeyLocator(certificate.getName().getPrefix(-1));
-
- // For temporary usage, we support RSA + SHA256 only, but will support more.
- signPacketWrapper(packet, signature, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
- }
+ sign(T& packet, const IdentityCertificate& certificate);
/**
* @brief Generate a key pair for the specified identity.
@@ -603,19 +606,9 @@
* @param keySize The size of the key pair.
* @return The name of the generated key.
*/
- Name
+ inline Name
generateKeyPair(const Name& identityName, bool isKsk = false,
- KeyType keyType = KEY_TYPE_RSA, int keySize = 2048)
- {
- Name keyName = Info::getNewKeyName(identityName, isKsk);
-
- Tpm::generateKeyPairInTpm(keyName.toUri(), keyType, keySize);
-
- shared_ptr<PublicKey> pubKey = Tpm::getPublicKeyFromTpm(keyName.toUri());
- Info::addPublicKey(keyName, keyType, *pubKey);
-
- return keyName;
- }
+ KeyType keyType = KEY_TYPE_RSA, int keySize = 2048);
/**
* @brief Sign the data using a particular key.
@@ -626,16 +619,9 @@
* @param digestAlgorithm the digest algorithm.
* @throws Tpm::Error
*/
- void
+ inline void
signPacketWrapper(Data& data, const SignatureSha256WithRsa& signature,
- const Name& keyName, DigestAlgorithm digestAlgorithm)
- {
- data.setSignature(signature);
- data.setSignatureValue(Tpm::signInTpm(data.wireEncode().value(),
- data.wireEncode().value_size() -
- data.getSignature().getValue().size(),
- keyName, digestAlgorithm));
- }
+ const Name& keyName, DigestAlgorithm digestAlgorithm);
/**
* @brief Sign the interest using a particular key.
@@ -646,44 +632,260 @@
* @param digestAlgorithm the digest algorithm.
* @throws Tpm::Error
*/
- void
+ inline void
signPacketWrapper(Interest& interest, const SignatureSha256WithRsa& signature,
- const Name& keyName, DigestAlgorithm digestAlgorithm)
- {
- Name signedName = interest.getName();
- signedName.append(signature.getInfo());
+ const Name& keyName, DigestAlgorithm digestAlgorithm);
- Block sigValue = Tpm::signInTpm(signedName.wireEncode().value(),
+
+private:
+ SecPublicInfo* m_pib;
+ SecTpm* m_tpm;
+};
+
+template<class T>
+inline
+KeyChain::KeyChain(T)
+ : m_pib(new typename T::Pib)
+ , m_tpm(new typename T::Tpm)
+{
+}
+
+inline Name
+KeyChain::createIdentity(const Name& identityName)
+{
+ m_pib->addIdentity(identityName);
+
+ Name keyName;
+ try
+ {
+ keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
+ }
+ catch (SecPublicInfo::Error& e)
+ {
+ keyName = generateRsaKeyPairAsDefault(identityName, true);
+ }
+
+ Name certName;
+ try
+ {
+ certName = m_pib->getDefaultCertificateNameForKey(keyName);
+ }
+ catch (SecPublicInfo::Error& e)
+ {
+ shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
+ m_pib->addCertificateAsIdentityDefault(*selfCert);
+ certName = selfCert->getName();
+ }
+
+ return certName;
+}
+
+inline Name
+KeyChain::generateRsaKeyPair(const Name& identityName, bool isKsk, int keySize)
+{
+ return generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
+}
+
+inline Name
+KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
+{
+ Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
+
+ m_pib->setDefaultKeyNameForIdentity(keyName);
+
+ return keyName;
+}
+
+template<typename T>
+void
+KeyChain::sign(T& packet)
+{
+ if (!static_cast<bool>(m_pib->defaultCertificate()))
+ setDefaultCertificateInternal();
+
+ sign(packet, *m_pib->defaultCertificate());
+}
+
+template<typename T>
+void
+KeyChain::sign(T& packet, const Name& certificateName)
+{
+ if (!m_pib->doesCertificateExist(certificateName))
+ throw SecPublicInfo::Error("Requested certificate [" +
+ certificateName.toUri() + "] doesn't exist");
+
+ SignatureSha256WithRsa signature;
+ // implicit conversion should take care
+ signature.setKeyLocator(certificateName.getPrefix(-1));
+
+ // For temporary usage, we support RSA + SHA256 only, but will support more.
+ signPacketWrapper(packet, signature,
+ IdentityCertificate::certificateNameToPublicKeyName(certificateName),
+ DIGEST_ALGORITHM_SHA256);
+}
+
+template<typename T>
+void
+KeyChain::signByIdentity(T& packet, const Name& identityName)
+{
+ Name signingCertificateName;
+ try
+ {
+ signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
+ }
+ catch (SecPublicInfo::Error& e)
+ {
+ signingCertificateName = createIdentity(identityName);
+ // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
+ // is a fatal error.
+ }
+
+ // We either get or create the signing certificate, sign packet! (no exception unless fatal
+ // error in TPM)
+ sign(packet, signingCertificateName);
+}
+
+inline Signature
+KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
+{
+ Name signingCertificateName;
+ try
+ {
+ signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
+ }
+ catch (SecPublicInfo::Error& e)
+ {
+ signingCertificateName = createIdentity(identityName);
+ // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
+ // is a fatal error.
+ }
+
+ // We either get or create the signing certificate, sign data! (no exception unless fatal error
+ // in TPM)
+ return sign(buffer, bufferLength, signingCertificateName);
+}
+
+inline void
+KeyChain::signWithSha256(Data& data)
+{
+ SignatureSha256 sig;
+ data.setSignature(sig);
+
+ Block sigValue(Tlv::SignatureValue,
+ crypto::sha256(data.wireEncode().value(),
+ data.wireEncode().value_size() -
+ data.getSignature().getValue().size()));
+ data.setSignatureValue(sigValue);
+}
+
+inline void
+KeyChain::deleteCertificate(const Name& certificateName)
+{
+ try
+ {
+ if (m_pib->getDefaultCertificateName() == certificateName)
+ return;
+ }
+ catch (SecPublicInfo::Error& e)
+ {
+ // Not a real error, just try to delete the certificate
+ }
+
+ m_pib->deleteCertificateInfo(certificateName);
+}
+
+inline void
+KeyChain::deleteKey(const Name& keyName)
+{
+ try
+ {
+ if (m_pib->getDefaultKeyNameForIdentity(m_pib->getDefaultIdentity()) == keyName)
+ return;
+ }
+ catch (SecPublicInfo::Error& e)
+ {
+ // Not a real error, just try to delete the key
+ }
+
+ m_pib->deletePublicKeyInfo(keyName);
+ m_tpm->deleteKeyPairInTpm(keyName);
+}
+
+inline void
+KeyChain::deleteIdentity(const Name& identity)
+{
+ try
+ {
+ if (m_pib->getDefaultIdentity() == identity)
+ return;
+ }
+ catch (SecPublicInfo::Error& e)
+ {
+ // Not a real error, just try to delete the identity
+ }
+
+ std::vector<Name> nameList;
+ m_pib->getAllKeyNamesOfIdentity(identity, nameList, true);
+ m_pib->getAllKeyNamesOfIdentity(identity, nameList, false);
+
+ m_pib->deleteIdentityInfo(identity);
+
+ std::vector<Name>::const_iterator it = nameList.begin();
+ for(; it != nameList.end(); it++)
+ m_tpm->deleteKeyPairInTpm(*it);
+}
+
+template<typename T>
+void
+KeyChain::sign(T& packet, const IdentityCertificate& certificate)
+{
+ SignatureSha256WithRsa signature;
+ signature.setKeyLocator(certificate.getName().getPrefix(-1));
+
+ // For temporary usage, we support RSA + SHA256 only, but will support more.
+ signPacketWrapper(packet, signature, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+}
+
+inline Name
+KeyChain::generateKeyPair(const Name& identityName, bool isKsk, KeyType keyType, int keySize)
+{
+ Name keyName = m_pib->getNewKeyName(identityName, isKsk);
+
+ m_tpm->generateKeyPairInTpm(keyName.toUri(), keyType, keySize);
+
+ shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
+ m_pib->addPublicKey(keyName, keyType, *pubKey);
+
+ return keyName;
+}
+
+inline void
+KeyChain::signPacketWrapper(Data& data, const SignatureSha256WithRsa& signature,
+ const Name& keyName, DigestAlgorithm digestAlgorithm)
+{
+ data.setSignature(signature);
+ data.setSignatureValue(m_tpm->signInTpm(data.wireEncode().value(),
+ data.wireEncode().value_size() -
+ data.getSignature().getValue().size(),
+ keyName, digestAlgorithm));
+}
+
+inline void
+KeyChain::signPacketWrapper(Interest& interest, const SignatureSha256WithRsa& signature,
+ const Name& keyName, DigestAlgorithm digestAlgorithm)
+{
+ Name signedName = interest.getName();
+ signedName.append(signature.getInfo());
+
+ Block sigValue = m_tpm->signInTpm(signedName.wireEncode().value(),
signedName.wireEncode().value_size(),
keyName,
DIGEST_ALGORITHM_SHA256);
- sigValue.encode();
- signedName.append(sigValue);
- interest.setName(signedName);
- }
+ sigValue.encode();
+ signedName.append(sigValue);
+ interest.setName(signedName);
+}
-};
-
-} // namespace ndn
-
-
-
-#if defined(NDN_CXX_HAVE_OSX_SECURITY) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
-
-namespace ndn {
-
-typedef KeyChainImpl<SecPublicInfoSqlite3, SecTpmOsx> KeyChain;
-
-} // namespace ndn
-
-#else
-
-namespace ndn {
-
-typedef KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> KeyChain;
-
-} // namespace ndn
-
-#endif // NDN_CXX_HAVE_OSX_SECURITY
+}
#endif // NDN_SECURITY_KEY_CHAIN_HPP