tttls1.3 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +3 -0
- data/.rubocop.yml +16 -0
- data/.travis.yml +8 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +21 -0
- data/README.md +52 -0
- data/Rakefile +133 -0
- data/example/helper.rb +17 -0
- data/example/https_client.rb +32 -0
- data/example/https_client_using_0rtt.rb +64 -0
- data/example/https_client_using_hrr.rb +35 -0
- data/example/https_client_using_ticket.rb +56 -0
- data/lib/tttls1.3/cipher_suites.rb +102 -0
- data/lib/tttls1.3/client.rb +745 -0
- data/lib/tttls1.3/connection.rb +380 -0
- data/lib/tttls1.3/cryptograph/aead.rb +118 -0
- data/lib/tttls1.3/cryptograph/passer.rb +22 -0
- data/lib/tttls1.3/cryptograph.rb +3 -0
- data/lib/tttls1.3/error.rb +22 -0
- data/lib/tttls1.3/key_schedule.rb +242 -0
- data/lib/tttls1.3/message/alert.rb +86 -0
- data/lib/tttls1.3/message/application_data.rb +27 -0
- data/lib/tttls1.3/message/certificate.rb +121 -0
- data/lib/tttls1.3/message/certificate_verify.rb +59 -0
- data/lib/tttls1.3/message/change_cipher_spec.rb +26 -0
- data/lib/tttls1.3/message/client_hello.rb +100 -0
- data/lib/tttls1.3/message/encrypted_extensions.rb +65 -0
- data/lib/tttls1.3/message/end_of_early_data.rb +29 -0
- data/lib/tttls1.3/message/extension/alpn.rb +70 -0
- data/lib/tttls1.3/message/extension/cookie.rb +47 -0
- data/lib/tttls1.3/message/extension/early_data_indication.rb +58 -0
- data/lib/tttls1.3/message/extension/key_share.rb +236 -0
- data/lib/tttls1.3/message/extension/pre_shared_key.rb +205 -0
- data/lib/tttls1.3/message/extension/psk_key_exchange_modes.rb +54 -0
- data/lib/tttls1.3/message/extension/record_size_limit.rb +46 -0
- data/lib/tttls1.3/message/extension/server_name.rb +91 -0
- data/lib/tttls1.3/message/extension/signature_algorithms.rb +69 -0
- data/lib/tttls1.3/message/extension/signature_algorithms_cert.rb +25 -0
- data/lib/tttls1.3/message/extension/status_request.rb +106 -0
- data/lib/tttls1.3/message/extension/supported_groups.rb +145 -0
- data/lib/tttls1.3/message/extension/supported_versions.rb +98 -0
- data/lib/tttls1.3/message/extension/unknown_extension.rb +38 -0
- data/lib/tttls1.3/message/extensions.rb +173 -0
- data/lib/tttls1.3/message/finished.rb +44 -0
- data/lib/tttls1.3/message/new_session_ticket.rb +89 -0
- data/lib/tttls1.3/message/record.rb +232 -0
- data/lib/tttls1.3/message/server_hello.rb +116 -0
- data/lib/tttls1.3/message.rb +48 -0
- data/lib/tttls1.3/sequence_number.rb +31 -0
- data/lib/tttls1.3/signature_scheme.rb +31 -0
- data/lib/tttls1.3/transcript.rb +69 -0
- data/lib/tttls1.3/utils.rb +91 -0
- data/lib/tttls1.3/version.rb +5 -0
- data/lib/tttls1.3.rb +16 -0
- data/spec/aead_spec.rb +95 -0
- data/spec/alert_spec.rb +54 -0
- data/spec/alpn_spec.rb +55 -0
- data/spec/application_data_spec.rb +26 -0
- data/spec/certificate_spec.rb +55 -0
- data/spec/certificate_verify_spec.rb +51 -0
- data/spec/change_cipher_spec_spec.rb +26 -0
- data/spec/cipher_suites_spec.rb +39 -0
- data/spec/client_hello_spec.rb +83 -0
- data/spec/client_spec.rb +319 -0
- data/spec/connection_spec.rb +114 -0
- data/spec/cookie_spec.rb +98 -0
- data/spec/early_data_indication_spec.rb +64 -0
- data/spec/encrypted_extensions_spec.rb +94 -0
- data/spec/error_spec.rb +18 -0
- data/spec/extensions_spec.rb +170 -0
- data/spec/finished_spec.rb +55 -0
- data/spec/key_schedule_spec.rb +198 -0
- data/spec/key_share_spec.rb +199 -0
- data/spec/new_session_ticket_spec.rb +80 -0
- data/spec/pre_shared_key_spec.rb +167 -0
- data/spec/psk_key_exchange_modes_spec.rb +45 -0
- data/spec/record_size_limit_spec.rb +61 -0
- data/spec/record_spec.rb +105 -0
- data/spec/server_hello_spec.rb +101 -0
- data/spec/server_name_spec.rb +110 -0
- data/spec/signature_algorithms_cert_spec.rb +73 -0
- data/spec/signature_algorithms_spec.rb +100 -0
- data/spec/spec_helper.rb +872 -0
- data/spec/status_request_spec.rb +73 -0
- data/spec/supported_groups_spec.rb +79 -0
- data/spec/supported_versions_spec.rb +136 -0
- data/spec/transcript_spec.rb +69 -0
- data/spec/unknown_extension_spec.rb +90 -0
- data/spec/utils_spec.rb +215 -0
- data/tttls1.3.gemspec +25 -0
- metadata +197 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe StatusRequest do
|
8
|
+
context 'default status_request' do
|
9
|
+
let(:extension) do
|
10
|
+
StatusRequest.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be generated' do
|
14
|
+
expect(extension.extension_type).to eq ExtensionType::STATUS_REQUEST
|
15
|
+
expect(extension.responder_id_list).to be_empty
|
16
|
+
expect(extension.request_extensions).to be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should be serialized' do
|
20
|
+
expect(extension.serialize).to eq "\x00\x05\x00\x05\x01\x00\x00\x00\x00"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'valid status_request' do
|
25
|
+
let(:extension) do
|
26
|
+
StatusRequest.new(responder_id_list: [], request_extensions: '')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should be generated' do
|
30
|
+
expect(extension.extension_type).to eq ExtensionType::STATUS_REQUEST
|
31
|
+
expect(extension.responder_id_list).to be_empty
|
32
|
+
expect(extension.request_extensions).to be_empty
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should be serialized' do
|
36
|
+
expect(extension.serialize).to eq "\x00\x05\x00\x05\x01\x00\x00\x00\x00"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'valid status_request, 0 length request ' do
|
41
|
+
let(:extension) do
|
42
|
+
StatusRequest.new(responder_id_list: nil, request_extensions: nil)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should be generated' do
|
46
|
+
expect(extension.extension_type).to eq ExtensionType::STATUS_REQUEST
|
47
|
+
expect(extension.responder_id_list).to be_empty
|
48
|
+
expect(extension.request_extensions).to be_empty
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should be serialized' do
|
52
|
+
expect(extension.serialize).to eq "\x00\x05\x00\x05\x01\x00\x00\x00\x00"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'valid status_request binary' do
|
57
|
+
let(:extension) do
|
58
|
+
StatusRequest.deserialize(TESTBINARY_STATUS_REQUEST)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should generate valid object' do
|
62
|
+
expect(extension.extension_type).to eq ExtensionType::STATUS_REQUEST
|
63
|
+
expect(extension.responder_id_list).to be_empty
|
64
|
+
expect(extension.request_extensions).to be_empty
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should generate serializable object' do
|
68
|
+
expect(extension.serialize)
|
69
|
+
.to eq ExtensionType::STATUS_REQUEST \
|
70
|
+
+ TESTBINARY_STATUS_REQUEST.prefix_uint16_length
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe SupportedGroups do
|
8
|
+
context 'valid supported_groups' do
|
9
|
+
let(:named_group_list) do
|
10
|
+
[NamedGroup::SECP256R1,
|
11
|
+
NamedGroup::SECP384R1]
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:extension) do
|
15
|
+
SupportedGroups.new(named_group_list)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should be generated' do
|
19
|
+
expect(extension.extension_type).to eq ExtensionType::SUPPORTED_GROUPS
|
20
|
+
expect(extension.named_group_list).to eq named_group_list
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should be serialized' do
|
24
|
+
expect(extension.serialize).to eq ExtensionType::SUPPORTED_GROUPS \
|
25
|
+
+ 6.to_uint16 \
|
26
|
+
+ 4.to_uint16 \
|
27
|
+
+ named_group_list.join
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'invalid supported_groups, empty,' do
|
32
|
+
let(:extension) do
|
33
|
+
SupportedGroups.new([])
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should not be generated' do
|
37
|
+
expect { extension }.to raise_error(ErrorAlerts)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'invalid supported_groups, too long,' do
|
42
|
+
let(:extension) do
|
43
|
+
SupportedGroups.new((0..2**15 - 1).to_a.map(&:to_uint16))
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should not be generated' do
|
47
|
+
expect { extension }.to raise_error(ErrorAlerts)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'valid supported_groups binary' do
|
52
|
+
let(:extension) do
|
53
|
+
SupportedGroups.deserialize(TESTBINARY_SUPPORTED_GROUPS)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should generate valid object' do
|
57
|
+
expect(extension.extension_type).to eq ExtensionType::SUPPORTED_GROUPS
|
58
|
+
expect(extension.named_group_list).to eq [NamedGroup::SECP256R1,
|
59
|
+
NamedGroup::SECP384R1,
|
60
|
+
NamedGroup::SECP521R1]
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should generate serializable object' do
|
64
|
+
expect(extension.serialize)
|
65
|
+
.to eq ExtensionType::SUPPORTED_GROUPS \
|
66
|
+
+ TESTBINARY_SUPPORTED_GROUPS.prefix_uint16_length
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'invalid supported_groups binary, malformed binary,' do
|
71
|
+
let(:extension) do
|
72
|
+
SupportedGroups.deserialize(TESTBINARY_SUPPORTED_GROUPS[0...-1])
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should return nil' do
|
76
|
+
expect(extension).to be nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe SupportedVersions do
|
8
|
+
context 'valid supported_versions of ClientHello' do
|
9
|
+
let(:extension) do
|
10
|
+
SupportedVersions.new(
|
11
|
+
msg_type: HandshakeType::CLIENT_HELLO,
|
12
|
+
versions: [ProtocolVersion::TLS_1_3, ProtocolVersion::TLS_1_2]
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should be generated' do
|
17
|
+
expect(extension.extension_type).to eq ExtensionType::SUPPORTED_VERSIONS
|
18
|
+
expect(extension.versions).to eq [ProtocolVersion::TLS_1_3,
|
19
|
+
ProtocolVersion::TLS_1_2]
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should be serialized' do
|
23
|
+
expect(extension.serialize).to eq ExtensionType::SUPPORTED_VERSIONS \
|
24
|
+
+ 5.to_uint16 \
|
25
|
+
+ 4.to_uint8 \
|
26
|
+
+ ProtocolVersion::TLS_1_3 \
|
27
|
+
+ ProtocolVersion::TLS_1_2
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'default supported_versions of ClientHello' do
|
32
|
+
let(:extension) do
|
33
|
+
SupportedVersions.new(msg_type: HandshakeType::CLIENT_HELLO)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should be generated' do
|
37
|
+
expect(extension.extension_type).to eq ExtensionType::SUPPORTED_VERSIONS
|
38
|
+
expect(extension.versions).to eq [ProtocolVersion::TLS_1_3]
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should be serialized' do
|
42
|
+
expect(extension.serialize).to eq ExtensionType::SUPPORTED_VERSIONS \
|
43
|
+
+ 3.to_uint16 \
|
44
|
+
+ 2.to_uint8 \
|
45
|
+
+ ProtocolVersion::TLS_1_3
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'invalid supported_versions of ClientHello, empty,' do
|
50
|
+
let(:extension) do
|
51
|
+
SupportedVersions.new(msg_type: HandshakeType::CLIENT_HELLO,
|
52
|
+
versions: [])
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not be generated' do
|
56
|
+
expect { extension }.to raise_error(ErrorAlerts)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'invalid supported_versions of ClientHello, too large,' do
|
61
|
+
let(:extension) do
|
62
|
+
SupportedVersions.new(msg_type: HandshakeType::CLIENT_HELLO,
|
63
|
+
versions: (0..127).to_a.map(&:to_uint16))
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should not be generated' do
|
67
|
+
expect { extension }.to raise_error(ErrorAlerts)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'valid supported_versions of ServerHello' do
|
72
|
+
let(:extension) do
|
73
|
+
SupportedVersions.new(msg_type: HandshakeType::SERVER_HELLO,
|
74
|
+
versions: [ProtocolVersion::TLS_1_3])
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should be generated' do
|
78
|
+
expect(extension.extension_type).to eq ExtensionType::SUPPORTED_VERSIONS
|
79
|
+
expect(extension.versions).to eq [ProtocolVersion::TLS_1_3]
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should be serialized' do
|
83
|
+
expect(extension.serialize).to eq ExtensionType::SUPPORTED_VERSIONS \
|
84
|
+
+ 2.to_uint16 \
|
85
|
+
+ ProtocolVersion::TLS_1_3
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'invalid supported_versions of ServerHello, empty,' do
|
90
|
+
let(:extension) do
|
91
|
+
SupportedVersions.new(msg_type: HandshakeType::SERVER_HELLO,
|
92
|
+
versions: [])
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should not be generated' do
|
96
|
+
expect { extension }.to raise_error(ErrorAlerts)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'valid supported_versions binary, ClientHello' do
|
101
|
+
let(:extension) do
|
102
|
+
SupportedVersions.deserialize(TESTBINARY_SUPPORTED_VERSIONS_CH,
|
103
|
+
HandshakeType::CLIENT_HELLO)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should generate valid object' do
|
107
|
+
expect(extension.extension_type).to eq ExtensionType::SUPPORTED_VERSIONS
|
108
|
+
expect(extension.versions).to eq [ProtocolVersion::TLS_1_3,
|
109
|
+
ProtocolVersion::TLS_1_2]
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should generate serializable object' do
|
113
|
+
expect(extension.serialize)
|
114
|
+
.to eq ExtensionType::SUPPORTED_VERSIONS \
|
115
|
+
+ TESTBINARY_SUPPORTED_VERSIONS_CH.prefix_uint16_length
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'valid supported_versions binary, ServerHello' do
|
120
|
+
let(:extension) do
|
121
|
+
SupportedVersions.deserialize(TESTBINARY_SUPPORTED_VERSIONS_SH,
|
122
|
+
HandshakeType::SERVER_HELLO)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should generate valid object' do
|
126
|
+
expect(extension.extension_type).to eq ExtensionType::SUPPORTED_VERSIONS
|
127
|
+
expect(extension.versions).to eq [ProtocolVersion::TLS_1_3]
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should generate serializable object' do
|
131
|
+
expect(extension.serialize)
|
132
|
+
.to eq ExtensionType::SUPPORTED_VERSIONS \
|
133
|
+
+ TESTBINARY_SUPPORTED_VERSIONS_SH.prefix_uint16_length
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
RSpec.describe Transcript do
|
7
|
+
context 'transcript, not including HRR,' do
|
8
|
+
let(:transcript) do
|
9
|
+
t = Transcript.new
|
10
|
+
t.merge!(
|
11
|
+
CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
|
12
|
+
SH => ServerHello.deserialize(TESTBINARY_SERVER_HELLO),
|
13
|
+
EE => EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS),
|
14
|
+
CT => Certificate.deserialize(TESTBINARY_CERTIFICATE),
|
15
|
+
CV => CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY),
|
16
|
+
SF => Finished.deserialize(TESTBINARY_SERVER_FINISHED),
|
17
|
+
CF => Finished.deserialize(TESTBINARY_CLIENT_FINISHED)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should return valid transcript-hash' do
|
22
|
+
expect(transcript.hash('SHA256', CF))
|
23
|
+
.to eq TESTBINARY_CH_CF_TRANSCRIPT_HASH
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'transcript, including HRR,' do
|
28
|
+
let(:transcript) do
|
29
|
+
t = Transcript.new
|
30
|
+
t.merge!(
|
31
|
+
CH1 => ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO1),
|
32
|
+
HRR => ServerHello.deserialize(TESTBINARY_HRR_HELLO_RETRY_REQUEST),
|
33
|
+
CH => ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO),
|
34
|
+
SH => ServerHello.deserialize(TESTBINARY_HRR_SERVER_HELLO),
|
35
|
+
EE =>
|
36
|
+
EncryptedExtensions.deserialize(TESTBINARY_HRR_ENCRYPTED_EXTENSIONS),
|
37
|
+
CT => Certificate.deserialize(TESTBINARY_HRR_CERTIFICATE),
|
38
|
+
CV => CertificateVerify.deserialize(TESTBINARY_HRR_CERTIFICATE_VERIFY),
|
39
|
+
SF => Finished.deserialize(TESTBINARY_HRR_SERVER_FINISHED),
|
40
|
+
CF => Finished.deserialize(TESTBINARY_HRR_CLIENT_FINISHED)
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should return valid transcript-hash' do
|
45
|
+
expect(transcript.hash('SHA256', SH))
|
46
|
+
.to eq TESTBINARY_HRR_CH1_SH_TRANSCRIPT_HASH
|
47
|
+
expect(transcript.hash('SHA256', CF))
|
48
|
+
.to eq TESTBINARY_HRR_CH1_CF_TRANSCRIPT_HASH
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'transcript, Resumed 0-RTT Handshake,' do
|
53
|
+
let(:transcript) do
|
54
|
+
t = Transcript.new
|
55
|
+
t.merge!(
|
56
|
+
CH => ClientHello.deserialize(TESTBINARY_0_RTT_CLIENT_HELLO)
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
let(:hash_len) do
|
61
|
+
OpenSSL::Digest.new('SHA256').digest_length
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should return valid transcript-hash' do
|
65
|
+
expect(transcript.truncate_hash('SHA256', CH, hash_len + 3))
|
66
|
+
.to eq TESTBINARY_0_RTT_BINDER_HASH
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe UnknownExtension do
|
8
|
+
context 'valid uknown extension, no extension_data' do
|
9
|
+
let(:extension) do
|
10
|
+
UnknownExtension.new(extension_type: "\x8a\x8a")
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be generated' do
|
14
|
+
expect(extension.extension_type).to eq "\x8a\x8a"
|
15
|
+
expect(extension.extension_data).to be_empty
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should be serialized' do
|
19
|
+
expect(extension.serialize).to eq "\x8a\x8a" + ''.prefix_uint16_length
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'valid uknown extension' do
|
24
|
+
let(:random_bytes) do
|
25
|
+
OpenSSL::Random.random_bytes(20)
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:extension) do
|
29
|
+
UnknownExtension.new(extension_type: "\x8a\x8a",
|
30
|
+
extension_data: random_bytes)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be generated' do
|
34
|
+
expect(extension.extension_type).to eq "\x8a\x8a"
|
35
|
+
expect(extension.extension_data).to eq random_bytes
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should be serialized' do
|
39
|
+
expect(extension.serialize).to eq "\x8a\x8a" \
|
40
|
+
+ random_bytes.prefix_uint16_length
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'invalid uknown extension, no extension_type,' do
|
45
|
+
let(:extension) do
|
46
|
+
UnknownExtension.new
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should not be generated' do
|
50
|
+
expect { extension }.to raise_error(ArgumentError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'valid uknown extension binary, binary is nil,' do
|
55
|
+
let(:extension) do
|
56
|
+
UnknownExtension.deserialize(nil, "\x8a\x8a")
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should generate valid object' do
|
60
|
+
expect(extension.extension_type).to eq "\x8a\x8a"
|
61
|
+
expect(extension.extension_data).to be_empty
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'valid uknown extension binary, binary is empty,' do
|
66
|
+
let(:extension) do
|
67
|
+
UnknownExtension.deserialize([], "\x8a\x8a")
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should generate valid object' do
|
71
|
+
expect(extension.extension_type).to eq "\x8a\x8a"
|
72
|
+
expect(extension.extension_data).to be_empty
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'valid uknown extension binary' do
|
77
|
+
let(:random_bytes) do
|
78
|
+
OpenSSL::Random.random_bytes(20)
|
79
|
+
end
|
80
|
+
|
81
|
+
let(:extension) do
|
82
|
+
UnknownExtension.deserialize(random_bytes, "\x8a\x8a")
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should generate valid object' do
|
86
|
+
expect(extension.extension_type).to eq "\x8a\x8a"
|
87
|
+
expect(extension.extension_data).to eq random_bytes
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/spec/utils_spec.rb
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe TTTLS13::Refinements do
|
8
|
+
context '0' do
|
9
|
+
let(:integer) do
|
10
|
+
0
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should return uint8' do
|
14
|
+
expect(integer.to_uint8).to eq "\x00"
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should return uint16' do
|
18
|
+
expect(integer.to_uint16).to eq "\x00\x00"
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should return uint24' do
|
22
|
+
expect(integer.to_uint24).to eq "\x00\x00\x00"
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should return uint32' do
|
26
|
+
expect(integer.to_uint32).to eq "\x00\x00\x00\x00"
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should return uint64' do
|
30
|
+
expect(integer.to_uint64).to eq "\x00\x00\x00\x00\x00"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context '-1' do
|
35
|
+
let(:integer) do
|
36
|
+
-1
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should not return uint8' do
|
40
|
+
expect { integer.to_uint8 }.to raise_error(ErrorAlerts)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should not return uint16' do
|
44
|
+
expect { integer.to_uint16 }.to raise_error(ErrorAlerts)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should not return uint24' do
|
48
|
+
expect { integer.to_uint24 }.to raise_error(ErrorAlerts)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should not return uint32' do
|
52
|
+
expect { integer.to_uint32 }.to raise_error(ErrorAlerts)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not return uint64' do
|
56
|
+
expect { integer.to_uint64 }.to raise_error(ErrorAlerts)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context '1 << 8' do
|
61
|
+
let(:integer) do
|
62
|
+
1 << 8
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should not return uint8' do
|
66
|
+
expect { integer.to_uint8 }.to raise_error(ErrorAlerts)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should return uint16' do
|
70
|
+
expect(integer.to_uint16).to eq "\x01\x00"
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should return uint24' do
|
74
|
+
expect(integer.to_uint24).to eq "\x00\x01\x00"
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should return uint32' do
|
78
|
+
expect(integer.to_uint32).to eq "\x00\x00\x01\x00"
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should return uint64' do
|
82
|
+
expect(integer.to_uint64).to eq "\x00\x00\x00\x01\x00"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context '1 << 16' do
|
87
|
+
let(:integer) do
|
88
|
+
1 << 16
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should not return uint8' do
|
92
|
+
expect { integer.to_uint8 }.to raise_error(ErrorAlerts)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should not return uint16' do
|
96
|
+
expect { integer.to_uint16 }.to raise_error(ErrorAlerts)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should return uint24' do
|
100
|
+
expect(integer.to_uint24).to eq "\x01\x00\x00"
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should return uint32' do
|
104
|
+
expect(integer.to_uint32).to eq "\x00\x01\x00\x00"
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should return uint64' do
|
108
|
+
expect(integer.to_uint64).to eq "\x00\x00\x01\x00\x00"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context '1 << 24' do
|
113
|
+
let(:integer) do
|
114
|
+
1 << 24
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should not return uint8' do
|
118
|
+
expect { integer.to_uint8 }.to raise_error(ErrorAlerts)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should not return uint16' do
|
122
|
+
expect { integer.to_uint16 }.to raise_error(ErrorAlerts)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should not return uint24' do
|
126
|
+
expect { integer.to_uint24 }.to raise_error(ErrorAlerts)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should return uint32' do
|
130
|
+
expect(integer.to_uint32).to eq "\x01\x00\x00\x00"
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should return uint64' do
|
134
|
+
expect(integer.to_uint64).to eq "\x00\x01\x00\x00\x00"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context '1 << 32' do
|
139
|
+
let(:integer) do
|
140
|
+
1 << 32
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should not return uint8' do
|
144
|
+
expect { integer.to_uint8 }.to raise_error(ErrorAlerts)
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should not return uint16' do
|
148
|
+
expect { integer.to_uint16 }.to raise_error(ErrorAlerts)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should not return uint24' do
|
152
|
+
expect { integer.to_uint24 }.to raise_error(ErrorAlerts)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should not return uint32' do
|
156
|
+
expect { integer.to_uint32 }.to raise_error(ErrorAlerts)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should return uint64' do
|
160
|
+
expect(integer.to_uint64).to eq "\x01\x00\x00\x00\x00"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context '1 << 64' do
|
165
|
+
let(:integer) do
|
166
|
+
1 << 64
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should not return uint8' do
|
170
|
+
expect { integer.to_uint8 }.to raise_error(ErrorAlerts)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should not return uint16' do
|
174
|
+
expect { integer.to_uint16 }.to raise_error(ErrorAlerts)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should not return uint24' do
|
178
|
+
expect { integer.to_uint24 }.to raise_error(ErrorAlerts)
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should not return uint32' do
|
182
|
+
expect { integer.to_uint32 }.to raise_error(ErrorAlerts)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should not return uint64' do
|
186
|
+
expect { integer.to_uint64 }.to raise_error(ErrorAlerts)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'string' do
|
191
|
+
let(:string) do
|
192
|
+
'string'
|
193
|
+
end
|
194
|
+
|
195
|
+
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"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
RSpec.describe Convert do
|
206
|
+
context 'binary' do
|
207
|
+
let(:binary) do
|
208
|
+
"\x01\x23\x45\x67\x89"
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should be converted to integer' do
|
212
|
+
expect(Convert.bin2i(binary)).to eq 4_886_718_345
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
data/tttls1.3.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'tttls1.3/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'tttls1.3'
|
9
|
+
spec.version = TTTLS13::VERSION
|
10
|
+
spec.authors = ['thekuwayama']
|
11
|
+
spec.email = ['thekuwayama@gmail.com']
|
12
|
+
spec.summary = 'TLS 1.3 implementation in Ruby'
|
13
|
+
spec.description = spec.summary
|
14
|
+
spec.homepage = 'https://github.com/thekuwayama/tttls1.3'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
spec.required_ruby_version = '>=2.6.1'
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
24
|
+
spec.add_dependency 'openssl'
|
25
|
+
end
|