Skip to content

Commit

Permalink
Merge pull request #112 from 18F/dmm/fix-namespace-bug-for-all-requests
Browse files Browse the repository at this point in the history
Include namespace bug fix for all validations
  • Loading branch information
Sgtpluck authored Aug 8, 2024
2 parents b829d7b + 224aa05 commit e52d679
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 146 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
saml_idp (0.21.7.pre.18f)
saml_idp (0.21.8.pre.18f)
activesupport
builder
faraday
Expand Down
4 changes: 2 additions & 2 deletions lib/saml_idp/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def matching_cert
Array(service_provider.certs).find do |cert|
document.valid_signature?(
fingerprint(cert),
options.merge(cert:, digest_method_fix_enabled: true)
options.merge(cert:)
)
end
end
Expand All @@ -189,7 +189,7 @@ def cert_errors
Array(service_provider.certs).map do |cert|
document.gather_errors(
fingerprint(cert),
options.merge(cert:, digest_method_fix_enabled: true)
options.merge(cert:)
)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/saml_idp/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module SamlIdp
VERSION = '0.21.7-18f'.freeze
VERSION = '0.21.8-18f'.freeze
end
20 changes: 5 additions & 15 deletions lib/saml_idp/xml_security.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ def validate_doc(base64_cert, soft = true, options = {})
else
validate_doc_embedded_signature(
base64_cert,
soft,
digest_method_fix_enabled: options[:digest_method_fix_enabled]
soft
)
end
end
Expand Down Expand Up @@ -172,8 +171,7 @@ def validate_doc_params_signature(base64_cert, soft = true, params)

def validate_doc_embedded_signature(
base64_cert,
soft = true,
digest_method_fix_enabled: false
soft = true
)
# check for inclusive namespaces
inclusive_namespaces = extract_inclusive_namespaces
Expand Down Expand Up @@ -204,10 +202,7 @@ def validate_doc_embedded_signature(
inclusive_namespaces
)

digest_algorithm = digest_method_algorithm(
ref,
digest_method_fix_enabled
)
digest_algorithm = digest_method_algorithm(ref)

hash = digest_algorithm.digest(canon_hashed_element)

Expand All @@ -233,13 +228,8 @@ def validate_doc_embedded_signature(
verify_signature(base64_cert, sig_alg, signature, canon_string, soft)
end

def digest_method_algorithm(ref, digest_method_fix_enabled)
digest_method = ref.at_xpath('//ds:DigestMethod | //DigestMethod', DS_NS)
if digest_method_fix_enabled || digest_method.namespace&.prefix.present?
algorithm(digest_method)
else
algorithm(nil)
end
def digest_method_algorithm(ref)
algorithm(ref.at_xpath('//ds:DigestMethod | //DigestMethod', DS_NS))
end

def verify_signature(base64_cert, sig_alg, signature, canon_string, soft)
Expand Down
140 changes: 13 additions & 127 deletions spec/xml_security_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,31 +63,6 @@ module SamlIdp
end
end
end

describe 'options[:digest_method_fix_enabled]' do
let(:xml_string) do
SamlIdp::Request.from_deflated_request(
signed_auth_request
).raw_xml
end

let(:digest_method_fix_enabled) { true }
let(:options) { { digest_method_fix_enabled: } }

context 'digest_method_fix_enabled is set to true' do
it 'validates the doc successfully' do
expect(subject.validate_doc(base64cert, true, options)).to be true
end
end

context 'digest_method_fix_enabled is set to false' do
let(:digest_method_fix_enabled) { false }

it 'validates the doc successfully' do
expect(subject.validate_doc(base64cert, true, options)).to be true
end
end
end
end

describe '#validate' do
Expand Down Expand Up @@ -147,114 +122,25 @@ module SamlIdp
sig_element.at_xpath('//ds:Reference | //Reference', ds_namespace)
end

context 'digest_method_fix_enabled is true' do
let(:digest_method_fix_enabled) { true }

context 'document does not have ds namespace for Signature elements' do
it 'returns the value in the DigestMethod node' do
expect(subject.send(
:digest_method_algorithm,
ref,
digest_method_fix_enabled
)).to eq OpenSSL::Digest::SHA256
end

describe 'when the DigestMethod node does not exist' do
before do
ref.at_xpath('//ds:DigestMethod | //DigestMethod', ds_namespace).remove
end

it 'returns the default algorithm type' do
expect(subject.send(
:digest_method_algorithm,
ref,
digest_method_fix_enabled
)).to eq OpenSSL::Digest::SHA1
end
end
end

context 'document does have ds namespace for Signature elements' do
let(:xml_string) do
SamlIdp::Request.from_deflated_request(
signed_auth_request
).raw_xml
end

it 'returns the value in the DigestMethod node' do
expect(subject.send(
:digest_method_algorithm,
ref,
digest_method_fix_enabled
)).to eq OpenSSL::Digest::SHA256
end

describe 'when the DigestMethod node does not exist' do
before do
ref.at_xpath('//ds:DigestMethod | //DigestMethod', ds_namespace).remove
end

it 'returns the default algorithm type' do
expect(subject.send(
:digest_method_algorithm,
ref,
digest_method_fix_enabled
)).to eq OpenSSL::Digest::SHA1
end
end
context 'when document does not have ds namespace for Signature elements' do
let(:xml_string) { fixture('valid_no_ns.xml', path: 'requests') }


it 'returns the value in the DigestMethod node' do
expect(subject.send(:digest_method_algorithm, ref)).to eq OpenSSL::Digest::SHA256
end
end

context 'digest_method_fix_enabled is false' do
let(:digest_method_fix_enabled) { false }

context 'document does not have ds namespace for Signature elements' do
let(:xml_string) { fixture('valid_no_ns.xml', path: 'requests') }

it 'returns the default algorithm type' do
expect(subject.send(
:digest_method_algorithm,
ref,
digest_method_fix_enabled
)).to eq OpenSSL::Digest::SHA1
end

describe 'when the namespace hash is not defined' do
it 'returns the default algorithm type' do
expect(subject.send(
:digest_method_algorithm,
ref,
digest_method_fix_enabled
)).to eq OpenSSL::Digest::SHA1
end
end
context 'document does have ds namespace for Signature elements' do
let(:xml_string) do
SamlIdp::Request.from_deflated_request(
signed_auth_request
).raw_xml
end

context 'document does have ds namespace for Signature elements' do
let(:xml_string) do
SamlIdp::Request.from_deflated_request(
signed_auth_request
).raw_xml
end

it 'returns the value in the DigestMethod node' do
expect(subject.send(
:digest_method_algorithm,
ref,
digest_method_fix_enabled
)).to eq OpenSSL::Digest::SHA256
end

describe 'when the namespace hash is not defined' do
it 'returns the value in the DigestMethod node' do
# in this scenario, the undefined namespace hash is ignored
expect(subject.send(
:digest_method_algorithm,
ref,
digest_method_fix_enabled
)).to eq OpenSSL::Digest::SHA256
end
end
it 'returns the value in the DigestMethod node' do
expect(subject.send(:digest_method_algorithm, ref)).to eq OpenSSL::Digest::SHA256
end
end
end
Expand Down

0 comments on commit e52d679

Please sign in to comment.