ruby-saml 0.8.16 → 0.9
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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +1 -6
- data/Gemfile +2 -12
- data/README.md +363 -35
- data/Rakefile +14 -0
- data/changelog.md +22 -9
- data/lib/onelogin/ruby-saml/attribute_service.rb +34 -0
- data/lib/onelogin/ruby-saml/attributes.rb +26 -64
- data/lib/onelogin/ruby-saml/authrequest.rb +47 -89
- data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +87 -0
- data/lib/onelogin/ruby-saml/logoutrequest.rb +34 -93
- data/lib/onelogin/ruby-saml/logoutresponse.rb +25 -24
- data/lib/onelogin/ruby-saml/metadata.rb +46 -16
- data/lib/onelogin/ruby-saml/response.rb +62 -322
- data/lib/onelogin/ruby-saml/saml_message.rb +78 -0
- data/lib/onelogin/ruby-saml/settings.rb +54 -121
- data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +26 -61
- data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +27 -84
- data/lib/onelogin/ruby-saml/utils.rb +32 -199
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/ruby-saml.rb +5 -2
- data/lib/schemas/{saml20assertion_schema.xsd → saml-schema-assertion-2.0.xsd} +283 -283
- data/lib/schemas/saml-schema-authn-context-2.0.xsd +23 -0
- data/lib/schemas/saml-schema-authn-context-types-2.0.xsd +821 -0
- data/lib/schemas/saml-schema-metadata-2.0.xsd +339 -0
- data/lib/schemas/{saml20protocol_schema.xsd → saml-schema-protocol-2.0.xsd} +302 -302
- data/lib/schemas/sstc-metadata-attr.xsd +35 -0
- data/lib/schemas/sstc-saml-attribute-ext.xsd +25 -0
- data/lib/schemas/sstc-saml-metadata-algsupport-v1.0.xsd +41 -0
- data/lib/schemas/sstc-saml-metadata-ui-v1.0.xsd +89 -0
- data/lib/schemas/{xenc_schema.xsd → xenc-schema.xsd} +1 -11
- data/lib/schemas/xml.xsd +287 -0
- data/lib/schemas/{xmldsig_schema.xsd → xmldsig-core-schema.xsd} +0 -9
- data/lib/xml_security.rb +83 -235
- data/ruby-saml.gemspec +1 -0
- data/test/idp_metadata_parser_test.rb +54 -0
- data/test/logoutrequest_test.rb +68 -144
- data/test/logoutresponse_test.rb +43 -25
- data/test/metadata_test.rb +87 -0
- data/test/request_test.rb +103 -90
- data/test/response_test.rb +181 -471
- data/test/responses/idp_descriptor.xml +3 -0
- data/test/responses/logoutresponse_fixtures.rb +5 -5
- data/test/responses/response_no_cert_and_encrypted_attrs.xml +29 -0
- data/test/responses/response_with_multiple_attribute_values.xml +1 -1
- data/test/responses/slo_request.xml +4 -0
- data/test/settings_test.rb +25 -112
- data/test/slo_logoutrequest_test.rb +41 -44
- data/test/slo_logoutresponse_test.rb +87 -167
- data/test/test_helper.rb +27 -102
- data/test/xml_security_test.rb +114 -337
- metadata +34 -84
- data/lib/onelogin/ruby-saml/setting_error.rb +0 -6
- data/test/certificates/certificate.der +0 -0
- data/test/certificates/formatted_certificate +0 -14
- data/test/certificates/formatted_chained_certificate +0 -42
- data/test/certificates/formatted_private_key +0 -12
- data/test/certificates/formatted_rsa_private_key +0 -12
- data/test/certificates/invalid_certificate1 +0 -1
- data/test/certificates/invalid_certificate2 +0 -1
- data/test/certificates/invalid_certificate3 +0 -12
- data/test/certificates/invalid_chained_certificate1 +0 -1
- data/test/certificates/invalid_private_key1 +0 -1
- data/test/certificates/invalid_private_key2 +0 -1
- data/test/certificates/invalid_private_key3 +0 -10
- data/test/certificates/invalid_rsa_private_key1 +0 -1
- data/test/certificates/invalid_rsa_private_key2 +0 -1
- data/test/certificates/invalid_rsa_private_key3 +0 -10
- data/test/certificates/ruby-saml-2.crt +0 -15
- data/test/requests/logoutrequest_fixtures.rb +0 -47
- data/test/responses/encrypted_new_attack.xml.base64 +0 -1
- data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +0 -1
- data/test/responses/invalids/invalid_issuer_message.xml.base64 +0 -1
- data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
- data/test/responses/invalids/no_signature.xml.base64 +0 -1
- data/test/responses/invalids/response_with_concealed_signed_assertion.xml +0 -51
- data/test/responses/invalids/response_with_doubled_signed_assertion.xml +0 -49
- data/test/responses/invalids/signature_wrapping_attack.xml.base64 +0 -1
- data/test/responses/response_node_text_attack.xml.base64 +0 -1
- data/test/responses/response_with_concealed_signed_assertion.xml +0 -51
- data/test/responses/response_with_doubled_signed_assertion.xml +0 -49
- data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
- data/test/responses/response_with_signed_assertion_3.xml +0 -30
- data/test/responses/response_with_signed_message_and_assertion.xml +0 -34
- data/test/responses/response_with_undefined_recipient.xml.base64 +0 -1
- data/test/responses/response_wrapped.xml.base64 +0 -150
- data/test/responses/valid_response.xml.base64 +0 -1
- data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
- data/test/utils_test.rb +0 -231
data/test/test_helper.rb
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
require 'rubygems'
|
|
2
|
-
require '
|
|
3
|
-
require '
|
|
2
|
+
require 'bundler'
|
|
3
|
+
require 'test/unit'
|
|
4
4
|
require 'mocha/setup'
|
|
5
|
-
require 'timecop'
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
require 'uuid'
|
|
9
|
-
else
|
|
10
|
-
require 'securerandom'
|
|
11
|
-
end
|
|
6
|
+
Bundler.require :default, :test
|
|
12
7
|
|
|
13
8
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
14
9
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
@@ -16,7 +11,7 @@ require 'ruby-saml'
|
|
|
16
11
|
|
|
17
12
|
ENV["ruby-saml/testing"] = "1"
|
|
18
13
|
|
|
19
|
-
class
|
|
14
|
+
class Test::Unit::TestCase
|
|
20
15
|
def fixture(document, base64 = true)
|
|
21
16
|
response = Dir.glob(File.join(File.dirname(__FILE__), "responses", "#{document}*")).first
|
|
22
17
|
if base64 && response =~ /\.xml$/
|
|
@@ -26,48 +21,32 @@ class Minitest::Test
|
|
|
26
21
|
end
|
|
27
22
|
end
|
|
28
23
|
|
|
29
|
-
def random_id
|
|
30
|
-
RUBY_VERSION < '1.9' ? "_#{UUID.new.generate}" : "_#{SecureRandom.uuid}"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def read_invalid_response(response)
|
|
34
|
-
File.read(File.join(File.dirname(__FILE__), "responses", "invalids", response))
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def read_response(response)
|
|
38
|
-
File.read(File.join(File.dirname(__FILE__), "responses", response))
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def read_certificate(certificate)
|
|
42
|
-
File.read(File.join(File.dirname(__FILE__), "certificates", certificate))
|
|
43
|
-
end
|
|
44
|
-
|
|
45
24
|
def response_document
|
|
46
|
-
@response_document ||=
|
|
25
|
+
@response_document ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response1.xml.base64'))
|
|
47
26
|
end
|
|
48
27
|
|
|
49
28
|
def response_document_2
|
|
50
|
-
@response_document2 ||=
|
|
29
|
+
@response_document2 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response2.xml.base64'))
|
|
51
30
|
end
|
|
52
31
|
|
|
53
32
|
def response_document_3
|
|
54
|
-
@response_document3 ||=
|
|
33
|
+
@response_document3 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response3.xml.base64'))
|
|
55
34
|
end
|
|
56
35
|
|
|
57
36
|
def response_document_4
|
|
58
|
-
@response_document4 ||=
|
|
37
|
+
@response_document4 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response4.xml.base64'))
|
|
59
38
|
end
|
|
60
39
|
|
|
61
40
|
def response_document_5
|
|
62
|
-
@response_document5 ||=
|
|
41
|
+
@response_document5 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response5.xml.base64'))
|
|
63
42
|
end
|
|
64
43
|
|
|
65
44
|
def r1_response_document_6
|
|
66
|
-
@response_document6 ||=
|
|
45
|
+
@response_document6 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'r1_response6.xml.base64'))
|
|
67
46
|
end
|
|
68
47
|
|
|
69
48
|
def ampersands_response
|
|
70
|
-
@
|
|
49
|
+
@ampersands_response ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response_with_ampersands.xml.base64'))
|
|
71
50
|
end
|
|
72
51
|
|
|
73
52
|
def response_document_6
|
|
@@ -77,20 +56,8 @@ class Minitest::Test
|
|
|
77
56
|
Base64.encode64(doc)
|
|
78
57
|
end
|
|
79
58
|
|
|
80
|
-
def
|
|
81
|
-
@
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def response_document_valid_signed
|
|
85
|
-
response_document_valid_signed ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'valid_response.xml.base64'))
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def response_document_valid_signed_without_x509certificate
|
|
89
|
-
@response_document_valid_signed_without_x509certificate ||= read_response("valid_response_without_x509certificate.xml.base64")
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def response_document_without_recipient
|
|
93
|
-
@response_document_without_recipient ||= read_response("response_with_undefined_recipient.xml.base64")
|
|
59
|
+
def response_document_7
|
|
60
|
+
@response_document7 ||= Base64.encode64(File.read(File.join(File.dirname(__FILE__), 'responses', 'response_no_cert_and_encrypted_attrs.xml')))
|
|
94
61
|
end
|
|
95
62
|
|
|
96
63
|
def wrapped_response_2
|
|
@@ -101,87 +68,45 @@ class Minitest::Test
|
|
|
101
68
|
@signature_fingerprint1 ||= "C5:19:85:D9:47:F1:BE:57:08:20:25:05:08:46:EB:27:F6:CA:B7:83"
|
|
102
69
|
end
|
|
103
70
|
|
|
104
|
-
def signature_fingerprint_valid_res
|
|
105
|
-
@signature_fingerprint1 ||= "4b68c453c7d994aad9025c99d5efcf566287fe8d"
|
|
106
|
-
end
|
|
107
|
-
|
|
108
71
|
def signature_1
|
|
109
|
-
@signature1 ||=
|
|
72
|
+
@signature1 ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'certificate1'))
|
|
110
73
|
end
|
|
111
74
|
|
|
112
75
|
def r1_signature_2
|
|
113
|
-
@signature2 ||=
|
|
76
|
+
@signature2 ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'r1_certificate2_base64'))
|
|
114
77
|
end
|
|
115
78
|
|
|
116
|
-
def
|
|
117
|
-
@
|
|
79
|
+
def idp_metadata
|
|
80
|
+
@idp_metadata ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'idp_descriptor.xml'))
|
|
118
81
|
end
|
|
119
82
|
|
|
120
|
-
def
|
|
121
|
-
@
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def response_multiple_attr_values
|
|
129
|
-
@response_multiple_attr_values = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
|
83
|
+
def logout_request_document
|
|
84
|
+
unless @logout_request_document
|
|
85
|
+
xml = File.read(File.join(File.dirname(__FILE__), 'responses', 'slo_request.xml'))
|
|
86
|
+
deflated = Zlib::Deflate.deflate(xml, 9)[2..-5]
|
|
87
|
+
@logout_request_document = Base64.encode64(deflated)
|
|
88
|
+
end
|
|
89
|
+
@logout_request_document
|
|
130
90
|
end
|
|
131
91
|
|
|
132
92
|
def ruby_saml_cert
|
|
133
93
|
@ruby_saml_cert ||= OpenSSL::X509::Certificate.new(ruby_saml_cert_text)
|
|
134
94
|
end
|
|
135
95
|
|
|
136
|
-
def ruby_saml_cert2
|
|
137
|
-
@ruby_saml_cert2 ||= OpenSSL::X509::Certificate.new(ruby_saml_cert_text2)
|
|
138
|
-
end
|
|
139
|
-
|
|
140
96
|
def ruby_saml_cert_fingerprint
|
|
141
97
|
@ruby_saml_cert_fingerprint ||= Digest::SHA1.hexdigest(ruby_saml_cert.to_der).scan(/../).join(":")
|
|
142
98
|
end
|
|
143
99
|
|
|
144
100
|
def ruby_saml_cert_text
|
|
145
|
-
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
def ruby_saml_cert_text2
|
|
149
|
-
read_certificate("ruby-saml-2.crt")
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def ruby_saml_key_text
|
|
153
|
-
read_certificate("ruby-saml.key")
|
|
101
|
+
File.read(File.join(File.dirname(__FILE__), 'certificates', 'ruby-saml.crt'))
|
|
154
102
|
end
|
|
155
103
|
|
|
156
104
|
def ruby_saml_key
|
|
157
105
|
@ruby_saml_key ||= OpenSSL::PKey::RSA.new(ruby_saml_key_text)
|
|
158
106
|
end
|
|
159
107
|
|
|
160
|
-
def
|
|
161
|
-
File.read(File.join(File.dirname(__FILE__),
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def decode_saml_request_payload(unauth_url)
|
|
165
|
-
payload = CGI.unescape(unauth_url.split("SAMLRequest=").last)
|
|
166
|
-
decoded = Base64.decode64(payload)
|
|
167
|
-
|
|
168
|
-
zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
|
169
|
-
inflated = zstream.inflate(decoded)
|
|
170
|
-
zstream.finish
|
|
171
|
-
zstream.close
|
|
172
|
-
inflated
|
|
108
|
+
def ruby_saml_key_text
|
|
109
|
+
File.read(File.join(File.dirname(__FILE__), 'certificates', 'ruby-saml.key'))
|
|
173
110
|
end
|
|
174
111
|
|
|
175
|
-
# decodes a base64 encoded SAML response for use in SloLogoutresponse tests
|
|
176
|
-
#
|
|
177
|
-
def decode_saml_response_payload(unauth_url)
|
|
178
|
-
payload = CGI.unescape(unauth_url.split("SAMLResponse=").last)
|
|
179
|
-
decoded = Base64.decode64(payload)
|
|
180
|
-
|
|
181
|
-
zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
|
182
|
-
inflated = zstream.inflate(decoded)
|
|
183
|
-
zstream.finish
|
|
184
|
-
zstream.close
|
|
185
|
-
inflated
|
|
186
|
-
end
|
|
187
112
|
end
|
data/test/xml_security_test.rb
CHANGED
|
@@ -1,197 +1,112 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'xml_security'
|
|
2
3
|
|
|
3
|
-
class XmlSecurityTest <
|
|
4
|
+
class XmlSecurityTest < Test::Unit::TestCase
|
|
4
5
|
include XMLSecurity
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
let(:settings) { OneLogin::RubySaml::Settings.new() }
|
|
11
|
-
|
|
12
|
-
before do
|
|
13
|
-
@base64cert = document.elements["//ds:X509Certificate"].text
|
|
7
|
+
context "XmlSecurity" do
|
|
8
|
+
setup do
|
|
9
|
+
@document = XMLSecurity::SignedDocument.new(Base64.decode64(response_document))
|
|
10
|
+
@base64cert = @document.elements["//ds:X509Certificate"].text
|
|
14
11
|
end
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
assert
|
|
13
|
+
should "should run validate without throwing NS related exceptions" do
|
|
14
|
+
assert !@document.validate_signature(@base64cert, true)
|
|
18
15
|
end
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
document.validate_signature(@base64cert, false)
|
|
17
|
+
should "should run validate with throwing NS related exceptions" do
|
|
18
|
+
assert_raise(OneLogin::RubySaml::ValidationError) do
|
|
19
|
+
@document.validate_signature(@base64cert, false)
|
|
23
20
|
end
|
|
24
21
|
end
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
should "not raise an error when softly validating the document multiple times" do
|
|
24
|
+
assert_nothing_raised do
|
|
25
|
+
2.times { @document.validate_signature(@base64cert, true) }
|
|
26
|
+
end
|
|
28
27
|
end
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
should "not raise an error when softly validating the document and the X509Certificate is missing" do
|
|
30
|
+
response = Base64.decode64(response_document)
|
|
31
|
+
response.sub!(/<ds:X509Certificate>.*<\/ds:X509Certificate>/, "")
|
|
32
|
+
document = XMLSecurity::SignedDocument.new(response)
|
|
33
|
+
assert_nothing_raised do
|
|
34
|
+
assert !document.validate_document("a fingerprint", true) # The fingerprint isn't relevant to this test
|
|
35
|
+
end
|
|
34
36
|
end
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
exception =
|
|
38
|
-
document.validate_document("no:fi:ng:er:pr:in:t", false)
|
|
38
|
+
should "should raise Fingerprint mismatch" do
|
|
39
|
+
exception = assert_raise(OneLogin::RubySaml::ValidationError) do
|
|
40
|
+
@document.validate_document("no:fi:ng:er:pr:in:t", false)
|
|
39
41
|
end
|
|
40
42
|
assert_equal("Fingerprint mismatch", exception.message)
|
|
43
|
+
assert @document.errors.include? "Fingerprint mismatch"
|
|
41
44
|
end
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
exception =
|
|
45
|
-
document.validate_signature(@base64cert, false)
|
|
46
|
+
should "should raise Digest mismatch" do
|
|
47
|
+
exception = assert_raise(OneLogin::RubySaml::ValidationError) do
|
|
48
|
+
@document.validate_signature(@base64cert, false)
|
|
46
49
|
end
|
|
47
50
|
assert_equal("Digest mismatch", exception.message)
|
|
51
|
+
assert @document.errors.include? "Digest mismatch"
|
|
48
52
|
end
|
|
49
53
|
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
should "should raise Key validation error" do
|
|
55
|
+
response = Base64.decode64(response_document)
|
|
56
|
+
response.sub!("<ds:DigestValue>pJQ7MS/ek4KRRWGmv/H43ReHYMs=</ds:DigestValue>",
|
|
52
57
|
"<ds:DigestValue>b9xsAXLsynugg3Wc1CI3kpWku+0=</ds:DigestValue>")
|
|
53
|
-
|
|
54
|
-
base64cert =
|
|
55
|
-
exception =
|
|
56
|
-
|
|
58
|
+
document = XMLSecurity::SignedDocument.new(response)
|
|
59
|
+
base64cert = document.elements["//ds:X509Certificate"].text
|
|
60
|
+
exception = assert_raise(OneLogin::RubySaml::ValidationError) do
|
|
61
|
+
document.validate_signature(base64cert, false)
|
|
57
62
|
end
|
|
58
63
|
assert_equal("Key validation error", exception.message)
|
|
64
|
+
assert document.errors.include? "Key validation error"
|
|
59
65
|
end
|
|
60
66
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
base64cert =
|
|
64
|
-
assert
|
|
67
|
+
should "correctly obtain the digest method with alternate namespace declaration" do
|
|
68
|
+
document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_xmlns, false))
|
|
69
|
+
base64cert = document.elements["//X509Certificate"].text
|
|
70
|
+
assert document.validate_signature(base64cert, false)
|
|
65
71
|
end
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
should "raise validation error when the X509Certificate is missing" do
|
|
74
|
+
response = Base64.decode64(response_document)
|
|
75
|
+
response.sub!(/<ds:X509Certificate>.*<\/ds:X509Certificate>/, "")
|
|
76
|
+
document = XMLSecurity::SignedDocument.new(response)
|
|
77
|
+
exception = assert_raise(OneLogin::RubySaml::ValidationError) do
|
|
78
|
+
document.validate_document("a fingerprint", false) # The fingerprint isn't relevant to this test
|
|
72
79
|
end
|
|
73
|
-
assert_equal("Certificate element missing in response (ds:X509Certificate)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
it "invalidaties when the X509Certificate is missing and the cert is provided but mismatches" do
|
|
77
|
-
decoded_response.sub!(/<ds:X509Certificate>.*<\/ds:X509Certificate>/, "")
|
|
78
|
-
mod_document = XMLSecurity::SignedDocument.new(decoded_response)
|
|
79
|
-
cert = OpenSSL::X509::Certificate.new(ruby_saml_cert)
|
|
80
|
-
assert !mod_document.validate_document("a fingerprint", true, :cert => cert) # The fingerprint isn't relevant to this test
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
describe "#canon_algorithm" do
|
|
85
|
-
it "C14N_EXCLUSIVE_1_0" do
|
|
86
|
-
canon_algorithm = Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0
|
|
87
|
-
assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/2001/10/xml-exc-c14n#")
|
|
88
|
-
assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/2001/10/xml-exc-c14n#WithComments")
|
|
89
|
-
assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("other")
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
it "C14N_1_0" do
|
|
93
|
-
canon_algorithm = Nokogiri::XML::XML_C14N_1_0
|
|
94
|
-
assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/TR/2001/REC-xml-c14n-20010315")
|
|
95
|
-
assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments")
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
it "XML_C14N_1_1" do
|
|
99
|
-
canon_algorithm = Nokogiri::XML::XML_C14N_1_1
|
|
100
|
-
assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/2006/12/xml-c14n11")
|
|
101
|
-
assert_equal canon_algorithm, XMLSecurity::BaseDocument.new.canon_algorithm("http://www.w3.org/2006/12/xml-c14n11#WithComments")
|
|
80
|
+
assert_equal("Certificate element missing in response (ds:X509Certificate)", exception.message)
|
|
102
81
|
end
|
|
103
82
|
end
|
|
104
83
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2000/09/xmldsig#sha1")
|
|
110
|
-
assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("other")
|
|
84
|
+
context "Algorithms" do
|
|
85
|
+
should "validate using SHA1" do
|
|
86
|
+
@document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha1, false))
|
|
87
|
+
assert @document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
|
|
111
88
|
end
|
|
112
89
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#sha256")
|
|
90
|
+
should "validate using SHA256" do
|
|
91
|
+
@document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha256, false))
|
|
92
|
+
assert @document.validate_document("28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA")
|
|
117
93
|
end
|
|
118
94
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#sha384")
|
|
95
|
+
should "validate using SHA384" do
|
|
96
|
+
@document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha384, false))
|
|
97
|
+
assert @document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
|
|
123
98
|
end
|
|
124
99
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
assert_equal alg, XMLSecurity::BaseDocument.new.algorithm("http://www.w3.org/2001/04/xmldsig-more#sha512")
|
|
100
|
+
should "validate using SHA512" do
|
|
101
|
+
@document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha512, false))
|
|
102
|
+
assert @document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
|
|
129
103
|
end
|
|
130
104
|
end
|
|
131
105
|
|
|
132
|
-
|
|
133
|
-
let(:response_fingerprint_test) { OneLogin::RubySaml::Response.new(fixture(:adfs_response_sha1, false)) }
|
|
134
|
-
|
|
135
|
-
it "validate using SHA1" do
|
|
136
|
-
sha1_fingerprint = "F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72"
|
|
137
|
-
sha1_fingerprint_downcase = "f13c6b80905a030e6c913e5d15faddb016454872"
|
|
138
|
-
|
|
139
|
-
assert response_fingerprint_test.document.validate_document(sha1_fingerprint)
|
|
140
|
-
assert response_fingerprint_test.document.validate_document(sha1_fingerprint, true, :fingerprint_alg => XMLSecurity::Document::SHA1)
|
|
141
|
-
|
|
142
|
-
assert response_fingerprint_test.document.validate_document(sha1_fingerprint_downcase)
|
|
143
|
-
assert response_fingerprint_test.document.validate_document(sha1_fingerprint_downcase, true, :fingerprint_alg => XMLSecurity::Document::SHA1)
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
it "validate using SHA256" do
|
|
147
|
-
sha256_fingerprint = "C4:C6:BD:41:EC:AD:57:97:CE:7B:7D:80:06:C3:E4:30:53:29:02:0B:DD:2D:47:02:9E:BD:85:AD:93:02:45:21"
|
|
148
|
-
|
|
149
|
-
assert !response_fingerprint_test.document.validate_document(sha256_fingerprint)
|
|
150
|
-
assert response_fingerprint_test.document.validate_document(sha256_fingerprint, true, :fingerprint_alg => XMLSecurity::Document::SHA256)
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
it "validate using SHA384" do
|
|
154
|
-
sha384_fingerprint = "98:FE:17:90:31:E7:68:18:8A:65:4D:DA:F5:76:E2:09:97:BE:8B:E3:7E:AA:8D:63:64:7C:0C:38:23:9A:AC:A2:EC:CE:48:A6:74:4D:E0:4C:50:80:40:B4:8D:55:14:14"
|
|
155
|
-
|
|
156
|
-
assert !response_fingerprint_test.document.validate_document(sha384_fingerprint)
|
|
157
|
-
assert response_fingerprint_test.document.validate_document(sha384_fingerprint, true, :fingerprint_alg => XMLSecurity::Document::SHA384)
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
it "validate using SHA512" do
|
|
161
|
-
sha512_fingerprint = "5A:AE:BA:D0:BA:9D:1E:25:05:01:1E:1A:C9:E9:FF:DB:ED:FA:6E:F7:52:EB:45:49:BD:DB:06:D8:A3:7E:CC:63:3A:04:A2:DD:DF:EE:61:05:D9:58:95:2A:77:17:30:4B:EB:4A:9F:48:4A:44:1C:D0:9E:0B:1E:04:77:FD:A3:D2"
|
|
106
|
+
context "XmlSecurity::SignedDocument" do
|
|
162
107
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
describe "Signature Algorithms" do
|
|
170
|
-
it "validate using SHA1" do
|
|
171
|
-
document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha1, false))
|
|
172
|
-
assert document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
it "validate using SHA256" do
|
|
176
|
-
document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha256, false))
|
|
177
|
-
assert document.validate_document("28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA")
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
it "validate using SHA384" do
|
|
181
|
-
document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha384, false))
|
|
182
|
-
assert document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
it "validate using SHA512" do
|
|
186
|
-
document = XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha512, false))
|
|
187
|
-
assert document.validate_document("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
describe "XmlSecurity::SignedDocument" do
|
|
192
|
-
|
|
193
|
-
describe "#extract_inclusive_namespaces" do
|
|
194
|
-
it "support explicit namespace resolution for exclusive canonicalization" do
|
|
108
|
+
context "#extract_inclusive_namespaces" do
|
|
109
|
+
should "support explicit namespace resolution for exclusive canonicalization" do
|
|
195
110
|
response = fixture(:open_saml_response, false)
|
|
196
111
|
document = XMLSecurity::SignedDocument.new(response)
|
|
197
112
|
inclusive_namespaces = document.send(:extract_inclusive_namespaces)
|
|
@@ -199,7 +114,7 @@ class XmlSecurityTest < Minitest::Test
|
|
|
199
114
|
assert_equal %w[ xs ], inclusive_namespaces
|
|
200
115
|
end
|
|
201
116
|
|
|
202
|
-
|
|
117
|
+
should "support implicit namespace resolution for exclusive canonicalization" do
|
|
203
118
|
response = fixture(:no_signature_ns, false)
|
|
204
119
|
document = XMLSecurity::SignedDocument.new(response)
|
|
205
120
|
inclusive_namespaces = document.send(:extract_inclusive_namespaces)
|
|
@@ -207,245 +122,107 @@ class XmlSecurityTest < Minitest::Test
|
|
|
207
122
|
assert_equal %w[ #default saml ds xs xsi ], inclusive_namespaces
|
|
208
123
|
end
|
|
209
124
|
|
|
210
|
-
|
|
211
|
-
|
|
125
|
+
should_eventually 'support inclusive canonicalization' do
|
|
126
|
+
|
|
212
127
|
response = OneLogin::RubySaml::Response.new(fixture("tdnf_response.xml"))
|
|
213
128
|
response.stubs(:conditions).returns(nil)
|
|
214
129
|
assert !response.is_valid?
|
|
130
|
+
settings = OneLogin::RubySaml::Settings.new
|
|
215
131
|
assert !response.is_valid?
|
|
216
132
|
response.settings = settings
|
|
217
133
|
assert !response.is_valid?
|
|
218
134
|
settings.idp_cert_fingerprint = "e6 38 9a 20 b7 4f 13 db 6a bc b1 42 6a e7 52 1d d6 56 d4 1b".upcase.gsub(" ", ":")
|
|
219
|
-
assert response.
|
|
135
|
+
assert response.validate!
|
|
220
136
|
end
|
|
221
137
|
|
|
222
|
-
|
|
138
|
+
should "return an empty list when inclusive namespace element is missing" do
|
|
223
139
|
response = fixture(:no_signature_ns, false)
|
|
224
140
|
response.slice! %r{<InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="#default saml ds xs xsi"/>}
|
|
225
141
|
|
|
226
142
|
document = XMLSecurity::SignedDocument.new(response)
|
|
227
143
|
inclusive_namespaces = document.send(:extract_inclusive_namespaces)
|
|
228
144
|
|
|
229
|
-
assert inclusive_namespaces.
|
|
145
|
+
assert inclusive_namespaces.empty?
|
|
230
146
|
end
|
|
231
147
|
end
|
|
232
148
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
settings
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
end
|
|
149
|
+
context "XMLSecurity::DSIG" do
|
|
150
|
+
should "sign a AuthNRequest" do
|
|
151
|
+
settings = OneLogin::RubySaml::Settings.new({
|
|
152
|
+
:idp_sso_target_url => "https://idp.example.com/sso",
|
|
153
|
+
:protocol_binding => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
|
|
154
|
+
:issuer => "https://sp.example.com/saml2",
|
|
155
|
+
:assertion_consumer_service_url => "https://sp.example.com/acs"
|
|
156
|
+
})
|
|
242
157
|
|
|
243
|
-
it "sign an AuthNRequest" do
|
|
244
158
|
request = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
|
|
245
159
|
request.sign_document(ruby_saml_key, ruby_saml_cert)
|
|
246
|
-
# verify our signature
|
|
247
|
-
signed_doc = XMLSecurity::SignedDocument.new(request.to_s)
|
|
248
|
-
assert signed_doc.validate_document(ruby_saml_cert_fingerprint, false)
|
|
249
160
|
|
|
250
|
-
request2 = OneLogin::RubySaml::Authrequest.new.create_authentication_xml_doc(settings)
|
|
251
|
-
request2.sign_document(ruby_saml_key, ruby_saml_cert_text)
|
|
252
161
|
# verify our signature
|
|
253
|
-
|
|
254
|
-
|
|
162
|
+
signed_doc = XMLSecurity::SignedDocument.new(request.to_s)
|
|
163
|
+
signed_doc.validate_document(ruby_saml_cert_fingerprint, false)
|
|
255
164
|
end
|
|
256
165
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
166
|
+
should "sign a LogoutRequest" do
|
|
167
|
+
settings = OneLogin::RubySaml::Settings.new({
|
|
168
|
+
:idp_slo_target_url => "https://idp.example.com/slo",
|
|
169
|
+
:protocol_binding => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
|
|
170
|
+
:issuer => "https://sp.example.com/saml2",
|
|
171
|
+
:single_logout_service_url => "https://sp.example.com/sls"
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
request = OneLogin::RubySaml::Logoutrequest.new.create_logout_request_xml_doc(settings)
|
|
175
|
+
request.sign_document(ruby_saml_key, ruby_saml_cert)
|
|
260
176
|
|
|
261
177
|
# verify our signature
|
|
262
178
|
signed_doc = XMLSecurity::SignedDocument.new(request.to_s)
|
|
263
|
-
|
|
179
|
+
signed_doc.validate_document(ruby_saml_cert_fingerprint, false)
|
|
264
180
|
end
|
|
265
181
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
logout_request2 = OneLogin::RubySaml::Logoutrequest.new.create_logout_request_xml_doc(settings)
|
|
274
|
-
logout_request2.sign_document(ruby_saml_key, ruby_saml_cert_text)
|
|
275
|
-
# verify our signature
|
|
276
|
-
signed_doc2 = XMLSecurity::SignedDocument.new(logout_request2.to_s)
|
|
277
|
-
signed_doc2.validate_document(ruby_saml_cert_fingerprint, false)
|
|
278
|
-
assert signed_doc2.validate_document(ruby_saml_cert_fingerprint, false)
|
|
279
|
-
end
|
|
182
|
+
should "sign a LogoutResponse" do
|
|
183
|
+
settings = OneLogin::RubySaml::Settings.new({
|
|
184
|
+
:idp_slo_target_url => "https://idp.example.com/slo",
|
|
185
|
+
:protocol_binding => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
|
|
186
|
+
:issuer => "https://sp.example.com/saml2",
|
|
187
|
+
:single_logout_service_url => "https://sp.example.com/sls"
|
|
188
|
+
})
|
|
280
189
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
logout_response.sign_document(ruby_saml_key, ruby_saml_cert)
|
|
284
|
-
# verify our signature
|
|
285
|
-
signed_doc = XMLSecurity::SignedDocument.new(logout_response.to_s)
|
|
286
|
-
assert signed_doc.validate_document(ruby_saml_cert_fingerprint, false)
|
|
190
|
+
response = OneLogin::RubySaml::SloLogoutresponse.new.create_logout_response_xml_doc(settings, 'request_id_example', "Custom Logout Message")
|
|
191
|
+
response.sign_document(ruby_saml_key, ruby_saml_cert)
|
|
287
192
|
|
|
288
|
-
logout_response2 = OneLogin::RubySaml::SloLogoutresponse.new.create_logout_response_xml_doc(settings, 'request_id_example', "Custom Logout Message")
|
|
289
|
-
logout_response2.sign_document(ruby_saml_key, ruby_saml_cert_text)
|
|
290
193
|
# verify our signature
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
assert signed_doc2.validate_document(ruby_saml_cert_fingerprint, false)
|
|
194
|
+
signed_doc = XMLSecurity::SignedDocument.new(response.to_s)
|
|
195
|
+
signed_doc.validate_document(ruby_saml_cert_fingerprint, false)
|
|
294
196
|
end
|
|
295
197
|
end
|
|
296
198
|
|
|
297
|
-
|
|
298
|
-
|
|
199
|
+
context "StarfieldTMS" do
|
|
200
|
+
setup do
|
|
299
201
|
@response = OneLogin::RubySaml::Response.new(fixture(:starfield_response))
|
|
300
|
-
@response.settings = OneLogin::RubySaml::Settings.new(
|
|
202
|
+
@response.settings = OneLogin::RubySaml::Settings.new(
|
|
203
|
+
:idp_cert_fingerprint => "8D:BA:53:8E:A3:B6:F9:F1:69:6C:BB:D9:D8:BD:41:B3:AC:4F:9D:4D"
|
|
204
|
+
)
|
|
301
205
|
end
|
|
302
206
|
|
|
303
|
-
|
|
207
|
+
should "be able to validate a good response" do
|
|
304
208
|
Timecop.freeze Time.parse('2012-11-28 17:55:00 UTC') do
|
|
305
209
|
assert @response.validate!
|
|
306
210
|
end
|
|
307
211
|
end
|
|
308
212
|
|
|
309
|
-
|
|
213
|
+
should "fail before response is valid" do
|
|
310
214
|
Timecop.freeze Time.parse('2012-11-20 17:55:00 UTC') do
|
|
311
215
|
assert ! @response.is_valid?
|
|
312
216
|
end
|
|
313
217
|
end
|
|
314
218
|
|
|
315
|
-
|
|
219
|
+
should "fail after response expires" do
|
|
316
220
|
Timecop.freeze Time.parse('2012-11-30 17:55:00 UTC') do
|
|
317
221
|
assert ! @response.is_valid?
|
|
318
222
|
end
|
|
319
223
|
end
|
|
320
224
|
end
|
|
321
225
|
|
|
322
|
-
describe '#validate_document' do
|
|
323
|
-
describe 'with valid document' do
|
|
324
|
-
describe 'when response has signed message and assertion' do
|
|
325
|
-
let(:document_data) { read_response('response_with_signed_message_and_assertion.xml') }
|
|
326
|
-
let(:document) { OneLogin::RubySaml::Response.new(document_data).document }
|
|
327
|
-
let(:fingerprint) { '4b68c453c7d994aad9025c99d5efcf566287fe8d' }
|
|
328
|
-
|
|
329
|
-
it 'is valid' do
|
|
330
|
-
assert document.validate_document(fingerprint, true), 'Document should be valid'
|
|
331
|
-
end
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
describe 'when response has signed assertion' do
|
|
335
|
-
let(:document_data) { read_response('response_with_signed_assertion_3.xml') }
|
|
336
|
-
let(:document) { OneLogin::RubySaml::Response.new(document_data).document }
|
|
337
|
-
let(:fingerprint) { '4b68c453c7d994aad9025c99d5efcf566287fe8d' }
|
|
338
|
-
|
|
339
|
-
it 'is valid' do
|
|
340
|
-
assert document.validate_document(fingerprint, true), 'Document should be valid'
|
|
341
|
-
end
|
|
342
|
-
end
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
describe 'signature_wrapping_attack' do
|
|
346
|
-
let(:document_data) { read_invalid_response("signature_wrapping_attack.xml.base64") }
|
|
347
|
-
let(:document) { OneLogin::RubySaml::Response.new(document_data).document }
|
|
348
|
-
let(:fingerprint) { 'afe71c28ef740bc87425be13a2263d37971da1f9' }
|
|
349
|
-
|
|
350
|
-
it 'is invalid' do
|
|
351
|
-
assert !document.validate_document(fingerprint, true), 'Document should be invalid'
|
|
352
|
-
end
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
describe 'signature wrapping attack - doubled SAML response body' do
|
|
356
|
-
let(:document_data) { read_invalid_response("response_with_doubled_signed_assertion.xml") }
|
|
357
|
-
let(:document) { OneLogin::RubySaml::Response.new(document_data) }
|
|
358
|
-
let(:fingerprint) { '4b68c453c7d994aad9025c99d5efcf566287fe8d' }
|
|
359
|
-
|
|
360
|
-
it 'is valid, but the unsigned information is ignored in favour of the signed information' do
|
|
361
|
-
assert document.document.validate_document(fingerprint, true), 'Document should be valid'
|
|
362
|
-
assert_equal 'someone@example.org', document.name_id, 'Document should expose only signed, valid details'
|
|
363
|
-
end
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
describe 'signature wrapping attack - concealed SAML response body' do
|
|
367
|
-
let(:document_data) { read_invalid_response("response_with_concealed_signed_assertion.xml") }
|
|
368
|
-
let(:document) { OneLogin::RubySaml::Response.new(document_data) }
|
|
369
|
-
let(:fingerprint) { '4b68c453c7d994aad9025c99d5efcf566287fe8d' }
|
|
370
|
-
|
|
371
|
-
it 'is valid, but fails to retrieve information' do
|
|
372
|
-
assert document.document.validate_document(fingerprint, true), 'Document should be valid'
|
|
373
|
-
assert document.name_id.nil?, 'Document should expose only signed, valid details'
|
|
374
|
-
end
|
|
375
|
-
end
|
|
376
|
-
|
|
377
|
-
describe 'when response has no cert and you provide cert' do
|
|
378
|
-
let(:document) { OneLogin::RubySaml::Response.new(response_document_valid_signed_without_x509certificate).document }
|
|
379
|
-
let(:idp_cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) }
|
|
380
|
-
let(:options) { {} }
|
|
381
|
-
|
|
382
|
-
it 'is valid' do
|
|
383
|
-
options[:cert] = idp_cert
|
|
384
|
-
assert document.document.validate_document(idp_cert, true, options), 'Document should be valid'
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
it 'is valid if cert text instead x509cert provided' do
|
|
388
|
-
options[:cert] = ruby_saml_cert_text
|
|
389
|
-
assert document.document.validate_document(idp_cert, true, options), 'Document should be valid'
|
|
390
|
-
end
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
describe 'when response has no cert and you dont provide cert' do
|
|
394
|
-
let(:document) { OneLogin::RubySaml::Response.new(response_document_valid_signed_without_x509certificate).document }
|
|
395
|
-
let(:options) { {} }
|
|
396
|
-
let(:idp_cert) { nil }
|
|
397
|
-
|
|
398
|
-
it 'is invalid' do
|
|
399
|
-
options[:cert] = idp_cert
|
|
400
|
-
assert !document.document.validate_document(idp_cert, true, options), 'Document should not be valid'
|
|
401
|
-
end
|
|
402
|
-
|
|
403
|
-
it 'is invalid and error raised' do
|
|
404
|
-
options[:cert] = idp_cert
|
|
405
|
-
assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
406
|
-
document.document.validate_document(idp_cert, false, options)
|
|
407
|
-
end
|
|
408
|
-
end
|
|
409
|
-
end
|
|
410
|
-
end
|
|
411
|
-
|
|
412
|
-
describe '#validate_document_with_cert' do
|
|
413
|
-
describe 'with valid document ' do
|
|
414
|
-
describe 'when response has cert' do
|
|
415
|
-
let(:document_data) { read_response('response_with_signed_message_and_assertion.xml') }
|
|
416
|
-
let(:document) { OneLogin::RubySaml::Response.new(document_data).document }
|
|
417
|
-
let(:idp_cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) }
|
|
418
|
-
let(:fingerprint) { '4b68c453c7d994aad9025c99d5efcf566287fe8d' }
|
|
419
|
-
|
|
420
|
-
it 'is valid' do
|
|
421
|
-
assert document.validate_document_with_cert(idp_cert), 'Document should be valid'
|
|
422
|
-
end
|
|
423
|
-
end
|
|
424
|
-
|
|
425
|
-
describe 'when response has no cert and you provide cert' do
|
|
426
|
-
let(:document) { OneLogin::RubySaml::Response.new(response_document_valid_signed_without_x509certificate).document }
|
|
427
|
-
let(:idp_cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) }
|
|
428
|
-
|
|
429
|
-
it 'is valid' do
|
|
430
|
-
assert document.validate_document_with_cert(idp_cert), 'Document should be valid'
|
|
431
|
-
end
|
|
432
|
-
end
|
|
433
|
-
|
|
434
|
-
describe 'when response has no cert and you dont provide cert' do
|
|
435
|
-
let(:document) { OneLogin::RubySaml::Response.new(response_document_valid_signed_without_x509certificate).document }
|
|
436
|
-
let(:idp_cert) { nil }
|
|
437
|
-
|
|
438
|
-
it 'is invalid' do
|
|
439
|
-
assert !document.validate_document_with_cert(idp_cert), 'Document should not be valid'
|
|
440
|
-
end
|
|
441
|
-
|
|
442
|
-
it 'is invalid and error raised' do
|
|
443
|
-
assert_raises(OneLogin::RubySaml::ValidationError) do
|
|
444
|
-
document.validate_document_with_cert(idp_cert, false)
|
|
445
|
-
end
|
|
446
|
-
end
|
|
447
|
-
end
|
|
448
|
-
end
|
|
449
|
-
end
|
|
450
226
|
end
|
|
227
|
+
|
|
451
228
|
end
|