Prevent deadlock of database mutex
[sqlcipher.git] / src / crypto.c
blob2241fb84b606a873a5cbf55dbd0ec75ec49b19d2
1 /*
2 ** SQLCipher
3 ** http://sqlcipher.net
4 **
5 ** Copyright (c) 2008 - 2013, ZETETIC LLC
6 ** All rights reserved.
7 **
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.
18 **
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.
29 **
31 /* BEGIN SQLCIPHER */
32 #ifdef SQLITE_HAS_CODEC
34 #include <assert.h>
35 #include "sqliteInt.h"
36 #include "btreeInt.h"
37 #include "crypto.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);
67 return rc;
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));
73 if(pDb->pBt) {
74 codec_ctx *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);
78 return SQLITE_ERROR;
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;
84 int rc;
86 if(pDb->pBt) {
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 ){
93 if(ctx) {
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);
98 } else
99 if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && zRight ) {
100 if(ctx) {
101 sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
103 } else
104 if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
105 if(ctx){
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);
115 } else
116 if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){
117 if(ctx) {
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);
122 } else
123 if( sqlite3StrICmp(zLeft, "cipher_migrate")==0 && !zRight ){
124 if(ctx){
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);
129 } else
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));
134 } else
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));
139 } else
140 if( sqlite3StrICmp(zLeft, "cipher_version")==0 && !zRight ){
141 codec_vdbe_return_static_string(pParse, "cipher_version", codec_get_cipher_version());
142 }else
143 if( sqlite3StrICmp(zLeft, "cipher")==0 ){
144 if(ctx) {
145 if( zRight ) {
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);
150 return SQLITE_ERROR;
151 }else {
152 codec_vdbe_return_static_string(pParse, "cipher",
153 sqlcipher_codec_ctx_get_cipher(ctx, 2));
156 }else
157 if( sqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){
158 if(ctx) sqlcipher_codec_ctx_set_cipher(ctx, zRight, 1); // change write cipher only
159 }else
160 if( sqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){
161 if( zRight ) {
162 sqlcipher_set_default_kdf_iter(atoi(zRight)); // change default KDF iterations
163 } else {
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);
168 }else
169 if( sqlite3StrICmp(zLeft, "kdf_iter")==0 ){
170 if(ctx) {
171 if( zRight ) {
172 sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration
173 } else {
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);
179 }else
180 if( sqlite3StrICmp(zLeft, "fast_kdf_iter")==0){
181 if(ctx) {
182 if( zRight ) {
183 sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration
184 } else {
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);
190 }else
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
193 }else
194 if( sqlite3StrICmp(zLeft,"cipher_page_size")==0 ){
195 if(ctx) {
196 if( zRight ) {
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);
202 } else {
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);
208 }else
209 if( sqlite3StrICmp(zLeft,"cipher_default_page_size")==0 ){
210 if( zRight ) {
211 sqlcipher_set_default_pagesize(atoi(zRight));
212 } else {
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);
217 }else
218 if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){
219 if( zRight ) {
220 sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));
221 } else {
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);
226 }else
227 if( sqlite3StrICmp(zLeft,"cipher_use_hmac")==0 ){
228 if(ctx) {
229 if( zRight ) {
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);
235 } else {
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);
241 }else
242 if( sqlite3StrICmp(zLeft,"cipher_hmac_pgno")==0 ){
243 if(ctx) {
244 if(zRight) {
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);
256 } else {
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");
261 } else {
262 codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "native");
266 }else
267 if( sqlite3StrICmp(zLeft,"cipher_hmac_salt_mask")==0 ){
268 if(ctx) {
269 if(zRight) {
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);
276 } else {
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);
282 }else {
283 return 0;
285 return 1;
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);
308 return NULL;
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));
314 switch(mode) {
315 case 0: /* decrypt */
316 case 2:
317 case 3:
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 */
322 return pData;
323 break;
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 */
329 break;
330 case 7:
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 */
335 break;
336 default:
337 return pData;
338 break;
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) {
356 int rc;
357 Pager *pPager = pDb->pBt->pBt->pPager;
358 sqlite3_file *fd = sqlite3Pager_get_fd(pPager);
359 codec_ctx *ctx;
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);
371 return rc;
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 */
386 if(fd != NULL) {
387 sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
389 sqlite3_mutex_leave(db->mutex);
391 return SQLITE_OK;
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) {
399 int db_index;
400 if(zDb == NULL){
401 return 0;
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) {
406 return db_index;
409 return 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);
424 return SQLITE_ERROR;
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);
432 /* sqlite3_rekey_v2
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));
448 if(pDb->pBt) {
449 codec_ctx *ctx;
450 int rc, page_count;
451 Pgno pgno;
452 PgHdr *page;
453 Pager *pPager = pDb->pBt->pBt->pPager;
455 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
457 if(ctx == NULL) {
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"));
460 return SQLITE_OK;
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);
482 } else {
483 CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred writing page %d\n", rc, pgno));
485 } else {
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);
496 } else {
497 CODEC_TRACE(("sqlite3_rekey_v2: rollback\n"));
498 sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0);
501 sqlite3_mutex_leave(db->mutex);
503 return SQLITE_OK;
505 return SQLITE_ERROR;
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));
511 if( pDb->pBt ) {
512 codec_ctx *ctx;
513 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
514 if(ctx) {
515 if(sqlcipher_codec_get_store_pass(ctx) == 1) {
516 sqlcipher_codec_get_pass(ctx, zKey, nKey);
517 } else {
518 sqlcipher_codec_get_keyspec(ctx, zKey, nKey);
520 } else {
521 *zKey = NULL;
522 *nKey = 0;
527 #ifndef OMIT_EXPORT
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){
550 int rc;
551 rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
552 if( rc ){
553 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
555 return rc;
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){
564 sqlite3_stmt *pStmt;
565 VVA_ONLY( int rc; )
566 if( !zSql ){
567 return SQLITE_NOMEM;
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){
585 sqlite3_stmt *pStmt;
586 int rc;
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));
593 if( rc!=SQLITE_OK ){
594 sqlcipher_finalize(db, pStmt, pzErrMsg);
595 return rc;
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);
624 db->xTrace = 0;
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'"
632 " AND rootpage>0"
633 , attachedDb);
634 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
635 if( rc!=SQLITE_OK ) goto end_of_export;
636 sqlite3_free(zSql);
638 zSql = sqlite3_mprintf(
639 "SELECT 'CREATE INDEX %s.' || substr(sql,14)"
640 " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %%' "
641 , attachedDb);
642 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
643 if( rc!=SQLITE_OK ) goto end_of_export;
644 sqlite3_free(zSql);
646 zSql = sqlite3_mprintf(
647 "SELECT 'CREATE UNIQUE INDEX %s.' || substr(sql,21) "
648 " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
649 , attachedDb);
650 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
651 if( rc!=SQLITE_OK ) goto end_of_export;
652 sqlite3_free(zSql);
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' "
663 " AND rootpage>0"
664 , attachedDb);
665 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
666 if( rc!=SQLITE_OK ) goto end_of_export;
667 sqlite3_free(zSql);
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;
677 sqlite3_free(zSql);
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;
686 sqlite3_free(zSql);
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)"
699 , attachedDb);
700 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execSql(db, &pzErrMsg, zSql);
701 if( rc!=SQLITE_OK ) goto end_of_export;
702 sqlite3_free(zSql);
704 zSql = NULL;
705 end_of_export:
706 db->flags = saved_flags;
707 db->nChange = saved_nChange;
708 db->nTotalChange = saved_nTotalChange;
709 db->xTrace = saved_xTrace;
711 sqlite3_free(zSql);
713 if(rc) {
714 if(pzErrMsg != NULL) {
715 sqlite3_result_error(context, pzErrMsg, -1);
716 sqlite3DbFree(db, pzErrMsg);
717 } else {
718 sqlite3_result_error(context, sqlite3ErrStr(rc), -1);
723 #endif
725 /* END SQLCIPHER */
726 #endif