tttls1.3 0.3.3 → 0.3.4
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/Gemfile +2 -1
- data/example/helper.rb +13 -4
- data/lib/tttls1.3/client.rb +3 -5
- data/lib/tttls1.3/cryptograph/aead.rb +0 -5
- data/lib/tttls1.3/ech.rb +2 -2
- data/lib/tttls1.3/key_schedule.rb +1 -1
- data/lib/tttls1.3/message/application_data.rb +1 -1
- data/lib/tttls1.3/message/client_hello.rb +8 -0
- data/lib/tttls1.3/message/extension/alpn.rb +1 -1
- data/lib/tttls1.3/message/extension/ech.rb +0 -3
- data/lib/tttls1.3/message/extension/ech_outer_extensions.rb +0 -1
- data/lib/tttls1.3/message/extension/key_share.rb +3 -6
- data/lib/tttls1.3/message/extension/pre_shared_key.rb +0 -3
- data/lib/tttls1.3/message/extension/server_name.rb +0 -1
- data/lib/tttls1.3/message/extension/signature_algorithms_cert.rb +1 -1
- data/lib/tttls1.3/message/extension/unknown_extension.rb +0 -1
- data/lib/tttls1.3/message/extensions.rb +0 -2
- data/lib/tttls1.3/message/record.rb +0 -2
- data/lib/tttls1.3/named_group.rb +1 -3
- data/lib/tttls1.3/server.rb +0 -1
- data/lib/tttls1.3/version.rb +1 -1
- data/spec/client_hello_spec.rb +19 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0913f70f0bdbfd6740f41ce7902f55660ea1bd99533a8f765f9d98a1bd56a58c'
|
4
|
+
data.tar.gz: 611a063ae74498d19636ebf3ee3741b76164856341bb38ec9966a999579bdfb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88f39003d30f4642c67a61169923fe248bc572b4a1c638eb36803dc4278aa91a499919784cd060fa35c522bcb935745d1b4542abb1963514aba1f86f1ea789fd
|
7
|
+
data.tar.gz: cd2ae8cd383cd9737a732d53c8ca27cbacdcd3c4a5b6bee62f5f43faba4fd8eb8067b0621df18d8b77db679823c3aa26947508fe5827939bf6741e6f417a1d80
|
data/Gemfile
CHANGED
data/example/helper.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
$LOAD_PATH << __dir__ + '/../lib'
|
4
4
|
|
5
|
+
require 'base64'
|
6
|
+
require 'resolv'
|
5
7
|
require 'socket'
|
6
8
|
require 'time'
|
7
9
|
require 'uri'
|
@@ -9,7 +11,6 @@ require 'webrick'
|
|
9
11
|
|
10
12
|
require 'ech_config'
|
11
13
|
require 'http/parser'
|
12
|
-
require 'svcb_rr_patch'
|
13
14
|
|
14
15
|
require 'tttls1.3'
|
15
16
|
|
@@ -86,7 +87,8 @@ def transcript_htmlize(transcript)
|
|
86
87
|
end
|
87
88
|
|
88
89
|
def parse_echconfigs_pem(pem)
|
89
|
-
|
90
|
+
# https://datatracker.ietf.org/doc/html/draft-farrell-tls-pemesni-08#section-3-4
|
91
|
+
s = pem.gsub(/-----(BEGIN|END) (ECH CONFIGS|ECHCONFIG)-----/, '')
|
90
92
|
.gsub("\n", '')
|
91
93
|
b = Base64.decode64(s)
|
92
94
|
raise 'failed to parse ECHConfigs' \
|
@@ -100,8 +102,15 @@ def resolve_echconfig(hostname)
|
|
100
102
|
hostname,
|
101
103
|
Resolv::DNS::Resource::IN::HTTPS
|
102
104
|
)
|
105
|
+
|
106
|
+
# https://datatracker.ietf.org/doc/html/draft-ietf-tls-svcb-ech-01#section-6
|
107
|
+
ech = 5
|
103
108
|
raise "failed to resolve echconfig via #{hostname} HTTPS RR" \
|
104
|
-
if rr.first.nil? ||
|
109
|
+
if rr.first.nil? || rr.first.params[ech].nil?
|
110
|
+
|
111
|
+
octet = rr.first.params[ech].value
|
112
|
+
raise 'failed to parse ECHConfigs' \
|
113
|
+
unless octet.length == octet.slice(0, 2).unpack1('n') + 2
|
105
114
|
|
106
|
-
|
115
|
+
ECHConfig.decode_vectors(octet.slice(2..)).first
|
107
116
|
end
|
data/lib/tttls1.3/client.rb
CHANGED
@@ -89,8 +89,8 @@ module TTTLS13
|
|
89
89
|
class Client
|
90
90
|
include Logging
|
91
91
|
|
92
|
-
HpkeSymmetricCipherSuit
|
93
|
-
ECHConfig::ECHConfigContents::HpkeKeyConfig::HpkeSymmetricCipherSuite
|
92
|
+
HpkeSymmetricCipherSuit \
|
93
|
+
= ECHConfig::ECHConfigContents::HpkeKeyConfig::HpkeSymmetricCipherSuite
|
94
94
|
|
95
95
|
attr_reader :transcript
|
96
96
|
|
@@ -110,7 +110,6 @@ module TTTLS13
|
|
110
110
|
raise Error::ConfigError unless valid_settings?
|
111
111
|
end
|
112
112
|
|
113
|
-
# NOTE:
|
114
113
|
# START <----+
|
115
114
|
# Send ClientHello | | Recv HelloRetryRequest
|
116
115
|
# [K_send = early data] | |
|
@@ -327,7 +326,7 @@ module TTTLS13
|
|
327
326
|
)
|
328
327
|
|
329
328
|
# rejected ECH
|
330
|
-
#
|
329
|
+
# It can compute (hrr_)accept_ech until client selects the
|
331
330
|
# cipher_suite.
|
332
331
|
if !sh.hrr? && use_ech?
|
333
332
|
if !@transcript.include?(HRR) && !key_schedule.accept_ech?
|
@@ -1008,7 +1007,6 @@ module TTTLS13
|
|
1008
1007
|
[new_exs, priv_keys]
|
1009
1008
|
end
|
1010
1009
|
|
1011
|
-
# NOTE:
|
1012
1010
|
# https://datatracker.ietf.org/doc/html/rfc8446#section-4.1.2
|
1013
1011
|
#
|
1014
1012
|
# @param ch1 [TTTLS13::Message::ClientHello]
|
@@ -23,8 +23,6 @@ module TTTLS13
|
|
23
23
|
when CipherSuite::TLS_CHACHA20_POLY1305_SHA256
|
24
24
|
@cipher = OpenSSL::Cipher.new('chacha20-poly1305')
|
25
25
|
else
|
26
|
-
# Note:
|
27
|
-
# not supported
|
28
26
|
# CipherSuite::TLS_AES_128_CCM_SHA256
|
29
27
|
# CipherSuite::TLS_AES_128_CCM_8_SHA256
|
30
28
|
raise Error::ErrorAlerts, :internal_error
|
@@ -36,7 +34,6 @@ module TTTLS13
|
|
36
34
|
@auth_tag_len = CipherSuite.auth_tag_len(@cipher_suite)
|
37
35
|
end
|
38
36
|
|
39
|
-
# NOTE:
|
40
37
|
# AEAD-Encrypt(write_key, nonce, additional_data, plaintext)
|
41
38
|
#
|
42
39
|
# @param content [String]
|
@@ -53,7 +50,6 @@ module TTTLS13
|
|
53
50
|
encrypted_data + cipher.auth_tag
|
54
51
|
end
|
55
52
|
|
56
|
-
# NOTE:
|
57
53
|
# AEAD-Decrypt(peer_write_key, nonce,
|
58
54
|
# additional_data, AEADEncrypted)
|
59
55
|
#
|
@@ -78,7 +74,6 @@ module TTTLS13
|
|
78
74
|
[clear[0...-postfix_len], clear[-postfix_len]]
|
79
75
|
end
|
80
76
|
|
81
|
-
# NOTE:
|
82
77
|
# struct {
|
83
78
|
# opaque content[TLSPlaintext.length];
|
84
79
|
# ContentType type;
|
data/lib/tttls1.3/ech.rb
CHANGED
@@ -19,7 +19,7 @@ module TTTLS13
|
|
19
19
|
# @param hpke_cipher_suite_selector [Method]
|
20
20
|
#
|
21
21
|
# @return [TTTLS13::Message::ClientHello]
|
22
|
-
# @return [TTTLS13::Message::ClientHello]
|
22
|
+
# @return [TTTLS13::Message::ClientHello] ClientHelloInner
|
23
23
|
# @return [TTTLS13::EchState]
|
24
24
|
# rubocop: disable Metrics/AbcSize
|
25
25
|
def self.offer_ech(inner, ech_config, hpke_cipher_suite_selector)
|
@@ -110,7 +110,7 @@ module TTTLS13
|
|
110
110
|
# @param ech_state [TTTLS13::EchState]
|
111
111
|
#
|
112
112
|
# @return [TTTLS13::Message::ClientHello]
|
113
|
-
# @return [TTTLS13::Message::ClientHello]
|
113
|
+
# @return [TTTLS13::Message::ClientHello] ClientHelloInner
|
114
114
|
def self.offer_new_ech(inner, ech_state)
|
115
115
|
# for ech_outer_extensions
|
116
116
|
replaced = \
|
@@ -250,7 +250,7 @@ module TTTLS13
|
|
250
250
|
#
|
251
251
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
252
252
|
#
|
253
|
-
# @
|
253
|
+
# @return [String]
|
254
254
|
def self.hkdf_expand(secret, info, length, digest)
|
255
255
|
hash_len = OpenSSL::Digest.new(digest).digest_length
|
256
256
|
raise Error::ErrorAlerts, :internal_error if length > 255 * hash_len
|
@@ -160,6 +160,14 @@ module TTTLS13
|
|
160
160
|
sg_groups.filter { |g| ks_groups.include?(g) } == ks_groups &&
|
161
161
|
ks_groups.uniq == ks_groups
|
162
162
|
end
|
163
|
+
|
164
|
+
# @return [Boolean]
|
165
|
+
def ch_inner?
|
166
|
+
ech = @extensions[Message::ExtensionType::ENCRYPTED_CLIENT_HELLO]
|
167
|
+
return false if ech.nil?
|
168
|
+
|
169
|
+
ech.type == Message::Extension::ECHClientHelloType::INNER
|
170
|
+
end
|
163
171
|
end
|
164
172
|
end
|
165
173
|
end
|
@@ -12,7 +12,6 @@ module TTTLS13
|
|
12
12
|
INNER = "\x01"
|
13
13
|
end
|
14
14
|
|
15
|
-
# NOTE:
|
16
15
|
# struct {
|
17
16
|
# ECHClientHelloType type;
|
18
17
|
# select (ECHClientHello.type) {
|
@@ -165,7 +164,6 @@ module TTTLS13
|
|
165
164
|
end
|
166
165
|
end
|
167
166
|
|
168
|
-
# NOTE:
|
169
167
|
# struct {
|
170
168
|
# ECHConfigList retry_configs;
|
171
169
|
# } ECHEncryptedExtensions;
|
@@ -202,7 +200,6 @@ module TTTLS13
|
|
202
200
|
end
|
203
201
|
end
|
204
202
|
|
205
|
-
# NOTE:
|
206
203
|
# struct {
|
207
204
|
# opaque confirmation[8];
|
208
205
|
# } ECHHelloRetryRequest;
|
@@ -11,7 +11,7 @@ module TTTLS13
|
|
11
11
|
attr_reader :msg_type
|
12
12
|
attr_reader :key_share_entry
|
13
13
|
|
14
|
-
# @param msg_type [TTTLS13::Message::
|
14
|
+
# @param msg_type [TTTLS13::Message::HandshakeType]
|
15
15
|
# @param key_share_entry [Array of KeyShareEntry]
|
16
16
|
#
|
17
17
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
@@ -108,7 +108,7 @@ module TTTLS13
|
|
108
108
|
[key_share, priv_keys]
|
109
109
|
end
|
110
110
|
|
111
|
-
# @param
|
111
|
+
# @param group [TTTLS13::NamedGroup]
|
112
112
|
#
|
113
113
|
# @return [TTTLS13::Message::Extensions::KeyShare]
|
114
114
|
# @return [OpenSSL::PKey::EC.$Object]
|
@@ -129,7 +129,7 @@ module TTTLS13
|
|
129
129
|
[key_share, ec]
|
130
130
|
end
|
131
131
|
|
132
|
-
# @param
|
132
|
+
# @param group [TTTLS13::NamedGroup]
|
133
133
|
#
|
134
134
|
# @return [TTTLS13::Message::Extensions::KeyShare]
|
135
135
|
def self.gen_hrr_key_share(group)
|
@@ -143,7 +143,6 @@ module TTTLS13
|
|
143
143
|
class << self
|
144
144
|
private
|
145
145
|
|
146
|
-
# NOTE:
|
147
146
|
# struct {
|
148
147
|
# KeyShareEntry client_shares<0..2^16-1>;
|
149
148
|
# } KeyShareClientHello;
|
@@ -178,7 +177,6 @@ module TTTLS13
|
|
178
177
|
key_share_entry
|
179
178
|
end
|
180
179
|
|
181
|
-
# NOTE:
|
182
180
|
# struct {
|
183
181
|
# KeyShareEntry server_share;
|
184
182
|
# } KeyShareServerHello;
|
@@ -201,7 +199,6 @@ module TTTLS13
|
|
201
199
|
[KeyShareEntry.new(group: group, key_exchange: key_exchange)]
|
202
200
|
end
|
203
201
|
|
204
|
-
# NOTE:
|
205
202
|
# struct {
|
206
203
|
# NamedGroup selected_group;
|
207
204
|
# } KeyShareHelloRetryRequest;
|
@@ -5,7 +5,6 @@ module TTTLS13
|
|
5
5
|
using Refinements
|
6
6
|
module Message
|
7
7
|
module Extension
|
8
|
-
# NOTE:
|
9
8
|
# struct {
|
10
9
|
# select (Handshake.msg_type) {
|
11
10
|
# case client_hello: OfferedPsks;
|
@@ -83,7 +82,6 @@ module TTTLS13
|
|
83
82
|
end
|
84
83
|
end
|
85
84
|
|
86
|
-
# NOTE:
|
87
85
|
# opaque PskBinderEntry<32..255>;
|
88
86
|
#
|
89
87
|
# struct {
|
@@ -172,7 +170,6 @@ module TTTLS13
|
|
172
170
|
# rubocop: enable Metrics/PerceivedComplexity
|
173
171
|
end
|
174
172
|
|
175
|
-
# NOTE:
|
176
173
|
# struct {
|
177
174
|
# opaque identity<1..2^16-1>;
|
178
175
|
# uint32 obfuscated_ticket_age;
|
@@ -5,7 +5,7 @@ module TTTLS13
|
|
5
5
|
module Message
|
6
6
|
module Extension
|
7
7
|
class SignatureAlgorithmsCert < SignatureAlgorithms
|
8
|
-
# @param
|
8
|
+
# @param supported_signature_algorithms [Array] Array of SignatureScheme
|
9
9
|
def initialize(supported_signature_algorithms)
|
10
10
|
super(supported_signature_algorithms)
|
11
11
|
@extension_type = ExtensionType::SIGNATURE_ALGORITHMS_CERT
|
@@ -21,7 +21,6 @@ module TTTLS13
|
|
21
21
|
|
22
22
|
alias super_fetch fetch
|
23
23
|
|
24
|
-
# NOTE:
|
25
24
|
# "pre_shared_key" MUST be the last extension in the ClientHello
|
26
25
|
#
|
27
26
|
# @return [String]
|
@@ -136,7 +135,6 @@ module TTTLS13
|
|
136
135
|
class << self
|
137
136
|
private
|
138
137
|
|
139
|
-
# NOTE:
|
140
138
|
# deserialize_extension ignores unparsable extension.
|
141
139
|
# Received unparsable binary, returns nil, doesn't raise
|
142
140
|
# ErrorAlerts :decode_error.
|
@@ -27,7 +27,6 @@ module TTTLS13
|
|
27
27
|
@cipher = cipher
|
28
28
|
end
|
29
29
|
|
30
|
-
# NOTE:
|
31
30
|
# serialize joins messages.
|
32
31
|
# If serialize is received Server Parameters(EE, CT, CV),
|
33
32
|
# it returns one binary.
|
@@ -50,7 +49,6 @@ module TTTLS13
|
|
50
49
|
end.join
|
51
50
|
end
|
52
51
|
|
53
|
-
# NOTE:
|
54
52
|
# If previous Record has surplus_binary,
|
55
53
|
# surplus_binary should is given to Record.deserialize as buffered.
|
56
54
|
#
|
data/lib/tttls1.3/named_group.rb
CHANGED
@@ -17,7 +17,6 @@ module TTTLS13
|
|
17
17
|
# ecdhe_private_use "\xfe\x00" ~ "\xfe\xff"
|
18
18
|
|
19
19
|
class << self
|
20
|
-
# NOTE:
|
21
20
|
# For secp256r1, secp384r1, and secp521r1
|
22
21
|
#
|
23
22
|
# struct {
|
@@ -57,7 +56,6 @@ module TTTLS13
|
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
60
|
-
# NOTE:
|
61
59
|
# SECG | ANSI X9.62 | NIST
|
62
60
|
# ------------+---------------+-------------
|
63
61
|
# secp256r1 | prime256v1 | NIST P-256
|
@@ -66,7 +64,7 @@ module TTTLS13
|
|
66
64
|
#
|
67
65
|
# https://datatracker.ietf.org/doc/html/rfc4492#appendix-A
|
68
66
|
#
|
69
|
-
# @param
|
67
|
+
# @param group [TTTLS13::Message::Extension::NamedGroup]
|
70
68
|
#
|
71
69
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
72
70
|
#
|
data/lib/tttls1.3/server.rb
CHANGED
data/lib/tttls1.3/version.rb
CHANGED
data/spec/client_hello_spec.rb
CHANGED
@@ -37,6 +37,7 @@ RSpec.describe ClientHello do
|
|
37
37
|
expect(message.legacy_compression_methods).to eq ["\x00"]
|
38
38
|
expect(message.extensions).to be_empty
|
39
39
|
expect(message.negotiated_tls_1_3?).to be false
|
40
|
+
expect(message.ch_inner?).to be false
|
40
41
|
end
|
41
42
|
|
42
43
|
it 'should be serialized' do
|
@@ -83,4 +84,22 @@ RSpec.describe ClientHello do
|
|
83
84
|
expect(message.serialize).to eq TESTBINARY_0_RTT_CLIENT_HELLO
|
84
85
|
end
|
85
86
|
end
|
87
|
+
|
88
|
+
context 'valid inner client_hello' do
|
89
|
+
let(:message) do
|
90
|
+
cipher_suites = CipherSuites.new([TLS_AES_256_GCM_SHA384,
|
91
|
+
TLS_CHACHA20_POLY1305_SHA256,
|
92
|
+
TLS_AES_128_GCM_SHA256])
|
93
|
+
ch = ClientHello.new(random: OpenSSL::Random.random_bytes(32),
|
94
|
+
legacy_session_id: Array.new(32, 0).map(&:chr).join,
|
95
|
+
cipher_suites: cipher_suites)
|
96
|
+
ch.extensions[Message::ExtensionType::ENCRYPTED_CLIENT_HELLO] \
|
97
|
+
= Message::Extension::ECHClientHello.new_inner
|
98
|
+
ch
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should generate ClientHelloInner' do
|
102
|
+
expect(message.ch_inner?).to be true
|
103
|
+
end
|
104
|
+
end
|
86
105
|
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.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thekuwayama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|