ruby-tls 2.0.1 → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f7767f8988f4ed0509937bd7a62a58797c0517a8
4
- data.tar.gz: f121662222885ede7f33dee6716358960936975b
3
+ metadata.gz: acce3678093f001d9085b46b4c163c4036a6dee0
4
+ data.tar.gz: 1f7ab340aa973063db130f597334ccf7505d45a8
5
5
  SHA512:
6
- metadata.gz: d497a9ec2805b26b7620b1347ccb6912e553e68f740b51db63d97dbe9033e7cc717e70440677de920046ac2cb5c14a3cb75ec4155f39ca19507b747a0b66b007
7
- data.tar.gz: 6a4ca688ff5609abde4f43f84befbd7f9e5c2fcf4329ff34e59a937a91b8b3d91e4a834f7ae4c71524d44072438c44cc4ec60274c0befef69b2343627edf2750
6
+ metadata.gz: edbee0e101783904e9fdadf6fdc1fccfc7785b3b69a798223ba36656ed71af5e475407a04a72a1c195688b3f6a6909a3e1ef20fd931db46309a4622e77fc56cb
7
+ data.tar.gz: 43dd6bb0b6a323bb282cdbdef4a2b81623cf01dfdc88ea28cb2df1cb66fc27d3caf8b8cf8c4659f51e8b574f60968b2a27fd03cd672472df853817864b94f33e
data/README.md CHANGED
@@ -34,6 +34,8 @@ class transport
34
34
  private_key: '/file/path.pem',
35
35
  cert_chain: '/file/path.crt',
36
36
  ciphers: 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!CAMELLIA:@STRENGTH' # (default)
37
+ # protocols: ["h2", "http/1.1"], # Can be used where OpenSSL >= 1.0.2 (Application Level Protocol negotiation)
38
+ # fallback: "http/1.1" # Optional fallback to a default protocol when either client or server doesn't support ALPN
37
39
  }
38
40
  @ssl_layer = RubyTls::SSL::Box.new(is_server, callback_obj, options)
39
41
  end
@@ -51,7 +53,7 @@ class transport
51
53
  # @tcp.send data
52
54
  end
53
55
 
54
- def handshake_cb
56
+ def handshake_cb(protocol)
55
57
  puts "initial handshake has completed"
56
58
  end
57
59
 
data/lib/ruby-tls/ssl.rb CHANGED
@@ -147,7 +147,30 @@ module RubyTls
147
147
  attach_function :SSL_CTX_set_cipher_list, [:ssl_ctx, :string], :int
148
148
  attach_function :SSL_CTX_set_session_id_context, [:ssl_ctx, :string, :buffer_length], :int
149
149
 
150
- # TODO:: SSL_CTX_set_alpn_protos
150
+ # OpenSSL before 1.0.2 do not have these methods
151
+ begin
152
+ attach_function :SSL_CTX_set_alpn_protos, [:ssl_ctx, :string, :uint], :int
153
+
154
+ SSL_TLSEXT_ERR_OK = 0
155
+ SSL_TLSEXT_ERR_ALERT_WARNING = 1
156
+ SSL_TLSEXT_ERR_ALERT_FATAL = 2
157
+ SSL_TLSEXT_ERR_NOACK = 3
158
+
159
+ OPENSSL_NPN_UNSUPPORTED = 0
160
+ OPENSSL_NPN_NEGOTIATED = 1
161
+ OPENSSL_NPN_NO_OVERLAP = 2
162
+
163
+ attach_function :SSL_select_next_proto, [:pointer, :pointer, :string, :uint, :string, :uint], :int
164
+
165
+ # array of str, unit8 out,uint8 in, *arg
166
+ callback :alpn_select_cb, [:ssl, :pointer, :pointer, :string, :uint, :pointer], :int
167
+ attach_function :SSL_CTX_set_alpn_select_cb, [:ssl_ctx, :alpn_select_cb, :pointer], :void
168
+
169
+ attach_function :SSL_get0_alpn_selected, [:ssl, :pointer, :pointer], :void
170
+ ALPN_SUPPORTED = true
171
+ rescue FFI::NotFoundError
172
+ ALPN_SUPPORTED = false
173
+ end
151
174
 
152
175
 
153
176
  # Deconstructor
@@ -201,19 +224,23 @@ keystr
201
224
  8
202
225
  end
203
226
 
204
- CRYPTO_LOCK = 0x1
205
- LockingCB = FFI::Function.new(:void, [:int, :int, :string, :int]) do |mode, type, file, line|
206
- if (mode & CRYPTO_LOCK) != 0
207
- SSL_LOCKS[type].lock
208
- else
209
- # Unlock a lock
210
- SSL_LOCKS[type].unlock
211
- end
212
- end
227
+ # Locking isn't provided as long as all writes are done on the same thread.
228
+ # This is my main use case. Happy to enable it if someone requires it and can
229
+ # get it to work on MRI Ruby (Currently only works on JRuby and Rubinius)
230
+ # as MRI callbacks occur on a thread pool?
213
231
 
214
- ThreadIdCB = FFI::Function.new(:ulong, []) do
215
- Thread.current.object_id
216
- end
232
+ #CRYPTO_LOCK = 0x1
233
+ #LockingCB = FFI::Function.new(:void, [:int, :int, :string, :int]) do |mode, type, file, line|
234
+ # if (mode & CRYPTO_LOCK) != 0
235
+ # SSL_LOCKS[type].lock
236
+ # else
237
+ # Unlock a lock
238
+ # SSL_LOCKS[type].unlock
239
+ # end
240
+ #end
241
+ #ThreadIdCB = FFI::Function.new(:ulong, []) do
242
+ # Thread.current.object_id
243
+ #end
217
244
 
218
245
 
219
246
  # INIT CODE
@@ -262,6 +289,29 @@ keystr
262
289
  CIPHERS = 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!CAMELLIA:@STRENGTH'.freeze
263
290
  SESSION = 'ruby-tls'.freeze
264
291
 
292
+
293
+ ALPN_LOOKUP = ThreadSafe::Cache.new
294
+ ALPN_Select_CB = FFI::Function.new(:int, [
295
+ # array of str, unit8 out,uint8 in, *arg
296
+ :pointer, :pointer, :pointer, :string, :uint, :pointer
297
+ ]) do |ssl_p, out, outlen, inp, inlen, arg|
298
+ ssl = Box::InstanceLookup[ssl_p.address]
299
+ return SSL::SSL_TLSEXT_ERR_ALERT_FATAL unless ssl
300
+
301
+ protos = ssl.context.alpn_str
302
+ status = SSL.SSL_select_next_proto(out, outlen, protos, protos.length, inp, inlen)
303
+ ssl.negotiated
304
+
305
+ case status
306
+ when SSL::OPENSSL_NPN_UNSUPPORTED
307
+ SSL::SSL_TLSEXT_ERR_ALERT_FATAL
308
+ when SSL::OPENSSL_NPN_NEGOTIATED
309
+ SSL::SSL_TLSEXT_ERR_OK
310
+ when SSL::OPENSSL_NPN_NO_OVERLAP
311
+ SSL::SSL_TLSEXT_ERR_ALERT_WARNING
312
+ end
313
+ end
314
+
265
315
  def initialize(server, options = {})
266
316
  @is_server = server
267
317
  @ssl_ctx = SSL.SSL_CTX_new(server ? SSL.SSLv23_server_method : SSL.SSLv23_client_method)
@@ -274,16 +324,27 @@ keystr
274
324
  end
275
325
 
276
326
  SSL.SSL_CTX_set_cipher_list(@ssl_ctx, options[:ciphers] || CIPHERS)
327
+ @alpn_set = false
277
328
 
278
329
  if @is_server
279
330
  SSL.SSL_CTX_sess_set_cache_size(@ssl_ctx, 128)
280
331
  SSL.SSL_CTX_set_session_id_context(@ssl_ctx, SESSION, 8)
332
+
333
+ if SSL::ALPN_SUPPORTED && options[:protocols]
334
+ @alpn_str = Context.build_alpn_string(options[:protocols])
335
+ SSL.SSL_CTX_set_alpn_select_cb(@ssl_ctx, ALPN_Select_CB, nil)
336
+ @alpn_set = true
337
+ end
281
338
  else
282
339
  set_private_key(options[:private_key])
283
340
  set_certificate(options[:cert_chain])
284
- end
285
341
 
286
- # TODO:: Check for ALPN support
342
+ # Check for ALPN support
343
+ if SSL::ALPN_SUPPORTED && options[:protocols]
344
+ protocols = Context.build_alpn_string(options[:protocols])
345
+ @alpn_set = SSL.SSL_CTX_set_alpn_protos(@ssl_ctx, protocols, protocols.length) == 0
346
+ end
347
+ end
287
348
  end
288
349
 
289
350
  def cleanup
@@ -295,11 +356,23 @@ keystr
295
356
 
296
357
  attr_reader :is_server
297
358
  attr_reader :ssl_ctx
359
+ attr_reader :alpn_set
360
+ attr_reader :alpn_str
298
361
 
299
362
 
300
363
  private
301
364
 
302
365
 
366
+ def self.build_alpn_string(protos)
367
+ protocols = ''.force_encoding('ASCII-8BIT')
368
+ protos.each do |prot|
369
+ protocol = prot.to_s
370
+ protocols << protocol.length
371
+ protocols << protocol
372
+ end
373
+ protocols
374
+ end
375
+
303
376
  def set_private_key(key)
304
377
  err = if key.is_a? FFI::Pointer
305
378
  SSL.SSL_CTX_use_PrivateKey(@ssl_ctx, key)
@@ -338,6 +411,8 @@ keystr
338
411
 
339
412
 
340
413
  class Box
414
+ InstanceLookup = ThreadSafe::Cache.new
415
+
341
416
  READ_BUFFER = 2048
342
417
 
343
418
  SSL_VERIFY_PEER = 0x01
@@ -347,6 +422,7 @@ keystr
347
422
 
348
423
  @handshake_completed = false
349
424
  @handshake_signaled = false
425
+ @negotiated = false
350
426
  @transport = transport
351
427
 
352
428
  @read_buffer = FFI::MemoryPointer.new(:char, READ_BUFFER, false)
@@ -360,11 +436,9 @@ keystr
360
436
 
361
437
  @write_queue = []
362
438
 
363
- # TODO:: if server && options[:alpn_string]
364
- # SSL_CTX_set_alpn_select_cb
365
-
366
439
  InstanceLookup[@ssl.address] = self
367
440
 
441
+ @alpn_fallback = options[:fallback]
368
442
  if options[:verify_peer]
369
443
  SSL.SSL_set_verify(@ssl, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, VerifyCB)
370
444
  end
@@ -374,6 +448,7 @@ keystr
374
448
 
375
449
 
376
450
  attr_reader :is_server
451
+ attr_reader :context
377
452
  attr_reader :handshake_completed
378
453
 
379
454
 
@@ -382,6 +457,22 @@ keystr
382
457
  SSL.SSL_get_peer_certificate(@ssl)
383
458
  end
384
459
 
460
+ def negotiated_protocol
461
+ return nil unless @context.alpn_set
462
+
463
+ proto = FFI::MemoryPointer.new(:pointer, 1, true)
464
+ len = FFI::MemoryPointer.new(:uint, 1, true)
465
+ SSL.SSL_get0_alpn_selected(@ssl, proto, len)
466
+
467
+ resp = proto.get_pointer(0)
468
+ if resp.address == 0
469
+ :failed
470
+ else
471
+ length = len.get_uint(0)
472
+ resp.read_string(length).to_sym
473
+ end
474
+ end
475
+
385
476
  def start
386
477
  return unless @ready
387
478
 
@@ -435,7 +526,30 @@ keystr
435
526
 
436
527
  def signal_handshake
437
528
  @handshake_signaled = true
438
- @transport.handshake_cb
529
+
530
+ # Check protocol support here
531
+ if @context.alpn_set
532
+ proto = negotiated_protocol
533
+
534
+ if proto == :failed
535
+ if @negotiated
536
+ # We should shutdown if this is the case
537
+ @transport.close_cb
538
+ return
539
+ elsif @alpn_fallback
540
+ # Client or Server with a client that doesn't support ALPN
541
+ proto = @alpn_fallback.to_sym
542
+ end
543
+ end
544
+ else
545
+ proto = nil
546
+ end
547
+
548
+ @transport.handshake_cb(proto)
549
+ end
550
+
551
+ def negotiated
552
+ @negotiated = true
439
553
  end
440
554
 
441
555
  SSL_RECEIVED_SHUTDOWN = 2
@@ -474,8 +588,6 @@ keystr
474
588
  end
475
589
  end
476
590
 
477
-
478
- InstanceLookup = ThreadSafe::Cache.new
479
591
  VerifyCB = FFI::Function.new(:int, [:int, :pointer]) do |preverify_ok, x509_store|
480
592
  x509 = SSL.X509_STORE_CTX_get_current_cert(x509_store)
481
593
  ssl = SSL.X509_STORE_CTX_get_ex_data(x509_store, SSL.SSL_get_ex_data_X509_STORE_CTX_idx)
@@ -1,3 +1,3 @@
1
1
  module RubyTls
2
- VERSION = "2.0.1"
2
+ VERSION = "2.1.0"
3
3
  end
data/spec/alpn_spec.rb ADDED
@@ -0,0 +1,415 @@
1
+ require 'ruby-tls'
2
+
3
+ if RubyTls::SSL::ALPN_SUPPORTED
4
+
5
+ describe RubyTls do
6
+
7
+ describe RubyTls::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 = RubyTls::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 = RubyTls::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 = RubyTls::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 = RubyTls::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 = RubyTls::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 = RubyTls::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 = RubyTls::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 = RubyTls::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/comms_spec.rb CHANGED
@@ -40,7 +40,7 @@ describe RubyTls do
40
40
  @server.ssl.decrypt(data) unless @stop
41
41
  end
42
42
 
43
- def handshake_cb
43
+ def handshake_cb(protocol)
44
44
  @client_data << 'ready'
45
45
  @interleaved << 'client ready'
46
46
 
@@ -80,7 +80,7 @@ describe RubyTls do
80
80
  @client.ssl.decrypt(data) unless @stop
81
81
  end
82
82
 
83
- def handshake_cb
83
+ def handshake_cb(protocol)
84
84
  @server_data << 'ready'
85
85
  @interleaved << 'server ready'
86
86
  end
data/spec/verify_spec.rb CHANGED
@@ -30,7 +30,7 @@ describe RubyTls do
30
30
  @server.ssl.decrypt(data) unless @stop
31
31
  end
32
32
 
33
- def handshake_cb
33
+ def handshake_cb(protocol)
34
34
  @client_data << 'ready'
35
35
  end
36
36
  end
@@ -71,7 +71,7 @@ describe RubyTls do
71
71
  @client.ssl.decrypt(data) unless @stop
72
72
  end
73
73
 
74
- def handshake_cb
74
+ def handshake_cb(protocol)
75
75
  @server_data << 'ready'
76
76
  end
77
77
 
@@ -126,7 +126,7 @@ describe RubyTls do
126
126
  @client.ssl.decrypt(data) unless @stop
127
127
  end
128
128
 
129
- def handshake_cb
129
+ def handshake_cb(protocol)
130
130
  @server_data << 'ready'
131
131
  end
132
132
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-tls
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen von Takach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-07 00:00:00.000000000 Z
11
+ date: 2015-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi-compiler
@@ -80,6 +80,7 @@ files:
80
80
  - lib/ruby-tls/ssl.rb
81
81
  - lib/ruby-tls/version.rb
82
82
  - ruby-tls.gemspec
83
+ - spec/alpn_spec.rb
83
84
  - spec/client.crt
84
85
  - spec/client.key
85
86
  - spec/comms_spec.rb
@@ -109,6 +110,7 @@ signing_key:
109
110
  specification_version: 4
110
111
  summary: Abstract TLS for Ruby
111
112
  test_files:
113
+ - spec/alpn_spec.rb
112
114
  - spec/client.crt
113
115
  - spec/client.key
114
116
  - spec/comms_spec.rb