security: Add new v2::KeyChain
Change-Id: I5fdf51ecd96b50db2a7cbf730c6e8b1d9fbe09e9
Refs: #2926
diff --git a/src/security/tpm/back-end-file.cpp b/src/security/tpm/back-end-file.cpp
index f16d7cf..1adcf1c 100644
--- a/src/security/tpm/back-end-file.cpp
+++ b/src/security/tpm/back-end-file.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -83,6 +83,13 @@
BackEndFile::~BackEndFile() = default;
+const std::string&
+BackEndFile::getScheme()
+{
+ static std::string scheme = "tpm-file";
+ return scheme;
+}
+
bool
BackEndFile::doHasKey(const Name& keyName) const
{
diff --git a/src/security/tpm/back-end-file.hpp b/src/security/tpm/back-end-file.hpp
index 02b575f..db58907 100644
--- a/src/security/tpm/back-end-file.hpp
+++ b/src/security/tpm/back-end-file.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -52,11 +52,18 @@
};
public:
+ /**
+ * @brief Create file-based TPM backend
+ * @param location Directory to store private keys
+ */
explicit
BackEndFile(const std::string& location = "");
~BackEndFile() override;
+ static const std::string&
+ getScheme();
+
private: // inherited from tpm::BackEnd
/**
* @return True if a key with name @p keyName exists in TPM.
@@ -87,14 +94,14 @@
/**
* @brief Delete a key with name @p keyName.
*
- * @throws Error if the deletion fails.
+ * @throw Error the deletion failed
*/
void
doDeleteKey(const Name& keyName) final;
/**
* @return A private key with name @p keyName in encrypted PKCS #8 format using password @p pw
- * @throws Error if the key cannot be exported, e.g., not enough privilege
+ * @throw Error the key cannot be exported, e.g., not enough privilege
*/
ConstBufferPtr
doExportKey(const Name& keyName, const char* pw, size_t pwLen) final;
@@ -107,7 +114,7 @@
* @param size The size of the key in encrypted PKCS #8 format
* @param pw The password to decrypt the key
* @param pwLen The length of the password
- * @throws Error if import fails.
+ * @throw Error import failed
*/
void
doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen) final;
diff --git a/src/security/tpm/back-end-mem.cpp b/src/security/tpm/back-end-mem.cpp
index beac9db..9d051c6 100644
--- a/src/security/tpm/back-end-mem.cpp
+++ b/src/security/tpm/back-end-mem.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -37,13 +37,20 @@
std::unordered_map<Name, shared_ptr<PrivateKey>> keys;
};
-BackEndMem::BackEndMem()
+BackEndMem::BackEndMem(const std::string&)
: m_impl(new Impl)
{
}
BackEndMem::~BackEndMem() = default;
+const std::string&
+BackEndMem::getScheme()
+{
+ static std::string scheme = "tpm-memory";
+ return scheme;
+}
+
bool
BackEndMem::doHasKey(const Name& keyName) const
{
diff --git a/src/security/tpm/back-end-mem.hpp b/src/security/tpm/back-end-mem.hpp
index 4253b5e..4bfa212 100644
--- a/src/security/tpm/back-end-mem.hpp
+++ b/src/security/tpm/back-end-mem.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -45,11 +45,18 @@
};
public:
+ /**
+ * @brief Create memory-based TPM backend
+ * @param location Not used (required by the TPM-registration interface)
+ */
explicit
- BackEndMem();
+ BackEndMem(const std::string& location = "");
~BackEndMem() override;
+ static const std::string&
+ getScheme();
+
private: // inherited from tpm::BackEnd
/**
@@ -80,14 +87,14 @@
/**
* @brief Delete a key with name @p keyName.
*
- * @throws Error if the deletion fails.
+ * @throw Error the deletion failed
*/
void
doDeleteKey(const Name& keyName) final;
/**
* @return A private key with name @p keyName in encrypted PKCS #8 format using password @p pw
- * @throws Error if the key cannot be exported, e.g., not enough privilege
+ * @throw Error the key cannot be exported, e.g., not enough privilege
*/
ConstBufferPtr
doExportKey(const Name& keyName, const char* pw, size_t pwLen) final;
@@ -100,7 +107,7 @@
* @param size The size of the key in encrypted PKCS #8 format
* @param pw The password to decrypt the key
* @param pwLen The length of password
- * @throws Error if import fails.
+ * @throw Error import failed
*/
void
doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen) final;
diff --git a/src/security/tpm/back-end-osx.cpp b/src/security/tpm/back-end-osx.cpp
index d423b10..178ae55 100644
--- a/src/security/tpm/back-end-osx.cpp
+++ b/src/security/tpm/back-end-osx.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -117,7 +117,7 @@
}
}
-BackEndOsx::BackEndOsx()
+BackEndOsx::BackEndOsx(const std::string&)
: m_impl(new Impl)
{
SecKeychainSetUserInteractionAllowed(!m_impl->isTerminalMode);
@@ -131,11 +131,11 @@
BackEndOsx::~BackEndOsx() = default;
-void
-BackEndOsx::setTerminalMode(bool isTerminal)
+const std::string&
+BackEndOsx::getScheme()
{
- m_impl->isTerminalMode = isTerminal;
- SecKeychainSetUserInteractionAllowed(!isTerminal);
+ static std::string scheme = "tpm-osxkeychain";
+ return scheme;
}
bool
@@ -144,8 +144,15 @@
return m_impl->isTerminalMode;
}
+void
+BackEndOsx::setTerminalMode(bool isTerminal) const
+{
+ m_impl->isTerminalMode = isTerminal;
+ SecKeychainSetUserInteractionAllowed(!isTerminal);
+}
+
bool
-BackEndOsx::isLocked() const
+BackEndOsx::isTpmLocked() const
{
SecKeychainStatus keychainStatus;
@@ -157,22 +164,22 @@
}
bool
-BackEndOsx::unlockTpm(const char* password, size_t passwordLength)
+BackEndOsx::unlockTpm(const char* pw, size_t pwLen) const
{
// If the default key chain is already unlocked, return immediately.
- if (!isLocked())
+ if (!isTpmLocked())
return true;
if (m_impl->isTerminalMode) {
// Use the supplied password.
- SecKeychainUnlock(m_impl->keyChainRef, passwordLength, password, true);
+ SecKeychainUnlock(m_impl->keyChainRef, pwLen, pw, true);
}
else {
// If inTerminal is not set, get the password from GUI.
SecKeychainUnlock(m_impl->keyChainRef, 0, nullptr, false);
}
- return !isLocked();
+ return !isTpmLocked();
}
ConstBufferPtr
diff --git a/src/security/tpm/back-end-osx.hpp b/src/security/tpm/back-end-osx.hpp
index 0fcd49f..29465c8 100644
--- a/src/security/tpm/back-end-osx.hpp
+++ b/src/security/tpm/back-end-osx.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -34,7 +34,7 @@
namespace tpm {
/**
- * @brief The back-end implementation of TPM based on OS X KeyChain service.
+ * @brief The back-end implementation of TPM based on macOS Keychain Services.
*/
class BackEndOsx : public BackEnd
{
@@ -50,39 +50,30 @@
};
public:
- BackEndOsx();
+ /**
+ * @brief Create TPM backed based on macOS KeyChain service
+ * @param location Not used (required by the TPM-registration interface)
+ */
+ explicit
+ BackEndOsx(const std::string& location = "");
~BackEndOsx() override;
+ static const std::string&
+ getScheme();
+
public: // management
- /**
- * @brief Set the terminal mode of TPM.
- *
- * In terminal mode, TPM will not ask user permission from GUI.
- */
+ bool
+ isTerminalMode() const final;
+
void
- setTerminalMode(bool isTerminal);
+ setTerminalMode(bool isTerminal) const final;
- /**
- * @brief Check if TPM is in terminal mode
- */
bool
- isTerminalMode() const;
+ isTpmLocked() const final;
- /**
- * @return True if TPM is locked, otherwise false
- */
bool
- isLocked() const;
-
- /**
- * @brief Unlock TPM
- *
- * @param password The password to unlock TPM
- * @param passwordLength The password size.
- */
- bool
- unlockTpm(const char* password = nullptr, size_t passwordLength = 0);
+ unlockTpm(const char* pw, size_t pwLen) const final;
public: // crypto transformation
/**
@@ -125,14 +116,14 @@
/**
* @brief Delete a key with name @p keyName.
*
- * @throws Error if the deletion fails.
+ * @throw Error the deletion failed
*/
void
doDeleteKey(const Name& keyName) final;
/**
* @return A private key with name @p keyName in encrypted PKCS #8 format using password @p pw
- * @throws Error if the key cannot be exported, e.g., not enough privilege
+ * @throw Error the key cannot be exported, e.g., not enough privilege
*/
ConstBufferPtr
doExportKey(const Name& keyName, const char* pw, size_t pwLen) final;
@@ -145,7 +136,7 @@
* @param size The size of the key in encrypted PKCS #8 format
* @param pw The password to decrypt the private key
* @param pwLen The length of the password
- * @throws Error if import fails
+ * @throw Error import fails
*/
void
doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen) final;
diff --git a/src/security/tpm/back-end.cpp b/src/security/tpm/back-end.cpp
index 18df659..72ef5fd 100644
--- a/src/security/tpm/back-end.cpp
+++ b/src/security/tpm/back-end.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -66,7 +66,7 @@
name::Component keyId;
do {
keyId = name::Component::fromNumber(random::generateSecureWord64());
- keyName = v2::constructKeyName(identity, params.getKeyId());
+ keyName = v2::constructKeyName(identity, keyId);
} while (hasKey(keyName));
const_cast<KeyParams&>(params).setKeyId(keyId);
@@ -133,6 +133,29 @@
keyHandle.setKeyName(v2::constructKeyName(identity, keyId));
}
+bool
+BackEnd::isTerminalMode() const
+{
+ return true;
+}
+
+void
+BackEnd::setTerminalMode(bool isTerminal) const
+{
+}
+
+bool
+BackEnd::isTpmLocked() const
+{
+ return false;
+}
+
+bool
+BackEnd::unlockTpm(const char* pw, size_t pwLen) const
+{
+ return !isTpmLocked();
+}
+
} // namespace tpm
} // namespace security
} // namespace ndn
diff --git a/src/security/tpm/back-end.hpp b/src/security/tpm/back-end.hpp
index 749b53d..4c55ab2 100644
--- a/src/security/tpm/back-end.hpp
+++ b/src/security/tpm/back-end.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -77,8 +77,8 @@
* The key name is set in the returned KeyHandle.
*
* @return The handle of the created key.
- * @throws Tpm::Error if @p params is invalid
- * @throws Error if the key cannot be created.
+ * @throw Tpm::Error @p params are invalid
+ * @throw Error the key cannot be created
*/
unique_ptr<KeyHandle>
createKey(const Name& identity, const KeyParams& params);
@@ -88,15 +88,15 @@
*
* Continuing to use existing KeyHandles on a deleted key results in undefined behavior.
*
- * @throws Error if the deletion fails.
+ * @throw Error if the deletion fails.
*/
void
deleteKey(const Name& keyName);
/**
* @return A private key with name @p keyName in encrypted PKCS #8 format using password @p pw
- * @throws Error if the key does not exist
- * @throws Error if the key cannot be exported, e.g., insufficient privilege
+ * @throw Error the key does not exist
+ * @throw Error the key cannot be exported, e.g., insufficient privilege
*/
ConstBufferPtr
exportKey(const Name& keyName, const char* pw, size_t pwLen);
@@ -109,11 +109,48 @@
* @param pkcs8Len The size of the key in encrypted PKCS #8 format
* @param pw The password to decrypt the private key
* @param pwLen The length of the password
- * @throws Error if import fails.
+ * @throw Error import failed
*/
void
importKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len, const char* pw, size_t pwLen);
+ /**
+ * @brief Check if TPM is in terminal mode
+ *
+ * Default implementation always returns true.
+ */
+ virtual bool
+ isTerminalMode() const;
+
+ /**
+ * @brief Set the terminal mode of TPM.
+ *
+ * In terminal mode, TPM will not ask user permission from GUI.
+ *
+ * Default implementation does nothing.
+ */
+ virtual void
+ setTerminalMode(bool isTerminal) const;
+
+ /**
+ * @return True if TPM is locked, otherwise false
+ *
+ * Default implementation always returns false.
+ */
+ virtual bool
+ isTpmLocked() const;
+
+ /**
+ * @brief Unlock TPM
+ *
+ * @param pw The password to unlock TPM
+ * @param pwLen The password size.
+ *
+ * Default implementation always returns !isTpmLocked()
+ */
+ virtual bool
+ unlockTpm(const char* pw, size_t pwLen) const;
+
protected: // static helper method
/**
* @brief Set the key name in @p keyHandle according to @p identity and @p params
@@ -141,7 +178,7 @@
* The key name is set in the returned KeyHandle.
*
* @return The handle of the created key.
- * @throws Error when key cannot be created.
+ * @throw Error key cannot be created
*/
virtual unique_ptr<KeyHandle>
doCreateKey(const Name& identity, const KeyParams& params) = 0;
@@ -149,14 +186,14 @@
/**
* @brief Delete a key with name @p keyName.
*
- * @throws Error if the deletion fails.
+ * @throw Error the deletion failed
*/
virtual void
doDeleteKey(const Name& keyName) = 0;
/**
* @return A private key with name @p keyName in encrypted PKCS #8 format using password @p pw
- * @throws Error if the key cannot be exported, e.g., insufficient privilege
+ * @throw Error the key cannot be exported, e.g., insufficient privilege
*/
virtual ConstBufferPtr
doExportKey(const Name& keyName, const char* pw, size_t pwLen) = 0;
@@ -169,7 +206,7 @@
* @param pkcs8Len The size of the key in PKCS #8 format
* @param pw The password to decrypt the private key
* @param pwLen The length of the password
- * @throws Error if import fails.
+ * @throw Error import failed
*/
virtual void
doImportKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len, const char* pw, size_t pwLen) = 0;
diff --git a/src/security/tpm/tpm.cpp b/src/security/tpm/tpm.cpp
index 234c48d..fad73b9 100644
--- a/src/security/tpm/tpm.cpp
+++ b/src/security/tpm/tpm.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -108,6 +108,30 @@
return key->decrypt(buf, size);
}
+bool
+Tpm::isTerminalMode() const
+{
+ return m_backEnd->isTerminalMode();
+}
+
+void
+Tpm::setTerminalMode(bool isTerminal) const
+{
+ m_backEnd->setTerminalMode(isTerminal);
+}
+
+bool
+Tpm::isTpmLocked() const
+{
+ return m_backEnd->isTpmLocked();
+}
+
+bool
+Tpm::unlockTpm(const char* password, size_t passwordLength) const
+{
+ return m_backEnd->unlockTpm(password, passwordLength);
+}
+
ConstBufferPtr
Tpm::exportPrivateKey(const Name& keyName, const char* pw, size_t pwLen)
{
diff --git a/src/security/tpm/tpm.hpp b/src/security/tpm/tpm.hpp
index 01b22ae..5c985f1 100644
--- a/src/security/tpm/tpm.hpp
+++ b/src/security/tpm/tpm.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -31,6 +31,11 @@
namespace ndn {
namespace security {
+
+namespace v2 {
+class KeyChain;
+} // namespace v2
+
namespace tpm {
class BackEnd;
@@ -48,14 +53,17 @@
* A TPM consists of a unified front-end interface and a back-end implementation. The front-end
* cache the handles of private keys which is provided by the back-end implementation.
*
- * @throw tpm::BackEnd::Error when underlying implementation has non-semantic error.
- * @throw Tpm::Error when there is an semantic error.
+ * @note Tpm instance is created and managed only by v2::KeyChain. v2::KeyChain::getTpm()
+ * returns a const reference to the managed Tpm instance, through which it is possible to
+ * check existence of private keys, get public keys for the private keys, sign, and decrypt
+ * the supplied buffers using managed private keys.
+ *
+ * @throw BackEnd::Error Failure with the underlying implementation having non-semantic errors
+ * @throw Tpm::Error Failure with semantic error in the underlying implementation
*/
class Tpm : noncopyable
{
public:
- friend class KeyChain;
-
class Error : public std::runtime_error
{
public:
@@ -106,6 +114,36 @@
ConstBufferPtr
decrypt(const uint8_t* buf, size_t size, const Name& keyName) const;
+public: // Management
+ /**
+ * @brief Check if TPM is in terminal mode
+ */
+ bool
+ isTerminalMode() const;
+
+ /**
+ * @brief Set the terminal mode of TPM.
+ *
+ * In terminal mode, TPM will not ask user permission from GUI.
+ */
+ void
+ setTerminalMode(bool isTerminal) const;
+
+ /**
+ * @return True if TPM is locked, otherwise false
+ */
+ bool
+ isTpmLocked() const;
+
+ /**
+ * @brief Unlock TPM
+ *
+ * @param password The password to unlock TPM
+ * @param passwordLength The password size.
+ */
+ bool
+ unlockTpm(const char* password, size_t passwordLength) const;
+
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/*
* @brief Create a new TPM instance with the specified @p location
@@ -128,7 +166,7 @@
* The created key is named as: /<identityName>/[keyId]/KEY
*
* @return the key name
- * @throws Tpm::Error if the key has already existed or the params is invalid
+ * @throw Tpm::Error the key has already existed or the params is invalid
*/
Name
createKey(const Name& identityName, const KeyParams& params);
@@ -179,7 +217,6 @@
}
private:
-
/**
* @brief Internal KeyHandle lookup
*
@@ -195,6 +232,8 @@
mutable std::unordered_map<Name, unique_ptr<KeyHandle>> m_keys;
unique_ptr<BackEnd> m_backEnd;
+
+ friend class v2::KeyChain;
};
} // namespace tpm