summaryrefslogtreecommitdiff
path: root/frontend
Unidiff
Diffstat (limited to 'frontend') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/Clipperz/Base.js28
-rw-r--r--frontend/beta/js/Clipperz/Crypto/PRNG.js130
-rw-r--r--frontend/beta/js/Clipperz/Crypto/SRP.js67
-rw-r--r--frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js2
-rw-r--r--frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js4
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js22
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js2
-rw-r--r--frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js47
-rw-r--r--frontend/delta/js/Clipperz/Crypto/PRNG.js128
-rw-r--r--frontend/delta/js/Clipperz/Crypto/SRP.js53
-rw-r--r--frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js27
-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
14 files changed, 390 insertions, 336 deletions
diff --git a/frontend/beta/js/Clipperz/Base.js b/frontend/beta/js/Clipperz/Base.js
index cf40314..1c6faa1 100644
--- a/frontend/beta/js/Clipperz/Base.js
+++ b/frontend/beta/js/Clipperz/Base.js
@@ -237,24 +237,52 @@ MochiKit.Base.update(Clipperz.Base, {
237 237
238 if (Clipperz.Base.objectType(aValue) == 'string') { 238 if (Clipperz.Base.objectType(aValue) == 'string') {
239 result = aValue; 239 result = aValue;
240 result = result.replace(/</img,"&lt;"); 240 result = result.replace(/</img,"&lt;");
241 result = result.replace(/>/img,"&gt;"); 241 result = result.replace(/>/img,"&gt;");
242 } else { 242 } else {
243 result = aValue; 243 result = aValue;
244 } 244 }
245 245
246 return result; 246 return result;
247 }, 247 },
248 248
249 'javascriptInjectionPattern': new RegExp("javascript:\/\/\"", "g"),
250
251 'sanitizeUrl': function(aValue) {
252 varresult;
253
254 if ((aValue != null) && this.javascriptInjectionPattern.test(aValue)) {
255 result = aValue.replace(this.javascriptInjectionPattern, '');
256 console.log("sanitized url", aValue, result);
257 } else {
258 result = aValue;
259 }
260
261 return result;
262 },
263
264 'sanitizeFavicon': function(aValue) {
265 varresult;
266
267 if ((aValue != null) && this.javascriptInjectionPattern.test(aValue)) {
268 result = aValue.replace(this.javascriptInjectionPattern, '');
269 console.log("sanitized favicon", aValue, result);
270 } else {
271 result = aValue;
272 }
273
274 return result;
275 },
276
249 //------------------------------------------------------------------------- 277 //-------------------------------------------------------------------------
250 278
251 'exception': { 279 'exception': {
252 'AbstractMethod': new MochiKit.Base.NamedError("Clipperz.Base.exception.AbstractMethod"), 280 'AbstractMethod': new MochiKit.Base.NamedError("Clipperz.Base.exception.AbstractMethod"),
253 'UnknownType': new MochiKit.Base.NamedError("Clipperz.Base.exception.UnknownType"), 281 'UnknownType': new MochiKit.Base.NamedError("Clipperz.Base.exception.UnknownType"),
254 'VulnerabilityIssue':new MochiKit.Base.NamedError("Clipperz.Base.exception.VulnerabilityIssue") 282 'VulnerabilityIssue':new MochiKit.Base.NamedError("Clipperz.Base.exception.VulnerabilityIssue")
255 }, 283 },
256 284
257 //------------------------------------------------------------------------- 285 //-------------------------------------------------------------------------
258 __syntaxFix__: "syntax fix" 286 __syntaxFix__: "syntax fix"
259 287
260}); 288});
diff --git a/frontend/beta/js/Clipperz/Crypto/PRNG.js b/frontend/beta/js/Clipperz/Crypto/PRNG.js
index b5c3f8a..6fdeca4 100644
--- a/frontend/beta/js/Clipperz/Crypto/PRNG.js
+++ b/frontend/beta/js/Clipperz/Crypto/PRNG.js
@@ -188,30 +188,24 @@ Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new C
188 188
189 this.updateGeneratorWithValue(entropyByte); 189 this.updateGeneratorWithValue(entropyByte);
190 setTimeout(this.collectEntropy, intervalTime); 190 setTimeout(this.collectEntropy, intervalTime);
191 }, 191 },
192 192
193 //------------------------------------------------------------------------- 193 //-------------------------------------------------------------------------
194 194
195 'numberOfRandomBits': function() { 195 'numberOfRandomBits': function() {
196 return 5; 196 return 5;
197 }, 197 },
198 198
199 //------------------------------------------------------------------------- 199 //-------------------------------------------------------------------------
200
201 'pollingFrequency': function() {
202 return 10;
203 },
204
205 //-------------------------------------------------------------------------
206 __syntaxFix__: "syntax fix" 200 __syntaxFix__: "syntax fix"
207}); 201});
208 202
209//***************************************************************************** 203//*****************************************************************************
210 204
211Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { 205Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) {
212 args = args || {}; 206 args = args || {};
213 207
214 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 208 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
215 209
216 this._numberOfBitsToCollectAtEachEvent = 4; 210 this._numberOfBitsToCollectAtEachEvent = 4;
217 this._randomBitsCollector = 0; 211 this._randomBitsCollector = 0;
@@ -236,30 +230,30 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
236 return this._randomBitsCollector; 230 return this._randomBitsCollector;
237 }, 231 },
238 232
239 'setRandomBitsCollector': function(aValue) { 233 'setRandomBitsCollector': function(aValue) {
240 this._randomBitsCollector = aValue; 234 this._randomBitsCollector = aValue;
241 }, 235 },
242 236
243 'appendRandomBitsToRandomBitsCollector': function(aValue) { 237 'appendRandomBitsToRandomBitsCollector': function(aValue) {
244 var collectedBits; 238 var collectedBits;
245 var numberOfRandomBitsCollected; 239 var numberOfRandomBitsCollected;
246 240
247 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); 241 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
248 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); 242 collectedBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
249 this.setRandomBitsCollector(collectetBits); 243 this.setRandomBitsCollector(collectedBits);
250 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); 244 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent();
251 245
252 if (numberOfRandomBitsCollected == 8) { 246 if (numberOfRandomBitsCollected == 8) {
253 this.updateGeneratorWithValue(collectetBits); 247 this.updateGeneratorWithValue(collectedBits);
254 numberOfRandomBitsCollected = 0; 248 numberOfRandomBitsCollected = 0;
255 this.setRandomBitsCollector(0); 249 this.setRandomBitsCollector(0);
256 } 250 }
257 251
258 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) 252 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
259 }, 253 },
260 254
261 //------------------------------------------------------------------------- 255 //-------------------------------------------------------------------------
262 256
263 'numberOfRandomBitsCollected': function() { 257 'numberOfRandomBitsCollected': function() {
264 return this._numberOfRandomBitsCollected; 258 return this._numberOfRandomBitsCollected;
265 }, 259 },
@@ -280,114 +274,72 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
280 mouseLocation = anEvent.mouse().client; 274 mouseLocation = anEvent.mouse().client;
281 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); 275 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask);
282 this.appendRandomBitsToRandomBitsCollector(randomBit) 276 this.appendRandomBitsToRandomBitsCollector(randomBit)
283 }, 277 },
284 278
285 //------------------------------------------------------------------------- 279 //-------------------------------------------------------------------------
286 280
287 'numberOfRandomBits': function() { 281 'numberOfRandomBits': function() {
288 return 1; 282 return 1;
289 }, 283 },
290 284
291 //------------------------------------------------------------------------- 285 //-------------------------------------------------------------------------
292
293 'pollingFrequency': function() {
294 return 10;
295 },
296
297 //-------------------------------------------------------------------------
298 __syntaxFix__: "syntax fix" 286 __syntaxFix__: "syntax fix"
299}); 287});
300 288
301//***************************************************************************** 289//*****************************************************************************
302 290
303Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) { 291Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) {
304 args = args || {}; 292 args = args || {};
305 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
306 293
307 this._randomBitsCollector = 0; 294 this._intervalTime = args.intervalTime || 1000;
308 this._numberOfRandomBitsCollected = 0; 295 this._browserCrypto = args.browserCrypto;
309 296
310 MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy'); 297 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
311 298
299 this.collectEntropy();
312 return this; 300 return this;
313} 301}
314 302
315Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 303Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
316
317 //-------------------------------------------------------------------------
318
319 'randomBitsCollector': function() {
320 return this._randomBitsCollector;
321 },
322 304
323 'setRandomBitsCollector': function(aValue) { 305 'intervalTime': function() {
324 this._randomBitsCollector = aValue; 306 return this._intervalTime;
325 }, 307 },
326 308
327 'appendRandomBitToRandomBitsCollector': function(aValue) { 309 'browserCrypto': function () {
328 var collectedBits; 310 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 }, 311 },
344 312
345 //------------------------------------------------------------------------- 313 //-------------------------------------------------------------------------
346 314
347 'numberOfRandomBitsCollected': function() { 315 'collectEntropy': function() {
348 return this._numberOfRandomBitsCollected; 316 varbytesToCollect;
349 },
350
351 'setNumberOfRandomBitsCollected': function(aValue) {
352 this._numberOfRandomBitsCollected = aValue;
353 },
354 317
355 //------------------------------------------------------------------------- 318 if (this.boostMode() == true) {
319 bytesToCollect = 64;
320 } else {
321 bytesToCollect = 8;
322 }
356 323
357 'collectEntropy': function(anEvent) { 324 var randomValuesArray = new Uint8Array(bytesToCollect);
358/* 325 this.browserCrypto().getRandomValues(randomValuesArray);
359 var mouseLocation; 326 for (var i = 0; i < randomValuesArray.length; i++) {
360 var randomBit; 327 this.updateGeneratorWithValue(randomValuesArray[i]);
361 328 }
362 mouseLocation = anEvent.mouse().client;
363
364 randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1);
365 this.appendRandomBitToRandomBitsCollector(randomBit);
366*/
367 },
368
369 //-------------------------------------------------------------------------
370 329
371 'numberOfRandomBits': function() { 330 setTimeout(this.collectEntropy, this.intervalTime());
372 return 1;
373 }, 331 },
374 332
375 //------------------------------------------------------------------------- 333 //-------------------------------------------------------------------------
376
377 'pollingFrequency': function() {
378 return 10;
379 },
380
381 //-------------------------------------------------------------------------
382 __syntaxFix__: "syntax fix" 334 __syntaxFix__: "syntax fix"
383}); 335});
384 336
385//############################################################################# 337//#############################################################################
386 338
387Clipperz.Crypto.PRNG.Fortuna = function(args) { 339Clipperz.Crypto.PRNG.Fortuna = function(args) {
388 vari,c; 340 vari,c;
389 341
390 args = args || {}; 342 args = args || {};
391 343
392 this._key = args.seed || null; 344 this._key = args.seed || null;
393 if (this._key == null) { 345 if (this._key == null) {
@@ -598,61 +550,55 @@ MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
598 this.randomnessSources().push(aRandomnessSource); 550 this.randomnessSources().push(aRandomnessSource);
599 551
600 if (this.isReadyToGenerateRandomValues() == false) { 552 if (this.isReadyToGenerateRandomValues() == false) {
601 aRandomnessSource.setBoostMode(true); 553 aRandomnessSource.setBoostMode(true);
602 } 554 }
603 }, 555 },
604 556
605 //------------------------------------------------------------------------- 557 //-------------------------------------------------------------------------
606 558
607 'deferredEntropyCollection': function(aValue) { 559 'deferredEntropyCollection': function(aValue) {
608 var result; 560 var result;
609 561
610//MochiKit.Logging.logDebug(">>> PRNG.deferredEntropyCollection");
611 562
612 if (this.isReadyToGenerateRandomValues()) { 563 if (this.isReadyToGenerateRandomValues()) {
613//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 1");
614 result = aValue; 564 result = aValue;
615 } else { 565 } else {
616//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 2");
617 var deferredResult; 566 var deferredResult;
618 567
619 Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true); 568 Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true);
620 569
621 deferredResult = new MochiKit.Async.Deferred(); 570 deferredResult = new MochiKit.Async.Deferred();
622 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - PRNG.deferredEntropyCollection - 1: " + res); return res;});
623 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); 571 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
624 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - PRNG.deferredEntropyCollection - 2: " + res); return res;});
625 MochiKit.Signal.connect(this, 572 MochiKit.Signal.connect(this,
626 'readyToGenerateRandomBytes', 573 'readyToGenerateRandomBytes',
627 deferredResult, 574 deferredResult,
628 'callback'); 575 'callback');
629 576
630 result = deferredResult; 577 result = deferredResult;
631 } 578 }
632//MochiKit.Logging.logDebug("<<< PRNG.deferredEntropyCollection - result: " + result);
633 579
634 return result; 580 return result;
635 }, 581 },
636 582
637 //------------------------------------------------------------------------- 583 //-------------------------------------------------------------------------
638 584
639 'fastEntropyAccumulationForTestingPurpose': function() { 585 'fastEntropyAccumulationForTestingPurpose': function() {
640 while (! this.isReadyToGenerateRandomValues()) { 586 while (! this.isReadyToGenerateRandomValues()) {
641 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));
642 } 588 }
643 }, 589 },
644 590
645 //------------------------------------------------------------------------- 591 //-------------------------------------------------------------------------
646 592/*
647 'dump': function(appendToDoc) { 593 'dump': function(appendToDoc) {
648 var tbl; 594 var tbl;
649 var i,c; 595 var i,c;
650 596
651 tbl = document.createElement("table"); 597 tbl = document.createElement("table");
652 tbl.border = 0; 598 tbl.border = 0;
653 with (tbl.style) { 599 with (tbl.style) {
654 border = "1px solid lightgrey"; 600 border = "1px solid lightgrey";
655 fontFamily = 'Helvetica, Arial, sans-serif'; 601 fontFamily = 'Helvetica, Arial, sans-serif';
656 fontSize = '8pt'; 602 fontSize = '8pt';
657 //borderCollapse = "collapse"; 603 //borderCollapse = "collapse";
658 } 604 }
@@ -740,25 +686,25 @@ MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
740 padding = "10px"; 686 padding = "10px";
741 } 687 }
742 if (document.getElementById(ne.id)) { 688 if (document.getElementById(ne.id)) {
743 MochiKit.DOM.swapDOM(ne.id, ne); 689 MochiKit.DOM.swapDOM(ne.id, ne);
744 } else { 690 } else {
745 document.body.appendChild(ne); 691 document.body.appendChild(ne);
746 } 692 }
747 ne.appendChild(tbl); 693 ne.appendChild(tbl);
748 } 694 }
749 695
750 return tbl; 696 return tbl;
751 }, 697 },
752 698*/
753 //----------------------------------------------------------------------------- 699 //-----------------------------------------------------------------------------
754 __syntaxFix__: "syntax fix" 700 __syntaxFix__: "syntax fix"
755}); 701});
756 702
757//############################################################################# 703//#############################################################################
758 704
759Clipperz.Crypto.PRNG.Random = function(args) { 705Clipperz.Crypto.PRNG.Random = function(args) {
760 args = args || {}; 706 args = args || {};
761 //MochiKit.Base.bindMethods(this); 707 //MochiKit.Base.bindMethods(this);
762 708
763 return this; 709 return this;
764} 710}
@@ -815,34 +761,44 @@ Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
815 // MouseRandomnessSource 761 // MouseRandomnessSource
816 // 762 //
817 //............................................................. 763 //.............................................................
818 { 764 {
819 varnewRandomnessSource; 765 varnewRandomnessSource;
820 766
821 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); 767 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
822 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 768 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
823 } 769 }
824 770
825 //............................................................. 771 //.............................................................
826 // 772 //
827 // KeyboardRandomnessSource 773 // CryptoRandomRandomnessSource
828 // 774 //
829 //............................................................. 775 //.............................................................
830 { 776 {
831 varnewRandomnessSource; 777 varnewRandomnessSource;
778 varbrowserCrypto;
832 779
833 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource(); 780 if (window.crypto && window.crypto.getRandomValues) {
834 _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 }
835 } 792 }
836
837 } 793 }
838 794
839 return _clipperz_crypt_prng_defaultPRNG; 795 return _clipperz_crypt_prng_defaultPRNG;
840}; 796};
841 797
842//############################################################################# 798//#############################################################################
843 799
844Clipperz.Crypto.PRNG.exception = { 800Clipperz.Crypto.PRNG.exception = {
845 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") 801 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
846}; 802};
847 803
848 804
diff --git a/frontend/beta/js/Clipperz/Crypto/SRP.js b/frontend/beta/js/Clipperz/Crypto/SRP.js
index 8cc80ba..8c522ad 100644
--- a/frontend/beta/js/Clipperz/Crypto/SRP.js
+++ b/frontend/beta/js/Clipperz/Crypto/SRP.js
@@ -35,44 +35,55 @@ try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e)
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//#############################################################################
@@ -120,146 +131,154 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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//MochiKit.Logging.logDebug("SRP a: " + this._a);
133 } 143 }
134 144
135 return this._a; 145 return this._a;
136 }, 146 },
137 147
138 //------------------------------------------------------------------------- 148 //-------------------------------------------------------------------------
139 149
140 'A': function () { 150 'A': function () {
141 if (this._A == null) { 151 if (this._A == null) {
142 //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
143 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());
144 154 if (this._A.equals(0) || negative(this._A)) {
145 if (this._A.equals(0)) { 155 MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0.");
146MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0.");
147 throw Clipperz.Crypto.SRP.exception.InvalidValue; 156 throw Clipperz.Crypto.SRP.exception.InvalidValue;
148 } 157 }
149//MochiKit.Logging.logDebug("SRP A: " + this._A);
150 } 158 }
151 159
152 return this._A; 160 return this._A;
153 }, 161 },
154 162
155 //------------------------------------------------------------------------- 163 //-------------------------------------------------------------------------
156 164
157 's': function () { 165 's': function () {
158 return this._s; 166 return this._s;
159//MochiKit.Logging.logDebug("SRP s: " + this._S);
160 }, 167 },
161 168
162 'set_s': function(aValue) { 169 'set_s': function(aValue) {
163 this._s = aValue; 170 this._s = aValue;
164 }, 171 },
165 172
166 //------------------------------------------------------------------------- 173 //-------------------------------------------------------------------------
167 174
168 'B': function () { 175 'B': function () {
169 return this._B; 176 return this._B;
170 }, 177 },
171 178
172 'set_B': function(aValue) { 179 'set_B': function(aValue) {
173 //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
174 if (! aValue.equals(0)) { 181 this._B = aValue;
175 this._B = aValue; 182 if (this._B.equals(0) || negative(this._B)) {
176//MochiKit.Logging.logDebug("SRP B: " + this._B); 183 MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0.");
177 } else {
178MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0.");
179 throw Clipperz.Crypto.SRP.exception.InvalidValue; 184 throw Clipperz.Crypto.SRP.exception.InvalidValue;
180 } 185 }
181 }, 186 },
182 187
183 //------------------------------------------------------------------------- 188 //-------------------------------------------------------------------------
184 189
185 'x': function () { 190 'x': function () {
186 if (this._x == null) { 191 if (this._x == null) {
187 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);
188//MochiKit.Logging.logDebug("SRP x: " + this._x);
189 } 193 }
190 194
191 return this._x; 195 return this._x;
192 }, 196 },
193 197
194 //------------------------------------------------------------------------- 198 //-------------------------------------------------------------------------
195 199
196 'u': function () { 200 'u': function () {
197 if (this._u == null) { 201 if (this._u == null) {
198 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);
199//MochiKit.Logging.logDebug("SRP u: " + this._u);
200 } 203 }
201 204
202 return this._u; 205 return this._u;
203 }, 206 },
204 207
205 //------------------------------------------------------------------------- 208 //-------------------------------------------------------------------------
206 209
207 'S': function () { 210 'S': function () {
208 if (this._S == null) { 211 if (this._S == null) {
209 var bigint; 212 var bigint;
210 varsrp; 213 varsrp;
211 214
212 bigint = Clipperz.Crypto.BigInt; 215 bigint = Clipperz.Crypto.BigInt;
213 srp = Clipperz.Crypto.SRP; 216 srp = Clipperz.Crypto.SRP;
214 217
215 this._S =bigint.powerModule( 218 this._S =bigint.powerModule(
216 bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())), 219 bigint.subtract(
217 bigint.add(this.a(), bigint.multiply(this.u(), this.x())), 220 this.B(),
218 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()
219 ) 228 )
220//MochiKit.Logging.logDebug("SRP S: " + this._S);
221 } 229 }
222 230
223 return this._S; 231 return this._S;
224 }, 232 },
225 233
226 //------------------------------------------------------------------------- 234 //-------------------------------------------------------------------------
227 235
228 'K': function () { 236 'K': function () {
229 if (this._K == null) { 237 if (this._K == null) {
230 this._K = this.stringHash(this.S().asString()); 238 this._K = this.stringHash(this.S().asString());
231//MochiKit.Logging.logDebug("SRP K: " + this._K);
232 } 239 }
233 240
234 return this._K; 241 return this._K;
235 }, 242 },
236 243
237 //------------------------------------------------------------------------- 244 //-------------------------------------------------------------------------
238 245
239 'M1': function () { 246 'M1': function () {
240 if (this._M1 == null) { 247 if (this._M1 == null) {
241 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());
242//MochiKit.Logging.logDebug("SRP M1: " + this._M1); 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);
243 } 262 }
244 263
245 return this._M1; 264 return this._M1;
246 }, 265 },
247 266
248 //------------------------------------------------------------------------- 267 //-------------------------------------------------------------------------
249 268
250 'M2': function () { 269 'M2': function () {
251 if (this._M2 == null) { 270 if (this._M2 == null) {
252 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());
253//MochiKit.Logging.logDebug("SRP M2: " + this._M2); 272//console.log("M2", this._M2);
254 } 273 }
255 274
256 return this._M2; 275 return this._M2;
257 }, 276 },
258 277
259 //========================================================================= 278 //=========================================================================
260 279
261 'serverSideCredentialsWithSalt': function(aSalt) { 280 'serverSideCredentialsWithSalt': function(aSalt) {
262 var result; 281 var result;
263 var s, x, v; 282 var s, x, v;
264 283
265 s = aSalt; 284 s = aSalt;
diff --git a/frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js b/frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js
index 2295d3f..369b9ce 100644
--- a/frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js
+++ b/frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js
@@ -129,25 +129,25 @@ Clipperz.PM.BookmarkletProcessor.prototype = MochiKit.Base.update(null, {
129 }, this.fields()) 129 }, this.fields())
130 } 130 }
131 131
132 return this._editableFields; 132 return this._editableFields;
133 }, 133 },
134 134
135 //------------------------------------------------------------------------- 135 //-------------------------------------------------------------------------
136 136
137 'hostname': function() { 137 'hostname': function() {
138 if (this._hostname == null) { 138 if (this._hostname == null) {
139 var actionUrl; 139 var actionUrl;
140 140
141 actionUrl = this.configuration()['form']['attributes']['action']; 141 actionUrl = Clipperz.Base.sanitizeUrl(this.configuration()['form']['attributes']['action']);
142//MochiKit.Logging.logDebug("+++ actionUrl: " + actionUrl); 142//MochiKit.Logging.logDebug("+++ actionUrl: " + actionUrl);
143 this._hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1'); 143 this._hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1');
144 } 144 }
145 145
146 return this._hostname; 146 return this._hostname;
147 }, 147 },
148 148
149 'favicon': function() { 149 'favicon': function() {
150 if (this._favicon == null) { 150 if (this._favicon == null) {
151 this._favicon = "http://" + this.hostname() + "/favicon.ico"; 151 this._favicon = "http://" + this.hostname() + "/favicon.ico";
152//MochiKit.Logging.logDebug("+++ favicon: " + this._favicon); 152//MochiKit.Logging.logDebug("+++ favicon: " + this._favicon);
153 } 153 }
diff --git a/frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js b/frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js
index 0e4640e..a5a4697 100644
--- a/frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js
+++ b/frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js
@@ -91,25 +91,25 @@ YAHOO.extendX(Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent, C
91 varresult; 91 varresult;
92 var option; 92 var option;
93 varrecordFieldKey; 93 varrecordFieldKey;
94 varrecordFields; 94 varrecordFields;
95 95
96//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.recordFieldOptions"); 96//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.recordFieldOptions");
97 recordFields = this.directLoginBinding().directLogin().record().currentVersion().fields(); 97 recordFields = this.directLoginBinding().directLogin().record().currentVersion().fields();
98 result = []; 98 result = [];
99 option = {tag:'option', value:null, html:'---'}; 99 option = {tag:'option', value:null, html:'---'};
100 result.push(option); 100 result.push(option);
101 for (recordFieldKey in recordFields) { 101 for (recordFieldKey in recordFields) {
102 //TODO: remove the value: field and replace it with element.dom.value = <some value> 102 //TODO: remove the value: field and replace it with element.dom.value = <some value>
103 option = {tag:'option', value:recordFieldKey, html:recordFields[recordFieldKey].label()} 103 option = {tag:'option', value:recordFieldKey, html:Clipperz.Base.sanitizeString(recordFields[recordFieldKey].label())}
104 if (recordFieldKey == this.directLoginBinding().fieldKey()) { 104 if (recordFieldKey == this.directLoginBinding().fieldKey()) {
105 option['selected'] = true; 105 option['selected'] = true;
106 } 106 }
107 result.push(option); 107 result.push(option);
108 } 108 }
109//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.recordFieldOptions"); 109//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.recordFieldOptions");
110 110
111 return result; 111 return result;
112 }, 112 },
113 113
114 //------------------------------------------------------------------------- 114 //-------------------------------------------------------------------------
115 115
@@ -141,25 +141,25 @@ YAHOO.extendX(Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent, C
141 141
142 this.getElement('editModeBox').show(); 142 this.getElement('editModeBox').show();
143//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateEditMode"); 143//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateEditMode");
144 }, 144 },
145 145
146 //------------------------------------------------------------------------- 146 //-------------------------------------------------------------------------
147 147
148 'updateViewMode': function() { 148 'updateViewMode': function() {
149//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.updateViewMode"); 149//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.updateViewMode");
150 this.getElement('editModeBox').hide(); 150 this.getElement('editModeBox').hide();
151 this.getElement('viewModeBox').show(); 151 this.getElement('viewModeBox').show();
152 152
153 this.getElement('viewValue').update(this.directLoginBinding().field().label()); 153 this.getElement('viewValue').update(Clipperz.Base.sanitizeString(this.directLoginBinding().field().label()));
154//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateViewMode"); 154//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateViewMode");
155 }, 155 },
156 156
157 //------------------------------------------------------------------------- 157 //-------------------------------------------------------------------------
158 158
159 'synchronizeComponentValues': function() { 159 'synchronizeComponentValues': function() {
160//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.synchronizeComponentValues") 160//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.synchronizeComponentValues")
161//MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.synchronizeComponentValues - 1 - " + this.getId('select')); 161//MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.synchronizeComponentValues - 1 - " + this.getId('select'));
162 this.directLoginBinding().setFieldKey(this.getDom('select').value); 162 this.directLoginBinding().setFieldKey(this.getDom('select').value);
163//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.synchronizeComponentValues"); 163//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.synchronizeComponentValues");
164 }, 164 },
165 165
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js b/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js
index c0cfa3c..56d9d59 100644
--- a/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js
+++ b/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js
@@ -29,25 +29,25 @@ if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {};
29//############################################################################# 29//#############################################################################
30 30
31Clipperz.PM.DataModel.DirectLogin = function(args) { 31Clipperz.PM.DataModel.DirectLogin = function(args) {
32//MochiKit.Logging.logDebug(">>> new Clipperz.PM.DataModel.DirectLogin"); 32//MochiKit.Logging.logDebug(">>> new Clipperz.PM.DataModel.DirectLogin");
33//console.log(">>> new Clipperz.PM.DataModel.DirectLogin - args: %o", args); 33//console.log(">>> new Clipperz.PM.DataModel.DirectLogin - args: %o", args);
34//console.log("--- formData: %s", Clipperz.Base.serializeJSON(args.formData)); 34//console.log("--- formData: %s", Clipperz.Base.serializeJSON(args.formData));
35 args = args || {}; 35 args = args || {};
36 36
37//MochiKit.Logging.logDebug("--- new Clipperz.PM.DataModel.DirectLogin - args: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args))); 37//MochiKit.Logging.logDebug("--- new Clipperz.PM.DataModel.DirectLogin - args: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args)));
38 this._record = args.record || null; 38 this._record = args.record || null;
39 this._label = args.label || "unnamed record" 39 this._label = args.label || "unnamed record"
40 this._reference = args.reference || Clipperz.PM.Crypto.randomKey(); 40 this._reference = args.reference || Clipperz.PM.Crypto.randomKey();
41 this._favicon = args.favicon || null; 41 this._favicon = Clipperz.Base.sanitizeFavicon(args.favicon) || null;
42 this._bookmarkletVersion = args.bookmarkletVersion || "0.1"; 42 this._bookmarkletVersion = args.bookmarkletVersion || "0.1";
43 43
44 this._directLoginInputs = null; 44 this._directLoginInputs = null;
45 45
46 this._formValues = args.formValues || {}; 46 this._formValues = args.formValues || {};
47 this.setFormData(args.formData || null); 47 this.setFormData(args.formData || null);
48//console.log("=== formData: %o", this.formData()); 48//console.log("=== formData: %o", this.formData());
49 49
50 if (args.legacyBindingData == null) { 50 if (args.legacyBindingData == null) {
51 this.setBindingData(args.bindingData || null); 51 this.setBindingData(args.bindingData || null);
52 } else { 52 } else {
53 this.setLegacyBindingData(args.legacyBindingData); 53 this.setLegacyBindingData(args.legacyBindingData);
@@ -93,27 +93,27 @@ Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, {
93 93
94 'setLabel': function(aValue) { 94 'setLabel': function(aValue) {
95 this._label = aValue; 95 this._label = aValue;
96 }, 96 },
97 97
98 //------------------------------------------------------------------------- 98 //-------------------------------------------------------------------------
99 99
100 'favicon': function() { 100 'favicon': function() {
101 if (this._favicon == null) { 101 if (this._favicon == null) {
102 varactionUrl; 102 varactionUrl;
103 var hostname; 103 var hostname;
104 104
105 actionUrl = this.formData()['attributes']['action']; 105 actionUrl = this.action();
106 hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1'); 106 hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1');
107 this._favicon = "http://" + hostname + "/favicon.ico"; 107 this._favicon = Clipperz.Base.sanitizeFavicon("http://" + hostname + "/favicon.ico");
108 } 108 }
109 109
110 return this._favicon; 110 return this._favicon;
111 }, 111 },
112 112
113 //------------------------------------------------------------------------- 113 //-------------------------------------------------------------------------
114 114
115 'fixedFavicon': function() { 115 'fixedFavicon': function() {
116 var result; 116 var result;
117 117
118 if (this._fixedFavicon == null) { 118 if (this._fixedFavicon == null) {
119 result = this.favicon(); 119 result = this.favicon();
@@ -128,24 +128,32 @@ Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, {
128 } 128 }
129 } else { 129 } else {
130 result = this._fixedFavicon; 130 result = this._fixedFavicon;
131 } 131 }
132 132
133 return result; 133 return result;
134 }, 134 },
135 135
136 'setFixedFavicon': function(aValue) { 136 'setFixedFavicon': function(aValue) {
137 this._fixedFavicon = aValue; 137 this._fixedFavicon = aValue;
138 }, 138 },
139 139
140 'action': function () {
141 varresult;
142
143 result = Clipperz.Base.sanitizeUrl(this.formData()['attributes']['action']);
144
145 return result;
146 },
147
140 //------------------------------------------------------------------------- 148 //-------------------------------------------------------------------------
141 149
142 'bookmarkletVersion': function() { 150 'bookmarkletVersion': function() {
143 return this._bookmarkletVersion; 151 return this._bookmarkletVersion;
144 }, 152 },
145 153
146 'setBookmarkletVersion': function(aValue) { 154 'setBookmarkletVersion': function(aValue) {
147 this._bookmarkletVersion = aValue; 155 this._bookmarkletVersion = aValue;
148 }, 156 },
149 157
150 //------------------------------------------------------------------------- 158 //-------------------------------------------------------------------------
151 159
@@ -433,25 +441,25 @@ Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, {
433 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() { 441 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() {
434 var formElement; 442 var formElement;
435 varformSubmitFunction; 443 varformSubmitFunction;
436 var submitButtons; 444 var submitButtons;
437 445
438//MochiKit.Logging.logDebug("### runDirectLogin - 3"); 446//MochiKit.Logging.logDebug("### runDirectLogin - 3");
439 // MochiKit.DOM.currentDocument().write('<html><head><title>' + this.label() + '</title><META http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body></body></html>') 447 // MochiKit.DOM.currentDocument().write('<html><head><title>' + this.label() + '</title><META http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body></body></html>')
440//MochiKit.Logging.logDebug("### runDirectLogin - 3.1"); 448//MochiKit.Logging.logDebug("### runDirectLogin - 3.1");
441 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, MochiKit.DOM.H3(null, "Loading " + this.label() + " ...")); 449 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, MochiKit.DOM.H3(null, "Loading " + this.label() + " ..."));
442//MochiKit.Logging.logDebug("### runDirectLogin - 4"); 450//MochiKit.Logging.logDebug("### runDirectLogin - 4");
443//console.log(this.formData()['attributes']); 451//console.log(this.formData()['attributes']);
444 formElement = MochiKit.DOM.FORM(MochiKit.Base.update({id:'directLoginForm'}, {'method':this.formData()['attributes']['method'], 452 formElement = MochiKit.DOM.FORM(MochiKit.Base.update({id:'directLoginForm'}, {'method':this.formData()['attributes']['method'],
445 'action':this.formData()['attributes']['action']})); 453 'action': this.action()}));
446//MochiKit.Logging.logDebug("### runDirectLogin - 5"); 454//MochiKit.Logging.logDebug("### runDirectLogin - 5");
447 formSubmitFunction = MochiKit.Base.method(formElement, 'submit'); 455 formSubmitFunction = MochiKit.Base.method(formElement, 'submit');
448//MochiKit.Logging.logDebug("### runDirectLogin - 6"); 456//MochiKit.Logging.logDebug("### runDirectLogin - 6");
449 457
450 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, 458 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body,
451 MochiKit.DOM.DIV({style:'display:none; visibility:hidden;'}, formElement) 459 MochiKit.DOM.DIV({style:'display:none; visibility:hidden;'}, formElement)
452 ); 460 );
453//MochiKit.Logging.logDebug("### runDirectLogin - 7"); 461//MochiKit.Logging.logDebug("### runDirectLogin - 7");
454 MochiKit.DOM.appendChildNodes(formElement, MochiKit.Base.map(MochiKit.Base.methodcaller("formConfiguration"), 462 MochiKit.DOM.appendChildNodes(formElement, MochiKit.Base.map(MochiKit.Base.methodcaller("formConfiguration"),
455 this.directLoginInputs())); 463 this.directLoginInputs()));
456//MochiKit.Logging.logDebug("### runDirectLogin - 8"); 464//MochiKit.Logging.logDebug("### runDirectLogin - 8");
457 465
@@ -478,27 +486,27 @@ Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, {
478 } 486 }
479 487
480 }, this)); 488 }, this));
481 }, 489 },
482 490
483 //------------------------------------------------------------------------- 491 //-------------------------------------------------------------------------
484 492
485 'runDirectLogin': function(aNewWindow) { 493 'runDirectLogin': function(aNewWindow) {
486 varnewWindow; 494 varnewWindow;
487 495
488//console.log("formData.attributes", this.formData()['attributes']); 496//console.log("formData.attributes", this.formData()['attributes']);
489 // if (/^javascript/.test(this.formData()['attributes']['action'])) { 497 // if (/^javascript/.test(this.formData()['attributes']['action'])) {
490 if ((/^(https?|webdav|ftp)\:/.test(this.formData()['attributes']['action']) == false) && 498 if ((/^(https?|webdav|ftp)\:/.test(this.action()) == false) &&
491 (this.formData()['attributes']['type'] != 'http_auth')) 499 (this.formData()['attributes']['type'] != 'http_auth')
492 { 500 ) {
493 var messageBoxConfiguration; 501 var messageBoxConfiguration;
494 502
495 if (typeof(aNewWindow) != 'undefined') { 503 if (typeof(aNewWindow) != 'undefined') {
496 aNewWindow.close(); 504 aNewWindow.close();
497 } 505 }
498 506
499 messageBoxConfiguration = {}; 507 messageBoxConfiguration = {};
500 messageBoxConfiguration.title = Clipperz.PM.Strings['VulnerabilityWarning_Panel_title']; 508 messageBoxConfiguration.title = Clipperz.PM.Strings['VulnerabilityWarning_Panel_title'];
501 messageBoxConfiguration.msg = Clipperz.PM.Strings['VulnerabilityWarning_Panel_message']; 509 messageBoxConfiguration.msg = Clipperz.PM.Strings['VulnerabilityWarning_Panel_message'];
502 messageBoxConfiguration.animEl = YAHOO.ext.Element.get("mainDiv"); 510 messageBoxConfiguration.animEl = YAHOO.ext.Element.get("mainDiv");
503 messageBoxConfiguration.progress = false; 511 messageBoxConfiguration.progress = false;
504 messageBoxConfiguration.closable = false; 512 messageBoxConfiguration.closable = false;
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js b/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js
index 236d7c9..ba302da 100644
--- a/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js
+++ b/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js
@@ -38,25 +38,25 @@ Clipperz.PM.DataModel.DirectLoginReference = function(args) {
38 if (args.directLogin != null) { 38 if (args.directLogin != null) {
39 this._reference = args.directLogin.reference(); 39 this._reference = args.directLogin.reference();
40 this._recordReference = args.directLogin.record().reference(); 40 this._recordReference = args.directLogin.record().reference();
41 this._label = args.directLogin.label(); 41 this._label = args.directLogin.label();
42 this._favicon = args.directLogin.favicon() || null; 42 this._favicon = args.directLogin.favicon() || null;
43 43
44 this._directLogin = args.directLogin; 44 this._directLogin = args.directLogin;
45 this._record = args.directLogin.record(); 45 this._record = args.directLogin.record();
46 } else { 46 } else {
47 this._reference = args.reference; 47 this._reference = args.reference;
48 this._recordReference = args.record; 48 this._recordReference = args.record;
49 this._label = args.label; 49 this._label = args.label;
50 this._favicon = args.favicon || null; 50 this._favicon = Clipperz.Base.sanitizeFavicon(args.favicon) || null;
51 51
52 this._directLogin = null; 52 this._directLogin = null;
53 this._record = null; 53 this._record = null;
54 } 54 }
55 55
56 this._fixedFavicon = null; 56 this._fixedFavicon = null;
57 57
58 return this; 58 return this;
59} 59}
60 60
61Clipperz.PM.DataModel.DirectLoginReference.prototype = MochiKit.Base.update(null, { 61Clipperz.PM.DataModel.DirectLoginReference.prototype = MochiKit.Base.update(null, {
62 62
diff --git a/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
index 1a5caff..b0b9b63 100644
--- a/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
+++ b/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
@@ -28,24 +28,25 @@ try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch
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._connections = {}; 38 this._connections = {};
39 39
40 this._C = null;
40 this._b = null; 41 this._b = null;
41 this._B = null; 42 this._B = null;
42 this._A = null; 43 this._A = null;
43 this._userData = null; 44 this._userData = null;
44 45
45 return this; 46 return this;
46} 47}
47 48
48//Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { 49//Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
49Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, { 50Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
50 51
51 //------------------------------------------------------------------------- 52 //-------------------------------------------------------------------------
@@ -135,24 +136,34 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
135//console.log("this._data", resultData); 136//console.log("this._data", resultData);
136 this._data = resultData; 137 this._data = resultData;
137 }, this)); 138 }, this));
138 139
139 deferredResult.callback(); 140 deferredResult.callback();
140//Clipperz.log("<<< Proxy.Test.setupWithData"); 141//Clipperz.log("<<< Proxy.Test.setupWithData");
141 142
142 return deferredResult; 143 return deferredResult;
143 }, 144 },
144 145
145 //========================================================================= 146 //=========================================================================
146 147
148 'C': function() {
149 return this._C;
150 },
151
152 'set_C': function(aValue) {
153 this._C = aValue;
154 },
155
156 //-------------------------------------------------------------------------
157
147 'b': function() { 158 'b': function() {
148 return this._b; 159 return this._b;
149 }, 160 },
150 161
151 'set_b': function(aValue) { 162 'set_b': function(aValue) {
152 this._b = aValue; 163 this._b = aValue;
153 }, 164 },
154 165
155 //------------------------------------------------------------------------- 166 //-------------------------------------------------------------------------
156 167
157 'B': function() { 168 'B': function() {
158 return this._B; 169 return this._B;
@@ -227,26 +238,26 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
227 238
228 if (localToll != null) { 239 if (localToll != null) {
229 if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) { 240 if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) {
230 throw "Toll value too low."; 241 throw "Toll value too low.";
231 }; 242 };
232 } else { 243 } else {
233 throw "Missing toll"; 244 throw "Missing toll";
234 } 245 }
235 } 246 }
236 }, 247 },
237 248
238 //========================================================================= 249 //=========================================================================
239 250
240 'processMessage': function(aFunctionName, someParameters) { 251 'processMessage': function (aFunctionName, someParameters) {
241 var result; 252 var result;
242 253
243 switch(aFunctionName) { 254 switch(aFunctionName) {
244 case 'knock': 255 case 'knock':
245 result = this._knock(someParameters); 256 result = this._knock(someParameters);
246 break; 257 break;
247 case 'registration': 258 case 'registration':
248 this.checkToll(aFunctionName, someParameters); 259 this.checkToll(aFunctionName, someParameters);
249 result = this._registration(someParameters.parameters); 260 result = this._registration(someParameters.parameters);
250 break; 261 break;
251 case 'handshake': 262 case 'handshake':
252 this.checkToll(aFunctionName, someParameters); 263 this.checkToll(aFunctionName, someParameters);
@@ -294,32 +305,32 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
294 // 'lock': someParameters['user']['lock'], 305 // 'lock': someParameters['user']['lock'],
295 'lock': Clipperz.Crypto.Base.generateRandomSeed(), 306 'lock': Clipperz.Crypto.Base.generateRandomSeed(),
296 // 'maxNumberOfRecords':'100', 307 // 'maxNumberOfRecords':'100',
297 'userDetails': someParameters['user']['header'], 308 'userDetails': someParameters['user']['header'],
298 'statistics': someParameters['user']['statistics'], 309 'statistics': someParameters['user']['statistics'],
299 'userDetailsVersion':someParameters['user']['version'], 310 'userDetailsVersion':someParameters['user']['version'],
300 'records':{} 311 'records':{}
301 } 312 }
302 } else { 313 } else {
303 throw "user already exists"; 314 throw "user already exists";
304 } 315 }
305 } else { 316 } else {
306 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 317 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
307 } 318 }
308 319
309 result = { 320 result = {
310 result: { 321 result: {
311 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'], 322 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'],
312 'result':'done' 323 'result':'done'
313 }, 324 },
314 toll: this.getTollForRequestType('CONNECT') 325 toll: this.getTollForRequestType('CONNECT')
315 } 326 }
316 327
317 return MochiKit.Async.succeed(result); 328 return MochiKit.Async.succeed(result);
318 }, 329 },
319 330
320 //------------------------------------------------------------------------- 331 //-------------------------------------------------------------------------
321 332
322 '_handshake': function(someParameters) { 333 '_handshake': function(someParameters) {
323 var result; 334 var result;
324 varnextTollRequestType; 335 varnextTollRequestType;
325 336
@@ -331,50 +342,66 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
331 var b, B, v; 342 var b, B, v;
332 343
333//console.log(">>> Proxy.Offline.DataStore._handshake.connect", someParameters); 344//console.log(">>> Proxy.Offline.DataStore._handshake.connect", someParameters);
334 userData = this.data()['users'][someParameters.parameters.C]; 345 userData = this.data()['users'][someParameters.parameters.C];
335 346
336 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) { 347 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) {
337 this.setUserData(userData); 348 this.setUserData(userData);
338 } else { 349 } else {
339 this.setUserData(this.data()['users']['catchAllUser']); 350 this.setUserData(this.data()['users']['catchAllUser']);
340 } 351 }
341 352
342 randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); 353 randomBytes = Clipperz.Crypto.Base.generateRandomSeed();
354 this.set_C(someParameters.parameters.C);
343 this.set_b(new Clipperz.Crypto.BigInt(randomBytes, 16)); 355 this.set_b(new Clipperz.Crypto.BigInt(randomBytes, 16));
344 v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16); 356 v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16);
345 this.set_B(v.add(Clipperz.Crypto.SRP.g().powerModule(this.b(), Clipperz.Crypto.SRP.n()))); 357 this.set_B((Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(this.b(), Clipperz.Crypto.SRP.n())));
346 358
347 this.set_A(someParameters.parameters.A); 359 this.set_A(someParameters.parameters.A);
348 360
349 result['s'] = this.userData()['s']; 361 result['s'] = this.userData()['s'];
350 result['B'] = this.B().asString(16); 362 result['B'] = this.B().asString(16);
351 363
352 nextTollRequestType = 'CONNECT'; 364 nextTollRequestType = 'CONNECT';
353 } else if (someParameters.message == "credentialCheck") { 365 } else if (someParameters.message == "credentialCheck") {
354 var v, u, S, A, K, M1; 366 var v, u, s, S, A, K, M1;
367 var stringHash = function (aValue) {
368 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
369 };
355 370
356//console.log(">>> Proxy.Offline.DataStore._handshake.credentialCheck", someParameters); 371//console.log(">>> Proxy.Offline.DataStore._handshake.credentialCheck", someParameters);
357 v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16); 372 v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16);
358 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(this.B().asString(10))).toHexString(), 16);
359 A = new Clipperz.Crypto.BigInt(this.A(), 16); 373 A = new Clipperz.Crypto.BigInt(this.A(), 16);
374 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + this.B().asString(10))).toHexString(), 16);
375 s = new Clipperz.Crypto.BigInt(this.userData()['s'], 16);
360 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(this.b(), Clipperz.Crypto.SRP.n()); 376 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(this.b(), Clipperz.Crypto.SRP.n());
361 377
362 K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2); 378 K = stringHash(S.asString(10));
363 379
364 M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + this.B().asString(10) + K)).toHexString().slice(2); 380 M1 = stringHash(
381 "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" +
382 stringHash(this.C()) +
383 s.asString(10) +
384 A.asString(10) +
385 this.B().asString(10) +
386 K
387 );
365 if (someParameters.parameters.M1 == M1) { 388 if (someParameters.parameters.M1 == M1) {
366 var M2; 389 var M2;
367 390
368 M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2); 391 M2 = stringHash(
392 A.asString(10) +
393 someParameters.parameters.M1 +
394 K
395 );
369 result['M2'] = M2; 396 result['M2'] = M2;
370 } else { 397 } else {
371 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); 398 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
372 } 399 }
373 400
374 nextTollRequestType = 'MESSAGE'; 401 nextTollRequestType = 'MESSAGE';
375 } else if (someParameters.message == "oneTimePassword") { 402 } else if (someParameters.message == "oneTimePassword") {
376 var otpData; 403 var otpData;
377 404
378//console.log("HANDSHAKE WITH OTP", someParameters.parameters.oneTimePasswordKey); 405//console.log("HANDSHAKE WITH OTP", someParameters.parameters.oneTimePasswordKey);
379//console.log("someParameters", someParameters); 406//console.log("someParameters", someParameters);
380//console.log("data.OTP", Clipperz.Base.serializeJSON(this.data()['onetimePasswords'])); 407//console.log("data.OTP", Clipperz.Base.serializeJSON(this.data()['onetimePasswords']));
diff --git a/frontend/delta/js/Clipperz/Crypto/PRNG.js b/frontend/delta/js/Clipperz/Crypto/PRNG.js
index c539f06..80d972f 100644
--- a/frontend/delta/js/Clipperz/Crypto/PRNG.js
+++ b/frontend/delta/js/Clipperz/Crypto/PRNG.js
@@ -12,24 +12,26 @@ refer to http://www.clipperz.com.
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
@@ -188,30 +190,24 @@ Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new C
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;
@@ -236,30 +232,30 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
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 },
@@ -280,114 +276,72 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
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) {
@@ -626,25 +580,25 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
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 }
@@ -732,25 +686,25 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
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}
@@ -775,25 +729,25 @@ Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
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;
@@ -807,34 +761,44 @@ Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
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
diff --git a/frontend/delta/js/Clipperz/Crypto/SRP.js b/frontend/delta/js/Clipperz/Crypto/SRP.js
index 597e72d..6898dfb 100644
--- a/frontend/delta/js/Clipperz/Crypto/SRP.js
+++ b/frontend/delta/js/Clipperz/Crypto/SRP.js
@@ -35,44 +35,55 @@ try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e)
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//#############################################################################
@@ -129,28 +140,27 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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;
@@ -158,98 +168,117 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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;
diff --git a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js
index 3f16f70..d03f873 100644
--- a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js
+++ b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js
@@ -79,47 +79,62 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.P
79 userData = this.data()['users'][someParameters.parameters.C]; 79 userData = this.data()['users'][someParameters.parameters.C];
80 80
81 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) { 81 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) {
82 aConnection['userData'] = userData; 82 aConnection['userData'] = userData;
83 aConnection['C'] = someParameters.parameters.C; 83 aConnection['C'] = someParameters.parameters.C;
84 } else { 84 } else {
85 aConnection['userData'] = this.data()['users']['catchAllUser']; 85 aConnection['userData'] = this.data()['users']['catchAllUser'];
86 } 86 }
87 87
88 randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); 88 randomBytes = Clipperz.Crypto.Base.generateRandomSeed();
89 aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16); 89 aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16);
90 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); 90 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
91 aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); 91 aConnection['B'] = (Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()));
92 92
93 aConnection['A'] = someParameters.parameters.A; 93 aConnection['A'] = someParameters.parameters.A;
94 94
95 result['s'] = aConnection['userData']['s']; 95 result['s'] = aConnection['userData']['s'];
96 result['B'] = aConnection['B'].asString(16); 96 result['B'] = aConnection['B'].asString(16);
97 97
98 nextTollRequestType = 'CONNECT'; 98 nextTollRequestType = 'CONNECT';
99 } else if (someParameters.message == "credentialCheck") { 99 } else if (someParameters.message == "credentialCheck") {
100 var v, u, S, A, K, M1; 100 var v, u, s, S, A, K, M1;
101 var stringHash = function (aValue) {
102 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
103 };
101 104
102 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); 105 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
103 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16);
104 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16); 106 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16);
107 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);
108 s = new Clipperz.Crypto.BigInt(aConnection['userData']['s'], 16);
105 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); 109 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n());
106 110
107 K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2); 111 K = stringHash(S.asString(10));
108 112
109 M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2); 113 M1 = stringHash(
114 "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" +
115 stringHash(aConnection['C']) +
116 s.asString(10) +
117 A.asString(10) +
118 aConnection['B'].asString(10) +
119 K
120 );
110 if (someParameters.parameters.M1 == M1) { 121 if (someParameters.parameters.M1 == M1) {
111 var M2; 122 var M2;
112 123
113 M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2); 124 M2 = stringHash(
125 A.asString(10) +
126 someParameters.parameters.M1 +
127 K
128 );
114 result['M2'] = M2; 129 result['M2'] = M2;
115 } else { 130 } else {
116 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); 131 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
117 } 132 }
118 133
119 nextTollRequestType = 'MESSAGE'; 134 nextTollRequestType = 'MESSAGE';
120 } else if (someParameters.message == "oneTimePassword") { 135 } else if (someParameters.message == "oneTimePassword") {
121 var otpData; 136 var otpData;
122 137
123 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; 138 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey];
124 139
125 try { 140 try {
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
@@ -12,24 +12,26 @@ refer to http://www.clipperz.com.
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
@@ -188,30 +190,24 @@ Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new C
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;
@@ -236,30 +232,30 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
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 },
@@ -280,114 +276,72 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
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) {
@@ -626,25 +580,25 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
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 }
@@ -732,25 +686,25 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
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}
@@ -775,25 +729,25 @@ Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
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;
@@ -807,34 +761,44 @@ Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
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
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
@@ -35,44 +35,55 @@ try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e)
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//#############################################################################
@@ -129,28 +140,27 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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;
@@ -158,98 +168,117 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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;
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
@@ -27,25 +27,25 @@ try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch
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 //-------------------------------------------------------------------------
@@ -282,32 +282,32 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
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
@@ -320,47 +320,62 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
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 {