Skip to content

Commit cc295ea

Browse files
committed
Ensure sig is added as first child of root in XML and add tests
1 parent deaf112 commit cc295ea

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

lib/xml_security.rb

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,13 @@ def sign_document(private_key, certificate, signature_method = RSA_SHA1, digest_
159159
x509_cert_element.text = Base64.encode64(certificate.to_der).gsub(/\n/, "")
160160

161161
# add the signature
162-
issuer_element = self.elements["//saml:Issuer"]
162+
issuer_element = elements["//saml:Issuer"]
163163
if issuer_element
164-
self.root.insert_after(issuer_element, signature_element)
164+
root.insert_after(issuer_element, signature_element)
165+
elsif first_child = root.children[0]
166+
root.insert_before(first_child, signature_element)
165167
else
166-
if sp_sso_descriptor = self.elements["/md:EntityDescriptor/md:SPSSODescriptor"]
167-
self.root.insert_before(sp_sso_descriptor, signature_element)
168-
else
169-
self.root.add_element(signature_element)
170-
end
168+
root.add_element(signature_element)
171169
end
172170
end
173171

test/metadata_test.rb

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ class MetadataTest < Minitest::Test
314314
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>]m, xml_text
315315
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], xml_text
316316
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], xml_text
317+
317318
signed_metadata = XMLSecurity::SignedDocument.new(xml_text)
318319
assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false)
319320

@@ -331,9 +332,51 @@ class MetadataTest < Minitest::Test
331332
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], xml_text
332333
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha512'/>], xml_text
333334

334-
signed_metadata_2 = XMLSecurity::SignedDocument.new(xml_text)
335+
signed_metadata = XMLSecurity::SignedDocument.new(xml_text)
336+
assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false)
337+
338+
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
339+
end
340+
end
341+
342+
describe "when custom metadata elements have been inserted" do
343+
let(:xml_text) { subclass.new.generate(settings, false) }
344+
let(:subclass) do
345+
Class.new(OneLogin::RubySaml::Metadata) do
346+
def add_extras(root, _settings)
347+
idp = REXML::Element.new("md:IDPSSODescriptor")
348+
idp.attributes['protocolSupportEnumeration'] = 'urn:oasis:names:tc:SAML:2.0:protocol'
349+
350+
nid = REXML::Element.new("md:NameIDFormat")
351+
nid.text = 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'
352+
idp.add_element(nid)
353+
354+
sso = REXML::Element.new("md:SingleSignOnService")
355+
sso.attributes['Binding'] = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
356+
sso.attributes['Location'] = 'https://foobar.com/sso'
357+
idp.add_element(sso)
358+
root.insert_before(root.children[0], idp)
359+
360+
org = REXML::Element.new("md:Organization")
361+
org.add_element("md:OrganizationName", 'xml:lang' => "en-US").text = 'ACME Inc.'
362+
org.add_element("md:OrganizationDisplayName", 'xml:lang' => "en-US").text = 'ACME'
363+
org.add_element("md:OrganizationURL", 'xml:lang' => "en-US").text = 'https://www.acme.com'
364+
root.insert_after(root.children[3], org)
365+
end
366+
end
367+
end
368+
369+
it "inserts signature as the first child of root element" do
370+
first_child = xml_doc.root.children[0]
371+
assert_equal first_child.prefix, 'ds'
372+
assert_equal first_child.name, 'Signature'
373+
374+
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>]m, xml_text
375+
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], xml_text
376+
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], xml_text
335377

336-
assert signed_metadata_2.validate_document(ruby_saml_cert_fingerprint, false)
378+
signed_metadata = XMLSecurity::SignedDocument.new(xml_text)
379+
assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false)
337380

338381
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
339382
end

0 commit comments

Comments
 (0)