rack-tctp 0.9.13 → 0.9.14
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 +4 -4
- data/ext/engine/engine.c +229 -229
- data/ext/engine/extconf.rb +6 -6
- data/lib/rack/tctp.rb +263 -260
- data/lib/rack/tctp/halec.rb +220 -212
- metadata +32 -18
data/lib/rack/tctp/halec.rb
CHANGED
@@ -1,213 +1,221 @@
|
|
1
|
-
require 'openssl'
|
2
|
-
require 'socket'
|
3
|
-
require 'radix'
|
4
|
-
|
5
|
-
require 'rack/tctp/engine'
|
6
|
-
|
7
|
-
# HTTP application layer encryption channel. Used for the Trusted Cloud Transfer Protocol (TCTP)
|
8
|
-
class Rack::TCTP::HALEC
|
9
|
-
# The SSL engine
|
10
|
-
attr_reader :engine
|
11
|
-
|
12
|
-
# The URL of this HALEC
|
13
|
-
attr_accessor :url
|
14
|
-
|
15
|
-
# The private key for a certificate (if any)
|
16
|
-
attr_reader :private_key
|
17
|
-
|
18
|
-
# A server or client certificate (if any)
|
19
|
-
attr_reader :certificate
|
20
|
-
|
21
|
-
# The thread for encrypting and decrypting data of this HALEC
|
22
|
-
attr_reader :async_thread
|
23
|
-
|
24
|
-
# The queue for encrypting and decrypting data
|
25
|
-
# @return [Queue] The async queue
|
26
|
-
# @!attr [r] async_queue
|
27
|
-
def async_queue
|
28
|
-
unless @async_queue
|
29
|
-
@async_queue = Queue.new
|
30
|
-
|
31
|
-
@async_thread = Thread.new do
|
32
|
-
begin
|
33
|
-
while true
|
34
|
-
item = @async_queue.pop
|
35
|
-
|
36
|
-
case item[0]
|
37
|
-
when :encrypt
|
38
|
-
item[2].call encrypt_data(item[1])
|
39
|
-
when :decrypt
|
40
|
-
item[2].call decrypt_data(item[1])
|
41
|
-
when :call
|
42
|
-
item[2].call
|
43
|
-
end
|
44
|
-
end
|
45
|
-
rescue Exception => e
|
46
|
-
#TODO Handle HALEC encryption thread shutdown
|
47
|
-
#TODO Handle OpenSSL error
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
#
|
63
|
-
# @
|
64
|
-
# @
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
#
|
90
|
-
# @
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
#
|
98
|
-
# @
|
99
|
-
# @
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
#
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
@
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
@
|
171
|
-
@
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
end
|
187
|
-
|
188
|
-
def
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
cert
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
1
|
+
require 'openssl'
|
2
|
+
require 'socket'
|
3
|
+
require 'radix'
|
4
|
+
|
5
|
+
require 'rack/tctp/engine'
|
6
|
+
|
7
|
+
# HTTP application layer encryption channel. Used for the Trusted Cloud Transfer Protocol (TCTP)
|
8
|
+
class Rack::TCTP::HALEC
|
9
|
+
# The SSL engine
|
10
|
+
attr_reader :engine
|
11
|
+
|
12
|
+
# The URL of this HALEC
|
13
|
+
attr_accessor :url
|
14
|
+
|
15
|
+
# The private key for a certificate (if any)
|
16
|
+
attr_reader :private_key
|
17
|
+
|
18
|
+
# A server or client certificate (if any)
|
19
|
+
attr_reader :certificate
|
20
|
+
|
21
|
+
# The thread for encrypting and decrypting data of this HALEC
|
22
|
+
attr_reader :async_thread
|
23
|
+
|
24
|
+
# The queue for encrypting and decrypting data
|
25
|
+
# @return [Queue] The async queue
|
26
|
+
# @!attr [r] async_queue
|
27
|
+
def async_queue
|
28
|
+
unless @async_queue
|
29
|
+
@async_queue = Queue.new
|
30
|
+
|
31
|
+
@async_thread = Thread.new do
|
32
|
+
begin
|
33
|
+
while true
|
34
|
+
item = @async_queue.pop
|
35
|
+
|
36
|
+
case item[0]
|
37
|
+
when :encrypt
|
38
|
+
item[2].call encrypt_data(item[1])
|
39
|
+
when :decrypt
|
40
|
+
item[2].call decrypt_data(item[1])
|
41
|
+
when :call
|
42
|
+
item[2].call
|
43
|
+
end
|
44
|
+
end
|
45
|
+
rescue Exception => e
|
46
|
+
#TODO Handle HALEC encryption thread shutdown
|
47
|
+
#TODO Handle OpenSSL error
|
48
|
+
unless item[0] == :call
|
49
|
+
item[2].call e
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
@async_queue
|
56
|
+
end
|
57
|
+
|
58
|
+
def initialize(options = {})
|
59
|
+
@url = options[:url] || nil
|
60
|
+
end
|
61
|
+
|
62
|
+
# Encrypts +plaintext+ data and either returns the encrypted data or calls a block with it.
|
63
|
+
# @param [String] plaintext The plaintext
|
64
|
+
# @return [String] The encrypted data
|
65
|
+
# @yield Gives the encrypted data to the block
|
66
|
+
# @yieldparam [String] The encrypted data
|
67
|
+
def encrypt_data(plaintext, &encrypted)
|
68
|
+
written = @engine.write plaintext
|
69
|
+
|
70
|
+
if written < plaintext.length
|
71
|
+
exit -1
|
72
|
+
end
|
73
|
+
|
74
|
+
read_data = []
|
75
|
+
|
76
|
+
while(read_chunk = @engine.extract)
|
77
|
+
read_data << read_chunk
|
78
|
+
end
|
79
|
+
|
80
|
+
if block_given?
|
81
|
+
read_data.each do |data|
|
82
|
+
encrypted.call data
|
83
|
+
end
|
84
|
+
else
|
85
|
+
read_data.join
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Encrypts +plaintext+ data asynchronously, yielding data to the block when done.
|
90
|
+
# @param [String] plaintext The plaintext
|
91
|
+
# @yield Gives the encrypted data to the block
|
92
|
+
# @yieldparam [String|Exception] The encrypted data or an exception
|
93
|
+
def encrypt_data_async(plaintext, &encrypted)
|
94
|
+
async_queue.push [:encrypt, plaintext, encrypted]
|
95
|
+
end
|
96
|
+
|
97
|
+
# Decrypts +encrypted+ data and either returns the plaintext or calls a block with it.
|
98
|
+
# @param [String] encrypted The encrypted data
|
99
|
+
# @return [String] The plaintext
|
100
|
+
# @yield Gives the plaintext to the block
|
101
|
+
# @yieldparam [String] The plaintext
|
102
|
+
def decrypt_data(encrypted, &decrypted)
|
103
|
+
injected = @engine.inject encrypted
|
104
|
+
|
105
|
+
unless injected
|
106
|
+
exit -1
|
107
|
+
end
|
108
|
+
|
109
|
+
read_data = []
|
110
|
+
|
111
|
+
begin
|
112
|
+
while(read_chunk = @engine.read)
|
113
|
+
read_data << read_chunk
|
114
|
+
end
|
115
|
+
rescue Exception => e
|
116
|
+
unless @engine.state == 'SSLOK '
|
117
|
+
raise e
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
if block_given? then
|
122
|
+
read_data.each do |data|
|
123
|
+
decrypted.call data
|
124
|
+
end
|
125
|
+
else
|
126
|
+
read_data.join
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Decrypts +encrypted+ data asynchronously, yielding data to the block when done.
|
131
|
+
# @param [String] encrypted The encrypted data
|
132
|
+
# @yield Gives the decrypted data to the block
|
133
|
+
# @yieldparam [String|Exception] the decrypted data or an exception
|
134
|
+
def decrypt_data_async(encrypted, &decrypted)
|
135
|
+
async_queue.push [:decrypt, encrypted, decrypted]
|
136
|
+
end
|
137
|
+
|
138
|
+
# Calls a given block asynchronously, considering the order of all calls to async methods.
|
139
|
+
def call_async(&block)
|
140
|
+
async_queue.push [:call, nil, block]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# The Client end of an HALEC
|
145
|
+
class Rack::TCTP::ClientHALEC < Rack::TCTP::HALEC
|
146
|
+
def initialize(options = {})
|
147
|
+
super(options)
|
148
|
+
|
149
|
+
@engine = Rack::TCTP::Engine.client
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# The Server end of an HALEC
|
154
|
+
class Rack::TCTP::ServerHALEC < Rack::TCTP::HALEC
|
155
|
+
def initialize(options = {})
|
156
|
+
super(options)
|
157
|
+
|
158
|
+
if(options[:private_key] && options[:certificate])
|
159
|
+
@private_key = options[:private_key]
|
160
|
+
@certificate = options[:certificate]
|
161
|
+
else
|
162
|
+
@private_key = self.class.default_key
|
163
|
+
@certificate = self.class.default_self_signed_certificate
|
164
|
+
end
|
165
|
+
|
166
|
+
@private_key_file = Tempfile.new('rack_tctp_pk')
|
167
|
+
@private_key_file.write @private_key.to_s
|
168
|
+
@private_key_file.close
|
169
|
+
|
170
|
+
@certificate_file = Tempfile.new('rack_tctp_cert')
|
171
|
+
@certificate_file.write @certificate.to_s
|
172
|
+
@certificate_file.close
|
173
|
+
|
174
|
+
@engine = Rack::TCTP::Engine.server(@private_key_file.path, @certificate_file.path)
|
175
|
+
end
|
176
|
+
|
177
|
+
class << self
|
178
|
+
@default_key
|
179
|
+
@default_self_signed_certificate
|
180
|
+
|
181
|
+
def initialize
|
182
|
+
default_key
|
183
|
+
default_self_signed_certificate
|
184
|
+
|
185
|
+
self
|
186
|
+
end
|
187
|
+
|
188
|
+
def default_key
|
189
|
+
@default_key ||= OpenSSL::PKey::RSA.new 2048
|
190
|
+
end
|
191
|
+
|
192
|
+
def default_self_signed_certificate
|
193
|
+
@default_self_signed_certificate ||= generate_self_signed_certificate
|
194
|
+
end
|
195
|
+
|
196
|
+
def generate_self_signed_certificate
|
197
|
+
name = OpenSSL::X509::Name.parse 'CN=tctp-server/DC=tctp'
|
198
|
+
|
199
|
+
cert = OpenSSL::X509::Certificate.new
|
200
|
+
cert.version = 2
|
201
|
+
cert.serial = 0
|
202
|
+
cert.not_before = Time.now
|
203
|
+
cert.not_after = Time.now + 3600
|
204
|
+
|
205
|
+
cert.public_key = @default_key.public_key
|
206
|
+
cert.subject = name
|
207
|
+
|
208
|
+
cert
|
209
|
+
end
|
210
|
+
|
211
|
+
# The slug URI can contain any HTTP compatible characters
|
212
|
+
def slug_base
|
213
|
+
Radix::Base.new(Radix::BASE::B62 + ['-', '_'])
|
214
|
+
end
|
215
|
+
|
216
|
+
# Generate a new random slug (2^64 possibilities)
|
217
|
+
def new_slug
|
218
|
+
slug_base.convert(rand(2**64), 10)
|
219
|
+
end
|
220
|
+
end
|
213
221
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-tctp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mathias Slawik
|
@@ -14,84 +14,98 @@ dependencies:
|
|
14
14
|
name: faker
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 1.1.2
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.1.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rack-test
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 0.6.2
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.6.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: test-unit
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 2.5.5
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 2.5.5
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: ruby-prof
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 0.13.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.13.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake-compiler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.9'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.9'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rest-client
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- - ~>
|
87
|
+
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: 1.6.7
|
76
90
|
type: :runtime
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- - ~>
|
94
|
+
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: 1.6.7
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: radix
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- - ~>
|
101
|
+
- - "~>"
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: 2.2.0
|
90
104
|
type: :runtime
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
|
-
- - ~>
|
108
|
+
- - "~>"
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: 2.2.0
|
97
111
|
description: Rack middleware for end-to-end security through TCTP
|
@@ -101,11 +115,11 @@ extensions:
|
|
101
115
|
- ext/engine/extconf.rb
|
102
116
|
extra_rdoc_files: []
|
103
117
|
files:
|
118
|
+
- ext/engine/engine.c
|
119
|
+
- ext/engine/extconf.rb
|
104
120
|
- lib/rack-tctp.rb
|
105
121
|
- lib/rack/tctp.rb
|
106
122
|
- lib/rack/tctp/halec.rb
|
107
|
-
- ext/engine/engine.c
|
108
|
-
- ext/engine/extconf.rb
|
109
123
|
homepage: https://github.com/mathiasslawik/rack-tctp
|
110
124
|
licenses:
|
111
125
|
- Apache-2.0
|
@@ -116,17 +130,17 @@ require_paths:
|
|
116
130
|
- lib
|
117
131
|
required_ruby_version: !ruby/object:Gem::Requirement
|
118
132
|
requirements:
|
119
|
-
- -
|
133
|
+
- - ">="
|
120
134
|
- !ruby/object:Gem::Version
|
121
135
|
version: '0'
|
122
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
137
|
requirements:
|
124
|
-
- -
|
138
|
+
- - ">="
|
125
139
|
- !ruby/object:Gem::Version
|
126
140
|
version: '0'
|
127
141
|
requirements: []
|
128
142
|
rubyforge_project:
|
129
|
-
rubygems_version: 2.
|
143
|
+
rubygems_version: 2.2.1
|
130
144
|
signing_key:
|
131
145
|
specification_version: 4
|
132
146
|
summary: Rack TCTP middleware
|