Exception and non exception based decoding

This commit is contained in:
Arun M 2017-12-16 18:50:44 +05:30
parent 7a511c46fe
commit c484ced63d
4 changed files with 53 additions and 6 deletions

View file

@ -26,7 +26,8 @@ enum class AlgorithmFailureSource
*/ */
enum class DecodeErrc enum class DecodeErrc
{ {
JsonParseError = 1, EmptyAlgoList = 1,
JsonParseError,
AlgHeaderMiss, AlgHeaderMiss,
TypHeaderMiss, TypHeaderMiss,
TypMismatch, TypMismatch,
@ -42,6 +43,7 @@ enum class VerificationErrc
InvalidIssuer, InvalidIssuer,
InvalidAudience, InvalidAudience,
ImmatureSignature, ImmatureSignature,
InvalidSignature,
}; };
/** /**

View file

@ -43,6 +43,8 @@ struct DecodeErrorCategory: std::error_category
{ {
switch (static_cast<DecodeErrc>(ev)) switch (static_cast<DecodeErrc>(ev))
{ {
case DecodeErrc::EmptyAlgoList:
return "empty algorithm list";
case DecodeErrc::AlgHeaderMiss: case DecodeErrc::AlgHeaderMiss:
return "missing algorithm header"; return "missing algorithm header";
case DecodeErrc::TypHeaderMiss: case DecodeErrc::TypHeaderMiss:
@ -82,6 +84,8 @@ struct VerificationErrorCategory: std::error_category
return "invalid audience"; return "invalid audience";
case VerificationErrc::ImmatureSignature: case VerificationErrc::ImmatureSignature:
return "immature signature"; return "immature signature";
case VerificationErrc::InvalidSignature:
return "invalid signature";
}; };
assert (0 && "Code not reached"); assert (0 && "Code not reached");

View file

@ -470,10 +470,15 @@ template <typename SequenceT, typename... Args>
jwt_object decode(const string_view enc_str, jwt_object decode(const string_view enc_str,
const string_view key, const string_view key,
const params::detail::algorithms_param<SequenceT>& algos, const params::detail::algorithms_param<SequenceT>& algos,
std::error_code& ec,
Args&&... args) Args&&... args)
{ {
ec.clear();
jwt_object obj;
if (algos.get().size() == 0) { if (algos.get().size() == 0) {
throw DecodeError("Algorithms list cannot be empty"); ec = DecodeErrc::EmptyAlgoList;
return obj;
} }
struct decode_params struct decode_params
@ -495,7 +500,6 @@ jwt_object decode(const string_view enc_str,
decode_params dparams{}; decode_params dparams{};
set_decode_params(dparams, std::forward<Args>(args)...); set_decode_params(dparams, std::forward<Args>(args)...);
jwt_object obj;
auto parts = jwt_object::three_parts(enc_str); auto parts = jwt_object::three_parts(enc_str);
//throws decode error //throws decode error
@ -505,7 +509,9 @@ jwt_object decode(const string_view enc_str,
obj.payload(jwt_payload{parts[1]}); obj.payload(jwt_payload{parts[1]});
if (dparams.verify) { if (dparams.verify) {
std::error_code ec = obj.verify(dparams, algos); ec = obj.verify(dparams, algos);
if (ec) return obj;
} }
jwt_signature jsign{key}; jwt_signature jsign{key};
@ -514,18 +520,43 @@ jwt_object decode(const string_view enc_str,
// Addition of '1' to account for the '.' character. // Addition of '1' to account for the '.' character.
auto l = parts[0].length() + 1 + parts[1].length(); 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]); verify_result_t res = jsign.verify(obj.header(), enc_str.substr(0, l), parts[2]);
if (res.second) { if (res.second) {
throw VerificationError(res.second.message()); ec = res.second;
return obj;
} }
if (!res.first) { if (!res.first) {
throw VerificationError("Verification failed due to unknown reason"); ec = VerificationErrc::InvalidSignature;
return obj;
} }
return obj; return obj;
} }
template <typename SequenceT, typename... Args>
jwt_object decode(const string_view enc_str,
const string_view key,
const params::detail::algorithms_param<SequenceT>& algos,
Args&&... args)
{
std::error_code ec{};
auto jwt_obj = decode(enc_str,
key,
algos,
ec,
std::forward<Args>(args)...);
if (ec) {
jwt_throw_exception(ec);
}
return jwt_obj;
}
} // END namespace jwt } // END namespace jwt

View file

@ -722,11 +722,21 @@ private: // Data Members
jwt_object jwt_decode(const string_view encoded_str, const string_view key, bool validate=true); jwt_object jwt_decode(const string_view encoded_str, const string_view key, bool validate=true);
/** /**
* NOTE: Memory allocation exceptions are not caught.
*/ */
template <typename SequenceT, typename... Args> template <typename SequenceT, typename... Args>
jwt_object decode(const string_view enc_str, jwt_object decode(const string_view enc_str,
const string_view key, const string_view key,
const params::detail::algorithms_param<SequenceT>& algos, const params::detail::algorithms_param<SequenceT>& algos,
std::error_code& ec,
Args&&... args);
/**
*/
template <typename SequenceT, typename... Args>
jwt_object decode(const string_view enc_str,
const string_view key,
const params::detail::algorithms_param<SequenceT>& algos,
Args&&... args); Args&&... args);