2 # codec.test developed by Stephen Lombardo (Zetetic LLC)
3 # sjlombardo at zetetic dot net
6 # Copyright (c) 2009, ZETETIC LLC
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are met:
11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above copyright
14 # notice, this list of conditions and the following disclaimer in the
15 # documentation and/or other materials provided with the distribution.
16 # * Neither the name of the ZETETIC LLC nor the
17 # names of its contributors may be used to endorse or promote products
18 # derived from this software without specific prior written permission.
20 # THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
21 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 # DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
24 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 # This file implements regression tests for SQLite library. The
32 # focus of this script is testing code cipher features.
34 # NOTE: tester.tcl has overridden the definition of sqlite3 to
35 # automatically pass in a key value. Thus tests in this file
36 # should explicitly close and open db with sqlite_orig in order
37 # to bypass default key assignment.
40 file delete -force test.db
41 file delete -force test2.db
42 file delete -force test3.db
43 file delete -force test4.db
45 set testdir [file dirname $argv0]
46 source $testdir/tester.tcl
48 # If the library is not compiled with has_codec support then
49 # skip all tests in this file.
50 if {![sqlite_orig -has-codec]} {
55 proc setup {file key} {
57 execsql "PRAGMA key=$key;"
60 INSERT INTO t1 VALUES ('test1', 'test2');
65 # The database is initially empty.
66 # set an hex key create some basic data
67 # create table and insert operations should work
68 # close database, open it again with the same
69 # hex key. verify that the table is readable
70 # and the data just inserted is visible
71 setup test.db "\"x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'\""
72 do_test will-open-with-correct-raw-key {
73 sqlite_orig db test.db
75 PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'";
76 SELECT name FROM sqlite_master WHERE type='table';
81 file delete -force test.db
83 # set an encryption key (non-hex) and create some basic data
84 # create table and insert operations should work
85 # close database, open it again with the same
86 # key. verify that the table is readable
87 # and the data just inserted is visible
88 setup test.db "'testkey'"
89 do_test will-open-with-correct-derived-key {
91 sqlite_orig db test.db
93 PRAGMA key = 'testkey';
94 SELECT name FROM sqlite_master WHERE type='table';
99 file delete -force test.db
101 # open the database and try to read from it without
102 # providing a passphrase. verify that the
103 # an error is returned from the library
104 setup test.db "'testkey'"
105 do_test wont-open-without-key {
106 sqlite_orig db test.db
108 SELECT name FROM sqlite_master WHERE type='table';
110 } {1 {file is encrypted or is not a database}}
112 file delete -force test.db
114 # open the database and try to set an invalid
115 # passphrase. verify that an error is returned
116 # and that data couldn't be read
117 setup test.db "'testkey'"
118 do_test wont-open-with-invalid-derived-key {
119 sqlite_orig db test.db
121 PRAGMA key = 'testkey2';
122 SELECT name FROM sqlite_master WHERE type='table';
124 } {1 {file is encrypted or is not a database}}
126 file delete -force test.db
128 # open the database and try to set an invalid
129 # hex key. verify that an error is returned
130 # and that data couldn't be read
131 setup test.db "'testkey'"
132 do_test wont-open-with-invalid-raw-key {
133 sqlite_orig db test.db
135 PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836480'";
136 SELECT name FROM sqlite_master WHERE type='table';
138 } {1 {file is encrypted or is not a database}}
140 file delete -force test.db
142 # test a large number of inserts in a transaction to a memory database
143 do_test memory-database {
144 sqlite_orig db :memory:
146 PRAGMA key = 'testkey3';
148 CREATE TABLE t2(a,b);
150 for {set i 1} {$i<=25000} {incr i} {
151 set r [expr {int(rand()*500000)}]
152 execsql "INSERT INTO t2 VALUES($i,$r);"
156 SELECT count(*) FROM t2;
158 SELECT count(*) FROM t2;
163 # test a large number of inserts in a transaction for multiple pages
164 do_test multi-page-database {
165 sqlite_orig db test.db
167 PRAGMA key = 'testkey';
168 CREATE TABLE t2(a,b);
171 for {set i 1} {$i<=25000} {incr i} {
172 set r [expr {int(rand()*500000)}]
173 execsql "INSERT INTO t2 VALUES($i,$r);"
177 SELECT count(*) FROM t2;
181 file delete -force test.db
183 # test a rekey operation as the first op on a database
184 # then test that now the new key opens the database
185 # now close database re-open with new key
186 setup test.db "'testkey'"
187 do_test rekey-as-first-operation {
188 sqlite_orig db test.db
190 PRAGMA key = 'testkey';
191 PRAGMA rekey = 'testkeynew';
195 sqlite_orig db test.db
197 PRAGMA key = 'testkeynew';
198 SELECT name FROM sqlite_master WHERE type='table';
202 file delete -force test.db
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
210 PRAGMA key = 'test123';
211 CREATE TABLE t1(a,b);
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');"
222 SELECT count(*) FROM t1;
223 PRAGMA rekey = 'test123';
224 SELECT count(*) FROM t1;
228 file delete -force test.db
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
234 do_test rekey-and-query-1 {
235 sqlite_orig db test.db
238 PRAGMA key = 'test123';
239 CREATE TABLE t1(a,b);
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');"
250 SELECT count(*) FROM t1;
251 PRAGMA rekey = 'test321';
252 SELECT count(*) FROM t1;
258 do_test rekey-and-query-2 {
259 sqlite_orig db test.db
261 PRAGMA key = 'test321';
262 SELECT count(*) FROM t1;
266 file delete -force test.db
268 # create a new database, insert some data
269 # delete about 50% of the data
270 # write some new data
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
281 PRAGMA key = 'test123';
282 CREATE TABLE t1(a,b);
283 CREATE INDEX ta_a ON t1(a);
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);"
292 set r [expr {int(rand()*32767)}]
293 set r1 [expr {int(rand()*32767)}]
294 execsql "UPDATE t1 SET b = $r WHERE a < $r1;"
296 set r [expr {int(rand()*32767)}]
298 execsql "DELETE FROM t1 WHERE a < $r;"
302 SELECT (count(*) > 0) FROM t1;
307 do_test rekey-delete-and-query-2 {
308 sqlite_orig db test.db
310 PRAGMA key = 'test123';
311 PRAGMA rekey = 'test321';
312 SELECT count(*) > 1 FROM t1;
313 PRAGMA integrity_check;
318 do_test rekey-delete-and-query-3 {
319 sqlite_orig db test.db
321 PRAGMA key = 'test321';
322 SELECT count(*) > 1 FROM t1;
326 file delete -force test.db
329 # same as previous test, but use WAL
330 do_test rekey-delete-and-query-wal-1 {
331 sqlite_orig db test.db
334 PRAGMA key = 'test123';
335 PRAGMA journal_mode = WAL;
336 CREATE TABLE t1(a,b);
337 CREATE INDEX ta_a ON t1(a);
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);"
346 set r [expr {int(rand()*32767)}]
347 set r1 [expr {int(rand()*32767)}]
348 execsql "UPDATE t1 SET b = $r WHERE a < $r1;"
350 set r [expr {int(rand()*32767)}]
352 execsql "DELETE FROM t1 WHERE a < $r;"
356 SELECT (count(*) > 0) FROM t1;
361 do_test rekey-delete-and-query-wal-2 {
362 sqlite_orig db test.db
364 PRAGMA key = 'test123';
365 PRAGMA journal_mode = WAL;
366 PRAGMA rekey = 'test321';
367 SELECT count(*) > 1 FROM t1;
368 PRAGMA integrity_check;
373 do_test rekey-delete-and-query-wal-3 {
374 sqlite_orig db test.db
376 PRAGMA key = 'test321';
377 PRAGMA journal_mode = WAL;
378 SELECT count(*) > 1 FROM t1;
382 file delete -force test.db
384 # attach an encrypted database
385 # without specifying key, verify it fails
386 setup test.db "'testkey'"
387 do_test attach-database-with-default-key {
388 sqlite_orig db2 test2.db
391 PRAGMA key = 'testkey';
392 CREATE TABLE t2(a,b);
393 INSERT INTO t2 VALUES ('test1', 'test2');
397 ATTACH 'test.db' AS db;
400 } {1 {unable to open database: test.db}}
402 file delete -force test.db
403 file delete -force test2.db
405 # attach an encrypted database
406 # where both database have the same
408 setup test.db "'testkey'"
409 do_test attach-database-with-same-key {
410 sqlite_orig db2 test2.db
413 PRAGMA key = 'testkey';
414 CREATE TABLE t2(a,b);
415 INSERT INTO t2 VALUES ('test1', 'test2');
419 SELECT count(*) FROM t2;
420 ATTACH 'test.db' AS db KEY 'testkey';
421 SELECT count(*) FROM db.t1;
426 file delete -force test.db
427 file delete -force test2.db
429 # attach an encrypted database
430 # where databases have different keys
431 setup test.db "'testkey'"
432 do_test attach-database-with-different-keys {
433 sqlite_orig db2 test2.db
436 PRAGMA key = 'testkey2';
437 CREATE TABLE t2(a,b);
438 INSERT INTO t2 VALUES ('test1', 'test2');
442 ATTACH 'test.db' AS db KEY 'testkey';
443 SELECT count(*) FROM db.t1;
444 SELECT count(*) FROM t2;
449 file delete -force test.db
450 file delete -force test2.db
452 # test locking across multiple handles
453 setup test.db "'testkey'"
454 do_test locking-across-multiple-handles-start {
455 sqlite_orig db test.db
458 PRAGMA key = 'testkey';
460 INSERT INTO t1 VALUES(1,2);
463 sqlite_orig dba test.db
465 PRAGMA key = 'testkey';
466 SELECT count(*) FROM t1;
469 } {1 {database is locked}}
471 do_test locking-accross-multiple-handles-finish {
477 SELECT count(*) FROM t1;
482 file delete -force test.db
485 setup test.db "'testkey'"
486 do_test alter-schema {
487 sqlite_orig db test.db
489 PRAGMA key = 'testkey';
490 ALTER TABLE t1 ADD COLUMN c;
491 INSERT INTO t1 VALUES (1,2,3);
492 INSERT INTO t1 VALUES (1,2,4);
493 CREATE TABLE t1a (a);
494 INSERT INTO t1a VALUES ('teststring');
498 sqlite_orig db test.db
500 PRAGMA key = 'testkey';
501 SELECT count(*) FROM t1 WHERE a IS NOT NULL;
502 SELECT count(*) FROM t1 WHERE c IS NOT NULL;
508 file delete -force test.db
510 # test alterations of KDF iterations and ciphers
512 setup test.db "'testkey'"
513 do_test non-standard-kdf-and-ciphers {
514 sqlite_orig db test.db
516 PRAGMA key = 'testkey';
517 PRAGMA rekey_kdf_iter = 1000;
518 PRAGMA rekey_cipher = 'aes-256-cfb';
519 PRAGMA rekey = 'testkey2';
520 INSERT INTO t1 VALUES (1,2);
524 sqlite_orig db test.db
526 PRAGMA key = 'testkey2';
527 PRAGMA kdf_iter = 1000;
528 PRAGMA cipher = 'aes-256-cfb';
529 SELECT count(*) FROM t1;
534 file delete -force test.db
536 # test alterations of CIPHER from CBC Mode requiring
537 # IV to ECB mode that does not
538 setup test.db "'testkey'"
539 do_test rekey-from-cbc-to-ecb-no-iv {
540 sqlite_orig db test.db
542 PRAGMA key = 'testkey';
546 for {set i 1} {$i<=1000} {incr i} {
547 set r [expr {int(rand()*500000)}]
548 execsql "INSERT INTO t1 VALUES($i,$r);"
553 PRAGMA rekey_kdf_iter = 1000;
554 PRAGMA rekey_cipher = 'aes-128-ecb';
555 PRAGMA rekey = 'testkey';
559 sqlite_orig db test.db
561 PRAGMA key = 'testkey';
562 PRAGMA kdf_iter = 1000;
563 PRAGMA cipher = 'aes-128-ecb';
564 SELECT count(*) FROM t1;
569 file delete -force test.db
571 # test alterations of CIPHER from ECB Mode (no IV) to CBC Mode
572 do_test rekey-from-ecb-to-cbc-with-iv {
573 sqlite_orig db test.db
575 PRAGMA key = 'testkey';
576 PRAGMA cipher = 'aes-256-ecb';
577 CREATE table t1(a,b);
581 for {set i 1} {$i<=1000} {incr i} {
582 set r [expr {int(rand()*500000)}]
583 execsql "INSERT INTO t1 VALUES($i,$r);"
588 PRAGMA rekey_cipher = 'aes-256-cbc';
589 PRAGMA rekey = 'testkey';
593 sqlite_orig db test.db
595 PRAGMA key = 'testkey';
596 SELECT count(*) FROM t1;
601 file delete -force test.db
603 # create an unencrypted database, attach a new encrypted volume
604 # copy data between, verify the encypted database is good afterwards
605 do_test unencrypted-attach {
606 sqlite_orig db test.db
609 CREATE TABLE t1(a,b);
613 for {set i 1} {$i<=1000} {incr i} {
614 set r [expr {int(rand()*500000)}]
615 execsql "INSERT INTO t1 VALUES($i,$r);"
620 ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey';
621 CREATE TABLE db2.t1(a,b);
622 INSERT INTO db2.t1 SELECT * FROM t1;
626 sqlite_orig db2 test2.db
628 PRAGMA key='testkey';
629 SELECT count(*) FROM t1;
633 file delete -force test.db
634 file delete -force test2.db
636 # create an unencrypted database, attach a new encrypted volume
637 # using a raw key copy data between, verify the encypted
638 # database is good afterwards
639 do_test unencryped-attach-raw-key {
640 sqlite_orig db test.db
643 CREATE TABLE t1(a,b);
647 for {set i 1} {$i<=1000} {incr i} {
648 set r [expr {int(rand()*500000)}]
649 execsql "INSERT INTO t1 VALUES($i,$r);"
654 ATTACH DATABASE 'test2.db' AS db2 KEY "x'10483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'";
655 CREATE TABLE db2.t1(a,b);
656 INSERT INTO db2.t1 SELECT * FROM t1;
660 sqlite_orig db2 test2.db
662 PRAGMA key="x'10483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'";
663 SELECT count(*) FROM t1;
667 file delete -force test.db
668 file delete -force test2.db
670 # create an encrypted database, attach an unencrypted volume
671 # copy data between, verify the unencypted database is good afterwards
672 do_test encryped-attach-unencrypted {
673 sqlite_orig db test.db
676 CREATE TABLE t1(a,b);
679 sqlite_orig db2 test2.db
681 PRAGMA key='testkey';
682 CREATE TABLE t1(a,b);
686 for {set i 1} {$i<=1000} {incr i} {
687 set r [expr {int(rand()*500000)}]
688 execsql "INSERT INTO t1 VALUES($i,$r);" db2
693 ATTACH DATABASE 'test.db' AS test KEY '';
694 INSERT INTO test.t1 SELECT * FROM t1;
695 DETACH DATABASE test;
699 SELECT count(*) FROM t1;
704 file delete -force test.db
705 file delete -force test2.db
707 # create an unencrypted database, attach an unencrypted volume
708 # copy data between, verify the unencypted database is good afterwards
709 do_test unencryped-attach-unencrypted {
710 sqlite_orig db test.db
713 CREATE TABLE t1(a,b);
716 sqlite_orig db2 test2.db
718 CREATE TABLE t1(a,b);
722 for {set i 1} {$i<=1000} {incr i} {
723 set r [expr {int(rand()*500000)}]
724 execsql "INSERT INTO t1 VALUES($i,$r);" db2
729 ATTACH DATABASE 'test.db' AS test;
730 INSERT INTO test.t1 SELECT * FROM t1;
731 DETACH DATABASE test;
735 SELECT count(*) FROM t1;
740 file delete -force test.db
741 file delete -force test2.db
743 # 1. create a database with a custom page size,
744 # 2. create table and insert operations should work
745 # 3. close database, open it again with the same
747 # 4. verify that the table is readable
748 # and the data just inserted is visible
749 do_test custom-pagesize {
750 sqlite_orig db test.db
753 PRAGMA key = 'testkey';
754 PRAGMA cipher_page_size = 4096;
755 CREATE table t1(a,b);
759 for {set i 1} {$i<=1000} {incr i} {
760 set r [expr {int(rand()*500000)}]
761 execsql "INSERT INTO t1 VALUES($i,'value $r');"
769 sqlite_orig db test.db
772 PRAGMA key = 'testkey';
773 PRAGMA cipher_page_size = 4096;
774 SELECT count(*) FROM t1;
780 # open the database with the default page size
781 ## and verfiy that it is not readable
782 do_test custom-pagesize-must-match {
783 sqlite_orig db test.db
785 PRAGMA key = 'testkey';
786 SELECT name FROM sqlite_master WHERE type='table';
788 } {1 {file is encrypted or is not a database}}
790 file delete -force test.db
792 # 1. create a database and insert a bunch of data, close the database
793 # 2. seek to the middle of a database page and write some junk
794 # 3. Open the database and verify that the database is no longer readable
795 do_test hmac-tamper-resistence {
796 sqlite_orig db test.db
799 PRAGMA key = 'testkey';
800 CREATE table t1(a,b);
804 for {set i 1} {$i<=1000} {incr i} {
805 set r [expr {int(rand()*500000)}]
806 execsql "INSERT INTO t1 VALUES($i,'value $r');"
815 # write some junk into the hmac segment, leaving
816 # the page data valid but with an invalid signature
817 hexio_write test.db 1000 0000
819 sqlite_orig db test.db
822 PRAGMA key = 'testkey';
823 SELECT count(*) FROM t1;
826 } {1 {file is encrypted or is not a database}}
828 file delete -force test.db
830 # 1. create a database and insert a bunch of data, close the database
831 # 2. seek to the middle of a database page and write some junk
832 # 3. Open the database and verify that the database is still readable
833 do_test nohmac-not-tamper-resistent {
834 sqlite_orig db test.db
837 PRAGMA key = 'testkey';
838 PRAGMA cipher_use_hmac = OFF;
839 PRAGMA cipher_page_size = 1024;
840 CREATE table t1(a,b);
844 for {set i 1} {$i<=1000} {incr i} {
845 set r [expr {int(rand()*500000)}]
846 execsql "INSERT INTO t1 VALUES($i,'value $r');"
855 # write some junk into the middle of the page
856 hexio_write test.db 2560 00
858 sqlite_orig db test.db
861 PRAGMA key = 'testkey';
862 PRAGMA cipher_use_hmac = OFF;
863 PRAGMA cipher_page_size = 1024;
864 SELECT count(*) FROM t1;
869 file delete -force test.db
871 # open a 1.1.8 database using the new code, HMAC disabled
872 do_test open-1.1.8-database {
873 sqlite_orig db sqlcipher-1.1.8-testkey.db
875 PRAGMA key = 'testkey';
876 PRAGMA cipher_use_hmac = OFF;
877 SELECT count(*) FROM t1;
880 } {4 1 1 one one 1 2 one two}
884 # open a 1.1.8 database without hmac, then copy the data
885 do_test attach-and-copy-1.1.8 {
886 sqlite_orig db sqlcipher-1.1.8-testkey.db
889 PRAGMA key = 'testkey';
890 PRAGMA cipher_use_hmac = OFF;
891 ATTACH DATABASE 'test.db' AS db2 KEY 'testkey-hmac';
892 CREATE TABLE db2.t1(a,b);
893 INSERT INTO db2.t1 SELECT * FROM main.t1;
898 sqlite_orig db test.db
900 PRAGMA key = 'testkey-hmac';
901 SELECT count(*) FROM t1;
904 } {4 1 1 one one 1 2 one two}
906 file delete -force test.db
908 # open a standard database, then attach a new
909 # database with completely different options.
910 # copy data between them, and verify that the
911 # new database can be opened with the proper data
912 do_test attached-database-pragmas {
913 sqlite_orig db test.db
916 PRAGMA key = 'testkey';
917 CREATE TABLE t1(a,b);
921 for {set i 1} {$i<=1000} {incr i} {
922 set r [expr {int(rand()*500000)}]
923 execsql "INSERT INTO t1 VALUES($i,'value $r');"
928 ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey2';
929 PRAGMA db2.cipher_page_size = 4096;
930 PRAGMA db2.cipher = 'aes-128-cbc';
931 PRAGMA db2.kdf_iter = 1000;
932 PRAGMA db2.cipher_use_hmac = OFF;
933 CREATE TABLE db2.t1(a,b);
934 INSERT INTO db2.t1 SELECT * FROM main.t1;
939 sqlite_orig db test2.db
941 PRAGMA key = 'testkey2';
942 PRAGMA cipher_page_size = 4096;
943 PRAGMA cipher = 'aes-128-cbc';
944 PRAGMA kdf_iter = 1000;
945 PRAGMA cipher_use_hmac = OFF;
946 SELECT count(*) FROM t1;
950 file delete -force test.db
951 file delete -force test2.db
953 # use the sqlcipher_export function
954 # on a non-existent database. Verify
955 # the error gets through.
956 do_test export-error {
957 sqlite_orig db test.db
960 PRAGMA key = 'testkey';
961 CREATE TABLE t1(a,b);
962 SELECT sqlcipher_export('nodb');
964 } {1 {unknown database nodb}}
966 file delete -force test.db
968 # use the sqlcipher_export function
969 # to copy a complicated database.
970 # tests autoincrement fields,
971 # indexes, views, and triggers,
972 # tables and virtual tables
973 do_test export-database {
974 sqlite_orig db test.db
977 PRAGMA key = 'testkey';
978 CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
979 CREATE UNIQUE INDEX b_idx ON t1(b);
980 CREATE INDEX c_idx ON t1(c);
982 CREATE TABLE t2(b,c);
983 CREATE TRIGGER t2_after_insert AFTER INSERT ON t2
985 INSERT INTO t1(b,c) VALUES (new.b, new.c);
991 CREATE VIRTUAL TABLE fts USING fts3(a,b);
994 -- start with one known value
995 INSERT INTO t2 VALUES(1000000,'value 1000000');
998 for {set i 1} {$i<=999} {incr i} {
999 set r [expr {int(rand()*500000)}]
1000 execsql "INSERT INTO t2 VALUES($i,'value $r');"
1004 INSERT INTO fts SELECT b,c FROM t1;
1007 ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey2';
1008 PRAGMA db2.cipher_page_size = 4096;
1010 SELECT sqlcipher_export('db2');
1012 DETACH DATABASE db2;
1016 sqlite_orig db test2.db
1018 PRAGMA key = 'testkey2';
1019 PRAGMA cipher_page_size = 4096;
1020 SELECT count(*) FROM t1;
1021 SELECT count(*) FROM v1;
1022 SELECT count(*) FROM sqlite_sequence;
1023 SELECT seq FROM sqlite_sequence WHERE name = 't1';
1024 INSERT INTO t2 VALUES(10001, 'value 938383');
1025 SELECT count(*) FROM t1; -- verify the trigger worked
1026 SELECT seq FROM sqlite_sequence WHERE name = 't1'; -- verify that autoincrement worked
1027 SELECT a FROM fts WHERE b MATCH '1000000';
1029 } {1000 1000 1 1000 1001 1001 1000000}
1031 file delete -force test.db
1032 file delete -force test2.db
1034 # 1. create a database with WAL journal mode
1035 # 2. create table and insert operations should work
1036 # 3. close database, open it again
1037 # 4. verify that the table is present, readable, and that
1038 # the journal mode is WAL
1039 do_test journal-mode-wal {
1040 sqlite_orig db test.db
1043 PRAGMA key = 'testkey';
1044 PRAGMA journal_mode = WAL;
1045 CREATE table t1(a,b);
1049 for {set i 1} {$i<=1000} {incr i} {
1050 set r [expr {int(rand()*500000)}]
1051 execsql "INSERT INTO t1 VALUES($i,'value $r');"
1059 sqlite_orig db test.db
1062 PRAGMA key = 'testkey';
1063 SELECT count(*) FROM t1;
1064 PRAGMA journal_mode;
1069 file delete -force test.db
1071 # Test rekey as first operation on an empty database. should be a no-op
1072 do_test rekey-as-first-op {
1073 sqlite_orig db test.db
1076 PRAGMA rekey = 'testkey';
1077 CREATE table t1(a,b);
1081 for {set i 1} {$i<=100} {incr i} {
1082 set r [expr {int(rand()*500000)}]
1083 execsql "INSERT INTO t1 VALUES($i,'value $r');"
1091 sqlite_orig db test.db
1094 PRAGMA rekey = 'testkey';
1095 SELECT count(*) FROM t1;
1100 file delete -force test.db
1102 # Test rekey as first operation follwed by key
1103 do_test rekey-then-key-as-first-ops {
1104 sqlite_orig db test.db
1107 PRAGMA rekey = '1234';
1108 PRAGMA key = 'testkey';
1109 CREATE table t1(a,b);
1113 for {set i 1} {$i<=100} {incr i} {
1114 set r [expr {int(rand()*500000)}]
1115 execsql "INSERT INTO t1 VALUES($i,'value $r');"
1123 sqlite_orig db test.db
1126 PRAGMA rekey = '4321';
1127 PRAGMA key = 'testkey';
1128 SELECT count(*) FROM t1;
1133 file delete -force test.db
1135 setup test.db "'testkey'"
1136 do_test multiple-key-calls-safe-1 {
1137 sqlite_orig db test.db
1139 PRAGMA key = 'testkey';
1140 PRAGMA cache_size = 0;
1141 SELECT name FROM sqlite_master WHERE type='table';
1145 do_test multiple-key-calls-safe-2 {
1147 PRAGMA key = 'wrong key';
1148 SELECT name FROM sqlite_master WHERE type='table';
1150 } {1 {file is encrypted or is not a database}}
1152 do_test multiple-key-calls-safe-3 {
1154 PRAGMA key = 'testkey';
1155 SELECT name FROM sqlite_master WHERE type='table';
1160 file delete -force test.db
1162 # 1. create a database with a custom hmac kdf iteration count,
1163 # 2. create table and insert operations should work
1164 # 3. close database, open it again with the same
1165 # key and hmac kdf iteration count
1166 # 4. verify that the table is readable
1167 # and the data just inserted is visible
1168 do_test custom-hmac-kdf-iter {
1169 sqlite_orig db test.db
1172 PRAGMA key = 'testkey';
1173 PRAGMA fast_kdf_iter = 10;
1174 CREATE table t1(a,b);
1178 for {set i 1} {$i<=1000} {incr i} {
1179 set r [expr {int(rand()*500000)}]
1180 execsql "INSERT INTO t1 VALUES($i,'value $r');"
1188 sqlite_orig db test.db
1191 PRAGMA key = 'testkey';
1192 PRAGMA fast_kdf_iter = 10;
1193 SELECT count(*) FROM t1;
1199 # open the database with the default hmac
1200 # kdf iteration count
1201 # to verify that it is not readable
1202 do_test custom-hmac-kdf-iter-must-match {
1203 sqlite_orig db test.db
1205 PRAGMA key = 'testkey';
1206 SELECT name FROM sqlite_master WHERE type='table';
1208 } {1 {file is encrypted or is not a database}}
1210 file delete -force test.db
1212 # open the database and turn on auto_vacuum
1213 # then insert a bunch of data, delete it
1214 # and verify that the file has become smaller
1215 # but can still be opened with the proper
1217 do_test auto-vacuum {
1218 sqlite_orig db test.db
1222 PRAGMA key = 'testkey';
1223 PRAGMA auto_vacuum=FULL;
1224 CREATE table t1(a,b);
1228 for {set i 1} {$i<=10000} {incr i} {
1229 set r [expr {int(rand()*500000)}]
1230 execsql "INSERT INTO t1 VALUES($i,'value $r');"
1233 lappend rc [execsql {
1235 SELECT count(*) FROM t1;
1238 # grab current size of file
1239 set sz [file size test.db]
1241 # delete some records, and verify
1242 # autovacuum removes them
1244 DELETE FROM t1 WHERE rowid > 5000;
1249 # grab new file size, post
1251 set sz2 [file size test.db]
1253 # verify that the new size is
1254 # smaller than the old size
1255 if {$sz > $sz2} { lappend rc true }
1257 sqlite_orig db test.db
1259 lappend rc [execsql {
1260 PRAGMA key = 'testkey';
1261 SELECT count(*) FROM t1;
1266 file delete -force test.db
1268 # open the database then insert a bunch of data.
1269 # then delete it and run a manual vacuum
1270 # verify that the file has become smaller
1271 # but can still be opened with the proper
1274 sqlite_orig db test.db
1278 PRAGMA key = 'testkey';
1279 CREATE table t1(a,b);
1283 for {set i 1} {$i<=10000} {incr i} {
1284 set r [expr {int(rand()*500000)}]
1285 execsql "INSERT INTO t1 VALUES($i,'value $r');"
1288 lappend rc [execsql {
1290 SELECT count(*) FROM t1;
1293 # grab current size of file
1294 set sz [file size test.db]
1297 DELETE FROM t1 WHERE rowid > 5000;
1302 # grab new file size, post
1304 set sz2 [file size test.db]
1306 # verify that the new size is
1307 # smaller than the old size
1308 if {$sz > $sz2} { lappend rc true }
1310 sqlite_orig db test.db
1311 lappend rc [execsql {
1312 PRAGMA key = 'testkey';
1313 SELECT count(*) FROM t1;
1318 file delete -force test.db
1320 # test kdf_iter and other pragmas
1321 # before a key is set. Verify that they
1323 do_test cipher-options-before-keys {
1324 sqlite_orig db test.db
1327 PRAGMA kdf_iter = 1000;
1328 PRAGMA cipher_page_size = 4096;
1329 PRAGMA cipher = 'aes-128-cbc';
1330 PRAGMA cipher_use_hmac = OFF;
1331 PRAGMA key = 'testkey';
1332 CREATE table t1(a,b);
1333 INSERT INTO t1 VALUES(1,2);
1337 sqlite_orig db test.db
1340 PRAGMA key = 'testkey';
1341 SELECT count(*) FROM t1;
1346 file delete -force test.db
1348 # open a 1.1.8 database (no HMAC), then
1349 # try to open another 1.1.8 database. The
1350 # attached database should have the same hmac
1351 # setting as the original
1352 do_test default-use-hmac-attach {
1353 file copy -force sqlcipher-1.1.8-testkey.db test.db
1354 sqlite_orig db test.db
1356 PRAGMA cipher_default_use_hmac = OFF;
1357 PRAGMA key = 'testkey';
1358 SELECT count(*) FROM t1;
1359 ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey';
1360 SELECT count(*) from db2.t1;
1361 PRAGMA cipher_default_use_hmac = ON;
1365 file delete -force test.db
1367 # open a 2.0 database (with HMAC), then
1368 # try to a 1.1.8 database. this should
1369 # fail because the hmac setting for the
1370 # attached database is not compatible
1371 do_test attach-1.1.8-database-from-2.0-fails {
1372 sqlite_orig db test.db
1374 PRAGMA key = 'testkey';
1375 CREATE table t1(a,b);
1376 ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey';
1378 } {1 {file is encrypted or is not a database}}
1380 file delete -force test.db
1382 # open a 2.0 database (with HMAC), then
1383 # set the default hmac setting to OFF.
1384 # try to a 1.1.8 database. this should
1385 # succeed now that hmac is off by default
1387 do_test change-default-use-hmac-attach {
1388 sqlite_orig db test.db
1390 PRAGMA key = 'testkey';
1391 CREATE table t1(a,b);
1392 INSERT INTO t1(a,b) VALUES (1,2);
1395 sqlite_orig db test.db
1397 PRAGMA key = 'testkey';
1398 SELECT count(*) FROM t1;
1399 PRAGMA cipher_default_use_hmac = OFF;
1400 ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey';
1401 SELECT count(*) from db2.t1;
1402 PRAGMA cipher_default_use_hmac = ON;
1406 file delete -force test.db
1408 # verify the pragma cipher_version
1409 # returns the currently configured
1411 do_test verify-pragma-cipher-version {
1412 sqlite_orig db test.db
1414 PRAGMA cipher_version;
1418 file delete -force test.db
1420 # create a new database, insert some data
1421 # and delete some data with
1423 do_test auto-vacuum-full {
1424 sqlite_orig db test.db
1427 PRAGMA key = 'test123';
1428 PRAGMA auto_vacuum = FULL;
1429 CREATE TABLE t1(a,b);
1433 for {set i 1} {$i<10000} {incr i} {
1434 set r [expr {int(rand()*32767)}]
1435 set r1 [expr {int(rand()*32767)}]
1436 execsql "INSERT INTO t1 VALUES($r,$r1);"
1438 set r [expr {int(rand()*32767)}]
1439 execsql "DELETE FROM t1 WHERE a < $r;"
1443 PRAGMA integrity_check;
1444 PRAGMA freelist_count;
1445 SELECT (count(*) > 0) FROM t1;
1449 file delete -force test.db
1451 # create a new database, insert some data
1452 # and delete some data with
1453 # auto_vacuum incremental
1454 do_test auto-vacuum-incremental {
1455 sqlite_orig db test.db
1458 PRAGMA key = 'test123';
1459 PRAGMA auto_vacuum = INCREMENTAL;
1460 CREATE TABLE t1(a,b);
1464 for {set i 1} {$i<10000} {incr i} {
1465 set r [expr {int(rand()*32767)}]
1466 set r1 [expr {int(rand()*32767)}]
1467 execsql "INSERT INTO t1 VALUES($r,$r1);"
1469 set r [expr {int(rand()*32767)}]
1470 execsql "DELETE FROM t1 WHERE a < $r;"
1474 PRAGMA incremental_vacuum;
1475 PRAGMA freelist_count;
1476 PRAGMA integrity_check;
1477 SELECT (count(*) > 0) FROM t1;
1481 file delete -force test.db
1484 # create a database with many hundred tables such that the schema
1485 # will overflow the first several pages of the database. verify the schema
1486 # is intact on open.
1487 do_test multipage-schema {
1488 sqlite_orig db test.db
1490 PRAGMA key = 'testkey';
1494 for {set i 1} {$i<=300} {incr i} {
1495 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
1503 sqlite_orig db test.db
1506 PRAGMA key = 'testkey';
1507 SELECT count(*) FROM sqlite_master where type = 'table';
1512 file delete -force test.db
1514 # create a database with many hundred tables such that the schema
1515 # will overflow the first several pages of the database. this time, enable
1516 # autovacuum on the database, which will cause sqlite to do some "short reads"
1517 # after the end of the main database file. verify that there are no HMAC errors
1518 # resulting from the short reads, and that the schema is intact when
1519 # the database is reopened
1520 do_test multipage-schema-autovacuum-shortread {
1521 sqlite_orig db test.db
1523 PRAGMA key = 'testkey';
1524 PRAGMA auto_vacuum = FULL;
1528 for {set i 1} {$i<=300} {incr i} {
1529 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
1537 sqlite_orig db test.db
1540 PRAGMA key = 'testkey';
1541 SELECT count(*) FROM sqlite_master where type = 'table';
1546 file delete -force test.db
1548 # same as multi-page-schema-autovacuum-shortread, except
1549 # using write ahead log mode
1550 do_test multipage-schema-autovacuum-shortread-wal {
1551 sqlite_orig db test.db
1553 PRAGMA key = 'testkey';
1554 PRAGMA auto_vacuum = FULL;
1555 PRAGMA journal_mode = WAL;
1559 for {set i 1} {$i<=300} {incr i} {
1560 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
1568 sqlite_orig db test.db
1571 PRAGMA key = 'testkey';
1572 SELECT count(*) FROM sqlite_master where type = 'table';
1576 file delete -force test.db
1578 # open a 2.0 database with little endian hmac page numbers (default)
1579 # verify it can be opened
1580 do_test open-2.0-le-database {
1581 sqlite_orig db sqlcipher-2.0-le-testkey.db
1583 PRAGMA key = 'testkey';
1584 SELECT count(*) FROM t1;
1587 } {4 1 1 one one 1 2 one two}
1590 # open a 2.0 database with big-endian hmac page numbers
1591 # verify it can be opened
1592 do_test open-2.0-be-database {
1593 sqlite_orig db sqlcipher-2.0-be-testkey.db
1595 PRAGMA key = 'testkey';
1596 PRAGMA cipher_hmac_pgno = be;
1597 SELECT count(*) FROM t1;
1600 } {4 1 1 one one 1 2 one two}
1603 # open a 2.0 database with big-endian hmac page numbers
1604 # attach a new database with little endian page numbers (default)
1605 # copy schema between the two, and verify the latter
1607 do_test be-to-le-migration {
1608 sqlite_orig db sqlcipher-2.0-be-testkey.db
1611 PRAGMA key = 'testkey';
1612 PRAGMA cipher_hmac_pgno = be;
1613 ATTACH DATABASE 'test.db' AS db2 KEY 'testkey';
1614 CREATE TABLE db2.t1(a,b);
1615 INSERT INTO db2.t1 SELECT * FROM main.t1;
1616 DETACH DATABASE db2;
1620 sqlite_orig db test.db
1622 PRAGMA key = 'testkey';
1623 SELECT count(*) FROM t1;
1626 } {4 1 1 one one 1 2 one two}
1628 file delete -force test.db
1630 # verify the pragma cipher_use_hmac
1631 # is set to true be default
1632 do_test verify-pragma-cipher-use-hmac-default {
1633 sqlite_orig db test.db
1635 PRAGMA key = 'test';
1636 PRAGMA cipher_use_hmac;
1640 file delete -force test.db
1642 # verify the pragma cipher_use_hmac
1643 # reports the flag turned off
1644 do_test verify-pragma-cipher-use-hmac-off {
1645 sqlite_orig db test.db
1647 PRAGMA key = 'test';
1648 PRAGMA cipher_use_hmac = off;
1649 PRAGMA cipher_use_hmac;
1653 file delete -force test.db
1655 # verify the pragma default_cipher_use_hmac
1656 # is set to true by default
1657 do_test verify-pragma-cipher-default-use-hmac-default {
1658 sqlite_orig db test.db
1660 PRAGMA cipher_default_use_hmac;
1664 file delete -force test.db
1666 # verify the pragma default_cipher_use_hmac
1667 # reports the flag turned off
1668 do_test verify-pragma-cipher-default-use-hmac-off {
1669 sqlite_orig db test.db
1671 PRAGMA cipher_default_use_hmac = off;
1672 PRAGMA cipher_default_use_hmac;
1673 -- Be sure to turn cipher_default_use_hmac
1674 -- back on or it will break later tests
1675 -- (it's a global flag)
1676 PRAGMA cipher_default_use_hmac = ON;
1680 file delete -force test.db
1682 # verify the pragma kdf_iter
1683 # reports the default value
1684 do_test verify-pragma-kdf-iter-reports-default {
1685 sqlite_orig db test.db
1687 PRAGMA key = 'test';
1692 file delete -force test.db
1694 # verify the pragma kdf_iter
1695 # reports value changed
1696 do_test verify-pragma-kdf-iter-reports-value-changed {
1697 sqlite_orig db test.db
1699 PRAGMA key = 'test';
1700 PRAGMA kdf_iter = 8000;
1705 file delete -force test.db
1707 # verify the pragma fast_kdf_iter
1708 # reports the default value
1709 do_test verify-pragma-fast-kdf-iter-reports-default {
1710 sqlite_orig db test.db
1712 PRAGMA key = 'test';
1713 PRAGMA fast_kdf_iter;
1717 file delete -force test.db
1719 # verify the pragma fast_kdf_iter
1720 # reports value changed
1721 do_test verify-pragma-kdf-iter-reports-value-changed {
1722 sqlite_orig db test.db
1724 PRAGMA key = 'test';
1725 PRAGMA fast_kdf_iter = 4000;
1726 PRAGMA fast_kdf_iter;
1730 file delete -force test.db
1732 # verify the pragma cipher_page_size
1733 # reports default value
1734 do_test verify-pragma-cipher-page-size-default {
1735 sqlite_orig db test.db
1737 PRAGMA key = 'test';
1738 PRAGMA cipher_page_size;
1742 file delete -force test.db
1744 # verify the pragma cipher_page_size
1745 # reports change in value
1746 do_test verify-pragma-cipher-page-size-changed {
1747 sqlite_orig db test.db
1749 PRAGMA key = 'test';
1750 PRAGMA cipher_page_size = 4096;
1751 PRAGMA cipher_page_size;
1755 file delete -force test.db
1757 # verify the pragma cipher
1758 # reports the default value
1759 do_test verify-pragma-cipher-default {
1760 sqlite_orig db test.db
1762 PRAGMA key = 'test';
1767 file delete -force test.db
1769 # verify the pragma cipher
1770 # reports a change in value
1771 do_test verify-pragma-cipher-changed {
1772 sqlite_orig db test.db
1774 PRAGMA key = 'test';
1775 PRAGMA cipher = 'AES-256-ECB';
1780 file delete -force test.db
1782 # verify the pragma cipher_hmac_salt_mask reports default
1783 do_test verify-pragma-hmac-salt-mask-reports-default {
1784 sqlite_orig db test.db
1786 PRAGMA key = 'test';
1787 PRAGMA cipher_hmac_salt_mask;
1791 file delete -force test.db
1793 # verify the pragma cipher_hmac_salt_mask reports
1794 # reports value changed
1795 do_test verify-pragma-hmac-salt-mask-reports-value-changed {
1796 sqlite_orig db test.db
1798 PRAGMA key = 'test';
1799 PRAGMA cipher_hmac_salt_mask = "x'11'";
1800 PRAGMA cipher_hmac_salt_mask;
1804 file delete -force test.db
1806 # verify the pragma cipher_hmac_pgno reports default
1807 do_test verify-pragma-hmac-pgno-reports-default {
1808 sqlite_orig db test.db
1810 PRAGMA key = 'test';
1811 PRAGMA cipher_hmac_pgno;
1815 file delete -force test.db
1817 # verify the pragma cipher_hmac_pgno
1818 # reports value changed
1819 do_test verify-pragma-hmac-pgno-reports-value-changed {
1820 sqlite_orig db test.db
1822 PRAGMA key = 'test';
1823 PRAGMA cipher_hmac_pgno = be;
1824 PRAGMA cipher_hmac_pgno;
1825 PRAGMA cipher_hmac_pgno = native;
1826 PRAGMA cipher_hmac_pgno;
1827 PRAGMA cipher_hmac_pgno = le;
1828 PRAGMA cipher_hmac_pgno;
1832 file delete -force test.db
1834 # open a 2.0 beta database with 4000 round hmac kdf and 0x00
1836 # verify it can be opened
1837 do_test open-2.0-beta-database {
1838 sqlite_orig db sqlcipher-2.0-beta-testkey.db
1840 PRAGMA key = 'testkey';
1841 PRAGMA fast_kdf_iter = 4000;
1842 PRAGMA cipher_hmac_salt_mask = "x'00'";
1843 SELECT count(*) FROM t1;
1846 } {2 test-0-0 test-0-1 test-1-0 test-1-1}
1849 # open a 2.0 beta database
1850 # attach a new standard database
1851 # copy schema between the two, and verify the latter
1853 do_test 2.0-beta-to-2.0-migration {
1854 sqlite_orig db sqlcipher-2.0-beta-testkey.db
1857 PRAGMA key = 'testkey';
1858 PRAGMA cipher_hmac_salt_mask = "x'00'";
1859 PRAGMA fast_kdf_iter = 4000;
1860 SELECT count(*) FROM sqlite_master;
1862 PRAGMA cipher_hmac_salt_mask = "x'3a'";
1863 ATTACH DATABASE 'test.db' AS db2 KEY 'testkey';
1865 CREATE TABLE db2.t1(a,b);
1866 INSERT INTO db2.t1 SELECT * FROM main.t1;
1867 DETACH DATABASE db2;
1871 sqlite_orig db test.db
1873 PRAGMA key = 'testkey';
1876 } {test-0-0 test-0-1 test-1-0 test-1-1}
1878 file delete -force test.db