jwt 2.8.2 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +79 -0
- data/README.md +189 -93
- data/lib/jwt/base64.rb +3 -0
- data/lib/jwt/claims/audience.rb +30 -0
- data/lib/jwt/claims/crit.rb +35 -0
- data/lib/jwt/claims/decode_verifier.rb +40 -0
- data/lib/jwt/claims/expiration.rb +32 -0
- data/lib/jwt/claims/issued_at.rb +22 -0
- data/lib/jwt/claims/issuer.rb +34 -0
- data/lib/jwt/claims/jwt_id.rb +35 -0
- data/lib/jwt/claims/not_before.rb +32 -0
- data/lib/jwt/claims/numeric.rb +77 -0
- data/lib/jwt/claims/required.rb +33 -0
- data/lib/jwt/claims/subject.rb +30 -0
- data/lib/jwt/claims/verification_methods.rb +20 -0
- data/lib/jwt/claims/verifier.rb +61 -0
- data/lib/jwt/claims.rb +74 -0
- data/lib/jwt/claims_validator.rb +6 -25
- data/lib/jwt/configuration/container.rb +20 -0
- data/lib/jwt/configuration/decode_configuration.rb +24 -0
- data/lib/jwt/configuration/jwk_configuration.rb +1 -0
- data/lib/jwt/configuration.rb +8 -0
- data/lib/jwt/decode.rb +28 -70
- data/lib/jwt/deprecations.rb +1 -0
- data/lib/jwt/encode.rb +17 -60
- data/lib/jwt/encoded_token.rb +139 -0
- data/lib/jwt/error.rb +34 -0
- data/lib/jwt/json.rb +1 -1
- data/lib/jwt/jwa/compat.rb +32 -0
- data/lib/jwt/jwa/ecdsa.rb +39 -25
- data/lib/jwt/jwa/eddsa.rb +20 -27
- data/lib/jwt/jwa/hmac.rb +25 -18
- data/lib/jwt/jwa/hmac_rbnacl.rb +43 -43
- data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +40 -39
- data/lib/jwt/jwa/none.rb +8 -3
- data/lib/jwt/jwa/ps.rb +20 -15
- data/lib/jwt/jwa/rsa.rb +20 -10
- data/lib/jwt/jwa/signing_algorithm.rb +63 -0
- data/lib/jwt/jwa/unsupported.rb +9 -8
- data/lib/jwt/jwa/wrapper.rb +27 -9
- data/lib/jwt/jwa.rb +30 -34
- data/lib/jwt/jwk/ec.rb +2 -3
- data/lib/jwt/jwk/hmac.rb +2 -3
- data/lib/jwt/jwk/key_base.rb +1 -0
- data/lib/jwt/jwk/key_finder.rb +1 -0
- data/lib/jwt/jwk/kid_as_key_digest.rb +1 -0
- data/lib/jwt/jwk/okp_rbnacl.rb +3 -4
- data/lib/jwt/jwk/rsa.rb +2 -3
- data/lib/jwt/jwk/set.rb +2 -0
- data/lib/jwt/jwk.rb +1 -0
- data/lib/jwt/token.rb +112 -0
- data/lib/jwt/verify.rb +16 -93
- data/lib/jwt/version.rb +30 -9
- data/lib/jwt.rb +20 -0
- data/ruby-jwt.gemspec +1 -0
- metadata +36 -7
data/lib/jwt/jwa/hmac.rb
CHANGED
@@ -2,35 +2,42 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
-
|
6
|
-
|
5
|
+
# Implementation of the HMAC family of algorithms
|
6
|
+
class Hmac
|
7
|
+
include JWT::JWA::SigningAlgorithm
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
'HS512' => OpenSSL::Digest::SHA512
|
12
|
-
}.freeze
|
13
|
-
|
14
|
-
SUPPORTED = MAPPING.keys
|
9
|
+
def self.from_algorithm(algorithm)
|
10
|
+
new(algorithm, OpenSSL::Digest.new(algorithm.downcase.gsub('hs', 'sha')))
|
11
|
+
end
|
15
12
|
|
16
|
-
def
|
17
|
-
|
13
|
+
def initialize(alg, digest)
|
14
|
+
@alg = alg
|
15
|
+
@digest = digest
|
16
|
+
end
|
18
17
|
|
19
|
-
|
18
|
+
def sign(data:, signing_key:)
|
19
|
+
signing_key ||= ''
|
20
|
+
raise_verify_error!('HMAC key expected to be a String') unless signing_key.is_a?(String)
|
20
21
|
|
21
|
-
OpenSSL::HMAC.digest(
|
22
|
+
OpenSSL::HMAC.digest(digest.new, signing_key, data)
|
22
23
|
rescue OpenSSL::HMACError => e
|
23
|
-
if
|
24
|
-
raise JWT::DecodeError, 'OpenSSL 3.0 does not support nil or empty hmac_secret'
|
25
|
-
end
|
24
|
+
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'
|
26
25
|
|
27
26
|
raise e
|
28
27
|
end
|
29
28
|
|
30
|
-
def verify(
|
31
|
-
SecurityUtils.secure_compare(signature, sign(
|
29
|
+
def verify(data:, signature:, verification_key:)
|
30
|
+
SecurityUtils.secure_compare(signature, sign(data: data, signing_key: verification_key))
|
32
31
|
end
|
33
32
|
|
33
|
+
register_algorithm(new('HS256', OpenSSL::Digest::SHA256))
|
34
|
+
register_algorithm(new('HS384', OpenSSL::Digest::SHA384))
|
35
|
+
register_algorithm(new('HS512', OpenSSL::Digest::SHA512))
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :digest
|
40
|
+
|
34
41
|
# Copy of https://github.com/rails/rails/blob/v7.0.3.1/activesupport/lib/active_support/security_utils.rb
|
35
42
|
# rubocop:disable Naming/MethodParameterName, Style/StringLiterals, Style/NumericPredicate
|
36
43
|
module SecurityUtils
|
data/lib/jwt/jwa/hmac_rbnacl.rb
CHANGED
@@ -1,49 +1,49 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module JWT
|
4
|
-
module
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
4
|
+
module JWA
|
5
|
+
# Implementation of the HMAC family of algorithms (using RbNaCl)
|
6
|
+
class HmacRbNaCl
|
7
|
+
include JWT::JWA::SigningAlgorithm
|
8
|
+
|
9
|
+
def self.from_algorithm(algorithm)
|
10
|
+
new(algorithm, ::RbNaCl::HMAC.const_get(algorithm.upcase.gsub('HS', 'SHA')))
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(alg, hmac)
|
14
|
+
@alg = alg
|
15
|
+
@hmac = hmac
|
16
|
+
end
|
17
|
+
|
18
|
+
def sign(data:, 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
|
+
hmac.auth(key_for_rbnacl(hmac, signing_key).encode('binary'), data.encode('binary'))
|
21
|
+
end
|
22
|
+
|
23
|
+
def verify(data:, signature:, verification_key:)
|
24
|
+
Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
|
25
|
+
hmac.verify(key_for_rbnacl(hmac, verification_key).encode('binary'), signature.encode('binary'), data.encode('binary'))
|
26
|
+
rescue ::RbNaCl::BadAuthenticatorError, ::RbNaCl::LengthError
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
register_algorithm(new('HS512256', ::RbNaCl::HMAC::SHA512256))
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :hmac
|
35
|
+
|
36
|
+
def key_for_rbnacl(hmac, key)
|
37
|
+
key ||= ''
|
38
|
+
raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
|
39
|
+
|
40
|
+
return padded_empty_key(hmac.key_bytes) if key == ''
|
41
|
+
|
42
|
+
key
|
43
|
+
end
|
44
|
+
|
45
|
+
def padded_empty_key(length)
|
46
|
+
Array.new(length, 0x0).pack('C*').encode('binary')
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -1,45 +1,46 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module JWT
|
4
|
-
module
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
4
|
+
module JWA
|
5
|
+
# Implementation of the HMAC family of algorithms (using RbNaCl prior to a certain version)
|
6
|
+
class HmacRbNaClFixed
|
7
|
+
include JWT::JWA::SigningAlgorithm
|
8
|
+
|
9
|
+
def self.from_algorithm(algorithm)
|
10
|
+
new(algorithm, ::RbNaCl::HMAC.const_get(algorithm.upcase.gsub('HS', 'SHA')))
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(alg, hmac)
|
14
|
+
@alg = alg
|
15
|
+
@hmac = hmac
|
16
|
+
end
|
17
|
+
|
18
|
+
def sign(data:, signing_key:)
|
19
|
+
signing_key ||= ''
|
20
|
+
Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
|
21
|
+
raise JWT::DecodeError, 'HMAC key expected to be a String' unless signing_key.is_a?(String)
|
22
|
+
|
23
|
+
hmac.auth(padded_key_bytes(signing_key, hmac.key_bytes), data.encode('binary'))
|
24
|
+
end
|
25
|
+
|
26
|
+
def verify(data:, signature:, verification_key:)
|
27
|
+
verification_key ||= ''
|
28
|
+
Deprecations.warning("The use of the algorithm #{alg} is deprecated and will be removed in the next major version of ruby-jwt")
|
29
|
+
raise JWT::DecodeError, 'HMAC key expected to be a String' unless verification_key.is_a?(String)
|
30
|
+
|
31
|
+
hmac.verify(padded_key_bytes(verification_key, hmac.key_bytes), signature.encode('binary'), data.encode('binary'))
|
32
|
+
rescue ::RbNaCl::BadAuthenticatorError, ::RbNaCl::LengthError
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
register_algorithm(new('HS512256', ::RbNaCl::HMAC::SHA512256))
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
attr_reader :hmac
|
41
|
+
|
42
|
+
def padded_key_bytes(key, bytesize)
|
43
|
+
key.bytes.fill(0, key.bytesize...bytesize).pack('C*')
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
data/lib/jwt/jwa/none.rb
CHANGED
@@ -2,10 +2,13 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
-
|
6
|
-
|
5
|
+
# Implementation of the none algorithm
|
6
|
+
class None
|
7
|
+
include JWT::JWA::SigningAlgorithm
|
7
8
|
|
8
|
-
|
9
|
+
def initialize
|
10
|
+
@alg = 'none'
|
11
|
+
end
|
9
12
|
|
10
13
|
def sign(*)
|
11
14
|
''
|
@@ -14,6 +17,8 @@ module JWT
|
|
14
17
|
def verify(*)
|
15
18
|
true
|
16
19
|
end
|
20
|
+
|
21
|
+
register_algorithm(new)
|
17
22
|
end
|
18
23
|
end
|
19
24
|
end
|
data/lib/jwt/jwa/ps.rb
CHANGED
@@ -2,29 +2,34 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
-
|
6
|
-
|
5
|
+
# Implementation of the RSASSA-PSS family of algorithms
|
6
|
+
class Ps
|
7
|
+
include JWT::JWA::SigningAlgorithm
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def sign(algorithm, msg, key)
|
13
|
-
unless key.is_a?(::OpenSSL::PKey::RSA)
|
14
|
-
raise EncodeError, "The given key is a #{key_class}. It has to be an OpenSSL::PKey::RSA instance."
|
15
|
-
end
|
9
|
+
def initialize(alg)
|
10
|
+
@alg = alg
|
11
|
+
@digest_algorithm = alg.sub('PS', 'sha')
|
12
|
+
end
|
16
13
|
|
17
|
-
|
14
|
+
def sign(data:, signing_key:)
|
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)
|
18
16
|
|
19
|
-
|
17
|
+
signing_key.sign_pss(digest_algorithm, data, salt_length: :digest, mgf1_hash: digest_algorithm)
|
20
18
|
end
|
21
19
|
|
22
|
-
def verify(
|
23
|
-
|
24
|
-
public_key.verify_pss(translated_algorithm, signature, signing_input, salt_length: :auto, mgf1_hash: translated_algorithm)
|
20
|
+
def verify(data:, signature:, verification_key:)
|
21
|
+
verification_key.verify_pss(digest_algorithm, signature, data, salt_length: :auto, mgf1_hash: digest_algorithm)
|
25
22
|
rescue OpenSSL::PKey::PKeyError
|
26
23
|
raise JWT::VerificationError, 'Signature verification raised'
|
27
24
|
end
|
25
|
+
|
26
|
+
register_algorithm(new('PS256'))
|
27
|
+
register_algorithm(new('PS384'))
|
28
|
+
register_algorithm(new('PS512'))
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :digest_algorithm
|
28
33
|
end
|
29
34
|
end
|
30
35
|
end
|
data/lib/jwt/jwa/rsa.rb
CHANGED
@@ -2,24 +2,34 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
-
|
6
|
-
|
5
|
+
# Implementation of the RSA family of algorithms
|
6
|
+
class Rsa
|
7
|
+
include JWT::JWA::SigningAlgorithm
|
7
8
|
|
8
|
-
|
9
|
+
def initialize(alg)
|
10
|
+
@alg = alg
|
11
|
+
@digest = alg.sub('RS', 'SHA')
|
12
|
+
end
|
9
13
|
|
10
|
-
def sign(
|
11
|
-
|
12
|
-
raise EncodeError, "The given key is a #{key.class}. It has to be an OpenSSL::PKey::RSA instance"
|
13
|
-
end
|
14
|
+
def sign(data:, signing_key:)
|
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)
|
14
16
|
|
15
|
-
|
17
|
+
signing_key.sign(OpenSSL::Digest.new(digest), data)
|
16
18
|
end
|
17
19
|
|
18
|
-
def verify(
|
19
|
-
|
20
|
+
def verify(data:, signature:, verification_key:)
|
21
|
+
verification_key.verify(OpenSSL::Digest.new(digest), signature, data)
|
20
22
|
rescue OpenSSL::PKey::PKeyError
|
21
23
|
raise JWT::VerificationError, 'Signature verification raised'
|
22
24
|
end
|
25
|
+
|
26
|
+
register_algorithm(new('RS256'))
|
27
|
+
register_algorithm(new('RS384'))
|
28
|
+
register_algorithm(new('RS512'))
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :digest
|
23
33
|
end
|
24
34
|
end
|
25
35
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
# JSON Web Algorithms
|
5
|
+
module JWA
|
6
|
+
# Base functionality for signing algorithms
|
7
|
+
module SigningAlgorithm
|
8
|
+
# Class methods for the SigningAlgorithm module
|
9
|
+
module ClassMethods
|
10
|
+
def register_algorithm(algo)
|
11
|
+
::JWT::JWA.register_algorithm(algo)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.included(klass)
|
16
|
+
klass.extend(ClassMethods)
|
17
|
+
klass.include(JWT::JWA::Compat)
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :alg
|
21
|
+
|
22
|
+
def valid_alg?(alg_to_check)
|
23
|
+
alg&.casecmp(alg_to_check)&.zero? == true
|
24
|
+
end
|
25
|
+
|
26
|
+
def header(*)
|
27
|
+
{ 'alg' => alg }
|
28
|
+
end
|
29
|
+
|
30
|
+
def sign(*)
|
31
|
+
raise_sign_error!('Algorithm implementation is missing the sign method')
|
32
|
+
end
|
33
|
+
|
34
|
+
def verify(*)
|
35
|
+
raise_verify_error!('Algorithm implementation is missing the verify method')
|
36
|
+
end
|
37
|
+
|
38
|
+
def raise_verify_error!(message)
|
39
|
+
raise(DecodeError.new(message).tap { |e| e.set_backtrace(caller(1)) })
|
40
|
+
end
|
41
|
+
|
42
|
+
def raise_sign_error!(message)
|
43
|
+
raise(EncodeError.new(message).tap { |e| e.set_backtrace(caller(1)) })
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class << self
|
48
|
+
def register_algorithm(algo)
|
49
|
+
algorithms[algo.alg.to_s.downcase] = algo
|
50
|
+
end
|
51
|
+
|
52
|
+
def find(algo)
|
53
|
+
algorithms.fetch(algo.to_s.downcase, Unsupported)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def algorithms
|
59
|
+
@algorithms ||= {}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/jwt/jwa/unsupported.rb
CHANGED
@@ -2,17 +2,18 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
+
# Represents an unsupported algorithm
|
5
6
|
module Unsupported
|
6
|
-
|
7
|
+
class << self
|
8
|
+
include JWT::JWA::SigningAlgorithm
|
7
9
|
|
8
|
-
|
10
|
+
def sign(*)
|
11
|
+
raise_sign_error!('Unsupported signing method')
|
12
|
+
end
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def verify(*)
|
15
|
-
raise JWT::VerificationError, 'Algorithm not supported'
|
14
|
+
def verify(*)
|
15
|
+
raise JWT::VerificationError, 'Algorithm not supported'
|
16
|
+
end
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
data/lib/jwt/jwa/wrapper.rb
CHANGED
@@ -2,24 +2,42 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
+
# @api private
|
5
6
|
class Wrapper
|
6
|
-
|
7
|
+
include SigningAlgorithm
|
7
8
|
|
8
|
-
def initialize(
|
9
|
-
@
|
10
|
-
|
9
|
+
def initialize(algorithm)
|
10
|
+
@algorithm = algorithm
|
11
|
+
end
|
12
|
+
|
13
|
+
def alg
|
14
|
+
return @algorithm.alg if @algorithm.respond_to?(:alg)
|
15
|
+
|
16
|
+
super
|
11
17
|
end
|
12
18
|
|
13
19
|
def valid_alg?(alg_to_check)
|
14
|
-
|
20
|
+
return @algorithm.valid_alg?(alg_to_check) if @algorithm.respond_to?(:valid_alg?)
|
21
|
+
|
22
|
+
super
|
15
23
|
end
|
16
24
|
|
17
|
-
def
|
18
|
-
|
25
|
+
def header(*args, **kwargs)
|
26
|
+
return @algorithm.header(*args, **kwargs) if @algorithm.respond_to?(:header)
|
27
|
+
|
28
|
+
super
|
19
29
|
end
|
20
30
|
|
21
|
-
def
|
22
|
-
|
31
|
+
def sign(*args, **kwargs)
|
32
|
+
return @algorithm.sign(*args, **kwargs) if @algorithm.respond_to?(:sign)
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
def verify(*args, **kwargs)
|
38
|
+
return @algorithm.verify(*args, **kwargs) if @algorithm.respond_to?(:verify)
|
39
|
+
|
40
|
+
super
|
23
41
|
end
|
24
42
|
end
|
25
43
|
end
|
data/lib/jwt/jwa.rb
CHANGED
@@ -8,54 +8,50 @@ rescue LoadError
|
|
8
8
|
raise if defined?(RbNaCl)
|
9
9
|
end
|
10
10
|
|
11
|
-
require_relative 'jwa/
|
12
|
-
require_relative 'jwa/
|
11
|
+
require_relative 'jwa/compat'
|
12
|
+
require_relative 'jwa/signing_algorithm'
|
13
13
|
require_relative 'jwa/ecdsa'
|
14
|
-
require_relative 'jwa/
|
15
|
-
require_relative 'jwa/ps'
|
14
|
+
require_relative 'jwa/hmac'
|
16
15
|
require_relative 'jwa/none'
|
16
|
+
require_relative 'jwa/ps'
|
17
|
+
require_relative 'jwa/rsa'
|
17
18
|
require_relative 'jwa/unsupported'
|
18
19
|
require_relative 'jwa/wrapper'
|
19
20
|
|
21
|
+
require_relative 'jwa/eddsa' if JWT.rbnacl?
|
22
|
+
|
23
|
+
if JWT.rbnacl_6_or_greater?
|
24
|
+
require_relative 'jwa/hmac_rbnacl'
|
25
|
+
elsif JWT.rbnacl?
|
26
|
+
require_relative 'jwa/hmac_rbnacl_fixed'
|
27
|
+
end
|
28
|
+
|
20
29
|
module JWT
|
30
|
+
# The JWA module contains all supported algorithms.
|
21
31
|
module JWA
|
22
|
-
ALGOS = [Hmac, Ecdsa, Rsa, Eddsa, Ps, None, Unsupported].tap do |l|
|
23
|
-
if ::JWT.rbnacl_6_or_greater?
|
24
|
-
require_relative 'jwa/hmac_rbnacl'
|
25
|
-
l << Algos::HmacRbNaCl
|
26
|
-
elsif ::JWT.rbnacl?
|
27
|
-
require_relative 'jwa/hmac_rbnacl_fixed'
|
28
|
-
l << Algos::HmacRbNaClFixed
|
29
|
-
end
|
30
|
-
end.freeze
|
31
|
-
|
32
32
|
class << self
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
# @api private
|
34
|
+
def resolve(algorithm)
|
35
|
+
return find(algorithm) if algorithm.is_a?(String) || algorithm.is_a?(Symbol)
|
36
36
|
|
37
|
-
|
38
|
-
|
37
|
+
unless algorithm.is_a?(SigningAlgorithm)
|
38
|
+
Deprecations.warning('Custom algorithms are required to include JWT::JWA::SigningAlgorithm. Custom algorithms that do not include this module may stop working in the next major version of ruby-jwt.')
|
39
|
+
return Wrapper.new(algorithm)
|
40
|
+
end
|
39
41
|
|
40
|
-
|
42
|
+
algorithm
|
41
43
|
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
# @api private
|
46
|
+
def resolve_and_sort(algorithms:, preferred_algorithm:)
|
47
|
+
algs = Array(algorithms).map { |alg| JWA.resolve(alg) }
|
48
|
+
algs.partition { |alg| alg.valid_alg?(preferred_algorithm) }.flatten
|
46
49
|
end
|
47
50
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
fallback = [nil, Unsupported]
|
53
|
-
ALGOS.each_with_object(Hash.new(fallback)) do |cls, hash|
|
54
|
-
cls.const_get(:SUPPORTED).each do |alg|
|
55
|
-
hash[alg.downcase] = [alg, cls]
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
51
|
+
# @deprecated The `::JWT::JWA.create` method is deprecated and will be removed in the next major version of ruby-jwt.
|
52
|
+
def create(algorithm)
|
53
|
+
Deprecations.warning('The ::JWT::JWA.create method is deprecated and will be removed in the next major version of ruby-jwt.')
|
54
|
+
resolve(algorithm)
|
59
55
|
end
|
60
56
|
end
|
61
57
|
end
|
data/lib/jwt/jwk/ec.rb
CHANGED
@@ -4,6 +4,7 @@ require 'forwardable'
|
|
4
4
|
|
5
5
|
module JWT
|
6
6
|
module JWK
|
7
|
+
# JWK representation for Elliptic Curve (EC) keys
|
7
8
|
class EC < KeyBase # rubocop:disable Metrics/ClassLength
|
8
9
|
KTY = 'EC'
|
9
10
|
KTYS = [KTY, OpenSSL::PKey::EC, JWT::JWK::EC].freeze
|
@@ -65,9 +66,7 @@ module JWT
|
|
65
66
|
end
|
66
67
|
|
67
68
|
def []=(key, value)
|
68
|
-
if EC_KEY_ELEMENTS.include?(key.to_sym)
|
69
|
-
raise ArgumentError, 'cannot overwrite cryptographic key attributes'
|
70
|
-
end
|
69
|
+
raise ArgumentError, 'cannot overwrite cryptographic key attributes' if EC_KEY_ELEMENTS.include?(key.to_sym)
|
71
70
|
|
72
71
|
super(key, value)
|
73
72
|
end
|
data/lib/jwt/jwk/hmac.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWK
|
5
|
+
# JWK for HMAC keys
|
5
6
|
class HMAC < KeyBase
|
6
7
|
KTY = 'oct'
|
7
8
|
KTYS = [KTY, String, JWT::JWK::HMAC].freeze
|
@@ -61,9 +62,7 @@ module JWT
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def []=(key, value)
|
64
|
-
if HMAC_KEY_ELEMENTS.include?(key.to_sym)
|
65
|
-
raise ArgumentError, 'cannot overwrite cryptographic key attributes'
|
66
|
-
end
|
65
|
+
raise ArgumentError, 'cannot overwrite cryptographic key attributes' if HMAC_KEY_ELEMENTS.include?(key.to_sym)
|
67
66
|
|
68
67
|
super(key, value)
|
69
68
|
end
|
data/lib/jwt/jwk/key_base.rb
CHANGED
data/lib/jwt/jwk/key_finder.rb
CHANGED