saml_tools 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.
- checksums.yaml +15 -0
- data/LICENSE +24 -0
- data/README.rdoc +65 -0
- data/Rakefile +28 -0
- data/lib/saml_tool.rb +23 -0
- data/lib/saml_tool/certificate.rb +27 -0
- data/lib/saml_tool/decoder.rb +35 -0
- data/lib/saml_tool/encoder.rb +31 -0
- data/lib/saml_tool/erb_builder.rb +33 -0
- data/lib/saml_tool/reader.rb +40 -0
- data/lib/saml_tool/redirect.rb +45 -0
- data/lib/saml_tool/response_reader.rb +148 -0
- data/lib/saml_tool/rsa_key.rb +13 -0
- data/lib/saml_tool/saml.rb +30 -0
- data/lib/saml_tool/settings.rb +24 -0
- data/lib/saml_tool/validator.rb +40 -0
- data/lib/saml_tool/version.rb +8 -0
- data/lib/saml_tools.rb +1 -0
- data/lib/schema/localised-saml-schema-assertion-2.0.xsd +292 -0
- data/lib/schema/localised-saml-schema-protocol-2.0.xsd +309 -0
- data/lib/schema/localised-xenc-schema.xsd +151 -0
- data/lib/schema/xmldsig-core-schema.xsd +318 -0
- data/test/files/TEST_FILES.rdoc +22 -0
- data/test/files/cacert.pem +21 -0
- data/test/files/open_saml_response.xml +56 -0
- data/test/files/request.saml.erb +28 -0
- data/test/files/response.xml +94 -0
- data/test/files/response_template.xml +63 -0
- data/test/files/usercert.p12 +0 -0
- data/test/files/userkey.pem +18 -0
- data/test/files/valid_saml_request.xml +13 -0
- data/test/test_helper.rb +51 -0
- data/test/units/saml_tool/certificate_test.rb +30 -0
- data/test/units/saml_tool/decoder_test.rb +36 -0
- data/test/units/saml_tool/encoder_test.rb +38 -0
- data/test/units/saml_tool/erb_builder_test.rb +50 -0
- data/test/units/saml_tool/reader_test.rb +104 -0
- data/test/units/saml_tool/redirect_test.rb +70 -0
- data/test/units/saml_tool/response_reader_test.rb +144 -0
- data/test/units/saml_tool/rsa_key_test.rb +21 -0
- data/test/units/saml_tool/saml_test.rb +21 -0
- data/test/units/saml_tool/settings_test.rb +36 -0
- data/test/units/saml_tool/validator_test.rb +16 -0
- metadata +168 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
M2Q5NTdiZmZmM2FkZTAwNDE4MTg5OTczNWEyODA5ZDNmOTE5ZmMzOQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZjE1NGRlYzdhMmQzZDg4N2ZiMTZlY2RkZGFjZWViMDNlOWJkOWI5Ng==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZjkwNjQyOTQxNTA4YjAwNmJjZDJjMzBiMTBhZGYxZWYzZDhmNzAzMmI0ZjZh
|
10
|
+
NTNlNzY4ODM0MDZmNjg0MGRkOTdhMDIxYjEwYWRhNjUyMTBmZDRlMjNkNGM4
|
11
|
+
NzQ2OThjZDcxN2NmNjVkZTM1MTFhNDZjMzk5OGIzN2RlOWI3ODE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZWY0OTc2Y2JiODhlYjIwYjdmY2Y2ZDhkM2Y4MjEzYThiMDAxY2YyNWNmODBl
|
14
|
+
ZjVlNWMxZWVlOWM3NTc1YjZkNjM1ZmQyODQxNjE5YzQ4M2UxZTMzOTUxOWIw
|
15
|
+
YWUwNjg2ZDk3MDNiNDg5NjFmMmRhYzA4Y2Y4NDVlNWYyNDI2MDI=
|
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
SAML Tools
|
2
|
+
|
3
|
+
Copyright (c) 2014 Rob Nichols, Warwickshire County Council
|
4
|
+
|
5
|
+
MIT License
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
8
|
+
a copy of this software and associated documentation files (the
|
9
|
+
"Software"), to deal in the Software without restriction, including
|
10
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
11
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
12
|
+
permit persons to whom the Software is furnished to do so, subject to
|
13
|
+
the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be
|
16
|
+
included in all copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
20
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
22
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
23
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
24
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
=SAML Tools
|
2
|
+
|
3
|
+
Tools to simplify the creation, validation and sending of SAML objects
|
4
|
+
|
5
|
+
== SamlTool::Certificate
|
6
|
+
Version of OpenSSL::X509::Certificate that adds methods to simplify the retrieval
|
7
|
+
of data used in SAML responses.
|
8
|
+
|
9
|
+
== SamlTool::Decoder
|
10
|
+
Decodes base64 and unzips content.
|
11
|
+
|
12
|
+
== SamlTool::Encoder
|
13
|
+
Zips content and base64 encodes it.
|
14
|
+
|
15
|
+
== SamlTool::ErbBuilder
|
16
|
+
Used to build SAML content from erb templates.
|
17
|
+
|
18
|
+
output = SamlTool::ErbBuilder.build(
|
19
|
+
template: '<foo><%= settings %></foo>',
|
20
|
+
settings: 'bar'
|
21
|
+
)
|
22
|
+
output == '<foo>bar</foo>'
|
23
|
+
|
24
|
+
== SamlTool::Reader
|
25
|
+
Wraps SAML documents and exposes data via methods
|
26
|
+
|
27
|
+
reader = SamlTool::Reader.new(
|
28
|
+
output,
|
29
|
+
{foo: '//foo/text()'}
|
30
|
+
)
|
31
|
+
reader.foo == 'bar'
|
32
|
+
|
33
|
+
== SamlTool::Redirect
|
34
|
+
Used to construct redirection uris
|
35
|
+
|
36
|
+
redirect = Redirect.uri(
|
37
|
+
to: 'http://example.com',
|
38
|
+
data: {
|
39
|
+
foo: 'bar'
|
40
|
+
}
|
41
|
+
)
|
42
|
+
redirect == "http://example.com?foo=bar"
|
43
|
+
|
44
|
+
== SamlTool::ResponseReader
|
45
|
+
A version of SamlTool::Reader tailored for handling SAML responses. It includes
|
46
|
+
a valid? method that validates the SAML structure and checks the signature is
|
47
|
+
correct.
|
48
|
+
|
49
|
+
== SamlTool::RsaKey
|
50
|
+
Version of OpenSSL::PKey::RSA that adds methods to simplify the retrieval
|
51
|
+
of data used in SAML responses.
|
52
|
+
|
53
|
+
== SamlTool::SAML
|
54
|
+
A wrapper for Nokogiri::XML, that applies defaults that are appropriate for SAML
|
55
|
+
|
56
|
+
== SamlTool::Settings
|
57
|
+
Packages up settings so that they can be more easily passed to other objects.
|
58
|
+
|
59
|
+
== SamlTool::Validator
|
60
|
+
Compares documents with SAML schemas to test if they have a valid structure.
|
61
|
+
|
62
|
+
== Further reading
|
63
|
+
|
64
|
+
I've {blogged here}[http://undervale.co.uk/blog/?p=490] about some of highs and
|
65
|
+
lows of building these tools.
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rdoc/task'
|
5
|
+
require 'rake/testtask'
|
6
|
+
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
Rake::RDocTask.new do |rdoc|
|
10
|
+
files =['README.rdoc', 'LICENSE', 'lib/**/*.rb']
|
11
|
+
rdoc.rdoc_files.add(files)
|
12
|
+
rdoc.main = "README.rdoc" # page to start on
|
13
|
+
rdoc.title = "SAML Tools Documentation"
|
14
|
+
rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
|
15
|
+
rdoc.options << '--line-numbers'
|
16
|
+
end
|
17
|
+
|
18
|
+
Rake::TestTask.new do |t|
|
19
|
+
t.test_files = FileList['test/**/*_test.rb']
|
20
|
+
end
|
21
|
+
|
22
|
+
task :console do
|
23
|
+
require 'irb'
|
24
|
+
require 'irb/completion'
|
25
|
+
require_relative 'lib/saml_tool'
|
26
|
+
ARGV.clear
|
27
|
+
IRB.start
|
28
|
+
end
|
data/lib/saml_tool.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Namespace definition
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'hashie'
|
5
|
+
require 'securerandom'
|
6
|
+
require 'base64'
|
7
|
+
require 'zlib'
|
8
|
+
require 'openssl'
|
9
|
+
require 'xmldsig'
|
10
|
+
|
11
|
+
module SamlTool
|
12
|
+
require_relative 'saml_tool/validator'
|
13
|
+
require_relative 'saml_tool/erb_builder'
|
14
|
+
require_relative 'saml_tool/encoder'
|
15
|
+
require_relative 'saml_tool/decoder'
|
16
|
+
require_relative 'saml_tool/redirect'
|
17
|
+
require_relative 'saml_tool/settings'
|
18
|
+
require_relative 'saml_tool/reader'
|
19
|
+
require_relative 'saml_tool/response_reader'
|
20
|
+
require_relative 'saml_tool/saml'
|
21
|
+
require_relative 'saml_tool/certificate'
|
22
|
+
require_relative 'saml_tool/rsa_key'
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
module SamlTool
|
3
|
+
class Certificate < OpenSSL::X509::Certificate
|
4
|
+
|
5
|
+
alias_method :serial_number, :serial
|
6
|
+
|
7
|
+
def without_leading_and_trailing_labels
|
8
|
+
to_s.lines.to_a[1..-2].join
|
9
|
+
end
|
10
|
+
alias_method :x509_certificate, :without_leading_and_trailing_labels
|
11
|
+
|
12
|
+
def issuer_name
|
13
|
+
@issuer_name ||= slash_list_to_comma_list(issuer)
|
14
|
+
end
|
15
|
+
|
16
|
+
def subject_name
|
17
|
+
@subject_name ||= slash_list_to_comma_list(subject)
|
18
|
+
end
|
19
|
+
|
20
|
+
def slash_list_to_comma_list(string)
|
21
|
+
string = string.to_s
|
22
|
+
string = string[1..-1] if string[0] == '/'
|
23
|
+
string.split('/').reverse.join(',')
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
module SamlTool
|
3
|
+
class Decoder
|
4
|
+
attr_reader :saml
|
5
|
+
attr_accessor :output
|
6
|
+
|
7
|
+
def self.decode(encoded_saml)
|
8
|
+
new(encoded_saml).decode
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(encoded_saml)
|
12
|
+
@saml = encoded_saml
|
13
|
+
@output = @saml.clone
|
14
|
+
end
|
15
|
+
|
16
|
+
def decode
|
17
|
+
base64
|
18
|
+
zlib
|
19
|
+
output
|
20
|
+
end
|
21
|
+
|
22
|
+
def base64
|
23
|
+
self.output = Base64.decode64 output
|
24
|
+
end
|
25
|
+
|
26
|
+
def zlib
|
27
|
+
zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS) # I have no idea why we're using minus Zlib::MAX_WBITS. Zlib documentation suggests just Zlib::MAX_WBITS should work, but it doesn't
|
28
|
+
self.output = zstream.inflate(output)
|
29
|
+
zstream.finish
|
30
|
+
zstream.close
|
31
|
+
return output
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
module SamlTool
|
3
|
+
class Encoder
|
4
|
+
attr_reader :saml
|
5
|
+
attr_accessor :output
|
6
|
+
|
7
|
+
def self.encode(saml)
|
8
|
+
new(saml).encode
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(saml)
|
12
|
+
@saml = saml
|
13
|
+
@output = @saml.clone
|
14
|
+
end
|
15
|
+
|
16
|
+
def encode
|
17
|
+
zlib
|
18
|
+
base64
|
19
|
+
output
|
20
|
+
end
|
21
|
+
|
22
|
+
def base64
|
23
|
+
self.output = Base64.encode64 output
|
24
|
+
end
|
25
|
+
|
26
|
+
def zlib
|
27
|
+
self.output = Zlib::Deflate.deflate(output, Zlib::BEST_COMPRESSION)[2..-5]
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'erb'
|
2
|
+
module SamlTool
|
3
|
+
class ErbBuilder
|
4
|
+
|
5
|
+
attr_reader :args, :settings, :template
|
6
|
+
|
7
|
+
def self.build(args)
|
8
|
+
new(args).to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(args)
|
12
|
+
@args = args
|
13
|
+
@settings = args[:settings]
|
14
|
+
@template = args[:template]
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
output
|
19
|
+
end
|
20
|
+
|
21
|
+
def output
|
22
|
+
@output ||= build_output
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_output
|
26
|
+
erb.result settings.send(:binding)
|
27
|
+
end
|
28
|
+
|
29
|
+
def erb
|
30
|
+
ERB.new(template)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
module SamlTool
|
3
|
+
class Reader
|
4
|
+
attr_reader :saml, :config, :namespaces
|
5
|
+
|
6
|
+
def initialize(saml, config = {}, namespaces = nil)
|
7
|
+
@saml = SamlTool::SAML(saml)
|
8
|
+
@config = Hashie::Mash.new(config)
|
9
|
+
@namespaces = namespaces
|
10
|
+
build_methods
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_hash
|
14
|
+
config.keys.inject({}){|hash, key| hash[key.to_sym] = send(key.to_sym); hash}
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def build_methods
|
19
|
+
@config.each do |key, value|
|
20
|
+
self.class.send :attr_reader, key.to_sym
|
21
|
+
source = saml.xpath(value, namespaces)
|
22
|
+
content = Content.new(source)
|
23
|
+
instance_variable_set("@#{key}".to_sym, content)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# A string with memory of the element that was the source of its content.
|
28
|
+
# Typically, the source will be a Nokogiri::XML::NodeSet. So:
|
29
|
+
# content --> text from an element.
|
30
|
+
# content.source --> the Nokogiri NodeSet the text was extracted from.
|
31
|
+
class Content < String
|
32
|
+
attr_reader :source
|
33
|
+
def initialize(source)
|
34
|
+
@source = source
|
35
|
+
super(source.to_s)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
module SamlTool
|
4
|
+
|
5
|
+
class Redirect
|
6
|
+
attr_reader :to, :data
|
7
|
+
|
8
|
+
def self.uri(args)
|
9
|
+
new(args).to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(args)
|
13
|
+
@to = args[:to]
|
14
|
+
@data = args[:data]
|
15
|
+
end
|
16
|
+
|
17
|
+
def uri
|
18
|
+
@uri || build_uri
|
19
|
+
end
|
20
|
+
|
21
|
+
def data_string
|
22
|
+
return data if data.kind_of? String
|
23
|
+
data.to_a.collect{|pair| pair.collect{|p| CGI.escape(p.to_s)}.join('=')}.join('&')
|
24
|
+
end
|
25
|
+
|
26
|
+
def append_data
|
27
|
+
uri.query = [uri.query, data_string].compact.join('&')
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
uri.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_uri
|
35
|
+
uri_from_to
|
36
|
+
append_data
|
37
|
+
return uri
|
38
|
+
end
|
39
|
+
|
40
|
+
def uri_from_to
|
41
|
+
@uri = URI(to)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require "openssl"
|
2
|
+
|
3
|
+
module SamlTool
|
4
|
+
class ResponseReader < Reader
|
5
|
+
|
6
|
+
# On creation, the keys for this hash will be converted into methods that
|
7
|
+
# will return the text gathered at the xpath in the matching value.
|
8
|
+
def default_config
|
9
|
+
{
|
10
|
+
base64_cert: '//ds:X509Certificate/text()',
|
11
|
+
canonicalization_method: '//ds:CanonicalizationMethod/@Algorithm',
|
12
|
+
reference_uri: '//ds:Reference/@URI',
|
13
|
+
inclusive_namespaces: '//ec:InclusiveNamespaces/@PrefixList',
|
14
|
+
digest_algorithm: '//ds:DigestMethod/@Algorithm',
|
15
|
+
digest_value: '//ds:DigestValue/text()',
|
16
|
+
signature_value: '//ds:SignatureValue/text()',
|
17
|
+
signature_algorithm: '//ds:SignatureMethod/@Algorithm',
|
18
|
+
signed_info: '//ds:SignedInfo'
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(saml, config = {}, namespaces = {})
|
23
|
+
super(
|
24
|
+
saml,
|
25
|
+
config.merge(default_config),
|
26
|
+
namespaces.merge(default_namespaces)
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def valid?
|
31
|
+
structurally_valid? && signature_verified? && digests_match?
|
32
|
+
end
|
33
|
+
|
34
|
+
def structurally_valid?
|
35
|
+
Validator.new(saml.to_s).valid?
|
36
|
+
end
|
37
|
+
|
38
|
+
def signature_verified?
|
39
|
+
certificate.public_key.verify(
|
40
|
+
signature_algorithm_class.new,
|
41
|
+
signature,
|
42
|
+
canonicalized_signed_info
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def digests_match?
|
47
|
+
digest_hash == decoded_digest_value
|
48
|
+
end
|
49
|
+
|
50
|
+
def signatureless
|
51
|
+
@signatureless ||= clone_saml_and_remove_signature
|
52
|
+
end
|
53
|
+
|
54
|
+
def certificate
|
55
|
+
@certificate ||= OpenSSL::X509::Certificate.new(raw_cert)
|
56
|
+
end
|
57
|
+
|
58
|
+
def raw_cert
|
59
|
+
@raw_cert ||= Base64.decode64(base64_cert)
|
60
|
+
end
|
61
|
+
|
62
|
+
def fingerprint
|
63
|
+
@fingerprint ||= Digest::SHA1.hexdigest(certificate.to_der)
|
64
|
+
end
|
65
|
+
|
66
|
+
def signature
|
67
|
+
@signature ||= Base64.decode64(signature_value)
|
68
|
+
end
|
69
|
+
|
70
|
+
def canonicalization_algorithm
|
71
|
+
case canonicalization_method
|
72
|
+
when "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" then Nokogiri::XML::XML_C14N_1_0
|
73
|
+
when "http://www.w3.org/2006/12/xml-c14n11" then Nokogiri::XML::XML_C14N_1_1
|
74
|
+
else Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def hashed_element
|
79
|
+
@hashed_element ||= signatureless.at_xpath("//*[@ID='#{reference_uri[1..-1]}']")
|
80
|
+
end
|
81
|
+
|
82
|
+
def canonicalized_hashed_element
|
83
|
+
hashed_element.canonicalize(
|
84
|
+
canonicalization_algorithm,
|
85
|
+
inclusive_namespaces.split(' ')
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
def canonicalized_signed_info
|
90
|
+
signed_info_element.canonicalize(
|
91
|
+
canonicalization_algorithm,
|
92
|
+
inclusive_namespaces.split(' ')
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
def signed_info_element
|
97
|
+
signed_info.source.first
|
98
|
+
end
|
99
|
+
|
100
|
+
def digest_algorithm_class
|
101
|
+
@digest_algorithm_class ||= determine_algorithm_class(digest_algorithm)
|
102
|
+
end
|
103
|
+
|
104
|
+
def signature_algorithm_class
|
105
|
+
@signature_algorithm_class ||= determine_algorithm_class(signature_algorithm)
|
106
|
+
end
|
107
|
+
|
108
|
+
def determine_algorithm_class(method_text)
|
109
|
+
case method_text.slice(/sha(\d+)\s*$/, 1)
|
110
|
+
when '256' then OpenSSL::Digest::SHA256
|
111
|
+
when '384' then OpenSSL::Digest::SHA384
|
112
|
+
when '512' then OpenSSL::Digest::SHA512
|
113
|
+
else
|
114
|
+
OpenSSL::Digest::SHA1
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def digest_hash
|
119
|
+
@digest_hash ||= digest_algorithm_class.digest(canonicalized_hashed_element)
|
120
|
+
end
|
121
|
+
|
122
|
+
def decoded_digest_value
|
123
|
+
Base64.decode64(digest_value)
|
124
|
+
end
|
125
|
+
|
126
|
+
def clone_saml_and_remove_signature
|
127
|
+
cloned_saml = saml.clone
|
128
|
+
cloned_saml.xpath('//ds:Signature', namespaces).remove
|
129
|
+
return SamlTool::SAML(cloned_saml.to_s)
|
130
|
+
end
|
131
|
+
|
132
|
+
def default_namespaces
|
133
|
+
{
|
134
|
+
ds: dsig,
|
135
|
+
ec: c14m
|
136
|
+
}
|
137
|
+
end
|
138
|
+
|
139
|
+
def c14m
|
140
|
+
'http://www.w3.org/2001/10/xml-exc-c14n#'
|
141
|
+
end
|
142
|
+
|
143
|
+
def dsig
|
144
|
+
'http://www.w3.org/2000/09/xmldsig#'
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|