tttls1.3 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4d612bec845851394778f851e83cd26a402c28b28282eadf1630684781dbfad
4
- data.tar.gz: 2b2ac159212b899dfd2f0281b756469033ab58ac57276a2c834166e9e1c1a659
3
+ metadata.gz: a040b2151b2f78c9e367a68a17f4ea10ca135939c0c2cffe28661b4ddb1162b5
4
+ data.tar.gz: 98707957f44e710898f5422f851dd1f1fb42f2694fe69cf2631422764a42498d
5
5
  SHA512:
6
- metadata.gz: 902358ead54f4e37bcb6921f8ac26cb0d365ff90c96f8b1d148286a08a057af719989ed0b24d34e99e646965ca7dbfbcdf2b07d9f28b84d3e00e62d904d8ff3f
7
- data.tar.gz: 33781ec8908342d9aa0670c1ce82516bd7a0fafbed7f49f470765b0d053883cee66b913fc14c060c83abe82dca863653ec7632efcbbcbc4b84dce577eef21764
6
+ metadata.gz: 9e8a23d34101af91fa0dd5c0e1853c54f3dd89c2c3611c319ccc9aa387a7f56347d15278f19a38a660ef1766679663e1432cedd48fd0b1a035b5c215b9df9a44
7
+ data.tar.gz: c6b513830b131fba783984079f68cd3026cec0e3811d045b11b8eef889b878e119067a0f09eaa73d81fc6dd4e52b910c5b7490571b551bf647281ce45cbd21d5
data/README.md CHANGED
@@ -98,6 +98,7 @@ tttls1.3 client is configurable using keyword arguments.
98
98
  | `:ticket_nonce` | String | nil | The ticket\_nonce for PSK. |
99
99
  | `:ticket_age_add` | String | nil | The ticket\_age\_add for PSK. |
100
100
  | `:ticket_timestamp` | Integer | nil | The ticket\_timestamp for PSK. |
101
+ | `:record_size_limit` | Integer | nil | The record\_size\_limit offerd in ClientHello extensions. If not needed to be present, set nil. |
101
102
  | `:compatibility_mode` | Boolean | true | If needed to send ChangeCipherSpec, set true. |
102
103
  | `:loglevel` | Logger constant | Logger::WARN | If needed to print verbose, set Logger::DEBUG. |
103
104
 
@@ -4,10 +4,10 @@
4
4
  require_relative 'helper'
5
5
  require 'etc'
6
6
  require 'logger'
7
+ require 'timeout'
7
8
 
8
9
  port = ARGV[0] || 4433
9
10
 
10
- tcpserver = TCPServer.open(port)
11
11
  settings = {
12
12
  crt_file: __dir__ + '/../tmp/server.crt',
13
13
  key_file: __dir__ + '/../tmp/server.key',
@@ -54,7 +54,6 @@ Etc.nprocessors.times do
54
54
  end
55
55
  # rubocop: enable Metrics/BlockLength
56
56
 
57
- loop do
58
- socket = tcpserver.accept
57
+ Socket.tcp_server_loop(port) do |socket, _addr|
59
58
  q << socket
60
59
  end
@@ -57,6 +57,18 @@ module TTTLS13
57
57
  raise Error::ErrorAlerts, :internal_error
58
58
  end
59
59
  end
60
+
61
+ def auth_tag_len(cipher_suite)
62
+ case cipher_suite
63
+ when TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384,
64
+ TLS_CHACHA20_POLY1305_SHA256 # , TLS_AES_128_CCM_SHA256
65
+ 16
66
+ # when TLS_AES_128_CCM_8_SHA256
67
+ # 8
68
+ else
69
+ raise Error::ErrorAlerts, :internal_error
70
+ end
71
+ end
60
72
  end
61
73
  end
62
74
 
@@ -58,6 +58,7 @@ module TTTLS13
58
58
  ticket_nonce: nil,
59
59
  ticket_age_add: nil,
60
60
  ticket_timestamp: nil,
61
+ record_size_limit: nil,
61
62
  compatibility_mode: true,
62
63
  loglevel: Logger::WARN
63
64
  }.freeze
@@ -282,7 +283,7 @@ module TTTLS13
282
283
  unless (ee.extensions.keys - ch.extensions.keys).empty?
283
284
 
284
285
  rsl = ee.extensions[Message::ExtensionType::RECORD_SIZE_LIMIT]
285
- @send_record_size = rsl.record_size_limit unless rsl.nil?
286
+ @recv_record_size = rsl.record_size_limit unless rsl.nil?
286
287
 
287
288
  @succeed_early_data = true \
288
289
  if ee.extensions.include?(Message::ExtensionType::EARLY_DATA)
@@ -394,6 +395,7 @@ module TTTLS13
394
395
  private
395
396
 
396
397
  # @return [Boolean]
398
+ # rubocop: disable Metrics/AbcSize
397
399
  # rubocop: disable Metrics/CyclomaticComplexity
398
400
  # rubocop: disable Metrics/PerceivedComplexity
399
401
  def valid_settings?
@@ -418,8 +420,12 @@ module TTTLS13
418
420
  unless ksg.nil? ||
419
421
  ((ksg - sg).empty? && sg.select { |g| ksg.include?(g) } == ksg)
420
422
 
423
+ rsl = @settings[:record_size_limit]
424
+ return false if !rsl.nil? && (rsl < 64 || rsl > 2**14 + 1)
425
+
421
426
  true
422
427
  end
428
+ # rubocop: enable Metrics/AbcSize
423
429
  # rubocop: enable Metrics/CyclomaticComplexity
424
430
  # rubocop: enable Metrics/PerceivedComplexity
425
431
 
@@ -465,8 +471,19 @@ module TTTLS13
465
471
  # @return [Hash of NamedGroup => OpenSSL::PKey::EC.$Object]
466
472
  # rubocop: disable Metrics/AbcSize
467
473
  # rubocop: disable Metrics/CyclomaticComplexity
474
+ # rubocop: disable Metrics/PerceivedComplexity
468
475
  def gen_ch_extensions
469
476
  exs = []
477
+ # server_name
478
+ exs << Message::Extension::ServerName.new(@hostname)
479
+
480
+ # record_size_limit
481
+ unless @settings[:record_size_limit].nil?
482
+ exs << Message::Extension::RecordSizeLimit.new(
483
+ @settings[:record_size_limit]
484
+ )
485
+ end
486
+
470
487
  # supported_versions: only TLS 1.3
471
488
  exs << Message::Extension::SupportedVersions.new(
472
489
  msg_type: Message::HandshakeType::CLIENT_HELLO
@@ -495,9 +512,6 @@ module TTTLS13
495
512
  = Message::Extension::KeyShare.gen_ch_key_share(ksg)
496
513
  exs << key_share
497
514
 
498
- # server_name
499
- exs << Message::Extension::ServerName.new(@hostname)
500
-
501
515
  # early_data
502
516
  exs << Message::Extension::EarlyDataIndication.new if use_early_data?
503
517
 
@@ -509,6 +523,7 @@ module TTTLS13
509
523
  end
510
524
  # rubocop: enable Metrics/AbcSize
511
525
  # rubocop: enable Metrics/CyclomaticComplexity
526
+ # rubocop: enable Metrics/PerceivedComplexity
512
527
 
513
528
  # @param extensions [TTTLS13::Message::Extensions]
514
529
  # @param binder_key [String, nil]
@@ -23,6 +23,7 @@ module TTTLS13
23
23
  @signature_scheme = nil # TTTLS13::SignatureScheme
24
24
  @state = 0 # ClientState or ServerState
25
25
  @send_record_size = Message::DEFAULT_RECORD_SIZE_LIMIT
26
+ @recv_record_size = Message::DEFAULT_RECORD_SIZE_LIMIT
26
27
  @alpn = nil # String
27
28
  @exporter_master_secret = nil # String
28
29
  end
@@ -263,7 +264,8 @@ module TTTLS13
263
264
 
264
265
  begin
265
266
  buffer = @binary_buffer
266
- record = Message::Record.deserialize(binary, cipher, buffer)
267
+ record = Message::Record.deserialize(binary, cipher, buffer,
268
+ @recv_record_size)
267
269
  @binary_buffer = record.surplus_binary
268
270
  rescue Error::ErrorAlerts => e
269
271
  terminate(e.message.to_sym)
@@ -5,6 +5,8 @@ module TTTLS13
5
5
  using Refinements
6
6
  module Cryptograph
7
7
  class Aead
8
+ attr_reader :auth_tag_len
9
+
8
10
  # @param cipher_suite [TTTLS13::CipherSuite]
9
11
  # @param write_key [String]
10
12
  # @param write_iv [String]
@@ -31,6 +33,7 @@ module TTTLS13
31
33
  @write_iv = write_iv
32
34
  @sequence_number = sequence_number
33
35
  @length_of_padding = length_of_padding
36
+ @auth_tag_len = CipherSuite.auth_tag_len(@cipher_suite)
34
37
  end
35
38
 
36
39
  # NOTE:
@@ -60,14 +63,15 @@ module TTTLS13
60
63
  #
61
64
  # @raise [OpenSSL::Cipher::CipherError]
62
65
  #
63
- # @return [String and TTTLS13::Message::ContentType]
66
+ # @return [String]
67
+ # @return [TTTLS13::Message::ContentType]
64
68
  def decrypt(encrypted_record, auth_data)
65
69
  reset_cipher
66
70
  decipher = @cipher.decrypt
67
- auth_tag = encrypted_record[-16..-1]
71
+ auth_tag = encrypted_record[-@auth_tag_len..-1]
68
72
  decipher.auth_tag = auth_tag
69
73
  decipher.auth_data = auth_data # record header of TLSCiphertext
70
- clear = decipher.update(encrypted_record[0...-16]) # auth_tag
74
+ clear = decipher.update(encrypted_record[0...-@auth_tag_len])
71
75
  decipher.final
72
76
  zeros_len = scan_zeros(clear)
73
77
  postfix_len = 1 + zeros_len # type || zeros
@@ -94,7 +98,7 @@ module TTTLS13
94
98
 
95
99
  # @return [String]
96
100
  def additional_data(plaintext_len)
97
- ciphertext_len = plaintext_len + 16 # length of auth_tag is 16
101
+ ciphertext_len = plaintext_len + @auth_tag_len
98
102
 
99
103
  Message::ContentType::APPLICATION_DATA \
100
104
  + Message::ProtocolVersion::TLS_1_2 \
@@ -13,7 +13,8 @@ module TTTLS13
13
13
 
14
14
  # @param encrypted_record [String]
15
15
  #
16
- # @return [String and TTTLS13::Message::ContentType]
16
+ # @return [String]
17
+ # @return [TTTLS13::Message::ContentType]
17
18
  def decrypt(encrypted_record, _auth_data)
18
19
  [encrypted_record, encrypted_record[0]]
19
20
  end
@@ -15,7 +15,8 @@ module TTTLS13
15
15
  def initialize(record_size_limit)
16
16
  @extension_type = ExtensionType::RECORD_SIZE_LIMIT
17
17
  @record_size_limit = record_size_limit
18
- raise Error::ErrorAlerts, :internal_error if @record_size_limit < 64
18
+ raise Error::ErrorAlerts, :internal_error \
19
+ if @record_size_limit < 64 || @record_size_limit > 2**14 + 1
19
20
  end
20
21
 
21
22
  # @return [String]
@@ -1,4 +1,3 @@
1
- # encoding: ascii-8bit
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module TTTLS13
@@ -22,7 +21,7 @@ module TTTLS13
22
21
  # @param cipher [TTTLS13::Cryptograph::$Object]
23
22
  def initialize(type:,
24
23
  legacy_record_version: ProtocolVersion::TLS_1_2,
25
- messages: [],
24
+ messages:,
26
25
  surplus_binary: '',
27
26
  cipher:)
28
27
  @type = type
@@ -48,7 +47,6 @@ module TTTLS13
48
47
  else
49
48
  fragments = [tlsplaintext]
50
49
  end
51
- fragments = [''] if fragments.empty?
52
50
 
53
51
  fragments.map do |s|
54
52
  @type + @legacy_record_version \
@@ -63,13 +61,16 @@ module TTTLS13
63
61
  # @param binary [String]
64
62
  # @param cipher [TTTLS13::Cryptograph::$Object]
65
63
  # @param buffered [String] surplus_binary
64
+ # @param record_size_limit [Integer]
66
65
  #
67
66
  # @raise [TTTLS13::Error::ErrorAlerts]
68
67
  #
69
68
  # @return [TTTLS13::Message::Record]
69
+ # rubocop: disable Metrics/AbcSize
70
70
  # rubocop: disable Metrics/CyclomaticComplexity
71
71
  # rubocop: disable Metrics/PerceivedComplexity
72
- def self.deserialize(binary, cipher, buffered = '')
72
+ def self.deserialize(binary, cipher, buffered = '',
73
+ record_size_limit = DEFAULT_RECORD_SIZE_LIMIT)
73
74
  raise Error::ErrorAlerts, :internal_error if binary.nil?
74
75
  raise Error::ErrorAlerts, :decode_error if binary.length < 5
75
76
 
@@ -85,17 +86,22 @@ module TTTLS13
85
86
  unless binary.length == 5 + fragment_len
86
87
 
87
88
  if type == ContentType::APPLICATION_DATA
89
+ if fragment.length - cipher.auth_tag_len > record_size_limit
90
+ raise Error::ErrorAlerts, :record_overflow
91
+ end
92
+
88
93
  fragment, inner_type = cipher.decrypt(fragment, binary.slice(0, 5))
89
94
  end
95
+
90
96
  messages, surplus_binary = deserialize_fragment(buffered + fragment,
91
97
  inner_type || type)
92
-
93
98
  Record.new(type: type,
94
99
  legacy_record_version: legacy_record_version,
95
100
  messages: messages,
96
101
  surplus_binary: surplus_binary,
97
102
  cipher: cipher)
98
103
  end
104
+ # rubocop: enable Metrics/AbcSize
99
105
  # rubocop: enable Metrics/CyclomaticComplexity
100
106
  # rubocop: enable Metrics/PerceivedComplexity
101
107
 
@@ -164,6 +164,10 @@ module TTTLS13
164
164
  terminate(:no_application_protocol) if @alpn.nil?
165
165
  end
166
166
 
167
+ # record_size_limit
168
+ ch_rsl = ch.extensions[Message::ExtensionType::RECORD_SIZE_LIMIT]
169
+ @send_record_size = ch_rsl.record_size_limit unless ch_rsl.nil?
170
+
167
171
  @state = ServerState::RECVD_CH
168
172
  when ServerState::RECVD_CH
169
173
  logger.debug('ServerState::RECVD_CH')
@@ -222,7 +226,9 @@ module TTTLS13
222
226
  logger.debug('ServerState::WAIT_FLIGHT2')
223
227
 
224
228
  ch = transcript[CH]
225
- ee = transcript[EE] = gen_encrypted_extensions(ch, @alpn)
229
+ rsl = @send_record_size \
230
+ unless ch.extensions[Message::ExtensionType::RECORD_SIZE_LIMIT].nil?
231
+ ee = transcript[EE] = gen_encrypted_extensions(ch, @alpn, rsl)
226
232
  # TODO: [Send CertificateRequest]
227
233
  ct = transcript[CT] = gen_certificate(@crt)
228
234
  digest = CipherSuite.digest(@cipher_suite)
@@ -377,11 +383,14 @@ module TTTLS13
377
383
  end
378
384
 
379
385
  # @param ch [TTTLS13::Message::ClientHello]
380
- # @param alpn [String]
386
+ # @param alpn [String, nil]
387
+ # @param record_size_limit [Integer, nil]
381
388
  #
382
389
  # @return [TTTLS13::Message::EncryptedExtensions]
383
- def gen_encrypted_extensions(ch, alpn = nil)
384
- Message::EncryptedExtensions.new(gen_ee_extensions(ch, alpn))
390
+ def gen_encrypted_extensions(ch, alpn = nil, record_size_limit = nil)
391
+ Message::EncryptedExtensions.new(
392
+ gen_ee_extensions(ch, alpn, record_size_limit)
393
+ )
385
394
  end
386
395
 
387
396
  # @param crt [OpenSSL::X509::Certificate]
@@ -440,9 +449,10 @@ module TTTLS13
440
449
 
441
450
  # @param ch [TTTLS13::Message::ClientHello]
442
451
  # @param alpn [String]
452
+ # @param record_size_limit [Integer, nil]
443
453
  #
444
454
  # @return [TTTLS13::Message::Extensions]
445
- def gen_ee_extensions(ch, alpn)
455
+ def gen_ee_extensions(ch, alpn, record_size_limit)
446
456
  exs = []
447
457
 
448
458
  # server_name
@@ -456,6 +466,10 @@ module TTTLS13
456
466
  # alpn
457
467
  exs << Message::Extension::Alpn.new([alpn]) unless alpn.nil?
458
468
 
469
+ # record_size_limit
470
+ exs << Message::Extension::RecordSizeLimit.new(record_size_limit) \
471
+ unless record_size_limit.nil?
472
+
459
473
  Message::Extensions.new(exs)
460
474
  end
461
475
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTTLS13
4
- VERSION = '0.2.7'
4
+ VERSION = '0.2.8'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tttls1.3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - thekuwayama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-19 00:00:00.000000000 Z
11
+ date: 2019-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler