tttls1.3 0.3.1 → 0.3.3
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 +4 -4
- data/.rubocop.yml +3 -0
- data/Gemfile +1 -0
- data/example/helper.rb +43 -0
- data/example/https_client_using_0rtt.rb +5 -3
- data/example/https_client_using_ech.rb +6 -7
- data/example/https_client_using_grease_ech.rb +0 -2
- data/example/https_client_using_hrr.rb +2 -1
- data/example/https_client_using_hrr_and_ech.rb +6 -7
- data/example/https_client_using_hrr_and_ticket.rb +4 -2
- data/example/https_client_using_status_request.rb +2 -1
- data/example/https_client_using_ticket.rb +4 -2
- data/example/https_client_using_ticket_and_ech.rb +57 -0
- data/example/https_server.rb +14 -1
- data/lib/tttls1.3/client.rb +205 -418
- data/lib/tttls1.3/connection.rb +21 -362
- data/lib/tttls1.3/ech.rb +426 -0
- data/lib/tttls1.3/endpoint.rb +276 -0
- data/lib/tttls1.3/message/certificate_verify.rb +1 -1
- data/lib/tttls1.3/message/extension/ech.rb +21 -24
- data/lib/tttls1.3/message/extension/ech_outer_extensions.rb +52 -0
- data/lib/tttls1.3/message/extension/signature_algorithms.rb +2 -2
- data/lib/tttls1.3/message/extension/supported_versions.rb +3 -3
- data/lib/tttls1.3/message/extension/unknown_extension.rb +2 -2
- data/lib/tttls1.3/message/extensions.rb +30 -0
- data/lib/tttls1.3/message.rb +1 -0
- data/lib/tttls1.3/server.rb +125 -63
- data/lib/tttls1.3/utils.rb +37 -0
- data/lib/tttls1.3/version.rb +1 -1
- data/lib/tttls1.3.rb +2 -1
- data/spec/client_spec.rb +21 -60
- data/spec/ech_outer_extensions_spec.rb +42 -0
- data/spec/ech_spec.rb +41 -0
- data/spec/{connection_spec.rb → endpoint_spec.rb} +41 -49
- data/spec/extensions_spec.rb +65 -0
- data/spec/server_spec.rb +12 -12
- data/spec/spec_helper.rb +4 -0
- metadata +11 -6
- data/lib/tttls1.3/hpke.rb +0 -91
data/lib/tttls1.3/version.rb
CHANGED
data/lib/tttls1.3.rb
CHANGED
@@ -21,7 +21,8 @@ require 'tttls1.3/key_schedule'
|
|
21
21
|
require 'tttls1.3/message'
|
22
22
|
require 'tttls1.3/sequence_number'
|
23
23
|
require 'tttls1.3/sslkeylogfile'
|
24
|
-
require 'tttls1.3/
|
24
|
+
require 'tttls1.3/ech'
|
25
25
|
require 'tttls1.3/connection'
|
26
|
+
require 'tttls1.3/endpoint'
|
26
27
|
require 'tttls1.3/client'
|
27
28
|
require 'tttls1.3/server'
|
data/spec/client_spec.rb
CHANGED
@@ -129,10 +129,11 @@ RSpec.describe Client do
|
|
129
129
|
client = Client.new(mock_socket, 'localhost')
|
130
130
|
digest = CipherSuite.digest(cipher_suite)
|
131
131
|
hash = transcript.hash(digest, EOED)
|
132
|
-
signature =
|
133
|
-
|
134
|
-
|
135
|
-
|
132
|
+
signature = Endpoint.sign_finished(
|
133
|
+
digest: digest,
|
134
|
+
finished_key: finished_key,
|
135
|
+
hash: hash
|
136
|
+
)
|
136
137
|
hs_wcipher = Cryptograph::Aead.new(
|
137
138
|
cipher_suite: cipher_suite,
|
138
139
|
write_key: TESTBINARY_CLIENT_FINISHED_WRITE_KEY,
|
@@ -215,20 +216,22 @@ RSpec.describe Client do
|
|
215
216
|
it 'should verify server Finished' do
|
216
217
|
digest = CipherSuite.digest(cipher_suite)
|
217
218
|
hash = transcript.hash(digest, CV)
|
218
|
-
expect(
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
219
|
+
expect(Endpoint.verified_finished?(
|
220
|
+
finished: sf,
|
221
|
+
digest: digest,
|
222
|
+
finished_key: key_schedule.server_finished_key,
|
223
|
+
hash: hash
|
224
|
+
)).to be true
|
223
225
|
end
|
224
226
|
|
225
227
|
it 'should sign client Finished' do
|
226
228
|
digest = CipherSuite.digest(cipher_suite)
|
227
229
|
hash = transcript.hash(digest, EOED)
|
228
|
-
expect(
|
229
|
-
|
230
|
-
|
231
|
-
|
230
|
+
expect(Endpoint.sign_finished(
|
231
|
+
digest: digest,
|
232
|
+
finished_key: key_schedule.client_finished_key,
|
233
|
+
hash: hash
|
234
|
+
)).to eq cf.verify_data
|
232
235
|
end
|
233
236
|
end
|
234
237
|
|
@@ -240,18 +243,16 @@ RSpec.describe Client do
|
|
240
243
|
Certificate.new(certificate_list: [CertificateEntry.new(server_crt)])
|
241
244
|
end
|
242
245
|
|
243
|
-
let(:client) do
|
244
|
-
Client.new(nil, 'localhost')
|
245
|
-
end
|
246
|
-
|
247
246
|
it 'should not certify certificate' do
|
248
|
-
expect(
|
247
|
+
expect(Endpoint.trusted_certificate?(certificate.certificate_list))
|
249
248
|
.to be false
|
250
249
|
end
|
251
250
|
|
252
251
|
it 'should certify certificate, received path to private ca.crt' do
|
253
|
-
expect(
|
254
|
-
|
252
|
+
expect(Endpoint.trusted_certificate?(
|
253
|
+
certificate.certificate_list,
|
254
|
+
__dir__ + '/fixtures/rsa_ca.crt'
|
255
|
+
)).to be true
|
255
256
|
end
|
256
257
|
end
|
257
258
|
|
@@ -270,44 +271,4 @@ RSpec.describe Client do
|
|
270
271
|
'SHA256')).to eq TESTBINARY_0_RTT_PSK
|
271
272
|
end
|
272
273
|
end
|
273
|
-
|
274
|
-
context 'EncodedClientHelloInner length' do
|
275
|
-
let(:server_name) do
|
276
|
-
'localhost'
|
277
|
-
end
|
278
|
-
|
279
|
-
let(:client) do
|
280
|
-
Client.new(nil, server_name)
|
281
|
-
end
|
282
|
-
|
283
|
-
let(:maximum_name_length) do
|
284
|
-
0
|
285
|
-
end
|
286
|
-
|
287
|
-
let(:encoded) do
|
288
|
-
extensions, = client.send(:gen_ch_extensions)
|
289
|
-
inner_ech = Message::Extension::ECHClientHello.new_inner
|
290
|
-
Message::ClientHello.new(
|
291
|
-
legacy_session_id: '',
|
292
|
-
cipher_suites: CipherSuites.new(DEFAULT_CH_CIPHER_SUITES),
|
293
|
-
extensions: extensions.merge(
|
294
|
-
Message::ExtensionType::ENCRYPTED_CLIENT_HELLO => inner_ech
|
295
|
-
)
|
296
|
-
)
|
297
|
-
end
|
298
|
-
|
299
|
-
let(:padding_encoded_ch_inner) do
|
300
|
-
client.send(
|
301
|
-
:padding_encoded_ch_inner,
|
302
|
-
encoded.serialize[4..],
|
303
|
-
server_name.length,
|
304
|
-
maximum_name_length
|
305
|
-
)
|
306
|
-
end
|
307
|
-
|
308
|
-
it 'should be equal placeholder_encoded_ch_inner_len' do
|
309
|
-
expect(client.send(:placeholder_encoded_ch_inner_len))
|
310
|
-
.to eq padding_encoded_ch_inner.length
|
311
|
-
end
|
312
|
-
end
|
313
274
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe ECHOuterExtensions do
|
8
|
+
context 'valid ech_outer_extensions, [key_share]' do
|
9
|
+
let(:extension) do
|
10
|
+
ECHOuterExtensions.new([ExtensionType::KEY_SHARE])
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be generated' do
|
14
|
+
expect(extension.extension_type).to eq ExtensionType::ECH_OUTER_EXTENSIONS
|
15
|
+
expect(extension.outer_extensions).to eq [ExtensionType::KEY_SHARE]
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should be serialized' do
|
19
|
+
expect(extension.serialize).to eq ExtensionType::ECH_OUTER_EXTENSIONS \
|
20
|
+
+ 3.to_uint16 \
|
21
|
+
+ 2.to_uint8 \
|
22
|
+
+ ExtensionType::KEY_SHARE
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'valid ech_outer_extensions binary' do
|
27
|
+
let(:extension) do
|
28
|
+
ECHOuterExtensions.deserialize(TESTBINARY_ECH_OUTER_EXTENSIONS)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should generate valid object' do
|
32
|
+
expect(extension.extension_type).to be ExtensionType::ECH_OUTER_EXTENSIONS
|
33
|
+
expect(extension.outer_extensions).to eq [ExtensionType::KEY_SHARE]
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should generate serializable object' do
|
37
|
+
expect(extension.serialize)
|
38
|
+
.to eq ExtensionType::ECH_OUTER_EXTENSIONS \
|
39
|
+
+ TESTBINARY_ECH_OUTER_EXTENSIONS.prefix_uint16_length
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/spec/ech_spec.rb
CHANGED
@@ -79,3 +79,44 @@ RSpec.describe ECHClientHello do
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
82
|
+
|
83
|
+
RSpec.describe Ech do
|
84
|
+
context 'EncodedClientHelloInner length' do
|
85
|
+
let(:server_name) do
|
86
|
+
'localhost'
|
87
|
+
end
|
88
|
+
|
89
|
+
let(:client) do
|
90
|
+
Client.new(nil, server_name)
|
91
|
+
end
|
92
|
+
|
93
|
+
let(:maximum_name_length) do
|
94
|
+
0
|
95
|
+
end
|
96
|
+
|
97
|
+
let(:encoded) do
|
98
|
+
extensions, = client.send(:gen_ch_extensions)
|
99
|
+
inner_ech = Message::Extension::ECHClientHello.new_inner
|
100
|
+
Message::ClientHello.new(
|
101
|
+
legacy_session_id: '',
|
102
|
+
cipher_suites: CipherSuites.new(DEFAULT_CH_CIPHER_SUITES),
|
103
|
+
extensions: extensions.merge(
|
104
|
+
Message::ExtensionType::ENCRYPTED_CLIENT_HELLO => inner_ech
|
105
|
+
)
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
let(:padding_encoded_ch_inner) do
|
110
|
+
Ech.padding_encoded_ch_inner(
|
111
|
+
encoded.serialize[4..],
|
112
|
+
server_name.length,
|
113
|
+
maximum_name_length
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should be equal placeholder_encoded_ch_inner_len' do
|
118
|
+
expect(Ech.placeholder_encoded_ch_inner_len)
|
119
|
+
.to eq padding_encoded_ch_inner.length
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
|
4
4
|
require_relative 'spec_helper'
|
5
5
|
|
6
|
-
RSpec.describe
|
7
|
-
context '
|
6
|
+
RSpec.describe Endpoint do
|
7
|
+
context 'endpoint, Simple 1-RTT Handshake,' do
|
8
8
|
let(:key) do
|
9
9
|
n = OpenSSL::BN.new(TESTBINARY_PKEY_MODULUS, 2)
|
10
10
|
e = OpenSSL::BN.new(TESTBINARY_PKEY_PUBLIC_EXPONENT, 2)
|
@@ -66,39 +66,35 @@ RSpec.describe Connection do
|
|
66
66
|
CipherSuite.digest(CipherSuite::TLS_AES_128_GCM_SHA256)
|
67
67
|
end
|
68
68
|
|
69
|
-
let(:connection) do
|
70
|
-
Connection.new(nil)
|
71
|
-
end
|
72
|
-
|
73
69
|
it 'should verify server CertificateVerify.signature' do
|
74
70
|
public_key = ct.certificate_list.first.cert_data.public_key
|
75
71
|
signature_scheme = cv.signature_scheme
|
76
72
|
signature = cv.signature
|
77
73
|
|
78
|
-
expect(
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
74
|
+
expect(Endpoint.verified_certificate_verify?(
|
75
|
+
public_key: public_key,
|
76
|
+
signature_scheme: signature_scheme,
|
77
|
+
signature: signature,
|
78
|
+
context: 'TLS 1.3, server CertificateVerify',
|
79
|
+
hash: transcript.hash(digest, CT)
|
80
|
+
)).to be true
|
85
81
|
end
|
86
82
|
|
87
83
|
it 'should sign client Finished.verify_data' do
|
88
|
-
expect(
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
84
|
+
expect(Endpoint.sign_finished(
|
85
|
+
digest: 'SHA256',
|
86
|
+
finished_key: TESTBINARY_CLIENT_FINISHED_KEY,
|
87
|
+
hash: transcript.hash(digest, EOED)
|
88
|
+
)).to eq cf.verify_data
|
93
89
|
end
|
94
90
|
|
95
91
|
it 'should verify server Finished.verify_data' do
|
96
|
-
expect(
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
92
|
+
expect(Endpoint.verified_finished?(
|
93
|
+
finished: sf,
|
94
|
+
digest: 'SHA256',
|
95
|
+
finished_key: TESTBINARY_SERVER_FINISHED_KEY,
|
96
|
+
hash: transcript.hash(digest, CV)
|
97
|
+
)).to be true
|
102
98
|
end
|
103
99
|
|
104
100
|
it 'should sign server CertificateVerify.signature' do
|
@@ -107,23 +103,23 @@ RSpec.describe Connection do
|
|
107
103
|
|
108
104
|
# used RSASSA-PSS signature_scheme, salt is a random sequence.
|
109
105
|
# CertificateVerify.signature is random.
|
110
|
-
signature =
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
expect(
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
106
|
+
signature = Endpoint.sign_certificate_verify(
|
107
|
+
key: key,
|
108
|
+
signature_scheme: signature_scheme,
|
109
|
+
context: 'TLS 1.3, server CertificateVerify',
|
110
|
+
hash: transcript.hash(digest, CT)
|
111
|
+
)
|
112
|
+
expect(Endpoint.verified_certificate_verify?(
|
113
|
+
public_key: public_key,
|
114
|
+
signature_scheme: signature_scheme,
|
115
|
+
signature: signature,
|
116
|
+
context: 'TLS 1.3, server CertificateVerify',
|
117
|
+
hash: transcript.hash(digest, CT)
|
118
|
+
)).to be true
|
123
119
|
end
|
124
120
|
end
|
125
121
|
|
126
|
-
context '
|
122
|
+
context 'endpoint, HelloRetryRequest,' do
|
127
123
|
let(:ct) do
|
128
124
|
Certificate.deserialize(TESTBINARY_HRR_CERTIFICATE)
|
129
125
|
end
|
@@ -154,22 +150,18 @@ RSpec.describe Connection do
|
|
154
150
|
CipherSuite.digest(CipherSuite::TLS_AES_128_GCM_SHA256)
|
155
151
|
end
|
156
152
|
|
157
|
-
let(:connection) do
|
158
|
-
Connection.new(nil)
|
159
|
-
end
|
160
|
-
|
161
153
|
it 'should verify server CertificateVerify.signature' do
|
162
154
|
public_key = ct.certificate_list.first.cert_data.public_key
|
163
155
|
signature_scheme = cv.signature_scheme
|
164
156
|
signature = cv.signature
|
165
157
|
|
166
|
-
expect(
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
158
|
+
expect(Endpoint.verified_certificate_verify?(
|
159
|
+
public_key: public_key,
|
160
|
+
signature_scheme: signature_scheme,
|
161
|
+
signature: signature,
|
162
|
+
context: 'TLS 1.3, server CertificateVerify',
|
163
|
+
hash: transcript.hash(digest, CT)
|
164
|
+
)).to be true
|
173
165
|
end
|
174
166
|
end
|
175
167
|
end
|
data/spec/extensions_spec.rb
CHANGED
@@ -182,4 +182,69 @@ RSpec.describe Extensions do
|
|
182
182
|
.to raise_error(ErrorAlerts)
|
183
183
|
end
|
184
184
|
end
|
185
|
+
|
186
|
+
context 'removing and replacing extensions from EncodedClientHelloInner' do
|
187
|
+
let(:extensions) do
|
188
|
+
extensions, = Client.new(nil, 'localhost').send(:gen_ch_extensions)
|
189
|
+
extensions
|
190
|
+
end
|
191
|
+
|
192
|
+
let(:no_key_share_exs) do
|
193
|
+
Extensions.new(
|
194
|
+
extensions.filter { |k, _| k != ExtensionType::KEY_SHARE }.values
|
195
|
+
)
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should be equal remove_and_replace! with []' do
|
199
|
+
expected = extensions.clone
|
200
|
+
got = extensions.remove_and_replace!([])
|
201
|
+
|
202
|
+
expect(got.keys).to eq expected.keys
|
203
|
+
expect(got[ExtensionType::ECH_OUTER_EXTENSIONS]).to eq nil
|
204
|
+
expect(extensions.keys - got.keys).to eq []
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'should be equal remove_and_replace! with [key_share]' do
|
208
|
+
expected = extensions.filter { |k, _| k != ExtensionType::KEY_SHARE }
|
209
|
+
expected[ExtensionType::ECH_OUTER_EXTENSIONS] = \
|
210
|
+
Extension::ECHOuterExtensions.new([ExtensionType::KEY_SHARE])
|
211
|
+
got = extensions.remove_and_replace!([ExtensionType::KEY_SHARE])
|
212
|
+
|
213
|
+
expect(got.keys).to eq expected.keys
|
214
|
+
expect(got[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions)
|
215
|
+
.to eq expected[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions
|
216
|
+
expect(extensions.keys - got.keys)
|
217
|
+
.to eq expected[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'should be equal remove_and_replace! with' \
|
221
|
+
' [key_share,supported_versions]' do
|
222
|
+
outer_extensions = [
|
223
|
+
ExtensionType::KEY_SHARE,
|
224
|
+
ExtensionType::SUPPORTED_VERSIONS
|
225
|
+
]
|
226
|
+
expected = extensions.filter { |k, _| !outer_extensions.include?(k) }
|
227
|
+
expected[ExtensionType::ECH_OUTER_EXTENSIONS] = \
|
228
|
+
Extension::ECHOuterExtensions.new(
|
229
|
+
extensions.filter { |k, _| outer_extensions.include?(k) }.keys
|
230
|
+
)
|
231
|
+
got = extensions.remove_and_replace!(outer_extensions)
|
232
|
+
|
233
|
+
expect(got.keys).to eq expected.keys
|
234
|
+
expect(got[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions)
|
235
|
+
.to eq expected[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions
|
236
|
+
expect(extensions.keys - got.keys)
|
237
|
+
.to eq expected[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'should be equal remove_and_replace! with no key_share extensions' \
|
241
|
+
' & [key_share]' do
|
242
|
+
expected = no_key_share_exs.clone
|
243
|
+
got = no_key_share_exs.remove_and_replace!([ExtensionType::KEY_SHARE])
|
244
|
+
|
245
|
+
expect(got).to eq expected
|
246
|
+
expect(got[ExtensionType::ECH_OUTER_EXTENSIONS]).to eq nil
|
247
|
+
expect(no_key_share_exs.keys - got.keys).to eq []
|
248
|
+
end
|
249
|
+
end
|
185
250
|
end
|
data/spec/server_spec.rb
CHANGED
@@ -174,13 +174,13 @@ RSpec.describe Server do
|
|
174
174
|
signature_scheme = cv.signature_scheme
|
175
175
|
signature = cv.signature
|
176
176
|
digest = CipherSuite.digest(cipher_suite)
|
177
|
-
expect(
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
177
|
+
expect(Endpoint.verified_certificate_verify?(
|
178
|
+
public_key: public_key,
|
179
|
+
signature_scheme: signature_scheme,
|
180
|
+
signature: signature,
|
181
|
+
context: 'TLS 1.3, server CertificateVerify',
|
182
|
+
hash: transcript.hash(digest, CT)
|
183
|
+
)).to be true
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
@@ -213,12 +213,12 @@ RSpec.describe Server do
|
|
213
213
|
end
|
214
214
|
|
215
215
|
let(:signature) do
|
216
|
-
server = Server.new(nil)
|
217
216
|
digest = CipherSuite.digest(cipher_suite)
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
217
|
+
Endpoint.sign_finished(
|
218
|
+
digest: digest,
|
219
|
+
finished_key: key_schedule.server_finished_key,
|
220
|
+
hash: transcript.hash(digest, CV)
|
221
|
+
)
|
222
222
|
end
|
223
223
|
|
224
224
|
let(:sf) do
|
data/spec/spec_helper.rb
CHANGED
@@ -245,6 +245,10 @@ TESTBINARY_ECH_HRR = <<BIN.split.map(&:hex).map(&:chr).join
|
|
245
245
|
00 00 00 00 00 00 00 00
|
246
246
|
BIN
|
247
247
|
|
248
|
+
TESTBINARY_ECH_OUTER_EXTENSIONS = <<BIN.split.map(&:hex).map(&:chr).join
|
249
|
+
02 00 33
|
250
|
+
BIN
|
251
|
+
|
248
252
|
# https://datatracker.ietf.org/doc/html/rfc8448#section-3
|
249
253
|
# 3. Simple 1-RTT Handshake
|
250
254
|
TESTBINARY_CLIENT_HELLO = <<BIN.split.map(&:hex).map(&:chr).join
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tttls1.3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thekuwayama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -108,6 +108,7 @@ files:
|
|
108
108
|
- example/https_client_using_hrr_and_ticket.rb
|
109
109
|
- example/https_client_using_status_request.rb
|
110
110
|
- example/https_client_using_ticket.rb
|
111
|
+
- example/https_client_using_ticket_and_ech.rb
|
111
112
|
- example/https_server.rb
|
112
113
|
- interop/client_spec.rb
|
113
114
|
- interop/server_spec.rb
|
@@ -119,8 +120,9 @@ files:
|
|
119
120
|
- lib/tttls1.3/cryptograph.rb
|
120
121
|
- lib/tttls1.3/cryptograph/aead.rb
|
121
122
|
- lib/tttls1.3/cryptograph/passer.rb
|
123
|
+
- lib/tttls1.3/ech.rb
|
124
|
+
- lib/tttls1.3/endpoint.rb
|
122
125
|
- lib/tttls1.3/error.rb
|
123
|
-
- lib/tttls1.3/hpke.rb
|
124
126
|
- lib/tttls1.3/key_schedule.rb
|
125
127
|
- lib/tttls1.3/logging.rb
|
126
128
|
- lib/tttls1.3/message.rb
|
@@ -138,6 +140,7 @@ files:
|
|
138
140
|
- lib/tttls1.3/message/extension/cookie.rb
|
139
141
|
- lib/tttls1.3/message/extension/early_data_indication.rb
|
140
142
|
- lib/tttls1.3/message/extension/ech.rb
|
143
|
+
- lib/tttls1.3/message/extension/ech_outer_extensions.rb
|
141
144
|
- lib/tttls1.3/message/extension/key_share.rb
|
142
145
|
- lib/tttls1.3/message/extension/pre_shared_key.rb
|
143
146
|
- lib/tttls1.3/message/extension/psk_key_exchange_modes.rb
|
@@ -173,12 +176,13 @@ files:
|
|
173
176
|
- spec/client_hello_spec.rb
|
174
177
|
- spec/client_spec.rb
|
175
178
|
- spec/compress_certificate_spec.rb
|
176
|
-
- spec/connection_spec.rb
|
177
179
|
- spec/cookie_spec.rb
|
178
180
|
- spec/early_data_indication_spec.rb
|
181
|
+
- spec/ech_outer_extensions_spec.rb
|
179
182
|
- spec/ech_spec.rb
|
180
183
|
- spec/encrypted_extensions_spec.rb
|
181
184
|
- spec/end_of_early_data_spec.rb
|
185
|
+
- spec/endpoint_spec.rb
|
182
186
|
- spec/error_spec.rb
|
183
187
|
- spec/extensions_spec.rb
|
184
188
|
- spec/finished_spec.rb
|
@@ -235,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
235
239
|
- !ruby/object:Gem::Version
|
236
240
|
version: '0'
|
237
241
|
requirements: []
|
238
|
-
rubygems_version: 3.
|
242
|
+
rubygems_version: 3.5.3
|
239
243
|
signing_key:
|
240
244
|
specification_version: 4
|
241
245
|
summary: TLS 1.3 implementation in Ruby (Tiny Trial TLS1.3 aka tttls1.3)
|
@@ -251,12 +255,13 @@ test_files:
|
|
251
255
|
- spec/client_hello_spec.rb
|
252
256
|
- spec/client_spec.rb
|
253
257
|
- spec/compress_certificate_spec.rb
|
254
|
-
- spec/connection_spec.rb
|
255
258
|
- spec/cookie_spec.rb
|
256
259
|
- spec/early_data_indication_spec.rb
|
260
|
+
- spec/ech_outer_extensions_spec.rb
|
257
261
|
- spec/ech_spec.rb
|
258
262
|
- spec/encrypted_extensions_spec.rb
|
259
263
|
- spec/end_of_early_data_spec.rb
|
264
|
+
- spec/endpoint_spec.rb
|
260
265
|
- spec/error_spec.rb
|
261
266
|
- spec/extensions_spec.rb
|
262
267
|
- spec/finished_spec.rb
|
data/lib/tttls1.3/hpke.rb
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module TTTLS13
|
5
|
-
# NOTE: Hpke module is the adapter for ech_config using hpke-rb.
|
6
|
-
module Hpke
|
7
|
-
module KemId
|
8
|
-
# https://www.iana.org/assignments/hpke/hpke.xhtml#hpke-kem-ids
|
9
|
-
P_256_SHA256 = 0x0010
|
10
|
-
P_384_SHA384 = 0x0011
|
11
|
-
P_521_SHA512 = 0x0012
|
12
|
-
X25519_SHA256 = 0x0020
|
13
|
-
X448_SHA512 = 0x0021
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.kem_id2dhkem(kem_id)
|
17
|
-
case kem_id
|
18
|
-
when KemId::P_256_SHA256
|
19
|
-
%i[p_256 sha256]
|
20
|
-
when KemId::P_384_SHA384
|
21
|
-
%i[p_384 sha384]
|
22
|
-
when KemId::P_521_SHA512
|
23
|
-
%i[p_521 sha512]
|
24
|
-
when KemId::X25519_SHA256
|
25
|
-
%i[x25519 sha256]
|
26
|
-
when KemId::X448_SHA512
|
27
|
-
%i[x448 sha512]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.kem_curve_name2dhkem(kem_curve_name)
|
32
|
-
case kem_curve_name
|
33
|
-
when :p_256
|
34
|
-
HPKE::DHKEM::EC::P_256
|
35
|
-
when :p_384
|
36
|
-
HPKE::DHKEM::EC::P_384
|
37
|
-
when :p_521
|
38
|
-
HPKE::DHKEM::EC::P_521
|
39
|
-
when :x25519
|
40
|
-
HPKE::DHKEM::X25519
|
41
|
-
when :x448
|
42
|
-
HPKE::DHKEM::X448
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
module KdfId
|
47
|
-
# https://www.iana.org/assignments/hpke/hpke.xhtml#hpke-kdf-ids
|
48
|
-
HKDF_SHA256 = 0x0001
|
49
|
-
HKDF_SHA384 = 0x0002
|
50
|
-
HKDF_SHA512 = 0x0003
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.kdf_id2kdf_hash(kdf_id)
|
54
|
-
case kdf_id
|
55
|
-
when KdfId::HKDF_SHA256
|
56
|
-
:sha256
|
57
|
-
when KdfId::HKDF_SHA384
|
58
|
-
:sha384
|
59
|
-
when KdfId::HKDF_SHA512
|
60
|
-
:sha512
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
module AeadId
|
65
|
-
# https://www.iana.org/assignments/hpke/hpke.xhtml#hpke-aead-ids
|
66
|
-
AES_128_GCM = 0x0001
|
67
|
-
AES_256_GCM = 0x0002
|
68
|
-
CHACHA20_POLY1305 = 0x0003
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.aead_id2overhead_len(aead_id)
|
72
|
-
case aead_id
|
73
|
-
when AeadId::AES_128_GCM, AeadId::CHACHA20_POLY1305
|
74
|
-
16
|
75
|
-
when AeadId::AES_256_GCM
|
76
|
-
32
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def self.aead_id2aead_cipher(aead_id)
|
81
|
-
case aead_id
|
82
|
-
when AeadId::AES_128_GCM
|
83
|
-
:aes_128_gcm
|
84
|
-
when AeadId::AES_256_GCM
|
85
|
-
:aes_256_gcm
|
86
|
-
when AeadId::CHACHA20_POLY1305
|
87
|
-
:chacha20_poly1305
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|