tttls1.3 0.2.12 → 0.2.16

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +32 -0
  3. data/.rubocop.yml +2 -2
  4. data/Gemfile +3 -4
  5. data/README.md +4 -1
  6. data/example/helper.rb +3 -3
  7. data/example/https_client.rb +1 -1
  8. data/example/https_client_using_0rtt.rb +2 -2
  9. data/example/https_client_using_hrr.rb +1 -1
  10. data/example/https_client_using_hrr_and_ticket.rb +2 -2
  11. data/example/https_client_using_status_request.rb +2 -2
  12. data/example/https_client_using_ticket.rb +2 -2
  13. data/example/https_server.rb +2 -2
  14. data/interop/client_spec.rb +6 -6
  15. data/interop/server_spec.rb +6 -6
  16. data/lib/tttls1.3/client.rb +106 -65
  17. data/lib/tttls1.3/connection.rb +43 -30
  18. data/lib/tttls1.3/cryptograph/aead.rb +20 -7
  19. data/lib/tttls1.3/cryptograph.rb +1 -1
  20. data/lib/tttls1.3/message/alert.rb +2 -2
  21. data/lib/tttls1.3/message/client_hello.rb +1 -0
  22. data/lib/tttls1.3/message/compressed_certificate.rb +82 -0
  23. data/lib/tttls1.3/message/extension/alpn.rb +5 -2
  24. data/lib/tttls1.3/message/extension/compress_certificate.rb +58 -0
  25. data/lib/tttls1.3/message/extension/signature_algorithms.rb +15 -5
  26. data/lib/tttls1.3/message/extension/signature_algorithms_cert.rb +5 -4
  27. data/lib/tttls1.3/message/extension/supported_groups.rb +2 -2
  28. data/lib/tttls1.3/message/extensions.rb +31 -18
  29. data/lib/tttls1.3/message/record.rb +28 -16
  30. data/lib/tttls1.3/message.rb +23 -21
  31. data/lib/tttls1.3/server.rb +88 -37
  32. data/lib/tttls1.3/transcript.rb +3 -7
  33. data/lib/tttls1.3/version.rb +1 -1
  34. data/spec/client_spec.rb +28 -19
  35. data/spec/compress_certificate_spec.rb +54 -0
  36. data/spec/connection_spec.rb +22 -15
  37. data/spec/extensions_spec.rb +16 -0
  38. data/spec/fixtures/rsa_rsa.crt +15 -15
  39. data/spec/fixtures/rsa_rsa.key +25 -25
  40. data/spec/key_schedule_spec.rb +48 -25
  41. data/spec/record_spec.rb +2 -2
  42. data/spec/server_hello_spec.rb +1 -1
  43. data/spec/server_spec.rb +23 -11
  44. data/spec/signature_algorithms_cert_spec.rb +4 -0
  45. data/spec/signature_algorithms_spec.rb +4 -0
  46. data/spec/spec_helper.rb +4 -0
  47. data/spec/transcript_spec.rb +34 -20
  48. data/tttls1.3.gemspec +0 -1
  49. metadata +11 -7
  50. data/.github/workflows/main.yml +0 -25
@@ -0,0 +1,82 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ module TTTLS13
5
+ using Refinements
6
+ module Message
7
+ class CompressedCertificate
8
+ attr_reader :msg_type
9
+ attr_reader :certificate_message
10
+ attr_reader :algorithm
11
+
12
+ # @param certificate_message [TTTLS13::Message::Certificate]
13
+ # @param algorithm [CertificateCompressionAlgorithm]
14
+ def initialize(certificate_message:, algorithm:)
15
+ @msg_type = HandshakeType::COMPRESSED_CERTIFICATE
16
+ @certificate_message = certificate_message
17
+ @algorithm = algorithm
18
+ end
19
+
20
+ # @return [String]
21
+ def serialize
22
+ binary = ''
23
+ binary += @algorithm
24
+ ct_bin = @certificate_message.serialize[4..]
25
+ binary += ct_bin.length.to_uint24
26
+ case @algorithm
27
+ when Extension::CertificateCompressionAlgorithm::ZLIB
28
+ binary += Zlib::Deflate.deflate(ct_bin).prefix_uint24_length
29
+ else # TODO: orig_msgs, ZSTD
30
+ raise Error::ErrorAlerts, :internal_error
31
+ end
32
+
33
+ @msg_type + binary.prefix_uint24_length
34
+ end
35
+
36
+ alias fragment serialize
37
+
38
+ # @param binary [String]
39
+ #
40
+ # @raise [TTTLS13::Error::ErrorAlerts]
41
+ #
42
+ # @return [TTTLS13::Message::CompressedCertificate]
43
+ # rubocop: disable Metrics/AbcSize
44
+ # rubocop: disable Metrics/CyclomaticComplexity
45
+ # rubocop: disable Metrics/PerceivedComplexity
46
+ def self.deserialize(binary)
47
+ raise Error::ErrorAlerts, :internal_error if binary.nil?
48
+ raise Error::ErrorAlerts, :decode_error if binary.length < 5
49
+ raise Error::ErrorAlerts, :internal_error \
50
+ unless binary[0] == HandshakeType::COMPRESSED_CERTIFICATE
51
+
52
+ msg_len = Convert.bin2i(binary.slice(1, 3))
53
+ algorithm = binary.slice(4, 2)
54
+ uncompressed_length = Convert.bin2i(binary.slice(6, 3))
55
+ ccm_len = Convert.bin2i(binary.slice(9, 3))
56
+ ct_bin = ''
57
+ case algorithm
58
+ when Extension::CertificateCompressionAlgorithm::ZLIB
59
+ ct_bin = Zlib::Inflate.inflate(binary.slice(12, ccm_len))
60
+ else # TODO: BROTLI, ZSTD
61
+ raise Error::ErrorAlerts, :bad_certificate
62
+ end
63
+
64
+ raise Error::ErrorAlerts, :bad_certificate \
65
+ unless ct_bin.length == uncompressed_length
66
+ raise Error::ErrorAlerts, :decode_error \
67
+ unless ccm_len + 12 == binary.length && msg_len + 4 == binary.length
68
+
69
+ certificate_message = Certificate.deserialize(
70
+ HandshakeType::CERTIFICATE + ct_bin.prefix_uint24_length
71
+ )
72
+ CompressedCertificate.new(
73
+ certificate_message: certificate_message,
74
+ algorithm: algorithm
75
+ )
76
+ end
77
+ # rubocop: enable Metrics/AbcSize
78
+ # rubocop: enable Metrics/CyclomaticComplexity
79
+ # rubocop: enable Metrics/PerceivedComplexity
80
+ end
81
+ end
82
+ end
@@ -27,9 +27,12 @@ module TTTLS13
27
27
 
28
28
  # @return [String]
29
29
  def serialize
30
- binary = @protocol_name_list.map(&:prefix_uint8_length).join
30
+ binary = @protocol_name_list
31
+ .map(&:prefix_uint8_length)
32
+ .join
33
+ .prefix_uint16_length
31
34
 
32
- @extension_type + binary.prefix_uint16_length.prefix_uint16_length
35
+ @extension_type + binary.prefix_uint16_length
33
36
  end
34
37
 
35
38
  # @param binary [String]
@@ -0,0 +1,58 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ module TTTLS13
5
+ using Refinements
6
+ module Message
7
+ module Extension
8
+ module CertificateCompressionAlgorithm
9
+ ZLIB = "\x00\x01"
10
+ # BROTLI = "\x00\x02" # UNSUPPORTED
11
+ # ZSTD = "\x00\x03" # UNSUPPORTED
12
+ end
13
+
14
+ # https://tools.ietf.org/html/rfc8879
15
+ class CompressCertificate
16
+ attr_reader :extension_type
17
+ attr_reader :algorithms
18
+
19
+ # @param algorithms [Array of CertificateCompressionAlgorithm]
20
+ #
21
+ # @raise [TTTLS13::Error::ErrorAlerts]
22
+ #
23
+ # @example
24
+ # CompressCertificate([CertificateCompressionAlgorithm::ZLIB])
25
+ def initialize(algorithms)
26
+ @extension_type = ExtensionType::COMPRESS_CERTIFICATE
27
+ @algorithms = algorithms || []
28
+ raise Error::ErrorAlerts, :internal_error \
29
+ if @algorithms.join.length < 2 ||
30
+ @algorithms.join.length > 2**8 - 2
31
+ end
32
+
33
+ # @return [String]
34
+ def serialize
35
+ binary = @algorithms.join.prefix_uint8_length
36
+
37
+ @extension_type + binary.prefix_uint16_length
38
+ end
39
+
40
+ # @param binary [String]
41
+ #
42
+ # @raise [TTTLS13::Error::ErrorAlerts]
43
+ #
44
+ # @return [TTTLS13::Message::Extension::CompressCertificate, nil]
45
+ def self.deserialize(binary)
46
+ raise Error::ErrorAlerts, :internal_error if binary.nil?
47
+
48
+ return nil if binary.length < 3
49
+
50
+ al_len = Convert.bin2i(binary.slice(0, 1))
51
+ return nil if binary.length != al_len + 1
52
+
53
+ CompressCertificate.new(binary.slice(1, al_len + 1).scan(/.{2}/m))
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -35,17 +35,17 @@ module TTTLS13
35
35
 
36
36
  # @return [String]
37
37
  def serialize
38
- binary = @supported_signature_algorithms.join
38
+ binary = @supported_signature_algorithms.join.prefix_uint16_length
39
39
 
40
- @extension_type + binary.prefix_uint16_length.prefix_uint16_length
40
+ @extension_type + binary.prefix_uint16_length
41
41
  end
42
42
 
43
43
  # @param binary [String]
44
44
  #
45
45
  # @raise [TTTLS13::Error::ErrorAlerts]
46
46
  #
47
- # @return [TTTLS13::Message::Extensions::SignatureAlgorithms, nil]
48
- def self.deserialize(binary)
47
+ # @return [Array of SignatureScheme]
48
+ def self.deserialize_supported_signature_algorithms(binary)
49
49
  raise Error::ErrorAlerts, :internal_error if binary.nil?
50
50
 
51
51
  return nil if binary.length < 2
@@ -61,7 +61,17 @@ module TTTLS13
61
61
  end
62
62
  return nil unless ssa_len + 2 == binary.length
63
63
 
64
- SignatureAlgorithms.new(supported_signature_algorithms)
64
+ supported_signature_algorithms
65
+ end
66
+
67
+ # @param binary [String]
68
+ #
69
+ # @return [TTTLS13::Message::Extensions::SignatureAlgorithms, nil]
70
+ def self.deserialize(binary)
71
+ ssa = deserialize_supported_signature_algorithms(binary)
72
+ return nil if ssa.nil?
73
+
74
+ SignatureAlgorithms.new(ssa)
65
75
  end
66
76
  end
67
77
  end
@@ -13,11 +13,12 @@ module TTTLS13
13
13
 
14
14
  # @param binary [String]
15
15
  #
16
- # @return [TTTLS13::Message::Extensions::SignatureAlgorithmsCert]
16
+ # @return [TTTLS13::Message::Extensions::SignatureAlgorithmsCert, nil]
17
17
  def self.deserialize(binary)
18
- extension = SignatureAlgorithms.deserialize(binary)
19
- extension.extension_type = ExtensionType::SIGNATURE_ALGORITHMS_CERT
20
- extension
18
+ ssa = deserialize_supported_signature_algorithms(binary)
19
+ return nil if ssa.nil?
20
+
21
+ SignatureAlgorithmsCert.new(ssa)
21
22
  end
22
23
  end
23
24
  end
@@ -21,9 +21,9 @@ module TTTLS13
21
21
 
22
22
  # @return [String]
23
23
  def serialize
24
- binary = @named_group_list.join
24
+ binary = @named_group_list.join.prefix_uint16_length
25
25
 
26
- @extension_type + binary.prefix_uint16_length.prefix_uint16_length
26
+ @extension_type + binary.prefix_uint16_length
27
27
  end
28
28
 
29
29
  # @param binary [String]
@@ -44,10 +44,11 @@ module TTTLS13
44
44
  #
45
45
  # @return [TTTLS13::Message::Extensions]
46
46
  # rubocop: disable Metrics/CyclomaticComplexity
47
+ # rubocop: disable Metrics/PerceivedComplexity
47
48
  def self.deserialize(binary, msg_type)
48
49
  raise Error::ErrorAlerts, :internal_error if binary.nil?
49
50
 
50
- extensions = []
51
+ exs = Extensions.new
51
52
  i = 0
52
53
  while i < binary.length
53
54
  raise Error::ErrorAlerts, :decode_error if i + 4 > binary.length
@@ -66,32 +67,41 @@ module TTTLS13
66
67
  ex = Extension::UnknownExtension.new(extension_type: extension_type,
67
68
  extension_data: ex_bin)
68
69
  end
69
- extensions << ex
70
+
71
+ # There MUST NOT be more than one extension of the same type in a
72
+ # given extension block.
73
+ raise Error::ErrorAlerts, :unsupported_extension \
74
+ if exs.include?(extension_type)
75
+
76
+ exs[extension_type] = ex
70
77
  i += ex_len
71
78
  end
72
79
  raise Error::ErrorAlerts, :decode_error unless i == binary.length
73
80
 
74
- Extensions.new(extensions)
81
+ exs
75
82
  end
76
83
  # rubocop: enable Metrics/CyclomaticComplexity
84
+ # rubocop: enable Metrics/PerceivedComplexity
77
85
 
78
86
  # @param key [TTTLS13::Message::ExtensionType]
87
+ # @param default
79
88
  #
80
89
  # @return [TTTLS13::Message::Extension::$Object]
81
- def [](key)
90
+ def fetch(key, default = nil)
82
91
  return nil if super_fetch(key, nil).is_a?(Extension::UnknownExtension)
83
92
 
84
- super_fetch(key, nil)
93
+ super_fetch(key, default)
85
94
  end
86
95
 
87
- # @param key [TTTLS13::Message::ExtensionType]
88
- # @param default
96
+ def [](key)
97
+ fetch(key)
98
+ end
99
+
100
+ # @param ex [TTTLS13::Message::Extension::$Object]
89
101
  #
90
102
  # @return [TTTLS13::Message::Extension::$Object]
91
- def fetch(key, default = nil)
92
- return nil if super_fetch(key, nil).is_a?(Extension::UnknownExtension)
93
-
94
- super_fetch(key, default)
103
+ def <<(ex)
104
+ store(ex.extension_type, ex)
95
105
  end
96
106
 
97
107
  class << self
@@ -119,20 +129,23 @@ module TTTLS13
119
129
  when ExtensionType::SERVER_NAME
120
130
  Extension::ServerName.deserialize(binary)
121
131
  when ExtensionType::STATUS_REQUEST
122
- if msg_type == HandshakeType::CLIENT_HELLO # ||
123
- # msg_type == HandshakeType::CERTIFICATE_REQUEST
124
- Extension::OCSPStatusRequest.deserialize(binary)
125
- elsif msg_type == HandshakeType::CERTIFICATE
126
- Extension::OCSPResponse.deserialize(binary)
127
- else
128
- return nil
132
+ if msg_type == HandshakeType::CLIENT_HELLO
133
+ return Extension::OCSPStatusRequest.deserialize(binary)
129
134
  end
135
+
136
+ if msg_type == HandshakeType::CERTIFICATE
137
+ return Extension::OCSPResponse.deserialize(binary)
138
+ end
139
+
140
+ Extension::UnknownExtension.deserialize(binary, extension_type)
130
141
  when ExtensionType::SUPPORTED_GROUPS
131
142
  Extension::SupportedGroups.deserialize(binary)
132
143
  when ExtensionType::SIGNATURE_ALGORITHMS
133
144
  Extension::SignatureAlgorithms.deserialize(binary)
134
145
  when ExtensionType::APPLICATION_LAYER_PROTOCOL_NEGOTIATION
135
146
  Extension::Alpn.deserialize(binary)
147
+ when ExtensionType::COMPRESS_CERTIFICATE
148
+ Extension::CompressCertificate.deserialize(binary)
136
149
  when ExtensionType::RECORD_SIZE_LIMIT
137
150
  Extension::RecordSizeLimit.deserialize(binary)
138
151
  when ExtensionType::PRE_SHARED_KEY
@@ -11,23 +11,19 @@ module TTTLS13
11
11
  attr_reader :type
12
12
  attr_reader :legacy_record_version
13
13
  attr_reader :messages
14
- attr_reader :surplus_binary
15
14
  attr_reader :cipher
16
15
 
17
16
  # @param type [TTTLS13::Message::ContentType]
18
17
  # @param legacy_record_version [TTTLS13::Message::ProtocolVersion]
19
18
  # @param messages [Array of TTTLS13::Message::$Object]
20
- # @param surplus_binary [String]
21
19
  # @param cipher [TTTLS13::Cryptograph::$Object]
22
20
  def initialize(type:,
23
21
  legacy_record_version: ProtocolVersion::TLS_1_2,
24
22
  messages:,
25
- surplus_binary: '',
26
23
  cipher:)
27
24
  @type = type
28
25
  @legacy_record_version = legacy_record_version
29
26
  @messages = messages
30
- @surplus_binary = surplus_binary
31
27
  @cipher = cipher
32
28
  end
33
29
 
@@ -40,7 +36,7 @@ module TTTLS13
40
36
  #
41
37
  # @return [String]
42
38
  def serialize(record_size_limit = DEFAULT_RECORD_SIZE_LIMIT)
43
- tlsplaintext = @messages.map(&:serialize).join + @surplus_binary
39
+ tlsplaintext = @messages.map(&:serialize).join
44
40
  if @cipher.is_a?(Cryptograph::Aead)
45
41
  max = @cipher.tlsplaintext_length_limit(record_size_limit)
46
42
  fragments = tlsplaintext.scan(/.{1,#{max}}/m)
@@ -66,6 +62,8 @@ module TTTLS13
66
62
  # @raise [TTTLS13::Error::ErrorAlerts]
67
63
  #
68
64
  # @return [TTTLS13::Message::Record]
65
+ # @return [Array of String]
66
+ # @return [String]
69
67
  # rubocop: disable Metrics/AbcSize
70
68
  # rubocop: disable Metrics/CyclomaticComplexity
71
69
  # rubocop: disable Metrics/PerceivedComplexity
@@ -93,13 +91,17 @@ module TTTLS13
93
91
  fragment, inner_type = cipher.decrypt(fragment, binary.slice(0, 5))
94
92
  end
95
93
 
96
- messages, surplus_binary = deserialize_fragment(buffered + fragment,
97
- inner_type || type)
98
- Record.new(type: type,
99
- legacy_record_version: legacy_record_version,
100
- messages: messages,
101
- surplus_binary: surplus_binary,
102
- cipher: cipher)
94
+ messages, orig_msgs, surplus_binary = deserialize_fragment(
95
+ buffered + fragment,
96
+ inner_type || type
97
+ )
98
+ record = Record.new(
99
+ type: type,
100
+ legacy_record_version: legacy_record_version,
101
+ messages: messages,
102
+ cipher: cipher
103
+ )
104
+ [record, orig_msgs, surplus_binary]
103
105
  end
104
106
  # rubocop: enable Metrics/AbcSize
105
107
  # rubocop: enable Metrics/CyclomaticComplexity
@@ -116,6 +118,7 @@ module TTTLS13
116
118
  Message::ServerHello,
117
119
  Message::EncryptedExtensions,
118
120
  Message::Certificate,
121
+ Message::CompressedCertificate,
119
122
  Message::CertificateVerify,
120
123
  Message::Finished,
121
124
  Message::EndOfEarlyData,
@@ -152,20 +155,24 @@ module TTTLS13
152
155
  raise Error::ErrorAlerts, :internal_error if binary.nil?
153
156
 
154
157
  surplus_binary = ''
158
+ orig_msgs = []
155
159
  case type
156
160
  when ContentType::HANDSHAKE
157
- messages, surplus_binary = deserialize_handshake(binary)
161
+ messages, orig_msgs, surplus_binary = deserialize_handshake(binary)
158
162
  when ContentType::CCS
159
163
  messages = [ChangeCipherSpec.deserialize(binary)]
164
+ orig_msgs = [binary]
160
165
  when ContentType::APPLICATION_DATA
161
166
  messages = [ApplicationData.deserialize(binary)]
167
+ orig_msgs = [binary]
162
168
  when ContentType::ALERT
163
169
  messages = [Alert.deserialize(binary)]
170
+ orig_msgs = [binary]
164
171
  else
165
172
  raise Error::ErrorAlerts, :unexpected_message
166
173
  end
167
174
 
168
- [messages, surplus_binary]
175
+ [messages, orig_msgs, surplus_binary]
169
176
  end
170
177
 
171
178
  # @param binary [String]
@@ -173,11 +180,13 @@ module TTTLS13
173
180
  # @raise [TTTLS13::Error::ErrorAlerts]
174
181
  #
175
182
  # @return [Array of TTTLS13::Message::$Object]
183
+ # @return [Array of String]
176
184
  # @return [String]
177
185
  def deserialize_handshake(binary)
178
186
  raise Error::ErrorAlerts, :internal_error if binary.nil?
179
187
 
180
188
  handshakes = []
189
+ orig_msgs = []
181
190
  i = 0
182
191
  while i < binary.length
183
192
  # Handshake.length is kind of uint24 and Record.length is kind of
@@ -185,18 +194,19 @@ module TTTLS13
185
194
  if binary.length < 4 + i ||
186
195
  binary.length < 4 + i + Convert.bin2i(binary.slice(i + 1, 3))
187
196
  surplus_binary = binary[i..]
188
- return [handshakes, surplus_binary]
197
+ return [handshakes, orig_msgs, surplus_binary]
189
198
  end
190
199
 
191
200
  msg_len = Convert.bin2i(binary.slice(i + 1, 3))
192
201
  msg_bin = binary.slice(i, msg_len + 4)
202
+ orig_msgs << msg_bin
193
203
  message = do_deserialize_handshake(msg_bin)
194
204
  i += msg_len + 4
195
205
  handshakes << message
196
206
  end
197
207
 
198
208
  surplus_binary = binary[i..]
199
- [handshakes, surplus_binary]
209
+ [handshakes, orig_msgs, surplus_binary]
200
210
  end
201
211
 
202
212
  # @param binary [String]
@@ -226,6 +236,8 @@ module TTTLS13
226
236
  NewSessionTicket.deserialize(binary)
227
237
  when HandshakeType::END_OF_EARLY_DATA
228
238
  EndOfEarlyData.deserialize(binary)
239
+ when HandshakeType::COMPRESSED_CERTIFICATE
240
+ CompressedCertificate.deserialize(binary)
229
241
  else
230
242
  raise Error::ErrorAlerts, :unexpected_message
231
243
  end
@@ -21,26 +21,27 @@ module TTTLS13
21
21
  DEFAULT_VERSIONS = [ProtocolVersion::TLS_1_3].freeze
22
22
 
23
23
  module HandshakeType
24
- HELLO_REQUEST = "\x00" # RESERVED
25
- CLIENT_HELLO = "\x01"
26
- SERVER_HELLO = "\x02"
27
- HELLO_VERIFY_REQUEST = "\x03" # RESERVED
28
- NEW_SESSION_TICKET = "\x04"
29
- END_OF_EARLY_DATA = "\x05"
30
- HELLO_RETRY_REQUEST = "\x06" # RESERVED
31
- ENCRYPTED_EXTENSIONS = "\x08"
32
- CERTIFICATE = "\x0b"
33
- SERVER_KEY_EXCHANGE = "\x0c" # RESERVED
34
- CERTIFICATE_REQUEST = "\x0d"
35
- SERVER_HELLO_DONE = "\x0e" # RESERVED
36
- CERTIFICATE_VERIFY = "\x0f"
37
- CLIENT_KEY_EXCHANGE = "\x10" # RESERVED
38
- FINISHED = "\x14"
39
- CERTIFICATE_URL = "\x15" # RESERVED
40
- CERTIFICATE_STATUS = "\x16" # RESERVED
41
- SUPPLEMENTAL_DATA = "\x17" # RESERVED
42
- KEY_UPDATE = "\x18"
43
- MESSAGE_HASH = "\xfe"
24
+ HELLO_REQUEST = "\x00" # RESERVED
25
+ CLIENT_HELLO = "\x01"
26
+ SERVER_HELLO = "\x02"
27
+ HELLO_VERIFY_REQUEST = "\x03" # RESERVED
28
+ NEW_SESSION_TICKET = "\x04"
29
+ END_OF_EARLY_DATA = "\x05"
30
+ HELLO_RETRY_REQUEST = "\x06" # RESERVED
31
+ ENCRYPTED_EXTENSIONS = "\x08"
32
+ CERTIFICATE = "\x0b"
33
+ SERVER_KEY_EXCHANGE = "\x0c" # RESERVED
34
+ CERTIFICATE_REQUEST = "\x0d"
35
+ SERVER_HELLO_DONE = "\x0e" # RESERVED
36
+ CERTIFICATE_VERIFY = "\x0f"
37
+ CLIENT_KEY_EXCHANGE = "\x10" # RESERVED
38
+ FINISHED = "\x14"
39
+ CERTIFICATE_URL = "\x15" # RESERVED
40
+ CERTIFICATE_STATUS = "\x16" # RESERVED
41
+ SUPPLEMENTAL_DATA = "\x17" # RESERVED
42
+ KEY_UPDATE = "\x18"
43
+ COMPRESSED_CERTIFICATE = "\x19"
44
+ MESSAGE_HASH = "\xfe"
44
45
  end
45
46
 
46
47
  module ExtensionType
@@ -56,6 +57,7 @@ module TTTLS13
56
57
  CLIENT_CERTIFICATE_TYPE = "\x00\x13"
57
58
  SERVER_CERTIFICATE_TYPE = "\x00\x14"
58
59
  PADDING = "\x00\x15"
60
+ COMPRESS_CERTIFICATE = "\x00\x1b"
59
61
  RECORD_SIZE_LIMIT = "\x00\x1c"
60
62
  PWD_PROTECT = "\x00\x1d"
61
63
  PWD_CLEAR = "\x00\x1e"
@@ -78,4 +80,4 @@ module TTTLS13
78
80
  end
79
81
  end
80
82
 
81
- Dir[File.dirname(__FILE__) + '/message/*.rb'].each { |f| require f }
83
+ Dir[File.dirname(__FILE__) + '/message/*.rb'].sort.each { |f| require f }