tttls1.3 0.1.4 → 0.2.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/README.md +35 -13
  4. data/Rakefile +2 -4
  5. data/example/helper.rb +30 -7
  6. data/example/https_client.rb +3 -20
  7. data/example/https_client_using_0rtt.rb +10 -24
  8. data/example/https_client_using_hrr.rb +3 -20
  9. data/example/https_client_using_ticket.rb +3 -20
  10. data/example/https_server.rb +43 -0
  11. data/interop/client_spec.rb +111 -22
  12. data/interop/helper.rb +1 -0
  13. data/interop/server_spec.rb +182 -0
  14. data/lib/tttls1.3/client.rb +115 -98
  15. data/lib/tttls1.3/connection.rb +119 -32
  16. data/lib/tttls1.3/message/certificate.rb +18 -0
  17. data/lib/tttls1.3/message/client_hello.rb +38 -0
  18. data/lib/tttls1.3/message/encrypted_extensions.rb +20 -16
  19. data/lib/tttls1.3/message/extension/key_share.rb +24 -2
  20. data/lib/tttls1.3/message/extension/supported_groups.rb +0 -87
  21. data/lib/tttls1.3/message/extensions.rb +1 -27
  22. data/lib/tttls1.3/message/new_session_ticket.rb +14 -0
  23. data/lib/tttls1.3/message/record.rb +23 -20
  24. data/lib/tttls1.3/message/server_hello.rb +27 -0
  25. data/lib/tttls1.3/message.rb +35 -2
  26. data/lib/tttls1.3/named_group.rb +89 -0
  27. data/lib/tttls1.3/server.rb +439 -0
  28. data/lib/tttls1.3/transcript.rb +6 -0
  29. data/lib/tttls1.3/version.rb +1 -1
  30. data/lib/tttls1.3.rb +3 -0
  31. data/spec/certificate_spec.rb +28 -1
  32. data/spec/client_spec.rb +14 -10
  33. data/spec/connection_spec.rb +43 -13
  34. data/spec/encrypted_extensions_spec.rb +4 -4
  35. data/spec/fixtures/rsa_ca.crt +29 -0
  36. data/spec/fixtures/rsa_ca.key +51 -0
  37. data/spec/fixtures/rsa_rsa.crt +23 -0
  38. data/spec/fixtures/rsa_rsa.key +27 -0
  39. data/spec/fixtures/rsa_secp256r1.crt +19 -0
  40. data/spec/fixtures/rsa_secp256r1.key +5 -0
  41. data/spec/fixtures/rsa_secp384r1.crt +19 -0
  42. data/spec/fixtures/rsa_secp384r1.key +6 -0
  43. data/spec/fixtures/rsa_secp521r1.crt +20 -0
  44. data/spec/fixtures/rsa_secp521r1.key +7 -0
  45. data/spec/server_spec.rb +186 -0
  46. data/spec/spec_helper.rb +43 -0
  47. metadata +28 -2
@@ -7,7 +7,9 @@ using Refinements
7
7
  RSpec.describe Certificate do
8
8
  context 'valid certificate' do
9
9
  let(:certificate) do
10
- OpenSSL::X509::Certificate.new(File.read(__dir__ + '/../tmp/server.crt'))
10
+ OpenSSL::X509::Certificate.new(
11
+ File.read(__dir__ + '/fixtures/rsa_rsa.crt')
12
+ )
11
13
  end
12
14
 
13
15
  let(:message) do
@@ -52,4 +54,29 @@ RSpec.describe Certificate do
52
54
  expect(message.serialize).to eq TESTBINARY_CERTIFICATE
53
55
  end
54
56
  end
57
+
58
+ context 'invalid certificate, including forbidden extension type,' do
59
+ let(:certificate) do
60
+ OpenSSL::X509::Certificate.new(
61
+ File.read(__dir__ + '/fixtures/rsa_rsa.crt')
62
+ )
63
+ end
64
+
65
+ let(:server_name) do
66
+ ServerName.new('')
67
+ end
68
+
69
+ let(:message) do
70
+ Certificate.new(
71
+ certificate_list: [
72
+ CertificateEntry.new(certificate, Extensions.new([server_name]))
73
+ ]
74
+ )
75
+ end
76
+
77
+ it 'should be generated' do
78
+ expect(message.msg_type).to eq HandshakeType::CERTIFICATE
79
+ expect(message.only_appearable_extensions?).to be false
80
+ end
81
+ end
55
82
  end
data/spec/client_spec.rb CHANGED
@@ -9,7 +9,8 @@ RSpec.describe Client do
9
9
  let(:record) do
10
10
  mock_socket = SimpleStream.new
11
11
  client = Client.new(mock_socket, 'localhost')
12
- client.send(:send_client_hello)
12
+ exs, _priv_keys = client.send(:gen_ch_extensions)
13
+ client.send(:send_client_hello, exs)
13
14
  Record.deserialize(mock_socket.read, Cryptograph::Passer.new)
14
15
  end
15
16
 
@@ -19,7 +20,10 @@ RSpec.describe Client do
19
20
  message = record.messages.first
20
21
  expect(message.msg_type).to eq HandshakeType::CLIENT_HELLO
21
22
  expect(message.legacy_version).to eq ProtocolVersion::TLS_1_2
22
- expect(message.cipher_suites).to eq DEFAULT_CH_CIPHER_SUITES
23
+ expect(message.cipher_suites)
24
+ .to eq [CipherSuite::TLS_AES_256_GCM_SHA384,
25
+ CipherSuite::TLS_CHACHA20_POLY1305_SHA256,
26
+ CipherSuite::TLS_AES_128_GCM_SHA256]
23
27
  expect(message.legacy_compression_methods).to eq ["\x00"]
24
28
  end
25
29
  end
@@ -165,11 +169,11 @@ RSpec.describe Client do
165
169
  end
166
170
 
167
171
  it 'should verify server CertificateVerify' do
168
- expect(client.send(:verify_certificate_verify)).to be true
172
+ expect(client.send(:verified_certificate_verify?)).to be true
169
173
  end
170
174
 
171
175
  it 'should verify server Finished' do
172
- expect(client.send(:verify_finished)).to be true
176
+ expect(client.send(:verified_finished?)).to be true
173
177
  end
174
178
 
175
179
  it 'should sign client Finished' do
@@ -219,7 +223,7 @@ RSpec.describe Client do
219
223
  client = Client.new(mock_socket, 'localhost')
220
224
  sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
221
225
  random = OpenSSL::Random.random_bytes(24) + \
222
- Client::DOWNGRADE_PROTECTION_TLS_1_2
226
+ Client.const_get(:DOWNGRADE_PROTECTION_TLS_1_2)
223
227
  sh.instance_variable_set(:@random, random)
224
228
  transcript = {
225
229
  CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
@@ -242,7 +246,7 @@ RSpec.describe Client do
242
246
  client = Client.new(mock_socket, 'localhost')
243
247
  sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
244
248
  random = OpenSSL::Random.random_bytes(24) + \
245
- Client::DOWNGRADE_PROTECTION_TLS_1_1
249
+ Client.const_get(:DOWNGRADE_PROTECTION_TLS_1_1)
246
250
  sh.instance_variable_set(:@random, random)
247
251
  transcript = {
248
252
  CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
@@ -283,7 +287,7 @@ RSpec.describe Client do
283
287
  context 'client, received Certificate signed by private CA,' do
284
288
  let(:certificate) do
285
289
  server_crt = OpenSSL::X509::Certificate.new(
286
- File.read(__dir__ + '/../tmp/server.crt')
290
+ File.read(__dir__ + '/fixtures/rsa_rsa.crt')
287
291
  )
288
292
  Certificate.new(certificate_list: [CertificateEntry.new(server_crt)])
289
293
  end
@@ -293,13 +297,13 @@ RSpec.describe Client do
293
297
  end
294
298
 
295
299
  it 'should not certify certificate' do
296
- expect(client.send(:certified_certificate?, certificate.certificate_list))
300
+ expect(client.send(:trusted_certificate?, certificate.certificate_list))
297
301
  .to be false
298
302
  end
299
303
 
300
304
  it 'should certify certificate, received path to private ca.crt' do
301
- expect(client.send(:certified_certificate?, certificate.certificate_list,
302
- __dir__ + '/../tmp/ca.crt')).to be true
305
+ expect(client.send(:trusted_certificate?, certificate.certificate_list,
306
+ __dir__ + '/fixtures/rsa_ca.crt')).to be true
303
307
  end
304
308
  end
305
309
 
@@ -5,6 +5,16 @@ require_relative 'spec_helper'
5
5
 
6
6
  RSpec.describe Connection do
7
7
  context 'connection, Simple 1-RTT Handshake,' do
8
+ let(:private_key) do
9
+ rsa = OpenSSL::PKey::RSA.new
10
+ rsa.set_key(OpenSSL::BN.new(TESTBINARY_PKEY_MODULUS, 2),
11
+ OpenSSL::BN.new(TESTBINARY_PKEY_PUBLIC_EXPONENT, 2),
12
+ OpenSSL::BN.new(TESTBINARY_PKEY_PRIVATE_EXPONENT, 2))
13
+ rsa.set_factors(OpenSSL::BN.new(TESTBINARY_PKEY_PRIME1, 2),
14
+ OpenSSL::BN.new(TESTBINARY_PKEY_PRIME2, 2))
15
+ rsa
16
+ end
17
+
8
18
  let(:ct) do
9
19
  Certificate.deserialize(TESTBINARY_CERTIFICATE)
10
20
  end
@@ -40,11 +50,11 @@ RSpec.describe Connection do
40
50
  end
41
51
 
42
52
  it 'should verify server CertificateVerify.signature' do
43
- certificate_pem = ct.certificate_list.first.cert_data.to_pem
53
+ public_key = ct.certificate_list.first.cert_data.public_key
44
54
  signature_scheme = cv.signature_scheme
45
55
  signature = cv.signature
46
- expect(connection.send(:do_verify_certificate_verify,
47
- certificate_pem: certificate_pem,
56
+ expect(connection.send(:do_verified_certificate_verify?,
57
+ public_key: public_key,
48
58
  signature_scheme: signature_scheme,
49
59
  signature: signature,
50
60
  context: 'TLS 1.3, server CertificateVerify',
@@ -52,8 +62,16 @@ RSpec.describe Connection do
52
62
  .to be true
53
63
  end
54
64
 
65
+ it 'should sign client Finished.verify_data' do
66
+ expect(connection.send(:do_sign_finished,
67
+ digest: 'SHA256',
68
+ finished_key: TESTBINARY_CLIENT_FINISHED_KEY,
69
+ handshake_context_end: EOED))
70
+ .to eq cf.verify_data
71
+ end
72
+
55
73
  it 'should verify server Finished.verify_data' do
56
- expect(connection.send(:do_verify_finished,
74
+ expect(connection.send(:do_verified_finished?,
57
75
  digest: 'SHA256',
58
76
  finished_key: TESTBINARY_SERVER_FINISHED_KEY,
59
77
  handshake_context_end: CV,
@@ -61,12 +79,24 @@ RSpec.describe Connection do
61
79
  .to be true
62
80
  end
63
81
 
64
- it 'should sign client Finished.verify_data' do
65
- expect(connection.send(:do_sign_finished,
66
- digest: 'SHA256',
67
- finished_key: TESTBINARY_CLIENT_FINISHED_KEY,
68
- handshake_context_end: EOED))
69
- .to eq cf.verify_data
82
+ it 'should sign server CertificateVerify.signature' do
83
+ public_key = ct.certificate_list.first.cert_data.public_key
84
+ signature_scheme = cv.signature_scheme
85
+
86
+ # used RSASSA-PSS signature_scheme, salt is a random sequence.
87
+ # CertificateVerify.signature is random.
88
+ signature = connection.send(:do_sign_certificate_verify,
89
+ private_key: private_key,
90
+ signature_scheme: signature_scheme,
91
+ context: 'TLS 1.3, server CertificateVerify',
92
+ handshake_context_end: CT)
93
+ expect(connection.send(:do_verified_certificate_verify?,
94
+ public_key: public_key,
95
+ signature_scheme: signature_scheme,
96
+ signature: signature,
97
+ context: 'TLS 1.3, server CertificateVerify',
98
+ handshake_context_end: CT))
99
+ .to be true
70
100
  end
71
101
  end
72
102
 
@@ -99,11 +129,11 @@ RSpec.describe Connection do
99
129
  end
100
130
 
101
131
  it 'should verify server CertificateVerify.signature' do
102
- certificate_pem = ct.certificate_list.first.cert_data.to_pem
132
+ public_key = ct.certificate_list.first.cert_data.public_key
103
133
  signature_scheme = cv.signature_scheme
104
134
  signature = cv.signature
105
- expect(connection.send(:do_verify_certificate_verify,
106
- certificate_pem: certificate_pem,
135
+ expect(connection.send(:do_verified_certificate_verify?,
136
+ public_key: public_key,
107
137
  signature_scheme: signature_scheme,
108
138
  signature: signature,
109
139
  context: 'TLS 1.3, server CertificateVerify',
@@ -31,7 +31,7 @@ RSpec.describe EncryptedExtensions do
31
31
  it 'should be generated' do
32
32
  expect(message.msg_type).to eq HandshakeType::ENCRYPTED_EXTENSIONS
33
33
  expect(message.extensions).to eq extensions
34
- expect(message.any_forbidden_extensions?).to be false
34
+ expect(message.only_appearable_extensions?).to be true
35
35
  end
36
36
 
37
37
  it 'should be serialized' do
@@ -55,7 +55,7 @@ RSpec.describe EncryptedExtensions do
55
55
  it 'should be generated' do
56
56
  expect(message.msg_type).to eq HandshakeType::ENCRYPTED_EXTENSIONS
57
57
  expect(message.extensions).to eq extensions
58
- expect(message.any_forbidden_extensions?).to be true
58
+ expect(message.only_appearable_extensions?).to be false
59
59
  end
60
60
  end
61
61
 
@@ -67,7 +67,7 @@ RSpec.describe EncryptedExtensions do
67
67
  it 'should be generated' do
68
68
  expect(message.msg_type).to eq HandshakeType::ENCRYPTED_EXTENSIONS
69
69
  expect(message.extensions).to eq Extensions.new
70
- expect(message.any_forbidden_extensions?).to be false
70
+ expect(message.only_appearable_extensions?).to be true
71
71
  end
72
72
 
73
73
  it 'should be serialized' do
@@ -84,7 +84,7 @@ RSpec.describe EncryptedExtensions do
84
84
 
85
85
  it 'should generate valid object' do
86
86
  expect(message.msg_type).to eq HandshakeType::ENCRYPTED_EXTENSIONS
87
- expect(message.any_forbidden_extensions?).to be false
87
+ expect(message.only_appearable_extensions?).to be true
88
88
  end
89
89
 
90
90
  it 'should generate valid serializable object' do
@@ -0,0 +1,29 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIE4TCCAsmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAd0ZXN0
3
+ LWNhMB4XDTE5MDUyMTE0MTAyM1oXDTI5MDUxODE0MTAyM1owEjEQMA4GA1UEAwwH
4
+ dGVzdC1jYTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALhDr6JVtpPi
5
+ FfRy/1WCfwEEHy1zKDXkrjSUYICdXP2WhaHBfL0k2sk4q2uRxEJl+st7SkGPl307
6
+ rFsrVLsWlRumVB7RuQ1ayvRdWTiOaEqRWtsW6f2IxKrv89Trh89gezpenbZ9RyIx
7
+ Kr2CMBEHLjxI3ON0x7ok18c/8eIVJzIjSo7cuCiVaSTlMS6Hj+XGtAzjLgKRojeR
8
+ meeuRzXatqZ6NGqjyB0u+Fg2Erijm4n5IIQyZrIyuIkMYak4pXZQ/9KMOsAoLHFc
9
+ OBKakkLFpRvaYWTg1zilGz7fdJrFHl9B5SKYstXYnjjyXEw91lYKxSO1MgZjqyJ8
10
+ G4GX8Lj0vSpCV10zRMPDvuuIUW3G/lyY6dZYWROuUGfRD0ithL6yVnjkFKdJ9YkM
11
+ pc/fN1llDEjcvxDY0yfPVRVIJtQ4Xy0txZG2G8Nke9rD1m7+wAegdrgiSP9NlbkR
12
+ /ALbw2GrUWVtR86HkrzADDvVsg5vSbSRf2pfgJTr37tl25QJ5EfHk9i2H2v0wcQ8
13
+ 6DN7gYtd45jD9N4rqfRgG4qfQ4wIGkSSRBZfE9CBRYwrL6frUga6QZgYkaxMcdQG
14
+ PVttF5WQwcR4blsqZ6n14dCjJkNWJ56qsq+bzf4WENB9SAZpKHv4rekfRUw7ZVBB
15
+ Secoisg/rbIkWFlnpSwyBWUhdGJ3C6mHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB
16
+ BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5rnZ4ZxbSKb4Py7wA+/a9zCbj
17
+ RDANBgkqhkiG9w0BAQsFAAOCAgEAbVYmzqfBrgl1CsAnTEKQW4WQGuPhrzWuAYm3
18
+ joVNDRzC3pkfHzt5/1hSJsqf9GA3HH+bDdStm0IB82SgycvSccqoEN1in8jwC3pi
19
+ LJSfqXf5qVonJtotfr4lkr9ay/wbsqsnEYQtkLafhT+n4/2cu72V6OJJBKldlqGz
20
+ Iugwx+3Dv8ZidtX7VQWkd0tyioxcTYaXQ3QvQZZXQ+wbuNOvTIlbmhZasR3jhSN0
21
+ ytEFS9qWZ5MS95jO1FWdStCvHA5abi5JRW7sGHkkkNXcFB0jgCLbmQlHIXgM3/sF
22
+ 3SJQPCil0wNE1wWWemD5BikAIN7F+WN1uAQ21AA8QXlpjDCKj+XAZDmTvS6Ttub6
23
+ BUqsxaEmz6A8mkqeL55FDEsQ8KpLHcAa9/RviuGequqiV4mJdP92oebGLaTeOJxD
24
+ rxxZjPXFrBkZ5UXjwdFdkNaIgRe7hza1N5SljyxzkXwG5iwA/4/4qoP0kkyC+ReR
25
+ 16y0t1papARFR47VPn5IAS9WRHNg7jklBkN1kwFyQR88/hi3zNPKOd4x6EN6HeC7
26
+ 8ggPXFKNShSkNz7RF/OxG4kEPaHva/U+tdZzid3/LlXYh6+eIgswFSLPMTAusPcu
27
+ Lx9N5nEmeIwTqrZGn0jCodsM7fYmqU4nmuEIUHjPTp+D1Vt0+c8ZxRy34N9mQRyE
28
+ PcAi66U=
29
+ -----END CERTIFICATE-----
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,23 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIID0TCCAbmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAd0ZXN0
3
+ LWNhMB4XDTE5MDUyMTE0MTAyM1oXDTI5MDUxODE0MTAyM1owFDESMBAGA1UEAwwJ
4
+ bG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy21id1l6
5
+ qLzJ+f6GdBhFeJWZ2w2AQaWCVzUHnBbfd1myPpGRMoHZfpESaI6TIrj6uIWAFDOj
6
+ EWTvmbfbxGZyElXvqRO6dipb5KBQGMHB+lgR53YxQp6D3DI7e58/YqKKnc2iwEaK
7
+ f7ax75lJZIyWJXimw1Gi/kUr60POdsRH6DmTzcW1cui6FMnBRHXkeOwudzTKJAOl
8
+ Zs4y9LuqkQbBN/mrgkraBu7XxmOhgWb+ejflzh98tLiCuNct/LIOPSwrVWDD1yE6
9
+ uOnEYo0zXaAN5TgJZLEvlfr3nZ/zDg2ifv9IJJoEdF9xwwFGFt2vAsCcP8NPDYFJ
10
+ QOUkEFPhHIfLgQIDAQABozAwLjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDAUBgNV
11
+ HREEDTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggIBAH8eKO0uRCh3GjDT
12
+ SsVBC6KIkqGibW1vdSzSIm/mMfRzhc0L5FD8vv4+gqeUD0hQr461oE8syTy/MnMY
13
+ cnj6W6G45pitF3PQUPxIUsAU0u/OcVkZpEy8B+uozm4Zem7KpRD7N18YUwJLT4Dd
14
+ FHeOCHu41aKxIcu/nFmklYRFp4v9WPOZiIktgMtub7RAYkb0+SXY3pNyPsUK0NL8
15
+ 70yI0WaA5b2cxw0R3KUdwwyjuDctq+VYuLgAzeoWNmbhDBA2pIwsgndnUD9n0VWf
16
+ JMYHNInyOiwkMTSVc0OI5nsYNs3sTX++rIIgsd0kA4T4hcfnx0fqiZCjUYRomXIR
17
+ jDKOpDs8JVMFEiUS+uKAwHfEjBRM6IvrvhB+s1wNDyw1OafKATUmINRheKFMRg9s
18
+ 02Ihr2eYAIfYtwADV3NvjEReBBJOg0VHyG1lUQyhji0EQIsZB2qaeExxAmPHxLvn
19
+ Au8qhHz8tKGQAsCzq41EAIJHOEXoP2+WzH/tOio7G7Pv3vrCpi/ALpkBbL7FL4l2
20
+ FfDzYGTibmOsKkeDf+h58uVOYSEDJLsWcr+dkAtZNxE2X8PCYs0G3S07QBEldcjO
21
+ a0S65vIALLJFGnLJw6bJd2xLNH1xRkMQK4n0UvzPP7Q8b1c7w+XsYs9WG1s2R8Lo
22
+ GcVsYp2SnqonWcM6V2pXcKCIFY3K
23
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEogIBAAKCAQEAy21id1l6qLzJ+f6GdBhFeJWZ2w2AQaWCVzUHnBbfd1myPpGR
3
+ MoHZfpESaI6TIrj6uIWAFDOjEWTvmbfbxGZyElXvqRO6dipb5KBQGMHB+lgR53Yx
4
+ Qp6D3DI7e58/YqKKnc2iwEaKf7ax75lJZIyWJXimw1Gi/kUr60POdsRH6DmTzcW1
5
+ cui6FMnBRHXkeOwudzTKJAOlZs4y9LuqkQbBN/mrgkraBu7XxmOhgWb+ejflzh98
6
+ tLiCuNct/LIOPSwrVWDD1yE6uOnEYo0zXaAN5TgJZLEvlfr3nZ/zDg2ifv9IJJoE
7
+ dF9xwwFGFt2vAsCcP8NPDYFJQOUkEFPhHIfLgQIDAQABAoIBACPC4fl7OG3ralJR
8
+ ZU+JaMUO/5IbqH1h3Cz6fJD7EGPJ1+TZ8D2ByDtQw3yv+7ux6xl/Fon2necT6G8M
9
+ fEzleY4xn0UI29GkFq11ZT9E6JXa36LiCzzb4vBVwFE2KI1tZ5LgMIk+nWBgPJ2T
10
+ Q+yyLj7+G8rgUhgDDvp33BbS4JU5IVQptwdC198e0/ISwSKt04XCQ0zyq7rEvwNj
11
+ 0DV+rTPnpvpiguNvqva31BFZOmFD0DyIkacX/SXdpVv1I8RDduF2c5aLyAQMcIVR
12
+ 8AM2dXV6kuJHW0IugTw8ljea9ph0m3TGQrrT5dbIb1qWSwSGFIwMiRk9qaA5XXc3
13
+ SdXdK8ECgYEA/L87aFb+i5EjB+uC/W9rEUc3jM6mu6AjxqLdYtZYCaMTc60z0OdA
14
+ aU37sGf9pClSYB0zhrYQl4IzLcKbzb9ULy41H38NwVgi1h2AwPzHAoDdMou326DJ
15
+ zwgYmRHAr8MG8cup2z6Ymn4K479RX9N2Si1H6yywJ1GHdJ/oUPtmqlkCgYEAzgum
16
+ j6jLVkRlkpjzL8yIYCV72XiEHfCEp0oYVBldnqjmmTNtLXoxyfy11CRtHTMBh+fJ
17
+ tx5qrJ9CI0FAw/XIoKbGNIgV/qi9DWIrU1r+ULLQYGT6icNsf+pkWC5yoRwc3pJR
18
+ NUBiUt2hydf3jaC5BUD3CvUhryASst7Q6JtztWkCgYBmSZJmYMa1fzB5NRQXMy9W
19
+ l8bggoWx61ZvPlxwcqTAibIGn7MXuW807u2McBmThXGkGk1PGIHQf03tGBRsCSGt
20
+ 0nqHW6kadWvr0ZbZA7QazEI5AZiQFxt1YSZrVGbx+vDljHIam9Owuo/3qebp7C+0
21
+ R20SvUwxLWqvhUPE+mmLSQKBgG51tH+DoC7JUCK9OHJBlkLlFXZKs5lRXexJPq2n
22
+ Q5dROP6coUUmIxcEEX5/YLespn9zdaJj/hA4+L3pt4zWcQ4fGlcDNbdmQqOwI0X2
23
+ nCwrEKb8u4urZrlUsSLNE8rnRVrU2hBQSeXex2NsElys80OrxkTrkXlPGncmGJz6
24
+ 6ZcxAoGAbFH7tKXJyNRXYdW7hcElCVSsFS3gaSwoBXIvXNOVlYEx2T1TpRE4HESc
25
+ a7PvXYr0UvkwHFk1Af0AX++/MlTWUWbftufMOcB55hI7Kf7OId+NTTtufY2sRTVt
26
+ RKLyfV7mPPmJS4HqksGvueiX4rfl4N4/WRVVWyEgIyrXkYgMmQQ=
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDBTCB7qADAgECAgEDMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB3Rlc3Qt
3
+ Y2EwHhcNMTkwNTIxMjEzMTI0WhcNMjkwNTE4MjEzMTI0WjAUMRIwEAYDVQQDDAls
4
+ b2NhbGhvc3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASCnjcLbROI51SD5Cqv
5
+ k7vK5NqfuQY5jJEX9Zvhw0XBQfnpxkUkauFFF7YhWcKkCeMD7iOavg7SdbI8ZsfH
6
+ hc1UozAwLjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIChDAUBgNVHREEDTALgglsb2Nh
7
+ bGhvc3QwDQYJKoZIhvcNAQELBQADggIBAAAMIex6Q3Quh+ZeO1LeZKPPHrG1rp2C
8
+ l9/YzeBfwPR7q8bS0g3TW9XJXsVPrgeQZU6WbsUin4B9ELSKEhpgDCPsAwXO5wIj
9
+ a+J0NdB3rX4Dfx/i7Q+EH2fR2Ap7jp0w2xnS0J1dodxTHUip+/lSKMbe4M1Xl2ZC
10
+ 6niubXkNTrOH6nOJc46zF5IIEvSnQNRac2fuDNWQJQTN7ZVCgremx33VIcjp7HU5
11
+ AEATvhEgV+wmmuG1ZH2PjlXkZSCMqUsdjtwwrtUOIfqm3AilrMP03XYwgHBhBuo/
12
+ tzso80ZM5tdE2uBRdh8gUD7pZq+qt3uC1kHnOBq2LSrwBZCiD2v1v6eQxZACYSTR
13
+ TYpDpknT6wwrRXfR2c23hwNgLVd+jZqaxB7NkuDNBACzpwPuYYtR5Au+LIQc2tSi
14
+ dXbXXo/vlGsh5tGfg7mP3kmtgu7oXBPJwRUWmwPAqXTaqCUuCNpyiHzeKXNXB2ci
15
+ gh1ss/dODO/wmJJI8GjsK/2iZ9Nsc26OwCQ98LWkfvQIePP6vP12AOfzsHO74zxA
16
+ 4rjUHpuENDp4HKrkxJ5B8O0xypychNrbe70PRV4bbyuqisMWm2kRRjIkkF83BCv4
17
+ Up4rq2UgtC9kJQLufkrNfAaRnKGAf4Uox86Hwz9yBV486+SRTuUu2aJxZUFgnlRR
18
+ dcfCc/o8347y
19
+ -----END CERTIFICATE-----
@@ -0,0 +1,5 @@
1
+ -----BEGIN EC PRIVATE KEY-----
2
+ MHcCAQEEIJed2ge/IS5cymZrs2yT94388aTvdzYj0A49VVCl3E2YoAoGCCqGSM49
3
+ AwEHoUQDQgAEgp43C20TiOdUg+Qqr5O7yuTan7kGOYyRF/Wb4cNFwUH56cZFJGrh
4
+ RRe2IVnCpAnjA+4jmr4O0nWyPGbHx4XNVA==
5
+ -----END EC PRIVATE KEY-----
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDIzCCAQugAwIBAgIBBDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAd0ZXN0
3
+ LWNhMB4XDTE5MDUyMTIxMzE0MloXDTI5MDUxODIxMzE0MlowFDESMBAGA1UEAwwJ
4
+ bG9jYWxob3N0MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3fbzFYYAPdEIi8wNtYfl
5
+ cjl5C5ewTn9fxP4O4Nzn47Hp0YRYC8E5z/bC4FHyKAAVO9axNSeEbtRAHkIMvzve
6
+ WlWB3Em5UxTmxNBcKwt1uY0HqIeQEO8fIjeYxrTslrfMozAwLjAJBgNVHRMEAjAA
7
+ MAsGA1UdDwQEAwIChDAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQEL
8
+ BQADggIBAJpz6zp4yCxAHho+rurIrj5JklOcRS44r4XGtBsHMkP7NwnX3xfSdqdx
9
+ aePkH29DuPd8N849lhu5FXBraHU7xzj6PVp0WZ5krCaShDEMm/CLro5U1imqCRpN
10
+ g/xNfWYi+hGFeknYJFwGyWIHRcnTL+QKrtmPuXkK3Q19WJvh960kqQ3DMBYGhlUL
11
+ 5E1bCKiAIiW+PP++AwQK5bzSKVTNB2tW7heznhU9lv3OOC3MuG/T48hbVaSSHV0X
12
+ NNFo3U1pwvMg4/AHgvVvyT2HSuEtPgnSAC9FZ9YFprFfSk+evZoFPBQ/8BXamB2h
13
+ t/MjpQGIo712plAbMyk+0rrAiAKey1P9AM6RkVHIeGETDu5lLCUDS9t6/mlAOtrt
14
+ t4z5WOxqpXPLEJSLwuAIchDSHktUirBeALGkG8+ro7uwURRyrCYTNuD8lVM8Gwib
15
+ 9mlsuzUs8ZDPrUX4BXnGgv2fIC+yWAlur9lSQtwcWkGkWki1d4QdjwPjV9WZ+87D
16
+ LiUSsMShWS5g1npyEuIje4SvsGN5RQWAk/sBG1i9EoGIWiUzwLlNR10UAmW9uuav
17
+ wkSstdu3OwRkR7wi70wN2pC7/IT6/Wow2mfRs3OhCCeg0739GzyVYCiL/geWiFri
18
+ nUMBYoULATkQeCw6iXyQR2697AISn3pUW1DXBfuTRaOOn7xyE2oQ
19
+ -----END CERTIFICATE-----
@@ -0,0 +1,6 @@
1
+ -----BEGIN EC PRIVATE KEY-----
2
+ MIGkAgEBBDAqi/qJgcuxcTF8cNJvK+kNRvm4xnB0WFYETI3ZVFQbX1g46S40honE
3
+ Vj+KoGtuN32gBwYFK4EEACKhZANiAATd9vMVhgA90QiLzA21h+VyOXkLl7BOf1/E
4
+ /g7g3OfjsenRhFgLwTnP9sLgUfIoABU71rE1J4Ru1EAeQgy/O95aVYHcSblTFObE
5
+ 0FwrC3W5jQeoh5AQ7x8iN5jGtOyWt8w=
6
+ -----END EC PRIVATE KEY-----
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDSTCCATGgAwIBAgIBBTANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAd0ZXN0
3
+ LWNhMB4XDTE5MDUyMTIxMzIwMFoXDTI5MDUxODIxMzIwMFowFDESMBAGA1UEAwwJ
4
+ bG9jYWxob3N0MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAjVT+nUIx3UB2eR9e
5
+ sjC3+oloaJARVlcjJc2f/JzvOsitJbK2/EdVyvLxt3V485p7Ljh8My/lcN2ZU9/s
6
+ 6VOTfd0BWxmXsP7PfSig2sE1ELJcCdtAJlv8vrP4OW8BQInERfJ3Nf5WZIrahYVL
7
+ PtAqvfkCnvVXuufeqFu3J1Yy9T/weo6jMDAuMAkGA1UdEwQCMAAwCwYDVR0PBAQD
8
+ AgKEMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAgEAjhUX
9
+ 3YHkYs+FXZryP2iJ18QCKLUl5q3/kOOSbRyjPQTFWJa1AyyudFyLGi4JUK/0fRIm
10
+ hq0Ns9h6yglVk0R7/X/rlbhF3c2kOl2ekhaJeo8RRHyuH1w49kTfXJYtNmTp+ZMB
11
+ bQwAXlmmFOTArdf4j4nbVqB3fYIyGTWll7190eUu5c9gS6FYNnVniIQhTFINh5ZK
12
+ pxW9w5CnUpVdRsCj1I/aFWGhDwCQap5ZDTD09HaV4xFuvnCWobSOaKfox2hmdwZk
13
+ JvsGWpGwTIO9kitF1L9tc9mzJr6cc/64wIwMPkYrM68kUcZn/FBxN4SEZJ1Y6yFI
14
+ wufeFP1rzVlD/9PZMDVN0Cpz1elmgo2kJSx+TxqF2LnymFfKxj4uo/aodU7MoQ5a
15
+ 6RRTxIC6SQmDLpwka7L30qvzLzB0u1FzdZPvxwH3+7eJOB9O231B+K+d+lN7uMaz
16
+ DsDIOa/3rLCHIZW2q48n0Bkm5HT1ZtroHI9xQMvTF8oSFUUB5tqE+owwRN/fWuyd
17
+ 3GiNp8y3WpKRXvCDqaJ8BiQxjXBjrtMbBLC73lIuQqMQiPzAeeEFOIlvwQ2qKi/M
18
+ pu88pahnI5th752GPv64zJsOQppe2wUuycMHgIIWX6RCgXbUod8rZOmeoYnkkjNZ
19
+ rY8omp53evRvLdPE2uTEnv3y4NiEGI36Pqny30o=
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,7 @@
1
+ -----BEGIN EC PRIVATE KEY-----
2
+ MIHcAgEBBEIBBJjLo07KrpdNcQAg2fEyPciF6nTVIhM3vbHH9t/ym+B9Q2nD0g+u
3
+ NZIL0S6x0xLdxhT94MMa961PbtD2OSuPpVegBwYFK4EEACOhgYkDgYYABACNVP6d
4
+ QjHdQHZ5H16yMLf6iWhokBFWVyMlzZ/8nO86yK0lsrb8R1XK8vG3dXjzmnsuOHwz
5
+ L+Vw3ZlT3+zpU5N93QFbGZew/s99KKDawTUQslwJ20AmW/y+s/g5bwFAicRF8nc1
6
+ /lZkitqFhUs+0Cq9+QKe9Ve6596oW7cnVjL1P/B6jg==
7
+ -----END EC PRIVATE KEY-----
@@ -0,0 +1,186 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe Server do
8
+ context 'server' do
9
+ let(:message) do
10
+ msg_len = TESTBINARY_CLIENT_HELLO.length
11
+ mock_socket = SimpleStream.new
12
+ mock_socket.write(ContentType::HANDSHAKE \
13
+ + ProtocolVersion::TLS_1_2 \
14
+ + msg_len.to_uint16 \
15
+ + TESTBINARY_CLIENT_HELLO)
16
+ server = Server.new(mock_socket)
17
+ server.send(:recv_client_hello)
18
+ end
19
+
20
+ it 'should receive ClientHello' do
21
+ expect(message.msg_type).to eq HandshakeType::CLIENT_HELLO
22
+ expect(message.legacy_version).to eq ProtocolVersion::TLS_1_2
23
+ expect(message.legacy_compression_methods).to eq ["\x00"]
24
+ end
25
+ end
26
+
27
+ context 'server' do
28
+ let(:crt) do
29
+ OpenSSL::X509::Certificate.new(
30
+ File.read(__dir__ + '/fixtures/rsa_rsa.crt')
31
+ )
32
+ end
33
+
34
+ let(:record) do
35
+ mock_socket = SimpleStream.new
36
+ server = Server.new(mock_socket)
37
+ server.instance_variable_set(:@crt, crt)
38
+ transcript = Transcript.new
39
+ transcript[CH] = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
40
+ server.instance_variable_set(:@transcript, transcript)
41
+ cipher_suite = server.send(:select_cipher_suite)
42
+ server.instance_variable_set(:@cipher_suite, cipher_suite)
43
+ named_group = server.send(:select_named_group)
44
+ server.instance_variable_set(:@named_group, named_group)
45
+ signature_scheme = server.send(:select_signature_scheme)
46
+ server.instance_variable_set(:@signature_scheme, signature_scheme)
47
+ exs, _priv_key = server.send(:gen_sh_extensions)
48
+ server.send(:send_server_hello, exs)
49
+ Record.deserialize(mock_socket.read, Cryptograph::Passer.new)
50
+ end
51
+
52
+ it 'should send ServerHello' do
53
+ expect(record.type).to eq ContentType::HANDSHAKE
54
+
55
+ message = record.messages.first
56
+ expect(message.msg_type).to eq HandshakeType::SERVER_HELLO
57
+ expect(message.legacy_version).to eq ProtocolVersion::TLS_1_2
58
+ expect(message.legacy_compression_method).to eq "\x00"
59
+ end
60
+ end
61
+
62
+ context 'server' do
63
+ let(:server) do
64
+ server = Server.new(nil)
65
+ transcript = Transcript.new
66
+ transcript[CH] = ClientHello.deserialize(TESTBINARY_CLIENT_HELLO)
67
+ server.instance_variable_set(:@transcript, transcript)
68
+ server
69
+ end
70
+
71
+ it 'should generate EncryptedExtensions' do
72
+ ee = server.send(:gen_encrypted_extensions)
73
+ expect(ee).to be_a_kind_of(EncryptedExtensions)
74
+ expect(ee.extensions).to include(ExtensionType::SERVER_NAME)
75
+ expect(ee.extensions[ExtensionType::SERVER_NAME].server_name).to eq ''
76
+ expect(ee.extensions).to include(ExtensionType::SUPPORTED_GROUPS)
77
+ expect(ee.extensions[ExtensionType::SUPPORTED_GROUPS].named_group_list)
78
+ .to eq [NamedGroup::SECP256R1,
79
+ NamedGroup::SECP384R1,
80
+ NamedGroup::SECP521R1]
81
+ end
82
+ end
83
+
84
+ context 'server' do
85
+ let(:server) do
86
+ server = Server.new(nil)
87
+ crt = OpenSSL::X509::Certificate.new(
88
+ File.read(__dir__ + '/fixtures/rsa_rsa.crt')
89
+ )
90
+ server.instance_variable_set(:@crt, crt)
91
+ server
92
+ end
93
+
94
+ it 'should generate Certificate' do
95
+ ct = server.send(:gen_certificate)
96
+ expect(ct).to be_a_kind_of(Certificate)
97
+
98
+ certificate_entry = ct.certificate_list.first
99
+ expect(certificate_entry.cert_data.subject.to_s).to eq '/CN=localhost'
100
+ end
101
+ end
102
+
103
+ context 'server' do
104
+ let(:key) do
105
+ rsa = OpenSSL::PKey::RSA.new
106
+ rsa.set_key(OpenSSL::BN.new(TESTBINARY_PKEY_MODULUS, 2),
107
+ OpenSSL::BN.new(TESTBINARY_PKEY_PUBLIC_EXPONENT, 2),
108
+ OpenSSL::BN.new(TESTBINARY_PKEY_PRIVATE_EXPONENT, 2))
109
+ rsa.set_factors(OpenSSL::BN.new(TESTBINARY_PKEY_PRIME1, 2),
110
+ OpenSSL::BN.new(TESTBINARY_PKEY_PRIME2, 2))
111
+ rsa
112
+ end
113
+
114
+ let(:ct) do
115
+ Certificate.deserialize(TESTBINARY_CERTIFICATE)
116
+ end
117
+
118
+ let(:server) do
119
+ server = Server.new(nil)
120
+ server.instance_variable_set(:@key, key)
121
+ transcript = Transcript.new
122
+ transcript.merge!(
123
+ CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
124
+ SH => ServerHello.deserialize(TESTBINARY_SERVER_HELLO),
125
+ EE => EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS),
126
+ CT => ct
127
+ )
128
+ server.instance_variable_set(:@transcript, transcript)
129
+ server.instance_variable_set(:@cipher_suite,
130
+ CipherSuite::TLS_AES_128_GCM_SHA256)
131
+ server.instance_variable_set(:@signature_scheme,
132
+ SignatureScheme::RSA_PSS_RSAE_SHA256)
133
+ server
134
+ end
135
+
136
+ it 'should generate CertificateVerify' do
137
+ cv = server.send(:gen_certificate_verify)
138
+ expect(cv).to be_a_kind_of(CertificateVerify)
139
+
140
+ # used RSASSA-PSS signature_scheme, salt is a random sequence.
141
+ # CertificateVerify.signature is random.
142
+ public_key = ct.certificate_list.first.cert_data.public_key
143
+ signature_scheme = cv.signature_scheme
144
+ signature = cv.signature
145
+ expect(server.send(:do_verified_certificate_verify?,
146
+ public_key: public_key,
147
+ signature_scheme: signature_scheme,
148
+ signature: signature,
149
+ context: 'TLS 1.3, server CertificateVerify',
150
+ handshake_context_end: CT))
151
+ .to be true
152
+ end
153
+ end
154
+
155
+ context 'server' do
156
+ let(:server) do
157
+ server = Server.new(nil)
158
+ transcript = Transcript.new
159
+ transcript.merge!(
160
+ CH => ClientHello.deserialize(TESTBINARY_CLIENT_HELLO),
161
+ SH => ServerHello.deserialize(TESTBINARY_SERVER_HELLO),
162
+ EE => EncryptedExtensions.deserialize(TESTBINARY_ENCRYPTED_EXTENSIONS),
163
+ CT => Certificate.deserialize(TESTBINARY_CERTIFICATE),
164
+ CV => CertificateVerify.deserialize(TESTBINARY_CERTIFICATE_VERIFY)
165
+ )
166
+ server.instance_variable_set(:@transcript, transcript)
167
+ ks = KeySchedule.new(shared_secret: TESTBINARY_SHARED_SECRET,
168
+ cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
169
+ transcript: transcript)
170
+ server.instance_variable_set(:@key_schedule, ks)
171
+ server.instance_variable_set(:@cipher_suite,
172
+ CipherSuite::TLS_AES_128_GCM_SHA256)
173
+ server
174
+ end
175
+
176
+ let(:verify_data) do
177
+ Finished.deserialize(TESTBINARY_SERVER_FINISHED).verify_data
178
+ end
179
+
180
+ it 'should generate Finished' do
181
+ sf = server.send(:gen_finished)
182
+ expect(sf).to be_a_kind_of(Finished)
183
+ expect(sf.verify_data).to eq verify_data
184
+ end
185
+ end
186
+ end