Merge branch 'prerelease' of github.com:sqlcipher/sqlcipher into ditto

This commit is contained in:
Billy Gray
2013-09-12 16:44:44 -04:00
2 changed files with 25 additions and 23 deletions
+1 -1
View File
@@ -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]);
}
}
+24 -22
View File
@@ -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;
}
@@ -907,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){
@@ -925,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;
}
@@ -956,15 +957,15 @@ 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;
char *set_user_version;
char *key;
int key_sz;
int user_version = 0;
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 */
@@ -980,24 +981,18 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
memcpy(key, ctx->read_ctx->pass, ctx->read_ctx->pass_sz);
if(db_filename){
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);
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, "");
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;
@@ -1006,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"));
@@ -1019,8 +1014,14 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
goto handle_error;
}
for(command_idx = 0; command_idx < (sizeof(commands)/sizeof(commands[0])); command_idx++){
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];
if(strcmp(command, "") == 0){
continue;
@@ -1031,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){
@@ -1073,7 +1075,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<ArraySize(aCopy); i+=2){
sqlite3BtreeGetMeta(pSrc, aCopy[i], &meta);
rc = sqlite3BtreeUpdateMeta(pDest, aCopy[i], meta+aCopy[i+1]);
if( NEVER(rc!=SQLITE_OK) ) goto handle_error;