summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>2015-09-01 13:05:10 +0200
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>2015-09-03 15:07:16 +0200
commit96a64db011ddc1f7da23deb1bbb7811d99866012 (patch)
treeddd4f72d436422669a7e0fe5a5bfc5288c6f0101 /tools
parent33860153791e816020a392c7ca235f1bb3e983f9 (diff)
downloadkey-manager-96a64db011ddc1f7da23deb1bbb7811d99866012.tar.gz
key-manager-96a64db011ddc1f7da23deb1bbb7811d99866012.tar.bz2
key-manager-96a64db011ddc1f7da23deb1bbb7811d99866012.zip
Add a tool for accessing encrypted database
[Problem] No way of debugging an encrypted database [Solution] Tool added [Verification] Run: ckm_db_tool ckm_db_tool 0 ckm_db_tool 0 <sql_command> ckm_db_tool <uid> <password> > .tables > .schema > <sql_command> > help > exit ckm_db_tool <uid> <password> <sql_command> Change-Id: I87662831808b0397b01db1e54c38b4dc4ad69129
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt1
-rw-r--r--tools/ckm_db_tool/CMakeLists.txt92
-rw-r--r--tools/ckm_db_tool/ckm-logic-ext.cpp57
-rw-r--r--tools/ckm_db_tool/ckm-logic-ext.h37
-rw-r--r--tools/ckm_db_tool/ckm_db_tool.cpp235
-rw-r--r--tools/ckm_db_tool/db-crypto-ext.cpp38
-rw-r--r--tools/ckm_db_tool/db-crypto-ext.h40
7 files changed, 500 insertions, 0 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index f1df9264..8764fad7 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -46,3 +46,4 @@ INSTALL(TARGETS ${CKM_TOOL}
WORLD_EXECUTE
)
+ADD_SUBDIRECTORY(ckm_db_tool) \ No newline at end of file
diff --git a/tools/ckm_db_tool/CMakeLists.txt b/tools/ckm_db_tool/CMakeLists.txt
new file mode 100644
index 00000000..065fafe8
--- /dev/null
+++ b/tools/ckm_db_tool/CMakeLists.txt
@@ -0,0 +1,92 @@
+SET(CKM_DB_TOOL "ckm_db_tool")
+SET(KEY_MANAGER_PATH ${PROJECT_SOURCE_DIR}/src/manager)
+
+PKG_CHECK_MODULES(CKM_DB_TOOL_DEP
+ REQUIRED
+ openssl
+ libsmack
+ libcrypto
+ capi-base-common
+ capi-system-info
+ vconf
+ libxml-2.0
+ )
+
+FIND_PACKAGE(Threads REQUIRED)
+
+INCLUDE_DIRECTORIES(
+ ${CKM_DB_TOOL_DEP_INCLUDE_DIRS}
+ ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/
+ ${KEY_MANAGER_PATH}/main
+ ${KEY_MANAGER_PATH}/common
+ ${KEY_MANAGER_PATH}/service
+ ${KEY_MANAGER_PATH}/initial-values
+ ${KEY_MANAGER_PATH}/sqlcipher
+ ${KEY_MANAGER_PATH}/dpl/core/include
+ ${KEY_MANAGER_PATH}/dpl/log/include
+ ${KEY_MANAGER_PATH}/dpl/db/include
+ ${KEY_MANAGER_PATH}/crypto
+ )
+
+SET(CKM_DB_TOOL_SOURCES
+ ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/ckm_db_tool.cpp
+ ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/db-crypto-ext.cpp
+ ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/ckm-logic-ext.cpp
+
+ ${KEY_MANAGER_PATH}/main/generic-socket-manager.cpp
+ ${KEY_MANAGER_PATH}/main/socket-manager.cpp
+ ${KEY_MANAGER_PATH}/main/smack-check.cpp
+ ${KEY_MANAGER_PATH}/main/thread-service.cpp
+ ${KEY_MANAGER_PATH}/main/socket-2-id.cpp
+ ${KEY_MANAGER_PATH}/service/certificate-store.cpp
+ ${KEY_MANAGER_PATH}/service/certificate-config.cpp
+ ${KEY_MANAGER_PATH}/service/digest.cpp
+ ${KEY_MANAGER_PATH}/service/file-lock.cpp
+ ${KEY_MANAGER_PATH}/service/access-control.cpp
+ ${KEY_MANAGER_PATH}/service/ckm-logic.cpp
+ ${KEY_MANAGER_PATH}/service/key-provider.cpp
+ ${KEY_MANAGER_PATH}/service/crypto-logic.cpp
+ ${KEY_MANAGER_PATH}/service/db-crypto.cpp
+ ${KEY_MANAGER_PATH}/service/file-system.cpp
+ ${KEY_MANAGER_PATH}/initial-values/parser.cpp
+ ${KEY_MANAGER_PATH}/initial-values/BufferHandler.cpp
+ ${KEY_MANAGER_PATH}/initial-values/CertHandler.cpp
+ ${KEY_MANAGER_PATH}/initial-values/DataHandler.cpp
+ ${KEY_MANAGER_PATH}/initial-values/KeyHandler.cpp
+ ${KEY_MANAGER_PATH}/initial-values/PermissionHandler.cpp
+ ${KEY_MANAGER_PATH}/initial-values/InitialValueHandler.cpp
+ ${KEY_MANAGER_PATH}/initial-values/InitialValuesFile.cpp
+ ${KEY_MANAGER_PATH}/initial-values/xml-utils.cpp
+ ${KEY_MANAGER_PATH}/dpl/core/src/assert.cpp
+ ${KEY_MANAGER_PATH}/dpl/db/src/sql_connection.cpp
+ ${KEY_MANAGER_PATH}/dpl/db/src/naive_synchronization_object.cpp
+ ${KEY_MANAGER_PATH}/sqlcipher/sqlcipher.c
+ ${KEY_MANAGER_PATH}/crypto/sw-backend/key.cpp
+ ${KEY_MANAGER_PATH}/crypto/sw-backend/internals.cpp
+ ${KEY_MANAGER_PATH}/crypto/sw-backend/store.cpp
+ ${KEY_MANAGER_PATH}/crypto/platform/decider.cpp
+ ${KEY_MANAGER_PATH}/crypto/tz-backend/store.cpp
+ ${KEY_MANAGER_PATH}/main/socket-2-id-mockup.cpp
+ )
+
+ADD_EXECUTABLE( ${CKM_DB_TOOL} ${CKM_DB_TOOL_SOURCES} )
+
+TARGET_LINK_LIBRARIES(${CKM_DB_TOOL}
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${CKM_DB_TOOL_DEP_LIBRARIES}
+ ${TARGET_KEY_MANAGER_COMMON}
+ -ldl
+ )
+
+#place for output file
+INSTALL(TARGETS ${CKM_DB_TOOL}
+ DESTINATION /usr/bin
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE
+ )
+
diff --git a/tools/ckm_db_tool/ckm-logic-ext.cpp b/tools/ckm_db_tool/ckm-logic-ext.cpp
new file mode 100644
index 00000000..020c5799
--- /dev/null
+++ b/tools/ckm_db_tool/ckm-logic-ext.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2000 - 2015 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 ckm-logic-ext.cpp
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 1.0
+ */
+
+#include <ckm-logic-ext.h>
+#include <db-crypto-ext.h>
+
+namespace CKM {
+
+DB::SqlConnection::Output CKMLogicExt::Execute(uid_t user, const std::string& cmd) {
+ if(user < 5000 && !m_systemDbUnlocked) {
+ if(CKM_API_SUCCESS != unlockSystemDB())
+ ThrowErr(Exc::DatabaseLocked, "can not unlock system database");
+ m_systemDbUnlocked = true;
+ }
+
+ DB::SqlConnection::Output output;
+
+ /*
+ * We need to access to DB::Crypto::m_connection to call Execute() on it. We don't want to mess
+ * with DB::Crypto too much so adding a friend and extending public interface was not an option.
+ * That's why we need a derived class DB::CryptoExt. m_userDataMap must be left unchanged after
+ * this operation but DB::Crypto can't be copied. According to C++ standard static casting
+ * DB::Crypto pointer to DB::CryptoExt pointer is UB. Therefore DB::Crypto is temporarily moved
+ * into DB::CryptoExt and moved back to m_userDataMap after the call to Execute().
+ */
+ DB::CryptoExt db(std::move(m_userDataMap[user].database));
+ try {
+ output = db.Execute(cmd);
+ m_userDataMap[user].database = std::move(*static_cast<DB::Crypto*>(&db));
+ return output;
+ } catch (const DB::SqlConnection::Exception::Base& e) {
+ m_userDataMap[user].database = std::move(*static_cast<DB::Crypto*>(&db));
+ throw;
+ }
+}
+
+} // namespace CKM
+
+
diff --git a/tools/ckm_db_tool/ckm-logic-ext.h b/tools/ckm_db_tool/ckm-logic-ext.h
new file mode 100644
index 00000000..515c41cd
--- /dev/null
+++ b/tools/ckm_db_tool/ckm-logic-ext.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2000 - 2015 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 ckm-logic-ext.h
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 1.0
+ */
+
+#pragma once
+
+#include <string>
+#include <ckm-logic.h>
+#include <dpl/db/sql_connection.h>
+
+namespace CKM {
+struct CKMLogicExt : public CKMLogic {
+ CKMLogicExt() : m_systemDbUnlocked(false) {}
+
+ DB::SqlConnection::Output Execute(uid_t user, const std::string& cmd);
+
+private:
+ bool m_systemDbUnlocked;
+};
+} // namespace CKM
diff --git a/tools/ckm_db_tool/ckm_db_tool.cpp b/tools/ckm_db_tool/ckm_db_tool.cpp
new file mode 100644
index 00000000..2ef8fdf4
--- /dev/null
+++ b/tools/ckm_db_tool/ckm_db_tool.cpp
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2000 - 2015 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 ckm_db_tool.cpp
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 1.0
+ */
+
+#include <iostream>
+#include <sstream>
+#include <exception>
+
+#include <ckm-logic-ext.h>
+
+#include <ckm/ckm-type.h>
+#include <ckm/ckm-error.h>
+#include <message-buffer.h>
+#include <dpl/db/sql_connection.h>
+#include <exception.h>
+
+using namespace std;
+using namespace CKM;
+
+namespace {
+const size_t MAX_LEN = 32;
+const char ELLIPSIS[] = "...";
+const size_t ELLIPSIS_LEN = sizeof(ELLIPSIS)/sizeof(ELLIPSIS[0]);
+
+const char* const SQL_TABLES = "SELECT name FROM sqlcipher_master "
+ "WHERE type IN ('table','view') AND name NOT LIKE 'sqlcipher_%' "
+ "UNION ALL "
+ "SELECT name FROM sqlcipher_temp_master "
+ "WHERE type IN ('table','view') "
+ "ORDER BY 1";
+
+const char* const SQL_SCHEMA = "SELECT sql FROM "
+ "(SELECT * FROM sqlcipher_master "
+ "UNION ALL "
+ "SELECT * FROM sqlcipher_temp_master) "
+ "WHERE type!='meta' AND sql!='NULL'"
+ "ORDER BY tbl_name, type DESC, name";
+} // namespace anonymous
+
+class DbWrapper {
+public:
+ DbWrapper(uid_t uid, Password pw) : m_uid(uid), m_pw(pw) {}
+
+ int unlock();
+ void lock();
+ void process(const string& cmd);
+
+private:
+ void displayRow(const DB::SqlConnection::Output::Row& row, bool trim);
+
+ uid_t m_uid;
+ Password m_pw;
+ CKMLogicExt m_logic;
+};
+
+int DbWrapper::unlock()
+{
+ // no unlock for system db
+ if (m_uid < 5000)
+ return CKM_API_SUCCESS;
+
+ int retCode;
+ RawBuffer ret = m_logic.unlockUserKey(m_uid, m_pw);
+ MessageBuffer buff;
+ buff.Push(ret);
+ buff.Deserialize(retCode);
+ return retCode;
+}
+
+void DbWrapper::lock()
+{
+ // no lock for system db
+ if (m_uid < 5000)
+ return;
+
+ m_logic.lockUserKey(m_uid);
+}
+
+void DbWrapper::process(const string& acmd)
+{
+ try {
+ string cmd = acmd;
+ bool trim = true;
+ if (acmd == ".tables") {
+ cmd = SQL_TABLES;
+ trim = false;
+ }
+ else if(acmd == ".schema") {
+ cmd = SQL_SCHEMA;
+ trim = false;
+ }
+
+ DB::SqlConnection::Output output = m_logic.Execute(m_uid, cmd);
+
+ if(output.GetNames().empty())
+ return;
+
+ displayRow(output.GetNames(), trim);
+ cout << "--------------------------" << endl;
+ for(const auto& row : output.GetValues()) {
+ displayRow(row, trim);
+ }
+ } catch (const DB::SqlConnection::Exception::Base& e) {
+ cout << e.GetMessage() << endl;
+ } catch (const Exc::Exception &e) {
+ cout << e.message() << endl;
+ } catch (const std::exception &e) {
+ cout << e.what() << endl;
+ } catch (...) {
+ cout << "Unexpected exception occurred" << endl;
+ }
+}
+
+void DbWrapper::displayRow(const DB::SqlConnection::Output::Row& row, bool trim)
+{
+ for(auto it = row.begin();it != row.end();it++) {
+ std::string col = *it;
+ if(trim && col.size() > MAX_LEN) {
+ col.resize(MAX_LEN);
+ col.replace(MAX_LEN-ELLIPSIS_LEN, ELLIPSIS_LEN, ELLIPSIS);
+ }
+ cout << col;
+ if(it+1 != row.end())
+ cout<< "|";
+ }
+ cout << endl;
+}
+
+void usage() {
+ cout << "ckm_db_tool - the command line tool for accessing key-manager encrypted databases." << endl;
+ cout << endl;
+ cout << "Usage: ckm_db_tool uid [password] [sql_command]" << endl;
+ cout << endl;
+ cout << "uid (mandatory) User id as in /opt/data/ckm/db-<uid>" << endl;
+ cout << "password (optional) Password used for database encryption. For system database (uid < 5000) no password should be used." << endl;
+ cout << "sql_command (optional) Sqlite3 command to execute on database. If empty the tool will enter interactive mode." << endl;
+ cout << endl;
+ cout << "Example:" << endl;
+ cout << "cmd_db_tool 5000 user-pass \"select * from names\"" << endl;
+}
+
+void internalHelp() {
+ cout << "[sqlite_command] executes sqlite command on database" << endl;
+ cout << ".tables shows a list of table names" << endl;
+ cout << ".schema shows Sqlite3 command used to create tables in the database" << endl;
+ cout << "help shows this help" << endl;
+ cout << "exit (Ctrl-D) quits the program" << endl;
+}
+
+int main(int argc, char* argv[])
+{
+ if(argc < 2 || !argv[1]) {
+ usage();
+ return -1;
+ }
+
+ // read uid
+ stringstream ss(argv[1]);
+ uid_t uid;
+ if(!(ss >> uid)) {
+ usage();
+ return -1;
+ }
+
+ int idx = 2;
+
+ // read password
+ Password pass;
+ if(uid >= 5000) {
+ if(argc > idx) {
+ pass = argv[idx];
+ idx++;
+ }
+ }
+
+ // read sqlite3 command
+ string argcmd;
+ if(argc > idx)
+ argcmd = argv[idx];
+
+ // unlock db
+ DbWrapper dbw(uid, pass);
+ int retCode = dbw.unlock();
+ if (retCode != CKM_API_SUCCESS ) {
+ cout << "Unlocking database failed: " << retCode << endl;
+ return -1;
+ }
+ cout << "Database unlocked" << endl;
+
+ for(;;) {
+ string cmd;
+ if (argcmd.empty()) {
+ cout << "> ";
+ if(!getline(cin, cmd)) {
+ cout << "exit" << endl;
+ break; // EOF
+ }
+ } else {
+ cmd = argcmd;
+ }
+
+ if(cmd == "exit")
+ break;
+ if(cmd == "help") {
+ internalHelp();
+ continue;
+ }
+
+ dbw.process(cmd);
+
+ if(!argcmd.empty())
+ break;
+ }
+ dbw.lock();
+ cout << "Database locked" << endl;
+
+ return 0;
+}
diff --git a/tools/ckm_db_tool/db-crypto-ext.cpp b/tools/ckm_db_tool/db-crypto-ext.cpp
new file mode 100644
index 00000000..92518aca
--- /dev/null
+++ b/tools/ckm_db_tool/db-crypto-ext.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 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 db-crypto-ext.cpp
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 1.0
+ * @brief Limited implementation of encrypted db access layer
+ */
+
+#include <db-crypto-ext.h>
+#include <dpl/exception.h>
+
+namespace CKM {
+namespace DB {
+
+SqlConnection::Output CryptoExt::Execute(const std::string& cmd) {
+ SqlConnection::Output out;
+ if(!m_connection) {
+ ThrowMsg(SqlConnection::Exception::ConnectionBroken, "Not connected to database");
+ }
+ m_connection->ExecCommand(&out, "%s", cmd.c_str());
+ return out;
+}
+} // namespace DB
+} // namespace CKM
diff --git a/tools/ckm_db_tool/db-crypto-ext.h b/tools/ckm_db_tool/db-crypto-ext.h
new file mode 100644
index 00000000..c4baeafa
--- /dev/null
+++ b/tools/ckm_db_tool/db-crypto-ext.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 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 db-crypto-ext.h
+ * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version 1.0
+ * @brief Header of encrypted db access layer
+ */
+
+#pragma once
+
+#include <db-crypto.h>
+#include <string>
+#include <utility>
+#include <dpl/db/sql_connection.h>
+
+namespace CKM {
+namespace DB {
+struct CryptoExt : public Crypto {
+ CryptoExt(Crypto orig) : Crypto(std::move(orig)) {}
+
+ SqlConnection::Output Execute(const std::string& cmd);
+};
+
+} // namespace DB
+} // namespace CKM
+