Support KONAI SE drafts/for/tizen
authorDongsun Lee <ds73.lee@samsung.com>
Fri, 12 Apr 2019 07:05:15 +0000 (16:05 +0900)
committerDongsun Lee <ds73.lee@samsung.com>
Fri, 12 Apr 2019 07:05:15 +0000 (16:05 +0900)
Change-Id: I5bed9b60c617b6c828c3f8d4edb0a04e45c75b1a
Signed-off-by: Dongsun Lee <ds73.lee@samsung.com>
dcm-client/dcmclient.cpp
dcm-daemon/CMakeLists.txt
dcm-daemon/konaise-backend/CMakeLists.txt [new file with mode: 0644]
dcm-daemon/konaise-backend/konaise.h [new file with mode: 0644]
dcm-daemon/konaise-backend/ksebackend.cpp [new file with mode: 0644]
dcm-daemon/konaise-backend/ksebackend.h [new file with mode: 0644]
dcm-daemon/konaise-backend/ksebackendcontext.cpp [new file with mode: 0644]
dcm-daemon/konaise-backend/ksebackendcontext.h [new file with mode: 0644]
packaging/device-certificate-manager.spec
tools/CMakeLists.txt
tools/konaise_tool.cpp [new file with mode: 0644]

index c8de053c708549d90e326624efe2de5301b58944..1bed22a1d953619cdcbfed7e6d6c456d3083261d 100644 (file)
@@ -253,7 +253,7 @@ int dcm_client_connection_impl::sign_data(mbedtls_md_type_t digestType, const vo
 
        if(!fCookie) {
 #ifdef USE_DLOG_LOGGING
-               LOGE("%s: Trying to request data signing in object %p but there is no connection", __FUNCTION__);
+               LOGE("%s: Trying to request data signing in object %p but there is no connection", __FUNCTION__, this);
 #endif
                return DCM_ERROR_SOCKET;
        }
index 2d8a157c48a33adfd7f470ab09fd3e15948a4461..d3cc61fa99525746f8a91ead153e7f08c7fbd490 100644 (file)
@@ -49,14 +49,16 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
 ###### Crypto Backends #######
 
 add_subdirectory(dummy-backend)
-add_subdirectory(see-backend)
+#add_subdirectory(see-backend)
+add_subdirectory(konaise-backend)
 
 IF(ENABLE_DUMMY_BACKEND)
        SET(DUMMY_BACKEND_OBJECTS $<TARGET_OBJECTS:dummy_backend_objects>)
        add_definitions(-DENABLE_DUMMY_BACKEND=1)
 ENDIF(ENABLE_DUMMY_BACKEND)
 
-SET(SEE_BACKEND_OBJECTS $<TARGET_OBJECTS:see-backend>)
+#SET(SEE_BACKEND_OBJECTS $<TARGET_OBJECTS:see-backend>)
+SET(SEE_BACKEND_OBJECTS $<TARGET_OBJECTS:kse-backend>)
 
 ###### Main executable #######
 
diff --git a/dcm-daemon/konaise-backend/CMakeLists.txt b/dcm-daemon/konaise-backend/CMakeLists.txt
new file mode 100644 (file)
index 0000000..59760c5
--- /dev/null
@@ -0,0 +1,6 @@
+add_library(kse-backend
+       OBJECT
+       ksebackend.cpp
+       ksebackendcontext.cpp)
+       
+add_dependencies(kse-backend protobuf_generated)               
diff --git a/dcm-daemon/konaise-backend/konaise.h b/dcm-daemon/konaise-backend/konaise.h
new file mode 100644 (file)
index 0000000..990a226
--- /dev/null
@@ -0,0 +1,65 @@
+/******************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#ifdef USE_KONAISE_HEADERS
+#include <konaise.h>
+#else
+
+#ifndef _KONAISE_SECURITY_H_
+#define _KONAISE_SECURITY_H_
+
+typedef struct _hal_init_param {
+       uint32_t i2c_port;
+       uint32_t gpio;
+} hal_init_param;
+
+
+typedef struct _hal_data {
+       void *data;
+       uint32_t data_len;
+       void *priv;
+} hal_data;
+
+typedef enum {
+       HAL_HASH_MD5,
+       HAL_HASH_SHA1,
+       HAL_HASH_SHA224,
+       HAL_HASH_SHA256,
+       HAL_HASH_SHA384,
+       HAL_HASH_SHA512,
+       HAL_HASH_UNKNOWN,
+} hal_hash_type;
+
+typedef enum {
+       HAL_ECDSA_BRAINPOOL_P256R1,
+       HAL_ECDSA_BRAINPOOL_P384R1,
+       HAL_ECDSA_BRAINPOOL_P512R1,
+       HAL_ECDSA_SEC_P256R1,
+       HAL_ECDSA_SEC_P384R1,
+       HAL_ECDSA_SEC_P512R1,
+} hal_ecdsa_curve;
+
+typedef struct _hal_ecdsa_mode {
+       hal_ecdsa_curve curve;
+       hal_hash_type hash_t;
+} hal_ecdsa_mode;
+
+
+#endif
+
+#endif
diff --git a/dcm-daemon/konaise-backend/ksebackend.cpp b/dcm-daemon/konaise-backend/ksebackend.cpp
new file mode 100644 (file)
index 0000000..748aac8
--- /dev/null
@@ -0,0 +1,106 @@
+/******************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#include "ksebackend.h"
+#include "ksebackendcontext.h"
+#include "logging.h"
+#include <mutex>
+
+#include "konaise.h"
+
+#define KSE_LIB_NAME "libkonaise.so"
+
+crypto_backend_registration<kse_backend> kse_backend::kse_crypto_backend_registration;
+
+kse_backend::kse_backend() :
+       fKseInitOK(false),
+       fDllResolver(std::string(KSE_LIB_NAME))
+{
+       BOOST_LOG_FUNCTION();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Constructed KSE backend";
+}
+
+kse_backend::~kse_backend() {
+       BOOST_LOG_FUNCTION();
+       if(fKseInitOK) {
+               try {
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Deinitializing KSE backend";
+                       fDllResolver.invoke<void>(nullptr, "hal_deinit");
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Deinitialized KSE backend";
+               } catch(...) {
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Exception caught when deinitializing KSE backend";
+               }
+       }
+}
+
+void kse_backend::initialize_kse() {
+       if(fKseInitOK)
+               return;
+
+       BOOST_LOG_FUNCTION();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Initializing KSE backend";
+
+       std::unique_lock<std::mutex> locker(fKSEMutex);
+
+       try {
+               hal_init_param init_parm = {};
+               int error = fDllResolver.invoke<int>(nullptr, "hal_init", &init_parm);
+
+               if(error != 0) {
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "KSE framework init failure: " << error;
+                       fKseInitOK = false;
+               } else {
+                       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "KSE framework initialized";
+                       fKseInitOK = true;
+               }
+       } catch(...) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception when initializing KSE backend";
+               fKseInitOK = false;
+       }
+}
+
+std::shared_ptr<abstract_crypto_backend_context> kse_backend::create_client_context(
+               const std::string& serviceName,
+               const std::string& usage,
+               const std::string& key_type)
+{
+       BOOST_LOG_FUNCTION();
+       initialize_kse();
+
+       if(!fKseInitOK)
+               throw std::runtime_error("KSE not initialized");
+
+       return std::make_shared<kse_backend_context>(std::static_pointer_cast<kse_backend>(shared_from_this()), key_type);
+}
+
+float kse_backend::will_handle_service(const std::string&,
+                       const std::string&)
+{
+       BOOST_LOG_FUNCTION();
+       if(!fDllResolver.ensure_loaded())
+               return -1.0f;
+
+       initialize_kse();
+
+       if(!fKseInitOK)
+               return -1.0f;
+
+       return 1.0f;
+}
diff --git a/dcm-daemon/konaise-backend/ksebackend.h b/dcm-daemon/konaise-backend/ksebackend.h
new file mode 100644 (file)
index 0000000..e23da83
--- /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_KSE_BACKEND_KSEBACKEND_H_
+#define DCM_DAEMON_KSE_BACKEND_KSEBACKEND_H_
+
+#include "abstractcryptobackend.h"
+#include "cryptobackendroster.h"
+#include <dllresolver.h>
+#include <mutex>
+
+class kse_backend: public asbtract_crypto_backend
+{
+public:
+       kse_backend();
+       virtual ~kse_backend();
+
+       virtual std::shared_ptr<abstract_crypto_backend_context> create_client_context(
+                       const std::string& serviceName,
+                       const std::string& usage,
+                       const std::string& key_type) override;
+
+       virtual float will_handle_service(const std::string& serviceName,
+                               const std::string& usage);
+
+       inline dll_resolver& get_dll_resolver() {
+               return fDllResolver;
+       }
+
+       static crypto_backend_registration<kse_backend> kse_crypto_backend_registration;
+
+private:
+       void initialize_kse();
+
+private:
+       bool                            fKseInitOK = false;
+       std::mutex                      fKSEMutex;
+       dll_resolver            fDllResolver;
+};
+
+#endif /* DCM_DAEMON_KSE_BACKEND_KSEBACKEND_H_ */
diff --git a/dcm-daemon/konaise-backend/ksebackendcontext.cpp b/dcm-daemon/konaise-backend/ksebackendcontext.cpp
new file mode 100644 (file)
index 0000000..ff6ece9
--- /dev/null
@@ -0,0 +1,250 @@
+/******************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#include "ksebackendcontext.h"
+#include "logging.h"
+#include "konaise.h"
+#include "mbedtls_wrapper.h"
+#include "cert_utils.h"
+
+#include <mbedtls/pk.h>
+
+#include <mbedtls/asn1write.h>
+#include <boost/algorithm/hex.hpp>
+
+static int kse_get_certificate_key = 0;
+static int kse_get_ecdsa_signature_key = 1;
+
+kse_backend_context::kse_backend_context(std::shared_ptr<kse_backend> backend, const std::string& keyType) :
+       fBackendPtr(backend)
+{
+       BOOST_LOG_FUNCTION();
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Created new KSE with key " << keyType;
+
+       if(keyType.empty() || keyType == "ECDSA") {
+               fKeyType = CRYPTO_KEY_TYPE_ECDSA;
+       } else {
+               throw std::invalid_argument("Unsupported key type");
+       }
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Created new KSE context at " << this;
+}
+
+kse_backend_context::~kse_backend_context()
+{
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Deleting KSE context " << this;
+}
+
+int kse_backend_context::request_certificate_chain(std::string& mutable_chain)
+{
+       BOOST_LOG_FUNCTION();
+       hal_data cert;
+
+#ifdef ENABLE_DEBUG_LODDING
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "KSE : Request certificate chain";
+#endif
+
+       auto backend = fBackendPtr.lock();
+
+       if(!backend) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Unable to acquire backend pointer";
+               return -EINVAL;
+       }
+
+       auto& resolver(backend->get_dll_resolver());
+
+       const char *method_name = "hal_get_certificate";
+       const unsigned int cert_idx = 0;
+       int error = resolver.invoke<int, unsigned int, hal_data *>(&kse_get_certificate_key,
+                                                                                                                               method_name, cert_idx, &cert);
+
+       if(error != 0) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Can't invoke get certificate function";
+               return -EINVAL;
+       }
+
+#ifdef ENABLE_DEBUG_LODDING
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "KSE: Got certificate with " << cert.data_len<< " bytes";
+#endif
+
+       try {
+               mutable_chain.assign((const char *)cert.data, cert.data_len);
+       } catch(...) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "KSE: Got exception when assigning data";
+               free(cert.data);
+               throw;
+       }
+
+       free(cert.data);
+
+#ifdef ENABLE_DEBUG_LODDING
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Requested certificate in " << this;
+#endif
+
+       return 0;
+}
+
+static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
+                                    unsigned char *sig, size_t *slen )
+{
+    int ret;
+    unsigned char buf[MBEDTLS_ECDSA_MAX_LEN];
+    unsigned char *p = buf + sizeof( buf );
+    size_t len = 0;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
+                                       MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
+
+    memcpy( sig, p, len );
+    *slen = len;
+
+    return 0;
+}
+
+int kse_backend_context::sign_crypto_data(MessageDigestType digestType, const std::string& dataToSign,
+               std::string& digestResult)
+{
+       BOOST_LOG_FUNCTION();
+       hal_data hashed_data = { };
+       hal_data signed_data = { };
+
+       hashed_data.data = (void *)dataToSign.c_str();
+       hashed_data.data_len = dataToSign.size();
+
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "KSE: Sign " << hashed_data.data_len << " bytes";
+
+       auto backend = fBackendPtr.lock();
+
+       if(!backend) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Unable to acquire backend pointer";
+               return -EINVAL;
+       }
+
+       auto& resolver(backend->get_dll_resolver());
+
+#ifdef ENABLE_DEBUG_LODDING
+       try {
+               std::string hex;
+               boost::algorithm::hex((const unsigned char *)hashed_data.data,
+                               (const unsigned char *)hashed_data.data + hashed_data.data_len,
+                               std::back_inserter(hex));
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Hashed data is " << hex;
+       } catch(...) {
+       }
+#endif
+
+       const char *method_name = "hal_ecdsa_sign_md";
+       unsigned int key_idx = 0;
+       hal_ecdsa_mode mode = {HAL_ECDSA_SEC_P256R1, HAL_HASH_UNKNOWN};
+       int error = resolver.invoke<int, hal_data, int, hal_ecdsa_mode, hal_data *>(
+               &kse_get_ecdsa_signature_key, method_name,
+               hashed_data, key_idx, mode, &signed_data);
+
+       if(error != 0) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) <<
+                               "Unable to generate ECDSA signature in " <<
+                               this <<
+                               " (" << error << ") : " <<
+                               mbedtls_error_to_string(error);
+
+               return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+       }
+
+#ifdef ENABLE_DEBUG_LODDING
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Signature length is " << signed_data.data_len;
+
+       try {
+               std::string hex;
+               boost::algorithm::hex((const unsigned char *)signed_data.data,
+                               (const unsigned char *)signed_data.data + signed_data.data_len,
+                               std::back_inserter(hex));
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Hex signature is " << hex;
+       } catch(...) {
+       }
+#endif
+
+       if(signed_data.data_len != 64) {
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) <<
+                               "Incorrect length of signed data " <<
+                               signed_data.data_len<<
+                               " but should be 64";
+
+               free(signed_data.data);
+               return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+       }
+
+#ifdef ENABLE_DEBUG_LODDING
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "KSE: Generated ECDSA signature";
+#endif
+
+    size_t sig_len = 0;
+    unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
+    mbedtls_mpi_wrapper r, s;
+
+    error = r.read_binary((const unsigned char *)signed_data.data, 32);
+
+    if(error == 0) {
+       error = s.read_binary(((const unsigned char *)signed_data.data) + 32, 32);
+    }
+
+    free(signed_data.data);
+
+    if(error != 0) {
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) <<
+                       "Unable to unserialize binary numbers : " <<
+                               mbedtls_error_to_string(error);
+       return error;
+    }
+
+    error = ecdsa_signature_to_asn1(&r, &s, sig, &sig_len);
+
+    if(error != 0) {
+       BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) <<
+                       "Unable to convert ECDSA signature : " <<
+                               mbedtls_error_to_string(error);
+       return error;
+    }
+
+#ifdef ENABLE_DEBUG_LODDING
+       try {
+               std::string hex;
+               boost::algorithm::hex(sig, sig + sig_len, std::back_inserter(hex));
+               BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Final signature is " << hex;
+       } catch(...) {
+       }
+#endif
+
+       digestResult.assign((const char *)sig, sig_len);
+       return 0;
+}
+
+CryptoKeyType kse_backend_context::key_type()
+{
+       return fKeyType;
+}
+
+unsigned int kse_backend_context::key_length()
+{
+       return 256;
+}
diff --git a/dcm-daemon/konaise-backend/ksebackendcontext.h b/dcm-daemon/konaise-backend/ksebackendcontext.h
new file mode 100644 (file)
index 0000000..6ca39a7
--- /dev/null
@@ -0,0 +1,49 @@
+/******************************************************************
+ *
+ * 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_KSE_BACKEND_KSEBACKENDCONTEXT_H_
+#define DCM_DAEMON_KSE_BACKEND_KSEBACKENDCONTEXT_H_
+
+#include "abstractcryptobackendcontext.h"
+#include "ksebackend.h"
+
+class kse_backend_context final : public abstract_crypto_backend_context {
+public:
+       kse_backend_context(std::shared_ptr<kse_backend> backend, const std::string& keyType);
+       virtual ~kse_backend_context();
+
+       virtual int request_certificate_chain(std::string& mutable_chain) override;
+
+       virtual int sign_crypto_data(MessageDigestType digestType, const std::string& dataToSign,
+                       std::string& digestResult) override;
+
+       virtual CryptoKeyType key_type() override;
+
+       virtual unsigned int key_length() override;
+
+private:
+       void fix_certificate_chain(std::string& cert_chain);
+
+private:
+       CryptoKeyType                                   fKeyType;
+       std::weak_ptr<kse_backend>              fBackendPtr;
+};
+
+#endif /* DCM_DAEMON_KSE_BACKEND_KSEBACKENDCONTEXT_H_ */
index 882d9db3517fb28a302ad4435b3565b91431e29d..6e83239a0b884577a457bf5cff816b853331e839 100644 (file)
@@ -122,3 +122,4 @@ fi
 %{_bindir}/dcm_example_capi
 %{_bindir}/dcm_api_test
 %{_bindir}/dcm_test_cert_rewriter
+%{_bindir}/dcm_konaise_tool
index 064d1a4b74b08daf6e61ba56098d4c6bc9aeb375..a99f57ff5eabf9a7774c0a04f4d16a48238987d7 100644 (file)
@@ -1,3 +1,21 @@
 add_executable(helper_bin2c
        bin2c.c)
-       
\ No newline at end of file
+
+#######################################################################################
+# For SE_KONAI
+ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)
+include_directories(${Boost_INCLUDE_DIRS})
+link_directories(${Boost_LIBRARY_DIRS})
+
+include_directories(../dcm-daemon ../dcm-daemon/konaise-backend)
+
+add_executable(dcm_konaise_tool 
+       ../dcm-daemon/dllresolver.cpp
+       konaise_tool.cpp)
+target_link_libraries(dcm_konaise_tool 
+       ${Boost_LOG_LIBRARY}
+       device-certificate-manager
+       dl)
+install(TARGETS dcm_konaise_tool RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+#######################################################################################
+
diff --git a/tools/konaise_tool.cpp b/tools/konaise_tool.cpp
new file mode 100644 (file)
index 0000000..5a30fe5
--- /dev/null
@@ -0,0 +1,302 @@
+/******************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <dllresolver.h>
+#include "konaise.h"
+
+#define KSE_LIB_NAME "libkonaise.so"
+
+static int kse_cert_get = 0x00;
+static int kse_cert_add = 0x01;
+static int kse_cert_del = 0x02;
+static int kse_key_get  = 0x10;
+static int kse_key_add  = 0x11;
+static int kse_key_del  = 0x12;
+
+
+typedef enum {
+    /*  AES */
+    HAL_KEY_AES_128,// 128 bits aes algorithm
+    HAL_KEY_AES_192, // 192 bits aes algorithm
+    HAL_KEY_AES_256, // 256 bits aes algorithm
+    /*  RSA */
+    HAL_KEY_RSA_1024, // 1024 bits rsa algorithm
+    HAL_KEY_RSA_2048, // 2048 bits rsa algorithm
+    HAL_KEY_RSA_3072, // 3072 bits rsa algorithm
+    HAL_KEY_RSA_4096,
+    /*  ECC: it doesn't support whole algorithm that mbedTLS support. it's have to be added*/
+    HAL_KEY_ECC_BRAINPOOL_P256R1, // ecc brainpool curve for p256r1
+    HAL_KEY_ECC_BRAINPOOL_P384R1, // ecc brainpool curve for p384r1
+    HAL_KEY_ECC_BRAINPOOL_P512R1, // ecc brainpool curve for p512r1
+    HAL_KEY_ECC_SEC_P256R1, // nist curve for p256r1
+    HAL_KEY_ECC_SEC_P384R1, // nist curve for p384r1
+    HAL_KEY_ECC_SEC_P512R1, // nist curve for p512r1
+    /*  Hmac */
+    HAL_KEY_HMAC_MD5, // hmac with md5
+    HAL_KEY_HMAC_SHA1, // hmac with sha1
+    HAL_KEY_HMAC_SHA224, // hmac with sha224
+    HAL_KEY_HMAC_SHA256, // hmac with sha256
+    HAL_KEY_HMAC_SHA384, // hmac with sha384
+    HAL_KEY_HMAC_SHA512, // hmac with sha512
+    /* DH */
+    HAL_KEY_DH_1024,
+    HAL_KEY_DH_2048,
+    HAL_KEY_UNKNOWN,
+} hal_key_type;
+
+
+class SEKonai {
+public:
+       SEKonai(const std::string& libraryName) :
+               fDllResolver(libraryName)
+       {
+               std::cout << "TRYING TO LOAD LIBRARY: " << libraryName<< std::endl;
+               loaded = fDllResolver.ensure_loaded();
+               std::cout << "LOAD LIBRARY: RESULT= " << loaded << std::endl;
+       }
+
+       ~SEKonai(){
+       }
+
+       bool is_loaded() {
+               return loaded;
+       }
+
+       void get_cert(int idx, const std::string& fileName){
+               hal_data data;
+               const char *method_name = "hal_get_certificate";
+               int error = fDllResolver.invoke<int, unsigned int, hal_data *>(&kse_cert_get,
+                                                               method_name, idx, &data);
+               if(error == 0) {
+                       write_file(fileName, data);
+                       std::cout << "SUCCEEDED in " << method_name << "." << std::endl;
+               } else {
+                       std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl;
+               }
+       }
+
+       void get_key(hal_key_type key_type, int idx, const std::string& fileName) {
+               hal_data data;
+               const char *method_name = "hal_get_key";
+               int error = fDllResolver.invoke<int, hal_key_type, unsigned int, hal_data *>(&kse_key_get,
+                                                               method_name, key_type, idx, &data);
+               if(error == 0) {
+                       write_file(fileName, data);
+                       std::cout << "SUCCEEDED in " << method_name << "." << std::endl;
+               } else {
+                       std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl;
+               }
+       }
+
+       void add_cert(const std::string& fileName, int idx) {
+               hal_data *data = read_file(fileName);
+               const char *method_name = "hal_set_certificate";
+               int error = fDllResolver.invoke<int, unsigned int>(&kse_cert_add, method_name, idx);
+               if(error == 0) {
+                       std::cout << "SUCCEEDED in " << method_name << "." << std::endl;
+               } else {
+                       std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl;
+               }
+               free(data);
+       }
+
+       void add_key(const std::string& fileName, hal_key_type key_type, int idx,
+                               const std::string& privFileName) {
+               hal_data *key = read_file(fileName);
+               hal_data *priKey = read_file(privFileName);
+               const char *method_name = "hal_set_key";
+               int error = fDllResolver.invoke<int, hal_key_type, unsigned int, hal_data *, hal_data *>(
+                                               &kse_key_add, method_name, key_type, idx, key, priKey);
+               if(error == 0) {
+                       std::cout << "SUCCEEDED in " << method_name << "." << std::endl;
+               } else {
+                       std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl;
+               }
+               free(key);
+               free(priKey);
+       }
+
+       void del_cert(int idx) {
+               const char *method_name = "hal_remove_certificate";
+               int error = fDllResolver.invoke<int, unsigned int>(&kse_key_del, method_name, idx);
+               if(error == 0) {
+                       std::cout << "SUCCEEDED in " << method_name << "." << std::endl;
+               } else {
+                       std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl;
+               }
+       }
+
+       void del_key(hal_key_type key_type, int idx) {
+               const char *method_name = "hal_remove_key";
+               int error = fDllResolver.invoke<int, hal_key_type, unsigned int>(&kse_key_del, method_name,
+                                                                                                                                                       key_type, idx);
+               if(error == 0) {
+                       std::cout << "SUCCEEDED in " << method_name << "." << std::endl;
+               } else {
+                       std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl;
+               }
+       }
+
+       hal_key_type get_key_type(const std::string& keyType) {
+               if(keyType.compare("HAL_KEY_AES_128") == 0) return HAL_KEY_AES_128;
+               if(keyType.compare("HAL_KEY_AES_192") == 0) return HAL_KEY_AES_192;
+               if(keyType.compare("HAL_KEY_AES_256") == 0) return HAL_KEY_AES_256;
+               if(keyType.compare("HAL_KEY_RSA_1024") == 0) return HAL_KEY_RSA_1024;
+               if(keyType.compare("HAL_KEY_RSA_2048") == 0) return HAL_KEY_RSA_2048;
+               if(keyType.compare("HAL_KEY_RSA_3072") == 0) return HAL_KEY_RSA_3072;
+               if(keyType.compare("HAL_KEY_RSA_4096") == 0) return HAL_KEY_RSA_4096;
+               if(keyType.compare("HAL_KEY_ECC_BRAINPOOL_P256R1") == 0) return HAL_KEY_ECC_BRAINPOOL_P256R1;
+               if(keyType.compare("HAL_KEY_ECC_BRAINPOOL_P384R1") == 0) return HAL_KEY_ECC_BRAINPOOL_P384R1;
+               if(keyType.compare("HAL_KEY_ECC_BRAINPOOL_P512R1") == 0) return HAL_KEY_ECC_BRAINPOOL_P512R1;
+               if(keyType.compare("HAL_KEY_ECC_SEC_P256R1") == 0) return HAL_KEY_ECC_SEC_P256R1;
+               if(keyType.compare("HAL_KEY_ECC_SEC_P384R1") == 0) return HAL_KEY_ECC_SEC_P384R1;
+               if(keyType.compare("HAL_KEY_ECC_SEC_P512R1") == 0) return HAL_KEY_ECC_SEC_P512R1;
+               if(keyType.compare("HAL_KEY_HMAC_MD5") == 0) return HAL_KEY_HMAC_MD5;
+               if(keyType.compare("HAL_KEY_HMAC_SHA1") == 0) return HAL_KEY_HMAC_SHA1;
+               if(keyType.compare("HAL_KEY_HMAC_SHA224") == 0) return HAL_KEY_HMAC_SHA224;
+               if(keyType.compare("HAL_KEY_HMAC_SHA256") == 0) return HAL_KEY_HMAC_SHA256;
+               if(keyType.compare("HAL_KEY_HMAC_SHA384") == 0) return HAL_KEY_HMAC_SHA384;
+               if(keyType.compare("HAL_KEY_HMAC_SHA512") == 0) return HAL_KEY_HMAC_SHA512;
+               if(keyType.compare("HAL_KEY_DH_1024") == 0) return HAL_KEY_DH_1024;
+               if(keyType.compare("HAL_KEY_DH_2048") == 0) return HAL_KEY_DH_2048;
+               return HAL_KEY_UNKNOWN;
+       }
+
+       std::string get_key_type_str(hal_key_type keyType) {
+               switch(keyType) {
+               case HAL_KEY_AES_128: return std::string("HAL_KEY_AES_128");
+               case HAL_KEY_AES_192: return std::string("HAL_KEY_AES_192");
+               case HAL_KEY_AES_256: return std::string("HAL_KEY_AES_256");
+               case HAL_KEY_RSA_1024: return std::string("HAL_KEY_RSA_1024");
+               case HAL_KEY_RSA_2048: return std::string("HAL_KEY_RSA_2048");
+               case HAL_KEY_RSA_3072: return std::string("HAL_KEY_RSA_3072");
+               case HAL_KEY_RSA_4096: return std::string("HAL_KEY_RSA_4096");
+               case HAL_KEY_ECC_BRAINPOOL_P256R1: return std::string("HAL_KEY_ECC_BRAINPOOL_P256R1");
+               case HAL_KEY_ECC_BRAINPOOL_P384R1: return std::string("HAL_KEY_ECC_BRAINPOOL_P384R1");
+               case HAL_KEY_ECC_BRAINPOOL_P512R1: return std::string("HAL_KEY_ECC_BRAINPOOL_P512R1");
+               case HAL_KEY_ECC_SEC_P256R1: return std::string("HAL_KEY_ECC_SEC_P256R1");
+               case HAL_KEY_ECC_SEC_P384R1: return std::string("HAL_KEY_ECC_SEC_P384R1");
+               case HAL_KEY_ECC_SEC_P512R1: return std::string("HAL_KEY_ECC_SEC_P512R1");
+               case HAL_KEY_HMAC_MD5: return std::string("HAL_KEY_HMAC_MD5");
+               case HAL_KEY_HMAC_SHA1: return std::string("HAL_KEY_HMAC_SHA1");
+               case HAL_KEY_HMAC_SHA224: return std::string("HAL_KEY_HMAC_SHA224");
+               case HAL_KEY_HMAC_SHA256: return std::string("HAL_KEY_HMAC_SHA256");
+               case HAL_KEY_HMAC_SHA384: return std::string("HAL_KEY_HMAC_SHA384");
+               case HAL_KEY_HMAC_SHA512: return std::string("HAL_KEY_HMAC_SHA512");
+               case HAL_KEY_DH_1024: return std::string("HAL_KEY_DH_1024");
+               case HAL_KEY_DH_2048: return std::string("HAL_KEY_DH_2048");
+               default: std::string("HAL_KEY_UNKNOWN");
+               }
+       }
+
+private:
+       dll_resolver fDllResolver;
+       bool loaded;
+
+       void free_hal_data(hal_data *data) {
+               if(data == NULL)
+                       return;
+               if(data->data != NULL)
+                       free(data->data);
+               free(data);
+       }
+
+       void write_file(const std::string& fileName, hal_data in) {
+               std::fstream outfile;
+               outfile = std::fstream(fileName, std::ios::out | std::ios::binary);
+               outfile.write((char*)in.data, in.data_len);
+               outfile.close();
+       }
+
+       hal_data* read_file(const std::string& fileName) {
+               if(fileName.size() == 0)
+                       return NULL;
+               std::ifstream input(fileName, std::ios::binary);
+               std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
+               unsigned char* data = (unsigned char*) malloc(buffer.size());
+               for(int i = 0; i < buffer.size(); i++)
+                       data[i] = buffer[i];
+               hal_data *ret = (hal_data *) malloc(sizeof(hal_data));
+               ret->data = data;
+               ret->data_len = buffer.size();
+               ret->priv = NULL;
+               return ret;
+       }
+};
+
+void print_usage(char *prog_name) {
+       std::cout << prog_name << " command  opt1 opt2 . . . " << std::endl;
+       std::cout << "  example: " << prog_name << " get_cert index outfile" << std::endl;
+       std::cout << "  example: " << prog_name << " add_cert infile index" << std::endl;
+       std::cout << "  example: " << prog_name << " del_cert index" << std::endl;
+       std::cout << "  example: " << prog_name << " get_key key_type index outfile" << std::endl;
+       std::cout << "  example: " << prog_name << " add_key infile key_type index in_privfile"<<std::endl;
+       std::cout << "  example: " << prog_name << " del_key key_type index" << std::endl;
+}
+
+int main(int argc, char ** argv)
+{
+       if(argc < 1) {
+               print_usage("Invalid Program Name");
+               return -1;
+       }
+       if(argc < 2) {
+               print_usage(argv[0]);
+               return -1;
+       }
+
+       SEKonai se(KSE_LIB_NAME);
+       if(!se.is_loaded()) {
+               std::cout << "LIBRARY WAS NOT LOADED!!" << std::endl;
+               return -1;
+       }
+       std::string cmd(argv[1]);
+       std::cout << "CMD=" << cmd << ", ARGC=" << argc << std::endl;
+
+       if((cmd.compare("get_cert") == 0) && argc > 3) {
+       std::cout << "CMD=" << "1" << std::endl;
+               se.get_cert(std::stoi(argv[2]), std::string(argv[3]));  
+       }else if((cmd.compare("add_cert") == 0) && argc > 3) {
+       std::cout << "CMD=" << "2" << std::endl;
+               se.add_cert(std::string(argv[2]), std::stoi(argv[3]));  
+       }else if((cmd.compare("del_cert") == 0) && argc > 2) {
+       std::cout << "CMD=" << "3" << std::endl;
+               se.del_cert(std::stoi(argv[2]));        
+       }else if((cmd.compare("get_key") == 0) && argc > 4) {
+       std::cout << "CMD=" << "4" << std::endl;
+               se.get_key(static_cast<hal_key_type>(std::stoi(argv[2])),
+                               std::stoi(argv[3]), std::string(argv[4]));      
+       }else if((cmd.compare("add_key") == 0) && argc > 5) {
+       std::cout << "CMD=" << "5" << std::endl;
+               se.add_key(std::string(argv[2]), static_cast<hal_key_type>(std::stoi(argv[3])),
+                               std::stoi(argv[4]), std::string(argv[5]));      
+       }else if((cmd.compare("del_key") == 0) && argc > 3) {
+       std::cout << "CMD=" << "6" << std::endl;
+               se.del_key(static_cast<hal_key_type>(std::stoi(argv[2])), std::stoi(argv[3]));  
+       }else {
+       std::cout << "CMD=" << "7" << std::endl;
+               print_usage(argv[0]);
+               return -1;
+       }
+       std::cout << "CMD=" << "8" << std::endl;
+
+       return 0;
+}