3 ** http://sqlcipher.net
5 ** Copyright (c) 2008 - 2013, ZETETIC LLC
6 ** All rights reserved.
8 ** Redistribution and use in source and binary forms, with or without
9 ** modification, are permitted provided that the following conditions are met:
10 ** * Redistributions of source code must retain the above copyright
11 ** notice, this list of conditions and the following disclaimer.
12 ** * Redistributions in binary form must reproduce the above copyright
13 ** notice, this list of conditions and the following disclaimer in the
14 ** documentation and/or other materials provided with the distribution.
15 ** * Neither the name of the ZETETIC LLC nor the
16 ** names of its contributors may be used to endorse or promote products
17 ** derived from this software without specific prior written permission.
19 ** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
20 ** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 ** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
23 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #ifdef SQLITE_HAS_CODEC
35 #include "sqliteInt.h"
39 static const char* codec_get_cipher_version() {
40 return CIPHER_VERSION
;
43 /* Generate code to return a string value */
44 static void codec_vdbe_return_static_string(Parse
*pParse
, const char *zLabel
, const char *value
){
45 Vdbe
*v
= sqlite3GetVdbe(pParse
);
46 sqlite3VdbeSetNumCols(v
, 1);
47 sqlite3VdbeSetColName(v
, 0, COLNAME_NAME
, zLabel
, SQLITE_STATIC
);
48 sqlite3VdbeAddOp4(v
, OP_String8
, 0, 1, 0, value
, 0);
49 sqlite3VdbeAddOp2(v
, OP_ResultRow
, 1, 1);
52 static int codec_set_btree_to_codec_pagesize(sqlite3
*db
, Db
*pDb
, codec_ctx
*ctx
) {
53 int rc
, page_sz
, reserve_sz
;
55 page_sz
= sqlcipher_codec_ctx_get_pagesize(ctx
);
56 reserve_sz
= sqlcipher_codec_ctx_get_reservesize(ctx
);
58 sqlite3_mutex_enter(db
->mutex
);
59 db
->nextPagesize
= page_sz
;
61 /* before forcing the page size we need to unset the BTS_PAGESIZE_FIXED flag, else
62 sqliteBtreeSetPageSize will block the change */
63 pDb
->pBt
->pBt
->btsFlags
&= ~BTS_PAGESIZE_FIXED
;
64 CODEC_TRACE(("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz
, reserve_sz
));
65 rc
= sqlite3BtreeSetPageSize(pDb
->pBt
, page_sz
, reserve_sz
, 0);
66 sqlite3_mutex_leave(db
->mutex
);
70 static int codec_set_pass_key(sqlite3
* db
, int nDb
, const void *zKey
, int nKey
, int for_ctx
) {
71 struct Db
*pDb
= &db
->aDb
[nDb
];
72 CODEC_TRACE(("codec_set_pass_key: entered db=%p nDb=%d zKey=%s nKey=%d for_ctx=%d\n", db
, nDb
, (char *)zKey
, nKey
, for_ctx
));
75 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
76 if(ctx
) return sqlcipher_codec_ctx_set_pass(ctx
, zKey
, nKey
, for_ctx
);
81 int sqlcipher_codec_pragma(sqlite3
* db
, int iDb
, Parse
*pParse
, const char *zLeft
, const char *zRight
) {
82 struct Db
*pDb
= &db
->aDb
[iDb
];
83 codec_ctx
*ctx
= NULL
;
87 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
90 CODEC_TRACE(("sqlcipher_codec_pragma: entered db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p\n", db
, iDb
, pParse
, zLeft
, zRight
, ctx
));
92 if( sqlite3StrICmp(zLeft
, "cipher_fips_status")== 0 && !zRight
){
94 char *fips_mode_status
= sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx
));
95 codec_vdbe_return_static_string(pParse
, "cipher_fips_status", fips_mode_status
);
96 sqlite3_free(fips_mode_status
);
99 if( sqlite3StrICmp(zLeft
, "cipher_store_pass")==0 && zRight
) {
101 sqlcipher_codec_set_store_pass(ctx
, sqlite3GetBoolean(zRight
, 1));
104 if( sqlite3StrICmp(zLeft
, "cipher_store_pass")==0 && !zRight
) {
106 char *store_pass_value
= sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx
));
107 codec_vdbe_return_static_string(pParse
, "cipher_store_pass", store_pass_value
);
108 sqlite3_free(store_pass_value
);
111 if( sqlite3StrICmp(zLeft
, "cipher_profile")== 0 && zRight
){
112 char *profile_status
= sqlite3_mprintf("%d", sqlcipher_cipher_profile(db
, zRight
));
113 codec_vdbe_return_static_string(pParse
, "cipher_profile", profile_status
);
114 sqlite3_free(profile_status
);
116 if( sqlite3StrICmp(zLeft
, "cipher_add_random")==0 && zRight
){
118 char *add_random_status
= sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx
, zRight
, sqlite3Strlen30(zRight
)));
119 codec_vdbe_return_static_string(pParse
, "cipher_add_random", add_random_status
);
120 sqlite3_free(add_random_status
);
123 if( sqlite3StrICmp(zLeft
, "cipher_migrate")==0 && !zRight
){
125 char *migrate_status
= sqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx
));
126 codec_vdbe_return_static_string(pParse
, "cipher_migrate", migrate_status
);
127 sqlite3_free(migrate_status
);
130 if( sqlite3StrICmp(zLeft
, "cipher_provider")==0 && !zRight
){
131 if(ctx
) { codec_vdbe_return_static_string(pParse
, "cipher_provider",
132 sqlcipher_codec_get_cipher_provider(ctx
));
135 if( sqlite3StrICmp(zLeft
, "cipher_provider_version")==0 && !zRight
){
136 if(ctx
) { codec_vdbe_return_static_string(pParse
, "cipher_provider_version",
137 sqlcipher_codec_get_provider_version(ctx
));
140 if( sqlite3StrICmp(zLeft
, "cipher_version")==0 && !zRight
){
141 codec_vdbe_return_static_string(pParse
, "cipher_version", codec_get_cipher_version());
143 if( sqlite3StrICmp(zLeft
, "cipher")==0 ){
146 sqlcipher_codec_ctx_set_cipher(ctx
, zRight
, 2); // change cipher for both
147 char *pragma_cipher_deprecated_msg
= "PRAGMA cipher command is deprecated, please remove from usage.";
148 codec_vdbe_return_static_string(pParse
, "cipher", pragma_cipher_deprecated_msg
);
149 sqlite3_log(SQLITE_WARNING
, pragma_cipher_deprecated_msg
);
152 codec_vdbe_return_static_string(pParse
, "cipher",
153 sqlcipher_codec_ctx_get_cipher(ctx
, 2));
157 if( sqlite3StrICmp(zLeft
, "rekey_cipher")==0 && zRight
){
158 if(ctx
) sqlcipher_codec_ctx_set_cipher(ctx
, zRight
, 1); // change write cipher only
160 if( sqlite3StrICmp(zLeft
,"cipher_default_kdf_iter")==0 ){
162 sqlcipher_set_default_kdf_iter(atoi(zRight
)); // change default KDF iterations
164 char *kdf_iter
= sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
165 codec_vdbe_return_static_string(pParse
, "cipher_default_kdf_iter", kdf_iter
);
166 sqlite3_free(kdf_iter
);
169 if( sqlite3StrICmp(zLeft
, "kdf_iter")==0 ){
172 sqlcipher_codec_ctx_set_kdf_iter(ctx
, atoi(zRight
), 2); // change of RW PBKDF2 iteration
174 char *kdf_iter
= sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx
, 2));
175 codec_vdbe_return_static_string(pParse
, "kdf_iter", kdf_iter
);
176 sqlite3_free(kdf_iter
);
180 if( sqlite3StrICmp(zLeft
, "fast_kdf_iter")==0){
183 sqlcipher_codec_ctx_set_fast_kdf_iter(ctx
, atoi(zRight
), 2); // change of RW PBKDF2 iteration
185 char *fast_kdf_iter
= sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx
, 2));
186 codec_vdbe_return_static_string(pParse
, "fast_kdf_iter", fast_kdf_iter
);
187 sqlite3_free(fast_kdf_iter
);
191 if( sqlite3StrICmp(zLeft
, "rekey_kdf_iter")==0 && zRight
){
192 if(ctx
) sqlcipher_codec_ctx_set_kdf_iter(ctx
, atoi(zRight
), 1); // write iterations only
194 if( sqlite3StrICmp(zLeft
,"cipher_page_size")==0 ){
197 int size
= atoi(zRight
);
198 rc
= sqlcipher_codec_ctx_set_pagesize(ctx
, size
);
199 if(rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, rc
);
200 rc
= codec_set_btree_to_codec_pagesize(db
, pDb
, ctx
);
201 if(rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, rc
);
203 char * page_size
= sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx
));
204 codec_vdbe_return_static_string(pParse
, "cipher_page_size", page_size
);
205 sqlite3_free(page_size
);
209 if( sqlite3StrICmp(zLeft
,"cipher_default_page_size")==0 ){
211 sqlcipher_set_default_pagesize(atoi(zRight
));
213 char *default_page_size
= sqlite3_mprintf("%d", sqlcipher_get_default_pagesize());
214 codec_vdbe_return_static_string(pParse
, "cipher_default_page_size", default_page_size
);
215 sqlite3_free(default_page_size
);
218 if( sqlite3StrICmp(zLeft
,"cipher_default_use_hmac")==0 ){
220 sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight
,1));
222 char *default_use_hmac
= sqlite3_mprintf("%d", sqlcipher_get_default_use_hmac());
223 codec_vdbe_return_static_string(pParse
, "cipher_default_use_hmac", default_use_hmac
);
224 sqlite3_free(default_use_hmac
);
227 if( sqlite3StrICmp(zLeft
,"cipher_use_hmac")==0 ){
230 rc
= sqlcipher_codec_ctx_set_use_hmac(ctx
, sqlite3GetBoolean(zRight
,1));
231 if(rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, rc
);
232 /* since the use of hmac has changed, the page size may also change */
233 rc
= codec_set_btree_to_codec_pagesize(db
, pDb
, ctx
);
234 if(rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, rc
);
236 char *hmac_flag
= sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_use_hmac(ctx
, 2));
237 codec_vdbe_return_static_string(pParse
, "cipher_use_hmac", hmac_flag
);
238 sqlite3_free(hmac_flag
);
242 if( sqlite3StrICmp(zLeft
,"cipher_hmac_pgno")==0 ){
245 // clear both pgno endian flags
246 if(sqlite3StrICmp(zRight
, "le") == 0) {
247 sqlcipher_codec_ctx_unset_flag(ctx
, CIPHER_FLAG_BE_PGNO
);
248 sqlcipher_codec_ctx_set_flag(ctx
, CIPHER_FLAG_LE_PGNO
);
249 } else if(sqlite3StrICmp(zRight
, "be") == 0) {
250 sqlcipher_codec_ctx_unset_flag(ctx
, CIPHER_FLAG_LE_PGNO
);
251 sqlcipher_codec_ctx_set_flag(ctx
, CIPHER_FLAG_BE_PGNO
);
252 } else if(sqlite3StrICmp(zRight
, "native") == 0) {
253 sqlcipher_codec_ctx_unset_flag(ctx
, CIPHER_FLAG_LE_PGNO
);
254 sqlcipher_codec_ctx_unset_flag(ctx
, CIPHER_FLAG_BE_PGNO
);
257 if(sqlcipher_codec_ctx_get_flag(ctx
, CIPHER_FLAG_LE_PGNO
, 2)) {
258 codec_vdbe_return_static_string(pParse
, "cipher_hmac_pgno", "le");
259 } else if(sqlcipher_codec_ctx_get_flag(ctx
, CIPHER_FLAG_BE_PGNO
, 2)) {
260 codec_vdbe_return_static_string(pParse
, "cipher_hmac_pgno", "be");
262 codec_vdbe_return_static_string(pParse
, "cipher_hmac_pgno", "native");
267 if( sqlite3StrICmp(zLeft
,"cipher_hmac_salt_mask")==0 ){
270 if (sqlite3StrNICmp(zRight
,"x'", 2) == 0 && sqlite3Strlen30(zRight
) == 5) {
271 unsigned char mask
= 0;
272 const unsigned char *hex
= (const unsigned char *)zRight
+2;
273 cipher_hex2bin(hex
,2,&mask
);
274 sqlcipher_set_hmac_salt_mask(mask
);
277 char *hmac_salt_mask
= sqlite3_mprintf("%02x", sqlcipher_get_hmac_salt_mask());
278 codec_vdbe_return_static_string(pParse
, "cipher_hmac_salt_mask", hmac_salt_mask
);
279 sqlite3_free(hmac_salt_mask
);
290 * sqlite3Codec can be called in multiple modes.
291 * encrypt mode - expected to return a pointer to the
292 * encrypted data without altering pData.
293 * decrypt mode - expected to return a pointer to pData, with
294 * the data decrypted in the input buffer
296 void* sqlite3Codec(void *iCtx
, void *data
, Pgno pgno
, int mode
) {
297 codec_ctx
*ctx
= (codec_ctx
*) iCtx
;
298 int offset
= 0, rc
= 0;
299 int page_sz
= sqlcipher_codec_ctx_get_pagesize(ctx
);
300 unsigned char *pData
= (unsigned char *) data
;
301 void *buffer
= sqlcipher_codec_ctx_get_data(ctx
);
302 void *kdf_salt
= sqlcipher_codec_ctx_get_kdf_salt(ctx
);
303 CODEC_TRACE(("sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d\n", pgno
, mode
, page_sz
));
305 /* call to derive keys if not present yet */
306 if((rc
= sqlcipher_codec_key_derive(ctx
)) != SQLITE_OK
) {
307 sqlcipher_codec_ctx_set_error(ctx
, rc
);
311 if(pgno
== 1) offset
= FILE_HEADER_SZ
; /* adjust starting pointers in data page for header offset on first page*/
313 CODEC_TRACE(("sqlite3Codec: switch mode=%d offset=%d\n", mode
, offset
));
315 case 0: /* decrypt */
318 if(pgno
== 1) memcpy(buffer
, SQLITE_FILE_HEADER
, FILE_HEADER_SZ
); /* copy file header to the first 16 bytes of the page */
319 rc
= sqlcipher_page_cipher(ctx
, CIPHER_READ_CTX
, pgno
, CIPHER_DECRYPT
, page_sz
- offset
, pData
+ offset
, (unsigned char*)buffer
+ offset
);
320 if(rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, rc
);
321 memcpy(pData
, buffer
, page_sz
); /* copy buffer data back to pData and return */
324 case 6: /* encrypt */
325 if(pgno
== 1) memcpy(buffer
, kdf_salt
, FILE_HEADER_SZ
); /* copy salt to output buffer */
326 rc
= sqlcipher_page_cipher(ctx
, CIPHER_WRITE_CTX
, pgno
, CIPHER_ENCRYPT
, page_sz
- offset
, pData
+ offset
, (unsigned char*)buffer
+ offset
);
327 if(rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, rc
);
328 return buffer
; /* return persistent buffer data, pData remains intact */
331 if(pgno
== 1) memcpy(buffer
, kdf_salt
, FILE_HEADER_SZ
); /* copy salt to output buffer */
332 rc
= sqlcipher_page_cipher(ctx
, CIPHER_READ_CTX
, pgno
, CIPHER_ENCRYPT
, page_sz
- offset
, pData
+ offset
, (unsigned char*)buffer
+ offset
);
333 if(rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, rc
);
334 return buffer
; /* return persistent buffer data, pData remains intact */
342 void sqlite3FreeCodecArg(void *pCodecArg
) {
343 codec_ctx
*ctx
= (codec_ctx
*) pCodecArg
;
344 if(pCodecArg
== NULL
) return;
345 sqlcipher_codec_ctx_free(&ctx
); // wipe and free allocated memory for the context
346 sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */
349 int sqlite3CodecAttach(sqlite3
* db
, int nDb
, const void *zKey
, int nKey
) {
350 struct Db
*pDb
= &db
->aDb
[nDb
];
352 CODEC_TRACE(("sqlite3CodecAttach: entered nDb=%d zKey=%s, nKey=%d\n", nDb
, (char *)zKey
, nKey
));
355 if(nKey
&& zKey
&& pDb
->pBt
) {
357 Pager
*pPager
= pDb
->pBt
->pBt
->pPager
;
358 sqlite3_file
*fd
= sqlite3Pager_get_fd(pPager
);
361 sqlcipher_activate(); /* perform internal initialization for sqlcipher */
363 sqlite3_mutex_enter(db
->mutex
);
365 /* point the internal codec argument against the contet to be prepared */
366 rc
= sqlcipher_codec_ctx_init(&ctx
, pDb
, pDb
->pBt
->pBt
->pPager
, fd
, zKey
, nKey
);
368 if(rc
!= SQLITE_OK
) {
369 /* initialization failed, do not attach potentially corrupted context */
370 sqlite3_mutex_leave(db
->mutex
);
374 sqlite3pager_sqlite3PagerSetCodec(sqlite3BtreePager(pDb
->pBt
), sqlite3Codec
, NULL
, sqlite3FreeCodecArg
, (void *) ctx
);
376 codec_set_btree_to_codec_pagesize(db
, pDb
, ctx
);
378 /* force secure delete. This has the benefit of wiping internal data when deleted
379 and also ensures that all pages are written to disk (i.e. not skipped by
380 sqlite3PagerDontWrite optimizations) */
381 sqlite3BtreeSecureDelete(pDb
->pBt
, 1);
383 /* if fd is null, then this is an in-memory database and
384 we dont' want to overwrite the AutoVacuum settings
385 if not null, then set to the default */
387 sqlite3BtreeSetAutoVacuum(pDb
->pBt
, SQLITE_DEFAULT_AUTOVACUUM
);
389 sqlite3_mutex_leave(db
->mutex
);
394 void sqlite3_activate_see(const char* in
) {
395 /* do nothing, security enhancements are always active */
398 static int sqlcipher_find_db_index(sqlite3
*db
, const char *zDb
) {
403 for(db_index
= 0; db_index
< db
->nDb
; db_index
++) {
404 struct Db
*pDb
= &db
->aDb
[db_index
];
405 if(strcmp(pDb
->zName
, zDb
) == 0) {
412 int sqlite3_key(sqlite3
*db
, const void *pKey
, int nKey
) {
413 CODEC_TRACE(("sqlite3_key entered: db=%p pKey=%s nKey=%d\n", db
, (char *)pKey
, nKey
));
414 return sqlite3_key_v2(db
, "main", pKey
, nKey
);
417 int sqlite3_key_v2(sqlite3
*db
, const char *zDb
, const void *pKey
, int nKey
) {
418 CODEC_TRACE(("sqlite3_key_v2: entered db=%p zDb=%s pKey=%s nKey=%d\n", db
, zDb
, (char *)pKey
, nKey
));
419 /* attach key if db and pKey are not null and nKey is > 0 */
420 if(db
&& pKey
&& nKey
) {
421 int db_index
= sqlcipher_find_db_index(db
, zDb
);
422 return sqlite3CodecAttach(db
, db_index
, pKey
, nKey
);
427 int sqlite3_rekey(sqlite3
*db
, const void *pKey
, int nKey
) {
428 CODEC_TRACE(("sqlite3_rekey entered: db=%p pKey=%s nKey=%d\n", db
, (char *)pKey
, nKey
));
429 return sqlite3_rekey_v2(db
, "main", pKey
, nKey
);
433 ** Given a database, this will reencrypt the database using a new key.
434 ** There is only one possible modes of operation - to encrypt a database
435 ** that is already encrpyted. If the database is not already encrypted
436 ** this should do nothing
437 ** The proposed logic for this function follows:
438 ** 1. Determine if the database is already encryptped
439 ** 2. If there is NOT already a key present do nothing
440 ** 3. If there is a key present, re-encrypt the database with the new key
442 int sqlite3_rekey_v2(sqlite3
*db
, const char *zDb
, const void *pKey
, int nKey
) {
443 CODEC_TRACE(("sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%s, nKey=%d\n", db
, zDb
, (char *)pKey
, nKey
));
444 if(db
&& pKey
&& nKey
) {
445 int db_index
= sqlcipher_find_db_index(db
, zDb
);
446 struct Db
*pDb
= &db
->aDb
[db_index
];
447 CODEC_TRACE(("sqlite3_rekey_v2: database pDb=%p db_index:%d\n", pDb
, db_index
));
453 Pager
*pPager
= pDb
->pBt
->pBt
->pPager
;
455 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
458 /* there was no codec attached to this database, so this should do nothing! */
459 CODEC_TRACE(("sqlite3_rekey_v2: no codec attached to db, exiting\n"));
463 sqlite3_mutex_enter(db
->mutex
);
465 codec_set_pass_key(db
, db_index
, pKey
, nKey
, CIPHER_WRITE_CTX
);
467 /* do stuff here to rewrite the database
468 ** 1. Create a transaction on the database
469 ** 2. Iterate through each page, reading it and then writing it.
470 ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
471 ** note: don't deallocate rekey since it may be used in a subsequent iteration
473 rc
= sqlite3BtreeBeginTrans(pDb
->pBt
, 1); /* begin write transaction */
474 sqlite3PagerPagecount(pPager
, &page_count
);
475 for(pgno
= 1; rc
== SQLITE_OK
&& pgno
<= (unsigned int)page_count
; pgno
++) { /* pgno's start at 1 see pager.c:pagerAcquire */
476 if(!sqlite3pager_is_mj_pgno(pPager
, pgno
)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */
477 rc
= sqlite3PagerGet(pPager
, pgno
, &page
, 0);
478 if(rc
== SQLITE_OK
) { /* write page see pager_incr_changecounter for example */
479 rc
= sqlite3PagerWrite(page
);
480 if(rc
== SQLITE_OK
) {
481 sqlite3PagerUnref(page
);
483 CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred writing page %d\n", rc
, pgno
));
486 CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred getting page %d\n", rc
, pgno
));
491 /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */
492 if(rc
== SQLITE_OK
) {
493 CODEC_TRACE(("sqlite3_rekey_v2: committing\n"));
494 rc
= sqlite3BtreeCommit(pDb
->pBt
);
495 sqlcipher_codec_key_copy(ctx
, CIPHER_WRITE_CTX
);
497 CODEC_TRACE(("sqlite3_rekey_v2: rollback\n"));
498 sqlite3BtreeRollback(pDb
->pBt
, SQLITE_ABORT_ROLLBACK
, 0);
501 sqlite3_mutex_leave(db
->mutex
);
508 void sqlite3CodecGetKey(sqlite3
* db
, int nDb
, void **zKey
, int *nKey
) {
509 struct Db
*pDb
= &db
->aDb
[nDb
];
510 CODEC_TRACE(("sqlite3CodecGetKey: entered db=%p, nDb=%d\n", db
, nDb
));
513 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
515 if(sqlcipher_codec_get_store_pass(ctx
) == 1) {
516 sqlcipher_codec_get_pass(ctx
, zKey
, nKey
);
518 sqlcipher_codec_get_keyspec(ctx
, zKey
, nKey
);
530 * Implementation of an "export" function that allows a caller
531 * to duplicate the main database to an attached database. This is intended
532 * as a conveneince for users who need to:
534 * 1. migrate from an non-encrypted database to an encrypted database
535 * 2. move from an encrypted database to a non-encrypted database
536 * 3. convert beween the various flavors of encrypted databases.
538 * This implementation is based heavily on the procedure and code used
539 * in vacuum.c, but is exposed as a function that allows export to any
540 * named attached database.
544 ** Finalize a prepared statement. If there was an error, store the
545 ** text of the error message in *pzErrMsg. Return the result code.
547 ** Based on vacuumFinalize from vacuum.c
549 static int sqlcipher_finalize(sqlite3
*db
, sqlite3_stmt
*pStmt
, char **pzErrMsg
){
551 rc
= sqlite3VdbeFinalize((Vdbe
*)pStmt
);
553 sqlite3SetString(pzErrMsg
, db
, sqlite3_errmsg(db
));
559 ** Execute zSql on database db. Return an error code.
561 ** Based on execSql from vacuum.c
563 static int sqlcipher_execSql(sqlite3
*db
, char **pzErrMsg
, const char *zSql
){
569 if( SQLITE_OK
!=sqlite3_prepare(db
, zSql
, -1, &pStmt
, 0) ){
570 sqlite3SetString(pzErrMsg
, db
, sqlite3_errmsg(db
));
571 return sqlite3_errcode(db
);
573 VVA_ONLY( rc
= ) sqlite3_step(pStmt
);
574 assert( rc
!=SQLITE_ROW
);
575 return sqlcipher_finalize(db
, pStmt
, pzErrMsg
);
579 ** Execute zSql on database db. The statement returns exactly
580 ** one column. Execute this as SQL on the same database.
582 ** Based on execExecSql from vacuum.c
584 static int sqlcipher_execExecSql(sqlite3
*db
, char **pzErrMsg
, const char *zSql
){
588 rc
= sqlite3_prepare(db
, zSql
, -1, &pStmt
, 0);
589 if( rc
!=SQLITE_OK
) return rc
;
591 while( SQLITE_ROW
==sqlite3_step(pStmt
) ){
592 rc
= sqlcipher_execSql(db
, pzErrMsg
, (char*)sqlite3_column_text(pStmt
, 0));
594 sqlcipher_finalize(db
, pStmt
, pzErrMsg
);
599 return sqlcipher_finalize(db
, pStmt
, pzErrMsg
);
603 * copy database and schema from the main database to an attached database
605 * Based on sqlite3RunVacuum from vacuum.c
607 void sqlcipher_exportFunc(sqlite3_context
*context
, int argc
, sqlite3_value
**argv
) {
608 sqlite3
*db
= sqlite3_context_db_handle(context
);
609 const char* attachedDb
= (const char*) sqlite3_value_text(argv
[0]);
610 int saved_flags
; /* Saved value of the db->flags */
611 int saved_nChange
; /* Saved value of db->nChange */
612 int saved_nTotalChange
; /* Saved value of db->nTotalChange */
613 void (*saved_xTrace
)(void*,const char*); /* Saved db->xTrace */
614 int rc
= SQLITE_OK
; /* Return code from service routines */
615 char *zSql
= NULL
; /* SQL statements */
616 char *pzErrMsg
= NULL
;
618 saved_flags
= db
->flags
;
619 saved_nChange
= db
->nChange
;
620 saved_nTotalChange
= db
->nTotalChange
;
621 saved_xTrace
= db
->xTrace
;
622 db
->flags
|= SQLITE_WriteSchema
| SQLITE_IgnoreChecks
| SQLITE_PreferBuiltin
;
623 db
->flags
&= ~(SQLITE_ForeignKeys
| SQLITE_ReverseOrder
);
626 /* Query the schema of the main database. Create a mirror schema
627 ** in the temporary database.
629 zSql
= sqlite3_mprintf(
630 "SELECT 'CREATE TABLE %s.' || substr(sql,14) "
631 " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
634 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
635 if( rc
!=SQLITE_OK
) goto end_of_export
;
638 zSql
= sqlite3_mprintf(
639 "SELECT 'CREATE INDEX %s.' || substr(sql,14)"
640 " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %%' "
642 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
643 if( rc
!=SQLITE_OK
) goto end_of_export
;
646 zSql
= sqlite3_mprintf(
647 "SELECT 'CREATE UNIQUE INDEX %s.' || substr(sql,21) "
648 " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
650 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
651 if( rc
!=SQLITE_OK
) goto end_of_export
;
654 /* Loop through the tables in the main database. For each, do
655 ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy
656 ** the contents to the temporary database.
658 zSql
= sqlite3_mprintf(
659 "SELECT 'INSERT INTO %s.' || quote(name) "
660 "|| ' SELECT * FROM main.' || quote(name) || ';'"
661 "FROM main.sqlite_master "
662 "WHERE type = 'table' AND name!='sqlite_sequence' "
665 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
666 if( rc
!=SQLITE_OK
) goto end_of_export
;
669 /* Copy over the sequence table
671 zSql
= sqlite3_mprintf(
672 "SELECT 'DELETE FROM %s.' || quote(name) || ';' "
673 "FROM %s.sqlite_master WHERE name='sqlite_sequence' "
674 , attachedDb
, attachedDb
);
675 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
676 if( rc
!=SQLITE_OK
) goto end_of_export
;
679 zSql
= sqlite3_mprintf(
680 "SELECT 'INSERT INTO %s.' || quote(name) "
681 "|| ' SELECT * FROM main.' || quote(name) || ';' "
682 "FROM %s.sqlite_master WHERE name=='sqlite_sequence';"
683 , attachedDb
, attachedDb
);
684 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
685 if( rc
!=SQLITE_OK
) goto end_of_export
;
688 /* Copy the triggers, views, and virtual tables from the main database
689 ** over to the temporary database. None of these objects has any
690 ** associated storage, so all we have to do is copy their entries
691 ** from the SQLITE_MASTER table.
693 zSql
= sqlite3_mprintf(
694 "INSERT INTO %s.sqlite_master "
695 " SELECT type, name, tbl_name, rootpage, sql"
696 " FROM main.sqlite_master"
697 " WHERE type='view' OR type='trigger'"
698 " OR (type='table' AND rootpage=0)"
700 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execSql(db
, &pzErrMsg
, zSql
);
701 if( rc
!=SQLITE_OK
) goto end_of_export
;
706 db
->flags
= saved_flags
;
707 db
->nChange
= saved_nChange
;
708 db
->nTotalChange
= saved_nTotalChange
;
709 db
->xTrace
= saved_xTrace
;
714 if(pzErrMsg
!= NULL
) {
715 sqlite3_result_error(context
, pzErrMsg
, -1);
716 sqlite3DbFree(db
, pzErrMsg
);
718 sqlite3_result_error(context
, sqlite3ErrStr(rc
), -1);