wss4r 0.5

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