Conscience Core
jwt.h
Go to the documentation of this file.
1 #ifndef JWT_CPP_JWT_H
2 #define JWT_CPP_JWT_H
3 
4 #ifndef JWT_DISABLE_PICOJSON
5 #ifndef PICOJSON_USE_INT64
6 #define PICOJSON_USE_INT64
7 #endif
8 #include "picojson/picojson.h"
9 #endif
10 
11 #ifndef JWT_DISABLE_BASE64
12 #include "base.h"
13 #endif
14 
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>
23 
24 #include <algorithm>
25 #include <chrono>
26 #include <cmath>
27 #include <functional>
28 #include <iterator>
29 #include <locale>
30 #include <memory>
31 #include <set>
32 #include <system_error>
33 #include <type_traits>
34 #include <unordered_map>
35 #include <utility>
36 #include <vector>
37 
38 #if __cplusplus > 201103L
39 #include <codecvt>
40 #endif
41 
42 #if __cplusplus >= 201402L
43 #ifdef __has_include
44 #if __has_include(<experimental/type_traits>)
45 #include <experimental/type_traits>
46 #endif
47 #endif
48 #endif
49 
50 #if OPENSSL_VERSION_NUMBER >= 0x30000000L // 3.0.0
51 #define JWT_OPENSSL_3_0
52 #elif OPENSSL_VERSION_NUMBER >= 0x10101000L // 1.1.1
53 #define JWT_OPENSSL_1_1_1
54 #elif OPENSSL_VERSION_NUMBER >= 0x10100000L // 1.1.0
55 #define JWT_OPENSSL_1_1_0
56 #elif OPENSSL_VERSION_NUMBER >= 0x10000000L // 1.0.0
57 #define JWT_OPENSSL_1_0_0
58 #endif
59 
60 #if defined(LIBRESSL_VERSION_NUMBER)
61 #if LIBRESSL_VERSION_NUMBER >= 0x3050300fL
62 #define JWT_OPENSSL_1_1_0
63 #else
64 #define JWT_OPENSSL_1_0_0
65 #endif
66 #endif
67 
68 #if defined(LIBWOLFSSL_VERSION_HEX)
69 #define JWT_OPENSSL_1_1_1
70 #endif
71 
72 #ifndef JWT_CLAIM_EXPLICIT
73 #define JWT_CLAIM_EXPLICIT explicit
74 #endif
75 
83 namespace jwt {
87  using date = std::chrono::system_clock::time_point;
88 
92  namespace error {
93  struct signature_verification_exception : public std::system_error {
94  using system_error::system_error;
95  };
96  struct signature_generation_exception : public std::system_error {
97  using system_error::system_error;
98  };
99  struct rsa_exception : public std::system_error {
100  using system_error::system_error;
101  };
102  struct ecdsa_exception : public std::system_error {
103  using system_error::system_error;
104  };
105  struct token_verification_exception : public std::system_error {
106  using system_error::system_error;
107  };
111  enum class rsa_error {
112  ok = 0,
113  cert_load_failed = 10,
122  };
126  inline std::error_category& rsa_error_category() {
127  class rsa_error_cat : public std::error_category {
128  public:
129  const char* name() const noexcept override { return "rsa_error"; };
130  std::string message(int ev) const override {
131  switch (static_cast<rsa_error>(ev)) {
132  case rsa_error::ok: return "no error";
133  case rsa_error::cert_load_failed: return "error loading cert into memory";
134  case rsa_error::get_key_failed: return "error getting key from certificate";
135  case rsa_error::write_key_failed: return "error writing key data in PEM format";
136  case rsa_error::write_cert_failed: return "error writing cert data in PEM format";
137  case rsa_error::convert_to_pem_failed: return "failed to convert key to pem";
138  case rsa_error::load_key_bio_write: return "failed to load key: bio write failed";
139  case rsa_error::load_key_bio_read: return "failed to load key: bio read failed";
140  case rsa_error::create_mem_bio_failed: return "failed to create memory bio";
141  case rsa_error::no_key_provided: return "at least one of public or private key need to be present";
142  default: return "unknown RSA error";
143  }
144  }
145  };
146  static rsa_error_cat cat;
147  return cat;
148  }
149 
150  inline std::error_code make_error_code(rsa_error e) { return {static_cast<int>(e), rsa_error_category()}; }
154  enum class ecdsa_error {
155  ok = 0,
156  load_key_bio_write = 10,
161  invalid_key,
163  };
167  inline std::error_category& ecdsa_error_category() {
168  class ecdsa_error_cat : public std::error_category {
169  public:
170  const char* name() const noexcept override { return "ecdsa_error"; };
171  std::string message(int ev) const override {
172  switch (static_cast<ecdsa_error>(ev)) {
173  case ecdsa_error::ok: return "no error";
174  case ecdsa_error::load_key_bio_write: return "failed to load key: bio write failed";
175  case ecdsa_error::load_key_bio_read: return "failed to load key: bio read failed";
176  case ecdsa_error::create_mem_bio_failed: return "failed to create memory bio";
178  return "at least one of public or private key need to be present";
179  case ecdsa_error::invalid_key_size: return "invalid key size";
180  case ecdsa_error::invalid_key: return "invalid key";
181  case ecdsa_error::create_context_failed: return "failed to create context";
182  default: return "unknown ECDSA error";
183  }
184  }
185  };
186  static ecdsa_error_cat cat;
187  return cat;
188  }
189 
190  inline std::error_code make_error_code(ecdsa_error e) { return {static_cast<int>(e), ecdsa_error_category()}; }
191 
196  ok = 0,
197  invalid_signature = 10,
205  };
209  inline std::error_category& signature_verification_error_category() {
210  class verification_error_cat : public std::error_category {
211  public:
212  const char* name() const noexcept override { return "signature_verification_error"; };
213  std::string message(int ev) const override {
214  switch (static_cast<signature_verification_error>(ev)) {
215  case signature_verification_error::ok: return "no error";
216  case signature_verification_error::invalid_signature: return "invalid signature";
218  return "failed to verify signature: could not create context";
220  return "failed to verify signature: VerifyInit failed";
222  return "failed to verify signature: VerifyUpdate failed";
224  return "failed to verify signature: VerifyFinal failed";
226  return "failed to verify signature: Could not get key";
228  return "failed to verify signature: EVP_PKEY_CTX_set_rsa_pss_saltlen failed";
230  return "failed to verify signature: i2d_ECDSA_SIG failed";
231  default: return "unknown signature verification error";
232  }
233  }
234  };
235  static verification_error_cat cat;
236  return cat;
237  }
238 
239  inline std::error_code make_error_code(signature_verification_error e) {
240  return {static_cast<int>(e), signature_verification_error_category()};
241  }
242 
247  ok = 0,
248  hmac_failed = 10,
262  };
266  inline std::error_category& signature_generation_error_category() {
267  class signature_generation_error_cat : public std::error_category {
268  public:
269  const char* name() const noexcept override { return "signature_generation_error"; };
270  std::string message(int ev) const override {
271  switch (static_cast<signature_generation_error>(ev)) {
272  case signature_generation_error::ok: return "no error";
273  case signature_generation_error::hmac_failed: return "hmac failed";
275  return "failed to create signature: could not create context";
277  return "failed to create signature: SignInit failed";
279  return "failed to create signature: SignUpdate failed";
281  return "failed to create signature: SignFinal failed";
282  case signature_generation_error::ecdsa_do_sign_failed: return "failed to generate ecdsa signature";
284  return "failed to create signature: DigestInit failed";
286  return "failed to create signature: DigestUpdate failed";
288  return "failed to create signature: DigestFinal failed";
290  return "failed to create signature: EVP_PKEY_CTX_set_rsa_padding failed";
292  return "failed to create signature: RSA_private_encrypt failed";
294  return "failed to generate signature: Could not get key";
296  return "failed to create signature: EVP_PKEY_CTX_set_rsa_pss_saltlen failed";
298  return "failed to create signature: d2i_ECDSA_SIG failed";
299  default: return "unknown signature generation error";
300  }
301  }
302  };
303  static signature_generation_error_cat cat = {};
304  return cat;
305  }
306 
307  inline std::error_code make_error_code(signature_generation_error e) {
308  return {static_cast<int>(e), signature_generation_error_category()};
309  }
310 
315  ok = 0,
316  wrong_algorithm = 10,
322  };
326  inline std::error_category& token_verification_error_category() {
327  class token_verification_error_cat : public std::error_category {
328  public:
329  const char* name() const noexcept override { return "token_verification_error"; };
330  std::string message(int ev) const override {
331  switch (static_cast<token_verification_error>(ev)) {
332  case token_verification_error::ok: return "no error";
333  case token_verification_error::wrong_algorithm: return "wrong algorithm";
334  case token_verification_error::missing_claim: return "decoded JWT is missing required claim(s)";
336  return "claim type does not match expected type";
338  return "claim value does not match expected value";
339  case token_verification_error::token_expired: return "token expired";
341  return "token doesn't contain the required audience";
342  default: return "unknown token verification error";
343  }
344  }
345  };
346  static token_verification_error_cat cat = {};
347  return cat;
348  }
349 
350  inline std::error_code make_error_code(token_verification_error e) {
351  return {static_cast<int>(e), token_verification_error_category()};
352  }
353 
354  inline void throw_if_error(std::error_code ec) {
355  if (ec) {
356  if (ec.category() == rsa_error_category()) throw rsa_exception(ec);
357  if (ec.category() == ecdsa_error_category()) throw ecdsa_exception(ec);
358  if (ec.category() == signature_verification_error_category())
361  if (ec.category() == token_verification_error_category()) throw token_verification_exception(ec);
362  }
363  }
364  } // namespace error
365 } // namespace jwt
366 
367 namespace std {
368  template<>
369  struct is_error_code_enum<jwt::error::rsa_error> : true_type {};
370  template<>
371  struct is_error_code_enum<jwt::error::ecdsa_error> : true_type {};
372  template<>
373  struct is_error_code_enum<jwt::error::signature_verification_error> : true_type {};
374  template<>
375  struct is_error_code_enum<jwt::error::signature_generation_error> : true_type {};
376  template<>
377  struct is_error_code_enum<jwt::error::token_verification_error> : true_type {};
378 } // namespace std
379 
380 namespace jwt {
388  namespace helper {
397  public:
398  constexpr evp_pkey_handle() noexcept = default;
399 #ifdef JWT_OPENSSL_1_0_0
400 
404  explicit evp_pkey_handle(EVP_PKEY* key) { m_key = std::shared_ptr<EVP_PKEY>(key, EVP_PKEY_free); }
405 
406  EVP_PKEY* get() const noexcept { return m_key.get(); }
407  bool operator!() const noexcept { return m_key == nullptr; }
408  explicit operator bool() const noexcept { return m_key != nullptr; }
409 
410  private:
411  std::shared_ptr<EVP_PKEY> m_key{nullptr};
412 #else
413 
417  explicit constexpr evp_pkey_handle(EVP_PKEY* key) noexcept : m_key{key} {}
418  evp_pkey_handle(const evp_pkey_handle& other) : m_key{other.m_key} {
419  if (m_key != nullptr && EVP_PKEY_up_ref(m_key) != 1) throw std::runtime_error("EVP_PKEY_up_ref failed");
420  }
421 // C++11 requires the body of a constexpr constructor to be empty
422 #if __cplusplus >= 201402L
423  constexpr
424 #endif
426  : m_key{other.m_key} {
427  other.m_key = nullptr;
428  }
430  if (&other == this) return *this;
431  decrement_ref_count(m_key);
432  m_key = other.m_key;
433  increment_ref_count(m_key);
434  return *this;
435  }
437  if (&other == this) return *this;
438  decrement_ref_count(m_key);
439  m_key = other.m_key;
440  other.m_key = nullptr;
441  return *this;
442  }
443  evp_pkey_handle& operator=(EVP_PKEY* key) {
444  decrement_ref_count(m_key);
445  m_key = key;
446  increment_ref_count(m_key);
447  return *this;
448  }
449  ~evp_pkey_handle() noexcept { decrement_ref_count(m_key); }
450 
451  EVP_PKEY* get() const noexcept { return m_key; }
452  bool operator!() const noexcept { return m_key == nullptr; }
453  explicit operator bool() const noexcept { return m_key != nullptr; }
454 
455  private:
456  EVP_PKEY* m_key{nullptr};
457 
458  static void increment_ref_count(EVP_PKEY* key) {
459  if (key != nullptr && EVP_PKEY_up_ref(key) != 1) throw std::runtime_error("EVP_PKEY_up_ref failed");
460  }
461  static void decrement_ref_count(EVP_PKEY* key) noexcept {
462  if (key != nullptr) EVP_PKEY_free(key);
463  }
464 #endif
465  };
466 
467  inline std::unique_ptr<BIO, decltype(&BIO_free_all)> make_mem_buf_bio() {
468  return std::unique_ptr<BIO, decltype(&BIO_free_all)>(BIO_new(BIO_s_mem()), BIO_free_all);
469  }
470 
471  inline std::unique_ptr<BIO, decltype(&BIO_free_all)> make_mem_buf_bio(const std::string& data) {
472  return std::unique_ptr<BIO, decltype(&BIO_free_all)>(
473 #if OPENSSL_VERSION_NUMBER <= 0x10100003L
474  BIO_new_mem_buf(const_cast<char*>(data.data()), static_cast<int>(data.size())), BIO_free_all
475 #else
476  BIO_new_mem_buf(data.data(), static_cast<int>(data.size())), BIO_free_all
477 #endif
478  );
479  }
480 
481  inline std::unique_ptr<EVP_MD_CTX, void (*)(EVP_MD_CTX*)> make_evp_md_ctx() {
482  return
483 #ifdef JWT_OPENSSL_1_0_0
484  std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_destroy)>(EVP_MD_CTX_create(), &EVP_MD_CTX_destroy);
485 #else
486  std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)>(EVP_MD_CTX_new(), &EVP_MD_CTX_free);
487 #endif
488  }
489 
497  inline std::string extract_pubkey_from_cert(const std::string& certstr, const std::string& pw,
498  std::error_code& ec) {
499  ec.clear();
500  auto certbio = make_mem_buf_bio(certstr);
501  auto keybio = make_mem_buf_bio();
502  if (!certbio || !keybio) {
504  return {};
505  }
506 
507  std::unique_ptr<X509, decltype(&X509_free)> cert(
508  PEM_read_bio_X509(certbio.get(), nullptr, nullptr, const_cast<char*>(pw.c_str())), X509_free);
509  if (!cert) {
511  return {};
512  }
513  std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)> key(X509_get_pubkey(cert.get()), EVP_PKEY_free);
514  if (!key) {
516  return {};
517  }
518  if (PEM_write_bio_PUBKEY(keybio.get(), key.get()) == 0) {
520  return {};
521  }
522  char* ptr = nullptr;
523  auto len = BIO_get_mem_data(keybio.get(), &ptr);
524  if (len <= 0 || ptr == nullptr) {
526  return {};
527  }
528  return {ptr, static_cast<size_t>(len)};
529  }
530 
538  inline std::string extract_pubkey_from_cert(const std::string& certstr, const std::string& pw = "") {
539  std::error_code ec;
540  auto res = extract_pubkey_from_cert(certstr, pw, ec);
542  return res;
543  }
544 
559  template<typename Decode>
560  std::string convert_base64_der_to_pem(const std::string& cert_base64_der_str, Decode decode,
561  std::error_code& ec) {
562  ec.clear();
563  const auto decodedStr = decode(cert_base64_der_str);
564  auto c_str = reinterpret_cast<const unsigned char*>(decodedStr.c_str());
565 
566  std::unique_ptr<X509, decltype(&X509_free)> cert(
567  d2i_X509(NULL, &c_str, static_cast<int>(decodedStr.size())), X509_free);
568  auto certbio = make_mem_buf_bio();
569  if (!cert || !certbio) {
571  return {};
572  }
573 
574  if (!PEM_write_bio_X509(certbio.get(), cert.get())) {
576  return {};
577  }
578 
579  char* ptr = nullptr;
580  const auto len = BIO_get_mem_data(certbio.get(), &ptr);
581  if (len <= 0 || ptr == nullptr) {
583  return {};
584  }
585 
586  return {ptr, static_cast<size_t>(len)};
587  }
588 
603  template<typename Decode>
604  std::string convert_base64_der_to_pem(const std::string& cert_base64_der_str, Decode decode) {
605  std::error_code ec;
606  auto res = convert_base64_der_to_pem(cert_base64_der_str, std::move(decode), ec);
608  return res;
609  }
610 #ifndef JWT_DISABLE_BASE64
611 
620  inline std::string convert_base64_der_to_pem(const std::string& cert_base64_der_str, std::error_code& ec) {
621  auto decode = [](const std::string& token) {
622  return base::decode<alphabet::base64>(base::pad<alphabet::base64>(token));
623  };
624  return convert_base64_der_to_pem(cert_base64_der_str, std::move(decode), ec);
625  }
626 
636  inline std::string convert_base64_der_to_pem(const std::string& cert_base64_der_str) {
637  std::error_code ec;
638  auto res = convert_base64_der_to_pem(cert_base64_der_str, ec);
640  return res;
641  }
642 #endif
643 
652  inline evp_pkey_handle load_public_key_from_string(const std::string& key, const std::string& password,
653  std::error_code& ec) {
654  ec.clear();
655  auto pubkey_bio = make_mem_buf_bio();
656  if (!pubkey_bio) {
658  return {};
659  }
660  if (key.substr(0, 27) == "-----BEGIN CERTIFICATE-----") {
661  auto epkey = helper::extract_pubkey_from_cert(key, password, ec);
662  if (ec) return {};
663  const int len = static_cast<int>(epkey.size());
664  if (BIO_write(pubkey_bio.get(), epkey.data(), len) != len) {
666  return {};
667  }
668  } else {
669  const int len = static_cast<int>(key.size());
670  if (BIO_write(pubkey_bio.get(), key.data(), len) != len) {
672  return {};
673  }
674  }
675 
676  evp_pkey_handle pkey(PEM_read_bio_PUBKEY(
677  pubkey_bio.get(), nullptr, nullptr,
678  (void*)password.data())); // NOLINT(google-readability-casting) requires `const_cast`
679  if (!pkey) ec = error::rsa_error::load_key_bio_read;
680  return pkey;
681  }
682 
692  inline evp_pkey_handle load_public_key_from_string(const std::string& key, const std::string& password = "") {
693  std::error_code ec;
694  auto res = load_public_key_from_string(key, password, ec);
696  return res;
697  }
698 
706  inline evp_pkey_handle load_private_key_from_string(const std::string& key, const std::string& password,
707  std::error_code& ec) {
708  auto privkey_bio = make_mem_buf_bio();
709  if (!privkey_bio) {
711  return {};
712  }
713  const int len = static_cast<int>(key.size());
714  if (BIO_write(privkey_bio.get(), key.data(), len) != len) {
716  return {};
717  }
718  evp_pkey_handle pkey(
719  PEM_read_bio_PrivateKey(privkey_bio.get(), nullptr, nullptr, const_cast<char*>(password.c_str())));
720  if (!pkey) ec = error::rsa_error::load_key_bio_read;
721  return pkey;
722  }
723 
731  inline evp_pkey_handle load_private_key_from_string(const std::string& key, const std::string& password = "") {
732  std::error_code ec;
733  auto res = load_private_key_from_string(key, password, ec);
735  return res;
736  }
737 
747  inline evp_pkey_handle load_public_ec_key_from_string(const std::string& key, const std::string& password,
748  std::error_code& ec) {
749  ec.clear();
750  auto pubkey_bio = make_mem_buf_bio();
751  if (!pubkey_bio) {
753  return {};
754  }
755  if (key.substr(0, 27) == "-----BEGIN CERTIFICATE-----") {
756  auto epkey = helper::extract_pubkey_from_cert(key, password, ec);
757  if (ec) return {};
758  const int len = static_cast<int>(epkey.size());
759  if (BIO_write(pubkey_bio.get(), epkey.data(), len) != len) {
761  return {};
762  }
763  } else {
764  const int len = static_cast<int>(key.size());
765  if (BIO_write(pubkey_bio.get(), key.data(), len) != len) {
767  return {};
768  }
769  }
770 
771  evp_pkey_handle pkey(PEM_read_bio_PUBKEY(
772  pubkey_bio.get(), nullptr, nullptr,
773  (void*)password.data())); // NOLINT(google-readability-casting) requires `const_cast`
775  return pkey;
776  }
777 
787  inline evp_pkey_handle load_public_ec_key_from_string(const std::string& key,
788  const std::string& password = "") {
789  std::error_code ec;
790  auto res = load_public_ec_key_from_string(key, password, ec);
792  return res;
793  }
794 
802  inline evp_pkey_handle load_private_ec_key_from_string(const std::string& key, const std::string& password,
803  std::error_code& ec) {
804  auto privkey_bio = make_mem_buf_bio();
805  if (!privkey_bio) {
807  return {};
808  }
809  const int len = static_cast<int>(key.size());
810  if (BIO_write(privkey_bio.get(), key.data(), len) != len) {
812  return {};
813  }
814  evp_pkey_handle pkey(
815  PEM_read_bio_PrivateKey(privkey_bio.get(), nullptr, nullptr, const_cast<char*>(password.c_str())));
817  return pkey;
818  }
819 
827  inline evp_pkey_handle load_private_ec_key_from_string(const std::string& key,
828  const std::string& password = "") {
829  std::error_code ec;
830  auto res = load_private_ec_key_from_string(key, password, ec);
832  return res;
833  }
834 
840  inline
841 #ifdef JWT_OPENSSL_1_0_0
842  std::string
843  bn2raw(BIGNUM* bn)
844 #else
845  std::string
846  bn2raw(const BIGNUM* bn)
847 #endif
848  {
849  std::string res(BN_num_bytes(bn), '\0');
850  BN_bn2bin(bn, (unsigned char*)res.data()); // NOLINT(google-readability-casting) requires `const_cast`
851  return res;
852  }
858  inline std::unique_ptr<BIGNUM, decltype(&BN_free)> raw2bn(const std::string& raw) {
859  return std::unique_ptr<BIGNUM, decltype(&BN_free)>(
860  BN_bin2bn(reinterpret_cast<const unsigned char*>(raw.data()), static_cast<int>(raw.size()), nullptr),
861  BN_free);
862  }
863  } // namespace helper
864 
874  namespace algorithm {
880  struct none {
884  std::string sign(const std::string& /*unused*/, std::error_code& ec) const {
885  ec.clear();
886  return {};
887  }
895  void verify(const std::string& /*unused*/, const std::string& signature, std::error_code& ec) const {
896  ec.clear();
897  if (!signature.empty()) { ec = error::signature_verification_error::invalid_signature; }
898  }
900  std::string name() const { return "none"; }
901  };
905  struct hmacsha {
912  hmacsha(std::string key, const EVP_MD* (*md)(), std::string name)
913  : secret(std::move(key)), md(md), alg_name(std::move(name)) {}
920  std::string sign(const std::string& data, std::error_code& ec) const {
921  ec.clear();
922  std::string res(static_cast<size_t>(EVP_MAX_MD_SIZE), '\0');
923  auto len = static_cast<unsigned int>(res.size());
924  if (HMAC(md(), secret.data(), static_cast<int>(secret.size()),
925  reinterpret_cast<const unsigned char*>(data.data()), static_cast<int>(data.size()),
926  (unsigned char*)res.data(), // NOLINT(google-readability-casting) requires `const_cast`
927  &len) == nullptr) {
929  return {};
930  }
931  res.resize(len);
932  return res;
933  }
940  void verify(const std::string& data, const std::string& signature, std::error_code& ec) const {
941  ec.clear();
942  auto res = sign(data, ec);
943  if (ec) return;
944 
945  bool matched = true;
946  for (size_t i = 0; i < std::min<size_t>(res.size(), signature.size()); i++)
947  if (res[i] != signature[i]) matched = false;
948  if (res.size() != signature.size()) matched = false;
949  if (!matched) {
951  return;
952  }
953  }
958  std::string name() const { return alg_name; }
959 
960  private:
962  const std::string secret;
964  const EVP_MD* (*md)();
966  const std::string alg_name;
967  };
971  struct rsa {
981  rsa(const std::string& public_key, const std::string& private_key, const std::string& public_key_password,
982  const std::string& private_key_password, const EVP_MD* (*md)(), std::string name)
983  : md(md), alg_name(std::move(name)) {
984  if (!private_key.empty()) {
985  pkey = helper::load_private_key_from_string(private_key, private_key_password);
986  } else if (!public_key.empty()) {
987  pkey = helper::load_public_key_from_string(public_key, public_key_password);
988  } else
990  }
997  std::string sign(const std::string& data, std::error_code& ec) const {
998  ec.clear();
999  auto ctx = helper::make_evp_md_ctx();
1000  if (!ctx) {
1002  return {};
1003  }
1004  if (!EVP_SignInit(ctx.get(), md())) {
1006  return {};
1007  }
1008 
1009  std::string res(EVP_PKEY_size(pkey.get()), '\0');
1010  unsigned int len = 0;
1011 
1012  if (!EVP_SignUpdate(ctx.get(), data.data(), data.size())) {
1014  return {};
1015  }
1016  if (EVP_SignFinal(ctx.get(), (unsigned char*)res.data(), &len, pkey.get()) == 0) {
1018  return {};
1019  }
1020 
1021  res.resize(len);
1022  return res;
1023  }
1030  void verify(const std::string& data, const std::string& signature, std::error_code& ec) const {
1031  ec.clear();
1032  auto ctx = helper::make_evp_md_ctx();
1033  if (!ctx) {
1035  return;
1036  }
1037  if (!EVP_VerifyInit(ctx.get(), md())) {
1039  return;
1040  }
1041  if (!EVP_VerifyUpdate(ctx.get(), data.data(), data.size())) {
1043  return;
1044  }
1045  auto res = EVP_VerifyFinal(ctx.get(), reinterpret_cast<const unsigned char*>(signature.data()),
1046  static_cast<unsigned int>(signature.size()), pkey.get());
1047  if (res != 1) {
1049  return;
1050  }
1051  }
1056  std::string name() const { return alg_name; }
1057 
1058  private:
1062  const EVP_MD* (*md)();
1064  const std::string alg_name;
1065  };
1069  struct ecdsa {
1081  ecdsa(const std::string& public_key, const std::string& private_key, const std::string& public_key_password,
1082  const std::string& private_key_password, const EVP_MD* (*md)(), std::string name, size_t siglen)
1083  : md(md), alg_name(std::move(name)), signature_length(siglen) {
1084  if (!private_key.empty()) {
1085  pkey = helper::load_private_ec_key_from_string(private_key, private_key_password);
1086  check_private_key(pkey.get());
1087  } else if (!public_key.empty()) {
1088  pkey = helper::load_public_ec_key_from_string(public_key, public_key_password);
1089  check_public_key(pkey.get());
1090  } else {
1092  }
1094 
1095  size_t keysize = EVP_PKEY_bits(pkey.get());
1096  if (keysize != signature_length * 4 && (signature_length != 132 || keysize != 521))
1098  }
1099 
1106  std::string sign(const std::string& data, std::error_code& ec) const {
1107  ec.clear();
1108  auto ctx = helper::make_evp_md_ctx();
1109  if (!ctx) {
1111  return {};
1112  }
1113  if (!EVP_DigestSignInit(ctx.get(), nullptr, md(), nullptr, pkey.get())) {
1115  return {};
1116  }
1117  if (!EVP_DigestUpdate(ctx.get(), data.data(), data.size())) {
1119  return {};
1120  }
1121 
1122  size_t len = 0;
1123  if (!EVP_DigestSignFinal(ctx.get(), nullptr, &len)) {
1125  return {};
1126  }
1127  std::string res(len, '\0');
1128  if (!EVP_DigestSignFinal(ctx.get(), (unsigned char*)res.data(), &len)) {
1130  return {};
1131  }
1132 
1133  res.resize(len);
1134  return der_to_p1363_signature(res, ec);
1135  }
1136 
1143  void verify(const std::string& data, const std::string& signature, std::error_code& ec) const {
1144  ec.clear();
1145  std::string der_signature = p1363_to_der_signature(signature, ec);
1146  if (ec) { return; }
1147 
1148  auto ctx = helper::make_evp_md_ctx();
1149  if (!ctx) {
1151  return;
1152  }
1153  if (!EVP_DigestVerifyInit(ctx.get(), nullptr, md(), nullptr, pkey.get())) {
1155  return;
1156  }
1157  if (!EVP_DigestUpdate(ctx.get(), data.data(), data.size())) {
1159  return;
1160  }
1161 
1162 #if OPENSSL_VERSION_NUMBER < 0x10002000L
1163  unsigned char* der_sig_data = reinterpret_cast<unsigned char*>(const_cast<char*>(der_signature.data()));
1164 #else
1165  const unsigned char* der_sig_data = reinterpret_cast<const unsigned char*>(der_signature.data());
1166 #endif
1167  auto res =
1168  EVP_DigestVerifyFinal(ctx.get(), der_sig_data, static_cast<unsigned int>(der_signature.length()));
1169  if (res == 0) {
1171  return;
1172  }
1173  if (res == -1) {
1175  return;
1176  }
1177  }
1182  std::string name() const { return alg_name; }
1183 
1184  private:
1185  static void check_public_key(EVP_PKEY* pkey) {
1186 #ifdef JWT_OPENSSL_3_0
1187  std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)> ctx(
1188  EVP_PKEY_CTX_new_from_pkey(nullptr, pkey, nullptr), EVP_PKEY_CTX_free);
1190  if (EVP_PKEY_public_check(ctx.get()) != 1) {
1192  }
1193 #else
1194  std::unique_ptr<EC_KEY, decltype(&EC_KEY_free)> eckey(EVP_PKEY_get1_EC_KEY(pkey), EC_KEY_free);
1195  if (!eckey) { throw error::ecdsa_exception(error::ecdsa_error::invalid_key); }
1196  if (EC_KEY_check_key(eckey.get()) == 0) throw error::ecdsa_exception(error::ecdsa_error::invalid_key);
1197 #endif
1198  }
1199 
1200  static void check_private_key(EVP_PKEY* pkey) {
1201 #ifdef JWT_OPENSSL_3_0
1202  std::unique_ptr<EVP_PKEY_CTX, decltype(&EVP_PKEY_CTX_free)> ctx(
1203  EVP_PKEY_CTX_new_from_pkey(nullptr, pkey, nullptr), EVP_PKEY_CTX_free);
1204  if (!ctx) { throw error::ecdsa_exception(error::ecdsa_error::create_context_failed); }
1205  if (EVP_PKEY_private_check(ctx.get()) != 1) {
1206  throw error::ecdsa_exception(error::ecdsa_error::invalid_key);
1207  }
1208 #else
1209  std::unique_ptr<EC_KEY, decltype(&EC_KEY_free)> eckey(EVP_PKEY_get1_EC_KEY(pkey), EC_KEY_free);
1210  if (!eckey) { throw error::ecdsa_exception(error::ecdsa_error::invalid_key); }
1211  if (EC_KEY_check_key(eckey.get()) == 0) throw error::ecdsa_exception(error::ecdsa_error::invalid_key);
1212 #endif
1213  }
1214 
1215  std::string der_to_p1363_signature(const std::string& der_signature, std::error_code& ec) const {
1216  const unsigned char* possl_signature = reinterpret_cast<const unsigned char*>(der_signature.data());
1217  std::unique_ptr<ECDSA_SIG, decltype(&ECDSA_SIG_free)> sig(
1218  d2i_ECDSA_SIG(nullptr, &possl_signature, der_signature.length()), ECDSA_SIG_free);
1219  if (!sig) {
1221  return {};
1222  }
1223 
1224 #ifdef JWT_OPENSSL_1_0_0
1225 
1226  auto rr = helper::bn2raw(sig->r);
1227  auto rs = helper::bn2raw(sig->s);
1228 #else
1229  const BIGNUM* r;
1230  const BIGNUM* s;
1231  ECDSA_SIG_get0(sig.get(), &r, &s);
1232  auto rr = helper::bn2raw(r);
1233  auto rs = helper::bn2raw(s);
1234 #endif
1235  if (rr.size() > signature_length / 2 || rs.size() > signature_length / 2)
1236  throw std::logic_error("bignum size exceeded expected length");
1237  rr.insert(0, signature_length / 2 - rr.size(), '\0');
1238  rs.insert(0, signature_length / 2 - rs.size(), '\0');
1239  return rr + rs;
1240  }
1241 
1242  std::string p1363_to_der_signature(const std::string& signature, std::error_code& ec) const {
1243  ec.clear();
1244  auto r = helper::raw2bn(signature.substr(0, signature.size() / 2));
1245  auto s = helper::raw2bn(signature.substr(signature.size() / 2));
1246 
1247  ECDSA_SIG* psig;
1248 #ifdef JWT_OPENSSL_1_0_0
1249  ECDSA_SIG sig;
1250  sig.r = r.get();
1251  sig.s = s.get();
1252  psig = &sig;
1253 #else
1254  std::unique_ptr<ECDSA_SIG, decltype(&ECDSA_SIG_free)> sig(ECDSA_SIG_new(), ECDSA_SIG_free);
1255  if (!sig) {
1257  return {};
1258  }
1259  ECDSA_SIG_set0(sig.get(), r.release(), s.release());
1260  psig = sig.get();
1261 #endif
1262 
1263  int length = i2d_ECDSA_SIG(psig, nullptr);
1264  if (length < 0) {
1266  return {};
1267  }
1268  std::string der_signature(length, '\0');
1269  unsigned char* psbuffer = (unsigned char*)der_signature.data();
1270  length = i2d_ECDSA_SIG(psig, &psbuffer);
1271  if (length < 0) {
1273  return {};
1274  }
1275  der_signature.resize(length);
1276  return der_signature;
1277  }
1278 
1280  helper::evp_pkey_handle pkey;
1282  const EVP_MD* (*md)();
1284  const std::string alg_name;
1286  const size_t signature_length;
1287  };
1288 
1289 #if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
1290 
1298  struct eddsa {
1309  eddsa(const std::string& public_key, const std::string& private_key, const std::string& public_key_password,
1310  const std::string& private_key_password, std::string name)
1311  : alg_name(std::move(name)) {
1312  if (!private_key.empty()) {
1313  pkey = helper::load_private_key_from_string(private_key, private_key_password);
1314  } else if (!public_key.empty()) {
1315  pkey = helper::load_public_key_from_string(public_key, public_key_password);
1316  } else
1318  }
1325  std::string sign(const std::string& data, std::error_code& ec) const {
1326  ec.clear();
1327  auto ctx = helper::make_evp_md_ctx();
1328  if (!ctx) {
1330  return {};
1331  }
1332  if (!EVP_DigestSignInit(ctx.get(), nullptr, nullptr, nullptr, pkey.get())) {
1334  return {};
1335  }
1336 
1337  size_t len = EVP_PKEY_size(pkey.get());
1338  std::string res(len, '\0');
1339 
1340 // LibreSSL is the special kid in the block, as it does not support EVP_DigestSign.
1341 // OpenSSL on the otherhand does not support using EVP_DigestSignUpdate for eddsa, which is why we end up with this
1342 // mess.
1343 #if defined(LIBRESSL_VERSION_NUMBER) || defined(LIBWOLFSSL_VERSION_HEX)
1344  ERR_clear_error();
1345  if (EVP_DigestSignUpdate(ctx.get(), reinterpret_cast<const unsigned char*>(data.data()), data.size()) !=
1346  1) {
1347  std::cout << ERR_error_string(ERR_get_error(), NULL) << std::endl;
1349  return {};
1350  }
1351  if (EVP_DigestSignFinal(ctx.get(), reinterpret_cast<unsigned char*>(&res[0]), &len) != 1) {
1353  return {};
1354  }
1355 #else
1356  if (EVP_DigestSign(ctx.get(), reinterpret_cast<unsigned char*>(&res[0]), &len,
1357  reinterpret_cast<const unsigned char*>(data.data()), data.size()) != 1) {
1359  return {};
1360  }
1361 #endif
1362 
1363  res.resize(len);
1364  return res;
1365  }
1366 
1373  void verify(const std::string& data, const std::string& signature, std::error_code& ec) const {
1374  ec.clear();
1375  auto ctx = helper::make_evp_md_ctx();
1376  if (!ctx) {
1378  return;
1379  }
1380  if (!EVP_DigestVerifyInit(ctx.get(), nullptr, nullptr, nullptr, pkey.get())) {
1382  return;
1383  }
1384 // LibreSSL is the special kid in the block, as it does not support EVP_DigestVerify.
1385 // OpenSSL on the otherhand does not support using EVP_DigestVerifyUpdate for eddsa, which is why we end up with this
1386 // mess.
1387 #if defined(LIBRESSL_VERSION_NUMBER) || defined(LIBWOLFSSL_VERSION_HEX)
1388  if (EVP_DigestVerifyUpdate(ctx.get(), reinterpret_cast<const unsigned char*>(data.data()),
1389  data.size()) != 1) {
1391  return;
1392  }
1393  if (EVP_DigestVerifyFinal(ctx.get(), reinterpret_cast<const unsigned char*>(signature.data()),
1394  signature.size()) != 1) {
1396  return;
1397  }
1398 #else
1399  auto res = EVP_DigestVerify(ctx.get(), reinterpret_cast<const unsigned char*>(signature.data()),
1400  signature.size(), reinterpret_cast<const unsigned char*>(data.data()),
1401  data.size());
1402  if (res != 1) {
1404  return;
1405  }
1406 #endif
1407  }
1412  std::string name() const { return alg_name; }
1413 
1414  private:
1418  const std::string alg_name;
1419  };
1420 #endif
1421 
1424  struct pss {
1434  pss(const std::string& public_key, const std::string& private_key, const std::string& public_key_password,
1435  const std::string& private_key_password, const EVP_MD* (*md)(), std::string name)
1436  : md(md), alg_name(std::move(name)) {
1437  if (!private_key.empty()) {
1438  pkey = helper::load_private_key_from_string(private_key, private_key_password);
1439  } else if (!public_key.empty()) {
1440  pkey = helper::load_public_key_from_string(public_key, public_key_password);
1441  } else
1443  }
1444 
1451  std::string sign(const std::string& data, std::error_code& ec) const {
1452  ec.clear();
1453  auto md_ctx = helper::make_evp_md_ctx();
1454  if (!md_ctx) {
1456  return {};
1457  }
1458  EVP_PKEY_CTX* ctx = nullptr;
1459  if (EVP_DigestSignInit(md_ctx.get(), &ctx, md(), nullptr, pkey.get()) != 1) {
1461  return {};
1462  }
1463  if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
1465  return {};
1466  }
1467 // wolfSSL does not require EVP_PKEY_CTX_set_rsa_pss_saltlen. The default behavior
1468 // sets the salt length to the hash length. Unlike OpenSSL which exposes this functionality.
1469 #ifndef LIBWOLFSSL_VERSION_HEX
1470  if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0) {
1472  return {};
1473  }
1474 #endif
1475  if (EVP_DigestUpdate(md_ctx.get(), data.data(), data.size()) != 1) {
1477  return {};
1478  }
1479 
1480  size_t size = EVP_PKEY_size(pkey.get());
1481  std::string res(size, 0x00);
1482  if (EVP_DigestSignFinal(
1483  md_ctx.get(),
1484  (unsigned char*)res.data(), // NOLINT(google-readability-casting) requires `const_cast`
1485  &size) <= 0) {
1487  return {};
1488  }
1489 
1490  return res;
1491  }
1492 
1499  void verify(const std::string& data, const std::string& signature, std::error_code& ec) const {
1500  ec.clear();
1501 
1502  auto md_ctx = helper::make_evp_md_ctx();
1503  if (!md_ctx) {
1505  return;
1506  }
1507  EVP_PKEY_CTX* ctx = nullptr;
1508  if (EVP_DigestVerifyInit(md_ctx.get(), &ctx, md(), nullptr, pkey.get()) != 1) {
1510  return;
1511  }
1512  if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
1514  return;
1515  }
1516 // wolfSSL does not require EVP_PKEY_CTX_set_rsa_pss_saltlen. The default behavior
1517 // sets the salt length to the hash length. Unlike OpenSSL which exposes this functionality.
1518 #ifndef LIBWOLFSSL_VERSION_HEX
1519  if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0) {
1521  return;
1522  }
1523 #endif
1524  if (EVP_DigestUpdate(md_ctx.get(), data.data(), data.size()) != 1) {
1526  return;
1527  }
1528 
1529  if (EVP_DigestVerifyFinal(md_ctx.get(), (unsigned char*)signature.data(), signature.size()) <= 0) {
1531  return;
1532  }
1533  }
1538  std::string name() const { return alg_name; }
1539 
1540  private:
1544  const EVP_MD* (*md)();
1546  const std::string alg_name;
1547  };
1548 
1552  struct hs256 : public hmacsha {
1557  explicit hs256(std::string key) : hmacsha(std::move(key), EVP_sha256, "HS256") {}
1558  };
1562  struct hs384 : public hmacsha {
1567  explicit hs384(std::string key) : hmacsha(std::move(key), EVP_sha384, "HS384") {}
1568  };
1572  struct hs512 : public hmacsha {
1577  explicit hs512(std::string key) : hmacsha(std::move(key), EVP_sha512, "HS512") {}
1578  };
1582  struct rs256 : public rsa {
1590  explicit rs256(const std::string& public_key, const std::string& private_key = "",
1591  const std::string& public_key_password = "", const std::string& private_key_password = "")
1592  : rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256, "RS256") {}
1593  };
1597  struct rs384 : public rsa {
1605  explicit rs384(const std::string& public_key, const std::string& private_key = "",
1606  const std::string& public_key_password = "", const std::string& private_key_password = "")
1607  : rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384, "RS384") {}
1608  };
1612  struct rs512 : public rsa {
1620  explicit rs512(const std::string& public_key, const std::string& private_key = "",
1621  const std::string& public_key_password = "", const std::string& private_key_password = "")
1622  : rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512, "RS512") {}
1623  };
1627  struct es256 : public ecdsa {
1637  explicit es256(const std::string& public_key, const std::string& private_key = "",
1638  const std::string& public_key_password = "", const std::string& private_key_password = "")
1639  : ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256, "ES256", 64) {}
1640  };
1644  struct es384 : public ecdsa {
1654  explicit es384(const std::string& public_key, const std::string& private_key = "",
1655  const std::string& public_key_password = "", const std::string& private_key_password = "")
1656  : ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384, "ES384", 96) {}
1657  };
1661  struct es512 : public ecdsa {
1671  explicit es512(const std::string& public_key, const std::string& private_key = "",
1672  const std::string& public_key_password = "", const std::string& private_key_password = "")
1673  : ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512, "ES512", 132) {}
1674  };
1678  struct es256k : public ecdsa {
1687  explicit es256k(const std::string& public_key, const std::string& private_key = "",
1688  const std::string& public_key_password = "", const std::string& private_key_password = "")
1689  : ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256, "ES256K", 64) {}
1690  };
1691 
1692 #if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0)
1693 
1700  struct ed25519 : public eddsa {
1710  explicit ed25519(const std::string& public_key, const std::string& private_key = "",
1711  const std::string& public_key_password = "", const std::string& private_key_password = "")
1712  : eddsa(public_key, private_key, public_key_password, private_key_password, "EdDSA") {}
1713  };
1714 
1722  struct ed448 : public eddsa {
1732  explicit ed448(const std::string& public_key, const std::string& private_key = "",
1733  const std::string& public_key_password = "", const std::string& private_key_password = "")
1734  : eddsa(public_key, private_key, public_key_password, private_key_password, "EdDSA") {}
1735  };
1736 #endif
1737 
1741  struct ps256 : public pss {
1749  explicit ps256(const std::string& public_key, const std::string& private_key = "",
1750  const std::string& public_key_password = "", const std::string& private_key_password = "")
1751  : pss(public_key, private_key, public_key_password, private_key_password, EVP_sha256, "PS256") {}
1752  };
1756  struct ps384 : public pss {
1764  explicit ps384(const std::string& public_key, const std::string& private_key = "",
1765  const std::string& public_key_password = "", const std::string& private_key_password = "")
1766  : pss(public_key, private_key, public_key_password, private_key_password, EVP_sha384, "PS384") {}
1767  };
1771  struct ps512 : public pss {
1779  explicit ps512(const std::string& public_key, const std::string& private_key = "",
1780  const std::string& public_key_password = "", const std::string& private_key_password = "")
1781  : pss(public_key, private_key, public_key_password, private_key_password, EVP_sha512, "PS512") {}
1782  };
1783  } // namespace algorithm
1784 
1788  namespace json {
1794  enum class type { boolean, integer, number, string, array, object };
1795  } // namespace json
1796 
1797  namespace details {
1798 #ifdef __cpp_lib_void_t
1799  template<typename... Ts>
1800  using void_t = std::void_t<Ts...>;
1801 #else
1802  // https://en.cppreference.com/w/cpp/types/void_t
1803  template<typename... Ts>
1804  struct make_void {
1805  using type = void;
1806  };
1807 
1808  template<typename... Ts>
1809  using void_t = typename make_void<Ts...>::type;
1810 #endif
1811 
1812 #ifdef __cpp_lib_experimental_detect
1813  template<template<typename...> class _Op, typename... _Args>
1814  using is_detected = std::experimental::is_detected<_Op, _Args...>;
1815 
1816  template<template<typename...> class _Op, typename... _Args>
1817  using is_detected_t = std::experimental::detected_t<_Op, _Args...>;
1818 #else
1819  struct nonesuch {
1820  nonesuch() = delete;
1821  ~nonesuch() = delete;
1822  nonesuch(nonesuch const&) = delete;
1823  nonesuch(nonesuch const&&) = delete;
1824  void operator=(nonesuch const&) = delete;
1825  void operator=(nonesuch&&) = delete;
1826  };
1827 
1828  // https://en.cppreference.com/w/cpp/experimental/is_detected
1829  template<class Default, class AlwaysVoid, template<class...> class Op, class... Args>
1830  struct detector {
1831  using value = std::false_type;
1832  using type = Default;
1833  };
1834 
1835  template<class Default, template<class...> class Op, class... Args>
1836  struct detector<Default, void_t<Op<Args...>>, Op, Args...> {
1837  using value = std::true_type;
1838  using type = Op<Args...>;
1839  };
1840 
1841  template<template<class...> class Op, class... Args>
1842  using is_detected = typename detector<nonesuch, void, Op, Args...>::value;
1843 
1844  template<template<class...> class Op, class... Args>
1845  using is_detected_t = typename detector<nonesuch, void, Op, Args...>::type;
1846 #endif
1847 
1848  template<typename traits_type>
1849  using get_type_function = decltype(traits_type::get_type);
1850 
1851  template<typename traits_type, typename value_type>
1852  using is_get_type_signature =
1853  typename std::is_same<get_type_function<traits_type>, json::type(const value_type&)>;
1854 
1855  template<typename traits_type, typename value_type>
1858  std::is_function<get_type_function<traits_type>>::value &&
1860  };
1861 
1862  template<typename traits_type>
1863  using as_object_function = decltype(traits_type::as_object);
1864 
1865  template<typename traits_type, typename value_type, typename object_type>
1866  using is_as_object_signature =
1867  typename std::is_same<as_object_function<traits_type>, object_type(const value_type&)>;
1868 
1869  template<typename traits_type, typename value_type, typename object_type>
1871  static constexpr auto value = std::is_constructible<value_type, object_type>::value &&
1873  std::is_function<as_object_function<traits_type>>::value &&
1875  };
1876 
1877  template<typename traits_type>
1878  using as_array_function = decltype(traits_type::as_array);
1879 
1880  template<typename traits_type, typename value_type, typename array_type>
1881  using is_as_array_signature =
1882  typename std::is_same<as_array_function<traits_type>, array_type(const value_type&)>;
1883 
1884  template<typename traits_type, typename value_type, typename array_type>
1886  static constexpr auto value = std::is_constructible<value_type, array_type>::value &&
1888  std::is_function<as_array_function<traits_type>>::value &&
1890  };
1891 
1892  template<typename traits_type>
1893  using as_string_function = decltype(traits_type::as_string);
1894 
1895  template<typename traits_type, typename value_type, typename string_type>
1896  using is_as_string_signature =
1897  typename std::is_same<as_string_function<traits_type>, string_type(const value_type&)>;
1898 
1899  template<typename traits_type, typename value_type, typename string_type>
1901  static constexpr auto value = std::is_constructible<value_type, string_type>::value &&
1903  std::is_function<as_string_function<traits_type>>::value &&
1905  };
1906 
1907  template<typename traits_type>
1908  using as_number_function = decltype(traits_type::as_number);
1909 
1910  template<typename traits_type, typename value_type, typename number_type>
1911  using is_as_number_signature =
1912  typename std::is_same<as_number_function<traits_type>, number_type(const value_type&)>;
1913 
1914  template<typename traits_type, typename value_type, typename number_type>
1916  static constexpr auto value = std::is_floating_point<number_type>::value &&
1917  std::is_constructible<value_type, number_type>::value &&
1919  std::is_function<as_number_function<traits_type>>::value &&
1921  };
1922 
1923  template<typename traits_type>
1924  using as_integer_function = decltype(traits_type::as_int);
1925 
1926  template<typename traits_type, typename value_type, typename integer_type>
1927  using is_as_integer_signature =
1928  typename std::is_same<as_integer_function<traits_type>, integer_type(const value_type&)>;
1929 
1930  template<typename traits_type, typename value_type, typename integer_type>
1932  static constexpr auto value = std::is_signed<integer_type>::value &&
1933  !std::is_floating_point<integer_type>::value &&
1934  std::is_constructible<value_type, integer_type>::value &&
1936  std::is_function<as_integer_function<traits_type>>::value &&
1938  };
1939 
1940  template<typename traits_type>
1941  using as_boolean_function = decltype(traits_type::as_bool);
1942 
1943  template<typename traits_type, typename value_type, typename boolean_type>
1944  using is_as_boolean_signature =
1945  typename std::is_same<as_boolean_function<traits_type>, boolean_type(const value_type&)>;
1946 
1947  template<typename traits_type, typename value_type, typename boolean_type>
1949  static constexpr auto value = std::is_convertible<boolean_type, bool>::value &&
1950  std::is_constructible<value_type, boolean_type>::value &&
1952  std::is_function<as_boolean_function<traits_type>>::value &&
1954  };
1955 
1956  template<typename traits>
1958  // Internal assertions for better feedback
1960  "traits must provide `jwt::json::type get_type(const value_type&)`");
1962  "traits must provide `object_type as_object(const value_type&)`");
1964  "traits must provide `array_type as_array(const value_type&)`");
1966  "traits must provide `string_type as_string(const value_type&)`");
1968  "traits must provide `number_type as_number(const value_type&)`");
1969  static_assert(
1971  "traits must provide `integer_type as_int(const value_type&)`");
1972  static_assert(
1974  "traits must provide `boolean_type as_bool(const value_type&)`");
1975 
1976  static constexpr auto value =
1984  };
1985 
1986  template<typename value_type>
1988  static constexpr auto value =
1989  std::is_default_constructible<value_type>::value &&
1990  std::is_constructible<value_type, const value_type&>::value && // a more generic is_copy_constructible
1991  std::is_move_constructible<value_type>::value && std::is_assignable<value_type, value_type>::value &&
1992  std::is_copy_assignable<value_type>::value && std::is_move_assignable<value_type>::value;
1993  // TODO(prince-chrismc): Stream operators
1994  };
1995 
1996  template<typename traits_type>
1997  using has_mapped_type = typename traits_type::mapped_type;
1998 
1999  template<typename traits_type>
2000  using has_key_type = typename traits_type::key_type;
2001 
2002  template<typename traits_type>
2003  using has_value_type = typename traits_type::value_type;
2004 
2005  template<typename object_type>
2006  using has_iterator = typename object_type::iterator;
2007 
2008  template<typename object_type>
2009  using has_const_iterator = typename object_type::const_iterator;
2010 
2011  template<typename object_type>
2012  using is_begin_signature =
2013  typename std::is_same<decltype(std::declval<object_type>().begin()), has_iterator<object_type>>;
2014 
2015  template<typename object_type>
2016  using is_begin_const_signature =
2017  typename std::is_same<decltype(std::declval<const object_type>().begin()), has_const_iterator<object_type>>;
2018 
2019  template<typename object_type>
2021  static constexpr auto value =
2024  };
2025 
2026  template<typename object_type>
2027  using is_end_signature =
2028  typename std::is_same<decltype(std::declval<object_type>().end()), has_iterator<object_type>>;
2029 
2030  template<typename object_type>
2031  using is_end_const_signature =
2032  typename std::is_same<decltype(std::declval<const object_type>().end()), has_const_iterator<object_type>>;
2033 
2034  template<typename object_type>
2035  struct supports_end {
2036  static constexpr auto value =
2039  };
2040 
2041  template<typename object_type, typename string_type>
2042  using is_count_signature = typename std::is_integral<decltype(std::declval<const object_type>().count(
2043  std::declval<const string_type>()))>;
2044 
2045  template<typename object_type, typename string_type>
2047  template<class>
2048  struct sfinae_true : std::true_type {};
2049 
2050  template<class T, class A0>
2051  static auto test_operator_plus(int)
2052  -> sfinae_true<decltype(std::declval<T>().operator[](std::declval<A0>()))>;
2053  template<class, class A0>
2054  static auto test_operator_plus(long) -> std::false_type;
2055 
2056  static constexpr auto value = decltype(test_operator_plus<object_type, string_type>(0)){};
2057  };
2058 
2059  template<typename object_type, typename value_type, typename string_type>
2062  static_assert(has_subscription_operator,
2063  "object_type must implementate the subscription operator '[]' for this library");
2064 
2065  static constexpr auto value = has_subscription_operator;
2066  };
2067 
2068  template<typename object_type, typename value_type, typename string_type>
2069  using is_at_const_signature =
2070  typename std::is_same<decltype(std::declval<const object_type>().at(std::declval<const string_type>())),
2071  const value_type&>;
2072 
2073  template<typename value_type, typename string_type, typename object_type>
2075  static constexpr auto value =
2077  std::is_same<typename object_type::mapped_type, value_type>::value &&
2079  (std::is_same<typename object_type::key_type, string_type>::value ||
2080  std::is_constructible<typename object_type::key_type, string_type>::value) &&
2085  };
2086 
2087  template<typename value_type, typename array_type>
2089  static constexpr auto value = std::is_same<typename array_type::value_type, value_type>::value;
2090  };
2091 
2092  template<typename string_type, typename integer_type>
2094  typename std::is_same<decltype(std::declval<string_type>().substr(std::declval<integer_type>(),
2095  std::declval<integer_type>())),
2097 
2098  template<typename string_type, typename integer_type>
2100  typename std::is_same<decltype(std::declval<string_type>().substr(std::declval<integer_type>())),
2102 
2103  template<typename string_type>
2104  struct has_operate_plus_method { // https://stackoverflow.com/a/9154394/8480874
2105  template<class>
2106  struct sfinae_true : std::true_type {};
2107 
2108  template<class T, class A0>
2109  static auto test_operator_plus(int)
2110  -> sfinae_true<decltype(std::declval<T>().operator+(std::declval<A0>()))>;
2111  template<class, class A0>
2112  static auto test_operator_plus(long) -> std::false_type;
2113 
2114  static constexpr auto value = decltype(test_operator_plus<string_type, string_type>(0)){};
2115  };
2116 
2117  template<typename string_type>
2119  typename std::is_same<decltype(std::operator+(std::declval<string_type>(), std::declval<string_type>())),
2121 
2122  template<typename string_type, typename integer_type>
2126  static_assert(substr, "string_type must have a substr method taking only a start index and an overload "
2127  "taking a start and end index, both must return a string_type");
2128 
2129  static constexpr auto operator_plus =
2131  static_assert(operator_plus,
2132  "string_type must have a '+' operator implemented which returns the concatenated string");
2133 
2134  static constexpr auto value = substr && operator_plus;
2135  };
2136 
2137  template<typename value_type, typename string_type, typename integer_type, typename object_type,
2138  typename array_type>
2140  // Internal assertions for better feedback
2142  "value_type must meet basic requirements, default constructor, copyable, moveable");
2144  "object_type must be a string_type to value_type container");
2146  "array_type must be a container of value_type");
2147 
2152  };
2153  } // namespace details
2154 
2162  template<typename json_traits>
2163  class basic_claim {
2170  static_assert(std::is_same<typename json_traits::string_type, std::string>::value ||
2171  std::is_convertible<typename json_traits::string_type, std::string>::value ||
2172  std::is_constructible<typename json_traits::string_type, std::string>::value,
2173  "string_type must be a std::string, convertible to a std::string, or construct a std::string.");
2174 
2175  static_assert(
2176  details::is_valid_json_types<typename json_traits::value_type, typename json_traits::string_type,
2177  typename json_traits::integer_type, typename json_traits::object_type,
2178  typename json_traits::array_type>::value,
2179  "must staisfy json container requirements");
2180  static_assert(details::is_valid_traits<json_traits>::value, "traits must satisfy requirements");
2181 
2182  typename json_traits::value_type val;
2183 
2184  public:
2185  using set_t = std::set<typename json_traits::string_type>;
2186 
2187  basic_claim() = default;
2188  basic_claim(const basic_claim&) = default;
2189  basic_claim(basic_claim&&) = default;
2190  basic_claim& operator=(const basic_claim&) = default;
2191  basic_claim& operator=(basic_claim&&) = default;
2192  ~basic_claim() = default;
2193 
2196  : val(typename json_traits::integer_type(std::chrono::system_clock::to_time_t(d))) {}
2198  JWT_CLAIM_EXPLICIT basic_claim(typename json_traits::value_type v) : val(std::move(v)) {}
2199  JWT_CLAIM_EXPLICIT basic_claim(const set_t& s) : val(typename json_traits::array_type(s.begin(), s.end())) {}
2200  template<typename Iterator>
2201  basic_claim(Iterator begin, Iterator end) : val(typename json_traits::array_type(begin, end)) {}
2202 
2207  typename json_traits::value_type to_json() const { return val; }
2208 
2213  std::istream& operator>>(std::istream& is) { return is >> val; }
2214 
2219  std::ostream& operator<<(std::ostream& os) { return os << val; }
2220 
2226  json::type get_type() const { return json_traits::get_type(val); }
2227 
2233  typename json_traits::string_type as_string() const { return json_traits::as_string(val); }
2234 
2243  date as_date() const {
2244  using std::chrono::system_clock;
2245  if (get_type() == json::type::number) return system_clock::from_time_t(std::round(as_number()));
2246  return system_clock::from_time_t(as_int());
2247  }
2248 
2254  typename json_traits::array_type as_array() const { return json_traits::as_array(val); }
2255 
2261  set_t as_set() const {
2262  set_t res;
2263  for (const auto& e : json_traits::as_array(val)) {
2264  res.insert(json_traits::as_string(e));
2265  }
2266  return res;
2267  }
2268 
2274  typename json_traits::integer_type as_int() const { return json_traits::as_int(val); }
2275 
2281  typename json_traits::boolean_type as_bool() const { return json_traits::as_bool(val); }
2282 
2288  typename json_traits::number_type as_number() const { return json_traits::as_number(val); }
2289  };
2290 
2291  namespace error {
2295  struct invalid_json_exception : public std::runtime_error {
2296  invalid_json_exception() : runtime_error("invalid json") {}
2297  };
2301  struct claim_not_present_exception : public std::out_of_range {
2302  claim_not_present_exception() : out_of_range("claim not found") {}
2303  };
2304  } // namespace error
2305 
2306  namespace details {
2307  template<typename json_traits>
2308  struct map_of_claims {
2311  using iterator = typename json_traits::object_type::iterator;
2312  using const_iterator = typename json_traits::object_type::const_iterator;
2313 
2314  map_of_claims() = default;
2315  map_of_claims(const map_of_claims&) = default;
2316  map_of_claims(map_of_claims&&) = default;
2317  map_of_claims& operator=(const map_of_claims&) = default;
2318  map_of_claims& operator=(map_of_claims&&) = default;
2319 
2320  map_of_claims(typename json_traits::object_type json) : claims(std::move(json)) {}
2321 
2322  iterator begin() { return claims.begin(); }
2323  iterator end() { return claims.end(); }
2324  const_iterator cbegin() const { return claims.begin(); }
2325  const_iterator cend() const { return claims.end(); }
2326  const_iterator begin() const { return claims.begin(); }
2327  const_iterator end() const { return claims.end(); }
2328 
2337  static typename json_traits::object_type parse_claims(const typename json_traits::string_type& str) {
2338  typename json_traits::value_type val;
2339  if (!json_traits::parse(val, str)) throw error::invalid_json_exception();
2340 
2341  return json_traits::as_object(val);
2342  };
2343 
2348  bool has_claim(const typename json_traits::string_type& name) const noexcept {
2349  return claims.count(name) != 0;
2350  }
2351 
2359  basic_claim_t get_claim(const typename json_traits::string_type& name) const {
2360  if (!has_claim(name)) throw error::claim_not_present_exception();
2361  return basic_claim_t{claims.at(name)};
2362  }
2363  };
2364  } // namespace details
2365 
2370  template<typename json_traits>
2371  class payload {
2372  protected:
2374 
2375  public:
2377 
2382  bool has_issuer() const noexcept { return has_payload_claim("iss"); }
2387  bool has_subject() const noexcept { return has_payload_claim("sub"); }
2392  bool has_audience() const noexcept { return has_payload_claim("aud"); }
2397  bool has_expires_at() const noexcept { return has_payload_claim("exp"); }
2402  bool has_not_before() const noexcept { return has_payload_claim("nbf"); }
2407  bool has_issued_at() const noexcept { return has_payload_claim("iat"); }
2412  bool has_id() const noexcept { return has_payload_claim("jti"); }
2419  typename json_traits::string_type get_issuer() const { return get_payload_claim("iss").as_string(); }
2426  typename json_traits::string_type get_subject() const { return get_payload_claim("sub").as_string(); }
2434  auto aud = get_payload_claim("aud");
2435  if (aud.get_type() == json::type::string) return {aud.as_string()};
2436 
2437  return aud.as_set();
2438  }
2445  date get_expires_at() const { return get_payload_claim("exp").as_date(); }
2452  date get_not_before() const { return get_payload_claim("nbf").as_date(); }
2459  date get_issued_at() const { return get_payload_claim("iat").as_date(); }
2466  typename json_traits::string_type get_id() const { return get_payload_claim("jti").as_string(); }
2471  bool has_payload_claim(const typename json_traits::string_type& name) const noexcept {
2472  return payload_claims.has_claim(name);
2473  }
2480  return payload_claims.get_claim(name);
2481  }
2482  };
2483 
2488  template<typename json_traits>
2489  class header {
2490  protected:
2492 
2493  public:
2499  bool has_algorithm() const noexcept { return has_header_claim("alg"); }
2504  bool has_type() const noexcept { return has_header_claim("typ"); }
2509  bool has_content_type() const noexcept { return has_header_claim("cty"); }
2514  bool has_key_id() const noexcept { return has_header_claim("kid"); }
2528  typename json_traits::string_type get_type() const { return get_header_claim("typ").as_string(); }
2542  typename json_traits::string_type get_key_id() const { return get_header_claim("kid").as_string(); }
2547  bool has_header_claim(const typename json_traits::string_type& name) const noexcept {
2548  return header_claims.has_claim(name);
2549  }
2556  return header_claims.get_claim(name);
2557  }
2558  };
2559 
2563  template<typename json_traits>
2564  class decoded_jwt : public header<json_traits>, public payload<json_traits> {
2565  protected:
2580 
2581  public:
2583 #ifndef JWT_DISABLE_BASE64
2584 
2594  : decoded_jwt(token, [](const typename json_traits::string_type& str) {
2595  return base::decode<alphabet::base64url>(base::pad<alphabet::base64url>(str));
2596  }) {}
2597 #endif
2598 
2609  template<typename Decode>
2611  auto hdr_end = token.find('.');
2612  if (hdr_end == json_traits::string_type::npos) throw std::invalid_argument("invalid token supplied");
2613  auto payload_end = token.find('.', hdr_end + 1);
2614  if (payload_end == json_traits::string_type::npos) throw std::invalid_argument("invalid token supplied");
2615  header_base64 = token.substr(0, hdr_end);
2616  payload_base64 = token.substr(hdr_end + 1, payload_end - hdr_end - 1);
2617  signature_base64 = token.substr(payload_end + 1);
2618 
2622 
2625  }
2626 
2631  const typename json_traits::string_type& get_token() const noexcept { return token; }
2636  const typename json_traits::string_type& get_header() const noexcept { return header; }
2641  const typename json_traits::string_type& get_payload() const noexcept { return payload; }
2646  const typename json_traits::string_type& get_signature() const noexcept { return signature; }
2651  const typename json_traits::string_type& get_header_base64() const noexcept { return header_base64; }
2656  const typename json_traits::string_type& get_payload_base64() const noexcept { return payload_base64; }
2661  const typename json_traits::string_type& get_signature_base64() const noexcept { return signature_base64; }
2666  typename json_traits::object_type get_payload_json() const { return this->payload_claims.claims; }
2671  typename json_traits::object_type get_header_json() const { return this->header_claims.claims; }
2680  return this->payload_claims.get_claim(name);
2681  }
2690  return this->header_claims.get_claim(name);
2691  }
2692  };
2693 
2698  template<typename json_traits>
2699  class builder {
2700  typename json_traits::object_type header_claims;
2701  typename json_traits::object_type payload_claims;
2702 
2703  public:
2704  builder() = default;
2711  builder& set_header_claim(const typename json_traits::string_type& id, typename json_traits::value_type c) {
2712  header_claims[id] = std::move(c);
2713  return *this;
2714  }
2715 
2723  header_claims[id] = c.to_json();
2724  return *this;
2725  }
2732  builder& set_payload_claim(const typename json_traits::string_type& id, typename json_traits::value_type c) {
2733  payload_claims[id] = std::move(c);
2734  return *this;
2735  }
2743  payload_claims[id] = c.to_json();
2744  return *this;
2745  }
2754  return set_header_claim("alg", typename json_traits::value_type(str));
2755  }
2762  return set_header_claim("typ", typename json_traits::value_type(str));
2763  }
2770  return set_header_claim("cty", typename json_traits::value_type(str));
2771  }
2779  return set_header_claim("kid", typename json_traits::value_type(str));
2780  }
2787  return set_payload_claim("iss", typename json_traits::value_type(str));
2788  }
2795  return set_payload_claim("sub", typename json_traits::value_type(str));
2796  }
2803  return set_payload_claim("aud", typename json_traits::value_type(a));
2804  }
2811  return set_payload_claim("aud", typename json_traits::value_type(aud));
2812  }
2836  builder& set_id(const typename json_traits::string_type& str) {
2837  return set_payload_claim("jti", typename json_traits::value_type(str));
2838  }
2839 
2851  template<typename Algo, typename Encode>
2852  typename json_traits::string_type sign(const Algo& algo, Encode encode) const {
2853  std::error_code ec;
2854  auto res = sign(algo, encode, ec);
2856  return res;
2857  }
2858 #ifndef JWT_DISABLE_BASE64
2859 
2867  template<typename Algo>
2868  typename json_traits::string_type sign(const Algo& algo) const {
2869  std::error_code ec;
2870  auto res = sign(algo, ec);
2872  return res;
2873  }
2874 #endif
2875 
2888  template<typename Algo, typename Encode>
2889  typename json_traits::string_type sign(const Algo& algo, Encode encode, std::error_code& ec) const {
2890  // make a copy such that a builder can be re-used
2891  typename json_traits::object_type obj_header = header_claims;
2892  if (header_claims.count("alg") == 0) obj_header["alg"] = typename json_traits::value_type(algo.name());
2893 
2894  const auto header = encode(json_traits::serialize(typename json_traits::value_type(obj_header)));
2895  const auto payload = encode(json_traits::serialize(typename json_traits::value_type(payload_claims)));
2896  const auto token = header + "." + payload;
2897 
2898  auto signature = algo.sign(token, ec);
2899  if (ec) return {};
2900 
2901  return token + "." + encode(signature);
2902  }
2903 #ifndef JWT_DISABLE_BASE64
2904 
2913  template<typename Algo>
2914  typename json_traits::string_type sign(const Algo& algo, std::error_code& ec) const {
2915  return sign(
2916  algo,
2917  [](const typename json_traits::string_type& data) {
2918  return base::trim<alphabet::base64url>(base::encode<alphabet::base64url>(data));
2919  },
2920  ec);
2921  }
2922 #endif
2923  };
2924 
2925  namespace verify_ops {
2929  template<typename json_traits>
2932  : current_time(ctime), jwt(j), default_leeway(l) {}
2933  // Current time, retrieved from the verifiers clock and cached for performance and consistency
2935  // The jwt passed to the verifier
2937  // The configured default leeway for this verification
2938  size_t default_leeway{0};
2939 
2940  // The claim key to apply this comparision on
2942 
2943  // Helper method to get a claim from the jwt in this context
2944  basic_claim<json_traits> get_claim(bool in_header, std::error_code& ec) const {
2945  if (in_header) {
2946  if (!jwt.has_header_claim(claim_key)) {
2948  return {};
2949  }
2950  return jwt.get_header_claim(claim_key);
2951  } else {
2952  if (!jwt.has_payload_claim(claim_key)) {
2954  return {};
2955  }
2956  return jwt.get_payload_claim(claim_key);
2957  }
2958  }
2959  basic_claim<json_traits> get_claim(bool in_header, json::type t, std::error_code& ec) const {
2960  auto c = get_claim(in_header, ec);
2961  if (ec) return {};
2962  if (c.get_type() != t) {
2964  return {};
2965  }
2966  return c;
2967  }
2968  basic_claim<json_traits> get_claim(std::error_code& ec) const { return get_claim(false, ec); }
2969  basic_claim<json_traits> get_claim(json::type t, std::error_code& ec) const {
2970  return get_claim(false, t, ec);
2971  }
2972  };
2973 
2977  template<typename json_traits, bool in_header = false>
2978  struct equals_claim {
2980  void operator()(const verify_context<json_traits>& ctx, std::error_code& ec) const {
2981  auto jc = ctx.get_claim(in_header, expected.get_type(), ec);
2982  if (ec) return;
2983  const bool matches = [&]() {
2984  switch (expected.get_type()) {
2985  case json::type::boolean: return expected.as_bool() == jc.as_bool();
2986  case json::type::integer: return expected.as_int() == jc.as_int();
2987  case json::type::number: return expected.as_number() == jc.as_number();
2988  case json::type::string: return expected.as_string() == jc.as_string();
2989  case json::type::array:
2990  case json::type::object:
2991  return json_traits::serialize(expected.to_json()) == json_traits::serialize(jc.to_json());
2992  default: throw std::logic_error("internal error, should be unreachable");
2993  }
2994  }();
2995  if (!matches) {
2997  return;
2998  }
2999  }
3000  };
3001 
3006  template<typename json_traits, bool in_header = false>
3008  const size_t leeway;
3009  void operator()(const verify_context<json_traits>& ctx, std::error_code& ec) const {
3010  auto jc = ctx.get_claim(in_header, json::type::integer, ec);
3011  if (ec) return;
3012  auto c = jc.as_date();
3013  if (ctx.current_time > c + std::chrono::seconds(leeway)) {
3015  }
3016  }
3017  };
3018 
3023  template<typename json_traits, bool in_header = false>
3025  const size_t leeway;
3026  void operator()(const verify_context<json_traits>& ctx, std::error_code& ec) const {
3027  auto jc = ctx.get_claim(in_header, json::type::integer, ec);
3028  if (ec) return;
3029  auto c = jc.as_date();
3030  if (ctx.current_time < c - std::chrono::seconds(leeway)) {
3032  }
3033  }
3034  };
3035 
3041  template<typename json_traits, bool in_header = false>
3044  void operator()(const verify_context<json_traits>& ctx, std::error_code& ec) const {
3045  auto c = ctx.get_claim(in_header, ec);
3046  if (ec) return;
3047  if (c.get_type() == json::type::string) {
3048  if (expected.size() != 1 || *expected.begin() != c.as_string()) {
3050  return;
3051  }
3052  } else if (c.get_type() == json::type::array) {
3053  auto jc = c.as_set();
3054  for (auto& e : expected) {
3055  if (jc.find(e) == jc.end()) {
3057  return;
3058  }
3059  }
3060  } else {
3062  return;
3063  }
3064  }
3065  };
3066 
3070  template<typename json_traits, bool in_header = false>
3073  std::locale locale;
3074  insensitive_string_claim(const typename json_traits::string_type& e, std::locale loc)
3075  : expected(to_lower_unicode(e, loc)), locale(loc) {}
3076 
3077  void operator()(const verify_context<json_traits>& ctx, std::error_code& ec) const {
3078  const auto c = ctx.get_claim(in_header, json::type::string, ec);
3079  if (ec) return;
3080  if (to_lower_unicode(c.as_string(), locale) != expected) {
3082  }
3083  }
3084 
3085  static std::string to_lower_unicode(const std::string& str, const std::locale& loc) {
3086 #if __cplusplus > 201103L
3087  std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> conv;
3088  auto wide = conv.from_bytes(str);
3089  auto& f = std::use_facet<std::ctype<wchar_t>>(loc);
3090  f.tolower(&wide[0], &wide[0] + wide.size());
3091  return conv.to_bytes(wide);
3092 #else
3093  std::string result;
3094  std::transform(str.begin(), str.end(), std::back_inserter(result),
3095  [&loc](unsigned char c) { return std::tolower(c, loc); });
3096  return result;
3097 #endif
3098  }
3099  };
3100  } // namespace verify_ops
3101 
3106  template<typename Clock, typename json_traits>
3107  class verifier {
3108  public:
3119  using verify_check_fn_t =
3120  std::function<void(const verify_ops::verify_context<json_traits>&, std::error_code& ec)>;
3121 
3122  private:
3123  struct algo_base {
3124  virtual ~algo_base() = default;
3125  virtual void verify(const std::string& data, const std::string& sig, std::error_code& ec) = 0;
3126  };
3127  template<typename T>
3128  struct algo : public algo_base {
3129  T alg;
3130  explicit algo(T a) : alg(a) {}
3131  void verify(const std::string& data, const std::string& sig, std::error_code& ec) override {
3132  alg.verify(data, sig, ec);
3133  }
3134  };
3136  std::unordered_map<typename json_traits::string_type, verify_check_fn_t> claims;
3138  size_t default_leeway = 0;
3140  Clock clock;
3142  std::unordered_map<std::string, std::shared_ptr<algo_base>> algs;
3143 
3144  public:
3149  explicit verifier(Clock c) : clock(c) {
3150  claims["exp"] = [](const verify_ops::verify_context<json_traits>& ctx, std::error_code& ec) {
3151  if (!ctx.jwt.has_expires_at()) return;
3152  auto exp = ctx.jwt.get_expires_at();
3153  if (ctx.current_time > exp + std::chrono::seconds(ctx.default_leeway)) {
3155  }
3156  };
3157  claims["iat"] = [](const verify_ops::verify_context<json_traits>& ctx, std::error_code& ec) {
3158  if (!ctx.jwt.has_issued_at()) return;
3159  auto iat = ctx.jwt.get_issued_at();
3160  if (ctx.current_time < iat - std::chrono::seconds(ctx.default_leeway)) {
3162  }
3163  };
3164  claims["nbf"] = [](const verify_ops::verify_context<json_traits>& ctx, std::error_code& ec) {
3165  if (!ctx.jwt.has_not_before()) return;
3166  auto nbf = ctx.jwt.get_not_before();
3167  if (ctx.current_time < nbf - std::chrono::seconds(ctx.default_leeway)) {
3169  }
3170  };
3171  }
3172 
3179  default_leeway = leeway;
3180  return *this;
3181  }
3190  return *this;
3191  }
3200  return *this;
3201  }
3210  return *this;
3211  }
3212 
3224  verifier& with_type(const typename json_traits::string_type& type, std::locale locale = std::locale{}) {
3225  return with_claim("typ", verify_ops::insensitive_string_claim<json_traits, true>{type, std::move(locale)});
3226  }
3227 
3235  return with_claim("iss", basic_claim_t(iss));
3236  }
3237 
3245  return with_claim("sub", basic_claim_t(sub));
3246  }
3254  claims["aud"] = verify_ops::is_subset_claim<json_traits>{aud};
3255  return *this;
3256  }
3264  typename basic_claim_t::set_t s;
3265  s.insert(aud);
3266  return with_audience(s);
3267  }
3274  verifier& with_id(const typename json_traits::string_type& id) { return with_claim("jti", basic_claim_t(id)); }
3275 
3283  claims[name] = fn;
3284  return *this;
3285  }
3286 
3295  }
3296 
3302  template<typename Algorithm>
3303  verifier& allow_algorithm(Algorithm alg) {
3304  algs[alg.name()] = std::make_shared<algo<Algorithm>>(alg);
3305  return *this;
3306  }
3307 
3313  void verify(const decoded_jwt<json_traits>& jwt) const {
3314  std::error_code ec;
3315  verify(jwt, ec);
3317  }
3323  void verify(const decoded_jwt<json_traits>& jwt, std::error_code& ec) const {
3324  ec.clear();
3325  const typename json_traits::string_type data = jwt.get_header_base64() + "." + jwt.get_payload_base64();
3326  const typename json_traits::string_type sig = jwt.get_signature();
3327  const std::string algo = jwt.get_algorithm();
3328  if (algs.count(algo) == 0) {
3330  return;
3331  }
3332  algs.at(algo)->verify(data, sig, ec);
3333  if (ec) return;
3334 
3335  verify_ops::verify_context<json_traits> ctx{clock.now(), jwt, default_leeway};
3336  for (auto& c : claims) {
3337  ctx.claim_key = c.first;
3338  c.second(ctx, ec);
3339  if (ec) return;
3340  }
3341  }
3342  };
3343 
3352  template<typename json_traits>
3353  class jwk {
3355  const details::map_of_claims<json_traits> jwk_claims;
3356 
3357  public:
3359  : jwk_claims(details::map_of_claims<json_traits>::parse_claims(str)) {}
3360 
3361  JWT_CLAIM_EXPLICIT jwk(const typename json_traits::value_type& json)
3362  : jwk_claims(json_traits::as_object(json)) {}
3363 
3372  typename json_traits::string_type get_key_type() const { return get_jwk_claim("kty").as_string(); }
3373 
3380  typename json_traits::string_type get_use() const { return get_jwk_claim("use").as_string(); }
3381 
3388  typename basic_claim_t::set_t get_key_operations() const { return get_jwk_claim("key_ops").as_set(); }
3389 
3396  typename json_traits::string_type get_algorithm() const { return get_jwk_claim("alg").as_string(); }
3397 
3404  typename json_traits::string_type get_key_id() const { return get_jwk_claim("kid").as_string(); }
3405 
3416  typename json_traits::string_type get_curve() const { return get_jwk_claim("crv").as_string(); }
3417 
3424  typename json_traits::array_type get_x5c() const { return get_jwk_claim("x5c").as_array(); };
3425 
3432  typename json_traits::string_type get_x5u() const { return get_jwk_claim("x5u").as_string(); };
3433 
3440  typename json_traits::string_type get_x5t() const { return get_jwk_claim("x5t").as_string(); };
3441 
3448  typename json_traits::string_type get_x5t_sha256() const { return get_jwk_claim("x5t#S256").as_string(); };
3449 
3457  auto x5c_array = get_jwk_claim("x5c").as_array();
3458  if (x5c_array.size() == 0) throw error::claim_not_present_exception();
3459 
3460  return json_traits::as_string(x5c_array.front());
3461  };
3462 
3467  bool has_key_type() const noexcept { return has_jwk_claim("kty"); }
3468 
3473  bool has_use() const noexcept { return has_jwk_claim("use"); }
3474 
3479  bool has_key_operations() const noexcept { return has_jwk_claim("key_ops"); }
3480 
3485  bool has_algorithm() const noexcept { return has_jwk_claim("alg"); }
3486 
3491  bool has_curve() const noexcept { return has_jwk_claim("crv"); }
3492 
3497  bool has_key_id() const noexcept { return has_jwk_claim("kid"); }
3498 
3503  bool has_x5u() const noexcept { return has_jwk_claim("x5u"); }
3504 
3509  bool has_x5c() const noexcept { return has_jwk_claim("x5c"); }
3510 
3515  bool has_x5t() const noexcept { return has_jwk_claim("x5t"); }
3516 
3521  bool has_x5t_sha256() const noexcept { return has_jwk_claim("x5t#S256"); }
3522 
3527  bool has_jwk_claim(const typename json_traits::string_type& name) const noexcept {
3528  return jwk_claims.has_claim(name);
3529  }
3530 
3537  return jwk_claims.get_claim(name);
3538  }
3539 
3540  bool empty() const noexcept { return jwk_claims.empty(); }
3541 
3546  typename json_traits::object_type get_claims() const { return this->jwk_claims.claims; }
3547  };
3548 
3559  template<typename json_traits>
3560  class jwks {
3561  public:
3563  using jwt_vector_t = std::vector<jwk_t>;
3564  using iterator = typename jwt_vector_t::iterator;
3565  using const_iterator = typename jwt_vector_t::const_iterator;
3566 
3568  typename json_traits::value_type parsed_val;
3569  if (!json_traits::parse(parsed_val, str)) throw error::invalid_json_exception();
3570 
3571  const details::map_of_claims<json_traits> jwks_json = json_traits::as_object(parsed_val);
3572  if (!jwks_json.has_claim("keys")) throw error::invalid_json_exception();
3573 
3574  auto jwk_list = jwks_json.get_claim("keys").as_array();
3575  std::transform(jwk_list.begin(), jwk_list.end(), std::back_inserter(jwk_claims),
3576  [](const typename json_traits::value_type& val) { return jwk_t{val}; });
3577  }
3578 
3579  iterator begin() { return jwk_claims.begin(); }
3580  iterator end() { return jwk_claims.end(); }
3581  const_iterator cbegin() const { return jwk_claims.begin(); }
3582  const_iterator cend() const { return jwk_claims.end(); }
3583  const_iterator begin() const { return jwk_claims.begin(); }
3584  const_iterator end() const { return jwk_claims.end(); }
3585 
3590  bool has_jwk(const typename json_traits::string_type& key_id) const noexcept {
3591  return find_by_kid(key_id) != end();
3592  }
3593 
3599  jwk_t get_jwk(const typename json_traits::string_type& key_id) const {
3600  const auto maybe = find_by_kid(key_id);
3601  if (maybe == end()) throw error::claim_not_present_exception();
3602  return *maybe;
3603  }
3604 
3605  private:
3606  jwt_vector_t jwk_claims;
3607 
3608  const_iterator find_by_kid(const typename json_traits::string_type& key_id) const noexcept {
3609  return std::find_if(cbegin(), cend(), [key_id](const jwk_t& jwk) {
3610  if (!jwk.has_key_id()) { return false; }
3611  return jwk.get_key_id() == key_id;
3612  });
3613  }
3614  };
3615 
3621  template<typename Clock, typename json_traits>
3624  }
3625 
3629  struct default_clock {
3630  date now() const { return date::clock::now(); }
3631  };
3632 
3638  template<typename json_traits>
3640  return verifier<default_clock, json_traits>(c);
3641  }
3642 
3646  template<typename json_traits>
3648  return builder<json_traits>();
3649  }
3650 
3659  template<typename json_traits, typename Decode>
3661  return decoded_jwt<json_traits>(token, decode);
3662  }
3663 
3671  template<typename json_traits>
3673  return decoded_jwt<json_traits>(token);
3674  }
3675 
3676  template<typename json_traits>
3678  return jwk<json_traits>(token);
3679  }
3680 
3681  template<typename json_traits>
3683  return jwks<json_traits>(token);
3684  }
3685 } // namespace jwt
3686 
3687 template<typename json_traits>
3688 std::istream& operator>>(std::istream& is, jwt::basic_claim<json_traits>& c) {
3689  return c.operator>>(is);
3690 }
3691 
3692 template<typename json_traits>
3693 std::ostream& operator<<(std::ostream& os, const jwt::basic_claim<json_traits>& c) {
3694  return os << c.to_json();
3695 }
3696 
3697 #ifndef JWT_DISABLE_PICOJSON
3699 #endif
3700 
3701 #endif
jwt::details::is_end_const_signature
typename std::is_same< decltype(std::declval< const object_type >().end()), has_const_iterator< object_type > > is_end_const_signature
Definition: jwt.h:2032
jwt::details::nonesuch::operator=
void operator=(nonesuch const &)=delete
jwt::error::make_error_code
std::error_code make_error_code(rsa_error e)
Definition: jwt.h:150
jwt::payload::has_expires_at
bool has_expires_at() const noexcept
Definition: jwt.h:2397
jwt::error::rsa_error::load_key_bio_read
@ load_key_bio_read
jwt::basic_claim::~basic_claim
~basic_claim()=default
jwt::builder::set_header_claim
builder & set_header_claim(const typename json_traits::string_type &id, basic_claim< json_traits > c)
Definition: jwt.h:2722
jwt::details::has_operate_plus_method
Definition: jwt.h:2104
jwt::details::map_of_claims::has_claim
bool has_claim(const typename json_traits::string_type &name) const noexcept
Definition: jwt.h:2348
jwt::jwks::cend
const_iterator cend() const
Definition: jwt.h:3582
jwt::payload::get_expires_at
date get_expires_at() const
Definition: jwt.h:2445
jwt::jwk::get_x5t_sha256
json_traits::string_type get_x5t_sha256() const
Definition: jwt.h:3448
jwt::details::map_of_claims::operator=
map_of_claims & operator=(const map_of_claims &)=default
jwt::algorithm::hmacsha::sign
std::string sign(const std::string &data, std::error_code &ec) const
Definition: jwt.h:920
jwt::verify_ops::date_after_claim
Definition: jwt.h:3024
jwt::verify_ops::insensitive_string_claim::expected
const json_traits::string_type expected
Definition: jwt.h:3072
jwt::decoded_jwt::get_token
const json_traits::string_type & get_token() const noexcept
Definition: jwt.h:2631
jwt::algorithm::rs256
Definition: jwt.h:1582
jwt::details::is_end_signature
typename std::is_same< decltype(std::declval< object_type >().end()), has_iterator< object_type > > is_end_signature
Definition: jwt.h:2028
jwt::error::signature_generation_error::signature_decoding_failed
@ signature_decoding_failed
jwt::details::is_substr_start_index_signature
typename std::is_same< decltype(std::declval< string_type >().substr(std::declval< integer_type >())), string_type > is_substr_start_index_signature
Definition: jwt.h:2101
jwt::algorithm::es384
Definition: jwt.h:1644
jwt::error::signature_generation_error::set_rsa_pss_saltlen_failed
@ set_rsa_pss_saltlen_failed
jwt::jwk::jwk
JWT_CLAIM_EXPLICIT jwk(const typename json_traits::string_type &str)
Definition: jwt.h:3358
jwt::algorithm::rsa::rsa
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:981
jwt::verify
verifier< default_clock, json_traits > verify(default_clock c={})
Definition: jwt.h:3639
jwt::algorithm::eddsa::name
std::string name() const
Definition: jwt.h:1412
jwt::details::map_of_claims::claims
json_traits::object_type claims
Definition: jwt.h:2309
jwt::json::type::object
@ object
jwt::verifier::not_before_leeway
verifier & not_before_leeway(size_t leeway)
Definition: jwt.h:3198
jwt::details::detector< Default, void_t< Op< Args... > >, Op, Args... >::value
std::true_type value
Definition: jwt.h:1837
jwt::header::has_algorithm
bool has_algorithm() const noexcept
Definition: jwt.h:2499
jwt::verifier::with_type
verifier & with_type(const typename json_traits::string_type &type, std::locale locale=std::locale{})
Definition: jwt.h:3224
jwt::basic_claim::basic_claim
JWT_CLAIM_EXPLICIT basic_claim(const set_t &s)
Definition: jwt.h:2199
jwt::algorithm::pss::pss
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:1434
jwt::error::rsa_error::ok
@ ok
jwt::builder::set_algorithm
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:2753
jwt::builder::set_issued_at
builder & set_issued_at(const date &d)
Definition: jwt.h:2830
jwt::error::rsa_error::write_cert_failed
@ write_cert_failed
jwt::error::signature_generation_error::hmac_failed
@ hmac_failed
jwt::jwk::has_curve
bool has_curve() const noexcept
Definition: jwt.h:3491
jwt::helper::extract_pubkey_from_cert
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:497
jwt::basic_claim::basic_claim
JWT_CLAIM_EXPLICIT basic_claim(typename json_traits::string_type s)
Definition: jwt.h:2194
jwt::algorithm::ps384::ps384
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:1764
jwt::algorithm::none::name
std::string name() const
Get algorithm name.
Definition: jwt.h:900
nlohmann::json
basic_json<> json
default JSON class
Definition: json.hpp:3472
jwt::payload::get_payload_claim
basic_claim_t get_payload_claim(const typename json_traits::string_type &name) const
Definition: jwt.h:2479
jwt::verify_ops::insensitive_string_claim
Definition: jwt.h:3071
jwt::verifier::with_claim
verifier & with_claim(const typename json_traits::string_type &name, verify_check_fn_t fn)
Definition: jwt.h:3282
jwt::helper::load_private_ec_key_from_string
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:802
jwt::error::ecdsa_error::load_key_bio_write
@ load_key_bio_write
jwt::helper::convert_base64_der_to_pem
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:560
jwt::details::is_as_number_signature
typename std::is_same< as_number_function< traits_type >, number_type(const value_type &)> is_as_number_signature
Definition: jwt.h:1912
jwt::details::is_valid_json_array
Definition: jwt.h:2088
jwt::basic_claim::set_t
std::set< typename json_traits::string_type > set_t
Definition: jwt.h:2185
jwt::algorithm::pss::verify
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition: jwt.h:1499
jwt::error::ecdsa_error::create_mem_bio_failed
@ create_mem_bio_failed
jwt::details::has_subcription_operator
Definition: jwt.h:2046
jwt::details::has_subcription_operator::sfinae_true
Definition: jwt.h:2048
jwt::details::map_of_claims::map_of_claims
map_of_claims()=default
jwt::algorithm::ecdsa::name
std::string name() const
Definition: jwt.h:1182
jwt::header::get_key_id
json_traits::string_type get_key_id() const
Definition: jwt.h:2542
jwt::payload::has_issued_at
bool has_issued_at() const noexcept
Definition: jwt.h:2407
jwt::jwks::end
const_iterator end() const
Definition: jwt.h:3584
jwt::payload::has_id
bool has_id() const noexcept
Definition: jwt.h:2412
jwt::verify_ops::equals_claim::operator()
void operator()(const verify_context< json_traits > &ctx, std::error_code &ec) const
Definition: jwt.h:2980
jwt::json::type::integer
@ integer
jwt::builder::set_subject
builder & set_subject(typename json_traits::string_type str)
Definition: jwt.h:2794
jwt::details::make_void::type
void type
Definition: jwt.h:1805
jwt::details::has_const_iterator
typename object_type::const_iterator has_const_iterator
Definition: jwt.h:2009
jwt::decoded_jwt::signature_base64
json_traits::string_type signature_base64
Unmodified signature part in base64.
Definition: jwt.h:2579
jwt::helper::raw2bn
std::unique_ptr< BIGNUM, decltype(&BN_free)> raw2bn(const std::string &raw)
Definition: jwt.h:858
jwt::builder::set_payload_claim
builder & set_payload_claim(const typename json_traits::string_type &id, typename json_traits::value_type c)
Definition: jwt.h:2732
jwt::json::type::string
@ string
jwt::error::token_verification_error
token_verification_error
Errors related to token verification errors.
Definition: jwt.h:314
jwt::verifier::allow_algorithm
verifier & allow_algorithm(Algorithm alg)
Definition: jwt.h:3303
jwt::error::signature_verification_error_category
std::error_category & signature_verification_error_category()
Error category for verification errors.
Definition: jwt.h:209
jwt::error::ecdsa_error::load_key_bio_read
@ load_key_bio_read
jwt::verifier
Definition: jwt.h:3107
jwt::builder::set_content_type
builder & set_content_type(typename json_traits::string_type str)
Definition: jwt.h:2769
jwt::algorithm::rs384
Definition: jwt.h:1597
jwt::jwk::has_use
bool has_use() const noexcept
Definition: jwt.h:3473
jwt::jwk::has_x5t_sha256
bool has_x5t_sha256() const noexcept
Definition: jwt.h:3521
jwt::basic_claim::operator<<
std::ostream & operator<<(std::ostream &os)
Definition: jwt.h:2219
picojson::boolean_type
@ boolean_type
Definition: picojson.h:122
jwt::payload::has_payload_claim
bool has_payload_claim(const typename json_traits::string_type &name) const noexcept
Definition: jwt.h:2471
jwt::details::as_integer_function
decltype(traits_type::as_int) as_integer_function
Definition: jwt.h:1924
jwt::algorithm::none::verify
void verify(const std::string &, const std::string &signature, std::error_code &ec) const
Check if the given signature is empty.
Definition: jwt.h:895
jwt::algorithm::hmacsha
Base class for HMAC family of algorithms.
Definition: jwt.h:905
jwt::details::as_boolean_function
decltype(traits_type::as_bool) as_boolean_function
Definition: jwt.h:1941
jwt::error::signature_generation_error::digestfinal_failed
@ digestfinal_failed
operator<<
std::ostream & operator<<(std::ostream &os, const jwt::basic_claim< json_traits > &c)
Definition: jwt.h:3693
jwt::jwk::has_x5t
bool has_x5t() const noexcept
Definition: jwt.h:3515
jwt::details::map_of_claims
Definition: jwt.h:2308
jwt::helper::load_public_key_from_string
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:652
jwt::decoded_jwt::decoded_jwt
decoded_jwt(const typename json_traits::string_type &token, Decode decode)
Parses a given token.
Definition: jwt.h:2610
jwt::error::token_verification_error::claim_value_missmatch
@ claim_value_missmatch
jwt::verifier::with_subject
verifier & with_subject(const typename json_traits::string_type &sub)
Definition: jwt.h:3244
jwt::verifier::with_id
verifier & with_id(const typename json_traits::string_type &id)
Definition: jwt.h:3274
jwt::details::is_subcription_operator_signature::has_subscription_operator
static constexpr auto has_subscription_operator
Definition: jwt.h:2061
jwt::details::supports_as_object::value
static constexpr auto value
Definition: jwt.h:1871
jwt::details::is_valid_json_string::operator_plus
static constexpr auto operator_plus
Definition: jwt.h:2129
jwt::builder::set_payload_claim
builder & set_payload_claim(const typename json_traits::string_type &id, basic_claim< json_traits > c)
Definition: jwt.h:2742
jwt::header::get_type
json_traits::string_type get_type() const
Definition: jwt.h:2528
jwt::helper::evp_pkey_handle::operator=
evp_pkey_handle & operator=(const evp_pkey_handle &other)
Definition: jwt.h:429
jwt::algorithm::ps256
Definition: jwt.h:1741
jwt::error::signature_generation_error_category
std::error_category & signature_generation_error_category()
Error category for signature generation errors.
Definition: jwt.h:266
jwt::helper::evp_pkey_handle::evp_pkey_handle
constexpr evp_pkey_handle() noexcept=default
jwt::details::is_valid_json_types
Definition: jwt.h:2139
jwt::verify_ops::is_subset_claim
Definition: jwt.h:3042
jwt::jwk::get_x5t
json_traits::string_type get_x5t() const
Definition: jwt.h:3440
jwt::error::ecdsa_error_category
std::error_category & ecdsa_error_category()
Error category for ECDSA errors.
Definition: jwt.h:167
jwt::verify_ops::insensitive_string_claim::locale
std::locale locale
Definition: jwt.h:3073
jwt::error::rsa_error::load_key_bio_write
@ load_key_bio_write
jwt::decoded_jwt::get_payload_json
json_traits::object_type get_payload_json() const
Definition: jwt.h:2666
jwt::error::ecdsa_error::invalid_key
@ invalid_key
jwt::builder::set_key_id
builder & set_key_id(typename json_traits::string_type str)
Set key id claim.
Definition: jwt.h:2778
jwt::algorithm::es512
Definition: jwt.h:1661
jwt::helper::evp_pkey_handle::operator!
bool operator!() const noexcept
Definition: jwt.h:452
jwt::helper::evp_pkey_handle
Handle class for EVP_PKEY structures.
Definition: jwt.h:396
jwt::builder::set_id
builder & set_id(const typename json_traits::string_type &str)
Definition: jwt.h:2836
jwt::error::signature_verification_error::get_key_failed
@ get_key_failed
jwt::jwks::end
iterator end()
Definition: jwt.h:3580
base.h
picojson::string_type
@ string_type
Definition: picojson.h:124
jwt::algorithm::rs512::rs512
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:1620
jwt::details::supports_get_type
Definition: jwt.h:1856
jwt::header::has_key_id
bool has_key_id() const noexcept
Definition: jwt.h:2514
jwt::decoded_jwt::payload
json_traits::string_type payload
Payload part decoded from base64.
Definition: jwt.h:2573
jwt::verify_ops::verify_context::jwt
const decoded_jwt< json_traits > & jwt
Definition: jwt.h:2936
jwt::error::rsa_error::convert_to_pem_failed
@ convert_to_pem_failed
jwt::decoded_jwt
Definition: jwt.h:2564
jwt::verifier::verifier
verifier(Clock c)
Definition: jwt.h:3149
jwt::error::rsa_exception
Definition: jwt.h:99
jwt::decoded_jwt::signature
json_traits::string_type signature
Signature part decoded from base64.
Definition: jwt.h:2577
jwt::error::ecdsa_error::invalid_key_size
@ invalid_key_size
jwt::verifier::with_issuer
verifier & with_issuer(const typename json_traits::string_type &iss)
Definition: jwt.h:3234
jwt::algorithm::pss::name
std::string name() const
Definition: jwt.h:1538
jwt::jwk
JSON Web Key.
Definition: jwt.h:3353
jwt::details::is_as_integer_signature
typename std::is_same< as_integer_function< traits_type >, integer_type(const value_type &)> is_as_integer_signature
Definition: jwt.h:1928
jwt::basic_claim::as_date
date as_date() const
Get the contained JSON value as a date.
Definition: jwt.h:2243
jwt::error::ecdsa_error::ok
@ ok
jwt::jwks::jwks
JWT_CLAIM_EXPLICIT jwks(const typename json_traits::string_type &str)
Definition: jwt.h:3567
jwt::algorithm::ecdsa::sign
std::string sign(const std::string &data, std::error_code &ec) const
Definition: jwt.h:1106
jwt::verifier::verify_check_fn_t
std::function< void(const verify_ops::verify_context< json_traits > &, std::error_code &ec)> verify_check_fn_t
Definition: jwt.h:3120
jwt::details::is_get_type_signature
typename std::is_same< get_type_function< traits_type >, json::type(const value_type &)> is_get_type_signature
Definition: jwt.h:1853
jwt::error::signature_verification_error::signature_encoding_failed
@ signature_encoding_failed
jwt::details::is_count_signature
typename std::is_integral< decltype(std::declval< const object_type >().count(std::declval< const string_type >()))> is_count_signature
Definition: jwt.h:2043
jwt::decoded_jwt::get_header
const json_traits::string_type & get_header() const noexcept
Definition: jwt.h:2636
jwt::details::is_valid_json_array::value
static constexpr auto value
Definition: jwt.h:2089
jwt::builder::sign
json_traits::string_type sign(const Algo &algo, Encode encode) const
Definition: jwt.h:2852
jwt::header::has_type
bool has_type() const noexcept
Definition: jwt.h:2504
jwt::verify_ops::insensitive_string_claim::operator()
void operator()(const verify_context< json_traits > &ctx, std::error_code &ec) const
Definition: jwt.h:3077
jwt::helper::evp_pkey_handle::evp_pkey_handle
evp_pkey_handle(const evp_pkey_handle &other)
Definition: jwt.h:418
jwt::details::detector::value
std::false_type value
Definition: jwt.h:1831
jwt::algorithm::hs256
Definition: jwt.h:1552
jwt::verify_ops::date_before_claim::operator()
void operator()(const verify_context< json_traits > &ctx, std::error_code &ec) const
Definition: jwt.h:3009
jwt::algorithm::ps384
Definition: jwt.h:1756
jwt::algorithm::hs384::hs384
hs384(std::string key)
Definition: jwt.h:1567
jwt::details::supports_end
Definition: jwt.h:2035
jwt::jwk::get_x5c
json_traits::array_type get_x5c() const
Definition: jwt.h:3424
jwt::error::rsa_error::get_key_failed
@ get_key_failed
conscience_core::bridging::commands::environment_entities::bool
const string const string EntityVideoSourcesCommandDataType CscPoint3d CscPoint3d bool
Definition: environmentEntitiesCommands.h:545
jwt::helper::load_public_ec_key_from_string
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:747
jwt::decoded_jwt::payload_base64
json_traits::string_type payload_base64
Unmodified payload part in base64.
Definition: jwt.h:2575
jwt::basic_claim::basic_claim
JWT_CLAIM_EXPLICIT basic_claim(const date &d)
Definition: jwt.h:2195
jwt::header::get_header_claim
basic_claim_t get_header_claim(const typename json_traits::string_type &name) const
Definition: jwt.h:2555
jwt::base::details::encode
std::string encode(const std::string &bin, const std::array< char, 64 > &alphabet, const std::string &fill)
Definition: base.h:132
jwt::details::map_of_claims::end
iterator end()
Definition: jwt.h:2323
jwt::verify_ops::date_before_claim::leeway
const size_t leeway
Definition: jwt.h:3008
jwt::algorithm::pss::sign
std::string sign(const std::string &data, std::error_code &ec) const
Definition: jwt.h:1451
jwt::error::signature_generation_error::signupdate_failed
@ signupdate_failed
jwt::details::supports_as_number::value
static constexpr auto value
Definition: jwt.h:1916
jwt::details::supports_as_array
Definition: jwt.h:1885
jwt::algorithm::rs512
Definition: jwt.h:1612
jwt::jwks::begin
iterator begin()
Definition: jwt.h:3579
jwt::details::map_of_claims::parse_claims
static json_traits::object_type parse_claims(const typename json_traits::string_type &str)
Parse a JSON string into a map of claims.
Definition: jwt.h:2337
jwt::details::is_valid_traits::value
static constexpr auto value
Definition: jwt.h:1976
operator>>
std::istream & operator>>(std::istream &is, jwt::basic_claim< json_traits > &c)
Definition: jwt.h:3688
jwt::details::supports_begin::value
static constexpr auto value
Definition: jwt.h:2021
jwt::basic_claim::basic_claim
JWT_CLAIM_EXPLICIT basic_claim(typename json_traits::value_type v)
Definition: jwt.h:2198
jwt::decoded_jwt::get_header_claim
basic_claim_t get_header_claim(const typename json_traits::string_type &name) const
Definition: jwt.h:2689
jwt::jwks::has_jwk
bool has_jwk(const typename json_traits::string_type &key_id) const noexcept
Definition: jwt.h:3590
jwt::error::signature_generation_error::rsa_private_encrypt_failed
@ rsa_private_encrypt_failed
jwt::helper::evp_pkey_handle::~evp_pkey_handle
~evp_pkey_handle() noexcept
Definition: jwt.h:449
jwt::jwks::const_iterator
typename jwt_vector_t::const_iterator const_iterator
Definition: jwt.h:3565
jwt::details::make_void
Definition: jwt.h:1804
JWT_CLAIM_EXPLICIT
#define JWT_CLAIM_EXPLICIT
Definition: jwt.h:73
jwt::algorithm::rsa::sign
std::string sign(const std::string &data, std::error_code &ec) const
Definition: jwt.h:997
jwt::details::as_array_function
decltype(traits_type::as_array) as_array_function
Definition: jwt.h:1878
jwt::algorithm::none
"none" algorithm.
Definition: jwt.h:880
jwt::decode
decoded_jwt< json_traits > decode(const typename json_traits::string_type &token)
Definition: jwt.h:3672
jwt::jwks::iterator
typename jwt_vector_t::iterator iterator
Definition: jwt.h:3564
jwt::payload::get_issuer
json_traits::string_type get_issuer() const
Definition: jwt.h:2419
jwt::default_clock
Definition: jwt.h:3629
jwt::error::signature_generation_exception
Definition: jwt.h:96
jwt::error::signature_verification_error::set_rsa_pss_saltlen_failed
@ set_rsa_pss_saltlen_failed
jwt::error::token_verification_error::missing_claim
@ missing_claim
jwt::builder::set_header_claim
builder & set_header_claim(const typename json_traits::string_type &id, typename json_traits::value_type c)
Definition: jwt.h:2711
jwt::error::signature_generation_error::ok
@ ok
jwt::builder::set_not_before
builder & set_not_before(const date &d)
Definition: jwt.h:2824
jwt::builder::set_expires_at
builder & set_expires_at(const date &d)
Definition: jwt.h:2818
picojson::number_type
@ number_type
Definition: picojson.h:123
jwt::details::is_valid_json_string::value
static constexpr auto value
Definition: jwt.h:2134
jwt::error::throw_if_error
void throw_if_error(std::error_code ec)
Definition: jwt.h:354
jwt::helper::bn2raw
std::string bn2raw(const BIGNUM *bn)
Definition: jwt.h:846
jwt::details::is_as_array_signature
typename std::is_same< as_array_function< traits_type >, array_type(const value_type &)> is_as_array_signature
Definition: jwt.h:1882
jwt::jwks
JWK Set.
Definition: jwt.h:3560
jwt::details::has_key_type
typename traits_type::key_type has_key_type
Definition: jwt.h:2000
jwt::algorithm::ed448::ed448
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:1732
jwt::verify_ops::date_before_claim
Definition: jwt.h:3007
jwt::helper::make_evp_md_ctx
std::unique_ptr< EVP_MD_CTX, void(*)(EVP_MD_CTX *)> make_evp_md_ctx()
Definition: jwt.h:481
jwt::details::map_of_claims::iterator
typename json_traits::object_type::iterator iterator
Definition: jwt.h:2311
jwt::error::signature_generation_error::signinit_failed
@ signinit_failed
jwt::verify_ops::verify_context
Definition: jwt.h:2930
jwt::decoded_jwt::get_payload
const json_traits::string_type & get_payload() const noexcept
Definition: jwt.h:2641
jwt::algorithm::ecdsa::ecdsa
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:1081
jwt::verify_ops::is_subset_claim::operator()
void operator()(const verify_context< json_traits > &ctx, std::error_code &ec) const
Definition: jwt.h:3044
jwt::algorithm::ecdsa::verify
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition: jwt.h:1143
jwt::header::get_content_type
json_traits::string_type get_content_type() const
Definition: jwt.h:2535
jwt::jwks::cbegin
const_iterator cbegin() const
Definition: jwt.h:3581
jwt::algorithm::hs384
Definition: jwt.h:1562
jwt::helper::evp_pkey_handle::operator=
evp_pkey_handle & operator=(evp_pkey_handle &&other) noexcept
Definition: jwt.h:436
jwt::date
std::chrono::system_clock::time_point date
Definition: jwt.h:87
jwt::verify_ops::verify_context::get_claim
basic_claim< json_traits > get_claim(bool in_header, std::error_code &ec) const
Definition: jwt.h:2944
jwt::error::rsa_error_category
std::error_category & rsa_error_category()
Error category for RSA errors.
Definition: jwt.h:126
jwt::verifier::with_audience
verifier & with_audience(const typename basic_claim_t::set_t &aud)
Definition: jwt.h:3253
jwt::details::is_detected_t
typename detector< nonesuch, void, Op, Args... >::type is_detected_t
Definition: jwt.h:1845
jwt::error::rsa_error::cert_load_failed
@ cert_load_failed
jwt::error::rsa_error::no_key_provided
@ no_key_provided
jwt::helper::evp_pkey_handle::evp_pkey_handle
constexpr evp_pkey_handle(EVP_PKEY *key) noexcept
Construct a new handle. The handle takes ownership of the key.
Definition: jwt.h:417
jwt::details::void_t
typename make_void< Ts... >::type void_t
Definition: jwt.h:1809
jwt::error::signature_verification_error
signature_verification_error
Errors related to verification of signatures.
Definition: jwt.h:195
jwt::json::type::boolean
@ boolean
jwt::error::rsa_error
rsa_error
Errors related to processing of RSA signatures.
Definition: jwt.h:111
jwt::algorithm::pss
Base class for PSS-RSA family of algorithms.
Definition: jwt.h:1424
jwt::parse_jwk
jwk< json_traits > parse_jwk(const typename json_traits::string_type &token)
Definition: jwt.h:3677
jwt::details::has_subcription_operator::test_operator_plus
static auto test_operator_plus(int) -> sfinae_true< decltype(std::declval< T >().operator[](std::declval< A0 >()))>
jwt::algorithm::rsa
Base class for RSA family of algorithms.
Definition: jwt.h:971
jwt::details::supports_begin
Definition: jwt.h:2020
jwt::details::supports_end::value
static constexpr auto value
Definition: jwt.h:2036
jwt::error::signature_generation_error::digestupdate_failed
@ digestupdate_failed
jwt::jwk::has_jwk_claim
bool has_jwk_claim(const typename json_traits::string_type &name) const noexcept
Definition: jwt.h:3527
jwt::json::type::number
@ number
jwt::decoded_jwt::header_base64
json_traits::string_type header_base64
Unmodified header part in base64.
Definition: jwt.h:2571
jwt::algorithm::rsa::verify
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition: jwt.h:1030
jwt
JSON Web Token.
Definition: base.h:20
jwt::basic_claim::basic_claim
JWT_CLAIM_EXPLICIT basic_claim(typename json_traits::array_type a)
Definition: jwt.h:2197
jwt::jwk::has_x5c
bool has_x5c() const noexcept
Definition: jwt.h:3509
jwt::verify_ops::equals_claim::expected
const basic_claim< json_traits > expected
Definition: jwt.h:2979
jwt::jwk::has_key_type
bool has_key_type() const noexcept
Definition: jwt.h:3467
jwt::basic_claim::basic_claim
basic_claim()=default
jwt::verifier::verify
void verify(const decoded_jwt< json_traits > &jwt) const
Definition: jwt.h:3313
jwt::jwk::get_algorithm
json_traits::string_type get_algorithm() const
Definition: jwt.h:3396
jwt::details::is_as_string_signature
typename std::is_same< as_string_function< traits_type >, string_type(const value_type &)> is_as_string_signature
Definition: jwt.h:1897
jwt::details::supports_as_integer
Definition: jwt.h:1931
jwt::details::is_valid_traits
Definition: jwt.h:1957
jwt::algorithm::eddsa::sign
std::string sign(const std::string &data, std::error_code &ec) const
Definition: jwt.h:1325
jwt::payload::has_audience
bool has_audience() const noexcept
Definition: jwt.h:2392
jwt::builder::set_type
builder & set_type(typename json_traits::string_type str)
Definition: jwt.h:2761
jwt::decoded_jwt::get_payload_claim
basic_claim_t get_payload_claim(const typename json_traits::string_type &name) const
Definition: jwt.h:2679
jwt::error::ecdsa_exception
Definition: jwt.h:102
jwt::header::has_header_claim
bool has_header_claim(const typename json_traits::string_type &name) const noexcept
Definition: jwt.h:2547
jwt::verify_ops::is_subset_claim::expected
const basic_claim< json_traits >::set_t expected
Definition: jwt.h:3043
jwt::basic_claim::as_set
set_t as_set() const
Definition: jwt.h:2261
jwt::details::is_valid_json_object::value
static constexpr auto value
Definition: jwt.h:2075
jwt::error::invalid_json_exception
Definition: jwt.h:2295
jwt::algorithm::ps512
Definition: jwt.h:1771
jwt::details::map_of_claims::cbegin
const_iterator cbegin() const
Definition: jwt.h:2324
nlohmann::detail::void
j template void())
Definition: json.hpp:4189
jwt::algorithm::eddsa::eddsa
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:1309
picojson::parse
std::string parse(value &out, Iter &pos, const Iter &last)
Definition: picojson.h:1098
jwt::decoded_jwt::get_signature
const json_traits::string_type & get_signature() const noexcept
Definition: jwt.h:2646
picojson.h
jwt::details::has_operate_plus_method::sfinae_true
Definition: jwt.h:2106
jwt::details::supports_as_object
Definition: jwt.h:1870
jwt::error::token_verification_error::wrong_algorithm
@ wrong_algorithm
jwt::basic_claim::operator=
basic_claim & operator=(const basic_claim &)=default
jwt::details::supports_as_number
Definition: jwt.h:1915
jwt::verify_ops::verify_context::verify_context
verify_context(date ctime, const decoded_jwt< json_traits > &j, size_t l)
Definition: jwt.h:2931
jwt::details::map_of_claims::get_claim
basic_claim_t get_claim(const typename json_traits::string_type &name) const
Definition: jwt.h:2359
jwt::details::has_operate_plus_method::test_operator_plus
static auto test_operator_plus(int) -> sfinae_true< decltype(std::declval< T >().operator+(std::declval< A0 >()))>
jwt::json::type
type
Generic JSON types used in JWTs.
Definition: jwt.h:1794
jwt::details::is_std_operate_plus_signature
typename std::is_same< decltype(std::operator+(std::declval< string_type >(), std::declval< string_type >())), string_type > is_std_operate_plus_signature
Definition: jwt.h:2120
jwt::details::map_of_claims::end
const_iterator end() const
Definition: jwt.h:2327
jwt::details::is_valid_json_types::value
static constexpr auto value
Definition: jwt.h:2148
jwt::payload::get_audience
basic_claim_t::set_t get_audience() const
Definition: jwt.h:2433
jwt::algorithm::eddsa
Base class for EdDSA family of algorithms.
Definition: jwt.h:1298
jwt::error::signature_verification_exception
Definition: jwt.h:93
jwt::error::signature_verification_error::invalid_signature
@ invalid_signature
jwt::error::signature_verification_error::verifyinit_failed
@ verifyinit_failed
jwt::error::signature_verification_error::create_context_failed
@ create_context_failed
jwt::verifier::basic_claim_t
basic_claim< json_traits > basic_claim_t
Definition: jwt.h:3109
jwt::payload::has_subject
bool has_subject() const noexcept
Definition: jwt.h:2387
jwt::payload::has_issuer
bool has_issuer() const noexcept
Definition: jwt.h:2382
jwt::verify_ops::insensitive_string_claim::to_lower_unicode
static std::string to_lower_unicode(const std::string &str, const std::locale &loc)
Definition: jwt.h:3085
jwt::error::invalid_json_exception::invalid_json_exception
invalid_json_exception()
Definition: jwt.h:2296
jwt::details::supports_as_integer::value
static constexpr auto value
Definition: jwt.h:1932
jwt::basic_claim::get_type
json::type get_type() const
Definition: jwt.h:2226
nlohmann::detail::detected_t
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:2277
jwt::decoded_jwt::token
json_traits::string_type token
Unmodifed token, as passed to constructor.
Definition: jwt.h:2567
jwt::details::supports_as_boolean
Definition: jwt.h:1948
jwt::basic_claim::as_bool
json_traits::boolean_type as_bool() const
Definition: jwt.h:2281
jwt::verify_ops::verify_context::current_time
date current_time
Definition: jwt.h:2934
jwt::helper::load_private_key_from_string
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:706
jwt::jwk::get_key_operations
basic_claim_t::set_t get_key_operations() const
Definition: jwt.h:3388
jwt::builder::builder
builder()=default
jwt::algorithm::eddsa::verify
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition: jwt.h:1373
jwt::verify_ops::verify_context::get_claim
basic_claim< json_traits > get_claim(json::type t, std::error_code &ec) const
Definition: jwt.h:2969
jwt::algorithm::es256k::es256k
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:1687
jwt::details::supports_get_type::value
static constexpr auto value
Definition: jwt.h:1857
jwt::verify_ops::verify_context::default_leeway
size_t default_leeway
Definition: jwt.h:2938
jwt::error::token_verification_error::token_expired
@ token_expired
jwt::payload::has_not_before
bool has_not_before() const noexcept
Definition: jwt.h:2402
jwt::verifier::issued_at_leeway
verifier & issued_at_leeway(size_t leeway)
Definition: jwt.h:3208
jwt::verifier::leeway
verifier & leeway(size_t leeway)
Definition: jwt.h:3178
jwt::error::signature_verification_error::verifyfinal_failed
@ verifyfinal_failed
jwt::decoded_jwt::get_header_json
json_traits::object_type get_header_json() const
Definition: jwt.h:2671
jwt::error::signature_verification_error::verifyupdate_failed
@ verifyupdate_failed
jwt::algorithm::hs512
Definition: jwt.h:1572
picojson::object_type
@ object_type
Definition: picojson.h:126
jwt::helper::evp_pkey_handle::operator=
evp_pkey_handle & operator=(EVP_PKEY *key)
Definition: jwt.h:443
jwt::details::supports_as_string
Definition: jwt.h:1900
jwt::helper::evp_pkey_handle::evp_pkey_handle
evp_pkey_handle(evp_pkey_handle &&other) noexcept
Definition: jwt.h:425
jwt::jwk::get_use
json_traits::string_type get_use() const
Definition: jwt.h:3380
jwt::algorithm::rs256::rs256
rs256(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:1590
jwt::algorithm::es512::es512
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:1671
jwt::details::map_of_claims::map_of_claims
map_of_claims(typename json_traits::object_type json)
Definition: jwt.h:2320
jwt::payload::get_not_before
date get_not_before() const
Definition: jwt.h:2452
jwt::verify_ops::verify_context::get_claim
basic_claim< json_traits > get_claim(std::error_code &ec) const
Definition: jwt.h:2968
jwt::details::is_as_object_signature
typename std::is_same< as_object_function< traits_type >, object_type(const value_type &)> is_as_object_signature
Definition: jwt.h:1867
jwt::algorithm::es256k
Definition: jwt.h:1678
jwt::header::get_algorithm
json_traits::string_type get_algorithm() const
Definition: jwt.h:2521
jwt::details::has_mapped_type
typename traits_type::mapped_type has_mapped_type
Definition: jwt.h:1997
jwt::verify_ops::verify_context::claim_key
json_traits::string_type claim_key
Definition: jwt.h:2941
jwt::algorithm::ecdsa
Base class for ECDSA family of algorithms.
Definition: jwt.h:1069
jwt::helper::make_mem_buf_bio
std::unique_ptr< BIO, decltype(&BIO_free_all)> make_mem_buf_bio()
Definition: jwt.h:467
jwt::header::header_claims
details::map_of_claims< json_traits > header_claims
Definition: jwt.h:2491
jwt::payload::get_subject
json_traits::string_type get_subject() const
Definition: jwt.h:2426
jwt::algorithm::hmacsha::name
std::string name() const
Definition: jwt.h:958
jwt::helper::evp_pkey_handle::get
EVP_PKEY * get() const noexcept
Definition: jwt.h:451
jwt::decode
decoded_jwt< json_traits > decode(const typename json_traits::string_type &token, Decode decode)
Definition: jwt.h:3660
jwt::decoded_jwt::header
json_traits::string_type header
Header part decoded from base64.
Definition: jwt.h:2569
jwt::error::signature_verification_error::ok
@ ok
jwt::error::claim_not_present_exception
Definition: jwt.h:2301
jwt::payload::payload_claims
details::map_of_claims< json_traits > payload_claims
Definition: jwt.h:2373
jwt::details::is_as_boolean_signature
typename std::is_same< as_boolean_function< traits_type >, boolean_type(const value_type &)> is_as_boolean_signature
Definition: jwt.h:1945
jwt::jwk::get_jwk_claim
basic_claim_t get_jwk_claim(const typename json_traits::string_type &name) const
Definition: jwt.h:3536
jwt::algorithm::es384::es384
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:1654
jwt::basic_claim::as_string
json_traits::string_type as_string() const
Definition: jwt.h:2233
jwt::builder
Definition: jwt.h:2699
jwt::basic_claim::to_json
json_traits::value_type to_json() const
Definition: jwt.h:2207
defaults.h
jwt::jwks::begin
const_iterator begin() const
Definition: jwt.h:3583
jwt::details::as_number_function
decltype(traits_type::as_number) as_number_function
Definition: jwt.h:1908
jwt::details::map_of_claims::begin
iterator begin()
Definition: jwt.h:2322
jwt::verify_ops::verify_context::get_claim
basic_claim< json_traits > get_claim(bool in_header, json::type t, std::error_code &ec) const
Definition: jwt.h:2959
std
Definition: json.hpp:4598
jwt::details::map_of_claims::begin
const_iterator begin() const
Definition: jwt.h:2326
jwt::details::is_subcription_operator_signature::value
static constexpr auto value
Definition: jwt.h:2065
jwt::details::has_iterator
typename object_type::iterator has_iterator
Definition: jwt.h:2006
jwt::decoded_jwt::get_header_base64
const json_traits::string_type & get_header_base64() const noexcept
Definition: jwt.h:2651
jwt::details::is_valid_json_value::value
static constexpr auto value
Definition: jwt.h:1988
jwt::algorithm::es256::es256
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:1637
jwt::error::signature_generation_error::digestinit_failed
@ digestinit_failed
jwt::details::get_type_function
decltype(traits_type::get_type) get_type_function
Definition: jwt.h:1849
jwt::payload::get_issued_at
date get_issued_at() const
Definition: jwt.h:2459
jwt::jwk::get_key_type
json_traits::string_type get_key_type() const
Definition: jwt.h:3372
jwt::decoded_jwt::get_signature_base64
const json_traits::string_type & get_signature_base64() const noexcept
Definition: jwt.h:2661
jwt::verify_ops::insensitive_string_claim::insensitive_string_claim
insensitive_string_claim(const typename json_traits::string_type &e, std::locale loc)
Definition: jwt.h:3074
jwt::verify_ops::date_after_claim::leeway
const size_t leeway
Definition: jwt.h:3025
jwt::details::nonesuch::~nonesuch
~nonesuch()=delete
jwt::jwk::has_x5u
bool has_x5u() const noexcept
Definition: jwt.h:3503
jwt::payload
Definition: jwt.h:2371
jwt::details::is_at_const_signature
typename std::is_same< decltype(std::declval< const object_type >().at(std::declval< const string_type >())), const value_type & > is_at_const_signature
Definition: jwt.h:2071
jwt::error::token_verification_error_category
std::error_category & token_verification_error_category()
Error category for token verification errors.
Definition: jwt.h:326
jwt::verifier::verify
void verify(const decoded_jwt< json_traits > &jwt, std::error_code &ec) const
Definition: jwt.h:3323
jwt::error::ecdsa_error::create_context_failed
@ create_context_failed
jwt::algorithm::rs384::rs384
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:1605
jwt::algorithm::none::sign
std::string sign(const std::string &, std::error_code &ec) const
Return an empty string.
Definition: jwt.h:884
jwt::error::rsa_error::create_mem_bio_failed
@ create_mem_bio_failed
jwt::details::is_valid_json_value
Definition: jwt.h:1987
jwt::details::nonesuch::nonesuch
nonesuch()=delete
c
double c
Definition: HybridAStar.cpp:84
jwt::create
builder< json_traits > create()
Definition: jwt.h:3647
jwt::details::supports_as_boolean::value
static constexpr auto value
Definition: jwt.h:1949
jwt::details::supports_as_array::value
static constexpr auto value
Definition: jwt.h:1886
jwt::details::has_subcription_operator::value
static constexpr auto value
Definition: jwt.h:2056
picojson::array_type
@ array_type
Definition: picojson.h:125
jwt::error::signature_generation_error::rsa_padding_failed
@ rsa_padding_failed
jwt::basic_claim::basic_claim
basic_claim(Iterator begin, Iterator end)
Definition: jwt.h:2201
jwt::details::detector< Default, void_t< Op< Args... > >, Op, Args... >::type
Op< Args... > type
Definition: jwt.h:1838
s
double s
Definition: HybridAStar.cpp:85
jwt::algorithm::ed25519
Definition: jwt.h:1700
jwt::builder::sign
json_traits::string_type sign(const Algo &algo, std::error_code &ec) const
Definition: jwt.h:2914
jwt::builder::sign
json_traits::string_type sign(const Algo &algo) const
Definition: jwt.h:2868
jwt::decoded_jwt::get_payload_base64
const json_traits::string_type & get_payload_base64() const noexcept
Definition: jwt.h:2656
jwt::error::signature_generation_error::ecdsa_do_sign_failed
@ ecdsa_do_sign_failed
jwt::details::as_string_function
decltype(traits_type::as_string) as_string_function
Definition: jwt.h:1893
jwt::builder::set_issuer
builder & set_issuer(typename json_traits::string_type str)
Definition: jwt.h:2786
jwt::algorithm::ed25519::ed25519
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:1710
jwt::details::is_begin_const_signature
typename std::is_same< decltype(std::declval< const object_type >().begin()), has_const_iterator< object_type > > is_begin_const_signature
Definition: jwt.h:2017
jwt::error::ecdsa_error::no_key_provided
@ no_key_provided
jwt::jwk::get_curve
json_traits::string_type get_curve() const
Get curve claim.
Definition: jwt.h:3416
jwt::verify_ops::date_after_claim::operator()
void operator()(const verify_context< json_traits > &ctx, std::error_code &ec) const
Definition: jwt.h:3026
f
double f
Definition: HybridAStar.cpp:190
jwt::verifier::with_audience
verifier & with_audience(const typename json_traits::string_type &aud)
Definition: jwt.h:3263
jwt::header
Definition: jwt.h:2489
jwt::details::is_substr_start_end_index_signature
typename std::is_same< decltype(std::declval< string_type >().substr(std::declval< integer_type >(), std::declval< integer_type >())), string_type > is_substr_start_end_index_signature
Definition: jwt.h:2096
jwt::builder::set_audience
builder & set_audience(typename json_traits::array_type a)
Definition: jwt.h:2802
jwt::algorithm::ps512::ps512
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:1779
jwt::details::supports_as_string::value
static constexpr auto value
Definition: jwt.h:1901
jwt::error::rsa_error::write_key_failed
@ write_key_failed
jwt::decoded_jwt::decoded_jwt
JWT_CLAIM_EXPLICIT decoded_jwt(const typename json_traits::string_type &token)
Parses a given token.
Definition: jwt.h:2593
jwt::algorithm::hs256::hs256
hs256(std::string key)
Definition: jwt.h:1557
jwt::error::token_verification_error::ok
@ ok
jwt::details::is_subcription_operator_signature
Definition: jwt.h:2060
jwt::jwk::empty
bool empty() const noexcept
Definition: jwt.h:3540
jwt::jwk::get_x5c_key_value
json_traits::string_type get_x5c_key_value() const
Definition: jwt.h:3456
jwt::jwk::has_key_id
bool has_key_id() const noexcept
Definition: jwt.h:3497
jwt::algorithm::hs512::hs512
hs512(std::string key)
Definition: jwt.h:1577
jwt::jwk::jwk
JWT_CLAIM_EXPLICIT jwk(const typename json_traits::value_type &json)
Definition: jwt.h:3361
jwt::algorithm::ed448
Definition: jwt.h:1722
jwt::basic_claim::as_number
json_traits::number_type as_number() const
Definition: jwt.h:2288
ptr
std::shared_ptr< T > ptr
Definition: CscCommon.h:29
jwt::jwk::has_algorithm
bool has_algorithm() const noexcept
Definition: jwt.h:3485
jwt::builder::sign
json_traits::string_type sign(const Algo &algo, Encode encode, std::error_code &ec) const
Definition: jwt.h:2889
jwt::details::map_of_claims::cend
const_iterator cend() const
Definition: jwt.h:2325
jwt::error::ecdsa_error
ecdsa_error
Errors related to processing of RSA signatures.
Definition: jwt.h:154
jwt::algorithm::rsa::name
std::string name() const
Definition: jwt.h:1056
jwt::verifier::expires_at_leeway
verifier & expires_at_leeway(size_t leeway)
Definition: jwt.h:3188
jwt::details::detector::type
Default type
Definition: jwt.h:1832
jwt::jwk::get_x5u
json_traits::string_type get_x5u() const
Definition: jwt.h:3432
jwt::basic_claim::operator>>
std::istream & operator>>(std::istream &is)
Definition: jwt.h:2213
jwt::algorithm::es256
Definition: jwt.h:1627
jwt::json::type::array
@ array
jwt::error::signature_generation_error::signfinal_failed
@ signfinal_failed
jwt::error::signature_generation_error
signature_generation_error
Errors related to signature generation errors.
Definition: jwt.h:246
jwt::error::token_verification_exception
Definition: jwt.h:105
jwt::jwk::has_key_operations
bool has_key_operations() const noexcept
Definition: jwt.h:3479
jwt::error::claim_not_present_exception::claim_not_present_exception
claim_not_present_exception()
Definition: jwt.h:2302
jwt::details::as_object_function
decltype(traits_type::as_object) as_object_function
Definition: jwt.h:1863
jwt::details::is_detected
typename detector< nonesuch, void, Op, Args... >::value is_detected
Definition: jwt.h:1842
jwt::details::is_valid_json_object
Definition: jwt.h:2074
jwt::error::token_verification_error::claim_type_missmatch
@ claim_type_missmatch
jwt::payload::get_id
json_traits::string_type get_id() const
Definition: jwt.h:2466
jwt::algorithm::ps256::ps256
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:1749
jwt::verify_ops::equals_claim
Definition: jwt.h:2978
jwt::jwk::get_claims
json_traits::object_type get_claims() const
Definition: jwt.h:3546
jwt::builder::set_audience
builder & set_audience(typename json_traits::string_type aud)
Definition: jwt.h:2810
jwt::jwks::jwt_vector_t
std::vector< jwk_t > jwt_vector_t
Definition: jwt.h:3563
jwt::details::has_value_type
typename traits_type::value_type has_value_type
Definition: jwt.h:2003
jwt::details::is_valid_json_string::substr
static constexpr auto substr
Definition: jwt.h:2124
jwt::error::token_verification_error::audience_missmatch
@ audience_missmatch
jwt::algorithm::hmacsha::hmacsha
hmacsha(std::string key, const EVP_MD *(*md)(), std::string name)
Definition: jwt.h:912
jwt::header::has_content_type
bool has_content_type() const noexcept
Definition: jwt.h:2509
jwt::basic_claim
a class to store a generic JSON value as claim
Definition: jwt.h:2163
jwt::error::signature_generation_error::create_context_failed
@ create_context_failed
jwt::parse_jwks
jwks< json_traits > parse_jwks(const typename json_traits::string_type &token)
Definition: jwt.h:3682
j
int j
Definition: HybridAStar.cpp:192
jwt::basic_claim::as_int
json_traits::integer_type as_int() const
Definition: jwt.h:2274
jwt::basic_claim::as_array
json_traits::array_type as_array() const
Definition: jwt.h:2254
jwt::error::signature_generation_error::get_key_failed
@ get_key_failed
jwt::jwk::get_key_id
json_traits::string_type get_key_id() const
Definition: jwt.h:3404
jwt::details::detector
Definition: jwt.h:1830
jwt::algorithm::hmacsha::verify
void verify(const std::string &data, const std::string &signature, std::error_code &ec) const
Definition: jwt.h:940
jwt::details::is_begin_signature
typename std::is_same< decltype(std::declval< object_type >().begin()), has_iterator< object_type > > is_begin_signature
Definition: jwt.h:2013
jwt::default_clock::now
date now() const
Definition: jwt.h:3630
jwt::verifier::with_claim
verifier & with_claim(const typename json_traits::string_type &name, basic_claim_t c)
Definition: jwt.h:3293
jwt::details::has_operate_plus_method::value
static constexpr auto value
Definition: jwt.h:2114
jwt::details::nonesuch
Definition: jwt.h:1819
i
int i
Definition: HybridAStar.cpp:191
jwt::details::map_of_claims::const_iterator
typename json_traits::object_type::const_iterator const_iterator
Definition: jwt.h:2312
jwt::details::is_valid_json_string
Definition: jwt.h:2123
jwt::jwks::get_jwk
jwk_t get_jwk(const typename json_traits::string_type &key_id) const
Definition: jwt.h:3599