mt-ruby-tls 2.4.0
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 +7 -0
- data/README.md +102 -0
- data/lib/mt-ruby-tls/ssl.rb +864 -0
- data/lib/mt-ruby-tls/version.rb +5 -0
- data/lib/mt-ruby-tls.rb +6 -0
- data/mt-ruby-tls.gemspec +31 -0
- data/spec/alpn_spec.rb +415 -0
- data/spec/client.crt +31 -0
- data/spec/client.key +51 -0
- data/spec/comms_spec.rb +120 -0
- data/spec/verify_spec.rb +267 -0
- metadata +121 -0
data/lib/mt-ruby-tls.rb
ADDED
data/mt-ruby-tls.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
$:.push File.expand_path("../lib", __FILE__)
|
5
|
+
require "mt-ruby-tls/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "mt-ruby-tls"
|
9
|
+
s.version = MTRubyTls::VERSION
|
10
|
+
s.authors = ["Giallombardo Nathan"]
|
11
|
+
s.email = ["nathan.giallombardo@mapotempo.com"]
|
12
|
+
s.licenses = ["MIT"]
|
13
|
+
s.homepage = "https://github.com/Mapotempo/mt-ruby-tls"
|
14
|
+
s.summary = "Abstract TLS for Ruby"
|
15
|
+
s.description = <<-EOF
|
16
|
+
Allows transport layers outside Ruby TCP to be secured.
|
17
|
+
EOF
|
18
|
+
|
19
|
+
s.add_dependency 'ffi-compiler', '>= 1.0', '< 2.0'
|
20
|
+
s.add_dependency 'concurrent-ruby', '~> 1.0'
|
21
|
+
|
22
|
+
s.add_development_dependency 'rspec', '~> 3.5'
|
23
|
+
s.add_development_dependency 'yard', '~> 0.9'
|
24
|
+
|
25
|
+
|
26
|
+
s.files = Dir["{lib}/**/*"] + %w(mt-ruby-tls.gemspec README.md)
|
27
|
+
s.test_files = Dir["spec/**/*"]
|
28
|
+
s.extra_rdoc_files = ["README.md"]
|
29
|
+
|
30
|
+
s.require_paths = ["lib"]
|
31
|
+
end
|
data/spec/alpn_spec.rb
ADDED
@@ -0,0 +1,415 @@
|
|
1
|
+
require 'mt-ruby-tls'
|
2
|
+
|
3
|
+
if MTRubyTls::SSL::ALPN_SUPPORTED
|
4
|
+
|
5
|
+
describe MTRubyTls do
|
6
|
+
|
7
|
+
describe MTRubyTls::SSL::Box do
|
8
|
+
|
9
|
+
it "should be able to negotiate a protocol" do
|
10
|
+
@server_data = []
|
11
|
+
@client_data = []
|
12
|
+
@interleaved = []
|
13
|
+
|
14
|
+
|
15
|
+
class Client3
|
16
|
+
def initialize(client_data, interleaved)
|
17
|
+
@client_data = client_data
|
18
|
+
@interleaved = interleaved
|
19
|
+
@ssl = MTRubyTls::SSL::Box.new(false, self, {
|
20
|
+
protocols: ["http/1.1", :h2]
|
21
|
+
})
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :ssl
|
25
|
+
attr_accessor :stop
|
26
|
+
attr_accessor :server
|
27
|
+
|
28
|
+
def close_cb
|
29
|
+
@client_data << 'client stopped'
|
30
|
+
@interleaved << 'client stopped'
|
31
|
+
@stop = true
|
32
|
+
end
|
33
|
+
|
34
|
+
def dispatch_cb(data)
|
35
|
+
@client_data << data
|
36
|
+
@interleaved << data
|
37
|
+
end
|
38
|
+
|
39
|
+
def transmit_cb(data)
|
40
|
+
if not @server.started
|
41
|
+
@server.started = true
|
42
|
+
@server.ssl.start
|
43
|
+
end
|
44
|
+
@server.ssl.decrypt(data) unless @stop
|
45
|
+
end
|
46
|
+
|
47
|
+
def handshake_cb(protocol)
|
48
|
+
@client_data << protocol
|
49
|
+
@interleaved << 'client ready'
|
50
|
+
|
51
|
+
sending = 'client request'
|
52
|
+
@ssl.encrypt(sending) unless @stop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
class Server3
|
58
|
+
def initialize(client, server_data, interleaved)
|
59
|
+
@client = client
|
60
|
+
@server_data = server_data
|
61
|
+
@interleaved = interleaved
|
62
|
+
@ssl = MTRubyTls::SSL::Box.new(true, self, {
|
63
|
+
protocols: [:h2, "http/1.1"]
|
64
|
+
})
|
65
|
+
end
|
66
|
+
|
67
|
+
attr_reader :ssl
|
68
|
+
attr_accessor :started
|
69
|
+
attr_accessor :stop
|
70
|
+
|
71
|
+
def close_cb
|
72
|
+
@server_data << 'server stop'
|
73
|
+
@interleaved << 'server stop'
|
74
|
+
@stop = true
|
75
|
+
end
|
76
|
+
|
77
|
+
def dispatch_cb(data)
|
78
|
+
@server_data << data
|
79
|
+
@interleaved << data
|
80
|
+
|
81
|
+
sending = 'server response'
|
82
|
+
@ssl.encrypt(sending) unless @stop
|
83
|
+
end
|
84
|
+
|
85
|
+
def transmit_cb(data)
|
86
|
+
@client.ssl.decrypt(data) unless @stop
|
87
|
+
end
|
88
|
+
|
89
|
+
def handshake_cb(protocol)
|
90
|
+
@server_data << protocol
|
91
|
+
@interleaved << 'server ready'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
@client = Client3.new(@client_data, @interleaved)
|
97
|
+
@server = Server3.new(@client, @server_data, @interleaved)
|
98
|
+
@client.server = @server
|
99
|
+
|
100
|
+
|
101
|
+
@client.ssl.start
|
102
|
+
@client.ssl.cleanup
|
103
|
+
@server.ssl.cleanup
|
104
|
+
|
105
|
+
expect(@server_data).to eq([:h2, 'client request'])
|
106
|
+
expect(@client_data).to eq([:h2, 'server response'])
|
107
|
+
expect(@interleaved).to eq(['server ready', 'client ready', 'client request', 'server response'])
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
it "should stop the server when a protocol cannot be negotiated" do
|
112
|
+
@server_data = []
|
113
|
+
@client_data = []
|
114
|
+
@interleaved = []
|
115
|
+
|
116
|
+
|
117
|
+
class Client4
|
118
|
+
def initialize(client_data, interleaved)
|
119
|
+
@client_data = client_data
|
120
|
+
@interleaved = interleaved
|
121
|
+
@ssl = MTRubyTls::SSL::Box.new(false, self, {
|
122
|
+
protocols: ["h2c"]
|
123
|
+
})
|
124
|
+
end
|
125
|
+
|
126
|
+
attr_reader :ssl
|
127
|
+
attr_accessor :stop
|
128
|
+
attr_accessor :server
|
129
|
+
|
130
|
+
def close_cb
|
131
|
+
@client_data << 'client stopped'
|
132
|
+
@interleaved << 'client stopped'
|
133
|
+
@stop = true
|
134
|
+
end
|
135
|
+
|
136
|
+
def dispatch_cb(data)
|
137
|
+
@client_data << data
|
138
|
+
@interleaved << data
|
139
|
+
end
|
140
|
+
|
141
|
+
def transmit_cb(data)
|
142
|
+
if not @server.started
|
143
|
+
@server.started = true
|
144
|
+
@server.ssl.start
|
145
|
+
end
|
146
|
+
@server.ssl.decrypt(data) unless @stop
|
147
|
+
end
|
148
|
+
|
149
|
+
def handshake_cb(protocol)
|
150
|
+
@client_data << 'ready'
|
151
|
+
@interleaved << 'client ready'
|
152
|
+
|
153
|
+
sending = 'client request'
|
154
|
+
@ssl.encrypt(sending) unless @stop
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
class Server4
|
160
|
+
def initialize(client, server_data, interleaved)
|
161
|
+
@client = client
|
162
|
+
@server_data = server_data
|
163
|
+
@interleaved = interleaved
|
164
|
+
@ssl = MTRubyTls::SSL::Box.new(true, self, {
|
165
|
+
protocols: ["http/1.1", "h2"]
|
166
|
+
})
|
167
|
+
end
|
168
|
+
|
169
|
+
attr_reader :ssl
|
170
|
+
attr_accessor :started
|
171
|
+
attr_accessor :stop
|
172
|
+
|
173
|
+
def close_cb
|
174
|
+
@server_data << 'server stop'
|
175
|
+
@interleaved << 'server stop'
|
176
|
+
@stop = true
|
177
|
+
end
|
178
|
+
|
179
|
+
def dispatch_cb(data)
|
180
|
+
@server_data << data
|
181
|
+
@interleaved << data
|
182
|
+
|
183
|
+
sending = 'server response'
|
184
|
+
@ssl.encrypt(sending) unless @stop
|
185
|
+
end
|
186
|
+
|
187
|
+
def transmit_cb(data)
|
188
|
+
@client.ssl.decrypt(data) unless @stop
|
189
|
+
end
|
190
|
+
|
191
|
+
def handshake_cb(protocol)
|
192
|
+
@server_data << 'ready'
|
193
|
+
@interleaved << 'server ready'
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
@client = Client4.new(@client_data, @interleaved)
|
199
|
+
@server = Server4.new(@client, @server_data, @interleaved)
|
200
|
+
@client.server = @server
|
201
|
+
|
202
|
+
|
203
|
+
@client.ssl.start
|
204
|
+
@client.ssl.cleanup
|
205
|
+
@server.ssl.cleanup
|
206
|
+
|
207
|
+
expect(@server_data).to eq(['server stop'])
|
208
|
+
expect(@client_data).to eq([])
|
209
|
+
expect(@interleaved).to eq(['server stop'])
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
it "should not stop the client if the server doesn't support ALPN" do
|
214
|
+
@server_data = []
|
215
|
+
@client_data = []
|
216
|
+
@interleaved = []
|
217
|
+
|
218
|
+
|
219
|
+
class Client5
|
220
|
+
def initialize(client_data, interleaved)
|
221
|
+
@client_data = client_data
|
222
|
+
@interleaved = interleaved
|
223
|
+
@ssl = MTRubyTls::SSL::Box.new(false, self, {
|
224
|
+
protocols: ["h2c"]
|
225
|
+
})
|
226
|
+
end
|
227
|
+
|
228
|
+
attr_reader :ssl
|
229
|
+
attr_accessor :stop
|
230
|
+
attr_accessor :server
|
231
|
+
|
232
|
+
def close_cb
|
233
|
+
@client_data << 'client stopped'
|
234
|
+
@interleaved << 'client stopped'
|
235
|
+
@stop = true
|
236
|
+
end
|
237
|
+
|
238
|
+
def dispatch_cb(data)
|
239
|
+
@client_data << data
|
240
|
+
@interleaved << data
|
241
|
+
end
|
242
|
+
|
243
|
+
def transmit_cb(data)
|
244
|
+
if not @server.started
|
245
|
+
@server.started = true
|
246
|
+
@server.ssl.start
|
247
|
+
end
|
248
|
+
@server.ssl.decrypt(data) unless @stop
|
249
|
+
end
|
250
|
+
|
251
|
+
def handshake_cb(protocol)
|
252
|
+
@client_data << protocol
|
253
|
+
@interleaved << 'client ready'
|
254
|
+
|
255
|
+
sending = 'client request'
|
256
|
+
@ssl.encrypt(sending) unless @stop
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
|
261
|
+
class Server5
|
262
|
+
def initialize(client, server_data, interleaved)
|
263
|
+
@client = client
|
264
|
+
@server_data = server_data
|
265
|
+
@interleaved = interleaved
|
266
|
+
@ssl = MTRubyTls::SSL::Box.new(true, self)
|
267
|
+
end
|
268
|
+
|
269
|
+
attr_reader :ssl
|
270
|
+
attr_accessor :started
|
271
|
+
attr_accessor :stop
|
272
|
+
|
273
|
+
def close_cb
|
274
|
+
@server_data << 'server stop'
|
275
|
+
@interleaved << 'server stop'
|
276
|
+
@stop = true
|
277
|
+
end
|
278
|
+
|
279
|
+
def dispatch_cb(data)
|
280
|
+
@server_data << data
|
281
|
+
@interleaved << data
|
282
|
+
|
283
|
+
sending = 'server response'
|
284
|
+
@ssl.encrypt(sending) unless @stop
|
285
|
+
end
|
286
|
+
|
287
|
+
def transmit_cb(data)
|
288
|
+
@client.ssl.decrypt(data) unless @stop
|
289
|
+
end
|
290
|
+
|
291
|
+
def handshake_cb(protocol)
|
292
|
+
@server_data << protocol
|
293
|
+
@interleaved << 'server ready'
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
|
298
|
+
@client = Client5.new(@client_data, @interleaved)
|
299
|
+
@server = Server5.new(@client, @server_data, @interleaved)
|
300
|
+
@client.server = @server
|
301
|
+
|
302
|
+
|
303
|
+
@client.ssl.start
|
304
|
+
@client.ssl.cleanup
|
305
|
+
@server.ssl.cleanup
|
306
|
+
|
307
|
+
expect(@client_data).to eq([:failed, 'server response'])
|
308
|
+
expect(@server_data).to eq([nil, 'client request'])
|
309
|
+
expect(@interleaved).to eq(['server ready', 'client ready', 'client request', 'server response'])
|
310
|
+
end
|
311
|
+
|
312
|
+
|
313
|
+
it "should not stop the server if the client doesn't support ALPN" do
|
314
|
+
@server_data = []
|
315
|
+
@client_data = []
|
316
|
+
@interleaved = []
|
317
|
+
|
318
|
+
|
319
|
+
class Client6
|
320
|
+
def initialize(client_data, interleaved)
|
321
|
+
@client_data = client_data
|
322
|
+
@interleaved = interleaved
|
323
|
+
@ssl = MTRubyTls::SSL::Box.new(false, self)
|
324
|
+
end
|
325
|
+
|
326
|
+
attr_reader :ssl
|
327
|
+
attr_accessor :stop
|
328
|
+
attr_accessor :server
|
329
|
+
|
330
|
+
def close_cb
|
331
|
+
@client_data << 'client stopped'
|
332
|
+
@interleaved << 'client stopped'
|
333
|
+
@stop = true
|
334
|
+
end
|
335
|
+
|
336
|
+
def dispatch_cb(data)
|
337
|
+
@client_data << data
|
338
|
+
@interleaved << data
|
339
|
+
end
|
340
|
+
|
341
|
+
def transmit_cb(data)
|
342
|
+
if not @server.started
|
343
|
+
@server.started = true
|
344
|
+
@server.ssl.start
|
345
|
+
end
|
346
|
+
@server.ssl.decrypt(data) unless @stop
|
347
|
+
end
|
348
|
+
|
349
|
+
def handshake_cb(protocol)
|
350
|
+
@client_data << protocol
|
351
|
+
@interleaved << 'client ready'
|
352
|
+
|
353
|
+
sending = 'client request'
|
354
|
+
@ssl.encrypt(sending) unless @stop
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
|
359
|
+
class Server6
|
360
|
+
def initialize(client, server_data, interleaved)
|
361
|
+
@client = client
|
362
|
+
@server_data = server_data
|
363
|
+
@interleaved = interleaved
|
364
|
+
@ssl = MTRubyTls::SSL::Box.new(true, self, {
|
365
|
+
protocols: ["h2", "http/1.1"],
|
366
|
+
fallback: "http/1.1"
|
367
|
+
})
|
368
|
+
end
|
369
|
+
|
370
|
+
attr_reader :ssl
|
371
|
+
attr_accessor :started
|
372
|
+
attr_accessor :stop
|
373
|
+
|
374
|
+
def close_cb
|
375
|
+
@server_data << 'server stop'
|
376
|
+
@interleaved << 'server stop'
|
377
|
+
@stop = true
|
378
|
+
end
|
379
|
+
|
380
|
+
def dispatch_cb(data)
|
381
|
+
@server_data << data
|
382
|
+
@interleaved << data
|
383
|
+
|
384
|
+
sending = 'server response'
|
385
|
+
@ssl.encrypt(sending) unless @stop
|
386
|
+
end
|
387
|
+
|
388
|
+
def transmit_cb(data)
|
389
|
+
@client.ssl.decrypt(data) unless @stop
|
390
|
+
end
|
391
|
+
|
392
|
+
def handshake_cb(protocol)
|
393
|
+
@server_data << protocol
|
394
|
+
@interleaved << 'server ready'
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
|
399
|
+
@client = Client6.new(@client_data, @interleaved)
|
400
|
+
@server = Server6.new(@client, @server_data, @interleaved)
|
401
|
+
@client.server = @server
|
402
|
+
|
403
|
+
|
404
|
+
@client.ssl.start
|
405
|
+
@client.ssl.cleanup
|
406
|
+
@server.ssl.cleanup
|
407
|
+
|
408
|
+
|
409
|
+
expect(@server_data).to eq([:"http/1.1", 'client request'])
|
410
|
+
expect(@client_data).to eq([nil, 'server response'])
|
411
|
+
expect(@interleaved).to eq(['server ready', 'client ready', 'client request', 'server response'])
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
415
|
+
end
|
data/spec/client.crt
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIFRDCCAywCAQEwDQYJKoZIhvcNAQEFBQAwaDELMAkGA1UEBhMCRU0xFTATBgNV
|
3
|
+
BAgTDEV2ZW50TWFjaGluZTEVMBMGA1UEChMMRXZlbnRNYWNoaW5lMRQwEgYDVQQL
|
4
|
+
EwtEZXZlbG9wbWVudDEVMBMGA1UEAxMMRXZlbnRNYWNoaW5lMB4XDTA5MDMyOTAy
|
5
|
+
MzE0NloXDTEwMDMyOTAyMzE0NlowaDELMAkGA1UEBhMCRU0xFTATBgNVBAgTDEV2
|
6
|
+
ZW50TWFjaGluZTEVMBMGA1UEChMMRXZlbnRNYWNoaW5lMRQwEgYDVQQLEwtEZXZl
|
7
|
+
bG9wbWVudDEVMBMGA1UEAxMMRXZlbnRNYWNoaW5lMIICIjANBgkqhkiG9w0BAQEF
|
8
|
+
AAOCAg8AMIICCgKCAgEAv1FSOIX1z7CQtVBFlrB0A3/V29T+22STKKmiRWYkKL5b
|
9
|
+
+hkrp9IZ5J4phZHgUVM2VDPOO2Oc2PU6dlGGZISg+UPERunTogxQKezCV0vcE9cK
|
10
|
+
OwzxCFDRvv5rK8aKMscfBLbNKocAXywuRRQmdxPiVRzbyPrl+qCr/EDLXAX3D77l
|
11
|
+
S8n2AwDg19VyI+IgFUE+Dy5e1eLoY6nV+Mq+vNXdn3ttF3t+ngac5pj5Q9h+pD5p
|
12
|
+
67baDHSnf/7cy2fa/LKrLolVHQR9G2K6cEfeM99NtcsMbkoPs4iI3FA05OVTQHXg
|
13
|
+
C8C8cRxrb9APl95I/ep65OIaCJgcdYxJ3QD3qOtQo6/NQsGnjbyiUxaEpjfqyT1N
|
14
|
+
uzWD81Q8uXGNS8yD6dDynt/lseBjyp2nfC3uQ5fY18VdIcu0MJ9pezBUKrNuhlsy
|
15
|
+
XXEZ2DXj4sY8QOvIcBqSB/zmS1nGEK55xrtkaiaNrY8fe8wRVpcPLxy+P225NFw+
|
16
|
+
B69FJRA0Lj6Jt9BM4hV/3MSIEWwTVhuw4E02ywDYTzz1wq3ITf0tsbIPn0hXQMxD
|
17
|
+
ohhAoKioM6u+yHtqsxD0eYaAWmHTVn5oDvOSGpvCpBfWHyA7FP5UQak0fKABEAgK
|
18
|
+
iQYEnb294AXwXymJttfGTIV/Ne4tLN5dIpNma8UO8rlThlcr6xnTQDbR3gkTDRsC
|
19
|
+
AwEAATANBgkqhkiG9w0BAQUFAAOCAgEAj7J8fy1LUWoVWnrXDAC9jwJ1nI/YjoSU
|
20
|
+
6ywke3o04+nZC5S+dPnuVy+HAwsU940CoNvP6RStI/bH6JL+NIqEFmwM3M8xIEWV
|
21
|
+
MYVPkfvQUxxGvDnaY7vv93u+6Q77HV3qlhAQBHChyuXyO7TG3+WzsiT9AnBNtAP0
|
22
|
+
4jClt5kCAQXLO/p0SFEZQ8Ru9SM8d1i73Z0VDVzs8jYWlBhiherSgbw1xK4wBOpJ
|
23
|
+
43XmjZsBSrDpiAXd07Ak3UL2GjfT7eStgebL3UIe39ThE/s/+l43bh0M6WbOBvyQ
|
24
|
+
i/rZ50kd1GvN0xnZhtv07hIJWO85FGWi7Oet8AzdUZJ17v1Md/f2vdhPVTFN9q+w
|
25
|
+
mQ6LxjackqCvaJaQfBEbqsn2Tklxk4tZuDioiQbOElT2e6vljQVJWIfNx38Ny2LM
|
26
|
+
aiXQPQu+4CI7meAh5gXM5nyJGbZvRPsxj89CqYzyHCYs5HBP3AsviBvn26ziOF+c
|
27
|
+
544VmHd9HkIv8UTC29hh+R64RlgMQQQdaXFaUrFPTs/do0k8n/c2bPc0iTdfi5Q2
|
28
|
+
gq6Vi8q6Ay5wGgTtRRbn/mWKuCFjEh94z6pF9Xr06NX0PuEOdf+Ls9vI5vz6G0w6
|
29
|
+
0Li7devEN7EKBY+7Mcjg918yq9i5tEiMkUgT68788t3fTC+4iUQ5fDtdrHsaOlIR
|
30
|
+
8bs/XQVNE/s=
|
31
|
+
-----END CERTIFICATE-----
|
data/spec/client.key
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
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
|
51
|
+
-----END RSA PRIVATE KEY-----
|
data/spec/comms_spec.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'mt-ruby-tls'
|
2
|
+
|
3
|
+
describe MTRubyTls do
|
4
|
+
|
5
|
+
describe MTRubyTls::SSL::Box do
|
6
|
+
|
7
|
+
it "fails when passed an unsupported TLS version" do
|
8
|
+
expect {
|
9
|
+
MTRubyTls::SSL::Box.new(false, nil, version: :TLS1_4)
|
10
|
+
}.to raise_error(/is unsupported/)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "succeeds when passed a supported TLS version" do
|
14
|
+
MTRubyTls::SSL::Box.new(false, nil, version: :TLS1_2) if MTRubyTls::SSL::VERSION_SUPPORTED
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be able to send and receive encrypted comms" do
|
18
|
+
@server_data = []
|
19
|
+
@client_data = []
|
20
|
+
@interleaved = []
|
21
|
+
|
22
|
+
|
23
|
+
class Client1
|
24
|
+
def initialize(client_data, interleaved)
|
25
|
+
@client_data = client_data
|
26
|
+
@interleaved = interleaved
|
27
|
+
@ssl = MTRubyTls::SSL::Box.new(false, self)
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :ssl
|
31
|
+
attr_accessor :stop
|
32
|
+
attr_accessor :server
|
33
|
+
|
34
|
+
def close_cb
|
35
|
+
@client_data << 'client stopped'
|
36
|
+
@interleaved << 'client stopped'
|
37
|
+
@stop = true
|
38
|
+
end
|
39
|
+
|
40
|
+
def dispatch_cb(data)
|
41
|
+
@client_data << data
|
42
|
+
@interleaved << data
|
43
|
+
end
|
44
|
+
|
45
|
+
def transmit_cb(data)
|
46
|
+
if not @server.started
|
47
|
+
@server.started = true
|
48
|
+
@server.ssl.start
|
49
|
+
end
|
50
|
+
@server.ssl.decrypt(data) unless @stop
|
51
|
+
end
|
52
|
+
|
53
|
+
def handshake_cb(protocol)
|
54
|
+
@client_data << 'ready'
|
55
|
+
@interleaved << 'client ready'
|
56
|
+
|
57
|
+
sending = 'client request'
|
58
|
+
@ssl.encrypt(sending) unless @stop
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
class Server1
|
64
|
+
def initialize(client, server_data, interleaved)
|
65
|
+
@client = client
|
66
|
+
@server_data = server_data
|
67
|
+
@interleaved = interleaved
|
68
|
+
@ssl = MTRubyTls::SSL::Box.new(true, self)
|
69
|
+
end
|
70
|
+
|
71
|
+
attr_reader :ssl
|
72
|
+
attr_accessor :started
|
73
|
+
attr_accessor :stop
|
74
|
+
|
75
|
+
def close_cb
|
76
|
+
@server_data << 'server stop'
|
77
|
+
@interleaved << 'server stop'
|
78
|
+
@stop = true
|
79
|
+
end
|
80
|
+
|
81
|
+
def dispatch_cb(data)
|
82
|
+
@server_data << data
|
83
|
+
@interleaved << data
|
84
|
+
|
85
|
+
sending = 'server response'
|
86
|
+
@ssl.encrypt(sending) unless @stop
|
87
|
+
end
|
88
|
+
|
89
|
+
def transmit_cb(data)
|
90
|
+
@client.ssl.decrypt(data) unless @stop
|
91
|
+
end
|
92
|
+
|
93
|
+
def handshake_cb(protocol)
|
94
|
+
@server_data << 'ready'
|
95
|
+
@interleaved << 'server ready'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
@client = Client1.new(@client_data, @interleaved)
|
101
|
+
@server = Server1.new(@client, @server_data, @interleaved)
|
102
|
+
@client.server = @server
|
103
|
+
|
104
|
+
|
105
|
+
@client.ssl.start
|
106
|
+
@client.ssl.cleanup
|
107
|
+
@server.ssl.cleanup
|
108
|
+
|
109
|
+
|
110
|
+
# Calls to encrypt should not cause crashes after cleanup
|
111
|
+
@server.ssl.encrypt('server response')
|
112
|
+
@client.ssl.encrypt('client request')
|
113
|
+
|
114
|
+
expect(@server_data).to eq(['ready', 'client request'])
|
115
|
+
expect(@client_data).to eq(['ready', 'server response'])
|
116
|
+
expect(@interleaved).to eq(['server ready', 'client ready', 'client request', 'server response'])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|