From 48ae31693ab371b441f802017e442a906e02586c Mon Sep 17 00:00:00 2001 From: Stephen Lombardo Date: Wed, 16 Aug 2023 14:52:46 -0400 Subject: [PATCH] raise error when trying to rekey unencrypted database, or use an empty key --- src/crypto.c | 2 +- src/pragma.c | 6 +++++ test/sqlcipher-core.test | 13 ++++++++++ test/sqlcipher-rekey.test | 64 +++++------------------------------------------ 4 files changed, 26 insertions(+), 59 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index bdbb2202..9c722fd4 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -971,7 +971,7 @@ int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) { if(ctx == NULL) { /* there was no codec attached to this database, so this should do nothing! */ sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3_rekey_v2: no codec attached to db, exiting"); - return SQLITE_OK; + return SQLITE_MISUSE; } sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3_rekey_v2: entering database mutex %p", db->mutex); diff --git a/src/pragma.c b/src/pragma.c index 27797f62..769bdd0f 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -2621,6 +2621,12 @@ void sqlite3Pragma( sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC); returnSingleText(v, "ok"); + } else { + sqlite3ErrorMsg(pParse, "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."); + goto pragma_out; } } break; diff --git a/test/sqlcipher-core.test b/test/sqlcipher-core.test index 573c2a55..5aed9fb6 100644 --- a/test/sqlcipher-core.test +++ b/test/sqlcipher-core.test @@ -877,6 +877,19 @@ do_test test_flags_combo { } {0 5 0} db close +# test empty key +# it should raise an error +do_test empty-key { + sqlite_orig db test.db + + catchsql { + PRAGMA key = ''; + } + +} {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.}} +db close +file delete -force test.db + # configure URI filename support # create a new encrypted database with the key via parameter # close database diff --git a/test/sqlcipher-rekey.test b/test/sqlcipher-rekey.test index 2e6534e3..267b8907 100644 --- a/test/sqlcipher-rekey.test +++ b/test/sqlcipher-rekey.test @@ -38,72 +38,20 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/sqlcipher.tcl -# Test rekey as first operation on an empty database. should be a no-op -do_test rekey-as-first-op { +# Test rekey as first operation on an empty database +# it should raise an error +do_test rekey-as-first-op-on-empty { sqlite_orig db test.db - execsql { + catchsql { PRAGMA rekey = 'testkey'; - CREATE table t1(a,b); - BEGIN; - } - - for {set i 1} {$i<=100} {incr i} { - set r [expr {int(rand()*500000)}] - execsql "INSERT INTO t1 VALUES($i,'value $r');" } - execsql { - COMMIT; - } - - db close - sqlite_orig db test.db - - execsql { - PRAGMA rekey = 'testkey'; - SELECT count(*) FROM t1; - } - -} {ok 100} +} {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.}} db close file delete -force test.db -# Test rekey as first operation follwed by key -do_test rekey-then-key-as-first-ops { - sqlite_orig db test.db - - execsql { - PRAGMA rekey = '1234'; - PRAGMA key = 'testkey'; - CREATE table t1(a,b); - BEGIN; - } - - for {set i 1} {$i<=100} {incr i} { - set r [expr {int(rand()*500000)}] - execsql "INSERT INTO t1 VALUES($i,'value $r');" - } - - execsql { - COMMIT; - } - - db close - sqlite_orig db test.db - - execsql { - PRAGMA rekey = '4321'; - PRAGMA key = 'testkey'; - SELECT count(*) FROM t1; - } - -} {ok ok 100} -db close -file delete -force test.db - - -# test a rekey operation as the first op on a database +# test a rekey operation as the first op on an existing database # then test that now the new key opens the database # now close database re-open with new key setup test.db "'testkey'" -- 2.11.4.GIT