Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/omniauth/login_dot_gov/id_token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def verify_nonce(session_nonce_digest)
def decoded_id_token
@decoded_id_token ||= JWT.decode(
id_token,
client.idp_configuration.public_key,
client.idp_configuration.public_keys,
true,
algorithm: 'RS256',
leeway: 10
Expand Down
10 changes: 6 additions & 4 deletions lib/omniauth/login_dot_gov/idp_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ def end_session_endpoint
openid_configuration['end_session_endpoint']
end

def public_key
@public_key = begin
certs = JSON.parse(jwks_endpoint_response.body)
JSON::JWK.new(certs['keys'].first).to_key
def public_keys
@public_keys = begin
keys = JSON.parse(jwks_endpoint_response.body)['keys']
keys.map do |key|
JSON::JWK.new(key).to_key
end
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/omniauth/login_dot_gov/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module OmniAuth
module LoginDotGov
VERSION = '2.2.0'.freeze
VERSION = '3.0.0'.freeze
end
end
2 changes: 1 addition & 1 deletion spec/omniauth/login_dot_gov/callback_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
let(:id_token_jwt) do
JWT.encode(
{ nonce: nonce },
IdpFixtures.private_key,
IdpFixtures.private_keys.first,
'RS256'
)
end
Expand Down
2 changes: 1 addition & 1 deletion spec/omniauth/login_dot_gov/id_token_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Response values
let(:access_token) { 'access-token-1234' }
let(:id_token_jwt) do
JWT.encode({ asdf: 1234 }, IdpFixtures.private_key, 'RS256')
JWT.encode({ asdf: 1234 }, IdpFixtures.private_keys.first, 'RS256')
end
let(:token_response_body) do
{
Expand Down
27 changes: 24 additions & 3 deletions spec/omniauth/login_dot_gov/id_token_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

let(:jwt_nonce) { session_nonce }
let(:jwt) do
JWT.encode({ nonce: jwt_nonce }, IdpFixtures.private_key, 'RS256')
JWT.encode({ nonce: jwt_nonce }, IdpFixtures.private_keys.first, 'RS256')
end

subject do
Expand Down Expand Up @@ -35,16 +35,37 @@
)
end
end

context 'when the key is signed by any of the private_keys' do
it 'returns true' do
aggregate_failures do
IdpFixtures.private_keys.each do |private_key|
jwt = JWT.encode({ nonce: jwt_nonce }, private_key, 'RS256')
expect(subject.verify_nonce(session_nonce_digest)).to eq(true)
end
end
end
end

context 'when the key is signed by an invalid private_key' do
let(:jwt) { JWT.encode({ nonce: jwt_nonce }, OpenSSL::PKey::RSA.new(2048), 'RS256') }
it 'raises VerificationError' do
expect do
subject.verify_nonce(session_nonce_digest)
end.to raise_error(JWT::VerificationError)
end
end

context 'when the token nbf is within 10 seconds past decoding time' do
let(:jwt) { JWT.encode({ nbf: Time.now.to_i + 10, nonce: jwt_nonce }, IdpFixtures.private_key, 'RS256') }
let(:jwt) { JWT.encode({ nbf: Time.now.to_i + 10, nonce: jwt_nonce }, IdpFixtures.private_keys.first, 'RS256') }

it 'allows 10 seconds of leeway' do
expect(subject.verify_nonce(session_nonce_digest)).to eq true
end
end

context 'when the token nbf is not within 10 seconds past decoding time' do
let(:jwt) { JWT.encode({ nbf: Time.now.to_i + 11, nonce: jwt_nonce }, IdpFixtures.private_key, 'RS256') }
let(:jwt) { JWT.encode({ nbf: Time.now.to_i + 11, nonce: jwt_nonce }, IdpFixtures.private_keys.first, 'RS256') }

it 'raises ImmatureSignature error' do
expect { subject.verify_nonce(session_nonce_digest) }.to raise_error(
Expand Down
10 changes: 5 additions & 5 deletions spec/omniauth/login_dot_gov/idp_configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,24 @@
end
end

describe '#public_key' do
describe '#public_keys' do
before { stub_openid_configuration_request }

context 'when the certs request is successful' do
before { stub_jwks_request }

it 'returns the IDP public key' do
result = subject.public_key
it 'returns the IDP public keys' do
result = subject.public_keys

expect(result.to_pem).to eq(IdpFixtures.public_key.to_pem)
expect(result.map(&:to_pem)).to eq(IdpFixtures.public_keys.map(&:to_pem))
end
end

context 'when the certs request fails' do
before { stub_jwks_request(body: 'Not found', status: 404) }

it 'raises an error' do
expect { subject.public_key }.to raise_error(
expect { subject.public_keys }.to raise_error(
OmniAuth::LoginDotGov::OpenidDiscoveryError,
'JWKS request failed with status code: 404'
)
Expand Down
16 changes: 10 additions & 6 deletions spec/support/fixtures/idp_fixtures.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
module IdpFixtures
def self.private_key
@private_key ||= OpenSSL::PKey::RSA.new(2048)
def self.private_keys
@private_keys ||= [OpenSSL::PKey::RSA.new(2048), OpenSSL::PKey::RSA.new(2048)]
end

def self.public_key
@public_key ||= private_key.public_key
def self.public_keys
@public_keys ||= private_keys.map do |private_key|
private_key.public_key
end
end

def self.public_key_jwk
JSON::JWK.new(public_key)
def self.public_key_jwks
public_keys.map do |public_key|
JSON::JWK.new(public_key)
end
end

def self.base_url
Expand Down
6 changes: 3 additions & 3 deletions spec/support/idp_webmocks/jwks_webmock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ def stub_jwks_request(body: default_jwks_response_body, status: 200)
end

def default_jwks_response_body
jwks_response_body(key: IdpFixtures.public_key_jwk)
jwks_response_body(keys: IdpFixtures.public_key_jwks)
end

def jwks_response_body(key:)
{ keys: [key] }.to_json
def jwks_response_body(keys:)
{ keys: keys }.to_json
end
end
4 changes: 2 additions & 2 deletions spec/support/mock_idp_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def jwks_uri
IdpFixtures.jwks_uri
end

def public_key
IdpFixtures.public_key
def public_keys
IdpFixtures.public_keys
end
end