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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +32 -0
- data/.rubocop.yml +9 -2
- data/Gemfile +1 -1
- data/README.md +5 -1
- data/Rakefile +66 -7
- data/example/helper.rb +6 -8
- data/example/https_client.rb +1 -1
- data/example/https_client_using_0rtt.rb +3 -3
- data/example/https_client_using_hrr.rb +1 -1
- data/example/https_client_using_hrr_and_ticket.rb +2 -2
- data/example/https_client_using_status_request.rb +31 -0
- data/example/https_client_using_ticket.rb +2 -2
- data/example/https_server.rb +6 -5
- data/interop/client_spec.rb +8 -8
- data/interop/helper.rb +10 -2
- data/interop/server_spec.rb +14 -10
- data/lib/tttls1.3.rb +1 -0
- data/lib/tttls1.3/client.rb +97 -12
- data/lib/tttls1.3/connection.rb +45 -12
- data/lib/tttls1.3/cryptograph.rb +1 -1
- data/lib/tttls1.3/cryptograph/aead.rb +20 -7
- data/lib/tttls1.3/message.rb +1 -1
- data/lib/tttls1.3/message/alert.rb +2 -2
- data/lib/tttls1.3/message/extension/status_request.rb +73 -17
- data/lib/tttls1.3/message/extensions.rb +35 -12
- data/lib/tttls1.3/server.rb +40 -13
- data/lib/tttls1.3/utils.rb +15 -0
- data/lib/tttls1.3/version.rb +1 -1
- data/spec/extensions_spec.rb +16 -0
- data/spec/fixtures/rsa_rsa.crt +15 -15
- data/spec/fixtures/rsa_rsa.key +25 -25
- data/spec/fixtures/rsa_rsa_ocsp.crt +18 -0
- data/spec/fixtures/rsa_rsa_ocsp.key +27 -0
- data/spec/server_hello_spec.rb +1 -1
- data/spec/spec_helper.rb +35 -1
- data/spec/status_request_spec.rb +77 -10
- data/tttls1.3.gemspec +1 -1
- metadata +14 -10
- data/.travis.yml +0 -18
- data/interop/Dockerfile +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3861f9a9864268fda75836b387c4a1f83e4edea0e885595155f2a352f69695ea
|
4
|
+
data.tar.gz: 617f9b12aa8ac8e39367b1b5f9fcba57d1bd3dc669fe645c7c6888a7140795bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/.rubocop.yml
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
AllCops:
|
2
2
|
TargetRubyVersion: 2.6
|
3
3
|
|
4
|
-
Style/
|
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/
|
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
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
|
-
[![
|
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,
|
74
|
-
|
75
|
-
|
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 =
|
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 =
|
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(
|
173
|
+
server_crt.sign(inter_key, digest)
|
115
174
|
File.write(SERVER_CRT, server_crt.to_pem)
|
116
175
|
end
|
117
176
|
|
data/example/helper.rb
CHANGED
@@ -21,24 +21,22 @@ def simple_http_request(hostname, path = '/')
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def simple_http_response(body)
|
24
|
-
|
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
|
-
|
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 =
|
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 =
|
50
|
+
parser.on_body = lambda do |chunk|
|
53
51
|
buf += chunk
|
54
52
|
end
|
55
53
|
|
56
|
-
parser.on_message_complete =
|
54
|
+
parser.on_message_complete = lambda do
|
57
55
|
client.close
|
58
56
|
end
|
59
57
|
|
data/example/https_client.rb
CHANGED
@@ -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 =
|
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:
|
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 =
|
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 =
|
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)
|
data/example/https_server.rb
CHANGED
@@ -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 =
|
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
|
-
|
42
|
-
|
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
|
data/interop/client_spec.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
167
|
-
|
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
|