tttls1.3 0.3.0 → 0.3.2

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/.rubocop.yml +3 -0
  4. data/.ruby-version +1 -1
  5. data/Gemfile +1 -0
  6. data/README.md +2 -2
  7. data/example/README.md +1 -1
  8. data/example/helper.rb +22 -0
  9. data/example/https_client.rb +4 -4
  10. data/example/https_client_using_0rtt.rb +6 -5
  11. data/example/https_client_using_ech.rb +5 -6
  12. data/example/https_client_using_grease_ech.rb +3 -5
  13. data/example/https_client_using_grease_psk.rb +8 -16
  14. data/example/https_client_using_hrr.rb +5 -4
  15. data/example/https_client_using_hrr_and_ech.rb +6 -6
  16. data/example/https_client_using_hrr_and_ticket.rb +5 -4
  17. data/example/https_client_using_status_request.rb +4 -5
  18. data/example/https_client_using_ticket.rb +5 -4
  19. data/example/https_server.rb +14 -1
  20. data/lib/tttls1.3/client.rb +205 -418
  21. data/lib/tttls1.3/connection.rb +21 -362
  22. data/lib/tttls1.3/ech.rb +410 -0
  23. data/lib/tttls1.3/endpoint.rb +276 -0
  24. data/lib/tttls1.3/message/certificate_verify.rb +1 -1
  25. data/lib/tttls1.3/message/extension/ech.rb +12 -10
  26. data/lib/tttls1.3/message/extension/signature_algorithms.rb +2 -2
  27. data/lib/tttls1.3/message/extension/supported_versions.rb +3 -3
  28. data/lib/tttls1.3/message/extension/unknown_extension.rb +2 -2
  29. data/lib/tttls1.3/server.rb +125 -63
  30. data/lib/tttls1.3/utils.rb +37 -0
  31. data/lib/tttls1.3/version.rb +1 -1
  32. data/lib/tttls1.3.rb +2 -1
  33. data/spec/client_spec.rb +21 -60
  34. data/spec/ech_spec.rb +39 -0
  35. data/spec/{connection_spec.rb → endpoint_spec.rb} +41 -49
  36. data/spec/server_spec.rb +12 -12
  37. data/tttls1.3.gemspec +1 -1
  38. metadata +8 -7
  39. data/lib/tttls1.3/hpke.rb +0 -91
data/spec/ech_spec.rb CHANGED
@@ -78,4 +78,43 @@ RSpec.describe ECHClientHello do
78
78
  expect(extension.confirmation).to eq "\x00" * 8
79
79
  end
80
80
  end
81
+
82
+ context 'EncodedClientHelloInner length' do
83
+ let(:server_name) do
84
+ 'localhost'
85
+ end
86
+
87
+ let(:client) do
88
+ Client.new(nil, server_name)
89
+ end
90
+
91
+ let(:maximum_name_length) do
92
+ 0
93
+ end
94
+
95
+ let(:encoded) do
96
+ extensions, = client.send(:gen_ch_extensions)
97
+ inner_ech = Message::Extension::ECHClientHello.new_inner
98
+ Message::ClientHello.new(
99
+ legacy_session_id: '',
100
+ cipher_suites: CipherSuites.new(DEFAULT_CH_CIPHER_SUITES),
101
+ extensions: extensions.merge(
102
+ Message::ExtensionType::ENCRYPTED_CLIENT_HELLO => inner_ech
103
+ )
104
+ )
105
+ end
106
+
107
+ let(:padding_encoded_ch_inner) do
108
+ Ech.padding_encoded_ch_inner(
109
+ encoded.serialize[4..],
110
+ server_name.length,
111
+ maximum_name_length
112
+ )
113
+ end
114
+
115
+ it 'should be equal placeholder_encoded_ch_inner_len' do
116
+ expect(Ech.placeholder_encoded_ch_inner_len)
117
+ .to eq padding_encoded_ch_inner.length
118
+ end
119
+ end
81
120
  end
@@ -3,8 +3,8 @@
3
3
 
4
4
  require_relative 'spec_helper'
5
5
 
6
- RSpec.describe Connection do
7
- context 'connection, Simple 1-RTT Handshake,' do
6
+ RSpec.describe Endpoint do
7
+ context 'endpoint, Simple 1-RTT Handshake,' do
8
8
  let(:key) do
9
9
  n = OpenSSL::BN.new(TESTBINARY_PKEY_MODULUS, 2)
10
10
  e = OpenSSL::BN.new(TESTBINARY_PKEY_PUBLIC_EXPONENT, 2)
@@ -66,39 +66,35 @@ RSpec.describe Connection do
66
66
  CipherSuite.digest(CipherSuite::TLS_AES_128_GCM_SHA256)
67
67
  end
68
68
 
69
- let(:connection) do
70
- Connection.new(nil)
71
- end
72
-
73
69
  it 'should verify server CertificateVerify.signature' do
74
70
  public_key = ct.certificate_list.first.cert_data.public_key
75
71
  signature_scheme = cv.signature_scheme
76
72
  signature = cv.signature
77
73
 
78
- expect(connection.send(:do_verified_certificate_verify?,
79
- public_key: public_key,
80
- signature_scheme: signature_scheme,
81
- signature: signature,
82
- context: 'TLS 1.3, server CertificateVerify',
83
- hash: transcript.hash(digest, CT)))
84
- .to be true
74
+ expect(Endpoint.verified_certificate_verify?(
75
+ public_key: public_key,
76
+ signature_scheme: signature_scheme,
77
+ signature: signature,
78
+ context: 'TLS 1.3, server CertificateVerify',
79
+ hash: transcript.hash(digest, CT)
80
+ )).to be true
85
81
  end
86
82
 
87
83
  it 'should sign client Finished.verify_data' do
88
- expect(connection.send(:sign_finished,
89
- digest: 'SHA256',
90
- finished_key: TESTBINARY_CLIENT_FINISHED_KEY,
91
- hash: transcript.hash(digest, EOED)))
92
- .to eq cf.verify_data
84
+ expect(Endpoint.sign_finished(
85
+ digest: 'SHA256',
86
+ finished_key: TESTBINARY_CLIENT_FINISHED_KEY,
87
+ hash: transcript.hash(digest, EOED)
88
+ )).to eq cf.verify_data
93
89
  end
94
90
 
95
91
  it 'should verify server Finished.verify_data' do
96
- expect(connection.send(:verified_finished?,
97
- finished: sf,
98
- digest: 'SHA256',
99
- finished_key: TESTBINARY_SERVER_FINISHED_KEY,
100
- hash: transcript.hash(digest, CV)))
101
- .to be true
92
+ expect(Endpoint.verified_finished?(
93
+ finished: sf,
94
+ digest: 'SHA256',
95
+ finished_key: TESTBINARY_SERVER_FINISHED_KEY,
96
+ hash: transcript.hash(digest, CV)
97
+ )).to be true
102
98
  end
103
99
 
104
100
  it 'should sign server CertificateVerify.signature' do
@@ -107,23 +103,23 @@ RSpec.describe Connection do
107
103
 
108
104
  # used RSASSA-PSS signature_scheme, salt is a random sequence.
109
105
  # CertificateVerify.signature is random.
110
- signature = connection.send(:do_sign_certificate_verify,
111
- key: key,
112
- signature_scheme: signature_scheme,
113
- context: 'TLS 1.3, server CertificateVerify',
114
- hash: transcript.hash(digest, CT))
115
-
116
- expect(connection.send(:do_verified_certificate_verify?,
117
- public_key: public_key,
118
- signature_scheme: signature_scheme,
119
- signature: signature,
120
- context: 'TLS 1.3, server CertificateVerify',
121
- hash: transcript.hash(digest, CT)))
122
- .to be true
106
+ signature = Endpoint.sign_certificate_verify(
107
+ key: key,
108
+ signature_scheme: signature_scheme,
109
+ context: 'TLS 1.3, server CertificateVerify',
110
+ hash: transcript.hash(digest, CT)
111
+ )
112
+ expect(Endpoint.verified_certificate_verify?(
113
+ public_key: public_key,
114
+ signature_scheme: signature_scheme,
115
+ signature: signature,
116
+ context: 'TLS 1.3, server CertificateVerify',
117
+ hash: transcript.hash(digest, CT)
118
+ )).to be true
123
119
  end
124
120
  end
125
121
 
126
- context 'connection, HelloRetryRequest,' do
122
+ context 'endpoint, HelloRetryRequest,' do
127
123
  let(:ct) do
128
124
  Certificate.deserialize(TESTBINARY_HRR_CERTIFICATE)
129
125
  end
@@ -154,22 +150,18 @@ RSpec.describe Connection do
154
150
  CipherSuite.digest(CipherSuite::TLS_AES_128_GCM_SHA256)
155
151
  end
156
152
 
157
- let(:connection) do
158
- Connection.new(nil)
159
- end
160
-
161
153
  it 'should verify server CertificateVerify.signature' do
162
154
  public_key = ct.certificate_list.first.cert_data.public_key
163
155
  signature_scheme = cv.signature_scheme
164
156
  signature = cv.signature
165
157
 
166
- expect(connection.send(:do_verified_certificate_verify?,
167
- public_key: public_key,
168
- signature_scheme: signature_scheme,
169
- signature: signature,
170
- context: 'TLS 1.3, server CertificateVerify',
171
- hash: transcript.hash(digest, CT)))
172
- .to be true
158
+ expect(Endpoint.verified_certificate_verify?(
159
+ public_key: public_key,
160
+ signature_scheme: signature_scheme,
161
+ signature: signature,
162
+ context: 'TLS 1.3, server CertificateVerify',
163
+ hash: transcript.hash(digest, CT)
164
+ )).to be true
173
165
  end
174
166
  end
175
167
  end
data/spec/server_spec.rb CHANGED
@@ -174,13 +174,13 @@ RSpec.describe Server do
174
174
  signature_scheme = cv.signature_scheme
175
175
  signature = cv.signature
176
176
  digest = CipherSuite.digest(cipher_suite)
177
- expect(server.send(:do_verified_certificate_verify?,
178
- public_key: public_key,
179
- signature_scheme: signature_scheme,
180
- signature: signature,
181
- context: 'TLS 1.3, server CertificateVerify',
182
- hash: transcript.hash(digest, CT)))
183
- .to be true
177
+ expect(Endpoint.verified_certificate_verify?(
178
+ public_key: public_key,
179
+ signature_scheme: signature_scheme,
180
+ signature: signature,
181
+ context: 'TLS 1.3, server CertificateVerify',
182
+ hash: transcript.hash(digest, CT)
183
+ )).to be true
184
184
  end
185
185
  end
186
186
 
@@ -213,12 +213,12 @@ RSpec.describe Server do
213
213
  end
214
214
 
215
215
  let(:signature) do
216
- server = Server.new(nil)
217
216
  digest = CipherSuite.digest(cipher_suite)
218
- server.send(:sign_finished,
219
- digest: digest,
220
- finished_key: key_schedule.server_finished_key,
221
- hash: transcript.hash(digest, CV))
217
+ Endpoint.sign_finished(
218
+ digest: digest,
219
+ finished_key: key_schedule.server_finished_key,
220
+ hash: transcript.hash(digest, CV)
221
+ )
222
222
  end
223
223
 
224
224
  let(:sf) do
data/tttls1.3.gemspec CHANGED
@@ -13,7 +13,7 @@ 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.7'
16
+ spec.required_ruby_version = '>=3.1'
17
17
 
18
18
  spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
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.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - thekuwayama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-23 00:00:00.000000000 Z
11
+ date: 2024-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -119,8 +119,9 @@ files:
119
119
  - lib/tttls1.3/cryptograph.rb
120
120
  - lib/tttls1.3/cryptograph/aead.rb
121
121
  - lib/tttls1.3/cryptograph/passer.rb
122
+ - lib/tttls1.3/ech.rb
123
+ - lib/tttls1.3/endpoint.rb
122
124
  - lib/tttls1.3/error.rb
123
- - lib/tttls1.3/hpke.rb
124
125
  - lib/tttls1.3/key_schedule.rb
125
126
  - lib/tttls1.3/logging.rb
126
127
  - lib/tttls1.3/message.rb
@@ -173,12 +174,12 @@ files:
173
174
  - spec/client_hello_spec.rb
174
175
  - spec/client_spec.rb
175
176
  - spec/compress_certificate_spec.rb
176
- - spec/connection_spec.rb
177
177
  - spec/cookie_spec.rb
178
178
  - spec/early_data_indication_spec.rb
179
179
  - spec/ech_spec.rb
180
180
  - spec/encrypted_extensions_spec.rb
181
181
  - spec/end_of_early_data_spec.rb
182
+ - spec/endpoint_spec.rb
182
183
  - spec/error_spec.rb
183
184
  - spec/extensions_spec.rb
184
185
  - spec/finished_spec.rb
@@ -228,14 +229,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
228
229
  requirements:
229
230
  - - ">="
230
231
  - !ruby/object:Gem::Version
231
- version: '2.7'
232
+ version: '3.1'
232
233
  required_rubygems_version: !ruby/object:Gem::Requirement
233
234
  requirements:
234
235
  - - ">="
235
236
  - !ruby/object:Gem::Version
236
237
  version: '0'
237
238
  requirements: []
238
- rubygems_version: 3.3.7
239
+ rubygems_version: 3.5.3
239
240
  signing_key:
240
241
  specification_version: 4
241
242
  summary: TLS 1.3 implementation in Ruby (Tiny Trial TLS1.3 aka tttls1.3)
@@ -251,12 +252,12 @@ test_files:
251
252
  - spec/client_hello_spec.rb
252
253
  - spec/client_spec.rb
253
254
  - spec/compress_certificate_spec.rb
254
- - spec/connection_spec.rb
255
255
  - spec/cookie_spec.rb
256
256
  - spec/early_data_indication_spec.rb
257
257
  - spec/ech_spec.rb
258
258
  - spec/encrypted_extensions_spec.rb
259
259
  - spec/end_of_early_data_spec.rb
260
+ - spec/endpoint_spec.rb
260
261
  - spec/error_spec.rb
261
262
  - spec/extensions_spec.rb
262
263
  - spec/finished_spec.rb
data/lib/tttls1.3/hpke.rb DELETED
@@ -1,91 +0,0 @@
1
- # encoding: ascii-8bit
2
- # frozen_string_literal: true
3
-
4
- module TTTLS13
5
- # NOTE: Hpke module is the adapter for ech_config using hpke-rb.
6
- module Hpke
7
- module KemId
8
- # https://www.iana.org/assignments/hpke/hpke.xhtml#hpke-kem-ids
9
- P_256_SHA256 = 0x0010
10
- P_384_SHA384 = 0x0011
11
- P_521_SHA512 = 0x0012
12
- X25519_SHA256 = 0x0020
13
- X448_SHA512 = 0x0021
14
- end
15
-
16
- def self.kem_id2dhkem(kem_id)
17
- case kem_id
18
- when KemId::P_256_SHA256
19
- %i[p_256 sha256]
20
- when KemId::P_384_SHA384
21
- %i[p_384 sha384]
22
- when KemId::P_521_SHA512
23
- %i[p_521 sha512]
24
- when KemId::X25519_SHA256
25
- %i[x25519 sha256]
26
- when KemId::X448_SHA512
27
- %i[x448 sha512]
28
- end
29
- end
30
-
31
- def self.kem_curve_name2dhkem(kem_curve_name)
32
- case kem_curve_name
33
- when :p_256
34
- HPKE::DHKEM::EC::P_256
35
- when :p_384
36
- HPKE::DHKEM::EC::P_384
37
- when :p_521
38
- HPKE::DHKEM::EC::P_521
39
- when :x25519
40
- HPKE::DHKEM::X25519
41
- when :x448
42
- HPKE::DHKEM::X448
43
- end
44
- end
45
-
46
- module KdfId
47
- # https://www.iana.org/assignments/hpke/hpke.xhtml#hpke-kdf-ids
48
- HKDF_SHA256 = 0x0001
49
- HKDF_SHA384 = 0x0002
50
- HKDF_SHA512 = 0x0003
51
- end
52
-
53
- def self.kdf_id2kdf_hash(kdf_id)
54
- case kdf_id
55
- when KdfId::HKDF_SHA256
56
- :sha256
57
- when KdfId::HKDF_SHA384
58
- :sha384
59
- when KdfId::HKDF_SHA512
60
- :sha512
61
- end
62
- end
63
-
64
- module AeadId
65
- # https://www.iana.org/assignments/hpke/hpke.xhtml#hpke-aead-ids
66
- AES_128_GCM = 0x0001
67
- AES_256_GCM = 0x0002
68
- CHACHA20_POLY1305 = 0x0003
69
- end
70
-
71
- def self.aead_id2overhead_len(aead_id)
72
- case aead_id
73
- when AeadId::AES_128_GCM, AeadId::CHACHA20_POLY1305
74
- 16
75
- when AeadId::AES_256_GCM
76
- 32
77
- end
78
- end
79
-
80
- def self.aead_id2aead_cipher(aead_id)
81
- case aead_id
82
- when AeadId::AES_128_GCM
83
- :aes_128_gcm
84
- when AeadId::AES_256_GCM
85
- :aes_256_gcm
86
- when AeadId::CHACHA20_POLY1305
87
- :chacha20_poly1305
88
- end
89
- end
90
- end
91
- end