mt-ruby-tls 2.4.0

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