Add encryption service 66/40166/15
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 29 May 2015 14:59:57 +0000 (16:59 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 26 Jun 2015 11:39:50 +0000 (04:39 -0700)
[Feature] Encryption/decryption implementation
[Solution] Encryption service added

[Verification] Run test: ckm-tests --group=CKM_ENCRYPTION_DECRYPTION

Change-Id: I3ff79b06eabb6957ef2bbbe9a5bf7e5e2a995a21

14 files changed:
packaging/key-manager.spec
src/CMakeLists.txt
src/manager/client/client-manager-impl.cpp
src/manager/client/client-manager-impl.h
src/manager/main/key-manager-main.cpp
src/manager/service/crypto-request.h [new file with mode: 0644]
src/manager/service/encryption-logic.cpp [new file with mode: 0644]
src/manager/service/encryption-logic.h [new file with mode: 0644]
src/manager/service/encryption-service.cpp [new file with mode: 0644]
src/manager/service/encryption-service.h [new file with mode: 0644]
src/manager/service/iencryption-service.h [new file with mode: 0644]
systemd/CMakeLists.txt
systemd/central-key-manager-api-encryption.socket [new file with mode: 0644]
systemd/central-key-manager.service.in

index 9d32beb..f6d52d8 100644 (file)
@@ -153,6 +153,7 @@ ln -s ../central-key-manager-listener.service %{buildroot}%{_unitdir}/multi-user
 ln -s ../central-key-manager-api-control.socket %{buildroot}%{_unitdir}/sockets.target.wants/central-key-manager-api-control.socket
 ln -s ../central-key-manager-api-storage.socket %{buildroot}%{_unitdir}/sockets.target.wants/central-key-manager-api-storage.socket
 ln -s ../central-key-manager-api-ocsp.socket %{buildroot}%{_unitdir}/sockets.target.wants/central-key-manager-api-ocsp.socket
+ln -s ../central-key-manager-api-encryption.socket %{buildroot}%{_unitdir}/sockets.target.wants/central-key-manager-api-encryption.socket
 
 %clean
 rm -rf %{buildroot}
@@ -222,6 +223,8 @@ fi
 %{_unitdir}/central-key-manager-api-storage.socket
 %{_unitdir}/sockets.target.wants/central-key-manager-api-ocsp.socket
 %{_unitdir}/central-key-manager-api-ocsp.socket
+%{_unitdir}/sockets.target.wants/central-key-manager-api-encryption.socket
+%{_unitdir}/central-key-manager-api-encryption.socket
 %{_datadir}/license/%{name}
 %{_datadir}/ckm/scripts/*.sql
 %{_datadir}/
index 1460a53..fd79979 100644 (file)
@@ -34,6 +34,8 @@ SET(KEY_MANAGER_SOURCES
     ${KEY_MANAGER_PATH}/service/db-crypto.cpp
     ${KEY_MANAGER_PATH}/service/ocsp-service.cpp
     ${KEY_MANAGER_PATH}/service/ocsp-logic.cpp
+    ${KEY_MANAGER_PATH}/service/encryption-service.cpp
+    ${KEY_MANAGER_PATH}/service/encryption-logic.cpp
     ${KEY_MANAGER_PATH}/initial-values/parser.cpp
     ${KEY_MANAGER_PATH}/initial-values/BufferHandler.cpp
     ${KEY_MANAGER_PATH}/initial-values/CertHandler.cpp
index 76a5e57..ca9d250 100644 (file)
@@ -763,11 +763,12 @@ int ManagerImpl::setPermission(const Alias &alias,
     });
 }
 
-int ManagerImpl::encrypt(const CryptoAlgorithm &algo,
-                         const Alias &keyAlias,
-                         const Password &password,
-                         const RawBuffer& plain,
-                         RawBuffer& encrypted)
+int ManagerImpl::crypt(EncryptionCommand command,
+          const CryptoAlgorithm &algo,
+          const Alias &keyAlias,
+          const Password &password,
+          const RawBuffer& input,
+          RawBuffer& output)
 {
     int my_counter = ++m_counter;
 
@@ -775,13 +776,13 @@ int ManagerImpl::encrypt(const CryptoAlgorithm &algo,
         MessageBuffer recv;
         AliasSupport helper(keyAlias);
         CryptoAlgorithmSerializable cas(algo);
-        auto send = MessageBuffer::Serialize(static_cast<int>(EncryptionCommand::ENCRYPT),
+        auto send = MessageBuffer::Serialize(static_cast<int>(command),
                                              my_counter,
                                              cas,
                                              helper.getName(),
                                              helper.getLabel(),
                                              password,
-                                             plain);
+                                             input);
 
         int retCode = m_encryptionConnection.processRequest(send.Pop(), recv);
         if (CKM_API_SUCCESS != retCode)
@@ -789,7 +790,7 @@ int ManagerImpl::encrypt(const CryptoAlgorithm &algo,
 
         int command;
         int counter;
-        recv.Deserialize(command, counter, encrypted);
+        recv.Deserialize(command, counter, retCode, output);
 
         if (my_counter != counter) {
             return CKM_API_ERROR_UNKNOWN;
@@ -799,40 +800,22 @@ int ManagerImpl::encrypt(const CryptoAlgorithm &algo,
     });
 }
 
+int ManagerImpl::encrypt(const CryptoAlgorithm &algo,
+            const Alias &keyAlias,
+            const Password &password,
+            const RawBuffer& plain,
+            RawBuffer& encrypted)
+{
+    return crypt(EncryptionCommand::ENCRYPT, algo, keyAlias, password, plain, encrypted);
+}
+
 int ManagerImpl::decrypt(const CryptoAlgorithm &algo,
                          const Alias &keyAlias,
                          const Password &password,
                          const RawBuffer& encrypted,
                          RawBuffer& decrypted)
 {
-    int my_counter = ++m_counter;
-
-    return try_catch([&] {
-        MessageBuffer recv;
-        AliasSupport helper(keyAlias);
-        CryptoAlgorithmSerializable cas(algo);
-        auto send = MessageBuffer::Serialize(static_cast<int>(EncryptionCommand::DECRYPT),
-                                             my_counter,
-                                             cas,
-                                             helper.getName(),
-                                             helper.getLabel(),
-                                             password,
-                                             encrypted);
-
-        int retCode = m_encryptionConnection.processRequest(send.Pop(), recv);
-        if (CKM_API_SUCCESS != retCode)
-            return retCode;
-
-        int command;
-        int counter;
-        recv.Deserialize(command, counter, decrypted);
-
-        if (my_counter != counter) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
-
-        return retCode;
-    });
+    return crypt(EncryptionCommand::DECRYPT, algo, keyAlias, password, encrypted, decrypted);
 }
 
 ManagerShPtr Manager::create() {
index fce5992..e9df170 100644 (file)
@@ -153,6 +153,13 @@ protected:
         const Policy &policyPrivateKey,
         const Policy &policyPublicKey);
 
+    int crypt(EncryptionCommand command,
+              const CryptoAlgorithm &algo,
+              const Alias &keyAlias,
+              const Password &password,
+              const RawBuffer& input,
+              RawBuffer& output);
+
     int m_counter;
     CKM::ServiceConnection m_storageConnection;
     CKM::ServiceConnection m_ocspConnection;
index 71c76e7..d1e486e 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <ckm-service.h>
 #include <ocsp-service.h>
+#include <encryption-service.h>
 
 #include <key-provider.h>
 #include <file-system.h>
@@ -100,6 +101,7 @@ int main(void) {
 
             REGISTER_SOCKET_SERVICE(manager, CKM::CKMService);
             REGISTER_SOCKET_SERVICE(manager, CKM::OCSPService);
+            REGISTER_SOCKET_SERVICE(manager, CKM::EncryptionService);
 
             manager.MainLoop();
         }
diff --git a/src/manager/service/crypto-request.h b/src/manager/service/crypto-request.h
new file mode 100644 (file)
index 0000000..d8acf2b
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       crypto-request.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#pragma once
+
+#include <generic-socket-manager.h>
+#include <protocols.h>
+#include <ckm/ckm-type.h>
+
+namespace CKM {
+
+struct CryptoRequest
+{
+    ConnectionID conn;
+    Credentials cred;
+    EncryptionCommand command;
+    int msgId;
+    CryptoAlgorithmSerializable cas;
+    Name name;
+    Label label;
+    Password password;
+    RawBuffer input;
+};
+
+} /* namespace CKM */
diff --git a/src/manager/service/encryption-logic.cpp b/src/manager/service/encryption-logic.cpp
new file mode 100644 (file)
index 0000000..5baac5b
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       encryption-logic.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include <encryption-logic.h>
+#include <ckm/ckm-error.h>
+#include <dpl/log/log.h>
+
+namespace CKM {
+
+void EncryptionLogic::Crypt(const CryptoRequest& request)
+{
+    // check arguments
+    if(request.input.empty()) {
+        LogError("No input data");
+        m_service.RespondToClient(request, CKM_API_ERROR_INPUT_PARAM);
+        return;
+    }
+
+    // store request in the map
+    auto ret = m_requests.insert(std::make_pair(request.msgId, request));
+    if (!ret.second) {
+        LogError("Request with id " << request.msgId << " already exists");
+        m_service.RespondToClient(request, CKM_API_ERROR_INPUT_PARAM);
+        return;
+    }
+
+    // request key
+    try {
+        m_service.RequestKey(request.cred, request.name, request.label);
+    } catch (...) {
+        LogError("Key request failed");
+        m_requests.erase(request.msgId);
+        m_service.RespondToClient(request, CKM_API_ERROR_SERVER_ERROR);
+    }
+}
+
+} /* namespace CKM */
diff --git a/src/manager/service/encryption-logic.h b/src/manager/service/encryption-logic.h
new file mode 100644 (file)
index 0000000..21876f6
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       encryption-logic.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#pragma once
+
+#include <map>
+#include <ckm/ckm-type.h>
+#include <generic-socket-manager.h>
+#include <protocols.h>
+#include <iencryption-service.h>
+#include <crypto-request.h>
+
+namespace CKM {
+
+class EncryptionLogic
+{
+public:
+    EncryptionLogic(IEncryptionService& service) : m_service(service) {}
+    virtual ~EncryptionLogic() {}
+
+    void Crypt(const CryptoRequest& request);
+private:
+    IEncryptionService& m_service;
+
+    std::map<int, CryptoRequest> m_requests;
+};
+
+} /* namespace CKM */
diff --git a/src/manager/service/encryption-service.cpp b/src/manager/service/encryption-service.cpp
new file mode 100644 (file)
index 0000000..47faf39
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       encryption-service.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include <stdexcept>
+#include <utility>
+#include <encryption-service.h>
+#include <protocols.h>
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+#include <crypto-request.h>
+
+namespace {
+const CKM::InterfaceID SOCKET_ID_ENCRYPTION = 0;
+} // namespace anonymous
+
+namespace CKM {
+
+EncryptionService::EncryptionService() : m_logic(*this)
+{
+}
+
+EncryptionService::~EncryptionService()
+{
+}
+
+void EncryptionService::RespondToClient(const CryptoRequest& request,
+                                        int retCode,
+                                        const RawBuffer& data)
+{
+    try {
+        RawBuffer response = MessageBuffer::Serialize(
+                static_cast<int>(request.command), request.msgId, retCode, data).Pop();
+        m_serviceManager->Write(request.conn, response);
+    } catch (...) {
+        LogError("Failed to send response to the client");
+    }
+}
+
+void EncryptionService::RequestKey(const Credentials& /*cred*/,
+                                   const Alias& /*alias*/,
+                                   const Label& /*label*/)
+{
+    // This will be replaced in next commit
+    throw std::runtime_error("Not supported");
+}
+
+GenericSocketService::ServiceDescriptionVector EncryptionService::GetServiceDescription()
+{
+    return ServiceDescriptionVector {
+        {SERVICE_SOCKET_ENCRYPTION, "key-manager::api-encryption", SOCKET_ID_ENCRYPTION}
+    };
+}
+
+void EncryptionService::Start() {
+    Create();
+}
+
+void EncryptionService::Stop() {
+    Join();
+}
+
+bool EncryptionService::ProcessOne(
+    const ConnectionID &conn,
+    ConnectionInfo &info)
+{
+    LogDebug ("process One");
+    try {
+        if (!info.buffer.Ready())
+            return false;
+
+        ProcessEncryption(conn, info.credentials, info.buffer);
+        return true;
+    } catch (MessageBuffer::Exception::Base) {
+        LogError("Broken protocol. Closing socket.");
+    } catch (const std::exception &e) {
+        LogError("Std exception:: " << e.what());
+    } catch (...) {
+        LogError("Unknown exception. Closing socket.");
+    }
+
+    m_serviceManager->Close(conn);
+    return false;
+}
+
+void EncryptionService::ProcessEncryption(const ConnectionID &conn,
+                                          const Credentials &cred,
+                                          MessageBuffer &buffer)
+{
+    int tmpCmd = 0;
+    CryptoRequest req;
+
+    buffer.Deserialize(tmpCmd, req.msgId, req.cas, req.name, req.label, req.password, req.input);
+    req.command = static_cast<EncryptionCommand>(tmpCmd);
+    if (req.command != EncryptionCommand::ENCRYPT && req.command != EncryptionCommand::DECRYPT)
+        throw std::runtime_error("Unsupported command: " + tmpCmd);
+
+    req.conn = conn;
+    req.cred = cred;
+    m_logic.Crypt(req);
+}
+
+} /* namespace CKM */
diff --git a/src/manager/service/encryption-service.h b/src/manager/service/encryption-service.h
new file mode 100644 (file)
index 0000000..70146a1
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       encryption-service.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#pragma once
+
+#include <thread-service.h>
+#include <noncopyable.h>
+#include <iencryption-service.h>
+#include <encryption-logic.h>
+
+namespace CKM {
+
+class EncryptionService : public ThreadService, public IEncryptionService
+{
+public:
+    EncryptionService();
+    virtual ~EncryptionService();
+    NONCOPYABLE(EncryptionService);
+
+    // from ThreadService
+    ServiceDescriptionVector GetServiceDescription();
+
+    void Start();
+    void Stop();
+private:
+    bool ProcessOne(const ConnectionID &conn, ConnectionInfo &info);
+    void ProcessEncryption(const ConnectionID &conn,
+                           const Credentials &cred,
+                           MessageBuffer &buffer);
+
+    // from IEncryptionService
+    virtual void RespondToClient(const CryptoRequest& request,
+                                 int retCode,
+                                 const RawBuffer& data = RawBuffer());
+    virtual void RequestKey(const Credentials& cred,
+                            const Alias& alias,
+                            const Label& label);
+
+    EncryptionLogic m_logic;
+};
+
+} /* namespace CKM */
diff --git a/src/manager/service/iencryption-service.h b/src/manager/service/iencryption-service.h
new file mode 100644 (file)
index 0000000..8e1ff5f
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       iencryption-service.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#pragma once
+
+#include <generic-socket-manager.h>
+#include <ckm/ckm-type.h>
+#include <generic-backend/gkey.h>
+#include <protocols.h>
+#include <crypto-request.h>
+
+namespace CKM {
+
+class IEncryptionService {
+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;
+};
+
+} // namespace CKM
+
+
index f9005e7..cda16ec 100644 (file)
@@ -8,6 +8,7 @@ INSTALL(FILES
     ${CMAKE_SOURCE_DIR}/systemd/central-key-manager-api-control.socket
     ${CMAKE_SOURCE_DIR}/systemd/central-key-manager-api-storage.socket
     ${CMAKE_SOURCE_DIR}/systemd/central-key-manager-api-ocsp.socket
+    ${CMAKE_SOURCE_DIR}/systemd/central-key-manager-api-encryption.socket
     DESTINATION
     ${SYSTEMD_UNIT_DIR}
 )
diff --git a/systemd/central-key-manager-api-encryption.socket b/systemd/central-key-manager-api-encryption.socket
new file mode 100644 (file)
index 0000000..21e8e81
--- /dev/null
@@ -0,0 +1,14 @@
+[Socket]
+ListenStream=/tmp/.central-key-manager-api-encryption.sock
+SocketMode=0777
+SmackLabelIPIn=key-manager::api-encryption
+SmackLabelIPOut=@
+
+Service=central-key-manager.service
+
+[Unit]
+Wants=central-key-manager.target
+Before=central-key-manager.target
+
+[Install]
+WantedBy=sockets.target
index 469db7a..0159131 100644 (file)
@@ -8,6 +8,7 @@ ExecStart=/usr/bin/key-manager
 Sockets=central-key-manager-api-storage.socket
 Sockets=central-key-manager-api-control.socket
 Sockets=central-key-manager-api-ocsp.socket
+Sockets=central-key-manager-api-encryption.socket
 EnvironmentFile=-@SYSTEMD_ENV_FILE@
 
 [Install]