tttls1.3 0.3.4 → 0.3.5
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 +4 -2
- data/.rubocop.yml +16 -11
- data/.ruby-version +1 -1
- data/Gemfile +3 -3
- data/README.md +4 -4
- data/Rakefile +3 -3
- data/example/helper.rb +1 -1
- data/example/https_client_using_0rtt.rb +1 -1
- data/example/https_client_using_ech.rb +1 -1
- data/example/https_client_using_hrr_and_ech.rb +1 -1
- data/example/https_client_using_hrr_and_ticket.rb +1 -1
- data/example/https_client_using_status_request.rb +1 -1
- data/example/https_client_using_ticket.rb +1 -1
- data/example/https_client_using_ticket_and_ech.rb +3 -3
- data/example/https_server.rb +1 -1
- data/interop/client_spec.rb +57 -31
- data/interop/server_spec.rb +74 -46
- data/interop/spec_helper.rb +2 -2
- data/lib/tttls1.3/cipher_suites.rb +21 -16
- data/lib/tttls1.3/client.rb +86 -73
- data/lib/tttls1.3/connection.rb +6 -15
- data/lib/tttls1.3/cryptograph/aead.rb +26 -16
- data/lib/tttls1.3/ech.rb +11 -15
- data/lib/tttls1.3/endpoint.rb +4 -25
- data/lib/tttls1.3/key_schedule.rb +1 -1
- data/lib/tttls1.3/logging.rb +1 -1
- data/lib/tttls1.3/message/alert.rb +3 -4
- data/lib/tttls1.3/message/certificate.rb +4 -7
- data/lib/tttls1.3/message/certificate_verify.rb +3 -5
- data/lib/tttls1.3/message/client_hello.rb +9 -15
- data/lib/tttls1.3/message/compressed_certificate.rb +3 -9
- data/lib/tttls1.3/message/encrypted_extensions.rb +1 -2
- data/lib/tttls1.3/message/extension/alpn.rb +1 -6
- data/lib/tttls1.3/message/extension/compress_certificate.rb +1 -2
- data/lib/tttls1.3/message/extension/cookie.rb +1 -2
- data/lib/tttls1.3/message/extension/early_data_indication.rb +1 -2
- data/lib/tttls1.3/message/extension/ech.rb +9 -16
- data/lib/tttls1.3/message/extension/ech_outer_extensions.rb +1 -2
- data/lib/tttls1.3/message/extension/key_share.rb +17 -43
- data/lib/tttls1.3/message/extension/pre_shared_key.rb +8 -17
- data/lib/tttls1.3/message/extension/psk_key_exchange_modes.rb +1 -2
- data/lib/tttls1.3/message/extension/record_size_limit.rb +1 -2
- data/lib/tttls1.3/message/extension/server_name.rb +1 -2
- data/lib/tttls1.3/message/extension/signature_algorithms.rb +1 -2
- data/lib/tttls1.3/message/extension/status_request.rb +4 -12
- data/lib/tttls1.3/message/extension/supported_groups.rb +1 -4
- data/lib/tttls1.3/message/extension/supported_versions.rb +2 -8
- data/lib/tttls1.3/message/extension/unknown_extension.rb +2 -3
- data/lib/tttls1.3/message/extensions.rb +1 -7
- data/lib/tttls1.3/message/finished.rb +1 -2
- data/lib/tttls1.3/message/new_session_ticket.rb +6 -12
- data/lib/tttls1.3/message/record.rb +10 -23
- data/lib/tttls1.3/message/server_hello.rb +10 -21
- data/lib/tttls1.3/named_group.rb +12 -6
- data/lib/tttls1.3/server.rb +39 -34
- data/lib/tttls1.3/shared_secret.rb +118 -0
- data/lib/tttls1.3/utils.rb +0 -15
- data/lib/tttls1.3/version.rb +1 -1
- data/lib/tttls1.3.rb +1 -1
- data/spec/certificate_verify_spec.rb +1 -1
- data/spec/client_hello_spec.rb +4 -4
- data/spec/client_spec.rb +13 -13
- data/spec/endpoint_spec.rb +11 -11
- data/spec/key_schedule_spec.rb +4 -4
- data/spec/new_session_ticket_spec.rb +4 -4
- data/spec/pre_shared_key_spec.rb +8 -8
- data/spec/record_spec.rb +1 -1
- data/spec/server_hello_spec.rb +5 -5
- data/spec/server_spec.rb +8 -8
- data/tttls1.3.gemspec +2 -2
- metadata +7 -10
- data/example/https_client_using_grease_psk.rb +0 -58
data/lib/tttls1.3/client.rb
CHANGED
@@ -37,6 +37,7 @@ module TTTLS13
|
|
37
37
|
private_constant :DEFAULT_CH_SIGNATURE_ALGORITHMS
|
38
38
|
|
39
39
|
DEFAULT_CH_NAMED_GROUP_LIST = [
|
40
|
+
NamedGroup::X25519,
|
40
41
|
NamedGroup::SECP256R1,
|
41
42
|
NamedGroup::SECP384R1,
|
42
43
|
NamedGroup::SECP521R1
|
@@ -152,7 +153,6 @@ module TTTLS13
|
|
152
153
|
@transcript = Transcript.new
|
153
154
|
key_schedule = nil # TTTLS13::KeySchedule
|
154
155
|
psk = nil
|
155
|
-
priv_keys = {} # Hash of NamedGroup => OpenSSL::PKey::$Object
|
156
156
|
if use_psk?
|
157
157
|
psk = gen_psk_from_nst(
|
158
158
|
@settings[:resumption_secret],
|
@@ -160,13 +160,14 @@ module TTTLS13
|
|
160
160
|
CipherSuite.digest(@settings[:psk_cipher_suite])
|
161
161
|
)
|
162
162
|
key_schedule = KeySchedule.new(
|
163
|
-
psk
|
163
|
+
psk:,
|
164
164
|
shared_secret: nil,
|
165
165
|
cipher_suite: @settings[:psk_cipher_suite],
|
166
166
|
transcript: @transcript
|
167
167
|
)
|
168
168
|
end
|
169
169
|
|
170
|
+
shared_secret = nil # TTTLS13::SharedSecret
|
170
171
|
hs_wcipher = nil # TTTLS13::Cryptograph::$Object
|
171
172
|
hs_rcipher = nil # TTTLS13::Cryptograph::$Object
|
172
173
|
e_wcipher = nil # TTTLS13::Cryptograph::$Object
|
@@ -189,7 +190,7 @@ module TTTLS13
|
|
189
190
|
when ClientState::START
|
190
191
|
logger.debug('ClientState::START')
|
191
192
|
|
192
|
-
extensions,
|
193
|
+
extensions, shared_secret = gen_ch_extensions
|
193
194
|
binder_key = (use_psk? ? key_schedule.binder_key_res : nil)
|
194
195
|
ch, inner, ech_state = send_client_hello(extensions, binder_key)
|
195
196
|
ch_outer = ch
|
@@ -280,8 +281,7 @@ module TTTLS13
|
|
280
281
|
unless ngl.include?(group) && !kse.map(&:group).include?(group)
|
281
282
|
|
282
283
|
# send new client_hello
|
283
|
-
extensions,
|
284
|
-
priv_keys = pk.merge(priv_keys)
|
284
|
+
extensions, shared_secret = gen_newch_extensions(ch1, hrr)
|
285
285
|
binder_key = (use_psk? ? key_schedule.binder_key_res : nil)
|
286
286
|
ch, inner = send_new_client_hello(
|
287
287
|
ch1,
|
@@ -312,15 +312,14 @@ module TTTLS13
|
|
312
312
|
@connection.terminate(:illegal_parameter) unless ch_ks.include?(sh_ks)
|
313
313
|
|
314
314
|
kse = sh.extensions[Message::ExtensionType::KEY_SHARE]
|
315
|
-
.key_share_entry
|
315
|
+
.key_share_entry
|
316
|
+
.first
|
316
317
|
ke = kse.key_exchange
|
317
318
|
@named_group = kse.group
|
318
|
-
priv_key = priv_keys[@named_group]
|
319
|
-
shared_secret = Endpoint.gen_shared_secret(ke, priv_key, @named_group)
|
320
319
|
@cipher_suite = sh.cipher_suite
|
321
320
|
key_schedule = KeySchedule.new(
|
322
|
-
psk
|
323
|
-
shared_secret: shared_secret,
|
321
|
+
psk:,
|
322
|
+
shared_secret: shared_secret.build(@named_group, ke),
|
324
323
|
cipher_suite: @cipher_suite,
|
325
324
|
transcript: @transcript
|
326
325
|
)
|
@@ -456,7 +455,7 @@ module TTTLS13
|
|
456
455
|
@connection.terminate(:decrypt_error) \
|
457
456
|
unless Endpoint.verified_finished?(
|
458
457
|
finished: sf,
|
459
|
-
digest
|
458
|
+
digest:,
|
460
459
|
finished_key: key_schedule.server_finished_key,
|
461
460
|
hash: @transcript.hash(digest, CV)
|
462
461
|
)
|
@@ -467,7 +466,7 @@ module TTTLS13
|
|
467
466
|
end
|
468
467
|
# TODO: Send Certificate [+ CertificateVerify]
|
469
468
|
signature = Endpoint.sign_finished(
|
470
|
-
digest
|
469
|
+
digest:,
|
471
470
|
finished_key: key_schedule.client_finished_key,
|
472
471
|
hash: @transcript.hash(digest, EOED)
|
473
472
|
)
|
@@ -690,25 +689,49 @@ module TTTLS13
|
|
690
689
|
# rubocop: enable Metrics/CyclomaticComplexity
|
691
690
|
# rubocop: enable Metrics/PerceivedComplexity
|
692
691
|
|
692
|
+
# @return [Boolean]
|
693
|
+
def use_alpn?
|
694
|
+
!@settings[:alpn].nil? && !@settings[:alpn].empty?
|
695
|
+
end
|
696
|
+
|
697
|
+
# @return [Boolean]
|
698
|
+
def use_signature_algorithms_cert?
|
699
|
+
!@settings[:signature_algorithms_cert].nil? &&
|
700
|
+
!@settings[:signature_algorithms_cert].empty?
|
701
|
+
end
|
702
|
+
|
703
|
+
# @return [Boolean]
|
704
|
+
def use_compress_certificate?
|
705
|
+
!@settings[:compress_certificate_algorithms].nil? &&
|
706
|
+
!@settings[:compress_certificate_algorithms].empty?
|
707
|
+
end
|
708
|
+
|
709
|
+
# @return [Boolean]
|
710
|
+
def use_record_size_limit?
|
711
|
+
!@settings[:record_size_limit].nil?
|
712
|
+
end
|
713
|
+
|
693
714
|
# @return [Boolean]
|
694
715
|
def use_psk?
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
716
|
+
%i[
|
717
|
+
ticket
|
718
|
+
resumption_secret
|
719
|
+
psk_cipher_suite
|
720
|
+
ticket_nonce
|
721
|
+
ticket_age_add
|
722
|
+
ticket_timestamp
|
723
|
+
].all? { |sy| !@settings[sy].nil? }
|
701
724
|
end
|
702
725
|
|
703
726
|
# @return [Boolean]
|
704
727
|
def use_early_data?
|
705
|
-
|
728
|
+
!@early_data.nil? && !@early_data.empty?
|
706
729
|
end
|
707
730
|
|
708
731
|
# @return [Boolean]
|
709
732
|
def use_ech?
|
710
|
-
|
711
|
-
|
733
|
+
ehcs = @settings[:ech_hpke_cipher_suites]
|
734
|
+
!ehcs.nil? && !ehcs.empty?
|
712
735
|
end
|
713
736
|
|
714
737
|
# @param cipher [TTTLS13::Cryptograph::Aead]
|
@@ -718,7 +741,7 @@ module TTTLS13
|
|
718
741
|
type: Message::ContentType::APPLICATION_DATA,
|
719
742
|
legacy_record_version: Message::ProtocolVersion::TLS_1_2,
|
720
743
|
messages: [ap],
|
721
|
-
cipher:
|
744
|
+
cipher:
|
722
745
|
)
|
723
746
|
@connection.send_record(ap_record)
|
724
747
|
end
|
@@ -735,18 +758,16 @@ module TTTLS13
|
|
735
758
|
end
|
736
759
|
|
737
760
|
# @return [TTTLS13::Message::Extensions]
|
738
|
-
# @return [
|
761
|
+
# @return [TTTLS13::SharedSecret]
|
739
762
|
# rubocop: disable Metrics/AbcSize
|
740
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
741
763
|
# rubocop: disable Metrics/MethodLength
|
742
|
-
# rubocop: disable Metrics/PerceivedComplexity
|
743
764
|
def gen_ch_extensions
|
744
765
|
exs = Message::Extensions.new
|
745
766
|
# server_name
|
746
767
|
exs << Message::Extension::ServerName.new(@hostname)
|
747
768
|
|
748
769
|
# record_size_limit
|
749
|
-
|
770
|
+
if use_record_size_limit?
|
750
771
|
exs << Message::Extension::RecordSizeLimit.new(
|
751
772
|
@settings[:record_size_limit]
|
752
773
|
)
|
@@ -763,8 +784,7 @@ module TTTLS13
|
|
763
784
|
)
|
764
785
|
|
765
786
|
# signature_algorithms_cert
|
766
|
-
if
|
767
|
-
!@settings[:signature_algorithms_cert].empty?
|
787
|
+
if use_signature_algorithms_cert?
|
768
788
|
exs << Message::Extension::SignatureAlgorithmsCert.new(
|
769
789
|
@settings[:signature_algorithms_cert]
|
770
790
|
)
|
@@ -776,7 +796,7 @@ module TTTLS13
|
|
776
796
|
|
777
797
|
# key_share
|
778
798
|
ksg = @settings[:key_share_groups] || groups
|
779
|
-
key_share,
|
799
|
+
key_share, shared_secret \
|
780
800
|
= Message::Extension::KeyShare.gen_ch_key_share(ksg)
|
781
801
|
exs << key_share
|
782
802
|
|
@@ -784,28 +804,24 @@ module TTTLS13
|
|
784
804
|
exs << Message::Extension::EarlyDataIndication.new if use_early_data?
|
785
805
|
|
786
806
|
# alpn
|
787
|
-
exs << Message::Extension::Alpn.new(@settings[:alpn]
|
788
|
-
if !@settings[:alpn].nil? && !@settings[:alpn].empty?
|
807
|
+
exs << Message::Extension::Alpn.new(@settings[:alpn]) if use_alpn?
|
789
808
|
|
790
809
|
# status_request
|
791
810
|
exs << Message::Extension::OCSPStatusRequest.new \
|
792
811
|
if @settings[:check_certificate_status]
|
793
812
|
|
794
813
|
# compress_certificate
|
795
|
-
if
|
796
|
-
!@settings[:compress_certificate_algorithms].empty?
|
814
|
+
if use_compress_certificate?
|
797
815
|
exs << Message::Extension::CompressCertificate.new(
|
798
816
|
@settings[:compress_certificate_algorithms]
|
799
817
|
)
|
800
818
|
end
|
801
819
|
|
802
|
-
[exs,
|
820
|
+
[exs, shared_secret]
|
803
821
|
end
|
822
|
+
|
804
823
|
# rubocop: enable Metrics/AbcSize
|
805
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
806
824
|
# rubocop: enable Metrics/MethodLength
|
807
|
-
# rubocop: enable Metrics/PerceivedComplexity
|
808
|
-
|
809
825
|
# @param extensions [TTTLS13::Message::Extensions]
|
810
826
|
# @param binder_key [String, nil]
|
811
827
|
#
|
@@ -816,7 +832,7 @@ module TTTLS13
|
|
816
832
|
def send_client_hello(extensions, binder_key = nil)
|
817
833
|
ch = Message::ClientHello.new(
|
818
834
|
cipher_suites: CipherSuites.new(@settings[:cipher_suites]),
|
819
|
-
extensions:
|
835
|
+
extensions:
|
820
836
|
)
|
821
837
|
|
822
838
|
# encrypted_client_hello
|
@@ -849,8 +865,8 @@ module TTTLS13
|
|
849
865
|
# at the end, sign PSK binder
|
850
866
|
if use_psk?
|
851
867
|
sign_psk_binder(
|
852
|
-
ch
|
853
|
-
binder_key:
|
868
|
+
ch:,
|
869
|
+
binder_key:
|
854
870
|
)
|
855
871
|
|
856
872
|
if use_ech?
|
@@ -874,7 +890,7 @@ module TTTLS13
|
|
874
890
|
# @param binder_key [String]
|
875
891
|
#
|
876
892
|
# @return [String]
|
877
|
-
def sign_psk_binder(ch1: nil, hrr: nil
|
893
|
+
def sign_psk_binder(ch:, binder_key:, ch1: nil, hrr: nil)
|
878
894
|
# pre_shared_key
|
879
895
|
#
|
880
896
|
# binder is computed as an HMAC over a transcript hash containing a
|
@@ -898,11 +914,11 @@ module TTTLS13
|
|
898
914
|
ch.extensions[Message::ExtensionType::PRE_SHARED_KEY] = psk
|
899
915
|
|
900
916
|
psk.offered_psks.binders[0] = Endpoint.sign_psk_binder(
|
901
|
-
ch1
|
902
|
-
hrr
|
903
|
-
ch
|
904
|
-
binder_key
|
905
|
-
digest:
|
917
|
+
ch1:,
|
918
|
+
hrr:,
|
919
|
+
ch:,
|
920
|
+
binder_key:,
|
921
|
+
digest:
|
906
922
|
)
|
907
923
|
end
|
908
924
|
|
@@ -913,11 +929,8 @@ module TTTLS13
|
|
913
929
|
# @param binder_key [String]
|
914
930
|
#
|
915
931
|
# @return [String]
|
916
|
-
def sign_grease_psk_binder(ch1: nil,
|
917
|
-
hrr: nil
|
918
|
-
ch_outer:,
|
919
|
-
inner_psk:,
|
920
|
-
binder_key:)
|
932
|
+
def sign_grease_psk_binder(ch_outer:, inner_psk:, binder_key:, ch1: nil,
|
933
|
+
hrr: nil)
|
921
934
|
digest = CipherSuite.digest(@settings[:psk_cipher_suite])
|
922
935
|
hash_len = OpenSSL::Digest.new(digest).digest_length
|
923
936
|
placeholder_binders = [hash_len.zeros]
|
@@ -939,7 +952,7 @@ module TTTLS13
|
|
939
952
|
msg_type: Message::HandshakeType::CLIENT_HELLO,
|
940
953
|
offered_psks: Message::Extension::OfferedPsks.new(
|
941
954
|
identities: [Message::Extension::PskIdentity.new(
|
942
|
-
identity
|
955
|
+
identity:,
|
943
956
|
obfuscated_ticket_age: ota
|
944
957
|
)],
|
945
958
|
binders: placeholder_binders
|
@@ -948,11 +961,11 @@ module TTTLS13
|
|
948
961
|
ch_outer.extensions[Message::ExtensionType::PRE_SHARED_KEY] = psk
|
949
962
|
|
950
963
|
psk.offered_psks.binders[0] = Endpoint.sign_psk_binder(
|
951
|
-
ch1
|
952
|
-
hrr
|
964
|
+
ch1:,
|
965
|
+
hrr:,
|
953
966
|
ch: ch_outer,
|
954
|
-
binder_key
|
955
|
-
digest:
|
967
|
+
binder_key:,
|
968
|
+
digest:
|
956
969
|
)
|
957
970
|
end
|
958
971
|
|
@@ -977,14 +990,14 @@ module TTTLS13
|
|
977
990
|
# @param hrr [TTTLS13::Message::ServerHello]
|
978
991
|
#
|
979
992
|
# @return [TTTLS13::Message::Extensions]
|
980
|
-
# @return [
|
993
|
+
# @return [TTTLS13::SharedSecret]
|
981
994
|
def gen_newch_extensions(ch1, hrr)
|
982
995
|
exs = Message::Extensions.new
|
983
996
|
# key_share
|
984
997
|
if hrr.extensions.include?(Message::ExtensionType::KEY_SHARE)
|
985
998
|
group = hrr.extensions[Message::ExtensionType::KEY_SHARE]
|
986
999
|
.key_share_entry.first.group
|
987
|
-
key_share,
|
1000
|
+
key_share, shared_secret \
|
988
1001
|
= Message::Extension::KeyShare.gen_ch_key_share([group])
|
989
1002
|
exs << key_share
|
990
1003
|
end
|
@@ -1004,7 +1017,7 @@ module TTTLS13
|
|
1004
1017
|
new_exs = ch1.extensions.merge(exs)
|
1005
1018
|
new_exs.delete(Message::ExtensionType::EARLY_DATA)
|
1006
1019
|
|
1007
|
-
[new_exs,
|
1020
|
+
[new_exs, shared_secret]
|
1008
1021
|
end
|
1009
1022
|
|
1010
1023
|
# https://datatracker.ietf.org/doc/html/rfc8446#section-4.1.2
|
@@ -1030,7 +1043,7 @@ module TTTLS13
|
|
1030
1043
|
legacy_session_id: ch1.legacy_session_id,
|
1031
1044
|
cipher_suites: ch1.cipher_suites,
|
1032
1045
|
legacy_compression_methods: ch1.legacy_compression_methods,
|
1033
|
-
extensions:
|
1046
|
+
extensions:
|
1034
1047
|
)
|
1035
1048
|
|
1036
1049
|
# encrypted_client_hello
|
@@ -1052,7 +1065,7 @@ module TTTLS13
|
|
1052
1065
|
# Updating the "pre_shared_key" extension if present by recomputing
|
1053
1066
|
# the "obfuscated_ticket_age" and binder values.
|
1054
1067
|
if ch1.extensions.include?(Message::ExtensionType::PRE_SHARED_KEY)
|
1055
|
-
sign_psk_binder(ch1
|
1068
|
+
sign_psk_binder(ch1:, hrr:, ch:, binder_key:)
|
1056
1069
|
|
1057
1070
|
if use_ech?
|
1058
1071
|
# it MUST also copy the "psk_key_exchange_modes" from the
|
@@ -1063,11 +1076,11 @@ module TTTLS13
|
|
1063
1076
|
ch.extensions[Message::ExtensionType::EARLY_DATA] \
|
1064
1077
|
= inner.extensions[Message::ExtensionType::EARLY_DATA]
|
1065
1078
|
sign_grease_psk_binder(
|
1066
|
-
ch1
|
1067
|
-
hrr
|
1079
|
+
ch1:,
|
1080
|
+
hrr:,
|
1068
1081
|
ch_outer: ch,
|
1069
1082
|
inner_psk: inner.extensions[Message::ExtensionType::PRE_SHARED_KEY],
|
1070
|
-
binder_key:
|
1083
|
+
binder_key:
|
1071
1084
|
)
|
1072
1085
|
end
|
1073
1086
|
end
|
@@ -1103,7 +1116,7 @@ module TTTLS13
|
|
1103
1116
|
# @return [String]
|
1104
1117
|
def recv_encrypted_extensions(cipher)
|
1105
1118
|
ee, orig_msg \
|
1106
|
-
= @connection.recv_message(receivable_ccs: true, cipher:
|
1119
|
+
= @connection.recv_message(receivable_ccs: true, cipher:)
|
1107
1120
|
@connection.terminate(:unexpected_message) \
|
1108
1121
|
unless ee.is_a?(Message::EncryptedExtensions)
|
1109
1122
|
|
@@ -1118,7 +1131,7 @@ module TTTLS13
|
|
1118
1131
|
# @return [String]
|
1119
1132
|
def recv_certificate(cipher)
|
1120
1133
|
ct, orig_msg \
|
1121
|
-
= @connection.recv_message(receivable_ccs: true, cipher:
|
1134
|
+
= @connection.recv_message(receivable_ccs: true, cipher:)
|
1122
1135
|
@connection.terminate(:unexpected_message) \
|
1123
1136
|
unless ct.is_a?(Message::Certificate)
|
1124
1137
|
|
@@ -1133,7 +1146,7 @@ module TTTLS13
|
|
1133
1146
|
# @return [String]
|
1134
1147
|
def recv_certificate_verify(cipher)
|
1135
1148
|
cv, orig_msg \
|
1136
|
-
= @connection.recv_message(receivable_ccs: true, cipher:
|
1149
|
+
= @connection.recv_message(receivable_ccs: true, cipher:)
|
1137
1150
|
@connection.terminate(:unexpected_message) \
|
1138
1151
|
unless cv.is_a?(Message::CertificateVerify)
|
1139
1152
|
|
@@ -1148,7 +1161,7 @@ module TTTLS13
|
|
1148
1161
|
# @return [String]
|
1149
1162
|
def recv_finished(cipher)
|
1150
1163
|
sf, orig_msg \
|
1151
|
-
= @connection.recv_message(receivable_ccs: true, cipher:
|
1164
|
+
= @connection.recv_message(receivable_ccs: true, cipher:)
|
1152
1165
|
@connection.terminate(:unexpected_message) \
|
1153
1166
|
unless sf.is_a?(Message::Finished)
|
1154
1167
|
|
@@ -1203,7 +1216,7 @@ module TTTLS13
|
|
1203
1216
|
if @settings[:check_certificate_status]
|
1204
1217
|
ee = ct.certificate_list.first
|
1205
1218
|
ocsp_response = ee.extensions[Message::ExtensionType::STATUS_REQUEST]
|
1206
|
-
|
1219
|
+
&.ocsp_response
|
1207
1220
|
cert = ee.cert_data
|
1208
1221
|
chain = ct.certificate_list[1..]&.map(&:cert_data)
|
1209
1222
|
return :bad_certificate_status_response \
|
@@ -1224,11 +1237,11 @@ module TTTLS13
|
|
1224
1237
|
signature = cv.signature
|
1225
1238
|
|
1226
1239
|
Endpoint.verified_certificate_verify?(
|
1227
|
-
public_key
|
1228
|
-
signature_scheme
|
1229
|
-
signature
|
1240
|
+
public_key:,
|
1241
|
+
signature_scheme:,
|
1242
|
+
signature:,
|
1230
1243
|
context: 'TLS 1.3, server CertificateVerify',
|
1231
|
-
hash:
|
1244
|
+
hash:
|
1232
1245
|
)
|
1233
1246
|
end
|
1234
1247
|
|
data/lib/tttls1.3/connection.rb
CHANGED
@@ -9,10 +9,7 @@ module TTTLS13
|
|
9
9
|
class Connection
|
10
10
|
include Logging
|
11
11
|
|
12
|
-
attr_accessor :state
|
13
|
-
attr_accessor :ap_wcipher
|
14
|
-
attr_accessor :ap_rcipher
|
15
|
-
attr_accessor :alert_wcipher
|
12
|
+
attr_accessor :state, :ap_wcipher, :ap_rcipher, :alert_wcipher
|
16
13
|
|
17
14
|
# @param socket [Socket]
|
18
15
|
# @param side [:client or :server]
|
@@ -34,8 +31,6 @@ module TTTLS13
|
|
34
31
|
# @raise [TTTLS13::Error::ConfigError]
|
35
32
|
#
|
36
33
|
# @return [String]
|
37
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
38
|
-
# rubocop: disable Metrics/PerceivedComplexity
|
39
34
|
def read(nst_process)
|
40
35
|
# secure channel has not established yet
|
41
36
|
raise Error::ConfigError \
|
@@ -58,8 +53,6 @@ module TTTLS13
|
|
58
53
|
|
59
54
|
message.fragment
|
60
55
|
end
|
61
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
62
|
-
# rubocop: enable Metrics/PerceivedComplexity
|
63
56
|
|
64
57
|
# @return [Boolean]
|
65
58
|
def eof?
|
@@ -91,9 +84,9 @@ module TTTLS13
|
|
91
84
|
# @param cipher [TTTLS13::Cryptograph::Aead, Passer]
|
92
85
|
def send_handshakes(type, messages, cipher)
|
93
86
|
record = Message::Record.new(
|
94
|
-
type
|
95
|
-
messages
|
96
|
-
cipher:
|
87
|
+
type:,
|
88
|
+
messages:,
|
89
|
+
cipher:
|
97
90
|
)
|
98
91
|
send_record(record)
|
99
92
|
end
|
@@ -115,7 +108,7 @@ module TTTLS13
|
|
115
108
|
type: Message::ContentType::APPLICATION_DATA,
|
116
109
|
legacy_record_version: Message::ProtocolVersion::TLS_1_2,
|
117
110
|
messages: [message],
|
118
|
-
cipher:
|
111
|
+
cipher:
|
119
112
|
)
|
120
113
|
send_record(ap_record)
|
121
114
|
end
|
@@ -129,7 +122,7 @@ module TTTLS13
|
|
129
122
|
type = Message::ContentType::APPLICATION_DATA \
|
130
123
|
if @alert_wcipher.is_a?(Cryptograph::Aead)
|
131
124
|
alert_record = Message::Record.new(
|
132
|
-
type
|
125
|
+
type:,
|
133
126
|
legacy_record_version: Message::ProtocolVersion::TLS_1_2,
|
134
127
|
messages: [message],
|
135
128
|
cipher: @alert_wcipher
|
@@ -150,7 +143,6 @@ module TTTLS13
|
|
150
143
|
#
|
151
144
|
# @return [TTTLS13::Message::$Object]
|
152
145
|
# @return [String]
|
153
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
154
146
|
def recv_message(receivable_ccs:, cipher:)
|
155
147
|
return @message_queue.shift unless @message_queue.empty?
|
156
148
|
|
@@ -184,7 +176,6 @@ module TTTLS13
|
|
184
176
|
|
185
177
|
[message, orig_msg]
|
186
178
|
end
|
187
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
188
179
|
|
189
180
|
# @param cipher [TTTLS13::Cryptograph::Aead, Passer]
|
190
181
|
#
|
@@ -17,14 +17,15 @@ module TTTLS13
|
|
17
17
|
@cipher_suite = cipher_suite
|
18
18
|
case cipher_suite
|
19
19
|
when CipherSuite::TLS_AES_128_GCM_SHA256
|
20
|
-
@cipher = OpenSSL::Cipher
|
20
|
+
@cipher = OpenSSL::Cipher.new('aes-128-gcm')
|
21
21
|
when CipherSuite::TLS_AES_256_GCM_SHA384
|
22
|
-
@cipher = OpenSSL::Cipher
|
22
|
+
@cipher = OpenSSL::Cipher.new('aes-256-gcm')
|
23
23
|
when CipherSuite::TLS_CHACHA20_POLY1305_SHA256
|
24
24
|
@cipher = OpenSSL::Cipher.new('chacha20-poly1305')
|
25
|
+
when CipherSuite::TLS_AES_128_CCM_SHA256,
|
26
|
+
CipherSuite::TLS_AES_128_CCM_8_SHA256
|
27
|
+
@cipher = OpenSSL::Cipher.new('aes-128-ccm')
|
25
28
|
else
|
26
|
-
# CipherSuite::TLS_AES_128_CCM_SHA256
|
27
|
-
# CipherSuite::TLS_AES_128_CCM_8_SHA256
|
28
29
|
raise Error::ErrorAlerts, :internal_error
|
29
30
|
end
|
30
31
|
@write_key = write_key
|
@@ -42,12 +43,14 @@ module TTTLS13
|
|
42
43
|
# @return [String]
|
43
44
|
def encrypt(content, type)
|
44
45
|
cipher = reset_cipher
|
45
|
-
|
46
|
-
cipher.
|
47
|
-
|
46
|
+
plain_text = content + type + @length_of_padding.zeros
|
47
|
+
cipher.ccm_data_len = plain_text.length \
|
48
|
+
if CipherSuite.ccm?(@cipher_suite)
|
49
|
+
cipher.auth_data = additional_data(plain_text.length)
|
50
|
+
cipher_text = cipher.update(plain_text) + cipher.final
|
48
51
|
@sequence_number.succ
|
49
52
|
|
50
|
-
|
53
|
+
cipher_text + cipher.auth_tag
|
51
54
|
end
|
52
55
|
|
53
56
|
# AEAD-Decrypt(peer_write_key, nonce,
|
@@ -62,16 +65,19 @@ module TTTLS13
|
|
62
65
|
# @return [TTTLS13::Message::ContentType]
|
63
66
|
def decrypt(encrypted_record, auth_data)
|
64
67
|
decipher = reset_decipher
|
65
|
-
|
68
|
+
cipher_text = encrypted_record[0...-@auth_tag_len]
|
69
|
+
decipher.ccm_data_len = cipher_text.length \
|
70
|
+
if CipherSuite.ccm?(@cipher_suite)
|
71
|
+
auth_tag = encrypted_record[-@auth_tag_len..]
|
66
72
|
decipher.auth_tag = auth_tag
|
67
73
|
decipher.auth_data = auth_data # record header of TLSCiphertext
|
68
|
-
|
74
|
+
plain_text = decipher.update(cipher_text)
|
69
75
|
decipher.final
|
70
|
-
zeros_len = scan_zeros(
|
76
|
+
zeros_len = scan_zeros(plain_text)
|
71
77
|
postfix_len = 1 + zeros_len # type || zeros
|
72
78
|
@sequence_number.succ
|
73
79
|
|
74
|
-
[
|
80
|
+
[plain_text[0...-postfix_len], plain_text[-postfix_len]]
|
75
81
|
end
|
76
82
|
|
77
83
|
# struct {
|
@@ -102,9 +108,11 @@ module TTTLS13
|
|
102
108
|
def reset_cipher
|
103
109
|
cipher = @cipher.encrypt
|
104
110
|
cipher.reset
|
111
|
+
cipher.auth_tag_len = @auth_tag_len \
|
112
|
+
if CipherSuite.ccm?(@cipher_suite)
|
113
|
+
cipher.iv_len = CipherSuite.iv_len(@cipher_suite)
|
105
114
|
cipher.key = @write_key
|
106
|
-
|
107
|
-
cipher.iv = @sequence_number.xor(@write_iv, iv_len)
|
115
|
+
cipher.iv = @sequence_number.xor(@write_iv, cipher.iv_len)
|
108
116
|
|
109
117
|
cipher
|
110
118
|
end
|
@@ -113,9 +121,11 @@ module TTTLS13
|
|
113
121
|
def reset_decipher
|
114
122
|
decipher = @cipher.decrypt
|
115
123
|
decipher.reset
|
124
|
+
decipher.auth_tag_len = @auth_tag_len \
|
125
|
+
if CipherSuite.ccm?(@cipher_suite)
|
126
|
+
decipher.iv_len = CipherSuite.iv_len(@cipher_suite)
|
116
127
|
decipher.key = @write_key
|
117
|
-
|
118
|
-
decipher.iv = @sequence_number.xor(@write_iv, iv_len)
|
128
|
+
decipher.iv = @sequence_number.xor(@write_iv, decipher.iv_len)
|
119
129
|
|
120
130
|
decipher
|
121
131
|
end
|
data/lib/tttls1.3/ech.rb
CHANGED
@@ -209,9 +209,9 @@ module TTTLS13
|
|
209
209
|
payload_len,
|
210
210
|
server_name)
|
211
211
|
aad_ech = Message::Extension::ECHClientHello.new_outer(
|
212
|
-
cipher_suite
|
213
|
-
config_id
|
214
|
-
enc
|
212
|
+
cipher_suite:,
|
213
|
+
config_id:,
|
214
|
+
enc:,
|
215
215
|
payload: payload_len.zeros
|
216
216
|
)
|
217
217
|
Message::ClientHello.new(
|
@@ -237,10 +237,10 @@ module TTTLS13
|
|
237
237
|
# @return [TTTLS13::Message::ClientHello]
|
238
238
|
def self.new_ch_outer(aad, cipher_suite, config_id, enc, payload)
|
239
239
|
outer_ech = Message::Extension::ECHClientHello.new_outer(
|
240
|
-
cipher_suite
|
241
|
-
config_id
|
242
|
-
enc
|
243
|
-
payload:
|
240
|
+
cipher_suite:,
|
241
|
+
config_id:,
|
242
|
+
enc:,
|
243
|
+
payload:
|
244
244
|
)
|
245
245
|
Message::ClientHello.new(
|
246
246
|
legacy_version: aad.legacy_version,
|
@@ -284,16 +284,16 @@ module TTTLS13
|
|
284
284
|
+ aead_id2overhead_len(AeadId::AES_128_GCM)
|
285
285
|
|
286
286
|
Message::Extension::ECHClientHello.new_outer(
|
287
|
-
cipher_suite
|
287
|
+
cipher_suite:,
|
288
288
|
config_id: Convert.bin2i(OpenSSL::Random.random_bytes(1)),
|
289
|
-
enc
|
289
|
+
enc:,
|
290
290
|
payload: OpenSSL::Random.random_bytes(payload_len)
|
291
291
|
)
|
292
292
|
end
|
293
293
|
|
294
294
|
# @return [Integer]
|
295
295
|
def self.placeholder_encoded_ch_inner_len
|
296
|
-
|
296
|
+
480
|
297
297
|
end
|
298
298
|
|
299
299
|
# @param inner [TTTLS13::Message::ClientHello]
|
@@ -399,11 +399,7 @@ module TTTLS13
|
|
399
399
|
end
|
400
400
|
|
401
401
|
class EchState
|
402
|
-
attr_reader :maximum_name_length
|
403
|
-
attr_reader :config_id
|
404
|
-
attr_reader :cipher_suite
|
405
|
-
attr_reader :public_name
|
406
|
-
attr_reader :ctx
|
402
|
+
attr_reader :maximum_name_length, :config_id, :cipher_suite, :public_name, :ctx
|
407
403
|
|
408
404
|
# @param maximum_name_length [Integer]
|
409
405
|
# @param config_id [Integer]
|