author | Michael Krelin <hacker@klever.net> | 2014-06-30 18:20:13 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2014-06-30 18:20:13 (UTC) |
commit | c392fe28606eefa0c814e5c25d641f5ffe623186 (patch) (unidiff) | |
tree | da03fe13ca09fadbebbad9b5d38750757270bae8 /frontend | |
parent | d341307d346dee62ee36b27f0f93b8f000748a96 (diff) | |
parent | 6dd16d9359e3a4dc306802588b09acd43947a606 (diff) | |
download | clipperz-c392fe28606eefa0c814e5c25d641f5ffe623186.zip clipperz-c392fe28606eefa0c814e5c25d641f5ffe623186.tar.gz clipperz-c392fe28606eefa0c814e5c25d641f5ffe623186.tar.bz2 |
Merge remote-tracking branch 'github/master' into nmaster
-rw-r--r-- | frontend/beta/js/Clipperz/Base.js | 28 | ||||
-rw-r--r-- | frontend/beta/js/Clipperz/Crypto/PRNG.js | 130 | ||||
-rw-r--r-- | frontend/beta/js/Clipperz/Crypto/SRP.js | 67 | ||||
-rw-r--r-- | frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js | 2 | ||||
-rw-r--r-- | frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js | 4 | ||||
-rw-r--r-- | frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js | 22 | ||||
-rw-r--r-- | frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js | 2 | ||||
-rw-r--r-- | frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js | 47 | ||||
-rw-r--r-- | frontend/delta/js/Clipperz/Crypto/PRNG.js | 128 | ||||
-rw-r--r-- | frontend/delta/js/Clipperz/Crypto/SRP.js | 53 | ||||
-rw-r--r-- | frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js | 27 | ||||
-rw-r--r-- | frontend/gamma/js/Clipperz/Crypto/PRNG.js | 128 | ||||
-rw-r--r-- | frontend/gamma/js/Clipperz/Crypto/SRP.js | 53 | ||||
-rw-r--r-- | frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js | 35 |
14 files changed, 390 insertions, 336 deletions
diff --git a/frontend/beta/js/Clipperz/Base.js b/frontend/beta/js/Clipperz/Base.js index cf40314..1c6faa1 100644 --- a/frontend/beta/js/Clipperz/Base.js +++ b/frontend/beta/js/Clipperz/Base.js | |||
@@ -1,303 +1,331 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | 24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } |
25 | if (typeof(Clipperz.Base) == 'undefined') { Clipperz.Base = {}; } | 25 | if (typeof(Clipperz.Base) == 'undefined') { Clipperz.Base = {}; } |
26 | 26 | ||
27 | Clipperz.Base.VERSION = "0.1"; | 27 | Clipperz.Base.VERSION = "0.1"; |
28 | Clipperz.Base.NAME = "Clipperz.Base"; | 28 | Clipperz.Base.NAME = "Clipperz.Base"; |
29 | 29 | ||
30 | MochiKit.Base.update(Clipperz.Base, { | 30 | MochiKit.Base.update(Clipperz.Base, { |
31 | 31 | ||
32 | //------------------------------------------------------------------------- | 32 | //------------------------------------------------------------------------- |
33 | 33 | ||
34 | '__repr__': function () { | 34 | '__repr__': function () { |
35 | return "[" + this.NAME + " " + this.VERSION + "]"; | 35 | return "[" + this.NAME + " " + this.VERSION + "]"; |
36 | }, | 36 | }, |
37 | 37 | ||
38 | //------------------------------------------------------------------------- | 38 | //------------------------------------------------------------------------- |
39 | 39 | ||
40 | 'toString': function () { | 40 | 'toString': function () { |
41 | return this.__repr__(); | 41 | return this.__repr__(); |
42 | }, | 42 | }, |
43 | 43 | ||
44 | //------------------------------------------------------------------------- | 44 | //------------------------------------------------------------------------- |
45 | 45 | ||
46 | 'trim': function (aValue) { | 46 | 'trim': function (aValue) { |
47 | return aValue.replace(/^\s+|\s+$/g, ""); | 47 | return aValue.replace(/^\s+|\s+$/g, ""); |
48 | }, | 48 | }, |
49 | 49 | ||
50 | //------------------------------------------------------------------------- | 50 | //------------------------------------------------------------------------- |
51 | 51 | ||
52 | 'stringToByteArray': function (aValue) { | 52 | 'stringToByteArray': function (aValue) { |
53 | varresult; | 53 | varresult; |
54 | var i, c; | 54 | var i, c; |
55 | 55 | ||
56 | result = []; | 56 | result = []; |
57 | 57 | ||
58 | c = aValue.length; | 58 | c = aValue.length; |
59 | for (i=0; i<c; i++) { | 59 | for (i=0; i<c; i++) { |
60 | result[i] = aValue.charCodeAt(i); | 60 | result[i] = aValue.charCodeAt(i); |
61 | } | 61 | } |
62 | 62 | ||
63 | return result; | 63 | return result; |
64 | }, | 64 | }, |
65 | 65 | ||
66 | //......................................................................... | 66 | //......................................................................... |
67 | 67 | ||
68 | 'byteArrayToString': function (anArrayOfBytes) { | 68 | 'byteArrayToString': function (anArrayOfBytes) { |
69 | varresult; | 69 | varresult; |
70 | var i, c; | 70 | var i, c; |
71 | 71 | ||
72 | result = ""; | 72 | result = ""; |
73 | 73 | ||
74 | c = anArrayOfBytes.length; | 74 | c = anArrayOfBytes.length; |
75 | for (i=0; i<c; i++) { | 75 | for (i=0; i<c; i++) { |
76 | result += String.fromCharCode(anArrayOfBytes[i]); | 76 | result += String.fromCharCode(anArrayOfBytes[i]); |
77 | } | 77 | } |
78 | 78 | ||
79 | return result; | 79 | return result; |
80 | }, | 80 | }, |
81 | 81 | ||
82 | //------------------------------------------------------------------------- | 82 | //------------------------------------------------------------------------- |
83 | 83 | ||
84 | 'getValueForKeyInFormContent': function (aFormContent, aKey) { | 84 | 'getValueForKeyInFormContent': function (aFormContent, aKey) { |
85 | return aFormContent[1][MochiKit.Base.find(aFormContent[0], aKey)]; | 85 | return aFormContent[1][MochiKit.Base.find(aFormContent[0], aKey)]; |
86 | }, | 86 | }, |
87 | 87 | ||
88 | //------------------------------------------------------------------------- | 88 | //------------------------------------------------------------------------- |
89 | 89 | ||
90 | 'indexOfObjectInArray': function(anObject, anArray) { | 90 | 'indexOfObjectInArray': function(anObject, anArray) { |
91 | varresult; | 91 | varresult; |
92 | vari, c; | 92 | vari, c; |
93 | 93 | ||
94 | result = -1; | 94 | result = -1; |
95 | 95 | ||
96 | c = anArray.length; | 96 | c = anArray.length; |
97 | for (i=0; ((i<c) && (result < 0)); i++) { | 97 | for (i=0; ((i<c) && (result < 0)); i++) { |
98 | if (anArray[i] === anObject) { | 98 | if (anArray[i] === anObject) { |
99 | result = i; | 99 | result = i; |
100 | } | 100 | } |
101 | } | 101 | } |
102 | 102 | ||
103 | return result; | 103 | return result; |
104 | }, | 104 | }, |
105 | 105 | ||
106 | 'removeObjectAtIndexFromArray': function(anIndex, anArray) { | 106 | 'removeObjectAtIndexFromArray': function(anIndex, anArray) { |
107 | anArray.splice(anIndex, 1); | 107 | anArray.splice(anIndex, 1); |
108 | }, | 108 | }, |
109 | 109 | ||
110 | 'removeObjectFromArray': function(anObject, anArray) { | 110 | 'removeObjectFromArray': function(anObject, anArray) { |
111 | varobjectIndex; | 111 | varobjectIndex; |
112 | 112 | ||
113 | objectIndex = Clipperz.Base.indexOfObjectInArray(anObject, anArray); | 113 | objectIndex = Clipperz.Base.indexOfObjectInArray(anObject, anArray); |
114 | if (objectIndex > -1) { | 114 | if (objectIndex > -1) { |
115 | Clipperz.Base.removeObjectAtIndexFromArray(objectIndex, anArray); | 115 | Clipperz.Base.removeObjectAtIndexFromArray(objectIndex, anArray); |
116 | } else { | 116 | } else { |
117 | // jslog.error("Trying to remove an object not present in the array"); | 117 | // jslog.error("Trying to remove an object not present in the array"); |
118 | //TODO: raise an exception | 118 | //TODO: raise an exception |
119 | } | 119 | } |
120 | }, | 120 | }, |
121 | 121 | ||
122 | 'removeFromArray': function(anArray, anObject) { | 122 | 'removeFromArray': function(anArray, anObject) { |
123 | return Clipperz.Base.removeObjectFromArray(anObject, anArray); | 123 | return Clipperz.Base.removeObjectFromArray(anObject, anArray); |
124 | }, | 124 | }, |
125 | 125 | ||
126 | //------------------------------------------------------------------------- | 126 | //------------------------------------------------------------------------- |
127 | 127 | ||
128 | 'splitStringAtFixedTokenSize': function(aString, aTokenSize) { | 128 | 'splitStringAtFixedTokenSize': function(aString, aTokenSize) { |
129 | var result; | 129 | var result; |
130 | varstringToProcess; | 130 | varstringToProcess; |
131 | 131 | ||
132 | stringToProcess = aString; | 132 | stringToProcess = aString; |
133 | result = []; | 133 | result = []; |
134 | if (stringToProcess != null) { | 134 | if (stringToProcess != null) { |
135 | while (stringToProcess.length > aTokenSize) { | 135 | while (stringToProcess.length > aTokenSize) { |
136 | result.push(stringToProcess.substring(0, aTokenSize)); | 136 | result.push(stringToProcess.substring(0, aTokenSize)); |
137 | stringToProcess = stringToProcess.substring(aTokenSize); | 137 | stringToProcess = stringToProcess.substring(aTokenSize); |
138 | } | 138 | } |
139 | 139 | ||
140 | result.push(stringToProcess); | 140 | result.push(stringToProcess); |
141 | } | 141 | } |
142 | 142 | ||
143 | return result; | 143 | return result; |
144 | }, | 144 | }, |
145 | 145 | ||
146 | //------------------------------------------------------------------------- | 146 | //------------------------------------------------------------------------- |
147 | 147 | ||
148 | 'objectType': function(anObject) { | 148 | 'objectType': function(anObject) { |
149 | var result; | 149 | var result; |
150 | 150 | ||
151 | if (anObject == null) { | 151 | if (anObject == null) { |
152 | result = null; | 152 | result = null; |
153 | } else { | 153 | } else { |
154 | result = typeof(anObject); | 154 | result = typeof(anObject); |
155 | 155 | ||
156 | if (result == "object") { | 156 | if (result == "object") { |
157 | if (anObject instanceof Array) { | 157 | if (anObject instanceof Array) { |
158 | result = 'array' | 158 | result = 'array' |
159 | } else if (anObject.constructor == Boolean) { | 159 | } else if (anObject.constructor == Boolean) { |
160 | result = 'boolean' | 160 | result = 'boolean' |
161 | } else if (anObject instanceof Date) { | 161 | } else if (anObject instanceof Date) { |
162 | result = 'date' | 162 | result = 'date' |
163 | } else if (anObject instanceof Error) { | 163 | } else if (anObject instanceof Error) { |
164 | result = 'error' | 164 | result = 'error' |
165 | } else if (anObject instanceof Function) { | 165 | } else if (anObject instanceof Function) { |
166 | result = 'function' | 166 | result = 'function' |
167 | } else if (anObject.constructor == Number) { | 167 | } else if (anObject.constructor == Number) { |
168 | result = 'number' | 168 | result = 'number' |
169 | } else if (anObject.constructor == String) { | 169 | } else if (anObject.constructor == String) { |
170 | result = 'string' | 170 | result = 'string' |
171 | } else if (anObject instanceof Object) { | 171 | } else if (anObject instanceof Object) { |
172 | result = 'object' | 172 | result = 'object' |
173 | } else { | 173 | } else { |
174 | throw Clipperz.Base.exception.UnknownType; | 174 | throw Clipperz.Base.exception.UnknownType; |
175 | } | 175 | } |
176 | } | 176 | } |
177 | } | 177 | } |
178 | 178 | ||
179 | return result; | 179 | return result; |
180 | }, | 180 | }, |
181 | 181 | ||
182 | //------------------------------------------------------------------------- | 182 | //------------------------------------------------------------------------- |
183 | 183 | ||
184 | 'escapeHTML': function(aValue) { | 184 | 'escapeHTML': function(aValue) { |
185 | var result; | 185 | var result; |
186 | 186 | ||
187 | result = aValue; | 187 | result = aValue; |
188 | result = result.replace(/</g, "<"); | 188 | result = result.replace(/</g, "<"); |
189 | result = result.replace(/>/g, ">"); | 189 | result = result.replace(/>/g, ">"); |
190 | 190 | ||
191 | return result; | 191 | return result; |
192 | }, | 192 | }, |
193 | 193 | ||
194 | //------------------------------------------------------------------------- | 194 | //------------------------------------------------------------------------- |
195 | 195 | ||
196 | 'deepClone': function(anObject) { | 196 | 'deepClone': function(anObject) { |
197 | var result; | 197 | var result; |
198 | 198 | ||
199 | result = Clipperz.Base.evalJSON(Clipperz.Base.serializeJSON(anObject)); | 199 | result = Clipperz.Base.evalJSON(Clipperz.Base.serializeJSON(anObject)); |
200 | 200 | ||
201 | return result; | 201 | return result; |
202 | }, | 202 | }, |
203 | 203 | ||
204 | //------------------------------------------------------------------------- | 204 | //------------------------------------------------------------------------- |
205 | 205 | ||
206 | 'evalJSON': function(aString) { | 206 | 'evalJSON': function(aString) { |
207 | /* | 207 | /* |
208 | var result; | 208 | var result; |
209 | 209 | ||
210 | //check for XSS injection | 210 | //check for XSS injection |
211 | if (/<script>/.test(aString)) { | 211 | if (/<script>/.test(aString)) { |
212 | throw "error"; | 212 | throw "error"; |
213 | } | 213 | } |
214 | 214 | ||
215 | if (/<iframe>/.test(aString)) { | 215 | if (/<iframe>/.test(aString)) { |
216 | throw "error"; | 216 | throw "error"; |
217 | } | 217 | } |
218 | 218 | ||
219 | result = MochiKit.Base.evalJSON(aString); | 219 | result = MochiKit.Base.evalJSON(aString); |
220 | 220 | ||
221 | return result; | 221 | return result; |
222 | */ | 222 | */ |
223 | 223 | ||
224 | // return MochiKit.Base.evalJSON(aString); | 224 | // return MochiKit.Base.evalJSON(aString); |
225 | return JSON2.parse(aString); | 225 | return JSON2.parse(aString); |
226 | }, | 226 | }, |
227 | 227 | ||
228 | 'serializeJSON': function(anObject) { | 228 | 'serializeJSON': function(anObject) { |
229 | // return MochiKit.Base.serializeJSON(anObject); | 229 | // return MochiKit.Base.serializeJSON(anObject); |
230 | return JSON2.stringify(anObject); | 230 | return JSON2.stringify(anObject); |
231 | }, | 231 | }, |
232 | 232 | ||
233 | //------------------------------------------------------------------------- | 233 | //------------------------------------------------------------------------- |
234 | 234 | ||
235 | 'sanitizeString': function(aValue) { | 235 | 'sanitizeString': function(aValue) { |
236 | var result; | 236 | var result; |
237 | 237 | ||
238 | if (Clipperz.Base.objectType(aValue) == 'string') { | 238 | if (Clipperz.Base.objectType(aValue) == 'string') { |
239 | result = aValue; | 239 | result = aValue; |
240 | result = result.replace(/</img,"<"); | 240 | result = result.replace(/</img,"<"); |
241 | result = result.replace(/>/img,">"); | 241 | result = result.replace(/>/img,">"); |
242 | } else { | 242 | } else { |
243 | result = aValue; | 243 | result = aValue; |
244 | } | 244 | } |
245 | 245 | ||
246 | return result; | 246 | return result; |
247 | }, | 247 | }, |
248 | 248 | ||
249 | 'javascriptInjectionPattern': new RegExp("javascript:\/\/\"", "g"), | ||
250 | |||
251 | 'sanitizeUrl': function(aValue) { | ||
252 | varresult; | ||
253 | |||
254 | if ((aValue != null) && this.javascriptInjectionPattern.test(aValue)) { | ||
255 | result = aValue.replace(this.javascriptInjectionPattern, ''); | ||
256 | console.log("sanitized url", aValue, result); | ||
257 | } else { | ||
258 | result = aValue; | ||
259 | } | ||
260 | |||
261 | return result; | ||
262 | }, | ||
263 | |||
264 | 'sanitizeFavicon': function(aValue) { | ||
265 | varresult; | ||
266 | |||
267 | if ((aValue != null) && this.javascriptInjectionPattern.test(aValue)) { | ||
268 | result = aValue.replace(this.javascriptInjectionPattern, ''); | ||
269 | console.log("sanitized favicon", aValue, result); | ||
270 | } else { | ||
271 | result = aValue; | ||
272 | } | ||
273 | |||
274 | return result; | ||
275 | }, | ||
276 | |||
249 | //------------------------------------------------------------------------- | 277 | //------------------------------------------------------------------------- |
250 | 278 | ||
251 | 'exception': { | 279 | 'exception': { |
252 | 'AbstractMethod': new MochiKit.Base.NamedError("Clipperz.Base.exception.AbstractMethod"), | 280 | 'AbstractMethod': new MochiKit.Base.NamedError("Clipperz.Base.exception.AbstractMethod"), |
253 | 'UnknownType': new MochiKit.Base.NamedError("Clipperz.Base.exception.UnknownType"), | 281 | 'UnknownType': new MochiKit.Base.NamedError("Clipperz.Base.exception.UnknownType"), |
254 | 'VulnerabilityIssue':new MochiKit.Base.NamedError("Clipperz.Base.exception.VulnerabilityIssue") | 282 | 'VulnerabilityIssue':new MochiKit.Base.NamedError("Clipperz.Base.exception.VulnerabilityIssue") |
255 | }, | 283 | }, |
256 | 284 | ||
257 | //------------------------------------------------------------------------- | 285 | //------------------------------------------------------------------------- |
258 | __syntaxFix__: "syntax fix" | 286 | __syntaxFix__: "syntax fix" |
259 | 287 | ||
260 | }); | 288 | }); |
261 | 289 | ||
262 | 290 | ||
263 | 291 | ||
264 | MochiKit.Base.registerComparator('Object dummy comparator', | 292 | MochiKit.Base.registerComparator('Object dummy comparator', |
265 | function(a, b) { | 293 | function(a, b) { |
266 | return ((a.constructor == Object) && (b.constructor == Object)); | 294 | return ((a.constructor == Object) && (b.constructor == Object)); |
267 | }, | 295 | }, |
268 | function(a, b) { | 296 | function(a, b) { |
269 | var result; | 297 | var result; |
270 | var aKeys; | 298 | var aKeys; |
271 | var bKeys; | 299 | var bKeys; |
272 | 300 | ||
273 | //MochiKit.Logging.logDebug(">>> comparator"); | 301 | //MochiKit.Logging.logDebug(">>> comparator"); |
274 | //MochiKit.Logging.logDebug("- a: " + Clipperz.Base.serializeJSON(a)); | 302 | //MochiKit.Logging.logDebug("- a: " + Clipperz.Base.serializeJSON(a)); |
275 | //MochiKit.Logging.logDebug("- b: " + Clipperz.Base.serializeJSON(a)); | 303 | //MochiKit.Logging.logDebug("- b: " + Clipperz.Base.serializeJSON(a)); |
276 | aKeys = MochiKit.Base.keys(a).sort(); | 304 | aKeys = MochiKit.Base.keys(a).sort(); |
277 | bKeys = MochiKit.Base.keys(b).sort(); | 305 | bKeys = MochiKit.Base.keys(b).sort(); |
278 | 306 | ||
279 | result = MochiKit.Base.compare(aKeys, bKeys); | 307 | result = MochiKit.Base.compare(aKeys, bKeys); |
280 | //if (result != 0) { | 308 | //if (result != 0) { |
281 | //MochiKit.Logging.logDebug("- comparator 'keys':"); | 309 | //MochiKit.Logging.logDebug("- comparator 'keys':"); |
282 | //MochiKit.Logging.logDebug("- comparator aKeys: " + Clipperz.Base.serializeJSON(aKeys)); | 310 | //MochiKit.Logging.logDebug("- comparator aKeys: " + Clipperz.Base.serializeJSON(aKeys)); |
283 | //MochiKit.Logging.logDebug("- comparator bKeys: " + Clipperz.Base.serializeJSON(bKeys)); | 311 | //MochiKit.Logging.logDebug("- comparator bKeys: " + Clipperz.Base.serializeJSON(bKeys)); |
284 | //} | 312 | //} |
285 | if (result == 0) { | 313 | if (result == 0) { |
286 | vari, c; | 314 | vari, c; |
287 | 315 | ||
288 | c = aKeys.length; | 316 | c = aKeys.length; |
289 | for (i=0; (i<c) && (result == 0); i++) { | 317 | for (i=0; (i<c) && (result == 0); i++) { |
290 | result = MochiKit.Base.compare(a[aKeys[i]], b[bKeys[i]]); | 318 | result = MochiKit.Base.compare(a[aKeys[i]], b[bKeys[i]]); |
291 | //if (result != 0) { | 319 | //if (result != 0) { |
292 | //MochiKit.Logging.logDebug("- comparator 'values':"); | 320 | //MochiKit.Logging.logDebug("- comparator 'values':"); |
293 | //MochiKit.Logging.logDebug("- comparator a[aKeys[i]]: " + Clipperz.Base.serializeJSON(a[aKeys[i]])); | 321 | //MochiKit.Logging.logDebug("- comparator a[aKeys[i]]: " + Clipperz.Base.serializeJSON(a[aKeys[i]])); |
294 | //MochiKit.Logging.logDebug("- comparator b[bKeys[i]]: " + Clipperz.Base.serializeJSON(b[bKeys[i]])); | 322 | //MochiKit.Logging.logDebug("- comparator b[bKeys[i]]: " + Clipperz.Base.serializeJSON(b[bKeys[i]])); |
295 | //} | 323 | //} |
296 | } | 324 | } |
297 | } | 325 | } |
298 | 326 | ||
299 | //MochiKit.Logging.logDebug("<<< comparator - result: " + result); | 327 | //MochiKit.Logging.logDebug("<<< comparator - result: " + result); |
300 | return result; | 328 | return result; |
301 | }, | 329 | }, |
302 | true | 330 | true |
303 | ); | 331 | ); |
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 | |||
@@ -1,849 +1,805 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { | 24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { |
25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; | 25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; |
26 | } | 26 | } |
27 | 27 | ||
28 | try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) { | 28 | try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) { |
29 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!"; | 29 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!"; |
30 | } | 30 | } |
31 | 31 | ||
32 | try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) { | 32 | try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) { |
33 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!"; | 33 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!"; |
34 | } | 34 | } |
35 | 35 | ||
36 | if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; } | 36 | if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; } |
37 | 37 | ||
38 | //############################################################################# | 38 | //############################################################################# |
39 | 39 | ||
40 | Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) { | 40 | Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) { |
41 | args = args || {}; | 41 | args = args || {}; |
42 | //MochiKit.Base.bindMethods(this); | 42 | //MochiKit.Base.bindMethods(this); |
43 | 43 | ||
44 | this._stack = new Clipperz.ByteArray(); | 44 | this._stack = new Clipperz.ByteArray(); |
45 | this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256; | 45 | this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256; |
46 | return this; | 46 | return this; |
47 | } | 47 | } |
48 | 48 | ||
49 | Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, { | 49 | Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, { |
50 | 50 | ||
51 | 'toString': function() { | 51 | 'toString': function() { |
52 | return "Clipperz.Crypto.PRNG.EntropyAccumulator"; | 52 | return "Clipperz.Crypto.PRNG.EntropyAccumulator"; |
53 | }, | 53 | }, |
54 | 54 | ||
55 | //------------------------------------------------------------------------- | 55 | //------------------------------------------------------------------------- |
56 | 56 | ||
57 | 'stack': function() { | 57 | 'stack': function() { |
58 | return this._stack; | 58 | return this._stack; |
59 | }, | 59 | }, |
60 | 60 | ||
61 | 'setStack': function(aValue) { | 61 | 'setStack': function(aValue) { |
62 | this._stack = aValue; | 62 | this._stack = aValue; |
63 | }, | 63 | }, |
64 | 64 | ||
65 | 'resetStack': function() { | 65 | 'resetStack': function() { |
66 | this.stack().reset(); | 66 | this.stack().reset(); |
67 | }, | 67 | }, |
68 | 68 | ||
69 | 'maxStackLengthBeforeHashing': function() { | 69 | 'maxStackLengthBeforeHashing': function() { |
70 | return this._maxStackLengthBeforeHashing; | 70 | return this._maxStackLengthBeforeHashing; |
71 | }, | 71 | }, |
72 | 72 | ||
73 | //------------------------------------------------------------------------- | 73 | //------------------------------------------------------------------------- |
74 | 74 | ||
75 | 'addRandomByte': function(aValue) { | 75 | 'addRandomByte': function(aValue) { |
76 | this.stack().appendByte(aValue); | 76 | this.stack().appendByte(aValue); |
77 | 77 | ||
78 | if (this.stack().length() > this.maxStackLengthBeforeHashing()) { | 78 | if (this.stack().length() > this.maxStackLengthBeforeHashing()) { |
79 | this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack())); | 79 | this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack())); |
80 | } | 80 | } |
81 | }, | 81 | }, |
82 | 82 | ||
83 | //------------------------------------------------------------------------- | 83 | //------------------------------------------------------------------------- |
84 | __syntaxFix__: "syntax fix" | 84 | __syntaxFix__: "syntax fix" |
85 | }); | 85 | }); |
86 | 86 | ||
87 | //############################################################################# | 87 | //############################################################################# |
88 | 88 | ||
89 | Clipperz.Crypto.PRNG.RandomnessSource = function(args) { | 89 | Clipperz.Crypto.PRNG.RandomnessSource = function(args) { |
90 | args = args || {}; | 90 | args = args || {}; |
91 | MochiKit.Base.bindMethods(this); | 91 | MochiKit.Base.bindMethods(this); |
92 | 92 | ||
93 | this._generator = args.generator || null; | 93 | this._generator = args.generator || null; |
94 | this._sourceId = args.sourceId || null; | 94 | this._sourceId = args.sourceId || null; |
95 | this._boostMode = args.boostMode || false; | 95 | this._boostMode = args.boostMode || false; |
96 | 96 | ||
97 | this._nextPoolIndex = 0; | 97 | this._nextPoolIndex = 0; |
98 | 98 | ||
99 | return this; | 99 | return this; |
100 | } | 100 | } |
101 | 101 | ||
102 | Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, { | 102 | Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, { |
103 | 103 | ||
104 | 'generator': function() { | 104 | 'generator': function() { |
105 | return this._generator; | 105 | return this._generator; |
106 | }, | 106 | }, |
107 | 107 | ||
108 | 'setGenerator': function(aValue) { | 108 | 'setGenerator': function(aValue) { |
109 | this._generator = aValue; | 109 | this._generator = aValue; |
110 | }, | 110 | }, |
111 | 111 | ||
112 | //------------------------------------------------------------------------- | 112 | //------------------------------------------------------------------------- |
113 | 113 | ||
114 | 'boostMode': function() { | 114 | 'boostMode': function() { |
115 | return this._boostMode; | 115 | return this._boostMode; |
116 | }, | 116 | }, |
117 | 117 | ||
118 | 'setBoostMode': function(aValue) { | 118 | 'setBoostMode': function(aValue) { |
119 | this._boostMode = aValue; | 119 | this._boostMode = aValue; |
120 | }, | 120 | }, |
121 | 121 | ||
122 | //------------------------------------------------------------------------- | 122 | //------------------------------------------------------------------------- |
123 | 123 | ||
124 | 'sourceId': function() { | 124 | 'sourceId': function() { |
125 | return this._sourceId; | 125 | return this._sourceId; |
126 | }, | 126 | }, |
127 | 127 | ||
128 | 'setSourceId': function(aValue) { | 128 | 'setSourceId': function(aValue) { |
129 | this._sourceId = aValue; | 129 | this._sourceId = aValue; |
130 | }, | 130 | }, |
131 | 131 | ||
132 | //------------------------------------------------------------------------- | 132 | //------------------------------------------------------------------------- |
133 | 133 | ||
134 | 'nextPoolIndex': function() { | 134 | 'nextPoolIndex': function() { |
135 | return this._nextPoolIndex; | 135 | return this._nextPoolIndex; |
136 | }, | 136 | }, |
137 | 137 | ||
138 | 'incrementNextPoolIndex': function() { | 138 | 'incrementNextPoolIndex': function() { |
139 | this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators()); | 139 | this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators()); |
140 | }, | 140 | }, |
141 | 141 | ||
142 | //------------------------------------------------------------------------- | 142 | //------------------------------------------------------------------------- |
143 | 143 | ||
144 | 'updateGeneratorWithValue': function(aRandomValue) { | 144 | 'updateGeneratorWithValue': function(aRandomValue) { |
145 | if (this.generator() != null) { | 145 | if (this.generator() != null) { |
146 | this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue); | 146 | this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue); |
147 | this.incrementNextPoolIndex(); | 147 | this.incrementNextPoolIndex(); |
148 | } | 148 | } |
149 | }, | 149 | }, |
150 | 150 | ||
151 | //------------------------------------------------------------------------- | 151 | //------------------------------------------------------------------------- |
152 | __syntaxFix__: "syntax fix" | 152 | __syntaxFix__: "syntax fix" |
153 | }); | 153 | }); |
154 | 154 | ||
155 | //############################################################################# | 155 | //############################################################################# |
156 | 156 | ||
157 | Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { | 157 | Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { |
158 | args = args || {}; | 158 | args = args || {}; |
159 | //MochiKit.Base.bindMethods(this); | 159 | //MochiKit.Base.bindMethods(this); |
160 | 160 | ||
161 | this._intervalTime = args.intervalTime || 1000; | 161 | this._intervalTime = args.intervalTime || 1000; |
162 | 162 | ||
163 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); | 163 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); |
164 | 164 | ||
165 | this.collectEntropy(); | 165 | this.collectEntropy(); |
166 | return this; | 166 | return this; |
167 | } | 167 | } |
168 | 168 | ||
169 | Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { | 169 | Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { |
170 | 170 | ||
171 | 'intervalTime': function() { | 171 | 'intervalTime': function() { |
172 | return this._intervalTime; | 172 | return this._intervalTime; |
173 | }, | 173 | }, |
174 | 174 | ||
175 | //------------------------------------------------------------------------- | 175 | //------------------------------------------------------------------------- |
176 | 176 | ||
177 | 'collectEntropy': function() { | 177 | 'collectEntropy': function() { |
178 | varnow; | 178 | varnow; |
179 | varentropyByte; | 179 | varentropyByte; |
180 | var intervalTime; | 180 | var intervalTime; |
181 | now = new Date(); | 181 | now = new Date(); |
182 | entropyByte = (now.getTime() & 0xff); | 182 | entropyByte = (now.getTime() & 0xff); |
183 | 183 | ||
184 | intervalTime = this.intervalTime(); | 184 | intervalTime = this.intervalTime(); |
185 | if (this.boostMode() == true) { | 185 | if (this.boostMode() == true) { |
186 | intervalTime = intervalTime / 9; | 186 | intervalTime = intervalTime / 9; |
187 | } | 187 | } |
188 | 188 | ||
189 | this.updateGeneratorWithValue(entropyByte); | 189 | this.updateGeneratorWithValue(entropyByte); |
190 | setTimeout(this.collectEntropy, intervalTime); | 190 | setTimeout(this.collectEntropy, intervalTime); |
191 | }, | 191 | }, |
192 | 192 | ||
193 | //------------------------------------------------------------------------- | 193 | //------------------------------------------------------------------------- |
194 | 194 | ||
195 | 'numberOfRandomBits': function() { | 195 | 'numberOfRandomBits': function() { |
196 | return 5; | 196 | return 5; |
197 | }, | 197 | }, |
198 | 198 | ||
199 | //------------------------------------------------------------------------- | 199 | //------------------------------------------------------------------------- |
200 | |||
201 | 'pollingFrequency': function() { | ||
202 | return 10; | ||
203 | }, | ||
204 | |||
205 | //------------------------------------------------------------------------- | ||
206 | __syntaxFix__: "syntax fix" | 200 | __syntaxFix__: "syntax fix" |
207 | }); | 201 | }); |
208 | 202 | ||
209 | //***************************************************************************** | 203 | //***************************************************************************** |
210 | 204 | ||
211 | Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { | 205 | Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { |
212 | args = args || {}; | 206 | args = args || {}; |
213 | 207 | ||
214 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); | 208 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); |
215 | 209 | ||
216 | this._numberOfBitsToCollectAtEachEvent = 4; | 210 | this._numberOfBitsToCollectAtEachEvent = 4; |
217 | this._randomBitsCollector = 0; | 211 | this._randomBitsCollector = 0; |
218 | this._numberOfRandomBitsCollected = 0; | 212 | this._numberOfRandomBitsCollected = 0; |
219 | 213 | ||
220 | MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); | 214 | MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); |
221 | 215 | ||
222 | return this; | 216 | return this; |
223 | } | 217 | } |
224 | 218 | ||
225 | Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { | 219 | Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { |
226 | 220 | ||
227 | //------------------------------------------------------------------------- | 221 | //------------------------------------------------------------------------- |
228 | 222 | ||
229 | 'numberOfBitsToCollectAtEachEvent': function() { | 223 | 'numberOfBitsToCollectAtEachEvent': function() { |
230 | return this._numberOfBitsToCollectAtEachEvent; | 224 | return this._numberOfBitsToCollectAtEachEvent; |
231 | }, | 225 | }, |
232 | 226 | ||
233 | //------------------------------------------------------------------------- | 227 | //------------------------------------------------------------------------- |
234 | 228 | ||
235 | 'randomBitsCollector': function() { | 229 | 'randomBitsCollector': function() { |
236 | return this._randomBitsCollector; | 230 | return this._randomBitsCollector; |
237 | }, | 231 | }, |
238 | 232 | ||
239 | 'setRandomBitsCollector': function(aValue) { | 233 | 'setRandomBitsCollector': function(aValue) { |
240 | this._randomBitsCollector = aValue; | 234 | this._randomBitsCollector = aValue; |
241 | }, | 235 | }, |
242 | 236 | ||
243 | 'appendRandomBitsToRandomBitsCollector': function(aValue) { | 237 | 'appendRandomBitsToRandomBitsCollector': function(aValue) { |
244 | var collectedBits; | 238 | var collectedBits; |
245 | var numberOfRandomBitsCollected; | 239 | var numberOfRandomBitsCollected; |
246 | 240 | ||
247 | numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); | 241 | numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); |
248 | collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); | 242 | collectedBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); |
249 | this.setRandomBitsCollector(collectetBits); | 243 | this.setRandomBitsCollector(collectedBits); |
250 | numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); | 244 | numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); |
251 | 245 | ||
252 | if (numberOfRandomBitsCollected == 8) { | 246 | if (numberOfRandomBitsCollected == 8) { |
253 | this.updateGeneratorWithValue(collectetBits); | 247 | this.updateGeneratorWithValue(collectedBits); |
254 | numberOfRandomBitsCollected = 0; | 248 | numberOfRandomBitsCollected = 0; |
255 | this.setRandomBitsCollector(0); | 249 | this.setRandomBitsCollector(0); |
256 | } | 250 | } |
257 | 251 | ||
258 | this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) | 252 | this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) |
259 | }, | 253 | }, |
260 | 254 | ||
261 | //------------------------------------------------------------------------- | 255 | //------------------------------------------------------------------------- |
262 | 256 | ||
263 | 'numberOfRandomBitsCollected': function() { | 257 | 'numberOfRandomBitsCollected': function() { |
264 | return this._numberOfRandomBitsCollected; | 258 | return this._numberOfRandomBitsCollected; |
265 | }, | 259 | }, |
266 | 260 | ||
267 | 'setNumberOfRandomBitsCollected': function(aValue) { | 261 | 'setNumberOfRandomBitsCollected': function(aValue) { |
268 | this._numberOfRandomBitsCollected = aValue; | 262 | this._numberOfRandomBitsCollected = aValue; |
269 | }, | 263 | }, |
270 | 264 | ||
271 | //------------------------------------------------------------------------- | 265 | //------------------------------------------------------------------------- |
272 | 266 | ||
273 | 'collectEntropy': function(anEvent) { | 267 | 'collectEntropy': function(anEvent) { |
274 | var mouseLocation; | 268 | var mouseLocation; |
275 | var randomBit; | 269 | var randomBit; |
276 | var mask; | 270 | var mask; |
277 | 271 | ||
278 | mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); | 272 | mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); |
279 | 273 | ||
280 | mouseLocation = anEvent.mouse().client; | 274 | mouseLocation = anEvent.mouse().client; |
281 | randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); | 275 | randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); |
282 | this.appendRandomBitsToRandomBitsCollector(randomBit) | 276 | this.appendRandomBitsToRandomBitsCollector(randomBit) |
283 | }, | 277 | }, |
284 | 278 | ||
285 | //------------------------------------------------------------------------- | 279 | //------------------------------------------------------------------------- |
286 | 280 | ||
287 | 'numberOfRandomBits': function() { | 281 | 'numberOfRandomBits': function() { |
288 | return 1; | 282 | return 1; |
289 | }, | 283 | }, |
290 | 284 | ||
291 | //------------------------------------------------------------------------- | 285 | //------------------------------------------------------------------------- |
292 | |||
293 | 'pollingFrequency': function() { | ||
294 | return 10; | ||
295 | }, | ||
296 | |||
297 | //------------------------------------------------------------------------- | ||
298 | __syntaxFix__: "syntax fix" | 286 | __syntaxFix__: "syntax fix" |
299 | }); | 287 | }); |
300 | 288 | ||
301 | //***************************************************************************** | 289 | //***************************************************************************** |
302 | 290 | ||
303 | Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) { | 291 | Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) { |
304 | args = args || {}; | 292 | args = args || {}; |
305 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); | ||
306 | 293 | ||
307 | this._randomBitsCollector = 0; | 294 | this._intervalTime = args.intervalTime || 1000; |
308 | this._numberOfRandomBitsCollected = 0; | 295 | this._browserCrypto = args.browserCrypto; |
309 | 296 | ||
310 | MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy'); | 297 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); |
311 | 298 | ||
299 | this.collectEntropy(); | ||
312 | return this; | 300 | return this; |
313 | } | 301 | } |
314 | 302 | ||
315 | Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { | 303 | Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { |
316 | |||
317 | //------------------------------------------------------------------------- | ||
318 | |||
319 | 'randomBitsCollector': function() { | ||
320 | return this._randomBitsCollector; | ||
321 | }, | ||
322 | 304 | ||
323 | 'setRandomBitsCollector': function(aValue) { | 305 | 'intervalTime': function() { |
324 | this._randomBitsCollector = aValue; | 306 | return this._intervalTime; |
325 | }, | 307 | }, |
326 | 308 | ||
327 | 'appendRandomBitToRandomBitsCollector': function(aValue) { | 309 | 'browserCrypto': function () { |
328 | var collectedBits; | 310 | return this._browserCrypto; |
329 | var numberOfRandomBitsCollected; | ||
330 | |||
331 | numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); | ||
332 | collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); | ||
333 | this.setRandomBitsCollector(collectetBits); | ||
334 | numberOfRandomBitsCollected ++; | ||
335 | |||
336 | if (numberOfRandomBitsCollected == 8) { | ||
337 | this.updateGeneratorWithValue(collectetBits); | ||
338 | numberOfRandomBitsCollected = 0; | ||
339 | this.setRandomBitsCollector(0); | ||
340 | } | ||
341 | |||
342 | this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) | ||
343 | }, | 311 | }, |
344 | 312 | ||
345 | //------------------------------------------------------------------------- | 313 | //------------------------------------------------------------------------- |
346 | 314 | ||
347 | 'numberOfRandomBitsCollected': function() { | 315 | 'collectEntropy': function() { |
348 | return this._numberOfRandomBitsCollected; | 316 | varbytesToCollect; |
349 | }, | ||
350 | |||
351 | 'setNumberOfRandomBitsCollected': function(aValue) { | ||
352 | this._numberOfRandomBitsCollected = aValue; | ||
353 | }, | ||
354 | 317 | ||
355 | //------------------------------------------------------------------------- | 318 | if (this.boostMode() == true) { |
319 | bytesToCollect = 64; | ||
320 | } else { | ||
321 | bytesToCollect = 8; | ||
322 | } | ||
356 | 323 | ||
357 | 'collectEntropy': function(anEvent) { | 324 | var randomValuesArray = new Uint8Array(bytesToCollect); |
358 | /* | 325 | this.browserCrypto().getRandomValues(randomValuesArray); |
359 | var mouseLocation; | 326 | for (var i = 0; i < randomValuesArray.length; i++) { |
360 | var randomBit; | 327 | this.updateGeneratorWithValue(randomValuesArray[i]); |
361 | 328 | } | |
362 | mouseLocation = anEvent.mouse().client; | ||
363 | |||
364 | randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1); | ||
365 | this.appendRandomBitToRandomBitsCollector(randomBit); | ||
366 | */ | ||
367 | }, | ||
368 | |||
369 | //------------------------------------------------------------------------- | ||
370 | 329 | ||
371 | 'numberOfRandomBits': function() { | 330 | setTimeout(this.collectEntropy, this.intervalTime()); |
372 | return 1; | ||
373 | }, | 331 | }, |
374 | 332 | ||
375 | //------------------------------------------------------------------------- | 333 | //------------------------------------------------------------------------- |
376 | |||
377 | 'pollingFrequency': function() { | ||
378 | return 10; | ||
379 | }, | ||
380 | |||
381 | //------------------------------------------------------------------------- | ||
382 | __syntaxFix__: "syntax fix" | 334 | __syntaxFix__: "syntax fix" |
383 | }); | 335 | }); |
384 | 336 | ||
385 | //############################################################################# | 337 | //############################################################################# |
386 | 338 | ||
387 | Clipperz.Crypto.PRNG.Fortuna = function(args) { | 339 | Clipperz.Crypto.PRNG.Fortuna = function(args) { |
388 | vari,c; | 340 | vari,c; |
389 | 341 | ||
390 | args = args || {}; | 342 | args = args || {}; |
391 | 343 | ||
392 | this._key = args.seed || null; | 344 | this._key = args.seed || null; |
393 | if (this._key == null) { | 345 | if (this._key == null) { |
394 | this._counter = 0; | 346 | this._counter = 0; |
395 | this._key = new Clipperz.ByteArray(); | 347 | this._key = new Clipperz.ByteArray(); |
396 | } else { | 348 | } else { |
397 | this._counter = 1; | 349 | this._counter = 1; |
398 | } | 350 | } |
399 | 351 | ||
400 | this._aesKey = null; | 352 | this._aesKey = null; |
401 | 353 | ||
402 | this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; | 354 | this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; |
403 | this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; | 355 | this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; |
404 | 356 | ||
405 | this._accumulators = []; | 357 | this._accumulators = []; |
406 | c = this.numberOfEntropyAccumulators(); | 358 | c = this.numberOfEntropyAccumulators(); |
407 | for (i=0; i<c; i++) { | 359 | for (i=0; i<c; i++) { |
408 | this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); | 360 | this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); |
409 | } | 361 | } |
410 | 362 | ||
411 | this._randomnessSources = []; | 363 | this._randomnessSources = []; |
412 | this._reseedCounter = 0; | 364 | this._reseedCounter = 0; |
413 | 365 | ||
414 | return this; | 366 | return this; |
415 | } | 367 | } |
416 | 368 | ||
417 | Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { | 369 | Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { |
418 | 370 | ||
419 | 'toString': function() { | 371 | 'toString': function() { |
420 | return "Clipperz.Crypto.PRNG.Fortuna"; | 372 | return "Clipperz.Crypto.PRNG.Fortuna"; |
421 | }, | 373 | }, |
422 | 374 | ||
423 | //------------------------------------------------------------------------- | 375 | //------------------------------------------------------------------------- |
424 | 376 | ||
425 | 'key': function() { | 377 | 'key': function() { |
426 | return this._key; | 378 | return this._key; |
427 | }, | 379 | }, |
428 | 380 | ||
429 | 'setKey': function(aValue) { | 381 | 'setKey': function(aValue) { |
430 | this._key = aValue; | 382 | this._key = aValue; |
431 | this._aesKey = null; | 383 | this._aesKey = null; |
432 | }, | 384 | }, |
433 | 385 | ||
434 | 'aesKey': function() { | 386 | 'aesKey': function() { |
435 | if (this._aesKey == null) { | 387 | if (this._aesKey == null) { |
436 | this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()}); | 388 | this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()}); |
437 | } | 389 | } |
438 | 390 | ||
439 | return this._aesKey; | 391 | return this._aesKey; |
440 | }, | 392 | }, |
441 | 393 | ||
442 | 'accumulators': function() { | 394 | 'accumulators': function() { |
443 | return this._accumulators; | 395 | return this._accumulators; |
444 | }, | 396 | }, |
445 | 397 | ||
446 | 'firstPoolReseedLevel': function() { | 398 | 'firstPoolReseedLevel': function() { |
447 | return this._firstPoolReseedLevel; | 399 | return this._firstPoolReseedLevel; |
448 | }, | 400 | }, |
449 | 401 | ||
450 | //------------------------------------------------------------------------- | 402 | //------------------------------------------------------------------------- |
451 | 403 | ||
452 | 'reseedCounter': function() { | 404 | 'reseedCounter': function() { |
453 | return this._reseedCounter; | 405 | return this._reseedCounter; |
454 | }, | 406 | }, |
455 | 407 | ||
456 | 'incrementReseedCounter': function() { | 408 | 'incrementReseedCounter': function() { |
457 | this._reseedCounter = this._reseedCounter +1; | 409 | this._reseedCounter = this._reseedCounter +1; |
458 | }, | 410 | }, |
459 | 411 | ||
460 | //------------------------------------------------------------------------- | 412 | //------------------------------------------------------------------------- |
461 | 413 | ||
462 | 'reseed': function() { | 414 | 'reseed': function() { |
463 | varnewKeySeed; | 415 | varnewKeySeed; |
464 | var reseedCounter; | 416 | var reseedCounter; |
465 | varreseedCounterMask; | 417 | varreseedCounterMask; |
466 | var i, c; | 418 | var i, c; |
467 | 419 | ||
468 | newKeySeed = this.key(); | 420 | newKeySeed = this.key(); |
469 | this.incrementReseedCounter(); | 421 | this.incrementReseedCounter(); |
470 | reseedCounter = this.reseedCounter(); | 422 | reseedCounter = this.reseedCounter(); |
471 | 423 | ||
472 | c = this.numberOfEntropyAccumulators(); | 424 | c = this.numberOfEntropyAccumulators(); |
473 | reseedCounterMask = 0xffffffff >>> (32 - c); | 425 | reseedCounterMask = 0xffffffff >>> (32 - c); |
474 | for (i=0; i<c; i++) { | 426 | for (i=0; i<c; i++) { |
475 | if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) { | 427 | if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) { |
476 | newKeySeed.appendBlock(this.accumulators()[i].stack()); | 428 | newKeySeed.appendBlock(this.accumulators()[i].stack()); |
477 | this.accumulators()[i].resetStack(); | 429 | this.accumulators()[i].resetStack(); |
478 | } | 430 | } |
479 | } | 431 | } |
480 | 432 | ||
481 | if (reseedCounter == 1) { | 433 | if (reseedCounter == 1) { |
482 | c = this.randomnessSources().length; | 434 | c = this.randomnessSources().length; |
483 | for (i=0; i<c; i++) { | 435 | for (i=0; i<c; i++) { |
484 | this.randomnessSources()[i].setBoostMode(false); | 436 | this.randomnessSources()[i].setBoostMode(false); |
485 | } | 437 | } |
486 | } | 438 | } |
487 | 439 | ||
488 | this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed)); | 440 | this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed)); |
489 | if (reseedCounter == 1) { | 441 | if (reseedCounter == 1) { |
490 | MochiKit.Logging.logDebug("### PRNG.readyToGenerateRandomBytes"); | 442 | MochiKit.Logging.logDebug("### PRNG.readyToGenerateRandomBytes"); |
491 | MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes'); | 443 | MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes'); |
492 | } | 444 | } |
493 | MochiKit.Signal.signal(this, 'reseeded'); | 445 | MochiKit.Signal.signal(this, 'reseeded'); |
494 | }, | 446 | }, |
495 | 447 | ||
496 | //------------------------------------------------------------------------- | 448 | //------------------------------------------------------------------------- |
497 | 449 | ||
498 | 'isReadyToGenerateRandomValues': function() { | 450 | 'isReadyToGenerateRandomValues': function() { |
499 | return this.reseedCounter() != 0; | 451 | return this.reseedCounter() != 0; |
500 | }, | 452 | }, |
501 | 453 | ||
502 | //------------------------------------------------------------------------- | 454 | //------------------------------------------------------------------------- |
503 | 455 | ||
504 | 'entropyLevel': function() { | 456 | 'entropyLevel': function() { |
505 | return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel()); | 457 | return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel()); |
506 | }, | 458 | }, |
507 | 459 | ||
508 | //------------------------------------------------------------------------- | 460 | //------------------------------------------------------------------------- |
509 | 461 | ||
510 | 'counter': function() { | 462 | 'counter': function() { |
511 | return this._counter; | 463 | return this._counter; |
512 | }, | 464 | }, |
513 | 465 | ||
514 | 'incrementCounter': function() { | 466 | 'incrementCounter': function() { |
515 | this._counter += 1; | 467 | this._counter += 1; |
516 | }, | 468 | }, |
517 | 469 | ||
518 | 'counterBlock': function() { | 470 | 'counterBlock': function() { |
519 | var result; | 471 | var result; |
520 | 472 | ||
521 | result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0); | 473 | result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0); |
522 | 474 | ||
523 | return result; | 475 | return result; |
524 | }, | 476 | }, |
525 | 477 | ||
526 | //------------------------------------------------------------------------- | 478 | //------------------------------------------------------------------------- |
527 | 479 | ||
528 | 'getRandomBlock': function() { | 480 | 'getRandomBlock': function() { |
529 | var result; | 481 | var result; |
530 | 482 | ||
531 | result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues())); | 483 | result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues())); |
532 | this.incrementCounter(); | 484 | this.incrementCounter(); |
533 | 485 | ||
534 | return result; | 486 | return result; |
535 | }, | 487 | }, |
536 | 488 | ||
537 | //------------------------------------------------------------------------- | 489 | //------------------------------------------------------------------------- |
538 | 490 | ||
539 | 'getRandomBytes': function(aSize) { | 491 | 'getRandomBytes': function(aSize) { |
540 | var result; | 492 | var result; |
541 | 493 | ||
542 | if (this.isReadyToGenerateRandomValues()) { | 494 | if (this.isReadyToGenerateRandomValues()) { |
543 | var i,c; | 495 | var i,c; |
544 | var newKey; | 496 | var newKey; |
545 | 497 | ||
546 | result = new Clipperz.ByteArray(); | 498 | result = new Clipperz.ByteArray(); |
547 | 499 | ||
548 | c = Math.ceil(aSize / (128 / 8)); | 500 | c = Math.ceil(aSize / (128 / 8)); |
549 | for (i=0; i<c; i++) { | 501 | for (i=0; i<c; i++) { |
550 | result.appendBlock(this.getRandomBlock()); | 502 | result.appendBlock(this.getRandomBlock()); |
551 | } | 503 | } |
552 | 504 | ||
553 | if (result.length() != aSize) { | 505 | if (result.length() != aSize) { |
554 | result = result.split(0, aSize); | 506 | result = result.split(0, aSize); |
555 | } | 507 | } |
556 | 508 | ||
557 | newKey = this.getRandomBlock().appendBlock(this.getRandomBlock()); | 509 | newKey = this.getRandomBlock().appendBlock(this.getRandomBlock()); |
558 | this.setKey(newKey); | 510 | this.setKey(newKey); |
559 | } else { | 511 | } else { |
560 | MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!"); | 512 | MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!"); |
561 | throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy; | 513 | throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy; |
562 | } | 514 | } |
563 | 515 | ||
564 | return result; | 516 | return result; |
565 | }, | 517 | }, |
566 | 518 | ||
567 | //------------------------------------------------------------------------- | 519 | //------------------------------------------------------------------------- |
568 | 520 | ||
569 | 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) { | 521 | 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) { |
570 | varselectedAccumulator; | 522 | varselectedAccumulator; |
571 | 523 | ||
572 | selectedAccumulator = this.accumulators()[aPoolId]; | 524 | selectedAccumulator = this.accumulators()[aPoolId]; |
573 | selectedAccumulator.addRandomByte(aRandomValue); | 525 | selectedAccumulator.addRandomByte(aRandomValue); |
574 | 526 | ||
575 | if (aPoolId == 0) { | 527 | if (aPoolId == 0) { |
576 | MochiKit.Signal.signal(this, 'addedRandomByte') | 528 | MochiKit.Signal.signal(this, 'addedRandomByte') |
577 | if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) { | 529 | if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) { |
578 | this.reseed(); | 530 | this.reseed(); |
579 | } | 531 | } |
580 | } | 532 | } |
581 | }, | 533 | }, |
582 | 534 | ||
583 | //------------------------------------------------------------------------- | 535 | //------------------------------------------------------------------------- |
584 | 536 | ||
585 | 'numberOfEntropyAccumulators': function() { | 537 | 'numberOfEntropyAccumulators': function() { |
586 | return this._numberOfEntropyAccumulators; | 538 | return this._numberOfEntropyAccumulators; |
587 | }, | 539 | }, |
588 | 540 | ||
589 | //------------------------------------------------------------------------- | 541 | //------------------------------------------------------------------------- |
590 | 542 | ||
591 | 'randomnessSources': function() { | 543 | 'randomnessSources': function() { |
592 | return this._randomnessSources; | 544 | return this._randomnessSources; |
593 | }, | 545 | }, |
594 | 546 | ||
595 | 'addRandomnessSource': function(aRandomnessSource) { | 547 | 'addRandomnessSource': function(aRandomnessSource) { |
596 | aRandomnessSource.setGenerator(this); | 548 | aRandomnessSource.setGenerator(this); |
597 | aRandomnessSource.setSourceId(this.randomnessSources().length); | 549 | aRandomnessSource.setSourceId(this.randomnessSources().length); |
598 | this.randomnessSources().push(aRandomnessSource); | 550 | this.randomnessSources().push(aRandomnessSource); |
599 | 551 | ||
600 | if (this.isReadyToGenerateRandomValues() == false) { | 552 | if (this.isReadyToGenerateRandomValues() == false) { |
601 | aRandomnessSource.setBoostMode(true); | 553 | aRandomnessSource.setBoostMode(true); |
602 | } | 554 | } |
603 | }, | 555 | }, |
604 | 556 | ||
605 | //------------------------------------------------------------------------- | 557 | //------------------------------------------------------------------------- |
606 | 558 | ||
607 | 'deferredEntropyCollection': function(aValue) { | 559 | 'deferredEntropyCollection': function(aValue) { |
608 | var result; | 560 | var result; |
609 | 561 | ||
610 | //MochiKit.Logging.logDebug(">>> PRNG.deferredEntropyCollection"); | ||
611 | 562 | ||
612 | if (this.isReadyToGenerateRandomValues()) { | 563 | if (this.isReadyToGenerateRandomValues()) { |
613 | //MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 1"); | ||
614 | result = aValue; | 564 | result = aValue; |
615 | } else { | 565 | } else { |
616 | //MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 2"); | ||
617 | var deferredResult; | 566 | var deferredResult; |
618 | 567 | ||
619 | Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true); | 568 | Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true); |
620 | 569 | ||
621 | deferredResult = new MochiKit.Async.Deferred(); | 570 | deferredResult = new MochiKit.Async.Deferred(); |
622 | // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - PRNG.deferredEntropyCollection - 1: " + res); return res;}); | ||
623 | deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); | 571 | deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); |
624 | // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - PRNG.deferredEntropyCollection - 2: " + res); return res;}); | ||
625 | MochiKit.Signal.connect(this, | 572 | MochiKit.Signal.connect(this, |
626 | 'readyToGenerateRandomBytes', | 573 | 'readyToGenerateRandomBytes', |
627 | deferredResult, | 574 | deferredResult, |
628 | 'callback'); | 575 | 'callback'); |
629 | 576 | ||
630 | result = deferredResult; | 577 | result = deferredResult; |
631 | } | 578 | } |
632 | //MochiKit.Logging.logDebug("<<< PRNG.deferredEntropyCollection - result: " + result); | ||
633 | 579 | ||
634 | return result; | 580 | return result; |
635 | }, | 581 | }, |
636 | 582 | ||
637 | //------------------------------------------------------------------------- | 583 | //------------------------------------------------------------------------- |
638 | 584 | ||
639 | 'fastEntropyAccumulationForTestingPurpose': function() { | 585 | 'fastEntropyAccumulationForTestingPurpose': function() { |
640 | while (! this.isReadyToGenerateRandomValues()) { | 586 | while (! this.isReadyToGenerateRandomValues()) { |
641 | this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); | 587 | this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); |
642 | } | 588 | } |
643 | }, | 589 | }, |
644 | 590 | ||
645 | //------------------------------------------------------------------------- | 591 | //------------------------------------------------------------------------- |
646 | 592 | /* | |
647 | 'dump': function(appendToDoc) { | 593 | 'dump': function(appendToDoc) { |
648 | var tbl; | 594 | var tbl; |
649 | var i,c; | 595 | var i,c; |
650 | 596 | ||
651 | tbl = document.createElement("table"); | 597 | tbl = document.createElement("table"); |
652 | tbl.border = 0; | 598 | tbl.border = 0; |
653 | with (tbl.style) { | 599 | with (tbl.style) { |
654 | border = "1px solid lightgrey"; | 600 | border = "1px solid lightgrey"; |
655 | fontFamily = 'Helvetica, Arial, sans-serif'; | 601 | fontFamily = 'Helvetica, Arial, sans-serif'; |
656 | fontSize = '8pt'; | 602 | fontSize = '8pt'; |
657 | //borderCollapse = "collapse"; | 603 | //borderCollapse = "collapse"; |
658 | } | 604 | } |
659 | var hdr = tbl.createTHead(); | 605 | var hdr = tbl.createTHead(); |
660 | var hdrtr = hdr.insertRow(0); | 606 | var hdrtr = hdr.insertRow(0); |
661 | // document.createElement("tr"); | 607 | // document.createElement("tr"); |
662 | { | 608 | { |
663 | var ntd; | 609 | var ntd; |
664 | 610 | ||
665 | ntd = hdrtr.insertCell(0); | 611 | ntd = hdrtr.insertCell(0); |
666 | ntd.style.borderBottom = "1px solid lightgrey"; | 612 | ntd.style.borderBottom = "1px solid lightgrey"; |
667 | ntd.style.borderRight = "1px solid lightgrey"; | 613 | ntd.style.borderRight = "1px solid lightgrey"; |
668 | ntd.appendChild(document.createTextNode("#")); | 614 | ntd.appendChild(document.createTextNode("#")); |
669 | 615 | ||
670 | ntd = hdrtr.insertCell(1); | 616 | ntd = hdrtr.insertCell(1); |
671 | ntd.style.borderBottom = "1px solid lightgrey"; | 617 | ntd.style.borderBottom = "1px solid lightgrey"; |
672 | ntd.style.borderRight = "1px solid lightgrey"; | 618 | ntd.style.borderRight = "1px solid lightgrey"; |
673 | ntd.appendChild(document.createTextNode("s")); | 619 | ntd.appendChild(document.createTextNode("s")); |
674 | 620 | ||
675 | ntd = hdrtr.insertCell(2); | 621 | ntd = hdrtr.insertCell(2); |
676 | ntd.colSpan = this.firstPoolReseedLevel(); | 622 | ntd.colSpan = this.firstPoolReseedLevel(); |
677 | ntd.style.borderBottom = "1px solid lightgrey"; | 623 | ntd.style.borderBottom = "1px solid lightgrey"; |
678 | ntd.style.borderRight = "1px solid lightgrey"; | 624 | ntd.style.borderRight = "1px solid lightgrey"; |
679 | ntd.appendChild(document.createTextNode("base values")); | 625 | ntd.appendChild(document.createTextNode("base values")); |
680 | 626 | ||
681 | ntd = hdrtr.insertCell(3); | 627 | ntd = hdrtr.insertCell(3); |
682 | ntd.colSpan = 20; | 628 | ntd.colSpan = 20; |
683 | ntd.style.borderBottom = "1px solid lightgrey"; | 629 | ntd.style.borderBottom = "1px solid lightgrey"; |
684 | ntd.appendChild(document.createTextNode("extra values")); | 630 | ntd.appendChild(document.createTextNode("extra values")); |
685 | 631 | ||
686 | } | 632 | } |
687 | 633 | ||
688 | c = this.accumulators().length; | 634 | c = this.accumulators().length; |
689 | for (i=0; i<c ; i++) { | 635 | for (i=0; i<c ; i++) { |
690 | varcurrentAccumulator; | 636 | varcurrentAccumulator; |
691 | var bdytr; | 637 | var bdytr; |
692 | var bdytd; | 638 | var bdytd; |
693 | var ii, cc; | 639 | var ii, cc; |
694 | 640 | ||
695 | currentAccumulator = this.accumulators()[i] | 641 | currentAccumulator = this.accumulators()[i] |
696 | 642 | ||
697 | bdytr = tbl.insertRow(true); | 643 | bdytr = tbl.insertRow(true); |
698 | 644 | ||
699 | bdytd = bdytr.insertCell(0); | 645 | bdytd = bdytr.insertCell(0); |
700 | bdytd.style.borderRight = "1px solid lightgrey"; | 646 | bdytd.style.borderRight = "1px solid lightgrey"; |
701 | bdytd.style.color = "lightgrey"; | 647 | bdytd.style.color = "lightgrey"; |
702 | bdytd.appendChild(document.createTextNode("" + i)); | 648 | bdytd.appendChild(document.createTextNode("" + i)); |
703 | 649 | ||
704 | bdytd = bdytr.insertCell(1); | 650 | bdytd = bdytr.insertCell(1); |
705 | bdytd.style.borderRight = "1px solid lightgrey"; | 651 | bdytd.style.borderRight = "1px solid lightgrey"; |
706 | bdytd.style.color = "gray"; | 652 | bdytd.style.color = "gray"; |
707 | bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); | 653 | bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); |
708 | 654 | ||
709 | 655 | ||
710 | cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); | 656 | cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); |
711 | for (ii=0; ii<cc; ii++) { | 657 | for (ii=0; ii<cc; ii++) { |
712 | var cellText; | 658 | var cellText; |
713 | 659 | ||
714 | bdytd = bdytr.insertCell(ii + 2); | 660 | bdytd = bdytr.insertCell(ii + 2); |
715 | 661 | ||
716 | if (ii < currentAccumulator.stack().length()) { | 662 | if (ii < currentAccumulator.stack().length()) { |
717 | cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); | 663 | cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); |
718 | } else { | 664 | } else { |
719 | cellText = "_"; | 665 | cellText = "_"; |
720 | } | 666 | } |
721 | 667 | ||
722 | if (ii == (this.firstPoolReseedLevel() - 1)) { | 668 | if (ii == (this.firstPoolReseedLevel() - 1)) { |
723 | bdytd.style.borderRight = "1px solid lightgrey"; | 669 | bdytd.style.borderRight = "1px solid lightgrey"; |
724 | } | 670 | } |
725 | 671 | ||
726 | bdytd.appendChild(document.createTextNode(cellText)); | 672 | bdytd.appendChild(document.createTextNode(cellText)); |
727 | } | 673 | } |
728 | 674 | ||
729 | } | 675 | } |
730 | 676 | ||
731 | 677 | ||
732 | if (appendToDoc) { | 678 | if (appendToDoc) { |
733 | var ne = document.createElement("div"); | 679 | var ne = document.createElement("div"); |
734 | ne.id = "entropyGeneratorStatus"; | 680 | ne.id = "entropyGeneratorStatus"; |
735 | with (ne.style) { | 681 | with (ne.style) { |
736 | fontFamily = "Courier New, monospace"; | 682 | fontFamily = "Courier New, monospace"; |
737 | fontSize = "12px"; | 683 | fontSize = "12px"; |
738 | lineHeight = "16px"; | 684 | lineHeight = "16px"; |
739 | borderTop = "1px solid black"; | 685 | borderTop = "1px solid black"; |
740 | padding = "10px"; | 686 | padding = "10px"; |
741 | } | 687 | } |
742 | if (document.getElementById(ne.id)) { | 688 | if (document.getElementById(ne.id)) { |
743 | MochiKit.DOM.swapDOM(ne.id, ne); | 689 | MochiKit.DOM.swapDOM(ne.id, ne); |
744 | } else { | 690 | } else { |
745 | document.body.appendChild(ne); | 691 | document.body.appendChild(ne); |
746 | } | 692 | } |
747 | ne.appendChild(tbl); | 693 | ne.appendChild(tbl); |
748 | } | 694 | } |
749 | 695 | ||
750 | return tbl; | 696 | return tbl; |
751 | }, | 697 | }, |
752 | 698 | */ | |
753 | //----------------------------------------------------------------------------- | 699 | //----------------------------------------------------------------------------- |
754 | __syntaxFix__: "syntax fix" | 700 | __syntaxFix__: "syntax fix" |
755 | }); | 701 | }); |
756 | 702 | ||
757 | //############################################################################# | 703 | //############################################################################# |
758 | 704 | ||
759 | Clipperz.Crypto.PRNG.Random = function(args) { | 705 | Clipperz.Crypto.PRNG.Random = function(args) { |
760 | args = args || {}; | 706 | args = args || {}; |
761 | //MochiKit.Base.bindMethods(this); | 707 | //MochiKit.Base.bindMethods(this); |
762 | 708 | ||
763 | return this; | 709 | return this; |
764 | } | 710 | } |
765 | 711 | ||
766 | Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { | 712 | Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { |
767 | 713 | ||
768 | 'toString': function() { | 714 | 'toString': function() { |
769 | return "Clipperz.Crypto.PRNG.Random"; | 715 | return "Clipperz.Crypto.PRNG.Random"; |
770 | }, | 716 | }, |
771 | 717 | ||
772 | //------------------------------------------------------------------------- | 718 | //------------------------------------------------------------------------- |
773 | 719 | ||
774 | 'getRandomBytes': function(aSize) { | 720 | 'getRandomBytes': function(aSize) { |
775 | //Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); | 721 | //Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); |
776 | varresult; | 722 | varresult; |
777 | var i,c; | 723 | var i,c; |
778 | 724 | ||
779 | result = new Clipperz.ByteArray() | 725 | result = new Clipperz.ByteArray() |
780 | c = aSize || 1; | 726 | c = aSize || 1; |
781 | for (i=0; i<c; i++) { | 727 | for (i=0; i<c; i++) { |
782 | result.appendByte((Math.random()*255) & 0xff); | 728 | result.appendByte((Math.random()*255) & 0xff); |
783 | } | 729 | } |
784 | 730 | ||
785 | //Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); | 731 | //Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); |
786 | return result; | 732 | return result; |
787 | }, | 733 | }, |
788 | 734 | ||
789 | //------------------------------------------------------------------------- | 735 | //------------------------------------------------------------------------- |
790 | __syntaxFix__: "syntax fix" | 736 | __syntaxFix__: "syntax fix" |
791 | }); | 737 | }); |
792 | 738 | ||
793 | //############################################################################# | 739 | //############################################################################# |
794 | 740 | ||
795 | _clipperz_crypt_prng_defaultPRNG = null; | 741 | _clipperz_crypt_prng_defaultPRNG = null; |
796 | 742 | ||
797 | Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { | 743 | Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { |
798 | if (_clipperz_crypt_prng_defaultPRNG == null) { | 744 | if (_clipperz_crypt_prng_defaultPRNG == null) { |
799 | _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); | 745 | _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); |
800 | 746 | ||
801 | //............................................................. | 747 | //............................................................. |
802 | // | 748 | // |
803 | // TimeRandomnessSource | 749 | // TimeRandomnessSource |
804 | // | 750 | // |
805 | //............................................................. | 751 | //............................................................. |
806 | { | 752 | { |
807 | var newRandomnessSource; | 753 | var newRandomnessSource; |
808 | 754 | ||
809 | newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); | 755 | newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); |
810 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | 756 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); |
811 | } | 757 | } |
812 | 758 | ||
813 | //............................................................. | 759 | //............................................................. |
814 | // | 760 | // |
815 | // MouseRandomnessSource | 761 | // MouseRandomnessSource |
816 | // | 762 | // |
817 | //............................................................. | 763 | //............................................................. |
818 | { | 764 | { |
819 | varnewRandomnessSource; | 765 | varnewRandomnessSource; |
820 | 766 | ||
821 | newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); | 767 | newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); |
822 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | 768 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); |
823 | } | 769 | } |
824 | 770 | ||
825 | //............................................................. | 771 | //............................................................. |
826 | // | 772 | // |
827 | // KeyboardRandomnessSource | 773 | // CryptoRandomRandomnessSource |
828 | // | 774 | // |
829 | //............................................................. | 775 | //............................................................. |
830 | { | 776 | { |
831 | varnewRandomnessSource; | 777 | varnewRandomnessSource; |
778 | varbrowserCrypto; | ||
832 | 779 | ||
833 | newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource(); | 780 | if (window.crypto && window.crypto.getRandomValues) { |
834 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | 781 | browserCrypto = window.crypto; |
782 | } else if (window.msCrypto && window.msCrypto.getRandomValues) { | ||
783 | browserCrypto = window.msCrypto; | ||
784 | } else { | ||
785 | browserCrypto = null; | ||
786 | } | ||
787 | |||
788 | if (browserCrypto != null) { | ||
789 | newRandomnessSource = new Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource({'browserCrypto':browserCrypto}); | ||
790 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | ||
791 | } | ||
835 | } | 792 | } |
836 | |||
837 | } | 793 | } |
838 | 794 | ||
839 | return _clipperz_crypt_prng_defaultPRNG; | 795 | return _clipperz_crypt_prng_defaultPRNG; |
840 | }; | 796 | }; |
841 | 797 | ||
842 | //############################################################################# | 798 | //############################################################################# |
843 | 799 | ||
844 | Clipperz.Crypto.PRNG.exception = { | 800 | Clipperz.Crypto.PRNG.exception = { |
845 | NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") | 801 | NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") |
846 | }; | 802 | }; |
847 | 803 | ||
848 | 804 | ||
849 | MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); | 805 | MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); |
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 | |||
@@ -1,326 +1,345 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { | 24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { |
25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; | 25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; |
26 | } | 26 | } |
27 | 27 | ||
28 | try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { | 28 | try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { |
29 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; | 29 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; |
30 | } | 30 | } |
31 | 31 | ||
32 | try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { | 32 | try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { |
33 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; | 33 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; |
34 | } | 34 | } |
35 | 35 | ||
36 | if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } | 36 | if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } |
37 | 37 | ||
38 | Clipperz.Crypto.SRP.VERSION = "0.1"; | 38 | Clipperz.Crypto.SRP.VERSION = "0.1"; |
39 | Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; | 39 | Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; |
40 | 40 | ||
41 | //############################################################################# | 41 | //############################################################################# |
42 | 42 | ||
43 | MochiKit.Base.update(Clipperz.Crypto.SRP, { | 43 | MochiKit.Base.update(Clipperz.Crypto.SRP, { |
44 | 44 | ||
45 | '_n': null, | 45 | '_n': null, |
46 | '_g': null, | 46 | '_g': null, |
47 | '_k': null, | ||
48 | |||
47 | //------------------------------------------------------------------------- | 49 | //------------------------------------------------------------------------- |
48 | 50 | ||
49 | 'n': function() { | 51 | 'n': function() { |
50 | if (Clipperz.Crypto.SRP._n == null) { | 52 | if (Clipperz.Crypto.SRP._n == null) { |
51 | Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); | 53 | Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); |
52 | } | 54 | } |
53 | 55 | ||
54 | return Clipperz.Crypto.SRP._n; | 56 | return Clipperz.Crypto.SRP._n; |
55 | }, | 57 | }, |
56 | 58 | ||
57 | //------------------------------------------------------------------------- | 59 | //------------------------------------------------------------------------- |
58 | 60 | ||
59 | 'g': function() { | 61 | 'g': function() { |
60 | if (Clipperz.Crypto.SRP._g == null) { | 62 | if (Clipperz.Crypto.SRP._g == null) { |
61 | Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation) | 63 | Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation) |
62 | } | 64 | } |
63 | 65 | ||
64 | return Clipperz.Crypto.SRP._g; | 66 | return Clipperz.Crypto.SRP._g; |
65 | }, | 67 | }, |
66 | 68 | ||
69 | 'k': function() { | ||
70 | if (Clipperz.Crypto.SRP._k == null) { | ||
71 | // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16); | ||
72 | Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16); | ||
73 | } | ||
74 | |||
75 | return Clipperz.Crypto.SRP._k; | ||
76 | }, | ||
77 | |||
67 | //----------------------------------------------------------------------------- | 78 | //----------------------------------------------------------------------------- |
68 | 79 | ||
69 | 'exception': { | 80 | 'exception': { |
70 | 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") | 81 | 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") |
71 | }, | 82 | }, |
72 | 83 | ||
73 | //------------------------------------------------------------------------- | 84 | //------------------------------------------------------------------------- |
74 | __syntaxFix__: "syntax fix" | 85 | __syntaxFix__: "syntax fix" |
75 | 86 | ||
76 | }); | 87 | }); |
77 | 88 | ||
78 | //############################################################################# | 89 | //############################################################################# |
79 | // | 90 | // |
80 | // S R P C o n n e c t i o n version 1.0 | 91 | // S R P C o n n e c t i o n version 1.0 |
81 | // | 92 | // |
82 | //============================================================================= | 93 | //============================================================================= |
83 | Clipperz.Crypto.SRP.Connection = function (args) { | 94 | Clipperz.Crypto.SRP.Connection = function (args) { |
84 | args = args || {}; | 95 | args = args || {}; |
85 | 96 | ||
86 | this._C = args.C; | 97 | this._C = args.C; |
87 | this._P = args.P; | 98 | this._P = args.P; |
88 | this.hash = args.hash; | 99 | this.hash = args.hash; |
89 | 100 | ||
90 | this._a = null; | 101 | this._a = null; |
91 | this._A = null; | 102 | this._A = null; |
92 | 103 | ||
93 | this._s = null; | 104 | this._s = null; |
94 | this._B = null; | 105 | this._B = null; |
95 | 106 | ||
96 | this._x = null; | 107 | this._x = null; |
97 | 108 | ||
98 | this._u = null; | 109 | this._u = null; |
99 | this._K = null; | 110 | this._K = null; |
100 | this._M1 = null; | 111 | this._M1 = null; |
101 | this._M2 = null; | 112 | this._M2 = null; |
102 | 113 | ||
103 | this._sessionKey = null; | 114 | this._sessionKey = null; |
104 | 115 | ||
105 | return this; | 116 | return this; |
106 | } | 117 | } |
107 | 118 | ||
108 | Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { | 119 | Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { |
109 | 120 | ||
110 | 'toString': function () { | 121 | 'toString': function () { |
111 | return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); | 122 | return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); |
112 | }, | 123 | }, |
113 | 124 | ||
114 | //------------------------------------------------------------------------- | 125 | //------------------------------------------------------------------------- |
115 | 126 | ||
116 | 'C': function () { | 127 | 'C': function () { |
117 | return this._C; | 128 | return this._C; |
118 | }, | 129 | }, |
119 | 130 | ||
120 | //------------------------------------------------------------------------- | 131 | //------------------------------------------------------------------------- |
121 | 132 | ||
122 | 'P': function () { | 133 | 'P': function () { |
123 | return this._P; | 134 | return this._P; |
124 | }, | 135 | }, |
125 | 136 | ||
126 | //------------------------------------------------------------------------- | 137 | //------------------------------------------------------------------------- |
127 | 138 | ||
128 | 'a': function () { | 139 | 'a': function () { |
129 | if (this._a == null) { | 140 | if (this._a == null) { |
130 | this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); | 141 | this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); |
131 | // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); | 142 | // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); |
132 | //MochiKit.Logging.logDebug("SRP a: " + this._a); | ||
133 | } | 143 | } |
134 | 144 | ||
135 | return this._a; | 145 | return this._a; |
136 | }, | 146 | }, |
137 | 147 | ||
138 | //------------------------------------------------------------------------- | 148 | //------------------------------------------------------------------------- |
139 | 149 | ||
140 | 'A': function () { | 150 | 'A': function () { |
141 | if (this._A == null) { | 151 | if (this._A == null) { |
142 | //Warning: this value should be strictly greater than zero: how should we perform this check? | 152 | //Warning: this value should be strictly greater than zero |
143 | this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); | 153 | this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); |
144 | 154 | if (this._A.equals(0) || negative(this._A)) { | |
145 | if (this._A.equals(0)) { | 155 | MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0."); |
146 | MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0."); | ||
147 | throw Clipperz.Crypto.SRP.exception.InvalidValue; | 156 | throw Clipperz.Crypto.SRP.exception.InvalidValue; |
148 | } | 157 | } |
149 | //MochiKit.Logging.logDebug("SRP A: " + this._A); | ||
150 | } | 158 | } |
151 | 159 | ||
152 | return this._A; | 160 | return this._A; |
153 | }, | 161 | }, |
154 | 162 | ||
155 | //------------------------------------------------------------------------- | 163 | //------------------------------------------------------------------------- |
156 | 164 | ||
157 | 's': function () { | 165 | 's': function () { |
158 | return this._s; | 166 | return this._s; |
159 | //MochiKit.Logging.logDebug("SRP s: " + this._S); | ||
160 | }, | 167 | }, |
161 | 168 | ||
162 | 'set_s': function(aValue) { | 169 | 'set_s': function(aValue) { |
163 | this._s = aValue; | 170 | this._s = aValue; |
164 | }, | 171 | }, |
165 | 172 | ||
166 | //------------------------------------------------------------------------- | 173 | //------------------------------------------------------------------------- |
167 | 174 | ||
168 | 'B': function () { | 175 | 'B': function () { |
169 | return this._B; | 176 | return this._B; |
170 | }, | 177 | }, |
171 | 178 | ||
172 | 'set_B': function(aValue) { | 179 | 'set_B': function(aValue) { |
173 | //Warning: this value should be strictly greater than zero: how should we perform this check? | 180 | //Warning: this value should be strictly greater than zero |
174 | if (! aValue.equals(0)) { | 181 | this._B = aValue; |
175 | this._B = aValue; | 182 | if (this._B.equals(0) || negative(this._B)) { |
176 | //MochiKit.Logging.logDebug("SRP B: " + this._B); | 183 | MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0."); |
177 | } else { | ||
178 | MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0."); | ||
179 | throw Clipperz.Crypto.SRP.exception.InvalidValue; | 184 | throw Clipperz.Crypto.SRP.exception.InvalidValue; |
180 | } | 185 | } |
181 | }, | 186 | }, |
182 | 187 | ||
183 | //------------------------------------------------------------------------- | 188 | //------------------------------------------------------------------------- |
184 | 189 | ||
185 | 'x': function () { | 190 | 'x': function () { |
186 | if (this._x == null) { | 191 | if (this._x == null) { |
187 | this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); | 192 | this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); |
188 | //MochiKit.Logging.logDebug("SRP x: " + this._x); | ||
189 | } | 193 | } |
190 | 194 | ||
191 | return this._x; | 195 | return this._x; |
192 | }, | 196 | }, |
193 | 197 | ||
194 | //------------------------------------------------------------------------- | 198 | //------------------------------------------------------------------------- |
195 | 199 | ||
196 | 'u': function () { | 200 | 'u': function () { |
197 | if (this._u == null) { | 201 | if (this._u == null) { |
198 | this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16); | 202 | this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.A().asString() + this.B().asString()), 16); |
199 | //MochiKit.Logging.logDebug("SRP u: " + this._u); | ||
200 | } | 203 | } |
201 | 204 | ||
202 | return this._u; | 205 | return this._u; |
203 | }, | 206 | }, |
204 | 207 | ||
205 | //------------------------------------------------------------------------- | 208 | //------------------------------------------------------------------------- |
206 | 209 | ||
207 | 'S': function () { | 210 | 'S': function () { |
208 | if (this._S == null) { | 211 | if (this._S == null) { |
209 | var bigint; | 212 | var bigint; |
210 | varsrp; | 213 | varsrp; |
211 | 214 | ||
212 | bigint = Clipperz.Crypto.BigInt; | 215 | bigint = Clipperz.Crypto.BigInt; |
213 | srp = Clipperz.Crypto.SRP; | 216 | srp = Clipperz.Crypto.SRP; |
214 | 217 | ||
215 | this._S =bigint.powerModule( | 218 | this._S =bigint.powerModule( |
216 | bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())), | 219 | bigint.subtract( |
217 | bigint.add(this.a(), bigint.multiply(this.u(), this.x())), | 220 | this.B(), |
218 | srp.n() | 221 | bigint.multiply( |
222 | Clipperz.Crypto.SRP.k(), | ||
223 | bigint.powerModule(srp.g(), this.x(), srp.n()) | ||
224 | ) | ||
225 | ), | ||
226 | bigint.add(this.a(), bigint.multiply(this.u(), this.x())), | ||
227 | srp.n() | ||
219 | ) | 228 | ) |
220 | //MochiKit.Logging.logDebug("SRP S: " + this._S); | ||
221 | } | 229 | } |
222 | 230 | ||
223 | return this._S; | 231 | return this._S; |
224 | }, | 232 | }, |
225 | 233 | ||
226 | //------------------------------------------------------------------------- | 234 | //------------------------------------------------------------------------- |
227 | 235 | ||
228 | 'K': function () { | 236 | 'K': function () { |
229 | if (this._K == null) { | 237 | if (this._K == null) { |
230 | this._K = this.stringHash(this.S().asString()); | 238 | this._K = this.stringHash(this.S().asString()); |
231 | //MochiKit.Logging.logDebug("SRP K: " + this._K); | ||
232 | } | 239 | } |
233 | 240 | ||
234 | return this._K; | 241 | return this._K; |
235 | }, | 242 | }, |
236 | 243 | ||
237 | //------------------------------------------------------------------------- | 244 | //------------------------------------------------------------------------- |
238 | 245 | ||
239 | 'M1': function () { | 246 | 'M1': function () { |
240 | if (this._M1 == null) { | 247 | if (this._M1 == null) { |
241 | this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); | 248 | // this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); |
242 | //MochiKit.Logging.logDebug("SRP M1: " + this._M1); | 249 | |
250 | //http://srp.stanford.edu/design.html | ||
251 | //User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K) | ||
252 | |||
253 | this._M1 = this.stringHash( | ||
254 | "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" + | ||
255 | this.stringHash(this.C()) + | ||
256 | this.s().asString() + | ||
257 | this.A().asString() + | ||
258 | this.B().asString() + | ||
259 | this.K() | ||
260 | ); | ||
261 | //console.log("M1", this._M1); | ||
243 | } | 262 | } |
244 | 263 | ||
245 | return this._M1; | 264 | return this._M1; |
246 | }, | 265 | }, |
247 | 266 | ||
248 | //------------------------------------------------------------------------- | 267 | //------------------------------------------------------------------------- |
249 | 268 | ||
250 | 'M2': function () { | 269 | 'M2': function () { |
251 | if (this._M2 == null) { | 270 | if (this._M2 == null) { |
252 | this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); | 271 | this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); |
253 | //MochiKit.Logging.logDebug("SRP M2: " + this._M2); | 272 | //console.log("M2", this._M2); |
254 | } | 273 | } |
255 | 274 | ||
256 | return this._M2; | 275 | return this._M2; |
257 | }, | 276 | }, |
258 | 277 | ||
259 | //========================================================================= | 278 | //========================================================================= |
260 | 279 | ||
261 | 'serverSideCredentialsWithSalt': function(aSalt) { | 280 | 'serverSideCredentialsWithSalt': function(aSalt) { |
262 | var result; | 281 | var result; |
263 | var s, x, v; | 282 | var s, x, v; |
264 | 283 | ||
265 | s = aSalt; | 284 | s = aSalt; |
266 | x = this.stringHash(s + this.P()); | 285 | x = this.stringHash(s + this.P()); |
267 | v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); | 286 | v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); |
268 | 287 | ||
269 | result = {}; | 288 | result = {}; |
270 | result['C'] = this.C(); | 289 | result['C'] = this.C(); |
271 | result['s'] = s; | 290 | result['s'] = s; |
272 | result['v'] = v.asString(16); | 291 | result['v'] = v.asString(16); |
273 | 292 | ||
274 | return result; | 293 | return result; |
275 | }, | 294 | }, |
276 | 295 | ||
277 | 'serverSideCredentials': function() { | 296 | 'serverSideCredentials': function() { |
278 | var result; | 297 | var result; |
279 | var s; | 298 | var s; |
280 | 299 | ||
281 | s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); | 300 | s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); |
282 | 301 | ||
283 | result = this.serverSideCredentialsWithSalt(s); | 302 | result = this.serverSideCredentialsWithSalt(s); |
284 | 303 | ||
285 | return result; | 304 | return result; |
286 | }, | 305 | }, |
287 | 306 | ||
288 | //========================================================================= | 307 | //========================================================================= |
289 | /* | 308 | /* |
290 | 'computeServerSide_S': function(b) { | 309 | 'computeServerSide_S': function(b) { |
291 | var result; | 310 | var result; |
292 | var v; | 311 | var v; |
293 | var bigint; | 312 | var bigint; |
294 | varsrp; | 313 | varsrp; |
295 | 314 | ||
296 | bigint = Clipperz.Crypto.BigInt; | 315 | bigint = Clipperz.Crypto.BigInt; |
297 | srp = Clipperz.Crypto.SRP; | 316 | srp = Clipperz.Crypto.SRP; |
298 | 317 | ||
299 | v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16); | 318 | v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16); |
300 | // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n()); | 319 | // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n()); |
301 | result = bigint.powerModule( | 320 | result = bigint.powerModule( |
302 | bigint.multiply( | 321 | bigint.multiply( |
303 | this.A(), | 322 | this.A(), |
304 | bigint.powerModule(v, this.u(), srp.n()) | 323 | bigint.powerModule(v, this.u(), srp.n()) |
305 | ), new Clipperz.Crypto.BigInt(b, 10), srp.n() | 324 | ), new Clipperz.Crypto.BigInt(b, 10), srp.n() |
306 | ); | 325 | ); |
307 | 326 | ||
308 | return result; | 327 | return result; |
309 | }, | 328 | }, |
310 | */ | 329 | */ |
311 | //========================================================================= | 330 | //========================================================================= |
312 | 331 | ||
313 | 'stringHash': function(aValue) { | 332 | 'stringHash': function(aValue) { |
314 | varresult; | 333 | varresult; |
315 | 334 | ||
316 | result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); | 335 | result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); |
317 | 336 | ||
318 | return result; | 337 | return result; |
319 | }, | 338 | }, |
320 | 339 | ||
321 | //========================================================================= | 340 | //========================================================================= |
322 | __syntaxFix__: "syntax fix" | 341 | __syntaxFix__: "syntax fix" |
323 | 342 | ||
324 | }); | 343 | }); |
325 | 344 | ||
326 | //############################################################################# | 345 | //############################################################################# |
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 | |||
@@ -1,283 +1,283 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | 24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } |
25 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | 25 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } |
26 | //if (typeof(Clipperz.PM.BookmarkletProcessor) == 'undefined') { Clipperz.PM.BookmarkletProcessor = {}; } | 26 | //if (typeof(Clipperz.PM.BookmarkletProcessor) == 'undefined') { Clipperz.PM.BookmarkletProcessor = {}; } |
27 | //if (typeof(Clipperz.PM.BookmarkletProcessor.versions) == 'undefined') { Clipperz.PM.BookmarkletProcessor.versions = {}; } | 27 | //if (typeof(Clipperz.PM.BookmarkletProcessor.versions) == 'undefined') { Clipperz.PM.BookmarkletProcessor.versions = {}; } |
28 | 28 | ||
29 | /* | 29 | /* |
30 | Clipperz.PM.BookmarkletProcessor.versions['abstract'] = function(anUser, aConfiguration) { | 30 | Clipperz.PM.BookmarkletProcessor.versions['abstract'] = function(anUser, aConfiguration) { |
31 | this._user = anUser; | 31 | this._user = anUser; |
32 | this._configuration = aConfiguration; | 32 | this._configuration = aConfiguration; |
33 | 33 | ||
34 | this._recordTitle = null; | 34 | this._recordTitle = null; |
35 | this._record = null; | 35 | this._record = null; |
36 | this._editableFields = null; | 36 | this._editableFields = null; |
37 | 37 | ||
38 | return this; | 38 | return this; |
39 | } | 39 | } |
40 | 40 | ||
41 | 41 | ||
42 | Clipperz.PM.BookmarkletProcessor.versions['abstract'].prototype = MochiKit.Base.update(null, { | 42 | Clipperz.PM.BookmarkletProcessor.versions['abstract'].prototype = MochiKit.Base.update(null, { |
43 | 43 | ||
44 | 'toString': function() { | 44 | 'toString': function() { |
45 | return "BookmarkletProcessor - " + this.user(); | 45 | return "BookmarkletProcessor - " + this.user(); |
46 | }, | 46 | }, |
47 | 47 | ||
48 | //------------------------------------------------------------------------- | 48 | //------------------------------------------------------------------------- |
49 | 49 | ||
50 | 'user': function() { | 50 | 'user': function() { |
51 | return this._user; | 51 | return this._user; |
52 | }, | 52 | }, |
53 | 53 | ||
54 | //------------------------------------------------------------------------- | 54 | //------------------------------------------------------------------------- |
55 | 55 | ||
56 | 'configuration': function() { | 56 | 'configuration': function() { |
57 | return this._configuration; | 57 | return this._configuration; |
58 | }, | 58 | }, |
59 | 59 | ||
60 | //------------------------------------------------------------------------- | 60 | //------------------------------------------------------------------------- |
61 | 61 | ||
62 | 'record': function() { | 62 | 'record': function() { |
63 | throw Clipperz.Base.exception.AbstractMethod; | 63 | throw Clipperz.Base.exception.AbstractMethod; |
64 | }, | 64 | }, |
65 | 65 | ||
66 | //------------------------------------------------------------------------- | 66 | //------------------------------------------------------------------------- |
67 | __syntaxFix__: "syntax fix" | 67 | __syntaxFix__: "syntax fix" |
68 | }); | 68 | }); |
69 | */ | 69 | */ |
70 | 70 | ||
71 | Clipperz.PM.BookmarkletProcessor = function(anUser, aConfiguration) { | 71 | Clipperz.PM.BookmarkletProcessor = function(anUser, aConfiguration) { |
72 | this._user = anUser; | 72 | this._user = anUser; |
73 | this._configuration = aConfiguration; | 73 | this._configuration = aConfiguration; |
74 | 74 | ||
75 | this._recordTitle = null; | 75 | this._recordTitle = null; |
76 | this._record = null; | 76 | this._record = null; |
77 | this._editableFields = null; | 77 | this._editableFields = null; |
78 | this._favicon = null; | 78 | this._favicon = null; |
79 | 79 | ||
80 | return this; | 80 | return this; |
81 | } | 81 | } |
82 | 82 | ||
83 | Clipperz.PM.BookmarkletProcessor.prototype = MochiKit.Base.update(null, { | 83 | Clipperz.PM.BookmarkletProcessor.prototype = MochiKit.Base.update(null, { |
84 | 84 | ||
85 | 'toString': function() { | 85 | 'toString': function() { |
86 | return "BookmarkletProcessor - " + this.user(); | 86 | return "BookmarkletProcessor - " + this.user(); |
87 | }, | 87 | }, |
88 | 88 | ||
89 | //------------------------------------------------------------------------- | 89 | //------------------------------------------------------------------------- |
90 | 90 | ||
91 | 'user': function() { | 91 | 'user': function() { |
92 | return this._user; | 92 | return this._user; |
93 | }, | 93 | }, |
94 | 94 | ||
95 | //------------------------------------------------------------------------- | 95 | //------------------------------------------------------------------------- |
96 | 96 | ||
97 | 'configuration': function() { | 97 | 'configuration': function() { |
98 | return this._configuration; | 98 | return this._configuration; |
99 | }, | 99 | }, |
100 | 100 | ||
101 | //------------------------------------------------------------------------- | 101 | //------------------------------------------------------------------------- |
102 | 102 | ||
103 | 'recordTitle': function() { | 103 | 'recordTitle': function() { |
104 | if (this._recordTitle == null) { | 104 | if (this._recordTitle == null) { |
105 | this._recordTitle = this.configuration().page.title; | 105 | this._recordTitle = this.configuration().page.title; |
106 | } | 106 | } |
107 | 107 | ||
108 | return this._recordTitle; | 108 | return this._recordTitle; |
109 | }, | 109 | }, |
110 | 110 | ||
111 | //------------------------------------------------------------------------- | 111 | //------------------------------------------------------------------------- |
112 | 112 | ||
113 | 'fields': function() { | 113 | 'fields': function() { |
114 | return this.configuration().form.inputs; | 114 | return this.configuration().form.inputs; |
115 | }, | 115 | }, |
116 | 116 | ||
117 | //------------------------------------------------------------------------- | 117 | //------------------------------------------------------------------------- |
118 | 118 | ||
119 | 'editableFields': function() { | 119 | 'editableFields': function() { |
120 | if (this._editableFields == null) { | 120 | if (this._editableFields == null) { |
121 | this._editableFields = MochiKit.Base.filter(function(aField) { | 121 | this._editableFields = MochiKit.Base.filter(function(aField) { |
122 | var result; | 122 | var result; |
123 | var type; | 123 | var type; |
124 | 124 | ||
125 | type = aField['type'].toLowerCase(); | 125 | type = aField['type'].toLowerCase(); |
126 | result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select')); | 126 | result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select')); |
127 | 127 | ||
128 | return result; | 128 | return result; |
129 | }, this.fields()) | 129 | }, this.fields()) |
130 | } | 130 | } |
131 | 131 | ||
132 | return this._editableFields; | 132 | return this._editableFields; |
133 | }, | 133 | }, |
134 | 134 | ||
135 | //------------------------------------------------------------------------- | 135 | //------------------------------------------------------------------------- |
136 | 136 | ||
137 | 'hostname': function() { | 137 | 'hostname': function() { |
138 | if (this._hostname == null) { | 138 | if (this._hostname == null) { |
139 | var actionUrl; | 139 | var actionUrl; |
140 | 140 | ||
141 | actionUrl = this.configuration()['form']['attributes']['action']; | 141 | actionUrl = Clipperz.Base.sanitizeUrl(this.configuration()['form']['attributes']['action']); |
142 | //MochiKit.Logging.logDebug("+++ actionUrl: " + actionUrl); | 142 | //MochiKit.Logging.logDebug("+++ actionUrl: " + actionUrl); |
143 | this._hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1'); | 143 | this._hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1'); |
144 | } | 144 | } |
145 | 145 | ||
146 | return this._hostname; | 146 | return this._hostname; |
147 | }, | 147 | }, |
148 | 148 | ||
149 | 'favicon': function() { | 149 | 'favicon': function() { |
150 | if (this._favicon == null) { | 150 | if (this._favicon == null) { |
151 | this._favicon = "http://" + this.hostname() + "/favicon.ico"; | 151 | this._favicon = "http://" + this.hostname() + "/favicon.ico"; |
152 | //MochiKit.Logging.logDebug("+++ favicon: " + this._favicon); | 152 | //MochiKit.Logging.logDebug("+++ favicon: " + this._favicon); |
153 | } | 153 | } |
154 | 154 | ||
155 | return this._favicon; | 155 | return this._favicon; |
156 | }, | 156 | }, |
157 | 157 | ||
158 | //------------------------------------------------------------------------- | 158 | //------------------------------------------------------------------------- |
159 | 159 | ||
160 | 'record': function() { | 160 | 'record': function() { |
161 | if (this._record == null) { | 161 | if (this._record == null) { |
162 | var record; | 162 | var record; |
163 | var recordVersion; | 163 | var recordVersion; |
164 | var directLogin; | 164 | var directLogin; |
165 | var bindings; | 165 | var bindings; |
166 | var i,c; | 166 | var i,c; |
167 | 167 | ||
168 | record = new Clipperz.PM.DataModel.Record({ | 168 | record = new Clipperz.PM.DataModel.Record({ |
169 | label:this.recordTitle(), | 169 | label:this.recordTitle(), |
170 | notes:"", | 170 | notes:"", |
171 | user:this.user() | 171 | user:this.user() |
172 | }); | 172 | }); |
173 | recordVersion = new Clipperz.PM.DataModel.RecordVersion(record, {}) | 173 | recordVersion = new Clipperz.PM.DataModel.RecordVersion(record, {}) |
174 | record.setCurrentVersion(recordVersion); | 174 | record.setCurrentVersion(recordVersion); |
175 | 175 | ||
176 | bindings = {}; | 176 | bindings = {}; |
177 | 177 | ||
178 | c = this.editableFields().length; | 178 | c = this.editableFields().length; |
179 | for (i=0; i<c; i++) { | 179 | for (i=0; i<c; i++) { |
180 | var formField; | 180 | var formField; |
181 | var recordField; | 181 | var recordField; |
182 | 182 | ||
183 | //MochiKit.Logging.logDebug(">>> adding a field"); | 183 | //MochiKit.Logging.logDebug(">>> adding a field"); |
184 | formField = this.editableFields()[i]; | 184 | formField = this.editableFields()[i]; |
185 | recordField = new Clipperz.PM.DataModel.RecordField({ | 185 | recordField = new Clipperz.PM.DataModel.RecordField({ |
186 | recordVersion:recordVersion, | 186 | recordVersion:recordVersion, |
187 | label:formField['name'], | 187 | label:formField['name'], |
188 | value:formField['value'], | 188 | value:formField['value'], |
189 | type:Clipperz.PM.Strings.inputTypeToRecordFieldType[formField['type']], | 189 | type:Clipperz.PM.Strings.inputTypeToRecordFieldType[formField['type']], |
190 | hidden:false | 190 | hidden:false |
191 | }); | 191 | }); |
192 | recordVersion.addField(recordField); | 192 | recordVersion.addField(recordField); |
193 | 193 | ||
194 | bindings[formField['name']] = recordField.key(); | 194 | bindings[formField['name']] = recordField.key(); |
195 | //MochiKit.Logging.logDebug("<<< adding a field"); | 195 | //MochiKit.Logging.logDebug("<<< adding a field"); |
196 | } | 196 | } |
197 | 197 | ||
198 | directLogin = new Clipperz.PM.DataModel.DirectLogin({ | 198 | directLogin = new Clipperz.PM.DataModel.DirectLogin({ |
199 | record:record, | 199 | record:record, |
200 | label:this.recordTitle() + Clipperz.PM.Strings['newDirectLoginLabelSuffix'], | 200 | label:this.recordTitle() + Clipperz.PM.Strings['newDirectLoginLabelSuffix'], |
201 | // bookmarkletVersion:this.version(), | 201 | // bookmarkletVersion:this.version(), |
202 | bookmarkletVersion:'0.2', | 202 | bookmarkletVersion:'0.2', |
203 | favicon:this.favicon(), | 203 | favicon:this.favicon(), |
204 | formData:this.configuration()['form'], | 204 | formData:this.configuration()['form'], |
205 | bindingData:bindings | 205 | bindingData:bindings |
206 | }); | 206 | }); |
207 | record.addDirectLogin(directLogin); | 207 | record.addDirectLogin(directLogin); |
208 | 208 | ||
209 | this.user().addRecord(record); | 209 | this.user().addRecord(record); |
210 | 210 | ||
211 | this._record = record; | 211 | this._record = record; |
212 | } | 212 | } |
213 | 213 | ||
214 | return this._record; | 214 | return this._record; |
215 | }, | 215 | }, |
216 | 216 | ||
217 | //------------------------------------------------------------------------- | 217 | //------------------------------------------------------------------------- |
218 | __syntaxFix__: "syntax fix" | 218 | __syntaxFix__: "syntax fix" |
219 | }); | 219 | }); |
220 | 220 | ||
221 | //############################################################################# | 221 | //############################################################################# |
222 | 222 | ||
223 | Clipperz.PM.BookmarkletProcessor.createRecordFromBookmarkletConfiguration = function(anUser, aConfiguration) { | 223 | Clipperz.PM.BookmarkletProcessor.createRecordFromBookmarkletConfiguration = function(anUser, aConfiguration) { |
224 | var processor; | 224 | var processor; |
225 | 225 | ||
226 | processor = new Clipperz.PM.BookmarkletProcessor(anUser, aConfiguration); | 226 | processor = new Clipperz.PM.BookmarkletProcessor(anUser, aConfiguration); |
227 | 227 | ||
228 | return processor.record(); | 228 | return processor.record(); |
229 | }; | 229 | }; |
230 | 230 | ||
231 | //----------------------------------------------------------------------------- | 231 | //----------------------------------------------------------------------------- |
232 | 232 | ||
233 | Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration = function(aConfiguration) { | 233 | Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration = function(aConfiguration) { |
234 | var result; | 234 | var result; |
235 | 235 | ||
236 | //throw "XSS Bookmarklet attempt"; | 236 | //throw "XSS Bookmarklet attempt"; |
237 | 237 | ||
238 | result = aConfiguration; | 238 | result = aConfiguration; |
239 | 239 | ||
240 | return result; | 240 | return result; |
241 | }; | 241 | }; |
242 | 242 | ||
243 | //----------------------------------------------------------------------------- | 243 | //----------------------------------------------------------------------------- |
244 | 244 | ||
245 | Clipperz.PM.BookmarkletProcessor.checkBookmarkletConfiguration = function(aConfiguration, aButton, aCallback) { | 245 | Clipperz.PM.BookmarkletProcessor.checkBookmarkletConfiguration = function(aConfiguration, aButton, aCallback) { |
246 | var result; | 246 | var result; |
247 | 247 | ||
248 | try { | 248 | try { |
249 | result = Clipperz.Base.evalJSON(aConfiguration); | 249 | result = Clipperz.Base.evalJSON(aConfiguration); |
250 | result = Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration(result); | 250 | result = Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration(result); |
251 | 251 | ||
252 | if (result['version'] != '0.2.3') { | 252 | if (result['version'] != '0.2.3') { |
253 | throw "WrongBookmarkletVersion"; | 253 | throw "WrongBookmarkletVersion"; |
254 | } | 254 | } |
255 | } catch (exception) { | 255 | } catch (exception) { |
256 | var title; | 256 | var title; |
257 | var message; | 257 | var message; |
258 | 258 | ||
259 | if (exception == "WrongBookmarkletVersion") { | 259 | if (exception == "WrongBookmarkletVersion") { |
260 | title = Clipperz.PM.Strings['newRecordPanelWrongBookmarkletVersionExceptionTitle']; | 260 | title = Clipperz.PM.Strings['newRecordPanelWrongBookmarkletVersionExceptionTitle']; |
261 | message = Clipperz.PM.Strings['newRecordPanelWrongBookmarkletVersionExceptionMessage']; | 261 | message = Clipperz.PM.Strings['newRecordPanelWrongBookmarkletVersionExceptionMessage']; |
262 | } else { | 262 | } else { |
263 | title = Clipperz.PM.Strings['newRecordPanelGeneralExceptionTitle']; | 263 | title = Clipperz.PM.Strings['newRecordPanelGeneralExceptionTitle']; |
264 | message = Clipperz.PM.Strings['newRecordPanelGeneralExceptionMessage']; | 264 | message = Clipperz.PM.Strings['newRecordPanelGeneralExceptionMessage']; |
265 | } | 265 | } |
266 | Clipperz.PM.Components.MessageBox().show({ | 266 | Clipperz.PM.Components.MessageBox().show({ |
267 | title:title, | 267 | title:title, |
268 | text:message, | 268 | text:message, |
269 | width:240, | 269 | width:240, |
270 | fn:aCallback, | 270 | fn:aCallback, |
271 | closable:false, | 271 | closable:false, |
272 | showProgressBar:false, | 272 | showProgressBar:false, |
273 | showCloseButton:false, | 273 | showCloseButton:false, |
274 | buttons:{'ok':Clipperz.PM.Strings['newRecordPanelExceptionPanelCloseButtonLabel']} | 274 | buttons:{'ok':Clipperz.PM.Strings['newRecordPanelExceptionPanelCloseButtonLabel']} |
275 | }, aButton); | 275 | }, aButton); |
276 | 276 | ||
277 | throw exception; | 277 | throw exception; |
278 | } | 278 | } |
279 | 279 | ||
280 | return result; | 280 | return result; |
281 | }; | 281 | }; |
282 | 282 | ||
283 | //----------------------------------------------------------------------------- | 283 | //----------------------------------------------------------------------------- |
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 | |||
@@ -1,169 +1,169 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | 24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } |
25 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | 25 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } |
26 | if (typeof(Clipperz.PM.Components) == 'undefined') { Clipperz.PM.Components = {}; } | 26 | if (typeof(Clipperz.PM.Components) == 'undefined') { Clipperz.PM.Components = {}; } |
27 | if (typeof(Clipperz.PM.Components.RecordDetail) == 'undefined') { Clipperz.PM.Components.RecordDetail = {}; } | 27 | if (typeof(Clipperz.PM.Components.RecordDetail) == 'undefined') { Clipperz.PM.Components.RecordDetail = {}; } |
28 | 28 | ||
29 | //############################################################################# | 29 | //############################################################################# |
30 | 30 | ||
31 | Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent = function(anElement, args) { | 31 | Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent = function(anElement, args) { |
32 | //MochiKit.Logging.logDebug(">>> new DirectLoginBindingComponent"); | 32 | //MochiKit.Logging.logDebug(">>> new DirectLoginBindingComponent"); |
33 | args = args || {}; | 33 | args = args || {}; |
34 | 34 | ||
35 | Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent.superclass.constructor.call(this, anElement, args); | 35 | Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent.superclass.constructor.call(this, anElement, args); |
36 | 36 | ||
37 | this._directLoginBinding = args.directLoginBinding || null; | 37 | this._directLoginBinding = args.directLoginBinding || null; |
38 | this.render(); | 38 | this.render(); |
39 | 39 | ||
40 | Clipperz.NotificationCenter.register(this.record(), 'addNewRecordField',this, 'syncAndUpdateEditMode'); | 40 | Clipperz.NotificationCenter.register(this.record(), 'addNewRecordField',this, 'syncAndUpdateEditMode'); |
41 | Clipperz.NotificationCenter.register(this.record(), 'removedField', this, 'syncAndUpdateEditMode'); | 41 | Clipperz.NotificationCenter.register(this.record(), 'removedField', this, 'syncAndUpdateEditMode'); |
42 | Clipperz.NotificationCenter.register(this.record(), 'updatedFieldLabel',this, 'syncAndUpdateEditMode'); | 42 | Clipperz.NotificationCenter.register(this.record(), 'updatedFieldLabel',this, 'syncAndUpdateEditMode'); |
43 | //MochiKit.Logging.logDebug("<<< new DirectLoginBindingComponent"); | 43 | //MochiKit.Logging.logDebug("<<< new DirectLoginBindingComponent"); |
44 | 44 | ||
45 | return this; | 45 | return this; |
46 | } | 46 | } |
47 | 47 | ||
48 | //============================================================================= | 48 | //============================================================================= |
49 | 49 | ||
50 | YAHOO.extendX(Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent, Clipperz.PM.Components.RecordDetail.AbstractComponent, { | 50 | YAHOO.extendX(Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent, Clipperz.PM.Components.RecordDetail.AbstractComponent, { |
51 | 51 | ||
52 | 'toString': function() { | 52 | 'toString': function() { |
53 | return "Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent component"; | 53 | return "Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent component"; |
54 | }, | 54 | }, |
55 | 55 | ||
56 | //------------------------------------------------------------------------- | 56 | //------------------------------------------------------------------------- |
57 | 57 | ||
58 | 'directLoginBinding': function() { | 58 | 'directLoginBinding': function() { |
59 | return this._directLoginBinding; | 59 | return this._directLoginBinding; |
60 | }, | 60 | }, |
61 | 61 | ||
62 | //------------------------------------------------------------------------- | 62 | //------------------------------------------------------------------------- |
63 | 63 | ||
64 | 'render': function() { | 64 | 'render': function() { |
65 | // Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'span', style:'font-weight:bold;', html:this.directLoginBinding().key()}) | 65 | // Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'span', style:'font-weight:bold;', html:this.directLoginBinding().key()}) |
66 | // Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'span', html:this.directLoginBinding().value()}) | 66 | // Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'span', html:this.directLoginBinding().value()}) |
67 | //MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.render"); | 67 | //MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.render"); |
68 | Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'td', cls:'directLoginBindingLabelTD', children:[ | 68 | Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'td', cls:'directLoginBindingLabelTD', children:[ |
69 | {tag:'span', html:this.directLoginBinding().key()} | 69 | {tag:'span', html:this.directLoginBinding().key()} |
70 | ]}); | 70 | ]}); |
71 | //MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.render - 1"); | 71 | //MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.render - 1"); |
72 | Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'td', cls:'directLoginBindingValueTD', children:[ | 72 | Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'td', cls:'directLoginBindingValueTD', children:[ |
73 | {tag:'div', id:this.getId('editModeBox'), children:[ | 73 | {tag:'div', id:this.getId('editModeBox'), children:[ |
74 | {tag:'select', id:this.getId('select'), children:this.recordFieldOptions()} | 74 | {tag:'select', id:this.getId('select'), children:this.recordFieldOptions()} |
75 | ]}, | 75 | ]}, |
76 | {tag:'div', id:this.getId('viewModeBox'), children:[ | 76 | {tag:'div', id:this.getId('viewModeBox'), children:[ |
77 | {tag:'span', id:this.getId('viewValue'), html:""} | 77 | {tag:'span', id:this.getId('viewValue'), html:""} |
78 | ]} | 78 | ]} |
79 | ]}); | 79 | ]}); |
80 | //MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.render - 2"); | 80 | //MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.render - 2"); |
81 | this.getElement('editModeBox').setVisibilityMode(YAHOO.ext.Element.DISPLAY); | 81 | this.getElement('editModeBox').setVisibilityMode(YAHOO.ext.Element.DISPLAY); |
82 | this.getElement('viewModeBox').setVisibilityMode(YAHOO.ext.Element.DISPLAY); | 82 | this.getElement('viewModeBox').setVisibilityMode(YAHOO.ext.Element.DISPLAY); |
83 | 83 | ||
84 | this.update(); | 84 | this.update(); |
85 | //MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.render"); | 85 | //MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.render"); |
86 | }, | 86 | }, |
87 | 87 | ||
88 | //------------------------------------------------------------------------- | 88 | //------------------------------------------------------------------------- |
89 | 89 | ||
90 | 'recordFieldOptions': function() { | 90 | 'recordFieldOptions': function() { |
91 | varresult; | 91 | varresult; |
92 | var option; | 92 | var option; |
93 | varrecordFieldKey; | 93 | varrecordFieldKey; |
94 | varrecordFields; | 94 | varrecordFields; |
95 | 95 | ||
96 | //MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.recordFieldOptions"); | 96 | //MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.recordFieldOptions"); |
97 | recordFields = this.directLoginBinding().directLogin().record().currentVersion().fields(); | 97 | recordFields = this.directLoginBinding().directLogin().record().currentVersion().fields(); |
98 | result = []; | 98 | result = []; |
99 | option = {tag:'option', value:null, html:'---'}; | 99 | option = {tag:'option', value:null, html:'---'}; |
100 | result.push(option); | 100 | result.push(option); |
101 | for (recordFieldKey in recordFields) { | 101 | for (recordFieldKey in recordFields) { |
102 | //TODO: remove the value: field and replace it with element.dom.value = <some value> | 102 | //TODO: remove the value: field and replace it with element.dom.value = <some value> |
103 | option = {tag:'option', value:recordFieldKey, html:recordFields[recordFieldKey].label()} | 103 | option = {tag:'option', value:recordFieldKey, html:Clipperz.Base.sanitizeString(recordFields[recordFieldKey].label())} |
104 | if (recordFieldKey == this.directLoginBinding().fieldKey()) { | 104 | if (recordFieldKey == this.directLoginBinding().fieldKey()) { |
105 | option['selected'] = true; | 105 | option['selected'] = true; |
106 | } | 106 | } |
107 | result.push(option); | 107 | result.push(option); |
108 | } | 108 | } |
109 | //MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.recordFieldOptions"); | 109 | //MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.recordFieldOptions"); |
110 | 110 | ||
111 | return result; | 111 | return result; |
112 | }, | 112 | }, |
113 | 113 | ||
114 | //------------------------------------------------------------------------- | 114 | //------------------------------------------------------------------------- |
115 | 115 | ||
116 | 'syncAndUpdateEditMode': function() { | 116 | 'syncAndUpdateEditMode': function() { |
117 | this.synchronizeComponentValues(); | 117 | this.synchronizeComponentValues(); |
118 | this.updateEditMode(); | 118 | this.updateEditMode(); |
119 | }, | 119 | }, |
120 | 120 | ||
121 | 'updateEditMode': function() { | 121 | 'updateEditMode': function() { |
122 | varselectElementBox; | 122 | varselectElementBox; |
123 | 123 | ||
124 | //MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.updateEditMode"); | 124 | //MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.updateEditMode"); |
125 | this.getElement('viewModeBox').hide(); | 125 | this.getElement('viewModeBox').hide(); |
126 | 126 | ||
127 | selectElementBox = this.getElement('editModeBox'); | 127 | selectElementBox = this.getElement('editModeBox'); |
128 | selectElementBox.update(""); | 128 | selectElementBox.update(""); |
129 | 129 | ||
130 | Clipperz.YUI.DomHelper.append(selectElementBox.dom, {tag:'select', id:this.getId('select'), children:this.recordFieldOptions()}); | 130 | Clipperz.YUI.DomHelper.append(selectElementBox.dom, {tag:'select', id:this.getId('select'), children:this.recordFieldOptions()}); |
131 | 131 | ||
132 | /* | 132 | /* |
133 | selectElement = this.getElement('select'); | 133 | selectElement = this.getElement('select'); |
134 | 134 | ||
135 | selectElement.update(""); | 135 | selectElement.update(""); |
136 | MochiKit.Iter.forEach(this.recordFieldOptions(), function(anOption) { | 136 | MochiKit.Iter.forEach(this.recordFieldOptions(), function(anOption) { |
137 | Clipperz.YUI.DomHelper.append(selectElement.dom, anOption); | 137 | Clipperz.YUI.DomHelper.append(selectElement.dom, anOption); |
138 | }); | 138 | }); |
139 | */ | 139 | */ |
140 | 140 | ||
141 | 141 | ||
142 | this.getElement('editModeBox').show(); | 142 | this.getElement('editModeBox').show(); |
143 | //MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateEditMode"); | 143 | //MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateEditMode"); |
144 | }, | 144 | }, |
145 | 145 | ||
146 | //------------------------------------------------------------------------- | 146 | //------------------------------------------------------------------------- |
147 | 147 | ||
148 | 'updateViewMode': function() { | 148 | 'updateViewMode': function() { |
149 | //MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.updateViewMode"); | 149 | //MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.updateViewMode"); |
150 | this.getElement('editModeBox').hide(); | 150 | this.getElement('editModeBox').hide(); |
151 | this.getElement('viewModeBox').show(); | 151 | this.getElement('viewModeBox').show(); |
152 | 152 | ||
153 | this.getElement('viewValue').update(this.directLoginBinding().field().label()); | 153 | this.getElement('viewValue').update(Clipperz.Base.sanitizeString(this.directLoginBinding().field().label())); |
154 | //MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateViewMode"); | 154 | //MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateViewMode"); |
155 | }, | 155 | }, |
156 | 156 | ||
157 | //------------------------------------------------------------------------- | 157 | //------------------------------------------------------------------------- |
158 | 158 | ||
159 | 'synchronizeComponentValues': function() { | 159 | 'synchronizeComponentValues': function() { |
160 | //MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.synchronizeComponentValues") | 160 | //MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.synchronizeComponentValues") |
161 | //MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.synchronizeComponentValues - 1 - " + this.getId('select')); | 161 | //MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.synchronizeComponentValues - 1 - " + this.getId('select')); |
162 | this.directLoginBinding().setFieldKey(this.getDom('select').value); | 162 | this.directLoginBinding().setFieldKey(this.getDom('select').value); |
163 | //MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.synchronizeComponentValues"); | 163 | //MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.synchronizeComponentValues"); |
164 | }, | 164 | }, |
165 | 165 | ||
166 | //------------------------------------------------------------------------- | 166 | //------------------------------------------------------------------------- |
167 | __syntaxFix__: "syntax fix" | 167 | __syntaxFix__: "syntax fix" |
168 | }); | 168 | }); |
169 | 169 | ||
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 | |||
@@ -1,531 +1,539 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | 24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } |
25 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | 25 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } |
26 | if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } | 26 | if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } |
27 | 27 | ||
28 | 28 | ||
29 | //############################################################################# | 29 | //############################################################################# |
30 | 30 | ||
31 | Clipperz.PM.DataModel.DirectLogin = function(args) { | 31 | Clipperz.PM.DataModel.DirectLogin = function(args) { |
32 | //MochiKit.Logging.logDebug(">>> new Clipperz.PM.DataModel.DirectLogin"); | 32 | //MochiKit.Logging.logDebug(">>> new Clipperz.PM.DataModel.DirectLogin"); |
33 | //console.log(">>> new Clipperz.PM.DataModel.DirectLogin - args: %o", args); | 33 | //console.log(">>> new Clipperz.PM.DataModel.DirectLogin - args: %o", args); |
34 | //console.log("--- formData: %s", Clipperz.Base.serializeJSON(args.formData)); | 34 | //console.log("--- formData: %s", Clipperz.Base.serializeJSON(args.formData)); |
35 | args = args || {}; | 35 | args = args || {}; |
36 | 36 | ||
37 | //MochiKit.Logging.logDebug("--- new Clipperz.PM.DataModel.DirectLogin - args: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args))); | 37 | //MochiKit.Logging.logDebug("--- new Clipperz.PM.DataModel.DirectLogin - args: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args))); |
38 | this._record = args.record || null; | 38 | this._record = args.record || null; |
39 | this._label = args.label || "unnamed record" | 39 | this._label = args.label || "unnamed record" |
40 | this._reference = args.reference || Clipperz.PM.Crypto.randomKey(); | 40 | this._reference = args.reference || Clipperz.PM.Crypto.randomKey(); |
41 | this._favicon = args.favicon || null; | 41 | this._favicon = Clipperz.Base.sanitizeFavicon(args.favicon) || null; |
42 | this._bookmarkletVersion = args.bookmarkletVersion || "0.1"; | 42 | this._bookmarkletVersion = args.bookmarkletVersion || "0.1"; |
43 | 43 | ||
44 | this._directLoginInputs = null; | 44 | this._directLoginInputs = null; |
45 | 45 | ||
46 | this._formValues = args.formValues || {}; | 46 | this._formValues = args.formValues || {}; |
47 | this.setFormData(args.formData || null); | 47 | this.setFormData(args.formData || null); |
48 | //console.log("=== formData: %o", this.formData()); | 48 | //console.log("=== formData: %o", this.formData()); |
49 | 49 | ||
50 | if (args.legacyBindingData == null) { | 50 | if (args.legacyBindingData == null) { |
51 | this.setBindingData(args.bindingData || null); | 51 | this.setBindingData(args.bindingData || null); |
52 | } else { | 52 | } else { |
53 | this.setLegacyBindingData(args.legacyBindingData); | 53 | this.setLegacyBindingData(args.legacyBindingData); |
54 | } | 54 | } |
55 | 55 | ||
56 | this._fixedFavicon = null; | 56 | this._fixedFavicon = null; |
57 | 57 | ||
58 | //this._formValues = args.formValues || (this.hasValuesToSet() ? {} : null); | 58 | //this._formValues = args.formValues || (this.hasValuesToSet() ? {} : null); |
59 | //MochiKit.Logging.logDebug("<<< new Clipperz.PM.DataModel.DirectLogin"); | 59 | //MochiKit.Logging.logDebug("<<< new Clipperz.PM.DataModel.DirectLogin"); |
60 | 60 | ||
61 | return this; | 61 | return this; |
62 | } | 62 | } |
63 | 63 | ||
64 | Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, { | 64 | Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, { |
65 | 65 | ||
66 | 'remove': function() { | 66 | 'remove': function() { |
67 | this.record().removeDirectLogin(this); | 67 | this.record().removeDirectLogin(this); |
68 | }, | 68 | }, |
69 | 69 | ||
70 | //------------------------------------------------------------------------- | 70 | //------------------------------------------------------------------------- |
71 | 71 | ||
72 | 'record': function() { | 72 | 'record': function() { |
73 | return this._record; | 73 | return this._record; |
74 | }, | 74 | }, |
75 | 75 | ||
76 | //------------------------------------------------------------------------- | 76 | //------------------------------------------------------------------------- |
77 | 77 | ||
78 | 'user': function() { | 78 | 'user': function() { |
79 | return this.record().user(); | 79 | return this.record().user(); |
80 | }, | 80 | }, |
81 | 81 | ||
82 | //------------------------------------------------------------------------- | 82 | //------------------------------------------------------------------------- |
83 | 83 | ||
84 | 'reference': function() { | 84 | 'reference': function() { |
85 | return this._reference; | 85 | return this._reference; |
86 | }, | 86 | }, |
87 | 87 | ||
88 | //------------------------------------------------------------------------- | 88 | //------------------------------------------------------------------------- |
89 | 89 | ||
90 | 'label': function() { | 90 | 'label': function() { |
91 | return this._label; | 91 | return this._label; |
92 | }, | 92 | }, |
93 | 93 | ||
94 | 'setLabel': function(aValue) { | 94 | 'setLabel': function(aValue) { |
95 | this._label = aValue; | 95 | this._label = aValue; |
96 | }, | 96 | }, |
97 | 97 | ||
98 | //------------------------------------------------------------------------- | 98 | //------------------------------------------------------------------------- |
99 | 99 | ||
100 | 'favicon': function() { | 100 | 'favicon': function() { |
101 | if (this._favicon == null) { | 101 | if (this._favicon == null) { |
102 | varactionUrl; | 102 | varactionUrl; |
103 | var hostname; | 103 | var hostname; |
104 | 104 | ||
105 | actionUrl = this.formData()['attributes']['action']; | 105 | actionUrl = this.action(); |
106 | hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1'); | 106 | hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1'); |
107 | this._favicon = "http://" + hostname + "/favicon.ico"; | 107 | this._favicon = Clipperz.Base.sanitizeFavicon("http://" + hostname + "/favicon.ico"); |
108 | } | 108 | } |
109 | 109 | ||
110 | return this._favicon; | 110 | return this._favicon; |
111 | }, | 111 | }, |
112 | 112 | ||
113 | //------------------------------------------------------------------------- | 113 | //------------------------------------------------------------------------- |
114 | 114 | ||
115 | 'fixedFavicon': function() { | 115 | 'fixedFavicon': function() { |
116 | var result; | 116 | var result; |
117 | 117 | ||
118 | if (this._fixedFavicon == null) { | 118 | if (this._fixedFavicon == null) { |
119 | result = this.favicon(); | 119 | result = this.favicon(); |
120 | 120 | ||
121 | if (Clipperz_IEisBroken) { | 121 | if (Clipperz_IEisBroken) { |
122 | if (this.user().preferences().disableUnsecureFaviconLoadingForIE()) { | 122 | if (this.user().preferences().disableUnsecureFaviconLoadingForIE()) { |
123 | if (result.indexOf('https://') != 0) { | 123 | if (result.indexOf('https://') != 0) { |
124 | result = Clipperz.PM.Strings['defaultFaviconUrl_IE']; | 124 | result = Clipperz.PM.Strings['defaultFaviconUrl_IE']; |
125 | this.setFixedFavicon(result); | 125 | this.setFixedFavicon(result); |
126 | } | 126 | } |
127 | } | 127 | } |
128 | } | 128 | } |
129 | } else { | 129 | } else { |
130 | result = this._fixedFavicon; | 130 | result = this._fixedFavicon; |
131 | } | 131 | } |
132 | 132 | ||
133 | return result; | 133 | return result; |
134 | }, | 134 | }, |
135 | 135 | ||
136 | 'setFixedFavicon': function(aValue) { | 136 | 'setFixedFavicon': function(aValue) { |
137 | this._fixedFavicon = aValue; | 137 | this._fixedFavicon = aValue; |
138 | }, | 138 | }, |
139 | 139 | ||
140 | 'action': function () { | ||
141 | varresult; | ||
142 | |||
143 | result = Clipperz.Base.sanitizeUrl(this.formData()['attributes']['action']); | ||
144 | |||
145 | return result; | ||
146 | }, | ||
147 | |||
140 | //------------------------------------------------------------------------- | 148 | //------------------------------------------------------------------------- |
141 | 149 | ||
142 | 'bookmarkletVersion': function() { | 150 | 'bookmarkletVersion': function() { |
143 | return this._bookmarkletVersion; | 151 | return this._bookmarkletVersion; |
144 | }, | 152 | }, |
145 | 153 | ||
146 | 'setBookmarkletVersion': function(aValue) { | 154 | 'setBookmarkletVersion': function(aValue) { |
147 | this._bookmarkletVersion = aValue; | 155 | this._bookmarkletVersion = aValue; |
148 | }, | 156 | }, |
149 | 157 | ||
150 | //------------------------------------------------------------------------- | 158 | //------------------------------------------------------------------------- |
151 | 159 | ||
152 | 'formData': function() { | 160 | 'formData': function() { |
153 | return this._formData; | 161 | return this._formData; |
154 | }, | 162 | }, |
155 | 163 | ||
156 | 'setFormData': function(aValue) { | 164 | 'setFormData': function(aValue) { |
157 | var formData; | 165 | var formData; |
158 | 166 | ||
159 | //MochiKit.Logging.logDebug(">>> DirectLogin.setFormData - " + Clipperz.Base.serializeJSON(aValue)); | 167 | //MochiKit.Logging.logDebug(">>> DirectLogin.setFormData - " + Clipperz.Base.serializeJSON(aValue)); |
160 | switch (this.bookmarkletVersion()) { | 168 | switch (this.bookmarkletVersion()) { |
161 | case "0.2": | 169 | case "0.2": |
162 | formData = aValue; | 170 | formData = aValue; |
163 | break; | 171 | break; |
164 | case "0.1": | 172 | case "0.1": |
165 | //MochiKit.Logging.logDebug("--- DirectLogin.setFormData - fixing form data from bookmarklet version 0.1"); | 173 | //MochiKit.Logging.logDebug("--- DirectLogin.setFormData - fixing form data from bookmarklet version 0.1"); |
166 | formData = this.fixFormDataFromBookmarkletVersion_0_1(aValue); | 174 | formData = this.fixFormDataFromBookmarkletVersion_0_1(aValue); |
167 | break; | 175 | break; |
168 | } | 176 | } |
169 | 177 | ||
170 | this._formData = aValue; | 178 | this._formData = aValue; |
171 | this.setBookmarkletVersion("0.2"); | 179 | this.setBookmarkletVersion("0.2"); |
172 | 180 | ||
173 | //MochiKit.Logging.logDebug("--- DirectLogin.setFormData - formData: " + Clipperz.Base.serializeJSON(formData)); | 181 | //MochiKit.Logging.logDebug("--- DirectLogin.setFormData - formData: " + Clipperz.Base.serializeJSON(formData)); |
174 | if (formData != null) { | 182 | if (formData != null) { |
175 | var i,c; | 183 | var i,c; |
176 | 184 | ||
177 | this._directLoginInputs = []; | 185 | this._directLoginInputs = []; |
178 | c = formData['inputs'].length; | 186 | c = formData['inputs'].length; |
179 | for (i=0; i<c; i++) { | 187 | for (i=0; i<c; i++) { |
180 | var directLoginInput; | 188 | var directLoginInput; |
181 | 189 | ||
182 | directLoginInput = new Clipperz.PM.DataModel.DirectLoginInput(this, formData['inputs'][i]); | 190 | directLoginInput = new Clipperz.PM.DataModel.DirectLoginInput(this, formData['inputs'][i]); |
183 | this._directLoginInputs.push(directLoginInput); | 191 | this._directLoginInputs.push(directLoginInput); |
184 | } | 192 | } |
185 | } | 193 | } |
186 | //MochiKit.Logging.logDebug("<<< DirectLogin.setFormData"); | 194 | //MochiKit.Logging.logDebug("<<< DirectLogin.setFormData"); |
187 | }, | 195 | }, |
188 | 196 | ||
189 | 'fixFormDataFromBookmarkletVersion_0_1': function(aValue) { | 197 | 'fixFormDataFromBookmarkletVersion_0_1': function(aValue) { |
190 | //{"type":"radio", "name":"action", "value":"new-user", "checked":false }, { "type":"radio", "name":"action", "value":"sign-in", "checked":true } | 198 | //{"type":"radio", "name":"action", "value":"new-user", "checked":false }, { "type":"radio", "name":"action", "value":"sign-in", "checked":true } |
191 | // || | 199 | // || |
192 | // \ / | 200 | // \ / |
193 | // \/ | 201 | // \/ |
194 | //{"name":"dominio", "type":"radio", "options":[{"value":"@alice.it", "checked":true}, {"value":"@tin.it", "checked":false}, {"value":"@virgilio.it", "checked":false}, {"value":"@tim.it", "checked":false}]} | 202 | //{"name":"dominio", "type":"radio", "options":[{"value":"@alice.it", "checked":true}, {"value":"@tin.it", "checked":false}, {"value":"@virgilio.it", "checked":false}, {"value":"@tim.it", "checked":false}]} |
195 | var result; | 203 | var result; |
196 | var inputs; | 204 | var inputs; |
197 | var updatedInputs; | 205 | var updatedInputs; |
198 | var radios; | 206 | var radios; |
199 | 207 | ||
200 | //MochiKit.Logging.logDebug(">>> DirectLogin.fixFormDataFromBookmarkletVersion_0_1"); | 208 | //MochiKit.Logging.logDebug(">>> DirectLogin.fixFormDataFromBookmarkletVersion_0_1"); |
201 | result = aValue; | 209 | result = aValue; |
202 | inputs = aValue['inputs']; | 210 | inputs = aValue['inputs']; |
203 | 211 | ||
204 | updatedInputs = MochiKit.Base.filter(function(anInput) { | 212 | updatedInputs = MochiKit.Base.filter(function(anInput) { |
205 | varresult; | 213 | varresult; |
206 | var type; | 214 | var type; |
207 | 215 | ||
208 | type = anInput['type'] || 'text'; | 216 | type = anInput['type'] || 'text'; |
209 | result = type.toLowerCase() != 'radio'; | 217 | result = type.toLowerCase() != 'radio'; |
210 | 218 | ||
211 | return result; | 219 | return result; |
212 | }, inputs); | 220 | }, inputs); |
213 | radios = MochiKit.Base.filter(function(anInput) { | 221 | radios = MochiKit.Base.filter(function(anInput) { |
214 | varresult; | 222 | varresult; |
215 | var type; | 223 | var type; |
216 | 224 | ||
217 | type = anInput['type'] || 'text'; | 225 | type = anInput['type'] || 'text'; |
218 | result = type.toLowerCase() == 'radio'; | 226 | result = type.toLowerCase() == 'radio'; |
219 | 227 | ||
220 | return result; | 228 | return result; |
221 | }, inputs); | 229 | }, inputs); |
222 | 230 | ||
223 | if (radios.length > 0) { | 231 | if (radios.length > 0) { |
224 | var updatedRadios; | 232 | var updatedRadios; |
225 | 233 | ||
226 | updatedRadios = {}; | 234 | updatedRadios = {}; |
227 | MochiKit.Iter.forEach(radios, MochiKit.Base.bind(function(aRadio) { | 235 | MochiKit.Iter.forEach(radios, MochiKit.Base.bind(function(aRadio) { |
228 | varradioConfiguration; | 236 | varradioConfiguration; |
229 | 237 | ||
230 | radioConfiguration = updatedRadios[aRadio['name']]; | 238 | radioConfiguration = updatedRadios[aRadio['name']]; |
231 | if (radioConfiguration == null) { | 239 | if (radioConfiguration == null) { |
232 | radioConfiguration = {type:'radio', name:aRadio['name'], options:[]}; | 240 | radioConfiguration = {type:'radio', name:aRadio['name'], options:[]}; |
233 | updatedRadios[aRadio['name']] = radioConfiguration; | 241 | updatedRadios[aRadio['name']] = radioConfiguration; |
234 | } | 242 | } |
235 | 243 | ||
236 | //TODO: remove the value: field and replace it with element.dom.value = <some value> | 244 | //TODO: remove the value: field and replace it with element.dom.value = <some value> |
237 | radioConfiguration.options.push({value:aRadio['value'], checked:aRadio['checked']}); | 245 | radioConfiguration.options.push({value:aRadio['value'], checked:aRadio['checked']}); |
238 | 246 | ||
239 | if ((aRadio['checked'] == true) && (this.formValues()[aRadio['name']] == null)) { | 247 | if ((aRadio['checked'] == true) && (this.formValues()[aRadio['name']] == null)) { |
240 | //MochiKit.Logging.logDebug("+++ setting value '" + aRadio['value'] + "' for key: '" + aRadio['name'] + "'"); | 248 | //MochiKit.Logging.logDebug("+++ setting value '" + aRadio['value'] + "' for key: '" + aRadio['name'] + "'"); |
241 | this.formValues()[aRadio['name']] = aRadio['value']; | 249 | this.formValues()[aRadio['name']] = aRadio['value']; |
242 | } | 250 | } |
243 | }, this)) | 251 | }, this)) |
244 | 252 | ||
245 | updatedInputs = MochiKit.Base.concat(updatedInputs, MochiKit.Base.values(updatedRadios)); | 253 | updatedInputs = MochiKit.Base.concat(updatedInputs, MochiKit.Base.values(updatedRadios)); |
246 | } | 254 | } |
247 | 255 | ||
248 | delete result.inputs; | 256 | delete result.inputs; |
249 | result.inputs = updatedInputs; | 257 | result.inputs = updatedInputs; |
250 | //MochiKit.Logging.logDebug("<<< DirectLogin.fixFormDataFromBookmarkletVersion_0_1"); | 258 | //MochiKit.Logging.logDebug("<<< DirectLogin.fixFormDataFromBookmarkletVersion_0_1"); |
251 | 259 | ||
252 | return result; | 260 | return result; |
253 | }, | 261 | }, |
254 | 262 | ||
255 | //......................................................................... | 263 | //......................................................................... |
256 | 264 | ||
257 | 'directLoginInputs': function() { | 265 | 'directLoginInputs': function() { |
258 | return this._directLoginInputs; | 266 | return this._directLoginInputs; |
259 | }, | 267 | }, |
260 | 268 | ||
261 | //------------------------------------------------------------------------- | 269 | //------------------------------------------------------------------------- |
262 | 270 | ||
263 | 'formValues': function() { | 271 | 'formValues': function() { |
264 | return this._formValues; | 272 | return this._formValues; |
265 | }, | 273 | }, |
266 | 274 | ||
267 | 'hasValuesToSet': function() { | 275 | 'hasValuesToSet': function() { |
268 | var result; | 276 | var result; |
269 | 277 | ||
270 | //MochiKit.Logging.logDebug(">>> DirectLogin.hasValuesToSet"); | 278 | //MochiKit.Logging.logDebug(">>> DirectLogin.hasValuesToSet"); |
271 | if (this.directLoginInputs() != null) { | 279 | if (this.directLoginInputs() != null) { |
272 | result = MochiKit.Iter.some(this.directLoginInputs(), MochiKit.Base.methodcaller('shouldSetValue')); | 280 | result = MochiKit.Iter.some(this.directLoginInputs(), MochiKit.Base.methodcaller('shouldSetValue')); |
273 | } else { | 281 | } else { |
274 | result = false; | 282 | result = false; |
275 | } | 283 | } |
276 | //MochiKit.Logging.logDebug("<<< DirectLogin.hasValuesToSet"); | 284 | //MochiKit.Logging.logDebug("<<< DirectLogin.hasValuesToSet"); |
277 | 285 | ||
278 | return result; | 286 | return result; |
279 | }, | 287 | }, |
280 | 288 | ||
281 | //'additionalValues': function() { | 289 | //'additionalValues': function() { |
282 | 'inputsRequiringAdditionalValues': function() { | 290 | 'inputsRequiringAdditionalValues': function() { |
283 | varresult; | 291 | varresult; |
284 | var inputs; | 292 | var inputs; |
285 | 293 | ||
286 | //MochiKit.Logging.logDebug(">>> DirectLogin.additionalValues"); | 294 | //MochiKit.Logging.logDebug(">>> DirectLogin.additionalValues"); |
287 | result = {}; | 295 | result = {}; |
288 | if (this.directLoginInputs() != null) { | 296 | if (this.directLoginInputs() != null) { |
289 | inputs = MochiKit.Base.filter(MochiKit.Base.methodcaller('shouldSetValue'), this.directLoginInputs()); | 297 | inputs = MochiKit.Base.filter(MochiKit.Base.methodcaller('shouldSetValue'), this.directLoginInputs()); |
290 | MochiKit.Iter.forEach(inputs, function(anInput) { | 298 | MochiKit.Iter.forEach(inputs, function(anInput) { |
291 | result[anInput.name()] = anInput; | 299 | result[anInput.name()] = anInput; |
292 | }) | 300 | }) |
293 | } | 301 | } |
294 | //MochiKit.Logging.logDebug("<<< DirectLogin.additionalValues"); | 302 | //MochiKit.Logging.logDebug("<<< DirectLogin.additionalValues"); |
295 | 303 | ||
296 | return result; | 304 | return result; |
297 | }, | 305 | }, |
298 | 306 | ||
299 | //------------------------------------------------------------------------- | 307 | //------------------------------------------------------------------------- |
300 | 308 | ||
301 | 'bindingData': function() { | 309 | 'bindingData': function() { |
302 | return this._bindingData; | 310 | return this._bindingData; |
303 | }, | 311 | }, |
304 | 312 | ||
305 | 'setBindingData': function(aValue) { | 313 | 'setBindingData': function(aValue) { |
306 | //MochiKit.Logging.logDebug(">>> DirectLogin.setBindingData"); | 314 | //MochiKit.Logging.logDebug(">>> DirectLogin.setBindingData"); |
307 | if (aValue != null) { | 315 | if (aValue != null) { |
308 | var bindingKey; | 316 | var bindingKey; |
309 | 317 | ||
310 | this._bindingData = aValue; | 318 | this._bindingData = aValue; |
311 | this._bindings = {}; | 319 | this._bindings = {}; |
312 | 320 | ||
313 | for (bindingKey in aValue) { | 321 | for (bindingKey in aValue) { |
314 | var directLoginBinding; | 322 | var directLoginBinding; |
315 | 323 | ||
316 | directLoginBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, bindingKey, {fieldKey:aValue[bindingKey]}); | 324 | directLoginBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, bindingKey, {fieldKey:aValue[bindingKey]}); |
317 | this._bindings[bindingKey] = directLoginBinding; | 325 | this._bindings[bindingKey] = directLoginBinding; |
318 | } | 326 | } |
319 | } else { | 327 | } else { |
320 | var editableFields; | 328 | var editableFields; |
321 | var bindings; | 329 | var bindings; |
322 | 330 | ||
323 | bindings = {}; | 331 | bindings = {}; |
324 | 332 | ||
325 | editableFields = MochiKit.Base.filter(function(aField) { | 333 | editableFields = MochiKit.Base.filter(function(aField) { |
326 | var result; | 334 | var result; |
327 | var type; | 335 | var type; |
328 | 336 | ||
329 | type = aField['type'].toLowerCase(); | 337 | type = aField['type'].toLowerCase(); |
330 | result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select')); | 338 | result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select')); |
331 | 339 | ||
332 | return result; | 340 | return result; |
333 | }, this.formData().inputs); | 341 | }, this.formData().inputs); |
334 | 342 | ||
335 | MochiKit.Iter.forEach(editableFields, function(anEditableField) { | 343 | MochiKit.Iter.forEach(editableFields, function(anEditableField) { |
336 | bindings[anEditableField['name']] = new Clipperz.PM.DataModel.DirectLoginBinding(this, anEditableField['name']); | 344 | bindings[anEditableField['name']] = new Clipperz.PM.DataModel.DirectLoginBinding(this, anEditableField['name']); |
337 | }, this); | 345 | }, this); |
338 | 346 | ||
339 | this._bindings = bindings; | 347 | this._bindings = bindings; |
340 | } | 348 | } |
341 | //MochiKit.Logging.logDebug("<<< DirectLogin.setBindingData"); | 349 | //MochiKit.Logging.logDebug("<<< DirectLogin.setBindingData"); |
342 | }, | 350 | }, |
343 | 351 | ||
344 | 'setLegacyBindingData': function(aValue) { | 352 | 'setLegacyBindingData': function(aValue) { |
345 | //MochiKit.Logging.logDebug(">>> DirectLogin.setLegacyBindingData"); | 353 | //MochiKit.Logging.logDebug(">>> DirectLogin.setLegacyBindingData"); |
346 | var bindingKey; | 354 | var bindingKey; |
347 | 355 | ||
348 | this._bindingData = aValue; | 356 | this._bindingData = aValue; |
349 | this._bindings = {}; | 357 | this._bindings = {}; |
350 | 358 | ||
351 | for (bindingKey in aValue) { | 359 | for (bindingKey in aValue) { |
352 | var directLoginBinding; | 360 | var directLoginBinding; |
353 | 361 | ||
354 | directLoginBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, bindingKey, {fieldName:aValue[bindingKey]}); | 362 | directLoginBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, bindingKey, {fieldName:aValue[bindingKey]}); |
355 | this._bindings[bindingKey] = directLoginBinding; | 363 | this._bindings[bindingKey] = directLoginBinding; |
356 | } | 364 | } |
357 | //MochiKit.Logging.logDebug("<<< DirectLogin.setLegacyBindingData"); | 365 | //MochiKit.Logging.logDebug("<<< DirectLogin.setLegacyBindingData"); |
358 | }, | 366 | }, |
359 | 367 | ||
360 | //......................................................................... | 368 | //......................................................................... |
361 | 369 | ||
362 | 'bindings': function() { | 370 | 'bindings': function() { |
363 | return this._bindings; | 371 | return this._bindings; |
364 | }, | 372 | }, |
365 | 373 | ||
366 | //------------------------------------------------------------------------- | 374 | //------------------------------------------------------------------------- |
367 | 375 | ||
368 | 'serializedData': function() { | 376 | 'serializedData': function() { |
369 | var result; | 377 | var result; |
370 | varbindingKey; | 378 | varbindingKey; |
371 | 379 | ||
372 | result = {}; | 380 | result = {}; |
373 | // result.reference = this.reference(); | 381 | // result.reference = this.reference(); |
374 | result.label = this.label(); | 382 | result.label = this.label(); |
375 | result.favicon = this.favicon() || ""; | 383 | result.favicon = this.favicon() || ""; |
376 | result.bookmarkletVersion = this.bookmarkletVersion(); | 384 | result.bookmarkletVersion = this.bookmarkletVersion(); |
377 | result.formData = this.formData(); | 385 | result.formData = this.formData(); |
378 | if (this.hasValuesToSet) { | 386 | if (this.hasValuesToSet) { |
379 | result.formValues = this.formValues(); | 387 | result.formValues = this.formValues(); |
380 | } | 388 | } |
381 | result.bindingData = {}; | 389 | result.bindingData = {}; |
382 | 390 | ||
383 | for (bindingKey in this.bindings()) { | 391 | for (bindingKey in this.bindings()) { |
384 | result.bindingData[bindingKey] = this.bindings()[bindingKey].serializedData(); | 392 | result.bindingData[bindingKey] = this.bindings()[bindingKey].serializedData(); |
385 | } | 393 | } |
386 | 394 | ||
387 | return result; | 395 | return result; |
388 | }, | 396 | }, |
389 | 397 | ||
390 | //------------------------------------------------------------------------- | 398 | //------------------------------------------------------------------------- |
391 | 399 | ||
392 | 'handleMissingFaviconImage': function(anEvent) { | 400 | 'handleMissingFaviconImage': function(anEvent) { |
393 | anEvent.stop(); | 401 | anEvent.stop(); |
394 | MochiKit.Signal.disconnectAll(anEvent.src()); | 402 | MochiKit.Signal.disconnectAll(anEvent.src()); |
395 | this.setFixedFavicon(Clipperz.PM.Strings['defaultFaviconUrl']); | 403 | this.setFixedFavicon(Clipperz.PM.Strings['defaultFaviconUrl']); |
396 | anEvent.src().src = this.fixedFavicon(); | 404 | anEvent.src().src = this.fixedFavicon(); |
397 | }, | 405 | }, |
398 | 406 | ||
399 | //========================================================================= | 407 | //========================================================================= |
400 | 408 | ||
401 | 'runHttpAuthDirectLogin': function(aWindow) { | 409 | 'runHttpAuthDirectLogin': function(aWindow) { |
402 | MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() { | 410 | MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() { |
403 | var completeUrl; | 411 | var completeUrl; |
404 | var url; | 412 | var url; |
405 | 413 | ||
406 | url = this.bindings()['url'].field().value(); | 414 | url = this.bindings()['url'].field().value(); |
407 | 415 | ||
408 | if (/^https?\:\/\//.test(url) == false) { | 416 | if (/^https?\:\/\//.test(url) == false) { |
409 | url = 'http://' + url; | 417 | url = 'http://' + url; |
410 | } | 418 | } |
411 | 419 | ||
412 | if (Clipperz_IEisBroken === true) { | 420 | if (Clipperz_IEisBroken === true) { |
413 | completeUrl = url; | 421 | completeUrl = url; |
414 | } else { | 422 | } else { |
415 | var username; | 423 | var username; |
416 | var password; | 424 | var password; |
417 | 425 | ||
418 | username = this.bindings()['username'].field().value(); | 426 | username = this.bindings()['username'].field().value(); |
419 | password = this.bindings()['password'].field().value(); | 427 | password = this.bindings()['password'].field().value(); |
420 | 428 | ||
421 | /(^https?\:\/\/)?(.*)/.test(url); | 429 | /(^https?\:\/\/)?(.*)/.test(url); |
422 | 430 | ||
423 | completeUrl = RegExp.$1 + username + ':' + password + '@' + RegExp.$2; | 431 | completeUrl = RegExp.$1 + username + ':' + password + '@' + RegExp.$2; |
424 | } | 432 | } |
425 | 433 | ||
426 | MochiKit.DOM.currentWindow().location.href = completeUrl; | 434 | MochiKit.DOM.currentWindow().location.href = completeUrl; |
427 | }, this)); | 435 | }, this)); |
428 | }, | 436 | }, |
429 | 437 | ||
430 | //------------------------------------------------------------------------- | 438 | //------------------------------------------------------------------------- |
431 | 439 | ||
432 | 'runSubmitFormDirectLogin': function(aWindow) { | 440 | 'runSubmitFormDirectLogin': function(aWindow) { |
433 | MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() { | 441 | MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() { |
434 | var formElement; | 442 | var formElement; |
435 | varformSubmitFunction; | 443 | varformSubmitFunction; |
436 | var submitButtons; | 444 | var submitButtons; |
437 | 445 | ||
438 | //MochiKit.Logging.logDebug("### runDirectLogin - 3"); | 446 | //MochiKit.Logging.logDebug("### runDirectLogin - 3"); |
439 | // MochiKit.DOM.currentDocument().write('<html><head><title>' + this.label() + '</title><META http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body></body></html>') | 447 | // MochiKit.DOM.currentDocument().write('<html><head><title>' + this.label() + '</title><META http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body></body></html>') |
440 | //MochiKit.Logging.logDebug("### runDirectLogin - 3.1"); | 448 | //MochiKit.Logging.logDebug("### runDirectLogin - 3.1"); |
441 | MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, MochiKit.DOM.H3(null, "Loading " + this.label() + " ...")); | 449 | MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, MochiKit.DOM.H3(null, "Loading " + this.label() + " ...")); |
442 | //MochiKit.Logging.logDebug("### runDirectLogin - 4"); | 450 | //MochiKit.Logging.logDebug("### runDirectLogin - 4"); |
443 | //console.log(this.formData()['attributes']); | 451 | //console.log(this.formData()['attributes']); |
444 | formElement = MochiKit.DOM.FORM(MochiKit.Base.update({id:'directLoginForm'}, {'method':this.formData()['attributes']['method'], | 452 | formElement = MochiKit.DOM.FORM(MochiKit.Base.update({id:'directLoginForm'}, {'method':this.formData()['attributes']['method'], |
445 | 'action':this.formData()['attributes']['action']})); | 453 | 'action': this.action()})); |
446 | //MochiKit.Logging.logDebug("### runDirectLogin - 5"); | 454 | //MochiKit.Logging.logDebug("### runDirectLogin - 5"); |
447 | formSubmitFunction = MochiKit.Base.method(formElement, 'submit'); | 455 | formSubmitFunction = MochiKit.Base.method(formElement, 'submit'); |
448 | //MochiKit.Logging.logDebug("### runDirectLogin - 6"); | 456 | //MochiKit.Logging.logDebug("### runDirectLogin - 6"); |
449 | 457 | ||
450 | MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, | 458 | MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, |
451 | MochiKit.DOM.DIV({style:'display:none; visibility:hidden;'}, formElement) | 459 | MochiKit.DOM.DIV({style:'display:none; visibility:hidden;'}, formElement) |
452 | ); | 460 | ); |
453 | //MochiKit.Logging.logDebug("### runDirectLogin - 7"); | 461 | //MochiKit.Logging.logDebug("### runDirectLogin - 7"); |
454 | MochiKit.DOM.appendChildNodes(formElement, MochiKit.Base.map(MochiKit.Base.methodcaller("formConfiguration"), | 462 | MochiKit.DOM.appendChildNodes(formElement, MochiKit.Base.map(MochiKit.Base.methodcaller("formConfiguration"), |
455 | this.directLoginInputs())); | 463 | this.directLoginInputs())); |
456 | //MochiKit.Logging.logDebug("### runDirectLogin - 8"); | 464 | //MochiKit.Logging.logDebug("### runDirectLogin - 8"); |
457 | 465 | ||
458 | submitButtons = MochiKit.Base.filter(function(anInputElement) { | 466 | submitButtons = MochiKit.Base.filter(function(anInputElement) { |
459 | //MochiKit.Logging.logDebug("### runDirectLogin - 8.1 - " + anInputElement); | 467 | //MochiKit.Logging.logDebug("### runDirectLogin - 8.1 - " + anInputElement); |
460 | //MochiKit.Logging.logDebug("### runDirectLogin - 8.2 - " + anInputElement.tagName); | 468 | //MochiKit.Logging.logDebug("### runDirectLogin - 8.2 - " + anInputElement.tagName); |
461 | //MochiKit.Logging.logDebug("### runDirectLogin - 8.3 - " + anInputElement.getAttribute('type')); | 469 | //MochiKit.Logging.logDebug("### runDirectLogin - 8.3 - " + anInputElement.getAttribute('type')); |
462 | return ((anInputElement.tagName.toLowerCase() == 'input') && (anInputElement.getAttribute('type').toLowerCase() == 'submit')); | 470 | return ((anInputElement.tagName.toLowerCase() == 'input') && (anInputElement.getAttribute('type').toLowerCase() == 'submit')); |
463 | }, formElement.elements) | 471 | }, formElement.elements) |
464 | //MochiKit.Logging.logDebug("### runDirectLogin - 9"); | 472 | //MochiKit.Logging.logDebug("### runDirectLogin - 9"); |
465 | 473 | ||
466 | if (submitButtons.length == 0) { | 474 | if (submitButtons.length == 0) { |
467 | //MochiKit.Logging.logDebug("### OLD submit") | 475 | //MochiKit.Logging.logDebug("### OLD submit") |
468 | if (Clipperz_IEisBroken == true) { | 476 | if (Clipperz_IEisBroken == true) { |
469 | //MochiKit.Logging.logDebug("### runDirectLogin - 10"); | 477 | //MochiKit.Logging.logDebug("### runDirectLogin - 10"); |
470 | formElement.submit(); | 478 | formElement.submit(); |
471 | } else { | 479 | } else { |
472 | //MochiKit.Logging.logDebug("### runDirectLogin - 11"); | 480 | //MochiKit.Logging.logDebug("### runDirectLogin - 11"); |
473 | formSubmitFunction(); | 481 | formSubmitFunction(); |
474 | } | 482 | } |
475 | } else { | 483 | } else { |
476 | //MochiKit.Logging.logDebug("### NEW submit") | 484 | //MochiKit.Logging.logDebug("### NEW submit") |
477 | submitButtons[0].click(); | 485 | submitButtons[0].click(); |
478 | } | 486 | } |
479 | 487 | ||
480 | }, this)); | 488 | }, this)); |
481 | }, | 489 | }, |
482 | 490 | ||
483 | //------------------------------------------------------------------------- | 491 | //------------------------------------------------------------------------- |
484 | 492 | ||
485 | 'runDirectLogin': function(aNewWindow) { | 493 | 'runDirectLogin': function(aNewWindow) { |
486 | varnewWindow; | 494 | varnewWindow; |
487 | 495 | ||
488 | //console.log("formData.attributes", this.formData()['attributes']); | 496 | //console.log("formData.attributes", this.formData()['attributes']); |
489 | // if (/^javascript/.test(this.formData()['attributes']['action'])) { | 497 | // if (/^javascript/.test(this.formData()['attributes']['action'])) { |
490 | if ((/^(https?|webdav|ftp)\:/.test(this.formData()['attributes']['action']) == false) && | 498 | if ((/^(https?|webdav|ftp)\:/.test(this.action()) == false) && |
491 | (this.formData()['attributes']['type'] != 'http_auth')) | 499 | (this.formData()['attributes']['type'] != 'http_auth') |
492 | { | 500 | ) { |
493 | var messageBoxConfiguration; | 501 | var messageBoxConfiguration; |
494 | 502 | ||
495 | if (typeof(aNewWindow) != 'undefined') { | 503 | if (typeof(aNewWindow) != 'undefined') { |
496 | aNewWindow.close(); | 504 | aNewWindow.close(); |
497 | } | 505 | } |
498 | 506 | ||
499 | messageBoxConfiguration = {}; | 507 | messageBoxConfiguration = {}; |
500 | messageBoxConfiguration.title = Clipperz.PM.Strings['VulnerabilityWarning_Panel_title']; | 508 | messageBoxConfiguration.title = Clipperz.PM.Strings['VulnerabilityWarning_Panel_title']; |
501 | messageBoxConfiguration.msg = Clipperz.PM.Strings['VulnerabilityWarning_Panel_message']; | 509 | messageBoxConfiguration.msg = Clipperz.PM.Strings['VulnerabilityWarning_Panel_message']; |
502 | messageBoxConfiguration.animEl = YAHOO.ext.Element.get("mainDiv"); | 510 | messageBoxConfiguration.animEl = YAHOO.ext.Element.get("mainDiv"); |
503 | messageBoxConfiguration.progress = false; | 511 | messageBoxConfiguration.progress = false; |
504 | messageBoxConfiguration.closable = false; | 512 | messageBoxConfiguration.closable = false; |
505 | messageBoxConfiguration.buttons = {'cancel': Clipperz.PM.Strings['VulnerabilityWarning_Panel_buttonLabel']}; | 513 | messageBoxConfiguration.buttons = {'cancel': Clipperz.PM.Strings['VulnerabilityWarning_Panel_buttonLabel']}; |
506 | 514 | ||
507 | Clipperz.YUI.MessageBox.show(messageBoxConfiguration); | 515 | Clipperz.YUI.MessageBox.show(messageBoxConfiguration); |
508 | 516 | ||
509 | throw Clipperz.Base.exception.VulnerabilityIssue; | 517 | throw Clipperz.Base.exception.VulnerabilityIssue; |
510 | } | 518 | } |
511 | 519 | ||
512 | //MochiKit.Logging.logDebug("### runDirectLogin - 1 : " + Clipperz.Base.serializeJSON(this.serializedData())); | 520 | //MochiKit.Logging.logDebug("### runDirectLogin - 1 : " + Clipperz.Base.serializeJSON(this.serializedData())); |
513 | if (typeof(aNewWindow) == 'undefined') { | 521 | if (typeof(aNewWindow) == 'undefined') { |
514 | newWindow = window.open(Clipperz.PM.Strings['directLoginJumpPageUrl'], ""); | 522 | newWindow = window.open(Clipperz.PM.Strings['directLoginJumpPageUrl'], ""); |
515 | } else { | 523 | } else { |
516 | newWindow = aNewWindow; | 524 | newWindow = aNewWindow; |
517 | } | 525 | } |
518 | //MochiKit.Logging.logDebug("### runDirectLogin - 2"); | 526 | //MochiKit.Logging.logDebug("### runDirectLogin - 2"); |
519 | 527 | ||
520 | if (this.formData()['attributes']['type'] == 'http_auth') { | 528 | if (this.formData()['attributes']['type'] == 'http_auth') { |
521 | this.runHttpAuthDirectLogin(newWindow); | 529 | this.runHttpAuthDirectLogin(newWindow); |
522 | } else { | 530 | } else { |
523 | this.runSubmitFormDirectLogin(newWindow) | 531 | this.runSubmitFormDirectLogin(newWindow) |
524 | } | 532 | } |
525 | }, | 533 | }, |
526 | 534 | ||
527 | //------------------------------------------------------------------------- | 535 | //------------------------------------------------------------------------- |
528 | __syntaxFix__: "syntax fix" | 536 | __syntaxFix__: "syntax fix" |
529 | 537 | ||
530 | }); | 538 | }); |
531 | 539 | ||
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 | |||
@@ -1,187 +1,187 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | 24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } |
25 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | 25 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } |
26 | if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } | 26 | if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } |
27 | 27 | ||
28 | 28 | ||
29 | //############################################################################# | 29 | //############################################################################# |
30 | 30 | ||
31 | Clipperz.PM.DataModel.DirectLoginReference = function(args) { | 31 | Clipperz.PM.DataModel.DirectLoginReference = function(args) { |
32 | args = args || {}; | 32 | args = args || {}; |
33 | 33 | ||
34 | //MochiKit.Logging.logDebug(">>> new DirectLoginReference: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args))); | 34 | //MochiKit.Logging.logDebug(">>> new DirectLoginReference: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args))); |
35 | //MochiKit.Logging.logDebug(">>> new DirectLoginReference - record: " + args.record); | 35 | //MochiKit.Logging.logDebug(">>> new DirectLoginReference - record: " + args.record); |
36 | this._user = args.user; | 36 | this._user = args.user; |
37 | 37 | ||
38 | if (args.directLogin != null) { | 38 | if (args.directLogin != null) { |
39 | this._reference = args.directLogin.reference(); | 39 | this._reference = args.directLogin.reference(); |
40 | this._recordReference = args.directLogin.record().reference(); | 40 | this._recordReference = args.directLogin.record().reference(); |
41 | this._label = args.directLogin.label(); | 41 | this._label = args.directLogin.label(); |
42 | this._favicon = args.directLogin.favicon() || null; | 42 | this._favicon = args.directLogin.favicon() || null; |
43 | 43 | ||
44 | this._directLogin = args.directLogin; | 44 | this._directLogin = args.directLogin; |
45 | this._record = args.directLogin.record(); | 45 | this._record = args.directLogin.record(); |
46 | } else { | 46 | } else { |
47 | this._reference = args.reference; | 47 | this._reference = args.reference; |
48 | this._recordReference = args.record; | 48 | this._recordReference = args.record; |
49 | this._label = args.label; | 49 | this._label = args.label; |
50 | this._favicon = args.favicon || null; | 50 | this._favicon = Clipperz.Base.sanitizeFavicon(args.favicon) || null; |
51 | 51 | ||
52 | this._directLogin = null; | 52 | this._directLogin = null; |
53 | this._record = null; | 53 | this._record = null; |
54 | } | 54 | } |
55 | 55 | ||
56 | this._fixedFavicon = null; | 56 | this._fixedFavicon = null; |
57 | 57 | ||
58 | return this; | 58 | return this; |
59 | } | 59 | } |
60 | 60 | ||
61 | Clipperz.PM.DataModel.DirectLoginReference.prototype = MochiKit.Base.update(null, { | 61 | Clipperz.PM.DataModel.DirectLoginReference.prototype = MochiKit.Base.update(null, { |
62 | 62 | ||
63 | 'user': function() { | 63 | 'user': function() { |
64 | return this._user; | 64 | return this._user; |
65 | }, | 65 | }, |
66 | 66 | ||
67 | //------------------------------------------------------------------------- | 67 | //------------------------------------------------------------------------- |
68 | 68 | ||
69 | 'reference': function() { | 69 | 'reference': function() { |
70 | return this._reference; | 70 | return this._reference; |
71 | }, | 71 | }, |
72 | 72 | ||
73 | //------------------------------------------------------------------------- | 73 | //------------------------------------------------------------------------- |
74 | 74 | ||
75 | 'synchronizeValues': function(aDirectLogin) { | 75 | 'synchronizeValues': function(aDirectLogin) { |
76 | this._label = aDirectLogin.label(); | 76 | this._label = aDirectLogin.label(); |
77 | this._favicon = aDirectLogin.favicon(); | 77 | this._favicon = aDirectLogin.favicon(); |
78 | }, | 78 | }, |
79 | 79 | ||
80 | //------------------------------------------------------------------------- | 80 | //------------------------------------------------------------------------- |
81 | 81 | ||
82 | 'label': function() { | 82 | 'label': function() { |
83 | return this._label; | 83 | return this._label; |
84 | }, | 84 | }, |
85 | 85 | ||
86 | //------------------------------------------------------------------------- | 86 | //------------------------------------------------------------------------- |
87 | 87 | ||
88 | 'recordReference': function() { | 88 | 'recordReference': function() { |
89 | return this._recordReference; | 89 | return this._recordReference; |
90 | }, | 90 | }, |
91 | 91 | ||
92 | //------------------------------------------------------------------------- | 92 | //------------------------------------------------------------------------- |
93 | 93 | ||
94 | 'record': function() { | 94 | 'record': function() { |
95 | //MochiKit.Logging.logDebug(">>> DirectLoginReference.record"); | 95 | //MochiKit.Logging.logDebug(">>> DirectLoginReference.record"); |
96 | if (this._record == null) { | 96 | if (this._record == null) { |
97 | this._record = this.user().records()[this.recordReference()]; | 97 | this._record = this.user().records()[this.recordReference()]; |
98 | } | 98 | } |
99 | 99 | ||
100 | //MochiKit.Logging.logDebug("<<< DirectLoginReference.record"); | 100 | //MochiKit.Logging.logDebug("<<< DirectLoginReference.record"); |
101 | return this._record; | 101 | return this._record; |
102 | }, | 102 | }, |
103 | 103 | ||
104 | //------------------------------------------------------------------------- | 104 | //------------------------------------------------------------------------- |
105 | 105 | ||
106 | 'favicon': function() { | 106 | 'favicon': function() { |
107 | return this._favicon; | 107 | return this._favicon; |
108 | }, | 108 | }, |
109 | 109 | ||
110 | //------------------------------------------------------------------------- | 110 | //------------------------------------------------------------------------- |
111 | 111 | ||
112 | 'fixedFavicon': function() { | 112 | 'fixedFavicon': function() { |
113 | var result; | 113 | var result; |
114 | 114 | ||
115 | if (this._fixedFavicon == null) { | 115 | if (this._fixedFavicon == null) { |
116 | result = this.favicon(); | 116 | result = this.favicon(); |
117 | 117 | ||
118 | if (Clipperz_IEisBroken && (this.user().preferences().disableUnsecureFaviconLoadingForIE()) && (result.indexOf('https://') != 0)) { | 118 | if (Clipperz_IEisBroken && (this.user().preferences().disableUnsecureFaviconLoadingForIE()) && (result.indexOf('https://') != 0)) { |
119 | result = Clipperz.PM.Strings['defaultFaviconUrl_IE']; | 119 | result = Clipperz.PM.Strings['defaultFaviconUrl_IE']; |
120 | this.setFixedFavicon(result); | 120 | this.setFixedFavicon(result); |
121 | } | 121 | } |
122 | } else { | 122 | } else { |
123 | result = this._fixedFavicon; | 123 | result = this._fixedFavicon; |
124 | } | 124 | } |
125 | 125 | ||
126 | return result; | 126 | return result; |
127 | }, | 127 | }, |
128 | 128 | ||
129 | 'setFixedFavicon': function(aValue) { | 129 | 'setFixedFavicon': function(aValue) { |
130 | this._fixedFavicon = aValue; | 130 | this._fixedFavicon = aValue; |
131 | }, | 131 | }, |
132 | 132 | ||
133 | //------------------------------------------------------------------------- | 133 | //------------------------------------------------------------------------- |
134 | 134 | ||
135 | 'setupJumpPageWindow': function(aWindow) { | 135 | 'setupJumpPageWindow': function(aWindow) { |
136 | //MochiKit.Logging.logDebug(">>> DirectLoginReference.setupJumpPageWindow - " + aWindow); | 136 | //MochiKit.Logging.logDebug(">>> DirectLoginReference.setupJumpPageWindow - " + aWindow); |
137 | try { | 137 | try { |
138 | MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() { | 138 | MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() { |
139 | MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, | 139 | MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, |
140 | MochiKit.DOM.H1(null, "Loading " + this.label()) | 140 | MochiKit.DOM.H1(null, "Loading " + this.label()) |
141 | ); | 141 | ); |
142 | }, this)); | 142 | }, this)); |
143 | } catch(e) { | 143 | } catch(e) { |
144 | MochiKit.Logging.logDebug("EXCEPTION: " + e); | 144 | MochiKit.Logging.logDebug("EXCEPTION: " + e); |
145 | } | 145 | } |
146 | //MochiKit.Logging.logDebug("<<< DirectLoginReference.setupJumpPageWindow"); | 146 | //MochiKit.Logging.logDebug("<<< DirectLoginReference.setupJumpPageWindow"); |
147 | }, | 147 | }, |
148 | 148 | ||
149 | //------------------------------------------------------------------------- | 149 | //------------------------------------------------------------------------- |
150 | 150 | ||
151 | 'deferredDirectLogin': function() { | 151 | 'deferredDirectLogin': function() { |
152 | var deferredResult; | 152 | var deferredResult; |
153 | 153 | ||
154 | //MochiKit.Logging.logDebug(">>> DirectLoginReference.deferredDirectLogin - " + this); | 154 | //MochiKit.Logging.logDebug(">>> DirectLoginReference.deferredDirectLogin - " + this); |
155 | deferredResult = new MochiKit.Async.Deferred(); | 155 | deferredResult = new MochiKit.Async.Deferred(); |
156 | //MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 1"); | 156 | //MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 1"); |
157 | deferredResult.addCallback(MochiKit.Base.method(this.record(), 'deferredData')); | 157 | deferredResult.addCallback(MochiKit.Base.method(this.record(), 'deferredData')); |
158 | //MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 2"); | 158 | //MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 2"); |
159 | deferredResult.addCallback(function(aRecord, aDirectLoginReference) { | 159 | deferredResult.addCallback(function(aRecord, aDirectLoginReference) { |
160 | return aRecord.directLogins()[aDirectLoginReference]; | 160 | return aRecord.directLogins()[aDirectLoginReference]; |
161 | }, this.record(), this.reference()); | 161 | }, this.record(), this.reference()); |
162 | //MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 3"); | 162 | //MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 3"); |
163 | deferredResult.callback(); | 163 | deferredResult.callback(); |
164 | //MochiKit.Logging.logDebug("<<< DirectLoginReference.deferredDirectLogin"); | 164 | //MochiKit.Logging.logDebug("<<< DirectLoginReference.deferredDirectLogin"); |
165 | 165 | ||
166 | return deferredResult; | 166 | return deferredResult; |
167 | }, | 167 | }, |
168 | 168 | ||
169 | //------------------------------------------------------------------------- | 169 | //------------------------------------------------------------------------- |
170 | 170 | ||
171 | 'handleMissingFaviconImage': function(anEvent) { | 171 | 'handleMissingFaviconImage': function(anEvent) { |
172 | //MochiKit.Logging.logDebug(">>> DirectLoginReference.handleMissingFaviconImage"); | 172 | //MochiKit.Logging.logDebug(">>> DirectLoginReference.handleMissingFaviconImage"); |
173 | anEvent.stop(); | 173 | anEvent.stop(); |
174 | MochiKit.Signal.disconnectAll(anEvent.src()); | 174 | MochiKit.Signal.disconnectAll(anEvent.src()); |
175 | this.setFixedFavicon(Clipperz.PM.Strings['defaultFaviconUrl']); | 175 | this.setFixedFavicon(Clipperz.PM.Strings['defaultFaviconUrl']); |
176 | //MochiKit.Logging.logDebug("--- DirectLoginReference.handleMissingFaviconImage - fixedFavicon: " + this.fixedFavicon()); | 176 | //MochiKit.Logging.logDebug("--- DirectLoginReference.handleMissingFaviconImage - fixedFavicon: " + this.fixedFavicon()); |
177 | //MochiKit.Logging.logDebug("--- DirectLoginReference.handleMissingFaviconImage - anEvent.src().src: " + anEvent.src().src); | 177 | //MochiKit.Logging.logDebug("--- DirectLoginReference.handleMissingFaviconImage - anEvent.src().src: " + anEvent.src().src); |
178 | // MochiKit.DOM.swapDOM(anEvent.src(), MochiKit.DOM.IMG({src:'this.fixedFavicon()'})); | 178 | // MochiKit.DOM.swapDOM(anEvent.src(), MochiKit.DOM.IMG({src:'this.fixedFavicon()'})); |
179 | anEvent.src().src = this.fixedFavicon(); | 179 | anEvent.src().src = this.fixedFavicon(); |
180 | //MochiKit.Logging.logDebug("<<< DirectLoginReference.handleMissingFaviconImage"); | 180 | //MochiKit.Logging.logDebug("<<< DirectLoginReference.handleMissingFaviconImage"); |
181 | }, | 181 | }, |
182 | 182 | ||
183 | //------------------------------------------------------------------------- | 183 | //------------------------------------------------------------------------- |
184 | __syntaxFix__: "syntax fix" | 184 | __syntaxFix__: "syntax fix" |
185 | 185 | ||
186 | }); | 186 | }); |
187 | 187 | ||
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 | |||
@@ -1,799 +1,826 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) { | 24 | try { 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 | ||
30 | Clipperz.PM.Proxy.Offline.DataStore = function(args) { | 30 | Clipperz.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, { |
49 | Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, { | 50 | Clipperz.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 | //------------------------------------------------------------------------- |
64 | 65 | ||
65 | 'data': function () { | 66 | 'data': function () { |
66 | return this._data; | 67 | return this._data; |
67 | }, | 68 | }, |
68 | 69 | ||
69 | //------------------------------------------------------------------------- | 70 | //------------------------------------------------------------------------- |
70 | 71 | ||
71 | 'tolls': function () { | 72 | 'tolls': function () { |
72 | return this._tolls; | 73 | return this._tolls; |
73 | }, | 74 | }, |
74 | 75 | ||
75 | //------------------------------------------------------------------------- | 76 | //------------------------------------------------------------------------- |
76 | 77 | ||
77 | 'connections': function () { | 78 | 'connections': function () { |
78 | return this._connections; | 79 | return this._connections; |
79 | }, | 80 | }, |
80 | 81 | ||
81 | //========================================================================= | 82 | //========================================================================= |
82 | 83 | ||
83 | 'resetData': function() { | 84 | 'resetData': function() { |
84 | this._data = { | 85 | this._data = { |
85 | 'users': { | 86 | 'users': { |
86 | 'catchAllUser': { | 87 | 'catchAllUser': { |
87 | __masterkey_test_value__: 'masterkey', | 88 | __masterkey_test_value__: 'masterkey', |
88 | s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00', | 89 | s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00', |
89 | v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00' | 90 | v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00' |
90 | } | 91 | } |
91 | } | 92 | } |
92 | }; | 93 | }; |
93 | }, | 94 | }, |
94 | 95 | ||
95 | //------------------------------------------------------------------------- | 96 | //------------------------------------------------------------------------- |
96 | 97 | ||
97 | 'setupWithEncryptedData': function(someData) { | 98 | 'setupWithEncryptedData': function(someData) { |
98 | this._data = Clipperz.Base.deepClone(someData); | 99 | this._data = Clipperz.Base.deepClone(someData); |
99 | }, | 100 | }, |
100 | 101 | ||
101 | //------------------------------------------------------------------------- | 102 | //------------------------------------------------------------------------- |
102 | 103 | ||
103 | 'setupWithData': function(someData) { | 104 | 'setupWithData': function(someData) { |
104 | var deferredResult; | 105 | var deferredResult; |
105 | var resultData; | 106 | var resultData; |
106 | var i, c; | 107 | var i, c; |
107 | 108 | ||
108 | //Clipperz.log(">>> Proxy.Test.setupWithData"); | 109 | //Clipperz.log(">>> Proxy.Test.setupWithData"); |
109 | resultData = this._data; | 110 | resultData = this._data; |
110 | 111 | ||
111 | deferredResult = new MochiKit.Async.Deferred(); | 112 | deferredResult = new MochiKit.Async.Deferred(); |
112 | c = someData['users'].length; | 113 | c = someData['users'].length; |
113 | 114 | ||
114 | for (i=0; i<c; i++) { | 115 | for (i=0; i<c; i++) { |
115 | varnewConnection; | 116 | varnewConnection; |
116 | varrecordConfiguration; | 117 | varrecordConfiguration; |
117 | 118 | ||
118 | deferredResult.addCallback(MochiKit.Base.method(this, 'userSerializedEncryptedData', someData['users'][i])); | 119 | deferredResult.addCallback(MochiKit.Base.method(this, 'userSerializedEncryptedData', someData['users'][i])); |
119 | deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) { | 120 | deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) { |
120 | //console.log("SERIALIZED USER", aUserSerializationContext); | 121 | //console.log("SERIALIZED USER", aUserSerializationContext); |
121 | resultData['users'][aUserSerializationContext['credentials']['C']] = { | 122 | resultData['users'][aUserSerializationContext['credentials']['C']] = { |
122 | 's': aUserSerializationContext['credentials']['s'], | 123 | 's': aUserSerializationContext['credentials']['s'], |
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 | ||
171 | 'set_A': function(aValue) { | 182 | 'set_A': function(aValue) { |
172 | this._A = aValue; | 183 | this._A = aValue; |
173 | }, | 184 | }, |
174 | 185 | ||
175 | //------------------------------------------------------------------------- | 186 | //------------------------------------------------------------------------- |
176 | 187 | ||
177 | 'userData': function() { | 188 | 'userData': function() { |
178 | return this._userData; | 189 | return this._userData; |
179 | }, | 190 | }, |
180 | 191 | ||
181 | 'setUserData': function(aValue) { | 192 | 'setUserData': function(aValue) { |
182 | this._userData = aValue; | 193 | this._userData = aValue; |
183 | }, | 194 | }, |
184 | 195 | ||
185 | //========================================================================= | 196 | //========================================================================= |
186 | 197 | ||
187 | 'getTollForRequestType': function (aRequestType) { | 198 | 'getTollForRequestType': function (aRequestType) { |
188 | varresult; | 199 | varresult; |
189 | vartargetValue; | 200 | vartargetValue; |
190 | var cost; | 201 | var cost; |
191 | 202 | ||
192 | targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); | 203 | targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); |
193 | switch (aRequestType) { | 204 | switch (aRequestType) { |
194 | case 'REGISTER': | 205 | case 'REGISTER': |
195 | cost = 5; | 206 | cost = 5; |
196 | break; | 207 | break; |
197 | case 'CONNECT': | 208 | case 'CONNECT': |
198 | cost = 5; | 209 | cost = 5; |
199 | break; | 210 | break; |
200 | case 'MESSAGE': | 211 | case 'MESSAGE': |
201 | cost = 2; | 212 | cost = 2; |
202 | break; | 213 | break; |
203 | } | 214 | } |
204 | 215 | ||
205 | result = { | 216 | result = { |
206 | requestType: aRequestType, | 217 | requestType: aRequestType, |
207 | targetValue: targetValue, | 218 | targetValue: targetValue, |
208 | cost: cost | 219 | cost: cost |
209 | } | 220 | } |
210 | 221 | ||
211 | if (this.shouldPayTolls()) { | 222 | if (this.shouldPayTolls()) { |
212 | this.tolls()[targetValue] = result; | 223 | this.tolls()[targetValue] = result; |
213 | } | 224 | } |
214 | 225 | ||
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; |
265 | }, | 276 | }, |
266 | 277 | ||
267 | //========================================================================= | 278 | //========================================================================= |
268 | 279 | ||
269 | '_knock': function(someParameters) { | 280 | '_knock': function(someParameters) { |
270 | var result; | 281 | var result; |
271 | 282 | ||
272 | result = { | 283 | result = { |
273 | toll: this.getTollForRequestType(someParameters['requestType']) | 284 | toll: this.getTollForRequestType(someParameters['requestType']) |
274 | // toll: { | 285 | // toll: { |
275 | // requestType: someParameters['requestType'], | 286 | // requestType: someParameters['requestType'], |
276 | // targetValue: "3a1ba0be23580f902885c6c8a6b035e228ed1ca74d77de5f9bb0e0c899f07cfe", | 287 | // targetValue: "3a1ba0be23580f902885c6c8a6b035e228ed1ca74d77de5f9bb0e0c899f07cfe", |
277 | // cost: | 288 | // cost: |
278 | // } | 289 | // } |
279 | } | 290 | } |
280 | 291 | ||
281 | return result; | 292 | return result; |
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'; |
393 | } else { | 420 | } else { |
394 | otpData['status'] = 'DISABLED'; | 421 | otpData['status'] = 'DISABLED'; |
395 | throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; | 422 | throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; |
396 | } | 423 | } |
397 | } else { | 424 | } else { |
398 | throw "The requested One Time Password was not active"; | 425 | throw "The requested One Time Password was not active"; |
399 | } | 426 | } |
400 | } else { | 427 | } else { |
401 | throw "The requested One Time Password has not been found" | 428 | throw "The requested One Time Password has not been found" |
402 | } | 429 | } |
403 | } catch (exception) { | 430 | } catch (exception) { |
404 | result = { | 431 | result = { |
405 | 'data': Clipperz.PM.Crypto.randomKey(), | 432 | 'data': Clipperz.PM.Crypto.randomKey(), |
406 | 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion | 433 | 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion |
407 | } | 434 | } |
408 | } | 435 | } |
409 | nextTollRequestType = 'CONNECT'; | 436 | nextTollRequestType = 'CONNECT'; |
410 | } else { | 437 | } else { |
411 | MochiKit.Logging.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); | 438 | MochiKit.Logging.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); |
412 | } | 439 | } |
413 | //console.log("<<< Proxy.Offline._handshake", result); | 440 | //console.log("<<< Proxy.Offline._handshake", result); |
414 | 441 | ||
415 | result = { | 442 | result = { |
416 | result: result, | 443 | result: result, |
417 | toll: this.getTollForRequestType(nextTollRequestType) | 444 | toll: this.getTollForRequestType(nextTollRequestType) |
418 | } | 445 | } |
419 | 446 | ||
420 | return MochiKit.Async.succeed(result); | 447 | return MochiKit.Async.succeed(result); |
421 | }, | 448 | }, |
422 | 449 | ||
423 | //------------------------------------------------------------------------- | 450 | //------------------------------------------------------------------------- |
424 | 451 | ||
425 | '_message': function(someParameters) { | 452 | '_message': function(someParameters) { |
426 | var result; | 453 | var result; |
427 | 454 | ||
428 | result = {}; | 455 | result = {}; |
429 | 456 | ||
430 | //===================================================================== | 457 | //===================================================================== |
431 | // | 458 | // |
432 | // R E A D - O N L Y M e t h o d s | 459 | // R E A D - O N L Y M e t h o d s |
433 | // | 460 | // |
434 | //===================================================================== | 461 | //===================================================================== |
435 | if (someParameters.message == 'getUserDetails') { | 462 | if (someParameters.message == 'getUserDetails') { |
436 | var recordsStats; | 463 | var recordsStats; |
437 | var recordReference; | 464 | var recordReference; |
438 | 465 | ||
439 | //try { | 466 | //try { |
440 | recordsStats = {}; | 467 | recordsStats = {}; |
441 | for (recordReference in this.userData()['records']) { | 468 | for (recordReference in this.userData()['records']) { |
442 | recordsStats[recordReference] = { | 469 | recordsStats[recordReference] = { |
443 | 'updateDate': this.userData()['records'][recordReference]['updateDate'] | 470 | 'updateDate': this.userData()['records'][recordReference]['updateDate'] |
444 | } | 471 | } |
445 | } | 472 | } |
446 | 473 | ||
447 | result['header'] = this.userDetails(); | 474 | result['header'] = this.userDetails(); |
448 | result['statistics'] = this.statistics(); | 475 | result['statistics'] = this.statistics(); |
449 | result['maxNumberOfRecords'] = this.userData()['maxNumberOfRecords']; | 476 | result['maxNumberOfRecords'] = this.userData()['maxNumberOfRecords']; |
450 | result['version'] = this.userData()['userDetailsVersion']; | 477 | result['version'] = this.userData()['userDetailsVersion']; |
451 | result['recordsStats'] = recordsStats; | 478 | result['recordsStats'] = recordsStats; |
452 | 479 | ||
453 | if (this.isReadOnly() == false) { | 480 | if (this.isReadOnly() == false) { |
454 | varlock; | 481 | varlock; |
455 | 482 | ||
456 | if (typeof(this.userData()['lock']) == 'undefined') { | 483 | if (typeof(this.userData()['lock']) == 'undefined') { |
457 | this.userData()['lock'] = "<<LOCK>>"; | 484 | this.userData()['lock'] = "<<LOCK>>"; |
458 | } | 485 | } |
459 | 486 | ||
460 | result['lock'] = this.userData()['lock']; | 487 | result['lock'] = this.userData()['lock']; |
461 | } | 488 | } |
462 | //} catch (exception) { | 489 | //} catch (exception) { |
463 | //console.log("*#*#*#*#*#*#*", exception); | 490 | //console.log("*#*#*#*#*#*#*", exception); |
464 | //throw exception; | 491 | //throw exception; |
465 | //} | 492 | //} |
466 | //===================================================================== | 493 | //===================================================================== |
467 | } else if (someParameters.message == 'getRecordDetail') { | 494 | } else if (someParameters.message == 'getRecordDetail') { |
468 | recordData = this.userData()['records'][someParameters['parameters']['reference']]; | 495 | recordData = this.userData()['records'][someParameters['parameters']['reference']]; |
469 | 496 | ||
470 | result['reference'] = someParameters['parameters']['reference']; | 497 | result['reference'] = someParameters['parameters']['reference']; |
471 | result['data'] = recordData['data']; | 498 | result['data'] = recordData['data']; |
472 | result['version'] = recordData['version']; | 499 | result['version'] = recordData['version']; |
473 | result['creationData'] = recordData['creationDate']; | 500 | result['creationData'] = recordData['creationDate']; |
474 | result['updateDate'] = recordData['updateDate']; | 501 | result['updateDate'] = recordData['updateDate']; |
475 | result['accessDate'] = recordData['accessDate']; | 502 | result['accessDate'] = recordData['accessDate']; |
476 | 503 | ||
477 | currentVersionData = recordData['versions'][recordData['currentVersion']]; | 504 | currentVersionData = recordData['versions'][recordData['currentVersion']]; |
478 | 505 | ||
479 | result['currentVersion'] = {}; | 506 | result['currentVersion'] = {}; |
480 | result['currentVersion']['reference'] = recordData['currentVersion']; | 507 | result['currentVersion']['reference'] = recordData['currentVersion']; |
481 | result['currentVersion']['version'] = currentVersionData['version']; | 508 | result['currentVersion']['version'] = currentVersionData['version']; |
482 | result['currentVersion']['header'] = currentVersionData['header']; | 509 | result['currentVersion']['header'] = currentVersionData['header']; |
483 | result['currentVersion']['data'] = currentVersionData['data']; | 510 | result['currentVersion']['data'] = currentVersionData['data']; |
484 | result['currentVersion']['creationData'] = currentVersionData['creationDate']; | 511 | result['currentVersion']['creationData'] = currentVersionData['creationDate']; |
485 | result['currentVersion']['updateDate'] = currentVersionData['updateDate']; | 512 | result['currentVersion']['updateDate'] = currentVersionData['updateDate']; |
486 | result['currentVersion']['accessDate'] = currentVersionData['accessDate']; | 513 | result['currentVersion']['accessDate'] = currentVersionData['accessDate']; |
487 | if (typeof(currentVersionData['previousVersion']) != 'undefined') { | 514 | if (typeof(currentVersionData['previousVersion']) != 'undefined') { |
488 | result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; | 515 | result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; |
489 | result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; | 516 | result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; |
490 | } | 517 | } |
491 | 518 | ||
492 | //===================================================================== | 519 | //===================================================================== |
493 | // | 520 | // |
494 | // R E A D - W R I T E M e t h o d s | 521 | // R E A D - W R I T E M e t h o d s |
495 | // | 522 | // |
496 | //===================================================================== | 523 | //===================================================================== |
497 | } else if (someParameters.message == 'upgradeUserCredentials') { | 524 | } else if (someParameters.message == 'upgradeUserCredentials') { |
498 | if (this.isReadOnly() == false) { | 525 | if (this.isReadOnly() == false) { |
499 | var parameters; | 526 | var parameters; |
500 | parameters = someParameters.parameters; | 527 | parameters = someParameters.parameters; |
501 | 528 | ||
502 | if (parameters['C'] == null) { | 529 | if (parameters['C'] == null) { |
503 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; | 530 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; |
504 | } else if (parameters['s'] == null) { | 531 | } else if (parameters['s'] == null) { |
505 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; | 532 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; |
506 | } else if (parameters['v'] == null) { | 533 | } else if (parameters['v'] == null) { |
507 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; | 534 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; |
508 | } else if (parameters['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) { | 535 | } else if (parameters['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) { |
509 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; | 536 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; |
510 | } else { | 537 | } else { |
511 | result = {result:"done", parameters:parameters}; | 538 | result = {result:"done", parameters:parameters}; |
512 | } | 539 | } |
513 | } else { | 540 | } else { |
514 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | 541 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; |
515 | } | 542 | } |
516 | //===================================================================== | 543 | //===================================================================== |
517 | /* } else if (someParameters.message == 'updateData') { | 544 | /* } else if (someParameters.message == 'updateData') { |
518 | if (this.isReadOnly() == false) { | 545 | if (this.isReadOnly() == false) { |
519 | var i, c; | 546 | var i, c; |
520 | 547 | ||
521 | //console.log("###==============================================================="); | 548 | //console.log("###==============================================================="); |
522 | //console.log("###>>>", Clipperz.Base.serializeJSON(someParameters)); | 549 | //console.log("###>>>", Clipperz.Base.serializeJSON(someParameters)); |
523 | //console.log("###--- userData", Clipperz.Base.serializeJSON(this.userData())); | 550 | //console.log("###--- userData", Clipperz.Base.serializeJSON(this.userData())); |
524 | if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { | 551 | if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { |
525 | throw "the lock attribute is not processed correctly" | 552 | throw "the lock attribute is not processed correctly" |
526 | } | 553 | } |
527 | 554 | ||
528 | this.userData()['userDetails'] = someParameters['parameters']['user']['header']; | 555 | this.userData()['userDetails'] = someParameters['parameters']['user']['header']; |
529 | this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; | 556 | this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; |
530 | this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; | 557 | this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; |
531 | 558 | ||
532 | c = someParameters['parameters']['records'].length; | 559 | c = someParameters['parameters']['records'].length; |
533 | for (i=0; i<c; i++) { | 560 | for (i=0; i<c; i++) { |
534 | var currentRecord; | 561 | var currentRecord; |
535 | var currentRecordData; | 562 | var currentRecordData; |
536 | 563 | ||
537 | currentRecordData = someParameters['parameters']['records'][i]; | 564 | currentRecordData = someParameters['parameters']['records'][i]; |
538 | currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; | 565 | currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; |
539 | 566 | ||
540 | if (currentRecord == null) { | 567 | if (currentRecord == null) { |
541 | } | 568 | } |
542 | 569 | ||
543 | currentRecord['data'] = currentRecordData['record']['data']; | 570 | currentRecord['data'] = currentRecordData['record']['data']; |
544 | currentRecord['version'] = currentRecordData['record']['version']; | 571 | currentRecord['version'] = currentRecordData['record']['version']; |
545 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; | 572 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; |
546 | 573 | ||
547 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { | 574 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { |
548 | 'data': currentRecordData['currentRecordVersion']['data'], | 575 | 'data': currentRecordData['currentRecordVersion']['data'], |
549 | 'version': currentRecordData['currentRecordVersion']['version'], | 576 | 'version': currentRecordData['currentRecordVersion']['version'], |
550 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], | 577 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], |
551 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'] | 578 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'] |
552 | } | 579 | } |
553 | } | 580 | } |
554 | 581 | ||
555 | this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); | 582 | this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); |
556 | result['lock'] = this.userData()['lock']; | 583 | result['lock'] = this.userData()['lock']; |
557 | result['result'] = 'done'; | 584 | result['result'] = 'done'; |
558 | //console.log("###<<< userData", Clipperz.Base.serializeJSON(this.userData())); | 585 | //console.log("###<<< userData", Clipperz.Base.serializeJSON(this.userData())); |
559 | } else { | 586 | } else { |
560 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | 587 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; |
561 | } | 588 | } |
562 | */ //===================================================================== | 589 | */ //===================================================================== |
563 | } else if (someParameters.message == 'saveChanges') { | 590 | } else if (someParameters.message == 'saveChanges') { |
564 | if (this.isReadOnly() == false) { | 591 | if (this.isReadOnly() == false) { |
565 | var i, c; | 592 | var i, c; |
566 | 593 | ||
567 | //console.log("###==============================================================="); | 594 | //console.log("###==============================================================="); |
568 | //console.log("###>>>", someParameters); | 595 | //console.log("###>>>", someParameters); |
569 | //console.log("###>>>", Clipperz.Base.serializeJSON(someParameters)); | 596 | //console.log("###>>>", Clipperz.Base.serializeJSON(someParameters)); |
570 | //console.log("###--- userData", Clipperz.Base.serializeJSON(this.userData())); | 597 | //console.log("###--- userData", Clipperz.Base.serializeJSON(this.userData())); |
571 | //console.log("###==============================================================="); | 598 | //console.log("###==============================================================="); |
572 | //console.log("--- userData.lock ", this.userData()['lock']); | 599 | //console.log("--- userData.lock ", this.userData()['lock']); |
573 | //console.log("--- parameters.lock", someParameters['parameters']['user']['lock']); | 600 | //console.log("--- parameters.lock", someParameters['parameters']['user']['lock']); |
574 | if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { | 601 | if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { |
575 | throw "the lock attribute is not processed correctly" | 602 | throw "the lock attribute is not processed correctly" |
576 | } | 603 | } |
577 | 604 | ||
578 | this.userData()['userDetails'] = someParameters['parameters']['user']['header']; | 605 | this.userData()['userDetails'] = someParameters['parameters']['user']['header']; |
579 | this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; | 606 | this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; |
580 | this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; | 607 | this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; |
581 | 608 | ||
582 | c = someParameters['parameters']['records']['updated'].length; | 609 | c = someParameters['parameters']['records']['updated'].length; |
583 | for (i=0; i<c; i++) { | 610 | for (i=0; i<c; i++) { |
584 | var currentRecord; | 611 | var currentRecord; |
585 | var currentRecordData; | 612 | var currentRecordData; |
586 | 613 | ||
587 | currentRecordData = someParameters['parameters']['records']['updated'][i]; | 614 | currentRecordData = someParameters['parameters']['records']['updated'][i]; |
588 | currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; | 615 | currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; |
589 | 616 | ||
590 | if ( | 617 | if ( |
591 | (typeof(this.userData()['records'][currentRecordData['record']['reference']]) == 'undefined') | 618 | (typeof(this.userData()['records'][currentRecordData['record']['reference']]) == 'undefined') |
592 | && | 619 | && |
593 | (typeof(currentRecordData['currentRecordVersion']) == 'undefined') | 620 | (typeof(currentRecordData['currentRecordVersion']) == 'undefined') |
594 | ) { | 621 | ) { |
595 | //console.log("######## SHIT HAPPENS"); | 622 | //console.log("######## SHIT HAPPENS"); |
596 | throw "Record added without a recordVersion"; | 623 | throw "Record added without a recordVersion"; |
597 | } | 624 | } |
598 | 625 | ||
599 | if (currentRecord == null) { | 626 | if (currentRecord == null) { |
600 | currentRecord = {}; | 627 | currentRecord = {}; |
601 | currentRecord['versions'] = {}; | 628 | currentRecord['versions'] = {}; |
602 | currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | 629 | currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); |
603 | currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | 630 | currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); |
604 | 631 | ||
605 | this.userData()['records'][currentRecordData['record']['reference']] = currentRecord; | 632 | this.userData()['records'][currentRecordData['record']['reference']] = currentRecord; |
606 | } | 633 | } |
607 | 634 | ||
608 | currentRecord['data'] = currentRecordData['record']['data']; | 635 | currentRecord['data'] = currentRecordData['record']['data']; |
609 | currentRecord['version']= currentRecordData['record']['version']; | 636 | currentRecord['version']= currentRecordData['record']['version']; |
610 | currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | 637 | currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); |
611 | 638 | ||
612 | if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') { | 639 | if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') { |
613 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; | 640 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; |
614 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { | 641 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { |
615 | 'data': currentRecordData['currentRecordVersion']['data'], | 642 | 'data': currentRecordData['currentRecordVersion']['data'], |
616 | 'version': currentRecordData['currentRecordVersion']['version'], | 643 | 'version': currentRecordData['currentRecordVersion']['version'], |
617 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], | 644 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], |
618 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'], | 645 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'], |
619 | 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), | 646 | 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), |
620 | 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), | 647 | 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), |
621 | 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()) | 648 | 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()) |
622 | } | 649 | } |
623 | } | 650 | } |
624 | } | 651 | } |
625 | 652 | ||
626 | c = someParameters['parameters']['records']['deleted'].length; | 653 | c = someParameters['parameters']['records']['deleted'].length; |
627 | for (i=0; i<c; i++) { | 654 | for (i=0; i<c; i++) { |
628 | var currentRecordReference; | 655 | var currentRecordReference; |
629 | 656 | ||
630 | currentRecordReference = someParameters['parameters']['records']['deleted'][i]; | 657 | currentRecordReference = someParameters['parameters']['records']['deleted'][i]; |
631 | //console.log("DELETING records", currentRecordReference); | 658 | //console.log("DELETING records", currentRecordReference); |
632 | delete this.userData()['records'][currentRecordReference]; | 659 | delete this.userData()['records'][currentRecordReference]; |
633 | } | 660 | } |
634 | 661 | ||
635 | this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); | 662 | this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); |
636 | result['lock'] = this.userData()['lock']; | 663 | result['lock'] = this.userData()['lock']; |
637 | result['result'] = 'done'; | 664 | result['result'] = 'done'; |
638 | //console.log("###<<< userData", Clipperz.Base.serializeJSON(this.userData())); | 665 | //console.log("###<<< userData", Clipperz.Base.serializeJSON(this.userData())); |
639 | } else { | 666 | } else { |
640 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | 667 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; |
641 | } | 668 | } |
642 | 669 | ||
643 | //===================================================================== | 670 | //===================================================================== |
644 | // | 671 | // |
645 | // U N H A N D L E D M e t h o d | 672 | // U N H A N D L E D M e t h o d |
646 | // | 673 | // |
647 | //===================================================================== | 674 | //===================================================================== |
648 | } else { | 675 | } else { |
649 | MochiKit.Logging.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message); | 676 | MochiKit.Logging.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message); |
650 | } | 677 | } |
651 | 678 | ||
652 | result = { | 679 | result = { |
653 | result: result, | 680 | result: result, |
654 | toll: this.getTollForRequestType('MESSAGE') | 681 | toll: this.getTollForRequestType('MESSAGE') |
655 | } | 682 | } |
656 | 683 | ||
657 | return MochiKit.Async.succeed(result); | 684 | return MochiKit.Async.succeed(result); |
658 | }, | 685 | }, |
659 | 686 | ||
660 | //------------------------------------------------------------------------- | 687 | //------------------------------------------------------------------------- |
661 | 688 | ||
662 | '_logout': function(someParameters) { | 689 | '_logout': function(someParameters) { |
663 | return MochiKit.Async.succeed({result: 'done'}); | 690 | return MochiKit.Async.succeed({result: 'done'}); |
664 | }, | 691 | }, |
665 | 692 | ||
666 | //========================================================================= | 693 | //========================================================================= |
667 | //######################################################################### | 694 | //######################################################################### |
668 | 695 | ||
669 | 'isTestData': function() { | 696 | 'isTestData': function() { |
670 | return (typeof(this.userData()['__masterkey_test_value__']) != 'undefined'); | 697 | return (typeof(this.userData()['__masterkey_test_value__']) != 'undefined'); |
671 | }, | 698 | }, |
672 | 699 | ||
673 | 'userDetails': function() { | 700 | 'userDetails': function() { |
674 | var result; | 701 | var result; |
675 | 702 | ||
676 | if (this.isTestData()) { | 703 | if (this.isTestData()) { |
677 | var serializedHeader; | 704 | var serializedHeader; |
678 | var version; | 705 | var version; |
679 | 706 | ||
680 | //MochiKit.Logging.logDebug("### test data"); | 707 | //MochiKit.Logging.logDebug("### test data"); |
681 | version = this.userData()['userDetailsVersion']; | 708 | version = this.userData()['userDetailsVersion']; |
682 | serializedHeader = Clipperz.Base.serializeJSON(this.userData()['userDetails']); | 709 | serializedHeader = Clipperz.Base.serializeJSON(this.userData()['userDetails']); |
683 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(this.userData()['__masterkey_test_value__'], serializedHeader); | 710 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(this.userData()['__masterkey_test_value__'], serializedHeader); |
684 | } else { | 711 | } else { |
685 | //MochiKit.Logging.logDebug("### NOT test data"); | 712 | //MochiKit.Logging.logDebug("### NOT test data"); |
686 | result = this.userData()['userDetails']; | 713 | result = this.userData()['userDetails']; |
687 | } | 714 | } |
688 | 715 | ||
689 | return result; | 716 | return result; |
690 | }, | 717 | }, |
691 | 718 | ||
692 | 'statistics': function() { | 719 | 'statistics': function() { |
693 | var result; | 720 | var result; |
694 | 721 | ||
695 | if (this.userData()['statistics'] != null) { | 722 | if (this.userData()['statistics'] != null) { |
696 | if (this.isTestData()) { | 723 | if (this.isTestData()) { |
697 | var serializedStatistics; | 724 | var serializedStatistics; |
698 | var version; | 725 | var version; |
699 | 726 | ||
700 | version = this.userData()['userDetailsVersion']; | 727 | version = this.userData()['userDetailsVersion']; |
701 | serializedStatistics = Clipperz.Base.serializeJSON(this.userData()['statistics']); | 728 | serializedStatistics = Clipperz.Base.serializeJSON(this.userData()['statistics']); |
702 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(this.userData()['__masterkey_test_value__'], serializedStatistics); | 729 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(this.userData()['__masterkey_test_value__'], serializedStatistics); |
703 | } else { | 730 | } else { |
704 | result = this.userData()['statistics']; | 731 | result = this.userData()['statistics']; |
705 | } | 732 | } |
706 | } else { | 733 | } else { |
707 | result = null; | 734 | result = null; |
708 | } | 735 | } |
709 | 736 | ||
710 | return result; | 737 | return result; |
711 | }, | 738 | }, |
712 | 739 | ||
713 | /* | 740 | /* |
714 | 'userSerializedEncryptedData': function(someData) { | 741 | 'userSerializedEncryptedData': function(someData) { |
715 | var deferredResult; | 742 | var deferredResult; |
716 | var deferredContext; | 743 | var deferredContext; |
717 | 744 | ||
718 | deferredContext = { 'data': someData }; | 745 | deferredContext = { 'data': someData }; |
719 | 746 | ||
720 | deferredResult = new Clipperz.Async.Deferred('Proxy.Test.serializeUserEncryptedData', {trace:false}); | 747 | deferredResult = new Clipperz.Async.Deferred('Proxy.Test.serializeUserEncryptedData', {trace:false}); |
721 | deferredResult.addCallback(MochiKit.Base.bind(function(aDeferredContext) { | 748 | deferredResult.addCallback(MochiKit.Base.bind(function(aDeferredContext) { |
722 | aDeferredContext['user'] = this.createUserUsingConfigurationData(aDeferredContext['data']); | 749 | aDeferredContext['user'] = this.createUserUsingConfigurationData(aDeferredContext['data']); |
723 | return aDeferredContext; | 750 | return aDeferredContext; |
724 | }, this)); | 751 | }, this)); |
725 | deferredResult.addCallback(function(aDeferredContext) { | 752 | deferredResult.addCallback(function(aDeferredContext) { |
726 | // return aDeferredContext['user'].encryptedDataUsingVersion(aDeferredContext['data']['version']); | 753 | // return aDeferredContext['user'].encryptedDataUsingVersion(aDeferredContext['data']['version']); |
727 | return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); | 754 | return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); |
728 | }); | 755 | }); |
729 | deferredResult.addCallback(function(aUserEncryptedData) { | 756 | deferredResult.addCallback(function(aUserEncryptedData) { |
730 | deferredContext['encryptedData'] = aUserEncryptedData; | 757 | deferredContext['encryptedData'] = aUserEncryptedData; |
731 | return deferredContext; | 758 | return deferredContext; |
732 | }); | 759 | }); |
733 | deferredResult.addCallback(function(aDeferredContext) { | 760 | deferredResult.addCallback(function(aDeferredContext) { |
734 | var connection; | 761 | var connection; |
735 | 762 | ||
736 | connection = new Clipperz.PM.Connection.communicationProtocol.versions[aDeferredContext['data']['connectionVersion']]() | 763 | connection = new Clipperz.PM.Connection.communicationProtocol.versions[aDeferredContext['data']['connectionVersion']]() |
737 | aDeferredContext['credentials'] = connection.serverSideUserCredentials(aDeferredContext['user'].username(),aDeferredContext['user'].passphrase()); | 764 | aDeferredContext['credentials'] = connection.serverSideUserCredentials(aDeferredContext['user'].username(),aDeferredContext['user'].passphrase()); |
738 | 765 | ||
739 | return aDeferredContext; | 766 | return aDeferredContext; |
740 | }); | 767 | }); |
741 | 768 | ||
742 | // deferredResult.addCallback(function(aDeferredContext) { | 769 | // deferredResult.addCallback(function(aDeferredContext) { |
743 | //console.log("#-#-#-#-#", aDeferredContext); | 770 | //console.log("#-#-#-#-#", aDeferredContext); |
744 | // return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); | 771 | // return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); |
745 | // }, deferredContext); | 772 | // }, deferredContext); |
746 | // deferredResult.addCallback(function(aUserSerializedData) { | 773 | // deferredResult.addCallback(function(aUserSerializedData) { |
747 | //console.log("USER SERIALIZED DATA", aUserSerializedData); | 774 | //console.log("USER SERIALIZED DATA", aUserSerializedData); |
748 | // }); | 775 | // }); |
749 | // | 776 | // |
750 | // deferredResult.addCallback(MochiKit.Async.succeed, deferredContext); | 777 | // deferredResult.addCallback(MochiKit.Async.succeed, deferredContext); |
751 | deferredResult.callback(deferredContext); | 778 | deferredResult.callback(deferredContext); |
752 | 779 | ||
753 | return deferredResult; | 780 | return deferredResult; |
754 | }, | 781 | }, |
755 | 782 | ||
756 | 'createUserUsingConfigurationData': function(someData) { | 783 | 'createUserUsingConfigurationData': function(someData) { |
757 | var result; | 784 | var result; |
758 | var user; | 785 | var user; |
759 | var recordLabel; | 786 | var recordLabel; |
760 | 787 | ||
761 | user = new Clipperz.PM.DataModel.User(); | 788 | user = new Clipperz.PM.DataModel.User(); |
762 | user.initForTests(); | 789 | user.initForTests(); |
763 | user.setUsername(someData['username']); | 790 | user.setUsername(someData['username']); |
764 | user.setPassphrase(someData['passphrase']); | 791 | user.setPassphrase(someData['passphrase']); |
765 | 792 | ||
766 | for (recordLabel in someData['records']) { | 793 | for (recordLabel in someData['records']) { |
767 | var recordData; | 794 | var recordData; |
768 | var record; | 795 | var record; |
769 | var i, c; | 796 | var i, c; |
770 | 797 | ||
771 | recordData = someData['records'][recordLabel]; | 798 | recordData = someData['records'][recordLabel]; |
772 | record = new Clipperz.PM.DataModel.Record({user:user, label:recordLabel}); | 799 | record = new Clipperz.PM.DataModel.Record({user:user, label:recordLabel}); |
773 | record.setNotes(recordData['notes']); | 800 | record.setNotes(recordData['notes']); |
774 | 801 | ||
775 | c = recordData['fields'].length; | 802 | c = recordData['fields'].length; |
776 | for (i=0; i<c; i++) { | 803 | for (i=0; i<c; i++) { |
777 | var recordField; | 804 | var recordField; |
778 | 805 | ||
779 | recordField = new Clipperz.PM.DataModel.RecordField(); | 806 | recordField = new Clipperz.PM.DataModel.RecordField(); |
780 | recordField.setLabel(recordData['fields'][i]['name']); | 807 | recordField.setLabel(recordData['fields'][i]['name']); |
781 | recordField.setValue(recordData['fields'][i]['value']); | 808 | recordField.setValue(recordData['fields'][i]['value']); |
782 | recordField.setType(recordData['fields'][i]['type']); | 809 | recordField.setType(recordData['fields'][i]['type']); |
783 | record.addField(recordField); | 810 | record.addField(recordField); |
784 | } | 811 | } |
785 | user.addRecord(record, true); | 812 | user.addRecord(record, true); |
786 | } | 813 | } |
787 | 814 | ||
788 | result = user; | 815 | result = user; |
789 | 816 | ||
790 | return result; | 817 | return result; |
791 | }, | 818 | }, |
792 | */ | 819 | */ |
793 | //========================================================================= | 820 | //========================================================================= |
794 | __syntaxFix__: "syntax fix" | 821 | __syntaxFix__: "syntax fix" |
795 | }); | 822 | }); |
796 | 823 | ||
797 | Clipperz.PM.Proxy.Offline.DataStore['exception'] = { | 824 | Clipperz.PM.Proxy.Offline.DataStore['exception'] = { |
798 | 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly") | 825 | 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly") |
799 | }; \ No newline at end of file | 826 | }; \ No newline at end of file |
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 | |||
@@ -1,841 +1,805 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | "use strict"; | ||
25 | |||
24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { | 26 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { |
25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; | 27 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; |
26 | } | 28 | } |
27 | 29 | ||
28 | try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) { | 30 | try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) { |
29 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!"; | 31 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!"; |
30 | } | 32 | } |
31 | 33 | ||
32 | try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) { | 34 | try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) { |
33 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!"; | 35 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!"; |
34 | } | 36 | } |
35 | 37 | ||
36 | if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; } | 38 | if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; } |
37 | 39 | ||
38 | //############################################################################# | 40 | //############################################################################# |
39 | 41 | ||
40 | Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) { | 42 | Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) { |
41 | args = args || {}; | 43 | args = args || {}; |
42 | //MochiKit.Base.bindMethods(this); | 44 | //MochiKit.Base.bindMethods(this); |
43 | 45 | ||
44 | this._stack = new Clipperz.ByteArray(); | 46 | this._stack = new Clipperz.ByteArray(); |
45 | this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256; | 47 | this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256; |
46 | return this; | 48 | return this; |
47 | } | 49 | } |
48 | 50 | ||
49 | Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, { | 51 | Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, { |
50 | 52 | ||
51 | 'toString': function() { | 53 | 'toString': function() { |
52 | return "Clipperz.Crypto.PRNG.EntropyAccumulator"; | 54 | return "Clipperz.Crypto.PRNG.EntropyAccumulator"; |
53 | }, | 55 | }, |
54 | 56 | ||
55 | //------------------------------------------------------------------------- | 57 | //------------------------------------------------------------------------- |
56 | 58 | ||
57 | 'stack': function() { | 59 | 'stack': function() { |
58 | return this._stack; | 60 | return this._stack; |
59 | }, | 61 | }, |
60 | 62 | ||
61 | 'setStack': function(aValue) { | 63 | 'setStack': function(aValue) { |
62 | this._stack = aValue; | 64 | this._stack = aValue; |
63 | }, | 65 | }, |
64 | 66 | ||
65 | 'resetStack': function() { | 67 | 'resetStack': function() { |
66 | this.stack().reset(); | 68 | this.stack().reset(); |
67 | }, | 69 | }, |
68 | 70 | ||
69 | 'maxStackLengthBeforeHashing': function() { | 71 | 'maxStackLengthBeforeHashing': function() { |
70 | return this._maxStackLengthBeforeHashing; | 72 | return this._maxStackLengthBeforeHashing; |
71 | }, | 73 | }, |
72 | 74 | ||
73 | //------------------------------------------------------------------------- | 75 | //------------------------------------------------------------------------- |
74 | 76 | ||
75 | 'addRandomByte': function(aValue) { | 77 | 'addRandomByte': function(aValue) { |
76 | this.stack().appendByte(aValue); | 78 | this.stack().appendByte(aValue); |
77 | 79 | ||
78 | if (this.stack().length() > this.maxStackLengthBeforeHashing()) { | 80 | if (this.stack().length() > this.maxStackLengthBeforeHashing()) { |
79 | this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack())); | 81 | this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack())); |
80 | } | 82 | } |
81 | }, | 83 | }, |
82 | 84 | ||
83 | //------------------------------------------------------------------------- | 85 | //------------------------------------------------------------------------- |
84 | __syntaxFix__: "syntax fix" | 86 | __syntaxFix__: "syntax fix" |
85 | }); | 87 | }); |
86 | 88 | ||
87 | //############################################################################# | 89 | //############################################################################# |
88 | 90 | ||
89 | Clipperz.Crypto.PRNG.RandomnessSource = function(args) { | 91 | Clipperz.Crypto.PRNG.RandomnessSource = function(args) { |
90 | args = args || {}; | 92 | args = args || {}; |
91 | MochiKit.Base.bindMethods(this); | 93 | MochiKit.Base.bindMethods(this); |
92 | 94 | ||
93 | this._generator = args.generator || null; | 95 | this._generator = args.generator || null; |
94 | this._sourceId = args.sourceId || null; | 96 | this._sourceId = args.sourceId || null; |
95 | this._boostMode = args.boostMode || false; | 97 | this._boostMode = args.boostMode || false; |
96 | 98 | ||
97 | this._nextPoolIndex = 0; | 99 | this._nextPoolIndex = 0; |
98 | 100 | ||
99 | return this; | 101 | return this; |
100 | } | 102 | } |
101 | 103 | ||
102 | Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, { | 104 | Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, { |
103 | 105 | ||
104 | 'generator': function() { | 106 | 'generator': function() { |
105 | return this._generator; | 107 | return this._generator; |
106 | }, | 108 | }, |
107 | 109 | ||
108 | 'setGenerator': function(aValue) { | 110 | 'setGenerator': function(aValue) { |
109 | this._generator = aValue; | 111 | this._generator = aValue; |
110 | }, | 112 | }, |
111 | 113 | ||
112 | //------------------------------------------------------------------------- | 114 | //------------------------------------------------------------------------- |
113 | 115 | ||
114 | 'boostMode': function() { | 116 | 'boostMode': function() { |
115 | return this._boostMode; | 117 | return this._boostMode; |
116 | }, | 118 | }, |
117 | 119 | ||
118 | 'setBoostMode': function(aValue) { | 120 | 'setBoostMode': function(aValue) { |
119 | this._boostMode = aValue; | 121 | this._boostMode = aValue; |
120 | }, | 122 | }, |
121 | 123 | ||
122 | //------------------------------------------------------------------------- | 124 | //------------------------------------------------------------------------- |
123 | 125 | ||
124 | 'sourceId': function() { | 126 | 'sourceId': function() { |
125 | return this._sourceId; | 127 | return this._sourceId; |
126 | }, | 128 | }, |
127 | 129 | ||
128 | 'setSourceId': function(aValue) { | 130 | 'setSourceId': function(aValue) { |
129 | this._sourceId = aValue; | 131 | this._sourceId = aValue; |
130 | }, | 132 | }, |
131 | 133 | ||
132 | //------------------------------------------------------------------------- | 134 | //------------------------------------------------------------------------- |
133 | 135 | ||
134 | 'nextPoolIndex': function() { | 136 | 'nextPoolIndex': function() { |
135 | return this._nextPoolIndex; | 137 | return this._nextPoolIndex; |
136 | }, | 138 | }, |
137 | 139 | ||
138 | 'incrementNextPoolIndex': function() { | 140 | 'incrementNextPoolIndex': function() { |
139 | this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators()); | 141 | this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators()); |
140 | }, | 142 | }, |
141 | 143 | ||
142 | //------------------------------------------------------------------------- | 144 | //------------------------------------------------------------------------- |
143 | 145 | ||
144 | 'updateGeneratorWithValue': function(aRandomValue) { | 146 | 'updateGeneratorWithValue': function(aRandomValue) { |
145 | if (this.generator() != null) { | 147 | if (this.generator() != null) { |
146 | this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue); | 148 | this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue); |
147 | this.incrementNextPoolIndex(); | 149 | this.incrementNextPoolIndex(); |
148 | } | 150 | } |
149 | }, | 151 | }, |
150 | 152 | ||
151 | //------------------------------------------------------------------------- | 153 | //------------------------------------------------------------------------- |
152 | __syntaxFix__: "syntax fix" | 154 | __syntaxFix__: "syntax fix" |
153 | }); | 155 | }); |
154 | 156 | ||
155 | //############################################################################# | 157 | //############################################################################# |
156 | 158 | ||
157 | Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { | 159 | Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { |
158 | args = args || {}; | 160 | args = args || {}; |
159 | //MochiKit.Base.bindMethods(this); | 161 | //MochiKit.Base.bindMethods(this); |
160 | 162 | ||
161 | this._intervalTime = args.intervalTime || 1000; | 163 | this._intervalTime = args.intervalTime || 1000; |
162 | 164 | ||
163 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); | 165 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); |
164 | 166 | ||
165 | this.collectEntropy(); | 167 | this.collectEntropy(); |
166 | return this; | 168 | return this; |
167 | } | 169 | } |
168 | 170 | ||
169 | Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { | 171 | Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { |
170 | 172 | ||
171 | 'intervalTime': function() { | 173 | 'intervalTime': function() { |
172 | return this._intervalTime; | 174 | return this._intervalTime; |
173 | }, | 175 | }, |
174 | 176 | ||
175 | //------------------------------------------------------------------------- | 177 | //------------------------------------------------------------------------- |
176 | 178 | ||
177 | 'collectEntropy': function() { | 179 | 'collectEntropy': function() { |
178 | varnow; | 180 | varnow; |
179 | varentropyByte; | 181 | varentropyByte; |
180 | var intervalTime; | 182 | var intervalTime; |
181 | now = new Date(); | 183 | now = new Date(); |
182 | entropyByte = (now.getTime() & 0xff); | 184 | entropyByte = (now.getTime() & 0xff); |
183 | 185 | ||
184 | intervalTime = this.intervalTime(); | 186 | intervalTime = this.intervalTime(); |
185 | if (this.boostMode() == true) { | 187 | if (this.boostMode() == true) { |
186 | intervalTime = intervalTime / 9; | 188 | intervalTime = intervalTime / 9; |
187 | } | 189 | } |
188 | 190 | ||
189 | this.updateGeneratorWithValue(entropyByte); | 191 | this.updateGeneratorWithValue(entropyByte); |
190 | setTimeout(this.collectEntropy, intervalTime); | 192 | setTimeout(this.collectEntropy, intervalTime); |
191 | }, | 193 | }, |
192 | 194 | ||
193 | //------------------------------------------------------------------------- | 195 | //------------------------------------------------------------------------- |
194 | 196 | ||
195 | 'numberOfRandomBits': function() { | 197 | 'numberOfRandomBits': function() { |
196 | return 5; | 198 | return 5; |
197 | }, | 199 | }, |
198 | 200 | ||
199 | //------------------------------------------------------------------------- | 201 | //------------------------------------------------------------------------- |
200 | |||
201 | 'pollingFrequency': function() { | ||
202 | return 10; | ||
203 | }, | ||
204 | |||
205 | //------------------------------------------------------------------------- | ||
206 | __syntaxFix__: "syntax fix" | 202 | __syntaxFix__: "syntax fix" |
207 | }); | 203 | }); |
208 | 204 | ||
209 | //***************************************************************************** | 205 | //***************************************************************************** |
210 | 206 | ||
211 | Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { | 207 | Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { |
212 | args = args || {}; | 208 | args = args || {}; |
213 | 209 | ||
214 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); | 210 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); |
215 | 211 | ||
216 | this._numberOfBitsToCollectAtEachEvent = 4; | 212 | this._numberOfBitsToCollectAtEachEvent = 4; |
217 | this._randomBitsCollector = 0; | 213 | this._randomBitsCollector = 0; |
218 | this._numberOfRandomBitsCollected = 0; | 214 | this._numberOfRandomBitsCollected = 0; |
219 | 215 | ||
220 | MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); | 216 | MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); |
221 | 217 | ||
222 | return this; | 218 | return this; |
223 | } | 219 | } |
224 | 220 | ||
225 | Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { | 221 | Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { |
226 | 222 | ||
227 | //------------------------------------------------------------------------- | 223 | //------------------------------------------------------------------------- |
228 | 224 | ||
229 | 'numberOfBitsToCollectAtEachEvent': function() { | 225 | 'numberOfBitsToCollectAtEachEvent': function() { |
230 | return this._numberOfBitsToCollectAtEachEvent; | 226 | return this._numberOfBitsToCollectAtEachEvent; |
231 | }, | 227 | }, |
232 | 228 | ||
233 | //------------------------------------------------------------------------- | 229 | //------------------------------------------------------------------------- |
234 | 230 | ||
235 | 'randomBitsCollector': function() { | 231 | 'randomBitsCollector': function() { |
236 | return this._randomBitsCollector; | 232 | return this._randomBitsCollector; |
237 | }, | 233 | }, |
238 | 234 | ||
239 | 'setRandomBitsCollector': function(aValue) { | 235 | 'setRandomBitsCollector': function(aValue) { |
240 | this._randomBitsCollector = aValue; | 236 | this._randomBitsCollector = aValue; |
241 | }, | 237 | }, |
242 | 238 | ||
243 | 'appendRandomBitsToRandomBitsCollector': function(aValue) { | 239 | 'appendRandomBitsToRandomBitsCollector': function(aValue) { |
244 | var collectedBits; | 240 | var collectedBits; |
245 | var numberOfRandomBitsCollected; | 241 | var numberOfRandomBitsCollected; |
246 | 242 | ||
247 | numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); | 243 | numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); |
248 | collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); | 244 | collectedBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); |
249 | this.setRandomBitsCollector(collectetBits); | 245 | this.setRandomBitsCollector(collectedBits); |
250 | numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); | 246 | numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); |
251 | 247 | ||
252 | if (numberOfRandomBitsCollected == 8) { | 248 | if (numberOfRandomBitsCollected == 8) { |
253 | this.updateGeneratorWithValue(collectetBits); | 249 | this.updateGeneratorWithValue(collectedBits); |
254 | numberOfRandomBitsCollected = 0; | 250 | numberOfRandomBitsCollected = 0; |
255 | this.setRandomBitsCollector(0); | 251 | this.setRandomBitsCollector(0); |
256 | } | 252 | } |
257 | 253 | ||
258 | this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) | 254 | this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) |
259 | }, | 255 | }, |
260 | 256 | ||
261 | //------------------------------------------------------------------------- | 257 | //------------------------------------------------------------------------- |
262 | 258 | ||
263 | 'numberOfRandomBitsCollected': function() { | 259 | 'numberOfRandomBitsCollected': function() { |
264 | return this._numberOfRandomBitsCollected; | 260 | return this._numberOfRandomBitsCollected; |
265 | }, | 261 | }, |
266 | 262 | ||
267 | 'setNumberOfRandomBitsCollected': function(aValue) { | 263 | 'setNumberOfRandomBitsCollected': function(aValue) { |
268 | this._numberOfRandomBitsCollected = aValue; | 264 | this._numberOfRandomBitsCollected = aValue; |
269 | }, | 265 | }, |
270 | 266 | ||
271 | //------------------------------------------------------------------------- | 267 | //------------------------------------------------------------------------- |
272 | 268 | ||
273 | 'collectEntropy': function(anEvent) { | 269 | 'collectEntropy': function(anEvent) { |
274 | var mouseLocation; | 270 | var mouseLocation; |
275 | var randomBit; | 271 | var randomBit; |
276 | var mask; | 272 | var mask; |
277 | 273 | ||
278 | mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); | 274 | mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); |
279 | 275 | ||
280 | mouseLocation = anEvent.mouse().client; | 276 | mouseLocation = anEvent.mouse().client; |
281 | randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); | 277 | randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); |
282 | this.appendRandomBitsToRandomBitsCollector(randomBit) | 278 | this.appendRandomBitsToRandomBitsCollector(randomBit) |
283 | }, | 279 | }, |
284 | 280 | ||
285 | //------------------------------------------------------------------------- | 281 | //------------------------------------------------------------------------- |
286 | 282 | ||
287 | 'numberOfRandomBits': function() { | 283 | 'numberOfRandomBits': function() { |
288 | return 1; | 284 | return 1; |
289 | }, | 285 | }, |
290 | 286 | ||
291 | //------------------------------------------------------------------------- | 287 | //------------------------------------------------------------------------- |
292 | |||
293 | 'pollingFrequency': function() { | ||
294 | return 10; | ||
295 | }, | ||
296 | |||
297 | //------------------------------------------------------------------------- | ||
298 | __syntaxFix__: "syntax fix" | 288 | __syntaxFix__: "syntax fix" |
299 | }); | 289 | }); |
300 | 290 | ||
301 | //***************************************************************************** | 291 | //***************************************************************************** |
302 | 292 | ||
303 | Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) { | 293 | Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) { |
304 | args = args || {}; | 294 | args = args || {}; |
305 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); | ||
306 | 295 | ||
307 | this._randomBitsCollector = 0; | 296 | this._intervalTime = args.intervalTime || 1000; |
308 | this._numberOfRandomBitsCollected = 0; | 297 | this._browserCrypto = args.browserCrypto; |
309 | 298 | ||
310 | MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy'); | 299 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); |
311 | 300 | ||
301 | this.collectEntropy(); | ||
312 | return this; | 302 | return this; |
313 | } | 303 | } |
314 | 304 | ||
315 | Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { | 305 | Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { |
316 | 306 | ||
317 | //------------------------------------------------------------------------- | 307 | 'intervalTime': function() { |
318 | 308 | return this._intervalTime; | |
319 | 'randomBitsCollector': function() { | ||
320 | return this._randomBitsCollector; | ||
321 | }, | ||
322 | |||
323 | 'setRandomBitsCollector': function(aValue) { | ||
324 | this._randomBitsCollector = aValue; | ||
325 | }, | 309 | }, |
326 | 310 | ||
327 | 'appendRandomBitToRandomBitsCollector': function(aValue) { | 311 | 'browserCrypto': function () { |
328 | var collectedBits; | 312 | return this._browserCrypto; |
329 | var numberOfRandomBitsCollected; | ||
330 | |||
331 | numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); | ||
332 | collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); | ||
333 | this.setRandomBitsCollector(collectetBits); | ||
334 | numberOfRandomBitsCollected ++; | ||
335 | |||
336 | if (numberOfRandomBitsCollected == 8) { | ||
337 | this.updateGeneratorWithValue(collectetBits); | ||
338 | numberOfRandomBitsCollected = 0; | ||
339 | this.setRandomBitsCollector(0); | ||
340 | } | ||
341 | |||
342 | this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) | ||
343 | }, | 313 | }, |
344 | 314 | ||
345 | //------------------------------------------------------------------------- | 315 | //------------------------------------------------------------------------- |
346 | 316 | ||
347 | 'numberOfRandomBitsCollected': function() { | 317 | 'collectEntropy': function() { |
348 | return this._numberOfRandomBitsCollected; | 318 | varbytesToCollect; |
349 | }, | ||
350 | |||
351 | 'setNumberOfRandomBitsCollected': function(aValue) { | ||
352 | this._numberOfRandomBitsCollected = aValue; | ||
353 | }, | ||
354 | 319 | ||
355 | //------------------------------------------------------------------------- | 320 | if (this.boostMode() == true) { |
321 | bytesToCollect = 64; | ||
322 | } else { | ||
323 | bytesToCollect = 8; | ||
324 | } | ||
356 | 325 | ||
357 | 'collectEntropy': function(anEvent) { | 326 | var randomValuesArray = new Uint8Array(bytesToCollect); |
358 | /* | 327 | this.browserCrypto().getRandomValues(randomValuesArray); |
359 | var mouseLocation; | 328 | for (var i = 0; i < randomValuesArray.length; i++) { |
360 | var randomBit; | 329 | this.updateGeneratorWithValue(randomValuesArray[i]); |
361 | 330 | } | |
362 | mouseLocation = anEvent.mouse().client; | ||
363 | |||
364 | randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1); | ||
365 | this.appendRandomBitToRandomBitsCollector(randomBit); | ||
366 | */ | ||
367 | }, | ||
368 | |||
369 | //------------------------------------------------------------------------- | ||
370 | 331 | ||
371 | 'numberOfRandomBits': function() { | 332 | setTimeout(this.collectEntropy, this.intervalTime()); |
372 | return 1; | ||
373 | }, | 333 | }, |
374 | 334 | ||
375 | //------------------------------------------------------------------------- | 335 | //------------------------------------------------------------------------- |
376 | |||
377 | 'pollingFrequency': function() { | ||
378 | return 10; | ||
379 | }, | ||
380 | |||
381 | //------------------------------------------------------------------------- | ||
382 | __syntaxFix__: "syntax fix" | 336 | __syntaxFix__: "syntax fix" |
383 | }); | 337 | }); |
384 | 338 | ||
385 | //############################################################################# | 339 | //############################################################################# |
386 | 340 | ||
387 | Clipperz.Crypto.PRNG.Fortuna = function(args) { | 341 | Clipperz.Crypto.PRNG.Fortuna = function(args) { |
388 | vari,c; | 342 | vari,c; |
389 | 343 | ||
390 | args = args || {}; | 344 | args = args || {}; |
391 | 345 | ||
392 | this._key = args.seed || null; | 346 | this._key = args.seed || null; |
393 | if (this._key == null) { | 347 | if (this._key == null) { |
394 | this._counter = 0; | 348 | this._counter = 0; |
395 | this._key = new Clipperz.ByteArray(); | 349 | this._key = new Clipperz.ByteArray(); |
396 | } else { | 350 | } else { |
397 | this._counter = 1; | 351 | this._counter = 1; |
398 | } | 352 | } |
399 | 353 | ||
400 | this._aesKey = null; | 354 | this._aesKey = null; |
401 | 355 | ||
402 | this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; | 356 | this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; |
403 | this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; | 357 | this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; |
404 | 358 | ||
405 | this._accumulators = []; | 359 | this._accumulators = []; |
406 | c = this.numberOfEntropyAccumulators(); | 360 | c = this.numberOfEntropyAccumulators(); |
407 | for (i=0; i<c; i++) { | 361 | for (i=0; i<c; i++) { |
408 | this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); | 362 | this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); |
409 | } | 363 | } |
410 | 364 | ||
411 | this._randomnessSources = []; | 365 | this._randomnessSources = []; |
412 | this._reseedCounter = 0; | 366 | this._reseedCounter = 0; |
413 | 367 | ||
414 | return this; | 368 | return this; |
415 | } | 369 | } |
416 | 370 | ||
417 | Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { | 371 | Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { |
418 | 372 | ||
419 | 'toString': function() { | 373 | 'toString': function() { |
420 | return "Clipperz.Crypto.PRNG.Fortuna"; | 374 | return "Clipperz.Crypto.PRNG.Fortuna"; |
421 | }, | 375 | }, |
422 | 376 | ||
423 | //------------------------------------------------------------------------- | 377 | //------------------------------------------------------------------------- |
424 | 378 | ||
425 | 'key': function() { | 379 | 'key': function() { |
426 | return this._key; | 380 | return this._key; |
427 | }, | 381 | }, |
428 | 382 | ||
429 | 'setKey': function(aValue) { | 383 | 'setKey': function(aValue) { |
430 | this._key = aValue; | 384 | this._key = aValue; |
431 | this._aesKey = null; | 385 | this._aesKey = null; |
432 | }, | 386 | }, |
433 | 387 | ||
434 | 'aesKey': function() { | 388 | 'aesKey': function() { |
435 | if (this._aesKey == null) { | 389 | if (this._aesKey == null) { |
436 | this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()}); | 390 | this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()}); |
437 | } | 391 | } |
438 | 392 | ||
439 | return this._aesKey; | 393 | return this._aesKey; |
440 | }, | 394 | }, |
441 | 395 | ||
442 | 'accumulators': function() { | 396 | 'accumulators': function() { |
443 | return this._accumulators; | 397 | return this._accumulators; |
444 | }, | 398 | }, |
445 | 399 | ||
446 | 'firstPoolReseedLevel': function() { | 400 | 'firstPoolReseedLevel': function() { |
447 | return this._firstPoolReseedLevel; | 401 | return this._firstPoolReseedLevel; |
448 | }, | 402 | }, |
449 | 403 | ||
450 | //------------------------------------------------------------------------- | 404 | //------------------------------------------------------------------------- |
451 | 405 | ||
452 | 'reseedCounter': function() { | 406 | 'reseedCounter': function() { |
453 | return this._reseedCounter; | 407 | return this._reseedCounter; |
454 | }, | 408 | }, |
455 | 409 | ||
456 | 'incrementReseedCounter': function() { | 410 | 'incrementReseedCounter': function() { |
457 | this._reseedCounter = this._reseedCounter +1; | 411 | this._reseedCounter = this._reseedCounter +1; |
458 | }, | 412 | }, |
459 | 413 | ||
460 | //------------------------------------------------------------------------- | 414 | //------------------------------------------------------------------------- |
461 | 415 | ||
462 | 'reseed': function() { | 416 | 'reseed': function() { |
463 | varnewKeySeed; | 417 | varnewKeySeed; |
464 | var reseedCounter; | 418 | var reseedCounter; |
465 | varreseedCounterMask; | 419 | varreseedCounterMask; |
466 | var i, c; | 420 | var i, c; |
467 | 421 | ||
468 | newKeySeed = this.key(); | 422 | newKeySeed = this.key(); |
469 | this.incrementReseedCounter(); | 423 | this.incrementReseedCounter(); |
470 | reseedCounter = this.reseedCounter(); | 424 | reseedCounter = this.reseedCounter(); |
471 | 425 | ||
472 | c = this.numberOfEntropyAccumulators(); | 426 | c = this.numberOfEntropyAccumulators(); |
473 | reseedCounterMask = 0xffffffff >>> (32 - c); | 427 | reseedCounterMask = 0xffffffff >>> (32 - c); |
474 | for (i=0; i<c; i++) { | 428 | for (i=0; i<c; i++) { |
475 | if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) { | 429 | if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) { |
476 | newKeySeed.appendBlock(this.accumulators()[i].stack()); | 430 | newKeySeed.appendBlock(this.accumulators()[i].stack()); |
477 | this.accumulators()[i].resetStack(); | 431 | this.accumulators()[i].resetStack(); |
478 | } | 432 | } |
479 | } | 433 | } |
480 | 434 | ||
481 | if (reseedCounter == 1) { | 435 | if (reseedCounter == 1) { |
482 | c = this.randomnessSources().length; | 436 | c = this.randomnessSources().length; |
483 | for (i=0; i<c; i++) { | 437 | for (i=0; i<c; i++) { |
484 | this.randomnessSources()[i].setBoostMode(false); | 438 | this.randomnessSources()[i].setBoostMode(false); |
485 | } | 439 | } |
486 | } | 440 | } |
487 | 441 | ||
488 | this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed)); | 442 | this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed)); |
489 | if (reseedCounter == 1) { | 443 | if (reseedCounter == 1) { |
490 | Clipperz.log("### PRNG.readyToGenerateRandomBytes"); | 444 | Clipperz.log("### PRNG.readyToGenerateRandomBytes"); |
491 | MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes'); | 445 | MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes'); |
492 | } | 446 | } |
493 | MochiKit.Signal.signal(this, 'reseeded'); | 447 | MochiKit.Signal.signal(this, 'reseeded'); |
494 | }, | 448 | }, |
495 | 449 | ||
496 | //------------------------------------------------------------------------- | 450 | //------------------------------------------------------------------------- |
497 | 451 | ||
498 | 'isReadyToGenerateRandomValues': function() { | 452 | 'isReadyToGenerateRandomValues': function() { |
499 | return this.reseedCounter() != 0; | 453 | return this.reseedCounter() != 0; |
500 | }, | 454 | }, |
501 | 455 | ||
502 | //------------------------------------------------------------------------- | 456 | //------------------------------------------------------------------------- |
503 | 457 | ||
504 | 'entropyLevel': function() { | 458 | 'entropyLevel': function() { |
505 | return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel()); | 459 | return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel()); |
506 | }, | 460 | }, |
507 | 461 | ||
508 | //------------------------------------------------------------------------- | 462 | //------------------------------------------------------------------------- |
509 | 463 | ||
510 | 'counter': function() { | 464 | 'counter': function() { |
511 | return this._counter; | 465 | return this._counter; |
512 | }, | 466 | }, |
513 | 467 | ||
514 | 'incrementCounter': function() { | 468 | 'incrementCounter': function() { |
515 | this._counter += 1; | 469 | this._counter += 1; |
516 | }, | 470 | }, |
517 | 471 | ||
518 | 'counterBlock': function() { | 472 | 'counterBlock': function() { |
519 | var result; | 473 | var result; |
520 | 474 | ||
521 | result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0); | 475 | result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0); |
522 | 476 | ||
523 | return result; | 477 | return result; |
524 | }, | 478 | }, |
525 | 479 | ||
526 | //------------------------------------------------------------------------- | 480 | //------------------------------------------------------------------------- |
527 | 481 | ||
528 | 'getRandomBlock': function() { | 482 | 'getRandomBlock': function() { |
529 | var result; | 483 | var result; |
530 | 484 | ||
531 | result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues())); | 485 | result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues())); |
532 | this.incrementCounter(); | 486 | this.incrementCounter(); |
533 | 487 | ||
534 | return result; | 488 | return result; |
535 | }, | 489 | }, |
536 | 490 | ||
537 | //------------------------------------------------------------------------- | 491 | //------------------------------------------------------------------------- |
538 | 492 | ||
539 | 'getRandomBytes': function(aSize) { | 493 | 'getRandomBytes': function(aSize) { |
540 | var result; | 494 | var result; |
541 | 495 | ||
542 | if (this.isReadyToGenerateRandomValues()) { | 496 | if (this.isReadyToGenerateRandomValues()) { |
543 | var i,c; | 497 | var i,c; |
544 | var newKey; | 498 | var newKey; |
545 | 499 | ||
546 | result = new Clipperz.ByteArray(); | 500 | result = new Clipperz.ByteArray(); |
547 | 501 | ||
548 | c = Math.ceil(aSize / (128 / 8)); | 502 | c = Math.ceil(aSize / (128 / 8)); |
549 | for (i=0; i<c; i++) { | 503 | for (i=0; i<c; i++) { |
550 | result.appendBlock(this.getRandomBlock()); | 504 | result.appendBlock(this.getRandomBlock()); |
551 | } | 505 | } |
552 | 506 | ||
553 | if (result.length() != aSize) { | 507 | if (result.length() != aSize) { |
554 | result = result.split(0, aSize); | 508 | result = result.split(0, aSize); |
555 | } | 509 | } |
556 | 510 | ||
557 | newKey = this.getRandomBlock().appendBlock(this.getRandomBlock()); | 511 | newKey = this.getRandomBlock().appendBlock(this.getRandomBlock()); |
558 | this.setKey(newKey); | 512 | this.setKey(newKey); |
559 | } else { | 513 | } else { |
560 | Clipperz.logWarning("Fortuna generator has not enough entropy, yet!"); | 514 | Clipperz.logWarning("Fortuna generator has not enough entropy, yet!"); |
561 | throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy; | 515 | throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy; |
562 | } | 516 | } |
563 | 517 | ||
564 | return result; | 518 | return result; |
565 | }, | 519 | }, |
566 | 520 | ||
567 | //------------------------------------------------------------------------- | 521 | //------------------------------------------------------------------------- |
568 | 522 | ||
569 | 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) { | 523 | 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) { |
570 | varselectedAccumulator; | 524 | varselectedAccumulator; |
571 | 525 | ||
572 | selectedAccumulator = this.accumulators()[aPoolId]; | 526 | selectedAccumulator = this.accumulators()[aPoolId]; |
573 | selectedAccumulator.addRandomByte(aRandomValue); | 527 | selectedAccumulator.addRandomByte(aRandomValue); |
574 | 528 | ||
575 | if (aPoolId == 0) { | 529 | if (aPoolId == 0) { |
576 | MochiKit.Signal.signal(this, 'addedRandomByte') | 530 | MochiKit.Signal.signal(this, 'addedRandomByte') |
577 | if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) { | 531 | if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) { |
578 | this.reseed(); | 532 | this.reseed(); |
579 | } | 533 | } |
580 | } | 534 | } |
581 | }, | 535 | }, |
582 | 536 | ||
583 | //------------------------------------------------------------------------- | 537 | //------------------------------------------------------------------------- |
584 | 538 | ||
585 | 'numberOfEntropyAccumulators': function() { | 539 | 'numberOfEntropyAccumulators': function() { |
586 | return this._numberOfEntropyAccumulators; | 540 | return this._numberOfEntropyAccumulators; |
587 | }, | 541 | }, |
588 | 542 | ||
589 | //------------------------------------------------------------------------- | 543 | //------------------------------------------------------------------------- |
590 | 544 | ||
591 | 'randomnessSources': function() { | 545 | 'randomnessSources': function() { |
592 | return this._randomnessSources; | 546 | return this._randomnessSources; |
593 | }, | 547 | }, |
594 | 548 | ||
595 | 'addRandomnessSource': function(aRandomnessSource) { | 549 | 'addRandomnessSource': function(aRandomnessSource) { |
596 | aRandomnessSource.setGenerator(this); | 550 | aRandomnessSource.setGenerator(this); |
597 | aRandomnessSource.setSourceId(this.randomnessSources().length); | 551 | aRandomnessSource.setSourceId(this.randomnessSources().length); |
598 | this.randomnessSources().push(aRandomnessSource); | 552 | this.randomnessSources().push(aRandomnessSource); |
599 | 553 | ||
600 | if (this.isReadyToGenerateRandomValues() == false) { | 554 | if (this.isReadyToGenerateRandomValues() == false) { |
601 | aRandomnessSource.setBoostMode(true); | 555 | aRandomnessSource.setBoostMode(true); |
602 | } | 556 | } |
603 | }, | 557 | }, |
604 | 558 | ||
605 | //------------------------------------------------------------------------- | 559 | //------------------------------------------------------------------------- |
606 | 560 | ||
607 | 'deferredEntropyCollection': function(aValue) { | 561 | 'deferredEntropyCollection': function(aValue) { |
608 | var result; | 562 | var result; |
609 | 563 | ||
610 | 564 | ||
611 | if (this.isReadyToGenerateRandomValues()) { | 565 | if (this.isReadyToGenerateRandomValues()) { |
612 | result = aValue; | 566 | result = aValue; |
613 | } else { | 567 | } else { |
614 | var deferredResult; | 568 | var deferredResult; |
615 | 569 | ||
616 | deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection"); | 570 | deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection"); |
617 | deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); | 571 | deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); |
618 | MochiKit.Signal.connect(this, | 572 | MochiKit.Signal.connect(this, |
619 | 'readyToGenerateRandomBytes', | 573 | 'readyToGenerateRandomBytes', |
620 | deferredResult, | 574 | deferredResult, |
621 | 'callback'); | 575 | 'callback'); |
622 | 576 | ||
623 | result = deferredResult; | 577 | result = deferredResult; |
624 | } | 578 | } |
625 | 579 | ||
626 | return result; | 580 | return result; |
627 | }, | 581 | }, |
628 | 582 | ||
629 | //------------------------------------------------------------------------- | 583 | //------------------------------------------------------------------------- |
630 | 584 | ||
631 | 'fastEntropyAccumulationForTestingPurpose': function() { | 585 | 'fastEntropyAccumulationForTestingPurpose': function() { |
632 | while (! this.isReadyToGenerateRandomValues()) { | 586 | while (! this.isReadyToGenerateRandomValues()) { |
633 | this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); | 587 | this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); |
634 | } | 588 | } |
635 | }, | 589 | }, |
636 | 590 | ||
637 | //------------------------------------------------------------------------- | 591 | //------------------------------------------------------------------------- |
638 | 592 | /* | |
639 | 'dump': function(appendToDoc) { | 593 | 'dump': function(appendToDoc) { |
640 | var tbl; | 594 | var tbl; |
641 | var i,c; | 595 | var i,c; |
642 | 596 | ||
643 | tbl = document.createElement("table"); | 597 | tbl = document.createElement("table"); |
644 | tbl.border = 0; | 598 | tbl.border = 0; |
645 | with (tbl.style) { | 599 | with (tbl.style) { |
646 | border = "1px solid lightgrey"; | 600 | border = "1px solid lightgrey"; |
647 | fontFamily = 'Helvetica, Arial, sans-serif'; | 601 | fontFamily = 'Helvetica, Arial, sans-serif'; |
648 | fontSize = '8pt'; | 602 | fontSize = '8pt'; |
649 | //borderCollapse = "collapse"; | 603 | //borderCollapse = "collapse"; |
650 | } | 604 | } |
651 | var hdr = tbl.createTHead(); | 605 | var hdr = tbl.createTHead(); |
652 | var hdrtr = hdr.insertRow(0); | 606 | var hdrtr = hdr.insertRow(0); |
653 | // document.createElement("tr"); | 607 | // document.createElement("tr"); |
654 | { | 608 | { |
655 | var ntd; | 609 | var ntd; |
656 | 610 | ||
657 | ntd = hdrtr.insertCell(0); | 611 | ntd = hdrtr.insertCell(0); |
658 | ntd.style.borderBottom = "1px solid lightgrey"; | 612 | ntd.style.borderBottom = "1px solid lightgrey"; |
659 | ntd.style.borderRight = "1px solid lightgrey"; | 613 | ntd.style.borderRight = "1px solid lightgrey"; |
660 | ntd.appendChild(document.createTextNode("#")); | 614 | ntd.appendChild(document.createTextNode("#")); |
661 | 615 | ||
662 | ntd = hdrtr.insertCell(1); | 616 | ntd = hdrtr.insertCell(1); |
663 | ntd.style.borderBottom = "1px solid lightgrey"; | 617 | ntd.style.borderBottom = "1px solid lightgrey"; |
664 | ntd.style.borderRight = "1px solid lightgrey"; | 618 | ntd.style.borderRight = "1px solid lightgrey"; |
665 | ntd.appendChild(document.createTextNode("s")); | 619 | ntd.appendChild(document.createTextNode("s")); |
666 | 620 | ||
667 | ntd = hdrtr.insertCell(2); | 621 | ntd = hdrtr.insertCell(2); |
668 | ntd.colSpan = this.firstPoolReseedLevel(); | 622 | ntd.colSpan = this.firstPoolReseedLevel(); |
669 | ntd.style.borderBottom = "1px solid lightgrey"; | 623 | ntd.style.borderBottom = "1px solid lightgrey"; |
670 | ntd.style.borderRight = "1px solid lightgrey"; | 624 | ntd.style.borderRight = "1px solid lightgrey"; |
671 | ntd.appendChild(document.createTextNode("base values")); | 625 | ntd.appendChild(document.createTextNode("base values")); |
672 | 626 | ||
673 | ntd = hdrtr.insertCell(3); | 627 | ntd = hdrtr.insertCell(3); |
674 | ntd.colSpan = 20; | 628 | ntd.colSpan = 20; |
675 | ntd.style.borderBottom = "1px solid lightgrey"; | 629 | ntd.style.borderBottom = "1px solid lightgrey"; |
676 | ntd.appendChild(document.createTextNode("extra values")); | 630 | ntd.appendChild(document.createTextNode("extra values")); |
677 | 631 | ||
678 | } | 632 | } |
679 | 633 | ||
680 | c = this.accumulators().length; | 634 | c = this.accumulators().length; |
681 | for (i=0; i<c ; i++) { | 635 | for (i=0; i<c ; i++) { |
682 | varcurrentAccumulator; | 636 | varcurrentAccumulator; |
683 | var bdytr; | 637 | var bdytr; |
684 | var bdytd; | 638 | var bdytd; |
685 | var ii, cc; | 639 | var ii, cc; |
686 | 640 | ||
687 | currentAccumulator = this.accumulators()[i] | 641 | currentAccumulator = this.accumulators()[i] |
688 | 642 | ||
689 | bdytr = tbl.insertRow(true); | 643 | bdytr = tbl.insertRow(true); |
690 | 644 | ||
691 | bdytd = bdytr.insertCell(0); | 645 | bdytd = bdytr.insertCell(0); |
692 | bdytd.style.borderRight = "1px solid lightgrey"; | 646 | bdytd.style.borderRight = "1px solid lightgrey"; |
693 | bdytd.style.color = "lightgrey"; | 647 | bdytd.style.color = "lightgrey"; |
694 | bdytd.appendChild(document.createTextNode("" + i)); | 648 | bdytd.appendChild(document.createTextNode("" + i)); |
695 | 649 | ||
696 | bdytd = bdytr.insertCell(1); | 650 | bdytd = bdytr.insertCell(1); |
697 | bdytd.style.borderRight = "1px solid lightgrey"; | 651 | bdytd.style.borderRight = "1px solid lightgrey"; |
698 | bdytd.style.color = "gray"; | 652 | bdytd.style.color = "gray"; |
699 | bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); | 653 | bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); |
700 | 654 | ||
701 | 655 | ||
702 | cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); | 656 | cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); |
703 | for (ii=0; ii<cc; ii++) { | 657 | for (ii=0; ii<cc; ii++) { |
704 | var cellText; | 658 | var cellText; |
705 | 659 | ||
706 | bdytd = bdytr.insertCell(ii + 2); | 660 | bdytd = bdytr.insertCell(ii + 2); |
707 | 661 | ||
708 | if (ii < currentAccumulator.stack().length()) { | 662 | if (ii < currentAccumulator.stack().length()) { |
709 | cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); | 663 | cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); |
710 | } else { | 664 | } else { |
711 | cellText = "_"; | 665 | cellText = "_"; |
712 | } | 666 | } |
713 | 667 | ||
714 | if (ii == (this.firstPoolReseedLevel() - 1)) { | 668 | if (ii == (this.firstPoolReseedLevel() - 1)) { |
715 | bdytd.style.borderRight = "1px solid lightgrey"; | 669 | bdytd.style.borderRight = "1px solid lightgrey"; |
716 | } | 670 | } |
717 | 671 | ||
718 | bdytd.appendChild(document.createTextNode(cellText)); | 672 | bdytd.appendChild(document.createTextNode(cellText)); |
719 | } | 673 | } |
720 | 674 | ||
721 | } | 675 | } |
722 | 676 | ||
723 | 677 | ||
724 | if (appendToDoc) { | 678 | if (appendToDoc) { |
725 | var ne = document.createElement("div"); | 679 | var ne = document.createElement("div"); |
726 | ne.id = "entropyGeneratorStatus"; | 680 | ne.id = "entropyGeneratorStatus"; |
727 | with (ne.style) { | 681 | with (ne.style) { |
728 | fontFamily = "Courier New, monospace"; | 682 | fontFamily = "Courier New, monospace"; |
729 | fontSize = "12px"; | 683 | fontSize = "12px"; |
730 | lineHeight = "16px"; | 684 | lineHeight = "16px"; |
731 | borderTop = "1px solid black"; | 685 | borderTop = "1px solid black"; |
732 | padding = "10px"; | 686 | padding = "10px"; |
733 | } | 687 | } |
734 | if (document.getElementById(ne.id)) { | 688 | if (document.getElementById(ne.id)) { |
735 | MochiKit.DOM.swapDOM(ne.id, ne); | 689 | MochiKit.DOM.swapDOM(ne.id, ne); |
736 | } else { | 690 | } else { |
737 | document.body.appendChild(ne); | 691 | document.body.appendChild(ne); |
738 | } | 692 | } |
739 | ne.appendChild(tbl); | 693 | ne.appendChild(tbl); |
740 | } | 694 | } |
741 | 695 | ||
742 | return tbl; | 696 | return tbl; |
743 | }, | 697 | }, |
744 | 698 | */ | |
745 | //----------------------------------------------------------------------------- | 699 | //----------------------------------------------------------------------------- |
746 | __syntaxFix__: "syntax fix" | 700 | __syntaxFix__: "syntax fix" |
747 | }); | 701 | }); |
748 | 702 | ||
749 | //############################################################################# | 703 | //############################################################################# |
750 | 704 | ||
751 | Clipperz.Crypto.PRNG.Random = function(args) { | 705 | Clipperz.Crypto.PRNG.Random = function(args) { |
752 | args = args || {}; | 706 | args = args || {}; |
753 | //MochiKit.Base.bindMethods(this); | 707 | //MochiKit.Base.bindMethods(this); |
754 | 708 | ||
755 | return this; | 709 | return this; |
756 | } | 710 | } |
757 | 711 | ||
758 | Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { | 712 | Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { |
759 | 713 | ||
760 | 'toString': function() { | 714 | 'toString': function() { |
761 | return "Clipperz.Crypto.PRNG.Random"; | 715 | return "Clipperz.Crypto.PRNG.Random"; |
762 | }, | 716 | }, |
763 | 717 | ||
764 | //------------------------------------------------------------------------- | 718 | //------------------------------------------------------------------------- |
765 | 719 | ||
766 | 'getRandomBytes': function(aSize) { | 720 | 'getRandomBytes': function(aSize) { |
767 | //Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); | 721 | //Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); |
768 | varresult; | 722 | varresult; |
769 | var i,c; | 723 | var i,c; |
770 | 724 | ||
771 | result = new Clipperz.ByteArray() | 725 | result = new Clipperz.ByteArray() |
772 | c = aSize || 1; | 726 | c = aSize || 1; |
773 | for (i=0; i<c; i++) { | 727 | for (i=0; i<c; i++) { |
774 | result.appendByte((Math.random()*255) & 0xff); | 728 | result.appendByte((Math.random()*255) & 0xff); |
775 | } | 729 | } |
776 | 730 | ||
777 | //Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); | 731 | //Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); |
778 | return result; | 732 | return result; |
779 | }, | 733 | }, |
780 | 734 | ||
781 | //------------------------------------------------------------------------- | 735 | //------------------------------------------------------------------------- |
782 | __syntaxFix__: "syntax fix" | 736 | __syntaxFix__: "syntax fix" |
783 | }); | 737 | }); |
784 | 738 | ||
785 | //############################################################################# | 739 | //############################################################################# |
786 | 740 | ||
787 | _clipperz_crypt_prng_defaultPRNG = null; | 741 | var _clipperz_crypt_prng_defaultPRNG = null; |
788 | 742 | ||
789 | Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { | 743 | Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { |
790 | if (_clipperz_crypt_prng_defaultPRNG == null) { | 744 | if (_clipperz_crypt_prng_defaultPRNG == null) { |
791 | _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); | 745 | _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); |
792 | 746 | ||
793 | //............................................................. | 747 | //............................................................. |
794 | // | 748 | // |
795 | // TimeRandomnessSource | 749 | // TimeRandomnessSource |
796 | // | 750 | // |
797 | //............................................................. | 751 | //............................................................. |
798 | { | 752 | { |
799 | var newRandomnessSource; | 753 | var newRandomnessSource; |
800 | 754 | ||
801 | newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); | 755 | newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); |
802 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | 756 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); |
803 | } | 757 | } |
804 | 758 | ||
805 | //............................................................. | 759 | //............................................................. |
806 | // | 760 | // |
807 | // MouseRandomnessSource | 761 | // MouseRandomnessSource |
808 | // | 762 | // |
809 | //............................................................. | 763 | //............................................................. |
810 | { | 764 | { |
811 | varnewRandomnessSource; | 765 | varnewRandomnessSource; |
812 | 766 | ||
813 | newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); | 767 | newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); |
814 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | 768 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); |
815 | } | 769 | } |
816 | 770 | ||
817 | //............................................................. | 771 | //............................................................. |
818 | // | 772 | // |
819 | // KeyboardRandomnessSource | 773 | // CryptoRandomRandomnessSource |
820 | // | 774 | // |
821 | //............................................................. | 775 | //............................................................. |
822 | { | 776 | { |
823 | varnewRandomnessSource; | 777 | varnewRandomnessSource; |
778 | varbrowserCrypto; | ||
824 | 779 | ||
825 | newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource(); | 780 | if (window.crypto && window.crypto.getRandomValues) { |
826 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | 781 | browserCrypto = window.crypto; |
782 | } else if (window.msCrypto && window.msCrypto.getRandomValues) { | ||
783 | browserCrypto = window.msCrypto; | ||
784 | } else { | ||
785 | browserCrypto = null; | ||
786 | } | ||
787 | |||
788 | if (browserCrypto != null) { | ||
789 | newRandomnessSource = new Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource({'browserCrypto':browserCrypto}); | ||
790 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | ||
791 | } | ||
827 | } | 792 | } |
828 | |||
829 | } | 793 | } |
830 | 794 | ||
831 | return _clipperz_crypt_prng_defaultPRNG; | 795 | return _clipperz_crypt_prng_defaultPRNG; |
832 | }; | 796 | }; |
833 | 797 | ||
834 | //############################################################################# | 798 | //############################################################################# |
835 | 799 | ||
836 | Clipperz.Crypto.PRNG.exception = { | 800 | Clipperz.Crypto.PRNG.exception = { |
837 | NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") | 801 | NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") |
838 | }; | 802 | }; |
839 | 803 | ||
840 | 804 | ||
841 | MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); | 805 | MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); |
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 | |||
@@ -1,316 +1,345 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { | 24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { |
25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; | 25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; |
26 | } | 26 | } |
27 | 27 | ||
28 | try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { | 28 | try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { |
29 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; | 29 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; |
30 | } | 30 | } |
31 | 31 | ||
32 | try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { | 32 | try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { |
33 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; | 33 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; |
34 | } | 34 | } |
35 | 35 | ||
36 | if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } | 36 | if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } |
37 | 37 | ||
38 | Clipperz.Crypto.SRP.VERSION = "0.1"; | 38 | Clipperz.Crypto.SRP.VERSION = "0.1"; |
39 | Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; | 39 | Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; |
40 | 40 | ||
41 | //############################################################################# | 41 | //############################################################################# |
42 | 42 | ||
43 | MochiKit.Base.update(Clipperz.Crypto.SRP, { | 43 | MochiKit.Base.update(Clipperz.Crypto.SRP, { |
44 | 44 | ||
45 | '_n': null, | 45 | '_n': null, |
46 | '_g': null, | 46 | '_g': null, |
47 | '_k': null, | ||
48 | |||
47 | //------------------------------------------------------------------------- | 49 | //------------------------------------------------------------------------- |
48 | 50 | ||
49 | 'n': function() { | 51 | 'n': function() { |
50 | if (Clipperz.Crypto.SRP._n == null) { | 52 | if (Clipperz.Crypto.SRP._n == null) { |
51 | Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); | 53 | Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); |
52 | } | 54 | } |
53 | 55 | ||
54 | return Clipperz.Crypto.SRP._n; | 56 | return Clipperz.Crypto.SRP._n; |
55 | }, | 57 | }, |
56 | 58 | ||
57 | //------------------------------------------------------------------------- | 59 | //------------------------------------------------------------------------- |
58 | 60 | ||
59 | 'g': function() { | 61 | 'g': function() { |
60 | if (Clipperz.Crypto.SRP._g == null) { | 62 | if (Clipperz.Crypto.SRP._g == null) { |
61 | Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation) | 63 | Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation) |
62 | } | 64 | } |
63 | 65 | ||
64 | return Clipperz.Crypto.SRP._g; | 66 | return Clipperz.Crypto.SRP._g; |
65 | }, | 67 | }, |
66 | 68 | ||
69 | 'k': function() { | ||
70 | if (Clipperz.Crypto.SRP._k == null) { | ||
71 | // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16); | ||
72 | Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16); | ||
73 | } | ||
74 | |||
75 | return Clipperz.Crypto.SRP._k; | ||
76 | }, | ||
77 | |||
67 | //----------------------------------------------------------------------------- | 78 | //----------------------------------------------------------------------------- |
68 | 79 | ||
69 | 'exception': { | 80 | 'exception': { |
70 | 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") | 81 | 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") |
71 | }, | 82 | }, |
72 | 83 | ||
73 | //------------------------------------------------------------------------- | 84 | //------------------------------------------------------------------------- |
74 | __syntaxFix__: "syntax fix" | 85 | __syntaxFix__: "syntax fix" |
75 | 86 | ||
76 | }); | 87 | }); |
77 | 88 | ||
78 | //############################################################################# | 89 | //############################################################################# |
79 | // | 90 | // |
80 | // S R P C o n n e c t i o n version 1.0 | 91 | // S R P C o n n e c t i o n version 1.0 |
81 | // | 92 | // |
82 | //============================================================================= | 93 | //============================================================================= |
83 | Clipperz.Crypto.SRP.Connection = function (args) { | 94 | Clipperz.Crypto.SRP.Connection = function (args) { |
84 | args = args || {}; | 95 | args = args || {}; |
85 | 96 | ||
86 | this._C = args.C; | 97 | this._C = args.C; |
87 | this._P = args.P; | 98 | this._P = args.P; |
88 | this.hash = args.hash; | 99 | this.hash = args.hash; |
89 | 100 | ||
90 | this._a = null; | 101 | this._a = null; |
91 | this._A = null; | 102 | this._A = null; |
92 | 103 | ||
93 | this._s = null; | 104 | this._s = null; |
94 | this._B = null; | 105 | this._B = null; |
95 | 106 | ||
96 | this._x = null; | 107 | this._x = null; |
97 | 108 | ||
98 | this._u = null; | 109 | this._u = null; |
99 | this._K = null; | 110 | this._K = null; |
100 | this._M1 = null; | 111 | this._M1 = null; |
101 | this._M2 = null; | 112 | this._M2 = null; |
102 | 113 | ||
103 | this._sessionKey = null; | 114 | this._sessionKey = null; |
104 | 115 | ||
105 | return this; | 116 | return this; |
106 | } | 117 | } |
107 | 118 | ||
108 | Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { | 119 | Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { |
109 | 120 | ||
110 | 'toString': function () { | 121 | 'toString': function () { |
111 | return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); | 122 | return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); |
112 | }, | 123 | }, |
113 | 124 | ||
114 | //------------------------------------------------------------------------- | 125 | //------------------------------------------------------------------------- |
115 | 126 | ||
116 | 'C': function () { | 127 | 'C': function () { |
117 | return this._C; | 128 | return this._C; |
118 | }, | 129 | }, |
119 | 130 | ||
120 | //------------------------------------------------------------------------- | 131 | //------------------------------------------------------------------------- |
121 | 132 | ||
122 | 'P': function () { | 133 | 'P': function () { |
123 | return this._P; | 134 | return this._P; |
124 | }, | 135 | }, |
125 | 136 | ||
126 | //------------------------------------------------------------------------- | 137 | //------------------------------------------------------------------------- |
127 | 138 | ||
128 | 'a': function () { | 139 | 'a': function () { |
129 | if (this._a == null) { | 140 | if (this._a == null) { |
130 | this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); | 141 | this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); |
131 | // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); | 142 | // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); |
132 | } | 143 | } |
133 | 144 | ||
134 | return this._a; | 145 | return this._a; |
135 | }, | 146 | }, |
136 | 147 | ||
137 | //------------------------------------------------------------------------- | 148 | //------------------------------------------------------------------------- |
138 | 149 | ||
139 | 'A': function () { | 150 | 'A': function () { |
140 | if (this._A == null) { | 151 | if (this._A == null) { |
141 | //Warning: this value should be strictly greater than zero: how should we perform this check? | 152 | //Warning: this value should be strictly greater than zero |
142 | this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); | 153 | this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); |
143 | 154 | if (this._A.equals(0) || negative(this._A)) { | |
144 | if (this._A.equals(0)) { | ||
145 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0."); | 155 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0."); |
146 | throw Clipperz.Crypto.SRP.exception.InvalidValue; | 156 | throw Clipperz.Crypto.SRP.exception.InvalidValue; |
147 | } | 157 | } |
148 | } | 158 | } |
149 | 159 | ||
150 | return this._A; | 160 | return this._A; |
151 | }, | 161 | }, |
152 | 162 | ||
153 | //------------------------------------------------------------------------- | 163 | //------------------------------------------------------------------------- |
154 | 164 | ||
155 | 's': function () { | 165 | 's': function () { |
156 | return this._s; | 166 | return this._s; |
157 | }, | 167 | }, |
158 | 168 | ||
159 | 'set_s': function(aValue) { | 169 | 'set_s': function(aValue) { |
160 | this._s = aValue; | 170 | this._s = aValue; |
161 | }, | 171 | }, |
162 | 172 | ||
163 | //------------------------------------------------------------------------- | 173 | //------------------------------------------------------------------------- |
164 | 174 | ||
165 | 'B': function () { | 175 | 'B': function () { |
166 | return this._B; | 176 | return this._B; |
167 | }, | 177 | }, |
168 | 178 | ||
169 | 'set_B': function(aValue) { | 179 | 'set_B': function(aValue) { |
170 | //Warning: this value should be strictly greater than zero: how should we perform this check? | 180 | //Warning: this value should be strictly greater than zero |
171 | if (! aValue.equals(0)) { | 181 | this._B = aValue; |
172 | this._B = aValue; | 182 | if (this._B.equals(0) || negative(this._B)) { |
173 | } else { | ||
174 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0."); | 183 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0."); |
175 | throw Clipperz.Crypto.SRP.exception.InvalidValue; | 184 | throw Clipperz.Crypto.SRP.exception.InvalidValue; |
176 | } | 185 | } |
177 | }, | 186 | }, |
178 | 187 | ||
179 | //------------------------------------------------------------------------- | 188 | //------------------------------------------------------------------------- |
180 | 189 | ||
181 | 'x': function () { | 190 | 'x': function () { |
182 | if (this._x == null) { | 191 | if (this._x == null) { |
183 | this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); | 192 | this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); |
184 | } | 193 | } |
185 | 194 | ||
186 | return this._x; | 195 | return this._x; |
187 | }, | 196 | }, |
188 | 197 | ||
189 | //------------------------------------------------------------------------- | 198 | //------------------------------------------------------------------------- |
190 | 199 | ||
191 | 'u': function () { | 200 | 'u': function () { |
192 | if (this._u == null) { | 201 | if (this._u == null) { |
193 | this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16); | 202 | this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.A().asString() + this.B().asString()), 16); |
194 | } | 203 | } |
195 | 204 | ||
196 | return this._u; | 205 | return this._u; |
197 | }, | 206 | }, |
198 | 207 | ||
199 | //------------------------------------------------------------------------- | 208 | //------------------------------------------------------------------------- |
200 | 209 | ||
201 | 'S': function () { | 210 | 'S': function () { |
202 | if (this._S == null) { | 211 | if (this._S == null) { |
203 | var bigint; | 212 | var bigint; |
204 | varsrp; | 213 | varsrp; |
205 | 214 | ||
206 | bigint = Clipperz.Crypto.BigInt; | 215 | bigint = Clipperz.Crypto.BigInt; |
207 | srp = Clipperz.Crypto.SRP; | 216 | srp = Clipperz.Crypto.SRP; |
208 | 217 | ||
209 | this._S =bigint.powerModule( | 218 | this._S =bigint.powerModule( |
210 | bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())), | 219 | bigint.subtract( |
211 | bigint.add(this.a(), bigint.multiply(this.u(), this.x())), | 220 | this.B(), |
212 | srp.n() | 221 | bigint.multiply( |
222 | Clipperz.Crypto.SRP.k(), | ||
223 | bigint.powerModule(srp.g(), this.x(), srp.n()) | ||
224 | ) | ||
225 | ), | ||
226 | bigint.add(this.a(), bigint.multiply(this.u(), this.x())), | ||
227 | srp.n() | ||
213 | ) | 228 | ) |
214 | } | 229 | } |
215 | 230 | ||
216 | return this._S; | 231 | return this._S; |
217 | }, | 232 | }, |
218 | 233 | ||
219 | //------------------------------------------------------------------------- | 234 | //------------------------------------------------------------------------- |
220 | 235 | ||
221 | 'K': function () { | 236 | 'K': function () { |
222 | if (this._K == null) { | 237 | if (this._K == null) { |
223 | this._K = this.stringHash(this.S().asString()); | 238 | this._K = this.stringHash(this.S().asString()); |
224 | } | 239 | } |
225 | 240 | ||
226 | return this._K; | 241 | return this._K; |
227 | }, | 242 | }, |
228 | 243 | ||
229 | //------------------------------------------------------------------------- | 244 | //------------------------------------------------------------------------- |
230 | 245 | ||
231 | 'M1': function () { | 246 | 'M1': function () { |
232 | if (this._M1 == null) { | 247 | if (this._M1 == null) { |
233 | this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); | 248 | // this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); |
249 | |||
250 | //http://srp.stanford.edu/design.html | ||
251 | //User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K) | ||
252 | |||
253 | this._M1 = this.stringHash( | ||
254 | "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" + | ||
255 | this.stringHash(this.C()) + | ||
256 | this.s().asString() + | ||
257 | this.A().asString() + | ||
258 | this.B().asString() + | ||
259 | this.K() | ||
260 | ); | ||
261 | //console.log("M1", this._M1); | ||
234 | } | 262 | } |
235 | 263 | ||
236 | return this._M1; | 264 | return this._M1; |
237 | }, | 265 | }, |
238 | 266 | ||
239 | //------------------------------------------------------------------------- | 267 | //------------------------------------------------------------------------- |
240 | 268 | ||
241 | 'M2': function () { | 269 | 'M2': function () { |
242 | if (this._M2 == null) { | 270 | if (this._M2 == null) { |
243 | this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); | 271 | this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); |
272 | //console.log("M2", this._M2); | ||
244 | } | 273 | } |
245 | 274 | ||
246 | return this._M2; | 275 | return this._M2; |
247 | }, | 276 | }, |
248 | 277 | ||
249 | //========================================================================= | 278 | //========================================================================= |
250 | 279 | ||
251 | 'serverSideCredentialsWithSalt': function(aSalt) { | 280 | 'serverSideCredentialsWithSalt': function(aSalt) { |
252 | var result; | 281 | var result; |
253 | var s, x, v; | 282 | var s, x, v; |
254 | 283 | ||
255 | s = aSalt; | 284 | s = aSalt; |
256 | x = this.stringHash(s + this.P()); | 285 | x = this.stringHash(s + this.P()); |
257 | v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); | 286 | v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); |
258 | 287 | ||
259 | result = {}; | 288 | result = {}; |
260 | result['C'] = this.C(); | 289 | result['C'] = this.C(); |
261 | result['s'] = s; | 290 | result['s'] = s; |
262 | result['v'] = v.asString(16); | 291 | result['v'] = v.asString(16); |
263 | 292 | ||
264 | return result; | 293 | return result; |
265 | }, | 294 | }, |
266 | 295 | ||
267 | 'serverSideCredentials': function() { | 296 | 'serverSideCredentials': function() { |
268 | var result; | 297 | var result; |
269 | var s; | 298 | var s; |
270 | 299 | ||
271 | s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); | 300 | s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); |
272 | 301 | ||
273 | result = this.serverSideCredentialsWithSalt(s); | 302 | result = this.serverSideCredentialsWithSalt(s); |
274 | 303 | ||
275 | return result; | 304 | return result; |
276 | }, | 305 | }, |
277 | 306 | ||
278 | //========================================================================= | 307 | //========================================================================= |
279 | /* | 308 | /* |
280 | 'computeServerSide_S': function(b) { | 309 | 'computeServerSide_S': function(b) { |
281 | var result; | 310 | var result; |
282 | var v; | 311 | var v; |
283 | var bigint; | 312 | var bigint; |
284 | varsrp; | 313 | varsrp; |
285 | 314 | ||
286 | bigint = Clipperz.Crypto.BigInt; | 315 | bigint = Clipperz.Crypto.BigInt; |
287 | srp = Clipperz.Crypto.SRP; | 316 | srp = Clipperz.Crypto.SRP; |
288 | 317 | ||
289 | v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16); | 318 | v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16); |
290 | // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n()); | 319 | // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n()); |
291 | result = bigint.powerModule( | 320 | result = bigint.powerModule( |
292 | bigint.multiply( | 321 | bigint.multiply( |
293 | this.A(), | 322 | this.A(), |
294 | bigint.powerModule(v, this.u(), srp.n()) | 323 | bigint.powerModule(v, this.u(), srp.n()) |
295 | ), new Clipperz.Crypto.BigInt(b, 10), srp.n() | 324 | ), new Clipperz.Crypto.BigInt(b, 10), srp.n() |
296 | ); | 325 | ); |
297 | 326 | ||
298 | return result; | 327 | return result; |
299 | }, | 328 | }, |
300 | */ | 329 | */ |
301 | //========================================================================= | 330 | //========================================================================= |
302 | 331 | ||
303 | 'stringHash': function(aValue) { | 332 | 'stringHash': function(aValue) { |
304 | varresult; | 333 | varresult; |
305 | 334 | ||
306 | result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); | 335 | result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); |
307 | 336 | ||
308 | return result; | 337 | return result; |
309 | }, | 338 | }, |
310 | 339 | ||
311 | //========================================================================= | 340 | //========================================================================= |
312 | __syntaxFix__: "syntax fix" | 341 | __syntaxFix__: "syntax fix" |
313 | 342 | ||
314 | }); | 343 | }); |
315 | 344 | ||
316 | //############################################################################# | 345 | //############################################################################# |
diff --git a/frontend/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 | |||
@@ -1,422 +1,437 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | try { if (typeof(Clipperz.PM.Proxy.Offline.DataStore) == 'undefined') { throw ""; }} catch (e) { | 24 | try { if (typeof(Clipperz.PM.Proxy.Offline.DataStore) == 'undefined') { throw ""; }} catch (e) { |
25 | throw "Clipperz.PM.Proxy.Offline.LocalStorageDataStore depends on Clipperz.PM.Proxy.Offline.DataStore!"; | 25 | throw "Clipperz.PM.Proxy.Offline.LocalStorageDataStore depends on Clipperz.PM.Proxy.Offline.DataStore!"; |
26 | } | 26 | } |
27 | 27 | ||
28 | //============================================================================= | 28 | //============================================================================= |
29 | 29 | ||
30 | Clipperz.PM.Proxy.Offline.LocalStorageDataStore = function(args) { | 30 | Clipperz.PM.Proxy.Offline.LocalStorageDataStore = 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._data = JSON.parse(localStorage.getItem('clipperz_dump_data')); | 34 | this._data = JSON.parse(localStorage.getItem('clipperz_dump_data')); |
35 | 35 | ||
36 | this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); | 36 | this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); |
37 | this._shouldPayTolls = args.shouldPayTolls || false; | 37 | this._shouldPayTolls = args.shouldPayTolls || false; |
38 | 38 | ||
39 | this._tolls = {}; | 39 | this._tolls = {}; |
40 | this._currentStaticConnection = null; | 40 | this._currentStaticConnection = null; |
41 | 41 | ||
42 | //Clipperz.PM.Proxy.Offline.LocalStorageDataStore.superclass.constructor.apply(this, arguments); | 42 | //Clipperz.PM.Proxy.Offline.LocalStorageDataStore.superclass.constructor.apply(this, arguments); |
43 | 43 | ||
44 | return this; | 44 | return this; |
45 | } | 45 | } |
46 | 46 | ||
47 | Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.PM.Proxy.Offline.DataStore, { | 47 | Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.PM.Proxy.Offline.DataStore, { |
48 | 48 | ||
49 | //========================================================================= | 49 | //========================================================================= |
50 | 50 | ||
51 | '_knock': function(aConnection, someParameters) { | 51 | '_knock': function(aConnection, someParameters) { |
52 | var result; | 52 | var result; |
53 | 53 | ||
54 | result = { | 54 | result = { |
55 | toll: this.getTollForRequestType(someParameters['requestType']) | 55 | toll: this.getTollForRequestType(someParameters['requestType']) |
56 | } | 56 | } |
57 | 57 | ||
58 | return result; | 58 | return result; |
59 | }, | 59 | }, |
60 | 60 | ||
61 | //------------------------------------------------------------------------- | 61 | //------------------------------------------------------------------------- |
62 | 62 | ||
63 | '_registration': function(aConnection, someParameters) { | 63 | '_registration': function(aConnection, someParameters) { |
64 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | 64 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; |
65 | }, | 65 | }, |
66 | 66 | ||
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"; |
138 | } | 153 | } |
139 | } else { | 154 | } else { |
140 | throw "The requested One Time Password was not active"; | 155 | throw "The requested One Time Password was not active"; |
141 | } | 156 | } |
142 | } else { | 157 | } else { |
143 | throw "The requested One Time Password has not been found" | 158 | throw "The requested One Time Password has not been found" |
144 | } | 159 | } |
145 | } catch (exception) { | 160 | } catch (exception) { |
146 | result = { | 161 | result = { |
147 | 'data': Clipperz.PM.Crypto.randomKey(), | 162 | 'data': Clipperz.PM.Crypto.randomKey(), |
148 | 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion | 163 | 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion |
149 | } | 164 | } |
150 | } | 165 | } |
151 | nextTollRequestType = 'CONNECT'; | 166 | nextTollRequestType = 'CONNECT'; |
152 | } else { | 167 | } else { |
153 | Clipperz.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); | 168 | Clipperz.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); |
154 | } | 169 | } |
155 | 170 | ||
156 | result = { | 171 | result = { |
157 | result: result, | 172 | result: result, |
158 | toll: this.getTollForRequestType(nextTollRequestType) | 173 | toll: this.getTollForRequestType(nextTollRequestType) |
159 | } | 174 | } |
160 | 175 | ||
161 | return result; | 176 | return result; |
162 | }, | 177 | }, |
163 | 178 | ||
164 | //------------------------------------------------------------------------- | 179 | //------------------------------------------------------------------------- |
165 | 180 | ||
166 | '_message': function(aConnection, someParameters) { | 181 | '_message': function(aConnection, someParameters) { |
167 | var result; | 182 | var result; |
168 | 183 | ||
169 | result = {}; | 184 | result = {}; |
170 | 185 | ||
171 | //===================================================================== | 186 | //===================================================================== |
172 | // | 187 | // |
173 | // R E A D - O N L Y M e t h o d s | 188 | // R E A D - O N L Y M e t h o d s |
174 | // | 189 | // |
175 | //===================================================================== | 190 | //===================================================================== |
176 | if (someParameters.message == 'getUserDetails') { | 191 | if (someParameters.message == 'getUserDetails') { |
177 | var recordsStats; | 192 | var recordsStats; |
178 | var recordReference; | 193 | var recordReference; |
179 | 194 | ||
180 | recordsStats = {}; | 195 | recordsStats = {}; |
181 | for (recordReference in aConnection['userData']['records']) { | 196 | for (recordReference in aConnection['userData']['records']) { |
182 | recordsStats[recordReference] = { | 197 | recordsStats[recordReference] = { |
183 | 'updateDate': aConnection['userData']['records'][recordReference]['updateDate'] | 198 | 'updateDate': aConnection['userData']['records'][recordReference]['updateDate'] |
184 | } | 199 | } |
185 | } | 200 | } |
186 | 201 | ||
187 | result['header'] = this.userDetails(aConnection); | 202 | result['header'] = this.userDetails(aConnection); |
188 | result['statistics'] = this.statistics(aConnection); | 203 | result['statistics'] = this.statistics(aConnection); |
189 | result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords']; | 204 | result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords']; |
190 | result['version'] = aConnection['userData']['userDetailsVersion']; | 205 | result['version'] = aConnection['userData']['userDetailsVersion']; |
191 | result['recordsStats'] = recordsStats; | 206 | result['recordsStats'] = recordsStats; |
192 | 207 | ||
193 | if (this.isReadOnly() == false) { | 208 | if (this.isReadOnly() == false) { |
194 | varlock; | 209 | varlock; |
195 | 210 | ||
196 | if (typeof(aConnection['userData']['lock']) == 'undefined') { | 211 | if (typeof(aConnection['userData']['lock']) == 'undefined') { |
197 | aConnection['userData']['lock'] = "<<LOCK>>"; | 212 | aConnection['userData']['lock'] = "<<LOCK>>"; |
198 | } | 213 | } |
199 | 214 | ||
200 | result['lock'] = aConnection['userData']['lock']; | 215 | result['lock'] = aConnection['userData']['lock']; |
201 | } | 216 | } |
202 | 217 | ||
203 | //===================================================================== | 218 | //===================================================================== |
204 | } else if (someParameters.message == 'getRecordDetail') { | 219 | } else if (someParameters.message == 'getRecordDetail') { |
205 | /* | 220 | /* |
206 | varrecordData; | 221 | varrecordData; |
207 | var currentVersionData; | 222 | var currentVersionData; |
208 | 223 | ||
209 | recordData = this.userData()['records'][someParameters['parameters']['reference']]; | 224 | recordData = this.userData()['records'][someParameters['parameters']['reference']]; |
210 | result['reference'] = someParameters['parameters']['reference']; | 225 | result['reference'] = someParameters['parameters']['reference']; |
211 | result['data'] = recordData['data']; | 226 | result['data'] = recordData['data']; |
212 | result['version'] = recordData['version']; | 227 | result['version'] = recordData['version']; |
213 | result['creationData'] = recordData['creationDate']; | 228 | result['creationData'] = recordData['creationDate']; |
214 | result['updateDate'] = recordData['updateDate']; | 229 | result['updateDate'] = recordData['updateDate']; |
215 | result['accessDate'] = recordData['accessDate']; | 230 | result['accessDate'] = recordData['accessDate']; |
216 | 231 | ||
217 | currentVersionData = recordData['versions'][recordData['currentVersion']]; | 232 | currentVersionData = recordData['versions'][recordData['currentVersion']]; |
218 | 233 | ||
219 | result['currentVersion'] = {}; | 234 | result['currentVersion'] = {}; |
220 | result['currentVersion']['reference'] = recordData['currentVersion']; | 235 | result['currentVersion']['reference'] = recordData['currentVersion']; |
221 | result['currentVersion']['version'] = currentVersionData['version']; | 236 | result['currentVersion']['version'] = currentVersionData['version']; |
222 | result['currentVersion']['header'] = currentVersionData['header']; | 237 | result['currentVersion']['header'] = currentVersionData['header']; |
223 | result['currentVersion']['data'] = currentVersionData['data']; | 238 | result['currentVersion']['data'] = currentVersionData['data']; |
224 | result['currentVersion']['creationData'] = currentVersionData['creationDate']; | 239 | result['currentVersion']['creationData'] = currentVersionData['creationDate']; |
225 | result['currentVersion']['updateDate'] = currentVersionData['updateDate']; | 240 | result['currentVersion']['updateDate'] = currentVersionData['updateDate']; |
226 | result['currentVersion']['accessDate'] = currentVersionData['accessDate']; | 241 | result['currentVersion']['accessDate'] = currentVersionData['accessDate']; |
227 | if (typeof(currentVersionData['previousVersion']) != 'undefined') { | 242 | if (typeof(currentVersionData['previousVersion']) != 'undefined') { |
228 | result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; | 243 | result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; |
229 | result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; | 244 | result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; |
230 | } | 245 | } |
231 | */ | 246 | */ |
232 | MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]); | 247 | MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]); |
233 | result['reference'] = someParameters['parameters']['reference']; | 248 | result['reference'] = someParameters['parameters']['reference']; |
234 | 249 | ||
235 | //===================================================================== | 250 | //===================================================================== |
236 | // | 251 | // |
237 | // R E A D - W R I T E M e t h o d s | 252 | // R E A D - W R I T E M e t h o d s |
238 | // | 253 | // |
239 | //===================================================================== | 254 | //===================================================================== |
240 | } else if (someParameters.message == 'upgradeUserCredentials') { | 255 | } else if (someParameters.message == 'upgradeUserCredentials') { |
241 | if (this.isReadOnly() == false) { | 256 | if (this.isReadOnly() == false) { |
242 | var parameters; | 257 | var parameters; |
243 | var credentials; | 258 | var credentials; |
244 | 259 | ||
245 | parameters = someParameters['parameters']; | 260 | parameters = someParameters['parameters']; |
246 | credentials = parameters['credentials']; | 261 | credentials = parameters['credentials']; |
247 | 262 | ||
248 | if ((credentials['C'] == null) | 263 | if ((credentials['C'] == null) |
249 | ||(credentials['s'] == null) | 264 | ||(credentials['s'] == null) |
250 | ||(credentials['v'] == null) | 265 | ||(credentials['v'] == null) |
251 | ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) | 266 | ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) |
252 | ) { | 267 | ) { |
253 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; | 268 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; |
254 | } else { | 269 | } else { |
255 | varoldCValue; | 270 | varoldCValue; |
256 | oldCValue = aConnection['C']; | 271 | oldCValue = aConnection['C']; |
257 | 272 | ||
258 | this.data()['users'][credentials['C']] = aConnection['userData']; | 273 | this.data()['users'][credentials['C']] = aConnection['userData']; |
259 | aConnection['C'] = credentials['C']; | 274 | aConnection['C'] = credentials['C']; |
260 | 275 | ||
261 | aConnection['userData']['s'] = credentials['s']; | 276 | aConnection['userData']['s'] = credentials['s']; |
262 | aConnection['userData']['v'] = credentials['v']; | 277 | aConnection['userData']['v'] = credentials['v']; |
263 | aConnection['userData']['version'] = credentials['version']; | 278 | aConnection['userData']['version'] = credentials['version']; |
264 | 279 | ||
265 | aConnection['userData']['userDetails'] = parameters['user']['header']; | 280 | aConnection['userData']['userDetails'] = parameters['user']['header']; |
266 | aConnection['userData']['userDetailsVersion'] = parameters['user']['version']; | 281 | aConnection['userData']['userDetailsVersion'] = parameters['user']['version']; |
267 | aConnection['userData']['statistics'] = parameters['user']['statistics']; | 282 | aConnection['userData']['statistics'] = parameters['user']['statistics']; |
268 | 283 | ||
269 | aConnection['userData']['lock'] = parameters['user']['lock']; | 284 | aConnection['userData']['lock'] = parameters['user']['lock']; |
270 | 285 | ||
271 | delete this.data()['users'][oldCValue]; | 286 | delete this.data()['users'][oldCValue]; |
272 | 287 | ||
273 | result = {result:"done", parameters:parameters}; | 288 | result = {result:"done", parameters:parameters}; |
274 | } | 289 | } |
275 | } else { | 290 | } else { |
276 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | 291 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; |
277 | } | 292 | } |
278 | 293 | ||
279 | //===================================================================== | 294 | //===================================================================== |
280 | 295 | ||
281 | } else if (someParameters.message == 'saveChanges') { | 296 | } else if (someParameters.message == 'saveChanges') { |
282 | if (this.isReadOnly() == false) { | 297 | if (this.isReadOnly() == false) { |
283 | var i, c; | 298 | var i, c; |
284 | 299 | ||
285 | if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) { | 300 | if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) { |
286 | throw "the lock attribute is not processed correctly" | 301 | throw "the lock attribute is not processed correctly" |
287 | } | 302 | } |
288 | 303 | ||
289 | aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header']; | 304 | aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header']; |
290 | aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics']; | 305 | aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics']; |
291 | aConnection['userData']['userDetailsVersion']= someParameters['parameters']['user']['version']; | 306 | aConnection['userData']['userDetailsVersion']= someParameters['parameters']['user']['version']; |
292 | 307 | ||
293 | c = someParameters['parameters']['records']['updated'].length; | 308 | c = someParameters['parameters']['records']['updated'].length; |
294 | for (i=0; i<c; i++) { | 309 | for (i=0; i<c; i++) { |
295 | var currentRecord; | 310 | var currentRecord; |
296 | var currentRecordData; | 311 | var currentRecordData; |
297 | 312 | ||
298 | currentRecordData = someParameters['parameters']['records']['updated'][i]; | 313 | currentRecordData = someParameters['parameters']['records']['updated'][i]; |
299 | currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']]; | 314 | currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']]; |
300 | 315 | ||
301 | if ( | 316 | if ( |
302 | (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined') | 317 | (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined') |
303 | && | 318 | && |
304 | (typeof(currentRecordData['currentRecordVersion']) == 'undefined') | 319 | (typeof(currentRecordData['currentRecordVersion']) == 'undefined') |
305 | ) { | 320 | ) { |
306 | throw "Record added without a recordVersion"; | 321 | throw "Record added without a recordVersion"; |
307 | } | 322 | } |
308 | 323 | ||
309 | if (currentRecord == null) { | 324 | if (currentRecord == null) { |
310 | currentRecord = {}; | 325 | currentRecord = {}; |
311 | currentRecord['versions'] = {}; | 326 | currentRecord['versions'] = {}; |
312 | currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | 327 | currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); |
313 | currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | 328 | currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); |
314 | 329 | ||
315 | aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord; | 330 | aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord; |
316 | } | 331 | } |
317 | 332 | ||
318 | currentRecord['data'] = currentRecordData['record']['data']; | 333 | currentRecord['data'] = currentRecordData['record']['data']; |
319 | currentRecord['version']= currentRecordData['record']['version']; | 334 | currentRecord['version']= currentRecordData['record']['version']; |
320 | currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | 335 | currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); |
321 | 336 | ||
322 | if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') { | 337 | if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') { |
323 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; | 338 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; |
324 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { | 339 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { |
325 | 'data': currentRecordData['currentRecordVersion']['data'], | 340 | 'data': currentRecordData['currentRecordVersion']['data'], |
326 | 'version': currentRecordData['currentRecordVersion']['version'], | 341 | 'version': currentRecordData['currentRecordVersion']['version'], |
327 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], | 342 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], |
328 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'], | 343 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'], |
329 | 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), | 344 | 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), |
330 | 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), | 345 | 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), |
331 | 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()) | 346 | 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()) |
332 | } | 347 | } |
333 | } | 348 | } |
334 | } | 349 | } |
335 | 350 | ||
336 | c = someParameters['parameters']['records']['deleted'].length; | 351 | c = someParameters['parameters']['records']['deleted'].length; |
337 | for (i=0; i<c; i++) { | 352 | for (i=0; i<c; i++) { |
338 | var currentRecordReference; | 353 | var currentRecordReference; |
339 | 354 | ||
340 | currentRecordReference = someParameters['parameters']['records']['deleted'][i]; | 355 | currentRecordReference = someParameters['parameters']['records']['deleted'][i]; |
341 | delete aConnection['userData']['records'][currentRecordReference]; | 356 | delete aConnection['userData']['records'][currentRecordReference]; |
342 | } | 357 | } |
343 | 358 | ||
344 | aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey(); | 359 | aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey(); |
345 | result['lock'] = aConnection['userData']['lock']; | 360 | result['lock'] = aConnection['userData']['lock']; |
346 | result['result'] = 'done'; | 361 | result['result'] = 'done'; |
347 | } else { | 362 | } else { |
348 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | 363 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; |
349 | } | 364 | } |
350 | 365 | ||
351 | //===================================================================== | 366 | //===================================================================== |
352 | // | 367 | // |
353 | // U N H A N D L E D M e t h o d | 368 | // U N H A N D L E D M e t h o d |
354 | // | 369 | // |
355 | //===================================================================== | 370 | //===================================================================== |
356 | } else { | 371 | } else { |
357 | Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message); | 372 | Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message); |
358 | } | 373 | } |
359 | 374 | ||
360 | result = { | 375 | result = { |
361 | result: result, | 376 | result: result, |
362 | toll: this.getTollForRequestType('MESSAGE') | 377 | toll: this.getTollForRequestType('MESSAGE') |
363 | } | 378 | } |
364 | 379 | ||
365 | // return MochiKit.Async.succeed(result); | 380 | // return MochiKit.Async.succeed(result); |
366 | return result; | 381 | return result; |
367 | }, | 382 | }, |
368 | 383 | ||
369 | //------------------------------------------------------------------------- | 384 | //------------------------------------------------------------------------- |
370 | 385 | ||
371 | '_logout': function(someParameters) { | 386 | '_logout': function(someParameters) { |
372 | // return MochiKit.Async.succeed({result: 'done'}); | 387 | // return MochiKit.Async.succeed({result: 'done'}); |
373 | return {result: 'done'}; | 388 | return {result: 'done'}; |
374 | }, | 389 | }, |
375 | 390 | ||
376 | //========================================================================= | 391 | //========================================================================= |
377 | //######################################################################### | 392 | //######################################################################### |
378 | /* | 393 | /* |
379 | 'userDetails': function(aConnection) { | 394 | 'userDetails': function(aConnection) { |
380 | var result; | 395 | var result; |
381 | 396 | ||
382 | if (this.isTestData(aConnection)) { | 397 | if (this.isTestData(aConnection)) { |
383 | var serializedHeader; | 398 | var serializedHeader; |
384 | var version; | 399 | var version; |
385 | 400 | ||
386 | //Clipperz.logDebug("### test data"); | 401 | //Clipperz.logDebug("### test data"); |
387 | version = aConnection['userData']['userDetailsVersion']; | 402 | version = aConnection['userData']['userDetailsVersion']; |
388 | serializedHeader = Clipperz.Base.serializeJSON(aConnection['userData']['userDetails']); | 403 | serializedHeader = Clipperz.Base.serializeJSON(aConnection['userData']['userDetails']); |
389 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedHeader); | 404 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedHeader); |
390 | } else { | 405 | } else { |
391 | //Clipperz.logDebug("### NOT test data"); | 406 | //Clipperz.logDebug("### NOT test data"); |
392 | result = aConnection['userData']['userDetails']; | 407 | result = aConnection['userData']['userDetails']; |
393 | } | 408 | } |
394 | 409 | ||
395 | return result; | 410 | return result; |
396 | }, | 411 | }, |
397 | 412 | ||
398 | 'statistics': function(aConnection) { | 413 | 'statistics': function(aConnection) { |
399 | var result; | 414 | var result; |
400 | 415 | ||
401 | if (aConnection['userData']['statistics'] != null) { | 416 | if (aConnection['userData']['statistics'] != null) { |
402 | if (this.isTestData(aConnection)) { | 417 | if (this.isTestData(aConnection)) { |
403 | var serializedStatistics; | 418 | var serializedStatistics; |
404 | var version; | 419 | var version; |
405 | 420 | ||
406 | version = aConnection['userData']['userDetailsVersion']; | 421 | version = aConnection['userData']['userDetailsVersion']; |
407 | serializedStatistics = Clipperz.Base.serializeJSON(aConnection['userData']['statistics']); | 422 | serializedStatistics = Clipperz.Base.serializeJSON(aConnection['userData']['statistics']); |
408 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedStatistics); | 423 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedStatistics); |
409 | } else { | 424 | } else { |
410 | result = aConnection['userData']['statistics']; | 425 | result = aConnection['userData']['statistics']; |
411 | } | 426 | } |
412 | } else { | 427 | } else { |
413 | result = null; | 428 | result = null; |
414 | } | 429 | } |
415 | 430 | ||
416 | return result; | 431 | return result; |
417 | }, | 432 | }, |
418 | */ | 433 | */ |
419 | //========================================================================= | 434 | //========================================================================= |
420 | __syntaxFix__: "syntax fix" | 435 | __syntaxFix__: "syntax fix" |
421 | }); | 436 | }); |
422 | 437 | ||
diff --git a/frontend/gamma/js/Clipperz/Crypto/PRNG.js b/frontend/gamma/js/Clipperz/Crypto/PRNG.js index c539f06..80d972f 100644 --- a/frontend/gamma/js/Clipperz/Crypto/PRNG.js +++ b/frontend/gamma/js/Clipperz/Crypto/PRNG.js | |||
@@ -1,841 +1,805 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | "use strict"; | ||
25 | |||
24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { | 26 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { |
25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; | 27 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; |
26 | } | 28 | } |
27 | 29 | ||
28 | try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) { | 30 | try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) { |
29 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!"; | 31 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!"; |
30 | } | 32 | } |
31 | 33 | ||
32 | try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) { | 34 | try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) { |
33 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!"; | 35 | throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!"; |
34 | } | 36 | } |
35 | 37 | ||
36 | if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; } | 38 | if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; } |
37 | 39 | ||
38 | //############################################################################# | 40 | //############################################################################# |
39 | 41 | ||
40 | Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) { | 42 | Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) { |
41 | args = args || {}; | 43 | args = args || {}; |
42 | //MochiKit.Base.bindMethods(this); | 44 | //MochiKit.Base.bindMethods(this); |
43 | 45 | ||
44 | this._stack = new Clipperz.ByteArray(); | 46 | this._stack = new Clipperz.ByteArray(); |
45 | this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256; | 47 | this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256; |
46 | return this; | 48 | return this; |
47 | } | 49 | } |
48 | 50 | ||
49 | Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, { | 51 | Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, { |
50 | 52 | ||
51 | 'toString': function() { | 53 | 'toString': function() { |
52 | return "Clipperz.Crypto.PRNG.EntropyAccumulator"; | 54 | return "Clipperz.Crypto.PRNG.EntropyAccumulator"; |
53 | }, | 55 | }, |
54 | 56 | ||
55 | //------------------------------------------------------------------------- | 57 | //------------------------------------------------------------------------- |
56 | 58 | ||
57 | 'stack': function() { | 59 | 'stack': function() { |
58 | return this._stack; | 60 | return this._stack; |
59 | }, | 61 | }, |
60 | 62 | ||
61 | 'setStack': function(aValue) { | 63 | 'setStack': function(aValue) { |
62 | this._stack = aValue; | 64 | this._stack = aValue; |
63 | }, | 65 | }, |
64 | 66 | ||
65 | 'resetStack': function() { | 67 | 'resetStack': function() { |
66 | this.stack().reset(); | 68 | this.stack().reset(); |
67 | }, | 69 | }, |
68 | 70 | ||
69 | 'maxStackLengthBeforeHashing': function() { | 71 | 'maxStackLengthBeforeHashing': function() { |
70 | return this._maxStackLengthBeforeHashing; | 72 | return this._maxStackLengthBeforeHashing; |
71 | }, | 73 | }, |
72 | 74 | ||
73 | //------------------------------------------------------------------------- | 75 | //------------------------------------------------------------------------- |
74 | 76 | ||
75 | 'addRandomByte': function(aValue) { | 77 | 'addRandomByte': function(aValue) { |
76 | this.stack().appendByte(aValue); | 78 | this.stack().appendByte(aValue); |
77 | 79 | ||
78 | if (this.stack().length() > this.maxStackLengthBeforeHashing()) { | 80 | if (this.stack().length() > this.maxStackLengthBeforeHashing()) { |
79 | this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack())); | 81 | this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack())); |
80 | } | 82 | } |
81 | }, | 83 | }, |
82 | 84 | ||
83 | //------------------------------------------------------------------------- | 85 | //------------------------------------------------------------------------- |
84 | __syntaxFix__: "syntax fix" | 86 | __syntaxFix__: "syntax fix" |
85 | }); | 87 | }); |
86 | 88 | ||
87 | //############################################################################# | 89 | //############################################################################# |
88 | 90 | ||
89 | Clipperz.Crypto.PRNG.RandomnessSource = function(args) { | 91 | Clipperz.Crypto.PRNG.RandomnessSource = function(args) { |
90 | args = args || {}; | 92 | args = args || {}; |
91 | MochiKit.Base.bindMethods(this); | 93 | MochiKit.Base.bindMethods(this); |
92 | 94 | ||
93 | this._generator = args.generator || null; | 95 | this._generator = args.generator || null; |
94 | this._sourceId = args.sourceId || null; | 96 | this._sourceId = args.sourceId || null; |
95 | this._boostMode = args.boostMode || false; | 97 | this._boostMode = args.boostMode || false; |
96 | 98 | ||
97 | this._nextPoolIndex = 0; | 99 | this._nextPoolIndex = 0; |
98 | 100 | ||
99 | return this; | 101 | return this; |
100 | } | 102 | } |
101 | 103 | ||
102 | Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, { | 104 | Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, { |
103 | 105 | ||
104 | 'generator': function() { | 106 | 'generator': function() { |
105 | return this._generator; | 107 | return this._generator; |
106 | }, | 108 | }, |
107 | 109 | ||
108 | 'setGenerator': function(aValue) { | 110 | 'setGenerator': function(aValue) { |
109 | this._generator = aValue; | 111 | this._generator = aValue; |
110 | }, | 112 | }, |
111 | 113 | ||
112 | //------------------------------------------------------------------------- | 114 | //------------------------------------------------------------------------- |
113 | 115 | ||
114 | 'boostMode': function() { | 116 | 'boostMode': function() { |
115 | return this._boostMode; | 117 | return this._boostMode; |
116 | }, | 118 | }, |
117 | 119 | ||
118 | 'setBoostMode': function(aValue) { | 120 | 'setBoostMode': function(aValue) { |
119 | this._boostMode = aValue; | 121 | this._boostMode = aValue; |
120 | }, | 122 | }, |
121 | 123 | ||
122 | //------------------------------------------------------------------------- | 124 | //------------------------------------------------------------------------- |
123 | 125 | ||
124 | 'sourceId': function() { | 126 | 'sourceId': function() { |
125 | return this._sourceId; | 127 | return this._sourceId; |
126 | }, | 128 | }, |
127 | 129 | ||
128 | 'setSourceId': function(aValue) { | 130 | 'setSourceId': function(aValue) { |
129 | this._sourceId = aValue; | 131 | this._sourceId = aValue; |
130 | }, | 132 | }, |
131 | 133 | ||
132 | //------------------------------------------------------------------------- | 134 | //------------------------------------------------------------------------- |
133 | 135 | ||
134 | 'nextPoolIndex': function() { | 136 | 'nextPoolIndex': function() { |
135 | return this._nextPoolIndex; | 137 | return this._nextPoolIndex; |
136 | }, | 138 | }, |
137 | 139 | ||
138 | 'incrementNextPoolIndex': function() { | 140 | 'incrementNextPoolIndex': function() { |
139 | this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators()); | 141 | this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators()); |
140 | }, | 142 | }, |
141 | 143 | ||
142 | //------------------------------------------------------------------------- | 144 | //------------------------------------------------------------------------- |
143 | 145 | ||
144 | 'updateGeneratorWithValue': function(aRandomValue) { | 146 | 'updateGeneratorWithValue': function(aRandomValue) { |
145 | if (this.generator() != null) { | 147 | if (this.generator() != null) { |
146 | this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue); | 148 | this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue); |
147 | this.incrementNextPoolIndex(); | 149 | this.incrementNextPoolIndex(); |
148 | } | 150 | } |
149 | }, | 151 | }, |
150 | 152 | ||
151 | //------------------------------------------------------------------------- | 153 | //------------------------------------------------------------------------- |
152 | __syntaxFix__: "syntax fix" | 154 | __syntaxFix__: "syntax fix" |
153 | }); | 155 | }); |
154 | 156 | ||
155 | //############################################################################# | 157 | //############################################################################# |
156 | 158 | ||
157 | Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { | 159 | Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { |
158 | args = args || {}; | 160 | args = args || {}; |
159 | //MochiKit.Base.bindMethods(this); | 161 | //MochiKit.Base.bindMethods(this); |
160 | 162 | ||
161 | this._intervalTime = args.intervalTime || 1000; | 163 | this._intervalTime = args.intervalTime || 1000; |
162 | 164 | ||
163 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); | 165 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); |
164 | 166 | ||
165 | this.collectEntropy(); | 167 | this.collectEntropy(); |
166 | return this; | 168 | return this; |
167 | } | 169 | } |
168 | 170 | ||
169 | Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { | 171 | Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { |
170 | 172 | ||
171 | 'intervalTime': function() { | 173 | 'intervalTime': function() { |
172 | return this._intervalTime; | 174 | return this._intervalTime; |
173 | }, | 175 | }, |
174 | 176 | ||
175 | //------------------------------------------------------------------------- | 177 | //------------------------------------------------------------------------- |
176 | 178 | ||
177 | 'collectEntropy': function() { | 179 | 'collectEntropy': function() { |
178 | varnow; | 180 | varnow; |
179 | varentropyByte; | 181 | varentropyByte; |
180 | var intervalTime; | 182 | var intervalTime; |
181 | now = new Date(); | 183 | now = new Date(); |
182 | entropyByte = (now.getTime() & 0xff); | 184 | entropyByte = (now.getTime() & 0xff); |
183 | 185 | ||
184 | intervalTime = this.intervalTime(); | 186 | intervalTime = this.intervalTime(); |
185 | if (this.boostMode() == true) { | 187 | if (this.boostMode() == true) { |
186 | intervalTime = intervalTime / 9; | 188 | intervalTime = intervalTime / 9; |
187 | } | 189 | } |
188 | 190 | ||
189 | this.updateGeneratorWithValue(entropyByte); | 191 | this.updateGeneratorWithValue(entropyByte); |
190 | setTimeout(this.collectEntropy, intervalTime); | 192 | setTimeout(this.collectEntropy, intervalTime); |
191 | }, | 193 | }, |
192 | 194 | ||
193 | //------------------------------------------------------------------------- | 195 | //------------------------------------------------------------------------- |
194 | 196 | ||
195 | 'numberOfRandomBits': function() { | 197 | 'numberOfRandomBits': function() { |
196 | return 5; | 198 | return 5; |
197 | }, | 199 | }, |
198 | 200 | ||
199 | //------------------------------------------------------------------------- | 201 | //------------------------------------------------------------------------- |
200 | |||
201 | 'pollingFrequency': function() { | ||
202 | return 10; | ||
203 | }, | ||
204 | |||
205 | //------------------------------------------------------------------------- | ||
206 | __syntaxFix__: "syntax fix" | 202 | __syntaxFix__: "syntax fix" |
207 | }); | 203 | }); |
208 | 204 | ||
209 | //***************************************************************************** | 205 | //***************************************************************************** |
210 | 206 | ||
211 | Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { | 207 | Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { |
212 | args = args || {}; | 208 | args = args || {}; |
213 | 209 | ||
214 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); | 210 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); |
215 | 211 | ||
216 | this._numberOfBitsToCollectAtEachEvent = 4; | 212 | this._numberOfBitsToCollectAtEachEvent = 4; |
217 | this._randomBitsCollector = 0; | 213 | this._randomBitsCollector = 0; |
218 | this._numberOfRandomBitsCollected = 0; | 214 | this._numberOfRandomBitsCollected = 0; |
219 | 215 | ||
220 | MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); | 216 | MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); |
221 | 217 | ||
222 | return this; | 218 | return this; |
223 | } | 219 | } |
224 | 220 | ||
225 | Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { | 221 | Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { |
226 | 222 | ||
227 | //------------------------------------------------------------------------- | 223 | //------------------------------------------------------------------------- |
228 | 224 | ||
229 | 'numberOfBitsToCollectAtEachEvent': function() { | 225 | 'numberOfBitsToCollectAtEachEvent': function() { |
230 | return this._numberOfBitsToCollectAtEachEvent; | 226 | return this._numberOfBitsToCollectAtEachEvent; |
231 | }, | 227 | }, |
232 | 228 | ||
233 | //------------------------------------------------------------------------- | 229 | //------------------------------------------------------------------------- |
234 | 230 | ||
235 | 'randomBitsCollector': function() { | 231 | 'randomBitsCollector': function() { |
236 | return this._randomBitsCollector; | 232 | return this._randomBitsCollector; |
237 | }, | 233 | }, |
238 | 234 | ||
239 | 'setRandomBitsCollector': function(aValue) { | 235 | 'setRandomBitsCollector': function(aValue) { |
240 | this._randomBitsCollector = aValue; | 236 | this._randomBitsCollector = aValue; |
241 | }, | 237 | }, |
242 | 238 | ||
243 | 'appendRandomBitsToRandomBitsCollector': function(aValue) { | 239 | 'appendRandomBitsToRandomBitsCollector': function(aValue) { |
244 | var collectedBits; | 240 | var collectedBits; |
245 | var numberOfRandomBitsCollected; | 241 | var numberOfRandomBitsCollected; |
246 | 242 | ||
247 | numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); | 243 | numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); |
248 | collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); | 244 | collectedBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); |
249 | this.setRandomBitsCollector(collectetBits); | 245 | this.setRandomBitsCollector(collectedBits); |
250 | numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); | 246 | numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); |
251 | 247 | ||
252 | if (numberOfRandomBitsCollected == 8) { | 248 | if (numberOfRandomBitsCollected == 8) { |
253 | this.updateGeneratorWithValue(collectetBits); | 249 | this.updateGeneratorWithValue(collectedBits); |
254 | numberOfRandomBitsCollected = 0; | 250 | numberOfRandomBitsCollected = 0; |
255 | this.setRandomBitsCollector(0); | 251 | this.setRandomBitsCollector(0); |
256 | } | 252 | } |
257 | 253 | ||
258 | this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) | 254 | this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) |
259 | }, | 255 | }, |
260 | 256 | ||
261 | //------------------------------------------------------------------------- | 257 | //------------------------------------------------------------------------- |
262 | 258 | ||
263 | 'numberOfRandomBitsCollected': function() { | 259 | 'numberOfRandomBitsCollected': function() { |
264 | return this._numberOfRandomBitsCollected; | 260 | return this._numberOfRandomBitsCollected; |
265 | }, | 261 | }, |
266 | 262 | ||
267 | 'setNumberOfRandomBitsCollected': function(aValue) { | 263 | 'setNumberOfRandomBitsCollected': function(aValue) { |
268 | this._numberOfRandomBitsCollected = aValue; | 264 | this._numberOfRandomBitsCollected = aValue; |
269 | }, | 265 | }, |
270 | 266 | ||
271 | //------------------------------------------------------------------------- | 267 | //------------------------------------------------------------------------- |
272 | 268 | ||
273 | 'collectEntropy': function(anEvent) { | 269 | 'collectEntropy': function(anEvent) { |
274 | var mouseLocation; | 270 | var mouseLocation; |
275 | var randomBit; | 271 | var randomBit; |
276 | var mask; | 272 | var mask; |
277 | 273 | ||
278 | mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); | 274 | mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); |
279 | 275 | ||
280 | mouseLocation = anEvent.mouse().client; | 276 | mouseLocation = anEvent.mouse().client; |
281 | randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); | 277 | randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); |
282 | this.appendRandomBitsToRandomBitsCollector(randomBit) | 278 | this.appendRandomBitsToRandomBitsCollector(randomBit) |
283 | }, | 279 | }, |
284 | 280 | ||
285 | //------------------------------------------------------------------------- | 281 | //------------------------------------------------------------------------- |
286 | 282 | ||
287 | 'numberOfRandomBits': function() { | 283 | 'numberOfRandomBits': function() { |
288 | return 1; | 284 | return 1; |
289 | }, | 285 | }, |
290 | 286 | ||
291 | //------------------------------------------------------------------------- | 287 | //------------------------------------------------------------------------- |
292 | |||
293 | 'pollingFrequency': function() { | ||
294 | return 10; | ||
295 | }, | ||
296 | |||
297 | //------------------------------------------------------------------------- | ||
298 | __syntaxFix__: "syntax fix" | 288 | __syntaxFix__: "syntax fix" |
299 | }); | 289 | }); |
300 | 290 | ||
301 | //***************************************************************************** | 291 | //***************************************************************************** |
302 | 292 | ||
303 | Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) { | 293 | Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) { |
304 | args = args || {}; | 294 | args = args || {}; |
305 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); | ||
306 | 295 | ||
307 | this._randomBitsCollector = 0; | 296 | this._intervalTime = args.intervalTime || 1000; |
308 | this._numberOfRandomBitsCollected = 0; | 297 | this._browserCrypto = args.browserCrypto; |
309 | 298 | ||
310 | MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy'); | 299 | Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); |
311 | 300 | ||
301 | this.collectEntropy(); | ||
312 | return this; | 302 | return this; |
313 | } | 303 | } |
314 | 304 | ||
315 | Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { | 305 | Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { |
316 | 306 | ||
317 | //------------------------------------------------------------------------- | 307 | 'intervalTime': function() { |
318 | 308 | return this._intervalTime; | |
319 | 'randomBitsCollector': function() { | ||
320 | return this._randomBitsCollector; | ||
321 | }, | ||
322 | |||
323 | 'setRandomBitsCollector': function(aValue) { | ||
324 | this._randomBitsCollector = aValue; | ||
325 | }, | 309 | }, |
326 | 310 | ||
327 | 'appendRandomBitToRandomBitsCollector': function(aValue) { | 311 | 'browserCrypto': function () { |
328 | var collectedBits; | 312 | return this._browserCrypto; |
329 | var numberOfRandomBitsCollected; | ||
330 | |||
331 | numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); | ||
332 | collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); | ||
333 | this.setRandomBitsCollector(collectetBits); | ||
334 | numberOfRandomBitsCollected ++; | ||
335 | |||
336 | if (numberOfRandomBitsCollected == 8) { | ||
337 | this.updateGeneratorWithValue(collectetBits); | ||
338 | numberOfRandomBitsCollected = 0; | ||
339 | this.setRandomBitsCollector(0); | ||
340 | } | ||
341 | |||
342 | this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) | ||
343 | }, | 313 | }, |
344 | 314 | ||
345 | //------------------------------------------------------------------------- | 315 | //------------------------------------------------------------------------- |
346 | 316 | ||
347 | 'numberOfRandomBitsCollected': function() { | 317 | 'collectEntropy': function() { |
348 | return this._numberOfRandomBitsCollected; | 318 | varbytesToCollect; |
349 | }, | ||
350 | |||
351 | 'setNumberOfRandomBitsCollected': function(aValue) { | ||
352 | this._numberOfRandomBitsCollected = aValue; | ||
353 | }, | ||
354 | 319 | ||
355 | //------------------------------------------------------------------------- | 320 | if (this.boostMode() == true) { |
321 | bytesToCollect = 64; | ||
322 | } else { | ||
323 | bytesToCollect = 8; | ||
324 | } | ||
356 | 325 | ||
357 | 'collectEntropy': function(anEvent) { | 326 | var randomValuesArray = new Uint8Array(bytesToCollect); |
358 | /* | 327 | this.browserCrypto().getRandomValues(randomValuesArray); |
359 | var mouseLocation; | 328 | for (var i = 0; i < randomValuesArray.length; i++) { |
360 | var randomBit; | 329 | this.updateGeneratorWithValue(randomValuesArray[i]); |
361 | 330 | } | |
362 | mouseLocation = anEvent.mouse().client; | ||
363 | |||
364 | randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1); | ||
365 | this.appendRandomBitToRandomBitsCollector(randomBit); | ||
366 | */ | ||
367 | }, | ||
368 | |||
369 | //------------------------------------------------------------------------- | ||
370 | 331 | ||
371 | 'numberOfRandomBits': function() { | 332 | setTimeout(this.collectEntropy, this.intervalTime()); |
372 | return 1; | ||
373 | }, | 333 | }, |
374 | 334 | ||
375 | //------------------------------------------------------------------------- | 335 | //------------------------------------------------------------------------- |
376 | |||
377 | 'pollingFrequency': function() { | ||
378 | return 10; | ||
379 | }, | ||
380 | |||
381 | //------------------------------------------------------------------------- | ||
382 | __syntaxFix__: "syntax fix" | 336 | __syntaxFix__: "syntax fix" |
383 | }); | 337 | }); |
384 | 338 | ||
385 | //############################################################################# | 339 | //############################################################################# |
386 | 340 | ||
387 | Clipperz.Crypto.PRNG.Fortuna = function(args) { | 341 | Clipperz.Crypto.PRNG.Fortuna = function(args) { |
388 | vari,c; | 342 | vari,c; |
389 | 343 | ||
390 | args = args || {}; | 344 | args = args || {}; |
391 | 345 | ||
392 | this._key = args.seed || null; | 346 | this._key = args.seed || null; |
393 | if (this._key == null) { | 347 | if (this._key == null) { |
394 | this._counter = 0; | 348 | this._counter = 0; |
395 | this._key = new Clipperz.ByteArray(); | 349 | this._key = new Clipperz.ByteArray(); |
396 | } else { | 350 | } else { |
397 | this._counter = 1; | 351 | this._counter = 1; |
398 | } | 352 | } |
399 | 353 | ||
400 | this._aesKey = null; | 354 | this._aesKey = null; |
401 | 355 | ||
402 | this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; | 356 | this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; |
403 | this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; | 357 | this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; |
404 | 358 | ||
405 | this._accumulators = []; | 359 | this._accumulators = []; |
406 | c = this.numberOfEntropyAccumulators(); | 360 | c = this.numberOfEntropyAccumulators(); |
407 | for (i=0; i<c; i++) { | 361 | for (i=0; i<c; i++) { |
408 | this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); | 362 | this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); |
409 | } | 363 | } |
410 | 364 | ||
411 | this._randomnessSources = []; | 365 | this._randomnessSources = []; |
412 | this._reseedCounter = 0; | 366 | this._reseedCounter = 0; |
413 | 367 | ||
414 | return this; | 368 | return this; |
415 | } | 369 | } |
416 | 370 | ||
417 | Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { | 371 | Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { |
418 | 372 | ||
419 | 'toString': function() { | 373 | 'toString': function() { |
420 | return "Clipperz.Crypto.PRNG.Fortuna"; | 374 | return "Clipperz.Crypto.PRNG.Fortuna"; |
421 | }, | 375 | }, |
422 | 376 | ||
423 | //------------------------------------------------------------------------- | 377 | //------------------------------------------------------------------------- |
424 | 378 | ||
425 | 'key': function() { | 379 | 'key': function() { |
426 | return this._key; | 380 | return this._key; |
427 | }, | 381 | }, |
428 | 382 | ||
429 | 'setKey': function(aValue) { | 383 | 'setKey': function(aValue) { |
430 | this._key = aValue; | 384 | this._key = aValue; |
431 | this._aesKey = null; | 385 | this._aesKey = null; |
432 | }, | 386 | }, |
433 | 387 | ||
434 | 'aesKey': function() { | 388 | 'aesKey': function() { |
435 | if (this._aesKey == null) { | 389 | if (this._aesKey == null) { |
436 | this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()}); | 390 | this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()}); |
437 | } | 391 | } |
438 | 392 | ||
439 | return this._aesKey; | 393 | return this._aesKey; |
440 | }, | 394 | }, |
441 | 395 | ||
442 | 'accumulators': function() { | 396 | 'accumulators': function() { |
443 | return this._accumulators; | 397 | return this._accumulators; |
444 | }, | 398 | }, |
445 | 399 | ||
446 | 'firstPoolReseedLevel': function() { | 400 | 'firstPoolReseedLevel': function() { |
447 | return this._firstPoolReseedLevel; | 401 | return this._firstPoolReseedLevel; |
448 | }, | 402 | }, |
449 | 403 | ||
450 | //------------------------------------------------------------------------- | 404 | //------------------------------------------------------------------------- |
451 | 405 | ||
452 | 'reseedCounter': function() { | 406 | 'reseedCounter': function() { |
453 | return this._reseedCounter; | 407 | return this._reseedCounter; |
454 | }, | 408 | }, |
455 | 409 | ||
456 | 'incrementReseedCounter': function() { | 410 | 'incrementReseedCounter': function() { |
457 | this._reseedCounter = this._reseedCounter +1; | 411 | this._reseedCounter = this._reseedCounter +1; |
458 | }, | 412 | }, |
459 | 413 | ||
460 | //------------------------------------------------------------------------- | 414 | //------------------------------------------------------------------------- |
461 | 415 | ||
462 | 'reseed': function() { | 416 | 'reseed': function() { |
463 | varnewKeySeed; | 417 | varnewKeySeed; |
464 | var reseedCounter; | 418 | var reseedCounter; |
465 | varreseedCounterMask; | 419 | varreseedCounterMask; |
466 | var i, c; | 420 | var i, c; |
467 | 421 | ||
468 | newKeySeed = this.key(); | 422 | newKeySeed = this.key(); |
469 | this.incrementReseedCounter(); | 423 | this.incrementReseedCounter(); |
470 | reseedCounter = this.reseedCounter(); | 424 | reseedCounter = this.reseedCounter(); |
471 | 425 | ||
472 | c = this.numberOfEntropyAccumulators(); | 426 | c = this.numberOfEntropyAccumulators(); |
473 | reseedCounterMask = 0xffffffff >>> (32 - c); | 427 | reseedCounterMask = 0xffffffff >>> (32 - c); |
474 | for (i=0; i<c; i++) { | 428 | for (i=0; i<c; i++) { |
475 | if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) { | 429 | if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) { |
476 | newKeySeed.appendBlock(this.accumulators()[i].stack()); | 430 | newKeySeed.appendBlock(this.accumulators()[i].stack()); |
477 | this.accumulators()[i].resetStack(); | 431 | this.accumulators()[i].resetStack(); |
478 | } | 432 | } |
479 | } | 433 | } |
480 | 434 | ||
481 | if (reseedCounter == 1) { | 435 | if (reseedCounter == 1) { |
482 | c = this.randomnessSources().length; | 436 | c = this.randomnessSources().length; |
483 | for (i=0; i<c; i++) { | 437 | for (i=0; i<c; i++) { |
484 | this.randomnessSources()[i].setBoostMode(false); | 438 | this.randomnessSources()[i].setBoostMode(false); |
485 | } | 439 | } |
486 | } | 440 | } |
487 | 441 | ||
488 | this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed)); | 442 | this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed)); |
489 | if (reseedCounter == 1) { | 443 | if (reseedCounter == 1) { |
490 | Clipperz.log("### PRNG.readyToGenerateRandomBytes"); | 444 | Clipperz.log("### PRNG.readyToGenerateRandomBytes"); |
491 | MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes'); | 445 | MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes'); |
492 | } | 446 | } |
493 | MochiKit.Signal.signal(this, 'reseeded'); | 447 | MochiKit.Signal.signal(this, 'reseeded'); |
494 | }, | 448 | }, |
495 | 449 | ||
496 | //------------------------------------------------------------------------- | 450 | //------------------------------------------------------------------------- |
497 | 451 | ||
498 | 'isReadyToGenerateRandomValues': function() { | 452 | 'isReadyToGenerateRandomValues': function() { |
499 | return this.reseedCounter() != 0; | 453 | return this.reseedCounter() != 0; |
500 | }, | 454 | }, |
501 | 455 | ||
502 | //------------------------------------------------------------------------- | 456 | //------------------------------------------------------------------------- |
503 | 457 | ||
504 | 'entropyLevel': function() { | 458 | 'entropyLevel': function() { |
505 | return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel()); | 459 | return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel()); |
506 | }, | 460 | }, |
507 | 461 | ||
508 | //------------------------------------------------------------------------- | 462 | //------------------------------------------------------------------------- |
509 | 463 | ||
510 | 'counter': function() { | 464 | 'counter': function() { |
511 | return this._counter; | 465 | return this._counter; |
512 | }, | 466 | }, |
513 | 467 | ||
514 | 'incrementCounter': function() { | 468 | 'incrementCounter': function() { |
515 | this._counter += 1; | 469 | this._counter += 1; |
516 | }, | 470 | }, |
517 | 471 | ||
518 | 'counterBlock': function() { | 472 | 'counterBlock': function() { |
519 | var result; | 473 | var result; |
520 | 474 | ||
521 | result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0); | 475 | result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0); |
522 | 476 | ||
523 | return result; | 477 | return result; |
524 | }, | 478 | }, |
525 | 479 | ||
526 | //------------------------------------------------------------------------- | 480 | //------------------------------------------------------------------------- |
527 | 481 | ||
528 | 'getRandomBlock': function() { | 482 | 'getRandomBlock': function() { |
529 | var result; | 483 | var result; |
530 | 484 | ||
531 | result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues())); | 485 | result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues())); |
532 | this.incrementCounter(); | 486 | this.incrementCounter(); |
533 | 487 | ||
534 | return result; | 488 | return result; |
535 | }, | 489 | }, |
536 | 490 | ||
537 | //------------------------------------------------------------------------- | 491 | //------------------------------------------------------------------------- |
538 | 492 | ||
539 | 'getRandomBytes': function(aSize) { | 493 | 'getRandomBytes': function(aSize) { |
540 | var result; | 494 | var result; |
541 | 495 | ||
542 | if (this.isReadyToGenerateRandomValues()) { | 496 | if (this.isReadyToGenerateRandomValues()) { |
543 | var i,c; | 497 | var i,c; |
544 | var newKey; | 498 | var newKey; |
545 | 499 | ||
546 | result = new Clipperz.ByteArray(); | 500 | result = new Clipperz.ByteArray(); |
547 | 501 | ||
548 | c = Math.ceil(aSize / (128 / 8)); | 502 | c = Math.ceil(aSize / (128 / 8)); |
549 | for (i=0; i<c; i++) { | 503 | for (i=0; i<c; i++) { |
550 | result.appendBlock(this.getRandomBlock()); | 504 | result.appendBlock(this.getRandomBlock()); |
551 | } | 505 | } |
552 | 506 | ||
553 | if (result.length() != aSize) { | 507 | if (result.length() != aSize) { |
554 | result = result.split(0, aSize); | 508 | result = result.split(0, aSize); |
555 | } | 509 | } |
556 | 510 | ||
557 | newKey = this.getRandomBlock().appendBlock(this.getRandomBlock()); | 511 | newKey = this.getRandomBlock().appendBlock(this.getRandomBlock()); |
558 | this.setKey(newKey); | 512 | this.setKey(newKey); |
559 | } else { | 513 | } else { |
560 | Clipperz.logWarning("Fortuna generator has not enough entropy, yet!"); | 514 | Clipperz.logWarning("Fortuna generator has not enough entropy, yet!"); |
561 | throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy; | 515 | throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy; |
562 | } | 516 | } |
563 | 517 | ||
564 | return result; | 518 | return result; |
565 | }, | 519 | }, |
566 | 520 | ||
567 | //------------------------------------------------------------------------- | 521 | //------------------------------------------------------------------------- |
568 | 522 | ||
569 | 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) { | 523 | 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) { |
570 | varselectedAccumulator; | 524 | varselectedAccumulator; |
571 | 525 | ||
572 | selectedAccumulator = this.accumulators()[aPoolId]; | 526 | selectedAccumulator = this.accumulators()[aPoolId]; |
573 | selectedAccumulator.addRandomByte(aRandomValue); | 527 | selectedAccumulator.addRandomByte(aRandomValue); |
574 | 528 | ||
575 | if (aPoolId == 0) { | 529 | if (aPoolId == 0) { |
576 | MochiKit.Signal.signal(this, 'addedRandomByte') | 530 | MochiKit.Signal.signal(this, 'addedRandomByte') |
577 | if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) { | 531 | if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) { |
578 | this.reseed(); | 532 | this.reseed(); |
579 | } | 533 | } |
580 | } | 534 | } |
581 | }, | 535 | }, |
582 | 536 | ||
583 | //------------------------------------------------------------------------- | 537 | //------------------------------------------------------------------------- |
584 | 538 | ||
585 | 'numberOfEntropyAccumulators': function() { | 539 | 'numberOfEntropyAccumulators': function() { |
586 | return this._numberOfEntropyAccumulators; | 540 | return this._numberOfEntropyAccumulators; |
587 | }, | 541 | }, |
588 | 542 | ||
589 | //------------------------------------------------------------------------- | 543 | //------------------------------------------------------------------------- |
590 | 544 | ||
591 | 'randomnessSources': function() { | 545 | 'randomnessSources': function() { |
592 | return this._randomnessSources; | 546 | return this._randomnessSources; |
593 | }, | 547 | }, |
594 | 548 | ||
595 | 'addRandomnessSource': function(aRandomnessSource) { | 549 | 'addRandomnessSource': function(aRandomnessSource) { |
596 | aRandomnessSource.setGenerator(this); | 550 | aRandomnessSource.setGenerator(this); |
597 | aRandomnessSource.setSourceId(this.randomnessSources().length); | 551 | aRandomnessSource.setSourceId(this.randomnessSources().length); |
598 | this.randomnessSources().push(aRandomnessSource); | 552 | this.randomnessSources().push(aRandomnessSource); |
599 | 553 | ||
600 | if (this.isReadyToGenerateRandomValues() == false) { | 554 | if (this.isReadyToGenerateRandomValues() == false) { |
601 | aRandomnessSource.setBoostMode(true); | 555 | aRandomnessSource.setBoostMode(true); |
602 | } | 556 | } |
603 | }, | 557 | }, |
604 | 558 | ||
605 | //------------------------------------------------------------------------- | 559 | //------------------------------------------------------------------------- |
606 | 560 | ||
607 | 'deferredEntropyCollection': function(aValue) { | 561 | 'deferredEntropyCollection': function(aValue) { |
608 | var result; | 562 | var result; |
609 | 563 | ||
610 | 564 | ||
611 | if (this.isReadyToGenerateRandomValues()) { | 565 | if (this.isReadyToGenerateRandomValues()) { |
612 | result = aValue; | 566 | result = aValue; |
613 | } else { | 567 | } else { |
614 | var deferredResult; | 568 | var deferredResult; |
615 | 569 | ||
616 | deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection"); | 570 | deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection"); |
617 | deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); | 571 | deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); |
618 | MochiKit.Signal.connect(this, | 572 | MochiKit.Signal.connect(this, |
619 | 'readyToGenerateRandomBytes', | 573 | 'readyToGenerateRandomBytes', |
620 | deferredResult, | 574 | deferredResult, |
621 | 'callback'); | 575 | 'callback'); |
622 | 576 | ||
623 | result = deferredResult; | 577 | result = deferredResult; |
624 | } | 578 | } |
625 | 579 | ||
626 | return result; | 580 | return result; |
627 | }, | 581 | }, |
628 | 582 | ||
629 | //------------------------------------------------------------------------- | 583 | //------------------------------------------------------------------------- |
630 | 584 | ||
631 | 'fastEntropyAccumulationForTestingPurpose': function() { | 585 | 'fastEntropyAccumulationForTestingPurpose': function() { |
632 | while (! this.isReadyToGenerateRandomValues()) { | 586 | while (! this.isReadyToGenerateRandomValues()) { |
633 | this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); | 587 | this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); |
634 | } | 588 | } |
635 | }, | 589 | }, |
636 | 590 | ||
637 | //------------------------------------------------------------------------- | 591 | //------------------------------------------------------------------------- |
638 | 592 | /* | |
639 | 'dump': function(appendToDoc) { | 593 | 'dump': function(appendToDoc) { |
640 | var tbl; | 594 | var tbl; |
641 | var i,c; | 595 | var i,c; |
642 | 596 | ||
643 | tbl = document.createElement("table"); | 597 | tbl = document.createElement("table"); |
644 | tbl.border = 0; | 598 | tbl.border = 0; |
645 | with (tbl.style) { | 599 | with (tbl.style) { |
646 | border = "1px solid lightgrey"; | 600 | border = "1px solid lightgrey"; |
647 | fontFamily = 'Helvetica, Arial, sans-serif'; | 601 | fontFamily = 'Helvetica, Arial, sans-serif'; |
648 | fontSize = '8pt'; | 602 | fontSize = '8pt'; |
649 | //borderCollapse = "collapse"; | 603 | //borderCollapse = "collapse"; |
650 | } | 604 | } |
651 | var hdr = tbl.createTHead(); | 605 | var hdr = tbl.createTHead(); |
652 | var hdrtr = hdr.insertRow(0); | 606 | var hdrtr = hdr.insertRow(0); |
653 | // document.createElement("tr"); | 607 | // document.createElement("tr"); |
654 | { | 608 | { |
655 | var ntd; | 609 | var ntd; |
656 | 610 | ||
657 | ntd = hdrtr.insertCell(0); | 611 | ntd = hdrtr.insertCell(0); |
658 | ntd.style.borderBottom = "1px solid lightgrey"; | 612 | ntd.style.borderBottom = "1px solid lightgrey"; |
659 | ntd.style.borderRight = "1px solid lightgrey"; | 613 | ntd.style.borderRight = "1px solid lightgrey"; |
660 | ntd.appendChild(document.createTextNode("#")); | 614 | ntd.appendChild(document.createTextNode("#")); |
661 | 615 | ||
662 | ntd = hdrtr.insertCell(1); | 616 | ntd = hdrtr.insertCell(1); |
663 | ntd.style.borderBottom = "1px solid lightgrey"; | 617 | ntd.style.borderBottom = "1px solid lightgrey"; |
664 | ntd.style.borderRight = "1px solid lightgrey"; | 618 | ntd.style.borderRight = "1px solid lightgrey"; |
665 | ntd.appendChild(document.createTextNode("s")); | 619 | ntd.appendChild(document.createTextNode("s")); |
666 | 620 | ||
667 | ntd = hdrtr.insertCell(2); | 621 | ntd = hdrtr.insertCell(2); |
668 | ntd.colSpan = this.firstPoolReseedLevel(); | 622 | ntd.colSpan = this.firstPoolReseedLevel(); |
669 | ntd.style.borderBottom = "1px solid lightgrey"; | 623 | ntd.style.borderBottom = "1px solid lightgrey"; |
670 | ntd.style.borderRight = "1px solid lightgrey"; | 624 | ntd.style.borderRight = "1px solid lightgrey"; |
671 | ntd.appendChild(document.createTextNode("base values")); | 625 | ntd.appendChild(document.createTextNode("base values")); |
672 | 626 | ||
673 | ntd = hdrtr.insertCell(3); | 627 | ntd = hdrtr.insertCell(3); |
674 | ntd.colSpan = 20; | 628 | ntd.colSpan = 20; |
675 | ntd.style.borderBottom = "1px solid lightgrey"; | 629 | ntd.style.borderBottom = "1px solid lightgrey"; |
676 | ntd.appendChild(document.createTextNode("extra values")); | 630 | ntd.appendChild(document.createTextNode("extra values")); |
677 | 631 | ||
678 | } | 632 | } |
679 | 633 | ||
680 | c = this.accumulators().length; | 634 | c = this.accumulators().length; |
681 | for (i=0; i<c ; i++) { | 635 | for (i=0; i<c ; i++) { |
682 | varcurrentAccumulator; | 636 | varcurrentAccumulator; |
683 | var bdytr; | 637 | var bdytr; |
684 | var bdytd; | 638 | var bdytd; |
685 | var ii, cc; | 639 | var ii, cc; |
686 | 640 | ||
687 | currentAccumulator = this.accumulators()[i] | 641 | currentAccumulator = this.accumulators()[i] |
688 | 642 | ||
689 | bdytr = tbl.insertRow(true); | 643 | bdytr = tbl.insertRow(true); |
690 | 644 | ||
691 | bdytd = bdytr.insertCell(0); | 645 | bdytd = bdytr.insertCell(0); |
692 | bdytd.style.borderRight = "1px solid lightgrey"; | 646 | bdytd.style.borderRight = "1px solid lightgrey"; |
693 | bdytd.style.color = "lightgrey"; | 647 | bdytd.style.color = "lightgrey"; |
694 | bdytd.appendChild(document.createTextNode("" + i)); | 648 | bdytd.appendChild(document.createTextNode("" + i)); |
695 | 649 | ||
696 | bdytd = bdytr.insertCell(1); | 650 | bdytd = bdytr.insertCell(1); |
697 | bdytd.style.borderRight = "1px solid lightgrey"; | 651 | bdytd.style.borderRight = "1px solid lightgrey"; |
698 | bdytd.style.color = "gray"; | 652 | bdytd.style.color = "gray"; |
699 | bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); | 653 | bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); |
700 | 654 | ||
701 | 655 | ||
702 | cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); | 656 | cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); |
703 | for (ii=0; ii<cc; ii++) { | 657 | for (ii=0; ii<cc; ii++) { |
704 | var cellText; | 658 | var cellText; |
705 | 659 | ||
706 | bdytd = bdytr.insertCell(ii + 2); | 660 | bdytd = bdytr.insertCell(ii + 2); |
707 | 661 | ||
708 | if (ii < currentAccumulator.stack().length()) { | 662 | if (ii < currentAccumulator.stack().length()) { |
709 | cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); | 663 | cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); |
710 | } else { | 664 | } else { |
711 | cellText = "_"; | 665 | cellText = "_"; |
712 | } | 666 | } |
713 | 667 | ||
714 | if (ii == (this.firstPoolReseedLevel() - 1)) { | 668 | if (ii == (this.firstPoolReseedLevel() - 1)) { |
715 | bdytd.style.borderRight = "1px solid lightgrey"; | 669 | bdytd.style.borderRight = "1px solid lightgrey"; |
716 | } | 670 | } |
717 | 671 | ||
718 | bdytd.appendChild(document.createTextNode(cellText)); | 672 | bdytd.appendChild(document.createTextNode(cellText)); |
719 | } | 673 | } |
720 | 674 | ||
721 | } | 675 | } |
722 | 676 | ||
723 | 677 | ||
724 | if (appendToDoc) { | 678 | if (appendToDoc) { |
725 | var ne = document.createElement("div"); | 679 | var ne = document.createElement("div"); |
726 | ne.id = "entropyGeneratorStatus"; | 680 | ne.id = "entropyGeneratorStatus"; |
727 | with (ne.style) { | 681 | with (ne.style) { |
728 | fontFamily = "Courier New, monospace"; | 682 | fontFamily = "Courier New, monospace"; |
729 | fontSize = "12px"; | 683 | fontSize = "12px"; |
730 | lineHeight = "16px"; | 684 | lineHeight = "16px"; |
731 | borderTop = "1px solid black"; | 685 | borderTop = "1px solid black"; |
732 | padding = "10px"; | 686 | padding = "10px"; |
733 | } | 687 | } |
734 | if (document.getElementById(ne.id)) { | 688 | if (document.getElementById(ne.id)) { |
735 | MochiKit.DOM.swapDOM(ne.id, ne); | 689 | MochiKit.DOM.swapDOM(ne.id, ne); |
736 | } else { | 690 | } else { |
737 | document.body.appendChild(ne); | 691 | document.body.appendChild(ne); |
738 | } | 692 | } |
739 | ne.appendChild(tbl); | 693 | ne.appendChild(tbl); |
740 | } | 694 | } |
741 | 695 | ||
742 | return tbl; | 696 | return tbl; |
743 | }, | 697 | }, |
744 | 698 | */ | |
745 | //----------------------------------------------------------------------------- | 699 | //----------------------------------------------------------------------------- |
746 | __syntaxFix__: "syntax fix" | 700 | __syntaxFix__: "syntax fix" |
747 | }); | 701 | }); |
748 | 702 | ||
749 | //############################################################################# | 703 | //############################################################################# |
750 | 704 | ||
751 | Clipperz.Crypto.PRNG.Random = function(args) { | 705 | Clipperz.Crypto.PRNG.Random = function(args) { |
752 | args = args || {}; | 706 | args = args || {}; |
753 | //MochiKit.Base.bindMethods(this); | 707 | //MochiKit.Base.bindMethods(this); |
754 | 708 | ||
755 | return this; | 709 | return this; |
756 | } | 710 | } |
757 | 711 | ||
758 | Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { | 712 | Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { |
759 | 713 | ||
760 | 'toString': function() { | 714 | 'toString': function() { |
761 | return "Clipperz.Crypto.PRNG.Random"; | 715 | return "Clipperz.Crypto.PRNG.Random"; |
762 | }, | 716 | }, |
763 | 717 | ||
764 | //------------------------------------------------------------------------- | 718 | //------------------------------------------------------------------------- |
765 | 719 | ||
766 | 'getRandomBytes': function(aSize) { | 720 | 'getRandomBytes': function(aSize) { |
767 | //Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); | 721 | //Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); |
768 | varresult; | 722 | varresult; |
769 | var i,c; | 723 | var i,c; |
770 | 724 | ||
771 | result = new Clipperz.ByteArray() | 725 | result = new Clipperz.ByteArray() |
772 | c = aSize || 1; | 726 | c = aSize || 1; |
773 | for (i=0; i<c; i++) { | 727 | for (i=0; i<c; i++) { |
774 | result.appendByte((Math.random()*255) & 0xff); | 728 | result.appendByte((Math.random()*255) & 0xff); |
775 | } | 729 | } |
776 | 730 | ||
777 | //Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); | 731 | //Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); |
778 | return result; | 732 | return result; |
779 | }, | 733 | }, |
780 | 734 | ||
781 | //------------------------------------------------------------------------- | 735 | //------------------------------------------------------------------------- |
782 | __syntaxFix__: "syntax fix" | 736 | __syntaxFix__: "syntax fix" |
783 | }); | 737 | }); |
784 | 738 | ||
785 | //############################################################################# | 739 | //############################################################################# |
786 | 740 | ||
787 | _clipperz_crypt_prng_defaultPRNG = null; | 741 | var _clipperz_crypt_prng_defaultPRNG = null; |
788 | 742 | ||
789 | Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { | 743 | Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { |
790 | if (_clipperz_crypt_prng_defaultPRNG == null) { | 744 | if (_clipperz_crypt_prng_defaultPRNG == null) { |
791 | _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); | 745 | _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); |
792 | 746 | ||
793 | //............................................................. | 747 | //............................................................. |
794 | // | 748 | // |
795 | // TimeRandomnessSource | 749 | // TimeRandomnessSource |
796 | // | 750 | // |
797 | //............................................................. | 751 | //............................................................. |
798 | { | 752 | { |
799 | var newRandomnessSource; | 753 | var newRandomnessSource; |
800 | 754 | ||
801 | newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); | 755 | newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); |
802 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | 756 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); |
803 | } | 757 | } |
804 | 758 | ||
805 | //............................................................. | 759 | //............................................................. |
806 | // | 760 | // |
807 | // MouseRandomnessSource | 761 | // MouseRandomnessSource |
808 | // | 762 | // |
809 | //............................................................. | 763 | //............................................................. |
810 | { | 764 | { |
811 | varnewRandomnessSource; | 765 | varnewRandomnessSource; |
812 | 766 | ||
813 | newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); | 767 | newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); |
814 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | 768 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); |
815 | } | 769 | } |
816 | 770 | ||
817 | //............................................................. | 771 | //............................................................. |
818 | // | 772 | // |
819 | // KeyboardRandomnessSource | 773 | // CryptoRandomRandomnessSource |
820 | // | 774 | // |
821 | //............................................................. | 775 | //............................................................. |
822 | { | 776 | { |
823 | varnewRandomnessSource; | 777 | varnewRandomnessSource; |
778 | varbrowserCrypto; | ||
824 | 779 | ||
825 | newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource(); | 780 | if (window.crypto && window.crypto.getRandomValues) { |
826 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | 781 | browserCrypto = window.crypto; |
782 | } else if (window.msCrypto && window.msCrypto.getRandomValues) { | ||
783 | browserCrypto = window.msCrypto; | ||
784 | } else { | ||
785 | browserCrypto = null; | ||
786 | } | ||
787 | |||
788 | if (browserCrypto != null) { | ||
789 | newRandomnessSource = new Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource({'browserCrypto':browserCrypto}); | ||
790 | _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); | ||
791 | } | ||
827 | } | 792 | } |
828 | |||
829 | } | 793 | } |
830 | 794 | ||
831 | return _clipperz_crypt_prng_defaultPRNG; | 795 | return _clipperz_crypt_prng_defaultPRNG; |
832 | }; | 796 | }; |
833 | 797 | ||
834 | //############################################################################# | 798 | //############################################################################# |
835 | 799 | ||
836 | Clipperz.Crypto.PRNG.exception = { | 800 | Clipperz.Crypto.PRNG.exception = { |
837 | NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") | 801 | NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") |
838 | }; | 802 | }; |
839 | 803 | ||
840 | 804 | ||
841 | MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); | 805 | MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); |
diff --git a/frontend/gamma/js/Clipperz/Crypto/SRP.js b/frontend/gamma/js/Clipperz/Crypto/SRP.js index 597e72d..6898dfb 100644 --- a/frontend/gamma/js/Clipperz/Crypto/SRP.js +++ b/frontend/gamma/js/Clipperz/Crypto/SRP.js | |||
@@ -1,316 +1,345 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { | 24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { |
25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; | 25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; |
26 | } | 26 | } |
27 | 27 | ||
28 | try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { | 28 | try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { |
29 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; | 29 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; |
30 | } | 30 | } |
31 | 31 | ||
32 | try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { | 32 | try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { |
33 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; | 33 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; |
34 | } | 34 | } |
35 | 35 | ||
36 | if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } | 36 | if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } |
37 | 37 | ||
38 | Clipperz.Crypto.SRP.VERSION = "0.1"; | 38 | Clipperz.Crypto.SRP.VERSION = "0.1"; |
39 | Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; | 39 | Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; |
40 | 40 | ||
41 | //############################################################################# | 41 | //############################################################################# |
42 | 42 | ||
43 | MochiKit.Base.update(Clipperz.Crypto.SRP, { | 43 | MochiKit.Base.update(Clipperz.Crypto.SRP, { |
44 | 44 | ||
45 | '_n': null, | 45 | '_n': null, |
46 | '_g': null, | 46 | '_g': null, |
47 | '_k': null, | ||
48 | |||
47 | //------------------------------------------------------------------------- | 49 | //------------------------------------------------------------------------- |
48 | 50 | ||
49 | 'n': function() { | 51 | 'n': function() { |
50 | if (Clipperz.Crypto.SRP._n == null) { | 52 | if (Clipperz.Crypto.SRP._n == null) { |
51 | Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); | 53 | Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); |
52 | } | 54 | } |
53 | 55 | ||
54 | return Clipperz.Crypto.SRP._n; | 56 | return Clipperz.Crypto.SRP._n; |
55 | }, | 57 | }, |
56 | 58 | ||
57 | //------------------------------------------------------------------------- | 59 | //------------------------------------------------------------------------- |
58 | 60 | ||
59 | 'g': function() { | 61 | 'g': function() { |
60 | if (Clipperz.Crypto.SRP._g == null) { | 62 | if (Clipperz.Crypto.SRP._g == null) { |
61 | Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation) | 63 | Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation) |
62 | } | 64 | } |
63 | 65 | ||
64 | return Clipperz.Crypto.SRP._g; | 66 | return Clipperz.Crypto.SRP._g; |
65 | }, | 67 | }, |
66 | 68 | ||
69 | 'k': function() { | ||
70 | if (Clipperz.Crypto.SRP._k == null) { | ||
71 | // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16); | ||
72 | Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16); | ||
73 | } | ||
74 | |||
75 | return Clipperz.Crypto.SRP._k; | ||
76 | }, | ||
77 | |||
67 | //----------------------------------------------------------------------------- | 78 | //----------------------------------------------------------------------------- |
68 | 79 | ||
69 | 'exception': { | 80 | 'exception': { |
70 | 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") | 81 | 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") |
71 | }, | 82 | }, |
72 | 83 | ||
73 | //------------------------------------------------------------------------- | 84 | //------------------------------------------------------------------------- |
74 | __syntaxFix__: "syntax fix" | 85 | __syntaxFix__: "syntax fix" |
75 | 86 | ||
76 | }); | 87 | }); |
77 | 88 | ||
78 | //############################################################################# | 89 | //############################################################################# |
79 | // | 90 | // |
80 | // S R P C o n n e c t i o n version 1.0 | 91 | // S R P C o n n e c t i o n version 1.0 |
81 | // | 92 | // |
82 | //============================================================================= | 93 | //============================================================================= |
83 | Clipperz.Crypto.SRP.Connection = function (args) { | 94 | Clipperz.Crypto.SRP.Connection = function (args) { |
84 | args = args || {}; | 95 | args = args || {}; |
85 | 96 | ||
86 | this._C = args.C; | 97 | this._C = args.C; |
87 | this._P = args.P; | 98 | this._P = args.P; |
88 | this.hash = args.hash; | 99 | this.hash = args.hash; |
89 | 100 | ||
90 | this._a = null; | 101 | this._a = null; |
91 | this._A = null; | 102 | this._A = null; |
92 | 103 | ||
93 | this._s = null; | 104 | this._s = null; |
94 | this._B = null; | 105 | this._B = null; |
95 | 106 | ||
96 | this._x = null; | 107 | this._x = null; |
97 | 108 | ||
98 | this._u = null; | 109 | this._u = null; |
99 | this._K = null; | 110 | this._K = null; |
100 | this._M1 = null; | 111 | this._M1 = null; |
101 | this._M2 = null; | 112 | this._M2 = null; |
102 | 113 | ||
103 | this._sessionKey = null; | 114 | this._sessionKey = null; |
104 | 115 | ||
105 | return this; | 116 | return this; |
106 | } | 117 | } |
107 | 118 | ||
108 | Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { | 119 | Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { |
109 | 120 | ||
110 | 'toString': function () { | 121 | 'toString': function () { |
111 | return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); | 122 | return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); |
112 | }, | 123 | }, |
113 | 124 | ||
114 | //------------------------------------------------------------------------- | 125 | //------------------------------------------------------------------------- |
115 | 126 | ||
116 | 'C': function () { | 127 | 'C': function () { |
117 | return this._C; | 128 | return this._C; |
118 | }, | 129 | }, |
119 | 130 | ||
120 | //------------------------------------------------------------------------- | 131 | //------------------------------------------------------------------------- |
121 | 132 | ||
122 | 'P': function () { | 133 | 'P': function () { |
123 | return this._P; | 134 | return this._P; |
124 | }, | 135 | }, |
125 | 136 | ||
126 | //------------------------------------------------------------------------- | 137 | //------------------------------------------------------------------------- |
127 | 138 | ||
128 | 'a': function () { | 139 | 'a': function () { |
129 | if (this._a == null) { | 140 | if (this._a == null) { |
130 | this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); | 141 | this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); |
131 | // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); | 142 | // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); |
132 | } | 143 | } |
133 | 144 | ||
134 | return this._a; | 145 | return this._a; |
135 | }, | 146 | }, |
136 | 147 | ||
137 | //------------------------------------------------------------------------- | 148 | //------------------------------------------------------------------------- |
138 | 149 | ||
139 | 'A': function () { | 150 | 'A': function () { |
140 | if (this._A == null) { | 151 | if (this._A == null) { |
141 | //Warning: this value should be strictly greater than zero: how should we perform this check? | 152 | //Warning: this value should be strictly greater than zero |
142 | this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); | 153 | this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); |
143 | 154 | if (this._A.equals(0) || negative(this._A)) { | |
144 | if (this._A.equals(0)) { | ||
145 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0."); | 155 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0."); |
146 | throw Clipperz.Crypto.SRP.exception.InvalidValue; | 156 | throw Clipperz.Crypto.SRP.exception.InvalidValue; |
147 | } | 157 | } |
148 | } | 158 | } |
149 | 159 | ||
150 | return this._A; | 160 | return this._A; |
151 | }, | 161 | }, |
152 | 162 | ||
153 | //------------------------------------------------------------------------- | 163 | //------------------------------------------------------------------------- |
154 | 164 | ||
155 | 's': function () { | 165 | 's': function () { |
156 | return this._s; | 166 | return this._s; |
157 | }, | 167 | }, |
158 | 168 | ||
159 | 'set_s': function(aValue) { | 169 | 'set_s': function(aValue) { |
160 | this._s = aValue; | 170 | this._s = aValue; |
161 | }, | 171 | }, |
162 | 172 | ||
163 | //------------------------------------------------------------------------- | 173 | //------------------------------------------------------------------------- |
164 | 174 | ||
165 | 'B': function () { | 175 | 'B': function () { |
166 | return this._B; | 176 | return this._B; |
167 | }, | 177 | }, |
168 | 178 | ||
169 | 'set_B': function(aValue) { | 179 | 'set_B': function(aValue) { |
170 | //Warning: this value should be strictly greater than zero: how should we perform this check? | 180 | //Warning: this value should be strictly greater than zero |
171 | if (! aValue.equals(0)) { | 181 | this._B = aValue; |
172 | this._B = aValue; | 182 | if (this._B.equals(0) || negative(this._B)) { |
173 | } else { | ||
174 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0."); | 183 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0."); |
175 | throw Clipperz.Crypto.SRP.exception.InvalidValue; | 184 | throw Clipperz.Crypto.SRP.exception.InvalidValue; |
176 | } | 185 | } |
177 | }, | 186 | }, |
178 | 187 | ||
179 | //------------------------------------------------------------------------- | 188 | //------------------------------------------------------------------------- |
180 | 189 | ||
181 | 'x': function () { | 190 | 'x': function () { |
182 | if (this._x == null) { | 191 | if (this._x == null) { |
183 | this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); | 192 | this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); |
184 | } | 193 | } |
185 | 194 | ||
186 | return this._x; | 195 | return this._x; |
187 | }, | 196 | }, |
188 | 197 | ||
189 | //------------------------------------------------------------------------- | 198 | //------------------------------------------------------------------------- |
190 | 199 | ||
191 | 'u': function () { | 200 | 'u': function () { |
192 | if (this._u == null) { | 201 | if (this._u == null) { |
193 | this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16); | 202 | this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.A().asString() + this.B().asString()), 16); |
194 | } | 203 | } |
195 | 204 | ||
196 | return this._u; | 205 | return this._u; |
197 | }, | 206 | }, |
198 | 207 | ||
199 | //------------------------------------------------------------------------- | 208 | //------------------------------------------------------------------------- |
200 | 209 | ||
201 | 'S': function () { | 210 | 'S': function () { |
202 | if (this._S == null) { | 211 | if (this._S == null) { |
203 | var bigint; | 212 | var bigint; |
204 | varsrp; | 213 | varsrp; |
205 | 214 | ||
206 | bigint = Clipperz.Crypto.BigInt; | 215 | bigint = Clipperz.Crypto.BigInt; |
207 | srp = Clipperz.Crypto.SRP; | 216 | srp = Clipperz.Crypto.SRP; |
208 | 217 | ||
209 | this._S =bigint.powerModule( | 218 | this._S =bigint.powerModule( |
210 | bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())), | 219 | bigint.subtract( |
211 | bigint.add(this.a(), bigint.multiply(this.u(), this.x())), | 220 | this.B(), |
212 | srp.n() | 221 | bigint.multiply( |
222 | Clipperz.Crypto.SRP.k(), | ||
223 | bigint.powerModule(srp.g(), this.x(), srp.n()) | ||
224 | ) | ||
225 | ), | ||
226 | bigint.add(this.a(), bigint.multiply(this.u(), this.x())), | ||
227 | srp.n() | ||
213 | ) | 228 | ) |
214 | } | 229 | } |
215 | 230 | ||
216 | return this._S; | 231 | return this._S; |
217 | }, | 232 | }, |
218 | 233 | ||
219 | //------------------------------------------------------------------------- | 234 | //------------------------------------------------------------------------- |
220 | 235 | ||
221 | 'K': function () { | 236 | 'K': function () { |
222 | if (this._K == null) { | 237 | if (this._K == null) { |
223 | this._K = this.stringHash(this.S().asString()); | 238 | this._K = this.stringHash(this.S().asString()); |
224 | } | 239 | } |
225 | 240 | ||
226 | return this._K; | 241 | return this._K; |
227 | }, | 242 | }, |
228 | 243 | ||
229 | //------------------------------------------------------------------------- | 244 | //------------------------------------------------------------------------- |
230 | 245 | ||
231 | 'M1': function () { | 246 | 'M1': function () { |
232 | if (this._M1 == null) { | 247 | if (this._M1 == null) { |
233 | this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); | 248 | // this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); |
249 | |||
250 | //http://srp.stanford.edu/design.html | ||
251 | //User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K) | ||
252 | |||
253 | this._M1 = this.stringHash( | ||
254 | "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" + | ||
255 | this.stringHash(this.C()) + | ||
256 | this.s().asString() + | ||
257 | this.A().asString() + | ||
258 | this.B().asString() + | ||
259 | this.K() | ||
260 | ); | ||
261 | //console.log("M1", this._M1); | ||
234 | } | 262 | } |
235 | 263 | ||
236 | return this._M1; | 264 | return this._M1; |
237 | }, | 265 | }, |
238 | 266 | ||
239 | //------------------------------------------------------------------------- | 267 | //------------------------------------------------------------------------- |
240 | 268 | ||
241 | 'M2': function () { | 269 | 'M2': function () { |
242 | if (this._M2 == null) { | 270 | if (this._M2 == null) { |
243 | this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); | 271 | this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); |
272 | //console.log("M2", this._M2); | ||
244 | } | 273 | } |
245 | 274 | ||
246 | return this._M2; | 275 | return this._M2; |
247 | }, | 276 | }, |
248 | 277 | ||
249 | //========================================================================= | 278 | //========================================================================= |
250 | 279 | ||
251 | 'serverSideCredentialsWithSalt': function(aSalt) { | 280 | 'serverSideCredentialsWithSalt': function(aSalt) { |
252 | var result; | 281 | var result; |
253 | var s, x, v; | 282 | var s, x, v; |
254 | 283 | ||
255 | s = aSalt; | 284 | s = aSalt; |
256 | x = this.stringHash(s + this.P()); | 285 | x = this.stringHash(s + this.P()); |
257 | v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); | 286 | v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); |
258 | 287 | ||
259 | result = {}; | 288 | result = {}; |
260 | result['C'] = this.C(); | 289 | result['C'] = this.C(); |
261 | result['s'] = s; | 290 | result['s'] = s; |
262 | result['v'] = v.asString(16); | 291 | result['v'] = v.asString(16); |
263 | 292 | ||
264 | return result; | 293 | return result; |
265 | }, | 294 | }, |
266 | 295 | ||
267 | 'serverSideCredentials': function() { | 296 | 'serverSideCredentials': function() { |
268 | var result; | 297 | var result; |
269 | var s; | 298 | var s; |
270 | 299 | ||
271 | s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); | 300 | s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); |
272 | 301 | ||
273 | result = this.serverSideCredentialsWithSalt(s); | 302 | result = this.serverSideCredentialsWithSalt(s); |
274 | 303 | ||
275 | return result; | 304 | return result; |
276 | }, | 305 | }, |
277 | 306 | ||
278 | //========================================================================= | 307 | //========================================================================= |
279 | /* | 308 | /* |
280 | 'computeServerSide_S': function(b) { | 309 | 'computeServerSide_S': function(b) { |
281 | var result; | 310 | var result; |
282 | var v; | 311 | var v; |
283 | var bigint; | 312 | var bigint; |
284 | varsrp; | 313 | varsrp; |
285 | 314 | ||
286 | bigint = Clipperz.Crypto.BigInt; | 315 | bigint = Clipperz.Crypto.BigInt; |
287 | srp = Clipperz.Crypto.SRP; | 316 | srp = Clipperz.Crypto.SRP; |
288 | 317 | ||
289 | v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16); | 318 | v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16); |
290 | // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n()); | 319 | // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n()); |
291 | result = bigint.powerModule( | 320 | result = bigint.powerModule( |
292 | bigint.multiply( | 321 | bigint.multiply( |
293 | this.A(), | 322 | this.A(), |
294 | bigint.powerModule(v, this.u(), srp.n()) | 323 | bigint.powerModule(v, this.u(), srp.n()) |
295 | ), new Clipperz.Crypto.BigInt(b, 10), srp.n() | 324 | ), new Clipperz.Crypto.BigInt(b, 10), srp.n() |
296 | ); | 325 | ); |
297 | 326 | ||
298 | return result; | 327 | return result; |
299 | }, | 328 | }, |
300 | */ | 329 | */ |
301 | //========================================================================= | 330 | //========================================================================= |
302 | 331 | ||
303 | 'stringHash': function(aValue) { | 332 | 'stringHash': function(aValue) { |
304 | varresult; | 333 | varresult; |
305 | 334 | ||
306 | result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); | 335 | result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); |
307 | 336 | ||
308 | return result; | 337 | return result; |
309 | }, | 338 | }, |
310 | 339 | ||
311 | //========================================================================= | 340 | //========================================================================= |
312 | __syntaxFix__: "syntax fix" | 341 | __syntaxFix__: "syntax fix" |
313 | 342 | ||
314 | }); | 343 | }); |
315 | 344 | ||
316 | //############################################################################# | 345 | //############################################################################# |
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js index b806cb7..e5f68a8 100644 --- a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js +++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js | |||
@@ -1,788 +1,803 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2013 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz, the online password manager. | 5 | This file is part of Clipperz, the online password manager. |
6 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
7 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
8 | 8 | ||
9 | * Clipperz is free software: you can redistribute it and/or modify it | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
10 | under the terms of the GNU Affero General Public License as published | 10 | under the terms of the GNU Affero General Public License as published |
11 | by the Free Software Foundation, either version 3 of the License, or | 11 | by the Free Software Foundation, either version 3 of the License, or |
12 | (at your option) any later version. | 12 | (at your option) any later version. |
13 | 13 | ||
14 | * Clipperz is distributed in the hope that it will be useful, but | 14 | * Clipperz is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
18 | 18 | ||
19 | * You should have received a copy of the GNU Affero General Public | 19 | * You should have received a copy of the GNU Affero General Public |
20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) { | 24 | try { 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 | ||
30 | Clipperz.PM.Proxy.Offline.DataStore = function(args) { | 30 | Clipperz.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 | ||
43 | Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { | 43 | Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { |
44 | 44 | ||
45 | //------------------------------------------------------------------------- | 45 | //------------------------------------------------------------------------- |
46 | 46 | ||
47 | 'isReadOnly': function () { | 47 | 'isReadOnly': function () { |
48 | return this._isReadOnly; | 48 | return this._isReadOnly; |
49 | }, | 49 | }, |
50 | 50 | ||
51 | //------------------------------------------------------------------------- | 51 | //------------------------------------------------------------------------- |
52 | 52 | ||
53 | 'shouldPayTolls': function() { | 53 | 'shouldPayTolls': function() { |
54 | return this._shouldPayTolls; | 54 | return this._shouldPayTolls; |
55 | }, | 55 | }, |
56 | 56 | ||
57 | //------------------------------------------------------------------------- | 57 | //------------------------------------------------------------------------- |
58 | 58 | ||
59 | 'data': function () { | 59 | 'data': function () { |
60 | return this._data; | 60 | return this._data; |
61 | }, | 61 | }, |
62 | 62 | ||
63 | //------------------------------------------------------------------------- | 63 | //------------------------------------------------------------------------- |
64 | 64 | ||
65 | 'tolls': function () { | 65 | 'tolls': function () { |
66 | return this._tolls; | 66 | return this._tolls; |
67 | }, | 67 | }, |
68 | 68 | ||
69 | //========================================================================= | 69 | //========================================================================= |
70 | 70 | ||
71 | 'resetData': function() { | 71 | 'resetData': function() { |
72 | this._data = { | 72 | this._data = { |
73 | 'users': { | 73 | 'users': { |
74 | 'catchAllUser': { | 74 | 'catchAllUser': { |
75 | __masterkey_test_value__: 'masterkey', | 75 | __masterkey_test_value__: 'masterkey', |
76 | s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00', | 76 | s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00', |
77 | v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00' | 77 | v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00' |
78 | } | 78 | } |
79 | } | 79 | } |
80 | }; | 80 | }; |
81 | }, | 81 | }, |
82 | 82 | ||
83 | //------------------------------------------------------------------------- | 83 | //------------------------------------------------------------------------- |
84 | 84 | ||
85 | 'setupWithEncryptedData': function(someData) { | 85 | 'setupWithEncryptedData': function(someData) { |
86 | this._data = Clipperz.Base.deepClone(someData); | 86 | this._data = Clipperz.Base.deepClone(someData); |
87 | }, | 87 | }, |
88 | 88 | ||
89 | //------------------------------------------------------------------------- | 89 | //------------------------------------------------------------------------- |
90 | 90 | ||
91 | 'setupWithData': function(someData) { | 91 | 'setupWithData': function(someData) { |
92 | var deferredResult; | 92 | var deferredResult; |
93 | var resultData; | 93 | var resultData; |
94 | var i, c; | 94 | var i, c; |
95 | 95 | ||
96 | //Clipperz.log(">>> Proxy.Test.setupWithData"); | 96 | //Clipperz.log(">>> Proxy.Test.setupWithData"); |
97 | resultData = this._data; | 97 | resultData = this._data; |
98 | 98 | ||
99 | deferredResult = new Clipperz.Async.Deferred("Proxy.Test.seupWithData", {trace:false}); | 99 | deferredResult = new Clipperz.Async.Deferred("Proxy.Test.seupWithData", {trace:false}); |
100 | c = someData['users'].length; | 100 | c = someData['users'].length; |
101 | 101 | ||
102 | for (i=0; i<c; i++) { | 102 | for (i=0; i<c; i++) { |
103 | varnewConnection; | 103 | varnewConnection; |
104 | varrecordConfiguration; | 104 | varrecordConfiguration; |
105 | 105 | ||
106 | deferredResult.addMethod(this, 'userSerializedEncryptedData', someData['users'][i]); | 106 | deferredResult.addMethod(this, 'userSerializedEncryptedData', someData['users'][i]); |
107 | deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) { | 107 | deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) { |
108 | resultData['users'][aUserSerializationContext['credentials']['C']] = { | 108 | resultData['users'][aUserSerializationContext['credentials']['C']] = { |
109 | 's': aUserSerializationContext['credentials']['s'], | 109 | 's': aUserSerializationContext['credentials']['s'], |
110 | 'v': aUserSerializationContext['credentials']['v'], | 110 | 'v': aUserSerializationContext['credentials']['v'], |
111 | 'version': aUserSerializationContext['data']['connectionVersion'], | 111 | 'version': aUserSerializationContext['data']['connectionVersion'], |
112 | 'userDetails': aUserSerializationContext['encryptedData']['user']['header'], | 112 | 'userDetails': aUserSerializationContext['encryptedData']['user']['header'], |
113 | 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'], | 113 | 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'], |
114 | 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'], | 114 | 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'], |
115 | 'lock': aUserSerializationContext['encryptedData']['user']['lock'], | 115 | 'lock': aUserSerializationContext['encryptedData']['user']['lock'], |
116 | 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records']) | 116 | 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records']) |
117 | } | 117 | } |
118 | }, this)); | 118 | }, this)); |
119 | } | 119 | } |
120 | 120 | ||
121 | deferredResult.addCallback(MochiKit.Base.bind(function() { | 121 | deferredResult.addCallback(MochiKit.Base.bind(function() { |
122 | this._data = resultData; | 122 | this._data = resultData; |
123 | }, this)); | 123 | }, this)); |
124 | 124 | ||
125 | deferredResult.callback(); | 125 | deferredResult.callback(); |
126 | //Clipperz.log("<<< Proxy.Test.setupWithData"); | 126 | //Clipperz.log("<<< Proxy.Test.setupWithData"); |
127 | 127 | ||
128 | return deferredResult; | 128 | return deferredResult; |
129 | }, | 129 | }, |
130 | 130 | ||
131 | //========================================================================= | 131 | //========================================================================= |
132 | 132 | ||
133 | 'getTollForRequestType': function (aRequestType) { | 133 | 'getTollForRequestType': function (aRequestType) { |
134 | varresult; | 134 | varresult; |
135 | vartargetValue; | 135 | vartargetValue; |
136 | var cost; | 136 | var cost; |
137 | 137 | ||
138 | targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); | 138 | targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); |
139 | switch (aRequestType) { | 139 | switch (aRequestType) { |
140 | case 'REGISTER': | 140 | case 'REGISTER': |
141 | cost = 5; | 141 | cost = 5; |
142 | break; | 142 | break; |
143 | case 'CONNECT': | 143 | case 'CONNECT': |
144 | cost = 5; | 144 | cost = 5; |
145 | break; | 145 | break; |
146 | case 'MESSAGE': | 146 | case 'MESSAGE': |
147 | cost = 2; | 147 | cost = 2; |
148 | break; | 148 | break; |
149 | } | 149 | } |
150 | 150 | ||
151 | result = { | 151 | result = { |
152 | requestType: aRequestType, | 152 | requestType: aRequestType, |
153 | targetValue: targetValue, | 153 | targetValue: targetValue, |
154 | cost: cost | 154 | cost: cost |
155 | } | 155 | } |
156 | 156 | ||
157 | if (this.shouldPayTolls()) { | 157 | if (this.shouldPayTolls()) { |
158 | this.tolls()[targetValue] = result; | 158 | this.tolls()[targetValue] = result; |
159 | } | 159 | } |
160 | 160 | ||
161 | return result; | 161 | return result; |
162 | }, | 162 | }, |
163 | 163 | ||
164 | //------------------------------------------------------------------------- | 164 | //------------------------------------------------------------------------- |
165 | 165 | ||
166 | 'checkToll': function (aFunctionName, someParameters) { | 166 | 'checkToll': function (aFunctionName, someParameters) { |
167 | if (this.shouldPayTolls()) { | 167 | if (this.shouldPayTolls()) { |
168 | var localToll; | 168 | var localToll; |
169 | vartollParameters; | 169 | vartollParameters; |
170 | 170 | ||
171 | tollParameters = someParameters['toll']; | 171 | tollParameters = someParameters['toll']; |
172 | localToll = this.tolls()[tollParameters['targetValue']]; | 172 | localToll = this.tolls()[tollParameters['targetValue']]; |
173 | 173 | ||
174 | if (localToll != null) { | 174 | if (localToll != null) { |
175 | if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) { | 175 | if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) { |
176 | throw "Toll value too low."; | 176 | throw "Toll value too low."; |
177 | }; | 177 | }; |
178 | } else { | 178 | } else { |
179 | throw "Missing toll"; | 179 | throw "Missing toll"; |
180 | } | 180 | } |
181 | } | 181 | } |
182 | }, | 182 | }, |
183 | 183 | ||
184 | //========================================================================= | 184 | //========================================================================= |
185 | 185 | ||
186 | 'currentStaticConnection': function () { | 186 | 'currentStaticConnection': function () { |
187 | if (this._currentStaticConnection == null) { | 187 | if (this._currentStaticConnection == null) { |
188 | this._currentStaticConnection = {}; | 188 | this._currentStaticConnection = {}; |
189 | } | 189 | } |
190 | 190 | ||
191 | return this._currentStaticConnection; | 191 | return this._currentStaticConnection; |
192 | }, | 192 | }, |
193 | 193 | ||
194 | //------------------------------------------------------------------------- | 194 | //------------------------------------------------------------------------- |
195 | 195 | ||
196 | 'getConnectionForRequest': function (aFunctionName, someParameters) { | 196 | 'getConnectionForRequest': function (aFunctionName, someParameters) { |
197 | varresult; | 197 | varresult; |
198 | 198 | ||
199 | if (this.shouldPayTolls()) { | 199 | if (this.shouldPayTolls()) { |
200 | if ((typeof(someParameters['toll']) != 'undefined') && (typeof(someParameters['toll']['targetValue']) != 'undefined')) { | 200 | if ((typeof(someParameters['toll']) != 'undefined') && (typeof(someParameters['toll']['targetValue']) != 'undefined')) { |
201 | result = this.tolls()[someParameters['toll']['targetValue']]['connection']; | 201 | result = this.tolls()[someParameters['toll']['targetValue']]['connection']; |
202 | if (typeof(result) == 'undefined') { | 202 | if (typeof(result) == 'undefined') { |
203 | result = {}; | 203 | result = {}; |
204 | } | 204 | } |
205 | } else { | 205 | } else { |
206 | result = {}; | 206 | result = {}; |
207 | } | 207 | } |
208 | } else { | 208 | } else { |
209 | result = this.currentStaticConnection(); | 209 | result = this.currentStaticConnection(); |
210 | } | 210 | } |
211 | 211 | ||
212 | return result; | 212 | return result; |
213 | }, | 213 | }, |
214 | 214 | ||
215 | //------------------------------------------------------------------------- | 215 | //------------------------------------------------------------------------- |
216 | 216 | ||
217 | 'storeConnectionForRequestWithConnectionAndResponse': function (aFunctionName, someParameters, aConnection, aResponse) { | 217 | 'storeConnectionForRequestWithConnectionAndResponse': function (aFunctionName, someParameters, aConnection, aResponse) { |
218 | if (this.shouldPayTolls()) { | 218 | if (this.shouldPayTolls()) { |
219 | if ((typeof(aResponse['toll']) != 'undefined') | 219 | if ((typeof(aResponse['toll']) != 'undefined') |
220 | &&(typeof(aResponse['toll']['targetValue']) != 'undefined') | 220 | &&(typeof(aResponse['toll']['targetValue']) != 'undefined') |
221 | &&(typeof(this.tolls()[aResponse['toll']['targetValue']]) != 'undefined') | 221 | &&(typeof(this.tolls()[aResponse['toll']['targetValue']]) != 'undefined') |
222 | ) { | 222 | ) { |
223 | this.tolls()[aResponse['toll']['targetValue']]['connection'] = aConnection; | 223 | this.tolls()[aResponse['toll']['targetValue']]['connection'] = aConnection; |
224 | } | 224 | } |
225 | } | 225 | } |
226 | }, | 226 | }, |
227 | 227 | ||
228 | //========================================================================= | 228 | //========================================================================= |
229 | 229 | ||
230 | 'processMessage': function (aFunctionName, someParameters) { | 230 | 'processMessage': function (aFunctionName, someParameters) { |
231 | var result; | 231 | var result; |
232 | varconnection; | 232 | varconnection; |
233 | 233 | ||
234 | connection = this.getConnectionForRequest(aFunctionName, someParameters); | 234 | connection = this.getConnectionForRequest(aFunctionName, someParameters); |
235 | 235 | ||
236 | switch(aFunctionName) { | 236 | switch(aFunctionName) { |
237 | case 'knock': | 237 | case 'knock': |
238 | result = this._knock(connection, someParameters); | 238 | result = this._knock(connection, someParameters); |
239 | break; | 239 | break; |
240 | case 'registration': | 240 | case 'registration': |
241 | this.checkToll(aFunctionName, someParameters); | 241 | this.checkToll(aFunctionName, someParameters); |
242 | result = this._registration(connection, someParameters.parameters); | 242 | result = this._registration(connection, someParameters.parameters); |
243 | break; | 243 | break; |
244 | case 'handshake': | 244 | case 'handshake': |
245 | this.checkToll(aFunctionName, someParameters); | 245 | this.checkToll(aFunctionName, someParameters); |
246 | result = this._handshake(connection, someParameters.parameters); | 246 | result = this._handshake(connection, someParameters.parameters); |
247 | break; | 247 | break; |
248 | case 'message': | 248 | case 'message': |
249 | this.checkToll(aFunctionName, someParameters); | 249 | this.checkToll(aFunctionName, someParameters); |
250 | result = this._message(connection, someParameters.parameters); | 250 | result = this._message(connection, someParameters.parameters); |
251 | break; | 251 | break; |
252 | case 'logout': | 252 | case 'logout': |
253 | this._currentStaticConnection = null; | 253 | this._currentStaticConnection = null; |
254 | result = this._logout(connection, someParameters.parameters); | 254 | result = this._logout(connection, someParameters.parameters); |
255 | break; | 255 | break; |
256 | } | 256 | } |
257 | 257 | ||
258 | this.storeConnectionForRequestWithConnectionAndResponse(aFunctionName, someParameters, connection, result); | 258 | this.storeConnectionForRequestWithConnectionAndResponse(aFunctionName, someParameters, connection, result); |
259 | 259 | ||
260 | return MochiKit.Async.succeed(result); | 260 | return MochiKit.Async.succeed(result); |
261 | }, | 261 | }, |
262 | 262 | ||
263 | //========================================================================= | 263 | //========================================================================= |
264 | 264 | ||
265 | '_knock': function(aConnection, someParameters) { | 265 | '_knock': function(aConnection, someParameters) { |
266 | var result; | 266 | var result; |
267 | 267 | ||
268 | result = { | 268 | result = { |
269 | toll: this.getTollForRequestType(someParameters['requestType']) | 269 | toll: this.getTollForRequestType(someParameters['requestType']) |
270 | } | 270 | } |
271 | 271 | ||
272 | return result; | 272 | return result; |
273 | }, | 273 | }, |
274 | 274 | ||
275 | //------------------------------------------------------------------------- | 275 | //------------------------------------------------------------------------- |
276 | 276 | ||
277 | '_registration': function(aConnection, someParameters) { | 277 | '_registration': function(aConnection, someParameters) { |
278 | if (this.isReadOnly() == false) { | 278 | if (this.isReadOnly() == false) { |
279 | if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') { | 279 | if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') { |
280 | this.data()['users'][someParameters['credentials']['C']] = { | 280 | this.data()['users'][someParameters['credentials']['C']] = { |
281 | 's': someParameters['credentials']['s'], | 281 | 's': someParameters['credentials']['s'], |
282 | 'v': someParameters['credentials']['v'], | 282 | 'v': someParameters['credentials']['v'], |
283 | 'version':someParameters['credentials']['version'], | 283 | 'version':someParameters['credentials']['version'], |
284 | // 'lock': Clipperz.Crypto.Base.generateRandomSeed(), | 284 | // 'lock': Clipperz.Crypto.Base.generateRandomSeed(), |
285 | 'userDetails': someParameters['user']['header'], | 285 | 'userDetails': someParameters['user']['header'], |
286 | 'statistics': someParameters['user']['statistics'], | 286 | 'statistics': someParameters['user']['statistics'], |
287 | 'userDetailsVersion':someParameters['user']['version'], | 287 | 'userDetailsVersion':someParameters['user']['version'], |
288 | 'records':{} | 288 | 'records':{} |
289 | } | 289 | } |
290 | } else { | 290 | } else { |
291 | throw "user already exists"; | 291 | throw "user already exists"; |
292 | } | 292 | } |
293 | } else { | 293 | } else { |
294 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | 294 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; |
295 | } | 295 | } |
296 | 296 | ||
297 | result = { | 297 | result = { |
298 | result: { | 298 | result: { |
299 | 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'], | 299 | 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'], |
300 | 'result':'done' | 300 | 'result':'done' |
301 | }, | 301 | }, |
302 | toll: this.getTollForRequestType('CONNECT') | 302 | toll: this.getTollForRequestType('CONNECT') |
303 | } | 303 | } |
304 | 304 | ||
305 | return result; | 305 | return result; |
306 | }, | 306 | }, |
307 | 307 | ||
308 | //------------------------------------------------------------------------- | 308 | //------------------------------------------------------------------------- |
309 | 309 | ||
310 | '_handshake': function(aConnection, someParameters) { | 310 | '_handshake': function(aConnection, someParameters) { |
311 | var result; | 311 | var result; |
312 | varnextTollRequestType; | 312 | varnextTollRequestType; |
313 | 313 | ||
314 | result = {}; | 314 | result = {}; |
315 | if (someParameters.message == "connect") { | 315 | if (someParameters.message == "connect") { |
316 | var userData; | 316 | var userData; |
317 | var randomBytes; | 317 | var randomBytes; |
318 | var v; | 318 | var v; |
319 | 319 | ||
320 | userData = this.data()['users'][someParameters.parameters.C]; | 320 | userData = this.data()['users'][someParameters.parameters.C]; |
321 | 321 | ||
322 | if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) { | 322 | if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) { |
323 | aConnection['userData'] = userData; | 323 | aConnection['userData'] = userData; |
324 | aConnection['C'] = someParameters.parameters.C; | 324 | aConnection['C'] = someParameters.parameters.C; |
325 | } else { | 325 | } else { |
326 | aConnection['userData'] = this.data()['users']['catchAllUser']; | 326 | aConnection['userData'] = this.data()['users']['catchAllUser']; |
327 | } | 327 | } |
328 | 328 | ||
329 | randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); | 329 | randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); |
330 | aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16); | 330 | aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16); |
331 | v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); | 331 | v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); |
332 | aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); | 332 | aConnection['B'] = (Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); |
333 | 333 | ||
334 | aConnection['A'] = someParameters.parameters.A; | 334 | aConnection['A'] = someParameters.parameters.A; |
335 | 335 | ||
336 | result['s'] = aConnection['userData']['s']; | 336 | result['s'] = aConnection['userData']['s']; |
337 | result['B'] = aConnection['B'].asString(16); | 337 | result['B'] = aConnection['B'].asString(16); |
338 | 338 | ||
339 | nextTollRequestType = 'CONNECT'; | 339 | nextTollRequestType = 'CONNECT'; |
340 | } else if (someParameters.message == "credentialCheck") { | 340 | } else if (someParameters.message == "credentialCheck") { |
341 | var v, u, S, A, K, M1; | 341 | var v, u, s, S, A, K, M1; |
342 | 342 | var stringHash = function (aValue) { | |
343 | return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); | ||
344 | }; | ||
345 | |||
343 | v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); | 346 | v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); |
344 | u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16); | ||
345 | A = new Clipperz.Crypto.BigInt(aConnection['A'], 16); | 347 | A = new Clipperz.Crypto.BigInt(aConnection['A'], 16); |
348 | u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10))).toHexString(), 16); | ||
349 | s = new Clipperz.Crypto.BigInt(aConnection['userData']['s'], 16); | ||
346 | S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); | 350 | S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); |
347 | 351 | ||
348 | K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2); | 352 | K = stringHash(S.asString(10)); |
349 | 353 | ||
350 | M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2); | 354 | M1 = stringHash( |
355 | "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" + | ||
356 | stringHash(aConnection['C']) + | ||
357 | s.asString(10) + | ||
358 | A.asString(10) + | ||
359 | aConnection['B'].asString(10) + | ||
360 | K | ||
361 | ); | ||
351 | if (someParameters.parameters.M1 == M1) { | 362 | if (someParameters.parameters.M1 == M1) { |
352 | var M2; | 363 | var M2; |
353 | 364 | ||
354 | M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2); | 365 | M2 = stringHash( |
366 | A.asString(10) + | ||
367 | someParameters.parameters.M1 + | ||
368 | K | ||
369 | ); | ||
355 | result['M2'] = M2; | 370 | result['M2'] = M2; |
356 | } else { | 371 | } else { |
357 | throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); | 372 | throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); |
358 | } | 373 | } |
359 | 374 | ||
360 | nextTollRequestType = 'MESSAGE'; | 375 | nextTollRequestType = 'MESSAGE'; |
361 | } else if (someParameters.message == "oneTimePassword") { | 376 | } else if (someParameters.message == "oneTimePassword") { |
362 | var otpData; | 377 | var otpData; |
363 | 378 | ||
364 | otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; | 379 | otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; |
365 | 380 | ||
366 | try { | 381 | try { |
367 | if (typeof(otpData) != 'undefined') { | 382 | if (typeof(otpData) != 'undefined') { |
368 | if (otpData['status'] == 'ACTIVE') { | 383 | if (otpData['status'] == 'ACTIVE') { |
369 | if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { | 384 | if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { |
370 | result = { | 385 | result = { |
371 | 'data': otpData['data'], | 386 | 'data': otpData['data'], |
372 | 'version':otpData['version'] | 387 | 'version':otpData['version'] |
373 | } | 388 | } |
374 | 389 | ||
375 | otpData['status'] = 'REQUESTED'; | 390 | otpData['status'] = 'REQUESTED'; |
376 | } else { | 391 | } else { |
377 | otpData['status'] = 'DISABLED'; | 392 | otpData['status'] = 'DISABLED'; |
378 | throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; | 393 | throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; |
379 | } | 394 | } |
380 | } else { | 395 | } else { |
381 | throw "The requested One Time Password was not active"; | 396 | throw "The requested One Time Password was not active"; |
382 | } | 397 | } |
383 | } else { | 398 | } else { |
384 | throw "The requested One Time Password has not been found" | 399 | throw "The requested One Time Password has not been found" |
385 | } | 400 | } |
386 | } catch (exception) { | 401 | } catch (exception) { |
387 | result = { | 402 | result = { |
388 | 'data': Clipperz.PM.Crypto.randomKey(), | 403 | 'data': Clipperz.PM.Crypto.randomKey(), |
389 | 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion | 404 | 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion |
390 | } | 405 | } |
391 | } | 406 | } |
392 | nextTollRequestType = 'CONNECT'; | 407 | nextTollRequestType = 'CONNECT'; |
393 | } else { | 408 | } else { |
394 | Clipperz.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); | 409 | Clipperz.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); |
395 | } | 410 | } |
396 | 411 | ||
397 | result = { | 412 | result = { |
398 | result: result, | 413 | result: result, |
399 | toll: this.getTollForRequestType(nextTollRequestType) | 414 | toll: this.getTollForRequestType(nextTollRequestType) |
400 | } | 415 | } |
401 | 416 | ||
402 | return result; | 417 | return result; |
403 | }, | 418 | }, |
404 | 419 | ||
405 | //------------------------------------------------------------------------- | 420 | //------------------------------------------------------------------------- |
406 | 421 | ||
407 | '_message': function(aConnection, someParameters) { | 422 | '_message': function(aConnection, someParameters) { |
408 | var result; | 423 | var result; |
409 | 424 | ||
410 | result = {}; | 425 | result = {}; |
411 | 426 | ||
412 | //===================================================================== | 427 | //===================================================================== |
413 | // | 428 | // |
414 | // R E A D - O N L Y M e t h o d s | 429 | // R E A D - O N L Y M e t h o d s |
415 | // | 430 | // |
416 | //===================================================================== | 431 | //===================================================================== |
417 | if (someParameters.message == 'getUserDetails') { | 432 | if (someParameters.message == 'getUserDetails') { |
418 | var recordsStats; | 433 | var recordsStats; |
419 | var recordReference; | 434 | var recordReference; |
420 | 435 | ||
421 | recordsStats = {}; | 436 | recordsStats = {}; |
422 | for (recordReference in aConnection['userData']['records']) { | 437 | for (recordReference in aConnection['userData']['records']) { |
423 | recordsStats[recordReference] = { | 438 | recordsStats[recordReference] = { |
424 | 'updateDate': aConnection['userData']['records'][recordReference]['updateDate'] | 439 | 'updateDate': aConnection['userData']['records'][recordReference]['updateDate'] |
425 | } | 440 | } |
426 | } | 441 | } |
427 | 442 | ||
428 | result['header'] = this.userDetails(aConnection); | 443 | result['header'] = this.userDetails(aConnection); |
429 | result['statistics'] = this.statistics(aConnection); | 444 | result['statistics'] = this.statistics(aConnection); |
430 | result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords']; | 445 | result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords']; |
431 | result['version'] = aConnection['userData']['userDetailsVersion']; | 446 | result['version'] = aConnection['userData']['userDetailsVersion']; |
432 | result['recordsStats'] = recordsStats; | 447 | result['recordsStats'] = recordsStats; |
433 | 448 | ||
434 | if (this.isReadOnly() == false) { | 449 | if (this.isReadOnly() == false) { |
435 | varlock; | 450 | varlock; |
436 | 451 | ||
437 | if (typeof(aConnection['userData']['lock']) == 'undefined') { | 452 | if (typeof(aConnection['userData']['lock']) == 'undefined') { |
438 | aConnection['userData']['lock'] = "<<LOCK>>"; | 453 | aConnection['userData']['lock'] = "<<LOCK>>"; |
439 | } | 454 | } |
440 | 455 | ||
441 | result['lock'] = aConnection['userData']['lock']; | 456 | result['lock'] = aConnection['userData']['lock']; |
442 | } | 457 | } |
443 | 458 | ||
444 | //===================================================================== | 459 | //===================================================================== |
445 | } else if (someParameters.message == 'getRecordDetail') { | 460 | } else if (someParameters.message == 'getRecordDetail') { |
446 | /* | 461 | /* |
447 | varrecordData; | 462 | varrecordData; |
448 | var currentVersionData; | 463 | var currentVersionData; |
449 | 464 | ||
450 | recordData = this.userData()['records'][someParameters['parameters']['reference']]; | 465 | recordData = this.userData()['records'][someParameters['parameters']['reference']]; |
451 | result['reference'] = someParameters['parameters']['reference']; | 466 | result['reference'] = someParameters['parameters']['reference']; |
452 | result['data'] = recordData['data']; | 467 | result['data'] = recordData['data']; |
453 | result['version'] = recordData['version']; | 468 | result['version'] = recordData['version']; |
454 | result['creationData'] = recordData['creationDate']; | 469 | result['creationData'] = recordData['creationDate']; |
455 | result['updateDate'] = recordData['updateDate']; | 470 | result['updateDate'] = recordData['updateDate']; |
456 | result['accessDate'] = recordData['accessDate']; | 471 | result['accessDate'] = recordData['accessDate']; |
457 | 472 | ||
458 | currentVersionData = recordData['versions'][recordData['currentVersion']]; | 473 | currentVersionData = recordData['versions'][recordData['currentVersion']]; |
459 | 474 | ||
460 | result['currentVersion'] = {}; | 475 | result['currentVersion'] = {}; |
461 | result['currentVersion']['reference'] = recordData['currentVersion']; | 476 | result['currentVersion']['reference'] = recordData['currentVersion']; |
462 | result['currentVersion']['version'] = currentVersionData['version']; | 477 | result['currentVersion']['version'] = currentVersionData['version']; |
463 | result['currentVersion']['header'] = currentVersionData['header']; | 478 | result['currentVersion']['header'] = currentVersionData['header']; |
464 | result['currentVersion']['data'] = currentVersionData['data']; | 479 | result['currentVersion']['data'] = currentVersionData['data']; |
465 | result['currentVersion']['creationData'] = currentVersionData['creationDate']; | 480 | result['currentVersion']['creationData'] = currentVersionData['creationDate']; |
466 | result['currentVersion']['updateDate'] = currentVersionData['updateDate']; | 481 | result['currentVersion']['updateDate'] = currentVersionData['updateDate']; |
467 | result['currentVersion']['accessDate'] = currentVersionData['accessDate']; | 482 | result['currentVersion']['accessDate'] = currentVersionData['accessDate']; |
468 | if (typeof(currentVersionData['previousVersion']) != 'undefined') { | 483 | if (typeof(currentVersionData['previousVersion']) != 'undefined') { |
469 | result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; | 484 | result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; |
470 | result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; | 485 | result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; |
471 | } | 486 | } |
472 | */ | 487 | */ |
473 | MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]); | 488 | MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]); |
474 | result['reference'] = someParameters['parameters']['reference']; | 489 | result['reference'] = someParameters['parameters']['reference']; |
475 | 490 | ||
476 | //===================================================================== | 491 | //===================================================================== |
477 | // | 492 | // |
478 | // R E A D - W R I T E M e t h o d s | 493 | // R E A D - W R I T E M e t h o d s |
479 | // | 494 | // |
480 | //===================================================================== | 495 | //===================================================================== |
481 | } else if (someParameters.message == 'upgradeUserCredentials') { | 496 | } else if (someParameters.message == 'upgradeUserCredentials') { |
482 | if (this.isReadOnly() == false) { | 497 | if (this.isReadOnly() == false) { |
483 | var parameters; | 498 | var parameters; |
484 | var credentials; | 499 | var credentials; |
485 | 500 | ||
486 | parameters = someParameters['parameters']; | 501 | parameters = someParameters['parameters']; |
487 | credentials = parameters['credentials']; | 502 | credentials = parameters['credentials']; |
488 | 503 | ||
489 | if ((credentials['C'] == null) | 504 | if ((credentials['C'] == null) |
490 | ||(credentials['s'] == null) | 505 | ||(credentials['s'] == null) |
491 | ||(credentials['v'] == null) | 506 | ||(credentials['v'] == null) |
492 | ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) | 507 | ||(credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) |
493 | ) { | 508 | ) { |
494 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; | 509 | result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; |
495 | } else { | 510 | } else { |
496 | varoldCValue; | 511 | varoldCValue; |
497 | oldCValue = aConnection['C']; | 512 | oldCValue = aConnection['C']; |
498 | 513 | ||
499 | this.data()['users'][credentials['C']] = aConnection['userData']; | 514 | this.data()['users'][credentials['C']] = aConnection['userData']; |
500 | aConnection['C'] = credentials['C']; | 515 | aConnection['C'] = credentials['C']; |
501 | 516 | ||
502 | aConnection['userData']['s'] = credentials['s']; | 517 | aConnection['userData']['s'] = credentials['s']; |
503 | aConnection['userData']['v'] = credentials['v']; | 518 | aConnection['userData']['v'] = credentials['v']; |
504 | aConnection['userData']['version'] = credentials['version']; | 519 | aConnection['userData']['version'] = credentials['version']; |
505 | 520 | ||
506 | aConnection['userData']['userDetails'] = parameters['user']['header']; | 521 | aConnection['userData']['userDetails'] = parameters['user']['header']; |
507 | aConnection['userData']['userDetailsVersion'] = parameters['user']['version']; | 522 | aConnection['userData']['userDetailsVersion'] = parameters['user']['version']; |
508 | aConnection['userData']['statistics'] = parameters['user']['statistics']; | 523 | aConnection['userData']['statistics'] = parameters['user']['statistics']; |
509 | 524 | ||
510 | aConnection['userData']['lock'] = parameters['user']['lock']; | 525 | aConnection['userData']['lock'] = parameters['user']['lock']; |
511 | 526 | ||
512 | delete this.data()['users'][oldCValue]; | 527 | delete this.data()['users'][oldCValue]; |
513 | 528 | ||
514 | result = {result:"done", parameters:parameters}; | 529 | result = {result:"done", parameters:parameters}; |
515 | } | 530 | } |
516 | } else { | 531 | } else { |
517 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | 532 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; |
518 | } | 533 | } |
519 | //===================================================================== | 534 | //===================================================================== |
520 | /* } else if (someParameters.message == 'updateData') { | 535 | /* } else if (someParameters.message == 'updateData') { |
521 | if (this.isReadOnly() == false) { | 536 | if (this.isReadOnly() == false) { |
522 | var i, c; | 537 | var i, c; |
523 | 538 | ||
524 | if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { | 539 | if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { |
525 | throw "the lock attribute is not processed correctly" | 540 | throw "the lock attribute is not processed correctly" |
526 | } | 541 | } |
527 | 542 | ||
528 | this.userData()['userDetails'] = someParameters['parameters']['user']['header']; | 543 | this.userData()['userDetails'] = someParameters['parameters']['user']['header']; |
529 | this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; | 544 | this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; |
530 | this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; | 545 | this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; |
531 | 546 | ||
532 | c = someParameters['parameters']['records'].length; | 547 | c = someParameters['parameters']['records'].length; |
533 | for (i=0; i<c; i++) { | 548 | for (i=0; i<c; i++) { |
534 | var currentRecord; | 549 | var currentRecord; |
535 | var currentRecordData; | 550 | var currentRecordData; |
536 | 551 | ||
537 | currentRecordData = someParameters['parameters']['records'][i]; | 552 | currentRecordData = someParameters['parameters']['records'][i]; |
538 | currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; | 553 | currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; |
539 | 554 | ||
540 | if (currentRecord == null) { | 555 | if (currentRecord == null) { |
541 | } | 556 | } |
542 | 557 | ||
543 | currentRecord['data'] = currentRecordData['record']['data']; | 558 | currentRecord['data'] = currentRecordData['record']['data']; |
544 | currentRecord['version'] = currentRecordData['record']['version']; | 559 | currentRecord['version'] = currentRecordData['record']['version']; |
545 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; | 560 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; |
546 | 561 | ||
547 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { | 562 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { |
548 | 'data': currentRecordData['currentRecordVersion']['data'], | 563 | 'data': currentRecordData['currentRecordVersion']['data'], |
549 | 'version': currentRecordData['currentRecordVersion']['version'], | 564 | 'version': currentRecordData['currentRecordVersion']['version'], |
550 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], | 565 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], |
551 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'] | 566 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'] |
552 | } | 567 | } |
553 | } | 568 | } |
554 | 569 | ||
555 | this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); | 570 | this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); |
556 | result['lock'] = this.userData()['lock']; | 571 | result['lock'] = this.userData()['lock']; |
557 | result['result'] = 'done'; | 572 | result['result'] = 'done'; |
558 | } else { | 573 | } else { |
559 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | 574 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; |
560 | } | 575 | } |
561 | */ //===================================================================== | 576 | */ //===================================================================== |
562 | } else if (someParameters.message == 'saveChanges') { | 577 | } else if (someParameters.message == 'saveChanges') { |
563 | if (this.isReadOnly() == false) { | 578 | if (this.isReadOnly() == false) { |
564 | var i, c; | 579 | var i, c; |
565 | 580 | ||
566 | if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) { | 581 | if (aConnection['userData']['lock']!= someParameters['parameters']['user']['lock']) { |
567 | throw "the lock attribute is not processed correctly" | 582 | throw "the lock attribute is not processed correctly" |
568 | } | 583 | } |
569 | 584 | ||
570 | aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header']; | 585 | aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header']; |
571 | aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics']; | 586 | aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics']; |
572 | aConnection['userData']['userDetailsVersion']= someParameters['parameters']['user']['version']; | 587 | aConnection['userData']['userDetailsVersion']= someParameters['parameters']['user']['version']; |
573 | 588 | ||
574 | c = someParameters['parameters']['records']['updated'].length; | 589 | c = someParameters['parameters']['records']['updated'].length; |
575 | for (i=0; i<c; i++) { | 590 | for (i=0; i<c; i++) { |
576 | var currentRecord; | 591 | var currentRecord; |
577 | var currentRecordData; | 592 | var currentRecordData; |
578 | 593 | ||
579 | currentRecordData = someParameters['parameters']['records']['updated'][i]; | 594 | currentRecordData = someParameters['parameters']['records']['updated'][i]; |
580 | currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']]; | 595 | currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']]; |
581 | 596 | ||
582 | if ( | 597 | if ( |
583 | (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined') | 598 | (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined') |
584 | && | 599 | && |
585 | (typeof(currentRecordData['currentRecordVersion']) == 'undefined') | 600 | (typeof(currentRecordData['currentRecordVersion']) == 'undefined') |
586 | ) { | 601 | ) { |
587 | throw "Record added without a recordVersion"; | 602 | throw "Record added without a recordVersion"; |
588 | } | 603 | } |
589 | 604 | ||
590 | if (currentRecord == null) { | 605 | if (currentRecord == null) { |
591 | currentRecord = {}; | 606 | currentRecord = {}; |
592 | currentRecord['versions'] = {}; | 607 | currentRecord['versions'] = {}; |
593 | currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | 608 | currentRecord['creationDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); |
594 | currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | 609 | currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); |
595 | 610 | ||
596 | aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord; | 611 | aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord; |
597 | } | 612 | } |
598 | 613 | ||
599 | currentRecord['data'] = currentRecordData['record']['data']; | 614 | currentRecord['data'] = currentRecordData['record']['data']; |
600 | currentRecord['version']= currentRecordData['record']['version']; | 615 | currentRecord['version']= currentRecordData['record']['version']; |
601 | currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); | 616 | currentRecord['updateDate']= Clipperz.PM.Date.formatDateWithUTCFormat(new Date()); |
602 | 617 | ||
603 | if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') { | 618 | if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') { |
604 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; | 619 | currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; |
605 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { | 620 | currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { |
606 | 'data': currentRecordData['currentRecordVersion']['data'], | 621 | 'data': currentRecordData['currentRecordVersion']['data'], |
607 | 'version': currentRecordData['currentRecordVersion']['version'], | 622 | 'version': currentRecordData['currentRecordVersion']['version'], |
608 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], | 623 | 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], |
609 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'], | 624 | 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'], |
610 | 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), | 625 | 'creationDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), |
611 | 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), | 626 | 'updateDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()), |
612 | 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()) | 627 | 'accessDate':Clipperz.PM.Date.formatDateWithUTCFormat(new Date()) |
613 | } | 628 | } |
614 | } | 629 | } |
615 | } | 630 | } |
616 | 631 | ||
617 | c = someParameters['parameters']['records']['deleted'].length; | 632 | c = someParameters['parameters']['records']['deleted'].length; |
618 | for (i=0; i<c; i++) { | 633 | for (i=0; i<c; i++) { |
619 | var currentRecordReference; | 634 | var currentRecordReference; |
620 | 635 | ||
621 | currentRecordReference = someParameters['parameters']['records']['deleted'][i]; | 636 | currentRecordReference = someParameters['parameters']['records']['deleted'][i]; |
622 | delete aConnection['userData']['records'][currentRecordReference]; | 637 | delete aConnection['userData']['records'][currentRecordReference]; |
623 | } | 638 | } |
624 | 639 | ||
625 | aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey(); | 640 | aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey(); |
626 | result['lock'] = aConnection['userData']['lock']; | 641 | result['lock'] = aConnection['userData']['lock']; |
627 | result['result'] = 'done'; | 642 | result['result'] = 'done'; |
628 | } else { | 643 | } else { |
629 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; | 644 | throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; |
630 | } | 645 | } |
631 | 646 | ||
632 | //===================================================================== | 647 | //===================================================================== |
633 | // | 648 | // |
634 | // U N H A N D L E D M e t h o d | 649 | // U N H A N D L E D M e t h o d |
635 | // | 650 | // |
636 | //===================================================================== | 651 | //===================================================================== |
637 | } else { | 652 | } else { |
638 | Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message); | 653 | Clipperz.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message); |
639 | } | 654 | } |
640 | 655 | ||
641 | result = { | 656 | result = { |
642 | result: result, | 657 | result: result, |
643 | toll: this.getTollForRequestType('MESSAGE') | 658 | toll: this.getTollForRequestType('MESSAGE') |
644 | } | 659 | } |
645 | 660 | ||
646 | // return MochiKit.Async.succeed(result); | 661 | // return MochiKit.Async.succeed(result); |
647 | return result; | 662 | return result; |
648 | }, | 663 | }, |
649 | 664 | ||
650 | //------------------------------------------------------------------------- | 665 | //------------------------------------------------------------------------- |
651 | 666 | ||
652 | '_logout': function(someParameters) { | 667 | '_logout': function(someParameters) { |
653 | // return MochiKit.Async.succeed({result: 'done'}); | 668 | // return MochiKit.Async.succeed({result: 'done'}); |
654 | return {result: 'done'}; | 669 | return {result: 'done'}; |
655 | }, | 670 | }, |
656 | 671 | ||
657 | //========================================================================= | 672 | //========================================================================= |
658 | //######################################################################### | 673 | //######################################################################### |
659 | 674 | ||
660 | 'isTestData': function(aConnection) { | 675 | 'isTestData': function(aConnection) { |
661 | return (typeof(aConnection['userData']['__masterkey_test_value__']) != 'undefined'); | 676 | return (typeof(aConnection['userData']['__masterkey_test_value__']) != 'undefined'); |
662 | }, | 677 | }, |
663 | 678 | ||
664 | 'userDetails': function(aConnection) { | 679 | 'userDetails': function(aConnection) { |
665 | var result; | 680 | var result; |
666 | 681 | ||
667 | if (this.isTestData(aConnection)) { | 682 | if (this.isTestData(aConnection)) { |
668 | var serializedHeader; | 683 | var serializedHeader; |
669 | var version; | 684 | var version; |
670 | 685 | ||
671 | //Clipperz.logDebug("### test data"); | 686 | //Clipperz.logDebug("### test data"); |
672 | version = aConnection['userData']['userDetailsVersion']; | 687 | version = aConnection['userData']['userDetailsVersion']; |
673 | serializedHeader = Clipperz.Base.serializeJSON(aConnection['userData']['userDetails']); | 688 | serializedHeader = Clipperz.Base.serializeJSON(aConnection['userData']['userDetails']); |
674 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedHeader); | 689 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedHeader); |
675 | } else { | 690 | } else { |
676 | //Clipperz.logDebug("### NOT test data"); | 691 | //Clipperz.logDebug("### NOT test data"); |
677 | result = aConnection['userData']['userDetails']; | 692 | result = aConnection['userData']['userDetails']; |
678 | } | 693 | } |
679 | 694 | ||
680 | return result; | 695 | return result; |
681 | }, | 696 | }, |
682 | 697 | ||
683 | 'statistics': function(aConnection) { | 698 | 'statistics': function(aConnection) { |
684 | var result; | 699 | var result; |
685 | 700 | ||
686 | if (aConnection['userData']['statistics'] != null) { | 701 | if (aConnection['userData']['statistics'] != null) { |
687 | if (this.isTestData(aConnection)) { | 702 | if (this.isTestData(aConnection)) { |
688 | var serializedStatistics; | 703 | var serializedStatistics; |
689 | var version; | 704 | var version; |
690 | 705 | ||
691 | version = aConnection['userData']['userDetailsVersion']; | 706 | version = aConnection['userData']['userDetailsVersion']; |
692 | serializedStatistics = Clipperz.Base.serializeJSON(aConnection['userData']['statistics']); | 707 | serializedStatistics = Clipperz.Base.serializeJSON(aConnection['userData']['statistics']); |
693 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedStatistics); | 708 | result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedStatistics); |
694 | } else { | 709 | } else { |
695 | result = aConnection['userData']['statistics']; | 710 | result = aConnection['userData']['statistics']; |
696 | } | 711 | } |
697 | } else { | 712 | } else { |
698 | result = null; | 713 | result = null; |
699 | } | 714 | } |
700 | 715 | ||
701 | return result; | 716 | return result; |
702 | }, | 717 | }, |
703 | 718 | ||
704 | /* | 719 | /* |
705 | 'userSerializedEncryptedData': function(someData) { | 720 | 'userSerializedEncryptedData': function(someData) { |
706 | var deferredResult; | 721 | var deferredResult; |
707 | var deferredContext; | 722 | var deferredContext; |
708 | 723 | ||
709 | deferredContext = { 'data': someData }; | 724 | deferredContext = { 'data': someData }; |
710 | 725 | ||
711 | deferredResult = new Clipperz.Async.Deferred('Proxy.Test.serializeUserEncryptedData', {trace:false}); | 726 | deferredResult = new Clipperz.Async.Deferred('Proxy.Test.serializeUserEncryptedData', {trace:false}); |
712 | deferredResult.addCallback(MochiKit.Base.bind(function(aDeferredContext) { | 727 | deferredResult.addCallback(MochiKit.Base.bind(function(aDeferredContext) { |
713 | aDeferredContext['user'] = this.createUserUsingConfigurationData(aDeferredContext['data']); | 728 | aDeferredContext['user'] = this.createUserUsingConfigurationData(aDeferredContext['data']); |
714 | return aDeferredContext; | 729 | return aDeferredContext; |
715 | }, this)); | 730 | }, this)); |
716 | deferredResult.addCallback(function(aDeferredContext) { | 731 | deferredResult.addCallback(function(aDeferredContext) { |
717 | // return aDeferredContext['user'].encryptedDataUsingVersion(aDeferredContext['data']['version']); | 732 | // return aDeferredContext['user'].encryptedDataUsingVersion(aDeferredContext['data']['version']); |
718 | return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); | 733 | return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); |
719 | }); | 734 | }); |
720 | deferredResult.addCallback(function(aUserEncryptedData) { | 735 | deferredResult.addCallback(function(aUserEncryptedData) { |
721 | deferredContext['encryptedData'] = aUserEncryptedData; | 736 | deferredContext['encryptedData'] = aUserEncryptedData; |
722 | return deferredContext; | 737 | return deferredContext; |
723 | }); | 738 | }); |
724 | deferredResult.addCallback(function(aDeferredContext) { | 739 | deferredResult.addCallback(function(aDeferredContext) { |
725 | var connection; | 740 | var connection; |
726 | 741 | ||
727 | connection = new Clipperz.PM.Connection.communicationProtocol.versions[aDeferredContext['data']['connectionVersion']]() | 742 | connection = new Clipperz.PM.Connection.communicationProtocol.versions[aDeferredContext['data']['connectionVersion']]() |
728 | aDeferredContext['credentials'] = connection.serverSideUserCredentials(aDeferredContext['user'].username(),aDeferredContext['user'].passphrase()); | 743 | aDeferredContext['credentials'] = connection.serverSideUserCredentials(aDeferredContext['user'].username(),aDeferredContext['user'].passphrase()); |
729 | 744 | ||
730 | return aDeferredContext; | 745 | return aDeferredContext; |
731 | }); | 746 | }); |
732 | 747 | ||
733 | // deferredResult.addCallback(function(aDeferredContext) { | 748 | // deferredResult.addCallback(function(aDeferredContext) { |
734 | // return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); | 749 | // return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']); |
735 | // }, deferredContext); | 750 | // }, deferredContext); |
736 | // deferredResult.addCallback(function(aUserSerializedData) { | 751 | // deferredResult.addCallback(function(aUserSerializedData) { |
737 | // }); | 752 | // }); |
738 | // | 753 | // |
739 | // deferredResult.addCallback(MochiKit.Async.succeed, deferredContext); | 754 | // deferredResult.addCallback(MochiKit.Async.succeed, deferredContext); |
740 | deferredResult.callback(deferredContext); | 755 | deferredResult.callback(deferredContext); |
741 | 756 | ||
742 | return deferredResult; | 757 | return deferredResult; |
743 | }, | 758 | }, |
744 | 759 | ||
745 | 'createUserUsingConfigurationData': function(someData) { | 760 | 'createUserUsingConfigurationData': function(someData) { |
746 | var result; | 761 | var result; |
747 | var user; | 762 | var user; |
748 | var recordLabel; | 763 | var recordLabel; |
749 | 764 | ||
750 | user = new Clipperz.PM.DataModel.User(); | 765 | user = new Clipperz.PM.DataModel.User(); |
751 | user.initForTests(); | 766 | user.initForTests(); |
752 | user.setUsername(someData['username']); | 767 | user.setUsername(someData['username']); |
753 | user.setPassphrase(someData['passphrase']); | 768 | user.setPassphrase(someData['passphrase']); |
754 | 769 | ||
755 | for (recordLabel in someData['records']) { | 770 | for (recordLabel in someData['records']) { |
756 | var recordData; | 771 | var recordData; |
757 | var record; | 772 | var record; |
758 | var i, c; | 773 | var i, c; |
759 | 774 | ||
760 | recordData = someData['records'][recordLabel]; | 775 | recordData = someData['records'][recordLabel]; |
761 | record = new Clipperz.PM.DataModel.Record({user:user, label:recordLabel}); | 776 | record = new Clipperz.PM.DataModel.Record({user:user, label:recordLabel}); |
762 | record.setNotes(recordData['notes']); | 777 | record.setNotes(recordData['notes']); |
763 | 778 | ||
764 | c = recordData['fields'].length; | 779 | c = recordData['fields'].length; |
765 | for (i=0; i<c; i++) { | 780 | for (i=0; i<c; i++) { |
766 | var recordField; | 781 | var recordField; |
767 | 782 | ||
768 | recordField = new Clipperz.PM.DataModel.RecordField(); | 783 | recordField = new Clipperz.PM.DataModel.RecordField(); |
769 | recordField.setLabel(recordData['fields'][i]['name']); | 784 | recordField.setLabel(recordData['fields'][i]['name']); |
770 | recordField.setValue(recordData['fields'][i]['value']); | 785 | recordField.setValue(recordData['fields'][i]['value']); |
771 | recordField.setType(recordData['fields'][i]['type']); | 786 | recordField.setType(recordData['fields'][i]['type']); |
772 | record.addField(recordField); | 787 | record.addField(recordField); |
773 | } | 788 | } |
774 | user.addRecord(record, true); | 789 | user.addRecord(record, true); |
775 | } | 790 | } |
776 | 791 | ||
777 | result = user; | 792 | result = user; |
778 | 793 | ||
779 | return result; | 794 | return result; |
780 | }, | 795 | }, |
781 | */ | 796 | */ |
782 | //========================================================================= | 797 | //========================================================================= |
783 | __syntaxFix__: "syntax fix" | 798 | __syntaxFix__: "syntax fix" |
784 | }); | 799 | }); |
785 | 800 | ||
786 | Clipperz.PM.Proxy.Offline.DataStore['exception'] = { | 801 | Clipperz.PM.Proxy.Offline.DataStore['exception'] = { |
787 | 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly") | 802 | 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly") |
788 | }; \ No newline at end of file | 803 | }; \ No newline at end of file |