Implementation of Control::unlockUserKey
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 5 Jun 2014 16:10:17 +0000 (18:10 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 12 Sep 2014 12:57:14 +0000 (14:57 +0200)
Change-Id: I18510e2c36b599f8bb7f486aad7b81bd9cd01647

src/CMakeLists.txt
src/manager/common/key-impl.cpp
src/manager/main/key-manager-main.cpp
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp
src/manager/service/file-system.cpp [moved from src/manager/service/FileSystem.cpp with 82% similarity]
src/manager/service/file-system.h [moved from src/manager/service/FileSystem.h with 94% similarity]
src/manager/service/key-provider.h

index 20fe78f..6985e81 100644 (file)
@@ -21,7 +21,7 @@ SET(KEY_MANAGER_SOURCES
     ${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(
index ca62f14..efdde04 100644 (file)
@@ -85,7 +85,7 @@ KeyImpl::KeyImpl(const RawBuffer &data, KeyType type, const std::string &passwor
         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);
index ad4e3e1..6facefb 100644 (file)
@@ -31,6 +31,8 @@
 #include <echo.h>
 #include <ckm-service.h>
 
+#include <key-provider.h>
+
 IMPLEMENT_SAFE_SINGLETON(CKM::Log::LogSystem);
 
 #define REGISTER_SOCKET_SERVICE(manager, service) \
@@ -73,14 +75,21 @@ int main(void) {
             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;
index 51a7cb1..5a4f82c 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <ckm/ckm-error.h>
 #include <ckm/ckm-type.h>
+#include <key-provider.h>
+#include <file-system.h>
 
 #include <ckm-logic.h>
 namespace CKM {
@@ -31,16 +33,35 @@ CKMLogic::CKMLogic(){}
 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));
@@ -48,7 +69,11 @@ RawBuffer CKMLogic::lockUserKey(uid_t user) {
 }
 
 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));
@@ -60,12 +85,18 @@ RawBuffer CKMLogic::changeUserPassword(
     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();
 }
 
@@ -73,11 +104,19 @@ RawBuffer CKMLogic::resetUserPassword(
     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();
 }
 
@@ -204,7 +243,5 @@ RawBuffer CKMLogic::createKeyPairECDSA(
     return response.Pop();
 }
 
-
-
 } // namespace CKM
 
index fcd0a76..d25bfc4 100644 (file)
 #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();
@@ -100,7 +105,7 @@ public:
         PolicySerializable policyPublicKey);
 
 private:
-
+    std::map<uid_t, UserData> m_userDataMap;
 };
 
 } // namespace CKM
index 2b99f36..6c82641 100644 (file)
@@ -94,6 +94,8 @@ bool CKMService::processOne(
         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.");
     }
similarity index 82%
rename from src/manager/service/FileSystem.cpp
rename to src/manager/service/file-system.cpp
index d1c1bee..1102f86 100644 (file)
  * @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 {
 
@@ -38,27 +37,21 @@ static const std::string CKM_DB_PREFIX = "db-";
 
 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;
@@ -69,7 +62,7 @@ RawBuffer FileSystem::getDomainKEK() const
 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));
similarity index 94%
rename from src/manager/service/FileSystem.h
rename to src/manager/service/file-system.h
index e53a5a5..b0045ba 100644 (file)
@@ -28,7 +28,7 @@ namespace CKM {
 
 class FileSystem {
 public:
-    FileSystem(int uid);
+    FileSystem(uid_t uid);
 
     std::string getDBPath() const;
     RawBuffer getDomainKEK() const;
@@ -36,8 +36,7 @@ public:
 
     virtual ~FileSystem(){}
 protected:
-    int m_uid;
-    std::string m_user;
+    uid_t m_uid;
 };
 
 }
index d76e47d..d5c6671 100644 (file)
@@ -9,14 +9,24 @@ namespace CKM {
 // 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
@@ -36,11 +46,14 @@ class KeyProvider {
     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
@@ -53,9 +66,9 @@ class KeyProvider {
 private:
        // [tak] modify variable name
        // m_dkek -> m_rawDKEK
-    KeyMaterialm_rawDKEK;
-
-       static int s_isInitialized;
+    KeyMaterial *m_rawDKEK;
+    bool m_isInitialized;
+       static bool s_isInitialized;
 };
 
 } // namespace CKM