Move declaration to top level of block
[sqlcipher.git] / src / crypto.c
blobc8941f7ac1f5950d386ce162839e902a8dba3dff
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 char *pragma_cipher_deprecated_msg = "PRAGMA cipher command is deprecated, please remove from usage.";
83 struct Db *pDb = &db->aDb[iDb];
84 codec_ctx *ctx = NULL;
85 int rc;
87 if(pDb->pBt) {
88 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
91 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));
93 if( sqlite3StrICmp(zLeft, "cipher_fips_status")== 0 && !zRight ){
94 if(ctx) {
95 char *fips_mode_status = sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx));
96 codec_vdbe_return_static_string(pParse, "cipher_fips_status", fips_mode_status);
97 sqlite3_free(fips_mode_status);
99 } else
100 if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && zRight ) {
101 if(ctx) {
102 sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
104 } else
105 if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
106 if(ctx){
107 char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
108 codec_vdbe_return_static_string(pParse, "cipher_store_pass", store_pass_value);
109 sqlite3_free(store_pass_value);
112 if( sqlite3StrICmp(zLeft, "cipher_profile")== 0 && zRight ){
113 char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight));
114 codec_vdbe_return_static_string(pParse, "cipher_profile", profile_status);
115 sqlite3_free(profile_status);
116 } else
117 if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){
118 if(ctx) {
119 char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, sqlite3Strlen30(zRight)));
120 codec_vdbe_return_static_string(pParse, "cipher_add_random", add_random_status);
121 sqlite3_free(add_random_status);
123 } else
124 if( sqlite3StrICmp(zLeft, "cipher_migrate")==0 && !zRight ){
125 if(ctx){
126 char *migrate_status = sqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx));
127 codec_vdbe_return_static_string(pParse, "cipher_migrate", migrate_status);
128 sqlite3_free(migrate_status);
130 } else
131 if( sqlite3StrICmp(zLeft, "cipher_provider")==0 && !zRight ){
132 if(ctx) { codec_vdbe_return_static_string(pParse, "cipher_provider",
133 sqlcipher_codec_get_cipher_provider(ctx));
135 } else
136 if( sqlite3StrICmp(zLeft, "cipher_provider_version")==0 && !zRight){
137 if(ctx) { codec_vdbe_return_static_string(pParse, "cipher_provider_version",
138 sqlcipher_codec_get_provider_version(ctx));
140 } else
141 if( sqlite3StrICmp(zLeft, "cipher_version")==0 && !zRight ){
142 codec_vdbe_return_static_string(pParse, "cipher_version", codec_get_cipher_version());
143 }else
144 if( sqlite3StrICmp(zLeft, "cipher")==0 ){
145 if(ctx) {
146 if( zRight ) {
147 sqlcipher_codec_ctx_set_cipher(ctx, zRight, 2); // change cipher for both
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) return rc; /* initialization failed, do not attach potentially corrupted context */
370 sqlite3pager_sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);
372 codec_set_btree_to_codec_pagesize(db, pDb, ctx);
374 /* force secure delete. This has the benefit of wiping internal data when deleted
375 and also ensures that all pages are written to disk (i.e. not skipped by
376 sqlite3PagerDontWrite optimizations) */
377 sqlite3BtreeSecureDelete(pDb->pBt, 1);
379 /* if fd is null, then this is an in-memory database and
380 we dont' want to overwrite the AutoVacuum settings
381 if not null, then set to the default */
382 if(fd != NULL) {
383 sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
385 sqlite3_mutex_leave(db->mutex);
387 return SQLITE_OK;
390 void sqlite3_activate_see(const char* in) {
391 /* do nothing, security enhancements are always active */
394 static int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) {
395 int db_index;
396 if(zDb == NULL){
397 return 0;
399 for(db_index = 0; db_index < db->nDb; db_index++) {
400 struct Db *pDb = &db->aDb[db_index];
401 if(strcmp(pDb->zName, zDb) == 0) {
402 return db_index;
405 return 0;
408 int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
409 CODEC_TRACE(("sqlite3_key entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey));
410 return sqlite3_key_v2(db, "main", pKey, nKey);
413 int sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
414 CODEC_TRACE(("sqlite3_key_v2: entered db=%p zDb=%s pKey=%s nKey=%d\n", db, zDb, (char *)pKey, nKey));
415 /* attach key if db and pKey are not null and nKey is > 0 */
416 if(db && pKey && nKey) {
417 int db_index = sqlcipher_find_db_index(db, zDb);
418 return sqlite3CodecAttach(db, db_index, pKey, nKey);
420 return SQLITE_ERROR;
423 int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
424 CODEC_TRACE(("sqlite3_rekey entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey));
425 return sqlite3_rekey_v2(db, "main", pKey, nKey);
428 /* sqlite3_rekey_v2
429 ** Given a database, this will reencrypt the database using a new key.
430 ** There is only one possible modes of operation - to encrypt a database
431 ** that is already encrpyted. If the database is not already encrypted
432 ** this should do nothing
433 ** The proposed logic for this function follows:
434 ** 1. Determine if the database is already encryptped
435 ** 2. If there is NOT already a key present do nothing
436 ** 3. If there is a key present, re-encrypt the database with the new key
438 int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
439 CODEC_TRACE(("sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%s, nKey=%d\n", db, zDb, (char *)pKey, nKey));
440 if(db && pKey && nKey) {
441 int db_index = sqlcipher_find_db_index(db, zDb);
442 struct Db *pDb = &db->aDb[db_index];
443 CODEC_TRACE(("sqlite3_rekey_v2: database pDb=%p db_index:%d\n", pDb, db_index));
444 if(pDb->pBt) {
445 codec_ctx *ctx;
446 int rc, page_count;
447 Pgno pgno;
448 PgHdr *page;
449 Pager *pPager = pDb->pBt->pBt->pPager;
451 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
453 if(ctx == NULL) {
454 /* there was no codec attached to this database, so this should do nothing! */
455 CODEC_TRACE(("sqlite3_rekey_v2: no codec attached to db, exiting\n"));
456 return SQLITE_OK;
459 sqlite3_mutex_enter(db->mutex);
461 codec_set_pass_key(db, db_index, pKey, nKey, CIPHER_WRITE_CTX);
463 /* do stuff here to rewrite the database
464 ** 1. Create a transaction on the database
465 ** 2. Iterate through each page, reading it and then writing it.
466 ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
467 ** note: don't deallocate rekey since it may be used in a subsequent iteration
469 rc = sqlite3BtreeBeginTrans(pDb->pBt, 1); /* begin write transaction */
470 sqlite3PagerPagecount(pPager, &page_count);
471 for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */
472 if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */
473 rc = sqlite3PagerGet(pPager, pgno, &page, 0);
474 if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
475 rc = sqlite3PagerWrite(page);
476 if(rc == SQLITE_OK) {
477 sqlite3PagerUnref(page);
478 } else {
479 CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred writing page %d\n", rc, pgno));
481 } else {
482 CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred getting page %d\n", rc, pgno));
487 /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */
488 if(rc == SQLITE_OK) {
489 CODEC_TRACE(("sqlite3_rekey_v2: committing\n"));
490 rc = sqlite3BtreeCommit(pDb->pBt);
491 sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
492 } else {
493 CODEC_TRACE(("sqlite3_rekey_v2: rollback\n"));
494 sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0);
497 sqlite3_mutex_leave(db->mutex);
499 return SQLITE_OK;
501 return SQLITE_ERROR;
504 void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) {
505 struct Db *pDb = &db->aDb[nDb];
506 CODEC_TRACE(("sqlite3CodecGetKey: entered db=%p, nDb=%d\n", db, nDb));
507 if( pDb->pBt ) {
508 codec_ctx *ctx;
509 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
510 if(ctx) {
511 if(sqlcipher_codec_get_store_pass(ctx) == 1) {
512 sqlcipher_codec_get_pass(ctx, zKey, nKey);
513 } else {
514 sqlcipher_codec_get_keyspec(ctx, zKey, nKey);
516 } else {
517 *zKey = NULL;
518 *nKey = 0;
523 #ifndef OMIT_EXPORT
526 * Implementation of an "export" function that allows a caller
527 * to duplicate the main database to an attached database. This is intended
528 * as a conveneince for users who need to:
530 * 1. migrate from an non-encrypted database to an encrypted database
531 * 2. move from an encrypted database to a non-encrypted database
532 * 3. convert beween the various flavors of encrypted databases.
534 * This implementation is based heavily on the procedure and code used
535 * in vacuum.c, but is exposed as a function that allows export to any
536 * named attached database.
540 ** Finalize a prepared statement. If there was an error, store the
541 ** text of the error message in *pzErrMsg. Return the result code.
543 ** Based on vacuumFinalize from vacuum.c
545 static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
546 int rc;
547 rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
548 if( rc ){
549 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
551 return rc;
555 ** Execute zSql on database db. Return an error code.
557 ** Based on execSql from vacuum.c
559 static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
560 sqlite3_stmt *pStmt;
561 VVA_ONLY( int rc; )
562 if( !zSql ){
563 return SQLITE_NOMEM;
565 if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
566 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
567 return sqlite3_errcode(db);
569 VVA_ONLY( rc = ) sqlite3_step(pStmt);
570 assert( rc!=SQLITE_ROW );
571 return sqlcipher_finalize(db, pStmt, pzErrMsg);
575 ** Execute zSql on database db. The statement returns exactly
576 ** one column. Execute this as SQL on the same database.
578 ** Based on execExecSql from vacuum.c
580 static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
581 sqlite3_stmt *pStmt;
582 int rc;
584 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
585 if( rc!=SQLITE_OK ) return rc;
587 while( SQLITE_ROW==sqlite3_step(pStmt) ){
588 rc = sqlcipher_execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
589 if( rc!=SQLITE_OK ){
590 sqlcipher_finalize(db, pStmt, pzErrMsg);
591 return rc;
595 return sqlcipher_finalize(db, pStmt, pzErrMsg);
599 * copy database and schema from the main database to an attached database
601 * Based on sqlite3RunVacuum from vacuum.c
603 void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
604 sqlite3 *db = sqlite3_context_db_handle(context);
605 const char* attachedDb = (const char*) sqlite3_value_text(argv[0]);
606 int saved_flags; /* Saved value of the db->flags */
607 int saved_nChange; /* Saved value of db->nChange */
608 int saved_nTotalChange; /* Saved value of db->nTotalChange */
609 void (*saved_xTrace)(void*,const char*); /* Saved db->xTrace */
610 int rc = SQLITE_OK; /* Return code from service routines */
611 char *zSql = NULL; /* SQL statements */
612 char *pzErrMsg = NULL;
614 saved_flags = db->flags;
615 saved_nChange = db->nChange;
616 saved_nTotalChange = db->nTotalChange;
617 saved_xTrace = db->xTrace;
618 db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
619 db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
620 db->xTrace = 0;
622 /* Query the schema of the main database. Create a mirror schema
623 ** in the temporary database.
625 zSql = sqlite3_mprintf(
626 "SELECT 'CREATE TABLE %s.' || substr(sql,14) "
627 " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
628 " AND rootpage>0"
629 , attachedDb);
630 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
631 if( rc!=SQLITE_OK ) goto end_of_export;
632 sqlite3_free(zSql);
634 zSql = sqlite3_mprintf(
635 "SELECT 'CREATE INDEX %s.' || substr(sql,14)"
636 " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %%' "
637 , attachedDb);
638 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
639 if( rc!=SQLITE_OK ) goto end_of_export;
640 sqlite3_free(zSql);
642 zSql = sqlite3_mprintf(
643 "SELECT 'CREATE UNIQUE INDEX %s.' || substr(sql,21) "
644 " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
645 , attachedDb);
646 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
647 if( rc!=SQLITE_OK ) goto end_of_export;
648 sqlite3_free(zSql);
650 /* Loop through the tables in the main database. For each, do
651 ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy
652 ** the contents to the temporary database.
654 zSql = sqlite3_mprintf(
655 "SELECT 'INSERT INTO %s.' || quote(name) "
656 "|| ' SELECT * FROM main.' || quote(name) || ';'"
657 "FROM main.sqlite_master "
658 "WHERE type = 'table' AND name!='sqlite_sequence' "
659 " AND rootpage>0"
660 , attachedDb);
661 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
662 if( rc!=SQLITE_OK ) goto end_of_export;
663 sqlite3_free(zSql);
665 /* Copy over the sequence table
667 zSql = sqlite3_mprintf(
668 "SELECT 'DELETE FROM %s.' || quote(name) || ';' "
669 "FROM %s.sqlite_master WHERE name='sqlite_sequence' "
670 , attachedDb, attachedDb);
671 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
672 if( rc!=SQLITE_OK ) goto end_of_export;
673 sqlite3_free(zSql);
675 zSql = sqlite3_mprintf(
676 "SELECT 'INSERT INTO %s.' || quote(name) "
677 "|| ' SELECT * FROM main.' || quote(name) || ';' "
678 "FROM %s.sqlite_master WHERE name=='sqlite_sequence';"
679 , attachedDb, attachedDb);
680 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
681 if( rc!=SQLITE_OK ) goto end_of_export;
682 sqlite3_free(zSql);
684 /* Copy the triggers, views, and virtual tables from the main database
685 ** over to the temporary database. None of these objects has any
686 ** associated storage, so all we have to do is copy their entries
687 ** from the SQLITE_MASTER table.
689 zSql = sqlite3_mprintf(
690 "INSERT INTO %s.sqlite_master "
691 " SELECT type, name, tbl_name, rootpage, sql"
692 " FROM main.sqlite_master"
693 " WHERE type='view' OR type='trigger'"
694 " OR (type='table' AND rootpage=0)"
695 , attachedDb);
696 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execSql(db, &pzErrMsg, zSql);
697 if( rc!=SQLITE_OK ) goto end_of_export;
698 sqlite3_free(zSql);
700 zSql = NULL;
701 end_of_export:
702 db->flags = saved_flags;
703 db->nChange = saved_nChange;
704 db->nTotalChange = saved_nTotalChange;
705 db->xTrace = saved_xTrace;
707 sqlite3_free(zSql);
709 if(rc) {
710 if(pzErrMsg != NULL) {
711 sqlite3_result_error(context, pzErrMsg, -1);
712 sqlite3DbFree(db, pzErrMsg);
713 } else {
714 sqlite3_result_error(context, sqlite3ErrStr(rc), -1);
719 #endif
721 /* END SQLCIPHER */
722 #endif