Protect concatenated data (un)wrapping with the keymanager.extended privilege 16/313416/7
authorFilip Skrzeczkowski <f.skrzeczkow@samsung.com>
Tue, 25 Jun 2024 14:24:28 +0000 (16:24 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Tue, 2 Jul 2024 09:12:01 +0000 (09:12 +0000)
Create an additional socket for processing requests made with the
extended API and check the keymanager.extended privilege

Change-Id: Ic548d195012ab2d4fd8d5a888bf20c45602b8bd2

packaging/key-manager.spec
src/manager/client/client-manager-impl.cpp
src/manager/client/client-manager-impl.h
src/manager/common/protocols.cpp
src/manager/common/protocols.h
src/manager/service/ckm-service.cpp
src/manager/service/ckm-service.h
systemd/CMakeLists.txt
systemd/central-key-manager-api-extended.socket [new file with mode: 0644]
systemd/central-key-manager.service.in

index 232f43b2896dad0f91e5dbf47b2d7b6ab8538fe1..c5ec2f7774b6d92c1d1576c01fc64df13352dcd2 100644 (file)
@@ -237,6 +237,7 @@ make %{?jobs:-j%jobs}
 %install_service multi-user.target.wants central-key-manager.service
 %install_service sockets.target.wants central-key-manager-api-control.socket
 %install_service sockets.target.wants central-key-manager-api-storage.socket
+%install_service sockets.target.wants central-key-manager-api-extended.socket
 %install_service sockets.target.wants central-key-manager-api-ocsp.socket
 %install_service sockets.target.wants central-key-manager-api-encryption.socket
 cp -a %{SOURCE1001} %{SOURCE1002} %{SOURCE1003} %{SOURCE1004} %{buildroot}%{_datadir}/
@@ -327,6 +328,8 @@ fi
 %{_unitdir}/central-key-manager-api-control.socket
 %{_unitdir}/sockets.target.wants/central-key-manager-api-storage.socket
 %{_unitdir}/central-key-manager-api-storage.socket
+%{_unitdir}/sockets.target.wants/central-key-manager-api-extended.socket
+%{_unitdir}/central-key-manager-api-extended.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
index ad2cdf2fa40e5383f234906d5990cb3aa337ad74..3f1f6e20d3a3892d616a0e0a918bdde319a70acb 100644 (file)
@@ -91,6 +91,7 @@ int doRequest(MessageBuffer &recv, CKM::ServiceConnection &conn, T&&...t)
 
 Manager::Impl::Impl()
        : m_storageConnection(SERVICE_SOCKET_CKM_STORAGE),
+         m_extendedConnection(SERVICE_SOCKET_CKM_EXTENDED),
          m_ocspConnection(SERVICE_SOCKET_OCSP),
          m_encryptionConnection(SERVICE_SOCKET_ENCRYPTION)
 {
@@ -828,7 +829,7 @@ int Manager::Impl::wrapConcatenatedData(const CryptoAlgorithm &params,
 
        return Request(*this,
                LogicCommand::WRAP_CONCATENATED_DATA,
-               m_storageConnection,
+               m_extendedConnection,
                CryptoAlgorithmSerializable(params),
                wrappingAliasHelper.getName(),
                wrappingAliasHelper.getOwner(),
@@ -858,7 +859,7 @@ int Manager::Impl::unwrapConcatenatedData(const CryptoAlgorithm &params,
 
        return Request(*this,
                LogicCommand::UNWRAP_CONCATENATED_DATA,
-               m_storageConnection,
+               m_extendedConnection,
                CryptoAlgorithmSerializable(params),
                wrappingAliasHelper.getName(),
                wrappingAliasHelper.getOwner(),
index d7fa94b7e7e77a9033ae3f270f3bb9a13b96af40..896bb8d83efbe2eaf5c3358d0dafb0df770c9717 100644 (file)
@@ -229,6 +229,7 @@ private:
 
        int m_counter = 0;
        CKM::ServiceConnection m_storageConnection;
+       CKM::ServiceConnection m_extendedConnection;
        CKM::ServiceConnection m_ocspConnection;
        CKM::ServiceConnection m_encryptionConnection;
 
index dc0a5bd43aa8d7c77573b4eb5b59f5e6359b7737..8edc4d9c3451bd372b017a0bd4b033bd79d2b710 100644 (file)
@@ -34,6 +34,8 @@ char const *const SERVICE_SOCKET_CKM_CONTROL =
        "/tmp/.central-key-manager-api-control.sock";
 char const *const SERVICE_SOCKET_CKM_STORAGE =
        "/tmp/.central-key-manager-api-storage.sock";
+char const *const SERVICE_SOCKET_CKM_EXTENDED =
+       "/tmp/.central-key-manager-api-extended.sock";
 char const *const SERVICE_SOCKET_OCSP =
        "/tmp/.central-key-manager-api-ocsp.sock";
 char const *const SERVICE_SOCKET_ENCRYPTION =
index ae2acbc48979f759161d235fbd1b2de83aa77bbe..aa9c4eaf071010e3ed0b779870d22f664371fb15 100644 (file)
@@ -38,6 +38,7 @@ namespace CKM {
 COMMON_API extern char const *const SERVICE_SOCKET_ECHO;
 COMMON_API extern char const *const SERVICE_SOCKET_CKM_CONTROL;
 COMMON_API extern char const *const SERVICE_SOCKET_CKM_STORAGE;
+COMMON_API extern char const *const SERVICE_SOCKET_CKM_EXTENDED;
 COMMON_API extern char const *const SERVICE_SOCKET_OCSP;
 COMMON_API extern char const *const SERVICE_SOCKET_ENCRYPTION;
 COMMON_API extern char const *const KEY_MANAGER_BOOST_TARGET;
index be4ebfe1e0d8fdeaf81680702376e464c3cc2fcd..7cfac0f5a548fd61413f012edbca6c6e62747067 100644 (file)
@@ -32,6 +32,7 @@
 namespace {
 const CKM::InterfaceID SOCKET_ID_CONTROL = 0;
 const CKM::InterfaceID SOCKET_ID_STORAGE = 1;
+const CKM::InterfaceID SOCKET_ID_EXTENDED = 2;
 } // namespace anonymous
 
 namespace CKM {
@@ -67,8 +68,11 @@ CKMService::GetServiceDescription()
 {
        // empty string on privilege field means non-privileged
        return ServiceDescriptionVector {
-               {SERVICE_SOCKET_CKM_CONTROL, "http://tizen.org/privilege/internal/service", SOCKET_ID_CONTROL},
-               {SERVICE_SOCKET_CKM_STORAGE, "", SOCKET_ID_STORAGE}
+               {SERVICE_SOCKET_CKM_CONTROL, "http://tizen.org/privilege/internal/service",
+                SOCKET_ID_CONTROL},
+               {SERVICE_SOCKET_CKM_STORAGE, "", SOCKET_ID_STORAGE},
+               {SERVICE_SOCKET_CKM_EXTENDED, "http://tizen.org/privilege/keymanager.extended",
+                SOCKET_ID_EXTENDED}
        };
 }
 
@@ -78,6 +82,24 @@ void CKMService::SetCommManager(CommMgr *manager)
        Register(*manager);
 }
 
+void CKMService::DeserializeCommand(
+       Credentials &cred,
+       MessageBuffer &buffer,
+       LogicCommand& command,
+       int& msgId)
+{
+       buffer.Deserialize(command);
+       buffer.Deserialize(msgId);
+
+       // This is a workaround solution for locktype=None in Tizen 2.2.1
+       // When locktype is None, lockscreen app doesn't interfere with unlocking process.
+       // Therefor lockscreen app cannot notify unlock events to key-manager when locktype is None.
+       // So, to unlock user data when lock type is None, key-manager always try to unlock user data
+       // with null password. Even if the result is fail, it will be ignored.
+       Password nullPassword("");
+       m_logic->unlockUserKey(cred.clientUid, nullPassword);
+}
+
 bool CKMService::ProcessOne(
        const ConnectionID &conn,
        ConnectionInfo &info,
@@ -90,10 +112,17 @@ bool CKMService::ProcessOne(
                if (!info.buffer.Ready())
                        return false;
 
-               if (info.interfaceID == SOCKET_ID_CONTROL)
-                       response = ProcessControl(info.buffer, allowed);
-               else
-                       response = ProcessStorage(info.credentials, info.buffer);
+               switch(info.interfaceID) {
+                       case SOCKET_ID_CONTROL:
+                               response = ProcessControl(info.buffer, allowed);
+                               break;
+                       case SOCKET_ID_STORAGE:
+                               response = ProcessStorage(info.credentials, info.buffer);
+                               break;
+                       case SOCKET_ID_EXTENDED:
+                               response = ProcessExtended(info.credentials, info.buffer, allowed);
+                               break;
+               }
 
                m_serviceManager->Write(conn, response);
 
@@ -216,16 +245,7 @@ RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
        Name name;
        ClientId explicitOwner, accessor;
 
-       buffer.Deserialize(command);
-       buffer.Deserialize(msgId);
-
-       // This is a workaround solution for locktype=None in Tizen 2.2.1
-       // When locktype is None, lockscreen app doesn't interfere with unlocking process.
-       // Therefor lockscreen app cannot notify unlock events to key-manager when locktype is None.
-       // So, to unlock user data when lock type is None, key-manager always try to unlock user data with null password.
-       // Even if the result is fail, it will be ignored.
-       Password nullPassword("");
-       m_logic->unlockUserKey(cred.clientUid, nullPassword);
+       DeserializeCommand(cred, buffer, command, msgId);
 
        LogDebug("Process storage. Command: " << static_cast<int>(command));
 
@@ -517,6 +537,34 @@ RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
                                        keyPassword);
        }
 
+       case LogicCommand::GET_BACKEND_INFO: {
+               BackendId backend;
+
+               buffer.Deserialize(backend);
+
+               return m_logic->getBackendInfo(msgId, backend);
+       }
+
+       default:
+               Throw(Exception::BrokenProtocol);
+       }
+}
+
+RawBuffer CKMService::ProcessExtended(Credentials &cred, MessageBuffer &buffer, bool allowed)
+{
+       LogicCommand command;
+       int msgId = 0;
+       DataType tmpDataType;
+       Name name;
+       ClientId explicitOwner, accessor;
+
+       DeserializeCommand(cred, buffer, command, msgId);
+
+       LogDebug("Process extended. Command: " << static_cast<int>(command));
+
+       std::function<RawBuffer(void)> logicFunc;
+
+       switch (command) {
        case LogicCommand::WRAP_CONCATENATED_DATA: {
                CryptoAlgorithmSerializable params;
                Name wrappingKeyName;
@@ -535,7 +583,9 @@ RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
                                                   keyPassword,
                                                   data);
 
-               return m_logic->wrapConcatenatedData(
+               logicFunc = [&, params, wrappingKeyName, wrappingKeyOwner, wrappingKeyPassword, keyName,
+                                        keyPassword, data]() {
+                       return m_logic->wrapConcatenatedData(
                                        cred,
                                        msgId,
                                        params,
@@ -546,6 +596,8 @@ RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
                                        cred.effectiveOwner(explicitOwner),
                                        keyPassword,
                                        data);
+               };
+               break;
        }
 
        case LogicCommand::UNWRAP_CONCATENATED_DATA: {
@@ -568,31 +620,34 @@ RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
                                                   size,
                                                   policy);
 
-               return m_logic->unwrapConcatenatedData(
-                                       cred,
-                                       msgId,
-                                       params,
-                                       wrappingKeyName,
-                                       cred.effectiveOwner(wrappingKeyOwner),
-                                       wrappingKeyPassword,
-                                       wrappedKey,
-                                       keyName,
-                                       cred.effectiveOwner(explicitOwner),
-                                       size,
-                                       policy);
-       }
-
-       case LogicCommand::GET_BACKEND_INFO: {
-               BackendId backend;
-
-               buffer.Deserialize(backend);
-
-               return m_logic->getBackendInfo(msgId, backend);
+               logicFunc = [&, params, wrappingKeyName, wrappingKeyOwner, wrappingKeyPassword, wrappedKey,
+                                        keyName, size, policy]() {
+                       return m_logic->unwrapConcatenatedData(
+                                               cred,
+                                               msgId,
+                                               params,
+                                               wrappingKeyName,
+                                               cred.effectiveOwner(wrappingKeyOwner),
+                                               wrappingKeyPassword,
+                                               wrappedKey,
+                                               keyName,
+                                               cred.effectiveOwner(explicitOwner),
+                                               size,
+                                               policy);
+               };
+               break;
        }
 
        default:
                Throw(Exception::BrokenProtocol);
        }
+
+       if (!allowed) {
+               LogError("Access denied!");
+               return SerializeMessage(msgId, CKM_API_ERROR_ACCESS_DENIED, RawBuffer());
+       }
+
+       return logicFunc();
 }
 
 void CKMService::ProcessMessage(MsgKeyRequest msg)
index 89cec9d135176a1f5c5b9b7b5888bf0d48cbfc5d..a815f69110208cf62f509d21dba6f9a8b9b62342 100644 (file)
@@ -49,6 +49,12 @@ public:
 private:
        virtual void SetCommManager(CommMgr *manager);
 
+       void DeserializeCommand(
+               Credentials &cred,
+               MessageBuffer &buffer,
+               LogicCommand& command,
+               int& msgId);
+
        class Exception {
        public:
                DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
@@ -68,6 +74,11 @@ private:
                Credentials &cred,
                MessageBuffer &buffer);
 
+       RawBuffer ProcessExtended(
+               Credentials &cred,
+               MessageBuffer &buffer,
+               bool allowed);
+
        virtual void ProcessMessage(MsgKeyRequest msg);
        virtual void ProcessMessage(MsgRemoveAppData msg);
 
index c230e23338a2797984220d6968fb2d5a131f0b88..7383ec725d8d47793597b4eb54f0c3a8d7e01f8e 100644 (file)
@@ -5,6 +5,7 @@ INSTALL(FILES
     ${CMAKE_SOURCE_DIR}/systemd/central-key-manager.service
     ${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-extended.socket
     ${CMAKE_SOURCE_DIR}/systemd/central-key-manager-api-ocsp.socket
     ${CMAKE_SOURCE_DIR}/systemd/central-key-manager-api-encryption.socket
     DESTINATION
diff --git a/systemd/central-key-manager-api-extended.socket b/systemd/central-key-manager-api-extended.socket
new file mode 100644 (file)
index 0000000..e6a498f
--- /dev/null
@@ -0,0 +1,9 @@
+[Socket]
+ListenStream=/tmp/.central-key-manager-api-extended.sock
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+Service=central-key-manager.service
+
+[Install]
+WantedBy=sockets.target
index 025aa3d42cf3767f5038b54842679da8dc103cac..0ef320be95ecbe71c6d20db2fe4b2dc22ef55af3 100644 (file)
@@ -2,7 +2,7 @@
 Description=Start the Central Key Manager
 DefaultDependencies=no
 RequiresMountsFor=/opt
-Requires=central-key-manager-api-storage.socket central-key-manager-api-control.socket central-key-manager-api-ocsp.socket central-key-manager-api-encryption.socket
+Requires=central-key-manager-api-storage.socket central-key-manager-api-extended.socket central-key-manager-api-control.socket central-key-manager-api-ocsp.socket central-key-manager-api-encryption.socket
 
 [Service]
 User=@USER_NAME@