tttls1.3 0.2.1 → 0.2.2

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.
@@ -3,6 +3,7 @@
3
3
 
4
4
  module TTTLS13
5
5
  using Refinements
6
+
6
7
  module ClientState
7
8
  # initial value is 0, eof value is -1
8
9
  START = 1
@@ -62,11 +63,6 @@ module TTTLS13
62
63
 
63
64
  # rubocop: disable Metrics/ClassLength
64
65
  class Client < Connection
65
- DOWNGRADE_PROTECTION_TLS_1_2 = "\x44\x4F\x57\x4E\x47\x52\x44\x01"
66
- private_constant :DOWNGRADE_PROTECTION_TLS_1_2
67
- DOWNGRADE_PROTECTION_TLS_1_1 = "\x44\x4F\x57\x4E\x47\x52\x44\x00"
68
- private_constant :DOWNGRADE_PROTECTION_TLS_1_1
69
-
70
66
  # @param socket [Socket]
71
67
  # @param hostname [String]
72
68
  # @param settings [Hash]
@@ -79,20 +75,8 @@ module TTTLS13
79
75
  logger.level = @settings[:loglevel]
80
76
 
81
77
  @early_data = ''
82
- @early_data_write_cipher = nil # Cryptograph::$Object
83
78
  @succeed_early_data = false
84
79
  raise Error::ConfigError unless valid_settings?
85
- return unless use_psk?
86
-
87
- digest = CipherSuite.digest(@settings[:psk_cipher_suite])
88
- @psk = gen_psk_from_nst(@settings[:resumption_master_secret],
89
- @settings[:ticket_nonce], digest)
90
- @key_schedule = KeySchedule.new(
91
- psk: @psk,
92
- shared_secret: nil,
93
- cipher_suite: @settings[:psk_cipher_suite],
94
- transcript: @transcript
95
- )
96
80
  end
97
81
 
98
82
  # NOTE:
@@ -135,98 +119,160 @@ module TTTLS13
135
119
  # rubocop: disable Metrics/MethodLength
136
120
  # rubocop: disable Metrics/PerceivedComplexity
137
121
  def connect
122
+ transcript = Transcript.new
123
+ key_schedule = nil # TTTLS13::KeySchedule
124
+ psk = nil
125
+ priv_keys = {} # Hash of NamedGroup => OpenSSL::PKey::$Object
126
+ if use_psk?
127
+ psk = gen_psk_from_nst(
128
+ @settings[:resumption_master_secret],
129
+ @settings[:ticket_nonce],
130
+ CipherSuite.digest(@settings[:psk_cipher_suite])
131
+ )
132
+ key_schedule = KeySchedule.new(
133
+ psk: psk,
134
+ shared_secret: nil,
135
+ cipher_suite: @settings[:psk_cipher_suite],
136
+ transcript: transcript
137
+ )
138
+ end
139
+
140
+ hs_wcipher = nil # TTTLS13::Cryptograph::$Object
141
+ hs_rcipher = nil # TTTLS13::Cryptograph::$Object
142
+ e_wcipher = nil # TTTLS13::Cryptograph::$Object
143
+
138
144
  @state = ClientState::START
139
145
  loop do
140
146
  case @state
141
147
  when ClientState::START
142
148
  logger.debug('ClientState::START')
143
149
 
144
- exs, @priv_keys = gen_ch_extensions
145
- @transcript[CH] = send_client_hello(exs)
150
+ extensions, priv_keys = gen_ch_extensions
151
+ binder_key = (use_psk? ? key_schedule.binder_key_res : nil)
152
+ transcript[CH] = send_client_hello(extensions, binder_key)
153
+
146
154
  send_ccs # compatibility mode
147
155
  if use_early_data?
148
- @early_data_write_cipher \
149
- = gen_cipher(@settings[:psk_cipher_suite],
150
- @key_schedule.early_data_write_key,
151
- @key_schedule.early_data_write_iv)
152
- send_early_data
156
+ e_wcipher = gen_cipher(
157
+ @settings[:psk_cipher_suite],
158
+ key_schedule.early_data_write_key,
159
+ key_schedule.early_data_write_iv
160
+ )
161
+ send_early_data(e_wcipher)
153
162
  end
154
163
 
155
164
  @state = ClientState::WAIT_SH
156
165
  when ClientState::WAIT_SH
157
166
  logger.debug('ClientState::WAIT_SH')
158
167
 
159
- sh = @transcript[SH] = recv_server_hello
160
- terminate(:illegal_parameter) unless sh.only_appearable_extensions?
168
+ sh = transcript[SH] = recv_server_hello
169
+
161
170
  # support only TLS 1.3
162
- terminate(:protocol_version) unless negotiated_tls_1_3?
171
+ terminate(:protocol_version) unless sh.negotiated_tls_1_3?
163
172
 
164
173
  # validate parameters
165
- terminate(:illegal_parameter) unless valid_sh_legacy_version?
166
- terminate(:illegal_parameter) unless valid_sh_random?
167
- terminate(:illegal_parameter) unless valid_sh_legacy_session_id_echo?
168
- terminate(:illegal_parameter) unless valid_sh_cipher_suite?
174
+ terminate(:illegal_parameter) unless sh.appearable_extensions?
175
+ terminate(:illegal_parameter) if sh.downgraded?
169
176
  terminate(:illegal_parameter) \
170
- if @transcript.include?(HRR) &&
171
- neq_hrr_cipher_suite?(sh.cipher_suite)
172
- terminate(:illegal_parameter) unless valid_sh_compression_method?
177
+ unless sh.legacy_compression_method == "\x00"
178
+
179
+ # validate sh using ch
180
+ ch = transcript[CH]
181
+ terminate(:illegal_parameter) \
182
+ unless sh.legacy_version == ch.legacy_version
183
+ terminate(:illegal_parameter) \
184
+ unless sh.legacy_session_id_echo == ch.legacy_session_id
185
+ terminate(:illegal_parameter) \
186
+ unless ch.cipher_suites.include?(sh.cipher_suite)
187
+ terminate(:unsupported_extension) \
188
+ unless (sh.extensions.keys - ch.extensions.keys).empty?
189
+
190
+ # validate sh using hrr
191
+ if transcript.include?(HRR)
192
+ hrr = transcript[HRR]
193
+ terminate(:illegal_parameter) \
194
+ unless sh.cipher_suite == hrr.cipher_suite
195
+
196
+ sh_sv = sh.extensions[Message::ExtensionType::SUPPORTED_VERSIONS]
197
+ hrr_sv = hrr.extensions[Message::ExtensionType::SUPPORTED_VERSIONS]
198
+ terminate(:illegal_parameter) \
199
+ unless sh_sv.versions == hrr_sv.versions
200
+ end
173
201
 
174
202
  # handling HRR
175
203
  if sh.hrr?
176
- terminate(:unexpected_message) if received_2nd_hrr?
204
+ terminate(:unexpected_message) if transcript.include?(HRR)
205
+ ch1 = transcript[CH1] = transcript.delete(CH)
206
+ hrr = transcript[HRR] = transcript.delete(SH)
177
207
 
178
- @transcript[CH1] = @transcript.delete(CH)
179
- @transcript[HRR] = @transcript.delete(SH)
208
+ # validate cookie
209
+ diff_sets = sh.extensions.keys - ch1.extensions.keys
180
210
  terminate(:unsupported_extension) \
181
- unless offered_ch_extensions?(sh.extensions, HRR)
182
- terminate(:illegal_parameter) unless valid_hrr_key_share?
183
-
184
- ch = send_new_client_hello(@transcript[CH1], @transcript[HRR])
185
- @transcript[CH] = ch
211
+ unless (diff_sets - [Message::ExtensionType::COOKIE]).empty?
212
+
213
+ # validate key_share
214
+ # TODO: pre_shared_key
215
+ ngl = ch1.extensions[Message::ExtensionType::SUPPORTED_GROUPS]
216
+ .named_group_list
217
+ kse = ch1.extensions[Message::ExtensionType::KEY_SHARE]
218
+ .key_share_entry
219
+ group = hrr.extensions[Message::ExtensionType::KEY_SHARE]
220
+ .key_share_entry.first.group
221
+ terminate(:illegal_parameter) \
222
+ unless ngl.include?(group) && !kse.map(&:group).include?(group)
223
+
224
+ # send new client_hello
225
+ extensions, pk = gen_newch_extensions(ch1, hrr)
226
+ priv_keys = pk.merge(priv_keys)
227
+ binder_key = (use_psk? ? key_schedule.binder_key_res : nil)
228
+ transcript[CH] = send_new_client_hello(ch1, hrr, extensions,
229
+ binder_key)
186
230
  @state = ClientState::WAIT_SH
187
231
  next
188
232
  end
189
233
 
190
- # validate extensions
191
- terminate(:unsupported_extension) \
192
- unless offered_ch_extensions?(sh.extensions)
193
-
194
- versions \
195
- = sh.extensions[Message::ExtensionType::SUPPORTED_VERSIONS].versions
196
- terminate(:illegal_parameter) \
197
- if @transcript.include?(HRR) &&
198
- neq_hrr_supported_versions?(versions)
199
-
200
234
  # generate shared secret
201
- @psk = nil unless sh.extensions
202
- .include?(Message::ExtensionType::PRE_SHARED_KEY)
203
- terminate(:illegal_parameter) unless valid_sh_key_share?
235
+ psk = nil unless sh.extensions
236
+ .include?(Message::ExtensionType::PRE_SHARED_KEY)
237
+ ch_ks = ch.extensions[Message::ExtensionType::KEY_SHARE]
238
+ .key_share_entry.map(&:group)
239
+ sh_ks = sh.extensions[Message::ExtensionType::KEY_SHARE]
240
+ .key_share_entry.first.group
241
+ terminate(:illegal_parameter) unless ch_ks.include?(sh_ks)
204
242
 
205
243
  kse = sh.extensions[Message::ExtensionType::KEY_SHARE]
206
244
  .key_share_entry.first
207
245
  ke = kse.key_exchange
208
- group = kse.group
209
- priv_key = @priv_keys[group]
210
- shared_secret = gen_shared_secret(ke, priv_key, group)
246
+ @named_group = kse.group
247
+ priv_key = priv_keys[@named_group]
248
+ shared_secret = gen_shared_secret(ke, priv_key, @named_group)
211
249
  @cipher_suite = sh.cipher_suite
212
- @key_schedule = KeySchedule.new(psk: @psk,
213
- shared_secret: shared_secret,
214
- cipher_suite: @cipher_suite,
215
- transcript: @transcript)
216
- @write_cipher = gen_cipher(@cipher_suite,
217
- @key_schedule.client_handshake_write_key,
218
- @key_schedule.client_handshake_write_iv)
219
- @read_cipher = gen_cipher(@cipher_suite,
220
- @key_schedule.server_handshake_write_key,
221
- @key_schedule.server_handshake_write_iv)
250
+ key_schedule = KeySchedule.new(
251
+ psk: psk,
252
+ shared_secret: shared_secret,
253
+ cipher_suite: @cipher_suite,
254
+ transcript: transcript
255
+ )
256
+ @alert_wcipher = hs_wcipher = gen_cipher(
257
+ @cipher_suite,
258
+ key_schedule.client_handshake_write_key,
259
+ key_schedule.client_handshake_write_iv
260
+ )
261
+ hs_rcipher = gen_cipher(
262
+ @cipher_suite,
263
+ key_schedule.server_handshake_write_key,
264
+ key_schedule.server_handshake_write_iv
265
+ )
222
266
  @state = ClientState::WAIT_EE
223
267
  when ClientState::WAIT_EE
224
268
  logger.debug('ClientState::WAIT_EE')
225
269
 
226
- ee = @transcript[EE] = recv_encrypted_extensions
227
- terminate(:illegal_parameter) unless ee.only_appearable_extensions?
270
+ ee = transcript[EE] = recv_encrypted_extensions(hs_rcipher)
271
+ terminate(:illegal_parameter) unless ee.appearable_extensions?
272
+
273
+ ch = transcript[CH]
228
274
  terminate(:unsupported_extension) \
229
- unless offered_ch_extensions?(ee.extensions)
275
+ unless (ee.extensions.keys - ch.extensions.keys).empty?
230
276
 
231
277
  rsl = ee.extensions[Message::ExtensionType::RECORD_SIZE_LIMIT]
232
278
  @send_record_size = rsl.record_size_limit unless rsl.nil?
@@ -235,17 +281,19 @@ module TTTLS13
235
281
  if ee.extensions.include?(Message::ExtensionType::EARLY_DATA)
236
282
 
237
283
  @state = ClientState::WAIT_CERT_CR
238
- @state = ClientState::WAIT_FINISHED unless @psk.nil?
284
+ @state = ClientState::WAIT_FINISHED unless psk.nil?
239
285
  when ClientState::WAIT_CERT_CR
240
286
  logger.debug('ClientState::WAIT_EE')
241
287
 
242
- message = recv_message
288
+ message = recv_message(receivable_ccs: true, cipher: hs_rcipher)
243
289
  if message.msg_type == Message::HandshakeType::CERTIFICATE
244
- ct = @transcript[CT] = message
245
- terminate(:illegal_parameter) unless ct.only_appearable_extensions?
290
+ ct = transcript[CT] = message
291
+ terminate(:illegal_parameter) unless ct.appearable_extensions?
292
+
293
+ ch = transcript[CH]
246
294
  terminate(:unsupported_extension) \
247
295
  unless ct.certificate_list.map(&:extensions)
248
- .all? { |ex| offered_ch_extensions?(ex) }
296
+ .all? { |e| (e.keys - ch.extensions.keys).empty? }
249
297
 
250
298
  terminate(:certificate_unknown) \
251
299
  unless trusted_certificate?(ct.certificate_list,
@@ -253,7 +301,7 @@ module TTTLS13
253
301
 
254
302
  @state = ClientState::WAIT_CV
255
303
  elsif message.msg_type == Message::HandshakeType::CERTIFICATE_REQUEST
256
- @transcript[CR] = message
304
+ transcript[CR] = message
257
305
  # TODO: client authentication
258
306
  @state = ClientState::WAIT_CERT
259
307
  else
@@ -262,11 +310,13 @@ module TTTLS13
262
310
  when ClientState::WAIT_CERT
263
311
  logger.debug('ClientState::WAIT_EE')
264
312
 
265
- ct = @transcript[CT] = recv_certificate
266
- terminate(:illegal_parameter) unless ct.only_appearable_extensions?
313
+ ct = transcript[CT] = recv_certificate(hs_rcipher)
314
+ terminate(:illegal_parameter) unless ct.appearable_extensions?
315
+
316
+ ch = transcript[CH]
267
317
  terminate(:unsupported_extension) \
268
318
  unless ct.certificate_list.map(&:extensions)
269
- .all? { |ex| offered_ch_extensions?(ex) }
319
+ .all? { |e| (e.keys - ch.extensions.keys).empty? }
270
320
 
271
321
  terminate(:certificate_unknown) \
272
322
  unless trusted_certificate?(ct.certificate_list,
@@ -276,27 +326,52 @@ module TTTLS13
276
326
  when ClientState::WAIT_CV
277
327
  logger.debug('ClientState::WAIT_EE')
278
328
 
279
- @transcript[CV] = recv_certificate_verify
280
- terminate(:decrypt_error) unless verified_certificate_verify?
329
+ cv = transcript[CV] = recv_certificate_verify(hs_rcipher)
330
+ digest = CipherSuite.digest(@cipher_suite)
331
+ hash = transcript.hash(digest, CT)
332
+ terminate(:decrypt_error) \
333
+ unless verified_certificate_verify?(transcript[CT], cv, hash)
334
+
335
+ @signature_scheme = cv.signature_scheme
336
+
281
337
  @state = ClientState::WAIT_FINISHED
282
338
  when ClientState::WAIT_FINISHED
283
339
  logger.debug('ClientState::WAIT_EE')
284
340
 
285
- @transcript[SF] = recv_finished
286
- terminate(:decrypt_error) unless verified_finished?
287
- @transcript[EOED] = send_eoed \
341
+ sf = transcript[SF] = recv_finished(hs_rcipher)
342
+ digest = CipherSuite.digest(@cipher_suite)
343
+ verified = verified_finished?(
344
+ finished: sf,
345
+ digest: digest,
346
+ finished_key: key_schedule.server_finished_key,
347
+ hash: transcript.hash(digest, CV)
348
+ )
349
+ terminate(:decrypt_error) unless verified
350
+
351
+ transcript[EOED] = send_eoed(e_wcipher) \
288
352
  if use_early_data? && succeed_early_data?
353
+
289
354
  # TODO: Send Certificate [+ CertificateVerify]
290
- @transcript[CF] = send_finished
291
- @write_cipher = gen_cipher(@cipher_suite,
292
- @key_schedule.client_application_write_key,
293
- @key_schedule.client_application_write_iv)
294
- @read_cipher = gen_cipher(@cipher_suite,
295
- @key_schedule.server_application_write_key,
296
- @key_schedule.server_application_write_iv)
355
+ signature = sign_finished(
356
+ digest: digest,
357
+ finished_key: key_schedule.client_finished_key,
358
+ hash: transcript.hash(digest, EOED)
359
+ )
360
+ transcript[CF] = send_finished(signature, hs_wcipher)
361
+ @alert_wcipher = @ap_wcipher = gen_cipher(
362
+ @cipher_suite,
363
+ key_schedule.client_application_write_key,
364
+ key_schedule.client_application_write_iv
365
+ )
366
+ @ap_rcipher = gen_cipher(
367
+ @cipher_suite,
368
+ key_schedule.server_application_write_key,
369
+ key_schedule.server_application_write_iv
370
+ )
371
+ @resumption_master_secret = key_schedule.resumption_master_secret
297
372
  @state = ClientState::CONNECTED
298
373
  when ClientState::CONNECTED
299
- logger.debug('ClientState::WAIT_EE')
374
+ logger.debug('ClientState::CONNECTED')
300
375
 
301
376
  break
302
377
  end
@@ -369,13 +444,14 @@ module TTTLS13
369
444
  !(@early_data.nil? || @early_data.empty?)
370
445
  end
371
446
 
372
- def send_early_data
447
+ # @param cipher [TTTLS13::Cryptograph::Aead]
448
+ def send_early_data(cipher)
373
449
  ap = Message::ApplicationData.new(@early_data)
374
450
  ap_record = Message::Record.new(
375
451
  type: Message::ContentType::APPLICATION_DATA,
376
452
  legacy_record_version: Message::ProtocolVersion::TLS_1_2,
377
453
  messages: [ap],
378
- cipher: @early_data_write_cipher
454
+ cipher: cipher
379
455
  )
380
456
  send_record(ap_record)
381
457
  end
@@ -395,8 +471,6 @@ module TTTLS13
395
471
 
396
472
  # @return [TTTLS13::Message::Extensions]
397
473
  # @return [Hash of NamedGroup => OpenSSL::PKey::EC.$Object]
398
- # rubocop: disable Metrics/AbcSize
399
- # rubocop: disable Metrics/CyclomaticComplexity
400
474
  def gen_ch_extensions
401
475
  exs = []
402
476
  # supported_versions: only TLS 1.3
@@ -428,24 +502,22 @@ module TTTLS13
428
502
  exs << key_share
429
503
 
430
504
  # server_name
431
- exs << Message::Extension::ServerName.new(@hostname) \
432
- if !@hostname.nil? && !@hostname.empty?
505
+ exs << Message::Extension::ServerName.new(@hostname)
433
506
 
434
507
  # early_data
435
508
  exs << Message::Extension::EarlyDataIndication.new if use_early_data?
436
509
 
437
510
  [Message::Extensions.new(exs), priv_keys]
438
511
  end
439
- # rubocop: enable Metrics/AbcSize
440
- # rubocop: enable Metrics/CyclomaticComplexity
441
512
 
442
- # @param exs [TTTLS13::Message::Extensions]
513
+ # @param extensions [TTTLS13::Message::Extensions]
514
+ # @param binder_key [String, nil]
443
515
  #
444
516
  # @return [TTTLS13::Message::ClientHello]
445
- def send_client_hello(exs)
517
+ def send_client_hello(extensions, binder_key = nil)
446
518
  ch = Message::ClientHello.new(
447
519
  cipher_suites: CipherSuites.new(@settings[:cipher_suites]),
448
- extensions: exs
520
+ extensions: extensions
449
521
  )
450
522
 
451
523
  if use_psk?
@@ -460,18 +532,25 @@ module TTTLS13
460
532
  )
461
533
  ch.extensions[Message::ExtensionType::PSK_KEY_EXCHANGE_MODES] = pkem
462
534
  # at the end, sign PSK binder
463
- sign_psk_binder(ch)
535
+ sign_psk_binder(
536
+ ch: ch,
537
+ binder_key: binder_key
538
+ )
464
539
  end
465
540
 
466
- send_handshakes(Message::ContentType::HANDSHAKE, [ch], @write_cipher)
541
+ send_handshakes(Message::ContentType::HANDSHAKE, [ch],
542
+ Cryptograph::Passer.new)
467
543
 
468
544
  ch
469
545
  end
470
546
 
547
+ # @param ch1 [TTTLS13::Message::ClientHello]
548
+ # @param hrr [TTTLS13::Message::ServerHello]
471
549
  # @param ch [TTTLS13::Message::ClientHello]
550
+ # @param binder_key [String]
472
551
  #
473
552
  # @return [String]
474
- def sign_psk_binder(ch)
553
+ def sign_psk_binder(ch1: nil, hrr: nil, ch:, binder_key:)
475
554
  # pre_shared_key
476
555
  #
477
556
  # binder is computed as an HMAC over a transcript hash containing a
@@ -494,9 +573,13 @@ module TTTLS13
494
573
  )
495
574
  ch.extensions[Message::ExtensionType::PRE_SHARED_KEY] = psk
496
575
 
497
- transcript = @transcript.clone
498
- transcript[CH] = ch
499
- psk.offered_psks.binders[0] = do_sign_psk_binder(digest, transcript)
576
+ psk.offered_psks.binders[0] = do_sign_psk_binder(
577
+ ch1: ch1,
578
+ hrr: hrr,
579
+ ch: ch,
580
+ binder_key: binder_key,
581
+ digest: digest
582
+ )
500
583
  end
501
584
 
502
585
  # @return [Integer]
@@ -507,24 +590,20 @@ module TTTLS13
507
590
  (age + Convert.bin2i(@settings[:ticket_age_add])) % (2**32)
508
591
  end
509
592
 
510
- # NOTE:
511
- # https://tools.ietf.org/html/rfc8446#section-4.1.2
512
- #
513
593
  # @param ch1 [TTTLS13::Message::ClientHello]
514
594
  # @param hrr [TTTLS13::Message::ServerHello]
515
595
  #
516
- # @return [TTTLS13::Message::ClientHello]
517
- def send_new_client_hello(ch1, hrr)
518
- arr = []
519
-
596
+ # @return [TTTLS13::Message::Extensions]
597
+ # @return [Hash of NamedGroup => OpenSSL::PKey::EC.$Object]
598
+ def gen_newch_extensions(ch1, hrr)
599
+ exs = []
520
600
  # key_share
521
601
  if hrr.extensions.include?(Message::ExtensionType::KEY_SHARE)
522
602
  group = hrr.extensions[Message::ExtensionType::KEY_SHARE]
523
603
  .key_share_entry.first.group
524
604
  key_share, priv_keys \
525
605
  = Message::Extension::KeyShare.gen_ch_key_share([group])
526
- arr << key_share
527
- @priv_keys = priv_keys.merge(@priv_keys)
606
+ exs << key_share
528
607
  end
529
608
 
530
609
  # cookie
@@ -535,21 +614,45 @@ module TTTLS13
535
614
  # HelloRetryRequest into a "cookie" extension in the new ClientHello.
536
615
  #
537
616
  # https://tools.ietf.org/html/rfc8446#section-4.2.2
538
- arr << hrr.extensions[Message::ExtensionType::COOKIE] \
617
+ exs << hrr.extensions[Message::ExtensionType::COOKIE] \
539
618
  if hrr.extensions.include?(Message::ExtensionType::COOKIE)
540
619
 
541
620
  # early_data
542
- new_exs = ch1.extensions.merge(Message::Extensions.new(arr))
621
+ new_exs = ch1.extensions.merge(Message::Extensions.new(exs))
543
622
  new_exs.delete(Message::ExtensionType::EARLY_DATA)
623
+
624
+ [new_exs, priv_keys]
625
+ end
626
+
627
+ # NOTE:
628
+ # https://tools.ietf.org/html/rfc8446#section-4.1.2
629
+ #
630
+ # @param ch1 [TTTLS13::Message::ClientHello]
631
+ # @param hrr [TTTLS13::Message::ServerHello]
632
+ # @param extensions [TTTLS13::Message::Extensions]
633
+ # @param binder_key [String, nil]
634
+ #
635
+ # @return [TTTLS13::Message::ClientHello]
636
+ def send_new_client_hello(ch1, hrr, extensions, binder_key = nil)
544
637
  ch = Message::ClientHello.new(
545
638
  legacy_version: ch1.legacy_version,
546
639
  random: ch1.random,
547
640
  legacy_session_id: ch1.legacy_session_id,
548
641
  cipher_suites: ch1.cipher_suites,
549
642
  legacy_compression_methods: ch1.legacy_compression_methods,
550
- extensions: new_exs
643
+ extensions: extensions
551
644
  )
552
- send_handshakes(Message::ContentType::HANDSHAKE, [ch], @write_cipher)
645
+
646
+ # pre_shared_key
647
+ #
648
+ # Updating the "pre_shared_key" extension if present by recomputing
649
+ # the "obfuscated_ticket_age" and binder values.
650
+ if ch1.extensions.include?(Message::ExtensionType::PRE_SHARED_KEY)
651
+ sign_psk_binder(ch1: ch1, hrr: hrr, ch: ch, binder_key: binder_key)
652
+ end
653
+
654
+ send_handshakes(Message::ContentType::HANDSHAKE, [ch],
655
+ Cryptograph::Passer.new)
553
656
 
554
657
  ch
555
658
  end
@@ -558,208 +661,98 @@ module TTTLS13
558
661
  #
559
662
  # @return [TTTLS13::Message::ServerHello]
560
663
  def recv_server_hello
561
- sh = recv_message
664
+ sh = recv_message(receivable_ccs: true, cipher: Cryptograph::Passer.new)
562
665
  terminate(:unexpected_message) unless sh.is_a?(Message::ServerHello)
563
666
 
564
667
  sh
565
668
  end
566
669
 
670
+ # @param cipher [TTTLS13::Cryptograph::Aead]
671
+ #
567
672
  # @raise [TTTLS13::Error::ErrorAlerts]
568
673
  #
569
674
  # @return [TTTLS13::Message::EncryptedExtensions]
570
- def recv_encrypted_extensions
571
- ee = recv_message
675
+ def recv_encrypted_extensions(cipher)
676
+ ee = recv_message(receivable_ccs: true, cipher: cipher)
572
677
  terminate(:unexpected_message) \
573
678
  unless ee.is_a?(Message::EncryptedExtensions)
574
679
 
575
680
  ee
576
681
  end
577
682
 
683
+ # @param cipher [TTTLS13::Cryptograph::Aead]
684
+ #
578
685
  # @raise [TTTLS13::Error::ErrorAlerts]
579
686
  #
580
687
  # @return [TTTLS13::Message::Certificate]
581
- def recv_certificate
582
- ct = recv_message
688
+ def recv_certificate(cipher)
689
+ ct = recv_message(receivable_ccs: true, cipher: cipher)
583
690
  terminate(:unexpected_message) unless ct.is_a?(Message::Certificate)
584
691
 
585
692
  ct
586
693
  end
587
694
 
695
+ # @param cipher [TTTLS13::Cryptograph::Aead]
696
+ #
588
697
  # @raise [TTTLS13::Error::ErrorAlerts]
589
698
  #
590
699
  # @return [TTTLS13::Message::CertificateVerify]
591
- def recv_certificate_verify
592
- cv = recv_message
700
+ def recv_certificate_verify(cipher)
701
+ cv = recv_message(receivable_ccs: true, cipher: cipher)
593
702
  terminate(:unexpected_message) unless cv.is_a?(Message::CertificateVerify)
594
703
 
595
704
  cv
596
705
  end
597
706
 
707
+ # @param cipher [TTTLS13::Cryptograph::Aead]
708
+ #
598
709
  # @raise [TTTLS13::Error::ErrorAlerts]
599
710
  #
600
711
  # @return [TTTLS13::Message::Finished]
601
- def recv_finished
602
- sf = recv_message
712
+ def recv_finished(cipher)
713
+ sf = recv_message(receivable_ccs: true, cipher: cipher)
603
714
  terminate(:unexpected_message) unless sf.is_a?(Message::Finished)
604
715
 
605
716
  sf
606
717
  end
607
718
 
719
+ # @param cipher [TTTLS13::Cryptograph::Aead]
720
+ #
608
721
  # @return [TTTLS13::Message::Finished]
609
- def send_finished
610
- cf = Message::Finished.new(sign_finished)
611
- send_handshakes(Message::ContentType::APPLICATION_DATA, [cf],
612
- @write_cipher)
722
+ def send_finished(signature, cipher)
723
+ cf = Message::Finished.new(signature)
724
+ send_handshakes(Message::ContentType::APPLICATION_DATA, [cf], cipher)
613
725
 
614
726
  cf
615
727
  end
616
728
 
729
+ # @param cipher [TTTLS13::Cryptograph::Aead]
730
+ #
617
731
  # @return [TTTLS13::Message::EndOfEarlyData]
618
- def send_eoed
732
+ def send_eoed(cipher)
619
733
  eoed = Message::EndOfEarlyData.new
620
- send_handshakes(Message::ContentType::APPLICATION_DATA, [eoed],
621
- @early_data_write_cipher)
734
+ send_handshakes(Message::ContentType::APPLICATION_DATA, [eoed], cipher)
622
735
 
623
736
  eoed
624
737
  end
625
738
 
739
+ # @param ct [TTTLS13::Message::Certificate]
740
+ # @param cv [TTTLS13::Message::CertificateVerify]
741
+ # @param hash [String]
742
+ #
626
743
  # @return [Boolean]
627
- def verified_certificate_verify?
628
- ct = @transcript[CT]
744
+ def verified_certificate_verify?(ct, cv, hash)
629
745
  public_key = ct.certificate_list.first.cert_data.public_key
630
- cv = @transcript[CV]
631
746
  signature_scheme = cv.signature_scheme
632
747
  signature = cv.signature
633
- context = 'TLS 1.3, server CertificateVerify'
634
- do_verified_certificate_verify?(public_key: public_key,
635
- signature_scheme: signature_scheme,
636
- signature: signature,
637
- context: context,
638
- handshake_context_end: CT)
639
- end
640
-
641
- # @return [String]
642
- def sign_finished
643
- digest = CipherSuite.digest(@cipher_suite)
644
- finished_key = @key_schedule.client_finished_key
645
- do_sign_finished(digest: digest,
646
- finished_key: finished_key,
647
- handshake_context_end: EOED)
648
- end
649
-
650
- # @return [Boolean]
651
- def verified_finished?
652
- digest = CipherSuite.digest(@cipher_suite)
653
- finished_key = @key_schedule.server_finished_key
654
- signature = @transcript[SF].verify_data
655
- do_verified_finished?(digest: digest,
656
- finished_key: finished_key,
657
- handshake_context_end: CV,
658
- signature: signature)
659
- end
660
-
661
- # NOTE:
662
- # This implementation supports only TLS 1.3,
663
- # so negotiated_tls_1_3? assumes that it sent ClientHello with:
664
- # 1. supported_versions == ["\x03\x04"]
665
- # 2. legacy_versions == ["\x03\x03"]
666
- #
667
- # @return [Boolean]
668
- def negotiated_tls_1_3?
669
- sh = @transcript[SH]
670
- sh_lv = sh.legacy_version
671
- sh_sv = sh.extensions[Message::ExtensionType::SUPPORTED_VERSIONS]
672
- &.versions || []
673
-
674
- sh_lv == Message::ProtocolVersion::TLS_1_2 &&
675
- sh_sv.first == Message::ProtocolVersion::TLS_1_3
676
- end
677
-
678
- # @return [Boolean]
679
- def valid_sh_random?
680
- sh_r8 = @transcript[SH].random[-8..]
681
-
682
- sh_r8 != DOWNGRADE_PROTECTION_TLS_1_2 &&
683
- sh_r8 != DOWNGRADE_PROTECTION_TLS_1_1
684
- end
685
-
686
- # @return [Boolean]
687
- def valid_sh_legacy_version?
688
- @transcript[CH].legacy_version ==
689
- @transcript[SH].legacy_version
690
- end
691
-
692
- # @return [Boolean]
693
- def valid_sh_legacy_session_id_echo?
694
- @transcript[CH].legacy_session_id ==
695
- @transcript[SH].legacy_session_id_echo
696
- end
697
-
698
- # @return [Boolean]
699
- def valid_sh_cipher_suite?
700
- @transcript[CH].cipher_suites.include?(@transcript[SH].cipher_suite)
701
- end
702
-
703
- # @return [Boolean]
704
- def valid_sh_compression_method?
705
- @transcript[SH].legacy_compression_method == "\x00"
706
- end
707
-
708
- # @param extensions [TTTLS13::Message::Extensions]
709
- # @param transcript_index [Integer]
710
- #
711
- # @return [Boolean]
712
- def offered_ch_extensions?(extensions, transcript_index = nil)
713
- keys = extensions.keys
714
- if transcript_index == HRR
715
- keys -= @transcript[CH1].extensions.keys
716
- keys -= [Message::ExtensionType::COOKIE]
717
- else
718
- keys -= @transcript[CH].extensions.keys
719
- end
720
- keys.empty?
721
- end
722
-
723
- # @return [Boolean]
724
- def received_2nd_hrr?
725
- @transcript.include?(HRR)
726
- end
727
-
728
- # @param cipher_suite [TTTLS13::CipherSuite]
729
- #
730
- # @return [Boolean]
731
- def neq_hrr_cipher_suite?(cipher_suite)
732
- cipher_suite != @transcript[HRR].cipher_suite
733
- end
734
748
 
735
- # @param versions [Array of TTTLS13::Message::ProtocolVersion]
736
- #
737
- # @return [Boolean]
738
- def neq_hrr_supported_versions?(versions)
739
- hrr = @transcript[HRR]
740
- versions != hrr.extensions[Message::ExtensionType::SUPPORTED_VERSIONS]
741
- .versions
742
- end
743
-
744
- # @return [Boolean]
745
- def valid_sh_key_share?
746
- offered = @transcript[CH].extensions[Message::ExtensionType::KEY_SHARE]
747
- .key_share_entry.map(&:group)
748
- selected = @transcript[SH].extensions[Message::ExtensionType::KEY_SHARE]
749
- .key_share_entry.first.group
750
- offered.include?(selected)
751
- end
752
-
753
- # @return [Boolean]
754
- def valid_hrr_key_share?
755
- # TODO: pre_shared_key
756
- ch1_exs = @transcript[CH1].extensions
757
- ngl = ch1_exs[Message::ExtensionType::SUPPORTED_GROUPS].named_group_list
758
- kse = ch1_exs[Message::ExtensionType::KEY_SHARE].key_share_entry
759
- group = @transcript[HRR].extensions[Message::ExtensionType::KEY_SHARE]
760
- .key_share_entry.first.group
761
-
762
- ngl.include?(group) && !kse.map(&:group).include?(group)
749
+ do_verified_certificate_verify?(
750
+ public_key: public_key,
751
+ signature_scheme: signature_scheme,
752
+ signature: signature,
753
+ context: 'TLS 1.3, server CertificateVerify',
754
+ hash: hash
755
+ )
763
756
  end
764
757
 
765
758
  # @param nst [TTTLS13::Message::NewSessionTicket]
@@ -768,7 +761,7 @@ module TTTLS13
768
761
  def process_new_session_ticket(nst)
769
762
  super(nst)
770
763
 
771
- rms = @key_schedule.resumption_master_secret
764
+ rms = @resumption_master_secret
772
765
  cs = @cipher_suite
773
766
  @settings[:process_new_session_ticket]&.call(nst, rms, cs)
774
767
  end