resilar / sqleet

SQLite3 encryption that sucks less
The Unlicense
375 stars 55 forks source link

Bug in function sqlite3_rekey_v2 #10

Closed utelle closed 6 years ago

utelle commented 6 years ago

When you use the command PRAGMA rekey='password' to encrypt a previously unencrypted database, this seems to work at first. However, the function sqlite3_rekey_v2 misses to set the codec member variable reader to the value of the codec member variable writer after sqlite3RunVacuum has finished. And that can lead to problems later on, if SQLite has to reread a page from disk. This will not work, because the reader is still a null pointer, so that it is assumed that the database is not encrypted, although pages were written to file encrypted.

Since SQLite caches database pages, the bug does not surface immediately, but you can demonstrate it with the following SQL commands:

create table t1 (c1 int, c2 char);
insert into t1 values (1, 'Arthur');
pragma rekey='Test';
attach database 'db_attached.db3' as db2; -- uses the encryption key of the main database
create table db2.t2 (c1 int, c2 char);
insert into db2.t2 values (2, 'Bernie');
detach database db2;
-- reattaching the database forces SQLite to read the schema from disk
attach database 'db_attached.db3' as db2; -- uses again the encryption key of the main database
-- ==>Error: unable to open database: db_attached.db3
resilar commented 6 years ago

Nice catch. The obvious fix is to set the reader pointer after rekey. I'll look into it during the weekend.

utelle commented 6 years ago

Indeed the fix is almost a one-liner, adding

codec->reader = codec->writer;

after the call to sqlite3RunVaccum will do the trick. However, this should be done only if sqlite3RunVaccum completed successfully, of course.

PS: Looking closer at your avatar I see Finnish words ... are you from Finland?

resilar commented 6 years ago

Decrypt code also needed to be updated in similar fashion (as was done in #11).

And yes, I'm Finnish. Do not mind the avatar - it's an edgy joke about the Moomins :)

utelle commented 6 years ago

Decrypt code also needed to be updated in similar fashion (as was done in #11).

I never experienced errors on rekeying a database, that is, I never tested, what happens when rekeying fails for whatever reason, but resetting the codec to its prior state seemed a logical thing to do.

And yes, I'm Finnish. Do not mind the avatar - it's an edgy joke about the Moomins :)

Terveisiä Suomeen! Olen Suomessa yleensä noin kerran vuodessa vierailemassa sukulaisia.