jwt_object API fixes

This commit is contained in:
Arun M 2017-11-23 17:24:56 +05:30
parent 0751d033dc
commit fc294cbc8a
7 changed files with 147 additions and 17 deletions

View file

@ -341,6 +341,25 @@ struct HMACSign
} }
/** /**
* Verifies the JWT string against the signature using
* the provided key.
*
* Arguments:
* @key : The secret/key to use for the signing.
* Cannot be empty string.
* @head : The part of JWT encoded string representing header
* and the payload claims.
* @sign : The signature part of the JWT encoded string.
*
* Returns:
* verify_result_t
* verify_result_t::first set to true if verification succeeds.
* false otherwise.
* verify_result_t::second set to relevant error if verification fails.
*
* Exceptions:
* Any allocation failure will result in jwt::MemoryAllocationException
* being thrown.
*/ */
static verify_result_t static verify_result_t
verify(const string_view key, const string_view head, const string_view sign); verify(const string_view key, const string_view head, const string_view sign);
@ -382,6 +401,7 @@ struct HMACSign<algo::NONE>
} }
/** /**
* Basically a no-op. Sets the error code to NoneAlgorithmUsed.
*/ */
static verify_result_t static verify_result_t
verify(const string_view key, const string_view head, const string_view sign) verify(const string_view key, const string_view head, const string_view sign)
@ -446,17 +466,10 @@ public:
return { std::move(sign), ec }; return { std::move(sign), ec };
} }
/*! /**
*/ */
static verify_result_t static verify_result_t
verify(const string_view key, const string_view head, const string_view sign) verify(const string_view key, const string_view head, const string_view sign);
{
bool compare_res = 0;
std::error_code ec{};
//TODO: Set the appropriate error code for none
return {compare_res, ec};
}
private: private:
/*! /*!

View file

@ -70,6 +70,31 @@ verify_result_t HMACSign<Hasher>::verify(
return { ret, ec }; return { ret, ec };
} }
template <typename Hasher>
verify_result_t PEMSign<Hasher>::verify(
const string_view key,
const string_view head,
const string_view jwt_sign)
{
/*
* unsigned char *sig = NULL;
* EVP_MD_CTX *mdctx = NULL;
* ECDSA_SIG *ec_sig = NULL;
* BIGNUM *ec_sig_r = NULL;
* BIGNUM *ec_sig_s = NULL;
* EVP_PKEY *pkey = NULL;
* const EVP_MD *alg;
* int type;
* int pkey_type;
* BIO *bufkey = NULL;
* int ret = 0;
* int slen;
*/
std::error_code ec{};
return { true, ec };
}
template <typename Hasher> template <typename Hasher>
EVP_PKEY* PEMSign<Hasher>::load_key( EVP_PKEY* PEMSign<Hasher>::load_key(
const string_view key, const string_view key,

View file

@ -5,7 +5,7 @@
namespace jwt { namespace jwt {
template <typename T> 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)
{ {
return pretty ? obj.create_json_obj().dump(2) return pretty ? obj.create_json_obj().dump(2)
@ -248,7 +248,7 @@ void jwt_object::set_parameters()
} }
template <typename T> template <typename T>
jwt_payload& jwt_object::add_claim(const std::string& name, T&& value) jwt_payload& jwt_object::add_claim(const string_view name, T&& value)
{ {
payload_.add_claim(name, std::forward<T>(value)); payload_.add_claim(name, std::forward<T>(value));
return payload_; return payload_;

View file

@ -243,6 +243,75 @@ std::ostream& operator<< (std::ostream& os, basic_string_view<CharT, Traits> sv)
return os; return os;
} }
namespace {
/*
* Copy of gcc implementation of murmurhash
* hash_bytes.cc
*/
inline size_t
unaligned_load(const char* p)
{
std::size_t result;
std::memcpy(&result, p, sizeof(result));
return result;
}
inline size_t
hash_bytes(const void* ptr, size_t len, size_t seed)
{
const size_t m = 0x5bd1e995;
size_t hash = seed ^ len;
const char* buf = static_cast<const char*>(ptr);
// Mix 4 bytes at a time into the hash.
while(len >= 4)
{
size_t k = unaligned_load(buf);
k *= m;
k ^= k >> 24;
k *= m;
hash *= m;
hash ^= k;
buf += 4;
len -= 4;
}
// Handle the last few bytes of the input array.
switch(len)
{
case 3:
hash ^= static_cast<unsigned char>(buf[2]) << 16;
//FALLTHROUGH
case 2:
hash ^= static_cast<unsigned char>(buf[1]) << 8;
//FALLTHROUGH
case 1:
hash ^= static_cast<unsigned char>(buf[0]);
hash *= m;
};
// Do a few final mixes of the hash.
hash ^= hash >> 13;
hash *= m;
hash ^= hash >> 15;
return hash;
}
}
} // END namespace jwt } // END namespace jwt
/// Provide a hash specialization
namespace std {
template <>
struct hash<jwt::string_view>
{
size_t operator()(const jwt::string_view& sv) const
{
return jwt::hash_bytes((void*)sv.data(), sv.length(), static_cast<size_t>(0xc70f6907UL));
}
};
}
#endif #endif

View file

@ -94,7 +94,8 @@ string_view reg_claims_to_str(enum registered_claims claim) noexcept
// Fwd declaration for friend functions to specify the // Fwd declaration for friend functions to specify the
// default arguments // default arguments
// See: https://stackoverflow.com/a/23336823/434233 // See: https://stackoverflow.com/a/23336823/434233
template <typename T> template <typename T, typename = typename std::enable_if<
detail::meta::has_create_json_obj_member<T>{}>::type>
std::string to_json_str(const T& obj, bool pretty=false); std::string to_json_str(const T& obj, bool pretty=false);
template <typename T> template <typename T>
@ -106,7 +107,7 @@ struct write_interface
{ {
/*! /*!
*/ */
template <typename T> template <typename T, typename Cond>
friend std::string to_json_str(const T& obj, bool pretty); friend std::string to_json_str(const T& obj, bool pretty);
/*! /*!
@ -284,7 +285,7 @@ public: // Exposed APIs
/** /**
*/ */
template <typename T> template <typename T>
bool add_claim(const std::string& cname, T&& cvalue, bool overwrite=false) bool add_claim(const string_view cname, T&& cvalue, bool overwrite=false)
{ {
// Duplicate claim names not allowed // Duplicate claim names not allowed
// if overwrite flag is set to true. // if overwrite flag is set to true.
@ -297,8 +298,6 @@ public: // Exposed APIs
claim_names_.emplace(cname.data(), cname.length()); claim_names_.emplace(cname.data(), cname.length());
//Add it to the json payload //Add it to the json payload
//TODO: claim name copied twice inside json
//and in the set
payload_[cname.data()] = std::forward<T>(cvalue); payload_[cname.data()] = std::forward<T>(cvalue);
return true; return true;
@ -521,7 +520,7 @@ public: // Exposed APIs
/** /**
*/ */
template <typename T> template <typename T>
jwt_payload& add_claim(const std::string& name, T&& value); jwt_payload& add_claim(const string_view name, T&& value);
/** /**
*/ */

Binary file not shown.

View file

@ -1,4 +1,7 @@
#include <iostream> #include <iostream>
#include <map>
#include <string>
#include <unordered_map>
#include "jwt/jwt.hpp" #include "jwt/jwt.hpp"
void basic_jwt_object_test() void basic_jwt_object_test()
@ -8,6 +11,27 @@ void basic_jwt_object_test()
{"a", "b"}, {"a", "b"},
{"c", "d"} {"c", "d"}
})); }));
//check with std::map
std::map<std::string, std::string> m;
m["a"] = "b";
m["c"] = "d";
jwt::jwt_object obj1{payload(m)};
auto obj2 = std::move(obj1);
std::cout << obj2.payload() << std::endl;
//check with unordered map of string_view
std::unordered_map<jwt::string_view, std::string> um = {
{"a", "b"},
{"c", "d"}
};
jwt::jwt_object obj3{payload(um)};
obj3.add_claim("f", true)
.add_claim("time", 176353563);
std::cout << jwt::to_json_str(obj3.payload(), true) << std::endl;
} }
int main() { int main() {