tttls1.3 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 356ce310f2323bede1cdfd21f6c18050d2ce9aca6da4c8ed67b439b597c92ba0
4
- data.tar.gz: d1bcb99ae830df4c8c40688d85e5c7efcda76e0c608ef0707b5201862a5baff8
3
+ metadata.gz: 9b99157535ca4f2b06f4fc6d374116fbc6e496a7807184c56b31be11852d6e5f
4
+ data.tar.gz: 33ff8b94d80529bcabd7c4b3d8fe5ea9ee6513d1d90f4efe307f4edf7bbfb1ac
5
5
  SHA512:
6
- metadata.gz: ae23baf431d2908aceae8e411deb2b8ebf33f8696e67602081c3f07b2d9dad523f8a21a251d5333243e2f44405e8efa0e6595e0af7a744c9fda05c026a824346
7
- data.tar.gz: '0978b73204cc49a3fac033904c98c17eb05f45a2793a5f326298414db09599d065ab599ce34e4cc73bbd928abed9cb988a35ef7248ec9af1ff8a121f6378da61'
6
+ metadata.gz: 29f4cd4e505e33ef0b6f03265a3ecdc8e988a32a965a9079b8c92ee57e50a6ad7e7864fb24d07a14b0ec956fce6ce1c85d9d8072e908e202393c1bd73ad54c1f
7
+ data.tar.gz: c5ed00504bbdb7ee0b051a3534ab2c51bbfdbadbd703ca761fb06367b85798217b04ba7b7d1a8003aeff756d3e9b8e7b6f7c375872250de4139e7400760608d4
data/.travis.yml CHANGED
@@ -1,8 +1,14 @@
1
1
  sudo: false
2
+
2
3
  language: ruby
4
+
3
5
  rvm:
4
6
  - 2.6.1
7
+ - 2.6.2
8
+ - 2.6.3
9
+
5
10
  before_install:
6
11
  - gem install bundler -v 2.0.1
7
12
  - bundle install
13
+
8
14
  script: bundle exec rake
data/Rakefile CHANGED
@@ -128,4 +128,18 @@ end
128
128
 
129
129
  RuboCop::RakeTask.new
130
130
  RSpec::Core::RakeTask.new(:spec)
131
+
132
+ desc 'interoperability test: TTTLS13::Client'
133
+ RSpec::Core::RakeTask.new(:interop_client) do |t|
134
+ t.pattern = Dir.glob('interop/client_spec.rb')
135
+ end
136
+
137
+ desc 'interoperability test: TTTLS13::Server'
138
+ RSpec::Core::RakeTask.new(:interop_server) do |t|
139
+ t.pattern = Dir.glob('interop/server_spec.rb')
140
+ end
141
+
142
+ desc 'interoperability test between openssl'
143
+ task interop: %i[interop_client interop_server]
144
+
131
145
  task default: %i[rubocop spec]
data/interop/Dockerfile CHANGED
@@ -1,6 +1,6 @@
1
1
  FROM ubuntu:18.04
2
2
 
3
- ARG version="1.1.1b"
3
+ ARG version="1.1.1c"
4
4
 
5
5
  RUN apt-get update && apt-get install -y --no-install-recommends \
6
6
  autoconf \
@@ -4,6 +4,7 @@
4
4
  require_relative 'helper'
5
5
 
6
6
  FIXTURES_DIR = __dir__ + '/../spec/fixtures'
7
+ PORT = 4433
7
8
 
8
9
  RSpec.describe Client do
9
10
  # testcases
@@ -147,28 +148,37 @@ RSpec.describe Client do
147
148
  'rsa_rsa.crt',
148
149
  'rsa_rsa.key',
149
150
  key_share_groups: []
151
+ ],
152
+ [
153
+ true,
154
+ '-alpn http/1.1',
155
+ 'rsa_rsa.crt',
156
+ 'rsa_rsa.key',
157
+ alpn: ['http/1.1']
150
158
  ]
151
159
  # rubocop: enable Metrics/LineLength
152
160
  ].each do |normal, opt, crt, key, settings|
153
161
  context 'client interop' do
154
162
  before do
155
- cmd = "docker run -v #{FIXTURES_DIR}:/tmp -p 4433:4433 -it openssl " \
156
- + 'openssl s_server ' \
163
+ cmd = 'openssl s_server ' \
157
164
  + "-cert /tmp/#{crt} " \
158
165
  + "-key /tmp/#{key} " \
159
166
  + '-tls1_3 ' \
160
167
  + '-www ' \
161
168
  + '-quiet ' \
162
169
  + opt
163
- pid = spawn(cmd)
170
+ pid = spawn('docker run ' \
171
+ + "--volume #{FIXTURES_DIR}:/tmp " \
172
+ + "--publish #{PORT}:#{PORT} " \
173
+ + 'openssl ' + cmd)
164
174
  Process.detach(pid)
165
175
 
166
- sleep(2.5) # waiting for openssl s_server
176
+ wait_to_listen(PORT)
167
177
  end
168
178
 
169
179
  let(:client) do
170
180
  hostname = 'localhost'
171
- @socket = TCPSocket.new(hostname, 4433)
181
+ @socket = TCPSocket.new(hostname, PORT)
172
182
  settings[:ca_file] = FIXTURES_DIR + '/rsa_ca.crt'
173
183
  Client.new(@socket, hostname, settings)
174
184
  end
data/interop/helper.rb CHANGED
@@ -11,3 +11,7 @@ include TTTLS13::SignatureScheme
11
11
  include TTTLS13::Message::Extension
12
12
  include TTTLS13::Error
13
13
  # rubocop: enable Style/MixinUsage
14
+
15
+ def wait_to_listen(port)
16
+ sleep(0.2) while `lsof -ni :#{port}`.empty?
17
+ end
@@ -4,7 +4,9 @@
4
4
  require_relative 'helper'
5
5
 
6
6
  FIXTURES_DIR = __dir__ + '/../spec/fixtures'
7
- tcpserver = TCPServer.open(4433)
7
+ PORT = 4433
8
+
9
+ tcpserver = TCPServer.open(PORT)
8
10
 
9
11
  RSpec.describe Server do
10
12
  # testcases
@@ -141,6 +143,20 @@ RSpec.describe Server do
141
143
  FIXTURES_DIR + '/rsa_rsa.crt',
142
144
  FIXTURES_DIR + '/rsa_rsa.key',
143
145
  {}
146
+ ],
147
+ [
148
+ true,
149
+ '-groups P-256:P-384:P-521 -alpn http/1.1',
150
+ FIXTURES_DIR + '/rsa_rsa.crt',
151
+ FIXTURES_DIR + '/rsa_rsa.key',
152
+ alpn: 'http/1.1'
153
+ ],
154
+ [
155
+ false,
156
+ '-groups P-256:P-384:P-521 -alpn foo',
157
+ FIXTURES_DIR + '/rsa_rsa.crt',
158
+ FIXTURES_DIR + '/rsa_rsa.key',
159
+ alpn: 'http/1.1'
144
160
  ]
145
161
  # rubocop: enable Metrics/LineLength
146
162
  ].each do |normal, opt, crt, key, settings|
@@ -153,15 +169,18 @@ RSpec.describe Server do
153
169
  end
154
170
 
155
171
  let(:client) do
172
+ wait_to_listen(PORT)
173
+
156
174
  ip = Socket.ip_address_list.find(&:ipv4_private?).ip_address
157
175
  cmd = 'echo -n ping | openssl s_client ' \
158
- + '-connect local:4433 ' \
176
+ + "-connect local:#{PORT} " \
159
177
  + '-tls1_3 ' \
160
178
  + '-CAfile /tmp/rsa_ca.crt ' \
161
179
  + '-servername localhost ' \
162
180
  + '-quiet ' \
163
181
  + opt
164
- "docker run -v #{FIXTURES_DIR}:/tmp " \
182
+ 'docker run ' \
183
+ + "--volume #{FIXTURES_DIR}:/tmp " \
165
184
  + "--add-host=local:#{ip} -it openssl " \
166
185
  + "sh -c \"#{cmd}\" 2>&1 >/dev/null"
167
186
  end
@@ -173,7 +192,7 @@ RSpec.describe Server do
173
192
 
174
193
  if normal
175
194
  it "should accept request from openssl s_client ...#{opt}" do
176
- spawn('sleep 2; ' + client)
195
+ spawn(client)
177
196
  expect { server.accept }.to_not raise_error
178
197
  expect(server.read).to include 'ping'
179
198
  expect { server.write('pong') }.to_not raise_error
@@ -181,7 +200,7 @@ RSpec.describe Server do
181
200
  end
182
201
  else # exceptions scenarios
183
202
  it "should NOT accept request from openssl s_client ...#{opt}" do
184
- spawn('sleep 2; ' + client)
203
+ spawn(client)
185
204
  expect { server.accept }.to raise_error ErrorAlerts
186
205
  end
187
206
  end
@@ -50,6 +50,7 @@ module TTTLS13
50
50
  signature_algorithms_cert: nil,
51
51
  supported_groups: DEFAULT_CH_NAMED_GROUP_LIST,
52
52
  key_share_groups: nil,
53
+ alpn: nil,
53
54
  process_new_session_ticket: nil,
54
55
  ticket: nil,
55
56
  resumption_master_secret: nil,
@@ -280,6 +281,10 @@ module TTTLS13
280
281
  @succeed_early_data = true \
281
282
  if ee.extensions.include?(Message::ExtensionType::EARLY_DATA)
282
283
 
284
+ @alpn = ee.extensions[
285
+ Message::ExtensionType::APPLICATION_LAYER_PROTOCOL_NEGOTIATION
286
+ ]&.protocol_name_list&.first
287
+
283
288
  @state = ClientState::WAIT_CERT_CR
284
289
  @state = ClientState::WAIT_FINISHED unless psk.nil?
285
290
  when ClientState::WAIT_CERT_CR
@@ -397,6 +402,11 @@ module TTTLS13
397
402
  @succeed_early_data
398
403
  end
399
404
 
405
+ # @return [String]
406
+ def negotiated_alpn
407
+ @alpn
408
+ end
409
+
400
410
  private
401
411
 
402
412
  # @return [Boolean]
@@ -471,6 +481,8 @@ module TTTLS13
471
481
 
472
482
  # @return [TTTLS13::Message::Extensions]
473
483
  # @return [Hash of NamedGroup => OpenSSL::PKey::EC.$Object]
484
+ # rubocop: disable Metrics/AbcSize
485
+ # rubocop: disable Metrics/CyclomaticComplexity
474
486
  def gen_ch_extensions
475
487
  exs = []
476
488
  # supported_versions: only TLS 1.3
@@ -507,8 +519,14 @@ module TTTLS13
507
519
  # early_data
508
520
  exs << Message::Extension::EarlyDataIndication.new if use_early_data?
509
521
 
522
+ # alpn
523
+ exs << Message::Extension::Alpn.new(@settings[:alpn].reject(&:empty?)) \
524
+ if !@settings[:alpn].nil? && !@settings[:alpn].empty?
525
+
510
526
  [Message::Extensions.new(exs), priv_keys]
511
527
  end
528
+ # rubocop: enable Metrics/AbcSize
529
+ # rubocop: enable Metrics/CyclomaticComplexity
512
530
 
513
531
  # @param extensions [TTTLS13::Message::Extensions]
514
532
  # @param binder_key [String, nil]
@@ -50,6 +50,7 @@ module TTTLS13
50
50
  cipher_suites: DEFAULT_SP_CIPHER_SUITES,
51
51
  signature_algorithms: DEFAULT_SP_SIGNATURE_ALGORITHMS,
52
52
  supported_groups: DEFAULT_SP_NAMED_GROUP_LIST,
53
+ alpn: nil,
53
54
  loglevel: Logger::WARN
54
55
  }.freeze
55
56
  private_constant :DEFAULT_SERVER_SETTINGS
@@ -151,6 +152,16 @@ module TTTLS13
151
152
  terminate(:illegal_parameter) unless ch.valid_key_share?
152
153
  terminate(:unrecognized_name) unless recognized_server_name?(ch, @crt)
153
154
 
155
+ # alpn
156
+ if !@settings[:alpn].nil? && !@settings[:alpn].empty?
157
+ pnl = ch.extensions[
158
+ Message::ExtensionType::APPLICATION_LAYER_PROTOCOL_NEGOTIATION
159
+ ]&.protocol_name_list || []
160
+ @alpn = pnl.find { |p| @settings[:alpn].include?(p) }
161
+
162
+ terminate(:no_application_protocol) if @alpn.nil?
163
+ end
164
+
154
165
  @state = ServerState::RECVD_CH
155
166
  when ServerState::RECVD_CH
156
167
  logger.debug('ServerState::RECVD_CH')
@@ -209,7 +220,7 @@ module TTTLS13
209
220
  logger.debug('ServerState::WAIT_FLIGHT2')
210
221
 
211
222
  ch = transcript[CH]
212
- ee = transcript[EE] = gen_encrypted_extensions(ch)
223
+ ee = transcript[EE] = gen_encrypted_extensions(ch, @alpn)
213
224
  # TODO: [Send CertificateRequest]
214
225
  ct = transcript[CT] = gen_certificate(@crt)
215
226
  digest = CipherSuite.digest(@cipher_suite)
@@ -335,9 +346,9 @@ module TTTLS13
335
346
  ksg = sp_groups.find do |g|
336
347
  !ks_groups.include?(g) && @settings[:supported_groups].include?(g)
337
348
  end
349
+ exs << Message::Extension::KeyShare.gen_hrr_key_share(ksg)
338
350
 
339
351
  # TODO: cookie
340
- exs << Message::Extension::KeyShare.gen_hrr_key_share(ksg)
341
352
 
342
353
  sh = Message::ServerHello.new(
343
354
  random: Message::HRR_RANDOM,
@@ -363,10 +374,11 @@ module TTTLS13
363
374
  end
364
375
 
365
376
  # @param ch [TTTLS13::Message::ClientHello]
377
+ # @param alpn [String]
366
378
  #
367
379
  # @return [TTTLS13::Message::EncryptedExtensions]
368
- def gen_encrypted_extensions(ch)
369
- Message::EncryptedExtensions.new(gen_ee_extensions(ch))
380
+ def gen_encrypted_extensions(ch, alpn = nil)
381
+ Message::EncryptedExtensions.new(gen_ee_extensions(ch, alpn))
370
382
  end
371
383
 
372
384
  # @param crt [OpenSSL::X509::Certificate]
@@ -424,9 +436,10 @@ module TTTLS13
424
436
  end
425
437
 
426
438
  # @param ch [TTTLS13::Message::ClientHello]
439
+ # @param alpn [String]
427
440
  #
428
441
  # @return [TTTLS13::Message::Extensions]
429
- def gen_ee_extensions(ch)
442
+ def gen_ee_extensions(ch, alpn)
430
443
  exs = []
431
444
 
432
445
  # server_name
@@ -437,6 +450,9 @@ module TTTLS13
437
450
  exs \
438
451
  << Message::Extension::SupportedGroups.new(@settings[:supported_groups])
439
452
 
453
+ # alpn
454
+ exs << Message::Extension::Alpn.new([alpn]) unless alpn.nil?
455
+
440
456
  Message::Extensions.new(exs)
441
457
  end
442
458
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTTLS13
4
- VERSION = '0.2.2'
4
+ VERSION = '0.2.3'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tttls1.3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - thekuwayama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-29 00:00:00.000000000 Z
11
+ date: 2019-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler