saml_tools 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|