jwt 2.4.1 → 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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +102 -14
  3. data/CONTRIBUTING.md +7 -7
  4. data/README.md +154 -37
  5. data/lib/jwt/base64.rb +33 -0
  6. data/lib/jwt/claims_validator.rb +1 -1
  7. data/lib/jwt/configuration/container.rb +32 -0
  8. data/lib/jwt/configuration/decode_configuration.rb +46 -0
  9. data/lib/jwt/configuration/jwk_configuration.rb +27 -0
  10. data/lib/jwt/configuration.rb +15 -0
  11. data/lib/jwt/decode.rb +44 -29
  12. data/lib/jwt/deprecations.rb +29 -0
  13. data/lib/jwt/encode.rb +24 -20
  14. data/lib/jwt/error.rb +1 -0
  15. data/lib/jwt/{algos → jwa}/ecdsa.rb +19 -7
  16. data/lib/jwt/jwa/eddsa.rb +42 -0
  17. data/lib/jwt/jwa/hmac.rb +75 -0
  18. data/lib/jwt/jwa/hmac_rbnacl.rb +50 -0
  19. data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +46 -0
  20. data/lib/jwt/{algos → jwa}/none.rb +4 -2
  21. data/lib/jwt/jwa/ps.rb +30 -0
  22. data/lib/jwt/jwa/rsa.rb +25 -0
  23. data/lib/jwt/{algos → jwa}/unsupported.rb +1 -1
  24. data/lib/jwt/jwa/wrapper.rb +26 -0
  25. data/lib/jwt/jwa.rb +62 -0
  26. data/lib/jwt/jwk/ec.rb +160 -63
  27. data/lib/jwt/jwk/hmac.rb +69 -24
  28. data/lib/jwt/jwk/key_base.rb +45 -7
  29. data/lib/jwt/jwk/key_finder.rb +19 -35
  30. data/lib/jwt/jwk/kid_as_key_digest.rb +15 -0
  31. data/lib/jwt/jwk/okp_rbnacl.rb +110 -0
  32. data/lib/jwt/jwk/rsa.rb +141 -54
  33. data/lib/jwt/jwk/set.rb +80 -0
  34. data/lib/jwt/jwk/thumbprint.rb +26 -0
  35. data/lib/jwt/jwk.rb +14 -11
  36. data/lib/jwt/verify.rb +8 -4
  37. data/lib/jwt/version.rb +23 -1
  38. data/lib/jwt/x5c_key_finder.rb +1 -4
  39. data/lib/jwt.rb +6 -4
  40. data/ruby-jwt.gemspec +11 -4
  41. metadata +41 -27
  42. data/.codeclimate.yml +0 -8
  43. data/.github/workflows/coverage.yml +0 -27
  44. data/.github/workflows/test.yml +0 -66
  45. data/.gitignore +0 -13
  46. data/.reek.yml +0 -22
  47. data/.rspec +0 -2
  48. data/.rubocop.yml +0 -67
  49. data/.sourcelevel.yml +0 -17
  50. data/Appraisals +0 -13
  51. data/Gemfile +0 -7
  52. data/Rakefile +0 -16
  53. data/lib/jwt/algos/eddsa.rb +0 -33
  54. data/lib/jwt/algos/hmac.rb +0 -36
  55. data/lib/jwt/algos/ps.rb +0 -43
  56. data/lib/jwt/algos/rsa.rb +0 -22
  57. data/lib/jwt/algos.rb +0 -44
  58. data/lib/jwt/default_options.rb +0 -18
  59. data/lib/jwt/security_utils.rb +0 -59
  60. 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.1
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: 2022-06-07 00:00:00.000000000 Z
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: reek
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: rspec
84
+ name: rubocop
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
@@ -101,46 +115,45 @@ 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
125
+ - lib/jwt/base64.rb
130
126
  - lib/jwt/claims_validator.rb
127
+ - lib/jwt/configuration.rb
128
+ - lib/jwt/configuration/container.rb
129
+ - lib/jwt/configuration/decode_configuration.rb
130
+ - lib/jwt/configuration/jwk_configuration.rb
131
131
  - lib/jwt/decode.rb
132
- - lib/jwt/default_options.rb
132
+ - lib/jwt/deprecations.rb
133
133
  - lib/jwt/encode.rb
134
134
  - lib/jwt/error.rb
135
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
136
147
  - lib/jwt/jwk.rb
137
148
  - lib/jwt/jwk/ec.rb
138
149
  - lib/jwt/jwk/hmac.rb
139
150
  - lib/jwt/jwk/key_base.rb
140
151
  - lib/jwt/jwk/key_finder.rb
152
+ - lib/jwt/jwk/kid_as_key_digest.rb
153
+ - lib/jwt/jwk/okp_rbnacl.rb
141
154
  - lib/jwt/jwk/rsa.rb
142
- - lib/jwt/security_utils.rb
143
- - lib/jwt/signature.rb
155
+ - lib/jwt/jwk/set.rb
156
+ - lib/jwt/jwk/thumbprint.rb
144
157
  - lib/jwt/verify.rb
145
158
  - lib/jwt/version.rb
146
159
  - lib/jwt/x5c_key_finder.rb
@@ -150,7 +163,8 @@ licenses:
150
163
  - MIT
151
164
  metadata:
152
165
  bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
153
- changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.4.1/CHANGELOG.md
166
+ changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.8.1/CHANGELOG.md
167
+ rubygems_mfa_required: 'true'
154
168
  post_install_message:
155
169
  rdoc_options: []
156
170
  require_paths:
data/.codeclimate.yml DELETED
@@ -1,8 +0,0 @@
1
- plugins:
2
- fixme:
3
- enabled: true
4
- shellcheck:
5
- enabled: true
6
- rubocop:
7
- enabled: true
8
- channel: rubocop-1-23-0
@@ -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
@@ -1,66 +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@v2
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
- strategy:
26
- fail-fast: false
27
- matrix:
28
- ruby:
29
- - 2.5
30
- - 2.6
31
- - 2.7
32
- - "3.0"
33
- - 3.1
34
- gemfile:
35
- - gemfiles/standalone.gemfile
36
- - gemfiles/openssl.gemfile
37
- - gemfiles/rbnacl.gemfile
38
- experimental: [false]
39
- include:
40
- - ruby: 2.7
41
- gemfile: 'gemfiles/rbnacl.gemfile'
42
- - ruby: "ruby-head"
43
- experimental: true
44
- - ruby: "truffleruby-head"
45
- experimental: true
46
- runs-on: ubuntu-20.04
47
- continue-on-error: ${{ matrix.experimental }}
48
- env:
49
- BUNDLE_GEMFILE: ${{ matrix.gemfile }}
50
-
51
- steps:
52
- - uses: actions/checkout@v2
53
-
54
- - name: Install libsodium
55
- run: |
56
- sudo apt-get update -q
57
- sudo apt-get install libsodium-dev -y
58
-
59
- - name: Set up Ruby
60
- uses: ruby/setup-ruby@v1
61
- with:
62
- ruby-version: ${{ matrix.ruby }}
63
- bundler-cache: true
64
-
65
- - name: Run tests
66
- run: bundle exec rspec
data/.gitignore DELETED
@@ -1,13 +0,0 @@
1
- .idea/
2
- jwt.gemspec
3
- pkg
4
- Gemfile.lock
5
- coverage/
6
- .DS_Store
7
- .rbenv-gemsets
8
- .ruby-version
9
- .vscode/
10
- .bundle
11
- *gemfile.lock
12
- .byebug_history
13
- *.gem
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
@@ -1,2 +0,0 @@
1
- --require spec_helper
2
- --color
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: 105
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
@@ -1,17 +0,0 @@
1
- engines:
2
- reek:
3
- enabled: true
4
- fixme:
5
- enabled: true
6
- rubocop:
7
- enabled: true
8
- channel: latest
9
- duplication:
10
- config:
11
- languages:
12
- - ruby
13
- enabled: true
14
- remark-lint:
15
- enabled: false
16
- exclude_paths:
17
- - spec
data/Appraisals DELETED
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- appraise 'standalone' do
4
- # No additions
5
- end
6
-
7
- appraise 'openssl' do
8
- gem 'openssl', '~> 2.1'
9
- end
10
-
11
- appraise 'rbnacl' do
12
- gem 'rbnacl'
13
- end
data/Gemfile DELETED
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- gemspec
6
-
7
- gem 'rubocop', '~> 1.23.0' # Keep .codeclimate.yml channel in sync with this one
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
@@ -1,33 +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
- end
31
- end
32
- end
33
- end
@@ -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
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module DefaultOptions
5
- DEFAULT_OPTIONS = {
6
- verify_expiration: true,
7
- verify_not_before: true,
8
- verify_iss: false,
9
- verify_iat: false,
10
- verify_jti: false,
11
- verify_aud: false,
12
- verify_sub: false,
13
- leeway: 0,
14
- algorithms: ['HS256'],
15
- required_claims: []
16
- }.freeze
17
- end
18
- end
@@ -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