${KEY_MANAGER_PATH}/service/ocsp.cpp
${KEY_MANAGER_PATH}/service/DBCryptoModule.cpp
${KEY_MANAGER_PATH}/service/CryptoService.cpp
- ${KEY_MANAGER_PATH}/service/FileSystem.cpp
+ ${KEY_MANAGER_PATH}/service/file-system.cpp
)
SET_SOURCE_FILES_PROPERTIES(
BIO_write(bio.get(), data.data(), data.size());
rsa = PEM_read_bio_RSAPrivateKey(bio.get(), NULL, NULL, pass);
} else if (type == KeyType::KEY_RSA_PUBLIC) {
- const unsigned char *p = (const unsigned char*)data.data();
+ const unsigned char *p = static_cast<const unsigned char*>(data.data());
rsa = d2i_RSA_PUBKEY(NULL, &p, data.size());
} else if (type == KeyType::KEY_RSA_PRIVATE) {
BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
#include <echo.h>
#include <ckm-service.h>
+#include <key-provider.h>
+
IMPLEMENT_SAFE_SINGLETON(CKM::Log::LogSystem);
#define REGISTER_SOCKET_SERVICE(manager, service) \
LogError("Error in pthread_sigmask");
return 1;
}
+ LogInfo("Init external liblaries SKMM and openssl");
+ CKM::KeyProvider::initializeLibrary();
+ // TODO initialize openssl here
+ {
+ LogInfo("Start!");
+ CKM::SocketManager manager;
- LogInfo("Start!");
- CKM::SocketManager manager;
-
- REGISTER_SOCKET_SERVICE(manager, CKM::EchoService);
- REGISTER_SOCKET_SERVICE(manager, CKM::CKMService);
+ REGISTER_SOCKET_SERVICE(manager, CKM::EchoService);
+ REGISTER_SOCKET_SERVICE(manager, CKM::CKMService);
- manager.MainLoop();
+ manager.MainLoop();
+ }
+ // Manager has been destroyed and we may close external libraries.
+ LogInfo("Deinit SKMM and openssl");
+ CKM::KeyProvider::closeLibrary();
}
UNHANDLED_EXCEPTION_HANDLER_END
return 0;
#include <ckm/ckm-error.h>
#include <ckm/ckm-type.h>
+#include <key-provider.h>
+#include <file-system.h>
#include <ckm-logic.h>
namespace CKM {
CKMLogic::~CKMLogic(){}
RawBuffer CKMLogic::unlockUserKey(uid_t user, const std::string &password) {
- (void)user;
- (void)password;
+ // TODO try catch for all errors that should be supported by error code
+ int retCode = KEY_MANAGER_API_SUCCESS;
+
+ UserData &handle = m_userDataMap[user];
+
+ if (!(handle.keyProvider.isInitialized())) {
+ auto &handle = m_userDataMap[user];
+
+ FileSystem fs(user);
+ auto wrappedDomainKEK = fs.getDomainKEK();
+
+ if (wrappedDomainKEK.empty()) {
+ wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
+ fs.saveDomainKEK(wrappedDomainKEK);
+ }
+
+ handle.keyProvider = KeyProvider(wrappedDomainKEK, password);
+
+ // TODO Now create database!
+ }
MessageBuffer response;
- Serialization::Serialize(response, static_cast<int>(KEY_MANAGER_API_SUCCESS));
+ Serialization::Serialize(response, retCode);
return response.Pop();
}
RawBuffer CKMLogic::lockUserKey(uid_t user) {
- (void)user;
+ // TODO try catch for all errors that should be supported by error code
+ m_userDataMap.erase(user);
MessageBuffer response;
Serialization::Serialize(response, static_cast<int>(KEY_MANAGER_API_SUCCESS));
}
RawBuffer CKMLogic::removeUserData(uid_t user) {
- (void)user;
+ // TODO try catch for all errors that should be supported by error code
+ m_userDataMap.erase(user);
+
+ FileSystem fs(user);
+// fs.removeUserData(); // remove DB also
MessageBuffer response;
Serialization::Serialize(response, static_cast<int>(KEY_MANAGER_API_SUCCESS));
const std::string &oldPassword,
const std::string &newPassword)
{
- (void)user;
- (void)oldPassword;
- (void)newPassword;
-
+ int retCode = KEY_MANAGER_API_SUCCESS;
+ // TODO try-catch
+ FileSystem fs(user);
+ auto wrappedDomainKEK = fs.getDomainKEK();
+ if (wrappedDomainKEK.empty()) {
+ retCode = KEY_MANAGER_API_ERROR_BAD_REQUEST;
+ } else {
+ wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
+ fs.saveDomainKEK(wrappedDomainKEK);
+ }
MessageBuffer response;
- Serialization::Serialize(response, static_cast<int>(KEY_MANAGER_API_SUCCESS));
+ Serialization::Serialize(response, retCode);
return response.Pop();
}
uid_t user,
const std::string &newPassword)
{
- (void)user;
- (void)newPassword;
+ int retCode = KEY_MANAGER_API_SUCCESS;
+ // TODO try-catch
+ if (m_userDataMap.count(user) <= 0) {
+ retCode = KEY_MANAGER_API_ERROR_BAD_REQUEST;
+ } else {
+ auto &handler = m_userDataMap[user];
+ auto wrappedDomainKEK = handler.keyProvider.getDomainKEK(newPassword);
+ FileSystem fs(user);
+ fs.saveDomainKEK(wrappedDomainKEK);
+ }
MessageBuffer response;
- Serialization::Serialize(response, static_cast<int>(KEY_MANAGER_API_SUCCESS));
+ Serialization::Serialize(response, retCode);
return response.Pop();
}
return response.Pop();
}
-
-
} // namespace CKM
#include <protocols.h>
#include <ckm/ckm-type.h>
#include <connection-info.h>
+#include <key-provider.h>
namespace CKM {
+struct UserData {
+ KeyProvider keyProvider;
+};
+
class CKMLogic {
public:
CKMLogic();
PolicySerializable policyPublicKey);
private:
-
+ std::map<uid_t, UserData> m_userDataMap;
};
} // namespace CKM
return true;
} Catch (MessageBuffer::Exception::Base) {
LogError("Broken protocol. Closing socket.");
+ } catch (const std::string &e) {
+ LogError("String exception(" << e << "). Closing socket");
} catch (...) {
LogError("Unknown exception. Closing socket.");
}
* @brief Sample service implementation.
*/
#include <sys/types.h>
-#include <pwd.h>
#include <string>
#include <sstream>
#include <fstream>
-#include <FileSystem.h>
+#include <file-system.h>
namespace {
namespace CKM {
-FileSystem::FileSystem(int uid)
+FileSystem::FileSystem(uid_t uid)
: m_uid(uid)
-{
- passwd *pass = getpwuid(uid);
- if (pass->pw_name)
- m_user = pass->pw_name;
- else
- m_user = std::to_string(uid);
-}
+{}
std::string FileSystem::getDBPath() const
{
std::stringstream ss;
- ss << CKM_DATA_PATH << CKM_DB_PREFIX << m_user;
+ ss << CKM_DATA_PATH << CKM_DB_PREFIX << m_uid;
return ss.str();
}
RawBuffer FileSystem::getDomainKEK() const
{
std::stringstream ss;
- ss << CKM_DATA_PATH << CKM_KEY_PREFIX << m_user;
+ ss << CKM_DATA_PATH << CKM_KEY_PREFIX << m_uid;
std::ifstream is(ss.str());
std::istreambuf_iterator<char> begin(is),end;
bool FileSystem::saveDomainKEK(const RawBuffer &buffer) const
{
std::stringstream ss;
- ss << CKM_DATA_PATH << CKM_KEY_PREFIX << m_user;
+ ss << CKM_DATA_PATH << CKM_KEY_PREFIX << m_uid;
std::ofstream os(ss.str(), std::ios::out | std::ofstream::binary);
std::copy(buffer.begin(), buffer.end(), std::ostreambuf_iterator<char>(os));
class FileSystem {
public:
- FileSystem(int uid);
+ FileSystem(uid_t uid);
std::string getDBPath() const;
RawBuffer getDomainKEK() const;
virtual ~FileSystem(){}
protected:
- int m_uid;
- std::string m_user;
+ uid_t m_uid;
};
}
// This is internal api so all functions should throw exception on errors.
class KeyProvider {
+public:
+ // To store in std containers
+ KeyProvider();
// In constructor you must check if SKMM is initialized. On error -> exception
// keyInWrapForm should be used like this:
// if (keyInWrapForm.size() != sizeof(WrappedKeyMaterial))
// throw exception; // buffer does not have proper size to store WrappedKeyMaterial
// WrappedKeyMaterial *wkm = static_cast<WrappedKeyMaterial>(keyInWrapForm.data());
- KeyProvider(const RawBuffer &domainKEKInWrapForm, const RawBuffer &password);
+ KeyProvider(const RawBuffer &domainKEKInWrapForm, const std::string &password);
- // Returns Key used to decrypt database.
+ KeyProvider(KeyProvider &&);
+ KeyProvider(const KeyProvider &) = delete;
+ KeyProvider& operator=(const KeyProvider &) = delete;
+ KeyProvider& operator=(KeyProvider &&);
+
+ bool isInitialized();
+
+ // Returns Key used to decrypt database.
KeyAES getDomainKEK();
// Returns Key in form used to store key in file
RawBuffer generateDEK(const std::string &smackLabel);
// used by change user password. On error -> exception
- static RawBuffer reencrypt(const RawBuffer &domainKEKInWrapForm, const RawBuffer &oldPass, const RawBuffer &newPass);
+ static RawBuffer reencrypt(
+ const RawBuffer &domainKEKInWrapForm,
+ const std::string &oldPass,
+ const std::string &newPass);
// First run of application for some user. DomainKEK was not created yet. We must create one.
// This key will be used to encrypt user database.
- static RawBuffer generateDomainKEK(const std::string &user, const RawBuffer &userPassword);
+ static RawBuffer generateDomainKEK(const std::string &user, const std::string &userPassword);
// This will be called by framework at the begin of the program
// [tak] need to declare return type
private:
// [tak] modify variable name
// m_dkek -> m_rawDKEK
- KeyMaterial* m_rawDKEK;
-
- static int s_isInitialized;
+ KeyMaterial *m_rawDKEK;
+ bool m_isInitialized;
+ static bool s_isInitialized;
};
} // namespace CKM