diff options
| author | Azul <azul@riseup.net> | 2012-10-04 11:23:00 +0200 | 
|---|---|---|
| committer | Azul <azul@riseup.net> | 2012-10-04 11:41:53 +0200 | 
| commit | 0e5f57d3e07db606a779485e1537d4db8b5d3da2 (patch) | |
| tree | 90733e690fac48da221f3fa7db04aa23ba5423b7 /lib | |
| parent | 66c3ed01eb012cae84193b4864c7c48eb77c2a8c (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
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/ruby-srp.rb | 1 | ||||
| -rw-r--r-- | lib/srp/authentication.rb | 15 | ||||
| -rw-r--r-- | lib/srp/client.rb | 27 | ||||
| -rw-r--r-- | lib/srp/session.rb | 87 | ||||
| -rw-r--r-- | lib/srp/util.rb | 7 | 
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 | 
