summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js47
-rw-r--r--frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js27
-rw-r--r--frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js35
3 files changed, 83 insertions, 26 deletions
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
@@ -16,48 +16,49 @@ refer to http://www.clipperz.com.
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) { 24try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!"; 25 throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!";
26} 26}
27 27
28//============================================================================= 28//=============================================================================
29 29
30Clipperz.PM.Proxy.Offline.DataStore = function(args) { 30Clipperz.PM.Proxy.Offline.DataStore = function(args) {
31 args = args || {}; 31 args = args || {};
32 32
33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null); 33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null);
34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); 34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly);
35 this._shouldPayTolls = args.shouldPayTolls || false; 35 this._shouldPayTolls = args.shouldPayTolls || false;
36 36
37 this._tolls = {}; 37 this._tolls = {};
38 this._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 //-------------------------------------------------------------------------
52 53
53 'isReadOnly': function () { 54 'isReadOnly': function () {
54 return this._isReadOnly; 55 return this._isReadOnly;
55 }, 56 },
56 57
57 //------------------------------------------------------------------------- 58 //-------------------------------------------------------------------------
58 59
59 'shouldPayTolls': function() { 60 'shouldPayTolls': function() {
60 return this._shouldPayTolls; 61 return this._shouldPayTolls;
61 }, 62 },
62 63
63 //------------------------------------------------------------------------- 64 //-------------------------------------------------------------------------
@@ -123,48 +124,58 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
123 'v': aUserSerializationContext['credentials']['v'], 124 'v': aUserSerializationContext['credentials']['v'],
124 'version': aUserSerializationContext['data']['connectionVersion'], 125 'version': aUserSerializationContext['data']['connectionVersion'],
125 'userDetails': aUserSerializationContext['encryptedData']['user']['header'], 126 'userDetails': aUserSerializationContext['encryptedData']['user']['header'],
126 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'], 127 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'],
127 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'], 128 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'],
128 'lock': aUserSerializationContext['encryptedData']['user']['lock'], 129 'lock': aUserSerializationContext['encryptedData']['user']['lock'],
129 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records']) 130 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records'])
130 } 131 }
131 }, this)); 132 }, this));
132 } 133 }
133 134
134 deferredResult.addCallback(MochiKit.Base.bind(function() { 135 deferredResult.addCallback(MochiKit.Base.bind(function() {
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;
159 }, 170 },
160 171
161 'set_B': function(aValue) { 172 'set_B': function(aValue) {
162 this._B = aValue; 173 this._B = aValue;
163 }, 174 },
164 175
165 //------------------------------------------------------------------------- 176 //-------------------------------------------------------------------------
166 177
167 'A': function() { 178 'A': function() {
168 return this._A; 179 return this._A;
169 }, 180 },
170 181
@@ -215,50 +226,50 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
215 return result; 226 return result;
216 }, 227 },
217 228
218 //------------------------------------------------------------------------- 229 //-------------------------------------------------------------------------
219 230
220 'checkToll': function (aFunctionName, someParameters) { 231 'checkToll': function (aFunctionName, someParameters) {
221 if (this.shouldPayTolls()) { 232 if (this.shouldPayTolls()) {
222 var localToll; 233 var localToll;
223 vartollParameters; 234 vartollParameters;
224 235
225 tollParameters = someParameters['toll']; 236 tollParameters = someParameters['toll'];
226 localToll = this.tolls()[tollParameters['targetValue']]; 237 localToll = this.tolls()[tollParameters['targetValue']];
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);
253 result = this._handshake(someParameters.parameters); 264 result = this._handshake(someParameters.parameters);
254 break; 265 break;
255 case 'message': 266 case 'message':
256 this.checkToll(aFunctionName, someParameters); 267 this.checkToll(aFunctionName, someParameters);
257 result = this._message(someParameters.parameters); 268 result = this._message(someParameters.parameters);
258 break; 269 break;
259 case 'logout': 270 case 'logout':
260 result = this._logout(someParameters.parameters); 271 result = this._logout(someParameters.parameters);
261 break; 272 break;
262 } 273 }
263 274
264 return result; 275 return result;
@@ -282,111 +293,127 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
282 }, 293 },
283 294
284 //------------------------------------------------------------------------- 295 //-------------------------------------------------------------------------
285 296
286 '_registration': function(someParameters) { 297 '_registration': function(someParameters) {
287//console.log("_registration", someParameters); 298//console.log("_registration", someParameters);
288 if (this.isReadOnly() == false) { 299 if (this.isReadOnly() == false) {
289 if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') { 300 if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') {
290 this.data()['users'][someParameters['credentials']['C']] = { 301 this.data()['users'][someParameters['credentials']['C']] = {
291 's': someParameters['credentials']['s'], 302 's': someParameters['credentials']['s'],
292 'v': someParameters['credentials']['v'], 303 'v': someParameters['credentials']['v'],
293 'version':someParameters['credentials']['version'], 304 'version':someParameters['credentials']['version'],
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
326//Clipperz.log(">>> Proxy.Offline.DataStore._handshake"); 337//Clipperz.log(">>> Proxy.Offline.DataStore._handshake");
327 result = {}; 338 result = {};
328 if (someParameters.message == "connect") { 339 if (someParameters.message == "connect") {
329 var userData; 340 var userData;
330 var randomBytes; 341 var randomBytes;
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']));
381 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; 408 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey];
382 409
383 try { 410 try {
384 if (typeof(otpData) != 'undefined') { 411 if (typeof(otpData) != 'undefined') {
385 if (otpData['status'] == 'ACTIVE') { 412 if (otpData['status'] == 'ACTIVE') {
386 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { 413 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) {
387 result = { 414 result = {
388 'data': otpData['data'], 415 'data': otpData['data'],
389 'version':otpData['version'] 416 'version':otpData['version']
390 } 417 }
391 418
392 otpData['status'] = 'REQUESTED'; 419 otpData['status'] = 'REQUESTED';
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
@@ -67,71 +67,86 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.P
67 //------------------------------------------------------------------------- 67 //-------------------------------------------------------------------------
68 68
69 '_handshake': function(aConnection, someParameters) { 69 '_handshake': function(aConnection, someParameters) {
70 var result; 70 var result;
71 varnextTollRequestType; 71 varnextTollRequestType;
72 72
73 result = {}; 73 result = {};
74 if (someParameters.message == "connect") { 74 if (someParameters.message == "connect") {
75 var userData; 75 var userData;
76 var randomBytes; 76 var randomBytes;
77 var v; 77 var v;
78 78
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 {
126 if (typeof(otpData) != 'undefined') { 141 if (typeof(otpData) != 'undefined') {
127 if (otpData['status'] == 'ACTIVE') { 142 if (otpData['status'] == 'ACTIVE') {
128 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { 143 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) {
129 result = { 144 result = {
130 'data': otpData['data'], 145 'data': otpData['data'],
131 'version':otpData['version'] 146 'version':otpData['version']
132 } 147 }
133 148
134 otpData['status'] = 'REQUESTED'; 149 otpData['status'] = 'REQUESTED';
135 } else { 150 } else {
136 otpData['status'] = 'DISABLED'; 151 otpData['status'] = 'DISABLED';
137 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; 152 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum";
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
@@ -15,49 +15,49 @@ refer to http://www.clipperz.com.
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) { 24try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!"; 25 throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!";
26} 26}
27 27
28//============================================================================= 28//=============================================================================
29 29
30Clipperz.PM.Proxy.Offline.DataStore = function(args) { 30Clipperz.PM.Proxy.Offline.DataStore = function(args) {
31 args = args || {}; 31 args = args || {};
32 32
33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null); 33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null);
34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); 34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly);
35 this._shouldPayTolls = args.shouldPayTolls || false; 35 this._shouldPayTolls = args.shouldPayTolls || false;
36 36
37 this._tolls = {}; 37 this._tolls = {};
38 this._currentStaticConnection = null; 38 this._currentStaticConnection = null;
39 39
40 return this; 40 return this;
41} 41}
42 42
43Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { 43Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
44 44
45 //------------------------------------------------------------------------- 45 //-------------------------------------------------------------------------
46 46
47 'isReadOnly': function () { 47 'isReadOnly': function () {
48 return this._isReadOnly; 48 return this._isReadOnly;
49 }, 49 },
50 50
51 //------------------------------------------------------------------------- 51 //-------------------------------------------------------------------------
52 52
53 'shouldPayTolls': function() { 53 'shouldPayTolls': function() {
54 return this._shouldPayTolls; 54 return this._shouldPayTolls;
55 }, 55 },
56 56
57 //------------------------------------------------------------------------- 57 //-------------------------------------------------------------------------
58 58
59 'data': function () { 59 'data': function () {
60 return this._data; 60 return this._data;
61 }, 61 },
62 62
63 //------------------------------------------------------------------------- 63 //-------------------------------------------------------------------------
@@ -270,109 +270,124 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
270 } 270 }
271 271
272 return result; 272 return result;
273 }, 273 },
274 274
275 //------------------------------------------------------------------------- 275 //-------------------------------------------------------------------------
276 276
277 '_registration': function(aConnection, someParameters) { 277 '_registration': function(aConnection, someParameters) {
278 if (this.isReadOnly() == false) { 278 if (this.isReadOnly() == false) {
279 if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') { 279 if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') {
280 this.data()['users'][someParameters['credentials']['C']] = { 280 this.data()['users'][someParameters['credentials']['C']] = {
281 's': someParameters['credentials']['s'], 281 's': someParameters['credentials']['s'],
282 'v': someParameters['credentials']['v'], 282 'v': someParameters['credentials']['v'],
283 'version':someParameters['credentials']['version'], 283 'version':someParameters['credentials']['version'],
284 // 'lock': Clipperz.Crypto.Base.generateRandomSeed(), 284 // 'lock': Clipperz.Crypto.Base.generateRandomSeed(),
285 'userDetails': someParameters['user']['header'], 285 'userDetails': someParameters['user']['header'],
286 'statistics': someParameters['user']['statistics'], 286 'statistics': someParameters['user']['statistics'],
287 'userDetailsVersion':someParameters['user']['version'], 287 'userDetailsVersion':someParameters['user']['version'],
288 'records':{} 288 'records':{}
289 } 289 }
290 } else { 290 } else {
291 throw "user already exists"; 291 throw "user already exists";
292 } 292 }
293 } else { 293 } else {
294 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 294 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
295 } 295 }
296 296
297 result = { 297 result = {
298 result: { 298 result: {
299 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'], 299 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'],
300 'result':'done' 300 'result':'done'
301 }, 301 },
302 toll: this.getTollForRequestType('CONNECT') 302 toll: this.getTollForRequestType('CONNECT')
303 } 303 }
304 304
305 return result; 305 return result;
306 }, 306 },
307 307
308 //------------------------------------------------------------------------- 308 //-------------------------------------------------------------------------
309 309
310 '_handshake': function(aConnection, someParameters) { 310 '_handshake': function(aConnection, someParameters) {
311 var result; 311 var result;
312 varnextTollRequestType; 312 varnextTollRequestType;
313 313
314 result = {}; 314 result = {};
315 if (someParameters.message == "connect") { 315 if (someParameters.message == "connect") {
316 var userData; 316 var userData;
317 var randomBytes; 317 var randomBytes;
318 var v; 318 var v;
319 319
320 userData = this.data()['users'][someParameters.parameters.C]; 320 userData = this.data()['users'][someParameters.parameters.C];
321 321
322 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) { 322 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) {
323 aConnection['userData'] = userData; 323 aConnection['userData'] = userData;
324 aConnection['C'] = someParameters.parameters.C; 324 aConnection['C'] = someParameters.parameters.C;
325 } else { 325 } else {
326 aConnection['userData'] = this.data()['users']['catchAllUser']; 326 aConnection['userData'] = this.data()['users']['catchAllUser'];
327 } 327 }
328 328
329 randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); 329 randomBytes = Clipperz.Crypto.Base.generateRandomSeed();
330 aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16); 330 aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16);
331 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); 331 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
332 aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); 332 aConnection['B'] = (Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()));
333 333
334 aConnection['A'] = someParameters.parameters.A; 334 aConnection['A'] = someParameters.parameters.A;
335 335
336 result['s'] = aConnection['userData']['s']; 336 result['s'] = aConnection['userData']['s'];
337 result['B'] = aConnection['B'].asString(16); 337 result['B'] = aConnection['B'].asString(16);
338 338
339 nextTollRequestType = 'CONNECT'; 339 nextTollRequestType = 'CONNECT';
340 } else if (someParameters.message == "credentialCheck") { 340 } else if (someParameters.message == "credentialCheck") {
341 var v, u, S, A, K, M1; 341 var v, u, s, S, A, K, M1;
342 342 var stringHash = function (aValue) {
343 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
344 };
345
343 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); 346 v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
344 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16);
345 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16); 347 A = new Clipperz.Crypto.BigInt(aConnection['A'], 16);
348 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10))).toHexString(), 16);
349 s = new Clipperz.Crypto.BigInt(aConnection['userData']['s'], 16);
346 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); 350 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n());
347 351
348 K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2); 352 K = stringHash(S.asString(10));
349 353
350 M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2); 354 M1 = stringHash(
355 "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" +
356 stringHash(aConnection['C']) +
357 s.asString(10) +
358 A.asString(10) +
359 aConnection['B'].asString(10) +
360 K
361 );
351 if (someParameters.parameters.M1 == M1) { 362 if (someParameters.parameters.M1 == M1) {
352 var M2; 363 var M2;
353 364
354 M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2); 365 M2 = stringHash(
366 A.asString(10) +
367 someParameters.parameters.M1 +
368 K
369 );
355 result['M2'] = M2; 370 result['M2'] = M2;
356 } else { 371 } else {
357 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); 372 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
358 } 373 }
359 374
360 nextTollRequestType = 'MESSAGE'; 375 nextTollRequestType = 'MESSAGE';
361 } else if (someParameters.message == "oneTimePassword") { 376 } else if (someParameters.message == "oneTimePassword") {
362 var otpData; 377 var otpData;
363 378
364 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; 379 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey];
365 380
366 try { 381 try {
367 if (typeof(otpData) != 'undefined') { 382 if (typeof(otpData) != 'undefined') {
368 if (otpData['status'] == 'ACTIVE') { 383 if (otpData['status'] == 'ACTIVE') {
369 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { 384 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) {
370 result = { 385 result = {
371 'data': otpData['data'], 386 'data': otpData['data'],
372 'version':otpData['version'] 387 'version':otpData['version']
373 } 388 }
374 389
375 otpData['status'] = 'REQUESTED'; 390 otpData['status'] = 'REQUESTED';
376 } else { 391 } else {
377 otpData['status'] = 'DISABLED'; 392 otpData['status'] = 'DISABLED';
378 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; 393 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum";