ruby-saml 0.8.15 → 0.8.16

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/onelogin/ruby-saml/logoutresponse.rb +8 -27
  3. data/lib/onelogin/ruby-saml/response.rb +48 -0
  4. data/lib/onelogin/ruby-saml/settings.rb +1 -10
  5. data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +101 -0
  6. data/lib/onelogin/ruby-saml/utils.rb +27 -0
  7. data/lib/onelogin/ruby-saml/version.rb +1 -1
  8. data/lib/ruby-saml.rb +1 -0
  9. data/test/certificates/certificate.der +0 -0
  10. data/test/certificates/formatted_certificate +14 -0
  11. data/test/certificates/formatted_chained_certificate +42 -0
  12. data/test/certificates/formatted_private_key +12 -0
  13. data/test/certificates/formatted_rsa_private_key +12 -0
  14. data/test/certificates/invalid_certificate1 +1 -0
  15. data/test/certificates/invalid_certificate2 +1 -0
  16. data/test/certificates/invalid_certificate3 +12 -0
  17. data/test/certificates/invalid_chained_certificate1 +1 -0
  18. data/test/certificates/invalid_private_key1 +1 -0
  19. data/test/certificates/invalid_private_key2 +1 -0
  20. data/test/certificates/invalid_private_key3 +10 -0
  21. data/test/certificates/invalid_rsa_private_key1 +1 -0
  22. data/test/certificates/invalid_rsa_private_key2 +1 -0
  23. data/test/certificates/invalid_rsa_private_key3 +10 -0
  24. data/test/logoutresponse_test.rb +2 -16
  25. data/test/requests/logoutrequest_fixtures.rb +47 -0
  26. data/test/response_test.rb +25 -0
  27. data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +1 -0
  28. data/test/responses/invalids/invalid_issuer_message.xml.base64 +1 -0
  29. data/test/responses/logoutresponse_fixtures.rb +4 -4
  30. data/test/settings_test.rb +106 -0
  31. data/test/slo_logoutrequest_test.rb +66 -0
  32. data/test/utils_test.rb +191 -1
  33. metadata +41 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3039afb4b2668c3859e51ae9eff0c1b423d7dda319a7d646b26702de315047af
4
- data.tar.gz: 2ef188024bd8030c659b499db22b3b28f2ae24930954f8c45cc69c175b8fc4e3
3
+ metadata.gz: 68cb87ca6e3a580cea96b7784b71f60afe0f0982fc9b3c7b2de4fdda0ea1af31
4
+ data.tar.gz: 216f43c0d0a179f3a9c506f198c31e2a01a08a8661bfaafbe3cb50811b1acf88
5
5
  SHA512:
6
- metadata.gz: 0ab896476c0de2ebcd71b060dc305d091e3b6c3be7abd81ce702389cb8e8409cbd5730a4a73a71dfdfedbeb7a0081f448ed4aec60737a8ce6c1b6fb966ce9c4f
7
- data.tar.gz: 203b1fd9b1fa4d23ab66cac8a034d3154a48e243bff21040ae2e873d191e90c0d8b8ccdfee368ca542c306fd58ddcdbeec700047893ae6044b82b406af43de18
6
+ metadata.gz: 35ba610649dbff55acae0612782ab7e81947907212b9c454494f9baa5c3926a126430eed919356049261a9cb40767d7079874f56f1b4cb1bd7efb637f4f6ba4f
7
+ data.tar.gz: a3e9ce681547c0e648f477198a134749c9febb1f86e042d2bb3266e01a740767672a667d0c85a162d0f11489e87ee4c1a53cbd15d45e6aeefeb31fc30a2fe99f
@@ -29,7 +29,7 @@ module OneLogin
29
29
 
30
30
  @options = options
31
31
  @response = OneLogin::RubySaml::Utils.decode_raw_saml(response)
32
- @document = XMLSecurity::SignedDocument.new(response)
32
+ @document = XMLSecurity::SignedDocument.new(@response)
33
33
  end
34
34
 
35
35
  def validate!
@@ -37,7 +37,7 @@ module OneLogin
37
37
  end
38
38
 
39
39
  def validate(soft = true)
40
- return false unless valid_saml?(soft) && valid_state?(soft)
40
+ return false unless validate_structure(soft)
41
41
 
42
42
  valid_in_response_to?(soft) && valid_issuer?(soft) && success?(soft)
43
43
  end
@@ -51,7 +51,7 @@ module OneLogin
51
51
 
52
52
  def in_response_to
53
53
  @in_response_to ||= begin
54
- node = REXML::XPath.first(document, "/p:LogoutResponse", { "p" => PROTOCOL, "a" => ASSERTION })
54
+ node = REXML::XPath.first(document, "/p:LogoutResponse", { "p" => PROTOCOL })
55
55
  node.nil? ? nil : node.attributes['InResponseTo']
56
56
  end
57
57
  end
@@ -59,7 +59,6 @@ module OneLogin
59
59
  def issuer
60
60
  @issuer ||= begin
61
61
  node = REXML::XPath.first(document, "/p:LogoutResponse/a:Issuer", { "p" => PROTOCOL, "a" => ASSERTION })
62
- node ||= REXML::XPath.first(document, "/p:LogoutResponse/a:Assertion/a:Issuer", { "p" => PROTOCOL, "a" => ASSERTION })
63
62
  Utils.element_text(node)
64
63
  end
65
64
  end
@@ -73,7 +72,7 @@ module OneLogin
73
72
 
74
73
  private
75
74
 
76
- def valid_saml?(soft = true)
75
+ def validate_structure(soft = true)
77
76
  Dir.chdir(File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'schemas'))) do
78
77
  @schema = Nokogiri::XML::Schema(IO.read('saml20protocol_schema.xsd'))
79
78
  @xml = Nokogiri::XML(self.document.to_s)
@@ -85,26 +84,6 @@ module OneLogin
85
84
  end
86
85
  end
87
86
 
88
- def valid_state?(soft = true)
89
- if response.empty?
90
- return soft ? false : validation_error("Blank response")
91
- end
92
-
93
- if settings.nil?
94
- return soft ? false : validation_error("No settings on response")
95
- end
96
-
97
- if settings.sp_entity_id.nil?
98
- return soft ? false : validation_error("No sp_entity_id in settings")
99
- end
100
-
101
- if settings.idp_cert_fingerprint.nil? && settings.idp_cert.nil?
102
- return soft ? false : validation_error("No fingerprint or certificate on settings")
103
- end
104
-
105
- true
106
- end
107
-
108
87
  def valid_in_response_to?(soft = true)
109
88
  return true unless self.options.has_key? :matches_request_id
110
89
 
@@ -116,8 +95,10 @@ module OneLogin
116
95
  end
117
96
 
118
97
  def valid_issuer?(soft = true)
119
- unless URI.parse(issuer) == URI.parse(self.settings.sp_entity_id)
120
- return soft ? false : validation_error("Doesn't match the issuer, expected: <#{self.settings.sp_entity_id}>, but was: <#{issuer}>")
98
+ return true if settings.nil? || settings.idp_entity_id.nil? || issuer.nil?
99
+
100
+ unless OneLogin::RubySaml::Utils.uri_match?(issuer, settings.idp_entity_id)
101
+ return soft ? false : validation_error("Doesn't match the issuer, expected: <#{self.settings.idp_entity_id}>, but was: <#{issuer}>")
121
102
  end
122
103
  true
123
104
  end
@@ -134,6 +134,34 @@ module OneLogin
134
134
  end
135
135
  end
136
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
+
137
165
  # @return [Array] The Audience elements from the Contitions of the SAML Response.
138
166
  #
139
167
  def audiences
@@ -157,6 +185,7 @@ module OneLogin
157
185
  validate_response_state(soft) &&
158
186
  validate_conditions(soft) &&
159
187
  validate_audience(soft) &&
188
+ validate_issuer(soft) &&
160
189
  validate_signature(soft) &&
161
190
  success?
162
191
  end
@@ -390,6 +419,25 @@ module OneLogin
390
419
  true
391
420
  end
392
421
 
422
+ def validate_issuer(soft = true)
423
+ return true if settings.idp_entity_id.nil?
424
+
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
436
+ end
437
+
438
+ true
439
+ end
440
+
393
441
  def validate_signature(soft = true)
394
442
  error_msg = "Invalid Signature on SAML Response"
395
443
 
@@ -27,6 +27,7 @@ module OneLogin
27
27
  attr_accessor :idp_cert_fingerprint
28
28
  attr_accessor :idp_cert
29
29
  attr_accessor :idp_slo_target_url
30
+ attr_accessor :idp_entity_id
30
31
  #sp data
31
32
  attr_accessor :sp_entity_id
32
33
  attr_accessor :assertion_consumer_service_url
@@ -36,7 +37,6 @@ module OneLogin
36
37
  attr_accessor :name_identifier_value
37
38
  attr_accessor :name_identifier_value_requested
38
39
  attr_accessor :sessionindex
39
- attr_accessor :assertion_consumer_logout_service_url
40
40
  attr_accessor :compress_request
41
41
  attr_accessor :compress_response
42
42
  attr_accessor :double_quote_xml_attribute_values
@@ -152,15 +152,6 @@ module OneLogin
152
152
  OpenSSL::X509::Certificate.new(formatted_cert)
153
153
  end
154
154
 
155
- # @return [OpenSSL::X509::Certificate|nil] Build the New SP certificate from the settings (previously format it)
156
- #
157
- def get_sp_cert_new
158
- return nil if certificate_new.nil? || certificate_new.empty?
159
-
160
- formatted_cert = OneLogin::RubySaml::Utils.format_cert(certificate_new)
161
- OpenSSL::X509::Certificate.new(formatted_cert)
162
- end
163
-
164
155
  # @return [OpenSSL::PKey::RSA] Build the SP private from the settings (previously format it)
165
156
  #
166
157
  def get_sp_key
@@ -0,0 +1,101 @@
1
+ require "xml_security"
2
+ require "time"
3
+
4
+ # Only supports SAML 2.0
5
+ # SAML2 Logout Request (SLO IdP initiated, Parser)
6
+ module OneLogin
7
+ module RubySaml
8
+ class SloLogoutrequest
9
+
10
+ ASSERTION = "urn:oasis:names:tc:SAML:2.0:assertion"
11
+ PROTOCOL = "urn:oasis:names:tc:SAML:2.0:protocol"
12
+
13
+ # OneLogin::RubySaml::Settings Toolkit settings
14
+ attr_accessor :settings
15
+
16
+ attr_reader :document
17
+ attr_reader :request
18
+ attr_reader :options
19
+
20
+ def initialize(request, settings = nil, options = {})
21
+ raise ArgumentError.new("Request cannot be nil") if request.nil?
22
+ self.settings = settings
23
+
24
+ @options = options
25
+ @request = OneLogin::RubySaml::Utils.decode_raw_saml(request)
26
+ @document = XMLSecurity::SignedDocument.new(@request)
27
+ end
28
+
29
+ def validate!
30
+ validate(false)
31
+ end
32
+
33
+ def validate(soft = true)
34
+ return false unless validate_structure(soft)
35
+
36
+ valid_issuer?(soft)
37
+ end
38
+
39
+ def name_id
40
+ @name_id ||= begin
41
+ node = REXML::XPath.first(document, "/p:LogoutRequest/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
42
+ Utils.element_text(node)
43
+ end
44
+ end
45
+
46
+ alias_method :nameid, :name_id
47
+
48
+ def name_id_format
49
+ @name_id_node ||= REXML::XPath.first(document, "/p:LogoutRequest/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
50
+ @name_id_format ||=
51
+ if @name_id_node && @name_id_node.attribute("Format")
52
+ @name_id_node.attribute("Format").value
53
+ end
54
+ end
55
+
56
+ alias_method :nameid_format, :name_id_format
57
+
58
+ def id
59
+ @id ||= begin
60
+ node = REXML::XPath.first(document, "/p:LogoutRequest", { "p" => PROTOCOL } )
61
+ node.nil? ? nil : node.attributes['ID']
62
+ end
63
+ end
64
+
65
+ def issuer
66
+ @issuer ||= begin
67
+ node = REXML::XPath.first(document, "/p:LogoutRequest/a:Issuer", { "p" => PROTOCOL, "a" => ASSERTION })
68
+ Utils.element_text(node)
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def validate_structure(soft = true)
75
+ Dir.chdir(File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'schemas'))) do
76
+ @schema = Nokogiri::XML::Schema(IO.read('saml20protocol_schema.xsd'))
77
+ @xml = Nokogiri::XML(self.document.to_s)
78
+ end
79
+ if soft
80
+ @schema.validate(@xml).map{ return false }
81
+ else
82
+ @schema.validate(@xml).map{ |error| validation_error("#{error.message}\n\n#{@xml.to_s}") }
83
+ end
84
+ end
85
+
86
+ def valid_issuer?(soft = true)
87
+ return true if settings.nil? || settings.idp_entity_id.nil? || issuer.nil?
88
+
89
+ unless OneLogin::RubySaml::Utils.uri_match?(issuer, settings.idp_entity_id)
90
+ return soft ? false : validation_error("Doesn't match the issuer, expected: <#{self.settings.idp_entity_id}>, but was: <#{issuer}>")
91
+ end
92
+ true
93
+ end
94
+
95
+ def validation_error(message)
96
+ raise ValidationError.new(message)
97
+ end
98
+
99
+ end
100
+ end
101
+ end
@@ -179,6 +179,33 @@ module OneLogin
179
179
  Zlib::Deflate.deflate(inflated, 9)[2..-5]
180
180
  end
181
181
 
182
+ # Given two strings, attempt to match them as URIs using Rails' parse method. If they can be parsed,
183
+ # then the fully-qualified domain name and the host should performa a case-insensitive match, per the
184
+ # RFC for URIs. If Rails can not parse the string in to URL pieces, return a boolean match of the
185
+ # two strings. This maintains the previous functionality.
186
+ # @return [Boolean]
187
+ def self.uri_match?(destination_url, settings_url)
188
+ dest_uri = URI.parse(destination_url)
189
+ acs_uri = URI.parse(settings_url)
190
+
191
+ if dest_uri.scheme.nil? || acs_uri.scheme.nil? || dest_uri.host.nil? || acs_uri.host.nil?
192
+ raise URI::InvalidURIError
193
+ else
194
+ dest_uri.scheme.downcase == acs_uri.scheme.downcase &&
195
+ dest_uri.host.downcase == acs_uri.host.downcase &&
196
+ dest_uri.path == acs_uri.path &&
197
+ dest_uri.query == acs_uri.query
198
+ end
199
+ rescue URI::InvalidURIError
200
+ original_uri_match?(destination_url, settings_url)
201
+ end
202
+
203
+ # If Rails' URI.parse can't match to valid URL, default back to the original matching service.
204
+ # @return [Boolean]
205
+ def self.original_uri_match?(destination_url, settings_url)
206
+ destination_url == settings_url
207
+ end
208
+
182
209
  end
183
210
  end
184
211
  end
@@ -1,5 +1,5 @@
1
1
  module OneLogin
2
2
  module RubySaml
3
- VERSION = '0.8.15'
3
+ VERSION = '0.8.16'
4
4
  end
5
5
  end
@@ -2,6 +2,7 @@ require 'onelogin/ruby-saml/logging'
2
2
  require 'onelogin/ruby-saml/authrequest'
3
3
  require 'onelogin/ruby-saml/logoutrequest'
4
4
  require 'onelogin/ruby-saml/logoutresponse'
5
+ require 'onelogin/ruby-saml/slo_logoutrequest'
5
6
  require 'onelogin/ruby-saml/slo_logoutresponse'
6
7
  require 'onelogin/ruby-saml/response'
7
8
  require 'onelogin/ruby-saml/settings'
@@ -0,0 +1,14 @@
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-----
@@ -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,12 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
3
+ NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
4
+ YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
5
+ hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
6
+ O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
7
+ B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
8
+ 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
9
+ d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
10
+ 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
11
+ GeW2AKaE6oqRqeVwGw4V
12
+ -----END PRIVATE KEY-----
@@ -0,0 +1,12 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
3
+ NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
4
+ YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
5
+ hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
6
+ O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
7
+ B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
8
+ 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
9
+ d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
10
+ 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
11
+ GeW2AKaE6oqRqeVwGw4V
12
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ -----BEGIN CERTIFICATE----- MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ -----END CERTIFICATE-----
@@ -0,0 +1 @@
1
+ MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UEBhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVhMDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIxwsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNzc28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jCmdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
@@ -0,0 +1,12 @@
1
+ MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE
2
+ BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh
3
+ MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx
4
+ wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz
5
+ c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq
6
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC
7
+ mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw
8
+ Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N
9
+ 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G
10
+ CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ
11
+ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1
12
+ 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
@@ -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 @@
1
+ -----BEGIN PRIVATE KEY----- MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3 NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3 B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK GeW2AKaE6oqRqeVwGw4V -----END PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUhtYzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfRhg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQRO1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOLd3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCKGeW2AKaE6oqRqeVwGw4V
@@ -0,0 +1,10 @@
1
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
2
+ NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
3
+ YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
4
+ hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
5
+ O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
6
+ B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
7
+ 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
8
+ d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
9
+ 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
10
+ GeW2AKaE6oqRqeVwGw4V
@@ -0,0 +1 @@
1
+ -----BEGIN RSA PRIVATE KEY----- MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3 NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3 B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK GeW2AKaE6oqRqeVwGw4V -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUhtYzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfRhg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQRO1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOLd3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCKGeW2AKaE6oqRqeVwGw4V
@@ -0,0 +1,10 @@
1
+ MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
2
+ NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
3
+ YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
4
+ hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
5
+ O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
6
+ B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
7
+ 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
8
+ d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
9
+ 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
10
+ GeW2AKaE6oqRqeVwGw4V
@@ -32,12 +32,12 @@ class LogoutResponseTest < Minitest::Test
32
32
  describe "#validate" do
33
33
  it "validate the response" do
34
34
  in_relation_to_request_id = random_id
35
-
35
+ settings.idp_entity_id = "https://example.com/idp"
36
36
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(valid_response({:uuid => in_relation_to_request_id}), settings)
37
37
 
38
38
  assert logoutresponse.validate
39
39
 
40
- assert_equal settings.sp_entity_id, logoutresponse.issuer
40
+ assert_equal settings.idp_entity_id, logoutresponse.issuer
41
41
  assert_equal in_relation_to_request_id, logoutresponse.in_response_to
42
42
 
43
43
  assert logoutresponse.success?
@@ -87,20 +87,6 @@ class LogoutResponseTest < Minitest::Test
87
87
  assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
88
88
  end
89
89
 
90
- it "raise validation error when in bad state" do
91
- # no settings
92
- logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_response)
93
- assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
94
- end
95
-
96
- it "raise validation error when in lack of sp_entity_id setting" do
97
- bad_settings = settings
98
- bad_settings.issuer = nil
99
- bad_settings.sp_entity_id = nil
100
- logoutresponse = OneLogin::RubySaml::Logoutresponse.new(unsuccessful_response, bad_settings)
101
- assert_raises(OneLogin::RubySaml::ValidationError) { logoutresponse.validate! }
102
- end
103
-
104
90
  it "raise error for invalid xml" do
105
91
  logoutresponse = OneLogin::RubySaml::Logoutresponse.new(invalid_xml_response, settings)
106
92
 
@@ -0,0 +1,47 @@
1
+ #encoding: utf-8
2
+
3
+ def default_request_opts
4
+ {
5
+ :uuid => "_28024690-000e-0130-b6d2-38f6b112be8b",
6
+ :issue_instant => Time.now.strftime('%Y-%m-%dT%H:%M:%SZ'),
7
+ :nameid => "testuser@example.com",
8
+ :nameid_format => "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
9
+ :settings => settings
10
+ }
11
+ end
12
+
13
+ def valid_request(opts = {})
14
+ opts = default_request_opts.merge!(opts)
15
+
16
+ "<samlp:LogoutRequest
17
+ xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
18
+ xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\"
19
+ ID=\"#{random_id}\" Version=\"2.0\"
20
+ IssueInstant=\"#{opts[:issue_instant]}\"
21
+ Destination=\"#{opts[:settings].idp_slo_target_url}\">
22
+ <saml:Issuer>#{opts[:settings].idp_entity_id}</saml:Issuer>
23
+ <saml:NameID Format=\"#{opts[:nameid_format]}\">#{opts[:nameid]}</saml:NameID>
24
+ </samlp:LogoutRequest>"
25
+ end
26
+
27
+ def invalid_xml_request
28
+ "<samlp:SomethingAwful
29
+ xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
30
+ ID=\"#{random_id}\" Version=\"2.0\">
31
+ </samlp:SomethingAwful>"
32
+ end
33
+
34
+ def settings
35
+ @settings ||= OneLogin::RubySaml::Settings.new(
36
+ {
37
+ :assertion_consumer_service_url => "http://app.muda.no/sso/consume",
38
+ :single_logout_service_url => "http://app.muda.no/sso/consume_logout",
39
+ :sp_entity_id => "http://app.muda.no",
40
+ :sp_name_qualifier => "http://sso.muda.no",
41
+ :idp_sso_target_url => "http://sso.muda.no/sso",
42
+ :idp_slo_target_url => "http://sso.muda.no/slo",
43
+ :idp_cert_fingerprint => "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
44
+ :name_identifier_format => "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
45
+ }
46
+ )
47
+ end
@@ -323,6 +323,31 @@ class ResponseTest < Minitest::Test
323
323
  end
324
324
  end
325
325
 
326
+ describe "#validate_issuer" do
327
+ it "return true when the issuer of the Message/Assertion matches the IdP entityId" do
328
+ response = OneLogin::RubySaml::Response.new(response_document_valid_signed)
329
+ response.settings = settings
330
+ assert response.send(:validate_issuer)
331
+
332
+ response.settings.idp_entity_id = 'https://app.onelogin.com/saml2'
333
+ assert response.send(:validate_issuer)
334
+ end
335
+
336
+ it "return false when the issuer of the Message does not match the IdP entityId" do
337
+ response = OneLogin::RubySaml::Response.new(read_invalid_response("invalid_issuer_message.xml.base64"))
338
+ response.settings = settings
339
+ response.settings.idp_entity_id = 'http://idp.example.com/'
340
+ assert !response.send(:validate_issuer)
341
+ end
342
+
343
+ it "return false when the issuer of the Assertion does not match the IdP entityId" do
344
+ response = OneLogin::RubySaml::Response.new(read_invalid_response("invalid_issuer_assertion.xml.base64"))
345
+ response.settings = settings
346
+ response.settings.idp_entity_id = 'http://idp.example.com/'
347
+ assert !response.send(:validate_issuer)
348
+ end
349
+ end
350
+
326
351
  describe "#name_id" do
327
352
  it "extract the value of the name id element" do
328
353
  response = OneLogin::RubySaml::Response.new(response_document)
@@ -0,0 +1 @@
1
+ nVdbc6rKEn4/Vec/WK7HlOEuYiXZZwQ1XlARNCYvp2AYBOUmg4L++j3gJSYm2Xutp8Se7p7v+3pmunn4Kw/8yg4l2IvCxypzT1f/evrvfx6wGfhxc4pwHIUYVYhTiJuF8bG6TcJmZGIPN0MzQLiZwqYO1GGTvaebJsYoSUmq6lVI/HNMnERpBCO/WlEQTr3QTEsobprGTYrC6dZx7mEUUCi048gLU3z1nwnxfezG1UpPeazGTm41oAAFTqpZdVGqOQjaNQfaXI3nHUTWeIllG8Q5PBMzosfq/wXRgpYj0jXRYpwazbCoBhssUxMbLFlgOMviiiCMt6gX4tQM08cqSzNMja7XGNFg+KbANxn+rVqZn3UkvKpExkqlFLJZxiZPJ0qeHd+j3AxiH5XEHqhrpwcbN3VvSWTYJmfhbXzRI8uy+4y7j5IlxdI0TdESRXxs7C1/nXY8xSO7FzpRmU42wyj0oOl7h1JcFaVuZFeAv4wSL3WDb5IzFEMXyWsohzXI8OGvKlVu8b5JCfJfpvuANcFmDbsmc8pY5JsiByUohKgym/Yeq7/+bTlLikZihtiJkgB//Pl7qFC4Q34UI7uGz+QIwN9L+KVqD9QtRsVbkvP+J+KdhHtPMjf9LXqqd6e6PlU9TRjpfVEaL1iqTs0ZvK43HksA186l4SL58eenY3Mp8DFCUbUFMth+wM5TrMnLpSrxstwaTplpKxss4YzbTfmlx4DtIHvDq5k/cjXZnvLtfR8e7ux0YoxovIGZEHGrLb2b7CEVBuOpLwZrecP0WWMyVwHf6q1HL2OB995io6tCMx/frejp4KU/YGfOAFBB3p+arc0sdveD0Z0qhCN3NxyH00Hg530B9hXnsAWPFzpX+MmrRowDtL8QXAi0pJipefkhF4+XQ25Kip7UXk/uHmQZvGqyrMmjEdQWUcCxcwWMWsv1xl17XSmjW0CbdYDS0lUNZ7L2qsw1rdvO+vPZoT1UwboLmFlbbqmyPuPzjgGM1nI0bwFoKG1/+9b1XSvoZBabx/DQnqqgcfR31Z7BCr7RlULzhc8VBQyOcdgA9Hz7dgCok9H5SAG0ulLzsaLlqtIxS5vx0aZ2erl8AP1j/KsB/LlxhbVHsPaNVXuuttRy71auqvqLsDZfOtvXRWtndf2DOm1nSlb6D9qZO7GCuWqxdmyt2qoKoiNmstv0RQjVXtdRAd2V9U1X71mcorULjQDguyOgyC1PI1Q0JaoHd9rb7lWj8iHd9ofLbTxgNAW+DnlHmMB1hkdLXYpnu7noHIyN/LxuGO4wN9Y8q2qsCvt4jGb9+URkGwN3H6w68iZfTvj5NpuupSQGPn0XuPu6OrH3qz2odxl+lSgvel3Y4yF0B3xK7bK4rRxoXfPbUZdZqwff1wPx8KZziwQtgaisRubsVdtkPQVooPWZU+vIqQWGKrvryp5G7YI7s77j6bv5gj3Ym2fAahSz6zCepR36Aq/25fH8ZYfvdtrCeeu4dkCPJyrbS5SZGG12g8lmUs/HAPUH9Wd6PxFV/nXIOWaq73qvQeDsF7K0Tjl9d6BG++T5MHFnYZ/eIwrP9EUeHrQ8gwElTTKwSTQTcFqsrZ8FcW91qHGU7CfojnXLa/H5oF+Mx6tAXV+SD9fovaHFTT0lJnzuBtc2ObJRpbxxP7d9XHo39S2ECONzH6Bu0h87KDgPFqeOmH/XERlqoQ516KLArF58vX92rnlla4foMkuIDZ6RJIY84iLn1HiaE2qIRWQ2YEQa0oixOcT/6VjwzWAQ7kiPtu+90vrDjFAkuE6jb60Vgukp9dk6Ipr3lEqHdBwz/b4YzD1TWjzSXEvXJpHD84FtJ0VhKvqkSKRtCTTHQwmREvl+VKCqPuEoQFGI/ncF9YT0uPknRCecchQ6XrFTUc9jA/z5rMCgaSEzQUn1kvCHlMU5/rMZbxSl43CcACcteLI0S18VUzoWc4qgF3uoqPZvjajUuxbUd8jPZ4P6oqpHusTb9gpXXIBtIVIxVB67a6Rcky+Q3rBhbth8qg/Y2l4xDhDp0sSDV5BufZ5+YB+g1LRJFQriJzKXsE8qfL/lyeGd8QchwDZ1w+KZQAGpRaX8+f01pEWih06OM8nTC22UF0eCsRAnSnWBzJKCIEp2g+YYnqHFusTVbcgiyWZsqYEs5xL6raIse77sN4oSXIRCivL0CynfF2WffDuReezpx88r2ISFHzFPyJ8sSuyLjF+kupH6Bsv1ykXMjzqnpCzWNkWfl28cKsWVf6wWb0e1/P+fHp6SEYkurOenxyJ+8PaWXzYpG0uFvOjNdB+T3XLyiUmWwuVPb9HH6BtZzqufNPma+Hn13I+KsZL6+LX89Dc=
@@ -0,0 +1 @@
1
+ PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c2FtbHA6UmVzcG9uc2UgeG1sbnM6c2FtbHA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeDY1YzllMWQ5LTY2MjItNGE4MC1kMjNjLTE4ZWQwOTdkZTU1MCIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDYtMTdUMTQ6NTQ6MTRaIiBEZXN0aW5hdGlvbj0iaHR0cDovL3N0dWZmLmNvbS9lbmRwb2ludHMvZW5kcG9pbnRzL2Fjcy5waHAiIEluUmVzcG9uc2VUbz0iXzU3YmNiZjcwLTdiMWYtMDEyZS1jODIxLTc4MmJjYjEzYmIzOCI+DQogIDxzYW1sOklzc3Vlcj5odHRwOi8vaW52YWxpZC5pc3N1ZXIuZXhhbXBsZS5jb20vPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4NCiAgPGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4NCiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI3JzYS1zaGExIi8+DQogIDxkczpSZWZlcmVuY2UgVVJJPSIjcGZ4NjVjOWUxZDktNjYyMi00YTgwLWQyM2MtMThlZDA5N2RlNTUwIj48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPjxkczpEaWdlc3RWYWx1ZT5TYmc4M0hkZXZwcTN5ajZJOVlRdDR3bkZGYnM9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPjRVbHROQWxmMHRwQWJEYnFnbkxUWXAxcFJRQ2NMbFZkZERCdDhYRC9WYmFzMTBJSkd2V09UeExqMkVMci9wbytuSWd5Zkw2ejlWcThidm5EVVNjT3o5bVg0OFFsclJaRXo0U3RGTzBCVWM2MjFreFpYM3ZMSXBoeHc1N3o0U2FvckVmZGRGOFFkazBPQTl1Z3dFb014Z2FqcklXbWRldC8zMTVBTGJFSk13VT08L2RzOlNpZ25hdHVyZVZhbHVlPg0KPGRzOktleUluZm8+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJQ2dUQ0NBZW9DQ1FDYk9scldEZFg3RlRBTkJna3Foa2lHOXcwQkFRVUZBRENCaERFTE1Ba0dBMVVFQmhNQ1RrOHhHREFXQmdOVkJBZ1REMEZ1WkhKbFlYTWdVMjlzWW1WeVp6RU1NQW9HQTFVRUJ4TURSbTl2TVJBd0RnWURWUVFLRXdkVlRrbE9SVlJVTVJnd0ZnWURWUVFERXc5bVpXbGtaUzVsY214aGJtY3VibTh4SVRBZkJna3Foa2lHOXcwQkNRRVdFbUZ1WkhKbFlYTkFkVzVwYm1WMGRDNXViekFlRncwd056QTJNVFV4TWpBeE16VmFGdzB3TnpBNE1UUXhNakF4TXpWYU1JR0VNUXN3Q1FZRFZRUUdFd0pPVHpFWU1CWUdBMVVFQ0JNUFFXNWtjbVZoY3lCVGIyeGlaWEpuTVF3d0NnWURWUVFIRXdOR2IyOHhFREFPQmdOVkJBb1RCMVZPU1U1RlZGUXhHREFXQmdOVkJBTVREMlpsYVdSbExtVnliR0Z1Wnk1dWJ6RWhNQjhHQ1NxR1NJYjNEUUVKQVJZU1lXNWtjbVZoYzBCMWJtbHVaWFIwTG01dk1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdRRGl2YmhSN1A1MTZ4L1MzQnFLeHVwUWUwTE9Ob2xpdXBpQk9lc0NPM1NIYkRybDMrcTlJYmZuZm1FMDRyTnVNY1BzSXhCMTYxVGREcEllc0xDbjdjOGFQSElTS090UGxBZVRaU25iOFFBdTdhUmpacTMrUGJyUDV1VzNUY2ZDR1B0S1R5dEhPZ2UvT2xKYm8wNzhkVmhYUTE0ZDFFRHdYSlcxclJYdVV0NEM4UUlEQVFBQk1BMEdDU3FHU0liM0RRRUJCUVVBQTRHQkFDRFZmcDg2SE9icVkrZThCVW9XUTkrVk1ReDFBU0RvaEJqd09zZzJXeWtVcVJYRitkTGZjVUg5ZFdSNjNDdFpJS0ZEYlN0Tm9tUG5RejduYksrb255Z3dCc3BWRWJuSHVVaWhacTNaVWRtdW1RcUN3NFV2cy8xVXZxM29yT28vV0pWaFR5dkxnRlZLMlFhclE0LzY3T1pmSGQ3UitQT0JYaG9waFNNdjFaT288L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT4NCiAgPHNhbWxwOlN0YXR1cz4NCiAgICA8c2FtbHA6U3RhdHVzQ29kZSBWYWx1ZT0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+DQogIDwvc2FtbHA6U3RhdHVzPg0KICA8c2FtbDpBc3NlcnRpb24geG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiBJRD0icGZ4Nzg0MTk5MWMtYzczZi00MDM1LWUyZWUtYzE3MGMwZTFkM2U0IiBWZXJzaW9uPSIyLjAiIElzc3VlSW5zdGFudD0iMjAxMS0wNi0xN1QxNDo1NDoxNFoiPg0KICAgIDxzYW1sOklzc3Vlcj5odHRwOi8vaWRwLmV4YW1wbGUuY29tLzwvc2FtbDpJc3N1ZXI+ICAgIA0KICAgIDxzYW1sOlN1YmplY3Q+DQogICAgICA8c2FtbDpOYW1lSUQgU1BOYW1lUXVhbGlmaWVyPSJoZWxsby5jb20iIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3JtYXQ6ZW1haWxBZGRyZXNzIj5zb21lb25lQGV4YW1wbGUuY29tPC9zYW1sOk5hbWVJRD4NCiAgICAgIDxzYW1sOlN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj4NCiAgICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgTm90T25PckFmdGVyPSIyMDIwLTA2LTE3VDE0OjU5OjE0WiIgUmVjaXBpZW50PSJodHRwOi8vc3R1ZmYuY29tL2VuZHBvaW50cy9lbmRwb2ludHMvYWNzLnBocCIgSW5SZXNwb25zZVRvPSJfNTdiY2JmNzAtN2IxZi0wMTJlLWM4MjEtNzgyYmNiMTNiYjM4Ii8+DQogICAgICA8L3NhbWw6U3ViamVjdENvbmZpcm1hdGlvbj4NCiAgICA8L3NhbWw6U3ViamVjdD4NCiAgICA8c2FtbDpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAxMC0wNi0xN1QxNDo1Mzo0NFoiIE5vdE9uT3JBZnRlcj0iMjAyMS0wNi0xN1QxNDo1OToxNFoiPg0KICAgICAgPHNhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj4NCiAgICAgICAgPHNhbWw6QXVkaWVuY2U+aHR0cDovL3N0dWZmLmNvbS9lbmRwb2ludHMvbWV0YWRhdGEucGhwPC9zYW1sOkF1ZGllbmNlPg0KICAgICAgPC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+DQogICAgPC9zYW1sOkNvbmRpdGlvbnM+DQogICAgPHNhbWw6QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDExLTA2LTE3VDE0OjU0OjA3WiIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAyMS0wNi0xN1QyMjo1NDoxNFoiIFNlc3Npb25JbmRleD0iXzUxYmUzNzk2NWZlYjU1NzlkODAzMTQxMDc2OTM2ZGMyZTlkMWQ5OGViZiI+DQogICAgICA8c2FtbDpBdXRobkNvbnRleHQ+DQogICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkPC9zYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPg0KICAgICAgPC9zYW1sOkF1dGhuQ29udGV4dD4NCiAgICA8L3NhbWw6QXV0aG5TdGF0ZW1lbnQ+DQogICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICAgICAgPHNhbWw6QXR0cmlidXRlIE5hbWU9Im1haWwiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6YmFzaWMiPg0KICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4c2k6dHlwZT0ieHM6c3RyaW5nIj5zb21lb25lQGV4YW1wbGUuY29tPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPg0KICAgICAgPC9zYW1sOkF0dHJpYnV0ZT4NCiAgICA8L3NhbWw6QXR0cmlidXRlU3RhdGVtZW50Pg0KICA8L3NhbWw6QXNzZXJ0aW9uPg0KPC9zYW1scDpSZXNwb25zZT4=
@@ -15,9 +15,9 @@ def valid_response(opts = {})
15
15
  xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
16
16
  ID=\"#{random_id}\" Version=\"2.0\"
17
17
  IssueInstant=\"#{opts[:issue_instant]}\"
18
- Destination=\"#{opts[:settings].single_logout_service_url}\"
18
+ Destination=\"#{opts[:settings].idp_slo_target_url}\"
19
19
  InResponseTo=\"#{opts[:uuid]}\">
20
- <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].sp_entity_id}</saml:Issuer>
20
+ <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].idp_entity_id}</saml:Issuer>
21
21
  <samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
22
22
  <samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
23
23
  Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\">
@@ -33,9 +33,9 @@ def unsuccessful_response(opts = {})
33
33
  xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
34
34
  ID=\"#{random_id}\" Version=\"2.0\"
35
35
  IssueInstant=\"#{opts[:issue_instant]}\"
36
- Destination=\"#{opts[:settings].single_logout_service_url}\"
36
+ Destination=\"#{opts[:settings].idp_slo_target_url}\"
37
37
  InResponseTo=\"#{opts[:uuid]}\">
38
- <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].sp_entity_id}</saml:Issuer>
38
+ <saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].idp_entity_id}</saml:Issuer>
39
39
  <samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
40
40
  <samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
41
41
  Value=\"urn:oasis:names:tc:SAML:2.0:status:Requester\">
@@ -42,6 +42,112 @@ class SettingsTest < Minitest::Test
42
42
  end
43
43
  end
44
44
 
45
+ describe "#get_idp_cert" do
46
+ it "returns nil when the cert is an empty string" do
47
+ @settings.idp_cert = ""
48
+ assert_nil @settings.get_idp_cert
49
+ end
50
+
51
+ it "returns nil when the cert is nil" do
52
+ @settings.idp_cert = nil
53
+ assert_nil @settings.get_idp_cert
54
+ end
55
+
56
+ it "returns the certificate when it is valid" do
57
+ @settings.idp_cert = ruby_saml_cert_text
58
+ assert @settings.get_idp_cert.kind_of? OpenSSL::X509::Certificate
59
+ end
60
+
61
+ it "raises when the certificate is not valid" do
62
+ # formatted but invalid cert
63
+ @settings.idp_cert = read_certificate("formatted_certificate")
64
+ assert_raises(OpenSSL::X509::CertificateError) {
65
+ @settings.get_idp_cert
66
+ }
67
+ end
68
+ end
69
+
70
+ describe "#get_sp_cert" do
71
+ it "returns nil when the cert is an empty string" do
72
+ @settings.certificate = ""
73
+ assert_nil @settings.get_sp_cert
74
+ end
75
+
76
+ it "returns nil when the cert is nil" do
77
+ @settings.certificate = nil
78
+ assert_nil @settings.get_sp_cert
79
+ end
80
+
81
+ it "returns the certificate when it is valid" do
82
+ @settings.certificate = ruby_saml_cert_text
83
+ assert @settings.get_sp_cert.kind_of? OpenSSL::X509::Certificate
84
+ end
85
+
86
+ it "raises when the certificate is not valid" do
87
+ # formatted but invalid cert
88
+ @settings.certificate = read_certificate("formatted_certificate")
89
+ assert_raises(OpenSSL::X509::CertificateError) {
90
+ @settings.get_sp_cert
91
+ }
92
+ end
93
+ end
94
+
95
+ describe "#get_sp_key" do
96
+ it "returns nil when the private key is an empty string" do
97
+ @settings.private_key = ""
98
+ assert_nil @settings.get_sp_key
99
+ end
100
+
101
+ it "returns nil when the private key is nil" do
102
+ @settings.private_key = nil
103
+ assert_nil @settings.get_sp_key
104
+ end
105
+
106
+ it "returns the private key when it is valid" do
107
+ @settings.private_key = ruby_saml_key_text
108
+ assert @settings.get_sp_key.kind_of? OpenSSL::PKey::RSA
109
+ end
110
+
111
+ it "raises when the private key is not valid" do
112
+ # formatted but invalid rsa private key
113
+ @settings.private_key = read_certificate("formatted_rsa_private_key")
114
+ assert_raises(OpenSSL::PKey::RSAError) {
115
+ @settings.get_sp_key
116
+ }
117
+ end
118
+
119
+ end
120
+
121
+ describe "#get_fingerprint" do
122
+ it "get the fingerprint value when cert and fingerprint in settings are nil" do
123
+ @settings.idp_cert_fingerprint = nil
124
+ @settings.idp_cert = nil
125
+ fingerprint = @settings.get_fingerprint
126
+ assert_nil fingerprint
127
+ end
128
+
129
+ it "get the fingerprint value when there is a cert at the settings" do
130
+ @settings.idp_cert_fingerprint = nil
131
+ @settings.idp_cert = ruby_saml_cert_text
132
+ fingerprint = @settings.get_fingerprint
133
+ assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
134
+ end
135
+
136
+ it "get the fingerprint value when there is a fingerprint at the settings" do
137
+ @settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
138
+ @settings.idp_cert = nil
139
+ fingerprint = @settings.get_fingerprint
140
+ assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
141
+ end
142
+
143
+ it "get the fingerprint value when there are cert and fingerprint at the settings" do
144
+ @settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
145
+ @settings.idp_cert = ruby_saml_cert_text
146
+ fingerprint = @settings.get_fingerprint
147
+ assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
148
+ end
149
+ end
150
+
45
151
  end
46
152
 
47
153
  end
@@ -0,0 +1,66 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "requests/logoutrequest_fixtures"))
3
+
4
+ class SloLogoutrequestTest < Minitest::Test
5
+
6
+ describe "SloLogoutrequest" do
7
+
8
+ describe "#new" do
9
+ it "raise an exception when request is initialized with nil" do
10
+ assert_raises(ArgumentError) { OneLogin::RubySaml::SloLogoutrequest.new(nil) }
11
+ end
12
+ it "default to empty settings" do
13
+ logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request)
14
+ assert logoutrequest.settings.nil?
15
+ end
16
+ it "accept constructor-injected settings" do
17
+ logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request, settings)
18
+ assert !logoutrequest.settings.nil?
19
+ end
20
+ it "accept constructor-injected options" do
21
+ logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request, nil, { :foo => :bar} )
22
+ assert !logoutrequest.options.empty?
23
+ end
24
+ it "support base64 encoded requests" do
25
+ expected_request = valid_request
26
+ logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(Base64.encode64(expected_request), settings)
27
+
28
+ assert_equal expected_request, logoutrequest.request
29
+ end
30
+ end
31
+
32
+ describe "#validate" do
33
+ it "validate the request" do
34
+ in_relation_to_request_id = random_id
35
+ settings.idp_entity_id = "https://example.com/idp"
36
+ logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request({:uuid => in_relation_to_request_id}), settings)
37
+
38
+ assert logoutrequest.validate
39
+
40
+ assert_equal settings.idp_entity_id, logoutrequest.issuer
41
+
42
+ assert_equal "testuser@example.com", logoutrequest.nameid
43
+
44
+ assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", logoutrequest.nameid_format
45
+ end
46
+
47
+ end
48
+
49
+ describe "#validate!" do
50
+ it "validates good requests" do
51
+ in_relation_to_request_id = random_id
52
+
53
+ logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request({:uuid => in_relation_to_request_id}), settings)
54
+
55
+ logoutrequest.validate!
56
+ end
57
+
58
+ it "raise error for invalid xml" do
59
+ logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(invalid_xml_request, settings)
60
+
61
+ assert_raises(OneLogin::RubySaml::ValidationError) { logoutrequest.validate! }
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -2,6 +2,194 @@ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
2
 
3
3
  class UtilsTest < Minitest::Test
4
4
  describe "Utils" do
5
+
6
+ describe "format_cert" do
7
+ let(:formatted_certificate) {read_certificate("formatted_certificate")}
8
+ let(:formatted_chained_certificate) {read_certificate("formatted_chained_certificate")}
9
+
10
+ it "returns empty string when the cert is an empty string" do
11
+ cert = ""
12
+ assert_equal "", OneLogin::RubySaml::Utils.format_cert(cert)
13
+ end
14
+
15
+ it "returns nil when the cert is nil" do
16
+ cert = nil
17
+ assert_nil OneLogin::RubySaml::Utils.format_cert(cert)
18
+ end
19
+
20
+ it "returns the certificate when it is valid" do
21
+ assert_equal formatted_certificate, OneLogin::RubySaml::Utils.format_cert(formatted_certificate)
22
+ end
23
+
24
+ it "reformats the certificate when there are spaces and no line breaks" do
25
+ invalid_certificate1 = read_certificate("invalid_certificate1")
26
+ assert_equal formatted_certificate, OneLogin::RubySaml::Utils.format_cert(invalid_certificate1)
27
+ end
28
+
29
+ it "reformats the certificate when there are spaces and no headers" do
30
+ invalid_certificate2 = read_certificate("invalid_certificate2")
31
+ assert_equal formatted_certificate, OneLogin::RubySaml::Utils.format_cert(invalid_certificate2)
32
+ end
33
+
34
+ it "returns the cert when it's encoded" do
35
+ encoded_certificate = read_certificate("certificate.der")
36
+ assert_equal encoded_certificate, OneLogin::RubySaml::Utils.format_cert(encoded_certificate)
37
+ end
38
+
39
+ it "reformats the certificate when there line breaks and no headers" do
40
+ invalid_certificate3 = read_certificate("invalid_certificate3")
41
+ assert_equal formatted_certificate, OneLogin::RubySaml::Utils.format_cert(invalid_certificate3)
42
+ end
43
+
44
+ it "returns the chained certificate when it is a valid chained certificate" do
45
+ assert_equal formatted_chained_certificate, OneLogin::RubySaml::Utils.format_cert(formatted_chained_certificate)
46
+ end
47
+
48
+ it "reformats the chained certificate when there are spaces and no line breaks" do
49
+ invalid_chained_certificate1 = read_certificate("invalid_chained_certificate1")
50
+ assert_equal formatted_chained_certificate, OneLogin::RubySaml::Utils.format_cert(invalid_chained_certificate1)
51
+ end
52
+
53
+ end
54
+
55
+ describe "format_private_key" do
56
+ let(:formatted_private_key) do
57
+ read_certificate("formatted_private_key")
58
+ end
59
+
60
+ it "returns empty string when the private key is an empty string" do
61
+ private_key = ""
62
+ assert_equal "", OneLogin::RubySaml::Utils.format_private_key(private_key)
63
+ end
64
+
65
+ it "returns nil when the private key is nil" do
66
+ private_key = nil
67
+ assert_nil OneLogin::RubySaml::Utils.format_private_key(private_key)
68
+ end
69
+
70
+ it "returns the private key when it is valid" do
71
+ assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(formatted_private_key)
72
+ end
73
+
74
+ it "reformats the private key when there are spaces and no line breaks" do
75
+ invalid_private_key1 = read_certificate("invalid_private_key1")
76
+ assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_private_key1)
77
+ end
78
+
79
+ it "reformats the private key when there are spaces and no headers" do
80
+ invalid_private_key2 = read_certificate("invalid_private_key2")
81
+ assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_private_key2)
82
+ end
83
+
84
+ it "reformats the private key when there line breaks and no headers" do
85
+ invalid_private_key3 = read_certificate("invalid_private_key3")
86
+ assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_private_key3)
87
+ end
88
+
89
+ describe "an RSA public key" do
90
+ let(:formatted_rsa_private_key) do
91
+ read_certificate("formatted_rsa_private_key")
92
+ end
93
+
94
+ it "returns the private key when it is valid" do
95
+ assert_equal formatted_rsa_private_key, OneLogin::RubySaml::Utils.format_private_key(formatted_rsa_private_key)
96
+ end
97
+
98
+ it "reformats the private key when there are spaces and no line breaks" do
99
+ invalid_rsa_private_key1 = read_certificate("invalid_rsa_private_key1")
100
+ assert_equal formatted_rsa_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_rsa_private_key1)
101
+ end
102
+
103
+ it "reformats the private key when there are spaces and no headers" do
104
+ invalid_rsa_private_key2 = read_certificate("invalid_rsa_private_key2")
105
+ assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_rsa_private_key2)
106
+ end
107
+
108
+ it "reformats the private key when there line breaks and no headers" do
109
+ invalid_rsa_private_key3 = read_certificate("invalid_rsa_private_key3")
110
+ assert_equal formatted_private_key, OneLogin::RubySaml::Utils.format_private_key(invalid_rsa_private_key3)
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "build_query" do
116
+ it "returns the query string" do
117
+ params = {}
118
+ params[:type] = "SAMLRequest"
119
+ params[:data] = "PHNhbWxwOkF1dGhuUmVxdWVzdCBEZXN0aW5hdGlvbj0naHR0cDovL2V4YW1wbGUuY29tP2ZpZWxkPXZhbHVlJyBJRD0nXzk4NmUxZDEwLWVhY2ItMDEzMi01MGRkLTAwOTBmNWRlZGQ3NycgSXNzdWVJbnN0YW50PScyMDE1LTA2LTAxVDIwOjM0OjU5WicgVmVyc2lvbj0nMi4wJyB4bWxuczpzYW1sPSd1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uJyB4bWxuczpzYW1scD0ndXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sJy8+"
120
+ params[:relay_state] = "http://example.com"
121
+ params[:sig_alg] = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
122
+ query_string = OneLogin::RubySaml::Utils.build_query(params)
123
+ assert_equal "SAMLRequest=PHNhbWxwOkF1dGhuUmVxdWVzdCBEZXN0aW5hdGlvbj0naHR0cDovL2V4YW1wbGUuY29tP2ZpZWxkPXZhbHVlJyBJRD0nXzk4NmUxZDEwLWVhY2ItMDEzMi01MGRkLTAwOTBmNWRlZGQ3NycgSXNzdWVJbnN0YW50PScyMDE1LTA2LTAxVDIwOjM0OjU5WicgVmVyc2lvbj0nMi4wJyB4bWxuczpzYW1sPSd1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uJyB4bWxuczpzYW1scD0ndXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sJy8%2B&RelayState=http%3A%2F%2Fexample.com&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1", query_string
124
+ end
125
+ end
126
+
127
+ describe "#status_error_msg" do
128
+ it "returns a error msg with a status message" do
129
+ error_msg = "The status code of the Logout Response was not Success"
130
+ status_code = "urn:oasis:names:tc:SAML:2.0:status:Requester"
131
+ status_message = "The request could not be performed due to an error on the part of the requester."
132
+ status_error_msg = OneLogin::RubySaml::Utils.status_error_msg(error_msg, status_code, status_message)
133
+ assert_equal = "The status code of the Logout Response was not Success, was Requester -> The request could not be performed due to an error on the part of the requester.", status_error_msg
134
+
135
+ status_error_msg2 = OneLogin::RubySaml::Utils.status_error_msg(error_msg, status_code)
136
+ assert_equal = "The status code of the Logout Response was not Success, was Requester", status_error_msg2
137
+
138
+ status_error_msg3 = OneLogin::RubySaml::Utils.status_error_msg(error_msg)
139
+ assert_equal = "The status code of the Logout Response was not Success", status_error_msg3
140
+ end
141
+ end
142
+
143
+ describe 'uri_match' do
144
+ it 'matches two urls' do
145
+ destination = 'http://www.example.com/test?var=stuff'
146
+ settings = 'http://www.example.com/test?var=stuff'
147
+ assert OneLogin::RubySaml::Utils.uri_match?(destination, settings)
148
+ end
149
+
150
+ it 'fails to match two urls' do
151
+ destination = 'http://www.example.com/test?var=stuff'
152
+ settings = 'http://www.example.com/othertest?var=stuff'
153
+ assert !OneLogin::RubySaml::Utils.uri_match?(destination, settings)
154
+ end
155
+
156
+ it "matches two URLs if the scheme case doesn't match" do
157
+ destination = 'http://www.example.com/test?var=stuff'
158
+ settings = 'HTTP://www.example.com/test?var=stuff'
159
+ assert OneLogin::RubySaml::Utils.uri_match?(destination, settings)
160
+ end
161
+
162
+ it "matches two URLs if the host case doesn't match" do
163
+ destination = 'http://www.EXAMPLE.com/test?var=stuff'
164
+ settings = 'http://www.example.com/test?var=stuff'
165
+ assert OneLogin::RubySaml::Utils.uri_match?(destination, settings)
166
+ end
167
+
168
+ it "fails to match two URLs if the path case doesn't match" do
169
+ destination = 'http://www.example.com/TEST?var=stuff'
170
+ settings = 'http://www.example.com/test?var=stuff'
171
+ assert !OneLogin::RubySaml::Utils.uri_match?(destination, settings)
172
+ end
173
+
174
+ it "fails to match two URLs if the query case doesn't match" do
175
+ destination = 'http://www.example.com/test?var=stuff'
176
+ settings = 'http://www.example.com/test?var=STUFF'
177
+ assert !OneLogin::RubySaml::Utils.uri_match?(destination, settings)
178
+ end
179
+
180
+ it 'matches two non urls' do
181
+ destination = 'stuff'
182
+ settings = 'stuff'
183
+ assert OneLogin::RubySaml::Utils.uri_match?(destination, settings)
184
+ end
185
+
186
+ it "fails to match two non urls" do
187
+ destination = 'stuff'
188
+ settings = 'not stuff'
189
+ assert !OneLogin::RubySaml::Utils.uri_match?(destination, settings)
190
+ end
191
+ end
192
+
5
193
  describe 'element_text' do
6
194
  it 'returns the element text' do
7
195
  element = REXML::Document.new('<element>element text</element>').elements.first
@@ -36,6 +224,8 @@ class UtilsTest < Minitest::Test
36
224
  element = REXML::Document.new('<element></element>').elements.first
37
225
  assert_equal '', OneLogin::RubySaml::Utils.element_text(element)
38
226
  end
227
+
228
+
39
229
  end
40
230
  end
41
- end
231
+ 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: 0.8.15
4
+ version: 0.8.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - OneLogin LLC
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-27 00:00:00.000000000 Z
11
+ date: 2020-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uuid
@@ -63,6 +63,7 @@ files:
63
63
  - lib/onelogin/ruby-saml/response.rb
64
64
  - lib/onelogin/ruby-saml/setting_error.rb
65
65
  - lib/onelogin/ruby-saml/settings.rb
66
+ - lib/onelogin/ruby-saml/slo_logoutrequest.rb
66
67
  - lib/onelogin/ruby-saml/slo_logoutresponse.rb
67
68
  - lib/onelogin/ruby-saml/utils.rb
68
69
  - lib/onelogin/ruby-saml/validation_error.rb
@@ -74,7 +75,22 @@ files:
74
75
  - lib/schemas/xmldsig_schema.xsd
75
76
  - lib/xml_security.rb
76
77
  - ruby-saml.gemspec
78
+ - test/certificates/certificate.der
77
79
  - test/certificates/certificate1
80
+ - test/certificates/formatted_certificate
81
+ - test/certificates/formatted_chained_certificate
82
+ - test/certificates/formatted_private_key
83
+ - test/certificates/formatted_rsa_private_key
84
+ - test/certificates/invalid_certificate1
85
+ - test/certificates/invalid_certificate2
86
+ - test/certificates/invalid_certificate3
87
+ - test/certificates/invalid_chained_certificate1
88
+ - test/certificates/invalid_private_key1
89
+ - test/certificates/invalid_private_key2
90
+ - test/certificates/invalid_private_key3
91
+ - test/certificates/invalid_rsa_private_key1
92
+ - test/certificates/invalid_rsa_private_key2
93
+ - test/certificates/invalid_rsa_private_key3
78
94
  - test/certificates/r1_certificate2_base64
79
95
  - test/certificates/ruby-saml-2.crt
80
96
  - test/certificates/ruby-saml.crt
@@ -82,6 +98,7 @@ files:
82
98
  - test/logoutrequest_test.rb
83
99
  - test/logoutresponse_test.rb
84
100
  - test/request_test.rb
101
+ - test/requests/logoutrequest_fixtures.rb
85
102
  - test/response_test.rb
86
103
  - test/responses/adfs_response_sha1.xml
87
104
  - test/responses/adfs_response_sha256.xml
@@ -89,6 +106,8 @@ files:
89
106
  - test/responses/adfs_response_sha512.xml
90
107
  - test/responses/adfs_response_xmlns.xml
91
108
  - test/responses/encrypted_new_attack.xml.base64
109
+ - test/responses/invalids/invalid_issuer_assertion.xml.base64
110
+ - test/responses/invalids/invalid_issuer_message.xml.base64
92
111
  - test/responses/invalids/multiple_signed.xml.base64
93
112
  - test/responses/invalids/no_signature.xml.base64
94
113
  - test/responses/invalids/response_with_concealed_signed_assertion.xml
@@ -121,6 +140,7 @@ files:
121
140
  - test/responses/valid_response_without_x509certificate.xml.base64
122
141
  - test/responses/wrapped_response_2.xml.base64
123
142
  - test/settings_test.rb
143
+ - test/slo_logoutrequest_test.rb
124
144
  - test/slo_logoutresponse_test.rb
125
145
  - test/test_helper.rb
126
146
  - test/utils_test.rb
@@ -149,7 +169,22 @@ signing_key:
149
169
  specification_version: 4
150
170
  summary: SAML Ruby Tookit
151
171
  test_files:
172
+ - test/certificates/certificate.der
152
173
  - test/certificates/certificate1
174
+ - test/certificates/formatted_certificate
175
+ - test/certificates/formatted_chained_certificate
176
+ - test/certificates/formatted_private_key
177
+ - test/certificates/formatted_rsa_private_key
178
+ - test/certificates/invalid_certificate1
179
+ - test/certificates/invalid_certificate2
180
+ - test/certificates/invalid_certificate3
181
+ - test/certificates/invalid_chained_certificate1
182
+ - test/certificates/invalid_private_key1
183
+ - test/certificates/invalid_private_key2
184
+ - test/certificates/invalid_private_key3
185
+ - test/certificates/invalid_rsa_private_key1
186
+ - test/certificates/invalid_rsa_private_key2
187
+ - test/certificates/invalid_rsa_private_key3
153
188
  - test/certificates/r1_certificate2_base64
154
189
  - test/certificates/ruby-saml-2.crt
155
190
  - test/certificates/ruby-saml.crt
@@ -157,6 +192,7 @@ test_files:
157
192
  - test/logoutrequest_test.rb
158
193
  - test/logoutresponse_test.rb
159
194
  - test/request_test.rb
195
+ - test/requests/logoutrequest_fixtures.rb
160
196
  - test/response_test.rb
161
197
  - test/responses/adfs_response_sha1.xml
162
198
  - test/responses/adfs_response_sha256.xml
@@ -164,6 +200,8 @@ test_files:
164
200
  - test/responses/adfs_response_sha512.xml
165
201
  - test/responses/adfs_response_xmlns.xml
166
202
  - test/responses/encrypted_new_attack.xml.base64
203
+ - test/responses/invalids/invalid_issuer_assertion.xml.base64
204
+ - test/responses/invalids/invalid_issuer_message.xml.base64
167
205
  - test/responses/invalids/multiple_signed.xml.base64
168
206
  - test/responses/invalids/no_signature.xml.base64
169
207
  - test/responses/invalids/response_with_concealed_signed_assertion.xml
@@ -196,6 +234,7 @@ test_files:
196
234
  - test/responses/valid_response_without_x509certificate.xml.base64
197
235
  - test/responses/wrapped_response_2.xml.base64
198
236
  - test/settings_test.rb
237
+ - test/slo_logoutrequest_test.rb
199
238
  - test/slo_logoutresponse_test.rb
200
239
  - test/test_helper.rb
201
240
  - test/utils_test.rb