mirror of
https://github.com/status-im/sqlcipher.git
synced 2026-08-30 22:11:14 +00:00
Merge branch 'prerelease'
This commit is contained in:
@@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.
|
||||
## [4.2.0] - (May 2019 - [4.2.0 changes])
|
||||
- Adds PRAGMA cipher_integrity_check to perform independent verification of page HMACs
|
||||
- Updates baseline to upstream SQLite 3.28.0
|
||||
- Improves PRAGMA cipher_migrate to handle keys containing non-terminating zero bytes
|
||||
|
||||
## [4.1.0] - (March 2019 - [4.1.0 changes])
|
||||
- Defer reading salt from header until key derivation is triggered
|
||||
|
||||
+38
-24
@@ -1256,7 +1256,7 @@ cleanup:
|
||||
|
||||
int sqlcipher_codec_ctx_integrity_check(codec_ctx *ctx, Parse *pParse, char *column) {
|
||||
Pgno page = 1;
|
||||
int i, trans_rc, rc = 0;
|
||||
int i, rc = 0;
|
||||
char *result;
|
||||
unsigned char *hmac_out = NULL;
|
||||
sqlite3_file *fd = sqlite3PagerFile(ctx->pBt->pBt->pPager);
|
||||
@@ -1284,13 +1284,6 @@ int sqlcipher_codec_ctx_integrity_check(codec_ctx *ctx, Parse *pParse, char *col
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* establish an exclusive lock on the database */
|
||||
if((trans_rc = sqlite3BtreeBeginTrans(ctx->pBt, 2, 0)) != SQLITE_OK) {
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, "unable to lock database", P4_TRANSIENT);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sqlite3OsFileSize(fd, &file_sz);
|
||||
hmac_out = sqlcipher_malloc(ctx->hmac_sz);
|
||||
|
||||
@@ -1330,7 +1323,6 @@ int sqlcipher_codec_ctx_integrity_check(codec_ctx *ctx, Parse *pParse, char *col
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if(trans_rc == SQLITE_OK) sqlite3BtreeRollback(ctx->pBt, SQLITE_OK, 0);
|
||||
if(hmac_out != NULL) sqlcipher_free(hmac_out, ctx->hmac_sz);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -1342,7 +1334,6 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
|
||||
const char *db_filename = sqlite3_db_filename(db, "main");
|
||||
char *set_user_version = NULL, *pass = NULL, *attach_command = NULL, *migrated_db_filename = NULL, *keyspec = NULL, *temp = NULL, *journal_mode = NULL, *set_journal_mode = NULL, *pragma_compat = NULL;
|
||||
Btree *pDest = NULL, *pSrc = NULL;
|
||||
const char* commands[5];
|
||||
sqlite3_file *srcfile, *destfile;
|
||||
#if defined(_WIN32) || defined(SQLITE_OS_WINRT)
|
||||
LPWSTR w_db_filename = NULL, w_migrated_db_filename = NULL;
|
||||
@@ -1389,23 +1380,46 @@ migrate:
|
||||
memcpy(migrated_db_filename, temp, sqlite3Strlen30(temp));
|
||||
sqlcipher_free(temp, sqlite3Strlen30(temp));
|
||||
|
||||
attach_command = sqlite3_mprintf("ATTACH DATABASE '%s' as migrate KEY '%q';", migrated_db_filename, pass);
|
||||
attach_command = sqlite3_mprintf("ATTACH DATABASE '%s' as migrate;", migrated_db_filename, pass);
|
||||
set_user_version = sqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version);
|
||||
|
||||
commands[0] = pragma_compat;
|
||||
commands[1] = "PRAGMA journal_mode = delete;"; /* force journal mode to DELETE, we will set it back later if different */
|
||||
commands[2] = attach_command;
|
||||
commands[3] = "SELECT sqlcipher_export('migrate');";
|
||||
commands[4] = set_user_version;
|
||||
|
||||
for(i = 0; i < ArraySize(commands); i++){
|
||||
rc = sqlite3_exec(db, commands[i], NULL, NULL, NULL);
|
||||
if(rc != SQLITE_OK){
|
||||
CODEC_TRACE("migration step %d failed error code %d\n", i, rc);
|
||||
goto handle_error;
|
||||
}
|
||||
rc = sqlite3_exec(db, pragma_compat, NULL, NULL, NULL);
|
||||
if(rc != SQLITE_OK){
|
||||
CODEC_TRACE("set compatibility mode failed, error code %d\n", rc);
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
|
||||
/* force journal mode to DELETE, we will set it back later if different */
|
||||
rc = sqlite3_exec(db, "PRAGMA journal_mode = delete;", NULL, NULL, NULL);
|
||||
if(rc != SQLITE_OK){
|
||||
CODEC_TRACE("force journal mode DELETE failed, error code %d\n", rc);
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
rc = sqlite3_exec(db, attach_command, NULL, NULL, NULL);
|
||||
if(rc != SQLITE_OK){
|
||||
CODEC_TRACE("attach failed, error code %d\n", rc);
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
rc = sqlite3_key_v2(db, "migrate", pass, pass_sz);
|
||||
if(rc != SQLITE_OK){
|
||||
CODEC_TRACE("keying attached database failed, error code %d\n", rc);
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
rc = sqlite3_exec(db, "SELECT sqlcipher_export('migrate');", NULL, NULL, NULL);
|
||||
if(rc != SQLITE_OK){
|
||||
CODEC_TRACE("sqlcipher_export failed, error code %d\n", rc);
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
rc = sqlite3_exec(db, set_user_version, NULL, NULL, NULL);
|
||||
if(rc != SQLITE_OK){
|
||||
CODEC_TRACE("set user version failed, error code %d\n", rc);
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
if( !db->autoCommit ){
|
||||
CODEC_TRACE("cannot migrate from within a transaction");
|
||||
goto handle_error;
|
||||
|
||||
@@ -308,25 +308,4 @@ do_test integrity-check-plaintext-header {
|
||||
} {{} 1 {{HMAC verification failed for page 1} {HMAC verification failed for page 2}}}
|
||||
file delete -force test.db
|
||||
|
||||
# verify database locking for cipher_integrity_check
|
||||
do_test integrity-check-locking {
|
||||
sqlite_orig db test.db
|
||||
sqlite_orig db2 test.db
|
||||
|
||||
execsql {
|
||||
PRAGMA key = 'test';
|
||||
CREATE TABLE t1(a,b);
|
||||
BEGIN EXCLUSIVE;
|
||||
INSERT INTO t1(a,b) VALUES (1,2);
|
||||
}
|
||||
|
||||
execsql {
|
||||
PRAGMA key = 'test';
|
||||
PRAGMA cipher_integrity_check;
|
||||
} db2
|
||||
} {{unable to lock database}}
|
||||
sqlite_orig db test.db
|
||||
sqlite_orig db2 test.db
|
||||
file delete -force test.db
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user