diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/srp/session.rb | 92 | ||||
| -rw-r--r-- | lib/srp/util.rb | 2 | 
2 files changed, 64 insertions, 30 deletions
diff --git a/lib/srp/session.rb b/lib/srp/session.rb index 38c9722..abf91cc 100644 --- a/lib/srp/session.rb +++ b/lib/srp/session.rb @@ -1,7 +1,7 @@  module SRP    class Session      include SRP::Util -    attr_accessor :user, :aa, :bb +    attr_accessor :user      def initialize(user, aa=nil)        @user = user @@ -11,28 +11,27 @@ module SRP      # 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)) +      server.validate(m)      end -    def authenticate!(m) -      authenticate(m) || raise(SRP::WrongPassword) +    def authenticate!(client_auth) +      authenticate(client_auth) || raise(SRP::WrongPassword)      end -    def authenticate(m) -      if(m == calculate_m(server_secret)) -        @m2 = calculate_m2 +    def authenticate(client_auth) +      if(client_auth == m) +        @authenticated = true          return @user        end      end      def to_hash -      if @m2 -        { :M2 => @m2.to_s(16) } +      if @authenticated +        { :M2 => m2.to_s(16) }        else          { :B => bb.to_s(16),  #         :b => @b.to_s(16),    # only use for debugging @@ -45,55 +44,90 @@ module SRP        to_hash.to_json(options)      end +    # for debugging use: +    def internal_state +      { +        username: @user.username, +        salt: @user.salt.to_s(16), +        verifier: @user.verifier.to_s(16), +        aa: aa.to_s(16), +        bb: bb.to_s(16), +        s: secret.to_s(16), +        k: k.to_s(16), +        m: m.to_s(16), +        m2: m2.to_s(16) +      } +    end + +    def aa +      @aa ||= modpow(GENERATOR, @a) # A = g^a (mod N) +    end + +    # B = g^b + k v (mod N) +    def bb +      @bb ||= (modpow(GENERATOR, @b) + multiplier * @user.verifier) % BIG_PRIME_N +    end +      protected      # only seed b for testing purposes. -    def initialize_server(aa, b = nil) +    def initialize_server(aa, ephemeral = nil)        @aa = aa -      @b =  b || bigrand(32).hex -      # B = g^b + k v (mod N) -      @bb = (modpow(GENERATOR, @b) + multiplier * @user.verifier) % BIG_PRIME_N -      @u = calculate_u +      @b = ephemeral || bigrand(32).hex      end      def initialize_client        @a = bigrand(32).hex -      @aa = modpow(GENERATOR, @a) # A = g^a (mod N) +      # bb will be set during handshake. +    end + +    def secret +      return client_secret if @a +      return server_secret if @b      end      # client: K = H( (B - kg^x) ^ (a + ux) )      def client_secret -      base = @bb +      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) +      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 +      base = (modpow(@user.verifier, u) * aa) % BIG_PRIME_N        modpow(base, @b)      end -    # this is outdated - SRP 6a uses +    # SRP 6a uses      # M = H(H(N) xor H(g), H(I), s, A, B, K) -    def calculate_m(secret) -      @k = sha256_int(secret).hex -      n_xor_g_long = hn_xor_hg.bytes.map{|b| "%02x" % b.ord}.join.hex -      username_hash = sha256_str(@user.username).hex -      @m = sha256_int(n_xor_g_long, username_hash, @user.salt, @aa, @bb, @k).hex +    def m +      @m ||= sha256_int(n_xor_g_long, login_hash, @user.salt, aa, bb, k).hex +    end + +    def m2 +      @m2 ||= sha256_int(aa, m, k).hex +    end + +    def k +      @k ||= sha256_int(secret).hex +    end + +    def n_xor_g_long +      @n_xor_g_long ||= hn_xor_hg.bytes.map{|b| "%02x" % b.ord}.join.hex      end -    def calculate_m2 -      sha256_int(@aa, @m, @k).hex +    def login_hash +      @login_hash ||= sha256_str(@user.username).hex      end -    def calculate_u -      sha256_int(@aa, @bb).hex +    def u +      @u ||= sha256_int(aa, bb).hex      end    end diff --git a/lib/srp/util.rb b/lib/srp/util.rb index 9f4cb1b..b01ef46 100644 --- a/lib/srp/util.rb +++ b/lib/srp/util.rb @@ -54,7 +54,7 @@ d15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e5      end      def multiplier -      @k ||= calculate_multiplier +      @muliplier ||= calculate_multiplier      end      protected  | 
