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 +4 -4
- data/README.md +1 -0
- data/example/https_server.rb +2 -3
- data/lib/tttls1.3/cipher_suites.rb +12 -0
- data/lib/tttls1.3/client.rb +19 -4
- data/lib/tttls1.3/connection.rb +3 -1
- data/lib/tttls1.3/cryptograph/aead.rb +8 -4
- data/lib/tttls1.3/cryptograph/passer.rb +2 -1
- data/lib/tttls1.3/message/extension/record_size_limit.rb +2 -1
- data/lib/tttls1.3/message/record.rb +11 -5
- data/lib/tttls1.3/server.rb +19 -5
- data/lib/tttls1.3/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a040b2151b2f78c9e367a68a17f4ea10ca135939c0c2cffe28661b4ddb1162b5
|
4
|
+
data.tar.gz: 98707957f44e710898f5422f851dd1f1fb42f2694fe69cf2631422764a42498d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
|
data/example/https_server.rb
CHANGED
@@ -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
|
-
|
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
|
|
data/lib/tttls1.3/client.rb
CHANGED
@@ -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
|
-
@
|
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]
|
data/lib/tttls1.3/connection.rb
CHANGED
@@ -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
|
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[
|
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
|
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 +
|
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
|
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
|
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
|
|
data/lib/tttls1.3/server.rb
CHANGED
@@ -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
|
-
|
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(
|
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
|
|
data/lib/tttls1.3/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2019-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|