Enable -Wshadow and fix warnings
[platform/core/security/key-manager.git] / src / manager / service / ckm-logic.cpp
index bc88876..f57f920 100644 (file)
@@ -81,7 +81,7 @@ int toBinaryData(const Crypto::Data &input, Crypto::Data &output)
        if (input.type.isKey()) {
                KeyShPtr output_key;
 
-               if (input.type.isSKey())
+               if (input.type.isSymmetricKey())
                        output_key = CKM::Key::createAES(input.data);
                else
                        output_key = CKM::Key::create(input.data);
@@ -823,13 +823,13 @@ RawBuffer CKMLogic::getData(
 
        int retCode = tryRet([&] {
                Crypto::GObjUPtr obj;
-               int retCode = readDataHelper(true, cred, dataType, name, owner,
-                                                                        password, obj, objDataType);
+               int retCode2 = readDataHelper(true, cred, dataType, name, owner,
+                                                                         password, obj, objDataType);
 
-               if (retCode == CKM_API_SUCCESS)
+               if (retCode2 == CKM_API_SUCCESS)
                        rowData = obj->getBinary();
 
-               return retCode;
+               return retCode2;
        });
 
        if (CKM_API_SUCCESS != retCode)
@@ -879,36 +879,36 @@ RawBuffer CKMLogic::getPKCS12(
 
                // read private key (mandatory)
                Crypto::GObjUPtr keyObj;
-               int retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, owner,
-                                                                        keyPassword, keyObj);
+               int retCode2 = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, owner,
+                                                                         keyPassword, keyObj);
 
-               if (retCode != CKM_API_SUCCESS) {
-                       if (retCode != CKM_API_ERROR_NOT_EXPORTABLE)
-                               return retCode;
+               if (retCode2 != CKM_API_SUCCESS) {
+                       if (retCode2 != CKM_API_ERROR_NOT_EXPORTABLE)
+                               return retCode2;
                } else {
                        privKey = CKM::Key::create(keyObj->getBinary());
                }
 
                // read certificate (mandatory)
                Crypto::GObjUPtr certObj;
-               retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, owner,
-                                                                certPassword, certObj);
+               retCode2 = readDataHelper(true, cred, DataType::CERTIFICATE, name, owner,
+                                                                 certPassword, certObj);
 
-               if (retCode != CKM_API_SUCCESS) {
-                       if (retCode != CKM_API_ERROR_NOT_EXPORTABLE)
-                               return retCode;
+               if (retCode2 != CKM_API_SUCCESS) {
+                       if (retCode2 != CKM_API_ERROR_NOT_EXPORTABLE)
+                               return retCode2;
                } else {
                        cert = CKM::Certificate::create(certObj->getBinary(), DataFormat::FORM_DER);
                }
 
                // read CA cert chain (optional)
                Crypto::GObjUPtrVector caChainObjs;
-               retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, owner,
-                                                                certPassword, caChainObjs);
+               retCode2 = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, owner,
+                                                                 certPassword, caChainObjs);
 
-               if (retCode != CKM_API_SUCCESS && retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
-                       if (retCode != CKM_API_ERROR_NOT_EXPORTABLE)
-                               return retCode;
+               if (retCode2 != CKM_API_SUCCESS && retCode2 != CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
+                       if (retCode2 != CKM_API_ERROR_NOT_EXPORTABLE)
+                               return retCode2;
                } else {
                        for (auto &caCertObj : caChainObjs)
                                caChain.push_back(CKM::Certificate::create(caCertObj->getBinary(),
@@ -917,11 +917,11 @@ RawBuffer CKMLogic::getPKCS12(
 
                // if anything found, return it
                if (privKey || cert || caChain.size() > 0)
-                       retCode = CKM_API_SUCCESS;
+                       retCode2 = CKM_API_SUCCESS;
 
                // prepare response
-               if (retCode != CKM_API_SUCCESS)
-                       return retCode;
+               if (retCode2 != CKM_API_SUCCESS)
+                       return retCode2;
 
                output = PKCS12Serializable(std::move(privKey), std::move(cert), std::move(caChain));
                return CKM_API_SUCCESS;
@@ -930,9 +930,9 @@ RawBuffer CKMLogic::getPKCS12(
        return SerializeMessage(msgId, retCode, output);
 }
 
-int CKMLogic::getDataListHelper(const Credentials &cred,
-                                                               const DataType dataType,
-                                                               OwnerNameVector &ownerNameVector)
+int CKMLogic::getAliasInfoListHelper(const Credentials &cred,
+                                                                        const DataType dataType,
+                                                                        AliasInfoVector &aliasInfoVector)
 {
        int retCode = CKM_API_ERROR_DB_LOCKED;
 
@@ -940,23 +940,20 @@ int CKMLogic::getDataListHelper(const Credentials &cred,
                auto &database = m_userDataMap[cred.clientUid].database;
 
                retCode = tryRet<CKM_API_ERROR_DB_ERROR>([&] {
-                       OwnerNameVector tmpVector;
+                       AliasInfoVector tmpVector;
 
                        if (dataType.isKey()) {
                                // list all key types
-                               database.listNames(cred.client,
+                               database.listInfos(cred.client,
                                                                   tmpVector,
                                                                   DataType::DB_KEY_FIRST,
                                                                   DataType::DB_KEY_LAST);
                        } else {
                                // list anything else
-                               database.listNames(cred.client,
-                                                                  tmpVector,
-                                                                  dataType);
+                               database.listInfos(cred.client, tmpVector, dataType);
                        }
 
-                       ownerNameVector.insert(ownerNameVector.end(), tmpVector.begin(),
-                                                                  tmpVector.end());
+                       aliasInfoVector.insert(aliasInfoVector.end(), tmpVector.begin(), tmpVector.end());
                        return CKM_API_SUCCESS;
                });
        }
@@ -969,9 +966,9 @@ RawBuffer CKMLogic::getDataList(
        int msgId,
        DataType dataType)
 {
-       OwnerNameVector systemVector;
-       OwnerNameVector userVector;
-       OwnerNameVector ownerNameVector;
+       AliasInfoVector systemVector;
+       AliasInfoVector userVector;
+       AliasInfoVector aliasInfoVector;
 
        int retCode = unlockSystemDB();
 
@@ -979,32 +976,32 @@ RawBuffer CKMLogic::getDataList(
                // system database
                if (m_accessControl.isSystemService(cred)) {
                        // lookup system DB
-                       retCode = getDataListHelper(Credentials(SYSTEM_DB_UID, CLIENT_ID_SYSTEM),
-                                                                               dataType,
-                                                                               systemVector);
+                       retCode = getAliasInfoListHelper(Credentials(SYSTEM_DB_UID, CLIENT_ID_SYSTEM),
+                                                                                        dataType,
+                                                                                        systemVector);
                } else {
                        // user - lookup system, then client DB
-                       retCode = getDataListHelper(Credentials(SYSTEM_DB_UID, cred.client),
-                                                                               dataType,
-                                                                               systemVector);
+                       retCode = getAliasInfoListHelper(Credentials(SYSTEM_DB_UID, cred.client),
+                                                                                        dataType,
+                                                                                        systemVector);
 
                        // private database
                        if (retCode == CKM_API_SUCCESS) {
-                               retCode = getDataListHelper(cred,
-                                                                                       dataType,
-                                                                                       userVector);
+                               retCode = getAliasInfoListHelper(cred,
+                                                                                                dataType,
+                                                                                                userVector);
                        }
                }
        }
 
        if (retCode == CKM_API_SUCCESS) {
-               ownerNameVector.insert(ownerNameVector.end(), systemVector.begin(),
+               aliasInfoVector.insert(aliasInfoVector.end(), systemVector.begin(),
                                                           systemVector.end());
-               ownerNameVector.insert(ownerNameVector.end(), userVector.begin(),
+               aliasInfoVector.insert(aliasInfoVector.end(), userVector.begin(),
                                                           userVector.end());
        }
 
-       return SerializeMessage(msgId, retCode, dataType, ownerNameVector);
+       return SerializeMessage(msgId, retCode, dataType, AliasInfoSerializableVector(aliasInfoVector));
 }
 
 int CKMLogic::importInitialData(
@@ -1028,7 +1025,7 @@ int CKMLogic::importInitialData(
                        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, true, !encParams.iv.empty());
 
                        Token token;
                        if (encParams.iv.empty()) {
@@ -1101,7 +1098,7 @@ std::tuple<CKMLogic::DBOperation, PermissionMask, int> CKMLogic::beginAndGetPerm
        const Name &name,
        const ClientId &owner)
 {
-       PermissionMask permission;
+       PermissionMask permission = Permission::NONE;
        auto [dbOp, retCode] = begin(cred, name, owner);
        if (retCode == CKM_API_SUCCESS)
                permission = toPermissionMask(dbOp.database().getPermissionRow(name, owner, cred.client));
@@ -1177,7 +1174,8 @@ RawBuffer CKMLogic::createKeyPair(
                bool exportable = policyPrv.extractable || policyPub.extractable;
                Policy lessRestricted(Password(), exportable, policyPrv.backend);
 
-               TokenPair keys = m_decider.getStore(policyPrv).generateAKey(
+               // For now any asymmetric key will do. If necessary we can extract it from keyGenParams.
+               TokenPair keys = m_decider.getStore(DataType::DB_KEY_FIRST, policyPrv, false).generateAKey(
                        keyGenParams,
                        policyPrv.password,
                        policyPub.password,
@@ -1202,17 +1200,17 @@ RawBuffer CKMLogic::createKeyAES(
 
        try {
                retCode = tryRet([&] {
-                       auto [dbOp, digest, retCode] = beginSaveAndGetHash(cred, name, owner);
-                       if (retCode != CKM_API_SUCCESS)
-                               return retCode;
+                       auto [dbOp, digest, retCode2] = beginSaveAndGetHash(cred, name, owner);
+                       if (retCode2 != CKM_API_SUCCESS)
+                               return retCode2;
 
                        // 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).generateSKey(keyGenAlgorithm,
-                                                                                                                                                                  policy.password,
-                                                                                                                                                                  digest);
+
+                       auto& store = m_decider.getStore(DataType::KEY_AES, policy, false);
+                       Token key = store.generateSKey(keyGenAlgorithm, policy.password, digest);
 
                        dbOp.finalize(std::move(key), policy);
                        return CKM_API_SUCCESS;
@@ -1435,13 +1433,13 @@ RawBuffer CKMLogic::createSignature(
        try {
                retCode = tryRet([&] {
                        Crypto::GObjUPtr obj;
-                       int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName,
-                                                                                owner, password, obj);
+                       int retCode2 = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName,
+                                                                                 owner, password, obj);
 
-                       if (retCode == CKM_API_SUCCESS)
+                       if (retCode2 == CKM_API_SUCCESS)
                                signature = obj->sign(cryptoAlg, message);
 
-                       return retCode;
+                       return retCode2;
                });
        } catch (const std::exception &e) {
                LogError("STD exception " << e.what());
@@ -1537,14 +1535,15 @@ RawBuffer CKMLogic::deriveKey(
        return SerializeMessage(msgID, tryRet([&] {
                // Get key/secret for internal service use. It won't be exported to the client
                Crypto::GObjUPtr obj;
+               DataType objType;
                int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST,
-                                                                        secretName, secretOwner, secretPassword, obj);
+                                                                        secretName, secretOwner, secretPassword, obj, objType);
                if (retCode != CKM_API_SUCCESS) {
                        if (retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
                                return retCode;
 
                        retCode = readDataHelper(false, cred, DataType::BINARY_DATA,
-                                                                        secretName, secretOwner, secretPassword, obj);
+                                                                        secretName, secretOwner, secretPassword, obj, objType);
                        if (retCode != CKM_API_SUCCESS)
                                return retCode;
                }
@@ -1553,6 +1552,14 @@ RawBuffer CKMLogic::deriveKey(
                if (ret != CKM_API_SUCCESS)
                        return ret;
 
+               // ECDH (private key) -> binary secret, KBKDF -> symmetric key
+               DataType newKeyType = objType.isKeyPrivate() ? DataType::BINARY_DATA : DataType::KEY_AES;
+               if (!m_decider.checkStore(obj->backendId(), newKeyType, newKeyPolicy, false)) {
+                       LogDebug("Can't import the derived key to backend " <<
+                                static_cast<int>(obj->backendId()) << " with given policy");
+                       return CKM_API_ERROR_INPUT_PARAM;
+               }
+
                // derive
                Token derived = obj->derive(params, newKeyPolicy.password, digest);
 
@@ -1569,17 +1576,16 @@ RawBuffer CKMLogic::importWrappedKey(
        const Name &wrappingKeyName,
        const ClientId &wrappingKeyOwner,
        const Password &wrappingKeyPassword,
-       const Name &encryptedKeyName,
-       const ClientId &encryptedKeyOwner,
-       const RawBuffer &encryptedKey,
-       const CKM::DataType encryptedKeyType,
-       const PolicySerializable &encryptedKeyPolicy)
+       const Name &keyName,
+       const ClientId &keyOwner,
+       const RawBuffer &wrappedKey,
+       const CKM::DataType keyType,
+       const PolicySerializable &policy)
 {
-
        return SerializeMessage(msgId, tryRet([&] {
                Crypto::GObjUPtr wrappingKey;
 
-               auto [dbOp, digest, retCode] = beginSaveAndGetHash(cred, encryptedKeyName, encryptedKeyOwner);
+               auto [dbOp, digest, retCode] = beginSaveAndGetHash(cred, keyName, keyOwner);
                if (retCode != CKM_API_SUCCESS)
                        return retCode;
 
@@ -1588,15 +1594,81 @@ RawBuffer CKMLogic::importWrappedKey(
                if (retCode != CKM_API_SUCCESS)
                        return retCode;
 
+               if (!m_decider.checkStore(wrappingKey->backendId(), keyType, policy, true)) {
+                       LogDebug("Can't import the wrapped key to backend " <<
+                                static_cast<int>(wrappingKey->backendId()) << " with given policy");
+                       return CKM_API_ERROR_INPUT_PARAM;
+               }
+
                Token token = wrappingKey->unwrap(params,
-                                                                                 Crypto::Data(encryptedKeyType, std::move(encryptedKey)),
-                                                                                 encryptedKeyPolicy.password,
+                                                                                 Crypto::Data(keyType, std::move(wrappedKey)),
+                                                                                 policy.password,
                                                                                  digest);
 
-               dbOp.finalize(std::move(token), encryptedKeyPolicy);
+               dbOp.finalize(std::move(token), policy);
 
                return retCode;
        }));
 }
 
+RawBuffer CKMLogic::exportWrappedKey(
+       const Credentials &cred,
+       const int msgID,
+       const CryptoAlgorithm &params,
+       const Name &wrappingKeyName,
+       const ClientId &wrappingKeyOwner,
+       const Password &wrappingKeyPassword,
+       const Name &keyName,
+       const ClientId &keyOwner,
+       const Password &keyPassword)
+{
+       Crypto::GObjUPtr wrappingKey;
+       DB::Row wrappedKeyRow;
+       DataType wrappedKeyType;
+       RawBuffer wrappedKey;
+
+       auto retCode = tryRet([&] {
+               auto retCode2 = readDataHelper(false, cred, DataType::DB_KEY_FIRST, wrappingKeyName,
+                                                                          wrappingKeyOwner, wrappingKeyPassword, wrappingKey);
+               if (retCode2 != CKM_API_SUCCESS)
+                       return retCode2;
+
+               retCode2 = readRowHelper(false, cred, DataType::DB_KEY_FIRST, keyName,
+                                                                keyOwner, keyPassword, wrappedKeyRow, wrappedKeyType);
+               if (retCode2 != CKM_API_SUCCESS)
+                       return retCode2;
+
+               wrappedKey = wrappingKey->wrap(params, wrappedKeyRow, keyPassword);
+
+               return retCode2;
+       });
+
+       return SerializeMessage(msgID, retCode, wrappedKeyType, wrappedKey);
+}
+
+RawBuffer CKMLogic::getBackendInfo(const int msgID, BackendId backend)
+{
+       BackendInfo info;
+       auto retCode = tryRet([&] {
+               CryptoBackend cryptoBackend;
+               if (backend == BackendId::SW)
+                       cryptoBackend = CryptoBackend::OpenSSL;
+               else if (backend == BackendId::TZ)
+                       cryptoBackend = CryptoBackend::TrustZone;
+               else
+                       return CKM_API_ERROR_INPUT_PARAM;
+
+               auto store = m_decider.getStore(cryptoBackend);
+               if (store == nullptr) {
+                       LogError("Required backend is unavailable");
+                       return CKM_API_ERROR_INPUT_PARAM;
+               }
+
+               info.maxChunkSize = store->maxChunkSize();
+               return CKM_API_SUCCESS;
+       });
+
+       return SerializeMessage(msgID, retCode, BackendInfoSerializable(info));
+}
+
 } // namespace CKM