summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzul <azul@riseup.net>2012-10-04 11:23:00 +0200
committerAzul <azul@riseup.net>2012-10-04 11:41:53 +0200
commit0e5f57d3e07db606a779485e1537d4db8b5d3da2 (patch)
tree90733e690fac48da221f3fa7db04aa23ba5423b7
parent66c3ed01eb012cae84193b4864c7c48eb77c2a8c (diff)
created session class to hold aa, bb and so forth - done for client
We have a session in the server already - duplication there now, merge next
-rw-r--r--lib/ruby-srp.rb1
-rw-r--r--lib/srp/authentication.rb15
-rw-r--r--lib/srp/client.rb27
-rw-r--r--lib/srp/session.rb87
-rw-r--r--lib/srp/util.rb7
5 files changed, 108 insertions, 29 deletions
diff --git a/lib/ruby-srp.rb b/lib/ruby-srp.rb
index d5d6cf3..383cbca 100644
--- a/lib/ruby-srp.rb
+++ b/lib/ruby-srp.rb
@@ -11,6 +11,7 @@ module SRP
autoload :Client, 'srp/client'
autoload :Authentication, 'srp/authentication'
autoload :Util, 'srp/util'
+ autoload :Session, 'srp/session'
class WrongPassword < StandardError
end
end
diff --git a/lib/srp/authentication.rb b/lib/srp/authentication.rb
index 3428fd4..c87fe1d 100644
--- a/lib/srp/authentication.rb
+++ b/lib/srp/authentication.rb
@@ -17,7 +17,7 @@ module SRP
end
def u
- calculate_u(aa, bb)
+ @u ||= calculate_u
end
# do not cache this - it's secret and someone might store the
@@ -28,11 +28,20 @@ module SRP
end
def m1(verifier)
- calculate_m(aa, bb, secret(verifier))
+ calculate_m(secret(verifier))
end
def m2(m1, verifier)
- calculate_m(aa, m1, secret(verifier))
+ sha256_int(@aa, m1, secret(verifier)).hex
+ end
+
+ protected
+ def calculate_u
+ sha256_int(@aa, @bb).hex
+ end
+
+ def calculate_m(s)
+ sha256_int(@aa, @bb, s).hex
end
end
diff --git a/lib/srp/client.rb b/lib/srp/client.rb
index de17fb3..94e36af 100644
--- a/lib/srp/client.rb
+++ b/lib/srp/client.rb
@@ -5,23 +5,23 @@ module SRP
include Util
- attr_reader :salt, :verifier
+ attr_reader :salt, :verifier, :username
def initialize(username, password, salt = nil)
@username = username
@password = password
@salt = salt || bigrand(4).hex
- @multiplier = multiplier # let's cache it
calculate_verifier
end
def authenticate(server)
- a = bigrand(32).hex
- aa = modpow(GENERATOR, a) # A = g^a (mod N)
- bb = server.handshake(@username, aa)
- u = calculate_u(aa, bb)
- client_s = calculate_client_s(private_key, a, bb, u)
- server.validate(calculate_m(aa, bb, client_s))
+ @session = SRP::Session.new(self)
+ @session.handshake(server)
+ @session.validate(server)
+ end
+
+ def private_key
+ @private_key ||= calculate_private_key
end
protected
@@ -30,23 +30,12 @@ module SRP
@verifier ||= modpow(GENERATOR, private_key)
end
- def private_key
- @private_key ||= calculate_private_key
- end
-
def calculate_private_key
shex = '%x' % [@salt]
inner = sha256_str([@username, @password].join(':'))
sha256_hex(shex, inner).hex
end
- def calculate_client_s(x, a, bb, u)
- base = bb
- base += BIG_PRIME_N * @multiplier
- base -= modpow(GENERATOR, x) * @multiplier
- base = base % BIG_PRIME_N
- modpow(base, x * u + a)
- end
end
end
diff --git a/lib/srp/session.rb b/lib/srp/session.rb
new file mode 100644
index 0000000..b61058b
--- /dev/null
+++ b/lib/srp/session.rb
@@ -0,0 +1,87 @@
+require File.expand_path(File.dirname(__FILE__) + '/util')
+
+module SRP
+ class Session
+ include Util
+ attr_accessor :user, :aa, :bb
+
+ def initialize(user, aa=nil)
+ @user = user
+ aa ? initialize_server(aa) : initialize_client
+ end
+
+ # client -> server: I, A = g^a
+ def handshake(server)
+ @bb = server.handshake(user.username, aa)
+ @u = calculate_u
+ end
+
+ # client -> server: M = H(H(N) xor H(g), H(I), s, A, B, K)
+ def validate(server)
+ server.validate(calculate_m(client_secret))
+ end
+
+ def authenticate!(m)
+ authenticate(m) || raise(SRP::WrongPassword)
+ end
+
+ def authenticate(m)
+ if(m == calculate_m(server_secret))
+ return m2
+ end
+ end
+
+ protected
+
+ def initialize_server(aa)
+ @aa = aa
+ @b = bigrand(32).hex
+ # B = g^b + k v (mod N)
+ @bb = (modpow(GENERATOR, @b) + multiplier * @user.verifier) % BIG_PRIME_N
+ @u = calculate_u
+ end
+
+ def initialize_client
+ @a = bigrand(32).hex
+ @aa = modpow(GENERATOR, @a) # A = g^a (mod N)
+ end
+
+ # client: K = H( (B - kg^x) ^ (a + ux) )
+ def client_secret
+ base = @bb
+ # base += BIG_PRIME_N * @multiplier
+ base -= modpow(GENERATOR, @user.private_key) * multiplier
+ base = base % BIG_PRIME_N
+ modpow(base, @user.private_key * @u + @a)
+ end
+
+ # server: K = H( (Av^u) ^ b )
+ # do not cache this - it's secret and someone might store the
+ # session in a CookieStore
+ def server_secret
+ base = (modpow(@user.verifier, @u) * @aa) % BIG_PRIME_N
+ modpow(base, @b)
+ end
+
+ def m1
+ calculate_m(server_secret)
+ end
+
+ def m2
+ sha256_int(@aa, m1, server_secret).hex
+ end
+
+ # this is outdated - SRP 6a uses
+ # M = H(H(N) xor H(g), H(I), s, A, B, K)
+ def calculate_m(s)
+ sha256_int(@aa, @bb, s).hex
+ end
+
+ def calculate_u
+ sha256_int(@aa, @bb).hex
+ end
+ end
+end
+
+
+
diff --git a/lib/srp/util.rb b/lib/srp/util.rb
index 087ce5d..50ff9bb 100644
--- a/lib/srp/util.rb
+++ b/lib/srp/util.rb
@@ -61,13 +61,6 @@ d15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e5
sha256_hex(BIG_PRIME_N.to_s(16), ghex).hex
end
- def calculate_m(aa, bb, s)
- sha256_int(aa, bb, s).hex
- end
-
- def calculate_u(aa, bb)
- sha256_int(aa, bb).hex
- end
end
end