jwt 2.7.0 → 2.10.2

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +155 -24
  3. data/README.md +208 -102
  4. data/lib/jwt/base64.rb +19 -2
  5. data/lib/jwt/claims/audience.rb +30 -0
  6. data/lib/jwt/claims/crit.rb +35 -0
  7. data/lib/jwt/claims/decode_verifier.rb +40 -0
  8. data/lib/jwt/claims/expiration.rb +32 -0
  9. data/lib/jwt/claims/issued_at.rb +22 -0
  10. data/lib/jwt/claims/issuer.rb +34 -0
  11. data/lib/jwt/claims/jwt_id.rb +35 -0
  12. data/lib/jwt/claims/not_before.rb +32 -0
  13. data/lib/jwt/claims/numeric.rb +77 -0
  14. data/lib/jwt/claims/required.rb +33 -0
  15. data/lib/jwt/claims/subject.rb +30 -0
  16. data/lib/jwt/claims/verification_methods.rb +20 -0
  17. data/lib/jwt/claims/verifier.rb +61 -0
  18. data/lib/jwt/claims.rb +74 -0
  19. data/lib/jwt/claims_validator.rb +6 -25
  20. data/lib/jwt/configuration/container.rb +34 -3
  21. data/lib/jwt/configuration/decode_configuration.rb +24 -0
  22. data/lib/jwt/configuration/jwk_configuration.rb +2 -1
  23. data/lib/jwt/configuration.rb +8 -0
  24. data/lib/jwt/decode.rb +34 -82
  25. data/lib/jwt/deprecations.rb +49 -0
  26. data/lib/jwt/encode.rb +18 -67
  27. data/lib/jwt/encoded_token.rb +139 -0
  28. data/lib/jwt/error.rb +35 -0
  29. data/lib/jwt/json.rb +1 -1
  30. data/lib/jwt/jwa/compat.rb +32 -0
  31. data/lib/jwt/jwa/ecdsa.rb +90 -0
  32. data/lib/jwt/jwa/eddsa.rb +35 -0
  33. data/lib/jwt/{algos → jwa}/hmac.rb +28 -19
  34. data/lib/jwt/jwa/hmac_rbnacl.rb +50 -0
  35. data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +47 -0
  36. data/lib/jwt/jwa/none.rb +24 -0
  37. data/lib/jwt/jwa/ps.rb +35 -0
  38. data/lib/jwt/jwa/rsa.rb +35 -0
  39. data/lib/jwt/jwa/signing_algorithm.rb +63 -0
  40. data/lib/jwt/jwa/unsupported.rb +20 -0
  41. data/lib/jwt/jwa/wrapper.rb +44 -0
  42. data/lib/jwt/jwa.rb +58 -0
  43. data/lib/jwt/jwk/ec.rb +44 -30
  44. data/lib/jwt/jwk/hmac.rb +2 -3
  45. data/lib/jwt/jwk/key_base.rb +4 -1
  46. data/lib/jwt/jwk/key_finder.rb +5 -4
  47. data/lib/jwt/jwk/kid_as_key_digest.rb +1 -0
  48. data/lib/jwt/jwk/okp_rbnacl.rb +3 -4
  49. data/lib/jwt/jwk/rsa.rb +2 -3
  50. data/lib/jwt/jwk/set.rb +3 -1
  51. data/lib/jwt/jwk.rb +2 -1
  52. data/lib/jwt/token.rb +112 -0
  53. data/lib/jwt/verify.rb +16 -89
  54. data/lib/jwt/version.rb +33 -11
  55. data/lib/jwt/x5c_key_finder.rb +2 -5
  56. data/lib/jwt.rb +24 -1
  57. data/ruby-jwt.gemspec +4 -0
  58. metadata +76 -19
  59. data/lib/jwt/algos/algo_wrapper.rb +0 -30
  60. data/lib/jwt/algos/ecdsa.rb +0 -62
  61. data/lib/jwt/algos/eddsa.rb +0 -33
  62. data/lib/jwt/algos/hmac_rbnacl.rb +0 -53
  63. data/lib/jwt/algos/hmac_rbnacl_fixed.rb +0 -52
  64. data/lib/jwt/algos/none.rb +0 -19
  65. data/lib/jwt/algos/ps.rb +0 -41
  66. data/lib/jwt/algos/rsa.rb +0 -21
  67. data/lib/jwt/algos/unsupported.rb +0 -19
  68. data/lib/jwt/algos.rb +0 -67
  69. data/lib/jwt/security_utils.rb +0 -32
metadata CHANGED
@@ -1,15 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Rudat
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-02-01 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
13
26
  - !ruby/object:Gem::Dependency
14
27
  name: appraisal
15
28
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +51,20 @@ dependencies:
38
51
  - - ">="
39
52
  - !ruby/object:Gem::Version
40
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: logger
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
41
68
  - !ruby/object:Gem::Dependency
42
69
  name: rake
43
70
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +93,20 @@ dependencies:
66
93
  - - ">="
67
94
  - !ruby/object:Gem::Version
68
95
  version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rubocop
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
69
110
  - !ruby/object:Gem::Dependency
70
111
  name: simplecov
71
112
  requirement: !ruby/object:Gem::Requirement
@@ -94,27 +135,45 @@ files:
94
135
  - LICENSE
95
136
  - README.md
96
137
  - lib/jwt.rb
97
- - lib/jwt/algos.rb
98
- - lib/jwt/algos/algo_wrapper.rb
99
- - lib/jwt/algos/ecdsa.rb
100
- - lib/jwt/algos/eddsa.rb
101
- - lib/jwt/algos/hmac.rb
102
- - lib/jwt/algos/hmac_rbnacl.rb
103
- - lib/jwt/algos/hmac_rbnacl_fixed.rb
104
- - lib/jwt/algos/none.rb
105
- - lib/jwt/algos/ps.rb
106
- - lib/jwt/algos/rsa.rb
107
- - lib/jwt/algos/unsupported.rb
108
138
  - lib/jwt/base64.rb
139
+ - lib/jwt/claims.rb
140
+ - lib/jwt/claims/audience.rb
141
+ - lib/jwt/claims/crit.rb
142
+ - lib/jwt/claims/decode_verifier.rb
143
+ - lib/jwt/claims/expiration.rb
144
+ - lib/jwt/claims/issued_at.rb
145
+ - lib/jwt/claims/issuer.rb
146
+ - lib/jwt/claims/jwt_id.rb
147
+ - lib/jwt/claims/not_before.rb
148
+ - lib/jwt/claims/numeric.rb
149
+ - lib/jwt/claims/required.rb
150
+ - lib/jwt/claims/subject.rb
151
+ - lib/jwt/claims/verification_methods.rb
152
+ - lib/jwt/claims/verifier.rb
109
153
  - lib/jwt/claims_validator.rb
110
154
  - lib/jwt/configuration.rb
111
155
  - lib/jwt/configuration/container.rb
112
156
  - lib/jwt/configuration/decode_configuration.rb
113
157
  - lib/jwt/configuration/jwk_configuration.rb
114
158
  - lib/jwt/decode.rb
159
+ - lib/jwt/deprecations.rb
115
160
  - lib/jwt/encode.rb
161
+ - lib/jwt/encoded_token.rb
116
162
  - lib/jwt/error.rb
117
163
  - lib/jwt/json.rb
164
+ - lib/jwt/jwa.rb
165
+ - lib/jwt/jwa/compat.rb
166
+ - lib/jwt/jwa/ecdsa.rb
167
+ - lib/jwt/jwa/eddsa.rb
168
+ - lib/jwt/jwa/hmac.rb
169
+ - lib/jwt/jwa/hmac_rbnacl.rb
170
+ - lib/jwt/jwa/hmac_rbnacl_fixed.rb
171
+ - lib/jwt/jwa/none.rb
172
+ - lib/jwt/jwa/ps.rb
173
+ - lib/jwt/jwa/rsa.rb
174
+ - lib/jwt/jwa/signing_algorithm.rb
175
+ - lib/jwt/jwa/unsupported.rb
176
+ - lib/jwt/jwa/wrapper.rb
118
177
  - lib/jwt/jwk.rb
119
178
  - lib/jwt/jwk/ec.rb
120
179
  - lib/jwt/jwk/hmac.rb
@@ -125,7 +184,7 @@ files:
125
184
  - lib/jwt/jwk/rsa.rb
126
185
  - lib/jwt/jwk/set.rb
127
186
  - lib/jwt/jwk/thumbprint.rb
128
- - lib/jwt/security_utils.rb
187
+ - lib/jwt/token.rb
129
188
  - lib/jwt/verify.rb
130
189
  - lib/jwt/version.rb
131
190
  - lib/jwt/x5c_key_finder.rb
@@ -135,9 +194,8 @@ licenses:
135
194
  - MIT
136
195
  metadata:
137
196
  bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
138
- changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.7.0/CHANGELOG.md
197
+ changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.10.2/CHANGELOG.md
139
198
  rubygems_mfa_required: 'true'
140
- post_install_message:
141
199
  rdoc_options: []
142
200
  require_paths:
143
201
  - lib
@@ -152,8 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
210
  - !ruby/object:Gem::Version
153
211
  version: '0'
154
212
  requirements: []
155
- rubygems_version: 3.3.7
156
- signing_key:
213
+ rubygems_version: 3.6.7
157
214
  specification_version: 4
158
215
  summary: JSON Web Token implementation in Ruby
159
216
  test_files: []
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module Algos
5
- class AlgoWrapper
6
- attr_reader :alg, :cls
7
-
8
- def initialize(alg, cls)
9
- @alg = alg
10
- @cls = cls
11
- end
12
-
13
- def valid_alg?(alg_to_check)
14
- alg.casecmp(alg_to_check)&.zero? == true
15
- end
16
-
17
- def sign(data:, signing_key:)
18
- cls.sign(alg, data, signing_key)
19
- end
20
-
21
- def verify(data:, signature:, verification_key:)
22
- cls.verify(alg, verification_key, data, signature)
23
- rescue OpenSSL::PKey::PKeyError # These should be moved to the algorithms that actually need this, but left here to ensure nothing will break.
24
- raise JWT::VerificationError, 'Signature verification raised'
25
- ensure
26
- OpenSSL.errors.clear
27
- end
28
- end
29
- end
30
- end
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module Algos
5
- module Ecdsa
6
- module_function
7
-
8
- NAMED_CURVES = {
9
- 'prime256v1' => {
10
- algorithm: 'ES256',
11
- digest: 'sha256'
12
- },
13
- 'secp256r1' => { # alias for prime256v1
14
- algorithm: 'ES256',
15
- digest: 'sha256'
16
- },
17
- 'secp384r1' => {
18
- algorithm: 'ES384',
19
- digest: 'sha384'
20
- },
21
- 'secp521r1' => {
22
- algorithm: 'ES512',
23
- digest: 'sha512'
24
- },
25
- 'secp256k1' => {
26
- algorithm: 'ES256K',
27
- digest: 'sha256'
28
- }
29
- }.freeze
30
-
31
- SUPPORTED = NAMED_CURVES.map { |_, c| c[:algorithm] }.uniq.freeze
32
-
33
- def sign(algorithm, msg, key)
34
- curve_definition = curve_by_name(key.group.curve_name)
35
- key_algorithm = curve_definition[:algorithm]
36
- if algorithm != key_algorithm
37
- raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key_algorithm} signing key was provided"
38
- end
39
-
40
- digest = OpenSSL::Digest.new(curve_definition[:digest])
41
- SecurityUtils.asn1_to_raw(key.dsa_sign_asn1(digest.digest(msg)), key)
42
- end
43
-
44
- def verify(algorithm, public_key, signing_input, signature)
45
- curve_definition = curve_by_name(public_key.group.curve_name)
46
- key_algorithm = curve_definition[:algorithm]
47
- if algorithm != key_algorithm
48
- raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key_algorithm} verification key was provided"
49
- end
50
-
51
- digest = OpenSSL::Digest.new(curve_definition[:digest])
52
- public_key.dsa_verify_asn1(digest.digest(signing_input), SecurityUtils.raw_to_asn1(signature, public_key))
53
- end
54
-
55
- def curve_by_name(name)
56
- NAMED_CURVES.fetch(name) do
57
- raise UnsupportedEcdsaCurve, "The ECDSA curve '#{name}' is not supported"
58
- end
59
- end
60
- end
61
- end
62
- 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(algorithm, msg, key)
11
- if key.class != RbNaCl::Signatures::Ed25519::SigningKey
12
- raise EncodeError, "Key given is a #{key.class} but has to be an RbNaCl::Signatures::Ed25519::SigningKey"
13
- end
14
- unless SUPPORTED.map(&:downcase).map(&:to_sym).include?(algorithm.downcase.to_sym)
15
- raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key.primitive} signing key was provided"
16
- end
17
-
18
- key.sign(msg)
19
- end
20
-
21
- def verify(algorithm, public_key, signing_input, signature)
22
- unless SUPPORTED.map(&:downcase).map(&:to_sym).include?(algorithm.downcase.to_sym)
23
- raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key.primitive} signing key was provided"
24
- end
25
- 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
26
-
27
- public_key.verify(signature, signing_input)
28
- rescue RbNaCl::CryptoError
29
- false
30
- end
31
- end
32
- end
33
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module Algos
5
- module HmacRbNaCl
6
- module_function
7
-
8
- MAPPING = {
9
- 'HS256' => ::RbNaCl::HMAC::SHA256,
10
- 'HS512256' => ::RbNaCl::HMAC::SHA512256,
11
- 'HS384' => nil,
12
- 'HS512' => ::RbNaCl::HMAC::SHA512
13
- }.freeze
14
-
15
- SUPPORTED = MAPPING.keys
16
-
17
- def sign(algorithm, msg, key)
18
- if (hmac = resolve_algorithm(algorithm))
19
- hmac.auth(key_for_rbnacl(hmac, key).encode('binary'), msg.encode('binary'))
20
- else
21
- Hmac.sign(algorithm, msg, key)
22
- end
23
- end
24
-
25
- def verify(algorithm, key, signing_input, signature)
26
- if (hmac = resolve_algorithm(algorithm))
27
- hmac.verify(key_for_rbnacl(hmac, key).encode('binary'), signature.encode('binary'), signing_input.encode('binary'))
28
- else
29
- Hmac.verify(algorithm, key, signing_input, signature)
30
- end
31
- rescue ::RbNaCl::BadAuthenticatorError
32
- false
33
- end
34
-
35
- def key_for_rbnacl(hmac, key)
36
- key ||= ''
37
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
38
-
39
- return padded_empty_key(hmac.key_bytes) if key == ''
40
-
41
- key
42
- end
43
-
44
- def resolve_algorithm(algorithm)
45
- MAPPING.fetch(algorithm)
46
- end
47
-
48
- def padded_empty_key(length)
49
- Array.new(length, 0x0).pack('C*').encode('binary')
50
- end
51
- end
52
- end
53
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module Algos
5
- module HmacRbNaClFixed
6
- module_function
7
-
8
- MAPPING = {
9
- 'HS256' => ::RbNaCl::HMAC::SHA256,
10
- 'HS512256' => ::RbNaCl::HMAC::SHA512256,
11
- 'HS384' => nil,
12
- 'HS512' => ::RbNaCl::HMAC::SHA512
13
- }.freeze
14
-
15
- SUPPORTED = MAPPING.keys
16
-
17
- def sign(algorithm, msg, key)
18
- key ||= ''
19
-
20
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
21
-
22
- if (hmac = resolve_algorithm(algorithm)) && key.bytesize <= hmac.key_bytes
23
- hmac.auth(padded_key_bytes(key, hmac.key_bytes), msg.encode('binary'))
24
- else
25
- Hmac.sign(algorithm, msg, key)
26
- end
27
- end
28
-
29
- def verify(algorithm, key, signing_input, signature)
30
- key ||= ''
31
-
32
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
33
-
34
- if (hmac = resolve_algorithm(algorithm)) && key.bytesize <= hmac.key_bytes
35
- hmac.verify(padded_key_bytes(key, hmac.key_bytes), signature.encode('binary'), signing_input.encode('binary'))
36
- else
37
- Hmac.verify(algorithm, key, signing_input, signature)
38
- end
39
- rescue ::RbNaCl::BadAuthenticatorError
40
- false
41
- end
42
-
43
- def resolve_algorithm(algorithm)
44
- MAPPING.fetch(algorithm)
45
- end
46
-
47
- def padded_key_bytes(key, bytesize)
48
- key.bytes.fill(0, key.bytesize...bytesize).pack('C*')
49
- end
50
- end
51
- end
52
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module Algos
5
- module None
6
- module_function
7
-
8
- SUPPORTED = %w[none].freeze
9
-
10
- def sign(*)
11
- ''
12
- end
13
-
14
- def verify(*)
15
- true
16
- end
17
- end
18
- end
19
- end
data/lib/jwt/algos/ps.rb DELETED
@@ -1,41 +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(algorithm, msg, key)
13
- require_openssl!
14
-
15
- key_class = key.class
16
-
17
- raise EncodeError, "The given key is a #{key_class}. It has to be an OpenSSL::PKey::RSA instance." if key_class == String
18
-
19
- translated_algorithm = algorithm.sub('PS', 'sha')
20
-
21
- key.sign_pss(translated_algorithm, msg, salt_length: :digest, mgf1_hash: translated_algorithm)
22
- end
23
-
24
- def verify(algorithm, public_key, signing_input, signature)
25
- require_openssl!
26
-
27
- SecurityUtils.verify_ps(algorithm, public_key, signing_input, signature)
28
- end
29
-
30
- def require_openssl!
31
- if Object.const_defined?('OpenSSL')
32
- if ::Gem::Version.new(OpenSSL::VERSION) < ::Gem::Version.new('2.1')
33
- raise JWT::RequiredDependencyError, "You currently have OpenSSL #{OpenSSL::VERSION}. PS support requires >= 2.1"
34
- end
35
- else
36
- raise JWT::RequiredDependencyError, 'PS signing requires OpenSSL +2.1'
37
- end
38
- end
39
- end
40
- end
41
- end
data/lib/jwt/algos/rsa.rb DELETED
@@ -1,21 +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(algorithm, msg, key)
11
- raise EncodeError, "The given key is a #{key.class}. It has to be an OpenSSL::PKey::RSA instance." if key.instance_of?(String)
12
-
13
- key.sign(OpenSSL::Digest.new(algorithm.sub('RS', 'sha')), msg)
14
- end
15
-
16
- def verify(algorithm, public_key, signing_input, signature)
17
- SecurityUtils.verify_rsa(algorithm, public_key, signing_input, signature)
18
- end
19
- end
20
- end
21
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module Algos
5
- module Unsupported
6
- module_function
7
-
8
- SUPPORTED = [].freeze
9
-
10
- def sign(*)
11
- raise NotImplementedError, 'Unsupported signing method'
12
- end
13
-
14
- def verify(*)
15
- raise JWT::VerificationError, 'Algorithm not supported'
16
- end
17
- end
18
- end
19
- end
data/lib/jwt/algos.rb DELETED
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- begin
4
- require 'rbnacl'
5
- rescue LoadError
6
- raise if defined?(RbNaCl)
7
- end
8
- require 'openssl'
9
-
10
- require 'jwt/security_utils'
11
- require 'jwt/algos/hmac'
12
- require 'jwt/algos/eddsa'
13
- require 'jwt/algos/ecdsa'
14
- require 'jwt/algos/rsa'
15
- require 'jwt/algos/ps'
16
- require 'jwt/algos/none'
17
- require 'jwt/algos/unsupported'
18
- require 'jwt/algos/algo_wrapper'
19
-
20
- module JWT
21
- module Algos
22
- extend self
23
-
24
- ALGOS = [Algos::Ecdsa,
25
- Algos::Rsa,
26
- Algos::Eddsa,
27
- Algos::Ps,
28
- Algos::None,
29
- Algos::Unsupported].tap do |l|
30
- if ::JWT.rbnacl_6_or_greater?
31
- require_relative 'algos/hmac_rbnacl'
32
- l.unshift(Algos::HmacRbNaCl)
33
- elsif ::JWT.rbnacl?
34
- require_relative 'algos/hmac_rbnacl_fixed'
35
- l.unshift(Algos::HmacRbNaClFixed)
36
- else
37
- l.unshift(Algos::Hmac)
38
- end
39
- end.freeze
40
-
41
- def find(algorithm)
42
- indexed[algorithm && algorithm.downcase]
43
- end
44
-
45
- def create(algorithm)
46
- Algos::AlgoWrapper.new(*find(algorithm))
47
- end
48
-
49
- def implementation?(algorithm)
50
- (algorithm.respond_to?(:valid_alg?) && algorithm.respond_to?(:verify)) ||
51
- (algorithm.respond_to?(:alg) && algorithm.respond_to?(:sign))
52
- end
53
-
54
- private
55
-
56
- def indexed
57
- @indexed ||= begin
58
- fallback = [nil, Algos::Unsupported]
59
- ALGOS.each_with_object(Hash.new(fallback)) do |cls, hash|
60
- cls.const_get(:SUPPORTED).each do |alg|
61
- hash[alg.downcase] = [alg, cls]
62
- end
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,32 +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 verify_rsa(algorithm, public_key, signing_input, signature)
11
- public_key.verify(OpenSSL::Digest.new(algorithm.sub('RS', 'sha')), signature, signing_input)
12
- end
13
-
14
- def verify_ps(algorithm, public_key, signing_input, signature)
15
- formatted_algorithm = algorithm.sub('PS', 'sha')
16
-
17
- public_key.verify_pss(formatted_algorithm, signature, signing_input, salt_length: :auto, mgf1_hash: formatted_algorithm)
18
- end
19
-
20
- def asn1_to_raw(signature, public_key)
21
- byte_size = (public_key.group.degree + 7) / 8
22
- OpenSSL::ASN1.decode(signature).value.map { |value| value.value.to_s(2).rjust(byte_size, "\x00") }.join
23
- end
24
-
25
- def raw_to_asn1(signature, private_key)
26
- byte_size = (private_key.group.degree + 7) / 8
27
- sig_bytes = signature[0..(byte_size - 1)]
28
- sig_char = signature[byte_size..-1] || ''
29
- OpenSSL::ASN1::Sequence.new([sig_bytes, sig_char].map { |int| OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(int, 2)) }).to_der
30
- end
31
- end
32
- end