Protocol refactoring.
[platform/core/security/key-manager.git] / src / manager / service / ckm-logic.cpp
index 0a6893f..2dc20a7 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,15 +417,12 @@ 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);
 
     // do not encrypt data with password during cc_mode on
-    if(m_accessControl.isCCMode()) {
-        crypto.encryptRow("", row);
-    } else {
-        crypto.encryptRow(policy.password, row);
-    }
+    Token token = store.import(dataType, data, m_accessControl.isCCMode() ? "" : policy.password);
+    DB::Row row(std::move(token), name, label, static_cast<int>(policy.extractable));
+    crypto.encryptRow(row);
     return row;
 }
 
@@ -449,7 +446,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 +456,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();
@@ -508,14 +505,15 @@ int CKMLogic::getKeyForService(
         const Name &name,
         const Label &label,
         const Password &pass,
-        Crypto::GKeyShPtr &key)
+        Crypto::GObjShPtr &key)
 {
     DB::Row row;
     try {
         // Key is for internal service use. It won't be exported to the client
-        int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, label, pass, row);
+        Crypto::GObjUPtr obj;
+        int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, label, pass, obj);
         if (retCode == CKM_API_SUCCESS)
-            key = m_decider.getStore(row).getKey(row);
+            key = std::move(obj);
         return retCode;
     } catch (const DB::Crypto::Exception::Base &e) {
         LogError("DB::Crypto failed with message: " << e.GetMessage());
@@ -632,7 +630,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 +647,33 @@ 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) {
+        try {
+            handler.crypto.decryptRow(Password(), r);
+            m_decider.getStore(r).destroy(r);
+        } catch (const Exc::AuthenticationFailed&) {
+            LogDebug("Authentication failed when removing data. Ignored.");
+        }
+    }
+
+    // delete row in db
+    handler.database.deleteRow(name, ownerLabel);
+    transaction.commit();
+
     return CKM_API_SUCCESS;
 }
 
@@ -711,7 +727,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 +771,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;
     }
 
@@ -778,6 +794,45 @@ int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
     return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
 }
 
+Crypto::GObjUPtr CKMLogic::rowToObject(
+    UserData& handler,
+    DB::Row row,
+    const Password& password)
+{
+    Crypto::GStore& store = m_decider.getStore(row);
+
+    Password pass = m_accessControl.isCCMode() ? "" : password;
+
+    // decrypt row
+    Crypto::GObjUPtr obj;
+    if(CryptoLogic::getSchemeVersion(row.encryptionScheme) == CryptoLogic::ENCRYPTION_V2) {
+        handler.crypto.decryptRow(Password(), row);
+
+        obj = store.getObject(row, pass);
+    } else {
+        // decrypt entirely with old scheme: b64(pass(appkey(data))) -> data
+        handler.crypto.decryptRow(pass, row);
+        // destroy it in store
+        store.destroy(row);
+
+        // import it to store with new scheme: data -> pass(data)
+        Token token = store.import(row.dataType,row.data, pass);
+
+        // get it from the store (it can be different than the data we imported into store)
+        obj = store.getObject(token, pass);
+
+        // update row with new token
+        *static_cast<Token*>(&row) = std::move(token);
+
+        // encrypt it with app key: pass(data) -> b64(appkey(pass(data))
+        handler.crypto.encryptRow(row);
+
+        // update it in db
+        handler.database.updateRow(row);
+    }
+    return obj;
+}
+
 int CKMLogic::readDataHelper(
     bool exportFlag,
     const Credentials &cred,
@@ -785,7 +840,7 @@ int CKMLogic::readDataHelper(
     const Name &name,
     const Label &label,
     const Password &password,
-    DB::RowVector &rows)
+    Crypto::GObjUPtrVector &objs)
 {
     auto &handler = selectDatabase(cred, label);
 
@@ -797,6 +852,7 @@ int CKMLogic::readDataHelper(
 
     // read rows
     DB::Crypto::Transaction transaction(&handler.database);
+    DB::RowVector rows;
     int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
     if(CKM_API_SUCCESS != retCode)
         return retCode;
@@ -809,20 +865,16 @@ 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);
+        objs.push_back(rowToObject(handler, std::move(row), password));
+    // rowToObject may modify db
+    transaction.commit();
 
     return CKM_API_SUCCESS;
 }
@@ -834,7 +886,21 @@ int CKMLogic::readDataHelper(
     const Name &name,
     const Label &label,
     const Password &password,
-    DB::Row &row)
+    Crypto::GObjUPtr &obj)
+{
+    DataType objDataType;
+    return readDataHelper(exportFlag, cred, dataType, name, label, password, obj, objDataType);
+}
+
+int CKMLogic::readDataHelper(
+    bool exportFlag,
+    const Credentials &cred,
+    DataType dataType,
+    const Name &name,
+    const Label &label,
+    const Password &password,
+    Crypto::GObjUPtr &obj,
+    DataType& objDataType)
 {
     auto &handler = selectDatabase(cred, label);
 
@@ -846,28 +912,26 @@ int CKMLogic::readDataHelper(
 
     // read row
     DB::Crypto::Transaction transaction(&handler.database);
+    DB::Row row;
     int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
     if(CKM_API_SUCCESS != retCode)
         return retCode;
 
+    objDataType = row.dataType;
+
     // check access rights
     retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
     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);
+    // load app key if needed
+    retCode = loadAppKey(handler, row.ownerLabel);
+    if(CKM_API_SUCCESS != retCode)
+        return retCode;
+
+    obj = rowToObject(handler, std::move(row), password);
+    // rowToObject may modify db
+    transaction.commit();
 
     return CKM_API_SUCCESS;
 }
@@ -882,9 +946,13 @@ RawBuffer CKMLogic::getData(
 {
     int retCode = CKM_API_SUCCESS;
     DB::Row row;
+    DataType objDataType;
 
     try {
-        retCode = readDataHelper(true, cred, dataType, name, label, password, row);
+        Crypto::GObjUPtr obj;
+        retCode = readDataHelper(true, cred, dataType, name, label, password, obj, objDataType);
+        if(retCode == CKM_API_SUCCESS)
+            row.data = std::move(obj->getBinary());
     } catch (const DB::Crypto::Exception::Base &e) {
         LogError("DB::Crypto failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
@@ -903,7 +971,7 @@ RawBuffer CKMLogic::getData(
     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
                                              commandId,
                                              retCode,
-                                             static_cast<int>(row.dataType),
+                                             static_cast<int>(objDataType),
                                              row.data);
     return response.Pop();
 }
@@ -921,27 +989,27 @@ int CKMLogic::getPKCS12Helper(
     int retCode;
 
     // read private key (mandatory)
-    DB::Row privKeyRow;
-    retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, privKeyRow);
+    Crypto::GObjUPtr keyObj;
+    retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, keyObj);
     if(retCode != CKM_API_SUCCESS)
         return retCode;
-    privKey = CKM::Key::create(privKeyRow.data);
+    privKey = CKM::Key::create(keyObj->getBinary());
 
     // read certificate (mandatory)
-    DB::Row certRow;
-    retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certRow);
+    Crypto::GObjUPtr certObj;
+    retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certObj);
     if(retCode != CKM_API_SUCCESS)
         return retCode;
-    cert = CKM::Certificate::create(certRow.data, DataFormat::FORM_DER);
+    cert = CKM::Certificate::create(certObj->getBinary(), DataFormat::FORM_DER);
 
     // read CA cert chain (optional)
-    DB::RowVector rawCaChain;
-    retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, rawCaChain);
+    Crypto::GObjUPtrVector caChainObjs;
+    retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, caChainObjs);
     if(retCode != CKM_API_SUCCESS &&
        retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
         return retCode;
-    for(auto &rawCaCert : rawCaChain)
-        caChain.push_back(CKM::Certificate::create(rawCaCert.data, DataFormat::FORM_DER));
+    for(auto &caCertObj : caChainObjs)
+        caChain.push_back(CKM::Certificate::create(caCertObj->getBinary(), DataFormat::FORM_DER));
 
     // if anything found, return it
     if(privKey || cert || caChain.size()>0)
@@ -1038,7 +1106,7 @@ RawBuffer CKMLogic::getDataList(
         {
             // lookup system DB
             retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
-                                                    LABEL_SYSTEM_DB),
+                                                    OWNER_ID_SYSTEM),
                                         dataType,
                                         systemVector);
         }
@@ -1085,7 +1153,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 +1182,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
@@ -1144,17 +1212,33 @@ int CKMLogic::createKeyAESHelper(
     const Label &label,
     const PolicySerializable &policy)
 {
+    auto &handler = selectDatabase(cred, label);
+
+    // use client label if not explicitly provided
+    const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
+    if( m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM)!=0)
+        return CKM_API_ERROR_INPUT_PARAM;
+
+    // check if save is possible
+    DB::Crypto::Transaction transaction(&handler.database);
+    int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
+    if(retCode != CKM_API_SUCCESS)
+        return retCode;
+
+    // create key in store
     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);
-
-    return saveDataHelper(cred,
-                          name,
-                          label,
-                          DataType::KEY_AES,
-                          key.data,
-                          policy);
+    Token key = m_decider.getStore(DataType::KEY_AES, policy.extractable).generateSKey(keyGenAlgorithm, policy.password);
+
+    // save the data
+    DB::Row row(std::move(key), name, ownerLabel, static_cast<int>(policy.extractable));
+    handler.crypto.encryptRow(row);
+
+    handler.database.saveRow(row);
+
+    transaction.commit();
+    return CKM_API_SUCCESS;
 }
 
 
@@ -1178,32 +1262,41 @@ int CKMLogic::createKeyPairHelper(
     if(!dt.isKey())
         ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value.");
 
+    // use client label if not explicitly provided
+    const Label &ownerLabelPrv = labelPrivate.empty() ? cred.smackLabel : labelPrivate;
+    if( m_accessControl.isSystemService(cred) && ownerLabelPrv.compare(OWNER_ID_SYSTEM)!=0)
+        return CKM_API_ERROR_INPUT_PARAM;
+    const Label &ownerLabelPub = labelPublic.empty() ? cred.smackLabel : labelPublic;
+    if( m_accessControl.isSystemService(cred) && ownerLabelPub.compare(OWNER_ID_SYSTEM)!=0)
+        return CKM_API_ERROR_INPUT_PARAM;
+
     bool exportable = policyPrivate.extractable || policyPublic.extractable;
-    TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams);
+    TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams,
+                                                                     policyPrivate.password,
+                                                                     policyPublic.password);
 
     DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
     // in case the same database is used for private and public - the second
     // transaction will not be executed
     DB::Crypto::Transaction transactionPub(&handlerPub.database);
 
-    int retCode = saveDataHelper(cred,
-                             namePrivate,
-                             labelPrivate,
-                             keys.first.dataType,
-                             keys.first.data,
-                             policyPrivate);
-    if (CKM_API_SUCCESS != retCode)
+    int retCode;
+    retCode = checkSaveConditions(cred, handlerPriv, namePrivate, ownerLabelPrv);
+    if(retCode != CKM_API_SUCCESS)
         return retCode;
-
-    retCode = saveDataHelper(cred,
-                             namePublic,
-                             labelPublic,
-                             keys.second.dataType,
-                             keys.second.data,
-                             policyPublic);
-    if (CKM_API_SUCCESS != retCode)
+    retCode = checkSaveConditions(cred, handlerPub, namePrivate, ownerLabelPub);
+    if(retCode != CKM_API_SUCCESS)
         return retCode;
 
+    // save the data
+    DB::Row rowPrv(std::move(keys.first), namePrivate, ownerLabelPrv, static_cast<int>(policyPrivate.extractable));
+    handlerPriv.crypto.encryptRow(rowPrv);
+    handlerPriv.database.saveRow(rowPrv);
+
+    DB::Row rowPub(std::move(keys.second), namePublic, ownerLabelPub, static_cast<int>(policyPublic.extractable));
+    handlerPub.crypto.encryptRow(rowPub);
+    handlerPub.database.saveRow(rowPub);
+
     transactionPub.commit();
     transactionPriv.commit();
     return CKM_API_SUCCESS;
@@ -1288,18 +1381,34 @@ int CKMLogic::readCertificateHelper(
 {
     DB::Row row;
     for (auto &i: labelNameVector) {
-        int ec = readDataHelper(false, cred, DataType::CERTIFICATE, i.second, i.first, Password(), row);
+        // certificates can't be protected with custom user password
+        Crypto::GObjUPtr obj;
+        int ec;
+        ec = readDataHelper(true,
+                            cred,
+                            DataType::CERTIFICATE,
+                            i.second,
+                            i.first,
+                            Password(),
+                            obj);
         if (ec != CKM_API_SUCCESS)
             return ec;
-        certVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
+
+        certVector.emplace_back(obj->getBinary(), DataFormat::FORM_DER);
 
         // try to read chain certificates (if present)
-        DB::RowVector rawCaChain;
-        ec = readDataHelper(false, cred, DataType::DB_CHAIN_FIRST, i.second, i.first, CKM::Password(), rawCaChain);
+        Crypto::GObjUPtrVector caChainObjs;
+        ec = readDataHelper(true,
+                            cred,
+                            DataType::DB_CHAIN_FIRST,
+                            i.second,
+                            i.first,
+                            CKM::Password(),
+                            caChainObjs);
         if(ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
             return ec;
-        for(auto &rawCaCert : rawCaChain)
-            certVector.push_back(CertificateImpl(rawCaCert.data, DataFormat::FORM_DER));
+        for(auto &caCertObj : caChainObjs)
+            certVector.emplace_back(caCertObj->getBinary(), DataFormat::FORM_DER);
     }
     return CKM_API_SUCCESS;
 }
@@ -1318,10 +1427,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,
@@ -1457,21 +1574,18 @@ RawBuffer CKMLogic::createSignature(
         const Label & ownerLabel,
         const Password &password,           // password for private_key
         const RawBuffer &message,
-        const HashAlgorithm hash,
-        const RSAPaddingAlgorithm padding)
+        const CryptoAlgorithm &cryptoAlg)
 {
     DB::Row row;
     RawBuffer signature;
-    CryptoAlgorithm cryptoAlg;
-    cryptoAlg.setParam(ParamName::SV_HASH_ALGO, hash);
-    cryptoAlg.setParam(ParamName::SV_RSA_PADDING, padding);
 
     int retCode = CKM_API_SUCCESS;
 
     try {
-        retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
+        Crypto::GObjUPtr obj;
+        retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, obj);
         if(retCode == CKM_API_SUCCESS) {
-            signature = m_decider.getStore(row).getKey(row)->sign(cryptoAlg, message);
+            signature = obj->sign(cryptoAlg, message);
         }
     } catch (const DB::Crypto::Exception::Base &e) {
         LogError("DB::Crypto failed with message: " << e.GetMessage());
@@ -1498,28 +1612,24 @@ RawBuffer CKMLogic::verifySignature(
         const Password &password,           // password for public_key (optional)
         const RawBuffer &message,
         const RawBuffer &signature,
-        const HashAlgorithm hash,
-        const RSAPaddingAlgorithm padding)
+        const CryptoAlgorithm &params)
 {
     int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
 
     try {
         DB::Row row;
 
-        CryptoAlgorithm params;
-        params.setParam(ParamName::SV_HASH_ALGO, hash);
-        params.setParam(ParamName::SV_RSA_PADDING, padding);
-
         // try certificate first - looking for a public key.
         // in case of PKCS, pub key from certificate will be found first
         // rather than private key from the same PKCS.
-        retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
+        Crypto::GObjUPtr obj;
+        retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, obj);
         if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
-            retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
+            retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, obj);
         }
 
         if (retCode == CKM_API_SUCCESS) {
-            retCode = m_decider.getStore(row).getKey(row)->verify(params, message, signature);
+            retCode = obj->verify(params, message, signature);
         }
     } catch (const Exc::Exception &e) {
         retCode = e.error();
@@ -1562,7 +1672,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;
 
@@ -1612,5 +1722,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