This repository has been archived by the owner on Aug 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reorganize and modernize spec to rspec expect format. 100% code cover…
…age. Disable rspec should.
- Loading branch information
Showing
7 changed files
with
467 additions
and
336 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,3 +30,7 @@ Style/FormatString: | |
|
||
Style/MethodName: | ||
Enabled: false | ||
|
||
Style/NumericLiterals: | ||
Enabled: false | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
# encoding: utf-8 | ||
require 'spec_helper' | ||
|
||
describe SIRP do | ||
# Simulate actual authentication scenario over HTTP | ||
# when the server is RESTful and has to persist authentication | ||
# state between challenge and response. | ||
# | ||
context 'simulated authentication' do | ||
before :all do | ||
@username = 'leonardo' | ||
password = 'icnivad' | ||
@auth = SIRP::Verifier.new(1024).generate_userauth(@username, password) | ||
|
||
# Simulate database persistance layer | ||
@db = { | ||
@username => { | ||
verifier: @auth[:verifier], | ||
salt: @auth[:salt] | ||
} | ||
} | ||
end | ||
|
||
it 'should authenticate with matching server and client params' do | ||
client = SIRP::Client.new(1024) | ||
verifier = SIRP::Verifier.new(1024) | ||
|
||
# phase 1 (client) | ||
aa = client.start_authentication | ||
|
||
# phaase 1 (server) | ||
v = @auth[:verifier] | ||
salt = @auth[:salt] | ||
bb = verifier.generate_B(v) | ||
b = format('%x' % verifier.b) | ||
|
||
# phase 2 (client) | ||
client_M = client.process_challenge(@username, 'icnivad', salt, bb) | ||
|
||
# phase 2 (server) | ||
proof = { A: aa, B: bb, b: b, I: @username, s: salt, v: v } | ||
server_H_AMK = verifier.verify_session(proof, client_M) | ||
expect(server_H_AMK).to be_truthy | ||
|
||
# phase 2 (client) | ||
expect(client.verify(server_H_AMK)).to be true | ||
end | ||
|
||
it 'should not authenticate when a bad password is injected in the flow' do | ||
client = SIRP::Client.new(1024) | ||
verifier = SIRP::Verifier.new(1024) | ||
|
||
# phase 1 (client) | ||
aa = client.start_authentication | ||
|
||
# phaase 1 (server) | ||
v = @auth[:verifier] | ||
salt = @auth[:salt] | ||
bb = verifier.generate_B(v) | ||
b = format('%x' % verifier.b) | ||
|
||
# phase 2 (client) | ||
client_M = client.process_challenge(@username, 'BAD PASSWORD', salt, bb) | ||
|
||
# phase 2 (server) | ||
proof = { A: aa, B: bb, b: b, I: @username, s: salt, v: v } | ||
server_H_AMK = verifier.verify_session(proof, client_M) | ||
expect(server_H_AMK).to be false | ||
|
||
# phase 2 (client) | ||
expect(client.verify(server_H_AMK)).to be false | ||
end | ||
|
||
it 'should authenticate when simulating a stateless server' do | ||
username = @username | ||
|
||
# START PHASE 1 | ||
|
||
# P1 : client generates A and begins auth | ||
client = SIRP::Client.new(1024) | ||
aa = client.start_authentication | ||
|
||
# P1 : username and A are sent (client -> server) | ||
|
||
# P1 : server finds user in DB | ||
_user = @db[username] | ||
expect(_user).not_to be_nil | ||
v = _user[:verifier] | ||
salt = _user[:salt] | ||
|
||
# P1 : server generates B, saves A and B to DB | ||
verifier = SIRP::Verifier.new(1024) | ||
_session = verifier.get_challenge_and_proof(username, v, salt, aa) | ||
expect(_session[:challenge][:B]).to eq verifier.B | ||
expect(_session[:challenge][:salt]).to eq salt | ||
|
||
# P1 : store proof to memory | ||
_user[:session_proof] = _session[:proof] | ||
|
||
# P1 : clear variables to simulate end of phase 1 | ||
verifier = username = v = bb = salt = nil | ||
|
||
# P1 : server sends salt and B to client | ||
client_response = _session[:challenge] | ||
|
||
# P1 : client receives B and salt (server -> client) | ||
bb = client_response[:B] | ||
salt = client_response[:salt] | ||
|
||
# START PHASE 2 | ||
|
||
# P2 : client generates session key | ||
# at this point _client_srp.a should be persisted! | ||
# calculate_client_key is stateful! | ||
mmc = client.process_challenge(@username, 'icnivad', salt, bb) | ||
expect(client.A).to be_truthy | ||
expect(client.M).to eq mmc | ||
expect(client.K).to be_truthy | ||
expect(client.H_AMK).to be_truthy | ||
|
||
# P2 : client sends username and M -> server | ||
client_M = client.M | ||
|
||
# P2 : server receives client M (client -> server) | ||
_user = @db[@username] | ||
|
||
# P2 : server retrives session from DB | ||
proof = _user[:session_proof] | ||
verifier = SIRP::Verifier.new(1024) | ||
server_H_AMK = verifier.verify_session(proof, client_M) | ||
expect(server_H_AMK).to be_truthy | ||
|
||
# Now the two parties have a shared, strong session key K. | ||
# To complete authentication, they need to prove to each other that | ||
# their keys match. | ||
|
||
expect(client.verify(server_H_AMK)).to be true | ||
expect(client.K).to eq verifier.K | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# encoding: utf-8 | ||
require 'spec_helper' | ||
|
||
describe SIRP do | ||
# From http://srp.stanford.edu/demo/demo.html using 1024 bit SHA1 values. | ||
context 'client' do | ||
before :all do | ||
@username = 'user' | ||
@password = 'password' | ||
@salt = '16ccfa081895fe1ed0bb' | ||
@a = '7ec87196e320a2f8dfe8979b1992e0d34439d24471b62c40564bb4302866e1c2' | ||
@b = '8143e2f299852a05717427ea9d87c6146e747d0da6e95f4390264e55a43ae96' | ||
end | ||
|
||
it 'should calculate A from random a' do | ||
client = SIRP::Client.new(1024) | ||
aa1 = client.start_authentication | ||
expect(('%b' % aa1.to_i(16)).length).to be >= 1000 | ||
|
||
client = SIRP::Client.new(1024) | ||
aa2 = client.start_authentication | ||
expect(('%b' % aa2.to_i(16)).length).to be >= 1000 | ||
|
||
expect(aa1).not_to eq aa2 | ||
end | ||
|
||
it 'should calculate A deterministicly from known @a' do | ||
client = SIRP::Client.new(1024) | ||
client.set_a(@a.to_i(16)) | ||
aa = client.start_authentication | ||
expect(aa).to eq '165366e23a10006a62fb8a0793757a299e2985103ad2e8cdee0cc37cac109f3f338ee12e2440eda97bfa7c75697709a5dc66faadca7806d43ea5839757d134ae7b28dd3333049198cc8d328998b8cd8352ff4e64b3bd5f08e40148d69b0843bce18cbbb30c7e4760296da5c92717fcac8bddc7875f55302e55d90a34226868d2' | ||
end | ||
|
||
it 'should calculate client session (S) and secret (K)' do | ||
client = SIRP::Client.new(1024) | ||
client.set_a(@a.to_i(16)) | ||
aa = client.start_authentication | ||
|
||
# Simulate server B | ||
bb = '56777d24af1121bd6af6aeb84238ff8d250122fe75ed251db0f47c289642ae7adb9ef319ce3ab23b6ecc97e5904749fc42f12bb016ecf39691db541f066667b8399bfa685c82b03ad8f92f75975ed086dbe0d470d4dd907ce11b19ee41b74aee72bd8445cde6b58c01f678e39ed9cd6b93c79382637df90777a96c10a768c510' | ||
mm = client.process_challenge(@username, @password, @salt, bb) | ||
|
||
# Client keys | ||
expect(client.S).to eq '7f44592cc616e0d761b2d3309d513b69b386c35f3ed9b11e6d43f15799b673d6dcfa4117b4456af978458d62ad61e1a37be625f46d2a5bd9a50aae359e4541275f0f4bd4b4caed9d2da224b491231f905d47abd9953179aa608854b84a0e0c6195e73715932b41ab8d0d4a2977e7642163be6802c5907fb9e233b8c96e457314' | ||
expect(client.K).to eq '404bf923682abeeb3c8c9164d2cdb6b6ba21b64d' | ||
end | ||
|
||
it 'should verify true with matching server H_AMK' do | ||
server_HAMK = 'abc123' | ||
client = SIRP::Client.new(1024) | ||
client.set_h_amk('abc123') | ||
expect(client.verify(server_HAMK)).to be true | ||
end | ||
|
||
it 'should verify false with non-matching server H_AMK' do | ||
server_HAMK = 'bbaadd' | ||
client = SIRP::Client.new(1024) | ||
client.set_h_amk('abc123') | ||
expect(client.verify(server_HAMK)).to be false | ||
end | ||
end | ||
end |
Oops, something went wrong.