From f2912623bc60f4055c4b0a633cd1df8ea1195a57 Mon Sep 17 00:00:00 2001 From: Stephen Lombardo Date: Tue, 3 Sep 2013 16:47:11 -0400 Subject: [PATCH 1/4] fix regression itroduced in prior commit --- src/crypto.h | 2 +- src/crypto_impl.c | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/crypto.h b/src/crypto.h index 7777565..f7738db 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++) { - sqlite3_snprintf(2, out + (i*2), "%02x ", in[i]); + sqlite3_snprintf(3, out + (i*2), "%02x ", in[i]); } } diff --git a/src/crypto_impl.c b/src/crypto_impl.c index 46dff89..cd5abd2 100644 --- a/src/crypto_impl.c +++ b/src/crypto_impl.c @@ -389,10 +389,9 @@ static int sqlcipher_cipher_ctx_set_keyspec(cipher_ctx *ctx, const unsigned char ctx->keyspec[0] = 'x'; ctx->keyspec[1] = '\''; - ctx->keyspec[ctx->keyspec_sz - 1] = '\''; cipher_bin2hex(key, key_sz, ctx->keyspec + 2); cipher_bin2hex(salt, salt_sz, ctx->keyspec + (key_sz * 2) + 2); - + ctx->keyspec[ctx->keyspec_sz - 1] = '\''; return SQLITE_OK; } @@ -980,15 +979,9 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { memcpy(key, ctx->read_ctx->pass, ctx->read_ctx->pass_sz); if(db_filename){ - + const char* commands[4]; 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){ @@ -1019,7 +1012,11 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { goto handle_error; } - + commands[0] = upgrade_4k_format == 1 ? pragma_4k_kdf_iter : ""; + commands[1] = upgrade_1x_format == 1 ? pragma_hmac_off : ""; + commands[2] = attach_command; + commands[3] = "SELECT sqlcipher_export('migrate');"; + for(command_idx = 0; command_idx < (sizeof(commands)/sizeof(commands[0])); command_idx++){ const char *command = commands[command_idx]; if(strcmp(command, "") == 0){ From 16167e9855c05b7801e3341391914ed263f3a2f1 Mon Sep 17 00:00:00 2001 From: Stephen Lombardo Date: Tue, 3 Sep 2013 16:54:23 -0400 Subject: [PATCH 2/4] restore use of ArraySize convenience function --- src/crypto_impl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crypto_impl.c b/src/crypto_impl.c index cd5abd2..f700aaa 100644 --- a/src/crypto_impl.c +++ b/src/crypto_impl.c @@ -1017,7 +1017,7 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { commands[2] = attach_command; commands[3] = "SELECT sqlcipher_export('migrate');"; - for(command_idx = 0; command_idx < (sizeof(commands)/sizeof(commands[0])); command_idx++){ + for(command_idx = 0; command_idx < ArraySize(commands); command_idx++){ const char *command = commands[command_idx]; if(strcmp(command, "") == 0){ continue; @@ -1070,7 +1070,7 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { sqlite3CodecGetKey(db, db->nDb - 1, (void**)&key, &password_sz); sqlite3CodecAttach(db, 0, key, password_sz); - for(i=0; i<(sizeof(aCopy)/sizeof(aCopy[0])); i+=2){ + for(i=0; i Date: Tue, 3 Sep 2013 17:29:13 -0400 Subject: [PATCH 3/4] remove unused variables --- src/crypto_impl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/crypto_impl.c b/src/crypto_impl.c index f700aaa..e15a6cf 100644 --- a/src/crypto_impl.c +++ b/src/crypto_impl.c @@ -955,7 +955,6 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { sqlite3 *db = ctx->pBt->db; const char *db_filename = sqlite3_db_filename(db, "main"); char *migrated_db_filename = sqlite3_mprintf("%s-migrated", db_filename); - 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; @@ -963,7 +962,6 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { int key_sz; int upgrade_1x_format = 0; int upgrade_4k_format = 0; - char *err = 0; static const unsigned char aCopy[] = { BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */ BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */ From 9d84aca41debd660519883f5d88a02c8bdcc5a24 Mon Sep 17 00:00:00 2001 From: Nick Parker Date: Thu, 12 Sep 2013 09:16:21 -0500 Subject: [PATCH 4/4] Proper format for key on attach, migrate user_version --- src/crypto_impl.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/crypto_impl.c b/src/crypto_impl.c index e15a6cf..804506f 100644 --- a/src/crypto_impl.c +++ b/src/crypto_impl.c @@ -906,11 +906,11 @@ const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx) { } -static int sqlcipher_check_connection(const char *filename, char *key, int key_sz, char *sql) { +static int sqlcipher_check_connection(const char *filename, char *key, int key_sz, char *sql, int *user_version) { int rc; sqlite3 *db = NULL; sqlite3_stmt *statement = NULL; - char *query_sqlite_master = "SELECT count(*) FROM sqlite_master;"; + char *query_user_version = "PRAGMA user_version;"; rc = sqlite3_open(filename, &db); if(rc != SQLITE_OK){ @@ -924,11 +924,13 @@ static int sqlcipher_check_connection(const char *filename, char *key, int key_s if(rc != SQLITE_OK){ goto cleanup; } - rc = sqlite3_prepare(db, query_sqlite_master, -1, &statement, NULL); + rc = sqlite3_prepare(db, query_user_version, -1, &statement, NULL); if(rc != SQLITE_OK){ goto cleanup; } - if(sqlite3_step(statement) == SQLITE_ROW){ + rc = sqlite3_step(statement); + if(rc == SQLITE_ROW){ + *user_version = sqlite3_column_int(statement, 0); rc = SQLITE_OK; } @@ -958,8 +960,10 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { char *pragma_hmac_off = "PRAGMA cipher_use_hmac = OFF;"; char *pragma_4k_kdf_iter = "PRAGMA kdf_iter = 4000;"; char *pragma_1x_and_4k; + char *set_user_version; char *key; int key_sz; + int user_version = 0; int upgrade_1x_format = 0; int upgrade_4k_format = 0; static const unsigned char aCopy[] = { @@ -977,18 +981,18 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { memcpy(key, ctx->read_ctx->pass, ctx->read_ctx->pass_sz); if(db_filename){ - const char* commands[4]; - char *attach_command = sqlite3_mprintf("ATTACH DATABASE '%s-migrated' as migrate KEY '%s';", + const char* commands[5]; + char *attach_command = sqlite3_mprintf("ATTACH DATABASE '%s-migrated' as migrate KEY '%q';", db_filename, key); - int rc = sqlcipher_check_connection(db_filename, key, key_sz, ""); + int rc = sqlcipher_check_connection(db_filename, key, key_sz, "", &user_version); if(rc == SQLITE_OK){ CODEC_TRACE(("No upgrade required - exiting\n")); goto exit; } // Version 2 - check for 4k with hmac format - rc = sqlcipher_check_connection(db_filename, key, key_sz, pragma_4k_kdf_iter); + rc = sqlcipher_check_connection(db_filename, key, key_sz, pragma_4k_kdf_iter, &user_version); if(rc == SQLITE_OK) { CODEC_TRACE(("Version 2 format found\n")); upgrade_4k_format = 1; @@ -997,7 +1001,7 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { // Version 1 - check both no hmac and 4k together 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); + rc = sqlcipher_check_connection(db_filename, key, key_sz, pragma_1x_and_4k, &user_version); sqlite3_free(pragma_1x_and_4k); if(rc == SQLITE_OK) { CODEC_TRACE(("Version 1 format found\n")); @@ -1010,10 +1014,12 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { goto handle_error; } + set_user_version = sqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version); commands[0] = upgrade_4k_format == 1 ? pragma_4k_kdf_iter : ""; commands[1] = upgrade_1x_format == 1 ? pragma_hmac_off : ""; commands[2] = attach_command; commands[3] = "SELECT sqlcipher_export('migrate');"; + commands[4] = set_user_version; for(command_idx = 0; command_idx < ArraySize(commands); command_idx++){ const char *command = commands[command_idx]; @@ -1026,6 +1032,7 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { } } sqlite3_free(attach_command); + sqlite3_free(set_user_version); sqlcipher_free(key, key_sz); if(rc == SQLITE_OK){