tttls1.3 0.2.15 → 0.2.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/README.md +2 -0
- 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/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 +2 -2
- 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/key_schedule_spec.rb +48 -25
- data/spec/record_spec.rb +2 -2
- data/spec/server_spec.rb +23 -11
- data/spec/spec_helper.rb +4 -0
- data/spec/transcript_spec.rb +34 -20
- metadata +7 -3
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
|
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
|
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.16
|
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: 2021-12-08 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,6 +136,7 @@ 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
|
@@ -194,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
197
|
- !ruby/object:Gem::Version
|
195
198
|
version: '0'
|
196
199
|
requirements: []
|
197
|
-
rubygems_version: 3.
|
200
|
+
rubygems_version: 3.2.22
|
198
201
|
signing_key:
|
199
202
|
specification_version: 4
|
200
203
|
summary: TLS 1.3 implementation in Ruby (Tiny Trial TLS1.3 aka tttls1.3)
|
@@ -209,6 +212,7 @@ test_files:
|
|
209
212
|
- spec/cipher_suites_spec.rb
|
210
213
|
- spec/client_hello_spec.rb
|
211
214
|
- spec/client_spec.rb
|
215
|
+
- spec/compress_certificate_spec.rb
|
212
216
|
- spec/connection_spec.rb
|
213
217
|
- spec/cookie_spec.rb
|
214
218
|
- spec/early_data_indication_spec.rb
|