diff --git a/test/logoutrequest_test.rb b/test/logoutrequest_test.rb index 0ade74d6..0f62f2e7 100644 --- a/test/logoutrequest_test.rb +++ b/test/logoutrequest_test.rb @@ -352,6 +352,7 @@ class RequestTest < Minitest::Test end it "raises error when no valid certs and :check_sp_cert_expiration is true" do + settings.certificate, settings.private_key = CertificateHelper.generate_pem_array(algorithm, not_after: Time.now - 60) settings.security[:check_sp_cert_expiration] = true assert_raises(RubySaml::ValidationError, 'The SP certificate expired.') do diff --git a/test/request_test.rb b/test/request_test.rb index f98f466e..5176ebeb 100644 --- a/test/request_test.rb +++ b/test/request_test.rb @@ -240,159 +240,6 @@ class RequestTest < Minitest::Test assert_match(/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport<\/saml:AuthnContextDeclRef>/, auth_doc.to_s) end - describe "#create_params signing with HTTP-POST binding" do - before do - settings.idp_sso_service_url = "http://example.com?field=value" - settings.idp_sso_service_binding = :post - settings.security[:authn_requests_signed] = true - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text - end - - it "create a signed request" do - params = RubySaml::Authrequest.new.create_params(settings) - request_xml = Base64.decode64(params["SAMLRequest"]) - assert_match %r[([a-zA-Z0-9/+=]+)], request_xml - assert_match %r[], request_xml - end - - it "create a signed request with 256 digest and signature methods" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 - settings.security[:digest_method] = RubySaml::XML::Document::SHA512 - - params = RubySaml::Authrequest.new.create_params(settings) - - request_xml = Base64.decode64(params["SAMLRequest"]) - assert_match %r[([a-zA-Z0-9/+=]+)], request_xml - assert_match %r[], request_xml - assert_match %r[], request_xml - end - - it "creates a signed request using the first certificate and key" do - settings.certificate = nil - settings.private_key = nil - settings.sp_cert_multi = { - signing: [ - { certificate: ruby_saml_cert_text, private_key: ruby_saml_key_text }, - CertificateHelper.generate_pem_hash - ] - } - - params = RubySaml::Authrequest.new.create_params(settings) - - request_xml = Base64.decode64(params["SAMLRequest"]) - assert_match %r[([a-zA-Z0-9/+=]+)], request_xml - assert_match %r[], request_xml - end - - it "creates a signed request using the first valid certificate and key when :check_sp_cert_expiration is true" do - settings.certificate = nil - settings.private_key = nil - settings.security[:check_sp_cert_expiration] = true - settings.sp_cert_multi = { - signing: [ - { certificate: ruby_saml_cert_text, private_key: ruby_saml_key_text }, - CertificateHelper.generate_pem_hash - ] - } - - params = RubySaml::Authrequest.new.create_params(settings) - - request_xml = Base64.decode64(params["SAMLRequest"]) - assert_match %r[([a-zA-Z0-9/+=]+)], request_xml - assert_match %r[], request_xml - end - - it "raises error when no valid certs and :check_sp_cert_expiration is true" do - settings.security[:check_sp_cert_expiration] = true - - assert_raises(RubySaml::ValidationError, 'The SP certificate expired.') do - RubySaml::Authrequest.new.create_params(settings) - end - end - end - - describe "#create_params signing with HTTP-Redirect binding" do - let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) } - - before do - settings.idp_sso_service_url = "http://example.com?field=value" - settings.idp_sso_service_binding = :redirect - settings.assertion_consumer_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" - settings.security[:authn_requests_signed] = true - settings.certificate = ruby_saml_cert_text - settings.private_key = ruby_saml_key_text - end - - it "create a signature parameter with RSA_SHA1 and validate it" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 - - params = RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com') - assert params['SAMLRequest'] - assert params[:RelayState] - assert params['Signature'] - assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA1 - - query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}" - query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" - query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" - - signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) - assert_equal signature_algorithm, OpenSSL::Digest::SHA1 - assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) - end - - it "create a signature parameter with RSA_SHA256 and validate it" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 - - params = RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com') - assert params['Signature'] - assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA256 - - query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}" - query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" - query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" - - signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) - assert_equal signature_algorithm, OpenSSL::Digest::SHA256 - assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) - end - - it "create a signature parameter using the first certificate and key" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 - settings.certificate = nil - settings.private_key = nil - settings.sp_cert_multi = { - signing: [ - { certificate: ruby_saml_cert_text, private_key: ruby_saml_key_text }, - CertificateHelper.generate_pem_hash - ] - } - - params = RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com') - assert params['SAMLRequest'] - assert params[:RelayState] - assert params['Signature'] - assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA1 - - query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}" - query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" - query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" - - signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) - assert_equal signature_algorithm, OpenSSL::Digest::SHA1 - assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) - end - - it "raises error when no valid certs and :check_sp_cert_expiration is true" do - settings.security[:check_sp_cert_expiration] = true - - assert_raises(RubySaml::ValidationError, 'The SP certificate expired.') do - RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com') - end - end - end - it "create the saml:AuthnContextClassRef element correctly" do settings.authn_context = 'secure/name/password/uri' auth_doc = RubySaml::Authrequest.new.create_authentication_xml_doc(settings) @@ -437,5 +284,165 @@ class RequestTest < Minitest::Test assert_equal "new_uuid", authnrequest.request_id end end + + with_each_key_algorithm do |algorithm| + describe "#create_params signing with HTTP-POST binding" do + before do + settings.idp_sso_service_url = "http://example.com?field=value" + settings.idp_sso_service_binding = :post + settings.security[:authn_requests_signed] = true + settings.certificate, settings.private_key = CertificateHelper.generate_pem_array(algorithm) + end + + it "create a signed request" do + params = RubySaml::Authrequest.new.create_params(settings) + request_xml = Base64.decode64(params["SAMLRequest"]) + assert_match %r[([a-zA-Z0-9/+=]+)], request_xml + assert_match signature_method_matcher(algorithm), request_xml + assert_match %r[], request_xml + end + + it "create a signed request with 256 digest and signature methods" do + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 + settings.security[:digest_method] = RubySaml::XML::Document::SHA512 + + params = RubySaml::Authrequest.new.create_params(settings) + + request_xml = Base64.decode64(params["SAMLRequest"]) + assert_match %r[([a-zA-Z0-9/+=]+)], request_xml + assert_match signature_method_matcher(algorithm), request_xml + assert_match %r[], request_xml + end + + it "creates a signed request using the first certificate and key" do + settings.certificate = nil + settings.private_key = nil + settings.sp_cert_multi = { + signing: [ + CertificateHelper.generate_pem_hash(algorithm), + CertificateHelper.generate_pem_hash + ] + } + + params = RubySaml::Authrequest.new.create_params(settings) + + request_xml = Base64.decode64(params["SAMLRequest"]) + assert_match %r[([a-zA-Z0-9/+=]+)], request_xml + assert_match signature_method_matcher(algorithm), request_xml + assert_match %r[], request_xml + end + + it "creates a signed request using the first valid certificate and key when :check_sp_cert_expiration is true" do + settings.certificate = nil + settings.private_key = nil + settings.security[:check_sp_cert_expiration] = true + settings.sp_cert_multi = { + signing: [ + CertificateHelper.generate_pem_hash(algorithm), + CertificateHelper.generate_pem_hash + ] + } + + params = RubySaml::Authrequest.new.create_params(settings) + + request_xml = Base64.decode64(params["SAMLRequest"]) + assert_match %r[([a-zA-Z0-9/+=]+)], request_xml + assert_match signature_method_matcher(algorithm), request_xml + assert_match %r[], request_xml + end + + it "raises error when no valid certs and :check_sp_cert_expiration is true" do + settings.certificate, settings.private_key = CertificateHelper.generate_pem_array(algorithm, not_after: Time.now - 60) + settings.security[:check_sp_cert_expiration] = true + + assert_raises(RubySaml::ValidationError, 'The SP certificate expired.') do + RubySaml::Authrequest.new.create_params(settings) + end + end + end + + describe "#create_params signing with HTTP-Redirect binding" do + let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) } + + before do + settings.idp_sso_service_url = "http://example.com?field=value" + settings.idp_sso_service_binding = :redirect + settings.assertion_consumer_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" + settings.security[:authn_requests_signed] = true + settings.certificate = ruby_saml_cert_text + settings.private_key = ruby_saml_key_text + end + + it "create a signature parameter with RSA_SHA1 and validate it" do + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 + + params = RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com') + assert params['SAMLRequest'] + assert params[:RelayState] + assert params['Signature'] + assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA1 + + query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}" + query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" + query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" + + signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) + assert_equal signature_algorithm, OpenSSL::Digest::SHA1 + assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) + end + + it "create a signature parameter with RSA_SHA256 and validate it" do + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 + + params = RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com') + assert params['Signature'] + assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA256 + + query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}" + query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" + query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" + + signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) + assert_equal signature_algorithm, OpenSSL::Digest::SHA256 + assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) + end + + it "create a signature parameter using the first certificate and key" do + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 + settings.certificate = nil + settings.private_key = nil + cert, pkey = CertificateHelper.generate_pair(algorithm) + settings.sp_cert_multi = { + signing: [ + { certificate: cert.to_pem, private_key: pkey.to_pem }, + CertificateHelper.generate_pem_hash + ] + } + + params = RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com') + assert params['SAMLRequest'] + assert params[:RelayState] + assert params['Signature'] + assert_equal params['SigAlg'], signature_method(algorithm, :sha1) + + query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}" + query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" + query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" + + signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) + assert_equal signature_algorithm, OpenSSL::Digest::SHA1 + assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) + end + + it "raises error when no valid certs and :check_sp_cert_expiration is true" do + settings.certificate, settings.private_key = CertificateHelper.generate_pem_array(algorithm, not_after: Time.now - 60) + settings.security[:check_sp_cert_expiration] = true + + assert_raises(RubySaml::ValidationError, 'The SP certificate expired.') do + RubySaml::Authrequest.new.create_params(settings, :RelayState => 'http://example.com') + end + end + end + end end end diff --git a/test/slo_logoutresponse_test.rb b/test/slo_logoutresponse_test.rb index efd33142..cc2ef8f6 100644 --- a/test/slo_logoutresponse_test.rb +++ b/test/slo_logoutresponse_test.rb @@ -97,260 +97,272 @@ class SloLogoutresponseTest < Minitest::Test end end - describe "signing with HTTP-POST binding" do - before do - settings.idp_sso_service_binding = :redirect - settings.idp_slo_service_binding = :post - settings.security[:logout_responses_signed] = true + describe "#manipulate response_id" do + it "be able to modify the response id" do + logoutresponse = RubySaml::SloLogoutresponse.new + response_id = logoutresponse.response_id + assert_equal response_id, logoutresponse.uuid + logoutresponse.uuid = "new_uuid" + assert_equal logoutresponse.response_id, logoutresponse.uuid + assert_equal "new_uuid", logoutresponse.response_id end + end - it "doesn't sign through create_xml_document" do - unauth_res = RubySaml::SloLogoutresponse.new - inflated = unauth_res.create_xml_document(settings).to_s + with_each_key_algorithm do |algorithm| + describe "signing with HTTP-POST binding" do + before do + settings.idp_sso_service_binding = :redirect + settings.idp_slo_service_binding = :post + settings.security[:logout_responses_signed] = true + settings.certificate, settings.private_key = CertificateHelper.generate_pem_array(algorithm) + end - refute_match %r[([a-zA-Z0-9/+=]+)], inflated - refute_match %r[], inflated - refute_match %r[], inflated - end + it "doesn't sign through create_xml_document" do + unauth_res = RubySaml::SloLogoutresponse.new + inflated = unauth_res.create_xml_document(settings).to_s - it "sign unsigned request" do - unauth_res = RubySaml::SloLogoutresponse.new - unauth_res_doc = unauth_res.create_xml_document(settings) - inflated = unauth_res_doc.to_s + refute_match %r[([a-zA-Z0-9/+=]+)], inflated + refute_match signature_method_matcher(algorithm), inflated + refute_match %r[], inflated + end - refute_match %r[([a-zA-Z0-9/+=]+)], inflated - refute_match %r[], inflated - refute_match %r[], inflated + it "sign unsigned request" do + unauth_res = RubySaml::SloLogoutresponse.new + unauth_res_doc = unauth_res.create_xml_document(settings) + inflated = unauth_res_doc.to_s - inflated = unauth_res.sign_document(unauth_res_doc, settings).to_s + refute_match %r[([a-zA-Z0-9/+=]+)], inflated + refute_match signature_method_matcher(algorithm), inflated + refute_match %r[], inflated - assert_match %r[([a-zA-Z0-9/+=]+)], inflated - assert_match %r[], inflated - assert_match %r[], inflated - end + inflated = unauth_res.sign_document(unauth_res_doc, settings).to_s - it "signs through create_logout_response_xml_doc" do - unauth_res = RubySaml::SloLogoutresponse.new - inflated = unauth_res.create_logout_response_xml_doc(settings).to_s + assert_match %r[([a-zA-Z0-9/+=]+)], inflated + assert_match signature_method_matcher(algorithm), inflated + assert_match %r[], inflated + end - assert_match %r[([a-zA-Z0-9/+=]+)], inflated - assert_match %r[], inflated - assert_match %r[], inflated - end + it "signs through create_logout_response_xml_doc" do + unauth_res = RubySaml::SloLogoutresponse.new + inflated = unauth_res.create_logout_response_xml_doc(settings).to_s - it "create a signed logout response" do - logout_request.settings = settings + assert_match %r[([a-zA-Z0-9/+=]+)], inflated + assert_match signature_method_matcher(algorithm), inflated + assert_match %r[], inflated + end - params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") + it "create a signed logout response" do + logout_request.settings = settings - response_xml = Base64.decode64(params["SAMLResponse"]) - assert_match %r[([a-zA-Z0-9/+=]+)], response_xml - assert_match(//, response_xml) - assert_match(//, response_xml) - end + params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") - it "create a signed logout response with SHA384 digest and signature method RSA_SHA512" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA512 - settings.security[:digest_method] = RubySaml::XML::Document::SHA384 - logout_request.settings = settings + response_xml = Base64.decode64(params["SAMLResponse"]) + assert_match %r[([a-zA-Z0-9/+=]+)], response_xml + assert_match(signature_method_matcher(algorithm), response_xml) + assert_match(//, response_xml) + end - params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") + it "create a signed logout response with SHA384 digest and signature method RSA_SHA512" do + # SHA384/SHA512 not supported by DSA + skip if algorithm == :dsa - response_xml = Base64.decode64(params["SAMLResponse"]) - assert_match %r[([a-zA-Z0-9/+=]+)], response_xml - assert_match(//, response_xml) - assert_match(//, response_xml) - end + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA512 + settings.security[:digest_method] = RubySaml::XML::Document::SHA384 + logout_request.settings = settings - it "create a signed logout response with SHA512 digest and signature method RSA_SHA384" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA384 - settings.security[:digest_method] = RubySaml::XML::Document::SHA512 - logout_request.settings = settings + params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") - params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") + response_xml = Base64.decode64(params["SAMLResponse"]) + assert_match %r[([a-zA-Z0-9/+=]+)], response_xml + assert_match(signature_method_matcher(algorithm, :sha512), response_xml) + assert_match(//, response_xml) + end - response_xml = Base64.decode64(params["SAMLResponse"]) - assert_match %r[([a-zA-Z0-9/+=]+)], response_xml - assert_match(//, response_xml) - assert_match(//, response_xml) - end + it "create a signed logout response with SHA512 digest and signature method RSA_SHA384" do + # SHA384/SHA512 not supported by DSA + skip if algorithm == :dsa - it "create a signed logout response using the first certificate and key" do - settings.certificate = nil - settings.private_key = nil - settings.sp_cert_multi = { - signing: [ - { certificate: ruby_saml_cert_text, private_key: ruby_saml_key_text }, - CertificateHelper.generate_pem_hash - ] - } - logout_request.settings = settings - - params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") - - response_xml = Base64.decode64(params["SAMLResponse"]) - assert_match %r[([a-zA-Z0-9/+=]+)], response_xml - assert_match(//, response_xml) - assert_match(//, response_xml) - end + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA384 + settings.security[:digest_method] = RubySaml::XML::Document::SHA512 + logout_request.settings = settings - it "create a signed logout response using the first valid certificate and key when :check_sp_cert_expiration is true" do - settings.certificate = nil - settings.private_key = nil - settings.security[:check_sp_cert_expiration] = true - settings.sp_cert_multi = { - signing: [ - { certificate: ruby_saml_cert_text, private_key: ruby_saml_key_text }, - CertificateHelper.generate_pem_hash - ] - } - logout_request.settings = settings - - params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") - - response_xml = Base64.decode64(params["SAMLResponse"]) - assert_match %r[([a-zA-Z0-9/+=]+)], response_xml - assert_match(//, response_xml) - assert_match(//, response_xml) - end + params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") - it "raises error when no valid certs and :check_sp_cert_expiration is true" do - settings.security[:check_sp_cert_expiration] = true - logout_request.settings = settings + response_xml = Base64.decode64(params["SAMLResponse"]) + assert_match %r[([a-zA-Z0-9/+=]+)], response_xml + assert_match(signature_method_matcher(algorithm, :sha384), response_xml) + assert_match(//, response_xml) + end - assert_raises(RubySaml::ValidationError, 'The SP certificate expired.') do - RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") + it "create a signed logout response using the first certificate and key" do + settings.certificate = nil + settings.private_key = nil + settings.sp_cert_multi = { + signing: [ + CertificateHelper.generate_pem_hash(algorithm), + CertificateHelper.generate_pem_hash + ] + } + logout_request.settings = settings + + params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") + + response_xml = Base64.decode64(params["SAMLResponse"]) + assert_match %r[([a-zA-Z0-9/+=]+)], response_xml + assert_match(signature_method_matcher(algorithm), response_xml) + assert_match(//, response_xml) end - end - end - describe "signing with HTTP-Redirect binding" do - let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) } + it "create a signed logout response using the first valid certificate and key when :check_sp_cert_expiration is true" do + settings.certificate = nil + settings.private_key = nil + settings.security[:check_sp_cert_expiration] = true + settings.sp_cert_multi = { + signing: [ + CertificateHelper.generate_pem_hash(algorithm), + CertificateHelper.generate_pem_hash + ] + } + logout_request.settings = settings + + params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") + + response_xml = Base64.decode64(params["SAMLResponse"]) + assert_match %r[([a-zA-Z0-9/+=]+)], response_xml + assert_match(signature_method_matcher(algorithm), response_xml) + assert_match(//, response_xml) + end + + it "raises error when no valid certs and :check_sp_cert_expiration is true" do + settings.certificate, settings.private_key = CertificateHelper.generate_pem_array(algorithm, not_after: Time.now - 60) + settings.security[:check_sp_cert_expiration] = true + logout_request.settings = settings - before do - settings.idp_sso_service_binding = :post - settings.idp_slo_service_binding = :redirect - settings.security[:logout_responses_signed] = true + assert_raises(RubySaml::ValidationError, 'The SP certificate expired.') do + RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") + end + end end - it "create a signature parameter with RSA_SHA1 and validate it" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 + describe "signing with HTTP-Redirect binding" do + let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) } - params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') - assert params['SAMLResponse'] - assert params[:RelayState] - assert params['Signature'] - assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA1 + before do + settings.idp_sso_service_binding = :post + settings.idp_slo_service_binding = :redirect + settings.security[:logout_responses_signed] = true + end - query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}" - query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" - query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" + it "create a signature parameter with RSA_SHA1 and validate it" do + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 - signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) - assert_equal signature_algorithm, OpenSSL::Digest::SHA1 - assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) - end + params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') + assert params['SAMLResponse'] + assert params[:RelayState] + assert params['Signature'] + assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA1 - it "create a signature parameter with RSA_SHA256 /SHA256 and validate it" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 + query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}" + query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" + query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" - params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') - assert params['SAMLResponse'] - assert params[:RelayState] - assert params['Signature'] + signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) + assert_equal signature_algorithm, OpenSSL::Digest::SHA1 + assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) + end - assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA256 + it "create a signature parameter with RSA_SHA256 /SHA256 and validate it" do + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 - query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}" - query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" - query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" + params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') + assert params['SAMLResponse'] + assert params[:RelayState] + assert params['Signature'] - signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) - assert_equal signature_algorithm, OpenSSL::Digest::SHA256 - assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) - end + assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA256 - it "create a signature parameter with RSA_SHA384 / SHA384 and validate it" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA384 + query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}" + query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" + query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" - params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') - assert params['SAMLResponse'] - assert params[:RelayState] - assert params['Signature'] + signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) + assert_equal signature_algorithm, OpenSSL::Digest::SHA256 + assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) + end - assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA384 + it "create a signature parameter with RSA_SHA384 / SHA384 and validate it" do + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA384 - query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}" - query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" - query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" + params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') + assert params['SAMLResponse'] + assert params[:RelayState] + assert params['Signature'] - signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) - assert_equal signature_algorithm, OpenSSL::Digest::SHA384 - assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) - end + assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA384 - it "create a signature parameter with RSA_SHA512 / SHA512 and validate it" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA512 + query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}" + query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" + query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" - params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') - assert params['SAMLResponse'] - assert params[:RelayState] - assert params['Signature'] + signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) + assert_equal signature_algorithm, OpenSSL::Digest::SHA384 + assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) + end - assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA512 + it "create a signature parameter with RSA_SHA512 / SHA512 and validate it" do + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA512 - query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}" - query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" - query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" + params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') + assert params['SAMLResponse'] + assert params[:RelayState] + assert params['Signature'] - signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) - assert_equal signature_algorithm, OpenSSL::Digest::SHA512 - assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) - end + assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA512 - it "create a signature parameter using the first certificate and key" do - settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 - settings.certificate = nil - settings.private_key = nil - settings.sp_cert_multi = { - signing: [ - { certificate: ruby_saml_cert_text, private_key: ruby_saml_key_text }, - CertificateHelper.generate_pem_hash - ] - } - - params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') - assert params['SAMLResponse'] - assert params[:RelayState] - assert params['Signature'] - assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA1 - - query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}" - query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" - query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" - - signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) - assert_equal signature_algorithm, OpenSSL::Digest::SHA1 - assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) - end + query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}" + query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" + query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" - it "raises error when no valid certs and :check_sp_cert_expiration is true" do - settings.security[:check_sp_cert_expiration] = true + signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) + assert_equal signature_algorithm, OpenSSL::Digest::SHA512 + assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) + end - assert_raises(RubySaml::ValidationError, 'The SP certificate expired.') do - RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') + it "create a signature parameter using the first certificate and key" do + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 + settings.certificate = nil + settings.private_key = nil + cert, pkey = CertificateHelper.generate_pair(algorithm) + settings.sp_cert_multi = { + signing: [ + { certificate: cert.to_pem, private_key: pkey.to_pem }, + CertificateHelper.generate_pem_hash + ] + } + + params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') + assert params['SAMLResponse'] + assert params[:RelayState] + assert params['Signature'] + assert_equal params['SigAlg'], signature_method(algorithm, :sha1) + + query_string = "SAMLResponse=#{CGI.escape(params['SAMLResponse'])}" + query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" + query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" + + signature_algorithm = RubySaml::XML::Crypto.hash_algorithm(params['SigAlg']) + assert_equal signature_algorithm, OpenSSL::Digest::SHA1 + assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) end - end - end - describe "#manipulate response_id" do - it "be able to modify the response id" do - logoutresponse = RubySaml::SloLogoutresponse.new - response_id = logoutresponse.response_id - assert_equal response_id, logoutresponse.uuid - logoutresponse.uuid = "new_uuid" - assert_equal logoutresponse.response_id, logoutresponse.uuid - assert_equal "new_uuid", logoutresponse.response_id + it "raises error when no valid certs and :check_sp_cert_expiration is true" do + settings.certificate, settings.private_key = CertificateHelper.generate_pem_array(algorithm, not_after: Time.now - 60) + settings.security[:check_sp_cert_expiration] = true + + assert_raises(RubySaml::ValidationError, 'The SP certificate expired.') do + RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message", :RelayState => 'http://example.com') + end + end end end end