changed encryption method of SecStrings from Rijndael to ArcFour (much faster)
git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@49 b624d157-de02-0410-bad0-e51aec6abb33
This commit is contained in:
parent
68f1d12d74
commit
f89372b0c5
|
@ -201,6 +201,7 @@ CEntry entry;
|
||||||
return false; }
|
return false; }
|
||||||
|
|
||||||
bRet = entry.ReadEntryField(FieldType,FieldSize,(Q_UINT8*)pField);
|
bRet = entry.ReadEntryField(FieldType,FieldSize,(Q_UINT8*)pField);
|
||||||
|
|
||||||
if((FieldType == 0xFFFF) && (bRet == true)){
|
if((FieldType == 0xFFFF) && (bRet == true)){
|
||||||
entry.sID=tmp_id++;
|
entry.sID=tmp_id++;
|
||||||
Entries << entry;
|
Entries << entry;
|
||||||
|
@ -272,14 +273,14 @@ if(paKey == NULL) return false;
|
||||||
KeyLen = strlen(paKey);
|
KeyLen = strlen(paKey);
|
||||||
|
|
||||||
if(KeyLen == 0) {
|
if(KeyLen == 0) {
|
||||||
SecString::overwrite(paKey,Password.length() + 1);
|
SecString::overwrite((unsigned char*)paKey,Password.length() + 1);
|
||||||
delete [] paKey;
|
delete [] paKey;
|
||||||
return false; }
|
return false; }
|
||||||
|
|
||||||
sha256_starts(&sha32);
|
sha256_starts(&sha32);
|
||||||
sha256_update(&sha32,(unsigned char*) paKey, KeyLen);
|
sha256_update(&sha32,(unsigned char*) paKey, KeyLen);
|
||||||
sha256_finish(&sha32,MasterKey);
|
sha256_finish(&sha32,MasterKey);
|
||||||
SecString::overwrite(paKey,Password.length() + 1);
|
SecString::overwrite((unsigned char*)paKey,Password.length() + 1);
|
||||||
delete [] paKey;
|
delete [] paKey;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -530,7 +531,6 @@ switch(FieldType)
|
||||||
memcpyFromLEnd32(&ImageID, (char*)pData);
|
memcpyFromLEnd32(&ImageID, (char*)pData);
|
||||||
break;
|
break;
|
||||||
case 0x0004:
|
case 0x0004:
|
||||||
//Title=(char*)pData;
|
|
||||||
Title=QString::fromUtf8((char*)pData);
|
Title=QString::fromUtf8((char*)pData);
|
||||||
break;
|
break;
|
||||||
case 0x0005:
|
case 0x0005:
|
||||||
|
@ -723,8 +723,9 @@ for(int i = 0; i < Entries.size(); i++){
|
||||||
FieldSize = Entries[i].Password.length() + 1; // Add terminating NULL character space
|
FieldSize = Entries[i].Password.length() + 1; // Add terminating NULL character space
|
||||||
memcpyToLEnd16(buffer+pos, &FieldType); pos += 2;
|
memcpyToLEnd16(buffer+pos, &FieldType); pos += 2;
|
||||||
memcpyToLEnd32(buffer+pos, &FieldSize); pos += 4;
|
memcpyToLEnd32(buffer+pos, &FieldSize); pos += 4;
|
||||||
memcpy(buffer+pos, Entries[i].Password.getString(),FieldSize); pos += FieldSize;
|
Entries[i].Password.unlock();
|
||||||
Entries[i].Password.delRef();
|
memcpy(buffer+pos, Entries[i].Password.string(),FieldSize); pos += FieldSize;
|
||||||
|
Entries[i].Password.lock();
|
||||||
|
|
||||||
FieldType = 0x0008;
|
FieldType = 0x0008;
|
||||||
FieldSize = Entries[i].Additional.utf8().length() + 1; // Add terminating NULL character space
|
FieldSize = Entries[i].Additional.utf8().length() + 1; // Add terminating NULL character space
|
||||||
|
@ -1225,8 +1226,12 @@ void assertEntriesEq(KPTestResults& results, CEntry* left, CEntry* right){
|
||||||
kp_assert(results, left->UserName == right->UserName);
|
kp_assert(results, left->UserName == right->UserName);
|
||||||
size += sizeof(left->UserName);
|
size += sizeof(left->UserName);
|
||||||
|
|
||||||
kp_assert(results, left->Password.getString() == right->Password.getString());
|
left->Password.unlock();
|
||||||
|
right->Password.unlock();
|
||||||
|
kp_assert(results, left->Password.string() == right->Password.string());
|
||||||
size += sizeof(left->Password);
|
size += sizeof(left->Password);
|
||||||
|
left->Password.lock();
|
||||||
|
right->Password.lock();
|
||||||
|
|
||||||
kp_assert(results, left->Additional == right->Additional);
|
kp_assert(results, left->Additional == right->Additional);
|
||||||
size += sizeof(left->Additional);
|
size += sizeof(left->Additional);
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* 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 <QByteArray>
|
||||||
|
#include "arcfour.h"
|
||||||
|
|
||||||
|
|
||||||
|
static inline void swap_byte(unsigned char *a, unsigned char *b)
|
||||||
|
{
|
||||||
|
unsigned char swapByte;
|
||||||
|
|
||||||
|
swapByte = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b = swapByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CArcFour::setKey(byte* key_data_ptr, int key_data_len){
|
||||||
|
RawKey=QByteArray((const char*)key_data_ptr,key_data_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CArcFour::prepareKey(){
|
||||||
|
unsigned char swapByte;
|
||||||
|
unsigned char index1;
|
||||||
|
unsigned char index2;
|
||||||
|
unsigned char* state;
|
||||||
|
short counter;
|
||||||
|
|
||||||
|
state = &key.state[0];
|
||||||
|
for(counter = 0; counter < 256; counter++)
|
||||||
|
state[counter] = counter;
|
||||||
|
key.x = 0;
|
||||||
|
key.y = 0;
|
||||||
|
index1 = 0;
|
||||||
|
index2 = 0;
|
||||||
|
for(counter = 0; counter < 256; counter++)
|
||||||
|
{
|
||||||
|
index2 = (RawKey.at(index1) + state[counter] + index2) % 256;
|
||||||
|
swap_byte(&state[counter], &state[index2]);
|
||||||
|
index1 = (index1 + 1) % RawKey.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CArcFour::encrypt(const byte* src, byte* dst,int length){
|
||||||
|
//qDebug("Key:%s",RawKey.data());
|
||||||
|
prepareKey();
|
||||||
|
unsigned char x;
|
||||||
|
unsigned char y;
|
||||||
|
unsigned char* state;
|
||||||
|
unsigned char xorIndex;
|
||||||
|
short counter;
|
||||||
|
|
||||||
|
x = key.x;
|
||||||
|
y = key.y;
|
||||||
|
|
||||||
|
state = &key.state[0];
|
||||||
|
for(counter = 0; counter < length; counter ++)
|
||||||
|
{
|
||||||
|
x = (x + 1) % 256;
|
||||||
|
y = (state[x] + y) % 256;
|
||||||
|
swap_byte(&state[x], &state[y]);
|
||||||
|
|
||||||
|
xorIndex = (state[x] + state[y]) % 256;
|
||||||
|
|
||||||
|
dst[counter]=src[counter]^state[xorIndex];
|
||||||
|
}
|
||||||
|
key.x = x;
|
||||||
|
key.y = y;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _ARCFOUR_H_
|
||||||
|
#define _ARCFOUR_H_
|
||||||
|
|
||||||
|
#ifndef byte
|
||||||
|
#define byte unsigned char
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class CArcFour{
|
||||||
|
public:
|
||||||
|
void encrypt(const byte* src, byte* dst,int length);
|
||||||
|
inline void decrypt(const byte* src, byte* dst,int length){encrypt(src,dst,length);} //just for readability
|
||||||
|
void setKey(byte* key, int length);
|
||||||
|
QByteArray RawKey;
|
||||||
|
private:
|
||||||
|
void prepareKey();
|
||||||
|
|
||||||
|
typedef struct rc4_key{
|
||||||
|
byte state[256];
|
||||||
|
byte x;
|
||||||
|
byte y;}rc4_key;
|
||||||
|
rc4_key key;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -77,9 +77,10 @@ setIcon(EntryIcons[entry->ImageID]);
|
||||||
Edit_Title->setText(entry->Title);
|
Edit_Title->setText(entry->Title);
|
||||||
Edit_UserName->setText(entry->UserName);
|
Edit_UserName->setText(entry->UserName);
|
||||||
Edit_URL->setText(entry->URL);
|
Edit_URL->setText(entry->URL);
|
||||||
Edit_Password->setText(entry->Password.getString());
|
entry->Password.unlock();
|
||||||
Edit_Password_w->setText(entry->Password.getString());
|
Edit_Password->setText(entry->Password.string());
|
||||||
entry->Password.delRef();
|
Edit_Password_w->setText(entry->Password.string());
|
||||||
|
entry->Password.lock();
|
||||||
if(!config.ShowPasswords)
|
if(!config.ShowPasswords)
|
||||||
ChangeEchoMode();
|
ChangeEchoMode();
|
||||||
OnPasswordwLostFocus();
|
OnPasswordwLostFocus();
|
||||||
|
@ -171,10 +172,10 @@ if(entry->URL!=Edit_URL->text())
|
||||||
ModFlag=true;
|
ModFlag=true;
|
||||||
if(entry->Additional!=Edit_Comment->text())
|
if(entry->Additional!=Edit_Comment->text())
|
||||||
ModFlag=true;
|
ModFlag=true;
|
||||||
QString& passw=entry->Password.getString();
|
entry->Password.unlock();
|
||||||
if(passw!=Edit_Password->text())
|
if(entry->Password.string()!=Edit_Password->text())
|
||||||
ModFlag=true;
|
ModFlag=true;
|
||||||
entry->Password.delRef();
|
entry->Password.lock();
|
||||||
|
|
||||||
entry->Expire=DateTime_Expire->dateTime();
|
entry->Expire=DateTime_Expire->dateTime();
|
||||||
entry->LastAccess=QDateTime::currentDateTime();
|
entry->LastAccess=QDateTime::currentDateTime();
|
||||||
|
|
|
@ -99,8 +99,9 @@ bool hit=false;
|
||||||
if(checkBox_URL->isChecked()) hit=hit||search(db->Entries[i].URL);
|
if(checkBox_URL->isChecked()) hit=hit||search(db->Entries[i].URL);
|
||||||
if(checkBox_Comment->isChecked()) hit=hit||search(db->Entries[i].Additional);
|
if(checkBox_Comment->isChecked()) hit=hit||search(db->Entries[i].Additional);
|
||||||
if(checkBox_Attachment->isChecked()) hit=hit||search(db->Entries[i].BinaryDesc);
|
if(checkBox_Attachment->isChecked()) hit=hit||search(db->Entries[i].BinaryDesc);
|
||||||
if(checkBox_Password->isChecked()) hit=hit||search(db->Entries[i].Password.getString());
|
db->Entries[i].Password.unlock();
|
||||||
db->Entries[i].Password.delRef();
|
if(checkBox_Password->isChecked()) hit=hit||search(db->Entries[i].Password.string());
|
||||||
|
db->Entries[i].Password.lock();
|
||||||
if(hit)Hits.push_back(db->Entries[i].sID);
|
if(hit)Hits.push_back(db->Entries[i].sID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ done(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CSearchDlg::search(QString& str){
|
bool CSearchDlg::search(const QString& str){
|
||||||
|
|
||||||
if(regexp){
|
if(regexp){
|
||||||
QRegExp exp(txt,checkBox_Cs->isChecked());
|
QRegExp exp(txt,checkBox_Cs->isChecked());
|
||||||
|
|
|
@ -41,7 +41,7 @@ private:
|
||||||
CGroup* group;
|
CGroup* group;
|
||||||
bool regexp;
|
bool regexp;
|
||||||
PwDatabase* db;
|
PwDatabase* db;
|
||||||
bool search(QString& str);
|
bool search(const QString& str);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -69,14 +69,31 @@ ContextMenu->popup(e->globalPos());
|
||||||
|
|
||||||
|
|
||||||
void KeepassEntryView::updateItems(unsigned int GroupID){
|
void KeepassEntryView::updateItems(unsigned int GroupID){
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
Items.clear();
|
Items.clear();
|
||||||
if(!db)return;
|
if(!db)return;
|
||||||
if(!GroupID)return;
|
if(!GroupID)return;
|
||||||
EntryViewItem *tmp=NULL;
|
|
||||||
for(int i=0;i<db->Entries.size();i++){
|
for(int i=0;i<db->Entries.size();i++){
|
||||||
CEntry* entry=&db->Entries[i];
|
if(db->Entries[i].GroupID==GroupID)
|
||||||
if(entry->GroupID==GroupID){
|
setEntry(&db->Entries[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeepassEntryView::showSearchResults(QList<Q_UINT32>& results){
|
||||||
|
clear();
|
||||||
|
Items.clear();
|
||||||
|
for(int j=0; j<results.size(); j++){
|
||||||
|
for(int i=0; i<db->Entries.size();i++){
|
||||||
|
if(db->Entries[i].sID == results[j])
|
||||||
|
setEntry(&db->Entries[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeepassEntryView::setEntry(CEntry* entry){
|
||||||
|
EntryViewItem* tmp=NULL;
|
||||||
Items.push_back(tmp=new EntryViewItem(this));
|
Items.push_back(tmp=new EntryViewItem(this));
|
||||||
Items.back()->pEntry=entry;
|
Items.back()->pEntry=entry;
|
||||||
int j=0;
|
int j=0;
|
||||||
|
@ -93,8 +110,9 @@ for(int i=0;i<db->Entries.size();i++){
|
||||||
if(config.ListView_HidePasswords)
|
if(config.ListView_HidePasswords)
|
||||||
tmp->setText(j++,"******");
|
tmp->setText(j++,"******");
|
||||||
else{
|
else{
|
||||||
tmp->setText(j++,entry->Password.getString());
|
entry->Password.unlock();
|
||||||
entry->Password.delRef();}}
|
tmp->setText(j++,entry->Password.string());
|
||||||
|
entry->Password.lock();}}
|
||||||
if(config.Columns[4]){
|
if(config.Columns[4]){
|
||||||
tmp->setText(j++,entry->Additional.section('\n',0,0));}
|
tmp->setText(j++,entry->Additional.section('\n',0,0));}
|
||||||
if(config.Columns[5]){
|
if(config.Columns[5]){
|
||||||
|
@ -108,17 +126,6 @@ for(int i=0;i<db->Entries.size();i++){
|
||||||
if(config.Columns[9]){
|
if(config.Columns[9]){
|
||||||
tmp->setText(j++,entry->BinaryDesc);}
|
tmp->setText(j++,entry->BinaryDesc);}
|
||||||
Items.back()->setIcon(0,EntryIcons[entry->ImageID]);
|
Items.back()->setIcon(0,EntryIcons[entry->ImageID]);
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeepassEntryView::showSearchResults(QList<Q_UINT32>& results){
|
|
||||||
updateItems(0);
|
|
||||||
for(int j=0; j<results.size(); j++){
|
|
||||||
for(int i=0; i<Items.size();i++){
|
|
||||||
if(Items[i]->pEntry->sID == results[j])
|
|
||||||
setItemHidden(Items[i],false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeepassEntryView::refreshItems(){
|
void KeepassEntryView::refreshItems(){
|
||||||
|
@ -141,8 +148,9 @@ for(int i=0;i<Items.size();i++){
|
||||||
if(config.ListView_HidePasswords)
|
if(config.ListView_HidePasswords)
|
||||||
tmp->setText(j++,"******");
|
tmp->setText(j++,"******");
|
||||||
else{
|
else{
|
||||||
tmp->setText(j++,entry->Password.getString());
|
entry->Password.unlock();
|
||||||
entry->Password.delRef();}}
|
tmp->setText(j++,entry->Password.string());
|
||||||
|
entry->Password.lock();}}
|
||||||
if(config.Columns[4]){
|
if(config.Columns[4]){
|
||||||
tmp->setText(j++,entry->Additional.section('\n',0,0));}
|
tmp->setText(j++,entry->Additional.section('\n',0,0));}
|
||||||
if(config.Columns[5]){
|
if(config.Columns[5]){
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
vector<EntryViewItem*>Items;
|
vector<EntryViewItem*>Items;
|
||||||
QMenu *ContextMenu;
|
QMenu *ContextMenu;
|
||||||
private:
|
private:
|
||||||
|
void setEntry(CEntry* entry);
|
||||||
int CurrentGroup;
|
int CurrentGroup;
|
||||||
protected:
|
protected:
|
||||||
virtual void contextMenuEvent(QContextMenuEvent *event);
|
virtual void contextMenuEvent(QContextMenuEvent *event);
|
||||||
|
|
|
@ -19,83 +19,89 @@
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "SecString.h"
|
#include "SecString.h"
|
||||||
#include <qmessagebox.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "crypto/arcfour.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
Q_UINT8 SecString::Key[32]={0};
|
CArcFour SecString::RC4;
|
||||||
|
|
||||||
|
SecString::operator QString(){
|
||||||
|
return string();
|
||||||
|
}
|
||||||
|
|
||||||
SecString::SecString(){
|
SecString::SecString(){
|
||||||
len=0;
|
locked=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SecString::length(){
|
||||||
|
return crypt.size();
|
||||||
|
}
|
||||||
|
|
||||||
SecString::~SecString(){
|
SecString::~SecString(){
|
||||||
overwrite(plaintext);
|
lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecString::getString(QString & str){
|
void SecString::lock(){
|
||||||
if(data.size()){
|
locked=true;
|
||||||
Rijndael aes;
|
overwrite(plain);
|
||||||
int r=aes.init(Rijndael::CBC, Rijndael::Decrypt,Key,Rijndael::Key32Bytes);
|
plain=QString();
|
||||||
if(r){ cout << "AES error, code " << r << endl;
|
|
||||||
exit(-1);}
|
|
||||||
char* out=new char[len];
|
|
||||||
r=aes.padDecrypt((unsigned char*)data.data(),data.size(),(unsigned char*)out);
|
|
||||||
if(r!=len){ cout << "AES error in SecString::getString(), r!=length, r=" << r << endl;
|
|
||||||
exit(-1);}
|
|
||||||
str=QString::fromUtf8(out,len);
|
|
||||||
overwrite(out,len);
|
|
||||||
delete [] out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString& SecString::getString(){
|
void SecString::unlock(){
|
||||||
getString(plaintext);
|
locked=false;
|
||||||
return plaintext;
|
plain=QString();
|
||||||
|
if(!crypt.length()){return;}
|
||||||
|
const unsigned char* buffer=new unsigned char[crypt.length()];
|
||||||
|
SecString::RC4.decrypt((byte*)crypt.data(),(unsigned char*)buffer,crypt.length());
|
||||||
|
plain=QString::fromUtf8((const char*)buffer,crypt.size());
|
||||||
|
overwrite((unsigned char*)buffer,crypt.size());
|
||||||
|
delete [] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecString::delRef(){
|
|
||||||
overwrite(plaintext);
|
const QString& SecString::string(){
|
||||||
|
if(locked){
|
||||||
|
printf("Error in function SecString::string(): string is locked\n");
|
||||||
|
return QString(">SEC_STRING_ERROR<");
|
||||||
|
}
|
||||||
|
return plain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecString::setString(QString& str,bool DelSrc){
|
|
||||||
Rijndael aes;
|
void SecString::setString(QString& str,bool DeleteSource){
|
||||||
int r=aes.init(Rijndael::CBC, Rijndael::Encrypt,Key,Rijndael::Key32Bytes);
|
QByteArray StrData=str.toUtf8();
|
||||||
if(r){ cout << "AES error, code " << r << endl;
|
int len=StrData.size();
|
||||||
exit(-1);}
|
unsigned char* buffer=new unsigned char[len];
|
||||||
int il=str.length();
|
SecString::RC4.encrypt((const unsigned char*)StrData.data(),buffer,len);
|
||||||
char* input=new char[il];
|
crypt=QByteArray((const char*)buffer,len);
|
||||||
char* output=new char[il+16];
|
overwrite(buffer,len);
|
||||||
memcpy(input,str.utf8(),il);
|
overwrite((unsigned char*)StrData.data(),len);
|
||||||
r=aes.padEncrypt((unsigned char*)input,il,(unsigned char*)output);
|
delete [] buffer;
|
||||||
if(r<0){ cout << "AES error, code " << r << endl;
|
if(DeleteSource){
|
||||||
exit(-1);}
|
overwrite(str);
|
||||||
len=il;
|
str=QString();}
|
||||||
data=QByteArray(output,r);
|
lock();
|
||||||
overwrite(input,il);
|
|
||||||
delete [] input;
|
|
||||||
if(DelSrc)overwrite(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecString::overwrite(char* str,int strlen){
|
void SecString::overwrite(unsigned char* str,int strlen){
|
||||||
if(strlen==0 || str==NULL)return;
|
if(strlen==0 || str==NULL)return;
|
||||||
getRandomBytes(str,strlen,1,false);
|
for(int i=0; i<strlen; i++){
|
||||||
|
str[i]=0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecString::overwrite(QString &str){
|
void SecString::overwrite(QString &str){
|
||||||
if(str.length()==0)return;
|
if(str.length()==0)return;
|
||||||
char* tmp=new char[str.length()];
|
for(int i=0; i<str.length(); i++){
|
||||||
getRandomBytes(tmp,str.length(),1,false);
|
((char*)str.data())[i]=0;
|
||||||
str=tmp;
|
}
|
||||||
delete [] tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SecString::length(){
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SecString::generateSessionKey(){
|
void SecString::generateSessionKey(){
|
||||||
getRandomBytes(Key,32,1,false);
|
CArcFour arc;
|
||||||
|
unsigned char* sessionkey=new unsigned char[32];
|
||||||
|
getRandomBytes(sessionkey,32,1,false);
|
||||||
|
RC4.setKey(sessionkey,32);
|
||||||
|
delete [] sessionkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,28 +23,29 @@
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <qstring.h>
|
#include <qstring.h>
|
||||||
#include <qglobal.h>
|
#include <qglobal.h>
|
||||||
#include "crypto/rijndael.h"
|
#include "crypto/arcfour.h"
|
||||||
|
|
||||||
class SecString{
|
class SecString{
|
||||||
public:
|
public:
|
||||||
SecString(unsigned char* key);
|
|
||||||
SecString();
|
SecString();
|
||||||
~SecString();
|
~SecString();
|
||||||
|
|
||||||
void getString(QString& str);
|
|
||||||
QString& getString();
|
|
||||||
void setString(QString& str, bool DelSrc=false);
|
void setString(QString& str, bool DelSrc=false);
|
||||||
void delRef();
|
void lock();
|
||||||
static void overwrite(char* str,int len);
|
void unlock();
|
||||||
static void overwrite(QString& str);
|
const QString& string();
|
||||||
|
operator QString();
|
||||||
int length();
|
int length();
|
||||||
|
|
||||||
|
static void overwrite(unsigned char* str,int len);
|
||||||
|
static void overwrite(QString& str);
|
||||||
static void generateSessionKey();
|
static void generateSessionKey();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Q_UINT8 Key[32];
|
bool locked;
|
||||||
QString plaintext;
|
static CArcFour RC4;
|
||||||
QByteArray data;
|
QByteArray crypt;
|
||||||
int len;
|
QString plain;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,8 @@ if(config.Language!="_DEUTSCH_"){
|
||||||
DateTimeFormat=QObject::trUtf8("dd'.'MM'.'yy' 'hh':'mm");
|
DateTimeFormat=QObject::trUtf8("dd'.'MM'.'yy' 'hh':'mm");
|
||||||
loadImages();
|
loadImages();
|
||||||
|
|
||||||
|
SecString::generateSessionKey();
|
||||||
|
|
||||||
KeepassMainWindow *mainWin = new KeepassMainWindow();
|
KeepassMainWindow *mainWin = new KeepassMainWindow();
|
||||||
mainWin->show();
|
mainWin->show();
|
||||||
int r=app->exec();
|
int r=app->exec();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2005 by Tarek Saidi *
|
* Copyright (C) 2005-2006 by Tarek Saidi *
|
||||||
* tarek.saidi@arcor.de *
|
* tarek.saidi@arcor.de *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
@ -303,9 +303,10 @@ void KeepassMainWindow::OnFileOpen(){
|
||||||
if(FileOpen)
|
if(FileOpen)
|
||||||
if(!closeDatabase())return;
|
if(!closeDatabase())return;
|
||||||
QString filename=QFileDialog::getOpenFileName(this,trUtf8("Databank öffnen..."),QDir::homePath(),"*.kdb");
|
QString filename=QFileDialog::getOpenFileName(this,trUtf8("Databank öffnen..."),QDir::homePath(),"*.kdb");
|
||||||
if(filename!=QString::null)
|
if(filename!=QString::null){
|
||||||
openDatabase(filename);
|
openDatabase(filename);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KeepassMainWindow::OnFileClose(){
|
void KeepassMainWindow::OnFileClose(){
|
||||||
closeDatabase();
|
closeDatabase();
|
||||||
|
@ -394,22 +395,26 @@ if(EntryView->selectedItems().size()!=1){
|
||||||
|
|
||||||
CEntry& entry=*((EntryViewItem*)(EntryView->selectedItems()[0]))->pEntry;
|
CEntry& entry=*((EntryViewItem*)(EntryView->selectedItems()[0]))->pEntry;
|
||||||
QString str=trUtf8("<B>Gruppe: </B>%1 <B>Titel: </B>%2 <B>Benutzername: </B>%3 <B>URL: </B><a href=%4>%4</a> <B>Passwort: </B>%5 <B>Erstellt: </B>%6 <B>letzte Änderung: </B>%7 <B>letzter Zugriff: </B>%8 <B>gültig bis: </B>%9");
|
QString str=trUtf8("<B>Gruppe: </B>%1 <B>Titel: </B>%2 <B>Benutzername: </B>%3 <B>URL: </B><a href=%4>%4</a> <B>Passwort: </B>%5 <B>Erstellt: </B>%6 <B>letzte Änderung: </B>%7 <B>letzter Zugriff: </B>%8 <B>gültig bis: </B>%9");
|
||||||
str=str.arg(currentGroup()->Name).arg(entry.Title);
|
//todo: a "CGroup* PwDatabase::getGroup(CEntry*)" method would be a good idea
|
||||||
|
str=str.arg(db->Groups[db->getGroupIndex(entry.GroupID)].Name).arg(entry.Title);
|
||||||
|
|
||||||
if(!config.ListView_HideUsernames) str=str.arg(entry.UserName);
|
if(!config.ListView_HideUsernames) str=str.arg(entry.UserName);
|
||||||
else str=str.arg("****");
|
else str=str.arg("****");
|
||||||
|
|
||||||
str=str.arg(entry.URL);
|
str=str.arg(entry.URL);
|
||||||
|
|
||||||
if(!config.ListView_HidePasswords) str=str.arg(entry.Password.getString());
|
entry.Password.unlock();
|
||||||
|
if(!config.ListView_HidePasswords) str=str.arg(entry.Password.string());
|
||||||
else str=str.arg("****");
|
else str=str.arg("****");
|
||||||
|
|
||||||
|
entry.Password.lock();
|
||||||
|
|
||||||
str=str.arg(entry.Creation.toString(Qt::LocalDate))
|
str=str.arg(entry.Creation.toString(Qt::LocalDate))
|
||||||
.arg(entry.LastMod.toString(Qt::LocalDate))
|
.arg(entry.LastMod.toString(Qt::LocalDate))
|
||||||
.arg(entry.LastAccess.toString(Qt::LocalDate))
|
.arg(entry.LastAccess.toString(Qt::LocalDate))
|
||||||
.arg(entry.Expire.toString(Qt::LocalDate));
|
.arg(entry.Expire.toString(Qt::LocalDate));
|
||||||
DetailView->setHtml(str);
|
DetailView->setHtml(str);
|
||||||
entry.Password.delRef();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,9 +674,10 @@ ClipboardTimer.start(config.ClipboardTimeOut*1000,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeepassMainWindow::OnEditPasswordToClipboard(){
|
void KeepassMainWindow::OnEditPasswordToClipboard(){
|
||||||
Clipboard->setText(currentEntry()->Password.getString(),QClipboard::Clipboard);
|
currentEntry()->Password.unlock();
|
||||||
|
Clipboard->setText(currentEntry()->Password.string(),QClipboard::Clipboard);
|
||||||
ClipboardTimer.start(config.ClipboardTimeOut*1000,true);
|
ClipboardTimer.start(config.ClipboardTimeOut*1000,true);
|
||||||
currentEntry()->Password.delRef();
|
currentEntry()->Password.lock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
src/src.pro
23
src/src.pro
|
@ -3,15 +3,8 @@
|
||||||
# Unterordner relativ zum Projektordner: ./src
|
# Unterordner relativ zum Projektordner: ./src
|
||||||
# Das Target ist eine Anwendung: ../bin/keepass
|
# Das Target ist eine Anwendung: ../bin/keepass
|
||||||
|
|
||||||
INSTALLS += target \
|
INSTALLS += Share
|
||||||
Share
|
|
||||||
Share.files += ../share/keepass/*
|
Share.files += ../share/keepass/*
|
||||||
unix{ target.path = /usr/local/bin
|
|
||||||
Share.path = /usr/local/share/keepass
|
|
||||||
}
|
|
||||||
macx{ target.path = /Applications
|
|
||||||
Share.path = /Applications/keepass.app/Contents/share/keepass
|
|
||||||
}
|
|
||||||
FORMS += forms/EditGroupDlg.ui \
|
FORMS += forms/EditGroupDlg.ui \
|
||||||
forms/SearchDlg.ui \
|
forms/SearchDlg.ui \
|
||||||
forms/AboutDlg.ui \
|
forms/AboutDlg.ui \
|
||||||
|
@ -57,7 +50,8 @@ HEADERS += lib/IniReader.h \
|
||||||
global.h \
|
global.h \
|
||||||
main.h \
|
main.h \
|
||||||
lib/GroupView.h \
|
lib/GroupView.h \
|
||||||
lib/EntryView.h
|
lib/EntryView.h \
|
||||||
|
crypto/arcfour.h
|
||||||
SOURCES += lib/IniReader.cpp \
|
SOURCES += lib/IniReader.cpp \
|
||||||
lib/UrlLabel.cpp \
|
lib/UrlLabel.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
|
@ -88,7 +82,8 @@ SOURCES += lib/IniReader.cpp \
|
||||||
Database.cpp \
|
Database.cpp \
|
||||||
lib/KdePlugin.cpp \
|
lib/KdePlugin.cpp \
|
||||||
lib/GroupView.cpp \
|
lib/GroupView.cpp \
|
||||||
lib/EntryView.cpp
|
lib/EntryView.cpp \
|
||||||
|
crypto/arcfour.cpp
|
||||||
QT += xml \
|
QT += xml \
|
||||||
qt3support
|
qt3support
|
||||||
MOC_DIR = ../build/moc
|
MOC_DIR = ../build/moc
|
||||||
|
@ -103,3 +98,11 @@ thread \
|
||||||
exceptions \
|
exceptions \
|
||||||
stl
|
stl
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
unix{
|
||||||
|
target.path = /usr/local/bin
|
||||||
|
Share.path = /usr/local/share/keepass
|
||||||
|
}
|
||||||
|
macx{
|
||||||
|
target.path = /Applications
|
||||||
|
Share.path = /Applications/keepass.app/Contents/share/keepass
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue