From 99c4f3a5fc4646fb8f4a1d9ec234a80a77905d12 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Fri, 3 Jul 2015 13:53:06 +0900 Subject: [PATCH 01/16] Fix table name to add backendId Change-Id: I5204529f11267f8df1b896435125108bc972bb63 Signed-off-by: Kyungwook Tak --- data/scripts/migrate_3.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/scripts/migrate_3.sql b/data/scripts/migrate_3.sql index 14a63c3..5a44cbb 100644 --- a/data/scripts/migrate_3.sql +++ b/data/scripts/migrate_3.sql @@ -22,4 +22,4 @@ -- update schema -ALTER TABLE NAMES ADD COLUMN backendId INTEGER NOT NULL DEFAULT 1; +ALTER TABLE OBJECTS ADD COLUMN backendId INTEGER NOT NULL DEFAULT 1; -- 2.7.4 From 2b9d8ad8aaacb32aaed13aee529af1fe839f6bb0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Grzelewski Date: Wed, 1 Jul 2015 15:47:27 +0200 Subject: [PATCH 02/16] Reduce number of error logs in ckm. Change-Id: Ibdf054bfa39723910dafd2eea64173b8e34f13e0 --- src/manager/common/exception.h | 4 ++-- src/manager/common/stringify.h | 2 +- src/manager/service/ckm-logic.cpp | 16 ++++++++-------- src/manager/service/file-system.cpp | 12 ++++++------ 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/manager/common/exception.h b/src/manager/common/exception.h index 611cad1..c174085 100644 --- a/src/manager/common/exception.h +++ b/src/manager/common/exception.h @@ -111,13 +111,13 @@ public: typedef DefineException InternalError; typedef DefineException InputParam; + StringifyDebug, PrintDebug> InputParam; typedef DefineException DatabaseLocked; typedef DefineException FileSystemFailed; typedef DefineException AuthenticationFailed; + StringifyDebug, PrintDebug> AuthenticationFailed; } // namespace Exc } // namespace CKM diff --git a/src/manager/common/stringify.h b/src/manager/common/stringify.h index 49a9a46..d989f44 100644 --- a/src/manager/common/stringify.h +++ b/src/manager/common/stringify.h @@ -37,7 +37,7 @@ public: } template - std::string operator()(const Args&... args){ + std::string operator()(const Args&...){ return std::string(); } }; diff --git a/src/manager/service/ckm-logic.cpp b/src/manager/service/ckm-logic.cpp index 0a6893f..8197fb9 100644 --- a/src/manager/service/ckm-logic.cpp +++ b/src/manager/service/ckm-logic.cpp @@ -372,7 +372,7 @@ int CKMLogic::checkSaveConditions( { // verify name and label are correct if (!isNameValid(name) || !isLabelValid(ownerLabel)) { - LogWarning("Invalid parameter passed to key-manager"); + LogDebug("Invalid parameter passed to key-manager"); return CKM_API_ERROR_INPUT_PARAM; } @@ -380,7 +380,7 @@ int CKMLogic::checkSaveConditions( int access_ec = m_accessControl.canSave(cred, ownerLabel); if( access_ec != CKM_API_SUCCESS) { - LogWarning("label " << cred.smackLabel << " can not save rows using label " << ownerLabel); + LogDebug("label " << cred.smackLabel << " can not save rows using label " << ownerLabel); return access_ec; } @@ -449,7 +449,7 @@ int CKMLogic::toBinaryData(DataType dataType, output_key = CKM::Key::create(input_data); if(output_key.get() == NULL) { - LogError("provided binary data is not valid key data"); + LogDebug("provided binary data is not valid key data"); return CKM_API_ERROR_INPUT_PARAM; } output_data = output_key->getDER(); @@ -459,7 +459,7 @@ int CKMLogic::toBinaryData(DataType dataType, CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER); if(cert.get() == NULL) { - LogError("provided binary data is not valid certificate data"); + LogDebug("provided binary data is not valid certificate data"); return CKM_API_ERROR_INPUT_PARAM; } output_data = cert->getDER(); @@ -632,7 +632,7 @@ int CKMLogic::removeDataHelper( // use client label if not explicitly provided const Label &ownerLabel = label.empty() ? cred.smackLabel : label; if (!isNameValid(name) || !isLabelValid(ownerLabel)) { - LogError("Invalid label or name format"); + LogDebug("Invalid label or name format"); return CKM_API_ERROR_INPUT_PARAM; } @@ -654,7 +654,7 @@ int CKMLogic::removeDataHelper( if(erased) transaction.commit(); else { - LogError("No row for given name and label"); + LogDebug("No row for given name and label"); return CKM_API_ERROR_DB_ALIAS_UNKNOWN; } @@ -711,7 +711,7 @@ int CKMLogic::readSingleRow(const Name &name, } if(!row_optional) { - LogError("No row for given name, label and type"); + LogDebug("No row for given name, label and type"); return CKM_API_ERROR_DB_ALIAS_UNKNOWN; } else { row = *row_optional; @@ -755,7 +755,7 @@ int CKMLogic::readMultiRow(const Name &name, } if(!output.size()) { - LogError("No row for given name, label and type"); + LogDebug("No row for given name, label and type"); return CKM_API_ERROR_DB_ALIAS_UNKNOWN; } diff --git a/src/manager/service/file-system.cpp b/src/manager/service/file-system.cpp index 96446c1..376d78d 100644 --- a/src/manager/service/file-system.cpp +++ b/src/manager/service/file-system.cpp @@ -209,10 +209,10 @@ UidVector FileSystem::getUIDsFromDBFile() { try { uids.push_back(static_cast(std::stoi((pDirEntry->d_name)+CKM_KEY_PREFIX.size()))); } catch (const std::invalid_argument) { - LogError("Error in extracting uid from db file. Error=std::invalid_argument." + LogDebug("Error in extracting uid from db file. Error=std::invalid_argument." "This will be ignored.File=" << pDirEntry->d_name << ""); } catch(const std::out_of_range) { - LogError("Error in extracting uid from db file. Error=std::out_of_range." + LogDebug("Error in extracting uid from db file. Error=std::out_of_range." "This will be ignored. File="<< pDirEntry->d_name << ""); } } @@ -226,28 +226,28 @@ int FileSystem::removeUserData() const { if (unlink(getDBPath().c_str())) { retCode = -1; err = errno; - LogError("Error in unlink user database: " << getDBPath() + LogDebug("Error in unlink user database: " << getDBPath() << "Errno: " << errno << " " << GetErrnoString(err)); } if (unlink(getDKEKPath().c_str())) { retCode = -1; err = errno; - LogError("Error in unlink user DKEK: " << getDKEKPath() + LogDebug("Error in unlink user DKEK: " << getDKEKPath() << "Errno: " << errno << " " << GetErrnoString(err)); } if (unlink(getDBDEKPath().c_str())) { retCode = -1; err = errno; - LogError("Error in unlink user DBDEK: " << getDBDEKPath() + LogDebug("Error in unlink user DBDEK: " << getDBDEKPath() << "Errno: " << errno << " " << GetErrnoString(err)); } if (unlink(getRemovedAppsPath().c_str())) { retCode = -1; err = errno; - LogError("Error in unlink user's Removed Apps File: " << getRemovedAppsPath() + LogDebug("Error in unlink user's Removed Apps File: " << getRemovedAppsPath() << "Errno: " << errno << " " << GetErrnoString(err)); } -- 2.7.4 From e5352a7e570bcce20f202d790ab7b4d7aa7f6078 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 3 Jul 2015 16:36:40 +0200 Subject: [PATCH 03/16] Fix parameter validation in ocsp [Problem] It's possible to pass invalid certificate chains to ocsp that will cause segfault. [Solution] Add argument check [Verification] Run ckm-tests --regexp=ocsp_check Change-Id: I267054f81780149a0512532a016c3f7caf30e900 --- src/manager/client-async/client-manager-async-impl.cpp | 2 ++ src/manager/client/client-manager-impl.cpp | 4 ++++ src/manager/service/ocsp-logic.cpp | 17 +++++++++++------ src/manager/service/ocsp.cpp | 4 ++-- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/manager/client-async/client-manager-async-impl.cpp b/src/manager/client-async/client-manager-async-impl.cpp index a04645e..2a37c24 100644 --- a/src/manager/client-async/client-manager-async-impl.cpp +++ b/src/manager/client-async/client-manager-async-impl.cpp @@ -248,6 +248,8 @@ void ManagerAsync::Impl::ocspCheck(const ObserverPtr& observer, try_catch_async([&] { RawBufferVector rawCertChain; for (auto &e: certificateChainVector) { + if(!e || e->empty()) + return observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); rawCertChain.push_back(e->getDER()); } diff --git a/src/manager/client/client-manager-impl.cpp b/src/manager/client/client-manager-impl.cpp index ca9d250..3bb1ef9 100644 --- a/src/manager/client/client-manager-impl.cpp +++ b/src/manager/client/client-manager-impl.cpp @@ -711,6 +711,10 @@ int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspSta RawBufferVector rawCertChain; for (auto &e: certChain) { + if (!e || e->empty()) { + LogError("Empty certificate"); + return CKM_API_ERROR_INPUT_PARAM; + } rawCertChain.push_back(e->getDER()); } diff --git a/src/manager/service/ocsp-logic.cpp b/src/manager/service/ocsp-logic.cpp index bd62d2c..af39e20 100644 --- a/src/manager/service/ocsp-logic.cpp +++ b/src/manager/service/ocsp-logic.cpp @@ -37,12 +37,17 @@ RawBuffer OCSPLogic::ocspCheck(int commandId, const RawBufferVector &rawChain) { int retCode = CKM_API_SUCCESS; int ocspStatus = CKM_API_OCSP_STATUS_INTERNAL_ERROR; - for (auto &e: rawChain) { - certChain.push_back(CertificateImpl(e, DataFormat::FORM_DER)); - if (certChain.rbegin()->empty()) { - LogDebug("Error in parsing certificates!"); - retCode = CKM_API_ERROR_INPUT_PARAM; - break; + if(rawChain.size() < 2) { + LogError("Certificate chain should contain at least 2 certificates"); + retCode = CKM_API_ERROR_INPUT_PARAM; + } else { + for (auto &e: rawChain) { + certChain.push_back(CertificateImpl(e, DataFormat::FORM_DER)); + if (certChain.rbegin()->empty()) { + LogDebug("Error in parsing certificates!"); + retCode = CKM_API_ERROR_INPUT_PARAM; + break; + } } } diff --git a/src/manager/service/ocsp.cpp b/src/manager/service/ocsp.cpp index 4f4477e..1dde8be 100644 --- a/src/manager/service/ocsp.cpp +++ b/src/manager/service/ocsp.cpp @@ -72,7 +72,7 @@ int OCSPModule::verify(const CertificateImplVector &certificateChain) { X509_STACK_PTR trustedCerts = create_x509_stack(); // skip first 2 certificates - for (auto it=certificateChain.cbegin()+2; it != certificateChain.cend(); it++) + for (auto it=certificateChain.cbegin()+2; it < certificateChain.cend(); it++) { if (it->empty()) { LogError("Error. Broken certificate chain."); @@ -81,7 +81,7 @@ int OCSPModule::verify(const CertificateImplVector &certificateChain) { sk_X509_push(trustedCerts.get(), it->getX509()); } - for (unsigned int i=0; i < certificateChain.size() -1; i++) {// except root certificate + for (int i=0; i < static_cast(certificateChain.size())-1; i++) {// except root certificate if (certificateChain[i].empty() || certificateChain[i+1].empty()) { LogError("Error. Broken certificate chain."); return CKM_API_OCSP_STATUS_INTERNAL_ERROR; -- 2.7.4 From 0df8f4ec79a11de5bf82ce472801467aa70defa8 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 2 Jul 2015 16:05:41 +0200 Subject: [PATCH 04/16] Fix segfault in getCertificateChain [Problem] When getCertificateChain is called with empty certificate a segfault occurs in client. [Solution] Add param check in client. [Verification] Run ckm-tests --regexp=T13122_get_chain_empty_cert && ckm-tests --regexp=T13121_get_chain_no_cert Change-Id: I4f29ab1ca95166de261ef9120897ac85ac80c722 --- src/manager/client/client-manager-impl.cpp | 6 ++++++ src/manager/service/ckm-logic.cpp | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/manager/client/client-manager-impl.cpp b/src/manager/client/client-manager-impl.cpp index 3bb1ef9..79774c1 100644 --- a/src/manager/client/client-manager-impl.cpp +++ b/src/manager/client/client-manager-impl.cpp @@ -573,6 +573,9 @@ int ManagerImpl::getCertificateChain( RawBufferVector untrustedVector; RawBufferVector trustedVector; + if(!certificate || certificate->empty()) + return CKM_API_ERROR_INPUT_PARAM; + for (auto &e: untrustedCertificates) { untrustedVector.push_back(e->getDER()); } @@ -601,6 +604,9 @@ int ManagerImpl::getCertificateChain( LabelNameVector untrustedVector; LabelNameVector trustedVector; + if(!certificate || certificate->empty()) + return CKM_API_ERROR_INPUT_PARAM; + for (auto &e: untrustedCertificates) { AliasSupport helper(e); untrustedVector.push_back(std::make_pair(helper.getLabel(), helper.getName())); diff --git a/src/manager/service/ckm-logic.cpp b/src/manager/service/ckm-logic.cpp index 8197fb9..3ce1e1c 100644 --- a/src/manager/service/ckm-logic.cpp +++ b/src/manager/service/ckm-logic.cpp @@ -1318,10 +1318,18 @@ int CKMLogic::getCertificateChainHelper( if (cert.empty()) return CKM_API_ERROR_INPUT_PARAM; - for (auto &e: untrustedCertificates) - untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER)); - for (auto &e: trustedCertificates) - trustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER)); + for (auto &e: untrustedCertificates) { + CertificateImpl c(e, DataFormat::FORM_DER); + if(c.empty()) + return CKM_API_ERROR_INPUT_PARAM; + untrustedCertVector.push_back(std::move(c)); + } + for (auto &e: trustedCertificates) { + CertificateImpl c(e, DataFormat::FORM_DER); + if(c.empty()) + return CKM_API_ERROR_INPUT_PARAM; + trustedCertVector.push_back(std::move(c)); + } CertificateStore store; int retCode = store.verifyCertificate(cert, -- 2.7.4 From 8a58e5016808f8c66abf9f58b42c8d8c02ba5ce4 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Fri, 17 Jul 2015 19:45:36 +0900 Subject: [PATCH 05/16] Match schema file version to db version Change-Id: I9379b1e4eb39125c0a421fc9655ce0f8c3641c4a Signed-off-by: Kyungwook Tak --- data/scripts/create_schema.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/scripts/create_schema.sql b/data/scripts/create_schema.sql index dac4bc0..8b66af9 100644 --- a/data/scripts/create_schema.sql +++ b/data/scripts/create_schema.sql @@ -16,7 +16,7 @@ * * @file create_schema.sql * @author Maciej Karpiuk (m.karpiuk2@samsung.com) - * @version 3.0 + * @version 4.0 * @brief DB script to create database schema. */ -- 2.7.4 From 6e04e42e061eee0d269d73b378a96ad91fc31ff8 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 2 Jul 2015 13:40:12 +0200 Subject: [PATCH 06/16] Openssl: add thread support and fix initialization [Problem] Openssl is used in multiple threads without proper thread support. Openssl initialization is scattered across several threads/files. [Solution] Lock and thread id callbacks registered. Openssl initialization refactored and fixed. [Verification] Run ckm-tests --output=text & ckm-tests-internal Change-Id: Iff26af6a0afd67001155aac040949bfde9cc6d31 --- src/manager/client-capi/ckmc-type.cpp | 5 +- src/manager/client/client-manager-impl.cpp | 2 +- src/manager/common/crypto-init.cpp | 131 ++++++++++++++++++++++++++-- src/manager/common/crypto-init.h | 5 +- src/manager/common/pkcs12-impl.cpp | 2 +- src/manager/crypto/sw-backend/internals.cpp | 28 ------ src/manager/crypto/sw-backend/internals.h | 6 -- src/manager/crypto/sw-backend/store.cpp | 2 - src/manager/main/key-manager-main.cpp | 16 +--- src/manager/main/service-thread.h | 5 ++ 10 files changed, 141 insertions(+), 61 deletions(-) diff --git a/src/manager/client-capi/ckmc-type.cpp b/src/manager/client-capi/ckmc-type.cpp index 94fad5e..c7458ab 100644 --- a/src/manager/client-capi/ckmc-type.cpp +++ b/src/manager/client-capi/ckmc-type.cpp @@ -34,6 +34,7 @@ #include #include #include +#include namespace { @@ -194,7 +195,7 @@ int ckmc_cert_new(unsigned char *raw_cert, size_t cert_size, ckmc_data_format_e KEY_MANAGER_CAPI int ckmc_load_cert_from_file(const char *file_path, ckmc_cert_s **cert) { - OpenSSL_add_all_algorithms(); + CKM::initOpenSslOnce(); FILE *fp = fopen(file_path, "r"); if(fp == NULL) @@ -394,7 +395,7 @@ int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase, ck }; - OpenSSL_add_all_algorithms(); + CKM::initOpenSslOnce(); int ret = CKMC_ERROR_NONE; diff --git a/src/manager/client/client-manager-impl.cpp b/src/manager/client/client-manager-impl.cpp index 79774c1..17c2361 100644 --- a/src/manager/client/client-manager-impl.cpp +++ b/src/manager/client/client-manager-impl.cpp @@ -92,7 +92,7 @@ ManagerImpl::ManagerImpl() m_ocspConnection(SERVICE_SOCKET_OCSP), m_encryptionConnection(SERVICE_SOCKET_ENCRYPTION) { - initCryptoLib(); + initOpenSslOnce(); } diff --git a/src/manager/common/crypto-init.cpp b/src/manager/common/crypto-init.cpp index 47f99b7..9b1a7b7 100644 --- a/src/manager/common/crypto-init.cpp +++ b/src/manager/common/crypto-init.cpp @@ -20,25 +20,142 @@ */ #include "crypto-init.h" + #include -#include #include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include namespace CKM { +namespace { + +const char* DEV_HW_RANDOM_FILE = "/dev/hwrng"; +const char* DEV_URANDOM_FILE = "/dev/urandom"; +const size_t RANDOM_BUFFER_LEN = 32; + +std::mutex* g_mutexes = NULL; + +void lockingCallback(int mode, int type, const char*, int) +{ + if(!g_mutexes) { + LogError("Openssl mutexes do not exist"); + return; + } + + if (mode & CRYPTO_LOCK) + g_mutexes[type].lock(); + else if (mode & CRYPTO_UNLOCK) + g_mutexes[type].unlock(); +} + +unsigned long threadIdCallback() { + std::hash hasher; + return hasher(std::this_thread::get_id()); +} + +void opensslInstallLocks() +{ + g_mutexes = new std::mutex[CRYPTO_num_locks()]; + + CRYPTO_set_id_callback(threadIdCallback); + CRYPTO_set_locking_callback(lockingCallback); +} + +void opensslUninstallLocks() +{ + CRYPTO_set_id_callback(NULL); + CRYPTO_set_locking_callback(NULL); + + delete[] g_mutexes; + g_mutexes = NULL; +} + +} // namespace anonymous + + +void initOpenSsl() { + // Loads all error strings (crypto and ssl) + SSL_load_error_strings(); + + /* + * Initialize libcrypto (add all algorithms, digests & ciphers) + * It also does the stuff from SSL_library_init() except for ssl_load_ciphers() + */ + OpenSSL_add_all_algorithms(); // Can be optimized by using EVP_add_cipher instead + + /* + * Initialize libssl (OCSP uses it) + * SSL_library_init() == OpenSSL_add_ssl_algorithms() + * It always returns 1 + */ + SSL_library_init(); + + // load default configuration (/etc/ssl/openssl.cnf) + OPENSSL_config(NULL); + + // enable FIPS mode by default + if(0 == FIPS_mode_set(1)) { + LogError("Failed to set FIPS mode"); + } + + /* + * Initialize entropy + * entropy sources - /dev/random,/dev/urandom(Default) + */ + int ret = 0; + + std::ifstream ifile(DEV_HW_RANDOM_FILE); + if(ifile.is_open()) + ret= RAND_load_file(DEV_HW_RANDOM_FILE, RANDOM_BUFFER_LEN); + + if(ret != RANDOM_BUFFER_LEN ){ + LogWarning("Error in HW_RAND file load"); + ret = RAND_load_file(DEV_URANDOM_FILE, RANDOM_BUFFER_LEN); + + if(ret != RANDOM_BUFFER_LEN) + LogError("Error in U_RAND_file_load"); + } + + // Install locks for multithreading support + opensslInstallLocks(); +} + +void deinitOpenSsl() { + opensslUninstallLocks(); + CONF_modules_unload(1); + EVP_cleanup(); + ERR_free_strings(); + deinitOpenSslThread(); +} + +void deinitOpenSslThread() { + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); +} namespace { std::mutex cryptoInitMutex; -void initOpenSSL(); +void initOpenSslAndDetach(); typedef void(*initFnPtr)(); // has to be atomic as storing function pointer is not an atomic operation on armv7l -std::atomic initFn (&initOpenSSL); +std::atomic initFn (&initOpenSslAndDetach); void initEmpty() {} -void initOpenSSL() { +void initOpenSslAndDetach() { // DCLP std::lock_guard lock(cryptoInitMutex); /* @@ -47,9 +164,7 @@ void initOpenSSL() { */ if(initFn.load(std::memory_order_relaxed) != &initEmpty) { - OpenSSL_add_all_ciphers(); - OpenSSL_add_all_algorithms(); - OpenSSL_add_all_digests(); + initOpenSsl(); /* * Synchronizes with load. Everything that happened before this store in this thread is @@ -62,7 +177,7 @@ void initOpenSSL() { } // namespace anonymous -void initCryptoLib() { +void initOpenSslOnce() { /* * Synchronizes with store. Everything that happened before store in another thread will be * visible in this thread after load. diff --git a/src/manager/common/crypto-init.h b/src/manager/common/crypto-init.h index 5845a12..e2419b1 100644 --- a/src/manager/common/crypto-init.h +++ b/src/manager/common/crypto-init.h @@ -24,7 +24,10 @@ namespace CKM { -COMMON_API void initCryptoLib(); +COMMON_API void initOpenSsl(); +COMMON_API void deinitOpenSsl(); +COMMON_API void deinitOpenSslThread(); +COMMON_API void initOpenSslOnce(); } // namespace CKM diff --git a/src/manager/common/pkcs12-impl.cpp b/src/manager/common/pkcs12-impl.cpp index 6c10ff1..6914698 100644 --- a/src/manager/common/pkcs12-impl.cpp +++ b/src/manager/common/pkcs12-impl.cpp @@ -69,7 +69,7 @@ PKCS12Impl::PKCS12Impl(const RawBuffer &buffer, const Password &password) } // needed if parsing is done before manager initialization - initCryptoLib(); + initOpenSslOnce(); if (!PKCS12_verify_mac(pkcs12, password.c_str(), password.size())) { LogDebug("Pkcs12 verify failed. Wrong password"); diff --git a/src/manager/crypto/sw-backend/internals.cpp b/src/manager/crypto/sw-backend/internals.cpp index ad646fb..658d6eb 100644 --- a/src/manager/crypto/sw-backend/internals.cpp +++ b/src/manager/crypto/sw-backend/internals.cpp @@ -19,7 +19,6 @@ * @version 1.0 */ #include -#include #include #include @@ -46,8 +45,6 @@ #define OPENSSL_SUCCESS 1 // DO NOTCHANGE THIS VALUE #define OPENSSL_FAIL 0 // DO NOTCHANGE THIS VALUE -#define DEV_HW_RANDOM_FILE "/dev/hwrng" -#define DEV_URANDOM_FILE "/dev/urandom" namespace CKM { namespace Crypto { @@ -284,31 +281,6 @@ InitCipherFn selectCipher(AlgoType type, size_t key_len = 32, bool encryption = } // anonymous namespace -int initialize() { - int hw_rand_ret = 0; - int u_rand_ret = 0; - - // try to initialize using ERR_load_crypto_strings and OpenSSL_add_all_algorithms - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - - // initialize entropy - std::ifstream ifile(DEV_HW_RANDOM_FILE); - if(ifile.is_open()) { - u_rand_ret= RAND_load_file(DEV_HW_RANDOM_FILE, 32); - } - if(u_rand_ret != 32 ){ - LogError("Error in HW_RAND file load"); - hw_rand_ret = RAND_load_file(DEV_URANDOM_FILE, 32); - - if(hw_rand_ret != 32) { - ThrowErr(Exc::Crypto::InternalError, "Error in U_RAND_file_load"); - } - } - - return CKM_CRYPTO_INIT_SUCCESS; -} - const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo) { const EVP_MD *md_algo=NULL; switch(hashAlgo) { diff --git a/src/manager/crypto/sw-backend/internals.h b/src/manager/crypto/sw-backend/internals.h index df3b245..ebd14de 100644 --- a/src/manager/crypto/sw-backend/internals.h +++ b/src/manager/crypto/sw-backend/internals.h @@ -39,12 +39,6 @@ namespace Crypto { namespace SW { namespace Internals { -// During initialization, FIPS_MODE and the entropy source are set -// and system certificates are loaded to memory. -// FIPS_MODE - ON, OFF(Default) -// entropy source - /dev/random,/dev/urandom(Default) -int initialize(); - TokenPair createKeyPairRSA(CryptoBackend backendId, const int size); TokenPair createKeyPairDSA(CryptoBackend backendId, const int size); TokenPair createKeyPairECDSA(CryptoBackend backendId, ElipticCurve type1); diff --git a/src/manager/crypto/sw-backend/store.cpp b/src/manager/crypto/sw-backend/store.cpp index 4d6b1bf..77bcb7a 100644 --- a/src/manager/crypto/sw-backend/store.cpp +++ b/src/manager/crypto/sw-backend/store.cpp @@ -41,8 +41,6 @@ namespace SW { Store::Store(CryptoBackend backendId) : GStore(backendId) { - // initialize openssl internals - Internals::initialize(); } GKeyUPtr Store::getKey(const Token &token) { diff --git a/src/manager/main/key-manager-main.cpp b/src/manager/main/key-manager-main.cpp index d1e486e..67a6631 100644 --- a/src/manager/main/key-manager-main.cpp +++ b/src/manager/main/key-manager-main.cpp @@ -22,11 +22,6 @@ #include #include -#include -#include -#include -#include - #include #include @@ -35,6 +30,7 @@ #include #include #include +#include #include #include @@ -88,10 +84,7 @@ int main(void) { } LogInfo("Init external libraries SKMM and openssl"); - SSL_load_error_strings(); - SSL_library_init(); - OpenSSL_add_all_ciphers(); - OPENSSL_config(NULL); + CKM::initOpenSsl(); CKM::KeyProvider::initializeLibrary(); @@ -108,9 +101,8 @@ int main(void) { // Manager has been destroyed and we may close external libraries. LogInfo("Deinit SKMM and openssl"); CKM::KeyProvider::closeLibrary(); - // Deinit OPENSSL ? - EVP_cleanup(); - ERR_free_strings(); + + CKM::deinitOpenSsl(); } catch (const std::runtime_error& e) { diff --git a/src/manager/main/service-thread.h b/src/manager/main/service-thread.h index 2b0609b..32087b7 100644 --- a/src/manager/main/service-thread.h +++ b/src/manager/main/service-thread.h @@ -34,6 +34,8 @@ #include #include +#include + #include #include @@ -95,6 +97,9 @@ protected: static void ThreadLoopStatic(ServiceThread *ptr) { ptr->ThreadLoop(); + + // cleanup openssl in every thread + deinitOpenSslThread(); } void ThreadLoop(){ -- 2.7.4 From 75b51d07a869d1dfcf02c2806f9950782fd258d7 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 2 Jul 2015 15:34:47 +0200 Subject: [PATCH 07/16] Add AAD support in AES GCM [Feature] Encryption service development. [Solution] Add AppendAAD method to EvpCipherWrapper. Use it to provide AAD in AES GCM encryption/decryption. [Verification] ckm-test --regexp=TED_1250_gcm_aad should pass. Change-Id: If461a875490b3a6319eb5c78b914bd4df6591746 --- src/manager/crypto/sw-backend/crypto.h | 11 +++++++++- src/manager/crypto/sw-backend/internals.cpp | 34 ++++++++++++++++++++++------- src/manager/crypto/sw-backend/internals.h | 6 +++-- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/manager/crypto/sw-backend/crypto.h b/src/manager/crypto/sw-backend/crypto.h index d23aac0..d42d930 100644 --- a/src/manager/crypto/sw-backend/crypto.h +++ b/src/manager/crypto/sw-backend/crypto.h @@ -52,6 +52,7 @@ struct Base { return EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr); } + virtual void AppendAAD(const T&) = 0; virtual T Append(const T&) = 0; virtual T Finalize() = 0; virtual ~Base(){ @@ -83,12 +84,20 @@ public: EVP_CIPHER_CTX_set_padding(m_ctx, 1); } + void AppendAAD(const T& data) { + static_assert(sizeof(typename T::value_type) == 1, "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"); + } + } + T Append(const T& data) { static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside container."); 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, "Failed in EVP_CipherUpdate"); + ThrowErr(Exc::Crypto::InternalError, "Append(): Failed in EVP_CipherUpdate"); } output.resize(bytesLen); return output; diff --git a/src/manager/crypto/sw-backend/internals.cpp b/src/manager/crypto/sw-backend/internals.cpp index 658d6eb..df9fbb7 100644 --- a/src/manager/crypto/sw-backend/internals.cpp +++ b/src/manager/crypto/sw-backend/internals.cpp @@ -534,11 +534,16 @@ std::pair encryptDataAesGcm( const RawBuffer &key, const RawBuffer &data, const RawBuffer &iv, - int tagSize) + int tagSize, + const RawBuffer &aad) { RawBuffer tag(tagSize); EvpCipherPtr enc; selectCipher(AlgoType::AES_GCM, key.size())(enc, key, iv); + + if (!aad.empty()) + enc->AppendAAD(aad); + RawBuffer result = enc->Append(data); RawBuffer tmp = enc->Finalize(); std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); @@ -552,9 +557,10 @@ RawBuffer encryptDataAesGcmPacked( const RawBuffer &key, const RawBuffer &data, const RawBuffer &iv, - int tagSize) + int tagSize, + const RawBuffer &aad) { - auto pair = encryptDataAesGcm(key, data, iv, tagSize); + auto pair = encryptDataAesGcm(key, data, iv, tagSize, aad); std::copy(pair.second.begin(), pair.second.end(), std::back_inserter(pair.first)); return pair.first; } @@ -577,7 +583,8 @@ RawBuffer decryptDataAesGcm( const RawBuffer &key, const RawBuffer &data, const RawBuffer &iv, - const RawBuffer &tag) + const RawBuffer &tag, + const RawBuffer &aad) { EvpCipherPtr dec; selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv); @@ -586,6 +593,9 @@ RawBuffer decryptDataAesGcm( ThrowErr(Exc::Crypto::InternalError, "Error in AES control function. Set tag failed."); } + if (!aad.empty()) + dec->AppendAAD(aad); + RawBuffer result = dec->Append(data); RawBuffer tmp = dec->Finalize(); std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); @@ -596,7 +606,8 @@ RawBuffer decryptDataAesGcmPacked( const RawBuffer &key, const RawBuffer &data, const RawBuffer &iv, - int tagSize) + int tagSize, + const RawBuffer &aad) { if (tagSize > static_cast(data.size())) ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag"); @@ -606,7 +617,8 @@ RawBuffer decryptDataAesGcmPacked( key, RawBuffer(data.data(), tagPos), iv, - RawBuffer(tagPos, data.data() + data.size())); + RawBuffer(tagPos, data.data() + data.size()), + aad); } RawBuffer symmetricEncrypt(const RawBuffer &key, @@ -626,10 +638,13 @@ RawBuffer symmetricEncrypt(const RawBuffer &key, { int tagLenBits = DEFAULT_AES_GCM_TAG_LEN; alg.getParam(ParamName::ED_TAG_LEN, tagLenBits); + RawBuffer aad; + alg.getParam(ParamName::ED_AAD, aad); return encryptDataAesGcmPacked(key, data, unpack(alg, ParamName::ED_IV), - tagLenBits/8); + tagLenBits/8, + aad); } default: break; @@ -655,10 +670,13 @@ RawBuffer symmetricDecrypt(const RawBuffer &key, { int tagLenBits = DEFAULT_AES_GCM_TAG_LEN; alg.getParam(ParamName::ED_TAG_LEN, tagLenBits); + RawBuffer aad; + alg.getParam(ParamName::ED_AAD, aad); return decryptDataAesGcmPacked(key, data, unpack(alg, ParamName::ED_IV), - tagLenBits/8); + tagLenBits/8, + aad); } default: break; diff --git a/src/manager/crypto/sw-backend/internals.h b/src/manager/crypto/sw-backend/internals.h index ebd14de..4d810d5 100644 --- a/src/manager/crypto/sw-backend/internals.h +++ b/src/manager/crypto/sw-backend/internals.h @@ -57,12 +57,14 @@ RawBuffer symmetricDecrypt(const RawBuffer &key, std::pair encryptDataAesGcm(const RawBuffer &key, const RawBuffer &data, const RawBuffer &iv, - int tagSizeBits); + int tagSize, + const RawBuffer &aad = RawBuffer()); RawBuffer decryptDataAesGcm(const RawBuffer &key, const RawBuffer &data, const RawBuffer &iv, - const RawBuffer &tag); + const RawBuffer &tag, + const RawBuffer &aad = RawBuffer()); RawBuffer encryptDataAes(AlgoType type, const RawBuffer &key, -- 2.7.4 From 8cfd51cfa09e81f89e0f35505e980206e76b06a1 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Tue, 7 Jul 2015 12:10:50 +0200 Subject: [PATCH 08/16] Add RSA OAEP support [Feature] Encryption service development [Solution] Add support for RSA OAEP encryption/decryption [Verification] Run ckm-tests --group=CKM_ENCRYPTION_DECRYPTION Change-Id: Ieb78fcb65fbd6e2042c2b7effe1ef7b66429fcbd --- .../crypto/generic-backend/algo-validation.h | 25 ++++++- src/manager/crypto/sw-backend/internals.cpp | 80 +++++++++++++++++++--- src/manager/crypto/sw-backend/internals.h | 7 ++ src/manager/crypto/sw-backend/key.cpp | 10 +++ src/manager/crypto/sw-backend/key.h | 2 + 5 files changed, 111 insertions(+), 13 deletions(-) diff --git a/src/manager/crypto/generic-backend/algo-validation.h b/src/manager/crypto/generic-backend/algo-validation.h index c8abc72..69dd95d 100644 --- a/src/manager/crypto/generic-backend/algo-validation.h +++ b/src/manager/crypto/generic-backend/algo-validation.h @@ -85,6 +85,12 @@ struct Type { }; }; +template +struct Unsupported { + static bool Check(const T&) { return false; } + static void Why(std::ostringstream& os) { os << "is not supported"; } +}; + ////////// Getters ////////////// @@ -93,12 +99,19 @@ template struct DefaultGetter { static T Get(const T& value) { return value; } static void What(std::ostringstream& os) { os << "value"; } + static void Print(std::ostringstream& os, const T& value) { os << static_cast(value); } }; +template <> +void DefaultGetter::Print(std::ostringstream& os, const RawBuffer& buffer) { + os << "[" << buffer.size() << "B buffer]"; +} + // returns buffer param size struct BufferSizeGetter { static size_t Get(const RawBuffer& buffer) { return buffer.size(); } static void What(std::ostringstream& os) { os << "buffer size"; } + static void Print(std::ostringstream& os, const RawBuffer& buffer) { os << buffer.size(); } }; @@ -126,6 +139,13 @@ typedef std::vector ValidatorVector; template struct VBuilder; +template <> +struct VBuilder<> { +static ValidatorVector Build() { + return ValidatorVector(); + } +}; + template struct VBuilder { static ValidatorVector Build() { @@ -187,8 +207,9 @@ struct ParamCheck : public ParamCheckBase { if(!Validator::Check(Getter::Get(value))) { os << "The "; Getter::What(os); - os << " of param '" << static_cast(Name) << "'=" << - static_cast(Getter::Get(value)) << " "; + os << " of param '" << static_cast(Name) << "'="; + Getter::Print(os, value); + os << " "; Validator::Why(os); ErrorHandler::Handle(os.str()); } diff --git a/src/manager/crypto/sw-backend/internals.cpp b/src/manager/crypto/sw-backend/internals.cpp index df9fbb7..3875c2b 100644 --- a/src/manager/crypto/sw-backend/internals.cpp +++ b/src/manager/crypto/sw-backend/internals.cpp @@ -96,8 +96,12 @@ typedef ParamCheck::Equals> IsEncryption; + AlgoType::AES_CFB>> IsSymEncryption; + +typedef ParamCheck::Equals> IsAsymEncryption; typedef ParamCheck, - BufferSizeGetter> GcmIvCheck; + DefaultValidator> GcmIvCheck; typedef ParamCheck::Equals<32, 64, 96, 104, 112, 120, 128>> GcmTagCheck; +typedef ParamCheck> RsaLabelCheck; + // sign / verify typedef ParamCheck::Build()); validators.emplace(AlgoType::AES_CFB, VBuilder::Build()); validators.emplace(AlgoType::AES_GCM, VBuilder::Build()); + validators.emplace(AlgoType::RSA_OAEP, VBuilder::Build()); return validators; }; ValidatorMap g_validators = initValidators(); @@ -207,8 +216,11 @@ void validateParams(const CryptoAlgorithm& ca) tc.Check(ca); AlgoType at = unpack(ca, ParamName::ALGO_TYPE); - for(const auto& validator : g_validators.at(at)) { - validator->Check(ca); + try { + for(const auto& validator : g_validators.at(at)) + validator->Check(ca); + } catch(const std::out_of_range&) { + ThrowErr(Exc::Crypto::InputParam, "Unsupported algorithm ", static_cast(at)); } } @@ -279,6 +291,39 @@ InitCipherFn selectCipher(AlgoType type, size_t key_len = 32, bool encryption = } } + +RawBuffer asymmetricHelper(int (*cryptoFn)(int, const unsigned char*, unsigned char*, RSA*, int), + const std::string logPrefix, + const EvpShPtr &pkey, + const CryptoAlgorithm &alg, + const RawBuffer &data) +{ + validateParams(alg); + + RSA* rsa = EVP_PKEY_get1_RSA(pkey.get()); + if (!rsa) + ThrowErr(Exc::Crypto::InputParam, logPrefix, "invalid key"); + + /* + * RSA_padding_add_PKCS1_OAEP supports custom label but RSA_public_encrypt calls it with NULL + * value so for now label is not supported. Alternative is to rewrite the openssl implementation + * to support it: openssl-fips/crypto/rsa/rsa_eay.c + */ + 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"); + + output.resize(ret); + return output; +} + } // anonymous namespace const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo) { @@ -625,7 +670,7 @@ RawBuffer symmetricEncrypt(const RawBuffer &key, const CryptoAlgorithm &alg, const RawBuffer &data) { - validateParams(alg); + validateParams(alg); AlgoType keyType = unpack(alg, ParamName::ALGO_TYPE); switch(keyType) @@ -649,15 +694,14 @@ RawBuffer symmetricEncrypt(const RawBuffer &key, default: break; } - ThrowErr(Exc::Crypto::OperationNotSupported, - "symmetric enc error: algorithm not recognized"); + ThrowErr(Exc::Crypto::OperationNotSupported, "symmetric enc: algorithm not recognized"); } RawBuffer symmetricDecrypt(const RawBuffer &key, const CryptoAlgorithm &alg, const RawBuffer &data) { - validateParams(alg); + validateParams(alg); AlgoType keyType = unpack(alg, ParamName::ALGO_TYPE); switch(keyType) @@ -681,7 +725,21 @@ RawBuffer symmetricDecrypt(const RawBuffer &key, default: break; } - ThrowErr(Exc::Crypto::InputParam, "symmetric dec error: algorithm not recognized"); + ThrowErr(Exc::Crypto::InputParam, "symmetric dec: algorithm not recognized"); +} + +RawBuffer asymmetricEncrypt(const EvpShPtr &pkey, + const CryptoAlgorithm &alg, + const RawBuffer &data) +{ + return asymmetricHelper(RSA_public_encrypt, "Asymmetric encryption: ", pkey, alg, data); +} + +RawBuffer asymmetricDecrypt(const EvpShPtr &pkey, + const CryptoAlgorithm &alg, + const RawBuffer &data) +{ + return asymmetricHelper(RSA_private_decrypt, "Asymmetric decryption: ", pkey, alg, data); } RawBuffer sign(EVP_PKEY *pkey, diff --git a/src/manager/crypto/sw-backend/internals.h b/src/manager/crypto/sw-backend/internals.h index 4d810d5..c71d106 100644 --- a/src/manager/crypto/sw-backend/internals.h +++ b/src/manager/crypto/sw-backend/internals.h @@ -25,6 +25,7 @@ #include #include #include +#include #define EVP_SUCCESS 1 // DO NOTCHANGE THIS VALUE #define EVP_FAIL 0 // DO NOTCHANGE THIS VALUE @@ -53,6 +54,12 @@ RawBuffer symmetricEncrypt(const RawBuffer &key, RawBuffer symmetricDecrypt(const RawBuffer &key, const CryptoAlgorithm &alg, const RawBuffer &cipher); +RawBuffer asymmetricEncrypt(const EvpShPtr &key, + const CryptoAlgorithm &alg, + const RawBuffer &data); +RawBuffer asymmetricDecrypt(const EvpShPtr &key, + const CryptoAlgorithm &alg, + const RawBuffer &data); std::pair encryptDataAesGcm(const RawBuffer &key, const RawBuffer &data, diff --git a/src/manager/crypto/sw-backend/key.cpp b/src/manager/crypto/sw-backend/key.cpp index 7ff0ebb..b1e57ff 100644 --- a/src/manager/crypto/sw-backend/key.cpp +++ b/src/manager/crypto/sw-backend/key.cpp @@ -108,6 +108,16 @@ int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message, const Raw return Internals::verify(evp, algWithType, message, sign); } +RawBuffer AKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data) +{ + return Internals::asymmetricEncrypt(getEvpShPtr(), alg, data); +} + +RawBuffer AKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &data) +{ + return Internals::asymmetricDecrypt(getEvpShPtr(), alg, data); +} + EvpShPtr AKey::getEvpShPtr() { if (m_evp) return m_evp; diff --git a/src/manager/crypto/sw-backend/key.h b/src/manager/crypto/sw-backend/key.h index df331ec..d5b7bfe 100644 --- a/src/manager/crypto/sw-backend/key.h +++ b/src/manager/crypto/sw-backend/key.h @@ -56,6 +56,8 @@ public: {} virtual RawBuffer sign(const CryptoAlgorithm &alg, const RawBuffer &message); virtual int verify(const CryptoAlgorithm &alg, const RawBuffer &message, const RawBuffer &sign); + virtual RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &); + virtual RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &); virtual RawBuffer getBinary() const; virtual ~AKey(){} protected: -- 2.7.4 From d924ac74a2d82370d095af2056e9d2e30257f2ba Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 9 Jul 2015 14:44:36 +0200 Subject: [PATCH 09/16] Implement asynchronous encryption/decryption API [Feature] Encryption/decryption API implementation [Solution] Add asynchronous interface for encryption and decryption [Verification] Run ckm-tests --group=CKM_ENCRYPTION_DECRYPTION Change-Id: Ie18d80a47885895aabbedc51d8bdb8ff60172726 --- src/CMakeLists.txt | 1 + src/include/ckm/ckm-manager-async.h | 19 +++++- .../client-async/client-manager-async-impl.cpp | 34 +++++++++- .../client-async/client-manager-async-impl.h | 10 ++- src/manager/client-async/client-manager-async.cpp | 22 ++++++- src/manager/client-async/encryption-receiver.cpp | 72 ++++++++++++++++++++++ src/manager/client-async/encryption-receiver.h | 46 ++++++++++++++ src/manager/client-async/ocsp-receiver.cpp | 2 +- src/manager/client-async/ocsp-receiver.h | 2 +- src/manager/client-async/receiver.h | 2 +- src/manager/client-async/service.cpp | 7 ++- src/manager/client-async/storage-receiver.cpp | 2 +- src/manager/client-async/storage-receiver.h | 2 +- 13 files changed, 210 insertions(+), 11 deletions(-) create mode 100644 src/manager/client-async/encryption-receiver.cpp create mode 100644 src/manager/client-async/encryption-receiver.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd79979..f76673f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -119,6 +119,7 @@ SET(KEY_MANAGER_CLIENT_SOURCES ${KEY_MANAGER_CLIENT_ASYNC_SRC_PATH}/service.cpp ${KEY_MANAGER_CLIENT_ASYNC_SRC_PATH}/storage-receiver.cpp ${KEY_MANAGER_CLIENT_ASYNC_SRC_PATH}/ocsp-receiver.cpp + ${KEY_MANAGER_CLIENT_ASYNC_SRC_PATH}/encryption-receiver.cpp ${KEY_MANAGER_CLIENT_ASYNC_SRC_PATH}/descriptor-set.cpp ${KEY_MANAGER_CLIENT_CAPI_SRC_PATH}/ckmc-type.cpp ${KEY_MANAGER_CLIENT_CAPI_SRC_PATH}/ckmc-error.cpp diff --git a/src/include/ckm/ckm-manager-async.h b/src/include/ckm/ckm-manager-async.h index fca4408..774bb32 100644 --- a/src/include/ckm/ckm-manager-async.h +++ b/src/include/ckm/ckm-manager-async.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2015 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. @@ -76,6 +76,9 @@ public: virtual void ReceivedSetPermission() {} + virtual void ReceivedEncrypted(RawBuffer &&) {} + virtual void ReceivedDecrypted(RawBuffer &&) {} + virtual ~Observer() {} }; @@ -191,6 +194,20 @@ public: const Label& accessor, PermissionMask permissionMask); + void encrypt( + const ObserverPtr& observer, + const CryptoAlgorithm& algo, + const Alias& keyAlias, + const Password& password, + const RawBuffer& plain); + + void decrypt( + const ObserverPtr& observer, + const CryptoAlgorithm& algo, + const Alias& keyAlias, + const Password& password, + const RawBuffer& encrypted); + private: std::unique_ptr m_impl; }; diff --git a/src/manager/client-async/client-manager-async-impl.cpp b/src/manager/client-async/client-manager-async-impl.cpp index 2a37c24..fb7bc8a 100644 --- a/src/manager/client-async/client-manager-async-impl.cpp +++ b/src/manager/client-async/client-manager-async-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2015 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. @@ -382,4 +382,36 @@ void ManagerAsync::Impl::observerCheck(const ManagerAsync::ObserverPtr& observer throw std::invalid_argument("Empty observer"); } +void ManagerAsync::Impl::crypt( + const ObserverPtr& observer, + const CryptoAlgorithm& algo, + const Alias& keyAlias, + const Password& password, + const RawBuffer& input, + bool encryption) +{ + observerCheck(observer); + if (input.empty() || keyAlias.empty()) + return observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + + try_catch_async([&] { + AliasSupport helper(keyAlias); + CryptoAlgorithmSerializable cas(algo); + m_counter++; + + auto send = MessageBuffer::Serialize( + static_cast(encryption?EncryptionCommand::ENCRYPT:EncryptionCommand::DECRYPT), + m_counter, + cas, + helper.getName(), + helper.getLabel(), + password, + input); + thread()->sendMessage(AsyncRequest(observer, + SERVICE_SOCKET_ENCRYPTION, + send.Pop(), + m_counter)); + }, [&observer](int error){ observer->ReceivedError(error); } ); +} + } // namespace CKM diff --git a/src/manager/client-async/client-manager-async-impl.h b/src/manager/client-async/client-manager-async-impl.h index d6bf0cf..02c132d 100644 --- a/src/manager/client-async/client-manager-async-impl.h +++ b/src/manager/client-async/client-manager-async-impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2015 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. @@ -154,6 +154,14 @@ public: }, [&observer](int error){ observer->ReceivedError(error); } ); } + void crypt( + const ObserverPtr& observer, + const CryptoAlgorithm& algo, + const Alias& keyAlias, + const Password& password, + const RawBuffer& input, + bool encryption); + private: template diff --git a/src/manager/client-async/client-manager-async.cpp b/src/manager/client-async/client-manager-async.cpp index d97cfd9..f79d12b 100644 --- a/src/manager/client-async/client-manager-async.cpp +++ b/src/manager/client-async/client-manager-async.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2015 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. @@ -258,5 +258,25 @@ void ManagerAsync::setPermission(const ObserverPtr& observer, m_impl->setPermission(observer, alias, accessor, permissionMask); } +void ManagerAsync::encrypt( + const ObserverPtr& observer, + const CryptoAlgorithm& algo, + const Alias& keyAlias, + const Password& password, + const RawBuffer& plain) +{ + m_impl->crypt(observer, algo, keyAlias, password, plain, true); +} + +void ManagerAsync::decrypt( + const ObserverPtr& observer, + const CryptoAlgorithm& algo, + const Alias& keyAlias, + const Password& password, + const RawBuffer& encrypted) +{ + m_impl->crypt(observer, algo, keyAlias, password, encrypted, false); +} + } // namespace CKM diff --git a/src/manager/client-async/encryption-receiver.cpp b/src/manager/client-async/encryption-receiver.cpp new file mode 100644 index 0000000..a406c0a --- /dev/null +++ b/src/manager/client-async/encryption-receiver.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2000 - 2015 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 encryption-receiver.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include +#include +#include + +namespace CKM { + +EncryptionReceiver::EncryptionReceiver(MessageBuffer& buffer, AsyncRequest::Map& requests) : + m_buffer(buffer), + m_requests(requests) +{ +} + +void EncryptionReceiver::processResponse() +{ + int command = 0; + int id = 0; + int retCode; + RawBuffer output; + m_buffer.Deserialize(command, id, retCode, output); + + auto it = m_requests.find(id); + if (it == m_requests.end()) { + LogError("Request with id " << id << " not found!"); + ThrowMsg(BadResponse, "Request with id " << id << " not found!"); + } + + // let it throw + AsyncRequest req = std::move(m_requests.at(id)); + m_requests.erase(id); + + switch (static_cast(command)) { + case EncryptionCommand::ENCRYPT: + if (retCode == CKM_API_SUCCESS) + req.observer->ReceivedEncrypted(std::move(output)); + else + req.observer->ReceivedError(retCode); + break; + case EncryptionCommand::DECRYPT: + if (retCode == CKM_API_SUCCESS) + req.observer->ReceivedDecrypted(std::move(output)); + else + req.observer->ReceivedError(retCode); + break; + default: + LogError("Unknown command id: " << command); + ThrowMsg(BadResponse, "Unknown command id: " << command); + break; + } +} + +} /* namespace CKM */ diff --git a/src/manager/client-async/encryption-receiver.h b/src/manager/client-async/encryption-receiver.h new file mode 100644 index 0000000..9995a31 --- /dev/null +++ b/src/manager/client-async/encryption-receiver.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2000 - 2015 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 encryption-receiver.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#pragma once + +#include +#include +#include +#include + +namespace CKM { + +class EncryptionReceiver : public IReceiver +{ +public: + EncryptionReceiver(MessageBuffer& buffer, AsyncRequest::Map& reqMap); + virtual ~EncryptionReceiver() {} + + NONCOPYABLE(EncryptionReceiver); + + void processResponse(); + +private: + MessageBuffer& m_buffer; + AsyncRequest::Map& m_requests; +}; + +} /* namespace CKM */ diff --git a/src/manager/client-async/ocsp-receiver.cpp b/src/manager/client-async/ocsp-receiver.cpp index f07883e..3b4af1a 100644 --- a/src/manager/client-async/ocsp-receiver.cpp +++ b/src/manager/client-async/ocsp-receiver.cpp @@ -30,7 +30,7 @@ OcspReceiver::OcspReceiver(MessageBuffer& buffer, AsyncRequest::Map& requests) : { } -void OcspReceiver::parseResponse() +void OcspReceiver::processResponse() { int id = 0, retCode = 0, ocspStatus = 0; m_buffer.Deserialize(id, retCode, ocspStatus); diff --git a/src/manager/client-async/ocsp-receiver.h b/src/manager/client-async/ocsp-receiver.h index bd6bf7b..93d2dec 100644 --- a/src/manager/client-async/ocsp-receiver.h +++ b/src/manager/client-async/ocsp-receiver.h @@ -36,7 +36,7 @@ public: NONCOPYABLE(OcspReceiver); - void parseResponse(); + void processResponse(); private: MessageBuffer& m_buffer; diff --git a/src/manager/client-async/receiver.h b/src/manager/client-async/receiver.h index 106a93b..cac1608 100644 --- a/src/manager/client-async/receiver.h +++ b/src/manager/client-async/receiver.h @@ -27,7 +27,7 @@ class IReceiver { public: DECLARE_EXCEPTION_TYPE(CKM::Exception, BadResponse); - virtual void parseResponse() = 0; + virtual void processResponse() = 0; virtual ~IReceiver() {}; }; diff --git a/src/manager/client-async/service.cpp b/src/manager/client-async/service.cpp index 55c3be2..39a4379 100644 --- a/src/manager/client-async/service.cpp +++ b/src/manager/client-async/service.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2015 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,7 @@ #include #include +#include #include namespace CKM { @@ -186,12 +187,14 @@ void Service::receiveData() receiver.reset(new StorageReceiver(*m_responseBuffer, m_responseMap)); else if (m_interface == SERVICE_SOCKET_OCSP) receiver.reset(new OcspReceiver(*m_responseBuffer, m_responseMap)); + else if (m_interface == SERVICE_SOCKET_ENCRYPTION) + receiver.reset(new EncryptionReceiver(*m_responseBuffer, m_responseMap)); else { LogError("Unknown service " << m_interface); serviceError(CKM_API_ERROR_RECV_FAILED); return; } - receiver->parseResponse(); + receiver->processResponse(); if (m_responseMap.empty()) watch(m_sendQueue.empty()?0:POLLOUT); diff --git a/src/manager/client-async/storage-receiver.cpp b/src/manager/client-async/storage-receiver.cpp index a15e0a3..15bee0b 100644 --- a/src/manager/client-async/storage-receiver.cpp +++ b/src/manager/client-async/storage-receiver.cpp @@ -35,7 +35,7 @@ StorageReceiver::StorageReceiver(MessageBuffer& buffer, AsyncRequest::Map& reque { } -void StorageReceiver::parseResponse() +void StorageReceiver::processResponse() { int command = 0, id = 0; m_buffer.Deserialize(command, id); diff --git a/src/manager/client-async/storage-receiver.h b/src/manager/client-async/storage-receiver.h index c838b3d..98847b6 100644 --- a/src/manager/client-async/storage-receiver.h +++ b/src/manager/client-async/storage-receiver.h @@ -37,7 +37,7 @@ public: NONCOPYABLE(StorageReceiver); - void parseResponse(); + void processResponse(); private: void parseGetCommand(); -- 2.7.4 From 488237a24e8ae3b1a82015dd7a7b88f4609d65ef Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Thu, 9 Jul 2015 15:18:01 +0200 Subject: [PATCH 10/16] Remove unnecessary argument names in function typedef [Problem] Unnecessary argument names in function typedef [Solution] Names removed [Verification] Successfull compilation Change-Id: I32255580b6b9e9c386493adb94f50e2f77b48661 --- src/manager/client-capi/ckmc-manager.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/manager/client-capi/ckmc-manager.cpp b/src/manager/client-capi/ckmc-manager.cpp index d971943..0fe3b94 100644 --- a/src/manager/client-capi/ckmc-manager.cpp +++ b/src/manager/client-capi/ckmc-manager.cpp @@ -117,11 +117,11 @@ ckmc_cert_list_s *_toNewCkmCertList(const CKM::CertificateShPtrVector &certVecto return start; } -typedef int (CKM::Manager::*cryptoFn)(const CKM::CryptoAlgorithm &algo, - const CKM::Alias &keyAlias, - const CKM::Password &password, - const CKM::RawBuffer& plain, - CKM::RawBuffer& encrypted); +typedef int (CKM::Manager::*cryptoFn)(const CKM::CryptoAlgorithm&, + const CKM::Alias&, + const CKM::Password&, + const CKM::RawBuffer&, + CKM::RawBuffer&); int _cryptoOperation(cryptoFn operation, const ckmc_param_list_s *params, -- 2.7.4 From f459c3382caf8fff147c5ca9623c09432a21f530 Mon Sep 17 00:00:00 2001 From: Bartlomiej Grzelewski Date: Wed, 1 Jul 2015 16:02:45 +0200 Subject: [PATCH 11/16] Update implementation of Stringify. Change-Id: Id237fe33a435be9ab7b28ad223e00bca23a95fc9 --- src/manager/common/exception.h | 2 +- src/manager/common/stringify.h | 21 ++++++++++++--------- src/manager/service/file-lock.cpp | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/manager/common/exception.h b/src/manager/common/exception.h index c174085..de4123a 100644 --- a/src/manager/common/exception.h +++ b/src/manager/common/exception.h @@ -78,7 +78,7 @@ class COMMON_API DefineException : public Exception { public: template DefineException(const char *path, const char *function, int line, const Args&... args) - : Exception(path, function, line, Stringify()(args...)) + : Exception(path, function, line, Stringify::Merge(args...)) { Before(m_path, m_function, m_line, DefineException::error(), m_message); } diff --git a/src/manager/common/stringify.h b/src/manager/common/stringify.h index d989f44..fbe2245 100644 --- a/src/manager/common/stringify.h +++ b/src/manager/common/stringify.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2015 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. @@ -31,35 +31,38 @@ class StringifyBasic; template <> class StringifyBasic { + StringifyBasic() = delete; public: - std::string operator()() { + static std::string Merge() { return std::string(); } template - std::string operator()(const Args&...){ + static std::string Merge(const Args&...){ return std::string(); } }; template <> class StringifyBasic { - void concatenate(std::ostringstream&) {} + StringifyBasic() = delete; + + static void Concatenate(std::ostringstream&) {} template - void concatenate(std::ostringstream& stream, const t& arg1, const Args&... args) { + static void Concatenate(std::ostringstream& stream, const t& arg1, const Args&... args) { stream << arg1; - concatenate(stream, args...); + Concatenate(stream, args...); } public: - std::string operator()() { + static std::string Merge() { return std::string(); } template - std::string operator()(const T& arg1, const Args&... args){ + static std::string Merge(const T& arg1, const Args&... args) { std::ostringstream stream; - concatenate(stream, arg1, args...); + Concatenate(stream, arg1, args...); return stream.str(); } }; diff --git a/src/manager/service/file-lock.cpp b/src/manager/service/file-lock.cpp index 41ce574..3bc6e38 100644 --- a/src/manager/service/file-lock.cpp +++ b/src/manager/service/file-lock.cpp @@ -41,7 +41,7 @@ namespace { template std::runtime_error io_exception(const Args&... args) { - return std::runtime_error(Stringify()(args...)); + return std::runtime_error(Stringify::Merge(args...)); }; } // namespace anonymous -- 2.7.4 From 23c59abc4f7af57d20f871b5882d972d4e31f850 Mon Sep 17 00:00:00 2001 From: Bartlomiej Grzelewski Date: Tue, 4 Aug 2015 15:45:41 +0200 Subject: [PATCH 12/16] Version 0.1.15 Change-Id: I52277c8cf9086d276379282971987d0fcead5ff0 --- packaging/key-manager.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec index f6d52d8..4466607 100644 --- a/packaging/key-manager.spec +++ b/packaging/key-manager.spec @@ -1,6 +1,6 @@ Name: key-manager Summary: Central Key Manager and utilities -Version: 0.1.14 +Version: 0.1.15 Release: 1 Group: System/Security License: Apache-2.0 -- 2.7.4 From 15d8fd29ebaaad00e242494c23b240bf1f72113e Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 10 Jul 2015 11:05:42 +0200 Subject: [PATCH 13/16] Call import & destroy on store [Problem] Data is not imported to store during row creation and is not destroyed in it during row removal. [Solution] Import and destroy are called. [Verification] Run ckm-tests --output=text Change-Id: I364c98790fa4cffc408f05b641712aaec0d4955c --- src/manager/crypto/platform/decider.cpp | 44 ++++++++--------- src/manager/crypto/platform/decider.h | 1 - src/manager/service/ckm-logic.cpp | 83 +++++++++++++++++++++------------ src/manager/service/ckm-logic.h | 2 + src/manager/service/db-row.h | 12 ++--- 5 files changed, 84 insertions(+), 58 deletions(-) diff --git a/src/manager/crypto/platform/decider.cpp b/src/manager/crypto/platform/decider.cpp index bcff97e..6c63c49 100644 --- a/src/manager/crypto/platform/decider.cpp +++ b/src/manager/crypto/platform/decider.cpp @@ -31,6 +31,29 @@ namespace CKM { namespace Crypto { +namespace { +CryptoBackend chooseCryptoBackend(DataType dataType, bool exportable) { +// The list of items that MUST be support by OpenSSL + if (dataType.isCertificate()) + return CryptoBackend::OpenSSL; + + if (dataType.isBinaryData()) + return CryptoBackend::OpenSSL; + + if (exportable) + return CryptoBackend::OpenSSL; + +// This is the place where we can use trust zone backend +// Examples: +// +// if (dataType.isKeyPrivate()) +// return CryptoBackend::TrustZone; + +// This item does not met Trust Zone requirements. Let's use software backend + return CryptoBackend::OpenSSL; +} +} // namespace + Decider::Decider() : m_swStore(new SW::Store(CryptoBackend::OpenSSL)) , m_tzStore(new TZ::Store(CryptoBackend::TrustZone)) @@ -58,27 +81,6 @@ GStore& Decider::getStore(DataType data, bool exportable) const { return getStore(chooseCryptoBackend(data, exportable)); } -CryptoBackend Decider::chooseCryptoBackend(DataType dataType, bool exportable) const { -// The list of items that MUST be support by OpenSSL - if (dataType.isCertificate()) - return CryptoBackend::OpenSSL; - - if (dataType.isBinaryData()) - return CryptoBackend::OpenSSL; - - if (exportable) - return CryptoBackend::OpenSSL; - -// This is the place where we can use trust zone backend -// Examples: -// -// if (dataType.isKeyPrivate()) -// return CryptoBackend::TrustZone; - -// This item does not met Trust Zone requirements. Let's use software backend - return CryptoBackend::OpenSSL; -} - } // namespace Crypto } // namespace CKM diff --git a/src/manager/crypto/platform/decider.h b/src/manager/crypto/platform/decider.h index 351f4e2..6be147c 100644 --- a/src/manager/crypto/platform/decider.h +++ b/src/manager/crypto/platform/decider.h @@ -37,7 +37,6 @@ public: Decider(); GStore& getStore(const Token &token) const; GStore& getStore(DataType data, bool exportable) const; - CryptoBackend chooseCryptoBackend(DataType data, bool exportable) const; virtual ~Decider(){} protected: diff --git a/src/manager/service/ckm-logic.cpp b/src/manager/service/ckm-logic.cpp index 3ce1e1c..c5915e8 100644 --- a/src/manager/service/ckm-logic.cpp +++ b/src/manager/service/ckm-logic.cpp @@ -417,8 +417,10 @@ DB::Row CKMLogic::createEncryptedRow( const RawBuffer &data, const Policy &policy) const { - DB::Row row(name, label, static_cast(policy.extractable), dataType, data, static_cast(data.size())); - row.backendId = m_decider.chooseCryptoBackend(dataType, policy.extractable); + Crypto::GStore& store = m_decider.getStore(dataType, policy.extractable); + Token token = store.import(dataType, data); + + DB::Row row(std::move(token), name, label, static_cast(policy.extractable)); // do not encrypt data with password during cc_mode on if(m_accessControl.isCCMode()) { @@ -649,15 +651,34 @@ int CKMLogic::removeDataHelper( return retCode; } - auto erased = handler.database.deleteRow(name, ownerLabel); - // check if the data existed or not - if(erased) - transaction.commit(); - else { + // get all matching rows + DB::RowVector rows; + handler.database.getRows(name, ownerLabel, DataType::DB_FIRST, DataType::DB_LAST, rows); + if (rows.empty()) { LogDebug("No row for given name and label"); return CKM_API_ERROR_DB_ALIAS_UNKNOWN; } + // load app key if needed + retCode = loadAppKey(handler, rows.front().ownerLabel); + if(CKM_API_SUCCESS != retCode) + return retCode; + + // destroy it in store + for(auto& r : rows) { + /* + * TODO: If row is encrypted with user password we won't be able to decrypt it (tz id). + * Encryption/decryption with user password and with app key should both be done inside the + * store (import, getKey and generateXKey). + */ + handler.crypto.decryptRow(Password(), r); + m_decider.getStore(r.dataType, r.exportable).destroy(r); + } + + // delete row in db + handler.database.deleteRow(name, ownerLabel); + transaction.commit(); + return CKM_API_SUCCESS; } @@ -809,18 +830,12 @@ int CKMLogic::readDataHelper( if(CKM_API_SUCCESS != retCode) return retCode; + // load app key if needed + retCode = loadAppKey(handler, firstRow.ownerLabel); + if(CKM_API_SUCCESS != retCode) + return retCode; + // decrypt row - if (!handler.crypto.haveKey(firstRow.ownerLabel)) { - RawBuffer key; - auto key_optional = handler.database.getKey(firstRow.ownerLabel); - if(!key_optional) { - LogError("No key for given label in database"); - return CKM_API_ERROR_DB_ERROR; - } - key = *key_optional; - key = handler.keyProvider.getPureDEK(key); - handler.crypto.pushKey(firstRow.ownerLabel, key); - } for(auto &row : rows) handler.crypto.decryptRow(password, row); @@ -855,18 +870,12 @@ int CKMLogic::readDataHelper( if(CKM_API_SUCCESS != retCode) return retCode; + // load app key if needed + retCode = loadAppKey(handler, row.ownerLabel); + if(CKM_API_SUCCESS != retCode) + return retCode; + // decrypt row - if (!handler.crypto.haveKey(row.ownerLabel)) { - RawBuffer key; - auto key_optional = handler.database.getKey(row.ownerLabel); - if(!key_optional) { - LogError("No key for given label in database"); - return CKM_API_ERROR_DB_ERROR; - } - key = *key_optional; - key = handler.keyProvider.getPureDEK(key); - handler.crypto.pushKey(row.ownerLabel, key); - } handler.crypto.decryptRow(password, row); return CKM_API_SUCCESS; @@ -1620,5 +1629,21 @@ RawBuffer CKMLogic::setPermission( return MessageBuffer::Serialize(command, msgID, retCode).Pop(); } +int CKMLogic::loadAppKey(UserData& handle, const Label& appLabel) +{ + if (!handle.crypto.haveKey(appLabel)) { + RawBuffer key; + auto key_optional = handle.database.getKey(appLabel); + if(!key_optional) { + LogError("No key for given label in database"); + return CKM_API_ERROR_DB_ERROR; + } + key = *key_optional; + key = handle.keyProvider.getPureDEK(key); + handle.crypto.pushKey(appLabel, key); + } + return CKM_API_SUCCESS; +} + } // namespace CKM diff --git a/src/manager/service/ckm-logic.h b/src/manager/service/ckm-logic.h index b6dc1eb..c73fc74 100644 --- a/src/manager/service/ckm-logic.h +++ b/src/manager/service/ckm-logic.h @@ -378,6 +378,8 @@ private: int resetUserPasswordHelper(uid_t user, const Password &newPassword); + int loadAppKey(UserData& handle, const Label& appLabel); + std::map m_userDataMap; AccessControl m_accessControl; Crypto::Decider m_decider; diff --git a/src/manager/service/db-row.h b/src/manager/service/db-row.h index 333f5cc..04907af 100644 --- a/src/manager/service/db-row.h +++ b/src/manager/service/db-row.h @@ -32,19 +32,17 @@ namespace DB { struct Row : public Token { Row() = default; - Row(const Name &pName, + Row(Token token, + const Name &pName, const Label &pLabel, - int pExportable, - DataType pDataType, - const RawBuffer &pData, - int pDataSize) : - Token(CryptoBackend::None, pDataType, pData) + int pExportable) : + Token(std::move(token)) , name(pName) , ownerLabel(pLabel) , exportable(pExportable) , algorithmType(DBCMAlgType::NONE) , encryptionScheme(0) - , dataSize(pDataSize) + , dataSize(data.size()) {} Name name; -- 2.7.4 From d53051801c957b57900be153091a7396688d048f Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 10 Jul 2015 12:31:40 +0200 Subject: [PATCH 14/16] Extend asynchronous API socket timeout [Problem] Encryption and decryption may take much longer than 10s. In such case it fails because of timeout. [Solution] Extend timeout to 60s. [Verification] Run ckm-tests --group=CKM_ENCRYPTION_DECRYPTION Change-Id: I14c4084d7c44d310ab69649bd55e608f1b627204 --- src/manager/client-async/descriptor-set.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manager/client-async/descriptor-set.h b/src/manager/client-async/descriptor-set.h index 7e166ba..7c70be1 100644 --- a/src/manager/client-async/descriptor-set.h +++ b/src/manager/client-async/descriptor-set.h @@ -80,7 +80,7 @@ public: * @throws Timeout exception in case of timeout * @throws InternalError in case of other error */ - void wait(int timeout_ms = 10000); + void wait(int timeout_ms = 60000); /* * Removes and closes all descriptors */ -- 2.7.4 From a13c57abd4d4c6e90ed1e66f74f582751eded47f Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 3 Jul 2015 16:51:22 +0200 Subject: [PATCH 15/16] Fix potential buffer overflow error CID: 40674 Change backported from security-server repository. Change-Id: I7613de85e79bc5627336c70842c64bd35eb36468 --- src/manager/main/socket-manager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/manager/main/socket-manager.cpp b/src/manager/main/socket-manager.cpp index 44a7d3c..c0bc93f 100644 --- a/src/manager/main/socket-manager.cpp +++ b/src/manager/main/socket-manager.cpp @@ -488,6 +488,14 @@ int SocketManager::CreateDomainSocketHelp( { int sockfd; + if(desc.serviceHandlerPath.size()*sizeof(decltype(desc.serviceHandlerPath)::value_type) >= + sizeof(static_cast(0)->sun_path)) + { + LogError("Service handler path too long: " << desc.serviceHandlerPath.size()); + ThrowMsg(Exception::InitFailed, + "Service handler path too long: " << desc.serviceHandlerPath.size()); + } + if (-1 == (sockfd = socket(AF_UNIX, SOCK_STREAM, 0))) { int err = errno; LogError("Error in socket: " << GetErrnoString(err)); -- 2.7.4 From 3a018155ff07445483178c7a1f668e69c9373705 Mon Sep 17 00:00:00 2001 From: Bartlomiej Grzelewski Date: Mon, 17 Aug 2015 12:04:21 +0200 Subject: [PATCH 16/16] Cleaning environment from systemd flags. Change-Id: I3065468d9948ccec19679de0eaa3a7e8046abc38 --- src/manager/main/socket-manager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/manager/main/socket-manager.cpp b/src/manager/main/socket-manager.cpp index c0bc93f..b94a38b 100644 --- a/src/manager/main/socket-manager.cpp +++ b/src/manager/main/socket-manager.cpp @@ -339,8 +339,7 @@ void SocketManager::ReadyForWrite(int sock) { void SocketManager::MainLoop() { // remove evironment values passed by systemd - // uncomment it after removing old security-server code - // sd_listen_fds(1); + sd_listen_fds(1); // Daemon is ready to work. sd_notify(0, "READY=1"); -- 2.7.4