Call import & destroy on store 92/43592/7
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 10 Jul 2015 09:05:42 +0000 (11:05 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 12 Aug 2015 12:30:04 +0000 (05:30 -0700)
[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
src/manager/crypto/platform/decider.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/db-row.h

index bcff97e..6c63c49 100644 (file)
 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
 
index 351f4e2..6be147c 100644 (file)
@@ -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:
index 3ce1e1c..c5915e8 100644 (file)
@@ -417,8 +417,10 @@ DB::Row CKMLogic::createEncryptedRow(
     const RawBuffer &data,
     const Policy &policy) const
 {
-    DB::Row row(name, label, static_cast<int>(policy.extractable), dataType, data, static_cast<int>(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<int>(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
 
index b6dc1eb..c73fc74 100644 (file)
@@ -378,6 +378,8 @@ private:
 
     int resetUserPasswordHelper(uid_t user, const Password &newPassword);
 
+    int loadAppKey(UserData& handle, const Label& appLabel);
+
     std::map<uid_t, UserData> m_userDataMap;
     AccessControl m_accessControl;
     Crypto::Decider m_decider;
index 333f5cc..04907af 100644 (file)
@@ -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;