aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-05-05 17:50:58 +0300
committershadchin <shadchin@yandex-team.ru>2022-05-05 17:50:58 +0300
commitdea1e96c926a63a534cf579e7450479f29dc1b45 (patch)
treecbdc7638febcf17dc537331356ec2621570ffe4f
parent570266d20cea70e21f7b00c6140a08902b1fb455 (diff)
downloadydb-dea1e96c926a63a534cf579e7450479f29dc1b45.tar.gz
Update contrib/libs/jwt-cpp to 0.4.0
ref:c22a6249506be3d6363f3ca316df6b0800de7e81
-rw-r--r--contrib/libs/jwt-cpp/.yandex_meta/devtools.copyrights.report4
-rw-r--r--contrib/libs/jwt-cpp/.yandex_meta/devtools.licenses.report2
-rw-r--r--contrib/libs/jwt-cpp/README.md3
-rw-r--r--contrib/libs/jwt-cpp/base.h68
-rw-r--r--contrib/libs/jwt-cpp/jwt.h290
-rw-r--r--contrib/libs/jwt-cpp/picojson/picojson.h (renamed from contrib/libs/jwt-cpp/picojson.h)12
6 files changed, 218 insertions, 161 deletions
diff --git a/contrib/libs/jwt-cpp/.yandex_meta/devtools.copyrights.report b/contrib/libs/jwt-cpp/.yandex_meta/devtools.copyrights.report
index 8a0cebfba3..5bf950733a 100644
--- a/contrib/libs/jwt-cpp/.yandex_meta/devtools.copyrights.report
+++ b/contrib/libs/jwt-cpp/.yandex_meta/devtools.copyrights.report
@@ -40,7 +40,7 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- picojson.h [2:4]
+ picojson/picojson.h [2:4]
KEEP COPYRIGHT_SERVICE_LABEL cb493d7b4451c90d47d799c48ee86dfc
BELONGS ya.make
@@ -64,4 +64,4 @@ BELONGS ya.make
Score : 100.00
Match type : COPYRIGHT
Files with this license:
- picojson.h [2:4]
+ picojson/picojson.h [2:4]
diff --git a/contrib/libs/jwt-cpp/.yandex_meta/devtools.licenses.report b/contrib/libs/jwt-cpp/.yandex_meta/devtools.licenses.report
index 9cca335064..7a2265a959 100644
--- a/contrib/libs/jwt-cpp/.yandex_meta/devtools.licenses.report
+++ b/contrib/libs/jwt-cpp/.yandex_meta/devtools.licenses.report
@@ -61,4 +61,4 @@ BELONGS ya.make
Match type : TEXT
Links : http://opensource.org/licenses/bsd-license.php, http://www.opensource.org/licenses/BSD-2-Clause, https://spdx.org/licenses/BSD-2-Clause
Files with this license:
- picojson.h [6:26]
+ picojson/picojson.h [6:26]
diff --git a/contrib/libs/jwt-cpp/README.md b/contrib/libs/jwt-cpp/README.md
index 5fc1459412..b42599a9ef 100644
--- a/contrib/libs/jwt-cpp/README.md
+++ b/contrib/libs/jwt-cpp/README.md
@@ -1,6 +1,7 @@
# jwt-cpp
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/5f7055e294744901991fd0a1620b231d)](https://app.codacy.com/app/Thalhammer/jwt-cpp?utm_source=github.com&utm_medium=referral&utm_content=Thalhammer/jwt-cpp&utm_campaign=Badge_Grade_Settings)
+[![Build Status](https://travis-ci.com/Thalhammer/jwt-cpp.svg?branch=master)](https://travis-ci.com/Thalhammer/jwt-cpp)
A header only library for creating and validating json web tokens in c++.
@@ -50,7 +51,7 @@ Creating a token (and signing) is equally easy.
auto token = jwt::create()
.set_issuer("auth0")
.set_type("JWS")
- .set_payload_claim("sample", std::string("test"))
+ .set_payload_claim("sample", jwt::claim(std::string("test")))
.sign(jwt::algorithm::hs256{"secret"});
```
diff --git a/contrib/libs/jwt-cpp/base.h b/contrib/libs/jwt-cpp/base.h
index dfca7fc08f..375e0eb08f 100644
--- a/contrib/libs/jwt-cpp/base.h
+++ b/contrib/libs/jwt-cpp/base.h
@@ -2,16 +2,26 @@
#include <string>
#include <array>
+#ifdef __has_cpp_attribute
+#if __has_cpp_attribute(fallthrough)
+#define JWT_FALLTHROUGH [[fallthrough]]
+#endif
+#endif
+
+#ifndef JWT_FALLTHROUGH
+#define JWT_FALLTHROUGH
+#endif
+
namespace jwt {
namespace alphabet {
struct base64 {
static const std::array<char, 64>& data() {
- static std::array<char, 64> data = {
- {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}};
- return data;
+ static std::array<char, 64> data = {
+ {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}};
+ return data;
};
static const std::string& fill() {
static std::string fill = "=";
@@ -20,12 +30,12 @@ namespace jwt {
};
struct base64url {
static const std::array<char, 64>& data() {
- static std::array<char, 64> data = {
- {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'}};
- return data;
+ static std::array<char, 64> data = {
+ {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'}};
+ return data;
};
static const std::string& fill() {
static std::string fill = "%3d";
@@ -44,6 +54,14 @@ namespace jwt {
static std::string decode(const std::string& base) {
return decode(base, T::data(), T::fill());
}
+ template<typename T>
+ static std::string pad(const std::string& base) {
+ return pad(base, T::fill());
+ }
+ template<typename T>
+ static std::string trim(const std::string& base) {
+ return trim(base, T::fill());
+ }
private:
static std::string encode(const std::string& bin, const std::array<char, 64>& alphabet, const std::string& fill) {
@@ -120,7 +138,7 @@ namespace jwt {
auto get_sextet = [&](size_t offset) {
for (size_t i = 0; i < alphabet.size(); i++) {
if (alphabet[i] == base[offset])
- return i;
+ return static_cast<uint32_t>(i);
}
throw std::runtime_error("Invalid input");
};
@@ -164,5 +182,29 @@ namespace jwt {
return res;
}
+
+ static std::string pad(const std::string& base, const std::string& fill) {
+ std::string padding;
+ switch (base.size() % 4) {
+ case 1:
+ padding += fill;
+ JWT_FALLTHROUGH;
+ case 2:
+ padding += fill;
+ JWT_FALLTHROUGH;
+ case 3:
+ padding += fill;
+ JWT_FALLTHROUGH;
+ default:
+ break;
+ }
+
+ return base + padding;
+ }
+
+ static std::string trim(const std::string& base, const std::string& fill) {
+ auto pos = base.find(fill);
+ return base.substr(0, pos);
+ }
};
}
diff --git a/contrib/libs/jwt-cpp/jwt.h b/contrib/libs/jwt-cpp/jwt.h
index 129554699a..6e557298dd 100644
--- a/contrib/libs/jwt-cpp/jwt.h
+++ b/contrib/libs/jwt-cpp/jwt.h
@@ -1,6 +1,6 @@
#pragma once
#define PICOJSON_USE_INT64
-#include "picojson.h"
+#include "picojson/picojson.h"
#include "base.h"
#include <set>
#include <chrono>
@@ -13,12 +13,12 @@
#include <openssl/err.h>
//If openssl version less than 1.1
-#if OPENSSL_VERSION_NUMBER < 269484032
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define OPENSSL10
#endif
#ifndef JWT_CLAIM_EXPLICIT
-#define JWT_CLAIM_EXPLICIT 0
+#define JWT_CLAIM_EXPLICIT explicit
#endif
namespace jwt {
@@ -74,11 +74,10 @@ namespace jwt {
namespace helper {
inline
std::string extract_pubkey_from_cert(const std::string& certstr, const std::string& pw = "") {
- // TODO: Cannot find the exact version this change happended
-#if OPENSSL_VERSION_NUMBER <= 0x1000114fL
+#if OPENSSL_VERSION_NUMBER <= 0x10100003L
std::unique_ptr<BIO, decltype(&BIO_free_all)> certbio(BIO_new_mem_buf(const_cast<char*>(certstr.data()), certstr.size()), BIO_free_all);
#else
- std::unique_ptr<BIO, decltype(&BIO_free_all)> certbio(BIO_new_mem_buf(certstr.data(), certstr.size()), BIO_free_all);
+ std::unique_ptr<BIO, decltype(&BIO_free_all)> certbio(BIO_new_mem_buf(certstr.data(), static_cast<int>(certstr.size())), BIO_free_all);
#endif
std::unique_ptr<BIO, decltype(&BIO_free_all)> keybio(BIO_new(BIO_s_mem()), BIO_free_all);
@@ -99,29 +98,59 @@ namespace jwt {
std::unique_ptr<BIO, decltype(&BIO_free_all)> pubkey_bio(BIO_new(BIO_s_mem()), BIO_free_all);
if(key.substr(0, 27) == "-----BEGIN CERTIFICATE-----") {
auto epkey = helper::extract_pubkey_from_cert(key, password);
- if ((size_t)BIO_write(pubkey_bio.get(), epkey.data(), epkey.size()) != epkey.size())
+ const int len = static_cast<int>(epkey.size());
+ if (BIO_write(pubkey_bio.get(), epkey.data(), len) != len)
throw rsa_exception("failed to load public key: bio_write failed");
} else {
- if ((size_t)BIO_write(pubkey_bio.get(), key.data(), key.size()) != key.size())
+ const int len = static_cast<int>(key.size());
+ if (BIO_write(pubkey_bio.get(), key.data(), len) != len)
throw rsa_exception("failed to load public key: bio_write failed");
}
std::shared_ptr<EVP_PKEY> pkey(PEM_read_bio_PUBKEY(pubkey_bio.get(), nullptr, nullptr, (void*)password.c_str()), EVP_PKEY_free);
if (!pkey)
- throw rsa_exception("failed to load public key: PEM_read_bio_PUBKEY failed");
+ throw rsa_exception("failed to load public key: PEM_read_bio_PUBKEY failed:" + std::string(ERR_error_string(ERR_get_error(), NULL)));
return pkey;
}
inline
std::shared_ptr<EVP_PKEY> load_private_key_from_string(const std::string& key, const std::string& password = "") {
std::unique_ptr<BIO, decltype(&BIO_free_all)> privkey_bio(BIO_new(BIO_s_mem()), BIO_free_all);
- if ((size_t)BIO_write(privkey_bio.get(), key.data(), key.size()) != key.size())
+ const int len = static_cast<int>(key.size());
+ if (BIO_write(privkey_bio.get(), key.data(), len) != len)
throw rsa_exception("failed to load private key: bio_write failed");
std::shared_ptr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(privkey_bio.get(), nullptr, nullptr, const_cast<char*>(password.c_str())), EVP_PKEY_free);
if (!pkey)
throw rsa_exception("failed to load private key: PEM_read_bio_PrivateKey failed");
return pkey;
}
+
+ /**
+ * Convert a OpenSSL BIGNUM to a std::string
+ * \param bn BIGNUM to convert
+ * \return bignum as string
+ */
+ inline
+#ifdef OPENSSL10
+ static std::string bn2raw(BIGNUM* bn)
+#else
+ static std::string bn2raw(const BIGNUM* bn)
+#endif
+ {
+ std::string res;
+ res.resize(BN_num_bytes(bn));
+ BN_bn2bin(bn, (unsigned char*)res.data());
+ return res;
+ }
+ /**
+ * Convert an std::string to a OpenSSL BIGNUM
+ * \param raw String to convert
+ * \return BIGNUM representation
+ */
+ inline
+ static std::unique_ptr<BIGNUM, decltype(&BN_free)> raw2bn(const std::string& raw) {
+ return std::unique_ptr<BIGNUM, decltype(&BN_free)>(BN_bin2bn((const unsigned char*)raw.data(), static_cast<int>(raw.size()), nullptr), BN_free);
+ }
}
namespace algorithm {
@@ -166,9 +195,9 @@ namespace jwt {
*/
std::string sign(const std::string& data) const {
std::string res;
- res.resize(EVP_MAX_MD_SIZE);
- unsigned int len = res.size();
- if (HMAC(md(), secret.data(), secret.size(), (const unsigned char*)data.data(), data.size(), (unsigned char*)res.data(), &len) == nullptr)
+ res.resize(static_cast<size_t>(EVP_MAX_MD_SIZE));
+ unsigned int len = static_cast<unsigned int>(res.size());
+ if (HMAC(md(), secret.data(), static_cast<int>(secret.size()), (const unsigned char*)data.data(), static_cast<int>(data.size()), (unsigned char*)res.data(), &len) == nullptr)
throw signature_generation_exception();
res.resize(len);
return res;
@@ -280,7 +309,7 @@ namespace jwt {
throw signature_verification_exception("failed to verify signature: VerifyInit failed");
if (!EVP_VerifyUpdate(ctx.get(), data.data(), data.size()))
throw signature_verification_exception("failed to verify signature: VerifyUpdate failed");
- auto res = EVP_VerifyFinal(ctx.get(), (const unsigned char*)signature.data(), signature.size(), pkey.get());
+ auto res = EVP_VerifyFinal(ctx.get(), (const unsigned char*)signature.data(), static_cast<unsigned int>(signature.size()), pkey.get());
if (res != 1)
throw signature_verification_exception("evp verify final failed: " + std::to_string(res) + " " + ERR_error_string(ERR_get_error(), NULL));
}
@@ -312,35 +341,44 @@ namespace jwt {
* \param md Pointer to hash function
* \param name Name of the algorithm
*/
- 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)(), const std::string& name)
- : md(md), alg_name(name)
+ 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)(), const std::string& name, size_t siglen)
+ : md(md), alg_name(name), signature_length(siglen)
{
if (!public_key.empty()) {
std::unique_ptr<BIO, decltype(&BIO_free_all)> pubkey_bio(BIO_new(BIO_s_mem()), BIO_free_all);
if(public_key.substr(0, 27) == "-----BEGIN CERTIFICATE-----") {
auto epkey = helper::extract_pubkey_from_cert(public_key, public_key_password);
- if ((size_t)BIO_write(pubkey_bio.get(), epkey.data(), epkey.size()) != epkey.size())
+ const int len = static_cast<int>(epkey.size());
+ if (BIO_write(pubkey_bio.get(), epkey.data(), len) != len)
throw ecdsa_exception("failed to load public key: bio_write failed");
} else {
- if ((size_t)BIO_write(pubkey_bio.get(), public_key.data(), public_key.size()) != public_key.size())
+ const int len = static_cast<int>(public_key.size());
+ if (BIO_write(pubkey_bio.get(), public_key.data(), len) != len)
throw ecdsa_exception("failed to load public key: bio_write failed");
}
pkey.reset(PEM_read_bio_EC_PUBKEY(pubkey_bio.get(), nullptr, nullptr, (void*)public_key_password.c_str()), EC_KEY_free);
if (!pkey)
- throw ecdsa_exception("failed to load public key: PEM_read_bio_EC_PUBKEY failed");
+ throw ecdsa_exception("failed to load public key: PEM_read_bio_EC_PUBKEY failed:" + std::string(ERR_error_string(ERR_get_error(), NULL)));
+ size_t keysize = EC_GROUP_get_degree(EC_KEY_get0_group(pkey.get()));
+ if(keysize != signature_length*4 && (signature_length != 132 || keysize != 521))
+ throw ecdsa_exception("invalid key size");
}
if (!private_key.empty()) {
std::unique_ptr<BIO, decltype(&BIO_free_all)> privkey_bio(BIO_new(BIO_s_mem()), BIO_free_all);
- if ((size_t)BIO_write(privkey_bio.get(), private_key.data(), private_key.size()) != private_key.size())
- throw rsa_exception("failed to load private key: bio_write failed");
+ const int len = static_cast<int>(private_key.size());
+ if (BIO_write(privkey_bio.get(), private_key.data(), len) != len)
+ throw ecdsa_exception("failed to load private key: bio_write failed");
pkey.reset(PEM_read_bio_ECPrivateKey(privkey_bio.get(), nullptr, nullptr, const_cast<char*>(private_key_password.c_str())), EC_KEY_free);
if (!pkey)
- throw rsa_exception("failed to load private key: PEM_read_bio_ECPrivateKey failed");
+ throw ecdsa_exception("failed to load private key: PEM_read_bio_ECPrivateKey failed");
+ size_t keysize = EC_GROUP_get_degree(EC_KEY_get0_group(pkey.get()));
+ if(keysize != signature_length*4 && (signature_length != 132 || keysize != 521))
+ throw ecdsa_exception("invalid key size");
}
if(!pkey)
- throw rsa_exception("at least one of public or private key need to be present");
+ throw ecdsa_exception("at least one of public or private key need to be present");
if(EC_KEY_check_key(pkey.get()) == 0)
throw ecdsa_exception("failed to load key: key is invalid");
@@ -355,19 +393,27 @@ namespace jwt {
const std::string hash = generate_hash(data);
std::unique_ptr<ECDSA_SIG, decltype(&ECDSA_SIG_free)>
- sig(ECDSA_do_sign((const unsigned char*)hash.data(), hash.size(), pkey.get()), ECDSA_SIG_free);
+ sig(ECDSA_do_sign((const unsigned char*)hash.data(), static_cast<int>(hash.size()), pkey.get()), ECDSA_SIG_free);
if(!sig)
throw signature_generation_exception();
#ifdef OPENSSL10
- return bn2raw(sig->r) + bn2raw(sig->s);
+ auto rr = helper::bn2raw(sig->r);
+ auto rs = helper::bn2raw(sig->s);
#else
const BIGNUM *r;
const BIGNUM *s;
ECDSA_SIG_get0(sig.get(), &r, &s);
- return bn2raw(r) + bn2raw(s);
+ auto rr = helper::bn2raw(r);
+ auto rs = helper::bn2raw(s);
#endif
+ if(rr.size() > signature_length/2 || rs.size() > signature_length/2)
+ throw std::logic_error("bignum size exceeded expected length");
+ while(rr.size() != signature_length/2) rr = '\0' + rr;
+ while(rs.size() != signature_length/2) rs = '\0' + rs;
+ return rr + rs;
}
+
/**
* Check if signature is valid
* \param data The data to check signature against
@@ -376,8 +422,8 @@ namespace jwt {
*/
void verify(const std::string& data, const std::string& signature) const {
const std::string hash = generate_hash(data);
- auto r = raw2bn(signature.substr(0, signature.size() / 2));
- auto s = raw2bn(signature.substr(signature.size() / 2));
+ auto r = helper::raw2bn(signature.substr(0, signature.size() / 2));
+ auto s = helper::raw2bn(signature.substr(signature.size() / 2));
#ifdef OPENSSL10
ECDSA_SIG sig;
@@ -387,11 +433,11 @@ namespace jwt {
if(ECDSA_do_verify((const unsigned char*)hash.data(), hash.size(), &sig, pkey.get()) != 1)
throw signature_verification_exception("Invalid signature");
#else
- ECDSA_SIG *sig = ECDSA_SIG_new();
+ std::unique_ptr<ECDSA_SIG, decltype(&ECDSA_SIG_free)> sig(ECDSA_SIG_new(), ECDSA_SIG_free);
- ECDSA_SIG_set0(sig, r.get(), s.get());
+ ECDSA_SIG_set0(sig.get(), r.release(), s.release());
- if(ECDSA_do_verify((const unsigned char*)hash.data(), hash.size(), sig, pkey.get()) != 1)
+ if(ECDSA_do_verify((const unsigned char*)hash.data(), static_cast<int>(hash.size()), sig.get(), pkey.get()) != 1)
throw signature_verification_exception("Invalid signature");
#endif
}
@@ -404,38 +450,6 @@ namespace jwt {
}
private:
/**
- * Convert a OpenSSL BIGNUM to a std::string
- * \param bn BIGNUM to convert
- * \return bignum as string
- */
-#ifdef OPENSSL10
- static std::string bn2raw(BIGNUM* bn)
-#else
- static std::string bn2raw(const BIGNUM* bn)
-#endif
- {
- std::string res;
- res.resize(BN_num_bytes(bn));
- BN_bn2bin(bn, (unsigned char*)res.data());
- if(res.size()%2 == 1 && res[0] == 0x00)
- return res.substr(1);
- return res;
- }
- /**
- * Convert an std::string to a OpenSSL BIGNUM
- * \param raw String to convert
- * \return BIGNUM representation
- */
- static std::unique_ptr<BIGNUM, decltype(&BN_free)> raw2bn(const std::string& raw) {
- if(static_cast<uint8_t>(raw[0]) >= 0x80) {
- std::string str(1, 0x00);
- str += raw;
- return std::unique_ptr<BIGNUM, decltype(&BN_free)>(BN_bin2bn((const unsigned char*)str.data(), str.size(), nullptr), BN_free);
- }
- return std::unique_ptr<BIGNUM, decltype(&BN_free)>(BN_bin2bn((const unsigned char*)raw.data(), raw.size(), nullptr), BN_free);
- }
-
- /**
* Hash the provided data using the hash function specified in constructor
* \param data Data to hash
* \return Hash of data
@@ -465,6 +479,8 @@ namespace jwt {
const EVP_MD*(*md)();
/// Algorithmname
const std::string alg_name;
+ /// Length of the resulting signature
+ const size_t signature_length;
};
/**
@@ -524,7 +540,7 @@ namespace jwt {
const int size = RSA_size(key.get());
std::string sig(size, 0x00);
- if(!RSA_public_decrypt(signature.size(), (const unsigned char*)signature.data(), (unsigned char*)sig.data(), key.get(), RSA_NO_PADDING))
+ if(!RSA_public_decrypt(static_cast<int>(signature.size()), (const unsigned char*)signature.data(), (unsigned char*)sig.data(), key.get(), RSA_NO_PADDING))
throw signature_verification_exception("Invalid signature");
if(!RSA_verify_PKCS1_PSS_mgf1(key.get(), (const unsigned char*)hash.data(), md(), md(), (const unsigned char*)sig.data(), -1))
@@ -617,7 +633,7 @@ namespace jwt {
* \param public_key_password Password to decrypt public key pem.
* \param privat_key_password Password to decrypt private key pem.
*/
- rs256(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
+ explicit rs256(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
: rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256, "RS256")
{}
};
@@ -632,7 +648,7 @@ namespace jwt {
* \param public_key_password Password to decrypt public key pem.
* \param privat_key_password Password to decrypt private key pem.
*/
- rs384(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
+ explicit rs384(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
: rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384, "RS384")
{}
};
@@ -647,7 +663,7 @@ namespace jwt {
* \param public_key_password Password to decrypt public key pem.
* \param privat_key_password Password to decrypt private key pem.
*/
- rs512(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
+ explicit rs512(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
: rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512, "RS512")
{}
};
@@ -662,8 +678,8 @@ namespace jwt {
* \param public_key_password Password to decrypt public key pem.
* \param privat_key_password Password to decrypt private key pem.
*/
- es256(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
- : ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256, "ES256")
+ explicit es256(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
+ : ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256, "ES256", 64)
{}
};
/**
@@ -677,8 +693,8 @@ namespace jwt {
* \param public_key_password Password to decrypt public key pem.
* \param privat_key_password Password to decrypt private key pem.
*/
- es384(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
- : ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384, "ES384")
+ explicit es384(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
+ : ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384, "ES384", 96)
{}
};
/**
@@ -692,8 +708,8 @@ namespace jwt {
* \param public_key_password Password to decrypt public key pem.
* \param privat_key_password Password to decrypt private key pem.
*/
- es512(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
- : ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512, "ES512")
+ explicit es512(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
+ : ecdsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512, "ES512", 132)
{}
};
@@ -708,7 +724,7 @@ namespace jwt {
* \param public_key_password Password to decrypt public key pem.
* \param privat_key_password Password to decrypt private key pem.
*/
- ps256(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
+ explicit ps256(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
: pss(public_key, private_key, public_key_password, private_key_password, EVP_sha256, "PS256")
{}
};
@@ -723,7 +739,7 @@ namespace jwt {
* \param public_key_password Password to decrypt public key pem.
* \param privat_key_password Password to decrypt private key pem.
*/
- ps384(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
+ explicit ps384(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
: pss(public_key, private_key, public_key_password, private_key_password, EVP_sha384, "PS384")
{}
};
@@ -738,7 +754,7 @@ namespace jwt {
* \param public_key_password Password to decrypt public key pem.
* \param privat_key_password Password to decrypt private key pem.
*/
- ps512(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
+ explicit ps512(const std::string& public_key, const std::string& private_key = "", const std::string& public_key_password = "", const std::string& private_key_password = "")
: pss(public_key, private_key, public_key_password, private_key_password, EVP_sha512, "PS512")
{}
};
@@ -763,33 +779,28 @@ namespace jwt {
claim()
: val()
{}
-#if JWT_CLAIM_EXPLICIT
- explicit claim(std::string s)
+ JWT_CLAIM_EXPLICIT claim(std::string s)
: val(std::move(s))
{}
- explicit claim(const date& s)
+ JWT_CLAIM_EXPLICIT claim(const date& s)
: val(int64_t(std::chrono::system_clock::to_time_t(s)))
{}
- explicit claim(const std::set<std::string>& s)
+ JWT_CLAIM_EXPLICIT claim(const std::set<std::string>& s)
: val(picojson::array(s.cbegin(), s.cend()))
{}
- explicit claim(const picojson::value& val)
+ JWT_CLAIM_EXPLICIT claim(const picojson::value& val)
: val(val)
{}
-#else
- claim(std::string s)
- : val(std::move(s))
- {}
- claim(const date& s)
- : val(int64_t(std::chrono::system_clock::to_time_t(s)))
- {}
- claim(const std::set<std::string>& s)
- : val(picojson::array(s.cbegin(), s.cend()))
- {}
- claim(const picojson::value& val)
- : val(val)
- {}
-#endif
+
+ template<typename Iterator>
+ claim(Iterator start, Iterator end)
+ : val(picojson::array())
+ {
+ auto& arr = val.get<picojson::array>();
+ for(; start != end; start++) {
+ arr.push_back(picojson::value(*start));
+ }
+ }
/**
* Get wrapped json object
@@ -800,6 +811,15 @@ namespace jwt {
}
/**
+ * Parse input stream into wrapped json object
+ * \return input stream
+ */
+ inline std::istream& operator>>(std::istream& is)
+ {
+ return is >> val;
+ }
+
+ /**
* Get type of contained object
* \return Type
* \throws std::logic_error An internal error occured
@@ -1126,36 +1146,9 @@ namespace jwt {
signature = signature_base64 = token.substr(payload_end + 1);
// Fix padding: JWT requires padding to get removed
- auto fix_padding = [](std::string& str) {
- switch (str.size() % 4) {
- case 1:
- str += alphabet::base64url::fill();
-#ifdef __has_cpp_attribute
-#if __has_cpp_attribute(fallthrough)
- [[fallthrough]];
-#endif
-#endif
- case 2:
- str += alphabet::base64url::fill();
-#ifdef __has_cpp_attribute
-#if __has_cpp_attribute(fallthrough)
- [[fallthrough]];
-#endif
-#endif
- case 3:
- str += alphabet::base64url::fill();
-#ifdef __has_cpp_attribute
-#if __has_cpp_attribute(fallthrough)
- [[fallthrough]];
-#endif
-#endif
- default:
- break;
- }
- };
- fix_padding(header);
- fix_padding(payload);
- fix_padding(signature);
+ header = base::pad<alphabet::base64url>(header);
+ payload = base::pad<alphabet::base64url>(payload);
+ signature = base::pad<alphabet::base64url>(signature);
header = base::decode<alphabet::base64url>(header);
payload = base::decode<alphabet::base64url>(payload);
@@ -1180,37 +1173,37 @@ namespace jwt {
* Get token string, as passed to constructor
* \return token as passed to constructor
*/
- const std::string& get_token() const { return token; }
+ const std::string& get_token() const noexcept { return token; }
/**
* Get header part as json string
* \return header part after base64 decoding
*/
- const std::string& get_header() const { return header; }
+ const std::string& get_header() const noexcept { return header; }
/**
* Get payload part as json string
* \return payload part after base64 decoding
*/
- const std::string& get_payload() const { return payload; }
+ const std::string& get_payload() const noexcept { return payload; }
/**
* Get signature part as json string
* \return signature part after base64 decoding
*/
- const std::string& get_signature() const { return signature; }
+ const std::string& get_signature() const noexcept { return signature; }
/**
* Get header part as base64 string
* \return header part before base64 decoding
*/
- const std::string& get_header_base64() const { return header_base64; }
+ const std::string& get_header_base64() const noexcept { return header_base64; }
/**
* Get payload part as base64 string
* \return payload part before base64 decoding
*/
- const std::string& get_payload_base64() const { return payload_base64; }
+ const std::string& get_payload_base64() const noexcept { return payload_base64; }
/**
* Get signature part as base64 string
* \return signature part before base64 decoding
*/
- const std::string& get_signature_base64() const { return signature_base64; }
+ const std::string& get_signature_base64() const noexcept { return signature_base64; }
};
@@ -1319,12 +1312,11 @@ namespace jwt {
* \return Final token as a string
*/
template<typename T>
- std::string sign(const T& algo) {
- this->set_algorithm(algo.name());
-
+ std::string sign(const T& algo) const {
picojson::object obj_header;
+ obj_header["alg"] = picojson::value(algo.name());
for (auto& e : header_claims) {
- obj_header.insert({ e.first, e.second.to_json() });
+ obj_header[e.first] = e.second.to_json();
}
picojson::object obj_payload;
for (auto& e : payload_claims) {
@@ -1332,10 +1324,7 @@ namespace jwt {
}
auto encode = [](const std::string& data) {
- auto base = base::encode<alphabet::base64url>(data);
- auto pos = base.find(alphabet::base64url::fill());
- base = base.substr(0, pos);
- return base;
+ return base::trim<alphabet::base64url>(base::encode<alphabet::base64url>(data));
};
std::string header = encode(picojson::value(obj_header).serialize());
@@ -1429,6 +1418,13 @@ namespace jwt {
*/
verifier& with_audience(const std::set<std::string>& aud) { return with_claim("aud", claim(aud)); }
/**
+ * Set an audience to check for.
+ * If the specified audiences is not present in the token the check fails.
+ * \param aud Audience to check for.
+ * \return *this to allow chaining
+ */
+ verifier& with_audience(const std::string& aud) { return with_claim("aud", claim(aud)); }
+ /**
* Set an id to check for.
* Check is casesensitive.
* \param id ID to check for.
@@ -1489,6 +1485,10 @@ namespace jwt {
throw token_verification_exception("claim " + key + " does not match expected");
}
}
+ else if (c.get_type() == claim::type::object) {
+ if( c.to_json().serialize() != jc.to_json().serialize())
+ throw token_verification_exception("claim " + key + " does not match expected");
+ }
else if (c.get_type() == claim::type::string) {
if (c.as_string() != jc.as_string())
throw token_verification_exception("claim " + key + " does not match expected");
@@ -1585,3 +1585,13 @@ namespace jwt {
return decoded_jwt(token);
}
}
+
+inline std::istream& operator>>(std::istream& is, jwt::claim& c)
+{
+ return c.operator>>(is);
+}
+
+inline std::ostream& operator<<(std::ostream& os, const jwt::claim& c)
+{
+ return os << c.to_json();
+}
diff --git a/contrib/libs/jwt-cpp/picojson.h b/contrib/libs/jwt-cpp/picojson/picojson.h
index c2321e9728..2fe0e4485f 100644
--- a/contrib/libs/jwt-cpp/picojson.h
+++ b/contrib/libs/jwt-cpp/picojson/picojson.h
@@ -75,13 +75,17 @@ extern "C" {
// experimental support for int64_t (see README.mkdn for detail)
#ifdef PICOJSON_USE_INT64
-
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
-
-#include <errno.h>
+#include <cerrno>
+#if __cplusplus >= 201103L
+#include <cinttypes>
+#else
+extern "C" {
#include <inttypes.h>
+}
+#endif
#endif
// to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0
@@ -1169,4 +1173,4 @@ inline std::ostream &operator<<(std::ostream &os, const picojson::value &x) {
#pragma warning(pop)
#endif
-#endif \ No newline at end of file
+#endif