ruby-saml 1.13.0 → 1.17.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.

@@ -613,7 +613,12 @@ module OneLogin
613
613
  #
614
614
  def validate_audience
615
615
  return true if options[:skip_audience]
616
- return true if audiences.empty? || settings.sp_entity_id.nil? || settings.sp_entity_id.empty?
616
+ return true if settings.sp_entity_id.nil? || settings.sp_entity_id.empty?
617
+
618
+ if audiences.empty?
619
+ return true unless settings.security[:strict_audience_validation]
620
+ return append_error("Invalid Audiences. The <AudienceRestriction> element contained only empty <Audience> elements. Expected audience #{settings.sp_entity_id}.")
621
+ end
617
622
 
618
623
  unless audiences.include? settings.sp_entity_id
619
624
  s = audiences.count > 1 ? 's' : '';
@@ -736,7 +741,7 @@ module OneLogin
736
741
  # @return [Boolean] True if the SessionNotOnOrAfter of the AuthnStatement is valid, otherwise (when expired) False if soft=True
737
742
  # @raise [ValidationError] if soft == false and validation fails
738
743
  #
739
- def validate_session_expiration(soft = true)
744
+ def validate_session_expiration
740
745
  return true if session_expires_at.nil?
741
746
 
742
747
  now = Time.now.utc
@@ -910,9 +915,9 @@ module OneLogin
910
915
  begin
911
916
  encrypted_node = xpath_first_from_signed_assertion('/a:Subject/a:EncryptedID')
912
917
  if encrypted_node
913
- node = decrypt_nameid(encrypted_node)
918
+ decrypt_nameid(encrypted_node)
914
919
  else
915
- node = xpath_first_from_signed_assertion('/a:Subject/a:NameID')
920
+ xpath_first_from_signed_assertion('/a:Subject/a:NameID')
916
921
  end
917
922
  end
918
923
  end
@@ -964,7 +969,7 @@ module OneLogin
964
969
  # @return [XMLSecurity::SignedDocument] The SAML Response with the assertion decrypted
965
970
  #
966
971
  def generate_decrypted_document
967
- if settings.nil? || !settings.get_sp_key
972
+ if settings.nil? || settings.get_sp_decryption_keys.empty?
968
973
  raise ValidationError.new('An EncryptedAssertion found and no SP private key found on the settings to decrypt it. Be sure you provided the :settings parameter at the initialize method')
969
974
  end
970
975
 
@@ -1007,42 +1012,42 @@ module OneLogin
1007
1012
  end
1008
1013
 
1009
1014
  # Decrypts an EncryptedID element
1010
- # @param encryptedid_node [REXML::Element] The EncryptedID element
1015
+ # @param encrypted_id_node [REXML::Element] The EncryptedID element
1011
1016
  # @return [REXML::Document] The decrypted EncrypedtID element
1012
1017
  #
1013
- def decrypt_nameid(encryptedid_node)
1014
- decrypt_element(encryptedid_node, /(.*<\/(\w+:)?NameID>)/m)
1018
+ def decrypt_nameid(encrypted_id_node)
1019
+ decrypt_element(encrypted_id_node, /(.*<\/(\w+:)?NameID>)/m)
1015
1020
  end
1016
1021
 
1017
- # Decrypts an EncryptedID element
1018
- # @param encryptedid_node [REXML::Element] The EncryptedID element
1019
- # @return [REXML::Document] The decrypted EncrypedtID element
1022
+ # Decrypts an EncryptedAttribute element
1023
+ # @param encrypted_attribute_node [REXML::Element] The EncryptedAttribute element
1024
+ # @return [REXML::Document] The decrypted EncryptedAttribute element
1020
1025
  #
1021
- def decrypt_attribute(encryptedattribute_node)
1022
- decrypt_element(encryptedattribute_node, /(.*<\/(\w+:)?Attribute>)/m)
1026
+ def decrypt_attribute(encrypted_attribute_node)
1027
+ decrypt_element(encrypted_attribute_node, /(.*<\/(\w+:)?Attribute>)/m)
1023
1028
  end
1024
1029
 
1025
1030
  # Decrypt an element
1026
- # @param encryptedid_node [REXML::Element] The encrypted element
1027
- # @param rgrex string Regex
1031
+ # @param encrypt_node [REXML::Element] The encrypted element
1032
+ # @param regexp [Regexp] The regular expression to extract the decrypted data
1028
1033
  # @return [REXML::Document] The decrypted element
1029
1034
  #
1030
- def decrypt_element(encrypt_node, rgrex)
1031
- if settings.nil? || !settings.get_sp_key
1035
+ def decrypt_element(encrypt_node, regexp)
1036
+ if settings.nil? || settings.get_sp_decryption_keys.empty?
1032
1037
  raise ValidationError.new('An ' + encrypt_node.name + ' found and no SP private key found on the settings to decrypt it')
1033
1038
  end
1034
1039
 
1035
-
1036
1040
  if encrypt_node.name == 'EncryptedAttribute'
1037
1041
  node_header = '<node xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
1038
1042
  else
1039
1043
  node_header = '<node xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">'
1040
1044
  end
1041
1045
 
1042
- elem_plaintext = OneLogin::RubySaml::Utils.decrypt_data(encrypt_node, settings.get_sp_key)
1046
+ elem_plaintext = OneLogin::RubySaml::Utils.decrypt_multi(encrypt_node, settings.get_sp_decryption_keys)
1047
+
1043
1048
  # If we get some problematic noise in the plaintext after decrypting.
1044
1049
  # This quick regexp parse will grab only the Element and discard the noise.
1045
- elem_plaintext = elem_plaintext.match(rgrex)[0]
1050
+ elem_plaintext = elem_plaintext.match(regexp)[0]
1046
1051
 
1047
1052
  # To avoid namespace errors if saml namespace is not defined
1048
1053
  # create a parent node first with the namespace defined
@@ -4,7 +4,6 @@ require 'base64'
4
4
  require 'nokogiri'
5
5
  require 'rexml/document'
6
6
  require 'rexml/xpath'
7
- require 'thread'
8
7
  require "onelogin/ruby-saml/error_handling"
9
8
 
10
9
  # Only supports SAML 2.0
@@ -69,14 +68,14 @@ module OneLogin
69
68
  xml = Nokogiri::XML(document.to_s) do |config|
70
69
  config.options = XMLSecurity::BaseDocument::NOKOGIRI_OPTIONS
71
70
  end
72
- rescue Exception => error
71
+ rescue StandardError => error
73
72
  return false if soft
74
73
  raise ValidationError.new("XML load failed: #{error.message}")
75
74
  end
76
75
 
77
76
  SamlMessage.schema.validate(xml).map do |schema_error|
78
77
  return false if soft
79
- raise ValidationError.new("#{schema_error.message}\n\n#{xml.to_s}")
78
+ raise ValidationError.new("#{schema_error.message}\n\n#{xml}")
80
79
  end
81
80
  end
82
81
 
@@ -20,7 +20,7 @@ module OneLogin
20
20
  end
21
21
 
22
22
  config.each do |k,v|
23
- acc = "#{k.to_s}=".to_sym
23
+ acc = "#{k}=".to_sym
24
24
  if respond_to? acc
25
25
  value = v.is_a?(Hash) ? v.dup : v
26
26
  send(acc, value)
@@ -60,8 +60,8 @@ module OneLogin
60
60
  attr_accessor :attributes_index
61
61
  attr_accessor :force_authn
62
62
  attr_accessor :certificate
63
- attr_accessor :certificate_new
64
63
  attr_accessor :private_key
64
+ attr_accessor :sp_cert_multi
65
65
  attr_accessor :authn_context
66
66
  attr_accessor :authn_context_comparison
67
67
  attr_accessor :authn_context_decl_ref
@@ -70,6 +70,7 @@ module OneLogin
70
70
  attr_accessor :security
71
71
  attr_accessor :soft
72
72
  # Deprecated
73
+ attr_accessor :certificate_new
73
74
  attr_accessor :assertion_consumer_logout_service_url
74
75
  attr_reader :assertion_consumer_logout_service_binding
75
76
  attr_accessor :issuer
@@ -180,10 +181,7 @@ module OneLogin
180
181
  # @return [OpenSSL::X509::Certificate|nil] Build the IdP certificate from the settings (previously format it)
181
182
  #
182
183
  def get_idp_cert
183
- return nil if idp_cert.nil? || idp_cert.empty?
184
-
185
- formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
186
- OpenSSL::X509::Certificate.new(formatted_cert)
184
+ OneLogin::RubySaml::Utils.build_cert_object(idp_cert)
187
185
  end
188
186
 
189
187
  # @return [Hash with 2 arrays of OpenSSL::X509::Certificate] Build multiple IdP certificates from the settings.
@@ -191,63 +189,79 @@ module OneLogin
191
189
  def get_idp_cert_multi
192
190
  return nil if idp_cert_multi.nil? || idp_cert_multi.empty?
193
191
 
194
- raise ArgumentError.new("Invalid value for idp_cert_multi") if not idp_cert_multi.is_a?(Hash)
192
+ raise ArgumentError.new("Invalid value for idp_cert_multi") unless idp_cert_multi.is_a?(Hash)
195
193
 
196
194
  certs = {:signing => [], :encryption => [] }
197
195
 
198
- if idp_cert_multi.key?(:signing) and not idp_cert_multi[:signing].empty?
199
- idp_cert_multi[:signing].each do |idp_cert|
200
- formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
201
- certs[:signing].push(OpenSSL::X509::Certificate.new(formatted_cert))
202
- end
203
- end
196
+ [:signing, :encryption].each do |type|
197
+ certs_for_type = idp_cert_multi[type] || idp_cert_multi[type.to_s]
198
+ next if !certs_for_type || certs_for_type.empty?
204
199
 
205
- if idp_cert_multi.key?(:encryption) and not idp_cert_multi[:encryption].empty?
206
- idp_cert_multi[:encryption].each do |idp_cert|
207
- formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
208
- certs[:encryption].push(OpenSSL::X509::Certificate.new(formatted_cert))
200
+ certs_for_type.each do |idp_cert|
201
+ certs[type].push(OneLogin::RubySaml::Utils.build_cert_object(idp_cert))
209
202
  end
210
203
  end
211
204
 
212
205
  certs
213
206
  end
214
207
 
215
- # @return [OpenSSL::X509::Certificate|nil] Build the SP certificate from the settings (previously format it)
216
- #
217
- def get_sp_cert
218
- return nil if certificate.nil? || certificate.empty?
208
+ # @return [Hash<Symbol, Array<Array<OpenSSL::X509::Certificate, OpenSSL::PKey::RSA>>>]
209
+ # Build the SP certificates and private keys from the settings. If
210
+ # check_sp_cert_expiration is true, only returns certificates and private keys
211
+ # that are not expired.
212
+ def get_sp_certs
213
+ certs = get_all_sp_certs
214
+ return certs unless security[:check_sp_cert_expiration]
219
215
 
220
- formatted_cert = OneLogin::RubySaml::Utils.format_cert(certificate)
221
- cert = OpenSSL::X509::Certificate.new(formatted_cert)
216
+ active_certs = { signing: [], encryption: [] }
217
+ certs.each do |use, pairs|
218
+ next if pairs.empty?
222
219
 
223
- if security[:check_sp_cert_expiration]
224
- if OneLogin::RubySaml::Utils.is_cert_expired(cert)
225
- raise OneLogin::RubySaml::ValidationError.new("The SP certificate expired.")
226
- end
220
+ pairs = pairs.select { |cert, _| !cert || OneLogin::RubySaml::Utils.is_cert_active(cert) }
221
+ raise OneLogin::RubySaml::ValidationError.new("The SP certificate expired.") if pairs.empty?
222
+
223
+ active_certs[use] = pairs.freeze
227
224
  end
225
+ active_certs.freeze
226
+ end
228
227
 
229
- cert
228
+ # @return [Array<OpenSSL::X509::Certificate, OpenSSL::PKey::RSA>]
229
+ # The SP signing certificate and private key.
230
+ def get_sp_signing_pair
231
+ get_sp_certs[:signing].first
230
232
  end
231
233
 
232
- # @return [OpenSSL::X509::Certificate|nil] Build the New SP certificate from the settings (previously format it)
233
- #
234
- def get_sp_cert_new
235
- return nil if certificate_new.nil? || certificate_new.empty?
234
+ # @return [OpenSSL::X509::Certificate] The SP signing certificate.
235
+ # @deprecated Use get_sp_signing_pair or get_sp_certs instead.
236
+ def get_sp_cert
237
+ node = get_sp_signing_pair
238
+ node[0] if node
239
+ end
236
240
 
237
- formatted_cert = OneLogin::RubySaml::Utils.format_cert(certificate_new)
238
- OpenSSL::X509::Certificate.new(formatted_cert)
241
+ # @return [OpenSSL::PKey::RSA] The SP signing key.
242
+ def get_sp_signing_key
243
+ node = get_sp_signing_pair
244
+ node[1] if node
239
245
  end
240
246
 
241
- # @return [OpenSSL::PKey::RSA] Build the SP private from the settings (previously format it)
242
- #
243
- def get_sp_key
244
- return nil if private_key.nil? || private_key.empty?
247
+ # @deprecated Use get_sp_signing_key or get_sp_certs instead.
248
+ alias_method :get_sp_key, :get_sp_signing_key
245
249
 
246
- formatted_private_key = OneLogin::RubySaml::Utils.format_private_key(private_key)
247
- OpenSSL::PKey::RSA.new(formatted_private_key)
250
+ # @return [Array<OpenSSL::PKey::RSA>] The SP decryption keys.
251
+ def get_sp_decryption_keys
252
+ ary = get_sp_certs[:encryption].map { |pair| pair[1] }
253
+ ary.compact!
254
+ ary.uniq!(&:to_pem)
255
+ ary.freeze
248
256
  end
249
257
 
250
- private
258
+ # @return [OpenSSL::X509::Certificate|nil] Build the New SP certificate from the settings.
259
+ #
260
+ # @deprecated Use get_sp_certs instead
261
+ def get_sp_cert_new
262
+ node = get_sp_certs[:signing].last
263
+ node[0] if node
264
+ end
251
265
 
252
266
  def idp_binding_from_embed_sign
253
267
  security[:embed_sign] ? Utils::BINDINGS[:post] : Utils::BINDINGS[:redirect]
@@ -280,9 +294,90 @@ module OneLogin
280
294
  :digest_method => XMLSecurity::Document::SHA1,
281
295
  :signature_method => XMLSecurity::Document::RSA_SHA1,
282
296
  :check_idp_cert_expiration => false,
283
- :check_sp_cert_expiration => false
297
+ :check_sp_cert_expiration => false,
298
+ :strict_audience_validation => false,
299
+ :lowercase_url_encoding => false
284
300
  }.freeze
285
301
  }.freeze
302
+
303
+ private
304
+
305
+ # @return [Hash<Symbol, Array<Array<OpenSSL::X509::Certificate, OpenSSL::PKey::RSA>>>]
306
+ # Build the SP certificates and private keys from the settings. Returns all
307
+ # certificates and private keys, even if they are expired.
308
+ def get_all_sp_certs
309
+ validate_sp_certs_params!
310
+ get_sp_certs_multi || get_sp_certs_single
311
+ end
312
+
313
+ # Validate certificate, certificate_new, private_key, and sp_cert_multi params.
314
+ def validate_sp_certs_params!
315
+ multi = sp_cert_multi && !sp_cert_multi.empty?
316
+ cert = certificate && !certificate.empty?
317
+ cert_new = certificate_new && !certificate_new.empty?
318
+ pk = private_key && !private_key.empty?
319
+ if multi && (cert || cert_new || pk)
320
+ raise ArgumentError.new("Cannot specify both sp_cert_multi and certificate, certificate_new, private_key parameters")
321
+ end
322
+ end
323
+
324
+ # Get certs from certificate, certificate_new, and private_key parameters.
325
+ def get_sp_certs_single
326
+ certs = { :signing => [], :encryption => [] }
327
+
328
+ sp_key = OneLogin::RubySaml::Utils.build_private_key_object(private_key)
329
+ cert = OneLogin::RubySaml::Utils.build_cert_object(certificate)
330
+ if cert || sp_key
331
+ ary = [cert, sp_key].freeze
332
+ certs[:signing] << ary
333
+ certs[:encryption] << ary
334
+ end
335
+
336
+ cert_new = OneLogin::RubySaml::Utils.build_cert_object(certificate_new)
337
+ if cert_new
338
+ ary = [cert_new, sp_key].freeze
339
+ certs[:signing] << ary
340
+ certs[:encryption] << ary
341
+ end
342
+
343
+ certs
344
+ end
345
+
346
+ # Get certs from get_sp_cert_multi parameter.
347
+ def get_sp_certs_multi
348
+ return if sp_cert_multi.nil? || sp_cert_multi.empty?
349
+
350
+ raise ArgumentError.new("sp_cert_multi must be a Hash") unless sp_cert_multi.is_a?(Hash)
351
+
352
+ certs = { :signing => [], :encryption => [] }.freeze
353
+
354
+ [:signing, :encryption].each do |type|
355
+ certs_for_type = sp_cert_multi[type] || sp_cert_multi[type.to_s]
356
+ next if !certs_for_type || certs_for_type.empty?
357
+
358
+ unless certs_for_type.is_a?(Array) && certs_for_type.all? { |cert| cert.is_a?(Hash) }
359
+ raise ArgumentError.new("sp_cert_multi :#{type} node must be an Array of Hashes")
360
+ end
361
+
362
+ certs_for_type.each do |pair|
363
+ cert = pair[:certificate] || pair['certificate'] || pair[:cert] || pair['cert']
364
+ key = pair[:private_key] || pair['private_key'] || pair[:key] || pair['key']
365
+
366
+ unless cert && key
367
+ raise ArgumentError.new("sp_cert_multi :#{type} node Hashes must specify keys :certificate and :private_key")
368
+ end
369
+
370
+ certs[type] << [
371
+ OneLogin::RubySaml::Utils.build_cert_object(cert),
372
+ OneLogin::RubySaml::Utils.build_private_key_object(key)
373
+ ].freeze
374
+ end
375
+ end
376
+
377
+ certs.each { |_, ary| ary.freeze }
378
+ certs
379
+ end
286
380
  end
287
381
  end
288
382
  end
383
+
@@ -62,10 +62,7 @@ module OneLogin
62
62
  # @return [String] Gets the NameID of the Logout Request.
63
63
  #
64
64
  def name_id
65
- @name_id ||= begin
66
- node = REXML::XPath.first(document, "/p:LogoutRequest/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
67
- Utils.element_text(node)
68
- end
65
+ @name_id ||= Utils.element_text(name_id_node)
69
66
  end
70
67
 
71
68
  alias_method :nameid, :name_id
@@ -73,15 +70,49 @@ module OneLogin
73
70
  # @return [String] Gets the NameID Format of the Logout Request.
74
71
  #
75
72
  def name_id_format
76
- @name_id_node ||= REXML::XPath.first(document, "/p:LogoutRequest/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
77
73
  @name_id_format ||=
78
- if @name_id_node && @name_id_node.attribute("Format")
79
- @name_id_node.attribute("Format").value
74
+ if name_id_node && name_id_node.attribute("Format")
75
+ name_id_node.attribute("Format").value
80
76
  end
81
77
  end
82
78
 
83
79
  alias_method :nameid_format, :name_id_format
84
80
 
81
+ def name_id_node
82
+ @name_id_node ||=
83
+ begin
84
+ encrypted_node = REXML::XPath.first(document, "/p:LogoutRequest/a:EncryptedID", { "p" => PROTOCOL, "a" => ASSERTION })
85
+ if encrypted_node
86
+ node = decrypt_nameid(encrypted_node)
87
+ else
88
+ node = REXML::XPath.first(document, "/p:LogoutRequest/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
89
+ end
90
+ end
91
+ end
92
+
93
+ # Decrypts an EncryptedID element
94
+ # @param encrypted_id_node [REXML::Element] The EncryptedID element
95
+ # @return [REXML::Document] The decrypted EncrypedtID element
96
+ #
97
+ def decrypt_nameid(encrypted_id_node)
98
+
99
+ if settings.nil? || settings.get_sp_decryption_keys.empty?
100
+ raise ValidationError.new('An ' + encrypted_id_node.name + ' found and no SP private key found on the settings to decrypt it')
101
+ end
102
+
103
+ elem_plaintext = OneLogin::RubySaml::Utils.decrypt_multi(encrypted_id_node, settings.get_sp_decryption_keys)
104
+ # If we get some problematic noise in the plaintext after decrypting.
105
+ # This quick regexp parse will grab only the Element and discard the noise.
106
+ elem_plaintext = elem_plaintext.match(/(.*<\/(\w+:)?NameID>)/m)[0]
107
+
108
+ # To avoid namespace errors if saml namespace is not defined
109
+ # create a parent node first with the namespace defined
110
+ node_header = '<node xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">'
111
+ elem_plaintext = node_header + elem_plaintext + '</node>'
112
+ doc = REXML::Document.new(elem_plaintext)
113
+ doc.root[0]
114
+ end
115
+
85
116
  # @return [String|nil] Gets the ID attribute from the Logout Request. if exists.
86
117
  #
87
118
  def id
@@ -248,32 +279,8 @@ module OneLogin
248
279
  return true unless options.has_key? :get_params
249
280
  return true unless options[:get_params].has_key? 'Signature'
250
281
 
251
- # SAML specifies that the signature should be derived from a concatenation
252
- # of URI-encoded values _as sent by the IDP_:
253
- #
254
- # > Further, note that URL-encoding is not canonical; that is, there are multiple legal encodings for a given
255
- # > value. The relying party MUST therefore perform the verification step using the original URL-encoded
256
- # > values it received on the query string. It is not sufficient to re-encode the parameters after they have been
257
- # > processed by software because the resulting encoding may not match the signer's encoding.
258
- #
259
- # <http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf>
260
- #
261
- # If we don't have the original parts (for backward compatibility) required to correctly verify the signature,
262
- # then fabricate them by re-encoding the parsed URI parameters, and hope that we're lucky enough to use
263
- # the exact same URI-encoding as the IDP. (This is not the case if the IDP is ADFS!)
264
- options[:raw_get_params] ||= {}
265
- if options[:raw_get_params]['SAMLRequest'].nil? && !options[:get_params]['SAMLRequest'].nil?
266
- options[:raw_get_params]['SAMLRequest'] = CGI.escape(options[:get_params]['SAMLRequest'])
267
- end
268
- if options[:raw_get_params]['RelayState'].nil? && !options[:get_params]['RelayState'].nil?
269
- options[:raw_get_params]['RelayState'] = CGI.escape(options[:get_params]['RelayState'])
270
- end
271
- if options[:raw_get_params]['SigAlg'].nil? && !options[:get_params]['SigAlg'].nil?
272
- options[:raw_get_params]['SigAlg'] = CGI.escape(options[:get_params]['SigAlg'])
273
- end
282
+ options[:raw_get_params] = OneLogin::RubySaml::Utils.prepare_raw_get_params(options[:raw_get_params], options[:get_params], settings.security[:lowercase_url_encoding])
274
283
 
275
- # If we only received the raw version of SigAlg,
276
- # then parse it back into the decoded params hash for convenience.
277
284
  if options[:get_params]['SigAlg'].nil? && !options[:raw_get_params]['SigAlg'].nil?
278
285
  options[:get_params]['SigAlg'] = CGI.unescape(options[:raw_get_params]['SigAlg'])
279
286
  end
@@ -335,7 +342,6 @@ module OneLogin
335
342
 
336
343
  true
337
344
  end
338
-
339
345
  end
340
346
  end
341
347
  end
@@ -13,7 +13,7 @@ module OneLogin
13
13
  class SloLogoutresponse < SamlMessage
14
14
 
15
15
  # Logout Response ID
16
- attr_reader :uuid
16
+ attr_accessor :uuid
17
17
 
18
18
  # Initializes the Logout Response. A SloLogoutresponse Object that is an extension of the SamlMessage class.
19
19
  # Asigns an ID, a random uuid.
@@ -41,7 +41,7 @@ module OneLogin
41
41
  saml_response = CGI.escape(params.delete("SAMLResponse"))
42
42
  response_params = "#{params_prefix}SAMLResponse=#{saml_response}"
43
43
  params.each_pair do |key, value|
44
- response_params << "&#{key.to_s}=#{CGI.escape(value.to_s)}"
44
+ response_params << "&#{key}=#{CGI.escape(value.to_s)}"
45
45
  end
46
46
 
47
47
  raise SettingError.new "Invalid settings, idp_slo_service_url is not set!" if url.nil? or url.empty?
@@ -78,9 +78,10 @@ module OneLogin
78
78
  response = deflate(response) if settings.compress_response
79
79
  base64_response = encode(response)
80
80
  response_params = {"SAMLResponse" => base64_response}
81
+ sp_signing_key = settings.get_sp_signing_key
81
82
 
82
- if settings.idp_slo_service_binding == Utils::BINDINGS[:redirect] && settings.security[:logout_responses_signed] && settings.private_key
83
- params['SigAlg'] = settings.security[:signature_method]
83
+ if settings.idp_slo_service_binding == Utils::BINDINGS[:redirect] && settings.security[:logout_responses_signed] && sp_signing_key
84
+ params['SigAlg'] = settings.security[:signature_method]
84
85
  url_string = OneLogin::RubySaml::Utils.build_query(
85
86
  :type => 'SAMLResponse',
86
87
  :data => base64_response,
@@ -88,7 +89,7 @@ module OneLogin
88
89
  :sig_alg => params['SigAlg']
89
90
  )
90
91
  sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
91
- signature = settings.get_sp_key.sign(sign_algorithm.new, url_string)
92
+ signature = sp_signing_key.sign(sign_algorithm.new, url_string)
92
93
  params['Signature'] = encode(signature)
93
94
  end
94
95
 
@@ -150,9 +151,8 @@ module OneLogin
150
151
 
151
152
  def sign_document(document, settings)
152
153
  # embed signature
153
- if settings.idp_slo_service_binding == Utils::BINDINGS[:post] && settings.private_key && settings.certificate
154
- private_key = settings.get_sp_key
155
- cert = settings.get_sp_cert
154
+ cert, private_key = settings.get_sp_signing_pair
155
+ if settings.idp_slo_service_binding == Utils::BINDINGS[:post] && private_key && cert
156
156
  document.sign_document(private_key, cert, settings.security[:signature_method], settings.security[:digest_method])
157
157
  end
158
158