jwt 3.1.1 → 3.2.0
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 +31 -7
- data/CONTRIBUTING.md +2 -2
- data/README.md +1 -1
- data/lib/jwt/configuration/decode_configuration.rb +7 -2
- data/lib/jwt/decode.rb +7 -1
- data/lib/jwt/encoded_token/claims_context.rb +23 -0
- data/lib/jwt/encoded_token.rb +2 -16
- data/lib/jwt/jwa/ecdsa.rb +3 -3
- data/lib/jwt/jwa/hmac.rb +29 -7
- data/lib/jwt/jwa/rsa.rb +3 -3
- data/lib/jwt/jwa/signer_context.rb +19 -0
- data/lib/jwt/jwa/verifier_context.rb +21 -0
- data/lib/jwt/jwa.rb +2 -30
- data/lib/jwt/jwk/ec.rb +2 -2
- data/lib/jwt/jwk/rsa.rb +1 -1
- data/lib/jwt/version.rb +2 -10
- data/lib/jwt/x5c_key_finder.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0bb396cd444a952a2c732720675f053ce5c4557978acf54acc0753a98b81f402
|
|
4
|
+
data.tar.gz: deeb4ea2635a1620f8dab94b4b7b2d6b7a01087ea0f45b9f79b408c9a7b23c25
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d9913bf66785a88c127148c5a4a3fd6dcd9a28820f53c20635ab5469cebdfb159366566ba8b198154c9a541927224c11e75ced5c9f5b69c1d32a9e01764ca0dd
|
|
7
|
+
data.tar.gz: e2d4765fa99b67229f3204b917aea480a1d4027c23a216f307f92d6ffa8acd049b72071377d7e0c4c8fcba5eb845f9751c944dbc87e9a597020665859edd40c1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v3.2.0](https://github.com/jwt/ruby-jwt/tree/v3.2.0) (2026-05-13)
|
|
4
|
+
|
|
5
|
+
[Full Changelog](https://github.com/jwt/ruby-jwt/compare/v3.1.2...v3.2.0)
|
|
6
|
+
|
|
7
|
+
**Features:**
|
|
8
|
+
|
|
9
|
+
- Add `enforce_hmac_key_length` configuration option [#716](https://github.com/jwt/ruby-jwt/pull/716) - ([@304](https://github.com/304))
|
|
10
|
+
|
|
11
|
+
**Fixes and enhancements:**
|
|
12
|
+
|
|
13
|
+
- Reject `nil` and empty HMAC keys when signing and verifying ([CVE-2026-45363](https://www.cve.org/CVERecord?id=CVE-2026-45363) / [GHSA-c32j-vqhx-rx3x](https://github.com/jwt/ruby-jwt/security/advisories/GHSA-c32j-vqhx-rx3x))
|
|
14
|
+
- Fix compatibility with the openssl 4.0 gem [#706](https://github.com/jwt/ruby-jwt/pull/706)
|
|
15
|
+
- Test against Ruby 4.0 on CI [#707](https://github.com/jwt/ruby-jwt/pull/707)
|
|
16
|
+
- Fix type error when header is not a JSON object [#715](https://github.com/jwt/ruby-jwt/pull/715) - ([@304](https://github.com/304))
|
|
17
|
+
|
|
18
|
+
## [v3.1.2](https://github.com/jwt/ruby-jwt/tree/v3.1.2) (2025-06-28)
|
|
19
|
+
|
|
20
|
+
[Full Changelog](https://github.com/jwt/ruby-jwt/compare/v3.1.1...v3.1.2)
|
|
21
|
+
|
|
22
|
+
**Fixes and enhancements:**
|
|
23
|
+
|
|
24
|
+
- Avoid using the same digest across calls in JWT::JWA::Ecdsa and JWT::JWA::Rsa [#697](https://github.com/jwt/ruby-jwt/pull/697)
|
|
25
|
+
- Fix signing with a EC JWK [#699](https://github.com/jwt/ruby-jwt/pull/699) ([@anakinj](https://github.com/anakinj))
|
|
26
|
+
|
|
3
27
|
## [v3.1.1](https://github.com/jwt/ruby-jwt/tree/v3.1.1) (2025-06-24)
|
|
4
28
|
|
|
5
29
|
[Full Changelog](https://github.com/jwt/ruby-jwt/compare/v3.1.0...v3.1.1)
|
|
@@ -65,7 +89,7 @@ Take a look at the [upgrade guide](UPGRADING.md) for more details.
|
|
|
65
89
|
- JWT::Token and JWT::EncodedToken for signing and verifying tokens [#621](https://github.com/jwt/ruby-jwt/pull/621) ([@anakinj](https://github.com/anakinj))
|
|
66
90
|
- Detached payload support for JWT::Token and JWT::EncodedToken [#630](https://github.com/jwt/ruby-jwt/pull/630) ([@anakinj](https://github.com/anakinj))
|
|
67
91
|
- Skip decoding payload if b64 header is present and false [#631](https://github.com/jwt/ruby-jwt/pull/631) ([@anakinj](https://github.com/anakinj))
|
|
68
|
-
- Remove a few custom
|
|
92
|
+
- Remove a few custom RuboCop configs [#638](https://github.com/jwt/ruby-jwt/pull/638) ([@anakinj](https://github.com/anakinj))
|
|
69
93
|
|
|
70
94
|
**Fixes and enhancements:**
|
|
71
95
|
|
|
@@ -343,7 +367,7 @@ Take a look at the [upgrade guide](UPGRADING.md) for more details.
|
|
|
343
367
|
**Implemented enhancements:**
|
|
344
368
|
|
|
345
369
|
- JWK does not decode. [\#332](https://github.com/jwt/ruby-jwt/issues/332)
|
|
346
|
-
- Inconsistent use of symbol and string keys in args \(exp and
|
|
370
|
+
- Inconsistent use of symbol and string keys in args \(exp and algorithm\). [\#331](https://github.com/jwt/ruby-jwt/issues/331)
|
|
347
371
|
- Pin simplecov to \< 0.18 [\#356](https://github.com/jwt/ruby-jwt/pull/356) ([anakinj](https://github.com/anakinj))
|
|
348
372
|
- verifies algorithm before evaluating keyfinder [\#346](https://github.com/jwt/ruby-jwt/pull/346) ([jb08](https://github.com/jb08))
|
|
349
373
|
- Update Rails 6 appraisal to use actual release version [\#336](https://github.com/jwt/ruby-jwt/pull/336) ([smudge](https://github.com/smudge))
|
|
@@ -458,7 +482,7 @@ Take a look at the [upgrade guide](UPGRADING.md) for more details.
|
|
|
458
482
|
- 'DecodeError'will replace 'ExpiredSignature' [\#260](https://github.com/jwt/ruby-jwt/issues/260)
|
|
459
483
|
- TypeError: no implicit conversion of OpenSSL::PKey::RSA into String [\#259](https://github.com/jwt/ruby-jwt/issues/259)
|
|
460
484
|
- NameError: uninitialized constant JWT::Algos::Eddsa::RbNaCl [\#258](https://github.com/jwt/ruby-jwt/issues/258)
|
|
461
|
-
- Get new token if
|
|
485
|
+
- Get new token if current token expired [\#256](https://github.com/jwt/ruby-jwt/issues/256)
|
|
462
486
|
- Infer algorithm from header [\#254](https://github.com/jwt/ruby-jwt/issues/254)
|
|
463
487
|
- Why is the result of decode is an array? [\#252](https://github.com/jwt/ruby-jwt/issues/252)
|
|
464
488
|
- Add support for headless token [\#251](https://github.com/jwt/ruby-jwt/issues/251)
|
|
@@ -677,8 +701,8 @@ Take a look at the [upgrade guide](UPGRADING.md) for more details.
|
|
|
677
701
|
**Implemented enhancements:**
|
|
678
702
|
|
|
679
703
|
- Refactor obsolete code for ruby 1.8 support [\#120](https://github.com/jwt/ruby-jwt/issues/120)
|
|
680
|
-
- Fix "
|
|
681
|
-
- Fix "
|
|
704
|
+
- Fix "RuboCop/Metrics/CyclomaticComplexity" issue in lib/jwt.rb [\#106](https://github.com/jwt/ruby-jwt/issues/106)
|
|
705
|
+
- Fix "RuboCop/Metrics/CyclomaticComplexity" issue in lib/jwt.rb [\#105](https://github.com/jwt/ruby-jwt/issues/105)
|
|
682
706
|
- Allow a proc to be passed for JTI verification [\#126](https://github.com/jwt/ruby-jwt/pull/126) ([yahooguntu](https://github.com/yahooguntu))
|
|
683
707
|
- Relax restrictions on "jti" claim verification [\#113](https://github.com/jwt/ruby-jwt/pull/113) ([lwe](https://github.com/lwe))
|
|
684
708
|
|
|
@@ -824,13 +848,13 @@ Take a look at the [upgrade guide](UPGRADING.md) for more details.
|
|
|
824
848
|
- Signature Verification to Return Verification Error rather than decode error [\#57](https://github.com/jwt/ruby-jwt/issues/57)
|
|
825
849
|
- Incorrect readme for leeway [\#55](https://github.com/jwt/ruby-jwt/issues/55)
|
|
826
850
|
- What is the reason behind stripping the = in base64 encoding? [\#54](https://github.com/jwt/ruby-jwt/issues/54)
|
|
827
|
-
-
|
|
851
|
+
- Preparations for version 2.x [\#50](https://github.com/jwt/ruby-jwt/issues/50)
|
|
828
852
|
- Release a new version [\#47](https://github.com/jwt/ruby-jwt/issues/47)
|
|
829
853
|
- Catch up for ActiveWhatever 4.1.1 series [\#40](https://github.com/jwt/ruby-jwt/issues/40)
|
|
830
854
|
|
|
831
855
|
**Merged pull requests:**
|
|
832
856
|
|
|
833
|
-
- raise verification error for
|
|
857
|
+
- raise verification error for signature verification [\#58](https://github.com/jwt/ruby-jwt/pull/58) ([punkle](https://github.com/punkle))
|
|
834
858
|
- Added support for not before claim verification [\#56](https://github.com/jwt/ruby-jwt/pull/56) ([punkle](https://github.com/punkle))
|
|
835
859
|
|
|
836
860
|
## [jwt-1.2.1](https://github.com/jwt/ruby-jwt/tree/jwt-1.2.1) (2015-01-22)
|
data/CONTRIBUTING.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Forking the project
|
|
4
4
|
|
|
5
|
-
Fork the project on GitHub and clone your own fork.
|
|
5
|
+
Fork the project on GitHub and clone your own fork. Instructions on forking can be found from the [GitHub Docs](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
git clone git@github.com:you/ruby-jwt.git
|
|
@@ -28,7 +28,7 @@ Before you start with your implementation make sure you are able to get a succes
|
|
|
28
28
|
|
|
29
29
|
The tests are written with rspec and [Appraisal](https://github.com/thoughtbot/appraisal) is used to ensure compatibility with 3rd party dependencies providing cryptographic features.
|
|
30
30
|
|
|
31
|
-
[
|
|
31
|
+
[RuboCop](https://github.com/rubocop/rubocop) is used to enforce the Ruby style.
|
|
32
32
|
|
|
33
33
|
To run the complete set of tests and linter run the following
|
|
34
34
|
|
data/README.md
CHANGED
|
@@ -265,7 +265,7 @@ jwk = JWT::JWK.import(JSON.parse(jwk_json))
|
|
|
265
265
|
|
|
266
266
|
token = JWT::Token.new(payload: payload, header: header)
|
|
267
267
|
|
|
268
|
-
token.sign!(key: jwk)
|
|
268
|
+
token.sign!(key: jwk, algorithm: 'HS256')
|
|
269
269
|
|
|
270
270
|
encoded_token = JWT::EncodedToken.new(token.jwt)
|
|
271
271
|
encoded_token.verify!(signature: { algorithm: ["HS256", "HS512"], key: jwk})
|
|
@@ -24,6 +24,8 @@ module JWT
|
|
|
24
24
|
# @return [Array<String>] the list of acceptable algorithms.
|
|
25
25
|
# @!attribute [rw] required_claims
|
|
26
26
|
# @return [Array<String>] the list of required claims.
|
|
27
|
+
# @!attribute [rw] enforce_hmac_key_length
|
|
28
|
+
# @return [Boolean] whether to enforce minimum HMAC key lengths. false disables validation (default).
|
|
27
29
|
|
|
28
30
|
attr_accessor :verify_expiration,
|
|
29
31
|
:verify_not_before,
|
|
@@ -34,7 +36,8 @@ module JWT
|
|
|
34
36
|
:verify_sub,
|
|
35
37
|
:leeway,
|
|
36
38
|
:algorithms,
|
|
37
|
-
:required_claims
|
|
39
|
+
:required_claims,
|
|
40
|
+
:enforce_hmac_key_length
|
|
38
41
|
|
|
39
42
|
# Initializes a new DecodeConfiguration instance with default settings.
|
|
40
43
|
def initialize
|
|
@@ -48,6 +51,7 @@ module JWT
|
|
|
48
51
|
@leeway = 0
|
|
49
52
|
@algorithms = ['HS256']
|
|
50
53
|
@required_claims = []
|
|
54
|
+
@enforce_hmac_key_length = false
|
|
51
55
|
end
|
|
52
56
|
|
|
53
57
|
# @api private
|
|
@@ -62,7 +66,8 @@ module JWT
|
|
|
62
66
|
verify_sub: verify_sub,
|
|
63
67
|
leeway: leeway,
|
|
64
68
|
algorithms: algorithms,
|
|
65
|
-
required_claims: required_claims
|
|
69
|
+
required_claims: required_claims,
|
|
70
|
+
enforce_hmac_key_length: enforce_hmac_key_length
|
|
66
71
|
}
|
|
67
72
|
end
|
|
68
73
|
end
|
data/lib/jwt/decode.rb
CHANGED
|
@@ -58,7 +58,7 @@ module JWT
|
|
|
58
58
|
|
|
59
59
|
def verify_algo
|
|
60
60
|
raise JWT::IncorrectAlgorithm, 'An algorithm must be specified' if allowed_algorithms.empty?
|
|
61
|
-
raise JWT::DecodeError, 'Token header not a JSON object' unless
|
|
61
|
+
raise JWT::DecodeError, 'Token header not a JSON object' unless valid_token_header?
|
|
62
62
|
raise JWT::IncorrectAlgorithm, 'Token is missing alg header' unless alg_in_header
|
|
63
63
|
raise JWT::IncorrectAlgorithm, 'Expected a different algorithm' if allowed_and_valid_algorithms.empty?
|
|
64
64
|
end
|
|
@@ -113,9 +113,15 @@ module JWT
|
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
def none_algorithm?
|
|
116
|
+
return false unless valid_token_header?
|
|
117
|
+
|
|
116
118
|
alg_in_header == 'none'
|
|
117
119
|
end
|
|
118
120
|
|
|
121
|
+
def valid_token_header?
|
|
122
|
+
token.header.is_a?(Hash)
|
|
123
|
+
end
|
|
124
|
+
|
|
119
125
|
def alg_in_header
|
|
120
126
|
token.header['alg']
|
|
121
127
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
module JWT
|
|
6
|
+
# @private
|
|
7
|
+
class EncodedToken
|
|
8
|
+
# Allow access to the unverified payload for claim verification.
|
|
9
|
+
class ClaimsContext
|
|
10
|
+
extend Forwardable
|
|
11
|
+
|
|
12
|
+
def_delegators :@token, :header, :unverified_payload
|
|
13
|
+
|
|
14
|
+
def initialize(token)
|
|
15
|
+
@token = token
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def payload
|
|
19
|
+
unverified_payload
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/jwt/encoded_token.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'encoded_token/claims_context'
|
|
4
|
+
|
|
3
5
|
module JWT
|
|
4
6
|
# Represents an encoded JWT token
|
|
5
7
|
#
|
|
@@ -12,22 +14,6 @@ module JWT
|
|
|
12
14
|
# encoded_token.verify_signature!(algorithm: 'HS256', key: 'secret')
|
|
13
15
|
# encoded_token.payload # => {'pay' => 'load'}
|
|
14
16
|
class EncodedToken
|
|
15
|
-
# @private
|
|
16
|
-
# Allow access to the unverified payload for claim verification.
|
|
17
|
-
class ClaimsContext
|
|
18
|
-
extend Forwardable
|
|
19
|
-
|
|
20
|
-
def_delegators :@token, :header, :unverified_payload
|
|
21
|
-
|
|
22
|
-
def initialize(token)
|
|
23
|
-
@token = token
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def payload
|
|
27
|
-
unverified_payload
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
17
|
DEFAULT_CLAIMS = [:exp].freeze
|
|
32
18
|
|
|
33
19
|
private_constant(:DEFAULT_CLAIMS)
|
data/lib/jwt/jwa/ecdsa.rb
CHANGED
|
@@ -8,7 +8,7 @@ module JWT
|
|
|
8
8
|
|
|
9
9
|
def initialize(alg, digest)
|
|
10
10
|
@alg = alg
|
|
11
|
-
@digest =
|
|
11
|
+
@digest = digest
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def sign(data:, signing_key:)
|
|
@@ -20,7 +20,7 @@ module JWT
|
|
|
20
20
|
|
|
21
21
|
raise IncorrectAlgorithm, "payload algorithm is #{alg} but #{key_algorithm} signing key was provided" if alg != key_algorithm
|
|
22
22
|
|
|
23
|
-
asn1_to_raw(signing_key.dsa_sign_asn1(digest.digest(data)), signing_key)
|
|
23
|
+
asn1_to_raw(signing_key.dsa_sign_asn1(OpenSSL::Digest.new(digest).digest(data)), signing_key)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def verify(data:, signature:, verification_key:)
|
|
@@ -32,7 +32,7 @@ module JWT
|
|
|
32
32
|
key_algorithm = curve_definition[:algorithm]
|
|
33
33
|
raise IncorrectAlgorithm, "payload algorithm is #{alg} but #{key_algorithm} verification key was provided" if alg != key_algorithm
|
|
34
34
|
|
|
35
|
-
verification_key.dsa_verify_asn1(digest.digest(data), raw_to_asn1(signature, verification_key))
|
|
35
|
+
verification_key.dsa_verify_asn1(OpenSSL::Digest.new(digest).digest(data), raw_to_asn1(signature, verification_key))
|
|
36
36
|
rescue OpenSSL::PKey::PKeyError
|
|
37
37
|
raise JWT::VerificationError, 'Signature verification raised'
|
|
38
38
|
end
|
data/lib/jwt/jwa/hmac.rb
CHANGED
|
@@ -6,24 +6,32 @@ module JWT
|
|
|
6
6
|
class Hmac
|
|
7
7
|
include JWT::JWA::SigningAlgorithm
|
|
8
8
|
|
|
9
|
+
# Minimum key lengths for HMAC algorithms based on RFC 7518 Section 3.2.
|
|
10
|
+
# Keys must be at least the size of the hash output to ensure sufficient
|
|
11
|
+
# entropy for the algorithm's security level.
|
|
12
|
+
MIN_KEY_LENGTHS = {
|
|
13
|
+
'HS256' => 32,
|
|
14
|
+
'HS384' => 48,
|
|
15
|
+
'HS512' => 64
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
9
18
|
def initialize(alg, digest)
|
|
10
19
|
@alg = alg
|
|
11
20
|
@digest = digest
|
|
12
21
|
end
|
|
13
22
|
|
|
14
23
|
def sign(data:, signing_key:)
|
|
15
|
-
signing_key
|
|
16
|
-
|
|
24
|
+
ensure_valid_key!(signing_key)
|
|
25
|
+
validate_key_length!(signing_key)
|
|
17
26
|
|
|
18
27
|
OpenSSL::HMAC.digest(digest.new, signing_key, data)
|
|
19
|
-
rescue OpenSSL::HMACError => e
|
|
20
|
-
raise_verify_error!('OpenSSL 3.0 does not support nil or empty hmac_secret') if signing_key == '' && e.message == 'EVP_PKEY_new_mac_key: malloc failure'
|
|
21
|
-
|
|
22
|
-
raise e
|
|
23
28
|
end
|
|
24
29
|
|
|
25
30
|
def verify(data:, signature:, verification_key:)
|
|
26
|
-
|
|
31
|
+
ensure_valid_key!(verification_key)
|
|
32
|
+
validate_key_length!(verification_key)
|
|
33
|
+
|
|
34
|
+
SecurityUtils.secure_compare(signature, OpenSSL::HMAC.digest(digest.new, verification_key, data))
|
|
27
35
|
end
|
|
28
36
|
|
|
29
37
|
register_algorithm(new('HS256', OpenSSL::Digest::SHA256))
|
|
@@ -34,6 +42,20 @@ module JWT
|
|
|
34
42
|
|
|
35
43
|
attr_reader :digest
|
|
36
44
|
|
|
45
|
+
def ensure_valid_key!(key)
|
|
46
|
+
raise_verify_error!('HMAC key expected to be a String') unless key.is_a?(String)
|
|
47
|
+
raise_verify_error!('HMAC key cannot be empty') if key.empty?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def validate_key_length!(key)
|
|
51
|
+
return unless JWT.configuration.decode.enforce_hmac_key_length
|
|
52
|
+
|
|
53
|
+
min_length = MIN_KEY_LENGTHS[alg]
|
|
54
|
+
return if key.bytesize >= min_length
|
|
55
|
+
|
|
56
|
+
raise_verify_error!("HMAC key must be at least #{min_length} bytes for #{alg} algorithm")
|
|
57
|
+
end
|
|
58
|
+
|
|
37
59
|
# Copy of https://github.com/rails/rails/blob/v7.0.3.1/activesupport/lib/active_support/security_utils.rb
|
|
38
60
|
# rubocop:disable Naming/MethodParameterName, Style/StringLiterals, Style/NumericPredicate
|
|
39
61
|
module SecurityUtils
|
data/lib/jwt/jwa/rsa.rb
CHANGED
|
@@ -8,18 +8,18 @@ module JWT
|
|
|
8
8
|
|
|
9
9
|
def initialize(alg)
|
|
10
10
|
@alg = alg
|
|
11
|
-
@digest =
|
|
11
|
+
@digest = alg.sub('RS', 'SHA')
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def sign(data:, signing_key:)
|
|
15
15
|
raise_sign_error!("The given key is a #{signing_key.class}. It has to be an OpenSSL::PKey::RSA instance") unless signing_key.is_a?(OpenSSL::PKey::RSA)
|
|
16
16
|
raise_sign_error!('The key length must be greater than or equal to 2048 bits') if signing_key.n.num_bits < 2048
|
|
17
17
|
|
|
18
|
-
signing_key.sign(digest, data)
|
|
18
|
+
signing_key.sign(OpenSSL::Digest.new(digest), data)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def verify(data:, signature:, verification_key:)
|
|
22
|
-
verification_key.verify(digest, signature, data)
|
|
22
|
+
verification_key.verify(OpenSSL::Digest.new(digest), signature, data)
|
|
23
23
|
rescue OpenSSL::PKey::PKeyError
|
|
24
24
|
raise JWT::VerificationError, 'Signature verification raised'
|
|
25
25
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JWT
|
|
4
|
+
module JWA
|
|
5
|
+
# @api private
|
|
6
|
+
class SignerContext
|
|
7
|
+
attr_reader :jwa
|
|
8
|
+
|
|
9
|
+
def initialize(jwa:, key:)
|
|
10
|
+
@jwa = jwa
|
|
11
|
+
@key = key
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def sign(*args, **kwargs)
|
|
15
|
+
@jwa.sign(*args, **kwargs, signing_key: @key)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JWT
|
|
4
|
+
module JWA
|
|
5
|
+
# @api private
|
|
6
|
+
class VerifierContext
|
|
7
|
+
attr_reader :jwa
|
|
8
|
+
|
|
9
|
+
def initialize(jwa:, keys:)
|
|
10
|
+
@jwa = jwa
|
|
11
|
+
@keys = Array(keys)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def verify(*args, **kwargs)
|
|
15
|
+
@keys.any? do |key|
|
|
16
|
+
@jwa.verify(*args, **kwargs, verification_key: key)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/jwt/jwa.rb
CHANGED
|
@@ -9,40 +9,12 @@ require_relative 'jwa/none'
|
|
|
9
9
|
require_relative 'jwa/ps'
|
|
10
10
|
require_relative 'jwa/rsa'
|
|
11
11
|
require_relative 'jwa/unsupported'
|
|
12
|
+
require_relative 'jwa/verifier_context'
|
|
13
|
+
require_relative 'jwa/signer_context'
|
|
12
14
|
|
|
13
15
|
module JWT
|
|
14
16
|
# The JWA module contains all supported algorithms.
|
|
15
17
|
module JWA
|
|
16
|
-
# @api private
|
|
17
|
-
class VerifierContext
|
|
18
|
-
attr_reader :jwa
|
|
19
|
-
|
|
20
|
-
def initialize(jwa:, keys:)
|
|
21
|
-
@jwa = jwa
|
|
22
|
-
@keys = Array(keys)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def verify(*args, **kwargs)
|
|
26
|
-
@keys.any? do |key|
|
|
27
|
-
@jwa.verify(*args, **kwargs, verification_key: key)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# @api private
|
|
33
|
-
class SignerContext
|
|
34
|
-
attr_reader :jwa
|
|
35
|
-
|
|
36
|
-
def initialize(jwa:, key:)
|
|
37
|
-
@jwa = jwa
|
|
38
|
-
@key = key
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def sign(*args, **kwargs)
|
|
42
|
-
@jwa.sign(*args, **kwargs, signing_key: @key)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
18
|
class << self
|
|
47
19
|
# @api private
|
|
48
20
|
def resolve(algorithm)
|
data/lib/jwt/jwk/ec.rb
CHANGED
|
@@ -71,8 +71,6 @@ module JWT
|
|
|
71
71
|
super
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
private
|
|
75
|
-
|
|
76
74
|
def jwa
|
|
77
75
|
return super if self[:alg]
|
|
78
76
|
|
|
@@ -80,6 +78,8 @@ module JWT
|
|
|
80
78
|
JWA.resolve(JWA::Ecdsa.curve_by_name(curve_name)[:algorithm])
|
|
81
79
|
end
|
|
82
80
|
|
|
81
|
+
private
|
|
82
|
+
|
|
83
83
|
def ec_key
|
|
84
84
|
@ec_key ||= create_ec_key(self[:crv], self[:x], self[:y], self[:d])
|
|
85
85
|
end
|
data/lib/jwt/jwk/rsa.rb
CHANGED
|
@@ -195,7 +195,7 @@ module JWT
|
|
|
195
195
|
|
|
196
196
|
if ::JWT.openssl_3?
|
|
197
197
|
alias create_rsa_key create_rsa_key_using_der
|
|
198
|
-
elsif OpenSSL::PKey::RSA.
|
|
198
|
+
elsif OpenSSL::PKey::RSA.method_defined?(:set_key)
|
|
199
199
|
alias create_rsa_key create_rsa_key_using_sets
|
|
200
200
|
else
|
|
201
201
|
alias create_rsa_key create_rsa_key_using_accessors
|
data/lib/jwt/version.rb
CHANGED
|
@@ -15,8 +15,8 @@ module JWT
|
|
|
15
15
|
# Version constants
|
|
16
16
|
module VERSION
|
|
17
17
|
MAJOR = 3
|
|
18
|
-
MINOR =
|
|
19
|
-
TINY =
|
|
18
|
+
MINOR = 2
|
|
19
|
+
TINY = 0
|
|
20
20
|
PRE = nil
|
|
21
21
|
|
|
22
22
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
|
@@ -32,14 +32,6 @@ module JWT
|
|
|
32
32
|
true if 3 * 0x10000000 <= OpenSSL::OPENSSL_VERSION_NUMBER
|
|
33
33
|
end
|
|
34
34
|
|
|
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
|
|
39
|
-
def self.openssl_3_hmac_empty_key_regression?
|
|
40
|
-
openssl_3? && openssl_version <= ::Gem::Version.new('3.0.0')
|
|
41
|
-
end
|
|
42
|
-
|
|
43
35
|
# Returns the OpenSSL version.
|
|
44
36
|
#
|
|
45
37
|
# @return [Gem::Version] the OpenSSL version.
|
data/lib/jwt/x5c_key_finder.rb
CHANGED
|
@@ -40,7 +40,7 @@ module JWT
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def parse_certificates(x5c_header_or_certificates)
|
|
43
|
-
if x5c_header_or_certificates.all?
|
|
43
|
+
if x5c_header_or_certificates.all?(OpenSSL::X509::Certificate)
|
|
44
44
|
x5c_header_or_certificates
|
|
45
45
|
else
|
|
46
46
|
x5c_header_or_certificates.map do |encoded|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jwt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tim Rudat
|
|
@@ -171,6 +171,7 @@ files:
|
|
|
171
171
|
- lib/jwt/decode.rb
|
|
172
172
|
- lib/jwt/encode.rb
|
|
173
173
|
- lib/jwt/encoded_token.rb
|
|
174
|
+
- lib/jwt/encoded_token/claims_context.rb
|
|
174
175
|
- lib/jwt/error.rb
|
|
175
176
|
- lib/jwt/json.rb
|
|
176
177
|
- lib/jwt/jwa.rb
|
|
@@ -179,8 +180,10 @@ files:
|
|
|
179
180
|
- lib/jwt/jwa/none.rb
|
|
180
181
|
- lib/jwt/jwa/ps.rb
|
|
181
182
|
- lib/jwt/jwa/rsa.rb
|
|
183
|
+
- lib/jwt/jwa/signer_context.rb
|
|
182
184
|
- lib/jwt/jwa/signing_algorithm.rb
|
|
183
185
|
- lib/jwt/jwa/unsupported.rb
|
|
186
|
+
- lib/jwt/jwa/verifier_context.rb
|
|
184
187
|
- lib/jwt/jwk.rb
|
|
185
188
|
- lib/jwt/jwk/ec.rb
|
|
186
189
|
- lib/jwt/jwk/hmac.rb
|
|
@@ -199,7 +202,7 @@ licenses:
|
|
|
199
202
|
- MIT
|
|
200
203
|
metadata:
|
|
201
204
|
bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
|
|
202
|
-
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v3.
|
|
205
|
+
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v3.2.0/CHANGELOG.md
|
|
203
206
|
rubygems_mfa_required: 'true'
|
|
204
207
|
rdoc_options: []
|
|
205
208
|
require_paths:
|
|
@@ -215,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
215
218
|
- !ruby/object:Gem::Version
|
|
216
219
|
version: '0'
|
|
217
220
|
requirements: []
|
|
218
|
-
rubygems_version:
|
|
221
|
+
rubygems_version: 4.0.10
|
|
219
222
|
specification_version: 4
|
|
220
223
|
summary: JSON Web Token implementation in Ruby
|
|
221
224
|
test_files: []
|