jwt 2.3.0 → 2.4.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/jwt/signature.rb CHANGED
@@ -13,7 +13,8 @@ end
13
13
  module JWT
14
14
  # Signature logic for JWT
15
15
  module Signature
16
- extend self
16
+ module_function
17
+
17
18
  ToSign = Struct.new(:algorithm, :msg, :key)
18
19
  ToVerify = Struct.new(:algorithm, :public_key, :signing_input, :signature)
19
20
 
@@ -23,13 +24,8 @@ module JWT
23
24
  end
24
25
 
25
26
  def verify(algorithm, key, signing_input, signature)
26
- return true if algorithm.casecmp('none').zero?
27
-
28
- raise JWT::DecodeError, 'No verification key available' unless key
29
-
30
27
  algo, code = Algos.find(algorithm)
31
- verified = algo.verify(ToVerify.new(code, key, signing_input, signature))
32
- raise(JWT::VerificationError, 'Signature verification raised') unless verified
28
+ algo.verify(ToVerify.new(code, key, signing_input, signature))
33
29
  rescue OpenSSL::PKey::PKeyError
34
30
  raise JWT::VerificationError, 'Signature verification raised'
35
31
  ensure
data/lib/jwt/verify.rb CHANGED
@@ -19,6 +19,7 @@ module JWT
19
19
  def verify_claims(payload, options)
20
20
  options.each do |key, val|
21
21
  next unless key.to_s =~ /verify/
22
+
22
23
  Verify.send(key, payload, options) if val
23
24
  end
24
25
  end
@@ -53,9 +54,14 @@ module JWT
53
54
 
54
55
  iss = @payload['iss']
55
56
 
56
- return if Array(options_iss).map(&:to_s).include?(iss.to_s)
57
+ options_iss = Array(options_iss).map { |item| item.is_a?(Symbol) ? item.to_s : item }
57
58
 
58
- raise(JWT::InvalidIssuerError, "Invalid issuer. Expected #{options_iss}, received #{iss || '<none>'}")
59
+ case iss
60
+ when *options_iss
61
+ nil
62
+ else
63
+ raise(JWT::InvalidIssuerError, "Invalid issuer. Expected #{options_iss}, received #{iss || '<none>'}")
64
+ end
59
65
  end
60
66
 
61
67
  def verify_jti
@@ -77,12 +83,14 @@ module JWT
77
83
 
78
84
  def verify_sub
79
85
  return unless (options_sub = @options[:sub])
86
+
80
87
  sub = @payload['sub']
81
88
  raise(JWT::InvalidSubError, "Invalid subject. Expected #{options_sub}, received #{sub || '<none>'}") unless sub.to_s == options_sub.to_s
82
89
  end
83
90
 
84
91
  def verify_required_claims
85
92
  return unless (options_required_claims = @options[:required_claims])
93
+
86
94
  options_required_claims.each do |required_claim|
87
95
  raise(JWT::MissingRequiredClaim, "Missing required claim #{required_claim}") unless @payload.include?(required_claim)
88
96
  end
data/lib/jwt/version.rb CHANGED
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  # Moments version builder module
@@ -12,11 +11,11 @@ module JWT
12
11
  # major version
13
12
  MAJOR = 2
14
13
  # minor version
15
- MINOR = 3
14
+ MINOR = 4
16
15
  # tiny version
17
16
  TINY = 0
18
17
  # alpha, beta, etc. tag
19
- PRE = nil
18
+ PRE = 'beta1'
20
19
 
21
20
  # Build version string
22
21
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+ require 'jwt/error'
5
+
6
+ module JWT
7
+ # If the x5c header certificate chain can be validated by trusted root
8
+ # certificates, and none of the certificates are revoked, returns the public
9
+ # key from the first certificate.
10
+ # See https://tools.ietf.org/html/rfc7515#section-4.1.6
11
+ class X5cKeyFinder
12
+ def initialize(root_certificates, crls = nil)
13
+ raise(ArgumentError, 'Root certificates must be specified') unless root_certificates
14
+
15
+ @store = build_store(root_certificates, crls)
16
+ end
17
+
18
+ def from(x5c_header_or_certificates)
19
+ signing_certificate, *certificate_chain = parse_certificates(x5c_header_or_certificates)
20
+ store_context = OpenSSL::X509::StoreContext.new(@store, signing_certificate, certificate_chain)
21
+
22
+ if store_context.verify
23
+ signing_certificate.public_key
24
+ else
25
+ error = "Certificate verification failed: #{store_context.error_string}."
26
+ if (current_cert = store_context.current_cert)
27
+ error = "#{error} Certificate subject: #{current_cert.subject}."
28
+ end
29
+
30
+ raise(JWT::VerificationError, error)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def build_store(root_certificates, crls)
37
+ store = OpenSSL::X509::Store.new
38
+ store.purpose = OpenSSL::X509::PURPOSE_ANY
39
+ store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK | OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
40
+ root_certificates.each { |certificate| store.add_cert(certificate) }
41
+ crls&.each { |crl| store.add_crl(crl) }
42
+ store
43
+ end
44
+
45
+ def parse_certificates(x5c_header_or_certificates)
46
+ if x5c_header_or_certificates.all? { |obj| obj.is_a?(OpenSSL::X509::Certificate) }
47
+ x5c_header_or_certificates
48
+ else
49
+ x5c_header_or_certificates.map do |encoded|
50
+ OpenSSL::X509::Certificate.new(::Base64.strict_decode64(encoded))
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
data/lib/jwt.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'jwt/base64'
3
+ require 'base64'
4
4
  require 'jwt/json'
5
5
  require 'jwt/decode'
6
6
  require 'jwt/default_options'
data/ruby-jwt.gemspec CHANGED
@@ -1,4 +1,6 @@
1
- lib = File.expand_path('../lib/', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'jwt/version'
4
6
 
@@ -13,7 +15,7 @@ Gem::Specification.new do |spec|
13
15
  spec.description = 'A pure ruby implementation of the RFC 7519 OAuth JSON Web Token (JWT) standard.'
14
16
  spec.homepage = 'https://github.com/jwt/ruby-jwt'
15
17
  spec.license = 'MIT'
16
- spec.required_ruby_version = '>= 2.1'
18
+ spec.required_ruby_version = '>= 2.5'
17
19
  spec.metadata = {
18
20
  'bug_tracker_uri' => 'https://github.com/jwt/ruby-jwt/issues',
19
21
  'changelog_uri' => "https://github.com/jwt/ruby-jwt/blob/v#{JWT.gem_version}/CHANGELOG.md"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Rudat
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-03 00:00:00.000000000 Z
11
+ date: 2022-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -87,6 +87,8 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
+ - ".codeclimate.yml"
91
+ - ".github/workflows/coverage.yml"
90
92
  - ".github/workflows/test.yml"
91
93
  - ".gitignore"
92
94
  - ".rspec"
@@ -96,6 +98,7 @@ files:
96
98
  - AUTHORS
97
99
  - Appraisals
98
100
  - CHANGELOG.md
101
+ - CODE_OF_CONDUCT.md
99
102
  - Gemfile
100
103
  - LICENSE
101
104
  - README.md
@@ -109,7 +112,6 @@ files:
109
112
  - lib/jwt/algos/ps.rb
110
113
  - lib/jwt/algos/rsa.rb
111
114
  - lib/jwt/algos/unsupported.rb
112
- - lib/jwt/base64.rb
113
115
  - lib/jwt/claims_validator.rb
114
116
  - lib/jwt/decode.rb
115
117
  - lib/jwt/default_options.rb
@@ -126,13 +128,14 @@ files:
126
128
  - lib/jwt/signature.rb
127
129
  - lib/jwt/verify.rb
128
130
  - lib/jwt/version.rb
131
+ - lib/jwt/x5c_key_finder.rb
129
132
  - ruby-jwt.gemspec
130
133
  homepage: https://github.com/jwt/ruby-jwt
131
134
  licenses:
132
135
  - MIT
133
136
  metadata:
134
137
  bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
135
- changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.3.0/CHANGELOG.md
138
+ changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.4.0.beta1/CHANGELOG.md
136
139
  post_install_message:
137
140
  rdoc_options: []
138
141
  require_paths:
@@ -141,12 +144,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
144
  requirements:
142
145
  - - ">="
143
146
  - !ruby/object:Gem::Version
144
- version: '2.1'
147
+ version: '2.5'
145
148
  required_rubygems_version: !ruby/object:Gem::Requirement
146
149
  requirements:
147
- - - ">="
150
+ - - ">"
148
151
  - !ruby/object:Gem::Version
149
- version: '0'
152
+ version: 1.3.1
150
153
  requirements: []
151
154
  rubygems_version: 3.2.19
152
155
  signing_key:
data/lib/jwt/base64.rb DELETED
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
-
5
- module JWT
6
- # Base64 helpers
7
- class Base64
8
- class << self
9
- def url_encode(str)
10
- ::Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
11
- end
12
-
13
- def url_decode(str)
14
- str += '=' * (4 - str.length.modulo(4))
15
- ::Base64.decode64(str.tr('-_', '+/'))
16
- end
17
- end
18
- end
19
- end