summaryrefslogtreecommitdiffabout
authorulf69 <ulf69>2004-11-07 02:10:50 (UTC)
committer ulf69 <ulf69>2004-11-07 02:10:50 (UTC)
commit31c3fc0e0673b9403fb4ef4a9836305d1d49ff83 (patch) (side-by-side diff)
treef5a44f4402294d6fd61e204489cdd776acb804aa
parent2b6072e39edbc8c9ab36e1e835b252a799db97a1 (diff)
downloadkdepimpi-31c3fc0e0673b9403fb4ef4a9836305d1d49ff83.zip
kdepimpi-31c3fc0e0673b9403fb4ef4a9836305d1d49ff83.tar.gz
kdepimpi-31c3fc0e0673b9403fb4ef4a9836305d1d49ff83.tar.bz2
Fixed nasty PwM/Pi file reading bug, when
the used hash algo of file is different then the global hash algo. CVS ----------------------------------------------------------------------
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/libgcryptif.cpp25
-rw-r--r--pwmanager/pwmanager/libgcryptif.h12
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp20
-rw-r--r--pwmanager/pwmanager/pwmdoc.h8
4 files changed, 46 insertions, 19 deletions
diff --git a/pwmanager/pwmanager/libgcryptif.cpp b/pwmanager/pwmanager/libgcryptif.cpp
index ff94bf6..15f6cef 100644
--- a/pwmanager/pwmanager/libgcryptif.cpp
+++ b/pwmanager/pwmanager/libgcryptif.cpp
@@ -32,25 +32,27 @@
#ifdef PWM_EMBEDDED
#include <pwmprefs.h>
#endif
PwMerror LibGCryptIf::encrypt(unsigned char **outBuf,
size_t *outBufLen,
unsigned char *inBuf,
size_t inBufLen,
const unsigned char *key,
size_t keylen,
- char _algo)
+ char _algo,
+ char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
+ )
{
PwMerror ret = e_success;
gcry_error_t err;
gcry_cipher_hd_t handle;
size_t blklen;
size_t unpaddedLen = inBufLen;
size_t cipherKeylen;
unsigned char *hashedKey;
unsigned char salt[STRING2KEY_SALTLEN];
int algo = mapCipherId(_algo);
if (!inBufLen || !keylen)
@@ -96,25 +98,25 @@ PwMerror LibGCryptIf::encrypt(unsigned char **outBuf,
err = gcry_cipher_open(&handle,
algo,
GCRY_CIPHER_MODE_CBC,
0);
if (err != GPG_ERR_NO_ERROR) {
printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_open() failed: ")
+ gcry_strerror(err));
ret = e_cryptNotImpl;
goto out;
}
// hash the "key" to a fixed size hash matching "cipherKeylen"
hashedKey = new unsigned char[cipherKeylen];
- hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, true);
+ hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, true, _hashalgo);
// so now set the hashed key
err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen);
if (err != GPG_ERR_NO_ERROR) {
printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_setkey() failed: ")
+ gcry_strerror(err));
ret = e_cryptNotImpl;
delete [] hashedKey;
goto out_close;
}
delete [] hashedKey;
/* allocate a buffer for the encrypted data.
* The size of the buffer is the inBuf length, but blklen
@@ -143,25 +145,27 @@ out_delete:
out_close:
gcry_cipher_close(handle);
out:
return ret;
}
PwMerror LibGCryptIf::decrypt(unsigned char **outBuf,
size_t *outBufLen,
const unsigned char *inBuf,
size_t inBufLen,
const unsigned char *key,
size_t keylen,
- char _algo)
+ char _algo,
+ char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
+)
{
PwMerror ret = e_success;
gcry_error_t err;
gcry_cipher_hd_t handle;
size_t cipherKeylen;
unsigned char *hashedKey;
unsigned char salt[STRING2KEY_SALTLEN];
int algo = mapCipherId(_algo);
if (!inBufLen || !keylen)
return e_invalidArg;
@@ -192,25 +196,25 @@ PwMerror LibGCryptIf::decrypt(unsigned char **outBuf,
err = gcry_cipher_open(&handle,
algo,
GCRY_CIPHER_MODE_CBC,
0);
if (err != GPG_ERR_NO_ERROR) {
printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_open() failed: ")
+ gcry_strerror(err));
ret = e_cryptNotImpl;
goto out;
}
// hash the "key" to a fixed size hash matching "cipherKeylen"
hashedKey = new unsigned char[cipherKeylen];
- hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, false);
+ hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, false, _hashalgo);
// so now set the hashed key
err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen);
if (err != GPG_ERR_NO_ERROR) {
printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_setkey() failed: ")
+ gcry_strerror(err));
ret = e_cryptNotImpl;
delete [] hashedKey;
goto out_close;
}
delete [] hashedKey;
*outBufLen = inBufLen - STRING2KEY_SALTLEN;
*outBuf = new unsigned char[*outBufLen];
@@ -305,33 +309,38 @@ int LibGCryptIf::mapHashId(char algo)
return GCRY_MD_TIGER;
default:
BUG();
}
return GCRY_MD_NONE;
}
bool LibGCryptIf::hashPassphrase(const unsigned char *pw,
size_t pwlen,
unsigned char *salt,
unsigned char *key,
size_t keylen,
- bool create)
+ bool create,
+ char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
+)
{
DEK dek;
STRING2KEY s2k;
bool ret;
dek.keylen = keylen;
s2k.mode = 1;
- s2k.hash_algo = mapHashId(conf()->confGlobHashAlgo());
+ //US bug: do not use the global hash algo here. Use the passed ago instead. The hashalgo stored in the file can
+ // be different from the one in the configuration.
+ s2k.hash_algo = mapHashId(_hashalgo //conf()->confGlobHashAlgo()
+ );
s2k.count = 0;
if (!create)
memcpy(s2k.salt, salt, STRING2KEY_SALTLEN);
ret = doHashPassphrase(&dek,
pw,
pwlen,
&s2k,
create);
if (!ret)
goto out;
memcpy(key, dek.key, dek.keylen);
if (create)
@@ -430,25 +439,25 @@ void LibGCryptIf::padData(unsigned char *buf,
*b = c;
++i;
}
}
void LibGCryptIf::unpadData(const unsigned char *buf,
size_t *bufLen)
{
size_t pos;
BUG_ON(*bufLen % 8);
pos = *bufLen - 1;
while (buf[pos] != static_cast<char>(0x01)) {
- qDebug("pos %d %d %d", pos, buf[pos], static_cast<char>(0x01) );
+ //qDebug("pos %d %d %d", pos, buf[pos], static_cast<char>(0x01) );
BUG_ON(!pos);
//LR BUG we should terminte the loop if p == 0
if ( pos == 0 )
break;
--pos;
}
*bufLen = pos;
- qDebug("ente ");
+ //qDebug("ente ");
}
#endif // CONFIG_PWMANAGER_GCRY
diff --git a/pwmanager/pwmanager/libgcryptif.h b/pwmanager/pwmanager/libgcryptif.h
index 1a7b658..9a987a2 100644
--- a/pwmanager/pwmanager/libgcryptif.h
+++ b/pwmanager/pwmanager/libgcryptif.h
@@ -64,35 +64,39 @@ public:
/** is libgcrypt available? */
static bool available()
{ return true; }
/** encrypt data. _algo is the PWM_CRYPT_* ID
* of the algorithm.
*/
PwMerror encrypt(unsigned char **outBuf,
size_t *outBufLen,
unsigned char *inBuf,
size_t inBufLen,
const unsigned char *key,
size_t keylen,
- char _algo);
+ char _algo,
+ char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
+);
/** decrypt data. _algo is the PWM_CRYPT_* ID
* of the algorithm.
*/
PwMerror decrypt(unsigned char **outBuf,
size_t *outBufLen,
const unsigned char *inBuf,
size_t inBufLen,
const unsigned char *key,
size_t keylen,
- char _algo);
+ char _algo,
+ char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
+);
/** hash data. _algo is the PWM_HASH_* ID of the hash */
PwMerror hash(unsigned char **outBuf,
size_t *outBufLen,
const unsigned char *inBuf,
size_t inBufLen,
char _algo);
/** returns the length of the hash. _algo is the PWM_HASH_*
* id of the hash. returns 0 on error.
*/
unsigned int hashLength(char _algo);
protected:
@@ -115,25 +119,27 @@ protected:
*/
int mapCipherId(char algo);
/** maps the PWM_HASH_* ID of an algorithm
* to the libgcrypt GCRY_MD_* ID
*/
int mapHashId(char algo);
/** hash a passphrase to a cipher key */
bool hashPassphrase(const unsigned char *pw,
size_t pwlen,
unsigned char *salt,
unsigned char *key,
size_t keylen,
- bool create);
+ bool create,
+ char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
+);
/** hash a passphrase to a cipher key */
bool doHashPassphrase(DEK *dek,
const unsigned char *pw,
size_t pwlen,
STRING2KEY *s2k,
bool create);
};
#else // CONFIG_PWMANAGER_GCRY
/** libgcrypt is not installed. This is a NOP wrapper. */
class LibGCryptIf
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index 17cb74a..a740d6d 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -478,25 +478,25 @@ PwMerror PwMDoc::saveDoc(char compress, const QString *file)
} else if (e != e_success) {
printDebug("PwMDoc::saveDoc(): writeDataHash() failed");
f.close();
ret = e_writeHeader;
goto out_moveback;
}
if (!compressDta(&serialized, compress)) {
printDebug("PwMDoc::saveDoc(): compressDta() failed");
f.close();
ret = e_enc;
goto out_moveback;
}
- e = encrypt(&serialized, &currentPw, &f, cryptAlgo);
+ e = encrypt(&serialized, &currentPw, &f, cryptAlgo, hashAlgo);
if (e == e_weakPw) {
printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw");
f.close();
ret = e_weakPw;
goto out_moveback;
} else if (e == e_cryptNotImpl) {
printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl");
f.close();
ret = e_cryptNotImpl;
goto out_moveback;
} else if (e != e_success) {
printDebug("PwMDoc::saveDoc(): encrypt() failed");
@@ -598,25 +598,25 @@ PwMerror PwMDoc::openDoc(const QString *file, int openLocked)
f.close();
if (ret == e_wrongPw) {
wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
return ret;
} else if (ret == e_noPw ||
ret == e_fileVer ||
ret == e_fileFormat ||
ret == e_hashNotImpl) {
return ret;
} else
return e_readFile;
}
- ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, &f);
+ ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, dataHashType, &f);
if (ret == e_cryptNotImpl) {
printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl");
f.close();
return e_cryptNotImpl;
} else if (ret != e_success) {
printDebug("PwMDoc::openDoc(): decrypt() failed");
f.close();
return e_readFile;
}
if (!decompressDta(&decrypted, compress)) {
printDebug("PwMDoc::openDoc(): decompressDta() failed");
f.close();
@@ -1298,25 +1298,27 @@ bool PwMDoc::decompressDta(string *d, char algo)
case PWM_COMPRESS_BZIP2: {
CompressBzip2 comp;
return comp.decompress(d);
}
#endif
case PWM_COMPRESS_NONE: {
return true;
}
}
return false;
}
-PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo)
+PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo,
+ char hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
+)
{
PWM_ASSERT(d);
PWM_ASSERT(pw);
PWM_ASSERT(f);
size_t encSize;
byte *encrypted = 0;
switch (algo) {
case PWM_CRYPT_BLOWFISH: {
Blowfish::padNull(d);
encSize = d->length();
@@ -1339,48 +1341,52 @@ PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo)
if (!LibGCryptIf::available())
return e_cryptNotImpl;
LibGCryptIf gc;
PwMerror err;
unsigned char *plain = new unsigned char[d->length() + 1024];
memcpy(plain, d->c_str(), d->length());
err = gc.encrypt(&encrypted,
&encSize,
plain,
d->length(),
reinterpret_cast<const unsigned char *>(pw->latin1()),
pw->length(),
- algo);
+ algo,
+ hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
+ );
delete [] plain;
if (err != e_success)
return e_cryptNotImpl;
break;
}
default: {
delete_ifnot_null_array(encrypted);
return e_cryptNotImpl;
} }
// write encrypted data to file
if (f->writeBlock(reinterpret_cast<const char *>(encrypted),
static_cast<Q_ULONG>(encSize))
!= static_cast<Q_LONG>(encSize)) {
delete_ifnot_null_array(encrypted);
return e_writeFile;
}
delete_ifnot_null_array(encrypted);
return e_success;
}
PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
- char algo, QFile *f)
+ char algo,
+ char hashalgo, //US BUG: pass _hashalgo because we need it in hashPassphrase
+ QFile *f)
{
PWM_ASSERT(d);
PWM_ASSERT(pw);
PWM_ASSERT(f);
unsigned int cryptLen = f->size() - pos;
byte *encrypted = new byte[cryptLen];
byte *decrypted = new byte[cryptLen];
f->at(pos);
#ifndef PWM_EMBEDDED
if (f->readBlock(reinterpret_cast<char *>(encrypted),
@@ -1414,25 +1420,27 @@ PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
case PWM_CRYPT_TWOFISH:
case PWM_CRYPT_TWOFISH128: {
if (!LibGCryptIf::available())
return e_cryptNotImpl;
LibGCryptIf gc;
PwMerror err;
err = gc.decrypt(&decrypted,
&cryptLen,
encrypted,
cryptLen,
reinterpret_cast<const unsigned char *>(pw->latin1()),
pw->length(),
- algo);
+ algo,
+ hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
+);
if (err != e_success) {
delete [] encrypted;
delete [] decrypted;
return e_cryptNotImpl;
}
break;
}
default: {
delete [] encrypted;
delete [] decrypted;
return e_cryptNotImpl;
} }
diff --git a/pwmanager/pwmanager/pwmdoc.h b/pwmanager/pwmanager/pwmdoc.h
index 138dd3d..9fcdda7 100644
--- a/pwmanager/pwmanager/pwmdoc.h
+++ b/pwmanager/pwmanager/pwmdoc.h
@@ -727,27 +727,31 @@ protected:
PwMerror writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
QString *pw, QFile *f);
/** write data-hash to file */
PwMerror writeDataHash(char dataHash, string *d, QFile *f);
/** check header. Read header info and verify key-hash and filever.
* returns length of header in "headerLength" */
PwMerror checkHeader(char *cryptAlgo, QString *pw, char *compress,
unsigned int *headerLength, char *dataHashType,
string *dataHash, QFile *f);
/** check the data-hash */
PwMerror checkDataHash(char dataHashType, const string *dataHash, const string *dataStream);
/** encrypt data "d" and write to "filename" */
- PwMerror encrypt(string *d, const QString *pw, QFile *f, char algo);
+ PwMerror encrypt(string *d, const QString *pw, QFile *f, char algo,
+ char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
+);
/** read data from file beginning at "pos", decrypt and return it */
- PwMerror decrypt(string *d, unsigned int pos, const QString *pw, char algo, QFile *f);
+ PwMerror decrypt(string *d, unsigned int pos, const QString *pw, char algo,
+ char _hashalgo, //US BUG: pass _hashalgo because we need it in hashPassphrase
+QFile *f);
/** compress the data */
bool compressDta(string *d, char algo);
/** uncompress the data */
bool decompressDta(string *d, char algo);
/** internal import function for a text-file generated by PwM.
* If this is not a valid PwM-exported file, it returns e_fileFormat */
PwMerror importText_PwM(const QString *file);
/** PwM-text-import helper function to extract the name/pw/comment out
* of one entry-line */
bool textExtractEntry_PwM(const char *in, ssize_t in_size, string *out);
/** compare two strings */
bool compareString(const string &s1, const string &s2, bool caseSensitive,