ruby-saml 0.8.16 → 0.9

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.

Files changed (90) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +1 -6
  4. data/Gemfile +2 -12
  5. data/README.md +363 -35
  6. data/Rakefile +14 -0
  7. data/changelog.md +22 -9
  8. data/lib/onelogin/ruby-saml/attribute_service.rb +34 -0
  9. data/lib/onelogin/ruby-saml/attributes.rb +26 -64
  10. data/lib/onelogin/ruby-saml/authrequest.rb +47 -89
  11. data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +87 -0
  12. data/lib/onelogin/ruby-saml/logoutrequest.rb +34 -93
  13. data/lib/onelogin/ruby-saml/logoutresponse.rb +25 -24
  14. data/lib/onelogin/ruby-saml/metadata.rb +46 -16
  15. data/lib/onelogin/ruby-saml/response.rb +62 -322
  16. data/lib/onelogin/ruby-saml/saml_message.rb +78 -0
  17. data/lib/onelogin/ruby-saml/settings.rb +54 -121
  18. data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +26 -61
  19. data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +27 -84
  20. data/lib/onelogin/ruby-saml/utils.rb +32 -199
  21. data/lib/onelogin/ruby-saml/version.rb +1 -1
  22. data/lib/ruby-saml.rb +5 -2
  23. data/lib/schemas/{saml20assertion_schema.xsd → saml-schema-assertion-2.0.xsd} +283 -283
  24. data/lib/schemas/saml-schema-authn-context-2.0.xsd +23 -0
  25. data/lib/schemas/saml-schema-authn-context-types-2.0.xsd +821 -0
  26. data/lib/schemas/saml-schema-metadata-2.0.xsd +339 -0
  27. data/lib/schemas/{saml20protocol_schema.xsd → saml-schema-protocol-2.0.xsd} +302 -302
  28. data/lib/schemas/sstc-metadata-attr.xsd +35 -0
  29. data/lib/schemas/sstc-saml-attribute-ext.xsd +25 -0
  30. data/lib/schemas/sstc-saml-metadata-algsupport-v1.0.xsd +41 -0
  31. data/lib/schemas/sstc-saml-metadata-ui-v1.0.xsd +89 -0
  32. data/lib/schemas/{xenc_schema.xsd → xenc-schema.xsd} +1 -11
  33. data/lib/schemas/xml.xsd +287 -0
  34. data/lib/schemas/{xmldsig_schema.xsd → xmldsig-core-schema.xsd} +0 -9
  35. data/lib/xml_security.rb +83 -235
  36. data/ruby-saml.gemspec +1 -0
  37. data/test/idp_metadata_parser_test.rb +54 -0
  38. data/test/logoutrequest_test.rb +68 -144
  39. data/test/logoutresponse_test.rb +43 -25
  40. data/test/metadata_test.rb +87 -0
  41. data/test/request_test.rb +103 -90
  42. data/test/response_test.rb +181 -471
  43. data/test/responses/idp_descriptor.xml +3 -0
  44. data/test/responses/logoutresponse_fixtures.rb +5 -5
  45. data/test/responses/response_no_cert_and_encrypted_attrs.xml +29 -0
  46. data/test/responses/response_with_multiple_attribute_values.xml +1 -1
  47. data/test/responses/slo_request.xml +4 -0
  48. data/test/settings_test.rb +25 -112
  49. data/test/slo_logoutrequest_test.rb +41 -44
  50. data/test/slo_logoutresponse_test.rb +87 -167
  51. data/test/test_helper.rb +27 -102
  52. data/test/xml_security_test.rb +114 -337
  53. metadata +34 -84
  54. data/lib/onelogin/ruby-saml/setting_error.rb +0 -6
  55. data/test/certificates/certificate.der +0 -0
  56. data/test/certificates/formatted_certificate +0 -14
  57. data/test/certificates/formatted_chained_certificate +0 -42
  58. data/test/certificates/formatted_private_key +0 -12
  59. data/test/certificates/formatted_rsa_private_key +0 -12
  60. data/test/certificates/invalid_certificate1 +0 -1
  61. data/test/certificates/invalid_certificate2 +0 -1
  62. data/test/certificates/invalid_certificate3 +0 -12
  63. data/test/certificates/invalid_chained_certificate1 +0 -1
  64. data/test/certificates/invalid_private_key1 +0 -1
  65. data/test/certificates/invalid_private_key2 +0 -1
  66. data/test/certificates/invalid_private_key3 +0 -10
  67. data/test/certificates/invalid_rsa_private_key1 +0 -1
  68. data/test/certificates/invalid_rsa_private_key2 +0 -1
  69. data/test/certificates/invalid_rsa_private_key3 +0 -10
  70. data/test/certificates/ruby-saml-2.crt +0 -15
  71. data/test/requests/logoutrequest_fixtures.rb +0 -47
  72. data/test/responses/encrypted_new_attack.xml.base64 +0 -1
  73. data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +0 -1
  74. data/test/responses/invalids/invalid_issuer_message.xml.base64 +0 -1
  75. data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
  76. data/test/responses/invalids/no_signature.xml.base64 +0 -1
  77. data/test/responses/invalids/response_with_concealed_signed_assertion.xml +0 -51
  78. data/test/responses/invalids/response_with_doubled_signed_assertion.xml +0 -49
  79. data/test/responses/invalids/signature_wrapping_attack.xml.base64 +0 -1
  80. data/test/responses/response_node_text_attack.xml.base64 +0 -1
  81. data/test/responses/response_with_concealed_signed_assertion.xml +0 -51
  82. data/test/responses/response_with_doubled_signed_assertion.xml +0 -49
  83. data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
  84. data/test/responses/response_with_signed_assertion_3.xml +0 -30
  85. data/test/responses/response_with_signed_message_and_assertion.xml +0 -34
  86. data/test/responses/response_with_undefined_recipient.xml.base64 +0 -1
  87. data/test/responses/response_wrapped.xml.base64 +0 -150
  88. data/test/responses/valid_response.xml.base64 +0 -1
  89. data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
  90. data/test/utils_test.rb +0 -231
@@ -1,30 +1,30 @@
1
1
  require "xml_security"
2
2
  require "time"
3
3
  require "nokogiri"
4
- require "onelogin/ruby-saml/utils"
5
- require 'onelogin/ruby-saml/attributes'
6
4
 
7
5
  # Only supports SAML 2.0
8
6
  module OneLogin
9
7
  module RubySaml
10
8
 
11
- class Response
9
+ class Response < SamlMessage
12
10
  ASSERTION = "urn:oasis:names:tc:SAML:2.0:assertion"
13
11
  PROTOCOL = "urn:oasis:names:tc:SAML:2.0:protocol"
14
12
  DSIG = "http://www.w3.org/2000/09/xmldsig#"
15
13
 
16
14
  # TODO: This should probably be ctor initialized too... WDYT?
17
15
  attr_accessor :settings
16
+ attr_accessor :errors
18
17
 
19
18
  attr_reader :options
20
19
  attr_reader :response
21
20
  attr_reader :document
22
21
 
23
22
  def initialize(response, options = {})
23
+ @errors = []
24
24
  raise ArgumentError.new("Response cannot be nil") if response.nil?
25
25
  @options = options
26
- @response = OneLogin::RubySaml::Utils.decode_raw_saml(response)
27
- @document = XMLSecurity::SignedDocument.new(@response)
26
+ @response = decode_raw_saml(response)
27
+ @document = XMLSecurity::SignedDocument.new(@response, @errors)
28
28
  end
29
29
 
30
30
  def is_valid?
@@ -35,16 +35,18 @@ module OneLogin
35
35
  validate(false)
36
36
  end
37
37
 
38
+ def errors
39
+ @errors
40
+ end
41
+
38
42
  # The value of the user identifier as designated by the initialization request response
39
43
  def name_id
40
44
  @name_id ||= begin
41
45
  node = xpath_first_from_signed_assertion('/a:Subject/a:NameID')
42
- Utils.element_text(node)
46
+ node.nil? ? nil : node.text
43
47
  end
44
48
  end
45
49
 
46
- alias nameid name_id
47
-
48
50
  def sessionindex
49
51
  @sessionindex ||= begin
50
52
  node = xpath_first_from_signed_assertion('/a:AuthnStatement')
@@ -52,9 +54,9 @@ module OneLogin
52
54
  end
53
55
  end
54
56
 
55
- # Gets the Attributes from the AttributeStatement element.
56
- #
57
+ # Returns OneLogin::RubySaml::Attributes enumerable collection.
57
58
  # All attributes can be iterated over +attributes.each+ or returned as array by +attributes.all+
59
+ #
58
60
  # For backwards compatibility ruby-saml returns by default only the first value for a given attribute with
59
61
  # attributes['name']
60
62
  # To get all of the attributes, use:
@@ -63,36 +65,24 @@ module OneLogin
63
65
  # OneLogin::RubySaml::Attributes.single_value_compatibility = false
64
66
  # Now this will return an array:
65
67
  # attributes['name']
66
- #
67
- # @return [Attributes] OneLogin::RubySaml::Attributes enumerable collection.
68
- #
69
68
  def attributes
70
69
  @attr_statements ||= begin
71
70
  attributes = Attributes.new
72
71
 
73
- stmt_elements = xpath_from_signed_assertion('/a:AttributeStatement')
74
- stmt_elements.each do |stmt_element|
75
- stmt_element.elements.each do |attr_element|
76
- name = attr_element.attributes["Name"]
77
- values = attr_element.elements.collect{|e|
78
- if (e.elements.nil? || e.elements.size == 0)
79
- # SAMLCore requires that nil AttributeValues MUST contain xsi:nil XML attribute set to "true" or "1"
80
- # otherwise the value is to be regarded as empty.
81
- ["true", "1"].include?(e.attributes['xsi:nil']) ? nil : Utils.element_text(e)
82
- # explicitly support saml2:NameID with saml2:NameQualifier if supplied in attributes
83
- # this is useful for allowing eduPersonTargetedId to be passed as an opaque identifier to use to
84
- # identify the subject in an SP rather than email or other less opaque attributes
85
- # NameQualifier, if present is prefixed with a "/" to the value
86
- else
87
- REXML::XPath.match(e,'a:NameID', { "a" => ASSERTION }).collect{|n|
88
- (n.attributes['NameQualifier'] ? n.attributes['NameQualifier'] +"/" : '') + Utils.element_text(n)
89
- }
90
- end
91
- }
92
-
93
- attributes.add(name, values.flatten)
94
- end
72
+ stmt_element = xpath_first_from_signed_assertion('/a:AttributeStatement')
73
+ return attributes if stmt_element.nil?
74
+
75
+ stmt_element.elements.each do |attr_element|
76
+ name = attr_element.attributes["Name"]
77
+ values = attr_element.elements.collect{|e|
78
+ # SAMLCore requires that nil AttributeValues MUST contain xsi:nil XML attribute set to "true" or "1"
79
+ # otherwise the value is to be regarded as empty.
80
+ ["true", "1"].include?(e.attributes['xsi:nil']) ? nil : e.text.to_s
81
+ }
82
+
83
+ attributes.add(name, values)
95
84
  end
85
+
96
86
  attributes
97
87
  end
98
88
  end
@@ -113,6 +103,13 @@ module OneLogin
113
103
  end
114
104
  end
115
105
 
106
+ def status_message
107
+ @status_message ||= begin
108
+ node = REXML::XPath.first(document, "/p:Response/p:Status/p:StatusMessage", { "p" => PROTOCOL, "a" => ASSERTION })
109
+ node.text if node
110
+ end
111
+ end
112
+
116
113
  # Conditions (if any) for the assertion to run
117
114
  def conditions
118
115
  @conditions ||= xpath_first_from_signed_assertion('/a:Conditions')
@@ -130,223 +127,43 @@ module OneLogin
130
127
  @issuer ||= begin
131
128
  node = REXML::XPath.first(document, "/p:Response/a:Issuer", { "p" => PROTOCOL, "a" => ASSERTION })
132
129
  node ||= xpath_first_from_signed_assertion('/a:Issuer')
133
- Utils.element_text(node)
134
- end
135
- end
136
-
137
- # Gets the Issuers (from Response and Assertion).
138
- # (returns the first node that matches the supplied xpath from the Response and from the Assertion)
139
- # @return [Array] Array with the Issuers (REXML::Element)
140
- #
141
- def issuers
142
- @issuers ||= begin
143
- issuer_response_nodes = REXML::XPath.match(
144
- document,
145
- "/p:Response/a:Issuer",
146
- { "p" => PROTOCOL, "a" => ASSERTION }
147
- )
148
-
149
- unless issuer_response_nodes.size == 1
150
- error_msg = "Issuer of the Response not found or multiple."
151
- raise ValidationError.new(error_msg)
152
- end
153
-
154
- issuer_assertion_nodes = xpath_from_signed_assertion("/a:Issuer")
155
- unless issuer_assertion_nodes.size == 1
156
- error_msg = "Issuer of the Assertion not found or multiple."
157
- raise ValidationError.new(error_msg)
158
- end
159
-
160
- nodes = issuer_response_nodes + issuer_assertion_nodes
161
- nodes.map { |node| Utils.element_text(node) }.compact.uniq
162
- end
163
- end
164
-
165
- # @return [Array] The Audience elements from the Contitions of the SAML Response.
166
- #
167
- def audiences
168
- @audiences ||= begin
169
- nodes = xpath_from_signed_assertion('/a:Conditions/a:AudienceRestriction/a:Audience')
170
- nodes.map { |node| Utils.element_text(node) }.reject(&:empty?)
130
+ node.nil? ? nil : node.text
171
131
  end
172
132
  end
173
133
 
174
134
  private
175
135
 
176
- def validation_error(message)
177
- raise ValidationError.new(message)
178
- end
179
-
180
136
  def validate(soft = true)
181
- validate_structure(soft) &&
182
- validate_success_status(soft) &&
183
- validate_num_assertion &&
184
- validate_signed_elements(soft) &&
185
- validate_response_state(soft) &&
186
- validate_conditions(soft) &&
187
- validate_audience(soft) &&
188
- validate_issuer(soft) &&
189
- validate_signature(soft) &&
190
- success?
137
+ valid_saml?(document, soft) &&
138
+ validate_response_state(soft) &&
139
+ validate_conditions(soft) &&
140
+ validate_issuer(soft) &&
141
+ document.validate_document(get_fingerprint, soft) &&
142
+ validate_success_status(soft)
191
143
  end
192
144
 
193
- # Validates that the SAML Response only contains a single Assertion (encrypted or not).
194
- # @return [Boolean] True if the SAML Response contains one unique Assertion, otherwise False
195
- #
196
- def validate_num_assertion(soft = true)
197
- assertions = REXML::XPath.match(
198
- document,
199
- "//a:Assertion",
200
- { "a" => ASSERTION }
201
- )
202
- encrypted_assertions = REXML::XPath.match(
203
- document,
204
- "//a:EncryptedAssertion",
205
- { "a" => ASSERTION }
206
- )
207
-
208
- unless assertions.size + encrypted_assertions.size == 1
209
- return soft ? false : validation_error("SAML Response must contain 1 assertion")
210
- end
211
-
212
- true
213
- end
214
-
215
- # Validates the Signed elements
216
- # @return [Boolean] True if there is 1 or 2 Elements signed in the SAML Response
217
- # an are a Response or an Assertion Element, otherwise False if soft=True
218
- #
219
- def validate_signed_elements(soft)
220
- signature_nodes = REXML::XPath.match(
221
- document,
222
- "//ds:Signature",
223
- {"ds"=>DSIG}
224
- )
225
- signed_elements = []
226
- verified_seis = []
227
- verified_ids = []
228
- signature_nodes.each do |signature_node|
229
- signed_element = signature_node.parent.name
230
- if signed_element != 'Response' && signed_element != 'Assertion'
231
- return soft ? false : validation_error("Invalid Signature Element '#{signed_element}'. SAML Response rejected")
232
- end
233
-
234
- if signature_node.parent.attributes['ID'].nil?
235
- return soft ? false : validation_error("Signed Element must contain an ID. SAML Response rejected")
236
- end
237
-
238
- id = signature_node.parent.attributes.get_attribute("ID").value
239
- if verified_ids.include?(id)
240
- return soft ? false : validation_error("Duplicated ID. SAML Response rejected")
241
- end
242
- verified_ids.push(id)
243
-
244
- # Check that reference URI matches the parent ID and no duplicate References or IDs
245
- ref = REXML::XPath.first(signature_node, ".//ds:Reference", {"ds"=>DSIG})
246
- if ref
247
- uri = ref.attributes.get_attribute("URI")
248
- if uri && !uri.value.empty?
249
- sei = uri.value[1..-1]
250
-
251
- unless sei == id
252
- return soft ? false : validation_error("Found an invalid Signed Element. SAML Response rejected")
253
- end
254
-
255
- if verified_seis.include?(sei)
256
- return soft ? false : validation_error("Duplicated Reference URI. SAML Response rejected")
257
- end
258
-
259
- verified_seis.push(sei)
260
- end
261
- end
262
-
263
- signed_elements << signed_element
264
- end
265
-
266
- unless signature_nodes.length < 3 && !signed_elements.empty?
267
- return soft ? false : validation_error("Found an unexpected number of Signature Element. SAML Response rejected")
268
- end
269
-
270
- true
271
- end
272
-
273
- # Validates the Status of the SAML Response
274
- # @return [Boolean] True if the SAML Response contains a Success code, otherwise False if soft == false
275
- # @raise [ValidationError] if soft == false and validation fails
276
- #
277
145
  def validate_success_status(soft = true)
278
- return true if success?
279
-
280
- return false unless soft
281
-
282
- error_msg = 'The status code of the Response was not Success'
283
- status_error_msg = OneLogin::RubySaml::Utils.status_error_msg(error_msg, status_code, status_message)
284
- return validation_error(status_error_msg)
285
- end
286
-
287
- # Checks if the Status has the "Success" code
288
- # @return [Boolean] True if the StatusCode is Sucess
289
- #
290
- def success?
291
- status_code == "urn:oasis:names:tc:SAML:2.0:status:Success"
292
- end
293
-
294
- # @return [String] StatusCode value from a SAML Response.
295
- #
296
- def status_code
297
- @status_code ||= begin
298
- nodes = REXML::XPath.match(
299
- document,
300
- "/p:Response/p:Status/p:StatusCode",
301
- { "p" => PROTOCOL }
302
- )
303
- if nodes.size == 1
304
- node = nodes[0]
305
- code = node.attributes["Value"] if node && node.attributes
306
-
307
- unless code == "urn:oasis:names:tc:SAML:2.0:status:Success"
308
- nodes = REXML::XPath.match(
309
- document,
310
- "/p:Response/p:Status/p:StatusCode/p:StatusCode",
311
- { "p" => PROTOCOL }
312
- )
313
- statuses = nodes.collect do |inner_node|
314
- inner_node.attributes["Value"]
315
- end
316
- extra_code = statuses.join(" | ")
317
- if extra_code
318
- code = "#{code} | #{extra_code}"
319
- end
320
- end
321
- code
322
- end
323
- end
324
- end
325
-
326
- # @return [String] the StatusMessage value from a SAML Response.
327
- #
328
- def status_message
329
- @status_message ||= begin
330
- nodes = REXML::XPath.match(
331
- document,
332
- "/p:Response/p:Status/p:StatusMessage",
333
- { "p" => PROTOCOL }
334
- )
335
- if nodes.size == 1
336
- Utils.element_text(nodes.first)
337
- end
146
+ if success?
147
+ true
148
+ else
149
+ soft ? false : validation_error(status_message)
338
150
  end
339
151
  end
340
152
 
341
153
  def validate_structure(soft = true)
342
154
  Dir.chdir(File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'schemas'))) do
343
- @schema = Nokogiri::XML::Schema(IO.read('saml20protocol_schema.xsd'))
155
+ @schema = Nokogiri::XML::Schema(IO.read('saml-schema-protocol-2.0.xsd'))
344
156
  @xml = Nokogiri::XML(self.document.to_s)
345
157
  end
346
158
  if soft
347
- @schema.validate(@xml).map{ return false }
159
+ @schema.validate(@xml).map{
160
+ @errors << "Schema validation failed";
161
+ return false
162
+ }
348
163
  else
349
- @schema.validate(@xml).map{ |error| validation_error("#{error.message}\n\n#{@xml.to_s}") }
164
+ @schema.validate(@xml).map{ |error| @errors << "#{error.message}\n\n#{@xml.to_s}";
165
+ validation_error("#{error.message}\n\n#{@xml.to_s}")
166
+ }
350
167
  end
351
168
  end
352
169
 
@@ -382,24 +199,13 @@ module OneLogin
382
199
  node
383
200
  end
384
201
 
385
- # Extracts all the appearances that matchs the subelt (pattern)
386
- # Search on any Assertion that is signed, or has a Response parent signed
387
- # @param subelt [String] The XPath pattern
388
- # @return [Array of REXML::Element] Return all matches
389
- #
390
- def xpath_from_signed_assertion(subelt=nil)
391
- node = REXML::XPath.match(
392
- document,
393
- "/p:Response/a:Assertion[@ID=$id]#{subelt}",
394
- { "p" => PROTOCOL, "a" => ASSERTION },
395
- { 'id' => document.signed_element_id }
396
- )
397
- node.concat( REXML::XPath.match(
398
- document,
399
- "/p:Response[@ID=$id]/a:Assertion#{subelt}",
400
- { "p" => PROTOCOL, "a" => ASSERTION },
401
- { 'id' => document.signed_element_id }
402
- ))
202
+ def get_fingerprint
203
+ if settings.idp_cert
204
+ cert = OpenSSL::X509::Certificate.new(settings.idp_cert)
205
+ Digest::SHA1.hexdigest(cert.to_der).upcase.scan(/../).join(":")
206
+ else
207
+ settings.idp_cert_fingerprint
208
+ end
403
209
  end
404
210
 
405
211
  def validate_conditions(soft = true)
@@ -409,10 +215,12 @@ module OneLogin
409
215
  now = Time.now.utc
410
216
 
411
217
  if not_before && (now + (options[:allowed_clock_drift] || 0)) < not_before
218
+ @errors << "Current time is earlier than NotBefore condition #{(now + (options[:allowed_clock_drift] || 0))} < #{not_before})"
412
219
  return soft ? false : validation_error("Current time is earlier than NotBefore condition")
413
220
  end
414
221
 
415
222
  if not_on_or_after && now >= not_on_or_after
223
+ @errors << "Current time is on or after NotOnOrAfter condition (#{now} >= #{not_on_or_after})"
416
224
  return soft ? false : validation_error("Current time is on or after NotOnOrAfter condition")
417
225
  end
418
226
 
@@ -422,64 +230,9 @@ module OneLogin
422
230
  def validate_issuer(soft = true)
423
231
  return true if settings.idp_entity_id.nil?
424
232
 
425
- begin
426
- obtained_issuers = issuers
427
- rescue ValidationError => e
428
- return soft ? false : validation_error("Error while extracting issuers")
429
- end
430
-
431
- obtained_issuers.each do |issuer|
432
- unless OneLogin::RubySaml::Utils.uri_match?(issuer, settings.idp_entity_id)
433
- error_msg = "Doesn't match the issuer, expected: <#{settings.idp_entity_id}>, but was: <#{issuer}>"
434
- return soft ? false : validation_error(error_msg)
435
- end
233
+ unless URI.parse(issuer) == URI.parse(settings.idp_entity_id)
234
+ return soft ? false : validation_error("Doesn't match the issuer, expected: <#{settings.idp_entity_id}>, but was: <#{issuer}>")
436
235
  end
437
-
438
- true
439
- end
440
-
441
- def validate_signature(soft = true)
442
- error_msg = "Invalid Signature on SAML Response"
443
-
444
- sig_elements = REXML::XPath.match(
445
- document,
446
- "/p:Response[@ID=$id]/ds:Signature]",
447
- { "p" => PROTOCOL, "ds" => DSIG },
448
- { 'id' => document.signed_element_id }
449
- )
450
-
451
- # Check signature nodes
452
- if sig_elements.nil? || sig_elements.size == 0
453
- sig_elements = REXML::XPath.match(
454
- document,
455
- "/p:Response/a:Assertion[@ID=$id]/ds:Signature",
456
- {"p" => PROTOCOL, "a" => ASSERTION, "ds"=>DSIG},
457
- { 'id' => document.signed_element_id }
458
- )
459
- end
460
-
461
- if sig_elements.size != 1
462
- if sig_elements.size == 0
463
- error_msg += ". Signed element id ##{doc.signed_element_id} is not found"
464
- else
465
- error_msg += ". Signed element id ##{doc.signed_element_id} is found more than once"
466
- end
467
- return soft ? false : validation_error(error_msg)
468
- end
469
-
470
- opts = {}
471
- opts[:fingerprint_alg] = OpenSSL::Digest::SHA1.new
472
- opts[:cert] = settings.get_idp_cert
473
- fingerprint = settings.get_fingerprint
474
-
475
- unless fingerprint
476
- return soft ? false : validation_error("No fingerprint or certificate on settings")
477
- end
478
-
479
- unless document.validate_document(fingerprint, soft, opts)
480
- return soft ? false : validation_error(error_msg)
481
- end
482
-
483
236
  true
484
237
  end
485
238
 
@@ -488,19 +241,6 @@ module OneLogin
488
241
  Time.parse(node.attributes[attribute])
489
242
  end
490
243
  end
491
-
492
- def validate_audience(soft = true)
493
- return true if audiences.empty? || settings.sp_entity_id.nil? || settings.sp_entity_id.empty?
494
-
495
- unless audiences.include? settings.sp_entity_id
496
- s = audiences.count > 1 ? 's' : '';
497
- error_msg = "Invalid Audience#{s}. The audience#{s} #{audiences.join(',')}, did not match the expected audience #{settings.sp_entity_id}"
498
- return soft ? false : validation_error(error_msg)
499
- end
500
-
501
- true
502
- end
503
-
504
244
  end
505
245
  end
506
246
  end