tttls1.3 0.3.4 → 0.3.5
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 +4 -2
- data/.rubocop.yml +16 -11
- data/.ruby-version +1 -1
- data/Gemfile +3 -3
- data/README.md +4 -4
- data/Rakefile +3 -3
- data/example/helper.rb +1 -1
- data/example/https_client_using_0rtt.rb +1 -1
- data/example/https_client_using_ech.rb +1 -1
- data/example/https_client_using_hrr_and_ech.rb +1 -1
- data/example/https_client_using_hrr_and_ticket.rb +1 -1
- data/example/https_client_using_status_request.rb +1 -1
- data/example/https_client_using_ticket.rb +1 -1
- data/example/https_client_using_ticket_and_ech.rb +3 -3
- data/example/https_server.rb +1 -1
- data/interop/client_spec.rb +57 -31
- data/interop/server_spec.rb +74 -46
- data/interop/spec_helper.rb +2 -2
- data/lib/tttls1.3/cipher_suites.rb +21 -16
- data/lib/tttls1.3/client.rb +86 -73
- data/lib/tttls1.3/connection.rb +6 -15
- data/lib/tttls1.3/cryptograph/aead.rb +26 -16
- data/lib/tttls1.3/ech.rb +11 -15
- data/lib/tttls1.3/endpoint.rb +4 -25
- data/lib/tttls1.3/key_schedule.rb +1 -1
- data/lib/tttls1.3/logging.rb +1 -1
- data/lib/tttls1.3/message/alert.rb +3 -4
- data/lib/tttls1.3/message/certificate.rb +4 -7
- data/lib/tttls1.3/message/certificate_verify.rb +3 -5
- data/lib/tttls1.3/message/client_hello.rb +9 -15
- data/lib/tttls1.3/message/compressed_certificate.rb +3 -9
- data/lib/tttls1.3/message/encrypted_extensions.rb +1 -2
- data/lib/tttls1.3/message/extension/alpn.rb +1 -6
- data/lib/tttls1.3/message/extension/compress_certificate.rb +1 -2
- data/lib/tttls1.3/message/extension/cookie.rb +1 -2
- data/lib/tttls1.3/message/extension/early_data_indication.rb +1 -2
- data/lib/tttls1.3/message/extension/ech.rb +9 -16
- data/lib/tttls1.3/message/extension/ech_outer_extensions.rb +1 -2
- data/lib/tttls1.3/message/extension/key_share.rb +17 -43
- data/lib/tttls1.3/message/extension/pre_shared_key.rb +8 -17
- data/lib/tttls1.3/message/extension/psk_key_exchange_modes.rb +1 -2
- data/lib/tttls1.3/message/extension/record_size_limit.rb +1 -2
- data/lib/tttls1.3/message/extension/server_name.rb +1 -2
- data/lib/tttls1.3/message/extension/signature_algorithms.rb +1 -2
- data/lib/tttls1.3/message/extension/status_request.rb +4 -12
- data/lib/tttls1.3/message/extension/supported_groups.rb +1 -4
- data/lib/tttls1.3/message/extension/supported_versions.rb +2 -8
- data/lib/tttls1.3/message/extension/unknown_extension.rb +2 -3
- data/lib/tttls1.3/message/extensions.rb +1 -7
- data/lib/tttls1.3/message/finished.rb +1 -2
- data/lib/tttls1.3/message/new_session_ticket.rb +6 -12
- data/lib/tttls1.3/message/record.rb +10 -23
- data/lib/tttls1.3/message/server_hello.rb +10 -21
- data/lib/tttls1.3/named_group.rb +12 -6
- data/lib/tttls1.3/server.rb +39 -34
- data/lib/tttls1.3/shared_secret.rb +118 -0
- data/lib/tttls1.3/utils.rb +0 -15
- data/lib/tttls1.3/version.rb +1 -1
- data/lib/tttls1.3.rb +1 -1
- data/spec/certificate_verify_spec.rb +1 -1
- data/spec/client_hello_spec.rb +4 -4
- data/spec/client_spec.rb +13 -13
- data/spec/endpoint_spec.rb +11 -11
- data/spec/key_schedule_spec.rb +4 -4
- data/spec/new_session_ticket_spec.rb +4 -4
- data/spec/pre_shared_key_spec.rb +8 -8
- data/spec/record_spec.rb +1 -1
- data/spec/server_hello_spec.rb +5 -5
- data/spec/server_spec.rb +8 -8
- data/tttls1.3.gemspec +2 -2
- metadata +7 -10
- data/example/https_client_using_grease_psk.rb +0 -58
@@ -0,0 +1,118 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module TTTLS13
|
5
|
+
class SharedSecret
|
6
|
+
def initialize
|
7
|
+
@priv_keys = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
# @param group [TTTLS13::NamedGroup]
|
11
|
+
# @param priv_key [OpenSSL::PKey::EC.$Object | OpenSSL::PKey::PKey.$Object]
|
12
|
+
def store!(group, priv_key)
|
13
|
+
@priv_keys[group] = priv_key
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param group [TTTLS13::NamedGroup]
|
17
|
+
# @param key_exchange [String]
|
18
|
+
#
|
19
|
+
# @return String
|
20
|
+
# rubocop: disable Metrics/MethodLength
|
21
|
+
def build(group, key_exchange)
|
22
|
+
case group
|
23
|
+
when NamedGroup::SECP256R1, NamedGroup::SECP384R1, NamedGroup::SECP521R1
|
24
|
+
curve = NamedGroup.curve_name(group)
|
25
|
+
pub_key = OpenSSL::PKey::EC::Point.new(
|
26
|
+
OpenSSL::PKey::EC::Group.new(curve),
|
27
|
+
OpenSSL::BN.new(key_exchange, 2)
|
28
|
+
)
|
29
|
+
@priv_keys[group].dh_compute_key(pub_key)
|
30
|
+
when NamedGroup::X25519
|
31
|
+
asn1_seq = OpenSSL::ASN1.Sequence(
|
32
|
+
[
|
33
|
+
OpenSSL::ASN1.Sequence(
|
34
|
+
[
|
35
|
+
# https://datatracker.ietf.org/doc/html/rfc8410#section-3
|
36
|
+
OpenSSL::ASN1.ObjectId('1.3.101.110')
|
37
|
+
]
|
38
|
+
),
|
39
|
+
OpenSSL::ASN1.BitString(key_exchange)
|
40
|
+
]
|
41
|
+
)
|
42
|
+
|
43
|
+
@priv_keys[group].derive(OpenSSL::PKey.read(asn1_seq.to_der))
|
44
|
+
when NamedGroup::X448
|
45
|
+
asn1_seq = OpenSSL::ASN1.Sequence(
|
46
|
+
[
|
47
|
+
OpenSSL::ASN1.Sequence(
|
48
|
+
[
|
49
|
+
# https://datatracker.ietf.org/doc/html/rfc8410#section-3
|
50
|
+
OpenSSL::ASN1.ObjectId('1.3.101.111')
|
51
|
+
]
|
52
|
+
),
|
53
|
+
OpenSSL::ASN1.BitString(key_exchange)
|
54
|
+
]
|
55
|
+
)
|
56
|
+
|
57
|
+
@priv_keys[group].derive(OpenSSL::PKey.read(asn1_seq.to_der))
|
58
|
+
else
|
59
|
+
# not supported other NamedGroup
|
60
|
+
raise Error::ErrorAlerts, :internal_error
|
61
|
+
end
|
62
|
+
end
|
63
|
+
# rubocop: enable Metrics/MethodLength
|
64
|
+
|
65
|
+
# @return [Array of TTTLS13::Message::Extensions::KeyShare]
|
66
|
+
def key_share_entries
|
67
|
+
@priv_keys.map do |group, priv_key|
|
68
|
+
case group
|
69
|
+
when NamedGroup::SECP256R1, NamedGroup::SECP384R1, NamedGroup::SECP521R1
|
70
|
+
Message::Extension::KeyShareEntry.new(
|
71
|
+
group:,
|
72
|
+
key_exchange: priv_key.public_key.to_octet_string(:uncompressed)
|
73
|
+
)
|
74
|
+
when NamedGroup::X25519, NamedGroup::X448
|
75
|
+
n_pk = NamedGroup.key_exchange_len(group)
|
76
|
+
Message::Extension::KeyShareEntry.new(
|
77
|
+
group:,
|
78
|
+
key_exchange: priv_key.public_to_der[-n_pk, n_pk]
|
79
|
+
)
|
80
|
+
else
|
81
|
+
# not supported other NamedGroup
|
82
|
+
raise Error::ErrorAlerts, :internal_error
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# @param group [TTTLS13::Message::Extension::NamedGroup]
|
88
|
+
#
|
89
|
+
# @return [OpenSSL::PKey::EC.$Object | OpenSSL::PKey::PKey.$Object]]
|
90
|
+
def [](group)
|
91
|
+
@priv_keys[group]
|
92
|
+
end
|
93
|
+
|
94
|
+
# @param groups [Array of TTTLS13::NamedGroup]
|
95
|
+
#
|
96
|
+
# @return [TTTLS13::SharedSecret]
|
97
|
+
def self.gen_from_named_groups(groups)
|
98
|
+
shared_secret = SharedSecret.new
|
99
|
+
|
100
|
+
groups.each do |group|
|
101
|
+
case group
|
102
|
+
when NamedGroup::SECP256R1, NamedGroup::SECP384R1, NamedGroup::SECP521R1
|
103
|
+
curve = NamedGroup.curve_name(group)
|
104
|
+
ec = OpenSSL::PKey::EC.generate(curve)
|
105
|
+
shared_secret.store!(group, ec)
|
106
|
+
when NamedGroup::X25519, NamedGroup::X448
|
107
|
+
pkey = OpenSSL::PKey.generate_key(NamedGroup.curve_name(group))
|
108
|
+
shared_secret.store!(group, pkey)
|
109
|
+
else
|
110
|
+
# not supported other NamedGroup
|
111
|
+
raise Error::ErrorAlerts, :internal_error
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
shared_secret
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/lib/tttls1.3/utils.rb
CHANGED
@@ -69,21 +69,6 @@ module TTTLS13
|
|
69
69
|
length.to_uint64 + self
|
70
70
|
end
|
71
71
|
end
|
72
|
-
|
73
|
-
refine OpenSSL::X509::Certificate do
|
74
|
-
unless method_defined?(:ocsp_uris)
|
75
|
-
define_method(:ocsp_uris) do
|
76
|
-
aia = extensions.find { |ex| ex.oid == 'authorityInfoAccess' }
|
77
|
-
return nil if aia.nil?
|
78
|
-
|
79
|
-
ostr = OpenSSL::ASN1.decode(aia.to_der).value.last
|
80
|
-
ocsp = OpenSSL::ASN1.decode(ostr.value)
|
81
|
-
.map(&:value)
|
82
|
-
.select { |des| des.first.value == 'OCSP' }
|
83
|
-
ocsp&.map { |o| o[1].value }
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
72
|
end
|
88
73
|
|
89
74
|
module Convert
|
data/lib/tttls1.3/version.rb
CHANGED
data/lib/tttls1.3.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'openssl'
|
4
4
|
require 'net/http'
|
5
|
-
require 'pp'
|
6
5
|
require 'logger'
|
7
6
|
|
8
7
|
require 'ech_config'
|
@@ -18,6 +17,7 @@ require 'tttls1.3/named_group'
|
|
18
17
|
require 'tttls1.3/cryptograph'
|
19
18
|
require 'tttls1.3/transcript'
|
20
19
|
require 'tttls1.3/key_schedule'
|
20
|
+
require 'tttls1.3/shared_secret'
|
21
21
|
require 'tttls1.3/message'
|
22
22
|
require 'tttls1.3/sequence_number'
|
23
23
|
require 'tttls1.3/sslkeylogfile'
|
data/spec/client_hello_spec.rb
CHANGED
@@ -21,9 +21,9 @@ RSpec.describe ClientHello do
|
|
21
21
|
end
|
22
22
|
|
23
23
|
let(:message) do
|
24
|
-
ClientHello.new(random
|
25
|
-
legacy_session_id
|
26
|
-
cipher_suites:
|
24
|
+
ClientHello.new(random:,
|
25
|
+
legacy_session_id:,
|
26
|
+
cipher_suites:)
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'should be generated' do
|
@@ -92,7 +92,7 @@ RSpec.describe ClientHello do
|
|
92
92
|
TLS_AES_128_GCM_SHA256])
|
93
93
|
ch = ClientHello.new(random: OpenSSL::Random.random_bytes(32),
|
94
94
|
legacy_session_id: Array.new(32, 0).map(&:chr).join,
|
95
|
-
cipher_suites:
|
95
|
+
cipher_suites:)
|
96
96
|
ch.extensions[Message::ExtensionType::ENCRYPTED_CLIENT_HELLO] \
|
97
97
|
= Message::Extension::ECHClientHello.new_inner
|
98
98
|
ch
|
data/spec/client_spec.rb
CHANGED
@@ -118,8 +118,8 @@ RSpec.describe Client do
|
|
118
118
|
let(:finished_key) do
|
119
119
|
key_schedule = KeySchedule.new(
|
120
120
|
shared_secret: TESTBINARY_SHARED_SECRET,
|
121
|
-
cipher_suite
|
122
|
-
transcript:
|
121
|
+
cipher_suite:,
|
122
|
+
transcript:
|
123
123
|
)
|
124
124
|
key_schedule.client_finished_key
|
125
125
|
end
|
@@ -130,19 +130,19 @@ RSpec.describe Client do
|
|
130
130
|
digest = CipherSuite.digest(cipher_suite)
|
131
131
|
hash = transcript.hash(digest, EOED)
|
132
132
|
signature = Endpoint.sign_finished(
|
133
|
-
digest
|
134
|
-
finished_key
|
135
|
-
hash:
|
133
|
+
digest:,
|
134
|
+
finished_key:,
|
135
|
+
hash:
|
136
136
|
)
|
137
137
|
hs_wcipher = Cryptograph::Aead.new(
|
138
|
-
cipher_suite
|
138
|
+
cipher_suite:,
|
139
139
|
write_key: TESTBINARY_CLIENT_FINISHED_WRITE_KEY,
|
140
140
|
write_iv: TESTBINARY_CLIENT_FINISHED_WRITE_IV,
|
141
141
|
sequence_number: SequenceNumber.new
|
142
142
|
)
|
143
143
|
client.send(:send_finished, signature, hs_wcipher)
|
144
144
|
hs_rcipher = Cryptograph::Aead.new(
|
145
|
-
cipher_suite
|
145
|
+
cipher_suite:,
|
146
146
|
write_key: TESTBINARY_CLIENT_FINISHED_WRITE_KEY,
|
147
147
|
write_iv: TESTBINARY_CLIENT_FINISHED_WRITE_IV,
|
148
148
|
sequence_number: SequenceNumber.new
|
@@ -194,8 +194,8 @@ RSpec.describe Client do
|
|
194
194
|
let(:key_schedule) do
|
195
195
|
KeySchedule.new(
|
196
196
|
shared_secret: TESTBINARY_SHARED_SECRET,
|
197
|
-
cipher_suite
|
198
|
-
transcript:
|
197
|
+
cipher_suite:,
|
198
|
+
transcript:
|
199
199
|
)
|
200
200
|
end
|
201
201
|
|
@@ -218,9 +218,9 @@ RSpec.describe Client do
|
|
218
218
|
hash = transcript.hash(digest, CV)
|
219
219
|
expect(Endpoint.verified_finished?(
|
220
220
|
finished: sf,
|
221
|
-
digest
|
221
|
+
digest:,
|
222
222
|
finished_key: key_schedule.server_finished_key,
|
223
|
-
hash:
|
223
|
+
hash:
|
224
224
|
)).to be true
|
225
225
|
end
|
226
226
|
|
@@ -228,9 +228,9 @@ RSpec.describe Client do
|
|
228
228
|
digest = CipherSuite.digest(cipher_suite)
|
229
229
|
hash = transcript.hash(digest, EOED)
|
230
230
|
expect(Endpoint.sign_finished(
|
231
|
-
digest
|
231
|
+
digest:,
|
232
232
|
finished_key: key_schedule.client_finished_key,
|
233
|
-
hash:
|
233
|
+
hash:
|
234
234
|
)).to eq cf.verify_data
|
235
235
|
end
|
236
236
|
end
|
data/spec/endpoint_spec.rb
CHANGED
@@ -72,9 +72,9 @@ RSpec.describe Endpoint do
|
|
72
72
|
signature = cv.signature
|
73
73
|
|
74
74
|
expect(Endpoint.verified_certificate_verify?(
|
75
|
-
public_key
|
76
|
-
signature_scheme
|
77
|
-
signature
|
75
|
+
public_key:,
|
76
|
+
signature_scheme:,
|
77
|
+
signature:,
|
78
78
|
context: 'TLS 1.3, server CertificateVerify',
|
79
79
|
hash: transcript.hash(digest, CT)
|
80
80
|
)).to be true
|
@@ -104,15 +104,15 @@ RSpec.describe Endpoint do
|
|
104
104
|
# used RSASSA-PSS signature_scheme, salt is a random sequence.
|
105
105
|
# CertificateVerify.signature is random.
|
106
106
|
signature = Endpoint.sign_certificate_verify(
|
107
|
-
key
|
108
|
-
signature_scheme
|
107
|
+
key:,
|
108
|
+
signature_scheme:,
|
109
109
|
context: 'TLS 1.3, server CertificateVerify',
|
110
110
|
hash: transcript.hash(digest, CT)
|
111
111
|
)
|
112
112
|
expect(Endpoint.verified_certificate_verify?(
|
113
|
-
public_key
|
114
|
-
signature_scheme
|
115
|
-
signature
|
113
|
+
public_key:,
|
114
|
+
signature_scheme:,
|
115
|
+
signature:,
|
116
116
|
context: 'TLS 1.3, server CertificateVerify',
|
117
117
|
hash: transcript.hash(digest, CT)
|
118
118
|
)).to be true
|
@@ -156,9 +156,9 @@ RSpec.describe Endpoint do
|
|
156
156
|
signature = cv.signature
|
157
157
|
|
158
158
|
expect(Endpoint.verified_certificate_verify?(
|
159
|
-
public_key
|
160
|
-
signature_scheme
|
161
|
-
signature
|
159
|
+
public_key:,
|
160
|
+
signature_scheme:,
|
161
|
+
signature:,
|
162
162
|
context: 'TLS 1.3, server CertificateVerify',
|
163
163
|
hash: transcript.hash(digest, CT)
|
164
164
|
)).to be true
|
data/spec/key_schedule_spec.rb
CHANGED
@@ -25,7 +25,7 @@ RSpec.describe KeySchedule do
|
|
25
25
|
)
|
26
26
|
KeySchedule.new(shared_secret: TESTBINARY_SHARED_SECRET,
|
27
27
|
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
28
|
-
transcript:
|
28
|
+
transcript:)
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'should generate secret' do
|
@@ -104,7 +104,7 @@ RSpec.describe KeySchedule do
|
|
104
104
|
KeySchedule.new(psk: TESTBINARY_0_RTT_PSK,
|
105
105
|
shared_secret: TESTBINARY_0_RTT_SHARED_SECRET,
|
106
106
|
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
107
|
-
transcript:
|
107
|
+
transcript:)
|
108
108
|
end
|
109
109
|
|
110
110
|
it 'should generate server parameters write_key, iv' do
|
@@ -131,7 +131,7 @@ RSpec.describe KeySchedule do
|
|
131
131
|
KeySchedule.new(psk: TESTBINARY_0_RTT_PSK,
|
132
132
|
shared_secret: nil,
|
133
133
|
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
134
|
-
transcript:
|
134
|
+
transcript:)
|
135
135
|
end
|
136
136
|
|
137
137
|
it 'should generate binder key for resumption PSKs' do
|
@@ -177,7 +177,7 @@ RSpec.describe KeySchedule do
|
|
177
177
|
)
|
178
178
|
KeySchedule.new(shared_secret: TESTBINARY_HRR_SHARED_SECRET,
|
179
179
|
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
180
|
-
transcript:
|
180
|
+
transcript:)
|
181
181
|
end
|
182
182
|
|
183
183
|
it 'should generate server finished_key' do
|
@@ -23,10 +23,10 @@ RSpec.describe NewSessionTicket do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
let(:message) do
|
26
|
-
NewSessionTicket.new(ticket_lifetime
|
27
|
-
ticket_age_add
|
28
|
-
ticket_nonce
|
29
|
-
ticket:
|
26
|
+
NewSessionTicket.new(ticket_lifetime:,
|
27
|
+
ticket_age_add:,
|
28
|
+
ticket_nonce:,
|
29
|
+
ticket:)
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'should be generated' do
|
data/spec/pre_shared_key_spec.rb
CHANGED
@@ -23,22 +23,22 @@ RSpec.describe PreSharedKey do
|
|
23
23
|
let(:identities) do
|
24
24
|
[
|
25
25
|
PskIdentity.new(
|
26
|
-
identity
|
27
|
-
obfuscated_ticket_age:
|
26
|
+
identity:,
|
27
|
+
obfuscated_ticket_age:
|
28
28
|
)
|
29
29
|
]
|
30
30
|
end
|
31
31
|
|
32
32
|
let(:offered_psks) do
|
33
33
|
OfferedPsks.new(
|
34
|
-
identities
|
35
|
-
binders:
|
34
|
+
identities:,
|
35
|
+
binders:
|
36
36
|
)
|
37
37
|
end
|
38
38
|
|
39
39
|
let(:extension) do
|
40
40
|
PreSharedKey.new(msg_type: HandshakeType::CLIENT_HELLO,
|
41
|
-
offered_psks:
|
41
|
+
offered_psks:)
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'should be generated' do
|
@@ -98,14 +98,14 @@ RSpec.describe PreSharedKey do
|
|
98
98
|
|
99
99
|
let(:offered_psks) do
|
100
100
|
OfferedPsks.new(
|
101
|
-
identities
|
102
|
-
binders:
|
101
|
+
identities:,
|
102
|
+
binders:
|
103
103
|
)
|
104
104
|
end
|
105
105
|
|
106
106
|
let(:extension) do
|
107
107
|
PreSharedKey.new(msg_type: HandshakeType::CLIENT_HELLO,
|
108
|
-
offered_psks:
|
108
|
+
offered_psks:)
|
109
109
|
end
|
110
110
|
|
111
111
|
it 'should be generated' do
|
data/spec/record_spec.rb
CHANGED
@@ -39,7 +39,7 @@ RSpec.describe Record do
|
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'should generate valid serializable object' do
|
42
|
-
expect(record.serialize).to eq
|
42
|
+
expect(record.serialize).to eq ContentType::CCS \
|
43
43
|
+ ProtocolVersion::TLS_1_2 \
|
44
44
|
+ 1.to_uint16 \
|
45
45
|
+ ChangeCipherSpec.new.serialize
|
data/spec/server_hello_spec.rb
CHANGED
@@ -19,9 +19,9 @@ RSpec.describe ServerHello do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
let(:message) do
|
22
|
-
ServerHello.new(random
|
23
|
-
legacy_session_id_echo
|
24
|
-
cipher_suite:
|
22
|
+
ServerHello.new(random:,
|
23
|
+
legacy_session_id_echo:,
|
24
|
+
cipher_suite:)
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'should be generated' do
|
@@ -121,8 +121,8 @@ RSpec.describe ServerHello do
|
|
121
121
|
|
122
122
|
let(:message) do
|
123
123
|
ServerHello.new(random: Message::HRR_RANDOM,
|
124
|
-
legacy_session_id_echo
|
125
|
-
cipher_suite:
|
124
|
+
legacy_session_id_echo:,
|
125
|
+
cipher_suite:)
|
126
126
|
end
|
127
127
|
|
128
128
|
it 'should be generated' do
|
data/spec/server_spec.rb
CHANGED
@@ -34,7 +34,6 @@ RSpec.describe Server do
|
|
34
34
|
let(:ch) do
|
35
35
|
ch = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
|
36
36
|
|
37
|
-
# X25519 is unsupported so @named_group uses SECP256R1.
|
38
37
|
key_share = KeyShare.new(
|
39
38
|
msg_type: HandshakeType::CLIENT_HELLO,
|
40
39
|
key_share_entry: [
|
@@ -77,7 +76,8 @@ RSpec.describe Server do
|
|
77
76
|
expect(ee.extensions[ExtensionType::SERVER_NAME].server_name).to eq ''
|
78
77
|
expect(ee.extensions).to include(ExtensionType::SUPPORTED_GROUPS)
|
79
78
|
expect(ee.extensions[ExtensionType::SUPPORTED_GROUPS].named_group_list)
|
80
|
-
.to eq [NamedGroup::
|
79
|
+
.to eq [NamedGroup::X25519,
|
80
|
+
NamedGroup::SECP256R1,
|
81
81
|
NamedGroup::SECP384R1,
|
82
82
|
NamedGroup::SECP521R1]
|
83
83
|
end
|
@@ -175,9 +175,9 @@ RSpec.describe Server do
|
|
175
175
|
signature = cv.signature
|
176
176
|
digest = CipherSuite.digest(cipher_suite)
|
177
177
|
expect(Endpoint.verified_certificate_verify?(
|
178
|
-
public_key
|
179
|
-
signature_scheme
|
180
|
-
signature
|
178
|
+
public_key:,
|
179
|
+
signature_scheme:,
|
180
|
+
signature:,
|
181
181
|
context: 'TLS 1.3, server CertificateVerify',
|
182
182
|
hash: transcript.hash(digest, CT)
|
183
183
|
)).to be true
|
@@ -208,14 +208,14 @@ RSpec.describe Server do
|
|
208
208
|
|
209
209
|
let(:key_schedule) do
|
210
210
|
KeySchedule.new(shared_secret: TESTBINARY_SHARED_SECRET,
|
211
|
-
cipher_suite
|
212
|
-
transcript:
|
211
|
+
cipher_suite:,
|
212
|
+
transcript:)
|
213
213
|
end
|
214
214
|
|
215
215
|
let(:signature) do
|
216
216
|
digest = CipherSuite.digest(cipher_suite)
|
217
217
|
Endpoint.sign_finished(
|
218
|
-
digest
|
218
|
+
digest:,
|
219
219
|
finished_key: key_schedule.server_finished_key,
|
220
220
|
hash: transcript.hash(digest, CV)
|
221
221
|
)
|
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 = '>=3.1'
|
16
|
+
spec.required_ruby_version = '>= 3.1.0'
|
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)/})
|
@@ -23,5 +23,5 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency 'ech_config', '~> 0.0.3'
|
24
24
|
spec.add_dependency 'hpke'
|
25
25
|
spec.add_dependency 'logger'
|
26
|
-
spec.add_dependency 'openssl'
|
26
|
+
spec.add_dependency 'openssl', '>= 3'
|
27
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
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.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thekuwayama
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: bundler
|
@@ -72,14 +71,14 @@ dependencies:
|
|
72
71
|
requirements:
|
73
72
|
- - ">="
|
74
73
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
74
|
+
version: '3'
|
76
75
|
type: :runtime
|
77
76
|
prerelease: false
|
78
77
|
version_requirements: !ruby/object:Gem::Requirement
|
79
78
|
requirements:
|
80
79
|
- - ">="
|
81
80
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
81
|
+
version: '3'
|
83
82
|
description: TLS 1.3 implementation in Ruby (Tiny Trial TLS1.3 aka tttls1.3)
|
84
83
|
email:
|
85
84
|
- thekuwayama@gmail.com
|
@@ -102,7 +101,6 @@ files:
|
|
102
101
|
- example/https_client_using_0rtt.rb
|
103
102
|
- example/https_client_using_ech.rb
|
104
103
|
- example/https_client_using_grease_ech.rb
|
105
|
-
- example/https_client_using_grease_psk.rb
|
106
104
|
- example/https_client_using_hrr.rb
|
107
105
|
- example/https_client_using_hrr_and_ech.rb
|
108
106
|
- example/https_client_using_hrr_and_ticket.rb
|
@@ -160,6 +158,7 @@ files:
|
|
160
158
|
- lib/tttls1.3/named_group.rb
|
161
159
|
- lib/tttls1.3/sequence_number.rb
|
162
160
|
- lib/tttls1.3/server.rb
|
161
|
+
- lib/tttls1.3/shared_secret.rb
|
163
162
|
- lib/tttls1.3/signature_scheme.rb
|
164
163
|
- lib/tttls1.3/sslkeylogfile.rb
|
165
164
|
- lib/tttls1.3/transcript.rb
|
@@ -224,7 +223,6 @@ homepage: https://github.com/thekuwayama/tttls1.3
|
|
224
223
|
licenses:
|
225
224
|
- MIT
|
226
225
|
metadata: {}
|
227
|
-
post_install_message:
|
228
226
|
rdoc_options: []
|
229
227
|
require_paths:
|
230
228
|
- lib
|
@@ -232,15 +230,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
232
230
|
requirements:
|
233
231
|
- - ">="
|
234
232
|
- !ruby/object:Gem::Version
|
235
|
-
version:
|
233
|
+
version: 3.1.0
|
236
234
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
235
|
requirements:
|
238
236
|
- - ">="
|
239
237
|
- !ruby/object:Gem::Version
|
240
238
|
version: '0'
|
241
239
|
requirements: []
|
242
|
-
rubygems_version: 3.
|
243
|
-
signing_key:
|
240
|
+
rubygems_version: 3.6.7
|
244
241
|
specification_version: 4
|
245
242
|
summary: TLS 1.3 implementation in Ruby (Tiny Trial TLS1.3 aka tttls1.3)
|
246
243
|
test_files:
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require_relative 'helper'
|
5
|
-
HpkeSymmetricCipherSuite = \
|
6
|
-
ECHConfig::ECHConfigContents::HpkeKeyConfig::HpkeSymmetricCipherSuite
|
7
|
-
|
8
|
-
uri = URI.parse(ARGV[0] || 'https://localhost:4433')
|
9
|
-
ca_file = __dir__ + '/../tmp/ca.crt'
|
10
|
-
req = simple_http_request(uri.host, uri.path)
|
11
|
-
|
12
|
-
rr = Resolv::DNS.new.getresources(
|
13
|
-
uri.host,
|
14
|
-
Resolv::DNS::Resource::IN::HTTPS
|
15
|
-
)
|
16
|
-
settings_2nd = {
|
17
|
-
ca_file: File.exist?(ca_file) ? ca_file : nil,
|
18
|
-
alpn: ['http/1.1'],
|
19
|
-
ech_config: rr.first.svc_params['ech'].echconfiglist.first,
|
20
|
-
ech_hpke_cipher_suites:
|
21
|
-
TTTLS13::STANDARD_CLIENT_ECH_HPKE_SYMMETRIC_CIPHER_SUITES,
|
22
|
-
sslkeylogfile: '/tmp/sslkeylogfile.log'
|
23
|
-
}
|
24
|
-
process_new_session_ticket = lambda do |nst, rms, cs|
|
25
|
-
return if Time.now.to_i - nst.timestamp > nst.ticket_lifetime
|
26
|
-
|
27
|
-
settings_2nd[:ticket] = nst.ticket
|
28
|
-
settings_2nd[:resumption_main_secret] = rms
|
29
|
-
settings_2nd[:psk_cipher_suite] = cs
|
30
|
-
settings_2nd[:ticket_nonce] = nst.ticket_nonce
|
31
|
-
settings_2nd[:ticket_age_add] = nst.ticket_age_add
|
32
|
-
settings_2nd[:ticket_timestamp] = nst.timestamp
|
33
|
-
end
|
34
|
-
settings_1st = {
|
35
|
-
ca_file: File.exist?(ca_file) ? ca_file : nil,
|
36
|
-
alpn: ['http/1.1'],
|
37
|
-
process_new_session_ticket: process_new_session_ticket,
|
38
|
-
ech_config: rr.first.svc_params['ech'].echconfiglist.first,
|
39
|
-
ech_hpke_cipher_suites:
|
40
|
-
TTTLS13::STANDARD_CLIENT_ECH_HPKE_SYMMETRIC_CIPHER_SUITES,
|
41
|
-
sslkeylogfile: '/tmp/sslkeylogfile.log'
|
42
|
-
}
|
43
|
-
|
44
|
-
[
|
45
|
-
# Initial Handshake:
|
46
|
-
settings_1st,
|
47
|
-
# Subsequent Handshake:
|
48
|
-
settings_2nd
|
49
|
-
].each do |settings|
|
50
|
-
socket = TCPSocket.new(uri.host, uri.port)
|
51
|
-
client = TTTLS13::Client.new(socket, uri.host, **settings)
|
52
|
-
client.connect
|
53
|
-
client.write(req)
|
54
|
-
|
55
|
-
print recv_http_response(client)
|
56
|
-
client.close unless client.eof?
|
57
|
-
socket.close
|
58
|
-
end
|