Deduplicate exception handling in CKMLogic a wee bit 54/243054/5
authorKonrad Lipinski <k.lipinski2@samsung.com>
Wed, 2 Sep 2020 17:55:07 +0000 (19:55 +0200)
committerKonrad Lipinski <k.lipinski2@samsung.com>
Wed, 16 Sep 2020 11:55:57 +0000 (13:55 +0200)
Change-Id: I330fc80d01393a7709fb3b4c05c563de96681e66

src/manager/service/ckm-logic.cpp

index f99451f..849654f 100644 (file)
@@ -71,6 +71,20 @@ namespace CKM {
 
 namespace {
 
+template <int ERROR_ON_CKM_EXCEPTION = CKM_API_ERROR_SERVER_ERROR, class F>
+int tryRet(F &&f)
+{
+       try {
+               static_assert(sizeof(int) == sizeof std::forward<F>(f)());
+               return std::forward<F>(f)();
+       } catch (const Exc::Exception &e) {
+               return e.error();
+       } catch (const CKM::Exception &e) {
+               LogError("CKM::Exception: " << e.GetMessage());
+               return ERROR_ON_CKM_EXCEPTION;
+       }
+}
+
 int toBinaryData(const Crypto::Data &input, Crypto::Data &output)
 {
        // verify the data integrity
@@ -261,9 +275,7 @@ int CKMLogic::unlockDatabase(uid_t user, const Password &password)
                        m_userDataMap[user].keyProvider.isInitialized())
                return CKM_API_SUCCESS;
 
-       int retCode = CKM_API_SUCCESS;
-
-       try {
+       int retCode = tryRet([&] {
                auto &handle = m_userDataMap[user];
 
                FileSystem fs(user);
@@ -295,12 +307,9 @@ int CKMLogic::unlockDatabase(uid_t user, const Password &password)
                        migrateSecureStorageData(false);
                else if (user == ADMIN_USER_DB_UID && SsMigration::hasData())
                        migrateSecureStorageData(true);
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
-       }
+
+               return CKM_API_SUCCESS;
+       });
 
        if (CKM_API_SUCCESS != retCode)
                m_userDataMap.erase(user);
@@ -398,18 +407,9 @@ RawBuffer CKMLogic::changeUserPassword(
        const Password &oldPassword,
        const Password &newPassword)
 {
-       int retCode = CKM_API_SUCCESS;
-
-       try {
-               retCode = changeUserPasswordHelper(user, oldPassword, newPassword);
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
-       }
-
-       return SerializeMessage(retCode);
+       return SerializeMessage(tryRet([&] {
+               return changeUserPasswordHelper(user, oldPassword, newPassword);
+       }));
 }
 
 int CKMLogic::resetUserPasswordHelper(
@@ -440,49 +440,32 @@ RawBuffer CKMLogic::resetUserPassword(
        uid_t user,
        const Password &newPassword)
 {
-       int retCode = CKM_API_SUCCESS;
-
-       try {
-               retCode = resetUserPasswordHelper(user, newPassword);
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
-       }
-
-       return SerializeMessage(retCode);
+       return SerializeMessage(tryRet([&] {
+               return resetUserPasswordHelper(user, newPassword);
+       }));
 }
 
 RawBuffer CKMLogic::removeApplicationData(const ClientId &owner)
 {
-       int retCode = CKM_API_SUCCESS;
+       return SerializeMessage(tryRet([&] {
+               if (owner.empty())
+                       return CKM_API_ERROR_INPUT_PARAM;
 
-       try {
-               if (owner.empty()) {
-                       retCode = CKM_API_ERROR_INPUT_PARAM;
-               } else {
-                       UidVector uids = FileSystem::getUIDsFromDBFile();
-
-                       for (auto userId : uids) {
-                               if (0 == m_userDataMap.count(userId)) {
-                                       FileSystem fs(userId);
-                                       fs.addRemovedApp(owner);
-                               } else {
-                                       auto &handle = m_userDataMap[userId];
-                                       handle.crypto.removeKey(owner);
-                                       handle.database.deleteKey(owner);
-                               }
+               UidVector uids = FileSystem::getUIDsFromDBFile();
+
+               for (auto userId : uids) {
+                       if (0 == m_userDataMap.count(userId)) {
+                               FileSystem fs(userId);
+                               fs.addRemovedApp(owner);
+                       } else {
+                               auto &handle = m_userDataMap[userId];
+                               handle.crypto.removeKey(owner);
+                               handle.database.deleteKey(owner);
                        }
                }
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
-       }
 
-       return SerializeMessage(retCode);
+               return CKM_API_SUCCESS;
+       }));
 }
 
 int CKMLogic::checkSaveConditions(
@@ -558,23 +541,15 @@ int CKMLogic::verifyAndSaveDataHelper(
        const Crypto::Data &data,
        const PolicySerializable &policy)
 {
-       int retCode = CKM_API_ERROR_UNKNOWN;
-
-       try {
+       return tryRet([&] {
                // check if data is correct
                Crypto::Data binaryData;
-               retCode = toBinaryData(data, binaryData);
+               int retCode = toBinaryData(data, binaryData);
 
-               if (retCode != CKM_API_SUCCESS)
-                       return retCode;
-               else
-                       return saveDataHelper(cred, name, explicitOwner, binaryData, policy);
-       } catch (const Exc::Exception &e) {
-               return e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               return CKM_API_ERROR_SERVER_ERROR;
-       }
+               return retCode != CKM_API_SUCCESS
+                       ? retCode
+                       : saveDataHelper(cred, name, explicitOwner, binaryData, policy);
+       });
 }
 
 int CKMLogic::getKeyForService(
@@ -584,7 +559,7 @@ int CKMLogic::getKeyForService(
        const Password &pass,
        Crypto::GObjShPtr &key)
 {
-       try {
+       return tryRet([&] {
                // Key is for internal service use. It won't be exported to the client
                Crypto::GObjUPtr obj;
                int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, explicitOwner,
@@ -594,12 +569,7 @@ int CKMLogic::getKeyForService(
                        key = std::move(obj);
 
                return retCode;
-       } catch (const Exc::Exception &e) {
-               return e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               return CKM_API_ERROR_SERVER_ERROR;
-       }
+       });
 }
 
 RawBuffer CKMLogic::saveData(
@@ -684,18 +654,9 @@ RawBuffer CKMLogic::savePKCS12(
        const PolicySerializable &keyPolicy,
        const PolicySerializable &certPolicy)
 {
-       int retCode = CKM_API_ERROR_UNKNOWN;
-
-       try {
-               retCode = saveDataHelper(cred, name, explicitOwner, pkcs, keyPolicy, certPolicy);
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
-       }
-
-       return SerializeMessage(msgId, retCode);
+       return SerializeMessage(msgId, tryRet([&] {
+               return saveDataHelper(cred, name, explicitOwner, pkcs, keyPolicy, certPolicy);
+       }));
 }
 
 
@@ -766,18 +727,9 @@ RawBuffer CKMLogic::removeData(
        const Name &name,
        const ClientId &explicitOwner)
 {
-       int retCode = CKM_API_ERROR_UNKNOWN;
-
-       try {
-               retCode = removeDataHelper(cred, name, explicitOwner);
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("Error: " << e.GetMessage());
-               retCode = CKM_API_ERROR_DB_ERROR;
-       }
-
-       return SerializeMessage(msgId, retCode);
+       return SerializeMessage(msgId, tryRet([&] {
+               return removeDataHelper(cred, name, explicitOwner);
+       }));
 }
 
 
@@ -963,23 +915,19 @@ RawBuffer CKMLogic::getData(
        const ClientId &explicitOwner,
        const Password &password)
 {
-       int retCode = CKM_API_SUCCESS;
        RawBuffer rowData;
        DataType objDataType;
 
-       try {
+       int retCode = tryRet([&] {
                Crypto::GObjUPtr obj;
-               retCode = readDataHelper(true, cred, dataType, name, explicitOwner,
+               int retCode = readDataHelper(true, cred, dataType, name, explicitOwner,
                                                                 password, obj, objDataType);
 
                if (retCode == CKM_API_SUCCESS)
                        rowData = obj->getBinary();
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
-       }
+
+               return retCode;
+       });
 
        if (CKM_API_SUCCESS != retCode)
                rowData.clear();
@@ -994,22 +942,14 @@ RawBuffer CKMLogic::getDataProtectionStatus(
                const Name &name,
                const ClientId &explicitOwner)
 {
-       int retCode = CKM_API_SUCCESS;
        bool status = false;
        DataType objDataType;
        Password password;
 
-       try {
+       int retCode = tryRet([&] {
                Crypto::GObjUPtr obj;
-               retCode = readDataHelper(false, cred, dataType, name, explicitOwner,
-                                                                password, obj, objDataType);
-
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
-       }
+               return readDataHelper(false, cred, dataType, name, explicitOwner, password, obj, objDataType);
+       });
 
        if (retCode == CKM_API_ERROR_AUTHENTICATION_FAILED) {
                status = true;
@@ -1084,26 +1024,21 @@ RawBuffer CKMLogic::getPKCS12(
        const Password &keyPassword,
        const Password &certPassword)
 {
-       int retCode = CKM_API_ERROR_UNKNOWN;
-
        PKCS12Serializable output;
 
-       try {
+       int retCode = tryRet([&] {
                KeyShPtr privKey;
                CertificateShPtr cert;
                CertificateShPtrVector caChain;
-               retCode = getPKCS12Helper(cred, name, explicitOwner, keyPassword,
+               int retCode = getPKCS12Helper(cred, name, explicitOwner, keyPassword,
                                                                  certPassword, privKey, cert, caChain);
 
                // prepare response
                if (retCode == CKM_API_SUCCESS)
                        output = PKCS12Serializable(std::move(privKey), std::move(cert), std::move(caChain));
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
-       }
+
+               return retCode;
+       });
 
        return SerializeMessage(msgId, retCode, output);
 }
@@ -1117,7 +1052,7 @@ int CKMLogic::getDataListHelper(const Credentials &cred,
        if (0 < m_userDataMap.count(cred.clientUid)) {
                auto &database = m_userDataMap[cred.clientUid].database;
 
-               try {
+               retCode = tryRet<CKM_API_ERROR_DB_ERROR>([&] {
                        OwnerNameVector tmpVector;
 
                        if (dataType.isKey()) {
@@ -1135,13 +1070,8 @@ int CKMLogic::getDataListHelper(const Credentials &cred,
 
                        ownerNameVector.insert(ownerNameVector.end(), tmpVector.begin(),
                                                                   tmpVector.end());
-                       retCode = CKM_API_SUCCESS;
-               } catch (const CKM::Exception &e) {
-                       LogError("Error: " << e.GetMessage());
-                       retCode = CKM_API_ERROR_DB_ERROR;
-               } catch (const Exc::Exception &e) {
-                       retCode = e.error();
-               }
+                       return CKM_API_SUCCESS;
+               });
        }
 
        return retCode;
@@ -1199,61 +1129,58 @@ int CKMLogic::importInitialData(
        const Policy &policy)
 {
        try {
-               if (encParams.iv.empty() != encParams.tag.empty()) {
-                       LogError("Both iv and tag must be empty or set");
-                       return CKM_API_ERROR_INPUT_PARAM;
-               }
+               return tryRet([&] {
+                       if (encParams.iv.empty() != encParams.tag.empty()) {
+                               LogError("Both iv and tag must be empty or set");
+                               return CKM_API_ERROR_INPUT_PARAM;
+                       }
 
-               // Inital values are always imported with root credentials. Client id is not important.
-               Credentials rootCred(0, "");
+                       // Inital values are always imported with root credentials. Client id is not important.
+                       Credentials rootCred(0, "");
 
-               auto &handler = selectDatabase(rootCred, CLIENT_ID_SYSTEM);
+                       auto &handler = selectDatabase(rootCred, CLIENT_ID_SYSTEM);
 
-               // check if save is possible
-               DB::Crypto::Transaction transaction(&handler.database);
-               int retCode = checkSaveConditions(rootCred, handler, name, CLIENT_ID_SYSTEM);
+                       // check if save is possible
+                       DB::Crypto::Transaction transaction(&handler.database);
+                       int retCode = checkSaveConditions(rootCred, handler, name, CLIENT_ID_SYSTEM);
 
-               if (retCode != CKM_API_SUCCESS)
-                       return retCode;
+                       if (retCode != CKM_API_SUCCESS)
+                               return retCode;
 
-               Crypto::GStore &store =
-                               m_decider.getStore(data.type, policy, !encParams.iv.empty());
+                       Crypto::GStore &store =
+                                       m_decider.getStore(data.type, policy, !encParams.iv.empty());
 
-               Token token;
+                       Token token;
 
-               if (encParams.iv.empty()) {
-            // Data are not encrypted, let's try to verify them
-                       Crypto::Data binaryData;
+                       if (encParams.iv.empty()) {
+                               // Data are not encrypted, let's try to verify them
+                               Crypto::Data binaryData;
 
-                       if (CKM_API_SUCCESS != (retCode = toBinaryData(data, binaryData)))
-                               return retCode;
+                               if (CKM_API_SUCCESS != (retCode = toBinaryData(data, binaryData)))
+                                       return retCode;
 
-                       token = store.import(binaryData,
-                                                                m_accessControl.isCCMode() ? "" : policy.password,
-                                                                encParams);
-               } else {
-                       token = store.import(data,
-                                                                m_accessControl.isCCMode() ? "" : policy.password,
-                                                                encParams);
-               }
+                               token = store.import(binaryData,
+                                                                        m_accessControl.isCCMode() ? "" : policy.password,
+                                                                        encParams);
+                       } else {
+                               token = store.import(data,
+                                                                        m_accessControl.isCCMode() ? "" : policy.password,
+                                                                        encParams);
+                       }
 
-               DB::Row row(std::move(token), name, CLIENT_ID_SYSTEM,
-                                       static_cast<int>(policy.extractable));
-               handler.crypto.encryptRow(row);
+                       DB::Row row(std::move(token), name, CLIENT_ID_SYSTEM,
+                                               static_cast<int>(policy.extractable));
+                       handler.crypto.encryptRow(row);
 
-               handler.database.saveRow(row);
-               transaction.commit();
-       } catch (const Exc::Exception &e) {
-               return e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               return CKM_API_ERROR_SERVER_ERROR;
+                       handler.database.saveRow(row);
+                       transaction.commit();
+
+                       return CKM_API_SUCCESS;
+               });
        } catch (const std::exception &e) {
                LogError("Std::exception: " << e.what());
                return CKM_API_ERROR_SERVER_ERROR;
        }
-
-       return CKM_API_SUCCESS;
 }
 
 int CKMLogic::saveDataHelper(
@@ -1462,26 +1389,10 @@ RawBuffer CKMLogic::createKeyPair(
        const PolicySerializable &policyPrivate,
        const PolicySerializable &policyPublic)
 {
-       int retCode = CKM_API_SUCCESS;
-
-       try {
-               retCode = createKeyPairHelper(
-                                         cred,
-                                         keyGenParams,
-                                         namePrivate,
-                                         explicitOwnerPrivate,
-                                         namePublic,
-                                         explicitOwnerPublic,
-                                         policyPrivate,
-                                         policyPublic);
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
-       }
-
-       return SerializeMessage(msgId, retCode);
+       return SerializeMessage(msgId, tryRet([&] {
+               return createKeyPairHelper(cred, keyGenParams, namePrivate, explicitOwnerPrivate,
+                                          namePublic, explicitOwnerPublic, policyPrivate, policyPublic);
+       }));
 }
 
 RawBuffer CKMLogic::createKeyAES(
@@ -1495,15 +1406,12 @@ RawBuffer CKMLogic::createKeyAES(
        int retCode = CKM_API_SUCCESS;
 
        try {
-               retCode = createKeyAESHelper(cred, size, name, explicitOwner, policy);
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
+               retCode = tryRet([&] {
+                       return createKeyAESHelper(cred, size, name, explicitOwner, policy);
+               });
        } catch (std::invalid_argument &e) {
                LogDebug("invalid argument error: " << e.what());
                retCode = CKM_API_ERROR_INPUT_PARAM;
-       } catch (const CKM::Exception &e) {
-               LogError("CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
        }
 
        return SerializeMessage(msgId, retCode);
@@ -1717,17 +1625,16 @@ RawBuffer CKMLogic::createSignature(
        int retCode = CKM_API_SUCCESS;
 
        try {
-               Crypto::GObjUPtr obj;
-               retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName,
-                                                                explicitOwner, password, obj);
+               retCode = tryRet([&] {
+                       Crypto::GObjUPtr obj;
+                       int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName,
+                                                    explicitOwner, password, obj);
 
-               if (retCode == CKM_API_SUCCESS)
-                       signature = obj->sign(cryptoAlg, message);
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("Unknown CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
+                       if (retCode == CKM_API_SUCCESS)
+                               signature = obj->sign(cryptoAlg, message);
+
+                       return retCode;
+               });
        } catch (const std::exception &e) {
                LogError("STD exception " << e.what());
                retCode = CKM_API_ERROR_SERVER_ERROR;
@@ -1746,15 +1653,13 @@ RawBuffer CKMLogic::verifySignature(
        const RawBuffer &signature,
        const CryptoAlgorithm &params)
 {
-       int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
-
-       try {
+       return SerializeMessage(msgId, tryRet([&] {
                // 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.
                Crypto::GObjUPtr obj;
-               retCode = readDataHelper(false, cred, DataType::CERTIFICATE,
-                                                                publicKeyOrCertName, explicitOwner, password, obj);
+               int retCode = readDataHelper(false, cred, DataType::CERTIFICATE,
+                                            publicKeyOrCertName, explicitOwner, password, obj);
 
                if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN)
                        retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST,
@@ -1762,14 +1667,9 @@ RawBuffer CKMLogic::verifySignature(
 
                if (retCode == CKM_API_SUCCESS)
                        retCode = obj->verify(params, message, signature);
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("Unknown CKM::Exception: " << e.GetMessage());
-               retCode = CKM_API_ERROR_SERVER_ERROR;
-       }
 
-       return SerializeMessage(msgId, retCode);
+               return retCode;
+       }));
 }
 
 int CKMLogic::setPermissionHelper(
@@ -1828,18 +1728,9 @@ RawBuffer CKMLogic::setPermission(
        const ClientId &accessor,
        const PermissionMask permissionMask)
 {
-       int retCode;
-
-       try {
-               retCode = setPermissionHelper(cred, name, explicitOwner, accessor, permissionMask);
-       } catch (const Exc::Exception &e) {
-               retCode = e.error();
-       } catch (const CKM::Exception &e) {
-               LogError("Error: " << e.GetMessage());
-               retCode = CKM_API_ERROR_DB_ERROR;
-       }
-
-       return SerializeMessage(msgID, retCode);
+       return SerializeMessage(msgID, tryRet([&] {
+               return setPermissionHelper(cred, name, explicitOwner, accessor, permissionMask);
+       }));
 }
 
 } // namespace CKM