mirror of
https://github.com/arun11299/cpp-jwt.git
synced 2025-05-15 09:18:33 +00:00
Added nbf check and more exception and error code handling
This commit is contained in:
parent
77c11e8eb9
commit
b5088a6d9c
6 changed files with 146 additions and 39 deletions
|
@ -451,8 +451,6 @@ public:
|
||||||
{
|
{
|
||||||
std::error_code ec{};
|
std::error_code ec{};
|
||||||
|
|
||||||
char* out;
|
|
||||||
unsigned int l;
|
|
||||||
std::string ii{data.data(), data.length()};
|
std::string ii{data.data(), data.length()};
|
||||||
|
|
||||||
EC_PKEY_uptr pkey{load_key(key, ec), ev_pkey_deletor};
|
EC_PKEY_uptr pkey{load_key(key, ec), ev_pkey_deletor};
|
||||||
|
|
|
@ -30,6 +30,19 @@ private:
|
||||||
const char* msg_ = nullptr;
|
const char* msg_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
class SigningError : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
SigningError(std::string msg)
|
||||||
|
: std::runtime_error(std::move(msg))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
class DecodeError final: public std::runtime_error
|
class DecodeError final: public std::runtime_error
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
|
|
||||||
namespace jwt {
|
namespace jwt {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
static void jwt_throw_exception(const std::error_code& ec);
|
||||||
|
|
||||||
template <typename T, typename Cond>
|
template <typename T, typename Cond>
|
||||||
std::string to_json_str(const T& obj, bool pretty)
|
std::string to_json_str(const T& obj, bool pretty)
|
||||||
{
|
{
|
||||||
|
@ -124,9 +128,11 @@ void jwt_payload::decode(const string_view enc_str) throw(DecodeError)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string jwt_signature::encode(const jwt_header& header,
|
std::string jwt_signature::encode(const jwt_header& header,
|
||||||
const jwt_payload& payload)
|
const jwt_payload& payload,
|
||||||
|
std::error_code& ec)
|
||||||
{
|
{
|
||||||
std::string jwt_msg;
|
std::string jwt_msg;
|
||||||
|
ec.clear();
|
||||||
//TODO: Optimize allocations
|
//TODO: Optimize allocations
|
||||||
|
|
||||||
sign_func_t sign_fn = get_sign_algorithm_impl(header);
|
sign_func_t sign_fn = get_sign_algorithm_impl(header);
|
||||||
|
@ -137,7 +143,7 @@ std::string jwt_signature::encode(const jwt_header& header,
|
||||||
std::string data = hdr_sign + '.' + pld_sign;
|
std::string data = hdr_sign + '.' + pld_sign;
|
||||||
auto res = sign_fn(key_, data);
|
auto res = sign_fn(key_, data);
|
||||||
if (res.second) {
|
if (res.second) {
|
||||||
std::cout << res.second.message() << std::endl;
|
ec = res.second;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,11 +329,21 @@ jwt_object& jwt_object::remove_claim(const string_view name)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string jwt_object::signature(std::error_code& ec) const
|
||||||
|
{
|
||||||
|
ec.clear();
|
||||||
|
jwt_signature jws{secret_};
|
||||||
|
return jws.encode(header_, payload_, ec);
|
||||||
|
}
|
||||||
|
|
||||||
std::string jwt_object::signature() const
|
std::string jwt_object::signature() const
|
||||||
{
|
{
|
||||||
jwt_signature jws{secret_};
|
std::error_code ec;
|
||||||
|
std::string res = signature(ec);
|
||||||
return jws.encode(header_, payload_);
|
if (ec) {
|
||||||
|
throw SigningError(ec.message());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Params, typename SequenceT>
|
template <typename Params, typename SequenceT>
|
||||||
|
@ -392,6 +408,22 @@ std::error_code jwt_object::verify(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Check for NBF
|
||||||
|
if (has_claim(registered_claims::not_before))
|
||||||
|
{
|
||||||
|
auto curr_time =
|
||||||
|
std::chrono::duration_cast<
|
||||||
|
std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||||
|
|
||||||
|
auto p_exp = payload()
|
||||||
|
.get_claim_value<uint64_t>(registered_claims::not_before);
|
||||||
|
|
||||||
|
if ((p_exp - dparams.leeway) < curr_time) {
|
||||||
|
ec = VerificationErrc::ImmatureSignature;
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,33 +596,34 @@ void jwt_throw_exception(const std::error_code& ec)
|
||||||
|
|
||||||
if (&cat == &theVerificationErrorCategory)
|
if (&cat == &theVerificationErrorCategory)
|
||||||
{
|
{
|
||||||
switch (ec.value()) {
|
switch (static_cast<VerificationErrc>(ec.value()))
|
||||||
case VerificationErrc::InvalidAlgorithm:
|
|
||||||
{
|
{
|
||||||
throw InvalidAlgorithmError(ec.message());
|
case VerificationErrc::InvalidAlgorithm:
|
||||||
}
|
{
|
||||||
case VerificationErrc::TokenExpired:
|
throw InvalidAlgorithmError(ec.message());
|
||||||
{
|
}
|
||||||
throw TokenExpiredError(ec.message());
|
case VerificationErrc::TokenExpired:
|
||||||
}
|
{
|
||||||
case VerificationErrc::InvalidIssuer:
|
throw TokenExpiredError(ec.message());
|
||||||
{
|
}
|
||||||
throw InvalidIssuerError(ec.message());
|
case VerificationErrc::InvalidIssuer:
|
||||||
}
|
{
|
||||||
case VerificationErrc::InvalidAudience:
|
throw InvalidIssuerError(ec.message());
|
||||||
{
|
}
|
||||||
throw InvalidAudienceError(ec.message());
|
case VerificationErrc::InvalidAudience:
|
||||||
}
|
{
|
||||||
case VerificationErrc::ImmatureSignature:
|
throw InvalidAudienceError(ec.message());
|
||||||
{
|
}
|
||||||
throw ImmatureSignatureError(ec.message());
|
case VerificationErrc::ImmatureSignature:
|
||||||
}
|
{
|
||||||
case VerificationErrc::InvalidSignature:
|
throw ImmatureSignatureError(ec.message());
|
||||||
{
|
}
|
||||||
throw InvalidSignatureError(ec.message());
|
case VerificationErrc::InvalidSignature:
|
||||||
}
|
{
|
||||||
default:
|
throw InvalidSignatureError(ec.message());
|
||||||
assert (0 && "Unknown error code");
|
}
|
||||||
|
default:
|
||||||
|
assert (0 && "Unknown error code");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,11 +634,14 @@ void jwt_throw_exception(const std::error_code& ec)
|
||||||
|
|
||||||
if (&cat == &theAlgorithmErrCategory)
|
if (&cat == &theAlgorithmErrCategory)
|
||||||
{
|
{
|
||||||
switch (ec.value()) {
|
switch (static_cast<AlgorithmErrc>(ec.value()))
|
||||||
case AlgorithmErrc::VerificationErr:
|
{
|
||||||
throw InvalidSignatureError(ec.message());
|
case AlgorithmErrc::VerificationErr:
|
||||||
default:
|
{
|
||||||
assert (0 && "Unknown error code or not to be treated as an error");
|
throw InvalidSignatureError(ec.message());
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert (0 && "Unknown error code or not to be treated as an error");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -505,7 +505,8 @@ public: // Exposed APIs
|
||||||
/*!
|
/*!
|
||||||
*/
|
*/
|
||||||
std::string encode(const jwt_header& header,
|
std::string encode(const jwt_header& header,
|
||||||
const jwt_payload& payload);
|
const jwt_payload& payload,
|
||||||
|
std::error_code& ec);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*/
|
*/
|
||||||
|
@ -666,6 +667,11 @@ public: // Exposed APIs
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
std::string signature(std::error_code& ec) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception throwing version.
|
||||||
|
*/
|
||||||
std::string signature() const;
|
std::string signature() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CPP_JWT_PARAMETERS_HPP
|
#define CPP_JWT_PARAMETERS_HPP
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <chrono>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -12,6 +13,9 @@
|
||||||
#include "jwt/string_view.hpp"
|
#include "jwt/string_view.hpp"
|
||||||
|
|
||||||
namespace jwt {
|
namespace jwt {
|
||||||
|
|
||||||
|
using system_time_t = std::chrono::time_point<std::chrono::system_clock>;
|
||||||
|
|
||||||
namespace params {
|
namespace params {
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,6 +176,24 @@ struct issuer_param
|
||||||
std::string iss_;
|
std::string iss_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
struct nbf_param
|
||||||
|
{
|
||||||
|
nbf_param(const jwt::system_time_t tp)
|
||||||
|
: duration_(std::chrono::duration_cast<
|
||||||
|
std::chrono::seconds>(tp.time_since_epoch()).count())
|
||||||
|
{}
|
||||||
|
|
||||||
|
nbf_param(const uint64_t epoch)
|
||||||
|
: duration_(epoch)
|
||||||
|
{}
|
||||||
|
|
||||||
|
uint64_t get() const noexcept { return duration_; }
|
||||||
|
|
||||||
|
uint64_t duration_;
|
||||||
|
};
|
||||||
|
|
||||||
} // END namespace detail
|
} // END namespace detail
|
||||||
|
|
||||||
// Useful typedef
|
// Useful typedef
|
||||||
|
@ -289,6 +311,38 @@ algorithms(SequenceConcept&& sc)
|
||||||
return { std::forward<SequenceConcept>(sc) };
|
return { std::forward<SequenceConcept>(sc) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
detail::audience_param
|
||||||
|
aud(const string_view aud)
|
||||||
|
{
|
||||||
|
return { aud.data() };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
detail::issuer_param
|
||||||
|
issuer(const string_view iss)
|
||||||
|
{
|
||||||
|
return { iss.data() };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
detail::nbf_param
|
||||||
|
nbf(const system_time_t tp)
|
||||||
|
{
|
||||||
|
return { tp };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
detail::nbf_param
|
||||||
|
nbf(const uint64_t epoch)
|
||||||
|
{
|
||||||
|
return { epoch };
|
||||||
|
}
|
||||||
|
|
||||||
} // END namespace params
|
} // END namespace params
|
||||||
} // END namespace jwt
|
} // END namespace jwt
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue