fixed password encoding problem (bug #1687864)
git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@190 b624d157-de02-0410-bad0-e51aec6abb33
This commit is contained in:
parent
5bb7d02298
commit
daaa9b866a
|
@ -1,5 +1,5 @@
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2005-2007 by Tarek Saidi *
|
* Copyright (C) 2005-2008 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 *
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
#include <QTextCodec>
|
||||||
#include "Kdb3Database.h"
|
#include "Kdb3Database.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -432,6 +433,7 @@ if(!File->open(QIODevice::ReadWrite)){
|
||||||
}
|
}
|
||||||
total_size=File->size();
|
total_size=File->size();
|
||||||
char* buffer = new char[total_size];
|
char* buffer = new char[total_size];
|
||||||
|
DECRYPT:
|
||||||
File->read(buffer,total_size);
|
File->read(buffer,total_size);
|
||||||
|
|
||||||
if(total_size < DB_HEADER_SIZE){
|
if(total_size < DB_HEADER_SIZE){
|
||||||
|
@ -463,6 +465,7 @@ else if(Flags & PWM_FLAG_TWOFISH) Algorithm = Twofish_Cipher;
|
||||||
else{error=tr("Unknown Encryption Algorithm.");
|
else{error=tr("Unknown Encryption Algorithm.");
|
||||||
return false;}
|
return false;}
|
||||||
|
|
||||||
|
|
||||||
if(!transformKey(RawMasterKey,MasterKey,TransfRandomSeed,KeyTransfRounds))return false;
|
if(!transformKey(RawMasterKey,MasterKey,TransfRandomSeed,KeyTransfRounds))return false;
|
||||||
quint8 FinalKey[32];
|
quint8 FinalKey[32];
|
||||||
|
|
||||||
|
@ -471,27 +474,38 @@ sha.update(FinalRandomSeed,16);
|
||||||
sha.update(MasterKey,32);
|
sha.update(MasterKey,32);
|
||||||
sha.finish(FinalKey);
|
sha.finish(FinalKey);
|
||||||
|
|
||||||
if(Algorithm == Rijndael_Cipher)
|
if(Algorithm == Rijndael_Cipher){
|
||||||
{ AESdecrypt aes;
|
AESdecrypt aes;
|
||||||
aes.key256(FinalKey);
|
aes.key256(FinalKey);
|
||||||
aes.cbc_decrypt((unsigned char*)buffer+DB_HEADER_SIZE,(unsigned char*)buffer+DB_HEADER_SIZE,total_size-DB_HEADER_SIZE,(unsigned char*)EncryptionIV);
|
aes.cbc_decrypt((unsigned char*)buffer+DB_HEADER_SIZE,(unsigned char*)buffer+DB_HEADER_SIZE,total_size-DB_HEADER_SIZE,(unsigned char*)EncryptionIV);
|
||||||
crypto_size=total_size-((quint8*)buffer)[total_size-1]-DB_HEADER_SIZE;
|
crypto_size=total_size-((quint8*)buffer)[total_size-1]-DB_HEADER_SIZE;
|
||||||
}
|
}
|
||||||
else if(Algorithm == Twofish_Cipher)
|
else if(Algorithm == Twofish_Cipher){
|
||||||
{
|
CTwofish twofish;
|
||||||
CTwofish twofish;
|
if(twofish.init(FinalKey, 32, EncryptionIV) != true){return false;}
|
||||||
if(twofish.init(FinalKey, 32, EncryptionIV) != true){return false;}
|
crypto_size = (unsigned long)twofish.padDecrypt((quint8 *)buffer + DB_HEADER_SIZE,
|
||||||
crypto_size = (unsigned long)twofish.padDecrypt((quint8 *)buffer + DB_HEADER_SIZE,
|
total_size - DB_HEADER_SIZE, (quint8 *)buffer + DB_HEADER_SIZE);
|
||||||
total_size - DB_HEADER_SIZE, (quint8 *)buffer + DB_HEADER_SIZE);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if((crypto_size > 2147483446) || (!crypto_size && NumGroups)){error=tr("Decryption failed.\nThe key is wrong or the file is damaged."); return false;}
|
if((crypto_size > 2147483446) || (!crypto_size && NumGroups)){error=tr("Decryption failed.\nThe key is wrong or the file is damaged."); return false;}
|
||||||
SHA256::hashBuffer(buffer+DB_HEADER_SIZE,FinalKey,crypto_size);
|
SHA256::hashBuffer(buffer+DB_HEADER_SIZE,FinalKey,crypto_size);
|
||||||
|
|
||||||
if(memcmp(ContentsHash, FinalKey, 32) != 0){
|
if(memcmp(ContentsHash, FinalKey, 32) != 0){
|
||||||
|
delete buffer;
|
||||||
|
if(PotentialEncodingIssue){
|
||||||
|
// KeePassX used Latin-1 encoding for passwords until version 0.3.1
|
||||||
|
// but KeePass/Win32 uses Windows Codepage 1252.
|
||||||
|
// Too stay compatible with databases created with KeePassX <= 0.3.1
|
||||||
|
// the loading function gives both encodings a try.
|
||||||
|
memcpy(RawMasterKey,RawMasterKey_Latin1,32);
|
||||||
|
PotentialEncodingIssue=false;
|
||||||
|
qDebug("Decryption failed. Retrying with Latin-1.");
|
||||||
|
return load(filename); // second 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;
|
||||||
return false;}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long pos = DB_HEADER_SIZE;
|
unsigned long pos = DB_HEADER_SIZE;
|
||||||
quint16 FieldType;
|
quint16 FieldType;
|
||||||
|
@ -737,10 +751,23 @@ bool Kdb3Database::setKey(const QString& password,const QString& keyfile){
|
||||||
|
|
||||||
bool Kdb3Database::setPasswordKey(const QString& Password){
|
bool Kdb3Database::setPasswordKey(const QString& Password){
|
||||||
assert(Password.size());
|
assert(Password.size());
|
||||||
SHA256::hashBuffer(Password.toLatin1().data(),RawMasterKey,Password.toLatin1().size());
|
QTextCodec* codec=QTextCodec::codecForName("Windows-1252");
|
||||||
QByteArray lat,utf;
|
QByteArray Password_CP1252 = codec->fromUnicode(Password);
|
||||||
utf=Password.toUtf8();
|
SHA256::hashBuffer(Password_CP1252.data(),RawMasterKey,Password_CP1252.size());
|
||||||
lat=Password.toLatin1();
|
QByteArray Password_Latin1 = Password.toLatin1();
|
||||||
|
if(Password_Latin1 != Password_CP1252){
|
||||||
|
// KeePassX used Latin-1 encoding for passwords until version 0.3.1
|
||||||
|
// but KeePass/Win32 uses Windows Codepage 1252.
|
||||||
|
// Too stay compatible with databases created with KeePassX <= 0.3.1
|
||||||
|
// the loading function gives both encodings a try.
|
||||||
|
PotentialEncodingIssue = true;
|
||||||
|
SHA256::hashBuffer(Password_Latin1.data(),RawMasterKey_Latin1,Password_Latin1.size());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If the password does not contain problematic characters we don't need
|
||||||
|
// to try both encodings.
|
||||||
|
PotentialEncodingIssue = false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -242,11 +242,13 @@ private:
|
||||||
QFile* File;
|
QFile* File;
|
||||||
QString error;
|
QString error;
|
||||||
bool KeyError;
|
bool KeyError;
|
||||||
|
bool PotentialEncodingIssue;
|
||||||
QList<StdEntry> UnknownMetaStreams;
|
QList<StdEntry> UnknownMetaStreams;
|
||||||
QMap<quint32,bool> TreeStateMetaStream;
|
QMap<quint32,bool> TreeStateMetaStream;
|
||||||
unsigned int KeyTransfRounds;
|
unsigned int KeyTransfRounds;
|
||||||
CryptAlgorithm Algorithm;
|
CryptAlgorithm Algorithm;
|
||||||
quint8 RawMasterKey[32];
|
quint8 RawMasterKey[32];
|
||||||
|
quint8 RawMasterKey_Latin1[32];
|
||||||
quint8 MasterKey[32];
|
quint8 MasterKey[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue