Diffstat (limited to 'frontend/gamma/js/Clipperz/Crypto/SRP.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/gamma/js/Clipperz/Crypto/SRP.js | 36 |
1 files changed, 12 insertions, 24 deletions
diff --git a/frontend/gamma/js/Clipperz/Crypto/SRP.js b/frontend/gamma/js/Clipperz/Crypto/SRP.js index 3b25275..597e72d 100644 --- a/frontend/gamma/js/Clipperz/Crypto/SRP.js +++ b/frontend/gamma/js/Clipperz/Crypto/SRP.js | |||
@@ -1,328 +1,316 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | Copyright 2008-2011 Clipperz Srl | 3 | Copyright 2008-2013 Clipperz Srl |
4 | 4 | ||
5 | This file is part of Clipperz Community Edition. | 5 | This file is part of Clipperz, the online password manager. |
6 | Clipperz Community Edition is an online password manager. | ||
7 | For further information about its features and functionalities please | 6 | For further information about its features and functionalities please |
8 | refer to http://www.clipperz.com. | 7 | refer to http://www.clipperz.com. |
9 | 8 | ||
10 | * Clipperz Community Edition is free software: you can redistribute | 9 | * Clipperz is free software: you can redistribute it and/or modify it |
11 | it and/or modify it under the terms of the GNU Affero General Public | 10 | under the terms of the GNU Affero General Public License as published |
12 | License as published by the Free Software Foundation, either version | 11 | by the Free Software Foundation, either version 3 of the License, or |
13 | 3 of the License, or (at your option) any later version. | 12 | (at your option) any later version. |
14 | 13 | ||
15 | * Clipperz Community Edition is distributed in the hope that it will | 14 | * Clipperz is distributed in the hope that it will be useful, but |
16 | be useful, but WITHOUT ANY WARRANTY; without even the implied | 15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. | 17 | See the GNU Affero General Public License for more details. |
19 | 18 | ||
20 | * 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 |
21 | License along with Clipperz Community Edition. If not, see | 20 | License along with Clipperz. If not, see http://www.gnu.org/licenses/. |
22 | <http://www.gnu.org/licenses/>. | ||
23 | 21 | ||
24 | */ | 22 | */ |
25 | 23 | ||
26 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { | 24 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { |
27 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; | 25 | throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; |
28 | } | 26 | } |
29 | 27 | ||
30 | try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { | 28 | try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { |
31 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; | 29 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; |
32 | } | 30 | } |
33 | 31 | ||
34 | try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { | 32 | try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { |
35 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; | 33 | throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; |
36 | } | 34 | } |
37 | 35 | ||
38 | if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } | 36 | if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } |
39 | 37 | ||
40 | Clipperz.Crypto.SRP.VERSION = "0.1"; | 38 | Clipperz.Crypto.SRP.VERSION = "0.1"; |
41 | Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; | 39 | Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; |
42 | 40 | ||
43 | //############################################################################# | 41 | //############################################################################# |
44 | 42 | ||
45 | MochiKit.Base.update(Clipperz.Crypto.SRP, { | 43 | MochiKit.Base.update(Clipperz.Crypto.SRP, { |
46 | 44 | ||
47 | '_n': null, | 45 | '_n': null, |
48 | '_g': null, | 46 | '_g': null, |
49 | //------------------------------------------------------------------------- | 47 | //------------------------------------------------------------------------- |
50 | 48 | ||
51 | 'n': function() { | 49 | 'n': function() { |
52 | if (Clipperz.Crypto.SRP._n == null) { | 50 | if (Clipperz.Crypto.SRP._n == null) { |
53 | Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); | 51 | Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); |
54 | } | 52 | } |
55 | 53 | ||
56 | return Clipperz.Crypto.SRP._n; | 54 | return Clipperz.Crypto.SRP._n; |
57 | }, | 55 | }, |
58 | 56 | ||
59 | //------------------------------------------------------------------------- | 57 | //------------------------------------------------------------------------- |
60 | 58 | ||
61 | 'g': function() { | 59 | 'g': function() { |
62 | if (Clipperz.Crypto.SRP._g == null) { | 60 | if (Clipperz.Crypto.SRP._g == null) { |
63 | Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation) | 61 | Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation) |
64 | } | 62 | } |
65 | 63 | ||
66 | return Clipperz.Crypto.SRP._g; | 64 | return Clipperz.Crypto.SRP._g; |
67 | }, | 65 | }, |
68 | 66 | ||
69 | //----------------------------------------------------------------------------- | 67 | //----------------------------------------------------------------------------- |
70 | 68 | ||
71 | 'exception': { | 69 | 'exception': { |
72 | 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") | 70 | 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") |
73 | }, | 71 | }, |
74 | 72 | ||
75 | //------------------------------------------------------------------------- | 73 | //------------------------------------------------------------------------- |
76 | __syntaxFix__: "syntax fix" | 74 | __syntaxFix__: "syntax fix" |
77 | 75 | ||
78 | }); | 76 | }); |
79 | 77 | ||
80 | //############################################################################# | 78 | //############################################################################# |
81 | // | 79 | // |
82 | // S R P C o n n e c t i o n version 1.0 | 80 | // S R P C o n n e c t i o n version 1.0 |
83 | // | 81 | // |
84 | //============================================================================= | 82 | //============================================================================= |
85 | Clipperz.Crypto.SRP.Connection = function (args) { | 83 | Clipperz.Crypto.SRP.Connection = function (args) { |
86 | args = args || {}; | 84 | args = args || {}; |
87 | 85 | ||
88 | this._C = args.C; | 86 | this._C = args.C; |
89 | this._P = args.P; | 87 | this._P = args.P; |
90 | this.hash = args.hash; | 88 | this.hash = args.hash; |
91 | 89 | ||
92 | this._a = null; | 90 | this._a = null; |
93 | this._A = null; | 91 | this._A = null; |
94 | 92 | ||
95 | this._s = null; | 93 | this._s = null; |
96 | this._B = null; | 94 | this._B = null; |
97 | 95 | ||
98 | this._x = null; | 96 | this._x = null; |
99 | 97 | ||
100 | this._u = null; | 98 | this._u = null; |
101 | this._K = null; | 99 | this._K = null; |
102 | this._M1 = null; | 100 | this._M1 = null; |
103 | this._M2 = null; | 101 | this._M2 = null; |
104 | 102 | ||
105 | this._sessionKey = null; | 103 | this._sessionKey = null; |
106 | 104 | ||
107 | return this; | 105 | return this; |
108 | } | 106 | } |
109 | 107 | ||
110 | Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { | 108 | Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { |
111 | 109 | ||
112 | 'toString': function () { | 110 | 'toString': function () { |
113 | return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); | 111 | return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); |
114 | }, | 112 | }, |
115 | 113 | ||
116 | //------------------------------------------------------------------------- | 114 | //------------------------------------------------------------------------- |
117 | 115 | ||
118 | 'C': function () { | 116 | 'C': function () { |
119 | return this._C; | 117 | return this._C; |
120 | }, | 118 | }, |
121 | 119 | ||
122 | //------------------------------------------------------------------------- | 120 | //------------------------------------------------------------------------- |
123 | 121 | ||
124 | 'P': function () { | 122 | 'P': function () { |
125 | return this._P; | 123 | return this._P; |
126 | }, | 124 | }, |
127 | 125 | ||
128 | //------------------------------------------------------------------------- | 126 | //------------------------------------------------------------------------- |
129 | 127 | ||
130 | 'a': function () { | 128 | 'a': function () { |
131 | if (this._a == null) { | 129 | if (this._a == null) { |
132 | this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); | 130 | this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); |
133 | // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); | 131 | // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); |
134 | //MochiKit.Logging.logDebug("SRP a: " + this._a); | ||
135 | } | 132 | } |
136 | 133 | ||
137 | return this._a; | 134 | return this._a; |
138 | }, | 135 | }, |
139 | 136 | ||
140 | //------------------------------------------------------------------------- | 137 | //------------------------------------------------------------------------- |
141 | 138 | ||
142 | 'A': function () { | 139 | 'A': function () { |
143 | if (this._A == null) { | 140 | if (this._A == null) { |
144 | //Warning: this value should be strictly greater than zero: how should we perform this check? | 141 | //Warning: this value should be strictly greater than zero: how should we perform this check? |
145 | this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); | 142 | this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); |
146 | 143 | ||
147 | if (this._A.equals(0)) { | 144 | if (this._A.equals(0)) { |
148 | MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0."); | 145 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0."); |
149 | throw Clipperz.Crypto.SRP.exception.InvalidValue; | 146 | throw Clipperz.Crypto.SRP.exception.InvalidValue; |
150 | } | 147 | } |
151 | //MochiKit.Logging.logDebug("SRP A: " + this._A); | ||
152 | } | 148 | } |
153 | 149 | ||
154 | return this._A; | 150 | return this._A; |
155 | }, | 151 | }, |
156 | 152 | ||
157 | //------------------------------------------------------------------------- | 153 | //------------------------------------------------------------------------- |
158 | 154 | ||
159 | 's': function () { | 155 | 's': function () { |
160 | return this._s; | 156 | return this._s; |
161 | //MochiKit.Logging.logDebug("SRP s: " + this._S); | ||
162 | }, | 157 | }, |
163 | 158 | ||
164 | 'set_s': function(aValue) { | 159 | 'set_s': function(aValue) { |
165 | this._s = aValue; | 160 | this._s = aValue; |
166 | }, | 161 | }, |
167 | 162 | ||
168 | //------------------------------------------------------------------------- | 163 | //------------------------------------------------------------------------- |
169 | 164 | ||
170 | 'B': function () { | 165 | 'B': function () { |
171 | return this._B; | 166 | return this._B; |
172 | }, | 167 | }, |
173 | 168 | ||
174 | 'set_B': function(aValue) { | 169 | 'set_B': function(aValue) { |
175 | //Warning: this value should be strictly greater than zero: how should we perform this check? | 170 | //Warning: this value should be strictly greater than zero: how should we perform this check? |
176 | if (! aValue.equals(0)) { | 171 | if (! aValue.equals(0)) { |
177 | this._B = aValue; | 172 | this._B = aValue; |
178 | //MochiKit.Logging.logDebug("SRP B: " + this._B); | ||
179 | } else { | 173 | } else { |
180 | MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0."); | 174 | Clipperz.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0."); |
181 | throw Clipperz.Crypto.SRP.exception.InvalidValue; | 175 | throw Clipperz.Crypto.SRP.exception.InvalidValue; |
182 | } | 176 | } |
183 | }, | 177 | }, |
184 | 178 | ||
185 | //------------------------------------------------------------------------- | 179 | //------------------------------------------------------------------------- |
186 | 180 | ||
187 | 'x': function () { | 181 | 'x': function () { |
188 | if (this._x == null) { | 182 | if (this._x == null) { |
189 | this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); | 183 | this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); |
190 | //MochiKit.Logging.logDebug("SRP x: " + this._x); | ||
191 | } | 184 | } |
192 | 185 | ||
193 | return this._x; | 186 | return this._x; |
194 | }, | 187 | }, |
195 | 188 | ||
196 | //------------------------------------------------------------------------- | 189 | //------------------------------------------------------------------------- |
197 | 190 | ||
198 | 'u': function () { | 191 | 'u': function () { |
199 | if (this._u == null) { | 192 | if (this._u == null) { |
200 | this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16); | 193 | this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16); |
201 | //MochiKit.Logging.logDebug("SRP u: " + this._u); | ||
202 | } | 194 | } |
203 | 195 | ||
204 | return this._u; | 196 | return this._u; |
205 | }, | 197 | }, |
206 | 198 | ||
207 | //------------------------------------------------------------------------- | 199 | //------------------------------------------------------------------------- |
208 | 200 | ||
209 | 'S': function () { | 201 | 'S': function () { |
210 | if (this._S == null) { | 202 | if (this._S == null) { |
211 | var bigint; | 203 | var bigint; |
212 | varsrp; | 204 | varsrp; |
213 | 205 | ||
214 | bigint = Clipperz.Crypto.BigInt; | 206 | bigint = Clipperz.Crypto.BigInt; |
215 | srp = Clipperz.Crypto.SRP; | 207 | srp = Clipperz.Crypto.SRP; |
216 | 208 | ||
217 | this._S =bigint.powerModule( | 209 | this._S =bigint.powerModule( |
218 | bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())), | 210 | bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())), |
219 | bigint.add(this.a(), bigint.multiply(this.u(), this.x())), | 211 | bigint.add(this.a(), bigint.multiply(this.u(), this.x())), |
220 | srp.n() | 212 | srp.n() |
221 | ) | 213 | ) |
222 | //MochiKit.Logging.logDebug("SRP S: " + this._S); | ||
223 | } | 214 | } |
224 | 215 | ||
225 | return this._S; | 216 | return this._S; |
226 | }, | 217 | }, |
227 | 218 | ||
228 | //------------------------------------------------------------------------- | 219 | //------------------------------------------------------------------------- |
229 | 220 | ||
230 | 'K': function () { | 221 | 'K': function () { |
231 | if (this._K == null) { | 222 | if (this._K == null) { |
232 | this._K = this.stringHash(this.S().asString()); | 223 | this._K = this.stringHash(this.S().asString()); |
233 | //MochiKit.Logging.logDebug("SRP K: " + this._K); | ||
234 | } | 224 | } |
235 | 225 | ||
236 | return this._K; | 226 | return this._K; |
237 | }, | 227 | }, |
238 | 228 | ||
239 | //------------------------------------------------------------------------- | 229 | //------------------------------------------------------------------------- |
240 | 230 | ||
241 | 'M1': function () { | 231 | 'M1': function () { |
242 | if (this._M1 == null) { | 232 | if (this._M1 == null) { |
243 | this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); | 233 | this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); |
244 | //MochiKit.Logging.logDebug("SRP M1: " + this._M1); | ||
245 | } | 234 | } |
246 | 235 | ||
247 | return this._M1; | 236 | return this._M1; |
248 | }, | 237 | }, |
249 | 238 | ||
250 | //------------------------------------------------------------------------- | 239 | //------------------------------------------------------------------------- |
251 | 240 | ||
252 | 'M2': function () { | 241 | 'M2': function () { |
253 | if (this._M2 == null) { | 242 | if (this._M2 == null) { |
254 | this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); | 243 | this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); |
255 | //MochiKit.Logging.logDebug("SRP M2: " + this._M2); | ||
256 | } | 244 | } |
257 | 245 | ||
258 | return this._M2; | 246 | return this._M2; |
259 | }, | 247 | }, |
260 | 248 | ||
261 | //========================================================================= | 249 | //========================================================================= |
262 | 250 | ||
263 | 'serverSideCredentialsWithSalt': function(aSalt) { | 251 | 'serverSideCredentialsWithSalt': function(aSalt) { |
264 | var result; | 252 | var result; |
265 | var s, x, v; | 253 | var s, x, v; |
266 | 254 | ||
267 | s = aSalt; | 255 | s = aSalt; |
268 | x = this.stringHash(s + this.P()); | 256 | x = this.stringHash(s + this.P()); |
269 | v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); | 257 | v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); |
270 | 258 | ||
271 | result = {}; | 259 | result = {}; |
272 | result['C'] = this.C(); | 260 | result['C'] = this.C(); |
273 | result['s'] = s; | 261 | result['s'] = s; |
274 | result['v'] = v.asString(16); | 262 | result['v'] = v.asString(16); |
275 | 263 | ||
276 | return result; | 264 | return result; |
277 | }, | 265 | }, |
278 | 266 | ||
279 | 'serverSideCredentials': function() { | 267 | 'serverSideCredentials': function() { |
280 | var result; | 268 | var result; |
281 | var s; | 269 | var s; |
282 | 270 | ||
283 | s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); | 271 | s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); |
284 | 272 | ||
285 | result = this.serverSideCredentialsWithSalt(s); | 273 | result = this.serverSideCredentialsWithSalt(s); |
286 | 274 | ||
287 | return result; | 275 | return result; |
288 | }, | 276 | }, |
289 | 277 | ||
290 | //========================================================================= | 278 | //========================================================================= |
291 | /* | 279 | /* |
292 | 'computeServerSide_S': function(b) { | 280 | 'computeServerSide_S': function(b) { |
293 | var result; | 281 | var result; |
294 | var v; | 282 | var v; |
295 | var bigint; | 283 | var bigint; |
296 | varsrp; | 284 | varsrp; |
297 | 285 | ||
298 | bigint = Clipperz.Crypto.BigInt; | 286 | bigint = Clipperz.Crypto.BigInt; |
299 | srp = Clipperz.Crypto.SRP; | 287 | srp = Clipperz.Crypto.SRP; |
300 | 288 | ||
301 | v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16); | 289 | v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16); |
302 | // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n()); | 290 | // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n()); |
303 | result = bigint.powerModule( | 291 | result = bigint.powerModule( |
304 | bigint.multiply( | 292 | bigint.multiply( |
305 | this.A(), | 293 | this.A(), |
306 | bigint.powerModule(v, this.u(), srp.n()) | 294 | bigint.powerModule(v, this.u(), srp.n()) |
307 | ), new Clipperz.Crypto.BigInt(b, 10), srp.n() | 295 | ), new Clipperz.Crypto.BigInt(b, 10), srp.n() |
308 | ); | 296 | ); |
309 | 297 | ||
310 | return result; | 298 | return result; |
311 | }, | 299 | }, |
312 | */ | 300 | */ |
313 | //========================================================================= | 301 | //========================================================================= |
314 | 302 | ||
315 | 'stringHash': function(aValue) { | 303 | 'stringHash': function(aValue) { |
316 | varresult; | 304 | varresult; |
317 | 305 | ||
318 | result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); | 306 | result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); |
319 | 307 | ||
320 | return result; | 308 | return result; |
321 | }, | 309 | }, |
322 | 310 | ||
323 | //========================================================================= | 311 | //========================================================================= |
324 | __syntaxFix__: "syntax fix" | 312 | __syntaxFix__: "syntax fix" |
325 | 313 | ||
326 | }); | 314 | }); |
327 | 315 | ||
328 | //############################################################################# | 316 | //############################################################################# |