tttls1.3 0.2.9 → 0.2.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +32 -0
  3. data/.rubocop.yml +9 -2
  4. data/Gemfile +1 -1
  5. data/README.md +5 -1
  6. data/Rakefile +66 -7
  7. data/example/helper.rb +6 -8
  8. data/example/https_client.rb +1 -1
  9. data/example/https_client_using_0rtt.rb +3 -3
  10. data/example/https_client_using_hrr.rb +1 -1
  11. data/example/https_client_using_hrr_and_ticket.rb +2 -2
  12. data/example/https_client_using_status_request.rb +31 -0
  13. data/example/https_client_using_ticket.rb +2 -2
  14. data/example/https_server.rb +6 -5
  15. data/interop/client_spec.rb +8 -8
  16. data/interop/helper.rb +10 -2
  17. data/interop/server_spec.rb +14 -10
  18. data/lib/tttls1.3.rb +1 -0
  19. data/lib/tttls1.3/client.rb +97 -12
  20. data/lib/tttls1.3/connection.rb +45 -12
  21. data/lib/tttls1.3/cryptograph.rb +1 -1
  22. data/lib/tttls1.3/cryptograph/aead.rb +20 -7
  23. data/lib/tttls1.3/message.rb +1 -1
  24. data/lib/tttls1.3/message/alert.rb +2 -2
  25. data/lib/tttls1.3/message/extension/status_request.rb +73 -17
  26. data/lib/tttls1.3/message/extensions.rb +35 -12
  27. data/lib/tttls1.3/server.rb +40 -13
  28. data/lib/tttls1.3/utils.rb +15 -0
  29. data/lib/tttls1.3/version.rb +1 -1
  30. data/spec/extensions_spec.rb +16 -0
  31. data/spec/fixtures/rsa_rsa.crt +15 -15
  32. data/spec/fixtures/rsa_rsa.key +25 -25
  33. data/spec/fixtures/rsa_rsa_ocsp.crt +18 -0
  34. data/spec/fixtures/rsa_rsa_ocsp.key +27 -0
  35. data/spec/server_hello_spec.rb +1 -1
  36. data/spec/spec_helper.rb +35 -1
  37. data/spec/status_request_spec.rb +77 -10
  38. data/tttls1.3.gemspec +1 -1
  39. metadata +14 -10
  40. data/.travis.yml +0 -18
  41. data/interop/Dockerfile +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89ddf39b7273edf08fbe46e3b043e3407e6858448643558c79e2d745956bb73a
4
- data.tar.gz: d3c67e1558ecf55ea64c6e1b7cf2ae8f76c52e25b02efd23161149532a0b35a9
3
+ metadata.gz: 3861f9a9864268fda75836b387c4a1f83e4edea0e885595155f2a352f69695ea
4
+ data.tar.gz: 617f9b12aa8ac8e39367b1b5f9fcba57d1bd3dc669fe645c7c6888a7140795bd
5
5
  SHA512:
6
- metadata.gz: 859ba8321cda498360389cc0fdb0cba509cec245f9b822855341e5a50bfcfd9ac38d69b976a55923aaa7026a0973b0d3349d5a1d25826ad70d73074904af0bf0
7
- data.tar.gz: 03a828102121e5bc70bdfc39e27e382355f0bc4d8ac9f3f925940d496dc845ec03c2e4c23d097de2a82f1edc3e3110ea4852d098f80239d9c0fa3e94b67fe63d
6
+ metadata.gz: 1f97901b82520b9c0a1fbc864e7e101749d9dacba3554e721eaf223fb1d4026384bf0756c8e9ac4578bcab37eb9c7b8e9c50b0387f3dfd7e8cf2d8456e709b14
7
+ data.tar.gz: a0d104b2e5dba0e7e7f8297a51b858f0912007f59350e1842e026639c1cc27d107c2737292f01cc2bf1fbc6c3374cb3426696f00ee2462c72d014c841ea3ce7d
@@ -0,0 +1,32 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ branches:
9
+ - '*'
10
+
11
+ jobs:
12
+ ci:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ ruby-version: ['2.6.x', '2.7.x']
17
+ steps:
18
+ - uses: docker://thekuwayama/openssl:latest
19
+ - name: Set up Ruby
20
+ uses: actions/setup-ruby@v1
21
+ - uses: actions/checkout@v1
22
+ - name: Install dependencies
23
+ run: |
24
+ gem --version
25
+ gem install bundler
26
+ bundle --version
27
+ bundle install
28
+ - name: Run test
29
+ run: |
30
+ bundle exec rake
31
+ bundle exec rake interop:client
32
+ bundle exec rake interop:server
@@ -1,19 +1,22 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 2.6
3
3
 
4
- Style/NumericLiterals:
4
+ Style/ConditionalAssignment:
5
5
  Enabled: false
6
6
 
7
7
  Style/Documentation:
8
8
  Enabled: false
9
9
 
10
+ Style/NumericLiterals:
11
+ Enabled: false
12
+
10
13
  Metrics/AbcSize:
11
14
  Max: 30
12
15
 
13
16
  Metrics/MethodLength:
14
17
  Max: 30
15
18
 
16
- Naming/UncommunicativeMethodParamName:
19
+ Naming/MethodParameterName:
17
20
  MinNameLength: 1
18
21
 
19
22
  Metrics/BlockLength:
@@ -21,3 +24,7 @@ Metrics/BlockLength:
21
24
  - 'Rakefile'
22
25
  - 'spec/*.rb'
23
26
  - 'interop/*.rb'
27
+
28
+ Layout/LineLength:
29
+ Exclude:
30
+ - 'tttls1.3.gemspec'
data/Gemfile CHANGED
@@ -10,7 +10,7 @@ group :test do
10
10
  gem 'pry'
11
11
  gem 'pry-byebug'
12
12
  gem 'rspec', '3.8.0'
13
- gem 'rubocop', '0.67.2'
13
+ gem 'rubocop', '0.78.0'
14
14
  end
15
15
 
16
16
  gemspec
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # tttls1.3
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/tttls1.3.svg)](https://badge.fury.io/rb/tttls1.3)
4
- [![Build Status](https://travis-ci.org/thekuwayama/tttls1.3.svg?branch=master)](https://travis-ci.org/thekuwayama/tttls1.3)
4
+ [![Actions Status](https://github.com/thekuwayama/tttls1.3/workflows/CI/badge.svg)](https://github.com/thekuwayama/tttls1.3/actions?workflow=CI)
5
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/47f3c267d9cfd2c8e388/maintainability)](https://codeclimate.com/github/thekuwayama/tttls1.3/maintainability)
6
6
 
7
7
  tttls1.3 is Ruby implementation of [TLS 1.3](https://tools.ietf.org/html/rfc8446) protocol.
@@ -100,6 +100,8 @@ tttls1.3 client is configurable using keyword arguments.
100
100
  | `:ticket_age_add` | String | nil | The ticket\_age\_add for PSK. |
101
101
  | `:ticket_timestamp` | Integer | nil | The ticket\_timestamp for PSK. |
102
102
  | `:record_size_limit` | Integer | nil | The record\_size\_limit offerd in ClientHello extensions. If not needed to be present, set nil. |
103
+ | `:check_certificate_status` | Boolean | false | If needed to check certificate status, set true. |
104
+ | `:process_certificate_status` | Proc | `TTTLS13::Client.method(:softfail_check_certificate_status)` | Proc(or Method) that checks received OCSPResponse. Its 3 arguments are OpenSSL::OCSP::Response, end-entity certificate(OpenSSL::X509::Certificate) and certificates chain(Array of Certificate) used for verification and it returns Boolean. |
103
105
  | `:compatibility_mode` | Boolean | true | If needed to send ChangeCipherSpec, set true. |
104
106
  | `:loglevel` | Logger constant | Logger::WARN | If needed to print verbose, set Logger::DEBUG. |
105
107
 
@@ -111,11 +113,13 @@ tttls1.3 server is configurable using keyword arguments.
111
113
  | key | type | default value | description |
112
114
  |-----|------|---------------|-------------|
113
115
  | `:crt_file` | String | nil | Path to the certificate file. This is a required setting. |
116
+ | `:chain_files` | Array of String | nil | Paths to the itermediate certificate files. |
114
117
  | `:key_file` | String | nil | Path to the private key file. This is a required setting. |
115
118
  | `:cipher_suites` | Array of TTTLS13::CipherSuite constant | `TLS_AES_256_GCM_SHA384`, `TLS_CHACHA20_POLY1305_SHA256`, `TLS_AES_128_GCM_SHA256` | List of supported cipher suites. |
116
119
  | `:signature_algorithms` | Array of TTTLS13::SignatureScheme constant | `ECDSA_SECP256R1_SHA256`, `ECDSA_SECP384R1_SHA384`, `ECDSA_SECP521R1_SHA512`, `RSA_PSS_RSAE_SHA256`, `RSA_PSS_RSAE_SHA384`, `RSA_PSS_RSAE_SHA512`, `RSA_PKCS1_SHA256`, `RSA_PKCS1_SHA384`, `RSA_PKCS1_SHA512` | List of supported signature algorithms. |
117
120
  | `:supported_groups` | Array of TTTLS13::NamedGroup constant | `SECP256R1`, `SECP384R1`, `SECP521R1` | List of supported named groups. |
118
121
  | `:alpn` | Array of String | nil | List of supported application protocols. If not needed to check this extension, set nil. |
122
+ | `:process_ocsp_response` | Proc | nil | Proc that gets OpenSSL::OCSP::Response. If not needed to staple OCSP::Response, set nil. |
119
123
  | `:compatibility_mode` | Boolean | true | If needed to send ChangeCipherSpec, set true. |
120
124
  | `:loglevel` | Logger constant | Logger::WARN | If needed to print verbose, set Logger::DEBUG. |
121
125
 
data/Rakefile CHANGED
@@ -9,9 +9,11 @@ require 'fileutils'
9
9
  TMP_DIR = __dir__ + '/tmp'
10
10
  CA_KEY = TMP_DIR + '/ca.key'
11
11
  CA_CRT = TMP_DIR + '/ca.crt'
12
+ INTER_KEY = TMP_DIR + '/intermediate.key'
13
+ INTER_CRT = TMP_DIR + '/intermediate.crt'
12
14
  SERVER_KEY = TMP_DIR + '/server.key'
13
15
  SERVER_CRT = TMP_DIR + '/server.crt'
14
- certs = [CA_KEY, CA_CRT, SERVER_KEY, SERVER_CRT]
16
+ certs = [CA_KEY, CA_CRT, INTER_KEY, INTER_CRT, SERVER_KEY, SERVER_CRT]
15
17
 
16
18
  directory TMP_DIR
17
19
 
@@ -64,15 +66,66 @@ file CA_CRT => [TMP_DIR, CA_KEY] do
64
66
  File.write(CA_CRT, ca_crt.to_pem)
65
67
  end
66
68
 
69
+ file INTER_KEY => TMP_DIR do
70
+ puts "generate #{INTER_KEY}..."
71
+ inter_key = OpenSSL::PKey::RSA.generate(2048)
72
+ File.write(INTER_KEY, inter_key.to_pem)
73
+ end
74
+
75
+ file INTER_CRT => [TMP_DIR, INTER_KEY] do
76
+ ca_key = OpenSSL::PKey::RSA.new(File.read(CA_KEY))
77
+ ca_crt = OpenSSL::X509::Certificate.new(File.read(CA_CRT))
78
+ inter_key = OpenSSL::PKey::RSA.new(File.read(INTER_KEY))
79
+
80
+ puts "generate #{INTER_CRT}..."
81
+ sub = OpenSSL::X509::Name.new
82
+ sub.add_entry('CN', 'test-intermediate')
83
+
84
+ inter_crt = OpenSSL::X509::Certificate.new
85
+ inter_crt.not_before = Time.now
86
+ inter_crt.not_after = Time.now + (60 * 60 * 24 * 365 * 10)
87
+ inter_crt.public_key = inter_key.public_key
88
+ inter_crt.serial = OpenSSL::BN.rand(64)
89
+ inter_crt.version = 2
90
+ inter_crt.issuer = ca_crt.subject
91
+ inter_crt.subject = sub
92
+
93
+ factory = OpenSSL::X509::ExtensionFactory.new
94
+ factory.subject_certificate = inter_crt
95
+ factory.issuer_certificate = ca_crt
96
+ inter_crt.add_extension(
97
+ factory.create_extension(
98
+ 'keyUsage',
99
+ 'critical, cRLSign, keyCertSign'
100
+ )
101
+ )
102
+ inter_crt.add_extension(
103
+ factory.create_extension(
104
+ 'basicConstraints',
105
+ 'critical, CA:true'
106
+ )
107
+ )
108
+ inter_crt.add_extension(
109
+ factory.create_extension(
110
+ 'subjectKeyIdentifier',
111
+ 'hash'
112
+ )
113
+ )
114
+
115
+ digest = OpenSSL::Digest::SHA256.new
116
+ inter_crt.sign(ca_key, digest)
117
+ File.write(INTER_CRT, inter_crt.to_pem)
118
+ end
119
+
67
120
  file SERVER_KEY => TMP_DIR do
68
121
  puts "generate #{SERVER_KEY}..."
69
122
  server_key = OpenSSL::PKey::RSA.generate(2048)
70
123
  File.write(SERVER_KEY, server_key.to_pem)
71
124
  end
72
125
 
73
- file SERVER_CRT => [TMP_DIR, CA_CRT, SERVER_KEY] do
74
- ca_key = OpenSSL::PKey::RSA.new(File.read(CA_KEY))
75
- ca_crt = OpenSSL::X509::Certificate.new(File.read(CA_CRT))
126
+ file SERVER_CRT => [TMP_DIR, INTER_CRT, SERVER_KEY] do
127
+ inter_key = OpenSSL::PKey::RSA.new(File.read(INTER_KEY))
128
+ inter_crt = OpenSSL::X509::Certificate.new(File.read(INTER_CRT))
76
129
  server_key = OpenSSL::PKey::RSA.new(File.read(SERVER_KEY))
77
130
 
78
131
  puts "generate #{SERVER_CRT}..."
@@ -85,12 +138,12 @@ file SERVER_CRT => [TMP_DIR, CA_CRT, SERVER_KEY] do
85
138
  server_crt.public_key = server_key.public_key
86
139
  server_crt.serial = OpenSSL::BN.rand(64)
87
140
  server_crt.version = 2
88
- server_crt.issuer = ca_crt.issuer
141
+ server_crt.issuer = inter_crt.subject
89
142
  server_crt.subject = sub
90
143
 
91
144
  factory = OpenSSL::X509::ExtensionFactory.new
92
145
  factory.subject_certificate = server_crt
93
- factory.issuer_certificate = ca_crt
146
+ factory.issuer_certificate = inter_crt
94
147
  server_crt.add_extension(
95
148
  factory.create_extension(
96
149
  'basicConstraints',
@@ -109,9 +162,15 @@ file SERVER_CRT => [TMP_DIR, CA_CRT, SERVER_KEY] do
109
162
  'DNS:localhost'
110
163
  )
111
164
  )
165
+ server_crt.add_extension(
166
+ factory.create_extension(
167
+ 'authorityInfoAccess',
168
+ 'caIssuers;URI:http://localhost:8080,OCSP;URI:http://localhost:8080'
169
+ )
170
+ )
112
171
 
113
172
  digest = OpenSSL::Digest::SHA256.new
114
- server_crt.sign(ca_key, digest)
173
+ server_crt.sign(inter_key, digest)
115
174
  File.write(SERVER_CRT, server_crt.to_pem)
116
175
  end
117
176
 
@@ -21,24 +21,22 @@ def simple_http_request(hostname, path = '/')
21
21
  end
22
22
 
23
23
  def simple_http_response(body)
24
- s = <<~RESPONSE
24
+ h = <<~RESPONSE_HEADER_EOS
25
25
  HTTP/1.1 200 OK
26
26
  Date: #{Time.now.httpdate}
27
27
  Content-Type: text/html
28
28
  Content-Length: #{body.length}
29
29
  Server: tttls1.3/examples
30
+ RESPONSE_HEADER_EOS
30
31
 
31
- #{body}
32
- RESPONSE
33
-
34
- s.gsub(WEBrick::LF, WEBrick::CRLF)
32
+ h.gsub(WEBrick::LF, WEBrick::CRLF) + WEBrick::CRLF + body
35
33
  end
36
34
 
37
35
  def recv_http_response(client)
38
36
  parser = HTTP::Parser.new
39
37
  buf = nil
40
38
 
41
- parser.on_headers_complete = proc do |headers|
39
+ parser.on_headers_complete = lambda do |headers|
42
40
  buf =
43
41
  [
44
42
  'HTTP/' + parser.http_version.join('.'),
@@ -49,11 +47,11 @@ def recv_http_response(client)
49
47
  + WEBrick::CRLF
50
48
  end
51
49
 
52
- parser.on_body = proc do |chunk|
50
+ parser.on_body = lambda do |chunk|
53
51
  buf += chunk
54
52
  end
55
53
 
56
- parser.on_message_complete = proc do
54
+ parser.on_message_complete = lambda do
57
55
  client.close
58
56
  end
59
57
 
@@ -12,7 +12,7 @@ settings = {
12
12
  ca_file: File.exist?(ca_file) ? ca_file : nil,
13
13
  alpn: ['http/1.1']
14
14
  }
15
- client = TTTLS13::Client.new(socket, hostname, settings)
15
+ client = TTTLS13::Client.new(socket, hostname, **settings)
16
16
  client.connect
17
17
  client.write(req)
18
18
 
@@ -11,7 +11,7 @@ settings_2nd = {
11
11
  ca_file: File.exist?(ca_file) ? ca_file : nil,
12
12
  alpn: ['http/1.1']
13
13
  }
14
- process_new_session_ticket = proc do |nst, rms, cs|
14
+ process_new_session_ticket = lambda do |nst, rms, cs|
15
15
  return if Time.now.to_i - nst.timestamp > nst.ticket_lifetime
16
16
 
17
17
  settings_2nd[:ticket] = nst.ticket
@@ -22,7 +22,7 @@ process_new_session_ticket = proc do |nst, rms, cs|
22
22
  settings_2nd[:ticket_timestamp] = nst.timestamp
23
23
  end
24
24
  settings_1st = {
25
- ca_file: FileTest.exists?(ca_file) ? ca_file : nil,
25
+ ca_file: File.exist?(ca_file) ? ca_file : nil,
26
26
  alpn: ['http/1.1'],
27
27
  process_new_session_ticket: process_new_session_ticket
28
28
  }
@@ -36,7 +36,7 @@ succeed_early_data = false
36
36
  settings_2nd
37
37
  ].each_with_index do |settings, i|
38
38
  socket = TCPSocket.new(hostname, port)
39
- client = TTTLS13::Client.new(socket, hostname, settings)
39
+ client = TTTLS13::Client.new(socket, hostname, **settings)
40
40
 
41
41
  # send message using early data; 0-RTT
42
42
  client.early_data(req) if i == 1 && settings.include?(:ticket)
@@ -13,7 +13,7 @@ settings = {
13
13
  key_share_groups: [], # empty KeyShareClientHello.client_shares
14
14
  alpn: ['http/1.1']
15
15
  }
16
- client = TTTLS13::Client.new(socket, hostname, settings)
16
+ client = TTTLS13::Client.new(socket, hostname, **settings)
17
17
  client.connect
18
18
  client.write(req)
19
19
  print recv_http_response(client)
@@ -11,7 +11,7 @@ settings_2nd = {
11
11
  ca_file: File.exist?(ca_file) ? ca_file : nil,
12
12
  alpn: ['http/1.1']
13
13
  }
14
- process_new_session_ticket = proc do |nst, rms, cs|
14
+ process_new_session_ticket = lambda do |nst, rms, cs|
15
15
  return if Time.now.to_i - nst.timestamp > nst.ticket_lifetime
16
16
 
17
17
  settings_2nd[:key_share_groups] = [] # empty KeyShareClientHello.client_shares
@@ -35,7 +35,7 @@ settings_1st = {
35
35
  settings_2nd
36
36
  ].each do |settings|
37
37
  socket = TCPSocket.new(hostname, port)
38
- client = TTTLS13::Client.new(socket, hostname, settings)
38
+ client = TTTLS13::Client.new(socket, hostname, **settings)
39
39
  client.connect
40
40
  client.write(req)
41
41
  print recv_http_response(client)
@@ -0,0 +1,31 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'helper'
5
+
6
+ hostname, port = (ARGV[0] || 'localhost:4433').split(':')
7
+ ca_file = __dir__ + '/../tmp/ca.crt'
8
+ req = simple_http_request(hostname)
9
+
10
+ process_certificate_status = lambda do |res, cert, chain|
11
+ puts 'stapled OCSPResponse: '
12
+ puts res.basic.status.pretty_inspect unless res.nil?
13
+ puts '-' * 10
14
+
15
+ TTTLS13::Client.softfail_check_certificate_status(res, cert, chain)
16
+ end
17
+
18
+ socket = TCPSocket.new(hostname, port)
19
+ settings = {
20
+ ca_file: File.exist?(ca_file) ? ca_file : nil,
21
+ alpn: ['http/1.1'],
22
+ check_certificate_status: true,
23
+ process_certificate_status: process_certificate_status
24
+ }
25
+ client = TTTLS13::Client.new(socket, hostname, **settings)
26
+ client.connect
27
+ client.write(req)
28
+
29
+ print recv_http_response(client)
30
+ client.close unless client.eof?
31
+ socket.close
@@ -11,7 +11,7 @@ settings_2nd = {
11
11
  ca_file: File.exist?(ca_file) ? ca_file : nil,
12
12
  alpn: ['http/1.1']
13
13
  }
14
- process_new_session_ticket = proc do |nst, rms, cs|
14
+ process_new_session_ticket = lambda do |nst, rms, cs|
15
15
  return if Time.now.to_i - nst.timestamp > nst.ticket_lifetime
16
16
 
17
17
  settings_2nd[:ticket] = nst.ticket
@@ -34,7 +34,7 @@ settings_1st = {
34
34
  settings_2nd
35
35
  ].each do |settings|
36
36
  socket = TCPSocket.new(hostname, port)
37
- client = TTTLS13::Client.new(socket, hostname, settings)
37
+ client = TTTLS13::Client.new(socket, hostname, **settings)
38
38
  client.connect
39
39
  client.write(req)
40
40
  print recv_http_response(client)
@@ -10,6 +10,7 @@ port = ARGV[0] || 4433
10
10
 
11
11
  settings = {
12
12
  crt_file: __dir__ + '/../tmp/server.crt',
13
+ chain_files: [__dir__ + '/../tmp/intermediate.crt'],
13
14
  key_file: __dir__ + '/../tmp/server.key',
14
15
  alpn: ['http/1.1']
15
16
  }
@@ -22,10 +23,10 @@ Etc.nprocessors.times do
22
23
  loop do
23
24
  s = q.pop
24
25
  Timeout.timeout(1) do
25
- server = TTTLS13::Server.new(s, settings)
26
+ server = TTTLS13::Server.new(s, **settings)
26
27
  parser = HTTP::Parser.new
27
28
 
28
- parser.on_message_complete = proc do
29
+ parser.on_message_complete = lambda do
29
30
  if !parser.http_method.nil?
30
31
  logger.info 'Receive Request'
31
32
  server.write(simple_http_response('TEST'))
@@ -38,10 +39,10 @@ Etc.nprocessors.times do
38
39
  begin
39
40
  server.accept
40
41
  parser << server.read until server.eof?
41
- rescue HTTP::Parser::Error, TTTLS13::Error::ErrorAlerts
42
- logger.warn 'Parser Error'
42
+ server.close
43
+ rescue StandardError => e
44
+ logger.warn e
43
45
  ensure
44
- server.close unless server.eof?
45
46
  parser.reset!
46
47
  end
47
48
  end
@@ -7,14 +7,13 @@ FIXTURES_DIR = __dir__ + '/../spec/fixtures'
7
7
  PORT = 4433
8
8
 
9
9
  RSpec.describe Client do
10
- # testcases
11
10
  # normal [Boolean] Is this nominal scenarios?
12
11
  # opt [String] openssl s_server options
13
12
  # crt [String] server crt file path
14
13
  # key [String] server key file path
15
14
  # settings [Hash] TTTLS13::Server settings
16
- [
17
- # rubocop: disable Metrics/LineLength
15
+ # rubocop: disable Layout/LineLength
16
+ testcases = [
18
17
  [
19
18
  true,
20
19
  '-ciphersuites TLS_AES_256_GCM_SHA384',
@@ -163,8 +162,9 @@ RSpec.describe Client do
163
162
  'rsa_rsa.key',
164
163
  compatibility_mode: false
165
164
  ]
166
- # rubocop: enable Metrics/LineLength
167
- ].each do |normal, opt, crt, key, settings|
165
+ ]
166
+ # rubocop: enable Layout/LineLength
167
+ testcases.each do |normal, opt, crt, key, settings|
168
168
  context 'client interop' do
169
169
  before do
170
170
  cmd = 'openssl s_server ' \
@@ -177,17 +177,17 @@ RSpec.describe Client do
177
177
  pid = spawn('docker run ' \
178
178
  + "--volume #{FIXTURES_DIR}:/tmp " \
179
179
  + "--publish #{PORT}:#{PORT} " \
180
- + 'openssl ' + cmd)
180
+ + 'thekuwayama/openssl ' + cmd)
181
181
  Process.detach(pid)
182
182
 
183
- wait_to_listen(PORT)
183
+ wait_to_listen('127.0.0.1', PORT)
184
184
  end
185
185
 
186
186
  let(:client) do
187
187
  hostname = 'localhost'
188
188
  @socket = TCPSocket.new(hostname, PORT)
189
189
  settings[:ca_file] = FIXTURES_DIR + '/rsa_ca.crt'
190
- Client.new(@socket, hostname, settings)
190
+ Client.new(@socket, hostname, **settings)
191
191
  end
192
192
 
193
193
  after do