tttls1.3 0.2.18 → 0.3.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 +4 -4
- data/.github/workflows/ci.yml +8 -5
- data/Gemfile +2 -0
- data/README.md +6 -3
- data/example/helper.rb +5 -2
- data/example/https_client_using_0rtt.rb +1 -1
- data/example/https_client_using_ech.rb +32 -0
- data/example/https_client_using_grease_ech.rb +26 -0
- data/example/https_client_using_grease_psk.rb +66 -0
- data/example/https_client_using_hrr_and_ech.rb +32 -0
- data/example/https_client_using_hrr_and_ticket.rb +1 -1
- data/example/https_client_using_ticket.rb +1 -1
- data/interop/client_spec.rb +3 -2
- data/interop/server_spec.rb +1 -3
- data/interop/{helper.rb → spec_helper.rb} +12 -5
- data/lib/tttls1.3/client.rb +553 -32
- data/lib/tttls1.3/connection.rb +9 -8
- data/lib/tttls1.3/cryptograph/aead.rb +1 -1
- data/lib/tttls1.3/error.rb +1 -1
- data/lib/tttls1.3/hpke.rb +91 -0
- data/lib/tttls1.3/key_schedule.rb +111 -8
- data/lib/tttls1.3/message/alert.rb +2 -1
- data/lib/tttls1.3/message/client_hello.rb +2 -1
- data/lib/tttls1.3/message/encrypted_extensions.rb +2 -1
- data/lib/tttls1.3/message/extension/alpn.rb +4 -5
- data/lib/tttls1.3/message/extension/compress_certificate.rb +1 -1
- data/lib/tttls1.3/message/extension/ech.rb +241 -0
- data/lib/tttls1.3/message/extension/key_share.rb +2 -4
- data/lib/tttls1.3/message/extension/server_name.rb +1 -1
- data/lib/tttls1.3/message/extensions.rb +20 -7
- data/lib/tttls1.3/message/record.rb +1 -1
- data/lib/tttls1.3/message/server_hello.rb +3 -5
- data/lib/tttls1.3/message.rb +3 -1
- data/lib/tttls1.3/named_group.rb +1 -1
- data/lib/tttls1.3/server.rb +2 -2
- data/lib/tttls1.3/utils.rb +8 -0
- data/lib/tttls1.3/version.rb +1 -1
- data/lib/tttls1.3.rb +4 -0
- data/spec/client_spec.rb +40 -0
- data/spec/connection_spec.rb +22 -7
- data/spec/ech_spec.rb +81 -0
- data/spec/extensions_spec.rb +1 -2
- data/spec/key_schedule_spec.rb +2 -2
- data/spec/server_spec.rb +22 -7
- data/spec/spec_helper.rb +41 -5
- data/tttls1.3.gemspec +2 -0
- metadata +39 -3
@@ -7,6 +7,7 @@ Dir[File.dirname(__FILE__) + '/extension/*.rb'].sort.each { |f| require f }
|
|
7
7
|
module TTTLS13
|
8
8
|
using Refinements
|
9
9
|
module Message
|
10
|
+
# rubocop: disable Metrics/ClassLength
|
10
11
|
class Extensions < Hash
|
11
12
|
# @param extensions [Array of TTTLS13::Message::Extension::$Object]
|
12
13
|
#
|
@@ -119,6 +120,7 @@ module TTTLS13
|
|
119
120
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
120
121
|
#
|
121
122
|
# @return [TTTLS13::Message::Extension::$Object, nil]
|
123
|
+
# rubocop: disable Metrics/AbcSize
|
122
124
|
# rubocop: disable Metrics/CyclomaticComplexity
|
123
125
|
# rubocop: disable Metrics/MethodLength
|
124
126
|
# rubocop: disable Metrics/PerceivedComplexity
|
@@ -130,14 +132,12 @@ module TTTLS13
|
|
130
132
|
Extension::ServerName.deserialize(binary)
|
131
133
|
when ExtensionType::STATUS_REQUEST
|
132
134
|
if msg_type == HandshakeType::CLIENT_HELLO
|
133
|
-
|
135
|
+
Extension::OCSPStatusRequest.deserialize(binary)
|
136
|
+
elsif msg_type == HandshakeType::CERTIFICATE
|
137
|
+
Extension::OCSPResponse.deserialize(binary)
|
138
|
+
else
|
139
|
+
Extension::UnknownExtension.deserialize(binary, extension_type)
|
134
140
|
end
|
135
|
-
|
136
|
-
if msg_type == HandshakeType::CERTIFICATE
|
137
|
-
return Extension::OCSPResponse.deserialize(binary)
|
138
|
-
end
|
139
|
-
|
140
|
-
Extension::UnknownExtension.deserialize(binary, extension_type)
|
141
141
|
when ExtensionType::SUPPORTED_GROUPS
|
142
142
|
Extension::SupportedGroups.deserialize(binary)
|
143
143
|
when ExtensionType::SIGNATURE_ALGORITHMS
|
@@ -162,14 +162,27 @@ module TTTLS13
|
|
162
162
|
Extension::SignatureAlgorithmsCert.deserialize(binary)
|
163
163
|
when ExtensionType::KEY_SHARE
|
164
164
|
Extension::KeyShare.deserialize(binary, msg_type)
|
165
|
+
when ExtensionType::ENCRYPTED_CLIENT_HELLO
|
166
|
+
case msg_type
|
167
|
+
when HandshakeType::CLIENT_HELLO
|
168
|
+
Extension::ECHClientHello.deserialize(binary)
|
169
|
+
when HandshakeType::ENCRYPTED_EXTENSIONS
|
170
|
+
Extension::ECHEncryptedExtensions.deserialize(binary)
|
171
|
+
when HandshakeType::HELLO_RETRY_REQUEST
|
172
|
+
Extension::ECHHelloRetryRequest.deserialize(binary)
|
173
|
+
else
|
174
|
+
Extension::UnknownExtension.deserialize(binary, extension_type)
|
175
|
+
end
|
165
176
|
else
|
166
177
|
Extension::UnknownExtension.deserialize(binary, extension_type)
|
167
178
|
end
|
168
179
|
end
|
180
|
+
# rubocop: enable Metrics/AbcSize
|
169
181
|
# rubocop: enable Metrics/CyclomaticComplexity
|
170
182
|
# rubocop: enable Metrics/MethodLength
|
171
183
|
# rubocop: enable Metrics/PerceivedComplexity
|
172
184
|
end
|
173
185
|
end
|
186
|
+
# rubocop: enable Metrics/ClassLength
|
174
187
|
end
|
175
188
|
end
|
@@ -17,7 +17,8 @@ module TTTLS13
|
|
17
17
|
ExtensionType::COOKIE,
|
18
18
|
ExtensionType::PASSWORD_SALT,
|
19
19
|
ExtensionType::SUPPORTED_VERSIONS,
|
20
|
-
ExtensionType::KEY_SHARE
|
20
|
+
ExtensionType::KEY_SHARE,
|
21
|
+
ExtensionType::ENCRYPTED_CLIENT_HELLO
|
21
22
|
].freeze
|
22
23
|
private_constant :APPEARABLE_HRR_EXTENSIONS
|
23
24
|
|
@@ -61,7 +62,6 @@ module TTTLS13
|
|
61
62
|
@cipher_suite = cipher_suite
|
62
63
|
@legacy_compression_method = legacy_compression_method
|
63
64
|
@extensions = extensions
|
64
|
-
@hrr = (random == HRR_RANDOM)
|
65
65
|
end
|
66
66
|
# rubocop: enable Metrics/ParameterLists
|
67
67
|
|
@@ -108,10 +108,8 @@ module TTTLS13
|
|
108
108
|
exs_bin = binary.slice(i, exs_len)
|
109
109
|
if random == HRR_RANDOM
|
110
110
|
msg_type = HandshakeType::HELLO_RETRY_REQUEST
|
111
|
-
@hrr = true
|
112
111
|
else
|
113
112
|
msg_type = HandshakeType::SERVER_HELLO
|
114
|
-
@hrr = false
|
115
113
|
end
|
116
114
|
extensions = Extensions.deserialize(exs_bin, msg_type)
|
117
115
|
i += exs_len
|
@@ -132,7 +130,7 @@ module TTTLS13
|
|
132
130
|
|
133
131
|
# @return [Boolean]
|
134
132
|
def hrr?
|
135
|
-
@
|
133
|
+
@random == HRR_RANDOM
|
136
134
|
end
|
137
135
|
|
138
136
|
# @return [Boolean]
|
data/lib/tttls1.3/message.rb
CHANGED
@@ -27,7 +27,7 @@ module TTTLS13
|
|
27
27
|
HELLO_VERIFY_REQUEST = "\x03" # RESERVED
|
28
28
|
NEW_SESSION_TICKET = "\x04"
|
29
29
|
END_OF_EARLY_DATA = "\x05"
|
30
|
-
HELLO_RETRY_REQUEST = "\x06"
|
30
|
+
HELLO_RETRY_REQUEST = "\x06"
|
31
31
|
ENCRYPTED_EXTENSIONS = "\x08"
|
32
32
|
CERTIFICATE = "\x0b"
|
33
33
|
SERVER_KEY_EXCHANGE = "\x0c" # RESERVED
|
@@ -72,6 +72,8 @@ module TTTLS13
|
|
72
72
|
POST_HANDSHAKE_AUTH = "\x00\x31"
|
73
73
|
SIGNATURE_ALGORITHMS_CERT = "\x00\x32"
|
74
74
|
KEY_SHARE = "\x00\x33"
|
75
|
+
# https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-17#section-11.1
|
76
|
+
ENCRYPTED_CLIENT_HELLO = "\xfe\x0d"
|
75
77
|
end
|
76
78
|
|
77
79
|
DEFINED_EXTENSIONS = ExtensionType.constants.map do |c|
|
data/lib/tttls1.3/named_group.rb
CHANGED
@@ -64,7 +64,7 @@ module TTTLS13
|
|
64
64
|
# secp384r1 | | NIST P-384
|
65
65
|
# secp521r1 | | NIST P-521
|
66
66
|
#
|
67
|
-
# https://
|
67
|
+
# https://datatracker.ietf.org/doc/html/rfc4492#appendix-A
|
68
68
|
#
|
69
69
|
# @param groups [Array of TTTLS13::Message::Extension::NamedGroup]
|
70
70
|
#
|
data/lib/tttls1.3/server.rb
CHANGED
@@ -136,7 +136,7 @@ module TTTLS13
|
|
136
136
|
# v
|
137
137
|
# CONNECTED
|
138
138
|
#
|
139
|
-
# https://
|
139
|
+
# https://datatracker.ietf.org/doc/html/rfc8446#appendix-A.2
|
140
140
|
#
|
141
141
|
# rubocop: disable Metrics/AbcSize
|
142
142
|
# rubocop: disable Metrics/BlockLength
|
@@ -323,7 +323,7 @@ module TTTLS13
|
|
323
323
|
transcript[CH].first.random,
|
324
324
|
key_schedule.client_application_traffic_secret
|
325
325
|
)
|
326
|
-
@
|
326
|
+
@exporter_secret = key_schedule.exporter_secret
|
327
327
|
@state = ServerState::CONNECTED
|
328
328
|
when ServerState::CONNECTED
|
329
329
|
logger.debug('ServerState::CONNECTED')
|
data/lib/tttls1.3/utils.rb
CHANGED
data/lib/tttls1.3/version.rb
CHANGED
data/lib/tttls1.3.rb
CHANGED
@@ -5,6 +5,9 @@ require 'net/http'
|
|
5
5
|
require 'pp'
|
6
6
|
require 'logger'
|
7
7
|
|
8
|
+
require 'ech_config'
|
9
|
+
require 'hpke'
|
10
|
+
|
8
11
|
require 'tttls1.3/version'
|
9
12
|
require 'tttls1.3/utils'
|
10
13
|
require 'tttls1.3/logging'
|
@@ -18,6 +21,7 @@ require 'tttls1.3/key_schedule'
|
|
18
21
|
require 'tttls1.3/message'
|
19
22
|
require 'tttls1.3/sequence_number'
|
20
23
|
require 'tttls1.3/sslkeylogfile'
|
24
|
+
require 'tttls1.3/hpke'
|
21
25
|
require 'tttls1.3/connection'
|
22
26
|
require 'tttls1.3/client'
|
23
27
|
require 'tttls1.3/server'
|
data/spec/client_spec.rb
CHANGED
@@ -270,4 +270,44 @@ RSpec.describe Client do
|
|
270
270
|
'SHA256')).to eq TESTBINARY_0_RTT_PSK
|
271
271
|
end
|
272
272
|
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
|
273
313
|
end
|
data/spec/connection_spec.rb
CHANGED
@@ -6,13 +6,28 @@ require_relative 'spec_helper'
|
|
6
6
|
RSpec.describe Connection do
|
7
7
|
context 'connection, Simple 1-RTT Handshake,' do
|
8
8
|
let(:key) do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
n = OpenSSL::BN.new(TESTBINARY_PKEY_MODULUS, 2)
|
10
|
+
e = OpenSSL::BN.new(TESTBINARY_PKEY_PUBLIC_EXPONENT, 2)
|
11
|
+
d = OpenSSL::BN.new(TESTBINARY_PKEY_PRIVATE_EXPONENT, 2)
|
12
|
+
p = OpenSSL::BN.new(TESTBINARY_PKEY_PRIME1, 2)
|
13
|
+
q = OpenSSL::BN.new(TESTBINARY_PKEY_PRIME2, 2)
|
14
|
+
dmp1 = d % (p - 1.to_bn)
|
15
|
+
dmq1 = d % (q - 1.to_bn)
|
16
|
+
iqmp = q**-1.to_bn % p
|
17
|
+
asn1 = OpenSSL::ASN1::Sequence(
|
18
|
+
[
|
19
|
+
OpenSSL::ASN1::Integer(0),
|
20
|
+
OpenSSL::ASN1::Integer(n),
|
21
|
+
OpenSSL::ASN1::Integer(e),
|
22
|
+
OpenSSL::ASN1::Integer(d),
|
23
|
+
OpenSSL::ASN1::Integer(p),
|
24
|
+
OpenSSL::ASN1::Integer(q),
|
25
|
+
OpenSSL::ASN1::Integer(dmp1),
|
26
|
+
OpenSSL::ASN1::Integer(dmq1),
|
27
|
+
OpenSSL::ASN1::Integer(iqmp)
|
28
|
+
]
|
29
|
+
)
|
30
|
+
OpenSSL::PKey::RSA.new(asn1)
|
16
31
|
end
|
17
32
|
|
18
33
|
let(:ct) do
|
data/spec/ech_spec.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe ECHClientHello do
|
8
|
+
context 'valid ECHClientHello outer binary' do
|
9
|
+
let(:extension) do
|
10
|
+
ECHClientHello.deserialize(TESTBINARY_ECH_OUTER)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should generate valid object' do
|
14
|
+
expect(extension.extension_type)
|
15
|
+
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO
|
16
|
+
expect(extension.type).to eq ECHClientHelloType::OUTER
|
17
|
+
expect(extension.cipher_suite.kdf_id.uint16).to eq 1
|
18
|
+
expect(extension.cipher_suite.aead_id.uint16).to eq 1
|
19
|
+
expect(extension.config_id).to eq 32
|
20
|
+
expect(extension.enc.length).to eq 32
|
21
|
+
expect(extension.payload.length).to eq 239
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should be serialized' do
|
25
|
+
expect(extension.serialize)
|
26
|
+
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO \
|
27
|
+
+ 281.to_uint16 \
|
28
|
+
+ ECHClientHelloType::OUTER \
|
29
|
+
+ 1.to_uint16 \
|
30
|
+
+ 1.to_uint16 \
|
31
|
+
+ 32.to_uint8 \
|
32
|
+
+ extension.enc.prefix_uint16_length \
|
33
|
+
+ extension.payload.prefix_uint16_length
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'valid ECHClientHello inner binary' do
|
38
|
+
let(:extension) do
|
39
|
+
ECHClientHello.deserialize(TESTBINARY_ECH_INNER)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should generate valid object' do
|
43
|
+
expect(extension.extension_type)
|
44
|
+
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO
|
45
|
+
expect(extension.type).to eq ECHClientHelloType::INNER
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should be serialized' do
|
49
|
+
expect(extension.serialize)
|
50
|
+
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO \
|
51
|
+
+ 1.to_uint16 \
|
52
|
+
+ ECHClientHelloType::INNER \
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'valid ECHEncryptedExtensions binary' do
|
57
|
+
let(:extension) do
|
58
|
+
ECHEncryptedExtensions.deserialize(TESTBINARY_ECH_EE)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should generate valid object' do
|
62
|
+
expect(extension.extension_type)
|
63
|
+
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO
|
64
|
+
expect(extension.retry_configs.is_a?(Array)).to be_truthy
|
65
|
+
expect(extension.retry_configs.length).to eq 1
|
66
|
+
expect(extension.retry_configs.first.is_a?(ECHConfig)).to be_truthy
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'valid ECHHelloRetryRequest binary' do
|
71
|
+
let(:extension) do
|
72
|
+
ECHHelloRetryRequest.deserialize(TESTBINARY_ECH_HRR)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should generate valid object' do
|
76
|
+
expect(extension.extension_type)
|
77
|
+
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO
|
78
|
+
expect(extension.confirmation).to eq "\x00" * 8
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/spec/extensions_spec.rb
CHANGED
data/spec/key_schedule_spec.rb
CHANGED
@@ -37,9 +37,9 @@ RSpec.describe KeySchedule do
|
|
37
37
|
.to eq TESTBINARY_C_AP_TRAFFIC
|
38
38
|
expect(key_schedule.server_application_traffic_secret)
|
39
39
|
.to eq TESTBINARY_S_AP_TRAFFIC
|
40
|
-
expect(key_schedule.
|
40
|
+
expect(key_schedule.exporter_secret)
|
41
41
|
.to eq TESTBINARY_EXP_MASTER
|
42
|
-
expect(key_schedule.
|
42
|
+
expect(key_schedule.resumption_secret)
|
43
43
|
.to eq TESTBINARY_RES_MASTER
|
44
44
|
end
|
45
45
|
|
data/spec/server_spec.rb
CHANGED
@@ -109,13 +109,28 @@ RSpec.describe Server do
|
|
109
109
|
|
110
110
|
context 'server' do
|
111
111
|
let(:key) do
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
112
|
+
n = OpenSSL::BN.new(TESTBINARY_PKEY_MODULUS, 2)
|
113
|
+
e = OpenSSL::BN.new(TESTBINARY_PKEY_PUBLIC_EXPONENT, 2)
|
114
|
+
d = OpenSSL::BN.new(TESTBINARY_PKEY_PRIVATE_EXPONENT, 2)
|
115
|
+
p = OpenSSL::BN.new(TESTBINARY_PKEY_PRIME1, 2)
|
116
|
+
q = OpenSSL::BN.new(TESTBINARY_PKEY_PRIME2, 2)
|
117
|
+
dmp1 = d % (p - 1.to_bn)
|
118
|
+
dmq1 = d % (q - 1.to_bn)
|
119
|
+
iqmp = q**-1.to_bn % p
|
120
|
+
asn1 = OpenSSL::ASN1::Sequence(
|
121
|
+
[
|
122
|
+
OpenSSL::ASN1::Integer(0),
|
123
|
+
OpenSSL::ASN1::Integer(n),
|
124
|
+
OpenSSL::ASN1::Integer(e),
|
125
|
+
OpenSSL::ASN1::Integer(d),
|
126
|
+
OpenSSL::ASN1::Integer(p),
|
127
|
+
OpenSSL::ASN1::Integer(q),
|
128
|
+
OpenSSL::ASN1::Integer(dmp1),
|
129
|
+
OpenSSL::ASN1::Integer(dmq1),
|
130
|
+
OpenSSL::ASN1::Integer(iqmp)
|
131
|
+
]
|
132
|
+
)
|
133
|
+
OpenSSL::PKey::RSA.new(asn1)
|
119
134
|
end
|
120
135
|
|
121
136
|
let(:ct) do
|
data/spec/spec_helper.rb
CHANGED
@@ -167,7 +167,7 @@ TESTBINARY_COMPRESS_CERTIFICATE = <<BIN.split.map(&:hex).map(&:chr).join
|
|
167
167
|
02 00 01
|
168
168
|
BIN
|
169
169
|
|
170
|
-
# https://
|
170
|
+
# https://datatracker.ietf.org/doc/html/rfc8448#section-3
|
171
171
|
# 2. Private Keys
|
172
172
|
TESTBINARY_PKEY_MODULUS = <<BIN.split.map(&:hex).map(&:chr).join
|
173
173
|
b4 bb 49 8f 82 79 30 3d 98 08 36 39 9b 36 c6 98
|
@@ -209,7 +209,43 @@ TESTBINARY_PKEY_PRIVATE_EXPONENT = <<BIN.split.map(&:hex).map(&:chr).join
|
|
209
209
|
c3 08 8d f2 5a e6 79 23 3d f8 a3 bd a2 ff 99 41
|
210
210
|
BIN
|
211
211
|
|
212
|
-
|
212
|
+
TESTBINARY_ECH_OUTER = <<BIN.split.map(&:hex).map(&:chr).join
|
213
|
+
00 00 01 00 01 20 00 20 00 01 02 03 04 05 06 07
|
214
|
+
08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17
|
215
|
+
18 19 1a 1b 1c 1d 1e 1f 00 ef 00 01 02 03 04 05
|
216
|
+
06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15
|
217
|
+
16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25
|
218
|
+
26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35
|
219
|
+
36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45
|
220
|
+
46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55
|
221
|
+
56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65
|
222
|
+
66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75
|
223
|
+
76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85
|
224
|
+
86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95
|
225
|
+
96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5
|
226
|
+
a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5
|
227
|
+
b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5
|
228
|
+
c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5
|
229
|
+
d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5
|
230
|
+
e6 e7 e8 e9 ea eb ec ed ee
|
231
|
+
BIN
|
232
|
+
|
233
|
+
TESTBINARY_ECH_INNER = <<BIN.split.map(&:hex).map(&:chr).join
|
234
|
+
01
|
235
|
+
BIN
|
236
|
+
|
237
|
+
TESTBINARY_ECH_EE = <<BIN.split.map(&:hex).map(&:chr).join
|
238
|
+
00 3a fe 0d 00 36 00 00 20 00 1e 00 00 00 00 00
|
239
|
+
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
240
|
+
00 00 00 00 00 00 00 00 00 00 04 00 01 00 01 00
|
241
|
+
09 6c 6f 63 61 6c 68 6f 73 74 00 00
|
242
|
+
BIN
|
243
|
+
|
244
|
+
TESTBINARY_ECH_HRR = <<BIN.split.map(&:hex).map(&:chr).join
|
245
|
+
00 00 00 00 00 00 00 00
|
246
|
+
BIN
|
247
|
+
|
248
|
+
# https://datatracker.ietf.org/doc/html/rfc8448#section-3
|
213
249
|
# 3. Simple 1-RTT Handshake
|
214
250
|
TESTBINARY_CLIENT_HELLO = <<BIN.split.map(&:hex).map(&:chr).join
|
215
251
|
01 00 00 c0 03 03 cb 34 ec b1 e7 81 63 ba 1c 38
|
@@ -517,7 +553,7 @@ TESTBINARY_CH_CF_TRANSCRIPT_HASH = <<BIN.split.map(&:hex).map(&:chr).join
|
|
517
553
|
84 65 8d 60 49 e8 64 29 42 6d b8 7c 54 ad 14 3d
|
518
554
|
BIN
|
519
555
|
|
520
|
-
# https://
|
556
|
+
# https://datatracker.ietf.org/doc/html/rfc8448#section-4
|
521
557
|
# 4. Resumed 0-RTT Handshake
|
522
558
|
TESTBINARY_0_RTT_CLIENT_HELLO = <<BIN.split.map(&:hex).map(&:chr).join
|
523
559
|
01 00 01 fc 03 03 1b c3 ce b6 bb e3 9c ff 93 83
|
@@ -642,7 +678,7 @@ BIN
|
|
642
678
|
TESTBINARY_0_RTT_CLIENT_APPLICATION_WRITE_IV \
|
643
679
|
= testbinary.split.map(&:hex).map(&:chr).join
|
644
680
|
|
645
|
-
# https://
|
681
|
+
# https://datatracker.ietf.org/doc/html/rfc8448#section-5
|
646
682
|
# 5. HelloRetryRequest
|
647
683
|
TESTBINARY_HRR_CLIENT_HELLO1 = <<BIN.split.map(&:hex).map(&:chr).join
|
648
684
|
01 00 00 b0 03 03 b0 b1 c5 a5 aa 37 c5 91 9f 2e
|
@@ -939,7 +975,7 @@ TESTBINARY_HRR_CH1_CF_TRANSCRIPT_HASH = <<BIN.split.map(&:hex).map(&:chr).join
|
|
939
975
|
3c aa 6e 48 3c 6c 65 df 53 15 18 88 e5 01 65 f4
|
940
976
|
BIN
|
941
977
|
|
942
|
-
# https://
|
978
|
+
# https://datatracker.ietf.org/doc/html/rfc8448#section-7
|
943
979
|
# 7. Compatibility Mode
|
944
980
|
TESTBINARY_RECORD_CCS = <<BIN.split.map(&:hex).map(&:chr).join
|
945
981
|
14 03 03 00 01 01
|
data/tttls1.3.gemspec
CHANGED
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
|
22
22
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
23
|
+
spec.add_dependency 'ech_config', '~> 0.0.3'
|
24
|
+
spec.add_dependency 'hpke'
|
23
25
|
spec.add_dependency 'logger'
|
24
26
|
spec.add_dependency 'openssl'
|
25
27
|
end
|
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.
|
4
|
+
version: 0.3.0
|
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: 2023-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ech_config
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.3
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.0.3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: hpke
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: logger
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +100,18 @@ files:
|
|
72
100
|
- example/helper.rb
|
73
101
|
- example/https_client.rb
|
74
102
|
- example/https_client_using_0rtt.rb
|
103
|
+
- example/https_client_using_ech.rb
|
104
|
+
- example/https_client_using_grease_ech.rb
|
105
|
+
- example/https_client_using_grease_psk.rb
|
75
106
|
- example/https_client_using_hrr.rb
|
107
|
+
- example/https_client_using_hrr_and_ech.rb
|
76
108
|
- example/https_client_using_hrr_and_ticket.rb
|
77
109
|
- example/https_client_using_status_request.rb
|
78
110
|
- example/https_client_using_ticket.rb
|
79
111
|
- example/https_server.rb
|
80
112
|
- interop/client_spec.rb
|
81
|
-
- interop/helper.rb
|
82
113
|
- interop/server_spec.rb
|
114
|
+
- interop/spec_helper.rb
|
83
115
|
- lib/tttls1.3.rb
|
84
116
|
- lib/tttls1.3/cipher_suites.rb
|
85
117
|
- lib/tttls1.3/client.rb
|
@@ -88,6 +120,7 @@ files:
|
|
88
120
|
- lib/tttls1.3/cryptograph/aead.rb
|
89
121
|
- lib/tttls1.3/cryptograph/passer.rb
|
90
122
|
- lib/tttls1.3/error.rb
|
123
|
+
- lib/tttls1.3/hpke.rb
|
91
124
|
- lib/tttls1.3/key_schedule.rb
|
92
125
|
- lib/tttls1.3/logging.rb
|
93
126
|
- lib/tttls1.3/message.rb
|
@@ -104,6 +137,7 @@ files:
|
|
104
137
|
- lib/tttls1.3/message/extension/compress_certificate.rb
|
105
138
|
- lib/tttls1.3/message/extension/cookie.rb
|
106
139
|
- lib/tttls1.3/message/extension/early_data_indication.rb
|
140
|
+
- lib/tttls1.3/message/extension/ech.rb
|
107
141
|
- lib/tttls1.3/message/extension/key_share.rb
|
108
142
|
- lib/tttls1.3/message/extension/pre_shared_key.rb
|
109
143
|
- lib/tttls1.3/message/extension/psk_key_exchange_modes.rb
|
@@ -142,6 +176,7 @@ files:
|
|
142
176
|
- spec/connection_spec.rb
|
143
177
|
- spec/cookie_spec.rb
|
144
178
|
- spec/early_data_indication_spec.rb
|
179
|
+
- spec/ech_spec.rb
|
145
180
|
- spec/encrypted_extensions_spec.rb
|
146
181
|
- spec/end_of_early_data_spec.rb
|
147
182
|
- spec/error_spec.rb
|
@@ -219,6 +254,7 @@ test_files:
|
|
219
254
|
- spec/connection_spec.rb
|
220
255
|
- spec/cookie_spec.rb
|
221
256
|
- spec/early_data_indication_spec.rb
|
257
|
+
- spec/ech_spec.rb
|
222
258
|
- spec/encrypted_extensions_spec.rb
|
223
259
|
- spec/end_of_early_data_spec.rb
|
224
260
|
- spec/error_spec.rb
|