${CMAKE_CURRENT_SOURCE_DIR}/ckm-logic-ext.cpp
${CMAKE_CURRENT_SOURCE_DIR}/db-wrapper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ui.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/decrypt.cpp
${KEY_MANAGER_PATH}/common/ckm-error.cpp
${KEY_MANAGER_PATH}/crypto/platform/decider.cpp
${KEY_MANAGER_PATH}/crypto/sw-backend/internals.cpp
const char *DB_CMD_OBJECT_SELECT = "SELECT * FROM [join_name_object_tables];";
+const char *DB_CMD_NAME_SELECT_BY_IDX = "SELECT name, label FROM NAMES WHERE idx = ?001;";
+
} // anonymous namespace
namespace CKM {
m_userDataMap[user].database.saveRow(row);
}
+NameEntry CKMLogicExt::getNameByIdx(uid_t user, int idx)
+{
+ DB::SqlConnection::DataCommandUniquePtr selectCommand =
+ m_userDataMap[user].database.m_connection->PrepareDataCommand(DB_CMD_NAME_SELECT_BY_IDX);
+ selectCommand->BindInteger(1, idx);
+
+ if (!selectCommand->Step())
+ ThrowErr(Exc::DatabaseFailed, "getting name from database failed");
+
+ NameEntry name;
+ name.name = selectCommand->GetColumnString(0);
+ name.owner = selectCommand->GetColumnString(1);
+ return name;
+}
+
+int CKMLogicExt::readDataHelperProtected(
+ const Credentials &cred,
+ DataType dataType,
+ const Name &name,
+ const ClientId &explicitOwner,
+ const Password &password,
+ Crypto::GObjUPtr &obj)
+{
+ return readDataHelper(false, cred, dataType, name, explicitOwner, password, obj);
+}
+
} // namespace CKM
/*
- * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dpl/db/sql_connection.h>
namespace CKM {
+
+struct NameEntry {
+ Name name;
+ ClientId owner;
+};
+
struct CKMLogicExt : public CKMLogic {
CKMLogicExt() : m_systemDbUnlocked(false) {}
DB::SqlConnection::Output Execute(uid_t user, const std::string &cmd);
DB::RowVector getRows(uid_t user);
void saveRow(uid_t user, const DB::Row &row);
+ NameEntry getNameByIdx(uid_t user, int idx);
+ int readDataHelperProtected(
+ const Credentials &cred,
+ DataType dataType,
+ const Name &name,
+ const ClientId &explicitOwner,
+ const Password &password,
+ Crypto::GObjUPtr &obj);
private:
bool m_systemDbUnlocked;
};
+
} // namespace CKM
cout << " -u, --uid UID User id as in <TZ_SYS_DATA>/ckm/db-<uid> - default value 0\n";
cout << " -p, --pass PASSWORD Password used for database encryption. For system database (uid < 5000) no password should be used.\n";
cout << " -c, --cmd SQLCOMMAND Sqlite3 command to execute on database. If command not provided tool will enter interactive mode.\n";
+ cout << " --decrypt Enables automatic decryption of the data column.\n";
cout << " -h, --help Shows this help.\n";
cout << "Example: Open database for user 5000 and select all data from table names\n";
cout << " cmd_db_tool -u 5000 -p P45W0RD \"select * from names\"\n";
uid_t uid = 0;
Password pass;
std::string argcmd;
+ bool shouldDecrypt = false;
while(1) {
int option_index = 0;
static struct option long_options[] = {
- {"uid", required_argument, 0, 'u'},
- {"cmd", required_argument, 0, 'c'},
- {"pass", required_argument, 0, 'p'},
- {"help", no_argument, 0, 'h'},
- {0, 0, 0, 0 }
+ {"uid", required_argument, 0, 'u'},
+ {"cmd", required_argument, 0, 'c'},
+ {"pass", required_argument, 0, 'p'},
+ {"decrypt", no_argument, 0, 'd'},
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0 }
};
int c = getopt_long(argc, argv, "u:c:p:h", long_options, &option_index);
case 'p':
pass = optarg;
break;
+ case 'd':
+ shouldDecrypt = true;
+ break;
}
}
continue;
}
- dbw.process(cmd);
+ dbw.process(cmd, shouldDecrypt);
if (!argcmd.empty())
break;
#include <string>
#include <algorithm>
+#include <utility>
#include <base64.h>
m_logic.lockUserKey(m_uid);
}
-void DbWrapper::process(const std::string &acmd)
+void DbWrapper::process(const std::string &acmd, bool shouldDecrypt)
{
try {
std::string cmd = acmd;
if (output.GetNames().empty())
return;
- displayRow(output.GetNames(), trim);
+ Decrypt decryptState(output.GetNames(), m_logic, m_uid);
+ Decrypt *decrypt = nullptr;
+ if (shouldDecrypt && decryptState.canDecryptQuery())
+ decrypt = &decryptState;
+
+ displayRow(output.GetNames(), trim, nullptr);
std::cout << "--------------------------" << std::endl;
for (const auto &row : output.GetValues()) {
- displayRow(row, trim);
+ displayRow(row, trim, decrypt);
}
} catch (const DB::SqlConnection::Exception::Base &e) {
UI::error() << "sql exception: " << e.GetMessage() << std::endl;
}
}
-void DbWrapper::displayRow(const DB::SqlConnection::Output::Row &row, bool trim)
+void DbWrapper::displayRow(const DB::SqlConnection::Output::Row &row, bool trim, Decrypt *decrypt)
{
+ std::pair<std::string, bool> decrypted;
+ if (decrypt)
+ decrypted = decrypt->tryDecrypt(row);
+
for (auto it = row.begin(); it != row.end(); it++) {
std::string col = *it;
+ if (decrypted.second && it - row.begin() == decrypt->getDataColumnIndex())
+ col = decrypted.first;
+
/*
* Convert unprintable data to base64. Note that a row may contain an incomplete data
* since it holds a binary data as a string.
/*
- * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dpl/db/sql_connection.h>
#include <exception.h>
#include "ckm-logic-ext.h"
+#include "decrypt.h"
namespace CKM {
int unlock();
void lock();
- void process(const std::string &cmd);
+ void process(const std::string &cmd, bool shouldDecrypt);
DB::RowVector getRows();
void saveRow(const DB::Row &row);
private:
- void displayRow(const DB::SqlConnection::Output::Row &row, bool trim);
+ void displayRow(const DB::SqlConnection::Output::Row &row, bool trim, Decrypt *decrypt);
uid_t m_uid;
Password m_pw;
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file decrypt.cpp
+ * @author Mateusz Cegielka (m.cegielka@samsung.com)
+ * @version 1.0
+ */
+
+#include "decrypt.h"
+#include "ui.h"
+
+#include <algorithm>
+#include <iostream>
+#include <stdexcept>
+
+#include <credentials.h>
+#include <generic-backend/gobj.h>
+
+#include <unistd.h>
+
+namespace {
+
+int findColumnByName(const std::string &name, const CKM::Decrypt::Row &columns)
+{
+ auto column = std::find(columns.begin(), columns.end(), name);
+ if (column == columns.end())
+ return -1;
+
+ return column - columns.begin();
+}
+
+std::string fmtObject(const CKM::NameEntry &name)
+{
+ return "'" + name.name + "'";
+}
+
+CKM::Password askObjectPassword(const std::string &displayName)
+{
+ std::string password = CKM::UI::promptPassword(
+ "enter password for object " + displayName + ":");
+ return CKM::Password(password.begin(), password.end());
+}
+
+} // anonymous namespace
+
+namespace CKM {
+
+Decrypt::Decrypt(const Row &columns, CKMLogicExt &logic, uid_t uid)
+ : m_logic(logic),
+ m_uid(uid),
+ m_columnData(-1),
+ m_columnDataType(-1),
+ m_columnIdx(-1)
+{
+ m_columnData = findColumnByName("data", columns);
+ if (m_columnData == -1)
+ return;
+ m_columnDataType = findColumnByName("dataType", columns);
+ m_columnIdx = findColumnByName("idx", columns);
+ if (m_columnDataType == -1 || m_columnIdx == -1)
+ UI::warning() << "unable to decrypt, missing dataType or idx columns" << std::endl;
+}
+
+bool Decrypt::canDecryptQuery() const
+{
+ return m_columnData != -1 && m_columnDataType != -1 && m_columnIdx != -1;
+}
+
+std::pair<std::string, bool> Decrypt::tryDecrypt(const Row &row) const
+{
+ NameEntry nameEntry = getNameEntry(row);
+ std::string name = fmtObject(nameEntry);
+
+ try {
+ return {decrypt(row, "", nameEntry), true};
+ } catch (const Exc::AuthenticationFailed &) {
+ }
+
+ while (true) {
+ Password password = askObjectPassword(name);
+ if (password.empty()) {
+ UI::warning() << "skipped decrypting object " << name << std::endl;
+ return {"", false};
+ }
+
+ try {
+ return {decrypt(row, password, nameEntry), true};
+ } catch (const Exc::AuthenticationFailed &) {
+ UI::error() << "authentication failed for object " << name << std::endl;
+ }
+ }
+}
+
+int Decrypt::getDataColumnIndex() const
+{
+ return m_columnData;
+}
+
+NameEntry Decrypt::getNameEntry(const Row &row) const
+{
+ int idx = std::stoi(row[m_columnIdx]);
+
+ return m_logic.getNameByIdx(m_uid, idx);
+}
+
+std::string Decrypt::decrypt(const Row &row, const Password &password,
+ const NameEntry& nameEntry) const
+{
+ DataType dataType = static_cast<DataType::Type>(std::stoi(row[m_columnDataType]));
+ Credentials credentials(m_uid, nameEntry.owner);
+ Crypto::GObjUPtr obj;
+
+ int ret = m_logic.readDataHelperProtected(credentials, dataType, nameEntry.name,
+ nameEntry.owner, password, obj);
+ if (ret != CKM_API_SUCCESS)
+ throw std::logic_error("reading row data failed");
+
+ RawBuffer decrypted = obj->getBinary();
+ UI::info() << "decrypted object " << fmtObject(nameEntry) << std::endl;
+ return std::string(decrypted.begin(), decrypted.end());
+}
+
+} // namespace CKM
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file decrypt.h
+ * @author Mateusz Cegielka (m.cegielka@samsung.com)
+ * @version 1.0
+ */
+
+#pragma once
+
+#include <string>
+#include <utility>
+
+#include "ckm-logic-ext.h"
+#include <dpl/db/sql_connection.h>
+
+namespace CKM {
+
+class Decrypt {
+public:
+ using Row = DB::SqlConnection::Output::Row;
+
+ Decrypt(const Row &columns, CKMLogicExt &logic, uid_t uid);
+
+ bool canDecryptQuery() const;
+ std::pair<std::string, bool> tryDecrypt(const Row &row) const;
+ int getDataColumnIndex() const;
+
+private:
+ NameEntry getNameEntry(const Row &row) const;
+ std::string decrypt(const Row &row, const Password &password, const NameEntry& name) const;
+
+ CKMLogicExt &m_logic;
+ uid_t m_uid;
+ int m_columnData;
+ int m_columnDataType;
+ int m_columnIdx;
+};
+
+} // namespace CKM
DB::Row row,
const Password &password);
+protected:
int readDataHelper(
bool exportFlag,
const Credentials &cred,
const Password &password,
Crypto::GObjUPtr &obj);
+private:
int readDataHelper(
bool exportFlag,
const Credentials &cred,