tttls1.3 0.2.14 → 0.2.17

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.
@@ -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]
@@ -121,6 +121,7 @@ module TTTLS13
121
121
  # @return [TTTLS13::Message::Extension::$Object, nil]
122
122
  # rubocop: disable Metrics/CyclomaticComplexity
123
123
  # rubocop: disable Metrics/MethodLength
124
+ # rubocop: disable Metrics/PerceivedComplexity
124
125
  def deserialize_extension(binary, extension_type, msg_type)
125
126
  raise Error::ErrorAlerts, :internal_error if binary.nil?
126
127
 
@@ -143,6 +144,8 @@ module TTTLS13
143
144
  Extension::SignatureAlgorithms.deserialize(binary)
144
145
  when ExtensionType::APPLICATION_LAYER_PROTOCOL_NEGOTIATION
145
146
  Extension::Alpn.deserialize(binary)
147
+ when ExtensionType::COMPRESS_CERTIFICATE
148
+ Extension::CompressCertificate.deserialize(binary)
146
149
  when ExtensionType::RECORD_SIZE_LIMIT
147
150
  Extension::RecordSizeLimit.deserialize(binary)
148
151
  when ExtensionType::PRE_SHARED_KEY
@@ -165,6 +168,7 @@ module TTTLS13
165
168
  end
166
169
  # rubocop: enable Metrics/CyclomaticComplexity
167
170
  # rubocop: enable Metrics/MethodLength
171
+ # rubocop: enable Metrics/PerceivedComplexity
168
172
  end
169
173
  end
170
174
  end
@@ -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"
@@ -44,6 +44,11 @@ module TTTLS13
44
44
  ].freeze
45
45
  private_constant :DEFAULT_SP_NAMED_GROUP_LIST
46
46
 
47
+ DEFAULT_SP_COMPRESS_CERTIFICATE_ALGORITHMS = [
48
+ Message::Extension::CertificateCompressionAlgorithm::ZLIB
49
+ ].freeze
50
+ private_constant :DEFAULT_SP_COMPRESS_CERTIFICATE_ALGORITHMS
51
+
47
52
  DEFAULT_SERVER_SETTINGS = {
48
53
  crt_file: nil,
49
54
  chain_files: nil,
@@ -53,6 +58,7 @@ module TTTLS13
53
58
  supported_groups: DEFAULT_SP_NAMED_GROUP_LIST,
54
59
  alpn: nil,
55
60
  process_ocsp_response: nil,
61
+ compress_certificate_algorithms: DEFAULT_SP_COMPRESS_CERTIFICATE_ALGORITHMS,
56
62
  compatibility_mode: true,
57
63
  loglevel: Logger::WARN
58
64
  }.freeze
@@ -140,7 +146,6 @@ module TTTLS13
140
146
  transcript = Transcript.new
141
147
  key_schedule = nil # TTTLS13::KeySchedule
142
148
  priv_key = nil # OpenSSL::PKey::$Object
143
-
144
149
  hs_wcipher = nil # TTTLS13::Cryptograph::$Object
145
150
  hs_rcipher = nil # TTTLS13::Cryptograph::$Object
146
151
 
@@ -151,7 +156,7 @@ module TTTLS13
151
156
  logger.debug('ServerState::START')
152
157
 
153
158
  receivable_ccs = transcript.include?(CH1)
154
- ch = transcript[CH] = recv_client_hello(receivable_ccs)
159
+ ch, = transcript[CH] = recv_client_hello(receivable_ccs)
155
160
 
156
161
  # support only TLS 1.3
157
162
  terminate(:protocol_version) unless ch.negotiated_tls_1_3?
@@ -183,7 +188,7 @@ module TTTLS13
183
188
  logger.debug('ServerState::RECVD_CH')
184
189
 
185
190
  # select parameters
186
- ch = transcript[CH]
191
+ ch, = transcript[CH]
187
192
  @cipher_suite = select_cipher_suite(ch)
188
193
  @named_group = select_named_group(ch)
189
194
  @signature_scheme = select_signature_scheme(ch, @crt)
@@ -192,8 +197,9 @@ module TTTLS13
192
197
 
193
198
  # send HRR
194
199
  if @named_group.nil?
195
- ch1 = transcript[CH1] = transcript.delete(CH)
196
- transcript[HRR] = send_hello_retry_request(ch1, @cipher_suite)
200
+ ch1, = transcript[CH1] = transcript.delete(CH)
201
+ hrr = send_hello_retry_request(ch1, @cipher_suite)
202
+ transcript[HRR] = [hrr, hrr.serialize]
197
203
  @state = ServerState::START
198
204
  next
199
205
  end
@@ -201,10 +207,14 @@ module TTTLS13
201
207
  when ServerState::NEGOTIATED
202
208
  logger.debug('ServerState::NEGOTIATED')
203
209
 
204
- ch = transcript[CH]
210
+ ch, = transcript[CH]
205
211
  extensions, priv_key = gen_sh_extensions(@named_group)
206
- transcript[SH] = send_server_hello(extensions, @cipher_suite,
207
- ch.legacy_session_id)
212
+ sh = send_server_hello(
213
+ extensions,
214
+ @cipher_suite,
215
+ ch.legacy_session_id
216
+ )
217
+ transcript[SH] = [sh, sh.serialize]
208
218
  send_ccs if @settings[:compatibility_mode]
209
219
 
210
220
  # generate shared secret
@@ -235,29 +245,30 @@ module TTTLS13
235
245
  when ServerState::WAIT_FLIGHT2
236
246
  logger.debug('ServerState::WAIT_FLIGHT2')
237
247
 
238
- ch = transcript[CH]
248
+ ch, = transcript[CH]
239
249
  rsl = @send_record_size \
240
250
  if ch.extensions.include?(Message::ExtensionType::RECORD_SIZE_LIMIT)
241
- ee = transcript[EE] = gen_encrypted_extensions(ch, @alpn, rsl)
251
+ ee = gen_encrypted_extensions(ch, @alpn, rsl)
252
+ transcript[EE] = [ee, ee.serialize]
242
253
  # TODO: [Send CertificateRequest]
243
254
 
244
255
  # status_request
245
256
  ocsp_response = fetch_ocsp_response \
246
257
  if ch.extensions.include?(Message::ExtensionType::STATUS_REQUEST)
247
- ct = transcript[CT] = gen_certificate(@crt, @chain, ocsp_response)
258
+ ct = gen_certificate(@crt, ch, @chain, ocsp_response)
259
+ transcript[CT] = [ct, ct.serialize]
248
260
  digest = CipherSuite.digest(@cipher_suite)
249
- cv = transcript[CV] = gen_certificate_verify(
250
- @key,
251
- @signature_scheme,
252
- transcript.hash(digest, CT)
253
- )
261
+ hash = transcript.hash(digest, CT)
262
+ cv = gen_certificate_verify(@key, @signature_scheme, hash)
263
+ transcript[CV] = [cv, cv.serialize]
254
264
  finished_key = key_schedule.server_finished_key
255
265
  signature = sign_finished(
256
266
  digest: digest,
257
267
  finished_key: finished_key,
258
268
  hash: transcript.hash(digest, CV)
259
269
  )
260
- sf = transcript[SF] = Message::Finished.new(signature)
270
+ sf = Message::Finished.new(signature)
271
+ transcript[SF] = [sf, sf.serialize]
261
272
  send_server_parameters([ee, ct, cv, sf], hs_wcipher)
262
273
  @state = ServerState::WAIT_FINISHED
263
274
  when ServerState::WAIT_CERT
@@ -267,7 +278,7 @@ module TTTLS13
267
278
  when ServerState::WAIT_FINISHED
268
279
  logger.debug('ServerState::WAIT_FINISHED')
269
280
 
270
- cf = transcript[CF] = recv_finished(hs_rcipher)
281
+ cf, = transcript[CF] = recv_finished(hs_rcipher)
271
282
  digest = CipherSuite.digest(@cipher_suite)
272
283
  verified = verified_finished?(
273
284
  finished: cf,
@@ -325,12 +336,15 @@ module TTTLS13
325
336
  # @raise [TTTLS13::Error::ErrorAlerts]
326
337
  #
327
338
  # @return [TTTLS13::Message::ClientHello]
339
+ # @return [String]
328
340
  def recv_client_hello(receivable_ccs)
329
- ch = recv_message(receivable_ccs: receivable_ccs,
330
- cipher: Cryptograph::Passer.new)
341
+ ch, orig_msg = recv_message(
342
+ receivable_ccs: receivable_ccs,
343
+ cipher: Cryptograph::Passer.new
344
+ )
331
345
  terminate(:unexpected_message) unless ch.is_a?(Message::ClientHello)
332
346
 
333
- ch
347
+ [ch, orig_msg]
334
348
  end
335
349
 
336
350
  # @param extensions [TTTLS13::Message::Extensions]
@@ -408,19 +422,39 @@ module TTTLS13
408
422
  end
409
423
 
410
424
  # @param crt [OpenSSL::X509::Certificate]
425
+ # @param ch [TTTLS13::Message::ClientHell]
411
426
  # @param chain [Array of OpenSSL::X509::Certificate]
412
427
  # @param ocsp_response [OpenSSL::OCSP::Response]
413
428
  #
414
- # @return [TTTLS13::Message::Certificate, nil]
415
- def gen_certificate(crt, chain = [], ocsp_response = nil)
429
+ # @return [TTTLS13::Message::Certificate, CompressedCertificate, nil]
430
+ # rubocop: disable Metrics/CyclomaticComplexity
431
+ def gen_certificate(crt, ch, chain = [], ocsp_response = nil)
416
432
  exs = Message::Extensions.new
417
433
  # status_request
418
434
  exs << Message::Extension::OCSPResponse.new(ocsp_response) \
419
435
  unless ocsp_response.nil?
420
436
  ces = [Message::CertificateEntry.new(crt, exs)] \
421
437
  + (chain || []).map { |c| Message::CertificateEntry.new(c) }
422
- Message::Certificate.new(certificate_list: ces)
438
+ ct = Message::Certificate.new(certificate_list: ces)
439
+
440
+ # compress_certificate
441
+ cc = ch.extensions[Message::ExtensionType::COMPRESS_CERTIFICATE]
442
+ if !cc.nil? && !cc.algorithms.empty?
443
+ cca = (@settings[:compress_certificate_algorithms] || []).find do |a|
444
+ cc.algorithms.include?(a)
445
+ end
446
+
447
+ unless cca.nil?
448
+ ct = Message::CompressedCertificate.new(
449
+ certificate_message: ct,
450
+ algorithm: cca
451
+ )
452
+ end
453
+ end
454
+
455
+ ct
423
456
  end
457
+ # rubocop: enable Metrics/CyclomaticComplexity
424
458
 
425
459
  # @param key [OpenSSL::PKey::PKey]
426
460
  # @param signature_scheme [TTTLS13::SignatureScheme]
@@ -442,11 +476,12 @@ module TTTLS13
442
476
  # @raise [TTTLS13::Error::ErrorAlerts]
443
477
  #
444
478
  # @return [TTTLS13::Message::Finished]
479
+ # @return [String]
445
480
  def recv_finished(cipher)
446
- cf = recv_message(receivable_ccs: true, cipher: cipher)
481
+ cf, orig_msg = recv_message(receivable_ccs: true, cipher: cipher)
447
482
  terminate(:unexpected_message) unless cf.is_a?(Message::Finished)
448
483
 
449
- cf
484
+ [cf, orig_msg]
450
485
  end
451
486
 
452
487
  # @param named_group [TTTLS13::NamedGroup]
@@ -19,10 +19,6 @@ module TTTLS13
19
19
  CF = 12
20
20
 
21
21
  class Transcript < Hash
22
- def initialize
23
- super
24
- end
25
-
26
22
  alias super_include? include?
27
23
 
28
24
  # @param digest [String] name of digest algorithm
@@ -62,12 +58,12 @@ module TTTLS13
62
58
  exc_prefix = Message::HandshakeType::MESSAGE_HASH \
63
59
  + "\x00\x00" \
64
60
  + OpenSSL::Digest.new(digest).digest_length.to_uint8 \
65
- + OpenSSL::Digest.digest(digest, self[CH1].serialize) \
66
- + self[HRR].serialize
61
+ + OpenSSL::Digest.digest(digest, self[CH1].last) \
62
+ + self[HRR].last
67
63
  end
68
64
 
69
65
  messages = (CH..end_index).to_a.map do |m|
70
- include?(m) ? self[m].serialize : ''
66
+ include?(m) ? self[m].last : ''
71
67
  end
72
68
  exc_prefix + messages.join
73
69
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTTLS13
4
- VERSION = '0.2.14'
4
+ VERSION = '0.2.17'
5
5
  end