Skip to content

Commit 4321795

Browse files
committed
Add ability to sign metadata.
1 parent 20e4853 commit 4321795

File tree

9 files changed

+54
-9
lines changed

9 files changed

+54
-9
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,10 @@ In order to be able to sign we need first to define the private key and the publ
336336
The settings related to sign are stored in the `security` attribute of the settings:
337337
338338
```ruby
339-
settings.security[:authn_requests_signed] = true # Enable or not signature on AuthNRequest
340-
settings.security[:logout_requests_signed] = true # Enable or not signature on Logout Request
339+
settings.security[:authn_requests_signed] = true # Enable or not signature on AuthNRequest
340+
settings.security[:logout_requests_signed] = true # Enable or not signature on Logout Request
341341
settings.security[:logout_responses_signed] = true # Enable or not signature on Logout Response
342+
settings.security[:metadata_signed] = true # Enable or not signature on Metadata
342343
343344
settings.security[:digest_method] = XMLSecurity::Document::SHA1
344345
settings.security[:signature_method] = XMLSecurity::Document::SHA1

lib/onelogin/ruby-saml/authrequest.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def create_authentication_xml_doc(settings)
111111
end
112112
end
113113

114-
# embebed sign
114+
# embed signature
115115
if settings.security[:authn_requests_signed] && settings.private_key && settings.certificate && settings.security[:embed_sign]
116116
private_key = settings.get_sp_key()
117117
cert = settings.get_sp_cert()

lib/onelogin/ruby-saml/logoutrequest.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def create_logout_request_xml_doc(settings)
8888
sessionindex.text = settings.sessionindex
8989
end
9090

91-
# embebed sign
91+
# embed signature
9292
if settings.security[:logout_requests_signed] && settings.private_key && settings.certificate && settings.security[:embed_sign]
9393
private_key = settings.get_sp_key()
9494
cert = settings.get_sp_cert()

lib/onelogin/ruby-saml/metadata.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module RubySaml
1313
include REXML
1414
class Metadata
1515
def generate(settings)
16-
meta_doc = REXML::Document.new
16+
meta_doc = XMLSecurity::Document.new
1717
root = meta_doc.add_element "md:EntityDescriptor", {
1818
"xmlns:md" => "urn:oasis:names:tc:SAML:2.0:metadata"
1919
}
@@ -85,6 +85,13 @@ def generate(settings)
8585
# <md:XACMLAuthzDecisionQueryDescriptor WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"/>
8686

8787
meta_doc << REXML::XMLDecl.new("1.0", "UTF-8")
88+
89+
# embed signature
90+
if settings.security[:metadata_signed] && settings.private_key && settings.certificate && settings.security[:embed_sign]
91+
private_key = settings.get_sp_key()
92+
meta_doc.sign_document(private_key, cert, settings.security[:signature_method], settings.security[:digest_method])
93+
end
94+
8895
ret = ""
8996
# pretty print the XML so IdP administrators can easily see what the SP supports
9097
meta_doc.write(ret, 1)

lib/onelogin/ruby-saml/slo_logoutresponse.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def create_logout_response_xml_doc(settings, request_id = nil, logout_message =
8686
issuer.text = settings.issuer
8787
end
8888

89-
# embebed sign
89+
# embed signature
9090
if settings.security[:logout_responses_signed] && settings.private_key && settings.certificate && settings.security[:embed_sign]
9191
private_key = settings.get_sp_key()
9292
cert = settings.get_sp_cert()

test/logoutrequest_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class RequestTest < Minitest::Test
8888
end
8989
end
9090

91-
describe "when the settings indicate to sign (embebed) the logout request" do
91+
describe "when the settings indicate to sign (embedded) the logout request" do
9292
it "created a signed logout request" do
9393
settings = OneLogin::RubySaml::Settings.new
9494
settings.idp_slo_target_url = "http://example.com?field=value"

test/metadata_test.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,42 @@ def setup
8484
assert_equal "Friendly Name", req_attr.attribute("FriendlyName").value
8585
assert_equal "Attribute Value", REXML::XPath.first(xml_doc, "//md:AttributeValue").text.strip
8686
end
87+
88+
describe "when the settings indicate to sign (embedded) the metadata" do
89+
it "create a signed metadata" do
90+
settings = OneLogin::RubySaml::Settings.new
91+
settings.issuer = "https://example.com"
92+
settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
93+
settings.assertion_consumer_service_url = "https://foo.example/saml/consume"
94+
settings.security[:metadata_signed] = true
95+
settings.security[:embed_sign] = true
96+
settings.certificate = ruby_saml_cert_text
97+
settings.private_key = ruby_saml_key_text
98+
xml_text = OneLogin::RubySaml::Metadata.new.generate(settings)
99+
100+
assert_match %r[<ds:SignatureValue>\s*([a-zA-Z0-9/+=]+)\s*</ds:SignatureValue>]m, xml_text
101+
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], xml_text
102+
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], xml_text
103+
end
104+
105+
it "create a signed metadata with 256 digest and signature methods" do
106+
settings = OneLogin::RubySaml::Settings.new
107+
settings.issuer = "https://example.com"
108+
settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
109+
settings.assertion_consumer_service_url = "https://foo.example/saml/consume"
110+
settings.security[:metadata_signed] = true
111+
settings.security[:embed_sign] = true
112+
settings.security[:signature_method] = XMLSecurity::Document::SHA256
113+
settings.security[:digest_method] = XMLSecurity::Document::SHA512
114+
settings.certificate = ruby_saml_cert_text
115+
settings.private_key = ruby_saml_key_text
116+
117+
xml_text = OneLogin::RubySaml::Metadata.new.generate(settings)
118+
119+
assert_match %r[<ds:SignatureValue>\s*([a-zA-Z0-9/+=]+)\s*</ds:SignatureValue>]m, xml_text
120+
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], xml_text
121+
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'/>], xml_text
122+
end
123+
end
87124
end
88125
end

test/request_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ class RequestTest < Minitest::Test
143143
end
144144
end
145145

146-
describe "when the settings indicate to sign (embebed) the request" do
146+
describe "when the settings indicate to sign (embedded) the request" do
147147
it "create a signed request" do
148148
settings = OneLogin::RubySaml::Settings.new
149149
settings.compress_request = false

test/slo_logoutresponse_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class SloLogoutresponseTest < Minitest::Test
6565
assert_match /<samlp:StatusMessage>Custom Logout Message<\/samlp:StatusMessage>/, inflated
6666
end
6767

68-
describe "when the settings indicate to sign (embebed) the logout response" do
68+
describe "when the settings indicate to sign (embedded) the logout response" do
6969
it "create a signed logout response" do
7070
settings = OneLogin::RubySaml::Settings.new
7171
settings.compress_response = false

0 commit comments

Comments
 (0)