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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +3 -0
- data/.rubocop.yml +16 -0
- data/.travis.yml +8 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +21 -0
- data/README.md +52 -0
- data/Rakefile +133 -0
- data/example/helper.rb +17 -0
- data/example/https_client.rb +32 -0
- data/example/https_client_using_0rtt.rb +64 -0
- data/example/https_client_using_hrr.rb +35 -0
- data/example/https_client_using_ticket.rb +56 -0
- data/lib/tttls1.3/cipher_suites.rb +102 -0
- data/lib/tttls1.3/client.rb +745 -0
- data/lib/tttls1.3/connection.rb +380 -0
- data/lib/tttls1.3/cryptograph/aead.rb +118 -0
- data/lib/tttls1.3/cryptograph/passer.rb +22 -0
- data/lib/tttls1.3/cryptograph.rb +3 -0
- data/lib/tttls1.3/error.rb +22 -0
- data/lib/tttls1.3/key_schedule.rb +242 -0
- data/lib/tttls1.3/message/alert.rb +86 -0
- data/lib/tttls1.3/message/application_data.rb +27 -0
- data/lib/tttls1.3/message/certificate.rb +121 -0
- data/lib/tttls1.3/message/certificate_verify.rb +59 -0
- data/lib/tttls1.3/message/change_cipher_spec.rb +26 -0
- data/lib/tttls1.3/message/client_hello.rb +100 -0
- data/lib/tttls1.3/message/encrypted_extensions.rb +65 -0
- data/lib/tttls1.3/message/end_of_early_data.rb +29 -0
- data/lib/tttls1.3/message/extension/alpn.rb +70 -0
- data/lib/tttls1.3/message/extension/cookie.rb +47 -0
- data/lib/tttls1.3/message/extension/early_data_indication.rb +58 -0
- data/lib/tttls1.3/message/extension/key_share.rb +236 -0
- data/lib/tttls1.3/message/extension/pre_shared_key.rb +205 -0
- data/lib/tttls1.3/message/extension/psk_key_exchange_modes.rb +54 -0
- data/lib/tttls1.3/message/extension/record_size_limit.rb +46 -0
- data/lib/tttls1.3/message/extension/server_name.rb +91 -0
- data/lib/tttls1.3/message/extension/signature_algorithms.rb +69 -0
- data/lib/tttls1.3/message/extension/signature_algorithms_cert.rb +25 -0
- data/lib/tttls1.3/message/extension/status_request.rb +106 -0
- data/lib/tttls1.3/message/extension/supported_groups.rb +145 -0
- data/lib/tttls1.3/message/extension/supported_versions.rb +98 -0
- data/lib/tttls1.3/message/extension/unknown_extension.rb +38 -0
- data/lib/tttls1.3/message/extensions.rb +173 -0
- data/lib/tttls1.3/message/finished.rb +44 -0
- data/lib/tttls1.3/message/new_session_ticket.rb +89 -0
- data/lib/tttls1.3/message/record.rb +232 -0
- data/lib/tttls1.3/message/server_hello.rb +116 -0
- data/lib/tttls1.3/message.rb +48 -0
- data/lib/tttls1.3/sequence_number.rb +31 -0
- data/lib/tttls1.3/signature_scheme.rb +31 -0
- data/lib/tttls1.3/transcript.rb +69 -0
- data/lib/tttls1.3/utils.rb +91 -0
- data/lib/tttls1.3/version.rb +5 -0
- data/lib/tttls1.3.rb +16 -0
- data/spec/aead_spec.rb +95 -0
- data/spec/alert_spec.rb +54 -0
- data/spec/alpn_spec.rb +55 -0
- data/spec/application_data_spec.rb +26 -0
- data/spec/certificate_spec.rb +55 -0
- data/spec/certificate_verify_spec.rb +51 -0
- data/spec/change_cipher_spec_spec.rb +26 -0
- data/spec/cipher_suites_spec.rb +39 -0
- data/spec/client_hello_spec.rb +83 -0
- data/spec/client_spec.rb +319 -0
- data/spec/connection_spec.rb +114 -0
- data/spec/cookie_spec.rb +98 -0
- data/spec/early_data_indication_spec.rb +64 -0
- data/spec/encrypted_extensions_spec.rb +94 -0
- data/spec/error_spec.rb +18 -0
- data/spec/extensions_spec.rb +170 -0
- data/spec/finished_spec.rb +55 -0
- data/spec/key_schedule_spec.rb +198 -0
- data/spec/key_share_spec.rb +199 -0
- data/spec/new_session_ticket_spec.rb +80 -0
- data/spec/pre_shared_key_spec.rb +167 -0
- data/spec/psk_key_exchange_modes_spec.rb +45 -0
- data/spec/record_size_limit_spec.rb +61 -0
- data/spec/record_spec.rb +105 -0
- data/spec/server_hello_spec.rb +101 -0
- data/spec/server_name_spec.rb +110 -0
- data/spec/signature_algorithms_cert_spec.rb +73 -0
- data/spec/signature_algorithms_spec.rb +100 -0
- data/spec/spec_helper.rb +872 -0
- data/spec/status_request_spec.rb +73 -0
- data/spec/supported_groups_spec.rb +79 -0
- data/spec/supported_versions_spec.rb +136 -0
- data/spec/transcript_spec.rb +69 -0
- data/spec/unknown_extension_spec.rb +90 -0
- data/spec/utils_spec.rb +215 -0
- data/tttls1.3.gemspec +25 -0
- metadata +197 -0
data/spec/error_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
RSpec.describe ErrorAlerts do
|
7
|
+
let(:error) do
|
8
|
+
ErrorAlerts.new('unexpected_message')
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:alert) do
|
12
|
+
Alert.new(description: ALERT_DESCRIPTION[:unexpected_message])
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should return alert' do
|
16
|
+
expect(error.to_alert.serialize).to eq alert.serialize
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
RSpec.describe Extensions do
|
7
|
+
context 'empty extensions' do
|
8
|
+
let(:extensions) do
|
9
|
+
Extensions.new
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should be generated' do
|
13
|
+
expect(extensions).to be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should be serialized' do
|
17
|
+
expect(extensions.serialize).to eq "\x00\x00"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:supported_versions) do
|
22
|
+
SupportedVersions.new(
|
23
|
+
msg_type: HandshakeType::CLIENT_HELLO,
|
24
|
+
versions: [ProtocolVersion::TLS_1_3]
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:signature_algorithms) do
|
29
|
+
SignatureAlgorithms.new([SignatureScheme::RSA_PSS_RSAE_SHA256])
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:supported_groups) do
|
33
|
+
SupportedGroups.new([NamedGroup::SECP256R1])
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:key_share) do
|
37
|
+
ec = OpenSSL::PKey::EC.new('prime256v1')
|
38
|
+
ec.generate_key!
|
39
|
+
KeyShare.new(
|
40
|
+
msg_type: HandshakeType::CLIENT_HELLO,
|
41
|
+
key_share_entry: [
|
42
|
+
KeyShareEntry.new(
|
43
|
+
group: NamedGroup::SECP256R1,
|
44
|
+
key_exchange: ec.public_key.to_octet_string(:uncompressed)
|
45
|
+
)
|
46
|
+
]
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
let(:server_name) do
|
51
|
+
ServerName.new('example.com')
|
52
|
+
end
|
53
|
+
|
54
|
+
let(:base_exs) do
|
55
|
+
[
|
56
|
+
supported_versions,
|
57
|
+
signature_algorithms,
|
58
|
+
supported_groups,
|
59
|
+
key_share,
|
60
|
+
server_name
|
61
|
+
]
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'client_hello base extensions' do
|
65
|
+
let(:extensions) do
|
66
|
+
Extensions.new(base_exs)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should be generated' do
|
70
|
+
expect(extensions)
|
71
|
+
.to include ExtensionType::SUPPORTED_VERSIONS => supported_versions
|
72
|
+
expect(extensions)
|
73
|
+
.to include ExtensionType::SIGNATURE_ALGORITHMS => signature_algorithms
|
74
|
+
expect(extensions)
|
75
|
+
.to include ExtensionType::SUPPORTED_GROUPS => supported_groups
|
76
|
+
expect(extensions)
|
77
|
+
.to include ExtensionType::KEY_SHARE => key_share
|
78
|
+
expect(extensions)
|
79
|
+
.to include ExtensionType::SERVER_NAME => server_name
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'extensions that include pre_shared_key' do
|
84
|
+
let(:pre_shared_key) do
|
85
|
+
PreSharedKey.deserialize(TESTBINARY_PRE_SHARED_KEY_CH,
|
86
|
+
HandshakeType::CLIENT_HELLO)
|
87
|
+
end
|
88
|
+
|
89
|
+
let(:extensions) do
|
90
|
+
exs = [pre_shared_key] + base_exs
|
91
|
+
Extensions.new(exs)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should be generated' do
|
95
|
+
expect(extensions)
|
96
|
+
.to include ExtensionType::SUPPORTED_VERSIONS => supported_versions
|
97
|
+
expect(extensions)
|
98
|
+
.to include ExtensionType::SIGNATURE_ALGORITHMS => signature_algorithms
|
99
|
+
expect(extensions)
|
100
|
+
.to include ExtensionType::SUPPORTED_GROUPS => supported_groups
|
101
|
+
expect(extensions)
|
102
|
+
.to include ExtensionType::KEY_SHARE => key_share
|
103
|
+
expect(extensions)
|
104
|
+
.to include ExtensionType::SERVER_NAME => server_name
|
105
|
+
expect(extensions)
|
106
|
+
.to include ExtensionType::PRE_SHARED_KEY => pre_shared_key
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should be serialized end with pre_shared_key' do
|
110
|
+
expect(extensions.serialize).to end_with TESTBINARY_PRE_SHARED_KEY_CH
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'extensions that include GREASE' do
|
115
|
+
let(:unknown_exs_key_aa) do
|
116
|
+
"\xaa\xaa"
|
117
|
+
end
|
118
|
+
|
119
|
+
let(:unknown_exs_key_bb) do
|
120
|
+
"\xbb\xbb"
|
121
|
+
end
|
122
|
+
|
123
|
+
let(:grease_aa) do
|
124
|
+
UnknownExtension.new(extension_type: unknown_exs_key_aa,
|
125
|
+
extension_data: '')
|
126
|
+
end
|
127
|
+
|
128
|
+
let(:grease_bb) do
|
129
|
+
UnknownExtension.new(extension_type: unknown_exs_key_bb,
|
130
|
+
extension_data: "\x00")
|
131
|
+
end
|
132
|
+
|
133
|
+
let(:extensions) do
|
134
|
+
exs = [grease_aa] + base_exs + [grease_bb]
|
135
|
+
Extensions.new(exs)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should be generated' do
|
139
|
+
expect(extensions)
|
140
|
+
.to include ExtensionType::SUPPORTED_VERSIONS => supported_versions
|
141
|
+
expect(extensions)
|
142
|
+
.to include ExtensionType::SIGNATURE_ALGORITHMS => signature_algorithms
|
143
|
+
expect(extensions)
|
144
|
+
.to include ExtensionType::SUPPORTED_GROUPS => supported_groups
|
145
|
+
expect(extensions)
|
146
|
+
.to include ExtensionType::KEY_SHARE => key_share
|
147
|
+
expect(extensions)
|
148
|
+
.to include ExtensionType::SERVER_NAME => server_name
|
149
|
+
# ignore UnknownExtension, so return nil
|
150
|
+
expect(extensions).to include unknown_exs_key_aa => nil
|
151
|
+
expect(extensions).to include unknown_exs_key_bb => nil
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'extensions binary' do
|
156
|
+
let(:extensions) do
|
157
|
+
Extensions.deserialize(TESTBINARY_EXTENSIONS,
|
158
|
+
HandshakeType::CLIENT_HELLO)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should generate object' do
|
162
|
+
expect(extensions).to include ExtensionType::SUPPORTED_GROUPS
|
163
|
+
expect(extensions).to include ExtensionType::KEY_SHARE
|
164
|
+
expect(extensions).to include ExtensionType::SUPPORTED_VERSIONS
|
165
|
+
expect(extensions).to include ExtensionType::SIGNATURE_ALGORITHMS
|
166
|
+
expect(extensions).to include ExtensionType::PSK_KEY_EXCHANGE_MODES
|
167
|
+
expect(extensions).to include ExtensionType::RECORD_SIZE_LIMIT
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe Finished do
|
8
|
+
context 'valid finished' do
|
9
|
+
let(:verify_data) do
|
10
|
+
OpenSSL::Random.random_bytes(128)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:message) do
|
14
|
+
Finished.new(verify_data)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should be generated' do
|
18
|
+
expect(message.msg_type).to eq HandshakeType::FINISHED
|
19
|
+
expect(message.verify_data).to eq verify_data
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should be serialized' do
|
23
|
+
expect(message.serialize).to eq HandshakeType::FINISHED \
|
24
|
+
+ verify_data.prefix_uint24_length
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'valid finished binary' do
|
29
|
+
let(:message) do
|
30
|
+
Finished.deserialize(TESTBINARY_SERVER_FINISHED)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should generate valid object' do
|
34
|
+
expect(message.msg_type).to eq HandshakeType::FINISHED
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should generate serializable object' do
|
38
|
+
expect(message.serialize).to eq TESTBINARY_SERVER_FINISHED
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'valid finished binary' do
|
43
|
+
let(:message) do
|
44
|
+
Finished.deserialize(TESTBINARY_CLIENT_FINISHED)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should generate valid object' do
|
48
|
+
expect(message.msg_type).to eq HandshakeType::FINISHED
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should generate serializable object' do
|
52
|
+
expect(message.serialize).to eq TESTBINARY_CLIENT_FINISHED
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
RSpec.describe KeySchedule do
|
7
|
+
context 'key_schedule, Simple 1-RTT Handshake,' do
|
8
|
+
let(:key_schedule) do
|
9
|
+
transcript = Transcript.new
|
10
|
+
transcript.merge!(
|
11
|
+
CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
|
12
|
+
SH => ServerHello.deserialize(TESTBINARY_SERVER_HELLO),
|
13
|
+
EE => EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS),
|
14
|
+
CT => Certificate.deserialize(TESTBINARY_CERTIFICATE),
|
15
|
+
CV => CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY),
|
16
|
+
SF => Finished.deserialize(TESTBINARY_SERVER_FINISHED),
|
17
|
+
CF => Finished.deserialize(TESTBINARY_CLIENT_FINISHED)
|
18
|
+
)
|
19
|
+
KeySchedule.new(shared_secret: TESTBINARY_SHARED_SECRET,
|
20
|
+
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
21
|
+
transcript: transcript)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should generate secret' do
|
25
|
+
expect(key_schedule.client_handshake_traffic_secret)
|
26
|
+
.to eq TESTBINARY_C_HS_TRAFFIC
|
27
|
+
expect(key_schedule.server_handshake_traffic_secret)
|
28
|
+
.to eq TESTBINARY_S_HS_TRAFFIC
|
29
|
+
expect(key_schedule.client_application_traffic_secret)
|
30
|
+
.to eq TESTBINARY_C_AP_TRAFFIC
|
31
|
+
expect(key_schedule.server_application_traffic_secret)
|
32
|
+
.to eq TESTBINARY_S_AP_TRAFFIC
|
33
|
+
expect(key_schedule.exporter_master_secret)
|
34
|
+
.to eq TESTBINARY_EXP_MASTER
|
35
|
+
expect(key_schedule.resumption_master_secret)
|
36
|
+
.to eq TESTBINARY_RES_MASTER
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should generate server finished_key' do
|
40
|
+
expect(key_schedule.server_finished_key)
|
41
|
+
.to eq TESTBINARY_SERVER_FINISHED_KEY
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should generate server parameters write_key, iv' do
|
45
|
+
expect(key_schedule.server_handshake_write_key)
|
46
|
+
.to eq TESTBINARY_SERVER_PARAMETERS_WRITE_KEY
|
47
|
+
expect(key_schedule.server_handshake_write_iv)
|
48
|
+
.to eq TESTBINARY_SERVER_PARAMETERS_WRITE_IV
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should generate client finished_key' do
|
52
|
+
expect(key_schedule.client_finished_key)
|
53
|
+
.to eq TESTBINARY_CLIENT_FINISHED_KEY
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should generate client finished write_key, iv' do
|
57
|
+
expect(key_schedule.client_handshake_write_key)
|
58
|
+
.to eq TESTBINARY_CLIENT_FINISHED_WRITE_KEY
|
59
|
+
expect(key_schedule.client_handshake_write_iv)
|
60
|
+
.to eq TESTBINARY_CLIENT_FINISHED_WRITE_IV
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should generete server application write_key, iv' do
|
64
|
+
expect(key_schedule.server_application_write_key)
|
65
|
+
.to eq TESTBINARY_SERVER_APPLICATION_WRITE_KEY
|
66
|
+
expect(key_schedule.server_application_write_iv)
|
67
|
+
.to eq TESTBINARY_SERVER_APPLICATION_WRITE_IV
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should generete client application write_key, iv' do
|
71
|
+
expect(key_schedule.client_application_write_key)
|
72
|
+
.to eq TESTBINARY_CLIENT_APPLICATION_WRITE_KEY
|
73
|
+
expect(key_schedule.client_application_write_iv)
|
74
|
+
.to eq TESTBINARY_CLIENT_APPLICATION_WRITE_IV
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'key_schedule, Resumed 0-RTT Handshake,' do
|
79
|
+
let(:key_schedule) do
|
80
|
+
transcript = Transcript.new
|
81
|
+
transcript.merge!(
|
82
|
+
CH => ClientHello.deserialize(TESTBINARY_0_RTT_CLIENT_HELLO),
|
83
|
+
SH => ServerHello.deserialize(TESTBINARY_0_RTT_SERVER_HELLO),
|
84
|
+
EE =>
|
85
|
+
EncryptedExtensions.deserialize(TESTBINARY_0_RTT_ENCRYPTED_EXTENSIONS),
|
86
|
+
SF => Finished.deserialize(TESTBINARY_0_RTT_SERVER_FINISHED),
|
87
|
+
EOED => EndOfEarlyData.deserialize(TESTBINARY_0_RTT_END_OF_EARLY_DATA),
|
88
|
+
CF => Finished.deserialize(TESTBINARY_0_RTT_CLIENT_FINISHED)
|
89
|
+
)
|
90
|
+
KeySchedule.new(psk: TESTBINARY_0_RTT_PSK,
|
91
|
+
shared_secret: TESTBINARY_0_RTT_SHARED_SECRET,
|
92
|
+
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
93
|
+
transcript: transcript)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should generate server parameters write_key, iv' do
|
97
|
+
expect(key_schedule.server_handshake_write_key)
|
98
|
+
.to eq TESTBINARY_0_RTT_SERVER_PARAMETERS_WRITE_KEY
|
99
|
+
expect(key_schedule.server_handshake_write_iv)
|
100
|
+
.to eq TESTBINARY_0_RTT_SERVER_PARAMETERS_WRITE_IV
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should generete client application write_key, iv' do
|
104
|
+
expect(key_schedule.client_application_write_key)
|
105
|
+
.to eq TESTBINARY_0_RTT_CLIENT_APPLICATION_WRITE_KEY
|
106
|
+
expect(key_schedule.client_application_write_iv)
|
107
|
+
.to eq TESTBINARY_0_RTT_CLIENT_APPLICATION_WRITE_IV
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'key_schedule, Resumed 0-RTT Handshake, ' \
|
112
|
+
'not negotiated shared_secret yet,' do
|
113
|
+
let(:key_schedule) do
|
114
|
+
transcript = Transcript.new
|
115
|
+
transcript[CH] = ClientHello.deserialize(TESTBINARY_0_RTT_CLIENT_HELLO)
|
116
|
+
KeySchedule.new(psk: TESTBINARY_0_RTT_PSK,
|
117
|
+
shared_secret: nil,
|
118
|
+
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
119
|
+
transcript: transcript)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should generate binder key for resumption PSKs' do
|
123
|
+
expect(key_schedule.binder_key_res)
|
124
|
+
.to eq TESTBINARY_0_RTT_BINDER_KEY_RES
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should generate client_early_traffic_secret' do
|
128
|
+
expect(key_schedule.client_early_traffic_secret)
|
129
|
+
.to eq TESTBINARY_0_RTT_C_E_TRAFFIC
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should generate 0-RTT application write_key, iv' do
|
133
|
+
expect(key_schedule.early_data_write_key)
|
134
|
+
.to eq TESTBINARY_0_RTT_EARLY_DATA_WRITE_KEY
|
135
|
+
expect(key_schedule.early_data_write_iv)
|
136
|
+
.to eq TESTBINARY_0_RTT_EARLY_DATA_WRITE_IV
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'key_schedule, HelloRetryRequest,' do
|
141
|
+
let(:key_schedule) do
|
142
|
+
transcript = Transcript.new
|
143
|
+
transcript.merge!(
|
144
|
+
CH1 => ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO1),
|
145
|
+
HRR => ServerHello.deserialize(TESTBINARY_HRR_HELLO_RETRY_REQUEST),
|
146
|
+
CH => ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO),
|
147
|
+
SH => ServerHello.deserialize(TESTBINARY_HRR_SERVER_HELLO),
|
148
|
+
EE =>
|
149
|
+
EncryptedExtensions.deserialize(TESTBINARY_HRR_ENCRYPTED_EXTENSIONS),
|
150
|
+
CT => Certificate.deserialize(TESTBINARY_HRR_CERTIFICATE),
|
151
|
+
CV => CertificateVerify.deserialize(TESTBINARY_HRR_CERTIFICATE_VERIFY),
|
152
|
+
SF => Finished.deserialize(TESTBINARY_HRR_SERVER_FINISHED),
|
153
|
+
CF => Finished.deserialize(TESTBINARY_HRR_CLIENT_FINISHED)
|
154
|
+
)
|
155
|
+
KeySchedule.new(shared_secret: TESTBINARY_HRR_SHARED_SECRET,
|
156
|
+
cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
|
157
|
+
transcript: transcript)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should generate server finished_key' do
|
161
|
+
expect(key_schedule.server_finished_key)
|
162
|
+
.to eq TESTBINARY_HRR_SERVER_FINISHED_KEY
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should generate server parameters write_key, iv' do
|
166
|
+
expect(key_schedule.server_handshake_write_key)
|
167
|
+
.to eq TESTBINARY_HRR_SERVER_PARAMETERS_WRITE_KEY
|
168
|
+
expect(key_schedule.server_handshake_write_iv)
|
169
|
+
.to eq TESTBINARY_HRR_SERVER_PARAMETERS_WRITE_IV
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should generate client finished_key' do
|
173
|
+
expect(key_schedule.client_finished_key)
|
174
|
+
.to eq TESTBINARY_HRR_CLIENT_FINISHED_KEY
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should generate client finished write_key, iv' do
|
178
|
+
expect(key_schedule.client_handshake_write_key)
|
179
|
+
.to eq TESTBINARY_HRR_CLIENT_FINISHED_WRITE_KEY
|
180
|
+
expect(key_schedule.client_handshake_write_iv)
|
181
|
+
.to eq TESTBINARY_HRR_CLIENT_FINISHED_WRITE_IV
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should generete server application write_key, iv' do
|
185
|
+
expect(key_schedule.server_application_write_key)
|
186
|
+
.to eq TESTBINARY_HRR_SERVER_APPLICATION_WRITE_KEY
|
187
|
+
expect(key_schedule.server_application_write_iv)
|
188
|
+
.to eq TESTBINARY_HRR_SERVER_APPLICATION_WRITE_IV
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'should generete client application write_key, iv' do
|
192
|
+
expect(key_schedule.client_application_write_key)
|
193
|
+
.to eq TESTBINARY_HRR_CLIENT_APPLICATION_WRITE_KEY
|
194
|
+
expect(key_schedule.client_application_write_iv)
|
195
|
+
.to eq TESTBINARY_HRR_CLIENT_APPLICATION_WRITE_IV
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
using Refinements
|
6
|
+
|
7
|
+
RSpec.describe KeyShare do
|
8
|
+
context 'valid key_share, KeyShareClientHello,' do
|
9
|
+
let(:public_key_secp384r1) do
|
10
|
+
"\x04" + OpenSSL::Random.random_bytes(96)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:public_key_secp256r1) do
|
14
|
+
"\x04" + OpenSSL::Random.random_bytes(64)
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:extension) do
|
18
|
+
KeyShare.new(
|
19
|
+
msg_type: HandshakeType::CLIENT_HELLO,
|
20
|
+
key_share_entry: [
|
21
|
+
KeyShareEntry.new(
|
22
|
+
group: NamedGroup::SECP384R1,
|
23
|
+
key_exchange: public_key_secp384r1
|
24
|
+
),
|
25
|
+
KeyShareEntry.new(
|
26
|
+
group: NamedGroup::SECP256R1,
|
27
|
+
key_exchange: public_key_secp256r1
|
28
|
+
)
|
29
|
+
]
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be generated' do
|
34
|
+
expect(extension.msg_type).to eq HandshakeType::CLIENT_HELLO
|
35
|
+
expect(extension.extension_type).to eq ExtensionType::KEY_SHARE
|
36
|
+
expect(extension.key_share_entry[0].group).to eq NamedGroup::SECP384R1
|
37
|
+
expect(extension.key_share_entry[0].key_exchange)
|
38
|
+
.to eq public_key_secp384r1
|
39
|
+
expect(extension.key_share_entry[1].group).to eq NamedGroup::SECP256R1
|
40
|
+
expect(extension.key_share_entry[1].key_exchange)
|
41
|
+
.to eq public_key_secp256r1
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should be serialized' do
|
45
|
+
expect(extension.serialize)
|
46
|
+
.to eq ExtensionType::KEY_SHARE \
|
47
|
+
+ 172.to_uint16 \
|
48
|
+
+ 170.to_uint16 \
|
49
|
+
+ NamedGroup::SECP384R1 \
|
50
|
+
+ NamedGroup.key_exchange_len(NamedGroup::SECP384R1).to_uint16 \
|
51
|
+
+ public_key_secp384r1 \
|
52
|
+
+ NamedGroup::SECP256R1 \
|
53
|
+
+ NamedGroup.key_exchange_len(NamedGroup::SECP256R1).to_uint16 \
|
54
|
+
+ public_key_secp256r1
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'valid key_share, empty KeyShare.client_shares vector' do
|
59
|
+
let(:extension) do
|
60
|
+
KeyShare.new(
|
61
|
+
msg_type: HandshakeType::CLIENT_HELLO,
|
62
|
+
key_share_entry: []
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should be generated' do
|
67
|
+
expect(extension.msg_type).to eq HandshakeType::CLIENT_HELLO
|
68
|
+
expect(extension.extension_type).to eq ExtensionType::KEY_SHARE
|
69
|
+
expect(extension.key_share_entry).to be_empty
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should be serialized' do
|
73
|
+
expect(extension.serialize).to eq ExtensionType::KEY_SHARE \
|
74
|
+
+ 2.to_uint16 \
|
75
|
+
+ 0.to_uint16
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'valid key_share, KeyShareServerHello,' do
|
80
|
+
let(:public_key_secp256r1) do
|
81
|
+
"\x04" + OpenSSL::Random.random_bytes(64)
|
82
|
+
end
|
83
|
+
|
84
|
+
let(:extension) do
|
85
|
+
KeyShare.new(
|
86
|
+
msg_type: HandshakeType::SERVER_HELLO,
|
87
|
+
key_share_entry: [
|
88
|
+
KeyShareEntry.new(
|
89
|
+
group: NamedGroup::SECP256R1,
|
90
|
+
key_exchange: public_key_secp256r1
|
91
|
+
)
|
92
|
+
]
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should be generated' do
|
97
|
+
expect(extension.msg_type).to eq HandshakeType::SERVER_HELLO
|
98
|
+
expect(extension.extension_type).to eq ExtensionType::KEY_SHARE
|
99
|
+
expect(extension.key_share_entry[0].group).to eq NamedGroup::SECP256R1
|
100
|
+
expect(extension.key_share_entry[0].key_exchange)
|
101
|
+
.to eq public_key_secp256r1
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should be serialized' do
|
105
|
+
expect(extension.serialize)
|
106
|
+
.to eq ExtensionType::KEY_SHARE \
|
107
|
+
+ 69.to_uint16 \
|
108
|
+
+ NamedGroup::SECP256R1 \
|
109
|
+
+ public_key_secp256r1.prefix_uint16_length
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'valid key_share, KeyShareHelloRetryRequest,' do
|
114
|
+
let(:extension) do
|
115
|
+
KeyShare.new(
|
116
|
+
msg_type: HandshakeType::HELLO_RETRY_REQUEST,
|
117
|
+
key_share_entry: [
|
118
|
+
KeyShareEntry.new(
|
119
|
+
group: NamedGroup::SECP256R1,
|
120
|
+
key_exchange: nil
|
121
|
+
)
|
122
|
+
]
|
123
|
+
)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should be generated' do
|
127
|
+
expect(extension.msg_type).to eq HandshakeType::HELLO_RETRY_REQUEST
|
128
|
+
expect(extension.extension_type).to eq ExtensionType::KEY_SHARE
|
129
|
+
expect(extension.key_share_entry[0].group).to eq NamedGroup::SECP256R1
|
130
|
+
expect(extension.key_share_entry[0].key_exchange).to be_empty
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should be serialized' do
|
134
|
+
expect(extension.serialize)
|
135
|
+
.to eq ExtensionType::KEY_SHARE \
|
136
|
+
+ NamedGroup::SECP256R1.prefix_uint16_length
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'valid key_share binary, KeyShareClientHello,' do
|
141
|
+
let(:extension) do
|
142
|
+
KeyShare.deserialize(TESTBINARY_KEY_SHARE_CH, HandshakeType::CLIENT_HELLO)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should generate valid object' do
|
146
|
+
expect(extension.msg_type).to eq HandshakeType::CLIENT_HELLO
|
147
|
+
expect(extension.extension_type).to eq ExtensionType::KEY_SHARE
|
148
|
+
expect(extension.key_share_entry[0].group).to eq NamedGroup::SECP256R1
|
149
|
+
expect(extension.key_share_entry[0].key_exchange.length)
|
150
|
+
.to eq NamedGroup.key_exchange_len(NamedGroup::SECP256R1)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should generate serializable object' do
|
154
|
+
expect(extension.serialize)
|
155
|
+
.to eq ExtensionType::KEY_SHARE \
|
156
|
+
+ TESTBINARY_KEY_SHARE_CH.prefix_uint16_length
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'valid key_share binary, KeyShareServerHello,' do
|
161
|
+
let(:extension) do
|
162
|
+
KeyShare.deserialize(TESTBINARY_KEY_SHARE_SH, HandshakeType::SERVER_HELLO)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should generate valid object' do
|
166
|
+
expect(extension.msg_type).to eq HandshakeType::SERVER_HELLO
|
167
|
+
expect(extension.extension_type).to eq ExtensionType::KEY_SHARE
|
168
|
+
expect(extension.key_share_entry[0].group).to eq NamedGroup::SECP256R1
|
169
|
+
expect(extension.key_share_entry[0].key_exchange.length)
|
170
|
+
.to eq NamedGroup.key_exchange_len(NamedGroup::SECP256R1)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should generate serializable object' do
|
174
|
+
expect(extension.serialize)
|
175
|
+
.to eq ExtensionType::KEY_SHARE \
|
176
|
+
+ TESTBINARY_KEY_SHARE_SH.prefix_uint16_length
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'valid key_share binary, KeyShareHelloRetryRequest,' do
|
181
|
+
let(:extension) do
|
182
|
+
KeyShare.deserialize(TESTBINARY_KEY_SHARE_HRR,
|
183
|
+
HandshakeType::HELLO_RETRY_REQUEST)
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should generate valid object' do
|
187
|
+
expect(extension.msg_type).to eq HandshakeType::HELLO_RETRY_REQUEST
|
188
|
+
expect(extension.extension_type).to eq ExtensionType::KEY_SHARE
|
189
|
+
expect(extension.key_share_entry[0].group).to eq NamedGroup::SECP256R1
|
190
|
+
expect(extension.key_share_entry[0].key_exchange).to be_empty
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'should generate serializable object' do
|
194
|
+
expect(extension.serialize)
|
195
|
+
.to eq ExtensionType::KEY_SHARE \
|
196
|
+
+ TESTBINARY_KEY_SHARE_HRR.prefix_uint16_length
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|