summaryrefslogtreecommitdiff
path: root/frontend/gamma
authorMichael Krelin <hacker@klever.net>2014-06-30 18:20:13 (UTC)
committer Michael Krelin <hacker@klever.net>2014-06-30 18:20:13 (UTC)
commitc392fe28606eefa0c814e5c25d641f5ffe623186 (patch) (unidiff)
treeda03fe13ca09fadbebbad9b5d38750757270bae8 /frontend/gamma
parentd341307d346dee62ee36b27f0f93b8f000748a96 (diff)
parent6dd16d9359e3a4dc306802588b09acd43947a606 (diff)
downloadclipperz-c392fe28606eefa0c814e5c25d641f5ffe623186.zip
clipperz-c392fe28606eefa0c814e5c25d641f5ffe623186.tar.gz
clipperz-c392fe28606eefa0c814e5c25d641f5ffe623186.tar.bz2
Merge remote-tracking branch 'github/master' into nmaster
Diffstat (limited to 'frontend/gamma') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/PRNG.js128
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/SRP.js53
-rw-r--r--frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js35
3 files changed, 112 insertions, 104 deletions
diff --git a/frontend/gamma/js/Clipperz/Crypto/PRNG.js b/frontend/gamma/js/Clipperz/Crypto/PRNG.js
index c539f06..80d972f 100644
--- a/frontend/gamma/js/Clipperz/Crypto/PRNG.js
+++ b/frontend/gamma/js/Clipperz/Crypto/PRNG.js
@@ -1,841 +1,805 @@
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
24"use strict";
25
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { 26try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; 27 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
26} 28}
27 29
28try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) { 30try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) {
29 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!"; 31 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!";
30} 32}
31 33
32try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) { 34try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) {
33 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!"; 35 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!";
34} 36}
35 37
36if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; } 38if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; }
37 39
38//############################################################################# 40//#############################################################################
39 41
40Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) { 42Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) {
41 args = args || {}; 43 args = args || {};
42 //MochiKit.Base.bindMethods(this); 44 //MochiKit.Base.bindMethods(this);
43 45
44 this._stack = new Clipperz.ByteArray(); 46 this._stack = new Clipperz.ByteArray();
45 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256; 47 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256;
46 return this; 48 return this;
47} 49}
48 50
49Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, { 51Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, {
50 52
51 'toString': function() { 53 'toString': function() {
52 return "Clipperz.Crypto.PRNG.EntropyAccumulator"; 54 return "Clipperz.Crypto.PRNG.EntropyAccumulator";
53 }, 55 },
54 56
55 //------------------------------------------------------------------------- 57 //-------------------------------------------------------------------------
56 58
57 'stack': function() { 59 'stack': function() {
58 return this._stack; 60 return this._stack;
59 }, 61 },
60 62
61 'setStack': function(aValue) { 63 'setStack': function(aValue) {
62 this._stack = aValue; 64 this._stack = aValue;
63 }, 65 },
64 66
65 'resetStack': function() { 67 'resetStack': function() {
66 this.stack().reset(); 68 this.stack().reset();
67 }, 69 },
68 70
69 'maxStackLengthBeforeHashing': function() { 71 'maxStackLengthBeforeHashing': function() {
70 return this._maxStackLengthBeforeHashing; 72 return this._maxStackLengthBeforeHashing;
71 }, 73 },
72 74
73 //------------------------------------------------------------------------- 75 //-------------------------------------------------------------------------
74 76
75 'addRandomByte': function(aValue) { 77 'addRandomByte': function(aValue) {
76 this.stack().appendByte(aValue); 78 this.stack().appendByte(aValue);
77 79
78 if (this.stack().length() > this.maxStackLengthBeforeHashing()) { 80 if (this.stack().length() > this.maxStackLengthBeforeHashing()) {
79 this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack())); 81 this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack()));
80 } 82 }
81 }, 83 },
82 84
83 //------------------------------------------------------------------------- 85 //-------------------------------------------------------------------------
84 __syntaxFix__: "syntax fix" 86 __syntaxFix__: "syntax fix"
85}); 87});
86 88
87//############################################################################# 89//#############################################################################
88 90
89Clipperz.Crypto.PRNG.RandomnessSource = function(args) { 91Clipperz.Crypto.PRNG.RandomnessSource = function(args) {
90 args = args || {}; 92 args = args || {};
91 MochiKit.Base.bindMethods(this); 93 MochiKit.Base.bindMethods(this);
92 94
93 this._generator = args.generator || null; 95 this._generator = args.generator || null;
94 this._sourceId = args.sourceId || null; 96 this._sourceId = args.sourceId || null;
95 this._boostMode = args.boostMode || false; 97 this._boostMode = args.boostMode || false;
96 98
97 this._nextPoolIndex = 0; 99 this._nextPoolIndex = 0;
98 100
99 return this; 101 return this;
100} 102}
101 103
102Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, { 104Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, {
103 105
104 'generator': function() { 106 'generator': function() {
105 return this._generator; 107 return this._generator;
106 }, 108 },
107 109
108 'setGenerator': function(aValue) { 110 'setGenerator': function(aValue) {
109 this._generator = aValue; 111 this._generator = aValue;
110 }, 112 },
111 113
112 //------------------------------------------------------------------------- 114 //-------------------------------------------------------------------------
113 115
114 'boostMode': function() { 116 'boostMode': function() {
115 return this._boostMode; 117 return this._boostMode;
116 }, 118 },
117 119
118 'setBoostMode': function(aValue) { 120 'setBoostMode': function(aValue) {
119 this._boostMode = aValue; 121 this._boostMode = aValue;
120 }, 122 },
121 123
122 //------------------------------------------------------------------------- 124 //-------------------------------------------------------------------------
123 125
124 'sourceId': function() { 126 'sourceId': function() {
125 return this._sourceId; 127 return this._sourceId;
126 }, 128 },
127 129
128 'setSourceId': function(aValue) { 130 'setSourceId': function(aValue) {
129 this._sourceId = aValue; 131 this._sourceId = aValue;
130 }, 132 },
131 133
132 //------------------------------------------------------------------------- 134 //-------------------------------------------------------------------------
133 135
134 'nextPoolIndex': function() { 136 'nextPoolIndex': function() {
135 return this._nextPoolIndex; 137 return this._nextPoolIndex;
136 }, 138 },
137 139
138 'incrementNextPoolIndex': function() { 140 'incrementNextPoolIndex': function() {
139 this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators()); 141 this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators());
140 }, 142 },
141 143
142 //------------------------------------------------------------------------- 144 //-------------------------------------------------------------------------
143 145
144 'updateGeneratorWithValue': function(aRandomValue) { 146 'updateGeneratorWithValue': function(aRandomValue) {
145 if (this.generator() != null) { 147 if (this.generator() != null) {
146 this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue); 148 this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue);
147 this.incrementNextPoolIndex(); 149 this.incrementNextPoolIndex();
148 } 150 }
149 }, 151 },
150 152
151 //------------------------------------------------------------------------- 153 //-------------------------------------------------------------------------
152 __syntaxFix__: "syntax fix" 154 __syntaxFix__: "syntax fix"
153}); 155});
154 156
155//############################################################################# 157//#############################################################################
156 158
157Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { 159Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) {
158 args = args || {}; 160 args = args || {};
159 //MochiKit.Base.bindMethods(this); 161 //MochiKit.Base.bindMethods(this);
160 162
161 this._intervalTime = args.intervalTime || 1000; 163 this._intervalTime = args.intervalTime || 1000;
162 164
163 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 165 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
164 166
165 this.collectEntropy(); 167 this.collectEntropy();
166 return this; 168 return this;
167} 169}
168 170
169Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 171Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
170 172
171 'intervalTime': function() { 173 'intervalTime': function() {
172 return this._intervalTime; 174 return this._intervalTime;
173 }, 175 },
174 176
175 //------------------------------------------------------------------------- 177 //-------------------------------------------------------------------------
176 178
177 'collectEntropy': function() { 179 'collectEntropy': function() {
178 varnow; 180 varnow;
179 varentropyByte; 181 varentropyByte;
180 var intervalTime; 182 var intervalTime;
181 now = new Date(); 183 now = new Date();
182 entropyByte = (now.getTime() & 0xff); 184 entropyByte = (now.getTime() & 0xff);
183 185
184 intervalTime = this.intervalTime(); 186 intervalTime = this.intervalTime();
185 if (this.boostMode() == true) { 187 if (this.boostMode() == true) {
186 intervalTime = intervalTime / 9; 188 intervalTime = intervalTime / 9;
187 } 189 }
188 190
189 this.updateGeneratorWithValue(entropyByte); 191 this.updateGeneratorWithValue(entropyByte);
190 setTimeout(this.collectEntropy, intervalTime); 192 setTimeout(this.collectEntropy, intervalTime);
191 }, 193 },
192 194
193 //------------------------------------------------------------------------- 195 //-------------------------------------------------------------------------
194 196
195 'numberOfRandomBits': function() { 197 'numberOfRandomBits': function() {
196 return 5; 198 return 5;
197 }, 199 },
198 200
199 //------------------------------------------------------------------------- 201 //-------------------------------------------------------------------------
200
201 'pollingFrequency': function() {
202 return 10;
203 },
204
205 //-------------------------------------------------------------------------
206 __syntaxFix__: "syntax fix" 202 __syntaxFix__: "syntax fix"
207}); 203});
208 204
209//***************************************************************************** 205//*****************************************************************************
210 206
211Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { 207Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) {
212 args = args || {}; 208 args = args || {};
213 209
214 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 210 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
215 211
216 this._numberOfBitsToCollectAtEachEvent = 4; 212 this._numberOfBitsToCollectAtEachEvent = 4;
217 this._randomBitsCollector = 0; 213 this._randomBitsCollector = 0;
218 this._numberOfRandomBitsCollected = 0; 214 this._numberOfRandomBitsCollected = 0;
219 215
220 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); 216 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy');
221 217
222 return this; 218 return this;
223} 219}
224 220
225Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 221Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
226 222
227 //------------------------------------------------------------------------- 223 //-------------------------------------------------------------------------
228 224
229 'numberOfBitsToCollectAtEachEvent': function() { 225 'numberOfBitsToCollectAtEachEvent': function() {
230 return this._numberOfBitsToCollectAtEachEvent; 226 return this._numberOfBitsToCollectAtEachEvent;
231 }, 227 },
232 228
233 //------------------------------------------------------------------------- 229 //-------------------------------------------------------------------------
234 230
235 'randomBitsCollector': function() { 231 'randomBitsCollector': function() {
236 return this._randomBitsCollector; 232 return this._randomBitsCollector;
237 }, 233 },
238 234
239 'setRandomBitsCollector': function(aValue) { 235 'setRandomBitsCollector': function(aValue) {
240 this._randomBitsCollector = aValue; 236 this._randomBitsCollector = aValue;
241 }, 237 },
242 238
243 'appendRandomBitsToRandomBitsCollector': function(aValue) { 239 'appendRandomBitsToRandomBitsCollector': function(aValue) {
244 var collectedBits; 240 var collectedBits;
245 var numberOfRandomBitsCollected; 241 var numberOfRandomBitsCollected;
246 242
247 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); 243 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
248 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); 244 collectedBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
249 this.setRandomBitsCollector(collectetBits); 245 this.setRandomBitsCollector(collectedBits);
250 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); 246 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent();
251 247
252 if (numberOfRandomBitsCollected == 8) { 248 if (numberOfRandomBitsCollected == 8) {
253 this.updateGeneratorWithValue(collectetBits); 249 this.updateGeneratorWithValue(collectedBits);
254 numberOfRandomBitsCollected = 0; 250 numberOfRandomBitsCollected = 0;
255 this.setRandomBitsCollector(0); 251 this.setRandomBitsCollector(0);
256 } 252 }
257 253
258 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) 254 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
259 }, 255 },
260 256
261 //------------------------------------------------------------------------- 257 //-------------------------------------------------------------------------
262 258
263 'numberOfRandomBitsCollected': function() { 259 'numberOfRandomBitsCollected': function() {
264 return this._numberOfRandomBitsCollected; 260 return this._numberOfRandomBitsCollected;
265 }, 261 },
266 262
267 'setNumberOfRandomBitsCollected': function(aValue) { 263 'setNumberOfRandomBitsCollected': function(aValue) {
268 this._numberOfRandomBitsCollected = aValue; 264 this._numberOfRandomBitsCollected = aValue;
269 }, 265 },
270 266
271 //------------------------------------------------------------------------- 267 //-------------------------------------------------------------------------
272 268
273 'collectEntropy': function(anEvent) { 269 'collectEntropy': function(anEvent) {
274 var mouseLocation; 270 var mouseLocation;
275 var randomBit; 271 var randomBit;
276 var mask; 272 var mask;
277 273
278 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); 274 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent());
279 275
280 mouseLocation = anEvent.mouse().client; 276 mouseLocation = anEvent.mouse().client;
281 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); 277 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask);
282 this.appendRandomBitsToRandomBitsCollector(randomBit) 278 this.appendRandomBitsToRandomBitsCollector(randomBit)
283 }, 279 },
284 280
285 //------------------------------------------------------------------------- 281 //-------------------------------------------------------------------------
286 282
287 'numberOfRandomBits': function() { 283 'numberOfRandomBits': function() {
288 return 1; 284 return 1;
289 }, 285 },
290 286
291 //------------------------------------------------------------------------- 287 //-------------------------------------------------------------------------
292
293 'pollingFrequency': function() {
294 return 10;
295 },
296
297 //-------------------------------------------------------------------------
298 __syntaxFix__: "syntax fix" 288 __syntaxFix__: "syntax fix"
299}); 289});
300 290
301//***************************************************************************** 291//*****************************************************************************
302 292
303Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) { 293Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) {
304 args = args || {}; 294 args = args || {};
305 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
306 295
307 this._randomBitsCollector = 0; 296 this._intervalTime = args.intervalTime || 1000;
308 this._numberOfRandomBitsCollected = 0; 297 this._browserCrypto = args.browserCrypto;
309 298
310 MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy'); 299 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
311 300
301 this.collectEntropy();
312 return this; 302 return this;
313} 303}
314 304
315Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 305Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
316 306
317 //------------------------------------------------------------------------- 307 'intervalTime': function() {
318 308 return this._intervalTime;
319 'randomBitsCollector': function() {
320 return this._randomBitsCollector;
321 },
322
323 'setRandomBitsCollector': function(aValue) {
324 this._randomBitsCollector = aValue;
325 }, 309 },
326 310
327 'appendRandomBitToRandomBitsCollector': function(aValue) { 311 'browserCrypto': function () {
328 var collectedBits; 312 return this._browserCrypto;
329 var numberOfRandomBitsCollected;
330
331 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
332 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
333 this.setRandomBitsCollector(collectetBits);
334 numberOfRandomBitsCollected ++;
335
336 if (numberOfRandomBitsCollected == 8) {
337 this.updateGeneratorWithValue(collectetBits);
338 numberOfRandomBitsCollected = 0;
339 this.setRandomBitsCollector(0);
340 }
341
342 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
343 }, 313 },
344 314
345 //------------------------------------------------------------------------- 315 //-------------------------------------------------------------------------
346 316
347 'numberOfRandomBitsCollected': function() { 317 'collectEntropy': function() {
348 return this._numberOfRandomBitsCollected; 318 varbytesToCollect;
349 },
350
351 'setNumberOfRandomBitsCollected': function(aValue) {
352 this._numberOfRandomBitsCollected = aValue;
353 },
354 319
355 //------------------------------------------------------------------------- 320 if (this.boostMode() == true) {
321 bytesToCollect = 64;
322 } else {
323 bytesToCollect = 8;
324 }
356 325
357 'collectEntropy': function(anEvent) { 326 var randomValuesArray = new Uint8Array(bytesToCollect);
358/* 327 this.browserCrypto().getRandomValues(randomValuesArray);
359 var mouseLocation; 328 for (var i = 0; i < randomValuesArray.length; i++) {
360 var randomBit; 329 this.updateGeneratorWithValue(randomValuesArray[i]);
361 330 }
362 mouseLocation = anEvent.mouse().client;
363
364 randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1);
365 this.appendRandomBitToRandomBitsCollector(randomBit);
366*/
367 },
368
369 //-------------------------------------------------------------------------
370 331
371 'numberOfRandomBits': function() { 332 setTimeout(this.collectEntropy, this.intervalTime());
372 return 1;
373 }, 333 },
374 334
375 //------------------------------------------------------------------------- 335 //-------------------------------------------------------------------------
376
377 'pollingFrequency': function() {
378 return 10;
379 },
380
381 //-------------------------------------------------------------------------
382 __syntaxFix__: "syntax fix" 336 __syntaxFix__: "syntax fix"
383}); 337});
384 338
385//############################################################################# 339//#############################################################################
386 340
387Clipperz.Crypto.PRNG.Fortuna = function(args) { 341Clipperz.Crypto.PRNG.Fortuna = function(args) {
388 vari,c; 342 vari,c;
389 343
390 args = args || {}; 344 args = args || {};
391 345
392 this._key = args.seed || null; 346 this._key = args.seed || null;
393 if (this._key == null) { 347 if (this._key == null) {
394 this._counter = 0; 348 this._counter = 0;
395 this._key = new Clipperz.ByteArray(); 349 this._key = new Clipperz.ByteArray();
396 } else { 350 } else {
397 this._counter = 1; 351 this._counter = 1;
398 } 352 }
399 353
400 this._aesKey = null; 354 this._aesKey = null;
401 355
402 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; 356 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64;
403 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; 357 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32;
404 358
405 this._accumulators = []; 359 this._accumulators = [];
406 c = this.numberOfEntropyAccumulators(); 360 c = this.numberOfEntropyAccumulators();
407 for (i=0; i<c; i++) { 361 for (i=0; i<c; i++) {
408 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); 362 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator());
409 } 363 }
410 364
411 this._randomnessSources = []; 365 this._randomnessSources = [];
412 this._reseedCounter = 0; 366 this._reseedCounter = 0;
413 367
414 return this; 368 return this;
415} 369}
416 370
417Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { 371Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, {
418 372
419 'toString': function() { 373 'toString': function() {
420 return "Clipperz.Crypto.PRNG.Fortuna"; 374 return "Clipperz.Crypto.PRNG.Fortuna";
421 }, 375 },
422 376
423 //------------------------------------------------------------------------- 377 //-------------------------------------------------------------------------
424 378
425 'key': function() { 379 'key': function() {
426 return this._key; 380 return this._key;
427 }, 381 },
428 382
429 'setKey': function(aValue) { 383 'setKey': function(aValue) {
430 this._key = aValue; 384 this._key = aValue;
431 this._aesKey = null; 385 this._aesKey = null;
432 }, 386 },
433 387
434 'aesKey': function() { 388 'aesKey': function() {
435 if (this._aesKey == null) { 389 if (this._aesKey == null) {
436 this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()}); 390 this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()});
437 } 391 }
438 392
439 return this._aesKey; 393 return this._aesKey;
440 }, 394 },
441 395
442 'accumulators': function() { 396 'accumulators': function() {
443 return this._accumulators; 397 return this._accumulators;
444 }, 398 },
445 399
446 'firstPoolReseedLevel': function() { 400 'firstPoolReseedLevel': function() {
447 return this._firstPoolReseedLevel; 401 return this._firstPoolReseedLevel;
448 }, 402 },
449 403
450 //------------------------------------------------------------------------- 404 //-------------------------------------------------------------------------
451 405
452 'reseedCounter': function() { 406 'reseedCounter': function() {
453 return this._reseedCounter; 407 return this._reseedCounter;
454 }, 408 },
455 409
456 'incrementReseedCounter': function() { 410 'incrementReseedCounter': function() {
457 this._reseedCounter = this._reseedCounter +1; 411 this._reseedCounter = this._reseedCounter +1;
458 }, 412 },
459 413
460 //------------------------------------------------------------------------- 414 //-------------------------------------------------------------------------
461 415
462 'reseed': function() { 416 'reseed': function() {
463 varnewKeySeed; 417 varnewKeySeed;
464 var reseedCounter; 418 var reseedCounter;
465 varreseedCounterMask; 419 varreseedCounterMask;
466 var i, c; 420 var i, c;
467 421
468 newKeySeed = this.key(); 422 newKeySeed = this.key();
469 this.incrementReseedCounter(); 423 this.incrementReseedCounter();
470 reseedCounter = this.reseedCounter(); 424 reseedCounter = this.reseedCounter();
471 425
472 c = this.numberOfEntropyAccumulators(); 426 c = this.numberOfEntropyAccumulators();
473 reseedCounterMask = 0xffffffff >>> (32 - c); 427 reseedCounterMask = 0xffffffff >>> (32 - c);
474 for (i=0; i<c; i++) { 428 for (i=0; i<c; i++) {
475 if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) { 429 if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) {
476 newKeySeed.appendBlock(this.accumulators()[i].stack()); 430 newKeySeed.appendBlock(this.accumulators()[i].stack());
477 this.accumulators()[i].resetStack(); 431 this.accumulators()[i].resetStack();
478 } 432 }
479 } 433 }
480 434
481 if (reseedCounter == 1) { 435 if (reseedCounter == 1) {
482 c = this.randomnessSources().length; 436 c = this.randomnessSources().length;
483 for (i=0; i<c; i++) { 437 for (i=0; i<c; i++) {
484 this.randomnessSources()[i].setBoostMode(false); 438 this.randomnessSources()[i].setBoostMode(false);
485 } 439 }
486 } 440 }
487 441
488 this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed)); 442 this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed));
489 if (reseedCounter == 1) { 443 if (reseedCounter == 1) {
490Clipperz.log("### PRNG.readyToGenerateRandomBytes"); 444Clipperz.log("### PRNG.readyToGenerateRandomBytes");
491 MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes'); 445 MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes');
492 } 446 }
493 MochiKit.Signal.signal(this, 'reseeded'); 447 MochiKit.Signal.signal(this, 'reseeded');
494 }, 448 },
495 449
496 //------------------------------------------------------------------------- 450 //-------------------------------------------------------------------------
497 451
498 'isReadyToGenerateRandomValues': function() { 452 'isReadyToGenerateRandomValues': function() {
499 return this.reseedCounter() != 0; 453 return this.reseedCounter() != 0;
500 }, 454 },
501 455
502 //------------------------------------------------------------------------- 456 //-------------------------------------------------------------------------
503 457
504 'entropyLevel': function() { 458 'entropyLevel': function() {
505 return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel()); 459 return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel());
506 }, 460 },
507 461
508 //------------------------------------------------------------------------- 462 //-------------------------------------------------------------------------
509 463
510 'counter': function() { 464 'counter': function() {
511 return this._counter; 465 return this._counter;
512 }, 466 },
513 467
514 'incrementCounter': function() { 468 'incrementCounter': function() {
515 this._counter += 1; 469 this._counter += 1;
516 }, 470 },
517 471
518 'counterBlock': function() { 472 'counterBlock': function() {
519 var result; 473 var result;
520 474
521 result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0); 475 result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0);
522 476
523 return result; 477 return result;
524 }, 478 },
525 479
526 //------------------------------------------------------------------------- 480 //-------------------------------------------------------------------------
527 481
528 'getRandomBlock': function() { 482 'getRandomBlock': function() {
529 var result; 483 var result;
530 484
531 result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues())); 485 result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues()));
532 this.incrementCounter(); 486 this.incrementCounter();
533 487
534 return result; 488 return result;
535 }, 489 },
536 490
537 //------------------------------------------------------------------------- 491 //-------------------------------------------------------------------------
538 492
539 'getRandomBytes': function(aSize) { 493 'getRandomBytes': function(aSize) {
540 var result; 494 var result;
541 495
542 if (this.isReadyToGenerateRandomValues()) { 496 if (this.isReadyToGenerateRandomValues()) {
543 var i,c; 497 var i,c;
544 var newKey; 498 var newKey;
545 499
546 result = new Clipperz.ByteArray(); 500 result = new Clipperz.ByteArray();
547 501
548 c = Math.ceil(aSize / (128 / 8)); 502 c = Math.ceil(aSize / (128 / 8));
549 for (i=0; i<c; i++) { 503 for (i=0; i<c; i++) {
550 result.appendBlock(this.getRandomBlock()); 504 result.appendBlock(this.getRandomBlock());
551 } 505 }
552 506
553 if (result.length() != aSize) { 507 if (result.length() != aSize) {
554 result = result.split(0, aSize); 508 result = result.split(0, aSize);
555 } 509 }
556 510
557 newKey = this.getRandomBlock().appendBlock(this.getRandomBlock()); 511 newKey = this.getRandomBlock().appendBlock(this.getRandomBlock());
558 this.setKey(newKey); 512 this.setKey(newKey);
559 } else { 513 } else {
560Clipperz.logWarning("Fortuna generator has not enough entropy, yet!"); 514Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
561 throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy; 515 throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy;
562 } 516 }
563 517
564 return result; 518 return result;
565 }, 519 },
566 520
567 //------------------------------------------------------------------------- 521 //-------------------------------------------------------------------------
568 522
569 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) { 523 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) {
570 varselectedAccumulator; 524 varselectedAccumulator;
571 525
572 selectedAccumulator = this.accumulators()[aPoolId]; 526 selectedAccumulator = this.accumulators()[aPoolId];
573 selectedAccumulator.addRandomByte(aRandomValue); 527 selectedAccumulator.addRandomByte(aRandomValue);
574 528
575 if (aPoolId == 0) { 529 if (aPoolId == 0) {
576 MochiKit.Signal.signal(this, 'addedRandomByte') 530 MochiKit.Signal.signal(this, 'addedRandomByte')
577 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) { 531 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) {
578 this.reseed(); 532 this.reseed();
579 } 533 }
580 } 534 }
581 }, 535 },
582 536
583 //------------------------------------------------------------------------- 537 //-------------------------------------------------------------------------
584 538
585 'numberOfEntropyAccumulators': function() { 539 'numberOfEntropyAccumulators': function() {
586 return this._numberOfEntropyAccumulators; 540 return this._numberOfEntropyAccumulators;
587 }, 541 },
588 542
589 //------------------------------------------------------------------------- 543 //-------------------------------------------------------------------------
590 544
591 'randomnessSources': function() { 545 'randomnessSources': function() {
592 return this._randomnessSources; 546 return this._randomnessSources;
593 }, 547 },
594 548
595 'addRandomnessSource': function(aRandomnessSource) { 549 'addRandomnessSource': function(aRandomnessSource) {
596 aRandomnessSource.setGenerator(this); 550 aRandomnessSource.setGenerator(this);
597 aRandomnessSource.setSourceId(this.randomnessSources().length); 551 aRandomnessSource.setSourceId(this.randomnessSources().length);
598 this.randomnessSources().push(aRandomnessSource); 552 this.randomnessSources().push(aRandomnessSource);
599 553
600 if (this.isReadyToGenerateRandomValues() == false) { 554 if (this.isReadyToGenerateRandomValues() == false) {
601 aRandomnessSource.setBoostMode(true); 555 aRandomnessSource.setBoostMode(true);
602 } 556 }
603 }, 557 },
604 558
605 //------------------------------------------------------------------------- 559 //-------------------------------------------------------------------------
606 560
607 'deferredEntropyCollection': function(aValue) { 561 'deferredEntropyCollection': function(aValue) {
608 var result; 562 var result;
609 563
610 564
611 if (this.isReadyToGenerateRandomValues()) { 565 if (this.isReadyToGenerateRandomValues()) {
612 result = aValue; 566 result = aValue;
613 } else { 567 } else {
614 var deferredResult; 568 var deferredResult;
615 569
616 deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection"); 570 deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection");
617 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); 571 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
618 MochiKit.Signal.connect(this, 572 MochiKit.Signal.connect(this,
619 'readyToGenerateRandomBytes', 573 'readyToGenerateRandomBytes',
620 deferredResult, 574 deferredResult,
621 'callback'); 575 'callback');
622 576
623 result = deferredResult; 577 result = deferredResult;
624 } 578 }
625 579
626 return result; 580 return result;
627 }, 581 },
628 582
629 //------------------------------------------------------------------------- 583 //-------------------------------------------------------------------------
630 584
631 'fastEntropyAccumulationForTestingPurpose': function() { 585 'fastEntropyAccumulationForTestingPurpose': function() {
632 while (! this.isReadyToGenerateRandomValues()) { 586 while (! this.isReadyToGenerateRandomValues()) {
633 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); 587 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
634 } 588 }
635 }, 589 },
636 590
637 //------------------------------------------------------------------------- 591 //-------------------------------------------------------------------------
638 592/*
639 'dump': function(appendToDoc) { 593 'dump': function(appendToDoc) {
640 var tbl; 594 var tbl;
641 var i,c; 595 var i,c;
642 596
643 tbl = document.createElement("table"); 597 tbl = document.createElement("table");
644 tbl.border = 0; 598 tbl.border = 0;
645 with (tbl.style) { 599 with (tbl.style) {
646 border = "1px solid lightgrey"; 600 border = "1px solid lightgrey";
647 fontFamily = 'Helvetica, Arial, sans-serif'; 601 fontFamily = 'Helvetica, Arial, sans-serif';
648 fontSize = '8pt'; 602 fontSize = '8pt';
649 //borderCollapse = "collapse"; 603 //borderCollapse = "collapse";
650 } 604 }
651 var hdr = tbl.createTHead(); 605 var hdr = tbl.createTHead();
652 var hdrtr = hdr.insertRow(0); 606 var hdrtr = hdr.insertRow(0);
653 // document.createElement("tr"); 607 // document.createElement("tr");
654 { 608 {
655 var ntd; 609 var ntd;
656 610
657 ntd = hdrtr.insertCell(0); 611 ntd = hdrtr.insertCell(0);
658 ntd.style.borderBottom = "1px solid lightgrey"; 612 ntd.style.borderBottom = "1px solid lightgrey";
659 ntd.style.borderRight = "1px solid lightgrey"; 613 ntd.style.borderRight = "1px solid lightgrey";
660 ntd.appendChild(document.createTextNode("#")); 614 ntd.appendChild(document.createTextNode("#"));
661 615
662 ntd = hdrtr.insertCell(1); 616 ntd = hdrtr.insertCell(1);
663 ntd.style.borderBottom = "1px solid lightgrey"; 617 ntd.style.borderBottom = "1px solid lightgrey";
664 ntd.style.borderRight = "1px solid lightgrey"; 618 ntd.style.borderRight = "1px solid lightgrey";
665 ntd.appendChild(document.createTextNode("s")); 619 ntd.appendChild(document.createTextNode("s"));
666 620
667 ntd = hdrtr.insertCell(2); 621 ntd = hdrtr.insertCell(2);
668 ntd.colSpan = this.firstPoolReseedLevel(); 622 ntd.colSpan = this.firstPoolReseedLevel();
669 ntd.style.borderBottom = "1px solid lightgrey"; 623 ntd.style.borderBottom = "1px solid lightgrey";
670 ntd.style.borderRight = "1px solid lightgrey"; 624 ntd.style.borderRight = "1px solid lightgrey";
671 ntd.appendChild(document.createTextNode("base values")); 625 ntd.appendChild(document.createTextNode("base values"));
672 626
673 ntd = hdrtr.insertCell(3); 627 ntd = hdrtr.insertCell(3);
674 ntd.colSpan = 20; 628 ntd.colSpan = 20;
675 ntd.style.borderBottom = "1px solid lightgrey"; 629 ntd.style.borderBottom = "1px solid lightgrey";
676 ntd.appendChild(document.createTextNode("extra values")); 630 ntd.appendChild(document.createTextNode("extra values"));
677 631
678 } 632 }
679 633
680 c = this.accumulators().length; 634 c = this.accumulators().length;
681 for (i=0; i<c ; i++) { 635 for (i=0; i<c ; i++) {
682 varcurrentAccumulator; 636 varcurrentAccumulator;
683 var bdytr; 637 var bdytr;
684 var bdytd; 638 var bdytd;
685 var ii, cc; 639 var ii, cc;
686 640
687 currentAccumulator = this.accumulators()[i] 641 currentAccumulator = this.accumulators()[i]
688 642
689 bdytr = tbl.insertRow(true); 643 bdytr = tbl.insertRow(true);
690 644
691 bdytd = bdytr.insertCell(0); 645 bdytd = bdytr.insertCell(0);
692 bdytd.style.borderRight = "1px solid lightgrey"; 646 bdytd.style.borderRight = "1px solid lightgrey";
693 bdytd.style.color = "lightgrey"; 647 bdytd.style.color = "lightgrey";
694 bdytd.appendChild(document.createTextNode("" + i)); 648 bdytd.appendChild(document.createTextNode("" + i));
695 649
696 bdytd = bdytr.insertCell(1); 650 bdytd = bdytr.insertCell(1);
697 bdytd.style.borderRight = "1px solid lightgrey"; 651 bdytd.style.borderRight = "1px solid lightgrey";
698 bdytd.style.color = "gray"; 652 bdytd.style.color = "gray";
699 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); 653 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
700 654
701 655
702 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); 656 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
703 for (ii=0; ii<cc; ii++) { 657 for (ii=0; ii<cc; ii++) {
704 var cellText; 658 var cellText;
705 659
706 bdytd = bdytr.insertCell(ii + 2); 660 bdytd = bdytr.insertCell(ii + 2);
707 661
708 if (ii < currentAccumulator.stack().length()) { 662 if (ii < currentAccumulator.stack().length()) {
709 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); 663 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
710 } else { 664 } else {
711 cellText = "_"; 665 cellText = "_";
712 } 666 }
713 667
714 if (ii == (this.firstPoolReseedLevel() - 1)) { 668 if (ii == (this.firstPoolReseedLevel() - 1)) {
715 bdytd.style.borderRight = "1px solid lightgrey"; 669 bdytd.style.borderRight = "1px solid lightgrey";
716 } 670 }
717 671
718 bdytd.appendChild(document.createTextNode(cellText)); 672 bdytd.appendChild(document.createTextNode(cellText));
719 } 673 }
720 674
721 } 675 }
722 676
723 677
724 if (appendToDoc) { 678 if (appendToDoc) {
725 var ne = document.createElement("div"); 679 var ne = document.createElement("div");
726 ne.id = "entropyGeneratorStatus"; 680 ne.id = "entropyGeneratorStatus";
727 with (ne.style) { 681 with (ne.style) {
728 fontFamily = "Courier New, monospace"; 682 fontFamily = "Courier New, monospace";
729 fontSize = "12px"; 683 fontSize = "12px";
730 lineHeight = "16px"; 684 lineHeight = "16px";
731 borderTop = "1px solid black"; 685 borderTop = "1px solid black";
732 padding = "10px"; 686 padding = "10px";
733 } 687 }
734 if (document.getElementById(ne.id)) { 688 if (document.getElementById(ne.id)) {
735 MochiKit.DOM.swapDOM(ne.id, ne); 689 MochiKit.DOM.swapDOM(ne.id, ne);
736 } else { 690 } else {
737 document.body.appendChild(ne); 691 document.body.appendChild(ne);
738 } 692 }
739 ne.appendChild(tbl); 693 ne.appendChild(tbl);
740 } 694 }
741 695
742 return tbl; 696 return tbl;
743 }, 697 },
744 698*/
745 //----------------------------------------------------------------------------- 699 //-----------------------------------------------------------------------------
746 __syntaxFix__: "syntax fix" 700 __syntaxFix__: "syntax fix"
747}); 701});
748 702
749//############################################################################# 703//#############################################################################
750 704
751Clipperz.Crypto.PRNG.Random = function(args) { 705Clipperz.Crypto.PRNG.Random = function(args) {
752 args = args || {}; 706 args = args || {};
753 //MochiKit.Base.bindMethods(this); 707 //MochiKit.Base.bindMethods(this);
754 708
755 return this; 709 return this;
756} 710}
757 711
758Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { 712Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
759 713
760 'toString': function() { 714 'toString': function() {
761 return "Clipperz.Crypto.PRNG.Random"; 715 return "Clipperz.Crypto.PRNG.Random";
762 }, 716 },
763 717
764 //------------------------------------------------------------------------- 718 //-------------------------------------------------------------------------
765 719
766 'getRandomBytes': function(aSize) { 720 'getRandomBytes': function(aSize) {
767//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); 721//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
768 varresult; 722 varresult;
769 var i,c; 723 var i,c;
770 724
771 result = new Clipperz.ByteArray() 725 result = new Clipperz.ByteArray()
772 c = aSize || 1; 726 c = aSize || 1;
773 for (i=0; i<c; i++) { 727 for (i=0; i<c; i++) {
774 result.appendByte((Math.random()*255) & 0xff); 728 result.appendByte((Math.random()*255) & 0xff);
775 } 729 }
776 730
777//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); 731//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
778 return result; 732 return result;
779 }, 733 },
780 734
781 //------------------------------------------------------------------------- 735 //-------------------------------------------------------------------------
782 __syntaxFix__: "syntax fix" 736 __syntaxFix__: "syntax fix"
783}); 737});
784 738
785//############################################################################# 739//#############################################################################
786 740
787_clipperz_crypt_prng_defaultPRNG = null; 741var _clipperz_crypt_prng_defaultPRNG = null;
788 742
789Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { 743Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
790 if (_clipperz_crypt_prng_defaultPRNG == null) { 744 if (_clipperz_crypt_prng_defaultPRNG == null) {
791 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); 745 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
792 746
793 //............................................................. 747 //.............................................................
794 // 748 //
795 // TimeRandomnessSource 749 // TimeRandomnessSource
796 // 750 //
797 //............................................................. 751 //.............................................................
798 { 752 {
799 var newRandomnessSource; 753 var newRandomnessSource;
800 754
801 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); 755 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
802 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 756 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
803 } 757 }
804 758
805 //............................................................. 759 //.............................................................
806 // 760 //
807 // MouseRandomnessSource 761 // MouseRandomnessSource
808 // 762 //
809 //............................................................. 763 //.............................................................
810 { 764 {
811 varnewRandomnessSource; 765 varnewRandomnessSource;
812 766
813 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); 767 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
814 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 768 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
815 } 769 }
816 770
817 //............................................................. 771 //.............................................................
818 // 772 //
819 // KeyboardRandomnessSource 773 // CryptoRandomRandomnessSource
820 // 774 //
821 //............................................................. 775 //.............................................................
822 { 776 {
823 varnewRandomnessSource; 777 varnewRandomnessSource;
778 varbrowserCrypto;
824 779
825 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource(); 780 if (window.crypto && window.crypto.getRandomValues) {
826 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 781 browserCrypto = window.crypto;
782 } else if (window.msCrypto && window.msCrypto.getRandomValues) {
783 browserCrypto = window.msCrypto;
784 } else {
785 browserCrypto = null;
786 }
787
788 if (browserCrypto != null) {
789 newRandomnessSource = new Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource({'browserCrypto':browserCrypto});
790 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
791 }
827 } 792 }
828
829 } 793 }
830 794
831 return _clipperz_crypt_prng_defaultPRNG; 795 return _clipperz_crypt_prng_defaultPRNG;
832}; 796};
833 797
834//############################################################################# 798//#############################################################################
835 799
836Clipperz.Crypto.PRNG.exception = { 800Clipperz.Crypto.PRNG.exception = {
837 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") 801 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
838}; 802};
839 803
840 804
841MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); 805MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);
diff --git a/frontend/gamma/js/Clipperz/Crypto/SRP.js b/frontend/gamma/js/Clipperz/Crypto/SRP.js
index 597e72d..6898dfb 100644
--- a/frontend/gamma/js/Clipperz/Crypto/SRP.js
+++ b/frontend/gamma/js/Clipperz/Crypto/SRP.js
@@ -1,316 +1,345 @@
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
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { 24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; 25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
26} 26}
27 27
28try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { 28try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) {
29 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; 29 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!";
30} 30}
31 31
32try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { 32try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
33 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; 33 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!";
34} 34}
35 35
36if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } 36if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; }
37 37
38Clipperz.Crypto.SRP.VERSION = "0.1"; 38Clipperz.Crypto.SRP.VERSION = "0.1";
39Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; 39Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP";
40 40
41//############################################################################# 41//#############################################################################
42 42
43MochiKit.Base.update(Clipperz.Crypto.SRP, { 43MochiKit.Base.update(Clipperz.Crypto.SRP, {
44 44
45 '_n': null, 45 '_n': null,
46 '_g': null, 46 '_g': null,
47 '_k': null,
48
47 //------------------------------------------------------------------------- 49 //-------------------------------------------------------------------------
48 50
49 'n': function() { 51 'n': function() {
50 if (Clipperz.Crypto.SRP._n == null) { 52 if (Clipperz.Crypto.SRP._n == null) {
51 Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); 53 Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16);
52 } 54 }
53 55
54 return Clipperz.Crypto.SRP._n; 56 return Clipperz.Crypto.SRP._n;
55 }, 57 },
56 58
57 //------------------------------------------------------------------------- 59 //-------------------------------------------------------------------------
58 60
59 'g': function() { 61 'g': function() {
60 if (Clipperz.Crypto.SRP._g == null) { 62 if (Clipperz.Crypto.SRP._g == null) {
61 Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation) 63 Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation)
62 } 64 }
63 65
64 return Clipperz.Crypto.SRP._g; 66 return Clipperz.Crypto.SRP._g;
65 }, 67 },
66 68
69 'k': function() {
70 if (Clipperz.Crypto.SRP._k == null) {
71 // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16);
72 Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16);
73 }
74
75 return Clipperz.Crypto.SRP._k;
76 },
77
67 //----------------------------------------------------------------------------- 78 //-----------------------------------------------------------------------------
68 79
69 'exception': { 80 'exception': {
70 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") 81 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue")
71 }, 82 },
72 83
73 //------------------------------------------------------------------------- 84 //-------------------------------------------------------------------------
74 __syntaxFix__: "syntax fix" 85 __syntaxFix__: "syntax fix"
75 86
76}); 87});
77 88
78//############################################################################# 89//#############################################################################
79// 90//
80 // S R P C o n n e c t i o n version 1.0 91 // S R P C o n n e c t i o n version 1.0
81// 92//
82//============================================================================= 93//=============================================================================
83Clipperz.Crypto.SRP.Connection = function (args) { 94Clipperz.Crypto.SRP.Connection = function (args) {
84 args = args || {}; 95 args = args || {};
85 96
86 this._C = args.C; 97 this._C = args.C;
87 this._P = args.P; 98 this._P = args.P;
88 this.hash = args.hash; 99 this.hash = args.hash;
89 100
90 this._a = null; 101 this._a = null;
91 this._A = null; 102 this._A = null;
92 103
93 this._s = null; 104 this._s = null;
94 this._B = null; 105 this._B = null;
95 106
96 this._x = null; 107 this._x = null;
97 108
98 this._u = null; 109 this._u = null;
99 this._K = null; 110 this._K = null;
100 this._M1 = null; 111 this._M1 = null;
101 this._M2 = null; 112 this._M2 = null;
102 113
103 this._sessionKey = null; 114 this._sessionKey = null;
104 115
105 return this; 116 return this;
106} 117}
107 118
108Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 119Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
109 120
110 'toString': function () { 121 'toString': function () {
111 return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); 122 return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription();
112 }, 123 },
113 124
114 //------------------------------------------------------------------------- 125 //-------------------------------------------------------------------------
115 126
116 'C': function () { 127 'C': function () {
117 return this._C; 128 return this._C;
118 }, 129 },
119 130
120 //------------------------------------------------------------------------- 131 //-------------------------------------------------------------------------
121 132
122 'P': function () { 133 'P': function () {
123 return this._P; 134 return this._P;
124 }, 135 },
125 136
126 //------------------------------------------------------------------------- 137 //-------------------------------------------------------------------------
127 138
128 'a': function () { 139 'a': function () {
129 if (this._a == null) { 140 if (this._a == null) {
130 this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); 141 this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16);
131 // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); 142 // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10);
132 } 143 }
133 144
134 return this._a; 145 return this._a;
135 }, 146 },
136 147
137 //------------------------------------------------------------------------- 148 //-------------------------------------------------------------------------
138 149
139 'A': function () { 150 'A': function () {
140 if (this._A == null) { 151 if (this._A == null) {
141 //Warning: this value should be strictly greater than zero: how should we perform this check? 152 //Warning: this value should be strictly greater than zero
142 this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); 153 this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n());
143 154 if (this._A.equals(0) || negative(this._A)) {
144 if (this._A.equals(0)) {
145 Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0."); 155 Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0.");
146 throw Clipperz.Crypto.SRP.exception.InvalidValue; 156 throw Clipperz.Crypto.SRP.exception.InvalidValue;
147 } 157 }
148 } 158 }
149 159
150 return this._A; 160 return this._A;
151 }, 161 },
152 162
153 //------------------------------------------------------------------------- 163 //-------------------------------------------------------------------------
154 164
155 's': function () { 165 's': function () {
156 return this._s; 166 return this._s;
157 }, 167 },
158 168
159 'set_s': function(aValue) { 169 'set_s': function(aValue) {
160 this._s = aValue; 170 this._s = aValue;
161 }, 171 },
162 172
163 //------------------------------------------------------------------------- 173 //-------------------------------------------------------------------------
164 174
165 'B': function () { 175 'B': function () {
166 return this._B; 176 return this._B;
167 }, 177 },
168 178
169 'set_B': function(aValue) { 179 'set_B': function(aValue) {
170 //Warning: this value should be strictly greater than zero: how should we perform this check? 180 //Warning: this value should be strictly greater than zero
171 if (! aValue.equals(0)) { 181 this._B = aValue;
172 this._B = aValue; 182 if (this._B.equals(0) || negative(this._B)) {
173 } else {
174 Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0."); 183 Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0.");
175 throw Clipperz.Crypto.SRP.exception.InvalidValue; 184 throw Clipperz.Crypto.SRP.exception.InvalidValue;
176 } 185 }
177 }, 186 },
178 187
179 //------------------------------------------------------------------------- 188 //-------------------------------------------------------------------------
180 189
181 'x': function () { 190 'x': function () {
182 if (this._x == null) { 191 if (this._x == null) {
183 this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); 192 this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16);
184 } 193 }
185 194
186 return this._x; 195 return this._x;
187 }, 196 },
188 197
189 //------------------------------------------------------------------------- 198 //-------------------------------------------------------------------------
190 199
191 'u': function () { 200 'u': function () {
192 if (this._u == null) { 201 if (this._u == null) {
193 this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16); 202 this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.A().asString() + this.B().asString()), 16);
194 } 203 }
195 204
196 return this._u; 205 return this._u;
197 }, 206 },
198 207
199 //------------------------------------------------------------------------- 208 //-------------------------------------------------------------------------
200 209
201 'S': function () { 210 'S': function () {
202 if (this._S == null) { 211 if (this._S == null) {
203 var bigint; 212 var bigint;
204 varsrp; 213 varsrp;
205 214
206 bigint = Clipperz.Crypto.BigInt; 215 bigint = Clipperz.Crypto.BigInt;
207 srp = Clipperz.Crypto.SRP; 216 srp = Clipperz.Crypto.SRP;
208 217
209 this._S =bigint.powerModule( 218 this._S =bigint.powerModule(
210 bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())), 219 bigint.subtract(
211 bigint.add(this.a(), bigint.multiply(this.u(), this.x())), 220 this.B(),
212 srp.n() 221 bigint.multiply(
222 Clipperz.Crypto.SRP.k(),
223 bigint.powerModule(srp.g(), this.x(), srp.n())
224 )
225 ),
226 bigint.add(this.a(), bigint.multiply(this.u(), this.x())),
227 srp.n()
213 ) 228 )
214 } 229 }
215 230
216 return this._S; 231 return this._S;
217 }, 232 },
218 233
219 //------------------------------------------------------------------------- 234 //-------------------------------------------------------------------------
220 235
221 'K': function () { 236 'K': function () {
222 if (this._K == null) { 237 if (this._K == null) {
223 this._K = this.stringHash(this.S().asString()); 238 this._K = this.stringHash(this.S().asString());
224 } 239 }
225 240
226 return this._K; 241 return this._K;
227 }, 242 },
228 243
229 //------------------------------------------------------------------------- 244 //-------------------------------------------------------------------------
230 245
231 'M1': function () { 246 'M1': function () {
232 if (this._M1 == null) { 247 if (this._M1 == null) {
233 this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); 248 // this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K());
249
250 //http://srp.stanford.edu/design.html
251 //User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K)
252
253 this._M1 = this.stringHash(
254 "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" +
255 this.stringHash(this.C()) +
256 this.s().asString() +
257 this.A().asString() +
258 this.B().asString() +
259 this.K()
260 );
261//console.log("M1", this._M1);
234 } 262 }
235 263
236 return this._M1; 264 return this._M1;
237 }, 265 },
238 266
239 //------------------------------------------------------------------------- 267 //-------------------------------------------------------------------------
240 268
241 'M2': function () { 269 'M2': function () {
242 if (this._M2 == null) { 270 if (this._M2 == null) {
243 this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); 271 this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K());
272//console.log("M2", this._M2);
244 } 273 }
245 274
246 return this._M2; 275 return this._M2;
247 }, 276 },
248 277
249 //========================================================================= 278 //=========================================================================
250 279
251 'serverSideCredentialsWithSalt': function(aSalt) { 280 'serverSideCredentialsWithSalt': function(aSalt) {
252 var result; 281 var result;
253 var s, x, v; 282 var s, x, v;
254 283
255 s = aSalt; 284 s = aSalt;
256 x = this.stringHash(s + this.P()); 285 x = this.stringHash(s + this.P());
257 v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); 286 v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n());
258 287
259 result = {}; 288 result = {};
260 result['C'] = this.C(); 289 result['C'] = this.C();
261 result['s'] = s; 290 result['s'] = s;
262 result['v'] = v.asString(16); 291 result['v'] = v.asString(16);
263 292
264 return result; 293 return result;
265 }, 294 },
266 295
267 'serverSideCredentials': function() { 296 'serverSideCredentials': function() {
268 var result; 297 var result;
269 var s; 298 var s;
270 299
271 s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); 300 s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
272 301
273 result = this.serverSideCredentialsWithSalt(s); 302 result = this.serverSideCredentialsWithSalt(s);
274 303
275 return result; 304 return result;
276 }, 305 },
277 306
278 //========================================================================= 307 //=========================================================================
279/* 308/*
280 'computeServerSide_S': function(b) { 309 'computeServerSide_S': function(b) {
281 var result; 310 var result;
282 var v; 311 var v;
283 var bigint; 312 var bigint;
284 varsrp; 313 varsrp;
285 314
286 bigint = Clipperz.Crypto.BigInt; 315 bigint = Clipperz.Crypto.BigInt;
287 srp = Clipperz.Crypto.SRP; 316 srp = Clipperz.Crypto.SRP;
288 317
289 v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16); 318 v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16);
290 // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n()); 319 // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n());
291 result = bigint.powerModule( 320 result = bigint.powerModule(
292 bigint.multiply( 321 bigint.multiply(
293 this.A(), 322 this.A(),
294 bigint.powerModule(v, this.u(), srp.n()) 323 bigint.powerModule(v, this.u(), srp.n())
295 ), new Clipperz.Crypto.BigInt(b, 10), srp.n() 324 ), new Clipperz.Crypto.BigInt(b, 10), srp.n()
296 ); 325 );
297 326
298 return result; 327 return result;
299 }, 328 },
300*/ 329*/
301 //========================================================================= 330 //=========================================================================
302 331
303 'stringHash': function(aValue) { 332 'stringHash': function(aValue) {
304 varresult; 333 varresult;
305 334
306 result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); 335 result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
307 336
308 return result; 337 return result;
309 }, 338 },
310 339
311 //========================================================================= 340 //=========================================================================
312 __syntaxFix__: "syntax fix" 341 __syntaxFix__: "syntax fix"
313 342
314}); 343});
315 344
316//############################################################################# 345//#############################################################################
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 b806cb7..e5f68a8 100644
--- a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
+++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
@@ -1,788 +1,803 @@
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
24try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) { 24try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!"; 25 throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!";
26} 26}
27 27
28//============================================================================= 28//=============================================================================
29 29
30Clipperz.PM.Proxy.Offline.DataStore = function(args) { 30Clipperz.PM.Proxy.Offline.DataStore = function(args) {
31 args = args || {}; 31 args = args || {};
32 32
33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null); 33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null);
34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); 34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly);
35 this._shouldPayTolls = args.shouldPayTolls || false; 35 this._shouldPayTolls = args.shouldPayTolls || false;
36 36
37 this._tolls = {}; 37 this._tolls = {};
38 this._currentStaticConnection = null; 38 this._currentStaticConnection = null;
39 39
40 return this; 40 return this;
41} 41}
42 42
43Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { 43Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
44 44
45 //------------------------------------------------------------------------- 45 //-------------------------------------------------------------------------
46 46
47 'isReadOnly': function () { 47 'isReadOnly': function () {
48 return this._isReadOnly; 48 return this._isReadOnly;
49 }, 49 },
50 50
51 //------------------------------------------------------------------------- 51 //-------------------------------------------------------------------------
52 52
53 'shouldPayTolls': function() { 53 'shouldPayTolls': function() {
54 return this._shouldPayTolls; 54 return this._shouldPayTolls;
55 }, 55 },
56 56
57 //------------------------------------------------------------------------- 57 //-------------------------------------------------------------------------
58 58
59 'data': function () { 59 'data': function () {
60 return this._data; 60 return this._data;
61 }, 61 },
62 62
63 //------------------------------------------------------------------------- 63 //-------------------------------------------------------------------------
64 64
65 'tolls': function () { 65 'tolls': function () {
66 return this._tolls; 66 return this._tolls;
67 }, 67 },
68 68
69 //========================================================================= 69 //=========================================================================
70 70
71 'resetData': function() { 71 'resetData': function() {
72 this._data = { 72 this._data = {
73 'users': { 73 'users': {
74 'catchAllUser': { 74 'catchAllUser': {
75 __masterkey_test_value__: 'masterkey', 75 __masterkey_test_value__: 'masterkey',
76 s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00', 76 s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
77 v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00' 77 v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
78 } 78 }
79 } 79 }
80 }; 80 };
81 }, 81 },
82 82
83 //------------------------------------------------------------------------- 83 //-------------------------------------------------------------------------
84 84
85 'setupWithEncryptedData': function(someData) { 85 'setupWithEncryptedData': function(someData) {
86 this._data = Clipperz.Base.deepClone(someData); 86 this._data = Clipperz.Base.deepClone(someData);
87 }, 87 },
88 88
89 //------------------------------------------------------------------------- 89 //-------------------------------------------------------------------------
90 90
91 'setupWithData': function(someData) { 91 'setupWithData': function(someData) {
92 var deferredResult; 92 var deferredResult;
93 var resultData; 93 var resultData;
94 var i, c; 94 var i, c;
95 95
96//Clipperz.log(">>> Proxy.Test.setupWithData"); 96//Clipperz.log(">>> Proxy.Test.setupWithData");
97 resultData = this._data; 97 resultData = this._data;
98 98
99 deferredResult = new Clipperz.Async.Deferred("Proxy.Test.seupWithData", {trace:false}); 99 deferredResult = new Clipperz.Async.Deferred("Proxy.Test.seupWithData", {trace:false});
100 c = someData['users'].length; 100 c = someData['users'].length;
101 101
102 for (i=0; i<c; i++) { 102 for (i=0; i<c; i++) {
103 varnewConnection; 103 varnewConnection;
104 varrecordConfiguration; 104 varrecordConfiguration;
105 105
106 deferredResult.addMethod(this, 'userSerializedEncryptedData', someData['users'][i]); 106 deferredResult.addMethod(this, 'userSerializedEncryptedData', someData['users'][i]);
107 deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) { 107 deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) {
108 resultData['users'][aUserSerializationContext['credentials']['C']] = { 108 resultData['users'][aUserSerializationContext['credentials']['C']] = {
109 's': aUserSerializationContext['credentials']['s'], 109 's': aUserSerializationContext['credentials']['s'],
110 'v': aUserSerializationContext['credentials']['v'], 110 'v': aUserSerializationContext['credentials']['v'],
111 'version': aUserSerializationContext['data']['connectionVersion'], 111 'version': aUserSerializationContext['data']['connectionVersion'],
112 'userDetails': aUserSerializationContext['encryptedData']['user']['header'], 112 'userDetails': aUserSerializationContext['encryptedData']['user']['header'],
113 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'], 113 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'],
114 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'], 114 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'],
115 'lock': aUserSerializationContext['encryptedData']['user']['lock'], 115 'lock': aUserSerializationContext['encryptedData']['user']['lock'],
116 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records']) 116 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records'])
117 } 117 }
118 }, this)); 118 }, this));
119 } 119 }
120 120
121 deferredResult.addCallback(MochiKit.Base.bind(function() { 121 deferredResult.addCallback(MochiKit.Base.bind(function() {
122 this._data = resultData; 122 this._data = resultData;
123 }, this)); 123 }, this));
124 124
125 deferredResult.callback(); 125 deferredResult.callback();
126//Clipperz.log("<<< Proxy.Test.setupWithData"); 126//Clipperz.log("<<< Proxy.Test.setupWithData");
127 127
128 return deferredResult; 128 return deferredResult;
129 }, 129 },
130 130
131 //========================================================================= 131 //=========================================================================
132 132
133 'getTollForRequestType': function (aRequestType) { 133 'getTollForRequestType': function (aRequestType) {
134 varresult; 134 varresult;
135 vartargetValue; 135 vartargetValue;
136 var cost; 136 var cost;
137 137
138 targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); 138 targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
139 switch (aRequestType) { 139 switch (aRequestType) {
140 case 'REGISTER': 140 case 'REGISTER':
141 cost = 5; 141 cost = 5;
142 break; 142 break;
143 case 'CONNECT': 143 case 'CONNECT':
144 cost = 5; 144 cost = 5;
145 break; 145 break;
146 case 'MESSAGE': 146 case 'MESSAGE':
147 cost = 2; 147 cost = 2;
148 break; 148 break;
149 } 149 }
150 150
151 result = { 151 result = {
152 requestType: aRequestType, 152 requestType: aRequestType,
153 targetValue: targetValue, 153 targetValue: targetValue,
154 cost: cost 154 cost: cost
155 } 155 }
156 156
157 if (this.shouldPayTolls()) { 157 if (this.shouldPayTolls()) {
158 this.tolls()[targetValue] = result; 158 this.tolls()[targetValue] = result;
159 } 159 }
160 160
161 return result; 161 return result;
162 }, 162 },
163 163
164 //------------------------------------------------------------------------- 164 //-------------------------------------------------------------------------
165 165
166 'checkToll': function (aFunctionName, someParameters) { 166 'checkToll': function (aFunctionName, someParameters) {
167 if (this.shouldPayTolls()) { 167 if (this.shouldPayTolls()) {
168 var localToll; 168 var localToll;
169 vartollParameters; 169 vartollParameters;
170 170
171 tollParameters = someParameters['toll']; 171 tollParameters = someParameters['toll'];
172 localToll = this.tolls()[tollParameters['targetValue']]; 172 localToll = this.tolls()[tollParameters['targetValue']];
173 173
174 if (localToll != null) { 174 if (localToll != null) {
175 if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) { 175 if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) {
176 throw "Toll value too low."; 176 throw "Toll value too low.";
177 }; 177 };
178 } else { 178 } else {
179 throw "Missing toll"; 179 throw "Missing toll";
180 } 180 }
181 } 181 }
182 }, 182 },
183 183
184 //========================================================================= 184 //=========================================================================
185 185
186 'currentStaticConnection': function () { 186 'currentStaticConnection': function () {
187 if (this._currentStaticConnection == null) { 187 if (this._currentStaticConnection == null) {
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'] = (Clipperz.Crypto.SRP.k().multiply(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, S, A, K, M1;
342 342 var stringHash = function (aValue) {
343 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
344 };
345
343 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); 346 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);
345 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16); 347 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16);
348 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10))).toHexString(), 16);
349 s = new Clipperz.Crypto.BigInt(aConnection['userData']['s'], 16);
346 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); 350 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n());
347 351
348 K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2); 352 K = stringHash(S.asString(10));
349 353
350 M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2); 354 M1 = stringHash(
355 "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" +
356 stringHash(aConnection['C']) +
357 s.asString(10) +
358 A.asString(10) +
359 aConnection['B'].asString(10) +
360 K
361 );
351 if (someParameters.parameters.M1 == M1) { 362 if (someParameters.parameters.M1 == M1) {
352 var M2; 363 var M2;
353 364
354 M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2); 365 M2 = stringHash(
366 A.asString(10) +
367 someParameters.parameters.M1 +
368 K
369 );
355 result['M2'] = M2; 370 result['M2'] = M2;
356 } else { 371 } else {
357 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); 372 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
358 } 373 }
359 374
360 nextTollRequestType = 'MESSAGE'; 375 nextTollRequestType = 'MESSAGE';
361 } else if (someParameters.message == "oneTimePassword") { 376 } else if (someParameters.message == "oneTimePassword") {
362 var otpData; 377 var otpData;
363 378
364 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; 379 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey];
365 380
366 try { 381 try {
367 if (typeof(otpData) != 'undefined') { 382 if (typeof(otpData) != 'undefined') {
368 if (otpData['status'] == 'ACTIVE') { 383 if (otpData['status'] == 'ACTIVE') {
369 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { 384 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) {
370 result = { 385 result = {
371 'data': otpData['data'], 386 'data': otpData['data'],
372 'version':otpData['version'] 387 'version':otpData['version']
373 } 388 }
374 389
375 otpData['status'] = 'REQUESTED'; 390 otpData['status'] = 'REQUESTED';
376 } else { 391 } else {
377 otpData['status'] = 'DISABLED'; 392 otpData['status'] = 'DISABLED';
378 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; 393 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum";
379 } 394 }
380 } else { 395 } else {
381 throw "The requested One Time Password was not active"; 396 throw "The requested One Time Password was not active";
382 } 397 }
383 } else { 398 } else {
384 throw "The requested One Time Password has not been found" 399 throw "The requested One Time Password has not been found"
385 } 400 }
386 } catch (exception) { 401 } catch (exception) {
387 result = { 402 result = {
388 'data': Clipperz.PM.Crypto.randomKey(), 403 'data': Clipperz.PM.Crypto.randomKey(),
389 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion 404 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion
390 } 405 }
391 } 406 }
392 nextTollRequestType = 'CONNECT'; 407 nextTollRequestType = 'CONNECT';
393 } else { 408 } else {
394 Clipperz.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); 409 Clipperz.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message);
395 } 410 }
396 411
397 result = { 412 result = {
398 result: result, 413 result: result,
399 toll: this.getTollForRequestType(nextTollRequestType) 414 toll: this.getTollForRequestType(nextTollRequestType)
400 } 415 }
401 416
402 return result; 417 return result;
403 }, 418 },
404 419
405 //------------------------------------------------------------------------- 420 //-------------------------------------------------------------------------
406 421
407 '_message': function(aConnection, someParameters) { 422 '_message': function(aConnection, someParameters) {
408 var result; 423 var result;
409 424
410 result = {}; 425 result = {};
411 426
412 //===================================================================== 427 //=====================================================================
413 // 428 //
414 // R E A D - O N L Y M e t h o d s 429 // R E A D - O N L Y M e t h o d s
415 // 430 //
416 //===================================================================== 431 //=====================================================================
417 if (someParameters.message == 'getUserDetails') { 432 if (someParameters.message == 'getUserDetails') {
418 var recordsStats; 433 var recordsStats;
419 var recordReference; 434 var recordReference;
420 435
421 recordsStats = {}; 436 recordsStats = {};
422 for (recordReference in aConnection['userData']['records']) { 437 for (recordReference in aConnection['userData']['records']) {
423 recordsStats[recordReference] = { 438 recordsStats[recordReference] = {
424 'updateDate': aConnection['userData']['records'][recordReference]['updateDate'] 439 'updateDate': aConnection['userData']['records'][recordReference]['updateDate']
425 } 440 }
426 } 441 }
427 442
428 result['header'] = this.userDetails(aConnection); 443 result['header'] = this.userDetails(aConnection);
429 result['statistics'] = this.statistics(aConnection); 444 result['statistics'] = this.statistics(aConnection);
430 result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords']; 445 result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords'];
431 result['version'] = aConnection['userData']['userDetailsVersion']; 446 result['version'] = aConnection['userData']['userDetailsVersion'];
432 result['recordsStats'] = recordsStats; 447 result['recordsStats'] = recordsStats;
433 448
434 if (this.isReadOnly() == false) { 449 if (this.isReadOnly() == false) {
435 varlock; 450 varlock;
436 451
437 if (typeof(aConnection['userData']['lock']) == 'undefined') { 452 if (typeof(aConnection['userData']['lock']) == 'undefined') {
438 aConnection['userData']['lock'] = "<<LOCK>>"; 453 aConnection['userData']['lock'] = "<<LOCK>>";
439 } 454 }
440 455
441 result['lock'] = aConnection['userData']['lock']; 456 result['lock'] = aConnection['userData']['lock'];
442 } 457 }
443 458
444 //===================================================================== 459 //=====================================================================
445 } else if (someParameters.message == 'getRecordDetail') { 460 } else if (someParameters.message == 'getRecordDetail') {
446/* 461/*
447 varrecordData; 462 varrecordData;
448 var currentVersionData; 463 var currentVersionData;
449 464
450 recordData = this.userData()['records'][someParameters['parameters']['reference']]; 465 recordData = this.userData()['records'][someParameters['parameters']['reference']];
451 result['reference'] = someParameters['parameters']['reference']; 466 result['reference'] = someParameters['parameters']['reference'];
452 result['data'] = recordData['data']; 467 result['data'] = recordData['data'];
453 result['version'] = recordData['version']; 468 result['version'] = recordData['version'];
454 result['creationData'] = recordData['creationDate']; 469 result['creationData'] = recordData['creationDate'];
455 result['updateDate'] = recordData['updateDate']; 470 result['updateDate'] = recordData['updateDate'];
456 result['accessDate'] = recordData['accessDate']; 471 result['accessDate'] = recordData['accessDate'];
457 472
458 currentVersionData = recordData['versions'][recordData['currentVersion']]; 473 currentVersionData = recordData['versions'][recordData['currentVersion']];
459 474
460 result['currentVersion'] = {}; 475 result['currentVersion'] = {};
461 result['currentVersion']['reference'] = recordData['currentVersion']; 476 result['currentVersion']['reference'] = recordData['currentVersion'];
462 result['currentVersion']['version'] = currentVersionData['version']; 477 result['currentVersion']['version'] = currentVersionData['version'];
463 result['currentVersion']['header'] = currentVersionData['header']; 478 result['currentVersion']['header'] = currentVersionData['header'];
464 result['currentVersion']['data'] = currentVersionData['data']; 479 result['currentVersion']['data'] = currentVersionData['data'];
465 result['currentVersion']['creationData'] = currentVersionData['creationDate']; 480 result['currentVersion']['creationData'] = currentVersionData['creationDate'];
466 result['currentVersion']['updateDate'] = currentVersionData['updateDate']; 481 result['currentVersion']['updateDate'] = currentVersionData['updateDate'];
467 result['currentVersion']['accessDate'] = currentVersionData['accessDate']; 482 result['currentVersion']['accessDate'] = currentVersionData['accessDate'];
468 if (typeof(currentVersionData['previousVersion']) != 'undefined') { 483 if (typeof(currentVersionData['previousVersion']) != 'undefined') {
469 result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; 484 result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey'];
470 result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; 485 result['currentVersion']['previousVersion'] = currentVersionData['previousVersion'];
471 } 486 }
472*/ 487*/
473 MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]); 488 MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]);
474 result['reference'] = someParameters['parameters']['reference']; 489 result['reference'] = someParameters['parameters']['reference'];
475 490
476 //===================================================================== 491 //=====================================================================
477 // 492 //
478 // R E A D - W R I T E M e t h o d s 493 // R E A D - W R I T E M e t h o d s
479 // 494 //
480 //===================================================================== 495 //=====================================================================
481 } else if (someParameters.message == 'upgradeUserCredentials') { 496 } else if (someParameters.message == 'upgradeUserCredentials') {
482 if (this.isReadOnly() == false) { 497 if (this.isReadOnly() == false) {
483 var parameters; 498 var parameters;
484 var credentials; 499 var credentials;
485 500
486 parameters = someParameters['parameters']; 501 parameters = someParameters['parameters'];
487 credentials = parameters['credentials']; 502 credentials = parameters['credentials'];
488 503
489 if ((credentials['C'] == null) 504 if ((credentials['C'] == null)
490 ||(credentials['s'] == null) 505 ||(credentials['s'] == null)
491 ||(credentials['v'] == null) 506 ||(credentials['v'] == null)
492 ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) 507 ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion)
493 ) { 508 ) {
494 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; 509 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed;
495 } else { 510 } else {
496 varoldCValue; 511 varoldCValue;
497 oldCValue = aConnection['C']; 512 oldCValue = aConnection['C'];
498 513
499 this.data()['users'][credentials['C']] = aConnection['userData']; 514 this.data()['users'][credentials['C']] = aConnection['userData'];
500 aConnection['C'] = credentials['C']; 515 aConnection['C'] = credentials['C'];
501 516
502 aConnection['userData']['s'] = credentials['s']; 517 aConnection['userData']['s'] = credentials['s'];
503 aConnection['userData']['v'] = credentials['v']; 518 aConnection['userData']['v'] = credentials['v'];
504 aConnection['userData']['version'] = credentials['version']; 519 aConnection['userData']['version'] = credentials['version'];
505 520
506 aConnection['userData']['userDetails'] = parameters['user']['header']; 521 aConnection['userData']['userDetails'] = parameters['user']['header'];
507 aConnection['userData']['userDetailsVersion'] = parameters['user']['version']; 522 aConnection['userData']['userDetailsVersion'] = parameters['user']['version'];
508 aConnection['userData']['statistics'] = parameters['user']['statistics']; 523 aConnection['userData']['statistics'] = parameters['user']['statistics'];
509 524
510 aConnection['userData']['lock'] = parameters['user']['lock']; 525 aConnection['userData']['lock'] = parameters['user']['lock'];
511 526
512 delete this.data()['users'][oldCValue]; 527 delete this.data()['users'][oldCValue];
513 528
514 result = {result:"done", parameters:parameters}; 529 result = {result:"done", parameters:parameters};
515 } 530 }
516 } else { 531 } else {
517 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 532 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
518 } 533 }
519 //===================================================================== 534 //=====================================================================
520 /* } else if (someParameters.message == 'updateData') { 535 /* } else if (someParameters.message == 'updateData') {
521 if (this.isReadOnly() == false) { 536 if (this.isReadOnly() == false) {
522 var i, c; 537 var i, c;
523 538
524 if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { 539 if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) {
525 throw "the lock attribute is not processed correctly" 540 throw "the lock attribute is not processed correctly"
526 } 541 }
527 542
528 this.userData()['userDetails'] = someParameters['parameters']['user']['header']; 543 this.userData()['userDetails'] = someParameters['parameters']['user']['header'];
529 this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; 544 this.userData()['statistics'] = someParameters['parameters']['user']['statistics'];
530 this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; 545 this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version'];
531 546
532 c = someParameters['parameters']['records'].length; 547 c = someParameters['parameters']['records'].length;
533 for (i=0; i<c; i++) { 548 for (i=0; i<c; i++) {
534 var currentRecord; 549 var currentRecord;
535 var currentRecordData; 550 var currentRecordData;
536 551
537 currentRecordData = someParameters['parameters']['records'][i]; 552 currentRecordData = someParameters['parameters']['records'][i];
538 currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; 553 currentRecord = this.userData()['records'][currentRecordData['record']['reference']];
539 554
540 if (currentRecord == null) { 555 if (currentRecord == null) {
541 } 556 }
542 557
543 currentRecord['data'] = currentRecordData['record']['data']; 558 currentRecord['data'] = currentRecordData['record']['data'];
544 currentRecord['version'] = currentRecordData['record']['version']; 559 currentRecord['version'] = currentRecordData['record']['version'];
545 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; 560 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference'];
546 561
547 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { 562 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = {
548 'data': currentRecordData['currentRecordVersion']['data'], 563 'data': currentRecordData['currentRecordVersion']['data'],
549 'version': currentRecordData['currentRecordVersion']['version'], 564 'version': currentRecordData['currentRecordVersion']['version'],
550 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], 565 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'],
551 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'] 566 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey']
552 } 567 }
553 } 568 }
554 569
555 this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); 570 this.userData()['lock'] = Clipperz.PM.Crypto.randomKey();
556 result['lock'] = this.userData()['lock']; 571 result['lock'] = this.userData()['lock'];
557 result['result'] = 'done'; 572 result['result'] = 'done';
558 } else { 573 } else {
559 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 574 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
560 } 575 }
561 */ //===================================================================== 576 */ //=====================================================================
562 } else if (someParameters.message == 'saveChanges') { 577 } else if (someParameters.message == 'saveChanges') {
563 if (this.isReadOnly() == false) { 578 if (this.isReadOnly() == false) {
564 var i, c; 579 var i, c;
565 580
566 if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) { 581 if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) {
567 throw "the lock attribute is not processed correctly" 582 throw "the lock attribute is not processed correctly"
568 } 583 }
569 584
570 aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header']; 585 aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header'];
571 aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics']; 586 aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics'];
572 aConnection['userData']['userDetailsVersion']= someParameters['parameters']['user']['version']; 587 aConnection['userData']['userDetailsVersion']= someParameters['parameters']['user']['version'];
573 588
574 c = someParameters['parameters']['records']['updated'].length; 589 c = someParameters['parameters']['records']['updated'].length;
575 for (i=0; i<c; i++) { 590 for (i=0; i<c; i++) {
576 var currentRecord; 591 var currentRecord;
577 var currentRecordData; 592 var currentRecordData;
578 593
579 currentRecordData = someParameters['parameters']['records']['updated'][i]; 594 currentRecordData = someParameters['parameters']['records']['updated'][i];
580 currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']]; 595 currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']];
581 596
582 if ( 597 if (
583 (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined') 598 (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined')
584 && 599 &&
585 (typeof(currentRecordData['currentRecordVersion']) == 'undefined') 600 (typeof(currentRecordData['currentRecordVersion']) == 'undefined')
586 ) { 601 ) {
587 throw "Record added without a recordVersion"; 602 throw "Record added without a recordVersion";
588 } 603 }
589 604
590 if (currentRecord == null) { 605 if (currentRecord == null) {
591 currentRecord = {}; 606 currentRecord = {};
592 currentRecord['versions'] = {}; 607 currentRecord['versions'] = {};
593 currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); 608 currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
594 currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); 609 currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
595 610
596 aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord; 611 aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord;
597 } 612 }
598 613
599 currentRecord['data'] = currentRecordData['record']['data']; 614 currentRecord['data'] = currentRecordData['record']['data'];
600 currentRecord['version']= currentRecordData['record']['version']; 615 currentRecord['version']= currentRecordData['record']['version'];
601 currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); 616 currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
602 617
603 if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') { 618 if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') {
604 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; 619 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference'];
605 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { 620 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = {
606 'data': currentRecordData['currentRecordVersion']['data'], 621 'data': currentRecordData['currentRecordVersion']['data'],
607 'version': currentRecordData['currentRecordVersion']['version'], 622 'version': currentRecordData['currentRecordVersion']['version'],
608 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], 623 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'],
609 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'], 624 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'],
610 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), 625 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
611 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), 626 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
612 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()) 627 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date())
613 } 628 }
614 } 629 }
615 } 630 }
616 631
617 c = someParameters['parameters']['records']['deleted'].length; 632 c = someParameters['parameters']['records']['deleted'].length;
618 for (i=0; i<c; i++) { 633 for (i=0; i<c; i++) {
619 var currentRecordReference; 634 var currentRecordReference;
620 635
621 currentRecordReference = someParameters['parameters']['records']['deleted'][i]; 636 currentRecordReference = someParameters['parameters']['records']['deleted'][i];
622 delete aConnection['userData']['records'][currentRecordReference]; 637 delete aConnection['userData']['records'][currentRecordReference];
623 } 638 }
624 639
625 aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey(); 640 aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey();
626 result['lock'] = aConnection['userData']['lock']; 641 result['lock'] = aConnection['userData']['lock'];
627 result['result'] = 'done'; 642 result['result'] = 'done';
628 } else { 643 } else {
629 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 644 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
630 } 645 }
631 646
632 //===================================================================== 647 //=====================================================================
633 // 648 //
634 // U N H A N D L E D M e t h o d 649 // U N H A N D L E D M e t h o d
635 // 650 //
636 //===================================================================== 651 //=====================================================================
637 } else { 652 } else {
638 Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message); 653 Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message);
639 } 654 }
640 655
641 result = { 656 result = {
642 result: result, 657 result: result,
643 toll: this.getTollForRequestType('MESSAGE') 658 toll: this.getTollForRequestType('MESSAGE')
644 } 659 }
645 660
646 // return MochiKit.Async.succeed(result); 661 // return MochiKit.Async.succeed(result);
647 return result; 662 return result;
648 }, 663 },
649 664
650 //------------------------------------------------------------------------- 665 //-------------------------------------------------------------------------
651 666
652 '_logout': function(someParameters) { 667 '_logout': function(someParameters) {
653 // return MochiKit.Async.succeed({result: 'done'}); 668 // return MochiKit.Async.succeed({result: 'done'});
654 return {result: 'done'}; 669 return {result: 'done'};
655 }, 670 },
656 671
657 //========================================================================= 672 //=========================================================================
658 //######################################################################### 673 //#########################################################################
659 674
660 'isTestData': function(aConnection) { 675 'isTestData': function(aConnection) {
661 return (typeof(aConnection['userData']['__masterkey_test_value__']) != 'undefined'); 676 return (typeof(aConnection['userData']['__masterkey_test_value__']) != 'undefined');
662 }, 677 },
663 678
664 'userDetails': function(aConnection) { 679 'userDetails': function(aConnection) {
665 var result; 680 var result;
666 681
667 if (this.isTestData(aConnection)) { 682 if (this.isTestData(aConnection)) {
668 var serializedHeader; 683 var serializedHeader;
669 var version; 684 var version;
670 685
671//Clipperz.logDebug("### test data"); 686//Clipperz.logDebug("### test data");
672 version = aConnection['userData']['userDetailsVersion']; 687 version = aConnection['userData']['userDetailsVersion'];
673 serializedHeader = Clipperz.Base.serializeJSON(aConnection['userData']['userDetails']); 688 serializedHeader = Clipperz.Base.serializeJSON(aConnection['userData']['userDetails']);
674 result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedHeader); 689 result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedHeader);
675 } else { 690 } else {
676//Clipperz.logDebug("### NOT test data"); 691//Clipperz.logDebug("### NOT test data");
677 result = aConnection['userData']['userDetails']; 692 result = aConnection['userData']['userDetails'];
678 } 693 }
679 694
680 return result; 695 return result;
681 }, 696 },
682 697
683 'statistics': function(aConnection) { 698 'statistics': function(aConnection) {
684 var result; 699 var result;
685 700
686 if (aConnection['userData']['statistics'] != null) { 701 if (aConnection['userData']['statistics'] != null) {
687 if (this.isTestData(aConnection)) { 702 if (this.isTestData(aConnection)) {
688 var serializedStatistics; 703 var serializedStatistics;
689 var version; 704 var version;
690 705
691 version = aConnection['userData']['userDetailsVersion']; 706 version = aConnection['userData']['userDetailsVersion'];
692 serializedStatistics = Clipperz.Base.serializeJSON(aConnection['userData']['statistics']); 707 serializedStatistics = Clipperz.Base.serializeJSON(aConnection['userData']['statistics']);
693 result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedStatistics); 708 result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedStatistics);
694 } else { 709 } else {
695 result = aConnection['userData']['statistics']; 710 result = aConnection['userData']['statistics'];
696 } 711 }
697 } else { 712 } else {
698 result = null; 713 result = null;
699 } 714 }
700 715
701 return result; 716 return result;
702 }, 717 },
703 718
704/* 719/*
705 'userSerializedEncryptedData': function(someData) { 720 'userSerializedEncryptedData': function(someData) {
706 var deferredResult; 721 var deferredResult;
707 var deferredContext; 722 var deferredContext;
708 723
709 deferredContext = { 'data': someData }; 724 deferredContext = { 'data': someData };
710 725
711 deferredResult = new Clipperz.Async.Deferred('Proxy.Test.serializeUserEncryptedData', {trace:false}); 726 deferredResult = new Clipperz.Async.Deferred('Proxy.Test.serializeUserEncryptedData', {trace:false});
712 deferredResult.addCallback(MochiKit.Base.bind(function(aDeferredContext) { 727 deferredResult.addCallback(MochiKit.Base.bind(function(aDeferredContext) {
713 aDeferredContext['user'] = this.createUserUsingConfigurationData(aDeferredContext['data']); 728 aDeferredContext['user'] = this.createUserUsingConfigurationData(aDeferredContext['data']);
714 return aDeferredContext; 729 return aDeferredContext;
715 }, this)); 730 }, this));
716 deferredResult.addCallback(function(aDeferredContext) { 731 deferredResult.addCallback(function(aDeferredContext) {
717 // return aDeferredContext['user'].encryptedDataUsingVersion(aDeferredContext['data']['version']); 732 // return aDeferredContext['user'].encryptedDataUsingVersion(aDeferredContext['data']['version']);
718 return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); 733 return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']);
719 }); 734 });
720 deferredResult.addCallback(function(aUserEncryptedData) { 735 deferredResult.addCallback(function(aUserEncryptedData) {
721 deferredContext['encryptedData'] = aUserEncryptedData; 736 deferredContext['encryptedData'] = aUserEncryptedData;
722 return deferredContext; 737 return deferredContext;
723 }); 738 });
724 deferredResult.addCallback(function(aDeferredContext) { 739 deferredResult.addCallback(function(aDeferredContext) {
725 var connection; 740 var connection;
726 741
727 connection = new Clipperz.PM.Connection.communicationProtocol.versions[aDeferredContext['data']['connectionVersion']]() 742 connection = new Clipperz.PM.Connection.communicationProtocol.versions[aDeferredContext['data']['connectionVersion']]()
728 aDeferredContext['credentials'] = connection.serverSideUserCredentials(aDeferredContext['user'].username(),aDeferredContext['user'].passphrase()); 743 aDeferredContext['credentials'] = connection.serverSideUserCredentials(aDeferredContext['user'].username(),aDeferredContext['user'].passphrase());
729 744
730 return aDeferredContext; 745 return aDeferredContext;
731 }); 746 });
732 747
733 // deferredResult.addCallback(function(aDeferredContext) { 748 // deferredResult.addCallback(function(aDeferredContext) {
734 // return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); 749 // return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']);
735 // }, deferredContext); 750 // }, deferredContext);
736 // deferredResult.addCallback(function(aUserSerializedData) { 751 // deferredResult.addCallback(function(aUserSerializedData) {
737 // }); 752 // });
738// 753//
739 // deferredResult.addCallback(MochiKit.Async.succeed, deferredContext); 754 // deferredResult.addCallback(MochiKit.Async.succeed, deferredContext);
740 deferredResult.callback(deferredContext); 755 deferredResult.callback(deferredContext);
741 756
742 return deferredResult; 757 return deferredResult;
743 }, 758 },
744 759
745 'createUserUsingConfigurationData': function(someData) { 760 'createUserUsingConfigurationData': function(someData) {
746 var result; 761 var result;
747 var user; 762 var user;
748 var recordLabel; 763 var recordLabel;
749 764
750 user = new Clipperz.PM.DataModel.User(); 765 user = new Clipperz.PM.DataModel.User();
751 user.initForTests(); 766 user.initForTests();
752 user.setUsername(someData['username']); 767 user.setUsername(someData['username']);
753 user.setPassphrase(someData['passphrase']); 768 user.setPassphrase(someData['passphrase']);
754 769
755 for (recordLabel in someData['records']) { 770 for (recordLabel in someData['records']) {
756 var recordData; 771 var recordData;
757 var record; 772 var record;
758 var i, c; 773 var i, c;
759 774
760 recordData = someData['records'][recordLabel]; 775 recordData = someData['records'][recordLabel];
761 record = new Clipperz.PM.DataModel.Record({user:user, label:recordLabel}); 776 record = new Clipperz.PM.DataModel.Record({user:user, label:recordLabel});
762 record.setNotes(recordData['notes']); 777 record.setNotes(recordData['notes']);
763 778
764 c = recordData['fields'].length; 779 c = recordData['fields'].length;
765 for (i=0; i<c; i++) { 780 for (i=0; i<c; i++) {
766 var recordField; 781 var recordField;
767 782
768 recordField = new Clipperz.PM.DataModel.RecordField(); 783 recordField = new Clipperz.PM.DataModel.RecordField();
769 recordField.setLabel(recordData['fields'][i]['name']); 784 recordField.setLabel(recordData['fields'][i]['name']);
770 recordField.setValue(recordData['fields'][i]['value']); 785 recordField.setValue(recordData['fields'][i]['value']);
771 recordField.setType(recordData['fields'][i]['type']); 786 recordField.setType(recordData['fields'][i]['type']);
772 record.addField(recordField); 787 record.addField(recordField);
773 } 788 }
774 user.addRecord(record, true); 789 user.addRecord(record, true);
775 } 790 }
776 791
777 result = user; 792 result = user;
778 793
779 return result; 794 return result;
780 }, 795 },
781*/ 796*/
782 //========================================================================= 797 //=========================================================================
783 __syntaxFix__: "syntax fix" 798 __syntaxFix__: "syntax fix"
784}); 799});
785 800
786Clipperz.PM.Proxy.Offline.DataStore['exception'] = { 801Clipperz.PM.Proxy.Offline.DataStore['exception'] = {
787 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly") 802 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly")
788}; \ No newline at end of file 803}; \ No newline at end of file