summaryrefslogtreecommitdiffabout
authorulf69 <ulf69>2004-10-15 22:47:12 (UTC)
committer ulf69 <ulf69>2004-10-15 22:47:12 (UTC)
commit1821dcc08c8f6f2bc0fdb991c335ed03262d1443 (patch) (side-by-side diff)
tree93249cb2cc3fbb57cc8cf6688afbc252629b62a4
parent71ee1be533cdbe7ce50c4f617254011fc640e88e (diff)
downloadkdepimpi-1821dcc08c8f6f2bc0fdb991c335ed03262d1443.zip
kdepimpi-1821dcc08c8f6f2bc0fdb991c335ed03262d1443.tar.gz
kdepimpi-1821dcc08c8f6f2bc0fdb991c335ed03262d1443.tar.bz2
*** empty log message ***
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--pwmanager/pwmanager/libgcryptif.cpp420
-rw-r--r--pwmanager/pwmanager/libgcryptif.h5
-rw-r--r--pwmanager/pwmanager/pwmanagerE.pro10
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp77
4 files changed, 446 insertions, 66 deletions
diff --git a/pwmanager/pwmanager/libgcryptif.cpp b/pwmanager/pwmanager/libgcryptif.cpp
index 8e55144..6f3a994 100644
--- a/pwmanager/pwmanager/libgcryptif.cpp
+++ b/pwmanager/pwmanager/libgcryptif.cpp
@@ -420,16 +420,436 @@ void LibGCryptIf::padData(unsigned char *buf,
}
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)) {
BUG_ON(!pos);
--pos;
}
*bufLen = pos;
}
#endif // CONFIG_PWMANAGER_GCRY
+
+#ifdef CONFIG_PWMANAGER_CRYPTO
+
+#include "pwmdoc.h"
+#include "randomizer.h"
+
+#include <openssl/crypto.h>
+
+PwMerror LibGCryptIf::encrypt(unsigned char **outBuf,
+ size_t *outBufLen,
+ unsigned char *inBuf,
+ size_t inBufLen,
+ const unsigned char *key,
+ size_t keylen,
+ char _algo)
+{
+ 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)
+ return e_invalidArg;
+
+ // test if algo is ready for encryption
+ err = gcry_cipher_algo_info(algo,
+ GCRYCTL_TEST_ALGO,
+ 0, 0);
+ if (err != GPG_ERR_NO_ERROR) {
+ printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_TEST_ALGO failed: ")
+ + gcry_strerror(err));
+ ret = e_cryptNotImpl;
+ goto out;
+ }
+ // get the algo block length
+ err = gcry_cipher_algo_info(algo,
+ GCRYCTL_GET_BLKLEN,
+ 0,
+ &blklen);
+ if (err != GPG_ERR_NO_ERROR) {
+ printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_BLKLEN failed: ")
+ + gcry_strerror(err));
+ ret = e_cryptNotImpl;
+ goto out;
+ }
+ /* double check if we have enough space.
+ * We have only 1024 extra bytes for padding and salt.
+ */
+ BUG_ON(blklen > 1024 - STRING2KEY_SALTLEN);
+ // get the algo key length
+ err = gcry_cipher_algo_info(algo,
+ GCRYCTL_GET_KEYLEN,
+ 0,
+ &cipherKeylen);
+ if (err != GPG_ERR_NO_ERROR) {
+ printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_KEYLEN failed: ")
+ + gcry_strerror(err));
+ ret = e_cryptNotImpl;
+ goto out;
+ }
+ // now open the algo and get a handle
+ 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);
+ // 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
+ * aligned and plus the length of the salt, that is appended.
+ */
+ *outBufLen = getBufLen(unpaddedLen, blklen) + STRING2KEY_SALTLEN;
+ *outBuf = new unsigned char[*outBufLen];
+ padData(inBuf, unpaddedLen, blklen);
+ // encrypt the padded data
+ err = gcry_cipher_encrypt(handle,
+ *outBuf,
+ *outBufLen - STRING2KEY_SALTLEN,
+ inBuf,
+ *outBufLen - STRING2KEY_SALTLEN);
+ if (err != GPG_ERR_NO_ERROR) {
+ printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ")
+ + gcry_strerror(err));
+ ret = e_cryptNotImpl;
+ goto out_delete;
+ }
+ // append the salt to the encrypted data
+ memcpy(*outBuf + *outBufLen - STRING2KEY_SALTLEN, salt, STRING2KEY_SALTLEN);
+ goto out_close;
+out_delete:
+ delete [] *outBuf;
+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)
+{
+ 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;
+
+ // test if algo is ready for encryption
+ err = gcry_cipher_algo_info(algo,
+ GCRYCTL_TEST_ALGO,
+ 0, 0);
+ if (err != GPG_ERR_NO_ERROR) {
+ printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_TEST_ALGO failed: ")
+ + gcry_strerror(err));
+ ret = e_cryptNotImpl;
+ goto out;
+ }
+ // get algo key length
+ err = gcry_cipher_algo_info(algo,
+ GCRYCTL_GET_KEYLEN,
+ 0,
+ &cipherKeylen);
+ if (err != GPG_ERR_NO_ERROR) {
+ printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_GET_KEYLEN failed: ")
+ + gcry_strerror(err));
+ ret = e_cryptNotImpl;
+ goto out;
+ }
+ // extract the salt of the encrypted data buffer
+ memcpy(salt, inBuf + inBufLen - STRING2KEY_SALTLEN, STRING2KEY_SALTLEN);
+ // open the algo and get a handle
+ 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);
+ // 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];
+ // decrypt the data
+ err = gcry_cipher_decrypt(handle,
+ *outBuf,
+ *outBufLen,
+ inBuf,
+ *outBufLen);
+ if (err != GPG_ERR_NO_ERROR) {
+ printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ")
+ + gcry_strerror(err));
+ ret = e_cryptNotImpl;
+ goto out_delete;
+ }
+ // remove all random padding
+ unpadData(*outBuf, outBufLen);
+ goto out_close;
+out_delete:
+ delete [] *outBuf;
+out_close:
+ gcry_cipher_close(handle);
+out:
+ return ret;
+}
+
+PwMerror LibGCryptIf::hash(unsigned char **outBuf,
+ size_t *outBufLen,
+ const unsigned char *inBuf,
+ size_t inBufLen,
+ char _algo)
+{
+ PwMerror ret = e_success;
+ unsigned int hashLen;
+ int algo = mapHashId(_algo);
+
+ hashLen = gcry_md_get_algo_dlen(algo);
+ *outBufLen = hashLen;
+ *outBuf = new unsigned char[*outBufLen];
+ gcry_md_hash_buffer(algo,
+ *outBuf,
+ inBuf,
+ inBufLen);
+ return ret;
+}
+
+unsigned int LibGCryptIf::hashLength(char _algo)
+{
+ unsigned int ret;
+ int algo = mapHashId(_algo);
+ ret = gcry_md_get_algo_dlen(algo);
+ return ret;
+}
+
+int LibGCryptIf::mapCipherId(char algo)
+{
+ switch (algo) {
+ case PWM_CRYPT_AES128:
+ return GCRY_CIPHER_AES;
+ case PWM_CRYPT_AES192:
+ return GCRY_CIPHER_AES192;
+ case PWM_CRYPT_AES256:
+ return GCRY_CIPHER_AES256;
+ case PWM_CRYPT_3DES:
+ return GCRY_CIPHER_3DES;
+ case PWM_CRYPT_TWOFISH:
+ return GCRY_CIPHER_TWOFISH;
+ case PWM_CRYPT_TWOFISH128:
+ return GCRY_CIPHER_TWOFISH128;
+ default:
+ BUG();
+ }
+ return GCRY_CIPHER_NONE;
+}
+
+int LibGCryptIf::mapHashId(char algo)
+{
+ switch (algo) {
+ case PWM_HASH_SHA1:
+ return GCRY_MD_SHA1;
+ case PWM_HASH_SHA256:
+ return GCRY_MD_SHA256;
+ case PWM_HASH_SHA384:
+ return GCRY_MD_SHA384;
+ case PWM_HASH_SHA512:
+ return GCRY_MD_SHA512;
+ case PWM_HASH_MD5:
+ return GCRY_MD_MD5;
+ case PWM_HASH_RMD160:
+ return GCRY_MD_RMD160;
+ case PWM_HASH_TIGER:
+ 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)
+{
+ DEK dek;
+ STRING2KEY s2k;
+ bool ret;
+
+ dek.keylen = keylen;
+ s2k.mode = 1;
+ s2k.hash_algo = mapHashId(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)
+ memcpy(salt, s2k.salt, STRING2KEY_SALTLEN);
+out:
+ return ret;
+}
+
+
+bool LibGCryptIf::doHashPassphrase(DEK *dek,
+ const unsigned char *pw,
+ size_t pwlen,
+ STRING2KEY *s2k,
+ bool create)
+{
+ // This function is derived from GnuPG-1.2.5-rc2
+ gcry_md_hd_t md;
+ gcry_error_t err;
+ bool ret = true;
+ size_t pass, i;
+ size_t used = 0;
+
+ PWM_ASSERT(s2k->hash_algo);
+ BUG_ON(!(dek->keylen > 0 && dek->keylen <= array_size(dek->key)));
+
+ err = gcry_md_open(&md, s2k->hash_algo, 0);
+ if (err != GPG_ERR_NO_ERROR) {
+ ret = false;
+ goto out;
+ }
+ for (pass = 0; used < dek->keylen; pass++) {
+ if (pass) {
+ gcry_md_reset(md);
+ for (i = 0; i < pass; i++) // preset the hash context
+ gcry_md_putc(md, 0);
+ }
+ if (s2k->mode == 1 || s2k->mode == 3) {
+ size_t len2 = pwlen + 8;
+ size_t count = len2;
+
+ if (create && !pass) {
+ Randomizer *rnd = Randomizer::obj();
+ const unsigned int salt_len = 8;
+ string rndBuf(rnd->genRndBuf(salt_len));
+ memcpy(s2k->salt, rndBuf.c_str(), salt_len);
+ if (s2k->mode == 3)
+ s2k->count = 96; // 65536 iterations
+ }
+ if (s2k->mode == 3) {
+ count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
+ if (count < len2)
+ count = len2;
+ }
+ // a little bit complicated because we need a ulong for count
+ while (count > len2) { // maybe iterated+salted
+ gcry_md_write(md, s2k->salt, 8);
+ gcry_md_write(md, pw, pwlen);
+ count -= len2;
+ }
+ if (count < 8) {
+ gcry_md_write(md, s2k->salt, count);
+ } else {
+ gcry_md_write(md, s2k->salt, 8);
+ count -= 8;
+ gcry_md_write(md, pw, count);
+ }
+ } else
+ gcry_md_write(md, pw, pwlen);
+ gcry_md_final(md);
+ i = gcry_md_get_algo_dlen(s2k->hash_algo);
+ if (i > dek->keylen - used)
+ i = dek->keylen - used;
+ memcpy(dek->key+used, gcry_md_read(md, s2k->hash_algo), i);
+ used += i;
+ }
+ gcry_md_close(md);
+out:
+ return ret;
+}
+
+void LibGCryptIf::padData(unsigned char *buf,
+ size_t bufLen,
+ size_t boundary)
+{
+ size_t numPadBytes = boundary - ((bufLen + 1) % boundary);
+ buf[bufLen] = static_cast<char>(0x01);
+ size_t i = 0;
+ Randomizer *rnd = Randomizer::obj();
+ char c;
+ unsigned char *b;
+ while (i < numPadBytes) {
+ c = rnd->genRndChar();
+ if (c == static_cast<char>(0x01))
+ continue;
+ b = buf + bufLen + 1 + i;
+ *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)) {
+ BUG_ON(!pos);
+ --pos;
+ }
+ *bufLen = pos;
+}
+
+#endif // CONFIG_PWMANAGER_CRYPTO
+
diff --git a/pwmanager/pwmanager/libgcryptif.h b/pwmanager/pwmanager/libgcryptif.h
index e86d638..7390827 100644
--- a/pwmanager/pwmanager/libgcryptif.h
+++ b/pwmanager/pwmanager/libgcryptif.h
@@ -5,34 +5,37 @@
* *
* hashPassphrase() is derived from GnuPG and is *
* Copyright (C) 1998, 1999, 2000, 2001, 2003 *
* Free Software Foundation, Inc. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
#ifndef __LIBGCRYPTIF_H
#define __LIBGCRYPTIF_H
#include "pwmexception.h"
+//US ENH: should we put this better into globalstuff.h?
+#define CONFIG_PWMANAGER_CRYPTO
+
//#undef CONFIG_PWMANAGER_GCRY // for debugging only.
-#ifdef CONFIG_PWMANAGER_GCRY
+#if defined CONFIG_PWMANAGER_GCRY || defined CONFIG_PWMANAGER_CRYPTO
#include <stddef.h>
#include <sys/types.h>
#include <stdint.h>
#define STRING2KEY_SALTLEN 8
/** interface class for the libgcrypt cipher and hash algorithms
* NOTE: Always allocate 1024 extra bytes for the inBuf (for padding)
*/
class LibGCryptIf
{
protected:
struct STRING2KEY
{
int mode;
diff --git a/pwmanager/pwmanager/pwmanagerE.pro b/pwmanager/pwmanager/pwmanagerE.pro
index 52d7586..294f549 100644
--- a/pwmanager/pwmanager/pwmanagerE.pro
+++ b/pwmanager/pwmanager/pwmanagerE.pro
@@ -1,84 +1,85 @@
TEMPLATE = app
CONFIG += qt warn_on
TARGET = pwmpi
OBJECTS_DIR = obj/$(PLATFORM)
MOC_DIR = moc/$(PLATFORM)
DESTDIR=$(QPEDIR)/bin
INCLUDEPATH += . ../../ ../../qtcompat ../../qtcompat/xml ../../libkdepim ../../microkde ../../microkde/kdecore ../../microkde/kdeui ../../microkde/kutils $(QPEDIR)/include
DEFINES += PWM_EMBEDDED
#enable this setting if you want debugoutput for pwmanager
-#DEFINES += CONFIG_DEBUG
+DEFINES += CONFIG_DEBUG
LIBS += -lmicrokde
LIBS += -lmicroqtcompat
LIBS += -lmicrokdepim
LIBS += -L$(QPEDIR)/lib
LIBS += -lqpe
LIBS += -lz
-LIBS += -lbz2
+#LIBS += -lbz2
LIBS += -lcrypto
LIBS += $(QTOPIALIB)
#INTERFACES = \
#addentrywnd.ui \
#configwnd.ui \
#findwnd.ui \
#getmasterpwwnd.ui \
#pwgenwnd.ui \
#setmasterpwwnd.ui \
#subtbledit.ui
#INTERFACES = \
#subtbledit.ui \
#HEADERS = \
#configuration_31compat.h \
#configuration.h \
#configwnd.h \
#configwndimpl.h \
#selftest.h
#subtbledit.h \
#subtbleditimpl.h \
+#compressbzip2.h \
HEADERS = \
addentrywnd_emb.h \
addentrywndimpl.h \
base64.h \
binentrygen.h \
blowfish.h \
commentbox.h \
compiler.h \
-compressbzip2.h \
compressgzip.h \
findwnd_emb.h \
findwndimpl.h \
genpasswd.h \
getkeycardwnd.h \
getmasterpwwnd_emb.h \
getmasterpwwndimpl.h \
globalstuff.h \
gpasmanfile.h \
htmlgen.h \
htmlparse.h \
ipc.h \
+libgcryptif.h \
listobjselectwnd.h \
listviewpwm.h \
printtext.h \
pwgenwnd_emb.h \
pwgenwndimpl.h \
pwmdoc.h \
pwmdocui.h \
pwmexception.h \
pwm.h \
pwminit.h \
pwmprefs.h \
pwmprint.h \
pwmtray.h \
pwmview.h \
pwmviewstyle_0.h \
pwmviewstyle_1.h \
@@ -95,52 +96,53 @@ kcmconfigs/kcmpwmconfig.h \
kcmconfigs/pwmconfigwidget.h \
#sources that need not be build
#SOURCES = \
#advcommeditimpl.cpp \
#configuration.cpp \
#configwnd.cpp \
#configwndimpl.cpp \
#configuration_31compat.cpp \
#htmlparse.cpp \
#printtext.cpp \
#selftest.cpp \
#pwmprint.cpp \
#spinforsignal.cpp
#subtbledit.cpp \
#subtbleditimpl.cpp \
+#compressbzip2.cpp \
SOURCES = \
addentrywnd_emb.cpp \
addentrywndimpl.cpp \
base64.cpp \
binentrygen.cpp \
blowfish.cpp \
commentbox.cpp \
-compressbzip2.cpp \
compressgzip.cpp \
findwnd_emb.cpp \
findwndimpl.cpp \
genpasswd.cpp \
getkeycardwnd.cpp \
getmasterpwwnd_emb.cpp \
getmasterpwwndimpl.cpp \
globalstuff.cpp \
gpasmanfile.cpp \
htmlgen.cpp \
ipc.cpp \
+libgcryptif.cpp \
listobjselectwnd.cpp \
listviewpwm.cpp \
main.cpp \
pwgenwnd_emb.cpp \
pwgenwndimpl.cpp \
pwm.cpp \
pwmdoc.cpp \
pwmdocui.cpp \
pwmexception.cpp \
pwminit.cpp \
pwmprefs.cpp \
pwmtray.cpp \
pwmview.cpp \
pwmviewstyle_0.cpp \
pwmviewstyle_1.cpp \
pwmviewstyle.cpp \
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index 4ad392e..a5df8f0 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -15,63 +15,74 @@
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#include "pwmdoc.h"
#include "pwmview.h"
#include "blowfish.h"
#include "sha1.h"
#include "globalstuff.h"
#include "gpasmanfile.h"
#include "serializer.h"
#include "compressgzip.h"
#include "compressbzip2.h"
#include "randomizer.h"
#include "pwminit.h"
-#ifndef PWM_EMBEDDED
-//US #include "libgryptif.h"
-#else
+#include "libgcryptif.h"
+#ifdef PWM_EMBEDDED
#include "pwmprefs.h"
#include "kglobal.h"
#endif
#include <kmessagebox.h>
#include <libkcal/syncdefines.h>
#ifdef CONFIG_KWALLETIF
# include "kwalletemu.h"
#endif // CONFIG_KWALLETIF
#include <qdatetime.h>
#include <qsize.h>
#include <qfileinfo.h>
#include <qfile.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
//US#include <iostream>
#include <algorithm>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdint.h>
+
+#ifdef PWM_EMBEDDED
+#ifndef Q_LONG
+#define Q_LONG long
+#endif
+
+#ifndef Q_ULONG
+#define Q_ULONG unsigned long
+#endif
+#endif //PWM_EMBEDDED
+
+
//TODO: reset to its normal value.
#define META_CHECK_TIMER_INTERVAL 10/*300*/ /* sek */
using namespace std;
void PwMDocList::add(PwMDoc *doc, const string &id)
{
#ifdef PWM_DEBUG
// check for existance of object in debug mode only.
vector<listItem>::iterator begin = docList.begin(),
end = docList.end(),
i = begin;
while (i != end) {
if (i->doc == doc) {
BUG();
@@ -339,39 +350,35 @@ PwMerror PwMDoc::saveDoc(char compress, const QString *file)
/* password is not available. This means, the
* document wasn't saved, yet.
*/
bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
QString pw(requestNewMpw(&useChipcard));
if (pw != "") {
currentPw = pw;
} else {
return e_noPw;
}
if (useChipcard) {
setDocStatFlag(DOC_STAT_USE_CHIPCARD);
} else {
unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
}
}
-#ifndef PWM_EMBEDDED
+
int _cryptAlgo = conf()->confGlobCryptAlgo();
int _hashAlgo = conf()->confGlobHashAlgo();
-#else
- int _cryptAlgo = PWM_CRYPT_BLOWFISH;
- int _hashAlgo = PWM_HASH_SHA1;
-#endif
// sanity check for the selected algorithms
if (_cryptAlgo < PWM_CRYPT_BLOWFISH ||
_cryptAlgo > PWM_CRYPT_TWOFISH128) {
printWarn("Invalid Crypto-Algorithm selected! "
"Config-file seems to be corrupt. "
"Falling back to Blowfish.");
_cryptAlgo = PWM_CRYPT_BLOWFISH;
}
if (_hashAlgo < PWM_HASH_SHA1 ||
_hashAlgo > PWM_HASH_TIGER) {
printWarn("Invalid Hash-Algorithm selected! "
"Config-file seems to be corrupt. "
"Falling back to SHA1.");
_hashAlgo = PWM_HASH_SHA1;
}
@@ -586,110 +593,92 @@ PwMerror PwMDoc::openDoc(const QString *file, int openLocked)
}
f.close();
timer()->start(DocTimer::id_mpwTimer);
timer()->start(DocTimer::id_autoLockTimer);
out_success:
openDocList.edit(this, getTitle().latin1());
emit docOpened(this);
return e_success;
}
PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
QString *pw, QFile *f)
{
PWM_ASSERT(pw);
PWM_ASSERT(f);
PWM_ASSERT(listView);
-#ifndef PWM_EMBEDDED
if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) {
return e_writeFile;
}
if (f->putch(PWM_FILE_VER) == -1 ||
f->putch(keyHash) == -1 ||
f->putch(dataHash) == -1 ||
f->putch(crypt) == -1 ||
f->putch(compress) == -1 ||
f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ?
(static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) {
return e_writeFile;
}
-#else
- if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
- (long)(strlen(FILE_ID_HEADER))) {
- return e_writeFile;
- }
- if (f->putch(PWM_FILE_VER) == -1 ||
- f->putch(keyHash) == -1 ||
- f->putch(dataHash) == -1 ||
- f->putch(crypt) == -1 ||
- f->putch(compress) == -1 ||
- f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ?
- ((char)(0x01)) : ((char)(0x00))) == -1) {
- return e_writeFile;
- }
-#endif
// write bytes of NUL-data. These bytes are reserved for future-use.
const int bufSize = 64;
char tmp_buf[bufSize];
memset(tmp_buf, 0x00, bufSize);
if (f->writeBlock(tmp_buf, bufSize) != bufSize)
return e_writeFile;
switch (keyHash) {
case PWM_HASH_SHA1: {
const int hashlen = SHA1_HASH_LEN_BYTE;
Sha1 hash;
hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
string ret = hash.sha1_read();
if (f->writeBlock(ret.c_str(), hashlen) != hashlen)
return e_writeFile;
break;
}
-#ifndef PWM_EMBEDDED
case PWM_HASH_SHA256:
/*... fall through */
case PWM_HASH_SHA384:
case PWM_HASH_SHA512:
case PWM_HASH_MD5:
case PWM_HASH_RMD160:
case PWM_HASH_TIGER:
{
if (!LibGCryptIf::available())
return e_hashNotImpl;
LibGCryptIf gc;
PwMerror err;
unsigned char *buf;
size_t hashLen;
err = gc.hash(&buf,
&hashLen,
reinterpret_cast<const unsigned char *>(pw->latin1()),
pw->length(),
keyHash);
if (err != e_success)
return e_hashNotImpl;
if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
!= static_cast<Q_LONG>(hashLen)) {
delete [] buf;
return e_hashNotImpl;
}
delete [] buf;
break;
}
-#endif
default: {
return e_hashNotImpl;
} }
return e_success;
}
PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
unsigned int *headerLength, char *dataHashType,
string *dataHash, QFile *f)
{
PWM_ASSERT(cryptAlgo);
PWM_ASSERT(pw);
PWM_ASSERT(headerLength);
PWM_ASSERT(dataHashType);
PWM_ASSERT(dataHash);
PWM_ASSERT(f);
@@ -749,92 +738,88 @@ PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
// verify key-hash
switch (keyHash) {
case PWM_HASH_SHA1: {
// read hash from header
const int hashLen = SHA1_HASH_LEN_BYTE;
string readHash;
int i;
for (i = 0; i < hashLen; ++i)
readHash.push_back(f->getch());
Sha1 hash;
hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
string ret = hash.sha1_read();
if (ret != readHash)
return e_wrongPw; // hash doesn't match (wrong key)
break;
}
-#ifndef PWM_EMBEDDED
case PWM_HASH_SHA256:
/*... fall through */
case PWM_HASH_SHA384:
case PWM_HASH_SHA512:
case PWM_HASH_MD5:
case PWM_HASH_RMD160:
case PWM_HASH_TIGER: {
if (!LibGCryptIf::available())
return e_hashNotImpl;
LibGCryptIf gc;
PwMerror err;
unsigned char *buf;
size_t hashLen;
err = gc.hash(&buf,
&hashLen,
reinterpret_cast<const unsigned char *>(pw->latin1()),
pw->length(),
keyHash);
if (err != e_success)
return e_hashNotImpl;
string calcHash(reinterpret_cast<const char *>(buf),
static_cast<string::size_type>(hashLen));
delete [] buf;
// read hash from header
string readHash;
size_t i;
for (i = 0; i < hashLen; ++i)
readHash.push_back(f->getch());
if (calcHash != readHash)
return e_wrongPw; // hash doesn't match (wrong key)
break;
}
-#endif
default: {
return e_hashNotImpl;
} }
// read the data-hash from the file
unsigned int hashLen, i;
switch (*dataHashType) {
case PWM_HASH_SHA1:
hashLen = SHA1_HASH_LEN_BYTE;
break;
-#ifndef PWM_EMBEDDED
case PWM_HASH_SHA256:
/*... fall through */
case PWM_HASH_SHA384:
case PWM_HASH_SHA512:
case PWM_HASH_MD5:
case PWM_HASH_RMD160:
case PWM_HASH_TIGER: {
if (!LibGCryptIf::available())
return e_hashNotImpl;
LibGCryptIf gc;
hashLen = gc.hashLength(*dataHashType);
if (hashLen == 0)
return e_hashNotImpl;
break;
}
-#endif
default:
return e_hashNotImpl;
}
*dataHash = "";
for (i = 0; i < hashLen; ++i) {
tmpRet = f->getch();
if (tmpRet == -1)
return e_fileFormat;
dataHash->push_back(static_cast<char>(tmpRet));
}
*headerLength = f->at();
#ifndef PWM_EMBEDDED
printDebug(string("opening file { compress: ")
+ tostr(static_cast<int>(*compress)) + " cryptAlgo: "
+ tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: "
+ tostr(static_cast<int>(keyHash))
@@ -852,62 +837,60 @@ PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f)
{
PWM_ASSERT(d);
PWM_ASSERT(f);
switch (dataHash) {
case PWM_HASH_SHA1: {
const int hashLen = SHA1_HASH_LEN_BYTE;
Sha1 h;
h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size());
string hRet = h.sha1_read();
if (f->writeBlock(hRet.c_str(), hashLen) != hashLen)
return e_writeFile;
break;
}
-#ifndef PWM_EMBEDDED
case PWM_HASH_SHA256:
/*... fall through */
case PWM_HASH_SHA384:
case PWM_HASH_SHA512:
case PWM_HASH_MD5:
case PWM_HASH_RMD160:
case PWM_HASH_TIGER: {
if (!LibGCryptIf::available())
return e_hashNotImpl;
LibGCryptIf gc;
PwMerror err;
unsigned char *buf;
size_t hashLen;
err = gc.hash(&buf,
&hashLen,
reinterpret_cast<const unsigned char *>(d->c_str()),
d->size(),
dataHash);
if (err != e_success)
return e_hashNotImpl;
if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
!= static_cast<Q_LONG>(hashLen)) {
delete [] buf;
return e_hashNotImpl;
}
delete [] buf;
break;
}
-#endif
default: {
return e_hashNotImpl;
} }
return e_success;
}
bool PwMDoc::backupFile(const QString &filePath)
{
QFileInfo fi(filePath);
if (!fi.exists())
return true; // Yes, true is correct.
QString pathOnly(fi.dirPath(true));
QString nameOnly(fi.fileName());
QString backupPath = pathOnly
+ "/~"
@@ -922,57 +905,44 @@ bool PwMDoc::copyFile(const QString &src, const QString &dst)
if (!fi.exists())
return false;
if (QFile::exists(dst)) {
if (!QFile::remove(dst))
return false;
}
QFile srcFd(src);
if (!srcFd.open(IO_ReadOnly))
return false;
QFile dstFd(dst);
if (!dstFd.open(IO_ReadWrite)) {
srcFd.close();
return false;
}
const int tmpBuf_size = 512;
char tmpBuf[tmpBuf_size];
-#ifndef PWM_EMBEDDED
Q_LONG bytesRead, bytesWritten;
-#else
- long bytesRead, bytesWritten;
-#endif
+
while (!srcFd.atEnd()) {
-#ifndef PWM_EMBEDDED
bytesRead = srcFd.readBlock(tmpBuf,
static_cast<Q_ULONG>(tmpBuf_size));
-#else
- bytesRead = srcFd.readBlock(tmpBuf,
- (unsigned long)(tmpBuf_size));
-#endif
if (bytesRead == -1) {
srcFd.close();
dstFd.close();
return false;
}
-#ifndef PWM_EMBEDDED
bytesWritten = dstFd.writeBlock(tmpBuf,
static_cast<Q_ULONG>(bytesRead));
-#else
- bytesWritten = dstFd.writeBlock(tmpBuf,
- (unsigned long)(bytesRead));
-#endif
if (bytesWritten != bytesRead) {
srcFd.close();
dstFd.close();
return false;
}
}
srcFd.close();
dstFd.close();
return true;
}
PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d,
bool dontFlagDirty, bool updateMeta)
{
PWM_ASSERT(d);
unsigned int cat = 0;
@@ -1287,80 +1257,69 @@ PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo)
size_t encSize;
byte *encrypted = 0;
switch (algo) {
case PWM_CRYPT_BLOWFISH: {
Blowfish::padNull(d);
encSize = d->length();
encrypted = new byte[encSize];
Blowfish bf;
if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) {
delete [] encrypted;
return e_weakPw;
}
bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize);
break;
}
-#ifndef PWM_EMBEDDED
case PWM_CRYPT_AES128:
/*... fall through */
case PWM_CRYPT_AES192:
case PWM_CRYPT_AES256:
case PWM_CRYPT_3DES:
case PWM_CRYPT_TWOFISH:
case PWM_CRYPT_TWOFISH128: {
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);
delete [] plain;
if (err != e_success)
return e_cryptNotImpl;
break;
}
-#endif
default: {
delete_ifnot_null_array(encrypted);
return e_cryptNotImpl;
} }
// write encrypted data to file
-#ifndef PWM_EMBEDDED
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;
}
-#else
- if (f->writeBlock((const char *)(encrypted),
- (unsigned long)(encSize))
- != (long)(encSize)) {
- delete_ifnot_null_array(encrypted);
- return e_writeFile;
- }
-#endif
delete_ifnot_null_array(encrypted);
return e_success;
}
PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
char algo, 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);
@@ -1375,59 +1334,57 @@ PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
#else
if (f->readBlock((char *)(encrypted),
(unsigned long)(cryptLen))
!= (long)(cryptLen)) {
delete [] encrypted;
delete [] decrypted;
return e_readFile;
}
#endif
switch (algo) {
case PWM_CRYPT_BLOWFISH: {
Blowfish bf;
bf.bf_setkey((byte *) pw->latin1(), pw->length());
bf.bf_decrypt(decrypted, encrypted, cryptLen);
break;
}
-#ifndef PWM_EMBEDDED
case PWM_CRYPT_AES128:
/*... fall through */
case PWM_CRYPT_AES192:
case PWM_CRYPT_AES256:
case PWM_CRYPT_3DES:
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);
if (err != e_success) {
delete [] encrypted;
delete [] decrypted;
return e_cryptNotImpl;
}
break;
}
-#endif
default: {
delete [] encrypted;
delete [] decrypted;
return e_cryptNotImpl;
} }
delete [] encrypted;
#ifndef PWM_EMBEDDED
d->assign(reinterpret_cast<const char *>(decrypted),
static_cast<string::size_type>(cryptLen));
#else
d->assign((const char *)(decrypted),
(string::size_type)(cryptLen));
#endif
delete [] decrypted;
if (algo == PWM_CRYPT_BLOWFISH) {
if (!Blowfish::unpadNull(d)) {
@@ -1439,61 +1396,59 @@ PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
}
PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash,
const string *dataStream)
{
PWM_ASSERT(dataHash);
PWM_ASSERT(dataStream);
switch(dataHashType) {
case PWM_HASH_SHA1: {
Sha1 hash;
hash.sha1_write((byte*)dataStream->c_str(), dataStream->length());
string ret = hash.sha1_read();
if (ret != *dataHash)
return e_fileCorrupt;
break;
}
-#ifndef PWM_EMBEDDED
case PWM_HASH_SHA256:
/*... fall through */
case PWM_HASH_SHA384:
case PWM_HASH_SHA512:
case PWM_HASH_MD5:
case PWM_HASH_RMD160:
case PWM_HASH_TIGER: {
if (!LibGCryptIf::available())
return e_hashNotImpl;
LibGCryptIf gc;
PwMerror err;
unsigned char *buf;
size_t hashLen;
err = gc.hash(&buf,
&hashLen,
reinterpret_cast<const unsigned char *>(dataStream->c_str()),
dataStream->length(),
dataHashType);
if (err != e_success)
return e_hashNotImpl;
string calcHash(reinterpret_cast<const char *>(buf),
static_cast<string::size_type>(hashLen));
delete [] buf;
if (calcHash != *dataHash)
return e_fileCorrupt;
break;
}
-#endif
default:
return e_hashNotImpl;
}
return e_success;
}
bool PwMDoc::lockAt(unsigned int category, unsigned int index,
bool lock)
{
if (index >= numEntries(category)) {
BUG();
return false;
}
if (lock == dti.dta[category].d[index].lockStat)
return true;