summaryrefslogtreecommitdiff
path: root/frontend/gamma/js
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2013-04-19 15:09:28 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2013-04-19 15:09:28 (UTC)
commit074e70457c90344b3c1cb236105638d692a0066b (patch) (unidiff)
treec5ffabd3eaf74cbeb69974beacdb5a5f8c235adc /frontend/gamma/js
parent48c9280c9a255f2a85ad5729830df884e64a9c5d (diff)
downloadclipperz-074e70457c90344b3c1cb236105638d692a0066b.zip
clipperz-074e70457c90344b3c1cb236105638d692a0066b.tar.gz
clipperz-074e70457c90344b3c1cb236105638d692a0066b.tar.bz2
Fixed an issue on the AES-CTR block mode
The previous version of the CTR encoding was incrementing the counter in a weird way, mixing up data from the previous block. The current fix can correctly decrypt data encoded with AES-CTR using other libraries/languages (currently tested only with Python).
Diffstat (limited to 'frontend/gamma/js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/AES_2.js843
-rw-r--r--frontend/gamma/js/Clipperz/PM/Crypto.js106
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/User.js4
-rw-r--r--frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js4
-rw-r--r--frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js5
5 files changed, 924 insertions, 38 deletions
diff --git a/frontend/gamma/js/Clipperz/Crypto/AES_2.js b/frontend/gamma/js/Clipperz/Crypto/AES_2.js
new file mode 100644
index 0000000..1627f39
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/AES_2.js
@@ -0,0 +1,843 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.AES_2 depends on Clipperz.ByteArray!";
26}
27
28 //Dependency commented to avoid a circular reference
29//try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
30 //throw "Clipperz.Crypto.AES_2 depends on Clipperz.Crypto.PRNG!";
31//}
32
33if (typeof(Clipperz.Crypto.AES_2) == 'undefined') { Clipperz.Crypto.AES_2 = {}; }
34
35//#############################################################################
36
37Clipperz.Crypto.AES_2.DeferredExecutionContext = function(args) {
38 args = args || {};
39
40 this._key = args.key;
41 this._message = args.message;
42 this._result = args.message.clone();
43 this._nonce = args.nonce;
44 this._messageLength = this._message.length();
45
46 this._messageArray = this._message.arrayValues();
47 this._resultArray = this._result.arrayValues();
48 this._nonceArray = this._nonce.arrayValues();
49
50 this._executionStep = 0;
51
52 // this._elaborationChunkSize = 1024; // 4096; // 16384; //4096;
53 this._elaborationChunks = 10;
54 this._pauseTime = 0.02; // 0.02 //0.2;
55
56 return this;
57}
58
59Clipperz.Crypto.AES_2.DeferredExecutionContext.prototype = MochiKit.Base.update(null, {
60
61 'key': function() {
62 return this._key;
63 },
64
65 'message': function() {
66 return this._message;
67 },
68
69 'messageLength': function() {
70 return this._messageLength;
71 },
72
73 'result': function() {
74 return new Clipperz.ByteArray(this.resultArray());
75 },
76
77 'nonce': function() {
78 return this._nonce;
79 },
80
81 'messageArray': function() {
82 return this._messageArray;
83 },
84
85 'resultArray': function() {
86 return this._resultArray;
87 },
88
89 'nonceArray': function() {
90 return this._nonceArray;
91 },
92
93 'elaborationChunkSize': function() {
94 // return Clipperz.Crypto.AES_2.DeferredExecution.chunkSize;
95 // return this._elaborationChunkSize;
96 return (this._elaborationChunks * 1024);
97 },
98
99 'executionStep': function() {
100 return this._executionStep;
101 },
102
103 'setExecutionStep': function(aValue) {
104 this._executionStep = aValue;
105 },
106
107 'tuneExecutionParameters': function (anElapsedTime) {
108//var originalChunks = this._elaborationChunks;
109 if (anElapsedTime > 0) {
110 this._elaborationChunks = Math.round(this._elaborationChunks * ((anElapsedTime + 1000)/(anElapsedTime * 2)));
111 }
112//Clipperz.log("tuneExecutionParameters - elapsedTime: " + anElapsedTime + /*originalChunks,*/ " chunks # " + this._elaborationChunks + " [" + this._executionStep + " / " + this._messageLength + "]");
113 },
114
115 'pause': function(aValue) {
116 // return MochiKit.Async.wait(Clipperz.Crypto.AES_2.DeferredExecution.pauseTime, aValue);
117 return MochiKit.Async.wait(this._pauseTime, aValue);
118 },
119
120 'isDone': function () {
121 return (this._executionStep >= this._messageLength);
122 },
123
124 //-----------------------------------------------------------------------------
125 __syntaxFix__: "syntax fix"
126
127});
128
129//#############################################################################
130
131Clipperz.Crypto.AES_2.Key = function(args) {
132 args = args || {};
133
134 this._key = args.key;
135 this._keySize = args.keySize || this.key().length();
136
137 if (this.keySize() == 128/8) {
138 this._b = 176;
139 this._numberOfRounds = 10;
140 } else if (this.keySize() == 256/8) {
141 this._b = 240;
142 this._numberOfRounds = 14;
143 } else {
144 Clipperz.logError("AES unsupported key size: " + (this.keySize() * 8) + " bits");
145 throw Clipperz.Crypto.AES_2.exception.UnsupportedKeySize;
146 }
147
148 this._stretchedKey = null;
149
150 return this;
151}
152
153Clipperz.Crypto.AES_2.Key.prototype = MochiKit.Base.update(null, {
154
155 'asString': function() {
156 return "Clipperz.Crypto.AES_2.Key (" + this.key().toHexString() + ")";
157 },
158
159 //-----------------------------------------------------------------------------
160
161 'key': function() {
162 return this._key;
163 },
164
165 'keySize': function() {
166 return this._keySize;
167 },
168
169 'b': function() {
170 return this._b;
171 },
172
173 'numberOfRounds': function() {
174 return this._numberOfRounds;
175 },
176 //=========================================================================
177
178 'keyScheduleCore': function(aWord, aRoundConstantsIndex) {
179 varresult;
180 var sbox;
181
182 sbox = Clipperz.Crypto.AES_2.sbox();
183
184 result = [sbox[aWord[1]] ^ Clipperz.Crypto.AES_2.roundConstants()[aRoundConstantsIndex],
185 sbox[aWord[2]],
186 sbox[aWord[3]],
187 sbox[aWord[0]]];
188
189 return result;
190 },
191
192 //-----------------------------------------------------------------------------
193
194 'xorWithPreviousStretchValues': function(aKey, aWord, aPreviousWordIndex) {
195 varresult;
196 var i,c;
197
198 result = [];
199 c = 4;
200 for (i=0; i<c; i++) {
201 result[i] = aWord[i] ^ aKey.byteAtIndex(aPreviousWordIndex + i);
202 }
203
204 return result;
205 },
206
207 //-----------------------------------------------------------------------------
208
209 'sboxShakeup': function(aWord) {
210 var result;
211 var sbox;
212 var i,c;
213
214 result = [];
215 sbox = Clipperz.Crypto.AES_2.sbox();
216 c =4;
217 for (i=0; i<c; i++) {
218 result[i] = sbox[aWord[i]];
219 }
220
221 return result;
222 },
223
224 //-----------------------------------------------------------------------------
225
226 'stretchKey': function(aKey) {
227 varcurrentWord;
228 varkeyLength;
229 varpreviousStretchIndex;
230 var i,c;
231
232 keyLength = aKey.length();
233 previousStretchIndex = keyLength - this.keySize();
234
235 currentWord = [aKey.byteAtIndex(keyLength - 4),
236 aKey.byteAtIndex(keyLength - 3),
237 aKey.byteAtIndex(keyLength - 2),
238 aKey.byteAtIndex(keyLength - 1)];
239 currentWord = this.keyScheduleCore(currentWord, keyLength / this.keySize());
240
241 if (this.keySize() == 256/8) {
242 c = 8;
243 } else if (this.keySize() == 128/8){
244 c = 4;
245 }
246
247 for (i=0; i<c; i++) {
248 if (i == 4) {
249 //fifth streatch word
250 currentWord = this.sboxShakeup(currentWord);
251 }
252
253 currentWord = this.xorWithPreviousStretchValues(aKey, currentWord, previousStretchIndex + (i*4));
254 aKey.appendBytes(currentWord);
255 }
256
257 return aKey;
258 },
259
260 //-----------------------------------------------------------------------------
261
262 'stretchedKey': function() {
263 if (this._stretchedKey == null) {
264 var stretchedKey;
265
266 stretchedKey = this.key().clone();
267
268 while (stretchedKey.length() < this.keySize()) {
269 stretchedKey.appendByte(0);
270 }
271
272 while (stretchedKey.length() < this.b()) {
273 stretchedKey = this.stretchKey(stretchedKey);
274 }
275
276 this._stretchedKey = stretchedKey.split(0, this.b());
277 }
278
279 return this._stretchedKey;
280 },
281
282 //=========================================================================
283 __syntaxFix__: "syntax fix"
284});
285
286//#############################################################################
287
288Clipperz.Crypto.AES_2.State = function(args) {
289 args = args || {};
290
291 this._data = args.block.slice(0);
292 this._key = args.key;
293
294 return this;
295}
296
297Clipperz.Crypto.AES_2.State.prototype = MochiKit.Base.update(null, {
298
299 'key': function() {
300 return this._key;
301 },
302
303 //-----------------------------------------------------------------------------
304
305 'data': function() {
306 return this._data;
307 },
308
309 'setData': function(aValue) {
310 this._data = aValue;
311 },
312
313 //=========================================================================
314
315 'addRoundKey': function(aRoundNumber) {
316 //each byte of the state is combined with the round key; each round key is derived from the cipher key using a key schedule.
317 vardata;
318 varstretchedKey;
319 varfirstStretchedKeyIndex;
320 var i,c;
321
322 data = this.data();
323 stretchedKey = this.key().stretchedKey();
324 firstStretchedKeyIndex = aRoundNumber * (128/8);
325 c = 128/8;
326 for (i=0; i<c; i++) {
327 data[i] = data[i] ^ stretchedKey.byteAtIndex(firstStretchedKeyIndex + i);
328 }
329 },
330
331 //-----------------------------------------------------------------------------
332
333 'subBytes': function() {
334 // a non-linear substitution step where each byte is replaced with another according to a lookup table.
335 var i,c;
336 vardata;
337 var sbox;
338
339 data = this.data();
340 sbox = Clipperz.Crypto.AES_2.sbox();
341
342 c = 16;
343 for (i=0; i<c; i++) {
344 data[i] = sbox[data[i]];
345 }
346 },
347
348 //-----------------------------------------------------------------------------
349
350 'shiftRows': function() {
351 //a transposition step where each row of the state is shifted cyclically a certain number of steps.
352 varnewValue;
353 vardata;
354 varshiftMapping;
355 vari,c;
356
357 newValue = new Array(16);
358 data = this.data();
359 shiftMapping = Clipperz.Crypto.AES_2.shiftRowMapping();
360 // [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
361 c = 16;
362 for (i=0; i<c; i++) {
363 newValue[i] = data[shiftMapping[i]];
364 }
365 for (i=0; i<c; i++) {
366 data[i] = newValue[i];
367 }
368 },
369
370 //-----------------------------------------------------------------------------
371/*
372 'mixColumnsWithValues': function(someValues) {
373 varresult;
374 vara;
375 var i,c;
376
377 c = 4;
378 result = [];
379 a = [];
380 for (i=0; i<c; i++) {
381 a[i] = [];
382 a[i][1] = someValues[i]
383 if ((a[i][1] & 0x80) == 0x80) {
384 a[i][2] = (a[i][1] << 1) ^ 0x11b;
385 } else {
386 a[i][2] = a[i][1] << 1;
387 }
388
389 a[i][3] = a[i][2] ^ a[i][1];
390 }
391
392 for (i=0; i<c; i++) {
393 varx;
394
395 x = Clipperz.Crypto.AES_2.mixColumnsMatrix()[i];
396 result[i] = a[0][x[0]] ^ a[1][x[1]] ^ a[2][x[2]] ^ a[3][x[3]];
397 }
398
399 return result;
400 },
401
402 'mixColumns': function() {
403 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
404 var data;
405 var i, c;
406
407 data = this.data();
408 c = 4;
409 for(i=0; i<c; i++) {
410 varblockIndex;
411 var mixedValues;
412
413 blockIndex = i * 4;
414 mixedValues = this.mixColumnsWithValues([data[blockIndex + 0],
415 data[blockIndex + 1],
416 data[blockIndex + 2],
417 data[blockIndex + 3]]);
418 data[blockIndex + 0] = mixedValues[0];
419 data[blockIndex + 1] = mixedValues[1];
420 data[blockIndex + 2] = mixedValues[2];
421 data[blockIndex + 3] = mixedValues[3];
422 }
423 },
424*/
425
426 'mixColumns': function() {
427 //a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
428 var data;
429 var i, c;
430 var a_1;
431 var a_2;
432
433 a_1 = new Array(4);
434 a_2 = new Array(4);
435
436 data = this.data();
437 c = 4;
438 for(i=0; i<c; i++) {
439 varblockIndex;
440 var ii, cc;
441
442 blockIndex = i * 4;
443
444 cc = 4;
445 for (ii=0; ii<cc; ii++) {
446 var value;
447
448 value = data[blockIndex + ii];
449 a_1[ii] = value;
450 a_2[ii] = (value & 0x80) ? ((value << 1) ^ 0x011b) : (value << 1);
451 }
452
453 data[blockIndex + 0] = a_2[0] ^ a_1[1] ^ a_2[1] ^ a_1[2] ^ a_1[3];
454 data[blockIndex + 1] = a_1[0] ^ a_2[1] ^ a_1[2] ^ a_2[2] ^ a_1[3];
455 data[blockIndex + 2] = a_1[0] ^ a_1[1] ^ a_2[2] ^ a_1[3] ^ a_2[3];
456 data[blockIndex + 3] = a_1[0] ^ a_2[0] ^ a_1[1] ^ a_1[2] ^ a_2[3];
457 }
458 },
459
460 //=========================================================================
461
462 'spinRound': function(aRoundNumber) {
463 this.addRoundKey(aRoundNumber);
464 this.subBytes();
465 this.shiftRows();
466 this.mixColumns();
467 },
468
469 'spinLastRound': function() {
470 this.addRoundKey(this.key().numberOfRounds() - 1);
471 this.subBytes();
472 this.shiftRows();
473 this.addRoundKey(this.key().numberOfRounds());
474 },
475
476 //=========================================================================
477
478 'encrypt': function() {
479 vari,c;
480
481 c = this.key().numberOfRounds() - 1;
482 for (i=0; i<c; i++) {
483 this.spinRound(i);
484 }
485
486 this.spinLastRound();
487 },
488
489 //=========================================================================
490 __syntaxFix__: "syntax fix"
491});
492
493//#############################################################################
494
495Clipperz.Crypto.AES_2.VERSION = "0.1";
496Clipperz.Crypto.AES_2.NAME = "Clipperz.Crypto.AES_2";
497
498MochiKit.Base.update(Clipperz.Crypto.AES_2, {
499
500 //http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-AES.html
501 //http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
502 //http://en.wikipedia.org/wiki/Rijndael_key_schedule
503 //http://en.wikipedia.org/wiki/Rijndael_S-box
504
505 '__repr__': function () {
506 return "[" + this.NAME + " " + this.VERSION + "]";
507 },
508
509 'toString': function () {
510 return this.__repr__();
511 },
512
513 //=============================================================================
514
515 '_sbox': null,
516 'sbox': function() {
517 if (Clipperz.Crypto.AES_2._sbox == null) {
518 Clipperz.Crypto.AES_2._sbox = [
5190x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
5200xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
5210xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
5220x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
5230x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
5240x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
5250xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
5260x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
5270xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
5280x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
5290xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
5300xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
5310xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
5320x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
5330xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
5340x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
535 ];
536 }
537
538 return Clipperz.Crypto.AES_2._sbox;
539 },
540
541 //-----------------------------------------------------------------------------
542 //
543 // 0 4 8 12 0 4 812
544 // 1 5 9 13 => 5 9 131
545 // 2 6 10 14 10 14 26
546 // 3 7 11 15 15 3 711
547 //
548 '_shiftRowMapping': null,
549 'shiftRowMapping': function() {
550 if (Clipperz.Crypto.AES_2._shiftRowMapping == null) {
551 Clipperz.Crypto.AES_2._shiftRowMapping = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
552 }
553
554 return Clipperz.Crypto.AES_2._shiftRowMapping;
555 },
556
557 //-----------------------------------------------------------------------------
558
559 '_mixColumnsMatrix': null,
560 'mixColumnsMatrix': function() {
561 if (Clipperz.Crypto.AES_2._mixColumnsMatrix == null) {
562 Clipperz.Crypto.AES_2._mixColumnsMatrix = [[2, 3, 1 ,1],
563 [1, 2, 3, 1],
564 [1, 1, 2, 3],
565 [3, 1, 1, 2] ];
566 }
567
568 return Clipperz.Crypto.AES_2._mixColumnsMatrix;
569 },
570
571 '_roundConstants': null,
572 'roundConstants': function() {
573 if (Clipperz.Crypto.AES_2._roundConstants == null) {
574 Clipperz.Crypto.AES_2._roundConstants = [ , 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154];
575 // Clipperz.Crypto.AES_2._roundConstants = [ , 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a];
576 }
577
578 return Clipperz.Crypto.AES_2._roundConstants;
579 },
580
581 //=============================================================================
582
583 'incrementNonce': function(nonce) {
584 var i;
585 var done;
586
587 done = false;
588 i = nonce.length - 1;
589
590 while ((i>=0) && (done == false)) {
591 var currentByteValue;
592
593 currentByteValue = nonce[i];
594
595 if (currentByteValue == 0xff) {
596 nonce[i] = 0;
597 if (i>= 0) {
598 i --;
599 } else {
600 done = true;
601 }
602 } else {
603 nonce[i] = currentByteValue + 1;
604 done = true;
605 }
606 }
607 },
608
609 //-----------------------------------------------------------------------------
610
611 'encryptBlock': function(aKey, aBlock) {
612 varresult;
613 varstate;
614
615 state = new Clipperz.Crypto.AES_2.State({block:aBlock, key:aKey});
616//is(state.data(), 'before');
617 state.encrypt();
618 result = state.data();
619
620 return result;
621 },
622
623 //-----------------------------------------------------------------------------
624
625 'encryptBlocks': function(aKey, aMessage, aNonce) {
626 varresult;
627 var nonce;
628 var self;
629 varmessageIndex;
630 varmessageLength;
631 var blockSize;
632
633 self = Clipperz.Crypto.AES_2;
634 blockSize = 128/8;
635 messageLength = aMessage.length;
636 nonce = aNonce;
637
638 result = aMessage;
639 messageIndex = 0;
640 while (messageIndex < messageLength) {
641 var encryptedBlock;
642 var i,c;
643
644 encryptedBlock = self.encryptBlock(aKey, nonce);
645
646 if ((messageLength - messageIndex) > blockSize) {
647 c = blockSize;
648 } else {
649 c = messageLength - messageIndex;
650 }
651
652 for (i=0; i<c; i++) {
653 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
654 }
655
656 messageIndex += blockSize;
657 // nonce = self.incrementNonce(nonce);
658 self.incrementNonce(nonce)
659 }
660
661 return result;
662 },
663
664 //-----------------------------------------------------------------------------
665
666 'encrypt': function(aKey, someData, aNonce) {
667 var result;
668 var nonce;
669 varencryptedData;
670 var key;
671
672 key = new Clipperz.Crypto.AES_2.Key({key:aKey});
673 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
674
675 encryptedData = Clipperz.Crypto.AES_2.encryptBlocks(key, someData.arrayValues(), nonce.arrayValues());
676
677 result = nonce.appendBytes(encryptedData);
678
679 return result;
680 },
681
682 //-----------------------------------------------------------------------------
683
684 'decrypt': function(aKey, someData) {
685 var result;
686 var nonce;
687 var encryptedData;
688 var decryptedData;
689 vardataIterator;
690 var key;
691
692 key = new Clipperz.Crypto.AES_2.Key({key:aKey});
693
694 encryptedData = someData.arrayValues();
695 nonce = encryptedData.slice(0, (128/8));
696 encryptedData = encryptedData.slice(128/8);
697 decryptedData = Clipperz.Crypto.AES_2.encryptBlocks(key, encryptedData, nonce);
698
699 result = new Clipperz.ByteArray(decryptedData);
700
701 return result;
702 },
703
704 //=============================================================================
705
706 'deferredEncryptExecutionChunk': function(anExecutionContext) {
707 varresult;
708 var nonce;
709 var self;
710 varmessageIndex;
711 varmessageLength;
712 var blockSize;
713 var executionLimit;
714 var startTime, endTime;
715
716 self = Clipperz.Crypto.AES_2;
717 startTime = new Date();
718 blockSize = 128/8;
719 messageLength = anExecutionContext.messageArray().length;
720 nonce = anExecutionContext.nonceArray();
721 result = anExecutionContext.resultArray();
722
723 messageIndex = anExecutionContext.executionStep();
724 executionLimit = messageIndex + anExecutionContext.elaborationChunkSize();
725 executionLimit = Math.min(executionLimit, messageLength);
726
727 while (messageIndex < executionLimit) {
728 var encryptedBlock;
729 var i,c;
730
731//console.log("+++ nonce: [" + nonce + "]")
732 encryptedBlock = self.encryptBlock(anExecutionContext.key(), nonce);
733
734 if ((executionLimit - messageIndex) > blockSize) {
735 c = blockSize;
736 } else {
737 c = executionLimit - messageIndex;
738 }
739
740 for (i=0; i<c; i++) {
741 result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
742 }
743
744 messageIndex += blockSize;
745 // nonce = self.incrementNonce(nonce);
746 self.incrementNonce(nonce);
747 }
748 anExecutionContext.setExecutionStep(messageIndex);
749 endTime = new Date();
750 anExecutionContext.tuneExecutionParameters(endTime - startTime);
751
752 return anExecutionContext;
753 },
754
755 //-----------------------------------------------------------------------------
756
757 'deferredEncryptBlocks': function(anExecutionContext) {
758 vardeferredResult;
759
760//console.log("executionContext", anExecutionContext)
761//console.log(" --- nonce: " + anExecutionContext.nonceArray())
762 if (! anExecutionContext.isDone()) {
763 deferredResult = Clipperz.Async.callbacks("Clipperz.Crypto.AES_2.deferredEncryptBloks", [
764 Clipperz.Crypto.AES_2.deferredEncryptExecutionChunk,
765 MochiKit.Base.method(anExecutionContext, 'pause'),
766 Clipperz.Crypto.AES_2.deferredEncryptBlocks
767 ], {trace:false}, anExecutionContext);
768 } else {
769 deferredResult = MochiKit.Async.succeed(anExecutionContext);
770 }
771
772 return deferredResult;
773 },
774
775 //-----------------------------------------------------------------------------
776
777 'deferredEncrypt': function(aKey, someData, aNonce) {
778 var deferredResult;
779 varexecutionContext;
780 var result;
781 var nonce;
782 var key;
783
784 key = new Clipperz.Crypto.AES_2.Key({key:aKey});
785 nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
786
787 executionContext = new Clipperz.Crypto.AES_2.DeferredExecutionContext({key:key, message:someData, nonce:nonce});
788
789 deferredResult = new Clipperz.Async.Deferred("AES.deferredEncrypt");
790 deferredResult.addCallback(Clipperz.Crypto.AES_2.deferredEncryptBlocks);
791 deferredResult.addCallback(function(anExecutionContext) {
792 var result;
793
794 result = anExecutionContext.nonce().clone();
795 result.appendBytes(anExecutionContext.resultArray());
796
797 return result;
798 });
799 deferredResult.callback(executionContext)
800
801 return deferredResult;
802 },
803
804 //-----------------------------------------------------------------------------
805
806 'deferredDecrypt': function(aKey, someData) {
807 var deferredResult
808 var nonce;
809 var message;
810 var key;
811
812 key = new Clipperz.Crypto.AES_2.Key({key:aKey});
813 nonce = someData.split(0, (128/8));
814//console.log("nonce: [" + nonce.arrayValues() + "]")
815 message = someData.split(128/8);
816//console.log("message: [" + message.arrayValues() + "]")
817 executionContext = new Clipperz.Crypto.AES_2.DeferredExecutionContext({key:key, message:message, nonce:nonce});
818
819 deferredResult = new Clipperz.Async.Deferred("AES.deferredDecrypt");
820 deferredResult.addCallback(Clipperz.Crypto.AES_2.deferredEncryptBlocks);
821 deferredResult.addCallback(function(anExecutionContext) {
822 return anExecutionContext.result();
823 });
824 deferredResult.callback(executionContext);
825
826 return deferredResult;
827 },
828
829 //-----------------------------------------------------------------------------
830 __syntaxFix__: "syntax fix"
831
832});
833
834//#############################################################################
835
836//Clipperz.Crypto.AES_2.DeferredExecution = {
837 // 'chunkSize': 16384, // 4096, // 1024 4096 8192 1638432768;
838 // 'pauseTime': 0.02 //0.2
839//}
840
841Clipperz.Crypto.AES_2.exception = {
842 'UnsupportedKeySize': new MochiKit.Base.NamedError("Clipperz.Crypto.AES_2.exception.UnsupportedKeySize")
843};
diff --git a/frontend/gamma/js/Clipperz/PM/Crypto.js b/frontend/gamma/js/Clipperz/PM/Crypto.js
index cd10e33..7edf17f 100644
--- a/frontend/gamma/js/Clipperz/PM/Crypto.js
+++ b/frontend/gamma/js/Clipperz/PM/Crypto.js
@@ -1,159 +1,159 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } 24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } 25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
26if (typeof(Clipperz.PM.Crypto) == 'undefined') { Clipperz.PM.Crypto = {}; } 26if (typeof(Clipperz.PM.Crypto) == 'undefined') { Clipperz.PM.Crypto = {}; }
27 27
28Clipperz.PM.Crypto.VERSION = "0.2"; 28Clipperz.PM.Crypto.VERSION = "0.2";
29Clipperz.PM.Crypto.NAME = "Clipperz.PM.Crypto"; 29Clipperz.PM.Crypto.NAME = "Clipperz.PM.Crypto";
30 30
31Clipperz.PM.Crypto.encryptingFunctions = {}; 31Clipperz.PM.Crypto.encryptingFunctions = {};
32 32
33MochiKit.Base.update(Clipperz.PM.Crypto, { 33MochiKit.Base.update(Clipperz.PM.Crypto, {
34 34
35 '__repr__': function () { 35 '__repr__': function () {
36 return "[" + this.NAME + " " + this.VERSION + "]"; 36 return "[" + this.NAME + " " + this.VERSION + "]";
37 }, 37 },
38 38
39 //------------------------------------------------------------------------- 39 //-------------------------------------------------------------------------
40 40
41 'toString': function () { 41 'toString': function () {
42 return this.__repr__(); 42 return this.__repr__();
43 }, 43 },
44 44
45 //------------------------------------------------------------------------- 45 //-------------------------------------------------------------------------
46/* 46/*
47 'communicationProtocol': { 47 'communicationProtocol': {
48 'currentVersion': '0.2', 48 'currentVersion': '0.2',
49 'versions': { 49 'versions': {
50 '0.1': Clipperz.PM.Connection.SRP['1.0'],//Clipperz.Crypto.SRP.versions['1.0'].Connection, 50 '0.1': Clipperz.PM.Connection.SRP['1.0'],//Clipperz.Crypto.SRP.versions['1.0'].Connection,
51 '0.2': Clipperz.PM.Connection.SRP['1.1']//Clipperz.Crypto.SRP.versions['1.1'].Connection 51 '0.2': Clipperz.PM.Connection.SRP['1.1']//Clipperz.Crypto.SRP.versions['1.1'].Connection
52 }, 52 },
53 'fallbackVersions': { 53 'fallbackVersions': {
54 'current':'0.1', 54 'current':'0.1',
55 '0.2': '0.1', 55 '0.2': '0.1',
56 '0.1': null 56 '0.1': null
57 } 57 }
58 }, 58 },
59*/ 59*/
60 //------------------------------------------------------------------------- 60 //-------------------------------------------------------------------------
61 61
62 'encryptingFunctions': { 62 'encryptingFunctions': {
63 'currentVersion': '0.3', 63 'currentVersion': '0.4',
64 'versions': { 64 'versions': {
65 65
66 //##################################################################### 66 //#####################################################################
67 67
68 '0.1': { 68 '0.1': {
69 'encrypt': function(aKey, aValue) { 69 'encrypt': function(aKey, aValue) {
70 return Clipperz.Crypto.Base.encryptUsingSecretKey(aKey, Clipperz.Base.serializeJSON(aValue)); 70 return Clipperz.Crypto.Base.encryptUsingSecretKey(aKey, Clipperz.Base.serializeJSON(aValue));
71 }, 71 },
72 72
73 'deferredEncrypt': function(aKey, aValue) { 73 'deferredEncrypt': function(aKey, aValue) {
74 var deferredResult; 74 var deferredResult;
75 75
76 deferredResult = new Clipperz.Async.Deferred("Crypto[0.1].deferredEncrypt"); 76 deferredResult = new Clipperz.Async.Deferred("Crypto[0.1].deferredEncrypt");
77 deferredResult.addCallback(Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].encrypt, aKey, aValue); 77 deferredResult.addCallback(Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].encrypt, aKey, aValue);
78 deferredResult.callback(); 78 deferredResult.callback();
79 79
80 return deferredResult; 80 return deferredResult;
81 }, 81 },
82 82
83 'decrypt': function(aKey, aValue) { 83 'decrypt': function(aKey, aValue) {
84 var result; 84 var result;
85 85
86 if (aValue != null) { 86 if (aValue != null) {
87 result = Clipperz.Base.evalJSON(Clipperz.Crypto.Base.decryptUsingSecretKey(aKey, aValue)); 87 result = Clipperz.Base.evalJSON(Clipperz.Crypto.Base.decryptUsingSecretKey(aKey, aValue));
88 } else { 88 } else {
89 result = null; 89 result = null;
90 } 90 }
91 91
92 return result; 92 return result;
93 }, 93 },
94 94
95 'deferredDecrypt': function(aKey, aValue) { 95 'deferredDecrypt': function(aKey, aValue) {
96 var deferredResult; 96 var deferredResult;
97 97
98 deferredResult = new Clipperz.Async.Deferred("Crypto.[0.1].deferredDecrypt"); 98 deferredResult = new Clipperz.Async.Deferred("Crypto.[0.1].deferredDecrypt");
99 deferredResult.addCallback(Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].decrypt, aKey, aValue); 99 deferredResult.addCallback(Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].decrypt, aKey, aValue);
100 deferredResult.callback(); 100 deferredResult.callback();
101 101
102 return deferredResult; 102 return deferredResult;
103 }, 103 },
104 104
105 'hash': function(aValue) { 105 'hash': function(aValue) {
106 var result; 106 var result;
107 var strngResult; 107 var strngResult;
108 108
109 stringResult = Clipperz.Crypto.Base.computeHashValue(aValue.asString()); //!!!!!!! 109 stringResult = Clipperz.Crypto.Base.computeHashValue(aValue.asString()); //!!!!!!!
110 result = new Clipperz.ByteArray("0x" + stringResult); 110 result = new Clipperz.ByteArray("0x" + stringResult);
111 111
112 return result; 112 return result;
113 }, 113 },
114 114
115 'deriveKey': function(aStringValue) { 115 'deriveKey': function(aStringValue) {
116 return Clipperz.Crypto.Base.computeHashValue(aStringValue); 116 return Clipperz.Crypto.Base.computeHashValue(aStringValue);
117 } 117 }
118 }, 118 },
119 119
120 //##################################################################### 120 //#####################################################################
121 121
122 '0.2': { 122 '0.2': {
123 'encrypt': function(aKey, aValue, aNonce) { 123 'encrypt': function(aKey, aValue, aNonce) {
124 var result; 124 var result;
125 varkey, value; 125 varkey, value;
126 var dataToEncrypt; 126 var dataToEncrypt;
127 var encryptedData; 127 var encryptedData;
128 128
129 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 129 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
130 value = new Clipperz.ByteArray(Clipperz.Base.serializeJSON(aValue)); 130 value = new Clipperz.ByteArray(Clipperz.Base.serializeJSON(aValue));
131 dataToEncrypt = Clipperz.Crypto.SHA.sha_d256(value).appendBlock(value); 131 dataToEncrypt = Clipperz.Crypto.SHA.sha_d256(value).appendBlock(value);
132 encryptedData = Clipperz.Crypto.AES.encrypt(key, dataToEncrypt, aNonce); 132 encryptedData = Clipperz.Crypto.AES.encrypt(key, dataToEncrypt, aNonce);
133 result = encryptedData.toBase64String(); 133 result = encryptedData.toBase64String();
134 134
135 return result; 135 return result;
136 }, 136 },
137 137
138 'deferredEncrypt': function(aKey, aValue, aNonce) { 138 'deferredEncrypt': function(aKey, aValue, aNonce) {
139 var deferredResult; 139 var deferredResult;
140 varkey, value; 140 varkey, value;
141 var dataToEncrypt; 141 var dataToEncrypt;
142 // var encryptedData; 142 // var encryptedData;
143 143
144 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 144 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
145 value = new Clipperz.ByteArray(Clipperz.Base.serializeJSON(aValue)); 145 value = new Clipperz.ByteArray(Clipperz.Base.serializeJSON(aValue));
146 dataToEncrypt = Clipperz.Crypto.SHA.sha_d256(value).appendBlock(value); 146 dataToEncrypt = Clipperz.Crypto.SHA.sha_d256(value).appendBlock(value);
147 147
148 deferredResult = new Clipperz.Async.Deferred("Crypto[0.2].deferredEncrypt") 148 deferredResult = new Clipperz.Async.Deferred("Crypto[0.2].deferredEncrypt")
149 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, dataToEncrypt, aNonce); 149 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, dataToEncrypt, aNonce);
150 deferredResult.addCallback(function(aResult) { 150 deferredResult.addCallback(function(aResult) {
151 return aResult.toBase64String(); 151 return aResult.toBase64String();
152 }) 152 })
153 deferredResult.callback(); 153 deferredResult.callback();
154 154
155 return deferredResult; 155 return deferredResult;
156 }, 156 },
157 157
158 'decrypt': function(aKey, aValue) { 158 'decrypt': function(aKey, aValue) {
159 var result; 159 var result;
@@ -227,282 +227,320 @@ MochiKit.Base.update(Clipperz.PM.Crypto, {
227 var result; 227 var result;
228 228
229 byteData = new Clipperz.ByteArray(aStringValue); 229 byteData = new Clipperz.ByteArray(aStringValue);
230 result = Clipperz.Crypto.SHA.sha_d256(byteData); 230 result = Clipperz.Crypto.SHA.sha_d256(byteData);
231 231
232 return result; 232 return result;
233 } 233 }
234 }, 234 },
235 235
236 //##################################################################### 236 //#####################################################################
237 237
238 '0.3': { 238 '0.3': {
239 'encrypt': function(aKey, aValue, aNonce) { 239 'encrypt': function(aKey, aValue, aNonce) {
240 var result; 240 var result;
241 varkey, value; 241 varkey, value;
242 var data; 242 var data;
243 var dataToEncrypt; 243 var dataToEncrypt;
244 var encryptedData; 244 var encryptedData;
245 245
246 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 246 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
247 value = Clipperz.Base.serializeJSON(aValue); 247 value = Clipperz.Base.serializeJSON(aValue);
248 data = new Clipperz.ByteArray(value); 248 data = new Clipperz.ByteArray(value);
249 encryptedData = Clipperz.Crypto.AES.encrypt(key, data, aNonce); 249 encryptedData = Clipperz.Crypto.AES.encrypt(key, data, aNonce);
250 result = encryptedData.toBase64String(); 250 result = encryptedData.toBase64String();
251 251
252 return result; 252 return result;
253 }, 253 },
254 254
255 'deferredEncrypt': function(aKey, aValue, aNonce) { 255 'deferredEncrypt': function(aKey, aValue, aNonce) {
256 var deferredResult; 256 var deferredResult;
257 varkey, value; 257 varkey, value;
258 var data; 258 var data;
259 var dataToEncrypt; 259 var dataToEncrypt;
260 var encryptedData; 260 var encryptedData;
261 261
262 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 262 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
263 value = Clipperz.Base.serializeJSON(aValue); 263 value = Clipperz.Base.serializeJSON(aValue);
264 data = new Clipperz.ByteArray(value); 264 data = new Clipperz.ByteArray(value);
265 265
266 deferredResult = new Clipperz.Async.Deferred("Crypto[0.3].deferredEncrypt") 266 deferredResult = new Clipperz.Async.Deferred("Crypto[0.3].deferredEncrypt")
267 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, data, aNonce); 267 deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, data, aNonce);
268 deferredResult.addCallback(function(aResult) { 268 deferredResult.addCallback(function(aResult) {
269 return aResult.toBase64String(); 269 return aResult.toBase64String();
270 }) 270 })
271 deferredResult.callback(); 271 deferredResult.callback();
272 272
273 return deferredResult; 273 return deferredResult;
274 }, 274 },
275 275
276 'decrypt': function(aKey, aValue) { 276 'decrypt': function(aKey, aValue) {
277 var result; 277 var result;
278 278
279 if (aValue != null) { 279 if (aValue != null) {
280 var key, value; 280 var key, value;
281 var decryptedData; 281 var decryptedData;
282 282
283 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 283 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
284 value = new Clipperz.ByteArray().appendBase64String(aValue); 284 value = new Clipperz.ByteArray().appendBase64String(aValue);
285 285
286 decryptedData = Clipperz.Crypto.AES.decrypt(key, value); 286 decryptedData = Clipperz.Crypto.AES.decrypt(key, value);
287 287
288 value = decryptedData.asString(); 288 value = decryptedData.asString();
289 try { 289 try {
290 result = Clipperz.Base.evalJSON(value); 290 result = Clipperz.Base.evalJSON(value);
291 } catch (exception) { 291 } catch (exception) {
292 Clipperz.logError("Error while decrypting data [3]"); 292 Clipperz.logError("Error while decrypting data [3]");
293 throw Clipperz.Crypto.Base.exception.CorruptedMessage; 293 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
294 } 294 }
295 } else { 295 } else {
296 result = null; 296 result = null;
297 } 297 }
298 298
299 return result; 299 return result;
300 }, 300 },
301 301
302 'deferredDecrypt': function(aKey, aValue) { 302 'deferredDecrypt': function(aKey, aValue) {
303 var deferredResult; 303 var deferredResult;
304 304
305 deferredResult = new Clipperz.Async.Deferred("Crypto[0.3].deferredDecrypt", {trace: false}); 305 deferredResult = new Clipperz.Async.Deferred("Crypto[0.3].deferredDecrypt", {trace: false});
306 // now = new Date; 306 // now = new Date;
307 307
308 if (aValue != null) { 308 if (aValue != null) {
309 var key, value; 309 var key, value;
310 // var decryptedData; 310 // var decryptedData;
311 311
312 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 312 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
313 value = new Clipperz.ByteArray().appendBase64String(aValue); 313 value = new Clipperz.ByteArray().appendBase64String(aValue);
314 314
315 deferredResult.addCallback(Clipperz.Crypto.AES.deferredDecrypt, key, value); 315 deferredResult.addCallback(Clipperz.Crypto.AES.deferredDecrypt, key, value);
316 deferredResult.addCallback(MochiKit.Async.wait, 0.1); 316 deferredResult.addCallback(MochiKit.Async.wait, 0.1);
317 deferredResult.addCallback(function(aResult) { 317 deferredResult.addCallback(function(aResult) {
318 return aResult.asString(); 318 return aResult.asString();
319 }); 319 });
320 deferredResult.addCallback(MochiKit.Async.wait, 0.1); 320 deferredResult.addCallback(MochiKit.Async.wait, 0.1);
321 deferredResult.addCallback(Clipperz.Base.evalJSON); 321 deferredResult.addCallback(Clipperz.Base.evalJSON);
322 deferredResult.addErrback(function(anError) { 322 deferredResult.addErrback(function(anError) {
323console.log("PIPPO_1", anError)
323 Clipperz.logError("Error while decrypting data [4]"); 324 Clipperz.logError("Error while decrypting data [4]");
324 throw Clipperz.Crypto.Base.exception.CorruptedMessage; 325 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
325 }) 326 })
326 } else { 327 } else {
327 deferredResult.addCallback(function() { 328 deferredResult.addCallback(function() {
328 return null; 329 return null;
329 }); 330 });
330 } 331 }
331 deferredResult.callback(); 332 deferredResult.callback();
332 333
333 return deferredResult; 334 return deferredResult;
334 }, 335 },
335 336
336 'hash': Clipperz.Crypto.SHA.sha_d256, 337 'hash': Clipperz.Crypto.SHA.sha_d256,
337 338
338 'deriveKey': function(aStringValue) { 339 'deriveKey': function(aStringValue) {
339 varbyteData; 340 varbyteData;
340 var result; 341 var result;
341 342
342 byteData = new Clipperz.ByteArray(aStringValue); 343 byteData = new Clipperz.ByteArray(aStringValue);
343 result = Clipperz.Crypto.SHA.sha_d256(byteData); 344 result = Clipperz.Crypto.SHA.sha_d256(byteData);
344 345
345 return result; 346 return result;
346 } 347 }
347
348 }, 348 },
349 349
350 //##################################################################### 350 //#####################################################################
351/* 351
352 '0.4': { 352 '0.4': {
353 'encrypt': function(aKey, aValue, aNonce) { 353 'encrypt': function(aKey, aValue, aNonce) {
354 var result; 354 var result;
355 varkey, value; 355 varkey, value;
356 var data; 356 var data;
357 var dataToEncrypt; 357 var dataToEncrypt;
358 var encryptedData; 358 var encryptedData;
359 359
360//Clipperz.logDebug(">>> [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt");
361 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 360 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
362//Clipperz.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 1");
363 value = Clipperz.Base.serializeJSON(aValue); 361 value = Clipperz.Base.serializeJSON(aValue);
364//Clipperz.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 2");
365/ *
366//Clipperz.logDebug("--> encrypt.fullSize: " + value.length);
367 value = value.replace(/":{"label":"/g, '":{l:"');
368 value = value.replace(/":{"key":"/g, '":{k:"');
369 value = value.replace(/":{"notes":"/g, '":{n:"');
370 value = value.replace(/":{"record":"/g, '":{r:"');
371 value = value.replace(/", "label":"/g, '",l:"');
372 value = value.replace(/", "favicon":"/g,'",f:"');
373//Clipperz.logDebug("<-- encrypt.compressed: " + value.length);
374* /
375 data = new Clipperz.ByteArray(value); 362 data = new Clipperz.ByteArray(value);
376//Clipperz.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 3"); 363 encryptedData = Clipperz.Crypto.AES_2.encrypt(key, data, aNonce);
377 encryptedData = Clipperz.Crypto.AES.encrypt(key, data, aNonce);
378//Clipperz.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 4");
379 result = encryptedData.toBase64String(); 364 result = encryptedData.toBase64String();
380//Clipperz.logDebug("<<< [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt");
381 365
382 return result; 366 return result;
383 }, 367 },
368
369 'deferredEncrypt': function(aKey, aValue, aNonce) {
370 var deferredResult;
371 varkey, value;
372 var data;
373 var dataToEncrypt;
374 var encryptedData;
375
376 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
377 value = Clipperz.Base.serializeJSON(aValue);
378 data = new Clipperz.ByteArray(value);
379
380 deferredResult = new Clipperz.Async.Deferred("Crypto[0.4].deferredEncrypt")
381 deferredResult.addCallback(Clipperz.Crypto.AES_2.deferredEncrypt, key, data, aNonce);
382 deferredResult.addCallback(function(aResult) {
383 return aResult.toBase64String();
384 })
385 deferredResult.callback();
386
387 return deferredResult;
388 },
384 389
385 'decrypt': function(aKey, aValue) { 390 'decrypt': function(aKey, aValue) {
386 var result; 391 var result;
387 392
388 if (aValue != null) { 393 if (aValue != null) {
389 var key, value; 394 var key, value;
390 var decryptedData; 395 var decryptedData;
391 396
392 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey)); 397 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
393 value = new Clipperz.ByteArray().appendBase64String(aValue); 398 value = new Clipperz.ByteArray().appendBase64String(aValue);
394 399
395 decryptedData = Clipperz.Crypto.AES.decrypt(key, value); 400 decryptedData = Clipperz.Crypto.AES_2.decrypt(key, value);
396 401
397 value = decryptedData.asString(); 402 value = decryptedData.asString();
398/ *
399 value = value.replace(/":{l:"/g,'":{"label":"');
400 value = value.replace(/":{k:"/g,'":{"key":"');
401 value = value.replace(/":{n:"/g,'":{"notes":"');
402 value = value.replace(/":{r:"/g,'":{"record":"');
403 value = value.replace(/",l:"/g, '", "label":"');
404 value = value.replace(/",f:"/g, '", "favicon":"');
405* /
406 try { 403 try {
407 result = Clipperz.Base.evalJSON(value); 404 result = Clipperz.Base.evalJSON(value);
408 } catch (exception) { 405 } catch (exception) {
409 Clipperz.logError("Error while decrypting data"); 406 console.log("PIPPO_2", anError)
407 Clipperz.logError("Error while decrypting data [4]");
410 throw Clipperz.Crypto.Base.exception.CorruptedMessage; 408 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
411 } 409 }
412
413
414 } else { 410 } else {
415 result = null; 411 result = null;
416 } 412 }
417 413
418 return result; 414 return result;
419 }, 415 },
420 416
421 'hash': Clipperz.Crypto.SHA.sha_d256 417 'deferredDecrypt': function(aKey, aValue) {
418 var deferredResult;
419
420 deferredResult = new Clipperz.Async.Deferred("Crypto[0.4].deferredDecrypt", {trace: false});
421
422 if (aValue != null) {
423 var key, value;
424
425 key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
426 value = new Clipperz.ByteArray().appendBase64String(aValue);
427
428 deferredResult.addCallback(Clipperz.Crypto.AES_2.deferredDecrypt, key, value);
429 deferredResult.addCallback(MochiKit.Async.wait, 0.1);
430 deferredResult.addCallback(function(aResult) {
431 return aResult.asString();
432 });
433 deferredResult.addCallback(MochiKit.Async.wait, 0.1);
434 deferredResult.addCallback(Clipperz.Base.evalJSON);
435 deferredResult.addErrback(function(anError) {
436 Clipperz.logError("Error while decrypting data [4]");
437 throw Clipperz.Crypto.Base.exception.CorruptedMessage;
438 })
439 } else {
440 deferredResult.addCallback(function() {
441 return null;
442 });
443 }
444 deferredResult.callback();
445
446 return deferredResult;
447 },
448
449 'hash': Clipperz.Crypto.SHA.sha_d256,
450
451 'deriveKey': function(aStringValue) {
452 varbyteData;
453 var result;
454
455 byteData = new Clipperz.ByteArray(aStringValue);
456 result = Clipperz.Crypto.SHA.sha_d256(byteData);
457
458 return result;
459 }
422 }, 460 },
423*/ 461
424 //##################################################################### 462 //#####################################################################
425 __syntaxFix__: "syntax fix" 463 __syntaxFix__: "syntax fix"
426 } 464 }
427 }, 465 },
428 466
429 //------------------------------------------------------------------------- 467 //-------------------------------------------------------------------------
430 468
431 'encrypt': function(aKey, aValue, aVersion) { 469 'encrypt': function(aKey, aValue, aVersion) {
432 return Clipperz.PM.Crypto.encryptingFunctions.versions[aVersion].encrypt(aKey, aValue); 470 return Clipperz.PM.Crypto.encryptingFunctions.versions[aVersion].encrypt(aKey, aValue);
433 }, 471 },
434 472
435 'deferredEncrypt': function(someParameters) { 473 'deferredEncrypt': function(someParameters) {
436 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters['version']].deferredEncrypt(someParameters['key'], someParameters['value']); 474 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters['version']].deferredEncrypt(someParameters['key'], someParameters['value']);
437 }, 475 },
438 476
439 //......................................................................... 477 //.........................................................................
440 478
441 'decrypt': function(aKey, aValue, aVersion) { 479 'decrypt': function(aKey, aValue, aVersion) {
442 return Clipperz.PM.Crypto.encryptingFunctions.versions[aVersion].decrypt(aKey, aValue); 480 return Clipperz.PM.Crypto.encryptingFunctions.versions[aVersion].decrypt(aKey, aValue);
443 }, 481 },
444 482
445 'deferredDecrypt': function(someParameters) { 483 'deferredDecrypt': function(someParameters) {
446 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters['version']].deferredDecrypt(someParameters['key'], someParameters['value']); 484 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters['version']].deferredDecrypt(someParameters['key'], someParameters['value']);
447 }, 485 },
448 486
449 //------------------------------------------------------------------------- 487 //-------------------------------------------------------------------------
450 488
451 'hash': function(aValue) { 489 'hash': function(aValue) {
452 return Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion]['hash'](aValue); 490 return Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion]['hash'](aValue);
453 }, 491 },
454 492
455 //------------------------------------------------------------------------- 493 //-------------------------------------------------------------------------
456 494
457 'randomKey': function() { 495 'randomKey': function() {
458 return Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); 496 return Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
459 }, 497 },
460 498
461 //------------------------------------------------------------------------- 499 //-------------------------------------------------------------------------
462 500
463 'deriveKey': function(aValue) { 501 'deriveKey': function(aValue) {
464 return Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion].deriveKey(aValue); 502 return Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion].deriveKey(aValue);
465 }, 503 },
466 504
467 //------------------------------------------------------------------------- 505 //-------------------------------------------------------------------------
468 506
469 'passwordEntropy': function(aValue) { 507 'passwordEntropy': function(aValue) {
470 var result; 508 var result;
471 varbitPerChar; 509 varbitPerChar;
472 510
473 bitPerChar = 4; 511 bitPerChar = 4;
474 if (/[a-z]/.test(aValue)) { 512 if (/[a-z]/.test(aValue)) {
475 bitPerChar ++; 513 bitPerChar ++;
476 } 514 }
477 if (/[A-Z]/.test(aValue)) { 515 if (/[A-Z]/.test(aValue)) {
478 bitPerChar ++; 516 bitPerChar ++;
479 } 517 }
480 if (/[^a-zA-Z0-9]/.test(aValue)) { 518 if (/[^a-zA-Z0-9]/.test(aValue)) {
481 bitPerChar ++; 519 bitPerChar ++;
482 } 520 }
483 521
484 result = aValue.length * bitPerChar; 522 result = aValue.length * bitPerChar;
485 523
486 return result; 524 return result;
487 }, 525 },
488 526
489 //------------------------------------------------------------------------- 527 //-------------------------------------------------------------------------
490 528
491 'nullValue': '####', 529 'nullValue': '####',
492 530
493 //------------------------------------------------------------------------- 531 //-------------------------------------------------------------------------
494 __syntaxFix__: "syntax fix" 532 __syntaxFix__: "syntax fix"
495 533
496}); 534});
497 535
498//***************************************************************************** 536//*****************************************************************************
499 537
500//MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, { 538//MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, {
501 //'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion] 539 //'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion]
502//}); 540//});
503 541
504MochiKit.Base.update(Clipperz.PM.Crypto.encryptingFunctions.versions, { 542MochiKit.Base.update(Clipperz.PM.Crypto.encryptingFunctions.versions, {
505 'current': Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion] 543 'current': Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion]
506}); 544});
507 545
508//***************************************************************************** 546//*****************************************************************************
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.js
index fd18faf..b94fe4c 100644
--- a/frontend/gamma/js/Clipperz/PM/DataModel/User.js
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.js
@@ -633,178 +633,178 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
633 'hasPendingChanges': function () { 633 'hasPendingChanges': function () {
634 vardeferredResult; 634 vardeferredResult;
635 635
636 deferredResult = new Clipperz.Async.Deferred("User.hasPendingChanges", {trace:false}); 636 deferredResult = new Clipperz.Async.Deferred("User.hasPendingChanges", {trace:false});
637 deferredResult.collectResults({ 637 deferredResult.collectResults({
638 'header': [ 638 'header': [
639 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasPendingChanges'), 639 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasPendingChanges'),
640 MochiKit.Base.values 640 MochiKit.Base.values
641 ], 641 ],
642 'records': MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasPendingChanges') 642 'records': MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasPendingChanges')
643 }); 643 });
644 deferredResult.addCallback(Clipperz.Async.or); 644 deferredResult.addCallback(Clipperz.Async.or);
645 deferredResult.callback(); 645 deferredResult.callback();
646 // recordsIndex = legacyHeader; 646 // recordsIndex = legacyHeader;
647 // preferences = legacyHeader; 647 // preferences = legacyHeader;
648 // oneTimePasswords= legacyHeader; 648 // oneTimePasswords= legacyHeader;
649 649
650 return deferredResult; 650 return deferredResult;
651 }, 651 },
652 652
653 //========================================================================= 653 //=========================================================================
654 654
655 'commitTransientState': function () { 655 'commitTransientState': function () {
656 return Clipperz.Async.callbacks("User.commitTransientState", [ 656 return Clipperz.Async.callbacks("User.commitTransientState", [
657 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'commitTransientState'), 657 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'commitTransientState'),
658 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'commitTransientState'), 658 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'commitTransientState'),
659 659
660 MochiKit.Base.method(this, 'transientState'), 660 MochiKit.Base.method(this, 'transientState'),
661 // MochiKit.Base.itemgetter('lock'), 661 // MochiKit.Base.itemgetter('lock'),
662 // MochiKit.Base.method(this, 'setServerLockValue'), 662 // MochiKit.Base.method(this, 'setServerLockValue'),
663 MochiKit.Base.method(this, 'resetTransientState', true) 663 MochiKit.Base.method(this, 'resetTransientState', true)
664 ], {trace:false}); 664 ], {trace:false});
665 }, 665 },
666 666
667 //------------------------------------------------------------------------- 667 //-------------------------------------------------------------------------
668 668
669 'revertChanges': function () { 669 'revertChanges': function () {
670 return Clipperz.Async.callbacks("User.revertChanges", [ 670 return Clipperz.Async.callbacks("User.revertChanges", [
671 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'revertChanges'), 671 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'revertChanges'),
672 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'revertChanges'), 672 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'revertChanges'),
673 MochiKit.Base.method(this, 'resetTransientState', false) 673 MochiKit.Base.method(this, 'resetTransientState', false)
674 ], {trace:false}); 674 ], {trace:false});
675 }, 675 },
676 676
677 //========================================================================= 677 //=========================================================================
678 678
679 'deleteAllCleanTextData': function () { 679 'deleteAllCleanTextData': function () {
680 return Clipperz.Async.callbacks("User.deleteAllCleanTextData", [ 680 return Clipperz.Async.callbacks("User.deleteAllCleanTextData", [
681 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'deleteAllCleanTextData'), 681 MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'deleteAllCleanTextData'),
682 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'deleteAllCleanTextData'), 682 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'deleteAllCleanTextData'),
683 683
684 MochiKit.Base.method(this.data(), 'removeAllData'), 684 MochiKit.Base.method(this.data(), 'removeAllData'),
685 MochiKit.Base.method(this, 'resetTransientState', false) 685 MochiKit.Base.method(this, 'resetTransientState', false)
686 ], {trace:false}); 686 ], {trace:false});
687 }, 687 },
688 688
689 //------------------------------------------------------------------------- 689 //-------------------------------------------------------------------------
690 690
691 'hasAnyCleanTextData': function () { 691 'hasAnyCleanTextData': function () {
692 vardeferredResult; 692 vardeferredResult;
693 693
694 deferredResult = new Clipperz.Async.Deferred("User.hasAnyCleanTextData", {trace:false}); 694 deferredResult = new Clipperz.Async.Deferred("User.hasAnyCleanTextData", {trace:false});
695 deferredResult.collectResults({ 695 deferredResult.collectResults({
696 'header':[ 696 'header':[
697 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasAnyCleanTextData'), 697 MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasAnyCleanTextData'),
698 MochiKit.Base.values 698 MochiKit.Base.values
699 ], 699 ],
700 'records':MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasAnyCleanTextData'), 700 'records':MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasAnyCleanTextData'),
701 'data': MochiKit.Base.bind(function () { 701 'data': MochiKit.Base.bind(function () {
702 return MochiKit.Async.succeed(! this.data().isEmpty()); 702 return MochiKit.Async.succeed(! this.data().isEmpty());
703 }, this), 703 }, this),
704 'transientState':MochiKit.Base.bind(function () { 704 'transientState':MochiKit.Base.bind(function () {
705 return MochiKit.Async.succeed(MochiKit.Base.keys(this.transientState()).length != 0); 705 return MochiKit.Async.succeed(MochiKit.Base.keys(this.transientState()).length != 0);
706 }, this) 706 }, this)
707 }); 707 });
708 deferredResult.addCallback(Clipperz.Async.or); 708 deferredResult.addCallback(Clipperz.Async.or);
709 deferredResult.callback(); 709 deferredResult.callback();
710 710
711 return deferredResult; 711 return deferredResult;
712 }, 712 },
713 713
714 //========================================================================= 714 //=========================================================================
715 715
716 'prepareRemoteDataWithKey': function (aKey /*, aCurrentKey*/) { 716 'prepareRemoteDataWithKey': function (aKey /*, aCurrentKey*/) {
717 var deferredResult; 717 var deferredResult;
718 varresult; 718 varresult;
719 719
720 result = {}; 720 result = {};
721 deferredResult = new Clipperz.Async.Deferred("User.prepareRemoteDataWithKey", {trace:false}); 721 deferredResult = new Clipperz.Async.Deferred("User.prepareRemoteDataWithKey", {trace:false});
722 deferredResult.addMethod(this, 'invokeMethodNamedOnHeader', 'prepareRemoteDataWithKey', aKey /*, aCurrentKey*/); 722 deferredResult.addMethod(this, 'invokeMethodNamedOnHeader', 'prepareRemoteDataWithKey', aKey /*, aCurrentKey*/);
723 deferredResult.addCallback(MochiKit.Base.bind(function (aResult, someHeaderPackedData) { 723 deferredResult.addCallback(MochiKit.Base.bind(function (aResult, someHeaderPackedData) {
724 var header; 724 var header;
725 725
726 header = {}; 726 header = {};
727 header['records'] = someHeaderPackedData['recordIndex']['records']; 727 header['records'] = someHeaderPackedData['recordIndex']['records'];
728 header['directLogins'] = someHeaderPackedData['recordIndex']['directLogins']; 728 header['directLogins'] = someHeaderPackedData['recordIndex']['directLogins'];
729 header['preferences'] = {'data': someHeaderPackedData['preferences']['data']}; // this._serverData['header']['preferences']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['preferences']; //??????????? 729 header['preferences'] = {'data': someHeaderPackedData['preferences']['data']};
730 header['oneTimePasswords'] = {'data': someHeaderPackedData['oneTimePasswords']['data']}; // this._serverData['header']['oneTimePasswords']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['oneTimePasswords']; //??????????? 730 header['oneTimePasswords']= {'data': someHeaderPackedData['oneTimePasswords']['data']};
731 header['version'] = '0.1'; 731 header['version'] = '0.1';
732 732
733 aResult['header'] = Clipperz.Base.serializeJSON(header); 733 aResult['header'] = Clipperz.Base.serializeJSON(header);
734 aResult['statistics'] = this._serverData['statistics']; //"someHeaderPackedData['statistics']['data']"; 734 aResult['statistics'] = this._serverData['statistics']; //"someHeaderPackedData['statistics']['data']";
735 735
736 return aResult; 736 return aResult;
737 }, this), result); 737 }, this), result);
738 deferredResult.addCallback(Clipperz.Async.setItem, result, 'version', Clipperz.PM.Crypto.encryptingFunctions.currentVersion); 738 deferredResult.addCallback(Clipperz.Async.setItem, result, 'version', Clipperz.PM.Crypto.encryptingFunctions.currentVersion);
739 // deferredResult.addCallback(Clipperz.Async.setItem, result, 'lock', this.serverLockValue()); 739 // deferredResult.addCallback(Clipperz.Async.setItem, result, 'lock', this.serverLockValue());
740 deferredResult.callback(); 740 deferredResult.callback();
741 741
742 return deferredResult; 742 return deferredResult;
743 }, 743 },
744 744
745 //========================================================================= 745 //=========================================================================
746 746
747 'saveChanges': function () { 747 'saveChanges': function () {
748 vardeferredResult; 748 vardeferredResult;
749 var messageParameters; 749 var messageParameters;
750 750
751 messageParameters = {}; 751 messageParameters = {};
752 752
753 deferredResult = new Clipperz.Async.Deferred("User.saveChangaes", {trace:false}); 753 deferredResult = new Clipperz.Async.Deferred("User.saveChangaes", {trace:false});
754 754
755 deferredResult.addMethod(this, 'getHeaderIndex', 'recordsIndex'); 755 deferredResult.addMethod(this, 'getHeaderIndex', 'recordsIndex');
756 deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords')); 756 deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords'));
757 deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'records'); 757 deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'records');
758 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 758 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
759 759
760 deferredResult.addMethod(this, 'getPassphrase'); 760 deferredResult.addMethod(this, 'getPassphrase');
761 deferredResult.addMethod(this, 'prepareRemoteDataWithKey'); 761 deferredResult.addMethod(this, 'prepareRemoteDataWithKey');
762 deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'user'); 762 deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'user');
763 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 763 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
764 764
765 deferredResult.addCallback(MochiKit.Async.succeed, messageParameters); 765 deferredResult.addCallback(MochiKit.Async.succeed, messageParameters);
766 deferredResult.addMethod(this.connection(), 'message', 'saveChanges'); 766 deferredResult.addMethod(this.connection(), 'message', 'saveChanges');
767 deferredResult.addCallback(MochiKit.Base.update, this.transientState()) 767 deferredResult.addCallback(MochiKit.Base.update, this.transientState())
768 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 768 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
769 769
770 deferredResult.addMethod(this, 'commitTransientState'); 770 deferredResult.addMethod(this, 'commitTransientState');
771 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 771 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
772 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userDataSuccessfullySaved'); 772 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userDataSuccessfullySaved');
773 773
774 deferredResult.addErrbackPass(MochiKit.Base.method(this, 'revertChanges')); 774 deferredResult.addErrbackPass(MochiKit.Base.method(this, 'revertChanges'));
775 deferredResult.addErrbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'failureWhileSavingUserData'); 775 deferredResult.addErrbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'failureWhileSavingUserData');
776 776
777 deferredResult.callback(); 777 deferredResult.callback();
778 778
779 return deferredResult; 779 return deferredResult;
780 }, 780 },
781 781
782 //========================================================================= 782 //=========================================================================
783 __syntaxFix__: "syntax fix" 783 __syntaxFix__: "syntax fix"
784}); 784});
785 785
786//----------------------------------------------------------------------------- 786//-----------------------------------------------------------------------------
787 787
788Clipperz.PM.DataModel.User.registerNewAccount = function (anUsername, aPassphraseFunction) { 788Clipperz.PM.DataModel.User.registerNewAccount = function (anUsername, aPassphraseFunction) {
789 vardeferredResult; 789 vardeferredResult;
790 var user; 790 var user;
791 791
792 user = new Clipperz.PM.DataModel.User({'username':anUsername, 'getPassphraseFunction':aPassphraseFunction}); 792 user = new Clipperz.PM.DataModel.User({'username':anUsername, 'getPassphraseFunction':aPassphraseFunction});
793 793
794 deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.User.registerNewAccount", {trace:false}); 794 deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.User.registerNewAccount", {trace:false});
795 deferredResult.addMethod(user, 'registerAsNewAccount'); 795 deferredResult.addMethod(user, 'registerAsNewAccount');
796 deferredResult.addMethod(user, 'login'); 796 deferredResult.addMethod(user, 'login');
797 deferredResult.addCallback(MochiKit.Async.succeed, user); 797 deferredResult.addCallback(MochiKit.Async.succeed, user);
798 deferredResult.callback(); 798 deferredResult.callback();
799 799
800 return deferredResult; 800 return deferredResult;
801} 801}
802 802
803//----------------------------------------------------------------------------- 803//-----------------------------------------------------------------------------
804 804
805Clipperz.PM.DataModel.User.exception = { 805Clipperz.PM.DataModel.User.exception = {
806 LoginFailed: new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.LoginFailed"), 806 LoginFailed: new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.LoginFailed"),
807 CredentialUpgradeFailed:new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed") 807 CredentialUpgradeFailed:new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed")
808}; 808};
809 809
810//----------------------------------------------------------------------------- 810//-----------------------------------------------------------------------------
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
index 326022c..b806cb7 100644
--- a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
+++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
@@ -188,193 +188,193 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
188 this._currentStaticConnection = {}; 188 this._currentStaticConnection = {};
189 } 189 }
190 190
191 return this._currentStaticConnection; 191 return this._currentStaticConnection;
192 }, 192 },
193 193
194 //------------------------------------------------------------------------- 194 //-------------------------------------------------------------------------
195 195
196 'getConnectionForRequest': function (aFunctionName, someParameters) { 196 'getConnectionForRequest': function (aFunctionName, someParameters) {
197 varresult; 197 varresult;
198 198
199 if (this.shouldPayTolls()) { 199 if (this.shouldPayTolls()) {
200 if ((typeof(someParameters['toll']) != 'undefined') && (typeof(someParameters['toll']['targetValue']) != 'undefined')) { 200 if ((typeof(someParameters['toll']) != 'undefined') && (typeof(someParameters['toll']['targetValue']) != 'undefined')) {
201 result = this.tolls()[someParameters['toll']['targetValue']]['connection']; 201 result = this.tolls()[someParameters['toll']['targetValue']]['connection'];
202 if (typeof(result) == 'undefined') { 202 if (typeof(result) == 'undefined') {
203 result = {}; 203 result = {};
204 } 204 }
205 } else { 205 } else {
206 result = {}; 206 result = {};
207 } 207 }
208 } else { 208 } else {
209 result = this.currentStaticConnection(); 209 result = this.currentStaticConnection();
210 } 210 }
211 211
212 return result; 212 return result;
213 }, 213 },
214 214
215 //------------------------------------------------------------------------- 215 //-------------------------------------------------------------------------
216 216
217 'storeConnectionForRequestWithConnectionAndResponse': function (aFunctionName, someParameters, aConnection, aResponse) { 217 'storeConnectionForRequestWithConnectionAndResponse': function (aFunctionName, someParameters, aConnection, aResponse) {
218 if (this.shouldPayTolls()) { 218 if (this.shouldPayTolls()) {
219 if ((typeof(aResponse['toll']) != 'undefined') 219 if ((typeof(aResponse['toll']) != 'undefined')
220 &&(typeof(aResponse['toll']['targetValue']) != 'undefined') 220 &&(typeof(aResponse['toll']['targetValue']) != 'undefined')
221 &&(typeof(this.tolls()[aResponse['toll']['targetValue']]) != 'undefined') 221 &&(typeof(this.tolls()[aResponse['toll']['targetValue']]) != 'undefined')
222 ) { 222 ) {
223 this.tolls()[aResponse['toll']['targetValue']]['connection'] = aConnection; 223 this.tolls()[aResponse['toll']['targetValue']]['connection'] = aConnection;
224 } 224 }
225 } 225 }
226 }, 226 },
227 227
228 //========================================================================= 228 //=========================================================================
229 229
230 'processMessage': function (aFunctionName, someParameters) { 230 'processMessage': function (aFunctionName, someParameters) {
231 var result; 231 var result;
232 varconnection; 232 varconnection;
233 233
234 connection = this.getConnectionForRequest(aFunctionName, someParameters); 234 connection = this.getConnectionForRequest(aFunctionName, someParameters);
235 235
236 switch(aFunctionName) { 236 switch(aFunctionName) {
237 case 'knock': 237 case 'knock':
238 result = this._knock(connection, someParameters); 238 result = this._knock(connection, someParameters);
239 break; 239 break;
240 case 'registration': 240 case 'registration':
241 this.checkToll(aFunctionName, someParameters); 241 this.checkToll(aFunctionName, someParameters);
242 result = this._registration(connection, someParameters.parameters); 242 result = this._registration(connection, someParameters.parameters);
243 break; 243 break;
244 case 'handshake': 244 case 'handshake':
245 this.checkToll(aFunctionName, someParameters); 245 this.checkToll(aFunctionName, someParameters);
246 result = this._handshake(connection, someParameters.parameters); 246 result = this._handshake(connection, someParameters.parameters);
247 break; 247 break;
248 case 'message': 248 case 'message':
249 this.checkToll(aFunctionName, someParameters); 249 this.checkToll(aFunctionName, someParameters);
250 result = this._message(connection, someParameters.parameters); 250 result = this._message(connection, someParameters.parameters);
251 break; 251 break;
252 case 'logout': 252 case 'logout':
253 this._currentStaticConnection = null; 253 this._currentStaticConnection = null;
254 result = this._logout(connection, someParameters.parameters); 254 result = this._logout(connection, someParameters.parameters);
255 break; 255 break;
256 } 256 }
257 257
258 this.storeConnectionForRequestWithConnectionAndResponse(aFunctionName, someParameters, connection, result); 258 this.storeConnectionForRequestWithConnectionAndResponse(aFunctionName, someParameters, connection, result);
259 259
260 return MochiKit.Async.succeed(result); 260 return MochiKit.Async.succeed(result);
261 }, 261 },
262 262
263 //========================================================================= 263 //=========================================================================
264 264
265 '_knock': function(aConnection, someParameters) { 265 '_knock': function(aConnection, someParameters) {
266 var result; 266 var result;
267 267
268 result = { 268 result = {
269 toll: this.getTollForRequestType(someParameters['requestType']) 269 toll: this.getTollForRequestType(someParameters['requestType'])
270 } 270 }
271 271
272 return result; 272 return result;
273 }, 273 },
274 274
275 //------------------------------------------------------------------------- 275 //-------------------------------------------------------------------------
276 276
277 '_registration': function(aConnection, someParameters) { 277 '_registration': function(aConnection, someParameters) {
278 if (this.isReadOnly() == false) { 278 if (this.isReadOnly() == false) {
279 if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') { 279 if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') {
280 this.data()['users'][someParameters['credentials']['C']] = { 280 this.data()['users'][someParameters['credentials']['C']] = {
281 's': someParameters['credentials']['s'], 281 's': someParameters['credentials']['s'],
282 'v': someParameters['credentials']['v'], 282 'v': someParameters['credentials']['v'],
283 'version':someParameters['credentials']['version'], 283 'version':someParameters['credentials']['version'],
284 'lock': Clipperz.Crypto.Base.generateRandomSeed(), 284 // 'lock': Clipperz.Crypto.Base.generateRandomSeed(),
285 'userDetails': someParameters['user']['header'], 285 'userDetails': someParameters['user']['header'],
286 'statistics': someParameters['user']['statistics'], 286 'statistics': someParameters['user']['statistics'],
287 'userDetailsVersion':someParameters['user']['version'], 287 'userDetailsVersion':someParameters['user']['version'],
288 'records':{} 288 'records':{}
289 } 289 }
290 } else { 290 } else {
291 throw "user already exists"; 291 throw "user already exists";
292 } 292 }
293 } else { 293 } else {
294 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 294 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
295 } 295 }
296 296
297 result = { 297 result = {
298 result: { 298 result: {
299 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'], 299 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'],
300 'result':'done' 300 'result':'done'
301 }, 301 },
302 toll: this.getTollForRequestType('CONNECT') 302 toll: this.getTollForRequestType('CONNECT')
303 } 303 }
304 304
305 return result; 305 return result;
306 }, 306 },
307 307
308 //------------------------------------------------------------------------- 308 //-------------------------------------------------------------------------
309 309
310 '_handshake': function(aConnection, someParameters) { 310 '_handshake': function(aConnection, someParameters) {
311 var result; 311 var result;
312 varnextTollRequestType; 312 varnextTollRequestType;
313 313
314 result = {}; 314 result = {};
315 if (someParameters.message == "connect") { 315 if (someParameters.message == "connect") {
316 var userData; 316 var userData;
317 var randomBytes; 317 var randomBytes;
318 var v; 318 var v;
319 319
320 userData = this.data()['users'][someParameters.parameters.C]; 320 userData = this.data()['users'][someParameters.parameters.C];
321 321
322 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) { 322 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) {
323 aConnection['userData'] = userData; 323 aConnection['userData'] = userData;
324 aConnection['C'] = someParameters.parameters.C; 324 aConnection['C'] = someParameters.parameters.C;
325 } else { 325 } else {
326 aConnection['userData'] = this.data()['users']['catchAllUser']; 326 aConnection['userData'] = this.data()['users']['catchAllUser'];
327 } 327 }
328 328
329 randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); 329 randomBytes = Clipperz.Crypto.Base.generateRandomSeed();
330 aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16); 330 aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16);
331 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); 331 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
332 aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); 332 aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()));
333 333
334 aConnection['A'] = someParameters.parameters.A; 334 aConnection['A'] = someParameters.parameters.A;
335 335
336 result['s'] = aConnection['userData']['s']; 336 result['s'] = aConnection['userData']['s'];
337 result['B'] = aConnection['B'].asString(16); 337 result['B'] = aConnection['B'].asString(16);
338 338
339 nextTollRequestType = 'CONNECT'; 339 nextTollRequestType = 'CONNECT';
340 } else if (someParameters.message == "credentialCheck") { 340 } else if (someParameters.message == "credentialCheck") {
341 var v, u, S, A, K, M1; 341 var v, u, S, A, K, M1;
342 342
343 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); 343 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
344 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16); 344 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16);
345 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16); 345 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16);
346 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); 346 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n());
347 347
348 K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2); 348 K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2);
349 349
350 M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2); 350 M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2);
351 if (someParameters.parameters.M1 == M1) { 351 if (someParameters.parameters.M1 == M1) {
352 var M2; 352 var M2;
353 353
354 M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2); 354 M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2);
355 result['M2'] = M2; 355 result['M2'] = M2;
356 } else { 356 } else {
357 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); 357 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
358 } 358 }
359 359
360 nextTollRequestType = 'MESSAGE'; 360 nextTollRequestType = 'MESSAGE';
361 } else if (someParameters.message == "oneTimePassword") { 361 } else if (someParameters.message == "oneTimePassword") {
362 var otpData; 362 var otpData;
363 363
364 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; 364 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey];
365 365
366 try { 366 try {
367 if (typeof(otpData) != 'undefined') { 367 if (typeof(otpData) != 'undefined') {
368 if (otpData['status'] == 'ACTIVE') { 368 if (otpData['status'] == 'ACTIVE') {
369 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { 369 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) {
370 result = { 370 result = {
371 'data': otpData['data'], 371 'data': otpData['data'],
372 'version':otpData['version'] 372 'version':otpData['version']
373 } 373 }
374 374
375 otpData['status'] = 'REQUESTED'; 375 otpData['status'] = 'REQUESTED';
376 } else { 376 } else {
377 otpData['status'] = 'DISABLED'; 377 otpData['status'] = 'DISABLED';
378 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; 378 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum";
379 } 379 }
380 } else { 380 } else {
@@ -476,193 +476,193 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
476 //===================================================================== 476 //=====================================================================
477 // 477 //
478 // R E A D - W R I T E M e t h o d s 478 // R E A D - W R I T E M e t h o d s
479 // 479 //
480 //===================================================================== 480 //=====================================================================
481 } else if (someParameters.message == 'upgradeUserCredentials') { 481 } else if (someParameters.message == 'upgradeUserCredentials') {
482 if (this.isReadOnly() == false) { 482 if (this.isReadOnly() == false) {
483 var parameters; 483 var parameters;
484 var credentials; 484 var credentials;
485 485
486 parameters = someParameters['parameters']; 486 parameters = someParameters['parameters'];
487 credentials = parameters['credentials']; 487 credentials = parameters['credentials'];
488 488
489 if ((credentials['C'] == null) 489 if ((credentials['C'] == null)
490 ||(credentials['s'] == null) 490 ||(credentials['s'] == null)
491 ||(credentials['v'] == null) 491 ||(credentials['v'] == null)
492 ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) 492 ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion)
493 ) { 493 ) {
494 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; 494 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed;
495 } else { 495 } else {
496 varoldCValue; 496 varoldCValue;
497 oldCValue = aConnection['C']; 497 oldCValue = aConnection['C'];
498 498
499 this.data()['users'][credentials['C']] = aConnection['userData']; 499 this.data()['users'][credentials['C']] = aConnection['userData'];
500 aConnection['C'] = credentials['C']; 500 aConnection['C'] = credentials['C'];
501 501
502 aConnection['userData']['s'] = credentials['s']; 502 aConnection['userData']['s'] = credentials['s'];
503 aConnection['userData']['v'] = credentials['v']; 503 aConnection['userData']['v'] = credentials['v'];
504 aConnection['userData']['version'] = credentials['version']; 504 aConnection['userData']['version'] = credentials['version'];
505 505
506 aConnection['userData']['userDetails'] = parameters['user']['header']; 506 aConnection['userData']['userDetails'] = parameters['user']['header'];
507 aConnection['userData']['userDetailsVersion'] = parameters['user']['version']; 507 aConnection['userData']['userDetailsVersion'] = parameters['user']['version'];
508 aConnection['userData']['statistics'] = parameters['user']['statistics']; 508 aConnection['userData']['statistics'] = parameters['user']['statistics'];
509 509
510 aConnection['userData']['lock'] = parameters['user']['lock']; 510 aConnection['userData']['lock'] = parameters['user']['lock'];
511 511
512 delete this.data()['users'][oldCValue]; 512 delete this.data()['users'][oldCValue];
513 513
514 result = {result:"done", parameters:parameters}; 514 result = {result:"done", parameters:parameters};
515 } 515 }
516 } else { 516 } else {
517 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 517 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
518 } 518 }
519 //===================================================================== 519 //=====================================================================
520 /* } else if (someParameters.message == 'updateData') { 520 /* } else if (someParameters.message == 'updateData') {
521 if (this.isReadOnly() == false) { 521 if (this.isReadOnly() == false) {
522 var i, c; 522 var i, c;
523 523
524 if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { 524 if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) {
525 throw "the lock attribute is not processed correctly" 525 throw "the lock attribute is not processed correctly"
526 } 526 }
527 527
528 this.userData()['userDetails'] = someParameters['parameters']['user']['header']; 528 this.userData()['userDetails'] = someParameters['parameters']['user']['header'];
529 this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; 529 this.userData()['statistics'] = someParameters['parameters']['user']['statistics'];
530 this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; 530 this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version'];
531 531
532 c = someParameters['parameters']['records'].length; 532 c = someParameters['parameters']['records'].length;
533 for (i=0; i<c; i++) { 533 for (i=0; i<c; i++) {
534 var currentRecord; 534 var currentRecord;
535 var currentRecordData; 535 var currentRecordData;
536 536
537 currentRecordData = someParameters['parameters']['records'][i]; 537 currentRecordData = someParameters['parameters']['records'][i];
538 currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; 538 currentRecord = this.userData()['records'][currentRecordData['record']['reference']];
539 539
540 if (currentRecord == null) { 540 if (currentRecord == null) {
541 } 541 }
542 542
543 currentRecord['data'] = currentRecordData['record']['data']; 543 currentRecord['data'] = currentRecordData['record']['data'];
544 currentRecord['version'] = currentRecordData['record']['version']; 544 currentRecord['version'] = currentRecordData['record']['version'];
545 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; 545 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference'];
546 546
547 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { 547 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = {
548 'data': currentRecordData['currentRecordVersion']['data'], 548 'data': currentRecordData['currentRecordVersion']['data'],
549 'version': currentRecordData['currentRecordVersion']['version'], 549 'version': currentRecordData['currentRecordVersion']['version'],
550 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], 550 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'],
551 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'] 551 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey']
552 } 552 }
553 } 553 }
554 554
555 this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); 555 this.userData()['lock'] = Clipperz.PM.Crypto.randomKey();
556 result['lock'] = this.userData()['lock']; 556 result['lock'] = this.userData()['lock'];
557 result['result'] = 'done'; 557 result['result'] = 'done';
558 } else { 558 } else {
559 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 559 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
560 } 560 }
561 */ //===================================================================== 561 */ //=====================================================================
562 } else if (someParameters.message == 'saveChanges') { 562 } else if (someParameters.message == 'saveChanges') {
563 if (this.isReadOnly() == false) { 563 if (this.isReadOnly() == false) {
564 var i, c; 564 var i, c;
565 565
566 if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) { 566 if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) {
567 throw "the lock attribute is not processed correctly" 567 throw "the lock attribute is not processed correctly"
568 } 568 }
569 569
570 aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header']; 570 aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header'];
571 aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics']; 571 aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics'];
572 aConnection['userData']['userDetailsVersions']= someParameters['parameters']['user']['version']; 572 aConnection['userData']['userDetailsVersion']= someParameters['parameters']['user']['version'];
573 573
574 c = someParameters['parameters']['records']['updated'].length; 574 c = someParameters['parameters']['records']['updated'].length;
575 for (i=0; i<c; i++) { 575 for (i=0; i<c; i++) {
576 var currentRecord; 576 var currentRecord;
577 var currentRecordData; 577 var currentRecordData;
578 578
579 currentRecordData = someParameters['parameters']['records']['updated'][i]; 579 currentRecordData = someParameters['parameters']['records']['updated'][i];
580 currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']]; 580 currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']];
581 581
582 if ( 582 if (
583 (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined') 583 (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined')
584 && 584 &&
585 (typeof(currentRecordData['currentRecordVersion']) == 'undefined') 585 (typeof(currentRecordData['currentRecordVersion']) == 'undefined')
586 ) { 586 ) {
587 throw "Record added without a recordVersion"; 587 throw "Record added without a recordVersion";
588 } 588 }
589 589
590 if (currentRecord == null) { 590 if (currentRecord == null) {
591 currentRecord = {}; 591 currentRecord = {};
592 currentRecord['versions'] = {}; 592 currentRecord['versions'] = {};
593 currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); 593 currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
594 currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); 594 currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
595 595
596 aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord; 596 aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord;
597 } 597 }
598 598
599 currentRecord['data'] = currentRecordData['record']['data']; 599 currentRecord['data'] = currentRecordData['record']['data'];
600 currentRecord['version']= currentRecordData['record']['version']; 600 currentRecord['version']= currentRecordData['record']['version'];
601 currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); 601 currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
602 602
603 if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') { 603 if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') {
604 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; 604 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference'];
605 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { 605 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = {
606 'data': currentRecordData['currentRecordVersion']['data'], 606 'data': currentRecordData['currentRecordVersion']['data'],
607 'version': currentRecordData['currentRecordVersion']['version'], 607 'version': currentRecordData['currentRecordVersion']['version'],
608 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], 608 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'],
609 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'], 609 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'],
610 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), 610 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
611 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), 611 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
612 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()) 612 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date())
613 } 613 }
614 } 614 }
615 } 615 }
616 616
617 c = someParameters['parameters']['records']['deleted'].length; 617 c = someParameters['parameters']['records']['deleted'].length;
618 for (i=0; i<c; i++) { 618 for (i=0; i<c; i++) {
619 var currentRecordReference; 619 var currentRecordReference;
620 620
621 currentRecordReference = someParameters['parameters']['records']['deleted'][i]; 621 currentRecordReference = someParameters['parameters']['records']['deleted'][i];
622 delete aConnection['userData']['records'][currentRecordReference]; 622 delete aConnection['userData']['records'][currentRecordReference];
623 } 623 }
624 624
625 aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey(); 625 aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey();
626 result['lock'] = aConnection['userData']['lock']; 626 result['lock'] = aConnection['userData']['lock'];
627 result['result'] = 'done'; 627 result['result'] = 'done';
628 } else { 628 } else {
629 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 629 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
630 } 630 }
631 631
632 //===================================================================== 632 //=====================================================================
633 // 633 //
634 // U N H A N D L E D M e t h o d 634 // U N H A N D L E D M e t h o d
635 // 635 //
636 //===================================================================== 636 //=====================================================================
637 } else { 637 } else {
638 Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message); 638 Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message);
639 } 639 }
640 640
641 result = { 641 result = {
642 result: result, 642 result: result,
643 toll: this.getTollForRequestType('MESSAGE') 643 toll: this.getTollForRequestType('MESSAGE')
644 } 644 }
645 645
646 // return MochiKit.Async.succeed(result); 646 // return MochiKit.Async.succeed(result);
647 return result; 647 return result;
648 }, 648 },
649 649
650 //------------------------------------------------------------------------- 650 //-------------------------------------------------------------------------
651 651
652 '_logout': function(someParameters) { 652 '_logout': function(someParameters) {
653 // return MochiKit.Async.succeed({result: 'done'}); 653 // return MochiKit.Async.succeed({result: 'done'});
654 return {result: 'done'}; 654 return {result: 'done'};
655 }, 655 },
656 656
657 //========================================================================= 657 //=========================================================================
658 //######################################################################### 658 //#########################################################################
659 659
660 'isTestData': function(aConnection) { 660 'isTestData': function(aConnection) {
661 return (typeof(aConnection['userData']['__masterkey_test_value__']) != 'undefined'); 661 return (typeof(aConnection['userData']['__masterkey_test_value__']) != 'undefined');
662 }, 662 },
663 663
664 'userDetails': function(aConnection) { 664 'userDetails': function(aConnection) {
665 var result; 665 var result;
666 666
667 if (this.isTestData(aConnection)) { 667 if (this.isTestData(aConnection)) {
668 var serializedHeader; 668 var serializedHeader;
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js
index d459726..1a860c5 100644
--- a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js
+++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js
@@ -50,107 +50,112 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Test, Clipperz.PM.Proxy.Offline, {
50 //========================================================================= 50 //=========================================================================
51 51
52 'expectedRequests': function () { 52 'expectedRequests': function () {
53 return this._expectedRequests; 53 return this._expectedRequests;
54 }, 54 },
55 55
56 //------------------------------------------------------------------------- 56 //-------------------------------------------------------------------------
57 57
58 'shouldCheckExpectedRequests': function () { 58 'shouldCheckExpectedRequests': function () {
59 return (this._expectedRequests != null); 59 return (this._expectedRequests != null);
60 }, 60 },
61 61
62 'setShouldCheckExpectedRequests': function(aValue) { 62 'setShouldCheckExpectedRequests': function(aValue) {
63 if (aValue) { 63 if (aValue) {
64 this._expectedRequests = aValue; 64 this._expectedRequests = aValue;
65 } else { 65 } else {
66 this._expectedRequests = null; 66 this._expectedRequests = null;
67 } 67 }
68 }, 68 },
69 69
70 //------------------------------------------------------------------------- 70 //-------------------------------------------------------------------------
71 71
72 'shouldNotReceiveAnyFurtherRequest': function () { 72 'shouldNotReceiveAnyFurtherRequest': function () {
73 this._isExpectingRequests = false; 73 this._isExpectingRequests = false;
74 }, 74 },
75 75
76 'mayReceiveMoreRequests': function () { 76 'mayReceiveMoreRequests': function () {
77 this._isExpectingRequests = true; 77 this._isExpectingRequests = true;
78 this.resetUnexpectedRequests(); 78 this.resetUnexpectedRequests();
79 }, 79 },
80 80
81 'isExpectingRequests': function () { 81 'isExpectingRequests': function () {
82 return this._isExpectingRequests; 82 return this._isExpectingRequests;
83 }, 83 },
84 84
85 //------------------------------------------------------------------------- 85 //-------------------------------------------------------------------------
86 86
87 'unexpectedRequests': function () { 87 'unexpectedRequests': function () {
88 return this._unexpectedRequests; 88 return this._unexpectedRequests;
89 }, 89 },
90 90
91 'resetUnexpectedRequests': function () { 91 'resetUnexpectedRequests': function () {
92 this._unexpectedRequests = []; 92 this._unexpectedRequests = [];
93 }, 93 },
94 94
95 //------------------------------------------------------------------------- 95 //-------------------------------------------------------------------------
96 96
97 'testExpectedRequestParameters': function (aPath, anActualRequest, anExpectedRequest) { 97 'testExpectedRequestParameters': function (aPath, anActualRequest, anExpectedRequest) {
98 var aKey; 98 var aKey;
99 for (aKey in anExpectedRequest) { 99 for (aKey in anExpectedRequest) {
100 if (typeof(anActualRequest[aKey]) == 'undefined') { 100 if (typeof(anActualRequest[aKey]) == 'undefined') {
101 throw "the expected paramter [" + aKey + "] is missing from the actual request"; 101 throw "the expected paramter [" + aKey + "] is missing from the actual request";
102 } 102 }
103 if (typeof(anExpectedRequest[aKey]) == 'object') { 103 if (typeof(anExpectedRequest[aKey]) == 'object') {
104 this.testExpectedRequestParameters(aPath + "." + aKey, anActualRequest[aKey], anExpectedRequest[aKey]) 104 this.testExpectedRequestParameters(aPath + "." + aKey, anActualRequest[aKey], anExpectedRequest[aKey])
105 } else { 105 } else {
106 if (! anExpectedRequest[aKey](anActualRequest[aKey])) { 106 if (! anExpectedRequest[aKey](anActualRequest[aKey])) {
107 throw "wrong value for paramter [" + aKey + "]; got '" + anActualRequest[aKey] + "'"; 107 throw "wrong value for paramter [" + aKey + "]; got '" + anActualRequest[aKey] + "'";
108 } 108 }
109 } 109 }
110 } 110 }
111 }, 111 },
112 112
113 //------------------------------------------------------------------------- 113 //-------------------------------------------------------------------------
114 114
115 'checkRequest': function(aFunctionName, someParameters) { 115 'checkRequest': function(aFunctionName, someParameters) {
116 if (this.shouldCheckExpectedRequests()) { 116 if (this.shouldCheckExpectedRequests()) {
117 var expectedRequest; 117 var expectedRequest;
118 118
119 expectedRequest = this.expectedRequests().pop(); 119 expectedRequest = this.expectedRequests().pop();
120 if (expectedRequest == null) { 120 if (expectedRequest == null) {
121 throw "Proxy.Test.sentMessage: no expected result specified. Got request '" + aFunctionName + "': " + someParameters; 121 throw "Proxy.Test.sentMessage: no expected result specified. Got request '" + aFunctionName + "': " + someParameters;
122 } 122 }
123 123
124 try { 124 try {
125 if (aFunctionName != expectedRequest.functionName) { 125 if (aFunctionName != expectedRequest.functionName) {
126 throw "wrong function name. Got '" + aFunctionName + "', expected '" + expectedRequest.request.functionName + "'"; 126 throw "wrong function name. Got '" + aFunctionName + "', expected '" + expectedRequest.request.functionName + "'";
127 } 127 }
128 128
129 this.testExpectedRequestParameters("parameters", someParameters, expectedRequest.parameters); 129 this.testExpectedRequestParameters("parameters", someParameters, expectedRequest.parameters);
130 } catch(exception) { 130 } catch(exception) {
131 throw "Proxy.Test.sentMessage[" + expectedRequest.name + "]: " + exception; 131 throw "Proxy.Test.sentMessage[" + expectedRequest.name + "]: " + exception;
132 } 132 }
133 } 133 }
134 }, 134 },
135 135
136 //========================================================================= 136 //=========================================================================
137 137
138 'sendMessage': function(aFunctionName, someParameters) { 138 'sendMessage': function(aFunctionName, someParameters) {
139 var result; 139 var result;
140 140
141 if (this.isExpectingRequests() == false) { 141 if (this.isExpectingRequests() == false) {
142 // throw Clipperz.PM.Connection.exception.UnexpectedRequest; 142 // throw Clipperz.PM.Connection.exception.UnexpectedRequest;
143Clipperz.log("UNEXPECTED REQUEST " + aFunctionName /* + ": " + Clipperz.Base.serializeJSON(someParameters) */); 143Clipperz.log("UNEXPECTED REQUEST " + aFunctionName /* + ": " + Clipperz.Base.serializeJSON(someParameters) */);
144 this.unexpectedRequests().push({'functionName':aFunctionName, 'someParameters': someParameters}); 144 this.unexpectedRequests().push({'functionName':aFunctionName, 'someParameters': someParameters});
145 }; 145 };
146//if (aFunctionName == 'knock') {
147 //console.log(">>> send message - " + aFunctionName, someParameters);
148//} else {
149 //console.log(">>> SEND MESSAGE - " + aFunctionName + " [" + someParameters['parameters']['message'] + "]", someParameters['parameters']['parameters']);
150//}
146 this.checkRequest(aFunctionName, someParameters); 151 this.checkRequest(aFunctionName, someParameters);
147 result = Clipperz.PM.Proxy.Test.superclass.sendMessage.call(this, aFunctionName, someParameters); 152 result = Clipperz.PM.Proxy.Test.superclass.sendMessage.call(this, aFunctionName, someParameters);
148 153
149 return result; 154 return result;
150 }, 155 },
151 156
152 //========================================================================= 157 //=========================================================================
153 __syntaxFix__: "syntax fix" 158 __syntaxFix__: "syntax fix"
154 159
155}); 160});
156 161