1 /*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2010, 2013 Oracle and/or its affiliates. All rights reserved.
5 */
6
7 /*
8 * This file implements SQLite encryption using the Berkeley DB encryption
9 * algorithms.
10 */
11 #include "sqliteInt.h"
12 #include "btreeInt.h"
13 #include <db.h>
14
15 #ifdef SQLITE_HAS_CODEC
16 void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
17
18 #define pDbEnv (pBt->dbenv)
19
20 /*
21 * sqlite3_key() is called only to set the encryption key for the "main"
22 * backend database, that is db->aDb[0]. The encryption key for attached
23 * databases is set directly via sqlite3CodecAttach().
24 */
sqlite3_key(sqlite3 * db,const void * key,int nkey)25 int sqlite3_key(sqlite3 *db, const void *key, int nkey) {
26 return sqlite3CodecAttach(db, 0, key, nkey);
27 }
28
sqlite3_rekey(sqlite3 * db,const void * key,int nkey)29 int sqlite3_rekey(sqlite3 *db, const void *key, int nkey) {
30 return 0;
31 }
32
sqlite3_activate_see(const char * zPassPhrase)33 void sqlite3_activate_see(const char *zPassPhrase) {
34 return;
35 }
36
37 /*
38 * Used by the ATTACH command and by sqlite3_key, set the encryption key for the
39 * backend-th database, where "main" is 0, "temp" is 1 and each additional
40 * ATTACH-ed database file is 2, 3, 4, ...
41 */
sqlite3CodecAttach(sqlite3 * db,int backend,const void * key,int nkey)42 int sqlite3CodecAttach(sqlite3 *db, int backend, const void *key, int nkey) {
43 struct BtShared *pBt;
44 int ret;
45
46 assert(db->aDb[backend].pBt != NULL);
47 pBt = db->aDb[backend].pBt->pBt;
48
49 /*
50 * An empty key means no encryption. Also, don't try to encrypt an
51 * environment that's already been opened. Don't encrypt an in-mem db
52 * since it will never be written to disk.
53 */
54 if (nkey == 0 || pBt->env_opened || pBt->dbStorage != DB_STORE_NAMED)
55 return dberr2sqlite(0, db->aDb[backend].pBt);
56
57 sqlite3_mutex_enter(db->mutex);
58
59 /*
60 * SQLite and BDB have slightly different semantics for the key.
61 * SQLite's key is a string of bytes whose length is specified
62 * separately, while BDB takes a NULL terminated string. We need to
63 * ensure the key is NULL terminated before passing to BDB, but we can't
64 * modify the given key, so we have to make a copy. BDB will make its
65 * own copy of the key, it's safe to free keystring after
66 * the set_encrypt call.
67 */
68 if (pBt->encrypt_pwd != NULL)
69 CLEAR_PWD(pBt);
70
71 if ((pBt->encrypt_pwd = malloc((size_t)nkey + 1)) == NULL) {
72 ret = ENOMEM;
73 goto err;
74 }
75
76 memcpy(pBt->encrypt_pwd, key, nkey);
77 /*
78 * We allocate nkey + 1 bytes, but will only clear nkey bytes to
79 * preserve the terminating NULL.
80 */
81 pBt->encrypt_pwd_len = nkey;
82 pBt->encrypt_pwd[nkey] = '\0';
83
84 ret = pDbEnv->set_encrypt(pDbEnv, pBt->encrypt_pwd, DB_ENCRYPT_AES);
85
86 pBt->encrypted = 1;
87
88 err: sqlite3_mutex_leave(db->mutex);
89
90 return dberr2sqlite(ret, db->aDb[backend].pBt);
91 }
92
93 /*
94 * Get the current key of the given database.
95 */
sqlite3CodecGetKey(sqlite3 * db,int backend,void ** keyp,int * nkeyp)96 void sqlite3CodecGetKey(sqlite3 *db, int backend, void **keyp, int *nkeyp) {
97 *keyp = db->aDb[backend].pBt->pBt->encrypt_pwd;
98 *nkeyp = db->aDb[backend].pBt->pBt->encrypt_pwd_len;
99 return;
100 }
101
102 #endif
103