lib/jwt.rb in jwt-1.5.4 vs lib/jwt.rb in jwt-1.5.5

- old
+ new

@@ -13,11 +13,11 @@ NAMED_CURVES = { 'prime256v1' => 'ES256', 'secp384r1' => 'ES384', 'secp521r1' => 'ES512' - } + }.freeze module_function def sign(algorithm, msg, key) if %w(HS256 HS384 HS512).include?(algorithm) @@ -25,22 +25,22 @@ elsif %w(RS256 RS384 RS512).include?(algorithm) sign_rsa(algorithm, msg, key) elsif %w(ES256 ES384 ES512).include?(algorithm) sign_ecdsa(algorithm, msg, key) else - fail NotImplementedError, 'Unsupported signing method' + raise NotImplementedError, 'Unsupported signing method' end end def sign_rsa(algorithm, msg, private_key) private_key.sign(OpenSSL::Digest.new(algorithm.sub('RS', 'sha')), msg) end def sign_ecdsa(algorithm, msg, private_key) key_algorithm = NAMED_CURVES[private_key.group.curve_name] if algorithm != key_algorithm - fail IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key_algorithm} signing key was provided" + raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key_algorithm} signing key was provided" end digest = OpenSSL::Digest.new(algorithm.sub('ES', 'sha')) asn1_to_raw(private_key.dsa_sign_asn1(digest.digest(msg)), private_key) end @@ -50,11 +50,11 @@ end def verify_ecdsa(algorithm, public_key, signing_input, signature) key_algorithm = NAMED_CURVES[public_key.group.curve_name] if algorithm != key_algorithm - fail IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key_algorithm} verification key was provided" + raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key_algorithm} verification key was provided" end digest = OpenSSL::Digest.new(algorithm.sub('ES', 'sha')) public_key.dsa_verify_asn1(digest.digest(signing_input), raw_to_asn1(signature, public_key)) end @@ -71,10 +71,11 @@ header = { 'typ' => 'JWT', 'alg' => algorithm }.merge(header_fields) base64url_encode(encode_json(header)) end def encoded_payload(payload) + raise InvalidPayload, "exp claim must be an integer" if payload['exp'] && payload['exp'].is_a?(Time) base64url_encode(encode_json(payload)) end def encoded_signature(signing_input, key, algorithm) if algorithm == 'none' @@ -92,12 +93,33 @@ segments << encoded_payload(payload) segments << encoded_signature(segments.join('.'), key, algorithm) segments.join('.') end + def decoded_segments(jwt, key = nil, verify = true, custom_options = {}, &keyfinder) + raise(JWT::DecodeError, 'Nil JSON web token') unless jwt + + options = { + verify_expiration: true, + verify_not_before: true, + verify_iss: false, + verify_iat: false, + verify_jti: false, + verify_aud: false, + verify_sub: false, + leeway: 0 + } + + merged_options = options.merge(custom_options) + + decoder = Decode.new jwt, key, verify, merged_options, &keyfinder + decoder.decode_segments + end + + def decode(jwt, key = nil, verify = true, custom_options = {}, &keyfinder) - fail(JWT::DecodeError, 'Nil JSON web token') unless jwt + raise(JWT::DecodeError, 'Nil JSON web token') unless jwt options = { verify_expiration: true, verify_not_before: true, verify_iss: false, @@ -110,38 +132,39 @@ merged_options = options.merge(custom_options) decoder = Decode.new jwt, key, verify, merged_options, &keyfinder header, payload, signature, signing_input = decoder.decode_segments - decoder.verify - fail(JWT::DecodeError, 'Not enough or too many segments') unless header && payload - if verify algo, key = signature_algorithm_and_key(header, key, &keyfinder) if merged_options[:algorithm] && algo != merged_options[:algorithm] - fail JWT::IncorrectAlgorithm, 'Expected a different algorithm' + raise JWT::IncorrectAlgorithm, 'Expected a different algorithm' end verify_signature(algo, key, signing_input, signature) end + decoder.verify + + raise(JWT::DecodeError, 'Not enough or too many segments') unless header && payload + [payload, header] end def signature_algorithm_and_key(header, key, &keyfinder) - key = keyfinder.call(header) if keyfinder + key = yield(header) if keyfinder [header['alg'], key] end def verify_signature(algo, key, signing_input, signature) if %w(HS256 HS384 HS512).include?(algo) - fail(JWT::VerificationError, 'Signature verification raised') unless secure_compare(signature, sign_hmac(algo, signing_input, key)) + raise(JWT::VerificationError, 'Signature verification raised') unless secure_compare(signature, sign_hmac(algo, signing_input, key)) elsif %w(RS256 RS384 RS512).include?(algo) - fail(JWT::VerificationError, 'Signature verification raised') unless verify_rsa(algo, key, signing_input, signature) + raise(JWT::VerificationError, 'Signature verification raised') unless verify_rsa(algo, key, signing_input, signature) elsif %w(ES256 ES384 ES512).include?(algo) - fail(JWT::VerificationError, 'Signature verification raised') unless verify_ecdsa(algo, key, signing_input, signature) + raise(JWT::VerificationError, 'Signature verification raised') unless verify_ecdsa(algo, key, signing_input, signature) else - fail JWT::VerificationError, 'Algorithm not supported' + raise JWT::VerificationError, 'Algorithm not supported' end rescue OpenSSL::PKey::PKeyError raise JWT::VerificationError, 'Signature verification raised' ensure OpenSSL.errors.clear