ruby-saml 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.

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