jwt 2.5.0 → 2.8.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 +92 -23
- data/CONTRIBUTING.md +7 -7
- data/README.md +125 -47
- data/lib/jwt/base64.rb +16 -2
- data/lib/jwt/claims_validator.rb +1 -1
- data/lib/jwt/configuration/container.rb +14 -3
- data/lib/jwt/decode.rb +41 -24
- data/lib/jwt/deprecations.rb +29 -0
- data/lib/jwt/encode.rb +23 -19
- data/lib/jwt/error.rb +1 -0
- data/lib/jwt/{algos → jwa}/ecdsa.rb +19 -7
- data/lib/jwt/jwa/eddsa.rb +42 -0
- data/lib/jwt/jwa/hmac.rb +75 -0
- data/lib/jwt/jwa/hmac_rbnacl.rb +50 -0
- data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +46 -0
- data/lib/jwt/{algos → jwa}/none.rb +4 -2
- data/lib/jwt/jwa/ps.rb +30 -0
- data/lib/jwt/jwa/rsa.rb +25 -0
- data/lib/jwt/{algos → jwa}/unsupported.rb +1 -1
- data/lib/jwt/jwa/wrapper.rb +26 -0
- data/lib/jwt/jwa.rb +62 -0
- data/lib/jwt/jwk/ec.rb +168 -116
- data/lib/jwt/jwk/hmac.rb +64 -28
- data/lib/jwt/jwk/key_base.rb +33 -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/verify.rb +8 -4
- data/lib/jwt/version.rb +20 -3
- data/lib/jwt/x5c_key_finder.rb +0 -3
- data/lib/jwt.rb +1 -0
- data/ruby-jwt.gemspec +11 -4
- metadata +35 -27
- 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/algos/eddsa.rb +0 -35
- data/lib/jwt/algos/hmac.rb +0 -36
- data/lib/jwt/algos/ps.rb +0 -43
- data/lib/jwt/algos/rsa.rb +0 -22
- data/lib/jwt/algos.rb +0 -44
- data/lib/jwt/security_utils.rb +0 -59
- data/lib/jwt/signature.rb +0 -35
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.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: 2024-02-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: base64
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: appraisal
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,7 +67,7 @@ dependencies:
|
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
70
|
+
name: rspec
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - ">="
|
@@ -67,7 +81,7 @@ dependencies:
|
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: rubocop
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
@@ -101,32 +115,13 @@ executables: []
|
|
101
115
|
extensions: []
|
102
116
|
extra_rdoc_files: []
|
103
117
|
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
118
|
- AUTHORS
|
113
|
-
- Appraisals
|
114
119
|
- CHANGELOG.md
|
115
120
|
- CODE_OF_CONDUCT.md
|
116
121
|
- CONTRIBUTING.md
|
117
|
-
- Gemfile
|
118
122
|
- LICENSE
|
119
123
|
- README.md
|
120
|
-
- Rakefile
|
121
124
|
- lib/jwt.rb
|
122
|
-
- lib/jwt/algos.rb
|
123
|
-
- lib/jwt/algos/ecdsa.rb
|
124
|
-
- lib/jwt/algos/eddsa.rb
|
125
|
-
- lib/jwt/algos/hmac.rb
|
126
|
-
- lib/jwt/algos/none.rb
|
127
|
-
- lib/jwt/algos/ps.rb
|
128
|
-
- lib/jwt/algos/rsa.rb
|
129
|
-
- lib/jwt/algos/unsupported.rb
|
130
125
|
- lib/jwt/base64.rb
|
131
126
|
- lib/jwt/claims_validator.rb
|
132
127
|
- lib/jwt/configuration.rb
|
@@ -134,19 +129,31 @@ files:
|
|
134
129
|
- lib/jwt/configuration/decode_configuration.rb
|
135
130
|
- lib/jwt/configuration/jwk_configuration.rb
|
136
131
|
- lib/jwt/decode.rb
|
132
|
+
- lib/jwt/deprecations.rb
|
137
133
|
- lib/jwt/encode.rb
|
138
134
|
- lib/jwt/error.rb
|
139
135
|
- lib/jwt/json.rb
|
136
|
+
- lib/jwt/jwa.rb
|
137
|
+
- lib/jwt/jwa/ecdsa.rb
|
138
|
+
- lib/jwt/jwa/eddsa.rb
|
139
|
+
- lib/jwt/jwa/hmac.rb
|
140
|
+
- lib/jwt/jwa/hmac_rbnacl.rb
|
141
|
+
- lib/jwt/jwa/hmac_rbnacl_fixed.rb
|
142
|
+
- lib/jwt/jwa/none.rb
|
143
|
+
- lib/jwt/jwa/ps.rb
|
144
|
+
- lib/jwt/jwa/rsa.rb
|
145
|
+
- lib/jwt/jwa/unsupported.rb
|
146
|
+
- lib/jwt/jwa/wrapper.rb
|
140
147
|
- lib/jwt/jwk.rb
|
141
148
|
- lib/jwt/jwk/ec.rb
|
142
149
|
- lib/jwt/jwk/hmac.rb
|
143
150
|
- lib/jwt/jwk/key_base.rb
|
144
151
|
- lib/jwt/jwk/key_finder.rb
|
145
152
|
- lib/jwt/jwk/kid_as_key_digest.rb
|
153
|
+
- lib/jwt/jwk/okp_rbnacl.rb
|
146
154
|
- lib/jwt/jwk/rsa.rb
|
155
|
+
- lib/jwt/jwk/set.rb
|
147
156
|
- lib/jwt/jwk/thumbprint.rb
|
148
|
-
- lib/jwt/security_utils.rb
|
149
|
-
- lib/jwt/signature.rb
|
150
157
|
- lib/jwt/verify.rb
|
151
158
|
- lib/jwt/version.rb
|
152
159
|
- lib/jwt/x5c_key_finder.rb
|
@@ -156,7 +163,8 @@ licenses:
|
|
156
163
|
- MIT
|
157
164
|
metadata:
|
158
165
|
bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
|
159
|
-
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.
|
166
|
+
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.8.1/CHANGELOG.md
|
167
|
+
rubygems_mfa_required: 'true'
|
160
168
|
post_install_message:
|
161
169
|
rdoc_options: []
|
162
170
|
require_paths:
|
@@ -172,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
180
|
- !ruby/object:Gem::Version
|
173
181
|
version: '0'
|
174
182
|
requirements: []
|
175
|
-
rubygems_version: 3.3.
|
183
|
+
rubygems_version: 3.3.7
|
176
184
|
signing_key:
|
177
185
|
specification_version: 4
|
178
186
|
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/algos/eddsa.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JWT
|
4
|
-
module Algos
|
5
|
-
module Eddsa
|
6
|
-
module_function
|
7
|
-
|
8
|
-
SUPPORTED = %w[ED25519 EdDSA].freeze
|
9
|
-
|
10
|
-
def sign(to_sign)
|
11
|
-
algorithm, msg, key = to_sign.values
|
12
|
-
if key.class != RbNaCl::Signatures::Ed25519::SigningKey
|
13
|
-
raise EncodeError, "Key given is a #{key.class} but has to be an RbNaCl::Signatures::Ed25519::SigningKey"
|
14
|
-
end
|
15
|
-
unless SUPPORTED.map(&:downcase).map(&:to_sym).include?(algorithm.downcase.to_sym)
|
16
|
-
raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key.primitive} signing key was provided"
|
17
|
-
end
|
18
|
-
|
19
|
-
key.sign(msg)
|
20
|
-
end
|
21
|
-
|
22
|
-
def verify(to_verify)
|
23
|
-
algorithm, public_key, signing_input, signature = to_verify.values
|
24
|
-
unless SUPPORTED.map(&:downcase).map(&:to_sym).include?(algorithm.downcase.to_sym)
|
25
|
-
raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key.primitive} signing key was provided"
|
26
|
-
end
|
27
|
-
raise DecodeError, "key given is a #{public_key.class} but has to be a RbNaCl::Signatures::Ed25519::VerifyKey" if public_key.class != RbNaCl::Signatures::Ed25519::VerifyKey
|
28
|
-
|
29
|
-
public_key.verify(signature, signing_input)
|
30
|
-
rescue RbNaCl::CryptoError
|
31
|
-
false
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/jwt/algos/hmac.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JWT
|
4
|
-
module Algos
|
5
|
-
module Hmac
|
6
|
-
module_function
|
7
|
-
|
8
|
-
SUPPORTED = %w[HS256 HS512256 HS384 HS512].freeze
|
9
|
-
|
10
|
-
def sign(to_sign)
|
11
|
-
algorithm, msg, key = to_sign.values
|
12
|
-
key ||= ''
|
13
|
-
authenticator, padded_key = SecurityUtils.rbnacl_fixup(algorithm, key)
|
14
|
-
if authenticator && padded_key
|
15
|
-
authenticator.auth(padded_key, msg.encode('binary'))
|
16
|
-
else
|
17
|
-
OpenSSL::HMAC.digest(OpenSSL::Digest.new(algorithm.sub('HS', 'sha')), key, msg)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def verify(to_verify)
|
22
|
-
algorithm, public_key, signing_input, signature = to_verify.values
|
23
|
-
authenticator, padded_key = SecurityUtils.rbnacl_fixup(algorithm, public_key)
|
24
|
-
if authenticator && padded_key
|
25
|
-
begin
|
26
|
-
authenticator.verify(padded_key, signature.encode('binary'), signing_input.encode('binary'))
|
27
|
-
rescue RbNaCl::BadAuthenticatorError
|
28
|
-
false
|
29
|
-
end
|
30
|
-
else
|
31
|
-
SecurityUtils.secure_compare(signature, sign(JWT::Signature::ToSign.new(algorithm, signing_input, public_key)))
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
data/lib/jwt/algos/ps.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JWT
|
4
|
-
module Algos
|
5
|
-
module Ps
|
6
|
-
# RSASSA-PSS signing algorithms
|
7
|
-
|
8
|
-
module_function
|
9
|
-
|
10
|
-
SUPPORTED = %w[PS256 PS384 PS512].freeze
|
11
|
-
|
12
|
-
def sign(to_sign)
|
13
|
-
require_openssl!
|
14
|
-
|
15
|
-
algorithm, msg, key = to_sign.values
|
16
|
-
|
17
|
-
key_class = key.class
|
18
|
-
|
19
|
-
raise EncodeError, "The given key is a #{key_class}. It has to be an OpenSSL::PKey::RSA instance." if key_class == String
|
20
|
-
|
21
|
-
translated_algorithm = algorithm.sub('PS', 'sha')
|
22
|
-
|
23
|
-
key.sign_pss(translated_algorithm, msg, salt_length: :digest, mgf1_hash: translated_algorithm)
|
24
|
-
end
|
25
|
-
|
26
|
-
def verify(to_verify)
|
27
|
-
require_openssl!
|
28
|
-
|
29
|
-
SecurityUtils.verify_ps(to_verify.algorithm, to_verify.public_key, to_verify.signing_input, to_verify.signature)
|
30
|
-
end
|
31
|
-
|
32
|
-
def require_openssl!
|
33
|
-
if Object.const_defined?('OpenSSL')
|
34
|
-
if ::Gem::Version.new(OpenSSL::VERSION) < ::Gem::Version.new('2.1')
|
35
|
-
raise JWT::RequiredDependencyError, "You currently have OpenSSL #{OpenSSL::VERSION}. PS support requires >= 2.1"
|
36
|
-
end
|
37
|
-
else
|
38
|
-
raise JWT::RequiredDependencyError, 'PS signing requires OpenSSL +2.1'
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
data/lib/jwt/algos/rsa.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module JWT
|
4
|
-
module Algos
|
5
|
-
module Rsa
|
6
|
-
module_function
|
7
|
-
|
8
|
-
SUPPORTED = %w[RS256 RS384 RS512].freeze
|
9
|
-
|
10
|
-
def sign(to_sign)
|
11
|
-
algorithm, msg, key = to_sign.values
|
12
|
-
raise EncodeError, "The given key is a #{key.class}. It has to be an OpenSSL::PKey::RSA instance." if key.instance_of?(String)
|
13
|
-
|
14
|
-
key.sign(OpenSSL::Digest.new(algorithm.sub('RS', 'sha')), msg)
|
15
|
-
end
|
16
|
-
|
17
|
-
def verify(to_verify)
|
18
|
-
SecurityUtils.verify_rsa(to_verify.algorithm, to_verify.public_key, to_verify.signing_input, to_verify.signature)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
data/lib/jwt/algos.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'jwt/algos/hmac'
|
4
|
-
require 'jwt/algos/eddsa'
|
5
|
-
require 'jwt/algos/ecdsa'
|
6
|
-
require 'jwt/algos/rsa'
|
7
|
-
require 'jwt/algos/ps'
|
8
|
-
require 'jwt/algos/none'
|
9
|
-
require 'jwt/algos/unsupported'
|
10
|
-
|
11
|
-
# JWT::Signature module
|
12
|
-
module JWT
|
13
|
-
# Signature logic for JWT
|
14
|
-
module Algos
|
15
|
-
extend self
|
16
|
-
|
17
|
-
ALGOS = [
|
18
|
-
Algos::Hmac,
|
19
|
-
Algos::Ecdsa,
|
20
|
-
Algos::Rsa,
|
21
|
-
Algos::Eddsa,
|
22
|
-
Algos::Ps,
|
23
|
-
Algos::None,
|
24
|
-
Algos::Unsupported
|
25
|
-
].freeze
|
26
|
-
|
27
|
-
def find(algorithm)
|
28
|
-
indexed[algorithm && algorithm.downcase]
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def indexed
|
34
|
-
@indexed ||= begin
|
35
|
-
fallback = [Algos::Unsupported, nil]
|
36
|
-
ALGOS.each_with_object(Hash.new(fallback)) do |alg, hash|
|
37
|
-
alg.const_get(:SUPPORTED).each do |code|
|
38
|
-
hash[code.downcase] = [alg, code]
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
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
|