4 #ifndef JWT_DISABLE_PICOJSON
5 #ifndef PICOJSON_USE_INT64
6 #define PICOJSON_USE_INT64
8 #include "goby/util/thirdparty/jwt-cpp/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/ssl.h>
31 #include <system_error>
32 #include <type_traits>
33 #include <unordered_map>
37 #if __cplusplus >= 201402L
39 #if __has_include(<experimental/type_traits>)
40 #include <experimental/type_traits>
45 #if OPENSSL_VERSION_NUMBER >= 0x30000000L // 3.0.0
46 #define JWT_OPENSSL_3_0
47 #elif OPENSSL_VERSION_NUMBER >= 0x10101000L // 1.1.1
48 #define JWT_OPENSSL_1_1_1
49 #elif OPENSSL_VERSION_NUMBER >= 0x10100000L // 1.1.0
50 #define JWT_OPENSSL_1_1_0
51 #elif OPENSSL_VERSION_NUMBER >= 0x10000000L // 1.0.0
52 #define JWT_OPENSSL_1_0_0
55 #if defined(LIBRESSL_VERSION_NUMBER)
56 #define JWT_OPENSSL_1_0_0
59 #if defined(LIBWOLFSSL_VERSION_HEX)
60 #define JWT_OPENSSL_1_1_1
63 #ifndef JWT_CLAIM_EXPLICIT
64 #define JWT_CLAIM_EXPLICIT explicit
79 using date = std::chrono::system_clock::time_point;
88 using system_error::system_error;
92 using system_error::system_error;
96 using system_error::system_error;
100 using system_error::system_error;
104 using system_error::system_error;
127 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
145 return "at least one of public or private key need to be present";
146 default:
return "unknown RSA error";
150 static rsa_error_cat cat;
177 class ecdsa_error_cat :
public std::error_category
180 const char* name()
const noexcept
override {
return "ecdsa_error"; };
181 std::string message(
int ev)
const override
190 return "at least one of public or private key need to be present";
194 default:
return "unknown ECDSA error";
198 static ecdsa_error_cat cat;
227 class verification_error_cat :
public std::error_category
230 const char* name()
const noexcept
override {
return "signature_verification_error"; };
231 std::string message(
int ev)
const override
238 return "failed to verify signature: could not create context";
240 return "failed to verify signature: VerifyInit failed";
242 return "failed to verify signature: VerifyUpdate failed";
244 return "failed to verify signature: VerifyFinal failed";
246 return "failed to verify signature: Could not get key";
248 return "failed to verify signature: EVP_PKEY_CTX_set_rsa_pss_saltlen failed";
250 return "failed to verify signature: i2d_ECDSA_SIG failed";
251 default:
return "unknown signature verification error";
255 static verification_error_cat cat;
290 class signature_generation_error_cat :
public std::error_category
293 const char* name()
const noexcept
override {
return "signature_generation_error"; };
294 std::string message(
int ev)
const override
301 return "failed to create signature: could not create context";
303 return "failed to create signature: SignInit failed";
305 return "failed to create signature: SignUpdate failed";
307 return "failed to create signature: SignFinal failed";
309 return "failed to generate ecdsa signature";
311 return "failed to create signature: DigestInit failed";
313 return "failed to create signature: DigestUpdate failed";
315 return "failed to create signature: DigestFinal failed";
317 return "failed to create signature: EVP_PKEY_CTX_set_rsa_padding failed";
319 return "failed to create signature: RSA_private_encrypt failed";
321 return "failed to generate signature: Could not get key";
323 return "failed to create signature: EVP_PKEY_CTX_set_rsa_pss_saltlen failed";
325 return "failed to create signature: d2i_ECDSA_SIG failed";
326 default:
return "unknown signature generation error";
330 static signature_generation_error_cat cat = {};
357 class token_verification_error_cat :
public std::error_category
360 const char* name()
const noexcept
override {
return "token_verification_error"; };
361 std::string message(
int ev)
const override
368 return "decoded JWT is missing required claim(s)";
370 return "claim type does not match expected type";
372 return "claim value does not match expected value";
375 return "token doesn't contain the required audience";
376 default:
return "unknown token verification error";
380 static token_verification_error_cat cat = {};
409 using error::ecdsa_exception;
410 using error::rsa_exception;
411 using error::signature_generation_exception;
412 using error::signature_verification_exception;
413 using error::token_verification_exception;
455 #if OPENSSL_VERSION_NUMBER <= 0x10100003L
456 std::unique_ptr<BIO, decltype(&BIO_free_all)> certbio(
457 BIO_new_mem_buf(
const_cast<char*
>(certstr.data()),
static_cast<int>(certstr.size())),
460 std::unique_ptr<BIO, decltype(&BIO_free_all)> certbio(
461 BIO_new_mem_buf(certstr.data(),
static_cast<int>(certstr.size())), BIO_free_all);
463 std::unique_ptr<BIO, decltype(&BIO_free_all)> keybio(BIO_new(BIO_s_mem()), BIO_free_all);
464 if (!certbio || !keybio)
470 std::unique_ptr<X509, decltype(&X509_free)> cert(
471 PEM_read_bio_X509(certbio.get(),
nullptr,
nullptr,
const_cast<char*
>(pw.c_str())),
478 std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)> key(X509_get_pubkey(cert.get()),
485 if (PEM_write_bio_PUBKEY(keybio.get(), key.get()) == 0)
491 auto len = BIO_get_mem_data(keybio.get(), &ptr);
492 if (len <= 0 || ptr ==
nullptr)
497 return {ptr,
static_cast<size_t>(len)};
529 template <
typename Decode>
534 const auto decodedStr =
decode(cert_base64_der_str);
535 auto c_str =
reinterpret_cast<const unsigned char*
>(decodedStr.c_str());
537 std::unique_ptr<X509, decltype(&X509_free)> cert(
538 d2i_X509(NULL, &c_str,
static_cast<int>(decodedStr.size())), X509_free);
539 std::unique_ptr<BIO, decltype(&BIO_free_all)> certbio(BIO_new(BIO_s_mem()), BIO_free_all);
540 if (!cert || !certbio)
546 if (!PEM_write_bio_X509(certbio.get(), cert.get()))
553 const auto len = BIO_get_mem_data(certbio.get(), &ptr);
554 if (len <= 0 || ptr ==
nullptr)
560 return {ptr,
static_cast<size_t>(len)};
577 template <
typename Decode>
585 #ifndef JWT_DISABLE_BASE64
598 auto decode = [](
const std::string& token)
599 {
return base::decode<alphabet::base64>(base::pad<alphabet::base64>(token)); };
630 const std::string& password,
634 std::unique_ptr<BIO, decltype(&BIO_free_all)> pubkey_bio(BIO_new(BIO_s_mem()), BIO_free_all);
640 if (key.substr(0, 27) ==
"-----BEGIN CERTIFICATE-----")
645 const int len =
static_cast<int>(epkey.size());
646 if (BIO_write(pubkey_bio.get(), epkey.data(), len) != len)
654 const int len =
static_cast<int>(key.size());
655 if (BIO_write(pubkey_bio.get(), key.data(), len) != len)
662 std::shared_ptr<EVP_PKEY> pkey(
664 pubkey_bio.get(),
nullptr,
nullptr,
665 (
void*)password.data()),
685 const std::string& password =
"")
701 const std::string& password,
704 std::unique_ptr<BIO, decltype(&BIO_free_all)> privkey_bio(BIO_new(BIO_s_mem()), BIO_free_all);
710 const int len =
static_cast<int>(key.size());
711 if (BIO_write(privkey_bio.get(), key.data(), len) != len)
716 std::shared_ptr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(privkey_bio.get(),
nullptr,
nullptr,
717 const_cast<char*
>(password.c_str())),
735 const std::string& password =
"")
753 const std::string& password,
757 std::unique_ptr<BIO, decltype(&BIO_free_all)> pubkey_bio(BIO_new(BIO_s_mem()), BIO_free_all);
763 if (key.substr(0, 27) ==
"-----BEGIN CERTIFICATE-----")
768 const int len =
static_cast<int>(epkey.size());
769 if (BIO_write(pubkey_bio.get(), epkey.data(), len) != len)
777 const int len =
static_cast<int>(key.size());
778 if (BIO_write(pubkey_bio.get(), key.data(), len) != len)
785 std::shared_ptr<EVP_PKEY> pkey(
787 pubkey_bio.get(),
nullptr,
nullptr,
788 (
void*)password.data()),
808 const std::string& password =
"")
824 const std::string& password,
827 std::unique_ptr<BIO, decltype(&BIO_free_all)> privkey_bio(BIO_new(BIO_s_mem()), BIO_free_all);
833 const int len =
static_cast<int>(key.size());
834 if (BIO_write(privkey_bio.get(), key.data(), len) != len)
839 std::shared_ptr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(privkey_bio.get(),
nullptr,
nullptr,
840 const_cast<char*
>(password.c_str())),
858 const std::string& password =
"")
872 #ifdef JWT_OPENSSL_1_0_0
880 std::string res(BN_num_bytes(bn),
'\0');
882 bn, (
unsigned char*)res.data());
890 inline std::unique_ptr<BIGNUM, decltype(&BN_free)>
raw2bn(
const std::string& raw)
892 return std::unique_ptr<BIGNUM, decltype(&BN_free)>(
893 BN_bin2bn(
reinterpret_cast<const unsigned char*
>(raw.data()),
static_cast<int>(raw.size()),
920 std::string
sign(
const std::string& , std::error_code& ec)
const
932 void verify(
const std::string& ,
const std::string& signature,
933 std::error_code& ec)
const
936 if (!signature.empty())
942 std::string
name()
const {
return "none"; }
956 : secret(std::move(key)), md(md), alg_name(std::move(
name))
965 std::string
sign(
const std::string& data, std::error_code& ec)
const
968 std::string res(
static_cast<size_t>(EVP_MAX_MD_SIZE),
'\0');
969 auto len =
static_cast<unsigned int>(res.size());
970 if (HMAC(md(), secret.data(),
static_cast<int>(secret.size()),
971 reinterpret_cast<const unsigned char*
>(data.data()),
static_cast<int>(data.size()),
988 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const
991 auto res =
sign(data, ec);
996 for (
size_t i = 0; i < std::min<size_t>(res.size(), signature.size()); i++)
997 if (res[i] != signature[i])
999 if (res.size() != signature.size())
1011 std::string
name()
const {
return alg_name; }
1015 const std::string secret;
1017 const EVP_MD* (*md)();
1019 const std::string alg_name;
1035 rsa(
const std::string& public_key,
const std::string& private_key,
1036 const std::string& public_key_password,
const std::string& private_key_password,
1037 const EVP_MD* (*md)(), std::string
name)
1038 : md(md), alg_name(std::move(
name))
1040 if (!private_key.empty())
1044 else if (!public_key.empty())
1057 std::string
sign(
const std::string& data, std::error_code& ec)
const
1060 #ifdef JWT_OPENSSL_1_0_0
1061 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> ctx(EVP_MD_CTX_create(),
1062 EVP_MD_CTX_destroy);
1064 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> ctx(EVP_MD_CTX_create(),
1072 if (!EVP_SignInit(ctx.get(), md()))
1078 std::string res(EVP_PKEY_size(pkey.get()),
'\0');
1079 unsigned int len = 0;
1081 if (!EVP_SignUpdate(ctx.get(), data.data(), data.size()))
1086 if (EVP_SignFinal(ctx.get(), (
unsigned char*)res.data(), &len, pkey.get()) == 0)
1101 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const
1104 #ifdef JWT_OPENSSL_1_0_0
1105 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> ctx(EVP_MD_CTX_create(),
1106 EVP_MD_CTX_destroy);
1108 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> ctx(EVP_MD_CTX_create(),
1116 if (!EVP_VerifyInit(ctx.get(), md()))
1121 if (!EVP_VerifyUpdate(ctx.get(), data.data(), data.size()))
1127 EVP_VerifyFinal(ctx.get(),
reinterpret_cast<const unsigned char*
>(signature.data()),
1128 static_cast<unsigned int>(signature.size()), pkey.get());
1139 std::string
name()
const {
return alg_name; }
1143 std::shared_ptr<EVP_PKEY> pkey;
1145 const EVP_MD* (*md)();
1147 const std::string alg_name;
1165 ecdsa(
const std::string& public_key,
const std::string& private_key,
1166 const std::string& public_key_password,
const std::string& private_key_password,
1167 const EVP_MD* (*md)(), std::string
name,
size_t siglen)
1168 : md(md), alg_name(std::move(
name)), signature_length(siglen)
1170 if (!private_key.empty())
1173 check_private_key(pkey.get());
1175 else if (!public_key.empty())
1178 check_public_key(pkey.get());
1187 size_t keysize = EVP_PKEY_bits(pkey.get());
1188 if (keysize != signature_length * 4 && (signature_length != 132 || keysize != 521))
1198 std::string
sign(
const std::string& data, std::error_code& ec)
const
1201 #ifdef JWT_OPENSSL_1_0_0
1202 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> ctx(EVP_MD_CTX_create(),
1203 EVP_MD_CTX_destroy);
1205 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> ctx(EVP_MD_CTX_create(),
1213 if (!EVP_DigestSignInit(ctx.get(),
nullptr, md(),
nullptr, pkey.get()))
1218 if (!EVP_DigestUpdate(ctx.get(), data.data(), data.size()))
1225 if (!EVP_DigestSignFinal(ctx.get(),
nullptr, &len))
1230 std::string res(len,
'\0');
1231 if (!EVP_DigestSignFinal(ctx.get(), (
unsigned char*)res.data(), &len))
1238 return der_to_p1363_signature(res, ec);
1247 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const
1250 std::string der_signature = p1363_to_der_signature(signature, ec);
1256 #ifdef JWT_OPENSSL_1_0_0
1257 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> ctx(EVP_MD_CTX_create(),
1258 EVP_MD_CTX_destroy);
1260 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> ctx(EVP_MD_CTX_create(),
1268 if (!EVP_DigestVerifyInit(ctx.get(),
nullptr, md(),
nullptr, pkey.get()))
1273 if (!EVP_DigestUpdate(ctx.get(), data.data(), data.size()))
1279 #if OPENSSL_VERSION_NUMBER < 0x10002000L
1280 unsigned char* der_sig_data =
1281 reinterpret_cast<unsigned char*
>(
const_cast<char*
>(der_signature.data()));
1283 const unsigned char* der_sig_data =
1284 reinterpret_cast<const unsigned char*
>(der_signature.data());
1286 auto res = EVP_DigestVerifyFinal(ctx.get(), der_sig_data,
1287 static_cast<unsigned int>(der_signature.length()));
1303 std::string
name()
const {
return alg_name; }
1306 static void check_public_key(EVP_PKEY* pkey)
1308 #ifdef JWT_OPENSSL_3_0
1309 std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)> ctx(
1310 EVP_PKEY_CTX_new_from_pkey(
nullptr, pkey,
nullptr), EVP_PKEY_CTX_free);
1315 if (EVP_PKEY_public_check(ctx.get()) != 1)
1320 std::unique_ptr<EC_KEY, decltype(&EC_KEY_free)> eckey(EVP_PKEY_get1_EC_KEY(pkey),
1326 if (EC_KEY_check_key(eckey.get()) == 0)
1331 static void check_private_key(EVP_PKEY* pkey)
1333 #ifdef JWT_OPENSSL_3_0
1334 std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)> ctx(
1335 EVP_PKEY_CTX_new_from_pkey(
nullptr, pkey,
nullptr), EVP_PKEY_CTX_free);
1340 if (EVP_PKEY_private_check(ctx.get()) != 1)
1345 std::unique_ptr<EC_KEY, decltype(&EC_KEY_free)> eckey(EVP_PKEY_get1_EC_KEY(pkey),
1351 if (EC_KEY_check_key(eckey.get()) == 0)
1356 std::string der_to_p1363_signature(
const std::string& der_signature, std::error_code& ec)
const
1358 const unsigned char* possl_signature =
1359 reinterpret_cast<const unsigned char*
>(der_signature.data());
1360 std::unique_ptr<ECDSA_SIG, decltype(&ECDSA_SIG_free)> sig(
1361 d2i_ECDSA_SIG(
nullptr, &possl_signature, der_signature.length()), ECDSA_SIG_free);
1368 #ifdef JWT_OPENSSL_1_0_0
1375 ECDSA_SIG_get0(sig.get(), &r, &s);
1379 if (rr.size() > signature_length / 2 || rs.size() > signature_length / 2)
1380 throw std::logic_error(
"bignum size exceeded expected length");
1381 rr.insert(0, signature_length / 2 - rr.size(),
'\0');
1382 rs.insert(0, signature_length / 2 - rs.size(),
'\0');
1386 std::string p1363_to_der_signature(
const std::string& signature, std::error_code& ec)
const
1389 auto r =
helper::raw2bn(signature.substr(0, signature.size() / 2));
1393 #ifdef JWT_OPENSSL_1_0_0
1399 std::unique_ptr<ECDSA_SIG, decltype(&ECDSA_SIG_free)> sig(ECDSA_SIG_new(), ECDSA_SIG_free);
1405 ECDSA_SIG_set0(sig.get(), r.release(), s.release());
1409 int length = i2d_ECDSA_SIG(psig,
nullptr);
1415 std::string der_signature(length,
'\0');
1416 unsigned char* psbuffer = (
unsigned char*)der_signature.data();
1417 length = i2d_ECDSA_SIG(psig, &psbuffer);
1423 der_signature.resize(length);
1424 return der_signature;
1428 std::shared_ptr<EVP_PKEY> pkey;
1430 const EVP_MD* (*md)();
1432 const std::string alg_name;
1434 const size_t signature_length;
1437 #if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
1458 eddsa(
const std::string& public_key,
const std::string& private_key,
1459 const std::string& public_key_password,
const std::string& private_key_password,
1461 : alg_name(std::move(
name))
1463 if (!private_key.empty())
1467 else if (!public_key.empty())
1480 std::string
sign(
const std::string& data, std::error_code& ec)
const
1483 #ifdef JWT_OPENSSL_1_0_0
1484 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> ctx(EVP_MD_CTX_create(),
1485 &EVP_MD_CTX_destroy);
1487 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> ctx(EVP_MD_CTX_new(),
1495 if (!EVP_DigestSignInit(ctx.get(),
nullptr,
nullptr,
nullptr, pkey.get()))
1501 size_t len = EVP_PKEY_size(pkey.get());
1502 std::string res(len,
'\0');
1507 #if defined(LIBRESSL_VERSION_NUMBER) || defined(LIBWOLFSSL_VERSION_HEX)
1509 if (EVP_DigestSignUpdate(ctx.get(),
reinterpret_cast<const unsigned char*
>(data.data()),
1512 std::cout << ERR_error_string(ERR_get_error(), NULL) << std::endl;
1516 if (EVP_DigestSignFinal(ctx.get(),
reinterpret_cast<unsigned char*
>(&res[0]), &len) != 1)
1522 if (EVP_DigestSign(ctx.get(),
reinterpret_cast<unsigned char*
>(&res[0]), &len,
1523 reinterpret_cast<const unsigned char*
>(data.data()), data.size()) != 1)
1540 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const
1543 #ifdef JWT_OPENSSL_1_0_0
1544 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> ctx(EVP_MD_CTX_create(),
1545 &EVP_MD_CTX_destroy);
1547 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> ctx(EVP_MD_CTX_new(),
1555 if (!EVP_DigestVerifyInit(ctx.get(),
nullptr,
nullptr,
nullptr, pkey.get()))
1563 #if defined(LIBRESSL_VERSION_NUMBER) || defined(LIBWOLFSSL_VERSION_HEX)
1564 if (EVP_DigestVerifyUpdate(ctx.get(),
reinterpret_cast<const unsigned char*
>(data.data()),
1570 if (EVP_DigestVerifyFinal(ctx.get(),
1571 reinterpret_cast<const unsigned char*
>(signature.data()),
1572 signature.size()) != 1)
1578 auto res = EVP_DigestVerify(
1579 ctx.get(),
reinterpret_cast<const unsigned char*
>(signature.data()), signature.size(),
1580 reinterpret_cast<const unsigned char*
>(data.data()), data.size());
1592 std::string
name()
const {
return alg_name; }
1596 std::shared_ptr<EVP_PKEY> pkey;
1598 const std::string alg_name;
1615 pss(
const std::string& public_key,
const std::string& private_key,
1616 const std::string& public_key_password,
const std::string& private_key_password,
1617 const EVP_MD* (*md)(), std::string
name)
1618 : md(md), alg_name(std::move(
name))
1620 if (!private_key.empty())
1624 else if (!public_key.empty())
1638 std::string
sign(
const std::string& data, std::error_code& ec)
const
1641 #ifdef JWT_OPENSSL_1_0_0
1642 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> md_ctx(EVP_MD_CTX_create(),
1643 &EVP_MD_CTX_destroy);
1645 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> md_ctx(EVP_MD_CTX_new(),
1653 EVP_PKEY_CTX* ctx =
nullptr;
1654 if (EVP_DigestSignInit(md_ctx.get(), &ctx, md(),
nullptr, pkey.get()) != 1)
1659 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0)
1666 #ifndef LIBWOLFSSL_VERSION_HEX
1667 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0)
1673 if (EVP_DigestUpdate(md_ctx.get(), data.data(), data.size()) != 1)
1679 size_t size = EVP_PKEY_size(pkey.get());
1680 std::string res(size, 0x00);
1681 if (EVP_DigestSignFinal(
1700 void verify(
const std::string& data,
const std::string& signature, std::error_code& ec)
const
1704 #ifdef JWT_OPENSSL_1_0_0
1705 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)> md_ctx(EVP_MD_CTX_create(),
1706 &EVP_MD_CTX_destroy);
1708 std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> md_ctx(EVP_MD_CTX_new(),
1716 EVP_PKEY_CTX* ctx =
nullptr;
1717 if (EVP_DigestVerifyInit(md_ctx.get(), &ctx, md(),
nullptr, pkey.get()) != 1)
1722 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0)
1729 #ifndef LIBWOLFSSL_VERSION_HEX
1730 if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0)
1736 if (EVP_DigestUpdate(md_ctx.get(), data.data(), data.size()) != 1)
1742 if (EVP_DigestVerifyFinal(md_ctx.get(), (
unsigned char*)signature.data(),
1743 signature.size()) <= 0)
1753 std::string
name()
const {
return alg_name; }
1757 std::shared_ptr<EVP_PKEY> pkey;
1759 const EVP_MD* (*md)();
1761 const std::string alg_name;
1773 explicit hs256(std::string key) :
hmacsha(std::move(key), EVP_sha256,
"HS256") {}
1784 explicit hs384(std::string key) :
hmacsha(std::move(key), EVP_sha384,
"HS384") {}
1795 explicit hs512(std::string key) :
hmacsha(std::move(key), EVP_sha512,
"HS512") {}
1809 explicit rs256(
const std::string& public_key,
const std::string& private_key =
"",
1810 const std::string& public_key_password =
"",
1811 const std::string& private_key_password =
"")
1812 :
rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
1829 explicit rs384(
const std::string& public_key,
const std::string& private_key =
"",
1830 const std::string& public_key_password =
"",
1831 const std::string& private_key_password =
"")
1832 :
rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384,
1849 explicit rs512(
const std::string& public_key,
const std::string& private_key =
"",
1850 const std::string& public_key_password =
"",
1851 const std::string& private_key_password =
"")
1852 :
rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512,
1871 explicit es256(
const std::string& public_key,
const std::string& private_key =
"",
1872 const std::string& public_key_password =
"",
1873 const std::string& private_key_password =
"")
1874 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
1893 explicit es384(
const std::string& public_key,
const std::string& private_key =
"",
1894 const std::string& public_key_password =
"",
1895 const std::string& private_key_password =
"")
1896 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384,
1915 explicit es512(
const std::string& public_key,
const std::string& private_key =
"",
1916 const std::string& public_key_password =
"",
1917 const std::string& private_key_password =
"")
1918 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512,
1936 explicit es256k(
const std::string& public_key,
const std::string& private_key =
"",
1937 const std::string& public_key_password =
"",
1938 const std::string& private_key_password =
"")
1939 :
ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
1945 #if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
1964 explicit ed25519(
const std::string& public_key,
const std::string& private_key =
"",
1965 const std::string& public_key_password =
"",
1966 const std::string& private_key_password =
"")
1967 :
eddsa(public_key, private_key, public_key_password, private_key_password,
"EdDSA")
1990 explicit ed448(
const std::string& public_key,
const std::string& private_key =
"",
1991 const std::string& public_key_password =
"",
1992 const std::string& private_key_password =
"")
1993 :
eddsa(public_key, private_key, public_key_password, private_key_password,
"EdDSA")
2011 explicit ps256(
const std::string& public_key,
const std::string& private_key =
"",
2012 const std::string& public_key_password =
"",
2013 const std::string& private_key_password =
"")
2014 :
pss(public_key, private_key, public_key_password, private_key_password, EVP_sha256,
2031 explicit ps384(
const std::string& public_key,
const std::string& private_key =
"",
2032 const std::string& public_key_password =
"",
2033 const std::string& private_key_password =
"")
2034 :
pss(public_key, private_key, public_key_password, private_key_password, EVP_sha384,
2051 explicit ps512(
const std::string& public_key,
const std::string& private_key =
"",
2052 const std::string& public_key_password =
"",
2053 const std::string& private_key_password =
"")
2054 :
pss(public_key, private_key, public_key_password, private_key_password, EVP_sha512,
2084 #ifdef __cpp_lib_void_t
2096 #ifdef __cpp_lib_experimental_detect
2097 template <
template <
typename...>
class _Op,
typename... _Args>
2100 template <
template <
typename...>
class _Op,
typename... _Args>
2114 template <
class Default,
class AlwaysVoid,
template <
class...>
class Op,
class... Args>
2121 template <
class Default,
template <
class...>
class Op,
class... Args>
2128 template <
template <
class...>
class Op,
class... Args>
2131 template <
template <
class...>
class Op,
class... Args>
2137 template <
typename traits_type,
typename value_type>
2139 typename std::is_same<get_type_function<traits_type>,
json::type(
const value_type&)>;
2144 std::is_function<get_type_function<traits_type>>
::value &&
2150 template <
typename traits_type,
typename value_type,
typename object_type>
2152 typename std::is_same<as_object_function<traits_type>, object_type(
const value_type&)>;
2157 std::is_constructible<value_type, object_type>::value &&
2159 std::is_function<as_object_function<traits_type>>
::value &&
2165 template <
typename traits_type,
typename value_type,
typename array_type>
2167 typename std::is_same<as_array_function<traits_type>, array_type(
const value_type&)>;
2171 static constexpr
auto value = std::is_constructible<value_type, array_type>::value &&
2173 std::is_function<as_array_function<traits_type>>
::value &&
2179 template <
typename traits_type,
typename value_type,
typename string_type>
2181 typename std::is_same<as_string_function<traits_type>, string_type(
const value_type&)>;
2186 std::is_constructible<value_type, string_type>::value &&
2188 std::is_function<as_string_function<traits_type>>
::value &&
2194 template <
typename traits_type,
typename value_type,
typename number_type>
2196 typename std::is_same<as_number_function<traits_type>, number_type(
const value_type&)>;
2201 std::is_floating_point<number_type>::value &&
2202 std::is_constructible<value_type, number_type>::value &&
2204 std::is_function<as_number_function<traits_type>>
::value &&
2210 template <
typename traits_type,
typename value_type,
typename integer_type>
2212 typename std::is_same<as_integer_function<traits_type>, integer_type(
const value_type&)>;
2214 template <
typename traits_type,
typename value_type,
typename integer_type>
2218 std::is_signed<integer_type>::value && !std::is_floating_point<integer_type>::value &&
2219 std::is_constructible<value_type, integer_type>::value &&
2221 std::is_function<as_integer_function<traits_type>>
::value &&
2227 template <
typename traits_type,
typename value_type,
typename boolean_type>
2229 typename std::is_same<as_boolean_function<traits_type>, boolean_type(
const value_type&)>;
2231 template <
typename traits_type,
typename value_type,
typename boolean_type>
2235 std::is_convertible<boolean_type, bool>::value &&
2236 std::is_constructible<value_type, boolean_type>::value &&
2238 std::is_function<as_boolean_function<traits_type>>
::value &&
2246 "traits must provide `jwt::json::type get_type(const value_type&)`");
2248 typename traits::object_type>::
value,
2249 "traits must provide `object_type as_object(const value_type&)`");
2252 "traits must provide `array_type as_array(const value_type&)`");
2254 typename traits::string_type>::
value,
2255 "traits must provide `string_type as_string(const value_type&)`");
2257 typename traits::number_type>::
value,
2258 "traits must provide `number_type as_number(const value_type&)`");
2260 typename traits::integer_type>::
value,
2261 "traits must provide `integer_type as_int(const value_type&)`");
2263 typename traits::boolean_type>::
value,
2264 "traits must provide `boolean_type as_bool(const value_type&)`");
2268 typename traits::object_type>
::value &&
2270 typename traits::array_type>
::value &&
2272 typename traits::string_type>
::value &&
2274 typename traits::number_type>
::value &&
2276 typename traits::integer_type>
::value &&
2278 typename traits::boolean_type>
::value;
2284 std::is_default_constructible<value_type>::value &&
2285 std::is_constructible<value_type,
2287 std::is_move_constructible<value_type>::value &&
2288 std::is_assignable<value_type, value_type>::value &&
2289 std::is_copy_assignable<value_type>::value && std::is_move_assignable<value_type>::value;
2293 template <
typename traits_type>
using has_mapped_type =
typename traits_type::mapped_type;
2295 template <
typename traits_type>
using has_key_type =
typename traits_type::key_type;
2297 template <
typename traits_type>
using has_value_type =
typename traits_type::value_type;
2299 template <
typename object_type>
using has_iterator =
typename object_type::iterator;
2303 template <
typename object_type>
2307 template <
typename object_type>
2309 typename std::is_same<decltype(std::declval<const object_type>().begin()),
2320 template <
typename object_type>
2324 template <
typename object_type>
2326 typename std::is_same<decltype(std::declval<const object_type>().end()),
2337 template <
typename object_type,
typename string_type>
2339 typename std::is_integral<decltype(std::declval<const object_type>().count(
2340 std::declval<const string_type>()))>;
2348 template <
class T,
class A0>
2353 static constexpr
auto value = decltype(test_operator_plus<object_type, string_type>(0)){};
2356 template <
typename object_type,
typename value_type,
typename string_type>
2362 "object_type must implementate the subscription operator '[]' for this library");
2367 template <
typename object_type,
typename value_type,
typename string_type>
2369 std::declval<const string_type>())),
2372 template <
typename value_type,
typename string_type,
typename object_type>
2377 std::is_same<typename object_type::mapped_type, value_type>::value &&
2379 (std::is_same<typename object_type::key_type, string_type>::value ||
2380 std::is_constructible<typename object_type::key_type, string_type>::value) &&
2388 std::is_same<
typename object_type::value_type,
2389 std::pair<const string_type, value_type>>
::value;
2394 static constexpr
auto value = std::is_same<typename array_type::value_type, value_type>::value;
2397 template <
typename string_type,
typename integer_type>
2399 typename std::is_same<decltype(std::declval<string_type>().substr(
2400 std::declval<integer_type>(), std::declval<integer_type>())),
2403 template <
typename string_type,
typename integer_type>
2405 decltype(std::declval<string_type>().substr(std::declval<integer_type>())), string_type>;
2413 template <
class T,
class A0>
2418 static constexpr
auto value = decltype(test_operator_plus<string_type, string_type>(0)){};
2421 template <
typename string_type>
2423 typename std::is_same<decltype(std::operator+(std::declval<string_type>(),
2424 std::declval<string_type>())),
2433 "string_type must have a substr method taking only a start index and an overload "
2434 "taking a start and end index, both must return a string_type");
2440 "string_type must have a '+' operator implemented which returns the concatenated string");
2445 template <
typename value_type,
typename string_type,
typename integer_type,
typename object_type,
2446 typename array_type>
2452 "value_type must meet basic requirements, default constructor, copyable, moveable");
2454 "object_type must be a string_type to value_type container");
2456 "array_type must be a container of value_type");
2481 static_assert(std::is_same<typename json_traits::string_type, std::string>::value ||
2482 std::is_convertible<typename json_traits::string_type, std::string>::value ||
2483 std::is_constructible<typename json_traits::string_type, std::string>::value,
2484 "string_type must be a std::string, convertible to a std::string, or construct a "
2488 typename json_traits::value_type,
typename json_traits::string_type,
2489 typename json_traits::integer_type,
typename json_traits::object_type,
2490 typename json_traits::array_type>::value,
2491 "must staisfy json container requirements");
2494 typename json_traits::value_type val;
2497 using set_t = std::set<typename json_traits::string_type>;
2508 : val(typename json_traits::integer_type(std::chrono::system_clock::to_time_t(d)))
2514 : val(typename json_traits::array_type(s.begin(), s.end()))
2517 template <
typename Iterator>
2518 basic_claim(Iterator begin, Iterator end) : val(typename json_traits::array_type(begin, end))
2526 typename json_traits::value_type
to_json()
const {
return val; }
2552 typename json_traits::string_type
as_string()
const {
return json_traits::as_string(val); }
2566 typename json_traits::array_type
as_array()
const {
return json_traits::as_array(val); }
2576 for (
const auto&
e : json_traits::as_array(val)) { res.insert(json_traits::as_string(
e)); }
2585 typename json_traits::integer_type
as_int()
const {
return json_traits::as_int(val); }
2592 typename json_traits::boolean_type
as_bool()
const {
return json_traits::as_bool(val); }
2599 typename json_traits::number_type
as_number()
const {
return json_traits::as_number(val); }
2624 typename json_traits::object_type claims;
2628 using iterator =
typename json_traits::object_type::iterator;
2654 static typename json_traits::object_type
2657 typename json_traits::value_type val;
2658 if (!json_traits::parse(val,
str))
2661 return json_traits::as_object(val);
2668 bool has_claim(
const typename json_traits::string_type& name)
const noexcept
2670 return claims.count(name) != 0;
2687 std::unordered_map<typename json_traits::string_type, basic_claim_t>
get_claims()
const
2690 typename json_traits::value_type,
typename json_traits::string_type,
2691 typename json_traits::object_type>::supports_claims_transform,
2692 "currently there is a limitation on the internal implemantation of the "
2693 "`object_type` to have an "
2694 "`std::pair` like `value_type`");
2696 std::unordered_map<typename json_traits::string_type, basic_claim_t> res;
2697 std::transform(claims.begin(), claims.end(), std::inserter(res, res.end()),
2698 [](
const typename json_traits::object_type::value_type& val)
2699 { return std::make_pair(val.first, basic_claim_t{val.second}); });
2721 bool has_issuer() const noexcept {
return has_payload_claim(
"iss"); }
2726 bool has_subject() const noexcept {
return has_payload_claim(
"sub"); }
2751 bool has_id() const noexcept {
return has_payload_claim(
"jti"); }
2760 return get_payload_claim(
"iss").as_string();
2770 return get_payload_claim(
"sub").as_string();
2780 auto aud = get_payload_claim(
"aud");
2781 if (aud.get_type() == json::type::string)
2782 return {aud.as_string()};
2784 return aud.as_set();
2813 typename json_traits::string_type
get_id()
const
2815 return get_payload_claim(
"jti").as_string();
2856 bool has_type() const noexcept {
return has_header_claim(
"typ"); }
2866 bool has_key_id() const noexcept {
return has_header_claim(
"kid"); }
2875 return get_header_claim(
"alg").as_string();
2885 return get_header_claim(
"typ").as_string();
2895 return get_header_claim(
"cty").as_string();
2905 return get_header_claim(
"kid").as_string();
2929 template <
typename json_traits>
2934 const typename json_traits::string_type
token;
2950 #ifndef JWT_DISABLE_BASE64
2962 token, [](const typename json_traits::string_type&
str)
2963 {
return base::decode<alphabet::base64url>(base::pad<alphabet::base64url>(
str)); })
2978 template <
typename Decode>
2981 auto hdr_end = token.find(
'.');
2982 if (hdr_end == json_traits::string_type::npos)
2983 throw std::invalid_argument(
"invalid token supplied");
2984 auto payload_end = token.find(
'.', hdr_end + 1);
2985 if (payload_end == json_traits::string_type::npos)
2986 throw std::invalid_argument(
"invalid token supplied");
2987 header_base64 = token.substr(0, hdr_end);
2988 payload_base64 = token.substr(hdr_end + 1, payload_end - hdr_end - 1);
2989 signature_base64 = token.substr(payload_end + 1);
2993 signature =
decode(signature_base64);
3003 const typename json_traits::string_type&
get_token() const noexcept {
return token; }
3018 const typename json_traits::string_type&
get_signature() const noexcept {
return signature; }
3025 return header_base64;
3033 return payload_base64;
3041 return signature_base64;
3049 return this->payload_claims.get_claims();
3057 return this->header_claims.get_claims();
3068 return this->payload_claims.get_claim(name);
3079 return this->header_claims.get_claim(name);
3089 typename json_traits::object_type header_claims;
3090 typename json_traits::object_type payload_claims;
3101 typename json_traits::value_type c)
3103 header_claims[id] = std::move(c);
3116 header_claims[id] = c.
to_json();
3126 typename json_traits::value_type c)
3128 payload_claims[id] = std::move(c);
3140 payload_claims[id] = c.
to_json();
3152 return set_header_claim(
"alg",
typename json_traits::value_type(
str));
3161 return set_header_claim(
"typ",
typename json_traits::value_type(
str));
3170 return set_header_claim(
"cty",
typename json_traits::value_type(
str));
3180 return set_header_claim(
"kid",
typename json_traits::value_type(
str));
3189 return set_payload_claim(
"iss",
typename json_traits::value_type(
str));
3198 return set_payload_claim(
"sub",
typename json_traits::value_type(
str));
3207 return set_payload_claim(
"aud",
typename json_traits::value_type(a));
3216 return set_payload_claim(
"aud",
typename json_traits::value_type(aud));
3252 return set_payload_claim(
"jti",
typename json_traits::value_type(
str));
3266 template <
typename Algo,
typename Encode>
3267 typename json_traits::string_type
sign(
const Algo& algo, Encode encode)
const
3270 auto res = sign(algo, encode, ec);
3274 #ifndef JWT_DISABLE_BASE64
3283 template <
typename Algo>
typename json_traits::string_type
sign(
const Algo& algo)
const
3286 auto res = sign(algo, ec);
3304 template <
typename Algo,
typename Encode>
3305 typename json_traits::string_type
sign(
const Algo& algo, Encode encode,
3306 std::error_code& ec)
const
3309 typename json_traits::object_type obj_header = header_claims;
3310 if (header_claims.count(
"alg") == 0)
3311 obj_header[
"alg"] =
typename json_traits::value_type(algo.name());
3314 encode(json_traits::serialize(
typename json_traits::value_type(obj_header)));
3316 encode(json_traits::serialize(
typename json_traits::value_type(payload_claims)));
3319 auto signature = algo.sign(token, ec);
3323 return token +
"." + encode(signature);
3325 #ifndef JWT_DISABLE_BASE64
3335 template <
typename Algo>
3336 typename json_traits::string_type
sign(
const Algo& algo, std::error_code& ec)
const
3340 [](
const typename json_traits::string_type& data)
3341 {
return base::trim<alphabet::base64url>(base::encode<alphabet::base64url>(data)); },
3347 namespace verify_ops
3355 : current_time(ctime),
jwt(j), default_leeway(l)
3363 size_t default_leeway{0};
3366 typename json_traits::string_type claim_key{};
3373 if (!
jwt.has_header_claim(claim_key))
3375 ec = error::token_verification_error::missing_claim;
3378 return jwt.get_header_claim(claim_key);
3382 if (!
jwt.has_payload_claim(claim_key))
3384 ec = error::token_verification_error::missing_claim;
3387 return jwt.get_payload_claim(claim_key);
3392 auto c = get_claim(in_header, ec);
3395 if (c.get_type() != t)
3397 ec = error::token_verification_error::claim_type_missmatch;
3405 return get_claim(
false, t, ec);
3412 template <
typename json_traits,
bool in_header = false>
struct equals_claim
3420 const bool matches = [&]()
3424 case json::type::boolean:
return expected.
as_bool() == jc.as_bool();
3425 case json::type::integer:
return expected.
as_int() == jc.as_int();
3426 case json::type::number:
return expected.
as_number() == jc.as_number();
3427 case json::type::string:
return expected.
as_string() == jc.as_string();
3428 case json::type::array:
3429 case json::type::object:
3430 return json_traits::serialize(expected.
to_json()) ==
3431 json_traits::serialize(jc.to_json());
3432 default:
throw std::logic_error(
"internal error, should be unreachable");
3437 ec = error::token_verification_error::claim_value_missmatch;
3452 auto jc = ctx.
get_claim(in_header, json::type::integer, ec);
3455 auto c = jc.as_date();
3456 if (ctx.
current_time > c + std::chrono::seconds(leeway))
3458 ec = error::token_verification_error::token_expired;
3472 auto jc = ctx.
get_claim(in_header, json::type::integer, ec);
3475 auto c = jc.as_date();
3476 if (ctx.
current_time < c - std::chrono::seconds(leeway))
3478 ec = error::token_verification_error::token_expired;
3496 if (c.get_type() == json::type::string)
3498 if (expected.size() != 1 || *expected.begin() != c.
as_string())
3500 ec = error::token_verification_error::audience_missmatch;
3504 else if (c.get_type() == json::type::array)
3506 auto jc = c.as_set();
3507 for (
auto&
e : expected)
3509 if (jc.find(
e) == jc.end())
3511 ec = error::token_verification_error::audience_missmatch;
3518 ec = error::token_verification_error::claim_type_missmatch;
3532 : expected(to_lower_unicode(
e, loc)), locale(loc)
3538 const auto c = ctx.
get_claim(in_header, json::type::string, ec);
3541 if (to_lower_unicode(c.as_string(), locale) != expected)
3543 ec = error::token_verification_error::claim_value_missmatch;
3549 std::wstring_convert<std::codecvt_utf8<wchar_t>,
wchar_t> conv;
3550 auto wide = conv.from_bytes(
str);
3551 auto& f = std::use_facet<std::ctype<wchar_t>>(loc);
3552 f.tolower(&wide[0], &wide[0] + wide.size());
3553 return conv.to_bytes(wide);
3562 template <
typename Clock,
typename json_traits>
class verifier
3581 virtual ~algo_base() =
default;
3582 virtual void verify(
const std::string& data,
const std::string& sig,
3583 std::error_code& ec) = 0;
3585 template <
typename T>
struct algo :
public algo_base
3588 explicit algo(T a) : alg(a) {}
3589 void verify(
const std::string& data,
const std::string& sig, std::error_code& ec)
override
3591 alg.verify(data, sig, ec);
3595 std::unordered_map<typename json_traits::string_type, verify_check_fn_t> claims;
3597 size_t default_leeway = 0;
3601 std::unordered_map<std::string, std::shared_ptr<algo_base>> algs;
3612 if (!ctx.
jwt.has_expires_at())
3614 auto exp = ctx.
jwt.get_expires_at();
3617 ec = error::token_verification_error::token_expired;
3622 if (!ctx.
jwt.has_issued_at())
3624 auto iat = ctx.
jwt.get_issued_at();
3627 ec = error::token_verification_error::token_expired;
3632 if (!ctx.
jwt.has_not_before())
3634 auto nbf = ctx.
jwt.get_not_before();
3637 ec = error::token_verification_error::token_expired;
3649 default_leeway = leeway;
3698 std::locale locale = std::locale{})
3701 type, std::move(locale)});
3746 return with_audience(s);
3789 algs[alg.name()] = std::make_shared<algo<Algorithm>>(alg);
3812 const typename json_traits::string_type data =
3813 jwt.get_header_base64() +
"." +
jwt.get_payload_base64();
3814 const typename json_traits::string_type sig =
jwt.get_signature();
3815 const std::string algo =
jwt.get_algorithm();
3816 if (algs.count(algo) == 0)
3818 ec = error::token_verification_error::wrong_algorithm;
3821 algs.at(algo)->verify(data, sig, ec);
3826 for (
auto& c : claims)
3828 ctx.claim_key = c.first;
3844 template <
typename json_traits>
class jwk
3851 : jwk_claims(details::map_of_claims<json_traits>::parse_claims(
str))
3856 : jwk_claims(json_traits::as_object(
json))
3870 return get_jwk_claim(
"kty").as_string();
3879 typename json_traits::string_type
get_use()
const {
return get_jwk_claim(
"use").as_string(); }
3889 return get_jwk_claim(
"key_ops").as_set();
3900 return get_jwk_claim(
"alg").as_string();
3911 return get_jwk_claim(
"kid").as_string();
3924 typename json_traits::string_type
get_curve()
const {
return get_jwk_claim(
"crv").as_string(); }
3932 typename json_traits::array_type
get_x5c()
const {
return get_jwk_claim(
"x5c").as_array(); };
3940 typename json_traits::string_type
get_x5u()
const {
return get_jwk_claim(
"x5u").as_string(); };
3948 typename json_traits::string_type
get_x5t()
const {
return get_jwk_claim(
"x5t").as_string(); };
3958 return get_jwk_claim(
"x5t#S256").as_string();
3969 auto x5c_array = get_jwk_claim(
"x5c").as_array();
3970 if (x5c_array.size() == 0)
3973 return json_traits::as_string(x5c_array.front());
3986 bool has_use() const noexcept {
return has_jwk_claim(
"use"); }
4004 bool has_curve() const noexcept {
return has_jwk_claim(
"crv"); }
4010 bool has_key_id() const noexcept {
return has_jwk_claim(
"kid"); }
4016 bool has_x5u() const noexcept {
return has_jwk_claim(
"x5u"); }
4022 bool has_x5c() const noexcept {
return has_jwk_claim(
"x5c"); }
4028 bool has_x5t() const noexcept {
return has_jwk_claim(
"x5t"); }
4040 bool has_jwk_claim(
const typename json_traits::string_type& name)
const noexcept
4055 bool empty() const noexcept {
return jwk_claims.empty(); }
4068 template <
typename json_traits>
class jwks
4078 typename json_traits::value_type parsed_val;
4079 if (!json_traits::parse(parsed_val,
str))
4086 auto jwk_list = jwks_json.
get_claim(
"keys").as_array();
4087 std::transform(jwk_list.begin(), jwk_list.end(), std::back_inserter(jwk_claims),
4088 [](
const typename json_traits::value_type& val) { return jwk_t{val}; });
4102 bool has_jwk(
const typename json_traits::string_type& key_id)
const noexcept
4104 return find_by_kid(key_id) != end();
4114 const auto maybe = find_by_kid(key_id);
4121 jwt_vector_t jwk_claims;
4123 const_iterator find_by_kid(
const typename json_traits::string_type& key_id)
const noexcept
4125 return std::find_if(cbegin(), cend(),
4126 [key_id](
const jwk_t&
jwk)
4162 return verifier<default_clock, json_traits>(c);
4178 template <
typename json_traits,
typename Decode>
4191 template <
typename json_traits>
4197 template <
typename json_traits>
4203 template <
typename json_traits>
4210 template <
typename json_traits>
4213 return c.operator>>(is);
4216 template <
typename json_traits>
4222 #ifndef JWT_DISABLE_PICOJSON
4223 #include "traits/kazuho-picojson/defaults.h"