tttls1.3 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa5d7f448e0c984d75be22a995278853b4d4b0c505aaaa92fc5e99f48371fc82
4
- data.tar.gz: 4a0d95465cabfd048ea1d7190c1c617dcc26a5395e06f7acc0173fcbbfe0bd04
3
+ metadata.gz: '0913f70f0bdbfd6740f41ce7902f55660ea1bd99533a8f765f9d98a1bd56a58c'
4
+ data.tar.gz: 611a063ae74498d19636ebf3ee3741b76164856341bb38ec9966a999579bdfb1
5
5
  SHA512:
6
- metadata.gz: 4035648fa81ae715315e1efbddd9b0b0506395180d0c7e994d6c8dd49d714e0754717b0cfa93bee702b4ef5a4d8e29bb765fae6045fdb7b24a3e25a1098eca38
7
- data.tar.gz: 3c9d5286f1724b4998325ab811bf2e6ce44dbbbebb3ffb3c6c01ffe76f2d730797a599196b1ec6c3a894265b16ed0b12a78f2eeca53a36b52980de85db76f247
6
+ metadata.gz: 88f39003d30f4642c67a61169923fe248bc572b4a1c638eb36803dc4278aa91a499919784cd060fa35c522bcb935745d1b4542abb1963514aba1f86f1ea789fd
7
+ data.tar.gz: cd2ae8cd383cd9737a732d53c8ca27cbacdcd3c4a5b6bee62f5f43faba4fd8eb8067b0621df18d8b77db679823c3aa26947508fe5827939bf6741e6f417a1d80
data/Gemfile CHANGED
@@ -9,11 +9,12 @@ gem 'openssl'
9
9
  gem 'rake'
10
10
 
11
11
  group :development do
12
+ gem 'base64'
12
13
  gem 'byebug'
13
14
  gem 'http_parser.rb'
15
+ gem 'resolv', '~> 0.4.0'
14
16
  gem 'rspec', '3.9.0'
15
17
  gem 'rubocop', '0.78.0'
16
- gem 'svcb_rr_patch'
17
18
  gem 'webrick'
18
19
  end
19
20
 
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
- s = pem.gsub(/-----(BEGIN|END) ECH CONFIGS-----/, '')
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? || !rr.first.svc_params.keys.include?('ech')
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
- rr.first.svc_params['ech'].echconfiglist.first
115
+ ECHConfig.decode_vectors(octet.slice(2..)).first
107
116
  end
@@ -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
- # NOTE: It can compute (hrr_)accept_ech until client selects the
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
- # @param [String]
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
@@ -6,7 +6,7 @@ module TTTLS13
6
6
  class ApplicationData
7
7
  attr_reader :fragment
8
8
 
9
- # @param [String]
9
+ # @param fragment [String]
10
10
  def initialize(fragment)
11
11
  @fragment = fragment
12
12
  end
@@ -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
@@ -9,7 +9,7 @@ module TTTLS13
9
9
  attr_reader :extension_type
10
10
  attr_reader :protocol_name_list
11
11
 
12
- # @param named_group_list [Array of String]
12
+ # @param protocol_name_list [Array] Array of String
13
13
  #
14
14
  # @raise [TTTLS13::Error::ErrorAlerts]
15
15
  #
@@ -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;
@@ -5,7 +5,6 @@ module TTTLS13
5
5
  using Refinements
6
6
  module Message
7
7
  module Extension
8
- # NOTE:
9
8
  # ExtensionType OuterExtensions<2..254>;
10
9
  class ECHOuterExtensions
11
10
  attr_reader :extension_type
@@ -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::ContentType]
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 groups [TTTLS13::NamedGroup]
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 groups [TTTLS13::NamedGroup]
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;
@@ -9,7 +9,6 @@ module TTTLS13
9
9
  HOST_NAME = "\x00"
10
10
  end
11
11
 
12
- # NOTE:
13
12
  # The extension_data field SHALL be empty when @server_name is empty.
14
13
  # Then, serialized extension_data is
15
14
  #
@@ -5,7 +5,7 @@ module TTTLS13
5
5
  module Message
6
6
  module Extension
7
7
  class SignatureAlgorithmsCert < SignatureAlgorithms
8
- # @param versions [Array of SignatureScheme]
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
@@ -5,7 +5,6 @@ module TTTLS13
5
5
  using Refinements
6
6
  module Message
7
7
  module Extension
8
- # NOTE:
9
8
  # Client/Server MUST ignore unrecognized extensions,
10
9
  # but transcript MUST include unrecognized extensions.
11
10
  class UnknownExtension
@@ -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
  #
@@ -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 groups [Array of TTTLS13::Message::Extension::NamedGroup]
67
+ # @param group [TTTLS13::Message::Extension::NamedGroup]
70
68
  #
71
69
  # @raise [TTTLS13::Error::ErrorAlerts]
72
70
  #
@@ -96,7 +96,6 @@ module TTTLS13
96
96
  end
97
97
  end
98
98
 
99
- # NOTE:
100
99
  # START <-----+
101
100
  # Recv ClientHello | | Send HelloRetryRequest
102
101
  # v |
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTTLS13
4
- VERSION = '0.3.3'
4
+ VERSION = '0.3.4'
5
5
  end
@@ -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.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-04-19 00:00:00.000000000 Z
11
+ date: 2024-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler