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 >= 0x3070100fL
61#define JWT_OPENSSL_1_1_1
62#elif LIBRESSL_VERSION_NUMBER >= 0x3050300fL
63#define JWT_OPENSSL_1_1_0
65#define JWT_OPENSSL_1_0_0
69#if defined(LIBWOLFSSL_VERSION_HEX)
70#define JWT_OPENSSL_1_1_1
73#ifndef JWT_CLAIM_EXPLICIT
74#define JWT_CLAIM_EXPLICIT explicit
88 using date = std::chrono::system_clock::time_point;
95 using system_error::system_error;
98 using system_error::system_error;
101 using system_error::system_error;
104 using system_error::system_error;
107 using system_error::system_error;
114 cert_load_failed = 10,
118 convert_to_pem_failed,
121 create_mem_bio_failed,
124 create_context_failed
130 class rsa_error_cat :
public std::error_category {
132 const char* name()
const noexcept override {
return "rsa_error"; };
133 std::string message(
int ev)
const override {
135 case rsa_error::ok:
return "no error";
136 case rsa_error::cert_load_failed:
return "error loading cert into memory";
137 case rsa_error::get_key_failed:
return "error getting key from certificate";
138 case rsa_error::write_key_failed:
return "error writing key data in PEM format";
139 case rsa_error::write_cert_failed:
return "error writing cert data in PEM format";
140 case rsa_error::convert_to_pem_failed:
return "failed to convert key to pem";
141 case rsa_error::load_key_bio_write:
return "failed to load key: bio write failed";
142 case rsa_error::load_key_bio_read:
return "failed to load key: bio read failed";
143 case rsa_error::create_mem_bio_failed:
return "failed to create memory bio";
144 case rsa_error::no_key_provided:
return "at least one of public or private key need to be present";
145 case rsa_error::set_rsa_failed:
return "set modulus and exponent to RSA failed";
146 case rsa_error::create_context_failed:
return "failed to create context";
147 default:
return "unknown RSA error";
151 static rsa_error_cat cat;
163 load_key_bio_write = 10,
165 create_mem_bio_failed,
169 create_context_failed,
174 convert_to_pem_failed,
182 class ecdsa_error_cat :
public std::error_category {
184 const char* name()
const noexcept override {
return "ecdsa_error"; };
185 std::string message(
int ev)
const override {
187 case ecdsa_error::ok:
return "no error";
188 case ecdsa_error::load_key_bio_write:
return "failed to load key: bio write failed";
189 case ecdsa_error::load_key_bio_read:
return "failed to load key: bio read failed";
190 case ecdsa_error::create_mem_bio_failed:
return "failed to create memory bio";
191 case ecdsa_error::no_key_provided:
192 return "at least one of public or private key need to be present";
193 case ecdsa_error::invalid_key_size:
return "invalid key size";
194 case ecdsa_error::invalid_key:
return "invalid key";
195 case ecdsa_error::create_context_failed:
return "failed to create context";
196 case ecdsa_error::cert_load_failed:
return "error loading cert into memory";
197 case ecdsa_error::get_key_failed:
return "error getting key from certificate";
198 case ecdsa_error::write_key_failed:
return "error writing key data in PEM format";
199 case ecdsa_error::write_cert_failed:
return "error writing cert data in PEM format";
200 case ecdsa_error::convert_to_pem_failed:
return "failed to convert key to pem";
201 case ecdsa_error::unknown_curve:
return "unknown curve";
202 case ecdsa_error::set_ecdsa_failed:
return "set parameters to ECDSA failed";
203 default:
return "unknown ECDSA error";
207 static ecdsa_error_cat cat;
220 invalid_signature = 10,
221 create_context_failed,
226 set_rsa_pss_saltlen_failed,
227 signature_encoding_failed
233 class verification_error_cat :
public std::error_category {
235 const char* name()
const noexcept override {
return "signature_verification_error"; };
236 std::string message(
int ev)
const override {
238 case signature_verification_error::ok:
return "no error";
239 case signature_verification_error::invalid_signature:
return "invalid signature";
240 case signature_verification_error::create_context_failed:
241 return "failed to verify signature: could not create context";
242 case signature_verification_error::verifyinit_failed:
243 return "failed to verify signature: VerifyInit failed";
244 case signature_verification_error::verifyupdate_failed:
245 return "failed to verify signature: VerifyUpdate failed";
246 case signature_verification_error::verifyfinal_failed:
247 return "failed to verify signature: VerifyFinal failed";
248 case signature_verification_error::get_key_failed:
249 return "failed to verify signature: Could not get key";
250 case signature_verification_error::set_rsa_pss_saltlen_failed:
251 return "failed to verify signature: EVP_PKEY_CTX_set_rsa_pss_saltlen failed";
252 case signature_verification_error::signature_encoding_failed:
253 return "failed to verify signature: i2d_ECDSA_SIG failed";
254 default:
return "unknown signature verification error";
258 static verification_error_cat cat;
274 create_context_failed,
278 ecdsa_do_sign_failed,
283 rsa_private_encrypt_failed,
285 set_rsa_pss_saltlen_failed,
286 signature_decoding_failed
292 class signature_generation_error_cat :
public std::error_category {
294 const char* name()
const noexcept override {
return "signature_generation_error"; };
295 std::string message(
int ev)
const override {
297 case signature_generation_error::ok:
return "no error";
298 case signature_generation_error::hmac_failed:
return "hmac failed";
299 case signature_generation_error::create_context_failed:
300 return "failed to create signature: could not create context";
301 case signature_generation_error::signinit_failed:
302 return "failed to create signature: SignInit failed";
303 case signature_generation_error::signupdate_failed:
304 return "failed to create signature: SignUpdate failed";
305 case signature_generation_error::signfinal_failed:
306 return "failed to create signature: SignFinal failed";
307 case signature_generation_error::ecdsa_do_sign_failed:
return "failed to generate ecdsa signature";
308 case signature_generation_error::digestinit_failed:
309 return "failed to create signature: DigestInit failed";
310 case signature_generation_error::digestupdate_failed:
311 return "failed to create signature: DigestUpdate failed";
312 case signature_generation_error::digestfinal_failed:
313 return "failed to create signature: DigestFinal failed";
314 case signature_generation_error::rsa_padding_failed:
315 return "failed to create signature: EVP_PKEY_CTX_set_rsa_padding failed";
316 case signature_generation_error::rsa_private_encrypt_failed:
317 return "failed to create signature: RSA_private_encrypt failed";
318 case signature_generation_error::get_key_failed:
319 return "failed to generate signature: Could not get key";
320 case signature_generation_error::set_rsa_pss_saltlen_failed:
321 return "failed to create signature: EVP_PKEY_CTX_set_rsa_pss_saltlen failed";
322 case signature_generation_error::signature_decoding_failed:
323 return "failed to create signature: d2i_ECDSA_SIG failed";
324 default:
return "unknown signature generation error";
328 static signature_generation_error_cat cat = {};
343 wrong_algorithm = 10,
345 claim_type_missmatch,
346 claim_value_missmatch,
354 class token_verification_error_cat :
public std::error_category {
356 const char* name()
const noexcept override {
return "token_verification_error"; };
357 std::string message(
int ev)
const override {
359 case token_verification_error::ok:
return "no error";
360 case token_verification_error::wrong_algorithm:
return "wrong algorithm";
361 case token_verification_error::missing_claim:
return "decoded JWT is missing required claim(s)";
362 case token_verification_error::claim_type_missmatch:
363 return "claim type does not match expected type";
364 case token_verification_error::claim_value_missmatch:
365 return "claim value does not match expected value";
366 case token_verification_error::token_expired:
return "token expired";
367 case token_verification_error::audience_missmatch:
368 return "token doesn't contain the required audience";
369 default:
return "unknown token verification error";
373 static token_verification_error_cat cat = {};
400 struct is_error_code_enum<jwt::error::rsa_error> : true_type {};
402 struct is_error_code_enum<jwt::error::ecdsa_error> : true_type {};
404 struct is_error_code_enum<jwt::error::signature_verification_error> : true_type {};
406 struct is_error_code_enum<jwt::error::signature_generation_error> : true_type {};
408 struct is_error_code_enum<jwt::error::token_verification_error> : true_type {};
433#ifdef JWT_OPENSSL_1_0_0
438 explicit evp_pkey_handle(EVP_PKEY* key) { m_key = std::shared_ptr<EVP_PKEY>(key, EVP_PKEY_free); }
440 EVP_PKEY* get() const noexcept {
return m_key.get(); }
441 bool operator!() const noexcept {
return m_key ==
nullptr; }
442 explicit operator bool() const noexcept {
return m_key !=
nullptr; }
445 std::shared_ptr<EVP_PKEY> m_key{
nullptr};
453 if (m_key !=
nullptr && EVP_PKEY_up_ref(m_key) != 1)
throw std::runtime_error(
"EVP_PKEY_up_ref failed");
456#if __cplusplus >= 201402L
460 : m_key{other.m_key} {
461 other.m_key =
nullptr;
464 if (&other ==
this)
return *
this;
465 decrement_ref_count(m_key);
467 increment_ref_count(m_key);
471 if (&other ==
this)
return *
this;
472 decrement_ref_count(m_key);
474 other.m_key =
nullptr;
478 decrement_ref_count(m_key);
480 increment_ref_count(m_key);
485 EVP_PKEY* get() const noexcept {
return m_key; }
486 bool operator!() const noexcept {
return m_key ==
nullptr; }
487 explicit operator bool() const noexcept {
return m_key !=
nullptr; }
490 EVP_PKEY* m_key{
nullptr};
492 static void increment_ref_count(EVP_PKEY* key) {
493 if (key !=
nullptr && EVP_PKEY_up_ref(key) != 1)
throw std::runtime_error(
"EVP_PKEY_up_ref failed");
495 static void decrement_ref_count(EVP_PKEY* key)
noexcept {
496 if (key !=
nullptr) EVP_PKEY_free(key);
501 inline std::unique_ptr<BIO,
decltype(&BIO_free_all)> make_mem_buf_bio() {
502 return std::unique_ptr<BIO, decltype(&BIO_free_all)>(BIO_new(BIO_s_mem()), BIO_free_all);
505 inline std::unique_ptr<BIO,
decltype(&BIO_free_all)> make_mem_buf_bio(
const std::string& data) {
506 return std::unique_ptr<BIO, decltype(&BIO_free_all)>(
507#
if OPENSSL_VERSION_NUMBER <= 0x10100003L
508 BIO_new_mem_buf(
const_cast<char*
>(data.data()),
static_cast<int>(data.size())), BIO_free_all
510 BIO_new_mem_buf(data.data(),
static_cast<int>(data.size())), BIO_free_all
515 template<
typename error_category = error::rsa_error>
516 std::string write_bio_to_string(std::unique_ptr<BIO,
decltype(&BIO_free_all)>& bio_out, std::error_code& ec) {
518 auto len = BIO_get_mem_data(bio_out.get(), &ptr);
519 if (len <= 0 || ptr ==
nullptr) {
520 ec = error_category::convert_to_pem_failed;
523 return {ptr,
static_cast<size_t>(len)};
526 inline std::unique_ptr<EVP_MD_CTX, void (*)(EVP_MD_CTX*)> make_evp_md_ctx() {
528#ifdef JWT_OPENSSL_1_0_0
529 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)>(EVP_MD_CTX_create(), &EVP_MD_CTX_destroy);
531 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)>(EVP_MD_CTX_new(), &EVP_MD_CTX_free);
543 template<
typename error_category = error::rsa_error>
546 auto certbio = make_mem_buf_bio(certstr);
547 auto keybio = make_mem_buf_bio();
548 if (!certbio || !keybio) {
549 ec = error_category::create_mem_bio_failed;
553 std::unique_ptr<X509,
decltype(&X509_free)> cert(
554 PEM_read_bio_X509(certbio.get(),
nullptr,
nullptr,
const_cast<char*
>(pw.c_str())), X509_free);
556 ec = error_category::cert_load_failed;
559 std::unique_ptr<EVP_PKEY,
decltype(&EVP_PKEY_free)> key(X509_get_pubkey(cert.get()), EVP_PKEY_free);
561 ec = error_category::get_key_failed;
564 if (PEM_write_bio_PUBKEY(keybio.get(), key.get()) == 0) {
565 ec = error_category::write_key_failed;
569 return write_bio_to_string<error_category>(keybio, ec);
580 template<
typename error_category = error::rsa_error>
597 auto c_str =
reinterpret_cast<const unsigned char*
>(cert_der_str.c_str());
599 std::unique_ptr<X509,
decltype(&X509_free)> cert(
600 d2i_X509(NULL, &c_str,
static_cast<int>(cert_der_str.size())), X509_free);
601 auto certbio = make_mem_buf_bio();
602 if (!cert || !certbio) {
603 ec = error::rsa_error::create_mem_bio_failed;
607 if (!PEM_write_bio_X509(certbio.get(), cert.get())) {
608 ec = error::rsa_error::write_cert_failed;
612 return write_bio_to_string(certbio, ec);
629 template<
typename Decode>
631 std::error_code& ec) {
633 const auto decoded_str =
decode(cert_base64_der_str);
651 template<
typename Decode>
672#ifndef JWT_DISABLE_BASE64
683 auto decode = [](
const std::string& token) {
715 template<
typename error_category = error::rsa_error>
717 std::error_code& ec) {
719 auto pubkey_bio = make_mem_buf_bio();
721 ec = error_category::create_mem_bio_failed;
724 if (key.substr(0, 27) ==
"-----BEGIN CERTIFICATE-----") {
728 if (epkey.size() >
static_cast<std::size_t
>((std::numeric_limits<int>::max)())) {
729 ec = error_category::load_key_bio_write;
732 int len =
static_cast<int>(epkey.size());
733 if (BIO_write(pubkey_bio.get(), epkey.data(), len) != len) {
734 ec = error_category::load_key_bio_write;
739 if (key.size() >
static_cast<std::size_t
>((std::numeric_limits<int>::max)())) {
740 ec = error_category::load_key_bio_write;
743 int len =
static_cast<int>(key.size());
744 if (BIO_write(pubkey_bio.get(), key.data(), len) != len) {
745 ec = error_category::load_key_bio_write;
751 pubkey_bio.get(),
nullptr,
nullptr,
752 (
void*)password.data()));
753 if (!pkey) ec = error_category::load_key_bio_read;
767 template<
typename error_category = error::rsa_error>
783 template<
typename error_category = error::rsa_error>
785 std::error_code& ec) {
787 auto private_key_bio = make_mem_buf_bio();
788 if (!private_key_bio) {
789 ec = error_category::create_mem_bio_failed;
792 const int len =
static_cast<int>(key.size());
793 if (BIO_write(private_key_bio.get(), key.data(), len) != len) {
794 ec = error_category::load_key_bio_write;
798 PEM_read_bio_PrivateKey(private_key_bio.get(),
nullptr,
nullptr,
const_cast<char*
>(password.c_str())));
799 if (!pkey) ec = error_category::load_key_bio_read;
811 template<
typename error_category = error::rsa_error>
831 std::error_code& ec) {
841#ifdef JWT_OPENSSL_1_0_0
849 std::string res(BN_num_bytes(bn),
'\0');
850 BN_bn2bin(bn, (
unsigned char*)res.data());
859 inline std::unique_ptr<BIGNUM,
decltype(&BN_free)>
raw2bn(
const std::string& raw, std::error_code& ec) {
861 BN_bin2bn(
reinterpret_cast<const unsigned char*
>(raw.data()),
static_cast<int>(raw.size()),
nullptr);
864 ec = error::rsa_error::set_rsa_failed;
865 return {
nullptr, BN_free};
867 return {bn, BN_free};
874 inline std::unique_ptr<BIGNUM,
decltype(&BN_free)>
raw2bn(
const std::string& raw) {
876 auto res =
raw2bn(raw, ec);
893 const std::string& password =
"") {
910 std::error_code& ec) {
928 template<
typename Decode>
930 Decode
decode, std::error_code& ec) {
932 auto decoded_modulus =
decode(modulus);
933 auto decoded_exponent =
decode(exponent);
940#if defined(JWT_OPENSSL_3_0)
944 std::unique_ptr<OSSL_PARAM_BLD,
decltype(&OSSL_PARAM_BLD_free)> param_bld(OSSL_PARAM_BLD_new(),
945 OSSL_PARAM_BLD_free);
947 ec = error::rsa_error::create_context_failed;
951 if (OSSL_PARAM_BLD_push_BN(param_bld.get(),
"n", n.get()) != 1 ||
952 OSSL_PARAM_BLD_push_BN(param_bld.get(),
"e", e.get()) != 1) {
953 ec = error::rsa_error::set_rsa_failed;
957 std::unique_ptr<OSSL_PARAM,
decltype(&OSSL_PARAM_free)> params(OSSL_PARAM_BLD_to_param(param_bld.get()),
960 ec = error::rsa_error::set_rsa_failed;
964 std::unique_ptr<EVP_PKEY_CTX,
decltype(&EVP_PKEY_CTX_free)> ctx(
965 EVP_PKEY_CTX_new_from_name(
nullptr,
"RSA",
nullptr), EVP_PKEY_CTX_free);
967 ec = error::rsa_error::create_context_failed;
973 EVP_PKEY* pkey = NULL;
974 if (EVP_PKEY_fromdata_init(ctx.get()) <= 0 ||
975 EVP_PKEY_fromdata(ctx.get(), &pkey, EVP_PKEY_KEYPAIR, params.get()) <= 0) {
980 ec = error::rsa_error::cert_load_failed;
988 std::unique_ptr<RSA,
decltype(&RSA_free)> rsa(RSA_new(), RSA_free);
990#if defined(JWT_OPENSSL_1_1_1) || defined(JWT_OPENSSL_1_1_0)
993 if (RSA_set0_key(rsa.get(), n.get(), e.get(),
nullptr) == 1) {
1000 ec = error::rsa_error::set_rsa_failed;
1003#elif defined(JWT_OPENSSL_1_0_0)
1004 rsa->e = e.release();
1005 rsa->n = n.release();
1010 auto pub_key_bio = make_mem_buf_bio();
1012 ec = error::rsa_error::create_mem_bio_failed;
1016 auto write_pem_to_bio =
1017#if defined(JWT_OPENSSL_3_0)
1019 &PEM_write_bio_PUBKEY;
1021 &PEM_write_bio_RSA_PUBKEY;
1023 if (write_pem_to_bio(pub_key_bio.get(), rsa.get()) != 1) {
1024 ec = error::rsa_error::load_key_bio_write;
1028 return write_bio_to_string<error::rsa_error>(pub_key_bio, ec);
1044 template<
typename Decode>
1053#ifndef JWT_DISABLE_BASE64
1065 const std::string& exponent, std::error_code& ec) {
1066 auto decode = [](
const std::string& token) {
1081 const std::string& exponent) {
1098 const std::string& password =
"") {
1105#if defined(JWT_OPENSSL_3_0)
1114 inline std::string curve2group(
const std::string curve, std::error_code& ec) {
1115 if (curve ==
"P-256") {
1116 return "prime256v1";
1117 }
else if (curve ==
"P-384") {
1119 }
else if (curve ==
"P-521") {
1122 ec = jwt::error::ecdsa_error::unknown_curve;
1136 inline int curve2nid(
const std::string curve, std::error_code& ec) {
1137 if (curve ==
"P-256") {
1138 return NID_X9_62_prime256v1;
1139 }
else if (curve ==
"P-384") {
1140 return NID_secp384r1;
1141 }
else if (curve ==
"P-521") {
1142 return NID_secp521r1;
1144 ec = jwt::error::ecdsa_error::unknown_curve;
1166 template<
typename Decode>
1168 const std::string& y, Decode
decode, std::error_code& ec) {
1170 auto decoded_x =
decode(x);
1171 auto decoded_y =
decode(y);
1173#if defined(JWT_OPENSSL_3_0)
1177 std::unique_ptr<OSSL_PARAM_BLD,
decltype(&OSSL_PARAM_BLD_free)> param_bld(OSSL_PARAM_BLD_new(),
1178 OSSL_PARAM_BLD_free);
1180 ec = error::ecdsa_error::create_context_failed;
1184 std::string group = helper::curve2group(curve, ec);
1188 std::string pub = std::string(
"\x04").append(decoded_x).append(decoded_y);
1190 if (OSSL_PARAM_BLD_push_utf8_string(param_bld.get(),
"group", group.data(), group.size()) != 1 ||
1191 OSSL_PARAM_BLD_push_octet_string(param_bld.get(),
"pub", pub.data(), pub.size()) != 1) {
1192 ec = error::ecdsa_error::set_ecdsa_failed;
1196 std::unique_ptr<OSSL_PARAM,
decltype(&OSSL_PARAM_free)> params(OSSL_PARAM_BLD_to_param(param_bld.get()),
1199 ec = error::ecdsa_error::set_ecdsa_failed;
1203 std::unique_ptr<EVP_PKEY_CTX,
decltype(&EVP_PKEY_CTX_free)> ctx(
1204 EVP_PKEY_CTX_new_from_name(
nullptr,
"EC",
nullptr), EVP_PKEY_CTX_free);
1206 ec = error::ecdsa_error::create_context_failed;
1212 EVP_PKEY* pkey = NULL;
1213 if (EVP_PKEY_fromdata_init(ctx.get()) <= 0 ||
1214 EVP_PKEY_fromdata(ctx.get(), &pkey, EVP_PKEY_KEYPAIR, params.get()) <= 0) {
1217 EVP_PKEY_free(pkey);
1219 ec = error::ecdsa_error::cert_load_failed;
1235 std::unique_ptr<EC_GROUP,
decltype(&EC_GROUP_free)> ecgroup(EC_GROUP_new_by_curve_name(nid), EC_GROUP_free);
1237 ec = error::ecdsa_error::set_ecdsa_failed;
1241 EC_GROUP_set_asn1_flag(ecgroup.get(), OPENSSL_EC_NAMED_CURVE);
1243 std::unique_ptr<EC_POINT,
decltype(&EC_POINT_free)> ecpoint(EC_POINT_new(ecgroup.get()), EC_POINT_free);
1245 EC_POINT_set_affine_coordinates_GFp(ecgroup.get(), ecpoint.get(), qx.get(), qy.get(),
nullptr) != 1) {
1246 ec = error::ecdsa_error::set_ecdsa_failed;
1250 std::unique_ptr<EC_KEY,
decltype(&EC_KEY_free)> ecdsa(EC_KEY_new(), EC_KEY_free);
1251 if (!ecdsa || EC_KEY_set_group(ecdsa.get(), ecgroup.get()) != 1 ||
1252 EC_KEY_set_public_key(ecdsa.get(), ecpoint.get()) != 1) {
1253 ec = error::ecdsa_error::set_ecdsa_failed;
1259 auto pub_key_bio = make_mem_buf_bio();
1261 ec = error::ecdsa_error::create_mem_bio_failed;
1265 auto write_pem_to_bio =
1266#if defined(JWT_OPENSSL_3_0)
1268 &PEM_write_bio_PUBKEY;
1270 &PEM_write_bio_EC_PUBKEY;
1272 if (write_pem_to_bio(pub_key_bio.get(), ecdsa.get()) != 1) {
1273 ec = error::ecdsa_error::load_key_bio_write;
1277 return write_bio_to_string<error::ecdsa_error>(pub_key_bio, ec);
1294 template<
typename Decode>
1296 const std::string& y, Decode
decode) {
1303#ifndef JWT_DISABLE_BASE64
1316 const std::string& y, std::error_code& ec) {
1317 auto decode = [](
const std::string& token) {
1333 const std::string& y) {
1363 std::string
sign(
const std::string& , std::error_code& ec)
const {
1374 void verify(
const std::string& ,
const std::string& signature, std::error_code& ec)
const {
1376 if (!signature.empty()) { ec = error::signature_verification_error::invalid_signature; }
1379 std::string
name()
const {
return "none"; }
1393 : secret(std::move(key)), md(md), alg_name(std::move(
name)) {}
1401 std::string
sign(
const std::string& data, std::error_code& ec)
const {
1403 std::string res(
static_cast<size_t>(EVP_MAX_MD_SIZE),
'\0');
1404 auto len =
static_cast<unsigned int>(res.size());
1405 if (HMAC(md(), secret.data(),
static_cast<int>(secret.size()),
1406 reinterpret_cast<const unsigned char*
>(data.data()),
static_cast<int>(data.size()),
1407 (
unsigned char*)res.data(),
1409 ec = error::signature_generation_error::hmac_failed;
1422 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const {
1424 auto res =
sign(data, ec);
1427 bool matched =
true;
1428 for (
size_t i = 0; i < std::min<size_t>(res.size(), signature.size()); i++)
1429 if (res[i] != signature[i]) matched =
false;
1430 if (res.size() != signature.size()) matched =
false;
1432 ec = error::signature_verification_error::invalid_signature;
1441 std::string
name()
const {
return alg_name; }
1445 const std::string secret;
1447 const EVP_MD* (*md)();
1449 const std::string alg_name;
1465 rsa(
const std::string& public_key,
const std::string& private_key,
const std::string& public_key_password,
1466 const std::string& private_key_password,
const EVP_MD* (*md)(), std::string
name)
1467 : md(md), alg_name(std::move(
name)) {
1468 if (!private_key.empty()) {
1469 pkey = helper::load_private_key_from_string(private_key, private_key_password);
1470 }
else if (!public_key.empty()) {
1471 pkey = helper::load_public_key_from_string(public_key, public_key_password);
1483 : pkey(std::move(key_pair)), md(md), alg_name(std::move(
name)) {
1492 std::string
sign(
const std::string& data, std::error_code& ec)
const {
1494 auto ctx = helper::make_evp_md_ctx();
1496 ec = error::signature_generation_error::create_context_failed;
1499 if (!EVP_SignInit(ctx.get(), md())) {
1500 ec = error::signature_generation_error::signinit_failed;
1504 std::string res(EVP_PKEY_size(pkey.get()),
'\0');
1505 unsigned int len = 0;
1507 if (!EVP_SignUpdate(ctx.get(), data.data(), data.size())) {
1508 ec = error::signature_generation_error::signupdate_failed;
1511 if (EVP_SignFinal(ctx.get(), (
unsigned char*)res.data(), &len, pkey.get()) == 0) {
1512 ec = error::signature_generation_error::signfinal_failed;
1526 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const {
1528 auto ctx = helper::make_evp_md_ctx();
1530 ec = error::signature_verification_error::create_context_failed;
1533 if (!EVP_VerifyInit(ctx.get(), md())) {
1534 ec = error::signature_verification_error::verifyinit_failed;
1537 if (!EVP_VerifyUpdate(ctx.get(), data.data(), data.size())) {
1538 ec = error::signature_verification_error::verifyupdate_failed;
1541 auto res = EVP_VerifyFinal(ctx.get(),
reinterpret_cast<const unsigned char*
>(signature.data()),
1542 static_cast<unsigned int>(signature.size()), pkey.get());
1544 ec = error::signature_verification_error::verifyfinal_failed;
1552 std::string
name()
const {
return alg_name; }
1558 const EVP_MD* (*md)();
1560 const std::string alg_name;
1577 ecdsa(
const std::string& public_key,
const std::string& private_key,
const std::string& public_key_password,
1578 const std::string& private_key_password,
const EVP_MD* (*md)(), std::string
name,
size_t siglen)
1579 : md(md), alg_name(std::move(
name)), signature_length(siglen) {
1580 if (!private_key.empty()) {
1581 pkey = helper::load_private_ec_key_from_string(private_key, private_key_password);
1582 check_private_key(pkey.get());
1583 }
else if (!public_key.empty()) {
1584 pkey = helper::load_public_ec_key_from_string(public_key, public_key_password);
1585 check_public_key(pkey.get());
1587 throw error::ecdsa_exception(error::ecdsa_error::no_key_provided);
1591 size_t keysize = EVP_PKEY_bits(pkey.get());
1592 if (keysize != signature_length * 4 && (signature_length != 132 || keysize != 521))
1605 : pkey(std::move(key_pair)), md(md), alg_name(std::move(
name)), signature_length(siglen) {
1607 size_t keysize = EVP_PKEY_bits(pkey.get());
1608 if (keysize != signature_length * 4 && (signature_length != 132 || keysize != 521))
1618 std::string
sign(
const std::string& data, std::error_code& ec)
const {
1620 auto ctx = helper::make_evp_md_ctx();
1622 ec = error::signature_generation_error::create_context_failed;
1625 if (!EVP_DigestSignInit(ctx.get(),
nullptr, md(),
nullptr, pkey.get())) {
1626 ec = error::signature_generation_error::signinit_failed;
1629 if (!EVP_DigestUpdate(ctx.get(), data.data(),
static_cast<unsigned int>(data.size()))) {
1630 ec = error::signature_generation_error::digestupdate_failed;
1635 if (!EVP_DigestSignFinal(ctx.get(),
nullptr, &len)) {
1636 ec = error::signature_generation_error::signfinal_failed;
1639 std::string res(len,
'\0');
1640 if (!EVP_DigestSignFinal(ctx.get(), (
unsigned char*)res.data(), &len)) {
1641 ec = error::signature_generation_error::signfinal_failed;
1646 return der_to_p1363_signature(res, ec);
1655 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const {
1657 std::string der_signature = p1363_to_der_signature(signature, ec);
1660 auto ctx = helper::make_evp_md_ctx();
1662 ec = error::signature_verification_error::create_context_failed;
1665 if (!EVP_DigestVerifyInit(ctx.get(),
nullptr, md(),
nullptr, pkey.get())) {
1666 ec = error::signature_verification_error::verifyinit_failed;
1669 if (!EVP_DigestUpdate(ctx.get(), data.data(),
static_cast<unsigned int>(data.size()))) {
1670 ec = error::signature_verification_error::verifyupdate_failed;
1674#if OPENSSL_VERSION_NUMBER < 0x10002000L
1675 unsigned char* der_sig_data =
reinterpret_cast<unsigned char*
>(
const_cast<char*
>(der_signature.data()));
1677 const unsigned char* der_sig_data =
reinterpret_cast<const unsigned char*
>(der_signature.data());
1680 EVP_DigestVerifyFinal(ctx.get(), der_sig_data,
static_cast<unsigned int>(der_signature.length()));
1682 ec = error::signature_verification_error::invalid_signature;
1686 ec = error::signature_verification_error::verifyfinal_failed;
1694 std::string
name()
const {
return alg_name; }
1697 static void check_public_key(EVP_PKEY* pkey) {
1698#ifdef JWT_OPENSSL_3_0
1699 std::unique_ptr<EVP_PKEY_CTX,
decltype(&EVP_PKEY_CTX_free)> ctx(
1700 EVP_PKEY_CTX_new_from_pkey(
nullptr, pkey,
nullptr), EVP_PKEY_CTX_free);
1702 if (EVP_PKEY_public_check(ctx.get()) != 1) {
1706 std::unique_ptr<EC_KEY,
decltype(&EC_KEY_free)> eckey(EVP_PKEY_get1_EC_KEY(pkey), EC_KEY_free);
1707 if (!eckey) {
throw error::ecdsa_exception(error::ecdsa_error::invalid_key); }
1708 if (EC_KEY_check_key(eckey.get()) == 0)
throw error::ecdsa_exception(error::ecdsa_error::invalid_key);
1712 static void check_private_key(EVP_PKEY* pkey) {
1713#ifdef JWT_OPENSSL_3_0
1714 std::unique_ptr<EVP_PKEY_CTX,
decltype(&EVP_PKEY_CTX_free)> ctx(
1715 EVP_PKEY_CTX_new_from_pkey(
nullptr, pkey,
nullptr), EVP_PKEY_CTX_free);
1716 if (!ctx) {
throw error::ecdsa_exception(error::ecdsa_error::create_context_failed); }
1717 if (EVP_PKEY_private_check(ctx.get()) != 1) {
1718 throw error::ecdsa_exception(error::ecdsa_error::invalid_key);
1721 std::unique_ptr<EC_KEY,
decltype(&EC_KEY_free)> eckey(EVP_PKEY_get1_EC_KEY(pkey), EC_KEY_free);
1722 if (!eckey) {
throw error::ecdsa_exception(error::ecdsa_error::invalid_key); }
1723 if (EC_KEY_check_key(eckey.get()) == 0)
throw error::ecdsa_exception(error::ecdsa_error::invalid_key);
1727 std::string der_to_p1363_signature(
const std::string& der_signature, std::error_code& ec)
const {
1728 const unsigned char* possl_signature =
reinterpret_cast<const unsigned char*
>(der_signature.data());
1729 std::unique_ptr<ECDSA_SIG,
decltype(&ECDSA_SIG_free)> sig(
1730 d2i_ECDSA_SIG(
nullptr, &possl_signature,
static_cast<long>(der_signature.length())),
1733 ec = error::signature_generation_error::signature_decoding_failed;
1737#ifdef JWT_OPENSSL_1_0_0
1743 ECDSA_SIG_get0(sig.get(), &r, &s);
1747 if (rr.size() > signature_length / 2 || rs.size() > signature_length / 2)
1748 throw std::logic_error(
"bignum size exceeded expected length");
1749 rr.insert(0, signature_length / 2 - rr.size(),
'\0');
1750 rs.insert(0, signature_length / 2 - rs.size(),
'\0');
1754 std::string p1363_to_der_signature(
const std::string& signature, std::error_code& ec)
const {
1756 auto r =
helper::raw2bn(signature.substr(0, signature.size() / 2), ec);
1758 auto s =
helper::raw2bn(signature.substr(signature.size() / 2), ec);
1762#ifdef JWT_OPENSSL_1_0_0
1768 std::unique_ptr<ECDSA_SIG,
decltype(&ECDSA_SIG_free)> sig(ECDSA_SIG_new(), ECDSA_SIG_free);
1770 ec = error::signature_verification_error::create_context_failed;
1773 ECDSA_SIG_set0(sig.get(), r.release(), s.release());
1777 int length = i2d_ECDSA_SIG(psig,
nullptr);
1779 ec = error::signature_verification_error::signature_encoding_failed;
1782 std::string der_signature(length,
'\0');
1783 unsigned char* psbuffer = (
unsigned char*)der_signature.data();
1784 length = i2d_ECDSA_SIG(psig, &psbuffer);
1786 ec = error::signature_verification_error::signature_encoding_failed;
1789 der_signature.resize(length);
1790 return der_signature;
1794 helper::evp_pkey_handle pkey;
1796 const EVP_MD* (*md)();
1798 const std::string alg_name;
1800 const size_t signature_length;
1803#if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
1824 eddsa(
const std::string& public_key,
const std::string& private_key,
const std::string& public_key_password,
1825 const std::string& private_key_password, std::string
name)
1826 : alg_name(std::move(
name)) {
1827 if (!private_key.empty()) {
1828 pkey = helper::load_private_key_from_string(private_key, private_key_password);
1829 }
else if (!public_key.empty()) {
1830 pkey = helper::load_public_key_from_string(public_key, public_key_password);
1840 std::string
sign(
const std::string& data, std::error_code& ec)
const {
1842 auto ctx = helper::make_evp_md_ctx();
1844 ec = error::signature_generation_error::create_context_failed;
1847 if (!EVP_DigestSignInit(ctx.get(),
nullptr,
nullptr,
nullptr, pkey.get())) {
1848 ec = error::signature_generation_error::signinit_failed;
1852 size_t len = EVP_PKEY_size(pkey.get());
1853 std::string res(len,
'\0');
1857#if defined(LIBWOLFSSL_VERSION_HEX)
1859 if (EVP_DigestSignUpdate(ctx.get(),
reinterpret_cast<const unsigned char*
>(data.data()), data.size()) !=
1861 std::cout << ERR_error_string(ERR_get_error(), NULL) <<
'\n';
1862 ec = error::signature_generation_error::signupdate_failed;
1865 if (EVP_DigestSignFinal(ctx.get(),
reinterpret_cast<unsigned char*
>(&res[0]), &len) != 1) {
1866 ec = error::signature_generation_error::signfinal_failed;
1870 if (EVP_DigestSign(ctx.get(),
reinterpret_cast<unsigned char*
>(&res[0]), &len,
1871 reinterpret_cast<const unsigned char*
>(data.data()), data.size()) != 1) {
1872 ec = error::signature_generation_error::signfinal_failed;
1887 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const {
1889 auto ctx = helper::make_evp_md_ctx();
1891 ec = error::signature_verification_error::create_context_failed;
1894 if (!EVP_DigestVerifyInit(ctx.get(),
nullptr,
nullptr,
nullptr, pkey.get())) {
1895 ec = error::signature_verification_error::verifyinit_failed;
1900#if defined(LIBWOLFSSL_VERSION_HEX)
1901 if (EVP_DigestVerifyUpdate(ctx.get(),
reinterpret_cast<const unsigned char*
>(data.data()),
1902 data.size()) != 1) {
1903 ec = error::signature_verification_error::verifyupdate_failed;
1906 if (EVP_DigestVerifyFinal(ctx.get(),
reinterpret_cast<const unsigned char*
>(signature.data()),
1907 signature.size()) != 1) {
1908 ec = error::signature_verification_error::verifyfinal_failed;
1912 auto res = EVP_DigestVerify(ctx.get(),
reinterpret_cast<const unsigned char*
>(signature.data()),
1913 signature.size(),
reinterpret_cast<const unsigned char*
>(data.data()),
1916 ec = error::signature_verification_error::verifyfinal_failed;
1925 std::string
name()
const {
return alg_name; }
1931 const std::string alg_name;
1947 pss(
const std::string& public_key,
const std::string& private_key,
const std::string& public_key_password,
1948 const std::string& private_key_password,
const EVP_MD* (*md)(), std::string
name)
1949 : md(md), alg_name(std::move(
name)) {
1950 if (!private_key.empty()) {
1951 pkey = helper::load_private_key_from_string(private_key, private_key_password);
1952 }
else if (!public_key.empty()) {
1953 pkey = helper::load_public_key_from_string(public_key, public_key_password);
1964 std::string
sign(
const std::string& data, std::error_code& ec)
const {
1966 auto md_ctx = helper::make_evp_md_ctx();
1968 ec = error::signature_generation_error::create_context_failed;
1971 EVP_PKEY_CTX* ctx =
nullptr;
1972 if (EVP_DigestSignInit(md_ctx.get(), &ctx, md(),
nullptr, pkey.get()) != 1) {
1973 ec = error::signature_generation_error::signinit_failed;
1976 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
1977 ec = error::signature_generation_error::rsa_padding_failed;
1982#ifndef LIBWOLFSSL_VERSION_HEX
1983 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0) {
1984 ec = error::signature_generation_error::set_rsa_pss_saltlen_failed;
1988 if (EVP_DigestUpdate(md_ctx.get(), data.data(),
static_cast<unsigned int>(data.size())) != 1) {
1989 ec = error::signature_generation_error::digestupdate_failed;
1993 size_t size = EVP_PKEY_size(pkey.get());
1994 std::string res(size, 0x00);
1995 if (EVP_DigestSignFinal(
1997 (
unsigned char*)res.data(),
1999 ec = error::signature_generation_error::signfinal_failed;
2012 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const {
2015 auto md_ctx = helper::make_evp_md_ctx();
2017 ec = error::signature_verification_error::create_context_failed;
2020 EVP_PKEY_CTX* ctx =
nullptr;
2021 if (EVP_DigestVerifyInit(md_ctx.get(), &ctx, md(),
nullptr, pkey.get()) != 1) {
2022 ec = error::signature_verification_error::verifyinit_failed;
2025 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
2026 ec = error::signature_generation_error::rsa_padding_failed;
2031#ifndef LIBWOLFSSL_VERSION_HEX
2032 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0) {
2033 ec = error::signature_verification_error::set_rsa_pss_saltlen_failed;
2037 if (EVP_DigestUpdate(md_ctx.get(), data.data(),
static_cast<unsigned int>(data.size())) != 1) {
2038 ec = error::signature_verification_error::verifyupdate_failed;
2042 if (EVP_DigestVerifyFinal(md_ctx.get(), (
unsigned char*)signature.data(), signature.size()) <= 0) {
2043 ec = error::signature_verification_error::verifyfinal_failed;
2051 std::string
name()
const {
return alg_name; }
2057 const EVP_MD* (*md)();
2059 const std::string alg_name;
2070 explicit hs256(std::string key) :
hmacsha(std::move(key), EVP_sha256,
"HS256") {}
2080 explicit hs384(std::string key) :
hmacsha(std::move(key), EVP_sha384,
"HS384") {}
2090 explicit hs512(std::string key) :
hmacsha(std::move(key), EVP_sha512,
"HS512") {}
2106 explicit rs256(
const std::string& public_key,
const std::string& private_key =
"",
2107 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2108 :
rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
"RS256") {}
2121 explicit rs384(
const std::string& public_key,
const std::string& private_key =
"",
2122 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2123 :
rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384,
"RS384") {}
2136 explicit rs512(
const std::string& public_key,
const std::string& private_key =
"",
2137 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2138 :
rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512,
"RS512") {}
2153 explicit es256(
const std::string& public_key,
const std::string& private_key =
"",
2154 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2155 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
"ES256", 64) {}
2170 explicit es384(
const std::string& public_key,
const std::string& private_key =
"",
2171 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2172 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384,
"ES384", 96) {}
2187 explicit es512(
const std::string& public_key,
const std::string& private_key =
"",
2188 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2189 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512,
"ES512", 132) {}
2203 explicit es256k(
const std::string& public_key,
const std::string& private_key =
"",
2204 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2205 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
"ES256K", 64) {}
2208#if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
2226 explicit ed25519(
const std::string& public_key,
const std::string& private_key =
"",
2227 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2228 :
eddsa(public_key, private_key, public_key_password, private_key_password,
"EdDSA") {}
2231#if !defined(LIBRESSL_VERSION_NUMBER)
2249 explicit ed448(
const std::string& public_key,
const std::string& private_key =
"",
2250 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2251 :
eddsa(public_key, private_key, public_key_password, private_key_password,
"EdDSA") {}
2267 explicit ps256(
const std::string& public_key,
const std::string& private_key =
"",
2268 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2269 :
pss(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
"PS256") {}
2282 explicit ps384(
const std::string& public_key,
const std::string& private_key =
"",
2283 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2284 :
pss(public_key, private_key, public_key_password, private_key_password, EVP_sha384,
"PS384") {}
2297 explicit ps512(
const std::string& public_key,
const std::string& private_key =
"",
2298 const std::string& public_key_password =
"",
const std::string& private_key_password =
"")
2299 :
pss(public_key, private_key, public_key_password, private_key_password, EVP_sha512,
"PS512") {}
2314 enum class type { boolean, integer, number, string, array,
object };
2318#ifdef __cpp_lib_void_t
2319 template<
typename... Ts>
2320 using void_t = std::void_t<Ts...>;
2323 template<
typename... Ts>
2328 template<
typename... Ts>
2329 using void_t =
typename make_void<Ts...>::type;
2332#ifdef __cpp_lib_experimental_detect
2333 template<
template<
typename...>
class _Op,
typename... _Args>
2334 using is_detected = std::experimental::is_detected<_Op, _Args...>;
2337 nonesuch() =
delete;
2338 ~nonesuch() =
delete;
2339 nonesuch(nonesuch
const&) =
delete;
2340 nonesuch(nonesuch
const&&) =
delete;
2341 void operator=(nonesuch
const&) =
delete;
2342 void operator=(nonesuch&&) =
delete;
2346 template<
class Default,
class AlwaysVoid,
template<
class...>
class Op,
class... Args>
2348 using value = std::false_type;
2349 using type = Default;
2352 template<
class Default,
template<
class...>
class Op,
class... Args>
2353 struct detector<Default, void_t<Op<Args...>>, Op, Args...> {
2354 using value = std::true_type;
2355 using type = Op<Args...>;
2358 template<
template<
class...>
class Op,
class... Args>
2359 using is_detected =
typename detector<nonesuch, void, Op, Args...>::value;
2362 template<
typename T,
typename Signature>
2363 using is_signature =
typename std::is_same<T, Signature>;
2365 template<
typename traits_type,
template<
typename...>
class Op,
typename Signature>
2366 struct is_function_signature_detected {
2367 using type = Op<traits_type>;
2368 static constexpr auto value = is_detected<Op, traits_type>::value && std::is_function<type>::value &&
2369 is_signature<type, Signature>::value;
2372 template<
typename traits_type,
typename value_type>
2373 struct supports_get_type {
2374 template<
typename T>
2375 using get_type_t =
decltype(T::get_type);
2377 static constexpr auto value =
2378 is_function_signature_detected<traits_type, get_type_t,
json::type(
const value_type&)>::value;
2381 static_assert(value,
"traits implementation must provide `jwt::json::type get_type(const value_type&)`");
2384#define JWT_CPP_JSON_TYPE_TYPE(TYPE) json_##TYPE_type
2385#define JWT_CPP_AS_TYPE_T(TYPE) as_##TYPE_t
2386#define JWT_CPP_SUPPORTS_AS(TYPE) \
2387 template<typename traits_type, typename value_type, typename JWT_CPP_JSON_TYPE_TYPE(TYPE)> \
2388 struct supports_as_##TYPE { \
2389 template<typename T> \
2390 using JWT_CPP_AS_TYPE_T(TYPE) = decltype(T::as_##TYPE); \
2392 static constexpr auto value = \
2393 is_function_signature_detected<traits_type, JWT_CPP_AS_TYPE_T(TYPE), \
2394 JWT_CPP_JSON_TYPE_TYPE(TYPE)(const value_type&)>::value; \
2396 static_assert(value, "traits implementation must provide `" #TYPE "_type as_" #TYPE "(const value_type&)`"); \
2399 JWT_CPP_SUPPORTS_AS(
object);
2400 JWT_CPP_SUPPORTS_AS(array);
2401 JWT_CPP_SUPPORTS_AS(
string);
2402 JWT_CPP_SUPPORTS_AS(number);
2403 JWT_CPP_SUPPORTS_AS(integer);
2404 JWT_CPP_SUPPORTS_AS(
boolean);
2406#undef JWT_CPP_JSON_TYPE_TYPE
2407#undef JWT_CPP_AS_TYPE_T
2408#undef JWT_CPP_SUPPORTS_AS
2410 template<
typename traits>
2411 struct is_valid_traits {
2412 static constexpr auto value =
2413 supports_get_type<traits, typename traits::value_type>::value &&
2414 supports_as_object<traits, typename traits::value_type, typename traits::object_type>::value &&
2415 supports_as_array<traits, typename traits::value_type, typename traits::array_type>::value &&
2416 supports_as_string<traits, typename traits::value_type, typename traits::string_type>::value &&
2417 supports_as_number<traits, typename traits::value_type, typename traits::number_type>::value &&
2418 supports_as_integer<traits, typename traits::value_type, typename traits::integer_type>::value &&
2419 supports_as_boolean<traits, typename traits::value_type, typename traits::boolean_type>::value;
2422 template<
typename value_type>
2423 struct is_valid_json_value {
2424 static constexpr auto value =
2425 std::is_default_constructible<value_type>::value &&
2426 std::is_constructible<value_type, const value_type&>::value &&
2427 std::is_move_constructible<value_type>::value && std::is_assignable<value_type, value_type>::value &&
2428 std::is_copy_assignable<value_type>::value && std::is_move_assignable<value_type>::value;
2433 template<
typename T,
typename =
void>
2434 struct is_iterable : std::false_type {};
2436 template<
typename T>
2437 struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>())),
2438#if __cplusplus > 201402L
2439 decltype(std::cbegin(std::declval<T>())), decltype(std::cend(std::declval<T>()))
2441 decltype(std::begin(std::declval<const T>())),
2442 decltype(std::end(std::declval<const T>()))
2444 >> : std::true_type {
2447#if __cplusplus > 201703L
2448 template<
typename T>
2449 inline constexpr bool is_iterable_v = is_iterable<T>::value;
2452 template<
typename object_type,
typename string_type>
2453 using is_count_signature =
typename std::is_integral<decltype(std::declval<const object_type>().count(
2454 std::declval<const string_type>()))>;
2456 template<
typename object_type,
typename string_type,
typename =
void>
2457 struct is_subcription_operator_signature : std::false_type {};
2459 template<
typename object_type,
typename string_type>
2460 struct is_subcription_operator_signature<
2461 object_type, string_type,
2462 void_t<decltype(std::declval<object_type>().operator[](std::declval<string_type>()))>> : std::true_type {
2466 "object_type must implementate the subscription operator '[]' taking string_type as an argument");
2469 template<
typename object_type,
typename value_type,
typename string_type>
2470 using is_at_const_signature =
2471 typename std::is_same<decltype(std::declval<const object_type>().at(std::declval<const string_type>())),
2474 template<
typename value_type,
typename string_type,
typename object_type>
2475 struct is_valid_json_object {
2476 template<
typename T>
2477 using mapped_type_t =
typename T::mapped_type;
2478 template<
typename T>
2479 using key_type_t =
typename T::key_type;
2480 template<
typename T>
2481 using iterator_t =
typename T::iterator;
2482 template<
typename T>
2483 using const_iterator_t =
typename T::const_iterator;
2485 static constexpr auto value =
2486 std::is_constructible<value_type, object_type>::value &&
2487 is_detected<mapped_type_t, object_type>::value &&
2488 std::is_same<typename object_type::mapped_type, value_type>::value &&
2489 is_detected<key_type_t, object_type>::value &&
2490 (std::is_same<typename object_type::key_type, string_type>::value ||
2491 std::is_constructible<typename object_type::key_type, string_type>::value) &&
2492 is_detected<iterator_t, object_type>::value && is_detected<const_iterator_t, object_type>::value &&
2493 is_iterable<object_type>::value && is_count_signature<object_type, string_type>::value &&
2494 is_subcription_operator_signature<object_type, string_type>::value &&
2495 is_at_const_signature<object_type, value_type, string_type>::value;
2498 template<
typename value_type,
typename array_type>
2499 struct is_valid_json_array {
2500 template<
typename T>
2501 using value_type_t =
typename T::value_type;
2502 using front_base_type =
typename std::decay<decltype(std::declval<array_type>().front())>::type;
2504 static constexpr auto value = std::is_constructible<value_type, array_type>::value &&
2505 is_iterable<array_type>::value &&
2506 is_detected<value_type_t, array_type>::value &&
2507 std::is_same<typename array_type::value_type, value_type>::value &&
2508 std::is_same<front_base_type, value_type>::value;
2511 template<
typename string_type,
typename integer_type>
2512 using is_substr_start_end_index_signature =
2513 typename std::is_same<decltype(std::declval<string_type>().substr(
2514 static_cast<size_t>(std::declval<integer_type>()),
2515 static_cast<size_t>(std::declval<integer_type>()))),
2518 template<
typename string_type,
typename integer_type>
2519 using is_substr_start_index_signature =
2520 typename std::is_same<decltype(std::declval<string_type>().substr(
2521 static_cast<size_t>(std::declval<integer_type>()))),
2524 template<
typename string_type>
2525 using is_std_operate_plus_signature =
2526 typename std::is_same<decltype(std::operator+(std::declval<string_type>(), std::declval<string_type>())),
2529 template<
typename value_type,
typename string_type,
typename integer_type>
2530 struct is_valid_json_string {
2531 static constexpr auto substr = is_substr_start_end_index_signature<string_type, integer_type>::value &&
2532 is_substr_start_index_signature<string_type, integer_type>::value;
2533 static_assert(substr,
"string_type must have a substr method taking only a start index and an overload "
2534 "taking a start and end index, both must return a string_type");
2536 static constexpr auto operator_plus = is_std_operate_plus_signature<string_type>::value;
2537 static_assert(operator_plus,
2538 "string_type must have a '+' operator implemented which returns the concatenated string");
2540 static constexpr auto value =
2541 std::is_constructible<value_type, string_type>::value && substr && operator_plus;
2544 template<
typename value_type,
typename number_type>
2545 struct is_valid_json_number {
2546 static constexpr auto value =
2547 std::is_floating_point<number_type>::value && std::is_constructible<value_type, number_type>::value;
2550 template<
typename value_type,
typename integer_type>
2551 struct is_valid_json_integer {
2552 static constexpr auto value = std::is_signed<integer_type>::value &&
2553 !std::is_floating_point<integer_type>::value &&
2554 std::is_constructible<value_type, integer_type>::value;
2556 template<
typename value_type,
typename boolean_type>
2557 struct is_valid_json_boolean {
2558 static constexpr auto value = std::is_convertible<boolean_type, bool>::value &&
2559 std::is_constructible<value_type, boolean_type>::value;
2562 template<
typename value_type,
typename object_type,
typename array_type,
typename string_type,
2563 typename number_type,
typename integer_type,
typename boolean_type>
2564 struct is_valid_json_types {
2566 static_assert(is_valid_json_value<value_type>::value,
2567 "value_type must meet basic requirements, default constructor, copyable, moveable");
2568 static_assert(is_valid_json_object<value_type, string_type, object_type>::value,
2569 "object_type must be a string_type to value_type container");
2570 static_assert(is_valid_json_array<value_type, array_type>::value,
2571 "array_type must be a container of value_type");
2573 static constexpr auto value = is_valid_json_value<value_type>::value &&
2574 is_valid_json_object<value_type, string_type, object_type>::value &&
2575 is_valid_json_array<value_type, array_type>::value &&
2576 is_valid_json_string<value_type, string_type, integer_type>::value &&
2577 is_valid_json_number<value_type, number_type>::value &&
2578 is_valid_json_integer<value_type, integer_type>::value &&
2579 is_valid_json_boolean<value_type, boolean_type>::value;
2590 template<
typename json_traits>
2598 static_assert(std::is_same<typename json_traits::string_type, std::string>::value ||
2599 std::is_convertible<typename json_traits::string_type, std::string>::value ||
2600 std::is_constructible<typename json_traits::string_type, std::string>::value,
2601 "string_type must be a std::string, convertible to a std::string, or construct a std::string.");
2604 details::is_valid_json_types<
typename json_traits::value_type,
typename json_traits::object_type,
2605 typename json_traits::array_type,
typename json_traits::string_type,
2606 typename json_traits::number_type,
typename json_traits::integer_type,
2607 typename json_traits::boolean_type>::value,
2608 "must satisfy json container requirements");
2609 static_assert(details::is_valid_traits<json_traits>::value,
"traits must satisfy requirements");
2611 typename json_traits::value_type val;
2617 using set_t = std::set<typename json_traits::string_type>;
2619 basic_claim() =
default;
2620 basic_claim(
const basic_claim&) =
default;
2621 basic_claim(basic_claim&&) =
default;
2622 basic_claim& operator=(
const basic_claim&) =
default;
2623 basic_claim& operator=(basic_claim&&) =
default;
2624 ~basic_claim() =
default;
2626 JWT_CLAIM_EXPLICIT basic_claim(
typename json_traits::string_type s) : val(std::move(s)) {}
2628 : val(typename json_traits::integer_type(
2629 std::chrono::duration_cast<std::chrono::seconds>(d.time_since_epoch()).count())) {}
2630 JWT_CLAIM_EXPLICIT basic_claim(
typename json_traits::array_type a) : val(std::move(a)) {}
2631 JWT_CLAIM_EXPLICIT basic_claim(
typename json_traits::value_type v) : val(std::move(v)) {}
2632 JWT_CLAIM_EXPLICIT basic_claim(
const set_t& s) : val(typename json_traits::array_type(s.begin(), s.end())) {}
2633 template<
typename Iterator>
2634 basic_claim(Iterator begin, Iterator end) : val(typename json_traits::array_type(begin, end)) {}
2640 typename json_traits::value_type
to_json()
const {
return val; }
2666 typename json_traits::string_type
as_string()
const {
return json_traits::as_string(val); }
2677 using std::chrono::system_clock;
2678 if (
get_type() == json::type::number)
2679 return date(std::chrono::seconds(
static_cast<int64_t
>(std::llround(
as_number()))));
2688 typename json_traits::array_type
as_array()
const {
return json_traits::as_array(val); }
2697 for (
const auto& e : json_traits::as_array(val)) {
2698 res.insert(json_traits::as_string(e));
2708 typename json_traits::integer_type
as_integer()
const {
return json_traits::as_integer(val); }
2715 typename json_traits::boolean_type
as_boolean()
const {
return json_traits::as_boolean(val); }
2722 typename json_traits::number_type
as_number()
const {
return json_traits::as_number(val); }
2729 struct invalid_json_exception :
public std::runtime_error {
2730 invalid_json_exception() : runtime_error(
"invalid json") {}
2735 struct claim_not_present_exception :
public std::out_of_range {
2736 claim_not_present_exception() : out_of_range(
"claim not found") {}
2741 template<
typename json_traits>
2742 struct map_of_claims {
2743 typename json_traits::object_type claims;
2745 using iterator =
typename json_traits::object_type::iterator;
2746 using const_iterator =
typename json_traits::object_type::const_iterator;
2748 map_of_claims() =
default;
2749 map_of_claims(
const map_of_claims&) =
default;
2750 map_of_claims(map_of_claims&&) =
default;
2751 map_of_claims& operator=(
const map_of_claims&) =
default;
2752 map_of_claims& operator=(map_of_claims&&) =
default;
2754 map_of_claims(
typename json_traits::object_type
json) : claims(std::move(
json)) {}
2756 iterator begin() {
return claims.begin(); }
2757 iterator end() {
return claims.end(); }
2758 const_iterator cbegin()
const {
return claims.begin(); }
2759 const_iterator cend()
const {
return claims.end(); }
2760 const_iterator begin()
const {
return claims.begin(); }
2761 const_iterator end()
const {
return claims.end(); }
2771 static typename json_traits::object_type parse_claims(
const typename json_traits::string_type& str) {
2772 typename json_traits::value_type val;
2773 if (!json_traits::parse(val, str))
throw error::invalid_json_exception();
2775 return json_traits::as_object(val);
2782 bool has_claim(
const typename json_traits::string_type& name)
const noexcept {
2783 return claims.count(name) != 0;
2793 basic_claim_t get_claim(
const typename json_traits::string_type& name)
const {
2794 if (!has_claim(name))
throw error::claim_not_present_exception();
2795 return basic_claim_t{claims.at(name)};
2804 template<
typename json_traits>
2807 details::map_of_claims<json_traits> payload_claims;
2869 if (aud.get_type() == json::type::string)
return {aud.as_string()};
2871 return aud.as_set();
2906 return payload_claims.has_claim(name);
2914 return payload_claims.get_claim(name);
2922 template<
typename json_traits>
2925 details::map_of_claims<json_traits> header_claims;
2982 return header_claims.has_claim(name);
2990 return header_claims.get_claim(name);
2997 template<
typename json_traits>
3001 typename json_traits::string_type
token;
3017#ifndef JWT_DISABLE_BASE64
3043 template<
typename Decode>
3045 auto hdr_end =
token.find(
'.');
3046 if (hdr_end == json_traits::string_type::npos)
throw std::invalid_argument(
"invalid token supplied");
3047 auto payload_end =
token.find(
'.', hdr_end + 1);
3048 if (payload_end == json_traits::string_type::npos)
throw std::invalid_argument(
"invalid token supplied");
3057 this->header_claims = details::map_of_claims<json_traits>::parse_claims(
header);
3058 this->payload_claims = details::map_of_claims<json_traits>::parse_claims(
payload);
3065 const typename json_traits::string_type&
get_token() const noexcept {
return token; }
3100 typename json_traits::object_type
get_payload_json()
const {
return this->payload_claims.claims; }
3105 typename json_traits::object_type
get_header_json()
const {
return this->header_claims.claims; }
3114 return this->payload_claims.get_claim(name);
3124 return this->header_claims.get_claim(name);
3132 template<
typename Clock,
typename json_traits>
3134 typename json_traits::object_type header_claims;
3135 typename json_traits::object_type payload_claims;
3153 header_claims[id] = std::move(c);
3164 header_claims[id] = c.
to_json();
3174 payload_claims[id] = std::move(c);
3184 payload_claims[id] = c.
to_json();
3265 template<
class Rep,
class Period>
3306 template<
typename Algo,
typename Encode>
3307 typename json_traits::string_type
sign(
const Algo& algo, Encode encode)
const {
3309 auto res =
sign(algo, encode, ec);
3313#ifndef JWT_DISABLE_BASE64
3322 template<
typename Algo>
3323 typename json_traits::string_type
sign(
const Algo& algo)
const {
3325 auto res =
sign(algo, ec);
3343 template<
typename Algo,
typename Encode>
3344 typename json_traits::string_type
sign(
const Algo& algo, Encode encode, std::error_code& ec)
const {
3346 typename json_traits::object_type obj_header = header_claims;
3347 if (header_claims.count(
"alg") == 0) obj_header[
"alg"] =
typename json_traits::value_type(algo.name());
3349 const auto header = encode(json_traits::serialize(
typename json_traits::value_type(obj_header)));
3350 const auto payload = encode(json_traits::serialize(
typename json_traits::value_type(payload_claims)));
3353 auto signature = algo.sign(token, ec);
3356 return token +
"." + encode(signature);
3358#ifndef JWT_DISABLE_BASE64
3368 template<
typename Algo>
3369 typename json_traits::string_type
sign(
const Algo& algo, std::error_code& ec)
const {
3372 [](
const typename json_traits::string_type& data) {
3380 namespace verify_ops {
3384 template<
typename json_traits>
3385 struct verify_context {
3407 ec = error::token_verification_error::missing_claim;
3413 ec = error::token_verification_error::missing_claim;
3429 if (c.get_type() != t) {
3430 ec = error::token_verification_error::claim_type_missmatch;
3455 template<
typename json_traits,
bool in_header = false>
3459 auto jc = ctx.
get_claim(in_header, expected.get_type(), ec);
3461 const bool matches = [&]() {
3462 switch (expected.get_type()) {
3463 case json::type::boolean:
return expected.as_boolean() == jc.as_boolean();
3464 case json::type::integer:
return expected.as_integer() == jc.as_integer();
3465 case json::type::number:
return expected.as_number() == jc.as_number();
3466 case json::type::string:
return expected.as_string() == jc.as_string();
3467 case json::type::array:
3468 case json::type::object:
3469 return json_traits::serialize(expected.to_json()) == json_traits::serialize(jc.to_json());
3470 default:
throw std::logic_error(
"internal error, should be unreachable");
3474 ec = error::token_verification_error::claim_value_missmatch;
3484 template<
typename json_traits,
bool in_header = false>
3486 const size_t leeway;
3488 auto jc = ctx.
get_claim(in_header, json::type::integer, ec);
3490 auto c = jc.as_date();
3491 if (ctx.
current_time > c + std::chrono::seconds(leeway)) {
3492 ec = error::token_verification_error::token_expired;
3501 template<
typename json_traits,
bool in_header = false>
3503 const size_t leeway;
3505 auto jc = ctx.
get_claim(in_header, json::type::integer, ec);
3507 auto c = jc.as_date();
3508 if (ctx.
current_time < c - std::chrono::seconds(leeway)) {
3509 ec = error::token_verification_error::token_expired;
3519 template<
typename json_traits,
bool in_header = false>
3525 if (c.get_type() == json::type::string) {
3526 if (expected.size() != 1 || *expected.begin() != c.as_string()) {
3527 ec = error::token_verification_error::audience_missmatch;
3530 }
else if (c.get_type() == json::type::array) {
3531 auto jc = c.as_set();
3532 for (
auto& e : expected) {
3533 if (jc.find(e) == jc.end()) {
3534 ec = error::token_verification_error::audience_missmatch;
3539 ec = error::token_verification_error::claim_type_missmatch;
3548 template<
typename json_traits,
bool in_header = false>
3549 struct insensitive_string_claim {
3550 const typename json_traits::string_type expected;
3552 insensitive_string_claim(
const typename json_traits::string_type& e, std::locale loc)
3553 : expected(to_lower_unicode(e, loc)), locale(loc) {}
3556 const auto c = ctx.
get_claim(in_header, json::type::string, ec);
3558 if (to_lower_unicode(c.as_string(), locale) != expected) {
3559 ec = error::token_verification_error::claim_value_missmatch;
3563 static std::string to_lower_unicode(
const std::string& str,
const std::locale& loc) {
3564 std::mbstate_t state = std::mbstate_t();
3565 const char* in_next = str.data();
3566 const char* in_end = str.data() + str.size();
3568 wide.reserve(str.size());
3570 while (in_next != in_end) {
3572 std::size_t result = std::mbrtowc(&wc, in_next, in_end - in_next, &state);
3573 if (result ==
static_cast<std::size_t
>(-1)) {
3574 throw std::runtime_error(
"encoding error: " + std::string(std::strerror(errno)));
3575 }
else if (result ==
static_cast<std::size_t
>(-2)) {
3576 throw std::runtime_error(
"conversion error: next bytes constitute an incomplete, but so far "
3577 "valid, multibyte character.");
3583 auto& f = std::use_facet<std::ctype<wchar_t>>(loc);
3584 f.tolower(&wide[0], &wide[0] + wide.size());
3587 out.reserve(wide.size());
3588 for (
wchar_t wc : wide) {
3589 char mb[MB_LEN_MAX];
3590 std::size_t n = std::wcrtomb(mb, wc, &state);
3591 if (n !=
static_cast<std::size_t
>(-1)) out.append(mb, n);
3603 template<
typename Clock,
typename json_traits>
3621 virtual ~algo_base() =
default;
3622 virtual void verify(
const std::string& data,
const std::string& sig, std::error_code& ec) = 0;
3624 template<
typename T>
3625 struct algo :
public algo_base {
3627 explicit algo(T a) : alg(a) {}
3628 void verify(
const std::string& data,
const std::string& sig, std::error_code& ec)
override {
3629 alg.verify(data, sig, ec);
3633 std::unordered_map<typename json_traits::string_type, verify_check_fn_t> claims;
3635 size_t default_leeway = 0;
3639 std::unordered_map<std::string, std::shared_ptr<algo_base>> algs;
3648 if (!ctx.
jwt.has_expires_at())
return;
3649 auto exp = ctx.
jwt.get_expires_at();
3651 ec = error::token_verification_error::token_expired;
3655 if (!ctx.
jwt.has_issued_at())
return;
3656 auto iat = ctx.
jwt.get_issued_at();
3658 ec = error::token_verification_error::token_expired;
3662 if (!ctx.
jwt.has_not_before())
return;
3663 auto nbf = ctx.
jwt.get_not_before();
3665 ec = error::token_verification_error::token_expired;
3721 verifier&
with_type(
const typename json_traits::string_type& type, std::locale locale = std::locale{}) {
3732 return with_claim(
"iss", basic_claim_t(iss));
3742 return with_claim(
"sub", basic_claim_t(sub));
3816 template<
typename Algorithm>
3818 algs[alg.name()] = std::make_shared<algo<Algorithm>>(alg);
3839 const typename json_traits::string_type data =
jwt.get_header_base64() +
"." +
jwt.get_payload_base64();
3840 const typename json_traits::string_type sig =
jwt.get_signature();
3841 const std::string algo =
jwt.get_algorithm();
3842 if (algs.count(algo) == 0) {
3843 ec = error::token_verification_error::wrong_algorithm;
3846 algs.at(algo)->verify(data, sig, ec);
3850 for (
auto& c : claims) {
3866 template<
typename json_traits>
3869 const details::map_of_claims<json_traits> jwk_claims;
3872 JWT_CLAIM_EXPLICIT jwk(
const typename json_traits::string_type& str)
3873 : jwk_claims(details::map_of_claims<json_traits>::parse_claims(str)) {}
3875 JWT_CLAIM_EXPLICIT jwk(
const typename json_traits::value_type&
json)
3876 : jwk_claims(json_traits::as_object(
json)) {}
3974 return json_traits::as_string(x5c_array.front());
4041 bool has_jwk_claim(
const typename json_traits::string_type& name)
const noexcept {
4042 return jwk_claims.has_claim(name);
4050 basic_claim_t
get_jwk_claim(
const typename json_traits::string_type& name)
const {
4051 return jwk_claims.get_claim(name);
4058 bool empty() const noexcept {
return jwk_claims.empty(); }
4064 typename json_traits::object_type
get_claims()
const {
return this->jwk_claims.claims; }
4077 template<
typename json_traits>
4084 using iterator =
typename jwks_vector_t::iterator;
4085 using const_iterator =
typename jwks_vector_t::const_iterator;
4098 JWT_CLAIM_EXPLICIT
jwks(
const typename json_traits::string_type& str) {
4099 typename json_traits::value_type parsed_val;
4102 const details::map_of_claims<json_traits> jwks_json = json_traits::as_object(parsed_val);
4105 auto jwk_list = jwks_json.get_claim(
"keys").as_array();
4106 std::transform(jwk_list.begin(), jwk_list.end(), std::back_inserter(jwk_claims),
4107 [](
const typename json_traits::value_type& val) { return jwks_t{val}; });
4110 iterator begin() {
return jwk_claims.begin(); }
4111 iterator end() {
return jwk_claims.end(); }
4112 const_iterator cbegin()
const {
return jwk_claims.begin(); }
4113 const_iterator cend()
const {
return jwk_claims.end(); }
4114 const_iterator begin()
const {
return jwk_claims.begin(); }
4115 const_iterator end()
const {
return jwk_claims.end(); }
4121 bool has_jwk(
const typename json_traits::string_type& key_id)
const noexcept {
4122 return find_by_kid(key_id) != end();
4131 const auto maybe = find_by_kid(key_id);
4137 jwks_vector_t jwk_claims;
4139 const_iterator find_by_kid(
const typename json_traits::string_type& key_id)
const noexcept {
4140 return std::find_if(cbegin(), cend(), [key_id](
const jwks_t&
jwk) {
4142 return jwk.get_key_id() == key_id;
4152 template<
typename Clock,
typename json_traits>
4162 template<
typename Clock,
typename json_traits>
4186 template<
typename json_traits>
4188 return verifier<default_clock, json_traits>(c);
4194 template<
typename json_traits>
4196 return builder<default_clock, json_traits>(c);
4213 template<
typename json_traits,
typename Decode>
4228 template<
typename json_traits>
4238 template<
typename json_traits>
4252 template<
typename json_traits>
4258template<
typename json_traits>
4260 return c.operator>>(is);
4263template<
typename json_traits>
4268#ifndef JWT_DISABLE_PICOJSON
4269#include "traits/kazuho-picojson/defaults.h"
a class to store a generic JSON value as claim
Definition jwt.h:2591
json_traits::number_type as_number() const
Definition jwt.h:2722
set_t as_set() const
Definition jwt.h:2695
json::type get_type() const
Definition jwt.h:2659
std::set< typename json_traits::string_type > set_t
Definition jwt.h:2617
std::istream & operator>>(std::istream &is)
Definition jwt.h:2646
json_traits::boolean_type as_boolean() const
Definition jwt.h:2715
date as_date() const
Get the contained JSON value as a date.
Definition jwt.h:2676
std::ostream & operator<<(std::ostream &os)
Definition jwt.h:2652
json_traits::integer_type as_integer() const
Definition jwt.h:2708
json_traits::value_type to_json() const
Definition jwt.h:2640
json_traits::array_type as_array() const
Definition jwt.h:2688
json_traits::string_type as_string() const
Definition jwt.h:2666
builder & set_audience(typename json_traits::string_type aud)
Definition jwt.h:3251
builder & set_payload_claim(const typename json_traits::string_type &id, basic_claim< json_traits > c)
Definition jwt.h:3183
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:3194
builder & set_expires_at(const date &d)
Definition jwt.h:3259
builder & set_expires_in(const std::chrono::duration< Rep, Period > &d)
Definition jwt.h:3266
builder & set_type(typename json_traits::string_type str)
Definition jwt.h:3202
JWT_CLAIM_EXPLICIT builder(Clock c)
Definition jwt.h:3145
json_traits::string_type sign(const Algo &algo, std::error_code &ec) const
Definition jwt.h:3369
builder & set_issued_at(const date &d)
Definition jwt.h:3280
json_traits::string_type sign(const Algo &algo) const
Definition jwt.h:3323
builder & set_payload_claim(const typename json_traits::string_type &id, typename json_traits::value_type c)
Definition jwt.h:3173
builder & set_id(const typename json_traits::string_type &str)
Definition jwt.h:3291
builder & set_header_claim(const typename json_traits::string_type &id, typename json_traits::value_type c)
Definition jwt.h:3152
builder & set_header_claim(const typename json_traits::string_type &id, basic_claim< json_traits > c)
Definition jwt.h:3163
json_traits::string_type sign(const Algo &algo, Encode encode) const
Definition jwt.h:3307
builder & set_audience(typename json_traits::array_type a)
Definition jwt.h:3243
json_traits::string_type sign(const Algo &algo, Encode encode, std::error_code &ec) const
Definition jwt.h:3344
builder & set_content_type(typename json_traits::string_type str)
Definition jwt.h:3210
builder & set_not_before(const date &d)
Definition jwt.h:3274
builder & set_subject(typename json_traits::string_type str)
Definition jwt.h:3235
builder & set_issued_now()
Definition jwt.h:3285
builder & set_key_id(typename json_traits::string_type str)
Set key id claim.
Definition jwt.h:3219
builder & set_issuer(typename json_traits::string_type str)
Definition jwt.h:3227
const json_traits::string_type & get_header() const noexcept
Definition jwt.h:3070
const json_traits::string_type & get_signature_base64() const noexcept
Definition jwt.h:3095
json_traits::string_type signature
Signature part decoded from base64.
Definition jwt.h:3011
json_traits::string_type header
Header part decoded from base64.
Definition jwt.h:3003
json_traits::string_type header_base64
Unmodified header part in base64.
Definition jwt.h:3005
json_traits::string_type token
Unmodified token, as passed to constructor.
Definition jwt.h:3001
basic_claim_t get_payload_claim(const typename json_traits::string_type &name) const
Definition jwt.h:3113
const json_traits::string_type & get_signature() const noexcept
Definition jwt.h:3080
JWT_CLAIM_EXPLICIT decoded_jwt(const typename json_traits::string_type &token)
Parses a given token.
Definition jwt.h:3027
basic_claim_t get_header_claim(const typename json_traits::string_type &name) const
Definition jwt.h:3123
decoded_jwt(const typename json_traits::string_type &token, Decode decode)
Parses a given token.
Definition jwt.h:3044
json_traits::object_type get_payload_json() const
Definition jwt.h:3100
json_traits::string_type signature_base64
Unmodified signature part in base64.
Definition jwt.h:3013
const json_traits::string_type & get_payload_base64() const noexcept
Definition jwt.h:3090
const json_traits::string_type & get_token() const noexcept
Definition jwt.h:3065
json_traits::object_type get_header_json() const
Definition jwt.h:3105
const json_traits::string_type & get_payload() const noexcept
Definition jwt.h:3075
const json_traits::string_type & get_header_base64() const noexcept
Definition jwt.h:3085
json_traits::string_type payload_base64
Unmodified payload part in base64.
Definition jwt.h:3009
json_traits::string_type payload
Payload part decoded from base64.
Definition jwt.h:3007
Handle class for EVP_PKEY structures.
Definition jwt.h:427
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:451
JSON Web Key.
Definition jwt.h:3867
bool has_x5c() const noexcept
Definition jwt.h:4023
json_traits::string_type get_curve() const
Get curve claim.
Definition jwt.h:3930
bool has_x5t_sha256() const noexcept
Definition jwt.h:4035
json_traits::string_type get_algorithm() const
Definition jwt.h:3910
json_traits::array_type get_x5c() const
Definition jwt.h:3938
json_traits::object_type get_claims() const
Definition jwt.h:4064
json_traits::string_type get_x5t() const
Definition jwt.h:3954
json_traits::string_type get_x5c_key_value() const
Definition jwt.h:3970
json_traits::string_type get_x5t_sha256() const
Definition jwt.h:3962
json_traits::string_type get_key_id() const
Definition jwt.h:3918
bool has_algorithm() const noexcept
Definition jwt.h:3999
json_traits::string_type get_use() const
Definition jwt.h:3894
bool has_key_id() const noexcept
Definition jwt.h:4011
bool has_x5u() const noexcept
Definition jwt.h:4017
bool has_key_operations() const noexcept
Definition jwt.h:3993
bool empty() const noexcept
Definition jwt.h:4058
bool has_use() const noexcept
Definition jwt.h:3987
bool has_x5t() const noexcept
Definition jwt.h:4029
bool has_jwk_claim(const typename json_traits::string_type &name) const noexcept
Definition jwt.h:4041
basic_claim_t::set_t get_key_operations() const
Definition jwt.h:3902
bool has_curve() const noexcept
Definition jwt.h:4005
bool has_key_type() const noexcept
Definition jwt.h:3981
basic_claim_t get_jwk_claim(const typename json_traits::string_type &name) const
Definition jwt.h:4050
json_traits::string_type get_x5u() const
Definition jwt.h:3946
json_traits::string_type get_key_type() const
Definition jwt.h:3886
JWK Set.
Definition jwt.h:4078
jwk< json_traits > jwks_t
JWK instance template specialization.
Definition jwt.h:4081
jwks_t get_jwk(const typename json_traits::string_type &key_id) const
Definition jwt.h:4130
std::vector< jwks_t > jwks_vector_t
Type specialization for the vector of JWK.
Definition jwt.h:4083
JWT_CLAIM_EXPLICIT jwks(const typename json_traits::string_type &str)
Definition jwt.h:4098
bool has_jwk(const typename json_traits::string_type &key_id) const noexcept
Definition jwt.h:4121
basic_claim_t::set_t get_audience() const
Definition jwt.h:2867
json_traits::string_type get_id() const
Definition jwt.h:2900
bool has_issued_at() const noexcept
Definition jwt.h:2841
bool has_not_before() const noexcept
Definition jwt.h:2836
bool has_payload_claim(const typename json_traits::string_type &name) const noexcept
Definition jwt.h:2905
bool has_subject() const noexcept
Definition jwt.h:2821
date get_not_before() const
Definition jwt.h:2886
bool has_issuer() const noexcept
Definition jwt.h:2816
bool has_id() const noexcept
Definition jwt.h:2846
bool has_expires_at() const noexcept
Definition jwt.h:2831
date get_issued_at() const
Definition jwt.h:2893
basic_claim_t get_payload_claim(const typename json_traits::string_type &name) const
Definition jwt.h:2913
bool has_audience() const noexcept
Definition jwt.h:2826
date get_expires_at() const
Definition jwt.h:2879
json_traits::string_type get_subject() const
Definition jwt.h:2860
json_traits::string_type get_issuer() const
Definition jwt.h:2853
verifier & expires_at_leeway(size_t leeway)
Definition jwt.h:3685
verifier & with_claim(const typename json_traits::string_type &name, verify_check_fn_t fn)
Definition jwt.h:3784
void verify(const decoded_jwt< json_traits > &jwt, std::error_code &ec) const
Definition jwt.h:3837
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:3616
verifier & not_before_leeway(size_t leeway)
Definition jwt.h:3695
verifier & issued_at_leeway(size_t leeway)
Definition jwt.h:3705
verifier & with_subject(const typename json_traits::string_type &sub)
Definition jwt.h:3741
verifier & with_audience(const typename basic_claim_t::set_t &aud)
Definition jwt.h:3750
verifier & with_claim(const typename json_traits::string_type &name, basic_claim_t c)
Definition jwt.h:3799
verifier & with_audience(const typename json_traits::string_type &aud)
Definition jwt.h:3760
void verify(const decoded_jwt< json_traits > &jwt) const
Definition jwt.h:3827
verifier(Clock c)
Definition jwt.h:3646
verifier & leeway(size_t leeway)
Definition jwt.h:3675
verifier & with_issuer(const typename json_traits::string_type &iss)
Definition jwt.h:3731
verifier & allow_algorithm(Algorithm alg)
Add an algorithm available for checking.
Definition jwt.h:3817
verifier & with_type(const typename json_traits::string_type &type, std::locale locale=std::locale{})
Definition jwt.h:3721
verifier & with_id(const typename json_traits::string_type &id)
Definition jwt.h:3771
Various cryptographic algorithms when working with JWT.
Definition jwt.h:1351
std::string trim(const std::string &base)
Generic base64 trimming.
Definition base.h:350
std::string decode(const std::string &base)
Generic base64 decoding.
Definition base.h:322
std::string pad(const std::string &base)
Generic base64 padding.
Definition base.h:336
std::string encode(const std::string &bin)
Generic base64 encoding.
Definition base.h:308
Everything related to error codes issued by the library.
Definition jwt.h:93
signature_verification_error
Errors related to verification of signatures.
Definition jwt.h:218
std::error_category & token_verification_error_category()
Error category for token verification errors.
Definition jwt.h:353
void throw_if_error(std::error_code ec)
Raises an exception if any JWT-CPP error codes are active.
Definition jwt.h:385
std::error_category & ecdsa_error_category()
Error category for ECDSA errors.
Definition jwt.h:181
std::error_category & signature_verification_error_category()
Error category for verification errors.
Definition jwt.h:232
std::error_category & rsa_error_category()
Error category for RSA errors.
Definition jwt.h:129
std::error_category & signature_generation_error_category()
Error category for signature generation errors.
Definition jwt.h:291
ecdsa_error
Errors related to processing of RSA signatures.
Definition jwt.h:161
rsa_error
Errors related to processing of RSA signatures.
Definition jwt.h:112
signature_generation_error
Errors related to signature generation errors.
Definition jwt.h:271
token_verification_error
Errors related to token verification errors.
Definition jwt.h:341
std::error_code make_error_code(rsa_error e)
Converts JWT-CPP errors into generic STL error_codes.
Definition jwt.h:157
A collection for working with certificates.
Definition jwt.h:419
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:544
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:830
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:716
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:929
std::unique_ptr< BIGNUM, decltype(&BN_free)> raw2bn(const std::string &raw, std::error_code &ec)
Definition jwt.h:859
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:909
int curve2nid(const std::string curve, std::error_code &ec)
Convert a curve name to an ID.
Definition jwt.h:1136
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:630
std::string bn2raw(const BIGNUM *bn)
Definition jwt.h:846
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:1167
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:784
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:594
JSON Abstractions for working with any library.
Definition jwt.h:2306
type
Categories for the various JSON types used in JWTs.
Definition jwt.h:2314
JSON Web Token.
Definition base.h:21
verifier< Clock, json_traits > verify(Clock c)
Definition jwt.h:4153
std::chrono::system_clock::time_point date
Definition jwt.h:88
builder< Clock, json_traits > create(Clock c)
Definition jwt.h:4163
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:4239
jwks< json_traits > parse_jwks(const typename json_traits::string_type &jwks_)
Definition jwt.h:4253
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:4214
verify_ops::verify_context< traits::boost_json > verify_context
Definition defaults.h:88
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition jwt.h:1655
std::string sign(const std::string &data, std::error_code &ec) const
Definition jwt.h:1618
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:1577
ecdsa(helper::evp_pkey_handle key_pair, const EVP_MD *(*md)(), std::string name, size_t siglen)
Definition jwt.h:1604
std::string name() const
Definition jwt.h:1694
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:2226
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:2249
std::string name() const
Definition jwt.h:1925
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:1824
std::string sign(const std::string &data, std::error_code &ec) const
Definition jwt.h:1840
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition jwt.h:1887
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:2153
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:2203
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:2170
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:2187
std::string sign(const std::string &data, std::error_code &ec) const
Definition jwt.h:1401
std::string name() const
Definition jwt.h:1441
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition jwt.h:1422
hmacsha(std::string key, const EVP_MD *(*md)(), std::string name)
Definition jwt.h:1392
hs256(std::string key)
Definition jwt.h:2070
hs384(std::string key)
Definition jwt.h:2080
hs512(std::string key)
Definition jwt.h:2090
"none" algorithm.
Definition jwt.h:1359
void verify(const std::string &, const std::string &signature, std::error_code &ec) const
Check if the given signature is empty.
Definition jwt.h:1374
std::string name() const
Get algorithm name.
Definition jwt.h:1379
std::string sign(const std::string &, std::error_code &ec) const
Return an empty string.
Definition jwt.h:1363
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:2267
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:2282
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:2297
std::string name() const
Definition jwt.h:2051
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:1947
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition jwt.h:2012
std::string sign(const std::string &data, std::error_code &ec) const
Definition jwt.h:1964
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:2106
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:2121
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:2136
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition jwt.h:1526
rsa(helper::evp_pkey_handle key_pair, const EVP_MD *(*md)(), std::string name)
Definition jwt.h:1482
std::string sign(const std::string &data, std::error_code &ec) const
Definition jwt.h:1492
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:1465
std::string name() const
Definition jwt.h:1552
date now() const
Definition jwt.h:4175
date current_time
Current time, retrieved from the verifiers clock and cached for performance and consistency.
Definition jwt.h:3389
basic_claim< json_traits > get_claim(bool in_header, json::type t, std::error_code &ec) const
Definition jwt.h:3426
size_t default_leeway
The configured default leeway for this verification.
Definition jwt.h:3393
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:3404
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:3447
basic_claim< json_traits > get_claim(std::error_code &ec) const
Helper method to get a payload claim from the jwt.
Definition jwt.h:3440
traits::boost_json::string_type claim_key
Definition jwt.h:3396
const decoded_jwt< json_traits > & jwt
The jwt passed to the verifier.
Definition jwt.h:3391