ruby-saml 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ruby-saml might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d6958524060034d6eaaf5c0f968711ecdc45e2bd
4
- data.tar.gz: f1714aa26982ce596b8e07f2e20a8637611d7523
3
+ metadata.gz: 39c30acdf4c50284b1112ea62b2be51c412cea9c
4
+ data.tar.gz: beeb518c01d3bb6d0b871a9909e7ab52f418eb4e
5
5
  SHA512:
6
- metadata.gz: 1cb2ee3fefaec17210a0087dbadc68698b4fa9969d20c81512c9d1904bf941a59179a73b2d46ed52c38867f0c201b82e9f8cdd0f50b114103b7fe72cfcbb7bdc
7
- data.tar.gz: ed45f61f08919d846edb627699ed1679f5d7e8c1c5136a4703d3c9129bc7259e9f761a1a8fc12bb439bd5e96128069c5c0b3b9115e1f8d38e55a874523793cec
6
+ metadata.gz: 387733f9fc5979968ec493dd2e961969925470ad5c2882a5b4e96266cac027d001a4ce5e11139948e5f2bef1f6cb1bbd436c617e3399fb605958ad76b9e93db5
7
+ data.tar.gz: ceeb701e8fe82826a20a1768406088cfd2a8f90f3970d95e6c79ca70cc609dac9072dfe58000f88cd8502e3e025fd1948fef0754d63387f0f922fe7fc1d53c39
data/README.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Ruby SAML [![Build Status](https://secure.travis-ci.org/onelogin/ruby-saml.svg)](http://travis-ci.org/onelogin/ruby-saml) [![Coverage Status](https://coveralls.io/repos/onelogin/ruby-saml/badge.svg?branch=master%0A)](https://coveralls.io/r/onelogin/ruby-saml?branch=master%0A) [![Gem Version](https://badge.fury.io/rb/ruby-saml.svg)](http://badge.fury.io/rb/ruby-saml)
2
2
 
3
+ ## Updating from 1.5.0 to 1.6.0
4
+
5
+ Version `1.6.0` changes the preferred way to construct instances of `Logoutresponse` and `SloLogoutrequest`. Previously the _SAMLResponse_, _RelayState_, and _SigAlg_ parameters of these message types were provided via the constructor's `options[:get_params]` parameter. Unfortunately this can result in incompatibility with other SAML implementations; signatures are specified to be computed based on the _sender's_ URI-encoding of the message, which can differ from that of Ruby SAML. In particular, Ruby SAML's URI-encoding does not match that of Microsoft ADFS, so messages from ADFS can fail signature validation.
6
+
7
+ The new preferred way to provide _SAMLResponse_, _RelayState_, and _SigAlg_ is via the `options[:raw_get_params]` parameter. For example:
8
+
9
+ ```ruby
10
+ # In this example `query_params` is assumed to contain decoded query parameters,
11
+ # and `raw_query_params` is assumed to contain encoded query parameters as sent by the IDP.
12
+ settings = {
13
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
14
+ settings.soft = false
15
+ }
16
+ options = {
17
+ get_params: {
18
+ "Signature" => query_params["Signature"],
19
+ },
20
+ raw_get_params: {
21
+ "SAMLRequest" => raw_query_params["SAMLRequest"],
22
+ "SigAlg" => raw_query_params["SigAlg"],
23
+ "RelayState" => raw_query_params["RelayState"],
24
+ },
25
+ }
26
+ slo_logout_request = OneLogin::RubySaml::SloLogoutrequest.new(query_params["SAMLRequest"], settings, options)
27
+ raise "Invalid Logout Request" unless slo_logout_request.is_valid?
28
+ ```
29
+
30
+ The old form is still supported for backward compatibility, but all Ruby SAML users should prefer `options[:raw_get_params]` where possible to ensure compatibility with other SAML implementations.
31
+
3
32
  ## Updating from 1.4.2 to 1.4.3
4
33
 
5
34
  Version `1.4.3` introduces Recipient validation of SubjectConfirmation elements.
@@ -470,10 +499,8 @@ The settings related to sign are stored in the `security` attribute of the setti
470
499
  ```ruby
471
500
  settings.security[:authn_requests_signed] = true # Enable or not signature on AuthNRequest
472
501
  settings.security[:logout_requests_signed] = true # Enable or not signature on Logout Request
473
- settings.security[:logout_responses_signed] = true # Enable or not
474
- signature on Logout Response
475
- settings.security[:want_assertions_signed] = true # Enable or not
476
- the requirement of signed assertion
502
+ settings.security[:logout_responses_signed] = true # Enable or not signature on Logout Response
503
+ settings.security[:want_assertions_signed] = true # Enable or not the requirement of signed assertion
477
504
  settings.security[:metadata_signed] = true # Enable or not signature on Metadata
478
505
 
479
506
  settings.security[:digest_method] = XMLSecurity::Document::SHA1
@@ -1,4 +1,11 @@
1
1
  # RubySaml Changelog
2
+ ### 1.6.0 (November 27, 2017)
3
+ * [#418](https://github.com/onelogin/ruby-saml/pull/418) Improve SAML message signature validation using original encoded parameters instead decoded in order to avoid conflicts (URL-encoding is not canonical, reported issues with ADFS)
4
+ * [#420](https://github.com/onelogin/ruby-saml/pull/420) Expose NameID Format on SloLogoutrequest
5
+ * [#423](https://github.com/onelogin/ruby-saml/pull/423) Allow format_cert to work with chained certificates
6
+ * [#422](https://github.com/onelogin/ruby-saml/pull/422) Use to_s for requested attribute value
7
+
8
+
2
9
  ### 1.5.0 (August 31, 2017)
3
10
  * [#400](https://github.com/onelogin/ruby-saml/pull/400) When validating Signature use stored IdP certficate if Signature contains no info about Certificate
4
11
  * [#402](https://github.com/onelogin/ruby-saml/pull/402) Fix validate_response_state method that rejected SAMLResponses when using idp_cert_multi and idp_cert and idp_cert_fingerprint were not provided.
@@ -103,7 +103,7 @@ module OneLogin
103
103
  @entity_descriptor = nil
104
104
 
105
105
  if idpsso_descriptor.nil?
106
- raise ArgumentError.new("idp_metadata may contain an IDPSSODescriptor element")
106
+ raise ArgumentError.new("idp_metadata must contain an IDPSSODescriptor element")
107
107
  end
108
108
 
109
109
  {
@@ -211,6 +211,12 @@ module OneLogin
211
211
  return true unless options.has_key? :get_params
212
212
  return true unless options[:get_params].has_key? 'Signature'
213
213
 
214
+ options[:raw_get_params] = OneLogin::RubySaml::Utils.prepare_raw_get_params(options[:raw_get_params], options[:get_params])
215
+
216
+ if options[:get_params]['SigAlg'].nil? && !options[:raw_get_params]['SigAlg'].nil?
217
+ options[:get_params]['SigAlg'] = CGI.unescape(options[:raw_get_params]['SigAlg'])
218
+ end
219
+
214
220
  idp_cert = settings.get_idp_cert
215
221
  idp_certs = settings.get_idp_cert_multi
216
222
 
@@ -218,11 +224,11 @@ module OneLogin
218
224
  return options.has_key? :relax_signature_validation
219
225
  end
220
226
 
221
- query_string = OneLogin::RubySaml::Utils.build_query(
222
- :type => 'SAMLResponse',
223
- :data => options[:get_params]['SAMLResponse'],
224
- :relay_state => options[:get_params]['RelayState'],
225
- :sig_alg => options[:get_params]['SigAlg']
227
+ query_string = OneLogin::RubySaml::Utils.build_query_from_raw_parts(
228
+ :type => 'SAMLResponse',
229
+ :raw_data => options[:raw_get_params]['SAMLResponse'],
230
+ :raw_relay_state => options[:raw_get_params]['RelayState'],
231
+ :raw_sig_alg => options[:raw_get_params]['SigAlg']
226
232
  )
227
233
 
228
234
  if idp_certs.nil? || idp_certs[:signing].empty?
@@ -8,12 +8,12 @@ module OneLogin
8
8
  module RubySaml
9
9
 
10
10
  # SAML2 Metadata. XML Metadata Builder
11
- #
11
+ #
12
12
  class Metadata
13
13
 
14
14
  # Return SP metadata based on the settings.
15
15
  # @param settings [OneLogin::RubySaml::Settings|nil] Toolkit settings
16
- # @param pretty_print [Boolean] Pretty print or not the response
16
+ # @param pretty_print [Boolean] Pretty print or not the response
17
17
  # (No pretty print if you gonna validate the signature)
18
18
  # @return [String] XML Metadata of the Service Provider
19
19
  #
@@ -83,7 +83,7 @@ module OneLogin
83
83
  if settings.attribute_consuming_service.configured?
84
84
  sp_acs = sp_sso.add_element "md:AttributeConsumingService", {
85
85
  "isDefault" => "true",
86
- "index" => settings.attribute_consuming_service.index
86
+ "index" => settings.attribute_consuming_service.index
87
87
  }
88
88
  srv_name = sp_acs.add_element "md:ServiceName", {
89
89
  "xml:lang" => "en"
@@ -92,14 +92,14 @@ module OneLogin
92
92
  settings.attribute_consuming_service.attributes.each do |attribute|
93
93
  sp_req_attr = sp_acs.add_element "md:RequestedAttribute", {
94
94
  "NameFormat" => attribute[:name_format],
95
- "Name" => attribute[:name],
95
+ "Name" => attribute[:name],
96
96
  "FriendlyName" => attribute[:friendly_name],
97
97
  "isRequired" => attribute[:is_required] || false
98
98
  }
99
99
  unless attribute[:attribute_value].nil?
100
100
  Array(attribute[:attribute_value]).each do |value|
101
101
  sp_attr_val = sp_req_attr.add_element "saml:AttributeValue"
102
- sp_attr_val.text = value.to_str
102
+ sp_attr_val.text = value.to_s
103
103
  end
104
104
  end
105
105
  end
@@ -121,7 +121,7 @@ module OneLogin
121
121
  # pretty print the XML so IdP administrators can easily see what the SP supports
122
122
  if pretty_print
123
123
  meta_doc.write(ret, 1)
124
- else
124
+ else
125
125
  ret = meta_doc.to_s
126
126
  end
127
127
 
@@ -66,6 +66,18 @@ module OneLogin
66
66
 
67
67
  alias_method :nameid, :name_id
68
68
 
69
+ # @return [String] Gets the NameID Format of the Logout Request.
70
+ #
71
+ def name_id_format
72
+ @name_id_node ||= REXML::XPath.first(document, "/p:LogoutRequest/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
73
+ @name_id_format ||=
74
+ if @name_id_node && @name_id_node.attribute("Format")
75
+ @name_id_node.attribute("Format").value
76
+ end
77
+ end
78
+
79
+ alias_method :nameid_format, :name_id_format
80
+
69
81
  # @return [String|nil] Gets the ID attribute from the Logout Request. if exists.
70
82
  #
71
83
  def id
@@ -229,6 +241,36 @@ module OneLogin
229
241
  return true unless options.has_key? :get_params
230
242
  return true unless options[:get_params].has_key? 'Signature'
231
243
 
244
+ # SAML specifies that the signature should be derived from a concatenation
245
+ # of URI-encoded values _as sent by the IDP_:
246
+ #
247
+ # > Further, note that URL-encoding is not canonical; that is, there are multiple legal encodings for a given
248
+ # > value. The relying party MUST therefore perform the verification step using the original URL-encoded
249
+ # > values it received on the query string. It is not sufficient to re-encode the parameters after they have been
250
+ # > processed by software because the resulting encoding may not match the signer's encoding.
251
+ #
252
+ # <http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf>
253
+ #
254
+ # If we don't have the original parts (for backward compatibility) required to correctly verify the signature,
255
+ # then fabricate them by re-encoding the parsed URI parameters, and hope that we're lucky enough to use
256
+ # the exact same URI-encoding as the IDP. (This is not the case if the IDP is ADFS!)
257
+ options[:raw_get_params] ||= {}
258
+ if options[:raw_get_params]['SAMLRequest'].nil? && !options[:get_params]['SAMLRequest'].nil?
259
+ options[:raw_get_params]['SAMLRequest'] = CGI.escape(options[:get_params]['SAMLRequest'])
260
+ end
261
+ if options[:raw_get_params]['RelayState'].nil? && !options[:get_params]['RelayState'].nil?
262
+ options[:raw_get_params]['RelayState'] = CGI.escape(options[:get_params]['RelayState'])
263
+ end
264
+ if options[:raw_get_params]['SigAlg'].nil? && !options[:get_params]['SigAlg'].nil?
265
+ options[:raw_get_params]['SigAlg'] = CGI.escape(options[:get_params]['SigAlg'])
266
+ end
267
+
268
+ # If we only received the raw version of SigAlg,
269
+ # then parse it back into the decoded params hash for convenience.
270
+ if options[:get_params]['SigAlg'].nil? && !options[:raw_get_params]['SigAlg'].nil?
271
+ options[:get_params]['SigAlg'] = CGI.unescape(options[:raw_get_params]['SigAlg'])
272
+ end
273
+
232
274
  idp_cert = settings.get_idp_cert
233
275
  idp_certs = settings.get_idp_cert_multi
234
276
 
@@ -236,11 +278,11 @@ module OneLogin
236
278
  return options.has_key? :relax_signature_validation
237
279
  end
238
280
 
239
- query_string = OneLogin::RubySaml::Utils.build_query(
240
- :type => 'SAMLRequest',
241
- :data => options[:get_params]['SAMLRequest'],
242
- :relay_state => options[:get_params]['RelayState'],
243
- :sig_alg => options[:get_params]['SigAlg']
281
+ query_string = OneLogin::RubySaml::Utils.build_query_from_raw_parts(
282
+ :type => 'SAMLRequest',
283
+ :raw_data => options[:raw_get_params]['SAMLRequest'],
284
+ :raw_relay_state => options[:raw_get_params]['RelayState'],
285
+ :raw_sig_alg => options[:raw_get_params]['SigAlg']
244
286
  )
245
287
 
246
288
  if idp_certs.nil? || idp_certs[:signing].empty?
@@ -24,11 +24,19 @@ module OneLogin
24
24
  # don't try to format an encoded certificate or if is empty or nil
25
25
  return cert if cert.nil? || cert.empty? || cert.match(/\x0d/)
26
26
 
27
- cert = cert.gsub(/\-{5}\s?(BEGIN|END) CERTIFICATE\s?\-{5}/, "")
28
- cert = cert.gsub(/[\n\r\s]/, "")
29
- cert = cert.scan(/.{1,64}/)
30
- cert = cert.join("\n")
31
- "-----BEGIN CERTIFICATE-----\n#{cert}\n-----END CERTIFICATE-----"
27
+ if cert.scan(/BEGIN CERTIFICATE/).length > 1
28
+ formatted_cert = []
29
+ cert.scan(/-{5}BEGIN CERTIFICATE-{5}[\n\r]?.*?-{5}END CERTIFICATE-{5}[\n\r]?/m) {|c|
30
+ formatted_cert << format_cert(c)
31
+ }
32
+ formatted_cert.join("\n")
33
+ else
34
+ cert = cert.gsub(/\-{5}\s?(BEGIN|END) CERTIFICATE\s?\-{5}/, "")
35
+ cert = cert.gsub(/[\n\r\s]/, "")
36
+ cert = cert.scan(/.{1,64}/)
37
+ cert = cert.join("\n")
38
+ "-----BEGIN CERTIFICATE-----\n#{cert}\n-----END CERTIFICATE-----"
39
+ end
32
40
  end
33
41
 
34
42
  # Return a properly formatted private key
@@ -67,6 +75,49 @@ module OneLogin
67
75
  url_string << "&SigAlg=#{CGI.escape(sig_alg)}"
68
76
  end
69
77
 
78
+ # Reconstruct a canonical query string from raw URI-encoded parts, to be used in verifying a signature
79
+ #
80
+ # @param params [Hash] Parameters to build the Query String
81
+ # @option params [String] :type 'SAMLRequest' or 'SAMLResponse'
82
+ # @option params [String] :raw_data URI-encoded, base64 encoded SAMLRequest or SAMLResponse, as sent by IDP
83
+ # @option params [String] :raw_relay_state URI-encoded RelayState parameter, as sent by IDP
84
+ # @option params [String] :raw_sig_alg URI-encoded SigAlg parameter, as sent by IDP
85
+ # @return [String] The Query String
86
+ #
87
+ def self.build_query_from_raw_parts(params)
88
+ type, raw_data, raw_relay_state, raw_sig_alg = [:type, :raw_data, :raw_relay_state, :raw_sig_alg].map { |k| params[k]}
89
+
90
+ url_string = "#{type}=#{raw_data}"
91
+ url_string << "&RelayState=#{raw_relay_state}" if raw_relay_state
92
+ url_string << "&SigAlg=#{raw_sig_alg}"
93
+ end
94
+
95
+ # Prepare raw GET parameters (build them from normal parameters
96
+ # if not provided).
97
+ #
98
+ # @param rawparams [Hash] Raw GET Parameters
99
+ # @param params [Hash] GET Parameters
100
+ # @return [Hash] New raw parameters
101
+ #
102
+ def self.prepare_raw_get_params(rawparams, params)
103
+ rawparams ||= {}
104
+
105
+ if rawparams['SAMLRequest'].nil? && !params['SAMLRequest'].nil?
106
+ rawparams['SAMLRequest'] = CGI.escape(params['SAMLRequest'])
107
+ end
108
+ if rawparams['SAMLResponse'].nil? && !params['SAMLResponse'].nil?
109
+ rawparams['SAMLResponse'] = CGI.escape(params['SAMLResponse'])
110
+ end
111
+ if rawparams['RelayState'].nil? && !params['RelayState'].nil?
112
+ rawparams['RelayState'] = CGI.escape(params['RelayState'])
113
+ end
114
+ if rawparams['SigAlg'].nil? && !params['SigAlg'].nil?
115
+ rawparams['SigAlg'] = CGI.escape(params['SigAlg'])
116
+ end
117
+
118
+ rawparams
119
+ end
120
+
70
121
  # Validate the Signature parameter sent on the HTTP-Redirect binding
71
122
  # @param params [Hash] Parameters to be used in the validation process
72
123
  # @option params [OpenSSL::X509::Certificate] cert The Identity provider public certtificate
@@ -1,5 +1,5 @@
1
1
  module OneLogin
2
2
  module RubySaml
3
- VERSION = '1.5.0'
3
+ VERSION = '1.6.0'
4
4
  end
5
5
  end
@@ -0,0 +1,42 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE
3
+ BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh
4
+ MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx
5
+ wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz
6
+ c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq
7
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC
8
+ mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw
9
+ Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N
10
+ 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G
11
+ CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ
12
+ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1
13
+ 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
14
+ -----END CERTIFICATE-----
15
+ -----BEGIN CERTIFICATE-----
16
+ MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE
17
+ BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh
18
+ MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx
19
+ wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz
20
+ c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq
21
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC
22
+ mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw
23
+ Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N
24
+ 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G
25
+ CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ
26
+ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1
27
+ 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
28
+ -----END CERTIFICATE-----
29
+ -----BEGIN CERTIFICATE-----
30
+ MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE
31
+ BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh
32
+ MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx
33
+ wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz
34
+ c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq
35
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC
36
+ mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw
37
+ Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N
38
+ 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G
39
+ CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ
40
+ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1
41
+ 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
42
+ -----END CERTIFICATE-----
@@ -0,0 +1 @@
1
+ -----BEGIN CERTIFICATE-----MIICPDCCAaWgAwIBAgIIEiC/9HMAWW AwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UEBhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVhMDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIxwsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNzc28xJDAiBgNVBAMTG2MyNWE wMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jCmdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpwVvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0GCSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ+4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/12Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ-----END CERTIFICATE----------BEGIN CERTIFICATE-----MIICPDCCAaWgAw IBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UEBhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVhMDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIxwsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNzc28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jCmdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpwVvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0GCSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ+4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/12Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ-----END CERTIFICATE----------BEGIN CERTIFICATE-----MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UEBhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVhMDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIxwsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNzc28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jCmdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpwVvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0GCSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ+4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/12Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ-----END CERTIFICATE-----
@@ -0,0 +1,4 @@
1
+ <samlp:LogoutRequest Version='2.0' ID='_c0348950-935b-0131-1060-782bcb56fcaa' xmlns:samlp='urn:oasis:names:tc:SAML:2.0:protocol' IssueInstant='2014-03-21T19:20:13'>
2
+ <saml:Issuer xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>https://app.onelogin.com/saml/metadata/SOMEACCOUNT</saml:Issuer>
3
+ <saml:NameID xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion' Format='urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'>someone@example.org</saml:NameID>
4
+ </samlp:LogoutRequest>
@@ -283,6 +283,80 @@ class RubySamlTest < Minitest::Test
283
283
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.send(:validate_signature) }
284
284
  assert logoutresponse.errors.include? "Invalid Signature on Logout Response"
285
285
  end
286
+
287
+ it "raise when get_params encoding differs from what this library generates" do
288
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
289
+ settings.soft = false
290
+ options = {}
291
+ options[:get_params] = params
292
+ options[:get_params]['RelayState'] = 'http://example.com'
293
+ logoutresponse = OneLogin::RubySaml::Logoutresponse.new(params['SAMLResponse'], settings, options)
294
+ # Assemble query string.
295
+ query = OneLogin::RubySaml::Utils.build_query(
296
+ :type => 'SAMLResponse',
297
+ :data => params['SAMLResponse'],
298
+ :relay_state => params['RelayState'],
299
+ :sig_alg => params['SigAlg']
300
+ )
301
+ # Modify the query string so that it encodes the same values,
302
+ # but with different percent-encoding. Sanity-check that they
303
+ # really are equialent before moving on.
304
+ original_query = query.dup
305
+ query.gsub!("example", "ex%61mple")
306
+ refute_equal(query, original_query)
307
+ assert_equal(CGI.unescape(query), CGI.unescape(original_query))
308
+ # Make normalised signature based on our modified params.
309
+ sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
310
+ signature = settings.get_sp_key.sign(sign_algorithm.new, query)
311
+ params['Signature'] = Base64.encode64(signature).gsub(/\n/, "")
312
+ # Re-create the Logoutresponse based on these modified parameters,
313
+ # and ask it to validate the signature. It will do it incorrectly,
314
+ # because it will compute it based on re-encoded query parameters,
315
+ # rather than their original encodings.
316
+ options[:get_params] = params
317
+ logoutresponse = OneLogin::RubySaml::Logoutresponse.new(params['SAMLResponse'], settings, options)
318
+ assert_raises(OneLogin::RubySaml::ValidationError, "Invalid Signature on Logout Request") do
319
+ logoutresponse.send(:validate_signature)
320
+ end
321
+ end
322
+
323
+ it "return true even if raw_get_params encoding differs from what this library generates" do
324
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
325
+ settings.soft = false
326
+ options = {}
327
+ options[:get_params] = params
328
+ options[:get_params]['RelayState'] = 'http://example.com'
329
+ logoutresponse = OneLogin::RubySaml::Logoutresponse.new(params['SAMLResponse'], settings, options)
330
+ # Assemble query string.
331
+ query = OneLogin::RubySaml::Utils.build_query(
332
+ :type => 'SAMLResponse',
333
+ :data => params['SAMLResponse'],
334
+ :relay_state => params['RelayState'],
335
+ :sig_alg => params['SigAlg']
336
+ )
337
+ # Modify the query string so that it encodes the same values,
338
+ # but with different percent-encoding. Sanity-check that they
339
+ # really are equialent before moving on.
340
+ original_query = query.dup
341
+ query.gsub!("example", "ex%61mple")
342
+ refute_equal(query, original_query)
343
+ assert_equal(CGI.unescape(query), CGI.unescape(original_query))
344
+ # Make normalised signature based on our modified params.
345
+ sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
346
+ signature = settings.get_sp_key.sign(sign_algorithm.new, query)
347
+ params['Signature'] = Base64.encode64(signature).gsub(/\n/, "")
348
+ # Re-create the Logoutresponse based on these modified parameters,
349
+ # and ask it to validate the signature. Provide the altered parameter
350
+ # in its raw URI-encoded form, so that we don't have to guess the value
351
+ # that contributed to the signature.
352
+ options[:get_params] = params
353
+ options[:get_params].delete("RelayState")
354
+ options[:raw_get_params] = {
355
+ "RelayState" => "http%3A%2F%2Fex%61mple.com",
356
+ }
357
+ logoutresponse = OneLogin::RubySaml::Logoutresponse.new(params['SAMLResponse'], settings, options)
358
+ assert logoutresponse.send(:validate_signature)
359
+ end
286
360
  end
287
361
 
288
362
  describe "#validate_signature" do
@@ -32,7 +32,7 @@ class MetadataTest < Minitest::Test
32
32
  assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", REXML::XPath.first(xml_doc, "//md:NameIDFormat").text.strip
33
33
 
34
34
  assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", acs.attribute("Binding").value
35
- assert_equal "https://foo.example/saml/consume", acs.attribute("Location").value
35
+ assert_equal "https://foo.example/saml/consume", acs.attribute("Location").value
36
36
 
37
37
  assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
38
38
  end
@@ -225,7 +225,7 @@ class MetadataTest < Minitest::Test
225
225
  before do
226
226
  settings.attribute_consuming_service.configure do
227
227
  service_name "Test Service"
228
- add_attribute(:name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name", :attribute_value => ["Attribute Value One", "Attribute Value Two"])
228
+ add_attribute(:name => 'Name', :name_format => 'Name Format', :friendly_name => 'Friendly Name', :attribute_value => ['Attribute Value One', false])
229
229
  end
230
230
  end
231
231
 
@@ -240,20 +240,20 @@ class MetadataTest < Minitest::Test
240
240
 
241
241
  attribute_values = REXML::XPath.match(xml_doc, "//saml:AttributeValue").map(&:text)
242
242
  assert_equal "Attribute Value One", attribute_values[0]
243
- assert_equal "Attribute Value Two", attribute_values[1]
243
+ assert_equal 'false', attribute_values[1]
244
244
 
245
245
  assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
246
246
  end
247
247
  end
248
248
 
249
249
  describe "when attribute service is configured" do
250
- let(:attr_svc) { REXML::XPath.first(xml_doc, "//md:AttributeConsumingService") }
251
- let(:req_attr) { REXML::XPath.first(xml_doc, "//md:RequestedAttribute") }
250
+ let(:attr_svc) { REXML::XPath.first(xml_doc, '//md:AttributeConsumingService') }
251
+ let(:req_attr) { REXML::XPath.first(xml_doc, '//md:RequestedAttribute') }
252
252
 
253
253
  before do
254
254
  settings.attribute_consuming_service.configure do
255
255
  service_name "Test Service"
256
- add_attribute(:name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name", :attribute_value => "Attribute Value")
256
+ add_attribute(:name => 'active', :name_format => 'format', :friendly_name => 'Active', :attribute_value => true)
257
257
  end
258
258
  end
259
259
 
@@ -262,10 +262,10 @@ class MetadataTest < Minitest::Test
262
262
  assert_equal "1", attr_svc.attribute("index").value
263
263
  assert_equal REXML::XPath.first(xml_doc, "//md:ServiceName").text.strip, "Test Service"
264
264
 
265
- assert_equal "Name", req_attr.attribute("Name").value
266
- assert_equal "Name Format", req_attr.attribute("NameFormat").value
267
- assert_equal "Friendly Name", req_attr.attribute("FriendlyName").value
268
- assert_equal "Attribute Value", REXML::XPath.first(xml_doc, "//saml:AttributeValue").text.strip
265
+ assert_equal 'active', req_attr.attribute('Name').value
266
+ assert_equal 'format', req_attr.attribute('NameFormat').value
267
+ assert_equal 'Active', req_attr.attribute('FriendlyName').value
268
+ assert_equal 'true', REXML::XPath.first(xml_doc, '//saml:AttributeValue').text.strip
269
269
 
270
270
  assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
271
271
  end
@@ -303,7 +303,7 @@ class MetadataTest < Minitest::Test
303
303
  assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], xml_text
304
304
  assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], xml_text
305
305
  signed_metadata = XMLSecurity::SignedDocument.new(xml_text)
306
- assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false)
306
+ assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false)
307
307
 
308
308
  assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
309
309
  end
@@ -321,7 +321,7 @@ class MetadataTest < Minitest::Test
321
321
 
322
322
  signed_metadata_2 = XMLSecurity::SignedDocument.new(xml_text)
323
323
 
324
- assert signed_metadata_2.validate_document(ruby_saml_cert_fingerprint, false)
324
+ assert signed_metadata_2.validate_document(ruby_saml_cert_fingerprint, false)
325
325
 
326
326
  assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
327
327
  end
@@ -91,6 +91,14 @@ class RubySamlTest < Minitest::Test
91
91
  end
92
92
  end
93
93
 
94
+ describe "#nameid_format" do
95
+ let(:logout_request) { OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document_with_name_id_format) }
96
+
97
+ it "extract the format attribute of the name id element" do
98
+ assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", logout_request.nameid_format
99
+ end
100
+ end
101
+
94
102
  describe "#issuer" do
95
103
  it "return the issuer inside the logout request" do
96
104
  assert_equal "https://app.onelogin.com/saml/metadata/SOMEACCOUNT", logout_request.issuer
@@ -322,6 +330,78 @@ class RubySamlTest < Minitest::Test
322
330
  logout_request_sign_test.send(:validate_signature)
323
331
  end
324
332
  end
333
+
334
+ it "raise when get_params encoding differs from what this library generates" do
335
+ # Use Logoutrequest only to build the SAMLRequest parameter.
336
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
337
+ settings.soft = false
338
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, "RelayState" => "http://example.com")
339
+ # Assemble query string.
340
+ query = OneLogin::RubySaml::Utils.build_query(
341
+ :type => 'SAMLRequest',
342
+ :data => params['SAMLRequest'],
343
+ :relay_state => params['RelayState'],
344
+ :sig_alg => params['SigAlg']
345
+ )
346
+ # Modify the query string so that it encodes the same values,
347
+ # but with different percent-encoding. Sanity-check that they
348
+ # really are equialent before moving on.
349
+ original_query = query.dup
350
+ query.gsub!("example", "ex%61mple")
351
+ refute_equal(query, original_query)
352
+ assert_equal(CGI.unescape(query), CGI.unescape(original_query))
353
+ # Make normalised signature based on our modified params.
354
+ sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
355
+ signature = settings.get_sp_key.sign(sign_algorithm.new, query)
356
+ params['Signature'] = Base64.encode64(signature).gsub(/\n/, "")
357
+ # Construct SloLogoutrequest and ask it to validate the signature.
358
+ # It will do it incorrectly, because it will compute it based on re-encoded
359
+ # query parameters, rather than their original encodings.
360
+ options = {}
361
+ options[:get_params] = params
362
+ options[:settings] = settings
363
+ logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
364
+ assert_raises(OneLogin::RubySaml::ValidationError, "Invalid Signature on Logout Request") do
365
+ logout_request_sign_test.send(:validate_signature)
366
+ end
367
+ end
368
+
369
+ it "return true even if raw_get_params encoding differs from what this library generates" do
370
+ # Use Logoutrequest only to build the SAMLRequest parameter.
371
+ settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
372
+ settings.soft = false
373
+ params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, "RelayState" => "http://example.com")
374
+ # Assemble query string.
375
+ query = OneLogin::RubySaml::Utils.build_query(
376
+ :type => 'SAMLRequest',
377
+ :data => params['SAMLRequest'],
378
+ :relay_state => params['RelayState'],
379
+ :sig_alg => params['SigAlg']
380
+ )
381
+ # Modify the query string so that it encodes the same values,
382
+ # but with different percent-encoding. Sanity-check that they
383
+ # really are equialent before moving on.
384
+ original_query = query.dup
385
+ query.gsub!("example", "ex%61mple")
386
+ refute_equal(query, original_query)
387
+ assert_equal(CGI.unescape(query), CGI.unescape(original_query))
388
+ # Make normalised signature based on our modified params.
389
+ sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
390
+ signature = settings.get_sp_key.sign(sign_algorithm.new, query)
391
+ params['Signature'] = Base64.encode64(signature).gsub(/\n/, "")
392
+ # Construct SloLogoutrequest and ask it to validate the signature.
393
+ # Provide the altered parameter in its raw URI-encoded form,
394
+ # so that we don't have to guess the value that contributed to the signature.
395
+ options = {}
396
+ options[:get_params] = params
397
+ options[:get_params].delete("RelayState")
398
+ options[:raw_get_params] = {
399
+ "RelayState" => "http%3A%2F%2Fex%61mple.com",
400
+ }
401
+ options[:settings] = settings
402
+ logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
403
+ assert logout_request_sign_test.send(:validate_signature)
404
+ end
325
405
  end
326
406
 
327
407
  describe "#validate_signature with multiple idp certs" do
@@ -183,6 +183,15 @@ class Minitest::Test
183
183
  @logout_request_document
184
184
  end
185
185
 
186
+ def logout_request_document_with_name_id_format
187
+ unless @logout_request_document_with_name_id_format
188
+ xml = read_logout_request("slo_request_with_name_id_format.xml")
189
+ deflated = Zlib::Deflate.deflate(xml, 9)[2..-5]
190
+ @logout_request_document_with_name_id_format = Base64.encode64(deflated)
191
+ end
192
+ @logout_request_document_with_name_id_format
193
+ end
194
+
186
195
  def logout_request_xml_with_session_index
187
196
  @logout_request_xml_with_session_index ||= File.read(File.join(File.dirname(__FILE__), 'logout_requests', 'slo_request_with_session_index.xml'))
188
197
  end
@@ -2,9 +2,8 @@ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
 
3
3
  class UtilsTest < Minitest::Test
4
4
  describe ".format_cert" do
5
- let(:formatted_certificate) do
6
- read_certificate("formatted_certificate")
7
- end
5
+ let(:formatted_certificate) {read_certificate("formatted_certificate")}
6
+ let(:formatted_chained_certificate) {read_certificate("formatted_chained_certificate")}
8
7
 
9
8
  it "returns empty string when the cert is an empty string" do
10
9
  cert = ""
@@ -34,6 +33,16 @@ class UtilsTest < Minitest::Test
34
33
  invalid_certificate3 = read_certificate("invalid_certificate3")
35
34
  assert_equal formatted_certificate, OneLogin::RubySaml::Utils.format_cert(invalid_certificate3)
36
35
  end
36
+
37
+ it "returns the chained certificate when it is a valid chained certificate" do
38
+ assert_equal formatted_chained_certificate, OneLogin::RubySaml::Utils.format_cert(formatted_chained_certificate)
39
+ end
40
+
41
+ it "reformats the chained certificate when there are spaces and no line breaks" do
42
+ invalid_chained_certificate1 = read_certificate("invalid_chained_certificate1")
43
+ assert_equal formatted_chained_certificate, OneLogin::RubySaml::Utils.format_cert(invalid_chained_certificate1)
44
+ end
45
+
37
46
  end
38
47
 
39
48
  describe ".format_private_key" do
@@ -138,7 +147,7 @@ class UtilsTest < Minitest::Test
138
147
  status_error_msg2 = OneLogin::RubySaml::Utils.status_error_msg(error_msg, status_code)
139
148
  assert_equal = "The status code of the Logout Response was not Success, was Requester", status_error_msg2
140
149
 
141
- status_error_msg3 = OneLogin::RubySaml::Utils.status_error_msg(error_msg)
150
+ status_error_msg3 = OneLogin::RubySaml::Utils.status_error_msg(error_msg)
142
151
  assert_equal = "The status code of the Logout Response was not Success", status_error_msg3
143
152
  end
144
153
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-saml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OneLogin LLC
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-31 00:00:00.000000000 Z
11
+ date: 2017-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -190,11 +190,13 @@ files:
190
190
  - test/certificates/certificate1
191
191
  - test/certificates/certificate_without_head_foot
192
192
  - test/certificates/formatted_certificate
193
+ - test/certificates/formatted_chained_certificate
193
194
  - test/certificates/formatted_private_key
194
195
  - test/certificates/formatted_rsa_private_key
195
196
  - test/certificates/invalid_certificate1
196
197
  - test/certificates/invalid_certificate2
197
198
  - test/certificates/invalid_certificate3
199
+ - test/certificates/invalid_chained_certificate1
198
200
  - test/certificates/invalid_private_key1
199
201
  - test/certificates/invalid_private_key2
200
202
  - test/certificates/invalid_private_key3
@@ -210,6 +212,7 @@ files:
210
212
  - test/logout_requests/slo_request.xml
211
213
  - test/logout_requests/slo_request.xml.base64
212
214
  - test/logout_requests/slo_request_deflated.xml.base64
215
+ - test/logout_requests/slo_request_with_name_id_format.xml
213
216
  - test/logout_requests/slo_request_with_session_index.xml
214
217
  - test/logout_responses/logoutresponse_fixtures.rb
215
218
  - test/logoutrequest_test.rb
@@ -330,7 +333,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
330
333
  version: '0'
331
334
  requirements: []
332
335
  rubyforge_project: http://www.rubygems.org/gems/ruby-saml
333
- rubygems_version: 2.5.1
336
+ rubygems_version: 2.4.8
334
337
  signing_key:
335
338
  specification_version: 4
336
339
  summary: SAML Ruby Tookit
@@ -338,11 +341,13 @@ test_files:
338
341
  - test/certificates/certificate1
339
342
  - test/certificates/certificate_without_head_foot
340
343
  - test/certificates/formatted_certificate
344
+ - test/certificates/formatted_chained_certificate
341
345
  - test/certificates/formatted_private_key
342
346
  - test/certificates/formatted_rsa_private_key
343
347
  - test/certificates/invalid_certificate1
344
348
  - test/certificates/invalid_certificate2
345
349
  - test/certificates/invalid_certificate3
350
+ - test/certificates/invalid_chained_certificate1
346
351
  - test/certificates/invalid_private_key1
347
352
  - test/certificates/invalid_private_key2
348
353
  - test/certificates/invalid_private_key3
@@ -358,6 +363,7 @@ test_files:
358
363
  - test/logout_requests/slo_request.xml
359
364
  - test/logout_requests/slo_request.xml.base64
360
365
  - test/logout_requests/slo_request_deflated.xml.base64
366
+ - test/logout_requests/slo_request_with_name_id_format.xml
361
367
  - test/logout_requests/slo_request_with_session_index.xml
362
368
  - test/logout_responses/logoutresponse_fixtures.rb
363
369
  - test/logoutrequest_test.rb