tttls1.3 0.3.6 → 0.3.7
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/.ruby-version +1 -1
- data/lib/tttls1.3/version.rb +1 -1
- data/lib/tttls1.3.rb +1 -0
- data/tttls1.3.gemspec +5 -2
- metadata +3 -113
- data/.github/workflows/ci.yml +0 -39
- data/.gitignore +0 -17
- data/spec/aead_spec.rb +0 -95
- data/spec/alert_spec.rb +0 -54
- data/spec/alpn_spec.rb +0 -55
- data/spec/application_data_spec.rb +0 -26
- data/spec/certificate_spec.rb +0 -82
- data/spec/certificate_verify_spec.rb +0 -51
- data/spec/change_cipher_spec_spec.rb +0 -26
- data/spec/cipher_suites_spec.rb +0 -39
- data/spec/client_hello_spec.rb +0 -105
- data/spec/client_spec.rb +0 -274
- data/spec/compress_certificate_spec.rb +0 -54
- data/spec/cookie_spec.rb +0 -98
- data/spec/early_data_indication_spec.rb +0 -64
- data/spec/ech_outer_extensions_spec.rb +0 -42
- data/spec/ech_spec.rb +0 -122
- data/spec/encrypted_extensions_spec.rb +0 -94
- data/spec/end_of_early_data_spec.rb +0 -28
- data/spec/endpoint_spec.rb +0 -167
- data/spec/error_spec.rb +0 -18
- data/spec/extensions_spec.rb +0 -250
- data/spec/finished_spec.rb +0 -55
- data/spec/fixtures/rsa_ca.crt +0 -18
- data/spec/fixtures/rsa_ca.key +0 -27
- data/spec/fixtures/rsa_rsa.crt +0 -18
- data/spec/fixtures/rsa_rsa.key +0 -27
- data/spec/fixtures/rsa_rsa_ocsp.crt +0 -18
- data/spec/fixtures/rsa_rsa_ocsp.key +0 -27
- data/spec/fixtures/rsa_rsassaPss.crt +0 -20
- data/spec/fixtures/rsa_rsassaPss.key +0 -27
- data/spec/fixtures/rsa_secp256r1.crt +0 -14
- data/spec/fixtures/rsa_secp256r1.key +0 -5
- data/spec/fixtures/rsa_secp384r1.crt +0 -14
- data/spec/fixtures/rsa_secp384r1.key +0 -6
- data/spec/fixtures/rsa_secp521r1.crt +0 -15
- data/spec/fixtures/rsa_secp521r1.key +0 -7
- data/spec/key_schedule_spec.rb +0 -221
- data/spec/key_share_spec.rb +0 -199
- data/spec/new_session_ticket_spec.rb +0 -80
- data/spec/pre_shared_key_spec.rb +0 -167
- data/spec/psk_key_exchange_modes_spec.rb +0 -45
- data/spec/record_size_limit_spec.rb +0 -61
- data/spec/record_spec.rb +0 -105
- data/spec/server_hello_spec.rb +0 -200
- data/spec/server_name_spec.rb +0 -110
- data/spec/server_spec.rb +0 -232
- data/spec/signature_algorithms_cert_spec.rb +0 -77
- data/spec/signature_algorithms_spec.rb +0 -104
- data/spec/spec_helper.rb +0 -990
- data/spec/status_request_spec.rb +0 -140
- data/spec/supported_groups_spec.rb +0 -79
- data/spec/supported_versions_spec.rb +0 -136
- data/spec/transcript_spec.rb +0 -83
- data/spec/unknown_extension_spec.rb +0 -90
- data/spec/utils_spec.rb +0 -235
data/spec/ech_spec.rb
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
# encoding: ascii-8bit
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require_relative 'spec_helper'
|
|
5
|
-
using Refinements
|
|
6
|
-
|
|
7
|
-
RSpec.describe ECHClientHello do
|
|
8
|
-
context 'valid ECHClientHello outer binary' do
|
|
9
|
-
let(:extension) do
|
|
10
|
-
ECHClientHello.deserialize(TESTBINARY_ECH_OUTER)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it 'should generate valid object' do
|
|
14
|
-
expect(extension.extension_type)
|
|
15
|
-
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO
|
|
16
|
-
expect(extension.type).to eq ECHClientHelloType::OUTER
|
|
17
|
-
expect(extension.cipher_suite.kdf_id.uint16).to eq 1
|
|
18
|
-
expect(extension.cipher_suite.aead_id.uint16).to eq 1
|
|
19
|
-
expect(extension.config_id).to eq 32
|
|
20
|
-
expect(extension.enc.length).to eq 32
|
|
21
|
-
expect(extension.payload.length).to eq 239
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'should be serialized' do
|
|
25
|
-
expect(extension.serialize)
|
|
26
|
-
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO \
|
|
27
|
-
+ 281.to_uint16 \
|
|
28
|
-
+ ECHClientHelloType::OUTER \
|
|
29
|
-
+ 1.to_uint16 \
|
|
30
|
-
+ 1.to_uint16 \
|
|
31
|
-
+ 32.to_uint8 \
|
|
32
|
-
+ extension.enc.prefix_uint16_length \
|
|
33
|
-
+ extension.payload.prefix_uint16_length
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context 'valid ECHClientHello inner binary' do
|
|
38
|
-
let(:extension) do
|
|
39
|
-
ECHClientHello.deserialize(TESTBINARY_ECH_INNER)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it 'should generate valid object' do
|
|
43
|
-
expect(extension.extension_type)
|
|
44
|
-
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO
|
|
45
|
-
expect(extension.type).to eq ECHClientHelloType::INNER
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it 'should be serialized' do
|
|
49
|
-
expect(extension.serialize)
|
|
50
|
-
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO \
|
|
51
|
-
+ 1.to_uint16 \
|
|
52
|
-
+ ECHClientHelloType::INNER \
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
context 'valid ECHEncryptedExtensions binary' do
|
|
57
|
-
let(:extension) do
|
|
58
|
-
ECHEncryptedExtensions.deserialize(TESTBINARY_ECH_EE)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it 'should generate valid object' do
|
|
62
|
-
expect(extension.extension_type)
|
|
63
|
-
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO
|
|
64
|
-
expect(extension.retry_configs.is_a?(Array)).to be_truthy
|
|
65
|
-
expect(extension.retry_configs.length).to eq 1
|
|
66
|
-
expect(extension.retry_configs.first.is_a?(ECHConfig)).to be_truthy
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
context 'valid ECHHelloRetryRequest binary' do
|
|
71
|
-
let(:extension) do
|
|
72
|
-
ECHHelloRetryRequest.deserialize(TESTBINARY_ECH_HRR)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it 'should generate valid object' do
|
|
76
|
-
expect(extension.extension_type)
|
|
77
|
-
.to eq ExtensionType::ENCRYPTED_CLIENT_HELLO
|
|
78
|
-
expect(extension.confirmation).to eq "\x00" * 8
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
RSpec.describe Ech do
|
|
84
|
-
context 'EncodedClientHelloInner length' do
|
|
85
|
-
let(:server_name) do
|
|
86
|
-
'localhost'
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
let(:client) do
|
|
90
|
-
Client.new(nil, server_name)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
let(:maximum_name_length) do
|
|
94
|
-
0
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
let(:encoded) do
|
|
98
|
-
extensions, = client.send(:gen_ch_extensions)
|
|
99
|
-
inner_ech = Message::Extension::ECHClientHello.new_inner
|
|
100
|
-
Message::ClientHello.new(
|
|
101
|
-
legacy_session_id: '',
|
|
102
|
-
cipher_suites: CipherSuites.new(DEFAULT_CH_CIPHER_SUITES),
|
|
103
|
-
extensions: extensions.merge(
|
|
104
|
-
Message::ExtensionType::ENCRYPTED_CLIENT_HELLO => inner_ech
|
|
105
|
-
)
|
|
106
|
-
)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
let(:padding_encoded_ch_inner) do
|
|
110
|
-
Ech.padding_encoded_ch_inner(
|
|
111
|
-
encoded.serialize[4..],
|
|
112
|
-
server_name.length,
|
|
113
|
-
maximum_name_length
|
|
114
|
-
)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
it 'should be equal placeholder_encoded_ch_inner_len' do
|
|
118
|
-
expect(Ech.placeholder_encoded_ch_inner_len)
|
|
119
|
-
.to eq padding_encoded_ch_inner.length
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
# encoding: ascii-8bit
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require_relative '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.appearable_extensions?).to be true
|
|
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.appearable_extensions?).to be false
|
|
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.appearable_extensions?).to be true
|
|
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.appearable_extensions?).to be true
|
|
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
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# encoding: ascii-8bit
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require_relative 'spec_helper'
|
|
5
|
-
using Refinements
|
|
6
|
-
|
|
7
|
-
RSpec.describe EndOfEarlyData do
|
|
8
|
-
context 'end_of_early_data' do
|
|
9
|
-
let(:message) do
|
|
10
|
-
EndOfEarlyData.new
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it 'should be serialized' do
|
|
14
|
-
expect(message.serialize).to eq HandshakeType::END_OF_EARLY_DATA \
|
|
15
|
-
+ ''.prefix_uint24_length
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
context 'valid end_of_early_data binary' do
|
|
20
|
-
let(:message) do
|
|
21
|
-
EndOfEarlyData.deserialize(TESTBINARY_0_RTT_END_OF_EARLY_DATA)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'should generate valid serializable object' do
|
|
25
|
-
expect(message.serialize).to eq TESTBINARY_0_RTT_END_OF_EARLY_DATA
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
data/spec/endpoint_spec.rb
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
# encoding: ascii-8bit
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require_relative 'spec_helper'
|
|
5
|
-
|
|
6
|
-
RSpec.describe Endpoint do
|
|
7
|
-
context 'endpoint, Simple 1-RTT Handshake,' do
|
|
8
|
-
let(:key) do
|
|
9
|
-
n = OpenSSL::BN.new(TESTBINARY_PKEY_MODULUS, 2)
|
|
10
|
-
e = OpenSSL::BN.new(TESTBINARY_PKEY_PUBLIC_EXPONENT, 2)
|
|
11
|
-
d = OpenSSL::BN.new(TESTBINARY_PKEY_PRIVATE_EXPONENT, 2)
|
|
12
|
-
p = OpenSSL::BN.new(TESTBINARY_PKEY_PRIME1, 2)
|
|
13
|
-
q = OpenSSL::BN.new(TESTBINARY_PKEY_PRIME2, 2)
|
|
14
|
-
dmp1 = d % (p - 1.to_bn)
|
|
15
|
-
dmq1 = d % (q - 1.to_bn)
|
|
16
|
-
iqmp = q**-1.to_bn % p
|
|
17
|
-
asn1 = OpenSSL::ASN1::Sequence(
|
|
18
|
-
[
|
|
19
|
-
OpenSSL::ASN1::Integer(0),
|
|
20
|
-
OpenSSL::ASN1::Integer(n),
|
|
21
|
-
OpenSSL::ASN1::Integer(e),
|
|
22
|
-
OpenSSL::ASN1::Integer(d),
|
|
23
|
-
OpenSSL::ASN1::Integer(p),
|
|
24
|
-
OpenSSL::ASN1::Integer(q),
|
|
25
|
-
OpenSSL::ASN1::Integer(dmp1),
|
|
26
|
-
OpenSSL::ASN1::Integer(dmq1),
|
|
27
|
-
OpenSSL::ASN1::Integer(iqmp)
|
|
28
|
-
]
|
|
29
|
-
)
|
|
30
|
-
OpenSSL::PKey::RSA.new(asn1)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
let(:ct) do
|
|
34
|
-
Certificate.deserialize(TESTBINARY_CERTIFICATE)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
let(:cv) do
|
|
38
|
-
CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
let(:cf) do
|
|
42
|
-
Finished.deserialize(TESTBINARY_CLIENT_FINISHED)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
let(:sf) do
|
|
46
|
-
Finished.deserialize(TESTBINARY_SERVER_FINISHED)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
let(:transcript) do
|
|
50
|
-
ch = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
|
|
51
|
-
sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
|
|
52
|
-
ee = EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS)
|
|
53
|
-
transcript = Transcript.new
|
|
54
|
-
transcript.merge!(
|
|
55
|
-
CH => [ch, TESTBINARY_CLIENT_HELLO],
|
|
56
|
-
SH => [sh, TESTBINARY_SERVER_HELLO],
|
|
57
|
-
EE => [ee, TESTBINARY_ENCRYPTED_EXTENSIONS],
|
|
58
|
-
CT => [ct, TESTBINARY_CERTIFICATE],
|
|
59
|
-
CV => [cv, TESTBINARY_CERTIFICATE_VERIFY],
|
|
60
|
-
CF => [cf, TESTBINARY_CLIENT_FINISHED],
|
|
61
|
-
SF => [sf, TESTBINARY_SERVER_FINISHED]
|
|
62
|
-
)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
let(:digest) do
|
|
66
|
-
CipherSuite.digest(CipherSuite::TLS_AES_128_GCM_SHA256)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it 'should verify server CertificateVerify.signature' do
|
|
70
|
-
public_key = ct.certificate_list.first.cert_data.public_key
|
|
71
|
-
signature_scheme = cv.signature_scheme
|
|
72
|
-
signature = cv.signature
|
|
73
|
-
|
|
74
|
-
expect(Endpoint.verified_certificate_verify?(
|
|
75
|
-
public_key:,
|
|
76
|
-
signature_scheme:,
|
|
77
|
-
signature:,
|
|
78
|
-
context: 'TLS 1.3, server CertificateVerify',
|
|
79
|
-
hash: transcript.hash(digest, CT)
|
|
80
|
-
)).to be true
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
it 'should sign client Finished.verify_data' do
|
|
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
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it 'should verify server Finished.verify_data' do
|
|
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
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
it 'should sign server CertificateVerify.signature' do
|
|
101
|
-
public_key = ct.certificate_list.first.cert_data.public_key
|
|
102
|
-
signature_scheme = cv.signature_scheme
|
|
103
|
-
|
|
104
|
-
# used RSASSA-PSS signature_scheme, salt is a random sequence.
|
|
105
|
-
# CertificateVerify.signature is random.
|
|
106
|
-
signature = Endpoint.sign_certificate_verify(
|
|
107
|
-
key:,
|
|
108
|
-
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:,
|
|
114
|
-
signature_scheme:,
|
|
115
|
-
signature:,
|
|
116
|
-
context: 'TLS 1.3, server CertificateVerify',
|
|
117
|
-
hash: transcript.hash(digest, CT)
|
|
118
|
-
)).to be true
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
context 'endpoint, HelloRetryRequest,' do
|
|
123
|
-
let(:ct) do
|
|
124
|
-
Certificate.deserialize(TESTBINARY_HRR_CERTIFICATE)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
let(:cv) do
|
|
128
|
-
CertificateVerify.deserialize(TESTBINARY_HRR_CERTIFICATE_VERIFY)
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
let(:transcript) do
|
|
132
|
-
ch1 = ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO1)
|
|
133
|
-
hrr = ServerHello.deserialize(TESTBINARY_HRR_HELLO_RETRY_REQUEST)
|
|
134
|
-
ch = ClientHello.deserialize(TESTBINARY_HRR_CLIENT_HELLO)
|
|
135
|
-
sh = ServerHello.deserialize(TESTBINARY_HRR_SERVER_HELLO)
|
|
136
|
-
ee = EncryptedExtensions.deserialize(TESTBINARY_HRR_ENCRYPTED_EXTENSIONS)
|
|
137
|
-
transcript = Transcript.new
|
|
138
|
-
transcript.merge!(
|
|
139
|
-
CH1 => [ch1, TESTBINARY_HRR_CLIENT_HELLO1],
|
|
140
|
-
HRR => [hrr, TESTBINARY_HRR_HELLO_RETRY_REQUEST],
|
|
141
|
-
CH => [ch, TESTBINARY_HRR_CLIENT_HELLO],
|
|
142
|
-
SH => [sh, TESTBINARY_HRR_SERVER_HELLO],
|
|
143
|
-
EE => [ee, TESTBINARY_HRR_ENCRYPTED_EXTENSIONS],
|
|
144
|
-
CT => [ct, TESTBINARY_HRR_CERTIFICATE],
|
|
145
|
-
CV => [cv, TESTBINARY_HRR_CERTIFICATE_VERIFY]
|
|
146
|
-
)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
let(:digest) do
|
|
150
|
-
CipherSuite.digest(CipherSuite::TLS_AES_128_GCM_SHA256)
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
it 'should verify server CertificateVerify.signature' do
|
|
154
|
-
public_key = ct.certificate_list.first.cert_data.public_key
|
|
155
|
-
signature_scheme = cv.signature_scheme
|
|
156
|
-
signature = cv.signature
|
|
157
|
-
|
|
158
|
-
expect(Endpoint.verified_certificate_verify?(
|
|
159
|
-
public_key:,
|
|
160
|
-
signature_scheme:,
|
|
161
|
-
signature:,
|
|
162
|
-
context: 'TLS 1.3, server CertificateVerify',
|
|
163
|
-
hash: transcript.hash(digest, CT)
|
|
164
|
-
)).to be true
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
end
|
data/spec/error_spec.rb
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# encoding: ascii-8bit
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require_relative '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
|
data/spec/extensions_spec.rb
DELETED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
# encoding: ascii-8bit
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require_relative 'spec_helper'
|
|
5
|
-
using Refinements
|
|
6
|
-
|
|
7
|
-
RSpec.describe Extensions do
|
|
8
|
-
context 'empty extensions' do
|
|
9
|
-
let(:extensions) do
|
|
10
|
-
Extensions.new
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it 'should be generated' do
|
|
14
|
-
expect(extensions).to be_empty
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it 'should be serialized' do
|
|
18
|
-
expect(extensions.serialize).to eq "\x00\x00"
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
let(:supported_versions) do
|
|
23
|
-
SupportedVersions.new(
|
|
24
|
-
msg_type: HandshakeType::CLIENT_HELLO,
|
|
25
|
-
versions: [ProtocolVersion::TLS_1_3]
|
|
26
|
-
)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
let(:signature_algorithms) do
|
|
30
|
-
SignatureAlgorithms.new([SignatureScheme::RSA_PSS_RSAE_SHA256])
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
let(:supported_groups) do
|
|
34
|
-
SupportedGroups.new([NamedGroup::SECP256R1])
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
let(:key_share) do
|
|
38
|
-
ec = OpenSSL::PKey::EC.generate('prime256v1')
|
|
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
|
-
|
|
171
|
-
context 'duplicated extension_type' do
|
|
172
|
-
let(:server_name) do
|
|
173
|
-
ServerName.new('example.com')
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
let(:testbinary) do
|
|
177
|
-
server_name.serialize * 2
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
it 'should raise error, if extension_type get duplicated' do
|
|
181
|
-
expect { Extensions.deserialize(testbinary, HandshakeType::CLIENT_HELLO) }
|
|
182
|
-
.to raise_error(ErrorAlerts)
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
context 'removing and replacing extensions from EncodedClientHelloInner' do
|
|
187
|
-
let(:extensions) do
|
|
188
|
-
extensions, = Client.new(nil, 'localhost').send(:gen_ch_extensions)
|
|
189
|
-
extensions
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
let(:no_key_share_exs) do
|
|
193
|
-
Extensions.new(
|
|
194
|
-
extensions.filter { |k, _| k != ExtensionType::KEY_SHARE }.values
|
|
195
|
-
)
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
it 'should be equal remove_and_replace! with []' do
|
|
199
|
-
expected = extensions.clone
|
|
200
|
-
got = extensions.remove_and_replace!([])
|
|
201
|
-
|
|
202
|
-
expect(got.keys).to eq expected.keys
|
|
203
|
-
expect(got[ExtensionType::ECH_OUTER_EXTENSIONS]).to eq nil
|
|
204
|
-
expect(extensions.keys - got.keys).to eq []
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
it 'should be equal remove_and_replace! with [key_share]' do
|
|
208
|
-
expected = extensions.filter { |k, _| k != ExtensionType::KEY_SHARE }
|
|
209
|
-
expected[ExtensionType::ECH_OUTER_EXTENSIONS] = \
|
|
210
|
-
Extension::ECHOuterExtensions.new([ExtensionType::KEY_SHARE])
|
|
211
|
-
got = extensions.remove_and_replace!([ExtensionType::KEY_SHARE])
|
|
212
|
-
|
|
213
|
-
expect(got.keys).to eq expected.keys
|
|
214
|
-
expect(got[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions)
|
|
215
|
-
.to eq expected[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions
|
|
216
|
-
expect(extensions.keys - got.keys)
|
|
217
|
-
.to eq expected[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
it 'should be equal remove_and_replace! with' \
|
|
221
|
-
' [key_share,supported_versions]' do
|
|
222
|
-
outer_extensions = [
|
|
223
|
-
ExtensionType::KEY_SHARE,
|
|
224
|
-
ExtensionType::SUPPORTED_VERSIONS
|
|
225
|
-
]
|
|
226
|
-
expected = extensions.filter { |k, _| !outer_extensions.include?(k) }
|
|
227
|
-
expected[ExtensionType::ECH_OUTER_EXTENSIONS] = \
|
|
228
|
-
Extension::ECHOuterExtensions.new(
|
|
229
|
-
extensions.filter { |k, _| outer_extensions.include?(k) }.keys
|
|
230
|
-
)
|
|
231
|
-
got = extensions.remove_and_replace!(outer_extensions)
|
|
232
|
-
|
|
233
|
-
expect(got.keys).to eq expected.keys
|
|
234
|
-
expect(got[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions)
|
|
235
|
-
.to eq expected[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions
|
|
236
|
-
expect(extensions.keys - got.keys)
|
|
237
|
-
.to eq expected[ExtensionType::ECH_OUTER_EXTENSIONS].outer_extensions
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
it 'should be equal remove_and_replace! with no key_share extensions' \
|
|
241
|
-
' & [key_share]' do
|
|
242
|
-
expected = no_key_share_exs.clone
|
|
243
|
-
got = no_key_share_exs.remove_and_replace!([ExtensionType::KEY_SHARE])
|
|
244
|
-
|
|
245
|
-
expect(got).to eq expected
|
|
246
|
-
expect(got[ExtensionType::ECH_OUTER_EXTENSIONS]).to eq nil
|
|
247
|
-
expect(no_key_share_exs.keys - got.keys).to eq []
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
|
-
end
|