⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwmanager.cpp

📁 KeePassX用于保护密码的安全
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************** *   Copyright (C) 2005-2006 by Tarek Saidi                                * *   tarek.saidi@arcor.de                                                  * *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * *   This program is distributed in the hope that it will be useful,       * *   but WITHOUT ANY WARRANTY; without even the implied warranty of        * *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         * *   GNU General Public License for more details.                          * *                                                                         * *   You should have received a copy of the GNU General Public License     * *   along with this program; if not, write to the                         * *   Free Software Foundation, Inc.,                                       * *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             * ***************************************************************************/#include "global.h"#include <iostream>#include <time.h>#include <qfile.h>#include <qstringlist.h>#include <qobject.h>#include <qdatetime.h>#include <QSysInfo>#include <QBuffer>#include "crypto/sha256.h"#include "crypto/rijndael.h"#include "crypto/twoclass.h"#include "lib/random.h"using namespace std;#include "PwManager.h"#include "main.h"#define _ERROR Errors << QString("Unexpected error in: %1, Line:%2").arg(__FILE__).arg(__LINE__);QString PwDatabase::getError(){if(Errors.size()){QString r=Errors.front();Errors.pop_front();return r;}else return QString(tr("Unknown Error"));}QString PwDatabase::getErrors(){QString r;for(int i=0; i<Errors.size(); i++){	r+=Errors[i];	r+='\n';}Errors.clear();return r;}QList<int> PwDatabase::getChildIds(CGroup* group){if(!group)return QList<int>();int GroupIndex=Groups.indexOf(*group);int i;QList<int> ids;for(i=GroupIndex+1; i<Groups.size(); i++){ ids << Groups[i].ID; if(Groups[i].Level <= group->Level) break;}return ids;}bool PwDatabase::openDatabase(QString filename, QString& err){unsigned long total_size,crypto_size;quint32 Signature1,Signature2,Version,NumGroups,NumEntries,Flags;quint8 TrafoRandomSeed[32];quint8 FinalRandomSeed[16];quint8 ContentsHash[32];quint8 EncryptionIV[16];file=new QFile(filename);if(!file->open(QIODevice::ReadWrite)){	if(!file->open(QIODevice::ReadOnly)){		Errors << tr("Could not open file.");		delete file;		file=NULL;		return false;	}}total_size=file->size();char* buffer = new char[total_size];file->read(buffer,total_size);if(total_size < DB_HEADER_SIZE){err=tr("Unexpected file size (DB_TOTAL_SIZE < DB_HEADER_SIZE)");return false; }memcpyFromLEnd32(&Signature1,buffer);memcpyFromLEnd32(&Signature2,buffer+4);memcpyFromLEnd32(&Flags,buffer+8);memcpyFromLEnd32(&Version,buffer+12);memcpy(FinalRandomSeed,buffer+16,16);memcpy(EncryptionIV,buffer+32,16);memcpyFromLEnd32(&NumGroups,buffer+48);memcpyFromLEnd32(&NumEntries,buffer+52);memcpy(ContentsHash,buffer+56,32);memcpy(TrafoRandomSeed,buffer+88,32);memcpyFromLEnd32(&KeyEncRounds,buffer+120);if((Signature1!=PWM_DBSIG_1) || (Signature2!=PWM_DBSIG_2)){err=tr("Wrong Signature");return false;}if((Version & 0xFFFFFF00) != (PWM_DBVER_DW & 0xFFFFFF00)){	err=tr("Unsupported File Version.");	return false;}if(Flags & PWM_FLAG_RIJNDAEL) CryptoAlgorithmus = ALGO_AES;else if(Flags & PWM_FLAG_TWOFISH) CryptoAlgorithmus = ALGO_TWOFISH;else { err=tr("Unknown Encryption Algorithm."); return false; }transformKey(MasterKey,TransformedMasterKey,TrafoRandomSeed,KeyEncRounds);quint8 FinalKey[32];sha256_context sha32;sha256_starts(&sha32);sha256_update(&sha32,FinalRandomSeed, 16);sha256_update(&sha32,TransformedMasterKey, 32);sha256_finish(&sha32,FinalKey);if(CryptoAlgorithmus == ALGO_AES)	{		Rijndael aes;		// Initialize Rijndael algorithm		if(aes.init(Rijndael::CBC, Rijndael::Decrypt, FinalKey,			Rijndael::Key32Bytes, EncryptionIV) != RIJNDAEL_SUCCESS)			{err=tr("AES-Init Failed");			 return false;}		// Decrypt! The first bytes aren't encrypted (that's the header)		crypto_size = (unsigned long)aes.padDecrypt((quint8 *)buffer + DB_HEADER_SIZE,			total_size  - DB_HEADER_SIZE, (quint8 *)buffer + DB_HEADER_SIZE);	}else if(CryptoAlgorithmus == ALGO_TWOFISH)	{		CTwofish twofish;		if(twofish.init(FinalKey, 32, EncryptionIV) != true){return false;}		crypto_size = (unsigned long)twofish.padDecrypt((quint8 *)buffer + DB_HEADER_SIZE,			total_size - DB_HEADER_SIZE, (quint8 *)buffer + DB_HEADER_SIZE);	}if((crypto_size > 2147483446) || (!crypto_size && NumGroups)){err=tr("Decryption failed.\nThe key is wrong or the file is damaged."); return false;}sha256_starts(&sha32);sha256_update(&sha32,(unsigned char *)buffer + DB_HEADER_SIZE,crypto_size);sha256_finish(&sha32,(unsigned char *)FinalKey);if(memcmp(ContentsHash, FinalKey, 32) != 0){err=tr("Hash test failed.\nThe key is wrong or the file is damaged.");return false;}unsigned long tmp_id=0;unsigned long pos = DB_HEADER_SIZE;quint16 FieldType;quint32 FieldSize;char* pField;bool bRet;CGroup group;	for(unsigned long CurGroup = 0; CurGroup < NumGroups; )	{		pField = buffer+pos;		memcpyFromLEnd16(&FieldType, pField);		pField += 2; pos += 2;		if(pos >= total_size) {		 err=tr("Unexpected error: Offset is out of range. [G1]");		 return false; }		memcpyFromLEnd32(&FieldSize, pField);		pField += 4; pos += 4;		if(pos >= (total_size + FieldSize)){		 err=tr("Unexpected error: Offset is out of range. [G2]");		return false;}		bRet = group.ReadGroupField(FieldType, FieldSize, (quint8 *)pField);		if((FieldType == 0xFFFF) && (bRet == true)){			Groups << group;			CurGroup++;} // Now and ONLY now the counter gets increased		pField += FieldSize;		pos += FieldSize;		if(pos >= total_size) {		 err=tr("Unexpected error: Offset is out of range. [G1]");		 return false;}	}CEntry entry;	for(unsigned long CurEntry = 0; CurEntry < NumEntries;)	{		pField = buffer+pos;		memcpyFromLEnd16(&FieldType, pField);		pField += 2; pos += 2;		if(pos >= total_size){		 err=tr("Unexpected error: Offset is out of range. [E1]");		 return false;}		memcpyFromLEnd32(&FieldSize, pField);		pField += 4; pos += 4;		if(pos >= (total_size + FieldSize)) {		 err=tr("Unexpected error: Offset is out of range. [E2]");		 return false; }		bRet = entry.ReadEntryField(FieldType,FieldSize,(quint8*)pField);		if((FieldType == 0xFFFF) && (bRet == true)){						entry.sID=tmp_id++;			Entries << entry;			CurEntry++;} // Now and ONLY now the counter gets increased		pField += FieldSize;		pos += FieldSize;		if(pos >= total_size) {		 err=tr("Unexpected error: Offset is out of range. [E3]");		 return false; }	}unsigned long CurGID, g, e, z, num;delete [] buffer;for(int i=0;i<Entries.size();i++){if(IsMetaStream(Entries[i])==true){	if(!parseMetaStream(Entries[i]))		UnkownMetaStreams << Entries[i];	deleteEntry(&Entries[i]);	i--;}}return true;}bool PwDatabase::parseMetaStream(const CEntry& entry){if(entry.Additional=="KPX_CUSTOM_ICONS_2")	return parseCustomIconsMetaStream(entry.BinaryData);if(entry.Additional=="KPX_CUSTOM_ICONS")	return parseCustomIconsMetaStreamV1(entry.BinaryData); return false; //unknown MetaStream}CEntry* PwDatabase::getEntry(const KpxUuid& uuid){	for(int i=0; i<Entries.size();i++)		if(Entries[i].Uuid==uuid)return &Entries[i];	return NULL;}/* legacy function */bool PwDatabase::parseCustomIconsMetaStreamV1(const QByteArray& dta){return true;}bool PwDatabase::parseCustomIconsMetaStream(const QByteArray& dta){quint32 NumIcons,NumEntries,NumGroups,offset;memcpyFromLEnd32(&NumIcons,dta.data());memcpyFromLEnd32(&NumEntries,dta.data()+4);memcpyFromLEnd32(&NumGroups,dta.data()+8);offset=12;CustomIcons.clear();for(int i=0;i<NumIcons;i++){	CustomIcons << QPixmap();	quint32 Size;	memcpyFromLEnd32(&Size,dta.data()+offset);	if(offset+Size > dta.size()){		CustomIcons.clear();		return false;}	offset+=4;	if(!CustomIcons.back().loadFromData((const unsigned char*)dta.data()+offset,Size,"PNG")){		CustomIcons.clear();		return false;}	offset+=Size;	if(offset > dta.size()){		CustomIcons.clear();		return false;}}for(int i=0;i<NumEntries;i++){	quint32 Icon;	KpxUuid EntryUuid;	EntryUuid.fromRaw(dta.data()+offset);	offset+=16;	memcpyFromLEnd32(&Icon,dta.data()+offset);	offset+=4;	CEntry* entry=getEntry(EntryUuid);	if(entry){		entry->OldImgID=entry->ImageID;		entry->ImageID=Icon;	}}for(int i=0;i<NumGroups;i++){	quint32 Group,Icon;	memcpyFromLEnd32(&Group,dta.data()+offset);	offset+=4;	memcpyFromLEnd32(&Icon,dta.data()+offset);	offset+=4;	Groups[Group].OldImgID=Groups[Group].ImageID;	Groups[Group].ImageID=Icon;}return true;}void PwDatabase::createCustomIconsMetaStream(CEntry* e){/* Rev 2 */e->BinaryDesc="bin-stream";e->Title="Meta-Info";e->UserName="SYSTEM";e->Additional="KPX_CUSTOM_ICONS_2";e->URL="$";e->ImageID=0;if(Groups.size())e->GroupID=Groups[0].ID;int Size=12;quint32 NumEntries=Entries.size();quint32 NumGroups=Groups.size();Size+=8*NumGroups+20*NumEntries;Size+=CustomIcons.size()*1000; // 1KB e->BinaryData.reserve(Size);e->BinaryData.resize(12);quint32 NumIcons=CustomIcons.size();memcpyToLEnd32(e->BinaryData.data(),&NumIcons);memcpyToLEnd32(e->BinaryData.data()+4,&NumEntries);memcpyToLEnd32(e->BinaryData.data()+8,&NumGroups);for(int i=0;i<CustomIcons.size();i++){	quint32 ImgSize;	char ImgSizeBin[4];	QByteArray png;	png.reserve(1000);	QBuffer buffer(&png);	CustomIcons[i].save(&buffer,"PNG",0);	ImgSize=png.size();	memcpyToLEnd32(ImgSizeBin,&ImgSize);	e->BinaryData.append(QByteArray::fromRawData(ImgSizeBin,4));	e->BinaryData.append(png);}for(quint32 i=0;i<Entries.size();i++){		char Bin[20];		Entries[i].Uuid.toRaw(Bin);		quint32 id=Entries[i].ImageID;		memcpyToLEnd32(Bin+16,&id);		e->BinaryData.append(QByteArray::fromRawData(Bin,20));}for(quint32 i=0;i<Groups.size();i++){		char Bin[8];		memcpyToLEnd32(Bin,&i);		quint32 id=Groups[i].ImageID;		memcpyToLEnd32(Bin+4,&id);		e->BinaryData.append(QByteArray::fromRawData(Bin,8));}}int PwDatabase::numIcons(){return BUILTIN_ICONS+CustomIcons.size();}QPixmap& PwDatabase::icon(int i){if(i>=BUILTIN_ICONS+CustomIcons.size())	return EntryIcons[0];if(i<BUILTIN_ICONS)	return EntryIcons[i];return CustomIcons[i-BUILTIN_ICONS];}void PwDatabase::addIcon(const QPixmap& icon){CustomIcons << icon;emit iconsModified();}void PwDatabase::removeIcon(int id){id-=BUILTIN_ICONS;if(id < 0 ) return;if(id >= CustomIcons.size()) return;CustomIcons.removeAt(id); // .isNull()==truefor(int i=0;i<Entries.size();i++){	if(Entries[i].ImageID == id+BUILTIN_ICONS)		Entries[i].ImageID=Entries[i].OldImgID;	if(Entries[i].ImageID>id+BUILTIN_ICONS)		Entries[i].ImageID--;}for(int i=0;i<Groups.size();i++){	if(Groups[i].ImageID == id+BUILTIN_ICONS)		Groups[i].ImageID=Groups[i].OldImgID;	if(Groups[i].ImageID>id+BUILTIN_ICONS)		Groups[i].ImageID--;}emit iconsModified();}void PwDatabase::replaceIcon(int id,const QPixmap& icon){if(id<BUILTIN_ICONS)return;CustomIcons[id-BUILTIN_ICONS]=icon;emit iconsModified();}void PwDatabase::transformKey(quint8* src,quint8* dst,quint8* KeySeed,int rounds){quint8* tmp=new quint8[32];Rijndael rijndael;sha256_context sha2;if(rijndael.init(Rijndael::ECB, Rijndael::Encrypt, (const quint8 *)KeySeed,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -