/*! \brief indicating that a provided file or binary has not a valid format */
#define CKM_API_ERROR_INVALID_FORMAT -17
-/*! \brief indicating that provided file doesn't exists or cannot be accessed in the file system */
+/*! \brief deprecated please do not use it. This value was replaced with CKM_API_ERROR_FILE_SYSTEM */
#define CKM_API_ERROR_FILE_ACCESS_DENIED -18
/*! \brief indicating that keys are not exportable and could not be returned to client */
#define CKM_API_ERROR_NOT_EXPORTABLE -19
+/*! \brief indicating that files are corrupted or access to files was denied */
+#define CKM_API_ERROR_FILE_SYSTEM -20
+
#define CKM_API_OCSP_STATUS_GOOD (1<<0)
#define CKM_API_OCSP_STATUS_UNSUPPORTED (1<<1)
#define CKM_API_OCSP_STATUS_UNKNOWN (1<<2)
ERRORDESCRIBE(CKM_API_ERROR_INVALID_FORMAT);
ERRORDESCRIBE(CKM_API_ERROR_FILE_ACCESS_DENIED);
ERRORDESCRIBE(CKM_API_ERROR_NOT_EXPORTABLE);
+ ERRORDESCRIBE(CKM_API_ERROR_FILE_SYSTEM);
ERRORDESCRIBE(CKM_API_ERROR_UNKNOWN);
default:
return "Error not defined";
}
}
+#undef ERRORDESCRIBE
+
} // namespace CKM
auto wrappedDKEKMain = fs.getDKEK();
auto wrappedDKEKBackup = fs.getDKEKBackup();
- if (wrappedDKEKMain.empty() && wrappedDKEKBackup.empty()) {
+ if (wrappedDKEKMain.empty()) {
wrappedDKEKMain = KeyProvider::generateDomainKEK(std::to_string(user), password);
fs.saveDKEK(wrappedDKEKMain);
}
handle.keyProvider = KeyProvider(first, password);
handle.isMainDKEK = true;
} catch (const KeyProvider::Exception::Base &e) {
+ // Second buffer is empty. Lets rethrow first error
if (second.empty())
throw;
handle.keyProvider = KeyProvider(second, password);
FileSystem fs(user);
if (handle.isMainDKEK)
- fs.saveDKEKBackup(fs.getDKEK());
+ fs.createDKEKBackup();
fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
}
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;
try {
} catch (const CryptoLogic::Exception::Base &e) {
LogError("CryptoLogic error: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
+ } catch (const FileSystem::Exception::Base &e) {
+ LogError("FileSystem error: " << e.GetMessage());
+ retCode = CKM_API_ERROR_FILE_SYSTEM;
} catch (const CKM::Exception &e) {
LogError("CKM::Exception: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
} catch (const KeyProvider::Exception::Base &e) {
LogError("Error in KeyProvider " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
+ } catch (const FileSystem::Exception::Base &e) {
+ LogError("Error in FileSystem " << e.GetMessage());
+ retCode = CKM_API_ERROR_FILE_SYSTEM;
} catch (const CKM::Exception &e) {
LogError("CKM::Exception: " << e.GetMessage());
retCode = CKM_API_ERROR_SERVER_ERROR;
const Password &newPassword)
{
int retCode = CKM_API_SUCCESS;
- // TODO try-catch
- if (0 == m_userDataMap.count(user)) {
- retCode = CKM_API_ERROR_BAD_REQUEST;
- } else {
- saveDKEKFile(user, newPassword);
+
+ try {
+ if (0 == m_userDataMap.count(user)) {
+ retCode = CKM_API_ERROR_BAD_REQUEST;
+ } else {
+ saveDKEKFile(user, newPassword);
+ }
+ } catch (const FileSystem::Exception::Base &e) {
+ LogError("Error in FileSystem " << e.GetMessage());
+ retCode = CKM_API_ERROR_FILE_SYSTEM;
+ } catch (const CKM::Exception &e) {
+ LogError("CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
}
return MessageBuffer::Serialize(retCode).Pop();
} catch (const DBCrypto::Exception::TransactionError &e) {
LogError("DBCrypto transaction failed with message " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const FileSystem::Exception::Base &e) {
+ LogError("Error in FileSystem " << e.GetMessage());
+ retCode = CKM_API_ERROR_FILE_SYSTEM;
+ } catch (const CKM::Exception &e) {
+ LogError("CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
}
return MessageBuffer::Serialize(retCode).Pop();
} catch (const DBCrypto::Exception::TransactionError &e) {
LogError("DBCrypto transaction failed with message " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const FileSystem::Exception::Base &e) {
+ LogError("Error in FileSystem " << e.GetMessage());
+ retCode = CKM_API_ERROR_FILE_SYSTEM;
+ } catch (const CKM::Exception &e) {
+ LogError("CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
}
}
} catch (const DBCrypto::Exception::TransactionError &e) {
LogError("DBCrypto transaction failed with message " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const CKM::Exception &e) {
+ LogError("CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
}
}
} catch (const DBCrypto::Exception::Base &e) {
LogError("DBCrypto failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const CKM::Exception &e) {
+ LogError("CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
}
if (CKM_API_SUCCESS != retCode) {
} catch (const DBCrypto::Exception::Base &e) {
LogError("DBCrypto failed with message: " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const CKM::Exception &e) {
+ LogError("CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
}
auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
} catch (DBCrypto::Exception::InternalError &e) {
LogDebug("DBCrypto internal error: " << e.GetMessage());
retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const CKM::Exception &e) {
+ LogError("CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
}
return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
RawBuffer FileSystem::loadFile(const std::string &path) const {
std::ifstream is(path);
- if (is.fail())
+ if (is.fail() && ENOENT == errno)
return RawBuffer();
+ if (is.fail()) {
+ auto description = GetErrnoString(errno);
+ LogError("Error opening file: " << path << " Reason: " << description);
+ ThrowMsg(Exception::OpenFailed,
+ "Error opening file: " << path << " Reason: " << description);
+ }
+
std::istreambuf_iterator<char> begin(is),end;
std::vector<char> buff(begin,end); // This trick does not work with boost vector
return loadFile(getDBDEKPath());
}
-bool FileSystem::saveFile(const std::string &path, const RawBuffer &buffer) const {
+void FileSystem::saveFile(const std::string &path, const RawBuffer &buffer) const {
std::ofstream os(path, std::ios::out | std::ofstream::binary | std::ofstream::trunc);
std::copy(buffer.begin(), buffer.end(), std::ostreambuf_iterator<char>(os));
- if (os.fail())
- return false;
// Prevent desynchronization in batter remove test.
os.flush();
fsync(FstreamAccessors<std::ofstream>::GetFd(os)); // flush kernel space buffer
os.close();
- return !os.fail();
+
+ if (os.fail())
+ ThrowMsg(Exception::SaveFailed, "Failed to save file: " << path);
}
-bool FileSystem::saveDKEK(const RawBuffer &buffer) const {
- return saveFile(getDKEKPath(), buffer);
+void FileSystem::saveDKEK(const RawBuffer &buffer) const {
+ saveFile(getDKEKPath(), buffer);
}
-bool FileSystem::saveDKEKBackup(const RawBuffer &buffer) const {
- return saveFile(getDKEKBackupPath(), buffer);
+void FileSystem::moveFile(const std::string &from, const std::string &to) const {
+ if (0 == ::rename(from.c_str(), to.c_str())) {
+ return;
+ }
+ auto description = GetErrnoString(errno);
+ LogError("Error during rename file DKEKBackup to DKEK: " << description);
+ ThrowMsg(Exception::RenameFailed,
+ "Error during rename file DKEKBackup to DKEK: " << description);
}
-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;
+void FileSystem::restoreDKEK() const {
+ moveFile(getDKEKBackupPath(), getDKEKPath());
}
-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;
+void FileSystem::createDKEKBackup() const {
+ moveFile(getDKEKPath(), getDKEKBackupPath());
}
-bool FileSystem::saveDBDEK(const RawBuffer &buffer) const {
- return saveFile(getDBDEKPath(), buffer);
+void FileSystem::removeDKEKBackup() const {
+ if (0 == unlink(getDKEKBackupPath().c_str())) {
+ return;
+ }
+ // Backup is accessible only during "change password transaction"
+ auto description = GetErrnoString(errno);
+ LogDebug("Error in unlink file DKEKBackup: " << description);
+}
+
+void FileSystem::saveDBDEK(const RawBuffer &buffer) const {
+ saveFile(getDBDEKPath(), buffer);
}
-bool FileSystem::addRemovedApp(const std::string &smackLabel) const
+void FileSystem::addRemovedApp(const std::string &smackLabel) const
{
std::ofstream outfile;
outfile.open(getRemovedAppsPath(), std::ios_base::app);
outfile << smackLabel << std::endl;
outfile.close();
- return !outfile.fail();
+ if (outfile.fail()) {
+ auto desc = GetErrnoString(errno);
+ LogError("Could not update file: " << getRemovedAppsPath() << " Reason: " << desc);
+ ThrowMsg(Exception::SaveFailed,
+ "Could not update file: " << getRemovedAppsPath() << " Reason: " << desc);
+ }
}
AppLabelVector FileSystem::clearRemovedsApps() const
errno = 0;
if ((mkdir(CKM_DATA_PATH.c_str(), 0700)) && (errno != EEXIST)) {
int err = errno;
- LogError("Error in mkdir. Data directory could not be created. Errno: "
- << err << " (" << GetErrnoString(err) << ")");
+ LogError("Error in mkdir " << CKM_DATA_PATH << ". Reason: " << GetErrnoString(err));
return -1; // TODO set up some error code
}
return 0;
struct dirent* pDirEntry = NULL;
while ( (!readdir_r(dirp.get(), pEntry.get(), &pDirEntry)) && pDirEntry ) {
-
// Ignore files with diffrent prefix
if (strncmp(pDirEntry->d_name, CKM_KEY_PREFIX.c_str(), CKM_KEY_PREFIX.size())) {
continue;
if (unlink(getDKEKBackupPath().c_str())) {
retCode = -1;
err = errno;
- LogError("Error in unlink user backup DKEK: " << getDKEKBackupPath()
+ LogDebug("Unlink user backup DKEK failed (file probably does not exists): " << getDKEKBackupPath()
<< "Errno: " << errno << " " << GetErrnoString(err));
}
class FileSystem {
public:
+ class Exception {
+ public:
+ DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, OpenFailed)
+ DECLARE_EXCEPTION_TYPE(Base, SaveFailed)
+ DECLARE_EXCEPTION_TYPE(Base, RenameFailed)
+ };
+
FileSystem(uid_t uid);
std::string getDBPath() const;
// Domain Key Encryption Key
RawBuffer getDKEK() const;
RawBuffer getDKEKBackup() const;
- bool saveDKEK(const RawBuffer &buffer) const;
+ void 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
+ void createDKEKBackup() const;
+ void restoreDKEK() const; // delete DKEK and move DKEKBackup -> DKEK
+ void removeDKEKBackup() const; // delete DKEKBackup
// Database Data Encryption Key
RawBuffer getDBDEK() const;
- bool saveDBDEK(const RawBuffer &buffer) const;
+ void saveDBDEK(const RawBuffer &buffer) const;
// Remove all ckm data related to user
int removeUserData() const;
- bool addRemovedApp(const std::string &smackLabel) const;
+ void addRemovedApp(const std::string &smackLabel) const;
AppLabelVector clearRemovedsApps() const;
static int init();
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;
+ void saveFile(const std::string &path, const RawBuffer &buffer) const;
std::string getRemovedAppsPath() const;
+ void moveFile(const std::string &from, const std::string &to) const;
uid_t m_uid;
};