Skip to content

Commit c6629b2

Browse files
committed
Merge branch 'master' into prerelease
2 parents a125d22 + ac8385c commit c6629b2

File tree

4 files changed

+259
-5
lines changed

4 files changed

+259
-5
lines changed

src/crypto.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,11 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
238238

239239
codec_set_btree_to_codec_pagesize(db, pDb, ctx);
240240

241+
/* force secure delete. This has the benefit of wiping internal data when deleted
242+
and also ensures that all pages are written to disk (i.e. not skipped by
243+
sqlite3PagerDontWrite optimizations) */
244+
sqlite3BtreeSecureDelete(pDb->pBt, 1);
245+
241246
/* if fd is null, then this is an in-memory database and
242247
we dont' want to overwrite the AutoVacuum settings
243248
if not null, then set to the default */
@@ -312,11 +317,14 @@ int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
312317
rc = sqlite3PagerGet(pPager, pgno, &page);
313318
if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
314319
rc = sqlite3PagerWrite(page);
315-
//printf("sqlite3PagerWrite(%d)\n", pgno);
316320
if(rc == SQLITE_OK) {
317321
sqlite3PagerUnref(page);
318-
}
319-
}
322+
} else {
323+
CODEC_TRACE(("sqlite3_rekey: error %d occurred writing page %d\n", rc, pgno));
324+
}
325+
} else {
326+
CODEC_TRACE(("sqlite3_rekey: error %d occurred getting page %d\n", rc, pgno));
327+
}
320328
}
321329
}
322330

src/crypto_impl.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ int sqlcipher_cipher_ctx_cmp(cipher_ctx *c1, cipher_ctx *c2) {
208208
&& c1->fast_kdf_iter == c2->fast_kdf_iter
209209
&& c1->key_sz == c2->key_sz
210210
&& c1->pass_sz == c2->pass_sz
211+
&& c1->use_hmac == c2->use_hmac
212+
&& c1->hmac_sz == c2->hmac_sz
211213
&& (
212214
c1->pass == c2->pass
213215
|| !sqlcipher_memcmp((const unsigned char*)c1->pass,

test/crypto.test

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,186 @@ do_test rekey-as-first-operation {
201201
db close
202202
file delete -force test.db
203203

204+
# create a new database, insert some data
205+
# then rekey it with the same password
206+
do_test rekey-same-passkey {
207+
sqlite_orig db test.db
208+
209+
execsql {
210+
PRAGMA key = 'test123';
211+
CREATE TABLE t1(a,b);
212+
BEGIN;
213+
}
214+
215+
for {set i 1} {$i<=1000} {incr i} {
216+
set r [expr {int(rand()*500000)}]
217+
execsql "INSERT INTO t1 VALUES($i,'value $r');"
218+
}
219+
220+
execsql {
221+
COMMIT;
222+
SELECT count(*) FROM t1;
223+
PRAGMA rekey = 'test123';
224+
SELECT count(*) FROM t1;
225+
}
226+
} {1000 1000}
227+
db close
228+
file delete -force test.db
229+
230+
# create a new database, insert some data
231+
# then rekey it. Make sure it is immediately
232+
# readable. Then close it and make sure it can be
233+
# read back
234+
do_test rekey-and-query-1 {
235+
sqlite_orig db test.db
236+
237+
execsql {
238+
PRAGMA key = 'test123';
239+
CREATE TABLE t1(a,b);
240+
BEGIN;
241+
}
242+
243+
for {set i 1} {$i<=1000} {incr i} {
244+
set r [expr {int(rand()*500000)}]
245+
execsql "INSERT INTO t1 VALUES($i,'value $r');"
246+
}
247+
248+
execsql {
249+
COMMIT;
250+
SELECT count(*) FROM t1;
251+
PRAGMA rekey = 'test321';
252+
SELECT count(*) FROM t1;
253+
}
254+
} {1000 1000}
255+
256+
db close
257+
258+
do_test rekey-and-query-2 {
259+
sqlite_orig db test.db
260+
execsql {
261+
PRAGMA key = 'test321';
262+
SELECT count(*) FROM t1;
263+
}
264+
} {1000}
265+
db close
266+
file delete -force test.db
267+
268+
# create a new database, insert some data
269+
# delete about 50% of the data
270+
# write some new data
271+
# delete another 50%
272+
# then rekey it. Make sure it is immediately
273+
# readable. Then close it and make sure it can be
274+
# read back. This test will ensure that Secure Delete
275+
# is enabled and all pages are being written and are not
276+
# being optimized out by sqlite3PagerDontWrite
277+
do_test rekey-delete-and-query-1 {
278+
sqlite_orig db test.db
279+
280+
execsql {
281+
PRAGMA key = 'test123';
282+
CREATE TABLE t1(a,b);
283+
CREATE INDEX ta_a ON t1(a);
284+
BEGIN;
285+
}
286+
287+
for {set i 1} {$i<1000} {incr i} {
288+
set r [expr {int(rand()*32767)}]
289+
set r1 [expr {int(rand()*32767)}]
290+
execsql "INSERT INTO t1 VALUES($r,$r1);"
291+
}
292+
set r [expr {int(rand()*32767)}]
293+
set r1 [expr {int(rand()*32767)}]
294+
execsql "UPDATE t1 SET b = $r WHERE a < $r1;"
295+
296+
set r [expr {int(rand()*32767)}]
297+
298+
execsql "DELETE FROM t1 WHERE a < $r;"
299+
300+
execsql {
301+
COMMIT;
302+
SELECT (count(*) > 0) FROM t1;
303+
}
304+
} {1}
305+
db close
306+
307+
do_test rekey-delete-and-query-2 {
308+
sqlite_orig db test.db
309+
execsql {
310+
PRAGMA key = 'test123';
311+
PRAGMA rekey = 'test321';
312+
SELECT count(*) > 1 FROM t1;
313+
PRAGMA integrity_check;
314+
}
315+
} {1 ok}
316+
db close
317+
318+
do_test rekey-delete-and-query-3 {
319+
sqlite_orig db test.db
320+
execsql {
321+
PRAGMA key = 'test321';
322+
SELECT count(*) > 1 FROM t1;
323+
}
324+
} {1}
325+
db close
326+
file delete -force test.db
327+
328+
329+
# same as previous test, but use WAL
330+
do_test rekey-delete-and-query-wal-1 {
331+
sqlite_orig db test.db
332+
333+
execsql {
334+
PRAGMA key = 'test123';
335+
PRAGMA journal_mode = WAL;
336+
CREATE TABLE t1(a,b);
337+
CREATE INDEX ta_a ON t1(a);
338+
BEGIN;
339+
}
340+
341+
for {set i 1} {$i<1000} {incr i} {
342+
set r [expr {int(rand()*32767)}]
343+
set r1 [expr {int(rand()*32767)}]
344+
execsql "INSERT INTO t1 VALUES($r,$r1);"
345+
}
346+
set r [expr {int(rand()*32767)}]
347+
set r1 [expr {int(rand()*32767)}]
348+
execsql "UPDATE t1 SET b = $r WHERE a < $r1;"
349+
350+
set r [expr {int(rand()*32767)}]
351+
352+
execsql "DELETE FROM t1 WHERE a < $r;"
353+
354+
execsql {
355+
COMMIT;
356+
SELECT (count(*) > 0) FROM t1;
357+
}
358+
} {1}
359+
db close
360+
361+
do_test rekey-delete-and-query-wal-2 {
362+
sqlite_orig db test.db
363+
execsql {
364+
PRAGMA key = 'test123';
365+
PRAGMA journal_mode = WAL;
366+
PRAGMA rekey = 'test321';
367+
SELECT count(*) > 1 FROM t1;
368+
PRAGMA integrity_check;
369+
}
370+
} {wal 1 ok}
371+
db close
372+
373+
do_test rekey-delete-and-query-wal-3 {
374+
sqlite_orig db test.db
375+
execsql {
376+
PRAGMA key = 'test321';
377+
PRAGMA journal_mode = WAL;
378+
SELECT count(*) > 1 FROM t1;
379+
}
380+
} {wal 1}
381+
db close
382+
file delete -force test.db
383+
204384
# attach an encrypted database
205385
# where both database have the same
206386
# key
@@ -1217,4 +1397,70 @@ do_test verify-pragma-cipher-version {
12171397
db close
12181398
file delete -force test.db
12191399

1400+
# create a new database, insert some data
1401+
# and delete some data with
1402+
# auto_vacuum on
1403+
do_test auto-vacuum-full {
1404+
sqlite_orig db test.db
1405+
1406+
execsql {
1407+
PRAGMA key = 'test123';
1408+
PRAGMA auto_vacuum = FULL;
1409+
CREATE TABLE t1(a,b);
1410+
BEGIN;
1411+
}
1412+
1413+
for {set i 1} {$i<10000} {incr i} {
1414+
set r [expr {int(rand()*32767)}]
1415+
set r1 [expr {int(rand()*32767)}]
1416+
execsql "INSERT INTO t1 VALUES($r,$r1);"
1417+
}
1418+
set r [expr {int(rand()*32767)}]
1419+
execsql "DELETE FROM t1 WHERE a < $r;"
1420+
1421+
execsql {
1422+
COMMIT;
1423+
PRAGMA integrity_check;
1424+
PRAGMA freelist_count;
1425+
SELECT (count(*) > 0) FROM t1;
1426+
}
1427+
} {ok 0 1}
1428+
db close
1429+
file delete -force test.db
1430+
1431+
# create a new database, insert some data
1432+
# and delete some data with
1433+
# auto_vacuum incremental
1434+
do_test auto-vacuum-incremental {
1435+
sqlite_orig db test.db
1436+
1437+
execsql {
1438+
PRAGMA key = 'test123';
1439+
PRAGMA auto_vacuum = INCREMENTAL;
1440+
CREATE TABLE t1(a,b);
1441+
BEGIN;
1442+
}
1443+
1444+
for {set i 1} {$i<10000} {incr i} {
1445+
set r [expr {int(rand()*32767)}]
1446+
set r1 [expr {int(rand()*32767)}]
1447+
execsql "INSERT INTO t1 VALUES($r,$r1);"
1448+
}
1449+
set r [expr {int(rand()*32767)}]
1450+
execsql "DELETE FROM t1 WHERE a < $r;"
1451+
1452+
execsql {
1453+
COMMIT;
1454+
PRAGMA incremental_vacuum;
1455+
PRAGMA freelist_count;
1456+
PRAGMA integrity_check;
1457+
SELECT (count(*) > 0) FROM t1;
1458+
}
1459+
} {0 ok 1}
1460+
db close
1461+
file delete -force test.db
1462+
1463+
1464+
1465+
12201466
finish_test

tool/crypto-speedtest.tcl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ catch {exec /bin/sh -c {rm -f perftest*.db}}
9595

9696
set fd [open perftest0.sql w]
9797
puts $fd {
98-
PRAGMA key='xyzzy';
99-
PRAGMA cipher_use_hmac=OFF;
10098
}
10199
close $fd
102100

0 commit comments

Comments
 (0)