Use common HAL API 43/318243/16
authorJakub Wlostowski <j.wlostowski@samsung.com>
Tue, 31 Dec 2024 13:24:22 +0000 (14:24 +0100)
committerJakub Wlostowski <j.wlostowski@samsung.com>
Thu, 30 Jan 2025 09:23:55 +0000 (10:23 +0100)
Change-Id: Ibc8eef869423a053e698eba641826272b0e6a8f7

18 files changed:
CMakeLists.txt
README.md
packaging/device-certificate-manager.spec
pkgconfig/CMakeLists.txt
pkgconfig/device-certificate-manager-backend.pc.in [deleted file]
rpm/CMakeLists.txt [deleted file]
rpm/macros.dcm-backend-api.in [deleted file]
src/dcm-client/CMakeLists.txt
src/dcm-daemon/CMakeLists.txt
src/dcm-daemon/dcm-backend-api.h [deleted file]
src/dcm-daemon/dcm-ext-backend-api.h [deleted file]
src/dcm-daemon/dcm_server.cpp
src/dcm-daemon/dcm_server.h
src/dcm-daemon/dcm_session.cpp
src/dcm-daemon/dcm_session.h
src/dcm-daemon/soresolver.cpp [deleted file]
src/dcm-daemon/soresolver.h [deleted file]
src/include/device_certificate_manager_ext.h

index 2244c89da0151d1e424b71a52ca52f7b4b19d8f1..e3856b88fb56972aa84771583080afef8f1f2a62 100644 (file)
@@ -55,6 +55,5 @@ ADD_SUBDIRECTORY(src/include)
 ADD_SUBDIRECTORY(src/dcm-client)
 ADD_SUBDIRECTORY(src/dcm-daemon)
 ADD_SUBDIRECTORY(pkgconfig)
-ADD_SUBDIRECTORY(rpm)
 ADD_SUBDIRECTORY(systemd)
 ADD_SUBDIRECTORY(tests)
index 8976fb44521399511ddcd4896d7197366d180cf9..fd6a404194071629da1101cc427e1e0693ad922f 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,32 +1,31 @@
-#Device Certificate Manager
+# Device Certificate Manager
 
-##About
+## About
 
 The Device Certificate Manager (DCM) provides cryptography services (digital certificates and keys) for authentication and secure communication with another system.
 Please visit the following webpage for the details about the prerequsities and the usage: [https://docs.tizen.org/application/native/guides/security/device-certificate-manager](https://docs.tizen.org/application/native/guides/security/device-certificate-manager).
 
-##Architecture
+## Architecture
 
 The DCM (tizen.org repository *platform/core/security/device-certificate-manager*) consists of two submodules: the client and the daemon.
 The client provides the public DCM API, while the daemon its implementation.
-The implementation is realized with the internal backend API (see the *src/dcm-daemon/dcm-backend-api.h* header file).
-Example implementation of this backend API may be found in the tizen.org separate repository: *platform/core/security/device-certificate-manager-backend*.
-The DCM backend repository provides dummy implementation based on the OpenSSL and dedicated mainly for the testing purposes.
+The implementation is realized with the external backend HAL API (see the *platform/hal/api/security* security-certs header files, for existing functions).
+Example implementation of this backend API may be found in the tizen.org separate repository: *platform/hal/backend/emulator/security-certs*.
+The security-certs backend repository provides example implementation based on the OpenSSL and dedicated mainly for the testing purposes.
 
-Backend is packed to the rpm device-certificate-manager-backend-dummy package, that provide the *libdcm-backend-api.so* library with the DCM backend API implementation.
+Backend is packed to the hal-backend-security-certs rpm package, that provides the *libhal-backend-security-certs.so* library with the Security Certs backend API implementation.
 The library is loaded dynamically by the DCM daemon at runtime.
-Although the DCM backend is not installed automatically with the DCM, it is required for proper work of the DCM and because of that it must be installed manually.
-Alternatively, the specific Tizen image may be configured to contain the chosen backend.
+It is required for proper work of the DCM.
 
-##Adding a new backend (a new SE device)
+## Adding a new backend (a new SE device)
 
-In order to support a new SE device in the DCM, a new backend API implementation must be developed, which means that the plugin developer must provide the implemenation of the plugin header (*src/dcm-daemon/dcm-backend-api.h*).
-Such an implementation may be based on the dummy implementation from the *platform/core/security/device-certificate-manager-backend* repository.
+In order to support a new SE device in the DCM, a new backend API implementation must be developed, which means that the plugin developer must provide the implemenation of the plugin header (*hal-security-certs.h* from *platform/hal/api/security* repository).
+Such an implementation may be based on the example implementation from the *platform/hal/backend/emulator/security-certs* repository.
 The new implementation may be added to this public repository or provided in the separate git repository.
-The most important item is to implement the *libdcm-backend-api.so* library and to install it in the system.
+The most important item is to implement the *libhal-backend-security-certs.so* library and to install it in the system.
 The DCM daemon does not need to be modified.
 
-##Testing
+## Testing
 There is currently one general testing application:
 - *device-certificate-manager-tests*
 Testing application should be executed after implementing changes to the DCM or to the DCM backend repository.
index 1b34efbd3b06e3acad16440fcfe2e2eedb18fa1d..d0ca59f7ada3dc0189490c7a7e9ac980d2604aa8 100644 (file)
@@ -16,6 +16,7 @@ BuildRequires: pkgconfig(cynara-client)
 BuildRequires: pkgconfig(cynara-creds-socket)
 BuildRequires: pkgconfig(cynara-session)
 BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(hal-api-security)
 BuildRequires: boost-devel
 %if "%{build_type}" == "COVERAGE"
 BuildRequires: lcov
@@ -49,13 +50,6 @@ Requires:    device-certificate-manager = %{version}-%{release}
 %description -n device-certificate-manager-ext-devel
 Device Certificate Manager development headers and libraries only for extension of the API
 
-%package -n device-certificate-manager-backend-devel
-Summary:       Device Certificate Manager backend (development)
-Group:         Security/Development
-
-%description -n device-certificate-manager-backend-devel
-Device Certificate Manager backend development header
-
 %package -n device-certificate-manager-tests
 Summary:       Internal tests for Device Certificate Manager
 Group:         Security/Testing
@@ -63,6 +57,8 @@ License:      Apache-2.0 and BSL-1.0
 BuildRequires: pkgconfig(security-manager)
 Requires:      device-certificate-manager = %{version}-%{release}
 Requires:      boost-test
+Requires(post): /usr/bin/system-info-tool
+Requires(postun): /usr/bin/system-info-tool
 
 %description -n device-certificate-manager-tests
 Internal tests for Device Certificate Manager
@@ -92,7 +88,6 @@ cp -a %{SOURCE1001} .
        -DUSER_NAME=%{user_name} \
        -DGROUP_NAME=%{group_name} \
        -DSMACK_DOMAIN_NAME=%{smack_domain_name} \
-       -DRPM_DIR=%{_sysconfdir}/rpm \
        -DCOVERAGE_DIR=%{coverage_dir}
 
 make
@@ -128,6 +123,16 @@ if [ $1 = 0 ]; then
        systemctl daemon-reload
 fi
 
+%post -n device-certificate-manager-tests
+
+/usr/bin/system-info-tool -s tizen.org/feature/security.device_certificate bool 1
+
+%postun -n device-certificate-manager-tests
+
+if [ $1 = 0 ]; then
+       /usr/bin/system-info-tool -s tizen.org/feature/security.device_certificate bool 0
+fi
+
 %files
 %manifest %{name}.manifest
 %license LICENSE
@@ -153,15 +158,6 @@ fi
 %{_includedir}/device-certificate-manager/device_certificate_manager_ext_types.h
 %{_libdir}/pkgconfig/device-certificate-manager-ext.pc
 
-%files backend-devel
-%manifest %{name}.manifest
-%license LICENSE
-%{_includedir}/device-certificate-manager-backend/dcm-backend-api.h
-%{_includedir}/device-certificate-manager-backend/dcm-ext-backend-api.h
-%{_includedir}/device-certificate-manager-backend/dcm_support.pb.h
-%{_libdir}/pkgconfig/device-certificate-manager-backend.pc
-%{_sysconfdir}/rpm/macros.dcm-backend-api
-
 %files tests
 %manifest %{name}.manifest
 %license LICENSE
index 08b647018304c2c95cc8f370c6d769f97caa5354..bdbcf476abda3faf029a921b2682ade6ae4002a2 100644 (file)
 
 CONFIGURE_FILE(device-certificate-manager.pc.in device-certificate-manager.pc @ONLY)
 CONFIGURE_FILE(device-certificate-manager-ext.pc.in device-certificate-manager-ext.pc @ONLY)
-CONFIGURE_FILE(device-certificate-manager-backend.pc.in device-certificate-manager-backend.pc @ONLY)
 
 INSTALL(FILES
        ${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager.pc
        ${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager-ext.pc
-       ${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager-backend.pc
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
diff --git a/pkgconfig/device-certificate-manager-backend.pc.in b/pkgconfig/device-certificate-manager-backend.pc.in
deleted file mode 100644 (file)
index 1a06dab..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-libdir=@CMAKE_INSTALL_FULL_LIBDIR@
-includedir=${prefix}/include
-
-Name: device-certificate-manager-backend
-Description: Device Certificate Manager Backend Package
-Version: @PROJECT_VERSION@
-Requires: protobuf-lite
-Cflags: -I${includedir}/device-certificate-manager-backend
diff --git a/rpm/CMakeLists.txt b/rpm/CMakeLists.txt
deleted file mode 100644 (file)
index 04a2998..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (c) 2019 - 2020 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         rpm/CMakeLists.txt
-# @author       Pawel Kowalski (p.kowalski2@partner.samsung.com)
-#
-
-CONFIGURE_FILE(macros.dcm-backend-api.in macros.dcm-backend-api @ONLY)
-
-INSTALL(FILES
-       ${CMAKE_CURRENT_BINARY_DIR}/macros.dcm-backend-api
-       DESTINATION ${RPM_DIR})
diff --git a/rpm/macros.dcm-backend-api.in b/rpm/macros.dcm-backend-api.in
deleted file mode 100644 (file)
index 31b1f96..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# RPM macros for package device-certificate-manager
-
-%dcm_backend_api() %(echo dcm-backend-api)
index 11dcf633c0b7e9b635f72818bce628264e382937..8767d7c701a676323a537caf36a44db37eef39ef 100644 (file)
@@ -96,7 +96,3 @@ SET_TARGET_PROPERTIES(${TARGET_CLIENT_EXT}
 
 INSTALL(TARGETS ${TARGET_CLIENT} ${TARGET_CLIENT_EXT}
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
-
-INSTALL(FILES
-       ${CMAKE_CURRENT_BINARY_DIR}/dcm_support.pb.h
-       DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/device-certificate-manager-backend)
index 0631d98266458f4884940eacc97ccccec953feb8..f5f568600a879d307cc6ac7af1ca5688a3ebb450 100644 (file)
@@ -30,6 +30,7 @@ FIND_PACKAGE(Boost REQUIRED
 
 PKG_CHECK_MODULES(DAEMON_DEPS
        REQUIRED
+       hal-api-security
        libsystemd
        cynara-client
        cynara-creds-socket
@@ -49,7 +50,6 @@ ADD_EXECUTABLE(${TARGET_DAEMON}
        dcm_session.cpp
        ../shared/protobuf_asio.cpp
        ../shared/log.cpp
-       soresolver.cpp
        ${PROTO_SRCS}
        ${PROTO_HDRS})
 
@@ -63,8 +63,3 @@ TARGET_LINK_LIBRARIES(${TARGET_DAEMON}
 
 INSTALL(TARGETS ${TARGET_DAEMON}
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
-
-INSTALL(FILES
-       dcm-backend-api.h
-       dcm-ext-backend-api.h
-       DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/device-certificate-manager-backend)
diff --git a/src/dcm-daemon/dcm-backend-api.h b/src/dcm-daemon/dcm-backend-api.h
deleted file mode 100644 (file)
index 7ae2ce0..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/******************************************************************
- *
- * Copyright 2019 - 2020 Samsung Electronics All Rights Reserved.
- *
- * Author: Pawel Kowalski <p.kowalski2@partner.samsung.com>
- *
- * 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.
- *
- ******************************************************************/
-
-#ifndef DCM_BACKEND_API_H_
-#define DCM_BACKEND_API_H_
-
-#include "dcm_support.pb.h"
-
-#ifndef API_DCM_BACKEND_EXPORT
-#define API_DCM_BACKEND_EXPORT __attribute__((visibility("default")))
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct dcm_backend_context {
-    void* backend;
-};
-
-API_DCM_BACKEND_EXPORT
-void dcm_backend_create_key_context(dcm_backend_context& ctx,
-                                    const std::string& keyType);
-
-API_DCM_BACKEND_EXPORT
-void dcm_backend_free_key_context(dcm_backend_context& ctx);
-
-API_DCM_BACKEND_EXPORT
-int dcm_backend_request_certificate_chain(dcm_backend_context& ctx,
-                                          std::string& chain);
-
-API_DCM_BACKEND_EXPORT
-int dcm_backend_sign_crypto_data(dcm_backend_context& ctx,
-                                 MessageDigestType digestType,
-                                 const std::string& dataToSign,
-                                 std::string& digestResult);
-
-API_DCM_BACKEND_EXPORT
-CryptoKeyType dcm_backend_key_type(dcm_backend_context& ctx);
-
-API_DCM_BACKEND_EXPORT
-unsigned int dcm_backend_key_length(dcm_backend_context& ctx);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* DCM_BACKEND_API_H_ */
diff --git a/src/dcm-daemon/dcm-ext-backend-api.h b/src/dcm-daemon/dcm-ext-backend-api.h
deleted file mode 100644 (file)
index 6c79749..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/******************************************************************
- *
- * Copyright 2021 Samsung Electronics 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.
- *
- ******************************************************************/
-
-#ifndef DCM_EXT_BACKEND_API_H_
-#define DCM_EXT_BACKEND_API_H_
-
-#ifndef API_DCM_EXT_BACKEND_EXPORT
-#define API_DCM_EXT_BACKEND_EXPORT __attribute__((visibility("default")))
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Calls relevant method/functionality in the backend.
- * Returns 0 in case of success or other code in case of error.
- *
- * If the backend developers wish to return backend-specific
- * error code to the caller that uses the DCM EXT client libary,
- * it should be implemented by returning 0 from function below
- * and returning custom information/data in output_data.
- *
- * This function should not throw exceptions.
- */
-API_DCM_EXT_BACKEND_EXPORT
-int dcm_ext_backend_call_api(const std::string& method_name,
-                             const std::string& input_data,
-                             std::string& output_data);
-
-/*
- * Returns the privilege that should be checked by Cynara in order for
- * DCM daemon to allow a client call to the method_name method/functionality.
- * Can return emtpy string in case no privilege guards access to the method.
- * Returns 0 in case of success or other code in case of error.
- *
- * This function should not throw exceptions.
- *
- * Nonzero error code returned by function will be treated as invalid
- * method name (and returned to DCM EXT client as invalid parameter error).
- */
-API_DCM_EXT_BACKEND_EXPORT
-int dcm_ext_backend_get_api_privilege(const std::string& method_name,
-                                      std::string& privilege);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* DCM_EXT_BACKEND_API_H_ */
index e034eef85a5405abe720f6614b6f6eaa12b9af94..2eb4f120d8ef50e0774b9ae09d69b803223ade6c 100644 (file)
 #include "dcm_session.h"
 #include "log.h"
 
+#include <hal/hal-security-certs.h>
+
 dcm_server::dcm_server(boost::asio::io_service& io_service,
        boost::asio::local::stream_protocol::acceptor&& acceptor) :
                fService(io_service),
                fTimer(io_service),
-               fAcceptor(std::move(acceptor)),
-               fSoResolver(std::make_shared<so_resolver>())
+               fAcceptor(std::move(acceptor))
 {
        LOGD("Construct server object");
 
@@ -47,10 +48,17 @@ dcm_server::dcm_server(boost::asio::io_service& io_service,
                LOGE("Can't initialize Cynara instance: " << error);
                throw std::runtime_error("Can't initialize Cynara instance");
        }
+
+       error = hal_security_certs_get_backend();
+       if (error) {
+               LOGE("Can't get DCM backend: " << error);
+               throw std::runtime_error("Can't get DCM backend");
+       }
 }
 
 dcm_server::~dcm_server()
 {
+       hal_security_certs_put_backend();
        cynara_finish(fCynaraInstance);
        LOGD("Destroy server object");
 }
@@ -86,8 +94,7 @@ void dcm_server::do_accept()
        std::shared_ptr<dcm_session> session;
 
        try {
-               session = std::make_shared<dcm_session>(fService, shared_from_this(),
-                       fSoResolver, fCynaraInstance);
+               session = std::make_shared<dcm_session>(fService, shared_from_this(), fCynaraInstance);
        } catch(std::bad_alloc& ex) {
                LOGE("Out of memory when trying to allocate new session");
                return;
index 128976bea6a0d5d44480157cd2ea924ae48e855e..59cd48e60678b9945f2cd98b655b54d51e12faca 100644 (file)
@@ -27,8 +27,6 @@
 #include <boost/noncopyable.hpp>
 #include <cynara-client.h>
 
-#include "soresolver.h"
-
 class dcm_server final : public boost::noncopyable, public std::enable_shared_from_this<dcm_server> {
 public:
        dcm_server(boost::asio::io_service& io_service,
@@ -44,7 +42,6 @@ private:
        boost::asio::io_service&                                                fService;
        boost::asio::deadline_timer                                             fTimer;
        boost::asio::local::stream_protocol::acceptor   fAcceptor;
-       std::shared_ptr<so_resolver>                                    fSoResolver;
        cynara*                                                                                 fCynaraInstance;
        unsigned int                                                                    fSessionCounter = 0;
 };
index bafed39f0ded243b756c46edbfd1d2a509e9a363..d9c0b20d7c4b796db693889dd035b3df4d173348 100644 (file)
 #include "device_certificate_manager.h"
 #include "log.h"
 
+#include <hal/hal-security-certs.h>
+
 #define DCM_DEFAULT_PRIVILEGE "http://tizen.org/privilege/devicecertificate"
 
+struct string_free_deleter {
+       void operator()(char * p) const {
+               free(p);
+       }
+};
+
+struct data_free_deleter {
+       void operator()(hal_security_certs_data_s* p) const {
+               if (p->buffer)
+                       free(p->buffer);
+               delete p;
+       }
+};
+
+using security_certs_data_ptr = std::unique_ptr<hal_security_certs_data_s, data_free_deleter>;
+
+dcm_error_e backend_to_dcm_error(int error) {
+       switch (error) {
+               case -EINVAL:
+                       return DCM_ERROR_INVALID_PARAMETER;
+               case -ENOMEM:
+                       return DCM_ERROR_OUT_OF_MEMORY;
+               case -EACCES:
+                       return DCM_ERROR_PERMISSION_DENIED;
+               case -ENODATA:
+                       return DCM_ERROR_NO_DATA;
+               default:
+                       return DCM_ERROR_UNKNOWN;
+       }
+}
+
+dcm_ext_error_e backend_to_dcm_ext_error(int error) {
+       switch (error) {
+               case -EINVAL:
+                       return DCM_EXT_ERROR_INVALID_PARAMETER;
+               case -ENOMEM:
+                       return DCM_EXT_ERROR_OUT_OF_MEMORY;
+               case -EACCES:
+                       return DCM_EXT_ERROR_PERMISSION_DENIED;
+               case -ENOTSUP:
+                       return DCM_EXT_ERROR_NOT_SUPPORTED;
+               default:
+                       return DCM_EXT_ERROR_UNKNOWN;
+       }
+}
+
 dcm_session::dcm_session(boost::asio::io_service& io_service,
        const std::shared_ptr<dcm_server>& server,
-       std::shared_ptr<so_resolver> soResolver,
        cynara* cynaraInstance) :
                fSocket(io_service),
                fServer(server),
-               fSoResolver(soResolver),
                fCynaraInstance(cynaraInstance)
 {
        LOGD("Create new session object " << this);
@@ -153,11 +199,12 @@ void dcm_session::reply(const ResponseMessage& resp) noexcept
        }
 }
 
-struct string_free_deleter {
-       void operator()(char * p) const {
-               free(p);
-       }
-};
+template <typename context, typename error>
+void dcm_session::reply_error(ResponseMessage& msg, context& ctx, error err, std::string error_msg) {
+       LOGE(error_msg);
+       ctx->set_result(err);
+       reply(msg);
+}
 
 static inline std::string cynara_error_to_string(int error) {
        char buffer[256];
@@ -227,17 +274,18 @@ void dcm_session::handle_context_association(const AssociateKeyContext& message)
 {
        LOGD("Associate context");
 
-       if(!verify_privileges(fSocket.native_handle(), DCM_DEFAULT_PRIVILEGE)) {
+       if (!verify_privileges(fSocket.native_handle(), DCM_DEFAULT_PRIVILEGE)) {
                LOGE("Client privilege check failure. Disconnect");
                return;
        }
 
+       int error;
        ResponseMessage msg;
        auto* contextResponse = msg.mutable_associate_context();
 
-       if(fBackendContext) {
-               contextResponse->set_result(EEXIST);
-               reply(msg);
+       if (fBackendContext) {
+               reply_error(msg, contextResponse, EEXIST,
+                                       "Backend context already exists");
                return;
        }
 
@@ -245,37 +293,49 @@ void dcm_session::handle_context_association(const AssociateKeyContext& message)
                " with usage " << message.usage() << " and key type " << message.key_type());
 
        auto server = fServer.lock();
-       if(!server) {
+       if (!server) {
                LOGE("Server object gone while handling message");
                return;
        }
 
-       int error = 0;
        try {
-               fBackendContext = std::unique_ptr<dcm_backend_context>(new dcm_backend_context);
-
-               fSoResolver->invoke<void, dcm_backend_context&, const std::string&>(
-                       "dcm_backend_create_key_context", *fBackendContext, message.key_type());
+               fBackendContext = std::unique_ptr<hal_security_certs_context_s>(new hal_security_certs_context_s);
+       } catch (std::bad_alloc&) {
+               reply_error(msg, contextResponse, backend_to_dcm_error(-ENOMEM),
+                                       "Out of memory when allocating memory for backend context");
+               return;
+       }
 
-               CryptoKeyType crypto_key_type = fSoResolver->invoke<CryptoKeyType, dcm_backend_context&>(
-                       "dcm_backend_key_type", *fBackendContext);
-               contextResponse->set_key_type(crypto_key_type);
+       hal_security_certs_data_s key_type_data =
+               {(char*)message.key_type().c_str(), message.key_type().size()};
+       error = hal_security_certs_create_key_context(fBackendContext.get(), key_type_data);
+       if (error) {
+               reply_error(msg, contextResponse, backend_to_dcm_error(error),
+                                       "Creating key context failed");
+               return;
+       }
 
-               unsigned int crypto_key_length = fSoResolver->invoke<unsigned int, dcm_backend_context&>(
-                       "dcm_backend_key_length", *fBackendContext);
-               contextResponse->set_key_length(crypto_key_length);
+       hal_security_certs_crypto_key_type_e key_type;
+       error = hal_security_certs_get_key_type(fBackendContext.get(), &key_type);
+       if (error) {
+               reply_error(msg, contextResponse, backend_to_dcm_error(error),
+                                       "Can't get key type");
+               return;
+       }
+       contextResponse->set_key_type((CryptoKeyType)key_type);
 
-               fCookie = (uintptr_t)fBackendContext.get();
-               contextResponse->set_context_cookie(fCookie);
-       } catch(std::bad_alloc&) {
-               error = -ENOMEM;
-       } catch(std::exception&) {
-               error = -EINVAL;
-       } catch(...) {
-               error = -EFAULT;
+       unsigned int key_length;
+       error = hal_security_certs_get_key_bit_length(fBackendContext.get(), &key_length);
+       if (error) {
+               reply_error(msg, contextResponse, backend_to_dcm_error(error),
+                                       "Can't get key length");
+               return;
        }
 
-       contextResponse->set_result(error);
+       contextResponse->set_key_length(key_length);
+       fCookie = (uintptr_t)fBackendContext.get();
+       contextResponse->set_context_cookie(fCookie);
+       contextResponse->set_result(0);
        reply(msg);
 }
 
@@ -285,50 +345,61 @@ void dcm_session::handle_cert_chain(const RequestCertificateChain& message)
 {
        LOGD("Request certificate chain");
 
-       if(!verify_privileges(fSocket.native_handle(), DCM_DEFAULT_PRIVILEGE)) {
+       if (!verify_privileges(fSocket.native_handle(), DCM_DEFAULT_PRIVILEGE)) {
                LOGE("Client privilege check failure. Disconnect");
                return;
        }
 
+       int error;
        ResponseMessage msg;
        auto* certificateResponse = msg.mutable_request_chain();
 
-       if(message.context_cookie() != fCookie) {
-               LOGE("Received unknown context cookie");
-               certificateResponse->set_result(-EINVAL);
-               reply(msg);
+       if (message.context_cookie() != fCookie) {
+               reply_error(msg, certificateResponse, backend_to_dcm_error(-EINVAL),
+                                       "Received unknown context cookie");
                return;
        }
 
-       if(!fBackendContext) {
-               LOGE("Context not associated with connection");
-               certificateResponse->set_result(-EINVAL);
-               reply(msg);
+       if (!fBackendContext) {
+               reply_error(msg, certificateResponse, backend_to_dcm_error(-EINVAL),
+                                       "Context not associated with connection");
                return;
        }
 
-       std::string cert_chain;
+       try {
+               security_certs_data_ptr cert_chain(new hal_security_certs_data_s);
+               error = hal_security_certs_request_certificate_chain(fBackendContext.get(), cert_chain.get());
+               if (error) {
+                       reply_error(msg, certificateResponse, backend_to_dcm_error(error),
+                                               "Failed requesting certificate chain");
+                       return;
+               }
+
+               if (cert_chain->buffer != NULL && cert_chain->length >= sPEMHeader.length() &&
+                       !memcmp(sPEMHeader.c_str(), cert_chain->buffer, sPEMHeader.size()) &&
+                       cert_chain->buffer[cert_chain->length - 1] != '\0')
+               {
+                       // Add missing 0
+                       char* new_buffer = static_cast<char*>(realloc(cert_chain->buffer, cert_chain->length + 1));
+                       if (new_buffer == NULL) {
+                               reply_error(msg, certificateResponse, backend_to_dcm_error(-ENOMEM),
+                                                       "Failed reallocating memory for certificate chain");
+                               return;
+                       }
 
-       int error = fSoResolver->invoke<int, dcm_backend_context&, std::string&>(
-               "dcm_backend_request_certificate_chain", *fBackendContext, cert_chain);
+                       cert_chain->buffer = new_buffer;
+                       cert_chain->length = cert_chain->length + 1;
+                       strncat(cert_chain->buffer, "\0", 1);
+               }
 
-       if(error != 0) {
-               certificateResponse->set_result(error);
+               *certificateResponse->mutable_cert_chain() = std::string(cert_chain->buffer, cert_chain->length);
+               certificateResponse->set_result(0);
                reply(msg);
+       } catch (std::bad_alloc&) {
+               reply_error(msg, certificateResponse, backend_to_dcm_error(-ENOMEM),
+                                       "Out of memory when allocating memory for output certificate chain");
                return;
        }
-
-       if(cert_chain.length() >= sPEMHeader.length() &&
-               !memcmp(sPEMHeader.c_str(), cert_chain.c_str(), sPEMHeader.size()) &&
-               cert_chain[cert_chain.size() - 1] != '\0')
-       {
-               // Add missing 0
-               cert_chain.push_back(0);
-       }
-
-       *certificateResponse->mutable_cert_chain() = cert_chain;
-       certificateResponse->set_result(0);
-       reply(msg);
 }
 
 int dcm_session::sign_request_check(const SignRequest& message)
@@ -351,86 +422,108 @@ int dcm_session::sign_request_check(const SignRequest& message)
        return true;
 }
 
-int dcm_session::sign(
-       MessageDigestType digest_type,
-       const std::string& message,
-       std::string& signature)
-{
-       return fSoResolver->invoke<int, dcm_backend_context&, MessageDigestType, const std::string&, std::string&>(
-               "dcm_backend_sign_crypto_data", *fBackendContext, digest_type, message, signature);
-}
-
 void dcm_session::handle_sign_request(const SignRequest& message)
 {
        LOGD("Request data signing");
 
-       if(!verify_privileges(fSocket.native_handle(), DCM_DEFAULT_PRIVILEGE)) {
+       if (!verify_privileges(fSocket.native_handle(), DCM_DEFAULT_PRIVILEGE)) {
                LOGE("Client privilege check failure. Disconnect");
                return;
        }
 
-       int ret;
+       int error;
        ResponseMessage msg;
        auto* signingResponse = msg.mutable_sign_data();
-       if (!sign_request_check(message)) {
-               ret = -EINVAL;
-       } else {
-               ret = sign(
-                       message.digest_type(), message.data_to_sign(), *signingResponse->mutable_signature());
-               if (ret != 0)
-                       LOGE("Signing failed");
-       }
-       signingResponse->set_result(ret);
-       reply(msg);
+
+       try {
+               security_certs_data_ptr signature(new hal_security_certs_data_s);
+               if (!sign_request_check(message)) {
+                       reply_error(msg, signingResponse, backend_to_dcm_error(-EINVAL),
+                                               "Sign request check failed");
+                       return;
+               } else {
+                       hal_security_certs_data_s message_data =
+                               {(char*)message.data_to_sign().c_str(), message.data_to_sign().size()};
+                       error = hal_security_certs_sign_crypto_data(fBackendContext.get(),
+                                                                                                               (hal_security_certs_digest_type_e)message.digest_type(),
+                                                                                                               message_data, signature.get());
+                       if (error) {
+                               reply_error(msg, signingResponse, backend_to_dcm_error(error),
+                                                       "Signing failed");
+                               return;
+                       }
+               }
+
+               *signingResponse->mutable_signature() = std::string(signature->buffer, signature->length);
+               signingResponse->set_result(0);
+               reply(msg);
+       } catch (std::bad_alloc&) {
+               reply_error(msg, signingResponse, backend_to_dcm_error(-ENOMEM),
+                                       "Out of memory when allocating memory for output signature");
+               return;
+       }
 }
 
 void dcm_session::handle_ext_call_request(const ExtCallRequest& message)
 {
        LOGD("Request EXT API call from backend");
+
+       int error;
        ResponseMessage msg;
        auto* extCallResponse = msg.mutable_ext_call();
-       std::string privilege;
 
        try {
-               if(fSoResolver->invoke<int, const std::string&, std::string&>(
-                               "dcm_ext_backend_get_api_privilege", message.method_name(), privilege)) {
-                       LOGE("Invalid method name for EXT API call - method name: " << message.method_name());
-                       extCallResponse->set_result(DCM_EXT_ERROR_INVALID_PARAMETER);
-                       reply(msg);
+               hal_security_certs_data_s method_name =
+                       {(char*)message.method_name().c_str(), message.method_name().size()};
+               security_certs_data_ptr privilege(new hal_security_certs_data_s{nullptr, 0});
+
+               error = hal_security_certs_ext_get_api_privilege(method_name, privilege.get());
+               if (error == -EINVAL) {
+                       reply_error(msg, extCallResponse, backend_to_dcm_ext_error(error),
+                                               "Invalid method name for EXT API call - method name: " + message.method_name());
+                       return;
+               } else if (error == -ENOTSUP) {
+                       reply_error(msg, extCallResponse, backend_to_dcm_ext_error(error),
+                                               "Couldn't call backend EXT API - backend doesn't support this functionality");
                        return;
                }
-       } catch (std::runtime_error&) {
-               LOGE("Couldn't call backend EXT API - backend doesn't support this functionality");
-               extCallResponse->set_result(DCM_EXT_ERROR_NOT_SUPPORTED);
-               reply(msg);
-               return;
-       }
 
-       if(!privilege.empty()) {
-               if(!verify_privileges(fSocket.native_handle(), privilege.c_str())) {
-                       LOGE("Client privilege check failure - access denied for method " << message.method_name()
-                       << " and privilege " << privilege);
-                       extCallResponse->set_result(DCM_EXT_ERROR_PERMISSION_DENIED);
-                       reply(msg);
-                       return;
+               if (privilege->buffer != NULL) {
+                       std::string privilegeStr(privilege->buffer, privilege->length);
+                       if (!verify_privileges(fSocket.native_handle(), privilegeStr.c_str())) {
+                               reply_error(msg, extCallResponse, DCM_EXT_ERROR_PERMISSION_DENIED,
+                                                       "Client privilege check failure - access denied for method " +
+                                                       message.method_name() + " and privilege " + privilegeStr);
+                               return;
+                       }
+               } else {
+                       LOGD("Access to method " << message.method_name()  << "  granted, no privilege check required");
                }
-       } else {
-               LOGD("Access to method " << message.method_name()  << "  granted, no privilege check required");
-       }
 
-       try {
-               int error = fSoResolver->invoke<int, const std::string&, const std::string&, std::string&>(
-                               "dcm_ext_backend_call_api", message.method_name(), message.input_data(), *extCallResponse->mutable_output_data());
+               hal_security_certs_data_s input_data =
+                       {(char*)message.input_data().c_str(), message.input_data().size()};
+               security_certs_data_ptr output_data(new hal_security_certs_data_s{nullptr, 0});
 
-               if(error) {
-                       LOGE("Error in dcm_ext_backend_call_api for method " << message.method_name() << " , error: " << error);
+               error = hal_security_certs_ext_call_api(method_name, input_data, output_data.get());
+               if (error == -EINVAL) {
+                       reply_error(msg, extCallResponse, backend_to_dcm_ext_error(error),
+                                               "Error in hal_security_certs_ext_call_api for method " +
+                                               message.method_name() + " , error: " + std::to_string(error));
+                       return;
+               } else if (error == -ENOTSUP) {
+                       reply_error(msg, extCallResponse, backend_to_dcm_ext_error(error),
+                                               "Couldn't call backend EXT API - backend doesn't support this functionality");
+                       return;
+               } else {
+                       *extCallResponse->mutable_output_data() = std::string(output_data->buffer, output_data->length);
+                       extCallResponse->set_result(0);
                }
-               extCallResponse->set_result(error ? DCM_EXT_ERROR_UNKNOWN : DCM_EXT_ERROR_NONE);
-       } catch (std::runtime_error&) {
-               LOGE("Couldn't call backend EXT API - backend doesn't support this functionality");
-               extCallResponse->set_result(DCM_EXT_ERROR_NOT_SUPPORTED);
+
+               reply(msg);
+       } catch (std::bad_alloc&) {
+               reply_error(msg, extCallResponse, backend_to_dcm_ext_error(-ENOMEM),
+                                       "Out of memory when allocating memory for output data");
        }
-       reply(msg);
 }
 
 void dcm_session::handle_close_context(const CloseKeyContext& message)
@@ -446,31 +539,17 @@ void dcm_session::handle_close_context(const CloseKeyContext& message)
        auto* closeResponse = msg.mutable_close_context();
 
        if(message.context_cookie() != fCookie) {
-               LOGE("Received unknown context cookie");
-               closeResponse->set_result(-EINVAL);
-               reply(msg);
+               reply_error(msg, closeResponse, backend_to_dcm_error(-EINVAL),
+                                       "Received unknown context cookie");
                return;
        }
 
        if(!fBackendContext) {
-               LOGE("Context not associated with connection");
-               closeResponse->set_result(-EINVAL);
-               reply(msg);
+               reply_error(msg, closeResponse, backend_to_dcm_error(-EINVAL),
+                                       "Context not associated with connection");
                return;
        }
 
-       int error = 0;
-       try {
-               fSoResolver->invoke<void, dcm_backend_context&>(
-                       "dcm_backend_free_key_context", *fBackendContext);
-       } catch(std::bad_alloc&) {
-               error = -ENOMEM;
-       } catch(std::exception&) {
-               error = -EINVAL;
-       } catch(...) {
-               error = -EFAULT;
-       }
-
-       closeResponse->set_result(error);
+       closeResponse->set_result(hal_security_certs_free_key_context(fBackendContext.get()));
        reply(msg);
 }
index 8b63e45c40b8361867d595a0649fbddcd712ca64..64fa34462aa512ad80c64d13dbc5b98772978a14 100644 (file)
@@ -30,8 +30,8 @@
 
 #include "dcm_support.pb.h"
 #include "protobuf_asio.h"
-#include "dcm-backend-api.h"
-#include "soresolver.h"
+
+#include <hal/hal-security-certs-types.h>
 
 class dcm_server;
 
@@ -40,7 +40,6 @@ class dcm_session final : public std::enable_shared_from_this<dcm_session>, publ
 public:
        dcm_session(boost::asio::io_service& io_service,
                const std::shared_ptr<dcm_server>& server,
-               std::shared_ptr<so_resolver> soResolver,
                cynara* cynaraInstance);
        ~dcm_session();
 
@@ -63,16 +62,17 @@ private:
        void handle_ext_call_request(const ExtCallRequest& message);
        void handle_close_context(const CloseKeyContext& message);
 
-       int sign(MessageDigestType digest_type, const std::string& message, std::string& signature);
        int sign_request_check(const SignRequest& message);
 
+       template <typename context, typename error>
+       void reply_error(ResponseMessage& msg, context& ctx, error err, std::string error_msg);
+
 private:
        boost::asio::local::stream_protocol::socket             fSocket;
        protobuf_async_message_serialization                    fSerializer;
        protobuf_async_message_deserialization                  fDeserializer;
        std::weak_ptr<dcm_server>                                               fServer;
-       std::shared_ptr<dcm_backend_context>                    fBackendContext;
-       std::shared_ptr<so_resolver>                                    fSoResolver;
+       std::shared_ptr<hal_security_certs_context_s>   fBackendContext;
        uint64_t                                                                                fCookie = 0;
        cynara*                                                                                 fCynaraInstance;
 };
diff --git a/src/dcm-daemon/soresolver.cpp b/src/dcm-daemon/soresolver.cpp
deleted file mode 100644 (file)
index 68ac0d8..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved.
- *
- * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
- *
- * 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.
- *
- ******************************************************************/
-
-#include <dlfcn.h>
-
-#include "soresolver.h"
-#include "log.h"
-
-so_resolver::so_resolver()
-{
-       LOGD("Loading library " << fLibraryName);
-
-       fLibraryHandle = dlopen(fLibraryName.c_str(), RTLD_LAZY | RTLD_LOCAL);
-       if(!fLibraryHandle) {
-               LOGE("Unable to load library " << fLibraryName << ": " << dlerror());
-               throw std::runtime_error("Unable to load backend");
-       }
-
-       LOGD("Library loaded " << fLibraryName);
-}
-
-so_resolver::~so_resolver()
-{
-       LOGD("Unloading library " << fLibraryName);
-       dlclose(fLibraryHandle);
-       LOGD("Unloaded library " << fLibraryName);
-}
-
-void* so_resolver::resolve_function(const std::string& name) noexcept
-{
-       LOGD("Resolving symbol " << name << " from " << fLibraryName);
-       void* sym = dlsym(fLibraryHandle, name.c_str());
-       if(!sym) {
-               LOGE("Unable to resolve symbol " << name << " from " << fLibraryName << ": Error is " << dlerror());
-       }
-       return sym;
-}
diff --git a/src/dcm-daemon/soresolver.h b/src/dcm-daemon/soresolver.h
deleted file mode 100644 (file)
index 47a2574..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved.
- *
- * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
- *
- * 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.
- *
- ******************************************************************/
-
-#ifndef DCM_DAEMON_SORESOLVER_H_
-#define DCM_DAEMON_SORESOLVER_H_
-
-#include <string>
-#include <stdexcept>
-
-#include <boost/noncopyable.hpp>
-
-#define DCM_BACKEND "libdcm-backend-api.so"
-
-class so_resolver : public boost::noncopyable {
-public:
-       so_resolver();
-       ~so_resolver();
-
-       void* resolve_function(const std::string& name) noexcept;
-
-       template<typename ReturnValue, typename... Args> ReturnValue invoke(const std::string& name, Args... args) {
-               typedef ReturnValue (* function_t)(Args...);
-               function_t func = (function_t)resolve_function(name);
-               if(!func) {
-                       throw std::runtime_error("Trying to call unresolved function");
-               }
-               return func(args...);
-       }
-
-private:
-       std::string     fLibraryName = DCM_BACKEND;
-       void*           fLibraryHandle = nullptr;
-};
-
-#endif /* DCM_DAEMON_SORESOLVER_H_ */
index 94f8528dc194196bbd3dbe8e4889391e64b883ce..aba8d2d0936a4ba26542d91616d059d1d5e98675 100644 (file)
@@ -30,7 +30,7 @@ extern "C" {
 
 /**
  * @platform
- * @brief Calls dcm_ext_backend_call_api in the DCM backend with specified method name & arguments.
+ * @brief Calls hal_security_certs_ext_call_api in the DCM backend with specified method name & arguments.
  * @since_tizen 6.5
  * @privlevel platform
  * @privilege custom one, defined by the backend for given method call