jwt 2.5.0 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -5
- data/CONTRIBUTING.md +7 -7
- data/README.md +109 -41
- data/lib/jwt/algos/algo_wrapper.rb +26 -0
- data/lib/jwt/algos/ecdsa.rb +18 -6
- data/lib/jwt/algos/eddsa.rb +2 -4
- data/lib/jwt/algos/hmac.rb +54 -17
- data/lib/jwt/algos/hmac_rbnacl.rb +53 -0
- data/lib/jwt/algos/hmac_rbnacl_fixed.rb +52 -0
- data/lib/jwt/algos/none.rb +3 -1
- data/lib/jwt/algos/ps.rb +7 -9
- data/lib/jwt/algos/rsa.rb +5 -4
- data/lib/jwt/algos.rb +37 -15
- data/lib/jwt/decode.rb +46 -23
- data/lib/jwt/encode.rb +29 -19
- data/lib/jwt/jwk/ec.rb +153 -116
- data/lib/jwt/jwk/hmac.rb +64 -28
- data/lib/jwt/jwk/key_base.rb +31 -11
- data/lib/jwt/jwk/key_finder.rb +19 -35
- data/lib/jwt/jwk/okp_rbnacl.rb +110 -0
- data/lib/jwt/jwk/rsa.rb +142 -77
- data/lib/jwt/jwk/set.rb +80 -0
- data/lib/jwt/jwk.rb +14 -11
- data/lib/jwt/version.rb +18 -2
- data/ruby-jwt.gemspec +8 -4
- metadata +10 -31
- data/.codeclimate.yml +0 -8
- data/.github/workflows/coverage.yml +0 -27
- data/.github/workflows/test.yml +0 -67
- data/.gitignore +0 -13
- data/.reek.yml +0 -22
- data/.rspec +0 -2
- data/.rubocop.yml +0 -67
- data/.sourcelevel.yml +0 -17
- data/Appraisals +0 -13
- data/Gemfile +0 -7
- data/Rakefile +0 -16
- data/lib/jwt/security_utils.rb +0 -59
- data/lib/jwt/signature.rb +0 -35
data/lib/jwt/jwk/set.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module JWT
|
6
|
+
module JWK
|
7
|
+
class Set
|
8
|
+
include Enumerable
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
attr_reader :keys
|
12
|
+
|
13
|
+
def initialize(jwks = nil, options = {}) # rubocop:disable Metrics/CyclomaticComplexity
|
14
|
+
jwks ||= {}
|
15
|
+
|
16
|
+
@keys = case jwks
|
17
|
+
when JWT::JWK::Set # Simple duplication
|
18
|
+
jwks.keys
|
19
|
+
when JWT::JWK::KeyBase # Singleton
|
20
|
+
[jwks]
|
21
|
+
when Hash
|
22
|
+
jwks = jwks.transform_keys(&:to_sym)
|
23
|
+
[*jwks[:keys]].map { |k| JWT::JWK.new(k, nil, options) }
|
24
|
+
when Array
|
25
|
+
jwks.map { |k| JWT::JWK.new(k, nil, options) }
|
26
|
+
else
|
27
|
+
raise ArgumentError, 'Can only create new JWKS from Hash, Array and JWK'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def export(options = {})
|
32
|
+
{ keys: @keys.map { |k| k.export(options) } }
|
33
|
+
end
|
34
|
+
|
35
|
+
def_delegators :@keys, :each, :size, :delete, :dig
|
36
|
+
|
37
|
+
def select!(&block)
|
38
|
+
return @keys.select! unless block
|
39
|
+
|
40
|
+
self if @keys.select!(&block)
|
41
|
+
end
|
42
|
+
|
43
|
+
def reject!(&block)
|
44
|
+
return @keys.reject! unless block
|
45
|
+
|
46
|
+
self if @keys.reject!(&block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def uniq!(&block)
|
50
|
+
self if @keys.uniq!(&block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def merge(enum)
|
54
|
+
@keys += JWT::JWK::Set.new(enum.to_a).keys
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def union(enum)
|
59
|
+
dup.merge(enum)
|
60
|
+
end
|
61
|
+
|
62
|
+
def add(key)
|
63
|
+
@keys << JWT::JWK.new(key)
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def ==(other)
|
68
|
+
other.is_a?(JWT::JWK::Set) && keys.sort == other.keys.sort
|
69
|
+
end
|
70
|
+
|
71
|
+
alias eql? ==
|
72
|
+
alias filter! select!
|
73
|
+
alias length size
|
74
|
+
# For symbolic manipulation
|
75
|
+
alias | union
|
76
|
+
alias + union
|
77
|
+
alias << add
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/jwt/jwk.rb
CHANGED
@@ -1,23 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'jwk/key_finder'
|
4
|
+
require_relative 'jwk/set'
|
4
5
|
|
5
6
|
module JWT
|
6
7
|
module JWK
|
7
8
|
class << self
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
def create_from(key, params = nil, options = {})
|
10
|
+
if key.is_a?(Hash)
|
11
|
+
jwk_kty = key[:kty] || key['kty']
|
12
|
+
raise JWT::JWKError, 'Key type (kty) not provided' unless jwk_kty
|
13
|
+
|
14
|
+
return mappings.fetch(jwk_kty.to_s) do |kty|
|
15
|
+
raise JWT::JWKError, "Key type #{kty} not supported"
|
16
|
+
end.new(key, params, options)
|
17
|
+
end
|
16
18
|
|
17
|
-
|
18
|
-
mappings.fetch(keypair.class) do |klass|
|
19
|
+
mappings.fetch(key.class) do |klass|
|
19
20
|
raise JWT::JWKError, "Cannot create JWK from a #{klass.name}"
|
20
|
-
end.new(
|
21
|
+
end.new(key, params, options)
|
21
22
|
end
|
22
23
|
|
23
24
|
def classes
|
@@ -26,6 +27,7 @@ module JWT
|
|
26
27
|
end
|
27
28
|
|
28
29
|
alias new create_from
|
30
|
+
alias import create_from
|
29
31
|
|
30
32
|
private
|
31
33
|
|
@@ -50,3 +52,4 @@ require_relative 'jwk/key_base'
|
|
50
52
|
require_relative 'jwk/ec'
|
51
53
|
require_relative 'jwk/rsa'
|
52
54
|
require_relative 'jwk/hmac'
|
55
|
+
require_relative 'jwk/okp_rbnacl' if ::JWT.rbnacl?
|
data/lib/jwt/version.rb
CHANGED
@@ -11,9 +11,9 @@ module JWT
|
|
11
11
|
# major version
|
12
12
|
MAJOR = 2
|
13
13
|
# minor version
|
14
|
-
MINOR =
|
14
|
+
MINOR = 7
|
15
15
|
# tiny version
|
16
|
-
TINY =
|
16
|
+
TINY = 1
|
17
17
|
# alpha, beta, etc. tag
|
18
18
|
PRE = nil
|
19
19
|
|
@@ -25,4 +25,20 @@ module JWT
|
|
25
25
|
return false if OpenSSL::OPENSSL_VERSION.include?('LibreSSL')
|
26
26
|
return true if OpenSSL::OPENSSL_VERSION_NUMBER >= 3 * 0x10000000
|
27
27
|
end
|
28
|
+
|
29
|
+
def self.rbnacl?
|
30
|
+
defined?(::RbNaCl)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.rbnacl_6_or_greater?
|
34
|
+
rbnacl? && ::Gem::Version.new(::RbNaCl::VERSION) >= ::Gem::Version.new('6.0.0')
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.openssl_3_hmac_empty_key_regression?
|
38
|
+
openssl_3? && openssl_version <= ::Gem::Version.new('3.0.0')
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.openssl_version
|
42
|
+
@openssl_version ||= ::Gem::Version.new(OpenSSL::VERSION)
|
43
|
+
end
|
28
44
|
end
|
data/ruby-jwt.gemspec
CHANGED
@@ -18,18 +18,22 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.required_ruby_version = '>= 2.5'
|
19
19
|
spec.metadata = {
|
20
20
|
'bug_tracker_uri' => 'https://github.com/jwt/ruby-jwt/issues',
|
21
|
-
'changelog_uri' => "https://github.com/jwt/ruby-jwt/blob/v#{JWT.gem_version}/CHANGELOG.md"
|
21
|
+
'changelog_uri' => "https://github.com/jwt/ruby-jwt/blob/v#{JWT.gem_version}/CHANGELOG.md",
|
22
|
+
'rubygems_mfa_required' => 'true'
|
22
23
|
}
|
23
24
|
|
24
|
-
spec.files = `git ls-files -z`.split("\x0").reject
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
26
|
+
f.match(%r{^(spec|gemfiles|coverage|bin)/}) || # Irrelevant folders
|
27
|
+
f.match(/^\.+/) || # Files and folders starting with .
|
28
|
+
f.match(/^(Appraisals|Gemfile|Rakefile)$/) # Irrelevant files
|
29
|
+
end
|
30
|
+
|
25
31
|
spec.executables = []
|
26
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
27
32
|
spec.require_paths = %w[lib]
|
28
33
|
|
29
34
|
spec.add_development_dependency 'appraisal'
|
30
35
|
spec.add_development_dependency 'bundler'
|
31
36
|
spec.add_development_dependency 'rake'
|
32
|
-
spec.add_development_dependency 'reek'
|
33
37
|
spec.add_development_dependency 'rspec'
|
34
38
|
spec.add_development_dependency 'simplecov'
|
35
39
|
end
|
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.
|
4
|
+
version: 2.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Rudat
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appraisal
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: reek
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: rspec
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,28 +87,20 @@ executables: []
|
|
101
87
|
extensions: []
|
102
88
|
extra_rdoc_files: []
|
103
89
|
files:
|
104
|
-
- ".codeclimate.yml"
|
105
|
-
- ".github/workflows/coverage.yml"
|
106
|
-
- ".github/workflows/test.yml"
|
107
|
-
- ".gitignore"
|
108
|
-
- ".reek.yml"
|
109
|
-
- ".rspec"
|
110
|
-
- ".rubocop.yml"
|
111
|
-
- ".sourcelevel.yml"
|
112
90
|
- AUTHORS
|
113
|
-
- Appraisals
|
114
91
|
- CHANGELOG.md
|
115
92
|
- CODE_OF_CONDUCT.md
|
116
93
|
- CONTRIBUTING.md
|
117
|
-
- Gemfile
|
118
94
|
- LICENSE
|
119
95
|
- README.md
|
120
|
-
- Rakefile
|
121
96
|
- lib/jwt.rb
|
122
97
|
- lib/jwt/algos.rb
|
98
|
+
- lib/jwt/algos/algo_wrapper.rb
|
123
99
|
- lib/jwt/algos/ecdsa.rb
|
124
100
|
- lib/jwt/algos/eddsa.rb
|
125
101
|
- lib/jwt/algos/hmac.rb
|
102
|
+
- lib/jwt/algos/hmac_rbnacl.rb
|
103
|
+
- lib/jwt/algos/hmac_rbnacl_fixed.rb
|
126
104
|
- lib/jwt/algos/none.rb
|
127
105
|
- lib/jwt/algos/ps.rb
|
128
106
|
- lib/jwt/algos/rsa.rb
|
@@ -143,10 +121,10 @@ files:
|
|
143
121
|
- lib/jwt/jwk/key_base.rb
|
144
122
|
- lib/jwt/jwk/key_finder.rb
|
145
123
|
- lib/jwt/jwk/kid_as_key_digest.rb
|
124
|
+
- lib/jwt/jwk/okp_rbnacl.rb
|
146
125
|
- lib/jwt/jwk/rsa.rb
|
126
|
+
- lib/jwt/jwk/set.rb
|
147
127
|
- lib/jwt/jwk/thumbprint.rb
|
148
|
-
- lib/jwt/security_utils.rb
|
149
|
-
- lib/jwt/signature.rb
|
150
128
|
- lib/jwt/verify.rb
|
151
129
|
- lib/jwt/version.rb
|
152
130
|
- lib/jwt/x5c_key_finder.rb
|
@@ -156,7 +134,8 @@ licenses:
|
|
156
134
|
- MIT
|
157
135
|
metadata:
|
158
136
|
bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
|
159
|
-
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.
|
137
|
+
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.7.1/CHANGELOG.md
|
138
|
+
rubygems_mfa_required: 'true'
|
160
139
|
post_install_message:
|
161
140
|
rdoc_options: []
|
162
141
|
require_paths:
|
@@ -172,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
151
|
- !ruby/object:Gem::Version
|
173
152
|
version: '0'
|
174
153
|
requirements: []
|
175
|
-
rubygems_version: 3.3.
|
154
|
+
rubygems_version: 3.3.7
|
176
155
|
signing_key:
|
177
156
|
specification_version: 4
|
178
157
|
summary: JSON Web Token implementation in Ruby
|
data/.codeclimate.yml
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
---
|
2
|
-
name: coverage
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
branches:
|
6
|
-
- "master"
|
7
|
-
jobs:
|
8
|
-
coverage:
|
9
|
-
name: coverage
|
10
|
-
runs-on: ubuntu-20.04
|
11
|
-
env:
|
12
|
-
BUNDLE_GEMFILE: 'gemfiles/rbnacl.gemfile'
|
13
|
-
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
14
|
-
steps:
|
15
|
-
- uses: actions/checkout@v2
|
16
|
-
- name: Install libsodium
|
17
|
-
run: |
|
18
|
-
sudo apt-get update -q
|
19
|
-
sudo apt-get install libsodium-dev -y
|
20
|
-
- name: Set up Ruby
|
21
|
-
uses: ruby/setup-ruby@v1
|
22
|
-
with:
|
23
|
-
ruby-version: "2.7"
|
24
|
-
bundler-cache: true
|
25
|
-
- uses: paambaati/codeclimate-action@v3.0.0
|
26
|
-
with:
|
27
|
-
coverageCommand: bundle exec rspec
|
data/.github/workflows/test.yml
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
---
|
2
|
-
name: test
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
branches:
|
6
|
-
- "*"
|
7
|
-
pull_request:
|
8
|
-
branches:
|
9
|
-
- "*"
|
10
|
-
jobs:
|
11
|
-
lint:
|
12
|
-
name: RuboCop
|
13
|
-
timeout-minutes: 30
|
14
|
-
runs-on: ubuntu-latest
|
15
|
-
steps:
|
16
|
-
- uses: actions/checkout@v3
|
17
|
-
- name: Set up Ruby
|
18
|
-
uses: ruby/setup-ruby@v1
|
19
|
-
with:
|
20
|
-
ruby-version: "3.0"
|
21
|
-
bundler-cache: true
|
22
|
-
- name: Run RuboCop
|
23
|
-
run: bundle exec rubocop
|
24
|
-
test:
|
25
|
-
name: ${{ matrix.os }} - Ruby ${{ matrix.ruby }}
|
26
|
-
runs-on: ${{ matrix.os }}
|
27
|
-
strategy:
|
28
|
-
fail-fast: false
|
29
|
-
matrix:
|
30
|
-
os:
|
31
|
-
- ubuntu-20.04
|
32
|
-
ruby:
|
33
|
-
- "2.5"
|
34
|
-
- "2.6"
|
35
|
-
- "2.7"
|
36
|
-
- "3.0"
|
37
|
-
- "3.1"
|
38
|
-
gemfile:
|
39
|
-
- gemfiles/standalone.gemfile
|
40
|
-
- gemfiles/openssl.gemfile
|
41
|
-
- gemfiles/rbnacl.gemfile
|
42
|
-
experimental: [false]
|
43
|
-
include:
|
44
|
-
- { os: ubuntu-20.04, ruby: "2.7", gemfile: 'gemfiles/rbnacl.gemfile', experimental: false }
|
45
|
-
- { os: ubuntu-22.04, ruby: "3.1", experimental: false }
|
46
|
-
- { os: ubuntu-20.04, ruby: "truffleruby-head", experimental: true }
|
47
|
-
- { os: ubuntu-22.04, ruby: "head", experimental: true }
|
48
|
-
continue-on-error: ${{ matrix.experimental }}
|
49
|
-
env:
|
50
|
-
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
51
|
-
|
52
|
-
steps:
|
53
|
-
- uses: actions/checkout@v3
|
54
|
-
|
55
|
-
- name: Install libsodium
|
56
|
-
run: |
|
57
|
-
sudo apt-get update -q
|
58
|
-
sudo apt-get install libsodium-dev -y
|
59
|
-
|
60
|
-
- name: Set up Ruby
|
61
|
-
uses: ruby/setup-ruby@v1
|
62
|
-
with:
|
63
|
-
ruby-version: ${{ matrix.ruby }}
|
64
|
-
bundler-cache: true
|
65
|
-
|
66
|
-
- name: Run tests
|
67
|
-
run: bundle exec rspec
|
data/.gitignore
DELETED
data/.reek.yml
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
---
|
2
|
-
detectors:
|
3
|
-
TooManyStatements:
|
4
|
-
max_statements: 10
|
5
|
-
UtilityFunction:
|
6
|
-
enabled: false
|
7
|
-
LongParameterList:
|
8
|
-
enabled: false
|
9
|
-
DuplicateMethodCall:
|
10
|
-
max_calls: 2
|
11
|
-
IrresponsibleModule:
|
12
|
-
enabled: false
|
13
|
-
NestedIterators:
|
14
|
-
max_allowed_nesting: 2
|
15
|
-
UnusedParameters:
|
16
|
-
enabled: false
|
17
|
-
FeatureEnvy:
|
18
|
-
enabled: false
|
19
|
-
ControlParameter:
|
20
|
-
enabled: false
|
21
|
-
UnusedPrivateMethod:
|
22
|
-
enabled: false
|
data/.rspec
DELETED
data/.rubocop.yml
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
AllCops:
|
2
|
-
TargetRubyVersion: 2.5
|
3
|
-
NewCops: enable
|
4
|
-
SuggestExtensions: false
|
5
|
-
Exclude:
|
6
|
-
- 'gemfiles/*.gemfile'
|
7
|
-
- 'vendor/**/*'
|
8
|
-
|
9
|
-
Style/Documentation:
|
10
|
-
Enabled: false
|
11
|
-
|
12
|
-
Style/BlockDelimiters:
|
13
|
-
Exclude:
|
14
|
-
- spec/**/*_spec.rb
|
15
|
-
|
16
|
-
Style/GuardClause:
|
17
|
-
Enabled: false
|
18
|
-
|
19
|
-
Style/IfUnlessModifier:
|
20
|
-
Enabled: false
|
21
|
-
|
22
|
-
Style/Lambda:
|
23
|
-
Enabled: false
|
24
|
-
|
25
|
-
Style/RaiseArgs:
|
26
|
-
Enabled: false
|
27
|
-
|
28
|
-
Metrics/AbcSize:
|
29
|
-
Max: 25
|
30
|
-
|
31
|
-
Metrics/ClassLength:
|
32
|
-
Max: 112
|
33
|
-
|
34
|
-
Metrics/ModuleLength:
|
35
|
-
Max: 100
|
36
|
-
|
37
|
-
Metrics/MethodLength:
|
38
|
-
Max: 20
|
39
|
-
|
40
|
-
Metrics/BlockLength:
|
41
|
-
Exclude:
|
42
|
-
- spec/**/*_spec.rb
|
43
|
-
|
44
|
-
Layout/LineLength:
|
45
|
-
Enabled: false
|
46
|
-
|
47
|
-
Layout/EndAlignment:
|
48
|
-
EnforcedStyleAlignWith: variable
|
49
|
-
|
50
|
-
Layout/EmptyLineBetweenDefs:
|
51
|
-
Enabled: true
|
52
|
-
AllowAdjacentOneLineDefs: true
|
53
|
-
|
54
|
-
Style/FormatString:
|
55
|
-
Enabled: false
|
56
|
-
|
57
|
-
Layout/MultilineMethodCallIndentation:
|
58
|
-
EnforcedStyle: indented
|
59
|
-
|
60
|
-
Layout/MultilineOperationIndentation:
|
61
|
-
EnforcedStyle: indented
|
62
|
-
|
63
|
-
Style/WordArray:
|
64
|
-
Enabled: false
|
65
|
-
|
66
|
-
Gemspec/RequireMFA:
|
67
|
-
Enabled: false
|
data/.sourcelevel.yml
DELETED
data/Appraisals
DELETED
data/Gemfile
DELETED
data/Rakefile
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'bundler/setup'
|
4
|
-
require 'bundler/gem_tasks'
|
5
|
-
|
6
|
-
begin
|
7
|
-
require 'rspec/core/rake_task'
|
8
|
-
require 'rubocop/rake_task'
|
9
|
-
|
10
|
-
RSpec::Core::RakeTask.new(:test)
|
11
|
-
RuboCop::RakeTask.new(:rubocop)
|
12
|
-
|
13
|
-
task default: %i[rubocop test]
|
14
|
-
rescue LoadError
|
15
|
-
puts 'RSpec rake tasks not available. Please run "bundle install" to install missing dependencies.'
|
16
|
-
end
|
data/lib/jwt/security_utils.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JWT
|
4
|
-
# Collection of security methods
|
5
|
-
#
|
6
|
-
# @see: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/security_utils.rb
|
7
|
-
module SecurityUtils
|
8
|
-
module_function
|
9
|
-
|
10
|
-
def secure_compare(left, right)
|
11
|
-
left_bytesize = left.bytesize
|
12
|
-
|
13
|
-
return false unless left_bytesize == right.bytesize
|
14
|
-
|
15
|
-
unpacked_left = left.unpack "C#{left_bytesize}"
|
16
|
-
result = 0
|
17
|
-
right.each_byte { |byte| result |= byte ^ unpacked_left.shift }
|
18
|
-
result.zero?
|
19
|
-
end
|
20
|
-
|
21
|
-
def verify_rsa(algorithm, public_key, signing_input, signature)
|
22
|
-
public_key.verify(OpenSSL::Digest.new(algorithm.sub('RS', 'sha')), signature, signing_input)
|
23
|
-
end
|
24
|
-
|
25
|
-
def verify_ps(algorithm, public_key, signing_input, signature)
|
26
|
-
formatted_algorithm = algorithm.sub('PS', 'sha')
|
27
|
-
|
28
|
-
public_key.verify_pss(formatted_algorithm, signature, signing_input, salt_length: :auto, mgf1_hash: formatted_algorithm)
|
29
|
-
end
|
30
|
-
|
31
|
-
def asn1_to_raw(signature, public_key)
|
32
|
-
byte_size = (public_key.group.degree + 7) / 8
|
33
|
-
OpenSSL::ASN1.decode(signature).value.map { |value| value.value.to_s(2).rjust(byte_size, "\x00") }.join
|
34
|
-
end
|
35
|
-
|
36
|
-
def raw_to_asn1(signature, private_key)
|
37
|
-
byte_size = (private_key.group.degree + 7) / 8
|
38
|
-
sig_bytes = signature[0..(byte_size - 1)]
|
39
|
-
sig_char = signature[byte_size..-1] || ''
|
40
|
-
OpenSSL::ASN1::Sequence.new([sig_bytes, sig_char].map { |int| OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(int, 2)) }).to_der
|
41
|
-
end
|
42
|
-
|
43
|
-
def rbnacl_fixup(algorithm, key)
|
44
|
-
algorithm = algorithm.sub('HS', 'SHA').to_sym
|
45
|
-
|
46
|
-
return [] unless defined?(RbNaCl) && RbNaCl::HMAC.constants(false).include?(algorithm)
|
47
|
-
|
48
|
-
authenticator = RbNaCl::HMAC.const_get(algorithm)
|
49
|
-
|
50
|
-
# Fall back to OpenSSL for keys larger than 32 bytes.
|
51
|
-
return [] if key.bytesize > authenticator.key_bytes
|
52
|
-
|
53
|
-
[
|
54
|
-
authenticator,
|
55
|
-
key.bytes.fill(0, key.bytesize...authenticator.key_bytes).pack('C*')
|
56
|
-
]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
data/lib/jwt/signature.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'jwt/security_utils'
|
4
|
-
require 'openssl'
|
5
|
-
require 'jwt/algos'
|
6
|
-
begin
|
7
|
-
require 'rbnacl'
|
8
|
-
rescue LoadError
|
9
|
-
raise if defined?(RbNaCl)
|
10
|
-
end
|
11
|
-
|
12
|
-
# JWT::Signature module
|
13
|
-
module JWT
|
14
|
-
# Signature logic for JWT
|
15
|
-
module Signature
|
16
|
-
module_function
|
17
|
-
|
18
|
-
ToSign = Struct.new(:algorithm, :msg, :key)
|
19
|
-
ToVerify = Struct.new(:algorithm, :public_key, :signing_input, :signature)
|
20
|
-
|
21
|
-
def sign(algorithm, msg, key)
|
22
|
-
algo, code = Algos.find(algorithm)
|
23
|
-
algo.sign ToSign.new(code, msg, key)
|
24
|
-
end
|
25
|
-
|
26
|
-
def verify(algorithm, key, signing_input, signature)
|
27
|
-
algo, code = Algos.find(algorithm)
|
28
|
-
algo.verify(ToVerify.new(code, key, signing_input, signature))
|
29
|
-
rescue OpenSSL::PKey::PKeyError
|
30
|
-
raise JWT::VerificationError, 'Signature verification raised'
|
31
|
-
ensure
|
32
|
-
OpenSSL.errors.clear
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|