tttls1.3 0.2.12 → 0.2.13

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: 9677aea746ca98f9d18cfc1e841d836291b7692088cea9fcc3122e88b0bcb32a
4
- data.tar.gz: e156e172215e1b76c45a4a43c85e6066499f65e0b0bf8a28c2d6fb524fd8940e
3
+ metadata.gz: d292d936d6b26ed1f6307bde684a4f982ea1ee2a7f287eeb306d33b048f855a3
4
+ data.tar.gz: ef33ef7ce5bd53425d7feb6d7ebf4bca2a3803cf50f930375a441cef0543ab0e
5
5
  SHA512:
6
- metadata.gz: f12cffcb976c740136afd8fa7b139400f58cb1a3795e7e7347192630e90b0c8e6c5138e9b98214bbc2a7f88a91ecd58332390ef1c1239ccf9d56a71f3f342743
7
- data.tar.gz: 5ab10fcdab0e5cac1c4940bb92753c06db1656f615a3146b552b54c119b28483388bbe8b725b8a412b13df0fa3f1f668eaebc7cfb537e10753a3f2e686cf2279
6
+ metadata.gz: 815f58f7d9d0d7c64911979b01304826601767d1397cdeda326856916b15f2d5c8e42b38379d91e9f720c29f2c71f6bdbe308d42e70428413fad345f553e1c42
7
+ data.tar.gz: fcffc6d40024429db1f4a4c5573b0680ce4fb603aa06d9876f274a202726e72078f538222cf0ea974a7bf444b11821350510fb7a89b1384c0bb25ce05ba7877f
@@ -11,15 +11,20 @@ on:
11
11
  jobs:
12
12
  ci:
13
13
  runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ ruby-version: ['2.6.x']
14
17
  steps:
15
- - uses: actions/checkout@v1
16
- - uses: actions/setup-ruby@v1
17
18
  - uses: thekuwayama/openssl@master
18
- with:
19
- ruby-version: '2.6.x'
20
- - run: gem install bundler
21
- - run: bundle install
22
- - run: docker pull thekuwayama/openssl
23
- - run: bundle exec rake
24
- - run: bundle exec rake interop:client
25
- - run: bundle exec rake interop:server
19
+ - name: Set up Ruby
20
+ uses: actions/setup-ruby@v1
21
+ - uses: actions/checkout@v1
22
+ - name: Install dependencies
23
+ run: |
24
+ gem install bundler
25
+ bundle install
26
+ - name: Run test
27
+ run: |
28
+ bundle exec rake
29
+ bundle exec rake interop:client
30
+ bundle exec rake interop:server
@@ -16,7 +16,7 @@ Metrics/AbcSize:
16
16
  Metrics/MethodLength:
17
17
  Max: 30
18
18
 
19
- Naming/UncommunicativeMethodParamName:
19
+ Naming/MethodParameterName:
20
20
  MinNameLength: 1
21
21
 
22
22
  Metrics/BlockLength:
data/Gemfile CHANGED
@@ -10,7 +10,7 @@ group :test do
10
10
  gem 'pry'
11
11
  gem 'pry-byebug'
12
12
  gem 'rspec', '3.8.0'
13
- gem 'rubocop', '0.67.2'
13
+ gem 'rubocop', '0.78.0'
14
14
  end
15
15
 
16
16
  gemspec
data/README.md CHANGED
@@ -119,6 +119,7 @@ tttls1.3 server is configurable using keyword arguments.
119
119
  | `:signature_algorithms` | Array of TTTLS13::SignatureScheme constant | `ECDSA_SECP256R1_SHA256`, `ECDSA_SECP384R1_SHA384`, `ECDSA_SECP521R1_SHA512`, `RSA_PSS_RSAE_SHA256`, `RSA_PSS_RSAE_SHA384`, `RSA_PSS_RSAE_SHA512`, `RSA_PKCS1_SHA256`, `RSA_PKCS1_SHA384`, `RSA_PKCS1_SHA512` | List of supported signature algorithms. |
120
120
  | `:supported_groups` | Array of TTTLS13::NamedGroup constant | `SECP256R1`, `SECP384R1`, `SECP521R1` | List of supported named groups. |
121
121
  | `:alpn` | Array of String | nil | List of supported application protocols. If not needed to check this extension, set nil. |
122
+ | `:process_ocsp_response` | Proc | nil | Proc that gets OpenSSL::OCSP::Response. If not needed to staple OCSP::Response, set nil. |
122
123
  | `:compatibility_mode` | Boolean | true | If needed to send ChangeCipherSpec, set true. |
123
124
  | `:loglevel` | Logger constant | Logger::WARN | If needed to print verbose, set Logger::DEBUG. |
124
125
 
@@ -36,7 +36,7 @@ def recv_http_response(client)
36
36
  parser = HTTP::Parser.new
37
37
  buf = nil
38
38
 
39
- parser.on_headers_complete = proc do |headers|
39
+ parser.on_headers_complete = lambda do |headers|
40
40
  buf =
41
41
  [
42
42
  'HTTP/' + parser.http_version.join('.'),
@@ -47,11 +47,11 @@ def recv_http_response(client)
47
47
  + WEBrick::CRLF
48
48
  end
49
49
 
50
- parser.on_body = proc do |chunk|
50
+ parser.on_body = lambda do |chunk|
51
51
  buf += chunk
52
52
  end
53
53
 
54
- parser.on_message_complete = proc do
54
+ parser.on_message_complete = lambda do
55
55
  client.close
56
56
  end
57
57
 
@@ -11,7 +11,7 @@ settings_2nd = {
11
11
  ca_file: File.exist?(ca_file) ? ca_file : nil,
12
12
  alpn: ['http/1.1']
13
13
  }
14
- process_new_session_ticket = proc do |nst, rms, cs|
14
+ process_new_session_ticket = lambda do |nst, rms, cs|
15
15
  return if Time.now.to_i - nst.timestamp > nst.ticket_lifetime
16
16
 
17
17
  settings_2nd[:ticket] = nst.ticket
@@ -11,7 +11,7 @@ settings_2nd = {
11
11
  ca_file: File.exist?(ca_file) ? ca_file : nil,
12
12
  alpn: ['http/1.1']
13
13
  }
14
- process_new_session_ticket = proc do |nst, rms, cs|
14
+ process_new_session_ticket = lambda do |nst, rms, cs|
15
15
  return if Time.now.to_i - nst.timestamp > nst.ticket_lifetime
16
16
 
17
17
  settings_2nd[:key_share_groups] = [] # empty KeyShareClientHello.client_shares
@@ -7,7 +7,7 @@ hostname, port = (ARGV[0] || 'localhost:4433').split(':')
7
7
  ca_file = __dir__ + '/../tmp/ca.crt'
8
8
  req = simple_http_request(hostname)
9
9
 
10
- process_certificate_status = proc do |res, cert, chain|
10
+ process_certificate_status = lambda do |res, cert, chain|
11
11
  puts 'stapled OCSPResponse: '
12
12
  puts res.basic.status.pretty_inspect unless res.nil?
13
13
  puts '-' * 10
@@ -11,7 +11,7 @@ settings_2nd = {
11
11
  ca_file: File.exist?(ca_file) ? ca_file : nil,
12
12
  alpn: ['http/1.1']
13
13
  }
14
- process_new_session_ticket = proc do |nst, rms, cs|
14
+ process_new_session_ticket = lambda do |nst, rms, cs|
15
15
  return if Time.now.to_i - nst.timestamp > nst.ticket_lifetime
16
16
 
17
17
  settings_2nd[:ticket] = nst.ticket
@@ -26,7 +26,7 @@ Etc.nprocessors.times do
26
26
  server = TTTLS13::Server.new(s, settings)
27
27
  parser = HTTP::Parser.new
28
28
 
29
- parser.on_message_complete = proc do
29
+ parser.on_message_complete = lambda do
30
30
  if !parser.http_method.nil?
31
31
  logger.info 'Receive Request'
32
32
  server.write(simple_http_response('TEST'))
@@ -403,23 +403,16 @@ module TTTLS13
403
403
  # @return [Boolean]
404
404
  #
405
405
  # @example
406
- # meth = Client.method(:softfail_check_certificate_status)
406
+ # m = Client.method(:softfail_check_certificate_status)
407
407
  # Client.new(
408
408
  # socket,
409
409
  # hostname,
410
410
  # check_certificate_status: true,
411
- # process_certificate_status: meth
411
+ # process_certificate_status: m
412
412
  # )
413
- # rubocop: disable Metrics/AbcSize
414
- # rubocop: disable Metrics/CyclomaticComplexity
415
- # rubocop: disable Metrics/PerceivedComplexity
416
413
  def self.softfail_check_certificate_status(res, cert, chain)
417
414
  ocsp_response = res
418
- store = OpenSSL::X509::Store.new
419
- store.set_default_paths
420
- context = OpenSSL::X509::StoreContext.new(store, cert, chain)
421
- context.verify
422
- cid = OpenSSL::OCSP::CertificateId.new(cert, context.chain[1])
415
+ cid = OpenSSL::OCSP::CertificateId.new(cert, chain.first)
423
416
 
424
417
  # When NOT received OCSPResponse in TLS handshake, this method will
425
418
  # send OCSPRequest. If ocsp_uri is NOT presented in Certificate, return
@@ -430,23 +423,25 @@ module TTTLS13
430
423
  return true if uri.nil?
431
424
 
432
425
  begin
433
- Timeout.timeout(2) { ocsp_response = send_ocsp_request(cid, uri) }
426
+ # send OCSP::Request
427
+ ocsp_request = gen_ocsp_request(cid)
428
+ Timeout.timeout(2) do
429
+ ocsp_response = send_ocsp_request(ocsp_request, uri)
430
+ end
431
+
432
+ # check nonce of OCSP::Response
433
+ check_nonce = ocsp_request.check_nonce(ocsp_response.basic)
434
+ return true unless [-1, 1].include?(check_nonce)
434
435
  rescue StandardError
435
436
  return true
436
437
  end
437
438
  end
438
- return false \
439
+ return true \
439
440
  if ocsp_response.status != OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL
440
441
 
441
442
  status = ocsp_response.basic.status.find { |s| s.first.cmp(cid) }
442
- return false if status[1] != OpenSSL::OCSP::V_CERTSTATUS_GOOD
443
- return false if !status[3].nil? && status[3] < Time.now
444
-
445
- ocsp_response.basic.verify(chain, store)
443
+ status[1] != OpenSSL::OCSP::V_CERTSTATUS_REVOKED
446
444
  end
447
- # rubocop: enable Metrics/AbcSize
448
- # rubocop: enable Metrics/CyclomaticComplexity
449
- # rubocop: enable Metrics/PerceivedComplexity
450
445
 
451
446
  private
452
447
 
@@ -479,6 +474,9 @@ module TTTLS13
479
474
  rsl = @settings[:record_size_limit]
480
475
  return false if !rsl.nil? && (rsl < 64 || rsl > 2**14 + 1)
481
476
 
477
+ return false if @settings[:check_certificate_status] &&
478
+ @settings[:process_certificate_status].nil?
479
+
482
480
  true
483
481
  end
484
482
  # rubocop: enable Metrics/AbcSize
@@ -530,7 +528,7 @@ module TTTLS13
530
528
  # rubocop: disable Metrics/MethodLength
531
529
  # rubocop: disable Metrics/PerceivedComplexity
532
530
  def gen_ch_extensions
533
- exs = []
531
+ exs = Message::Extensions.new
534
532
  # server_name
535
533
  exs << Message::Extension::ServerName.new(@hostname)
536
534
 
@@ -580,7 +578,7 @@ module TTTLS13
580
578
  exs << Message::Extension::OCSPStatusRequest.new \
581
579
  if @settings[:check_certificate_status]
582
580
 
583
- [Message::Extensions.new(exs), priv_keys]
581
+ [exs, priv_keys]
584
582
  end
585
583
  # rubocop: enable Metrics/AbcSize
586
584
  # rubocop: enable Metrics/CyclomaticComplexity
@@ -673,7 +671,7 @@ module TTTLS13
673
671
  # @return [TTTLS13::Message::Extensions]
674
672
  # @return [Hash of NamedGroup => OpenSSL::PKey::EC.$Object]
675
673
  def gen_newch_extensions(ch1, hrr)
676
- exs = []
674
+ exs = Message::Extensions.new
677
675
  # key_share
678
676
  if hrr.extensions.include?(Message::ExtensionType::KEY_SHARE)
679
677
  group = hrr.extensions[Message::ExtensionType::KEY_SHARE]
@@ -695,7 +693,7 @@ module TTTLS13
695
693
  if hrr.extensions.include?(Message::ExtensionType::COOKIE)
696
694
 
697
695
  # early_data
698
- new_exs = ch1.extensions.merge(Message::Extensions.new(exs))
696
+ new_exs = ch1.extensions.merge(exs)
699
697
  new_exs.delete(Message::ExtensionType::EARLY_DATA)
700
698
 
701
699
  [new_exs, priv_keys]
@@ -541,19 +541,27 @@ module TTTLS13
541
541
 
542
542
  class << self
543
543
  # @param cid [OpenSSL::OCSP::CertificateId]
544
- # @param uri [String]
545
544
  #
546
- # @return [OpenSSL::OCSP::Response]
547
- def send_ocsp_request(cid, uri)
548
- # generate OCSPRequest
545
+ # @return [OpenSSL::OCSP::Request]
546
+ def gen_ocsp_request(cid)
549
547
  ocsp_request = OpenSSL::OCSP::Request.new
550
548
  ocsp_request.add_certid(cid)
551
549
  ocsp_request.add_nonce
550
+ ocsp_request
551
+ end
552
+
553
+ # @param ocsp_request [OpenSSL::OCSP::Request]
554
+ # @param uri_string [String]
555
+ #
556
+ # @raise [Net::OpenTimeout, OpenSSL::OCSP::OCSPError, URI::$Exception]
557
+ #
558
+ # @return [OpenSSL::OCSP::Response, n
559
+ def send_ocsp_request(ocsp_request, uri_string)
552
560
  # send HTTP POST
553
- uri = URI.parse(uri)
561
+ uri = URI.parse(uri_string)
554
562
  path = uri.path
555
563
  path = '/' if path.nil? || path.empty?
556
- http_response = Net::HTTP.start uri.host, uri.port do |http|
564
+ http_response = Net::HTTP.start(uri.host, uri.port) do |http|
557
565
  http.post(
558
566
  path,
559
567
  ocsp_request.to_der,
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- Dir[File.dirname(__FILE__) + '/cryptograph/*.rb'].each { |f| require f }
3
+ Dir[File.dirname(__FILE__) + '/cryptograph/*.rb'].sort.each { |f| require f }
@@ -78,4 +78,4 @@ module TTTLS13
78
78
  end
79
79
  end
80
80
 
81
- Dir[File.dirname(__FILE__) + '/message/*.rb'].each { |f| require f }
81
+ Dir[File.dirname(__FILE__) + '/message/*.rb'].sort.each { |f| require f }
@@ -8,7 +8,7 @@ module TTTLS13
8
8
  FATAL = "\x02"
9
9
  end
10
10
 
11
- # rubocop: disable Layout/AlignHash
11
+ # rubocop: disable Layout/HashAlignment
12
12
  ALERT_DESCRIPTION = {
13
13
  close_notify: "\x00",
14
14
  unexpected_message: "\x0a",
@@ -38,7 +38,7 @@ module TTTLS13
38
38
  certificate_required: "\x74",
39
39
  no_application_protocol: "\x78"
40
40
  }.freeze
41
- # rubocop: enable Layout/AlignHash
41
+ # rubocop: enable Layout/HashAlignment
42
42
 
43
43
  class Alert
44
44
  attr_reader :level
@@ -44,10 +44,11 @@ module TTTLS13
44
44
  #
45
45
  # @return [TTTLS13::Message::Extensions]
46
46
  # rubocop: disable Metrics/CyclomaticComplexity
47
+ # rubocop: disable Metrics/PerceivedComplexity
47
48
  def self.deserialize(binary, msg_type)
48
49
  raise Error::ErrorAlerts, :internal_error if binary.nil?
49
50
 
50
- extensions = []
51
+ exs = Extensions.new
51
52
  i = 0
52
53
  while i < binary.length
53
54
  raise Error::ErrorAlerts, :decode_error if i + 4 > binary.length
@@ -66,32 +67,41 @@ module TTTLS13
66
67
  ex = Extension::UnknownExtension.new(extension_type: extension_type,
67
68
  extension_data: ex_bin)
68
69
  end
69
- extensions << ex
70
+
71
+ # There MUST NOT be more than one extension of the same type in a
72
+ # given extension block.
73
+ raise Error::ErrorAlerts, :unsupported_extension \
74
+ if exs.include?(extension_type)
75
+
76
+ exs[extension_type] = ex
70
77
  i += ex_len
71
78
  end
72
79
  raise Error::ErrorAlerts, :decode_error unless i == binary.length
73
80
 
74
- Extensions.new(extensions)
81
+ exs
75
82
  end
76
83
  # rubocop: enable Metrics/CyclomaticComplexity
84
+ # rubocop: enable Metrics/PerceivedComplexity
77
85
 
78
86
  # @param key [TTTLS13::Message::ExtensionType]
87
+ # @param default
79
88
  #
80
89
  # @return [TTTLS13::Message::Extension::$Object]
81
- def [](key)
90
+ def fetch(key, default = nil)
82
91
  return nil if super_fetch(key, nil).is_a?(Extension::UnknownExtension)
83
92
 
84
- super_fetch(key, nil)
93
+ super_fetch(key, default)
85
94
  end
86
95
 
87
- # @param key [TTTLS13::Message::ExtensionType]
88
- # @param default
96
+ def [](key)
97
+ fetch(key)
98
+ end
99
+
100
+ # @param ex [TTTLS13::Message::Extension::$Object]
89
101
  #
90
102
  # @return [TTTLS13::Message::Extension::$Object]
91
- def fetch(key, default = nil)
92
- return nil if super_fetch(key, nil).is_a?(Extension::UnknownExtension)
93
-
94
- super_fetch(key, default)
103
+ def <<(ex)
104
+ store(ex.extension_type, ex)
95
105
  end
96
106
 
97
107
  class << self
@@ -111,7 +121,6 @@ module TTTLS13
111
121
  # @return [TTTLS13::Message::Extension::$Object, nil]
112
122
  # rubocop: disable Metrics/CyclomaticComplexity
113
123
  # rubocop: disable Metrics/MethodLength
114
- # rubocop: disable Metrics/PerceivedComplexity
115
124
  def deserialize_extension(binary, extension_type, msg_type)
116
125
  raise Error::ErrorAlerts, :internal_error if binary.nil?
117
126
 
@@ -119,14 +128,15 @@ module TTTLS13
119
128
  when ExtensionType::SERVER_NAME
120
129
  Extension::ServerName.deserialize(binary)
121
130
  when ExtensionType::STATUS_REQUEST
122
- if msg_type == HandshakeType::CLIENT_HELLO # ||
123
- # msg_type == HandshakeType::CERTIFICATE_REQUEST
124
- Extension::OCSPStatusRequest.deserialize(binary)
125
- elsif msg_type == HandshakeType::CERTIFICATE
126
- Extension::OCSPResponse.deserialize(binary)
127
- else
128
- return nil
131
+ if msg_type == HandshakeType::CLIENT_HELLO
132
+ return Extension::OCSPStatusRequest.deserialize(binary)
129
133
  end
134
+
135
+ if msg_type == HandshakeType::CERTIFICATE
136
+ return Extension::OCSPResponse.deserialize(binary)
137
+ end
138
+
139
+ Extension::UnknownExtension.deserialize(binary, extension_type)
130
140
  when ExtensionType::SUPPORTED_GROUPS
131
141
  Extension::SupportedGroups.deserialize(binary)
132
142
  when ExtensionType::SIGNATURE_ALGORITHMS
@@ -155,7 +165,6 @@ module TTTLS13
155
165
  end
156
166
  # rubocop: enable Metrics/CyclomaticComplexity
157
167
  # rubocop: enable Metrics/MethodLength
158
- # rubocop: enable Metrics/PerceivedComplexity
159
168
  end
160
169
  end
161
170
  end
@@ -52,6 +52,7 @@ module TTTLS13
52
52
  signature_algorithms: DEFAULT_SP_SIGNATURE_ALGORITHMS,
53
53
  supported_groups: DEFAULT_SP_NAMED_GROUP_LIST,
54
54
  alpn: nil,
55
+ process_ocsp_response: nil,
55
56
  compatibility_mode: true,
56
57
  loglevel: Logger::WARN
57
58
  }.freeze
@@ -236,10 +237,14 @@ module TTTLS13
236
237
 
237
238
  ch = transcript[CH]
238
239
  rsl = @send_record_size \
239
- unless ch.extensions[Message::ExtensionType::RECORD_SIZE_LIMIT].nil?
240
+ if ch.extensions.include?(Message::ExtensionType::RECORD_SIZE_LIMIT)
240
241
  ee = transcript[EE] = gen_encrypted_extensions(ch, @alpn, rsl)
241
242
  # TODO: [Send CertificateRequest]
242
- ct = transcript[CT] = gen_certificate(@crt, @chain)
243
+
244
+ # status_request
245
+ ocsp_response = fetch_ocsp_response \
246
+ if ch.extensions.include?(Message::ExtensionType::STATUS_REQUEST)
247
+ ct = transcript[CT] = gen_certificate(@crt, @chain, ocsp_response)
243
248
  digest = CipherSuite.digest(@cipher_suite)
244
249
  cv = transcript[CV] = gen_certificate_verify(
245
250
  @key,
@@ -350,7 +355,7 @@ module TTTLS13
350
355
  #
351
356
  # @return [TTTLS13::Message::ServerHello]
352
357
  def send_hello_retry_request(ch1, cipher_suite)
353
- exs = []
358
+ exs = Message::Extensions.new
354
359
  # supported_versions
355
360
  exs << Message::Extension::SupportedVersions.new(
356
361
  msg_type: Message::HandshakeType::SERVER_HELLO
@@ -372,7 +377,7 @@ module TTTLS13
372
377
  random: Message::HRR_RANDOM,
373
378
  legacy_session_id_echo: ch1.legacy_session_id,
374
379
  cipher_suite: cipher_suite,
375
- extensions: Message::Extensions.new(exs)
380
+ extensions: exs
376
381
  )
377
382
  send_handshakes(Message::ContentType::HANDSHAKE, [sh],
378
383
  Cryptograph::Passer.new)
@@ -404,11 +409,16 @@ module TTTLS13
404
409
 
405
410
  # @param crt [OpenSSL::X509::Certificate]
406
411
  # @param chain [Array of OpenSSL::X509::Certificate]
412
+ # @param ocsp_response [OpenSSL::OCSP::Response]
407
413
  #
408
414
  # @return [TTTLS13::Message::Certificate, nil]
409
- def gen_certificate(crt, chain = [])
410
- ces = [crt] + (chain || [])
411
- ces.map! { |c| Message::CertificateEntry.new(c) }
415
+ def gen_certificate(crt, chain = [], ocsp_response = nil)
416
+ exs = Message::Extensions.new
417
+ # status_request
418
+ exs << Message::Extension::OCSPResponse.new(ocsp_response) \
419
+ unless ocsp_response.nil?
420
+ ces = [Message::CertificateEntry.new(crt, exs)] \
421
+ + (chain || []).map { |c| Message::CertificateEntry.new(c) }
412
422
  Message::Certificate.new(certificate_list: ces)
413
423
  end
414
424
 
@@ -444,7 +454,7 @@ module TTTLS13
444
454
  # @return [TTTLS13::Message::Extensions]
445
455
  # @return [OpenSSL::PKey::EC.$Object]
446
456
  def gen_sh_extensions(named_group)
447
- exs = []
457
+ exs = Message::Extensions.new
448
458
  # supported_versions: only TLS 1.3
449
459
  exs << Message::Extension::SupportedVersions.new(
450
460
  msg_type: Message::HandshakeType::SERVER_HELLO
@@ -455,7 +465,7 @@ module TTTLS13
455
465
  = Message::Extension::KeyShare.gen_sh_key_share(named_group)
456
466
  exs << key_share
457
467
 
458
- [Message::Extensions.new(exs), priv_key]
468
+ [exs, priv_key]
459
469
  end
460
470
 
461
471
  # @param ch [TTTLS13::Message::ClientHello]
@@ -464,15 +474,16 @@ module TTTLS13
464
474
  #
465
475
  # @return [TTTLS13::Message::Extensions]
466
476
  def gen_ee_extensions(ch, alpn, record_size_limit)
467
- exs = []
477
+ exs = Message::Extensions.new
468
478
 
469
479
  # server_name
470
480
  exs << Message::Extension::ServerName.new('') \
471
481
  if ch.extensions.include?(Message::ExtensionType::SERVER_NAME)
472
482
 
473
483
  # supported_groups
474
- exs \
475
- << Message::Extension::SupportedGroups.new(@settings[:supported_groups])
484
+ exs << Message::Extension::SupportedGroups.new(
485
+ @settings[:supported_groups]
486
+ )
476
487
 
477
488
  # alpn
478
489
  exs << Message::Extension::Alpn.new([alpn]) unless alpn.nil?
@@ -481,7 +492,7 @@ module TTTLS13
481
492
  exs << Message::Extension::RecordSizeLimit.new(record_size_limit) \
482
493
  unless record_size_limit.nil?
483
494
 
484
- Message::Extensions.new(exs)
495
+ exs
485
496
  end
486
497
 
487
498
  # @param key [OpenSSL::PKey::PKey]
@@ -543,6 +554,11 @@ module TTTLS13
543
554
 
544
555
  matching_san?(crt, server_name)
545
556
  end
557
+
558
+ # @return [OpenSSL::OCSP::Response, nil]
559
+ def fetch_ocsp_response
560
+ @settings[:process_ocsp_response]&.call
561
+ end
546
562
  end
547
563
  # rubocop: enable Metrics/ClassLength
548
564
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TTTLS13
4
- VERSION = '0.2.12'
4
+ VERSION = '0.2.13'
5
5
  end
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require_relative 'spec_helper'
5
+ using Refinements
5
6
 
6
7
  RSpec.describe Extensions do
7
8
  context 'empty extensions' do
@@ -167,4 +168,19 @@ RSpec.describe Extensions do
167
168
  expect(extensions).to include ExtensionType::RECORD_SIZE_LIMIT
168
169
  end
169
170
  end
171
+
172
+ context 'duplicated extension_type' do
173
+ let(:server_name) do
174
+ ServerName.new('example.com')
175
+ end
176
+
177
+ let(:testbinary) do
178
+ server_name.serialize * 2
179
+ end
180
+
181
+ it 'should raise error, if extension_type get duplicated' do
182
+ expect { Extensions.deserialize(testbinary, HandshakeType::CLIENT_HELLO) }
183
+ .to raise_error(ErrorAlerts)
184
+ end
185
+ end
170
186
  end
@@ -187,7 +187,7 @@ RSpec.describe ServerHello do
187
187
  let(:message) do
188
188
  sh = ServerHello.deserialize(TESTBINARY_SERVER_HELLO)
189
189
  extensions = sh.instance_variable_get(:@extensions)
190
- extensions[ExtensionType::SUPPORTED_VERSIONS] = nil
190
+ extensions.delete(ExtensionType::SUPPORTED_VERSIONS)
191
191
  sh.instance_variable_set(:@extensions, extensions)
192
192
  sh
193
193
  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.12
4
+ version: 0.2.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - thekuwayama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-04 00:00:00.000000000 Z
11
+ date: 2020-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler