Implement key retrieval in encryption service 01/41801/9
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 17 Jun 2015 12:19:50 +0000 (14:19 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 26 Jun 2015 11:42:53 +0000 (04:42 -0700)
[Feature] Encryption/decryption service implementation
[Solution] Encryption service sends a key request, CKM service retrieves the
key and returns it to Encryption service.

[Verification] Run ckm-tests --group=CKM_ENCRYPTION_DECRYPTION and observe
journalctl -f. TED_0010_encrypt_invalid_param_list should print:
"Attempt to retrieve key failed with error: -15" (5 times)
other failing tests should print:
"Encryption/decryption not yet supported"

Change-Id: I56dc8a08ba211e996295f962da12193027c1a78c

src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp
src/manager/service/ckm-service.h
src/manager/service/encryption-logic.cpp
src/manager/service/encryption-logic.h
src/manager/service/encryption-service.cpp
src/manager/service/encryption-service.h
src/manager/service/iencryption-service.h

index 7ec4213..35e9613 100644 (file)
@@ -503,6 +503,34 @@ int CKMLogic::verifyAndSaveDataHelper(
     return retCode;
 }
 
+int CKMLogic::getKeyForService(
+        const Credentials &cred,
+        const Name &name,
+        const Label &label,
+        const Password &pass,
+        Crypto::GKeyShPtr &key)
+{
+    DB::Row row;
+    try {
+        // Key is for internal service use. It won't be exported to the client
+        int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, label, pass, row);
+        if (retCode == CKM_API_SUCCESS)
+            key = m_decider.getStore(row).getKey(row);
+        return retCode;
+    } catch (const KeyProvider::Exception::Base &e) {
+        LogError("KeyProvider failed with error: " << e.GetMessage());
+        return CKM_API_ERROR_SERVER_ERROR;
+    } catch (const DB::Crypto::Exception::Base &e) {
+        LogError("DB::Crypto failed with message: " << e.GetMessage());
+        return CKM_API_ERROR_DB_ERROR;
+    } catch (const Exc::Exception &e) {
+        return e.error();
+    } catch (const CKM::Exception &e) {
+        LogError("CKM::Exception: " << e.GetMessage());
+        return CKM_API_ERROR_SERVER_ERROR;
+    }
+}
+
 RawBuffer CKMLogic::saveData(
     const Credentials &cred,
     int commandId,
index afc90be..b6dc1eb 100644 (file)
@@ -35,6 +35,7 @@
 #include <access-control.h>
 #include <certificate-impl.h>
 #include <sys/types.h>
+#include <generic-backend/gkey.h>
 
 #include <platform/decider.h>
 
@@ -201,6 +202,12 @@ public:
         DataType dataType,
         const PolicySerializable &policy);
 
+    int getKeyForService(const Credentials &cred,
+                         const Name &name,
+                         const Label &label,
+                         const Password& pass,
+                         Crypto::GKeyShPtr& key);
+
 private:
 
     // select private/system database depending on asking uid and owner label.
index 644e1c4..0631ddd 100644 (file)
@@ -59,6 +59,12 @@ GenericSocketService::ServiceDescriptionVector CKMService::GetServiceDescription
     };
 }
 
+void CKMService::SetCommManager(CommMgr *manager)
+{
+    ThreadService::SetCommManager(manager);
+    Register(*manager);
+}
+
 bool CKMService::ProcessOne(
     const ConnectionID &conn,
     ConnectionInfo &info)
@@ -378,5 +384,22 @@ RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
     }
 }
 
+void CKMService::ProcessMessage(MsgKeyRequest msg)
+{
+    Crypto::GKeyShPtr key;
+    int ret = m_logic->getKeyForService(msg.cred,
+                                        msg.name,
+                                        msg.label,
+                                        msg.password,
+                                        key);
+    MsgKeyResponse kResp(msg.id, key, ret);
+    try {
+        if (!m_commMgr->SendMessage(kResp))
+            LogError("No listener found"); // can't do much more
+    } catch (...) {
+        LogError("Uncaught exception in SendMessage. Check listeners.");
+    }
+}
+
 } // namespace CKM
 
index b8b6c55..5bc7230 100644 (file)
@@ -21,7 +21,8 @@
  */
 #pragma once
 
-#include <thread-service.h>
+#include <mutex>
+#include <message-service.h>
 #include <message-buffer.h>
 #include <dpl/exception.h>
 
@@ -29,7 +30,7 @@ namespace CKM {
 
 class CKMLogic;
 
-class CKMService : public CKM::ThreadService
+class CKMService : public ThreadMessageService<MsgKeyRequest>
 {
 public:
     CKMService();
@@ -46,6 +47,8 @@ public:
     ServiceDescriptionVector GetServiceDescription();
 
 private:
+    virtual void SetCommManager(CommMgr *manager);
+
     class Exception {
     public:
         DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
@@ -63,6 +66,8 @@ private:
         Credentials &cred,
         MessageBuffer &buffer);
 
+    virtual void ProcessMessage(MsgKeyRequest msg);
+
     CKMLogic *m_logic;
 };
 
index 5baac5b..2fd733c 100644 (file)
@@ -44,7 +44,7 @@ void EncryptionLogic::Crypt(const CryptoRequest& request)
 
     // request key
     try {
-        m_service.RequestKey(request.cred, request.name, request.label);
+        m_service.RequestKey(request);
     } catch (...) {
         LogError("Key request failed");
         m_requests.erase(request.msgId);
@@ -52,4 +52,31 @@ void EncryptionLogic::Crypt(const CryptoRequest& request)
     }
 }
 
+void EncryptionLogic::KeyRetrieved(MsgKeyResponse response)
+{
+    auto it = m_requests.find(response.id);
+    if (it == m_requests.end()) {
+        LogError("No matching request found"); // nothing we can do
+        return;
+    }
+    CryptoRequest req = std::move(it->second);
+    m_requests.erase(it);
+
+    if (response.error != CKM_API_SUCCESS) {
+        LogError("Attempt to retrieve key failed with error: " << response.error);
+        m_service.RespondToClient(req, response.error);
+        return;
+    }
+
+    if (!response.key) {
+        LogError("Retrieved key is empty");
+        m_service.RespondToClient(req, CKM_API_ERROR_SERVER_ERROR);
+        return;
+    }
+
+    // TODO encrypt/decrypt
+    LogError("Encryption/decryption not yet supported");
+    m_service.RespondToClient(req, CKM_API_ERROR_SERVER_ERROR);
+}
+
 } /* namespace CKM */
index 21876f6..8f941dd 100644 (file)
@@ -37,6 +37,7 @@ public:
     virtual ~EncryptionLogic() {}
 
     void Crypt(const CryptoRequest& request);
+    void KeyRetrieved(MsgKeyResponse response);
 private:
     IEncryptionService& m_service;
 
index 47faf39..f08dbfa 100644 (file)
@@ -54,12 +54,11 @@ void EncryptionService::RespondToClient(const CryptoRequest& request,
     }
 }
 
-void EncryptionService::RequestKey(const Credentials& /*cred*/,
-                                   const Alias& /*alias*/,
-                                   const Label& /*label*/)
+void EncryptionService::RequestKey(const CryptoRequest& request)
 {
-    // This will be replaced in next commit
-    throw std::runtime_error("Not supported");
+    MsgKeyRequest kReq(request.msgId, request.cred, request.name, request.label, request.password);
+    if (!m_commMgr->SendMessage(kReq))
+        throw std::runtime_error("No listener found"); // TODO
 }
 
 GenericSocketService::ServiceDescriptionVector EncryptionService::GetServiceDescription()
@@ -77,6 +76,12 @@ void EncryptionService::Stop() {
     Join();
 }
 
+void EncryptionService::SetCommManager(CommMgr *manager)
+{
+    ThreadService::SetCommManager(manager);
+    Register(*manager);
+}
+
 bool EncryptionService::ProcessOne(
     const ConnectionID &conn,
     ConnectionInfo &info)
@@ -100,6 +105,11 @@ bool EncryptionService::ProcessOne(
     return false;
 }
 
+void EncryptionService::ProcessMessage(MsgKeyResponse msg)
+{
+    m_logic.KeyRetrieved(std::move(msg));
+}
+
 void EncryptionService::ProcessEncryption(const ConnectionID &conn,
                                           const Credentials &cred,
                                           MessageBuffer &buffer)
index 70146a1..73140b7 100644 (file)
 
 #pragma once
 
-#include <thread-service.h>
+#include <message-service.h>
 #include <noncopyable.h>
 #include <iencryption-service.h>
 #include <encryption-logic.h>
+#include <service-messages.h>
 
 namespace CKM {
 
-class EncryptionService : public ThreadService, public IEncryptionService
+class EncryptionService : public ThreadMessageService<MsgKeyResponse>, public IEncryptionService
 {
 public:
     EncryptionService();
@@ -40,8 +41,12 @@ public:
 
     void Start();
     void Stop();
+
 private:
+    virtual void SetCommManager(CommMgr *manager);
+
     bool ProcessOne(const ConnectionID &conn, ConnectionInfo &info);
+    void ProcessMessage(MsgKeyResponse msg);
     void ProcessEncryption(const ConnectionID &conn,
                            const Credentials &cred,
                            MessageBuffer &buffer);
@@ -50,9 +55,7 @@ private:
     virtual void RespondToClient(const CryptoRequest& request,
                                  int retCode,
                                  const RawBuffer& data = RawBuffer());
-    virtual void RequestKey(const Credentials& cred,
-                            const Alias& alias,
-                            const Label& label);
+    virtual void RequestKey(const CryptoRequest& request);
 
     EncryptionLogic m_logic;
 };
index 8e1ff5f..2c1d906 100644 (file)
@@ -34,9 +34,7 @@ public:
     virtual void RespondToClient(const CryptoRequest& request,
                                  int retCode,
                                  const RawBuffer& data = RawBuffer()) = 0;
-    virtual void RequestKey(const Credentials& cred,
-                            const Alias& alias,
-                            const Label& label) = 0;
+    virtual void RequestKey(const CryptoRequest& request) = 0;
 };
 
 } // namespace CKM