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.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +16 -0
  5. data/.travis.yml +8 -0
  6. data/Gemfile +13 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +52 -0
  9. data/Rakefile +133 -0
  10. data/example/helper.rb +17 -0
  11. data/example/https_client.rb +32 -0
  12. data/example/https_client_using_0rtt.rb +64 -0
  13. data/example/https_client_using_hrr.rb +35 -0
  14. data/example/https_client_using_ticket.rb +56 -0
  15. data/lib/tttls1.3/cipher_suites.rb +102 -0
  16. data/lib/tttls1.3/client.rb +745 -0
  17. data/lib/tttls1.3/connection.rb +380 -0
  18. data/lib/tttls1.3/cryptograph/aead.rb +118 -0
  19. data/lib/tttls1.3/cryptograph/passer.rb +22 -0
  20. data/lib/tttls1.3/cryptograph.rb +3 -0
  21. data/lib/tttls1.3/error.rb +22 -0
  22. data/lib/tttls1.3/key_schedule.rb +242 -0
  23. data/lib/tttls1.3/message/alert.rb +86 -0
  24. data/lib/tttls1.3/message/application_data.rb +27 -0
  25. data/lib/tttls1.3/message/certificate.rb +121 -0
  26. data/lib/tttls1.3/message/certificate_verify.rb +59 -0
  27. data/lib/tttls1.3/message/change_cipher_spec.rb +26 -0
  28. data/lib/tttls1.3/message/client_hello.rb +100 -0
  29. data/lib/tttls1.3/message/encrypted_extensions.rb +65 -0
  30. data/lib/tttls1.3/message/end_of_early_data.rb +29 -0
  31. data/lib/tttls1.3/message/extension/alpn.rb +70 -0
  32. data/lib/tttls1.3/message/extension/cookie.rb +47 -0
  33. data/lib/tttls1.3/message/extension/early_data_indication.rb +58 -0
  34. data/lib/tttls1.3/message/extension/key_share.rb +236 -0
  35. data/lib/tttls1.3/message/extension/pre_shared_key.rb +205 -0
  36. data/lib/tttls1.3/message/extension/psk_key_exchange_modes.rb +54 -0
  37. data/lib/tttls1.3/message/extension/record_size_limit.rb +46 -0
  38. data/lib/tttls1.3/message/extension/server_name.rb +91 -0
  39. data/lib/tttls1.3/message/extension/signature_algorithms.rb +69 -0
  40. data/lib/tttls1.3/message/extension/signature_algorithms_cert.rb +25 -0
  41. data/lib/tttls1.3/message/extension/status_request.rb +106 -0
  42. data/lib/tttls1.3/message/extension/supported_groups.rb +145 -0
  43. data/lib/tttls1.3/message/extension/supported_versions.rb +98 -0
  44. data/lib/tttls1.3/message/extension/unknown_extension.rb +38 -0
  45. data/lib/tttls1.3/message/extensions.rb +173 -0
  46. data/lib/tttls1.3/message/finished.rb +44 -0
  47. data/lib/tttls1.3/message/new_session_ticket.rb +89 -0
  48. data/lib/tttls1.3/message/record.rb +232 -0
  49. data/lib/tttls1.3/message/server_hello.rb +116 -0
  50. data/lib/tttls1.3/message.rb +48 -0
  51. data/lib/tttls1.3/sequence_number.rb +31 -0
  52. data/lib/tttls1.3/signature_scheme.rb +31 -0
  53. data/lib/tttls1.3/transcript.rb +69 -0
  54. data/lib/tttls1.3/utils.rb +91 -0
  55. data/lib/tttls1.3/version.rb +5 -0
  56. data/lib/tttls1.3.rb +16 -0
  57. data/spec/aead_spec.rb +95 -0
  58. data/spec/alert_spec.rb +54 -0
  59. data/spec/alpn_spec.rb +55 -0
  60. data/spec/application_data_spec.rb +26 -0
  61. data/spec/certificate_spec.rb +55 -0
  62. data/spec/certificate_verify_spec.rb +51 -0
  63. data/spec/change_cipher_spec_spec.rb +26 -0
  64. data/spec/cipher_suites_spec.rb +39 -0
  65. data/spec/client_hello_spec.rb +83 -0
  66. data/spec/client_spec.rb +319 -0
  67. data/spec/connection_spec.rb +114 -0
  68. data/spec/cookie_spec.rb +98 -0
  69. data/spec/early_data_indication_spec.rb +64 -0
  70. data/spec/encrypted_extensions_spec.rb +94 -0
  71. data/spec/error_spec.rb +18 -0
  72. data/spec/extensions_spec.rb +170 -0
  73. data/spec/finished_spec.rb +55 -0
  74. data/spec/key_schedule_spec.rb +198 -0
  75. data/spec/key_share_spec.rb +199 -0
  76. data/spec/new_session_ticket_spec.rb +80 -0
  77. data/spec/pre_shared_key_spec.rb +167 -0
  78. data/spec/psk_key_exchange_modes_spec.rb +45 -0
  79. data/spec/record_size_limit_spec.rb +61 -0
  80. data/spec/record_spec.rb +105 -0
  81. data/spec/server_hello_spec.rb +101 -0
  82. data/spec/server_name_spec.rb +110 -0
  83. data/spec/signature_algorithms_cert_spec.rb +73 -0
  84. data/spec/signature_algorithms_spec.rb +100 -0
  85. data/spec/spec_helper.rb +872 -0
  86. data/spec/status_request_spec.rb +73 -0
  87. data/spec/supported_groups_spec.rb +79 -0
  88. data/spec/supported_versions_spec.rb +136 -0
  89. data/spec/transcript_spec.rb +69 -0
  90. data/spec/unknown_extension_spec.rb +90 -0
  91. data/spec/utils_spec.rb +215 -0
  92. data/tttls1.3.gemspec +25 -0
  93. metadata +197 -0
@@ -0,0 +1,319 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe Client do
8
+ context 'client' do
9
+ let(:record) do
10
+ mock_socket = SimpleStream.new
11
+ client = Client.new(mock_socket, 'localhost')
12
+ client.send(:send_client_hello)
13
+ Record.deserialize(mock_socket.read, Cryptograph::Passer.new)
14
+ end
15
+
16
+ it 'should send default ClientHello' do
17
+ expect(record.type).to eq ContentType::HANDSHAKE
18
+
19
+ message = record.messages.first
20
+ expect(message.msg_type).to eq HandshakeType::CLIENT_HELLO
21
+ expect(message.legacy_version).to eq ProtocolVersion::TLS_1_2
22
+ expect(message.cipher_suites).to eq DEFAULT_CH_CIPHER_SUITES
23
+ expect(message.legacy_compression_methods).to eq ["\x00"]
24
+ end
25
+ end
26
+
27
+ context 'client' do
28
+ let(:message) do
29
+ msg_len = TESTBINARY_SERVER_HELLO.length
30
+ mock_socket = SimpleStream.new
31
+ mock_socket.write(ContentType::HANDSHAKE \
32
+ + ProtocolVersion::TLS_1_2 \
33
+ + msg_len.to_uint16 \
34
+ + TESTBINARY_SERVER_HELLO)
35
+ client = Client.new(mock_socket, 'localhost')
36
+ client.send(:recv_server_hello)
37
+ end
38
+
39
+ it 'should receive ServerHello' do
40
+ expect(message.msg_type).to eq HandshakeType::SERVER_HELLO
41
+ expect(message.legacy_version).to eq ProtocolVersion::TLS_1_2
42
+ expect(message.cipher_suite).to eq CipherSuite::TLS_AES_128_GCM_SHA256
43
+ expect(message.legacy_compression_method).to eq "\x00"
44
+ end
45
+ end
46
+
47
+ context 'client' do
48
+ let(:client) do
49
+ mock_socket = SimpleStream.new
50
+ mock_socket.write(TESTBINARY_SERVER_PARAMETERS_RECORD)
51
+ client = Client.new(mock_socket, 'localhost')
52
+ client.instance_variable_set(:@cipher_suite,
53
+ CipherSuite::TLS_AES_128_GCM_SHA256)
54
+ read_seq_num = SequenceNumber.new
55
+ cipher = Cryptograph::Aead.new(
56
+ cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
57
+ write_key: TESTBINARY_SERVER_PARAMETERS_WRITE_KEY,
58
+ write_iv: TESTBINARY_SERVER_PARAMETERS_WRITE_IV,
59
+ sequence_number: read_seq_num
60
+ )
61
+ client.instance_variable_set(:@read_cipher, cipher)
62
+ client.instance_variable_set(:@read_seq_num, read_seq_num)
63
+ client
64
+ end
65
+
66
+ it 'should receive EncryptedExtensions' do
67
+ message = client.send(:recv_encrypted_extensions)
68
+ expect(message.msg_type).to eq HandshakeType::ENCRYPTED_EXTENSIONS
69
+ end
70
+
71
+ it 'should receive Certificate' do
72
+ client.send(:recv_encrypted_extensions) # to skip
73
+ message = client.send(:recv_certificate)
74
+ expect(message.msg_type).to eq HandshakeType::CERTIFICATE
75
+ end
76
+
77
+ it 'should receive CertificateVerify' do
78
+ client.send(:recv_encrypted_extensions) # to skip
79
+ client.send(:recv_certificate) # to skip
80
+ message = client.send(:recv_certificate_verify)
81
+ expect(message.msg_type).to eq HandshakeType::CERTIFICATE_VERIFY
82
+ end
83
+
84
+ it 'should receive Finished' do
85
+ client.send(:recv_encrypted_extensions) # to skip
86
+ client.send(:recv_certificate) # to skip
87
+ client.send(:recv_certificate_verify) # to skip
88
+ message = client.send(:recv_finished)
89
+ expect(message.msg_type).to eq HandshakeType::FINISHED
90
+ end
91
+ end
92
+
93
+ context 'client' do
94
+ let(:record) do
95
+ mock_socket = SimpleStream.new
96
+ client = Client.new(mock_socket, 'localhost')
97
+ transcript = Transcript.new
98
+ transcript.merge!(
99
+ CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
100
+ SH => ServerHello.deserialize(TESTBINARY_SERVER_HELLO),
101
+ EE => EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS),
102
+ CT => Certificate.deserialize(TESTBINARY_CERTIFICATE),
103
+ CV => CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY),
104
+ SF => Finished.deserialize(TESTBINARY_SERVER_FINISHED)
105
+ )
106
+ client.instance_variable_set(:@transcript, transcript)
107
+ ks = KeySchedule.new(shared_secret: TESTBINARY_SHARED_SECRET,
108
+ cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
109
+ transcript: transcript)
110
+ client.instance_variable_set(:@key_schedule, ks)
111
+ client.instance_variable_set(:@cipher_suite,
112
+ CipherSuite::TLS_AES_128_GCM_SHA256)
113
+ write_seq_num = SequenceNumber.new
114
+ write_cipher = Cryptograph::Aead.new(
115
+ cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
116
+ write_key: TESTBINARY_CLIENT_FINISHED_WRITE_KEY,
117
+ write_iv: TESTBINARY_CLIENT_FINISHED_WRITE_IV,
118
+ sequence_number: write_seq_num
119
+ )
120
+ client.instance_variable_set(:@write_cipher, write_cipher)
121
+ client.instance_variable_set(:@write_seq_num, write_seq_num)
122
+ client.send(:send_finished)
123
+ read_cipher = Cryptograph::Aead.new(
124
+ cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
125
+ write_key: TESTBINARY_CLIENT_FINISHED_WRITE_KEY,
126
+ write_iv: TESTBINARY_CLIENT_FINISHED_WRITE_IV,
127
+ sequence_number: SequenceNumber.new
128
+ )
129
+ Record.deserialize(mock_socket.read, read_cipher)
130
+ end
131
+
132
+ it 'should send Finished' do
133
+ expect(record.type).to eq ContentType::APPLICATION_DATA
134
+
135
+ message = record.messages.first
136
+ expect(message.msg_type).to eq HandshakeType::FINISHED
137
+ expect(message.serialize).to eq TESTBINARY_CLIENT_FINISHED
138
+ end
139
+ end
140
+
141
+ context 'client' do
142
+ let(:client) do
143
+ client = Client.new(nil, 'localhost')
144
+ transcript = Transcript.new
145
+ transcript.merge!(
146
+ CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
147
+ SH => ServerHello.deserialize(TESTBINARY_SERVER_HELLO),
148
+ EE => EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS),
149
+ CT => Certificate.deserialize(TESTBINARY_CERTIFICATE),
150
+ CV => CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY),
151
+ SF => Finished.deserialize(TESTBINARY_SERVER_FINISHED)
152
+ )
153
+ client.instance_variable_set(:@transcript, transcript)
154
+ ks = KeySchedule.new(shared_secret: TESTBINARY_SHARED_SECRET,
155
+ cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
156
+ transcript: transcript)
157
+ client.instance_variable_set(:@key_schedule, ks)
158
+ client.instance_variable_set(:@cipher_suite,
159
+ CipherSuite::TLS_AES_128_GCM_SHA256)
160
+ client
161
+ end
162
+
163
+ let(:client_finished) do
164
+ Finished.deserialize(TESTBINARY_CLIENT_FINISHED)
165
+ end
166
+
167
+ it 'should verify server CertificateVerify' do
168
+ expect(client.send(:verify_certificate_verify)).to be true
169
+ end
170
+
171
+ it 'should verify server Finished' do
172
+ expect(client.send(:verify_finished)).to be true
173
+ end
174
+
175
+ it 'should sign client Finished' do
176
+ expect(client.send(:sign_finished)).to eq client_finished.verify_data
177
+ end
178
+ end
179
+
180
+ context 'client' do
181
+ let(:client) do
182
+ client = Client.new(nil, 'localhost')
183
+ transcript = {
184
+ CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
185
+ SH => ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
186
+ }
187
+ client.instance_variable_set(:@transcript, transcript)
188
+ client
189
+ end
190
+
191
+ it 'should check that ServerHello.legacy_version matches ' \
192
+ 'ClientHello.legacy_version' do
193
+ expect(client.send(:valid_sh_legacy_version?)).to be true
194
+ end
195
+
196
+ it 'should check that ServerHello.legacy_session_id_echo matches ' \
197
+ 'ClientHello.legacy_session_id' do
198
+ expect(client.send(:valid_sh_legacy_session_id_echo?)).to be true
199
+ end
200
+
201
+ it 'should check that ServerHello.cipher_suite is included in' \
202
+ 'ClientHello.cipher_suites' do
203
+ expect(client.send(:valid_sh_cipher_suite?)).to be true
204
+ end
205
+
206
+ it 'should check that ServerHello.compression_method is valid value' do
207
+ expect(client.send(:valid_sh_compression_method?)).to be true
208
+ end
209
+
210
+ it 'should check that negotiated protocol_version is TLS 1.3' do
211
+ expect(client.send(:negotiated_tls_1_3?)).to be true
212
+ end
213
+ end
214
+
215
+ context 'client, received ServerHello with random[-8..] == ' \
216
+ 'downgrade protection value(TLS 1.2),' do
217
+ let(:client) do
218
+ mock_socket = SimpleStream.new
219
+ client = Client.new(mock_socket, 'localhost')
220
+ sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
221
+ random = OpenSSL::Random.random_bytes(24) + \
222
+ Client::DOWNGRADE_PROTECTION_TLS_1_2
223
+ sh.instance_variable_set(:@random, random)
224
+ transcript = {
225
+ CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
226
+ SH => sh
227
+ }
228
+ client.instance_variable_set(:@transcript, transcript)
229
+ client
230
+ end
231
+
232
+ it 'should check downgrade protection value' do
233
+ expect { client.send(:negotiated_tls_1_3?) }.to raise_error(ErrorAlerts)
234
+ end
235
+ end
236
+
237
+ context 'client, received ServerHello with random[-8..] == ' \
238
+ 'downgrade protection value(prior to TLS 1.2),' do
239
+ let(:client) do
240
+ mock_socket = SimpleStream.new
241
+ client = Client.new(mock_socket, 'localhost')
242
+ sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
243
+ random = OpenSSL::Random.random_bytes(24) + \
244
+ Client::DOWNGRADE_PROTECTION_TLS_1_1
245
+ sh.instance_variable_set(:@random, random)
246
+ transcript = {
247
+ CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
248
+ SH => sh
249
+ }
250
+ client.instance_variable_set(:@transcript, transcript)
251
+ client
252
+ end
253
+
254
+ it 'should check downgrade protection value' do
255
+ expect { client.send(:negotiated_tls_1_3?) }.to raise_error(ErrorAlerts)
256
+ end
257
+ end
258
+
259
+ context 'client, received ServerHello with supported_versions not ' \
260
+ 'including "\x03\x04",' do
261
+ let(:client) do
262
+ mock_socket = SimpleStream.new
263
+ client = Client.new(mock_socket, 'localhost')
264
+ sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
265
+ extensions = sh.instance_variable_get(:@extensions)
266
+ extensions[ExtensionType::SUPPORTED_VERSIONS] = nil
267
+ sh.instance_variable_set(:@extensions, extensions)
268
+ transcript = {
269
+ CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
270
+ SH => sh
271
+ }
272
+ client.instance_variable_set(:@transcript, transcript)
273
+ client
274
+ end
275
+
276
+ it 'should check negotiated protocol_version' do
277
+ expect(client.send(:negotiated_tls_1_3?)).to be false
278
+ end
279
+ end
280
+
281
+ context 'client, received Certificate signed by private CA,' do
282
+ let(:certificate) do
283
+ server_crt = OpenSSL::X509::Certificate.new(
284
+ File.read(__dir__ + '/../tmp/server.crt')
285
+ )
286
+ Certificate.new(certificate_list: [CertificateEntry.new(server_crt)])
287
+ end
288
+
289
+ let(:client) do
290
+ Client.new(nil, 'localhost')
291
+ end
292
+
293
+ it 'should not certify certificate' do
294
+ expect(client.send(:certified_certificate?, certificate.certificate_list))
295
+ .to be false
296
+ end
297
+
298
+ it 'should certify certificate, received path to private ca.crt' do
299
+ expect(client.send(:certified_certificate?, certificate.certificate_list,
300
+ __dir__ + '/../tmp/ca.crt')).to be true
301
+ end
302
+ end
303
+
304
+ context 'client using PSK' do
305
+ let(:client) do
306
+ Client.new(nil, 'localhost')
307
+ end
308
+
309
+ let(:ticket_nonce) do
310
+ nst = NewSessionTicket.deserialize(TESTBINARY_NEW_SESSION_TICKET)
311
+ nst.ticket_nonce
312
+ end
313
+
314
+ it 'should generate PSK from NewSessionTicket of previous handshake' do
315
+ expect(client.send(:gen_psk_from_nst, TESTBINARY_RES_MASTER, ticket_nonce,
316
+ 'SHA256')).to eq TESTBINARY_0_RTT_PSK
317
+ end
318
+ end
319
+ end
@@ -0,0 +1,114 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+
6
+ RSpec.describe Connection do
7
+ context 'connection, Simple 1-RTT Handshake,' do
8
+ let(:ct) do
9
+ Certificate.deserialize(TESTBINARY_CERTIFICATE)
10
+ end
11
+
12
+ let(:cv) do
13
+ CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY)
14
+ end
15
+
16
+ let(:cf) do
17
+ Finished.deserialize(TESTBINARY_CLIENT_FINISHED)
18
+ end
19
+
20
+ let(:sf) do
21
+ Finished.deserialize(TESTBINARY_SERVER_FINISHED)
22
+ end
23
+
24
+ let(:connection) do
25
+ connection = Connection.new(nil)
26
+ transcript = Transcript.new
27
+ transcript.merge!(
28
+ CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
29
+ SH => ServerHello.deserialize(TESTBINARY_SERVER_HELLO),
30
+ EE => EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS),
31
+ CT => ct,
32
+ CV => cv,
33
+ CF => cf,
34
+ SF => sf
35
+ )
36
+ connection.instance_variable_set(:@transcript, transcript)
37
+ connection.instance_variable_set(:@cipher_suite,
38
+ CipherSuite::TLS_AES_128_GCM_SHA256)
39
+ connection
40
+ end
41
+
42
+ it 'should verify server CertificateVerify.signature' do
43
+ certificate_pem = ct.certificate_list.first.cert_data.to_pem
44
+ signature_scheme = cv.signature_scheme
45
+ signature = cv.signature
46
+ expect(connection.send(:do_verify_certificate_verify,
47
+ certificate_pem: certificate_pem,
48
+ signature_scheme: signature_scheme,
49
+ signature: signature,
50
+ context: 'TLS 1.3, server CertificateVerify',
51
+ handshake_context_end: CT))
52
+ .to be true
53
+ end
54
+
55
+ it 'should verify server Finished.verify_data' do
56
+ expect(connection.send(:do_verify_finished,
57
+ digest: 'SHA256',
58
+ finished_key: TESTBINARY_SERVER_FINISHED_KEY,
59
+ handshake_context_end: CV,
60
+ signature: sf.verify_data))
61
+ .to be true
62
+ end
63
+
64
+ it 'should sign client Finished.verify_data' do
65
+ expect(connection.send(:do_sign_finished,
66
+ digest: 'SHA256',
67
+ finished_key: TESTBINARY_CLIENT_FINISHED_KEY,
68
+ handshake_context_end: EOED))
69
+ .to eq cf.verify_data
70
+ end
71
+ end
72
+
73
+ context 'connection, HelloRetryRequest,' do
74
+ let(:ct) do
75
+ Certificate.deserialize(TESTBINARY_HRR_CERTIFICATE)
76
+ end
77
+
78
+ let(:cv) do
79
+ CertificateVerify.deserialize(TESTBINARY_HRR_CERTIFICATE_VERIFY)
80
+ end
81
+
82
+ let(:connection) do
83
+ connection = Connection.new(nil)
84
+ transcript = Transcript.new
85
+ transcript.merge!(
86
+ CH1 => ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO1),
87
+ HRR => ServerHello.deserialize(TESTBINARY_HRR_HELLO_RETRY_REQUEST),
88
+ CH => ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO),
89
+ SH => ServerHello.deserialize(TESTBINARY_HRR_SERVER_HELLO),
90
+ EE =>
91
+ EncryptedExtensions.deserialize(TESTBINARY_HRR_ENCRYPTED_EXTENSIONS),
92
+ CT => ct,
93
+ CV => cv
94
+ )
95
+ connection.instance_variable_set(:@transcript, transcript)
96
+ connection.instance_variable_set(:@cipher_suite,
97
+ CipherSuite::TLS_AES_128_GCM_SHA256)
98
+ connection
99
+ end
100
+
101
+ it 'should verify server CertificateVerify.signature' do
102
+ certificate_pem = ct.certificate_list.first.cert_data.to_pem
103
+ signature_scheme = cv.signature_scheme
104
+ signature = cv.signature
105
+ expect(connection.send(:do_verify_certificate_verify,
106
+ certificate_pem: certificate_pem,
107
+ signature_scheme: signature_scheme,
108
+ signature: signature,
109
+ context: 'TLS 1.3, server CertificateVerify',
110
+ handshake_context_end: CT))
111
+ .to be true
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,98 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe Cookie do
8
+ context 'valid cookie' do
9
+ let(:cookie) do
10
+ OpenSSL::Random.random_bytes(2**16 - 3)
11
+ end
12
+
13
+ let(:extension) do
14
+ Cookie.new(cookie)
15
+ end
16
+
17
+ it 'should be generated' do
18
+ expect(extension.extension_type).to eq ExtensionType::COOKIE
19
+ expect(extension.cookie).to eq cookie
20
+ end
21
+
22
+ it 'should be serialized' do
23
+ expect(extension.serialize).to eq ExtensionType::COOKIE \
24
+ + (2**16 - 1).to_uint16 \
25
+ + (2**16 - 3).to_uint16 \
26
+ + cookie
27
+ end
28
+ end
29
+
30
+ context 'ignored cookie, empty,' do
31
+ let(:extension) do
32
+ Cookie.new('')
33
+ end
34
+
35
+ it 'should be generated' do
36
+ expect(extension.extension_type).to eq ExtensionType::COOKIE
37
+ expect(extension.cookie).to eq ''
38
+ end
39
+ end
40
+
41
+ context 'ignored cookie, nil,' do
42
+ let(:extension) do
43
+ Cookie.new(nil)
44
+ end
45
+
46
+ it 'should not be generated' do
47
+ expect(extension.extension_type).to eq ExtensionType::COOKIE
48
+ expect(extension.cookie).to eq ''
49
+ end
50
+ end
51
+
52
+ context 'invalid cookie, too long,' do
53
+ let(:extension) do
54
+ Cookie.new('a' * (2**16 - 2))
55
+ end
56
+
57
+ it 'should not be generated' do
58
+ expect { extension }.to raise_error(ErrorAlerts)
59
+ end
60
+ end
61
+
62
+ context 'valid cookie binary' do
63
+ let(:extension) do
64
+ Cookie.deserialize(TESTBINARY_COOKIE)
65
+ end
66
+
67
+ it 'should generate object' do
68
+ expect(extension.extension_type).to eq ExtensionType::COOKIE
69
+ expect(extension.cookie).to eq TESTBINARY_COOKIE[2..]
70
+ end
71
+
72
+ it 'should generate serializable object' do
73
+ expect(extension.serialize).to eq ExtensionType::COOKIE \
74
+ + TESTBINARY_COOKIE.prefix_uint16_length
75
+ end
76
+ end
77
+
78
+ context 'cookie binary, empty,' do
79
+ let(:extension) do
80
+ Cookie.deserialize("\x00\x00")
81
+ end
82
+
83
+ it 'should generat object' do
84
+ expect(extension.extension_type).to eq ExtensionType::COOKIE
85
+ expect(extension.cookie).to eq ''
86
+ end
87
+ end
88
+
89
+ context 'invalid cookie binary, malformed binary,' do
90
+ let(:extension) do
91
+ Cookie.deserialize(TESTBINARY_COOKIE[0...-1])
92
+ end
93
+
94
+ it 'should return nil' do
95
+ expect(extension).to be nil
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe EarlyDataIndication do
8
+ context 'valid early_data_indication, NewSessionTicket,' do
9
+ let(:extension) do
10
+ EarlyDataIndication.new(2**32 - 1)
11
+ end
12
+
13
+ it 'should be generated' do
14
+ expect(extension.extension_type).to eq ExtensionType::EARLY_DATA
15
+ expect(extension.max_early_data_size).to eq 2**32 - 1
16
+ end
17
+
18
+ it 'should be serialized' do
19
+ expect(extension.serialize).to eq ExtensionType::EARLY_DATA \
20
+ + 4.to_uint16 \
21
+ + (2**32 - 1).to_uint32
22
+ end
23
+ end
24
+
25
+ context 'valid early_data_indication, ClientHello or EncryptedExtensions,' do
26
+ let(:extension) do
27
+ EarlyDataIndication.new(nil)
28
+ end
29
+
30
+ it 'should be generated' do
31
+ expect(extension.extension_type).to eq ExtensionType::EARLY_DATA
32
+ expect(extension.max_early_data_size).to be nil
33
+ end
34
+
35
+ it 'should be serialized' do
36
+ expect(extension.serialize).to eq ExtensionType::EARLY_DATA \
37
+ + 0.to_uint16
38
+ end
39
+ end
40
+
41
+ context 'valid early_data_indication binary, NewSessionTicket,' do
42
+ let(:extension) do
43
+ EarlyDataIndication.deserialize(TESTBINARY_EARLY_DATA_INDICATION_NST,
44
+ HandshakeType::NEW_SESSION_TICKET)
45
+ end
46
+
47
+ it 'should generate valid object' do
48
+ expect(extension.extension_type).to eq ExtensionType::EARLY_DATA
49
+ expect(extension.max_early_data_size).to eq 1024
50
+ end
51
+ end
52
+
53
+ context 'valid early_data_indication binary, ClientHello,' do
54
+ let(:extension) do
55
+ EarlyDataIndication.deserialize(TESTBINARY_EARLY_DATA_INDICATION_CH,
56
+ HandshakeType::CLIENT_HELLO)
57
+ end
58
+
59
+ it 'should generate valid object' do
60
+ expect(extension.extension_type).to eq ExtensionType::EARLY_DATA
61
+ expect(extension.max_early_data_size).to be nil
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,94 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe EncryptedExtensions do
8
+ context 'valid encrypted_extensions' do
9
+ let(:server_name) do
10
+ ServerName.new('')
11
+ end
12
+
13
+ let(:supported_groups) do
14
+ SupportedGroups.new(
15
+ [
16
+ NamedGroup::SECP256R1,
17
+ NamedGroup::SECP384R1,
18
+ NamedGroup::SECP521R1
19
+ ]
20
+ )
21
+ end
22
+
23
+ let(:extensions) do
24
+ Extensions.new([server_name, supported_groups])
25
+ end
26
+
27
+ let(:message) do
28
+ EncryptedExtensions.new(extensions)
29
+ end
30
+
31
+ it 'should be generated' do
32
+ expect(message.msg_type).to eq HandshakeType::ENCRYPTED_EXTENSIONS
33
+ expect(message.extensions).to eq extensions
34
+ expect(message.any_forbidden_extensions?).to be false
35
+ end
36
+
37
+ it 'should be serialized' do
38
+ expect(message.serialize)
39
+ .to eq HandshakeType::ENCRYPTED_EXTENSIONS \
40
+ + extensions.serialize.prefix_uint24_length
41
+ end
42
+ end
43
+
44
+ context 'invalid encrypted_extensions, including forbidden extension type,' do
45
+ let(:extensions) do
46
+ signature_algorithms \
47
+ = SignatureAlgorithms.new([SignatureScheme::ECDSA_SECP256R1_SHA256])
48
+ Extensions.new([signature_algorithms])
49
+ end
50
+
51
+ let(:message) do
52
+ EncryptedExtensions.new(extensions)
53
+ end
54
+
55
+ it 'should be generated' do
56
+ expect(message.msg_type).to eq HandshakeType::ENCRYPTED_EXTENSIONS
57
+ expect(message.extensions).to eq extensions
58
+ expect(message.any_forbidden_extensions?).to be true
59
+ end
60
+ end
61
+
62
+ context 'valid encrypted_extensions, nil argument,' do
63
+ let(:message) do
64
+ EncryptedExtensions.new(nil)
65
+ end
66
+
67
+ it 'should be generated' do
68
+ expect(message.msg_type).to eq HandshakeType::ENCRYPTED_EXTENSIONS
69
+ expect(message.extensions).to eq Extensions.new
70
+ expect(message.any_forbidden_extensions?).to be false
71
+ end
72
+
73
+ it 'should be serialized' do
74
+ expect(message.serialize)
75
+ .to eq HandshakeType::ENCRYPTED_EXTENSIONS \
76
+ + Extensions.new.serialize.prefix_uint24_length
77
+ end
78
+ end
79
+
80
+ context 'valid encrypted_extensions binary' do
81
+ let(:message) do
82
+ EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS)
83
+ end
84
+
85
+ it 'should generate valid object' do
86
+ expect(message.msg_type).to eq HandshakeType::ENCRYPTED_EXTENSIONS
87
+ expect(message.any_forbidden_extensions?).to be false
88
+ end
89
+
90
+ it 'should generate valid serializable object' do
91
+ expect(message.serialize).to eq TESTBINARY_ENCRYPTED_EXTENSIONS
92
+ end
93
+ end
94
+ end