Diffstat (limited to 'frontend/delta/js/Clipperz/Crypto/SRP.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/delta/js/Clipperz/Crypto/SRP.js | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/frontend/delta/js/Clipperz/Crypto/SRP.js b/frontend/delta/js/Clipperz/Crypto/SRP.js new file mode 100644 index 0000000..597e72d --- a/dev/null +++ b/frontend/delta/js/Clipperz/Crypto/SRP.js | |||
@@ -0,0 +1,316 @@ | |||
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 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { | ||
25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; | ||
26 | } | ||
27 | |||
28 | try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { | ||
29 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; | ||
30 | } | ||
31 | |||
32 | try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { | ||
33 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; | ||
34 | } | ||
35 | |||
36 | if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } | ||
37 | |||
38 | Clipperz.Crypto.SRP.VERSION = "0.1"; | ||
39 | Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; | ||
40 | |||
41 | //############################################################################# | ||
42 | |||
43 | MochiKit.Base.update(Clipperz.Crypto.SRP, { | ||
44 | |||
45 | '_n': null, | ||
46 | '_g': null, | ||
47 | //------------------------------------------------------------------------- | ||
48 | |||
49 | 'n': function() { | ||
50 | if (Clipperz.Crypto.SRP._n == null) { | ||
51 | Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); | ||
52 | } | ||
53 | |||
54 | return Clipperz.Crypto.SRP._n; | ||
55 | }, | ||
56 | |||
57 | //------------------------------------------------------------------------- | ||
58 | |||
59 | 'g': function() { | ||
60 | 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) | ||
62 | } | ||
63 | |||
64 | return Clipperz.Crypto.SRP._g; | ||
65 | }, | ||
66 | |||
67 | //----------------------------------------------------------------------------- | ||
68 | |||
69 | 'exception': { | ||
70 | 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") | ||
71 | }, | ||
72 | |||
73 | //------------------------------------------------------------------------- | ||
74 | __syntaxFix__: "syntax fix" | ||
75 | |||
76 | }); | ||
77 | |||
78 | //############################################################################# | ||
79 | // | ||
80 | // S R P C o n n e c t i o n version 1.0 | ||
81 | // | ||
82 | //============================================================================= | ||
83 | Clipperz.Crypto.SRP.Connection = function (args) { | ||
84 | args = args || {}; | ||
85 | |||
86 | this._C = args.C; | ||
87 | this._P = args.P; | ||
88 | this.hash = args.hash; | ||
89 | |||
90 | this._a = null; | ||
91 | this._A = null; | ||
92 | |||
93 | this._s = null; | ||
94 | this._B = null; | ||
95 | |||
96 | this._x = null; | ||
97 | |||
98 | this._u = null; | ||
99 | this._K = null; | ||
100 | this._M1 = null; | ||
101 | this._M2 = null; | ||
102 | |||
103 | this._sessionKey = null; | ||
104 | |||
105 | return this; | ||
106 | } | ||
107 | |||
108 | Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { | ||
109 | |||
110 | 'toString': function () { | ||
111 | return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); | ||
112 | }, | ||
113 | |||
114 | //------------------------------------------------------------------------- | ||
115 | |||
116 | 'C': function () { | ||
117 | return this._C; | ||
118 | }, | ||
119 | |||
120 | //------------------------------------------------------------------------- | ||
121 | |||
122 | 'P': function () { | ||
123 | return this._P; | ||
124 | }, | ||
125 | |||
126 | //------------------------------------------------------------------------- | ||
127 | |||
128 | 'a': function () { | ||
129 | if (this._a == null) { | ||
130 | 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); | ||
132 | } | ||
133 | |||
134 | return this._a; | ||
135 | }, | ||
136 | |||
137 | //------------------------------------------------------------------------- | ||
138 | |||
139 | 'A': function () { | ||
140 | if (this._A == null) { | ||
141 | //Warning: this value should be strictly greater than zero: how should we perform this check? | ||
142 | this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); | ||
143 | |||
144 | if (this._A.equals(0)) { | ||
145 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0."); | ||
146 | throw Clipperz.Crypto.SRP.exception.InvalidValue; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | return this._A; | ||
151 | }, | ||
152 | |||
153 | //------------------------------------------------------------------------- | ||
154 | |||
155 | 's': function () { | ||
156 | return this._s; | ||
157 | }, | ||
158 | |||
159 | 'set_s': function(aValue) { | ||
160 | this._s = aValue; | ||
161 | }, | ||
162 | |||
163 | //------------------------------------------------------------------------- | ||
164 | |||
165 | 'B': function () { | ||
166 | return this._B; | ||
167 | }, | ||
168 | |||
169 | 'set_B': function(aValue) { | ||
170 | //Warning: this value should be strictly greater than zero: how should we perform this check? | ||
171 | if (! aValue.equals(0)) { | ||
172 | this._B = aValue; | ||
173 | } else { | ||
174 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0."); | ||
175 | throw Clipperz.Crypto.SRP.exception.InvalidValue; | ||
176 | } | ||
177 | }, | ||
178 | |||
179 | //------------------------------------------------------------------------- | ||
180 | |||
181 | 'x': function () { | ||
182 | if (this._x == null) { | ||
183 | this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); | ||
184 | } | ||
185 | |||
186 | return this._x; | ||
187 | }, | ||
188 | |||
189 | //------------------------------------------------------------------------- | ||
190 | |||
191 | 'u': function () { | ||
192 | if (this._u == null) { | ||
193 | this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16); | ||
194 | } | ||
195 | |||
196 | return this._u; | ||
197 | }, | ||
198 | |||
199 | //------------------------------------------------------------------------- | ||
200 | |||
201 | 'S': function () { | ||
202 | if (this._S == null) { | ||
203 | var bigint; | ||
204 | varsrp; | ||
205 | |||
206 | bigint = Clipperz.Crypto.BigInt; | ||
207 | srp = Clipperz.Crypto.SRP; | ||
208 | |||
209 | this._S =bigint.powerModule( | ||
210 | bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())), | ||
211 | bigint.add(this.a(), bigint.multiply(this.u(), this.x())), | ||
212 | srp.n() | ||
213 | ) | ||
214 | } | ||
215 | |||
216 | return this._S; | ||
217 | }, | ||
218 | |||
219 | //------------------------------------------------------------------------- | ||
220 | |||
221 | 'K': function () { | ||
222 | if (this._K == null) { | ||
223 | this._K = this.stringHash(this.S().asString()); | ||
224 | } | ||
225 | |||
226 | return this._K; | ||
227 | }, | ||
228 | |||
229 | //------------------------------------------------------------------------- | ||
230 | |||
231 | 'M1': function () { | ||
232 | if (this._M1 == null) { | ||
233 | this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); | ||
234 | } | ||
235 | |||
236 | return this._M1; | ||
237 | }, | ||
238 | |||
239 | //------------------------------------------------------------------------- | ||
240 | |||
241 | 'M2': function () { | ||
242 | if (this._M2 == null) { | ||
243 | this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); | ||
244 | } | ||
245 | |||
246 | return this._M2; | ||
247 | }, | ||
248 | |||
249 | //========================================================================= | ||
250 | |||
251 | 'serverSideCredentialsWithSalt': function(aSalt) { | ||
252 | var result; | ||
253 | var s, x, v; | ||
254 | |||
255 | s = aSalt; | ||
256 | x = this.stringHash(s + this.P()); | ||
257 | v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); | ||
258 | |||
259 | result = {}; | ||
260 | result['C'] = this.C(); | ||
261 | result['s'] = s; | ||
262 | result['v'] = v.asString(16); | ||
263 | |||
264 | return result; | ||
265 | }, | ||
266 | |||
267 | 'serverSideCredentials': function() { | ||
268 | var result; | ||
269 | var s; | ||
270 | |||
271 | s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); | ||
272 | |||
273 | result = this.serverSideCredentialsWithSalt(s); | ||
274 | |||
275 | return result; | ||
276 | }, | ||
277 | |||
278 | //========================================================================= | ||
279 | /* | ||
280 | 'computeServerSide_S': function(b) { | ||
281 | var result; | ||
282 | var v; | ||
283 | var bigint; | ||
284 | varsrp; | ||
285 | |||
286 | bigint = Clipperz.Crypto.BigInt; | ||
287 | srp = Clipperz.Crypto.SRP; | ||
288 | |||
289 | 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()); | ||
291 | result = bigint.powerModule( | ||
292 | bigint.multiply( | ||
293 | this.A(), | ||
294 | bigint.powerModule(v, this.u(), srp.n()) | ||
295 | ), new Clipperz.Crypto.BigInt(b, 10), srp.n() | ||
296 | ); | ||
297 | |||
298 | return result; | ||
299 | }, | ||
300 | */ | ||
301 | //========================================================================= | ||
302 | |||
303 | 'stringHash': function(aValue) { | ||
304 | varresult; | ||
305 | |||
306 | result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); | ||
307 | |||
308 | return result; | ||
309 | }, | ||
310 | |||
311 | //========================================================================= | ||
312 | __syntaxFix__: "syntax fix" | ||
313 | |||
314 | }); | ||
315 | |||
316 | //############################################################################# | ||