jwt 2.8.1 → 2.9.3

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.
data/lib/jwt/decode.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
-
5
- require 'jwt/verify'
6
4
  require 'jwt/x5c_key_finder'
7
5
 
8
6
  # JWT::Decode module
@@ -10,7 +8,7 @@ module JWT
10
8
  # Decoding logic for JWT
11
9
  class Decode
12
10
  def initialize(jwt, key, verify, options, &keyfinder)
13
- raise(JWT::DecodeError, 'Nil JSON web token') unless jwt
11
+ raise JWT::DecodeError, 'Nil JSON web token' unless jwt
14
12
 
15
13
  @jwt = jwt
16
14
  @key = key
@@ -30,7 +28,7 @@ module JWT
30
28
  verify_signature
31
29
  verify_claims
32
30
  end
33
- raise(JWT::DecodeError, 'Not enough or too many segments') unless header && payload
31
+ raise JWT::DecodeError, 'Not enough or too many segments' unless header && payload
34
32
 
35
33
  [payload, header]
36
34
  end
@@ -46,21 +44,22 @@ module JWT
46
44
 
47
45
  return if Array(@key).any? { |key| verify_signature_for?(key) }
48
46
 
49
- raise(JWT::VerificationError, 'Signature verification failed')
47
+ raise JWT::VerificationError, 'Signature verification failed'
50
48
  end
51
49
 
52
50
  def verify_algo
53
- raise(JWT::IncorrectAlgorithm, 'An algorithm must be specified') if allowed_algorithms.empty?
54
- raise(JWT::IncorrectAlgorithm, 'Token is missing alg header') unless alg_in_header
55
- raise(JWT::IncorrectAlgorithm, 'Expected a different algorithm') if allowed_and_valid_algorithms.empty?
51
+ raise JWT::IncorrectAlgorithm, 'An algorithm must be specified' if allowed_algorithms.empty?
52
+ raise JWT::DecodeError, 'Token header not a JSON object' unless header.is_a?(Hash)
53
+ raise JWT::IncorrectAlgorithm, 'Token is missing alg header' unless alg_in_header
54
+ raise JWT::IncorrectAlgorithm, 'Expected a different algorithm' if allowed_and_valid_algorithms.empty?
56
55
  end
57
56
 
58
57
  def set_key
59
58
  @key = find_key(&@keyfinder) if @keyfinder
60
59
  @key = ::JWT::JWK::KeyFinder.new(jwks: @options[:jwks], allow_nil_kid: @options[:allow_nil_kid]).key_for(header['kid']) if @options[:jwks]
61
- if (x5c_options = @options[:x5c])
62
- @key = X5cKeyFinder.new(x5c_options[:root_certificates], x5c_options[:crls]).from(header['x5c'])
63
- end
60
+ return unless (x5c_options = @options[:x5c])
61
+
62
+ @key = X5cKeyFinder.new(x5c_options[:root_certificates], x5c_options[:crls]).from(header['x5c'])
64
63
  end
65
64
 
66
65
  def verify_signature_for?(key)
@@ -92,7 +91,7 @@ module JWT
92
91
  end
93
92
 
94
93
  def resolve_allowed_algorithms
95
- algs = given_algorithms.map { |alg| JWA.create(alg) }
94
+ algs = given_algorithms.map { |alg| JWA.resolve(alg) }
96
95
 
97
96
  sort_by_alg_header(algs)
98
97
  end
@@ -113,8 +112,7 @@ module JWT
113
112
  end
114
113
 
115
114
  def verify_claims
116
- Verify.verify_claims(payload, @options)
117
- Verify.verify_required_claims(payload, @options)
115
+ Claims::DecodeVerifier.verify!(payload, @options)
118
116
  end
119
117
 
120
118
  def validate_segment_count!
@@ -122,7 +120,7 @@ module JWT
122
120
  return if !@verify && segment_length == 2 # If no verifying required, the signature is not needed
123
121
  return if segment_length == 2 && none_algorithm?
124
122
 
125
- raise(JWT::DecodeError, 'Not enough or too many segments')
123
+ raise JWT::DecodeError, 'Not enough or too many segments'
126
124
  end
127
125
 
128
126
  def segment_length
@@ -4,15 +4,34 @@ module JWT
4
4
  # Deprecations module to handle deprecation warnings in the gem
5
5
  module Deprecations
6
6
  class << self
7
- def warning(message)
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
8
15
  case JWT.configuration.deprecation_warnings
9
- when :warn
10
- warn("[DEPRECATION WARNING] #{message}")
11
16
  when :once
12
17
  return if record_warned(message)
13
-
14
- warn("[DEPRECATION WARNING] #{message}")
18
+ when :warn
19
+ # noop
20
+ else
21
+ return
15
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) }
16
35
  end
17
36
 
18
37
  private
data/lib/jwt/encode.rb CHANGED
@@ -1,20 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'jwa'
4
- require_relative 'claims_validator'
5
4
 
6
5
  # JWT::Encode module
7
6
  module JWT
8
7
  # Encoding logic for JWT
9
8
  class Encode
10
- ALG_KEY = 'alg'
11
-
12
9
  def initialize(options)
13
10
  @payload = options[:payload]
14
11
  @key = options[:key]
15
- @algorithm = JWA.create(options[:algorithm])
12
+ @algorithm = JWA.resolve(options[:algorithm])
16
13
  @headers = options[:headers].transform_keys(&:to_s)
17
- @headers[ALG_KEY] = @algorithm.alg
18
14
  end
19
15
 
20
16
  def segments
@@ -41,7 +37,7 @@ module JWT
41
37
  end
42
38
 
43
39
  def encode_header
44
- encode_data(@headers)
40
+ encode_data(@headers.merge(@algorithm.header(signing_key: @key)))
45
41
  end
46
42
 
47
43
  def encode_payload
@@ -55,7 +51,7 @@ module JWT
55
51
  def validate_claims!
56
52
  return unless @payload.is_a?(Hash)
57
53
 
58
- ClaimsValidator.new(@payload).validate!
54
+ Claims.verify_payload!(@payload, :numeric)
59
55
  end
60
56
 
61
57
  def encode_signature
@@ -0,0 +1,29 @@
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/ecdsa.rb CHANGED
@@ -2,8 +2,35 @@
2
2
 
3
3
  module JWT
4
4
  module JWA
5
- module Ecdsa
6
- module_function
5
+ class Ecdsa
6
+ include JWT::JWA::SigningAlgorithm
7
+
8
+ def initialize(alg, digest)
9
+ @alg = alg
10
+ @digest = OpenSSL::Digest.new(digest)
11
+ end
12
+
13
+ def sign(data:, signing_key:)
14
+ curve_definition = curve_by_name(signing_key.group.curve_name)
15
+ 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
19
+
20
+ asn1_to_raw(signing_key.dsa_sign_asn1(digest.digest(data)), signing_key)
21
+ end
22
+
23
+ def verify(data:, signature:, verification_key:)
24
+ curve_definition = curve_by_name(verification_key.group.curve_name)
25
+ 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
29
+
30
+ verification_key.dsa_verify_asn1(digest.digest(data), raw_to_asn1(signature, verification_key))
31
+ rescue OpenSSL::PKey::PKeyError
32
+ raise JWT::VerificationError, 'Signature verification raised'
33
+ end
7
34
 
8
35
  NAMED_CURVES = {
9
36
  'prime256v1' => {
@@ -28,38 +55,28 @@ module JWT
28
55
  }
29
56
  }.freeze
30
57
 
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
- asn1_to_raw(key.dsa_sign_asn1(digest.digest(msg)), key)
58
+ NAMED_CURVES.each_value do |v|
59
+ register_algorithm(new(v[:algorithm], v[:digest]))
42
60
  end
43
61
 
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), raw_to_asn1(signature, public_key))
53
- rescue OpenSSL::PKey::PKeyError
54
- raise JWT::VerificationError, 'Signature verification raised'
62
+ def self.from_algorithm(algorithm)
63
+ new(algorithm, algorithm.downcase.gsub('es', 'sha'))
55
64
  end
56
65
 
57
- def curve_by_name(name)
66
+ def self.curve_by_name(name)
58
67
  NAMED_CURVES.fetch(name) do
59
68
  raise UnsupportedEcdsaCurve, "The ECDSA curve '#{name}' is not supported"
60
69
  end
61
70
  end
62
71
 
72
+ private
73
+
74
+ attr_reader :digest
75
+
76
+ def curve_by_name(name)
77
+ self.class.curve_by_name(name)
78
+ end
79
+
63
80
  def raw_to_asn1(signature, private_key)
64
81
  byte_size = (private_key.group.degree + 7) / 8
65
82
  sig_bytes = signature[0..(byte_size - 1)]
data/lib/jwt/jwa/eddsa.rb CHANGED
@@ -2,41 +2,33 @@
2
2
 
3
3
  module JWT
4
4
  module JWA
5
- module Eddsa
6
- SUPPORTED = %w[ED25519 EdDSA].freeze
7
- SUPPORTED_DOWNCASED = SUPPORTED.map(&:downcase).freeze
5
+ class Eddsa
6
+ include JWT::JWA::SigningAlgorithm
8
7
 
9
- class << self
10
- def sign(algorithm, msg, key)
11
- unless key.is_a?(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
-
15
- validate_algorithm!(algorithm)
8
+ def initialize(alg)
9
+ @alg = alg
10
+ end
16
11
 
17
- key.sign(msg)
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")
18
15
  end
19
16
 
20
- def verify(algorithm, public_key, signing_input, signature)
21
- unless public_key.is_a?(RbNaCl::Signatures::Ed25519::VerifyKey)
22
- raise DecodeError, "key given is a #{public_key.class} but has to be a RbNaCl::Signatures::Ed25519::VerifyKey"
23
- end
24
-
25
- validate_algorithm!(algorithm)
17
+ signing_key.sign(data)
18
+ end
26
19
 
27
- public_key.verify(signature, signing_input)
28
- rescue RbNaCl::CryptoError
29
- false
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")
30
23
  end
31
24
 
32
- private
33
-
34
- def validate_algorithm!(algorithm)
35
- return if SUPPORTED_DOWNCASED.include?(algorithm.downcase)
36
-
37
- raise IncorrectAlgorithm, "Algorithm #{algorithm} not supported. Supported algoritms are #{SUPPORTED.join(', ')}"
38
- end
25
+ verification_key.verify(signature, data)
26
+ rescue RbNaCl::CryptoError
27
+ false
39
28
  end
29
+
30
+ register_algorithm(new('ED25519'))
31
+ register_algorithm(new('EdDSA'))
40
32
  end
41
33
  end
42
34
  end
data/lib/jwt/jwa/hmac.rb CHANGED
@@ -2,35 +2,43 @@
2
2
 
3
3
  module JWT
4
4
  module JWA
5
- module Hmac
6
- module_function
5
+ class Hmac
6
+ include JWT::JWA::SigningAlgorithm
7
7
 
8
- MAPPING = {
9
- 'HS256' => OpenSSL::Digest::SHA256,
10
- 'HS384' => OpenSSL::Digest::SHA384,
11
- 'HS512' => OpenSSL::Digest::SHA512
12
- }.freeze
13
-
14
- SUPPORTED = MAPPING.keys
8
+ def self.from_algorithm(algorithm)
9
+ new(algorithm, OpenSSL::Digest.new(algorithm.downcase.gsub('hs', 'sha')))
10
+ end
15
11
 
16
- def sign(algorithm, msg, key)
17
- key ||= ''
12
+ def initialize(alg, digest)
13
+ @alg = alg
14
+ @digest = digest
15
+ end
18
16
 
19
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
17
+ def sign(data:, signing_key:)
18
+ signing_key ||= ''
19
+ raise_verify_error!('HMAC key expected to be a String') unless signing_key.is_a?(String)
20
20
 
21
- OpenSSL::HMAC.digest(MAPPING[algorithm].new, key, msg)
21
+ OpenSSL::HMAC.digest(digest.new, signing_key, data)
22
22
  rescue OpenSSL::HMACError => e
23
- if key == '' && e.message == 'EVP_PKEY_new_mac_key: malloc failure'
24
- raise JWT::DecodeError, 'OpenSSL 3.0 does not support nil or empty hmac_secret'
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
25
  end
26
26
 
27
27
  raise e
28
28
  end
29
29
 
30
- def verify(algorithm, key, signing_input, signature)
31
- SecurityUtils.secure_compare(signature, sign(algorithm, signing_input, key))
30
+ def verify(data:, signature:, verification_key:)
31
+ SecurityUtils.secure_compare(signature, sign(data: data, signing_key: verification_key))
32
32
  end
33
33
 
34
+ register_algorithm(new('HS256', OpenSSL::Digest::SHA256))
35
+ register_algorithm(new('HS384', OpenSSL::Digest::SHA384))
36
+ register_algorithm(new('HS512', OpenSSL::Digest::SHA512))
37
+
38
+ private
39
+
40
+ attr_reader :digest
41
+
34
42
  # Copy of https://github.com/rails/rails/blob/v7.0.3.1/activesupport/lib/active_support/security_utils.rb
35
43
  # rubocop:disable Naming/MethodParameterName, Style/StringLiterals, Style/NumericPredicate
36
44
  module SecurityUtils
@@ -1,49 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JWT
4
- module Algos
5
- module HmacRbNaCl
6
- MAPPING = { 'HS512256' => ::RbNaCl::HMAC::SHA512256 }.freeze
7
- SUPPORTED = MAPPING.keys
8
- class << self
9
- def sign(algorithm, msg, key)
10
- Deprecations.warning("The use of the algorithm #{algorithm} is deprecated and will be removed in the next major version of ruby-jwt")
11
- if (hmac = resolve_algorithm(algorithm))
12
- hmac.auth(key_for_rbnacl(hmac, key).encode('binary'), msg.encode('binary'))
13
- else
14
- Hmac.sign(algorithm, msg, key)
15
- end
16
- end
17
-
18
- def verify(algorithm, key, signing_input, signature)
19
- Deprecations.warning("The use of the algorithm #{algorithm} is deprecated and will be removed in the next major version of ruby-jwt")
20
- if (hmac = resolve_algorithm(algorithm))
21
- hmac.verify(key_for_rbnacl(hmac, key).encode('binary'), signature.encode('binary'), signing_input.encode('binary'))
22
- else
23
- Hmac.verify(algorithm, key, signing_input, signature)
24
- end
25
- rescue ::RbNaCl::BadAuthenticatorError, ::RbNaCl::LengthError
26
- false
27
- end
28
-
29
- private
30
-
31
- def key_for_rbnacl(hmac, key)
32
- key ||= ''
33
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
34
-
35
- return padded_empty_key(hmac.key_bytes) if key == ''
36
-
37
- key
38
- end
39
-
40
- def resolve_algorithm(algorithm)
41
- MAPPING.fetch(algorithm)
42
- end
43
-
44
- def padded_empty_key(length)
45
- Array.new(length, 0x0).pack('C*').encode('binary')
46
- end
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')
47
46
  end
48
47
  end
49
48
  end
@@ -1,45 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JWT
4
- module Algos
5
- module HmacRbNaClFixed
6
- MAPPING = { 'HS512256' => ::RbNaCl::HMAC::SHA512256 }.freeze
7
- SUPPORTED = MAPPING.keys
8
-
9
- class << self
10
- def sign(algorithm, msg, key)
11
- key ||= ''
12
- Deprecations.warning("The use of the algorithm #{algorithm} is deprecated and will be removed in the next major version of ruby-jwt")
13
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
14
-
15
- if (hmac = resolve_algorithm(algorithm)) && key.bytesize <= hmac.key_bytes
16
- hmac.auth(padded_key_bytes(key, hmac.key_bytes), msg.encode('binary'))
17
- else
18
- Hmac.sign(algorithm, msg, key)
19
- end
20
- end
21
-
22
- def verify(algorithm, key, signing_input, signature)
23
- key ||= ''
24
- Deprecations.warning("The use of the algorithm #{algorithm} is deprecated and will be removed in the next major version of ruby-jwt")
25
- raise JWT::DecodeError, 'HMAC key expected to be a String' unless key.is_a?(String)
26
-
27
- if (hmac = resolve_algorithm(algorithm)) && key.bytesize <= hmac.key_bytes
28
- hmac.verify(padded_key_bytes(key, hmac.key_bytes), signature.encode('binary'), signing_input.encode('binary'))
29
- else
30
- Hmac.verify(algorithm, key, signing_input, signature)
31
- end
32
- rescue ::RbNaCl::BadAuthenticatorError, ::RbNaCl::LengthError
33
- false
34
- end
35
-
36
- def resolve_algorithm(algorithm)
37
- MAPPING.fetch(algorithm)
38
- end
39
-
40
- def padded_key_bytes(key, bytesize)
41
- key.bytes.fill(0, key.bytesize...bytesize).pack('C*')
42
- end
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
43
  end
44
44
  end
45
45
  end
data/lib/jwt/jwa/none.rb CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
  module JWT
4
4
  module JWA
5
- module None
6
- module_function
5
+ class None
6
+ include JWT::JWA::SigningAlgorithm
7
7
 
8
- SUPPORTED = %w[none].freeze
8
+ def initialize
9
+ @alg = 'none'
10
+ end
9
11
 
10
12
  def sign(*)
11
13
  ''
@@ -14,6 +16,8 @@ module JWT
14
16
  def verify(*)
15
17
  true
16
18
  end
19
+
20
+ register_algorithm(new)
17
21
  end
18
22
  end
19
23
  end
data/lib/jwt/jwa/ps.rb CHANGED
@@ -2,29 +2,35 @@
2
2
 
3
3
  module JWT
4
4
  module JWA
5
- module Ps
6
- # RSASSA-PSS signing algorithms
5
+ class Ps
6
+ include JWT::JWA::SigningAlgorithm
7
7
 
8
- module_function
9
-
10
- SUPPORTED = %w[PS256 PS384 PS512].freeze
8
+ def initialize(alg)
9
+ @alg = alg
10
+ @digest_algorithm = alg.sub('PS', 'sha')
11
+ end
11
12
 
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."
13
+ 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.")
15
16
  end
16
17
 
17
- translated_algorithm = algorithm.sub('PS', 'sha')
18
-
19
- key.sign_pss(translated_algorithm, msg, salt_length: :digest, mgf1_hash: translated_algorithm)
18
+ signing_key.sign_pss(digest_algorithm, data, salt_length: :digest, mgf1_hash: digest_algorithm)
20
19
  end
21
20
 
22
- def verify(algorithm, public_key, signing_input, signature)
23
- translated_algorithm = algorithm.sub('PS', 'sha')
24
- public_key.verify_pss(translated_algorithm, signature, signing_input, salt_length: :auto, mgf1_hash: translated_algorithm)
21
+ def verify(data:, signature:, verification_key:)
22
+ verification_key.verify_pss(digest_algorithm, signature, data, salt_length: :auto, mgf1_hash: digest_algorithm)
25
23
  rescue OpenSSL::PKey::PKeyError
26
24
  raise JWT::VerificationError, 'Signature verification raised'
27
25
  end
26
+
27
+ register_algorithm(new('PS256'))
28
+ register_algorithm(new('PS384'))
29
+ register_algorithm(new('PS512'))
30
+
31
+ private
32
+
33
+ attr_reader :digest_algorithm
28
34
  end
29
35
  end
30
36
  end