git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@1 b624d157-de02-0410-bad0-e51aec6abb33master
@ -0,0 +1,9 @@ |
||||
# Diese Datei wurde mit dem qmake-Manager von KDevelop erstellt. |
||||
# ------------------------------------------- |
||||
# Unterverzeichnis relativ zum Projektverzeichnis: . |
||||
# Das Target ist Projekt im Unterverzeichnis |
||||
|
||||
CONFIG += release \ |
||||
warn_on |
||||
TEMPLATE = subdirs |
||||
SUBDIRS += src |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 634 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
@ -0,0 +1,57 @@ |
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Tarek Saidi * |
||||
* mail@tarek-saidi.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 "Database.h" |
||||
|
||||
|
||||
CEntry::CEntry(){ |
||||
ImageID=0; |
||||
GroupID=0; |
||||
Creation.SetToNow(); |
||||
LastMod.SetToNow(); |
||||
LastAccess.SetToNow(); |
||||
Expire.Set(28,12,2999,0,0,0); |
||||
BinaryDataLength=0; |
||||
pBinaryData=NULL; |
||||
} |
||||
|
||||
bool CGroup::UI_ExpandByDefault=true; |
||||
|
||||
CGroup::CGroup(){ |
||||
Creation.SetToNow(); |
||||
LastAccess.SetToNow(); |
||||
LastMod.SetToNow(); |
||||
Expire.Set(1,1,2999,0,0,0); |
||||
Level=0; |
||||
ImageID=0; |
||||
Name="<Group>"; |
||||
UI_ItemIsExpanded=UI_ExpandByDefault; |
||||
} |
||||
|
||||
CGroup::~CGroup(){ |
||||
} |
||||
|
||||
CEntry::~CEntry(){ |
||||
if(pBinaryData) { |
||||
delete [] pBinaryData; |
||||
} |
||||
pBinaryData=NULL; |
||||
|
||||
} |
@ -0,0 +1,99 @@ |
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Tarek Saidi * |
||||
* mail@tarek-saidi.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. * |
||||
***************************************************************************/ |
||||
#ifndef _DATABASE_H_ |
||||
#define _DATABASE_H_ |
||||
|
||||
#include <vector.h> |
||||
#include "lib/PwmTime.h" |
||||
#include "lib/SecString.h" |
||||
|
||||
class CEntry{ |
||||
public: |
||||
CEntry(); |
||||
~CEntry(); |
||||
UINT8 ID[16]; |
||||
UINT32 sID; |
||||
UINT32 GroupID; |
||||
UINT32 ImageID; |
||||
QString Title; |
||||
QString URL; |
||||
QString UserName; |
||||
SecString Password; |
||||
QString Additional; |
||||
QString BinaryDesc; |
||||
CPwmTime Creation; |
||||
CPwmTime LastMod; |
||||
CPwmTime LastAccess; |
||||
CPwmTime Expire; |
||||
UINT8 *pBinaryData; |
||||
UINT32 BinaryDataLength; |
||||
UINT32 PasswordLength; |
||||
bool ReadEntryField(UINT16 FieldType, UINT32 FieldSize, UINT8 *pData); |
||||
}; |
||||
|
||||
|
||||
class CGroup{ |
||||
public: |
||||
CGroup(); |
||||
~CGroup(); |
||||
UINT32 ID; |
||||
UINT32 ImageID; |
||||
UINT32 NumEntries; |
||||
QString Name; |
||||
CPwmTime Creation; |
||||
CPwmTime LastMod; |
||||
CPwmTime LastAccess; |
||||
CPwmTime Expire; |
||||
UINT16 Level; |
||||
UINT32 Flags; |
||||
bool ReadGroupField(UINT16 FieldType, UINT32 FieldSize, UINT8 *pData); |
||||
|
||||
bool UI_ItemIsExpanded; |
||||
static bool UI_ExpandByDefault; |
||||
|
||||
}; |
||||
|
||||
|
||||
typedef vector<CEntry>::iterator EntryItr; |
||||
typedef vector<CGroup>::iterator GroupItr; |
||||
|
||||
|
||||
class AbstractDatabase{ |
||||
public: |
||||
vector<CGroup>Groups; |
||||
vector<CEntry>Entries; |
||||
}; |
||||
|
||||
|
||||
|
||||
class Database:public AbstractDatabase{ |
||||
public: |
||||
int CryptoAlgorithmus; |
||||
int KeyEncRounds; |
||||
QString filename; |
||||
bool modflag; |
||||
int SearchGroupID; |
||||
|
||||
protected: |
||||
UINT8 MasterKey[32]; |
||||
UINT8 TransformedMasterKey[32]; |
||||
}; |
||||
|
||||
#endif |
@ -0,0 +1,155 @@ |
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Tarek Saidi * |
||||
* mail@tarek-saidi.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 "ListViews.h" |
||||
#include "PwManager.h" |
||||
#include <qstring.h> |
||||
#include <qlistview.h> |
||||
|
||||
|
||||
|
||||
GroupItem::GroupItem(CGroup* group, QListView * parent ) : QListViewItem(parent) |
||||
{ |
||||
pGroup=group; |
||||
setDropEnabled(true); |
||||
} |
||||
|
||||
GroupItem::GroupItem(CGroup* group, QListViewItem * parent ): QListViewItem(parent) |
||||
{ |
||||
pGroup=group; |
||||
setDropEnabled(true); |
||||
} |
||||
|
||||
GroupItem::GroupItem(CGroup* group, QListView * parent, QListViewItem * after ): QListViewItem(parent,after) |
||||
{ |
||||
pGroup=group; |
||||
setDropEnabled(true); |
||||
} |
||||
|
||||
GroupItem::GroupItem(CGroup* group, QListViewItem * parent, QListViewItem * after ): QListViewItem(parent,after) |
||||
{ |
||||
pGroup=group; |
||||
setDropEnabled(true); |
||||
} |
||||
|
||||
GroupItem::GroupItem(CGroup* group, QListView* parent, QString l1,QString l2,QString l3,QString l4, |
||||
QString l5,QString l6,QString l7,QString l8) |
||||
:QListViewItem(parent,l1,l2,l3,l4,l5,l6,l7,l8) |
||||
{ |
||||
pGroup=group; |
||||
setDropEnabled(true); |
||||
} |
||||
|
||||
GroupItem::GroupItem(CGroup* group, QListViewItem* parent, QString l1,QString l2,QString l3,QString l4, |
||||
QString l5,QString l6,QString l7,QString l8) |
||||
:QListViewItem(parent,l1,l2,l3,l4,l5,l6,l7,l8) |
||||
{ |
||||
pGroup=group; |
||||
setDropEnabled(true); |
||||
} |
||||
|
||||
GroupItem::GroupItem(CGroup* group, QListView* parent,QListViewItem* after, QString l1,QString l2,QString l3,QString l4, |
||||
QString l5,QString l6,QString l7,QString l8) |
||||
:QListViewItem(parent,after,l1,l2,l3,l4,l5,l6,l7,l8) |
||||
{ |
||||
pGroup=group; |
||||
setDropEnabled(true); |
||||
} |
||||
|
||||
GroupItem::GroupItem(CGroup* group, QListViewItem* parent,QListViewItem* after, QString l1,QString l2,QString l3,QString l4, |
||||
QString l5,QString l6,QString l7,QString l8) |
||||
:QListViewItem(parent,after,l1,l2,l3,l4,l5,l6,l7,l8) |
||||
{ |
||||
pGroup=group; |
||||
setDropEnabled(true); |
||||
} |
||||
|
||||
GroupItem::~GroupItem(){} |
||||
|
||||
|
||||
bool GroupItem::acceptDrop(const QMimeSource* mime){ |
||||
qDebug("DropEvent\n"); |
||||
return true; |
||||
} |
||||
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
EntryItem::EntryItem(CEntry* entry, QListView * parent ) : QListViewItem(parent) |
||||
{ |
||||
pEntry=entry; |
||||
setDragEnabled(true); |
||||
} |
||||
|
||||
EntryItem::EntryItem(CEntry* entry, QListViewItem * parent ): QListViewItem(parent) |
||||
{ |
||||
pEntry=entry; |
||||
setDragEnabled(true); |
||||
} |
||||
|
||||
EntryItem::EntryItem(CEntry* entry, QListView * parent, QListViewItem * after ): QListViewItem(parent,after) |
||||
{ |
||||
pEntry=entry; |
||||
setDragEnabled(true); |
||||
} |
||||
|
||||
EntryItem::EntryItem(CEntry* entry, QListViewItem * parent, QListViewItem * after ): QListViewItem(parent,after) |
||||
{ |
||||
pEntry=entry; |
||||
setDragEnabled(true); |
||||
} |
||||
|
||||
EntryItem::EntryItem(CEntry* entry, QListView* parent, QString l1,QString l2,QString l3,QString l4, |
||||
QString l5,QString l6,QString l7,QString l8) |
||||
:QListViewItem(parent,l1,l2,l3,l4,l5,l6,l7,l8) |
||||
{ |
||||
pEntry=entry; |
||||
setDragEnabled(true); |
||||
} |
||||
|
||||
EntryItem::EntryItem(CEntry* entry, QListViewItem* parent, QString l1,QString l2,QString l3,QString l4, |
||||
QString l5,QString l6,QString l7,QString l8) |
||||
:QListViewItem(parent,l1,l2,l3,l4,l5,l6,l7,l8) |
||||
{ |
||||
pEntry=entry; |
||||
setDragEnabled(true); |
||||
} |
||||
|
||||
EntryItem::EntryItem(CEntry* entry, QListView* parent,QListViewItem* after, QString l1,QString l2,QString l3,QString l4, |
||||
QString l5,QString l6,QString l7,QString l8) |
||||
:QListViewItem(parent,after,l1,l2,l3,l4,l5,l6,l7,l8) |
||||
{ |
||||
pEntry=entry; |
||||
setDragEnabled(true); |
||||
} |
||||
|
||||
EntryItem::EntryItem(CEntry* entry, QListViewItem* parent,QListViewItem* after, QString l1,QString l2,QString l3,QString l4, |
||||
QString l5,QString l6,QString l7,QString l8) |
||||
:QListViewItem(parent,after,l1,l2,l3,l4,l5,l6,l7,l8) |
||||
{ |
||||
pEntry=entry; |
||||
setDragEnabled(true); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
CGroupView::CGroupView(QWidget * parent, const char * name, WFlags f):QListView(parent,name,f){ |
||||
|
||||
}; |
@ -0,0 +1,108 @@ |
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Tarek Saidi * |
||||
* mail@tarek-saidi.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. * |
||||
***************************************************************************/ |
||||
#ifndef _LISTVIEWS_H_ |
||||
#define _LISTVIEWS_H_ |
||||
|
||||
#include <qlistview.h> |
||||
#include <qmime.h> |
||||
#include "PwManager.h" |
||||
|
||||
class GroupItem: public QListViewItem{ |
||||
public: |
||||
CGroup* pGroup; |
||||
virtual bool acceptDrop(const QMimeSource * mime); |
||||
///////////////////////////////////////////////////////////////////////
|
||||
GroupItem(CGroup*, QListView * parent ); |
||||
GroupItem(CGroup*, QListViewItem * parent ); |
||||
GroupItem(CGroup*, QListView * parent, QListViewItem * after ); |
||||
GroupItem(CGroup*, QListViewItem * parent, QListViewItem * after ); |
||||
|
||||
GroupItem(CGroup*, QListView * parent, |
||||
QString, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null ); |
||||
|
||||
GroupItem(CGroup*, QListViewItem * parent, |
||||
QString, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null ); |
||||
|
||||
GroupItem(CGroup*, QListView * parent, QListViewItem * after, |
||||
QString, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null ); |
||||
|
||||
GroupItem(CGroup*, QListViewItem * parent, QListViewItem * after, |
||||
QString, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null ); |
||||
~GroupItem(); |
||||
/////////////////////////////////////////////////////////////////////////
|
||||
}; |
||||
|
||||
|
||||
class EntryItem: public QListViewItem{ |
||||
public: |
||||
CEntry* pEntry; |
||||
///////////////////////////////////////////////////////////////////////
|
||||
EntryItem(CEntry*, QListView * parent ); |
||||
EntryItem(CEntry*, QListViewItem * parent ); |
||||
EntryItem(CEntry*, QListView * parent, QListViewItem * after ); |
||||
EntryItem(CEntry*, QListViewItem * parent, QListViewItem * after ); |
||||
|
||||
EntryItem(CEntry*, QListView * parent, |
||||
QString, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null ); |
||||
|
||||
EntryItem(CEntry*, QListViewItem * parent, |
||||
QString, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null ); |
||||
|
||||
EntryItem(CEntry*, QListView * parent, QListViewItem * after, |
||||
QString, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null ); |
||||
|
||||
EntryItem(CEntry*, QListViewItem * parent, QListViewItem * after, |
||||
QString, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null, |
||||
QString = QString::null, QString = QString::null ); |
||||
/////////////////////////////////////////////////////////////////////////
|
||||
}; |
||||
|
||||
|
||||
class CGroupView: public QListView{ |
||||
public: |
||||
CGroupView(QWidget * parent = 0, const char * name = 0, WFlags f = 0 ); |
||||
|
||||
|
||||
}; |
||||
|
||||
#endif |
@ -0,0 +1,915 @@ |
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 by Tarek Saidi * |
||||
* tarek@linux * |
||||
* * |
||||
* 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 <iostream.h> |
||||
#include <time.h> |
||||
#include <qfile.h> |
||||
#include <qstringlist.h> |
||||
#include <qobject.h> |
||||
#include <qdatetime.h> |
||||
#include "crypto/sha256.h" |
||||
#include "crypto/rijndael.h" |
||||
#include "crypto/twoclass.h" |
||||
#include "lib/random.h" |
||||
|
||||
#include "PwManager.h" |
||||
|
||||
bool PwDatabase::loadDatabase(QString _filename, QString& err){ |
||||
unsigned long total_size,crypto_size; |
||||
UINT32 Signature1,Signature2,Version,NumGroups,NumEntries,Flags; |
||||
UINT8 TrafoRandomSeed[32]; |
||||
UINT8 FinalRandomSeed[16]; |
||||
UINT8 ContentsHash[32]; |
||||
UINT8 EncryptionIV[16]; |
||||
|
||||
filename=_filename; |
||||
QFile file(filename); |
||||
file.open(IO_ReadOnly); |
||||
total_size=file.size(); |
||||
char* buffer = new char[total_size]; |
||||
file.readBlock(buffer,total_size); |
||||
file.close(); |
||||
|
||||
if(total_size < DB_HEADER_SIZE){ |
||||
err=trUtf8("Unerwartete Dateigröße (Dateigröße < DB_HEADER_SIZE)"); |
||||
return false; } |
||||
|
||||
memcpy(&Signature1,buffer,4); |
||||
memcpy(&Signature2,buffer+4,4); |
||||
memcpy(&Flags,buffer+8,4); |
||||
memcpy(&Version,buffer+12,4); |
||||
memcpy(FinalRandomSeed,buffer+16,16); |
||||
memcpy(EncryptionIV,buffer+32,16); |
||||
memcpy(&NumGroups,buffer+48,4); |
||||
memcpy(&NumEntries,buffer+52,4); |
||||
memcpy(ContentsHash,buffer+56,32); |
||||
memcpy(TrafoRandomSeed,buffer+88,32); |
||||
memcpy(&KeyEncRounds,buffer+120,4); |
||||
|
||||
if((Signature1!=PWM_DBSIG_1) || (Signature2!=PWM_DBSIG_2)){ |
||||
err=trUtf8("Falsche Signatur"); |
||||
return false;} |
||||
|
||||
|
||||
if((Version & 0xFFFFFF00) != (PWM_DBVER_DW & 0xFFFFFF00)){ |
||||
err=trUtf8("Nicht unterstüzte Dateiversion"); |
||||
return false;} |
||||
|
||||
if(Flags & PWM_FLAG_RIJNDAEL) CryptoAlgorithmus = ALGO_AES; |
||||
else if(Flags & PWM_FLAG_TWOFISH) CryptoAlgorithmus = ALGO_TWOFISH; |
||||
else { |
||||
err=trUtf8("Unbekannter Verschlüsselungsalgorithmus"); |
||||
return false; |
||||
} |
||||
|
||||
transformKey(MasterKey,TransformedMasterKey,TrafoRandomSeed,KeyEncRounds); |
||||
UINT8 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) |
||||
{return false;} |
||||
// Decrypt! The first bytes aren't encrypted (that's the header)
|
||||
crypto_size = (unsigned long)aes.padDecrypt((UINT8 *)buffer + DB_HEADER_SIZE, |
||||
total_size - DB_HEADER_SIZE, (UINT8 *)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((UINT8 *)buffer + DB_HEADER_SIZE, |
||||
total_size - DB_HEADER_SIZE, (UINT8 *)buffer + DB_HEADER_SIZE); |
||||
} |
||||
|
||||
if((crypto_size > 2147483446) || (crypto_size == 0)){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=trUtf8("Hash-Test fehlgeschlage: der Schlüssl ist falsch oder die Datei ist beschädigt."); |
||||
return false;} |
||||
|
||||
|
||||
Groups.resize(NumGroups); |
||||
Entries.resize(NumEntries); |
||||
|
||||
unsigned long tmp_id=0; |
||||
unsigned long pos = DB_HEADER_SIZE; |
||||
UINT16 FieldType; |
||||
UINT32 FieldSize; |
||||
char* pField; |
||||
bool bRet; |
||||
|
||||
|
||||
for(unsigned long CurGroup = 0; CurGroup < NumGroups; ) |
||||
{ |
||||
pField = buffer+pos; |
||||
|
||||
memcpy(&FieldType, pField, 2); |
||||
pField += 2; pos += 2; |
||||
if(pos >= total_size) { |
||||
return false; } |
||||
|
||||
memcpy(&FieldSize, pField, 4); |
||||
pField += 4; pos += 4; |
||||
if(pos >= (total_size + FieldSize)) { |
||||
return false;} |
||||
|
||||
bRet = Groups[CurGroup].ReadGroupField(FieldType, FieldSize, (UINT8 *)pField); |
||||
if((FieldType == 0xFFFF) && (bRet == true)){ |
||||
CurGroup++;} // Now and ONLY now the counter gets increased
|
||||
|
||||
pField += FieldSize; |
||||
pos += FieldSize; |
||||
if(pos >= total_size) { return false;} |
||||
} |
||||
|
||||
|
||||
for(unsigned long CurEntry = 0; CurEntry < NumEntries;) |
||||
{ |
||||
pField = buffer+pos; |
||||
|
||||
memcpy(&FieldType, pField, 2); |
||||
pField += 2; pos += 2; |
||||
if(pos >= total_size){ |
||||
return false;} |
||||
|
||||
memcpy(&FieldSize, pField, 4); |
||||
pField += 4; pos += 4; |
||||
if(pos >= (total_size + FieldSize)) { |
||||
return false; } |
||||
|
||||
bRet = Entries[CurEntry].ReadEntryField(FieldType,FieldSize,(UINT8*)pField); |
||||
if((FieldType == 0xFFFF) && (bRet == true)){ |
||||
Entries[CurEntry].sID=tmp_id++; |
||||
CurEntry++;} // Now and ONLY now the counter gets increased
|
||||
|
||||
pField += FieldSize; |
||||
pos += FieldSize; |
||||
if(pos >= total_size) { |
||||
return false; } |
||||
} |
||||
|
||||
unsigned long CurGID, g, e, z, num; |
||||
delete [] buffer; |
||||
|
||||
for(vector<CEntry>::iterator i=Entries.begin();i!=Entries.end();i++){ |
||||
if(IsMetaStream(*i)==true){ |
||||
///@TODO Parse Metastreams
|
||||
deleteEntry(i); |
||||
i--; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
|
||||
void PwDatabase::transformKey(UINT8* src,UINT8* dst,UINT8* KeySeed,int rounds){ |
||||
UINT8* tmp=new UINT8[32]; |
||||
Rijndael rijndael; |
||||
sha256_context sha2; |
||||
if(rijndael.init(Rijndael::ECB, Rijndael::Encrypt, (const UINT8 *)KeySeed, |
||||
Rijndael::Key32Bytes, 0) != RIJNDAEL_SUCCESS){ |
||||
cout << QString("unexpected error in %1, line %2").arg(__FILE__).arg(__LINE__) << endl; |
||||
exit(1);} |
||||
|
||||
memcpy(tmp,src,32); |
||||
for(int i=0;i<rounds;i++){ |
||||
rijndael.blockEncrypt((const UINT8 *)tmp, 256, (UINT8 *)tmp); |
||||
} |
||||
|
||||
sha256_starts(&sha2); |
||||
sha256_update(&sha2,tmp,32); |
||||
sha256_finish(&sha2,tmp); |
||||
|
||||
memcpy(dst,tmp,32); |
||||
delete [] tmp; |
||||
} |
||||
|
||||
bool PwDatabase::CalcMasterKeyByPassword(QString& Password){ |
||||
|
||||
unsigned long KeyLen, FileSize, Read; |
||||
sha256_context sha32; |
||||
char *paKey = NULL; |
||||
|
||||
if(Password == QString::null) return false; |
||||
|
||||
paKey = new char[Password.length() + 1]; |
||||
if(paKey == NULL) return false; |
||||
strcpy(paKey, Password); |
||||
|
||||
|
||||
|
||||
if(paKey == NULL) return false; |
||||
|
||||
KeyLen = strlen(paKey); |
||||
|
||||
if(KeyLen == 0) { |
||||
SecString::overwrite(paKey,Password.length() + 1); |
||||
delete [] paKey; |
||||
return false; } |
||||
|
||||
sha256_starts(&sha32); |
||||
sha256_update(&sha32,(unsigned char*) paKey, KeyLen); |
||||
sha256_finish(&sha32,MasterKey); |
||||
SecString::overwrite(paKey,Password.length() + 1); |
||||
delete [] paKey; |
||||
return true; |
||||
} |
||||
|
||||
|
||||
bool PwDatabase::CalcMasterKeyByFile(QString filename){ |
||||
|
||||
QFile file(filename); |
||||
if(file.open(IO_ReadOnly) == false) return false; |
||||
unsigned long FileSize=file.size(); |
||||
|
||||
if(FileSize == 32){ |
||||
if(file.readBlock((char*)MasterKey,32) != 32){ |
||||
file.close(); |
||||
return false;} |
||||
} |
||||
else |
||||
{ |
||||
sha256_context sha32; |
||||
sha256_starts(&sha32); |
||||
unsigned char* buffer = new unsigned char[2048]; |
||||
while(1) |
||||
{ |
||||
unsigned long read=file.readBlock((char*)buffer,2048); |
||||
if(read == 0) break; |
||||
sha256_update(&sha32,buffer,read); |
||||
if(read != 2048) break; |
||||
} |
||||
sha256_finish(&sha32,MasterKey); |
||||
delete [] buffer; |
||||
} |
||||
|
||||
file.close(); |
||||
return true; |
||||
} |
||||
|
||||
|
||||
CEntry* PwDatabase::addEntry(){ |
||||
CEntry NewEntry; |
||||
if(Entries.size()==0){ |
||||
NewEntry.sID=0; |
||||
getRandomBytes(&NewEntry.ID,16,1,false); |
||||
} |
||||
else { |
||||
NewEntry.sID=(*(Entries.end()-1)).sID+1; |
||||
while(1){ |
||||
bool used=false; |
||||
getRandomBytes(&NewEntry.ID,16,1,false); |
||||
for(int j=0;j<Entries.size();j++){ |
||||
int k; |
||||
for(k=0;k<16;k++){if(Entries[j].ID[k]!=NewEntry.ID[k])k=0;break;} |
||||
if(k==15)used=true;} |
||||
if(used==false)break; |
||||
}} |
||||
Entries.push_back(NewEntry); |
||||
return &Entries.back(); |
||||
} |
||||
|
||||
|
||||
bool PwDatabase::CalcMasterKeyByFileAndPw(QString filename, QString& Password){ |
||||
UINT8* FileKey; |
||||
UINT8* PasswordKey; |
||||
PasswordKey=new UINT8[32]; |
||||
FileKey=new UINT8[32]; |
||||
sha256_context sha32; |
||||
/////////////////////////
|
||||
QFile file(filename); |
||||
if(file.open(IO_ReadOnly) == false) return false; |
||||
unsigned long FileSize=file.size(); |
||||
if(FileSize == 32){ |
||||
if(file.readBlock((char*)FileKey,32) != 32){ |
||||
file.close(); |
||||
return false;} |
||||
} |
||||
else{ |
||||
sha256_starts(&sha32); |
||||
unsigned char* buffer = new unsigned char[2048]; |
||||
while(1) |
||||
{ |
||||
unsigned long read=file.readBlock((char*)buffer,2048); |
||||
if(read == 0) break; |
||||
sha256_update(&sha32,buffer,read); |
||||
if(read != 2048) break; |
||||
} |
||||
sha256_finish(&sha32,FileKey); |
||||
delete [] buffer; |
||||
} |
||||
file.close(); |
||||
|
||||
//////////////////////
|
||||
|
||||
unsigned long KeyLen; |
||||
char *paKey = NULL; |
||||
if(Password == QString::null) return false; |
||||
paKey = new char[Password.length() + 1]; |
||||
if(paKey == NULL) return false; |
||||
strcpy(paKey, Password); |
||||
if(paKey == NULL) return false; |
||||
KeyLen = strlen(paKey); |
||||
if(KeyLen == 0) { |
||||
delete [] paKey; |
||||
return false; } |
||||
sha256_starts(&sha32); |
||||
sha256_update(&sha32,(unsigned char*) paKey, KeyLen); |
||||
sha256_finish(&sha32,PasswordKey); |
||||
delete [] paKey; |
||||
////////////////////
|
||||
sha256_starts(&sha32); |
||||
sha256_update(&sha32,(unsigned char*)PasswordKey,32); |
||||
sha256_update(&sha32,(unsigned char*)FileKey,32); |
||||
sha256_finish(&sha32,MasterKey); |
||||
delete[] PasswordKey; |
||||
delete[] FileKey; |
||||
} |
||||
|
||||
|
||||
vector<CEntry>::iterator PwDatabase::deleteEntry(vector<CEntry>::iterator iterator){ |
||||
return Entries.erase(iterator); |
||||
} |
||||
|
||||
vector<CEntry>::iterator PwDatabase::deleteEntry(CEntry* entry){ |
||||
return deleteEntry(getEntryIterator(entry)); |
||||
} |
||||
|
||||
bool PwDatabase::IsMetaStream(CEntry& p){ |
||||
|
||||
if(p.pBinaryData == NULL) return false; |
||||
if(p.Additional == NULL) return false; |
||||
if(p.BinaryDesc == NULL) return false; |
||||
if(p.BinaryDesc != "bin-stream") return false; |
||||
if(p.Title == NULL) return false; |
||||
if(p.Title != "Meta-Info") return false; |
||||
if(p.UserName == NULL) return false; |
||||
if(p.UserName != "SYSTEM") return false; |
||||
if(p.URL == NULL) return false; |
||||
if(p.URL != "$") return false; |
||||
if(p.ImageID != 0) return false; |
||||
return true; |
||||
} |
||||
|
||||
|
||||
|
||||
void PwDatabase::moveEntry(CEntry* entry,CGroup* dst){ |
||||
entry->GroupID=dst->ID; |
||||
} |
||||
|
||||
|
||||
|
||||
bool CGroup::ReadGroupField(UINT16 FieldType, UINT32 FieldSize, UINT8 *pData) |
||||
{ |
||||
|
||||
switch(FieldType) |
||||
{ |
||||
case 0x0000: |
||||
// Ignore field
|
||||
break; |
||||
case 0x0001: |
||||
memcpy(&ID, pData, 4); |
||||
break; |
||||
case 0x0002: |
||||
//Name.fromUtf8((char*)pData);
|
||||
Name=QString::fromUtf8((char*)pData); |
||||
break; |
||||
case 0x0003: |
||||
Creation.Set(pData); |
||||
break; |
||||
case 0x0004: |
||||
LastMod.Set(pData); |
||||
break; |
||||
case 0x0005: |
||||
LastAccess.Set(pData); |
||||
break; |
||||
case 0x0006: |
||||
Expire.Set(pData); |
||||
break; |
||||
case 0x0007: |
||||
memcpy(&ImageID, pData, 4); |
||||
break; |
||||
case 0x0008: |
||||
memcpy(&Level, pData, 2); |
||||
break; |
||||
case 0x0009: |
||||
memcpy(&Flags, pData, 4); |
||||
break; |
||||
case 0xFFFF: |
||||
break; |
||||
default: |
||||
return false; // Field unsupported
|
||||
} |
||||
|
||||
return true; // Field supported
|
||||
} |
||||
|
||||
PwDatabase::PwDatabase(){ |
||||
SearchGroupID=-1; |
||||
} |
||||
|
||||
PwDatabase::~PwDatabase(){ |
||||
|
||||
} |
||||
|
||||
|
||||
bool CEntry::ReadEntryField(UINT16 FieldType, UINT32 FieldSize, UINT8 *pData){ |
||||
|
||||
|
||||
switch(FieldType) |
||||
{ |
||||
case 0x0000: |
||||
// Ignore field
|
||||
break; |
||||
case 0x0001: |
||||
memcpy(ID, pData, 16); |
||||
break; |
||||
case 0x0002: |
||||
memcpy(&GroupID, pData, 4); |
||||
break; |
||||
case 0x0003: |
||||
memcpy(&ImageID, pData, 4); |
||||
break; |
||||
case 0x0004: |
||||
//Title=(char*)pData;
|
||||
Title=QString::fromUtf8((char*)pData); |
||||
break; |
||||
case 0x0005: |
||||
URL=QString::fromUtf8((char*)pData); |
||||
break; |
||||
case 0x0006: |
||||
UserName=QString::fromUtf8((char*)pData); |
||||
break; |
||||
case 0x0007:{ |
||||
QString s=QString::fromUtf8((char*)pData); |
||||
Password.setString(s,true); |
||||
break;} |
||||
case 0x0008: |
||||
Additional=QString::fromUtf8((char*)pData); |
||||
break; |
||||
case 0x0009: |
||||
Creation.Set(pData); |
||||
break; |
||||
case 0x000A: |
||||
LastMod.Set(pData); |
||||
break; |
||||
case 0x000B: |
||||
LastAccess.Set(pData); |
||||
break; |
||||
case 0x000C: |
||||
Expire.Set(pData); |
||||
break; |
||||
case 0x000D: |
||||
BinaryDesc=(char*)pData; |
||||
break; |
||||
case 0x000E: |
||||
if(FieldSize != 0) |
||||
{ |
||||
///@TODO: im Destruktor löschen
|
||||
///@TODO: im Konstruktor auf Null
|
||||
pBinaryData = new UINT8[FieldSize]; |
||||
memcpy(pBinaryData, pData, FieldSize); |
||||
BinaryDataLength = FieldSize; |
||||
} |
||||
else |
||||
{pBinaryData=0;} |
||||
break; |
||||
case 0xFFFF: |
||||
///@TODO: Alle Elemente geladen - Status setzen oder so was
|
||||
break; |
||||
default: |
||||
return false; // Field unsupported
|
||||
} |
||||
|
||||
return true; // Field processed
|
||||
} |
||||
|
||||
bool PwDatabase::CloseDataBase(){ |
||||
Groups.clear(); |
||||
Entries.clear(); |
||||
return true; |
||||
} |
||||
|
||||
bool PwDatabase::SaveDataBase(QString filename){ |
||||
CGroup SearchGroup; |
||||
UINT32 NumGroups,NumEntries,Signature1,Signature2,Flags,Version; |
||||
UINT8 TrafoRandomSeed[32]; |
||||
UINT8 FinalRandomSeed[16]; |
||||
UINT8 ContentsHash[32]; |
||||
UINT8 EncryptionIV[16]; |
||||
|
||||
if(SearchGroupID!=-1){ |
||||
for(int i=0;i<Groups.size();i++){ |
||||
if(Groups[i].ID==SearchGroupID){ |
||||
SearchGroup=Groups[i]; |
||||
Groups.erase(getGroupIterator(&Groups[i]));} |
||||
} |
||||
} |
||||
if(filename==QString::null)return false; |
||||
QFile file(filename); |
||||
unsigned int FileSize; |
||||
|
||||
//->Add Metastreams
|
||||
FileSize=DB_HEADER_SIZE; |
||||
// Get the size of all groups (94 Byte + length of the name string)
|
||||
for(int i = 0; i < Groups.size(); i++){ |
||||
FileSize += 94 + Groups[i].Name.utf8().length()+1; |
||||
|