Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packaging/android/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ LOCAL_CFLAGS += -DHAVE_USLEEP=1
LOCAL_CFLAGS += -DSQLITE_ENABLE_FTS5
LOCAL_CFLAGS += -DSQLITE_ENABLE_RTREE
LOCAL_CFLAGS += -DSQLITE_ENABLE_FTS3
LOCAL_CFLAGS += -DSQLITE_ENABLE_BATCH_ATOMIC_WRITE

# Select default encryption scheme
# ChaCha20-Poly1305 is the default
Expand Down
4 changes: 4 additions & 0 deletions src/cipher_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,11 @@ SQLITE_PRIVATE unsigned char* mcReadDatabaseHeader(Codec* codec, unsigned char*
sqlite3_int64 fileSize = 0;
int ret = sqlite3OsFileSize(fd, &fileSize);
if (fileSize == 0)
{
/* Empty file: there is no salt yet, a random salt will be generated */
*rc = SQLITE_OK;
return NULL;
}
}
if (*rc == SQLITE_OK)
hdr = dbHeader;
Expand Down
18 changes: 14 additions & 4 deletions src/memory_secure.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,26 @@ SQLITE_PRIVATE void sqlite3mcInitMemoryMethods()
#if SQLITE3MC_SECURE_MEMORY
if (!mcSecureMemoryInitialized)
{
if (sqlite3_config(SQLITE_CONFIG_GETMALLOC, &mcDefaultMemoryMethods) == SQLITE_OK)
sqlite3_mem_methods currentMemoryMethods;
if (sqlite3_config(SQLITE_CONFIG_GETMALLOC, &currentMemoryMethods) == SQLITE_OK)
{
mcSecureMemoryMethods.pAppData = mcDefaultMemoryMethods.pAppData;
if (sqlite3_config(SQLITE_CONFIG_MALLOC, &mcSecureMemoryMethods) == SQLITE_OK)
if (currentMemoryMethods.xMalloc == mcSecureMemoryMethods.xMalloc)
{
/* Still installed after sqlite3_shutdown(), do not wrap it a second time */
mcSecureMemoryInitialized = 1;
}
else
{
mcSecureMemoryFlag = mcSecureMemoryInitialized = 0;
mcDefaultMemoryMethods = currentMemoryMethods;
mcSecureMemoryMethods.pAppData = mcDefaultMemoryMethods.pAppData;
if (sqlite3_config(SQLITE_CONFIG_MALLOC, &mcSecureMemoryMethods) == SQLITE_OK)
{
mcSecureMemoryInitialized = 1;
}
else
{
mcSecureMemoryFlag = mcSecureMemoryInitialized = 0;
}
}
}
else
Expand Down
4 changes: 2 additions & 2 deletions src/sqlite3mc_vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,8 +723,8 @@ static sqlite3mc_file* mcFindDbMainFileName(sqlite3mc_vfs* mcVfs, const char* zF
static sqlite3mc_vfs* mcFindVfs(sqlite3* db, const char* zDbName)
{
int dbIndex = (zDbName) ? sqlite3FindDbName(db, zDbName) : 0;
Pager* pager = sqlite3BtreePager(db->aDb[dbIndex].pBt);
sqlite3_vfs* dbVfs = pager->pVfs;
Btree* pBt = (dbIndex >= 0) ? db->aDb[dbIndex].pBt : NULL;
sqlite3_vfs* dbVfs = (pBt != NULL) ? sqlite3BtreePager(pBt)->pVfs : NULL;

sqlite3mc_vfs* pVfsMC = NULL;
if (dbVfs && dbVfs->xOpen == mcVfsOpen)
Expand Down
50 changes: 49 additions & 1 deletion test/rekeytest.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
** always be supplied (rekey, failure case, plain -> encrypted)
** Part 8 : salt management (random salt, salt in memory across several rekeys,
** rekey_salt=on/off) and behaviour when reading the file header
** (unencrypted/empty/too short file, I/O error while reading the header)
** (unencrypted/empty/too short file, I/O error while reading the header),
** key, rekey and backup for a schema name without a database file
**
** Invariant in parts 3 and 6 (after every rekey, whether it failed or not):
** exactly ONE of the two states (old/new) is completely readable
Expand Down Expand Up @@ -1765,6 +1766,25 @@ static void t8_short_header(void)
rc = open_state("chacha20", "k", &db, &n);
CHECK(rc == SQLITE_OK && n == 1, "reopened and readable without cipher_salt");
if (db) sqlite3_close(db);

/* A second new DB with the same key must get a different salt */
{
unsigned char h2[16];
remove_files();
write_bytes(DBFILE, 0);
rc = sqlite3_open_v2(DBFILE, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "multipleciphers-faulty");
if (rc == SQLITE_OK)
{
set_params(db, "chacha20");
keyRc = sqlite3_key(db, "k", 1);
rc = sqlite3_exec(db, "CREATE TABLE t(a INTEGER PRIMARY KEY, b TEXT)", 0, 0, 0);
if (keyRc != SQLITE_OK) rc = keyRc;
}
sqlite3_close(db);
db = 0;
CHECK(rc == SQLITE_OK && read_header_salt(h2) && memcmp(h, h2, 16) != 0,
"second empty file + same key: different salt");
}
}

for (i = 0; i < sizeof(sizes) / sizeof(sizes[0]); i++)
Expand Down Expand Up @@ -1827,6 +1847,33 @@ static void t8_header_read_error(void)
CHECK(state_ok("chacha20", "old-key", g_nrows), "afterwards completely readable with the correct key");
}

/* Key, rekey and backup for a schema name without a database file
** (unknown name, "temp" before it is used): an error, no crash */
static void t8_schema_without_file(void)
{
sqlite3* db = 0;
sqlite3* dbDest = 0;
sqlite3_backup* backup;
int rc;

printf("\n== key, rekey and backup for a schema without database file ==\n");
snprintf(g_ctx, sizeof(g_ctx), "Part 8: schema_without_file");
remove_files();
rc = sqlite3_open_v2(DBFILE, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "multipleciphers-faulty");
CHECK(rc == SQLITE_OK, "DB opened");
if (rc != SQLITE_OK) return;
CHECK(sqlite3_key_v2(db, "nosuchdb", "k", 1) != SQLITE_OK, "key for an unknown schema fails");
CHECK(sqlite3_key_v2(db, "temp", "k", 1) != SQLITE_OK, "key for temp fails");
CHECK(sqlite3_rekey_v2(db, "nosuchdb", "k", 1) != SQLITE_OK, "rekey for an unknown schema fails");
CHECK(sqlite3_rekey_v2(db, "temp", "k", 1) != SQLITE_OK, "rekey for temp fails");
rc = sqlite3_open(":memory:", &dbDest);
backup = (rc == SQLITE_OK) ? sqlite3_backup_init(dbDest, "main", db, "temp") : NULL;
if (backup) sqlite3_backup_finish(backup);
CHECK(rc == SQLITE_OK, "backup from temp returns without a crash");
sqlite3_close(dbDest);
sqlite3_close(db);
}

static void run_part8(void)
{
t8_random_salt();
Expand All @@ -1837,6 +1884,7 @@ static void run_part8(void)
t8_plain_with_key();
t8_short_header();
t8_header_read_error();
t8_schema_without_file();
}

/* ------------------------------------------------------------------ */
Expand Down
Loading