tttls1.3 0.2.0 → 0.2.1
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/lib/tttls1.3/client.rb +5 -7
- data/lib/tttls1.3/connection.rb +9 -8
- data/lib/tttls1.3/message/extension/key_share.rb +11 -0
- data/lib/tttls1.3/message/server_hello.rb +5 -6
- data/lib/tttls1.3/server.rb +61 -18
- data/lib/tttls1.3/version.rb +1 -1
- data/spec/server_hello_spec.rb +39 -0
- data/spec/server_spec.rb +2 -2
- 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: 98d9d2196c5b71c0bef8d7abb8838afb1c6d6bc42cdf5b09f24402591cb259ce
|
4
|
+
data.tar.gz: 7fa9dbb492a6a1b8b1b4040b212c8678aaa1fa384da421faa550bb64891908c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee9f193f6d30c8248cebe79a34c949dbbd39529eb5df949dfd02e6fb164c474334d6767b3d2c9ce99794fb04368744ccb24063e92ca078bdf45e64f05004ec70
|
7
|
+
data.tar.gz: 974e0c1bfd02a73fa38ce1e46fb22032e68d43c8823692b1f0b79e6c3f417e4cf94206e9d865ef3aea7ece3c8d4268e235248c88f664264cf2e83a2df8963ecc
|
data/lib/tttls1.3/client.rb
CHANGED
@@ -420,6 +420,7 @@ module TTTLS13
|
|
420
420
|
# supported_groups
|
421
421
|
groups = @settings[:supported_groups]
|
422
422
|
exs << Message::Extension::SupportedGroups.new(groups)
|
423
|
+
|
423
424
|
# key_share
|
424
425
|
ksg = @settings[:key_share_groups] || groups
|
425
426
|
key_share, priv_keys \
|
@@ -668,7 +669,7 @@ module TTTLS13
|
|
668
669
|
sh = @transcript[SH]
|
669
670
|
sh_lv = sh.legacy_version
|
670
671
|
sh_sv = sh.extensions[Message::ExtensionType::SUPPORTED_VERSIONS]
|
671
|
-
|
672
|
+
&.versions || []
|
672
673
|
|
673
674
|
sh_lv == Message::ProtocolVersion::TLS_1_2 &&
|
674
675
|
sh_sv.first == Message::ProtocolVersion::TLS_1_3
|
@@ -744,7 +745,7 @@ module TTTLS13
|
|
744
745
|
def valid_sh_key_share?
|
745
746
|
offered = @transcript[CH].extensions[Message::ExtensionType::KEY_SHARE]
|
746
747
|
.key_share_entry.map(&:group)
|
747
|
-
selected = @transcript[
|
748
|
+
selected = @transcript[SH].extensions[Message::ExtensionType::KEY_SHARE]
|
748
749
|
.key_share_entry.first.group
|
749
750
|
offered.include?(selected)
|
750
751
|
end
|
@@ -754,14 +755,11 @@ module TTTLS13
|
|
754
755
|
# TODO: pre_shared_key
|
755
756
|
ch1_exs = @transcript[CH1].extensions
|
756
757
|
ngl = ch1_exs[Message::ExtensionType::SUPPORTED_GROUPS].named_group_list
|
758
|
+
kse = ch1_exs[Message::ExtensionType::KEY_SHARE].key_share_entry
|
757
759
|
group = @transcript[HRR].extensions[Message::ExtensionType::KEY_SHARE]
|
758
760
|
.key_share_entry.first.group
|
759
|
-
return false unless ngl.include?(group)
|
760
761
|
|
761
|
-
|
762
|
-
return false if !kse.empty? && kse.map(&:group).include?(group)
|
763
|
-
|
764
|
-
true
|
762
|
+
ngl.include?(group) && !kse.map(&:group).include?(group)
|
765
763
|
end
|
766
764
|
|
767
765
|
# @param nst [TTTLS13::Message::NewSessionTicket]
|
data/lib/tttls1.3/connection.rb
CHANGED
@@ -363,15 +363,16 @@ module TTTLS13
|
|
363
363
|
end
|
364
364
|
|
365
365
|
# @return [Boolean]
|
366
|
-
#
|
367
|
-
# Received ccs before the first ClientHello message or after the peer's
|
368
|
-
# Finished message, peer MUST abort.
|
369
366
|
def receivable_ccs?
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
367
|
+
# Received ccs before the first ClientHello message or after the peer's
|
368
|
+
# Finished message, peer MUST abort.
|
369
|
+
#
|
370
|
+
# Server may receive an unprotected record of type change_cipher_spec
|
371
|
+
# between the first and second ClientHello
|
372
|
+
finished = (@endpoint == :client ? SF : CF)
|
373
|
+
|
374
|
+
(@transcript.include?(CH) || @transcript.include?(CH1)) &&
|
375
|
+
!@transcript.include?(finished)
|
375
376
|
end
|
376
377
|
|
377
378
|
# @param symbol [Symbol] key of ALERT_DESCRIPTION
|
@@ -131,6 +131,17 @@ module TTTLS13
|
|
131
131
|
[key_share, ec]
|
132
132
|
end
|
133
133
|
|
134
|
+
# @param groups [TTTLS13::NamedGroup]
|
135
|
+
#
|
136
|
+
# @return [TTTLS13::Message::Extensions::KeyShare]
|
137
|
+
def self.gen_hrr_key_share(group)
|
138
|
+
kse = KeyShareEntry.new(group: group)
|
139
|
+
KeyShare.new(
|
140
|
+
msg_type: HandshakeType::HELLO_RETRY_REQUEST,
|
141
|
+
key_share_entry: [kse]
|
142
|
+
)
|
143
|
+
end
|
144
|
+
|
134
145
|
class << self
|
135
146
|
private
|
136
147
|
|
@@ -21,13 +21,12 @@ module TTTLS13
|
|
21
21
|
].freeze
|
22
22
|
private_constant :APPEARABLE_HRR_EXTENSIONS
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
"\xc2\xa2\x11\x16\x7a\xbb\x8c\x5e\x07\x9e\x09\xe2\xc8\xa8\x33\x9c"
|
29
|
-
private_constant :HRR_RANDOM
|
24
|
+
# special value of the SHA-256 of "HelloRetryRequest"
|
25
|
+
HRR_RANDOM \
|
26
|
+
= "\xcf\x21\xad\x74\xe5\x9a\x61\x11\xbe\x1d\x8c\x02\x1e\x65\xb8\x91" \
|
27
|
+
"\xc2\xa2\x11\x16\x7a\xbb\x8c\x5e\x07\x9e\x09\xe2\xc8\xa8\x33\x9c"
|
30
28
|
|
29
|
+
class ServerHello
|
31
30
|
attr_reader :msg_type
|
32
31
|
attr_reader :legacy_version
|
33
32
|
attr_reader :random
|
data/lib/tttls1.3/server.rb
CHANGED
@@ -140,14 +140,22 @@ module TTTLS13
|
|
140
140
|
terminate(:protocol_version) unless negotiated_tls_1_3?
|
141
141
|
|
142
142
|
# validate/select parameters
|
143
|
+
terminamte(:illegal_parameter) unless valid_ch_compression_methods?
|
144
|
+
terminate(:illegal_parameter) unless valid_ch_key_share?
|
145
|
+
terminate(:unrecognized_name) unless recognized_server_name?
|
143
146
|
@cipher_suite = select_cipher_suite
|
144
147
|
@named_group = select_named_group
|
145
148
|
@signature_scheme = select_signature_scheme
|
146
149
|
terminate(:handshake_failure) \
|
147
|
-
if @cipher_suite.nil? || @
|
148
|
-
|
149
|
-
|
150
|
-
|
150
|
+
if @cipher_suite.nil? || @signature_scheme.nil?
|
151
|
+
|
152
|
+
# send HRR
|
153
|
+
if @named_group.nil?
|
154
|
+
@transcript[CH1] = @transcript.delete(CH)
|
155
|
+
@transcript[HRR] = send_hello_retry_request
|
156
|
+
@state = ServerState::START
|
157
|
+
next
|
158
|
+
end
|
151
159
|
@state = ServerState::NEGOTIATED
|
152
160
|
when ServerState::NEGOTIATED
|
153
161
|
logger.debug('ServerState::NEGOTIATED')
|
@@ -157,12 +165,10 @@ module TTTLS13
|
|
157
165
|
send_ccs # compatibility mode
|
158
166
|
|
159
167
|
# generate shared secret
|
160
|
-
terminate(:illegal_parameter) unless valid_ch_key_share?
|
161
168
|
ke = @transcript[CH].extensions[Message::ExtensionType::KEY_SHARE]
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
# TODO: Send HelloRetryRequest
|
169
|
+
&.key_share_entry
|
170
|
+
&.find { |e| e.group == @named_group }
|
171
|
+
&.key_exchange
|
166
172
|
shared_secret = gen_shared_secret(ke, @priv_key, @named_group)
|
167
173
|
@key_schedule = KeySchedule.new(psk: @psk,
|
168
174
|
shared_secret: shared_secret,
|
@@ -260,6 +266,38 @@ module TTTLS13
|
|
260
266
|
sh
|
261
267
|
end
|
262
268
|
|
269
|
+
# @return [TTTLS13::Message::ServerHello]
|
270
|
+
def send_hello_retry_request
|
271
|
+
exs = []
|
272
|
+
# supported_versions
|
273
|
+
exs << Message::Extension::SupportedVersions.new(
|
274
|
+
msg_type: Message::HandshakeType::SERVER_HELLO
|
275
|
+
)
|
276
|
+
|
277
|
+
# key_share
|
278
|
+
ch1 = @transcript[CH1]
|
279
|
+
sp_groups = ch1.extensions[Message::ExtensionType::SUPPORTED_GROUPS]
|
280
|
+
&.named_group_list || []
|
281
|
+
ks_groups = ch1.extensions[Message::ExtensionType::KEY_SHARE]
|
282
|
+
&.key_share_entry&.map(&:group) || []
|
283
|
+
ksg = sp_groups.find do |g|
|
284
|
+
!ks_groups.include?(g) && @settings[:supported_groups].include?(g)
|
285
|
+
end
|
286
|
+
|
287
|
+
# TODO: cookie
|
288
|
+
exs << Message::Extension::KeyShare.gen_hrr_key_share(ksg)
|
289
|
+
|
290
|
+
sh = Message::ServerHello.new(
|
291
|
+
random: Message::HRR_RANDOM,
|
292
|
+
legacy_session_id_echo: ch1.legacy_session_id,
|
293
|
+
cipher_suite: @cipher_suite,
|
294
|
+
extensions: Message::Extensions.new(exs)
|
295
|
+
)
|
296
|
+
send_handshakes(Message::ContentType::HANDSHAKE, [sh], @write_cipher)
|
297
|
+
|
298
|
+
sh
|
299
|
+
end
|
300
|
+
|
263
301
|
# @param messages [Array of TTTLS13::Message::$Object]
|
264
302
|
#
|
265
303
|
# @return [Array of TTTLS13::Message::$Object]
|
@@ -374,7 +412,7 @@ module TTTLS13
|
|
374
412
|
ch = @transcript[CH]
|
375
413
|
ch_lv = ch.legacy_version
|
376
414
|
ch_sv = ch.extensions[Message::ExtensionType::SUPPORTED_VERSIONS]
|
377
|
-
|
415
|
+
&.versions || []
|
378
416
|
|
379
417
|
ch_lv == Message::ProtocolVersion::TLS_1_2 &&
|
380
418
|
ch_sv.include?(Message::ProtocolVersion::TLS_1_3)
|
@@ -389,12 +427,11 @@ module TTTLS13
|
|
389
427
|
|
390
428
|
# @return [TTTLS13::NamedGroup, nil]
|
391
429
|
def select_named_group
|
392
|
-
|
393
|
-
|
394
|
-
&.named_group_list || []
|
430
|
+
ks_groups = @transcript[CH].extensions[Message::ExtensionType::KEY_SHARE]
|
431
|
+
&.key_share_entry&.map(&:group) || []
|
395
432
|
|
396
|
-
|
397
|
-
@settings[:supported_groups].include?(
|
433
|
+
ks_groups.find do |g|
|
434
|
+
@settings[:supported_groups].include?(g)
|
398
435
|
end
|
399
436
|
end
|
400
437
|
|
@@ -402,7 +439,7 @@ module TTTLS13
|
|
402
439
|
def select_signature_scheme
|
403
440
|
algorithms \
|
404
441
|
= @transcript[CH].extensions[Message::ExtensionType::SIGNATURE_ALGORITHMS]
|
405
|
-
|
442
|
+
&.supported_signature_algorithms || []
|
406
443
|
|
407
444
|
do_select_signature_algorithms(algorithms, @crt).find do |ss|
|
408
445
|
@settings[:signature_algorithms].include?(ss)
|
@@ -418,7 +455,7 @@ module TTTLS13
|
|
418
455
|
def recognized_server_name?
|
419
456
|
server_name \
|
420
457
|
= @transcript[CH].extensions[Message::ExtensionType::SERVER_NAME]
|
421
|
-
|
458
|
+
&.server_name
|
422
459
|
|
423
460
|
return true if server_name.nil?
|
424
461
|
|
@@ -432,7 +469,13 @@ module TTTLS13
|
|
432
469
|
sg = @transcript[CH].extensions[Message::ExtensionType::SUPPORTED_GROUPS]
|
433
470
|
sp_groups = sg&.named_group_list || []
|
434
471
|
|
435
|
-
|
472
|
+
# Each KeyShareEntry value MUST correspond to a group offered in the
|
473
|
+
# "supported_groups" extension and MUST appear in the same order.
|
474
|
+
#
|
475
|
+
# Clients MUST NOT offer multiple KeyShareEntry values for the same group.
|
476
|
+
(ks_groups - sp_groups).empty? &&
|
477
|
+
sp_groups.filter { |g| ks_groups.include?(g) } == ks_groups &&
|
478
|
+
ks_groups.uniq == ks_groups
|
436
479
|
end
|
437
480
|
end
|
438
481
|
# rubocop: enable Metrics/ClassLength
|
data/lib/tttls1.3/version.rb
CHANGED
data/spec/server_hello_spec.rb
CHANGED
@@ -98,4 +98,43 @@ RSpec.describe ServerHello do
|
|
98
98
|
expect(message.serialize).to eq TESTBINARY_0_RTT_SERVER_HELLO
|
99
99
|
end
|
100
100
|
end
|
101
|
+
|
102
|
+
context 'default hello_retry_request' do
|
103
|
+
let(:legacy_session_id_echo) do
|
104
|
+
Array.new(32, 0).map(&:chr).join
|
105
|
+
end
|
106
|
+
|
107
|
+
let(:cipher_suite) do
|
108
|
+
CipherSuite::TLS_AES_256_GCM_SHA384
|
109
|
+
end
|
110
|
+
|
111
|
+
let(:message) do
|
112
|
+
ServerHello.new(random: Message::HRR_RANDOM,
|
113
|
+
legacy_session_id_echo: legacy_session_id_echo,
|
114
|
+
cipher_suite: cipher_suite)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should be generated' do
|
118
|
+
expect(message.msg_type).to eq HandshakeType::SERVER_HELLO
|
119
|
+
expect(message.legacy_version).to eq ProtocolVersion::TLS_1_2
|
120
|
+
expect(message.random).to eq Message::HRR_RANDOM
|
121
|
+
expect(message.legacy_session_id_echo).to eq legacy_session_id_echo
|
122
|
+
expect(message.cipher_suite).to eq CipherSuite::TLS_AES_256_GCM_SHA384
|
123
|
+
expect(message.legacy_compression_method).to eq "\x00"
|
124
|
+
expect(message.extensions).to be_empty
|
125
|
+
expect(message.hrr?).to eq true
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should be serialized' do
|
129
|
+
expect(message.serialize).to eq HandshakeType::SERVER_HELLO \
|
130
|
+
+ 72.to_uint24 \
|
131
|
+
+ ProtocolVersion::TLS_1_2 \
|
132
|
+
+ Message::HRR_RANDOM \
|
133
|
+
+ legacy_session_id_echo.length.to_uint8 \
|
134
|
+
+ legacy_session_id_echo \
|
135
|
+
+ cipher_suite \
|
136
|
+
+ "\x00" \
|
137
|
+
+ Extensions.new.serialize
|
138
|
+
end
|
139
|
+
end
|
101
140
|
end
|
data/spec/server_spec.rb
CHANGED
@@ -40,8 +40,8 @@ RSpec.describe Server do
|
|
40
40
|
server.instance_variable_set(:@transcript, transcript)
|
41
41
|
cipher_suite = server.send(:select_cipher_suite)
|
42
42
|
server.instance_variable_set(:@cipher_suite, cipher_suite)
|
43
|
-
named_group
|
44
|
-
server.instance_variable_set(:@named_group,
|
43
|
+
# X25519 is unsupported so @named_group uses SECP256R1.
|
44
|
+
server.instance_variable_set(:@named_group, NamedGroup::SECP256R1)
|
45
45
|
signature_scheme = server.send(:select_signature_scheme)
|
46
46
|
server.instance_variable_set(:@signature_scheme, signature_scheme)
|
47
47
|
exs, _priv_key = server.send(:gen_sh_extensions)
|
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.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thekuwayama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-05-
|
11
|
+
date: 2019-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|