diff --git a/LICENSE b/LICENSE index c141165e..8f4b441d 100644 --- a/LICENSE +++ b/LICENSE @@ -21,4 +21,3 @@ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/README.md b/README.md index 9aed3671..f5767ede 100644 --- a/README.md +++ b/README.md @@ -411,7 +411,7 @@ but it can be done as follows: * Provide the XML to the parse method if the signature was validated ```ruby -require "xml_security" +require "ruby_saml/xml" require "ruby_saml/utils" require "ruby_saml/idp_metadata_parser" @@ -431,7 +431,7 @@ get.basic_auth uri.user, uri.password if uri.user response = http.request(get) xml = response.body errors = [] -doc = XMLSecurity::SignedDocument.new(xml, errors) +doc = RubySaml::XML::SignedDocument.new(xml, errors) cert_str = "" cert = RubySaml::Utils.format_cert("cert_str") metadata_sign_cert = OpenSSL::X509::Certificate.new(cert) @@ -634,8 +634,8 @@ to specify different certificates for each function. You may also globally set the SP signature and digest method, to be used in SP signing (functions 1 and 2 above): ```ruby - settings.security[:digest_method] = XMLSecurity::Document::SHA1 - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:digest_method] = RubySaml::XML::Document::SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 ``` #### Signing SP Metadata @@ -979,3 +979,14 @@ end # Output XML with custom metadata MyMetadata.new.generate(settings) ``` + +## Attribution + +Portions of the code in `RubySaml::XML` namespace is adapted from earlier work +copyrighted by either Oracle and/or Todd W. Saxton. The original code was distributed +under the Common Development and Distribution License (CDDL) 1.0. This code is planned to +be written entirely in future versions. + +## License + +RubySaml is made available under the MIT License. Refer to [LICENSE](LICENSE). diff --git a/UPGRADING.md b/UPGRADING.md index f333ea55..3af69acb 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -8,14 +8,26 @@ Before attempting to upgrade to `2.0.0`: - Upgrade your project to minimum Ruby 3.0, JRuby 9.4, or TruffleRuby 22. - Upgrade RubySaml to `1.17.x`. Note that RubySaml `1.17.x` is compatible with up to Ruby 3.3. -### Root namespace changed to RubySaml +### Root "OneLogin" namespace changed to "RubySaml" -RubySaml version `2.0.0` changes the root namespace from `OneLogin::RubySaml::` to just `RubySaml::`. This will require you -to search your codebase for the string `OneLogin::` and remove it as appropriate. Aside from this namespace change, +RubySaml version `2.0.0` changes the root namespace from `OneLogin::RubySaml::` to just `RubySaml::`. +Please remove `OneLogin::` and `onelogin/` everywhere in your codebase. Aside from this namespace change, the class names themselves have intentionally been kept the same. -For backward compatibility, the alias `OneLogin = Object` has been set, so `OneLogin::RubySaml::` will still work. -This alias will be removed in RubySaml version `2.1.0`. +Note that the project folder structure has also been updated accordingly. Notably, the directory +`lib/onelogin/schemas` is now `lib/ruby_saml/schemas`. + +For backward compatibility, the alias `OneLogin = Object` has been set, so `OneLogin::RubySaml::` will still work +as before. This alias will be removed in RubySaml version `2.1.0`. + +### Root "XMLSecurity" namespace changed to "RubySaml::XML" + +RubySaml version `2.0.0` changes the namespace `RubySaml::XML::` to `RubySaml::XML::`. Please search your +codebase for `RubySaml::XML::` and replace it as appropriate. In addition, you must replace direct usage of +`require 'xml_security'` with `require 'ruby_saml/xml'`. + +For backward compatibility, the alias `XMLSecurity = RubySaml::XML` has been set, so `RubySaml::XML::` will still work +as before. This alias will be removed in RubySaml version `2.1.0`. ### Security: Change default hashing algorithm to SHA-256 (was SHA-1) @@ -30,9 +42,9 @@ To preserve the old insecure SHA-1 behavior *(not recommended)*, you may set `Ru ```ruby # Preserve RubySaml 1.x insecure SHA-1 behavior settings = RubySaml::Settings.new -settings.idp_cert_fingerprint_algorithm = XMLSecurity::Document::SHA1 -settings.security[:digest_method] = XMLSecurity::Document::SHA1 -settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 +settings.idp_cert_fingerprint_algorithm = RubySaml::XML::Document::SHA1 +settings.security[:digest_method] = RubySaml::XML::Document::SHA1 +settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 ``` ## Updating from 1.12.x to 1.13.0 @@ -108,7 +120,7 @@ The new preferred way to provide _SAMLResponse_, _RelayState_, and _SigAlg_ is v # In this example `query_params` is assumed to contain decoded query parameters, # and `raw_query_params` is assumed to contain encoded query parameters as sent by the IDP. settings = { - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.soft = false } options = { diff --git a/lib/ruby_saml.rb b/lib/ruby_saml.rb index 01410c9a..e3b1fe53 100644 --- a/lib/ruby_saml.rb +++ b/lib/ruby_saml.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'ruby_saml/logging' +require 'ruby_saml/xml' require 'ruby_saml/saml_message' require 'ruby_saml/authrequest' require 'ruby_saml/logoutrequest' @@ -18,5 +19,6 @@ require 'ruby_saml/utils' require 'ruby_saml/version' -# @deprecated This alias will be removed in version 2.1.0 +# @deprecated These aliases add compatibility with v1.x and will be removed in v2.1.0 OneLogin = Object +XMLSecurity = RubySaml::XML diff --git a/lib/ruby_saml/authrequest.rb b/lib/ruby_saml/authrequest.rb index 539b8add..73b9fd19 100644 --- a/lib/ruby_saml/authrequest.rb +++ b/lib/ruby_saml/authrequest.rb @@ -84,7 +84,7 @@ def create_params(settings, params={}) relay_state: relay_state, sig_alg: params['SigAlg'] ) - sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method]) + sign_algorithm = RubySaml::XML::BaseDocument.new.algorithm(settings.security[:signature_method]) signature = sp_signing_key.sign(sign_algorithm.new, url_string) params['Signature'] = encode(signature) end @@ -108,7 +108,7 @@ def create_authentication_xml_doc(settings) def create_xml_document(settings) time = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ") - request_doc = XMLSecurity::Document.new + request_doc = RubySaml::XML::Document.new request_doc.uuid = uuid root = request_doc.add_element "samlp:AuthnRequest", { "xmlns:samlp" => "urn:oasis:names:tc:SAML:2.0:protocol", "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion" } diff --git a/lib/ruby_saml/idp_metadata_parser.rb b/lib/ruby_saml/idp_metadata_parser.rb index 270137fa..9f99b021 100644 --- a/lib/ruby_saml/idp_metadata_parser.rb +++ b/lib/ruby_saml/idp_metadata_parser.rb @@ -376,13 +376,13 @@ def certificates # @return [String|nil] the fingerpint of the X509Certificate if it exists # - def fingerprint(certificate, fingerprint_algorithm = XMLSecurity::Document::SHA256) + def fingerprint(certificate, fingerprint_algorithm = RubySaml::XML::Document::SHA256) @fingerprint ||= begin return unless certificate cert = OpenSSL::X509::Certificate.new(Base64.decode64(certificate)) - fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(fingerprint_algorithm).new + fingerprint_alg = RubySaml::XML::BaseDocument.new.algorithm(fingerprint_algorithm).new fingerprint_alg.hexdigest(cert.to_der).upcase.scan(/../).join(":") end end diff --git a/lib/ruby_saml/logoutrequest.rb b/lib/ruby_saml/logoutrequest.rb index d808c054..f1b6e1d3 100644 --- a/lib/ruby_saml/logoutrequest.rb +++ b/lib/ruby_saml/logoutrequest.rb @@ -81,7 +81,7 @@ def create_params(settings, params={}) relay_state: relay_state, sig_alg: params['SigAlg'] ) - sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method]) + sign_algorithm = RubySaml::XML::BaseDocument.new.algorithm(settings.security[:signature_method]) signature = settings.get_sp_signing_key.sign(sign_algorithm.new, url_string) params['Signature'] = encode(signature) end @@ -105,7 +105,7 @@ def create_logout_request_xml_doc(settings) def create_xml_document(settings) time = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ") - request_doc = XMLSecurity::Document.new + request_doc = RubySaml::XML::Document.new request_doc.uuid = uuid root = request_doc.add_element "samlp:LogoutRequest", { "xmlns:samlp" => "urn:oasis:names:tc:SAML:2.0:protocol", "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion" } diff --git a/lib/ruby_saml/logoutresponse.rb b/lib/ruby_saml/logoutresponse.rb index 7c885239..ae92a1e5 100644 --- a/lib/ruby_saml/logoutresponse.rb +++ b/lib/ruby_saml/logoutresponse.rb @@ -1,8 +1,7 @@ # frozen_string_literal: true -require "xml_security" +require "ruby_saml/xml" require "ruby_saml/saml_message" - require "time" # Only supports SAML 2.0 @@ -45,7 +44,7 @@ def initialize(response, settings = nil, options = {}) @options = options @response = decode_raw_saml(response, settings) - @document = XMLSecurity::SignedDocument.new(@response) + @document = RubySaml::XML::SignedDocument.new(@response) super() end diff --git a/lib/ruby_saml/metadata.rb b/lib/ruby_saml/metadata.rb index a979aa3d..b76624d1 100644 --- a/lib/ruby_saml/metadata.rb +++ b/lib/ruby_saml/metadata.rb @@ -21,7 +21,7 @@ class Metadata # @return [String] XML Metadata of the Service Provider # def generate(settings, pretty_print=false, valid_until=nil, cache_duration=nil) - meta_doc = XMLSecurity::Document.new + meta_doc = RubySaml::XML::Document.new add_xml_declaration(meta_doc) root = add_root_element(meta_doc, settings, valid_until, cache_duration) sp_sso = add_sp_sso_element(root, settings) diff --git a/lib/ruby_saml/response.rb b/lib/ruby_saml/response.rb index 774df663..a12007ea 100644 --- a/lib/ruby_saml/response.rb +++ b/lib/ruby_saml/response.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "xml_security" +require "ruby_saml/xml" require "ruby_saml/attributes" require "time" @@ -65,7 +65,7 @@ def initialize(response, options = {}) end @response = decode_raw_saml(response, settings) - @document = XMLSecurity::SignedDocument.new(@response, @errors) + @document = RubySaml::XML::SignedDocument.new(@response, @errors) if assertion_encrypted? @decrypted_document = generate_decrypted_document @@ -951,7 +951,7 @@ def xpath_from_signed_assertion(subelt=nil) end # Generates the decrypted_document - # @return [XMLSecurity::SignedDocument] The SAML Response with the assertion decrypted + # @return [RubySaml::XML::SignedDocument] The SAML Response with the assertion decrypted # def generate_decrypted_document if settings.nil? || settings.get_sp_decryption_keys.empty? @@ -964,8 +964,8 @@ def generate_decrypted_document end # Obtains a SAML Response with the EncryptedAssertion element decrypted - # @param document_copy [XMLSecurity::SignedDocument] A copy of the original SAML Response with the encrypted assertion - # @return [XMLSecurity::SignedDocument] The SAML Response with the assertion decrypted + # @param document_copy [RubySaml::XML::SignedDocument] A copy of the original SAML Response with the encrypted assertion + # @return [RubySaml::XML::SignedDocument] The SAML Response with the assertion decrypted # def decrypt_assertion_from_document(document_copy) response_node = REXML::XPath.first( @@ -980,7 +980,7 @@ def decrypt_assertion_from_document(document_copy) ) response_node.add(decrypt_assertion(encrypted_assertion_node)) encrypted_assertion_node.remove - XMLSecurity::SignedDocument.new(response_node.to_s) + RubySaml::XML::SignedDocument.new(response_node.to_s) end # Decrypts an EncryptedAssertion element diff --git a/lib/ruby_saml/saml_message.rb b/lib/ruby_saml/saml_message.rb index dd8b2571..9e29f896 100644 --- a/lib/ruby_saml/saml_message.rb +++ b/lib/ruby_saml/saml_message.rb @@ -67,7 +67,7 @@ def id(document) def valid_saml?(document, soft = true) begin xml = Nokogiri::XML(document.to_s) do |config| - config.options = XMLSecurity::BaseDocument::NOKOGIRI_OPTIONS + config.options = RubySaml::XML::BaseDocument::NOKOGIRI_OPTIONS end rescue StandardError => error return false if soft diff --git a/lib/ruby_saml/settings.rb b/lib/ruby_saml/settings.rb index 5b3229c2..8b71a8cd 100644 --- a/lib/ruby_saml/settings.rb +++ b/lib/ruby_saml/settings.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "xml_security" +require "ruby_saml/xml" require "ruby_saml/attribute_service" require "ruby_saml/utils" require "ruby_saml/validation_error" @@ -173,7 +173,7 @@ def get_fingerprint idp_cert_fingerprint || begin idp_cert = get_idp_cert if idp_cert - fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(idp_cert_fingerprint_algorithm).new + fingerprint_alg = RubySaml::XML::BaseDocument.new.algorithm(idp_cert_fingerprint_algorithm).new fingerprint_alg.hexdigest(idp_cert.to_der).upcase.scan(/../).join(":") end end @@ -277,7 +277,7 @@ def get_binding(value) DEFAULTS = { assertion_consumer_service_binding: Utils::BINDINGS[:post], single_logout_service_binding: Utils::BINDINGS[:redirect], - idp_cert_fingerprint_algorithm: XMLSecurity::Document::SHA256, + idp_cert_fingerprint_algorithm: RubySaml::XML::Document::SHA256, compress_request: true, compress_response: true, message_max_bytesize: 250_000, @@ -292,8 +292,8 @@ def get_binding(value) want_name_id: false, metadata_signed: false, embed_sign: false, # Deprecated - digest_method: XMLSecurity::Document::SHA256, - signature_method: XMLSecurity::Document::RSA_SHA256, + digest_method: RubySaml::XML::Document::SHA256, + signature_method: RubySaml::XML::Document::RSA_SHA256, check_idp_cert_expiration: false, check_sp_cert_expiration: false, strict_audience_validation: false, diff --git a/lib/ruby_saml/slo_logoutresponse.rb b/lib/ruby_saml/slo_logoutresponse.rb index d2337816..5dd0ab6d 100644 --- a/lib/ruby_saml/slo_logoutresponse.rb +++ b/lib/ruby_saml/slo_logoutresponse.rb @@ -90,7 +90,7 @@ def create_params(settings, request_id = nil, logout_message = nil, params = {}, relay_state: relay_state, sig_alg: params['SigAlg'] ) - sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method]) + sign_algorithm = RubySaml::XML::BaseDocument.new.algorithm(settings.security[:signature_method]) signature = sp_signing_key.sign(sign_algorithm.new, url_string) params['Signature'] = encode(signature) end @@ -117,7 +117,7 @@ def create_logout_response_xml_doc(settings, request_id = nil, logout_message = def create_xml_document(settings, request_id = nil, logout_message = nil, status_code = nil) time = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ') - response_doc = XMLSecurity::Document.new + response_doc = RubySaml::XML::Document.new response_doc.uuid = uuid destination = settings.idp_slo_response_service_url || settings.idp_slo_service_url diff --git a/lib/ruby_saml/utils.rb b/lib/ruby_saml/utils.rb index 29810b53..a0440ec3 100644 --- a/lib/ruby_saml/utils.rb +++ b/lib/ruby_saml/utils.rb @@ -229,7 +229,7 @@ def self.escape_request_param(param, lowercase_url_encoding) # def self.verify_signature(params) cert, sig_alg, signature, query_string = %i[cert sig_alg signature query_string].map { |k| params[k]} - signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(sig_alg) + signature_algorithm = RubySaml::XML::BaseDocument.new.algorithm(sig_alg) cert.public_key.verify(signature_algorithm.new, Base64.decode64(signature), query_string) end diff --git a/lib/ruby_saml/xml.rb b/lib/ruby_saml/xml.rb new file mode 100644 index 00000000..31bfa691 --- /dev/null +++ b/lib/ruby_saml/xml.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require 'ruby_saml/xml/base_document' +require 'ruby_saml/xml/document' +require 'ruby_saml/xml/signed_document' diff --git a/lib/ruby_saml/xml/base_document.rb b/lib/ruby_saml/xml/base_document.rb new file mode 100644 index 00000000..a2918eab --- /dev/null +++ b/lib/ruby_saml/xml/base_document.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'rexml/document' +require 'rexml/xpath' +require 'nokogiri' +require 'openssl' +require 'digest/sha1' +require 'digest/sha2' + +module RubySaml + module XML + class BaseDocument < REXML::Document + REXML::Document.entity_expansion_limit = 0 + + C14N = 'http://www.w3.org/2001/10/xml-exc-c14n#' + DSIG = 'http://www.w3.org/2000/09/xmldsig#' + NOKOGIRI_OPTIONS = Nokogiri::XML::ParseOptions::STRICT | + Nokogiri::XML::ParseOptions::NONET + + def canon_algorithm(element) + algorithm = element + if algorithm.is_a?(REXML::Element) + algorithm = element.attribute('Algorithm').value + end + + case algorithm + when 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315', + 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments' + Nokogiri::XML::XML_C14N_1_0 + when 'http://www.w3.org/2006/12/xml-c14n11', + 'http://www.w3.org/2006/12/xml-c14n11#WithComments' + Nokogiri::XML::XML_C14N_1_1 + else + Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0 + end + end + + def algorithm(element) + algorithm = element + if algorithm.is_a?(REXML::Element) + algorithm = element.attribute('Algorithm').value + end + + algorithm = algorithm && algorithm =~ /(rsa-)?sha(.*?)$/i && ::Regexp.last_match(2).to_i + + case algorithm + when 1 then OpenSSL::Digest::SHA1 + when 384 then OpenSSL::Digest::SHA384 + when 512 then OpenSSL::Digest::SHA512 + else + OpenSSL::Digest::SHA256 + end + end + end + end +end diff --git a/lib/ruby_saml/xml/document.rb b/lib/ruby_saml/xml/document.rb new file mode 100644 index 00000000..a37ab09f --- /dev/null +++ b/lib/ruby_saml/xml/document.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +require 'ruby_saml/xml/base_document' + +module RubySaml + module XML + class Document < BaseDocument + RSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1' + RSA_SHA256 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' + RSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384' + RSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512' + SHA1 = 'http://www.w3.org/2000/09/xmldsig#sha1' + SHA256 = 'http://www.w3.org/2001/04/xmlenc#sha256' + SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#sha384' + SHA512 = 'http://www.w3.org/2001/04/xmlenc#sha512' + ENVELOPED_SIG = 'http://www.w3.org/2000/09/xmldsig#enveloped-signature' + INC_PREFIX_LIST = '#default samlp saml ds xs xsi md' + + attr_writer :uuid + + def uuid + @uuid ||= document.root&.attributes&.[]('ID') + end + + # + # + # + # + # + # + # + # + # + # etc. + # + # + # + # + # + def sign_document(private_key, certificate, signature_method = RSA_SHA256, digest_method = SHA256) + noko = Nokogiri::XML(to_s) do |config| + config.options = RubySaml::XML::BaseDocument::NOKOGIRI_OPTIONS + end + + signature_element = REXML::Element.new('ds:Signature').add_namespace('ds', DSIG) + signed_info_element = signature_element.add_element('ds:SignedInfo') + signed_info_element.add_element('ds:CanonicalizationMethod', {'Algorithm' => C14N}) + signed_info_element.add_element('ds:SignatureMethod', {'Algorithm'=>signature_method}) + + # Add Reference + reference_element = signed_info_element.add_element('ds:Reference', {'URI' => "##{uuid}"}) + + # Add Transforms + transforms_element = reference_element.add_element('ds:Transforms') + transforms_element.add_element('ds:Transform', {'Algorithm' => ENVELOPED_SIG}) + c14element = transforms_element.add_element('ds:Transform', {'Algorithm' => C14N}) + c14element.add_element('ec:InclusiveNamespaces', {'xmlns:ec' => C14N, 'PrefixList' => INC_PREFIX_LIST}) + + digest_method_element = reference_element.add_element('ds:DigestMethod', {'Algorithm' => digest_method}) + inclusive_namespaces = INC_PREFIX_LIST.split + canon_doc = noko.canonicalize(canon_algorithm(C14N), inclusive_namespaces) + reference_element.add_element('ds:DigestValue').text = compute_digest(canon_doc, algorithm(digest_method_element)) + + # add SignatureValue + noko_sig_element = Nokogiri::XML(signature_element.to_s) do |config| + config.options = RubySaml::XML::BaseDocument::NOKOGIRI_OPTIONS + end + + noko_signed_info_element = noko_sig_element.at_xpath('//ds:Signature/ds:SignedInfo', 'ds' => DSIG) + canon_string = noko_signed_info_element.canonicalize(canon_algorithm(C14N)) + + signature = compute_signature(private_key, algorithm(signature_method).new, canon_string) + signature_element.add_element('ds:SignatureValue').text = signature + + # add KeyInfo + key_info_element = signature_element.add_element('ds:KeyInfo') + x509_element = key_info_element.add_element('ds:X509Data') + x509_cert_element = x509_element.add_element('ds:X509Certificate') + if certificate.is_a?(String) + certificate = OpenSSL::X509::Certificate.new(certificate) + end + x509_cert_element.text = Base64.encode64(certificate.to_der).gsub(/\n/, '') + + # add the signature + issuer_element = elements['//saml:Issuer'] + if issuer_element + root.insert_after(issuer_element, signature_element) + elsif (first_child = root.children[0]) + root.insert_before(first_child, signature_element) + else + root.add_element(signature_element) + end + end + + protected + + def compute_signature(private_key, signature_algorithm, document) + Base64.encode64(private_key.sign(signature_algorithm, document)).gsub(/\n/, '') + end + + def compute_digest(document, digest_algorithm) + digest = digest_algorithm.digest(document) + Base64.encode64(digest).strip + end + end + end +end diff --git a/lib/ruby_saml/xml/signed_document.rb b/lib/ruby_saml/xml/signed_document.rb new file mode 100644 index 00000000..444a062a --- /dev/null +++ b/lib/ruby_saml/xml/signed_document.rb @@ -0,0 +1,238 @@ +# frozen_string_literal: true + +require 'ruby_saml/xml/base_document' +require 'ruby_saml/error_handling' +require 'ruby_saml/utils' + +module RubySaml + module XML + class SignedDocument < BaseDocument + include RubySaml::ErrorHandling + + attr_writer :signed_element_id + + def initialize(response, errors = []) + super(response) + @errors = errors + end + + def signed_element_id + @signed_element_id ||= extract_signed_element_id + end + + def validate_document(idp_cert_fingerprint, soft = true, options = {}) + # get cert from response + cert_element = REXML::XPath.first( + self, + "//ds:X509Certificate", + { "ds"=>DSIG } + ) + + if cert_element + base64_cert = RubySaml::Utils.element_text(cert_element) + cert_text = Base64.decode64(base64_cert) + begin + cert = OpenSSL::X509::Certificate.new(cert_text) + rescue OpenSSL::X509::CertificateError => _e + return append_error('Document Certificate Error', soft) + end + + if options[:fingerprint_alg] + fingerprint_alg = RubySaml::XML::BaseDocument.new.algorithm(options[:fingerprint_alg]).new + else + fingerprint_alg = OpenSSL::Digest.new('SHA256') + end + fingerprint = fingerprint_alg.hexdigest(cert.to_der) + + # check cert matches registered idp cert + if fingerprint != idp_cert_fingerprint.gsub(/[^a-zA-Z0-9]/,'').downcase + return append_error('Fingerprint mismatch', soft) + end + elsif options[:cert] + base64_cert = Base64.encode64(options[:cert].to_pem) + elsif soft + return false + else + return append_error('Certificate element missing in response (ds:X509Certificate) and not cert provided at settings', soft) + end + validate_signature(base64_cert, soft) + end + + def validate_document_with_cert(idp_cert, soft = true) + # get cert from response + cert_element = REXML::XPath.first( + self, + '//ds:X509Certificate', + { 'ds'=>DSIG } + ) + + if cert_element + base64_cert = RubySaml::Utils.element_text(cert_element) + cert_text = Base64.decode64(base64_cert) + begin + cert = OpenSSL::X509::Certificate.new(cert_text) + rescue OpenSSL::X509::CertificateError => _e + return append_error('Document Certificate Error', soft) + end + + # check saml response cert matches provided idp cert + if idp_cert.to_pem != cert.to_pem + return append_error('Certificate of the Signature element does not match provided certificate', soft) + end + else + base64_cert = Base64.encode64(idp_cert.to_pem) + end + validate_signature(base64_cert, true) + end + + def validate_signature(base64_cert, soft = true) + document = Nokogiri::XML(to_s) do |config| + config.options = RubySaml::XML::BaseDocument::NOKOGIRI_OPTIONS + end + + # create a rexml document + @working_copy ||= REXML::Document.new(to_s).root + + # get signature node + sig_element = REXML::XPath.first( + @working_copy, + '//ds:Signature', + {'ds'=>DSIG} + ) + + # signature method + sig_alg_value = REXML::XPath.first( + sig_element, + './ds:SignedInfo/ds:SignatureMethod', + {'ds'=>DSIG} + ) + signature_algorithm = algorithm(sig_alg_value) + + # get signature + base64_signature = REXML::XPath.first( + sig_element, + './ds:SignatureValue', + {'ds' => DSIG} + ) + signature = Base64.decode64(RubySaml::Utils.element_text(base64_signature)) + + # canonicalization method + canon_algorithm = canon_algorithm REXML::XPath.first( + sig_element, + './ds:SignedInfo/ds:CanonicalizationMethod', + 'ds' => DSIG + ) + + noko_sig_element = document.at_xpath('//ds:Signature', 'ds' => DSIG) + noko_signed_info_element = noko_sig_element.at_xpath('./ds:SignedInfo', 'ds' => DSIG) + + canon_string = noko_signed_info_element.canonicalize(canon_algorithm) + noko_sig_element.remove + + # get inclusive namespaces + inclusive_namespaces = extract_inclusive_namespaces + + # check digests + ref = REXML::XPath.first(sig_element, '//ds:Reference', {'ds'=>DSIG}) + + hashed_element = document.at_xpath('//*[@ID=$id]', nil, { 'id' => extract_signed_element_id }) + + canon_algorithm = canon_algorithm REXML::XPath.first( + ref, + '//ds:CanonicalizationMethod', + { 'ds' => DSIG } + ) + + canon_algorithm = process_transforms(ref, canon_algorithm) + + canon_hashed_element = hashed_element.canonicalize(canon_algorithm, inclusive_namespaces) + + digest_algorithm = algorithm(REXML::XPath.first( + ref, + '//ds:DigestMethod', + { 'ds' => DSIG } + )) + hash = digest_algorithm.digest(canon_hashed_element) + encoded_digest_value = REXML::XPath.first( + ref, + '//ds:DigestValue', + { 'ds' => DSIG } + ) + digest_value = Base64.decode64(RubySaml::Utils.element_text(encoded_digest_value)) + + unless digests_match?(hash, digest_value) + return append_error('Digest mismatch', soft) + end + + # get certificate object + cert_text = Base64.decode64(base64_cert) + cert = OpenSSL::X509::Certificate.new(cert_text) + + # verify signature + unless cert.public_key.verify(signature_algorithm.new, signature, canon_string) + return append_error('Key validation error', soft) + end + + true + end + + private + + def process_transforms(ref, canon_algorithm) + transforms = REXML::XPath.match( + ref, + '//ds:Transforms/ds:Transform', + { 'ds' => DSIG } + ) + + transforms.each do |transform_element| + next unless transform_element.attributes && transform_element.attributes['Algorithm'] + + algorithm = transform_element.attributes['Algorithm'] + case algorithm + when 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315', + 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments' + canon_algorithm = Nokogiri::XML::XML_C14N_1_0 + when 'http://www.w3.org/2006/12/xml-c14n11', + 'http://www.w3.org/2006/12/xml-c14n11#WithComments' + canon_algorithm = Nokogiri::XML::XML_C14N_1_1 + when 'http://www.w3.org/2001/10/xml-exc-c14n#', + 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments' + canon_algorithm = Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0 + end + end + + canon_algorithm + end + + 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} + ) + + return nil if reference_element.nil? + + sei = reference_element.attribute('URI').value[1..] + sei.nil? ? reference_element.parent.parent.parent.attribute('ID').value : sei + end + + def extract_inclusive_namespaces + element = REXML::XPath.first( + self, + '//ec:InclusiveNamespaces', + { 'ec' => C14N } + ) + return unless element + + prefix_list = element.attributes.get_attribute('PrefixList').value + prefix_list.split + end + end + end +end diff --git a/lib/xml_security.rb b/lib/xml_security.rb deleted file mode 100644 index fb791d42..00000000 --- a/lib/xml_security.rb +++ /dev/null @@ -1,414 +0,0 @@ -# frozen_string_literal: true - -# The contents of this file are subject to the terms -# of the Common Development and Distribution License -# (the License). You may not use this file except in -# compliance with the License. -# -# You can obtain a copy of the License at -# https://opensso.dev.java.net/public/CDDLv1.0.html or -# opensso/legal/CDDLv1.0.txt -# See the License for the specific language governing -# permission and limitations under the License. -# -# When distributing Covered Code, include this CDDL -# Header Notice in each file and include the License file -# at opensso/legal/CDDLv1.0.txt. -# If applicable, add the following below the CDDL Header, -# with the fields enclosed by brackets [] replaced by -# your own identifying information: -# "Portions Copyrighted [year] [name of copyright owner]" -# -# $Id: xml_sec.rb,v 1.6 2007/10/24 00:28:41 todddd Exp $ -# -# Copyright 2007 Sun Microsystems Inc. All Rights Reserved -# Portions Copyrighted 2007 Todd W Saxton. - -require 'rubygems' -require "rexml/document" -require "rexml/xpath" -require "openssl" -require 'nokogiri' -require "digest/sha1" -require "digest/sha2" -require "ruby_saml/utils" -require "ruby_saml/error_handling" - -module XMLSecurity - - class BaseDocument < REXML::Document - REXML::Document.entity_expansion_limit = 0 - - C14N = "http://www.w3.org/2001/10/xml-exc-c14n#" - DSIG = "http://www.w3.org/2000/09/xmldsig#" - NOKOGIRI_OPTIONS = Nokogiri::XML::ParseOptions::STRICT | - Nokogiri::XML::ParseOptions::NONET - - def canon_algorithm(element) - algorithm = element - if algorithm.is_a?(REXML::Element) - algorithm = element.attribute('Algorithm').value - end - - case algorithm - when "http://www.w3.org/TR/2001/REC-xml-c14n-20010315", - "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" - Nokogiri::XML::XML_C14N_1_0 - when "http://www.w3.org/2006/12/xml-c14n11", - "http://www.w3.org/2006/12/xml-c14n11#WithComments" - Nokogiri::XML::XML_C14N_1_1 - else - Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0 - end - end - - def algorithm(element) - algorithm = element - if algorithm.is_a?(REXML::Element) - algorithm = element.attribute("Algorithm").value - end - - algorithm = algorithm && algorithm =~ /(rsa-)?sha(.*?)$/i && ::Regexp.last_match(2).to_i - - case algorithm - when 1 then OpenSSL::Digest::SHA1 - when 384 then OpenSSL::Digest::SHA384 - when 512 then OpenSSL::Digest::SHA512 - else - OpenSSL::Digest::SHA256 - end - end - - end - - class Document < BaseDocument - RSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1" - RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" - RSA_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384" - RSA_SHA512 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" - SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1" - SHA256 = 'http://www.w3.org/2001/04/xmlenc#sha256' - SHA384 = "http://www.w3.org/2001/04/xmldsig-more#sha384" - SHA512 = 'http://www.w3.org/2001/04/xmlenc#sha512' - ENVELOPED_SIG = "http://www.w3.org/2000/09/xmldsig#enveloped-signature" - INC_PREFIX_LIST = "#default samlp saml ds xs xsi md" - - attr_writer :uuid - - def uuid - @uuid ||= document.root&.attributes&.[]('ID') - end - - # - # - # - # - # - # - # - # - # - # etc. - # - # - # - # - # - def sign_document(private_key, certificate, signature_method = RSA_SHA256, digest_method = SHA256) - noko = Nokogiri::XML(to_s) do |config| - config.options = XMLSecurity::BaseDocument::NOKOGIRI_OPTIONS - end - - signature_element = REXML::Element.new("ds:Signature").add_namespace('ds', DSIG) - signed_info_element = signature_element.add_element("ds:SignedInfo") - signed_info_element.add_element("ds:CanonicalizationMethod", {"Algorithm" => C14N}) - signed_info_element.add_element("ds:SignatureMethod", {"Algorithm"=>signature_method}) - - # Add Reference - reference_element = signed_info_element.add_element("ds:Reference", {"URI" => "##{uuid}"}) - - # Add Transforms - transforms_element = reference_element.add_element("ds:Transforms") - transforms_element.add_element("ds:Transform", {"Algorithm" => ENVELOPED_SIG}) - c14element = transforms_element.add_element("ds:Transform", {"Algorithm" => C14N}) - c14element.add_element("ec:InclusiveNamespaces", {"xmlns:ec" => C14N, "PrefixList" => INC_PREFIX_LIST}) - - digest_method_element = reference_element.add_element("ds:DigestMethod", {"Algorithm" => digest_method}) - inclusive_namespaces = INC_PREFIX_LIST.split - canon_doc = noko.canonicalize(canon_algorithm(C14N), inclusive_namespaces) - reference_element.add_element("ds:DigestValue").text = compute_digest(canon_doc, algorithm(digest_method_element)) - - # add SignatureValue - noko_sig_element = Nokogiri::XML(signature_element.to_s) do |config| - config.options = XMLSecurity::BaseDocument::NOKOGIRI_OPTIONS - end - - noko_signed_info_element = noko_sig_element.at_xpath('//ds:Signature/ds:SignedInfo', 'ds' => DSIG) - canon_string = noko_signed_info_element.canonicalize(canon_algorithm(C14N)) - - signature = compute_signature(private_key, algorithm(signature_method).new, canon_string) - signature_element.add_element("ds:SignatureValue").text = signature - - # add KeyInfo - key_info_element = signature_element.add_element("ds:KeyInfo") - x509_element = key_info_element.add_element("ds:X509Data") - x509_cert_element = x509_element.add_element("ds:X509Certificate") - if certificate.is_a?(String) - certificate = OpenSSL::X509::Certificate.new(certificate) - end - x509_cert_element.text = Base64.encode64(certificate.to_der).gsub(/\n/, "") - - # add the signature - issuer_element = elements["//saml:Issuer"] - if issuer_element - root.insert_after(issuer_element, signature_element) - elsif (first_child = root.children[0]) - root.insert_before(first_child, signature_element) - else - root.add_element(signature_element) - end - end - - protected - - def compute_signature(private_key, signature_algorithm, document) - Base64.encode64(private_key.sign(signature_algorithm, document)).gsub(/\n/, "") - end - - def compute_digest(document, digest_algorithm) - digest = digest_algorithm.digest(document) - Base64.encode64(digest).strip - end - - end - - class SignedDocument < BaseDocument - include RubySaml::ErrorHandling - - attr_writer :signed_element_id - - def initialize(response, errors = []) - super(response) - @errors = errors - end - - def signed_element_id - @signed_element_id ||= extract_signed_element_id - end - - def validate_document(idp_cert_fingerprint, soft = true, options = {}) - # get cert from response - cert_element = REXML::XPath.first( - self, - "//ds:X509Certificate", - { "ds"=>DSIG } - ) - - if cert_element - base64_cert = RubySaml::Utils.element_text(cert_element) - cert_text = Base64.decode64(base64_cert) - begin - cert = OpenSSL::X509::Certificate.new(cert_text) - rescue OpenSSL::X509::CertificateError => _e - return append_error("Document Certificate Error", soft) - end - - if options[:fingerprint_alg] - fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(options[:fingerprint_alg]).new - else - fingerprint_alg = OpenSSL::Digest.new('SHA256') - end - fingerprint = fingerprint_alg.hexdigest(cert.to_der) - - # check cert matches registered idp cert - if fingerprint != idp_cert_fingerprint.gsub(/[^a-zA-Z0-9]/,"").downcase - return append_error("Fingerprint mismatch", soft) - end - elsif options[:cert] - base64_cert = Base64.encode64(options[:cert].to_pem) - elsif soft - return false - else - return append_error("Certificate element missing in response (ds:X509Certificate) and not cert provided at settings", soft) - end - validate_signature(base64_cert, soft) - end - - def validate_document_with_cert(idp_cert, soft = true) - # get cert from response - cert_element = REXML::XPath.first( - self, - "//ds:X509Certificate", - { "ds"=>DSIG } - ) - - if cert_element - base64_cert = RubySaml::Utils.element_text(cert_element) - cert_text = Base64.decode64(base64_cert) - begin - cert = OpenSSL::X509::Certificate.new(cert_text) - rescue OpenSSL::X509::CertificateError => _e - return append_error("Document Certificate Error", soft) - end - - # check saml response cert matches provided idp cert - if idp_cert.to_pem != cert.to_pem - return append_error("Certificate of the Signature element does not match provided certificate", soft) - end - else - base64_cert = Base64.encode64(idp_cert.to_pem) - end - validate_signature(base64_cert, true) - end - - def validate_signature(base64_cert, soft = true) - document = Nokogiri::XML(to_s) do |config| - config.options = XMLSecurity::BaseDocument::NOKOGIRI_OPTIONS - end - - # create a rexml document - @working_copy ||= REXML::Document.new(to_s).root - - # get signature node - sig_element = REXML::XPath.first( - @working_copy, - "//ds:Signature", - {"ds"=>DSIG} - ) - - # signature method - sig_alg_value = REXML::XPath.first( - sig_element, - "./ds:SignedInfo/ds:SignatureMethod", - {"ds"=>DSIG} - ) - signature_algorithm = algorithm(sig_alg_value) - - # get signature - base64_signature = REXML::XPath.first( - sig_element, - "./ds:SignatureValue", - {"ds" => DSIG} - ) - signature = Base64.decode64(RubySaml::Utils.element_text(base64_signature)) - - # canonicalization method - canon_algorithm = canon_algorithm REXML::XPath.first( - sig_element, - './ds:SignedInfo/ds:CanonicalizationMethod', - 'ds' => DSIG - ) - - noko_sig_element = document.at_xpath('//ds:Signature', 'ds' => DSIG) - noko_signed_info_element = noko_sig_element.at_xpath('./ds:SignedInfo', 'ds' => DSIG) - - canon_string = noko_signed_info_element.canonicalize(canon_algorithm) - noko_sig_element.remove - - # get inclusive namespaces - inclusive_namespaces = extract_inclusive_namespaces - - # check digests - ref = REXML::XPath.first(sig_element, "//ds:Reference", {"ds"=>DSIG}) - - hashed_element = document.at_xpath("//*[@ID=$id]", nil, { 'id' => extract_signed_element_id }) - - canon_algorithm = canon_algorithm REXML::XPath.first( - ref, - '//ds:CanonicalizationMethod', - { "ds" => DSIG } - ) - - canon_algorithm = process_transforms(ref, canon_algorithm) - - canon_hashed_element = hashed_element.canonicalize(canon_algorithm, inclusive_namespaces) - - digest_algorithm = algorithm(REXML::XPath.first( - ref, - "//ds:DigestMethod", - { "ds" => DSIG } - )) - hash = digest_algorithm.digest(canon_hashed_element) - encoded_digest_value = REXML::XPath.first( - ref, - "//ds:DigestValue", - { "ds" => DSIG } - ) - digest_value = Base64.decode64(RubySaml::Utils.element_text(encoded_digest_value)) - - unless digests_match?(hash, digest_value) - return append_error("Digest mismatch", soft) - end - - # get certificate object - cert_text = Base64.decode64(base64_cert) - cert = OpenSSL::X509::Certificate.new(cert_text) - - # verify signature - unless cert.public_key.verify(signature_algorithm.new, signature, canon_string) - return append_error("Key validation error", soft) - end - - true - end - - private - - def process_transforms(ref, canon_algorithm) - transforms = REXML::XPath.match( - ref, - "//ds:Transforms/ds:Transform", - { "ds" => DSIG } - ) - - transforms.each do |transform_element| - next unless transform_element.attributes && transform_element.attributes["Algorithm"] - - algorithm = transform_element.attributes["Algorithm"] - case algorithm - when "http://www.w3.org/TR/2001/REC-xml-c14n-20010315", - "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" - canon_algorithm = Nokogiri::XML::XML_C14N_1_0 - when "http://www.w3.org/2006/12/xml-c14n11", - "http://www.w3.org/2006/12/xml-c14n11#WithComments" - canon_algorithm = Nokogiri::XML::XML_C14N_1_1 - when "http://www.w3.org/2001/10/xml-exc-c14n#", - "http://www.w3.org/2001/10/xml-exc-c14n#WithComments" - canon_algorithm = Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0 - end - end - - canon_algorithm - end - - 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} - ) - - return nil if reference_element.nil? - - sei = reference_element.attribute("URI").value[1..] - sei.nil? ? reference_element.parent.parent.parent.attribute("ID").value : sei - end - - def extract_inclusive_namespaces - element = REXML::XPath.first( - self, - "//ec:InclusiveNamespaces", - { "ec" => C14N } - ) - return unless element - - prefix_list = element.attributes.get_attribute("PrefixList").value - prefix_list.split - end - - end -end diff --git a/test/idp_metadata_parser_test.rb b/test/idp_metadata_parser_test.rb index 860aecce..613045fa 100644 --- a/test/idp_metadata_parser_test.rb +++ b/test/idp_metadata_parser_test.rb @@ -157,27 +157,27 @@ def initialize; end settings = idp_metadata_parser.parse(idp_metadata, { :settings => { :security => { - :digest_method => XMLSecurity::Document::SHA256, - :signature_method => XMLSecurity::Document::RSA_SHA256 + :digest_method => RubySaml::XML::Document::SHA256, + :signature_method => RubySaml::XML::Document::RSA_SHA256 } } }) assert_equal "C4:C6:BD:41:EC:AD:57:97:CE:7B:7D:80:06:C3:E4:30:53:29:02:0B:DD:2D:47:02:9E:BD:85:AD:93:02:45:21", settings.idp_cert_fingerprint - assert_equal XMLSecurity::Document::SHA256, settings.security[:digest_method] - assert_equal XMLSecurity::Document::RSA_SHA256, settings.security[:signature_method] + assert_equal RubySaml::XML::Document::SHA256, settings.security[:digest_method] + assert_equal RubySaml::XML::Document::RSA_SHA256, settings.security[:signature_method] end it "merges results into given settings object" do settings = RubySaml::Settings.new(:security => { - :digest_method => XMLSecurity::Document::SHA256, - :signature_method => XMLSecurity::Document::RSA_SHA256 + :digest_method => RubySaml::XML::Document::SHA256, + :signature_method => RubySaml::XML::Document::RSA_SHA256 }) RubySaml::IdpMetadataParser.new.parse(idp_metadata_descriptor, :settings => settings) assert_equal "C4:C6:BD:41:EC:AD:57:97:CE:7B:7D:80:06:C3:E4:30:53:29:02:0B:DD:2D:47:02:9E:BD:85:AD:93:02:45:21", settings.idp_cert_fingerprint - assert_equal XMLSecurity::Document::SHA256, settings.security[:digest_method] - assert_equal XMLSecurity::Document::RSA_SHA256, settings.security[:signature_method] + assert_equal RubySaml::XML::Document::SHA256, settings.security[:digest_method] + assert_equal RubySaml::XML::Document::RSA_SHA256, settings.security[:signature_method] end end @@ -256,8 +256,8 @@ def initialize; end parsed_metadata = idp_metadata_parser.parse_to_hash(idp_metadata, { :settings => { :security => { - :digest_method => XMLSecurity::Document::SHA256, - :signature_method => XMLSecurity::Document::RSA_SHA256 + :digest_method => RubySaml::XML::Document::SHA256, + :signature_method => RubySaml::XML::Document::RSA_SHA256 } } }) diff --git a/test/logoutrequest_test.rb b/test/logoutrequest_test.rb index 2336d72f..98ec156d 100644 --- a/test/logoutrequest_test.rb +++ b/test/logoutrequest_test.rb @@ -177,8 +177,8 @@ class RequestTest < Minitest::Test it "create a signed logout request with 256 digest and signature method" do settings.compress_request = false - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256 - settings.security[:digest_method] = XMLSecurity::Document::SHA256 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 + settings.security[:digest_method] = RubySaml::XML::Document::SHA256 params = RubySaml::Logoutrequest.new.create_params(settings) request_xml = Base64.decode64(params["SAMLRequest"]) @@ -189,8 +189,8 @@ class RequestTest < Minitest::Test it "create a signed logout request with 512 digest and signature method RSA_SHA384" do settings.compress_request = false - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384 - settings.security[:digest_method] = XMLSecurity::Document::SHA512 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA384 + settings.security[:digest_method] = RubySaml::XML::Document::SHA512 params = RubySaml::Logoutrequest.new.create_params(settings) request_xml = Base64.decode64(params["SAMLRequest"]) @@ -261,73 +261,73 @@ class RequestTest < Minitest::Test end it "create a signature parameter with RSA_SHA1 / SHA1 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') assert params['SAMLRequest'] assert params[:RelayState] assert params['Signature'] - assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA1 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 / SHA256 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') assert params['Signature'] - assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA256 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 with RSA_SHA384 / SHA384 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA384 params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') assert params['Signature'] - assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA384 + assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA384 query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}" query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" - signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 it "create a signature parameter with RSA_SHA512 / SHA512 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA512 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA512 params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') assert params['Signature'] - assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA512 + assert_equal params['SigAlg'], RubySaml::XML::Document::RSA_SHA512 query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}" query_string << "&RelayState=#{CGI.escape(params[:RelayState])}" query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}" - signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 it "create a signature parameter using the first certificate and key" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.compress_request = false settings.certificate = nil settings.private_key = nil @@ -342,13 +342,13 @@ class RequestTest < Minitest::Test assert params['SAMLRequest'] assert params[:RelayState] assert params['Signature'] - assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA1 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 @@ -397,19 +397,19 @@ class RequestTest < Minitest::Test end it "create a signature parameter with RSA_SHA1 / SHA1 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') assert params['SAMLRequest'] assert params[:RelayState] assert params['Signature'] - assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA1 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 diff --git a/test/logoutresponse_test.rb b/test/logoutresponse_test.rb index 4d5455b2..55f41901 100644 --- a/test/logoutresponse_test.rb +++ b/test/logoutresponse_test.rb @@ -234,7 +234,7 @@ class RubySamlTest < Minitest::Test it "return true when no idp_cert is provided and option :relax_signature_validation is present" do settings.idp_cert = nil - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params['RelayState'] = params[:RelayState] options = {} options[:get_params] = params @@ -245,7 +245,7 @@ class RubySamlTest < Minitest::Test it "return false when no idp_cert is provided and no option :relax_signature_validation is present" do settings.idp_cert = nil - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params['RelayState'] = params[:RelayState] options = {} options[:get_params] = params @@ -254,7 +254,7 @@ class RubySamlTest < Minitest::Test end it "return true when valid RSA_SHA1 Signature" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params['RelayState'] = params[:RelayState] options = {} options[:get_params] = params @@ -263,7 +263,7 @@ class RubySamlTest < Minitest::Test end it "return true when valid RSA_SHA256 Signature" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 params['RelayState'] = params[:RelayState] options = {} options[:get_params] = params @@ -272,7 +272,7 @@ class RubySamlTest < Minitest::Test end it "return false when invalid RSA_SHA1 Signature" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params['RelayState'] = 'http://invalid.example.com' options = {} options[:get_params] = params @@ -281,7 +281,7 @@ class RubySamlTest < Minitest::Test end it "raise when invalid RSA_SHA1 Signature" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.soft = false params['RelayState'] = 'http://invalid.example.com' options = {} @@ -293,7 +293,7 @@ class RubySamlTest < Minitest::Test end it "raise when get_params encoding differs from what this library generates" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.soft = false options = {} options[:get_params] = params @@ -314,7 +314,7 @@ class RubySamlTest < Minitest::Test refute_equal(query, original_query) assert_equal(CGI.unescape(query), CGI.unescape(original_query)) # Make normalised signature based on our modified params. - sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method]) + sign_algorithm = RubySaml::XML::BaseDocument.new.algorithm(settings.security[:signature_method]) signature = settings.get_sp_signing_key.sign(sign_algorithm.new, query) params['Signature'] = Base64.encode64(signature).gsub(/\n/, "") # Re-create the Logoutresponse based on these modified parameters, @@ -329,7 +329,7 @@ class RubySamlTest < Minitest::Test end it "return true even if raw_get_params encoding differs from what this library generates" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.soft = false options = {} options[:get_params] = params @@ -350,7 +350,7 @@ class RubySamlTest < Minitest::Test refute_equal(query, original_query) assert_equal(CGI.unescape(query), CGI.unescape(original_query)) # Make normalised signature based on our modified params. - sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method]) + sign_algorithm = RubySaml::XML::BaseDocument.new.algorithm(settings.security[:signature_method]) signature = settings.get_sp_signing_key.sign(sign_algorithm.new, query) params['Signature'] = Base64.encode64(signature).gsub(/\n/, "") # Re-create the Logoutresponse based on these modified parameters, @@ -373,7 +373,7 @@ class RubySamlTest < Minitest::Test before do settings.soft = true settings.idp_slo_service_url = "http://example.com?field=value" - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.security[:logout_responses_signed] = true settings.certificate = ruby_saml_cert_text settings.private_key = ruby_saml_key_text diff --git a/test/metadata_test.rb b/test/metadata_test.rb index 2b30c399..b97b8b38 100644 --- a/test/metadata_test.rb +++ b/test/metadata_test.rb @@ -340,7 +340,7 @@ class MetadataTest < Minitest::Test assert_match %r[], xml_text assert_match %r[], xml_text - signed_metadata = XMLSecurity::SignedDocument.new(xml_text) + signed_metadata = RubySaml::XML::SignedDocument.new(xml_text) assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false) assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd") @@ -348,8 +348,8 @@ class MetadataTest < Minitest::Test describe "when digest and signature methods are specified" do before do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256 - settings.security[:digest_method] = XMLSecurity::Document::SHA512 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 + settings.security[:digest_method] = RubySaml::XML::Document::SHA512 end it "creates a signed metadata with specified digest and signature methods" do @@ -357,7 +357,7 @@ class MetadataTest < Minitest::Test assert_match %r[], xml_text assert_match %r[], xml_text - signed_metadata = XMLSecurity::SignedDocument.new(xml_text) + signed_metadata = RubySaml::XML::SignedDocument.new(xml_text) assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false) assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd") @@ -400,7 +400,7 @@ def add_extras(root, _settings) assert_match %r[], xml_text assert_match %r[], xml_text - signed_metadata = XMLSecurity::SignedDocument.new(xml_text) + signed_metadata = RubySaml::XML::SignedDocument.new(xml_text) assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false) assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd") diff --git a/test/onelogin_alias_test.rb b/test/onelogin_alias_test.rb index 18ee3dc9..84e0e628 100644 --- a/test/onelogin_alias_test.rb +++ b/test/onelogin_alias_test.rb @@ -132,7 +132,7 @@ def generate_audience_error(expected, actual) end it "be able to parse a document which contains ampersands" do - XMLSecurity::SignedDocument.any_instance.stubs(:digests_match?).returns(true) + RubySaml::XML::SignedDocument.any_instance.stubs(:digests_match?).returns(true) OneLogin::RubySaml::Response.any_instance.stubs(:validate_conditions).returns(true) ampersands_response = OneLogin::RubySaml::Response.new(ampersands_document) diff --git a/test/request_test.rb b/test/request_test.rb index 1aab6a4b..585158bf 100644 --- a/test/request_test.rb +++ b/test/request_test.rb @@ -258,8 +258,8 @@ class RequestTest < Minitest::Test end it "create a signed request with 256 digest and signature methods" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256 - settings.security[:digest_method] = XMLSecurity::Document::SHA512 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 + settings.security[:digest_method] = RubySaml::XML::Document::SHA512 params = RubySaml::Authrequest.new.create_params(settings) @@ -327,41 +327,41 @@ class RequestTest < Minitest::Test end it "create a signature parameter with RSA_SHA1 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + 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'], XMLSecurity::Document::RSA_SHA1 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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] = XMLSecurity::Document::RSA_SHA256 + 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'], XMLSecurity::Document::RSA_SHA256 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.compress_request = false settings.certificate = nil settings.private_key = nil @@ -376,13 +376,13 @@ class RequestTest < Minitest::Test assert params['SAMLRequest'] assert params[:RelayState] assert params['Signature'] - assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA1 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 @@ -462,19 +462,19 @@ class RequestTest < Minitest::Test end it "create a signature parameter with RSA_SHA1 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + 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'], XMLSecurity::Document::RSA_SHA1 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.algorithm(params['SigAlg']) assert_equal signature_algorithm, OpenSSL::Digest::SHA1 assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string) diff --git a/test/response_test.rb b/test/response_test.rb index 588c3b61..be9a437e 100644 --- a/test/response_test.rb +++ b/test/response_test.rb @@ -74,7 +74,7 @@ def generate_audience_error(expected, actual) end it "be able to parse a document which contains ampersands" do - XMLSecurity::SignedDocument.any_instance.stubs(:digests_match?).returns(true) + RubySaml::XML::SignedDocument.any_instance.stubs(:digests_match?).returns(true) RubySaml::Response.any_instance.stubs(:validate_conditions).returns(true) ampersands_response = RubySaml::Response.new(ampersands_document) @@ -382,7 +382,7 @@ def generate_audience_error(expected, actual) no_signature_response.stubs(:validate_subject_confirmation).returns(true) no_signature_response.settings = settings no_signature_response.settings.idp_cert_fingerprint = "3D:C5:BC:58:60:5D:19:64:94:E3:BA:C8:3D:49:01:D5:56:34:44:65:C2:85:0A:A8:65:A5:AC:76:7E:65:1F:F7" - XMLSecurity::SignedDocument.any_instance.expects(:validate_signature).returns(true) + RubySaml::XML::SignedDocument.any_instance.expects(:validate_signature).returns(true) assert no_signature_response.is_valid? end @@ -1377,7 +1377,7 @@ def generate_audience_error(expected, actual) it 'sign an unsigned SAML Response XML and initiate the SAML object with it' do xml = Base64.decode64(fixture("test_sign.xml")) - document = XMLSecurity::Document.new(xml) + document = RubySaml::XML::Document.new(xml) formatted_cert = RubySaml::Utils.format_cert(ruby_saml_cert_text) cert = OpenSSL::X509::Certificate.new(formatted_cert) diff --git a/test/settings_test.rb b/test/settings_test.rb index 4b0ac49a..523993c6 100644 --- a/test/settings_test.rb +++ b/test/settings_test.rb @@ -118,14 +118,14 @@ class SettingsTest < Minitest::Test settings = RubySaml::Settings.new settings.security[:authn_requests_signed] = true settings.security[:embed_sign] = true - settings.security[:digest_method] = XMLSecurity::Document::SHA512 - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA512 + settings.security[:digest_method] = RubySaml::XML::Document::SHA512 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA512 new_settings = RubySaml::Settings.new assert_equal new_settings.security[:authn_requests_signed], false assert_equal new_settings.security[:embed_sign], false - assert_equal new_settings.security[:digest_method], XMLSecurity::Document::SHA256 - assert_equal new_settings.security[:signature_method], XMLSecurity::Document::RSA_SHA256 + assert_equal new_settings.security[:digest_method], RubySaml::XML::Document::SHA256 + assert_equal new_settings.security[:signature_method], RubySaml::XML::Document::RSA_SHA256 end it "overrides only provided security attributes passing a second parameter" do diff --git a/test/slo_logoutrequest_test.rb b/test/slo_logoutrequest_test.rb index e0e7eb90..d1657c83 100644 --- a/test/slo_logoutrequest_test.rb +++ b/test/slo_logoutrequest_test.rb @@ -59,12 +59,12 @@ class RubySamlTest < Minitest::Test settings.certificate = ruby_saml_cert_text settings.private_key = ruby_saml_key_text settings.idp_cert = ruby_saml_cert_text - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params = {} params['SAMLRequest'] = logout_request_deflated_base64 params['RelayState'] = 'http://invalid.example.com' params['Signature'] = 'invalid_signature' - params['SigAlg'] = XMLSecurity::Document::RSA_SHA1 + params['SigAlg'] = RubySaml::XML::Document::RSA_SHA1 options = {} options[:get_params] = params @@ -307,7 +307,7 @@ class RubySamlTest < Minitest::Test it "return true when no idp_cert is provided and option :relax_signature_validation is present" do settings.idp_cert = nil - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') params['RelayState'] = params[:RelayState] options = {} @@ -320,7 +320,7 @@ class RubySamlTest < Minitest::Test it "return false when no idp_cert is provided and no option :relax_signature_validation is present" do settings.idp_cert = nil - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') params['RelayState'] = params[:RelayState] options = {} @@ -331,7 +331,7 @@ class RubySamlTest < Minitest::Test end it "return true when valid RSA_SHA1 Signature" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') params['RelayState'] = params[:RelayState] options = {} @@ -342,7 +342,7 @@ class RubySamlTest < Minitest::Test end it "return true when valid RSA_SHA256 Signature" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') options = {} options[:get_params] = params @@ -353,7 +353,7 @@ class RubySamlTest < Minitest::Test end it "return false when invalid RSA_SHA1 Signature" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') params['RelayState'] = 'http://invalid.example.com' params[:RelayState] = params['RelayState'] @@ -366,7 +366,7 @@ class RubySamlTest < Minitest::Test end it "raise when invalid RSA_SHA1 Signature" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.soft = false params = RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com') params['RelayState'] = 'http://invalid.example.com' @@ -383,7 +383,7 @@ class RubySamlTest < Minitest::Test it "raise when get_params encoding differs from what this library generates" do # Use Logoutrequest only to build the SAMLRequest parameter. - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.soft = false params = RubySaml::Logoutrequest.new.create_params(settings, "RelayState" => "http://example.com") # Assemble query string. @@ -401,7 +401,7 @@ class RubySamlTest < Minitest::Test refute_equal(query, original_query) assert_equal(CGI.unescape(query), CGI.unescape(original_query)) # Make normalised signature based on our modified params. - sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method]) + sign_algorithm = RubySaml::XML::BaseDocument.new.algorithm(settings.security[:signature_method]) signature = settings.get_sp_signing_key.sign(sign_algorithm.new, query) params['Signature'] = Base64.encode64(signature).gsub(/\n/, "") # Construct SloLogoutrequest and ask it to validate the signature. @@ -418,7 +418,7 @@ class RubySamlTest < Minitest::Test it "return true even if raw_get_params encoding differs from what this library generates" do # Use Logoutrequest only to build the SAMLRequest parameter. - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.soft = false params = RubySaml::Logoutrequest.new.create_params(settings, "RelayState" => "http://example.com") # Assemble query string. @@ -436,7 +436,7 @@ class RubySamlTest < Minitest::Test refute_equal(query, original_query) assert_equal(CGI.unescape(query), CGI.unescape(original_query)) # Make normalised signature based on our modified params. - sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method]) + sign_algorithm = RubySaml::XML::BaseDocument.new.algorithm(settings.security[:signature_method]) signature = settings.get_sp_signing_key.sign(sign_algorithm.new, query) params['Signature'] = Base64.encode64(signature).gsub(/\n/, "") # Construct SloLogoutrequest and ask it to validate the signature. @@ -455,7 +455,7 @@ class RubySamlTest < Minitest::Test it "handles Azure AD downcased request encoding" do # Use Logoutrequest only to build the SAMLRequest parameter. - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 settings.soft = false # Creating the query manually to tweak it later instead of using @@ -473,7 +473,7 @@ class RubySamlTest < Minitest::Test # Assemble query string. query = "SAMLRequest=#{params['SAMLRequest']}&SigAlg=#{params['SigAlg']}" # Make normalised signature based on our modified params. - sign_algorithm = XMLSecurity::BaseDocument.new.algorithm( + sign_algorithm = RubySaml::XML::BaseDocument.new.algorithm( settings.security[:signature_method] ) signature = settings.get_sp_signing_key.sign(sign_algorithm.new, query) @@ -506,7 +506,7 @@ class RubySamlTest < Minitest::Test settings.private_key = ruby_saml_key_text settings.idp_cert = nil settings.security[:logout_requests_signed] = true - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 end it "return true when at least a idp_cert is valid" do diff --git a/test/slo_logoutresponse_test.rb b/test/slo_logoutresponse_test.rb index f55d6afb..32659d57 100644 --- a/test/slo_logoutresponse_test.rb +++ b/test/slo_logoutresponse_test.rb @@ -152,8 +152,8 @@ class SloLogoutresponseTest < Minitest::Test end it "create a signed logout response with SHA384 digest and signature method RSA_SHA512" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA512 - settings.security[:digest_method] = XMLSecurity::Document::SHA384 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA512 + settings.security[:digest_method] = RubySaml::XML::Document::SHA384 logout_request.settings = settings params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message") @@ -165,8 +165,8 @@ class SloLogoutresponseTest < Minitest::Test end it "create a signed logout response with SHA512 digest and signature method RSA_SHA384" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384 - settings.security[:digest_method] = XMLSecurity::Document::SHA512 + 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") @@ -237,82 +237,82 @@ class SloLogoutresponseTest < Minitest::Test end it "create a signature parameter with RSA_SHA1 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 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'], XMLSecurity::Document::RSA_SHA1 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 /SHA256 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA256 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'], XMLSecurity::Document::RSA_SHA256 + assert_equal params['SigAlg'], 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'])}" - signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 with RSA_SHA384 / SHA384 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA384 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'], XMLSecurity::Document::RSA_SHA384 + assert_equal params['SigAlg'], 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'])}" - signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 it "create a signature parameter with RSA_SHA512 / SHA512 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA512 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA512 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'], XMLSecurity::Document::RSA_SHA512 + assert_equal params['SigAlg'], 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'])}" - signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 it "create a signature parameter using the first certificate and key" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 settings.compress_request = false settings.certificate = nil settings.private_key = nil @@ -327,13 +327,13 @@ class SloLogoutresponseTest < Minitest::Test assert params['SAMLResponse'] assert params[:RelayState] assert params['Signature'] - assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA1 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 @@ -390,19 +390,19 @@ class SloLogoutresponseTest < Minitest::Test end it "create a signature parameter with RSA_SHA1 and validate it" do - settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1 + settings.security[:signature_method] = RubySaml::XML::Document::RSA_SHA1 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'], XMLSecurity::Document::RSA_SHA1 + 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 = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg']) + signature_algorithm = RubySaml::XML::BaseDocument.new.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 diff --git a/test/xml_security_test.rb b/test/xml_test.rb similarity index 82% rename from test/xml_security_test.rb rename to test/xml_test.rb index 59919849..b8a67176 100644 --- a/test/xml_security_test.rb +++ b/test/xml_test.rb @@ -1,14 +1,12 @@ require_relative 'test_helper' -require 'xml_security' +require 'ruby_saml/xml' -class XmlSecurityTest < Minitest::Test - include XMLSecurity - - describe "XmlSecurity" do +class XmlTest < Minitest::Test + describe "RubySaml::XML" do let(:decoded_response) { Base64.decode64(response_document_without_recipient) } - let(:document) { XMLSecurity::SignedDocument.new(decoded_response) } - let(:settings) { RubySaml::Settings.new() } + let(:document) { RubySaml::XML::SignedDocument.new(decoded_response) } + let(:settings) { RubySaml::Settings.new } before do @base64cert = document.elements["//ds:X509Certificate"].text @@ -30,7 +28,7 @@ class XmlSecurityTest < Minitest::Test it "not raise an error when softly validating the document and the X509Certificate is missing" do decoded_response.sub!(/.*<\/ds:X509Certificate>/, "") - mod_document = XMLSecurity::SignedDocument.new(decoded_response) + mod_document = RubySaml::XML::SignedDocument.new(decoded_response) assert !mod_document.validate_document("a fingerprint", true) # The fingerprint isn't relevant to this test end @@ -53,7 +51,7 @@ class XmlSecurityTest < Minitest::Test it "should raise Key validation error" do decoded_response.sub!("pJQ7MS/ek4KRRWGmv/H43ReHYMs=", "b9xsAXLsynugg3Wc1CI3kpWku+0=") - mod_document = XMLSecurity::SignedDocument.new(decoded_response) + mod_document = RubySaml::XML::SignedDocument.new(decoded_response) base64cert = mod_document.elements["//ds:X509Certificate"].text exception = assert_raises(RubySaml::ValidationError) do mod_document.validate_signature(base64cert, false) @@ -63,14 +61,14 @@ class XmlSecurityTest < Minitest::Test end it "correctly obtain the digest method with alternate namespace declaration" do - adfs_document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_xmlns, false)) + adfs_document = RubySaml::XML::SignedDocument.new(fixture(:adfs_response_xmlns, false)) base64cert = adfs_document.elements["//X509Certificate"].text assert adfs_document.validate_signature(base64cert, false) end it "raise validation error when the X509Certificate is missing and no cert provided" do decoded_response.sub!(/.*<\/ds:X509Certificate>/, "") - mod_document = XMLSecurity::SignedDocument.new(decoded_response) + mod_document = RubySaml::XML::SignedDocument.new(decoded_response) exception = assert_raises(RubySaml::ValidationError) do mod_document.validate_document("a fingerprint", false) # The fingerprint isn't relevant to this test end @@ -79,7 +77,7 @@ class XmlSecurityTest < Minitest::Test it "invalidaties when the X509Certificate is missing and the cert is provided but mismatches" do decoded_response.sub!(/.*<\/ds:X509Certificate>/, "") - mod_document = XMLSecurity::SignedDocument.new(decoded_response) + mod_document = RubySaml::XML::SignedDocument.new(decoded_response) cert = OpenSSL::X509::Certificate.new(ruby_saml_cert) assert !mod_document.validate_document("a fingerprint", true, :cert => cert) # The fingerprint isn't relevant to this test end @@ -88,48 +86,48 @@ class XmlSecurityTest < Minitest::Test describe "#canon_algorithm" do it "C14N_EXCLUSIVE_1_0" do canon_algorithm = Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0 - assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/2001/10/xml-exc-c14n#") - assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/2001/10/xml-exc-c14n#WithComments") - assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("other") + assert_equal canon_algorithm, RubySaml::XML::BaseDocument.new.canon_algorithm("http://www.w3.org/2001/10/xml-exc-c14n#") + assert_equal canon_algorithm, RubySaml::XML::BaseDocument.new.canon_algorithm("http://www.w3.org/2001/10/xml-exc-c14n#WithComments") + assert_equal canon_algorithm, RubySaml::XML::BaseDocument.new.canon_algorithm("other") end it "C14N_1_0" do canon_algorithm = Nokogiri::XML::XML_C14N_1_0 - assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/TR/2001/REC-xml-c14n-20010315") - assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments") + assert_equal canon_algorithm, RubySaml::XML::BaseDocument.new.canon_algorithm("http://www.w3.org/TR/2001/REC-xml-c14n-20010315") + assert_equal canon_algorithm, RubySaml::XML::BaseDocument.new.canon_algorithm("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments") end it "XML_C14N_1_1" do canon_algorithm = Nokogiri::XML::XML_C14N_1_1 - assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/2006/12/xml-c14n11") - assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/2006/12/xml-c14n11#WithComments") + assert_equal canon_algorithm, RubySaml::XML::BaseDocument.new.canon_algorithm("http://www.w3.org/2006/12/xml-c14n11") + assert_equal canon_algorithm, RubySaml::XML::BaseDocument.new.canon_algorithm("http://www.w3.org/2006/12/xml-c14n11#WithComments") end end describe "#algorithm" do it "SHA1" do alg = OpenSSL::Digest::SHA1 - assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2000/09/xmldsig#rsa-sha1") - assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2000/09/xmldsig#sha1") + assert_equal alg, RubySaml::XML::BaseDocument.new.algorithm("http://www.w3.org/2000/09/xmldsig#rsa-sha1") + assert_equal alg, RubySaml::XML::BaseDocument.new.algorithm("http://www.w3.org/2000/09/xmldsig#sha1") end it "SHA256" do alg = OpenSSL::Digest::SHA256 - assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256") - assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#sha256") - assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("other") + assert_equal alg, RubySaml::XML::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256") + assert_equal alg, RubySaml::XML::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#sha256") + assert_equal alg, RubySaml::XML::BaseDocument.new.algorithm("other") end it "SHA384" do alg = OpenSSL::Digest::SHA384 - assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384") - assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#sha384") + assert_equal alg, RubySaml::XML::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384") + assert_equal alg, RubySaml::XML::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#sha384") end it "SHA512" do alg = OpenSSL::Digest::SHA512 - assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512") - assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#sha512") + assert_equal alg, RubySaml::XML::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512") + assert_equal alg, RubySaml::XML::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#sha512") end end @@ -140,8 +138,8 @@ class XmlSecurityTest < Minitest::Test sha1_fingerprint = "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72" sha1_fingerprint_downcase = sha1_fingerprint.tr(':', '').downcase - assert response_fingerprint_test.document.validate_document(sha1_fingerprint, true, fingerprint_alg: XMLSecurity::Document::SHA1) - assert response_fingerprint_test.document.validate_document(sha1_fingerprint_downcase, true, fingerprint_alg: XMLSecurity::Document::SHA1) + assert response_fingerprint_test.document.validate_document(sha1_fingerprint, true, fingerprint_alg: RubySaml::XML::Document::SHA1) + assert response_fingerprint_test.document.validate_document(sha1_fingerprint_downcase, true, fingerprint_alg: RubySaml::XML::Document::SHA1) end it "validate using SHA256" do @@ -149,46 +147,46 @@ class XmlSecurityTest < Minitest::Test sha256_fingerprint_downcase = sha256_fingerprint.tr(':', '').downcase assert response_fingerprint_test.document.validate_document(sha256_fingerprint) - assert response_fingerprint_test.document.validate_document(sha256_fingerprint, true, fingerprint_alg: XMLSecurity::Document::SHA256) + assert response_fingerprint_test.document.validate_document(sha256_fingerprint, true, fingerprint_alg: RubySaml::XML::Document::SHA256) assert response_fingerprint_test.document.validate_document(sha256_fingerprint_downcase) - assert response_fingerprint_test.document.validate_document(sha256_fingerprint_downcase, true, fingerprint_alg: XMLSecurity::Document::SHA256) + assert response_fingerprint_test.document.validate_document(sha256_fingerprint_downcase, true, fingerprint_alg: RubySaml::XML::Document::SHA256) end it "validate using SHA384" do sha384_fingerprint = "98:FE:17:90:31:E7:68:18:8A:65:4D:DA:F5:76:E2:09:97:BE:8B:E3:7E:AA:8D:63:64:7C:0C:38:23:9A:AC:A2:EC:CE:48:A6:74:4D:E0:4C:50:80:40:B4:8D:55:14:14" assert !response_fingerprint_test.document.validate_document(sha384_fingerprint) - assert response_fingerprint_test.document.validate_document(sha384_fingerprint, true, fingerprint_alg: XMLSecurity::Document::SHA384) + assert response_fingerprint_test.document.validate_document(sha384_fingerprint, true, fingerprint_alg: RubySaml::XML::Document::SHA384) end it "validate using SHA512" do sha512_fingerprint = "5A:AE:BA:D0:BA:9D:1E:25:05:01:1E:1A:C9:E9:FF:DB:ED:FA:6E:F7:52:EB:45:49:BD:DB:06:D8:A3:7E:CC:63:3A:04:A2:DD:DF:EE:61:05:D9:58:95:2A:77:17:30:4B:EB:4A:9F:48:4A:44:1C:D0:9E:0B:1E:04:77:FD:A3:D2" assert !response_fingerprint_test.document.validate_document(sha512_fingerprint) - assert response_fingerprint_test.document.validate_document(sha512_fingerprint, true, fingerprint_alg: XMLSecurity::Document::SHA512) + assert response_fingerprint_test.document.validate_document(sha512_fingerprint, true, fingerprint_alg: RubySaml::XML::Document::SHA512) end end describe "Signature Algorithms" do it "validate using SHA1" do - document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha1, false)) + document = RubySaml::XML::SignedDocument.new(fixture(:adfs_response_sha1, false)) assert document.validate_document("C4:C6:BD:41:EC:AD:57:97:CE:7B:7D:80:06:C3:E4:30:53:29:02:0B:DD:2D:47:02:9E:BD:85:AD:93:02:45:21") end it "validate using SHA256" do - document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha256, false)) + document = RubySaml::XML::SignedDocument.new(fixture(:adfs_response_sha256, false)) assert document.validate_document("3D:C5:BC:58:60:5D:19:64:94:E3:BA:C8:3D:49:01:D5:56:34:44:65:C2:85:0A:A8:65:A5:AC:76:7E:65:1F:F7") end it "validate using SHA384" do - document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha384, false)) + document = RubySaml::XML::SignedDocument.new(fixture(:adfs_response_sha384, false)) assert document.validate_document("C4:C6:BD:41:EC:AD:57:97:CE:7B:7D:80:06:C3:E4:30:53:29:02:0B:DD:2D:47:02:9E:BD:85:AD:93:02:45:21") end it "validate using SHA512" do - document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha512, false)) + document = RubySaml::XML::SignedDocument.new(fixture(:adfs_response_sha512, false)) assert document.validate_document("C4:C6:BD:41:EC:AD:57:97:CE:7B:7D:80:06:C3:E4:30:53:29:02:0B:DD:2D:47:02:9E:BD:85:AD:93:02:45:21") end end @@ -198,7 +196,7 @@ class XmlSecurityTest < Minitest::Test describe "#extract_inclusive_namespaces" do it "support explicit namespace resolution for exclusive canonicalization" do response = fixture(:open_saml_response, false) - document = XMLSecurity::SignedDocument.new(response) + document = RubySaml::XML::SignedDocument.new(response) inclusive_namespaces = document.send(:extract_inclusive_namespaces) assert_equal %w[ xs ], inclusive_namespaces @@ -206,7 +204,7 @@ class XmlSecurityTest < Minitest::Test it "support implicit namespace resolution for exclusive canonicalization" do response = fixture(:no_signature_ns, false) - document = XMLSecurity::SignedDocument.new(response) + document = RubySaml::XML::SignedDocument.new(response) inclusive_namespaces = document.send(:extract_inclusive_namespaces) assert_equal %w[ #default saml ds xs xsi ], inclusive_namespaces @@ -228,14 +226,14 @@ class XmlSecurityTest < Minitest::Test response = fixture(:no_signature_ns, false) response.slice! %r{} - document = XMLSecurity::SignedDocument.new(response) + document = RubySaml::XML::SignedDocument.new(response) inclusive_namespaces = document.send(:extract_inclusive_namespaces) assert inclusive_namespaces.nil? end end - describe "XMLSecurity::DSIG" do + describe "RubySaml::XML::DSIG" do before do settings.idp_sso_service_url = "https://idp.example.com/sso" settings.protocol_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" @@ -249,13 +247,13 @@ class XmlSecurityTest < Minitest::Test request = RubySaml::Authrequest.new.create_authentication_xml_doc(settings) request.sign_document(ruby_saml_key, ruby_saml_cert) # verify our signature - signed_doc = XMLSecurity::SignedDocument.new(request.to_s) + signed_doc = RubySaml::XML::SignedDocument.new(request.to_s) assert signed_doc.validate_document(ruby_saml_cert_fingerprint, false) request2 = RubySaml::Authrequest.new.create_authentication_xml_doc(settings) request2.sign_document(ruby_saml_key, ruby_saml_cert_text) # verify our signature - signed_doc2 = XMLSecurity::SignedDocument.new(request2.to_s) + signed_doc2 = RubySaml::XML::SignedDocument.new(request2.to_s) assert signed_doc2.validate_document(ruby_saml_cert_fingerprint, false) end @@ -264,7 +262,7 @@ class XmlSecurityTest < Minitest::Test request.sign_document(ruby_saml_key, ruby_saml_cert_text) # verify our signature - signed_doc = XMLSecurity::SignedDocument.new(request.to_s) + signed_doc = RubySaml::XML::SignedDocument.new(request.to_s) assert signed_doc.validate_document(ruby_saml_cert_fingerprint, false) end @@ -272,13 +270,13 @@ class XmlSecurityTest < Minitest::Test logout_request = RubySaml::Logoutrequest.new.create_logout_request_xml_doc(settings) logout_request.sign_document(ruby_saml_key, ruby_saml_cert) # verify our signature - signed_doc = XMLSecurity::SignedDocument.new(logout_request.to_s) + signed_doc = RubySaml::XML::SignedDocument.new(logout_request.to_s) assert signed_doc.validate_document(ruby_saml_cert_fingerprint, false) logout_request2 = RubySaml::Logoutrequest.new.create_logout_request_xml_doc(settings) logout_request2.sign_document(ruby_saml_key, ruby_saml_cert_text) # verify our signature - signed_doc2 = XMLSecurity::SignedDocument.new(logout_request2.to_s) + signed_doc2 = RubySaml::XML::SignedDocument.new(logout_request2.to_s) signed_doc2.validate_document(ruby_saml_cert_fingerprint, false) assert signed_doc2.validate_document(ruby_saml_cert_fingerprint, false) end @@ -287,13 +285,13 @@ class XmlSecurityTest < Minitest::Test logout_response = RubySaml::SloLogoutresponse.new.create_logout_response_xml_doc(settings, 'request_id_example', "Custom Logout Message") logout_response.sign_document(ruby_saml_key, ruby_saml_cert) # verify our signature - signed_doc = XMLSecurity::SignedDocument.new(logout_response.to_s) + signed_doc = RubySaml::XML::SignedDocument.new(logout_response.to_s) assert signed_doc.validate_document(ruby_saml_cert_fingerprint, false) logout_response2 = RubySaml::SloLogoutresponse.new.create_logout_response_xml_doc(settings, 'request_id_example', "Custom Logout Message") logout_response2.sign_document(ruby_saml_key, ruby_saml_cert_text) # verify our signature - signed_doc2 = XMLSecurity::SignedDocument.new(logout_response2.to_s) + signed_doc2 = RubySaml::XML::SignedDocument.new(logout_response2.to_s) signed_doc2.validate_document(ruby_saml_cert_fingerprint, false) assert signed_doc2.validate_document(ruby_saml_cert_fingerprint, false) end