pwcompat.cpp
来自「一款密码保险箱源码」· C++ 代码 · 共 651 行 · 第 1/2 页
CPP
651 行
sha256_hash(m_pMasterKey, 32, &sha32);
sha256_end((unsigned char *)uFinalKey, &sha32);
ASSERT(((uFileSize - sizeof(PW_DBHEADER_V2)) % 16) == 0);
if(m_nAlgorithm == ALGO_AES)
{
CRijndael aes;
// Initialize Rijndael algorithm
if(aes.Init(CRijndael::CBC, CRijndael::DecryptDir, uFinalKey,
CRijndael::Key32Bytes, hdr.aEncryptionIV) != RIJNDAEL_SUCCESS)
{ _OPENDB_FAIL; }
// Decrypt! The first bytes aren't encrypted (that's the header)
uEncryptedPartSize = (unsigned long)aes.PadDecrypt((UINT8 *)pVirtualFile + sizeof(PW_DBHEADER_V2),
uFileSize - sizeof(PW_DBHEADER_V2), (UINT8 *)pVirtualFile + sizeof(PW_DBHEADER_V2));
}
else if(m_nAlgorithm == ALGO_TWOFISH)
{
CTwofish twofish;
if(twofish.Init(uFinalKey, 32, hdr.aEncryptionIV) != true)
{ _OPENDB_FAIL };
uEncryptedPartSize = (unsigned long)twofish.PadDecrypt((UINT8 *)pVirtualFile + sizeof(PW_DBHEADER_V2),
uFileSize - sizeof(PW_DBHEADER_V2), (UINT8 *)pVirtualFile + sizeof(PW_DBHEADER_V2));
}
else
{
ASSERT(FALSE); _OPENDB_FAIL; // This should never happen
}
// Check for success
if((uEncryptedPartSize > 2147483446) || (uEncryptedPartSize == 0))
{ _OPENDB_FAIL; }
// Check if key is correct (with high probability)
sha256_begin(&sha32);
sha256_hash((unsigned char *)pVirtualFile + sizeof(PW_DBHEADER_V2), uEncryptedPartSize, &sha32);
sha256_end((unsigned char *)uFinalKey, &sha32);
if(memcmp(hdr.aContentsHash, uFinalKey, 32) != 0)
{ _OPENDB_FAIL; }
NewDatabase(); // Create a new database and initialize internal structures
memset(&pwGroupTemplate, 0, 16);
RESET_PWG_TEMPLATE(&pwGroupTemplate);
// Add groups from the memory file to the internal structures
unsigned long uCurGroup;
BOOL bRet;
pos = sizeof(PW_DBHEADER_V2);
for(uCurGroup = 0; uCurGroup < hdr.dwGroups; )
{
p = &pVirtualFile[pos];
memcpy(&usFieldType, p, 2);
p += 2; pos += 2;
if(pos >= uFileSize) { _OPENDB_FAIL; }
memcpy(&dwFieldSize, p, 4);
p += 4; pos += 4;
if(pos >= (uFileSize + dwFieldSize)) { _OPENDB_FAIL; }
bRet = _ReadGroupFieldV2(usFieldType, dwFieldSize, (BYTE *)p, &pwGroupTemplate);
if((usFieldType == 0xFFFF) && (bRet == TRUE))
uCurGroup++; // Now and ONLY now the counter gets increased
p += dwFieldSize;
pos += dwFieldSize;
if(pos >= uFileSize) { _OPENDB_FAIL; }
}
SAFE_DELETE_ARRAY(pwGroupTemplate.pszGroupName);
RESET_PWE_TEMPLATE(&pwEntryTemplate);
// Get the entries
unsigned long uCurEntry;
for(uCurEntry = 0; uCurEntry < hdr.dwEntries; )
{
p = &pVirtualFile[pos];
memcpy(&usFieldType, p, 2);
p += 2; pos += 2;
if(pos >= uFileSize) { _OPENDB_FAIL; }
memcpy(&dwFieldSize, p, 4);
p += 4; pos += 4;
if(pos >= (uFileSize + dwFieldSize)) { _OPENDB_FAIL; }
bRet = _ReadEntryFieldV2(usFieldType, dwFieldSize, (BYTE *)p, &pwEntryTemplate);
if((usFieldType == 0xFFFF) && (bRet == TRUE))
uCurEntry++; // Now and ONLY now the counter gets increased
p += dwFieldSize;
pos += dwFieldSize;
if(pos >= uFileSize) { _OPENDB_FAIL; }
}
SAFE_DELETE_ARRAY(pwEntryTemplate.pszTitle);
SAFE_DELETE_ARRAY(pwEntryTemplate.pszURL);
SAFE_DELETE_ARRAY(pwEntryTemplate.pszUserName);
SAFE_DELETE_ARRAY(pwEntryTemplate.pszPassword);
SAFE_DELETE_ARRAY(pwEntryTemplate.pszAdditional);
SAFE_DELETE_ARRAY(pwEntryTemplate.pszBinaryDesc);
SAFE_DELETE_ARRAY(pwEntryTemplate.pBinaryData);
// Erase and delete memory file
mem_erase((unsigned char *)pVirtualFile, uAllocated);
SAFE_DELETE_ARRAY(pVirtualFile);
return TRUE;
}
BOOL CPwManager::_ReadGroupFieldV2(USHORT usFieldType, DWORD dwFieldSize, BYTE *pData, PW_GROUP *pGroup)
{
BYTE aCompressedTime[5];
#ifdef NDEBUG
UNREFERENCED_PARAMETER(dwFieldSize);
#endif
switch(usFieldType)
{
case 0x0000:
// Ignore field
break;
case 0x0001:
memcpy(&pGroup->uGroupId, pData, 4);
break;
case 0x0002:
ASSERT(dwFieldSize != 0);
SAFE_DELETE_ARRAY(pGroup->pszGroupName);
pGroup->pszGroupName = _UTF8ToStringV2((UTF8_BYTE *)pData);
break;
case 0x0003:
memcpy(aCompressedTime, pData, 5);
TimeToPwTime(aCompressedTime, &pGroup->tCreation);
break;
case 0x0004:
memcpy(aCompressedTime, pData, 5);
TimeToPwTime(aCompressedTime, &pGroup->tLastMod);
break;
case 0x0005:
memcpy(aCompressedTime, pData, 5);
TimeToPwTime(aCompressedTime, &pGroup->tLastAccess);
break;
case 0x0006:
memcpy(aCompressedTime, pData, 5);
TimeToPwTime(aCompressedTime, &pGroup->tExpire);
break;
case 0x0007:
memcpy(&pGroup->uImageId, pData, 4);
break;
case 0x0008:
memcpy(&pGroup->usLevel, pData, 2);
break;
case 0x0009:
memcpy(&pGroup->dwFlags, pData, 4);
break;
case 0xFFFF:
AddGroup(pGroup);
SAFE_DELETE_ARRAY(pGroup->pszGroupName);
RESET_PWG_TEMPLATE(pGroup);
break;
default:
return FALSE; // Field unsupported
}
return TRUE; // Field supported
}
BOOL CPwManager::_ReadEntryFieldV2(USHORT usFieldType, DWORD dwFieldSize, BYTE *pData, PW_ENTRY *pEntry)
{
BYTE aCompressedTime[5];
switch(usFieldType)
{
case 0x0000:
// Ignore field
break;
case 0x0001:
memcpy(pEntry->uuid, pData, 16);
break;
case 0x0002:
memcpy(&pEntry->uGroupId, pData, 4);
break;
case 0x0003:
memcpy(&pEntry->uImageId, pData, 4);
break;
case 0x0004:
ASSERT(dwFieldSize != 0);
SAFE_DELETE_ARRAY(pEntry->pszTitle);
pEntry->pszTitle = _UTF8ToStringV2((UTF8_BYTE *)pData);
break;
case 0x0005:
ASSERT(dwFieldSize != 0);
SAFE_DELETE_ARRAY(pEntry->pszURL);
pEntry->pszURL = _UTF8ToStringV2((UTF8_BYTE *)pData);
break;
case 0x0006:
ASSERT(dwFieldSize != 0);
SAFE_DELETE_ARRAY(pEntry->pszUserName);
pEntry->pszUserName = _UTF8ToStringV2((UTF8_BYTE *)pData);
break;
case 0x0007:
ASSERT(dwFieldSize != 0);
SAFE_DELETE_ARRAY(pEntry->pszPassword);
pEntry->pszPassword = _UTF8ToStringV2((UTF8_BYTE *)pData);
break;
case 0x0008:
ASSERT(dwFieldSize != 0);
SAFE_DELETE_ARRAY(pEntry->pszAdditional);
pEntry->pszAdditional = _UTF8ToStringV2((UTF8_BYTE *)pData);
break;
case 0x0009:
ASSERT(dwFieldSize == 5);
memcpy(aCompressedTime, pData, 5);
TimeToPwTime(aCompressedTime, &pEntry->tCreation);
break;
case 0x000A:
ASSERT(dwFieldSize == 5);
memcpy(aCompressedTime, pData, 5);
TimeToPwTime(aCompressedTime, &pEntry->tLastMod);
break;
case 0x000B:
ASSERT(dwFieldSize == 5);
memcpy(aCompressedTime, pData, 5);
TimeToPwTime(aCompressedTime, &pEntry->tLastAccess);
break;
case 0x000C:
ASSERT(dwFieldSize == 5);
memcpy(aCompressedTime, pData, 5);
TimeToPwTime(aCompressedTime, &pEntry->tExpire);
break;
case 0x000D:
ASSERT(dwFieldSize != 0);
SAFE_DELETE_ARRAY(pEntry->pszBinaryDesc);
pEntry->pszBinaryDesc = _UTF8ToStringV2((UTF8_BYTE *)pData);
break;
case 0x000E:
SAFE_DELETE_ARRAY(pEntry->pBinaryData);
if(dwFieldSize != 0)
{
pEntry->pBinaryData = new BYTE[dwFieldSize];
memcpy(pEntry->pBinaryData, pData, dwFieldSize);
pEntry->uBinaryDataLen = dwFieldSize;
}
break;
case 0xFFFF:
ASSERT(dwFieldSize == 0);
AddEntry(pEntry);
SAFE_DELETE_ARRAY(pEntry->pszTitle);
SAFE_DELETE_ARRAY(pEntry->pszURL);
SAFE_DELETE_ARRAY(pEntry->pszUserName);
SAFE_DELETE_ARRAY(pEntry->pszPassword);
SAFE_DELETE_ARRAY(pEntry->pszAdditional);
SAFE_DELETE_ARRAY(pEntry->pszBinaryDesc);
SAFE_DELETE_ARRAY(pEntry->pBinaryData);
RESET_PWE_TEMPLATE(pEntry);
break;
default:
return FALSE; // Field unsupported
}
return TRUE; // Field processed
}
TCHAR *_UTF8ToStringV2(const UTF8_BYTE *pUTF8String)
{
DWORD i = 0, j = 0;
DWORD dwNumChars;
TCHAR *p;
BYTE b0, b1, b2;
TCHAR tch;
ASSERT(pUTF8String != NULL);
dwNumChars = _UTF8NumChars(pUTF8String);
if(dwNumChars == 0) return NULL;
p = new TCHAR[dwNumChars + 1];
ASSERT(p != NULL);
if(p == NULL) return NULL;
while(1)
{
b0 = pUTF8String[i]; i++;
if(b0 < 0x80)
{
p[j] = (TCHAR)b0; j++;
}
else
{
b1 = pUTF8String[i]; i++;
ASSERT((b1 & 0xC0) == 0x80);
if((b1 & 0xC0) != 0x80) break;
if((b0 & 0xE0) == 0xC0)
{
tch = (TCHAR)(b0 & 0x1F);
tch <<= 6;
tch |= (b1 & 0x3F);
p[j] = tch; j++;
}
else
{
b2 = pUTF8String[i]; i++;
ASSERT((b2 & 0xC0) == 0x80);
if((b2 & 0xC0) != 0x80) break;
tch = (TCHAR)(b0 & 0xF);
tch <<= 6;
tch |= (b1 & 0x3F);
tch <<= 6;
tch |= (b2 & 0x3F);
p[j] = tch; j++;
}
}
if(b0 == 0) break;
}
return p;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?