move key preparation into sqlite3_key and out of sqlite3CodecAttach for cleaner interface

This commit is contained in:
Stephen Lombardo 2008-07-30 20:55:42 -04:00
parent ce3851b8ad
commit c9b06918b1
2 changed files with 38 additions and 32 deletions

View File

@ -32,11 +32,10 @@ typedef struct {
Btree *pBt;
void *key;
void *rand;
char *pKey;
void *buffer;
} codec_ctx;
static int codec_page_hash(Pgno pgno, void *in, int inLen, void *out, int *outLen) {
static int codec_page_hash(Pgno pgno, const void *in, int inLen, void *out, int *outLen) {
EVP_MD_CTX mdctx;
unsigned int md_sz;
unsigned char md_value[EVP_MAX_MD_SIZE];
@ -56,7 +55,7 @@ static int codec_page_hash(Pgno pgno, void *in, int inLen, void *out, int *outLe
*outLen = md_sz;
}
static int codec_passphrase_hash(void *in, int inLen, void *out, int *outLen) {
static int codec_passphrase_hash(const void *in, int inLen, void *out, int *outLen) {
EVP_MD_CTX mdctx;
unsigned int md_sz;
unsigned char md_value[EVP_MAX_MD_SIZE];
@ -71,6 +70,24 @@ static int codec_passphrase_hash(void *in, int inLen, void *out, int *outLen) {
*outLen = md_sz;
}
static int codec_prepare_key(sqlite3 *db, const void *zKey, int nKey, void *out, int *nOut) {
/* 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 ' */
int half_n = n/2;
const char *z = zKey + 2; /* adjust lead offset of x' */
void *key = sqlite3HexToBlob(db, z, n);
memcpy(out, key, half_n);
*nOut = half_n;
memset(key, 0, half_n); /* cleanup temporary key data */
sqlite3_free(key);
/* otherwise the key is provided as a string so hash it to get key data */
} else {
codec_passphrase_hash(zKey, nKey, out, nOut);
}
}
/*
* ctx - codec context
* pgno - page number in database
@ -182,7 +199,6 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
RAND_pseudo_bytes(ctx->rand, 16);
/* pre-allocate a page buffer of PageSize bytes. This will
be used as a persistent buffer for encryption and decryption
operations to avoid overhead of multiple memory allocations*/
@ -191,32 +207,13 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
ctx->key_sz = EVP_CIPHER_key_length(CIPHER);
/* when key size is exactly the same size as nKey then we assume
we've recieved raw key data (i.e. through the attach of another
database */
if(nKey == ctx->key_sz) {
ctx->key = sqlite3DbMallocRaw(db, ctx->key_sz);
if(ctx->key == NULL) return SQLITE_NOMEM;
memcpy(ctx->key, zKey, nKey);
/* if key string starts with x' then assume this is a blob literal key*/
} else 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' */
assert((n/2) == ctx->key_sz); /* keylength after hex decode should equal cipher key length */
ctx->key = sqlite3HexToBlob(db, z, n);
/* key size should be exactly the same size as nKey since this is
raw key data at this point */
assert(nKey == ctx->key_sz);
/* otherwise the key is provided as a string so hash it to get key data */
} else {
int key_sz;
ctx->key = sqlite3DbMallocRaw(db, ctx->key_sz);
if(ctx->key == NULL) return SQLITE_NOMEM;
codec_passphrase_hash(zKey, nKey, ctx->key, &key_sz);
assert(key_sz == ctx->key_sz);
}
ctx->key = sqlite3DbMallocRaw(db, ctx->key_sz);
if(ctx->key == NULL) return SQLITE_NOMEM;
memcpy(ctx->key, zKey, nKey);
sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, (void *) ctx);
}
@ -228,10 +225,19 @@ void sqlite3_activate_see(const char* in) {
int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
if(db) {
int i;
int i, prepared_key_sz;
int key_sz = EVP_CIPHER_key_length(CIPHER);
void *key = sqlite3DbMallocRaw(db, key_sz);
codec_prepare_key(db, pKey, nKey, key, &prepared_key_sz);
assert(prepared_key_sz == key_sz);
for(i=0; i<db->nDb; i++){
sqlite3CodecAttach(db, i, pKey, nKey);
sqlite3CodecAttach(db, i, key, prepared_key_sz);
}
memset(key, 0, key_sz); /* cleanup temporary key data */
sqlite3_free(key);
}
}

View File

@ -5355,7 +5355,7 @@ i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
#endif /* SQLITE_OMIT_DISKIO */
/* BEGIN CRYPTO */
#if defined(SQLITE_HAS_CODEC)
#ifdef SQLITE_HAS_CODEC
int sqlite3pager_get_codec(Pager *pPager, void **ctx) {
*ctx = pPager->pCodecArg;