jwt 2.9.3 → 2.10.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 +13 -16
- data/README.md +153 -83
- data/lib/jwt/base64.rb +3 -0
- data/lib/jwt/claims/audience.rb +10 -0
- data/lib/jwt/claims/crit.rb +35 -0
- data/lib/jwt/claims/decode_verifier.rb +3 -3
- data/lib/jwt/claims/expiration.rb +10 -0
- data/lib/jwt/claims/issued_at.rb +7 -0
- data/lib/jwt/claims/issuer.rb +10 -0
- data/lib/jwt/claims/jwt_id.rb +10 -0
- data/lib/jwt/claims/not_before.rb +10 -0
- data/lib/jwt/claims/numeric.rb +22 -0
- data/lib/jwt/claims/required.rb +10 -0
- data/lib/jwt/claims/subject.rb +10 -0
- data/lib/jwt/claims/verification_methods.rb +20 -0
- data/lib/jwt/claims/verifier.rb +6 -7
- data/lib/jwt/claims.rb +6 -14
- data/lib/jwt/claims_validator.rb +4 -2
- 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 -68
- data/lib/jwt/deprecations.rb +1 -0
- data/lib/jwt/encode.rb +17 -56
- 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 +3 -0
- data/lib/jwt/jwa/ecdsa.rb +3 -6
- data/lib/jwt/jwa/eddsa.rb +7 -6
- data/lib/jwt/jwa/hmac.rb +2 -3
- data/lib/jwt/jwa/hmac_rbnacl.rb +1 -0
- data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +1 -0
- data/lib/jwt/jwa/none.rb +1 -0
- data/lib/jwt/jwa/ps.rb +2 -3
- data/lib/jwt/jwa/rsa.rb +2 -3
- data/lib/jwt/jwa/signing_algorithm.rb +3 -0
- data/lib/jwt/jwa/unsupported.rb +1 -0
- data/lib/jwt/jwa/wrapper.rb +1 -0
- data/lib/jwt/jwa.rb +11 -3
- 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 +6 -0
- data/lib/jwt/version.rb +33 -10
- data/lib/jwt.rb +16 -0
- metadata +8 -4
data/lib/jwt/encode.rb
CHANGED
@@ -2,68 +2,29 @@
|
|
2
2
|
|
3
3
|
require_relative 'jwa'
|
4
4
|
|
5
|
-
# JWT::Encode module
|
6
5
|
module JWT
|
7
|
-
#
|
6
|
+
# The Encode class is responsible for encoding JWT tokens.
|
8
7
|
class Encode
|
8
|
+
# Initializes a new Encode instance.
|
9
|
+
#
|
10
|
+
# @param options [Hash] the options for encoding the JWT token.
|
11
|
+
# @option options [Hash] :payload the payload of the JWT token.
|
12
|
+
# @option options [Hash] :headers the headers of the JWT token.
|
13
|
+
# @option options [String] :key the key used to sign the JWT token.
|
14
|
+
# @option options [String] :algorithm the algorithm used to sign the JWT token.
|
9
15
|
def initialize(options)
|
10
|
-
@
|
11
|
-
@key
|
12
|
-
@algorithm
|
13
|
-
@headers = options[:headers].transform_keys(&:to_s)
|
16
|
+
@token = Token.new(payload: options[:payload], header: options[:headers])
|
17
|
+
@key = options[:key]
|
18
|
+
@algorithm = options[:algorithm]
|
14
19
|
end
|
15
20
|
|
21
|
+
# Encodes the JWT token and returns its segments.
|
22
|
+
#
|
23
|
+
# @return [String] the encoded JWT token.
|
16
24
|
def segments
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def encoded_header
|
24
|
-
@encoded_header ||= encode_header
|
25
|
-
end
|
26
|
-
|
27
|
-
def encoded_payload
|
28
|
-
@encoded_payload ||= encode_payload
|
29
|
-
end
|
30
|
-
|
31
|
-
def encoded_signature
|
32
|
-
@encoded_signature ||= encode_signature
|
33
|
-
end
|
34
|
-
|
35
|
-
def encoded_header_and_payload
|
36
|
-
@encoded_header_and_payload ||= combine(encoded_header, encoded_payload)
|
37
|
-
end
|
38
|
-
|
39
|
-
def encode_header
|
40
|
-
encode_data(@headers.merge(@algorithm.header(signing_key: @key)))
|
41
|
-
end
|
42
|
-
|
43
|
-
def encode_payload
|
44
|
-
encode_data(@payload)
|
45
|
-
end
|
46
|
-
|
47
|
-
def signature
|
48
|
-
@algorithm.sign(data: encoded_header_and_payload, signing_key: @key)
|
49
|
-
end
|
50
|
-
|
51
|
-
def validate_claims!
|
52
|
-
return unless @payload.is_a?(Hash)
|
53
|
-
|
54
|
-
Claims.verify_payload!(@payload, :numeric)
|
55
|
-
end
|
56
|
-
|
57
|
-
def encode_signature
|
58
|
-
::JWT::Base64.url_encode(signature)
|
59
|
-
end
|
60
|
-
|
61
|
-
def encode_data(data)
|
62
|
-
::JWT::Base64.url_encode(JWT::JSON.generate(data))
|
63
|
-
end
|
64
|
-
|
65
|
-
def combine(*parts)
|
66
|
-
parts.join('.')
|
25
|
+
@token.verify_claims!(:numeric)
|
26
|
+
@token.sign!(algorithm: @algorithm, key: @key)
|
27
|
+
@token.jwt
|
67
28
|
end
|
68
29
|
end
|
69
30
|
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
# Represents an encoded JWT token
|
5
|
+
#
|
6
|
+
# Processing an encoded and signed token:
|
7
|
+
#
|
8
|
+
# token = JWT::Token.new(payload: {pay: 'load'})
|
9
|
+
# token.sign!(algorithm: 'HS256', key: 'secret')
|
10
|
+
#
|
11
|
+
# encoded_token = JWT::EncodedToken.new(token.jwt)
|
12
|
+
# encoded_token.verify_signature!(algorithm: 'HS256', key: 'secret')
|
13
|
+
# encoded_token.payload # => {'pay' => 'load'}
|
14
|
+
class EncodedToken
|
15
|
+
include Claims::VerificationMethods
|
16
|
+
|
17
|
+
# Returns the original token provided to the class.
|
18
|
+
# @return [String] The JWT token.
|
19
|
+
attr_reader :jwt
|
20
|
+
|
21
|
+
# Initializes a new EncodedToken instance.
|
22
|
+
#
|
23
|
+
# @param jwt [String] the encoded JWT token.
|
24
|
+
# @raise [ArgumentError] if the provided JWT is not a String.
|
25
|
+
def initialize(jwt)
|
26
|
+
raise ArgumentError, 'Provided JWT must be a String' unless jwt.is_a?(String)
|
27
|
+
|
28
|
+
@jwt = jwt
|
29
|
+
@encoded_header, @encoded_payload, @encoded_signature = jwt.split('.')
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the decoded signature of the JWT token.
|
33
|
+
#
|
34
|
+
# @return [String] the decoded signature.
|
35
|
+
def signature
|
36
|
+
@signature ||= ::JWT::Base64.url_decode(encoded_signature || '')
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the encoded signature of the JWT token.
|
40
|
+
#
|
41
|
+
# @return [String] the encoded signature.
|
42
|
+
attr_reader :encoded_signature
|
43
|
+
|
44
|
+
# Returns the decoded header of the JWT token.
|
45
|
+
#
|
46
|
+
# @return [Hash] the header.
|
47
|
+
def header
|
48
|
+
@header ||= parse_and_decode(@encoded_header)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the encoded header of the JWT token.
|
52
|
+
#
|
53
|
+
# @return [String] the encoded header.
|
54
|
+
attr_reader :encoded_header
|
55
|
+
|
56
|
+
# Returns the payload of the JWT token.
|
57
|
+
#
|
58
|
+
# @return [Hash] the payload.
|
59
|
+
def payload
|
60
|
+
@payload ||= decode_payload
|
61
|
+
end
|
62
|
+
|
63
|
+
# Sets or returns the encoded payload of the JWT token.
|
64
|
+
#
|
65
|
+
# @return [String] the encoded payload.
|
66
|
+
attr_accessor :encoded_payload
|
67
|
+
|
68
|
+
# Returns the signing input of the JWT token.
|
69
|
+
#
|
70
|
+
# @return [String] the signing input.
|
71
|
+
def signing_input
|
72
|
+
[encoded_header, encoded_payload].join('.')
|
73
|
+
end
|
74
|
+
|
75
|
+
# Verifies the signature of the JWT token.
|
76
|
+
#
|
77
|
+
# @param algorithm [String, Array<String>, Object, Array<Object>] the algorithm(s) to use for verification.
|
78
|
+
# @param key [String, Array<String>] the key(s) to use for verification.
|
79
|
+
# @param key_finder [#call] an object responding to `call` to find the key for verification.
|
80
|
+
# @return [nil]
|
81
|
+
# @raise [JWT::VerificationError] if the signature verification fails.
|
82
|
+
# @raise [ArgumentError] if neither key nor key_finder is provided, or if both are provided.
|
83
|
+
def verify_signature!(algorithm:, key: nil, key_finder: nil)
|
84
|
+
raise ArgumentError, 'Provide either key or key_finder, not both or neither' if key.nil? == key_finder.nil?
|
85
|
+
|
86
|
+
key ||= key_finder.call(self)
|
87
|
+
|
88
|
+
return if valid_signature?(algorithm: algorithm, key: key)
|
89
|
+
|
90
|
+
raise JWT::VerificationError, 'Signature verification failed'
|
91
|
+
end
|
92
|
+
|
93
|
+
# Checks if the signature of the JWT token is valid.
|
94
|
+
#
|
95
|
+
# @param algorithm [String, Array<String>, Object, Array<Object>] the algorithm(s) to use for verification.
|
96
|
+
# @param key [String, Array<String>] the key(s) to use for verification.
|
97
|
+
# @return [Boolean] true if the signature is valid, false otherwise.
|
98
|
+
def valid_signature?(algorithm:, key:)
|
99
|
+
Array(JWA.resolve_and_sort(algorithms: algorithm, preferred_algorithm: header['alg'])).any? do |algo|
|
100
|
+
Array(key).any? do |one_key|
|
101
|
+
algo.verify(data: signing_input, signature: signature, verification_key: one_key)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
alias to_s jwt
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def decode_payload
|
111
|
+
raise JWT::DecodeError, 'Encoded payload is empty' if encoded_payload == ''
|
112
|
+
|
113
|
+
if unencoded_payload?
|
114
|
+
verify_claims!(crit: ['b64'])
|
115
|
+
return parse_unencoded(encoded_payload)
|
116
|
+
end
|
117
|
+
|
118
|
+
parse_and_decode(encoded_payload)
|
119
|
+
end
|
120
|
+
|
121
|
+
def unencoded_payload?
|
122
|
+
header['b64'] == false
|
123
|
+
end
|
124
|
+
|
125
|
+
def parse_and_decode(segment)
|
126
|
+
parse(::JWT::Base64.url_decode(segment || ''))
|
127
|
+
end
|
128
|
+
|
129
|
+
def parse_unencoded(segment)
|
130
|
+
parse(segment)
|
131
|
+
end
|
132
|
+
|
133
|
+
def parse(segment)
|
134
|
+
JWT::JSON.parse(segment)
|
135
|
+
rescue ::JSON::ParserError
|
136
|
+
raise JWT::DecodeError, 'Invalid segment encoding'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/lib/jwt/error.rb
CHANGED
@@ -1,23 +1,57 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module JWT
|
4
|
+
# The EncodeError class is raised when there is an error encoding a JWT.
|
4
5
|
class EncodeError < StandardError; end
|
6
|
+
|
7
|
+
# The DecodeError class is raised when there is an error decoding a JWT.
|
5
8
|
class DecodeError < StandardError; end
|
9
|
+
|
10
|
+
# The RequiredDependencyError class is raised when a required dependency is missing.
|
6
11
|
class RequiredDependencyError < StandardError; end
|
7
12
|
|
13
|
+
# The VerificationError class is raised when there is an error verifying a JWT.
|
8
14
|
class VerificationError < DecodeError; end
|
15
|
+
|
16
|
+
# The ExpiredSignature class is raised when the JWT signature has expired.
|
9
17
|
class ExpiredSignature < DecodeError; end
|
18
|
+
|
19
|
+
# The IncorrectAlgorithm class is raised when the JWT algorithm is incorrect.
|
10
20
|
class IncorrectAlgorithm < DecodeError; end
|
21
|
+
|
22
|
+
# The ImmatureSignature class is raised when the JWT signature is immature.
|
11
23
|
class ImmatureSignature < DecodeError; end
|
24
|
+
|
25
|
+
# The InvalidIssuerError class is raised when the JWT issuer is invalid.
|
12
26
|
class InvalidIssuerError < DecodeError; end
|
27
|
+
|
28
|
+
# The UnsupportedEcdsaCurve class is raised when the ECDSA curve is unsupported.
|
13
29
|
class UnsupportedEcdsaCurve < IncorrectAlgorithm; end
|
30
|
+
|
31
|
+
# The InvalidIatError class is raised when the JWT issued at (iat) claim is invalid.
|
14
32
|
class InvalidIatError < DecodeError; end
|
33
|
+
|
34
|
+
# The InvalidAudError class is raised when the JWT audience (aud) claim is invalid.
|
15
35
|
class InvalidAudError < DecodeError; end
|
36
|
+
|
37
|
+
# The InvalidSubError class is raised when the JWT subject (sub) claim is invalid.
|
16
38
|
class InvalidSubError < DecodeError; end
|
39
|
+
|
40
|
+
# The InvalidCritError class is raised when the JWT crit header is invalid.
|
41
|
+
class InvalidCritError < DecodeError; end
|
42
|
+
|
43
|
+
# The InvalidJtiError class is raised when the JWT ID (jti) claim is invalid.
|
17
44
|
class InvalidJtiError < DecodeError; end
|
45
|
+
|
46
|
+
# The InvalidPayload class is raised when the JWT payload is invalid.
|
18
47
|
class InvalidPayload < DecodeError; end
|
48
|
+
|
49
|
+
# The MissingRequiredClaim class is raised when a required claim is missing from the JWT.
|
19
50
|
class MissingRequiredClaim < DecodeError; end
|
51
|
+
|
52
|
+
# The Base64DecodeError class is raised when there is an error decoding a Base64-encoded string.
|
20
53
|
class Base64DecodeError < DecodeError; end
|
21
54
|
|
55
|
+
# The JWKError class is raised when there is an error with the JSON Web Key (JWK).
|
22
56
|
class JWKError < DecodeError; end
|
23
57
|
end
|
data/lib/jwt/json.rb
CHANGED
data/lib/jwt/jwa/compat.rb
CHANGED
data/lib/jwt/jwa/ecdsa.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
+
# ECDSA signing algorithm
|
5
6
|
class Ecdsa
|
6
7
|
include JWT::JWA::SigningAlgorithm
|
7
8
|
|
@@ -13,9 +14,7 @@ module JWT
|
|
13
14
|
def sign(data:, signing_key:)
|
14
15
|
curve_definition = curve_by_name(signing_key.group.curve_name)
|
15
16
|
key_algorithm = curve_definition[:algorithm]
|
16
|
-
if alg != key_algorithm
|
17
|
-
raise IncorrectAlgorithm, "payload algorithm is #{alg} but #{key_algorithm} signing key was provided"
|
18
|
-
end
|
17
|
+
raise IncorrectAlgorithm, "payload algorithm is #{alg} but #{key_algorithm} signing key was provided" if alg != key_algorithm
|
19
18
|
|
20
19
|
asn1_to_raw(signing_key.dsa_sign_asn1(digest.digest(data)), signing_key)
|
21
20
|
end
|
@@ -23,9 +22,7 @@ module JWT
|
|
23
22
|
def verify(data:, signature:, verification_key:)
|
24
23
|
curve_definition = curve_by_name(verification_key.group.curve_name)
|
25
24
|
key_algorithm = curve_definition[:algorithm]
|
26
|
-
if alg != key_algorithm
|
27
|
-
raise IncorrectAlgorithm, "payload algorithm is #{alg} but #{key_algorithm} verification key was provided"
|
28
|
-
end
|
25
|
+
raise IncorrectAlgorithm, "payload algorithm is #{alg} but #{key_algorithm} verification key was provided" if alg != key_algorithm
|
29
26
|
|
30
27
|
verification_key.dsa_verify_asn1(digest.digest(data), raw_to_asn1(signature, verification_key))
|
31
28
|
rescue OpenSSL::PKey::PKeyError
|
data/lib/jwt/jwa/eddsa.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
+
# Implementation of the EdDSA family of algorithms
|
5
6
|
class Eddsa
|
6
7
|
include JWT::JWA::SigningAlgorithm
|
7
8
|
|
@@ -10,17 +11,17 @@ module JWT
|
|
10
11
|
end
|
11
12
|
|
12
13
|
def sign(data:, signing_key:)
|
13
|
-
unless signing_key.is_a?(RbNaCl::Signatures::Ed25519::SigningKey)
|
14
|
-
|
15
|
-
|
14
|
+
raise_sign_error!("Key given is a #{signing_key.class} but has to be an RbNaCl::Signatures::Ed25519::SigningKey") unless signing_key.is_a?(RbNaCl::Signatures::Ed25519::SigningKey)
|
15
|
+
|
16
|
+
Deprecations.warning('Using Ed25519 keys is deprecated and will be removed in a future version of ruby-jwt. Please use the ruby-eddsa gem instead.')
|
16
17
|
|
17
18
|
signing_key.sign(data)
|
18
19
|
end
|
19
20
|
|
20
21
|
def verify(data:, signature:, verification_key:)
|
21
|
-
unless verification_key.is_a?(RbNaCl::Signatures::Ed25519::VerifyKey)
|
22
|
-
|
23
|
-
|
22
|
+
raise_verify_error!("key given is a #{verification_key.class} but has to be a RbNaCl::Signatures::Ed25519::VerifyKey") unless verification_key.is_a?(RbNaCl::Signatures::Ed25519::VerifyKey)
|
23
|
+
|
24
|
+
Deprecations.warning('Using Ed25519 keys is deprecated and will be removed in a future version of ruby-jwt. Please use the ruby-eddsa gem instead.')
|
24
25
|
|
25
26
|
verification_key.verify(signature, data)
|
26
27
|
rescue RbNaCl::CryptoError
|
data/lib/jwt/jwa/hmac.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
+
# Implementation of the HMAC family of algorithms
|
5
6
|
class Hmac
|
6
7
|
include JWT::JWA::SigningAlgorithm
|
7
8
|
|
@@ -20,9 +21,7 @@ module JWT
|
|
20
21
|
|
21
22
|
OpenSSL::HMAC.digest(digest.new, signing_key, data)
|
22
23
|
rescue OpenSSL::HMACError => e
|
23
|
-
if signing_key == '' && e.message == 'EVP_PKEY_new_mac_key: malloc failure'
|
24
|
-
raise_verify_error!('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
|
data/lib/jwt/jwa/hmac_rbnacl.rb
CHANGED
data/lib/jwt/jwa/none.rb
CHANGED
data/lib/jwt/jwa/ps.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
+
# Implementation of the RSASSA-PSS family of algorithms
|
5
6
|
class Ps
|
6
7
|
include JWT::JWA::SigningAlgorithm
|
7
8
|
|
@@ -11,9 +12,7 @@ module JWT
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def sign(data:, signing_key:)
|
14
|
-
unless signing_key.is_a?(::OpenSSL::PKey::RSA)
|
15
|
-
raise_sign_error!("The given key is a #{signing_key.class}. It has to be an OpenSSL::PKey::RSA instance.")
|
16
|
-
end
|
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)
|
17
16
|
|
18
17
|
signing_key.sign_pss(digest_algorithm, data, salt_length: :digest, mgf1_hash: digest_algorithm)
|
19
18
|
end
|
data/lib/jwt/jwa/rsa.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWA
|
5
|
+
# Implementation of the RSA family of algorithms
|
5
6
|
class Rsa
|
6
7
|
include JWT::JWA::SigningAlgorithm
|
7
8
|
|
@@ -11,9 +12,7 @@ module JWT
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def sign(data:, signing_key:)
|
14
|
-
unless signing_key.is_a?(OpenSSL::PKey::RSA)
|
15
|
-
raise_sign_error!("The given key is a #{signing_key.class}. It has to be an OpenSSL::PKey::RSA instance")
|
16
|
-
end
|
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)
|
17
16
|
|
18
17
|
signing_key.sign(digest, data)
|
19
18
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module JWT
|
4
|
+
# JSON Web Algorithms
|
4
5
|
module JWA
|
6
|
+
# Base functionality for signing algorithms
|
5
7
|
module SigningAlgorithm
|
8
|
+
# Class methods for the SigningAlgorithm module
|
6
9
|
module ClassMethods
|
7
10
|
def register_algorithm(algo)
|
8
11
|
::JWT::JWA.register_algorithm(algo)
|
data/lib/jwt/jwa/unsupported.rb
CHANGED
data/lib/jwt/jwa/wrapper.rb
CHANGED
data/lib/jwt/jwa.rb
CHANGED
@@ -18,9 +18,7 @@ require_relative 'jwa/rsa'
|
|
18
18
|
require_relative 'jwa/unsupported'
|
19
19
|
require_relative 'jwa/wrapper'
|
20
20
|
|
21
|
-
if JWT.rbnacl?
|
22
|
-
require_relative 'jwa/eddsa'
|
23
|
-
end
|
21
|
+
require_relative 'jwa/eddsa' if JWT.rbnacl?
|
24
22
|
|
25
23
|
if JWT.rbnacl_6_or_greater?
|
26
24
|
require_relative 'jwa/hmac_rbnacl'
|
@@ -29,8 +27,10 @@ elsif JWT.rbnacl?
|
|
29
27
|
end
|
30
28
|
|
31
29
|
module JWT
|
30
|
+
# The JWA module contains all supported algorithms.
|
32
31
|
module JWA
|
33
32
|
class << self
|
33
|
+
# @api private
|
34
34
|
def resolve(algorithm)
|
35
35
|
return find(algorithm) if algorithm.is_a?(String) || algorithm.is_a?(Symbol)
|
36
36
|
|
@@ -42,7 +42,15 @@ module JWT
|
|
42
42
|
algorithm
|
43
43
|
end
|
44
44
|
|
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
|
49
|
+
end
|
50
|
+
|
51
|
+
# @deprecated The `::JWT::JWA.create` method is deprecated and will be removed in the next major version of ruby-jwt.
|
45
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.')
|
46
54
|
resolve(algorithm)
|
47
55
|
end
|
48
56
|
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
data/lib/jwt/jwk/okp_rbnacl.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWK
|
5
|
+
# JSON Web Key (JWK) representation for Ed25519 keys
|
5
6
|
class OKPRbNaCl < KeyBase
|
6
7
|
KTY = 'OKP'
|
7
8
|
KTYS = [KTY, JWT::JWK::OKPRbNaCl, RbNaCl::Signatures::Ed25519::SigningKey, RbNaCl::Signatures::Ed25519::VerifyKey].freeze
|
@@ -10,7 +11,7 @@ module JWT
|
|
10
11
|
|
11
12
|
def initialize(key, params = nil, options = {})
|
12
13
|
params ||= {}
|
13
|
-
|
14
|
+
Deprecations.warning('Using the OKP JWK for Ed25519 keys is deprecated and will be removed in a future version of ruby-jwt. Please use the ruby-eddsa gem instead.')
|
14
15
|
# For backwards compatibility when kid was a String
|
15
16
|
params = { kid: params } if params.is_a?(String)
|
16
17
|
|
@@ -83,9 +84,7 @@ module JWT
|
|
83
84
|
x: ::JWT::Base64.url_encode(verify_key.to_bytes)
|
84
85
|
}
|
85
86
|
|
86
|
-
if signing_key
|
87
|
-
params[:d] = ::JWT::Base64.url_encode(signing_key.to_bytes)
|
88
|
-
end
|
87
|
+
params[:d] = ::JWT::Base64.url_encode(signing_key.to_bytes) if signing_key
|
89
88
|
|
90
89
|
params
|
91
90
|
end
|
data/lib/jwt/jwk/rsa.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module JWT
|
4
4
|
module JWK
|
5
|
+
# JSON Web Key (JWK) representation of a RSA key
|
5
6
|
class RSA < KeyBase # rubocop:disable Metrics/ClassLength
|
6
7
|
BINARY = 2
|
7
8
|
KTY = 'RSA'
|
@@ -64,9 +65,7 @@ module JWT
|
|
64
65
|
end
|
65
66
|
|
66
67
|
def []=(key, value)
|
67
|
-
if RSA_KEY_ELEMENTS.include?(key.to_sym)
|
68
|
-
raise ArgumentError, 'cannot overwrite cryptographic key attributes'
|
69
|
-
end
|
68
|
+
raise ArgumentError, 'cannot overwrite cryptographic key attributes' if RSA_KEY_ELEMENTS.include?(key.to_sym)
|
70
69
|
|
71
70
|
super(key, value)
|
72
71
|
end
|
data/lib/jwt/jwk/set.rb
CHANGED