Save database using the correct password encoding when opening with a different encoding

git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@267 b624d157-de02-0410-bad0-e51aec6abb33
master
sniperbeamer 16 years ago
parent d08a2f2372
commit 688bfe44c7
  1. 30
      src/Kdb3Database.cpp
  2. 5
      src/Kdb3Database.h
  3. 4
      src/mainwindow.cpp

@ -52,7 +52,8 @@ bool Kdb3Database::StdEntryLessThan(const Kdb3Database::StdEntry& This,const Kdb
} }
Kdb3Database::Kdb3Database() : RawMasterKey(32), RawMasterKey_Latin1(32), RawMasterKey_UTF8(32), MasterKey(32){ Kdb3Database::Kdb3Database() : RawMasterKey(32), RawMasterKey_CP1252(32),
RawMasterKey_Latin1(32), RawMasterKey_UTF8(32), MasterKey(32){
} }
QString Kdb3Database::getError(){ QString Kdb3Database::getError(){
@ -104,7 +105,7 @@ int Kdb3Database::numIcons(){
bool Kdb3Database::parseMetaStream(const StdEntry& entry){ bool Kdb3Database::parseMetaStream(const StdEntry& entry){
qDebug("Found Metastream: %s",entry.Comment.toUtf8().data()); qDebug("Found Metastream: %s", CSTR(entry.Comment));
if(entry.Comment=="KPX_GROUP_TREE_STATE"){ if(entry.Comment=="KPX_GROUP_TREE_STATE"){
parseGroupTreeStateMetaStream(entry.Binary); parseGroupTreeStateMetaStream(entry.Binary);
@ -492,13 +493,17 @@ void Kdb3Database::restoreGroupTreeState(){
} }
} }
bool Kdb3Database::load(QString identifier){
return loadReal(identifier, false);
}
#define LOAD_RETURN_CLEANUP \ #define LOAD_RETURN_CLEANUP \
delete File; \ delete File; \
File = NULL; \ File = NULL; \
delete[] buffer; \ delete[] buffer; \
return false; return false;
bool Kdb3Database::load(QString filename){ bool Kdb3Database::loadReal(QString filename, bool differentEncoding) {
unsigned long total_size,crypto_size; unsigned long total_size,crypto_size;
quint32 Signature1,Signature2,Version,NumGroups,NumEntries,Flags; quint32 Signature1,Signature2,Version,NumGroups,NumEntries,Flags;
quint8 FinalRandomSeed[16]; quint8 FinalRandomSeed[16];
@ -599,7 +604,7 @@ bool Kdb3Database::load(QString filename){
RawMasterKey.copyData(RawMasterKey_Latin1); RawMasterKey.copyData(RawMasterKey_Latin1);
PotentialEncodingIssueLatin1 = false; PotentialEncodingIssueLatin1 = false;
qDebug("Decryption failed. Retrying with Latin-1."); qDebug("Decryption failed. Retrying with Latin-1.");
return load(filename); // second try return loadReal(filename, true); // second try
} }
if(PotentialEncodingIssueUTF8){ if(PotentialEncodingIssueUTF8){
delete[] buffer; delete[] buffer;
@ -609,7 +614,7 @@ bool Kdb3Database::load(QString filename){
RawMasterKey.copyData(RawMasterKey_UTF8); RawMasterKey.copyData(RawMasterKey_UTF8);
PotentialEncodingIssueUTF8 = false; PotentialEncodingIssueUTF8 = false;
qDebug("Decryption failed. Retrying with UTF-8."); qDebug("Decryption failed. Retrying with UTF-8.");
return load(filename); // second/third try return loadReal(filename, true); // second/third try
} }
error=tr("Hash test failed.\nThe key is wrong or the file is damaged."); error=tr("Hash test failed.\nThe key is wrong or the file is damaged.");
KeyError=true; KeyError=true;
@ -735,6 +740,12 @@ bool Kdb3Database::load(QString filename){
createHandles(); createHandles();
restoreGroupTreeState(); restoreGroupTreeState();
passwordEncodingChanged = differentEncoding;
if (differentEncoding) {
RawMasterKey.copyData(RawMasterKey_CP1252);
generateMasterKey();
}
return true; return true;
} }
@ -856,16 +867,17 @@ bool Kdb3Database::setKey(const QString& password,const QString& keyfile){
return setPasswordKey(password); return setPasswordKey(password);
if(!keyfile.isEmpty()) if(!keyfile.isEmpty())
return setFileKey(keyfile); return setFileKey(keyfile);
assert(false); Q_ASSERT(false);
} }
bool Kdb3Database::setPasswordKey(const QString& Password){ bool Kdb3Database::setPasswordKey(const QString& Password){
Q_ASSERT(Password.size()); Q_ASSERT(Password.size());
QTextCodec* codec=QTextCodec::codecForName("Windows-1252"); QTextCodec* codec=QTextCodec::codecForName("Windows-1252");
QByteArray Password_CP1252 = codec->fromUnicode(Password); QByteArray Password_CP1252 = codec->fromUnicode(Password);
RawMasterKey.unlock(); RawMasterKey_CP1252.unlock();
SHA256::hashBuffer(Password_CP1252.data(),*RawMasterKey,Password_CP1252.size()); SHA256::hashBuffer(Password_CP1252.data(),*RawMasterKey_CP1252,Password_CP1252.size());
RawMasterKey.lock(); RawMasterKey_CP1252.lock();
RawMasterKey.copyData(RawMasterKey_CP1252);
QByteArray Password_Latin1 = Password.toLatin1(); QByteArray Password_Latin1 = Password.toLatin1();
QByteArray Password_UTF8 = Password.toUtf8(); QByteArray Password_UTF8 = Password.toUtf8();

@ -187,7 +187,10 @@ public:
virtual void generateMasterKey(); virtual void generateMasterKey();
//virtual IDatabase* groupToNewDb(IGroupHandle* group); //virtual IDatabase* groupToNewDb(IGroupHandle* group);
inline bool hasPasswordEncodingChanged() { return passwordEncodingChanged; };
private: private:
bool loadReal(QString filename, bool differentEncoding);
QDateTime dateFromPackedStruct5(const unsigned char* pBytes); QDateTime dateFromPackedStruct5(const unsigned char* pBytes);
void dateToPackedStruct5(const QDateTime& datetime, unsigned char* dst); void dateToPackedStruct5(const QDateTime& datetime, unsigned char* dst);
bool isMetaStream(StdEntry& Entry); bool isMetaStream(StdEntry& Entry);
@ -241,11 +244,13 @@ private:
unsigned int KeyTransfRounds; unsigned int KeyTransfRounds;
CryptAlgorithm Algorithm; CryptAlgorithm Algorithm;
SecData RawMasterKey; SecData RawMasterKey;
SecData RawMasterKey_CP1252;
SecData RawMasterKey_Latin1; SecData RawMasterKey_Latin1;
SecData RawMasterKey_UTF8; SecData RawMasterKey_UTF8;
SecData MasterKey; SecData MasterKey;
quint8 TransfRandomSeed[32]; quint8 TransfRandomSeed[32];
bool hasV4IconMetaStream; bool hasV4IconMetaStream;
bool passwordEncodingChanged;
}; };
class KeyTransform : public QThread{ class KeyTransform : public QThread{

@ -413,7 +413,7 @@ bool KeepassMainWindow::openDatabase(QString filename,bool IsAuto){
config->setLastKeyLocation(QString()); config->setLastKeyLocation(QString());
config->setLastKeyType(PASSWORD); config->setLastKeyType(PASSWORD);
} }
db=dynamic_cast<IDatabase*>(new Kdb3Database()); db = new Kdb3Database();
PasswordDialog::DlgFlags flags=PasswordDialog::Flag_None; PasswordDialog::DlgFlags flags=PasswordDialog::Flag_None;
if(IsAuto) if(IsAuto)
flags = PasswordDialog::Flag_Auto; flags = PasswordDialog::Flag_Auto;
@ -455,7 +455,7 @@ bool KeepassMainWindow::openDatabase(QString filename,bool IsAuto){
GroupView->createItems(); GroupView->createItems();
EntryView->showGroup(NULL); EntryView->showGroup(NULL);
setStateFileOpen(true); setStateFileOpen(true);
setStateFileModified(false); setStateFileModified(static_cast<Kdb3Database*>(db)->hasPasswordEncodingChanged());
} }
else{ else{
statusbarState = 2; statusbarState = 2;