diff --git a/src/crypto.c b/src/crypto.c index 73d66e7..54b0a1c 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -342,10 +342,10 @@ void sqlite3_activate_see(const char* in) { } static int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) { + int db_index; if(zDb == NULL){ return 0; } - int db_index; for(db_index = 0; db_index < db->nDb; db_index++) { struct Db *pDb = &db->aDb[db_index]; if(strcmp(pDb->zName, zDb) == 0) { @@ -418,7 +418,7 @@ int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) { */ rc = sqlite3BtreeBeginTrans(pDb->pBt, 1); /* begin write transaction */ sqlite3PagerPagecount(pPager, &page_count); - for(pgno = 1; rc == SQLITE_OK && pgno <= page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */ + for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */ if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */ rc = sqlite3PagerGet(pPager, pgno, &page); if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */ diff --git a/src/crypto.h b/src/crypto.h index 8b5c64f..7777565 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -152,7 +152,7 @@ static void cipher_hex2bin(const char *hex, int sz, unsigned char *out){ static void cipher_bin2hex(const unsigned char* in, int sz, char *out) { int i; for(i=0; i < sz; i++) { - sprintf(out + (i*2), "%02x ", in[i]); + sqlite3_snprintf(2, out + (i*2), "%02x ", in[i]); } } diff --git a/src/crypto_impl.c b/src/crypto_impl.c index 5071703..46dff89 100644 --- a/src/crypto_impl.c +++ b/src/crypto_impl.c @@ -906,6 +906,43 @@ const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx) { return ctx->read_ctx->provider->get_provider_name(ctx->read_ctx); } + +static int sqlcipher_check_connection(const char *filename, char *key, int key_sz, char *sql) { + int rc; + sqlite3 *db = NULL; + sqlite3_stmt *statement = NULL; + char *query_sqlite_master = "SELECT count(*) FROM sqlite_master;"; + + rc = sqlite3_open(filename, &db); + if(rc != SQLITE_OK){ + goto cleanup; + } + rc = sqlite3_key(db, key, key_sz); + if(rc != SQLITE_OK){ + goto cleanup; + } + rc = sqlite3_exec(db, sql, NULL, NULL, NULL); + if(rc != SQLITE_OK){ + goto cleanup; + } + rc = sqlite3_prepare(db, query_sqlite_master, -1, &statement, NULL); + if(rc != SQLITE_OK){ + goto cleanup; + } + if(sqlite3_step(statement) == SQLITE_ROW){ + rc = SQLITE_OK; + } + +cleanup: + if(statement){ + sqlite3_finalize(statement); + } + if(db){ + sqlite3_close(db); + } + return rc; +} + int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { u32 meta; int rc = 0; @@ -922,11 +959,11 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { char *query_sqlite_master = "SELECT count(*) from sqlite_master;"; char *pragma_hmac_off = "PRAGMA cipher_use_hmac = OFF;"; char *pragma_4k_kdf_iter = "PRAGMA kdf_iter = 4000;"; + char *pragma_1x_and_4k; char *key; int key_sz; int upgrade_1x_format = 0; int upgrade_4k_format = 0; - sqlite3 *test; char *err = 0; static const unsigned char aCopy[] = { BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */ @@ -935,6 +972,8 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { BTREE_USER_VERSION, 0, /* Preserve the user version */ BTREE_APPLICATION_ID, 0, /* Preserve the application id */ }; + + key_sz = ctx->read_ctx->pass_sz + 1; key = sqlcipher_malloc(key_sz); memset(key, 0, key_sz); @@ -944,6 +983,12 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { char *attach_command = sqlite3_mprintf("ATTACH DATABASE '%s-migrated' as migrate KEY '%s';", db_filename, key); + const char* commands[] = { + upgrade_4k_format == 1 ? pragma_4k_kdf_iter : "", + upgrade_1x_format == 1 ? pragma_hmac_off : "", + attach_command, + "SELECT sqlcipher_export('migrate');", + }; int rc = sqlcipher_check_connection(db_filename, key, key_sz, ""); if(rc == SQLITE_OK){ @@ -959,7 +1004,7 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { } // Version 1 - check both no hmac and 4k together - char *pragma_1x_and_4k = sqlite3_mprintf("%s%s", pragma_hmac_off, + pragma_1x_and_4k = sqlite3_mprintf("%s%s", pragma_hmac_off, pragma_4k_kdf_iter); rc = sqlcipher_check_connection(db_filename, key, key_sz, pragma_1x_and_4k); sqlite3_free(pragma_1x_and_4k); @@ -974,13 +1019,8 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { goto handle_error; } - const char *commands[] = { - upgrade_4k_format == 1 ? pragma_4k_kdf_iter : "", - upgrade_1x_format == 1 ? pragma_hmac_off : "", - attach_command, - "SELECT sqlcipher_export('migrate');", - }; - for(command_idx = 0; command_idx < ArraySize(commands); command_idx++){ + + for(command_idx = 0; command_idx < (sizeof(commands)/sizeof(commands[0])); command_idx++){ const char *command = commands[command_idx]; if(strcmp(command, "") == 0){ continue; @@ -994,6 +1034,10 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { sqlcipher_free(key, key_sz); if(rc == SQLITE_OK){ + Btree *pDest; + Btree *pSrc; + int i = 0; + if( !db->autoCommit ){ CODEC_TRACE(("cannot migrate from within a transaction")); goto handle_error; @@ -1014,9 +1058,9 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder); db->xTrace = 0; - Btree *pDest = db->aDb[0].pBt; + pDest = db->aDb[0].pBt; pDb = &(db->aDb[db->nDb-1]); - Btree *pSrc = pDb->pBt; + pSrc = pDb->pBt; rc = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL); rc = sqlite3BtreeBeginTrans(pSrc, 2); @@ -1029,8 +1073,7 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { sqlite3CodecGetKey(db, db->nDb - 1, (void**)&key, &password_sz); sqlite3CodecAttach(db, 0, key, password_sz); - int i = 0; - for(i=0; i