adds PRAGMA cipher_compatibility and cipher_default_compatibility
This commit is contained in:
parent
60b49b6826
commit
e4b66d6cc8
Binary file not shown.
104
src/crypto.c
104
src/crypto.c
|
@ -369,7 +369,6 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef
|
|||
} else if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) {
|
||||
rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512);
|
||||
}
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
} else {
|
||||
int algorithm = sqlcipher_get_default_hmac_algorithm();
|
||||
if(algorithm == SQLCIPHER_HMAC_SHA1) {
|
||||
|
@ -415,7 +414,6 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef
|
|||
} else if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) {
|
||||
rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512);
|
||||
}
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
} else {
|
||||
int algorithm = sqlcipher_get_default_kdf_algorithm();
|
||||
if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
|
||||
|
@ -427,6 +425,108 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef
|
|||
}
|
||||
}
|
||||
}else
|
||||
if( sqlite3StrICmp(zLeft,"cipher_compatibility")==0 ){
|
||||
if(ctx) {
|
||||
if(zRight) {
|
||||
int version = atoi(zRight);
|
||||
|
||||
switch(version) {
|
||||
case 1:
|
||||
rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 4000);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 0);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 4000);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 64000);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
break;
|
||||
|
||||
default:
|
||||
rc = sqlcipher_codec_ctx_set_pagesize(ctx, 4096);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA512);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA512);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 256000);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
break;
|
||||
}
|
||||
|
||||
rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
|
||||
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
|
||||
}
|
||||
}
|
||||
}else
|
||||
if( sqlite3StrICmp(zLeft,"cipher_default_compatibility")==0 ){
|
||||
if(zRight) {
|
||||
int version = atoi(zRight);
|
||||
switch(version) {
|
||||
case 1:
|
||||
sqlcipher_set_default_pagesize(1024);
|
||||
sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
|
||||
sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
|
||||
sqlcipher_set_default_kdf_iter(4000);
|
||||
sqlcipher_set_default_use_hmac(0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
sqlcipher_set_default_pagesize(1024);
|
||||
sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
|
||||
sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
|
||||
sqlcipher_set_default_kdf_iter(4000);
|
||||
sqlcipher_set_default_use_hmac(1);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
sqlcipher_set_default_pagesize(1024);
|
||||
sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
|
||||
sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
|
||||
sqlcipher_set_default_kdf_iter(64000);
|
||||
sqlcipher_set_default_use_hmac(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
sqlcipher_set_default_pagesize(4096);
|
||||
sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512);
|
||||
sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512);
|
||||
sqlcipher_set_default_kdf_iter(256000);
|
||||
sqlcipher_set_default_use_hmac(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else
|
||||
if( sqlite3StrICmp(zLeft,"cipher_memory_security")==0 ){
|
||||
if( zRight ) {
|
||||
sqlcipher_set_mem_security(sqlite3GetBoolean(zRight,1));
|
||||
|
|
|
@ -1235,14 +1235,11 @@ cleanup:
|
|||
}
|
||||
|
||||
int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
|
||||
int i, pass_sz, keyspec_sz, nRes, user_version, upgrade_from, rc, oflags;
|
||||
int i, pass_sz, keyspec_sz, nRes, user_version, rc, oflags;
|
||||
Db *pDb = 0;
|
||||
sqlite3 *db = ctx->pBt->db;
|
||||
const char *db_filename = sqlite3_db_filename(db, "main");
|
||||
char *v1_pragmas = "PRAGMA cipher_use_hmac = OFF; PRAGMA kdf_iter = 4000; PRAGMA cipher_page_size = 1024; PRAGMA cipher_hmac_algorithm = HMAC_SHA1; PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;";
|
||||
char *v2_pragmas = "PRAGMA kdf_iter = 4000; PRAGMA cipher_page_size = 1024; PRAGMA cipher_hmac_algorithm = HMAC_SHA1; PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;";
|
||||
char *v3_pragmas = "PRAGMA kdf_iter = 64000; PRAGMA cipher_page_size = 1024; PRAGMA cipher_hmac_algorithm = HMAC_SHA1; PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;";
|
||||
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;
|
||||
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;
|
||||
|
@ -1250,7 +1247,7 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
|
|||
LPWSTR w_db_filename = NULL, w_migrated_db_filename = NULL;
|
||||
int w_db_filename_sz = 0, w_migrated_db_filename_sz = 0;
|
||||
#endif
|
||||
pass_sz = keyspec_sz = rc = user_version = upgrade_from = 0;
|
||||
pass_sz = keyspec_sz = rc = user_version = 0;
|
||||
|
||||
if(!db_filename || sqlite3Strlen30(db_filename) < 1)
|
||||
goto cleanup; /* exit immediately if this is an in memory database */
|
||||
|
@ -1268,29 +1265,19 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Version 3 - check for 64k with hmac format and 1024 page size */
|
||||
rc = sqlcipher_check_connection(db_filename, pass, pass_sz, v3_pragmas, &user_version, &journal_mode);
|
||||
for(int i = 3; i > 0; i--) {
|
||||
pragma_compat = sqlite3_mprintf("PRAGMA cipher_compatibility = %d;", i);
|
||||
rc = sqlcipher_check_connection(db_filename, pass, pass_sz, pragma_compat, &user_version, &journal_mode);
|
||||
if(rc == SQLITE_OK) {
|
||||
CODEC_TRACE("Version 3 format found\n");
|
||||
upgrade_from = 3;
|
||||
CODEC_TRACE("Version %d format found\n", i);
|
||||
goto migrate;
|
||||
}
|
||||
|
||||
/* Version 2 - check for 4k with hmac format and 1024 page size */
|
||||
rc = sqlcipher_check_connection(db_filename, pass, pass_sz, v2_pragmas, &user_version, &journal_mode);
|
||||
if(rc == SQLITE_OK) {
|
||||
CODEC_TRACE("Version 2 format found\n");
|
||||
upgrade_from = 2;
|
||||
goto migrate;
|
||||
}
|
||||
|
||||
/* Version 1 - check no HMAC, 4k KDF, and 1024 page size */
|
||||
rc = sqlcipher_check_connection(db_filename, pass, pass_sz, v1_pragmas, &user_version, &journal_mode);
|
||||
if(rc == SQLITE_OK) {
|
||||
CODEC_TRACE("Version 1 format found\n");
|
||||
upgrade_from = 1;
|
||||
goto migrate;
|
||||
if(pragma_compat) sqlcipher_free(pragma_compat, sqlite3Strlen30(pragma_compat));
|
||||
pragma_compat = NULL;
|
||||
}
|
||||
/* if we exit the loop normally we failed to determine the version, this is an error */
|
||||
CODEC_TRACE("Upgrade format not determined\n");
|
||||
goto handle_error;
|
||||
|
||||
migrate:
|
||||
|
||||
|
@ -1303,20 +1290,8 @@ migrate:
|
|||
|
||||
attach_command = sqlite3_mprintf("ATTACH DATABASE '%s' as migrate KEY '%q';", migrated_db_filename, pass);
|
||||
set_user_version = sqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version);
|
||||
switch(upgrade_from) {
|
||||
case 1:
|
||||
commands[0] = v1_pragmas;
|
||||
break;
|
||||
case 2:
|
||||
commands[0] = v2_pragmas;
|
||||
break;
|
||||
case 3:
|
||||
commands[0] = v3_pragmas;
|
||||
break;
|
||||
default:
|
||||
CODEC_TRACE("Upgrade format not determined\n");
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
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');";
|
||||
|
@ -1423,6 +1398,7 @@ cleanup:
|
|||
if(set_user_version) sqlcipher_free(set_user_version, sqlite3Strlen30(set_user_version));
|
||||
if(set_journal_mode) sqlcipher_free(set_journal_mode, sqlite3Strlen30(set_journal_mode));
|
||||
if(journal_mode) sqlcipher_free(journal_mode, sqlite3Strlen30(journal_mode));
|
||||
if(pragma_compat) sqlcipher_free(pragma_compat, sqlite3Strlen30(pragma_compat));
|
||||
#if defined(_WIN32) || defined(SQLITE_OS_WINRT)
|
||||
if(w_db_filename) sqlcipher_free(w_db_filename, w_db_filename_sz);
|
||||
if(w_migrated_db_filename) sqlcipher_free(w_migrated_db_filename, w_migrated_db_filename_sz);
|
||||
|
|
|
@ -107,6 +107,17 @@ db2 close
|
|||
file delete -force test.db
|
||||
file delete -force test2.db
|
||||
|
||||
# open a 4.0 database
|
||||
do_test compat-open-4.0-database {
|
||||
sqlite_orig db $sampleDir/sqlcipher-4.0-testkey.db
|
||||
execsql {
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {ok 78536}
|
||||
db close
|
||||
|
||||
# create an encrypted database, attach an default-key encrypted volume
|
||||
# copy data between, verify the second database
|
||||
do_test encrypted-attach-default-key {
|
||||
|
@ -1228,6 +1239,99 @@ db close
|
|||
file delete -force plain.db
|
||||
file delete -force encrypted.db
|
||||
|
||||
# open a 1.1.8 database using cipher_compatibility
|
||||
do_test compat-open-1.1.8-database {
|
||||
sqlite_orig db $sampleDir/sqlcipher-1.1.8-testkey.db
|
||||
execsql {
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA cipher_compatibility = 1;
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {ok 75709}
|
||||
db close
|
||||
|
||||
# open a 2.0 database using cipher_compatibility
|
||||
do_test compat-open-2.0-database {
|
||||
sqlite_orig db $sampleDir/sqlcipher-2.0-le-testkey.db
|
||||
execsql {
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA cipher_compatibility = 2;
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {ok 78536}
|
||||
db close
|
||||
|
||||
# open a 3.0 database using cipher_compatibility
|
||||
do_test compat-open-3.0-database {
|
||||
sqlite_orig db $sampleDir/sqlcipher-3.0-testkey.db
|
||||
execsql {
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA cipher_compatibility = 3;
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {ok 78536}
|
||||
db close
|
||||
|
||||
# open a 4.0 database using cipher_compatibility
|
||||
do_test compat-open-4.0-database {
|
||||
sqlite_orig db $sampleDir/sqlcipher-4.0-testkey.db
|
||||
execsql {
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA cipher_compatibility = 4;
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {ok 78536}
|
||||
db close
|
||||
|
||||
# open a 1.1.8 database using cipher_default_compatibility
|
||||
do_test default-compat-open-1.1.8-database {
|
||||
sqlite_orig db $sampleDir/sqlcipher-1.1.8-testkey.db
|
||||
execsql {
|
||||
PRAGMA cipher_default_compatibility = 1;
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {ok 75709}
|
||||
db close
|
||||
|
||||
# open a 2.0 database using cipher_default_compatibility
|
||||
do_test default-compat-open-2.0-database {
|
||||
sqlite_orig db $sampleDir/sqlcipher-2.0-le-testkey.db
|
||||
execsql {
|
||||
PRAGMA cipher_default_compatibility = 2;
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {ok 78536}
|
||||
|
||||
# open a 3.0 database using cipher_default_compatibility
|
||||
do_test default-compat-open-3.0-database {
|
||||
sqlite_orig db $sampleDir/sqlcipher-3.0-testkey.db
|
||||
execsql {
|
||||
PRAGMA cipher_default_compatibility = 3;
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {ok 78536}
|
||||
|
||||
# re-open a 4.0 database using cipher_default_compatibility
|
||||
do_test default-compat-open-4.0-database {
|
||||
sqlite_orig db $sampleDir/sqlcipher-4.0-testkey.db
|
||||
execsql {
|
||||
PRAGMA cipher_default_compatibility = 4;
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
}
|
||||
} {ok 78536}
|
||||
|
||||
sqlite3_test_control_pending_byte $old_pending_byte
|
||||
|
||||
finish_test
|
||||
|
|
Loading…
Reference in New Issue