From 23cd75894b5eccb3128c7a0b147044ec943b2340 Mon Sep 17 00:00:00 2001 From: Pawel Kowalski Date: Mon, 25 Sep 2017 10:36:02 +0200 Subject: [PATCH 01/16] Add openssl error handling in key-manager There was no distinction between different types of errors returned by OpenSSL functions. Because of that the information returned to a developer could be not complete and misleading. In order to solve this problem, translator of OpenSSL errors to CKM errors was written. Now, macro OPENSSL_ERROR_HANDLE may be used to handle OpenSSL errors and provide full error information into log system. Change-Id: I63b54f76faaa5b36385bed167db03d97f034402f --- src/include/ckmc/ckmc-manager.h | 6 +- src/manager/CMakeLists.txt | 1 + src/manager/common/exception.h | 2 + src/manager/common/openssl-error-handler.cpp | 193 +++++++++++++++++++++++++ src/manager/common/openssl-error-handler.h | 55 +++++++ src/manager/crypto/generic-backend/exception.h | 1 + src/manager/crypto/sw-backend/crypto.h | 25 ++-- src/manager/crypto/sw-backend/internals.cpp | 167 ++++++++------------- src/manager/crypto/sw-backend/internals.h | 6 +- src/manager/crypto/sw-backend/obj.cpp | 3 - src/manager/crypto/sw-backend/store.cpp | 10 +- src/manager/service/crypto-logic.cpp | 14 +- 12 files changed, 346 insertions(+), 137 deletions(-) create mode 100644 src/manager/common/openssl-error-handler.cpp create mode 100644 src/manager/common/openssl-error-handler.h diff --git a/src/include/ckmc/ckmc-manager.h b/src/include/ckmc/ckmc-manager.h index 7cc2d9a..3924929 100644 --- a/src/include/ckmc/ckmc-manager.h +++ b/src/include/ckmc/ckmc-manager.h @@ -814,7 +814,7 @@ int ckmc_remove_alias(const char *alias); * otherwise a negative error value * @retval #CKMC_ERROR_NONE Successful * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid - * mandatory algorithm parameter, decrypted = NULL, + * mandatory algorithm parameter or RSA data too long, decrypted = NULL, * ppencrypted = NULL) * @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in) * @retval #CKMC_ERROR_DB_ERROR Failed due to the error with unknown reason @@ -851,8 +851,8 @@ int ckmc_encrypt_data(ckmc_param_list_h params, const char *key_alias, const cha * otherwise a negative error value * @retval #CKMC_ERROR_NONE Successful * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid - * mandatory algorithm parameter, encrypted = NULL, - * ppdecrypted = NULL) + * mandatory algorithm parameter, GCM tag authentication failed, key or data is wrong, + * in case of RSA key is wrong or data too long, encrypted = NULL, ppdecrypted = NULL) * @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in) * @retval #CKMC_ERROR_DB_ERROR Failed due to the error with unknown reason * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN Key with given alias does not exist diff --git a/src/manager/CMakeLists.txt b/src/manager/CMakeLists.txt index d07b817..4247a74 100644 --- a/src/manager/CMakeLists.txt +++ b/src/manager/CMakeLists.txt @@ -17,6 +17,7 @@ SET(COMMON_SOURCES ${COMMON_PATH}/common/base64.cpp ${COMMON_PATH}/common/crypto-init.cpp ${COMMON_PATH}/common/data-type.cpp + ${COMMON_PATH}/common/openssl-error-handler.cpp ${COMMON_PATH}/common/exception.cpp ${COMMON_PATH}/common/protocols.cpp ${COMMON_PATH}/common/message-buffer.cpp diff --git a/src/manager/common/exception.h b/src/manager/common/exception.h index 2218830..10414b9 100644 --- a/src/manager/common/exception.h +++ b/src/manager/common/exception.h @@ -124,6 +124,8 @@ using InputParam = DefineException; using AuthenticationFailed = DefineException; +using VerificationFailed = + DefineException; using InvalidFormat = DefineException; using BadResponse = diff --git a/src/manager/common/openssl-error-handler.cpp b/src/manager/common/openssl-error-handler.cpp new file mode 100644 index 0000000..cac3834 --- /dev/null +++ b/src/manager/common/openssl-error-handler.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2017 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 openssl-error-handler.cpp + * @author Pawel Kowalski (p.kowalski2@partner.samsung.com) + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "openssl-error-handler.h" +#include + +#include +#include +#include + +#define OPENSSL_SUCCESS 1 + +namespace CKM { + +static const int GENERIC_REASON_MAX = 99; + +#define ERRORDESCRIBE(name) case name: return #name +const char *ckm_debug_translate_error(int err) +{ + switch (err) { + ERRORDESCRIBE(CKM_API_SUCCESS); + ERRORDESCRIBE(CKM_API_ERROR_INPUT_PARAM); + ERRORDESCRIBE(CKM_API_ERROR_OUT_OF_MEMORY); + ERRORDESCRIBE(CKM_API_ERROR_SERVER_ERROR); + ERRORDESCRIBE(CKM_API_ERROR_AUTHENTICATION_FAILED); + ERRORDESCRIBE(CKM_API_ERROR_VERIFICATION_FAILED); + default: return "Error not defined"; + } +} +#undef ERRORDESCRIBE + +void errorDump() +{ + BIO *bio = BIO_new(BIO_s_mem()); + ERR_print_errors(bio); + char *buf = NULL; + size_t len = BIO_get_mem_data(bio, &buf); + BIO_free(bio); + std::string ret(buf, len); + free(buf); + LogError(ret); +} + +void errorHandle(const char *file, int line, const char *function, int openssl_ret) +{ + if (openssl_ret >= OPENSSL_SUCCESS) + return; + + int ret = CKM_API_SUCCESS; + + unsigned long err = ERR_peek_error(); + + if (err == 0) + ret = CKM_API_ERROR_SERVER_ERROR; + + /* known errors */ + switch (err) { +#if OPENSSL_VERSION_NUMBER > 0x10100000L + case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): + case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): +#else /* OPENSSL_VERSION_NUMBER > 0x10100000L */ + case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS): + case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS): + case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): + case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): +#endif /* OPENSSL_VERSION_NUMBER > 0x10100000L */ + case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION): + case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE): + case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS): + case ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE): + case ERR_PACK(ERR_LIB_DSA, DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE): + case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG): + case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG): + case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT): + case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT): + case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ): + case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ): + case ERR_PACK(ERR_LIB_PEM, PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ): + ret = CKM_API_ERROR_INPUT_PARAM; + break; + case ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY): + case ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE): + case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, EVP_R_NO_VERIFY_FUNCTION_CONFIGURED): + ret = CKM_API_ERROR_VERIFICATION_FAILED; + break; + } + + /* known rsa padding errors */ + if (ret == CKM_API_SUCCESS && ERR_GET_LIB(err) == ERR_LIB_RSA) { + switch (ERR_GET_FUNC(err)) { + case RSA_F_CHECK_PADDING_MD: + case RSA_F_RSA_PADDING_CHECK_NONE: + case RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP: + case RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1: + case RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1: + case RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2: + case RSA_F_RSA_PADDING_CHECK_SSLV23: + case RSA_F_RSA_PADDING_CHECK_X931: + case RSA_F_RSA_PADDING_ADD_NONE: + case RSA_F_RSA_PADDING_ADD_PKCS1_OAEP: + case RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1: + case RSA_F_RSA_PADDING_ADD_PKCS1_PSS: + case RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1: + case RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1: + case RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2: + case RSA_F_RSA_PADDING_ADD_SSLV23: + case RSA_F_RSA_PADDING_ADD_X931: + ret = CKM_API_ERROR_INPUT_PARAM; + break; + } + } + + /* fatal errors */ + int reason = ERR_GET_REASON(err); + if (ret == CKM_API_SUCCESS && reason <= GENERIC_REASON_MAX && (err & ERR_R_FATAL) > 0) { + switch (reason) { + case ERR_R_MALLOC_FAILURE: + ret = CKM_API_ERROR_OUT_OF_MEMORY; + break; + case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED: + case ERR_R_PASSED_NULL_PARAMETER: + ret = CKM_API_ERROR_INPUT_PARAM; + break; + case ERR_R_INTERNAL_ERROR: + case ERR_R_DISABLED: + ret = CKM_API_ERROR_SERVER_ERROR; + break; + } + } + + /* neither known nor fatal, unknown */ + if (ret == CKM_API_SUCCESS) { + errorDump(); + } + + /* remove all errors from queue */ + ERR_clear_error(); + + switch(ret) { + case CKM_API_ERROR_INPUT_PARAM: + throw CKM::Exc::InputParam(file, function, line, ""); + case CKM_API_ERROR_OUT_OF_MEMORY: + throw CKM::Exc::InternalError(file, function, line, "Out of memory"); + case CKM_API_ERROR_SERVER_ERROR: + throw CKM::Exc::InternalError(file, function, line, ""); + case CKM_API_ERROR_AUTHENTICATION_FAILED: + throw CKM::Exc::AuthenticationFailed(file, function, line, ""); + case CKM_API_ERROR_VERIFICATION_FAILED: + throw CKM::Exc::VerificationFailed(file, function, line, ""); + default: + throw CKM::Exc::InternalError(file, function, line, "Error not described"); + } + +} + +} // namespace CKM \ No newline at end of file diff --git a/src/manager/common/openssl-error-handler.h b/src/manager/common/openssl-error-handler.h new file mode 100644 index 0000000..407d2fa --- /dev/null +++ b/src/manager/common/openssl-error-handler.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017 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 openssl-error-handler.h + * @author Pawel Kowalski (p.kowalski2@partner.samsung.com) + */ + +#pragma once + +#include +#include +#include +#include + +#include + +#include +#include +#include + +namespace CKM { + +COMMON_API void errorDump(); +#define OPENSSL_ERROR_DUMP() errorDump() +#define OPENSSL_ERROR_CLEAR() ERR_clear_error() + +/** + * Function responsible for translating the OpenSSL error to CKM error and + * clearing/dumping the OpenSSL error queue. + * + * The function checks only first error in the queue. + * If the function doesn't find any error in OpenSSL queue or is not + * able to translate it, it will return CKM_API_ERROR_SERVER_ERROR and + * dump OpenSSL errors if any. The function clears the error queue and + * returns the result of translation. + */ +COMMON_API void errorHandle(const char *file, int line, const char *function, int openssl_ret); +#define OPENSSL_ERROR_HANDLE(openssl_ret) { \ + ERR_clear_error(); \ + errorHandle(__FILE__, __LINE__, __func__, openssl_ret); \ +} + +} // namespace CKM \ No newline at end of file diff --git a/src/manager/crypto/generic-backend/exception.h b/src/manager/crypto/generic-backend/exception.h index cdd4415..f1155e1 100644 --- a/src/manager/crypto/generic-backend/exception.h +++ b/src/manager/crypto/generic-backend/exception.h @@ -31,6 +31,7 @@ typedef CKM::Exc::InternalError InternalError; typedef CKM::Exc::InternalError DataTypeNotSupported; typedef CKM::Exc::InternalError OperationNotSupported; typedef CKM::Exc::InternalError WrongBackend; +typedef CKM::Exc::AuthenticationFailed AuthenticationFailed; } // namespace Exc } // namespace Crypto diff --git a/src/manager/crypto/sw-backend/crypto.h b/src/manager/crypto/sw-backend/crypto.h index 9925197..08ba272 100644 --- a/src/manager/crypto/sw-backend/crypto.h +++ b/src/manager/crypto/sw-backend/crypto.h @@ -23,12 +23,15 @@ #include #include +#include #include #include #include +#include + namespace CKM { namespace Crypto { namespace SW { @@ -48,9 +51,9 @@ struct Base { // Low level api. // Allows various cipher specific parameters to be determined and set. - int Control(int type, int arg, void *ptr) + void Control(int type, int arg, void *ptr) { - return EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr); + OPENSSL_ERROR_HANDLE(EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr)); } virtual void AppendAAD(const T &) = 0; @@ -75,15 +78,14 @@ public: { if (static_cast(key.size()) != EVP_CIPHER_key_length(type)) ThrowErr(Exc::Crypto::InternalError, "Wrong key size! Expected: ", - EVP_CIPHER_key_length(type), " Get: ", key.size()); + EVP_CIPHER_key_length(type), " Get: ", key.size()); if (static_cast(iv.size()) < EVP_CIPHER_iv_length(type)) ThrowErr(Exc::Crypto::InternalError, "Wrong iv size! Expected: ", EVP_CIPHER_iv_length(type), " Get: ", iv.size()); - if (1 != EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(), - encryption ? 1 : 0)) - ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherInit"); + OPENSSL_ERROR_HANDLE(EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(), + encryption ? 1 : 0)); EVP_CIPHER_CTX_set_padding(m_ctx, 1); } @@ -94,8 +96,7 @@ public: "Unsupported type inside container."); int bytesLen; - if (1 != EVP_CipherUpdate(m_ctx, NULL, &bytesLen, data.data(), data.size())) - ThrowErr(Exc::Crypto::InternalError, "AppendAAD(): Failed in EVP_CipherUpdate"); + OPENSSL_ERROR_HANDLE(EVP_CipherUpdate(m_ctx, NULL, &bytesLen, data.data(), data.size())); } T Append(const T &data) @@ -105,9 +106,8 @@ public: int bytesLen = static_cast(data.size() + EVP_CIPHER_CTX_block_size(m_ctx)); T output(bytesLen); - if (1 != EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(), - data.size())) - ThrowErr(Exc::Crypto::InternalError, "Append(): Failed in EVP_CipherUpdate"); + OPENSSL_ERROR_HANDLE(EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(), + data.size())); output.resize(bytesLen); return output; @@ -118,8 +118,7 @@ public: int bytesLen = EVP_CIPHER_CTX_block_size(m_ctx); T output(bytesLen); - if (1 != EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen)) - ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherFinal"); + OPENSSL_ERROR_HANDLE(EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen)); output.resize(bytesLen); return output; diff --git a/src/manager/crypto/sw-backend/internals.cpp b/src/manager/crypto/sw-backend/internals.cpp index b519e11..afa3c88 100644 --- a/src/manager/crypto/sw-backend/internals.cpp +++ b/src/manager/crypto/sw-backend/internals.cpp @@ -44,8 +44,10 @@ #include #include -#define OPENSSL_SUCCESS 1 // DO NOTCHANGE THIS VALUE -#define OPENSSL_FAIL 0 // DO NOTCHANGE THIS VALUE +#include + +#define OPENSSL_SUCCESS 1 // DO NOT CHANGE THIS VALUE +#define OPENSSL_FAIL 0 // DO NOT CHANGE THIS VALUE namespace CKM { namespace Crypto { @@ -323,15 +325,17 @@ RawBuffer asymmetricHelper(int (*cryptoFn)(int, const unsigned char *, */ RawBuffer output; output.resize(RSA_size(rsa)); - int ret = cryptoFn(data.size(), - data.data(), - output.data(), - rsa, - RSA_PKCS1_OAEP_PADDING); - RSA_free(rsa); - - if (ret < 0) - ThrowErr(Exc::Crypto::InternalError, logPrefix, "failed"); + int ret; + try { + OPENSSL_ERROR_HANDLE(ret = cryptoFn(data.size(), + data.data(), + output.data(), + rsa, + RSA_PKCS1_OAEP_PADDING)); + } catch (...) { + RSA_free(rsa); + throw; + } output.resize(ret); return output; @@ -409,18 +413,13 @@ DataPair createKeyPairRSA(const int size) ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function !!"); - if (EVP_PKEY_keygen_init(ctx.get()) <= 0) - ThrowErr(Exc::Crypto::InternalError, - "Error in EVP_PKEY_keygen_init function !!"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(ctx.get())); - if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size) <= 0) - ThrowErr(Exc::Crypto::InternalError, - "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size)); EVP_PKEY *pkeyTmp = NULL; - if (!EVP_PKEY_keygen(ctx.get(), &pkeyTmp)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(ctx.get(), &pkeyTmp)); pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free); @@ -445,19 +444,14 @@ DataPair createKeyPairDSA(const int size) if (!pctx) ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function"); - if (EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) - ThrowErr(Exc::Crypto::InternalError, - "Error in EVP_PKEY_paramgen_init function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen_init(pctx.get())); - if (EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size)) - ThrowErr(Exc::Crypto::InternalError, - "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(", size, ") function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size)); /* Generate parameters */ EVP_PKEY *pparamTmp = NULL; - if (EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen(pctx.get(), &pparamTmp)); pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free); @@ -467,14 +461,12 @@ DataPair createKeyPairDSA(const int size) if (!kctx) ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); - if (EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(kctx.get())); /* Generate the key */ EVP_PKEY *pkeyTmp = NULL; - if (!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(kctx.get(), &pkeyTmp)); pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free); @@ -512,19 +504,14 @@ DataPair createKeyPairECDSA(ElipticCurve type) if (!pctx) ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function"); - if (EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) - ThrowErr(Exc::Crypto::InternalError, - "Error in EVP_PKEY_paramgen_init function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen_init(pctx.get())); - if (EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve)) - ThrowErr(Exc::Crypto::InternalError, - "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve)); /* Generate parameters */ EVP_PKEY *pparamTmp = NULL; - if (EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen(pctx.get(), &pparamTmp)); pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free); @@ -534,14 +521,12 @@ DataPair createKeyPairECDSA(ElipticCurve type) if (!kctx) ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); - if (EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(kctx.get())); /* Generate the key */ EVP_PKEY *pkeyTmp = NULL; - if (!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(kctx.get(), &pkeyTmp)); pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free); @@ -626,9 +611,7 @@ std::pair encryptDataAesGcm( RawBuffer tmp = enc->Finalize(); std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); - if (0 == enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data())) - ThrowErr(Exc::Crypto::InternalError, - "Error in AES control function. Get tag failed."); + enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data()); return std::make_pair(result, tag); } @@ -655,7 +638,12 @@ RawBuffer decryptDataAes( EvpCipherPtr dec; selectCipher(type, key.size(), false)(dec, key, iv); RawBuffer result = dec->Append(data); - RawBuffer tmp = dec->Finalize(); + RawBuffer tmp; + try { + tmp = dec->Finalize(); + } catch (const Exc::Exception &e) { + ThrowErr(Exc::InputParam, "Authentication failed in AES finalize function (wrong key/data was used)."); + } std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); return result; } @@ -671,15 +659,18 @@ RawBuffer decryptDataAesGcm( selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv); void *ptr = (void *)tag.data(); - if (0 == dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr)) - ThrowErr(Exc::Crypto::InternalError, - "Error in AES control function. Set tag failed."); + dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr); if (!aad.empty()) dec->AppendAAD(aad); RawBuffer result = dec->Append(data); - RawBuffer tmp = dec->Finalize(); + RawBuffer tmp; + try { + tmp = dec->Finalize(); + } catch (const Exc::Exception &e) { + ThrowErr(Exc::InputParam, "Tag authentication failed in AES finalize function (the tag doesn't match)."); + } std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); return result; } @@ -831,39 +822,27 @@ RawBuffer signMessage(EVP_PKEY *privKey, if (!pctx.get()) ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); - if (EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign_init function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_sign_init(pctx.get())); /* Set padding algorithm */ if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) - if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) - ThrowErr(Exc::Crypto::InputParam, - "Error in EVP_PKEY_CTX_set_rsa_padding function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)); /* Finalize the Sign operation */ /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the * signature. Length is returned in slen */ size_t slen; - if (EVP_SUCCESS != EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), - message.size())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size())); /* Allocate memory for the signature based on size in slen */ RawBuffer sig(slen); - if (EVP_SUCCESS == EVP_PKEY_sign(pctx.get(), - sig.data(), - &slen, - message.data(), - message.size())) { - // Set value to return RawData - sig.resize(slen); - return sig; - } + OPENSSL_ERROR_HANDLE(EVP_PKEY_sign(pctx.get(), sig.data(), &slen, message.data(), message.size())); - ThrowErr(Exc::Crypto::InputParam, - "Error in EVP_PKEY_sign function. Input param error."); + // Set value to return RawData + sig.resize(slen); + return sig; } RawBuffer digestSignMessage(EVP_PKEY *privKey, @@ -879,35 +858,27 @@ RawBuffer digestSignMessage(EVP_PKEY *privKey, if (!mdctx.get()) ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function"); - if (EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, - privKey)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignInit function"); + OPENSSL_ERROR_HANDLE(EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey)); /* Set padding algorithm */ if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) - if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) - ThrowErr(Exc::Crypto::InputParam, - "Error in EVP_PKEY_CTX_set_rsa_padding function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)); /* Call update with the message */ - if (EVP_SUCCESS != EVP_DigestSignUpdate(mdctx.get(), message.data(), - message.size())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignUpdate function"); + OPENSSL_ERROR_HANDLE(EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size())); /* Finalize the DigestSign operation */ /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the * signature. Length is returned in slen */ size_t slen; - if (EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), NULL, &slen)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function"); + OPENSSL_ERROR_HANDLE(EVP_DigestSignFinal(mdctx.get(), NULL, &slen)); /* Allocate memory for the signature based on size in slen */ RawBuffer sig(slen); /* Obtain the signature */ - if (EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function"); + OPENSSL_ERROR_HANDLE(EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen)); // Set value to return RawData sig.resize(slen); @@ -965,16 +936,13 @@ int verifyMessage(EVP_PKEY *pubKey, if (!pctx.get()) ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); - if (EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_verify_init function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_verify_init(pctx.get())); - /* Set padding algorithm */ + /* Set padding algorithm */ if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) - if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) - ThrowErr(Exc::Crypto::InputParam, - "Error in EVP_PKEY_CTX_set_rsa_padding function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)); - if (EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(), + if (OPENSSL_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(), signature.size(), message.data(), message.size())) return CKM_API_SUCCESS; @@ -991,25 +959,17 @@ int digestVerifyMessage(EVP_PKEY *pubKey, EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy); EVP_PKEY_CTX *pctx = NULL; - /* Create the Message Digest Context */ if (!mdctx.get()) ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function"); - if (EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, - pubKey)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyInit function"); + OPENSSL_ERROR_HANDLE(EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey)); if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) - if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) - ThrowErr(Exc::Crypto::InputParam, - "Error in EVP_PKEY_CTX_set_rsa_padding function"); + OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)); - if (EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(), - message.size())) - ThrowErr(Exc::Crypto::InternalError, - "Error in EVP_DigestVerifyUpdate function"); + OPENSSL_ERROR_HANDLE(EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size())); - if (EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(), + if (OPENSSL_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(), const_cast(signature.data()), signature.size())) return CKM_API_SUCCESS; @@ -1088,5 +1048,4 @@ bool verifyBinaryData(DataType dataType, const RawBuffer &buffer) } // namespace Internals } // namespace SW } // namespace Crypto -} // namespace CKM - +} // namespace CKM \ No newline at end of file diff --git a/src/manager/crypto/sw-backend/internals.h b/src/manager/crypto/sw-backend/internals.h index 56a1e00..0c984c6 100644 --- a/src/manager/crypto/sw-backend/internals.h +++ b/src/manager/crypto/sw-backend/internals.h @@ -24,9 +24,6 @@ #include #include -#define EVP_SUCCESS 1 // DO NOTCHANGE THIS VALUE -#define EVP_FAIL 0 // DO NOTCHANGE THIS VALUE - #define CKM_CRYPTO_INIT_SUCCESS 1 #define CKM_CRYPTO_CREATEKEY_SUCCESS 2 #define CKM_VERIFY_CHAIN_SUCCESS 5 @@ -131,5 +128,4 @@ bool verifyBinaryData(DataType dataType, const RawBuffer &buffer); } // namespace Internals } // namespace SW } // namespace Crypto -} // namespace CKM - +} // namespace CKM \ No newline at end of file diff --git a/src/manager/crypto/sw-backend/obj.cpp b/src/manager/crypto/sw-backend/obj.cpp index 8b5e21a..a7a7cdc 100644 --- a/src/manager/crypto/sw-backend/obj.cpp +++ b/src/manager/crypto/sw-backend/obj.cpp @@ -30,9 +30,6 @@ #include #include -#define EVP_SUCCESS 1 // DO NOTCHANGE THIS VALUE -#define EVP_FAIL 0 // DO NOTCHANGE THIS VALUE - namespace CKM { namespace Crypto { namespace SW { diff --git a/src/manager/crypto/sw-backend/store.cpp b/src/manager/crypto/sw-backend/store.cpp index d9a7353..63cd046 100644 --- a/src/manager/crypto/sw-backend/store.cpp +++ b/src/manager/crypto/sw-backend/store.cpp @@ -112,8 +112,10 @@ RawBuffer unpack(const RawBuffer &packed, const Password &pass) try { ret = Crypto::SW::Internals::decryptDataAesGcm(key, encrypted, iv, tag); - } catch (const Exc::Crypto::InternalError &e) { - ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed"); + } catch (const Exc::Crypto::InputParam &e) { + ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed, authentication failed"); + } catch (const Exc::Exception &e) { + ThrowErr(Exc::InternalError, "Decryption with custom password failed, internal error"); } return ret; @@ -133,8 +135,8 @@ RawBuffer pack(const RawBuffer &data, const Password &pass) try { ret = Crypto::SW::Internals::encryptDataAesGcm(key, data, iv, Params::DEFAULT_AES_GCM_TAG_LEN_BYTES); - } catch (const Exc::Crypto::InternalError &e) { - ThrowErr(Exc::AuthenticationFailed, "Encryption with custom password failed"); + } catch (const Exc::Exception &e) { + ThrowErr(Exc::InternalError, "Encryption with custom password failed, internal error"); } scheme |= EncryptionScheme::PASSWORD; diff --git a/src/manager/service/crypto-logic.cpp b/src/manager/service/crypto-logic.cpp index 536783c..3cbfedb 100644 --- a/src/manager/service/crypto-logic.cpp +++ b/src/manager/service/crypto-logic.cpp @@ -127,8 +127,6 @@ void CryptoLogic::encryptRow(DB::Row &row) { DB::Row crow = row; RawBuffer key; - RawBuffer result1; - RawBuffer result2; crow.algorithmType = DBCMAlgType::AES_GCM_256; crow.dataSize = crow.data.size(); @@ -147,8 +145,13 @@ void CryptoLogic::encryptRow(DB::Row &row) CLEAR_FLAGS(crow.encryptionScheme); SET_FLAG(ENCR_APPKEY, crow.encryptionScheme); - auto dataPair = Crypto::SW::Internals::encryptDataAesGcm(key, crow.data, + std::pair dataPair; + try { + dataPair = Crypto::SW::Internals::encryptDataAesGcm(key, crow.data, crow.iv, AES_GCM_TAG_SIZE); + } catch (const Exc::Exception &e) { + ThrowErr(Exc::InternalError, "Encryption failed in encryptRow"); + } crow.data = dataPair.first; crow.tag = dataPair.second; @@ -171,7 +174,6 @@ void CryptoLogic::decryptRow(const Password &password, DB::Row &row) { DB::Row crow = row; RawBuffer key; - RawBuffer digest, dataDigest; if (row.algorithmType != DBCMAlgType::AES_GCM_256) ThrowErr(Exc::AuthenticationFailed, "Invalid algorithm type."); @@ -215,8 +217,10 @@ void CryptoLogic::decryptRow(const Password &password, DB::Row &row) crow.tag); } } - } catch (const Exc::Exception &e) { + } catch (const Exc::Crypto::InputParam &e) { ThrowErr(Exc::AuthenticationFailed, e.message()); + } catch (const Exc::Exception &e) { + ThrowErr(Exc::InternalError, "Internal error during decryption"); } if (static_cast(crow.data.size()) < crow.dataSize) -- 2.7.4 From 9abf98902c3b3c661a0c61b26a957cd5fba564ed Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Thu, 11 Jan 2018 10:38:00 +0100 Subject: [PATCH 02/16] Updated documentation to match supported features when key-manager-ta is present. GP API specification has subtle impact on features supported by key-manager: * passing data chunks bigger than TEEC_CONFIG_SHAREDMEM_MAX_SIZE is not supported by TEE Subtracting few kB for passing keys, options/cipher, at least 500 kB is left for user-data * GCM modes with tag lengths 32 and 64 bits are treated as insecure and are also not supported Change-Id: I9634531dbbfea153a2f4f45bc790521eff014e83 --- doc/key-manager_doc.h | 9 +++++++++ src/include/ckm/ckm-manager-async.h | 10 ++++++++++ src/include/ckm/ckm-manager.h | 10 ++++++++++ src/include/ckmc/ckmc-manager.h | 10 ++++++++-- src/include/ckmc/ckmc-type.h | 3 ++- 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/doc/key-manager_doc.h b/doc/key-manager_doc.h index 776a124..f553f7a 100644 --- a/doc/key-manager_doc.h +++ b/doc/key-manager_doc.h @@ -24,6 +24,7 @@ * @defgroup CAPI_KEY_MANAGER_MODULE Key Manager * @brief The key manager provides a secure repository protected by Tizen platform for keys, certificates, and sensitive data of users and/or their APPs. * Additionally, the key manager provides secure cryptographic operations for non-exportable keys without revealing key values to clients. + * Since Tizen 5.0 on chosen system images, module may use ARM TrustZone technology and may rely on particular TEE (Trusted Execution Environment) implementation. * @section CAPI_KEY_MANAGER_MODULE_OVERVIEW Overview * * @@ -64,6 +65,14 @@ * - The client can specify only its own package id in the alias when storing a key, certificate, or data. * - A client should specify the package id of the owner in the alias to retrieve a a key, certificate, or data shared by other applications. * - Aliases are returned as the format of "package_id name" from the key-manager. + * Supported features + * Since Tizen 5.0 on chosen images, the realization of module functionality can be implemened using ARM TrustZone technology. + * Differences in standards governing TrustZone implementation and previous software-based implementation cause following differences in module operation: + * - When using TrustZone-based backend, GCM modes with 32 and 64 bit tag lengths are not supported. + * Global Platform TEE specification treats these configurations as unsafe and not supported. + * - When using TrustZone-based backend, passing big amounts of data (encryption/decryption) to the module has additional size restriction. + * Now it depends on the TEEC_CONFIG_SHAREDMEM_MAX_SIZE definition, specific for given TEE implementation, minus size of key-information needed to be passed to TEE. + * Minimum supported value for passing data to the module is at 500 kB. */ diff --git a/src/include/ckm/ckm-manager-async.h b/src/include/ckm/ckm-manager-async.h index da2d445..f812aea 100644 --- a/src/include/ckm/ckm-manager-async.h +++ b/src/include/ckm/ckm-manager-async.h @@ -196,6 +196,11 @@ public: const Label &accessor, PermissionMask permissionMask); + // This function will encrypt data. + // Since Tizen 5.0, on chosen images using TEE backend: + // * maximum size of data can be limited to TEE-specific value; minimum 500 kB is supported) + // * GCM modes with short tags (32 and 64 bits) are not supported + // In these cases, key-manager can return a CKM_API_ERROR_SERVER_ERROR void encrypt( const ObserverPtr &observer, const CryptoAlgorithm &algo, @@ -203,6 +208,11 @@ public: const Password &password, const RawBuffer &plain); + // This function will decrypt data. + // Since Tizen 5.0, on chosen images using TEE backend: + // * maximum size of data can be limited to TEE-specific value; minimum 500 kB is supported) + // * GCM modes with short tags (32 and 64 bits) are not supported + // In these cases, key-manager can return a CKM_API_ERROR_SERVER_ERROR void decrypt( const ObserverPtr &observer, const CryptoAlgorithm &algo, diff --git a/src/include/ckm/ckm-manager.h b/src/include/ckm/ckm-manager.h index c300fff..8f67384 100644 --- a/src/include/ckm/ckm-manager.h +++ b/src/include/ckm/ckm-manager.h @@ -146,12 +146,22 @@ public: int setPermission(const Alias &alias, const Label &accessor, PermissionMask permissionMask); + // This function will encrypt data. + // Since Tizen 5.0, on chosen images using TEE backend: + // * maximum size of data can be limited to TEE-specific value; minimum 500 kB is supported) + // * GCM modes with short tags (32 and 64 bits) are not supported + // In these cases, key-manager can return a CKM_API_ERROR_SERVER_ERROR int encrypt(const CryptoAlgorithm &algo, const Alias &keyAlias, const Password &password, const RawBuffer &plain, RawBuffer &encrypted); + // This function will decrypt data. + // Since Tizen 5.0, on chosen images using TEE backend: + // * maximum size of data can be limited to TEE-specific value; minimum 500 kB is supported) + // * GCM modes with short tags (32 and 64 bits) are not supported + // In these cases, key-manager can return a CKM_API_ERROR_SERVER_ERROR int decrypt(const CryptoAlgorithm &algo, const Alias &keyAlias, const Password &password, diff --git a/src/include/ckmc/ckmc-manager.h b/src/include/ckmc/ckmc-manager.h index 3924929..86ee07f 100644 --- a/src/include/ckmc/ckmc-manager.h +++ b/src/include/ckmc/ckmc-manager.h @@ -804,9 +804,11 @@ int ckmc_remove_alias(const char *alias); * @param[in] password The password used in decrypting a key value \n * If password of the policy is provided in ckmc_save_key(), the same * password should be provided - * @param[in] decrypted Data to be encrypted. In case of AES algorithm there are no restrictions on the size of data. + * @param[in] decrypted Data to be encrypted. In case of AES algorithm there are no restrictions on the size of data, + * if S/W backend is used. If module uses TEE backend (since Tizen 5.0 on chosen images), + * maximum size of data is implementation-specific and at least 500 kB. * For RSA the size must be smaller or equal to key size in bytes - 42. - * Example: for 1024 RSA key the maximum data size is 1024/8 - 42 = 86 + * Example: for 1024 RSA key the maximum data size is 1024/8 - 42 = 86. * @param[out] ppencrypted Encrypted data (some algorithms may return additional information embedded in encrypted data. * AES GCM is an example) \n * The caller is responsible for freeing @a encrypted with ckmc_buffer_free() @@ -821,6 +823,7 @@ int ckmc_remove_alias(const char *alias); * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN Key with given alias does not exist * @retval #CKMC_ERROR_PERMISSION_DENIED Failed to access key manager * @retval #CKMC_ERROR_AUTHENTICATION_FAILED Key decryption failed because password is incorrect + * @retval #CKMC_ERROR_SERVER_ERROR Too big data size or unsupported GCM mode (32 and 64 bit tag lengths not supported on TEE backend) or internal error * @pre User is already logged in and the user key is already loaded into memory in plain text form. * @see ckmc_buffer_free() * @see ckmc_param_list_new() @@ -845,6 +848,8 @@ int ckmc_encrypt_data(ckmc_param_list_h params, const char *key_alias, const cha * @param[in] password The password used in decrypting a key value \n * If password of the policy is provided in ckmc_save_key(), the same password should be provided * @param[in] encrypted Data to be decrypted (some algorithms may require additional information embedded in encrypted data. AES GCM is an example) + * Since Tizen 5.0, on chosen images where module is using TEE backend, data size is limited to at least 500 kB + * (TEE implementation-specific). * @param[out] ppdecrypted Decrypted data \n * The caller is responsible for freeing @a decrypted with ckmc_buffer_free() * @return @c 0 on success, @@ -858,6 +863,7 @@ int ckmc_encrypt_data(ckmc_param_list_h params, const char *key_alias, const cha * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN Key with given alias does not exist * @retval #CKMC_ERROR_PERMISSION_DENIED Failed to access key manager * @retval #CKMC_ERROR_AUTHENTICATION_FAILED Key decryption failed because password is incorrect + * @retval #CKMC_ERROR_SERVER_ERROR Too big data size or unsupported GCM mode (32 and 64 bit tag lengths not supported on TEE backend) or internal error * @pre User is already logged in and the user key is already loaded into memory in plain text form. * @see ckmc_buffer_free() * @see ckmc_param_list_new() diff --git a/src/include/ckmc/ckmc-type.h b/src/include/ckmc/ckmc-type.h index 949fbec..036415f 100644 --- a/src/include/ckmc/ckmc-type.h +++ b/src/include/ckmc/ckmc-type.h @@ -325,7 +325,8 @@ typedef enum __ckmc_algo_type { - CKMC_PARAM_ED_IV = initialization vector(mandatory) - CKMC_PARAM_ED_TAG_LEN = GCM tag length in bits. One of {32, 64, 96, 104, 112, 120, 128} (optional, if not present, the - length 128 is used) + length 128 is used; since Tizen 5.0, if TrustZone backend is used, + 32 and 64 lengths are not supported) - CKMC_PARAM_ED_AAD = additional authentication data(optional) */ CKMC_ALGO_AES_CFB, /**< AES-CFB algorithm -- 2.7.4 From 16541e45b75db1f98d39abc0686c1d820ff03814 Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Wed, 7 Mar 2018 11:50:22 +0100 Subject: [PATCH 03/16] Updated documentation headers - typos fix Change-Id: I8ad994a7164f6d85573030e0aeb340c1f0e50d14 --- src/include/ckmc/ckmc-type.h | 4 ++-- src/manager/client/client-common.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/include/ckmc/ckmc-type.h b/src/include/ckmc/ckmc-type.h index 036415f..8a4217b 100644 --- a/src/include/ckmc/ckmc-type.h +++ b/src/include/ckmc/ckmc-type.h @@ -76,7 +76,7 @@ KEY_MANAGER_CAPI extern char const *const ckmc_owner_id_separator; /** * @brief The owner of system database. * @since_tizen 3.0 - * @remarks #ckmc_owner_id_system constains id connected with all system applications that run with uid less than 5000. + * @remarks #ckmc_owner_id_system contains id connected with all system applications that run with uid less than 5000. * Client should use #ckmc_owner_id_system to access data owned by system application and stored in system database. * Client must have permission to access proper row. * @see ckmc_alias_new() @@ -166,7 +166,7 @@ typedef enum __ckmc_access_right { */ typedef enum __ckmc_permission { CKMC_PERMISSION_NONE = 0x00, /**< Clear permissions */ - CKMC_PERMISSION_READ = 0x01, /**< Eead allowed */ + CKMC_PERMISSION_READ = 0x01, /**< Read allowed */ CKMC_PERMISSION_REMOVE = 0x02 /**< Remove allowed */ } ckmc_permission_e; diff --git a/src/manager/client/client-common.h b/src/manager/client/client-common.h index 9dc071c..442da37 100644 --- a/src/manager/client/client-common.h +++ b/src/manager/client/client-common.h @@ -19,7 +19,7 @@ * @file client-common.h * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) * @version 1.0 - * @brief This file constains implementation of common types + * @brief This file contains implementation of common types * used in Central Key Manager. */ -- 2.7.4 From 6f58f2e27aafb72d9f9b06cf31566847422b52bc Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 7 Mar 2018 17:49:11 +0100 Subject: [PATCH 04/16] Remove redundant libcrypto dependency openssl pkg-config requires libcrypto and libssl Change-Id: I222e458a26e0dc15d82654d35fdccc126411000f --- src/CMakeLists.txt | 1 - src/manager/CMakeLists.txt | 1 - tests/encryption-scheme/CMakeLists.txt | 1 - tools/ckm_db_tool/CMakeLists.txt | 1 - 4 files changed, 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ea04f25..04e4d52 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,7 +10,6 @@ PKG_CHECK_MODULES(KEY_MANAGER_DEP glib-2.0 openssl libsmack - libcrypto libsystemd-daemon capi-base-common capi-system-info diff --git a/src/manager/CMakeLists.txt b/src/manager/CMakeLists.txt index 4247a74..2f071eb 100644 --- a/src/manager/CMakeLists.txt +++ b/src/manager/CMakeLists.txt @@ -3,7 +3,6 @@ PKG_CHECK_MODULES(COMMON_DEP dlog openssl libsmack - libcrypto libsystemd-journal ) diff --git a/tests/encryption-scheme/CMakeLists.txt b/tests/encryption-scheme/CMakeLists.txt index 65b7c26..d9f3529 100644 --- a/tests/encryption-scheme/CMakeLists.txt +++ b/tests/encryption-scheme/CMakeLists.txt @@ -23,7 +23,6 @@ INCLUDE(FindPkgConfig) PKG_CHECK_MODULES(ENCRYPTION_SCHEME_DEP REQUIRED openssl - libcrypto libsmack) FIND_PACKAGE(Threads REQUIRED) diff --git a/tools/ckm_db_tool/CMakeLists.txt b/tools/ckm_db_tool/CMakeLists.txt index 40de878..6524712 100644 --- a/tools/ckm_db_tool/CMakeLists.txt +++ b/tools/ckm_db_tool/CMakeLists.txt @@ -5,7 +5,6 @@ PKG_CHECK_MODULES(CKM_DB_TOOL_DEP REQUIRED openssl libsmack - libcrypto capi-base-common capi-system-info libxml-2.0 -- 2.7.4 From bf9f2a516388182c20fb416762235c26666b69f5 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 7 Mar 2018 17:56:41 +0100 Subject: [PATCH 05/16] Remove unnecessary dependencies Do not expose unnecessary libraries to the program that is linking with key-manager library. If the program will not be using the symbols of the required library, it should not be linking directly to that library. Change-Id: I07264f35d023881be8b104307941565047813688 --- build/key-manager.pc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/key-manager.pc.in b/build/key-manager.pc.in index 4867073..b24e72a 100644 --- a/build/key-manager.pc.in +++ b/build/key-manager.pc.in @@ -6,6 +6,6 @@ includedir=${prefix}/include Name: key-manager Description: Central Key Manager Package Version: @VERSION@ -Requires: openssl libsmack +Requires: Libs: -L${libdir} -lkey-manager-client -lkey-manager-common -lkey-manager-control-client Cflags: -I${includedir}/ckm -- 2.7.4 From 9107c1e02042939f41245dfe90a1b2cd0c2adf08 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 2 Mar 2018 15:35:04 +0100 Subject: [PATCH 06/16] Properly detect the presence of TA Tef-simulator and optee use different TA file name formats. Key-manager was detecting the presence of TA by checking the existence of TA file with hardcoded format. It worked with tef-simulator but it failed to detect the TA presence in case of optee. This commit replaces the TA file presence checking with an attempt to open a session using libteec. If an attempt succeeds the decider selects TZ backend. Otherwise, it falls back to SW backend. Change-Id: I840d6b58a1ffa39885a4b8ded0ff70f4147c3de0 --- src/manager/crypto/platform/decider.cpp | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/src/manager/crypto/platform/decider.cpp b/src/manager/crypto/platform/decider.cpp index d5a5506..2a93729 100644 --- a/src/manager/crypto/platform/decider.cpp +++ b/src/manager/crypto/platform/decider.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -41,8 +42,6 @@ namespace Crypto { namespace { -const std::string TA_STORE_PATH = "/usr/lib/tastore"; - template std::string ValueToString(const T& value) { @@ -54,18 +53,6 @@ std::string ValueToString(const T& value) return str.str(); } -std::string convertTeecUUIDToString(TEEC_UUID uuid) -{ - std::string uuidStr; - uuidStr += ValueToString(uuid.timeLow); - uuidStr += ValueToString(uuid.timeMid); - uuidStr += ValueToString(uuid.timeHiAndVersion); - for (auto& c: uuid.clockSeqAndNode) - uuidStr += ValueToString(c); - - return uuidStr; -} - CryptoBackend chooseCryptoBackend(DataType data, const Policy &policy, bool encrypted) @@ -94,16 +81,16 @@ CryptoBackend chooseCryptoBackend(DataType data, if (!data.isSKey()) return CryptoBackend::OpenSSL; - // Check if key-manager TA exists - std::string taUUIDStr = convertTeecUUIDToString(KM_TA_UUID); - - LogDebug("Checking for " << TA_STORE_PATH << "/" << taUUIDStr); - std::ifstream taFile(TA_STORE_PATH + "/" + taUUIDStr); - if (taFile) - return CryptoBackend::TrustZone; + try { + LogDebug("Trying to open TA session..."); + TZ::Internals::TrustZoneContext::Instance(); + } catch (const Exc::Crypto::InternalError& e) { + LogDebug("...failed. Selecting SW backend."); + return CryptoBackend::OpenSSL; + } - // no TA available - fallback to OpenSSL - return CryptoBackend::OpenSSL; + LogDebug("...succeeded. Selecting TZ backend."); + return CryptoBackend::TrustZone; } } // namespace -- 2.7.4 From 873b8e71eeab8beb2bcc87d518908887c43254e2 Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Thu, 22 Mar 2018 16:50:00 +0900 Subject: [PATCH 07/16] Fix coverity defects - 105284: Buffer not null terminated - 108955: Big parameter passed by value - 109815: Uncaught exception Change-Id: I303a652d6ae0540f7d6daa833a30ef0fb691ffb8 Signed-off-by: Dongsun Lee --- src/manager/client-async/connection-thread.cpp | 12 ++++++++++-- src/manager/service/encryption-service.cpp | 2 +- src/manager/service/key-provider.cpp | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/manager/client-async/connection-thread.cpp b/src/manager/client-async/connection-thread.cpp index 555056b..d663513 100644 --- a/src/manager/client-async/connection-thread.cpp +++ b/src/manager/client-async/connection-thread.cpp @@ -57,8 +57,16 @@ ConnectionThread::ConnectionThread() : ConnectionThread::~ConnectionThread() { m_join = true; - m_pipe.notify(); - m_thread.join(); + try { + m_pipe.notify(); + m_thread.join(); + } catch (CKM::Exception &e) { + LogError("CKM::Exception::Exception " << e.DumpToString()); + } catch (std::exception &e) { + LogError("STD exception " << e.what()); + } catch (...) { + LogError("Unknown exception occured"); + } } void ConnectionThread::run() diff --git a/src/manager/service/encryption-service.cpp b/src/manager/service/encryption-service.cpp index f886867..e403584 100644 --- a/src/manager/service/encryption-service.cpp +++ b/src/manager/service/encryption-service.cpp @@ -103,7 +103,7 @@ bool EncryptionService::ProcessOne( ProcessEncryption(conn, info.credentials, info.buffer); return true; - } catch (MessageBuffer::Exception::Base) { + } catch (MessageBuffer::Exception::Base &) { LogError("Broken protocol. Closing socket."); } catch (const std::exception &e) { LogError("Std exception:: " << e.what()); diff --git a/src/manager/service/key-provider.cpp b/src/manager/service/key-provider.cpp index 60cce23..15bff3d 100644 --- a/src/manager/service/key-provider.cpp +++ b/src/manager/service/key-provider.cpp @@ -56,7 +56,7 @@ void WrappedKeyAndInfoContainer::setKeyInfoLabel(const std::string label) strncpy( wrappedKeyAndInfo->keyInfo.label, label.c_str(), - MAX_LABEL_SIZE); + MAX_LABEL_SIZE-1); } void WrappedKeyAndInfoContainer::setKeyInfoSalt(const unsigned char *salt, -- 2.7.4 From ee31296a3cf4c9ef4d77298d781761e3bff5d279 Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Wed, 18 Apr 2018 13:25:37 +0200 Subject: [PATCH 08/16] Disable default build with tz-backend Migration to VD causes build breaks because of missing optee dependency. Relation between key-manager and key-manager-ta needs to be re-worked. For now it will be disabled. Change-Id: I5312db283e3514d7c54dfa7caffd6738b5568e2f --- CMakeLists.txt | 4 ++++ packaging/key-manager.spec | 9 ++++++++- src/CMakeLists.txt | 28 ++++++++++++++++++++++----- src/manager/crypto/platform/decider.cpp | 16 ++++++++++++++-- tests/CMakeLists.txt | 31 +++++++++++++++++++++++------- tools/ckm_db_tool/CMakeLists.txt | 34 ++++++++++++++++++++++++++------- 6 files changed, 100 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d345f01..64aa088 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,10 @@ ADD_DEFINITIONS("-DINITIAL_VALUES_DIR=\"${INITIAL_VALUES_DIR}\"") ADD_DEFINITIONS("-DCA_CERTS_DIR=\"${CA_CERTS_DIR}\"") ADD_DEFINITIONS("-DSYSTEMD_ENV_FILE=\"${SYSTEMD_ENV_FILE}\"") +IF (TZ_BACKEND_ENABLED) + ADD_DEFINITIONS("-DTZ_BACKEND_ENABLED") +ENDIF() + IF (DEFINED WATCHDOG_ENABLED) MESSAGE("WATCHDOG ENABELD!") ADD_DEFINITIONS("-DWATCHDOG_ENABLED") diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec index d953b27..fe470a7 100644 --- a/packaging/key-manager.spec +++ b/packaging/key-manager.spec @@ -1,6 +1,7 @@ %global watchdog_enabled 1 %global watchdog_timeout_sec 60 %global watchdog_notify_sec 20 +%global tz_backend_enabled 0 Name: key-manager Summary: Central Key Manager and utilities @@ -35,10 +36,11 @@ BuildRequires: pkgconfig(argos_watchdog) %endif BuildRequires: boost-devel BuildRequires: ca-certificates-devel +%if %{tz_backend_enabled} == 1 BuildRequires: key-manager-ta-devel BuildRequires: key-manager-ta-serialization-devel BuildRequires: pkgconfig(tef-libteec) -#Requires(pre): tizen-platform-config-tools +%endif Requires: libkey-manager-common = %{version}-%{release} %{?systemd_requires} @@ -164,6 +166,11 @@ export LDFLAGS+="-Wl,--rpath=%{_libdir},-Bsymbolic-functions " -DWATCHDOG_TIMEOUT_SEC=%{watchdog_timeout_sec} \ -DWATCHDOG_NOTIFY_SEC=%{watchdog_notify_sec} \ %endif +%if %{tz_backend_enabled} == 1 + -DTZ_BACKEND_ENABLED=ON \ +%else + -DTZ_BACKEND_ENABLED=OFF \ +%endif -DTEST_DIR=%{test_dir} make %{?jobs:-j%jobs} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 04e4d52..a4943c8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,6 +4,13 @@ ELSE (DEFINED WATCHDOG_ENABLED) SET(EXTRA_KM_DEPS) ENDIF (DEFINED WATCHDOG_ENABLED) +IF (TZ_BACKEND_ENABLED) +SET(EXTRA_KM_DEPS + ${EXTRA_KM_DEPS} + tef-libteec + ) +ENDIF() + PKG_CHECK_MODULES(KEY_MANAGER_DEP REQUIRED dlog @@ -19,7 +26,6 @@ PKG_CHECK_MODULES(KEY_MANAGER_DEP cynara-creds-socket pkgmgr vconf - tef-libteec ${EXTRA_KM_DEPS} ) FIND_PACKAGE(Threads REQUIRED) @@ -75,14 +81,20 @@ SET(KEY_MANAGER_SOURCES ${KEY_MANAGER_PATH}/crypto/sw-backend/internals.cpp ${KEY_MANAGER_PATH}/crypto/sw-backend/store.cpp ${KEY_MANAGER_PATH}/crypto/platform/decider.cpp + ${SECURITY_MANAGER_WRAPPER_PATH} + ${CYNARA_WRAPPER_PATH} + ) + +IF(TZ_BACKEND_ENABLED) +SET(KEY_MANAGER_SOURCES + ${KEY_MANAGER_SOURCES} ${KEY_MANAGER_PATH}/crypto/tz-backend/obj.cpp ${KEY_MANAGER_PATH}/crypto/tz-backend/store.cpp ${KEY_MANAGER_PATH}/crypto/tz-backend/internals.cpp ${KEY_MANAGER_PATH}/crypto/tz-backend/tz-context.cpp ${KEY_MANAGER_PATH}/crypto/tz-backend/tz-memory.cpp - ${SECURITY_MANAGER_WRAPPER_PATH} - ${CYNARA_WRAPPER_PATH} ) +ENDIF() SET_SOURCE_FILES_PROPERTIES( ${KEY_MANAGER_SOURCES} @@ -110,14 +122,20 @@ LINK_DIRECTORIES(${KEY_MANAGER_DEP_LIBRARY_DIRS}) ADD_EXECUTABLE(${TARGET_KEY_MANAGER} ${KEY_MANAGER_SOURCES}) +IF(TZ_BACKEND_ENABLED) +SET(KM_LINK_EXTRA_DEPS + ${KM_LINK_EXTRA_DEPS} + km_serialization + ) +ENDIF() + TARGET_LINK_LIBRARIES(${TARGET_KEY_MANAGER} ${CMAKE_THREAD_LIBS_INIT} ${KEY_MANAGER_DEP_LIBRARIES} ${TARGET_KEY_MANAGER_COMMON} + ${KM_LINK_EXTRA_DEPS} -ldl - km_serialization ) - ################################################################################ SET(KEY_MANAGER_CLIENT_VERSION_MAJOR 1) diff --git a/src/manager/crypto/platform/decider.cpp b/src/manager/crypto/platform/decider.cpp index 2a93729..a2f16e2 100644 --- a/src/manager/crypto/platform/decider.cpp +++ b/src/manager/crypto/platform/decider.cpp @@ -27,11 +27,14 @@ #include #include + +#ifdef TZ_BACKEND_ENABLED #include #include #include #include +#endif // TZ_BACKEND_ENABLED #include #include @@ -57,6 +60,7 @@ CryptoBackend chooseCryptoBackend(DataType data, const Policy &policy, bool encrypted) { +#ifdef TZ_BACKEND_ENABLED // user directly point proper backend - we will not discuss with it if (policy.backend == CKM::PolicyBackend::FORCE_SOFTWARE) return CryptoBackend::OpenSSL; @@ -91,13 +95,21 @@ CryptoBackend chooseCryptoBackend(DataType data, LogDebug("...succeeded. Selecting TZ backend."); return CryptoBackend::TrustZone; +#else // TZ_BACKEND_ENABLED + (void) data; + (void) policy; + (void) encrypted; + return CryptoBackend::OpenSSL; +#endif // TZ_BACKEND_ENABLED } } // namespace Decider::Decider() : m_swStore(new SW::Store(CryptoBackend::OpenSSL)) +#ifdef TZ_BACKEND_ENABLED , m_tzStore(new TZ::Store(CryptoBackend::TrustZone)) +#endif { } @@ -112,10 +124,10 @@ GStore &Decider::getStore(CryptoBackend cryptoBackend) const if (cryptoBackend == CryptoBackend::OpenSSL) gStore = m_swStore.get(); - +#ifdef TZ_BACKEND_ENABLED if (cryptoBackend == CryptoBackend::TrustZone) gStore = m_tzStore.get(); - +#endif if (gStore) return *gStore; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e90d8d7..7af494c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -68,7 +68,6 @@ SET(TEST_MERGED_SOURCES ${KEY_MANAGER_TEST_MERGED_SRC}/test_stringify.cpp ${KEY_MANAGER_TEST_MERGED_SRC}/test_ss-crypto.cpp ${KEY_MANAGER_TEST_MERGED_SRC}/test_sw-backend.cpp - ${KEY_MANAGER_TEST_MERGED_SRC}/test_tz-backend.cpp ${KEY_MANAGER_TEST_MERGED_SRC}/test_xml-parser.cpp # duplicated srcs to test hidden symbols @@ -77,11 +76,6 @@ SET(TEST_MERGED_SOURCES ${KEY_MANAGER_PATH}/crypto/sw-backend/internals.cpp ${KEY_MANAGER_PATH}/crypto/sw-backend/obj.cpp ${KEY_MANAGER_PATH}/crypto/sw-backend/store.cpp - ${KEY_MANAGER_PATH}/crypto/tz-backend/obj.cpp - ${KEY_MANAGER_PATH}/crypto/tz-backend/store.cpp - ${KEY_MANAGER_PATH}/crypto/tz-backend/internals.cpp - ${KEY_MANAGER_PATH}/crypto/tz-backend/tz-context.cpp - ${KEY_MANAGER_PATH}/crypto/tz-backend/tz-memory.cpp ${KEY_MANAGER_PATH}/dpl/core/src/assert.cpp ${KEY_MANAGER_PATH}/dpl/core/src/colors.cpp ${KEY_MANAGER_PATH}/dpl/core/src/errno_string.cpp @@ -102,17 +96,40 @@ SET(TEST_MERGED_SOURCES ${KEY_MANAGER_PATH}/service/ss-crypto.cpp ) +IF(TZ_BACKEND_ENABLED) +SET(TEST_MERGED_SOURCES + ${TEST_MERGED_SOURCES} + ${KEY_MANAGER_TEST_MERGED_SRC}/test_tz-backend.cpp + + # duplicated srcs to test hidden symbols + ${KEY_MANAGER_PATH}/crypto/tz-backend/obj.cpp + ${KEY_MANAGER_PATH}/crypto/tz-backend/store.cpp + ${KEY_MANAGER_PATH}/crypto/tz-backend/internals.cpp + ${KEY_MANAGER_PATH}/crypto/tz-backend/tz-context.cpp + ${KEY_MANAGER_PATH}/crypto/tz-backend/tz-memory.cpp + ) +ENDIF() + LINK_DIRECTORIES(${KEY_MANAGER_DEP_LIBRARY_DIRS}) ADD_EXECUTABLE(${TARGET_TEST_MERGED} ${TEST_MERGED_SOURCES}) + +IF(TZ_BACKEND_ENABLED) +SET(TEST_LINK_EXTRA_DEPS + ${TEST_LINK_EXTRA_DEPS} + teec + km_serialization + ) +ENDIF() + TARGET_LINK_LIBRARIES(${TARGET_TEST_MERGED} ${TARGET_KEY_MANAGER_COMMON} ${CMAKE_THREAD_LIBS_INIT} ${KEY_MANAGER_DEP_LIBRARIES} ${TARGET_ENCRYPTION_SCHEME_COMMON} + ${TEST_LINK_EXTRA_DEPS} boost_unit_test_framework - teec km_serialization -ldl ) diff --git a/tools/ckm_db_tool/CMakeLists.txt b/tools/ckm_db_tool/CMakeLists.txt index 6524712..7b78c1a 100644 --- a/tools/ckm_db_tool/CMakeLists.txt +++ b/tools/ckm_db_tool/CMakeLists.txt @@ -1,6 +1,12 @@ SET(CKM_DB_TOOL "ckm_db_tool") SET(KEY_MANAGER_PATH ${PROJECT_SOURCE_DIR}/src/manager) +IF (TZ_BACKEND_ENABLED) +SET(CKM_DB_TOOL_EXTRA_DEP + tef-libteec + ) +ENDIF() + PKG_CHECK_MODULES(CKM_DB_TOOL_DEP REQUIRED openssl @@ -11,7 +17,7 @@ PKG_CHECK_MODULES(CKM_DB_TOOL_DEP cynara-client-async cynara-creds-socket security-manager - tef-libteec + ${CKM_DB_TOOL_EXTRA_DEP} ) FIND_PACKAGE(Threads REQUIRED) @@ -38,11 +44,6 @@ SET(CKM_DB_TOOL_SOURCES ${KEY_MANAGER_PATH}/crypto/sw-backend/internals.cpp ${KEY_MANAGER_PATH}/crypto/sw-backend/obj.cpp ${KEY_MANAGER_PATH}/crypto/sw-backend/store.cpp - ${KEY_MANAGER_PATH}/crypto/tz-backend/internals.cpp - ${KEY_MANAGER_PATH}/crypto/tz-backend/obj.cpp - ${KEY_MANAGER_PATH}/crypto/tz-backend/store.cpp - ${KEY_MANAGER_PATH}/crypto/tz-backend/tz-context.cpp - ${KEY_MANAGER_PATH}/crypto/tz-backend/tz-memory.cpp ${KEY_MANAGER_PATH}/dpl/core/src/assert.cpp ${KEY_MANAGER_PATH}/dpl/db/src/naive_synchronization_object.cpp ${KEY_MANAGER_PATH}/dpl/db/src/sql_connection.cpp @@ -78,15 +79,34 @@ SET(CKM_DB_TOOL_SOURCES ${KEY_MANAGER_PATH}/sqlcipher/sqlcipher.c ) +IF(TZ_BACKEND_ENABLED) +SET(CKM_DB_TOOL_SOURCES + ${CKM_DB_TOOL_SOURCES} + ${KEY_MANAGER_PATH}/crypto/tz-backend/internals.cpp + ${KEY_MANAGER_PATH}/crypto/tz-backend/obj.cpp + ${KEY_MANAGER_PATH}/crypto/tz-backend/store.cpp + ${KEY_MANAGER_PATH}/crypto/tz-backend/tz-context.cpp + ${KEY_MANAGER_PATH}/crypto/tz-backend/tz-memory.cpp + ) +ENDIF() + LINK_DIRECTORIES(${CKM_DB_TOOL_DEP_LIBRARY_DIRS}) ADD_EXECUTABLE( ${CKM_DB_TOOL} ${CKM_DB_TOOL_SOURCES} ) +IF(TZ_BACKEND_ENABLED) +SET(CKM_DB_TOOL_LINK_EXTRA_DEPS + ${CKM_DB_TOOL_LINK_EXTRA_DEPS} + teec + km_serialization + ) +ENDIF() + TARGET_LINK_LIBRARIES(${CKM_DB_TOOL} ${CMAKE_THREAD_LIBS_INIT} ${CKM_DB_TOOL_DEP_LIBRARIES} ${TARGET_KEY_MANAGER_COMMON} - teec km_serialization + ${CKM_DB_TOOL_LINK_EXTRA_DEPS} -ldl ) -- 2.7.4 From 93e4c829856c82b083d51dede0211fa486047fce Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Tue, 8 May 2018 13:56:48 +0900 Subject: [PATCH 09/16] Fix coverity defect - 120541 : improper use of nagative value Change-Id: Ic93d890a08def810a8f09ed6bbb8171e440438df Signed-off-by: Dongsun Lee --- src/manager/common/openssl-error-handler.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/manager/common/openssl-error-handler.cpp b/src/manager/common/openssl-error-handler.cpp index cac3834..40c3d2b 100644 --- a/src/manager/common/openssl-error-handler.cpp +++ b/src/manager/common/openssl-error-handler.cpp @@ -60,9 +60,14 @@ void errorDump() BIO *bio = BIO_new(BIO_s_mem()); ERR_print_errors(bio); char *buf = NULL; - size_t len = BIO_get_mem_data(bio, &buf); + long len = BIO_get_mem_data(bio, &buf); + if(len < 0) { + LogError("Fail in BIO_get_mem_data()"); + return; + } + size_t length = static_cast(len); BIO_free(bio); - std::string ret(buf, len); + std::string ret(buf, length); free(buf); LogError(ret); } @@ -190,4 +195,4 @@ void errorHandle(const char *file, int line, const char *function, int openssl_r } -} // namespace CKM \ No newline at end of file +} // namespace CKM -- 2.7.4 From ac4e965a376dfdd05fcc4cc1661f74bffac2aea4 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 6 Jul 2018 15:13:50 +0200 Subject: [PATCH 10/16] Make key-manager build with boost 1.65 Add dummy implementation of newly added abstract methods. Change-Id: If491af391431a769a2e84360425852a53be25f16 --- tests/colour_log_formatter.cpp | 14 ++++++++++++++ tests/colour_log_formatter.h | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/tests/colour_log_formatter.cpp b/tests/colour_log_formatter.cpp index 8a112a2..81e9938 100644 --- a/tests/colour_log_formatter.cpp +++ b/tests/colour_log_formatter.cpp @@ -317,11 +317,25 @@ colour_log_formatter::log_entry_context(std::ostream& os, boost::unit_test::cons (void)os; (void)value; } + +void +colour_log_formatter::log_entry_context(std::ostream&, + boost::unit_test::log_level, + boost::unit_test::const_string) +{ +} + void colour_log_formatter::entry_context_finish(std::ostream& os) { (void)os; } + +void +colour_log_formatter::entry_context_finish(std::ostream&, + boost::unit_test::log_level) +{ +} //____________________________________________________________________________// //____________________________________________________________________________// diff --git a/tests/colour_log_formatter.h b/tests/colour_log_formatter.h index d165004..233edc3 100644 --- a/tests/colour_log_formatter.h +++ b/tests/colour_log_formatter.h @@ -62,7 +62,12 @@ public: void log_entry_context( std::ostream& os, boost::unit_test::const_string value); + void log_entry_context( + std::ostream& os, + boost::unit_test::log_level l, + boost::unit_test::const_string value); void entry_context_finish(std::ostream& os); + void entry_context_finish(std::ostream& os, boost::unit_test::log_level l); private: bool m_isTestCaseFailed; }; -- 2.7.4 From 3f269161226259db05411999e54b6f3ea33bda53 Mon Sep 17 00:00:00 2001 From: Bartlomiej Grzelewski Date: Wed, 2 Aug 2017 14:21:44 +0200 Subject: [PATCH 11/16] Test version of ckm_db_merge ckm_db_merge allows to read database and copy it's contents to other one. ckm_db_merge supports db since versions 0.1.14. Please note: both databases will be automatically migrated to the newest schema. Change-Id: I5cec9dfdc2ab75a2ccd5156b0bb05cb46d134480 --- packaging/key-manager.spec | 1 + src/manager/service/db-crypto.h | 6 +- tools/ckm_db_tool/CMakeLists.txt | 23 +++- tools/ckm_db_tool/ckm-logic-ext.cpp | 32 ++++-- tools/ckm_db_tool/ckm-logic-ext.h | 4 +- tools/ckm_db_tool/ckm_db_merge.cpp | 193 +++++++++++++++++++++++++++++++ tools/ckm_db_tool/ckm_db_tool.cpp | 221 ++++++++++-------------------------- tools/ckm_db_tool/db-crypto-ext.cpp | 30 ++++- tools/ckm_db_tool/db-crypto-ext.h | 3 +- tools/ckm_db_tool/db-wrapper.cpp | 138 ++++++++++++++++++++++ tools/ckm_db_tool/db-wrapper.h | 55 +++++++++ 11 files changed, 520 insertions(+), 186 deletions(-) create mode 100644 tools/ckm_db_tool/ckm_db_merge.cpp create mode 100644 tools/ckm_db_tool/db-wrapper.cpp create mode 100644 tools/ckm_db_tool/db-wrapper.h diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec index fe470a7..aead73a 100644 --- a/packaging/key-manager.spec +++ b/packaging/key-manager.spec @@ -322,5 +322,6 @@ fi %{bin_dir}/ckm-tests-internal %{bin_dir}/ckm_so_loader %{bin_dir}/ckm_db_tool +%{bin_dir}/ckm_db_merge %{bin_dir}/ckm_generate_db %test_dir diff --git a/src/manager/service/db-crypto.h b/src/manager/service/db-crypto.h index 3fbacf6..f4021c3 100644 --- a/src/manager/service/db-crypto.h +++ b/src/manager/service/db-crypto.h @@ -200,6 +200,9 @@ public: protected: SqlConnection *m_connection; + Row getRow( + const SqlConnection::DataCommandUniquePtr &selectCommand) const; + private: bool m_inUserTransaction; @@ -219,9 +222,6 @@ private: ScriptOptional getScript(const std::string &scriptName) const; ScriptOptional getMigrationScript(int db_version) const; - Row getRow( - const SqlConnection::DataCommandUniquePtr &selectCommand) const; - void createTable( const char *create_cmd, const char *table_name); diff --git a/tools/ckm_db_tool/CMakeLists.txt b/tools/ckm_db_tool/CMakeLists.txt index 7b78c1a..4a47a1d 100644 --- a/tools/ckm_db_tool/CMakeLists.txt +++ b/tools/ckm_db_tool/CMakeLists.txt @@ -1,4 +1,5 @@ SET(CKM_DB_TOOL "ckm_db_tool") +SET(CKM_DB_MERGE "ckm_db_merge") SET(KEY_MANAGER_PATH ${PROJECT_SOURCE_DIR}/src/manager) IF (TZ_BACKEND_ENABLED) @@ -36,10 +37,10 @@ INCLUDE_DIRECTORIES( ${KEY_MANAGER_PATH}/crypto ) -SET(CKM_DB_TOOL_SOURCES - ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/ckm_db_tool.cpp +SET(CKM_DB_TOOLS_SOURCES ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/db-crypto-ext.cpp ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/ckm-logic-ext.cpp + ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/db-wrapper.cpp ${KEY_MANAGER_PATH}/crypto/platform/decider.cpp ${KEY_MANAGER_PATH}/crypto/sw-backend/internals.cpp ${KEY_MANAGER_PATH}/crypto/sw-backend/obj.cpp @@ -80,8 +81,8 @@ SET(CKM_DB_TOOL_SOURCES ) IF(TZ_BACKEND_ENABLED) -SET(CKM_DB_TOOL_SOURCES - ${CKM_DB_TOOL_SOURCES} +SET(CKM_DB_TOOLS_SOURCES + ${CKM_DB_TOOLS_SOURCES} ${KEY_MANAGER_PATH}/crypto/tz-backend/internals.cpp ${KEY_MANAGER_PATH}/crypto/tz-backend/obj.cpp ${KEY_MANAGER_PATH}/crypto/tz-backend/store.cpp @@ -92,7 +93,7 @@ ENDIF() LINK_DIRECTORIES(${CKM_DB_TOOL_DEP_LIBRARY_DIRS}) -ADD_EXECUTABLE( ${CKM_DB_TOOL} ${CKM_DB_TOOL_SOURCES} ) +ADD_EXECUTABLE(${CKM_DB_TOOL} ${CKM_DB_TOOLS_SOURCES} ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/ckm_db_tool.cpp) IF(TZ_BACKEND_ENABLED) SET(CKM_DB_TOOL_LINK_EXTRA_DEPS @@ -110,8 +111,18 @@ TARGET_LINK_LIBRARIES(${CKM_DB_TOOL} -ldl ) +ADD_EXECUTABLE(${CKM_DB_MERGE} ${CKM_DB_TOOLS_SOURCES} ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/ckm_db_merge.cpp) + +TARGET_LINK_LIBRARIES(${CKM_DB_MERGE} + ${CMAKE_THREAD_LIBS_INIT} + ${CKM_DB_TOOL_DEP_LIBRARIES} + ${TARGET_KEY_MANAGER_COMMON} + ${CKM_DB_TOOL_LINK_EXTRA_DEPS} + -ldl + ) + #place for output file -INSTALL(TARGETS ${CKM_DB_TOOL} +INSTALL(TARGETS ${CKM_DB_TOOL} ${CKM_DB_MERGE} DESTINATION ${BIN_DIR} PERMISSIONS OWNER_READ OWNER_WRITE diff --git a/tools/ckm_db_tool/ckm-logic-ext.cpp b/tools/ckm_db_tool/ckm-logic-ext.cpp index a82b5db..6d64fc4 100644 --- a/tools/ckm_db_tool/ckm-logic-ext.cpp +++ b/tools/ckm_db_tool/ckm-logic-ext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2017 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. @@ -27,15 +27,6 @@ namespace CKM { DB::SqlConnection::Output CKMLogicExt::Execute(uid_t user, const std::string &cmd) { - if (user < 5000 && !m_systemDbUnlocked) { - if (CKM_API_SUCCESS != unlockSystemDB()) - ThrowErr(Exc::DatabaseLocked, "can not unlock system database"); - - m_systemDbUnlocked = true; - } - - DB::SqlConnection::Output output; - /* * We need to access to DB::Crypto::m_connection to call Execute() on it. We don't want to mess * with DB::Crypto too much so adding a friend and extending public interface was not an option. @@ -47,7 +38,7 @@ DB::SqlConnection::Output CKMLogicExt::Execute(uid_t user, DB::CryptoExt db(std::move(m_userDataMap[user].database)); try { - output = db.Execute(cmd); + DB::SqlConnection::Output output = db.Execute(cmd); m_userDataMap[user].database = std::move(*static_cast(&db)); return output; } catch (const DB::SqlConnection::Exception::Base &e) { @@ -56,6 +47,25 @@ DB::SqlConnection::Output CKMLogicExt::Execute(uid_t user, } } +DB::RowVector CKMLogicExt::getRows(uid_t user) +{ + DB::CryptoExt db(std::move(m_userDataMap[user].database)); + + try { + DB::RowVector output = db.getRows(); + m_userDataMap[user].database = std::move(*static_cast(&db)); + return output; + } catch (const DB::SqlConnection::Exception::Base &e) { + m_userDataMap[user].database = std::move(*static_cast(&db)); + throw; + } +} + +void CKMLogicExt::saveRow(uid_t user, const DB::Row &row) +{ + m_userDataMap[user].database.saveRow(row); +} + } // namespace CKM diff --git a/tools/ckm_db_tool/ckm-logic-ext.h b/tools/ckm_db_tool/ckm-logic-ext.h index ca6916f..c988179 100644 --- a/tools/ckm_db_tool/ckm-logic-ext.h +++ b/tools/ckm_db_tool/ckm-logic-ext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2017 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. @@ -30,6 +30,8 @@ struct CKMLogicExt : public CKMLogic { CKMLogicExt() : m_systemDbUnlocked(false) {} DB::SqlConnection::Output Execute(uid_t user, const std::string &cmd); + DB::RowVector getRows(uid_t user); + void saveRow(uid_t user, const DB::Row &row); private: bool m_systemDbUnlocked; diff --git a/tools/ckm_db_tool/ckm_db_merge.cpp b/tools/ckm_db_tool/ckm_db_merge.cpp new file mode 100644 index 0000000..17e308c --- /dev/null +++ b/tools/ckm_db_tool/ckm_db_merge.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2000 - 2017 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 ckm_db_merge.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +using namespace std; +using namespace CKM; + +typedef function RowFilter; +typedef vector RowFilterVector; + +bool printRow(const DB::Row &row) { + string iv(10, ' '), data(10, ' '); + for (std::size_t i=0; i < iv.size(); ++i) { + if (row.iv.size() > i) iv[i] = row.iv[i]; + if (row.data.size() > i) data[i] = row.data[i]; + } + cout << "Read row:"; + cout << "\n Name: " << row.name; + cout << "\n Owner: " << row.ownerLabel; + cout << "\n Exportable: " << row.exportable; + cout << "\n Alg type: " << static_cast(row.algorithmType); + cout << "\n Enc schema: " << row.encryptionScheme; + cout << "\n Data size: " << row.dataSize; + cout << "\n BackendId: " << static_cast(row.backendId); + cout << "\n Data(first 10 chars): " << data; + cout << "\n IV(first 10 chars): " << iv; + cout << "\n"; + return true; +} + +void printUsage() +{ + cout << "Usage: ckm_db_merge [OPTION]\n"; + cout << "Copy data from one key-manager database into other one.\n"; + cout << "Options:\n"; + cout << " -v, --verbose print additional data on screen\n"; + cout << " -s, --source UID database UID from were data will be readed - default value 0\n"; + cout << " -t, --target UID database UID to were data will be writen - default value 0\n"; + cout << " -p, --spass PASSWORD password for source database - default empty string\n"; + cout << " -r, --tpass PASSWORD password for target database - default emtpy string\n"; + cout << " -o, --owner OWNER change the owner of information in database to OWNER\n"; + cout << " -h, --help print this help on screen\n"; + cout << "Example: Copy data from db-5001 to db-0 (system database) and change object owner to /System\n"; + cout << " ckm_db_merge -s 5001 -t 0 -p !@#SDFCV -o \"/System\"\n"; + cout << "Please note: This tool automatically updates databases to newest scheme!" << endl; +} + +int mergeDatabase( + uid_t uid1, + const Password &pass1, + uid_t uid2, + const Password &pass2, + const RowFilterVector &filters) +{ + DbWrapper source(uid1, pass1); + DbWrapper target(uid2, pass2); + + int ret; + + if (CKM_API_SUCCESS != (ret = source.unlock())) { // this should migrate database to newest version + cerr << "Unlocking source database failed: " << ret << endl; + return 1; + } + if (CKM_API_SUCCESS != (ret = target.unlock())) { // this should migrate database to newest version + cerr << "Unlocking target database failed: " << ret << endl; + return 1; + } + + DB::RowVector data = source.getRows(); + + // apply all filters to each row + for (auto &e : data) { + bool migrate = true; + for (auto &f : filters) { + migrate &= f(e); + } + if (migrate) { + try { + target.saveRow(e); + } catch (const CKM::DB::SqlConnection::Exception::Base &e) { + cerr << "Sql exception. Migration failed or object already exist in database: " << e.DumpToString() << endl; + } + } + } + + source.lock(); + target.lock(); + return 0; +} + +int main(int argc, char *argv[]) { + Password password1, password2; + uid_t uid1 = 0, uid2 = 0; + string owner; + RowFilterVector filters; + try { + while (1) { + int option_index = 0; + + static struct option long_options[] = { + {"verbose", no_argument, 0, 'v'}, + {"source", required_argument, 0, 's'}, + {"target", required_argument, 0, 't'}, + {"spass", required_argument, 0, 'p'}, + {"tpass", required_argument, 0, 'r'}, + {"owner", required_argument, 0, 'o'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0 } + }; + int c = getopt_long(argc, argv, "vs:t:p:r:o:h", long_options, &option_index); + + if (-1 == c) + break; + + switch (c) { + case 'v': + filters.push_back(printRow); + break; + case 's': + uid1 = stoi(optarg); + break; + case 't': + uid2 = stoi(optarg); + break; + case 'p': + password1 = optarg; + break; + case 'r': + password2 = optarg; + break; + case 'o': + owner = optarg; // I cannot pass optarg to lambda because it's pointer + filters.push_back([=](DB::Row &row) {row.ownerLabel = owner; return true;}); + break; + case 'h': + printUsage(); + return 0; + case '?': + case ':': + default: + printUsage(); + return 1; + } + } + + if (uid1 == uid2) { + cerr << "Source database and target database must be different!" << endl; + return 1; + } + + return mergeDatabase(uid1, password1, uid2, password2, filters); + } catch (const CKM::DB::SqlConnection::Exception::InvalidColumn &e) { + cerr << "Invalid Column exception was catched. Probably migration failed. " << e.DumpToString() << endl; + } catch (const invalid_argument &e) { + cerr << "Argument could not be converted" << endl; + } catch (const out_of_range &e) { + cerr << "Out of range" << endl; + } catch (const exception &e) { + cerr << "Unexpected error: " << e.what() << endl; + } catch (...) { + cerr << "Unknown exception" << endl; + } + + return 1; +} diff --git a/tools/ckm_db_tool/ckm_db_tool.cpp b/tools/ckm_db_tool/ckm_db_tool.cpp index 672cd86..2435ee3 100644 --- a/tools/ckm_db_tool/ckm_db_tool.cpp +++ b/tools/ckm_db_tool/ckm_db_tool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2017 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. @@ -23,147 +23,29 @@ #include #include -#include +#include +#include -#include -#include -#include -#include -#include +#include using namespace std; using namespace CKM; -namespace { -const size_t MAX_LEN = 32; -const char ELLIPSIS[] = "..."; -const size_t ELLIPSIS_LEN = sizeof(ELLIPSIS) / sizeof(ELLIPSIS[0]); - -const char *const SQL_TABLES = "SELECT name FROM sqlcipher_master " - "WHERE type IN ('table','view') AND name NOT LIKE 'sqlcipher_%' " - "UNION ALL " - "SELECT name FROM sqlcipher_temp_master " - "WHERE type IN ('table','view') " - "ORDER BY 1"; - -const char *const SQL_SCHEMA = "SELECT sql FROM " - "(SELECT * FROM sqlcipher_master " - "UNION ALL " - "SELECT * FROM sqlcipher_temp_master) " - "WHERE type!='meta' AND sql!='NULL'" - "ORDER BY tbl_name, type DESC, name"; -} // namespace anonymous - -class DbWrapper { -public: - DbWrapper(uid_t uid, Password pw) : m_uid(uid), m_pw(pw) {} - - int unlock(); - void lock(); - void process(const string &cmd); - -private: - void displayRow(const DB::SqlConnection::Output::Row &row, bool trim); - - uid_t m_uid; - Password m_pw; - CKMLogicExt m_logic; -}; - -int DbWrapper::unlock() -{ - // no unlock for system db - if (m_uid < 5000) - return CKM_API_SUCCESS; - - int retCode; - RawBuffer ret = m_logic.unlockUserKey(m_uid, m_pw); - MessageBuffer buff; - buff.Push(ret); - buff.Deserialize(retCode); - return retCode; -} - -void DbWrapper::lock() -{ - // no lock for system db - if (m_uid < 5000) - return; - - m_logic.lockUserKey(m_uid); -} - -void DbWrapper::process(const string &acmd) -{ - try { - string cmd = acmd; - bool trim = true; - - if (acmd == ".tables") { - cmd = SQL_TABLES; - trim = false; - } else if (acmd == ".schema") { - cmd = SQL_SCHEMA; - trim = false; - } - - DB::SqlConnection::Output output = m_logic.Execute(m_uid, cmd); - - if (output.GetNames().empty()) - return; - - displayRow(output.GetNames(), trim); - cout << "--------------------------" << endl; - - for (const auto &row : output.GetValues()) { - displayRow(row, trim); - } - } catch (const DB::SqlConnection::Exception::Base &e) { - cerr << e.GetMessage() << endl; - } catch (const Exc::Exception &e) { - cerr << e.message() << endl; - } catch (const std::exception &e) { - cerr << e.what() << endl; - } catch (...) { - cerr << "Unexpected exception occurred" << endl; - } -} - -void DbWrapper::displayRow(const DB::SqlConnection::Output::Row &row, bool trim) -{ - for (auto it = row.begin(); it != row.end(); it++) { - std::string col = *it; - - if (trim && col.size() > MAX_LEN) { - col.resize(MAX_LEN); - col.replace(MAX_LEN - ELLIPSIS_LEN, ELLIPSIS_LEN, ELLIPSIS); - } - - cout << col; - - if (it + 1 != row.end()) - cout << "|"; - } - - cout << endl; -} - void usage() { - cout << "ckm_db_tool - the command line tool for accessing key-manager encrypted databases." - << endl; - cout << endl; - cout << "Usage: ckm_db_tool uid [password] [sql_command]" << endl; - cout << endl; - cout << "uid (mandatory) User id as in /ckm/db-" << - endl; - cout << "password (optional) Password used for database encryption. For system database (uid < 5000) no password should be used." - << endl; - cout << "sql_command (optional) Sqlite3 command to execute on database. If empty the tool will enter interactive mode." - << endl; - cout << endl; - cout << "Example:" << endl; - cout << "cmd_db_tool 5000 user-pass \"select * from names\"" << endl; + cout << "Usage: ckm_db_tool [OPTION]\n"; + cout << "The command line tool for accessing key-manager encrypted databases.\n"; + cout << "Options:\n"; + cout << " -u, --uid UID User id as in /ckm/db- - default value 0\n"; + cout << " -p, --pass PASSWORD Password used for database encryption. For system database (uid < 5000) no password should be used.\n"; + cout << " -c, --cmd SQLCOMMAND Sqlite3 command to execute on database. If command not provided tool will enter interactive mode.\n"; + cout << " -h, --help Shows this help.\n"; + cout << "Example: Open database for user 5000 and select all data from table names\n"; + cout << " cmd_db_tool -u 5000 -p P45W0RD \"select * from names\"\n"; + cout << "Example: Open database for user 5001 in interactive mode\n"; + cout << " cmd_db_tool -uid 5001 -p user-strong-password\n"; + cout << "Example: Open database for user 0 in interactive mode\n"; + cout << " cmd_db_tool" << endl; } void internalHelp() @@ -179,43 +61,49 @@ void internalHelp() int main(int argc, char *argv[]) { try { - if (argc < 2 || !argv[1]) { - usage(); - return -1; - } - - // read uid - stringstream ss(argv[1]); - uid_t uid; + uid_t uid = 0; + Password pass; + std::string argcmd; + while(1) { + int option_index = 0; - if (!(ss >> uid)) { - usage(); - return -1; - } + static struct option long_options[] = { + {"uid", required_argument, 0, 'u'}, + {"cmd", required_argument, 0, 'c'}, + {"pass", required_argument, 0, 'p'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0 } + }; - int idx = 2; + int c = getopt_long(argc, argv, "u:c:p:h", long_options, &option_index); - // read password - Password pass; + if (-1 == c) + break; - if (uid >= 5000) { - if (argc > idx) { - pass = argv[idx]; - idx++; + switch (c) { + default: + case ':': + case '?': + case 'h': + usage(); + return 0; + case 'u': + uid = std::stoi(optarg); + break; + case 'c': + argcmd = optarg; + break; + case 'p': + pass = optarg; + break; } } - // read sqlite3 command - string argcmd; - - if (argc > idx) - argcmd = argv[idx]; - // unlock db DbWrapper dbw(uid, pass); - int retCode = dbw.unlock(); + int retCode; - if (retCode != CKM_API_SUCCESS) { + if (CKM_API_SUCCESS != (retCode = dbw.unlock())) { cerr << "Unlocking database failed: " << retCode << endl; return -1; } @@ -254,8 +142,15 @@ int main(int argc, char *argv[]) cout << "Database locked" << endl; return 0; + } catch (const std::invalid_argument &e) { + cerr << "Argument could not be converted" << endl; + } catch (const std::out_of_range &e) { + cerr << "Out of range" << endl; + } catch (const std::exception &e) { + cerr << "Exception: " << e.what() << endl; } catch (...) { cerr << "Unexpected exception occurred" << endl; - return -1; } + return -1; } + diff --git a/tools/ckm_db_tool/db-crypto-ext.cpp b/tools/ckm_db_tool/db-crypto-ext.cpp index 2667145..90d5a4f 100644 --- a/tools/ckm_db_tool/db-crypto-ext.cpp +++ b/tools/ckm_db_tool/db-crypto-ext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2017 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. @@ -26,6 +26,9 @@ namespace CKM { namespace DB { +const char *DB_CMD_OBJECT_SELECT = + "SELECT * FROM [join_name_object_tables];"; + SqlConnection::Output CryptoExt::Execute(const std::string &cmd) { SqlConnection::Output out; @@ -38,5 +41,30 @@ SqlConnection::Output CryptoExt::Execute(const std::string &cmd) m_connection->ExecCommand(&out, "%s", cmd.c_str()); return out; } + +RowVector CryptoExt::getRows() +{ + try { + RowVector output; + SqlConnection::DataCommandUniquePtr selectCommand = + m_connection->PrepareDataCommand(DB_CMD_OBJECT_SELECT); + + while (selectCommand->Step()) { + // extract data + output.push_back(getRow(selectCommand)); + } + + return output; + } catch (const SqlConnection::Exception::InvalidColumn &) { + LogError("Select statement invalid column error"); + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare select statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute select statement"); + } + + ThrowErr(Exc::DatabaseFailed, "Couldn't get row from database"); +} + } // namespace DB } // namespace CKM diff --git a/tools/ckm_db_tool/db-crypto-ext.h b/tools/ckm_db_tool/db-crypto-ext.h index 5991af1..bb1eb35 100644 --- a/tools/ckm_db_tool/db-crypto-ext.h +++ b/tools/ckm_db_tool/db-crypto-ext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015-2017 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. @@ -33,6 +33,7 @@ struct CryptoExt : public Crypto { CryptoExt(Crypto orig) : Crypto(std::move(orig)) {} SqlConnection::Output Execute(const std::string &cmd); + RowVector getRows(); }; } // namespace DB diff --git a/tools/ckm_db_tool/db-wrapper.cpp b/tools/ckm_db_tool/db-wrapper.cpp new file mode 100644 index 0000000..e7027db --- /dev/null +++ b/tools/ckm_db_tool/db-wrapper.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2000 - 2017 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 db-wrapper.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + */ +#include + +#include + +namespace { + +const size_t MAX_LEN = 32; +const char ELLIPSIS[] = "..."; +const size_t ELLIPSIS_LEN = sizeof(ELLIPSIS) / sizeof(ELLIPSIS[0]); + + +const char *const SQL_TABLES = "SELECT name FROM sqlcipher_master " + "WHERE type IN ('table','view') AND name NOT LIKE 'sqlcipher_%' " + "UNION ALL " + "SELECT name FROM sqlcipher_temp_master " + "WHERE type IN ('table','view') " + "ORDER BY 1"; + +const char *const SQL_SCHEMA = "SELECT sql FROM " + "(SELECT * FROM sqlcipher_master " + "UNION ALL " + "SELECT * FROM sqlcipher_temp_master) " + "WHERE type!='meta' AND sql!='NULL'" + "ORDER BY tbl_name, type DESC, name"; +} // anonymous namespace + +namespace CKM { + +int DbWrapper::unlock() +{ + // no unlock for system db + if (m_uid == 0 && m_pw.empty()) + return m_logic.unlockSystemDB(); + + int retCode; + RawBuffer ret = m_logic.unlockUserKey(m_uid, m_pw); + MessageBuffer buff; + buff.Push(ret); + buff.Deserialize(retCode); + return retCode; +} + +void DbWrapper::lock() +{ + // no lock for system db + if (m_uid < 5000) + return; + + m_logic.lockUserKey(m_uid); +} + +void DbWrapper::process(const std::string &acmd) +{ + try { + std::string cmd = acmd; + bool trim = true; + + if (acmd == ".tables") { + cmd = SQL_TABLES; + trim = false; + } else if (acmd == ".schema") { + cmd = SQL_SCHEMA; + trim = false; + } + + DB::SqlConnection::Output output = m_logic.Execute(m_uid, cmd); + + if (output.GetNames().empty()) + return; + + displayRow(output.GetNames(), trim); + std::cout << "--------------------------" << std::endl; + + for (const auto &row : output.GetValues()) { + displayRow(row, trim); + } + } catch (const DB::SqlConnection::Exception::Base &e) { + std::cerr << e.GetMessage() << std::endl; + } catch (const Exc::Exception &e) { + std::cerr << e.message() << std::endl; + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + } catch (...) { + std::cerr << "Unexpected exception occurred" << std::endl; + } +} + +void DbWrapper::displayRow(const DB::SqlConnection::Output::Row &row, bool trim) +{ + for (auto it = row.begin(); it != row.end(); it++) { + std::string col = *it; + + if (trim && col.size() > MAX_LEN) { + col.resize(MAX_LEN); + col.replace(MAX_LEN - ELLIPSIS_LEN, ELLIPSIS_LEN, ELLIPSIS); + } + + std::cout << col; + + if (it + 1 != row.end()) + std::cout << "|"; + } + + std::cout << std::endl; +} + +DB::RowVector DbWrapper::getRows() +{ + return m_logic.getRows(m_uid); +} + +void DbWrapper::saveRow(const DB::Row &row) +{ + return m_logic.saveRow(m_uid, row); +} + +} // namespace CKM diff --git a/tools/ckm_db_tool/db-wrapper.h b/tools/ckm_db_tool/db-wrapper.h new file mode 100644 index 0000000..2fa6653 --- /dev/null +++ b/tools/ckm_db_tool/db-wrapper.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2000 - 2017 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 db-wrapper.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + */ +#pragma once + +#include + +#include +#include +#include +#include +#include + +#include + +namespace CKM { + +class DbWrapper { +public: + DbWrapper(uid_t uid, Password pw) : m_uid(uid), m_pw(pw) {} + + int unlock(); + void lock(); + void process(const std::string &cmd); + DB::RowVector getRows(); + void saveRow(const DB::Row &row); + +private: + void displayRow(const DB::SqlConnection::Output::Row &row, bool trim); + + uid_t m_uid; + Password m_pw; + CKMLogicExt m_logic; +}; + +} // namespace CKM + -- 2.7.4 From 38a26555739c4da1a722437f48a9874c64a24201 Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Thu, 9 Aug 2018 12:53:46 +0900 Subject: [PATCH 12/16] Add RequiresMountsFor=/opt to central-key-manager.service. In order to apply User/Group to .service, we need /opt/etc/{passwd,group}. Signed-off-by: INSUN PYO Change-Id: I0ff03a7bc65565605ac43754349979b351c16796 --- systemd/central-key-manager.service.in | 1 + 1 file changed, 1 insertion(+) diff --git a/systemd/central-key-manager.service.in b/systemd/central-key-manager.service.in index bd9c130..3562f07 100644 --- a/systemd/central-key-manager.service.in +++ b/systemd/central-key-manager.service.in @@ -1,6 +1,7 @@ [Unit] Description=Start the Central Key Manager DefaultDependencies=no +RequiresMountsFor=/opt [Service] User=@USER_NAME@ -- 2.7.4 From d4ecf3ef0ffe3feaa6e5fb1373fdaa9395989a97 Mon Sep 17 00:00:00 2001 From: Pawel Kowalski Date: Thu, 16 Aug 2018 10:19:14 +0200 Subject: [PATCH 13/16] Add Apache 2.0 license headers Change-Id: Ia61efbc57ce93ed3714dafe9edada7cb244c54d3 --- src/manager/main/smack-check.cpp | 16 ++++++++++++++++ src/manager/service/key-provider.cpp | 16 ++++++++++++++++ src/manager/service/key-provider.h | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/manager/main/smack-check.cpp b/src/manager/main/smack-check.cpp index 70f71da..5e9344d 100644 --- a/src/manager/main/smack-check.cpp +++ b/src/manager/main/smack-check.cpp @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2014 - 2018 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 + */ + #include #include diff --git a/src/manager/service/key-provider.cpp b/src/manager/service/key-provider.cpp index 15bff3d..98dedd4 100644 --- a/src/manager/service/key-provider.cpp +++ b/src/manager/service/key-provider.cpp @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2014 - 2018 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 + */ + #include #include #include diff --git a/src/manager/service/key-provider.h b/src/manager/service/key-provider.h index 9242e11..82b79e6 100644 --- a/src/manager/service/key-provider.h +++ b/src/manager/service/key-provider.h @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2014 - 2018 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 + */ + #pragma once #include -- 2.7.4 From eab56821b4051e51b69d9492df4b47d9aecd9a9f Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Tue, 17 Jul 2018 14:14:18 +0200 Subject: [PATCH 14/16] Add protection against memory leaking during deserialization Change-Id: I1fbcd7daf1674dd1ad6b9eaffdba76263bda370b --- src/manager/dpl/core/include/dpl/serialization.h | 60 ++++++++++++++---------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/src/manager/dpl/core/include/dpl/serialization.h b/src/manager/dpl/core/include/dpl/serialization.h index 5d4ed2b..4448923 100644 --- a/src/manager/dpl/core/include/dpl/serialization.h +++ b/src/manager/dpl/core/include/dpl/serialization.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2011 - 2018 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. @@ -260,6 +260,17 @@ struct Deserialization { object = new T(stream); } + // *& deserialization template to simplify rest of the code + template + static inline void DeserializePtr(IStream &stream, T *&value) + { + T *tmp = new T; + std::unique_ptr ptr(tmp); + Deserialize(stream, *tmp); + ptr.release(); + value = tmp; + } + // char static void Deserialize(IStream &stream, char &value) { @@ -267,8 +278,7 @@ struct Deserialization { } static void Deserialize(IStream &stream, char *&value) { - value = new char; - stream.Read(sizeof(*value), value); + DeserializePtr(stream, value); } // unsigned char @@ -278,8 +288,7 @@ struct Deserialization { } static void Deserialize(IStream &stream, unsigned char *&value) { - value = new unsigned char; - stream.Read(sizeof(*value), value); + DeserializePtr(stream, value); } // unsigned int32 @@ -289,8 +298,7 @@ struct Deserialization { } static void Deserialize(IStream &stream, uint32_t *&value) { - value = new uint32_t; - stream.Read(sizeof(*value), value); + DeserializePtr(stream, value); } // int32 @@ -300,8 +308,7 @@ struct Deserialization { } static void Deserialize(IStream &stream, int32_t *&value) { - value = new int32_t; - stream.Read(sizeof(*value), value); + DeserializePtr(stream, value); } // unsigned int64 @@ -311,8 +318,7 @@ struct Deserialization { } static void Deserialize(IStream &stream, uint64_t *&value) { - value = new uint64_t; - stream.Read(sizeof(*value), value); + DeserializePtr(stream, value); } // int64 @@ -322,8 +328,7 @@ struct Deserialization { } static void Deserialize(IStream &stream, int64_t *&value) { - value = new int64_t; - stream.Read(sizeof(*value), value); + DeserializePtr(stream, value); } // bool @@ -333,8 +338,7 @@ struct Deserialization { } static void Deserialize(IStream &stream, bool *&value) { - value = new bool; - stream.Read(sizeof(*value), value); + DeserializePtr(stream, value); } template @@ -375,8 +379,7 @@ struct Deserialization { template static void Deserialize(IStream &stream, std::list *&list) { - list = new std::list; - Deserialize(stream, *list); + DeserializePtr(stream, list); } // RawBuffer @@ -392,8 +395,7 @@ struct Deserialization { template static void Deserialize(IStream &stream, std::vector *&vec) { - vec = new std::vector; - Deserialize(stream, *vec); + DeserializePtr>(stream, vec); } // std::vector @@ -412,8 +414,7 @@ struct Deserialization { template static void Deserialize(IStream &stream, std::vector *&vec) { - vec = new std::vector; - Deserialize(stream, *vec); + DeserializePtr(stream, vec); } // std::pair @@ -426,8 +427,7 @@ struct Deserialization { template static void Deserialize(IStream &stream, std::pair *&p) { - p = new std::pair; - Deserialize(stream, *p); + DeserializePtr(stream, p); } // std::map @@ -448,8 +448,7 @@ struct Deserialization { template static void Deserialize(IStream &stream, std::map *&map) { - map = new std::map; - Deserialize(stream, *map); + DeserializePtr(stream, map); } }; // struct Deserialization @@ -486,6 +485,17 @@ struct Deserializer : public Deserializer { Deserialization::Deserialize(stream, f); Deserializer::Deserialize(stream, args...); } + + static void Deserialize(IStream &stream, First *&f, Args &... args) + { + First *tmp = NULL; + Deserialization::Deserialize(stream, tmp); + std::unique_ptr ptr(tmp); + Deserializer::Deserialize(stream, args...); + ptr.release(); + f = tmp; + } + }; // end of recursion -- 2.7.4 From 2d9d8282745322c2abe083ebe5511ff92cdd45ff Mon Sep 17 00:00:00 2001 From: Konrad Lipinski Date: Thu, 2 Aug 2018 12:44:44 +0200 Subject: [PATCH 15/16] Make spec compliant with gbs --incremental According to [1], %prep section of the spec file should contain a single %setup macro, nothing else. According to [2], manifest %files are best copied to %{buildroot}%{_datadir} in the %install section. Moved manifest copy operations from %prep to %install accordingly. References [1] https://source.tizen.org/documentation/reference/git-build-system/usage/gbs-build [2] https://wiki.tizen.org/Security/Application_installation_and_Manifest Change-Id: Iacf755558636f939a540482f849e810780c19a51 --- packaging/key-manager.spec | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec index aead73a..1a3dd0b 100644 --- a/packaging/key-manager.spec +++ b/packaging/key-manager.spec @@ -128,10 +128,6 @@ and password change events from PAM %prep %setup -q -cp -a %{SOURCE1001} . -cp -a %{SOURCE1002} . -cp -a %{SOURCE1003} . -cp -a %{SOURCE1004} . %build %if 0%{?sec_build_binary_debug_enable} @@ -182,6 +178,7 @@ make %{?jobs:-j%jobs} %install_service sockets.target.wants central-key-manager-api-storage.socket %install_service sockets.target.wants central-key-manager-api-ocsp.socket %install_service sockets.target.wants central-key-manager-api-encryption.socket +cp -a %{SOURCE1001} %{SOURCE1002} %{SOURCE1003} %{SOURCE1004} %{buildroot}%{_datadir}/ %pre # tzplatform-get sync breaked because of on-development situation. comment out just for temporary @@ -278,23 +275,23 @@ fi %{bin_dir}/ckm_tool %files -n key-manager-pam-plugin -%manifest key-manager-pam-plugin.manifest +%manifest %{_datadir}/key-manager-pam-plugin.manifest %license LICENSE %{_libdir}/security/pam_key_manager_plugin.so* %files -n libkey-manager-common -%manifest libkey-manager-common.manifest +%manifest %{_datadir}/libkey-manager-common.manifest %license LICENSE %{_libdir}/libkey-manager-common.so.* %files -n libkey-manager-client -%manifest libkey-manager-client.manifest +%manifest %{_datadir}/libkey-manager-client.manifest %license LICENSE %{_libdir}/libkey-manager-client.so.* %{_libdir}/libkey-manager-control-client.so.* %files -n libkey-manager-client-devel -%manifest libkey-manager-client-devel.manifest +%manifest %{_datadir}/libkey-manager-client-devel.manifest %license LICENSE %{_libdir}/libkey-manager-client.so %{_libdir}/libkey-manager-control-client.so -- 2.7.4 From b61e8105c2dbdf36b33cc870624ec4ce2efbcadd Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Tue, 28 Aug 2018 13:51:14 +0900 Subject: [PATCH 16/16] Fix TYPO in key-manager_doc.h Change-Id: I11dbc3468e8277f0cef978f722ecbe275e1048f6 Signed-off-by: Dongsun Lee --- doc/key-manager_doc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/key-manager_doc.h b/doc/key-manager_doc.h index f553f7a..62b5fce 100644 --- a/doc/key-manager_doc.h +++ b/doc/key-manager_doc.h @@ -66,7 +66,7 @@ * - A client should specify the package id of the owner in the alias to retrieve a a key, certificate, or data shared by other applications. * - Aliases are returned as the format of "package_id name" from the key-manager. * Supported features - * Since Tizen 5.0 on chosen images, the realization of module functionality can be implemened using ARM TrustZone technology. + * Since Tizen 5.0 on chosen images, the realization of module functionality can be implemented using ARM TrustZone technology. * Differences in standards governing TrustZone implementation and previous software-based implementation cause following differences in module operation: * - When using TrustZone-based backend, GCM modes with 32 and 64 bit tag lengths are not supported. * Global Platform TEE specification treats these configurations as unsafe and not supported. -- 2.7.4
APIDescription