summaryrefslogtreecommitdiff
path: root/src/manager/dpl
diff options
context:
space:
mode:
authorZofia Abramowska <z.abramowska@samsung.com>2014-05-29 10:45:39 +0200
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>2014-09-12 14:57:08 +0200
commitfd177b0eff5862b24e4f1562f518f93e7c412ef4 (patch)
tree127b60bb91c686054a7c304de62ad6bb3b5d3cba /src/manager/dpl
parentd04f705ad7cc4c8956f3c7e7213dcecc064245a1 (diff)
downloadkey-manager-fd177b0eff5862b24e4f1562f518f93e7c412ef4.tar.gz
key-manager-fd177b0eff5862b24e4f1562f518f93e7c412ef4.tar.bz2
key-manager-fd177b0eff5862b24e4f1562f518f93e7c412ef4.zip
Adapt SQLConnection to sqlcipher
Added public methods for key setting and resetting using sqlcipher sqlite3_key and sqlite3_rekey functions. Change-Id: I8a1136beb1bb9b962b72635c254eb211237fc851
Diffstat (limited to 'src/manager/dpl')
-rw-r--r--src/manager/dpl/db/include/dpl/db/sql_connection.h40
-rw-r--r--src/manager/dpl/db/src/sql_connection.cpp63
2 files changed, 94 insertions, 9 deletions
diff --git a/src/manager/dpl/db/include/dpl/db/sql_connection.h b/src/manager/dpl/db/include/dpl/db/sql_connection.h
index 4d0590c2..41b0c119 100644
--- a/src/manager/dpl/db/include/dpl/db/sql_connection.h
+++ b/src/manager/dpl/db/include/dpl/db/sql_connection.h
@@ -33,6 +33,7 @@
#include <string>
#include <dpl/assert.h>
#include <stdint.h>
+#include <vector>
namespace CKM {
namespace DB {
@@ -53,6 +54,7 @@ class SqlConnection
DECLARE_EXCEPTION_TYPE(Base, ConnectionBroken)
DECLARE_EXCEPTION_TYPE(Base, InternalError)
DECLARE_EXCEPTION_TYPE(Base, InvalidColumn)
+ DECLARE_EXCEPTION_TYPE(Base, InvalidArguments)
};
typedef int ColumnIndex;
@@ -372,12 +374,7 @@ class SqlConnection
enum Option
{
RO = SQLCIPHER_OPEN_NOMUTEX | SQLCIPHER_OPEN_READONLY,
- /**
- * *TODO: please remove CREATE option from RW flag when all places
- * that need that switched do CRW
- */
- RW = SQLCIPHER_OPEN_NOMUTEX | SQLCIPHER_OPEN_READWRITE |
- SQLCIPHER_OPEN_CREATE,
+ RW = SQLCIPHER_OPEN_NOMUTEX | SQLCIPHER_OPEN_READWRITE,
CRW = RW | SQLCIPHER_OPEN_CREATE
};
};
@@ -416,6 +413,8 @@ class SqlConnection
// Synchronization object
std::unique_ptr<SynchronizationObject> m_synchronizationObject;
+ bool m_isKeySet;
+
virtual void Connect(const std::string &address,
Flag::Option = Flag::RO);
virtual void Disconnect();
@@ -448,6 +447,35 @@ class SqlConnection
virtual ~SqlConnection();
/**
+ * Added extension for encryption functionality:
+ *
+ * SetKey gives sqlcipher key, which will be used to encrypt the database
+ * This function will only fail because of invalid arguments. To check if
+ * database can be opened with provided key, it is necessary to perform
+ * some operation on the database (i.e. read from it) and confirm if it
+ * succeeds.
+ * Password must have length >= 1.
+ *
+ * @param rawPass password given in raw binary format
+ */
+ void SetKey(const std::vector<unsigned char> &rawPass);
+
+ /**
+ * ResetKey is used for changing key used for database encryption.
+ * If key was already set by using SetKey, this function will only change it.
+ * If no key was yet set, this function first will set key with rawPassOld and
+ * then change it to rawPassNew.
+ * Same rules for failing apply as for SetKey.
+ * Both password must have length >=1.
+ *
+ * @param rawPassOld current password for encryption in raw binary format
+ * @param rawPassNew new password for encryption in raw binary format
+ *
+ */
+ void ResetKey(const std::vector<unsigned char> &rawPassOld,
+ const std::vector<unsigned char> &rawPassNew);
+
+ /**
* Execute SQL command without result
*
* @param format
diff --git a/src/manager/dpl/db/src/sql_connection.cpp b/src/manager/dpl/db/src/sql_connection.cpp
index 1a1a10ec..8015bccd 100644
--- a/src/manager/dpl/db/src/sql_connection.cpp
+++ b/src/manager/dpl/db/src/sql_connection.cpp
@@ -368,7 +368,7 @@ void SqlConnection::DataCommand::Reset()
{
/*
* According to:
- * http://www.sqlite.org/c3ref/stmt.html
+ * http://www.sqllite.org/c3ref/stmt.html
*
* if last sqlcipher3_step command on this stmt returned an error,
* then sqlcipher3_reset will return that error, althought it is not an error.
@@ -625,6 +625,62 @@ void SqlConnection::Connect(const std::string &address,
TurnOnForeignKeys();
}
+static std::string rawToHexString(const std::vector<unsigned char> &raw) {
+ std::string str(raw.size() * 2, '0');
+ for (std::size_t i = 0; i < raw.size(); i++)
+ sprintf(&str[i*2], "%02X", raw[i]);
+ return str;
+}
+
+void SqlConnection::SetKey(const std::vector<unsigned char> &rawPass){
+ if (m_connection == NULL) {
+ LogPedantic("Cannot set key. No connection to DB!");
+ return;
+ }
+ std::string pass = "x'" + rawToHexString(rawPass) + "'";
+ int result = sqlcipher3_key(m_connection, pass.c_str(), pass.length());
+ if (result == SQLCIPHER_OK) {
+ LogPedantic("Set key on DB");
+ } else {
+ //sqlcipher3_key fails only when m_connection == NULL || key == NULL ||
+ // key length == 0
+ LogPedantic("Failed to set key on DB");
+ ThrowMsg(Exception::InvalidArguments, result);
+ }
+
+ m_isKeySet = true;
+};
+
+void SqlConnection::ResetKey(const std::vector<unsigned char> &rawPassOld,
+ const std::vector<unsigned char> &rawPassNew) {
+ if (m_connection == NULL) {
+ LogPedantic("Cannot reset key. No connection to DB!");
+ return;
+ }
+ // sqlcipher3_rekey requires for key to be already set
+ if (!m_isKeySet)
+ SetKey(rawPassOld);
+
+ std::string pass = "x'" + rawToHexString(rawPassNew) + "'";
+ int result = sqlcipher3_rekey(m_connection, pass.c_str(), pass.length());
+ if (result == SQLCIPHER_OK) {
+ LogPedantic("Reset key on DB");
+ } else {
+ //sqlcipher3_rekey fails only when m_connection == NULL || key == NULL ||
+ // key length == 0
+ LogPedantic("Failed to reset key on DB");
+ ThrowMsg(Exception::InvalidArguments, result);
+ }
+ //Wiping out the key (required)
+ pass.assign(pass.length(), '0');
+ for(std::size_t i = 0; i < pass.length(); i++) {
+ if(pass[i] != '0') {
+ LogPedantic("Wiping key failed.");
+ ThrowMsg(Exception::InternalError, "Wiping key failed");
+ }
+ }
+}
+
void SqlConnection::Disconnect()
{
if (m_connection == NULL) {
@@ -663,7 +719,7 @@ bool SqlConnection::CheckTableExist(const char *tableName)
}
DataCommandAutoPtr command =
- PrepareDataCommand("select tbl_name from sqlite_master where name=?;");
+ PrepareDataCommand("select tbl_name from sqlcipher_master where name=?;");
command->BindString(1, tableName);
@@ -680,7 +736,8 @@ SqlConnection::SqlConnection(const std::string &address,
SynchronizationObject *synchronizationObject) :
m_connection(NULL),
m_dataCommandsCount(0),
- m_synchronizationObject(synchronizationObject)
+ m_synchronizationObject(synchronizationObject),
+ m_isKeySet(false)
{
LogPedantic("Opening database connection to: " << address);