diff --git a/include/jwt/error_codes.hpp b/include/jwt/error_codes.hpp index 742eeff..063a97a 100644 --- a/include/jwt/error_codes.hpp +++ b/include/jwt/error_codes.hpp @@ -34,6 +34,8 @@ enum class DecodeErrc TypHeaderMiss, TypMismatch, DuplClaims, + KeyNotPresent, + KeyNotRequiredForNoneAlg, }; /** diff --git a/include/jwt/impl/error_codes.ipp b/include/jwt/impl/error_codes.ipp index 2862917..40b1e58 100644 --- a/include/jwt/impl/error_codes.ipp +++ b/include/jwt/impl/error_codes.ipp @@ -59,6 +59,10 @@ struct DecodeErrorCategory: std::error_category return "json parse failed"; case DecodeErrc::DuplClaims: return "duplicate claims"; + case DecodeErrc::KeyNotPresent: + return "key not present"; + case DecodeErrc::KeyNotRequiredForNoneAlg: + return "key not required for NONE algorithm"; }; assert (0 && "Code not reached"); diff --git a/include/jwt/impl/jwt.ipp b/include/jwt/impl/jwt.ipp index 37d4218..a9289aa 100644 --- a/include/jwt/impl/jwt.ipp +++ b/include/jwt/impl/jwt.ipp @@ -464,13 +464,19 @@ jwt_object::three_parts(const string_view enc_str) return result; } +template +void jwt_object::set_decode_params(DecodeParams& dparams, params::detail::secret_param s, Rest&&... args) +{ + dparams.secret.assign(s.get().data(), s.get().length()); + dparams.has_secret = true; + jwt_object::set_decode_params(dparams, std::forward(args)...); +} template void jwt_object::set_decode_params(DecodeParams& dparams, params::detail::leeway_param l, Rest&&... args) { dparams.leeway = l.get(); jwt_object::set_decode_params(dparams, std::forward(args)...); - return; } template @@ -478,7 +484,6 @@ void jwt_object::set_decode_params(DecodeParams& dparams, params::detail::verify { dparams.verify = v.get(); jwt_object::set_decode_params(dparams, std::forward(args)...); - return; } template @@ -487,7 +492,6 @@ void jwt_object::set_decode_params(DecodeParams& dparams, params::detail::issuer dparams.issuer = std::move(i).get(); dparams.has_issuer = true; jwt_object::set_decode_params(dparams, std::forward(args)...); - return; } template @@ -508,7 +512,6 @@ void jwt_object::set_decode_params(DecodeParams& dparams) template jwt_object decode(const string_view enc_str, - const string_view key, const params::detail::algorithms_param& algos, std::error_code& ec, Args&&... args) @@ -523,14 +526,21 @@ jwt_object decode(const string_view enc_str, struct decode_params { + /// key to decode the JWS + bool has_secret = false; + std::string secret; + /// Verify parameter. Defaulted to true. bool verify = true; + /// Leeway parameter. Defaulted to zero seconds. uint32_t leeway = 0; + ///The issuer //TODO: optional type bool has_issuer = false; std::string issuer; + ///The audience //TODO: optional type bool has_aud = false; @@ -571,6 +581,15 @@ jwt_object decode(const string_view enc_str, ec = DecodeErrc::SignatureFormatError; return obj; } + + if (!dparams.has_secret) { + ec = DecodeErrc::KeyNotPresent; + return obj; + } + } else { + if (dparams.has_secret) { + ec = DecodeErrc::KeyNotRequiredForNoneAlg; + } } //throws decode error @@ -589,7 +608,7 @@ jwt_object decode(const string_view enc_str, //Verify the signature only if some algorithm was used if (obj.header().algo() != algorithm::NONE) { - jwt_signature jsign{key}; + jwt_signature jsign{dparams.secret}; // Length of the encoded header and payload only. // Addition of '1' to account for the '.' character. @@ -617,13 +636,11 @@ jwt_object decode(const string_view enc_str, template jwt_object decode(const string_view enc_str, - const string_view key, const params::detail::algorithms_param& algos, Args&&... args) { std::error_code ec{}; auto jwt_obj = decode(enc_str, - key, algos, ec, std::forward(args)...); @@ -681,6 +698,11 @@ void jwt_throw_exception(const std::error_code& ec) { throw SignatureFormatError(ec.message()); } + case DecodeErrc::KeyNotRequiredForNoneAlg: + { + // Not an error. Just to be ignored. + break; + } default: { throw DecodeError(ec.message()); diff --git a/include/jwt/jwt.hpp b/include/jwt/jwt.hpp index b122458..56cee40 100644 --- a/include/jwt/jwt.hpp +++ b/include/jwt/jwt.hpp @@ -730,6 +730,9 @@ private: // private APIs public: //TODO: Not good /// Decode parameters + template + static void set_decode_params(DecodeParams& dparams, params::detail::secret_param s, Rest&&... args); + template static void set_decode_params(DecodeParams& dparams, params::detail::leeway_param l, Rest&&... args); @@ -766,7 +769,6 @@ jwt_object jwt_decode(const string_view encoded_str, const string_view key, bool */ template jwt_object decode(const string_view enc_str, - const string_view key, const params::detail::algorithms_param& algos, std::error_code& ec, Args&&... args); @@ -775,7 +777,6 @@ jwt_object decode(const string_view enc_str, */ template jwt_object decode(const string_view enc_str, - const string_view key, const params::detail::algorithms_param& algos, Args&&... args); diff --git a/tests/test_jwt_decode b/tests/test_jwt_decode index 515770a..67917eb 100755 Binary files a/tests/test_jwt_decode and b/tests/test_jwt_decode differ diff --git a/tests/test_jwt_decode.cc b/tests/test_jwt_decode.cc index 05c8065..b6d1be7 100644 --- a/tests/test_jwt_decode.cc +++ b/tests/test_jwt_decode.cc @@ -9,7 +9,7 @@ TEST (DecodeTest, InvalidFinalDotForNoneAlg) "eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ"; std::error_code ec; - auto obj = jwt::decode(inv_enc_str, "", algorithms({"none", "hs256"}), ec); + auto obj = jwt::decode(inv_enc_str, algorithms({"none", "hs256"}), ec); ASSERT_TRUE (ec); EXPECT_EQ (ec.value(), static_cast(jwt::DecodeErrc::SignatureFormatError)); @@ -22,7 +22,7 @@ TEST (DecodeTest, DecodeNoneAlgSign) "eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ."; std::error_code ec; - auto obj = jwt::decode(enc_str, "", algorithms({"none"}), ec, verify(false)); + auto obj = jwt::decode(enc_str, algorithms({"none"}), ec, verify(false)); EXPECT_TRUE (ec); EXPECT_EQ (ec.value(), static_cast(jwt::AlgorithmErrc::NoneAlgorithmUsed)); @@ -45,7 +45,7 @@ TEST (DecodeTest, DecodeWrongAlgo) "eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ."; std::error_code ec; - auto obj = jwt::decode(enc_str, "", algorithms({"hs256"}), ec, verify(true)); + auto obj = jwt::decode(enc_str, algorithms({"hs256"}), ec, secret(""), verify(true)); EXPECT_TRUE (ec); EXPECT_EQ (ec.value(), static_cast(jwt::VerificationErrc::InvalidAlgorithm)); } @@ -58,7 +58,7 @@ TEST (DecodeTest, DecodeInvalidHeader) "ehbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ."; std::error_code ec; - auto obj = jwt::decode(enc_str, "", algorithms({"hs256"}), ec, verify(true)); + auto obj = jwt::decode(enc_str, algorithms({"hs256"}), ec, secret(""), verify(true)); ASSERT_TRUE (ec); EXPECT_EQ (ec.value(), static_cast(jwt::DecodeErrc::JsonParseError)); @@ -72,7 +72,7 @@ TEST (DecodeTest, DecodeInvalidPayload) "eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyfhuWcikiJyaWZ0LmlvIiwiZXhwIsexNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ."; std::error_code ec; - auto obj = jwt::decode(enc_str, "", algorithms({"none"}), ec, verify(true)); + auto obj = jwt::decode(enc_str, algorithms({"none"}), ec, verify(true)); ASSERT_TRUE (ec); EXPECT_EQ (ec.value(), static_cast(jwt::DecodeErrc::JsonParseError)); @@ -88,7 +88,7 @@ TEST (DecodeTest, DecodeHS256) "jk7bRQKTLvs1RcuvMc2B_rt6WBYPoVPirYi_QRBPiuk"; std::error_code ec; - auto obj = jwt::decode(enc_str, "secret", algorithms({"none", "hs256"}), ec, verify(false)); + auto obj = jwt::decode(enc_str, algorithms({"none", "hs256"}), ec, verify(false), secret("secret")); ASSERT_FALSE (ec); EXPECT_TRUE (obj.has_claim("iss")); @@ -108,10 +108,10 @@ TEST (DecodeTest, DecodeHS384) "eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ." "cGN4FZCe9Y2c1dA-jP71IXGnYbJRc4OaUTa5m7N7ybF5h6wBwxWQ-pdcxYchjDBL"; - const jwt::string_view secret = "0123456789abcdefghijklmnopqrstuvwxyz"; + const jwt::string_view key = "0123456789abcdefghijklmnopqrstuvwxyz"; std::error_code ec; - auto obj = jwt::decode(enc_str, secret, algorithms({"none", "hs384"}), ec, verify(false)); + auto obj = jwt::decode(enc_str, algorithms({"none", "hs384"}), ec, verify(false), secret(key)); ASSERT_FALSE (ec); EXPECT_TRUE (obj.has_claim("sub")); @@ -127,10 +127,10 @@ TEST (DecodeTest, DecodeHS512) "eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ." "vQ-1JSFN1kPjUI3URP6AFK5z8V7xLhyhw-76QWhQg9Xcy-IgrJ-bCTYLBjgaprrcEWwpSnBQnP3QnIxYK0HEaQ"; - const jwt::string_view secret = "00112233445566778899"; + const jwt::string_view key = "00112233445566778899"; std::error_code ec; - auto obj = jwt::decode(enc_str, secret, algorithms({"none", "hs384", "hs512"}), ec, verify(false)); + auto obj = jwt::decode(enc_str, algorithms({"none", "hs384", "hs512"}), ec, verify(false), secret(key)); ASSERT_FALSE (ec); @@ -138,7 +138,6 @@ TEST (DecodeTest, DecodeHS512) EXPECT_TRUE (obj.payload().has_claim_with_value("sub", "nothing much")); } - int main(int argc, char* argv[]) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS();