ciam-es 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/Gemfile +4 -0
  4. data/README.md +127 -0
  5. data/ciam-es.gemspec +23 -0
  6. data/lib/ciam-es.rb +14 -0
  7. data/lib/ciam/ruby-saml/authrequest.rb +206 -0
  8. data/lib/ciam/ruby-saml/coding.rb +34 -0
  9. data/lib/ciam/ruby-saml/error_handling.rb +27 -0
  10. data/lib/ciam/ruby-saml/logging.rb +26 -0
  11. data/lib/ciam/ruby-saml/logout_request.rb +126 -0
  12. data/lib/ciam/ruby-saml/logout_response.rb +132 -0
  13. data/lib/ciam/ruby-saml/metadata.rb +509 -0
  14. data/lib/ciam/ruby-saml/request.rb +81 -0
  15. data/lib/ciam/ruby-saml/response.rb +683 -0
  16. data/lib/ciam/ruby-saml/settings.rb +89 -0
  17. data/lib/ciam/ruby-saml/utils.rb +225 -0
  18. data/lib/ciam/ruby-saml/validation_error.rb +7 -0
  19. data/lib/ciam/ruby-saml/version.rb +5 -0
  20. data/lib/ciam/xml_security.rb +166 -0
  21. data/lib/ciam/xml_security_new.rb +373 -0
  22. data/lib/schemas/saml20assertion_schema.xsd +283 -0
  23. data/lib/schemas/saml20protocol_schema.xsd +302 -0
  24. data/lib/schemas/xenc_schema.xsd +146 -0
  25. data/lib/schemas/xmldsig_schema.xsd +318 -0
  26. data/test/certificates/certificate1 +12 -0
  27. data/test/logoutrequest_test.rb +98 -0
  28. data/test/request_test.rb +53 -0
  29. data/test/response_test.rb +219 -0
  30. data/test/responses/adfs_response_sha1.xml +46 -0
  31. data/test/responses/adfs_response_sha256.xml +46 -0
  32. data/test/responses/adfs_response_sha384.xml +46 -0
  33. data/test/responses/adfs_response_sha512.xml +46 -0
  34. data/test/responses/no_signature_ns.xml +48 -0
  35. data/test/responses/open_saml_response.xml +56 -0
  36. data/test/responses/response1.xml.base64 +1 -0
  37. data/test/responses/response2.xml.base64 +79 -0
  38. data/test/responses/response3.xml.base64 +66 -0
  39. data/test/responses/response4.xml.base64 +93 -0
  40. data/test/responses/response5.xml.base64 +102 -0
  41. data/test/responses/response_with_ampersands.xml +139 -0
  42. data/test/responses/response_with_ampersands.xml.base64 +93 -0
  43. data/test/responses/simple_saml_php.xml +71 -0
  44. data/test/responses/wrapped_response_2.xml.base64 +150 -0
  45. data/test/settings_test.rb +43 -0
  46. data/test/test_helper.rb +65 -0
  47. data/test/xml_security_test.rb +123 -0
  48. metadata +145 -0
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
2
+
3
+ class SettingsTest < Test::Unit::TestCase
4
+
5
+ context "Settings" do
6
+ setup do
7
+ @settings = Ciam::Saml::Settings.new
8
+ end
9
+ should "should provide getters and settings" do
10
+ accessors = [
11
+ :assertion_consumer_service_url, :issuer, :sp_name_qualifier,
12
+ :idp_sso_target_url, :idp_cert_fingerprint, :name_identifier_format,
13
+ :idp_slo_target_url, :name_identifier_value, :sessionindex
14
+ ]
15
+
16
+ accessors.each do |accessor|
17
+ value = Kernel.rand
18
+ @settings.send("#{accessor}=".to_sym, value)
19
+ assert_equal value, @settings.send(accessor)
20
+ end
21
+ end
22
+
23
+ should "create settings from hash" do
24
+
25
+ config = {
26
+ :assertion_consumer_service_url => "http://app.muda.no/sso",
27
+ :issuer => "http://muda.no",
28
+ :sp_name_qualifier => "http://sso.muda.no",
29
+ :idp_sso_target_url => "http://sso.muda.no/sso",
30
+ :idp_slo_target_url => "http://sso.muda.no/slo",
31
+ :idp_cert_fingerprint => "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
32
+ :name_identifier_format => "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
33
+ }
34
+ @settings = Ciam::Saml::Settings.new(config)
35
+
36
+ config.each do |k,v|
37
+ assert_equal v, @settings.send(k)
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,65 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ require 'ruby-saml'
9
+
10
+ ENV["ruby-saml/testing"] = "1"
11
+
12
+ class Test::Unit::TestCase
13
+ def fixture(document, base64 = true)
14
+ response = Dir.glob(File.join(File.dirname(__FILE__), "responses", "#{document}*")).first
15
+ if base64 && response =~ /\.xml$/
16
+ Base64.encode64(File.read(response))
17
+ else
18
+ File.read(response)
19
+ end
20
+ end
21
+
22
+ def response_document
23
+ @response_document ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response1.xml.base64'))
24
+ end
25
+
26
+ def response_document_2
27
+ @response_document2 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response2.xml.base64'))
28
+ end
29
+
30
+ def response_document_3
31
+ @response_document3 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response3.xml.base64'))
32
+ end
33
+
34
+ def response_document_4
35
+ @response_document4 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response4.xml.base64'))
36
+ end
37
+
38
+ def response_document_5
39
+ @response_document5 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response5.xml.base64'))
40
+ end
41
+
42
+ def ampersands_response
43
+ @ampersands_resposne ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'response_with_ampersands.xml.base64'))
44
+ end
45
+
46
+ def response_document_6
47
+ doc = Base64.decode64(response_document)
48
+ doc.gsub!(/NotBefore=\"(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z\"/, "NotBefore=\"#{(Time.now-300).getutc.strftime("%Y-%m-%dT%XZ")}\"")
49
+ doc.gsub!(/NotOnOrAfter=\"(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z\"/, "NotOnOrAfter=\"#{(Time.now+300).getutc.strftime("%Y-%m-%dT%XZ")}\"")
50
+ Base64.encode64(doc)
51
+ end
52
+
53
+ def wrapped_response_2
54
+ @wrapped_response_2 ||= File.read(File.join(File.dirname(__FILE__), 'responses', 'wrapped_response_2.xml.base64'))
55
+ end
56
+
57
+ def signature_fingerprint_1
58
+ @signature_fingerprint1 ||= "C5:19:85:D9:47:F1:BE:57:08:20:25:05:08:46:EB:27:F6:CA:B7:83"
59
+ end
60
+
61
+ def signature_1
62
+ @signature1 ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'certificate1'))
63
+ end
64
+
65
+ end
@@ -0,0 +1,123 @@
1
+ require 'test_helper'
2
+ require 'xml_security'
3
+
4
+ class XmlSecurityTest < Test::Unit::TestCase
5
+ include XMLSecurity
6
+
7
+ context "XmlSecurity" do
8
+ setup do
9
+ @document = Ciam::XMLSecurity::SignedDocument.new(Base64.decode64(response_document))
10
+ @base64cert = @document.elements["//ds:X509Certificate"].text
11
+ end
12
+
13
+ should "should run validate without throwing NS related exceptions" do
14
+ assert !@document.validate_doc(@base64cert, true)
15
+ end
16
+
17
+ should "should run validate with throwing NS related exceptions" do
18
+ assert_raise(Ciam::Saml::ValidationError) do
19
+ @document.validate_doc(@base64cert, false)
20
+ end
21
+ end
22
+
23
+ should "not raise an error when softly validating the document multiple times" do
24
+ assert_nothing_raised do
25
+ 2.times { @document.validate_doc(@base64cert, true) }
26
+ end
27
+ end
28
+
29
+ should "should raise Fingerprint mismatch" do
30
+ exception = assert_raise(Ciam::Saml::ValidationError) do
31
+ @document.validate("no:fi:ng:er:pr:in:t", false)
32
+ end
33
+ assert_equal("Fingerprint mismatch", exception.message)
34
+ end
35
+
36
+ should "should raise Digest mismatch" do
37
+ exception = assert_raise(Ciam::Saml::ValidationError) do
38
+ @document.validate_doc(@base64cert, false)
39
+ end
40
+ assert_equal("Digest mismatch", exception.message)
41
+ end
42
+
43
+ should "should raise Key validation error" do
44
+ response = Base64.decode64(response_document)
45
+ response.sub!("<ds:DigestValue>pJQ7MS/ek4KRRWGmv/H43ReHYMs=</ds:DigestValue>",
46
+ "<ds:DigestValue>b9xsAXLsynugg3Wc1CI3kpWku+0=</ds:DigestValue>")
47
+ document = Ciam::XMLSecurity::SignedDocument.new(response)
48
+ base64cert = document.elements["//ds:X509Certificate"].text
49
+ exception = assert_raise(Ciam::Saml::ValidationError) do
50
+ document.validate_doc(base64cert, false)
51
+ end
52
+ assert_equal("Key validation error", exception.message)
53
+ end
54
+ end
55
+
56
+ context "Algorithms" do
57
+ should "validate using SHA1" do
58
+ @document = Ciam::XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha1, false))
59
+ assert @document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
60
+ end
61
+
62
+ should "validate using SHA256" do
63
+ @document = Ciam::XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha256, false))
64
+ assert @document.validate("28:74:9B:E8:1F:E8:10:9C:A8:7C:A9:C3:E3:C5:01:6C:92:1C:B4:BA")
65
+ end
66
+
67
+ should "validate using SHA384" do
68
+ @document = Ciam::XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha384, false))
69
+ assert @document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
70
+ end
71
+
72
+ should "validate using SHA512" do
73
+ @document = Ciam::XMLSecurity::SignedDocument.new(fixture(:adfs_response_sha512, false))
74
+ assert @document.validate("F1:3C:6B:80:90:5A:03:0E:6C:91:3E:5D:15:FA:DD:B0:16:45:48:72")
75
+ end
76
+ end
77
+
78
+ context "Ciam::XmlSecurity::SignedDocument" do
79
+
80
+ context "#extract_inclusive_namespaces" do
81
+ should "support explicit namespace resolution for exclusive canonicalization" do
82
+ response = fixture(:open_saml_response, false)
83
+ document = Ciam::XMLSecurity::SignedDocument.new(response)
84
+ inclusive_namespaces = document.send(:extract_inclusive_namespaces)
85
+
86
+ assert_equal %w[ xs ], inclusive_namespaces
87
+ end
88
+
89
+ should "support implicit namespace resolution for exclusive canonicalization" do
90
+ response = fixture(:no_signature_ns, false)
91
+ document = Ciam::XMLSecurity::SignedDocument.new(response)
92
+ inclusive_namespaces = document.send(:extract_inclusive_namespaces)
93
+
94
+ assert_equal %w[ #default saml ds xs xsi ], inclusive_namespaces
95
+ end
96
+
97
+ should_eventually 'support inclusive canonicalization' do
98
+
99
+ response = Ciam::Saml::Response.new(fixture("tdnf_response.xml"))
100
+ response.stubs(:conditions).returns(nil)
101
+ assert !response.is_valid?
102
+ settings = Ciam::Saml::Settings.new
103
+ assert !response.is_valid?
104
+ response.settings = settings
105
+ assert !response.is_valid?
106
+ 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(" ", ":")
107
+ assert response.validate!
108
+ end
109
+
110
+ should "return an empty list when inclusive namespace element is missing" do
111
+ response = fixture(:no_signature_ns, false)
112
+ response.slice! %r{<InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="#default saml ds xs xsi"/>}
113
+
114
+ document = Ciam::XMLSecurity::SignedDocument.new(response)
115
+ inclusive_namespaces = document.send(:extract_inclusive_namespaces)
116
+
117
+ assert inclusive_namespaces.empty?
118
+ end
119
+ end
120
+
121
+ end
122
+
123
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ciam-es
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Fabiano Pavan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-07-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: canonix
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: uuid
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 1.6.7.2
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.6.7.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: addressable
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.7.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 2.7.0
69
+ description: 'SAML toolkit for Ruby programs to integrate with CIAM Milano '
70
+ email: fabiano.pavan@soluzionipa.it
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".document"
76
+ - Gemfile
77
+ - README.md
78
+ - ciam-es.gemspec
79
+ - lib/ciam-es.rb
80
+ - lib/ciam/ruby-saml/authrequest.rb
81
+ - lib/ciam/ruby-saml/coding.rb
82
+ - lib/ciam/ruby-saml/error_handling.rb
83
+ - lib/ciam/ruby-saml/logging.rb
84
+ - lib/ciam/ruby-saml/logout_request.rb
85
+ - lib/ciam/ruby-saml/logout_response.rb
86
+ - lib/ciam/ruby-saml/metadata.rb
87
+ - lib/ciam/ruby-saml/request.rb
88
+ - lib/ciam/ruby-saml/response.rb
89
+ - lib/ciam/ruby-saml/settings.rb
90
+ - lib/ciam/ruby-saml/utils.rb
91
+ - lib/ciam/ruby-saml/validation_error.rb
92
+ - lib/ciam/ruby-saml/version.rb
93
+ - lib/ciam/xml_security.rb
94
+ - lib/ciam/xml_security_new.rb
95
+ - lib/schemas/saml20assertion_schema.xsd
96
+ - lib/schemas/saml20protocol_schema.xsd
97
+ - lib/schemas/xenc_schema.xsd
98
+ - lib/schemas/xmldsig_schema.xsd
99
+ - test/certificates/certificate1
100
+ - test/logoutrequest_test.rb
101
+ - test/request_test.rb
102
+ - test/response_test.rb
103
+ - test/responses/adfs_response_sha1.xml
104
+ - test/responses/adfs_response_sha256.xml
105
+ - test/responses/adfs_response_sha384.xml
106
+ - test/responses/adfs_response_sha512.xml
107
+ - test/responses/no_signature_ns.xml
108
+ - test/responses/open_saml_response.xml
109
+ - test/responses/response1.xml.base64
110
+ - test/responses/response2.xml.base64
111
+ - test/responses/response3.xml.base64
112
+ - test/responses/response4.xml.base64
113
+ - test/responses/response5.xml.base64
114
+ - test/responses/response_with_ampersands.xml
115
+ - test/responses/response_with_ampersands.xml.base64
116
+ - test/responses/simple_saml_php.xml
117
+ - test/responses/wrapped_response_2.xml.base64
118
+ - test/settings_test.rb
119
+ - test/test_helper.rb
120
+ - test/xml_security_test.rb
121
+ homepage: https://github.com/EuroServizi/ciam-es
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options:
127
+ - "--charset=UTF-8"
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubygems_version: 3.0.6
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: SAML Ruby Tookit CIAM
145
+ test_files: []