jwt 2.9.3 → 3.1.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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +108 -47
  3. data/CODE_OF_CONDUCT.md +14 -14
  4. data/CONTRIBUTING.md +9 -10
  5. data/README.md +273 -234
  6. data/UPGRADING.md +47 -0
  7. data/lib/jwt/base64.rb +4 -10
  8. data/lib/jwt/claims/audience.rb +10 -0
  9. data/lib/jwt/claims/crit.rb +35 -0
  10. data/lib/jwt/claims/decode_verifier.rb +3 -3
  11. data/lib/jwt/claims/expiration.rb +10 -0
  12. data/lib/jwt/claims/issued_at.rb +7 -0
  13. data/lib/jwt/claims/issuer.rb +10 -0
  14. data/lib/jwt/claims/jwt_id.rb +10 -0
  15. data/lib/jwt/claims/not_before.rb +10 -0
  16. data/lib/jwt/claims/numeric.rb +9 -19
  17. data/lib/jwt/claims/required.rb +10 -0
  18. data/lib/jwt/claims/subject.rb +10 -0
  19. data/lib/jwt/claims/verifier.rb +6 -7
  20. data/lib/jwt/claims.rb +4 -19
  21. data/lib/jwt/configuration/container.rb +20 -1
  22. data/lib/jwt/configuration/decode_configuration.rb +24 -0
  23. data/lib/jwt/configuration/jwk_configuration.rb +1 -0
  24. data/lib/jwt/configuration.rb +8 -0
  25. data/lib/jwt/decode.rb +42 -79
  26. data/lib/jwt/encode.rb +17 -56
  27. data/lib/jwt/encoded_token.rb +236 -0
  28. data/lib/jwt/error.rb +32 -1
  29. data/lib/jwt/json.rb +1 -1
  30. data/lib/jwt/jwa/ecdsa.rb +31 -13
  31. data/lib/jwt/jwa/hmac.rb +2 -7
  32. data/lib/jwt/jwa/none.rb +1 -0
  33. data/lib/jwt/jwa/ps.rb +3 -3
  34. data/lib/jwt/jwa/rsa.rb +6 -6
  35. data/lib/jwt/jwa/signing_algorithm.rb +3 -1
  36. data/lib/jwt/jwa/unsupported.rb +1 -0
  37. data/lib/jwt/jwa.rb +77 -24
  38. data/lib/jwt/jwk/ec.rb +54 -65
  39. data/lib/jwt/jwk/hmac.rb +5 -6
  40. data/lib/jwt/jwk/key_base.rb +16 -1
  41. data/lib/jwt/jwk/key_finder.rb +35 -8
  42. data/lib/jwt/jwk/kid_as_key_digest.rb +1 -0
  43. data/lib/jwt/jwk/rsa.rb +7 -4
  44. data/lib/jwt/jwk/set.rb +2 -0
  45. data/lib/jwt/jwk.rb +1 -1
  46. data/lib/jwt/token.rb +131 -0
  47. data/lib/jwt/version.rb +24 -19
  48. data/lib/jwt.rb +17 -7
  49. data/ruby-jwt.gemspec +2 -0
  50. metadata +36 -16
  51. data/lib/jwt/claims_validator.rb +0 -16
  52. data/lib/jwt/deprecations.rb +0 -48
  53. data/lib/jwt/jwa/compat.rb +0 -29
  54. data/lib/jwt/jwa/eddsa.rb +0 -34
  55. data/lib/jwt/jwa/hmac_rbnacl.rb +0 -49
  56. data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +0 -46
  57. data/lib/jwt/jwa/wrapper.rb +0 -43
  58. data/lib/jwt/jwk/okp_rbnacl.rb +0 -110
  59. data/lib/jwt/verify.rb +0 -34
data/lib/jwt/token.rb ADDED
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWT
4
+ # Represents a JWT token
5
+ #
6
+ # Basic token signed using the HS256 algorithm:
7
+ #
8
+ # token = JWT::Token.new(payload: {pay: 'load'})
9
+ # token.sign!(algorithm: 'HS256', key: 'secret')
10
+ # token.jwt # => eyJhb....
11
+ #
12
+ # Custom headers will be combined with generated headers:
13
+ # token = JWT::Token.new(payload: {pay: 'load'}, header: {custom: "value"})
14
+ # token.sign!(algorithm: 'HS256', key: 'secret')
15
+ # token.header # => {"custom"=>"value", "alg"=>"HS256"}
16
+ #
17
+ class Token
18
+ # Initializes a new Token instance.
19
+ #
20
+ # @param header [Hash] the header of the JWT token.
21
+ # @param payload [Hash] the payload of the JWT token.
22
+ def initialize(payload:, header: {})
23
+ @header = header&.transform_keys(&:to_s)
24
+ @payload = payload
25
+ end
26
+
27
+ # Returns the decoded signature of the JWT token.
28
+ #
29
+ # @return [String] the decoded signature of the JWT token.
30
+ def signature
31
+ @signature ||= ::JWT::Base64.url_decode(encoded_signature || '')
32
+ end
33
+
34
+ # Returns the encoded signature of the JWT token.
35
+ #
36
+ # @return [String] the encoded signature of the JWT token.
37
+ def encoded_signature
38
+ @encoded_signature ||= ::JWT::Base64.url_encode(signature)
39
+ end
40
+
41
+ # Returns the decoded header of the JWT token.
42
+ #
43
+ # @return [Hash] the header of the JWT token.
44
+ attr_reader :header
45
+
46
+ # Returns the encoded header of the JWT token.
47
+ #
48
+ # @return [String] the encoded header of the JWT token.
49
+ def encoded_header
50
+ @encoded_header ||= ::JWT::Base64.url_encode(JWT::JSON.generate(header))
51
+ end
52
+
53
+ # Returns the payload of the JWT token.
54
+ #
55
+ # @return [Hash] the payload of the JWT token.
56
+ attr_reader :payload
57
+
58
+ # Returns the encoded payload of the JWT token.
59
+ #
60
+ # @return [String] the encoded payload of the JWT token.
61
+ def encoded_payload
62
+ @encoded_payload ||= ::JWT::Base64.url_encode(JWT::JSON.generate(payload))
63
+ end
64
+
65
+ # Returns the signing input of the JWT token.
66
+ #
67
+ # @return [String] the signing input of the JWT token.
68
+ def signing_input
69
+ @signing_input ||= [encoded_header, encoded_payload].join('.')
70
+ end
71
+
72
+ # Returns the JWT token as a string.
73
+ #
74
+ # @return [String] the JWT token as a string.
75
+ # @raise [JWT::EncodeError] if the token is not signed or other encoding issues
76
+ def jwt
77
+ @jwt ||= (@signature && [encoded_header, @detached_payload ? '' : encoded_payload, encoded_signature].join('.')) || raise(::JWT::EncodeError, 'Token is not signed')
78
+ end
79
+
80
+ # Detaches the payload according to https://datatracker.ietf.org/doc/html/rfc7515#appendix-F
81
+ #
82
+ def detach_payload!
83
+ @detached_payload = true
84
+
85
+ nil
86
+ end
87
+
88
+ # Signs the JWT token.
89
+ #
90
+ # @param key [String, JWT::JWK::KeyBase] the key to use for signing.
91
+ # @param algorithm [String, Object] the algorithm to use for signing.
92
+ # @return [void]
93
+ # @raise [JWT::EncodeError] if the token is already signed or other problems when signing
94
+ def sign!(key:, algorithm:)
95
+ raise ::JWT::EncodeError, 'Token already signed' if @signature
96
+
97
+ JWA.create_signer(algorithm: algorithm, key: key).tap do |signer|
98
+ header.merge!(signer.jwa.header) { |_key, old, _new| old }
99
+ @signature = signer.sign(data: signing_input)
100
+ end
101
+
102
+ nil
103
+ end
104
+
105
+ # Verifies the claims of the token.
106
+ # @param options [Array<Symbol>, Hash] the claims to verify.
107
+ # @raise [JWT::DecodeError] if the claims are invalid.
108
+ def verify_claims!(*options)
109
+ Claims::Verifier.verify!(self, *options)
110
+ end
111
+
112
+ # Returns the errors of the claims of the token.
113
+ # @param options [Array<Symbol>, Hash] the claims to verify.
114
+ # @return [Array<Symbol>] the errors of the claims.
115
+ def claim_errors(*options)
116
+ Claims::Verifier.errors(self, *options)
117
+ end
118
+
119
+ # Returns whether the claims of the token are valid.
120
+ # @param options [Array<Symbol>, Hash] the claims to verify.
121
+ # @return [Boolean] whether the claims are valid.
122
+ def valid_claims?(*options)
123
+ claim_errors(*options).empty?
124
+ end
125
+
126
+ # Returns the JWT token as a string.
127
+ #
128
+ # @return [String] the JWT token as a string.
129
+ alias to_s jwt
130
+ end
131
+ end
data/lib/jwt/version.rb CHANGED
@@ -1,44 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Moments version builder module
3
+ # JSON Web Token implementation
4
+ #
5
+ # Should be up to date with the latest spec:
6
+ # https://tools.ietf.org/html/rfc7519
4
7
  module JWT
8
+ # Returns the gem version of the JWT library.
9
+ #
10
+ # @return [Gem::Version] the gem version.
5
11
  def self.gem_version
6
- Gem::Version.new VERSION::STRING
12
+ Gem::Version.new(VERSION::STRING)
7
13
  end
8
14
 
9
- # Moments version builder module
15
+ # Version constants
10
16
  module VERSION
11
- # major version
12
- MAJOR = 2
13
- # minor version
14
- MINOR = 9
15
- # tiny version
16
- TINY = 3
17
- # alpha, beta, etc. tag
17
+ MAJOR = 3
18
+ MINOR = 1
19
+ TINY = 2
18
20
  PRE = nil
19
21
 
20
- # Build version string
21
22
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
22
23
  end
23
24
 
25
+ # Checks if the OpenSSL version is 3 or greater.
26
+ #
27
+ # @return [Boolean] true if OpenSSL version is 3 or greater, false otherwise.
28
+ # @api private
24
29
  def self.openssl_3?
25
30
  return false if OpenSSL::OPENSSL_VERSION.include?('LibreSSL')
26
31
 
27
32
  true if 3 * 0x10000000 <= OpenSSL::OPENSSL_VERSION_NUMBER
28
33
  end
29
34
 
30
- def self.rbnacl?
31
- defined?(::RbNaCl)
32
- end
33
-
34
- def self.rbnacl_6_or_greater?
35
- rbnacl? && ::Gem::Version.new(::RbNaCl::VERSION) >= ::Gem::Version.new('6.0.0')
36
- end
37
-
35
+ # Checks if there is an OpenSSL 3 HMAC empty key regression.
36
+ #
37
+ # @return [Boolean] true if there is an OpenSSL 3 HMAC empty key regression, false otherwise.
38
+ # @api private
38
39
  def self.openssl_3_hmac_empty_key_regression?
39
40
  openssl_3? && openssl_version <= ::Gem::Version.new('3.0.0')
40
41
  end
41
42
 
43
+ # Returns the OpenSSL version.
44
+ #
45
+ # @return [Gem::Version] the OpenSSL version.
46
+ # @api private
42
47
  def self.openssl_version
43
48
  @openssl_version ||= ::Gem::Version.new(OpenSSL::VERSION)
44
49
  end
data/lib/jwt.rb CHANGED
@@ -5,14 +5,12 @@ require 'jwt/base64'
5
5
  require 'jwt/json'
6
6
  require 'jwt/decode'
7
7
  require 'jwt/configuration'
8
- require 'jwt/deprecations'
9
8
  require 'jwt/encode'
10
9
  require 'jwt/error'
11
10
  require 'jwt/jwk'
12
11
  require 'jwt/claims'
13
-
14
- require 'jwt/claims_validator'
15
- require 'jwt/verify'
12
+ require 'jwt/encoded_token'
13
+ require 'jwt/token'
16
14
 
17
15
  # JSON Web Token implementation
18
16
  #
@@ -23,6 +21,13 @@ module JWT
23
21
 
24
22
  module_function
25
23
 
24
+ # Encodes a payload into a JWT.
25
+ #
26
+ # @param payload [Hash] the payload to encode.
27
+ # @param key [String] the key used to sign the JWT.
28
+ # @param algorithm [String] the algorithm used to sign the JWT.
29
+ # @param header_fields [Hash] additional headers to include in the JWT.
30
+ # @return [String] the encoded JWT.
26
31
  def encode(payload, key, algorithm = 'HS256', header_fields = {})
27
32
  Encode.new(payload: payload,
28
33
  key: key,
@@ -30,9 +35,14 @@ module JWT
30
35
  headers: header_fields).segments
31
36
  end
32
37
 
38
+ # Decodes a JWT to extract the payload and header
39
+ #
40
+ # @param jwt [String] the JWT to decode.
41
+ # @param key [String] the key used to verify the JWT.
42
+ # @param verify [Boolean] whether to verify the JWT signature.
43
+ # @param options [Hash] additional options for decoding.
44
+ # @return [Array<Hash>] the decoded payload and headers.
33
45
  def decode(jwt, key = nil, verify = true, options = {}, &keyfinder) # rubocop:disable Style/OptionalBooleanParameter
34
- Deprecations.context do
35
- Decode.new(jwt, key, verify, configuration.decode.to_h.merge(options), &keyfinder).decode_segments
36
- end
46
+ Decode.new(jwt, key, verify, configuration.decode.to_h.merge(options), &keyfinder).decode_segments
37
47
  end
38
48
  end
data/ruby-jwt.gemspec CHANGED
@@ -35,6 +35,8 @@ Gem::Specification.new do |spec|
35
35
 
36
36
  spec.add_development_dependency 'appraisal'
37
37
  spec.add_development_dependency 'bundler'
38
+ spec.add_development_dependency 'irb'
39
+ spec.add_development_dependency 'logger'
38
40
  spec.add_development_dependency 'rake'
39
41
  spec.add_development_dependency 'rspec'
40
42
  spec.add_development_dependency 'rubocop'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.3
4
+ version: 3.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Rudat
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-10-03 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: base64
@@ -52,6 +51,34 @@ dependencies:
52
51
  - - ">="
53
52
  - !ruby/object:Gem::Version
54
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: irb
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'
68
+ - !ruby/object:Gem::Dependency
69
+ name: logger
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
55
82
  - !ruby/object:Gem::Dependency
56
83
  name: rake
57
84
  requirement: !ruby/object:Gem::Requirement
@@ -121,10 +148,12 @@ files:
121
148
  - CONTRIBUTING.md
122
149
  - LICENSE
123
150
  - README.md
151
+ - UPGRADING.md
124
152
  - lib/jwt.rb
125
153
  - lib/jwt/base64.rb
126
154
  - lib/jwt/claims.rb
127
155
  - lib/jwt/claims/audience.rb
156
+ - lib/jwt/claims/crit.rb
128
157
  - lib/jwt/claims/decode_verifier.rb
129
158
  - lib/jwt/claims/expiration.rb
130
159
  - lib/jwt/claims/issued_at.rb
@@ -135,40 +164,33 @@ files:
135
164
  - lib/jwt/claims/required.rb
136
165
  - lib/jwt/claims/subject.rb
137
166
  - lib/jwt/claims/verifier.rb
138
- - lib/jwt/claims_validator.rb
139
167
  - lib/jwt/configuration.rb
140
168
  - lib/jwt/configuration/container.rb
141
169
  - lib/jwt/configuration/decode_configuration.rb
142
170
  - lib/jwt/configuration/jwk_configuration.rb
143
171
  - lib/jwt/decode.rb
144
- - lib/jwt/deprecations.rb
145
172
  - lib/jwt/encode.rb
173
+ - lib/jwt/encoded_token.rb
146
174
  - lib/jwt/error.rb
147
175
  - lib/jwt/json.rb
148
176
  - lib/jwt/jwa.rb
149
- - lib/jwt/jwa/compat.rb
150
177
  - lib/jwt/jwa/ecdsa.rb
151
- - lib/jwt/jwa/eddsa.rb
152
178
  - lib/jwt/jwa/hmac.rb
153
- - lib/jwt/jwa/hmac_rbnacl.rb
154
- - lib/jwt/jwa/hmac_rbnacl_fixed.rb
155
179
  - lib/jwt/jwa/none.rb
156
180
  - lib/jwt/jwa/ps.rb
157
181
  - lib/jwt/jwa/rsa.rb
158
182
  - lib/jwt/jwa/signing_algorithm.rb
159
183
  - lib/jwt/jwa/unsupported.rb
160
- - lib/jwt/jwa/wrapper.rb
161
184
  - lib/jwt/jwk.rb
162
185
  - lib/jwt/jwk/ec.rb
163
186
  - lib/jwt/jwk/hmac.rb
164
187
  - lib/jwt/jwk/key_base.rb
165
188
  - lib/jwt/jwk/key_finder.rb
166
189
  - lib/jwt/jwk/kid_as_key_digest.rb
167
- - lib/jwt/jwk/okp_rbnacl.rb
168
190
  - lib/jwt/jwk/rsa.rb
169
191
  - lib/jwt/jwk/set.rb
170
192
  - lib/jwt/jwk/thumbprint.rb
171
- - lib/jwt/verify.rb
193
+ - lib/jwt/token.rb
172
194
  - lib/jwt/version.rb
173
195
  - lib/jwt/x5c_key_finder.rb
174
196
  - ruby-jwt.gemspec
@@ -177,9 +199,8 @@ licenses:
177
199
  - MIT
178
200
  metadata:
179
201
  bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
180
- changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.9.3/CHANGELOG.md
202
+ changelog_uri: https://github.com/jwt/ruby-jwt/blob/v3.1.2/CHANGELOG.md
181
203
  rubygems_mfa_required: 'true'
182
- post_install_message:
183
204
  rdoc_options: []
184
205
  require_paths:
185
206
  - lib
@@ -194,8 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
215
  - !ruby/object:Gem::Version
195
216
  version: '0'
196
217
  requirements: []
197
- rubygems_version: 3.5.16
198
- signing_key:
218
+ rubygems_version: 3.6.7
199
219
  specification_version: 4
200
220
  summary: JSON Web Token implementation in Ruby
201
221
  test_files: []
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'error'
4
-
5
- module JWT
6
- class ClaimsValidator
7
- def initialize(payload)
8
- @payload = payload
9
- end
10
-
11
- def validate!
12
- Claims.verify_payload!(@payload, :numeric)
13
- true
14
- end
15
- end
16
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- # Deprecations module to handle deprecation warnings in the gem
5
- module Deprecations
6
- class << self
7
- def context
8
- yield.tap { emit_warnings }
9
- ensure
10
- Thread.current[:jwt_warning_store] = nil
11
- end
12
-
13
- def warning(message, only_if_valid: false)
14
- method_name = only_if_valid ? :store : :warn
15
- case JWT.configuration.deprecation_warnings
16
- when :once
17
- return if record_warned(message)
18
- when :warn
19
- # noop
20
- else
21
- return
22
- end
23
-
24
- send(method_name, "[DEPRECATION WARNING] #{message}")
25
- end
26
-
27
- def store(message)
28
- (Thread.current[:jwt_warning_store] ||= []) << message
29
- end
30
-
31
- def emit_warnings
32
- return if Thread.current[:jwt_warning_store].nil?
33
-
34
- Thread.current[:jwt_warning_store].each { |warning| warn(warning) }
35
- end
36
-
37
- private
38
-
39
- def record_warned(message)
40
- @warned ||= []
41
- return true if @warned.include?(message)
42
-
43
- @warned << message
44
- false
45
- end
46
- end
47
- end
48
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module JWA
5
- module Compat
6
- module ClassMethods
7
- def from_algorithm(algorithm)
8
- new(algorithm)
9
- end
10
-
11
- def sign(algorithm, msg, key)
12
- Deprecations.warning('Support for calling sign with positional arguments will be removed in future ruby-jwt versions')
13
-
14
- from_algorithm(algorithm).sign(data: msg, signing_key: key)
15
- end
16
-
17
- def verify(algorithm, key, signing_input, signature)
18
- Deprecations.warning('Support for calling verify with positional arguments will be removed in future ruby-jwt versions')
19
-
20
- from_algorithm(algorithm).verify(data: signing_input, signature: signature, verification_key: key)
21
- end
22
- end
23
-
24
- def self.included(klass)
25
- klass.extend(ClassMethods)
26
- end
27
- end
28
- end
29
- end
data/lib/jwt/jwa/eddsa.rb DELETED
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module JWA
5
- class Eddsa
6
- include JWT::JWA::SigningAlgorithm
7
-
8
- def initialize(alg)
9
- @alg = alg
10
- end
11
-
12
- def sign(data:, signing_key:)
13
- unless signing_key.is_a?(RbNaCl::Signatures::Ed25519::SigningKey)
14
- raise_encode_error!("Key given is a #{signing_key.class} but has to be an RbNaCl::Signatures::Ed25519::SigningKey")
15
- end
16
-
17
- signing_key.sign(data)
18
- end
19
-
20
- def verify(data:, signature:, verification_key:)
21
- unless verification_key.is_a?(RbNaCl::Signatures::Ed25519::VerifyKey)
22
- raise_decode_error!("key given is a #{verification_key.class} but has to be a RbNaCl::Signatures::Ed25519::VerifyKey")
23
- end
24
-
25
- verification_key.verify(signature, data)
26
- rescue RbNaCl::CryptoError
27
- false
28
- end
29
-
30
- register_algorithm(new('ED25519'))
31
- register_algorithm(new('EdDSA'))
32
- end
33
- end
34
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module JWA
5
- class HmacRbNaCl
6
- include JWT::JWA::SigningAlgorithm
7
-
8
- def self.from_algorithm(algorithm)
9
- new(algorithm, ::RbNaCl::HMAC.const_get(algorithm.upcase.gsub('HS', 'SHA')))
10
- end
11
-
12
- def initialize(alg, hmac)
13
- @alg = alg
14
- @hmac = hmac
15
- end
16
-
17
- def sign(data:, signing_key:)
18
- Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
19
- hmac.auth(key_for_rbnacl(hmac, signing_key).encode('binary'), data.encode('binary'))
20
- end
21
-
22
- def verify(data:, signature:, verification_key:)
23
- Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
24
- hmac.verify(key_for_rbnacl(hmac, verification_key).encode('binary'), signature.encode('binary'), data.encode('binary'))
25
- rescue ::RbNaCl::BadAuthenticatorError, ::RbNaCl::LengthError
26
- false
27
- end
28
-
29
- register_algorithm(new('HS512256', ::RbNaCl::HMAC::SHA512256))
30
-
31
- private
32
-
33
- attr_reader :hmac
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 padded_empty_key(length)
45
- Array.new(length, 0x0).pack('C*').encode('binary')
46
- end
47
- end
48
- end
49
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module JWA
5
- class HmacRbNaClFixed
6
- include JWT::JWA::SigningAlgorithm
7
-
8
- def self.from_algorithm(algorithm)
9
- new(algorithm, ::RbNaCl::HMAC.const_get(algorithm.upcase.gsub('HS', 'SHA')))
10
- end
11
-
12
- def initialize(alg, hmac)
13
- @alg = alg
14
- @hmac = hmac
15
- end
16
-
17
- def sign(data:, signing_key:)
18
- signing_key ||= ''
19
- Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
20
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless signing_key.is_a?(String)
21
-
22
- hmac.auth(padded_key_bytes(signing_key, hmac.key_bytes), data.encode('binary'))
23
- end
24
-
25
- def verify(data:, signature:, verification_key:)
26
- verification_key ||= ''
27
- Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
28
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless verification_key.is_a?(String)
29
-
30
- hmac.verify(padded_key_bytes(verification_key, hmac.key_bytes), signature.encode('binary'), data.encode('binary'))
31
- rescue ::RbNaCl::BadAuthenticatorError, ::RbNaCl::LengthError
32
- false
33
- end
34
-
35
- register_algorithm(new('HS512256', ::RbNaCl::HMAC::SHA512256))
36
-
37
- private
38
-
39
- attr_reader :hmac
40
-
41
- def padded_key_bytes(key, bytesize)
42
- key.bytes.fill(0, key.bytesize...bytesize).pack('C*')
43
- end
44
- end
45
- end
46
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module JWT
4
- module JWA
5
- class Wrapper
6
- include SigningAlgorithm
7
-
8
- def initialize(algorithm)
9
- @algorithm = algorithm
10
- end
11
-
12
- def alg
13
- return @algorithm.alg if @algorithm.respond_to?(:alg)
14
-
15
- super
16
- end
17
-
18
- def valid_alg?(alg_to_check)
19
- return @algorithm.valid_alg?(alg_to_check) if @algorithm.respond_to?(:valid_alg?)
20
-
21
- super
22
- end
23
-
24
- def header(*args, **kwargs)
25
- return @algorithm.header(*args, **kwargs) if @algorithm.respond_to?(:header)
26
-
27
- super
28
- end
29
-
30
- def sign(*args, **kwargs)
31
- return @algorithm.sign(*args, **kwargs) if @algorithm.respond_to?(:sign)
32
-
33
- super
34
- end
35
-
36
- def verify(*args, **kwargs)
37
- return @algorithm.verify(*args, **kwargs) if @algorithm.respond_to?(:verify)
38
-
39
- super
40
- end
41
- end
42
- end
43
- end