From 15d8fd29ebaaad00e242494c23b240bf1f72113e Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 10 Jul 2015 11:05:42 +0200 Subject: [PATCH] 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