summaryrefslogtreecommitdiff
authorMichael Krelin <hacker@klever.net>2014-06-30 18:20:13 (UTC)
committer Michael Krelin <hacker@klever.net>2014-06-30 18:20:13 (UTC)
commitc392fe28606eefa0c814e5c25d641f5ffe623186 (patch) (unidiff)
treeda03fe13ca09fadbebbad9b5d38750757270bae8
parentd341307d346dee62ee36b27f0f93b8f000748a96 (diff)
parent6dd16d9359e3a4dc306802588b09acd43947a606 (diff)
downloadclipperz-c392fe28606eefa0c814e5c25d641f5ffe623186.zip
clipperz-c392fe28606eefa0c814e5c25d641f5ffe623186.tar.gz
clipperz-c392fe28606eefa0c814e5c25d641f5ffe623186.tar.bz2
Merge remote-tracking branch 'github/master' into nmaster
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--README.md32
-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
15 files changed, 407 insertions, 351 deletions
diff --git a/README.md b/README.md
index e44df48..8e7cb6b 100644
--- a/README.md
+++ b/README.md
@@ -13,16 +13,21 @@ Read more on the [Clipperz website][home].
13 13
14[home]: http://www.clipperz.com 14[home]: https://clipperz.is
15 15
16## Why an open source version 16## Why an open source version of Clipperz?
17 17
18Because we want to enable as many people as possible to play with our code. So that you can start trusting it, the code not the developers. 18Because we want to enable as many people as possible to play with our code. So that they can start trusting it. The code, not its developers.
19 19
20In order to allow you to inspect the code and analyze the traffic it generates between client and server, we had to provide an easy way to locally deploy the whole service. 20In order to allow anyone not just to inspect the source code, but also to analyze the traffic it generates between client and server, we made available this open source version as an easy way to locally deploy the whole password manager web app on your machine. You can choose among the available backends (PHP/MySQL, Python/AppEngine, …) or [contribute][CA] your own.
21 21
22Feel free to host on your machine a web service identical to [Clipperz online password manager][home]. You can choose among **multiple backends** (PHP/MySQL, Python/AppEngine, …) or you can [contribute][CA] your own. 22Whatever is your motivation for playing with Clipperz code, we would love to hear from you: [get in contact][contact]!
23 23
24Whatever is your motivation, we would love to hear from you: [get in contact!][contact] 24## Security warning
25 25
26[CA]: http://www.clipperz.com/open_source/contributor_agreement 26The open source version of Clipperz is suitable for **testing and educational purposes only**. Do not use it as an actual password management solution.
27[contact]: http://www.clipperz.com/about/contacts 27
28As an example, the current PHP backend lacks several critical capabilities such as bot protection and concurrent sessions management, moreover it could be vulnerable to serious threats (SQL injections, remote code execution, ...).
29
30[CA]: https://clipperz.is/open_source/contributor_agreement
31[contact]: https://clipperz.is/about/contacts
32[clipperz]: https://clipperz.is
28 33
@@ -36,4 +41,4 @@ Our favorite payment method is clearly Bitcoin ([learn why here][why]), but you
36 41
37[why]: http://www.clipperz.com/pricing/why_bitcoin 42[why]: https://clipperz.is/pricing/why_bitcoin
38[donations]: http://www.clipperz.com/donations 43[donations]: https://clipperz.is/donations
39 44
@@ -41,3 +46,3 @@ Our favorite payment method is clearly Bitcoin ([learn why here][why]), but you
41## License 46## License
42ALL the code included in this project, if not otherwise stated, is released with the [AGPL v3][agpl] license (see `LICENSE.txt`), and all rights are reserved to Clipperz Srl. For any use not allowed by the AGPL license, please [contact us][contact] to inquire about licensing options for commercial applications. 47ALL the code included in this project, if not otherwise stated, is released with the [AGPL v3][agpl] license (see `LICENSE.txt`), and all rights are reserved to Clipperz Srl. For any use not allowed by the AGPL license, please [contact us][contact] to inquire about licensing options for commercial applications.
43 48
@@ -46,5 +51,2 @@ ALL the code included in this project, if not otherwise stated, is released with
46 51
47## Warnings
48Please note that the open source version of Clipperz Password Manager may not be suitable for mass deployments, depending on how robust is the backend you select. As an example, the current PHP backend lacks several critical capabilities such as bot protection and concurrent sessions management.
49
50## Contributions 52## Contributions
@@ -117,2 +119,2 @@ This application has not been fully tested, so there may be still problems due t
117 119
118[pog]: http://www.phpobjectgenerator.com/ \ No newline at end of file 120[pog]: http://www.phpobjectgenerator.com/
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
@@ -248,2 +248,30 @@ MochiKit.Base.update(Clipperz.Base, {
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 //-------------------------------------------------------------------------
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
@@ -199,8 +199,2 @@ Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new C
199 //------------------------------------------------------------------------- 199 //-------------------------------------------------------------------------
200
201 'pollingFrequency': function() {
202 return 10;
203 },
204
205 //-------------------------------------------------------------------------
206 __syntaxFix__: "syntax fix" 200 __syntaxFix__: "syntax fix"
@@ -247,4 +241,4 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
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();
@@ -252,3 +246,3 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
252 if (numberOfRandomBitsCollected == 8) { 246 if (numberOfRandomBitsCollected == 8) {
253 this.updateGeneratorWithValue(collectetBits); 247 this.updateGeneratorWithValue(collectedBits);
254 numberOfRandomBitsCollected = 0; 248 numberOfRandomBitsCollected = 0;
@@ -291,8 +285,2 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
291 //------------------------------------------------------------------------- 285 //-------------------------------------------------------------------------
292
293 'pollingFrequency': function() {
294 return 10;
295 },
296
297 //-------------------------------------------------------------------------
298 __syntaxFix__: "syntax fix" 286 __syntaxFix__: "syntax fix"
@@ -302,11 +290,11 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
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;
@@ -314,30 +302,10 @@ Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) {
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 },
@@ -346,28 +314,18 @@ Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(n
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 },
@@ -375,8 +333,2 @@ Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(n
375 //------------------------------------------------------------------------- 333 //-------------------------------------------------------------------------
376
377 'pollingFrequency': function() {
378 return 10;
379 },
380
381 //-------------------------------------------------------------------------
382 __syntaxFix__: "syntax fix" 334 __syntaxFix__: "syntax fix"
@@ -609,9 +561,6 @@ MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
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;
@@ -621,5 +570,3 @@ MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
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,
@@ -631,3 +578,2 @@ MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
631 } 578 }
632//MochiKit.Logging.logDebug("<<< PRNG.deferredEntropyCollection - result: " + result);
633 579
@@ -645,3 +591,3 @@ MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
645 //------------------------------------------------------------------------- 591 //-------------------------------------------------------------------------
646 592/*
647 'dump': function(appendToDoc) { 593 'dump': function(appendToDoc) {
@@ -751,3 +697,3 @@ MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
751 }, 697 },
752 698*/
753 //----------------------------------------------------------------------------- 699 //-----------------------------------------------------------------------------
@@ -826,3 +772,3 @@ Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
826 // 772 //
827 // KeyboardRandomnessSource 773 // CryptoRandomRandomnessSource
828 // 774 //
@@ -831,7 +777,17 @@ Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
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 }
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
@@ -46,2 +46,4 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, {
46 '_g': null, 46 '_g': null,
47 '_k': null,
48
47 //------------------------------------------------------------------------- 49 //-------------------------------------------------------------------------
@@ -66,2 +68,11 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, {
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 //-----------------------------------------------------------------------------
@@ -131,3 +142,2 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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 }
@@ -141,10 +151,8 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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 }
@@ -158,3 +166,2 @@ MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to
158 return this._s; 166 return this._s;
159//MochiKit.Logging.logDebug("SRP s: " + this._S);
160 }, 167 },
@@ -172,8 +179,6 @@ MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to
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;
@@ -187,3 +192,2 @@ MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to
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 }
@@ -197,4 +201,3 @@ MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to
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 }
@@ -215,7 +218,12 @@ MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to
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 }
@@ -230,3 +238,2 @@ MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to
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 }
@@ -240,4 +247,16 @@ MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to
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 }
@@ -252,3 +271,3 @@ MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to
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 }
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
@@ -140,3 +140,3 @@ Clipperz.PM.BookmarkletProcessor.prototype = MochiKit.Base.update(null, {
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);
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
@@ -102,3 +102,3 @@ YAHOO.extendX(Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent, C
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()) {
@@ -152,3 +152,3 @@ YAHOO.extendX(Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent, C
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");
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
@@ -40,3 +40,3 @@ Clipperz.PM.DataModel.DirectLogin = function(args) {
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";
@@ -104,5 +104,5 @@ Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, {
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 }
@@ -139,2 +139,10 @@ Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, {
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 //-------------------------------------------------------------------------
@@ -444,3 +452,3 @@ Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, {
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");
@@ -489,5 +497,5 @@ Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, {
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;
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
@@ -49,3 +49,3 @@ Clipperz.PM.DataModel.DirectLoginReference = function(args) {
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
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
@@ -39,2 +39,3 @@ Clipperz.PM.Proxy.Offline.DataStore = function(args) {
39 39
40 this._C = null;
40 this._b = null; 41 this._b = null;
@@ -146,2 +147,12 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
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() {
@@ -238,4 +249,4 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
238 //========================================================================= 249 //=========================================================================
239 250
240 'processMessage': function(aFunctionName, someParameters) { 251 'processMessage': function (aFunctionName, someParameters) {
241 var result; 252 var result;
@@ -305,3 +316,3 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
305 } else { 316 } else {
306 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 317 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
307 } 318 }
@@ -312,3 +323,3 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
312 'result':'done' 323 'result':'done'
313 }, 324 },
314 toll: this.getTollForRequestType('CONNECT') 325 toll: this.getTollForRequestType('CONNECT')
@@ -342,5 +353,6 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
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
@@ -353,3 +365,6 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
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
@@ -357,9 +372,17 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
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) {
@@ -367,3 +390,7 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
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;
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
@@ -23,2 +23,4 @@ refer to http://www.clipperz.com.
23 23
24"use strict";
25
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { 26try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
@@ -199,8 +201,2 @@ Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new C
199 //------------------------------------------------------------------------- 201 //-------------------------------------------------------------------------
200
201 'pollingFrequency': function() {
202 return 10;
203 },
204
205 //-------------------------------------------------------------------------
206 __syntaxFix__: "syntax fix" 202 __syntaxFix__: "syntax fix"
@@ -247,4 +243,4 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
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();
@@ -252,3 +248,3 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
252 if (numberOfRandomBitsCollected == 8) { 248 if (numberOfRandomBitsCollected == 8) {
253 this.updateGeneratorWithValue(collectetBits); 249 this.updateGeneratorWithValue(collectedBits);
254 numberOfRandomBitsCollected = 0; 250 numberOfRandomBitsCollected = 0;
@@ -291,8 +287,2 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
291 //------------------------------------------------------------------------- 287 //-------------------------------------------------------------------------
292
293 'pollingFrequency': function() {
294 return 10;
295 },
296
297 //-------------------------------------------------------------------------
298 __syntaxFix__: "syntax fix" 288 __syntaxFix__: "syntax fix"
@@ -302,11 +292,11 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
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;
@@ -314,30 +304,10 @@ Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) {
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 },
@@ -346,28 +316,18 @@ Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(n
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 },
@@ -375,8 +335,2 @@ Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(n
375 //------------------------------------------------------------------------- 335 //-------------------------------------------------------------------------
376
377 'pollingFrequency': function() {
378 return 10;
379 },
380
381 //-------------------------------------------------------------------------
382 __syntaxFix__: "syntax fix" 336 __syntaxFix__: "syntax fix"
@@ -637,3 +591,3 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
637 //------------------------------------------------------------------------- 591 //-------------------------------------------------------------------------
638 592/*
639 'dump': function(appendToDoc) { 593 'dump': function(appendToDoc) {
@@ -743,3 +697,3 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
743 }, 697 },
744 698*/
745 //----------------------------------------------------------------------------- 699 //-----------------------------------------------------------------------------
@@ -786,3 +740,3 @@ Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
786 740
787_clipperz_crypt_prng_defaultPRNG = null; 741var _clipperz_crypt_prng_defaultPRNG = null;
788 742
@@ -818,3 +772,3 @@ Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
818 // 772 //
819 // KeyboardRandomnessSource 773 // CryptoRandomRandomnessSource
820 // 774 //
@@ -823,7 +777,17 @@ Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
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 }
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
@@ -46,2 +46,4 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, {
46 '_g': null, 46 '_g': null,
47 '_k': null,
48
47 //------------------------------------------------------------------------- 49 //-------------------------------------------------------------------------
@@ -66,2 +68,11 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, {
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 //-----------------------------------------------------------------------------
@@ -140,6 +151,5 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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.");
@@ -169,6 +179,5 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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.");
@@ -192,3 +201,3 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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 }
@@ -209,5 +218,11 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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 )
@@ -232,3 +247,16 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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 }
@@ -243,2 +271,3 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(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 }
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
@@ -90,3 +90,3 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.P
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
@@ -99,12 +99,23 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.P
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) {
@@ -112,3 +123,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.P
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;
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
@@ -23,2 +23,4 @@ refer to http://www.clipperz.com.
23 23
24"use strict";
25
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { 26try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
@@ -199,8 +201,2 @@ Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new C
199 //------------------------------------------------------------------------- 201 //-------------------------------------------------------------------------
200
201 'pollingFrequency': function() {
202 return 10;
203 },
204
205 //-------------------------------------------------------------------------
206 __syntaxFix__: "syntax fix" 202 __syntaxFix__: "syntax fix"
@@ -247,4 +243,4 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
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();
@@ -252,3 +248,3 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
252 if (numberOfRandomBitsCollected == 8) { 248 if (numberOfRandomBitsCollected == 8) {
253 this.updateGeneratorWithValue(collectetBits); 249 this.updateGeneratorWithValue(collectedBits);
254 numberOfRandomBitsCollected = 0; 250 numberOfRandomBitsCollected = 0;
@@ -291,8 +287,2 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
291 //------------------------------------------------------------------------- 287 //-------------------------------------------------------------------------
292
293 'pollingFrequency': function() {
294 return 10;
295 },
296
297 //-------------------------------------------------------------------------
298 __syntaxFix__: "syntax fix" 288 __syntaxFix__: "syntax fix"
@@ -302,11 +292,11 @@ Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new
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;
@@ -314,30 +304,10 @@ Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) {
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 },
@@ -346,28 +316,18 @@ Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(n
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 },
@@ -375,8 +335,2 @@ Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(n
375 //------------------------------------------------------------------------- 335 //-------------------------------------------------------------------------
376
377 'pollingFrequency': function() {
378 return 10;
379 },
380
381 //-------------------------------------------------------------------------
382 __syntaxFix__: "syntax fix" 336 __syntaxFix__: "syntax fix"
@@ -637,3 +591,3 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
637 //------------------------------------------------------------------------- 591 //-------------------------------------------------------------------------
638 592/*
639 'dump': function(appendToDoc) { 593 'dump': function(appendToDoc) {
@@ -743,3 +697,3 @@ Clipperz.logWarning("Fortuna generator has not enough entropy, yet!");
743 }, 697 },
744 698*/
745 //----------------------------------------------------------------------------- 699 //-----------------------------------------------------------------------------
@@ -786,3 +740,3 @@ Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
786 740
787_clipperz_crypt_prng_defaultPRNG = null; 741var _clipperz_crypt_prng_defaultPRNG = null;
788 742
@@ -818,3 +772,3 @@ Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
818 // 772 //
819 // KeyboardRandomnessSource 773 // CryptoRandomRandomnessSource
820 // 774 //
@@ -823,7 +777,17 @@ Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
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 }
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
@@ -46,2 +46,4 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, {
46 '_g': null, 46 '_g': null,
47 '_k': null,
48
47 //------------------------------------------------------------------------- 49 //-------------------------------------------------------------------------
@@ -66,2 +68,11 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, {
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 //-----------------------------------------------------------------------------
@@ -140,6 +151,5 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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.");
@@ -169,6 +179,5 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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.");
@@ -192,3 +201,3 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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 }
@@ -209,5 +218,11 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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 )
@@ -232,3 +247,16 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
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 }
@@ -243,2 +271,3 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(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 }
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
@@ -38,3 +38,3 @@ Clipperz.PM.Proxy.Offline.DataStore = function(args) {
38 this._currentStaticConnection = null; 38 this._currentStaticConnection = null;
39 39
40 return this; 40 return this;
@@ -293,3 +293,3 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
293 } else { 293 } else {
294 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 294 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
295 } 295 }
@@ -300,3 +300,3 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
300 'result':'done' 300 'result':'done'
301 }, 301 },
302 toll: this.getTollForRequestType('CONNECT') 302 toll: this.getTollForRequestType('CONNECT')
@@ -331,3 +331,3 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
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
@@ -340,12 +340,23 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
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) {
@@ -353,3 +364,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
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;