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.
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTRubyTls
4
+ VERSION = '2.4.0'
5
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mt-ruby-tls/ssl' # Loads OpenSSL using FFI
4
+
5
+ module MTRubyTls
6
+ end
@@ -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-----
@@ -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
+