mirror of
https://github.com/arun11299/cpp-jwt.git
synced 2025-05-14 16:58:34 +00:00
Verification
This commit is contained in:
parent
796abd6e65
commit
81e6b2392e
8 changed files with 125 additions and 30 deletions
Binary file not shown.
|
@ -25,7 +25,7 @@ using sign_func_t = sign_result_t (*) (const string_view key,
|
|||
const string_view data);
|
||||
///
|
||||
using verify_func_t = verify_result_t (*) (const string_view key,
|
||||
const string_view header,
|
||||
const string_view head,
|
||||
const string_view jwt_sign);
|
||||
|
||||
namespace algo {
|
||||
|
@ -215,7 +215,7 @@ struct HMACSign<algo::NONE>
|
|||
static verify_result_t
|
||||
verify(const string_view key, const string_view head, const string_view sign)
|
||||
{
|
||||
int compare_res = 0;
|
||||
bool compare_res = 0;
|
||||
std::error_code ec{};
|
||||
|
||||
//TODO: Set the appropriate error code for none
|
||||
|
@ -268,6 +268,18 @@ public:
|
|||
return {std::move(sign), ec};
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
static verify_result_t
|
||||
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:
|
||||
/*!
|
||||
*/
|
||||
|
@ -284,5 +296,7 @@ private:
|
|||
|
||||
} // END namespace jwt
|
||||
|
||||
#include "jwt/impl/algorithm.ipp"
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -189,7 +189,7 @@ std::string base64_decode(const char* in, size_t len)
|
|||
|
||||
/*!
|
||||
*/
|
||||
void base64_uri_encode(char* data, size_t len) noexcept
|
||||
size_t base64_uri_encode(char* data, size_t len) noexcept
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
|
@ -209,7 +209,7 @@ void base64_uri_encode(char* data, size_t len) noexcept
|
|||
};
|
||||
}
|
||||
|
||||
return;
|
||||
return j;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -219,7 +219,9 @@ std::string base64_uri_decode(const char* data, size_t len)
|
|||
std::string uri_dec;
|
||||
uri_dec.resize(len + 4);
|
||||
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
size_t i = 0;
|
||||
|
||||
for (; i < len; ++i) {
|
||||
switch (data[i]) {
|
||||
case '-':
|
||||
uri_dec[i] = '+';
|
||||
|
|
|
@ -26,7 +26,7 @@ template <typename T>
|
|||
struct has_create_json_obj_member<T,
|
||||
void_t<
|
||||
decltype(
|
||||
std::declval<T&&>.create_json_obj(),
|
||||
std::declval<T&&>().create_json_obj(),
|
||||
(void)0
|
||||
)
|
||||
>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef CPP_JWT_ALGORITHM_IPP
|
||||
#define CPP_JWT_ALGORITHM_IPP
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace jwt {
|
||||
|
||||
template <typename Hasher>
|
||||
|
@ -14,10 +16,14 @@ verify_result_t HMACSign<Hasher>::verify(
|
|||
if (ptr) BIO_free_all(ptr);
|
||||
};
|
||||
|
||||
using bio_deletor_t = decltype(bio_deletor);
|
||||
using BIO_unique_ptr = std::unique_ptr<BIO_unique_ptr, bio_deletor_t>;
|
||||
std::cout << "Key: " << key << std::endl;
|
||||
std::cout << "Head: " << head << std::endl;
|
||||
std::cout << "JWT: " << jwt_sign << std::endl;
|
||||
|
||||
BIO_unique_ptr b64{BIO_new(BIO_f_base64())};
|
||||
using bio_deletor_t = decltype(bio_deletor);
|
||||
using BIO_unique_ptr = std::unique_ptr<BIO, bio_deletor_t>;
|
||||
|
||||
BIO_unique_ptr b64{BIO_new(BIO_f_base64()), bio_deletor};
|
||||
if (!b64) {
|
||||
//TODO: set error code
|
||||
return {false, ec};
|
||||
|
@ -29,10 +35,11 @@ verify_result_t HMACSign<Hasher>::verify(
|
|||
return {false, ec};
|
||||
}
|
||||
|
||||
BIO_push(b64, bmem);
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
BIO_push(b64.get(), bmem);
|
||||
BIO_set_flags(b64.get(), BIO_FLAGS_BASE64_NO_NL);
|
||||
|
||||
unsigned char enc_buf[EVP_MAX_MD_SIZE];
|
||||
uint32_t enc_buf_len = 0;
|
||||
|
||||
unsigned char* res = HMAC(Hasher{}(),
|
||||
key.data(),
|
||||
|
@ -41,12 +48,36 @@ verify_result_t HMACSign<Hasher>::verify(
|
|||
head.length(),
|
||||
enc_buf,
|
||||
&enc_buf_len);
|
||||
if (!res) {
|
||||
//TODO: set error code
|
||||
return {false, ec};
|
||||
}
|
||||
|
||||
return {true, ec};
|
||||
BIO_write(b64.get(), enc_buf, enc_buf_len);
|
||||
(void)BIO_flush(b64.get());
|
||||
|
||||
int len = BIO_pending(bmem);
|
||||
if (len < 0) {
|
||||
//TODO: set error code
|
||||
return {false, ec};
|
||||
}
|
||||
|
||||
std::string cbuf;
|
||||
cbuf.resize(len + 1);
|
||||
|
||||
len = BIO_read(bmem, &cbuf[0], len);
|
||||
cbuf.resize(len);
|
||||
|
||||
//Make the base64 string url safe
|
||||
auto new_len = jwt::base64_uri_encode(&cbuf[0], cbuf.length());
|
||||
cbuf.resize(new_len);
|
||||
std::cout << "cbuf: " << cbuf << std::endl;
|
||||
|
||||
return {string_view{cbuf} == jwt_sign, ec};
|
||||
}
|
||||
|
||||
template <typename Hasher>
|
||||
sign_result_t PEMSign<Hasher>::load_key(const string_view key)
|
||||
EVP_PKEY* PEMSign<Hasher>::load_key(const string_view key)
|
||||
{
|
||||
auto bio_deletor = [](BIO* ptr) {
|
||||
if (ptr) BIO_free(ptr);
|
||||
|
|
|
@ -79,7 +79,7 @@ std::string jwt_signature::encode(const jwt_header& header,
|
|||
std::string jwt_msg;
|
||||
//TODO: Optimize allocations
|
||||
|
||||
sign_func_t sign_fn = get_algorithm_impl(header);
|
||||
sign_func_t sign_fn = get_sign_algorithm_impl(header);
|
||||
|
||||
std::string hdr_sign = header.base64_encode();
|
||||
std::string pld_sign = payload.base64_encode();
|
||||
|
@ -88,7 +88,8 @@ std::string jwt_signature::encode(const jwt_header& header,
|
|||
auto res = sign_fn(key_, data);
|
||||
|
||||
std::string b64hash = base64_encode(res.first.c_str(), res.first.length());
|
||||
base64_uri_encode(&b64hash[0], b64hash.length());
|
||||
auto new_len = base64_uri_encode(&b64hash[0], b64hash.length());
|
||||
b64hash.resize(new_len);
|
||||
|
||||
jwt_msg = data + '.' + b64hash;
|
||||
|
||||
|
@ -97,16 +98,18 @@ std::string jwt_signature::encode(const jwt_header& header,
|
|||
|
||||
bool jwt_signature::verify(const jwt_header& header,
|
||||
const string_view hdr_pld_sign,
|
||||
const srting_view jwt_sign)
|
||||
const string_view jwt_sign)
|
||||
{
|
||||
//TODO: is bool the right choice ?
|
||||
verify_func_t verify_fn = get_verify_algorithm_impl(header);
|
||||
verify_fn(key_, hdr_pld_sign, jwt_sign);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
sign_func_t
|
||||
jwt_signature::get_algorithm_impl(const jwt_header& hdr) const noexcept
|
||||
jwt_signature::get_sign_algorithm_impl(const jwt_header& hdr) const noexcept
|
||||
{
|
||||
sign_func_t ret = nullptr;
|
||||
|
||||
|
@ -148,16 +151,61 @@ jwt_signature::get_algorithm_impl(const jwt_header& hdr) const noexcept
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
verify_func_t
|
||||
jwt_signature::get_verify_algorithm_impl(const jwt_header& hdr) const noexcept
|
||||
{
|
||||
verify_func_t ret = nullptr;
|
||||
|
||||
switch (hdr.algo()) {
|
||||
case algorithm::HS256:
|
||||
ret = HMACSign<algo::HS256>::verify;
|
||||
break;
|
||||
case algorithm::HS384:
|
||||
ret = HMACSign<algo::HS384>::verify;
|
||||
break;
|
||||
case algorithm::HS512:
|
||||
ret = HMACSign<algo::HS512>::verify;
|
||||
break;
|
||||
case algorithm::NONE:
|
||||
ret = HMACSign<algo::NONE>::verify;
|
||||
break;
|
||||
case algorithm::RS256:
|
||||
ret = PEMSign<algo::RS256>::verify;
|
||||
break;
|
||||
case algorithm::RS384:
|
||||
ret = PEMSign<algo::RS384>::verify;
|
||||
break;
|
||||
case algorithm::RS512:
|
||||
ret = PEMSign<algo::RS512>::verify;
|
||||
break;
|
||||
case algorithm::ES256:
|
||||
ret = PEMSign<algo::ES256>::verify;
|
||||
break;
|
||||
case algorithm::ES384:
|
||||
ret = PEMSign<algo::ES384>::verify;
|
||||
break;
|
||||
case algorithm::ES512:
|
||||
ret = PEMSign<algo::ES512>::verify;
|
||||
break;
|
||||
default:
|
||||
assert (0 && "Code not reached");
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//====================================================================
|
||||
|
||||
void jwt_decode(string_view encoded_str, string_view key, bool validate)
|
||||
void jwt_decode(const string_view encoded_str, const string_view key, bool validate)
|
||||
{
|
||||
//TODO: implement error_code
|
||||
size_t fpos = encoded_str.find_first_of('.');
|
||||
assert (fpos != string_view::npos);
|
||||
|
||||
string_view head{&encoded_str[0], fpos};
|
||||
std::cout << "Head: " << head << std::endl;
|
||||
jwt_header hdr;
|
||||
hdr.decode(head);
|
||||
|
||||
|
@ -166,13 +214,13 @@ void jwt_decode(string_view encoded_str, string_view key, bool validate)
|
|||
//TODO: Check for none algorithm
|
||||
}
|
||||
string_view body{&encoded_str[fpos + 1], spos - fpos - 1};
|
||||
std::cout << "Body: " << body << std::endl;
|
||||
|
||||
//Json objects or claims get set in the decode
|
||||
jwt_payload pld;
|
||||
pld.decode(body);
|
||||
|
||||
|
||||
jwt_signature jsign{key};
|
||||
jsign.verify(hdr, encoded_str.substr(0, spos), encoded_str);
|
||||
}
|
||||
|
||||
} // END namespace jwt
|
||||
|
|
|
@ -176,7 +176,7 @@ struct write_interface
|
|||
|
||||
/*!
|
||||
*/
|
||||
template <typename T>
|
||||
template <typename T, typename Cond>
|
||||
friend std::ostream& operator<< (std::ostream& os, const T& obj);
|
||||
};
|
||||
|
||||
|
@ -195,12 +195,9 @@ struct base64_enc_dec
|
|||
{
|
||||
std::string jstr = to_json_str(*static_cast<const Derived*>(this), with_pretty);
|
||||
std::string b64_str = jwt::base64_encode(jstr.c_str(), jstr.length());
|
||||
size_t rpos = b64_str.length();
|
||||
while(b64_str[rpos-1] == '=') rpos--;
|
||||
// Remove the '=' characters
|
||||
b64_str.resize(rpos);
|
||||
// Do the URI safe encoding
|
||||
jwt::base64_uri_encode(&b64_str[0], b64_str.length());
|
||||
auto new_len = jwt::base64_uri_encode(&b64_str[0], b64_str.length());
|
||||
b64_str.resize(new_len);
|
||||
|
||||
return b64_str;
|
||||
}
|
||||
|
@ -438,7 +435,11 @@ public: // Exposed APIs
|
|||
private: // Private implementation
|
||||
/*!
|
||||
*/
|
||||
sign_func_t get_algorithm_impl(const jwt_header& hdr) const noexcept;
|
||||
sign_func_t get_sign_algorithm_impl(const jwt_header& hdr) const noexcept;
|
||||
|
||||
/*!
|
||||
*/
|
||||
verify_func_t get_verify_algorithm_impl(const jwt_header& hdr) const noexcept;
|
||||
|
||||
private: // Data members;
|
||||
/// The key for creating the JWS
|
||||
|
@ -461,12 +462,11 @@ private: // Data Members
|
|||
jwt_header header_;
|
||||
/// JWT payload section
|
||||
jwt_payload payload_;
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
*/
|
||||
void jwt_decode(string_view encoded_str, string_view key, bool validate=true);
|
||||
void jwt_decode(const string_view encoded_str, const string_view key, bool validate=true);
|
||||
|
||||
|
||||
} // END namespace jwt
|
||||
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue