wss4r 0.5

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 (39) hide show
  1. data/README +300 -0
  2. data/lib/wss4r/aws/utils.rb +37 -0
  3. data/lib/wss4r/config/config.rb +105 -0
  4. data/lib/wss4r/rpc/proxy.rb +26 -0
  5. data/lib/wss4r/rpc/router.rb +46 -0
  6. data/lib/wss4r/rpc/wssdriver.rb +19 -0
  7. data/lib/wss4r/security/crypto/certificate.rb +21 -0
  8. data/lib/wss4r/security/crypto/cipher.rb +161 -0
  9. data/lib/wss4r/security/crypto/hash.rb +35 -0
  10. data/lib/wss4r/security/exceptions/exceptions.rb +62 -0
  11. data/lib/wss4r/security/resolver.rb +23 -0
  12. data/lib/wss4r/security/security.rb +148 -0
  13. data/lib/wss4r/security/util/hash_util.rb +39 -0
  14. data/lib/wss4r/security/util/names.rb +38 -0
  15. data/lib/wss4r/security/util/namespaces.rb +21 -0
  16. data/lib/wss4r/security/util/reference_elements.rb +15 -0
  17. data/lib/wss4r/security/util/soap_parser.rb +73 -0
  18. data/lib/wss4r/security/util/transformer_factory.rb +29 -0
  19. data/lib/wss4r/security/util/types.rb +25 -0
  20. data/lib/wss4r/security/util/xmlcanonicalizer.rb +427 -0
  21. data/lib/wss4r/security/util/xmlutils.rb +58 -0
  22. data/lib/wss4r/security/xml/encrypted_data.rb +110 -0
  23. data/lib/wss4r/security/xml/encrypted_key.rb +74 -0
  24. data/lib/wss4r/security/xml/key_info.rb +52 -0
  25. data/lib/wss4r/security/xml/reference.rb +53 -0
  26. data/lib/wss4r/security/xml/reference_list.rb +24 -0
  27. data/lib/wss4r/security/xml/security.rb +92 -0
  28. data/lib/wss4r/security/xml/signature.rb +69 -0
  29. data/lib/wss4r/security/xml/signature_value.rb +26 -0
  30. data/lib/wss4r/security/xml/signed_info.rb +83 -0
  31. data/lib/wss4r/security/xml/timestamp.rb +47 -0
  32. data/lib/wss4r/security/xml/tokentypes.rb +180 -0
  33. data/lib/wss4r/server/wssstandaloneserver.rb +27 -0
  34. data/lib/wss4r/soap/processor.rb +92 -0
  35. data/lib/wss4r/tokenresolver/authenticateuserresolver.rb +34 -0
  36. data/lib/wss4r/tokenresolver/certificateresolver.rb +62 -0
  37. data/lib/wss4r/tokenresolver/databaseresolver.rb +56 -0
  38. data/lib/wss4r/tokenresolver/resolver.rb +13 -0
  39. metadata +95 -0
@@ -0,0 +1,46 @@
1
+ class SOAP::RPC::Router
2
+ def unmarshal(conn_data)
3
+ opt = {}
4
+ opt[:security] = @security
5
+ contenttype = conn_data.receive_contenttype
6
+ if /#{MIMEMessage::MultipartContentType}/i =~ contenttype
7
+ opt[:external_content] = {}
8
+ mime = MIMEMessage.parse("Content-Type: " + contenttype, conn_data.receive_string)
9
+ mime.parts.each do |part|
10
+ value = Attachment.new(part.content)
11
+ value.contentid = part.contentid
12
+ obj = SOAPAttachment.new(value)
13
+ opt[:external_content][value.contentid] = obj if value.contentid
14
+ end
15
+ opt[:charset] = StreamHandler.parse_media_type(mime.root.headers['content-type'].str)
16
+ env = Processor.unmarshal(mime.root.content, opt)
17
+ else
18
+ opt[:charset] = ::SOAP::StreamHandler.parse_media_type(contenttype)
19
+ env = Processor.unmarshal(conn_data.receive_string, opt)
20
+ end
21
+ charset = opt[:charset]
22
+ conn_data.send_contenttype = "text/xml; charset=\"#{charset}\""
23
+ env
24
+ end
25
+
26
+ def marshal(conn_data, env, default_encodingstyle = nil)
27
+ opt = {}
28
+ opt[:security] = @security
29
+ opt[:external_content] = nil
30
+ opt[:default_encodingstyle] = default_encodingstyle
31
+ opt[:generate_explicit_type] = @generate_explicit_type
32
+ response_string = Processor.marshal(env, opt)
33
+ conn_data.send_string = response_string
34
+ if ext = opt[:external_content]
35
+ mimeize(conn_data, ext)
36
+ end
37
+ conn_data
38
+ end
39
+
40
+ def security()
41
+ if (@security == nil)
42
+ @security = Security.new()
43
+ end
44
+ @security
45
+ end
46
+ end
@@ -0,0 +1,19 @@
1
+ require "soap/rpc/driver"
2
+ require "soap/soap"
3
+ require "soap/processor"
4
+ require "wss4r/security/security"
5
+ require "wss4r/soap/processor"
6
+ require "wss4r/rpc/proxy"
7
+ require "wss4r/rpc/router"
8
+
9
+ include SOAP
10
+
11
+ module SOAP
12
+ module RPC
13
+ class Driver
14
+ def security()
15
+ @proxy.security()
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ module OpenSSL
2
+ module X509
3
+
4
+ class Certificate
5
+ def key_identifier()
6
+ ext = extensions.find {|e| e.oid == 'subjectKeyIdentifier' }
7
+ key_identifier = Base64.encode64(ext.to_der()[11..30])
8
+ return key_identifier.gsub("\n","")
9
+ end
10
+
11
+ def filename()
12
+ return @filename
13
+ end
14
+
15
+ def filename=(filename)
16
+ @filename = filename
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,161 @@
1
+ module WSS4R
2
+ module Security
3
+ module Crypto
4
+
5
+ class SymmetricEncrypter
6
+ def initialize(algorithm, key = nil, iv = nil)
7
+ @cipher = Cipher.new(algorithm)
8
+ @algorithm = algorithm
9
+ if (iv == nil)
10
+ @iv = @cipher.random_iv()
11
+ else
12
+ @iv = iv
13
+ end
14
+ if (key == nil)
15
+ @key = @cipher.random_key()
16
+ else
17
+ @key = key
18
+ end
19
+ end
20
+
21
+ def encrypt_to_b64(text)
22
+ @cipher.encrypt(@key, @iv)
23
+ @cipher.key = @key
24
+ cipher = @cipher.update(text)
25
+ cipher << @cipher.final()
26
+ Base64.encode64(cipher)
27
+ end
28
+
29
+ def decrypt(text)
30
+ @cipher.decrypt(@key, @iv)
31
+ @cipher.key = @key
32
+ @cipher.iv = @iv
33
+ cipher = @cipher.update(text[8..-1])
34
+ cipher << @cipher.final()
35
+ cipher
36
+ end
37
+
38
+ def iv()
39
+ @iv
40
+ end
41
+
42
+ def key()
43
+ @key
44
+ end
45
+
46
+ def key=(key)
47
+ @key
48
+ end
49
+
50
+ def iv_b64()
51
+ Base64.encode64(@iv)
52
+ end
53
+
54
+ def key_b64()
55
+ Base64.encode64(@key)
56
+ end
57
+ end
58
+
59
+ class TripleDESSymmetricEncrypter < SymmetricEncrypter
60
+ def initialize(key = nil, iv = nil)
61
+ @cipher = Cipher.new("DES-EDE3-CBC")
62
+ if (iv == nil)
63
+ @iv = @cipher.random_iv()
64
+ else
65
+ @iv = iv
66
+ end
67
+ if (key == nil)
68
+ @key = @cipher.random_key()
69
+ else
70
+ @key = key
71
+ end
72
+ end
73
+
74
+ def decrypt(text)
75
+ @cipher.decrypt(@key, @iv)
76
+ @cipher.key = @key
77
+ @cipher.iv = @iv
78
+ cipher = @cipher.update(text[8..-1])
79
+ cipher << @cipher.final()
80
+ cipher
81
+ end
82
+
83
+ def algorithm()
84
+ Types::ALGORITHM_3DES_CBC
85
+ end
86
+
87
+ def iv=(text_iv)
88
+ @iv = text_iv[0..7]
89
+ end
90
+ end
91
+
92
+ class AESSymmetricEncrypter < SymmetricEncrypter
93
+ def initialize(key = nil, iv = nil)
94
+ @cipher = Cipher.new(self.cipher_name)
95
+ if (iv == nil)
96
+ @iv = @cipher.random_iv()
97
+ else
98
+ @iv = iv
99
+ end
100
+ if (key == nil)
101
+ @key = @cipher.random_key()
102
+ else
103
+ @key = key
104
+ end
105
+ end
106
+
107
+ def decrypt(text)
108
+ @cipher.decrypt(@key, @iv)
109
+ @cipher.key = @key
110
+ @cipher.iv = @iv
111
+ cipher = @cipher.update(text[16..-1])
112
+ cipher << @cipher.final()
113
+ cipher
114
+ end
115
+
116
+ def algorithm()
117
+ Types::ALGORITHM_AES_CBC
118
+ end
119
+
120
+ def cipher_name()
121
+ "AES-256-CBC"
122
+ end
123
+
124
+ def iv=(text_iv)
125
+ @iv = text_iv[0..15]
126
+ end
127
+ end
128
+
129
+ class AES128SymmetricEncrypter < AESSymmetricEncrypter
130
+ def initialize(key = nil, iv = nil)
131
+ super(key, iv)
132
+ end
133
+
134
+ def algorithm()
135
+ Types::ALGORITHM_AES128_CBC
136
+ end
137
+
138
+ def cipher_name()
139
+ "AES-128-CBC"
140
+ end
141
+ end
142
+
143
+ class AsymmetricEncrypter
144
+ def initialize(filename)
145
+ @private_key = RSA.new(File.read(filename))
146
+ end
147
+
148
+ def decrypt_symmetrickey_from_b64(text)
149
+ ciphertext = @private_rsa_key.private_decrypt(text)
150
+ iv = ciphertext[0..7]
151
+ key = ciphertext[8..-1]
152
+ symmetric_key = Cipher.new(@symmetric_algorithm)
153
+ symmetric_key.decrypt(key, iv)
154
+ symmetric_key.key = key
155
+ symmetric_key
156
+ end
157
+ end
158
+
159
+ end #Crypto
160
+ end #Security
161
+ end #WSS4R
@@ -0,0 +1,35 @@
1
+ require "openssl"
2
+ include OpenSSL
3
+ include OpenSSL::Digest
4
+
5
+
6
+ module WSS4R
7
+ module Security
8
+ module Crypto
9
+
10
+ class CryptHash
11
+
12
+ def initialize(type = "SHA1")
13
+ @digest = SHA1.new() if (type == "SHA1")
14
+ @digest = MD5.new() if (type == "MD5")
15
+ end
16
+
17
+ def digest(value)
18
+ @digest.update(value)
19
+ return @digest.digest()
20
+ end
21
+
22
+ def digest_b64(value)
23
+ digest = self.digest(value)
24
+ return Base64.encode64(digest)
25
+ end
26
+
27
+ def to_s()
28
+ return @digest.to_s()
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,62 @@
1
+ module WSS4R
2
+ module Security
3
+ module Exceptions
4
+
5
+ class FaultString
6
+ attr_reader :data
7
+ def initialize(data)
8
+ @data = data
9
+ end
10
+ end
11
+
12
+ class WSS4RFault < SOAP::FaultError
13
+ attr_accessor :faultcode, :faultstring, :faultactor, :detail
14
+
15
+ def initialize(faultcode,faultstring,faultactor,detail)
16
+ @faultcode = faultcode
17
+ @faultstring = FaultString.new(faultstring)
18
+ @faultactor = faultactor
19
+ @detail = detail
20
+ end
21
+ end
22
+
23
+ class VerificationFault < WSS4RFault
24
+ def initialize()
25
+ @faultcode = "100"
26
+ @faultstring = FaultString.new("Signature not valid!")
27
+ @faultactor = "test"
28
+ @detail = "Signature verification failed."
29
+ end
30
+ end
31
+
32
+ class TimestampFault < WSS4RFault
33
+ def initialize()
34
+ @faultcode = "101"
35
+ @faultstring = FaultString.new("Timestamp not valid")
36
+ @faultactor = "test"
37
+ @detail = "Timestamp verification failed."
38
+ end
39
+ end
40
+
41
+ class UsernameTokenFault < WSS4RFault
42
+ def initialize()
43
+ @faultcode = "102"
44
+ @faultstring = FaultString.new("UsernameToken not valid")
45
+ @faultactor = "test"
46
+ @detail = "UsernameToken verification failed."
47
+ end
48
+ end
49
+
50
+ class NoSecurityFault < WSS4RFault
51
+ def initialize()
52
+ @faultcode = "103"
53
+ @faultstring = FaultString.new("No security token received.")
54
+ @faultactor = "test"
55
+ @detail = "No security token received."
56
+ end
57
+ end
58
+
59
+ end #WSS4R
60
+ end #Security
61
+ end #Exceptions
62
+
@@ -0,0 +1,23 @@
1
+ class Resolver < Array
2
+ def authenticate_user(usernametoken)
3
+ self.each{|r|
4
+ success = r.authenticate_user(usernametoken)
5
+ return true if (success)
6
+ }
7
+ false
8
+ end
9
+ def private_key(certificate)
10
+ self.each{|r|
11
+ key = r.private_key(certificate)
12
+ return key if (key)
13
+ }
14
+ nil
15
+ end
16
+ def certificate_by_subject(subject)
17
+ self.each{|r|
18
+ certificate = r.certificate_by_subject(subject)
19
+ return certificate if (certificate)
20
+ }
21
+ nil
22
+ end
23
+ end
@@ -0,0 +1,148 @@
1
+ require "wss4r/security/xml/encrypted_key"
2
+ require "wss4r/security/xml/signature"
3
+ require "wss4r/security/xml/tokentypes"
4
+ require "wss4r/security/xml/encrypted_data"
5
+ require "wss4r/security/xml/reference_list"
6
+ require "wss4r/security/xml/security"
7
+ require "wss4r/security/xml/signed_info"
8
+ require "wss4r/security/xml/key_info"
9
+ require "wss4r/security/xml/signature_value"
10
+ require "wss4r/security/xml/reference"
11
+ require "wss4r/security/xml/timestamp"
12
+
13
+ require "wss4r/security/crypto/certificate"
14
+ require "wss4r/security/crypto/cipher"
15
+ require "wss4r/security/crypto/hash"
16
+
17
+ require "wss4r/security/util/transformer_factory"
18
+ require "wss4r/security/util/reference_elements"
19
+ require "wss4r/security/util/xmlcanonicalizer"
20
+ require "wss4r/security/util/namespaces"
21
+ require "wss4r/security/util/xmlutils"
22
+ require "wss4r/security/util/names"
23
+ require "wss4r/security/util/types"
24
+ require "wss4r/security/util/soap_parser"
25
+ require "wss4r/security/exceptions/exceptions"
26
+
27
+ require "wss4r/config/config"
28
+ require "wss4r/security/resolver"
29
+
30
+ require "time"
31
+ require "base64"
32
+ require "rexml/document"
33
+
34
+ require "soap/rpc/driver"
35
+ include SOAP
36
+
37
+ include OpenSSL
38
+ include OpenSSL::X509
39
+ include OpenSSL::Digest
40
+ include OpenSSL::Cipher
41
+ include OpenSSL::PKey
42
+
43
+ include WSS4R::Security::Xml
44
+ include WSS4R::Security::Util
45
+ include WSS4R::Security::Crypto
46
+ include WSS4R::Security::Exceptions
47
+
48
+
49
+ module WSS4R
50
+ module Security
51
+
52
+ class Security
53
+ attr_reader :tokens
54
+
55
+ @@resolver = Resolver.new()
56
+
57
+ def initialize()
58
+ @tokens = Array.new()
59
+ end
60
+
61
+ def add_security_token(token)
62
+ @tokens.push(token)
63
+ end
64
+
65
+ def add_security_resolver(resolver)
66
+ @@resolver.push(resolver)
67
+ end
68
+
69
+ def clear_resolver!()
70
+ @@resolver.clear()
71
+ end
72
+
73
+ def clear_tokens!()
74
+ @tokens.clear()
75
+ end
76
+
77
+ def resolver()
78
+ @@resolver
79
+ end
80
+
81
+ def process_document_marshal(document)
82
+ return if (@tokens.size() == 0)
83
+ SOAPParser.document=(document)
84
+
85
+ document.root.add_namespace("xmlns:wsu", Namespaces::WSU)
86
+ document.root.add_namespace("xmlns:wsse", Namespaces::WSSE)
87
+ document.root.add_namespace("xmlns:wsa", Namespaces::WSA)
88
+ document.root.add_namespace("xmlns:xenc", Namespaces::XENCD)
89
+ document.root.add_namespace("xmlns:xsd", Namespaces::XSD)
90
+ document.root.add_namespace("xmlns:xsi", Namespaces::XSI)
91
+ root = document.root()
92
+ soap_prefix = nil
93
+ soap_ns=nil
94
+ root.attributes.each_attribute() {|attr|
95
+ if (attr.value() == Namespaces::S11)
96
+ soap_prefix = attr.name()
97
+ soap_ns = Namespaces::S11
98
+ end
99
+ if (attr.value() == Namespaces::S12)
100
+ soap_prefix = attr.name()
101
+ soap_ns = Namespaces::S12
102
+ end
103
+ }
104
+ SOAPParser::soap_ns=(soap_ns)
105
+ SOAPParser::soap_prefix=(soap_prefix)
106
+
107
+ soap_body = XPath.first(document, "/env:Envelope/env:Body", {SOAPParser::soap_prefix => SOAPParser::soap_ns})
108
+
109
+ #soap_body = XPath.first(document, soap_prefix+":Envelope/"+soap_prefix+":Body")
110
+ #soap_body = SOAPParser.part(SOAPParser::BODY)
111
+ return if !soap_body
112
+ root.delete_element(soap_body)
113
+ soap_header = SOAPParser.part(SOAPParser::HEADER)
114
+ if (soap_header == nil)
115
+ soap_header = root.add_element(Names::HEADER)
116
+ end
117
+ root.add_element(soap_body)
118
+ security = WSS4R::Security::Xml::Security.new()
119
+
120
+ security.process(document)
121
+
122
+ @tokens.each{|token|
123
+ token.process(document)
124
+ }
125
+ ####Sort
126
+ security = XPath.first(root, "/env:Envelope/env:Header/wsse:Security")#, {SOAPParser::soap_prefix=>SOAPParser::soap_ns})
127
+ timestamp = XPath.first(security, "wsu:Timestamp")
128
+ @t = timestamp
129
+ @s = security
130
+ children = security.children()
131
+ children.each{|child|
132
+ security.delete(child)
133
+ }
134
+ children.delete(timestamp)
135
+ security.add_element(timestamp)
136
+ children.each{|child|
137
+ security.add_element(child)
138
+ }
139
+ end
140
+
141
+ def process_document_unmarshal(document)
142
+ security = WSS4R::Security::Xml::Security.new()
143
+ security.unprocess(document)
144
+ end
145
+ end
146
+
147
+ end #Security
148
+ end #WSS4R