Move all sources to src/ directory 78/234778/9
authorDariusz Michaluk <d.michaluk@samsung.com>
Thu, 28 May 2020 12:20:57 +0000 (14:20 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Mon, 6 Jul 2020 09:59:38 +0000 (11:59 +0200)
Change-Id: I0ffe64f5cc8b3591d1951503f46011173f173ab3

51 files changed:
CMakeLists.txt
README.md
dcm-client/CMakeLists.txt [deleted file]
dcm-client/dcm_client.h [deleted file]
dcm-client/dcm_client_p.h [deleted file]
dcm-client/dcm_support.proto [deleted file]
dcm-client/dcmclient.cpp [deleted file]
dcm-client/device_certificate_manager.cpp [deleted file]
dcm-client/device_certificate_manager.h [deleted file]
dcm-client/version_script.lds [deleted file]
dcm-daemon/CMakeLists.txt [deleted file]
dcm-daemon/boost_log_dlog_sink.h [deleted file]
dcm-daemon/dcm-backend-api.h [deleted file]
dcm-daemon/dcmserver.cpp [deleted file]
dcm-daemon/dcmserver.h [deleted file]
dcm-daemon/dcmsession.cpp [deleted file]
dcm-daemon/dcmsession.h [deleted file]
dcm-daemon/exception_translator.h [deleted file]
dcm-daemon/logging.h [deleted file]
dcm-daemon/main.cpp [deleted file]
dcm-daemon/serviceadapter.cpp [deleted file]
dcm-daemon/serviceadapter.h [deleted file]
dcm-daemon/soresolver.cpp [deleted file]
dcm-daemon/soresolver.h [deleted file]
shared/protobuf_asio.cpp [deleted file]
shared/protobuf_asio.h [deleted file]
src/dcm-client/CMakeLists.txt [new file with mode: 0644]
src/dcm-client/dcm_client.h [new file with mode: 0644]
src/dcm-client/dcm_client_p.h [new file with mode: 0644]
src/dcm-client/dcm_support.proto [new file with mode: 0644]
src/dcm-client/dcmclient.cpp [new file with mode: 0644]
src/dcm-client/device_certificate_manager.cpp [new file with mode: 0644]
src/dcm-client/device_certificate_manager.h [new file with mode: 0644]
src/dcm-client/version_script.lds [new file with mode: 0644]
src/dcm-daemon/CMakeLists.txt [new file with mode: 0644]
src/dcm-daemon/boost_log_dlog_sink.h [new file with mode: 0644]
src/dcm-daemon/dcm-backend-api.h [new file with mode: 0644]
src/dcm-daemon/dcmserver.cpp [new file with mode: 0644]
src/dcm-daemon/dcmserver.h [new file with mode: 0644]
src/dcm-daemon/dcmsession.cpp [new file with mode: 0644]
src/dcm-daemon/dcmsession.h [new file with mode: 0644]
src/dcm-daemon/exception_translator.h [new file with mode: 0644]
src/dcm-daemon/logging.h [new file with mode: 0644]
src/dcm-daemon/main.cpp [new file with mode: 0644]
src/dcm-daemon/serviceadapter.cpp [new file with mode: 0644]
src/dcm-daemon/serviceadapter.h [new file with mode: 0644]
src/dcm-daemon/soresolver.cpp [new file with mode: 0644]
src/dcm-daemon/soresolver.h [new file with mode: 0644]
src/shared/protobuf_asio.cpp [new file with mode: 0644]
src/shared/protobuf_asio.h [new file with mode: 0644]
tests/CMakeLists.txt

index 4c7e341358e1b89813d225760afab1f1b428cfb6..8c02f4e69b40abc40dcb6c801419e3dff4bd3c0c 100644 (file)
@@ -42,9 +42,9 @@ SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
 SET(DCM_UNIX_SOCKET_PATH "/run/device-certificate-manager.socket")
 ADD_DEFINITIONS(-DDCM_UNIX_SOCKET_PATH="${DCM_UNIX_SOCKET_PATH}")
 
-INCLUDE_DIRECTORIES(shared)
-ADD_SUBDIRECTORY(dcm-client)
-ADD_SUBDIRECTORY(dcm-daemon)
+INCLUDE_DIRECTORIES(src/shared)
+ADD_SUBDIRECTORY(src/dcm-client)
+ADD_SUBDIRECTORY(src/dcm-daemon)
 ADD_SUBDIRECTORY(pkgconfig)
 ADD_SUBDIRECTORY(rpm)
 ADD_SUBDIRECTORY(systemd)
index 7990f6e47f0bb6f13f0354db2c0b4fa3c4a6824a..f684e22e39624cf00569a3eb8fb2381559cd9c16 100644 (file)
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ Please visit the following webpage for the details about the prerequsities and t
 
 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 *dcm-daemon/dcm-backend-api.h* header file).
+The implementation is realized with the internal backend API (see the *src/dcm-daemon/dcm-backend-api.h* header file).
 Example implementations 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 two implementations:
 1) dedicated for the KONAI SE device,
@@ -32,7 +32,7 @@ The difference in the cerificates ordering is the reason why the *backend* level
 
 ##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 (*dcm-daemon/dcm-backend-api.h*).
+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 KONAI SE implementation from the *platform/core/security/device-certificate-manager-backend* 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.
diff --git a/dcm-client/CMakeLists.txt b/dcm-client/CMakeLists.txt
deleted file mode 100644 (file)
index ac78ed7..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (c) 2017 - 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        dcm-client/CMakeLists.txt
-# @author      Dariusz Michaluk <d.michaluk@samsung.com>
-# @author      Jaroslaw Pelczar <j.pelczar@samsung.com>
-
-FIND_PACKAGE(Threads REQUIRED)
-FIND_PACKAGE(Protobuf REQUIRED)
-
-FIND_LIBRARY(MBEDTLS_LIB mbedtls)
-
-FIND_PACKAGE(Boost REQUIRED
-       COMPONENTS
-       system)
-
-PKG_CHECK_MODULES(CLIENT_DEPS REQUIRED dlog)
-
-INCLUDE_DIRECTORIES(SYSTEM ${CLIENT_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
-LINK_DIRECTORIES(${CLIENT_DEPS_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS})
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
-
-PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS dcm_support.proto)
-
-SET(TARGET_CLIENT "device-certificate-manager")
-ADD_LIBRARY(${TARGET_CLIENT}
-       SHARED
-       dcmclient.cpp
-       device_certificate_manager.cpp
-       ../shared/protobuf_asio.cpp
-       ${PROTO_SRCS}
-       ${PROTO_HDRS})
-
-TARGET_LINK_LIBRARIES(${TARGET_CLIENT}
-       ${Boost_SYSTEM_LIBRARY}
-       ${PROTOBUF_LITE_LIBRARIES}
-       ${MBEDTLS_LIB}
-       ${CLIENT_DEPS_LIBRARIES}
-       ${CMAKE_THREAD_LIBS_INIT})
-
-SET_PROPERTY(TARGET ${TARGET_CLIENT} APPEND PROPERTY LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version_script.lds")
-SET_TARGET_PROPERTIES(${TARGET_CLIENT}
-       PROPERTIES
-       VERSION ${PROJECT_VERSION}
-       DEFINE_SYMBOL DEVICE_CERTIFICATE_MANAGER_EXPORT
-       VISIBILITY_INLINES_HIDDEN TRUE
-       C_VISIBILITY_PRESET hidden
-       CXX_VISIBILITY_PRESET hidden)
-
-INSTALL(TARGETS ${TARGET_CLIENT}
-       LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
-
-INSTALL(FILES
-       device_certificate_manager.h
-       DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/device-certificate-manager)
-
-INSTALL(FILES
-       ${CMAKE_CURRENT_BINARY_DIR}/dcm_support.pb.h
-       DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/device-certificate-manager-backend)
diff --git a/dcm-client/dcm_client.h b/dcm-client/dcm_client.h
deleted file mode 100644 (file)
index bd6ce70..0000000
+++ /dev/null
@@ -1,80 +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_CLIENT_DCM_CLIENT_H_
-#define DCM_CLIENT_DCM_CLIENT_H_
-
-#include <mbedtls/md.h>
-
-#include <memory>
-#include <vector>
-
-class dcm_client_connection :
-       public std::enable_shared_from_this<dcm_client_connection>
-{
-private:
-       dcm_client_connection(const dcm_client_connection&) = delete;
-       dcm_client_connection& operator = (const dcm_client_connection&) = delete;
-
-protected:
-       dcm_client_connection();
-       ~dcm_client_connection();
-
-public:
-       /*!
-        * Initialize default instance of the client connection.
-        *
-        * Standard C++ exceptions may be thrown in case of error
-        */
-       static std::shared_ptr<dcm_client_connection> create();
-
-       /*!
-        * Associate key context with this object. This function can be called
-        * only once. This function doesn't throw any exceptions.
-        */
-       virtual bool create_context(const std::string& serviceName,
-                       const std::string& usage,
-                       const std::string& key_type) noexcept = 0;
-
-
-       /*!
-        * Request certificate chain associated with this context
-        */
-       virtual int get_certificate_chain(std::vector<uint8_t>& chain) noexcept = 0;
-
-       /*!
-        * Return name of key type (UNKNOWN, RSA or ECDSA for now)
-        */
-       virtual const std::string& key_type() const noexcept = 0;
-
-       /*!
-        * Return length of the crypto key in bits
-        */
-       virtual unsigned int key_length() const noexcept = 0;
-
-       /*!
-        * Sign data with context certificate
-        */
-       virtual int sign_data(mbedtls_md_type_t digestType,
-                               const void * hash_data, size_t hash_size,
-                               std::vector<uint8_t>& digest) noexcept = 0;
-};
-
-#endif /* DCM_CLIENT_DCM_CLIENT_H_ */
diff --git a/dcm-client/dcm_client_p.h b/dcm-client/dcm_client_p.h
deleted file mode 100644 (file)
index 9fe1749..0000000
+++ /dev/null
@@ -1,67 +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_CLIENT_DCM_CLIENT_P_H_
-#define DCM_CLIENT_DCM_CLIENT_P_H_
-
-#include "dcm_client.h"
-#include "dcm_support.pb.h"
-#include <memory>
-#include <mutex>
-#include <array>
-#include <boost/asio.hpp>
-
-class dcm_client_connection_impl final : public dcm_client_connection
-{
-public:
-       dcm_client_connection_impl();
-       dcm_client_connection_impl(boost::asio::io_service& ioService);
-       virtual ~dcm_client_connection_impl();
-
-       bool create_context(const std::string& serviceName,
-                       const std::string& usage,
-                       const std::string& key_type) noexcept override;
-
-       int get_certificate_chain(std::vector<uint8_t>& chain) noexcept override;
-
-       const std::string& key_type() const noexcept override;
-
-       unsigned int key_length() const noexcept override;
-
-       int sign_data(mbedtls_md_type_t digestType,
-                                       const void * hash_data, size_t hash_size,
-                                       std::vector<uint8_t>& digest) noexcept override;
-
-       void sendReceive(RequestMessage& request, ResponseMessage& response);
-
-private:
-       void ensureSocketConnected();
-
-
-private:
-       boost::asio::io_service                 fIOService;
-       std::mutex                                              fLock;
-       uint64_t                                                fCookie = 0;
-       std::unique_ptr<boost::asio::local::stream_protocol::socket> fSocket;
-       CryptoKeyType                                   fKeyType = CRYPTO_KEY_TYPE_INVALID;
-       unsigned int                                    fKeyLength = 0;
-};
-
-#endif /* DCM_CLIENT_DCM_CLIENT_P_H_ */
diff --git a/dcm-client/dcm_support.proto b/dcm-client/dcm_support.proto
deleted file mode 100644 (file)
index 4adc4cf..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-syntax = "proto2";
-option optimize_for = LITE_RUNTIME;
-
-/*
- * Type of the crypto key
- */
-enum CryptoKeyType {
-       CRYPTO_KEY_TYPE_INVALID = 0;
-       CRYPTO_KEY_TYPE_ECDSA = 1;
-       CRYPTO_KEY_TYPE_RSA = 2;
-}
-
-/*
- * These values match the mbedtls ones
- */
-enum MessageDigestType {
-    MD_NONE = 0;
-    MD_MD2 = 1;
-    MD_MD4 = 2;
-    MD_MD5 = 3;
-    MD_SHA1 = 4;
-    MD_SHA224 = 5;
-    MD_SHA256 = 6;
-    MD_SHA384 = 7;
-    MD_SHA512 = 8;
-    MD_RIPEMD160 = 9;
-}
-
-message AssociateKeyContext
-{
-               required string service = 1;
-               required string usage = 2;
-               required string key_type = 3;
-}
-
-message AssociateKeyContextResponse
-{
-               required int32 result = 1;
-               optional uint64 context_cookie = 2;
-               optional CryptoKeyType key_type = 3;
-               optional uint32 key_length = 4;
-}
-
-message RequestCertificateChain
-{
-               required uint64 context_cookie = 1;
-}
-
-message RequestCertificateChainResponse
-{
-               required int32 result = 1;
-               optional bytes cert_chain = 2;
-}
-
-message SignRequest
-{
-               required uint64 context_cookie = 1;
-               required bytes data_to_sign = 2;
-               required MessageDigestType digest_type = 3;
-}
-
-message SignResponse
-{
-               required int32 result = 1;
-               optional bytes signature = 2;
-}
-
-message RequestMessage {
-       oneof request_oneof {
-               AssociateKeyContext                     associate_context = 1;
-               RequestCertificateChain         request_chain = 2;
-               SignRequest                                     sign_data = 3;
-       }
-}
-
-message ResponseMessage {
-       oneof reply_oneof {
-               AssociateKeyContextResponse             associate_context = 1;
-               RequestCertificateChainResponse request_chain = 2;
-               SignResponse                                    sign_data = 3;
-       }
-}
diff --git a/dcm-client/dcmclient.cpp b/dcm-client/dcmclient.cpp
deleted file mode 100644 (file)
index 322420b..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2020 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.
- *
- ******************************************************************/
-
-#include "dcm_client_p.h"
-#include "dcm_support.pb.h"
-#include "device_certificate_manager.h"
-#include <cassert>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/io/coded_stream.h>
-#include "protobuf_asio.h"
-#include <inttypes.h>
-#include <mbedtls/ssl.h>
-
-#define LOG_TAG                "DCM_CLIENT"
-#include <dlog.h>
-
-static_assert(MD_NONE == (unsigned int)MBEDTLS_MD_NONE, "MBEDTLS_MD_NONE mismatch");
-static_assert(MD_MD2 == (unsigned int)MBEDTLS_MD_MD2, "MBEDTLS_MD_MD2 mismatch");
-static_assert(MD_MD4 == (unsigned int)MBEDTLS_MD_MD4, "MBEDTLS_MD_MD4 mismatch");
-static_assert(MD_MD5 == (unsigned int)MBEDTLS_MD_MD5, "MBEDTLS_MD_MD5 mismatch");
-static_assert(MD_SHA1 == (unsigned int)MBEDTLS_MD_SHA1, "MBEDTLS_MD_SHA1 mismatch");
-static_assert(MD_SHA224 == (unsigned int)MBEDTLS_MD_SHA224, "MBEDTLS_MD_SHA224 mismatch");
-static_assert(MD_SHA256 == (unsigned int)MBEDTLS_MD_SHA256, "MBEDTLS_MD_SHA256 mismatch");
-static_assert(MD_SHA384 == (unsigned int)MBEDTLS_MD_SHA384, "MBEDTLS_MD_SHA384 mismatch");
-static_assert(MD_SHA512 == (unsigned int)MBEDTLS_MD_SHA512, "MBEDTLS_MD_SHA512 mismatch");
-static_assert(MD_RIPEMD160 == (unsigned int)MBEDTLS_MD_RIPEMD160, "MBEDTLS_MD_RIPEMD160 mismatch");
-
-static std::string sKeyTypeUnknown("UNKNOWN");
-static std::string sKeyTypeRSA("RSA");
-static std::string sKeyTypeECDSA("ECDSA");
-
-dcm_client_connection_impl::dcm_client_connection_impl()
-{
-}
-
-dcm_client_connection_impl::~dcm_client_connection_impl()
-{
-}
-
-dcm_client_connection::dcm_client_connection()
-{
-}
-
-dcm_client_connection::~dcm_client_connection()
-{
-}
-
-std::shared_ptr<dcm_client_connection> dcm_client_connection::create()
-{
-       return std::make_shared<dcm_client_connection_impl>();
-}
-
-void dcm_client_connection_impl::sendReceive(RequestMessage& request, ResponseMessage& response)
-{
-       protobuf_sync_message_serialization(*fSocket).encodeMessage(request);
-       protobuf_sync_message_deserialization(*fSocket).decodeMessage(response);
-}
-
-bool dcm_client_connection_impl::create_context(const std::string& serviceName,
-               const std::string& usage,
-               const std::string& key_type) noexcept
-{
-       std::lock_guard<std::mutex> locker(fLock);
-
-       if(fCookie) {
-               LOGE("%s: Cookie has already been requested for session %p", __FUNCTION__, this);
-               // Already created
-               return false;
-       }
-
-       if(!fSocket) {
-               try {
-                       ensureSocketConnected();
-               } catch(std::exception& ex) {
-                       LOGE("%s: Caught exception \"%s\" when connecting socket for session %p", __FUNCTION__, ex.what(), this);
-                       return false;
-               } catch(...) {
-                       LOGE("%s: Caught unknown exception when connecting socket for session %p", __FUNCTION__, this);
-                       return false;
-               }
-       }
-
-       try {
-               RequestMessage request;
-               ResponseMessage response;
-
-               auto * assoc_req = request.mutable_associate_context();
-
-               assoc_req->set_service(serviceName);
-               assoc_req->set_usage(usage);
-               assoc_req->set_key_type(key_type);
-
-               sendReceive(request, response);
-
-               if(!response.has_associate_context()) {
-                       LOGE("%s: received response is not context association message in context %p", __FUNCTION__, this);
-                       return false;
-               }
-
-               auto& assoc_message(response.associate_context());
-
-               if(assoc_message.result() != 0) {
-                       LOGE("%s: Received context association message with error %d in %p", __FUNCTION__, assoc_message.result(), this);
-                       return false;
-               }
-
-               fCookie = assoc_message.context_cookie();
-               fKeyType = assoc_message.key_type();
-               fKeyLength = assoc_message.key_length();
-       } catch(std::exception& ex) {
-               LOGE("%s: Caught exception \"%s\" when establishing cookie for session %p", __FUNCTION__, ex.what(), this);
-               fSocket.reset();
-               return false;
-       } catch(...) {
-               LOGE("%s: Caught unknown exception when establishing cookie for session %p", __FUNCTION__, this);
-               fSocket.reset();
-               return false;
-       }
-
-       return true;
-}
-
-void dcm_client_connection_impl::ensureSocketConnected()
-{
-       fSocket.reset(new boost::asio::local::stream_protocol::socket(fIOService));
-       boost::asio::local::stream_protocol::endpoint endpoint(DCM_UNIX_SOCKET_PATH);
-       fSocket->connect(endpoint);
-}
-
-int dcm_client_connection_impl::get_certificate_chain(std::vector<uint8_t>& chain) noexcept
-{
-       std::lock_guard<std::mutex> locker(fLock);
-
-       if(!fCookie) {
-               LOGE("%s: Trying to request certificate in session %p without connection", __FUNCTION__, this);
-               return DCM_ERROR_INVALID_PARAMETER;
-       }
-
-       try {
-               RequestMessage request;
-               ResponseMessage response;
-
-               auto * cert_req  = request.mutable_request_chain();
-
-               cert_req->set_context_cookie(fCookie);
-
-               sendReceive(request, response);
-
-               if(!response.has_request_chain()) {
-                       LOGE("%s: Response from server is not certificate chain response on session %p", __FUNCTION__, this);
-                       return DCM_ERROR_NO_DATA;
-               }
-
-               auto& cert_resp(response.request_chain());
-
-               if(cert_resp.result() != 0) {
-                       LOGE("%s: Server can't respond with certificate chain: error %d in session %p", __FUNCTION__,
-                                       cert_resp.result(), this);
-                       return DCM_ERROR_NO_DATA;
-               }
-
-               if(cert_resp.cert_chain().size() == 0) {
-                       LOGE("%s: Server can't respond with certificate chain: certificate empty", __FUNCTION__);
-                       return DCM_ERROR_NO_DATA;
-               }
-
-               // Add space for last zero byte if needed
-               chain.reserve(cert_resp.cert_chain().size() + 1);
-               chain.resize(cert_resp.cert_chain().size());
-
-               memcpy(&chain[0], cert_resp.cert_chain().c_str(), cert_resp.cert_chain().size());
-
-               if(chain[chain.size() - 1] != 0) {
-                       // Pad with zero
-                       chain.push_back(0);
-               }
-       } catch(std::bad_alloc&) {
-               LOGE("%s: Out of memory when requesting certificate for session %p", __FUNCTION__, this);
-               return DCM_ERROR_OUT_OF_MEMORY;
-       } catch(std::invalid_argument&) {
-               LOGE("%s: Invalid argument passed for certificate request for session %p", __FUNCTION__, this);
-               return DCM_ERROR_INVALID_PARAMETER;
-       } catch(std::exception& ex) {
-               LOGE("%s: When requesting certificate for session %p received exception : %s", __FUNCTION__, this, ex.what());
-               return DCM_ERROR_UNKNOWN;
-       } catch(...) {
-               LOGE("%s: When requesting certificate for session %p received exception : %s", __FUNCTION__, this, "Unknown error");
-               return DCM_ERROR_UNKNOWN;
-       }
-
-       return DCM_ERROR_NONE;
-}
-
-const std::string& dcm_client_connection_impl::key_type() const noexcept {
-       switch(fKeyType) {
-       case CRYPTO_KEY_TYPE_RSA: return sKeyTypeRSA;
-       case CRYPTO_KEY_TYPE_ECDSA: return sKeyTypeECDSA;
-       default: return sKeyTypeUnknown;
-       }
-}
-
-int dcm_client_connection_impl::sign_data(mbedtls_md_type_t digestType, const void * hash_data,
-               size_t hash_size, std::vector<uint8_t>& digest) noexcept
-{
-       std::lock_guard<std::mutex> locker(fLock);
-
-       if(!fCookie) {
-               LOGE("%s: Trying to request data signing in object %p but there is no connection", __FUNCTION__, this);
-               return DCM_ERROR_SOCKET;
-       }
-
-       /*
-        * If hash_size == 0 then hash type must be known
-        */
-       if(hash_size == 0) {
-               if(digestType == MBEDTLS_MD_NONE) {
-                       LOGE("%s: Digest type is NONE and hash size is 0", __FUNCTION__);
-                       return DCM_ERROR_INVALID_PARAMETER;
-               }
-
-               const mbedtls_md_info_t * md_info = mbedtls_md_info_from_type(digestType);
-
-               if(!md_info) {
-                       LOGE("%s: Can't find hash data for digest type %d", __FUNCTION__, digestType);
-                       return DCM_ERROR_INVALID_PARAMETER;
-               }
-
-               hash_size = mbedtls_md_get_size(md_info);
-       } else if(hash_size != 0 && digestType != MBEDTLS_MD_NONE) {
-               /*
-                * If hash_size != 0 then hash type can be specified
-                */
-               const mbedtls_md_info_t * md_info = mbedtls_md_info_from_type(digestType);
-
-               if(!md_info) {
-                       LOGE("%s: Can't find hash data for digest type %d", __FUNCTION__, digestType);
-                       return DCM_ERROR_INVALID_PARAMETER;
-               }
-
-               if(hash_size != mbedtls_md_get_size(md_info)) {
-                       LOGE("%s: Hash size mismatch. Expected %zd but got %zd", __FUNCTION__, hash_size, (size_t)mbedtls_md_get_size(md_info));
-                       return DCM_ERROR_INVALID_PARAMETER;
-               }
-       }
-
-       try {
-               RequestMessage request;
-               ResponseMessage response;
-
-               auto * sign_req  = request.mutable_sign_data();
-
-               sign_req->set_context_cookie(fCookie);
-               sign_req->set_data_to_sign(hash_data, hash_size);
-               sign_req->set_digest_type(static_cast<MessageDigestType>(digestType));
-
-               sendReceive(request, response);
-
-               if(!response.has_sign_data()) {
-                       LOGE("%s: Response for hash signature has no signature data", __FUNCTION__);
-                       return DCM_ERROR_INVALID_PARAMETER;
-               }
-
-               auto& sign_resp(response.sign_data());
-
-               if(sign_resp.result() != 0) {
-                       LOGE("%s: Signature request for session %p received error %d", __FUNCTION__, this, sign_resp.result());
-                       return DCM_ERROR_INVALID_PARAMETER;
-               }
-
-               const auto& signature = sign_resp.signature();
-
-               if(signature.empty()) {
-                       LOGE("%s: Received signature object is empty for session %p", __FUNCTION__, this);
-                       return DCM_ERROR_INVALID_PARAMETER;
-               }
-
-               digest.resize(signature.size());
-               memcpy(&digest[0], signature.c_str(), signature.size());
-       } catch(std::bad_alloc&) {
-               LOGE("%s: Out of memory when processing sign request for session %p", __FUNCTION__, this);
-               return DCM_ERROR_OUT_OF_MEMORY;
-       } catch(...) {
-               LOGE("%s: When processing signature for session %p got exception : %s", __FUNCTION__, this, "Unknown error");
-               return DCM_ERROR_UNKNOWN;
-       }
-
-       return DCM_ERROR_NONE;
-}
-
-unsigned int dcm_client_connection_impl::key_length() const noexcept {
-       return fKeyLength;
-}
diff --git a/dcm-client/device_certificate_manager.cpp b/dcm-client/device_certificate_manager.cpp
deleted file mode 100644 (file)
index bef03c8..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2020 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.
- *
- ******************************************************************/
-
-#include "device_certificate_manager.h"
-#include "dcm_client.h"
-
-#include <mbedtls/pk_internal.h>
-#include <mbedtls/md.h>
-
-#include <vector>
-#include <cstring>
-
-#ifndef API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-#define API_DEVICE_CERTIFICATE_MANAGER_EXPORT __attribute__((visibility("default")))
-#endif
-
-#define LOG_TAG                "DCM_CLIENT"
-#include <dlog.h>
-
-static mbedtls_md_type_t to_mbedtls_md_type(dcm_digest_algorithm_e md)
-{
-  switch(md) {
-    case DCM_DIGEST_NONE:
-      return MBEDTLS_MD_NONE;
-    case DCM_DIGEST_MD2:
-      return MBEDTLS_MD_MD2;
-    case DCM_DIGEST_MD4:
-      return MBEDTLS_MD_MD4;
-    case DCM_DIGEST_MD5:
-      return MBEDTLS_MD_MD5;
-    case DCM_DIGEST_SHA1:
-      return MBEDTLS_MD_SHA1;
-    case DCM_DIGEST_SHA224:
-      return MBEDTLS_MD_SHA224;
-    case DCM_DIGEST_SHA256:
-      return MBEDTLS_MD_SHA256;
-    case DCM_DIGEST_SHA384:
-      return MBEDTLS_MD_SHA384;
-    case DCM_DIGEST_SHA512:
-      return MBEDTLS_MD_SHA512;
-    case DCM_DIGEST_RIPEMD160:
-      return MBEDTLS_MD_RIPEMD160;
-    default:
-      return MBEDTLS_MD_NONE;
-  }
-}
-
-struct dcm_key_context_internal {
-       std::shared_ptr<dcm_client_connection> connection;
-};
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_create_key_context(const char *service, const char *usage, const char *key_type, void **key_ctx)
-{
-       try {
-               if(!key_ctx)
-                       return DCM_ERROR_INVALID_PARAMETER;
-
-               std::unique_ptr<dcm_key_context_internal> context(new dcm_key_context_internal());
-
-               std::string service_string(service ? service : "");
-               std::string usage_string(usage ? usage : "");
-               std::string keytype_string(key_type ? key_type : "");
-
-               context->connection = dcm_client_connection::create();
-
-               if(!context->connection->create_context(service_string, usage_string, keytype_string)) {
-                       LOGE("Can't create connection context");
-                       return DCM_ERROR_SOCKET;
-               }
-
-               *key_ctx = context.release();
-               return DCM_ERROR_NONE;
-       } catch(std::exception& ex) {
-               LOGE("Context creation failure: %s", ex.what());
-               return DCM_ERROR_UNKNOWN;
-       } catch(...) {
-               LOGE("Context creation failure");
-               return DCM_ERROR_UNKNOWN;
-       }
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_free_key_context(void *key_ctx)
-{
-       if(!key_ctx)
-               return DCM_ERROR_NONE;
-
-       delete reinterpret_cast<dcm_key_context_internal *>(key_ctx);
-
-       return DCM_ERROR_NONE;
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_get_certificate_chain(const void *key_ctx, char **cert_chain, size_t *cert_chain_len)
-{
-       if(!key_ctx || !cert_chain || !cert_chain_len)
-               return DCM_ERROR_INVALID_PARAMETER;
-
-       const dcm_key_context_internal *context =
-               reinterpret_cast<const dcm_key_context_internal *>(key_ctx);
-
-       std::vector<uint8_t> cert;
-       int result = context->connection->get_certificate_chain(cert);
-       if(result == DCM_ERROR_NONE) {
-               *cert_chain = (char*)malloc(sizeof(uint8_t) * cert.size());
-               if(*cert_chain == NULL)
-                       return DCM_ERROR_OUT_OF_MEMORY;
-               memcpy(*cert_chain, cert.data(), cert.size());
-               *cert_chain_len = cert.size();
-       }
-
-       return result;
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_get_key_bit_length(const void *key_ctx, size_t *key_bit_len)
-{
-       if(!key_ctx || !key_bit_len)
-               return DCM_ERROR_INVALID_PARAMETER;
-
-       const dcm_key_context_internal *context =
-               reinterpret_cast<const dcm_key_context_internal *>(key_ctx);
-       *key_bit_len = context->connection->key_length();
-
-       return DCM_ERROR_NONE;
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_get_key_type(const void *key_ctx, char **key_type)
-{
-       if(!key_ctx || !key_type)
-               return DCM_ERROR_INVALID_PARAMETER;
-
-       const dcm_key_context_internal *context =
-               reinterpret_cast<const dcm_key_context_internal *>(key_ctx);
-
-       std::string type = context->connection->key_type();
-       *key_type = (char*)malloc(sizeof(char) * (type.length() + 1));
-       if(*key_type == NULL)
-               return DCM_ERROR_OUT_OF_MEMORY;
-       memcpy(*key_type, type.c_str(), type.length() + 1);
-
-       return DCM_ERROR_NONE;
-}
-
-API_DEVICE_CERTIFICATE_MANAGER_EXPORT
-int dcm_create_signature(const void *key_ctx, dcm_digest_algorithm_e md,
-                        const char *message, size_t message_len,
-                        char **signature, size_t *signature_len)
-{
-       if(!key_ctx || !signature || !signature_len)
-               return DCM_ERROR_INVALID_PARAMETER;
-
-       const dcm_key_context_internal *context =
-               reinterpret_cast<const dcm_key_context_internal *>(key_ctx);
-
-       std::vector<uint8_t> digest;
-       int result = context->connection->sign_data(to_mbedtls_md_type(md), message, message_len, digest);
-       if(result == DCM_ERROR_NONE) {
-               if(digest.size() > MBEDTLS_MPI_MAX_SIZE)
-                       return DCM_ERROR_INVALID_PARAMETER;
-
-               *signature = (char*)malloc(sizeof(uint8_t) * digest.size());
-               if(*signature == NULL)
-                       return DCM_ERROR_OUT_OF_MEMORY;
-               memcpy(*signature, digest.data(), digest.size());
-               *signature_len = digest.size();
-       }
-
-       return result;
-}
diff --git a/dcm-client/device_certificate_manager.h b/dcm-client/device_certificate_manager.h
deleted file mode 100644 (file)
index 9e53a83..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2018 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 __DEVICE_CERTIFICATE_MANAGER_H__
-#define __DEVICE_CERTIFICATE_MANAGER_H__
-
-#include <stddef.h>
-#include <tizen.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @addtogroup CAPI_DEVICE_CERTIFICATE_MANAGER_MODULE
- * @{
- */
-
-
-/**
- * @brief Enumeration for DCM error values.
- * @since_tizen 5.0
- */
-typedef enum {
-    DCM_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
-    DCM_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid function parameter */
-    DCM_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
-    DCM_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
-    DCM_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Feature needed to run API is not supported */
-    DCM_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< No data available */
-    DCM_ERROR_UNKNOWN = TIZEN_ERROR_UNKNOWN, /**< Unknown error */
-
-    DCM_ERROR_SOCKET = TIZEN_ERROR_DEVICE_CERTIFICATE_MANAGER | 0x01, /**< Socket error between client and server */
-} dcm_error_e;
-
-
-/**
- * @brief Enumeration for DCM message digest algorithms.
- * @since_tizen 5.0
- */
-typedef enum {
-    DCM_DIGEST_NONE=0, /**< No message digest algorithm */
-    DCM_DIGEST_MD2, /**< Message digest algorithm MD2 */
-    DCM_DIGEST_MD4, /**< Message digest algorithm MD4 */
-    DCM_DIGEST_MD5, /**< Message digest algorithm MD5 */
-    DCM_DIGEST_SHA1, /**< Message digest algorithm SHA1 */
-    DCM_DIGEST_SHA224, /**< Message digest algorithm SHA224 */
-    DCM_DIGEST_SHA256, /**< Message digest algorithm SHA256 */
-    DCM_DIGEST_SHA384, /**< Message digest algorithm SHA384 */
-    DCM_DIGEST_SHA512, /**< Message digest algorithm SHA512 */
-    DCM_DIGEST_RIPEMD160, /**< Message digest algorithm RIPEMD160 */
-} dcm_digest_algorithm_e;
-
-
-/**
- * @platform
- * @brief Creates a new key context based on specific name indication (service name, key usage, key type).
- * @since_tizen 5.0
- * @privlevel platform
- * @privilege %http://tizen.org/privilege/devicecertificate
- *
- * @remarks The @a key_ctx should be freed with dcm_free_key_context() after use.
- *
- * @param[in] service  Service name indicates first category name (if null, default value is used)
- * @param[in] usage  Usage name indicates sub-category name (if null, default value is used)
- * @param[in] key_type  Key type name indication (if null, default value is used)
- * @param[out] key_ctx  Newly created key context
- * @return #DCM_ERROR_NONE on success,
- *         otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
- * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
- * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_SOCKET Socket error between client and server
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- *
- * @see dcm_free_key_context()
- */
-int dcm_create_key_context(const char *service, const char *usage, const char *key_type, void **key_ctx);
-
-
-/**
- * @platform
- * @brief Destroys the key context that was created by calling dcm_create_key_context().
- * @since_tizen 5.0
- * @privlevel platform
- * @privilege %http://tizen.org/privilege/devicecertificate
- *
- * @param[in] key_ctx  Key context object to be deallocated
- * @return #DCM_ERROR_NONE on success,
- *         otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
- * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
- * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_SOCKET Socket error between client and server
- * @retval #DCM_ERROR_NO_DATA No such key context object
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- *
- * @see dcm_create_key_context()
- */
-int dcm_free_key_context(void *key_ctx);
-
-
-/**
- * @platform
- * @brief Returns a certificate chain which was pre-injected in device.
- * @since_tizen 5.0
- * @privlevel platform
- * @privilege %http://tizen.org/privilege/devicecertificate
- *
- * @remarks The @a cert_chain should be freed using free().
- *
- * @param[in] key_ctx  Key context object that identifies proper certificate chain
- * @param[out] cert_chain  Certificate chain in binary, will be allocated by the library
- * @param[out] cert_chain_len  The total length of certificate chain
- * @return #DCM_ERROR_NONE on success,
- *         otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
- * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
- * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_SOCKET Socket error between client and server
- * @retval #DCM_ERROR_NO_DATA No certificate chain available
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- */
-int dcm_get_certificate_chain(const void *key_ctx, char **cert_chain, size_t *cert_chain_len);
-
-
-/**
- * @platform
- * @brief Returns the key size in bits for a given key context.
- * @since_tizen 5.0
- * @privlevel platform
- * @privilege %http://tizen.org/privilege/devicecertificate
- *
- * @param[in] key_ctx  Key context object that identifies proper certificate chain
- * @param[out] key_bit_len  Key length in bits
- * @return #DCM_ERROR_NONE on success,
- *         otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
- * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
- * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_SOCKET Socket error between client and server
- * @retval #DCM_ERROR_NO_DATA No certificate chain available
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- */
-int dcm_get_key_bit_length(const void *key_ctx, size_t *key_bit_len);
-
-
-/**
- * @platform
- * @brief Returns the key type name for a given key context.
- * @since_tizen 5.0
- * @privlevel platform
- * @privilege %http://tizen.org/privilege/devicecertificate
- *
- * @remarks The @a key_type should be freed using free().
- *
- * @param[in] key_ctx  Key context object that identifies proper certificate chain
- * @param[out] key_type  Key type name (UNKNOWN, RSA or ECDSA), will be allocated by the library
- * @return #DCM_ERROR_NONE on success,
- *         otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
- * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
- * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_SOCKET Socket error between client and server
- * @retval #DCM_ERROR_NO_DATA No certificate chain available
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- */
-int dcm_get_key_type(const void *key_ctx, char **key_type);
-
-/**
- * @platform
- * @brief Creates a signature on a given data using a private key and returns the signature.
- * @since_tizen 5.0
- * @privlevel platform
- * @privilege %http://tizen.org/privilege/devicecertificate
- *
- * @remarks The private key is identified by @a key_ctx.
- * @remarks The @a message can be NULL but then @a message_len must be 0.
- * @remarks The @a signature should be freed using free().
- *
- * @param[in] key_ctx  Key context object that identifies a proper private key for signing
- * @param[in] md  Message digest algorithm used in creating signature
- * @param[in] message  Message that is signed with a key
- * @param[in] message_len  Length of the message
- * @param[out] signature  Newly created signature, will be allocated by the library
- * @param[out] signature_len  Length of a newly created signature
- * @return #DCM_ERROR_NONE on success,
- *         otherwise a negative error value
- *
- * @retval #DCM_ERROR_NONE Successful
- * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
- * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
- * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
- * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
- * @retval #DCM_ERROR_SOCKET Socket error between client and server
- * @retval #DCM_ERROR_UNKNOWN Unknown error
- */
-int dcm_create_signature(const void *key_ctx, dcm_digest_algorithm_e md,
-                         const char *message, size_t message_len,
-                         char **signature, size_t *signature_len);
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DEVICE_CERTIFICATE_MANAGER_H__ */
diff --git a/dcm-client/version_script.lds b/dcm-client/version_script.lds
deleted file mode 100644 (file)
index 9b724fc..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-DCMCLIENT_2.0 {
-       global:
-               dcm_create_key_context;
-               dcm_free_key_context;
-               dcm_get_certificate_chain;
-               dcm_get_key_bit_length;
-               dcm_get_key_type;
-               dcm_create_signature;
-       local:
-               *;
-};
diff --git a/dcm-daemon/CMakeLists.txt b/dcm-daemon/CMakeLists.txt
deleted file mode 100644 (file)
index 65b31de..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (c) 2017 - 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        dcm-daemon/CMakeLists.txt
-# @author      Dariusz Michaluk <d.michaluk@samsung.com>
-# @author      Jaroslaw Pelczar <j.pelczar@samsung.com>
-
-FIND_PACKAGE(Threads REQUIRED)
-FIND_PACKAGE(Protobuf REQUIRED)
-
-FIND_PACKAGE(Boost REQUIRED
-       COMPONENTS
-       log
-       thread
-       system)
-
-PKG_CHECK_MODULES(DAEMON_DEPS
-       REQUIRED
-       libsystemd
-       cynara-client
-       cynara-creds-socket
-       cynara-session
-       dlog)
-
-INCLUDE_DIRECTORIES(SYSTEM ${DAEMON_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
-LINK_DIRECTORIES(${DAEMON_DEPS_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS})
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
-
-PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ../dcm-client/dcm_support.proto)
-
-ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)
-
-SET(TARGET_DAEMON "device-certificate-managerd")
-ADD_EXECUTABLE(${TARGET_DAEMON}
-       main.cpp
-       dcmserver.cpp
-       dcmsession.cpp
-       serviceadapter.cpp
-       ../shared/protobuf_asio.cpp
-       soresolver.cpp
-       ${PROTO_SRCS}
-       ${PROTO_HDRS})
-
-TARGET_LINK_LIBRARIES(${TARGET_DAEMON}
-       ${Boost_LOG_LIBRARY}
-       ${Boost_THREAD_LIBRARY}
-       ${Boost_SYSTEM_LIBRARY}
-       ${PROTOBUF_LITE_LIBRARIES}
-       ${DAEMON_DEPS_LIBRARIES}
-       ${CMAKE_THREAD_LIBS_INIT}
-       dl)
-
-INSTALL(TARGETS ${TARGET_DAEMON}
-       RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
-
-INSTALL(FILES
-       dcm-backend-api.h
-       DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/device-certificate-manager-backend)
diff --git a/dcm-daemon/boost_log_dlog_sink.h b/dcm-daemon/boost_log_dlog_sink.h
deleted file mode 100644 (file)
index 89f50f3..0000000
+++ /dev/null
@@ -1,89 +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 SHARED_BOOST_LOG_DLOG_SINK_H_
-#define SHARED_BOOST_LOG_DLOG_SINK_H_
-
-#include <boost/log/sinks.hpp>
-#include <functional>
-
-#include <dlog.h>
-
-template<typename AttributeValueT = int> class dlog_direct_severity_mapping :
-       public boost::log::sinks::basic_direct_mapping<log_priority, AttributeValueT>
-{
-       typedef  boost::log::sinks::basic_direct_mapping<log_priority, AttributeValueT> base_type;
-public:
-       explicit dlog_direct_severity_mapping(boost::log::attribute_name const& name) :
-               base_type(name)
-       {
-       }
-};
-
-template<typename AttributeValueT = int> class dlog_custom_severity_mapping :
-       public boost::log::sinks::basic_custom_mapping<log_priority, AttributeValueT>
-{
-       typedef  boost::log::sinks::basic_custom_mapping<log_priority, AttributeValueT> base_type;
-public:
-       explicit dlog_custom_severity_mapping(boost::log::attribute_name const& name) :
-               base_type(name, DLOG_DEBUG)
-       {
-       }
-};
-
-class dlog_output_backend :
-       public boost::log::sinks::basic_formatted_sink_backend<char>
-{
-       typedef boost::log::sinks::basic_formatted_sink_backend<char>   base_type;
-       typedef std::function< log_priority (boost::log::record_view const&) > severity_mapper_type;
-
-private:
-       std::string                             log_domain_;
-       severity_mapper_type    level_mapper_;
-
-       inline void send(log_priority level, string_type const& formatted_message) {
-               dlog_print(level, log_domain_.c_str(), "%s", formatted_message.c_str());
-       }
-
-public:
-       dlog_output_backend()
-       {
-       }
-
-    void consume(boost::log::record_view const& rec, string_type const& formatted_message) {
-       if(!level_mapper_) {
-               send(DLOG_DEBUG, formatted_message);
-       } else {
-               send(level_mapper_(rec), formatted_message);
-       }
-    }
-
-       void set_log_domain(const std::string& name)
-       {
-               log_domain_ = name;
-       }
-
-    void set_severity_mapper(severity_mapper_type const& mapper)
-    {
-       level_mapper_ = mapper;
-    }
-};
-
-#endif /* SHARED_BOOST_LOG_DLOG_SINK_H_ */
diff --git a/dcm-daemon/dcm-backend-api.h b/dcm-daemon/dcm-backend-api.h
deleted file mode 100644 (file)
index 208ff61..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/******************************************************************
- *
- * Copyright 2019 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& mutable_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/dcm-daemon/dcmserver.cpp b/dcm-daemon/dcmserver.cpp
deleted file mode 100644 (file)
index bb6c509..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2019 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 "dcmserver.h"
-#include "dcmsession.h"
-#include "logging.h"
-
-dcm_server::dcm_server(boost::asio::io_service& io_service, boost::asio::local::stream_protocol::acceptor&& acceptor, std::string lib_backend) :
-       fService(io_service),
-       fTimer(io_service),
-       fAcceptor(std::move(acceptor)),
-       fSoResolver(std::make_shared<so_resolver>(lib_backend))
-{
-       BOOST_LOG_FUNCTION();
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Construct server object";
-}
-
-dcm_server::~dcm_server()
-{
-       BOOST_LOG_FUNCTION();
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Destroy server object";
-}
-
-void dcm_server::start()
-{
-       do_accept();
-}
-
-void dcm_server::do_accept()
-{
-       BOOST_LOG_FUNCTION();
-
-       auto self(this->shared_from_this());
-       std::shared_ptr<dcm_session> session;
-
-       try {
-               session = std::make_shared<dcm_session>(fService, fTimer, shared_from_this(), fSoResolver);
-       } catch(std::bad_alloc& ex) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Out of memory when trying to allocate new session";
-               return;
-       } catch(std::exception& ex) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Can't create new session object: " << ex.what();
-               return;
-       }
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Start accepting connections";
-       session->start_timer();
-
-       fAcceptor.async_accept(session->socket(),
-               [session, self](boost::system::error_code error_code)
-               {
-                       BOOST_LOG_FUNCTION();
-                       if(!error_code) {
-                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Accepted session";
-                               session->start();
-                       } else {
-                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't accept new session " << error_code;
-                       }
-                       self->do_accept();
-               });
-}
diff --git a/dcm-daemon/dcmserver.h b/dcm-daemon/dcmserver.h
deleted file mode 100644 (file)
index c05dc5b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2019 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_DCMSERVER_H_
-#define DCM_DAEMON_DCMSERVER_H_
-
-#include <boost/asio.hpp>
-#include <boost/noncopyable.hpp>
-#include <mutex>
-#include <memory>
-#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, boost::asio::local::stream_protocol::acceptor&& acceptor, std::string lib_backend);
-       ~dcm_server();
-       void start();
-
-private:
-       void do_accept();
-
-private:
-       boost::asio::io_service&                                                fService;
-       boost::asio::deadline_timer                                             fTimer;
-       boost::asio::local::stream_protocol::acceptor   fAcceptor;
-       std::mutex                                                                              fLock;
-       std::shared_ptr<so_resolver> fSoResolver;
-};
-
-#endif /* DCM_DAEMON_DCMSERVER_H_ */
diff --git a/dcm-daemon/dcmsession.cpp b/dcm-daemon/dcmsession.cpp
deleted file mode 100644 (file)
index fa3c3f5..0000000
+++ /dev/null
@@ -1,440 +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 "dcmsession.h"
-#include "logging.h"
-#include "exception_translator.h"
-#include "dcmserver.h"
-
-#include <iostream>
-#include <cassert>
-#include <map>
-#include <mutex>
-
-#include <cynara-client.h>
-#include <cynara-creds-socket.h>
-#include <cynara-session.h>
-
-extern cynara * gGlobalCynaraInstance;
-
-static inline std::string cynara_error_to_string(int error) {
-       char buffer[256];
-       int ret = cynara_strerror(error, buffer, sizeof(buffer));
-       if(ret == CYNARA_API_SUCCESS)
-               return std::string(buffer);
-       return std::string("Can't translate error");
-}
-
-unsigned int globalSessionCounter = 0;
-
-dcm_session::dcm_session(boost::asio::io_service& io_service,
-               boost::asio::deadline_timer& timer,
-               const std::shared_ptr<dcm_server>& server,
-               std::shared_ptr<so_resolver> soResolver) :
-       fService(io_service),
-       fTimer(timer),
-       fSocket(io_service),
-       fServer(server),
-       fSoResolver(soResolver)
-{
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Create new session object " << this;
-       globalSessionCounter++;
-}
-
-dcm_session::~dcm_session()
-{
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Destroy session object " << this;
-}
-
-struct string_free_deleter {
-       void operator()(char * p) const {
-               free(p);
-       }
-};
-
-bool dcm_session::verify_privileges(int handle)
-{
-       BOOST_LOG_FUNCTION();
-
-       int ret = 0;
-       char * tmp_str;
-       pid_t pid = 0;
-
-       std::unique_ptr<char, string_free_deleter> user;
-       std::unique_ptr<char, string_free_deleter> client;
-       std::unique_ptr<char, string_free_deleter> client_session;
-
-       /* Get user info */
-       tmp_str = nullptr;
-       ret = cynara_creds_socket_get_user(handle, USER_METHOD_DEFAULT, &tmp_str);
-       if(ret != CYNARA_API_SUCCESS) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get user from socket : " << ret << " - " << cynara_error_to_string(ret);
-               return false;
-       }
-       user.reset(tmp_str);
-
-       /* Get client info */
-       tmp_str = nullptr;
-       ret = cynara_creds_socket_get_client(handle, CLIENT_METHOD_DEFAULT, &tmp_str);
-       if(ret != CYNARA_API_SUCCESS) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get client from socket : " << ret << " - " << cynara_error_to_string(ret);
-               return false;
-       }
-       client.reset(tmp_str);
-
-
-       /* Get client PID from socket */
-       ret = cynara_creds_socket_get_pid(handle, &pid);
-       if(ret != CYNARA_API_SUCCESS) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get PID from socket : " << ret << " - " << cynara_error_to_string(ret);
-               return false;
-       }
-
-       client_session.reset(cynara_session_from_pid(pid));
-       if(!client_session) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get session identifier from PID";
-               return false;
-       }
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Got new session from " << pid << " with user " <<
-                       user.get() << ", client ID " << client.get() << " and session ID " << client_session.get();
-
-       ret = cynara_check(gGlobalCynaraInstance,
-                       client.get(),
-                       client_session.get(),
-                       user.get(),
-                       "http://tizen.org/privilege/devicecertificate");
-
-       if(ret != CYNARA_API_ACCESS_ALLOWED) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) <<
-                               "Application access denied - no internet permission for " <<
-                               pid <<
-                               " - " <<
-                               cynara_error_to_string(ret);
-
-               return false;
-       }
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Access granted for " << pid;
-
-       return true;
-}
-
-void dcm_session::start()
-{
-       BOOST_LOG_FUNCTION();
-
-       int handle = fSocket.native_handle();
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Accepted connection with socket " << fSocket.native_handle();
-
-       if(verify_privileges(handle)) {
-               stop_timer();
-               do_receive();
-       } else {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Client privilege check failure. Disconnect";
-               start_timer();
-       }
-}
-
-void dcm_session::start_timer()
-{
-       globalSessionCounter--;
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Number of active connections: " << globalSessionCounter;
-
-       if(globalSessionCounter == 0) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "No active connections, server will be closed after few seconds";
-               fTimer.expires_from_now(boost::posix_time::seconds(10));
-               /* operation_aborted error is returned whenever we cancel the timer or we reset the timer using expires_from_now function */
-               fTimer.async_wait([this](const boost::system::error_code &error) {
-                       if(error != boost::asio::error::operation_aborted) {
-                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "No active connections, server will be closed";
-                               fService.stop();
-                       }
-               });
-       }
-}
-
-void dcm_session::stop_timer()
-{
-       globalSessionCounter++;
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Number of active connections: " << globalSessionCounter;
-
-       fTimer.cancel();
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Timer cancelled";
-}
-
-void dcm_session::do_receive() noexcept
-{
-       BOOST_LOG_FUNCTION();
-
-       try {
-               auto self(shared_from_this());
-
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Read new message";
-
-               fDeserializer.read_message(fSocket,
-                       [self, this](const boost::system::error_code& error, std::size_t bytes_read) {
-                                       BOOST_LOG_FUNCTION();
-                                       if(!error) {
-                                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Received " << bytes_read << " bytes from client";
-                                               decode_message();
-                                       } else {
-                                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Client disconnected: " << error;
-                                               // Connection object will be released by shared ptr
-                                               start_timer();
-                                       }
-                       });
-       } catch(std::exception& ex) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while trying to read message : " << ex.what();
-               // Connection object will be released by shared ptr
-       } catch(...) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while trying to read message : " << "unknown";
-               // Connection object will be released by shared ptr
-       }
-}
-
-void dcm_session::decode_message() noexcept
-{
-       BOOST_LOG_FUNCTION();
-       try {
-               // Try to decode whole message
-               RequestMessage requestMessage;
-
-               if(!fDeserializer.decode_received_message(requestMessage)) {
-                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't parse message from stream";
-                       // This will terminate connection
-                       return;
-               }
-
-               switch(requestMessage.request_oneof_case())
-               {
-               case RequestMessage::kAssociateContext:
-                       handle_context_association(requestMessage.associate_context());
-                       break;
-               case RequestMessage::kRequestChain:
-                       handle_cert_chain(requestMessage.request_chain());
-                       break;
-               case RequestMessage::kSignData:
-                       handle_sign_request(requestMessage.sign_data());
-                       break;
-               default:
-                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Incorrect request message type";
-                       // This will terminate connection
-                       return;
-               }
-       } catch(std::exception& ex) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while parsing message : " << ex.what();
-               // Connection object will be released by shared ptr
-       } catch(...) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while parsing message : " << "unknown";
-               // Connection object will be released by shared ptr
-       }
-}
-
-void dcm_session::reply(const ResponseMessage& resp) noexcept
-{
-       BOOST_LOG_FUNCTION();
-       try {
-               auto self(shared_from_this());
-
-               fSerializer.encodeMessage(resp);
-
-               fSerializer.async_write(fSocket,
-                               [self, this](const boost::system::error_code& error, std::size_t bytes_written)
-                       {
-                               BOOST_LOG_FUNCTION();
-                               if(!error) {
-                                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Written " << bytes_written << " to socket";
-                                       do_receive();
-                               } else {
-                                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Server disconnected: " << error;
-                                       // Connection object will be released by shared ptr
-                               }
-                       });
-       } catch(std::exception& ex) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while sending message : " << ex.what();
-               // Connection object will be released by shared ptr
-       } catch(...) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while sending message : " << "unknown";
-               // Connection object will be released by shared ptr
-       }
-}
-
-void dcm_session::handle_context_association(const AssociateKeyContext& message)
-{
-       BOOST_LOG_FUNCTION();
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Associate context";
-
-       ResponseMessage msg;
-       auto * contextResponse = msg.mutable_associate_context();
-
-       if(fBackendContext) {
-               contextResponse->set_result(EEXIST);
-               reply(msg);
-               return;
-       }
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Associate context from service " <<
-               message.service() << " with usage " << message.usage() << " and key type " << message.key_type();
-
-       auto server = fServer.lock();
-
-       if(!server) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Server object gone while handling message";
-               return;
-       }
-
-       int error = run_with_exception_handler([&]() {
-
-               bool loaded = fSoResolver->ensure_loaded();
-               if (loaded) {
-                       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()
-                       );
-
-                       CryptoKeyType crypto_key_type = fSoResolver->invoke<CryptoKeyType, dcm_backend_context&>(
-                               "dcm_backend_key_type",
-                               *fBackendContext
-                       );
-                       contextResponse->set_key_type(crypto_key_type);
-
-                       unsigned int crypto_key_length = fSoResolver->invoke<unsigned int, dcm_backend_context&>(
-                               "dcm_backend_key_length",
-                               *fBackendContext
-                       );
-                       contextResponse->set_key_length(crypto_key_length);
-               }
-               else {
-                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "No crypto usable backend available";
-                       throw std::invalid_argument("Unable to find crypto backend");
-               }
-               fCookie = (uintptr_t)fBackendContext.get();
-               contextResponse->set_context_cookie(fCookie);
-       });
-
-       contextResponse->set_result(error);
-
-       reply(msg);
-}
-
-static const std::string sPEMHeader("-----BEGIN CERTIFICATE-----\n");
-
-void dcm_session::handle_cert_chain(const RequestCertificateChain& message)
-{
-       BOOST_LOG_FUNCTION();
-
-       ResponseMessage msg;
-       auto * certificateResponse = msg.mutable_request_chain();
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Request certificate chain";
-
-       if(message.context_cookie() != fCookie) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Received unknown context cookie";
-               certificateResponse->set_result(-EINVAL);
-               reply(msg);
-               return;
-       }
-
-       if(!fBackendContext) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Context not associated with connection";
-               certificateResponse->set_result(-EINVAL);
-               reply(msg);
-               return;
-       }
-
-       std::string cert_chain;
-
-       int error = 0;
-       bool loaded = fSoResolver->ensure_loaded();
-       if (loaded) {
-               error = fSoResolver->invoke<int, dcm_backend_context&, std::string&>(
-                       "dcm_backend_request_certificate_chain",
-                       *fBackendContext,
-                       cert_chain
-               );
-       }
-
-       if(error != 0) {
-               certificateResponse->set_result(error);
-               reply(msg);
-               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);
-}
-
-void dcm_session::handle_sign_request(const SignRequest& message)
-{
-       BOOST_LOG_FUNCTION();
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Request data signing";
-
-       ResponseMessage msg;
-       auto * signingResponse = msg.mutable_sign_data();
-
-       if(message.context_cookie() != fCookie) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Received unknown context cookie";
-               signingResponse->set_result(-EINVAL);
-               reply(msg);
-               return;
-       }
-
-       if(!fBackendContext) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Context not associated with connection";
-               signingResponse->set_result(-EINVAL);
-               reply(msg);
-               return;
-       }
-
-       if(message.data_to_sign().size() == 0) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Data to sign is empty and hash type is NONE";
-               signingResponse->set_result(-EINVAL);
-               return;
-       }
-
-       int error = 0;
-       bool loaded = fSoResolver->ensure_loaded();
-       if (loaded) {
-               error = fSoResolver->invoke<int, dcm_backend_context&, MessageDigestType, const std::string&, std::string&>(
-                       "dcm_backend_sign_crypto_data",
-                       *fBackendContext,
-                       message.digest_type(),
-                       message.data_to_sign(),
-                       *signingResponse->mutable_signature()
-               );
-       }
-       signingResponse->set_result(error);
-
-       reply(msg);
-}
diff --git a/dcm-daemon/dcmsession.h b/dcm-daemon/dcmsession.h
deleted file mode 100644 (file)
index abddb29..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2019 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_DCMSESSION_H_
-#define DCM_DAEMON_DCMSESSION_H_
-
-#include <memory>
-#include <boost/asio.hpp>
-#include <boost/noncopyable.hpp>
-#include "dcm_support.pb.h"
-#include "protobuf_asio.h"
-#include "dcm-backend-api.h"
-#include "soresolver.h"
-
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-
-class dcm_server;
-
-class dcm_session final : public std::enable_shared_from_this<dcm_session>,
-       public boost::noncopyable
-{
-public:
-       dcm_session(boost::asio::io_service& io_service, boost::asio::deadline_timer& timer, const std::shared_ptr<dcm_server>& server, std::shared_ptr<so_resolver> soResolver);
-       ~dcm_session();
-
-       void start();
-       void start_timer();
-       void stop_timer();
-
-       inline boost::asio::local::stream_protocol::socket& socket() {
-               return fSocket;
-       }
-
-private:
-       void do_receive() noexcept;
-       void decode_message() noexcept;
-       void reply(const ResponseMessage& resp) noexcept;
-
-       bool verify_privileges(int handle);
-
-       void handle_context_association(const AssociateKeyContext& message);
-       void handle_cert_chain(const RequestCertificateChain& message);
-       void handle_sign_request(const SignRequest& message);
-
-private:
-       boost::asio::io_service&                                                fService;
-       boost::asio::deadline_timer&                                    fTimer;
-       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;
-       uint64_t                                                                                fCookie = 0;
-};
-
-#endif /* DCM_DAEMON_DCMSESSION_H_ */
diff --git a/dcm-daemon/exception_translator.h b/dcm-daemon/exception_translator.h
deleted file mode 100644 (file)
index 1395888..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 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_EXCEPTION_TRANSLATOR_H_
-#define DCM_DAEMON_EXCEPTION_TRANSLATOR_H_
-
-#include <memory>
-#include <stdexcept>
-#include <cerrno>
-#include <boost/system/system_error.hpp>
-
-template<typename T> inline int run_with_exception_handler(T t) {
-       try {
-               t();
-       } catch(boost::system::system_error& ex) {
-               return -ex.code().value();
-       } catch(std::bad_alloc&) {
-               return -ENOMEM;
-       } catch(std::domain_error&) {
-               return -EDOM;
-       } catch(std::invalid_argument&) {
-               return -EINVAL;
-       } catch(std::length_error&) {
-               return -EINVAL;
-       } catch(std::out_of_range&) {
-               return -EINVAL;
-       } catch(std::range_error&) {
-               return -ERANGE;
-       } catch(std::overflow_error&) {
-               return -EOVERFLOW;
-       } catch(std::underflow_error&) {
-               return -EOVERFLOW;
-       } catch(std::exception&) {
-               return -EINVAL;
-       } catch(...) {
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
-#endif /* DCM_DAEMON_EXCEPTION_TRANSLATOR_H_ */
diff --git a/dcm-daemon/logging.h b/dcm-daemon/logging.h
deleted file mode 100644 (file)
index bae7977..0000000
+++ /dev/null
@@ -1,53 +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_LOGGING_H_
-#define DCM_DAEMON_LOGGING_H_
-
-#include <boost/log/common.hpp>
-#include <boost/log/expressions.hpp>
-#include <boost/log/attributes.hpp>
-#include <boost/log/sinks/sync_frontend.hpp>
-#include <boost/log/sinks/syslog_backend.hpp>
-#include <boost/log/sources/logger.hpp>
-#include <boost/log/utility/setup/console.hpp>
-#include <boost/log/utility/setup/common_attributes.hpp>
-#include <boost/log/attributes/timer.hpp>
-#include <boost/log/attributes/named_scope.hpp>
-
-#define LOG_TAG                "DCM_SERVER"
-#include <dlog.h>
-
-enum class log_severity {
-       debug,
-       normal,
-       warning,
-       error
-};
-
-// Global logger declaration
-BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(dcm_logger, boost::log::sources::severity_logger_mt<log_severity>)
-
-#if defined(NDEBUG) && !defined(DEBUG)
-#else
-#define ENABLE_DEBUG_LOGGING           1
-#endif
-
-#endif /* DCM_DAEMON_LOGGING_H_ */
diff --git a/dcm-daemon/main.cpp b/dcm-daemon/main.cpp
deleted file mode 100644 (file)
index 09183e8..0000000
+++ /dev/null
@@ -1,185 +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 <boost/asio.hpp>
-
-#include <iostream>
-#include <unistd.h>
-#include <cstdlib>
-#include <sys/stat.h>
-#include <sys/signal.h>
-
-#include "dcmserver.h"
-#include "logging.h"
-#include "serviceadapter.h"
-
-#include <boost/log/sinks.hpp>
-#include <boost/log/support/date_time.hpp>
-
-#include "boost_log_dlog_sink.h"
-
-#include <cynara-client.h>
-
-BOOST_LOG_ATTRIBUTE_KEYWORD(_scope, "Scope", boost::log::attributes::named_scope::value_type)
-BOOST_LOG_ATTRIBUTE_KEYWORD(_timestamp, "TimeStamp", boost::posix_time::ptime)
-BOOST_LOG_ATTRIBUTE_KEYWORD(_severity, "Severity", log_severity)
-
-void init_logging()
-{
-       auto sink = boost::make_shared<boost::log::sinks::synchronous_sink<dlog_output_backend>>();
-
-       dlog_custom_severity_mapping<log_severity> mapping("Severity");
-
-       mapping[log_severity::debug] = DLOG_DEBUG;
-       mapping[log_severity::error] = DLOG_ERROR;
-       mapping[log_severity::normal] = DLOG_INFO;
-       mapping[log_severity::warning] = DLOG_WARN;
-
-       sink->locked_backend()->set_severity_mapper(mapping);
-       sink->locked_backend()->set_log_domain(LOG_TAG);
-
-#ifndef ENABLE_DEBUG_LOGGING
-       sink->set_filter(_severity >= log_severity::normal);
-#endif
-
-       sink->set_formatter(boost::log::expressions::stream
-        << boost::log::expressions::attr< unsigned int >("RecordID") // First an attribute "RecordID" is written to the log
-        << " [" // then this delimiter separates it from the rest of the line
-        << boost::log::expressions::if_(boost::log::expressions::has_attr("Tag"))
-           [
-               boost::log::expressions::stream << boost::log::expressions::attr< std::string >("Tag") // then goes another attribute named "Tag"
-                                               // Note here we explicitly stated that its type
-                                               // should be std::string. We could omit it just
-                                               // like we did it with the "RecordID", but in this case
-                                               // library would have to detect the actual attribute value
-                                               // type in run time which has the following consequences:
-                                               // - On the one hand, the attribute would have been output
-                                               //   even if it has another type (not std::string).
-                                               // - On the other, this detection does not come for free
-                                               //   and will result in performance decrease.
-                                               //
-                                               // In general it's better you to specify explicitly which
-                                               // type should an attribute have wherever it is possible.
-                                               // You may specify an MPL sequence of types if the attribute
-                                               // may have more than one type. And you will have to specify
-                                               // it anyway if the library is not familiar with it (see
-                                               // boost/log/utility/type_dispatch/standard_types.hpp for the list
-                                               // of the supported out-of-the-box types).
-                << "] [" // yet another delimiter
-           ]
-        << boost::log::expressions::format_named_scope("Scope", boost::log::keywords::format = "%n", boost::log::keywords::iteration = boost::log::expressions::reverse) << "] "
-        << boost::log::expressions::smessage); // here goes the log record text
-       boost::log::core::get()->add_sink(sink);
-
-       boost::log::add_common_attributes();
-       boost::log::core::get()->add_thread_attribute("Scope", boost::log::attributes::named_scope());
-}
-
-cynara * gGlobalCynaraInstance;
-
-int main()
-{
-       int error = 0;
-
-       try {
-               init_logging();
-       } catch(...) {
-               std::cerr << "init_logging() failed" << std::endl;
-               return EXIT_FAILURE;
-       }
-
-       BOOST_LOG_FUNCTION();
-
-       service_adapter serviceAdapter;
-
-       cynara_configuration * cynara_conf = nullptr;
-       error = cynara_configuration_create(&cynara_conf);
-       if(error != CYNARA_API_SUCCESS) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't initialize Cynara configuration: " << error;
-               serviceAdapter.notify_start_failure(error);
-               return EXIT_FAILURE;
-       }
-
-       error = cynara_initialize(&gGlobalCynaraInstance, cynara_conf);
-
-       cynara_configuration_destroy(cynara_conf);
-
-       if(error != CYNARA_API_SUCCESS) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't initialize Cynara instance: " << error;
-               serviceAdapter.notify_start_failure(error);
-               return EXIT_FAILURE;
-       }
-
-       try {
-               boost::asio::io_service io_service;
-
-               /* Catch signals */
-               boost::asio::signal_set stop_signals(io_service, SIGINT, SIGTERM);
-
-               stop_signals.async_wait([&io_service](const boost::system::error_code&, int sig) {
-                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "Stopped by signal " << sig;
-                       io_service.stop();
-               });
-
-               /* Change the file mode mask */
-               (void)umask(0);
-
-               /* Use root directory as working directory */
-               error = chdir("/");
-               (void)error; // Don't care
-
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Create platform socket";
-
-               std::string lib_backend = "libdcm-backend-api.so.1.0";
-               auto server(std::make_shared<dcm_server>(io_service, serviceAdapter.create_platform_socket_acceptor(io_service), lib_backend));
-
-               boost::asio::signal_set hup_signals(io_service, SIGHUP);
-
-               hup_signals.async_wait([](const boost::system::error_code&, int) {
-                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "Received HUP signal";
-               });
-
-               serviceAdapter.notify_start_complete();
-
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Start server";
-
-               server->start();
-               io_service.run();
-       } catch(std::bad_alloc& e) {
-               serviceAdapter.notify_start_failure(ENOMEM);
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Server failed with OOM exception: " << e.what();
-               return EXIT_FAILURE;
-       } catch(std::exception& e) {
-               serviceAdapter.notify_start_failure(EFAULT);
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Server failed with exception: " << e.what();
-               return EXIT_FAILURE;
-       } catch(...) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Server failed with unknown exception";
-               serviceAdapter.notify_start_failure(EFAULT);
-               return EXIT_FAILURE;
-       }
-
-       cynara_finish(gGlobalCynaraInstance);
-       gGlobalCynaraInstance = nullptr;
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "Server terminated";
-
-       return 0;
-}
diff --git a/dcm-daemon/serviceadapter.cpp b/dcm-daemon/serviceadapter.cpp
deleted file mode 100644 (file)
index 6ea5804..0000000
+++ /dev/null
@@ -1,87 +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 "serviceadapter.h"
-#include "logging.h"
-
-#include <cstring>
-
-#include <systemd/sd-daemon.h>
-
-service_adapter::service_adapter()
-{
-}
-
-service_adapter::~service_adapter()
-{
-}
-
-boost::asio::local::stream_protocol::acceptor service_adapter::create_platform_socket_acceptor(boost::asio::io_service& io_service)
-{
-       BOOST_LOG_FUNCTION();
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Try to get socket from systemd";
-
-       int n = sd_listen_fds(0);
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << n << " sockets provided by systemd";
-
-       if( n > 0 ) {
-               for(int fd = SD_LISTEN_FDS_START ; fd < SD_LISTEN_FDS_START + n ; ++fd) {
-                       if(sd_is_socket_unix(fd, SOCK_STREAM, 1, fDefaultSocketPath.c_str(), 0)) {
-                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) <<  "Got UNIX domain socket with fd " << fd;
-
-                               return boost::asio::local::stream_protocol::acceptor(
-                                       io_service,
-                                       boost::asio::local::stream_protocol(),
-                                       fd);
-                       }
-               }
-       }
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "No systemd sockets found";
-
-       throw std::runtime_error("No socket created by systemd");
-}
-
-void service_adapter::notify_start_complete()
-{
-       BOOST_LOG_FUNCTION();
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "Notify start completed to systemd";
-
-       sd_listen_fds(1);
-       sd_notify(0, "READY=1");
-       fStartCompleteNotified = true;
-}
-
-void service_adapter::notify_start_failure(int error)
-{
-       BOOST_LOG_FUNCTION();
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Notify start failure";
-
-       if(!fStartCompleteNotified) {
-               char buffer[512];
-               buffer[0] = '\0';
-               if(!strerror_r(error, buffer, sizeof(buffer)))
-                       sd_notifyf(0, "STATUS=Failed to start up: %s\nERRNO=%d", buffer, error);
-               else
-                       sd_notifyf(0, "STATUS=Failed to start up: (no message)\nERRNO=%d", error);
-       }
-}
diff --git a/dcm-daemon/serviceadapter.h b/dcm-daemon/serviceadapter.h
deleted file mode 100644 (file)
index e19e1ab..0000000
+++ /dev/null
@@ -1,42 +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_SERVICEADAPTER_H_
-#define DCM_DAEMON_SERVICEADAPTER_H_
-
-#include <boost/noncopyable.hpp>
-#include <boost/asio.hpp>
-
-class service_adapter final : public boost::noncopyable {
-public:
-       service_adapter();
-       ~service_adapter();
-
-       boost::asio::local::stream_protocol::acceptor create_platform_socket_acceptor(boost::asio::io_service& io_service);
-
-       void notify_start_complete();
-       void notify_start_failure(int error);
-
-private:
-       std::string                     fDefaultSocketPath = DCM_UNIX_SOCKET_PATH;
-       bool                            fStartCompleteNotified = false;
-};
-
-#endif /* DCM_DAEMON_SERVICEADAPTER_H_ */
diff --git a/dcm-daemon/soresolver.cpp b/dcm-daemon/soresolver.cpp
deleted file mode 100644 (file)
index 30e0b62..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2019 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 "soresolver.h"
-#include "logging.h"
-#include <dlfcn.h>
-
-so_resolver::so_resolver(const std::string& libraryName) :
-       fLibraryName(libraryName),
-       fLibraryHandle(nullptr)
-{
-}
-
-so_resolver::~so_resolver()
-{
-       if(fLibraryHandle.load(std::memory_order_relaxed)) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Unloading library " << fLibraryName;
-               dlclose(fLibraryHandle.exchange(nullptr, std::memory_order_relaxed));
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Unloaded library " << fLibraryName;
-       }
-}
-
-void * so_resolver::resolve_function(const std::string& name) noexcept
-{
-       BOOST_LOG_FUNCTION();
-
-       std::unique_lock<std::mutex> locker(fCacheLock);
-       auto it = fCache.find(name);
-
-       if(it != fCache.end())
-               return it->second;
-
-       void * handle = fLibraryHandle.load(std::memory_order_relaxed);
-
-       if(handle) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Resolving symbol " << name << " from " << fLibraryName;
-               void * sym = dlsym(handle, name.c_str());
-               if(!sym) {
-                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) <<  "Unable to resolve symbol " << name << " from " <<
-                                       fLibraryName << ": Error is " << dlerror();
-               } else {
-                       try {
-                               fCache.emplace(name, sym);
-                       } catch(...) {
-                       }
-               }
-               return sym;
-       }
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Trying to resolve symbol " << name << " from not loaded library " << fLibraryName;
-
-       return nullptr;
-}
-
-bool so_resolver::ensure_loaded() noexcept
-{
-       BOOST_LOG_FUNCTION();
-
-       std::unique_lock<std::mutex> locker(fCacheLock);
-
-       void * handle = fLibraryHandle.load(std::memory_order_acquire);
-
-       if(handle)
-               return true;
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Loading library " << fLibraryName;
-
-       handle = dlopen(fLibraryName.c_str(), RTLD_LAZY | RTLD_LOCAL);
-
-       if(!handle) {
-               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Unable to load library " << fLibraryName << ": " << dlerror();
-               return false;
-       }
-
-       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Library loaded " << fLibraryName;
-
-       void * expectedValue = nullptr;
-
-       if(!fLibraryHandle.compare_exchange_strong(expectedValue, handle, std::memory_order_release)) {
-               // Someone else have opened the library
-               dlclose(handle);
-       }
-
-       return true;
-}
diff --git a/dcm-daemon/soresolver.h b/dcm-daemon/soresolver.h
deleted file mode 100644 (file)
index 800e624..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2019 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 <boost/noncopyable.hpp>
-#include <string>
-#include <atomic>
-#include <stdexcept>
-#include <map>
-#include <mutex>
-#include <string>
-
-class so_resolver : public boost::noncopyable {
-public:
-       so_resolver(const std::string& libraryName);
-       ~so_resolver();
-
-       bool ensure_loaded() noexcept;
-       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;
-       std::atomic<void *>                     fLibraryHandle;
-       std::mutex                                              fCacheLock;
-       std::map<std::string, void *>   fCache;
-};
-
-#endif /* DCM_DAEMON_SORESOLVER_H_ */
diff --git a/shared/protobuf_asio.cpp b/shared/protobuf_asio.cpp
deleted file mode 100644 (file)
index fd8a9fd..0000000
+++ /dev/null
@@ -1,99 +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 <stdexcept>
-
-#include <google/protobuf/io/coded_stream.h>
-
-#include "protobuf_asio.h"
-
-protobuf_sync_message_serialization::protobuf_sync_message_serialization(
-       boost::asio::local::stream_protocol::socket& socket) :
-       fSocket(socket)
-{
-}
-
-void protobuf_sync_message_serialization::encodeMessage(const google::protobuf::MessageLite& message)
-{
-       google::protobuf::io::CopyingOutputStreamAdaptor os(this);
-       google::protobuf::io::CodedOutputStream coded_os(&os);
-
-       coded_os.WriteLittleEndian32(message.ByteSizeLong());
-       if(!message.SerializeToCodedStream(&coded_os)) {
-               throw std::invalid_argument("Message serialization error");
-       }
-}
-
-bool protobuf_sync_message_serialization::Write(const void* buffer, int size)
-{
-       try {
-               boost::asio::write(fSocket, boost::asio::buffer(buffer, size));
-       } catch(...) {
-               return false;
-       }
-       return true;
-}
-
-protobuf_sync_message_deserialization::protobuf_sync_message_deserialization(
-               boost::asio::local::stream_protocol::socket& socket) :
-               fSocket(socket)
-{
-}
-
-void protobuf_sync_message_deserialization::decodeMessage(google::protobuf::MessageLite& message)
-{
-       google::protobuf::uint8 header[4];
-       google::protobuf::uint32 length;
-       boost::asio::read(fSocket, boost::asio::buffer(header));
-       google::protobuf::io::CodedInputStream::ReadLittleEndian32FromArray(header, &length);
-
-       if(length < 1 || length > MESSAGE_LENGHT_MAX) {
-               throw std::length_error("Invalid message length");
-       }
-
-       std::unique_ptr<char[]> local_array(new char[length]);
-
-       boost::asio::read(fSocket, boost::asio::buffer(local_array.get(), length));
-
-       if(!message.ParseFromArray(local_array.get(), length)) {
-               throw std::invalid_argument("Invalid message format");
-       }
-}
-
-void protobuf_async_message_serialization::encodeMessage(const google::protobuf::MessageLite& message)
-{
-       int bufferSize = message.ByteSizeLong();
-       fBuffer.resize(bufferSize + sizeof(uint32_t));
-       google::protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray(bufferSize,
-                       reinterpret_cast<google::protobuf::uint8 *>(&fBuffer[0]));
-       if(!message.SerializeToArray(&fBuffer[sizeof(uint32_t)], bufferSize)) {
-               throw std::invalid_argument("Message serialization error");
-       }
-}
-
-protobuf_async_message_deserialization::protobuf_async_message_deserialization()
-{
-       fBuffer.reserve(128);
-}
-
-bool protobuf_async_message_deserialization::decode_received_message(google::protobuf::MessageLite& message)
-{
-       return message.ParseFromArray(&fBuffer[0], fBuffer.size());
-}
diff --git a/shared/protobuf_asio.h b/shared/protobuf_asio.h
deleted file mode 100644 (file)
index a040352..0000000
+++ /dev/null
@@ -1,108 +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 SHARED_PROTOBUF_ASIO_H_
-#define SHARED_PROTOBUF_ASIO_H_
-
-#include <vector>
-
-#include <boost/asio.hpp>
-#include <boost/noncopyable.hpp>
-#include <google/protobuf/message_lite.h>
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
-#include <google/protobuf/io/coded_stream.h>
-
-static const size_t MESSAGE_LENGHT_MAX = 65536;
-
-class protobuf_sync_message_serialization final :
-       boost::noncopyable,
-       google::protobuf::io::CopyingOutputStream
-{
-       boost::asio::local::stream_protocol::socket& fSocket;
-public:
-       protobuf_sync_message_serialization(boost::asio::local::stream_protocol::socket& socket);
-       void encodeMessage(const google::protobuf::MessageLite& message);
-
-private:
-       virtual bool Write(const void* buffer, int size) override;
-};
-
-class protobuf_sync_message_deserialization final : boost::noncopyable
-{
-       boost::asio::local::stream_protocol::socket& fSocket;
-public:
-       protobuf_sync_message_deserialization(boost::asio::local::stream_protocol::socket& socket);
-       void decodeMessage(google::protobuf::MessageLite& message);
-};
-
-class protobuf_async_message_serialization final : boost::noncopyable
-{
-       std::vector<char> fBuffer;
-public:
-       void encodeMessage(const google::protobuf::MessageLite& message);
-
-       template<typename WriteStream, typename WriteHandler> void async_write(WriteStream& stream, WriteHandler&& handler) {
-               boost::asio::async_write(stream, boost::asio::buffer(fBuffer), handler);
-       }
-};
-
-class protobuf_async_message_deserialization final : public boost::noncopyable
-{
-       std::vector<char> fBuffer;
-       google::protobuf::uint32 fMessageLength = 0;
-public:
-       protobuf_async_message_deserialization();
-
-       template<typename ReadSocket, typename ReadHandler> void read_message(ReadSocket& socket, ReadHandler&& handler) {
-               fBuffer.resize(4);
-               fMessageLength = 0;
-
-               boost::asio::async_read(socket, boost::asio::buffer(fBuffer),
-                       [this, handler, &socket](const boost::system::error_code& error, std::size_t bytes_read) {
-                               if(!error) {
-                                       assert(bytes_read == fBuffer.size());
-                                       (void)bytes_read;
-                                       assert(fMessageLength == 0);
-
-                                       google::protobuf::io::CodedInputStream::ReadLittleEndian32FromArray(
-                                               (const google::protobuf::uint8 *)&fBuffer[0], &fMessageLength);
-
-                                       if(fMessageLength >= 1 && fMessageLength < MESSAGE_LENGHT_MAX) {
-                                               try {
-                                                       fBuffer.resize(fMessageLength);
-                                               } catch(...) {
-                                                       handler(boost::system::errc::make_error_code(boost::system::errc::not_enough_memory), 0);
-                                                       return;
-                                               }
-
-                                               boost::asio::async_read(socket, boost::asio::buffer(fBuffer), handler);
-                                       } else {
-                                               handler(boost::system::errc::make_error_code(boost::system::errc::message_size), 0);
-                                       }
-                               } else {
-                                       handler(error, 0);
-                               }
-               });
-       }
-
-       bool decode_received_message(google::protobuf::MessageLite& message);
-};
-
-#endif /* SHARED_PROTOBUF_ASIO_H_ */
diff --git a/src/dcm-client/CMakeLists.txt b/src/dcm-client/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ac78ed7
--- /dev/null
@@ -0,0 +1,70 @@
+# Copyright (c) 2017 - 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        dcm-client/CMakeLists.txt
+# @author      Dariusz Michaluk <d.michaluk@samsung.com>
+# @author      Jaroslaw Pelczar <j.pelczar@samsung.com>
+
+FIND_PACKAGE(Threads REQUIRED)
+FIND_PACKAGE(Protobuf REQUIRED)
+
+FIND_LIBRARY(MBEDTLS_LIB mbedtls)
+
+FIND_PACKAGE(Boost REQUIRED
+       COMPONENTS
+       system)
+
+PKG_CHECK_MODULES(CLIENT_DEPS REQUIRED dlog)
+
+INCLUDE_DIRECTORIES(SYSTEM ${CLIENT_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
+LINK_DIRECTORIES(${CLIENT_DEPS_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS dcm_support.proto)
+
+SET(TARGET_CLIENT "device-certificate-manager")
+ADD_LIBRARY(${TARGET_CLIENT}
+       SHARED
+       dcmclient.cpp
+       device_certificate_manager.cpp
+       ../shared/protobuf_asio.cpp
+       ${PROTO_SRCS}
+       ${PROTO_HDRS})
+
+TARGET_LINK_LIBRARIES(${TARGET_CLIENT}
+       ${Boost_SYSTEM_LIBRARY}
+       ${PROTOBUF_LITE_LIBRARIES}
+       ${MBEDTLS_LIB}
+       ${CLIENT_DEPS_LIBRARIES}
+       ${CMAKE_THREAD_LIBS_INIT})
+
+SET_PROPERTY(TARGET ${TARGET_CLIENT} APPEND PROPERTY LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version_script.lds")
+SET_TARGET_PROPERTIES(${TARGET_CLIENT}
+       PROPERTIES
+       VERSION ${PROJECT_VERSION}
+       DEFINE_SYMBOL DEVICE_CERTIFICATE_MANAGER_EXPORT
+       VISIBILITY_INLINES_HIDDEN TRUE
+       C_VISIBILITY_PRESET hidden
+       CXX_VISIBILITY_PRESET hidden)
+
+INSTALL(TARGETS ${TARGET_CLIENT}
+       LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+INSTALL(FILES
+       device_certificate_manager.h
+       DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/device-certificate-manager)
+
+INSTALL(FILES
+       ${CMAKE_CURRENT_BINARY_DIR}/dcm_support.pb.h
+       DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/device-certificate-manager-backend)
diff --git a/src/dcm-client/dcm_client.h b/src/dcm-client/dcm_client.h
new file mode 100644 (file)
index 0000000..bd6ce70
--- /dev/null
@@ -0,0 +1,80 @@
+/******************************************************************
+ *
+ * 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_CLIENT_DCM_CLIENT_H_
+#define DCM_CLIENT_DCM_CLIENT_H_
+
+#include <mbedtls/md.h>
+
+#include <memory>
+#include <vector>
+
+class dcm_client_connection :
+       public std::enable_shared_from_this<dcm_client_connection>
+{
+private:
+       dcm_client_connection(const dcm_client_connection&) = delete;
+       dcm_client_connection& operator = (const dcm_client_connection&) = delete;
+
+protected:
+       dcm_client_connection();
+       ~dcm_client_connection();
+
+public:
+       /*!
+        * Initialize default instance of the client connection.
+        *
+        * Standard C++ exceptions may be thrown in case of error
+        */
+       static std::shared_ptr<dcm_client_connection> create();
+
+       /*!
+        * Associate key context with this object. This function can be called
+        * only once. This function doesn't throw any exceptions.
+        */
+       virtual bool create_context(const std::string& serviceName,
+                       const std::string& usage,
+                       const std::string& key_type) noexcept = 0;
+
+
+       /*!
+        * Request certificate chain associated with this context
+        */
+       virtual int get_certificate_chain(std::vector<uint8_t>& chain) noexcept = 0;
+
+       /*!
+        * Return name of key type (UNKNOWN, RSA or ECDSA for now)
+        */
+       virtual const std::string& key_type() const noexcept = 0;
+
+       /*!
+        * Return length of the crypto key in bits
+        */
+       virtual unsigned int key_length() const noexcept = 0;
+
+       /*!
+        * Sign data with context certificate
+        */
+       virtual int sign_data(mbedtls_md_type_t digestType,
+                               const void * hash_data, size_t hash_size,
+                               std::vector<uint8_t>& digest) noexcept = 0;
+};
+
+#endif /* DCM_CLIENT_DCM_CLIENT_H_ */
diff --git a/src/dcm-client/dcm_client_p.h b/src/dcm-client/dcm_client_p.h
new file mode 100644 (file)
index 0000000..9fe1749
--- /dev/null
@@ -0,0 +1,67 @@
+/******************************************************************
+ *
+ * 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_CLIENT_DCM_CLIENT_P_H_
+#define DCM_CLIENT_DCM_CLIENT_P_H_
+
+#include "dcm_client.h"
+#include "dcm_support.pb.h"
+#include <memory>
+#include <mutex>
+#include <array>
+#include <boost/asio.hpp>
+
+class dcm_client_connection_impl final : public dcm_client_connection
+{
+public:
+       dcm_client_connection_impl();
+       dcm_client_connection_impl(boost::asio::io_service& ioService);
+       virtual ~dcm_client_connection_impl();
+
+       bool create_context(const std::string& serviceName,
+                       const std::string& usage,
+                       const std::string& key_type) noexcept override;
+
+       int get_certificate_chain(std::vector<uint8_t>& chain) noexcept override;
+
+       const std::string& key_type() const noexcept override;
+
+       unsigned int key_length() const noexcept override;
+
+       int sign_data(mbedtls_md_type_t digestType,
+                                       const void * hash_data, size_t hash_size,
+                                       std::vector<uint8_t>& digest) noexcept override;
+
+       void sendReceive(RequestMessage& request, ResponseMessage& response);
+
+private:
+       void ensureSocketConnected();
+
+
+private:
+       boost::asio::io_service                 fIOService;
+       std::mutex                                              fLock;
+       uint64_t                                                fCookie = 0;
+       std::unique_ptr<boost::asio::local::stream_protocol::socket> fSocket;
+       CryptoKeyType                                   fKeyType = CRYPTO_KEY_TYPE_INVALID;
+       unsigned int                                    fKeyLength = 0;
+};
+
+#endif /* DCM_CLIENT_DCM_CLIENT_P_H_ */
diff --git a/src/dcm-client/dcm_support.proto b/src/dcm-client/dcm_support.proto
new file mode 100644 (file)
index 0000000..4adc4cf
--- /dev/null
@@ -0,0 +1,82 @@
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+
+/*
+ * Type of the crypto key
+ */
+enum CryptoKeyType {
+       CRYPTO_KEY_TYPE_INVALID = 0;
+       CRYPTO_KEY_TYPE_ECDSA = 1;
+       CRYPTO_KEY_TYPE_RSA = 2;
+}
+
+/*
+ * These values match the mbedtls ones
+ */
+enum MessageDigestType {
+    MD_NONE = 0;
+    MD_MD2 = 1;
+    MD_MD4 = 2;
+    MD_MD5 = 3;
+    MD_SHA1 = 4;
+    MD_SHA224 = 5;
+    MD_SHA256 = 6;
+    MD_SHA384 = 7;
+    MD_SHA512 = 8;
+    MD_RIPEMD160 = 9;
+}
+
+message AssociateKeyContext
+{
+               required string service = 1;
+               required string usage = 2;
+               required string key_type = 3;
+}
+
+message AssociateKeyContextResponse
+{
+               required int32 result = 1;
+               optional uint64 context_cookie = 2;
+               optional CryptoKeyType key_type = 3;
+               optional uint32 key_length = 4;
+}
+
+message RequestCertificateChain
+{
+               required uint64 context_cookie = 1;
+}
+
+message RequestCertificateChainResponse
+{
+               required int32 result = 1;
+               optional bytes cert_chain = 2;
+}
+
+message SignRequest
+{
+               required uint64 context_cookie = 1;
+               required bytes data_to_sign = 2;
+               required MessageDigestType digest_type = 3;
+}
+
+message SignResponse
+{
+               required int32 result = 1;
+               optional bytes signature = 2;
+}
+
+message RequestMessage {
+       oneof request_oneof {
+               AssociateKeyContext                     associate_context = 1;
+               RequestCertificateChain         request_chain = 2;
+               SignRequest                                     sign_data = 3;
+       }
+}
+
+message ResponseMessage {
+       oneof reply_oneof {
+               AssociateKeyContextResponse             associate_context = 1;
+               RequestCertificateChainResponse request_chain = 2;
+               SignResponse                                    sign_data = 3;
+       }
+}
diff --git a/src/dcm-client/dcmclient.cpp b/src/dcm-client/dcmclient.cpp
new file mode 100644 (file)
index 0000000..322420b
--- /dev/null
@@ -0,0 +1,307 @@
+/******************************************************************
+ *
+ * Copyright 2017 - 2020 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.
+ *
+ ******************************************************************/
+
+#include "dcm_client_p.h"
+#include "dcm_support.pb.h"
+#include "device_certificate_manager.h"
+#include <cassert>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/coded_stream.h>
+#include "protobuf_asio.h"
+#include <inttypes.h>
+#include <mbedtls/ssl.h>
+
+#define LOG_TAG                "DCM_CLIENT"
+#include <dlog.h>
+
+static_assert(MD_NONE == (unsigned int)MBEDTLS_MD_NONE, "MBEDTLS_MD_NONE mismatch");
+static_assert(MD_MD2 == (unsigned int)MBEDTLS_MD_MD2, "MBEDTLS_MD_MD2 mismatch");
+static_assert(MD_MD4 == (unsigned int)MBEDTLS_MD_MD4, "MBEDTLS_MD_MD4 mismatch");
+static_assert(MD_MD5 == (unsigned int)MBEDTLS_MD_MD5, "MBEDTLS_MD_MD5 mismatch");
+static_assert(MD_SHA1 == (unsigned int)MBEDTLS_MD_SHA1, "MBEDTLS_MD_SHA1 mismatch");
+static_assert(MD_SHA224 == (unsigned int)MBEDTLS_MD_SHA224, "MBEDTLS_MD_SHA224 mismatch");
+static_assert(MD_SHA256 == (unsigned int)MBEDTLS_MD_SHA256, "MBEDTLS_MD_SHA256 mismatch");
+static_assert(MD_SHA384 == (unsigned int)MBEDTLS_MD_SHA384, "MBEDTLS_MD_SHA384 mismatch");
+static_assert(MD_SHA512 == (unsigned int)MBEDTLS_MD_SHA512, "MBEDTLS_MD_SHA512 mismatch");
+static_assert(MD_RIPEMD160 == (unsigned int)MBEDTLS_MD_RIPEMD160, "MBEDTLS_MD_RIPEMD160 mismatch");
+
+static std::string sKeyTypeUnknown("UNKNOWN");
+static std::string sKeyTypeRSA("RSA");
+static std::string sKeyTypeECDSA("ECDSA");
+
+dcm_client_connection_impl::dcm_client_connection_impl()
+{
+}
+
+dcm_client_connection_impl::~dcm_client_connection_impl()
+{
+}
+
+dcm_client_connection::dcm_client_connection()
+{
+}
+
+dcm_client_connection::~dcm_client_connection()
+{
+}
+
+std::shared_ptr<dcm_client_connection> dcm_client_connection::create()
+{
+       return std::make_shared<dcm_client_connection_impl>();
+}
+
+void dcm_client_connection_impl::sendReceive(RequestMessage& request, ResponseMessage& response)
+{
+       protobuf_sync_message_serialization(*fSocket).encodeMessage(request);
+       protobuf_sync_message_deserialization(*fSocket).decodeMessage(response);
+}
+
+bool dcm_client_connection_impl::create_context(const std::string& serviceName,
+               const std::string& usage,
+               const std::string& key_type) noexcept
+{
+       std::lock_guard<std::mutex> locker(fLock);
+
+       if(fCookie) {
+               LOGE("%s: Cookie has already been requested for session %p", __FUNCTION__, this);
+               // Already created
+               return false;
+       }
+
+       if(!fSocket) {
+               try {
+                       ensureSocketConnected();
+               } catch(std::exception& ex) {
+                       LOGE("%s: Caught exception \"%s\" when connecting socket for session %p", __FUNCTION__, ex.what(), this);
+                       return false;
+               } catch(...) {
+                       LOGE("%s: Caught unknown exception when connecting socket for session %p", __FUNCTION__, this);
+                       return false;
+               }
+       }
+
+       try {
+               RequestMessage request;
+               ResponseMessage response;
+
+               auto * assoc_req = request.mutable_associate_context();
+
+               assoc_req->set_service(serviceName);
+               assoc_req->set_usage(usage);
+               assoc_req->set_key_type(key_type);
+
+               sendReceive(request, response);
+
+               if(!response.has_associate_context()) {
+                       LOGE("%s: received response is not context association message in context %p", __FUNCTION__, this);
+                       return false;
+               }
+
+               auto& assoc_message(response.associate_context());
+
+               if(assoc_message.result() != 0) {
+                       LOGE("%s: Received context association message with error %d in %p", __FUNCTION__, assoc_message.result(), this);
+                       return false;
+               }
+
+               fCookie = assoc_message.context_cookie();
+               fKeyType = assoc_message.key_type();
+               fKeyLength = assoc_message.key_length();
+       } catch(std::exception& ex) {
+               LOGE("%s: Caught exception \"%s\" when establishing cookie for session %p", __FUNCTION__, ex.what(), this);
+               fSocket.reset();
+               return false;
+       } catch(...) {
+               LOGE("%s: Caught unknown exception when establishing cookie for session %p", __FUNCTION__, this);
+               fSocket.reset();
+               return false;
+       }
+
+       return true;
+}
+
+void dcm_client_connection_impl::ensureSocketConnected()
+{
+       fSocket.reset(new boost::asio::local::stream_protocol::socket(fIOService));
+       boost::asio::local::stream_protocol::endpoint endpoint(DCM_UNIX_SOCKET_PATH);
+       fSocket->connect(endpoint);
+}
+
+int dcm_client_connection_impl::get_certificate_chain(std::vector<uint8_t>& chain) noexcept
+{
+       std::lock_guard<std::mutex> locker(fLock);
+
+       if(!fCookie) {
+               LOGE("%s: Trying to request certificate in session %p without connection", __FUNCTION__, this);
+               return DCM_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               RequestMessage request;
+               ResponseMessage response;
+
+               auto * cert_req  = request.mutable_request_chain();
+
+               cert_req->set_context_cookie(fCookie);
+
+               sendReceive(request, response);
+
+               if(!response.has_request_chain()) {
+                       LOGE("%s: Response from server is not certificate chain response on session %p", __FUNCTION__, this);
+                       return DCM_ERROR_NO_DATA;
+               }
+
+               auto& cert_resp(response.request_chain());
+
+               if(cert_resp.result() != 0) {
+                       LOGE("%s: Server can't respond with certificate chain: error %d in session %p", __FUNCTION__,
+                                       cert_resp.result(), this);
+                       return DCM_ERROR_NO_DATA;
+               }
+
+               if(cert_resp.cert_chain().size() == 0) {
+                       LOGE("%s: Server can't respond with certificate chain: certificate empty", __FUNCTION__);
+                       return DCM_ERROR_NO_DATA;
+               }
+
+               // Add space for last zero byte if needed
+               chain.reserve(cert_resp.cert_chain().size() + 1);
+               chain.resize(cert_resp.cert_chain().size());
+
+               memcpy(&chain[0], cert_resp.cert_chain().c_str(), cert_resp.cert_chain().size());
+
+               if(chain[chain.size() - 1] != 0) {
+                       // Pad with zero
+                       chain.push_back(0);
+               }
+       } catch(std::bad_alloc&) {
+               LOGE("%s: Out of memory when requesting certificate for session %p", __FUNCTION__, this);
+               return DCM_ERROR_OUT_OF_MEMORY;
+       } catch(std::invalid_argument&) {
+               LOGE("%s: Invalid argument passed for certificate request for session %p", __FUNCTION__, this);
+               return DCM_ERROR_INVALID_PARAMETER;
+       } catch(std::exception& ex) {
+               LOGE("%s: When requesting certificate for session %p received exception : %s", __FUNCTION__, this, ex.what());
+               return DCM_ERROR_UNKNOWN;
+       } catch(...) {
+               LOGE("%s: When requesting certificate for session %p received exception : %s", __FUNCTION__, this, "Unknown error");
+               return DCM_ERROR_UNKNOWN;
+       }
+
+       return DCM_ERROR_NONE;
+}
+
+const std::string& dcm_client_connection_impl::key_type() const noexcept {
+       switch(fKeyType) {
+       case CRYPTO_KEY_TYPE_RSA: return sKeyTypeRSA;
+       case CRYPTO_KEY_TYPE_ECDSA: return sKeyTypeECDSA;
+       default: return sKeyTypeUnknown;
+       }
+}
+
+int dcm_client_connection_impl::sign_data(mbedtls_md_type_t digestType, const void * hash_data,
+               size_t hash_size, std::vector<uint8_t>& digest) noexcept
+{
+       std::lock_guard<std::mutex> locker(fLock);
+
+       if(!fCookie) {
+               LOGE("%s: Trying to request data signing in object %p but there is no connection", __FUNCTION__, this);
+               return DCM_ERROR_SOCKET;
+       }
+
+       /*
+        * If hash_size == 0 then hash type must be known
+        */
+       if(hash_size == 0) {
+               if(digestType == MBEDTLS_MD_NONE) {
+                       LOGE("%s: Digest type is NONE and hash size is 0", __FUNCTION__);
+                       return DCM_ERROR_INVALID_PARAMETER;
+               }
+
+               const mbedtls_md_info_t * md_info = mbedtls_md_info_from_type(digestType);
+
+               if(!md_info) {
+                       LOGE("%s: Can't find hash data for digest type %d", __FUNCTION__, digestType);
+                       return DCM_ERROR_INVALID_PARAMETER;
+               }
+
+               hash_size = mbedtls_md_get_size(md_info);
+       } else if(hash_size != 0 && digestType != MBEDTLS_MD_NONE) {
+               /*
+                * If hash_size != 0 then hash type can be specified
+                */
+               const mbedtls_md_info_t * md_info = mbedtls_md_info_from_type(digestType);
+
+               if(!md_info) {
+                       LOGE("%s: Can't find hash data for digest type %d", __FUNCTION__, digestType);
+                       return DCM_ERROR_INVALID_PARAMETER;
+               }
+
+               if(hash_size != mbedtls_md_get_size(md_info)) {
+                       LOGE("%s: Hash size mismatch. Expected %zd but got %zd", __FUNCTION__, hash_size, (size_t)mbedtls_md_get_size(md_info));
+                       return DCM_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       try {
+               RequestMessage request;
+               ResponseMessage response;
+
+               auto * sign_req  = request.mutable_sign_data();
+
+               sign_req->set_context_cookie(fCookie);
+               sign_req->set_data_to_sign(hash_data, hash_size);
+               sign_req->set_digest_type(static_cast<MessageDigestType>(digestType));
+
+               sendReceive(request, response);
+
+               if(!response.has_sign_data()) {
+                       LOGE("%s: Response for hash signature has no signature data", __FUNCTION__);
+                       return DCM_ERROR_INVALID_PARAMETER;
+               }
+
+               auto& sign_resp(response.sign_data());
+
+               if(sign_resp.result() != 0) {
+                       LOGE("%s: Signature request for session %p received error %d", __FUNCTION__, this, sign_resp.result());
+                       return DCM_ERROR_INVALID_PARAMETER;
+               }
+
+               const auto& signature = sign_resp.signature();
+
+               if(signature.empty()) {
+                       LOGE("%s: Received signature object is empty for session %p", __FUNCTION__, this);
+                       return DCM_ERROR_INVALID_PARAMETER;
+               }
+
+               digest.resize(signature.size());
+               memcpy(&digest[0], signature.c_str(), signature.size());
+       } catch(std::bad_alloc&) {
+               LOGE("%s: Out of memory when processing sign request for session %p", __FUNCTION__, this);
+               return DCM_ERROR_OUT_OF_MEMORY;
+       } catch(...) {
+               LOGE("%s: When processing signature for session %p got exception : %s", __FUNCTION__, this, "Unknown error");
+               return DCM_ERROR_UNKNOWN;
+       }
+
+       return DCM_ERROR_NONE;
+}
+
+unsigned int dcm_client_connection_impl::key_length() const noexcept {
+       return fKeyLength;
+}
diff --git a/src/dcm-client/device_certificate_manager.cpp b/src/dcm-client/device_certificate_manager.cpp
new file mode 100644 (file)
index 0000000..bef03c8
--- /dev/null
@@ -0,0 +1,187 @@
+/******************************************************************
+ *
+ * Copyright 2017 - 2020 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.
+ *
+ ******************************************************************/
+
+#include "device_certificate_manager.h"
+#include "dcm_client.h"
+
+#include <mbedtls/pk_internal.h>
+#include <mbedtls/md.h>
+
+#include <vector>
+#include <cstring>
+
+#ifndef API_DEVICE_CERTIFICATE_MANAGER_EXPORT
+#define API_DEVICE_CERTIFICATE_MANAGER_EXPORT __attribute__((visibility("default")))
+#endif
+
+#define LOG_TAG                "DCM_CLIENT"
+#include <dlog.h>
+
+static mbedtls_md_type_t to_mbedtls_md_type(dcm_digest_algorithm_e md)
+{
+  switch(md) {
+    case DCM_DIGEST_NONE:
+      return MBEDTLS_MD_NONE;
+    case DCM_DIGEST_MD2:
+      return MBEDTLS_MD_MD2;
+    case DCM_DIGEST_MD4:
+      return MBEDTLS_MD_MD4;
+    case DCM_DIGEST_MD5:
+      return MBEDTLS_MD_MD5;
+    case DCM_DIGEST_SHA1:
+      return MBEDTLS_MD_SHA1;
+    case DCM_DIGEST_SHA224:
+      return MBEDTLS_MD_SHA224;
+    case DCM_DIGEST_SHA256:
+      return MBEDTLS_MD_SHA256;
+    case DCM_DIGEST_SHA384:
+      return MBEDTLS_MD_SHA384;
+    case DCM_DIGEST_SHA512:
+      return MBEDTLS_MD_SHA512;
+    case DCM_DIGEST_RIPEMD160:
+      return MBEDTLS_MD_RIPEMD160;
+    default:
+      return MBEDTLS_MD_NONE;
+  }
+}
+
+struct dcm_key_context_internal {
+       std::shared_ptr<dcm_client_connection> connection;
+};
+
+API_DEVICE_CERTIFICATE_MANAGER_EXPORT
+int dcm_create_key_context(const char *service, const char *usage, const char *key_type, void **key_ctx)
+{
+       try {
+               if(!key_ctx)
+                       return DCM_ERROR_INVALID_PARAMETER;
+
+               std::unique_ptr<dcm_key_context_internal> context(new dcm_key_context_internal());
+
+               std::string service_string(service ? service : "");
+               std::string usage_string(usage ? usage : "");
+               std::string keytype_string(key_type ? key_type : "");
+
+               context->connection = dcm_client_connection::create();
+
+               if(!context->connection->create_context(service_string, usage_string, keytype_string)) {
+                       LOGE("Can't create connection context");
+                       return DCM_ERROR_SOCKET;
+               }
+
+               *key_ctx = context.release();
+               return DCM_ERROR_NONE;
+       } catch(std::exception& ex) {
+               LOGE("Context creation failure: %s", ex.what());
+               return DCM_ERROR_UNKNOWN;
+       } catch(...) {
+               LOGE("Context creation failure");
+               return DCM_ERROR_UNKNOWN;
+       }
+}
+
+API_DEVICE_CERTIFICATE_MANAGER_EXPORT
+int dcm_free_key_context(void *key_ctx)
+{
+       if(!key_ctx)
+               return DCM_ERROR_NONE;
+
+       delete reinterpret_cast<dcm_key_context_internal *>(key_ctx);
+
+       return DCM_ERROR_NONE;
+}
+
+API_DEVICE_CERTIFICATE_MANAGER_EXPORT
+int dcm_get_certificate_chain(const void *key_ctx, char **cert_chain, size_t *cert_chain_len)
+{
+       if(!key_ctx || !cert_chain || !cert_chain_len)
+               return DCM_ERROR_INVALID_PARAMETER;
+
+       const dcm_key_context_internal *context =
+               reinterpret_cast<const dcm_key_context_internal *>(key_ctx);
+
+       std::vector<uint8_t> cert;
+       int result = context->connection->get_certificate_chain(cert);
+       if(result == DCM_ERROR_NONE) {
+               *cert_chain = (char*)malloc(sizeof(uint8_t) * cert.size());
+               if(*cert_chain == NULL)
+                       return DCM_ERROR_OUT_OF_MEMORY;
+               memcpy(*cert_chain, cert.data(), cert.size());
+               *cert_chain_len = cert.size();
+       }
+
+       return result;
+}
+
+API_DEVICE_CERTIFICATE_MANAGER_EXPORT
+int dcm_get_key_bit_length(const void *key_ctx, size_t *key_bit_len)
+{
+       if(!key_ctx || !key_bit_len)
+               return DCM_ERROR_INVALID_PARAMETER;
+
+       const dcm_key_context_internal *context =
+               reinterpret_cast<const dcm_key_context_internal *>(key_ctx);
+       *key_bit_len = context->connection->key_length();
+
+       return DCM_ERROR_NONE;
+}
+
+API_DEVICE_CERTIFICATE_MANAGER_EXPORT
+int dcm_get_key_type(const void *key_ctx, char **key_type)
+{
+       if(!key_ctx || !key_type)
+               return DCM_ERROR_INVALID_PARAMETER;
+
+       const dcm_key_context_internal *context =
+               reinterpret_cast<const dcm_key_context_internal *>(key_ctx);
+
+       std::string type = context->connection->key_type();
+       *key_type = (char*)malloc(sizeof(char) * (type.length() + 1));
+       if(*key_type == NULL)
+               return DCM_ERROR_OUT_OF_MEMORY;
+       memcpy(*key_type, type.c_str(), type.length() + 1);
+
+       return DCM_ERROR_NONE;
+}
+
+API_DEVICE_CERTIFICATE_MANAGER_EXPORT
+int dcm_create_signature(const void *key_ctx, dcm_digest_algorithm_e md,
+                        const char *message, size_t message_len,
+                        char **signature, size_t *signature_len)
+{
+       if(!key_ctx || !signature || !signature_len)
+               return DCM_ERROR_INVALID_PARAMETER;
+
+       const dcm_key_context_internal *context =
+               reinterpret_cast<const dcm_key_context_internal *>(key_ctx);
+
+       std::vector<uint8_t> digest;
+       int result = context->connection->sign_data(to_mbedtls_md_type(md), message, message_len, digest);
+       if(result == DCM_ERROR_NONE) {
+               if(digest.size() > MBEDTLS_MPI_MAX_SIZE)
+                       return DCM_ERROR_INVALID_PARAMETER;
+
+               *signature = (char*)malloc(sizeof(uint8_t) * digest.size());
+               if(*signature == NULL)
+                       return DCM_ERROR_OUT_OF_MEMORY;
+               memcpy(*signature, digest.data(), digest.size());
+               *signature_len = digest.size();
+       }
+
+       return result;
+}
diff --git a/src/dcm-client/device_certificate_manager.h b/src/dcm-client/device_certificate_manager.h
new file mode 100644 (file)
index 0000000..9e53a83
--- /dev/null
@@ -0,0 +1,240 @@
+/******************************************************************
+ *
+ * Copyright 2017 - 2018 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 __DEVICE_CERTIFICATE_MANAGER_H__
+#define __DEVICE_CERTIFICATE_MANAGER_H__
+
+#include <stddef.h>
+#include <tizen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_DEVICE_CERTIFICATE_MANAGER_MODULE
+ * @{
+ */
+
+
+/**
+ * @brief Enumeration for DCM error values.
+ * @since_tizen 5.0
+ */
+typedef enum {
+    DCM_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+    DCM_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid function parameter */
+    DCM_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+    DCM_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
+    DCM_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Feature needed to run API is not supported */
+    DCM_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< No data available */
+    DCM_ERROR_UNKNOWN = TIZEN_ERROR_UNKNOWN, /**< Unknown error */
+
+    DCM_ERROR_SOCKET = TIZEN_ERROR_DEVICE_CERTIFICATE_MANAGER | 0x01, /**< Socket error between client and server */
+} dcm_error_e;
+
+
+/**
+ * @brief Enumeration for DCM message digest algorithms.
+ * @since_tizen 5.0
+ */
+typedef enum {
+    DCM_DIGEST_NONE=0, /**< No message digest algorithm */
+    DCM_DIGEST_MD2, /**< Message digest algorithm MD2 */
+    DCM_DIGEST_MD4, /**< Message digest algorithm MD4 */
+    DCM_DIGEST_MD5, /**< Message digest algorithm MD5 */
+    DCM_DIGEST_SHA1, /**< Message digest algorithm SHA1 */
+    DCM_DIGEST_SHA224, /**< Message digest algorithm SHA224 */
+    DCM_DIGEST_SHA256, /**< Message digest algorithm SHA256 */
+    DCM_DIGEST_SHA384, /**< Message digest algorithm SHA384 */
+    DCM_DIGEST_SHA512, /**< Message digest algorithm SHA512 */
+    DCM_DIGEST_RIPEMD160, /**< Message digest algorithm RIPEMD160 */
+} dcm_digest_algorithm_e;
+
+
+/**
+ * @platform
+ * @brief Creates a new key context based on specific name indication (service name, key usage, key type).
+ * @since_tizen 5.0
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/devicecertificate
+ *
+ * @remarks The @a key_ctx should be freed with dcm_free_key_context() after use.
+ *
+ * @param[in] service  Service name indicates first category name (if null, default value is used)
+ * @param[in] usage  Usage name indicates sub-category name (if null, default value is used)
+ * @param[in] key_type  Key type name indication (if null, default value is used)
+ * @param[out] key_ctx  Newly created key context
+ * @return #DCM_ERROR_NONE on success,
+ *         otherwise a negative error value
+ *
+ * @retval #DCM_ERROR_NONE Successful
+ * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
+ * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
+ * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
+ * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
+ * @retval #DCM_ERROR_SOCKET Socket error between client and server
+ * @retval #DCM_ERROR_UNKNOWN Unknown error
+ *
+ * @see dcm_free_key_context()
+ */
+int dcm_create_key_context(const char *service, const char *usage, const char *key_type, void **key_ctx);
+
+
+/**
+ * @platform
+ * @brief Destroys the key context that was created by calling dcm_create_key_context().
+ * @since_tizen 5.0
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/devicecertificate
+ *
+ * @param[in] key_ctx  Key context object to be deallocated
+ * @return #DCM_ERROR_NONE on success,
+ *         otherwise a negative error value
+ *
+ * @retval #DCM_ERROR_NONE Successful
+ * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
+ * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
+ * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
+ * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
+ * @retval #DCM_ERROR_SOCKET Socket error between client and server
+ * @retval #DCM_ERROR_NO_DATA No such key context object
+ * @retval #DCM_ERROR_UNKNOWN Unknown error
+ *
+ * @see dcm_create_key_context()
+ */
+int dcm_free_key_context(void *key_ctx);
+
+
+/**
+ * @platform
+ * @brief Returns a certificate chain which was pre-injected in device.
+ * @since_tizen 5.0
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/devicecertificate
+ *
+ * @remarks The @a cert_chain should be freed using free().
+ *
+ * @param[in] key_ctx  Key context object that identifies proper certificate chain
+ * @param[out] cert_chain  Certificate chain in binary, will be allocated by the library
+ * @param[out] cert_chain_len  The total length of certificate chain
+ * @return #DCM_ERROR_NONE on success,
+ *         otherwise a negative error value
+ *
+ * @retval #DCM_ERROR_NONE Successful
+ * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
+ * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
+ * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
+ * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
+ * @retval #DCM_ERROR_SOCKET Socket error between client and server
+ * @retval #DCM_ERROR_NO_DATA No certificate chain available
+ * @retval #DCM_ERROR_UNKNOWN Unknown error
+ */
+int dcm_get_certificate_chain(const void *key_ctx, char **cert_chain, size_t *cert_chain_len);
+
+
+/**
+ * @platform
+ * @brief Returns the key size in bits for a given key context.
+ * @since_tizen 5.0
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/devicecertificate
+ *
+ * @param[in] key_ctx  Key context object that identifies proper certificate chain
+ * @param[out] key_bit_len  Key length in bits
+ * @return #DCM_ERROR_NONE on success,
+ *         otherwise a negative error value
+ *
+ * @retval #DCM_ERROR_NONE Successful
+ * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
+ * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
+ * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
+ * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
+ * @retval #DCM_ERROR_SOCKET Socket error between client and server
+ * @retval #DCM_ERROR_NO_DATA No certificate chain available
+ * @retval #DCM_ERROR_UNKNOWN Unknown error
+ */
+int dcm_get_key_bit_length(const void *key_ctx, size_t *key_bit_len);
+
+
+/**
+ * @platform
+ * @brief Returns the key type name for a given key context.
+ * @since_tizen 5.0
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/devicecertificate
+ *
+ * @remarks The @a key_type should be freed using free().
+ *
+ * @param[in] key_ctx  Key context object that identifies proper certificate chain
+ * @param[out] key_type  Key type name (UNKNOWN, RSA or ECDSA), will be allocated by the library
+ * @return #DCM_ERROR_NONE on success,
+ *         otherwise a negative error value
+ *
+ * @retval #DCM_ERROR_NONE Successful
+ * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
+ * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
+ * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
+ * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
+ * @retval #DCM_ERROR_SOCKET Socket error between client and server
+ * @retval #DCM_ERROR_NO_DATA No certificate chain available
+ * @retval #DCM_ERROR_UNKNOWN Unknown error
+ */
+int dcm_get_key_type(const void *key_ctx, char **key_type);
+
+/**
+ * @platform
+ * @brief Creates a signature on a given data using a private key and returns the signature.
+ * @since_tizen 5.0
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/devicecertificate
+ *
+ * @remarks The private key is identified by @a key_ctx.
+ * @remarks The @a message can be NULL but then @a message_len must be 0.
+ * @remarks The @a signature should be freed using free().
+ *
+ * @param[in] key_ctx  Key context object that identifies a proper private key for signing
+ * @param[in] md  Message digest algorithm used in creating signature
+ * @param[in] message  Message that is signed with a key
+ * @param[in] message_len  Length of the message
+ * @param[out] signature  Newly created signature, will be allocated by the library
+ * @param[out] signature_len  Length of a newly created signature
+ * @return #DCM_ERROR_NONE on success,
+ *         otherwise a negative error value
+ *
+ * @retval #DCM_ERROR_NONE Successful
+ * @retval #DCM_ERROR_INVALID_PARAMETER Input parameter is invalid
+ * @retval #DCM_ERROR_OUT_OF_MEMORY Out of memory during processing
+ * @retval #DCM_ERROR_PERMISSION_DENIED Failed to access device certificate manager
+ * @retval #DCM_ERROR_NOT_SUPPORTED Feature needed to run API is not supported
+ * @retval #DCM_ERROR_SOCKET Socket error between client and server
+ * @retval #DCM_ERROR_UNKNOWN Unknown error
+ */
+int dcm_create_signature(const void *key_ctx, dcm_digest_algorithm_e md,
+                         const char *message, size_t message_len,
+                         char **signature, size_t *signature_len);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DEVICE_CERTIFICATE_MANAGER_H__ */
diff --git a/src/dcm-client/version_script.lds b/src/dcm-client/version_script.lds
new file mode 100644 (file)
index 0000000..9b724fc
--- /dev/null
@@ -0,0 +1,11 @@
+DCMCLIENT_2.0 {
+       global:
+               dcm_create_key_context;
+               dcm_free_key_context;
+               dcm_get_certificate_chain;
+               dcm_get_key_bit_length;
+               dcm_get_key_type;
+               dcm_create_signature;
+       local:
+               *;
+};
diff --git a/src/dcm-daemon/CMakeLists.txt b/src/dcm-daemon/CMakeLists.txt
new file mode 100644 (file)
index 0000000..65b31de
--- /dev/null
@@ -0,0 +1,69 @@
+# Copyright (c) 2017 - 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        dcm-daemon/CMakeLists.txt
+# @author      Dariusz Michaluk <d.michaluk@samsung.com>
+# @author      Jaroslaw Pelczar <j.pelczar@samsung.com>
+
+FIND_PACKAGE(Threads REQUIRED)
+FIND_PACKAGE(Protobuf REQUIRED)
+
+FIND_PACKAGE(Boost REQUIRED
+       COMPONENTS
+       log
+       thread
+       system)
+
+PKG_CHECK_MODULES(DAEMON_DEPS
+       REQUIRED
+       libsystemd
+       cynara-client
+       cynara-creds-socket
+       cynara-session
+       dlog)
+
+INCLUDE_DIRECTORIES(SYSTEM ${DAEMON_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
+LINK_DIRECTORIES(${DAEMON_DEPS_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ../dcm-client/dcm_support.proto)
+
+ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)
+
+SET(TARGET_DAEMON "device-certificate-managerd")
+ADD_EXECUTABLE(${TARGET_DAEMON}
+       main.cpp
+       dcmserver.cpp
+       dcmsession.cpp
+       serviceadapter.cpp
+       ../shared/protobuf_asio.cpp
+       soresolver.cpp
+       ${PROTO_SRCS}
+       ${PROTO_HDRS})
+
+TARGET_LINK_LIBRARIES(${TARGET_DAEMON}
+       ${Boost_LOG_LIBRARY}
+       ${Boost_THREAD_LIBRARY}
+       ${Boost_SYSTEM_LIBRARY}
+       ${PROTOBUF_LITE_LIBRARIES}
+       ${DAEMON_DEPS_LIBRARIES}
+       ${CMAKE_THREAD_LIBS_INIT}
+       dl)
+
+INSTALL(TARGETS ${TARGET_DAEMON}
+       RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+INSTALL(FILES
+       dcm-backend-api.h
+       DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/device-certificate-manager-backend)
diff --git a/src/dcm-daemon/boost_log_dlog_sink.h b/src/dcm-daemon/boost_log_dlog_sink.h
new file mode 100644 (file)
index 0000000..89f50f3
--- /dev/null
@@ -0,0 +1,89 @@
+/******************************************************************
+ *
+ * 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 SHARED_BOOST_LOG_DLOG_SINK_H_
+#define SHARED_BOOST_LOG_DLOG_SINK_H_
+
+#include <boost/log/sinks.hpp>
+#include <functional>
+
+#include <dlog.h>
+
+template<typename AttributeValueT = int> class dlog_direct_severity_mapping :
+       public boost::log::sinks::basic_direct_mapping<log_priority, AttributeValueT>
+{
+       typedef  boost::log::sinks::basic_direct_mapping<log_priority, AttributeValueT> base_type;
+public:
+       explicit dlog_direct_severity_mapping(boost::log::attribute_name const& name) :
+               base_type(name)
+       {
+       }
+};
+
+template<typename AttributeValueT = int> class dlog_custom_severity_mapping :
+       public boost::log::sinks::basic_custom_mapping<log_priority, AttributeValueT>
+{
+       typedef  boost::log::sinks::basic_custom_mapping<log_priority, AttributeValueT> base_type;
+public:
+       explicit dlog_custom_severity_mapping(boost::log::attribute_name const& name) :
+               base_type(name, DLOG_DEBUG)
+       {
+       }
+};
+
+class dlog_output_backend :
+       public boost::log::sinks::basic_formatted_sink_backend<char>
+{
+       typedef boost::log::sinks::basic_formatted_sink_backend<char>   base_type;
+       typedef std::function< log_priority (boost::log::record_view const&) > severity_mapper_type;
+
+private:
+       std::string                             log_domain_;
+       severity_mapper_type    level_mapper_;
+
+       inline void send(log_priority level, string_type const& formatted_message) {
+               dlog_print(level, log_domain_.c_str(), "%s", formatted_message.c_str());
+       }
+
+public:
+       dlog_output_backend()
+       {
+       }
+
+    void consume(boost::log::record_view const& rec, string_type const& formatted_message) {
+       if(!level_mapper_) {
+               send(DLOG_DEBUG, formatted_message);
+       } else {
+               send(level_mapper_(rec), formatted_message);
+       }
+    }
+
+       void set_log_domain(const std::string& name)
+       {
+               log_domain_ = name;
+       }
+
+    void set_severity_mapper(severity_mapper_type const& mapper)
+    {
+       level_mapper_ = mapper;
+    }
+};
+
+#endif /* SHARED_BOOST_LOG_DLOG_SINK_H_ */
diff --git a/src/dcm-daemon/dcm-backend-api.h b/src/dcm-daemon/dcm-backend-api.h
new file mode 100644 (file)
index 0000000..208ff61
--- /dev/null
@@ -0,0 +1,65 @@
+/******************************************************************
+ *
+ * Copyright 2019 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& mutable_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/dcmserver.cpp b/src/dcm-daemon/dcmserver.cpp
new file mode 100644 (file)
index 0000000..bb6c509
--- /dev/null
@@ -0,0 +1,78 @@
+/******************************************************************
+ *
+ * Copyright 2017 - 2019 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 "dcmserver.h"
+#include "dcmsession.h"
+#include "logging.h"
+
+dcm_server::dcm_server(boost::asio::io_service& io_service, boost::asio::local::stream_protocol::acceptor&& acceptor, std::string lib_backend) :
+       fService(io_service),
+       fTimer(io_service),
+       fAcceptor(std::move(acceptor)),
+       fSoResolver(std::make_shared<so_resolver>(lib_backend))
+{
+       BOOST_LOG_FUNCTION();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Construct server object";
+}
+
+dcm_server::~dcm_server()
+{
+       BOOST_LOG_FUNCTION();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Destroy server object";
+}
+
+void dcm_server::start()
+{
+       do_accept();
+}
+
+void dcm_server::do_accept()
+{
+       BOOST_LOG_FUNCTION();
+
+       auto self(this->shared_from_this());
+       std::shared_ptr<dcm_session> session;
+
+       try {
+               session = std::make_shared<dcm_session>(fService, fTimer, shared_from_this(), fSoResolver);
+       } catch(std::bad_alloc& ex) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Out of memory when trying to allocate new session";
+               return;
+       } catch(std::exception& ex) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Can't create new session object: " << ex.what();
+               return;
+       }
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Start accepting connections";
+       session->start_timer();
+
+       fAcceptor.async_accept(session->socket(),
+               [session, self](boost::system::error_code error_code)
+               {
+                       BOOST_LOG_FUNCTION();
+                       if(!error_code) {
+                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Accepted session";
+                               session->start();
+                       } else {
+                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't accept new session " << error_code;
+                       }
+                       self->do_accept();
+               });
+}
diff --git a/src/dcm-daemon/dcmserver.h b/src/dcm-daemon/dcmserver.h
new file mode 100644 (file)
index 0000000..c05dc5b
--- /dev/null
@@ -0,0 +1,47 @@
+/******************************************************************
+ *
+ * Copyright 2017 - 2019 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_DCMSERVER_H_
+#define DCM_DAEMON_DCMSERVER_H_
+
+#include <boost/asio.hpp>
+#include <boost/noncopyable.hpp>
+#include <mutex>
+#include <memory>
+#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, boost::asio::local::stream_protocol::acceptor&& acceptor, std::string lib_backend);
+       ~dcm_server();
+       void start();
+
+private:
+       void do_accept();
+
+private:
+       boost::asio::io_service&                                                fService;
+       boost::asio::deadline_timer                                             fTimer;
+       boost::asio::local::stream_protocol::acceptor   fAcceptor;
+       std::mutex                                                                              fLock;
+       std::shared_ptr<so_resolver> fSoResolver;
+};
+
+#endif /* DCM_DAEMON_DCMSERVER_H_ */
diff --git a/src/dcm-daemon/dcmsession.cpp b/src/dcm-daemon/dcmsession.cpp
new file mode 100644 (file)
index 0000000..fa3c3f5
--- /dev/null
@@ -0,0 +1,440 @@
+/******************************************************************
+ *
+ * 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 "dcmsession.h"
+#include "logging.h"
+#include "exception_translator.h"
+#include "dcmserver.h"
+
+#include <iostream>
+#include <cassert>
+#include <map>
+#include <mutex>
+
+#include <cynara-client.h>
+#include <cynara-creds-socket.h>
+#include <cynara-session.h>
+
+extern cynara * gGlobalCynaraInstance;
+
+static inline std::string cynara_error_to_string(int error) {
+       char buffer[256];
+       int ret = cynara_strerror(error, buffer, sizeof(buffer));
+       if(ret == CYNARA_API_SUCCESS)
+               return std::string(buffer);
+       return std::string("Can't translate error");
+}
+
+unsigned int globalSessionCounter = 0;
+
+dcm_session::dcm_session(boost::asio::io_service& io_service,
+               boost::asio::deadline_timer& timer,
+               const std::shared_ptr<dcm_server>& server,
+               std::shared_ptr<so_resolver> soResolver) :
+       fService(io_service),
+       fTimer(timer),
+       fSocket(io_service),
+       fServer(server),
+       fSoResolver(soResolver)
+{
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Create new session object " << this;
+       globalSessionCounter++;
+}
+
+dcm_session::~dcm_session()
+{
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Destroy session object " << this;
+}
+
+struct string_free_deleter {
+       void operator()(char * p) const {
+               free(p);
+       }
+};
+
+bool dcm_session::verify_privileges(int handle)
+{
+       BOOST_LOG_FUNCTION();
+
+       int ret = 0;
+       char * tmp_str;
+       pid_t pid = 0;
+
+       std::unique_ptr<char, string_free_deleter> user;
+       std::unique_ptr<char, string_free_deleter> client;
+       std::unique_ptr<char, string_free_deleter> client_session;
+
+       /* Get user info */
+       tmp_str = nullptr;
+       ret = cynara_creds_socket_get_user(handle, USER_METHOD_DEFAULT, &tmp_str);
+       if(ret != CYNARA_API_SUCCESS) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get user from socket : " << ret << " - " << cynara_error_to_string(ret);
+               return false;
+       }
+       user.reset(tmp_str);
+
+       /* Get client info */
+       tmp_str = nullptr;
+       ret = cynara_creds_socket_get_client(handle, CLIENT_METHOD_DEFAULT, &tmp_str);
+       if(ret != CYNARA_API_SUCCESS) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get client from socket : " << ret << " - " << cynara_error_to_string(ret);
+               return false;
+       }
+       client.reset(tmp_str);
+
+
+       /* Get client PID from socket */
+       ret = cynara_creds_socket_get_pid(handle, &pid);
+       if(ret != CYNARA_API_SUCCESS) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get PID from socket : " << ret << " - " << cynara_error_to_string(ret);
+               return false;
+       }
+
+       client_session.reset(cynara_session_from_pid(pid));
+       if(!client_session) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get session identifier from PID";
+               return false;
+       }
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Got new session from " << pid << " with user " <<
+                       user.get() << ", client ID " << client.get() << " and session ID " << client_session.get();
+
+       ret = cynara_check(gGlobalCynaraInstance,
+                       client.get(),
+                       client_session.get(),
+                       user.get(),
+                       "http://tizen.org/privilege/devicecertificate");
+
+       if(ret != CYNARA_API_ACCESS_ALLOWED) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) <<
+                               "Application access denied - no internet permission for " <<
+                               pid <<
+                               " - " <<
+                               cynara_error_to_string(ret);
+
+               return false;
+       }
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Access granted for " << pid;
+
+       return true;
+}
+
+void dcm_session::start()
+{
+       BOOST_LOG_FUNCTION();
+
+       int handle = fSocket.native_handle();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Accepted connection with socket " << fSocket.native_handle();
+
+       if(verify_privileges(handle)) {
+               stop_timer();
+               do_receive();
+       } else {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Client privilege check failure. Disconnect";
+               start_timer();
+       }
+}
+
+void dcm_session::start_timer()
+{
+       globalSessionCounter--;
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Number of active connections: " << globalSessionCounter;
+
+       if(globalSessionCounter == 0) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "No active connections, server will be closed after few seconds";
+               fTimer.expires_from_now(boost::posix_time::seconds(10));
+               /* operation_aborted error is returned whenever we cancel the timer or we reset the timer using expires_from_now function */
+               fTimer.async_wait([this](const boost::system::error_code &error) {
+                       if(error != boost::asio::error::operation_aborted) {
+                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "No active connections, server will be closed";
+                               fService.stop();
+                       }
+               });
+       }
+}
+
+void dcm_session::stop_timer()
+{
+       globalSessionCounter++;
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Number of active connections: " << globalSessionCounter;
+
+       fTimer.cancel();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Timer cancelled";
+}
+
+void dcm_session::do_receive() noexcept
+{
+       BOOST_LOG_FUNCTION();
+
+       try {
+               auto self(shared_from_this());
+
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Read new message";
+
+               fDeserializer.read_message(fSocket,
+                       [self, this](const boost::system::error_code& error, std::size_t bytes_read) {
+                                       BOOST_LOG_FUNCTION();
+                                       if(!error) {
+                                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Received " << bytes_read << " bytes from client";
+                                               decode_message();
+                                       } else {
+                                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Client disconnected: " << error;
+                                               // Connection object will be released by shared ptr
+                                               start_timer();
+                                       }
+                       });
+       } catch(std::exception& ex) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while trying to read message : " << ex.what();
+               // Connection object will be released by shared ptr
+       } catch(...) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while trying to read message : " << "unknown";
+               // Connection object will be released by shared ptr
+       }
+}
+
+void dcm_session::decode_message() noexcept
+{
+       BOOST_LOG_FUNCTION();
+       try {
+               // Try to decode whole message
+               RequestMessage requestMessage;
+
+               if(!fDeserializer.decode_received_message(requestMessage)) {
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't parse message from stream";
+                       // This will terminate connection
+                       return;
+               }
+
+               switch(requestMessage.request_oneof_case())
+               {
+               case RequestMessage::kAssociateContext:
+                       handle_context_association(requestMessage.associate_context());
+                       break;
+               case RequestMessage::kRequestChain:
+                       handle_cert_chain(requestMessage.request_chain());
+                       break;
+               case RequestMessage::kSignData:
+                       handle_sign_request(requestMessage.sign_data());
+                       break;
+               default:
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Incorrect request message type";
+                       // This will terminate connection
+                       return;
+               }
+       } catch(std::exception& ex) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while parsing message : " << ex.what();
+               // Connection object will be released by shared ptr
+       } catch(...) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while parsing message : " << "unknown";
+               // Connection object will be released by shared ptr
+       }
+}
+
+void dcm_session::reply(const ResponseMessage& resp) noexcept
+{
+       BOOST_LOG_FUNCTION();
+       try {
+               auto self(shared_from_this());
+
+               fSerializer.encodeMessage(resp);
+
+               fSerializer.async_write(fSocket,
+                               [self, this](const boost::system::error_code& error, std::size_t bytes_written)
+                       {
+                               BOOST_LOG_FUNCTION();
+                               if(!error) {
+                                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Written " << bytes_written << " to socket";
+                                       do_receive();
+                               } else {
+                                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Server disconnected: " << error;
+                                       // Connection object will be released by shared ptr
+                               }
+                       });
+       } catch(std::exception& ex) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while sending message : " << ex.what();
+               // Connection object will be released by shared ptr
+       } catch(...) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while sending message : " << "unknown";
+               // Connection object will be released by shared ptr
+       }
+}
+
+void dcm_session::handle_context_association(const AssociateKeyContext& message)
+{
+       BOOST_LOG_FUNCTION();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Associate context";
+
+       ResponseMessage msg;
+       auto * contextResponse = msg.mutable_associate_context();
+
+       if(fBackendContext) {
+               contextResponse->set_result(EEXIST);
+               reply(msg);
+               return;
+       }
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Associate context from service " <<
+               message.service() << " with usage " << message.usage() << " and key type " << message.key_type();
+
+       auto server = fServer.lock();
+
+       if(!server) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Server object gone while handling message";
+               return;
+       }
+
+       int error = run_with_exception_handler([&]() {
+
+               bool loaded = fSoResolver->ensure_loaded();
+               if (loaded) {
+                       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()
+                       );
+
+                       CryptoKeyType crypto_key_type = fSoResolver->invoke<CryptoKeyType, dcm_backend_context&>(
+                               "dcm_backend_key_type",
+                               *fBackendContext
+                       );
+                       contextResponse->set_key_type(crypto_key_type);
+
+                       unsigned int crypto_key_length = fSoResolver->invoke<unsigned int, dcm_backend_context&>(
+                               "dcm_backend_key_length",
+                               *fBackendContext
+                       );
+                       contextResponse->set_key_length(crypto_key_length);
+               }
+               else {
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "No crypto usable backend available";
+                       throw std::invalid_argument("Unable to find crypto backend");
+               }
+               fCookie = (uintptr_t)fBackendContext.get();
+               contextResponse->set_context_cookie(fCookie);
+       });
+
+       contextResponse->set_result(error);
+
+       reply(msg);
+}
+
+static const std::string sPEMHeader("-----BEGIN CERTIFICATE-----\n");
+
+void dcm_session::handle_cert_chain(const RequestCertificateChain& message)
+{
+       BOOST_LOG_FUNCTION();
+
+       ResponseMessage msg;
+       auto * certificateResponse = msg.mutable_request_chain();
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Request certificate chain";
+
+       if(message.context_cookie() != fCookie) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Received unknown context cookie";
+               certificateResponse->set_result(-EINVAL);
+               reply(msg);
+               return;
+       }
+
+       if(!fBackendContext) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Context not associated with connection";
+               certificateResponse->set_result(-EINVAL);
+               reply(msg);
+               return;
+       }
+
+       std::string cert_chain;
+
+       int error = 0;
+       bool loaded = fSoResolver->ensure_loaded();
+       if (loaded) {
+               error = fSoResolver->invoke<int, dcm_backend_context&, std::string&>(
+                       "dcm_backend_request_certificate_chain",
+                       *fBackendContext,
+                       cert_chain
+               );
+       }
+
+       if(error != 0) {
+               certificateResponse->set_result(error);
+               reply(msg);
+               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);
+}
+
+void dcm_session::handle_sign_request(const SignRequest& message)
+{
+       BOOST_LOG_FUNCTION();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Request data signing";
+
+       ResponseMessage msg;
+       auto * signingResponse = msg.mutable_sign_data();
+
+       if(message.context_cookie() != fCookie) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Received unknown context cookie";
+               signingResponse->set_result(-EINVAL);
+               reply(msg);
+               return;
+       }
+
+       if(!fBackendContext) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Context not associated with connection";
+               signingResponse->set_result(-EINVAL);
+               reply(msg);
+               return;
+       }
+
+       if(message.data_to_sign().size() == 0) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Data to sign is empty and hash type is NONE";
+               signingResponse->set_result(-EINVAL);
+               return;
+       }
+
+       int error = 0;
+       bool loaded = fSoResolver->ensure_loaded();
+       if (loaded) {
+               error = fSoResolver->invoke<int, dcm_backend_context&, MessageDigestType, const std::string&, std::string&>(
+                       "dcm_backend_sign_crypto_data",
+                       *fBackendContext,
+                       message.digest_type(),
+                       message.data_to_sign(),
+                       *signingResponse->mutable_signature()
+               );
+       }
+       signingResponse->set_result(error);
+
+       reply(msg);
+}
diff --git a/src/dcm-daemon/dcmsession.h b/src/dcm-daemon/dcmsession.h
new file mode 100644 (file)
index 0000000..abddb29
--- /dev/null
@@ -0,0 +1,75 @@
+/******************************************************************
+ *
+ * Copyright 2017 - 2019 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_DCMSESSION_H_
+#define DCM_DAEMON_DCMSESSION_H_
+
+#include <memory>
+#include <boost/asio.hpp>
+#include <boost/noncopyable.hpp>
+#include "dcm_support.pb.h"
+#include "protobuf_asio.h"
+#include "dcm-backend-api.h"
+#include "soresolver.h"
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+class dcm_server;
+
+class dcm_session final : public std::enable_shared_from_this<dcm_session>,
+       public boost::noncopyable
+{
+public:
+       dcm_session(boost::asio::io_service& io_service, boost::asio::deadline_timer& timer, const std::shared_ptr<dcm_server>& server, std::shared_ptr<so_resolver> soResolver);
+       ~dcm_session();
+
+       void start();
+       void start_timer();
+       void stop_timer();
+
+       inline boost::asio::local::stream_protocol::socket& socket() {
+               return fSocket;
+       }
+
+private:
+       void do_receive() noexcept;
+       void decode_message() noexcept;
+       void reply(const ResponseMessage& resp) noexcept;
+
+       bool verify_privileges(int handle);
+
+       void handle_context_association(const AssociateKeyContext& message);
+       void handle_cert_chain(const RequestCertificateChain& message);
+       void handle_sign_request(const SignRequest& message);
+
+private:
+       boost::asio::io_service&                                                fService;
+       boost::asio::deadline_timer&                                    fTimer;
+       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;
+       uint64_t                                                                                fCookie = 0;
+};
+
+#endif /* DCM_DAEMON_DCMSESSION_H_ */
diff --git a/src/dcm-daemon/exception_translator.h b/src/dcm-daemon/exception_translator.h
new file mode 100644 (file)
index 0000000..1395888
--- /dev/null
@@ -0,0 +1,59 @@
+/******************************************************************
+ *
+ * Copyright 2017 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_EXCEPTION_TRANSLATOR_H_
+#define DCM_DAEMON_EXCEPTION_TRANSLATOR_H_
+
+#include <memory>
+#include <stdexcept>
+#include <cerrno>
+#include <boost/system/system_error.hpp>
+
+template<typename T> inline int run_with_exception_handler(T t) {
+       try {
+               t();
+       } catch(boost::system::system_error& ex) {
+               return -ex.code().value();
+       } catch(std::bad_alloc&) {
+               return -ENOMEM;
+       } catch(std::domain_error&) {
+               return -EDOM;
+       } catch(std::invalid_argument&) {
+               return -EINVAL;
+       } catch(std::length_error&) {
+               return -EINVAL;
+       } catch(std::out_of_range&) {
+               return -EINVAL;
+       } catch(std::range_error&) {
+               return -ERANGE;
+       } catch(std::overflow_error&) {
+               return -EOVERFLOW;
+       } catch(std::underflow_error&) {
+               return -EOVERFLOW;
+       } catch(std::exception&) {
+               return -EINVAL;
+       } catch(...) {
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
+#endif /* DCM_DAEMON_EXCEPTION_TRANSLATOR_H_ */
diff --git a/src/dcm-daemon/logging.h b/src/dcm-daemon/logging.h
new file mode 100644 (file)
index 0000000..bae7977
--- /dev/null
@@ -0,0 +1,53 @@
+/******************************************************************
+ *
+ * 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_LOGGING_H_
+#define DCM_DAEMON_LOGGING_H_
+
+#include <boost/log/common.hpp>
+#include <boost/log/expressions.hpp>
+#include <boost/log/attributes.hpp>
+#include <boost/log/sinks/sync_frontend.hpp>
+#include <boost/log/sinks/syslog_backend.hpp>
+#include <boost/log/sources/logger.hpp>
+#include <boost/log/utility/setup/console.hpp>
+#include <boost/log/utility/setup/common_attributes.hpp>
+#include <boost/log/attributes/timer.hpp>
+#include <boost/log/attributes/named_scope.hpp>
+
+#define LOG_TAG                "DCM_SERVER"
+#include <dlog.h>
+
+enum class log_severity {
+       debug,
+       normal,
+       warning,
+       error
+};
+
+// Global logger declaration
+BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(dcm_logger, boost::log::sources::severity_logger_mt<log_severity>)
+
+#if defined(NDEBUG) && !defined(DEBUG)
+#else
+#define ENABLE_DEBUG_LOGGING           1
+#endif
+
+#endif /* DCM_DAEMON_LOGGING_H_ */
diff --git a/src/dcm-daemon/main.cpp b/src/dcm-daemon/main.cpp
new file mode 100644 (file)
index 0000000..09183e8
--- /dev/null
@@ -0,0 +1,185 @@
+/******************************************************************
+ *
+ * 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 <boost/asio.hpp>
+
+#include <iostream>
+#include <unistd.h>
+#include <cstdlib>
+#include <sys/stat.h>
+#include <sys/signal.h>
+
+#include "dcmserver.h"
+#include "logging.h"
+#include "serviceadapter.h"
+
+#include <boost/log/sinks.hpp>
+#include <boost/log/support/date_time.hpp>
+
+#include "boost_log_dlog_sink.h"
+
+#include <cynara-client.h>
+
+BOOST_LOG_ATTRIBUTE_KEYWORD(_scope, "Scope", boost::log::attributes::named_scope::value_type)
+BOOST_LOG_ATTRIBUTE_KEYWORD(_timestamp, "TimeStamp", boost::posix_time::ptime)
+BOOST_LOG_ATTRIBUTE_KEYWORD(_severity, "Severity", log_severity)
+
+void init_logging()
+{
+       auto sink = boost::make_shared<boost::log::sinks::synchronous_sink<dlog_output_backend>>();
+
+       dlog_custom_severity_mapping<log_severity> mapping("Severity");
+
+       mapping[log_severity::debug] = DLOG_DEBUG;
+       mapping[log_severity::error] = DLOG_ERROR;
+       mapping[log_severity::normal] = DLOG_INFO;
+       mapping[log_severity::warning] = DLOG_WARN;
+
+       sink->locked_backend()->set_severity_mapper(mapping);
+       sink->locked_backend()->set_log_domain(LOG_TAG);
+
+#ifndef ENABLE_DEBUG_LOGGING
+       sink->set_filter(_severity >= log_severity::normal);
+#endif
+
+       sink->set_formatter(boost::log::expressions::stream
+        << boost::log::expressions::attr< unsigned int >("RecordID") // First an attribute "RecordID" is written to the log
+        << " [" // then this delimiter separates it from the rest of the line
+        << boost::log::expressions::if_(boost::log::expressions::has_attr("Tag"))
+           [
+               boost::log::expressions::stream << boost::log::expressions::attr< std::string >("Tag") // then goes another attribute named "Tag"
+                                               // Note here we explicitly stated that its type
+                                               // should be std::string. We could omit it just
+                                               // like we did it with the "RecordID", but in this case
+                                               // library would have to detect the actual attribute value
+                                               // type in run time which has the following consequences:
+                                               // - On the one hand, the attribute would have been output
+                                               //   even if it has another type (not std::string).
+                                               // - On the other, this detection does not come for free
+                                               //   and will result in performance decrease.
+                                               //
+                                               // In general it's better you to specify explicitly which
+                                               // type should an attribute have wherever it is possible.
+                                               // You may specify an MPL sequence of types if the attribute
+                                               // may have more than one type. And you will have to specify
+                                               // it anyway if the library is not familiar with it (see
+                                               // boost/log/utility/type_dispatch/standard_types.hpp for the list
+                                               // of the supported out-of-the-box types).
+                << "] [" // yet another delimiter
+           ]
+        << boost::log::expressions::format_named_scope("Scope", boost::log::keywords::format = "%n", boost::log::keywords::iteration = boost::log::expressions::reverse) << "] "
+        << boost::log::expressions::smessage); // here goes the log record text
+       boost::log::core::get()->add_sink(sink);
+
+       boost::log::add_common_attributes();
+       boost::log::core::get()->add_thread_attribute("Scope", boost::log::attributes::named_scope());
+}
+
+cynara * gGlobalCynaraInstance;
+
+int main()
+{
+       int error = 0;
+
+       try {
+               init_logging();
+       } catch(...) {
+               std::cerr << "init_logging() failed" << std::endl;
+               return EXIT_FAILURE;
+       }
+
+       BOOST_LOG_FUNCTION();
+
+       service_adapter serviceAdapter;
+
+       cynara_configuration * cynara_conf = nullptr;
+       error = cynara_configuration_create(&cynara_conf);
+       if(error != CYNARA_API_SUCCESS) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't initialize Cynara configuration: " << error;
+               serviceAdapter.notify_start_failure(error);
+               return EXIT_FAILURE;
+       }
+
+       error = cynara_initialize(&gGlobalCynaraInstance, cynara_conf);
+
+       cynara_configuration_destroy(cynara_conf);
+
+       if(error != CYNARA_API_SUCCESS) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't initialize Cynara instance: " << error;
+               serviceAdapter.notify_start_failure(error);
+               return EXIT_FAILURE;
+       }
+
+       try {
+               boost::asio::io_service io_service;
+
+               /* Catch signals */
+               boost::asio::signal_set stop_signals(io_service, SIGINT, SIGTERM);
+
+               stop_signals.async_wait([&io_service](const boost::system::error_code&, int sig) {
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "Stopped by signal " << sig;
+                       io_service.stop();
+               });
+
+               /* Change the file mode mask */
+               (void)umask(0);
+
+               /* Use root directory as working directory */
+               error = chdir("/");
+               (void)error; // Don't care
+
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Create platform socket";
+
+               std::string lib_backend = "libdcm-backend-api.so.1.0";
+               auto server(std::make_shared<dcm_server>(io_service, serviceAdapter.create_platform_socket_acceptor(io_service), lib_backend));
+
+               boost::asio::signal_set hup_signals(io_service, SIGHUP);
+
+               hup_signals.async_wait([](const boost::system::error_code&, int) {
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "Received HUP signal";
+               });
+
+               serviceAdapter.notify_start_complete();
+
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Start server";
+
+               server->start();
+               io_service.run();
+       } catch(std::bad_alloc& e) {
+               serviceAdapter.notify_start_failure(ENOMEM);
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Server failed with OOM exception: " << e.what();
+               return EXIT_FAILURE;
+       } catch(std::exception& e) {
+               serviceAdapter.notify_start_failure(EFAULT);
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Server failed with exception: " << e.what();
+               return EXIT_FAILURE;
+       } catch(...) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Server failed with unknown exception";
+               serviceAdapter.notify_start_failure(EFAULT);
+               return EXIT_FAILURE;
+       }
+
+       cynara_finish(gGlobalCynaraInstance);
+       gGlobalCynaraInstance = nullptr;
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "Server terminated";
+
+       return 0;
+}
diff --git a/src/dcm-daemon/serviceadapter.cpp b/src/dcm-daemon/serviceadapter.cpp
new file mode 100644 (file)
index 0000000..6ea5804
--- /dev/null
@@ -0,0 +1,87 @@
+/******************************************************************
+ *
+ * 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 "serviceadapter.h"
+#include "logging.h"
+
+#include <cstring>
+
+#include <systemd/sd-daemon.h>
+
+service_adapter::service_adapter()
+{
+}
+
+service_adapter::~service_adapter()
+{
+}
+
+boost::asio::local::stream_protocol::acceptor service_adapter::create_platform_socket_acceptor(boost::asio::io_service& io_service)
+{
+       BOOST_LOG_FUNCTION();
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Try to get socket from systemd";
+
+       int n = sd_listen_fds(0);
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << n << " sockets provided by systemd";
+
+       if( n > 0 ) {
+               for(int fd = SD_LISTEN_FDS_START ; fd < SD_LISTEN_FDS_START + n ; ++fd) {
+                       if(sd_is_socket_unix(fd, SOCK_STREAM, 1, fDefaultSocketPath.c_str(), 0)) {
+                               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) <<  "Got UNIX domain socket with fd " << fd;
+
+                               return boost::asio::local::stream_protocol::acceptor(
+                                       io_service,
+                                       boost::asio::local::stream_protocol(),
+                                       fd);
+                       }
+               }
+       }
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "No systemd sockets found";
+
+       throw std::runtime_error("No socket created by systemd");
+}
+
+void service_adapter::notify_start_complete()
+{
+       BOOST_LOG_FUNCTION();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "Notify start completed to systemd";
+
+       sd_listen_fds(1);
+       sd_notify(0, "READY=1");
+       fStartCompleteNotified = true;
+}
+
+void service_adapter::notify_start_failure(int error)
+{
+       BOOST_LOG_FUNCTION();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Notify start failure";
+
+       if(!fStartCompleteNotified) {
+               char buffer[512];
+               buffer[0] = '\0';
+               if(!strerror_r(error, buffer, sizeof(buffer)))
+                       sd_notifyf(0, "STATUS=Failed to start up: %s\nERRNO=%d", buffer, error);
+               else
+                       sd_notifyf(0, "STATUS=Failed to start up: (no message)\nERRNO=%d", error);
+       }
+}
diff --git a/src/dcm-daemon/serviceadapter.h b/src/dcm-daemon/serviceadapter.h
new file mode 100644 (file)
index 0000000..e19e1ab
--- /dev/null
@@ -0,0 +1,42 @@
+/******************************************************************
+ *
+ * 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_SERVICEADAPTER_H_
+#define DCM_DAEMON_SERVICEADAPTER_H_
+
+#include <boost/noncopyable.hpp>
+#include <boost/asio.hpp>
+
+class service_adapter final : public boost::noncopyable {
+public:
+       service_adapter();
+       ~service_adapter();
+
+       boost::asio::local::stream_protocol::acceptor create_platform_socket_acceptor(boost::asio::io_service& io_service);
+
+       void notify_start_complete();
+       void notify_start_failure(int error);
+
+private:
+       std::string                     fDefaultSocketPath = DCM_UNIX_SOCKET_PATH;
+       bool                            fStartCompleteNotified = false;
+};
+
+#endif /* DCM_DAEMON_SERVICEADAPTER_H_ */
diff --git a/src/dcm-daemon/soresolver.cpp b/src/dcm-daemon/soresolver.cpp
new file mode 100644 (file)
index 0000000..30e0b62
--- /dev/null
@@ -0,0 +1,102 @@
+/******************************************************************
+ *
+ * Copyright 2017 - 2019 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 "soresolver.h"
+#include "logging.h"
+#include <dlfcn.h>
+
+so_resolver::so_resolver(const std::string& libraryName) :
+       fLibraryName(libraryName),
+       fLibraryHandle(nullptr)
+{
+}
+
+so_resolver::~so_resolver()
+{
+       if(fLibraryHandle.load(std::memory_order_relaxed)) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Unloading library " << fLibraryName;
+               dlclose(fLibraryHandle.exchange(nullptr, std::memory_order_relaxed));
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Unloaded library " << fLibraryName;
+       }
+}
+
+void * so_resolver::resolve_function(const std::string& name) noexcept
+{
+       BOOST_LOG_FUNCTION();
+
+       std::unique_lock<std::mutex> locker(fCacheLock);
+       auto it = fCache.find(name);
+
+       if(it != fCache.end())
+               return it->second;
+
+       void * handle = fLibraryHandle.load(std::memory_order_relaxed);
+
+       if(handle) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Resolving symbol " << name << " from " << fLibraryName;
+               void * sym = dlsym(handle, name.c_str());
+               if(!sym) {
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) <<  "Unable to resolve symbol " << name << " from " <<
+                                       fLibraryName << ": Error is " << dlerror();
+               } else {
+                       try {
+                               fCache.emplace(name, sym);
+                       } catch(...) {
+                       }
+               }
+               return sym;
+       }
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Trying to resolve symbol " << name << " from not loaded library " << fLibraryName;
+
+       return nullptr;
+}
+
+bool so_resolver::ensure_loaded() noexcept
+{
+       BOOST_LOG_FUNCTION();
+
+       std::unique_lock<std::mutex> locker(fCacheLock);
+
+       void * handle = fLibraryHandle.load(std::memory_order_acquire);
+
+       if(handle)
+               return true;
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Loading library " << fLibraryName;
+
+       handle = dlopen(fLibraryName.c_str(), RTLD_LAZY | RTLD_LOCAL);
+
+       if(!handle) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Unable to load library " << fLibraryName << ": " << dlerror();
+               return false;
+       }
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Library loaded " << fLibraryName;
+
+       void * expectedValue = nullptr;
+
+       if(!fLibraryHandle.compare_exchange_strong(expectedValue, handle, std::memory_order_release)) {
+               // Someone else have opened the library
+               dlclose(handle);
+       }
+
+       return true;
+}
diff --git a/src/dcm-daemon/soresolver.h b/src/dcm-daemon/soresolver.h
new file mode 100644 (file)
index 0000000..800e624
--- /dev/null
@@ -0,0 +1,56 @@
+/******************************************************************
+ *
+ * Copyright 2017 - 2019 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 <boost/noncopyable.hpp>
+#include <string>
+#include <atomic>
+#include <stdexcept>
+#include <map>
+#include <mutex>
+#include <string>
+
+class so_resolver : public boost::noncopyable {
+public:
+       so_resolver(const std::string& libraryName);
+       ~so_resolver();
+
+       bool ensure_loaded() noexcept;
+       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;
+       std::atomic<void *>                     fLibraryHandle;
+       std::mutex                                              fCacheLock;
+       std::map<std::string, void *>   fCache;
+};
+
+#endif /* DCM_DAEMON_SORESOLVER_H_ */
diff --git a/src/shared/protobuf_asio.cpp b/src/shared/protobuf_asio.cpp
new file mode 100644 (file)
index 0000000..fd8a9fd
--- /dev/null
@@ -0,0 +1,99 @@
+/******************************************************************
+ *
+ * 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 <stdexcept>
+
+#include <google/protobuf/io/coded_stream.h>
+
+#include "protobuf_asio.h"
+
+protobuf_sync_message_serialization::protobuf_sync_message_serialization(
+       boost::asio::local::stream_protocol::socket& socket) :
+       fSocket(socket)
+{
+}
+
+void protobuf_sync_message_serialization::encodeMessage(const google::protobuf::MessageLite& message)
+{
+       google::protobuf::io::CopyingOutputStreamAdaptor os(this);
+       google::protobuf::io::CodedOutputStream coded_os(&os);
+
+       coded_os.WriteLittleEndian32(message.ByteSizeLong());
+       if(!message.SerializeToCodedStream(&coded_os)) {
+               throw std::invalid_argument("Message serialization error");
+       }
+}
+
+bool protobuf_sync_message_serialization::Write(const void* buffer, int size)
+{
+       try {
+               boost::asio::write(fSocket, boost::asio::buffer(buffer, size));
+       } catch(...) {
+               return false;
+       }
+       return true;
+}
+
+protobuf_sync_message_deserialization::protobuf_sync_message_deserialization(
+               boost::asio::local::stream_protocol::socket& socket) :
+               fSocket(socket)
+{
+}
+
+void protobuf_sync_message_deserialization::decodeMessage(google::protobuf::MessageLite& message)
+{
+       google::protobuf::uint8 header[4];
+       google::protobuf::uint32 length;
+       boost::asio::read(fSocket, boost::asio::buffer(header));
+       google::protobuf::io::CodedInputStream::ReadLittleEndian32FromArray(header, &length);
+
+       if(length < 1 || length > MESSAGE_LENGHT_MAX) {
+               throw std::length_error("Invalid message length");
+       }
+
+       std::unique_ptr<char[]> local_array(new char[length]);
+
+       boost::asio::read(fSocket, boost::asio::buffer(local_array.get(), length));
+
+       if(!message.ParseFromArray(local_array.get(), length)) {
+               throw std::invalid_argument("Invalid message format");
+       }
+}
+
+void protobuf_async_message_serialization::encodeMessage(const google::protobuf::MessageLite& message)
+{
+       int bufferSize = message.ByteSizeLong();
+       fBuffer.resize(bufferSize + sizeof(uint32_t));
+       google::protobuf::io::CodedOutputStream::WriteLittleEndian32ToArray(bufferSize,
+                       reinterpret_cast<google::protobuf::uint8 *>(&fBuffer[0]));
+       if(!message.SerializeToArray(&fBuffer[sizeof(uint32_t)], bufferSize)) {
+               throw std::invalid_argument("Message serialization error");
+       }
+}
+
+protobuf_async_message_deserialization::protobuf_async_message_deserialization()
+{
+       fBuffer.reserve(128);
+}
+
+bool protobuf_async_message_deserialization::decode_received_message(google::protobuf::MessageLite& message)
+{
+       return message.ParseFromArray(&fBuffer[0], fBuffer.size());
+}
diff --git a/src/shared/protobuf_asio.h b/src/shared/protobuf_asio.h
new file mode 100644 (file)
index 0000000..a040352
--- /dev/null
@@ -0,0 +1,108 @@
+/******************************************************************
+ *
+ * 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 SHARED_PROTOBUF_ASIO_H_
+#define SHARED_PROTOBUF_ASIO_H_
+
+#include <vector>
+
+#include <boost/asio.hpp>
+#include <boost/noncopyable.hpp>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/io/coded_stream.h>
+
+static const size_t MESSAGE_LENGHT_MAX = 65536;
+
+class protobuf_sync_message_serialization final :
+       boost::noncopyable,
+       google::protobuf::io::CopyingOutputStream
+{
+       boost::asio::local::stream_protocol::socket& fSocket;
+public:
+       protobuf_sync_message_serialization(boost::asio::local::stream_protocol::socket& socket);
+       void encodeMessage(const google::protobuf::MessageLite& message);
+
+private:
+       virtual bool Write(const void* buffer, int size) override;
+};
+
+class protobuf_sync_message_deserialization final : boost::noncopyable
+{
+       boost::asio::local::stream_protocol::socket& fSocket;
+public:
+       protobuf_sync_message_deserialization(boost::asio::local::stream_protocol::socket& socket);
+       void decodeMessage(google::protobuf::MessageLite& message);
+};
+
+class protobuf_async_message_serialization final : boost::noncopyable
+{
+       std::vector<char> fBuffer;
+public:
+       void encodeMessage(const google::protobuf::MessageLite& message);
+
+       template<typename WriteStream, typename WriteHandler> void async_write(WriteStream& stream, WriteHandler&& handler) {
+               boost::asio::async_write(stream, boost::asio::buffer(fBuffer), handler);
+       }
+};
+
+class protobuf_async_message_deserialization final : public boost::noncopyable
+{
+       std::vector<char> fBuffer;
+       google::protobuf::uint32 fMessageLength = 0;
+public:
+       protobuf_async_message_deserialization();
+
+       template<typename ReadSocket, typename ReadHandler> void read_message(ReadSocket& socket, ReadHandler&& handler) {
+               fBuffer.resize(4);
+               fMessageLength = 0;
+
+               boost::asio::async_read(socket, boost::asio::buffer(fBuffer),
+                       [this, handler, &socket](const boost::system::error_code& error, std::size_t bytes_read) {
+                               if(!error) {
+                                       assert(bytes_read == fBuffer.size());
+                                       (void)bytes_read;
+                                       assert(fMessageLength == 0);
+
+                                       google::protobuf::io::CodedInputStream::ReadLittleEndian32FromArray(
+                                               (const google::protobuf::uint8 *)&fBuffer[0], &fMessageLength);
+
+                                       if(fMessageLength >= 1 && fMessageLength < MESSAGE_LENGHT_MAX) {
+                                               try {
+                                                       fBuffer.resize(fMessageLength);
+                                               } catch(...) {
+                                                       handler(boost::system::errc::make_error_code(boost::system::errc::not_enough_memory), 0);
+                                                       return;
+                                               }
+
+                                               boost::asio::async_read(socket, boost::asio::buffer(fBuffer), handler);
+                                       } else {
+                                               handler(boost::system::errc::make_error_code(boost::system::errc::message_size), 0);
+                                       }
+                               } else {
+                                       handler(error, 0);
+                               }
+               });
+       }
+
+       bool decode_received_message(google::protobuf::MessageLite& message);
+};
+
+#endif /* SHARED_PROTOBUF_ASIO_H_ */
index b0425f5ce72dfc0a1f5d8bfc861967958f558c22..52995a225fa09f7a9988932f6c55130d3c90263e 100644 (file)
@@ -22,7 +22,7 @@ FIND_PACKAGE(Boost REQUIRED
 
 INCLUDE_DIRECTORIES(SYSTEM ${Boost_INCLUDE_DIRS})
 LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
-INCLUDE_DIRECTORIES(../dcm-client)
+INCLUDE_DIRECTORIES(../src/dcm-client)
 
 ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)
 ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK)