wss4r 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README +300 -0
- data/lib/wss4r/aws/utils.rb +37 -0
- data/lib/wss4r/config/config.rb +105 -0
- data/lib/wss4r/rpc/proxy.rb +26 -0
- data/lib/wss4r/rpc/router.rb +46 -0
- data/lib/wss4r/rpc/wssdriver.rb +19 -0
- data/lib/wss4r/security/crypto/certificate.rb +21 -0
- data/lib/wss4r/security/crypto/cipher.rb +161 -0
- data/lib/wss4r/security/crypto/hash.rb +35 -0
- data/lib/wss4r/security/exceptions/exceptions.rb +62 -0
- data/lib/wss4r/security/resolver.rb +23 -0
- data/lib/wss4r/security/security.rb +148 -0
- data/lib/wss4r/security/util/hash_util.rb +39 -0
- data/lib/wss4r/security/util/names.rb +38 -0
- data/lib/wss4r/security/util/namespaces.rb +21 -0
- data/lib/wss4r/security/util/reference_elements.rb +15 -0
- data/lib/wss4r/security/util/soap_parser.rb +73 -0
- data/lib/wss4r/security/util/transformer_factory.rb +29 -0
- data/lib/wss4r/security/util/types.rb +25 -0
- data/lib/wss4r/security/util/xmlcanonicalizer.rb +427 -0
- data/lib/wss4r/security/util/xmlutils.rb +58 -0
- data/lib/wss4r/security/xml/encrypted_data.rb +110 -0
- data/lib/wss4r/security/xml/encrypted_key.rb +74 -0
- data/lib/wss4r/security/xml/key_info.rb +52 -0
- data/lib/wss4r/security/xml/reference.rb +53 -0
- data/lib/wss4r/security/xml/reference_list.rb +24 -0
- data/lib/wss4r/security/xml/security.rb +92 -0
- data/lib/wss4r/security/xml/signature.rb +69 -0
- data/lib/wss4r/security/xml/signature_value.rb +26 -0
- data/lib/wss4r/security/xml/signed_info.rb +83 -0
- data/lib/wss4r/security/xml/timestamp.rb +47 -0
- data/lib/wss4r/security/xml/tokentypes.rb +180 -0
- data/lib/wss4r/server/wssstandaloneserver.rb +27 -0
- data/lib/wss4r/soap/processor.rb +92 -0
- data/lib/wss4r/tokenresolver/authenticateuserresolver.rb +34 -0
- data/lib/wss4r/tokenresolver/certificateresolver.rb +62 -0
- data/lib/wss4r/tokenresolver/databaseresolver.rb +56 -0
- data/lib/wss4r/tokenresolver/resolver.rb +13 -0
- metadata +95 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
require "rexml/document"
|
2
|
+
|
3
|
+
include REXML
|
4
|
+
|
5
|
+
class REXML::Element
|
6
|
+
def index_of(e)
|
7
|
+
return -1 if (e == nil)
|
8
|
+
children = self.children()
|
9
|
+
children.each_with_index {|child, i|
|
10
|
+
return i if (child.local_name() == e.local_name())
|
11
|
+
}
|
12
|
+
return -1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class REXML::Document
|
17
|
+
def select(xpath)
|
18
|
+
#XPath.first(document, "/env:Envelope/env:Header/wsse:Security/ds:Signature")
|
19
|
+
element = XPath.first(self, xpath)
|
20
|
+
if (element != nil)
|
21
|
+
return element
|
22
|
+
end
|
23
|
+
node_path = xpath.sub("/","").split("/")
|
24
|
+
|
25
|
+
element = self
|
26
|
+
|
27
|
+
node_path.each{|expr|
|
28
|
+
element = select_element(element, expr)
|
29
|
+
if (element == nil)
|
30
|
+
return nil
|
31
|
+
end
|
32
|
+
}
|
33
|
+
element
|
34
|
+
end
|
35
|
+
|
36
|
+
def select_element(element, name)
|
37
|
+
childs = Array.new()
|
38
|
+
element.each_child{|child|
|
39
|
+
if (child.node_type() == :element)
|
40
|
+
if (child.expanded_name() == name)
|
41
|
+
childs.push(child)
|
42
|
+
return child
|
43
|
+
end
|
44
|
+
end
|
45
|
+
}
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def element_with_attribute(key, value)
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
if __FILE__ == $0
|
55
|
+
document = REXML::Document.new(File.new(ARGV[0]))
|
56
|
+
element = document.select("/env:Envelope/env:Header/wsse:Security/ds:Signature")
|
57
|
+
puts("selected: " + element.to_s())
|
58
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module WSS4R
|
2
|
+
module Security
|
3
|
+
module Xml
|
4
|
+
|
5
|
+
class EncryptedData
|
6
|
+
attr_accessor :cipher_value, :ref_id, :algorithm, :sessionkey_algorithm, :security_token
|
7
|
+
|
8
|
+
def initialize(security_token=nil)
|
9
|
+
if (security_token != nil)
|
10
|
+
@security_token = security_token
|
11
|
+
end
|
12
|
+
@sessionkey_algorithm = Types::ALGORITHM_3DES_CBC
|
13
|
+
end
|
14
|
+
|
15
|
+
def unprocess(encrypted_data)
|
16
|
+
cipher_value = XPath.first(encrypted_data, "xenc:CipherData/xenc:CipherValue", {"xenc" => Namespaces::XENC})
|
17
|
+
algorithm = XPath.first(encrypted_data, "xenc:EncryptionMethod", {"xenc" => Namespaces::XENC})
|
18
|
+
ref_id = encrypted_data.attributes["Id"]
|
19
|
+
self.cipher_value=(cipher_value.text())
|
20
|
+
self.ref_id=(ref_id)
|
21
|
+
self.algorithm=(algorithm.attributes["Algorithm"])
|
22
|
+
end
|
23
|
+
|
24
|
+
def process(document)
|
25
|
+
root = document.root()
|
26
|
+
soap_ns = nil
|
27
|
+
soap_prefix = root.prefix()
|
28
|
+
root.attributes.each_attribute() {|attr|
|
29
|
+
if (attr.value() == Namespaces::S11)
|
30
|
+
soap_ns = Namespaces::S11
|
31
|
+
end
|
32
|
+
if (attr.value() == Namespaces::S12)
|
33
|
+
soap_ns = Namespaces::S12
|
34
|
+
end
|
35
|
+
}
|
36
|
+
old_soap_body = XPath.first(document, "/env:Envelope/env:Body", {SOAPParser::soap_prefix=>SOAPParser::soap_ns})
|
37
|
+
#old_soap_body = SOAPParser.part(SOAPParser::BODY)
|
38
|
+
|
39
|
+
soap_body_string = ""
|
40
|
+
if defined?(REXML::Formatters)
|
41
|
+
formatter = REXML::Formatters::Default.new
|
42
|
+
old_soap_body.each_element(){|e|
|
43
|
+
formatter.write(e, soap_body_string)
|
44
|
+
}
|
45
|
+
else
|
46
|
+
old_soap_body.each_element(){|e|
|
47
|
+
e.write(soap_body_string)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
root.delete(old_soap_body)
|
51
|
+
soap_body = root.add_element(Names::BODY)
|
52
|
+
old_soap_body.attributes().each_attribute{|a|
|
53
|
+
soap_body.add_attribute(a.expanded_name(), a.value())
|
54
|
+
#puts(a.expanded_name() + " => " + a.value())
|
55
|
+
}
|
56
|
+
digest = CryptHash.new().digest_b64(soap_body.to_s()).strip()
|
57
|
+
encrypted_data = soap_body.add_element(Names::ENCRYPTED_DATA)
|
58
|
+
encrypted_data.add_namespace("xmlns:xenc", Namespaces::XENC)
|
59
|
+
@ref_id = "EncryptedContent-"+digest.to_s()
|
60
|
+
encrypted_data.add_attributes({"Type"=>Types::XENC_CONTENT, "Id"=>@ref_id})
|
61
|
+
|
62
|
+
if (@sessionkey_algorithm == Types::ALGORITHM_3DES_CBC)
|
63
|
+
symmetric_encrypter = TripleDESSymmetricEncrypter.new()
|
64
|
+
elsif (@sessionkey_algorithm == Types::ALGORITHM_AES_CBC)
|
65
|
+
symmetric_encrypter = AESSymmetricEncrypter.new()
|
66
|
+
elsif (@sessionkey_algorithm == Types::ALGORITHM_AES128_CBC)
|
67
|
+
symmetric_encrypter = AES128SymmetricEncrypter.new()
|
68
|
+
else
|
69
|
+
raise "Unsupported encryption algorithm #{@sessionkey_algorithm}"
|
70
|
+
end
|
71
|
+
encryption_method = encrypted_data.add_element(Names::ENCRYPTION_METHOD)
|
72
|
+
encryption_method.add_attribute("Algorithm", @sessionkey_algorithm)
|
73
|
+
encrypted_body = symmetric_encrypter.encrypt_to_b64(symmetric_encrypter.iv() + soap_body_string)
|
74
|
+
encrypted_key = EncryptedKey.new(@security_token, symmetric_encrypter, self)
|
75
|
+
cipher_data = encrypted_data.add_element(Names::CIPHER_DATA)
|
76
|
+
cipher_value = cipher_data.add_element(Names::CIPHER_VALUE)
|
77
|
+
cipher_value.text=(encrypted_body.gsub("\n",""))
|
78
|
+
encrypted_key.process(document)
|
79
|
+
end
|
80
|
+
|
81
|
+
def decrypt(document, encrypted_key)
|
82
|
+
if (algorithm == Types::ALGORITHM_3DES_CBC)
|
83
|
+
symmetric_encrypter = TripleDESSymmetricEncrypter.new(encrypted_key.symmetric_key())
|
84
|
+
elsif (algorithm == Types::ALGORITHM_AES_CBC)
|
85
|
+
symmetric_encrypter = AESSymmetricEncrypter.new(encrypted_key.symmetric_key())
|
86
|
+
elsif (algorithm == Types::ALGORITHM_AES128_CBC)
|
87
|
+
symmetric_encrypter = AES128SymmetricEncrypter.new(encrypted_key.symmetric_key())
|
88
|
+
else
|
89
|
+
raise "Unsupported encryption algorithm #{algorithm}"
|
90
|
+
end
|
91
|
+
raw_data = Base64.decode64(@cipher_value)
|
92
|
+
symmetric_encrypter.iv=(raw_data)
|
93
|
+
decrypted_element = symmetric_encrypter.decrypt(raw_data)
|
94
|
+
reference = encrypted_key.reference_list().uris()[0]
|
95
|
+
reference = reference[1..-1] # remove leading #
|
96
|
+
encrypted_element = XPath.first(document, "//*[@Id='"+reference+"']")
|
97
|
+
parent = encrypted_element.parent()
|
98
|
+
|
99
|
+
#document.root().delete_element("//" + Names::SECURITY)
|
100
|
+
parent.delete(encrypted_element)
|
101
|
+
|
102
|
+
new_element = Document.new(decrypted_element)
|
103
|
+
parent.add(new_element)
|
104
|
+
#puts("encrypted_data.decrypt: " + element.to_s())
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end #Xml
|
109
|
+
end #Security
|
110
|
+
end #WSS4R
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module WSS4R
|
2
|
+
module Security
|
3
|
+
module Xml
|
4
|
+
|
5
|
+
class EncryptedKey
|
6
|
+
attr_reader :x509security_token, :symmetric_encrypter, :symmetric_key, :reference_list
|
7
|
+
|
8
|
+
def initialize(x509security_token=nil, symmetric_encrypter=nil, encrypted_data = nil)
|
9
|
+
@x509security_token = x509security_token
|
10
|
+
@symmetric_encrypter = symmetric_encrypter
|
11
|
+
@encrypted_data = encrypted_data
|
12
|
+
@reference_list = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def unprocess(encrypted_key)
|
16
|
+
#key_info = SOAPParser.element(encrypted_key, SOAPParser::KEY_INFO)
|
17
|
+
algorithm = XPath.first(encrypted_key, "//xenc:EncryptionMethod", {"xenc" => Namespaces::XENC})
|
18
|
+
key_info_element = XPath.first(encrypted_key, "ds:KeyInfo", {"ds"=>Namespaces::DS})
|
19
|
+
key_info = KeyInfo.new(key_info_element)
|
20
|
+
resolver = WSS4R::Security::Security.new().resolver()
|
21
|
+
@reference_list = ReferenceList.new(encrypted_key.get_elements("//xenc:ReferenceList")[0])
|
22
|
+
private_key = resolver.private_key(key_info.security_token().certificate())
|
23
|
+
key_info.security_token().private_key=(private_key)
|
24
|
+
|
25
|
+
@x509security_token = key_info.security_token()
|
26
|
+
|
27
|
+
cipher_value = XPath.first(encrypted_key, "xenc:CipherData/xenc:CipherValue", {"xenc" => Namespaces::XENC})
|
28
|
+
@symmetric_key = @x509security_token.private_decrypt_b64(cipher_value.text())
|
29
|
+
end
|
30
|
+
|
31
|
+
def process(document)
|
32
|
+
#Encrypts the symmetric key with the public key from the certificate and add an EncryptedKey element to env:Body/wsse:Security
|
33
|
+
#@x509security_token.get_xml(document)
|
34
|
+
wsse_security = Security.new()
|
35
|
+
wsse_security = wsse_security.process(document)
|
36
|
+
security_token = @x509security_token.process(document)
|
37
|
+
|
38
|
+
children = wsse_security.children()
|
39
|
+
children.each{|child|
|
40
|
+
wsse_security.delete(child)
|
41
|
+
}
|
42
|
+
wsse_security.add_element(security_token)
|
43
|
+
encrypted_key = wsse_security.add_element(Names::ENCRYPTED_KEY)
|
44
|
+
children.each{|child|
|
45
|
+
wsse_security.add_element(child)
|
46
|
+
}
|
47
|
+
|
48
|
+
encrypted_key.add_namespace("xmlns:xenc", Namespaces::XENC)
|
49
|
+
document.add_namespace("xmlns:xenc", Namespaces::XENC)
|
50
|
+
encryption_method = encrypted_key.add_element(Names::ENCRYPTION_METHOD)
|
51
|
+
encryption_method.add_attribute("Algorithm", Types::ALGORITHM_RSA15)
|
52
|
+
key_info = encrypted_key.add_element(Names::KEY_INFO)
|
53
|
+
key_info.add_namespace("xmlns:ds",Namespaces::DS)
|
54
|
+
security_token_ref = key_info.add_element(Names::SECURITY_TOKEN_REFERENCE)
|
55
|
+
reference = security_token_ref.add_element("wsse:Reference")
|
56
|
+
|
57
|
+
reference.add_attribute("URI", "#"+@x509security_token.get_id())
|
58
|
+
reference.add_attribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3")
|
59
|
+
cipher_data = encrypted_key.add_element(Names::CIPHER_DATA)
|
60
|
+
cipher_value = cipher_data.add_element(Names::CIPHER_VALUE)
|
61
|
+
cipher_value.text = @x509security_token.public_encrypt_b64(@symmetric_encrypter.key()).gsub("\n","")
|
62
|
+
reference_list = encrypted_key.add_element(Names::REFERENCE_LIST)
|
63
|
+
data_reference = reference_list.add_element(Names::DATA_REFERENCE)
|
64
|
+
data_reference.add_attribute("URI", "#" + @encrypted_data.ref_id())
|
65
|
+
end
|
66
|
+
|
67
|
+
def symmetric_encrypter()
|
68
|
+
@symmetric_encrypter
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end #Xml
|
73
|
+
end #Security
|
74
|
+
end #WSS4R
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module WSS4R
|
2
|
+
module Security
|
3
|
+
module Xml
|
4
|
+
|
5
|
+
class KeyInfo
|
6
|
+
attr_accessor :security_token, :type, :key_identifier
|
7
|
+
|
8
|
+
KEY_IDENTIFIER = "KEY_IDENTIFIER"
|
9
|
+
REFERENCE = "REFERENCE"
|
10
|
+
|
11
|
+
def initialize(p, *type)
|
12
|
+
if (p.kind_of?(SecurityToken))
|
13
|
+
@security_token = p
|
14
|
+
if (type != nil)
|
15
|
+
@type = type
|
16
|
+
else
|
17
|
+
@type = KEY_IDENTIFIER
|
18
|
+
end
|
19
|
+
else
|
20
|
+
reference = XPath.first(p, "wsse:SecurityTokenReference/wsse:Reference", {"wsse" => Namespaces::WSSE})
|
21
|
+
@uri = reference.attribute("URI").value()[1..-1]
|
22
|
+
@value_type = reference.attribute("ValueType").value()
|
23
|
+
@ref_element = XPath.first(p.document(), "//*[@wsu:Id='"+@uri+"']")
|
24
|
+
@security_token = X509SecurityToken.new(@ref_element.text())
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_xml(parent)
|
29
|
+
key_info = parent.add_element(Names::KEY_INFO)
|
30
|
+
security_token_ref = key_info.add_element(Names::SECURITY_TOKEN_REFERENCE)
|
31
|
+
security_token_ref.add_namespace("xmlns:wsu", Namespaces::WSU)
|
32
|
+
wsu_id = REXML::Attribute.new("wsu:Id",security_token_ref.object_id().to_s())
|
33
|
+
security_token_ref.add_attribute(wsu_id)
|
34
|
+
if (@type == "KEY_IDENTIFIER")
|
35
|
+
key_identifier = security_token_ref.add_element(Names::KEY_IDENTIFIER)
|
36
|
+
key_identifier.add_attribute("ValueType", Types::VALUE_KEYIDENTIFIER)
|
37
|
+
key_identifier.add_attribute("EncodingType", Types::ENCODING_X509V3)
|
38
|
+
key_identifier.text=(@security_token.key_identifier())
|
39
|
+
else
|
40
|
+
reference = security_token_ref.add_element(Names::REFERENCE_WSSE)
|
41
|
+
reference.add_attribute("ValueType", Types::REFERENCE_VALUETYPE_X509)
|
42
|
+
reference.add_attribute("URI", "#"+@security_token.get_id())
|
43
|
+
end
|
44
|
+
parent
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end #Xml
|
51
|
+
end #Security
|
52
|
+
end #WSS4R
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module WSS4R
|
2
|
+
module Security
|
3
|
+
module Xml
|
4
|
+
|
5
|
+
class Reference
|
6
|
+
attr_reader :uri
|
7
|
+
|
8
|
+
def initialize(element, prefix_list = nil)
|
9
|
+
@ref_element = nil
|
10
|
+
@transforms = Array.new()
|
11
|
+
@prefix_list = prefix_list
|
12
|
+
@uri = element.attribute("URI").to_s()[1..-1] #remove leading #
|
13
|
+
|
14
|
+
elements = XPath.match(element, "Transforms/Transform", {"ds:" => Namespaces::DS})
|
15
|
+
#element.each_element("ds:Transforms/ds:Transform"){|e|
|
16
|
+
elements.each{|e|
|
17
|
+
@transforms.push(e.attribute("Algorithm"))
|
18
|
+
}
|
19
|
+
elements = XPath.match(element, "ds:DigestMethod", {"ds" => Namespaces::DS})
|
20
|
+
#element.each_element("ds:DigestMethod"){|e|
|
21
|
+
elements.each{|e|
|
22
|
+
@digest_algorithm = e.attribute("Algorithm")
|
23
|
+
}
|
24
|
+
elements = XPath.match(element, "ds:DigestValue", {"ds" => Namespaces::DS})
|
25
|
+
#element.each_element("ds:DigestValue"){|e|
|
26
|
+
elements.each{|e|
|
27
|
+
@digest_value = e.text().strip()
|
28
|
+
}
|
29
|
+
@ref_element = XPath.first(element.document, "//*[@wsu:Id='"+@uri+"']")
|
30
|
+
end
|
31
|
+
|
32
|
+
def verify()
|
33
|
+
trans_element = nil
|
34
|
+
@transforms.each{|transform_algorithm|
|
35
|
+
transformer = TransformerFactory::get_instance(transform_algorithm)
|
36
|
+
transformer.prefix_list=(@prefix_list)
|
37
|
+
trans_element = transformer.canonicalize_element(@ref_element)
|
38
|
+
}
|
39
|
+
if (@transforms.size() == 0)
|
40
|
+
transformer = TransformerFactory::get_instance("http://www.w3.org/2001/10/xml-exc-c14n#")
|
41
|
+
transformer.prefix_list=(@prefix_list)
|
42
|
+
trans_element = transformer.canonicalize_element(@ref_element)
|
43
|
+
end
|
44
|
+
digester = DigestFactory::get_instance(@digest_algorithm.value())
|
45
|
+
digest = digester.digest_b64(trans_element)
|
46
|
+
return true if (digest == @digest_value)
|
47
|
+
false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module WSS4R
|
2
|
+
module Security
|
3
|
+
module Xml
|
4
|
+
|
5
|
+
class ReferenceList
|
6
|
+
attr_reader :uris
|
7
|
+
|
8
|
+
def initialize(referencelist)
|
9
|
+
@uris = parse_reference_list(referencelist)
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse_reference_list(list)
|
13
|
+
@uris = Array.new()
|
14
|
+
elements = list.get_elements("//" + Names::DATA_REFERENCE)
|
15
|
+
elements.each{|e|
|
16
|
+
@uris.push(e.attribute("URI").value())
|
17
|
+
}
|
18
|
+
@uris
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end #Xml
|
23
|
+
end #Security
|
24
|
+
end #WSS4R
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module WSS4R
|
2
|
+
module Security
|
3
|
+
module Xml
|
4
|
+
|
5
|
+
class Security
|
6
|
+
def initialize()
|
7
|
+
end
|
8
|
+
|
9
|
+
def process(document)
|
10
|
+
security = XPath.first(document, "/env:Envelope/env:Header/wsse:Security")#, {SOAPParser::soap_prefix=>SOAPParser::soap_ns})
|
11
|
+
return security if (security != nil)
|
12
|
+
header = XPath.first(document, "/env:Envelope/env:Header", {SOAPParser::soap_prefix=>SOAPParser::soap_ns})
|
13
|
+
security = header.add_element(Names::SECURITY, {"env:mustUnderstand"=>"1"})
|
14
|
+
security.add_namespace("xmlns:wsse", Namespaces::WSSE)
|
15
|
+
Timestamp.new().process(security)
|
16
|
+
security
|
17
|
+
end
|
18
|
+
|
19
|
+
def unprocess(document)
|
20
|
+
# Is the document signed?
|
21
|
+
#signature_element = SOAPParser.part(SOAPParser::SIGNATURE)
|
22
|
+
#wsse = XPath.first(document, "/soap:Envelope/soap:Header/wsse:Security", {"soap"=>Namespaces::SOAP})
|
23
|
+
wsse = XPath.first(document, "/env:Envelope/env:Header/wsse:Security")
|
24
|
+
|
25
|
+
timestamp = XPath.first(document, "/soap:Envelope/soap:Header/wsse:Security/wsu:Timestamp", {"soap"=>Namespaces::SOAP, "wsse"=>Namespaces::WSSE, "wsu"=>Namespaces::WSU})
|
26
|
+
#TODO: check timestamp, if it exists
|
27
|
+
if (timestamp != nil)
|
28
|
+
t = Timestamp.new()
|
29
|
+
t.unprocess(timestamp)
|
30
|
+
t.verify()
|
31
|
+
end
|
32
|
+
signature_element = XPath.first(document, "/env:Envelope/env:Header/wsse:Security/ds:Signature", {"env"=>Namespaces::SOAP, "ds"=>Namespaces::DS})
|
33
|
+
header = XPath.first(document, "/env:Envelope/env:Header", {"env"=>Namespaces::SOAP, "ds"=>Namespaces::DS})
|
34
|
+
|
35
|
+
encrypted_key_element = SOAPParser.part(SOAPParser::ENCRYPTED_KEY)
|
36
|
+
|
37
|
+
signature_index = wsse.index_of(signature_element) || 0
|
38
|
+
encryption_index = wsse.index_of(encrypted_key_element)
|
39
|
+
|
40
|
+
if (signature_index < encryption_index)
|
41
|
+
if (signature_element != nil)
|
42
|
+
handle_signature(signature_element)
|
43
|
+
end
|
44
|
+
encrypted_key_element = SOAPParser.part(SOAPParser::ENCRYPTED_KEY)
|
45
|
+
if (encrypted_key_element != nil)
|
46
|
+
handle_encryption(document, encrypted_key_element)
|
47
|
+
end
|
48
|
+
else
|
49
|
+
encrypted_key_element = SOAPParser.part(SOAPParser::ENCRYPTED_KEY)
|
50
|
+
if (encrypted_key_element != nil)
|
51
|
+
handle_encryption(document, encrypted_key_element)
|
52
|
+
end
|
53
|
+
signature_element = XPath.first(document, "/env:Envelope/env:Header/wsse:Security/ds:Signature", {"env"=>Namespaces::SOAP, "ds"=>Namespaces::DS})
|
54
|
+
if (signature_element != nil)
|
55
|
+
handle_signature(signature_element)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
#UsernameToken in the document?
|
59
|
+
usernametoken = XPath.first(document, "/env:Envelope/env:Header/wsse:Security/wsse:UsernameToken", {"env"=>Namespaces::SOAP, "ds"=>Namespaces::DS})
|
60
|
+
if (usernametoken)
|
61
|
+
handle_usernametoken(document, usernametoken)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def handle_signature(signature_element)
|
66
|
+
signature = Signature.new(nil)
|
67
|
+
signature.unprocess(signature_element)
|
68
|
+
signature.verify()
|
69
|
+
end
|
70
|
+
|
71
|
+
def handle_encryption(document, encrypted_key_element)
|
72
|
+
encrypted_key = EncryptedKey.new()
|
73
|
+
encrypted_key.unprocess(encrypted_key_element)
|
74
|
+
encrypted_data = EncryptedData.new(encrypted_key.x509security_token())
|
75
|
+
body = SOAPParser.part(SOAPParser::BODY)
|
76
|
+
encrypted_data.unprocess(body.get_elements("//xenc:EncryptedData")[0])
|
77
|
+
encrypted_data.decrypt(document, encrypted_key)
|
78
|
+
end
|
79
|
+
|
80
|
+
def handle_usernametoken(document, token)
|
81
|
+
usernametoken = UsernameToken.new()
|
82
|
+
usernametoken.unprocess(token)
|
83
|
+
resolver = WSS4R::Security::Security.new().resolver()
|
84
|
+
success = resolver.authenticate_user(usernametoken)
|
85
|
+
return true if success
|
86
|
+
raise Exception.new("User not authenticated!") if (!success)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end #Xml
|
91
|
+
end #Security
|
92
|
+
end #WSS4R
|