tttls1.3 0.2.5 → 0.2.6

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: 99aff91ae6a3b3c49b7492320eca02c45372e58e8cc6fcf636363c767e18870b
4
- data.tar.gz: 2c2327dbe62382897b92c2a89b3f74a45735d6ec40ac08f5ca62dc4f07ec8df8
3
+ metadata.gz: 434477f28514352dc19f51a5164df0544e4f10c0902726fb6daea7dd6a3b418e
4
+ data.tar.gz: 2efb6ab4f448b4e96d733f33475e21df10d0286faa8fde16ead1e88d3a4d09b4
5
5
  SHA512:
6
- metadata.gz: c786c4679ca31d9ac60c1d9954cd2fd4e867cf55126a341409bc1aae294df984534861598d5b22643d2d5ab9acefa18cb85b63d7e5cafb90f04e6b41914bf417
7
- data.tar.gz: ec601d3640d8518b0a0d6ae35a1453a9444995db944bfaa48e12c627ca58bc01d31e0ffb0925356d686cd97b7665f556152d3f858a245b501eb981a17ffb8dca
6
+ metadata.gz: 6459d7ac7994d985e6877e599908fd1d18fe35e70f476fc5091a8e59909c08c61ad9d4f9a3356c030fb53ce0a8c10d39d4963bb2f06255f95ae2068e952e88ad
7
+ data.tar.gz: 06efcf0f787fb07c88541df0874046c9b81a7e774d012e548f785fa9a8fcb0abe30bf3cf0da1b6e4f315bd4316b438a37d935bf6cc955104bc1c9bc74aeccf64
data/.rubocop.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 2.6
3
3
 
4
+ Style/NumericLiterals:
5
+ Enabled: false
6
+
4
7
  Style/Documentation:
5
8
  Enabled: false
6
9
 
data/example/README.md ADDED
@@ -0,0 +1,25 @@
1
+ ## Usage
2
+
3
+ The examples use PEM files in `../tmp/`.
4
+
5
+ If you needed those, you could generate example PEM files, `ca.crt`, `ca.key`, `server.crt` and `server.key`, using `rake`.
6
+
7
+ ```bash
8
+ $ rake gen_certs
9
+ ```
10
+
11
+ The examples run as follows:
12
+
13
+ ```bash
14
+ $ ruby https_client.rb
15
+
16
+ $ ruby https_client.rb localhost:4433
17
+ ```
18
+
19
+ Note that `https_server.rb` requires PEM files of certificate and private key.
20
+
21
+ ```bash
22
+ $ ruby https_server.rb
23
+
24
+ $ ruby https_server.rb 4433
25
+ ```
data/example/helper.rb CHANGED
@@ -5,35 +5,58 @@ $LOAD_PATH << __dir__ + '/../lib'
5
5
  require 'socket'
6
6
  require 'tttls1.3'
7
7
  require 'webrick'
8
+ require 'http/parser'
9
+ require 'time'
8
10
 
9
- def simple_http_request(hostname)
10
- s = <<~BIN
11
- GET / HTTP/1.1
11
+ def simple_http_request(hostname, path = '/')
12
+ s = <<~REQUEST
13
+ GET #{path} HTTP/1.1
12
14
  Host: #{hostname}
13
- User-Agent: https_client
15
+ User-Agent: tttls1.3/examples
14
16
  Accept: */*
15
17
 
16
- BIN
17
- s.gsub("\n", "\r\n")
18
+ REQUEST
19
+
20
+ s.gsub(WEBrick::LF, WEBrick::CRLF)
21
+ end
22
+
23
+ def simple_http_response(body)
24
+ s = <<~RESPONSE
25
+ HTTP/1.1 200 OK
26
+ Date: #{Time.now.httpdate}
27
+ Content-Type: text/html
28
+ Content-Length: #{body.length}
29
+ Server: tttls1.3/examples
30
+
31
+ #{body}
32
+ RESPONSE
33
+
34
+ s.gsub(WEBrick::LF, WEBrick::CRLF)
18
35
  end
19
36
 
20
37
  def recv_http_response(client)
21
- # status line, header
22
- buf = ''
23
- buf += client.read until buf.include?(WEBrick::CRLF * 2)
24
- header = buf.split(WEBrick::CRLF * 2).first
25
- # header; Content-Length
26
- cl_line = header.split(WEBrick::CRLF).find { |s| s.match(/Content-Length:/i) }
27
-
28
- # body
29
- unless cl_line.nil?
30
- cl = cl_line.split(':').last.to_i
31
- buf = buf.split(WEBrick::CRLF * 2)[1..].join
32
- while buf.length < cl
33
- s = client.read
34
- buf += s
35
- end
38
+ parser = HTTP::Parser.new
39
+ buf = nil
40
+
41
+ parser.on_headers_complete = proc do |headers|
42
+ buf =
43
+ [
44
+ 'HTTP/' + parser.http_version.join('.'),
45
+ parser.status_code,
46
+ WEBrick::HTTPStatus.reason_phrase(parser.status_code)
47
+ ].join(' ') + "\r\n" \
48
+ + headers.map { |k, v| k + ': ' + v + WEBrick::CRLF }.join \
49
+ + WEBrick::CRLF
50
+ end
51
+
52
+ parser.on_body = proc do |chunk|
53
+ buf += chunk
54
+ end
55
+
56
+ parser.on_message_complete = proc do
57
+ client.close
36
58
  end
37
59
 
38
- header + WEBrick::CRLF * 2 + buf
60
+ parser << client.read until client.eof?
61
+ buf
39
62
  end
@@ -4,15 +4,18 @@
4
4
  require_relative 'helper'
5
5
 
6
6
  hostname, port = (ARGV[0] || 'localhost:4433').split(':')
7
+ ca_file = __dir__ + '/../tmp/ca.crt'
7
8
  req = simple_http_request(hostname)
8
9
 
9
10
  socket = TCPSocket.new(hostname, port)
10
11
  settings = {
11
- ca_file: __dir__ + '/../tmp/ca.crt',
12
- alpn: ['http/1.1', 'http/1.0']
12
+ ca_file: File.exist?(ca_file) ? ca_file : nil,
13
+ alpn: ['http/1.1']
13
14
  }
14
15
  client = TTTLS13::Client.new(socket, hostname, settings)
15
16
  client.connect
16
17
  client.write(req)
18
+
17
19
  print recv_http_response(client)
18
- client.close
20
+ client.close unless client.eof?
21
+ socket.close
@@ -4,11 +4,12 @@
4
4
  require_relative 'helper'
5
5
 
6
6
  hostname, port = (ARGV[0] || 'localhost:4433').split(':')
7
+ ca_file = __dir__ + '/../tmp/ca.crt'
7
8
  req = simple_http_request(hostname)
8
9
 
9
10
  settings_2nd = {
10
- ca_file: __dir__ + '/../tmp/ca.crt',
11
- alpn: ['http/1.1', 'http/1.0']
11
+ ca_file: File.exist?(ca_file) ? ca_file : nil,
12
+ alpn: ['http/1.1']
12
13
  }
13
14
  process_new_session_ticket = proc do |nst, rms, cs|
14
15
  return if Time.now.to_i - nst.timestamp > nst.ticket_lifetime
@@ -21,8 +22,8 @@ process_new_session_ticket = proc do |nst, rms, cs|
21
22
  settings_2nd[:ticket_timestamp] = nst.timestamp
22
23
  end
23
24
  settings_1st = {
24
- ca_file: __dir__ + '/../tmp/ca.crt',
25
- alpn: ['http/1.1', 'http/1.0'],
25
+ ca_file: FileTest.exists?(ca_file) ? ca_file : nil,
26
+ alpn: ['http/1.1'],
26
27
  process_new_session_ticket: process_new_session_ticket
27
28
  }
28
29
 
@@ -43,7 +44,8 @@ succeed_early_data = false
43
44
  # send message after Simple 1-RTT Handshake
44
45
  client.write(req) if i.zero? || !client.succeed_early_data?
45
46
  print recv_http_response(client)
46
- client.close
47
+ client.close unless client.eof?
48
+ socket.close
47
49
 
48
50
  succeed_early_data = client.succeed_early_data?
49
51
  end
@@ -4,16 +4,18 @@
4
4
  require_relative 'helper'
5
5
 
6
6
  hostname, port = (ARGV[0] || 'localhost:4433').split(':')
7
+ ca_file = __dir__ + '/../tmp/ca.crt'
7
8
  req = simple_http_request(hostname)
8
9
 
9
10
  socket = TCPSocket.new(hostname, port)
10
11
  settings = {
11
- ca_file: __dir__ + '/../tmp/ca.crt',
12
+ ca_file: File.exist?(ca_file) ? ca_file : nil,
12
13
  key_share_groups: [], # empty KeyShareClientHello.client_shares
13
- alpn: ['http/1.1', 'http/1.0']
14
+ alpn: ['http/1.1']
14
15
  }
15
16
  client = TTTLS13::Client.new(socket, hostname, settings)
16
17
  client.connect
17
18
  client.write(req)
18
19
  print recv_http_response(client)
19
- client.close
20
+ client.close unless client.eof?
21
+ socket.close
@@ -4,11 +4,12 @@
4
4
  require_relative 'helper'
5
5
 
6
6
  hostname, port = (ARGV[0] || 'localhost:4433').split(':')
7
+ ca_file = __dir__ + '/../tmp/ca.crt'
7
8
  req = simple_http_request(hostname)
8
9
 
9
10
  settings_2nd = {
10
- ca_file: __dir__ + '/../tmp/ca.crt',
11
- alpn: ['http/1.1', 'http/1.0']
11
+ ca_file: File.exist?(ca_file) ? ca_file : nil,
12
+ alpn: ['http/1.1']
12
13
  }
13
14
  process_new_session_ticket = proc do |nst, rms, cs|
14
15
  return if Time.now.to_i - nst.timestamp > nst.ticket_lifetime
@@ -22,8 +23,8 @@ process_new_session_ticket = proc do |nst, rms, cs|
22
23
  settings_2nd[:ticket_timestamp] = nst.timestamp
23
24
  end
24
25
  settings_1st = {
25
- ca_file: __dir__ + '/../tmp/ca.crt',
26
- alpn: ['http/1.1', 'http/1.0'],
26
+ ca_file: File.exist?(ca_file) ? ca_file : nil,
27
+ alpn: ['http/1.1'],
27
28
  process_new_session_ticket: process_new_session_ticket
28
29
  }
29
30
 
@@ -38,5 +39,6 @@ settings_1st = {
38
39
  client.connect
39
40
  client.write(req)
40
41
  print recv_http_response(client)
41
- client.close
42
+ client.close unless client.eof?
43
+ socket.close
42
44
  end
@@ -4,11 +4,12 @@
4
4
  require_relative 'helper'
5
5
 
6
6
  hostname, port = (ARGV[0] || 'localhost:4433').split(':')
7
+ ca_file = __dir__ + '/../tmp/ca.crt'
7
8
  req = simple_http_request(hostname)
8
9
 
9
10
  settings_2nd = {
10
- ca_file: __dir__ + '/../tmp/ca.crt',
11
- alpn: ['http/1.1', 'http/1.0']
11
+ ca_file: File.exist?(ca_file) ? ca_file : nil,
12
+ alpn: ['http/1.1']
12
13
  }
13
14
  process_new_session_ticket = proc do |nst, rms, cs|
14
15
  return if Time.now.to_i - nst.timestamp > nst.ticket_lifetime
@@ -21,8 +22,8 @@ process_new_session_ticket = proc do |nst, rms, cs|
21
22
  settings_2nd[:ticket_timestamp] = nst.timestamp
22
23
  end
23
24
  settings_1st = {
24
- ca_file: __dir__ + '/../tmp/ca.crt',
25
- alpn: ['http/1.1', 'http/1.0'],
25
+ ca_file: File.exist?(ca_file) ? ca_file : nil,
26
+ alpn: ['http/1.1'],
26
27
  process_new_session_ticket: process_new_session_ticket
27
28
  }
28
29
 
@@ -37,5 +38,6 @@ settings_1st = {
37
38
  client.connect
38
39
  client.write(req)
39
40
  print recv_http_response(client)
40
- client.close
41
+ client.close unless client.eof?
42
+ socket.close
41
43
  end
@@ -2,6 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require_relative 'helper'
5
+ require 'etc'
6
+ require 'logger'
5
7
 
6
8
  port = ARGV[0] || 4433
7
9
 
@@ -9,38 +11,50 @@ tcpserver = TCPServer.open(port)
9
11
  settings = {
10
12
  crt_file: __dir__ + '/../tmp/server.crt',
11
13
  key_file: __dir__ + '/../tmp/server.key',
12
- alpn: ['http/1.1', 'http/1.0']
14
+ alpn: ['http/1.1']
13
15
  }
14
16
 
17
+ q = Queue.new
18
+ logger = Logger.new(STDERR, Logger::WARN)
15
19
  # rubocop: disable Metrics/BlockLength
16
- loop do
17
- socket = tcpserver.accept
18
- Thread.start(socket) do |s|
19
- Timeout.timeout(5) do
20
- server = TTTLS13::Server.new(s, settings)
21
- server.accept
22
- buffer = ''
23
- buffer += server.read until buffer.include?(WEBrick::CRLF * 2)
24
- req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
25
- req.parse(StringIO.new(buffer))
26
- puts req.to_s
27
- res = WEBrick::HTTPResponse.new(WEBrick::Config::HTTP)
28
- res.status = 200
29
- res.body = 'Hello'
30
- res.content_length = 5
31
- res.content_type = 'text/html'
32
- server.write(
33
- res.status_line \
34
- + res.header.map { |k, v| k + ': ' + v }.join(WEBrick::CRLF) \
35
- + WEBrick::CRLF * 2 \
36
- + res.body
37
- )
38
- server.close
20
+ Etc.nprocessors.times do
21
+ Thread.start do
22
+ loop do
23
+ s = q.pop
24
+ Timeout.timeout(1) do
25
+ server = TTTLS13::Server.new(s, settings)
26
+ parser = HTTP::Parser.new
27
+
28
+ parser.on_message_complete = proc do
29
+ if !parser.http_method.nil?
30
+ logger.info 'Receive Request'
31
+ server.write(simple_http_response('TEST'))
32
+ server.close
33
+ else
34
+ logger.warn 'Not Request'
35
+ end
36
+ end
37
+
38
+ begin
39
+ server.accept
40
+ parser << server.read until server.eof?
41
+ rescue HTTP::Parser::Error, TTTLS13::Error::ErrorAlerts
42
+ logger.warn 'Parser Error'
43
+ ensure
44
+ server.close unless server.eof?
45
+ parser.reset!
46
+ end
47
+ end
48
+ rescue Timeout::Error
49
+ logger.warn 'Timeout'
50
+ ensure
51
+ s.close
39
52
  end
40
- rescue Timeout::Error => e
41
- puts e.to_s + "\n\n"
42
- ensure
43
- s.close
44
53
  end
45
54
  end
46
55
  # rubocop: enable Metrics/BlockLength
56
+
57
+ loop do
58
+ socket = tcpserver.accept
59
+ q << socket
60
+ end
@@ -151,10 +151,10 @@ RSpec.describe Client do
151
151
  ],
152
152
  [
153
153
  true,
154
- '-alpn http/1.1',
154
+ '-alpn http/1.0',
155
155
  'rsa_rsa.crt',
156
156
  'rsa_rsa.key',
157
- alpn: ['http/1.1']
157
+ alpn: ['http/1.0']
158
158
  ],
159
159
  [
160
160
  true,
@@ -146,24 +146,24 @@ RSpec.describe Server do
146
146
  ],
147
147
  [
148
148
  true,
149
- '-groups P-256:P-384:P-521 -alpn http/1.1',
149
+ '-groups P-256:P-384:P-521 -alpn pingpong',
150
150
  FIXTURES_DIR + '/rsa_rsa.crt',
151
151
  FIXTURES_DIR + '/rsa_rsa.key',
152
- alpn: ['http/1.1']
152
+ alpn: ['pingpong']
153
153
  ],
154
154
  [
155
155
  true,
156
156
  '-groups P-256:P-384:P-521',
157
157
  FIXTURES_DIR + '/rsa_rsa.crt',
158
158
  FIXTURES_DIR + '/rsa_rsa.key',
159
- alpn: ['http/1.1']
159
+ alpn: ['pingpong']
160
160
  ],
161
161
  [
162
162
  false,
163
163
  '-groups P-256:P-384:P-521 -alpn foo',
164
164
  FIXTURES_DIR + '/rsa_rsa.crt',
165
165
  FIXTURES_DIR + '/rsa_rsa.key',
166
- alpn: ['http/1.1']
166
+ alpn: ['pingpong']
167
167
  ],
168
168
  [
169
169
  true,
@@ -169,12 +169,17 @@ module TTTLS13
169
169
 
170
170
  sh = transcript[SH] = recv_server_hello
171
171
 
172
+ # downgrade protection
173
+ if !sh.negotiated_tls_1_3? && sh.downgraded?
174
+ terminate(:illegal_parameter)
172
175
  # support only TLS 1.3
173
- terminate(:protocol_version) unless sh.negotiated_tls_1_3?
176
+ elsif !sh.negotiated_tls_1_3?
177
+ terminate(:protocol_version)
178
+ end
174
179
 
175
180
  # validate parameters
176
- terminate(:illegal_parameter) unless sh.appearable_extensions?
177
- terminate(:illegal_parameter) if sh.downgraded?
181
+ terminate(:illegal_parameter) \
182
+ unless sh.appearable_extensions?
178
183
  terminate(:illegal_parameter) \
179
184
  unless sh.legacy_compression_method == "\x00"
180
185
 
@@ -66,7 +66,7 @@ module TTTLS13
66
66
  #
67
67
  # @raise [TTTLS13::Error::ErrorAlerts]
68
68
  #
69
- # @return [TTTLS13::Message::Record, String]
69
+ # @return [TTTLS13::Message::Record]
70
70
  # rubocop: disable Metrics/CyclomaticComplexity
71
71
  # rubocop: disable Metrics/PerceivedComplexity
72
72
  def self.deserialize(binary, cipher, buffered = '')
@@ -140,7 +140,7 @@ module TTTLS13
140
140
  #
141
141
  # @raise [TTTLS13::Error::ErrorAlerts]
142
142
  #
143
- # @return [Array of TTTLS13::Message::$Object, String]
143
+ # @return [Array of TTTLS13::Message::$Object]
144
144
  # @return [String]
145
145
  def deserialize_fragment(binary, type)
146
146
  raise Error::ErrorAlerts, :internal_error if binary.nil?
@@ -15,46 +15,28 @@ module TTTLS13
15
15
  raise Error::ErrorAlerts, :internal_error \
16
16
  if negative? || self >= (1 << 16)
17
17
 
18
- [
19
- self / (1 << 8),
20
- self % (1 << 8)
21
- ].map(&:chr).join
18
+ [self].pack('n')
22
19
  end
23
20
 
24
21
  def to_uint24
25
22
  raise Error::ErrorAlerts, :internal_error \
26
23
  if negative? || self >= (1 << 24)
27
24
 
28
- [
29
- self / (1 << 16),
30
- self % (1 << 16) / (1 << 8),
31
- self % (1 << 8)
32
- ].map(&:chr).join
25
+ [self].pack('N1')[1..]
33
26
  end
34
27
 
35
28
  def to_uint32
36
29
  raise Error::ErrorAlerts, :internal_error \
37
30
  if negative? || self >= (1 << 32)
38
31
 
39
- [
40
- self / (1 << 24),
41
- self % (1 << 24) / (1 << 16),
42
- self % (1 << 16) / (1 << 8),
43
- self % (1 << 8)
44
- ].map(&:chr).join
32
+ [self].pack('N1')
45
33
  end
46
34
 
47
35
  def to_uint64
48
36
  raise Error::ErrorAlerts, :internal_error \
49
37
  if negative? || self >= (1 << 64)
50
38
 
51
- [
52
- self / (1 << 32),
53
- self % (1 << 32) / (1 << 24),
54
- self % (1 << 24) / (1 << 16),
55
- self % (1 << 16) / (1 << 8),
56
- self % (1 << 8)
57
- ].map(&:chr).join
39
+ [self >> 32, self].pack('N2')
58
40
  end
59
41
  end
60
42
 
@@ -84,7 +66,7 @@ module TTTLS13
84
66
  module Convert
85
67
  class << self
86
68
  def bin2i(binary)
87
- binary.unpack('C*').reverse.map.with_index { |x, i| x << 8 * i }.sum
69
+ OpenSSL::BN.new(binary, 2).to_i
88
70
  end
89
71
  end
90
72
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTTLS13
4
- VERSION = '0.2.5'
4
+ VERSION = '0.2.6'
5
5
  end
data/spec/utils_spec.rb CHANGED
@@ -11,23 +11,28 @@ RSpec.describe TTTLS13::Refinements do
11
11
  end
12
12
 
13
13
  it 'should return uint8' do
14
+ expect(integer.to_uint8.length).to eq 1
14
15
  expect(integer.to_uint8).to eq "\x00"
15
16
  end
16
17
 
17
18
  it 'should return uint16' do
19
+ expect(integer.to_uint16.length).to eq 2
18
20
  expect(integer.to_uint16).to eq "\x00\x00"
19
21
  end
20
22
 
21
23
  it 'should return uint24' do
24
+ expect(integer.to_uint24.length).to eq 3
22
25
  expect(integer.to_uint24).to eq "\x00\x00\x00"
23
26
  end
24
27
 
25
28
  it 'should return uint32' do
29
+ expect(integer.to_uint32.length).to eq 4
26
30
  expect(integer.to_uint32).to eq "\x00\x00\x00\x00"
27
31
  end
28
32
 
29
33
  it 'should return uint64' do
30
- expect(integer.to_uint64).to eq "\x00\x00\x00\x00\x00"
34
+ expect(integer.to_uint64.length).to eq 8
35
+ expect(integer.to_uint64).to eq "\x00\x00\x00\x00\x00\x00\x00\x00"
31
36
  end
32
37
  end
33
38
 
@@ -67,19 +72,23 @@ RSpec.describe TTTLS13::Refinements do
67
72
  end
68
73
 
69
74
  it 'should return uint16' do
75
+ expect(integer.to_uint16.length).to eq 2
70
76
  expect(integer.to_uint16).to eq "\x01\x00"
71
77
  end
72
78
 
73
79
  it 'should return uint24' do
80
+ expect(integer.to_uint24.length).to eq 3
74
81
  expect(integer.to_uint24).to eq "\x00\x01\x00"
75
82
  end
76
83
 
77
84
  it 'should return uint32' do
85
+ expect(integer.to_uint32.length).to eq 4
78
86
  expect(integer.to_uint32).to eq "\x00\x00\x01\x00"
79
87
  end
80
88
 
81
89
  it 'should return uint64' do
82
- expect(integer.to_uint64).to eq "\x00\x00\x00\x01\x00"
90
+ expect(integer.to_uint64.length).to eq 8
91
+ expect(integer.to_uint64).to eq "\x00\x00\x00\x00\x00\x00\x01\x00"
83
92
  end
84
93
  end
85
94
 
@@ -97,15 +106,18 @@ RSpec.describe TTTLS13::Refinements do
97
106
  end
98
107
 
99
108
  it 'should return uint24' do
109
+ expect(integer.to_uint24.length).to eq 3
100
110
  expect(integer.to_uint24).to eq "\x01\x00\x00"
101
111
  end
102
112
 
103
113
  it 'should return uint32' do
114
+ expect(integer.to_uint32.length).to eq 4
104
115
  expect(integer.to_uint32).to eq "\x00\x01\x00\x00"
105
116
  end
106
117
 
107
118
  it 'should return uint64' do
108
- expect(integer.to_uint64).to eq "\x00\x00\x01\x00\x00"
119
+ expect(integer.to_uint64.length).to eq 8
120
+ expect(integer.to_uint64).to eq "\x00\x00\x00\x00\x00\x01\x00\x00"
109
121
  end
110
122
  end
111
123
 
@@ -127,11 +139,13 @@ RSpec.describe TTTLS13::Refinements do
127
139
  end
128
140
 
129
141
  it 'should return uint32' do
142
+ expect(integer.to_uint32.length).to eq 4
130
143
  expect(integer.to_uint32).to eq "\x01\x00\x00\x00"
131
144
  end
132
145
 
133
146
  it 'should return uint64' do
134
- expect(integer.to_uint64).to eq "\x00\x01\x00\x00\x00"
147
+ expect(integer.to_uint64.length).to eq 8
148
+ expect(integer.to_uint64).to eq "\x00\x00\x00\x00\x01\x00\x00\x00"
135
149
  end
136
150
  end
137
151
 
@@ -157,7 +171,8 @@ RSpec.describe TTTLS13::Refinements do
157
171
  end
158
172
 
159
173
  it 'should return uint64' do
160
- expect(integer.to_uint64).to eq "\x01\x00\x00\x00\x00"
174
+ expect(integer.to_uint64.length).to eq 8
175
+ expect(integer.to_uint64).to eq "\x00\x00\x00\x01\x00\x00\x00\x00"
161
176
  end
162
177
  end
163
178
 
@@ -193,11 +208,16 @@ RSpec.describe TTTLS13::Refinements do
193
208
  end
194
209
 
195
210
  it 'should be prefixed' do
196
- expect(string.prefix_uint8_length).to eq "\x06string"
197
- expect(string.prefix_uint16_length).to eq "\x00\x06string"
198
- expect(string.prefix_uint24_length).to eq "\x00\x00\x06string"
199
- expect(string.prefix_uint32_length).to eq "\x00\x00\x00\x06string"
200
- expect(string.prefix_uint64_length).to eq "\x00\x00\x00\x00\x06string"
211
+ expect(string.prefix_uint8_length)
212
+ .to eq "\x06string"
213
+ expect(string.prefix_uint16_length)
214
+ .to eq "\x00\x06string"
215
+ expect(string.prefix_uint24_length)
216
+ .to eq "\x00\x00\x06string"
217
+ expect(string.prefix_uint32_length)
218
+ .to eq "\x00\x00\x00\x06string"
219
+ expect(string.prefix_uint64_length)
220
+ .to eq "\x00\x00\x00\x00\x00\x00\x00\x06string"
201
221
  end
202
222
  end
203
223
  end
@@ -209,7 +229,7 @@ RSpec.describe Convert do
209
229
  end
210
230
 
211
231
  it 'should be converted to integer' do
212
- expect(Convert.bin2i(binary)).to eq 4_886_718_345
232
+ expect(Convert.bin2i(binary)).to eq 4886718345
213
233
  end
214
234
  end
215
235
  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.5
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - thekuwayama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-24 00:00:00.000000000 Z
11
+ date: 2019-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,6 +67,7 @@ files:
67
67
  - LICENSE.txt
68
68
  - README.md
69
69
  - Rakefile
70
+ - example/README.md
70
71
  - example/helper.rb
71
72
  - example/https_client.rb
72
73
  - example/https_client_using_0rtt.rb