From c484ced63dcc80d2deb88ce84d90ce6882a8b8ee Mon Sep 17 00:00:00 2001 From: Arun M Date: Sat, 16 Dec 2017 18:50:44 +0530 Subject: [PATCH] Exception and non exception based decoding --- include/jwt/error_codes.hpp | 4 +++- include/jwt/impl/error_codes.ipp | 4 ++++ include/jwt/impl/jwt.ipp | 41 ++++++++++++++++++++++++++++---- include/jwt/jwt.hpp | 10 ++++++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/include/jwt/error_codes.hpp b/include/jwt/error_codes.hpp index 08d2b7d..6b63a9b 100644 --- a/include/jwt/error_codes.hpp +++ b/include/jwt/error_codes.hpp @@ -26,7 +26,8 @@ enum class AlgorithmFailureSource */ enum class DecodeErrc { - JsonParseError = 1, + EmptyAlgoList = 1, + JsonParseError, AlgHeaderMiss, TypHeaderMiss, TypMismatch, @@ -42,6 +43,7 @@ enum class VerificationErrc InvalidIssuer, InvalidAudience, ImmatureSignature, + InvalidSignature, }; /** diff --git a/include/jwt/impl/error_codes.ipp b/include/jwt/impl/error_codes.ipp index 672967c..d3bda2d 100644 --- a/include/jwt/impl/error_codes.ipp +++ b/include/jwt/impl/error_codes.ipp @@ -43,6 +43,8 @@ struct DecodeErrorCategory: std::error_category { switch (static_cast(ev)) { + case DecodeErrc::EmptyAlgoList: + return "empty algorithm list"; case DecodeErrc::AlgHeaderMiss: return "missing algorithm header"; case DecodeErrc::TypHeaderMiss: @@ -82,6 +84,8 @@ struct VerificationErrorCategory: std::error_category return "invalid audience"; case VerificationErrc::ImmatureSignature: return "immature signature"; + case VerificationErrc::InvalidSignature: + return "invalid signature"; }; assert (0 && "Code not reached"); diff --git a/include/jwt/impl/jwt.ipp b/include/jwt/impl/jwt.ipp index a5f31c8..6766a86 100644 --- a/include/jwt/impl/jwt.ipp +++ b/include/jwt/impl/jwt.ipp @@ -470,10 +470,15 @@ 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) { + ec.clear(); + jwt_object obj; + if (algos.get().size() == 0) { - throw DecodeError("Algorithms list cannot be empty"); + ec = DecodeErrc::EmptyAlgoList; + return obj; } struct decode_params @@ -495,7 +500,6 @@ jwt_object decode(const string_view enc_str, decode_params dparams{}; set_decode_params(dparams, std::forward(args)...); - jwt_object obj; auto parts = jwt_object::three_parts(enc_str); //throws decode error @@ -505,7 +509,9 @@ jwt_object decode(const string_view enc_str, obj.payload(jwt_payload{parts[1]}); if (dparams.verify) { - std::error_code ec = obj.verify(dparams, algos); + ec = obj.verify(dparams, algos); + + if (ec) return obj; } jwt_signature jsign{key}; @@ -514,18 +520,43 @@ jwt_object decode(const string_view enc_str, // Addition of '1' to account for the '.' character. auto l = parts[0].length() + 1 + parts[1].length(); + //MemoryAllocationError is not caught verify_result_t res = jsign.verify(obj.header(), enc_str.substr(0, l), parts[2]); if (res.second) { - throw VerificationError(res.second.message()); + ec = res.second; + return obj; } if (!res.first) { - throw VerificationError("Verification failed due to unknown reason"); + ec = VerificationErrc::InvalidSignature; + return obj; } return obj; } + + +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)...); + + if (ec) { + jwt_throw_exception(ec); + } + + return jwt_obj; +} + } // END namespace jwt diff --git a/include/jwt/jwt.hpp b/include/jwt/jwt.hpp index 2a9ba86..52401aa 100644 --- a/include/jwt/jwt.hpp +++ b/include/jwt/jwt.hpp @@ -722,11 +722,21 @@ private: // Data Members jwt_object jwt_decode(const string_view encoded_str, const string_view key, bool validate=true); /** + * NOTE: Memory allocation exceptions are not caught. */ 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); + +/** + */ +template +jwt_object decode(const string_view enc_str, + const string_view key, + const params::detail::algorithms_param& algos, Args&&... args);