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
@@ -10,9 +10,7 @@ module TTTLS13
|
|
10
10
|
end
|
11
11
|
|
12
12
|
class OCSPStatusRequest
|
13
|
-
attr_reader :extension_type
|
14
|
-
attr_reader :responder_id_list
|
15
|
-
attr_reader :request_extensions
|
13
|
+
attr_reader :extension_type, :responder_id_list, :request_extensions
|
16
14
|
|
17
15
|
# @param responder_id_list [Array of OpenSSL::ASN1::ASN1Data]
|
18
16
|
# @param request_extensions [Array of OpenSSL::ASN1::ASN1Data]
|
@@ -43,8 +41,6 @@ module TTTLS13
|
|
43
41
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
44
42
|
#
|
45
43
|
# @return [TTTLS13::Message::Extension::OCSPStatusRequest, nil]
|
46
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
47
|
-
# rubocop: disable Metrics/PerceivedComplexity
|
48
44
|
def self.deserialize(binary)
|
49
45
|
raise Error::ErrorAlerts, :internal_error if binary.nil?
|
50
46
|
return nil if binary.length < 5 ||
|
@@ -71,12 +67,9 @@ module TTTLS13
|
|
71
67
|
i += re_len
|
72
68
|
return nil unless i == binary.length
|
73
69
|
|
74
|
-
OCSPStatusRequest.new(responder_id_list
|
75
|
-
request_extensions:
|
70
|
+
OCSPStatusRequest.new(responder_id_list:,
|
71
|
+
request_extensions:)
|
76
72
|
end
|
77
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
78
|
-
# rubocop: enable Metrics/PerceivedComplexity
|
79
|
-
|
80
73
|
class << self
|
81
74
|
private
|
82
75
|
|
@@ -111,8 +104,7 @@ module TTTLS13
|
|
111
104
|
end
|
112
105
|
|
113
106
|
class OCSPResponse
|
114
|
-
attr_reader :extension_type
|
115
|
-
attr_reader :ocsp_response
|
107
|
+
attr_reader :extension_type, :ocsp_response
|
116
108
|
|
117
109
|
# @param ocsp_response [OpenSSL::OCSP::Response]
|
118
110
|
#
|
@@ -6,8 +6,7 @@ module TTTLS13
|
|
6
6
|
module Message
|
7
7
|
module Extension
|
8
8
|
class SupportedGroups
|
9
|
-
attr_reader :extension_type
|
10
|
-
attr_reader :named_group_list
|
9
|
+
attr_reader :extension_type, :named_group_list
|
11
10
|
|
12
11
|
# @param named_group_list [Array of NamedGroup]
|
13
12
|
#
|
@@ -31,7 +30,6 @@ module TTTLS13
|
|
31
30
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
32
31
|
#
|
33
32
|
# @return [TTTLS13::Message::Extension::SupportedGroups, nil]
|
34
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
35
33
|
def self.deserialize(binary)
|
36
34
|
raise Error::ErrorAlerts, :internal_error if binary.nil?
|
37
35
|
|
@@ -51,7 +49,6 @@ module TTTLS13
|
|
51
49
|
|
52
50
|
SupportedGroups.new(named_group_list)
|
53
51
|
end
|
54
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
55
52
|
end
|
56
53
|
end
|
57
54
|
end
|
@@ -6,15 +6,12 @@ module TTTLS13
|
|
6
6
|
module Message
|
7
7
|
module Extension
|
8
8
|
class SupportedVersions
|
9
|
-
attr_reader :extension_type
|
10
|
-
attr_reader :msg_type
|
11
|
-
attr_reader :versions
|
9
|
+
attr_reader :extension_type, :msg_type, :versions
|
12
10
|
|
13
11
|
# @param msg_type [TTTLS13::Message::ContentType]
|
14
12
|
# @param versions [Array of ProtocolVersion]
|
15
13
|
#
|
16
14
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
17
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
18
15
|
def initialize(msg_type:, versions: DEFAULT_VERSIONS)
|
19
16
|
@extension_type = ExtensionType::SUPPORTED_VERSIONS
|
20
17
|
@msg_type = msg_type
|
@@ -30,7 +27,6 @@ module TTTLS13
|
|
30
27
|
raise Error::ErrorAlerts, :internal_error
|
31
28
|
end
|
32
29
|
end
|
33
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
34
30
|
|
35
31
|
# @return [String]
|
36
32
|
def serialize
|
@@ -64,7 +60,7 @@ module TTTLS13
|
|
64
60
|
else
|
65
61
|
return nil
|
66
62
|
end
|
67
|
-
SupportedVersions.new(msg_type
|
63
|
+
SupportedVersions.new(msg_type:, versions:)
|
68
64
|
end
|
69
65
|
|
70
66
|
# @param binary [String]
|
@@ -72,7 +68,6 @@ module TTTLS13
|
|
72
68
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
73
69
|
#
|
74
70
|
# @return [Array of String, nil]
|
75
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
76
71
|
def self.deserialize_versions(binary)
|
77
72
|
raise Error::ErrorAlerts, :internal_error if binary.nil?
|
78
73
|
|
@@ -91,7 +86,6 @@ module TTTLS13
|
|
91
86
|
|
92
87
|
versions
|
93
88
|
end
|
94
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
95
89
|
end
|
96
90
|
end
|
97
91
|
end
|
@@ -8,8 +8,7 @@ module TTTLS13
|
|
8
8
|
# Client/Server MUST ignore unrecognized extensions,
|
9
9
|
# but transcript MUST include unrecognized extensions.
|
10
10
|
class UnknownExtension
|
11
|
-
attr_reader :extension_type
|
12
|
-
attr_reader :extension_data
|
11
|
+
attr_reader :extension_type, :extension_data
|
13
12
|
|
14
13
|
# @param extension_type [String]
|
15
14
|
# @param extension_data [String]
|
@@ -28,7 +27,7 @@ module TTTLS13
|
|
28
27
|
#
|
29
28
|
# @return [TTTLS13::Message::Extension::UnknownExtension]
|
30
29
|
def self.deserialize(binary, extension_type)
|
31
|
-
UnknownExtension.new(extension_type
|
30
|
+
UnknownExtension.new(extension_type:,
|
32
31
|
extension_data: binary)
|
33
32
|
end
|
34
33
|
end
|
@@ -43,8 +43,6 @@ module TTTLS13
|
|
43
43
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
44
44
|
#
|
45
45
|
# @return [TTTLS13::Message::Extensions]
|
46
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
47
|
-
# rubocop: disable Metrics/PerceivedComplexity
|
48
46
|
def self.deserialize(binary, msg_type)
|
49
47
|
raise Error::ErrorAlerts, :internal_error if binary.nil?
|
50
48
|
|
@@ -64,7 +62,7 @@ module TTTLS13
|
|
64
62
|
ex = deserialize_extension(ex_bin, extension_type, msg_type)
|
65
63
|
if ex.nil?
|
66
64
|
# ignore unparsable binary, but only transcript
|
67
|
-
ex = Extension::UnknownExtension.new(extension_type
|
65
|
+
ex = Extension::UnknownExtension.new(extension_type:,
|
68
66
|
extension_data: ex_bin)
|
69
67
|
end
|
70
68
|
|
@@ -80,8 +78,6 @@ module TTTLS13
|
|
80
78
|
|
81
79
|
exs
|
82
80
|
end
|
83
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
84
|
-
# rubocop: enable Metrics/PerceivedComplexity
|
85
81
|
|
86
82
|
# @param key [TTTLS13::Message::ExtensionType]
|
87
83
|
# @param default
|
@@ -149,7 +145,6 @@ module TTTLS13
|
|
149
145
|
# rubocop: disable Metrics/AbcSize
|
150
146
|
# rubocop: disable Metrics/CyclomaticComplexity
|
151
147
|
# rubocop: disable Metrics/MethodLength
|
152
|
-
# rubocop: disable Metrics/PerceivedComplexity
|
153
148
|
def deserialize_extension(binary, extension_type, msg_type)
|
154
149
|
raise Error::ErrorAlerts, :internal_error if binary.nil?
|
155
150
|
|
@@ -208,7 +203,6 @@ module TTTLS13
|
|
208
203
|
# rubocop: enable Metrics/AbcSize
|
209
204
|
# rubocop: enable Metrics/CyclomaticComplexity
|
210
205
|
# rubocop: enable Metrics/MethodLength
|
211
|
-
# rubocop: enable Metrics/PerceivedComplexity
|
212
206
|
end
|
213
207
|
end
|
214
208
|
# rubocop: enable Metrics/ClassLength
|
@@ -11,13 +11,7 @@ module TTTLS13
|
|
11
11
|
private_constant :APPEARABLE_NST_EXTENSIONS
|
12
12
|
|
13
13
|
class NewSessionTicket
|
14
|
-
attr_reader :msg_type
|
15
|
-
attr_reader :ticket_lifetime
|
16
|
-
attr_reader :ticket_age_add
|
17
|
-
attr_reader :ticket_nonce
|
18
|
-
attr_reader :ticket
|
19
|
-
attr_reader :extensions
|
20
|
-
attr_reader :timestamp
|
14
|
+
attr_reader :msg_type, :ticket_lifetime, :ticket_age_add, :ticket_nonce, :ticket, :extensions, :timestamp
|
21
15
|
|
22
16
|
# @param ticket_lifetime [Integer]
|
23
17
|
# @param ticket_age_add [String]
|
@@ -83,11 +77,11 @@ module TTTLS13
|
|
83
77
|
raise Error::ErrorAlerts, :decode_error unless i == msg_len + 4 &&
|
84
78
|
i == binary.length
|
85
79
|
|
86
|
-
NewSessionTicket.new(ticket_lifetime
|
87
|
-
ticket_age_add
|
88
|
-
ticket_nonce
|
89
|
-
ticket
|
90
|
-
extensions:
|
80
|
+
NewSessionTicket.new(ticket_lifetime:,
|
81
|
+
ticket_age_add:,
|
82
|
+
ticket_nonce:,
|
83
|
+
ticket:,
|
84
|
+
extensions:)
|
91
85
|
end
|
92
86
|
# rubocop: enable Metrics/AbcSize
|
93
87
|
|
@@ -8,19 +8,14 @@ module TTTLS13
|
|
8
8
|
|
9
9
|
# rubocop: disable Metrics/ClassLength
|
10
10
|
class Record
|
11
|
-
attr_reader :type
|
12
|
-
attr_reader :legacy_record_version
|
13
|
-
attr_reader :messages
|
14
|
-
attr_reader :cipher
|
11
|
+
attr_reader :type, :legacy_record_version, :messages, :cipher
|
15
12
|
|
16
13
|
# @param type [TTTLS13::Message::ContentType]
|
17
14
|
# @param legacy_record_version [TTTLS13::Message::ProtocolVersion]
|
18
15
|
# @param messages [Array of TTTLS13::Message::$Object]
|
19
16
|
# @param cipher [TTTLS13::Cryptograph::$Object]
|
20
17
|
def initialize(type:,
|
21
|
-
legacy_record_version: ProtocolVersion::TLS_1_2
|
22
|
-
messages:,
|
23
|
-
cipher:)
|
18
|
+
messages:, cipher:, legacy_record_version: ProtocolVersion::TLS_1_2)
|
24
19
|
@type = type
|
25
20
|
@legacy_record_version = legacy_record_version
|
26
21
|
@messages = messages
|
@@ -63,8 +58,6 @@ module TTTLS13
|
|
63
58
|
# @return [Array of String]
|
64
59
|
# @return [String]
|
65
60
|
# rubocop: disable Metrics/AbcSize
|
66
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
67
|
-
# rubocop: disable Metrics/PerceivedComplexity
|
68
61
|
def self.deserialize(binary, cipher, buffered = '',
|
69
62
|
record_size_limit = DEFAULT_RECORD_SIZE_LIMIT)
|
70
63
|
raise Error::ErrorAlerts, :internal_error if binary.nil?
|
@@ -82,9 +75,7 @@ module TTTLS13
|
|
82
75
|
unless binary.length == 5 + fragment_len
|
83
76
|
|
84
77
|
if type == ContentType::APPLICATION_DATA
|
85
|
-
if fragment.length - cipher.auth_tag_len > record_size_limit
|
86
|
-
raise Error::ErrorAlerts, :record_overflow
|
87
|
-
end
|
78
|
+
raise Error::ErrorAlerts, :record_overflow if fragment.length - cipher.auth_tag_len > record_size_limit
|
88
79
|
|
89
80
|
fragment, inner_type = cipher.decrypt(fragment, binary.slice(0, 5))
|
90
81
|
end
|
@@ -94,16 +85,14 @@ module TTTLS13
|
|
94
85
|
inner_type || type
|
95
86
|
)
|
96
87
|
record = Record.new(
|
97
|
-
type
|
98
|
-
legacy_record_version
|
99
|
-
messages
|
100
|
-
cipher:
|
88
|
+
type:,
|
89
|
+
legacy_record_version:,
|
90
|
+
messages:,
|
91
|
+
cipher:
|
101
92
|
)
|
102
93
|
[record, orig_msgs, surplus_binary]
|
103
94
|
end
|
104
95
|
# rubocop: enable Metrics/AbcSize
|
105
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
106
|
-
# rubocop: enable Metrics/PerceivedComplexity
|
107
96
|
|
108
97
|
private
|
109
98
|
|
@@ -122,11 +111,11 @@ module TTTLS13
|
|
122
111
|
Message::EndOfEarlyData,
|
123
112
|
Message::NewSessionTicket].include?(m.class)
|
124
113
|
ContentType::HANDSHAKE
|
125
|
-
elsif m.
|
114
|
+
elsif m.instance_of?(ChangeCipherSpec)
|
126
115
|
ContentType::CCS
|
127
|
-
elsif m.
|
116
|
+
elsif m.instance_of?(Message::ApplicationData)
|
128
117
|
ContentType::APPLICATION_DATA
|
129
|
-
elsif m.
|
118
|
+
elsif m.instance_of?(Message::Alert)
|
130
119
|
ContentType::ALERT
|
131
120
|
else
|
132
121
|
raise Error::ErrorAlerts, :internal_error
|
@@ -212,7 +201,6 @@ module TTTLS13
|
|
212
201
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
213
202
|
#
|
214
203
|
# @return [Array of TTTLS13::Message::$Object]
|
215
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
216
204
|
def do_deserialize_handshake(binary)
|
217
205
|
raise Error::ErrorAlerts, :internal_error if binary.nil?
|
218
206
|
raise Error::ErrorAlerts, :decode_error if binary.empty?
|
@@ -240,7 +228,6 @@ module TTTLS13
|
|
240
228
|
raise Error::ErrorAlerts, :unexpected_message
|
241
229
|
end
|
242
230
|
end
|
243
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
244
231
|
end
|
245
232
|
end
|
246
233
|
# rubocop: enable Metrics/ClassLength
|
@@ -34,13 +34,8 @@ module TTTLS13
|
|
34
34
|
"\xc2\xa2\x11\x16\x7a\xbb\x8c\x5e\x07\x9e\x09\xe2\xc8\xa8\x33\x9c"
|
35
35
|
|
36
36
|
class ServerHello
|
37
|
-
attr_reader :msg_type
|
38
|
-
|
39
|
-
attr_reader :random
|
40
|
-
attr_reader :legacy_session_id_echo
|
41
|
-
attr_reader :cipher_suite
|
42
|
-
attr_reader :legacy_compression_method
|
43
|
-
attr_reader :extensions
|
37
|
+
attr_reader :msg_type, :legacy_version, :random, :legacy_session_id_echo, :cipher_suite,
|
38
|
+
:legacy_compression_method, :extensions
|
44
39
|
|
45
40
|
# @param legacy_version [String]
|
46
41
|
# @param random [String]
|
@@ -49,10 +44,8 @@ module TTTLS13
|
|
49
44
|
# @param legacy_compression_method [String]
|
50
45
|
# @param extensions [TTTLS13::Message::Extensions]
|
51
46
|
# rubocop: disable Metrics/ParameterLists
|
52
|
-
def initialize(legacy_version: ProtocolVersion::TLS_1_2,
|
47
|
+
def initialize(legacy_session_id_echo:, cipher_suite:, legacy_version: ProtocolVersion::TLS_1_2,
|
53
48
|
random: OpenSSL::Random.random_bytes(32),
|
54
|
-
legacy_session_id_echo:,
|
55
|
-
cipher_suite:,
|
56
49
|
legacy_compression_method: "\x00",
|
57
50
|
extensions: Extensions.new)
|
58
51
|
@msg_type = HandshakeType::SERVER_HELLO
|
@@ -84,9 +77,7 @@ module TTTLS13
|
|
84
77
|
#
|
85
78
|
# @return [TTTLS13::Message::ServerHello]
|
86
79
|
# rubocop: disable Metrics/AbcSize
|
87
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
88
80
|
# rubocop: disable Metrics/MethodLength
|
89
|
-
# rubocop: disable Metrics/PerceivedComplexity
|
90
81
|
def self.deserialize(binary)
|
91
82
|
raise Error::ErrorAlerts, :internal_error if binary.nil?
|
92
83
|
raise Error::ErrorAlerts, :decode_error if binary.length < 39
|
@@ -116,18 +107,16 @@ module TTTLS13
|
|
116
107
|
raise Error::ErrorAlerts, :decode_error unless i == msg_len + 4 &&
|
117
108
|
i == binary.length
|
118
109
|
|
119
|
-
ServerHello.new(legacy_version
|
120
|
-
random
|
121
|
-
legacy_session_id_echo
|
122
|
-
cipher_suite
|
123
|
-
legacy_compression_method
|
124
|
-
extensions:
|
110
|
+
ServerHello.new(legacy_version:,
|
111
|
+
random:,
|
112
|
+
legacy_session_id_echo:,
|
113
|
+
cipher_suite:,
|
114
|
+
legacy_compression_method:,
|
115
|
+
extensions:)
|
125
116
|
end
|
117
|
+
|
126
118
|
# rubocop: enable Metrics/AbcSize
|
127
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
128
119
|
# rubocop: enable Metrics/MethodLength
|
129
|
-
# rubocop: enable Metrics/PerceivedComplexity
|
130
|
-
|
131
120
|
# @return [Boolean]
|
132
121
|
def hrr?
|
133
122
|
@random == HRR_RANDOM
|
data/lib/tttls1.3/named_group.rb
CHANGED
@@ -6,8 +6,8 @@ module TTTLS13
|
|
6
6
|
SECP256R1 = "\x00\x17"
|
7
7
|
SECP384R1 = "\x00\x18"
|
8
8
|
SECP521R1 = "\x00\x19"
|
9
|
-
|
10
|
-
|
9
|
+
X25519 = "\x00\x1d"
|
10
|
+
X448 = "\x00\x1e"
|
11
11
|
# FFDHE2048 = "\x01\x00" # UNSUPPORTED
|
12
12
|
# FFDHE3072 = "\x01\x01" # UNSUPPORTED
|
13
13
|
# FFDHE4096 = "\x01\x02" # UNSUPPORTED
|
@@ -25,6 +25,8 @@ module TTTLS13
|
|
25
25
|
# opaque Y[coordinate_length];
|
26
26
|
# } UncompressedPointRepresentation;
|
27
27
|
#
|
28
|
+
# https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.8.2
|
29
|
+
#
|
28
30
|
# @param group [TTTLS13::Message::Extension::NamedGroup]
|
29
31
|
#
|
30
32
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
@@ -38,11 +40,11 @@ module TTTLS13
|
|
38
40
|
97
|
39
41
|
when SECP521R1
|
40
42
|
133
|
43
|
+
when X25519
|
44
|
+
32
|
45
|
+
when X448
|
46
|
+
56
|
41
47
|
# not supported other NamedGroup
|
42
|
-
# when X25519
|
43
|
-
# 32
|
44
|
-
# when X448
|
45
|
-
# 56
|
46
48
|
# when FFDHE2048
|
47
49
|
# 256
|
48
50
|
# when FFDHE4096
|
@@ -77,6 +79,10 @@ module TTTLS13
|
|
77
79
|
'secp384r1'
|
78
80
|
when SECP521R1
|
79
81
|
'secp521r1'
|
82
|
+
when X25519
|
83
|
+
'X25519'
|
84
|
+
when X448
|
85
|
+
'X448'
|
80
86
|
else
|
81
87
|
# not supported other NamedGroup
|
82
88
|
raise Error::ErrorAlerts, :internal_error
|
data/lib/tttls1.3/server.rb
CHANGED
@@ -38,6 +38,7 @@ module TTTLS13
|
|
38
38
|
private_constant :DEFAULT_SP_SIGNATURE_ALGORITHMS
|
39
39
|
|
40
40
|
DEFAULT_SP_NAMED_GROUP_LIST = [
|
41
|
+
NamedGroup::X25519,
|
41
42
|
NamedGroup::SECP256R1,
|
42
43
|
NamedGroup::SECP384R1,
|
43
44
|
NamedGroup::SECP521R1
|
@@ -73,6 +74,7 @@ module TTTLS13
|
|
73
74
|
|
74
75
|
# @param socket [Socket]
|
75
76
|
# @param settings [Hash]
|
77
|
+
# rubocop: disable Metrics/AbcSize
|
76
78
|
def initialize(socket, **settings)
|
77
79
|
@connection = Connection.new(socket, :server)
|
78
80
|
@settings = DEFAULT_SERVER_SETTINGS.merge(settings)
|
@@ -95,6 +97,7 @@ module TTTLS13
|
|
95
97
|
raise Error::ConfigError unless cert.verify(sign.public_key)
|
96
98
|
end
|
97
99
|
end
|
100
|
+
# rubocop: enable Metrics/AbcSize
|
98
101
|
|
99
102
|
# START <-----+
|
100
103
|
# Recv ClientHello | | Send HelloRetryRequest
|
@@ -147,7 +150,7 @@ module TTTLS13
|
|
147
150
|
def accept
|
148
151
|
@transcript = Transcript.new
|
149
152
|
key_schedule = nil # TTTLS13::KeySchedule
|
150
|
-
|
153
|
+
shared_secret = nil # TTTLS13::SharedSecret
|
151
154
|
hs_wcipher = nil # TTTLS13::Cryptograph::$Object
|
152
155
|
hs_rcipher = nil # TTTLS13::Cryptograph::$Object
|
153
156
|
sslkeylogfile = nil # TTTLS13::SslKeyLogFile::Writer
|
@@ -186,7 +189,7 @@ module TTTLS13
|
|
186
189
|
ch_alpn = ch.extensions[
|
187
190
|
Message::ExtensionType::APPLICATION_LAYER_PROTOCOL_NEGOTIATION
|
188
191
|
]
|
189
|
-
if
|
192
|
+
if use_alpn? && !ch_alpn.nil?
|
190
193
|
@alpn = ch_alpn.protocol_name_list
|
191
194
|
.find { |p| @settings[:alpn].include?(p) }
|
192
195
|
|
@@ -222,7 +225,7 @@ module TTTLS13
|
|
222
225
|
logger.debug('ServerState::NEGOTIATED')
|
223
226
|
|
224
227
|
ch, = @transcript[CH]
|
225
|
-
extensions,
|
228
|
+
extensions, shared_secret = gen_sh_extensions(@named_group)
|
226
229
|
sh = send_server_hello(
|
227
230
|
extensions,
|
228
231
|
@cipher_suite,
|
@@ -233,13 +236,12 @@ module TTTLS13
|
|
233
236
|
|
234
237
|
# generate shared secret
|
235
238
|
ke = ch.extensions[Message::ExtensionType::KEY_SHARE]
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
shared_secret = Endpoint.gen_shared_secret(ke, priv_key, @named_group)
|
239
|
+
&.key_share_entry
|
240
|
+
&.find { |kse| kse.group == @named_group }
|
241
|
+
&.key_exchange
|
240
242
|
key_schedule = KeySchedule.new(
|
241
243
|
psk: @psk,
|
242
|
-
shared_secret: shared_secret,
|
244
|
+
shared_secret: shared_secret.build(@named_group, ke),
|
243
245
|
cipher_suite: @cipher_suite,
|
244
246
|
transcript: @transcript
|
245
247
|
)
|
@@ -285,8 +287,8 @@ module TTTLS13
|
|
285
287
|
@transcript[CV] = [cv, cv.serialize]
|
286
288
|
finished_key = key_schedule.server_finished_key
|
287
289
|
signature = Endpoint.sign_finished(
|
288
|
-
digest
|
289
|
-
finished_key
|
290
|
+
digest:,
|
291
|
+
finished_key:,
|
290
292
|
hash: @transcript.hash(digest, CV)
|
291
293
|
)
|
292
294
|
sf = Message::Finished.new(signature)
|
@@ -304,7 +306,7 @@ module TTTLS13
|
|
304
306
|
digest = CipherSuite.digest(@cipher_suite)
|
305
307
|
verified = Endpoint.verified_finished?(
|
306
308
|
finished: cf,
|
307
|
-
digest
|
309
|
+
digest:,
|
308
310
|
finished_key: key_schedule.client_finished_key,
|
309
311
|
hash: @transcript.hash(digest, EOED)
|
310
312
|
)
|
@@ -416,6 +418,11 @@ module TTTLS13
|
|
416
418
|
true
|
417
419
|
end
|
418
420
|
|
421
|
+
# @return [Boolean]
|
422
|
+
def use_alpn?
|
423
|
+
!@settings[:alpn].nil? && !@settings[:alpn].empty?
|
424
|
+
end
|
425
|
+
|
419
426
|
# @param receivable_ccs [Boolean]
|
420
427
|
#
|
421
428
|
# @raise [TTTLS13::Error::ErrorAlerts]
|
@@ -424,7 +431,7 @@ module TTTLS13
|
|
424
431
|
# @return [String]
|
425
432
|
def recv_client_hello(receivable_ccs)
|
426
433
|
ch, orig_msg = @connection.recv_message(
|
427
|
-
receivable_ccs
|
434
|
+
receivable_ccs:,
|
428
435
|
cipher: Cryptograph::Passer.new
|
429
436
|
)
|
430
437
|
@connection.terminate(:unexpected_message) \
|
@@ -441,8 +448,8 @@ module TTTLS13
|
|
441
448
|
def send_server_hello(extensions, cipher_suite, session_id)
|
442
449
|
sh = Message::ServerHello.new(
|
443
450
|
legacy_session_id_echo: session_id,
|
444
|
-
cipher_suite
|
445
|
-
extensions:
|
451
|
+
cipher_suite:,
|
452
|
+
extensions:
|
446
453
|
)
|
447
454
|
@connection.send_handshakes(Message::ContentType::HANDSHAKE, [sh],
|
448
455
|
Cryptograph::Passer.new)
|
@@ -463,9 +470,9 @@ module TTTLS13
|
|
463
470
|
|
464
471
|
# key_share
|
465
472
|
sp_groups = ch1.extensions[Message::ExtensionType::SUPPORTED_GROUPS]
|
466
|
-
|
473
|
+
&.named_group_list || []
|
467
474
|
ks_groups = ch1.extensions[Message::ExtensionType::KEY_SHARE]
|
468
|
-
|
475
|
+
&.key_share_entry&.map(&:group) || []
|
469
476
|
ksg = sp_groups.find do |g|
|
470
477
|
!ks_groups.include?(g) && @settings[:supported_groups].include?(g)
|
471
478
|
end
|
@@ -476,7 +483,7 @@ module TTTLS13
|
|
476
483
|
sh = Message::ServerHello.new(
|
477
484
|
random: Message::HRR_RANDOM,
|
478
485
|
legacy_session_id_echo: ch1.legacy_session_id,
|
479
|
-
cipher_suite
|
486
|
+
cipher_suite:,
|
480
487
|
extensions: exs
|
481
488
|
)
|
482
489
|
@connection.send_handshakes(Message::ContentType::HANDSHAKE, [sh],
|
@@ -513,7 +520,6 @@ module TTTLS13
|
|
513
520
|
# @param ocsp_response [OpenSSL::OCSP::Response]
|
514
521
|
#
|
515
522
|
# @return [TTTLS13::Message::Certificate, CompressedCertificate, nil]
|
516
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
517
523
|
def gen_certificate(crt, ch, chain = [], ocsp_response = nil)
|
518
524
|
exs = Message::Extensions.new
|
519
525
|
# status_request
|
@@ -540,7 +546,6 @@ module TTTLS13
|
|
540
546
|
|
541
547
|
ct
|
542
548
|
end
|
543
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
544
549
|
|
545
550
|
# @param key [OpenSSL::PKey::PKey]
|
546
551
|
# @param signature_scheme [TTTLS13::SignatureScheme]
|
@@ -549,12 +554,12 @@ module TTTLS13
|
|
549
554
|
# @return [TTTLS13::Message::CertificateVerify, nil]
|
550
555
|
def gen_certificate_verify(key, signature_scheme, hash)
|
551
556
|
signature = sign_certificate_verify(
|
552
|
-
key
|
553
|
-
signature_scheme
|
554
|
-
hash:
|
557
|
+
key:,
|
558
|
+
signature_scheme:,
|
559
|
+
hash:
|
555
560
|
)
|
556
|
-
Message::CertificateVerify.new(signature_scheme
|
557
|
-
signature:
|
561
|
+
Message::CertificateVerify.new(signature_scheme:,
|
562
|
+
signature:)
|
558
563
|
end
|
559
564
|
|
560
565
|
# @param cipher [TTTLS13::Cryptograph::Aead]
|
@@ -565,7 +570,7 @@ module TTTLS13
|
|
565
570
|
# @return [String]
|
566
571
|
def recv_finished(cipher)
|
567
572
|
cf, orig_msg \
|
568
|
-
= @connection.recv_message(receivable_ccs: true, cipher:
|
573
|
+
= @connection.recv_message(receivable_ccs: true, cipher:)
|
569
574
|
@connection.terminate(:unexpected_message) \
|
570
575
|
unless cf.is_a?(Message::Finished)
|
571
576
|
|
@@ -575,7 +580,7 @@ module TTTLS13
|
|
575
580
|
# @param named_group [TTTLS13::NamedGroup]
|
576
581
|
#
|
577
582
|
# @return [TTTLS13::Message::Extensions]
|
578
|
-
# @return [
|
583
|
+
# @return [TTTLS13::SharedSecret]
|
579
584
|
def gen_sh_extensions(named_group)
|
580
585
|
exs = Message::Extensions.new
|
581
586
|
# supported_versions: only TLS 1.3
|
@@ -584,11 +589,11 @@ module TTTLS13
|
|
584
589
|
)
|
585
590
|
|
586
591
|
# key_share
|
587
|
-
key_share,
|
592
|
+
key_share, shared_secret \
|
588
593
|
= Message::Extension::KeyShare.gen_sh_key_share(named_group)
|
589
594
|
exs << key_share
|
590
595
|
|
591
|
-
[exs,
|
596
|
+
[exs, shared_secret]
|
592
597
|
end
|
593
598
|
|
594
599
|
# @param ch [TTTLS13::Message::ClientHello]
|
@@ -625,10 +630,10 @@ module TTTLS13
|
|
625
630
|
# @return [String]
|
626
631
|
def sign_certificate_verify(key:, signature_scheme:, hash:)
|
627
632
|
Endpoint.sign_certificate_verify(
|
628
|
-
key
|
629
|
-
signature_scheme
|
633
|
+
key:,
|
634
|
+
signature_scheme:,
|
630
635
|
context: 'TLS 1.3, server CertificateVerify',
|
631
|
-
hash:
|
636
|
+
hash:
|
632
637
|
)
|
633
638
|
end
|
634
639
|
|
@@ -646,7 +651,7 @@ module TTTLS13
|
|
646
651
|
# @return [TTTLS13::NamedGroup, nil]
|
647
652
|
def select_named_group(ch)
|
648
653
|
ks_groups = ch.extensions[Message::ExtensionType::KEY_SHARE]
|
649
|
-
|
654
|
+
&.key_share_entry&.map(&:group) || []
|
650
655
|
|
651
656
|
ks_groups.find do |g|
|
652
657
|
@settings[:supported_groups].include?(g)
|
@@ -659,7 +664,7 @@ module TTTLS13
|
|
659
664
|
# @return [TTTLS13::SignatureScheme, nil]
|
660
665
|
def select_signature_scheme(ch, crt)
|
661
666
|
algorithms = ch.extensions[Message::ExtensionType::SIGNATURE_ALGORITHMS]
|
662
|
-
|
667
|
+
&.supported_signature_algorithms || []
|
663
668
|
|
664
669
|
Endpoint.select_signature_algorithms(algorithms, crt).find do |ss|
|
665
670
|
@settings[:signature_algorithms].include?(ss)
|
@@ -672,7 +677,7 @@ module TTTLS13
|
|
672
677
|
# @return [Boolean]
|
673
678
|
def recognized_server_name?(ch, crt)
|
674
679
|
server_name = ch.extensions[Message::ExtensionType::SERVER_NAME]
|
675
|
-
|
680
|
+
&.server_name
|
676
681
|
return true if server_name.nil?
|
677
682
|
|
678
683
|
Endpoint.matching_san?(crt, server_name)
|