+
+
+
4#ifndef JWT_DISABLE_PICOJSON
+
5#ifndef PICOJSON_USE_INT64
+
6#define PICOJSON_USE_INT64
+
+
8#include "picojson/picojson.h"
+
+
+
11#ifndef JWT_DISABLE_BASE64
+
+
+
+
15#include <openssl/ec.h>
+
16#include <openssl/ecdsa.h>
+
17#include <openssl/err.h>
+
18#include <openssl/evp.h>
+
19#include <openssl/hmac.h>
+
20#include <openssl/pem.h>
+
21#include <openssl/rsa.h>
+
22#include <openssl/ssl.h>
+
+
+
+
+
+
+
+
+
+
+
+
34#include <system_error>
+
+
36#include <unordered_map>
+
+
+
+
40#if __cplusplus >= 201402L
+
+
42#if __has_include(<experimental/type_traits>)
+
43#include <experimental/type_traits>
+
+
+
+
+
48#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
49#define JWT_OPENSSL_3_0
+
50#include <openssl/param_build.h>
+
51#elif OPENSSL_VERSION_NUMBER >= 0x10101000L
+
52#define JWT_OPENSSL_1_1_1
+
53#elif OPENSSL_VERSION_NUMBER >= 0x10100000L
+
54#define JWT_OPENSSL_1_1_0
+
55#elif OPENSSL_VERSION_NUMBER >= 0x10000000L
+
56#define JWT_OPENSSL_1_0_0
+
+
+
59#if defined(LIBRESSL_VERSION_NUMBER)
+
60#if LIBRESSL_VERSION_NUMBER >= 0x3050300fL
+
61#define JWT_OPENSSL_1_1_0
+
+
63#define JWT_OPENSSL_1_0_0
+
+
+
+
67#if defined(LIBWOLFSSL_VERSION_HEX)
+
68#define JWT_OPENSSL_1_1_1
+
+
+
71#ifndef JWT_CLAIM_EXPLICIT
+
72#define JWT_CLAIM_EXPLICIT explicit
+
+
+
+
86 using date = std::chrono::system_clock::time_point;
+
+
+
+
+
+
93 using system_error::system_error;
+
+
+
+
+
96 using system_error::system_error;
+
+
+
+
+
99 using system_error::system_error;
+
+
+
+
+
102 using system_error::system_error;
+
+
+
+
+
105 using system_error::system_error;
+
+
+
+
+
+
112 cert_load_failed = 10,
+
+
+
+
116 convert_to_pem_failed,
+
+
+
119 create_mem_bio_failed,
+
+
+
122 create_context_failed
+
+
+
+
+
128 class rsa_error_cat :
public std::error_category {
+
+
130 const char* name()
const noexcept override {
return "rsa_error"; };
+
131 std::string message(
int ev)
const override {
+
+
133 case rsa_error::ok:
return "no error";
+
134 case rsa_error::cert_load_failed:
return "error loading cert into memory";
+
135 case rsa_error::get_key_failed:
return "error getting key from certificate";
+
136 case rsa_error::write_key_failed:
return "error writing key data in PEM format";
+
137 case rsa_error::write_cert_failed:
return "error writing cert data in PEM format";
+
138 case rsa_error::convert_to_pem_failed:
return "failed to convert key to pem";
+
139 case rsa_error::load_key_bio_write:
return "failed to load key: bio write failed";
+
140 case rsa_error::load_key_bio_read:
return "failed to load key: bio read failed";
+
141 case rsa_error::create_mem_bio_failed:
return "failed to create memory bio";
+
142 case rsa_error::no_key_provided:
return "at least one of public or private key need to be present";
+
143 case rsa_error::set_rsa_failed:
return "set modulus and exponent to RSA failed";
+
144 case rsa_error::create_context_failed:
return "failed to create context";
+
145 default:
return "unknown RSA error";
+
+
+
+
149 static rsa_error_cat cat;
+
+
+
+
+
+
+
+
161 load_key_bio_write = 10,
+
+
163 create_mem_bio_failed,
+
+
+
+
167 create_context_failed,
+
+
+
+
+
172 convert_to_pem_failed,
+
+
+
+
+
+
+
180 class ecdsa_error_cat :
public std::error_category {
+
+
182 const char* name()
const noexcept override {
return "ecdsa_error"; };
+
183 std::string message(
int ev)
const override {
+
+
185 case ecdsa_error::ok:
return "no error";
+
186 case ecdsa_error::load_key_bio_write:
return "failed to load key: bio write failed";
+
187 case ecdsa_error::load_key_bio_read:
return "failed to load key: bio read failed";
+
188 case ecdsa_error::create_mem_bio_failed:
return "failed to create memory bio";
+
189 case ecdsa_error::no_key_provided:
+
190 return "at least one of public or private key need to be present";
+
191 case ecdsa_error::invalid_key_size:
return "invalid key size";
+
192 case ecdsa_error::invalid_key:
return "invalid key";
+
193 case ecdsa_error::create_context_failed:
return "failed to create context";
+
194 case ecdsa_error::cert_load_failed:
return "error loading cert into memory";
+
195 case ecdsa_error::get_key_failed:
return "error getting key from certificate";
+
196 case ecdsa_error::write_key_failed:
return "error writing key data in PEM format";
+
197 case ecdsa_error::write_cert_failed:
return "error writing cert data in PEM format";
+
198 case ecdsa_error::convert_to_pem_failed:
return "failed to convert key to pem";
+
199 case ecdsa_error::unknown_curve:
return "unknown curve";
+
200 case ecdsa_error::set_ecdsa_failed:
return "set parameters to ECDSA failed";
+
201 default:
return "unknown ECDSA error";
+
+
+
+
205 static ecdsa_error_cat cat;
+
+
+
+
+
+
+
+
+
218 invalid_signature = 10,
+
219 create_context_failed,
+
+
+
+
+
224 set_rsa_pss_saltlen_failed,
+
225 signature_encoding_failed
+
+
+
+
+
231 class verification_error_cat :
public std::error_category {
+
+
233 const char* name()
const noexcept override {
return "signature_verification_error"; };
+
234 std::string message(
int ev)
const override {
+
+
236 case signature_verification_error::ok:
return "no error";
+
237 case signature_verification_error::invalid_signature:
return "invalid signature";
+
238 case signature_verification_error::create_context_failed:
+
239 return "failed to verify signature: could not create context";
+
240 case signature_verification_error::verifyinit_failed:
+
241 return "failed to verify signature: VerifyInit failed";
+
242 case signature_verification_error::verifyupdate_failed:
+
243 return "failed to verify signature: VerifyUpdate failed";
+
244 case signature_verification_error::verifyfinal_failed:
+
245 return "failed to verify signature: VerifyFinal failed";
+
246 case signature_verification_error::get_key_failed:
+
247 return "failed to verify signature: Could not get key";
+
248 case signature_verification_error::set_rsa_pss_saltlen_failed:
+
249 return "failed to verify signature: EVP_PKEY_CTX_set_rsa_pss_saltlen failed";
+
250 case signature_verification_error::signature_encoding_failed:
+
251 return "failed to verify signature: i2d_ECDSA_SIG failed";
+
252 default:
return "unknown signature verification error";
+
+
+
+
256 static verification_error_cat cat;
+
+
+
+
+
+
+
+
+
+
272 create_context_failed,
+
+
+
+
276 ecdsa_do_sign_failed,
+
+
+
+
+
281 rsa_private_encrypt_failed,
+
+
283 set_rsa_pss_saltlen_failed,
+
284 signature_decoding_failed
+
+
+
+
+
290 class signature_generation_error_cat :
public std::error_category {
+
+
292 const char* name()
const noexcept override {
return "signature_generation_error"; };
+
293 std::string message(
int ev)
const override {
+
+
295 case signature_generation_error::ok:
return "no error";
+
296 case signature_generation_error::hmac_failed:
return "hmac failed";
+
297 case signature_generation_error::create_context_failed:
+
298 return "failed to create signature: could not create context";
+
299 case signature_generation_error::signinit_failed:
+
300 return "failed to create signature: SignInit failed";
+
301 case signature_generation_error::signupdate_failed:
+
302 return "failed to create signature: SignUpdate failed";
+
303 case signature_generation_error::signfinal_failed:
+
304 return "failed to create signature: SignFinal failed";
+
305 case signature_generation_error::ecdsa_do_sign_failed:
return "failed to generate ecdsa signature";
+
306 case signature_generation_error::digestinit_failed:
+
307 return "failed to create signature: DigestInit failed";
+
308 case signature_generation_error::digestupdate_failed:
+
309 return "failed to create signature: DigestUpdate failed";
+
310 case signature_generation_error::digestfinal_failed:
+
311 return "failed to create signature: DigestFinal failed";
+
312 case signature_generation_error::rsa_padding_failed:
+
313 return "failed to create signature: EVP_PKEY_CTX_set_rsa_padding failed";
+
314 case signature_generation_error::rsa_private_encrypt_failed:
+
315 return "failed to create signature: RSA_private_encrypt failed";
+
316 case signature_generation_error::get_key_failed:
+
317 return "failed to generate signature: Could not get key";
+
318 case signature_generation_error::set_rsa_pss_saltlen_failed:
+
319 return "failed to create signature: EVP_PKEY_CTX_set_rsa_pss_saltlen failed";
+
320 case signature_generation_error::signature_decoding_failed:
+
321 return "failed to create signature: d2i_ECDSA_SIG failed";
+
322 default:
return "unknown signature generation error";
+
+
+
+
326 static signature_generation_error_cat cat = {};
+
+
+
+
+
+
+
+
+
341 wrong_algorithm = 10,
+
+
343 claim_type_missmatch,
+
344 claim_value_missmatch,
+
+
+
+
+
+
+
352 class token_verification_error_cat :
public std::error_category {
+
+
354 const char* name()
const noexcept override {
return "token_verification_error"; };
+
355 std::string message(
int ev)
const override {
+
+
357 case token_verification_error::ok:
return "no error";
+
358 case token_verification_error::wrong_algorithm:
return "wrong algorithm";
+
359 case token_verification_error::missing_claim:
return "decoded JWT is missing required claim(s)";
+
360 case token_verification_error::claim_type_missmatch:
+
361 return "claim type does not match expected type";
+
362 case token_verification_error::claim_value_missmatch:
+
363 return "claim value does not match expected value";
+
364 case token_verification_error::token_expired:
return "token expired";
+
365 case token_verification_error::audience_missmatch:
+
366 return "token doesn't contain the required audience";
+
367 default:
return "unknown token verification error";
+
+
+
+
371 static token_verification_error_cat cat = {};
+
+
+
+
+
+
+
+
+
+
+
+
398 struct is_error_code_enum<
jwt::error::rsa_error> : true_type {};
+
+
400 struct is_error_code_enum<
jwt::error::ecdsa_error> : true_type {};
+
+
402 struct is_error_code_enum<
jwt::error::signature_verification_error> : true_type {};
+
+
404 struct is_error_code_enum<
jwt::error::signature_generation_error> : true_type {};
+
+
406 struct is_error_code_enum<
jwt::error::token_verification_error> : true_type {};
+
+
+
+
+
+
+
+
+
+
431#ifdef JWT_OPENSSL_1_0_0
+
436 explicit evp_pkey_handle(EVP_PKEY* key) { m_key = std::shared_ptr<EVP_PKEY>(key, EVP_PKEY_free); }
+
+
438 EVP_PKEY* get() const noexcept {
return m_key.get(); }
+
439 bool operator!() const noexcept {
return m_key ==
nullptr; }
+
440 explicit operator bool() const noexcept {
return m_key !=
nullptr; }
+
+
+
443 std::shared_ptr<EVP_PKEY> m_key{
nullptr};
+
+
+
+
451 if (m_key !=
nullptr && EVP_PKEY_up_ref(m_key) != 1)
throw std::runtime_error(
"EVP_PKEY_up_ref failed");
+
+
+
454#if __cplusplus >= 201402L
+
+
+
+
458 : m_key{other.m_key} {
+
459 other.m_key =
nullptr;
+
+
+
462 if (&other ==
this)
return *
this;
+
463 decrement_ref_count(m_key);
+
+
465 increment_ref_count(m_key);
+
+
+
+
469 if (&other ==
this)
return *
this;
+
470 decrement_ref_count(m_key);
+
+
472 other.m_key =
nullptr;
+
+
+
+
476 decrement_ref_count(m_key);
+
+
478 increment_ref_count(m_key);
+
+
+
481 ~evp_pkey_handle() noexcept { decrement_ref_count(m_key); }
+
+
483 EVP_PKEY* get() const noexcept {
return m_key; }
+
484 bool operator!() const noexcept {
return m_key ==
nullptr; }
+
485 explicit operator bool() const noexcept {
return m_key !=
nullptr; }
+
+
+
488 EVP_PKEY* m_key{
nullptr};
+
+
490 static void increment_ref_count(EVP_PKEY* key) {
+
491 if (key !=
nullptr && EVP_PKEY_up_ref(key) != 1)
throw std::runtime_error(
"EVP_PKEY_up_ref failed");
+
+
493 static void decrement_ref_count(EVP_PKEY* key)
noexcept {
+
494 if (key !=
nullptr) EVP_PKEY_free(key);
+
+
+
+
+
+
499 inline std::unique_ptr<BIO,
decltype(&BIO_free_all)> make_mem_buf_bio() {
+
500 return std::unique_ptr<BIO, decltype(&BIO_free_all)>(BIO_new(BIO_s_mem()), BIO_free_all);
+
+
+
503 inline std::unique_ptr<BIO,
decltype(&BIO_free_all)> make_mem_buf_bio(
const std::string& data) {
+
504 return std::unique_ptr<BIO, decltype(&BIO_free_all)>(
+
505#
if OPENSSL_VERSION_NUMBER <= 0x10100003L
+
506 BIO_new_mem_buf(
const_cast<char*
>(data.data()),
static_cast<int>(data.size())), BIO_free_all
+
+
508 BIO_new_mem_buf(data.data(),
static_cast<int>(data.size())), BIO_free_all
+
+
+
+
+
513 template<
typename error_category = error::rsa_error>
+
514 std::string write_bio_to_string(std::unique_ptr<BIO,
decltype(&BIO_free_all)>& bio_out, std::error_code& ec) {
+
+
516 auto len = BIO_get_mem_data(bio_out.get(), &ptr);
+
517 if (len <= 0 || ptr ==
nullptr) {
+
518 ec = error_category::convert_to_pem_failed;
+
+
+
521 return {ptr,
static_cast<size_t>(len)};
+
+
+
524 inline std::unique_ptr<EVP_MD_CTX, void (*)(EVP_MD_CTX*)> make_evp_md_ctx() {
+
+
526#ifdef JWT_OPENSSL_1_0_0
+
527 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)>(EVP_MD_CTX_create(), &EVP_MD_CTX_destroy);
+
+
529 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)>(EVP_MD_CTX_new(), &EVP_MD_CTX_free);
+
+
+
+
541 template<
typename error_category = error::rsa_error>
+
+
+
+
544 auto certbio = make_mem_buf_bio(certstr);
+
545 auto keybio = make_mem_buf_bio();
+
546 if (!certbio || !keybio) {
+
547 ec = error_category::create_mem_bio_failed;
+
+
+
+
551 std::unique_ptr<X509,
decltype(&X509_free)> cert(
+
552 PEM_read_bio_X509(certbio.get(),
nullptr,
nullptr,
const_cast<char*
>(pw.c_str())), X509_free);
+
+
554 ec = error_category::cert_load_failed;
+
+
+
557 std::unique_ptr<EVP_PKEY,
decltype(&EVP_PKEY_free)> key(X509_get_pubkey(cert.get()), EVP_PKEY_free);
+
+
559 ec = error_category::get_key_failed;
+
+
+
562 if (PEM_write_bio_PUBKEY(keybio.get(), key.get()) == 0) {
+
563 ec = error_category::write_key_failed;
+
+
+
+
567 return write_bio_to_string<error_category>(keybio, ec);
+
+
+
+
578 template<
typename error_category = error::rsa_error>
+
+
+
+
581 auto res = extract_pubkey_from_cert<error_category>(certstr, pw, ec);
+
+
+
+
+
+
+
+
+
+
595 auto c_str =
reinterpret_cast<const unsigned char*
>(cert_der_str.c_str());
+
+
597 std::unique_ptr<X509,
decltype(&X509_free)> cert(
+
598 d2i_X509(NULL, &c_str,
static_cast<int>(cert_der_str.size())), X509_free);
+
599 auto certbio = make_mem_buf_bio();
+
600 if (!cert || !certbio) {
+
601 ec = error::rsa_error::create_mem_bio_failed;
+
+
+
+
605 if (!PEM_write_bio_X509(certbio.get(), cert.get())) {
+
606 ec = error::rsa_error::write_cert_failed;
+
+
+
+
610 return write_bio_to_string(certbio, ec);
+
+
+
+
627 template<
typename Decode>
+
+
+
629 std::error_code& ec) {
+
+
631 const auto decoded_str =
decode(cert_base64_der_str);
+
+
+
+
+
649 template<
typename Decode>
+
+
+
+
+
670#ifndef JWT_DISABLE_BASE64
+
+
+
681 auto decode = [](
const std::string& token) {
+
682 return base::decode<alphabet::base64>(base::pad<alphabet::base64>(token));
+
+
+
+
+
+
+
+
713 template<
typename error_category = error::rsa_error>
+
+
+
715 std::error_code& ec) {
+
+
717 auto pubkey_bio = make_mem_buf_bio();
+
+
719 ec = error_category::create_mem_bio_failed;
+
+
+
722 if (key.substr(0, 27) ==
"-----BEGIN CERTIFICATE-----") {
+
723 auto epkey = helper::extract_pubkey_from_cert<error_category>(key, password, ec);
+
+
725 const int len =
static_cast<int>(epkey.size());
+
726 if (BIO_write(pubkey_bio.get(), epkey.data(), len) != len) {
+
727 ec = error_category::load_key_bio_write;
+
+
+
+
731 const int len =
static_cast<int>(key.size());
+
732 if (BIO_write(pubkey_bio.get(), key.data(), len) != len) {
+
733 ec = error_category::load_key_bio_write;
+
+
+
+
+
+
739 pubkey_bio.get(),
nullptr,
nullptr,
+
740 (
void*)password.data()));
+
741 if (!pkey) ec = error_category::load_key_bio_read;
+
+
+
+
+
755 template<
typename error_category = error::rsa_error>
+
+
+
+
758 auto res = load_public_key_from_string<error_category>(key, password, ec);
+
+
+
+
+
+
771 template<
typename error_category = error::rsa_error>
+
+
+
773 std::error_code& ec) {
+
+
775 auto private_key_bio = make_mem_buf_bio();
+
776 if (!private_key_bio) {
+
777 ec = error_category::create_mem_bio_failed;
+
+
+
780 const int len =
static_cast<int>(key.size());
+
781 if (BIO_write(private_key_bio.get(), key.data(), len) != len) {
+
782 ec = error_category::load_key_bio_write;
+
+
+
+
786 PEM_read_bio_PrivateKey(private_key_bio.get(),
nullptr,
nullptr,
const_cast<char*
>(password.c_str())));
+
787 if (!pkey) ec = error_category::load_key_bio_read;
+
+
+
+
+
799 template<
typename error_category = error::rsa_error>
+
+
+
+
802 auto res = load_private_key_from_string<error_category>(key, password, ec);
+
+
+
+
+
+
+
+
819 std::error_code& ec) {
+
820 return load_public_key_from_string<error::ecdsa_error>(key, password, ec);
+
+
+
+
+
829#ifdef JWT_OPENSSL_1_0_0
+
+
+
+
+
+
+
+
+
837 std::string res(BN_num_bytes(bn),
'\0');
+
838 BN_bn2bin(bn, (
unsigned char*)res.data());
+
+
+
+
+
847 inline std::unique_ptr<BIGNUM,
decltype(&BN_free)>
raw2bn(
const std::string& raw, std::error_code& ec) {
+
+
849 BN_bin2bn(
reinterpret_cast<const unsigned char*
>(raw.data()),
static_cast<int>(raw.size()),
nullptr);
+
+
+
852 ec = error::rsa_error::set_rsa_failed;
+
853 return {
nullptr, BN_free};
+
+
855 return {bn, BN_free};
+
+
+
+
862 inline std::unique_ptr<BIGNUM,
decltype(&BN_free)>
raw2bn(
const std::string& raw) {
+
+
864 auto res =
raw2bn(raw, ec);
+
+
+
+
+
+
+
+
881 const std::string& password =
"") {
+
+
883 auto res = load_public_key_from_string<error::ecdsa_error>(key, password, ec);
+
+
+
+
+
+
+
+
898 std::error_code& ec) {
+
899 return load_private_key_from_string<error::ecdsa_error>(key, password, ec);
+
+
+
+
916 template<
typename Decode>
+
+
+
918 Decode
decode, std::error_code& ec) {
+
+
920 auto decoded_modulus =
decode(modulus);
+
921 auto decoded_exponent =
decode(exponent);
+
+
+
+
+
+
+
928#if defined(JWT_OPENSSL_3_0)
+
+
+
+
932 std::unique_ptr<OSSL_PARAM_BLD,
decltype(&OSSL_PARAM_BLD_free)> param_bld(OSSL_PARAM_BLD_new(),
+
933 OSSL_PARAM_BLD_free);
+
+
935 ec = error::rsa_error::create_context_failed;
+
+
+
+
939 if (OSSL_PARAM_BLD_push_BN(param_bld.get(),
"n", n.get()) != 1 ||
+
940 OSSL_PARAM_BLD_push_BN(param_bld.get(),
"e", e.get()) != 1) {
+
941 ec = error::rsa_error::set_rsa_failed;
+
+
+
+
945 std::unique_ptr<OSSL_PARAM,
decltype(&OSSL_PARAM_free)> params(OSSL_PARAM_BLD_to_param(param_bld.get()),
+
+
+
948 ec = error::rsa_error::set_rsa_failed;
+
+
+
+
952 std::unique_ptr<EVP_PKEY_CTX,
decltype(&EVP_PKEY_CTX_free)> ctx(
+
953 EVP_PKEY_CTX_new_from_name(
nullptr,
"RSA",
nullptr), EVP_PKEY_CTX_free);
+
+
955 ec = error::rsa_error::create_context_failed;
+
+
+
+
+
+
961 EVP_PKEY* pkey = NULL;
+
962 if (EVP_PKEY_fromdata_init(ctx.get()) <= 0 ||
+
963 EVP_PKEY_fromdata(ctx.get(), &pkey, EVP_PKEY_KEYPAIR, params.get()) <= 0) {
+
+
+
+
+
968 ec = error::rsa_error::cert_load_failed;
+
+
+
+
+
+
+
+
976 std::unique_ptr<RSA,
decltype(&RSA_free)> rsa(RSA_new(), RSA_free);
+
+
978#if defined(JWT_OPENSSL_1_1_1) || defined(JWT_OPENSSL_1_1_0)
+
+
+
981 if (RSA_set0_key(rsa.get(), n.get(), e.get(),
nullptr) == 1) {
+
+
+
+
+
+
+
988 ec = error::rsa_error::set_rsa_failed;
+
+
+
991#elif defined(JWT_OPENSSL_1_0_0)
+
992 rsa->e = e.release();
+
993 rsa->n = n.release();
+
+
+
+
+
998 auto pub_key_bio = make_mem_buf_bio();
+
+
1000 ec = error::rsa_error::create_mem_bio_failed;
+
+
+
+
1004 auto write_pem_to_bio =
+
1005#if defined(JWT_OPENSSL_3_0)
+
+
1007 &PEM_write_bio_PUBKEY;
+
+
1009 &PEM_write_bio_RSA_PUBKEY;
+
+
1011 if (write_pem_to_bio(pub_key_bio.get(), rsa.get()) != 1) {
+
1012 ec = error::rsa_error::load_key_bio_write;
+
+
+
+
1016 return write_bio_to_string<error::rsa_error>(pub_key_bio, ec);
+
+
+
+
1032 template<
typename Decode>
+
+
+
1041#ifndef JWT_DISABLE_BASE64
+
+
+
1053 const std::string& exponent, std::error_code& ec) {
+
1054 auto decode = [](
const std::string& token) {
+
1055 return base::decode<alphabet::base64url>(base::pad<alphabet::base64url>(token));
+
+
+
+
+
+
+
1069 const std::string& exponent) {
+
+
+
+
+
+
+
+
+
+
1086 const std::string& password =
"") {
+
+
1088 auto res = load_private_key_from_string<error::ecdsa_error>(key, password, ec);
+
+
+
+
+
+
1093#if defined(JWT_OPENSSL_3_0)
+
+
1102 inline std::string curve2group(
const std::string curve, std::error_code& ec) {
+
1103 if (curve ==
"P-256") {
+
1104 return "prime256v1";
+
1105 }
else if (curve ==
"P-384") {
+
+
1107 }
else if (curve ==
"P-521") {
+
+
+
1110 ec = jwt::error::ecdsa_error::unknown_curve;
+
+
+
+
+
+
+
+
1124 inline int curve2nid(
const std::string curve, std::error_code& ec) {
+
1125 if (curve ==
"P-256") {
+
1126 return NID_X9_62_prime256v1;
+
1127 }
else if (curve ==
"P-384") {
+
1128 return NID_secp384r1;
+
1129 }
else if (curve ==
"P-521") {
+
1130 return NID_secp521r1;
+
+
1132 ec = jwt::error::ecdsa_error::unknown_curve;
+
+
+
+
+
+
+
+
1154 template<
typename Decode>
+
+
+
1156 const std::string& y, Decode
decode, std::error_code& ec) {
+
+
1158 auto decoded_x =
decode(x);
+
1159 auto decoded_y =
decode(y);
+
+
1161#if defined(JWT_OPENSSL_3_0)
+
+
+
+
1165 std::unique_ptr<OSSL_PARAM_BLD,
decltype(&OSSL_PARAM_BLD_free)> param_bld(OSSL_PARAM_BLD_new(),
+
1166 OSSL_PARAM_BLD_free);
+
+
1168 ec = error::ecdsa_error::create_context_failed;
+
+
+
+
1172 std::string group = helper::curve2group(curve, ec);
+
+
+
+
1176 std::string pub = std::string(
"\x04").append(decoded_x).append(decoded_y);
+
+
1178 if (OSSL_PARAM_BLD_push_utf8_string(param_bld.get(),
"group", group.data(), group.size()) != 1 ||
+
1179 OSSL_PARAM_BLD_push_octet_string(param_bld.get(),
"pub", pub.data(), pub.size()) != 1) {
+
1180 ec = error::ecdsa_error::set_ecdsa_failed;
+
+
+
+
1184 std::unique_ptr<OSSL_PARAM,
decltype(&OSSL_PARAM_free)> params(OSSL_PARAM_BLD_to_param(param_bld.get()),
+
+
+
1187 ec = error::ecdsa_error::set_ecdsa_failed;
+
+
+
+
1191 std::unique_ptr<EVP_PKEY_CTX,
decltype(&EVP_PKEY_CTX_free)> ctx(
+
1192 EVP_PKEY_CTX_new_from_name(
nullptr,
"EC",
nullptr), EVP_PKEY_CTX_free);
+
+
1194 ec = error::ecdsa_error::create_context_failed;
+
+
+
+
+
+
1200 EVP_PKEY* pkey = NULL;
+
1201 if (EVP_PKEY_fromdata_init(ctx.get()) <= 0 ||
+
1202 EVP_PKEY_fromdata(ctx.get(), &pkey, EVP_PKEY_KEYPAIR, params.get()) <= 0) {
+
+
+
1205 EVP_PKEY_free(pkey);
+
+
1207 ec = error::ecdsa_error::cert_load_failed;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
1223 std::unique_ptr<EC_GROUP,
decltype(&EC_GROUP_free)> ecgroup(EC_GROUP_new_by_curve_name(nid), EC_GROUP_free);
+
+
1225 ec = error::ecdsa_error::set_ecdsa_failed;
+
+
+
+
1229 EC_GROUP_set_asn1_flag(ecgroup.get(), OPENSSL_EC_NAMED_CURVE);
+
+
1231 std::unique_ptr<EC_POINT,
decltype(&EC_POINT_free)> ecpoint(EC_POINT_new(ecgroup.get()), EC_POINT_free);
+
+
1233 EC_POINT_set_affine_coordinates_GFp(ecgroup.get(), ecpoint.get(), qx.get(), qy.get(),
nullptr) != 1) {
+
1234 ec = error::ecdsa_error::set_ecdsa_failed;
+
+
+
+
1238 std::unique_ptr<EC_KEY,
decltype(&EC_KEY_free)> ecdsa(EC_KEY_new(), EC_KEY_free);
+
1239 if (!ecdsa || EC_KEY_set_group(ecdsa.get(), ecgroup.get()) != 1 ||
+
1240 EC_KEY_set_public_key(ecdsa.get(), ecpoint.get()) != 1) {
+
1241 ec = error::ecdsa_error::set_ecdsa_failed;
+
+
+
+
+
+
1247 auto pub_key_bio = make_mem_buf_bio();
+
+
1249 ec = error::ecdsa_error::create_mem_bio_failed;
+
+
+
+
1253 auto write_pem_to_bio =
+
1254#if defined(JWT_OPENSSL_3_0)
+
+
1256 &PEM_write_bio_PUBKEY;
+
+
1258 &PEM_write_bio_EC_PUBKEY;
+
+
1260 if (write_pem_to_bio(pub_key_bio.get(), ecdsa.get()) != 1) {
+
1261 ec = error::ecdsa_error::load_key_bio_write;
+
+
+
+
1265 return write_bio_to_string<error::ecdsa_error>(pub_key_bio, ec);
+
+
+
+
1282 template<
typename Decode>
+
+
+
1284 const std::string& y, Decode
decode) {
+
+
+
+
+
+
+
+
1291#ifndef JWT_DISABLE_BASE64
+
+
+
1304 const std::string& y, std::error_code& ec) {
+
1305 auto decode = [](
const std::string& token) {
+
1306 return base::decode<alphabet::base64url>(base::pad<alphabet::base64url>(token));
+
+
+
+
+
+
+
1321 const std::string& y) {
+
+
+
+
+
+
+
+
+
+
+
+
1339 namespace algorithm {
+
+
+
+
1351 std::string
sign(
const std::string& , std::error_code& ec)
const {
+
+
+
+
+
+
1362 void verify(
const std::string& ,
const std::string& signature, std::error_code& ec)
const {
+
+
1364 if (!signature.empty()) { ec = error::signature_verification_error::invalid_signature; }
+
+
+
1367 std::string
name()
const {
return "none"; }
+
+
+
+
+
+
+
1381 : secret(std::move(key)), md(md), alg_name(std::move(
name)) {}
+
+
+
1389 std::string
sign(
const std::string& data, std::error_code& ec)
const {
+
+
1391 std::string res(
static_cast<size_t>(EVP_MAX_MD_SIZE),
'\0');
+
1392 auto len =
static_cast<unsigned int>(res.size());
+
1393 if (HMAC(md(), secret.data(),
static_cast<int>(secret.size()),
+
1394 reinterpret_cast<const unsigned char*
>(data.data()),
static_cast<int>(data.size()),
+
1395 (
unsigned char*)res.data(),
+
+
1397 ec = error::signature_generation_error::hmac_failed;
+
+
+
+
+
+
+
+
1410 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const {
+
+
1412 auto res =
sign(data, ec);
+
+
+
1415 bool matched =
true;
+
1416 for (
size_t i = 0; i < std::min<size_t>(res.size(), signature.size()); i++)
+
1417 if (res[i] != signature[i]) matched =
false;
+
1418 if (res.size() != signature.size()) matched =
false;
+
+
1420 ec = error::signature_verification_error::invalid_signature;
+
+
+
+
+
1429 std::string
name()
const {
return alg_name; }
+
+
+
1433 const std::string secret;
+
1435 const EVP_MD* (*md)();
+
1437 const std::string alg_name;
+
+
+
+
+
+
1453 rsa(
const std::string& public_key,
const std::string& private_key,
const std::string& public_key_password,
+
1454 const std::string& private_key_password,
const EVP_MD* (*md)(), std::string
name)
+
1455 : md(md), alg_name(std::move(
name)) {
+
1456 if (!private_key.empty()) {
+
+
1458 }
else if (!public_key.empty()) {
+
+
+
+
+
+
+
1469 std::string
sign(
const std::string& data, std::error_code& ec)
const {
+
+
1471 auto ctx = helper::make_evp_md_ctx();
+
+
1473 ec = error::signature_generation_error::create_context_failed;
+
+
+
1476 if (!EVP_SignInit(ctx.get(), md())) {
+
1477 ec = error::signature_generation_error::signinit_failed;
+
+
+
+
1481 std::string res(EVP_PKEY_size(pkey.get()),
'\0');
+
1482 unsigned int len = 0;
+
+
1484 if (!EVP_SignUpdate(ctx.get(), data.data(), data.size())) {
+
1485 ec = error::signature_generation_error::signupdate_failed;
+
+
+
1488 if (EVP_SignFinal(ctx.get(), (
unsigned char*)res.data(), &len, pkey.get()) == 0) {
+
1489 ec = error::signature_generation_error::signfinal_failed;
+
+
+
+
+
+
+
+
+
1503 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const {
+
+
1505 auto ctx = helper::make_evp_md_ctx();
+
+
1507 ec = error::signature_verification_error::create_context_failed;
+
+
+
1510 if (!EVP_VerifyInit(ctx.get(), md())) {
+
1511 ec = error::signature_verification_error::verifyinit_failed;
+
+
+
1514 if (!EVP_VerifyUpdate(ctx.get(), data.data(), data.size())) {
+
1515 ec = error::signature_verification_error::verifyupdate_failed;
+
+
+
1518 auto res = EVP_VerifyFinal(ctx.get(),
reinterpret_cast<const unsigned char*
>(signature.data()),
+
1519 static_cast<unsigned int>(signature.size()), pkey.get());
+
+
1521 ec = error::signature_verification_error::verifyfinal_failed;
+
+
+
+
+
1529 std::string
name()
const {
return alg_name; }
+
+
+
+
1535 const EVP_MD* (*md)();
+
1537 const std::string alg_name;
+
+
+
+
+
+
1554 ecdsa(
const std::string& public_key,
const std::string& private_key,
const std::string& public_key_password,
+
1555 const std::string& private_key_password,
const EVP_MD* (*md)(), std::string
name,
size_t siglen)
+
1556 : md(md), alg_name(std::move(
name)), signature_length(siglen) {
+
1557 if (!private_key.empty()) {
+
+
1559 check_private_key(pkey.get());
+
1560 }
else if (!public_key.empty()) {
+
+
1562 check_public_key(pkey.get());
+
+
+
+
+
+
1568 size_t keysize = EVP_PKEY_bits(pkey.get());
+
1569 if (keysize != signature_length * 4 && (signature_length != 132 || keysize != 521))
+
+
+
+
+
+
1579 std::string
sign(
const std::string& data, std::error_code& ec)
const {
+
+
1581 auto ctx = helper::make_evp_md_ctx();
+
+
1583 ec = error::signature_generation_error::create_context_failed;
+
+
+
1586 if (!EVP_DigestSignInit(ctx.get(),
nullptr, md(),
nullptr, pkey.get())) {
+
1587 ec = error::signature_generation_error::signinit_failed;
+
+
+
1590 if (!EVP_DigestUpdate(ctx.get(), data.data(), data.size())) {
+
1591 ec = error::signature_generation_error::digestupdate_failed;
+
+
+
+
+
1596 if (!EVP_DigestSignFinal(ctx.get(),
nullptr, &len)) {
+
1597 ec = error::signature_generation_error::signfinal_failed;
+
+
+
1600 std::string res(len,
'\0');
+
1601 if (!EVP_DigestSignFinal(ctx.get(), (
unsigned char*)res.data(), &len)) {
+
1602 ec = error::signature_generation_error::signfinal_failed;
+
+
+
+
+
1607 return der_to_p1363_signature(res, ec);
+
+
+
+
+
1616 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const {
+
+
1618 std::string der_signature = p1363_to_der_signature(signature, ec);
+
+
+
1621 auto ctx = helper::make_evp_md_ctx();
+
+
1623 ec = error::signature_verification_error::create_context_failed;
+
+
+
1626 if (!EVP_DigestVerifyInit(ctx.get(),
nullptr, md(),
nullptr, pkey.get())) {
+
1627 ec = error::signature_verification_error::verifyinit_failed;
+
+
+
1630 if (!EVP_DigestUpdate(ctx.get(), data.data(), data.size())) {
+
1631 ec = error::signature_verification_error::verifyupdate_failed;
+
+
+
+
1635#if OPENSSL_VERSION_NUMBER < 0x10002000L
+
1636 unsigned char* der_sig_data =
reinterpret_cast<unsigned char*
>(
const_cast<char*
>(der_signature.data()));
+
+
1638 const unsigned char* der_sig_data =
reinterpret_cast<const unsigned char*
>(der_signature.data());
+
+
+
1641 EVP_DigestVerifyFinal(ctx.get(), der_sig_data,
static_cast<unsigned int>(der_signature.length()));
+
+
1643 ec = error::signature_verification_error::invalid_signature;
+
+
+
+
1647 ec = error::signature_verification_error::verifyfinal_failed;
+
+
+
+
+
1655 std::string
name()
const {
return alg_name; }
+
+
+
1658 static void check_public_key(EVP_PKEY* pkey) {
+
1659#ifdef JWT_OPENSSL_3_0
+
1660 std::unique_ptr<EVP_PKEY_CTX,
decltype(&EVP_PKEY_CTX_free)> ctx(
+
1661 EVP_PKEY_CTX_new_from_pkey(
nullptr, pkey,
nullptr), EVP_PKEY_CTX_free);
+
+
1663 if (EVP_PKEY_public_check(ctx.get()) != 1) {
+
+
+
+
1667 std::unique_ptr<EC_KEY,
decltype(&EC_KEY_free)> eckey(EVP_PKEY_get1_EC_KEY(pkey), EC_KEY_free);
+
1668 if (!eckey) {
throw error::ecdsa_exception(error::ecdsa_error::invalid_key); }
+
1669 if (EC_KEY_check_key(eckey.get()) == 0)
throw error::ecdsa_exception(error::ecdsa_error::invalid_key);
+
+
+
+
1673 static void check_private_key(EVP_PKEY* pkey) {
+
1674#ifdef JWT_OPENSSL_3_0
+
1675 std::unique_ptr<EVP_PKEY_CTX,
decltype(&EVP_PKEY_CTX_free)> ctx(
+
1676 EVP_PKEY_CTX_new_from_pkey(
nullptr, pkey,
nullptr), EVP_PKEY_CTX_free);
+
1677 if (!ctx) {
throw error::ecdsa_exception(error::ecdsa_error::create_context_failed); }
+
1678 if (EVP_PKEY_private_check(ctx.get()) != 1) {
+
1679 throw error::ecdsa_exception(error::ecdsa_error::invalid_key);
+
+
+
1682 std::unique_ptr<EC_KEY,
decltype(&EC_KEY_free)> eckey(EVP_PKEY_get1_EC_KEY(pkey), EC_KEY_free);
+
1683 if (!eckey) {
throw error::ecdsa_exception(error::ecdsa_error::invalid_key); }
+
1684 if (EC_KEY_check_key(eckey.get()) == 0)
throw error::ecdsa_exception(error::ecdsa_error::invalid_key);
+
+
+
+
1688 std::string der_to_p1363_signature(
const std::string& der_signature, std::error_code& ec)
const {
+
1689 const unsigned char* possl_signature =
reinterpret_cast<const unsigned char*
>(der_signature.data());
+
1690 std::unique_ptr<ECDSA_SIG,
decltype(&ECDSA_SIG_free)> sig(
+
1691 d2i_ECDSA_SIG(
nullptr, &possl_signature,
static_cast<long>(der_signature.length())),
+
+
+
1694 ec = error::signature_generation_error::signature_decoding_failed;
+
+
+
+
1698#ifdef JWT_OPENSSL_1_0_0
+
+
+
+
+
+
1704 ECDSA_SIG_get0(sig.get(), &r, &s);
+
+
+
+
1708 if (rr.size() > signature_length / 2 || rs.size() > signature_length / 2)
+
1709 throw std::logic_error(
"bignum size exceeded expected length");
+
1710 rr.insert(0, signature_length / 2 - rr.size(),
'\0');
+
1711 rs.insert(0, signature_length / 2 - rs.size(),
'\0');
+
+
+
+
1715 std::string p1363_to_der_signature(
const std::string& signature, std::error_code& ec)
const {
+
+
1717 auto r =
helper::raw2bn(signature.substr(0, signature.size() / 2), ec);
+
+
1719 auto s =
helper::raw2bn(signature.substr(signature.size() / 2), ec);
+
+
+
+
1723#ifdef JWT_OPENSSL_1_0_0
+
+
+
+
+
+
1729 std::unique_ptr<ECDSA_SIG,
decltype(&ECDSA_SIG_free)> sig(ECDSA_SIG_new(), ECDSA_SIG_free);
+
+
1731 ec = error::signature_verification_error::create_context_failed;
+
+
+
1734 ECDSA_SIG_set0(sig.get(), r.release(), s.release());
+
+
+
+
1738 int length = i2d_ECDSA_SIG(psig,
nullptr);
+
+
1740 ec = error::signature_verification_error::signature_encoding_failed;
+
+
+
1743 std::string der_signature(length,
'\0');
+
1744 unsigned char* psbuffer = (
unsigned char*)der_signature.data();
+
1745 length = i2d_ECDSA_SIG(psig, &psbuffer);
+
+
1747 ec = error::signature_verification_error::signature_encoding_failed;
+
+
+
1750 der_signature.resize(length);
+
1751 return der_signature;
+
+
+
1755 helper::evp_pkey_handle pkey;
+
1757 const EVP_MD* (*md)();
+
1759 const std::string alg_name;
+
1761 const size_t signature_length;
+
+
+
+
1764#if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
+
+
+
+
1784 eddsa(
const std::string& public_key,
const std::string& private_key,
const std::string& public_key_password,
+
1785 const std::string& private_key_password, std::string
name)
+
1786 : alg_name(std::move(
name)) {
+
1787 if (!private_key.empty()) {
+
+
1789 }
else if (!public_key.empty()) {
+
+
+
+
+
+
+
1800 std::string
sign(
const std::string& data, std::error_code& ec)
const {
+
+
1802 auto ctx = helper::make_evp_md_ctx();
+
+
1804 ec = error::signature_generation_error::create_context_failed;
+
+
+
1807 if (!EVP_DigestSignInit(ctx.get(),
nullptr,
nullptr,
nullptr, pkey.get())) {
+
1808 ec = error::signature_generation_error::signinit_failed;
+
+
+
+
1812 size_t len = EVP_PKEY_size(pkey.get());
+
1813 std::string res(len,
'\0');
+
+
+
+
+
1818#if defined(LIBRESSL_VERSION_NUMBER) || defined(LIBWOLFSSL_VERSION_HEX)
+
+
1820 if (EVP_DigestSignUpdate(ctx.get(),
reinterpret_cast<const unsigned char*
>(data.data()), data.size()) !=
+
+
1822 std::cout << ERR_error_string(ERR_get_error(), NULL) << std::endl;
+
1823 ec = error::signature_generation_error::signupdate_failed;
+
+
+
1826 if (EVP_DigestSignFinal(ctx.get(),
reinterpret_cast<unsigned char*
>(&res[0]), &len) != 1) {
+
1827 ec = error::signature_generation_error::signfinal_failed;
+
+
+
+
1831 if (EVP_DigestSign(ctx.get(),
reinterpret_cast<unsigned char*
>(&res[0]), &len,
+
1832 reinterpret_cast<const unsigned char*
>(data.data()), data.size()) != 1) {
+
1833 ec = error::signature_generation_error::signfinal_failed;
+
+
+
+
+
+
+
+
+
+
+
1848 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const {
+
+
1850 auto ctx = helper::make_evp_md_ctx();
+
+
1852 ec = error::signature_verification_error::create_context_failed;
+
+
+
1855 if (!EVP_DigestVerifyInit(ctx.get(),
nullptr,
nullptr,
nullptr, pkey.get())) {
+
1856 ec = error::signature_verification_error::verifyinit_failed;
+
+
+
+
+
+
1862#if defined(LIBRESSL_VERSION_NUMBER) || defined(LIBWOLFSSL_VERSION_HEX)
+
1863 if (EVP_DigestVerifyUpdate(ctx.get(),
reinterpret_cast<const unsigned char*
>(data.data()),
+
1864 data.size()) != 1) {
+
1865 ec = error::signature_verification_error::verifyupdate_failed;
+
+
+
1868 if (EVP_DigestVerifyFinal(ctx.get(),
reinterpret_cast<const unsigned char*
>(signature.data()),
+
1869 signature.size()) != 1) {
+
1870 ec = error::signature_verification_error::verifyfinal_failed;
+
+
+
+
1874 auto res = EVP_DigestVerify(ctx.get(),
reinterpret_cast<const unsigned char*
>(signature.data()),
+
1875 signature.size(),
reinterpret_cast<const unsigned char*
>(data.data()),
+
+
+
1878 ec = error::signature_verification_error::verifyfinal_failed;
+
+
+
+
+
+
1887 std::string
name()
const {
return alg_name; }
+
+
+
+
1893 const std::string alg_name;
+
+
+
+
+
+
+
1909 pss(
const std::string& public_key,
const std::string& private_key,
const std::string& public_key_password,
+
1910 const std::string& private_key_password,
const EVP_MD* (*md)(), std::string
name)
+
1911 : md(md), alg_name(std::move(
name)) {
+
1912 if (!private_key.empty()) {
+
+
1914 }
else if (!public_key.empty()) {
+
+
+
+
+
+
+
+
1926 std::string
sign(
const std::string& data, std::error_code& ec)
const {
+
+
1928 auto md_ctx = helper::make_evp_md_ctx();
+
+
1930 ec = error::signature_generation_error::create_context_failed;
+
+
+
1933 EVP_PKEY_CTX* ctx =
nullptr;
+
1934 if (EVP_DigestSignInit(md_ctx.get(), &ctx, md(),
nullptr, pkey.get()) != 1) {
+
1935 ec = error::signature_generation_error::signinit_failed;
+
+
+
1938 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
+
1939 ec = error::signature_generation_error::rsa_padding_failed;
+
+
+
+
+
1944#ifndef LIBWOLFSSL_VERSION_HEX
+
1945 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0) {
+
1946 ec = error::signature_generation_error::set_rsa_pss_saltlen_failed;
+
+
+
+
1950 if (EVP_DigestUpdate(md_ctx.get(), data.data(), data.size()) != 1) {
+
1951 ec = error::signature_generation_error::digestupdate_failed;
+
+
+
+
1955 size_t size = EVP_PKEY_size(pkey.get());
+
1956 std::string res(size, 0x00);
+
1957 if (EVP_DigestSignFinal(
+
+
1959 (
unsigned char*)res.data(),
+
+
1961 ec = error::signature_generation_error::signfinal_failed;
+
+
+
+
+
+
+
+
+
1974 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const {
+
+
+
1977 auto md_ctx = helper::make_evp_md_ctx();
+
+
1979 ec = error::signature_verification_error::create_context_failed;
+
+
+
1982 EVP_PKEY_CTX* ctx =
nullptr;
+
1983 if (EVP_DigestVerifyInit(md_ctx.get(), &ctx, md(),
nullptr, pkey.get()) != 1) {
+
1984 ec = error::signature_verification_error::verifyinit_failed;
+
+
+
1987 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
+
1988 ec = error::signature_generation_error::rsa_padding_failed;
+
+
+
+
+
1993#ifndef LIBWOLFSSL_VERSION_HEX
+
1994 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0) {
+
1995 ec = error::signature_verification_error::set_rsa_pss_saltlen_failed;
+
+
+
+
1999 if (EVP_DigestUpdate(md_ctx.get(), data.data(), data.size()) != 1) {
+
2000 ec = error::signature_verification_error::verifyupdate_failed;
+
+
+
+
2004 if (EVP_DigestVerifyFinal(md_ctx.get(), (
unsigned char*)signature.data(), signature.size()) <= 0) {
+
2005 ec = error::signature_verification_error::verifyfinal_failed;
+
+
+
+
+
2013 std::string
name()
const {
return alg_name; }
+
+
+
+
2019 const EVP_MD* (*md)();
+
2021 const std::string alg_name;
+
+
+
+
+
+
2032 explicit hs256(std::string key) :
hmacsha(std::move(key), EVP_sha256,
"HS256") {}
+
+
+
+
+
2042 explicit hs384(std::string key) :
hmacsha(std::move(key), EVP_sha384,
"HS384") {}
+
+
+
+
+
2052 explicit hs512(std::string key) :
hmacsha(std::move(key), EVP_sha512,
"HS512") {}
+
+
+
+
+
+
2068 explicit rs256(
const std::string& public_key,
const std::string& private_key =
"",
+
2069 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2070 :
rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
"RS256") {}
+
+
+
+
+
+
+
2083 explicit rs384(
const std::string& public_key,
const std::string& private_key =
"",
+
2084 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2085 :
rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384,
"RS384") {}
+
+
+
+
+
+
+
2098 explicit rs512(
const std::string& public_key,
const std::string& private_key =
"",
+
2099 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2100 :
rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512,
"RS512") {}
+
+
+
+
+
+
+
2115 explicit es256(
const std::string& public_key,
const std::string& private_key =
"",
+
2116 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2117 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
"ES256", 64) {}
+
+
+
+
+
+
+
2132 explicit es384(
const std::string& public_key,
const std::string& private_key =
"",
+
2133 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2134 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384,
"ES384", 96) {}
+
+
+
+
+
+
+
2149 explicit es512(
const std::string& public_key,
const std::string& private_key =
"",
+
2150 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2151 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512,
"ES512", 132) {}
+
+
+
+
+
+
+
2165 explicit es256k(
const std::string& public_key,
const std::string& private_key =
"",
+
2166 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2167 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
"ES256K", 64) {}
+
+
+
+
+
2170#if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
+
+
+
+
2188 explicit ed25519(
const std::string& public_key,
const std::string& private_key =
"",
+
2189 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2190 :
eddsa(public_key, private_key, public_key_password, private_key_password,
"EdDSA") {}
+
+
+
+
+
+
+
+
2210 explicit ed448(
const std::string& public_key,
const std::string& private_key =
"",
+
2211 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2212 :
eddsa(public_key, private_key, public_key_password, private_key_password,
"EdDSA") {}
+
+
+
+
+
+
+
+
+
2227 explicit ps256(
const std::string& public_key,
const std::string& private_key =
"",
+
2228 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2229 :
pss(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
"PS256") {}
+
+
+
+
+
+
+
2242 explicit ps384(
const std::string& public_key,
const std::string& private_key =
"",
+
2243 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2244 :
pss(public_key, private_key, public_key_password, private_key_password, EVP_sha384,
"PS384") {}
+
+
+
+
+
+
+
2257 explicit ps512(
const std::string& public_key,
const std::string& private_key =
"",
+
2258 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
+
2259 :
pss(public_key, private_key, public_key_password, private_key_password, EVP_sha512,
"PS512") {}
+
+
+
+
+
+
+
+
+
2274 enum class type { boolean, integer, number, string, array,
object };
+
+
+
+
+
2278#ifdef __cpp_lib_void_t
+
2279 template<
typename... Ts>
+
2280 using void_t = std::void_t<Ts...>;
+
+
+
2283 template<
typename... Ts>
+
+
+
+
+
2288 template<
typename... Ts>
+
2289 using void_t =
typename make_void<Ts...>::type;
+
+
+
2292#ifdef __cpp_lib_experimental_detect
+
2293 template<
template<
typename...>
class _Op,
typename... _Args>
+
2294 using is_detected = std::experimental::is_detected<_Op, _Args...>;
+
+
+
2297 nonesuch() =
delete;
+
2298 ~nonesuch() =
delete;
+
2299 nonesuch(nonesuch
const&) =
delete;
+
2300 nonesuch(nonesuch
const&&) =
delete;
+
2301 void operator=(nonesuch
const&) =
delete;
+
2302 void operator=(nonesuch&&) =
delete;
+
+
+
+
2306 template<
class Default,
class AlwaysVoid,
template<
class...>
class Op,
class... Args>
+
+
2308 using value = std::false_type;
+
2309 using type = Default;
+
+
+
2312 template<
class Default,
template<
class...>
class Op,
class... Args>
+
2313 struct detector<Default, void_t<Op<Args...>>, Op, Args...> {
+
2314 using value = std::true_type;
+
2315 using type = Op<Args...>;
+
+
+
2318 template<
template<
class...>
class Op,
class... Args>
+
2319 using is_detected =
typename detector<nonesuch, void, Op, Args...>::value;
+
+
+
2322 template<
typename T,
typename Signature>
+
2323 using is_signature =
typename std::is_same<T, Signature>;
+
+
2325 template<
typename traits_type,
template<
typename...>
class Op,
typename Signature>
+
2326 struct is_function_signature_detected {
+
2327 using type = Op<traits_type>;
+
2328 static constexpr auto value = is_detected<Op, traits_type>::value && std::is_function<type>::value &&
+
2329 is_signature<type, Signature>::value;
+
+
+
2332 template<
typename traits_type,
typename value_type>
+
2333 struct supports_get_type {
+
2334 template<
typename T>
+
2335 using get_type_t =
decltype(T::get_type);
+
+
2337 static constexpr auto value =
+
2338 is_function_signature_detected<traits_type, get_type_t, json::type(
const value_type&)>::value;
+
+
+
2341 static_assert(value,
"traits implementation must provide `jwt::json::type get_type(const value_type&)`");
+
+
+
2344#define JWT_CPP_JSON_TYPE_TYPE(TYPE) json_##TYPE_type
+
2345#define JWT_CPP_AS_TYPE_T(TYPE) as_##TYPE_t
+
2346#define JWT_CPP_SUPPORTS_AS(TYPE) \
+
2347 template<typename traits_type, typename value_type, typename JWT_CPP_JSON_TYPE_TYPE(TYPE)> \
+
2348 struct supports_as_##TYPE { \
+
2349 template<typename T> \
+
2350 using JWT_CPP_AS_TYPE_T(TYPE) = decltype(T::as_##TYPE); \
+
+
2352 static constexpr auto value = \
+
2353 is_function_signature_detected<traits_type, JWT_CPP_AS_TYPE_T(TYPE), \
+
2354 JWT_CPP_JSON_TYPE_TYPE(TYPE)(const value_type&)>::value; \
+
+
2356 static_assert(value, "traits implementation must provide `" #TYPE "_type as_" #TYPE "(const value_type&)`"); \
+
+
+
2359 JWT_CPP_SUPPORTS_AS(
object);
+
2360 JWT_CPP_SUPPORTS_AS(array);
+
2361 JWT_CPP_SUPPORTS_AS(
string);
+
2362 JWT_CPP_SUPPORTS_AS(number);
+
2363 JWT_CPP_SUPPORTS_AS(integer);
+
2364 JWT_CPP_SUPPORTS_AS(
boolean);
+
+
2366#undef JWT_CPP_JSON_TYPE_TYPE
+
2367#undef JWT_CPP_AS_TYPE_T
+
2368#undef JWT_CPP_SUPPORTS_AS
+
+
2370 template<
typename traits>
+
2371 struct is_valid_traits {
+
2372 static constexpr auto value =
+
2373 supports_get_type<traits, typename traits::value_type>::value &&
+
2374 supports_as_object<traits, typename traits::value_type, typename traits::object_type>::value &&
+
2375 supports_as_array<traits, typename traits::value_type, typename traits::array_type>::value &&
+
2376 supports_as_string<traits, typename traits::value_type, typename traits::string_type>::value &&
+
2377 supports_as_number<traits, typename traits::value_type, typename traits::number_type>::value &&
+
2378 supports_as_integer<traits, typename traits::value_type, typename traits::integer_type>::value &&
+
2379 supports_as_boolean<traits, typename traits::value_type, typename traits::boolean_type>::value;
+
+
+
2382 template<
typename value_type>
+
2383 struct is_valid_json_value {
+
2384 static constexpr auto value =
+
2385 std::is_default_constructible<value_type>::value &&
+
2386 std::is_constructible<value_type, const value_type&>::value &&
+
2387 std::is_move_constructible<value_type>::value && std::is_assignable<value_type, value_type>::value &&
+
2388 std::is_copy_assignable<value_type>::value && std::is_move_assignable<value_type>::value;
+
+
+
+
+
2393 template<
typename T,
typename =
void>
+
2394 struct is_iterable : std::false_type {};
+
+
2396 template<
typename T>
+
2397 struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>())),
+
2398#if __cplusplus > 201402L
+
2399 decltype(std::cbegin(std::declval<T>())), decltype(std::cend(std::declval<T>()))
+
+
2401 decltype(std::begin(std::declval<const T>())),
+
2402 decltype(std::end(std::declval<const T>()))
+
+
2404 >> : std::true_type {
+
+
+
2407#if __cplusplus > 201703L
+
2408 template<
typename T>
+
2409 inline constexpr bool is_iterable_v = is_iterable<T>::value;
+
+
+
2412 template<
typename object_type,
typename string_type>
+
2413 using is_count_signature =
typename std::is_integral<decltype(std::declval<const object_type>().count(
+
2414 std::declval<const string_type>()))>;
+
+
2416 template<
typename object_type,
typename string_type,
typename =
void>
+
2417 struct is_subcription_operator_signature : std::false_type {};
+
+
2419 template<
typename object_type,
typename string_type>
+
2420 struct is_subcription_operator_signature<
+
2421 object_type, string_type,
+
2422 void_t<decltype(std::declval<object_type>().operator[](std::declval<string_type>()))>> : std::true_type {
+
+
+
+
2426 "object_type must implementate the subscription operator '[]' taking string_type as an argument");
+
+
+
2429 template<
typename object_type,
typename value_type,
typename string_type>
+
2430 using is_at_const_signature =
+
2431 typename std::is_same<decltype(std::declval<const object_type>().at(std::declval<const string_type>())),
+
+
+
2434 template<
typename value_type,
typename string_type,
typename object_type>
+
2435 struct is_valid_json_object {
+
2436 template<
typename T>
+
2437 using mapped_type_t =
typename T::mapped_type;
+
2438 template<
typename T>
+
2439 using key_type_t =
typename T::key_type;
+
2440 template<
typename T>
+
2441 using iterator_t =
typename T::iterator;
+
2442 template<
typename T>
+
2443 using const_iterator_t =
typename T::const_iterator;
+
+
2445 static constexpr auto value =
+
2446 std::is_constructible<value_type, object_type>::value &&
+
2447 is_detected<mapped_type_t, object_type>::value &&
+
2448 std::is_same<typename object_type::mapped_type, value_type>::value &&
+
2449 is_detected<key_type_t, object_type>::value &&
+
2450 (std::is_same<typename object_type::key_type, string_type>::value ||
+
2451 std::is_constructible<typename object_type::key_type, string_type>::value) &&
+
2452 is_detected<iterator_t, object_type>::value && is_detected<const_iterator_t, object_type>::value &&
+
2453 is_iterable<object_type>::value && is_count_signature<object_type, string_type>::value &&
+
2454 is_subcription_operator_signature<object_type, string_type>::value &&
+
2455 is_at_const_signature<object_type, value_type, string_type>::value;
+
+
+
2458 template<
typename value_type,
typename array_type>
+
2459 struct is_valid_json_array {
+
2460 template<
typename T>
+
2461 using value_type_t =
typename T::value_type;
+
2462 using front_base_type =
typename std::decay<decltype(std::declval<array_type>().front())>::type;
+
+
2464 static constexpr auto value = std::is_constructible<value_type, array_type>::value &&
+
2465 is_iterable<array_type>::value &&
+
2466 is_detected<value_type_t, array_type>::value &&
+
2467 std::is_same<typename array_type::value_type, value_type>::value &&
+
2468 std::is_same<front_base_type, value_type>::value;
+
+
+
2471 template<
typename string_type,
typename integer_type>
+
2472 using is_substr_start_end_index_signature =
+
2473 typename std::is_same<decltype(std::declval<string_type>().substr(std::declval<integer_type>(),
+
2474 std::declval<integer_type>())),
+
+
+
2477 template<
typename string_type,
typename integer_type>
+
2478 using is_substr_start_index_signature =
+
2479 typename std::is_same<decltype(std::declval<string_type>().substr(std::declval<integer_type>())),
+
+
+
2482 template<
typename string_type>
+
2483 using is_std_operate_plus_signature =
+
2484 typename std::is_same<decltype(std::operator+(std::declval<string_type>(), std::declval<string_type>())),
+
+
+
2487 template<
typename value_type,
typename string_type,
typename integer_type>
+
2488 struct is_valid_json_string {
+
2489 static constexpr auto substr = is_substr_start_end_index_signature<string_type, integer_type>::value &&
+
2490 is_substr_start_index_signature<string_type, integer_type>::value;
+
2491 static_assert(substr,
"string_type must have a substr method taking only a start index and an overload "
+
2492 "taking a start and end index, both must return a string_type");
+
+
2494 static constexpr auto operator_plus = is_std_operate_plus_signature<string_type>::value;
+
2495 static_assert(operator_plus,
+
2496 "string_type must have a '+' operator implemented which returns the concatenated string");
+
+
2498 static constexpr auto value =
+
2499 std::is_constructible<value_type, string_type>::value && substr && operator_plus;
+
+
+
2502 template<
typename value_type,
typename number_type>
+
2503 struct is_valid_json_number {
+
2504 static constexpr auto value =
+
2505 std::is_floating_point<number_type>::value && std::is_constructible<value_type, number_type>::value;
+
+
+
2508 template<
typename value_type,
typename integer_type>
+
2509 struct is_valid_json_integer {
+
2510 static constexpr auto value = std::is_signed<integer_type>::value &&
+
2511 !std::is_floating_point<integer_type>::value &&
+
2512 std::is_constructible<value_type, integer_type>::value;
+
+
2514 template<
typename value_type,
typename boolean_type>
+
2515 struct is_valid_json_boolean {
+
2516 static constexpr auto value = std::is_convertible<boolean_type, bool>::value &&
+
2517 std::is_constructible<value_type, boolean_type>::value;
+
+
+
2520 template<
typename value_type,
typename object_type,
typename array_type,
typename string_type,
+
2521 typename number_type,
typename integer_type,
typename boolean_type>
+
2522 struct is_valid_json_types {
+
+
2524 static_assert(is_valid_json_value<value_type>::value,
+
2525 "value_type must meet basic requirements, default constructor, copyable, moveable");
+
2526 static_assert(is_valid_json_object<value_type, string_type, object_type>::value,
+
2527 "object_type must be a string_type to value_type container");
+
2528 static_assert(is_valid_json_array<value_type, array_type>::value,
+
2529 "array_type must be a container of value_type");
+
+
2531 static constexpr auto value = is_valid_json_value<value_type>::value &&
+
2532 is_valid_json_object<value_type, string_type, object_type>::value &&
+
2533 is_valid_json_array<value_type, array_type>::value &&
+
2534 is_valid_json_string<value_type, string_type, integer_type>::value &&
+
2535 is_valid_json_number<value_type, number_type>::value &&
+
2536 is_valid_json_integer<value_type, integer_type>::value &&
+
2537 is_valid_json_boolean<value_type, boolean_type>::value;
+
+
+
+
2548 template<
typename json_traits>
+
+
+
2556 static_assert(std::is_same<typename json_traits::string_type, std::string>::value ||
+
2557 std::is_convertible<typename json_traits::string_type, std::string>::value ||
+
2558 std::is_constructible<typename json_traits::string_type, std::string>::value,
+
2559 "string_type must be a std::string, convertible to a std::string, or construct a std::string.");
+
+
+
2562 details::is_valid_json_types<
typename json_traits::value_type,
typename json_traits::object_type,
+
2563 typename json_traits::array_type,
typename json_traits::string_type,
+
2564 typename json_traits::number_type,
typename json_traits::integer_type,
+
2565 typename json_traits::boolean_type>::value,
+
2566 "must satisfy json container requirements");
+
2567 static_assert(details::is_valid_traits<json_traits>::value,
"traits must satisfy requirements");
+
+
2569 typename json_traits::value_type val;
+
+
+
2575 using set_t = std::set<typename json_traits::string_type>;
+
+
+
+
+
+
+
+
+
2584 JWT_CLAIM_EXPLICIT
basic_claim(
typename json_traits::string_type s) : val(std::move(s)) {}
+
+
2586 : val(typename json_traits::integer_type(std::chrono::system_clock::to_time_t(d))) {}
+
2587 JWT_CLAIM_EXPLICIT basic_claim(
typename json_traits::array_type a) : val(std::move(a)) {}
+
2588 JWT_CLAIM_EXPLICIT basic_claim(
typename json_traits::value_type v) : val(std::move(v)) {}
+
2589 JWT_CLAIM_EXPLICIT basic_claim(
const set_t& s) : val(typename json_traits::array_type(s.begin(), s.end())) {}
+
2590 template<
typename Iterator>
+
2591 basic_claim(Iterator begin, Iterator end) : val(typename json_traits::array_type(begin, end)) {}
+
+
2597 typename json_traits::value_type
to_json()
const {
return val; }
+
+
+
+
+
+
2616 json::type
get_type()
const {
return json_traits::get_type(val); }
+
+
2623 typename json_traits::string_type
as_string()
const {
return json_traits::as_string(val); }
+
+
+
+
2634 using std::chrono::system_clock;
+
2635 if (
get_type() == json::type::number)
return system_clock::from_time_t(std::round(
as_number()));
+
2636 return system_clock::from_time_t(
as_integer());
+
+
+
+
2644 typename json_traits::array_type
as_array()
const {
return json_traits::as_array(val); }
+
+
+
+
+
2653 for (
const auto& e : json_traits::as_array(val)) {
+
2654 res.insert(json_traits::as_string(e));
+
+
+
+
+
+
2664 typename json_traits::integer_type
as_integer()
const {
return json_traits::as_integer(val); }
+
+
2671 typename json_traits::boolean_type
as_boolean()
const {
return json_traits::as_boolean(val); }
+
+
2678 typename json_traits::number_type
as_number()
const {
return json_traits::as_number(val); }
+
+
+
+
+
+
+
+
+
+
2697 template<
typename json_traits>
+
2698 struct map_of_claims {
+
2699 typename json_traits::object_type claims;
+
+
2701 using iterator =
typename json_traits::object_type::iterator;
+
2702 using const_iterator =
typename json_traits::object_type::const_iterator;
+
+
2704 map_of_claims() =
default;
+
2705 map_of_claims(
const map_of_claims&) =
default;
+
2706 map_of_claims(map_of_claims&&) =
default;
+
2707 map_of_claims& operator=(
const map_of_claims&) =
default;
+
2708 map_of_claims& operator=(map_of_claims&&) =
default;
+
+
2710 map_of_claims(
typename json_traits::object_type json) : claims(std::move(json)) {}
+
+
2712 iterator begin() {
return claims.begin(); }
+
2713 iterator end() {
return claims.end(); }
+
2714 const_iterator cbegin()
const {
return claims.begin(); }
+
2715 const_iterator cend()
const {
return claims.end(); }
+
2716 const_iterator begin()
const {
return claims.begin(); }
+
2717 const_iterator end()
const {
return claims.end(); }
+
+
2727 static typename json_traits::object_type parse_claims(
const typename json_traits::string_type& str) {
+
2728 typename json_traits::value_type val;
+
2729 if (!json_traits::parse(val, str))
throw error::invalid_json_exception();
+
+
2731 return json_traits::as_object(val);
+
+
+
2738 bool has_claim(
const typename json_traits::string_type& name)
const noexcept {
+
2739 return claims.count(name) != 0;
+
+
+
2749 basic_claim_t get_claim(
const typename json_traits::string_type& name)
const {
+
2750 if (!has_claim(name))
throw error::claim_not_present_exception();
+
2751 return basic_claim_t{claims.at(name)};
+
+
+
+
+
2760 template<
typename json_traits>
+
+
+
+
2763 details::map_of_claims<json_traits> payload_claims;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
2825 if (aud.get_type() == json::type::string)
return {aud.as_string()};
+
+
2827 return aud.as_set();
+
+
+
+
+
+
+
+
+
2862 return payload_claims.has_claim(name);
+
+
+
+
+
2870 return payload_claims.get_claim(name);
+
+
+
+
+
+
2878 template<
typename json_traits>
+
+
+
+
2881 details::map_of_claims<json_traits> header_claims;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
2938 return header_claims.has_claim(name);
+
+
+
+
+
2946 return header_claims.get_claim(name);
+
+
+
+
+
+
2953 template<
typename json_traits>
+
+
+
+
2957 typename json_traits::string_type
token;
+
+
+
+
+
+
+
+
+
+
2973#ifndef JWT_DISABLE_BASE64
+
+
+
+
2985 return base::decode<alphabet::base64url>(base::pad<alphabet::base64url>(str));
+
+
+
+
2999 template<
typename Decode>
+
+
+
3001 auto hdr_end =
token.find(
'.');
+
3002 if (hdr_end == json_traits::string_type::npos)
throw std::invalid_argument(
"invalid token supplied");
+
3003 auto payload_end =
token.find(
'.', hdr_end + 1);
+
3004 if (payload_end == json_traits::string_type::npos)
throw std::invalid_argument(
"invalid token supplied");
+
+
+
+
+
+
+
+
+
3013 this->header_claims = details::map_of_claims<json_traits>::parse_claims(
header);
+
3014 this->payload_claims = details::map_of_claims<json_traits>::parse_claims(
payload);
+
+
+
+
3021 const typename json_traits::string_type&
get_token() const noexcept {
return token; }
+
+
+
+
+
+
+
3056 typename json_traits::object_type
get_payload_json()
const {
return this->payload_claims.claims; }
+
3061 typename json_traits::object_type
get_header_json()
const {
return this->header_claims.claims; }
+
+
+
3070 return this->payload_claims.get_claim(name);
+
+
+
+
+
3080 return this->header_claims.get_claim(name);
+
+
+
+
+
+
3088 template<
typename Clock,
typename json_traits>
+
+
+
3090 typename json_traits::object_type header_claims;
+
3091 typename json_traits::object_type payload_claims;
+
+
+
+
+
+
+
+
3109 header_claims[id] = std::move(c);
+
+
+
+
+
+
+
3120 header_claims[id] = c.
to_json();
+
+
+
+
+
+
3130 payload_claims[id] = std::move(c);
+
+
+
+
+
+
3140 payload_claims[id] = c.
to_json();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
3262 template<
typename Algo,
typename Encode>
+
+
3263 typename json_traits::string_type
sign(
const Algo& algo, Encode encode)
const {
+
+
3265 auto res =
sign(algo, encode, ec);
+
+
+
+
+
3269#ifndef JWT_DISABLE_BASE64
+
3278 template<
typename Algo>
+
+
3279 typename json_traits::string_type
sign(
const Algo& algo)
const {
+
+
3281 auto res =
sign(algo, ec);
+
+
+
+
+
+
+
3299 template<
typename Algo,
typename Encode>
+
+
3300 typename json_traits::string_type
sign(
const Algo& algo, Encode encode, std::error_code& ec)
const {
+
+
3302 typename json_traits::object_type obj_header = header_claims;
+
3303 if (header_claims.count(
"alg") == 0) obj_header[
"alg"] =
typename json_traits::value_type(algo.name());
+
+
3305 const auto header = encode(json_traits::serialize(
typename json_traits::value_type(obj_header)));
+
3306 const auto payload = encode(json_traits::serialize(
typename json_traits::value_type(payload_claims)));
+
+
+
3309 auto signature = algo.sign(token, ec);
+
+
+
3312 return token +
"." + encode(signature);
+
+
+
3314#ifndef JWT_DISABLE_BASE64
+
3324 template<
typename Algo>
+
+
3325 typename json_traits::string_type
sign(
const Algo& algo, std::error_code& ec)
const {
+
+
+
3328 [](
const typename json_traits::string_type& data) {
+
3329 return base::trim<alphabet::base64url>(base::encode<alphabet::base64url>(data));
+
+
+
+
+
+
+
+
+
3336 namespace verify_ops {
+
3340 template<
typename json_traits>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
3363 ec = error::token_verification_error::missing_claim;
+
+
+
+
+
+
3369 ec = error::token_verification_error::missing_claim;
+
+
+
+
+
+
+
+
+
+
+
3385 if (c.get_type() != t) {
+
3386 ec = error::token_verification_error::claim_type_missmatch;
+
+
+
+
+
+
+
+
+
+
+
3411 template<
typename json_traits,
bool in_header = false>
+
+
+
+
+
+
+
3417 const bool matches = [&]() {
+
+
3419 case json::type::boolean:
return expected.
as_boolean() == jc.as_boolean();
+
3420 case json::type::integer:
return expected.
as_integer() == jc.as_integer();
+
3421 case json::type::number:
return expected.
as_number() == jc.as_number();
+
3422 case json::type::string:
return expected.
as_string() == jc.as_string();
+
3423 case json::type::array:
+
3424 case json::type::object:
+
3425 return json_traits::serialize(expected.
to_json()) == json_traits::serialize(jc.to_json());
+
3426 default:
throw std::logic_error(
"internal error, should be unreachable");
+
+
+
+
3430 ec = error::token_verification_error::claim_value_missmatch;
+
+
+
+
+
+
+
3440 template<
typename json_traits,
bool in_header = false>
+
+
+
3442 const size_t leeway;
+
+
3444 auto jc = ctx.
get_claim(in_header, json::type::integer, ec);
+
+
3446 auto c = jc.as_date();
+
3447 if (ctx.
current_time > c + std::chrono::seconds(leeway)) {
+
3448 ec = error::token_verification_error::token_expired;
+
+
+
+
+
+
3457 template<
typename json_traits,
bool in_header = false>
+
+
+
3459 const size_t leeway;
+
+
3461 auto jc = ctx.
get_claim(in_header, json::type::integer, ec);
+
+
3463 auto c = jc.as_date();
+
3464 if (ctx.
current_time < c - std::chrono::seconds(leeway)) {
+
3465 ec = error::token_verification_error::token_expired;
+
+
+
+
+
+
3475 template<
typename json_traits,
bool in_header = false>
+
+
+
+
+
+
+
3481 if (c.get_type() == json::type::string) {
+
3482 if (expected.size() != 1 || *expected.begin() != c.as_string()) {
+
3483 ec = error::token_verification_error::audience_missmatch;
+
+
+
3486 }
else if (c.get_type() == json::type::array) {
+
3487 auto jc = c.as_set();
+
3488 for (
auto& e : expected) {
+
3489 if (jc.find(e) == jc.end()) {
+
3490 ec = error::token_verification_error::audience_missmatch;
+
+
+
+
+
3495 ec = error::token_verification_error::claim_type_missmatch;
+
+
+
+
+
+
+
3504 template<
typename json_traits,
bool in_header = false>
+
+
+
3506 const typename json_traits::string_type expected;
+
+
+
3509 : expected(to_lower_unicode(e, loc)), locale(loc) {}
+
+
+
3512 const auto c = ctx.
get_claim(in_header, json::type::string, ec);
+
+
3514 if (to_lower_unicode(c.as_string(), locale) != expected) {
+
3515 ec = error::token_verification_error::claim_value_missmatch;
+
+
+
+
3519 static std::string to_lower_unicode(
const std::string& str,
const std::locale& loc) {
+
3520 std::mbstate_t state = std::mbstate_t();
+
3521 const char* in_next = str.data();
+
3522 const char* in_end = str.data() + str.size();
+
+
3524 wide.reserve(str.size());
+
+
3526 while (in_next != in_end) {
+
+
3528 std::size_t result = std::mbrtowc(&wc, in_next, in_end - in_next, &state);
+
3529 if (result ==
static_cast<std::size_t
>(-1)) {
+
3530 throw std::runtime_error(
"encoding error: " + std::string(std::strerror(errno)));
+
3531 }
else if (result ==
static_cast<std::size_t
>(-2)) {
+
3532 throw std::runtime_error(
"conversion error: next bytes constitute an incomplete, but so far "
+
3533 "valid, multibyte character.");
+
+
+
+
+
+
3539 auto& f = std::use_facet<std::ctype<wchar_t>>(loc);
+
3540 f.tolower(&wide[0], &wide[0] + wide.size());
+
+
+
3543 out.reserve(wide.size());
+
3544 for (
wchar_t wc : wide) {
+
3545 char mb[MB_LEN_MAX];
+
3546 std::size_t n = std::wcrtomb(mb, wc, &state);
+
3547 if (n !=
static_cast<std::size_t
>(-1)) out.append(mb, n);
+
+
+
+
+
+
+
+
+
3559 template<
typename Clock,
typename json_traits>
+
+
+
+
+
+
+
+
+
+
3577 virtual ~algo_base() =
default;
+
3578 virtual void verify(
const std::string& data,
const std::string& sig, std::error_code& ec) = 0;
+
+
3580 template<
typename T>
+
3581 struct algo :
public algo_base {
+
+
3583 explicit algo(T a) : alg(a) {}
+
3584 void verify(
const std::string& data,
const std::string& sig, std::error_code& ec)
override {
+
3585 alg.verify(data, sig, ec);
+
+
+
3589 std::unordered_map<typename json_traits::string_type, verify_check_fn_t> claims;
+
3591 size_t default_leeway = 0;
+
+
3595 std::unordered_map<std::string, std::shared_ptr<algo_base>> algs;
+
+
+
+
+
+
3604 if (!ctx.
jwt.has_expires_at())
return;
+
3605 auto exp = ctx.
jwt.get_expires_at();
+
+
3607 ec = error::token_verification_error::token_expired;
+
+
+
+
3611 if (!ctx.
jwt.has_issued_at())
return;
+
3612 auto iat = ctx.
jwt.get_issued_at();
+
+
3614 ec = error::token_verification_error::token_expired;
+
+
+
+
3618 if (!ctx.
jwt.has_not_before())
return;
+
3619 auto nbf = ctx.
jwt.get_not_before();
+
+
3621 ec = error::token_verification_error::token_expired;
+
+
+
+
+
+
+
+
+
+
+
+
3677 verifier&
with_type(
const typename json_traits::string_type& type, std::locale locale = std::locale{}) {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
3772 template<
typename Algorithm>
+
+
+
3774 algs[alg.name()] = std::make_shared<algo<Algorithm>>(alg);
+
+
+
+
+
+
+
+
+
3795 const typename json_traits::string_type data =
jwt.get_header_base64() +
"." +
jwt.get_payload_base64();
+
3796 const typename json_traits::string_type sig =
jwt.get_signature();
+
3797 const std::string algo =
jwt.get_algorithm();
+
3798 if (algs.count(algo) == 0) {
+
3799 ec = error::token_verification_error::wrong_algorithm;
+
+
+
3802 algs.at(algo)->verify(data, sig, ec);
+
+
+
+
3806 for (
auto& c : claims) {
+
3807 ctx.claim_key = c.first;
+
+
+
+
+
+
+
+
+
3822 template<
typename json_traits>
+
+
+
+
3825 const details::map_of_claims<json_traits> jwk_claims;
+
+
+
3828 JWT_CLAIM_EXPLICIT
jwk(
const typename json_traits::string_type& str)
+
3829 : jwk_claims(details::map_of_claims<json_traits>::parse_claims(str)) {}
+
+
3831 JWT_CLAIM_EXPLICIT
jwk(
const typename json_traits::value_type& json)
+
3832 : jwk_claims(json_traits::as_object(json)) {}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
3930 return json_traits::as_string(x5c_array.front());
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
3997 bool has_jwk_claim(
const typename json_traits::string_type& name)
const noexcept {
+
3998 return jwk_claims.has_claim(name);
+
+
+
+
+
+
4007 return jwk_claims.get_claim(name);
+
+
+
+
4014 bool empty() const noexcept {
return jwk_claims.empty(); }
+
+
4020 typename json_traits::object_type
get_claims()
const {
return this->jwk_claims.claims; }
+
+
+
+
4033 template<
typename json_traits>
+
+
+
+
+
+
4040 using iterator =
typename jwks_vector_t::iterator;
+
4041 using const_iterator =
typename jwks_vector_t::const_iterator;
+
+
+
+
+
4054 JWT_CLAIM_EXPLICIT
jwks(
const typename json_traits::string_type& str) {
+
4055 typename json_traits::value_type parsed_val;
+
+
+
4058 const details::map_of_claims<json_traits> jwks_json = json_traits::as_object(parsed_val);
+
+
+
4061 auto jwk_list = jwks_json.get_claim(
"keys").as_array();
+
4062 std::transform(jwk_list.begin(), jwk_list.end(), std::back_inserter(jwk_claims),
+
4063 [](
const typename json_traits::value_type& val) { return jwks_t{val}; });
+
+
+
+
4066 iterator begin() {
return jwk_claims.begin(); }
+
4067 iterator end() {
return jwk_claims.end(); }
+
4068 const_iterator cbegin()
const {
return jwk_claims.begin(); }
+
4069 const_iterator cend()
const {
return jwk_claims.end(); }
+
4070 const_iterator begin()
const {
return jwk_claims.begin(); }
+
4071 const_iterator end()
const {
return jwk_claims.end(); }
+
+
+
4077 bool has_jwk(
const typename json_traits::string_type& key_id)
const noexcept {
+
4078 return find_by_kid(key_id) != end();
+
+
+
+
+
+
4087 const auto maybe = find_by_kid(key_id);
+
+
+
+
+
+
+
4093 jwks_vector_t jwk_claims;
+
+
4095 const_iterator find_by_kid(
const typename json_traits::string_type& key_id)
const noexcept {
+
4096 return std::find_if(cbegin(), cend(), [key_id](
const jwks_t&
jwk) {
+
+
+
+
+
+
+
+
4108 template<
typename Clock,
typename json_traits>
+
+
+
4118 template<
typename Clock,
typename json_traits>
+
+
+
+
+
4142 template<
typename json_traits>
+
+
+
4144 return verifier<default_clock, json_traits>(c);
+
+
+
+
4150 template<
typename json_traits>
+
+
+
4152 return builder<default_clock, json_traits>(c);
+
+
+
+
4169 template<
typename json_traits,
typename Decode>
+
+
+
4184 template<
typename json_traits>
+
+
4194 template<
typename json_traits>
+
+
4208 template<
typename json_traits>
+
+
+
+
4214template<
typename json_traits>
+
+
4216 return c.operator>>(is);
+
+
+
4219template<
typename json_traits>
+
+
+
+
+
4224#ifndef JWT_DISABLE_PICOJSON
+
4225#include "traits/kazuho-picojson/defaults.h"
+
+
+
+
a class to store a generic JSON value as claim
Definition jwt.h:2549
+
json_traits::number_type as_number() const
Definition jwt.h:2678
+
set_t as_set() const
Definition jwt.h:2651
+
json::type get_type() const
Definition jwt.h:2616
+
std::set< typename json_traits::string_type > set_t
Definition jwt.h:2575
+
std::istream & operator>>(std::istream &is)
Definition jwt.h:2603
+
json_traits::boolean_type as_boolean() const
Definition jwt.h:2671
+
date as_date() const
Get the contained JSON value as a date.
Definition jwt.h:2633
+
std::ostream & operator<<(std::ostream &os)
Definition jwt.h:2609
+
json_traits::integer_type as_integer() const
Definition jwt.h:2664
+
json_traits::value_type to_json() const
Definition jwt.h:2597
+
json_traits::array_type as_array() const
Definition jwt.h:2644
+
json_traits::string_type as_string() const
Definition jwt.h:2623
+
+
builder & set_audience(typename json_traits::string_type aud)
Definition jwt.h:3207
+
builder & set_payload_claim(const typename json_traits::string_type &id, basic_claim< json_traits > c)
Definition jwt.h:3139
+
builder & set_expires_in(const std::chrono::duration< Rep > &d)
Definition jwt.h:3222
+
builder & set_algorithm(typename json_traits::string_type str)
Set algorithm claim You normally don't need to do this, as the algorithm is automatically set if you ...
Definition jwt.h:3150
+
builder & set_expires_at(const date &d)
Definition jwt.h:3215
+
builder & set_type(typename json_traits::string_type str)
Definition jwt.h:3158
+
JWT_CLAIM_EXPLICIT builder(Clock c)
Definition jwt.h:3101
+
json_traits::string_type sign(const Algo &algo, std::error_code &ec) const
Definition jwt.h:3325
+
builder & set_issued_at(const date &d)
Definition jwt.h:3236
+
json_traits::string_type sign(const Algo &algo) const
Definition jwt.h:3279
+
builder & set_payload_claim(const typename json_traits::string_type &id, typename json_traits::value_type c)
Definition jwt.h:3129
+
builder & set_id(const typename json_traits::string_type &str)
Definition jwt.h:3247
+
builder & set_header_claim(const typename json_traits::string_type &id, typename json_traits::value_type c)
Definition jwt.h:3108
+
builder & set_header_claim(const typename json_traits::string_type &id, basic_claim< json_traits > c)
Definition jwt.h:3119
+
json_traits::string_type sign(const Algo &algo, Encode encode) const
Definition jwt.h:3263
+
builder & set_audience(typename json_traits::array_type a)
Definition jwt.h:3199
+
json_traits::string_type sign(const Algo &algo, Encode encode, std::error_code &ec) const
Definition jwt.h:3300
+
builder & set_content_type(typename json_traits::string_type str)
Definition jwt.h:3166
+
builder & set_not_before(const date &d)
Definition jwt.h:3230
+
builder & set_subject(typename json_traits::string_type str)
Definition jwt.h:3191
+
builder & set_issued_now()
Definition jwt.h:3241
+
builder & set_key_id(typename json_traits::string_type str)
Set key id claim.
Definition jwt.h:3175
+
builder & set_issuer(typename json_traits::string_type str)
Definition jwt.h:3183
+
+
const json_traits::string_type & get_header() const noexcept
Definition jwt.h:3026
+
const json_traits::string_type & get_signature_base64() const noexcept
Definition jwt.h:3051
+
json_traits::string_type signature
Signature part decoded from base64.
Definition jwt.h:2967
+
json_traits::string_type header
Header part decoded from base64.
Definition jwt.h:2959
+
json_traits::string_type header_base64
Unmodified header part in base64.
Definition jwt.h:2961
+
json_traits::string_type token
Unmodified token, as passed to constructor.
Definition jwt.h:2957
+
basic_claim_t get_payload_claim(const typename json_traits::string_type &name) const
Definition jwt.h:3069
+
const json_traits::string_type & get_signature() const noexcept
Definition jwt.h:3036
+
JWT_CLAIM_EXPLICIT decoded_jwt(const typename json_traits::string_type &token)
Parses a given token.
Definition jwt.h:2983
+
basic_claim_t get_header_claim(const typename json_traits::string_type &name) const
Definition jwt.h:3079
+
decoded_jwt(const typename json_traits::string_type &token, Decode decode)
Parses a given token.
Definition jwt.h:3000
+
json_traits::object_type get_payload_json() const
Definition jwt.h:3056
+
json_traits::string_type signature_base64
Unmodified signature part in base64.
Definition jwt.h:2969
+
const json_traits::string_type & get_payload_base64() const noexcept
Definition jwt.h:3046
+
const json_traits::string_type & get_token() const noexcept
Definition jwt.h:3021
+
json_traits::object_type get_header_json() const
Definition jwt.h:3061
+
const json_traits::string_type & get_payload() const noexcept
Definition jwt.h:3031
+
const json_traits::string_type & get_header_base64() const noexcept
Definition jwt.h:3041
+
json_traits::string_type payload_base64
Unmodified payload part in base64.
Definition jwt.h:2965
+
json_traits::string_type payload
Payload part decoded from base64.
Definition jwt.h:2963
+
+
+
+
+
+
+
+
+
+
+
+
Handle class for EVP_PKEY structures.
Definition jwt.h:425
+
constexpr evp_pkey_handle() noexcept=default
Creates a null key pointer.
+
constexpr evp_pkey_handle(EVP_PKEY *key) noexcept
Construct a new handle. The handle takes ownership of the key.
Definition jwt.h:449
+
JSON Web Key.
Definition jwt.h:3823
+
bool has_x5c() const noexcept
Definition jwt.h:3979
+
json_traits::string_type get_curve() const
Get curve claim.
Definition jwt.h:3886
+
bool has_x5t_sha256() const noexcept
Definition jwt.h:3991
+
json_traits::string_type get_algorithm() const
Definition jwt.h:3866
+
json_traits::array_type get_x5c() const
Definition jwt.h:3894
+
json_traits::object_type get_claims() const
Definition jwt.h:4020
+
json_traits::string_type get_x5t() const
Definition jwt.h:3910
+
json_traits::string_type get_x5c_key_value() const
Definition jwt.h:3926
+
json_traits::string_type get_x5t_sha256() const
Definition jwt.h:3918
+
json_traits::string_type get_key_id() const
Definition jwt.h:3874
+
bool has_algorithm() const noexcept
Definition jwt.h:3955
+
json_traits::string_type get_use() const
Definition jwt.h:3850
+
bool has_key_id() const noexcept
Definition jwt.h:3967
+
bool has_x5u() const noexcept
Definition jwt.h:3973
+
bool has_key_operations() const noexcept
Definition jwt.h:3949
+
bool empty() const noexcept
Definition jwt.h:4014
+
bool has_use() const noexcept
Definition jwt.h:3943
+
bool has_x5t() const noexcept
Definition jwt.h:3985
+
bool has_jwk_claim(const typename json_traits::string_type &name) const noexcept
Definition jwt.h:3997
+
basic_claim_t::set_t get_key_operations() const
Definition jwt.h:3858
+
bool has_curve() const noexcept
Definition jwt.h:3961
+
bool has_key_type() const noexcept
Definition jwt.h:3937
+
basic_claim_t get_jwk_claim(const typename json_traits::string_type &name) const
Definition jwt.h:4006
+
json_traits::string_type get_x5u() const
Definition jwt.h:3902
+
json_traits::string_type get_key_type() const
Definition jwt.h:3842
+
JWK Set.
Definition jwt.h:4034
+
jwks_t get_jwk(const typename json_traits::string_type &key_id) const
Definition jwt.h:4086
+
+
std::vector< jwks_t > jwks_vector_t
Type specialization for the vector of JWK.
Definition jwt.h:4039
+
JWT_CLAIM_EXPLICIT jwks(const typename json_traits::string_type &str)
Definition jwt.h:4054
+
bool has_jwk(const typename json_traits::string_type &key_id) const noexcept
Definition jwt.h:4077
+
+
basic_claim_t::set_t get_audience() const
Definition jwt.h:2823
+
json_traits::string_type get_id() const
Definition jwt.h:2856
+
bool has_issued_at() const noexcept
Definition jwt.h:2797
+
bool has_not_before() const noexcept
Definition jwt.h:2792
+
bool has_payload_claim(const typename json_traits::string_type &name) const noexcept
Definition jwt.h:2861
+
bool has_subject() const noexcept
Definition jwt.h:2777
+
date get_not_before() const
Definition jwt.h:2842
+
bool has_issuer() const noexcept
Definition jwt.h:2772
+
bool has_id() const noexcept
Definition jwt.h:2802
+
bool has_expires_at() const noexcept
Definition jwt.h:2787
+
date get_issued_at() const
Definition jwt.h:2849
+
basic_claim_t get_payload_claim(const typename json_traits::string_type &name) const
Definition jwt.h:2869
+
bool has_audience() const noexcept
Definition jwt.h:2782
+
date get_expires_at() const
Definition jwt.h:2835
+
json_traits::string_type get_subject() const
Definition jwt.h:2816
+
json_traits::string_type get_issuer() const
Definition jwt.h:2809
+
+
verifier & expires_at_leeway(size_t leeway)
Definition jwt.h:3641
+
verifier & with_claim(const typename json_traits::string_type &name, verify_check_fn_t fn)
Definition jwt.h:3740
+
void verify(const decoded_jwt< json_traits > &jwt, std::error_code &ec) const
Definition jwt.h:3793
+
std::function< void(const verify_ops::verify_context< json_traits > &, std::error_code &ec)> verify_check_fn_t
Verification function data structure.
Definition jwt.h:3572
+
verifier & not_before_leeway(size_t leeway)
Definition jwt.h:3651
+
verifier & issued_at_leeway(size_t leeway)
Definition jwt.h:3661
+
verifier & with_subject(const typename json_traits::string_type &sub)
Definition jwt.h:3697
+
verifier & with_audience(const typename basic_claim_t::set_t &aud)
Definition jwt.h:3706
+
verifier & with_claim(const typename json_traits::string_type &name, basic_claim_t c)
Definition jwt.h:3755
+
verifier & with_audience(const typename json_traits::string_type &aud)
Definition jwt.h:3716
+
void verify(const decoded_jwt< json_traits > &jwt) const
Definition jwt.h:3783
+
verifier(Clock c)
Definition jwt.h:3602
+
verifier & leeway(size_t leeway)
Definition jwt.h:3631
+
verifier & with_issuer(const typename json_traits::string_type &iss)
Definition jwt.h:3687
+
verifier & allow_algorithm(Algorithm alg)
Add an algorithm available for checking.
Definition jwt.h:3773
+
verifier & with_type(const typename json_traits::string_type &type, std::locale locale=std::locale{})
Definition jwt.h:3677
+
verifier & with_id(const typename json_traits::string_type &id)
Definition jwt.h:3727
+
signature_verification_error
Errors related to verification of signatures.
Definition jwt.h:216
+
std::error_category & token_verification_error_category()
Error category for token verification errors.
Definition jwt.h:351
+
void throw_if_error(std::error_code ec)
Raises an exception if any JWT-CPP error codes are active.
Definition jwt.h:383
+
std::error_category & ecdsa_error_category()
Error category for ECDSA errors.
Definition jwt.h:179
+
std::error_category & signature_verification_error_category()
Error category for verification errors.
Definition jwt.h:230
+
std::error_category & rsa_error_category()
Error category for RSA errors.
Definition jwt.h:127
+
std::error_category & signature_generation_error_category()
Error category for signature generation errors.
Definition jwt.h:289
+
ecdsa_error
Errors related to processing of RSA signatures.
Definition jwt.h:159
+
rsa_error
Errors related to processing of RSA signatures.
Definition jwt.h:110
+
signature_generation_error
Errors related to signature generation errors.
Definition jwt.h:269
+
token_verification_error
Errors related to token verification errors.
Definition jwt.h:339
+
std::error_code make_error_code(rsa_error e)
Converts JWT-CPP errors into generic STL error_codes.
Definition jwt.h:155
+
std::string extract_pubkey_from_cert(const std::string &certstr, const std::string &pw, std::error_code &ec)
Extract the public key of a pem certificate.
Definition jwt.h:542
+
evp_pkey_handle load_public_ec_key_from_string(const std::string &key, const std::string &password, std::error_code &ec)
Load a public key from a string.
Definition jwt.h:818
+
evp_pkey_handle load_public_key_from_string(const std::string &key, const std::string &password, std::error_code &ec)
Load a public key from a string.
Definition jwt.h:714
+
std::string create_public_key_from_rsa_components(const std::string &modulus, const std::string &exponent, Decode decode, std::error_code &ec)
create public key from modulus and exponent. This is defined in RFC 7518 Section 6....
Definition jwt.h:917
+
std::unique_ptr< BIGNUM, decltype(&BN_free)> raw2bn(const std::string &raw, std::error_code &ec)
Definition jwt.h:847
+
evp_pkey_handle load_private_ec_key_from_string(const std::string &key, const std::string &password, std::error_code &ec)
Load a private key from a string.
Definition jwt.h:897
+
int curve2nid(const std::string curve, std::error_code &ec)
Convert a curve name to an ID.
Definition jwt.h:1124
+
std::string convert_base64_der_to_pem(const std::string &cert_base64_der_str, Decode decode, std::error_code &ec)
Convert the certificate provided as base64 DER to PEM.
Definition jwt.h:628
+
std::string bn2raw(const BIGNUM *bn)
Definition jwt.h:834
+
std::string create_public_key_from_ec_components(const std::string &curve, const std::string &x, const std::string &y, Decode decode, std::error_code &ec)
Definition jwt.h:1155
+
evp_pkey_handle load_private_key_from_string(const std::string &key, const std::string &password, std::error_code &ec)
Load a private key from a string.
Definition jwt.h:772
+
std::string convert_der_to_pem(const std::string &cert_der_str, std::error_code &ec)
Convert the certificate provided as DER to PEM.
Definition jwt.h:592
+
type
Categories for the various JSON types used in JWTs.
Definition jwt.h:2274
+
JSON Web Token.
Definition base.h:21
+
verifier< Clock, json_traits > verify(Clock c)
Definition jwt.h:4109
+
std::chrono::system_clock::time_point date
Definition jwt.h:86
+
builder< Clock, json_traits > create(Clock c)
Definition jwt.h:4119
+
verifier< default_clock, traits::boost_json > verify()
Definition defaults.h:23
+
jwk< json_traits > parse_jwk(const typename json_traits::string_type &jwk_)
Definition jwt.h:4195
+
jwks< json_traits > parse_jwks(const typename json_traits::string_type &jwks_)
Definition jwt.h:4209
+
decoded_jwt< json_traits > decode(const typename json_traits::string_type &token, Decode decode)
Decode a token. This can be used to to help access important feild like 'x5c' for verifying tokens....
Definition jwt.h:4170
+
verify_ops::verify_context< traits::boost_json > verify_context
Definition defaults.h:88
+
Base class for ECDSA family of algorithms.
Definition jwt.h:1542
+
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition jwt.h:1616
+
std::string sign(const std::string &data, std::error_code &ec) const
Definition jwt.h:1579
+
ecdsa(const std::string &public_key, const std::string &private_key, const std::string &public_key_password, const std::string &private_key_password, const EVP_MD *(*md)(), std::string name, size_t siglen)
Definition jwt.h:1554
+
std::string name() const
Definition jwt.h:1655
+
+
ed25519(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2188
+
+
ed448(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2210
+
Base class for EdDSA family of algorithms.
Definition jwt.h:1773
+
std::string name() const
Definition jwt.h:1887
+
eddsa(const std::string &public_key, const std::string &private_key, const std::string &public_key_password, const std::string &private_key_password, std::string name)
Definition jwt.h:1784
+
std::string sign(const std::string &data, std::error_code &ec) const
Definition jwt.h:1800
+
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition jwt.h:1848
+
+
es256(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2115
+
+
es256k(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2165
+
+
es384(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2132
+
+
es512(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2149
+
Base class for HMAC family of algorithms.
Definition jwt.h:1372
+
std::string sign(const std::string &data, std::error_code &ec) const
Definition jwt.h:1389
+
std::string name() const
Definition jwt.h:1429
+
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition jwt.h:1410
+
hmacsha(std::string key, const EVP_MD *(*md)(), std::string name)
Definition jwt.h:1380
+
+
hs256(std::string key)
Definition jwt.h:2032
+
+
hs384(std::string key)
Definition jwt.h:2042
+
+
hs512(std::string key)
Definition jwt.h:2052
+
"none" algorithm.
Definition jwt.h:1347
+
void verify(const std::string &, const std::string &signature, std::error_code &ec) const
Check if the given signature is empty.
Definition jwt.h:1362
+
std::string name() const
Get algorithm name.
Definition jwt.h:1367
+
std::string sign(const std::string &, std::error_code &ec) const
Return an empty string.
Definition jwt.h:1351
+
+
ps256(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2227
+
+
ps384(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2242
+
+
ps512(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2257
+
Base class for PSS-RSA family of algorithms.
Definition jwt.h:1899
+
std::string name() const
Definition jwt.h:2013
+
pss(const std::string &public_key, const std::string &private_key, const std::string &public_key_password, const std::string &private_key_password, const EVP_MD *(*md)(), std::string name)
Definition jwt.h:1909
+
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition jwt.h:1974
+
std::string sign(const std::string &data, std::error_code &ec) const
Definition jwt.h:1926
+
+
rs256(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Construct new instance of algorithm.
Definition jwt.h:2068
+
+
rs384(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2083
+
+
rs512(const std::string &public_key, const std::string &private_key="", const std::string &public_key_password="", const std::string &private_key_password="")
Definition jwt.h:2098
+
Base class for RSA family of algorithms.
Definition jwt.h:1442
+
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition jwt.h:1503
+
std::string sign(const std::string &data, std::error_code &ec) const
Definition jwt.h:1469
+
rsa(const std::string &public_key, const std::string &private_key, const std::string &public_key_password, const std::string &private_key_password, const EVP_MD *(*md)(), std::string name)
Definition jwt.h:1453
+
std::string name() const
Definition jwt.h:1529
+
+
date now() const
Definition jwt.h:4131
+
+
+
+
+
+
+
+
+
+
+
+
+
+
date current_time
Current time, retrieved from the verifiers clock and cached for performance and consistency.
Definition jwt.h:3345
+
basic_claim< json_traits > get_claim(bool in_header, json::type t, std::error_code &ec) const
Definition jwt.h:3382
+
size_t default_leeway
The configured default leeway for this verification.
Definition jwt.h:3349
+
basic_claim< json_traits > get_claim(bool in_header, std::error_code &ec) const
Helper method to get a claim from the jwt in this context.
Definition jwt.h:3360
+
basic_claim< json_traits > get_claim(json::type t, std::error_code &ec) const
Helper method to get a payload claim of a specific type from the jwt.
Definition jwt.h:3403
+
basic_claim< json_traits > get_claim(std::error_code &ec) const
Helper method to get a payload claim from the jwt.
Definition jwt.h:3396
+
json_traits::string_type claim_key
The claim key to apply this comparison on.
Definition jwt.h:3352
+
const decoded_jwt< json_traits > & jwt
The jwt passed to the verifier.
Definition jwt.h:3347
+