summaryrefslogtreecommitdiff
path: root/test/crypto.test
diff options
context:
space:
mode:
Diffstat (limited to 'test/crypto.test')
-rw-r--r--test/crypto.test417
1 files changed, 414 insertions, 3 deletions
diff --git a/test/crypto.test b/test/crypto.test
index aabb481..5fb11f2 100644
--- a/test/crypto.test
+++ b/test/crypto.test
@@ -201,6 +201,186 @@ do_test rekey-as-first-operation {
db close
file delete -force test.db
+# create a new database, insert some data
+# then rekey it with the same password
+do_test rekey-same-passkey {
+ sqlite_orig db test.db
+
+ execsql {
+ PRAGMA key = 'test123';
+ CREATE TABLE t1(a,b);
+ BEGIN;
+ }
+
+ for {set i 1} {$i<=1000} {incr i} {
+ set r [expr {int(rand()*500000)}]
+ execsql "INSERT INTO t1 VALUES($i,'value $r');"
+ }
+
+ execsql {
+ COMMIT;
+ SELECT count(*) FROM t1;
+ PRAGMA rekey = 'test123';
+ SELECT count(*) FROM t1;
+ }
+} {1000 1000}
+db close
+file delete -force test.db
+
+# create a new database, insert some data
+# then rekey it. Make sure it is immediately
+# readable. Then close it and make sure it can be
+# read back
+do_test rekey-and-query-1 {
+ sqlite_orig db test.db
+
+ execsql {
+ PRAGMA key = 'test123';
+ CREATE TABLE t1(a,b);
+ BEGIN;
+ }
+
+ for {set i 1} {$i<=1000} {incr i} {
+ set r [expr {int(rand()*500000)}]
+ execsql "INSERT INTO t1 VALUES($i,'value $r');"
+ }
+
+ execsql {
+ COMMIT;
+ SELECT count(*) FROM t1;
+ PRAGMA rekey = 'test321';
+ SELECT count(*) FROM t1;
+ }
+} {1000 1000}
+
+db close
+
+do_test rekey-and-query-2 {
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA key = 'test321';
+ SELECT count(*) FROM t1;
+ }
+} {1000}
+db close
+file delete -force test.db
+
+# create a new database, insert some data
+# delete about 50% of the data
+# write some new data
+# delete another 50%
+# then rekey it. Make sure it is immediately
+# readable. Then close it and make sure it can be
+# read back. This test will ensure that Secure Delete
+# is enabled and all pages are being written and are not
+# being optimized out by sqlite3PagerDontWrite
+do_test rekey-delete-and-query-1 {
+ sqlite_orig db test.db
+
+ execsql {
+ PRAGMA key = 'test123';
+ CREATE TABLE t1(a,b);
+ CREATE INDEX ta_a ON t1(a);
+ BEGIN;
+ }
+
+ for {set i 1} {$i<1000} {incr i} {
+ set r [expr {int(rand()*32767)}]
+ set r1 [expr {int(rand()*32767)}]
+ execsql "INSERT INTO t1 VALUES($r,$r1);"
+ }
+ set r [expr {int(rand()*32767)}]
+ set r1 [expr {int(rand()*32767)}]
+ execsql "UPDATE t1 SET b = $r WHERE a < $r1;"
+
+ set r [expr {int(rand()*32767)}]
+
+ execsql "DELETE FROM t1 WHERE a < $r;"
+
+ execsql {
+ COMMIT;
+ SELECT (count(*) > 0) FROM t1;
+ }
+} {1}
+db close
+
+do_test rekey-delete-and-query-2 {
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA key = 'test123';
+ PRAGMA rekey = 'test321';
+ SELECT count(*) > 1 FROM t1;
+ PRAGMA integrity_check;
+ }
+} {1 ok}
+db close
+
+do_test rekey-delete-and-query-3 {
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA key = 'test321';
+ SELECT count(*) > 1 FROM t1;
+ }
+} {1}
+db close
+file delete -force test.db
+
+
+# same as previous test, but use WAL
+do_test rekey-delete-and-query-wal-1 {
+ sqlite_orig db test.db
+
+ execsql {
+ PRAGMA key = 'test123';
+ PRAGMA journal_mode = WAL;
+ CREATE TABLE t1(a,b);
+ CREATE INDEX ta_a ON t1(a);
+ BEGIN;
+ }
+
+ for {set i 1} {$i<1000} {incr i} {
+ set r [expr {int(rand()*32767)}]
+ set r1 [expr {int(rand()*32767)}]
+ execsql "INSERT INTO t1 VALUES($r,$r1);"
+ }
+ set r [expr {int(rand()*32767)}]
+ set r1 [expr {int(rand()*32767)}]
+ execsql "UPDATE t1 SET b = $r WHERE a < $r1;"
+
+ set r [expr {int(rand()*32767)}]
+
+ execsql "DELETE FROM t1 WHERE a < $r;"
+
+ execsql {
+ COMMIT;
+ SELECT (count(*) > 0) FROM t1;
+ }
+} {1}
+db close
+
+do_test rekey-delete-and-query-wal-2 {
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA key = 'test123';
+ PRAGMA journal_mode = WAL;
+ PRAGMA rekey = 'test321';
+ SELECT count(*) > 1 FROM t1;
+ PRAGMA integrity_check;
+ }
+} {wal 1 ok}
+db close
+
+do_test rekey-delete-and-query-wal-3 {
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA key = 'test321';
+ PRAGMA journal_mode = WAL;
+ SELECT count(*) > 1 FROM t1;
+ }
+} {wal 1}
+db close
+file delete -force test.db
+
# attach an encrypted database
# where both database have the same
# key
@@ -611,8 +791,9 @@ do_test hmac-tamper-resistence {
db close
- # write some junk into the middle of the page
- hexio_write test.db 2560 00
+ # write some junk into the hmac segment, leaving
+ # the page data valid but with an invalid signature
+ hexio_write test.db 1000 0000
sqlite_orig db test.db
@@ -621,7 +802,7 @@ do_test hmac-tamper-resistence {
SELECT count(*) FROM t1;
}
-} {1 {database disk image is malformed}}
+} {1 {file is encrypted or is not a database}}
db close
file delete -force test.db
@@ -1145,4 +1326,234 @@ do_test cipher-options-before-keys {
db close
file delete -force test.db
+# open a 1.1.8 database (no HMAC), then
+# try to open another 1.1.8 database. The
+# attached database should have the same hmac
+# setting as the original
+do_test default-use-hmac-attach {
+ file copy -force sqlcipher-1.1.8-testkey.db test.db
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA cipher_default_use_hmac = OFF;
+ PRAGMA key = 'testkey';
+ SELECT count(*) FROM t1;
+ ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2;
+ SELECT count(*) from db2.t1;
+ PRAGMA cipher_default_use_hmac = ON;
+ }
+} {4 4}
+db close
+file delete -force test.db
+
+# open a 2.0 database (with HMAC), then
+# try to a 1.1.8 database. this should
+# fail because the hmac setting for the
+# attached database is not compatible
+do_test attach-1.1.8-database-from-2.0-fails {
+ sqlite_orig db test.db
+ catchsql {
+ PRAGMA key = 'testkey';
+ CREATE table t1(a,b);
+ ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2;
+ }
+} {1 {file is encrypted or is not a database}}
+db close
+file delete -force test.db
+
+# open a 2.0 database (with HMAC), then
+# set the default hmac setting to OFF.
+# try to a 1.1.8 database. this should
+# succeed now that hmac is off by default
+# before the attach
+do_test change-default-use-hmac-attach {
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA key = 'testkey';
+ CREATE table t1(a,b);
+ INSERT INTO t1(a,b) VALUES (1,2);
+ }
+ db close
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA key = 'testkey';
+ SELECT count(*) FROM t1;
+ PRAGMA cipher_default_use_hmac = OFF;
+ ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2;
+ SELECT count(*) from db2.t1;
+ PRAGMA cipher_default_use_hmac = ON;
+ }
+} {1 4}
+db close
+file delete -force test.db
+
+# verify the pragma cipher_version
+# returns the currently configured
+# sqlcipher version
+do_test verify-pragma-cipher-version {
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA cipher_version;
+ }
+} {2.0.6}
+db close
+file delete -force test.db
+
+# create a new database, insert some data
+# and delete some data with
+# auto_vacuum on
+do_test auto-vacuum-full {
+ sqlite_orig db test.db
+
+ execsql {
+ PRAGMA key = 'test123';
+ PRAGMA auto_vacuum = FULL;
+ CREATE TABLE t1(a,b);
+ BEGIN;
+ }
+
+ for {set i 1} {$i<10000} {incr i} {
+ set r [expr {int(rand()*32767)}]
+ set r1 [expr {int(rand()*32767)}]
+ execsql "INSERT INTO t1 VALUES($r,$r1);"
+ }
+ set r [expr {int(rand()*32767)}]
+ execsql "DELETE FROM t1 WHERE a < $r;"
+
+ execsql {
+ COMMIT;
+ PRAGMA integrity_check;
+ PRAGMA freelist_count;
+ SELECT (count(*) > 0) FROM t1;
+ }
+} {ok 0 1}
+db close
+file delete -force test.db
+
+# create a new database, insert some data
+# and delete some data with
+# auto_vacuum incremental
+do_test auto-vacuum-incremental {
+ sqlite_orig db test.db
+
+ execsql {
+ PRAGMA key = 'test123';
+ PRAGMA auto_vacuum = INCREMENTAL;
+ CREATE TABLE t1(a,b);
+ BEGIN;
+ }
+
+ for {set i 1} {$i<10000} {incr i} {
+ set r [expr {int(rand()*32767)}]
+ set r1 [expr {int(rand()*32767)}]
+ execsql "INSERT INTO t1 VALUES($r,$r1);"
+ }
+ set r [expr {int(rand()*32767)}]
+ execsql "DELETE FROM t1 WHERE a < $r;"
+
+ execsql {
+ COMMIT;
+ PRAGMA incremental_vacuum;
+ PRAGMA freelist_count;
+ PRAGMA integrity_check;
+ SELECT (count(*) > 0) FROM t1;
+ }
+} {0 ok 1}
+db close
+file delete -force test.db
+
+
+# create a database with many hundred tables such that the schema
+# will overflow the first several pages of the database. verify the schema
+# is intact on open.
+do_test multipage-schema {
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA key = 'testkey';
+ BEGIN EXCLUSIVE;
+ } db
+
+ for {set i 1} {$i<=300} {incr i} {
+ execsql "CREATE TABLE tab$i (a TEXT, b TEXT, c TEXT, d TEXT, e TEXT, f TEXT, g TEXT, h TEXT, i TEXT, j TEXT, k, TEXT, l, m TEXT, n TEXT, o TEXT, p TEXT);" db
+ }
+
+ execsql {
+ COMMIT;
+ } db
+
+ db close
+ sqlite_orig db test.db
+
+ execsql {
+ PRAGMA key = 'testkey';
+ SELECT count(*) FROM sqlite_master where type = 'table';
+ } db
+
+} {300}
+db close
+file delete -force test.db
+
+# create a database with many hundred tables such that the schema
+# will overflow the first several pages of the database. this time, enable
+# autovacuum on the database, which will cause sqlite to do some "short reads"
+# after the end of the main database file. verify that there are no HMAC errors
+# resulting from the short reads, and that the schema is intact when
+# the database is reopened
+do_test multipage-schema-autovacuum-shortread {
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA key = 'testkey';
+ PRAGMA auto_vacuum = FULL;
+ BEGIN EXCLUSIVE;
+ } db
+
+ for {set i 1} {$i<=300} {incr i} {
+ execsql "CREATE TABLE tab$i (a TEXT, b TEXT, c TEXT, d TEXT, e TEXT, f TEXT, g TEXT, h TEXT, i TEXT, j TEXT, k, TEXT, l, m TEXT, n TEXT, o TEXT, p TEXT);" db
+ }
+
+ execsql {
+ COMMIT;
+ } db
+
+ db close
+ sqlite_orig db test.db
+
+ execsql {
+ PRAGMA key = 'testkey';
+ SELECT count(*) FROM sqlite_master where type = 'table';
+ } db
+
+} {300}
+db close
+file delete -force test.db
+
+# same as multi-page-schema-autovacuum-shortread, except
+# using write ahead log mode
+do_test multipage-schema-autovacuum-shortread-wal {
+ sqlite_orig db test.db
+ execsql {
+ PRAGMA key = 'testkey';
+ PRAGMA auto_vacuum = FULL;
+ PRAGMA journal_mode = WAL;
+ BEGIN EXCLUSIVE;
+ } db
+
+ for {set i 1} {$i<=300} {incr i} {
+ execsql "CREATE TABLE tab$i (a TEXT, b TEXT, c TEXT, d TEXT, e TEXT, f TEXT, g TEXT, h TEXT, i TEXT, j TEXT, k, TEXT, l, m TEXT, n TEXT, o TEXT, p TEXT);" db
+ }
+
+ execsql {
+ COMMIT;
+ } db
+
+ db close
+ sqlite_orig db test.db
+
+ execsql {
+ PRAGMA key = 'testkey';
+ SELECT count(*) FROM sqlite_master where type = 'table';
+ } db
+} {300}
+db close
+file delete -force test.db
+
finish_test