From 6a1f447f4155796ca9b2510c49f52559b3934c17 Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 20 Nov 2012 12:25:17 +0100 Subject: make sure srp.login also works as a callback --- src/srp.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/srp.js b/src/srp.js index e57b7e9..c754818 100644 --- a/src/srp.js +++ b/src/srp.js @@ -2,12 +2,12 @@ var srp = (function(){ function signup() { - this.remote.signup(); + srp.remote.signup(); }; function login() { - this.remote.login(); + srp.remote.login(); }; return { -- cgit v1.2.3 From 443a9d3aa5e66f98d7f701e04967620781f3012c Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 20 Nov 2012 12:37:23 +0100 Subject: make sure we get the current password and login --- src/srp_session.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/srp_session.js b/src/srp_session.js index b278993..cfeaadb 100644 --- a/src/srp_session.js +++ b/src/srp_session.js @@ -21,8 +21,8 @@ srp.Session = function(login, password) { var M = null; var M2 = null; var authenticated = false; - var I = login || document.getElementById("srp_username").value; - var pass = password || document.getElementById("srp_password").value; + var I = login; + var pass = password; // *** Accessor methods *** @@ -57,9 +57,16 @@ srp.Session = function(login, password) { // Returns the user's identity this.getI = function() { + I = I || document.getElementById("srp_username").value; return I; }; + // Returns the user's identity + this.getPass = function() { + pass = pass || document.getElementById("srp_password").value; + return pass; + }; + // some 16 byte random number this.getSalt = function() { return new BigInteger(64, rng).toString(16); @@ -77,7 +84,8 @@ srp.Session = function(login, password) { // Calculates the X value and return it as a BigInteger this.calcX = function(salt) { - return new BigInteger(SHA256(hex2a(salt + SHA256(I + ":" + pass))), 16); + var inner = salt + SHA256(this.getI() + ":" + this.getPass()) + return new BigInteger(SHA256(hex2a(inner)), 16); }; this.getV = function(salt) -- cgit v1.2.3 From 635ea47f1c19d7985a8f5107c070ae19edf9dd54 Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 20 Nov 2012 12:43:34 +0100 Subject: all request should go to absolute paths They should be independent of the url we're serving the page from --- spec/login_spec.js | 8 ++++---- spec/signup_spec.js | 2 +- src/jqueryRest.js | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/login_spec.js b/spec/login_spec.js index 16a63d0..e806cff 100644 --- a/spec/login_spec.js +++ b/spec/login_spec.js @@ -45,9 +45,9 @@ describe("Login with srp var", function() { srp.loggedIn = sinon.spy(); srp.login(); - this.expectRequest('sessions.json', 'login=' +login+ '&A=' +A, 'POST'); + this.expectRequest('/sessions.json', 'login=' +login+ '&A=' +A, 'POST'); this.respondJSON({salt: salt, B: B}); - this.expectRequest('sessions/'+login+'.json', 'client_auth='+M, 'PUT'); + this.expectRequest('/sessions/'+login+'.json', 'client_auth='+M, 'PUT'); this.respondJSON({M2: M2}); expect(srp.loggedIn).toHaveBeenCalled(); @@ -58,7 +58,7 @@ describe("Login with srp var", function() { var error = {login: "something went wrong on the server side"}; srp.login(); - this.expectRequest('sessions.json', 'login=' +login+ '&A=' +A, 'POST'); + this.expectRequest('/sessions.json', 'login=' +login+ '&A=' +A, 'POST'); this.respondJSON(error, 422); //this.expectNoMoreRequests(); @@ -72,7 +72,7 @@ describe("Login with srp var", function() { srp.error = sinon.spy(); srp.login(); - this.expectRequest('sessions.json', 'login=' +login+ '&A=' +A, 'POST'); + this.expectRequest('/sessions.json', 'login=' +login+ '&A=' +A, 'POST'); this.respondJSON({salt: salt, B: 0}); // aborting if B=0 expect(this.requests).toEqual([]); diff --git a/spec/signup_spec.js b/spec/signup_spec.js index 41af179..72689b1 100644 --- a/spec/signup_spec.js +++ b/spec/signup_spec.js @@ -25,7 +25,7 @@ describe("Signup with srp var", function() { srp.signedUp = callback; srp.session.getSalt = function() {return "4c78c3f8"}; srp.signup(); - this.expectRequest('users.json', "user[login]=testuser&user[password_salt]=4c78c3f8&user[password_verifier]=474c26aa42d11f20544a00f7bf9711c4b5cf7aab95ed448df82b95521b96668e7480b16efce81c861870302560ddf6604c67df54f1d04b99d5bb9d0f02c6051ada5dc9d594f0d4314e12f876cfca3dcd99fc9c98c2e6a5e04298b11061fb8549a22cde0564e91514080df79bca1c38c682214d65d590f66b3719f954b078b83c", 'POST') + this.expectRequest('/users.json', "user[login]=testuser&user[password_salt]=4c78c3f8&user[password_verifier]=474c26aa42d11f20544a00f7bf9711c4b5cf7aab95ed448df82b95521b96668e7480b16efce81c861870302560ddf6604c67df54f1d04b99d5bb9d0f02c6051ada5dc9d594f0d4314e12f876cfca3dcd99fc9c98c2e6a5e04298b11061fb8549a22cde0564e91514080df79bca1c38c682214d65d590f66b3719f954b078b83c", 'POST') this.respondJSON({password_salt: "4c78c3f8", login: "testuser", ok: "true"}); expect(callback).toHaveBeenCalled(); }); diff --git a/src/jqueryRest.js b/src/jqueryRest.js index c4b0161..1a60385 100644 --- a/src/jqueryRest.js +++ b/src/jqueryRest.js @@ -3,16 +3,16 @@ srp.remote = (function(){ // we do not fetch the salt from the server function register(session) { - return $.post("users.json", { user: session.signup() }); + return $.post("/users.json", { user: session.signup() }); } function handshake(session) { - return $.post("sessions.json", session.handshake()); + return $.post("/sessions.json", session.handshake()); } function authenticate(session) { return $.ajax({ - url: "sessions/" + session.getI() + ".json", + url: "/sessions/" + session.getI() + ".json", type: 'PUT', data: {client_auth: session.getM()} }); -- cgit v1.2.3 From ac5e8d8aa7d4a69a20e20d3079691d13ed2faa66 Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 22 Nov 2012 12:49:46 +0100 Subject: using done/fail instead of success/error, handing all properties to fail --- src/jqueryRest.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jqueryRest.js b/src/jqueryRest.js index 1a60385..20692e9 100644 --- a/src/jqueryRest.js +++ b/src/jqueryRest.js @@ -28,14 +28,14 @@ srp.remote = (function(){ function signup(){ jqueryRest.register(srp.session) - .success(srp.signedUp) - .error(error) + .done(srp.signedUp) + .fail(error) }; function login(){ jqueryRest.handshake(srp.session) - .success(receiveSalts) - .error(error) + .done(receiveSalts) + .fail(error) }; function receiveSalts(response){ @@ -51,8 +51,8 @@ srp.remote = (function(){ { srp.session.calculations(response.salt, response.B); jqueryRest.authenticate(srp.session) - .success(confirmAuthentication) - .error(error); + .done(confirmAuthentication) + .fail(error); } }; @@ -68,7 +68,7 @@ srp.remote = (function(){ // The server will send error messages as json alongside // the http error response. - function error(xhr) + function error(xhr, text, thrown) { srp.error($.parseJSON(xhr.responseText)) }; -- cgit v1.2.3 From 61ab6195768e78f1378caca7ca8ef4e7adcaebb3 Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 22 Nov 2012 12:56:12 +0100 Subject: catch empty responses --- src/jqueryRest.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/jqueryRest.js b/src/jqueryRest.js index 20692e9..bc3bb51 100644 --- a/src/jqueryRest.js +++ b/src/jqueryRest.js @@ -70,7 +70,10 @@ srp.remote = (function(){ // the http error response. function error(xhr, text, thrown) { - srp.error($.parseJSON(xhr.responseText)) + if (xhr.responseText && xhr.responseText != "") + srp.error($.parseJSON(xhr.responseText)); + else + srp.error("Server did not respond."); }; return { -- cgit v1.2.3 From 076d6e251e4caf826787d87b11434e535960455c Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 22 Nov 2012 13:01:22 +0100 Subject: don't cache password and login --- src/srp_session.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/srp_session.js b/src/srp_session.js index cfeaadb..3f27e3e 100644 --- a/src/srp_session.js +++ b/src/srp_session.js @@ -57,13 +57,13 @@ srp.Session = function(login, password) { // Returns the user's identity this.getI = function() { - I = I || document.getElementById("srp_username").value; + I = login || document.getElementById("srp_username").value; return I; }; - // Returns the user's identity + // Returns the password currently typed in this.getPass = function() { - pass = pass || document.getElementById("srp_password").value; + pass = password || document.getElementById("srp_password").value; return pass; }; -- cgit v1.2.3 From 32719dee1d9a4d6ce717eef948dedd54f77b288b Mon Sep 17 00:00:00 2001 From: Azul Date: Fri, 23 Nov 2012 15:33:33 +0100 Subject: addToForm: add the srp signup data to an existing form --- src/jqueryRest.js | 14 ++++++++++++++ src/srp.js | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/jqueryRest.js b/src/jqueryRest.js index bc3bb51..abc53d4 100644 --- a/src/jqueryRest.js +++ b/src/jqueryRest.js @@ -18,6 +18,9 @@ srp.remote = (function(){ }); } + function addSignupToForm(session) { + } + return { register: register, handshake: handshake, @@ -38,6 +41,17 @@ srp.remote = (function(){ .fail(error) }; + function addToForm(){ + form = this.target; + $.each(srp.session.signup(), function(key, value) { + form.append($('', { + type: 'hidden', + name: key + value: value + })); + } + } + function receiveSalts(response){ // B = 0 will make the algorithm always succeed // -> refuse such a server answer diff --git a/src/srp.js b/src/srp.js index c754818..cbfdd10 100644 --- a/src/srp.js +++ b/src/srp.js @@ -10,9 +10,15 @@ var srp = (function(){ srp.remote.login(); }; + function addToForm() + { + srp.remote.addToForm(); + }; + return { signup: signup, - login: login + login: login, + addToForm: addToForm } }()); -- cgit v1.2.3 From fff770a866b44abce6fe0fc5d5ffde034225436d Mon Sep 17 00:00:00 2001 From: Azul Date: Sun, 25 Nov 2012 12:55:00 +0100 Subject: API: update instead of addToForm addToForm was an attempt to not use ajax but just the normal form submit. Turns out it's easy to add hidden fields to the form but quite cumbersome to remove the password fields from teh form so they are not submitted over the eventually untrusted channel. So we use ajax for updates just like for signup. --- src/jqueryRest.js | 35 +++++++++++++++++++---------------- src/srp.js | 8 ++++---- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/jqueryRest.js b/src/jqueryRest.js index abc53d4..bfa4592 100644 --- a/src/jqueryRest.js +++ b/src/jqueryRest.js @@ -1,9 +1,17 @@ srp.remote = (function(){ var jqueryRest = (function() { - // we do not fetch the salt from the server + // TODO: Do we need to differentiate between PUT and POST? function register(session) { - return $.post("/users.json", { user: session.signup() }); + return $.post("/users.json", {user: session.signup() }); + } + + function update(url, session) { + return $.ajax({ + url: url, + type: 'PUT', + data: {user: session.signup() } + }); } function handshake(session) { @@ -18,11 +26,9 @@ srp.remote = (function(){ }); } - function addSignupToForm(session) { - } - return { register: register, + update: update, handshake: handshake, authenticate: authenticate }; @@ -35,23 +41,19 @@ srp.remote = (function(){ .fail(error) }; + function update(submitEvent){ + var form = submitEvent.target; + jqueryRest.update(form.action, srp.session) + .done(srp.updated) + .fail(error) + }; + function login(){ jqueryRest.handshake(srp.session) .done(receiveSalts) .fail(error) }; - function addToForm(){ - form = this.target; - $.each(srp.session.signup(), function(key, value) { - form.append($('', { - type: 'hidden', - name: key - value: value - })); - } - } - function receiveSalts(response){ // B = 0 will make the algorithm always succeed // -> refuse such a server answer @@ -92,6 +94,7 @@ srp.remote = (function(){ return { signup: signup, + update: update, login: login } diff --git a/src/srp.js b/src/srp.js index cbfdd10..efd50d2 100644 --- a/src/srp.js +++ b/src/srp.js @@ -10,15 +10,15 @@ var srp = (function(){ srp.remote.login(); }; - function addToForm() + function update(submitEvent) { - srp.remote.addToForm(); + srp.remote.update(submitEvent); }; return { signup: signup, - login: login, - addToForm: addToForm + update: update, + login: login } }()); -- cgit v1.2.3 From 3f37e98acca731e9272848dea77b7a64a5ed7615 Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 20 Mar 2013 12:49:34 +0100 Subject: use a proper random a for the handshake --- src/srp_session.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/srp_session.js b/src/srp_session.js index 3f27e3e..b1b6014 100644 --- a/src/srp_session.js +++ b/src/srp_session.js @@ -7,8 +7,7 @@ srp.Session = function(login, password) { var k = new BigInteger("bf66c44a428916cad64aa7c679f3fd897ad4c375e9bbb4cbf2f5de241d618ef0", 16); var rng = new SecureRandom(); -// var a = new BigInteger(32, rng); - var a = new BigInteger("d498c3d024ec17689b5320e33fc349a3f3f91320384155b3043fa410c90eab71", 16); + var a = new BigInteger(32, rng); var A = g.modPow(a, N); while(A.mod(N) == 0) { -- cgit v1.2.3 From d29d1146865d36e9d9789d3936e7a9163511be0a Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 20 Mar 2013 12:51:26 +0100 Subject: added version file --- Version | 1 + 1 file changed, 1 insertion(+) create mode 100644 Version diff --git a/Version b/Version new file mode 100644 index 0000000..0d91a54 --- /dev/null +++ b/Version @@ -0,0 +1 @@ +0.3.0 -- cgit v1.2.3