Merge branch 'prerelease'

This commit is contained in:
Stephen Lombardo
2019-05-29 16:44:35 -04:00
3 changed files with 39 additions and 45 deletions
+1
View File
@@ -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
View File
@@ -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;
-21
View File
@@ -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