Diffstat (limited to 'frontend/delta/js/Clipperz/PM/DataModel/OneTimePassword.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/delta/js/Clipperz/PM/DataModel/OneTimePassword.js | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/frontend/delta/js/Clipperz/PM/DataModel/OneTimePassword.js b/frontend/delta/js/Clipperz/PM/DataModel/OneTimePassword.js new file mode 100644 index 0000000..fbca1ff --- a/dev/null +++ b/frontend/delta/js/Clipperz/PM/DataModel/OneTimePassword.js | |||
@@ -0,0 +1,350 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2013 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz, the online password manager. | ||
6 | For further information about its features and functionalities please | ||
7 | refer to http://www.clipperz.com. | ||
8 | |||
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 | ||
11 | by the Free Software Foundation, either version 3 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | * Clipperz is distributed in the hope that it will be useful, but | ||
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
17 | See the GNU Affero General Public License for more details. | ||
18 | |||
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/. | ||
21 | |||
22 | */ | ||
23 | |||
24 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | ||
25 | if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } | ||
26 | if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } | ||
27 | |||
28 | |||
29 | //############################################################################# | ||
30 | |||
31 | Clipperz.PM.DataModel.OneTimePassword = function(args) { | ||
32 | args = args || {}; | ||
33 | |||
34 | //this._user = args['user']; | ||
35 | this._reference = args['reference']|| Clipperz.PM.Crypto.randomKey(); | ||
36 | this._password = args['password']; | ||
37 | this._passwordValue = Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword(args['password']); | ||
38 | this._creationDate = args['created'] ? Clipperz.PM.Date.parseDateWithUTCFormat(args['created']) : new Date(); | ||
39 | this._usageDate = args['used'] ? Clipperz.PM.Date.parseDateWithUTCFormat(args['used']) : null; | ||
40 | |||
41 | this._status = args['status'] || 'ACTIVE'; //'REQUESTED', 'USED', 'DISABLED' | ||
42 | this._connectionInfo= null; | ||
43 | |||
44 | this._key = null; | ||
45 | this._keyChecksum= null; | ||
46 | |||
47 | return this; | ||
48 | } | ||
49 | |||
50 | Clipperz.PM.DataModel.OneTimePassword.prototype = MochiKit.Base.update(null, { | ||
51 | |||
52 | 'toString': function() { | ||
53 | return "Clipperz.PM.DataModel.OneTimePassword"; | ||
54 | }, | ||
55 | /* | ||
56 | //------------------------------------------------------------------------- | ||
57 | |||
58 | 'user': function() { | ||
59 | return this._user; | ||
60 | }, | ||
61 | |||
62 | //------------------------------------------------------------------------- | ||
63 | |||
64 | 'password': function() { | ||
65 | return this._password; | ||
66 | }, | ||
67 | |||
68 | //------------------------------------------------------------------------- | ||
69 | |||
70 | 'passwordValue': function() { | ||
71 | return this._passwordValue; | ||
72 | }, | ||
73 | |||
74 | //------------------------------------------------------------------------- | ||
75 | |||
76 | 'creationDate': function() { | ||
77 | return this._creationDate; | ||
78 | }, | ||
79 | |||
80 | //------------------------------------------------------------------------- | ||
81 | |||
82 | 'reference': function() { | ||
83 | return this._reference; | ||
84 | }, | ||
85 | |||
86 | //------------------------------------------------------------------------- | ||
87 | |||
88 | 'key': function() { | ||
89 | if (this._key == null) { | ||
90 | this._key = Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(this.user().username(), this.passwordValue()); | ||
91 | } | ||
92 | |||
93 | return this._key; | ||
94 | }, | ||
95 | |||
96 | //------------------------------------------------------------------------- | ||
97 | |||
98 | 'keyChecksum': function() { | ||
99 | if (this._keyChecksum == null) { | ||
100 | this._keyChecksum = Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(this.user().username(), this.passwordValue()); | ||
101 | } | ||
102 | |||
103 | return this._keyChecksum; | ||
104 | }, | ||
105 | */ | ||
106 | //------------------------------------------------------------------------- | ||
107 | |||
108 | 'status': function() { | ||
109 | return this._status; | ||
110 | }, | ||
111 | |||
112 | 'setStatus': function(aValue) { | ||
113 | this._status = aValue; | ||
114 | }, | ||
115 | |||
116 | //------------------------------------------------------------------------- | ||
117 | /* | ||
118 | 'serializedData': function() { | ||
119 | var result; | ||
120 | |||
121 | result = { | ||
122 | 'password': this.password(), | ||
123 | 'created': this.creationDate() ? Clipperz.PM.Date.formatDateWithUTCFormat(this.creationDate()) : null, | ||
124 | 'used': this.usageDate() ? Clipperz.PM.Date.formatDateWithUTCFormat(this.usageDate()) : null, | ||
125 | 'status': this.status() | ||
126 | }; | ||
127 | |||
128 | return result; | ||
129 | }, | ||
130 | |||
131 | //------------------------------------------------------------------------- | ||
132 | |||
133 | 'packedPassphrase': function() { | ||
134 | var result; | ||
135 | var packedPassphrase; | ||
136 | var encodedPassphrase; | ||
137 | varprefixPadding; | ||
138 | var suffixPadding; | ||
139 | var getRandomBytes; | ||
140 | |||
141 | getRandomBytes = MochiKit.Base.method(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'getRandomBytes'); | ||
142 | |||
143 | encodedPassphrase = new Clipperz.ByteArray(this.user().passphrase()).toBase64String(); | ||
144 | //Clipperz.logDebug("--- encodedPassphrase.length: " + encodedPassphrase.length); | ||
145 | prefixPadding = getRandomBytes(getRandomBytes(1).byteAtIndex(0)).toBase64String(); | ||
146 | //Clipperz.logDebug("--- prefixPadding.length: " + prefixPadding.length); | ||
147 | suffixPadding = getRandomBytes((500 - prefixPadding.length - encodedPassphrase.length) * 6 / 8).toBase64String(); | ||
148 | //Clipperz.logDebug("--- suffixPadding.length: " + suffixPadding.length); | ||
149 | //Clipperz.logDebug("--- total.length: " + (prefixPadding.length + encodedPassphrase.length + suffixPadding.length)); | ||
150 | |||
151 | packedPassphrase = { | ||
152 | 'prefix': prefixPadding, | ||
153 | 'passphrase': encodedPassphrase, | ||
154 | 'suffix': suffixPadding | ||
155 | }; | ||
156 | |||
157 | // result = Clipperz.Base.serializeJSON(packedPassphrase); | ||
158 | result = packedPassphrase; | ||
159 | //Clipperz.logDebug("===== OTP packedPassprase: [" + result.length + "]" + result); | ||
160 | //Clipperz.logDebug("<<< OneTimePassword.packedPassphrase"); | ||
161 | |||
162 | return result; | ||
163 | }, | ||
164 | |||
165 | //------------------------------------------------------------------------- | ||
166 | |||
167 | 'encryptedPackedPassphrase': function() { | ||
168 | return Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion(this.passwordValue(), this.packedPassphrase()) | ||
169 | }, | ||
170 | |||
171 | //------------------------------------------------------------------------- | ||
172 | |||
173 | 'encryptedData': function() { | ||
174 | var deferredResult; | ||
175 | varresult; | ||
176 | |||
177 | //Clipperz.logDebug(">>> OneTimePassword.encryptedData"); | ||
178 | //Clipperz.logDebug("--- OneTimePassword.encryptedData - id: " + this.reference()); | ||
179 | result = { | ||
180 | 'reference': this.reference(), | ||
181 | 'key': this.key(), | ||
182 | 'keyChecksum': this.keyChecksum(), | ||
183 | 'data': "", | ||
184 | 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion | ||
185 | } | ||
186 | //Clipperz.logDebug("--- OneTimePassword.encryptedData - 2: " + Clipperz.Base.serializeJSON(result)); | ||
187 | deferredResult = new MochiKit.Async.Deferred(); | ||
188 | //Clipperz.logDebug("--- OneTimePassword.encryptedData - 3"); | ||
189 | //deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.encryptedData - 1: " + res); return res;}); | ||
190 | //# deferredResult.addCallback(Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion, this.passwordValue(), this.packedPassphrase()); | ||
191 | deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedPackedPassphrase')); | ||
192 | //Clipperz.logDebug("--- OneTimePassword.encryptedData - 4"); | ||
193 | //deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.encryptedData - 2: [" + res.length + "]" + res); return res;}); | ||
194 | deferredResult.addCallback(function(aResult, res) { | ||
195 | aResult['data'] = res; | ||
196 | return aResult; | ||
197 | }, result); | ||
198 | //Clipperz.logDebug("--- OneTimePassword.encryptedData - 5"); | ||
199 | //deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.encryptedData - 3: " + Clipperz.Base.serializeJSON(res)); return res;}); | ||
200 | deferredResult.callback(); | ||
201 | //Clipperz.logDebug("--- OneTimePassword.encryptedData - 6"); | ||
202 | |||
203 | return deferredResult; | ||
204 | }, | ||
205 | |||
206 | //------------------------------------------------------------------------- | ||
207 | |||
208 | 'saveChanges': function() { | ||
209 | var deferredResult; | ||
210 | varresult; | ||
211 | |||
212 | //Clipperz.logDebug(">>> OneTimePassword.saveChanges"); | ||
213 | result = {}; | ||
214 | deferredResult = new MochiKit.Async.Deferred(); | ||
215 | |||
216 | deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_encryptUserData'); | ||
217 | deferredResult.addCallback(MochiKit.Base.method(this.user(), 'encryptedData')); | ||
218 | deferredResult.addCallback(function(aResult, res) { | ||
219 | aResult['user'] = res; | ||
220 | return aResult; | ||
221 | }, result); | ||
222 | |||
223 | deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_encryptOTPData'); | ||
224 | deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData')); | ||
225 | deferredResult.addCallback(function(aResult, res) { | ||
226 | aResult['oneTimePassword'] = res; | ||
227 | return aResult; | ||
228 | }, result); | ||
229 | |||
230 | deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_sendingData'); | ||
231 | //deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.saveChanges - 1: " + Clipperz.Base.serializeJSON(res)); return res;}); | ||
232 | deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'addNewOneTimePassword'); | ||
233 | |||
234 | deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_updatingInterface'); | ||
235 | //deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.saveChanges - 2: " + res); return res;}); | ||
236 | deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'OTPUpdated'); | ||
237 | deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'oneTimePassword_saveChanges_done', null); | ||
238 | //deferredResult.addBoth(function(res) {Clipperz.logDebug("OneTimePassword.saveChanges - 2: " + res); return res;}); | ||
239 | deferredResult.callback(); | ||
240 | //Clipperz.logDebug("<<< OneTimePassword.saveChanges"); | ||
241 | |||
242 | return deferredResult; | ||
243 | }, | ||
244 | |||
245 | //------------------------------------------------------------------------- | ||
246 | |||
247 | 'usageDate': function() { | ||
248 | return this._usageDate; | ||
249 | }, | ||
250 | |||
251 | 'setUsageDate': function(aValue) { | ||
252 | this._usageDate = aValue; | ||
253 | }, | ||
254 | |||
255 | //------------------------------------------------------------------------- | ||
256 | |||
257 | 'connectionInfo': function() { | ||
258 | return this._connectionInfo; | ||
259 | }, | ||
260 | |||
261 | 'setConnectionInfo': function(aValue) { | ||
262 | this._connectionInfo = aValue; | ||
263 | }, | ||
264 | |||
265 | //------------------------------------------------------------------------- | ||
266 | |||
267 | 'isExpired': function() { | ||
268 | return (this.usageDate() != null); | ||
269 | }, | ||
270 | |||
271 | //------------------------------------------------------------------------- | ||
272 | |||
273 | 'updateStatusWithValues': function(someValues) { | ||
274 | var result; | ||
275 | |||
276 | result = false; | ||
277 | |||
278 | if (someValues['status'] != this.status()) { | ||
279 | result = true; | ||
280 | } | ||
281 | |||
282 | this.setStatus(someValues['status']); | ||
283 | this.setUsageDate(Clipperz.PM.Date.parseDateWithUTCFormat(someValues['requestDate'])); | ||
284 | this.setConnectionInfo(someValues['connection']); | ||
285 | |||
286 | return result; | ||
287 | }, | ||
288 | */ | ||
289 | //------------------------------------------------------------------------- | ||
290 | __syntaxFix__: "syntax fix" | ||
291 | }); | ||
292 | |||
293 | //############################################################################# | ||
294 | |||
295 | Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword = function(anUsername, aPassword) { | ||
296 | return Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aPassword)).toHexString().substring(2); | ||
297 | } | ||
298 | |||
299 | Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword = function(anUsername, aPassword) { | ||
300 | return Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(anUsername + aPassword)).toHexString().substring(2); | ||
301 | } | ||
302 | |||
303 | //============================================================================= | ||
304 | |||
305 | Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue = function(aPassword) { | ||
306 | var result; | ||
307 | |||
308 | //"yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg" | ||
309 | if (aPassword.replace(/[\s\-]/g, '').length == 32) { | ||
310 | try { | ||
311 | var passwordByteArray; | ||
312 | |||
313 | passwordByteArray = new Clipperz.ByteArray(); | ||
314 | passwordByteArray.appendBase32String(aPassword); | ||
315 | |||
316 | result = true; | ||
317 | } catch(exception) { | ||
318 | result = false; | ||
319 | } | ||
320 | } else { | ||
321 | result = false; | ||
322 | } | ||
323 | |||
324 | return result; | ||
325 | } | ||
326 | |||
327 | //============================================================================= | ||
328 | |||
329 | Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword = function(aPassword) { | ||
330 | varresult; | ||
331 | |||
332 | if (aPassword.replace(/[\s\-]/g, '').length == 32) { | ||
333 | try { | ||
334 | var passwordByteArray; | ||
335 | |||
336 | passwordByteArray = new Clipperz.ByteArray(); | ||
337 | passwordByteArray.appendBase32String(aPassword); | ||
338 | |||
339 | result = passwordByteArray.toBase64String(); | ||
340 | } catch(exception) { | ||
341 | result = aPassword; | ||
342 | } | ||
343 | } else { | ||
344 | result = aPassword; | ||
345 | } | ||
346 | |||
347 | return result; | ||
348 | } | ||
349 | |||
350 | //############################################################################# | ||