author | ulf69 <ulf69> | 2004-10-15 22:47:12 (UTC) |
---|---|---|
committer | ulf69 <ulf69> | 2004-10-15 22:47:12 (UTC) |
commit | 1821dcc08c8f6f2bc0fdb991c335ed03262d1443 (patch) (side-by-side diff) | |
tree | 93249cb2cc3fbb57cc8cf6688afbc252629b62a4 | |
parent | 71ee1be533cdbe7ce50c4f617254011fc640e88e (diff) | |
download | kdepimpi-1821dcc08c8f6f2bc0fdb991c335ed03262d1443.zip kdepimpi-1821dcc08c8f6f2bc0fdb991c335ed03262d1443.tar.gz kdepimpi-1821dcc08c8f6f2bc0fdb991c335ed03262d1443.tar.bz2 |
*** empty log message ***
-rw-r--r-- | pwmanager/pwmanager/libgcryptif.cpp | 420 | ||||
-rw-r--r-- | pwmanager/pwmanager/libgcryptif.h | 5 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmanagerE.pro | 10 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmdoc.cpp | 77 |
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; |