Merge sqlite-release(3.43.1) into prerelease-integration
[sqlcipher.git] / test / sqlcipher-core.test
blob5aed9fb66c2bb6fdb8c4987620fe97afa488673d
1 # SQLCipher
2 # codec.test developed by Stephen Lombardo (Zetetic LLC)
3 # sjlombardo at zetetic dot net
4 # http://zetetic.net
6 # Copyright (c) 2018, ZETETIC LLC
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are met:
9 #     * Redistributions of source code must retain the above copyright
10 #       notice, this list of conditions and the following disclaimer.
11 #     * Redistributions in binary form must reproduce the above copyright
12 #       notice, this list of conditions and the following disclaimer in the
13 #       documentation and/or other materials provided with the distribution.
14 #     * Neither the name of the ZETETIC LLC nor the
15 #       names of its contributors may be used to endorse or promote products
16 #       derived from this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
19 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 # DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
22 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 # This file implements regression tests for SQLite library.  The
30 # focus of this script is testing code cipher features.
32 # NOTE: tester.tcl has overridden the definition of sqlite3 to
33 # automatically pass in a key value. Thus tests in this file
34 # should explicitly close and open db with sqlite_orig in order
35 # to bypass default key assignment.
37 set testdir [file dirname $argv0]
38 source $testdir/tester.tcl
39 source $testdir/sqlcipher.tcl
41 # The database is initially empty.
42 # set an hex key create some basic data
43 # create table and insert operations should work
44 # close database, open it again with the same
45 # hex key. verify that the table is readable
46 # and the data just inserted is visible
47 setup test.db "\"x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'\""
48 do_test will-open-with-correct-raw-key {
49   sqlite_orig db test.db
50   execsql {
51     PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'";
52     SELECT name FROM sqlite_schema WHERE type='table';
53     SELECT * from t1;
54   }
55 } {ok t1 test1 test2}
56 db close
57 file delete -force test.db
59 # set an encryption key (non-hex) and create some basic data
60 # create table and insert operations should work
61 # close database, open it again with the same
62 # key. verify that the table is readable
63 # and the data just inserted is visible
64 setup test.db "'testkey'"
65 do_test will-open-with-correct-derived-key {
67   sqlite_orig db test.db
68   execsql {
69     PRAGMA key = 'testkey';
70     SELECT name FROM sqlite_schema WHERE type='table';
71     SELECT * from t1;
72   }
73 } {ok t1 test1 test2}
74 db close
75 file delete -force test.db
77 # set an encryption key (non-hex) and create
78 # temp tables, verify you can read from
79 # sqlite_temp_master
80 setup test.db "'testkey'"
81 do_test test-temp-master {
82   sqlite_orig db test.db
83   execsql {
84     PRAGMA key = 'testkey';
85     CREATE TEMPORARY TABLE temp_t1(a,b);
86     INSERT INTO temp_t1(a,b) VALUES ('test1', 'test2');
87     SELECT name FROM sqlite_temp_master WHERE type='table';
88     SELECT * from temp_t1;
89   }
90 } {ok temp_t1 test1 test2}
91 db close
92 file delete -force test.db
94 # verify that a when a standard database is encrypted the first
95 # 16 bytes are not "SQLite format 3\0" 
96 do_test test-sqlcipher-header-overwrite {
97   sqlite_orig db test.db
98   execsql {
99     PRAGMA key = 'test';
100     CREATE TABLE t1(a,b);
101   }
102   db close
103   set header [hexio_read test.db 0 16]
104   string equal $header "53514C69746520666F726D6174203300"
105 } {0}
106 file delete -force test.db
108 # open the database and try to read from it without
109 # providing a passphrase. verify that the 
110 # an error is returned from the library
111 setup test.db "'testkey'"
112 do_test wont-open-without-key {
113   sqlite_orig db test.db
114   catchsql {
115     SELECT name FROM sqlite_schema WHERE type='table';
116   }
117 } {1 {file is not a database}}
118 db close
119 file delete -force test.db
121 # open the database and try to set an invalid
122 # passphrase. verify that an error is returned
123 # and that data couldn't be read
124 setup test.db "'testkey'"
125 do_test wont-open-with-invalid-derived-key {
126   sqlite_orig db test.db
127   catchsql {
128     PRAGMA key = 'testkey2';
129     SELECT name FROM sqlite_schema WHERE type='table';
130   }
131 } {1 {file is not a database}}
132 db close
133 file delete -force test.db
135 # open the database and try to set an invalid
136 # hex key. verify that an error is returned
137 # and that data couldn't be read
138 setup test.db "'testkey'"
139 do_test wont-open-with-invalid-raw-key {
140   sqlite_orig db test.db
141   catchsql {
142     PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836480'";
143     SELECT name FROM sqlite_schema WHERE type='table';
144   }
145 } {1 {file is not a database}}
146 db close
147 file delete -force test.db
149 # test a large number of inserts in a transaction to a memory database 
150 do_test memory-database {
151   sqlite_orig db :memory:
152   execsql {
153     PRAGMA key = 'testkey3';
154     BEGIN;
155     CREATE TABLE t2(a,b);
156   }
157   for {set i 1} {$i<=25000} {incr i} {
158     set r [expr {int(rand()*500000)}]
159     execsql "INSERT INTO t2 VALUES($i,$r);" 
160   }
161   execsql {
162     COMMIT;
163     SELECT count(*) FROM t2;
164     DELETE FROM t2;
165     SELECT count(*) FROM t2;
166   } 
167 } {25000 0}
168 db close
170 # test a large number of inserts in a transaction for multiple pages
171 do_test multi-page-database {
172   sqlite_orig db test.db
173   execsql {
174     PRAGMA key = 'testkey';
175     CREATE TABLE t2(a,b);
176     BEGIN;
177   }
178   for {set i 1} {$i<=25000} {incr i} {
179     set r [expr {int(rand()*500000)}]
180     execsql "INSERT INTO t2 VALUES($i,$r);" 
181   }
182   execsql {
183     COMMIT;
184     SELECT count(*) FROM t2;
185   } 
186 } {25000}
187 db close
188 file delete -force test.db
190 # attach an encrypted database
191 # without specifying key, verify it fails
192 # even if the source passwords are the same
193 # because the kdf salts are different
194 setup test.db "'testkey'"
195 do_test attach-database-with-default-key {
196   sqlite_orig db2 test2.db
197   set rc {}
199   execsql {
200     PRAGMA key = 'testkey';
201     PRAGMA cipher_add_random = "x'deadbaad'";
202     CREATE TABLE t2(a,b);
203     INSERT INTO t2 VALUES ('test1', 'test2'); 
204   } db2
206   lappend rc [catchsql {
207     ATTACH 'test.db' AS db;
208   } db2]
210   lappend rc [string equal [hexio_read test.db 0 16] [hexio_read test2.db 0 16]]
212 } {{1 {file is not a database}} 0}
213 db2 close
214 file delete -force test.db
215 file delete -force test2.db
217 # attach an empty encrypted database
218 # without specifying key, verify the database has the same
219 # salt and as the original 
220 setup test.db "'testkey'"
221 do_test attach-empty-database-with-default-key {
222   sqlite_orig db test.db
223   set rc {}
225   execsql {
226     PRAGMA  key='testkey';
227     INSERT INTO t1(a,b) values (1,2);
228     ATTACH DATABASE 'test2.db' AS test;
229     CREATE TABLE test.t1(a,b);
230     INSERT INTO test.t1 SELECT * FROM t1;
231     DETACH DATABASE test;
232   }
234   sqlite_orig db2 test2.db
236   lappend rc [execsql {
237     PRAGMA  key='testkey';
238     SELECT count(*) FROM t1;
239   } db2]
240   lappend rc [string equal [hexio_read test.db 0 16] [hexio_read test2.db 0 16]]
241 } {{ok 2} 1}
242 db close
243 db2 close
244 file delete -force test.db
245 file delete -force test2.db
247 # attach an empty encrypted database as the first operation on a keyed database. Verify
248 # that the new database has the same salt as the original.
250 # HISTORICAL NOTE: The original behavior of SQLCipher under these conditions
251 # was that the databases would have different salts but the same keys. This was because
252 # derivation of the key spec would not have occurred yet. However, upstream check-in
253 # https://sqlite.org/src/info/a02da71f3a80dd8e changed this behavior by
254 # forcing a read of the main database schema during the attach operation.
255 # This causes the main database to be opened and the key derivation logic to fire which
256 # reads the salt. Thus the current behavior of this test should now be identical
257 # to the previous attach-empty-database-with-default-key.
259 setup test.db "'testkey'"
260 do_test attach-empty-database-with-default-key-first-op {
261   sqlite_orig db test.db
262   set rc {}
264   execsql {
265     PRAGMA  key='testkey';
266     ATTACH DATABASE 'test2.db' AS test;
267     CREATE TABLE test.t1(a,b);
268     INSERT INTO test.t1 SELECT * FROM t1;
269     DETACH DATABASE test;
270   }
272   sqlite_orig db2 test2.db
274   lappend rc [execsql {
275     PRAGMA  key='testkey';
276     SELECT count(*) FROM t1;
277   } db2]
279   lappend rc [string equal [hexio_read test.db 0 16] [hexio_read test2.db 0 16]]
280 } {{ok 1} 1}
281 db close
282 db2 close
283 file delete -force test.db
284 file delete -force test2.db
286 # attach an empty encrypted database 
287 # on a keyed database when PRAGMA cipher_store_pass = 1
288 # and verify different salts
289 setup test.db "'testkey'"
290 do_test attach-empty-database-with-cipher-store-pass {
291   sqlite_orig db test.db
292   set rc {}
294   execsql {
295     PRAGMA  key='testkey';
296     PRAGMA cipher_store_pass = 1;
297     INSERT INTO t1(a,b) VALUES (1,2);
298     ATTACH DATABASE 'test2.db' AS test;
299     CREATE TABLE test.t1(a,b);
300     INSERT INTO test.t1 SELECT * FROM t1;
301     DETACH DATABASE test;
302   }
304   sqlite_orig db2 test2.db
306   lappend rc [execsql {
307     PRAGMA  key='testkey';
308     SELECT count(*) FROM t1;
309   } db2]
310   lappend rc [string equal [hexio_read test.db 0 16] [hexio_read test2.db 0 16]]
311 } {{ok 2} 0}
312 db close
313 db2 close
314 file delete -force test.db
315 file delete -force test2.db
317 # attach an encrypted database
318 # without specifying key, verify it attaches
319 # correctly when PRAGMA cipher_store_pass = 1
320 # is set
321 do_test attach-database-with-default-key-using-cipher-store-pass {
322     sqlite_orig db1 test.db  
323     execsql {
324         PRAGMA key = 'testkey';
325         CREATE TABLE t1(a,b);
326         INSERT INTO t1(a,b) VALUES('foo', 'bar');        
327     } db1
328     db1 close
330     sqlite_orig db2 test2.db
331     execsql {
332       PRAGMA key = 'testkey';
333       CREATE TABLE t2(a,b);
334       INSERT INTO t2 VALUES ('test1', 'test2'); 
335     } db2
336     db2 close
338     sqlite_orig db1 test.db
339     execsql {
340         PRAGMA key = 'testkey';
341         PRAGMA cipher_store_pass = 1;
342         ATTACH DATABASE 'test2.db' as db2;
343         SELECT sqlcipher_export('db2');
344         DETACH DATABASE db2;
345     } db1
346     db1 close
348     sqlite_orig db2 test2.db  
349     execsql {
350         PRAGMA key = 'testkey';
351         SELECT * FROM t1;
352     } db2
354 } {ok foo bar}
355 db2 close
356 file delete -force test.db
357 file delete -force test2.db
359 # attach an encrypted database
360 # where both database have the same
361 # key explicitly and verify they have different
362 # salt values
363 setup test.db "'testkey'"
364 do_test attach-database-with-same-key {
365   sqlite_orig db2 test2.db
366   
367   set rc {}
369   execsql {
370     PRAGMA key = 'testkey';
371     CREATE TABLE t2(a,b);
372     INSERT INTO t2 VALUES ('test1', 'test2'); 
373   } db2
375   lappend rc [execsql {
376     SELECT count(*) FROM t2;
377     ATTACH 'test.db' AS db KEY 'testkey';
378     SELECT count(*) FROM db.t1;
379   } db2]
380   
381   lappend rc [string equal [hexio_read test.db 0 16] [hexio_read test2.db 0 16]]
382 } {{1 1} 0}
383 db2 close
384 file delete -force test.db
385 file delete -force test2.db
387 # attach an encrypted database
388 # where databases have different keys
389 setup test.db "'testkey'"
390 do_test attach-database-with-different-keys {
391   sqlite_orig db2 test2.db
393   execsql {
394     PRAGMA key = 'testkey2';
395     CREATE TABLE t2(a,b);
396     INSERT INTO t2 VALUES ('test1', 'test2'); 
397   } db2
398   
399   execsql {
400     ATTACH 'test.db' AS db KEY 'testkey';
401     SELECT count(*) FROM db.t1;
402     SELECT count(*) FROM t2;
403   } db2
405 } {1 1}
406 db2 close
407 file delete -force test.db
408 file delete -force test2.db
410 # test locking across multiple handles
411 setup test.db "'testkey'"
412 do_test locking-across-multiple-handles-start {
413   sqlite_orig db test.db
415   execsql {
416     PRAGMA key = 'testkey';
417     BEGIN EXCLUSIVE;
418     INSERT INTO t1 VALUES(1,2);
419   } 
420   
421   sqlite_orig dba test.db
422   catchsql {
423     PRAGMA key = 'testkey';
424       SELECT count(*) FROM t1;
425   } dba
427  } {1 {database is locked}} 
429 do_test locking-accross-multiple-handles-finish {
430  execsql {
431     COMMIT;
432   }
434   execsql {
435     SELECT count(*) FROM t1;
436   } dba
437 } {2}
438 db close
439 dba close
440 file delete -force test.db
442 # alter schema
443 setup test.db "'testkey'"
444 do_test alter-schema {
445   sqlite_orig db test.db
446   execsql {
447     PRAGMA key = 'testkey';
448     ALTER TABLE t1 ADD COLUMN c;
449     INSERT INTO t1 VALUES (1,2,3);
450     INSERT INTO t1 VALUES (1,2,4);
451     CREATE TABLE t1a (a);
452     INSERT INTO t1a VALUES ('teststring');
453   }
454   db close
456   sqlite_orig db test.db
457   execsql {
458     PRAGMA key = 'testkey';
459     SELECT count(*) FROM t1 WHERE a IS NOT NULL;
460     SELECT count(*) FROM t1 WHERE c IS NOT NULL;
461     SELECT * FROM t1a;
462   } 
464 } {ok 3 2 teststring}
465 db close
466 file delete -force test.db
468 # test alterations of KDF iterations and ciphers
469 # rekey then add
470 setup test.db "'testkey'"
471 do_test verify-errors-for-rekey-kdf-and-cipher-changes {
472   sqlite_orig db test.db
473   execsql {
474     PRAGMA key = 'testkey';
475     PRAGMA rekey_kdf_iter = 1000;
476     PRAGMA rekey_cipher = 'aes-256-ecb';
477   } 
478 } {ok {PRAGMA rekey_kdf_iter is no longer supported.} {PRAGMA rekey_cipher is no longer supported.}}
479 db close
480 file delete -force test.db
483 setup test.db "'testkey'"
484 do_test verify-errors-for-cipher-change {
485   sqlite_orig db test.db
486   execsql {
487     PRAGMA key = 'testkey';
488     PRAGMA cipher = 'aes-256-ecb';
489   } 
490 } {ok {PRAGMA cipher is no longer supported.}}
491 db close
492 file delete -force test.db
495 # 1. create a database with a custom page size, 
496 # 2. create table and insert operations should work
497 # 3. close database, open it again with the same
498 #    key and page size
499 # 4. verify that the table is readable
500 #    and the data just inserted is visible
501 do_test custom-pagesize {
502   sqlite_orig db test.db
504   execsql {
505     PRAGMA key = 'testkey';
506     PRAGMA cipher_page_size = 8192;
507     CREATE table t1(a,b);
508     BEGIN;
509   }
511   for {set i 1} {$i<=1000} {incr i} {
512     set r [expr {int(rand()*500000)}]
513     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
514   }
516   execsql {
517     COMMIT;
518   } 
520   db close
521   sqlite_orig db test.db
523   execsql {
524     PRAGMA key = 'testkey';
525     PRAGMA cipher_page_size = 8192;
526     SELECT count(*) FROM t1;
527   }
529 } {ok 1000}
530 db close
532 # open the database with the default page size
533 ## and verfiy that it is not readable 
534 do_test custom-pagesize-must-match {
535   sqlite_orig db test.db
536   catchsql {
537     PRAGMA key = 'testkey';
538     SELECT name FROM sqlite_schema WHERE type='table';
539   }
540 } {1 {file is not a database}}
541 db close
542 file delete -force test.db
545 # 1. create a database with WAL journal mode
546 # 2. create table and insert operations should work
547 # 3. close database, open it again
548 # 4. verify that the table is present, readable, and that
549 #    the journal mode is WAL
550 do_test journal-mode-wal {
551   sqlite_orig db test.db
553   execsql {
554     PRAGMA key = 'testkey';
555     PRAGMA journal_mode = WAL;
556     CREATE table t1(a,b);
557     BEGIN;
558   }
560   for {set i 1} {$i<=1000} {incr i} {
561     set r [expr {int(rand()*500000)}]
562     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
563   }
565   execsql {
566     COMMIT;
567   } 
569   db close
570   sqlite_orig db test.db
572   execsql {
573     PRAGMA key = 'testkey';
574     SELECT count(*) FROM t1;
575     PRAGMA journal_mode;
576   }
578 } {ok 1000 wal}
579 db close
580 file delete -force test.db
582 # open a database and try to use an invalid
583 # passphrase. verify that an error is returned
584 # and that data couldn't be read. without closing the databsae
585 # set the correct key and verify it is working.
586 setup test.db "'testkey'"
587 do_test multiple-key-calls-safe-wrong-key-first {
588   sqlite_orig db test.db
589   set rc {}
591   lappend rc [catchsql {
592     PRAGMA key = 'testkey2';
593     SELECT count(*) FROM sqlite_schema;
594   }]
596   lappend rc [execsql {
597     PRAGMA key = 'testkey';
598     SELECT count(*) FROM sqlite_schema;
599   }]
600 } {{1 {file is not a database}} {ok 1}}
601 db close
602 file delete -force test.db
604 # open a databse and use the valid key. Then
605 # use pragma key to try to set an invalid key
606 # without closing the database. It should not do anything
608 setup test.db "'testkey'"
609 do_test multiple-key-calls-safe {
610   sqlite_orig db test.db
611   execsql {
612     PRAGMA key = 'testkey';
613     PRAGMA cache_size = 0; 
614     SELECT name FROM sqlite_schema WHERE type='table';
615     PRAGMA key = 'wrong key'; 
616     SELECT name FROM sqlite_schema WHERE type='table';
617     PRAGMA key = 'testkey'; 
618     SELECT name FROM sqlite_schema WHERE type='table';
619   }
620 } {ok t1 ok t1 ok t1}
622 db close
623 file delete -force test.db
625 # 1. create a database with a custom hmac kdf iteration count, 
626 # 2. create table and insert operations should work
627 # 3. close database, open it again with the same
628 #    key and  hmac kdf iteration count
629 # 4. verify that the table is readable
630 #    and the data just inserted is visible
631 do_test custom-hmac-kdf-iter {
632   sqlite_orig db test.db
634   execsql {
635     PRAGMA key = 'testkey';
636     PRAGMA kdf_iter = 10;
637     CREATE table t1(a,b);
638     BEGIN;
639   }
641   for {set i 1} {$i<=1000} {incr i} {
642     set r [expr {int(rand()*500000)}]
643     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
644   }
646   execsql {
647     COMMIT;
648   } 
650   db close
651   sqlite_orig db test.db
653   execsql {
654     PRAGMA key = 'testkey';
655     PRAGMA kdf_iter = 10;
656     SELECT count(*) FROM t1;
657   }
659 } {ok 1000}
660 db close
662 # open the database with the default hmac
663 # kdf iteration count
664 # to verify that it is not readable 
665 do_test custom-hmac-kdf-iter-must-match {
666   sqlite_orig db test.db
667   catchsql {
668     PRAGMA key = 'testkey';
669     SELECT name FROM sqlite_schema WHERE type='table';
670   }
671 } {1 {file is not a database}}
672 db close
673 file delete -force test.db
675 # open the database and turn on auto_vacuum
676 # then insert a bunch of data, delete it 
677 # and verify that the file has become smaller
678 # but can still be opened with the proper
679 # key
680 do_test auto-vacuum {
681   sqlite_orig db test.db
682   set rc {}
684   execsql {
685     PRAGMA key = 'testkey';
686     PRAGMA auto_vacuum=FULL;
687     CREATE table t1(a,b);
688     BEGIN;
689   }
691   for {set i 1} {$i<=10000} {incr i} {
692     set r [expr {int(rand()*500000)}]
693     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
694   }
696   lappend rc [execsql {
697     COMMIT;
698     SELECT count(*) FROM t1;
699   }]
701   # grab current size of file
702   set sz [file size test.db]
703   
704   # delete some records, and verify
705   # autovacuum removes them
706   execsql {
707     DELETE FROM t1 WHERE rowid > 5000;
708   } 
710   db close
712   # grab new file size, post
713   # autovacuum
714   set sz2 [file size test.db]
716   # verify that the new size is 
717   # smaller than the old size
718   if {$sz > $sz2} { lappend rc true }
720   sqlite_orig db test.db
722   lappend rc [execsql {
723     PRAGMA key = 'testkey';
724     SELECT count(*) FROM t1;
725   }]
727 } {10000 true {ok 5000}}
728 db close
729 file delete -force test.db
731 # test kdf_iter and other pragmas 
732 # before a key is set. Verify that they
733 # are no-ops
734 do_test cipher-options-before-keys {
735   sqlite_orig db test.db
737   execsql {
738     PRAGMA kdf_iter = 1000;
739     PRAGMA cipher_page_size = 8192;
740     PRAGMA cipher_use_hmac = OFF;
741     PRAGMA key = 'testkey';
742     CREATE table t1(a,b);
743     INSERT INTO t1 VALUES(1,2);
744   }
745   db close
747   sqlite_orig db test.db
749   execsql {
750     PRAGMA key = 'testkey';
751     SELECT count(*) FROM t1;
752   }
754 } {ok 1}
755 db close
756 file delete -force test.db
758 # verify memory security behavior
759 # initially should report OFF
760 # then enable, check that it is ON
761 # try to turn if off, but verify that it
762 # can't be unset.
763 do_test verify-memory-security {
764     sqlite_orig db test.db
765     execsql {
766         PRAGMA cipher_memory_security;
767         PRAGMA cipher_memory_security = ON;
768         PRAGMA cipher_memory_security;
769         PRAGMA cipher_memory_security = OFF;
770         PRAGMA cipher_memory_security;
771     }
772 } {0 1 1}
773 db close
774 file delete -force test.db
776 # create two new database files, write to each
777 # and verify that they have different (i.e. random)
778 # salt values
779 do_test test-random-salt {
780   sqlite_orig db test.db
781   sqlite_orig db2 test2.db
782   execsql {
783     PRAGMA key = 'test';
784     CREATE TABLE t1(a,b);
785     INSERT INTO t1(a,b) VALUES (1,2);
786   }
787   execsql {
788     PRAGMA key = 'test';
789     CREATE TABLE t1(a,b);
790     INSERT INTO t1(a,b) VALUES (1,2);
791   } db2
792   db close
793   db2 close
794   string equal [hexio_read test.db 0 16] [hexio_read test2.db 0 16]
795 } {0}
796 file delete -force test.db
797 file delete -force test2.db
799 # test scenario where multiple handles are opened
800 # to a file that does not exist, where both handles
801 # use the same key
802 do_test multiple-handles-same-key-and-salt {
803   sqlite_orig db test.db
804   sqlite_orig dba test.db
806   execsql {
807     PRAGMA key = 'testkey';
808   }
809   execsql {
810     PRAGMA key = 'testkey';
811   } dba
813   execsql {
814     CREATE TABLE t1(a,b);
815     INSERT INTO t1 VALUES(1,2);
816   }
818   execsql {
819     SELECT count(*) FROM t1;
820   }
821   execsql {
822     SELECT count(*) FROM t1;
823   } dba
825 } {1}
826 db close
827 dba close
828 file delete -force test.db
830 do_test test_flags_fail_encrypt {
831   sqlite_orig db :memory:
832   execsql {
833     PRAGMA cipher_test;
834     PRAGMA cipher_test_on = fail_encrypt;
835     PRAGMA cipher_test;
836     PRAGMA cipher_test_off = fail_encrypt;
837     PRAGMA cipher_test;
838   }
839 } {0 1 0}
840 db close
842 do_test test_flags_fail_decrypt {
843   sqlite_orig db :memory:
844   execsql {
845     PRAGMA cipher_test;
846     PRAGMA cipher_test_on = fail_decrypt;
847     PRAGMA cipher_test;
848     PRAGMA cipher_test_off = fail_decrypt;
849     PRAGMA cipher_test;
850   }
851 } {0 2 0}
852 db close
854 do_test test_flags_fail_migrate {
855   sqlite_orig db :memory:
856   execsql {
857     PRAGMA cipher_test;
858     PRAGMA cipher_test_on = fail_migrate;
859     PRAGMA cipher_test;
860     PRAGMA cipher_test_off = fail_migrate;
861     PRAGMA cipher_test;
862   }
863 } {0 4 0}
864 db close
866 do_test test_flags_combo {
867   sqlite_orig db :memory:
868   execsql {
869     PRAGMA cipher_test;
870     PRAGMA cipher_test_on = fail_encrypt;
871     PRAGMA cipher_test_on = fail_migrate;
872     PRAGMA cipher_test;
873     PRAGMA cipher_test_off = fail_encrypt;
874     PRAGMA cipher_test_off = fail_migrate;
875     PRAGMA cipher_test;
876   }
877 } {0 5 0}
878 db close
880 # test empty key
881 # it should raise an error
882 do_test empty-key {
883   sqlite_orig db test.db
885   catchsql {
886     PRAGMA key = '';
887   }
889 } {1 {An error occurred with PRAGMA key or rekey. PRAGMA key requires a key of one or more characters. PRAGMA rekey can only be run on an existing encrypted database. Use sqlcipher_export() and ATTACH to convert encrypted/plaintext databases.}}
890 db close
891 file delete -force test.db
893 # configure URI filename support
894 # create a new encrypted database with the key via parameter
895 # close database
896 # open normally providing key via pragma verify
897 # correct key works
898 sqlite3_shutdown
899 sqlite3_config_uri 1
900 do_test uri-key {
901   sqlite_orig db file:test.db?a=a&key=testkey&c=c
903   execsql {
904     CREATE TABLE t1(a,b);
905     INSERT INTO t1 VALUES(1,2);
906   }
908   db close
909   sqlite_orig db test.db
911   catchsql {
912     PRAGMA key = 'testkey';
913     SELECT count(*) FROM t1;
914   }
916   db close
917   sqlite_orig db test.db
919   execsql {
920     PRAGMA key = 'testkey';
921     SELECT count(*) FROM t1;
922   }
924 } {ok 1}
925 db close
927 # verify wrong key fails
928 do_test uri-key-2 {
929   sqlite_orig db test.db
930   catchsql {
931     PRAGMA key = 'test';
932     SELECT count(*) FROM t1;
933   }
934 } {1 {file is not a database}}
935 db close
936 file delete -force test.db
937 sqlite3_shutdown
938 sqlite3_config_uri 0
940 finish_test