tttls1.3 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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