From 569c6676a6ddb0ff73821d7693b5e18ddef809b9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 16 Oct 2014 22:51:35 -0400 Subject: Imported Upstream version 3.2.0 --- test/crypto.test | 427 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 391 insertions(+), 36 deletions(-) (limited to 'test/crypto.test') diff --git a/test/crypto.test b/test/crypto.test index 8a58fe0..629be5d 100644 --- a/test/crypto.test +++ b/test/crypto.test @@ -4,8 +4,6 @@ # http://zetetic.net # # Copyright (c) 2009, ZETETIC LLC -# All rights reserved. -# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright @@ -44,6 +42,7 @@ file delete -force test4.db set testdir [file dirname $argv0] source $testdir/tester.tcl +set old_pending_byte [sqlite3_test_control_pending_byte 0x40000000] # If the library is not compiled with has_codec support then # skip all tests in this file. @@ -88,6 +87,21 @@ proc if_built_with_commoncrypto {name cmd expected} { } } +proc cmpFilesChunked {file1 file2 {chunksize 16384}} { + set f1 [open $file1]; fconfigure $f1 -translation binary + set f2 [open $file2]; fconfigure $f2 -translation binary + while {1} { + set d1 [read $f1 $chunksize] + set d2 [read $f2 $chunksize] + set diff [string compare $d1 $d2] + if {$diff != 0 || [eof $f1] || [eof $f2]} { + close $f1; close $f2 + return $diff + } + } + return 0 +} + # The database is initially empty. # set an hex key create some basic data # create table and insert operations should work @@ -407,9 +421,75 @@ do_test rekey-delete-and-query-wal-3 { db close file delete -force test.db +# attach an encrypted database +# without specifying key, verify it fails +# even if the source passwords are the same +# because the kdf salts are different +setup test.db "'testkey'" +do_test attach-database-with-default-key { + sqlite_orig db2 test2.db + execsql { + PRAGMA key = 'testkey'; + PRAGMA cipher_add_random = "x'deadbaad'"; + CREATE TABLE t2(a,b); + INSERT INTO t2 VALUES ('test1', 'test2'); + } db2 + + catchsql { + ATTACH 'test.db' AS db; + } db2 + +} {1 {file is encrypted or is not a database}} +db2 close +file delete -force test.db +file delete -force test2.db + +# attach an encrypted database +# without specifying key, verify it attaches +# correctly when PRAGMA cipher_store_pass = 1 +# is set. +do_test attach-database-with-default-key-using-cipher-store-pass { + + sqlite_orig db1 test.db + execsql { + PRAGMA key = 'testkey'; + CREATE TABLE t1(a,b); + INSERT INTO t1(a,b) VALUES('foo', 'bar'); + } db1 + db1 close + + sqlite_orig db2 test2.db + execsql { + PRAGMA key = 'testkey'; + CREATE TABLE t2(a,b); + INSERT INTO t2 VALUES ('test1', 'test2'); + } db2 + db2 close + + sqlite_orig db1 test.db + execsql { + PRAGMA key = 'testkey'; + PRAGMA cipher_store_pass = 1; + ATTACH DATABASE 'test2.db' as db2; + SELECT sqlcipher_export('db2'); + DETACH DATABASE db2; + } db1 + db1 close + + sqlite_orig db2 test2.db + execsql { + PRAGMA key = 'testkey'; + SELECT * FROM t1; + } db2 + +} {foo bar} +db2 close +file delete -force test.db +file delete -force test2.db + # attach an encrypted database # where both database have the same -# key +# key explicitly setup test.db "'testkey'" do_test attach-database-with-same-key { sqlite_orig db2 test2.db @@ -422,7 +502,7 @@ do_test attach-database-with-same-key { execsql { SELECT count(*) FROM t2; - ATTACH 'test.db' AS db; + ATTACH 'test.db' AS db KEY 'testkey'; SELECT count(*) FROM db.t1; } db2 @@ -607,7 +687,7 @@ file delete -force test.db # create an unencrypted database, attach a new encrypted volume # copy data between, verify the encypted database is good afterwards -do_test unencryped-attach { +do_test unencrypted-attach { sqlite_orig db test.db execsql { @@ -641,7 +721,7 @@ file delete -force test2.db # create an unencrypted database, attach a new encrypted volume # using a raw key copy data between, verify the encypted # database is good afterwards -do_test unencryped-attach-raw-key { +do_test unencrypted-attach-raw-key { sqlite_orig db test.db execsql { @@ -672,9 +752,45 @@ db2 close file delete -force test.db file delete -force test2.db +# create an encrypted database, attach an default-key encrypted volume +# copy data between, verify the second database +do_test encrypted-attach-default-key { + sqlite_orig db test.db + + execsql { + PRAGMA key='testkey'; + 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,$r);" + } + + execsql { + COMMIT; + ATTACH DATABASE 'test2.db' AS test; + CREATE TABLE test.t1(a,b); + INSERT INTO test.t1 SELECT * FROM t1; + DETACH DATABASE test; + } + + sqlite_orig db2 test2.db + + execsql { + PRAGMA key='testkey'; + SELECT count(*) FROM t1; + } db2 +} {1000} +db close +db2 close +file delete -force test.db +file delete -force test2.db + # create an encrypted database, attach an unencrypted volume # copy data between, verify the unencypted database is good afterwards -do_test encryped-attach-unencrypted { +do_test encrypted-attach-unencrypted { sqlite_orig db test.db execsql { @@ -683,7 +799,7 @@ do_test encryped-attach-unencrypted { sqlite_orig db2 test2.db execsql { - PRAGMA key='testkey'; + PRAGMA key = 'testkey'; CREATE TABLE t1(a,b); BEGIN; } db2 @@ -711,7 +827,7 @@ file delete -force test2.db # create an unencrypted database, attach an unencrypted volume # copy data between, verify the unencypted database is good afterwards -do_test unencryped-attach-unencrypted { +do_test unencrypted-attach-unencrypted { sqlite_orig db test.db execsql { @@ -875,16 +991,18 @@ file delete -force test.db # open a 1.1.8 database using the new code, HMAC disabled do_test open-1.1.8-database { - sqlite_orig db sqlcipher-1.1.8-testkey.db + file copy -force sqlcipher-1.1.8-testkey.db test.db + sqlite_orig db test.db execsql { PRAGMA key = 'testkey'; - PRAGMA cipher_use_hmac = OFF; + PRAGMA cipher_use_hmac = off; + PRAGMA kdf_iter = 4000; SELECT count(*) FROM t1; - SELECT * FROM t1; + SELECT distinct * FROM t1; } -} {4 1 1 one one 1 2 one two} +} {75709 1 1 one one 1 2 one two 1 2} db close - +file delete -force test.db # open a 1.1.8 database without hmac, then copy the data do_test attach-and-copy-1.1.8 { @@ -893,6 +1011,7 @@ do_test attach-and-copy-1.1.8 { execsql { PRAGMA key = 'testkey'; PRAGMA cipher_use_hmac = OFF; + PRAGMA kdf_iter = 4000; ATTACH DATABASE 'test.db' AS db2 KEY 'testkey-hmac'; CREATE TABLE db2.t1(a,b); INSERT INTO db2.t1 SELECT * FROM main.t1; @@ -904,9 +1023,9 @@ do_test attach-and-copy-1.1.8 { execsql { PRAGMA key = 'testkey-hmac'; SELECT count(*) FROM t1; - SELECT * FROM t1; + SELECT distinct * FROM t1; } -} {4 1 1 one one 1 2 one two} +} {75709 1 1 one one 1 2 one two 1 2} db close file delete -force test.db @@ -1350,22 +1469,24 @@ do_test cipher-options-before-keys { db close file delete -force test.db -# open a 1.1.8 database (no HMAC), then +# open a 1.1.8 database (no HMAC, 4K iter), 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 { +do_test default-hmac-kdf-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 cipher_default_kdf_iter = 4000; PRAGMA key = 'testkey'; SELECT count(*) FROM t1; - ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2; + ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey'; SELECT count(*) from db2.t1; PRAGMA cipher_default_use_hmac = ON; + PRAGMA cipher_default_kdf_iter = 64000; } -} {4 4} +} {75709 75709} db close file delete -force test.db @@ -1378,18 +1499,18 @@ do_test attach-1.1.8-database-from-2.0-fails { catchsql { PRAGMA key = 'testkey'; CREATE table t1(a,b); - ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2; + ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey'; } } {1 {file is encrypted or is not a database}} db close file delete -force test.db -# open a 2.0 database (with HMAC), then +# open a 2.0 database (with HMAC, 4k iter), 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 { +do_test change-default-hmac-kdf-attach { sqlite_orig db test.db execsql { PRAGMA key = 'testkey'; @@ -1402,11 +1523,13 @@ do_test change-default-use-hmac-attach { PRAGMA key = 'testkey'; SELECT count(*) FROM t1; PRAGMA cipher_default_use_hmac = OFF; - ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2; + PRAGMA cipher_default_kdf_iter = 4000; + ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey'; SELECT count(*) from db2.t1; PRAGMA cipher_default_use_hmac = ON; + PRAGMA cipher_default_kdf_iter = 64000; } -} {1 4} +} {1 75709} db close file delete -force test.db @@ -1418,7 +1541,7 @@ do_test verify-pragma-cipher-version { execsql { PRAGMA cipher_version; } -} {2.2.1} +} {3.2.0} db close file delete -force test.db @@ -1580,16 +1703,29 @@ do_test multipage-schema-autovacuum-shortread-wal { db close file delete -force test.db +# open a 3.0 database with little endian hmac page numbers (default) +# verify it can be opened +do_test open-3.0-le-database { + sqlite_orig db sqlcipher-3.0-testkey.db + execsql { + PRAGMA key = 'testkey'; + SELECT count(*) FROM t1; + SELECT distinct * FROM t1; + } +} {78536 1 1 one one 1 2 one two} +db close + # open a 2.0 database with little endian hmac page numbers (default) # verify it can be opened do_test open-2.0-le-database { sqlite_orig db sqlcipher-2.0-le-testkey.db execsql { PRAGMA key = 'testkey'; + PRAGMA kdf_iter = 4000; SELECT count(*) FROM t1; - SELECT * FROM t1; + SELECT distinct * FROM t1; } -} {4 1 1 one one 1 2 one two} +} {78536 1 1 one one 1 2 one two} db close # open a 2.0 database with big-endian hmac page numbers @@ -1599,10 +1735,11 @@ do_test open-2.0-be-database { execsql { PRAGMA key = 'testkey'; PRAGMA cipher_hmac_pgno = be; + PRAGMA kdf_iter = 4000; SELECT count(*) FROM t1; - SELECT * FROM t1; + SELECT distinct * FROM t1; } -} {4 1 1 one one 1 2 one two} +} {78536 1 1 one one 1 2 one two} db close # open a 2.0 database with big-endian hmac page numbers @@ -1615,6 +1752,7 @@ do_test be-to-le-migration { execsql { PRAGMA key = 'testkey'; PRAGMA cipher_hmac_pgno = be; + PRAGMA kdf_iter = 4000; ATTACH DATABASE 'test.db' AS db2 KEY 'testkey'; CREATE TABLE db2.t1(a,b); INSERT INTO db2.t1 SELECT * FROM main.t1; @@ -1626,9 +1764,9 @@ do_test be-to-le-migration { execsql { PRAGMA key = 'testkey'; SELECT count(*) FROM t1; - SELECT * FROM t1; + SELECT distinct * FROM t1; } -} {4 1 1 one one 1 2 one two} +} {78536 1 1 one one 1 2 one two} db close file delete -force test.db @@ -1684,6 +1822,31 @@ do_test verify-pragma-cipher-default-use-hmac-off { db close file delete -force test.db +# verify the pragma default_cipher_kdf_iter +# is set to 64000 by default +do_test verify-pragma-cipher-default-kdf-iter-default { + sqlite_orig db test.db + execsql { + PRAGMA cipher_default_kdf_iter; + } +} {64000} +db close +file delete -force test.db + + +# verify the pragma default_cipher_kdf_ter +# reports changes +do_test verify-pragma-cipher-default-use-hmac-off { + sqlite_orig db test.db + execsql { + PRAGMA cipher_default_kdf_iter = 1000; + PRAGMA cipher_default_kdf_iter; + PRAGMA cipher_default_kdf_iter = 64000; + } +} {1000} +db close +file delete -force test.db + # verify the pragma kdf_iter # reports the default value do_test verify-pragma-kdf-iter-reports-default { @@ -1692,7 +1855,7 @@ do_test verify-pragma-kdf-iter-reports-default { PRAGMA key = 'test'; PRAGMA kdf_iter; } -} {4000} +} {64000} db close file delete -force test.db @@ -1843,12 +2006,13 @@ do_test open-2.0-beta-database { sqlite_orig db sqlcipher-2.0-beta-testkey.db execsql { PRAGMA key = 'testkey'; + PRAGMA kdf_iter = 4000; PRAGMA fast_kdf_iter = 4000; PRAGMA cipher_hmac_salt_mask = "x'00'"; SELECT count(*) FROM t1; - SELECT * FROM t1; + SELECT distinct * FROM t1; } -} {2 test-0-0 test-0-1 test-1-0 test-1-1} +} {38768 test-0-0 test-0-1 test-1-0 test-1-1} db close # open a 2.0 beta database @@ -1861,6 +2025,7 @@ do_test 2.0-beta-to-2.0-migration { execsql { PRAGMA key = 'testkey'; PRAGMA cipher_hmac_salt_mask = "x'00'"; + PRAGMA kdf_iter = 4000; PRAGMA fast_kdf_iter = 4000; SELECT count(*) FROM sqlite_master; @@ -1876,7 +2041,7 @@ do_test 2.0-beta-to-2.0-migration { sqlite_orig db test.db execsql { PRAGMA key = 'testkey'; - SELECT * FROM t1; + SELECT distinct * FROM t1; } } {test-0-0 test-0-1 test-1-0 test-1-1} db close @@ -1902,4 +2067,194 @@ if_built_with_commoncrypto verify-default-cipher { db close file delete -force test.db +do_test migrate-1.1.8-database-to-3x-format { + file copy -force sqlcipher-1.1.8-testkey.db test.db + sqlite_orig db test.db + execsql { + PRAGMA key = 'testkey'; + PRAGMA cipher_migrate; + } + db close + + sqlite_orig db test.db + execsql { + PRAGMA key = 'testkey'; + SELECT count(*) FROM sqlite_master; + } +} {1} +db close +file delete -force test.db + +do_test migrate-2-0-le-database-to-3x-format { + file copy -force sqlcipher-2.0-le-testkey.db test.db + sqlite_orig db test.db + execsql { + PRAGMA key = 'testkey'; + PRAGMA cipher_migrate; + } + db close + + sqlite_orig db test.db + execsql { + PRAGMA key = 'testkey'; + SELECT count(*) FROM sqlite_master; + } +} {1} +db close +file delete -force test.db + +do_test key-database-by-name { + sqlite_orig db test.db + execsql { + attach database 'new.db' as new; + pragma new.key = 'foo'; + create table new.t1(a,b); + insert into new.t1(a,b) values('foo', 'bar'); + detach database new; + } + db close + + sqlite_orig db new.db + execsql { + pragma key = 'foo'; + select * from t1; + } +} {foo bar} +db close +file delete -force test.db +file delete -force new.db + +do_test key-multiple-databases-with-different-keys-using-pragma { + sqlite_orig db test.db + execsql { + pragma key = 'foobar'; + create table t1(a,b); + insert into t1(a,b) values('baz','qux'); + attach database 'new.db' as new; + pragma new.key = 'foo'; + create table new.t1(a,b); + insert into new.t1(a,b) values('foo', 'bar'); + detach database new; + } + db close + + sqlite_orig db new.db + execsql { + pragma key = 'foo'; + attach database 'test.db' as test key 'foobar'; + select * from t1; + select * from test.t1; + } +} {foo bar baz qux} +db close +file delete -force test.db +file delete -force new.db + +do_test rekey-database-by-name { + sqlite_orig db test.db + execsql { + attach database 'new.db' as new; + pragma new.key = 'foo'; + create table new.t1(a,b); + insert into new.t1(a,b) values('foo', 'bar'); + pragma new.rekey = 'bar'; + detach database new; + } + db close + + sqlite_orig db new.db + execsql { + pragma key = 'bar'; + select * from t1; + } +} {foo bar} +db close +file delete -force test.db +file delete -force new.db + +# Requires SQLCipher to be built with -DSQLCIPHER_TEST +if_built_with_libtomcrypt verify-random-data-alters-file-content { + file delete -force test.db + file delete -force test2.db + file delete -force test3.db + set rc {} + + sqlite_orig db test.db + execsql { + PRAGMA key="x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'"; + create table t1(a,b); + } + db close + sqlite_orig db test2.db + execsql { + PRAGMA key="x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'"; + create table t1(a,b); + } + db close + sqlite_orig db test3.db + execsql { + PRAGMA key="x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'"; + PRAGMA cipher_add_random = "x'deadbaad'"; + create table t1(a,b); + } + db close + lappend rc [cmpFilesChunked test.db test2.db] + lappend rc [cmpFilesChunked test2.db test3.db] +} {0 1} +file delete -force test.db +file delete -force test2.db +file delete -force test3.db + +do_test can-migrate-with-keys-longer-than-64-characters { + sqlite_orig db test.db + execsql { + PRAGMA key = "012345678901234567890123456789012345678901234567890123456789012345"; + PRAGMA kdf_iter = 4000; + PRAGMA user_version = 5; + } + db close + + sqlite_orig db test.db + execsql { + PRAGMA key = "012345678901234567890123456789012345678901234567890123456789012345"; + PRAGMA cipher_migrate; + } + db close + + sqlite_orig db test.db + execsql { + PRAGMA key = "012345678901234567890123456789012345678901234567890123456789012345"; + PRAGMA user_version; + } +} {5} +db close +file delete -force test.db + +do_test can-migrate-with-raw-hex-key { + sqlite_orig db test.db + execsql { + PRAGMA key = "x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'"; + PRAGMA kdf_iter = 4000; + PRAGMA cipher_use_hmac = off; + PRAGMA user_version = 5; + } + db close + + sqlite_orig db test.db + execsql { + PRAGMA key = "x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'"; + PRAGMA cipher_migrate; + } + + sqlite_orig db test.db + execsql { + PRAGMA key = "x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'"; + PRAGMA user_version; + } + +} {5} +db close +file delete -force test.db + +sqlite3_test_control_pending_byte $old_pending_byte finish_test -- cgit v1.2.3