2 # codec.test developed by Stephen Lombardo (Zetetic LLC)
3 # sjlombardo at zetetic dot 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 # Test rekey as first operation on an empty database. should be a no-op
42 do_test rekey-as-first-op {
43 sqlite_orig db test.db
46 PRAGMA rekey = 'testkey';
51 for {set i 1} {$i<=100} {incr i} {
52 set r [expr {int(rand()*500000)}]
53 execsql "INSERT INTO t1 VALUES($i,'value $r');"
61 sqlite_orig db test.db
64 PRAGMA rekey = 'testkey';
65 SELECT count(*) FROM t1;
70 file delete -force test.db
72 # Test rekey as first operation follwed by key
73 do_test rekey-then-key-as-first-ops {
74 sqlite_orig db test.db
77 PRAGMA rekey = '1234';
78 PRAGMA key = 'testkey';
83 for {set i 1} {$i<=100} {incr i} {
84 set r [expr {int(rand()*500000)}]
85 execsql "INSERT INTO t1 VALUES($i,'value $r');"
93 sqlite_orig db test.db
96 PRAGMA rekey = '4321';
97 PRAGMA key = 'testkey';
98 SELECT count(*) FROM t1;
103 file delete -force test.db
106 # test a rekey operation as the first op on a database
107 # then test that now the new key opens the database
108 # now close database re-open with new key
109 setup test.db "'testkey'"
110 do_test rekey-as-first-operation {
111 sqlite_orig db test.db
113 PRAGMA key = 'testkey';
114 PRAGMA rekey = 'testkeynew';
118 sqlite_orig db test.db
120 PRAGMA key = 'testkeynew';
121 SELECT name FROM sqlite_schema WHERE type='table';
125 file delete -force test.db
127 # create a new database, insert some data
128 # then rekey it with the same password
129 do_test rekey-same-passkey {
130 sqlite_orig db test.db
133 PRAGMA key = 'test123';
134 CREATE TABLE t1(a,b);
138 for {set i 1} {$i<=1000} {incr i} {
139 set r [expr {int(rand()*500000)}]
140 execsql "INSERT INTO t1 VALUES($i,'value $r');"
145 SELECT count(*) FROM t1;
146 PRAGMA rekey = 'test123';
147 SELECT count(*) FROM t1;
151 file delete -force test.db
153 # create a new database, insert some data
154 # then rekey it. Make sure it is immediately
155 # readable. Then close it and make sure it can be
157 do_test rekey-and-query-1 {
158 sqlite_orig db test.db
161 PRAGMA key = 'test123';
162 CREATE TABLE t1(a,b);
166 for {set i 1} {$i<=1000} {incr i} {
167 set r [expr {int(rand()*500000)}]
168 execsql "INSERT INTO t1 VALUES($i,'value $r');"
173 SELECT count(*) FROM t1;
174 PRAGMA rekey = 'test321';
175 SELECT count(*) FROM t1;
181 do_test rekey-and-query-2 {
182 sqlite_orig db test.db
184 PRAGMA key = 'test321';
185 SELECT count(*) FROM t1;
189 file delete -force test.db
191 # create a new database, insert some data
192 # delete about 50% of the data
193 # write some new data
195 # then rekey it. Make sure it is immediately
196 # readable. Then close it and make sure it can be
197 # read back. This test will ensure that Secure Delete
198 # is enabled and all pages are being written and are not
199 # being optimized out by sqlite3PagerDontWrite
200 do_test rekey-delete-and-query-1 {
201 sqlite_orig db test.db
204 PRAGMA key = 'test123';
205 CREATE TABLE t1(a,b);
206 CREATE INDEX ta_a ON t1(a);
210 for {set i 1} {$i<1000} {incr i} {
211 set r1 [expr {int(rand()*32767)}]
212 execsql "INSERT INTO t1 VALUES($i,$r1);"
215 execsql "DELETE FROM t1 WHERE a < 500;"
217 set r1 [expr {int(rand()*32767)}]
218 execsql "UPDATE t1 SET b = $r1 WHERE a < 750;"
220 execsql "DELETE FROM t1 WHERE a > 750;"
224 SELECT (count(*) > 0) FROM t1;
229 do_test rekey-delete-and-query-2 {
230 sqlite_orig db test.db
232 PRAGMA key = 'test123';
233 PRAGMA rekey = 'test321';
234 SELECT count(*) > 1 FROM t1;
235 PRAGMA integrity_check;
240 do_test rekey-delete-and-query-3 {
241 sqlite_orig db test.db
243 PRAGMA key = 'test321';
244 SELECT count(*) > 1 FROM t1;
248 file delete -force test.db
251 # same as previous test, but use WAL
252 do_test rekey-delete-and-query-wal-1 {
253 sqlite_orig db test.db
256 PRAGMA key = 'test123';
257 PRAGMA journal_mode = WAL;
258 CREATE TABLE t1(a,b);
259 CREATE INDEX ta_a ON t1(a);
263 for {set i 1} {$i<1000} {incr i} {
264 set r1 [expr {int(rand()*32767)}]
265 execsql "INSERT INTO t1 VALUES($i,$r1);"
268 execsql "DELETE FROM t1 WHERE a < 500;"
270 set r1 [expr {int(rand()*32767)}]
271 execsql "UPDATE t1 SET b = $r1 WHERE a < 750;"
273 execsql "DELETE FROM t1 WHERE a > 750;"
277 SELECT (count(*) > 0) FROM t1;
282 do_test rekey-delete-and-query-wal-2 {
283 sqlite_orig db test.db
285 PRAGMA key = 'test123';
286 PRAGMA journal_mode = WAL;
287 PRAGMA rekey = 'test321';
288 SELECT count(*) > 1 FROM t1;
289 PRAGMA integrity_check;
294 do_test rekey-delete-and-query-wal-3 {
295 sqlite_orig db test.db
297 PRAGMA key = 'test321';
298 PRAGMA journal_mode = WAL;
299 SELECT count(*) > 1 FROM t1;
303 file delete -force test.db
305 do_test rekey-database-by-name {
306 sqlite_orig db test.db
308 attach database 'new.db' as new;
309 pragma new.key = 'foo';
310 create table new.t1(a,b);
311 insert into new.t1(a,b) values('foo', 'bar');
312 pragma new.rekey = 'bar';
317 sqlite_orig db new.db
324 file delete -force test.db
325 file delete -force new.db