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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +2 -2
- data/.rubocop.yml +5 -1
- data/Gemfile +2 -3
- data/README.md +3 -1
- data/lib/tttls1.3/client.rb +85 -42
- data/lib/tttls1.3/connection.rb +24 -19
- data/lib/tttls1.3/message/client_hello.rb +1 -0
- data/lib/tttls1.3/message/compressed_certificate.rb +82 -0
- data/lib/tttls1.3/message/end_of_early_data.rb +8 -1
- data/lib/tttls1.3/message/extension/alpn.rb +5 -2
- data/lib/tttls1.3/message/extension/compress_certificate.rb +58 -0
- data/lib/tttls1.3/message/extension/signature_algorithms.rb +15 -5
- data/lib/tttls1.3/message/extension/signature_algorithms_cert.rb +5 -4
- data/lib/tttls1.3/message/extension/supported_groups.rb +2 -2
- data/lib/tttls1.3/message/extensions.rb +4 -0
- data/lib/tttls1.3/message/record.rb +28 -16
- data/lib/tttls1.3/message.rb +22 -20
- data/lib/tttls1.3/server.rb +61 -26
- data/lib/tttls1.3/transcript.rb +3 -7
- data/lib/tttls1.3/version.rb +1 -1
- data/spec/client_spec.rb +28 -19
- data/spec/compress_certificate_spec.rb +54 -0
- data/spec/connection_spec.rb +22 -15
- data/spec/end_of_early_data_spec.rb +28 -0
- data/spec/key_schedule_spec.rb +48 -25
- data/spec/record_spec.rb +2 -2
- data/spec/server_spec.rb +23 -11
- data/spec/signature_algorithms_cert_spec.rb +4 -0
- data/spec/signature_algorithms_spec.rb +4 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/transcript_spec.rb +34 -20
- data/tttls1.3.gemspec +1 -2
- metadata +10 -4
data/spec/client_spec.rb
CHANGED
@@ -11,7 +11,7 @@ RSpec.describe Client do
|
|
11
11
|
client = Client.new(mock_socket, 'localhost')
|
12
12
|
extensions, _priv_keys = client.send(:gen_ch_extensions)
|
13
13
|
client.send(:send_client_hello, extensions)
|
14
|
-
Record.deserialize(mock_socket.read, Cryptograph::Passer.new)
|
14
|
+
Record.deserialize(mock_socket.read, Cryptograph::Passer.new).first
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'should send default ClientHello' do
|
@@ -37,7 +37,7 @@ RSpec.describe Client do
|
|
37
37
|
+ msg_len.to_uint16 \
|
38
38
|
+ TESTBINARY_SERVER_HELLO)
|
39
39
|
client = Client.new(mock_socket, 'localhost')
|
40
|
-
client.send(:recv_server_hello)
|
40
|
+
client.send(:recv_server_hello).first
|
41
41
|
end
|
42
42
|
|
43
43
|
it 'should receive ServerHello' do
|
@@ -65,20 +65,20 @@ RSpec.describe Client do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
it 'should receive EncryptedExtensions' do
|
68
|
-
message = client.send(:recv_encrypted_extensions, cipher)
|
68
|
+
message, = client.send(:recv_encrypted_extensions, cipher)
|
69
69
|
expect(message.msg_type).to eq HandshakeType::ENCRYPTED_EXTENSIONS
|
70
70
|
end
|
71
71
|
|
72
72
|
it 'should receive Certificate' do
|
73
73
|
client.send(:recv_encrypted_extensions, cipher) # to skip
|
74
|
-
message = client.send(:recv_certificate, cipher)
|
74
|
+
message, = client.send(:recv_certificate, cipher)
|
75
75
|
expect(message.msg_type).to eq HandshakeType::CERTIFICATE
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'should receive CertificateVerify' do
|
79
79
|
client.send(:recv_encrypted_extensions, cipher) # to skip
|
80
80
|
client.send(:recv_certificate, cipher) # to skip
|
81
|
-
message = client.send(:recv_certificate_verify, cipher)
|
81
|
+
message, = client.send(:recv_certificate_verify, cipher)
|
82
82
|
expect(message.msg_type).to eq HandshakeType::CERTIFICATE_VERIFY
|
83
83
|
end
|
84
84
|
|
@@ -86,7 +86,7 @@ RSpec.describe Client do
|
|
86
86
|
client.send(:recv_encrypted_extensions, cipher) # to skip
|
87
87
|
client.send(:recv_certificate, cipher) # to skip
|
88
88
|
client.send(:recv_certificate_verify, cipher) # to skip
|
89
|
-
message = client.send(:recv_finished, cipher)
|
89
|
+
message, = client.send(:recv_finished, cipher)
|
90
90
|
expect(message.msg_type).to eq HandshakeType::FINISHED
|
91
91
|
end
|
92
92
|
end
|
@@ -97,14 +97,20 @@ RSpec.describe Client do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
let(:transcript) do
|
100
|
+
ch = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
|
101
|
+
sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
|
102
|
+
ee = EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS)
|
103
|
+
ct = Certificate.deserialize(TESTBINARY_CERTIFICATE)
|
104
|
+
cv = CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY)
|
105
|
+
sf = Finished.deserialize(TESTBINARY_SERVER_FINISHED)
|
100
106
|
transcript = Transcript.new
|
101
107
|
transcript.merge!(
|
102
|
-
CH =>
|
103
|
-
SH =>
|
104
|
-
EE =>
|
105
|
-
CT =>
|
106
|
-
CV =>
|
107
|
-
SF =>
|
108
|
+
CH => [ch, TESTBINARY_CLIENT_HELLO],
|
109
|
+
SH => [sh, TESTBINARY_SERVER_HELLO],
|
110
|
+
EE => [ee, TESTBINARY_ENCRYPTED_EXTENSIONS],
|
111
|
+
CT => [ct, TESTBINARY_CERTIFICATE],
|
112
|
+
CV => [cv, TESTBINARY_CERTIFICATE_VERIFY],
|
113
|
+
SF => [sf, TESTBINARY_SERVER_FINISHED]
|
108
114
|
)
|
109
115
|
transcript
|
110
116
|
end
|
@@ -140,7 +146,7 @@ RSpec.describe Client do
|
|
140
146
|
write_iv: TESTBINARY_CLIENT_FINISHED_WRITE_IV,
|
141
147
|
sequence_number: SequenceNumber.new
|
142
148
|
)
|
143
|
-
Record.deserialize(mock_socket.read, hs_rcipher)
|
149
|
+
Record.deserialize(mock_socket.read, hs_rcipher).first
|
144
150
|
end
|
145
151
|
|
146
152
|
it 'should send Finished' do
|
@@ -170,14 +176,17 @@ RSpec.describe Client do
|
|
170
176
|
end
|
171
177
|
|
172
178
|
let(:transcript) do
|
179
|
+
ch = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
|
180
|
+
sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
|
181
|
+
ee = EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS)
|
173
182
|
transcript = Transcript.new
|
174
183
|
transcript.merge!(
|
175
|
-
CH =>
|
176
|
-
SH =>
|
177
|
-
EE =>
|
178
|
-
CT => ct,
|
179
|
-
CV => cv,
|
180
|
-
SF => sf
|
184
|
+
CH => [ch, TESTBINARY_CLIENT_HELLO],
|
185
|
+
SH => [sh, TESTBINARY_SERVER_HELLO],
|
186
|
+
EE => [ee, TESTBINARY_ENCRYPTED_EXTENSIONS],
|
187
|
+
CT => [ct, TESTBINARY_CERTIFICATE],
|
188
|
+
CV => [cv, TESTBINARY_CERTIFICATE_VERIFY],
|
189
|
+
SF => [sf, TESTBINARY_SERVER_FINISHED]
|
181
190
|
)
|
182
191
|
end
|
183
192
|
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe Alpn do
|
8
|
+
context 'valid compress_certificate' do
|
9
|
+
let(:algorithms) do
|
10
|
+
[CertificateCompressionAlgorithm::ZLIB]
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:extension) do
|
14
|
+
CompressCertificate.new(algorithms)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should be generated' do
|
18
|
+
expect(extension.extension_type)
|
19
|
+
.to eq ExtensionType::COMPRESS_CERTIFICATE
|
20
|
+
expect(extension.algorithms).to eq algorithms
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should be serialized' do
|
24
|
+
expect(extension.serialize)
|
25
|
+
.to eq ExtensionType::COMPRESS_CERTIFICATE \
|
26
|
+
+ 3.to_uint16 \
|
27
|
+
+ 2.to_uint8 \
|
28
|
+
+ "\x00\x01"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'invalid compress_certificate, empty,' do
|
33
|
+
let(:extension) do
|
34
|
+
CompressCertificate.new([])
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should not be generated' do
|
38
|
+
expect { extension }.to raise_error(ErrorAlerts)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'valid compress_certificate binary' do
|
43
|
+
let(:extension) do
|
44
|
+
CompressCertificate.deserialize(TESTBINARY_COMPRESS_CERTIFICATE)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should generate valid object' do
|
48
|
+
expect(extension.extension_type)
|
49
|
+
.to eq ExtensionType::COMPRESS_CERTIFICATE
|
50
|
+
expect(extension.algorithms)
|
51
|
+
.to eq [CertificateCompressionAlgorithm::ZLIB]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/spec/connection_spec.rb
CHANGED
@@ -32,15 +32,18 @@ RSpec.describe Connection do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
let(:transcript) do
|
35
|
+
ch = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
|
36
|
+
sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
|
37
|
+
ee = EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS)
|
35
38
|
transcript = Transcript.new
|
36
39
|
transcript.merge!(
|
37
|
-
CH =>
|
38
|
-
SH =>
|
39
|
-
EE =>
|
40
|
-
CT => ct,
|
41
|
-
CV => cv,
|
42
|
-
CF => cf,
|
43
|
-
SF => sf
|
40
|
+
CH => [ch, TESTBINARY_CLIENT_HELLO],
|
41
|
+
SH => [sh, TESTBINARY_SERVER_HELLO],
|
42
|
+
EE => [ee, TESTBINARY_ENCRYPTED_EXTENSIONS],
|
43
|
+
CT => [ct, TESTBINARY_CERTIFICATE],
|
44
|
+
CV => [cv, TESTBINARY_CERTIFICATE_VERIFY],
|
45
|
+
CF => [cf, TESTBINARY_CLIENT_FINISHED],
|
46
|
+
SF => [sf, TESTBINARY_SERVER_FINISHED]
|
44
47
|
)
|
45
48
|
end
|
46
49
|
|
@@ -115,16 +118,20 @@ RSpec.describe Connection do
|
|
115
118
|
end
|
116
119
|
|
117
120
|
let(:transcript) do
|
121
|
+
ch1 = ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO1)
|
122
|
+
hrr = ServerHello.deserialize(TESTBINARY_HRR_HELLO_RETRY_REQUEST)
|
123
|
+
ch = ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO)
|
124
|
+
sh = ServerHello.deserialize(TESTBINARY_HRR_SERVER_HELLO)
|
125
|
+
ee = EncryptedExtensions.deserialize(TESTBINARY_HRR_ENCRYPTED_EXTENSIONS)
|
118
126
|
transcript = Transcript.new
|
119
127
|
transcript.merge!(
|
120
|
-
CH1 =>
|
121
|
-
HRR =>
|
122
|
-
CH =>
|
123
|
-
SH =>
|
124
|
-
EE =>
|
125
|
-
|
126
|
-
|
127
|
-
CV => cv
|
128
|
+
CH1 => [ch1, TESTBINARY_HRR_CLIENT_HELLO1],
|
129
|
+
HRR => [hrr, TESTBINARY_HRR_HELLO_RETRY_REQUEST],
|
130
|
+
CH => [ch, TESTBINARY_HRR_CLIENT_HELLO],
|
131
|
+
SH => [sh, TESTBINARY_HRR_SERVER_HELLO],
|
132
|
+
EE => [ee, TESTBINARY_HRR_ENCRYPTED_EXTENSIONS],
|
133
|
+
CT => [ct, TESTBINARY_HRR_CERTIFICATE],
|
134
|
+
CV => [cv, TESTBINARY_HRR_CERTIFICATE_VERIFY]
|
128
135
|
)
|
129
136
|
end
|
130
137
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe EndOfEarlyData do
|
8
|
+
context 'end_of_early_data' do
|
9
|
+
let(:message) do
|
10
|
+
EndOfEarlyData.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be serialized' do
|
14
|
+
expect(message.serialize).to eq HandshakeType::END_OF_EARLY_DATA \
|
15
|
+
+ ''.prefix_uint24_length
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'valid end_of_early_data binary' do
|
20
|
+
let(:message) do
|
21
|
+
EndOfEarlyData.deserialize(TESTBINARY_0_RTT_END_OF_EARLY_DATA)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should generate valid serializable object' do
|
25
|
+
expect(message.serialize).to eq TESTBINARY_0_RTT_END_OF_EARLY_DATA
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/spec/key_schedule_spec.rb
CHANGED
@@ -6,15 +6,22 @@ require_relative 'spec_helper'
|
|
6
6
|
RSpec.describe KeySchedule do
|
7
7
|
context 'key_schedule, Simple 1-RTT Handshake,' do
|
8
8
|
let(:key_schedule) do
|
9
|
+
ch = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
|
10
|
+
sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
|
11
|
+
ee = EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS)
|
12
|
+
ct = Certificate.deserialize(TESTBINARY_CERTIFICATE)
|
13
|
+
cv = CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY)
|
14
|
+
sf = Finished.deserialize(TESTBINARY_SERVER_FINISHED)
|
15
|
+
cf = Finished.deserialize(TESTBINARY_CLIENT_FINISHED)
|
9
16
|
transcript = Transcript.new
|
10
17
|
transcript.merge!(
|
11
|
-
CH =>
|
12
|
-
SH =>
|
13
|
-
EE =>
|
14
|
-
CT =>
|
15
|
-
CV =>
|
16
|
-
SF =>
|
17
|
-
CF =>
|
18
|
+
CH => [ch, TESTBINARY_CLIENT_HELLO],
|
19
|
+
SH => [sh, TESTBINARY_SERVER_HELLO],
|
20
|
+
EE => [ee, TESTBINARY_ENCRYPTED_EXTENSIONS],
|
21
|
+
CT => [ct, TESTBINARY_CERTIFICATE],
|
22
|
+
CV => [cv, TESTBINARY_CERTIFICATE_VERIFY],
|
23
|
+
SF => [sf, TESTBINARY_SERVER_FINISHED],
|
24
|
+
CF => [cf, TESTBINARY_CLIENT_FINISHED]
|
18
25
|
)
|
19
26
|
KeySchedule.new(shared_secret: TESTBINARY_SHARED_SECRET,
|
20
27
|
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
@@ -77,15 +84,22 @@ RSpec.describe KeySchedule do
|
|
77
84
|
|
78
85
|
context 'key_schedule, Resumed 0-RTT Handshake,' do
|
79
86
|
let(:key_schedule) do
|
87
|
+
ch = ClientHello.deserialize(TESTBINARY_0_RTT_CLIENT_HELLO)
|
88
|
+
sh = ServerHello.deserialize(TESTBINARY_0_RTT_SERVER_HELLO)
|
89
|
+
ee = EncryptedExtensions.deserialize(
|
90
|
+
TESTBINARY_0_RTT_ENCRYPTED_EXTENSIONS
|
91
|
+
)
|
92
|
+
sf = Finished.deserialize(TESTBINARY_0_RTT_SERVER_FINISHED)
|
93
|
+
eoed = EndOfEarlyData.deserialize(TESTBINARY_0_RTT_END_OF_EARLY_DATA)
|
94
|
+
cf = Finished.deserialize(TESTBINARY_0_RTT_CLIENT_FINISHED)
|
80
95
|
transcript = Transcript.new
|
81
96
|
transcript.merge!(
|
82
|
-
CH =>
|
83
|
-
SH =>
|
84
|
-
EE =>
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
CF => Finished.deserialize(TESTBINARY_0_RTT_CLIENT_FINISHED)
|
97
|
+
CH => [ch, TESTBINARY_0_RTT_CLIENT_HELLO],
|
98
|
+
SH => [sh, TESTBINARY_0_RTT_SERVER_HELLO],
|
99
|
+
EE => [ee, TESTBINARY_0_RTT_ENCRYPTED_EXTENSIONS],
|
100
|
+
SF => [sf, TESTBINARY_0_RTT_SERVER_FINISHED],
|
101
|
+
EOED => [eoed, TESTBINARY_0_RTT_END_OF_EARLY_DATA],
|
102
|
+
CF => [cf, TESTBINARY_0_RTT_CLIENT_FINISHED]
|
89
103
|
)
|
90
104
|
KeySchedule.new(psk: TESTBINARY_0_RTT_PSK,
|
91
105
|
shared_secret: TESTBINARY_0_RTT_SHARED_SECRET,
|
@@ -111,8 +125,9 @@ RSpec.describe KeySchedule do
|
|
111
125
|
context 'key_schedule, Resumed 0-RTT Handshake, ' \
|
112
126
|
'not negotiated shared_secret yet,' do
|
113
127
|
let(:key_schedule) do
|
128
|
+
ch = ClientHello.deserialize(TESTBINARY_0_RTT_CLIENT_HELLO)
|
114
129
|
transcript = Transcript.new
|
115
|
-
transcript[CH] =
|
130
|
+
transcript[CH] = [ch, TESTBINARY_0_RTT_CLIENT_HELLO]
|
116
131
|
KeySchedule.new(psk: TESTBINARY_0_RTT_PSK,
|
117
132
|
shared_secret: nil,
|
118
133
|
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
@@ -139,18 +154,26 @@ RSpec.describe KeySchedule do
|
|
139
154
|
|
140
155
|
context 'key_schedule, HelloRetryRequest,' do
|
141
156
|
let(:key_schedule) do
|
157
|
+
ch1 = ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO1)
|
158
|
+
hrr = ServerHello.deserialize(TESTBINARY_HRR_HELLO_RETRY_REQUEST)
|
159
|
+
ch = ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO)
|
160
|
+
sh = ServerHello.deserialize(TESTBINARY_HRR_SERVER_HELLO)
|
161
|
+
ee = EncryptedExtensions.deserialize(TESTBINARY_HRR_ENCRYPTED_EXTENSIONS)
|
162
|
+
ct = Certificate.deserialize(TESTBINARY_HRR_CERTIFICATE)
|
163
|
+
cv = CertificateVerify.deserialize(TESTBINARY_HRR_CERTIFICATE_VERIFY)
|
164
|
+
sf = Finished.deserialize(TESTBINARY_HRR_SERVER_FINISHED)
|
165
|
+
cf = Finished.deserialize(TESTBINARY_HRR_CLIENT_FINISHED)
|
142
166
|
transcript = Transcript.new
|
143
167
|
transcript.merge!(
|
144
|
-
CH1 =>
|
145
|
-
HRR =>
|
146
|
-
CH =>
|
147
|
-
SH =>
|
148
|
-
EE =>
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
CF => Finished.deserialize(TESTBINARY_HRR_CLIENT_FINISHED)
|
168
|
+
CH1 => [ch1, TESTBINARY_HRR_CLIENT_HELLO1],
|
169
|
+
HRR => [hrr, TESTBINARY_HRR_HELLO_RETRY_REQUEST],
|
170
|
+
CH => [ch, TESTBINARY_HRR_CLIENT_HELLO],
|
171
|
+
SH => [sh, TESTBINARY_HRR_SERVER_HELLO],
|
172
|
+
EE => [ee, TESTBINARY_HRR_ENCRYPTED_EXTENSIONS],
|
173
|
+
CT => [ct, TESTBINARY_HRR_CERTIFICATE],
|
174
|
+
CV => [cv, TESTBINARY_HRR_CERTIFICATE_VERIFY],
|
175
|
+
SF => [sf, TESTBINARY_HRR_SERVER_FINISHED],
|
176
|
+
CF => [cf, TESTBINARY_HRR_CLIENT_FINISHED]
|
154
177
|
)
|
155
178
|
KeySchedule.new(shared_secret: TESTBINARY_HRR_SHARED_SECRET,
|
156
179
|
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
data/spec/record_spec.rb
CHANGED
@@ -30,7 +30,7 @@ RSpec.describe Record do
|
|
30
30
|
|
31
31
|
context 'valid record binary' do
|
32
32
|
let(:record) do
|
33
|
-
Record.deserialize(TESTBINARY_RECORD_CCS, Passer.new)
|
33
|
+
Record.deserialize(TESTBINARY_RECORD_CCS, Passer.new).first
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'should generate valid record header and ChangeCipherSpec' do
|
@@ -75,7 +75,7 @@ RSpec.describe Record do
|
|
75
75
|
write_iv: TESTBINARY_SERVER_PARAMETERS_WRITE_IV,
|
76
76
|
sequence_number: SequenceNumber.new
|
77
77
|
)
|
78
|
-
Record.deserialize(TESTBINARY_SERVER_PARAMETERS_RECORD, cipher)
|
78
|
+
Record.deserialize(TESTBINARY_SERVER_PARAMETERS_RECORD, cipher).first
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'should generate valid record header' do
|
data/spec/server_spec.rb
CHANGED
@@ -14,7 +14,7 @@ RSpec.describe Server do
|
|
14
14
|
+ msg_len.to_uint16 \
|
15
15
|
+ TESTBINARY_CLIENT_HELLO)
|
16
16
|
server = Server.new(mock_socket)
|
17
|
-
server.send(:recv_client_hello, true)
|
17
|
+
server.send(:recv_client_hello, true).first
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'should receive ClientHello' do
|
@@ -90,12 +90,16 @@ RSpec.describe Server do
|
|
90
90
|
)
|
91
91
|
end
|
92
92
|
|
93
|
+
let(:ch) do
|
94
|
+
ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
|
95
|
+
end
|
96
|
+
|
93
97
|
let(:server) do
|
94
98
|
Server.new(nil)
|
95
99
|
end
|
96
100
|
|
97
101
|
it 'should generate Certificate' do
|
98
|
-
ct = server.send(:gen_certificate, crt)
|
102
|
+
ct = server.send(:gen_certificate, crt, ch)
|
99
103
|
expect(ct).to be_a_kind_of(Certificate)
|
100
104
|
|
101
105
|
certificate_entry = ct.certificate_list.first
|
@@ -119,12 +123,15 @@ RSpec.describe Server do
|
|
119
123
|
end
|
120
124
|
|
121
125
|
let(:transcript) do
|
126
|
+
ch = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
|
127
|
+
sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
|
128
|
+
ee = EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS)
|
122
129
|
transcript = Transcript.new
|
123
130
|
transcript.merge!(
|
124
|
-
CH =>
|
125
|
-
SH =>
|
126
|
-
EE =>
|
127
|
-
CT => ct
|
131
|
+
CH => [ch, TESTBINARY_CLIENT_HELLO],
|
132
|
+
SH => [sh, TESTBINARY_SERVER_HELLO],
|
133
|
+
EE => [ee, TESTBINARY_ENCRYPTED_EXTENSIONS],
|
134
|
+
CT => [ct, TESTBINARY_CERTIFICATE]
|
128
135
|
)
|
129
136
|
end
|
130
137
|
|
@@ -168,13 +175,18 @@ RSpec.describe Server do
|
|
168
175
|
end
|
169
176
|
|
170
177
|
let(:transcript) do
|
178
|
+
ch = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
|
179
|
+
sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
|
180
|
+
ee = EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS)
|
181
|
+
ct = Certificate.deserialize(TESTBINARY_CERTIFICATE)
|
182
|
+
cv = CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY)
|
171
183
|
transcript = Transcript.new
|
172
184
|
transcript.merge!(
|
173
|
-
CH =>
|
174
|
-
SH =>
|
175
|
-
EE =>
|
176
|
-
CT =>
|
177
|
-
CV =>
|
185
|
+
CH => [ch, TESTBINARY_CLIENT_HELLO],
|
186
|
+
SH => [sh, TESTBINARY_SERVER_HELLO],
|
187
|
+
EE => [ee, TESTBINARY_ENCRYPTED_EXTENSIONS],
|
188
|
+
CT => [ct, TESTBINARY_CERTIFICATE],
|
189
|
+
CV => [cv, TESTBINARY_CERTIFICATE_VERIFY]
|
178
190
|
)
|
179
191
|
transcript
|
180
192
|
end
|
@@ -24,6 +24,8 @@ RSpec.describe SignatureAlgorithmsCert do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'should be generated' do
|
27
|
+
expect(extension).to be_a(SignatureAlgorithmsCert)
|
28
|
+
|
27
29
|
expect(extension.extension_type)
|
28
30
|
.to eq ExtensionType::SIGNATURE_ALGORITHMS_CERT
|
29
31
|
expect(extension.supported_signature_algorithms)
|
@@ -58,6 +60,8 @@ RSpec.describe SignatureAlgorithmsCert do
|
|
58
60
|
end
|
59
61
|
|
60
62
|
it 'should generate valid object' do
|
63
|
+
expect(extension).to be_a(SignatureAlgorithmsCert)
|
64
|
+
|
61
65
|
expect(extension.extension_type)
|
62
66
|
.to eq ExtensionType::SIGNATURE_ALGORITHMS_CERT
|
63
67
|
expect(extension.supported_signature_algorithms)
|
@@ -24,6 +24,8 @@ RSpec.describe SignatureAlgorithms do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'should be generated' do
|
27
|
+
expect(extension).to be_a(SignatureAlgorithms)
|
28
|
+
|
27
29
|
expect(extension.extension_type).to eq ExtensionType::SIGNATURE_ALGORITHMS
|
28
30
|
expect(extension.supported_signature_algorithms)
|
29
31
|
.to eq supported_signature_algorithms
|
@@ -76,6 +78,8 @@ RSpec.describe SignatureAlgorithms do
|
|
76
78
|
end
|
77
79
|
|
78
80
|
it 'should generate valid object' do
|
81
|
+
expect(extension).to be_a(SignatureAlgorithms)
|
82
|
+
|
79
83
|
expect(extension.extension_type).to eq ExtensionType::SIGNATURE_ALGORITHMS
|
80
84
|
expect(extension.supported_signature_algorithms)
|
81
85
|
.to eq supported_signature_algorithms
|
data/spec/spec_helper.rb
CHANGED
@@ -163,6 +163,10 @@ BIN
|
|
163
163
|
|
164
164
|
TESTBINARY_EARLY_DATA_INDICATION_CH = ''
|
165
165
|
|
166
|
+
TESTBINARY_COMPRESS_CERTIFICATE = <<BIN.split.map(&:hex).map(&:chr).join
|
167
|
+
02 00 01
|
168
|
+
BIN
|
169
|
+
|
166
170
|
# https://tools.ietf.org/html/rfc8448#section-3
|
167
171
|
# 2. Private Keys
|
168
172
|
TESTBINARY_PKEY_MODULUS = <<BIN.split.map(&:hex).map(&:chr).join
|
data/spec/transcript_spec.rb
CHANGED
@@ -6,15 +6,22 @@ require_relative 'spec_helper'
|
|
6
6
|
RSpec.describe Transcript do
|
7
7
|
context 'transcript, not including HRR,' do
|
8
8
|
let(:transcript) do
|
9
|
+
ch = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
|
10
|
+
sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
|
11
|
+
ee = EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS)
|
12
|
+
ct = Certificate.deserialize(TESTBINARY_CERTIFICATE)
|
13
|
+
cv = CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY)
|
14
|
+
sf = Finished.deserialize(TESTBINARY_SERVER_FINISHED)
|
15
|
+
cf = Finished.deserialize(TESTBINARY_CLIENT_FINISHED)
|
9
16
|
t = Transcript.new
|
10
17
|
t.merge!(
|
11
|
-
CH =>
|
12
|
-
SH =>
|
13
|
-
EE =>
|
14
|
-
CT =>
|
15
|
-
CV =>
|
16
|
-
SF =>
|
17
|
-
CF =>
|
18
|
+
CH => [ch, TESTBINARY_CLIENT_HELLO],
|
19
|
+
SH => [sh, TESTBINARY_SERVER_HELLO],
|
20
|
+
EE => [ee, TESTBINARY_ENCRYPTED_EXTENSIONS],
|
21
|
+
CT => [ct, TESTBINARY_CERTIFICATE],
|
22
|
+
CV => [cv, TESTBINARY_CERTIFICATE_VERIFY],
|
23
|
+
SF => [sf, TESTBINARY_SERVER_FINISHED],
|
24
|
+
CF => [cf, TESTBINARY_CLIENT_FINISHED]
|
18
25
|
)
|
19
26
|
end
|
20
27
|
|
@@ -26,18 +33,26 @@ RSpec.describe Transcript do
|
|
26
33
|
|
27
34
|
context 'transcript, including HRR,' do
|
28
35
|
let(:transcript) do
|
36
|
+
ch1 = ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO1)
|
37
|
+
hrr = ServerHello.deserialize(TESTBINARY_HRR_HELLO_RETRY_REQUEST)
|
38
|
+
ch = ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO)
|
39
|
+
sh = ServerHello.deserialize(TESTBINARY_HRR_SERVER_HELLO)
|
40
|
+
ee = EncryptedExtensions.deserialize(TESTBINARY_HRR_ENCRYPTED_EXTENSIONS)
|
41
|
+
ct = Certificate.deserialize(TESTBINARY_HRR_CERTIFICATE)
|
42
|
+
cv = CertificateVerify.deserialize(TESTBINARY_HRR_CERTIFICATE_VERIFY)
|
43
|
+
sf = Finished.deserialize(TESTBINARY_HRR_SERVER_FINISHED)
|
44
|
+
cf = Finished.deserialize(TESTBINARY_HRR_CLIENT_FINISHED)
|
29
45
|
t = Transcript.new
|
30
46
|
t.merge!(
|
31
|
-
CH1 =>
|
32
|
-
HRR =>
|
33
|
-
CH =>
|
34
|
-
SH =>
|
35
|
-
EE =>
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
CF => Finished.deserialize(TESTBINARY_HRR_CLIENT_FINISHED)
|
47
|
+
CH1 => [ch1, TESTBINARY_HRR_CLIENT_HELLO1],
|
48
|
+
HRR => [hrr, TESTBINARY_HRR_HELLO_RETRY_REQUEST],
|
49
|
+
CH => [ch, TESTBINARY_HRR_CLIENT_HELLO],
|
50
|
+
SH => [sh, TESTBINARY_HRR_SERVER_HELLO],
|
51
|
+
EE => [ee, TESTBINARY_HRR_ENCRYPTED_EXTENSIONS],
|
52
|
+
CT => [ct, TESTBINARY_HRR_CERTIFICATE],
|
53
|
+
CV => [cv, TESTBINARY_HRR_CERTIFICATE_VERIFY],
|
54
|
+
SF => [sf, TESTBINARY_HRR_SERVER_FINISHED],
|
55
|
+
CF => [cf, TESTBINARY_HRR_CLIENT_FINISHED]
|
41
56
|
)
|
42
57
|
end
|
43
58
|
|
@@ -51,10 +66,9 @@ RSpec.describe Transcript do
|
|
51
66
|
|
52
67
|
context 'transcript, Resumed 0-RTT Handshake,' do
|
53
68
|
let(:transcript) do
|
69
|
+
ch = ClientHello.deserialize(TESTBINARY_0_RTT_CLIENT_HELLO)
|
54
70
|
t = Transcript.new
|
55
|
-
t.merge!(
|
56
|
-
CH => ClientHello.deserialize(TESTBINARY_0_RTT_CLIENT_HELLO)
|
57
|
-
)
|
71
|
+
t.merge!(CH => [ch, TESTBINARY_0_RTT_CLIENT_HELLO])
|
58
72
|
end
|
59
73
|
|
60
74
|
let(:hash_len) do
|
data/tttls1.3.gemspec
CHANGED
@@ -13,10 +13,9 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.description = spec.summary
|
14
14
|
spec.homepage = 'https://github.com/thekuwayama/tttls1.3'
|
15
15
|
spec.license = 'MIT'
|
16
|
-
spec.required_ruby_version = '>=2.
|
16
|
+
spec.required_ruby_version = '>=2.7'
|
17
17
|
|
18
18
|
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
19
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
20
|
spec.require_paths = ['lib']
|
22
21
|
|
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.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thekuwayama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -96,9 +96,11 @@ files:
|
|
96
96
|
- lib/tttls1.3/message/certificate_verify.rb
|
97
97
|
- lib/tttls1.3/message/change_cipher_spec.rb
|
98
98
|
- lib/tttls1.3/message/client_hello.rb
|
99
|
+
- lib/tttls1.3/message/compressed_certificate.rb
|
99
100
|
- lib/tttls1.3/message/encrypted_extensions.rb
|
100
101
|
- lib/tttls1.3/message/end_of_early_data.rb
|
101
102
|
- lib/tttls1.3/message/extension/alpn.rb
|
103
|
+
- lib/tttls1.3/message/extension/compress_certificate.rb
|
102
104
|
- lib/tttls1.3/message/extension/cookie.rb
|
103
105
|
- lib/tttls1.3/message/extension/early_data_indication.rb
|
104
106
|
- lib/tttls1.3/message/extension/key_share.rb
|
@@ -134,10 +136,12 @@ files:
|
|
134
136
|
- spec/cipher_suites_spec.rb
|
135
137
|
- spec/client_hello_spec.rb
|
136
138
|
- spec/client_spec.rb
|
139
|
+
- spec/compress_certificate_spec.rb
|
137
140
|
- spec/connection_spec.rb
|
138
141
|
- spec/cookie_spec.rb
|
139
142
|
- spec/early_data_indication_spec.rb
|
140
143
|
- spec/encrypted_extensions_spec.rb
|
144
|
+
- spec/end_of_early_data_spec.rb
|
141
145
|
- spec/error_spec.rb
|
142
146
|
- spec/extensions_spec.rb
|
143
147
|
- spec/finished_spec.rb
|
@@ -187,14 +191,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
187
191
|
requirements:
|
188
192
|
- - ">="
|
189
193
|
- !ruby/object:Gem::Version
|
190
|
-
version: 2.
|
194
|
+
version: '2.7'
|
191
195
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
192
196
|
requirements:
|
193
197
|
- - ">="
|
194
198
|
- !ruby/object:Gem::Version
|
195
199
|
version: '0'
|
196
200
|
requirements: []
|
197
|
-
rubygems_version: 3.
|
201
|
+
rubygems_version: 3.2.22
|
198
202
|
signing_key:
|
199
203
|
specification_version: 4
|
200
204
|
summary: TLS 1.3 implementation in Ruby (Tiny Trial TLS1.3 aka tttls1.3)
|
@@ -209,10 +213,12 @@ test_files:
|
|
209
213
|
- spec/cipher_suites_spec.rb
|
210
214
|
- spec/client_hello_spec.rb
|
211
215
|
- spec/client_spec.rb
|
216
|
+
- spec/compress_certificate_spec.rb
|
212
217
|
- spec/connection_spec.rb
|
213
218
|
- spec/cookie_spec.rb
|
214
219
|
- spec/early_data_indication_spec.rb
|
215
220
|
- spec/encrypted_extensions_spec.rb
|
221
|
+
- spec/end_of_early_data_spec.rb
|
216
222
|
- spec/error_spec.rb
|
217
223
|
- spec/extensions_spec.rb
|
218
224
|
- spec/finished_spec.rb
|