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