switch digest to sha256 (requires sha256 support in openssl); allow setting a passphrase instead of raw blob key; update readme
This commit is contained in:
parent
11dd40da8d
commit
a45a181cee
16
Makefile.in
16
Makefile.in
|
@ -17,6 +17,7 @@
|
|||
#
|
||||
TOP = @srcdir@
|
||||
|
||||
|
||||
# C Compiler and options for use in building executables that
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
|
@ -122,6 +123,13 @@ USE_GCOV = @USE_GCOV@
|
|||
LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV))
|
||||
LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV))
|
||||
|
||||
# BEGIN CRYPTO
|
||||
CRYPTOLIBOBJ = \
|
||||
crypto.lo
|
||||
|
||||
CRYPTOSRC = \
|
||||
$(TOP)/src/crypto.c
|
||||
# END CRYPTO
|
||||
|
||||
# The directory into which to store package information for
|
||||
|
||||
|
@ -160,7 +168,7 @@ OBJS0 = alter.lo analyze.lo attach.lo auth.lo bitvec.lo btmutex.lo \
|
|||
select.lo status.lo table.lo tokenize.lo trigger.lo update.lo \
|
||||
util.lo vacuum.lo \
|
||||
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbefifo.lo vdbemem.lo \
|
||||
where.lo utf.lo legacy.lo vtab.lo
|
||||
where.lo utf.lo legacy.lo vtab.lo $(CRYPTOLIBOBJ)
|
||||
|
||||
# Object files for the amalgamation.
|
||||
#
|
||||
|
@ -175,6 +183,7 @@ LIBOBJ = $(OBJS$(USE_AMALGAMATION))
|
|||
# All of the source code files.
|
||||
#
|
||||
SRC = \
|
||||
$(CRYPTOSRC) \
|
||||
$(TOP)/src/alter.c \
|
||||
$(TOP)/src/analyze.c \
|
||||
$(TOP)/src/attach.c \
|
||||
|
@ -464,6 +473,11 @@ lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c
|
|||
sqlite3.lo: sqlite3.c
|
||||
$(LTCOMPILE) -c sqlite3.c
|
||||
|
||||
# BEGIN CRYPTO
|
||||
crypto.lo: $(TOP)/src/crypto.c $(HDR)
|
||||
$(LTCOMPILE) -c $(TOP)/src/crypto.c
|
||||
# END CRYPTO
|
||||
|
||||
# Rules to build individual files
|
||||
#
|
||||
alter.lo: $(TOP)/src/alter.c $(HDR)
|
||||
|
|
17
README
17
README
|
@ -1,3 +1,20 @@
|
|||
== SQLite Cipher Introduction ==
|
||||
|
||||
SQLite Cipher is an SQLite extension that provides transparent 256 bit AES encryption of database files.
|
||||
Pages are encrypted before being written to disk and are decrypted when read back.
|
||||
|
||||
Encryption is provided by the OpenSSL crypto library.
|
||||
|
||||
Static linking (replace /opt/local/lib with the path to libcrypto.a)
|
||||
./configure --disable-amalgamation CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="/opt/local/lib/libcrypto.a"
|
||||
make
|
||||
|
||||
Dynamic linking
|
||||
./configure --disable-amalgamation CFLAGS="-DSQLITE_HAS_CODEC -lcrypto"
|
||||
make
|
||||
|
||||
== End Introduction ==
|
||||
|
||||
This directory contains source code to
|
||||
|
||||
SQLite: An Embeddable SQL Database Engine
|
||||
|
|
150
sqlite3.def
150
sqlite3.def
|
@ -1,150 +0,0 @@
|
|||
EXPORTS
|
||||
sqlite3_aggregate_context
|
||||
sqlite3_aggregate_count
|
||||
sqlite3_auto_extension
|
||||
sqlite3_bind_blob
|
||||
sqlite3_bind_double
|
||||
sqlite3_bind_int
|
||||
sqlite3_bind_int64
|
||||
sqlite3_bind_null
|
||||
sqlite3_bind_parameter_count
|
||||
sqlite3_bind_parameter_index
|
||||
sqlite3_bind_parameter_name
|
||||
sqlite3_bind_text
|
||||
sqlite3_bind_text16
|
||||
sqlite3_bind_value
|
||||
sqlite3_bind_zeroblob
|
||||
sqlite3_blob_bytes
|
||||
sqlite3_blob_close
|
||||
sqlite3_blob_open
|
||||
sqlite3_blob_read
|
||||
sqlite3_blob_write
|
||||
sqlite3_busy_handler
|
||||
sqlite3_busy_timeout
|
||||
sqlite3_changes
|
||||
sqlite3_clear_bindings
|
||||
sqlite3_close
|
||||
sqlite3_collation_needed
|
||||
sqlite3_collation_needed16
|
||||
sqlite3_column_blob
|
||||
sqlite3_column_bytes
|
||||
sqlite3_column_bytes16
|
||||
sqlite3_column_count
|
||||
sqlite3_column_decltype
|
||||
sqlite3_column_decltype16
|
||||
sqlite3_column_double
|
||||
sqlite3_column_int
|
||||
sqlite3_column_int64
|
||||
sqlite3_column_name
|
||||
sqlite3_column_name16
|
||||
sqlite3_column_text
|
||||
sqlite3_column_text16
|
||||
sqlite3_column_type
|
||||
sqlite3_column_value
|
||||
sqlite3_commit_hook
|
||||
sqlite3_complete
|
||||
sqlite3_complete16
|
||||
sqlite3_create_collation
|
||||
sqlite3_create_collation16
|
||||
sqlite3_create_collation_v2
|
||||
sqlite3_create_function
|
||||
sqlite3_create_function16
|
||||
sqlite3_create_module
|
||||
sqlite3_create_module_v2
|
||||
sqlite3_data_count
|
||||
sqlite3_db_handle
|
||||
sqlite3_declare_vtab
|
||||
sqlite3_enable_load_extension
|
||||
sqlite3_enable_shared_cache
|
||||
sqlite3_errcode
|
||||
sqlite3_errmsg
|
||||
sqlite3_errmsg16
|
||||
sqlite3_exec
|
||||
sqlite3_expired
|
||||
sqlite3_extended_result_codes
|
||||
sqlite3_file_control
|
||||
sqlite3_finalize
|
||||
sqlite3_free
|
||||
sqlite3_free_table
|
||||
sqlite3_get_autocommit
|
||||
sqlite3_get_auxdata
|
||||
sqlite3_get_table
|
||||
sqlite3_global_recover
|
||||
sqlite3_interrupt
|
||||
sqlite3_last_insert_rowid
|
||||
sqlite3_libversion
|
||||
sqlite3_libversion_number
|
||||
sqlite3_load_extension
|
||||
sqlite3_malloc
|
||||
sqlite3_memory_alarm
|
||||
sqlite3_memory_highwater
|
||||
sqlite3_memory_used
|
||||
sqlite3_mprintf
|
||||
sqlite3_mutex_alloc
|
||||
sqlite3_mutex_enter
|
||||
sqlite3_mutex_free
|
||||
sqlite3_mutex_leave
|
||||
sqlite3_mutex_try
|
||||
sqlite3_open
|
||||
sqlite3_open16
|
||||
sqlite3_open_v2
|
||||
sqlite3_overload_function
|
||||
sqlite3_prepare
|
||||
sqlite3_prepare16
|
||||
sqlite3_prepare16_v2
|
||||
sqlite3_prepare_v2
|
||||
sqlite3_profile
|
||||
sqlite3_progress_handler
|
||||
sqlite3_randomness
|
||||
sqlite3_realloc
|
||||
sqlite3_release_memory
|
||||
sqlite3_reset
|
||||
sqlite3_reset_auto_extension
|
||||
sqlite3_result_blob
|
||||
sqlite3_result_double
|
||||
sqlite3_result_error
|
||||
sqlite3_result_error16
|
||||
sqlite3_result_error_code
|
||||
sqlite3_result_error_nomem
|
||||
sqlite3_result_error_toobig
|
||||
sqlite3_result_int
|
||||
sqlite3_result_int64
|
||||
sqlite3_result_null
|
||||
sqlite3_result_text
|
||||
sqlite3_result_text16
|
||||
sqlite3_result_text16be
|
||||
sqlite3_result_text16le
|
||||
sqlite3_result_value
|
||||
sqlite3_result_zeroblob
|
||||
sqlite3_rollback_hook
|
||||
sqlite3_set_authorizer
|
||||
sqlite3_set_auxdata
|
||||
sqlite3_sleep
|
||||
sqlite3_snprintf
|
||||
sqlite3_soft_heap_limit
|
||||
sqlite3_sql
|
||||
sqlite3_step
|
||||
sqlite3_test_control
|
||||
sqlite3_thread_cleanup
|
||||
sqlite3_threadsafe
|
||||
sqlite3_total_changes
|
||||
sqlite3_trace
|
||||
sqlite3_transfer_bindings
|
||||
sqlite3_update_hook
|
||||
sqlite3_user_data
|
||||
sqlite3_value_blob
|
||||
sqlite3_value_bytes
|
||||
sqlite3_value_bytes16
|
||||
sqlite3_value_double
|
||||
sqlite3_value_int
|
||||
sqlite3_value_int64
|
||||
sqlite3_value_numeric_type
|
||||
sqlite3_value_text
|
||||
sqlite3_value_text16
|
||||
sqlite3_value_text16be
|
||||
sqlite3_value_text16le
|
||||
sqlite3_value_type
|
||||
sqlite3_vfs_find
|
||||
sqlite3_vfs_register
|
||||
sqlite3_vfs_unregister
|
||||
sqlite3_vmprintf
|
54
src/crypto.c
54
src/crypto.c
|
@ -1,10 +1,11 @@
|
|||
/* BEGIN CRYPTO */
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
|
||||
#include "sqliteInt.h"
|
||||
#include "btreeInt.h"
|
||||
#include <assert.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "sqliteInt.h"
|
||||
#include "btreeInt.h"
|
||||
#include "crypto.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -16,7 +17,7 @@ typedef struct {
|
|||
void *buffer;
|
||||
} codec_ctx;
|
||||
|
||||
static int codec_hash(codec_ctx *ctx, void *out, int *outLen, void *in, int inLen) {
|
||||
static int codec_page_hash(Pgno pgno, void *in, int inLen, void *out, int *outLen) {
|
||||
EVP_MD_CTX mdctx;
|
||||
unsigned int md_sz;
|
||||
unsigned char md_value[EVP_MAX_MD_SIZE];
|
||||
|
@ -24,10 +25,9 @@ static int codec_hash(codec_ctx *ctx, void *out, int *outLen, void *in, int inLe
|
|||
EVP_MD_CTX_init(&mdctx);
|
||||
EVP_DigestInit_ex(&mdctx, DIGEST, NULL);
|
||||
|
||||
if(ctx->rand)
|
||||
EVP_DigestUpdate(&mdctx, ctx->rand, 16);
|
||||
EVP_DigestUpdate(&mdctx, in, inLen); /* add random "salt" data to hash*/
|
||||
EVP_DigestUpdate(&mdctx, &pgno, sizeof(pgno));
|
||||
|
||||
EVP_DigestUpdate(&mdctx, in, inLen);
|
||||
EVP_DigestFinal_ex(&mdctx, md_value, &md_sz);
|
||||
|
||||
memcpy(out, md_value, md_sz);
|
||||
|
@ -37,6 +37,21 @@ static int codec_hash(codec_ctx *ctx, void *out, int *outLen, void *in, int inLe
|
|||
*outLen = md_sz;
|
||||
}
|
||||
|
||||
static int codec_passphrase_hash(void *in, int inLen, void *out, int *outLen) {
|
||||
EVP_MD_CTX mdctx;
|
||||
unsigned int md_sz;
|
||||
unsigned char md_value[EVP_MAX_MD_SIZE];
|
||||
|
||||
EVP_MD_CTX_init(&mdctx);
|
||||
EVP_DigestInit_ex(&mdctx, DIGEST, NULL);
|
||||
EVP_DigestUpdate(&mdctx, in, inLen);
|
||||
EVP_DigestFinal_ex(&mdctx, md_value, &md_sz);
|
||||
memcpy(out, md_value, md_sz);
|
||||
EVP_MD_CTX_cleanup(&mdctx);
|
||||
memset(md_value, 0, md_sz);
|
||||
*outLen = md_sz;
|
||||
}
|
||||
|
||||
/*
|
||||
* ctx - codec context
|
||||
* pgno - page number in database
|
||||
|
@ -45,12 +60,16 @@ static int codec_hash(codec_ctx *ctx, void *out, int *outLen, void *in, int inLe
|
|||
* in - pointer to input bytes
|
||||
* out - pouter to output bytes
|
||||
*/
|
||||
static int codec_cipher(codec_ctx *ctx, int pgno, int mode, int size, void *in, void *out) {
|
||||
static int codec_cipher(codec_ctx *ctx, Pgno pgno, int mode, int size, void *in, void *out) {
|
||||
EVP_CIPHER_CTX ectx;
|
||||
unsigned char iv[EVP_MAX_MD_SIZE];
|
||||
int iv_sz, tmp_csz, csz;
|
||||
|
||||
codec_hash(ctx, iv, &iv_sz, &pgno, sizeof(pgno));
|
||||
/* the initilization vector is created from the hash of the
|
||||
16 byte database random salt and the page number. This will
|
||||
ensure that each page in the database has a unique initialization
|
||||
vector */
|
||||
codec_page_hash(pgno, ctx->rand, 16, iv, &iv_sz);
|
||||
|
||||
EVP_CipherInit(&ectx, CIPHER, NULL, NULL, mode);
|
||||
EVP_CIPHER_CTX_set_padding(&ectx, 0);
|
||||
|
@ -64,11 +83,6 @@ static int codec_cipher(codec_ctx *ctx, int pgno, int mode, int size, void *in,
|
|||
assert(size == csz);
|
||||
}
|
||||
|
||||
|
||||
void sqlite3_activate_see(const char* in) {
|
||||
/* do nothing, security enhancements are always active */
|
||||
}
|
||||
|
||||
/*
|
||||
* sqlite3Codec can be called in multiple modes.
|
||||
* encrypt mode - expected to return a pointer to the
|
||||
|
@ -152,12 +166,22 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
|
|||
operations to avoid overhead of multiple memory allocations*/
|
||||
ctx->buffer = sqlite3_malloc(sqlite3BtreeGetPageSize(ctx->pBt));
|
||||
|
||||
/* if key string starts with x' then this is a blob literal key*/
|
||||
ctx->key_sz = EVP_CIPHER_key_length(CIPHER);
|
||||
|
||||
/* if key string starts with x' then assume this is a blob literal key*/
|
||||
if(sqlite3StrNICmp(zKey,"x'", 2) == 0) {
|
||||
int n = nKey - 3; /* adjust for leading x' and tailing ' */
|
||||
const char *z = zKey + 2; /* adjust lead offset of x' */
|
||||
ctx->key_sz = EVP_CIPHER_key_length(CIPHER);
|
||||
|
||||
assert((n/2) == ctx->key_sz); /* keylength after hex decode should equal cipher key length */
|
||||
ctx->key = sqlite3HexToBlob(db, z, n);
|
||||
|
||||
/* otherwise the key is provided as a string so hash it to get key data */
|
||||
} else {
|
||||
int key_sz;
|
||||
ctx->key = sqlite3_malloc(ctx->key_sz);
|
||||
codec_passphrase_hash(zKey, nKey, ctx->key, &key_sz);
|
||||
assert(key_sz == ctx->key_sz);
|
||||
}
|
||||
|
||||
sqlite3pager_set_codec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, (void *) ctx);
|
||||
|
|
15
src/crypto.h
15
src/crypto.h
|
@ -1,15 +1,28 @@
|
|||
/*
|
||||
** SQLite Security Enh
|
||||
** crypto.h developed by Stephen Lombardo (Zetetic LLC)
|
||||
** sjlombardo at zetetic dot net
|
||||
** http://zetetic.net
|
||||
**
|
||||
** July 30, 2008
|
||||
**
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
**
|
||||
*/
|
||||
/* BEGIN CRYPTO */
|
||||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_H
|
||||
|
||||
#define CIPHER EVP_aes_256_cfb()
|
||||
#define DIGEST EVP_sha1()
|
||||
#define DIGEST EVP_sha256()
|
||||
|
||||
/* HDR_SIZE allocates 16 bytes for random salt and 8 bytes for page size */
|
||||
#define HDR_SZ 24
|
||||
|
|
16
src/pager.c
16
src/pager.c
|
@ -5353,3 +5353,19 @@ i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
|
|||
}
|
||||
|
||||
#endif /* SQLITE_OMIT_DISKIO */
|
||||
|
||||
/* BEGIN CRYPTO */
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
|
||||
int sqlite3pager_get_codec(Pager *pPager, void **ctx) {
|
||||
*ctx = pPager->pCodecArg;
|
||||
}
|
||||
|
||||
void sqlite3pager_set_codec(Pager *pPager, void *(*xCodec)(void*,void*,Pgno,int), void *pCodecArg){
|
||||
pPager->xCodec = xCodec;
|
||||
pPager->pCodecArg = pCodecArg;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* END CRYPTO */
|
||||
|
||||
|
|
Loading…
Reference in New Issue