ruby-saml 1.11.0 → 1.12.1

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.

Files changed (158) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +14 -12
  3. data/README.md +76 -22
  4. data/changelog.md +27 -0
  5. data/lib/onelogin/ruby-saml/attributes.rb +24 -1
  6. data/lib/onelogin/ruby-saml/authrequest.rb +9 -4
  7. data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +62 -24
  8. data/lib/onelogin/ruby-saml/logoutrequest.rb +7 -1
  9. data/lib/onelogin/ruby-saml/logoutresponse.rb +4 -0
  10. data/lib/onelogin/ruby-saml/metadata.rb +9 -1
  11. data/lib/onelogin/ruby-saml/response.rb +38 -16
  12. data/lib/onelogin/ruby-saml/saml_message.rb +6 -0
  13. data/lib/onelogin/ruby-saml/setting_error.rb +6 -0
  14. data/lib/onelogin/ruby-saml/settings.rb +34 -2
  15. data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +4 -0
  16. data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +27 -14
  17. data/lib/onelogin/ruby-saml/utils.rb +56 -0
  18. data/lib/onelogin/ruby-saml/version.rb +1 -1
  19. data/lib/xml_security.rb +34 -6
  20. data/ruby-saml.gemspec +8 -4
  21. metadata +22 -282
  22. data/test/certificates/certificate.der +0 -0
  23. data/test/certificates/certificate1 +0 -12
  24. data/test/certificates/certificate_without_head_foot +0 -1
  25. data/test/certificates/formatted_certificate +0 -14
  26. data/test/certificates/formatted_chained_certificate +0 -42
  27. data/test/certificates/formatted_private_key +0 -12
  28. data/test/certificates/formatted_rsa_private_key +0 -12
  29. data/test/certificates/invalid_certificate1 +0 -1
  30. data/test/certificates/invalid_certificate2 +0 -1
  31. data/test/certificates/invalid_certificate3 +0 -12
  32. data/test/certificates/invalid_chained_certificate1 +0 -1
  33. data/test/certificates/invalid_private_key1 +0 -1
  34. data/test/certificates/invalid_private_key2 +0 -1
  35. data/test/certificates/invalid_private_key3 +0 -10
  36. data/test/certificates/invalid_rsa_private_key1 +0 -1
  37. data/test/certificates/invalid_rsa_private_key2 +0 -1
  38. data/test/certificates/invalid_rsa_private_key3 +0 -10
  39. data/test/certificates/ruby-saml-2.crt +0 -15
  40. data/test/certificates/ruby-saml.crt +0 -14
  41. data/test/certificates/ruby-saml.key +0 -15
  42. data/test/idp_metadata_parser_test.rb +0 -594
  43. data/test/logging_test.rb +0 -62
  44. data/test/logout_requests/invalid_slo_request.xml +0 -6
  45. data/test/logout_requests/slo_request.xml +0 -4
  46. data/test/logout_requests/slo_request.xml.base64 +0 -1
  47. data/test/logout_requests/slo_request_deflated.xml.base64 +0 -1
  48. data/test/logout_requests/slo_request_with_name_id_format.xml +0 -4
  49. data/test/logout_requests/slo_request_with_session_index.xml +0 -5
  50. data/test/logout_responses/logoutresponse_fixtures.rb +0 -86
  51. data/test/logoutrequest_test.rb +0 -260
  52. data/test/logoutresponse_test.rb +0 -427
  53. data/test/metadata/idp_descriptor.xml +0 -26
  54. data/test/metadata/idp_descriptor_2.xml +0 -56
  55. data/test/metadata/idp_descriptor_3.xml +0 -14
  56. data/test/metadata/idp_descriptor_4.xml +0 -72
  57. data/test/metadata/idp_metadata_different_sign_and_encrypt_cert.xml +0 -72
  58. data/test/metadata/idp_metadata_multi_certs.xml +0 -75
  59. data/test/metadata/idp_metadata_multi_signing_certs.xml +0 -52
  60. data/test/metadata/idp_metadata_same_sign_and_encrypt_cert.xml +0 -71
  61. data/test/metadata/idp_multiple_descriptors.xml +0 -59
  62. data/test/metadata/idp_multiple_descriptors_2.xml +0 -59
  63. data/test/metadata/no_idp_descriptor.xml +0 -21
  64. data/test/metadata_test.rb +0 -331
  65. data/test/request_test.rb +0 -340
  66. data/test/response_test.rb +0 -1629
  67. data/test/responses/adfs_response_sha1.xml +0 -46
  68. data/test/responses/adfs_response_sha256.xml +0 -46
  69. data/test/responses/adfs_response_sha384.xml +0 -46
  70. data/test/responses/adfs_response_sha512.xml +0 -46
  71. data/test/responses/adfs_response_xmlns.xml +0 -45
  72. data/test/responses/attackxee.xml +0 -13
  73. data/test/responses/invalids/duplicated_attributes.xml.base64 +0 -1
  74. data/test/responses/invalids/empty_destination.xml.base64 +0 -1
  75. data/test/responses/invalids/empty_nameid.xml.base64 +0 -1
  76. data/test/responses/invalids/encrypted_new_attack.xml.base64 +0 -1
  77. data/test/responses/invalids/invalid_audience.xml.base64 +0 -1
  78. data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +0 -1
  79. data/test/responses/invalids/invalid_issuer_message.xml.base64 +0 -1
  80. data/test/responses/invalids/invalid_signature_position.xml.base64 +0 -1
  81. data/test/responses/invalids/invalid_subjectconfirmation_inresponse.xml.base64 +0 -1
  82. data/test/responses/invalids/invalid_subjectconfirmation_nb.xml.base64 +0 -1
  83. data/test/responses/invalids/invalid_subjectconfirmation_noa.xml.base64 +0 -1
  84. data/test/responses/invalids/invalid_subjectconfirmation_recipient.xml.base64 +0 -1
  85. data/test/responses/invalids/multiple_assertions.xml.base64 +0 -2
  86. data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
  87. data/test/responses/invalids/no_authnstatement.xml.base64 +0 -1
  88. data/test/responses/invalids/no_conditions.xml.base64 +0 -1
  89. data/test/responses/invalids/no_id.xml.base64 +0 -1
  90. data/test/responses/invalids/no_issuer_assertion.xml.base64 +0 -1
  91. data/test/responses/invalids/no_issuer_response.xml.base64 +0 -1
  92. data/test/responses/invalids/no_nameid.xml.base64 +0 -1
  93. data/test/responses/invalids/no_saml2.xml.base64 +0 -1
  94. data/test/responses/invalids/no_signature.xml.base64 +0 -1
  95. data/test/responses/invalids/no_status.xml.base64 +0 -1
  96. data/test/responses/invalids/no_status_code.xml.base64 +0 -1
  97. data/test/responses/invalids/no_subjectconfirmation_data.xml.base64 +0 -1
  98. data/test/responses/invalids/no_subjectconfirmation_method.xml.base64 +0 -1
  99. data/test/responses/invalids/response_invalid_signed_element.xml.base64 +0 -1
  100. data/test/responses/invalids/response_with_concealed_signed_assertion.xml +0 -51
  101. data/test/responses/invalids/response_with_doubled_signed_assertion.xml +0 -49
  102. data/test/responses/invalids/signature_wrapping_attack.xml.base64 +0 -1
  103. data/test/responses/invalids/status_code_responder.xml.base64 +0 -1
  104. data/test/responses/invalids/status_code_responer_and_msg.xml.base64 +0 -1
  105. data/test/responses/invalids/wrong_spnamequalifier.xml.base64 +0 -1
  106. data/test/responses/no_signature_ns.xml +0 -48
  107. data/test/responses/open_saml_response.xml +0 -56
  108. data/test/responses/response_assertion_wrapped.xml.base64 +0 -93
  109. data/test/responses/response_audience_self_closed_tag.xml.base64 +0 -1
  110. data/test/responses/response_double_status_code.xml.base64 +0 -1
  111. data/test/responses/response_encrypted_attrs.xml.base64 +0 -1
  112. data/test/responses/response_encrypted_nameid.xml.base64 +0 -1
  113. data/test/responses/response_eval.xml +0 -7
  114. data/test/responses/response_no_cert_and_encrypted_attrs.xml +0 -29
  115. data/test/responses/response_node_text_attack.xml.base64 +0 -1
  116. data/test/responses/response_node_text_attack2.xml.base64 +0 -1
  117. data/test/responses/response_node_text_attack3.xml.base64 +0 -1
  118. data/test/responses/response_unsigned_xml_base64 +0 -1
  119. data/test/responses/response_with_ampersands.xml +0 -139
  120. data/test/responses/response_with_ampersands.xml.base64 +0 -93
  121. data/test/responses/response_with_ds_namespace_at_the_root.xml.base64 +0 -1
  122. data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
  123. data/test/responses/response_with_multiple_attribute_values.xml +0 -67
  124. data/test/responses/response_with_retrieval_method.xml +0 -26
  125. data/test/responses/response_with_saml2_namespace.xml.base64 +0 -102
  126. data/test/responses/response_with_signed_assertion.xml.base64 +0 -66
  127. data/test/responses/response_with_signed_assertion_2.xml.base64 +0 -1
  128. data/test/responses/response_with_signed_assertion_3.xml +0 -30
  129. data/test/responses/response_with_signed_message_and_assertion.xml +0 -34
  130. data/test/responses/response_with_undefined_recipient.xml.base64 +0 -1
  131. data/test/responses/response_without_attributes.xml.base64 +0 -79
  132. data/test/responses/response_without_reference_uri.xml.base64 +0 -1
  133. data/test/responses/response_wrapped.xml.base64 +0 -150
  134. data/test/responses/signed_message_encrypted_signed_assertion.xml.base64 +0 -1
  135. data/test/responses/signed_message_encrypted_unsigned_assertion.xml.base64 +0 -1
  136. data/test/responses/signed_nameid_in_atts.xml +0 -47
  137. data/test/responses/signed_unqual_nameid_in_atts.xml +0 -47
  138. data/test/responses/simple_saml_php.xml +0 -71
  139. data/test/responses/starfield_response.xml.base64 +0 -1
  140. data/test/responses/test_sign.xml +0 -43
  141. data/test/responses/unsigned_encrypted_adfs.xml +0 -23
  142. data/test/responses/unsigned_message_aes128_encrypted_signed_assertion.xml.base64 +0 -1
  143. data/test/responses/unsigned_message_aes192_encrypted_signed_assertion.xml.base64 +0 -1
  144. data/test/responses/unsigned_message_aes256_encrypted_signed_assertion.xml.base64 +0 -1
  145. data/test/responses/unsigned_message_des192_encrypted_signed_assertion.xml.base64 +0 -1
  146. data/test/responses/unsigned_message_encrypted_assertion_without_saml_namespace.xml.base64 +0 -1
  147. data/test/responses/unsigned_message_encrypted_signed_assertion.xml.base64 +0 -1
  148. data/test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64 +0 -1
  149. data/test/responses/valid_response.xml.base64 +0 -1
  150. data/test/responses/valid_response_with_formatted_x509certificate.xml.base64 +0 -1
  151. data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
  152. data/test/saml_message_test.rb +0 -56
  153. data/test/settings_test.rb +0 -338
  154. data/test/slo_logoutrequest_test.rb +0 -467
  155. data/test/slo_logoutresponse_test.rb +0 -233
  156. data/test/test_helper.rb +0 -333
  157. data/test/utils_test.rb +0 -259
  158. data/test/xml_security_test.rb +0 -421
@@ -1,467 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
- require 'logout_responses/logoutresponse_fixtures'
3
-
4
- require 'onelogin/ruby-saml/slo_logoutrequest'
5
- require 'timecop'
6
-
7
- class RubySamlTest < Minitest::Test
8
-
9
- describe "SloLogoutrequest" do
10
-
11
- let(:settings) { OneLogin::RubySaml::Settings.new }
12
- let(:logout_request) { OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document) }
13
- let(:invalid_logout_request) { OneLogin::RubySaml::SloLogoutrequest.new(invalid_logout_request_document) }
14
-
15
- before do
16
- settings.idp_entity_id = 'https://app.onelogin.com/saml/metadata/SOMEACCOUNT'
17
- settings.soft = true
18
- logout_request.settings = settings
19
- invalid_logout_request.settings = settings
20
- end
21
-
22
- describe "initiator" do
23
- it "raise an exception when logout request is initialized with nil" do
24
- assert_raises(ArgumentError) { OneLogin::RubySaml::SloLogoutrequest.new(nil) }
25
- end
26
- end
27
-
28
- describe "#is_valid?" do
29
- it "return false when logout request is initialized with blank data" do
30
- logout_request_blank = OneLogin::RubySaml::SloLogoutrequest.new('')
31
- assert !logout_request_blank.is_valid?
32
- assert_includes logout_request_blank.errors, 'Blank logout request'
33
- end
34
-
35
- it "return true when the logout request is initialized with valid data" do
36
- assert logout_request.is_valid?
37
- assert_empty logout_request.errors
38
- assert_equal 'someone@example.org', logout_request.nameid
39
- end
40
-
41
- it "should be idempotent when the logout request is initialized with invalid data" do
42
- assert !invalid_logout_request.is_valid?
43
- assert_equal ['Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd'], invalid_logout_request.errors
44
- assert !invalid_logout_request.is_valid?
45
- assert_equal ['Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd'], invalid_logout_request.errors
46
- end
47
-
48
- it "should be idempotent when the logout request is initialized with valid data" do
49
- assert logout_request.is_valid?
50
- assert_empty logout_request.errors
51
- assert logout_request.is_valid?
52
- assert_empty logout_request.errors
53
- end
54
-
55
- it "collect errors when collect_errors=true" do
56
- settings.idp_entity_id = 'http://idp.example.com/invalid'
57
- settings.idp_slo_target_url = "http://example.com?field=value"
58
- settings.security[:logout_requests_signed] = true
59
- settings.security[:embed_sign] = false
60
- settings.certificate = ruby_saml_cert_text
61
- settings.private_key = ruby_saml_key_text
62
- settings.idp_cert = ruby_saml_cert_text
63
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
64
- params = {}
65
- params['SAMLRequest'] = logout_request_deflated_base64
66
- params['RelayState'] = 'http://invalid.example.com'
67
- params['Signature'] = 'invalid_signature'
68
- params['SigAlg'] = XMLSecurity::Document::RSA_SHA1
69
- options = {}
70
- options[:get_params] = params
71
-
72
- logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
73
- logout_request_sign_test.settings = settings
74
-
75
- collect_errors = true
76
- assert !logout_request_sign_test.is_valid?(collect_errors)
77
- assert_includes logout_request_sign_test.errors, "Invalid Signature on Logout Request"
78
- assert_includes logout_request_sign_test.errors, "Doesn't match the issuer, expected: <http://idp.example.com/invalid>, but was: <https://app.onelogin.com/saml/metadata/SOMEACCOUNT>"
79
- end
80
-
81
- it "raise error for invalid xml" do
82
- invalid_logout_request.soft = false
83
- assert_raises(OneLogin::RubySaml::ValidationError) { invalid_logout_request.is_valid? }
84
- end
85
-
86
- end
87
-
88
- describe "#nameid" do
89
- it "extract the value of the name id element" do
90
- assert_equal "someone@example.org", logout_request.nameid
91
- end
92
- end
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
-
102
- describe "#issuer" do
103
- it "return the issuer inside the logout request" do
104
- assert_equal "https://app.onelogin.com/saml/metadata/SOMEACCOUNT", logout_request.issuer
105
- end
106
- end
107
-
108
- describe "#id" do
109
- it "extract the value of the ID attribute" do
110
- assert_equal "_c0348950-935b-0131-1060-782bcb56fcaa", logout_request.id
111
- end
112
- end
113
-
114
- describe "#not_on_or_after" do
115
- it "extract the value of the NotOnOrAfter attribute" do
116
- time_value = '2014-07-17T01:01:48Z'
117
- assert_nil logout_request.not_on_or_after
118
- logout_request.document.root.attributes['NotOnOrAfter'] = time_value
119
- assert_equal Time.parse(time_value), logout_request.not_on_or_after
120
- end
121
- end
122
-
123
- describe '#session_indexes' do
124
- it "return empty array when no SessionIndex" do
125
- assert_equal [], logout_request.session_indexes
126
- end
127
-
128
- it "return an Array with one SessionIndex" do
129
- logout_request_with_session_index = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_xml_with_session_index)
130
- assert_equal ['_ea853497-c58a-408a-bc23-c849752d9741'], logout_request_with_session_index.session_indexes
131
- end
132
- end
133
-
134
- describe "#validate_id" do
135
- it "return true when there is a valid ID in the logout request" do
136
- assert logout_request.send(:validate_id)
137
- assert_empty logout_request.errors
138
- end
139
-
140
- it "return false when there is an invalid ID in the logout request" do
141
- logout_request_blank = OneLogin::RubySaml::SloLogoutrequest.new('')
142
- assert !logout_request_blank.send(:validate_id)
143
- assert_includes logout_request_blank.errors, "Missing ID attribute on Logout Request"
144
- end
145
- end
146
-
147
- describe "#validate_version" do
148
- it "return true when the logout request is SAML 2.0 Version" do
149
- assert logout_request.send(:validate_version)
150
- end
151
-
152
- it "return false when the logout request is not SAML 2.0 Version" do
153
- logout_request_blank = OneLogin::RubySaml::SloLogoutrequest.new('')
154
- assert !logout_request_blank.send(:validate_version)
155
- assert_includes logout_request_blank.errors, "Unsupported SAML version"
156
- end
157
- end
158
-
159
- describe "#validate_not_on_or_after" do
160
- it "return true when the logout request has a valid NotOnOrAfter or does not contain any" do
161
- assert logout_request.send(:validate_not_on_or_after)
162
- assert_empty logout_request.errors
163
- Timecop.freeze Time.parse('2011-06-14T18:25:01.516Z') do
164
- time_value = '2014-07-17T01:01:48Z'
165
- logout_request.document.root.attributes['NotOnOrAfter'] = time_value
166
- assert logout_request.send(:validate_not_on_or_after)
167
- assert_empty logout_request.errors
168
- end
169
- end
170
-
171
- it "return false when the logout request has an invalid NotOnOrAfter" do
172
- logout_request.document.root.attributes['NotOnOrAfter'] = '2014-07-17T01:01:48Z'
173
- assert !logout_request.send(:validate_not_on_or_after)
174
- assert /Current time is on or after NotOnOrAfter/.match(logout_request.errors[0])
175
- end
176
-
177
- it "raise when the logout request has an invalid NotOnOrAfter" do
178
- logout_request.document.root.attributes['NotOnOrAfter'] = '2014-07-17T01:01:48Z'
179
- logout_request.soft = false
180
- assert_raises(OneLogin::RubySaml::ValidationError, "Current time is on or after NotOnOrAfter") do
181
- logout_request.send(:validate_not_on_or_after)
182
- end
183
- end
184
- end
185
-
186
- describe "#validate_request_state" do
187
- it "return true when valid logout request xml" do
188
- assert logout_request.send(:validate_request_state)
189
- assert_empty logout_request.errors
190
- assert logout_request.send(:validate_request_state)
191
- assert_empty logout_request.errors
192
- end
193
-
194
- it "return false when invalid logout request xml" do
195
- logout_request_blank = OneLogin::RubySaml::SloLogoutrequest.new('')
196
- logout_request_blank.soft = true
197
- assert !logout_request_blank.send(:validate_request_state)
198
- assert_includes logout_request_blank.errors, "Blank logout request"
199
- end
200
-
201
- it "raise error for invalid xml" do
202
- logout_request_blank = OneLogin::RubySaml::SloLogoutrequest.new('')
203
- logout_request_blank.soft = false
204
- assert_raises(OneLogin::RubySaml::ValidationError, "Blank logout request") do
205
- logout_request_blank.send(:validate_request_state)
206
- end
207
- end
208
- end
209
-
210
- describe "#validate_structure" do
211
- it "return true when encountering a valid Logout Request xml" do
212
- assert logout_request.send(:validate_structure)
213
- assert_empty logout_request.errors
214
- end
215
-
216
- it "return false when encountering a Logout Request bad formatted" do
217
- assert !invalid_logout_request.send(:validate_structure)
218
- assert_includes invalid_logout_request.errors, "Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd"
219
- end
220
-
221
- it "raise when encountering a Logout Request bad formatted" do
222
- invalid_logout_request.soft = false
223
- assert_raises(OneLogin::RubySaml::ValidationError, "Element '{urn:oasis:names:tc:SAML:2.0:assertion}Issuer': This element is not expected") do
224
- invalid_logout_request.send(:validate_structure)
225
- end
226
- end
227
- end
228
-
229
- describe "#validate_issuer" do
230
- it "return true when the issuer of the Logout Request matchs the IdP entityId" do
231
- logout_request.settings.idp_entity_id = 'https://app.onelogin.com/saml/metadata/SOMEACCOUNT'
232
- assert logout_request.send(:validate_issuer)
233
- end
234
- it "return false when the issuer of the Logout Request does not match the IdP entityId" do
235
- logout_request.settings.idp_entity_id = 'http://idp.example.com/invalid'
236
- assert !logout_request.send(:validate_issuer)
237
- assert_includes logout_request.errors, "Doesn't match the issuer, expected: <#{logout_request.settings.idp_entity_id}>, but was: <https://app.onelogin.com/saml/metadata/SOMEACCOUNT>"
238
- end
239
- it "raise when the issuer of the Logout Request does not match the IdP entityId" do
240
- logout_request.settings.idp_entity_id = 'http://idp.example.com/invalid'
241
- logout_request.soft = false
242
- assert_raises(OneLogin::RubySaml::ValidationError, "Doesn't match the issuer, expected: <#{logout_request.settings.idp_entity_id}>, but was: <https://app.onelogin.com/saml/metadata/SOMEACCOUNT>") do
243
- logout_request.send(:validate_issuer)
244
- end
245
- end
246
- end
247
-
248
- describe "#validate_signature" do
249
- before do
250
- settings.idp_slo_target_url = "http://example.com?field=value"
251
- settings.security[:logout_requests_signed] = true
252
- settings.security[:embed_sign] = false
253
- settings.certificate = ruby_saml_cert_text
254
- settings.private_key = ruby_saml_key_text
255
- settings.idp_cert = ruby_saml_cert_text
256
- end
257
-
258
- it "return true when no idp_cert is provided and option :relax_signature_validation is present" do
259
- settings.idp_cert = nil
260
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
261
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
262
- params['RelayState'] = params[:RelayState]
263
- options = {}
264
- options[:get_params] = params
265
- options[:relax_signature_validation] = true
266
- logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
267
- logout_request_sign_test.settings = settings
268
- assert logout_request_sign_test.send(:validate_signature)
269
- end
270
-
271
- it "return false when no idp_cert is provided and no option :relax_signature_validation is present" do
272
- settings.idp_cert = nil
273
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
274
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
275
- params['RelayState'] = params[:RelayState]
276
- options = {}
277
- options[:get_params] = params
278
- logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
279
- logout_request_sign_test.settings = settings
280
- assert !logout_request_sign_test.send(:validate_signature)
281
- end
282
-
283
- it "return true when valid RSA_SHA1 Signature" do
284
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
285
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
286
- params['RelayState'] = params[:RelayState]
287
- options = {}
288
- options[:get_params] = params
289
- logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
290
- logout_request_sign_test.settings = settings
291
- assert logout_request_sign_test.send(:validate_signature)
292
- end
293
-
294
- it "return true when valid RSA_SHA256 Signature" do
295
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
296
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
297
- options = {}
298
- options[:get_params] = params
299
- logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
300
- params['RelayState'] = params[:RelayState]
301
- logout_request_sign_test.settings = settings
302
- assert logout_request_sign_test.send(:validate_signature)
303
- end
304
-
305
- it "return false when invalid RSA_SHA1 Signature" do
306
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
307
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
308
- params['RelayState'] = 'http://invalid.example.com'
309
- params[:RelayState] = params['RelayState']
310
- options = {}
311
- options[:get_params] = params
312
-
313
- logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
314
- logout_request_sign_test.settings = settings
315
- assert !logout_request_sign_test.send(:validate_signature)
316
- end
317
-
318
- it "raise when invalid RSA_SHA1 Signature" do
319
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
320
- settings.soft = false
321
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
322
- params['RelayState'] = 'http://invalid.example.com'
323
- params[:RelayState] = params['RelayState']
324
- options = {}
325
- options[:get_params] = params
326
- options[:settings] = settings
327
-
328
- logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
329
- assert_raises(OneLogin::RubySaml::ValidationError, "Invalid Signature on Logout Request") do
330
- logout_request_sign_test.send(:validate_signature)
331
- end
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
405
- end
406
-
407
- describe "#validate_signature with multiple idp certs" do
408
- before do
409
- settings.idp_slo_target_url = "http://example.com?field=value"
410
- settings.certificate = ruby_saml_cert_text
411
- settings.private_key = ruby_saml_key_text
412
- settings.idp_cert = nil
413
- settings.security[:logout_requests_signed] = true
414
- settings.security[:embed_sign] = false
415
- settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
416
- end
417
-
418
- it "return true when at least a idp_cert is valid" do
419
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
420
- params['RelayState'] = params[:RelayState]
421
- options = {}
422
- options[:get_params] = params
423
- logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
424
- settings.idp_cert_multi = {
425
- :signing => [ruby_saml_cert_text2, ruby_saml_cert_text],
426
- :encryption => []
427
- }
428
- logout_request_sign_test.settings = settings
429
- assert logout_request_sign_test.send(:validate_signature)
430
- end
431
-
432
- it "return false when cert expired and check_idp_cert_expiration expired" do
433
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
434
- params['RelayState'] = params[:RelayState]
435
- options = {}
436
- options[:get_params] = params
437
- settings.security[:check_idp_cert_expiration] = true
438
- logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
439
- settings.idp_cert = nil
440
- settings.idp_cert_multi = {
441
- :signing => [ruby_saml_cert_text],
442
- :encryption => []
443
- }
444
- logout_request_sign_test.settings = settings
445
- assert !logout_request_sign_test.send(:validate_signature)
446
- assert_includes logout_request_sign_test.errors, "IdP x509 certificate expired"
447
- end
448
-
449
- it "return false when none cert on idp_cert_multi is valid" do
450
- params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
451
- params['RelayState'] = params[:RelayState]
452
- options = {}
453
- options[:get_params] = params
454
- logout_request_sign_test = OneLogin::RubySaml::SloLogoutrequest.new(params['SAMLRequest'], options)
455
- settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
456
- settings.idp_cert_multi = {
457
- :signing => [ruby_saml_cert_text2, ruby_saml_cert_text2],
458
- :encryption => []
459
- }
460
- logout_request_sign_test.settings = settings
461
- assert !logout_request_sign_test.send(:validate_signature)
462
- assert_includes logout_request_sign_test.errors, "Invalid Signature on Logout Request"
463
-
464
- end
465
- end
466
- end
467
- end