tttls1.3 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +16 -0
  5. data/.travis.yml +8 -0
  6. data/Gemfile +13 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +52 -0
  9. data/Rakefile +133 -0
  10. data/example/helper.rb +17 -0
  11. data/example/https_client.rb +32 -0
  12. data/example/https_client_using_0rtt.rb +64 -0
  13. data/example/https_client_using_hrr.rb +35 -0
  14. data/example/https_client_using_ticket.rb +56 -0
  15. data/lib/tttls1.3/cipher_suites.rb +102 -0
  16. data/lib/tttls1.3/client.rb +745 -0
  17. data/lib/tttls1.3/connection.rb +380 -0
  18. data/lib/tttls1.3/cryptograph/aead.rb +118 -0
  19. data/lib/tttls1.3/cryptograph/passer.rb +22 -0
  20. data/lib/tttls1.3/cryptograph.rb +3 -0
  21. data/lib/tttls1.3/error.rb +22 -0
  22. data/lib/tttls1.3/key_schedule.rb +242 -0
  23. data/lib/tttls1.3/message/alert.rb +86 -0
  24. data/lib/tttls1.3/message/application_data.rb +27 -0
  25. data/lib/tttls1.3/message/certificate.rb +121 -0
  26. data/lib/tttls1.3/message/certificate_verify.rb +59 -0
  27. data/lib/tttls1.3/message/change_cipher_spec.rb +26 -0
  28. data/lib/tttls1.3/message/client_hello.rb +100 -0
  29. data/lib/tttls1.3/message/encrypted_extensions.rb +65 -0
  30. data/lib/tttls1.3/message/end_of_early_data.rb +29 -0
  31. data/lib/tttls1.3/message/extension/alpn.rb +70 -0
  32. data/lib/tttls1.3/message/extension/cookie.rb +47 -0
  33. data/lib/tttls1.3/message/extension/early_data_indication.rb +58 -0
  34. data/lib/tttls1.3/message/extension/key_share.rb +236 -0
  35. data/lib/tttls1.3/message/extension/pre_shared_key.rb +205 -0
  36. data/lib/tttls1.3/message/extension/psk_key_exchange_modes.rb +54 -0
  37. data/lib/tttls1.3/message/extension/record_size_limit.rb +46 -0
  38. data/lib/tttls1.3/message/extension/server_name.rb +91 -0
  39. data/lib/tttls1.3/message/extension/signature_algorithms.rb +69 -0
  40. data/lib/tttls1.3/message/extension/signature_algorithms_cert.rb +25 -0
  41. data/lib/tttls1.3/message/extension/status_request.rb +106 -0
  42. data/lib/tttls1.3/message/extension/supported_groups.rb +145 -0
  43. data/lib/tttls1.3/message/extension/supported_versions.rb +98 -0
  44. data/lib/tttls1.3/message/extension/unknown_extension.rb +38 -0
  45. data/lib/tttls1.3/message/extensions.rb +173 -0
  46. data/lib/tttls1.3/message/finished.rb +44 -0
  47. data/lib/tttls1.3/message/new_session_ticket.rb +89 -0
  48. data/lib/tttls1.3/message/record.rb +232 -0
  49. data/lib/tttls1.3/message/server_hello.rb +116 -0
  50. data/lib/tttls1.3/message.rb +48 -0
  51. data/lib/tttls1.3/sequence_number.rb +31 -0
  52. data/lib/tttls1.3/signature_scheme.rb +31 -0
  53. data/lib/tttls1.3/transcript.rb +69 -0
  54. data/lib/tttls1.3/utils.rb +91 -0
  55. data/lib/tttls1.3/version.rb +5 -0
  56. data/lib/tttls1.3.rb +16 -0
  57. data/spec/aead_spec.rb +95 -0
  58. data/spec/alert_spec.rb +54 -0
  59. data/spec/alpn_spec.rb +55 -0
  60. data/spec/application_data_spec.rb +26 -0
  61. data/spec/certificate_spec.rb +55 -0
  62. data/spec/certificate_verify_spec.rb +51 -0
  63. data/spec/change_cipher_spec_spec.rb +26 -0
  64. data/spec/cipher_suites_spec.rb +39 -0
  65. data/spec/client_hello_spec.rb +83 -0
  66. data/spec/client_spec.rb +319 -0
  67. data/spec/connection_spec.rb +114 -0
  68. data/spec/cookie_spec.rb +98 -0
  69. data/spec/early_data_indication_spec.rb +64 -0
  70. data/spec/encrypted_extensions_spec.rb +94 -0
  71. data/spec/error_spec.rb +18 -0
  72. data/spec/extensions_spec.rb +170 -0
  73. data/spec/finished_spec.rb +55 -0
  74. data/spec/key_schedule_spec.rb +198 -0
  75. data/spec/key_share_spec.rb +199 -0
  76. data/spec/new_session_ticket_spec.rb +80 -0
  77. data/spec/pre_shared_key_spec.rb +167 -0
  78. data/spec/psk_key_exchange_modes_spec.rb +45 -0
  79. data/spec/record_size_limit_spec.rb +61 -0
  80. data/spec/record_spec.rb +105 -0
  81. data/spec/server_hello_spec.rb +101 -0
  82. data/spec/server_name_spec.rb +110 -0
  83. data/spec/signature_algorithms_cert_spec.rb +73 -0
  84. data/spec/signature_algorithms_spec.rb +100 -0
  85. data/spec/spec_helper.rb +872 -0
  86. data/spec/status_request_spec.rb +73 -0
  87. data/spec/supported_groups_spec.rb +79 -0
  88. data/spec/supported_versions_spec.rb +136 -0
  89. data/spec/transcript_spec.rb +69 -0
  90. data/spec/unknown_extension_spec.rb +90 -0
  91. data/spec/utils_spec.rb +215 -0
  92. data/tttls1.3.gemspec +25 -0
  93. metadata +197 -0
@@ -0,0 +1,80 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe NewSessionTicket do
8
+ context 'new_session_ticket' do
9
+ let(:ticket_lifetime) do
10
+ 7200 # two_hours
11
+ end
12
+
13
+ let(:ticket_age_add) do
14
+ OpenSSL::Random.random_bytes(4)
15
+ end
16
+
17
+ let(:ticket_nonce) do
18
+ "\x00" * 255
19
+ end
20
+
21
+ let(:ticket) do
22
+ OpenSSL::Random.random_bytes(255)
23
+ end
24
+
25
+ let(:message) do
26
+ NewSessionTicket.new(ticket_lifetime: ticket_lifetime,
27
+ ticket_age_add: ticket_age_add,
28
+ ticket_nonce: ticket_nonce,
29
+ ticket: ticket)
30
+ end
31
+
32
+ it 'should be generated' do
33
+ expect(message.msg_type).to eq HandshakeType::NEW_SESSION_TICKET
34
+ expect(message.ticket_lifetime).to eq ticket_lifetime
35
+ expect(message.ticket_age_add).to eq ticket_age_add
36
+ expect(message.ticket_nonce).to eq ticket_nonce
37
+ expect(message.ticket).to eq ticket
38
+ expect(message.extensions).to be_empty
39
+ end
40
+
41
+ it 'should be serialized' do
42
+ expect(message.serialize).to eq HandshakeType::NEW_SESSION_TICKET \
43
+ + 523.to_uint24 \
44
+ + ticket_lifetime.to_uint32 \
45
+ + ticket_age_add \
46
+ + ticket_nonce.prefix_uint8_length \
47
+ + ticket.prefix_uint16_length \
48
+ + Extensions.new.serialize
49
+ end
50
+ end
51
+
52
+ context 'new_session_ticket, invalid ticket_age_add,' do
53
+ let(:message) do
54
+ NewSessionTicket.new(ticket_lifetime: 60 * 60 * 2, # 2 hours
55
+ ticket_age_add: OpenSSL::Random.random_bytes(32),
56
+ ticket_nonce: "\x00" * 255,
57
+ ticket: OpenSSL::Random.random_bytes(255))
58
+ end
59
+
60
+ it 'should not be generated' do
61
+ expect { message }.to raise_error(ErrorAlerts)
62
+ end
63
+ end
64
+
65
+ context 'valid new_session_ticket binary' do
66
+ let(:message) do
67
+ NewSessionTicket.deserialize(TESTBINARY_NEW_SESSION_TICKET)
68
+ end
69
+
70
+ it 'should generate object' do
71
+ expect(message.msg_type).to eq HandshakeType::NEW_SESSION_TICKET
72
+ expect(message.ticket_lifetime).to eq 30
73
+ expect(message.ticket_nonce).to eq "\x00\x00"
74
+ end
75
+
76
+ it 'should generate serializable object' do
77
+ expect(message.serialize).to eq TESTBINARY_NEW_SESSION_TICKET
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,167 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe PreSharedKey do
8
+ context 'valid pre_shared_key of ClientHello' do
9
+ let(:identity) do
10
+ OpenSSL::Random.random_bytes(32)
11
+ end
12
+
13
+ let(:obfuscated_ticket_age) do
14
+ OpenSSL::BN.rand_range(1 << 32).to_i
15
+ end
16
+
17
+ let(:binders) do
18
+ [
19
+ OpenSSL::Random.random_bytes(32)
20
+ ]
21
+ end
22
+
23
+ let(:identities) do
24
+ [
25
+ PskIdentity.new(
26
+ identity: identity,
27
+ obfuscated_ticket_age: obfuscated_ticket_age
28
+ )
29
+ ]
30
+ end
31
+
32
+ let(:offered_psks) do
33
+ OfferedPsks.new(
34
+ identities: identities,
35
+ binders: binders
36
+ )
37
+ end
38
+
39
+ let(:extension) do
40
+ PreSharedKey.new(msg_type: HandshakeType::CLIENT_HELLO,
41
+ offered_psks: offered_psks)
42
+ end
43
+
44
+ it 'should be generated' do
45
+ expect(extension.msg_type).to eq HandshakeType::CLIENT_HELLO
46
+ expect(extension.extension_type).to eq ExtensionType::PRE_SHARED_KEY
47
+ expect(extension.offered_psks).to eq offered_psks
48
+ expect(extension.selected_identity).to be_nil
49
+ end
50
+
51
+ it 'should be serialized' do
52
+ expect(extension.serialize).to eq ExtensionType::PRE_SHARED_KEY \
53
+ + 75.to_uint16 \
54
+ + 38.to_uint16 \
55
+ + 32.to_uint16 \
56
+ + identity \
57
+ + obfuscated_ticket_age.to_uint32 \
58
+ + 33.to_uint16 \
59
+ + "\x20" \
60
+ + binders.join
61
+ end
62
+ end
63
+
64
+ context 'valid pre_shared_key, ClientHello,' do
65
+ let(:identity_1) do
66
+ OpenSSL::Random.random_bytes(32)
67
+ end
68
+ let(:identity_2) do
69
+ OpenSSL::Random.random_bytes(32)
70
+ end
71
+
72
+ let(:obfuscated_ticket_age_1) do
73
+ OpenSSL::BN.rand_range(1 << 32).to_i
74
+ end
75
+ let(:obfuscated_ticket_age_2) do
76
+ OpenSSL::BN.rand_range(1 << 32).to_i
77
+ end
78
+
79
+ let(:binders) do
80
+ [
81
+ OpenSSL::Random.random_bytes(32),
82
+ OpenSSL::Random.random_bytes(32)
83
+ ]
84
+ end
85
+
86
+ let(:identities) do
87
+ [
88
+ PskIdentity.new(
89
+ identity: identity_1,
90
+ obfuscated_ticket_age: obfuscated_ticket_age_1
91
+ ),
92
+ PskIdentity.new(
93
+ identity: identity_2,
94
+ obfuscated_ticket_age: obfuscated_ticket_age_2
95
+ )
96
+ ]
97
+ end
98
+
99
+ let(:offered_psks) do
100
+ OfferedPsks.new(
101
+ identities: identities,
102
+ binders: binders
103
+ )
104
+ end
105
+
106
+ let(:extension) do
107
+ PreSharedKey.new(msg_type: HandshakeType::CLIENT_HELLO,
108
+ offered_psks: offered_psks)
109
+ end
110
+
111
+ it 'should be generated' do
112
+ expect(extension.msg_type).to eq HandshakeType::CLIENT_HELLO
113
+ expect(extension.extension_type).to eq ExtensionType::PRE_SHARED_KEY
114
+ expect(extension.offered_psks).to eq offered_psks
115
+ expect(extension.selected_identity).to be_nil
116
+ end
117
+
118
+ it 'should be serialized' do
119
+ expect(extension.serialize).to eq ExtensionType::PRE_SHARED_KEY \
120
+ + 146.to_uint16 \
121
+ + 76.to_uint16 \
122
+ + identity_1.prefix_uint16_length \
123
+ + obfuscated_ticket_age_1.to_uint32 \
124
+ + identity_2.prefix_uint16_length \
125
+ + obfuscated_ticket_age_2.to_uint32 \
126
+ + 66.to_uint16 \
127
+ + binders[0].prefix_uint8_length \
128
+ + binders[1].prefix_uint8_length
129
+ end
130
+ end
131
+
132
+ context 'valid pre_shared_key binary, ClientHello,' do
133
+ let(:extension) do
134
+ PreSharedKey.deserialize(TESTBINARY_PRE_SHARED_KEY_CH,
135
+ HandshakeType::CLIENT_HELLO)
136
+ end
137
+
138
+ it 'should generate valid object' do
139
+ expect(extension.msg_type).to eq HandshakeType::CLIENT_HELLO
140
+ expect(extension.extension_type).to eq ExtensionType::PRE_SHARED_KEY
141
+ end
142
+
143
+ it 'should generate valid serializable object' do
144
+ expect(extension.serialize)
145
+ .to eq ExtensionType::PRE_SHARED_KEY \
146
+ + TESTBINARY_PRE_SHARED_KEY_CH.prefix_uint16_length
147
+ end
148
+ end
149
+
150
+ context 'valid pre_shared_key binary, ServerHello,' do
151
+ let(:extension) do
152
+ PreSharedKey.deserialize(TESTBINARY_PRE_SHARED_KEY_SH,
153
+ HandshakeType::SERVER_HELLO)
154
+ end
155
+
156
+ it 'should generate valid object' do
157
+ expect(extension.msg_type).to eq HandshakeType::SERVER_HELLO
158
+ expect(extension.extension_type).to eq ExtensionType::PRE_SHARED_KEY
159
+ end
160
+
161
+ it 'should generate valid serializable object' do
162
+ expect(extension.serialize)
163
+ .to eq ExtensionType::PRE_SHARED_KEY \
164
+ + TESTBINARY_PRE_SHARED_KEY_SH.prefix_uint16_length
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe PskKeyExchangeModes do
8
+ context 'valid psk_key_exchange_modes' do
9
+ let(:extension) do
10
+ PskKeyExchangeModes.new([PskKeyExchangeMode::PSK_KE,
11
+ PskKeyExchangeMode::PSK_DHE_KE])
12
+ end
13
+
14
+ it 'should generate valid psk_key_exchange_modes' do
15
+ expect(extension.extension_type)
16
+ .to eq ExtensionType::PSK_KEY_EXCHANGE_MODES
17
+ expect(extension.ke_modes).to eq [PskKeyExchangeMode::PSK_KE,
18
+ PskKeyExchangeMode::PSK_DHE_KE]
19
+ expect(extension.serialize)
20
+ .to eq ExtensionType::PSK_KEY_EXCHANGE_MODES \
21
+ + 3.to_uint16 \
22
+ + [PskKeyExchangeMode::PSK_KE,
23
+ PskKeyExchangeMode::PSK_DHE_KE].join.prefix_uint8_length
24
+ end
25
+ end
26
+
27
+ context 'valid psk_key_exchange_modes binary' do
28
+ let(:extension) do
29
+ PskKeyExchangeModes.deserialize(TESTBINARY_PSK_KEY_EXCHANGE_MODES)
30
+ end
31
+
32
+ it 'should generate valid object' do
33
+ expect(extension.extension_type)
34
+ .to eq ExtensionType::PSK_KEY_EXCHANGE_MODES
35
+ expect(extension.ke_modes).to eq [PskKeyExchangeMode::PSK_KE,
36
+ PskKeyExchangeMode::PSK_DHE_KE]
37
+ end
38
+
39
+ it 'should generate serializable object' do
40
+ expect(extension.serialize)
41
+ .to eq ExtensionType::PSK_KEY_EXCHANGE_MODES \
42
+ + TESTBINARY_PSK_KEY_EXCHANGE_MODES.prefix_uint16_length
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe RecordSizeLimit do
8
+ context 'vailid record_size_limit' do
9
+ let(:extension) do
10
+ RecordSizeLimit.new(2**14)
11
+ end
12
+
13
+ it 'should be generated' do
14
+ expect(extension.extension_type).to eq ExtensionType::RECORD_SIZE_LIMIT
15
+ expect(extension.record_size_limit).to eq 2**14
16
+ end
17
+
18
+ it 'should be serialized' do
19
+ expect(extension.serialize).to eq ExtensionType::RECORD_SIZE_LIMIT \
20
+ + 2.to_uint16 \
21
+ + (2**14).to_uint16
22
+ end
23
+ end
24
+
25
+ context 'invalid record_size_limit' do
26
+ let(:extension) do
27
+ RecordSizeLimit.new(63)
28
+ end
29
+
30
+ it 'should not generated' do
31
+ expect { extension }.to raise_error(ErrorAlerts)
32
+ end
33
+ end
34
+
35
+ context 'valid record_size_limit binary' do
36
+ let(:extension) do
37
+ RecordSizeLimit.deserialize(TESTBINARY_RECORD_SIZE_LIMIT)
38
+ end
39
+
40
+ it 'should generate valid object' do
41
+ expect(extension.extension_type).to eq ExtensionType::RECORD_SIZE_LIMIT
42
+ expect(extension.record_size_limit).to eq 2**14
43
+ end
44
+
45
+ it 'should generate serializable object' do
46
+ expect(extension.serialize)
47
+ .to eq ExtensionType::RECORD_SIZE_LIMIT \
48
+ + TESTBINARY_RECORD_SIZE_LIMIT.prefix_uint16_length
49
+ end
50
+ end
51
+
52
+ context 'invalid record_size_limit binary, too short record_size_limit,' do
53
+ let(:extension) do
54
+ RecordSizeLimit.deserialize(63.to_uint16)
55
+ end
56
+
57
+ it 'should not generate object' do
58
+ expect { extension }.to raise_error(ErrorAlerts)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,105 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe Record do
8
+ context 'valid record' do
9
+ let(:record) do
10
+ Record.new(
11
+ type: ContentType::CCS,
12
+ legacy_record_version: ProtocolVersion::TLS_1_2,
13
+ messages: [ChangeCipherSpec.new],
14
+ cipher: Passer.new
15
+ )
16
+ end
17
+
18
+ it 'should be generated' do
19
+ expect(record.type).to eq ContentType::CCS
20
+ expect(record.legacy_record_version).to eq ProtocolVersion::TLS_1_2
21
+ end
22
+
23
+ it 'should be serialized' do
24
+ expect(record.serialize).to eq ContentType::CCS \
25
+ + ProtocolVersion::TLS_1_2 \
26
+ + 1.to_uint16 \
27
+ + ChangeCipherSpec.new.serialize
28
+ end
29
+ end
30
+
31
+ context 'valid record binary' do
32
+ let(:record) do
33
+ Record.deserialize(TESTBINARY_RECORD_CCS, Passer.new)
34
+ end
35
+
36
+ it 'should generate valid record header and ChangeCipherSpec' do
37
+ expect(record.type).to eq ContentType::CCS
38
+ expect(record.legacy_record_version).to eq ProtocolVersion::TLS_1_2
39
+ end
40
+
41
+ it 'should generate valid serializable object' do
42
+ expect(record.serialize).to eq ContentType::CCS \
43
+ + ProtocolVersion::TLS_1_2 \
44
+ + 1.to_uint16 \
45
+ + ChangeCipherSpec.new.serialize
46
+ end
47
+ end
48
+
49
+ context 'invalid record binary, too short,' do
50
+ let(:record) do
51
+ Record.deserialize(TESTBINARY_RECORD_CCS[0...-1],
52
+ Passer.new)
53
+ end
54
+
55
+ it 'should not generate object' do
56
+ expect { record }.to raise_error(ErrorAlerts)
57
+ end
58
+ end
59
+
60
+ context 'invalid record binary, nil,' do
61
+ let(:record) do
62
+ Record.deserialize(nil, Passer.new)
63
+ end
64
+
65
+ it 'should not generate object' do
66
+ expect { record }.to raise_error(ErrorAlerts)
67
+ end
68
+ end
69
+
70
+ context 'server parameters record binary' do
71
+ let(:record) do
72
+ cipher = Cryptograph::Aead.new(
73
+ cipher_suite: CipherSuite::TLS_AES_128_GCM_SHA256,
74
+ write_key: TESTBINARY_SERVER_PARAMETERS_WRITE_KEY,
75
+ write_iv: TESTBINARY_SERVER_PARAMETERS_WRITE_IV,
76
+ sequence_number: SequenceNumber.new
77
+ )
78
+ Record.deserialize(TESTBINARY_SERVER_PARAMETERS_RECORD, cipher)
79
+ end
80
+
81
+ it 'should generate valid record header' do
82
+ expect(record.type).to eq ContentType::APPLICATION_DATA
83
+ expect(record.legacy_record_version).to eq ProtocolVersion::TLS_1_2
84
+ end
85
+
86
+ it 'should generate valid server parameters' do
87
+ expect(record.messages[0].msg_type)
88
+ .to eq HandshakeType::ENCRYPTED_EXTENSIONS
89
+ expect(record.messages[0].serialize)
90
+ .to eq TESTBINARY_ENCRYPTED_EXTENSIONS
91
+ expect(record.messages[1].msg_type)
92
+ .to eq HandshakeType::CERTIFICATE
93
+ expect(record.messages[1].serialize)
94
+ .to eq TESTBINARY_CERTIFICATE
95
+ expect(record.messages[2].msg_type)
96
+ .to eq HandshakeType::CERTIFICATE_VERIFY
97
+ expect(record.messages[2].serialize)
98
+ .to eq TESTBINARY_CERTIFICATE_VERIFY
99
+ expect(record.messages[3].msg_type)
100
+ .to eq HandshakeType::FINISHED
101
+ expect(record.messages[3].serialize)
102
+ .to eq TESTBINARY_SERVER_FINISHED
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,101 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe ServerHello do
8
+ context 'default server_hello' do
9
+ let(:random) do
10
+ OpenSSL::Random.random_bytes(32)
11
+ end
12
+
13
+ let(:legacy_session_id_echo) do
14
+ Array.new(32, 0).map(&:chr).join
15
+ end
16
+
17
+ let(:cipher_suite) do
18
+ CipherSuite::TLS_AES_256_GCM_SHA384
19
+ end
20
+
21
+ let(:message) do
22
+ ServerHello.new(random: random,
23
+ legacy_session_id_echo: legacy_session_id_echo,
24
+ cipher_suite: cipher_suite)
25
+ end
26
+
27
+ it 'should be generated' do
28
+ expect(message.msg_type).to eq HandshakeType::SERVER_HELLO
29
+ expect(message.legacy_version).to eq ProtocolVersion::TLS_1_2
30
+ expect(message.random).to eq random
31
+ expect(message.legacy_session_id_echo).to eq legacy_session_id_echo
32
+ expect(message.cipher_suite).to eq CipherSuite::TLS_AES_256_GCM_SHA384
33
+ expect(message.legacy_compression_method).to eq "\x00"
34
+ expect(message.extensions).to be_empty
35
+ end
36
+
37
+ it 'should be serialized' do
38
+ expect(message.serialize).to eq HandshakeType::SERVER_HELLO \
39
+ + 72.to_uint24 \
40
+ + ProtocolVersion::TLS_1_2 \
41
+ + random \
42
+ + legacy_session_id_echo.length.to_uint8 \
43
+ + legacy_session_id_echo \
44
+ + cipher_suite \
45
+ + "\x00" \
46
+ + Extensions.new.serialize
47
+ end
48
+ end
49
+
50
+ context 'valid server_hello binary' do
51
+ let(:message) do
52
+ ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
53
+ end
54
+
55
+ it 'should generate valid object' do
56
+ expect(message.msg_type).to eq HandshakeType::SERVER_HELLO
57
+ expect(message.legacy_version).to eq ProtocolVersion::TLS_1_2
58
+ expect(message.cipher_suite).to eq CipherSuite::TLS_AES_128_GCM_SHA256
59
+ expect(message.legacy_compression_method).to eq "\x00"
60
+ end
61
+
62
+ it 'should generate valid serializable object' do
63
+ expect(message.serialize).to eq TESTBINARY_SERVER_HELLO
64
+ end
65
+ end
66
+
67
+ context 'hello_retry_request binary' do
68
+ let(:message) do
69
+ ServerHello.deserialize(TESTBINARY_HRR_HELLO_RETRY_REQUEST)
70
+ end
71
+
72
+ it 'should generate valid object' do
73
+ expect(message.msg_type).to eq HandshakeType::SERVER_HELLO
74
+ expect(message.legacy_version).to eq ProtocolVersion::TLS_1_2
75
+ expect(message.cipher_suite).to eq CipherSuite::TLS_AES_128_GCM_SHA256
76
+ expect(message.legacy_compression_method).to eq "\x00"
77
+ expect(message.hrr?).to be true
78
+ end
79
+
80
+ it 'should generate valid serializable object' do
81
+ expect(message.serialize).to eq TESTBINARY_HRR_HELLO_RETRY_REQUEST
82
+ end
83
+ end
84
+
85
+ context 'valid server_hello binary, 0-RTT,' do
86
+ let(:message) do
87
+ ServerHello.deserialize(TESTBINARY_0_RTT_SERVER_HELLO)
88
+ end
89
+
90
+ it 'should generate valid object' do
91
+ expect(message.msg_type).to eq HandshakeType::SERVER_HELLO
92
+ expect(message.legacy_version).to eq ProtocolVersion::TLS_1_2
93
+ expect(message.cipher_suite).to eq CipherSuite::TLS_AES_128_GCM_SHA256
94
+ expect(message.legacy_compression_method).to eq "\x00"
95
+ end
96
+
97
+ it 'should generate valid serializable object' do
98
+ expect(message.serialize).to eq TESTBINARY_0_RTT_SERVER_HELLO
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,110 @@
1
+ # encoding: ascii-8bit
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+ using Refinements
6
+
7
+ RSpec.describe ServerName do
8
+ context 'valid server_name, example.com,' do
9
+ let(:extension) do
10
+ ServerName.new('example.com')
11
+ end
12
+
13
+ it 'should be generated' do
14
+ expect(extension.extension_type).to eq ExtensionType::SERVER_NAME
15
+ expect(extension.server_name).to eq 'example.com'
16
+ end
17
+
18
+ it 'should be serialized' do
19
+ expect(extension.serialize).to eq ExtensionType::SERVER_NAME \
20
+ + 16.to_uint16 \
21
+ + 14.to_uint16 \
22
+ + NameType::HOST_NAME \
23
+ + 11.to_uint16 \
24
+ + 'example.com'
25
+ end
26
+ end
27
+
28
+ context 'valid server_name, empty HostName,' do
29
+ let(:extension) do
30
+ ServerName.new('')
31
+ end
32
+
33
+ it 'should be generated' do
34
+ expect(extension.extension_type).to eq ExtensionType::SERVER_NAME
35
+ end
36
+
37
+ it 'should be serialized' do
38
+ expect(extension.serialize).to eq ExtensionType::SERVER_NAME \
39
+ + 0.to_uint16
40
+ end
41
+ end
42
+
43
+ context 'invalid server_name, too long HostName,' do
44
+ let(:extension) do
45
+ ServerName.new('a' * (2**16 - 4))
46
+ end
47
+
48
+ it 'should not be generated' do
49
+ expect { extension }.to raise_error(ErrorAlerts)
50
+ end
51
+ end
52
+
53
+ context 'valid server_name binary' do
54
+ let(:extension) do
55
+ ServerName.deserialize(TESTBINARY_SERVER_NAME)
56
+ end
57
+
58
+ it 'should generate valid object' do
59
+ expect(extension.extension_type).to eq ExtensionType::SERVER_NAME
60
+ expect(extension.server_name).to eq 'github.com'
61
+ end
62
+
63
+ it 'should generate serializable object' do
64
+ expect(extension.serialize)
65
+ .to eq ExtensionType::SERVER_NAME \
66
+ + TESTBINARY_SERVER_NAME.prefix_uint16_length
67
+ end
68
+ end
69
+
70
+ context 'invalid server_name binary, malformed binary,' do
71
+ let(:extension) do
72
+ ServerName.deserialize(TESTBINARY_SERVER_NAME[0...-1])
73
+ end
74
+
75
+ it 'should return nil' do
76
+ expect(extension).to be nil
77
+ end
78
+ end
79
+
80
+ context 'invalid server_name binary, unknown NameType,' do
81
+ let(:testbinary) do
82
+ name_type = "\xff"
83
+ binary = name_type + 'example.com'.prefix_uint16_length
84
+ binary.prefix_uint16_length.prefix_uint16_length
85
+ end
86
+
87
+ let(:extension) do
88
+ ServerName.deserialize(testbinary)
89
+ end
90
+
91
+ it 'should return nil' do
92
+ expect(extension).to be nil
93
+ end
94
+ end
95
+
96
+ context 'invalid server_name binary, empty HostName,' do
97
+ let(:testbinary) do
98
+ binary = NameType::HOST_NAME + ''.prefix_uint16_length
99
+ binary.prefix_uint16_length.prefix_uint16_length
100
+ end
101
+
102
+ let(:extension) do
103
+ ServerName.deserialize(testbinary)
104
+ end
105
+
106
+ it 'should return nil' do
107
+ expect(extension).to be nil
108
+ end
109
+ end
110
+ end