tttls1.3 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/example/helper.rb +21 -0
- data/example/https_client_using_0rtt.rb +1 -1
- data/example/https_server.rb +14 -1
- data/lib/tttls1.3/client.rb +205 -418
- data/lib/tttls1.3/connection.rb +21 -362
- data/lib/tttls1.3/ech.rb +410 -0
- data/lib/tttls1.3/endpoint.rb +276 -0
- data/lib/tttls1.3/message/certificate_verify.rb +1 -1
- data/lib/tttls1.3/message/extension/ech.rb +12 -10
- data/lib/tttls1.3/message/extension/signature_algorithms.rb +2 -2
- data/lib/tttls1.3/message/extension/supported_versions.rb +3 -3
- data/lib/tttls1.3/message/extension/unknown_extension.rb +2 -2
- data/lib/tttls1.3/server.rb +125 -63
- data/lib/tttls1.3/utils.rb +37 -0
- data/lib/tttls1.3/version.rb +1 -1
- data/lib/tttls1.3.rb +2 -1
- data/spec/client_spec.rb +21 -60
- data/spec/ech_spec.rb +39 -0
- data/spec/{connection_spec.rb → endpoint_spec.rb} +41 -49
- data/spec/server_spec.rb +12 -12
- metadata +7 -6
- 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
|
7
|
-
context '
|
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(
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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(
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
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(
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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 =
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
expect(
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
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 '
|
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(
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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(
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
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
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
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
|
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.
|
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:
|
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
|
@@ -235,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
235
236
|
- !ruby/object:Gem::Version
|
236
237
|
version: '0'
|
237
238
|
requirements: []
|
238
|
-
rubygems_version: 3.
|
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
|