+ return CKM_API_SUCCESS;
+}
+
+
+int CKMLogic::readMultiRow(const Name &name,
+ const Label &ownerLabel,
+ DataType dataType,
+ DB::Crypto & database,
+ DB::RowVector &output)
+{
+ if (dataType.isKey())
+ {
+ // read all key types
+ database.getRows(name,
+ ownerLabel,
+ DataType::DB_KEY_FIRST,
+ DataType::DB_KEY_LAST,
+ output);
+ }
+ else if (dataType.isChainCert())
+ {
+ // read all key types
+ database.getRows(name,
+ ownerLabel,
+ DataType::DB_CHAIN_FIRST,
+ DataType::DB_CHAIN_LAST,
+ output);
+ }
+ else
+ {
+ // read anything else
+ database.getRows(name,
+ ownerLabel,
+ dataType,
+ output);
+ }
+
+ if(!output.size()) {
+ LogError("No row for given name, label and type");
+ return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+ }
+
+ return CKM_API_SUCCESS;
+}
+
+int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
+ const Name &name,
+ const Label &ownerLabel,
+ const Label &accessorLabel,
+ const DB::Row &row,
+ bool exportFlag,
+ DB::Crypto & database)
+{
+ PermissionMaskOptional permissionRowOpt =
+ database.getPermissionRow(name, ownerLabel, accessorLabel);
+
+ if(exportFlag)
+ return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt));
+ return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
+}
+
+int CKMLogic::readDataHelper(
+ bool exportFlag,
+ const Credentials &cred,
+ DataType dataType,
+ const Name &name,
+ const Label &label,
+ const Password &password,
+ DB::RowVector &rows)
+{
+ auto &handler = selectDatabase(cred, label);
+
+ // use client label if not explicitly provided
+ const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
+
+ if (!isNameValid(name) || !isLabelValid(ownerLabel))
+ return CKM_API_ERROR_INPUT_PARAM;
+
+ // read rows
+ DB::Crypto::Transaction transaction(&handler.database);
+ int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
+ if(CKM_API_SUCCESS != retCode)
+ return retCode;
+
+ // all read rows belong to the same owner
+ DB::Row & firstRow = rows.at(0);
+
+ // check access rights
+ retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
+ 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);
+
+ return CKM_API_SUCCESS;
+}
+
+int CKMLogic::readDataHelper(
+ bool exportFlag,
+ const Credentials &cred,
+ DataType dataType,
+ const Name &name,
+ const Label &label,
+ const Password &password,
+ DB::Row &row)
+{
+ auto &handler = selectDatabase(cred, label);
+
+ // use client label if not explicitly provided
+ const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
+
+ if (!isNameValid(name) || !isLabelValid(ownerLabel))
+ return CKM_API_ERROR_INPUT_PARAM;
+
+ // read row
+ DB::Crypto::Transaction transaction(&handler.database);
+ int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
+ if(CKM_API_SUCCESS != retCode)
+ return retCode;
+
+ // 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)) {