Permalink
Browse files

Manually merged in Christian's XML security fix. ( onelogin@78586a3 )

  • Loading branch information...
1 parent 135a19a commit 5bc840505b526ef0faff61838543e27c65a06766 Cal Heldenbrand committed Feb 14, 2012
Showing with 24 additions and 4 deletions.
  1. +9 −4 lib/xml_security.rb
  2. +11 −0 test/response_test.rb
  3. +4 −0 test/test_helper.rb
View
@@ -45,7 +45,7 @@ def initialize(response)
def validate(settings, soft = true)
@settings = settings
- x509_cert = self.elements["//ds:X509Certificate"]
+ x509_cert = REXML::XPath.first(self, "//ds:X509Certificate")
# What to do if the document doesn't have an X509 cert?
# I'm not sure if the SAML specs require a cert with signed docs,
# or if the absense of a cert means this document is not signed.
@@ -105,10 +105,11 @@ def validate_doc(base64_cert, soft = true)
hashed_element = REXML::XPath.first(self, "//[@ID='#{uri[1,uri.size]}']")
canoner = XML::Util::XmlCanonicalizer.new(false, true)
canoner.inclusive_namespaces = inclusive_namespaces if canoner.respond_to?(:inclusive_namespaces) && !inclusive_namespaces.empty?
- canon_hashed_element = canoner.canonicalize(hashed_element)
+ canon_hashed_element = canoner.canonicalize(hashed_element).gsub('&', '&')
hash = Base64.encode64(Digest::SHA1.digest(canon_hashed_element)).chomp
digest_value = REXML::XPath.first(ref, "//ds:DigestValue", {"ds"=>"http://www.w3.org/2000/09/xmldsig#"}).text
- if hash != digest_value
+
+ unless digests_match?(hash, digest_value)
return soft ? false : (raise Onelogin::Saml::ValidationError.new("Digest mismatch"))
end
end
@@ -133,7 +134,11 @@ def validate_doc(base64_cert, soft = true)
end
private
-
+
+ def digests_match?(hash, digest_value)
+ hash == digest_value
+ end
+
def extract_signed_element_id
reference_element = REXML::XPath.first(self, "//ds:Signature/ds:SignedInfo/ds:Reference", {"ds"=>DSIG})
self.signed_element_id = reference_element.attribute("URI").value unless reference_element.nil?
View
@@ -7,6 +7,17 @@ class RubySamlTest < Test::Unit::TestCase
assert_raises(ArgumentError) { Onelogin::Saml::Response.new(nil) }
end
+ should "be able to parse a document which contains ampersands" do
+ XMLSecurity::SignedDocument.any_instance.stubs(:digests_match?).returns(true)
+ Onelogin::Saml::Response.any_instance.stubs(:validate_conditions).returns(true)
+
+ response = Onelogin::Saml::Response.new(ampersands_response)
+ settings = Onelogin::Saml::Settings.new
+ settings.idp_cert_fingerprint = 'c51985d947f1be57082025050846eb27f6cab783'
+ response.settings = settings
+ response.validate!
+ end
+
should "adapt namespace" do
response = Onelogin::Saml::Response.new(response_document)
assert !response.name_id.nil?
View
@@ -39,6 +39,10 @@ def response_document_5
@response_document5 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response5.xml.base64'))
end
+ def ampersands_response
+ @ampersands_resposne ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response_with_ampersands.xml.base64'))
+ end
+
def response_document_6
doc = Base64.decode64(response_document)
doc.gsub!(/NotBefore=\"(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z\"/, "NotBefore=\"#{(Time.now-300).getutc.strftime("%Y-%m-%dT%XZ")}\"")

0 comments on commit 5bc8405

Please sign in to comment.