mirror of
https://github.com/arun11299/cpp-jwt.git
synced 2025-05-15 17:28:37 +00:00
Exception and non exception based decoding
This commit is contained in:
parent
7a511c46fe
commit
c484ced63d
4 changed files with 53 additions and 6 deletions
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -721,6 +721,16 @@ 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>
|
||||||
|
jwt_object decode(const string_view enc_str,
|
||||||
|
const string_view key,
|
||||||
|
const params::detail::algorithms_param<SequenceT>& algos,
|
||||||
|
std::error_code& ec,
|
||||||
|
Args&&... args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
template <typename SequenceT, typename... Args>
|
template <typename SequenceT, typename... Args>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue