Ignore failing row decryption during data removal
[platform/core/security/key-manager.git] / src / manager / service / ckm-logic.cpp
index a173cd7..217d0cd 100644 (file)
@@ -191,7 +191,7 @@ UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incomi
         if (0 == m_userDataMap.count(cred.clientUid))
             ThrowErr(Exc::DatabaseLocked, "database with UID: ", cred.clientUid, " locked");
 
-        if (0 != incoming_label.compare(LABEL_SYSTEM_DB))
+        if (0 != incoming_label.compare(OWNER_ID_SYSTEM))
             return m_userDataMap[cred.clientUid];
     }
 
@@ -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;
     }
 
@@ -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()) {
@@ -449,7 +451,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 +461,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 +634,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;
     }
 
@@ -649,15 +651,38 @@ int CKMLogic::removeDataHelper(
         return retCode;
     }
 
-    auto erased = handler.database.deleteRow(name, ownerLabel);
-    // check if the data existed or not
-    if(erased)
-        transaction.commit();
-    else {
-        LogError("No row for given name and label");
+    // 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).
+         */
+        try {
+            handler.crypto.decryptRow(Password(), r);
+        } catch (const Exc::AuthenticationFailed&) {
+            LogDebug("Authentication failed when removing data. Ignored.");
+        }
+        m_decider.getStore(r.dataType, r.exportable).destroy(r);
+    }
+
+    // delete row in db
+    handler.database.deleteRow(name, ownerLabel);
+    transaction.commit();
+
     return CKM_API_SUCCESS;
 }
 
@@ -711,7 +736,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 +780,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;
     }
 
@@ -809,18 +834,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 +874,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;
@@ -1038,7 +1051,7 @@ RawBuffer CKMLogic::getDataList(
         {
             // lookup system DB
             retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
-                                                    LABEL_SYSTEM_DB),
+                                                    OWNER_ID_SYSTEM),
                                         dataType,
                                         systemVector);
         }
@@ -1085,7 +1098,7 @@ int CKMLogic::saveDataHelper(
 
     // use client label if not explicitly provided
     const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
-    if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
+    if( m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM)!=0)
         return CKM_API_ERROR_INPUT_PARAM;
 
     // check if save is possible
@@ -1114,7 +1127,7 @@ int CKMLogic::saveDataHelper(
 
     // use client label if not explicitly provided
     const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
-    if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
+    if( m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM)!=0)
         return CKM_API_ERROR_INPUT_PARAM;
 
     // check if save is possible
@@ -1145,6 +1158,7 @@ int CKMLogic::createKeyAESHelper(
     const PolicySerializable &policy)
 {
     CryptoAlgorithm keyGenAlgorithm;
+    keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
     keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size);
     Token key = m_decider.getStore(DataType::KEY_AES, policy.extractable).generateSKey(keyGenAlgorithm);
 
@@ -1317,10 +1331,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,
@@ -1561,7 +1583,7 @@ int CKMLogic::setPermissionHelper(
         return CKM_API_ERROR_INPUT_PARAM;
 
     // system database does not support write/remove permissions
-    if ((0 == ownerLabel.compare(LABEL_SYSTEM_DB)) &&
+    if ((0 == ownerLabel.compare(OWNER_ID_SYSTEM)) &&
         (permissionMask & Permission::REMOVE))
         return CKM_API_ERROR_INPUT_PARAM;
 
@@ -1611,5 +1633,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