tttls1.3 0.2.12 → 0.2.16

Sign up to get free protection for your applications and to get access to all the features.
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 }