add_subdirectory(dummy-backend)
add_subdirectory(see-backend)
+add_subdirectory(konaise-backend)
IF(ENABLE_DUMMY_BACKEND)
SET(DUMMY_BACKEND_OBJECTS $<TARGET_OBJECTS:dummy_backend_objects>)
ENDIF(ENABLE_DUMMY_BACKEND)
SET(SEE_BACKEND_OBJECTS $<TARGET_OBJECTS:see-backend>)
+SET(KSE_BACKEND_OBJECTS $<TARGET_OBJECTS:kse-backend>)
###### Main executable #######
${PROTO_HDRS}
${DUMMY_BACKEND_OBJECTS}
${SEE_BACKEND_OBJECTS}
+ ${KSE_BACKEND_OBJECTS}
)
-
+
add_dependencies(device-certificate-managerd protobuf_generated)
ApplyCxx11Standard(device-certificate-managerd)
###### Framework linking #######
-target_link_libraries(device-certificate-managerd
+target_link_libraries(device-certificate-managerd
${Boost_LOG_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
- ${Boost_SYSTEM_LIBRARY}
+ ${Boost_SYSTEM_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
${MBEDTLS_LIB}
${MBEDCRYPTO_LIB}
IF(ENABLE_SYSTEMD_SUPPORT)
target_link_libraries(device-certificate-managerd ${SYSTEMD_LIBRARIES})
-ENDIF(ENABLE_SYSTEMD_SUPPORT)
+ENDIF(ENABLE_SYSTEMD_SUPPORT)
IF(CYNARA_FOUND)
target_link_libraries(device-certificate-managerd ${CYNARA_LIBRARIES})
###### Installation #######
-install(TARGETS device-certificate-managerd
+install(TARGETS device-certificate-managerd
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
--- /dev/null
+add_library(kse-backend
+ OBJECT
+ ksebackend.cpp
+ ksebackendcontext.cpp)
+add_dependencies(kse-backend protobuf_generated)
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2019 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
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2019 Samsung Electronics All Rights Reserved.
+ *
+ * Author: Dongsun Lee <ds73.lee@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;
+}
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2019 Samsung Electronics All Rights Reserved.
+ *
+ * Author: Dongsun Lee <ds73.lee@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_ */
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2019 Samsung Electronics All Rights Reserved.
+ *
+ * Author: Dongsun Lee <ds73.lee@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>
+
+#define PRIVATE_KEY_INDEX 1
+#define SUBCA_CERT_INDEX 2
+#define LEAF_CERT_INDEX 3
+
+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::get_certificate(unsigned int index, std::string& outcert)
+{
+ hal_data cert = {0};
+ const char *method_name = "hal_get_certificate";
+
+ 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());
+ int error = resolver.invoke<int, unsigned int, hal_data *>(&kse_get_certificate_key,
+ method_name, index, &cert);
+ if(error != 0) {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::error)
+ << "Failed to get certificate. error=" << error;
+ return -EINVAL;
+ }
+
+#ifdef ENABLE_DEBUG_LODDING
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug)
+ << "KSE: Got certificate with " << cert.data_len
+ << " bytes and index " << index;
+#endif
+ try {
+ outcert.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);
+
+ return 0;
+}
+
+int kse_backend_context::request_certificate_chain(std::string& mutable_chain)
+{
+ BOOST_LOG_FUNCTION();
+#ifdef ENABLE_DEBUG_LODDING
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug)
+ << "KSE : Request certificate chain";
+#endif
+
+ std::string leaf_cert;
+ std::string subca_cert;
+
+ int error = 0;
+
+ if(error = get_certificate(LEAF_CERT_INDEX, leaf_cert))
+ return error;
+ if(error = get_certificate(SUBCA_CERT_INDEX, subca_cert))
+ return error;
+
+ x509_crt_rewriter cert_writer;
+ if(error = cert_writer.parse(reinterpret_cast<const unsigned char *>(leaf_cert.c_str()),
+ leaf_cert.length()+1)) {
+ return error;
+ }
+ if(error = cert_writer.parse(reinterpret_cast<const unsigned char *>(subca_cert.c_str()),
+ subca_cert.length()+1)) {
+ return error;
+ }
+ cert_writer.sort_chain();
+
+ mutable_chain.append(cert_writer.emit_pem());
+
+#ifdef ENABLE_DEBUG_LODDING
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug)
+ << "Requested certificate in " << this;
+#endif
+
+ 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";
+ hal_ecdsa_mode mode = {HAL_ECDSA_SEC_P256R1, HAL_HASH_UNKNOWN};
+
+ int error = resolver.invoke<int, hal_data *, unsigned int, hal_ecdsa_mode *, hal_data *>(
+ &kse_get_ecdsa_signature_key, method_name,
+ &hashed_data, PRIVATE_KEY_INDEX, &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(...) {
+ }
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "KSE: Generated ECDSA signature";
+#endif
+
+ digestResult.assign((const char *)signed_data.data, signed_data.data_len);
+
+ free(signed_data.data);
+ return 0;
+}
+
+CryptoKeyType kse_backend_context::key_type()
+{
+ return fKeyType;
+}
+
+unsigned int kse_backend_context::key_length()
+{
+ return 256;
+}
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2019 Samsung Electronics All Rights Reserved.
+ *
+ * Author: Dongsun Lee <ds73.lee@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:
+ int get_certificate(unsigned int index, std::string& cert);
+
+private:
+ CryptoKeyType fKeyType;
+ std::weak_ptr<kse_backend> fBackendPtr;
+};
+
+#endif /* DCM_DAEMON_KSE_BACKEND_KSEBACKENDCONTEXT_H_ */
%{_bindir}/dcm_example_capi
%{_bindir}/dcm_api_test
%{_bindir}/dcm_test_cert_rewriter
+%{_bindir}/dcm_konaise_tool
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})
+#######################################################################################
+
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2019 Samsung Electronics All Rights Reserved.
+ *
+ * Author: Dongsun Lee <ds73.lee@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 <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;
+static int kse_ec_sign = 0x21;
+static int kse_ec_verify= 0x22;
+
+
+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)
+ {
+ loaded = fDllResolver.ensure_loaded();
+ }
+
+ ~SEKonai(){
+ }
+
+ bool is_loaded() {
+ return loaded;
+ }
+
+ void get_cert(int idx, const std::string& fileName){
+ hal_data cert = {0};
+
+ const char *method_name = "hal_get_certificate";
+ int error = fDllResolver.invoke<int, unsigned int, hal_data *>(&kse_cert_get,
+ method_name, idx, &cert);
+ if(error == 0) {
+ write_file(fileName, cert);
+ 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 = {0};
+ 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, hal_data *>(&kse_cert_add,
+ method_name, idx, data);
+ if(error == 0) {
+ std::cout << "SUCCEEDED in " << method_name << "." << std::endl;
+ } else {
+ std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl;
+ }
+ free_hal_data(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 = {0};
+ if(privFileName.size() != 0)
+ 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_hal_data(key);
+ free_hal_data(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;
+ }
+ }
+
+ void ec_sec_p256r1_sign(std::string hash_file, int key_idx, std::string sig_file) {
+ hal_data *hashed_data = read_file(hash_file);
+ hal_data signed_data = {0};
+
+ const char *method_name = "hal_ecdsa_sign_md";
+ hal_ecdsa_mode mode = {HAL_ECDSA_SEC_P256R1, HAL_HASH_UNKNOWN};
+ int error = fDllResolver.invoke<int, hal_data *,
+ unsigned int, hal_ecdsa_mode *, hal_data *>(
+ &kse_ec_sign, method_name,
+ hashed_data, key_idx, &mode, &signed_data);
+ if(error == 0) {
+ write_file(sig_file, signed_data);
+ std::cout << "SUCCEEDED in " << method_name << "." << std::endl;
+ } else {
+ std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl;
+ }
+ free_hal_data(hashed_data);
+ free(signed_data.data);
+ }
+
+ void ec_sec_p256r1_verify(std::string hash_file, int key_idx, std::string sig_file) {
+ // ec_sign hash_file key_index key_type sigfile(out)
+ hal_data *hashed_data = read_file(hash_file);
+ hal_data *signed_data = read_file(sig_file);
+
+ const char *method_name = "hal_ecdsa_verify_md";
+ hal_ecdsa_mode mode = {HAL_ECDSA_SEC_P256R1, HAL_HASH_UNKNOWN};
+ int error = fDllResolver.invoke<int, hal_ecdsa_mode, hal_data *, hal_data *,
+ unsigned int>(
+ &kse_ec_verify, method_name,
+ mode, hashed_data, signed_data, key_idx);
+ if(error == 0) {
+ std::cout << "SUCCEEDED in " << method_name << "." << std::endl;
+ } else {
+ std::cout << "FAILED in " << method_name << ". ERROR=" << error << std::endl;
+ }
+ free_hal_data(hashed_data);
+ free_hal_data(signed_data);
+ }
+
+ 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: return 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;
+ std::cout << " example: " << prog_name << " ec_sec_p256r1_sign hash_file key_idx sigfile(out)" << std::endl;
+ std::cout << " example: " << prog_name << " ec_sec_p256r1_verify hash_file key_idx sigfile(in)" << std::endl;
+}
+
+int main(int argc, char ** argv)
+{
+ 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]);
+
+ if((cmd.compare("get_cert") == 0) && argc > 3) {
+ se.get_cert(std::stoi(argv[2]), std::string(argv[3]));
+ }else if((cmd.compare("add_cert") == 0) && argc > 3) {
+ se.add_cert(std::string(argv[2]), std::stoi(argv[3]));
+ }else if((cmd.compare("del_cert") == 0) && argc > 2) {
+ se.del_cert(std::stoi(argv[2]));
+ }else if((cmd.compare("get_key") == 0) && argc > 4) {
+ se.get_key(se.get_key_type(std::string(argv[2])),
+ std::stoi(argv[3]), std::string(argv[4]));
+ }else if((cmd.compare("add_key") == 0) && argc >= 5) {
+ char * priv_file = nullptr;
+ if(argc > 5)
+ priv_file = argv[5];
+ se.add_key(std::string(argv[2]), se.get_key_type(std::string(argv[3])),
+ std::stoi(argv[4]), std::string(priv_file));
+ }else if((cmd.compare("del_key") == 0) && argc > 3) {
+ se.del_key(se.get_key_type(std::string(argv[2])), std::stoi(argv[3]));
+ }else if((cmd.compare("ec_sec_p256r1_sign") == 0) && argc > 4) {
+ se.ec_sec_p256r1_sign(std::string(argv[2]), std::stoi(argv[3]),
+ std::string(argv[4]));
+ }else if((cmd.compare("ec_sec_p256r1_verify") == 0) && argc > 4) {
+ se.ec_sec_p256r1_verify(std::string(argv[2]), std::stoi(argv[3]),
+ std::string(argv[4]));
+ }else {
+ print_usage(argv[0]);
+ return -1;
+ }
+
+ return 0;
+}