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; }
 | 
			
		||||
 | 
			
		||||
		bRet = entry.ReadEntryField(FieldType,FieldSize,(Q_UINT8*)pField);
 | 
			
		||||
 | 
			
		||||
		if((FieldType == 0xFFFF) && (bRet == true)){			
 | 
			
		||||
			entry.sID=tmp_id++;
 | 
			
		||||
			Entries << entry;
 | 
			
		||||
| 
						 | 
				
			
			@ -272,14 +273,14 @@ if(paKey == NULL) return false;
 | 
			
		|||
KeyLen = strlen(paKey);
 | 
			
		||||
 | 
			
		||||
if(KeyLen == 0) {
 | 
			
		||||
SecString::overwrite(paKey,Password.length() + 1);
 | 
			
		||||
SecString::overwrite((unsigned char*)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);
 | 
			
		||||
SecString::overwrite((unsigned char*)paKey,Password.length() + 1);
 | 
			
		||||
delete [] paKey;
 | 
			
		||||
return true;
 | 
			
		||||
 }
 | 
			
		||||
| 
						 | 
				
			
			@ -530,7 +531,6 @@ switch(FieldType)
 | 
			
		|||
		memcpyFromLEnd32(&ImageID, (char*)pData);
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x0004:
 | 
			
		||||
		//Title=(char*)pData;
 | 
			
		||||
		Title=QString::fromUtf8((char*)pData);
 | 
			
		||||
		break;
 | 
			
		||||
	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
 | 
			
		||||
		memcpyToLEnd16(buffer+pos, &FieldType); pos += 2;
 | 
			
		||||
		memcpyToLEnd32(buffer+pos, &FieldSize); pos += 4;
 | 
			
		||||
		memcpy(buffer+pos, Entries[i].Password.getString(),FieldSize);  pos += FieldSize;
 | 
			
		||||
		Entries[i].Password.delRef();
 | 
			
		||||
		Entries[i].Password.unlock();
 | 
			
		||||
		memcpy(buffer+pos, Entries[i].Password.string(),FieldSize);  pos += FieldSize;
 | 
			
		||||
		Entries[i].Password.lock();
 | 
			
		||||
 | 
			
		||||
		FieldType = 0x0008;
 | 
			
		||||
		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);
 | 
			
		||||
	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);
 | 
			
		||||
	left->Password.lock();
 | 
			
		||||
	right->Password.lock();
 | 
			
		||||
 | 
			
		||||
	kp_assert(results, left->Additional == right->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_UserName->setText(entry->UserName);
 | 
			
		||||
Edit_URL->setText(entry->URL);
 | 
			
		||||
Edit_Password->setText(entry->Password.getString());
 | 
			
		||||
Edit_Password_w->setText(entry->Password.getString());
 | 
			
		||||
entry->Password.delRef();
 | 
			
		||||
entry->Password.unlock();
 | 
			
		||||
Edit_Password->setText(entry->Password.string());
 | 
			
		||||
Edit_Password_w->setText(entry->Password.string());
 | 
			
		||||
entry->Password.lock();
 | 
			
		||||
if(!config.ShowPasswords)
 | 
			
		||||
  ChangeEchoMode();
 | 
			
		||||
OnPasswordwLostFocus();
 | 
			
		||||
| 
						 | 
				
			
			@ -171,10 +172,10 @@ if(entry->URL!=Edit_URL->text())
 | 
			
		|||
	ModFlag=true;
 | 
			
		||||
if(entry->Additional!=Edit_Comment->text())
 | 
			
		||||
	ModFlag=true;
 | 
			
		||||
QString& passw=entry->Password.getString();
 | 
			
		||||
if(passw!=Edit_Password->text())
 | 
			
		||||
entry->Password.unlock();
 | 
			
		||||
if(entry->Password.string()!=Edit_Password->text())
 | 
			
		||||
	ModFlag=true;
 | 
			
		||||
entry->Password.delRef();
 | 
			
		||||
entry->Password.lock();
 | 
			
		||||
 | 
			
		||||
entry->Expire=DateTime_Expire->dateTime();
 | 
			
		||||
entry->LastAccess=QDateTime::currentDateTime();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,8 +99,9 @@ bool hit=false;
 | 
			
		|||
 if(checkBox_URL->isChecked())		hit=hit||search(db->Entries[i].URL);
 | 
			
		||||
 if(checkBox_Comment->isChecked())	hit=hit||search(db->Entries[i].Additional);
 | 
			
		||||
 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.delRef();
 | 
			
		||||
 db->Entries[i].Password.unlock();
 | 
			
		||||
 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +110,7 @@ done(1);
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool CSearchDlg::search(QString& str){
 | 
			
		||||
bool CSearchDlg::search(const QString& str){
 | 
			
		||||
 | 
			
		||||
if(regexp){
 | 
			
		||||
 QRegExp exp(txt,checkBox_Cs->isChecked());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ private:
 | 
			
		|||
  CGroup* group;
 | 
			
		||||
  bool regexp;
 | 
			
		||||
  PwDatabase* db;
 | 
			
		||||
  bool search(QString& str);
 | 
			
		||||
  bool search(const QString& str);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,14 +69,31 @@ ContextMenu->popup(e->globalPos());
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void KeepassEntryView::updateItems(unsigned int GroupID){
 | 
			
		||||
 | 
			
		||||
clear();
 | 
			
		||||
Items.clear();
 | 
			
		||||
if(!db)return;
 | 
			
		||||
if(!GroupID)return;
 | 
			
		||||
EntryViewItem *tmp=NULL;
 | 
			
		||||
for(int i=0;i<db->Entries.size();i++){
 | 
			
		||||
  CEntry* entry=&db->Entries[i];
 | 
			
		||||
  if(entry->GroupID==GroupID){
 | 
			
		||||
  if(db->Entries[i].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.back()->pEntry=entry;
 | 
			
		||||
  int j=0;
 | 
			
		||||
| 
						 | 
				
			
			@ -93,8 +110,9 @@ for(int i=0;i<db->Entries.size();i++){
 | 
			
		|||
    if(config.ListView_HidePasswords)
 | 
			
		||||
      tmp->setText(j++,"******");
 | 
			
		||||
    else{
 | 
			
		||||
      tmp->setText(j++,entry->Password.getString());
 | 
			
		||||
      entry->Password.delRef();}}
 | 
			
		||||
	  entry->Password.unlock();
 | 
			
		||||
      tmp->setText(j++,entry->Password.string());
 | 
			
		||||
      entry->Password.lock();}}
 | 
			
		||||
  if(config.Columns[4]){
 | 
			
		||||
    tmp->setText(j++,entry->Additional.section('\n',0,0));}
 | 
			
		||||
  if(config.Columns[5]){
 | 
			
		||||
| 
						 | 
				
			
			@ -108,17 +126,6 @@ for(int i=0;i<db->Entries.size();i++){
 | 
			
		|||
  if(config.Columns[9]){
 | 
			
		||||
   tmp->setText(j++,entry->BinaryDesc);}
 | 
			
		||||
  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(){
 | 
			
		||||
| 
						 | 
				
			
			@ -141,8 +148,9 @@ for(int i=0;i<Items.size();i++){
 | 
			
		|||
    if(config.ListView_HidePasswords)
 | 
			
		||||
      tmp->setText(j++,"******");
 | 
			
		||||
    else{
 | 
			
		||||
      tmp->setText(j++,entry->Password.getString());
 | 
			
		||||
      entry->Password.delRef();}}
 | 
			
		||||
      entry->Password.unlock();
 | 
			
		||||
      tmp->setText(j++,entry->Password.string());
 | 
			
		||||
      entry->Password.lock();}}
 | 
			
		||||
  if(config.Columns[4]){
 | 
			
		||||
    tmp->setText(j++,entry->Additional.section('\n',0,0));}
 | 
			
		||||
  if(config.Columns[5]){
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,7 @@ public:
 | 
			
		|||
 vector<EntryViewItem*>Items;
 | 
			
		||||
 QMenu *ContextMenu;
 | 
			
		||||
private:
 | 
			
		||||
 void setEntry(CEntry* entry);
 | 
			
		||||
 int CurrentGroup;
 | 
			
		||||
protected:
 | 
			
		||||
 virtual void contextMenuEvent(QContextMenuEvent *event);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,83 +19,89 @@
 | 
			
		|||
 ***************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "SecString.h"
 | 
			
		||||
#include <qmessagebox.h>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include "crypto/arcfour.h"
 | 
			
		||||
#include "random.h"
 | 
			
		||||
using namespace std;
 | 
			
		||||
Q_UINT8 SecString::Key[32]={0};
 | 
			
		||||
CArcFour SecString::RC4;
 | 
			
		||||
 | 
			
		||||
SecString::operator QString(){
 | 
			
		||||
return string();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SecString::SecString(){
 | 
			
		||||
len=0;
 | 
			
		||||
locked=true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SecString::length(){
 | 
			
		||||
return crypt.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SecString::~SecString(){
 | 
			
		||||
overwrite(plaintext);
 | 
			
		||||
lock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SecString::getString(QString & str){
 | 
			
		||||
if(data.size()){
 | 
			
		||||
Rijndael aes;
 | 
			
		||||
int r=aes.init(Rijndael::CBC, Rijndael::Decrypt,Key,Rijndael::Key32Bytes);
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
void SecString::lock(){
 | 
			
		||||
locked=true;
 | 
			
		||||
overwrite(plain);
 | 
			
		||||
plain=QString();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString& SecString::getString(){
 | 
			
		||||
getString(plaintext);
 | 
			
		||||
return plaintext;
 | 
			
		||||
void SecString::unlock(){
 | 
			
		||||
locked=false;
 | 
			
		||||
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;
 | 
			
		||||
int r=aes.init(Rijndael::CBC, Rijndael::Encrypt,Key,Rijndael::Key32Bytes);
 | 
			
		||||
if(r){ cout << "AES error, code " << r << endl;
 | 
			
		||||
       exit(-1);}
 | 
			
		||||
int il=str.length();
 | 
			
		||||
char* input=new char[il];
 | 
			
		||||
char* output=new char[il+16];
 | 
			
		||||
memcpy(input,str.utf8(),il);
 | 
			
		||||
r=aes.padEncrypt((unsigned char*)input,il,(unsigned char*)output);
 | 
			
		||||
if(r<0){ cout << "AES error, code " << r << endl;
 | 
			
		||||
         exit(-1);}
 | 
			
		||||
len=il;
 | 
			
		||||
data=QByteArray(output,r);
 | 
			
		||||
overwrite(input,il);
 | 
			
		||||
delete [] input;
 | 
			
		||||
if(DelSrc)overwrite(str);
 | 
			
		||||
 | 
			
		||||
void SecString::setString(QString& str,bool DeleteSource){
 | 
			
		||||
QByteArray StrData=str.toUtf8();
 | 
			
		||||
int len=StrData.size();
 | 
			
		||||
unsigned char* buffer=new unsigned char[len];
 | 
			
		||||
SecString::RC4.encrypt((const unsigned char*)StrData.data(),buffer,len);
 | 
			
		||||
crypt=QByteArray((const char*)buffer,len);
 | 
			
		||||
overwrite(buffer,len);
 | 
			
		||||
overwrite((unsigned char*)StrData.data(),len);
 | 
			
		||||
delete [] buffer;
 | 
			
		||||
if(DeleteSource){
 | 
			
		||||
  overwrite(str);
 | 
			
		||||
  str=QString();}
 | 
			
		||||
lock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SecString::overwrite(char* str,int strlen){
 | 
			
		||||
void SecString::overwrite(unsigned char* str,int strlen){
 | 
			
		||||
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){
 | 
			
		||||
if(str.length()==0)return;
 | 
			
		||||
char* tmp=new char[str.length()];
 | 
			
		||||
getRandomBytes(tmp,str.length(),1,false);
 | 
			
		||||
str=tmp;
 | 
			
		||||
delete [] tmp;
 | 
			
		||||
for(int i=0; i<str.length(); i++){
 | 
			
		||||
	((char*)str.data())[i]=0;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SecString::length(){
 | 
			
		||||
return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 <qstring.h>
 | 
			
		||||
#include <qglobal.h>
 | 
			
		||||
#include "crypto/rijndael.h"
 | 
			
		||||
#include "crypto/arcfour.h"
 | 
			
		||||
 | 
			
		||||
class SecString{
 | 
			
		||||
public:
 | 
			
		||||
 SecString(unsigned char* key);
 | 
			
		||||
 SecString();
 | 
			
		||||
 ~SecString();
 | 
			
		||||
 | 
			
		||||
 void getString(QString& str);
 | 
			
		||||
 QString& getString();
 | 
			
		||||
 void setString(QString& str, bool DelSrc=false);
 | 
			
		||||
 void delRef();
 | 
			
		||||
 static void overwrite(char* str,int len);
 | 
			
		||||
 static void overwrite(QString& str);
 | 
			
		||||
 void lock();
 | 
			
		||||
 void unlock();
 | 
			
		||||
 const QString& string();
 | 
			
		||||
 operator QString();
 | 
			
		||||
 int length();
 | 
			
		||||
 | 
			
		||||
 static void overwrite(unsigned char* str,int len);
 | 
			
		||||
 static void overwrite(QString& str);
 | 
			
		||||
 static void generateSessionKey();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 static Q_UINT8 Key[32];
 | 
			
		||||
 QString plaintext;
 | 
			
		||||
 QByteArray data;
 | 
			
		||||
 int len;
 | 
			
		||||
 bool locked;
 | 
			
		||||
 static CArcFour RC4;
 | 
			
		||||
 QByteArray crypt;
 | 
			
		||||
 QString plain;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,6 +123,8 @@ if(config.Language!="_DEUTSCH_"){
 | 
			
		|||
DateTimeFormat=QObject::trUtf8("dd'.'MM'.'yy' 'hh':'mm");
 | 
			
		||||
loadImages();
 | 
			
		||||
 | 
			
		||||
SecString::generateSessionKey();
 | 
			
		||||
 | 
			
		||||
KeepassMainWindow *mainWin = new KeepassMainWindow();
 | 
			
		||||
mainWin->show();
 | 
			
		||||
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                                                  *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify  *
 | 
			
		||||
| 
						 | 
				
			
			@ -303,9 +303,10 @@ void KeepassMainWindow::OnFileOpen(){
 | 
			
		|||
if(FileOpen)
 | 
			
		||||
 if(!closeDatabase())return;
 | 
			
		||||
QString filename=QFileDialog::getOpenFileName(this,trUtf8("Databank öffnen..."),QDir::homePath(),"*.kdb");
 | 
			
		||||
if(filename!=QString::null)
 | 
			
		||||
if(filename!=QString::null){
 | 
			
		||||
 openDatabase(filename);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KeepassMainWindow::OnFileClose(){
 | 
			
		||||
closeDatabase();
 | 
			
		||||
| 
						 | 
				
			
			@ -394,22 +395,26 @@ if(EntryView->selectedItems().size()!=1){
 | 
			
		|||
 | 
			
		||||
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");
 | 
			
		||||
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);
 | 
			
		||||
else str=str.arg("****");
 | 
			
		||||
 | 
			
		||||
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("****");
 | 
			
		||||
 | 
			
		||||
entry.Password.lock();
 | 
			
		||||
 | 
			
		||||
str=str.arg(entry.Creation.toString(Qt::LocalDate))
 | 
			
		||||
	  .arg(entry.LastMod.toString(Qt::LocalDate))
 | 
			
		||||
	  .arg(entry.LastAccess.toString(Qt::LocalDate))
 | 
			
		||||
	  .arg(entry.Expire.toString(Qt::LocalDate));
 | 
			
		||||
DetailView->setHtml(str);
 | 
			
		||||
entry.Password.delRef();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -669,9 +674,10 @@ ClipboardTimer.start(config.ClipboardTimeOut*1000,true);
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
currentEntry()->Password.delRef();
 | 
			
		||||
currentEntry()->Password.lock();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										23
									
								
								src/src.pro
								
								
								
								
							
							
						
						
									
										23
									
								
								src/src.pro
								
								
								
								
							| 
						 | 
				
			
			@ -3,15 +3,8 @@
 | 
			
		|||
# Unterordner relativ zum Projektordner: ./src
 | 
			
		||||
# Das Target ist eine Anwendung:  ../bin/keepass
 | 
			
		||||
 | 
			
		||||
INSTALLS += target \
 | 
			
		||||
            Share
 | 
			
		||||
INSTALLS += Share 
 | 
			
		||||
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/SearchDlg.ui \
 | 
			
		||||
         forms/AboutDlg.ui \
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +50,8 @@ HEADERS += lib/IniReader.h \
 | 
			
		|||
           global.h \
 | 
			
		||||
           main.h \
 | 
			
		||||
           lib/GroupView.h \
 | 
			
		||||
           lib/EntryView.h 
 | 
			
		||||
           lib/EntryView.h \
 | 
			
		||||
           crypto/arcfour.h 
 | 
			
		||||
SOURCES += lib/IniReader.cpp \
 | 
			
		||||
           lib/UrlLabel.cpp \
 | 
			
		||||
           main.cpp \
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +82,8 @@ SOURCES += lib/IniReader.cpp \
 | 
			
		|||
           Database.cpp \
 | 
			
		||||
           lib/KdePlugin.cpp \
 | 
			
		||||
           lib/GroupView.cpp \
 | 
			
		||||
           lib/EntryView.cpp 
 | 
			
		||||
           lib/EntryView.cpp \
 | 
			
		||||
           crypto/arcfour.cpp 
 | 
			
		||||
QT += xml \
 | 
			
		||||
qt3support
 | 
			
		||||
MOC_DIR = ../build/moc
 | 
			
		||||
| 
						 | 
				
			
			@ -103,3 +98,11 @@ thread \
 | 
			
		|||
exceptions \
 | 
			
		||||
stl
 | 
			
		||||
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