CKMLogic::~CKMLogic(){}
-RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) {
+void CKMLogic::loadDKEKFile(uid_t user, const Password &password, bool apiReq) {
+ auto &handle = m_userDataMap[user];
+
+ FileSystem fs(user);
+
+ auto wrappedDKEKMain = fs.getDKEK();
+ auto wrappedDKEKBackup = fs.getDKEKBackup();
+
+ if (wrappedDKEKMain.empty() && wrappedDKEKBackup.empty()) {
+ wrappedDKEKMain = KeyProvider::generateDomainKEK(std::to_string(user), password);
+ fs.saveDKEK(wrappedDKEKMain);
+ }
+
+ chooseDKEKFile(handle, password, wrappedDKEKMain, wrappedDKEKBackup);
+
+ if (!password.empty() || apiReq) {
+ handle.isDKEKConfirmed = true;
+
+ if (true == handle.isMainDKEK)
+ fs.removeDKEKBackup();
+ else
+ fs.restoreDKEK();
+ }
+}
+
+void CKMLogic::chooseDKEKFile(
+ UserData &handle,
+ const Password &password,
+ const RawBuffer &first,
+ const RawBuffer &second)
+{
+ try {
+ handle.keyProvider = KeyProvider(first, password);
+ handle.isMainDKEK = true;
+ } catch (const KeyProvider::Exception::Base &e) {
+ if (second.empty())
+ throw;
+ handle.keyProvider = KeyProvider(second, password);
+ handle.isMainDKEK = false;
+ }
+}
+
+void CKMLogic::saveDKEKFile(uid_t user, const Password &password) {
+ auto &handle = m_userDataMap[user];
+
+ FileSystem fs(user);
+ if (handle.isMainDKEK)
+ fs.saveDKEKBackup(fs.getDKEK());
+
+ fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
+
+ handle.isMainDKEK = true;
+ handle.isDKEKConfirmed = false;
+}
+
+RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password, bool apiRequest) {
// TODO try catch for all errors that should be supported by error code
int retCode = CKM_API_SUCCESS;
if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
auto &handle = m_userDataMap[user];
FileSystem fs(user);
- auto wrappedDomainKEK = fs.getDKEK();
- if (wrappedDomainKEK.empty()) {
- wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
- fs.saveDKEK(wrappedDomainKEK);
- }
-
- handle.keyProvider = KeyProvider(wrappedDomainKEK, password);
+ loadDKEKFile(user, password, apiRequest);
auto wrappedDatabaseDEK = fs.getDBDEK();
for(auto& appSmackLabel : removedApps) {
handle.database.deleteKey(appSmackLabel);
}
+ } else if (apiRequest == true && m_userDataMap[user].isDKEKConfirmed == false) {
+ // now we will try to choose the DKEK key and remove old one
+ loadDKEKFile(user, password, apiRequest);
}
} catch (const KeyProvider::Exception::PassWordError &e) {
LogError("Incorrect Password " << e.GetMessage());
{
int retCode = CKM_API_SUCCESS;
try {
- FileSystem fs(user);
- auto wrappedDomainKEK = fs.getDKEK();
- if (wrappedDomainKEK.empty()) {
- retCode = CKM_API_ERROR_BAD_REQUEST;
- } else {
- wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
- fs.saveDKEK(wrappedDomainKEK);
- }
+ loadDKEKFile(user, oldPassword, true);
+ saveDKEKFile(user, newPassword);
} catch (const KeyProvider::Exception::PassWordError &e) {
LogError("Incorrect Password " << e.GetMessage());
retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
if (0 == m_userDataMap.count(user)) {
retCode = CKM_API_ERROR_BAD_REQUEST;
} else {
- auto &handler = m_userDataMap[user];
- FileSystem fs(user);
- fs.saveDKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
+ saveDKEKFile(user, newPassword);
}
return MessageBuffer::Serialize(retCode).Pop();
* @brief Sample service implementation.
*/
#include <string.h>
+#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
const std::string CKM_DATA_PATH = "/opt/data/ckm/";
const std::string CKM_KEY_PREFIX = "key-";
+const std::string CKM_KEY_BACKUP_PREFIX = "key-backup-";
const std::string CKM_DB_KEY_PREFIX = "db-key-";
const std::string CKM_DB_PREFIX = "db-";
const std::string CKM_REMOVED_APP_PREFIX = "removed-app-";
return ss.str();
}
+std::string FileSystem::getDKEKBackupPath() const {
+ std::stringstream ss;
+ ss << CKM_DATA_PATH << CKM_KEY_BACKUP_PREFIX << m_uid;
+ return ss.str();
+}
+
std::string FileSystem::getDBDEKPath() const {
std::stringstream ss;
ss << CKM_DATA_PATH << CKM_DB_KEY_PREFIX << m_uid;
return loadFile(getDKEKPath());
}
+RawBuffer FileSystem::getDKEKBackup() const
+{
+ return loadFile(getDKEKBackupPath());
+}
+
RawBuffer FileSystem::getDBDEK() const
{
return loadFile(getDBDEKPath());
return saveFile(getDKEKPath(), buffer);
}
+bool FileSystem::saveDKEKBackup(const RawBuffer &buffer) const {
+ return saveFile(getDKEKBackupPath(), buffer);
+}
+
+bool FileSystem::restoreDKEK() const {
+ if (0 == ::rename(getDKEKBackupPath().c_str(), getDKEKPath().c_str()))
+ return true;
+ int err = errno;
+ LogError("Error in rename file DKEKBackup to DKEK: " << GetErrnoString(err));
+ return false;
+}
+
+bool FileSystem::removeDKEKBackup() const {
+ if (0 == unlink(getDKEKBackupPath().c_str()))
+ return true;
+ int err = errno;
+ LogError("Error in unlink file DKEKBackup: " << GetErrnoString(err));
+ return false;
+}
+
bool FileSystem::saveDBDEK(const RawBuffer &buffer) const {
return saveFile(getDBDEKPath(), buffer);
}
<< "Errno: " << errno << " " << GetErrnoString(err));
}
+ if (unlink(getDKEKBackupPath().c_str())) {
+ retCode = -1;
+ err = errno;
+ LogError("Error in unlink user backup DKEK: " << getDKEKBackupPath()
+ << "Errno: " << errno << " " << GetErrnoString(err));
+ }
+
if (unlink(getDBDEKPath().c_str())) {
retCode = -1;
err = errno;
// Domain Key Encryption Key
RawBuffer getDKEK() const;
+ RawBuffer getDKEKBackup() const;
bool saveDKEK(const RawBuffer &buffer) const;
+ // Functions required in "password change transaction"
+ bool saveDKEKBackup(const RawBuffer &buffer) const;
+ bool restoreDKEK() const; // delete DKEK and move DKEKBackup -> DKEK
+ bool removeDKEKBackup() const; // delete DKEKBackup
+
// Database Data Encryption Key
RawBuffer getDBDEK() const;
bool saveDBDEK(const RawBuffer &buffer) const;
virtual ~FileSystem(){}
protected:
std::string getDKEKPath() const;
+ std::string getDKEKBackupPath() const;
std::string getDBDEKPath() const;
RawBuffer loadFile(const std::string &path) const;
bool saveFile(const std::string &path, const RawBuffer &buffer) const;
uid_t m_uid;
};
-}
+} // namespace CKM