Skip to content
This repository has been archived by the owner on Aug 26, 2022. It is now read-only.

Commit

Permalink
Add yard docs and a code of conduct
Browse files Browse the repository at this point in the history
  • Loading branch information
grempe committed May 15, 2016
1 parent b64d06d commit e27e83b
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 21 deletions.
1 change: 1 addition & 0 deletions .yardopts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--no-private lib/**/*.rb - README.md LICENSE.txt CODE_OF_CONDUCT.md
49 changes: 49 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Contributor Code of Conduct

As contributors and maintainers of this project, and in the interest of
fostering an open and welcoming community, we pledge to respect all people who
contribute through reporting issues, posting feature requests, updating
documentation, submitting pull requests or patches, and other activities.

We are committed to making participation in this project a harassment-free
experience for everyone, regardless of level of experience, gender, gender
identity and expression, sexual orientation, disability, personal appearance,
body size, race, ethnicity, age, religion, or nationality.

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic
addresses, without explicit permission
* Other unethical or unprofessional conduct

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

By adopting this Code of Conduct, project maintainers commit themselves to
fairly and consistently applying these principles to every aspect of managing
this project. Project maintainers who do not follow or enforce the Code of
Conduct may be permanently removed from the project team.

This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting a project maintainer at [email protected]. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. Maintainers are
obligated to maintain confidentiality with regard to the reporter of an
incident.

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.3.0, available at
[http://contributor-covenant.org/version/1/3/0/][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/3/0/
23 changes: 20 additions & 3 deletions lib/sirp/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,30 @@ class Client
include SIRP
attr_reader :N, :g, :k, :a, :A, :S, :K, :M, :H_AMK, :hash

# @param group [Integer] the group size in bits
def initialize(group = 2048)
# select modulus (N) and generator (g)
@N, @g, @hash = Ng(group)
@k = calc_k(@N, @g, hash)
end

# Phase 1 : Start the authentication process by generating the 'A' value
# and send it, along with the username, to the server.
#
# @return [String] the value of 'A' in hex
def start_authentication
# Generate a/A private and public components
@a ||= SecureRandom.hex(32).hex
@A = num_to_hex(calc_A(@a, @N, @g))
end

# Process initiated authentication challenge.
# Returns M if authentication is successful, false otherwise.
# Salt and B should be given in hex.
# Phase 1 : Process the salt and B value provided by the server.
#
# @param username [String] the client provided authentication username
# @param password [String] the client provided authentication password
# @param xsalt [String] the server provided salt for the username in hex
# @param xbb [String] the server verifier 'B' value in hex
# @return [String] the client 'M' value in hex
def process_challenge(username, password, xsalt, xbb)
bb = xbb.to_i(16)

Expand All @@ -43,6 +52,14 @@ def process_challenge(username, password, xsalt, xbb)
@M
end

# Phase 2 : Verify that the server provided H(A,M,K) value matches
# the client generated version. This is the last step of mutual
# authentication and confirms that the client and server have
# completed the auth process.
#
# @param server_HAMK [String] the server provided H_AMK in hex
# @return [true,false] returns true if the server and client agree on the
# H_AMK value, false if not
def verify(server_HAMK)
return false unless @H_AMK
# Secure constant time comparison, hash the params to ensure
Expand Down
14 changes: 7 additions & 7 deletions lib/sirp/sirp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ def sha_str(s, hash_klass)
end

# Constant time string comparison.
# Extracted from Rack::Utils
# https://github.com/rack/rack/blob/master/lib/rack/utils.rb
# Extracted from Rack::Utils
# https://github.com/rack/rack/blob/master/lib/rack/utils.rb
#
# NOTE: the values compared should be of fixed length, such as strings
# that have already been processed by HMAC. This should not be used
# on variable length plaintext strings because it could leak length info
# via timing attacks. The user provided value should always be passed
# in as the second parameter so as not to leak info about the secret.
# NOTE: the values compared should be of fixed length, such as strings
# that have already been processed by HMAC. This should not be used
# on variable length plaintext strings because it could leak length info
# via timing attacks. The user provided value should always be passed
# in as the second parameter so as not to leak info about the secret.
#
# @param a [String] the private value
# @param b [String] the user provided value
Expand Down
46 changes: 35 additions & 11 deletions lib/sirp/verifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,32 @@ def initialize(group = 2048)
@k = calc_k(@N, @g, hash)
end

# Initial user creation for the persistance layer.
# Not part of the authentication process.
# Returns { <username>, <password verifier>, <salt> }
# Phase 0 ; Generate a verifier and salt client-side. This should be
# used during the initial user registration process. All three values
# should be provided as attributes in the user registration process. The
# verifier and salt should be persisted server-side. The verifier
# should be protected and never made public or returned to the user.
# The salt should be returned to the user to start Phase 1 of the
# authentication process.
#
# @param username [String] the authentication username
# @param password [String] the authentication password
# @return [Hash] a Hash of the username, verifier, and salt
def generate_userauth(username, password)
@salt ||= SecureRandom.hex(10)
x = calc_x(username, password, @salt, hash)
v = calc_v(x, @N, @g)
{ username: username, verifier: num_to_hex(v), salt: @salt }
end

# Authentication phase 1 - create challenge.
# Returns Hash with challenge for client and proof to be stored on server.
# Parameters should be given in hex.
# Phase 1 - Create a challenge for the client, and a proof to be stored
# on the server for later use when verifying the client response.
#
# @param username [String] the client provided authentication username
# @param xverifier [String] the server stored verifier for the username in hex
# @param xsalt [String] the server stored salt for the username in hex
# @param xaa [String] the client provided 'A' value in hex
# @return [Hash] a Hash with the challenge for the client and a proof for the server
def get_challenge_and_proof(username, xverifier, xsalt, xaa)
# SRP-6a safety check
return false if (xaa.to_i(16) % @N).zero?
Expand All @@ -34,9 +47,20 @@ def get_challenge_and_proof(username, xverifier, xsalt, xaa)
}
end

# returns H_AMK on success, false on failure
# User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K)
# Host -> User: H(A, M, K)
# Phase 2 - Use the server stored proof and the client provided 'M' value.
# Calculates a server 'M' value and compares it to the client provided one,
# and if they match the client and server have negotiated equal secrets.
# Returns a H(A, M, K) value on success and false on failure.
#
# Sets the @K value, which is the client and server negotiated secret key
# if verification succeeds. This can be used to derive strong encryption keys
# for later use. The client independently calculates the same @K value as well.
#
# If authentication fails the H_AMK value must not be provided to the client.
#
# @param proof [Hash] the server stored proof Hash with keys A, B, b, I, s, v
# @param client_M [String] the client provided 'M' value in hex
# @return [String, false] the H_AMK value in hex for the client, or false if verification failed
def verify_session(proof, client_M)
@A = proof[:A]
@B = proof[:B]
Expand Down Expand Up @@ -65,8 +89,8 @@ def verify_session(proof, client_M)
end
end

# generates challenge
# input verifier in hex
# @param xverifier [String] the server stored verifier for the username in hex
# @return [String] the B value in hex
def generate_B(xverifier)
v = xverifier.to_i(16)
@b ||= SecureRandom.hex(32).hex
Expand Down

0 comments on commit e27e83b

Please sign in to comment.