From b4949414a688ec970fde97604ca2bd1b8724f592 Mon Sep 17 00:00:00 2001
From: johnnyshields <27655+johnnyshields@users.noreply.github.com>
Date: Tue, 9 Jul 2024 12:19:46 +0900
Subject: [PATCH] Use SHA256 hashing algorithm by default. Affects signatures,
digests, and fingerprints
---
CHANGELOG.md | 1 +
README.md | 2 +-
UPGRADING.md | 22 ++++++++++--
lib/ruby_saml/idp_metadata_parser.rb | 2 +-
lib/ruby_saml/settings.rb | 6 ++--
lib/xml_security.rb | 8 ++---
test/idp_metadata_parser_test.rb | 38 ++++++++++----------
test/logoutrequest_test.rb | 36 +++++++++----------
test/metadata_test.rb | 8 ++---
test/request_test.rb | 8 ++---
test/response_test.rb | 10 +++---
test/settings_test.rb | 8 ++---
test/slo_logoutresponse_test.rb | 52 ++++++++++++++--------------
test/test_helper.rb | 2 +-
test/utils_test.rb | 4 +--
test/xml_security_test.rb | 41 +++++++++++-----------
16 files changed, 134 insertions(+), 114 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 33184e5c..820750a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
* [#685](https://github.com/SAML-Toolkits/ruby-saml/pull/685) Create namespace alias `OneLogin = Object` for backward compatibility, to be removed in version `2.1.0`.
* [#685](https://github.com/SAML-Toolkits/ruby-saml/pull/685) Change directly structure from `lib/onelogin/ruby-saml` to `lib/ruby_saml`.
* [#685](https://github.com/SAML-Toolkits/ruby-saml/pull/685) Move schema files from `lib/onelogin/schemas` to `lib/ruby_saml/schemas`.
+* [#686](https://github.com/SAML-Toolkits/ruby-saml/pull/686) Use SHA-256 as the default hashing algorithm everywhere instead of SHA-1, including signatures, fingerprints, and digests.
### 1.17.0
* [#673](https://github.com/SAML-Toolkits/ruby-saml/pull/673) Add `Settings#sp_cert_multi` paramter to facilitate SP certificate and key rotation.
diff --git a/README.md b/README.md
index 9d037ae1..9aed3671 100644
--- a/README.md
+++ b/README.md
@@ -200,7 +200,7 @@ def saml_settings
settings.idp_slo_service_url = "https://app.onelogin.com/trust/saml2/http-redirect/slo/#{OneLoginAppId}"
settings.idp_slo_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" # or :post, :redirect
settings.idp_cert_fingerprint = OneLoginAppCertFingerPrint
- settings.idp_cert_fingerprint_algorithm = "http://www.w3.org/2000/09/xmldsig#sha1"
+ settings.idp_cert_fingerprint_algorithm = "http://www.w3.org/2000/09/xmldsig#sha256"
settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
# Optional for most SAML IdPs
diff --git a/UPGRADING.md b/UPGRADING.md
index a124a02a..f333ea55 100644
--- a/UPGRADING.md
+++ b/UPGRADING.md
@@ -2,13 +2,13 @@
## Updating from 1.17.x to 2.0.0
-### Before Upgrading
+### Before upgrading
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 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,
@@ -17,6 +17,24 @@ 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`.
+### Security: Change default hashing algorithm to SHA-256 (was SHA-1)
+
+For security reasons, RubySaml version `2.0.0` uses SHA-256 as its default hashing algorithm everywhere
+instead of the now-obsolete SHA-1. This affects:
+- The default signature and digest algorithms used when generating SP metadata.
+- The default signature algorithm used when generating SP messages such as AuthnRequests.
+- The default fingerprint of IdP metadata (`:idp_cert_fingerprint` as generated by `RubySaml::IdpMetadataParser`)
+
+To preserve the old insecure SHA-1 behavior *(not recommended)*, you may set `RubySaml::Settings` as follows:
+
+```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
+```
+
## Updating from 1.12.x to 1.13.0
Version `1.13.0` adds `settings.idp_sso_service_binding` and `settings.idp_slo_service_binding`, and
diff --git a/lib/ruby_saml/idp_metadata_parser.rb b/lib/ruby_saml/idp_metadata_parser.rb
index 0c2443d5..270137fa 100644
--- a/lib/ruby_saml/idp_metadata_parser.rb
+++ b/lib/ruby_saml/idp_metadata_parser.rb
@@ -376,7 +376,7 @@ def certificates
# @return [String|nil] the fingerpint of the X509Certificate if it exists
#
- def fingerprint(certificate, fingerprint_algorithm = XMLSecurity::Document::SHA1)
+ def fingerprint(certificate, fingerprint_algorithm = XMLSecurity::Document::SHA256)
@fingerprint ||= begin
return unless certificate
diff --git a/lib/ruby_saml/settings.rb b/lib/ruby_saml/settings.rb
index 9eb6debd..5b3229c2 100644
--- a/lib/ruby_saml/settings.rb
+++ b/lib/ruby_saml/settings.rb
@@ -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::SHA1,
+ idp_cert_fingerprint_algorithm: XMLSecurity::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::SHA1,
- signature_method: XMLSecurity::Document::RSA_SHA1,
+ digest_method: XMLSecurity::Document::SHA256,
+ signature_method: XMLSecurity::Document::RSA_SHA256,
check_idp_cert_expiration: false,
check_sp_cert_expiration: false,
strict_audience_validation: false,
diff --git a/lib/xml_security.rb b/lib/xml_security.rb
index ea3354a8..fb791d42 100644
--- a/lib/xml_security.rb
+++ b/lib/xml_security.rb
@@ -71,11 +71,11 @@ def algorithm(element)
algorithm = algorithm && algorithm =~ /(rsa-)?sha(.*?)$/i && ::Regexp.last_match(2).to_i
case algorithm
- when 256 then OpenSSL::Digest::SHA256
+ when 1 then OpenSSL::Digest::SHA1
when 384 then OpenSSL::Digest::SHA384
when 512 then OpenSSL::Digest::SHA512
else
- OpenSSL::Digest::SHA1
+ OpenSSL::Digest::SHA256
end
end
@@ -114,7 +114,7 @@ def uuid
#
#
#
- def sign_document(private_key, certificate, signature_method = RSA_SHA1, digest_method = SHA1)
+ 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
@@ -216,7 +216,7 @@ def validate_document(idp_cert_fingerprint, soft = true, options = {})
if options[:fingerprint_alg]
fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(options[:fingerprint_alg]).new
else
- fingerprint_alg = OpenSSL::Digest.new('SHA1')
+ fingerprint_alg = OpenSSL::Digest.new('SHA256')
end
fingerprint = fingerprint_alg.hexdigest(cert.to_der)
diff --git a/test/idp_metadata_parser_test.rb b/test/idp_metadata_parser_test.rb
index c616c299..860aecce 100644
--- a/test/idp_metadata_parser_test.rb
+++ b/test/idp_metadata_parser_test.rb
@@ -26,7 +26,7 @@ def initialize; end
assert_equal "https://hello.example.com/access/saml/idp.xml", settings.idp_entity_id
assert_equal "https://hello.example.com/access/saml/login", settings.idp_sso_service_url
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", settings.idp_sso_service_binding
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
+ 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 "https://hello.example.com/access/saml/logout", settings.idp_slo_service_url
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", settings.idp_slo_service_binding
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", settings.name_identifier_format
@@ -38,7 +38,7 @@ def initialize; end
idp_metadata_parser = RubySaml::IdpMetadataParser.new
idp_metadata = idp_metadata_descriptor
settings = idp_metadata_parser.parse(idp_metadata)
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
+ 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
end
it "extract certificate from md:KeyDescriptor[@use='encryption']" do
@@ -46,7 +46,7 @@ def initialize; end
idp_metadata = idp_metadata_descriptor
idp_metadata = idp_metadata.sub(/(.*?)<\/md:KeyDescriptor>/m, "")
settings = idp_metadata_parser.parse(idp_metadata)
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
+ 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
end
it "extract certificate from md:KeyDescriptor" do
@@ -55,7 +55,7 @@ def initialize; end
idp_metadata = idp_metadata.sub(/(.*?)<\/md:KeyDescriptor>/m, "")
idp_metadata = idp_metadata.sub('', '')
settings = idp_metadata_parser.parse(idp_metadata)
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
+ 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
end
it "extract SSO endpoint with no specific binding, it takes the first" do
@@ -162,7 +162,7 @@ def initialize; end
}
}
})
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
+ 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]
end
@@ -175,7 +175,7 @@ def initialize; end
RubySaml::IdpMetadataParser.new.parse(idp_metadata_descriptor, :settings => settings)
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
+ 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]
end
@@ -190,7 +190,7 @@ def initialize; end
assert_equal "https://hello.example.com/access/saml/idp.xml", metadata[:idp_entity_id]
assert_equal "https://hello.example.com/access/saml/login", metadata[:idp_sso_service_url]
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", metadata[:idp_sso_service_binding]
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", metadata[:idp_cert_fingerprint]
+ 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", metadata[:idp_cert_fingerprint]
assert_equal "https://hello.example.com/access/saml/logout", metadata[:idp_slo_service_url]
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", metadata[:idp_slo_service_binding]
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", metadata[:name_identifier_format]
@@ -202,7 +202,7 @@ def initialize; end
idp_metadata_parser = RubySaml::IdpMetadataParser.new
idp_metadata = idp_metadata_descriptor
metadata = idp_metadata_parser.parse_to_hash(idp_metadata)
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", metadata[:idp_cert_fingerprint]
+ 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", metadata[:idp_cert_fingerprint]
end
it "extract certificate from md:KeyDescriptor[@use='encryption']" do
@@ -210,7 +210,7 @@ def initialize; end
idp_metadata = idp_metadata_descriptor
idp_metadata = idp_metadata.sub(/(.*?)<\/md:KeyDescriptor>/m, "")
parsed_metadata = idp_metadata_parser.parse_to_hash(idp_metadata)
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", parsed_metadata[:idp_cert_fingerprint]
+ 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", parsed_metadata[:idp_cert_fingerprint]
end
it "extract certificate from md:KeyDescriptor" do
@@ -219,7 +219,7 @@ def initialize; end
idp_metadata = idp_metadata.sub(/(.*?)<\/md:KeyDescriptor>/m, "")
idp_metadata = idp_metadata.sub('', '')
parsed_metadata = idp_metadata_parser.parse_to_hash(idp_metadata)
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", parsed_metadata[:idp_cert_fingerprint]
+ 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", parsed_metadata[:idp_cert_fingerprint]
end
it "extract SSO endpoint with no specific binding, it takes the first" do
@@ -261,7 +261,7 @@ def initialize; end
}
}
})
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", parsed_metadata[:idp_cert_fingerprint]
+ 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", parsed_metadata[:idp_cert_fingerprint]
assert_nil parsed_metadata[:security]
end
@@ -272,8 +272,8 @@ def initialize; end
metadata1 = idp_metadata_parser.parse_to_hash(idp_metadata1)
metadata2 = idp_metadata_parser.parse_to_hash(idp_metadata2)
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", metadata1[:idp_cert_fingerprint]
- assert_equal "CD:2B:2B:DA:FF:F5:DB:64:10:7C:AC:FD:FE:0F:CB:5D:73:5F:16:07", metadata2[:idp_cert_fingerprint]
+ 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", metadata1[:idp_cert_fingerprint]
+ assert_equal "E5:52:D9:2C:3C:DC:3D:09:5C:90:76:82:AB:B6:75:B4:92:92:2C:42:87:7E:18:EB:17:F3:1F:39:FE:9F:7C:6A", metadata2[:idp_cert_fingerprint]
end
end
@@ -320,7 +320,7 @@ def initialize; end
assert_equal "https://hello.example.com/access/saml/idp.xml", settings.idp_entity_id
assert_equal "https://hello.example.com/access/saml/login", settings.idp_sso_service_url
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", settings.idp_sso_service_binding
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.idp_cert_fingerprint
+ 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 "https://hello.example.com/access/saml/logout", settings.idp_slo_service_url
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", settings.idp_slo_service_binding
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", settings.name_identifier_format
@@ -356,7 +356,7 @@ def initialize; end
assert_equal "https://hello.example.com/access/saml/idp.xml", parsed_metadata[:idp_entity_id]
assert_equal "https://hello.example.com/access/saml/login", parsed_metadata[:idp_sso_service_url]
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", parsed_metadata[:idp_sso_service_binding]
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", parsed_metadata[:idp_cert_fingerprint]
+ 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", parsed_metadata[:idp_cert_fingerprint]
assert_equal "https://hello.example.com/access/saml/logout", parsed_metadata[:idp_slo_service_url]
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", parsed_metadata[:idp_slo_service_binding]
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", parsed_metadata[:name_identifier_format]
@@ -467,7 +467,7 @@ def initialize; end
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", @settings.name_identifier_format
assert_equal "https://hello.example.com/access/saml/login", @settings.idp_sso_service_url
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", @settings.idp_sso_service_binding
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", @settings.idp_cert_fingerprint
+ 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 "https://hello.example.com/access/saml/logout", @settings.idp_slo_service_url
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", @settings.idp_slo_service_binding
assert_equal ["AuthToken", "SSOStartPage"], @settings.idp_attribute_names
@@ -477,10 +477,10 @@ def initialize; end
it "should handle multiple descriptors at once" do
settings = @idp_metadata_parser.parse_to_array(@idp_metadata)
assert_equal "https://foo.example.com/access/saml/idp.xml", settings.first[:idp_entity_id]
- assert_equal "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72", settings.first[:idp_cert_fingerprint]
+ 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.first[:idp_cert_fingerprint]
assert_equal '2014-04-17T18:02:33.910Z', settings.first[:valid_until]
assert_equal "https://bar.example.com/access/saml/idp.xml", settings.last[:idp_entity_id]
- assert_equal "08:EB:6E:60:A2:14:4E:89:EC:FA:05:74:9D:72:BF:5D:BE:54:F0:1A", settings.last[:idp_cert_fingerprint]
+ assert_equal "74:E4:FA:29:20:26:36:8A:72:5E:9D:CF:4F:8E:1F:DC:D4:CE:E2:3C:9D:6F:93:35:A1:A7:8A:4D:79:83:21:D0", settings.last[:idp_cert_fingerprint]
assert_equal '2014-04-17T18:02:33.910Z', settings.last[:valid_until]
end
end
@@ -649,7 +649,7 @@ def initialize; end
it "should return idp_cert and idp_cert_fingerprint and no idp_cert_multi" do
assert_equal(expected_cert, @settings.idp_cert)
- assert_equal("2D:A9:40:88:28:EE:67:BB:4A:5B:E0:58:A7:CC:71:95:2D:1B:C9:D3", @settings.idp_cert_fingerprint)
+ assert_equal("46:E3:68:F4:ED:61:43:2B:EC:36:E3:99:E9:03:4B:99:E5:B3:58:EF:A9:A9:00:FC:2D:C8:7C:14:C6:60:E3:8F", @settings.idp_cert_fingerprint)
assert_equal({ :signing => [expected_cert], :encryption => [expected_cert] }, @settings.idp_cert_multi)
assert_equal("https://app.onelogin.com/saml/metadata/383123", @settings.idp_entity_id)
assert_equal("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", @settings.name_identifier_format)
diff --git a/test/logoutrequest_test.rb b/test/logoutrequest_test.rb
index 30a5f5b9..2336d72f 100644
--- a/test/logoutrequest_test.rb
+++ b/test/logoutrequest_test.rb
@@ -123,8 +123,8 @@ class RequestTest < Minitest::Test
inflated = unauth_req.create_xml_document(settings).to_s
refute_match %r[([a-zA-Z0-9/+=]+)], inflated
- refute_match %r[], inflated
- refute_match %r[], inflated
+ refute_match %r[], inflated
+ refute_match %r[], inflated
end
it "sign unsigned request" do
@@ -133,14 +133,14 @@ class RequestTest < Minitest::Test
inflated = unauth_req_doc.to_s
refute_match %r[([a-zA-Z0-9/+=]+)], inflated
- refute_match %r[], inflated
- refute_match %r[], inflated
+ refute_match %r[], inflated
+ refute_match %r[], inflated
inflated = unauth_req.sign_document(unauth_req_doc, settings).to_s
assert_match %r[([a-zA-Z0-9/+=]+)], inflated
- assert_match %r[], inflated
- assert_match %r[], inflated
+ assert_match %r[], inflated
+ assert_match %r[], inflated
end
it "signs through create_logout_request_xml_doc" do
@@ -148,8 +148,8 @@ class RequestTest < Minitest::Test
inflated = unauth_req.create_logout_request_xml_doc(settings).to_s
assert_match %r[([a-zA-Z0-9/+=]+)], inflated
- assert_match %r[], inflated
- assert_match %r[], inflated
+ assert_match %r[], inflated
+ assert_match %r[], inflated
end
it "create a signed logout request" do
@@ -160,8 +160,8 @@ class RequestTest < Minitest::Test
inflated = decode_saml_request_payload(unauth_url)
assert_match %r[([a-zA-Z0-9/+=]+)], inflated
- assert_match %r[], inflated
- assert_match %r[], inflated
+ assert_match %r[], inflated
+ assert_match %r[], inflated
end
it "create an uncompressed signed logout request" do
@@ -171,8 +171,8 @@ class RequestTest < Minitest::Test
request_xml = Base64.decode64(params["SAMLRequest"])
assert_match %r[([a-zA-Z0-9/+=]+)], request_xml
- assert_match %r[], request_xml
- assert_match %r[], request_xml
+ assert_match %r[], request_xml
+ assert_match %r[], request_xml
end
it "create a signed logout request with 256 digest and signature method" do
@@ -215,8 +215,8 @@ class RequestTest < Minitest::Test
request_xml = Base64.decode64(params["SAMLRequest"])
assert_match %r[([a-zA-Z0-9/+=]+)], request_xml
- assert_match %r[], request_xml
- assert_match %r[], request_xml
+ assert_match %r[], request_xml
+ assert_match %r[], request_xml
end
it "create a signed logout request using the first valid certificate and key when :check_sp_cert_expiration is true" do
@@ -235,8 +235,8 @@ class RequestTest < Minitest::Test
request_xml = Base64.decode64(params["SAMLRequest"])
assert_match %r[([a-zA-Z0-9/+=]+)], request_xml
- assert_match %r[], request_xml
- assert_match %r[], request_xml
+ assert_match %r[], request_xml
+ assert_match %r[], request_xml
end
it "raises error when no valid certs and :check_sp_cert_expiration is true" do
@@ -380,8 +380,8 @@ class RequestTest < Minitest::Test
inflated = decode_saml_request_payload(unauth_url)
assert_match %r[([a-zA-Z0-9/+=]+)], inflated
- assert_match %r[], inflated
- assert_match %r[], inflated
+ assert_match %r[], inflated
+ assert_match %r[], inflated
end
end
diff --git a/test/metadata_test.rb b/test/metadata_test.rb
index e72928da..2b30c399 100644
--- a/test/metadata_test.rb
+++ b/test/metadata_test.rb
@@ -337,8 +337,8 @@ class MetadataTest < Minitest::Test
it "creates a signed metadata" do
assert_match %r[([a-zA-Z0-9/+=]+)]m, xml_text
- assert_match %r[], xml_text
- assert_match %r[], xml_text
+ assert_match %r[], xml_text
+ assert_match %r[], xml_text
signed_metadata = XMLSecurity::SignedDocument.new(xml_text)
assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false)
@@ -397,8 +397,8 @@ def add_extras(root, _settings)
assert_equal first_child.name, 'Signature'
assert_match %r[([a-zA-Z0-9/+=]+)]m, xml_text
- assert_match %r[], xml_text
- assert_match %r[], xml_text
+ assert_match %r[], xml_text
+ assert_match %r[], xml_text
signed_metadata = XMLSecurity::SignedDocument.new(xml_text)
assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false)
diff --git a/test/request_test.rb b/test/request_test.rb
index 00c190a6..1aab6a4b 100644
--- a/test/request_test.rb
+++ b/test/request_test.rb
@@ -254,7 +254,7 @@ class RequestTest < Minitest::Test
params = RubySaml::Authrequest.new.create_params(settings)
request_xml = Base64.decode64(params["SAMLRequest"])
assert_match %r[([a-zA-Z0-9/+=]+)], request_xml
- assert_match %r[], request_xml
+ assert_match %r[], request_xml
end
it "create a signed request with 256 digest and signature methods" do
@@ -283,7 +283,7 @@ class RequestTest < Minitest::Test
request_xml = Base64.decode64(params["SAMLRequest"])
assert_match %r[([a-zA-Z0-9/+=]+)], request_xml
- assert_match %r[], request_xml
+ assert_match %r[], request_xml
end
it "creates a signed request using the first valid certificate and key when :check_sp_cert_expiration is true" do
@@ -301,7 +301,7 @@ class RequestTest < Minitest::Test
request_xml = Base64.decode64(params["SAMLRequest"])
assert_match %r[([a-zA-Z0-9/+=]+)], request_xml
- assert_match %r[], request_xml
+ assert_match %r[], request_xml
end
it "raises error when no valid certs and :check_sp_cert_expiration is true" do
@@ -444,7 +444,7 @@ class RequestTest < Minitest::Test
params = RubySaml::Authrequest.new.create_params(settings)
request_xml = Base64.decode64(params["SAMLRequest"])
assert_match %r[([a-zA-Z0-9/+=]+)], request_xml
- assert_match %r[], request_xml
+ assert_match %r[], request_xml
end
end
diff --git a/test/response_test.rb b/test/response_test.rb
index 31240648..588c3b61 100644
--- a/test/response_test.rb
+++ b/test/response_test.rb
@@ -381,7 +381,7 @@ def generate_audience_error(expected, actual)
no_signature_response.stubs(:conditions).returns(nil)
no_signature_response.stubs(:validate_subject_confirmation).returns(true)
no_signature_response.settings = settings
- no_signature_response.settings.idp_cert_fingerprint = "28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA"
+ 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)
assert no_signature_response.is_valid?
end
@@ -390,7 +390,7 @@ def generate_audience_error(expected, actual)
adfs_response = RubySaml::Response.new(fixture(:adfs_response_sha256))
adfs_response.stubs(:conditions).returns(nil)
adfs_response.stubs(:validate_subject_confirmation).returns(true)
- settings.idp_cert_fingerprint = "28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA"
+ 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"
adfs_response.settings = settings
adfs_response.soft = true
assert adfs_response.is_valid?
@@ -878,14 +878,14 @@ def generate_audience_error(expected, actual)
end
it "return true when the signature is valid and ds namespace is at the root" do
- settings.idp_cert_fingerprint = '5614657ab692b960480389723a36446a5fe1f7ec'
+ settings.idp_cert_fingerprint = '19a4fff2e8fcc7f3ea5046348dbf1d81320654d1f712028cc97933cb1247fc99'
response_with_ds_namespace_at_the_root.settings = settings
assert response_with_ds_namespace_at_the_root.send(:validate_signature)
assert_empty response_with_ds_namespace_at_the_root.errors
end
it "return true when the signature is valid and fingerprint provided" do
- settings.idp_cert_fingerprint = '49:EC:3F:A4:71:8A:1E:C9:DB:70:A7:CC:33:36:96:F0:48:8C:4E:DA'
+ settings.idp_cert_fingerprint = 'D0:35:89:BB:11:16:CB:3C:26:B0:D4:DA:CE:2A:91:B9:E0:A6:D8:E8:BF:93:C2:5B:74:0D:52:01:47:72:CE:E4'
xml = 'PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIERlc3RpbmF0aW9uPSJodHRwczovL2NvZGVycGFkLmlvL3NhbWwvYWNzIiBJRD0iXzEwOGE1ZTg0MDllYzRjZjlhY2QxYzQ2OWU5ZDcxNGFkIiBJblJlc3BvbnNlVG89Il80ZmZmYWE2MC02OTZiLTAxMzMtMzg4Ni0wMjQxZjY1YzA2OTMiIElzc3VlSW5zdGFudD0iMjAxNS0xMS0wOVQyMzo1NTo0M1oiIFZlcnNpb249IjIuMCI+PHNhbWw6SXNzdWVyIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPmh0dHBzOi8vbG9naW4uaHVsdS5jb208L3NhbWw6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIj48L2RzOkNhbm9uaWNhbGl6YXRpb25NZXRob2Q+PGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNyc2Etc2hhMSI+PC9kczpTaWduYXR1cmVNZXRob2Q+PGRzOlJlZmVyZW5jZSBVUkk9IiNfMTA4YTVlODQwOWVjNGNmOWFjZDFjNDY5ZTlkNzE0YWQiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSI+PC9kczpUcmFuc2Zvcm0+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyI+PC9kczpUcmFuc2Zvcm0+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSI+PC9kczpEaWdlc3RNZXRob2Q+PGRzOkRpZ2VzdFZhbHVlPm9sQllXbTQyRi9oZm0xdHJYTHk2a3V6MXlMUT08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6U2lnbmF0dXJlVmFsdWU+dXNRTmY5WGpKTDRlOXVucnVCdWViSnQ3R0tXM2hJUk9teWVqTm1NMHM4WFhlWHN3WHc4U3ZCZi8zeDNNWEpkWnpNV0pOM3ExN2tGWHN2bTVna1JzbkE9PTwvZHM6U2lnbmF0dXJlVmFsdWU+PGRzOktleUluZm8+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJQ1FEQ0NBZXFnQXdJQkFnSUpBSVZOdzVLRzR1aTFNQTBHQ1NxR1NJYjNEUUVCQlFVQU1Fd3hDekFKQmdOVkJBWVRBa2RDTVJJd0VBWURWUVFJRXdsQ1pYSnJjMmhwY21VeEVEQU9CZ05WQkFjVEIwNWxkMkoxY25reEZ6QVZCZ05WQkFvVERrMTVJRU52YlhCaGJua2dUSFJrTUI0WERURXlNVEF5TlRBMk1qY3pORm9YRFRJeU1UQXlNekEyTWpjek5Gb3dUREVMTUFrR0ExVUVCaE1DUjBJeEVqQVFCZ05WQkFnVENVSmxjbXR6YUdseVpURVFNQTRHQTFVRUJ4TUhUbVYzWW5WeWVURVhNQlVHQTFVRUNoTU9UWGtnUTI5dGNHRnVlU0JNZEdRd1hEQU5CZ2txaGtpRzl3MEJBUUVGQUFOTEFEQklBa0VBd1NOL2dpMzNSbXBBUW9MUWo3UDZ6QW5OVDBSbjdiakMzMjNuM3ExT25mdm52UjBmUWp2TnQ3ckRrQTVBdjVRbk02VjRZVU5Vbk1mYk9RcTBXTGJMU3dJREFRQUJvNEd1TUlHck1CMEdBMVVkRGdRV0JCUWZJSDFvZkJWcHNSQWNJTUsyaGJsN25nTVRZREI4QmdOVkhTTUVkVEJ6Z0JRZklIMW9mQlZwc1JBY0lNSzJoYmw3bmdNVFlLRlFwRTR3VERFTE1Ba0dBMVVFQmhNQ1IwSXhFakFRQmdOVkJBZ1RDVUpsY210emFHbHlaVEVRTUE0R0ExVUVCeE1IVG1WM1luVnllVEVYTUJVR0ExVUVDaE1PVFhrZ1EyOXRjR0Z1ZVNCTWRHU0NDUUNGVGNPU2h1TG90VEFNQmdOVkhSTUVCVEFEQVFIL01BMEdDU3FHU0liM0RRRUJCUVVBQTBFQXFvZ1YzdVBjbEtYRG1EWk1UN3ZsUFl4TEFxQ0dIWnRsQ3h6NGhNNEtTdGxEMi9HTmMxWGlMYjFoL0swQ0pMRG9zckVJYm0zd2lPMk12VEVSclZZU01RPT08L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT48c2FtbHA6U3RhdHVzPjxzYW1scDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiPjwvc2FtbHA6U3RhdHVzQ29kZT48L3NhbWxwOlN0YXR1cz48c2FtbDpBc3NlcnRpb24geG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9Il8wMTg4MmRhOTM2OTQ0ZDFlYTZlZmY0NDA2NTc2MzFiNSIgSXNzdWVJbnN0YW50PSIyMDE1LTExLTA5VDIzOjU1OjQzWiIgVmVyc2lvbj0iMi4wIj48c2FtbDpJc3N1ZXI+aHR0cHM6Ly9sb2dpbi5odWx1LmNvbTwvc2FtbDpJc3N1ZXI+PGRzOlNpZ25hdHVyZSB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiPjwvZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZD48ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIj48L2RzOlNpZ25hdHVyZU1ldGhvZD48ZHM6UmVmZXJlbmNlIFVSST0iI18wMTg4MmRhOTM2OTQ0ZDFlYTZlZmY0NDA2NTc2MzFiNSI+PGRzOlRyYW5zZm9ybXM+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIj48L2RzOlRyYW5zZm9ybT48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIj48L2RzOlRyYW5zZm9ybT48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNzaGExIj48L2RzOkRpZ2VzdE1ldGhvZD48ZHM6RGlnZXN0VmFsdWU+cmo2YzhucC9BUmV0ZkJ1dWVOSzNPS0xDYnowPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5hR05FemZHM1dLcExKc2ZLRGJSNmpva2d6OEFnZ0FIRVVESEZyd0dsTHVQeWpyNEl3M09NcFNkV2gyL01YK1F3M1dPTk5mNHJNalh5TGVZSFJIVGpMQT09PC9kczpTaWduYXR1cmVWYWx1ZT48ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlDUURDQ0FlcWdBd0lCQWdJSkFJVk53NUtHNHVpMU1BMEdDU3FHU0liM0RRRUJCUVVBTUV3eEN6QUpCZ05WQkFZVEFrZENNUkl3RUFZRFZRUUlFd2xDWlhKcmMyaHBjbVV4RURBT0JnTlZCQWNUQjA1bGQySjFjbmt4RnpBVkJnTlZCQW9URGsxNUlFTnZiWEJoYm5rZ1RIUmtNQjRYRFRFeU1UQXlOVEEyTWpjek5Gb1hEVEl5TVRBeU16QTJNamN6TkZvd1RERUxNQWtHQTFVRUJoTUNSMEl4RWpBUUJnTlZCQWdUQ1VKbGNtdHphR2x5WlRFUU1BNEdBMVVFQnhNSFRtVjNZblZ5ZVRFWE1CVUdBMVVFQ2hNT1RYa2dRMjl0Y0dGdWVTQk1kR1F3WERBTkJna3Foa2lHOXcwQkFRRUZBQU5MQURCSUFrRUF3U04vZ2kzM1JtcEFRb0xRajdQNnpBbk5UMFJuN2JqQzMyM24zcTFPbmZ2bnZSMGZRanZOdDdyRGtBNUF2NVFuTTZWNFlVTlVuTWZiT1FxMFdMYkxTd0lEQVFBQm80R3VNSUdyTUIwR0ExVWREZ1FXQkJRZklIMW9mQlZwc1JBY0lNSzJoYmw3bmdNVFlEQjhCZ05WSFNNRWRUQnpnQlFmSUgxb2ZCVnBzUkFjSU1LMmhibDduZ01UWUtGUXBFNHdUREVMTUFrR0ExVUVCaE1DUjBJeEVqQVFCZ05WQkFnVENVSmxjbXR6YUdseVpURVFNQTRHQTFVRUJ4TUhUbVYzWW5WeWVURVhNQlVHQTFVRUNoTU9UWGtnUTI5dGNHRnVlU0JNZEdTQ0NRQ0ZUY09TaHVMb3RUQU1CZ05WSFJNRUJUQURBUUgvTUEwR0NTcUdTSWIzRFFFQkJRVUFBMEVBcW9nVjN1UGNsS1hEbURaTVQ3dmxQWXhMQXFDR0hadGxDeHo0aE00S1N0bEQyL0dOYzFYaUxiMWgvSzBDSkxEb3NyRUlibTN3aU8yTXZURVJyVllTTVE9PTwvZHM6WDUwOUNlcnRpZmljYXRlPjwvZHM6WDUwOURhdGE+PC9kczpLZXlJbmZvPjwvZHM6U2lnbmF0dXJlPjxzYW1sOlN1YmplY3Q+PHNhbWw6TmFtZUlEIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3JtYXQ6ZW1haWxBZGRyZXNzIiBTUE5hbWVRdWFsaWZpZXI9Imh0dHBzOi8vY29kZXJwYWQuaW8iPm1hdHQuanVyaWtAaHVsdS5jb208L3NhbWw6TmFtZUlEPjxzYW1sOlN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj48c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uRGF0YSBJblJlc3BvbnNlVG89Il80ZmZmYWE2MC02OTZiLTAxMzMtMzg4Ni0wMjQxZjY1YzA2OTMiIE5vdE9uT3JBZnRlcj0iMjAxNS0xMS0xMFQwMDoxMDo0M1oiIFJlY2lwaWVudD0iaHR0cHM6Ly9jb2RlcnBhZC5pby9zYW1sL2FjcyI+PC9zYW1sOlN1YmplY3RDb25maXJtYXRpb25EYXRhPjwvc2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uPjwvc2FtbDpTdWJqZWN0PjxzYW1sOkNvbmRpdGlvbnMgTm90QmVmb3JlPSIyMDE1LTExLTA5VDIyOjU1OjQzWiIgTm90T25PckFmdGVyPSIyMDE1LTExLTEwVDAwOjEwOjQzWiI+PHNhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj48c2FtbDpBdWRpZW5jZT5odHRwczovL2NvZGVycGFkLmlvPC9zYW1sOkF1ZGllbmNlPjwvc2FtbDpBdWRpZW5jZVJlc3RyaWN0aW9uPjwvc2FtbDpDb25kaXRpb25zPjxzYW1sOkF1dGhuU3RhdGVtZW50IEF1dGhuSW5zdGFudD0iMjAxNS0xMS0wOVQyMzo1NTo0M1oiPjxzYW1sOkF1dGhuQ29udGV4dD48c2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3NlczpQYXNzd29yZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj48L3NhbWw6QXV0aG5Db250ZXh0Pjwvc2FtbDpBdXRoblN0YXRlbWVudD48c2FtbDpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PHNhbWw6QXR0cmlidXRlIE5hbWU9IkdpdmVuLW5hbWUiPjxzYW1sOkF0dHJpYnV0ZVZhbHVlPk1hdHQ8L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48c2FtbDpBdHRyaWJ1dGUgTmFtZT0iU3VybmFtZSI+PHNhbWw6QXR0cmlidXRlVmFsdWU+SnVyaWs8L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48c2FtbDpBdHRyaWJ1dGUgTmFtZT0iRW1haWwiPjxzYW1sOkF0dHJpYnV0ZVZhbHVlPm1hdHQuanVyaWtAaHVsdS5jb208L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48L3NhbWw6QXR0cmlidXRlU3RhdGVtZW50Pjwvc2FtbDpBc3NlcnRpb24+PC9zYW1scDpSZXNwb25zZT4='
response_x = RubySaml::Response.new(xml)
response_x.settings = settings
@@ -1497,7 +1497,7 @@ def generate_audience_error(expected, actual)
describe "retrieve nameID and attributes from encrypted assertion" do
before do
- settings.idp_cert_fingerprint = 'EE:17:4E:FB:A8:81:71:12:0D:2A:78:43:BC:E7:0C:07:58:79:F4:F4'
+ settings.idp_cert_fingerprint = '55:FD:5F:3F:43:5A:AC:E6:79:89:BF:25:48:81:A1:C4:F3:37:3B:CB:1B:4D:68:A0:3E:A5:C9:FF:61:48:01:3F'
settings.sp_entity_id = 'http://rubysaml.com:3000/saml/metadata'
settings.assertion_consumer_service_url = 'http://rubysaml.com:3000/saml/acs'
settings.certificate = ruby_saml_cert_text
diff --git a/test/settings_test.rb b/test/settings_test.rb
index b31fb59a..4b0ac49a 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::SHA256
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
+ settings.security[:digest_method] = XMLSecurity::Document::SHA512
+ settings.security[:signature_method] = XMLSecurity::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::SHA1
- assert_equal new_settings.security[:signature_method], XMLSecurity::Document::RSA_SHA1
+ assert_equal new_settings.security[:digest_method], XMLSecurity::Document::SHA256
+ assert_equal new_settings.security[:signature_method], XMLSecurity::Document::RSA_SHA256
end
it "overrides only provided security attributes passing a second parameter" do
diff --git a/test/slo_logoutresponse_test.rb b/test/slo_logoutresponse_test.rb
index 6680a262..f55d6afb 100644
--- a/test/slo_logoutresponse_test.rb
+++ b/test/slo_logoutresponse_test.rb
@@ -111,8 +111,8 @@ class SloLogoutresponseTest < Minitest::Test
inflated = unauth_res.create_xml_document(settings).to_s
refute_match %r[([a-zA-Z0-9/+=]+)], inflated
- refute_match %r[], inflated
- refute_match %r[], inflated
+ refute_match %r[], inflated
+ refute_match %r[], inflated
end
it "sign unsigned request" do
@@ -121,14 +121,14 @@ class SloLogoutresponseTest < Minitest::Test
inflated = unauth_res_doc.to_s
refute_match %r[([a-zA-Z0-9/+=]+)], inflated
- refute_match %r[], inflated
- refute_match %r[], inflated
+ refute_match %r[], inflated
+ refute_match %r[], inflated
inflated = unauth_res.sign_document(unauth_res_doc, settings).to_s
assert_match %r[([a-zA-Z0-9/+=]+)], inflated
- assert_match %r[], inflated
- assert_match %r[], inflated
+ assert_match %r[], inflated
+ assert_match %r[], inflated
end
it "signs through create_logout_response_xml_doc" do
@@ -136,8 +136,8 @@ class SloLogoutresponseTest < Minitest::Test
inflated = unauth_res.create_logout_response_xml_doc(settings).to_s
assert_match %r[([a-zA-Z0-9/+=]+)], inflated
- assert_match %r[], inflated
- assert_match %r[], inflated
+ assert_match %r[], inflated
+ assert_match %r[], inflated
end
it "create a signed logout response" do
@@ -147,24 +147,24 @@ class SloLogoutresponseTest < Minitest::Test
response_xml = Base64.decode64(params["SAMLResponse"])
assert_match %r[([a-zA-Z0-9/+=]+)], response_xml
- assert_match(//, response_xml)
- assert_match(//, response_xml)
+ assert_match(//, response_xml)
+ assert_match(//, response_xml)
end
- it "create a signed logout response with 256 digest and signature methods" do
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
- settings.security[:digest_method] = XMLSecurity::Document::SHA256
+ 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
logout_request.settings = settings
params = RubySaml::SloLogoutresponse.new.create_params(settings, logout_request.id, "Custom Logout Message")
response_xml = Base64.decode64(params["SAMLResponse"])
assert_match %r[([a-zA-Z0-9/+=]+)], response_xml
- assert_match(//, response_xml)
- assert_match(//, response_xml)
+ assert_match(//, response_xml)
+ assert_match(//, response_xml)
end
- it "create a signed logout response with 512 digest and signature method RSA_SHA384" do
+ 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
logout_request.settings = settings
@@ -192,8 +192,8 @@ class SloLogoutresponseTest < Minitest::Test
response_xml = Base64.decode64(params["SAMLResponse"])
assert_match %r[([a-zA-Z0-9/+=]+)], response_xml
- assert_match(//, response_xml)
- assert_match(//, response_xml)
+ assert_match(//, response_xml)
+ assert_match(//, response_xml)
end
it "create a signed logout response using the first valid certificate and key when :check_sp_cert_expiration is true" do
@@ -212,8 +212,8 @@ class SloLogoutresponseTest < Minitest::Test
response_xml = Base64.decode64(params["SAMLResponse"])
assert_match %r[([a-zA-Z0-9/+=]+)], response_xml
- assert_match(//, response_xml)
- assert_match(//, response_xml)
+ assert_match(//, response_xml)
+ assert_match(//, response_xml)
end
it "raises error when no valid certs and :check_sp_cert_expiration is true" do
@@ -359,8 +359,8 @@ class SloLogoutresponseTest < Minitest::Test
inflated = unauth_res.create_xml_document(settings).to_s
refute_match %r[([a-zA-Z0-9/+=]+)], inflated
- refute_match %r[], inflated
- refute_match %r[], inflated
+ refute_match %r[], inflated
+ refute_match %r[], inflated
end
it "sign unsigned request" do
@@ -369,14 +369,14 @@ class SloLogoutresponseTest < Minitest::Test
inflated = unauth_res_doc.to_s
refute_match %r[([a-zA-Z0-9/+=]+)], inflated
- refute_match %r[], inflated
- refute_match %r[], inflated
+ refute_match %r[], inflated
+ refute_match %r[], inflated
inflated = unauth_res.sign_document(unauth_res_doc, settings).to_s
assert_match %r[([a-zA-Z0-9/+=]+)], inflated
- assert_match %r[], inflated
- assert_match %r[], inflated
+ assert_match %r[], inflated
+ assert_match %r[], inflated
end
end
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 1c8e3e5a..ef5dc344 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -279,7 +279,7 @@ def ruby_saml_cert2
end
def ruby_saml_cert_fingerprint
- @ruby_saml_cert_fingerprint ||= Digest::SHA1.hexdigest(ruby_saml_cert.to_der).scan(/../).join(":")
+ @ruby_saml_cert_fingerprint ||= Digest::SHA256.hexdigest(ruby_saml_cert.to_der).scan(/../).join(":")
end
def ruby_saml_cert_text
diff --git a/test/utils_test.rb b/test/utils_test.rb
index 23360cb2..b0e7f2b1 100644
--- a/test/utils_test.rb
+++ b/test/utils_test.rb
@@ -195,9 +195,9 @@ def result(duration, reference = 0)
params[:type] = "SAMLRequest"
params[:data] = "PHNhbWxwOkF1dGhuUmVxdWVzdCBEZXN0aW5hdGlvbj0naHR0cDovL2V4YW1wbGUuY29tP2ZpZWxkPXZhbHVlJyBJRD0nXzk4NmUxZDEwLWVhY2ItMDEzMi01MGRkLTAwOTBmNWRlZGQ3NycgSXNzdWVJbnN0YW50PScyMDE1LTA2LTAxVDIwOjM0OjU5WicgVmVyc2lvbj0nMi4wJyB4bWxuczpzYW1sPSd1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uJyB4bWxuczpzYW1scD0ndXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sJy8+"
params[:relay_state] = "http://example.com"
- params[:sig_alg] = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
+ params[:sig_alg] = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
query_string = RubySaml::Utils.build_query(params)
- assert_equal "SAMLRequest=PHNhbWxwOkF1dGhuUmVxdWVzdCBEZXN0aW5hdGlvbj0naHR0cDovL2V4YW1wbGUuY29tP2ZpZWxkPXZhbHVlJyBJRD0nXzk4NmUxZDEwLWVhY2ItMDEzMi01MGRkLTAwOTBmNWRlZGQ3NycgSXNzdWVJbnN0YW50PScyMDE1LTA2LTAxVDIwOjM0OjU5WicgVmVyc2lvbj0nMi4wJyB4bWxuczpzYW1sPSd1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uJyB4bWxuczpzYW1scD0ndXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sJy8%2B&RelayState=http%3A%2F%2Fexample.com&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1", query_string
+ assert_equal "SAMLRequest=PHNhbWxwOkF1dGhuUmVxdWVzdCBEZXN0aW5hdGlvbj0naHR0cDovL2V4YW1wbGUuY29tP2ZpZWxkPXZhbHVlJyBJRD0nXzk4NmUxZDEwLWVhY2ItMDEzMi01MGRkLTAwOTBmNWRlZGQ3NycgSXNzdWVJbnN0YW50PScyMDE1LTA2LTAxVDIwOjM0OjU5WicgVmVyc2lvbj0nMi4wJyB4bWxuczpzYW1sPSd1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uJyB4bWxuczpzYW1scD0ndXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sJy8%2B&RelayState=http%3A%2F%2Fexample.com&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256", query_string
end
end
diff --git a/test/xml_security_test.rb b/test/xml_security_test.rb
index 5abf3801..59919849 100644
--- a/test/xml_security_test.rb
+++ b/test/xml_security_test.rb
@@ -111,13 +111,13 @@ class XmlSecurityTest < Minitest::Test
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, XMLSecurity::BaseDocument.new.algorithm("other")
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")
end
it "SHA384" do
@@ -138,34 +138,35 @@ class XmlSecurityTest < Minitest::Test
it "validate using SHA1" do
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 = "f13c6b80905a030e6c913e5d15faddb016454872"
+ sha1_fingerprint_downcase = sha1_fingerprint.tr(':', '').downcase
- assert response_fingerprint_test.document.validate_document(sha1_fingerprint)
- 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)
- 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: XMLSecurity::Document::SHA1)
+ assert response_fingerprint_test.document.validate_document(sha1_fingerprint_downcase, true, fingerprint_alg: XMLSecurity::Document::SHA1)
end
it "validate using SHA256" do
sha256_fingerprint = "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"
+ 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)
- assert response_fingerprint_test.document.validate_document(sha256_fingerprint, true, :fingerprint_alg => XMLSecurity::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)
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: XMLSecurity::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: XMLSecurity::Document::SHA512)
end
end
@@ -173,22 +174,22 @@ class XmlSecurityTest < Minitest::Test
describe "Signature Algorithms" do
it "validate using SHA1" do
document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha1, false))
- assert document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
+ 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))
- assert document.validate_document("28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA")
+ 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))
- assert document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
+ 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))
- assert document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
+ 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
@@ -302,7 +303,7 @@ class XmlSecurityTest < Minitest::Test
let (:response) { RubySaml::Response.new(fixture(:starfield_response)) }
before do
- response.settings = RubySaml::Settings.new(:idp_cert_fingerprint => "8D:BA:53:8E:A3:B6:F9:F1:69:6C:BB:D9:D8:BD:41:B3:AC:4F:9D:4D")
+ response.settings = RubySaml::Settings.new(idp_cert_fingerprint: "8F:EB:0C:79:30:4A:E4:DF:B4:BD:7F:23:EE:29:3A:29:20:FE:BC:15:11:70:79:53:F4:37:55:05:2B:38:1A:42")
end
it "be able to validate a good response" do
@@ -343,7 +344,7 @@ class XmlSecurityTest < Minitest::Test
describe 'when response has signed message and assertion' do
let(:document_data) { read_response('response_with_signed_message_and_assertion.xml') }
let(:document) { RubySaml::Response.new(document_data).document }
- let(:fingerprint) { '4b68c453c7d994aad9025c99d5efcf566287fe8d' }
+ let(:fingerprint) { '6385109dd146a45d4382799491cb2707bd1ebda3738f27a0e4a4a8159c0fe6cd' }
it 'is valid' do
assert document.validate_document(fingerprint, true), 'Document should be valid'
@@ -353,7 +354,7 @@ class XmlSecurityTest < Minitest::Test
describe 'when response has signed assertion' do
let(:document_data) { read_response('response_with_signed_assertion_3.xml') }
let(:document) { RubySaml::Response.new(document_data).document }
- let(:fingerprint) { '4b68c453c7d994aad9025c99d5efcf566287fe8d' }
+ let(:fingerprint) { '6385109dd146a45d4382799491cb2707bd1ebda3738f27a0e4a4a8159c0fe6cd' }
it 'is valid' do
assert document.validate_document(fingerprint, true), 'Document should be valid'
@@ -374,7 +375,7 @@ class XmlSecurityTest < Minitest::Test
describe 'signature wrapping attack - doubled SAML response body' do
let(:document_data) { read_invalid_response("response_with_doubled_signed_assertion.xml") }
let(:document) { RubySaml::Response.new(document_data) }
- let(:fingerprint) { '4b68c453c7d994aad9025c99d5efcf566287fe8d' }
+ let(:fingerprint) { '6385109dd146a45d4382799491cb2707bd1ebda3738f27a0e4a4a8159c0fe6cd' }
it 'is valid, but the unsigned information is ignored in favour of the signed information' do
assert document.document.validate_document(fingerprint, true), 'Document should be valid'
@@ -385,7 +386,7 @@ class XmlSecurityTest < Minitest::Test
describe 'signature wrapping attack - concealed SAML response body' do
let(:document_data) { read_invalid_response("response_with_concealed_signed_assertion.xml") }
let(:document) { RubySaml::Response.new(document_data) }
- let(:fingerprint) { '4b68c453c7d994aad9025c99d5efcf566287fe8d' }
+ let(:fingerprint) { '6385109dd146a45d4382799491cb2707bd1ebda3738f27a0e4a4a8159c0fe6cd' }
it 'is valid, but fails to retrieve information' do
assert document.document.validate_document(fingerprint, true), 'Document should be valid'