summaryrefslogtreecommitdiffabout
Unidiff
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
@@ -12,225 +12,229 @@
12 * as published by the Free Software Foundation. * 12 * as published by the Free Software Foundation. *
13 * * 13 * *
14 ***************************************************************************/ 14 ***************************************************************************/
15 15
16/*************************************************************************** 16/***************************************************************************
17 * copyright (C) 2004 by Ulf Schenk 17 * copyright (C) 2004 by Ulf Schenk
18 * This file is originaly based on version 1.1 of pwmanager 18 * This file is originaly based on version 1.1 of pwmanager
19 * and was modified to run on embedded devices that run microkde 19 * and was modified to run on embedded devices that run microkde
20 * 20 *
21 * $Id$ 21 * $Id$
22 **************************************************************************/ 22 **************************************************************************/
23 23
24#include "libgcryptif.h" 24#include "libgcryptif.h"
25 25
26#ifdef CONFIG_PWMANAGER_GCRY 26#ifdef CONFIG_PWMANAGER_GCRY
27 27
28#include "pwmdoc.h" 28#include "pwmdoc.h"
29#include "randomizer.h" 29#include "randomizer.h"
30 30
31#include <gcrypt.h> 31#include <gcrypt.h>
32 32
33#ifdef PWM_EMBEDDED 33#ifdef PWM_EMBEDDED
34#include <pwmprefs.h> 34#include <pwmprefs.h>
35#endif 35#endif
36 36
37 37
38PwMerror LibGCryptIf::encrypt(unsigned char **outBuf, 38PwMerror LibGCryptIf::encrypt(unsigned char **outBuf,
39 size_t *outBufLen, 39 size_t *outBufLen,
40 unsigned char *inBuf, 40 unsigned char *inBuf,
41 size_t inBufLen, 41 size_t inBufLen,
42 const unsigned char *key, 42 const unsigned char *key,
43 size_t keylen, 43 size_t keylen,
44 char _algo) 44 char _algo,
45 char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
46 )
45{ 47{
46 PwMerror ret = e_success; 48 PwMerror ret = e_success;
47 gcry_error_t err; 49 gcry_error_t err;
48 gcry_cipher_hd_t handle; 50 gcry_cipher_hd_t handle;
49 size_t blklen; 51 size_t blklen;
50 size_t unpaddedLen = inBufLen; 52 size_t unpaddedLen = inBufLen;
51 size_t cipherKeylen; 53 size_t cipherKeylen;
52 unsigned char *hashedKey; 54 unsigned char *hashedKey;
53 unsigned char salt[STRING2KEY_SALTLEN]; 55 unsigned char salt[STRING2KEY_SALTLEN];
54 int algo = mapCipherId(_algo); 56 int algo = mapCipherId(_algo);
55 57
56 if (!inBufLen || !keylen) 58 if (!inBufLen || !keylen)
57 return e_invalidArg; 59 return e_invalidArg;
58 60
59 // test if algo is ready for encryption 61 // test if algo is ready for encryption
60 err = gcry_cipher_algo_info(algo, 62 err = gcry_cipher_algo_info(algo,
61 GCRYCTL_TEST_ALGO, 63 GCRYCTL_TEST_ALGO,
62 0, 0); 64 0, 0);
63 if (err != GPG_ERR_NO_ERROR) { 65 if (err != GPG_ERR_NO_ERROR) {
64 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_TEST_ALGO failed: ") 66 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_TEST_ALGO failed: ")
65 + gcry_strerror(err)); 67 + gcry_strerror(err));
66 ret = e_cryptNotImpl; 68 ret = e_cryptNotImpl;
67 goto out; 69 goto out;
68 } 70 }
69 // get the algo block length 71 // get the algo block length
70 err = gcry_cipher_algo_info(algo, 72 err = gcry_cipher_algo_info(algo,
71 GCRYCTL_GET_BLKLEN, 73 GCRYCTL_GET_BLKLEN,
72 0, 74 0,
73 &blklen); 75 &blklen);
74 if (err != GPG_ERR_NO_ERROR) { 76 if (err != GPG_ERR_NO_ERROR) {
75 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_BLKLEN failed: ") 77 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_BLKLEN failed: ")
76 + gcry_strerror(err)); 78 + gcry_strerror(err));
77 ret = e_cryptNotImpl; 79 ret = e_cryptNotImpl;
78 goto out; 80 goto out;
79 } 81 }
80 /* double check if we have enough space. 82 /* double check if we have enough space.
81 * We have only 1024 extra bytes for padding and salt. 83 * We have only 1024 extra bytes for padding and salt.
82 */ 84 */
83 BUG_ON(blklen > 1024 - STRING2KEY_SALTLEN); 85 BUG_ON(blklen > 1024 - STRING2KEY_SALTLEN);
84 // get the algo key length 86 // get the algo key length
85 err = gcry_cipher_algo_info(algo, 87 err = gcry_cipher_algo_info(algo,
86 GCRYCTL_GET_KEYLEN, 88 GCRYCTL_GET_KEYLEN,
87 0, 89 0,
88 &cipherKeylen); 90 &cipherKeylen);
89 if (err != GPG_ERR_NO_ERROR) { 91 if (err != GPG_ERR_NO_ERROR) {
90 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_KEYLEN failed: ") 92 printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_KEYLEN failed: ")
91 + gcry_strerror(err)); 93 + gcry_strerror(err));
92 ret = e_cryptNotImpl; 94 ret = e_cryptNotImpl;
93 goto out; 95 goto out;
94 } 96 }
95 // now open the algo and get a handle 97 // now open the algo and get a handle
96 err = gcry_cipher_open(&handle, 98 err = gcry_cipher_open(&handle,
97 algo, 99 algo,
98 GCRY_CIPHER_MODE_CBC, 100 GCRY_CIPHER_MODE_CBC,
99 0); 101 0);
100 if (err != GPG_ERR_NO_ERROR) { 102 if (err != GPG_ERR_NO_ERROR) {
101 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_open() failed: ") 103 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_open() failed: ")
102 + gcry_strerror(err)); 104 + gcry_strerror(err));
103 ret = e_cryptNotImpl; 105 ret = e_cryptNotImpl;
104 goto out; 106 goto out;
105 } 107 }
106 // hash the "key" to a fixed size hash matching "cipherKeylen" 108 // hash the "key" to a fixed size hash matching "cipherKeylen"
107 hashedKey = new unsigned char[cipherKeylen]; 109 hashedKey = new unsigned char[cipherKeylen];
108 hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, true); 110 hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, true, _hashalgo);
109 // so now set the hashed key 111 // so now set the hashed key
110 err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen); 112 err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen);
111 if (err != GPG_ERR_NO_ERROR) { 113 if (err != GPG_ERR_NO_ERROR) {
112 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_setkey() failed: ") 114 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_setkey() failed: ")
113 + gcry_strerror(err)); 115 + gcry_strerror(err));
114 ret = e_cryptNotImpl; 116 ret = e_cryptNotImpl;
115 delete [] hashedKey; 117 delete [] hashedKey;
116 goto out_close; 118 goto out_close;
117 } 119 }
118 delete [] hashedKey; 120 delete [] hashedKey;
119 /* allocate a buffer for the encrypted data. 121 /* allocate a buffer for the encrypted data.
120 * The size of the buffer is the inBuf length, but blklen 122 * The size of the buffer is the inBuf length, but blklen
121 * aligned and plus the length of the salt, that is appended. 123 * aligned and plus the length of the salt, that is appended.
122 */ 124 */
123 *outBufLen = getBufLen(unpaddedLen, blklen) + STRING2KEY_SALTLEN; 125 *outBufLen = getBufLen(unpaddedLen, blklen) + STRING2KEY_SALTLEN;
124 *outBuf = new unsigned char[*outBufLen]; 126 *outBuf = new unsigned char[*outBufLen];
125 padData(inBuf, unpaddedLen, blklen); 127 padData(inBuf, unpaddedLen, blklen);
126 // encrypt the padded data 128 // encrypt the padded data
127 err = gcry_cipher_encrypt(handle, 129 err = gcry_cipher_encrypt(handle,
128 *outBuf, 130 *outBuf,
129 *outBufLen - STRING2KEY_SALTLEN, 131 *outBufLen - STRING2KEY_SALTLEN,
130 inBuf, 132 inBuf,
131 *outBufLen - STRING2KEY_SALTLEN); 133 *outBufLen - STRING2KEY_SALTLEN);
132 if (err != GPG_ERR_NO_ERROR) { 134 if (err != GPG_ERR_NO_ERROR) {
133 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ") 135 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ")
134 + gcry_strerror(err)); 136 + gcry_strerror(err));
135 ret = e_cryptNotImpl; 137 ret = e_cryptNotImpl;
136 goto out_delete; 138 goto out_delete;
137 } 139 }
138 // append the salt to the encrypted data 140 // append the salt to the encrypted data
139 memcpy(*outBuf + *outBufLen - STRING2KEY_SALTLEN, salt, STRING2KEY_SALTLEN); 141 memcpy(*outBuf + *outBufLen - STRING2KEY_SALTLEN, salt, STRING2KEY_SALTLEN);
140 goto out_close; 142 goto out_close;
141out_delete: 143out_delete:
142 delete [] *outBuf; 144 delete [] *outBuf;
143out_close: 145out_close:
144 gcry_cipher_close(handle); 146 gcry_cipher_close(handle);
145out: 147out:
146 return ret; 148 return ret;
147} 149}
148 150
149PwMerror LibGCryptIf::decrypt(unsigned char **outBuf, 151PwMerror LibGCryptIf::decrypt(unsigned char **outBuf,
150 size_t *outBufLen, 152 size_t *outBufLen,
151 const unsigned char *inBuf, 153 const unsigned char *inBuf,
152 size_t inBufLen, 154 size_t inBufLen,
153 const unsigned char *key, 155 const unsigned char *key,
154 size_t keylen, 156 size_t keylen,
155 char _algo) 157 char _algo,
158 char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
159)
156{ 160{
157 PwMerror ret = e_success; 161 PwMerror ret = e_success;
158 gcry_error_t err; 162 gcry_error_t err;
159 gcry_cipher_hd_t handle; 163 gcry_cipher_hd_t handle;
160 size_t cipherKeylen; 164 size_t cipherKeylen;
161 unsigned char *hashedKey; 165 unsigned char *hashedKey;
162 unsigned char salt[STRING2KEY_SALTLEN]; 166 unsigned char salt[STRING2KEY_SALTLEN];
163 int algo = mapCipherId(_algo); 167 int algo = mapCipherId(_algo);
164 168
165 if (!inBufLen || !keylen) 169 if (!inBufLen || !keylen)
166 return e_invalidArg; 170 return e_invalidArg;
167 171
168 // test if algo is ready for encryption 172 // test if algo is ready for encryption
169 err = gcry_cipher_algo_info(algo, 173 err = gcry_cipher_algo_info(algo,
170 GCRYCTL_TEST_ALGO, 174 GCRYCTL_TEST_ALGO,
171 0, 0); 175 0, 0);
172 if (err != GPG_ERR_NO_ERROR) { 176 if (err != GPG_ERR_NO_ERROR) {
173 printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_TEST_ALGO failed: ") 177 printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_TEST_ALGO failed: ")
174 + gcry_strerror(err)); 178 + gcry_strerror(err));
175 ret = e_cryptNotImpl; 179 ret = e_cryptNotImpl;
176 goto out; 180 goto out;
177 } 181 }
178 // get algo key length 182 // get algo key length
179 err = gcry_cipher_algo_info(algo, 183 err = gcry_cipher_algo_info(algo,
180 GCRYCTL_GET_KEYLEN, 184 GCRYCTL_GET_KEYLEN,
181 0, 185 0,
182 &cipherKeylen); 186 &cipherKeylen);
183 if (err != GPG_ERR_NO_ERROR) { 187 if (err != GPG_ERR_NO_ERROR) {
184 printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_GET_KEYLEN failed: ") 188 printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_GET_KEYLEN failed: ")
185 + gcry_strerror(err)); 189 + gcry_strerror(err));
186 ret = e_cryptNotImpl; 190 ret = e_cryptNotImpl;
187 goto out; 191 goto out;
188 } 192 }
189 // extract the salt of the encrypted data buffer 193 // extract the salt of the encrypted data buffer
190 memcpy(salt, inBuf + inBufLen - STRING2KEY_SALTLEN, STRING2KEY_SALTLEN); 194 memcpy(salt, inBuf + inBufLen - STRING2KEY_SALTLEN, STRING2KEY_SALTLEN);
191 // open the algo and get a handle 195 // open the algo and get a handle
192 err = gcry_cipher_open(&handle, 196 err = gcry_cipher_open(&handle,
193 algo, 197 algo,
194 GCRY_CIPHER_MODE_CBC, 198 GCRY_CIPHER_MODE_CBC,
195 0); 199 0);
196 if (err != GPG_ERR_NO_ERROR) { 200 if (err != GPG_ERR_NO_ERROR) {
197 printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_open() failed: ") 201 printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_open() failed: ")
198 + gcry_strerror(err)); 202 + gcry_strerror(err));
199 ret = e_cryptNotImpl; 203 ret = e_cryptNotImpl;
200 goto out; 204 goto out;
201 } 205 }
202 // hash the "key" to a fixed size hash matching "cipherKeylen" 206 // hash the "key" to a fixed size hash matching "cipherKeylen"
203 hashedKey = new unsigned char[cipherKeylen]; 207 hashedKey = new unsigned char[cipherKeylen];
204 hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, false); 208 hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, false, _hashalgo);
205 // so now set the hashed key 209 // so now set the hashed key
206 err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen); 210 err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen);
207 if (err != GPG_ERR_NO_ERROR) { 211 if (err != GPG_ERR_NO_ERROR) {
208 printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_setkey() failed: ") 212 printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_setkey() failed: ")
209 + gcry_strerror(err)); 213 + gcry_strerror(err));
210 ret = e_cryptNotImpl; 214 ret = e_cryptNotImpl;
211 delete [] hashedKey; 215 delete [] hashedKey;
212 goto out_close; 216 goto out_close;
213 } 217 }
214 delete [] hashedKey; 218 delete [] hashedKey;
215 *outBufLen = inBufLen - STRING2KEY_SALTLEN; 219 *outBufLen = inBufLen - STRING2KEY_SALTLEN;
216 *outBuf = new unsigned char[*outBufLen]; 220 *outBuf = new unsigned char[*outBufLen];
217 // decrypt the data 221 // decrypt the data
218 err = gcry_cipher_decrypt(handle, 222 err = gcry_cipher_decrypt(handle,
219 *outBuf, 223 *outBuf,
220 *outBufLen, 224 *outBufLen,
221 inBuf, 225 inBuf,
222 *outBufLen); 226 *outBufLen);
223 if (err != GPG_ERR_NO_ERROR) { 227 if (err != GPG_ERR_NO_ERROR) {
224 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ") 228 printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ")
225 + gcry_strerror(err)); 229 + gcry_strerror(err));
226 ret = e_cryptNotImpl; 230 ret = e_cryptNotImpl;
227 goto out_delete; 231 goto out_delete;
228 } 232 }
229 // remove all random padding 233 // remove all random padding
230 unpadData(*outBuf, outBufLen); 234 unpadData(*outBuf, outBufLen);
231 goto out_close; 235 goto out_close;
232out_delete: 236out_delete:
233 delete [] *outBuf; 237 delete [] *outBuf;
234out_close: 238out_close:
235 gcry_cipher_close(handle); 239 gcry_cipher_close(handle);
236out: 240out:
@@ -285,73 +289,78 @@ int LibGCryptIf::mapCipherId(char algo)
285 } 289 }
286 return GCRY_CIPHER_NONE; 290 return GCRY_CIPHER_NONE;
287} 291}
288 292
289int LibGCryptIf::mapHashId(char algo) 293int LibGCryptIf::mapHashId(char algo)
290{ 294{
291 switch (algo) { 295 switch (algo) {
292 case PWM_HASH_SHA1: 296 case PWM_HASH_SHA1:
293 return GCRY_MD_SHA1; 297 return GCRY_MD_SHA1;
294 case PWM_HASH_SHA256: 298 case PWM_HASH_SHA256:
295 return GCRY_MD_SHA256; 299 return GCRY_MD_SHA256;
296 case PWM_HASH_SHA384: 300 case PWM_HASH_SHA384:
297 return GCRY_MD_SHA384; 301 return GCRY_MD_SHA384;
298 case PWM_HASH_SHA512: 302 case PWM_HASH_SHA512:
299 return GCRY_MD_SHA512; 303 return GCRY_MD_SHA512;
300 case PWM_HASH_MD5: 304 case PWM_HASH_MD5:
301 return GCRY_MD_MD5; 305 return GCRY_MD_MD5;
302 case PWM_HASH_RMD160: 306 case PWM_HASH_RMD160:
303 return GCRY_MD_RMD160; 307 return GCRY_MD_RMD160;
304 case PWM_HASH_TIGER: 308 case PWM_HASH_TIGER:
305 return GCRY_MD_TIGER; 309 return GCRY_MD_TIGER;
306 default: 310 default:
307 BUG(); 311 BUG();
308 } 312 }
309 return GCRY_MD_NONE; 313 return GCRY_MD_NONE;
310} 314}
311 315
312bool LibGCryptIf::hashPassphrase(const unsigned char *pw, 316bool LibGCryptIf::hashPassphrase(const unsigned char *pw,
313 size_t pwlen, 317 size_t pwlen,
314 unsigned char *salt, 318 unsigned char *salt,
315 unsigned char *key, 319 unsigned char *key,
316 size_t keylen, 320 size_t keylen,
317 bool create) 321 bool create,
322 char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
323)
318{ 324{
319 DEK dek; 325 DEK dek;
320 STRING2KEY s2k; 326 STRING2KEY s2k;
321 bool ret; 327 bool ret;
322 328
323 dek.keylen = keylen; 329 dek.keylen = keylen;
324 s2k.mode = 1; 330 s2k.mode = 1;
325 s2k.hash_algo = mapHashId(conf()->confGlobHashAlgo()); 331 //US bug: do not use the global hash algo here. Use the passed ago instead. The hashalgo stored in the file can
332 // be different from the one in the configuration.
333 s2k.hash_algo = mapHashId(_hashalgo //conf()->confGlobHashAlgo()
334 );
326 s2k.count = 0; 335 s2k.count = 0;
327 if (!create) 336 if (!create)
328 memcpy(s2k.salt, salt, STRING2KEY_SALTLEN); 337 memcpy(s2k.salt, salt, STRING2KEY_SALTLEN);
329 ret = doHashPassphrase(&dek, 338 ret = doHashPassphrase(&dek,
330 pw, 339 pw,
331 pwlen, 340 pwlen,
332 &s2k, 341 &s2k,
333 create); 342 create);
334 if (!ret) 343 if (!ret)
335 goto out; 344 goto out;
336 memcpy(key, dek.key, dek.keylen); 345 memcpy(key, dek.key, dek.keylen);
337 if (create) 346 if (create)
338 memcpy(salt, s2k.salt, STRING2KEY_SALTLEN); 347 memcpy(salt, s2k.salt, STRING2KEY_SALTLEN);
339out: 348out:
340 return ret; 349 return ret;
341} 350}
342 351
343 352
344bool LibGCryptIf::doHashPassphrase(DEK *dek, 353bool LibGCryptIf::doHashPassphrase(DEK *dek,
345 const unsigned char *pw, 354 const unsigned char *pw,
346 size_t pwlen, 355 size_t pwlen,
347 STRING2KEY *s2k, 356 STRING2KEY *s2k,
348 bool create) 357 bool create)
349{ 358{
350 // This function is derived from GnuPG-1.2.5-rc2 359 // This function is derived from GnuPG-1.2.5-rc2
351 gcry_md_hd_t md; 360 gcry_md_hd_t md;
352 gcry_error_t err; 361 gcry_error_t err;
353 bool ret = true; 362 bool ret = true;
354 size_t pass, i; 363 size_t pass, i;
355 size_t used = 0; 364 size_t used = 0;
356 365
357 PWM_ASSERT(s2k->hash_algo); 366 PWM_ASSERT(s2k->hash_algo);
@@ -410,45 +419,45 @@ bool LibGCryptIf::doHashPassphrase(DEK *dek,
410 gcry_md_close(md); 419 gcry_md_close(md);
411out: 420out:
412 return ret; 421 return ret;
413} 422}
414 423
415void LibGCryptIf::padData(unsigned char *buf, 424void LibGCryptIf::padData(unsigned char *buf,
416 size_t bufLen, 425 size_t bufLen,
417 size_t boundary) 426 size_t boundary)
418{ 427{
419 size_t numPadBytes = boundary - ((bufLen + 1) % boundary); 428 size_t numPadBytes = boundary - ((bufLen + 1) % boundary);
420 buf[bufLen] = static_cast<char>(0x01); 429 buf[bufLen] = static_cast<char>(0x01);
421 size_t i = 0; 430 size_t i = 0;
422 Randomizer *rnd = Randomizer::obj(); 431 Randomizer *rnd = Randomizer::obj();
423 char c; 432 char c;
424 unsigned char *b; 433 unsigned char *b;
425 while (i < numPadBytes) { 434 while (i < numPadBytes) {
426 c = rnd->genRndChar(); 435 c = rnd->genRndChar();
427 if (c == static_cast<char>(0x01)) 436 if (c == static_cast<char>(0x01))
428 continue; 437 continue;
429 b = buf + bufLen + 1 + i; 438 b = buf + bufLen + 1 + i;
430 *b = c; 439 *b = c;
431 ++i; 440 ++i;
432 } 441 }
433} 442}
434 443
435void LibGCryptIf::unpadData(const unsigned char *buf, 444void LibGCryptIf::unpadData(const unsigned char *buf,
436 size_t *bufLen) 445 size_t *bufLen)
437{ 446{
438 size_t pos; 447 size_t pos;
439 BUG_ON(*bufLen % 8); 448 BUG_ON(*bufLen % 8);
440 pos = *bufLen - 1; 449 pos = *bufLen - 1;
441 while (buf[pos] != static_cast<char>(0x01)) { 450 while (buf[pos] != static_cast<char>(0x01)) {
442 qDebug("pos %d %d %d", pos, buf[pos], static_cast<char>(0x01) ); 451 //qDebug("pos %d %d %d", pos, buf[pos], static_cast<char>(0x01) );
443 BUG_ON(!pos); 452 BUG_ON(!pos);
444 //LR BUG we should terminte the loop if p == 0 453 //LR BUG we should terminte the loop if p == 0
445 if ( pos == 0 ) 454 if ( pos == 0 )
446 break; 455 break;
447 --pos; 456 --pos;
448 } 457 }
449 *bufLen = pos; 458 *bufLen = pos;
450 qDebug("ente "); 459 //qDebug("ente ");
451} 460}
452 461
453#endif // CONFIG_PWMANAGER_GCRY 462#endif // CONFIG_PWMANAGER_GCRY
454 463
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
@@ -44,116 +44,122 @@
44 * NOTE: Always allocate 1024 extra bytes for the inBuf (for padding) 44 * NOTE: Always allocate 1024 extra bytes for the inBuf (for padding)
45 */ 45 */
46class LibGCryptIf 46class LibGCryptIf
47{ 47{
48protected: 48protected:
49 struct STRING2KEY 49 struct STRING2KEY
50 { 50 {
51 int mode; 51 int mode;
52 int hash_algo; 52 int hash_algo;
53 uint8_t salt[STRING2KEY_SALTLEN]; 53 uint8_t salt[STRING2KEY_SALTLEN];
54 uint32_t count; 54 uint32_t count;
55 }; 55 };
56 struct DEK 56 struct DEK
57 { 57 {
58 size_t keylen; 58 size_t keylen;
59 uint8_t key[32]; // this is the largest used keylen (256 bit) 59 uint8_t key[32]; // this is the largest used keylen (256 bit)
60 }; 60 };
61 61
62public: 62public:
63 LibGCryptIf() { } 63 LibGCryptIf() { }
64 /** is libgcrypt available? */ 64 /** is libgcrypt available? */
65 static bool available() 65 static bool available()
66 { return true; } 66 { return true; }
67 /** encrypt data. _algo is the PWM_CRYPT_* ID 67 /** encrypt data. _algo is the PWM_CRYPT_* ID
68 * of the algorithm. 68 * of the algorithm.
69 */ 69 */
70 PwMerror encrypt(unsigned char **outBuf, 70 PwMerror encrypt(unsigned char **outBuf,
71 size_t *outBufLen, 71 size_t *outBufLen,
72 unsigned char *inBuf, 72 unsigned char *inBuf,
73 size_t inBufLen, 73 size_t inBufLen,
74 const unsigned char *key, 74 const unsigned char *key,
75 size_t keylen, 75 size_t keylen,
76 char _algo); 76 char _algo,
77 char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
78);
77 /** decrypt data. _algo is the PWM_CRYPT_* ID 79 /** decrypt data. _algo is the PWM_CRYPT_* ID
78 * of the algorithm. 80 * of the algorithm.
79 */ 81 */
80 PwMerror decrypt(unsigned char **outBuf, 82 PwMerror decrypt(unsigned char **outBuf,
81 size_t *outBufLen, 83 size_t *outBufLen,
82 const unsigned char *inBuf, 84 const unsigned char *inBuf,
83 size_t inBufLen, 85 size_t inBufLen,
84 const unsigned char *key, 86 const unsigned char *key,
85 size_t keylen, 87 size_t keylen,
86 char _algo); 88 char _algo,
89 char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
90);
87 /** hash data. _algo is the PWM_HASH_* ID of the hash */ 91 /** hash data. _algo is the PWM_HASH_* ID of the hash */
88 PwMerror hash(unsigned char **outBuf, 92 PwMerror hash(unsigned char **outBuf,
89 size_t *outBufLen, 93 size_t *outBufLen,
90 const unsigned char *inBuf, 94 const unsigned char *inBuf,
91 size_t inBufLen, 95 size_t inBufLen,
92 char _algo); 96 char _algo);
93 /** returns the length of the hash. _algo is the PWM_HASH_* 97 /** returns the length of the hash. _algo is the PWM_HASH_*
94 * id of the hash. returns 0 on error. 98 * id of the hash. returns 0 on error.
95 */ 99 */
96 unsigned int hashLength(char _algo); 100 unsigned int hashLength(char _algo);
97 101
98protected: 102protected:
99 /** returns the total buffer length */ 103 /** returns the total buffer length */
100 size_t getBufLen(size_t inBufLen, size_t boundary) 104 size_t getBufLen(size_t inBufLen, size_t boundary)
101 { 105 {
102 return ((boundary - (inBufLen % boundary)) + inBufLen); 106 return ((boundary - (inBufLen % boundary)) + inBufLen);
103 } 107 }
104 /** pad the data up to the given boundary. 108 /** pad the data up to the given boundary.
105 * "buf" has to be big enough! 109 * "buf" has to be big enough!
106 */ 110 */
107 void padData(unsigned char *buf, 111 void padData(unsigned char *buf,
108 size_t bufLen, 112 size_t bufLen,
109 size_t boundary); 113 size_t boundary);
110 /** unpad the data */ 114 /** unpad the data */
111 void unpadData(const unsigned char *buf, 115 void unpadData(const unsigned char *buf,
112 size_t *bufLen); 116 size_t *bufLen);
113 /** maps the PWM_CRYPT_* ID of an algorithm 117 /** maps the PWM_CRYPT_* ID of an algorithm
114 * to the libgcrypt GCRY_CIPHER_* ID 118 * to the libgcrypt GCRY_CIPHER_* ID
115 */ 119 */
116 int mapCipherId(char algo); 120 int mapCipherId(char algo);
117 /** maps the PWM_HASH_* ID of an algorithm 121 /** maps the PWM_HASH_* ID of an algorithm
118 * to the libgcrypt GCRY_MD_* ID 122 * to the libgcrypt GCRY_MD_* ID
119 */ 123 */
120 int mapHashId(char algo); 124 int mapHashId(char algo);
121 /** hash a passphrase to a cipher key */ 125 /** hash a passphrase to a cipher key */
122 bool hashPassphrase(const unsigned char *pw, 126 bool hashPassphrase(const unsigned char *pw,
123 size_t pwlen, 127 size_t pwlen,
124 unsigned char *salt, 128 unsigned char *salt,
125 unsigned char *key, 129 unsigned char *key,
126 size_t keylen, 130 size_t keylen,
127 bool create); 131 bool create,
132 char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
133);
128 /** hash a passphrase to a cipher key */ 134 /** hash a passphrase to a cipher key */
129 bool doHashPassphrase(DEK *dek, 135 bool doHashPassphrase(DEK *dek,
130 const unsigned char *pw, 136 const unsigned char *pw,
131 size_t pwlen, 137 size_t pwlen,
132 STRING2KEY *s2k, 138 STRING2KEY *s2k,
133 bool create); 139 bool create);
134}; 140};
135 141
136 142
137#else // CONFIG_PWMANAGER_GCRY 143#else // CONFIG_PWMANAGER_GCRY
138/** libgcrypt is not installed. This is a NOP wrapper. */ 144/** libgcrypt is not installed. This is a NOP wrapper. */
139class LibGCryptIf 145class LibGCryptIf
140{ 146{
141public: 147public:
142 LibGCryptIf() { } 148 LibGCryptIf() { }
143 static bool available() 149 static bool available()
144 { return false; } 150 { return false; }
145 PwMerror encrypt(unsigned char **, 151 PwMerror encrypt(unsigned char **,
146 size_t *, 152 size_t *,
147 unsigned char *, 153 unsigned char *,
148 size_t, 154 size_t,
149 const unsigned char *, 155 const unsigned char *,
150 size_t, 156 size_t,
151 char) 157 char)
152 { return e_cryptNotImpl; } 158 { return e_cryptNotImpl; }
153 PwMerror decrypt(unsigned char **, 159 PwMerror decrypt(unsigned char **,
154 size_t *, 160 size_t *,
155 const unsigned char *, 161 const unsigned char *,
156 size_t, 162 size_t,
157 const unsigned char *, 163 const unsigned char *,
158 size_t, 164 size_t,
159 char) 165 char)
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
@@ -458,65 +458,65 @@ PwMerror PwMDoc::saveDoc(char compress, const QString *file)
458 ret = e_hashNotImpl; 458 ret = e_hashNotImpl;
459 goto out_moveback; 459 goto out_moveback;
460 } else if (e != e_success) { 460 } else if (e != e_success) {
461 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed"); 461 printDebug("PwMDoc::saveDoc(): writeFileHeader() failed");
462 f.close(); 462 f.close();
463 ret = e_writeHeader; 463 ret = e_writeHeader;
464 goto out_moveback; 464 goto out_moveback;
465 } 465 }
466 if (!serializeDta(&serialized)) { 466 if (!serializeDta(&serialized)) {
467 printDebug("PwMDoc::saveDoc(): serializeDta() failed"); 467 printDebug("PwMDoc::saveDoc(): serializeDta() failed");
468 f.close(); 468 f.close();
469 ret = e_serializeDta; 469 ret = e_serializeDta;
470 goto out_moveback; 470 goto out_moveback;
471 } 471 }
472 e = writeDataHash(hashAlgo, &serialized, &f); 472 e = writeDataHash(hashAlgo, &serialized, &f);
473 if (e == e_hashNotImpl) { 473 if (e == e_hashNotImpl) {
474 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl"); 474 printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl");
475 f.close(); 475 f.close();
476 ret = e_hashNotImpl; 476 ret = e_hashNotImpl;
477 goto out_moveback; 477 goto out_moveback;
478 } else if (e != e_success) { 478 } else if (e != e_success) {
479 printDebug("PwMDoc::saveDoc(): writeDataHash() failed"); 479 printDebug("PwMDoc::saveDoc(): writeDataHash() failed");
480 f.close(); 480 f.close();
481 ret = e_writeHeader; 481 ret = e_writeHeader;
482 goto out_moveback; 482 goto out_moveback;
483 } 483 }
484 if (!compressDta(&serialized, compress)) { 484 if (!compressDta(&serialized, compress)) {
485 printDebug("PwMDoc::saveDoc(): compressDta() failed"); 485 printDebug("PwMDoc::saveDoc(): compressDta() failed");
486 f.close(); 486 f.close();
487 ret = e_enc; 487 ret = e_enc;
488 goto out_moveback; 488 goto out_moveback;
489 } 489 }
490 e = encrypt(&serialized, &currentPw, &f, cryptAlgo); 490 e = encrypt(&serialized, &currentPw, &f, cryptAlgo, hashAlgo);
491 if (e == e_weakPw) { 491 if (e == e_weakPw) {
492 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw"); 492 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw");
493 f.close(); 493 f.close();
494 ret = e_weakPw; 494 ret = e_weakPw;
495 goto out_moveback; 495 goto out_moveback;
496 } else if (e == e_cryptNotImpl) { 496 } else if (e == e_cryptNotImpl) {
497 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl"); 497 printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl");
498 f.close(); 498 f.close();
499 ret = e_cryptNotImpl; 499 ret = e_cryptNotImpl;
500 goto out_moveback; 500 goto out_moveback;
501 } else if (e != e_success) { 501 } else if (e != e_success) {
502 printDebug("PwMDoc::saveDoc(): encrypt() failed"); 502 printDebug("PwMDoc::saveDoc(): encrypt() failed");
503 f.close(); 503 f.close();
504 ret = e_enc; 504 ret = e_enc;
505 goto out_moveback; 505 goto out_moveback;
506 } 506 }
507 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 507 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
508 f.close(); 508 f.close();
509#ifndef _WIN32_ 509#ifndef _WIN32_
510 if (chmod(filename.latin1(), 510 if (chmod(filename.latin1(),
511 conf()->confGlobFilePermissions())) { 511 conf()->confGlobFilePermissions())) {
512 printWarn(string("chmod failed: ") + strerror(errno)); 512 printWarn(string("chmod failed: ") + strerror(errno));
513 } 513 }
514#endif 514#endif
515 openDocList.edit(this, getTitle().latin1()); 515 openDocList.edit(this, getTitle().latin1());
516 if (wasDeepLocked) { 516 if (wasDeepLocked) {
517 /* Do _not_ save the data with the deepLock() 517 /* Do _not_ save the data with the deepLock()
518 * call, because this will recurse 518 * call, because this will recurse
519 * into saveDoc() 519 * into saveDoc()
520 */ 520 */
521 deepLock(true, false); 521 deepLock(true, false);
522 /* We don't check return value here, because 522 /* We don't check return value here, because
@@ -578,65 +578,65 @@ PwMerror PwMDoc::openDoc(const QString *file, int openLocked)
578 return e_alreadyOpen; 578 return e_alreadyOpen;
579 } 579 }
580 QFile f(filename); 580 QFile f(filename);
581 581
582 if (openLocked == 2) { 582 if (openLocked == 2) {
583 // open deep-locked 583 // open deep-locked
584 if (!QFile::exists(filename)) 584 if (!QFile::exists(filename))
585 return e_openFile; 585 return e_openFile;
586 if (deepLock(true, false) != e_success) 586 if (deepLock(true, false) != e_success)
587 return e_openFile; 587 return e_openFile;
588 goto out_success; 588 goto out_success;
589 } 589 }
590 590
591 if (!f.open(IO_ReadOnly)) 591 if (!f.open(IO_ReadOnly))
592 return e_openFile; 592 return e_openFile;
593 593
594 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen, 594 ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen,
595 &dataHashType, &dataHash, &f); 595 &dataHashType, &dataHash, &f);
596 if (ret != e_success) { 596 if (ret != e_success) {
597 printDebug("PwMDoc::openDoc(): checkHeader() failed"); 597 printDebug("PwMDoc::openDoc(): checkHeader() failed");
598 f.close(); 598 f.close();
599 if (ret == e_wrongPw) { 599 if (ret == e_wrongPw) {
600 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 600 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
601 return ret; 601 return ret;
602 } else if (ret == e_noPw || 602 } else if (ret == e_noPw ||
603 ret == e_fileVer || 603 ret == e_fileVer ||
604 ret == e_fileFormat || 604 ret == e_fileFormat ||
605 ret == e_hashNotImpl) { 605 ret == e_hashNotImpl) {
606 return ret; 606 return ret;
607 } else 607 } else
608 return e_readFile; 608 return e_readFile;
609 } 609 }
610 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, &f); 610 ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, dataHashType, &f);
611 if (ret == e_cryptNotImpl) { 611 if (ret == e_cryptNotImpl) {
612 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl"); 612 printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl");
613 f.close(); 613 f.close();
614 return e_cryptNotImpl; 614 return e_cryptNotImpl;
615 } else if (ret != e_success) { 615 } else if (ret != e_success) {
616 printDebug("PwMDoc::openDoc(): decrypt() failed"); 616 printDebug("PwMDoc::openDoc(): decrypt() failed");
617 f.close(); 617 f.close();
618 return e_readFile; 618 return e_readFile;
619 } 619 }
620 if (!decompressDta(&decrypted, compress)) { 620 if (!decompressDta(&decrypted, compress)) {
621 printDebug("PwMDoc::openDoc(): decompressDta() failed"); 621 printDebug("PwMDoc::openDoc(): decompressDta() failed");
622 f.close(); 622 f.close();
623 return e_fileCorrupt; 623 return e_fileCorrupt;
624 } 624 }
625 ret = checkDataHash(dataHashType, &dataHash, &decrypted); 625 ret = checkDataHash(dataHashType, &dataHash, &decrypted);
626 if (ret == e_hashNotImpl) { 626 if (ret == e_hashNotImpl) {
627 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl"); 627 printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl");
628 f.close(); 628 f.close();
629 return e_hashNotImpl; 629 return e_hashNotImpl;
630 } else if (ret != e_success) { 630 } else if (ret != e_success) {
631 printDebug("PwMDoc::openDoc(): checkDataHash() failed"); 631 printDebug("PwMDoc::openDoc(): checkDataHash() failed");
632 f.close(); 632 f.close();
633 return e_fileCorrupt; 633 return e_fileCorrupt;
634 } 634 }
635 if (!deSerializeDta(&decrypted, openLocked == 1)) { 635 if (!deSerializeDta(&decrypted, openLocked == 1)) {
636 printDebug("PwMDoc::openDoc(): deSerializeDta() failed"); 636 printDebug("PwMDoc::openDoc(): deSerializeDta() failed");
637 f.close(); 637 f.close();
638 return e_readFile; 638 return e_readFile;
639 } 639 }
640 f.close(); 640 f.close();
641 timer()->start(DocTimer::id_mpwTimer); 641 timer()->start(DocTimer::id_mpwTimer);
642 timer()->start(DocTimer::id_autoLockTimer); 642 timer()->start(DocTimer::id_autoLockTimer);
@@ -1278,181 +1278,189 @@ bool PwMDoc::compressDta(string *d, char algo)
1278 } 1278 }
1279#endif 1279#endif
1280 case PWM_COMPRESS_NONE: { 1280 case PWM_COMPRESS_NONE: {
1281 return true; 1281 return true;
1282 } default: { 1282 } default: {
1283 BUG(); 1283 BUG();
1284 } 1284 }
1285 } 1285 }
1286 return false; 1286 return false;
1287} 1287}
1288 1288
1289bool PwMDoc::decompressDta(string *d, char algo) 1289bool PwMDoc::decompressDta(string *d, char algo)
1290{ 1290{
1291 PWM_ASSERT(d); 1291 PWM_ASSERT(d);
1292 switch (algo) { 1292 switch (algo) {
1293 case PWM_COMPRESS_GZIP: { 1293 case PWM_COMPRESS_GZIP: {
1294 CompressGzip comp; 1294 CompressGzip comp;
1295 return comp.decompress(d); 1295 return comp.decompress(d);
1296 } 1296 }
1297#ifndef PWM_EMBEDDED 1297#ifndef PWM_EMBEDDED
1298 case PWM_COMPRESS_BZIP2: { 1298 case PWM_COMPRESS_BZIP2: {
1299 CompressBzip2 comp; 1299 CompressBzip2 comp;
1300 return comp.decompress(d); 1300 return comp.decompress(d);
1301 } 1301 }
1302#endif 1302#endif
1303 case PWM_COMPRESS_NONE: { 1303 case PWM_COMPRESS_NONE: {
1304 return true; 1304 return true;
1305 } 1305 }
1306 } 1306 }
1307 return false; 1307 return false;
1308} 1308}
1309 1309
1310PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo) 1310PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo,
1311 char hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1312)
1311{ 1313{
1312 PWM_ASSERT(d); 1314 PWM_ASSERT(d);
1313 PWM_ASSERT(pw); 1315 PWM_ASSERT(pw);
1314 PWM_ASSERT(f); 1316 PWM_ASSERT(f);
1315 1317
1316 size_t encSize; 1318 size_t encSize;
1317 byte *encrypted = 0; 1319 byte *encrypted = 0;
1318 1320
1319 switch (algo) { 1321 switch (algo) {
1320 case PWM_CRYPT_BLOWFISH: { 1322 case PWM_CRYPT_BLOWFISH: {
1321 Blowfish::padNull(d); 1323 Blowfish::padNull(d);
1322 encSize = d->length(); 1324 encSize = d->length();
1323 encrypted = new byte[encSize]; 1325 encrypted = new byte[encSize];
1324 Blowfish bf; 1326 Blowfish bf;
1325 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) { 1327 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) {
1326 delete [] encrypted; 1328 delete [] encrypted;
1327 return e_weakPw; 1329 return e_weakPw;
1328 } 1330 }
1329 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize); 1331 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize);
1330 break; 1332 break;
1331 } 1333 }
1332 case PWM_CRYPT_AES128: 1334 case PWM_CRYPT_AES128:
1333 /*... fall through */ 1335 /*... fall through */
1334 case PWM_CRYPT_AES192: 1336 case PWM_CRYPT_AES192:
1335 case PWM_CRYPT_AES256: 1337 case PWM_CRYPT_AES256:
1336 case PWM_CRYPT_3DES: 1338 case PWM_CRYPT_3DES:
1337 case PWM_CRYPT_TWOFISH: 1339 case PWM_CRYPT_TWOFISH:
1338 case PWM_CRYPT_TWOFISH128: { 1340 case PWM_CRYPT_TWOFISH128: {
1339 if (!LibGCryptIf::available()) 1341 if (!LibGCryptIf::available())
1340 return e_cryptNotImpl; 1342 return e_cryptNotImpl;
1341 LibGCryptIf gc; 1343 LibGCryptIf gc;
1342 PwMerror err; 1344 PwMerror err;
1343 unsigned char *plain = new unsigned char[d->length() + 1024]; 1345 unsigned char *plain = new unsigned char[d->length() + 1024];
1344 memcpy(plain, d->c_str(), d->length()); 1346 memcpy(plain, d->c_str(), d->length());
1345 err = gc.encrypt(&encrypted, 1347 err = gc.encrypt(&encrypted,
1346 &encSize, 1348 &encSize,
1347 plain, 1349 plain,
1348 d->length(), 1350 d->length(),
1349 reinterpret_cast<const unsigned char *>(pw->latin1()), 1351 reinterpret_cast<const unsigned char *>(pw->latin1()),
1350 pw->length(), 1352 pw->length(),
1351 algo); 1353 algo,
1354 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1355 );
1352 delete [] plain; 1356 delete [] plain;
1353 if (err != e_success) 1357 if (err != e_success)
1354 return e_cryptNotImpl; 1358 return e_cryptNotImpl;
1355 break; 1359 break;
1356 } 1360 }
1357 default: { 1361 default: {
1358 delete_ifnot_null_array(encrypted); 1362 delete_ifnot_null_array(encrypted);
1359 return e_cryptNotImpl; 1363 return e_cryptNotImpl;
1360 } } 1364 } }
1361 1365
1362 // write encrypted data to file 1366 // write encrypted data to file
1363 if (f->writeBlock(reinterpret_cast<const char *>(encrypted), 1367 if (f->writeBlock(reinterpret_cast<const char *>(encrypted),
1364 static_cast<Q_ULONG>(encSize)) 1368 static_cast<Q_ULONG>(encSize))
1365 != static_cast<Q_LONG>(encSize)) { 1369 != static_cast<Q_LONG>(encSize)) {
1366 delete_ifnot_null_array(encrypted); 1370 delete_ifnot_null_array(encrypted);
1367 return e_writeFile; 1371 return e_writeFile;
1368 } 1372 }
1369 delete_ifnot_null_array(encrypted); 1373 delete_ifnot_null_array(encrypted);
1370 return e_success; 1374 return e_success;
1371} 1375}
1372 1376
1373PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw, 1377PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
1374 char algo, QFile *f) 1378 char algo,
1379 char hashalgo, //US BUG: pass _hashalgo because we need it in hashPassphrase
1380 QFile *f)
1375{ 1381{
1376 PWM_ASSERT(d); 1382 PWM_ASSERT(d);
1377 PWM_ASSERT(pw); 1383 PWM_ASSERT(pw);
1378 PWM_ASSERT(f); 1384 PWM_ASSERT(f);
1379 1385
1380 unsigned int cryptLen = f->size() - pos; 1386 unsigned int cryptLen = f->size() - pos;
1381 byte *encrypted = new byte[cryptLen]; 1387 byte *encrypted = new byte[cryptLen];
1382 byte *decrypted = new byte[cryptLen]; 1388 byte *decrypted = new byte[cryptLen];
1383 1389
1384 f->at(pos); 1390 f->at(pos);
1385#ifndef PWM_EMBEDDED 1391#ifndef PWM_EMBEDDED
1386 if (f->readBlock(reinterpret_cast<char *>(encrypted), 1392 if (f->readBlock(reinterpret_cast<char *>(encrypted),
1387 static_cast<Q_ULONG>(cryptLen)) 1393 static_cast<Q_ULONG>(cryptLen))
1388 != static_cast<Q_LONG>(cryptLen)) { 1394 != static_cast<Q_LONG>(cryptLen)) {
1389 delete [] encrypted; 1395 delete [] encrypted;
1390 delete [] decrypted; 1396 delete [] decrypted;
1391 return e_readFile; 1397 return e_readFile;
1392 } 1398 }
1393#else 1399#else
1394 if (f->readBlock((char *)(encrypted), 1400 if (f->readBlock((char *)(encrypted),
1395 (unsigned long)(cryptLen)) 1401 (unsigned long)(cryptLen))
1396 != (long)(cryptLen)) { 1402 != (long)(cryptLen)) {
1397 delete [] encrypted; 1403 delete [] encrypted;
1398 delete [] decrypted; 1404 delete [] decrypted;
1399 return e_readFile; 1405 return e_readFile;
1400 } 1406 }
1401#endif 1407#endif
1402 switch (algo) { 1408 switch (algo) {
1403 case PWM_CRYPT_BLOWFISH: { 1409 case PWM_CRYPT_BLOWFISH: {
1404 Blowfish bf; 1410 Blowfish bf;
1405 bf.bf_setkey((byte *) pw->latin1(), pw->length()); 1411 bf.bf_setkey((byte *) pw->latin1(), pw->length());
1406 bf.bf_decrypt(decrypted, encrypted, cryptLen); 1412 bf.bf_decrypt(decrypted, encrypted, cryptLen);
1407 break; 1413 break;
1408 } 1414 }
1409 case PWM_CRYPT_AES128: 1415 case PWM_CRYPT_AES128:
1410 /*... fall through */ 1416 /*... fall through */
1411 case PWM_CRYPT_AES192: 1417 case PWM_CRYPT_AES192:
1412 case PWM_CRYPT_AES256: 1418 case PWM_CRYPT_AES256:
1413 case PWM_CRYPT_3DES: 1419 case PWM_CRYPT_3DES:
1414 case PWM_CRYPT_TWOFISH: 1420 case PWM_CRYPT_TWOFISH:
1415 case PWM_CRYPT_TWOFISH128: { 1421 case PWM_CRYPT_TWOFISH128: {
1416 if (!LibGCryptIf::available()) 1422 if (!LibGCryptIf::available())
1417 return e_cryptNotImpl; 1423 return e_cryptNotImpl;
1418 LibGCryptIf gc; 1424 LibGCryptIf gc;
1419 PwMerror err; 1425 PwMerror err;
1420 err = gc.decrypt(&decrypted, 1426 err = gc.decrypt(&decrypted,
1421 &cryptLen, 1427 &cryptLen,
1422 encrypted, 1428 encrypted,
1423 cryptLen, 1429 cryptLen,
1424 reinterpret_cast<const unsigned char *>(pw->latin1()), 1430 reinterpret_cast<const unsigned char *>(pw->latin1()),
1425 pw->length(), 1431 pw->length(),
1426 algo); 1432 algo,
1433 hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
1434);
1427 if (err != e_success) { 1435 if (err != e_success) {
1428 delete [] encrypted; 1436 delete [] encrypted;
1429 delete [] decrypted; 1437 delete [] decrypted;
1430 return e_cryptNotImpl; 1438 return e_cryptNotImpl;
1431 } 1439 }
1432 break; 1440 break;
1433 } 1441 }
1434 default: { 1442 default: {
1435 delete [] encrypted; 1443 delete [] encrypted;
1436 delete [] decrypted; 1444 delete [] decrypted;
1437 return e_cryptNotImpl; 1445 return e_cryptNotImpl;
1438 } } 1446 } }
1439 delete [] encrypted; 1447 delete [] encrypted;
1440#ifndef PWM_EMBEDDED 1448#ifndef PWM_EMBEDDED
1441 d->assign(reinterpret_cast<const char *>(decrypted), 1449 d->assign(reinterpret_cast<const char *>(decrypted),
1442 static_cast<string::size_type>(cryptLen)); 1450 static_cast<string::size_type>(cryptLen));
1443#else 1451#else
1444 d->assign((const char *)(decrypted), 1452 d->assign((const char *)(decrypted),
1445 (string::size_type)(cryptLen)); 1453 (string::size_type)(cryptLen));
1446#endif 1454#endif
1447 delete [] decrypted; 1455 delete [] decrypted;
1448 if (algo == PWM_CRYPT_BLOWFISH) { 1456 if (algo == PWM_CRYPT_BLOWFISH) {
1449 if (!Blowfish::unpadNull(d)) { 1457 if (!Blowfish::unpadNull(d)) {
1450 BUG(); 1458 BUG();
1451 return e_readFile; 1459 return e_readFile;
1452 } 1460 }
1453 } 1461 }
1454 return e_success; 1462 return e_success;
1455} 1463}
1456 1464
1457PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash, 1465PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash,
1458 const string *dataStream) 1466 const string *dataStream)
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
@@ -707,67 +707,71 @@ protected:
707 * for this document, while it's unnamed. If it's 0, 707 * for this document, while it's unnamed. If it's 0,
708 * we have to get a new unique one. 708 * we have to get a new unique one.
709 */ 709 */
710 unsigned int unnamedNum; 710 unsigned int unnamedNum;
711 /** is this doc going to be deleted (executing in destructor context) */ 711 /** is this doc going to be deleted (executing in destructor context) */
712 bool deleted; 712 bool deleted;
713 /** document timer */ 713 /** document timer */
714 DocTimer *_timer; 714 DocTimer *_timer;
715 /** lock counter for the "dataChanged" signal */ 715 /** lock counter for the "dataChanged" signal */
716 unsigned int dataChangedLock; 716 unsigned int dataChangedLock;
717 717
718 /** list of all open documents */ 718 /** list of all open documents */
719 static PwMDocList openDocList; 719 static PwMDocList openDocList;
720 720
721protected: 721protected:
722 /** serialize "dta" and return it in "d". */ 722 /** serialize "dta" and return it in "d". */
723 bool serializeDta(string *d); 723 bool serializeDta(string *d);
724 /** de-serialize "d" and overwrite "dta" */ 724 /** de-serialize "d" and overwrite "dta" */
725 bool deSerializeDta(const string *d, bool entriesLocked); 725 bool deSerializeDta(const string *d, bool entriesLocked);
726 /** write header to file */ 726 /** write header to file */
727 PwMerror writeFileHeader(char keyHash, char dataHash, char crypt, char compress, 727 PwMerror writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
728 QString *pw, QFile *f); 728 QString *pw, QFile *f);
729 /** write data-hash to file */ 729 /** write data-hash to file */
730 PwMerror writeDataHash(char dataHash, string *d, QFile *f); 730 PwMerror writeDataHash(char dataHash, string *d, QFile *f);
731 /** check header. Read header info and verify key-hash and filever. 731 /** check header. Read header info and verify key-hash and filever.
732 * returns length of header in "headerLength" */ 732 * returns length of header in "headerLength" */
733 PwMerror checkHeader(char *cryptAlgo, QString *pw, char *compress, 733 PwMerror checkHeader(char *cryptAlgo, QString *pw, char *compress,
734 unsigned int *headerLength, char *dataHashType, 734 unsigned int *headerLength, char *dataHashType,
735 string *dataHash, QFile *f); 735 string *dataHash, QFile *f);
736 /** check the data-hash */ 736 /** check the data-hash */
737 PwMerror checkDataHash(char dataHashType, const string *dataHash, const string *dataStream); 737 PwMerror checkDataHash(char dataHashType, const string *dataHash, const string *dataStream);
738 /** encrypt data "d" and write to "filename" */ 738 /** encrypt data "d" and write to "filename" */
739 PwMerror encrypt(string *d, const QString *pw, QFile *f, char algo); 739 PwMerror encrypt(string *d, const QString *pw, QFile *f, char algo,
740 char _hashalgo //US BUG: pass _hashalgo because we need it in hashPassphrase
741);
740 /** read data from file beginning at "pos", decrypt and return it */ 742 /** read data from file beginning at "pos", decrypt and return it */
741 PwMerror decrypt(string *d, unsigned int pos, const QString *pw, char algo, QFile *f); 743 PwMerror decrypt(string *d, unsigned int pos, const QString *pw, char algo,
744 char _hashalgo, //US BUG: pass _hashalgo because we need it in hashPassphrase
745QFile *f);
742 /** compress the data */ 746 /** compress the data */
743 bool compressDta(string *d, char algo); 747 bool compressDta(string *d, char algo);
744 /** uncompress the data */ 748 /** uncompress the data */
745 bool decompressDta(string *d, char algo); 749 bool decompressDta(string *d, char algo);
746 /** internal import function for a text-file generated by PwM. 750 /** internal import function for a text-file generated by PwM.
747 * If this is not a valid PwM-exported file, it returns e_fileFormat */ 751 * If this is not a valid PwM-exported file, it returns e_fileFormat */
748 PwMerror importText_PwM(const QString *file); 752 PwMerror importText_PwM(const QString *file);
749 /** PwM-text-import helper function to extract the name/pw/comment out 753 /** PwM-text-import helper function to extract the name/pw/comment out
750 * of one entry-line */ 754 * of one entry-line */
751 bool textExtractEntry_PwM(const char *in, ssize_t in_size, string *out); 755 bool textExtractEntry_PwM(const char *in, ssize_t in_size, string *out);
752 /** compare two strings */ 756 /** compare two strings */
753 bool compareString(const string &s1, const string &s2, bool caseSensitive, 757 bool compareString(const string &s1, const string &s2, bool caseSensitive,
754 bool exactWordMatch); 758 bool exactWordMatch);
755 /** clears all document-data */ 759 /** clears all document-data */
756 void clearDoc(); 760 void clearDoc();
757 /** delete all empty categories */ 761 /** delete all empty categories */
758 void delAllEmptyCat(bool dontFlagDirty); 762 void delAllEmptyCat(bool dontFlagDirty);
759 /** set a document status flag */ 763 /** set a document status flag */
760 void setDocStatFlag(unsigned int statFlag) 764 void setDocStatFlag(unsigned int statFlag)
761 { curDocStat |= statFlag; } 765 { curDocStat |= statFlag; }
762 /** unset a document status flag */ 766 /** unset a document status flag */
763 void unsetDocStatFlag(unsigned int statFlag) 767 void unsetDocStatFlag(unsigned int statFlag)
764 { curDocStat &= ~statFlag; } 768 { curDocStat &= ~statFlag; }
765 /** get a document status flag */ 769 /** get a document status flag */
766 bool getDocStatFlag(unsigned int statFlag) const 770 bool getDocStatFlag(unsigned int statFlag) const
767 { return (curDocStat & statFlag); } 771 { return (curDocStat & statFlag); }
768 /** set the "currentPassword" */ 772 /** set the "currentPassword" */
769 void setCurrentPw(const QString &pw) 773 void setCurrentPw(const QString &pw)
770 { 774 {
771 currentPw = pw; 775 currentPw = pw;
772 setDocStatFlag(DOC_STAT_DISK_DIRTY); 776 setDocStatFlag(DOC_STAT_DISK_DIRTY);
773 } 777 }