董淳光SQLITE3?使用总结(4)

<script></script>标签:知识/探索 | ? |
void sqlite3CodecGetKey(sqlite3* db, int nDB, void** Key, int* nKey)
{
return ;
}
?
int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen);
void sqlite3_activate_see(const char* right )
{??
return;
}
?
int sqlite3_key(sqlite3 *db, const void *pKey, int nKey);
int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey);
?
// 从用户提供的缓冲区中得到一个加密密钥
// 用户提供的密钥可能位数上满足不了要求,使用这个函数来完成密钥扩展
static unsigned char * DeriveKey(const void *pKey, int nKeyLen);
//创建或更新一个页的加密算法索引.此函数会申请缓冲区.
static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryptBlock pExisting);
//加密/解密函数, 被pager调用
void * sqlite3Codec(void *pArg, unsigned char *data, Pgno nPageNum, int nMode);
//设置密码函数
int __stdcall sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize);
// 修改密码函数
int __stdcall sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySize);
//销毁一个加密块及相关的缓冲区,密钥.
static void DestroyCryptBlock(LPCryptBlock pBlock);
static void * sqlite3pager_get_codecarg(Pager *pPager);
void sqlite3pager_set_codec(Pager *pPager,void *(*xCodec)(void*,void*,Pgno,int),void *pCodecArg??? );
?
//加密/解密函数, 被pager调用
void * sqlite3Codec(void *pArg, unsigned char *data, Pgno nPageNum, int nMode)
{
LPCryptBlock pBlock = (LPCryptBlock)pArg;
unsigned int dwPageSize = 0;
?
if (!pBlock) return data;
?
// 确保pager的页长度和加密块的页长度相等.如果改变,就需要调整.
if (nMode != 2)
{
???? PgHdr *pageHeader;
???? pageHeader = DATA_TO_PGHDR(data);
???? if (pageHeader->pPager->pageSize != pBlock->PageSize)
???? {
????????? CreateCryptBlock(0, pageHeader->pPager, pBlock);
???? }
}
switch(nMode)
{
case 0: // Undo a "case 7" journal file encryption
case 2: //重载一个页
case 3: //载入一个页
???? if (!pBlock->ReadKey) break;
???? dwPageSize = pBlock->PageSize;
???? My_DeEncrypt_Func(data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE );?
????? break;
case 6: //加密一个主数据库文件的页
???? if (!pBlock->WriteKey) break;
?
???? memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize);
???? data = pBlock->Data + CRYPT_OFFSET;
???? dwPageSize = pBlock->PageSize;
???? My_Encrypt_Func(data , dwPageSize, pBlock->WriteKey, DB_KEY_LENGTH_BYTE );
???? break;
case 7: //加密事务文件的页
???? if (!pBlock->ReadKey) break;
???? memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize);
???? data = pBlock->Data + CRYPT_OFFSET;
???? dwPageSize = pBlock->PageSize;
???? My_Encrypt_Func( data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE );
???? break;
}
return data;
}
//销毁一个加密块及相关的缓冲区,密钥.
static void DestroyCryptBlock(LPCryptBlock pBlock)
{
//销毁读密钥.
if (pBlock->ReadKey){
???? sqliteFree(pBlock->ReadKey);
}
?
//如果写密钥存在并且不等于读密钥,也销毁.
if (pBlock->WriteKey && pBlock->WriteKey != pBlock->ReadKey){
???? sqliteFree(pBlock->WriteKey);
}
if(pBlock->Data){
???? sqliteFree(pBlock->Data);
}
//释放加密块.
sqliteFree(pBlock);
}
static void * sqlite3pager_get_codecarg(Pager *pPager)
{
return (pPager->xCodec) ? pPager->pCodecArg: NULL;
}
// 从用户提供的缓冲区中得到一个加密密钥
static unsigned char * DeriveKey(const void *pKey, int nKeyLen)
{
unsigned char *? hKey = NULL;
int j;
if( pKey == NULL || nKeyLen == 0 )
{
???? return NULL;
}
hKey = sqliteMalloc( DB_KEY_LENGTH_BYTE + 1 );
if( hKey == NULL )
{
???? return NULL;
}
hKey[ DB_KEY_LENGTH_BYTE ] = 0;
if( nKeyLen < DB_KEY_LENGTH_BYTE )
{
???? memcpy( hKey, pKey, nKeyLen ); //先拷贝得到密钥前面的部分
???? j = DB_KEY_LENGTH_BYTE - nKeyLen;
???? //补充密钥后面的部分
???? memset(? hKey + nKeyLen,? DB_KEY_PADDING, j? );
}
else
{ //密钥位数已经足够,直接把密钥取过来
???? memcpy(? hKey, pKey, DB_KEY_LENGTH_BYTE );
}
return hKey;
}
//创建或更新一个页的加密算法索引.此函数会申请缓冲区.
static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryptBlock pExisting)
{
LPCryptBlock pBlock;
if (!pExisting) //创建新加密块
{
???? pBlock = sqliteMalloc(sizeof(CryptBlock));
???? memset(pBlock, 0, sizeof(CryptBlock));
???? pBlock->ReadKey = hKey;
???? pBlock->WriteKey = hKey;
???? pBlock->PageSize = pager->pageSize;
???? pBlock->Data = (unsigned char*)sqliteMalloc(pBlock->PageSize + CRYPT_OFFSET);
}
else //更新存在的加密块
{
???? pBlock = pExisting;
???? if ( pBlock->PageSize != pager->pageSize && !pBlock->Data){
????????? sqliteFree(pBlock->Data);
????????? pBlock->PageSize = pager->pageSize;
????????? pBlock->Data = (unsigned char*)sqliteMalloc(pBlock->PageSize + CRYPT_OFFSET);
???? }
}
memset(pBlock->Data, 0, pBlock->PageSize + CRYPT_OFFSET);
return pBlock;
}
void sqlite3pager_set_codec(
???????????????????????????? Pager *pPager,
???????????????????????????? void *(*xCodec)(void*,void*,Pgno,int),
??????????????????????????? void *pCodecArg
???????????????????????????? )
{
pPager->xCodec = xCodec;
pPager->pCodecArg = pCodecArg;
}