From a196b81b8d1c88536aa8cc91e25a649f090cac84 Mon Sep 17 00:00:00 2001 From: shields Date: Fri, 5 Feb 2021 02:58:24 +0900 Subject: [PATCH 01/13] Ignore casing of algorithm. Preserve original casing during encode/decode. --- lib/jwt/decode.rb | 25 +++++++++++++------------ lib/jwt/signature.rb | 4 +++- spec/jwt_spec.rb | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/lib/jwt/decode.rb b/lib/jwt/decode.rb index 9ee144fe..d7380a37 100644 --- a/lib/jwt/decode.rb +++ b/lib/jwt/decode.rb @@ -43,22 +43,23 @@ def verify_signature end def options_includes_algo_in_header? - allowed_algorithms.include? header['alg'] + allowed_algorithms.include? header['alg'].upcase end def allowed_algorithms # Order is very important - first check for string keys, next for symbols - if @options.key?('algorithm') - [@options['algorithm']] - elsif @options.key?(:algorithm) - [@options[:algorithm]] - elsif @options.key?('algorithms') - @options['algorithms'] || [] - elsif @options.key?(:algorithms) - @options[:algorithms] || [] - else - [] - end + algos = if @options.key?('algorithm') + @options['algorithm'] + elsif @options.key?(:algorithm) + @options[:algorithm] + elsif @options.key?('algorithms') + @options['algorithms'] + elsif @options.key?(:algorithms) + @options[:algorithms] + else + [] + end + Array(algos).map(&:upcase) end def find_key(&keyfinder) diff --git a/lib/jwt/signature.rb b/lib/jwt/signature.rb index f4a73282..30a00470 100644 --- a/lib/jwt/signature.rb +++ b/lib/jwt/signature.rb @@ -31,6 +31,7 @@ module Signature ToVerify = Struct.new(:algorithm, :public_key, :signing_input, :signature) def sign(algorithm, msg, key) + algorithm = algorithm.upcase algo = ALGOS.find do |alg| alg.const_get(:SUPPORTED).include? algorithm end @@ -38,7 +39,8 @@ def sign(algorithm, msg, key) end def verify(algorithm, key, signing_input, signature) - return true if algorithm == 'none' + algorithm = algorithm.upcase + return true if algorithm == 'NONE' raise JWT::DecodeError, 'No verification key available' unless key diff --git a/spec/jwt_spec.rb b/spec/jwt_spec.rb index 1ffedc99..53c4edcf 100644 --- a/spec/jwt_spec.rb +++ b/spec/jwt_spec.rb @@ -510,4 +510,26 @@ end.not_to raise_error end end + + context 'algorithm case insensitivity' do + let(:payload) { { 'a' => 1, 'b' => 'b' } } + + it 'ignores algorithm casing during encode/decode' do + enc = JWT.encode(payload, '', 'hs256') + expect(JWT.decode(enc, '')).to eq([payload, { 'alg' => 'hs256'}]) + + enc = JWT.encode(payload, data[:rsa_private], 'ps384') + puts JWT.decode(enc, nil, false, algorithm: 'ps384').inspect + expect(JWT.decode(enc, data[:rsa_public], true, algorithm: 'PS384')).to eq([payload, { 'alg' => 'ps384'}]) + + enc = JWT.encode(payload, data[:rsa_private], 'RS512') + expect(JWT.decode(enc, data[:rsa_public], true, algorithm: 'rs512')).to eq([payload, { 'alg' => 'RS512'}]) + end + + it 'raises error for invalid algorithm' do + expect do + JWT.encode(payload, '', 'xyz') + end.to raise_error(NotImplementedError) + end + end end From 135b002c9ccb2465a551e401278e0f3baee8eaa7 Mon Sep 17 00:00:00 2001 From: shields Date: Fri, 5 Feb 2021 03:04:29 +0900 Subject: [PATCH 02/13] Fix indentation as per auto-code review --- lib/jwt/decode.rb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/jwt/decode.rb b/lib/jwt/decode.rb index d7380a37..b6f40da5 100644 --- a/lib/jwt/decode.rb +++ b/lib/jwt/decode.rb @@ -49,16 +49,16 @@ def options_includes_algo_in_header? def allowed_algorithms # Order is very important - first check for string keys, next for symbols algos = if @options.key?('algorithm') - @options['algorithm'] - elsif @options.key?(:algorithm) - @options[:algorithm] - elsif @options.key?('algorithms') - @options['algorithms'] - elsif @options.key?(:algorithms) - @options[:algorithms] - else - [] - end + @options['algorithm'] + elsif @options.key?(:algorithm) + @options[:algorithm] + elsif @options.key?('algorithms') + @options['algorithms'] + elsif @options.key?(:algorithms) + @options[:algorithms] + else + [] + end Array(algos).map(&:upcase) end From 99bb1b9c1df42036e25f63797089811fd2c49c57 Mon Sep 17 00:00:00 2001 From: shields Date: Fri, 5 Feb 2021 18:47:38 +0900 Subject: [PATCH 03/13] Case insensitivity v2: coerce algo to correct casing --- lib/jwt/algos.rb | 32 ++++++++++++++++++++++++++++++++ lib/jwt/algos/eddsa.rb | 2 +- lib/jwt/algos/unsupported.rb | 2 +- lib/jwt/encode.rb | 3 ++- lib/jwt/signature.rb | 31 ++++++------------------------- spec/jwt_spec.rb | 11 +++++------ 6 files changed, 47 insertions(+), 34 deletions(-) create mode 100644 lib/jwt/algos.rb diff --git a/lib/jwt/algos.rb b/lib/jwt/algos.rb new file mode 100644 index 00000000..0654bfd6 --- /dev/null +++ b/lib/jwt/algos.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'jwt/algos/hmac' +require 'jwt/algos/eddsa' +require 'jwt/algos/ecdsa' +require 'jwt/algos/rsa' +require 'jwt/algos/ps' +require 'jwt/algos/unsupported' + +# JWT::Signature module +module JWT + # Signature logic for JWT + module Algos + extend self + ALGOS = [ + Algos::Hmac, + Algos::Ecdsa, + Algos::Rsa, + Algos::Eddsa, + Algos::Ps, + Algos::Unsupported + ].freeze + + def find(algorithm) + ALGOS.each do |alg| + code = alg.const_get(:SUPPORTED).find {|a| a.upcase == algorithm.upcase } + return [alg, code] if code + end + nil + end + end +end diff --git a/lib/jwt/algos/eddsa.rb b/lib/jwt/algos/eddsa.rb index aec8b757..1bd3d1e5 100644 --- a/lib/jwt/algos/eddsa.rb +++ b/lib/jwt/algos/eddsa.rb @@ -3,7 +3,7 @@ module Algos module Eddsa module_function - SUPPORTED = %w[ED25519].freeze + SUPPORTED = %w[Ed25519].freeze def sign(to_sign) algorithm, msg, key = to_sign.values diff --git a/lib/jwt/algos/unsupported.rb b/lib/jwt/algos/unsupported.rb index 99ddcb71..2f02e79a 100644 --- a/lib/jwt/algos/unsupported.rb +++ b/lib/jwt/algos/unsupported.rb @@ -3,7 +3,7 @@ module Algos module Unsupported module_function - SUPPORTED = Object.new.tap { |object| object.define_singleton_method(:include?) { |*| true } } + SUPPORTED = Object.new.tap { |object| object.define_singleton_method(:find) { |*| true } } def verify(*) raise JWT::VerificationError, 'Algorithm not supported' end diff --git a/lib/jwt/encode.rb b/lib/jwt/encode.rb index 35ddba79..3e127d67 100644 --- a/lib/jwt/encode.rb +++ b/lib/jwt/encode.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require_relative './algos' require_relative './claims_validator' # JWT::Encode module @@ -12,7 +13,7 @@ class Encode def initialize(options) @payload = options[:payload] @key = options[:key] - @algorithm = options[:algorithm] + _, @algorithm = Algos.find(options[:algorithm]) @headers = options[:headers].each_with_object({}) { |(key, value), headers| headers[key.to_s] = value } end diff --git a/lib/jwt/signature.rb b/lib/jwt/signature.rb index 30a00470..43061bb0 100644 --- a/lib/jwt/signature.rb +++ b/lib/jwt/signature.rb @@ -2,12 +2,7 @@ require 'jwt/security_utils' require 'openssl' -require 'jwt/algos/hmac' -require 'jwt/algos/eddsa' -require 'jwt/algos/ecdsa' -require 'jwt/algos/rsa' -require 'jwt/algos/ps' -require 'jwt/algos/unsupported' +require 'jwt/algos' begin require 'rbnacl' rescue LoadError @@ -19,35 +14,21 @@ module JWT # Signature logic for JWT module Signature extend self - ALGOS = [ - Algos::Hmac, - Algos::Ecdsa, - Algos::Rsa, - Algos::Eddsa, - Algos::Ps, - Algos::Unsupported - ].freeze ToSign = Struct.new(:algorithm, :msg, :key) ToVerify = Struct.new(:algorithm, :public_key, :signing_input, :signature) def sign(algorithm, msg, key) - algorithm = algorithm.upcase - algo = ALGOS.find do |alg| - alg.const_get(:SUPPORTED).include? algorithm - end - algo.sign ToSign.new(algorithm, msg, key) + algo, code = Algos.find(algorithm) + algo.sign ToSign.new(code, msg, key) end def verify(algorithm, key, signing_input, signature) - algorithm = algorithm.upcase - return true if algorithm == 'NONE' + return true if algorithm.upcase == 'NONE' raise JWT::DecodeError, 'No verification key available' unless key - algo = ALGOS.find do |alg| - alg.const_get(:SUPPORTED).include? algorithm - end - verified = algo.verify(ToVerify.new(algorithm, key, signing_input, signature)) + algo, code = Algos.find(algorithm) + verified = algo.verify(ToVerify.new(code, key, signing_input, signature)) raise(JWT::VerificationError, 'Signature verification raised') unless verified rescue OpenSSL::PKey::PKeyError raise JWT::VerificationError, 'Signature verification raised' diff --git a/spec/jwt_spec.rb b/spec/jwt_spec.rb index 53c4edcf..33f8f96d 100644 --- a/spec/jwt_spec.rb +++ b/spec/jwt_spec.rb @@ -37,8 +37,8 @@ if defined?(RbNaCl) data.merge!( - 'ED25519_private' => RbNaCl::Signatures::Ed25519::SigningKey.new('abcdefghijklmnopqrstuvwxyzABCDEF'), - 'ED25519_public' => RbNaCl::Signatures::Ed25519::SigningKey.new('abcdefghijklmnopqrstuvwxyzABCDEF').verify_key, + 'Ed25519_private' => RbNaCl::Signatures::Ed25519::SigningKey.new('abcdefghijklmnopqrstuvwxyzABCDEF'), + 'Ed25519_public' => RbNaCl::Signatures::Ed25519::SigningKey.new('abcdefghijklmnopqrstuvwxyzABCDEF').verify_key, ) end data @@ -190,7 +190,7 @@ end if defined?(RbNaCl) - %w[ED25519].each do |alg| + %w[Ed25519].each do |alg| context "alg: #{alg}" do before(:each) do data[alg] = JWT.encode payload, data["#{alg}_private"], alg @@ -516,11 +516,10 @@ it 'ignores algorithm casing during encode/decode' do enc = JWT.encode(payload, '', 'hs256') - expect(JWT.decode(enc, '')).to eq([payload, { 'alg' => 'hs256'}]) + expect(JWT.decode(enc, '')).to eq([payload, { 'alg' => 'HS256'}]) enc = JWT.encode(payload, data[:rsa_private], 'ps384') - puts JWT.decode(enc, nil, false, algorithm: 'ps384').inspect - expect(JWT.decode(enc, data[:rsa_public], true, algorithm: 'PS384')).to eq([payload, { 'alg' => 'ps384'}]) + expect(JWT.decode(enc, data[:rsa_public], true, algorithm: 'PS384')).to eq([payload, { 'alg' => 'PS384'}]) enc = JWT.encode(payload, data[:rsa_private], 'RS512') expect(JWT.decode(enc, data[:rsa_public], true, algorithm: 'rs512')).to eq([payload, { 'alg' => 'RS512'}]) From 58f39a77d3a627aabb7066613d4ef76592af003a Mon Sep 17 00:00:00 2001 From: shields Date: Sat, 6 Feb 2021 17:50:28 +0900 Subject: [PATCH 04/13] Fixes to case insensitivity --- lib/jwt/algos.rb | 20 ++++++++++++++++---- lib/jwt/algos/none.rb | 14 ++++++++++++++ lib/jwt/algos/unsupported.rb | 2 +- lib/jwt/decode.rb | 4 ++-- lib/jwt/signature.rb | 2 +- 5 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 lib/jwt/algos/none.rb diff --git a/lib/jwt/algos.rb b/lib/jwt/algos.rb index 0654bfd6..a0945305 100644 --- a/lib/jwt/algos.rb +++ b/lib/jwt/algos.rb @@ -5,6 +5,7 @@ require 'jwt/algos/ecdsa' require 'jwt/algos/rsa' require 'jwt/algos/ps' +require 'jwt/algos/none' require 'jwt/algos/unsupported' # JWT::Signature module @@ -18,15 +19,26 @@ module Algos Algos::Rsa, Algos::Eddsa, Algos::Ps, + Algos::None, Algos::Unsupported ].freeze def find(algorithm) - ALGOS.each do |alg| - code = alg.const_get(:SUPPORTED).find {|a| a.upcase == algorithm.upcase } - return [alg, code] if code + indexed[algorithm && algorithm.downcase] + end + + private + + def indexed + @indexed ||= begin + algos = ALGOS.dup + fallback = [algos.pop, nil] + algos.each_with_object(Hash.new(fallback)) do |alg, hash| + alg.const_get(:SUPPORTED).each do |code| + hash[code.downcase] = [alg, code] + end + end end - nil end end end diff --git a/lib/jwt/algos/none.rb b/lib/jwt/algos/none.rb new file mode 100644 index 00000000..70277844 --- /dev/null +++ b/lib/jwt/algos/none.rb @@ -0,0 +1,14 @@ +module JWT + module Algos + module None + module_function + + SUPPORTED = ['none'] + def verify(*) + end + + def sign(*) + end + end + end +end diff --git a/lib/jwt/algos/unsupported.rb b/lib/jwt/algos/unsupported.rb index 2f02e79a..55674658 100644 --- a/lib/jwt/algos/unsupported.rb +++ b/lib/jwt/algos/unsupported.rb @@ -3,7 +3,7 @@ module Algos module Unsupported module_function - SUPPORTED = Object.new.tap { |object| object.define_singleton_method(:find) { |*| true } } + SUPPORTED = [] def verify(*) raise JWT::VerificationError, 'Algorithm not supported' end diff --git a/lib/jwt/decode.rb b/lib/jwt/decode.rb index b6f40da5..dd017668 100644 --- a/lib/jwt/decode.rb +++ b/lib/jwt/decode.rb @@ -43,7 +43,7 @@ def verify_signature end def options_includes_algo_in_header? - allowed_algorithms.include? header['alg'].upcase + allowed_algorithms.any? { |alg| alg.casecmp?(header['alg']) } end def allowed_algorithms @@ -59,7 +59,7 @@ def allowed_algorithms else [] end - Array(algos).map(&:upcase) + Array(algos) end def find_key(&keyfinder) diff --git a/lib/jwt/signature.rb b/lib/jwt/signature.rb index 43061bb0..cd7aba81 100644 --- a/lib/jwt/signature.rb +++ b/lib/jwt/signature.rb @@ -23,7 +23,7 @@ def sign(algorithm, msg, key) end def verify(algorithm, key, signing_input, signature) - return true if algorithm.upcase == 'NONE' + return true if algorithm.casecmp?('none') raise JWT::DecodeError, 'No verification key available' unless key From 0d2199c0c8b62d067fd6bd5d19b20a79056a2960 Mon Sep 17 00:00:00 2001 From: shields Date: Sat, 6 Feb 2021 17:55:10 +0900 Subject: [PATCH 05/13] Freeze constants --- lib/jwt/algos/none.rb | 2 +- lib/jwt/algos/unsupported.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/jwt/algos/none.rb b/lib/jwt/algos/none.rb index 70277844..168bc1cc 100644 --- a/lib/jwt/algos/none.rb +++ b/lib/jwt/algos/none.rb @@ -3,7 +3,7 @@ module Algos module None module_function - SUPPORTED = ['none'] + SUPPORTED = %w[none].freeze def verify(*) end diff --git a/lib/jwt/algos/unsupported.rb b/lib/jwt/algos/unsupported.rb index 55674658..ab995b7a 100644 --- a/lib/jwt/algos/unsupported.rb +++ b/lib/jwt/algos/unsupported.rb @@ -3,7 +3,7 @@ module Algos module Unsupported module_function - SUPPORTED = [] + SUPPORTED = [].freeze def verify(*) raise JWT::VerificationError, 'Algorithm not supported' end From 49083793ded582fcff59794b6010b7a4e7f8654c Mon Sep 17 00:00:00 2001 From: shields Date: Sat, 6 Feb 2021 17:57:40 +0900 Subject: [PATCH 06/13] Fix auto-code review --- lib/jwt/algos.rb | 1 + lib/jwt/algos/none.rb | 7 +++---- lib/jwt/algos/unsupported.rb | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/jwt/algos.rb b/lib/jwt/algos.rb index a0945305..15897c3e 100644 --- a/lib/jwt/algos.rb +++ b/lib/jwt/algos.rb @@ -13,6 +13,7 @@ module JWT # Signature logic for JWT module Algos extend self + ALGOS = [ Algos::Hmac, Algos::Ecdsa, diff --git a/lib/jwt/algos/none.rb b/lib/jwt/algos/none.rb index 168bc1cc..df0565c7 100644 --- a/lib/jwt/algos/none.rb +++ b/lib/jwt/algos/none.rb @@ -4,11 +4,10 @@ module None module_function SUPPORTED = %w[none].freeze - def verify(*) - end - def sign(*) - end + def verify(*); end + + def sign(*); end end end end diff --git a/lib/jwt/algos/unsupported.rb b/lib/jwt/algos/unsupported.rb index ab995b7a..3c2bb825 100644 --- a/lib/jwt/algos/unsupported.rb +++ b/lib/jwt/algos/unsupported.rb @@ -4,6 +4,7 @@ module Unsupported module_function SUPPORTED = [].freeze + def verify(*) raise JWT::VerificationError, 'Algorithm not supported' end From a332b5ed160136ff62ffb18682635aab6e9d622e Mon Sep 17 00:00:00 2001 From: shields Date: Sat, 6 Feb 2021 18:07:23 +0900 Subject: [PATCH 07/13] Minor cleanup --- lib/jwt/algos/none.rb | 6 ++++-- lib/jwt/algos/unsupported.rb | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/jwt/algos/none.rb b/lib/jwt/algos/none.rb index df0565c7..17d15f14 100644 --- a/lib/jwt/algos/none.rb +++ b/lib/jwt/algos/none.rb @@ -5,9 +5,11 @@ module None SUPPORTED = %w[none].freeze - def verify(*); end - def sign(*); end + + def verify(*) + true + end end end end diff --git a/lib/jwt/algos/unsupported.rb b/lib/jwt/algos/unsupported.rb index 3c2bb825..179a262e 100644 --- a/lib/jwt/algos/unsupported.rb +++ b/lib/jwt/algos/unsupported.rb @@ -5,13 +5,13 @@ module Unsupported SUPPORTED = [].freeze - def verify(*) - raise JWT::VerificationError, 'Algorithm not supported' - end - def sign(*) raise NotImplementedError, 'Unsupported signing method' end + + def verify(*) + raise JWT::VerificationError, 'Algorithm not supported' + end end end end From ec597335ea1de038f14e37e53e4089abe7f2c551 Mon Sep 17 00:00:00 2001 From: shields Date: Sat, 6 Feb 2021 18:11:50 +0900 Subject: [PATCH 08/13] Fix code climate review --- lib/jwt/encode.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/jwt/encode.rb b/lib/jwt/encode.rb index 3e127d67..bdeeab2f 100644 --- a/lib/jwt/encode.rb +++ b/lib/jwt/encode.rb @@ -11,10 +11,10 @@ class Encode ALG_KEY = 'alg'.freeze def initialize(options) - @payload = options[:payload] - @key = options[:key] + @payload = options[:payload] + @key = options[:key] _, @algorithm = Algos.find(options[:algorithm]) - @headers = options[:headers].each_with_object({}) { |(key, value), headers| headers[key.to_s] = value } + @headers = options[:headers].each_with_object({}) { |(key, value), headers| headers[key.to_s] = value } end def segments From 6387bc104a8dc58f8b592f6f64298df94cdf9398 Mon Sep 17 00:00:00 2001 From: shields Date: Sat, 6 Feb 2021 18:14:07 +0900 Subject: [PATCH 09/13] Whitelist extend self for algos.rb --- .rubocop_todo.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 5d7a97d6..b053b403 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -126,11 +126,12 @@ Style/MethodCallWithoutArgsParentheses: Exclude: - 'spec/jwt_spec.rb' -# Offense count: 1 +# Offense count: 2 # Configuration parameters: EnforcedStyle. # SupportedStyles: module_function, extend_self Style/ModuleFunction: Exclude: + - 'lib/jwt/algos.rb' - 'lib/jwt/signature.rb' # Offense count: 1 From 4b2ccd803c204b8414369dbeb80e7cb07579b843 Mon Sep 17 00:00:00 2001 From: shields Date: Sun, 7 Feb 2021 01:37:38 +0900 Subject: [PATCH 10/13] casecmp? is only in Ruby 2.5 and greater --- lib/jwt/decode.rb | 2 +- lib/jwt/signature.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/jwt/decode.rb b/lib/jwt/decode.rb index dd017668..619e354e 100644 --- a/lib/jwt/decode.rb +++ b/lib/jwt/decode.rb @@ -43,7 +43,7 @@ def verify_signature end def options_includes_algo_in_header? - allowed_algorithms.any? { |alg| alg.casecmp?(header['alg']) } + allowed_algorithms.any? { |alg| alg.casecmp(header['alg']) == 0 } end def allowed_algorithms diff --git a/lib/jwt/signature.rb b/lib/jwt/signature.rb index cd7aba81..91253fca 100644 --- a/lib/jwt/signature.rb +++ b/lib/jwt/signature.rb @@ -23,7 +23,7 @@ def sign(algorithm, msg, key) end def verify(algorithm, key, signing_input, signature) - return true if algorithm.casecmp?('none') + return true if algorithm.casecmp('none') == 0 raise JWT::DecodeError, 'No verification key available' unless key From 0647ffdb24f0801c2615f85444fbbecd234d9122 Mon Sep 17 00:00:00 2001 From: shields Date: Mon, 8 Feb 2021 06:08:31 +0900 Subject: [PATCH 11/13] Fix rubocop --- lib/jwt/decode.rb | 2 +- lib/jwt/signature.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/jwt/decode.rb b/lib/jwt/decode.rb index 619e354e..29ff181e 100644 --- a/lib/jwt/decode.rb +++ b/lib/jwt/decode.rb @@ -43,7 +43,7 @@ def verify_signature end def options_includes_algo_in_header? - allowed_algorithms.any? { |alg| alg.casecmp(header['alg']) == 0 } + allowed_algorithms.any? { |alg| alg.casecmp(header['alg']).zero? } end def allowed_algorithms diff --git a/lib/jwt/signature.rb b/lib/jwt/signature.rb index 91253fca..e490d9eb 100644 --- a/lib/jwt/signature.rb +++ b/lib/jwt/signature.rb @@ -23,7 +23,7 @@ def sign(algorithm, msg, key) end def verify(algorithm, key, signing_input, signature) - return true if algorithm.casecmp('none') == 0 + return true if algorithm.casecmp('none').zero? raise JWT::DecodeError, 'No verification key available' unless key From 6300a32a5864f183c2bab401fedc2ce87b900413 Mon Sep 17 00:00:00 2001 From: shields Date: Mon, 8 Feb 2021 21:43:20 +0900 Subject: [PATCH 12/13] Respond to comments --- lib/jwt/algos.rb | 5 ++--- spec/jwt_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/jwt/algos.rb b/lib/jwt/algos.rb index 15897c3e..aa46a60f 100644 --- a/lib/jwt/algos.rb +++ b/lib/jwt/algos.rb @@ -32,9 +32,8 @@ def find(algorithm) def indexed @indexed ||= begin - algos = ALGOS.dup - fallback = [algos.pop, nil] - algos.each_with_object(Hash.new(fallback)) do |alg, hash| + fallback = [Algos::Unsupported, nil] + ALGOS.each_with_object(Hash.new(fallback)) do |alg, hash| alg.const_get(:SUPPORTED).each do |code| hash[code.downcase] = [alg, code] end diff --git a/spec/jwt_spec.rb b/spec/jwt_spec.rb index 33f8f96d..fbec8e90 100644 --- a/spec/jwt_spec.rb +++ b/spec/jwt_spec.rb @@ -518,8 +518,8 @@ enc = JWT.encode(payload, '', 'hs256') expect(JWT.decode(enc, '')).to eq([payload, { 'alg' => 'HS256'}]) - enc = JWT.encode(payload, data[:rsa_private], 'ps384') - expect(JWT.decode(enc, data[:rsa_public], true, algorithm: 'PS384')).to eq([payload, { 'alg' => 'PS384'}]) + enc = JWT.encode(payload, data[:rsa_private], 'rs512') + expect(JWT.decode(enc, data[:rsa_public], true, algorithm: 'RS512')).to eq([payload, { 'alg' => 'RS512'}]) enc = JWT.encode(payload, data[:rsa_private], 'RS512') expect(JWT.decode(enc, data[:rsa_public], true, algorithm: 'rs512')).to eq([payload, { 'alg' => 'RS512'}]) From 53101a8da17b4b939a31ec3326a03c26ab369365 Mon Sep 17 00:00:00 2001 From: shields Date: Tue, 9 Feb 2021 05:55:19 +0900 Subject: [PATCH 13/13] Revert casing of ED25519 --- lib/jwt/algos/eddsa.rb | 2 +- spec/jwt_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/jwt/algos/eddsa.rb b/lib/jwt/algos/eddsa.rb index 1bd3d1e5..aec8b757 100644 --- a/lib/jwt/algos/eddsa.rb +++ b/lib/jwt/algos/eddsa.rb @@ -3,7 +3,7 @@ module Algos module Eddsa module_function - SUPPORTED = %w[Ed25519].freeze + SUPPORTED = %w[ED25519].freeze def sign(to_sign) algorithm, msg, key = to_sign.values diff --git a/spec/jwt_spec.rb b/spec/jwt_spec.rb index fbec8e90..a5e5f3d6 100644 --- a/spec/jwt_spec.rb +++ b/spec/jwt_spec.rb @@ -37,8 +37,8 @@ if defined?(RbNaCl) data.merge!( - 'Ed25519_private' => RbNaCl::Signatures::Ed25519::SigningKey.new('abcdefghijklmnopqrstuvwxyzABCDEF'), - 'Ed25519_public' => RbNaCl::Signatures::Ed25519::SigningKey.new('abcdefghijklmnopqrstuvwxyzABCDEF').verify_key, + 'ED25519_private' => RbNaCl::Signatures::Ed25519::SigningKey.new('abcdefghijklmnopqrstuvwxyzABCDEF'), + 'ED25519_public' => RbNaCl::Signatures::Ed25519::SigningKey.new('abcdefghijklmnopqrstuvwxyzABCDEF').verify_key, ) end data @@ -190,7 +190,7 @@ end if defined?(RbNaCl) - %w[Ed25519].each do |alg| + %w[ED25519].each do |alg| context "alg: #{alg}" do before(:each) do data[alg] = JWT.encode payload, data["#{alg}_private"], alg