TdDb: reuse derived sqlcipher version
GitOrigin-RevId: 28a94a5dee34f47850deb5cf1ca41e92e24bf648
This commit is contained in:
parent
45bfb1b384
commit
28596f1a3f
@ -301,7 +301,7 @@ Status TdDb::init_sqlite(int32 scheduler_id, const TdParameters ¶meters, DbK
|
|||||||
|
|
||||||
sqlite_path_ = sql_database_path;
|
sqlite_path_ = sql_database_path;
|
||||||
TRY_RESULT(db_instance, SqliteDb::change_key(sqlite_path_, key, old_key));
|
TRY_RESULT(db_instance, SqliteDb::change_key(sqlite_path_, key, old_key));
|
||||||
sql_connection_ = std::make_shared<SqliteConnectionSafe>(sql_database_path, key);
|
sql_connection_ = std::make_shared<SqliteConnectionSafe>(sql_database_path, key, db_instance.get_cipher_version());
|
||||||
sql_connection_->set(std::move(db_instance));
|
sql_connection_->set(std::move(db_instance));
|
||||||
auto &db = sql_connection_->get();
|
auto &db = sql_connection_->get();
|
||||||
|
|
||||||
|
@ -13,9 +13,10 @@
|
|||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
SqliteConnectionSafe::SqliteConnectionSafe(string path, DbKey key)
|
SqliteConnectionSafe::SqliteConnectionSafe(string path, DbKey key, optional<int32> cipher_version)
|
||||||
: path_(std::move(path)), lsls_connection_([path = path_, key = std::move(key)] {
|
: path_(std::move(path))
|
||||||
auto r_db = SqliteDb::open_with_key(path, key);
|
, lsls_connection_([path = path_, key = std::move(key), cipher_version = std::move(cipher_version)] {
|
||||||
|
auto r_db = SqliteDb::open_with_key(path, key, cipher_version.copy());
|
||||||
if (r_db.is_error()) {
|
if (r_db.is_error()) {
|
||||||
auto r_stat = stat(path);
|
auto r_stat = stat(path);
|
||||||
if (r_stat.is_error()) {
|
if (r_stat.is_error()) {
|
||||||
|
@ -12,13 +12,14 @@
|
|||||||
#include "td/db/SqliteDb.h"
|
#include "td/db/SqliteDb.h"
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/optional.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
class SqliteConnectionSafe {
|
class SqliteConnectionSafe {
|
||||||
public:
|
public:
|
||||||
SqliteConnectionSafe() = default;
|
SqliteConnectionSafe() = default;
|
||||||
explicit SqliteConnectionSafe(string path, DbKey key = DbKey::empty());
|
explicit SqliteConnectionSafe(string path, DbKey key = DbKey::empty(), optional<int32> cipher_version = {});
|
||||||
|
|
||||||
SqliteDb &get();
|
SqliteDb &get();
|
||||||
void set(SqliteDb &&db);
|
void set(SqliteDb &&db);
|
||||||
|
@ -171,15 +171,15 @@ Status SqliteDb::check_encryption() {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<SqliteDb> SqliteDb::open_with_key(CSlice path, const DbKey &db_key) {
|
Result<SqliteDb> SqliteDb::open_with_key(CSlice path, const DbKey &db_key, optional<int32> cipher_version) {
|
||||||
auto res = do_open_with_key(path, db_key, false);
|
auto res = do_open_with_key(path, db_key, cipher_version ? cipher_version.value() : 0);
|
||||||
if (res.is_error()) {
|
if (res.is_error() && !cipher_version) {
|
||||||
return do_open_with_key(path, db_key, true);
|
return do_open_with_key(path, db_key, 3);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<SqliteDb> SqliteDb::do_open_with_key(CSlice path, const DbKey &db_key, bool with_cipher_migrate) {
|
Result<SqliteDb> SqliteDb::do_open_with_key(CSlice path, const DbKey &db_key, int32 cipher_version) {
|
||||||
SqliteDb db;
|
SqliteDb db;
|
||||||
TRY_STATUS(db.init(path));
|
TRY_STATUS(db.init(path));
|
||||||
if (!db_key.is_empty()) {
|
if (!db_key.is_empty()) {
|
||||||
@ -188,15 +188,24 @@ Result<SqliteDb> SqliteDb::do_open_with_key(CSlice path, const DbKey &db_key, bo
|
|||||||
}
|
}
|
||||||
auto key = db_key_to_sqlcipher_key(db_key);
|
auto key = db_key_to_sqlcipher_key(db_key);
|
||||||
TRY_STATUS(db.exec(PSLICE() << "PRAGMA key = " << key));
|
TRY_STATUS(db.exec(PSLICE() << "PRAGMA key = " << key));
|
||||||
if (with_cipher_migrate) {
|
if (cipher_version != 0) {
|
||||||
LOG(INFO) << "Try Sqlcipher compatibility mode";
|
LOG(INFO) << "Try Sqlcipher compatibility mode with version=" << cipher_version;
|
||||||
TRY_STATUS(db.exec("PRAGMA cipher_compatibility = 3"));
|
TRY_STATUS(db.exec(PSLICE() << "PRAGMA cipher_compatibility = " << cipher_version));
|
||||||
}
|
}
|
||||||
|
db.set_cipher_version(cipher_version);
|
||||||
}
|
}
|
||||||
TRY_STATUS_PREFIX(db.check_encryption(), "Can't open database: ");
|
TRY_STATUS_PREFIX(db.check_encryption(), "Can't open database: ");
|
||||||
return std::move(db);
|
return std::move(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SqliteDb::set_cipher_version(int32 cipher_version) {
|
||||||
|
raw_->set_cipher_version(cipher_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<int32> SqliteDb::get_cipher_version() {
|
||||||
|
return raw_->get_cipher_version();
|
||||||
|
}
|
||||||
|
|
||||||
Result<SqliteDb> SqliteDb::change_key(CSlice path, const DbKey &new_db_key, const DbKey &old_db_key) {
|
Result<SqliteDb> SqliteDb::change_key(CSlice path, const DbKey &new_db_key, const DbKey &old_db_key) {
|
||||||
PerfWarningTimer perf("change key", 0.001);
|
PerfWarningTimer perf("change key", 0.001);
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "td/db/detail/RawSqliteDb.h"
|
#include "td/db/detail/RawSqliteDb.h"
|
||||||
|
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/optional.h"
|
||||||
#include "td/utils/Slice.h"
|
#include "td/utils/Slice.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ class SqliteDb {
|
|||||||
static Status destroy(Slice path) TD_WARN_UNUSED_RESULT;
|
static Status destroy(Slice path) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
// Anyway we can't change the key on the fly, so having static functions is more than enough
|
// Anyway we can't change the key on the fly, so having static functions is more than enough
|
||||||
static Result<SqliteDb> open_with_key(CSlice path, const DbKey &db_key);
|
static Result<SqliteDb> open_with_key(CSlice path, const DbKey &db_key, optional<int32> cipher_version = {});
|
||||||
static Result<SqliteDb> change_key(CSlice path, const DbKey &new_db_key, const DbKey &old_db_key);
|
static Result<SqliteDb> change_key(CSlice path, const DbKey &new_db_key, const DbKey &old_db_key);
|
||||||
|
|
||||||
Status last_error();
|
Status last_error();
|
||||||
@ -77,6 +78,8 @@ class SqliteDb {
|
|||||||
detail::RawSqliteDb::with_db_path(main_path, f);
|
detail::RawSqliteDb::with_db_path(main_path, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optional<int32> get_cipher_version();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit SqliteDb(std::shared_ptr<detail::RawSqliteDb> raw) : raw_(std::move(raw)) {
|
explicit SqliteDb(std::shared_ptr<detail::RawSqliteDb> raw) : raw_(std::move(raw)) {
|
||||||
}
|
}
|
||||||
@ -84,7 +87,8 @@ class SqliteDb {
|
|||||||
bool enable_logging_ = false;
|
bool enable_logging_ = false;
|
||||||
|
|
||||||
Status check_encryption();
|
Status check_encryption();
|
||||||
static Result<SqliteDb> do_open_with_key(CSlice path, const DbKey &db_key, bool with_cipher_migrate);
|
static Result<SqliteDb> do_open_with_key(CSlice path, const DbKey &db_key, int32 cipher_version);
|
||||||
|
void set_cipher_version(int32 cipher_version);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/optional.h"
|
||||||
#include "td/utils/Slice.h"
|
#include "td/utils/Slice.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
@ -56,10 +57,19 @@ class RawSqliteDb {
|
|||||||
return begin_cnt_ == 0;
|
return begin_cnt_ == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_cipher_version(int32 cipher_version) {
|
||||||
|
cipher_version_ = cipher_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<int32> get_cipher_version() const {
|
||||||
|
return cipher_version_.copy();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sqlite3 *db_;
|
sqlite3 *db_;
|
||||||
std::string path_;
|
std::string path_;
|
||||||
size_t begin_cnt_{0};
|
size_t begin_cnt_{0};
|
||||||
|
optional<int32> cipher_version_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
Loading…
Reference in New Issue
Block a user