Make secret an optional argument for decode

This commit is contained in:
Arun M 2017-12-26 20:20:53 +05:30
parent 6c2bbe9ad0
commit 99f3c1db86
6 changed files with 48 additions and 20 deletions

View file

@ -34,6 +34,8 @@ enum class DecodeErrc
TypHeaderMiss, TypHeaderMiss,
TypMismatch, TypMismatch,
DuplClaims, DuplClaims,
KeyNotPresent,
KeyNotRequiredForNoneAlg,
}; };
/** /**

View file

@ -59,6 +59,10 @@ struct DecodeErrorCategory: std::error_category
return "json parse failed"; return "json parse failed";
case DecodeErrc::DuplClaims: case DecodeErrc::DuplClaims:
return "duplicate claims"; 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"); assert (0 && "Code not reached");

View file

@ -464,13 +464,19 @@ jwt_object::three_parts(const string_view enc_str)
return result; return result;
} }
template <typename DecodeParams, typename... Rest>
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<Rest>(args)...);
}
template <typename DecodeParams, typename... Rest> template <typename DecodeParams, typename... Rest>
void jwt_object::set_decode_params(DecodeParams& dparams, params::detail::leeway_param l, Rest&&... args) void jwt_object::set_decode_params(DecodeParams& dparams, params::detail::leeway_param l, Rest&&... args)
{ {
dparams.leeway = l.get(); dparams.leeway = l.get();
jwt_object::set_decode_params(dparams, std::forward<Rest>(args)...); jwt_object::set_decode_params(dparams, std::forward<Rest>(args)...);
return;
} }
template <typename DecodeParams, typename... Rest> template <typename DecodeParams, typename... Rest>
@ -478,7 +484,6 @@ void jwt_object::set_decode_params(DecodeParams& dparams, params::detail::verify
{ {
dparams.verify = v.get(); dparams.verify = v.get();
jwt_object::set_decode_params(dparams, std::forward<Rest>(args)...); jwt_object::set_decode_params(dparams, std::forward<Rest>(args)...);
return;
} }
template <typename DecodeParams, typename... Rest> template <typename DecodeParams, typename... Rest>
@ -487,7 +492,6 @@ void jwt_object::set_decode_params(DecodeParams& dparams, params::detail::issuer
dparams.issuer = std::move(i).get(); dparams.issuer = std::move(i).get();
dparams.has_issuer = true; dparams.has_issuer = true;
jwt_object::set_decode_params(dparams, std::forward<Rest>(args)...); jwt_object::set_decode_params(dparams, std::forward<Rest>(args)...);
return;
} }
template <typename DecodeParams, typename... Rest> template <typename DecodeParams, typename... Rest>
@ -508,7 +512,6 @@ void jwt_object::set_decode_params(DecodeParams& dparams)
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 params::detail::algorithms_param<SequenceT>& algos, const params::detail::algorithms_param<SequenceT>& algos,
std::error_code& ec, std::error_code& ec,
Args&&... args) Args&&... args)
@ -523,14 +526,21 @@ jwt_object decode(const string_view enc_str,
struct decode_params struct decode_params
{ {
/// key to decode the JWS
bool has_secret = false;
std::string secret;
/// Verify parameter. Defaulted to true. /// Verify parameter. Defaulted to true.
bool verify = true; bool verify = true;
/// Leeway parameter. Defaulted to zero seconds. /// Leeway parameter. Defaulted to zero seconds.
uint32_t leeway = 0; uint32_t leeway = 0;
///The issuer ///The issuer
//TODO: optional type //TODO: optional type
bool has_issuer = false; bool has_issuer = false;
std::string issuer; std::string issuer;
///The audience ///The audience
//TODO: optional type //TODO: optional type
bool has_aud = false; bool has_aud = false;
@ -571,6 +581,15 @@ jwt_object decode(const string_view enc_str,
ec = DecodeErrc::SignatureFormatError; ec = DecodeErrc::SignatureFormatError;
return obj; return obj;
} }
if (!dparams.has_secret) {
ec = DecodeErrc::KeyNotPresent;
return obj;
}
} else {
if (dparams.has_secret) {
ec = DecodeErrc::KeyNotRequiredForNoneAlg;
}
} }
//throws decode error //throws decode error
@ -589,7 +608,7 @@ jwt_object decode(const string_view enc_str,
//Verify the signature only if some algorithm was used //Verify the signature only if some algorithm was used
if (obj.header().algo() != algorithm::NONE) { if (obj.header().algo() != algorithm::NONE) {
jwt_signature jsign{key}; jwt_signature jsign{dparams.secret};
// Length of the encoded header and payload only. // Length of the encoded header and payload only.
// Addition of '1' to account for the '.' character. // Addition of '1' to account for the '.' character.
@ -617,13 +636,11 @@ jwt_object decode(const string_view enc_str,
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 params::detail::algorithms_param<SequenceT>& algos, const params::detail::algorithms_param<SequenceT>& algos,
Args&&... args) Args&&... args)
{ {
std::error_code ec{}; std::error_code ec{};
auto jwt_obj = decode(enc_str, auto jwt_obj = decode(enc_str,
key,
algos, algos,
ec, ec,
std::forward<Args>(args)...); std::forward<Args>(args)...);
@ -681,6 +698,11 @@ void jwt_throw_exception(const std::error_code& ec)
{ {
throw SignatureFormatError(ec.message()); throw SignatureFormatError(ec.message());
} }
case DecodeErrc::KeyNotRequiredForNoneAlg:
{
// Not an error. Just to be ignored.
break;
}
default: default:
{ {
throw DecodeError(ec.message()); throw DecodeError(ec.message());

View file

@ -730,6 +730,9 @@ private: // private APIs
public: //TODO: Not good public: //TODO: Not good
/// Decode parameters /// Decode parameters
template <typename DecodeParams, typename... Rest>
static void set_decode_params(DecodeParams& dparams, params::detail::secret_param s, Rest&&... args);
template <typename DecodeParams, typename... Rest> template <typename DecodeParams, typename... Rest>
static void set_decode_params(DecodeParams& dparams, params::detail::leeway_param l, Rest&&... args); 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 <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 params::detail::algorithms_param<SequenceT>& algos, const params::detail::algorithms_param<SequenceT>& algos,
std::error_code& ec, std::error_code& ec,
Args&&... args); Args&&... args);
@ -775,7 +777,6 @@ jwt_object decode(const string_view enc_str,
*/ */
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 params::detail::algorithms_param<SequenceT>& algos, const params::detail::algorithms_param<SequenceT>& algos,
Args&&... args); Args&&... args);

Binary file not shown.

View file

@ -9,7 +9,7 @@ TEST (DecodeTest, InvalidFinalDotForNoneAlg)
"eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ"; "eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ";
std::error_code ec; 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); ASSERT_TRUE (ec);
EXPECT_EQ (ec.value(), static_cast<int>(jwt::DecodeErrc::SignatureFormatError)); EXPECT_EQ (ec.value(), static_cast<int>(jwt::DecodeErrc::SignatureFormatError));
@ -22,7 +22,7 @@ TEST (DecodeTest, DecodeNoneAlgSign)
"eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ."; "eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ.";
std::error_code ec; 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_TRUE (ec);
EXPECT_EQ (ec.value(), static_cast<int>(jwt::AlgorithmErrc::NoneAlgorithmUsed)); EXPECT_EQ (ec.value(), static_cast<int>(jwt::AlgorithmErrc::NoneAlgorithmUsed));
@ -45,7 +45,7 @@ TEST (DecodeTest, DecodeWrongAlgo)
"eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ."; "eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ.";
std::error_code ec; 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_TRUE (ec);
EXPECT_EQ (ec.value(), static_cast<int>(jwt::VerificationErrc::InvalidAlgorithm)); EXPECT_EQ (ec.value(), static_cast<int>(jwt::VerificationErrc::InvalidAlgorithm));
} }
@ -58,7 +58,7 @@ TEST (DecodeTest, DecodeInvalidHeader)
"ehbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ."; "ehbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ.";
std::error_code ec; 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); ASSERT_TRUE (ec);
EXPECT_EQ (ec.value(), static_cast<int>(jwt::DecodeErrc::JsonParseError)); EXPECT_EQ (ec.value(), static_cast<int>(jwt::DecodeErrc::JsonParseError));
@ -72,7 +72,7 @@ TEST (DecodeTest, DecodeInvalidPayload)
"eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyfhuWcikiJyaWZ0LmlvIiwiZXhwIsexNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ."; "eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0.eyfhuWcikiJyaWZ0LmlvIiwiZXhwIsexNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ.";
std::error_code ec; 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); ASSERT_TRUE (ec);
EXPECT_EQ (ec.value(), static_cast<int>(jwt::DecodeErrc::JsonParseError)); EXPECT_EQ (ec.value(), static_cast<int>(jwt::DecodeErrc::JsonParseError));
@ -88,7 +88,7 @@ TEST (DecodeTest, DecodeHS256)
"jk7bRQKTLvs1RcuvMc2B_rt6WBYPoVPirYi_QRBPiuk"; "jk7bRQKTLvs1RcuvMc2B_rt6WBYPoVPirYi_QRBPiuk";
std::error_code ec; 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); ASSERT_FALSE (ec);
EXPECT_TRUE (obj.has_claim("iss")); EXPECT_TRUE (obj.has_claim("iss"));
@ -108,10 +108,10 @@ TEST (DecodeTest, DecodeHS384)
"eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ." "eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ."
"cGN4FZCe9Y2c1dA-jP71IXGnYbJRc4OaUTa5m7N7ybF5h6wBwxWQ-pdcxYchjDBL"; "cGN4FZCe9Y2c1dA-jP71IXGnYbJRc4OaUTa5m7N7ybF5h6wBwxWQ-pdcxYchjDBL";
const jwt::string_view secret = "0123456789abcdefghijklmnopqrstuvwxyz"; const jwt::string_view key = "0123456789abcdefghijklmnopqrstuvwxyz";
std::error_code ec; 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); ASSERT_FALSE (ec);
EXPECT_TRUE (obj.has_claim("sub")); EXPECT_TRUE (obj.has_claim("sub"));
@ -127,10 +127,10 @@ TEST (DecodeTest, DecodeHS512)
"eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ." "eyJhdWQiOiJyaWZ0LmlvIiwiZXhwIjoxNTEzODYzMzcxLCJzdWIiOiJub3RoaW5nIG11Y2gifQ."
"vQ-1JSFN1kPjUI3URP6AFK5z8V7xLhyhw-76QWhQg9Xcy-IgrJ-bCTYLBjgaprrcEWwpSnBQnP3QnIxYK0HEaQ"; "vQ-1JSFN1kPjUI3URP6AFK5z8V7xLhyhw-76QWhQg9Xcy-IgrJ-bCTYLBjgaprrcEWwpSnBQnP3QnIxYK0HEaQ";
const jwt::string_view secret = "00112233445566778899"; const jwt::string_view key = "00112233445566778899";
std::error_code ec; 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); ASSERT_FALSE (ec);
@ -138,7 +138,6 @@ TEST (DecodeTest, DecodeHS512)
EXPECT_TRUE (obj.payload().has_claim_with_value("sub", "nothing much")); EXPECT_TRUE (obj.payload().has_claim_with_value("sub", "nothing much"));
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();