From 67c26e30b2bbf70484ee0b657f37680710677370 Mon Sep 17 00:00:00 2001 From: Chris Mc Date: Sat, 1 Oct 2022 23:19:11 +0200 Subject: [PATCH 01/10] define a base exception class --- include/jwt-cpp/jwt.h | 28 +++--- tests/ClaimTest.cpp | 2 + tests/JwksTest.cpp | 1 + tests/TokenTest.cpp | 143 +++++++++++++++------------ tests/traits/BoostJsonTest.cpp | 3 +- tests/traits/JsonconsTest.cpp | 3 +- tests/traits/NlohmannTest.cpp | 1 + tests/traits/TraitsTest.cpp.mustache | 3 +- 8 files changed, 102 insertions(+), 82 deletions(-) diff --git a/include/jwt-cpp/jwt.h b/include/jwt-cpp/jwt.h index 4dd77ff56..ef8e65b47 100644 --- a/include/jwt-cpp/jwt.h +++ b/include/jwt-cpp/jwt.h @@ -90,19 +90,23 @@ namespace jwt { * \brief Everything related to error codes issued by the library */ namespace error { - struct signature_verification_exception : public std::system_error { + struct exception : public std::exception { + using exception::exception; + } + + struct signature_verification_exception : exception, public std::system_error { using system_error::system_error; }; - struct signature_generation_exception : public std::system_error { + struct signature_generation_exception : exception, public std::system_error { using system_error::system_error; }; - struct rsa_exception : public std::system_error { + struct rsa_exception : exception, public std::system_error { using system_error::system_error; }; - struct ecdsa_exception : public std::system_error { + struct ecdsa_exception : exception, public std::system_error { using system_error::system_error; }; - struct token_verification_exception : public std::system_error { + struct token_verification_exception : exception, public std::system_error { using system_error::system_error; }; /** @@ -362,15 +366,8 @@ namespace jwt { } } } // namespace error - - // FIXME: Remove - // Keep backward compat at least for a couple of revisions - using error::ecdsa_exception; - using error::rsa_exception; - using error::signature_generation_exception; - using error::signature_verification_exception; - using error::token_verification_exception; } // namespace jwt + namespace std { template<> struct is_error_code_enum : true_type {}; @@ -383,6 +380,7 @@ namespace std { template<> struct is_error_code_enum : true_type {}; } // namespace std + namespace jwt { /** * \brief A collection for working with certificates @@ -2316,13 +2314,13 @@ namespace jwt { /** * Attempt to parse JSON was unsuccessful */ - struct invalid_json_exception : public std::runtime_error { + struct invalid_json_exception : exception, public std::runtime_error { invalid_json_exception() : runtime_error("invalid json") {} }; /** * Attempt to access claim was unsuccessful */ - struct claim_not_present_exception : public std::out_of_range { + struct claim_not_present_exception : exception, public std::out_of_range { claim_not_present_exception() : out_of_range("claim not found") {} }; } // namespace error diff --git a/tests/ClaimTest.cpp b/tests/ClaimTest.cpp index 9ad2cc5a1..509bff2d5 100644 --- a/tests/ClaimTest.cpp +++ b/tests/ClaimTest.cpp @@ -123,6 +123,7 @@ TEST(ClaimTest, PicoJSONTraitsAsDouble) { TEST(ClaimTest, MapOfClaim) { using map = jwt::details::map_of_claims; + ASSERT_THROW(map::parse_claims(R"##(__ not json __)##"), jwt::error::exception); ASSERT_THROW(map::parse_claims(R"##(__ not json __)##"), jwt::error::invalid_json_exception); const map claims{ map::parse_claims(R"##({ "array": [1], "string" : "hello world", "number": 9.9, "bool": true})##")}; @@ -137,5 +138,6 @@ TEST(ClaimTest, MapOfClaim) { ASSERT_EQ(claims.get_claim("string").as_string(), "hello world"); ASSERT_EQ(claims.get_claim("number").as_number(), 9.9); ASSERT_EQ(claims.get_claim("bool").as_bool(), true); + ASSERT_THROW(claims.get_claim("__missing__"), jwt::error::exception); ASSERT_THROW(claims.get_claim("__missing__"), jwt::error::claim_not_present_exception); } diff --git a/tests/JwksTest.cpp b/tests/JwksTest.cpp index 92cb15a2d..6d2b6b8b9 100644 --- a/tests/JwksTest.cpp +++ b/tests/JwksTest.cpp @@ -14,6 +14,7 @@ TEST(JwksTest, OneKeyParse) { "kid": "123456789", "x5t": "NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg" })"; + ASSERT_THROW(jwt::parse_jwk("__not_json__"), jwt::error::exception); ASSERT_THROW(jwt::parse_jwk("__not_json__"), jwt::error::invalid_json_exception); ASSERT_THROW(jwt::parse_jwk(R"##(["not","an","object"])##"), std::bad_cast); diff --git a/tests/TokenTest.cpp b/tests/TokenTest.cpp index 76a3f4ab1..ae447d394 100644 --- a/tests/TokenTest.cpp +++ b/tests/TokenTest.cpp @@ -114,18 +114,23 @@ TEST(TokenTest, CreateTokenES256) { ASSERT_THROW( jwt::verify().allow_algorithm(jwt::algorithm::es256(ecdsa256_pub_key_invalid, "", "", "")).verify(decoded), - jwt::signature_verification_exception); + jwt::error::signature_verification_exception); ASSERT_NO_THROW(jwt::verify().allow_algorithm(jwt::algorithm::es256(ecdsa256_pub_key, "", "", "")).verify(decoded)); } TEST(TokenTest, CreateTokenES256NoPrivate) { - ASSERT_THROW( []() { auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign( jwt::algorithm::es256(ecdsa256_pub_key, "", "", "")); }(), - jwt::signature_generation_exception); + jwt::jwt::error::exception); + ASSERT_THROW( + []() { + auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign( + jwt::algorithm::es256(ecdsa256_pub_key, "", "", "")); + }(), + jwt::jwt::error::signature_generation_exception); } TEST(TokenTest, CreateTokenES384) { @@ -137,7 +142,10 @@ TEST(TokenTest, CreateTokenES384) { ASSERT_THROW( jwt::verify().allow_algorithm(jwt::algorithm::es384(ecdsa384_pub_key_invalid, "", "", "")).verify(decoded), - jwt::signature_verification_exception); + jwt::error::exception); + ASSERT_THROW( + jwt::verify().allow_algorithm(jwt::algorithm::es384(ecdsa384_pub_key_invalid, "", "", "")).verify(decoded), + jwt::error::signature_verification_exception); ASSERT_NO_THROW(jwt::verify().allow_algorithm(jwt::algorithm::es384(ecdsa384_pub_key, "", "", "")).verify(decoded)); } @@ -148,7 +156,7 @@ TEST(TokenTest, CreateTokenES384NoPrivate) { auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign( jwt::algorithm::es384(ecdsa384_pub_key, "", "", "")); }(), - jwt::signature_generation_exception); + jwt::jwt::error::signature_generation_exception); } TEST(TokenTest, CreateTokenES512) { @@ -160,7 +168,7 @@ TEST(TokenTest, CreateTokenES512) { ASSERT_THROW( jwt::verify().allow_algorithm(jwt::algorithm::es512(ecdsa521_pub_key_invalid, "", "", "")).verify(decoded), - jwt::signature_verification_exception); + jwt::error::signature_verification_exception); ASSERT_NO_THROW(jwt::verify().allow_algorithm(jwt::algorithm::es512(ecdsa521_pub_key, "", "", "")).verify(decoded)); } @@ -171,7 +179,7 @@ TEST(TokenTest, CreateTokenES512NoPrivate) { auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign( jwt::algorithm::es512(ecdsa521_pub_key, "", "", "")); }(), - jwt::signature_generation_exception); + jwt::jwt::error::signature_generation_exception); } #if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0) @@ -184,7 +192,7 @@ TEST(TokenTest, CreateTokenEd25519) { ASSERT_THROW( jwt::verify().allow_algorithm(jwt::algorithm::ed25519(ed25519_pub_key_invalid, "", "", "")).verify(decoded), - jwt::signature_verification_exception); + jwt::error::signature_verification_exception); ASSERT_NO_THROW( jwt::verify().allow_algorithm(jwt::algorithm::ed25519(ed25519_pub_key, "", "", "")).verify(decoded)); } @@ -198,7 +206,7 @@ TEST(TokenTest, CreateTokenEd448) { ASSERT_THROW( jwt::verify().allow_algorithm(jwt::algorithm::ed448(ed448_pub_key_invalid, "", "", "")).verify(decoded), - jwt::signature_verification_exception); + jwt::error::signature_verification_exception); ASSERT_NO_THROW(jwt::verify().allow_algorithm(jwt::algorithm::ed448(ed448_pub_key, "", "", "")).verify(decoded)); } #endif @@ -214,7 +222,8 @@ TEST(TokenTest, VerifyTokenWrongAlgorithm) { auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); } TEST(TokenTest, VerifyTokenNoneFail) { @@ -225,7 +234,7 @@ TEST(TokenTest, VerifyTokenNoneFail) { auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } TEST(TokenTest, VerifyTokenRS256FailNoKey) { @@ -233,7 +242,12 @@ TEST(TokenTest, VerifyTokenRS256FailNoKey) { []() { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::rs256("", "", "", "")).with_issuer("auth0"); }(), - jwt::rsa_exception); + jwt::error::exception); + ASSERT_THROW( + []() { + auto verify = jwt::verify().allow_algorithm(jwt::algorithm::rs256("", "", "", "")).with_issuer("auth0"); + }(), + jwt::error::rsa_exception); } TEST(TokenTest, VerifyTokenRS256) { @@ -291,7 +305,7 @@ TEST(TokenTest, VerifyTokenRS256Fail) { auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } TEST(TokenTest, VerifyTokenRS512) { @@ -347,7 +361,7 @@ TEST(TokenTest, VerifyTokenRS512Fail) { auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } TEST(TokenTest, VerifyTokenHS256) { @@ -367,7 +381,7 @@ TEST(TokenTest, VerifyTokenHS256Fail) { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::hs256{"wrongsecret"}).with_issuer("auth0"); auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } TEST(TokenTest, VerifyTokenHS256FailSignatureLength) { @@ -377,7 +391,7 @@ TEST(TokenTest, VerifyTokenHS256FailSignatureLength) { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::hs256{"secret"}).with_issuer("auth0"); auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } TEST(TokenTest, VerifyFail) { @@ -393,42 +407,42 @@ TEST(TokenTest, VerifyFail) { { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_issuer("auth"); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); } { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_type("JWT"); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); } { auto verify = jwt::verify() .allow_algorithm(jwt::algorithm::none{}) .with_issuer("auth0") .with_audience(std::set{"test"}); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); } { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_issuer("auth0").with_audience("test"); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); } { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_issuer("auth0").with_subject("test"); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); } { auto verify = jwt::verify() .allow_algorithm(jwt::algorithm::none{}) .with_issuer("auth0") .with_claim("myclaim", jwt::claim(std::string("test"))); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); } { auto verify = jwt::verify() .allow_algorithm(jwt::algorithm::none{}) .with_issuer("auth0") .with_claim("typetest", jwt::claim(picojson::value(true))); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); } { jwt::claim object; @@ -440,7 +454,7 @@ TEST(TokenTest, VerifyFail) { .allow_algorithm(jwt::algorithm::none{}) .with_issuer("auth0") .with_claim("myclaim", object); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); } } { @@ -451,7 +465,7 @@ TEST(TokenTest, VerifyFail) { { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::none{}).with_issuer("auth0").with_audience("test"); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); } } } @@ -461,7 +475,7 @@ TEST(TokenTest, VerifyTokenES256FailNoKey) { []() { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es256("", "", "", "")).with_issuer("auth0"); }(), - jwt::ecdsa_exception); + jwt::error::ecdsa_exception); } TEST(TokenTest, VerifyTokenES256) { @@ -481,7 +495,7 @@ TEST(TokenTest, VerifyTokenES256Fail) { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es256(ecdsa256_pub_key_invalid, "", "", "")); auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } TEST(TokenTest, VerifyTokenES384) { @@ -503,7 +517,7 @@ TEST(TokenTest, VerifyTokenES384Fail) { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es384(ecdsa384_pub_key_invalid, "", "", "")); auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } TEST(TokenTest, VerifyTokenES521) { @@ -527,7 +541,7 @@ TEST(TokenTest, VerifyTokenES521Fail) { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::es512(ecdsa521_pub_key_invalid, "", "", "")); auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } TEST(TokenTest, VerifyTokenPS256) { @@ -571,7 +585,8 @@ TEST(TokenTest, VerifyTokenPS256Fail) { auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } TEST(TokenTest, VerifyTokenPS256FailNoKey) { @@ -579,7 +594,7 @@ TEST(TokenTest, VerifyTokenPS256FailNoKey) { []() { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::ps256("", "", "", "")).with_issuer("auth0"); }(), - jwt::rsa_exception); + jwt::error::rsa_exception); } #if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0) @@ -602,7 +617,7 @@ TEST(TokenTest, VerifyTokenEd25519Fail) { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::ed25519(ed25519_pub_key_invalid, "", "", "")); auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } TEST(TokenTest, VerifyTokenEd448) { @@ -626,7 +641,7 @@ TEST(TokenTest, VerifyTokenEd448Fail) { auto verify = jwt::verify().allow_algorithm(jwt::algorithm::ed448(ed448_pub_key_invalid, "", "", "")); auto decoded_token = jwt::decode(token); - ASSERT_THROW(verify.verify(decoded_token), jwt::signature_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::signature_verification_exception); } #endif @@ -641,7 +656,7 @@ TEST(TokenTest, VerifyTokenExpireFail) { auto verify = jwt::verify({std::chrono::system_clock::from_time_t(110)}) .allow_algorithm(jwt::algorithm::none{}); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); std::error_code ec; ASSERT_NO_THROW(verify.verify(decoded_token, ec)); ASSERT_TRUE(!(!ec)); @@ -668,7 +683,7 @@ TEST(TokenTest, VerifyTokenNBFFail) { auto verify = jwt::verify({std::chrono::system_clock::from_time_t(90)}) .allow_algorithm(jwt::algorithm::none{}); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); std::error_code ec; ASSERT_NO_THROW(verify.verify(decoded_token, ec)); ASSERT_TRUE(!(!ec)); @@ -695,7 +710,7 @@ TEST(TokenTest, VerifyTokenIATFail) { auto verify = jwt::verify({std::chrono::system_clock::from_time_t(90)}) .allow_algorithm(jwt::algorithm::none{}); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); std::error_code ec; ASSERT_NO_THROW(verify.verify(decoded_token, ec)); ASSERT_TRUE(!(!ec)); @@ -738,36 +753,36 @@ TEST(TokenTest, GetClaimThrows) { TEST(TokenTest, ThrowInvalidKeyLength) { // We should throw if passed the wrong size - ASSERT_THROW(jwt::algorithm::es256(ecdsa384_pub_key, ""), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es256("", ecdsa384_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es256(ecdsa384_pub_key, ecdsa384_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es256(ecdsa521_pub_key, ""), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es256("", ecdsa521_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es256(ecdsa521_pub_key, ecdsa521_priv_key), jwt::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es256(ecdsa384_pub_key, ""), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es256("", ecdsa384_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es256(ecdsa384_pub_key, ecdsa384_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es256(ecdsa521_pub_key, ""), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es256("", ecdsa521_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es256(ecdsa521_pub_key, ecdsa521_priv_key), jwt::error::ecdsa_exception); // But also if only one cert has the wrong size - ASSERT_THROW(jwt::algorithm::es256(ecdsa256_pub_key, ecdsa384_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es256(ecdsa256_pub_key, ecdsa521_priv_key), jwt::ecdsa_exception); - - ASSERT_THROW(jwt::algorithm::es384(ecdsa256_pub_key, ""), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es384("", ecdsa256_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es384(ecdsa256_pub_key, ecdsa256_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es384(ecdsa521_pub_key, ""), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es384("", ecdsa521_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es384(ecdsa521_pub_key, ecdsa521_priv_key), jwt::ecdsa_exception); - - ASSERT_THROW(jwt::algorithm::es384(ecdsa384_pub_key, ecdsa256_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es384(ecdsa384_pub_key, ecdsa521_priv_key), jwt::ecdsa_exception); - - ASSERT_THROW(jwt::algorithm::es512(ecdsa256_pub_key, ""), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es512("", ecdsa256_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es512(ecdsa256_pub_key, ecdsa256_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es512(ecdsa384_pub_key, ""), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es512("", ecdsa384_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es512(ecdsa384_pub_key, ecdsa384_priv_key), jwt::ecdsa_exception); - - ASSERT_THROW(jwt::algorithm::es512(ecdsa521_pub_key, ecdsa256_priv_key), jwt::ecdsa_exception); - ASSERT_THROW(jwt::algorithm::es512(ecdsa521_pub_key, ecdsa384_priv_key), jwt::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es256(ecdsa256_pub_key, ecdsa384_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es256(ecdsa256_pub_key, ecdsa521_priv_key), jwt::error::ecdsa_exception); + + ASSERT_THROW(jwt::algorithm::es384(ecdsa256_pub_key, ""), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es384("", ecdsa256_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es384(ecdsa256_pub_key, ecdsa256_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es384(ecdsa521_pub_key, ""), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es384("", ecdsa521_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es384(ecdsa521_pub_key, ecdsa521_priv_key), jwt::error::ecdsa_exception); + + ASSERT_THROW(jwt::algorithm::es384(ecdsa384_pub_key, ecdsa256_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es384(ecdsa384_pub_key, ecdsa521_priv_key), jwt::error::ecdsa_exception); + + ASSERT_THROW(jwt::algorithm::es512(ecdsa256_pub_key, ""), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es512("", ecdsa256_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es512(ecdsa256_pub_key, ecdsa256_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es512(ecdsa384_pub_key, ""), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es512("", ecdsa384_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es512(ecdsa384_pub_key, ecdsa384_priv_key), jwt::error::ecdsa_exception); + + ASSERT_THROW(jwt::algorithm::es512(ecdsa521_pub_key, ecdsa256_priv_key), jwt::error::ecdsa_exception); + ASSERT_THROW(jwt::algorithm::es512(ecdsa521_pub_key, ecdsa384_priv_key), jwt::error::ecdsa_exception); // Make sure we do not throw if the correct params are passed ASSERT_NO_THROW(jwt::algorithm::es256(ecdsa256_pub_key, ecdsa256_priv_key)); diff --git a/tests/traits/BoostJsonTest.cpp b/tests/traits/BoostJsonTest.cpp index 6c25904f9..d3f8f4d2c 100644 --- a/tests/traits/BoostJsonTest.cpp +++ b/tests/traits/BoostJsonTest.cpp @@ -93,7 +93,8 @@ TEST(BoostJsonTest, VerifyTokenExpired) { const auto decoded_token = jwt::decode(token); const auto verify = jwt::verify().allow_algorithm(jwt::algorithm::hs256{"secret"}).with_issuer("auth0"); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); std::error_code ec; ASSERT_NO_THROW(verify.verify(decoded_token, ec)); diff --git a/tests/traits/JsonconsTest.cpp b/tests/traits/JsonconsTest.cpp index 005c26367..52e2c19bb 100644 --- a/tests/traits/JsonconsTest.cpp +++ b/tests/traits/JsonconsTest.cpp @@ -97,7 +97,8 @@ TEST(JsonconsTest, VerifyTokenExpired) { const auto verify = jwt::verify() .allow_algorithm(jwt::algorithm::hs256{"secret"}) .with_issuer("auth0"); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); std::error_code ec; ASSERT_NO_THROW(verify.verify(decoded_token, ec)); diff --git a/tests/traits/NlohmannTest.cpp b/tests/traits/NlohmannTest.cpp index aa613827b..148a2f1bd 100644 --- a/tests/traits/NlohmannTest.cpp +++ b/tests/traits/NlohmannTest.cpp @@ -92,6 +92,7 @@ TEST(NlohmannTest, VerifyTokenExpired) { const auto decoded_token = jwt::decode(token); const auto verify = jwt::verify().allow_algorithm(jwt::algorithm::hs256{"secret"}).with_issuer("auth0"); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::exception); ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); std::error_code ec; diff --git a/tests/traits/TraitsTest.cpp.mustache b/tests/traits/TraitsTest.cpp.mustache index c690a6106..27c6bc9cc 100644 --- a/tests/traits/TraitsTest.cpp.mustache +++ b/tests/traits/TraitsTest.cpp.mustache @@ -97,7 +97,8 @@ TEST({{test_suite_name}}, VerifyTokenExpired) { const auto verify = jwt::verify() .allow_algorithm(jwt::algorithm::hs256{"secret"}) .with_issuer("auth0"); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); std::error_code ec; ASSERT_NO_THROW(verify.verify(decoded_token, ec)); From c10724d9ed51ca6dae4a281472ac1d6279d7f372 Mon Sep 17 00:00:00 2001 From: Chris Mc Date: Sat, 1 Oct 2022 23:23:45 +0200 Subject: [PATCH 02/10] fix --- include/jwt-cpp/jwt.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/jwt-cpp/jwt.h b/include/jwt-cpp/jwt.h index ef8e65b47..6223febac 100644 --- a/include/jwt-cpp/jwt.h +++ b/include/jwt-cpp/jwt.h @@ -90,9 +90,12 @@ namespace jwt { * \brief Everything related to error codes issued by the library */ namespace error { + /** + * \brief Generic base class for all JWT specific exceptions + */ struct exception : public std::exception { using exception::exception; - } + }; struct signature_verification_exception : exception, public std::system_error { using system_error::system_error; From c437f8215c7647d1b93de48e65f43f123af12639 Mon Sep 17 00:00:00 2001 From: Chris Mc Date: Sat, 1 Oct 2022 23:28:24 +0200 Subject: [PATCH 03/10] add missing namespace --- include/jwt-cpp/jwt.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/include/jwt-cpp/jwt.h b/include/jwt-cpp/jwt.h index 6223febac..2b85659ec 100644 --- a/include/jwt-cpp/jwt.h +++ b/include/jwt-cpp/jwt.h @@ -975,7 +975,7 @@ namespace jwt { } else if (!public_key.empty()) { pkey = helper::load_public_key_from_string(public_key, public_key_password); } else - throw rsa_exception(error::rsa_error::no_key_provided); + throw error::rsa_exception(error::rsa_error::no_key_provided); } /** * Sign jwt data @@ -1085,13 +1085,13 @@ namespace jwt { pkey = helper::load_public_ec_key_from_string(public_key, public_key_password); check_public_key(pkey.get()); } else { - throw ecdsa_exception(error::ecdsa_error::no_key_provided); + throw error::ecdsa_exception(error::ecdsa_error::no_key_provided); } - if (!pkey) throw ecdsa_exception(error::ecdsa_error::invalid_key); + if (!pkey) throw error::ecdsa_exception(error::ecdsa_error::invalid_key); size_t keysize = EVP_PKEY_bits(pkey.get()); if (keysize != signature_length * 4 && (signature_length != 132 || keysize != 521)) - throw ecdsa_exception(error::ecdsa_error::invalid_key_size); + throw error::ecdsa_exception(error::ecdsa_error::invalid_key_size); } /** @@ -1191,12 +1191,12 @@ namespace jwt { #ifdef JWT_OPENSSL_3_0 std::unique_ptr ctx( EVP_PKEY_CTX_new_from_pkey(nullptr, pkey, nullptr), EVP_PKEY_CTX_free); - if (!ctx) { throw ecdsa_exception(error::ecdsa_error::create_context_failed); } - if (EVP_PKEY_public_check(ctx.get()) != 1) { throw ecdsa_exception(error::ecdsa_error::invalid_key); } + if (!ctx) { throw error::ecdsa_exception(error::ecdsa_error::create_context_failed); } + if (EVP_PKEY_public_check(ctx.get()) != 1) { throw error::ecdsa_exception(error::ecdsa_error::invalid_key); } #else std::unique_ptr eckey(EVP_PKEY_get1_EC_KEY(pkey), EC_KEY_free); - if (!eckey) { throw ecdsa_exception(error::ecdsa_error::invalid_key); } - if (EC_KEY_check_key(eckey.get()) == 0) throw ecdsa_exception(error::ecdsa_error::invalid_key); + if (!eckey) { throw error::ecdsa_exception(error::ecdsa_error::invalid_key); } + if (EC_KEY_check_key(eckey.get()) == 0) throw error::ecdsa_exception(error::ecdsa_error::invalid_key); #endif } @@ -1204,12 +1204,12 @@ namespace jwt { #ifdef JWT_OPENSSL_3_0 std::unique_ptr ctx( EVP_PKEY_CTX_new_from_pkey(nullptr, pkey, nullptr), EVP_PKEY_CTX_free); - if (!ctx) { throw ecdsa_exception(error::ecdsa_error::create_context_failed); } - if (EVP_PKEY_private_check(ctx.get()) != 1) { throw ecdsa_exception(error::ecdsa_error::invalid_key); } + if (!ctx) { throw error::ecdsa_exception(error::ecdsa_error::create_context_failed); } + if (EVP_PKEY_private_check(ctx.get()) != 1) { throw error::ecdsa_exception(error::ecdsa_error::invalid_key); } #else std::unique_ptr eckey(EVP_PKEY_get1_EC_KEY(pkey), EC_KEY_free); - if (!eckey) { throw ecdsa_exception(error::ecdsa_error::invalid_key); } - if (EC_KEY_check_key(eckey.get()) == 0) throw ecdsa_exception(error::ecdsa_error::invalid_key); + if (!eckey) { throw error::ecdsa_exception(error::ecdsa_error::invalid_key); } + if (EC_KEY_check_key(eckey.get()) == 0) throw error::ecdsa_exception(error::ecdsa_error::invalid_key); #endif } @@ -1315,7 +1315,7 @@ namespace jwt { } else if (!public_key.empty()) { pkey = helper::load_public_key_from_string(public_key, public_key_password); } else - throw ecdsa_exception(error::ecdsa_error::load_key_bio_read); + throw error::ecdsa_exception(error::ecdsa_error::load_key_bio_read); } /** * Sign jwt data @@ -1450,7 +1450,7 @@ namespace jwt { } else if (!public_key.empty()) { pkey = helper::load_public_key_from_string(public_key, public_key_password); } else - throw rsa_exception(error::rsa_error::no_key_provided); + throw error::rsa_exception(error::rsa_error::no_key_provided); } /** From bb6da777669a5569b4952b66e6cdc610b9fcb6c7 Mon Sep 17 00:00:00 2001 From: Chris Mc Date: Sat, 1 Oct 2022 23:30:45 +0200 Subject: [PATCH 04/10] fix ambiguity --- include/jwt-cpp/jwt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/jwt-cpp/jwt.h b/include/jwt-cpp/jwt.h index 2b85659ec..6a243353b 100644 --- a/include/jwt-cpp/jwt.h +++ b/include/jwt-cpp/jwt.h @@ -94,7 +94,7 @@ namespace jwt { * \brief Generic base class for all JWT specific exceptions */ struct exception : public std::exception { - using exception::exception; + using std::exception::exception; }; struct signature_verification_exception : exception, public std::system_error { From 01b7e20a2ae89a9cc0e750a0cde4755997a424ff Mon Sep 17 00:00:00 2001 From: Chris Mc Date: Sat, 1 Oct 2022 23:32:50 +0200 Subject: [PATCH 05/10] fix copy pasting --- tests/TokenTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/TokenTest.cpp b/tests/TokenTest.cpp index ae447d394..f26e0b170 100644 --- a/tests/TokenTest.cpp +++ b/tests/TokenTest.cpp @@ -124,13 +124,13 @@ TEST(TokenTest, CreateTokenES256NoPrivate) { auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign( jwt::algorithm::es256(ecdsa256_pub_key, "", "", "")); }(), - jwt::jwt::error::exception); + jwt::error::exception); ASSERT_THROW( []() { auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign( jwt::algorithm::es256(ecdsa256_pub_key, "", "", "")); }(), - jwt::jwt::error::signature_generation_exception); + jwt::error::signature_generation_exception); } TEST(TokenTest, CreateTokenES384) { @@ -156,7 +156,7 @@ TEST(TokenTest, CreateTokenES384NoPrivate) { auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign( jwt::algorithm::es384(ecdsa384_pub_key, "", "", "")); }(), - jwt::jwt::error::signature_generation_exception); + jwt::error::signature_generation_exception); } TEST(TokenTest, CreateTokenES512) { @@ -179,7 +179,7 @@ TEST(TokenTest, CreateTokenES512NoPrivate) { auto token = jwt::create().set_issuer("auth0").set_type("JWS").sign( jwt::algorithm::es512(ecdsa521_pub_key, "", "", "")); }(), - jwt::jwt::error::signature_generation_exception); + jwt::error::signature_generation_exception); } #if !defined(JWT_OPENSSL_1_0_0) && !defined(JWT_OPENSSL_1_1_0) From 180055f225e4321007dd542a96fef93a7d86c1e1 Mon Sep 17 00:00:00 2001 From: Chris Mc Date: Sat, 1 Oct 2022 23:36:08 +0200 Subject: [PATCH 06/10] missing namespace --- tests/OpenSSLErrorTest.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/OpenSSLErrorTest.cpp b/tests/OpenSSLErrorTest.cpp index 02da9793c..45ada667b 100644 --- a/tests/OpenSSLErrorTest.cpp +++ b/tests/OpenSSLErrorTest.cpp @@ -490,7 +490,7 @@ TEST(OpenSSLErrorTest, ExtractPubkeyFromCert) { try { jwt::helper::extract_pubkey_from_cert(sample_cert, ""); FAIL(); // Should never reach this - } catch (const jwt::rsa_exception& e) { ec = e.code(); } + } catch (const jwt::error::rsa_exception& e) { ec = e.code(); } }); } @@ -516,7 +516,7 @@ TEST(OpenSSLErrorTest, ConvertCertBase64DerToPem) { try { jwt::helper::convert_base64_der_to_pem(sample_cert_base64_der); FAIL(); // Should never reach this - } catch (const jwt::rsa_exception& e) { ec = e.code(); } + } catch (const jwt::error::rsa_exception& e) { ec = e.code(); } }); } @@ -545,7 +545,7 @@ TEST(OpenSSLErrorTest, LoadPublicKeyFromString) { try { jwt::helper::load_public_key_from_string(rsa_pub_key, ""); FAIL(); // Should never reach this - } catch (const jwt::rsa_exception& e) { ec = e.code(); } + } catch (const jwt::error::rsa_exception& e) { ec = e.code(); } }); } @@ -582,7 +582,7 @@ TEST(OpenSSLErrorTest, LoadPublicKeyCertFromString) { try { jwt::helper::load_public_key_from_string(sample_cert, ""); FAIL(); // Should never reach this - } catch (const jwt::rsa_exception& e) { ec = e.code(); } + } catch (const jwt::error::rsa_exception& e) { ec = e.code(); } }); } @@ -619,7 +619,7 @@ TEST(OpenSSLErrorTest, LoadPrivateKeyFromString) { try { jwt::helper::load_private_key_from_string(rsa_priv_key, ""); FAIL(); // Should never reach this - } catch (const jwt::rsa_exception& e) { ec = e.code(); } + } catch (const jwt::error::rsa_exception& e) { ec = e.code(); } }); } From 9a67f42b821f001fbb45c007aafbfe04b33a9722 Mon Sep 17 00:00:00 2001 From: Chris Mc Date: Sat, 1 Oct 2022 23:41:46 +0200 Subject: [PATCH 07/10] linter --- include/jwt-cpp/jwt.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/jwt-cpp/jwt.h b/include/jwt-cpp/jwt.h index 6a243353b..a1887b1a1 100644 --- a/include/jwt-cpp/jwt.h +++ b/include/jwt-cpp/jwt.h @@ -1192,7 +1192,9 @@ namespace jwt { std::unique_ptr ctx( EVP_PKEY_CTX_new_from_pkey(nullptr, pkey, nullptr), EVP_PKEY_CTX_free); if (!ctx) { throw error::ecdsa_exception(error::ecdsa_error::create_context_failed); } - if (EVP_PKEY_public_check(ctx.get()) != 1) { throw error::ecdsa_exception(error::ecdsa_error::invalid_key); } + if (EVP_PKEY_public_check(ctx.get()) != 1) { + throw error::ecdsa_exception(error::ecdsa_error::invalid_key); + } #else std::unique_ptr eckey(EVP_PKEY_get1_EC_KEY(pkey), EC_KEY_free); if (!eckey) { throw error::ecdsa_exception(error::ecdsa_error::invalid_key); } @@ -1205,7 +1207,9 @@ namespace jwt { std::unique_ptr ctx( EVP_PKEY_CTX_new_from_pkey(nullptr, pkey, nullptr), EVP_PKEY_CTX_free); if (!ctx) { throw error::ecdsa_exception(error::ecdsa_error::create_context_failed); } - if (EVP_PKEY_private_check(ctx.get()) != 1) { throw error::ecdsa_exception(error::ecdsa_error::invalid_key); } + if (EVP_PKEY_private_check(ctx.get()) != 1) { + throw error::ecdsa_exception(error::ecdsa_error::invalid_key); + } #else std::unique_ptr eckey(EVP_PKEY_get1_EC_KEY(pkey), EC_KEY_free); if (!eckey) { throw error::ecdsa_exception(error::ecdsa_error::invalid_key); } From ef502eee384e70522d6c35c131e26d6295d05e30 Mon Sep 17 00:00:00 2001 From: Chris Mc Date: Sat, 1 Oct 2022 23:41:55 +0200 Subject: [PATCH 08/10] traits --- tests/traits/NlohmannTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/traits/NlohmannTest.cpp b/tests/traits/NlohmannTest.cpp index 148a2f1bd..3bad72668 100644 --- a/tests/traits/NlohmannTest.cpp +++ b/tests/traits/NlohmannTest.cpp @@ -93,7 +93,7 @@ TEST(NlohmannTest, VerifyTokenExpired) { const auto verify = jwt::verify().allow_algorithm(jwt::algorithm::hs256{"secret"}).with_issuer("auth0"); ASSERT_THROW(verify.verify(decoded_token), jwt::error::exception); - ASSERT_THROW(verify.verify(decoded_token), jwt::token_verification_exception); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); std::error_code ec; ASSERT_NO_THROW(verify.verify(decoded_token, ec)); From 647449e98dad657bf3164ef6c7f837a1b0da6cb0 Mon Sep 17 00:00:00 2001 From: Christopher McArthur Date: Tue, 4 Oct 2022 17:40:41 +0200 Subject: [PATCH 09/10] messing with exceptions some more --- include/jwt-cpp/base.h | 23 ++- include/jwt-cpp/jwt.h | 168 +++++++++--------- include/jwt-cpp/traits/boost-json/defaults.h | 12 +- .../traits/danielaparker-jsoncons/defaults.h | 12 +- include/jwt-cpp/traits/defaults.h.mustache | 12 +- .../jwt-cpp/traits/kazuho-picojson/defaults.h | 12 +- .../jwt-cpp/traits/nlohmann-json/defaults.h | 12 +- 7 files changed, 133 insertions(+), 118 deletions(-) diff --git a/include/jwt-cpp/base.h b/include/jwt-cpp/base.h index cef493d19..9e0f8f536 100644 --- a/include/jwt-cpp/base.h +++ b/include/jwt-cpp/base.h @@ -18,6 +18,14 @@ #endif namespace jwt { + namespace error { + /** + * An issue ocurred encoding or decoding + */ + struct cryptographic_exception : public std::runtime_error { + using runtime_error::runtime_error + }; + } /** * \brief character maps when encoding and decoding */ @@ -90,7 +98,7 @@ namespace jwt { inline uint32_t index(const std::array& alphabet, char symbol) { auto itr = std::find_if(alphabet.cbegin(), alphabet.cend(), [symbol](char c) { return c == symbol; }); - if (itr == alphabet.cend()) { throw std::runtime_error("Invalid input: not within alphabet"); } + if (itr == alphabet.cend()) { throw error::cryptographic_exception("Invalid input: symbol '" + &symbol + "' not within alphabet"); } return std::distance(alphabet.cbegin(), itr); } @@ -100,7 +108,6 @@ namespace jwt { * \brief A collection of fellable functions for working with base64 and base64url */ namespace base { - namespace details { struct padding { size_t count = 0; @@ -181,10 +188,10 @@ namespace jwt { inline std::string decode(const std::string& base, const std::array& alphabet, const std::vector& fill) { const auto pad = count_padding(base, fill); - if (pad.count > 2) throw std::runtime_error("Invalid input: too much fill"); + if (pad.count > 2) throw error::cryptographic_exception("Invalid input: too much fill"); const size_t size = base.size() - pad.length; - if ((size + pad.count) % 4 != 0) throw std::runtime_error("Invalid input: incorrect total size"); + if ((size + pad.count) % 4 != 0) throw error::cryptographic_exception("Invalid input: incorrect total size"); size_t out_size = size / 4 * 3; std::string res; @@ -251,6 +258,14 @@ namespace jwt { std::string encode(const std::string& bin) { return details::encode(bin, T::data(), T::fill()); } + /** + * \brief base64 decode a string using any alphabet + * + * \tparam T the alphabet to convert back into + * \param base the base64 encoded to decode + * \return std::string containing the decoded contents + * \throw cryptographic_exception + */ template std::string decode(const std::string& base) { return details::decode(base, T::data(), T::fill()); diff --git a/include/jwt-cpp/jwt.h b/include/jwt-cpp/jwt.h index a1887b1a1..a6e636671 100644 --- a/include/jwt-cpp/jwt.h +++ b/include/jwt-cpp/jwt.h @@ -93,24 +93,24 @@ namespace jwt { /** * \brief Generic base class for all JWT specific exceptions */ - struct exception : public std::exception { - using std::exception::exception; + struct exception : public std::system_error { + using system_error::system_error; }; - struct signature_verification_exception : exception, public std::system_error { - using system_error::system_error; + struct signature_verification_exception : exception { + using exception::exception; }; - struct signature_generation_exception : exception, public std::system_error { - using system_error::system_error; + struct signature_generation_exception : exception { + using exception::exception; }; - struct rsa_exception : exception, public std::system_error { - using system_error::system_error; + struct rsa_exception : exception { + using exception::exception; }; - struct ecdsa_exception : exception, public std::system_error { - using system_error::system_error; + struct ecdsa_exception : exception { + using exception::exception; }; - struct token_verification_exception : exception, public std::system_error { - using system_error::system_error; + struct token_verification_exception : exception { + using exception::exception; }; /** * \brief Errors related to processing of RSA signatures @@ -418,7 +418,7 @@ namespace jwt { std::shared_ptr m_key{nullptr}; #else /** - * \brief Contruct a new handle. The handle takes ownership of the key. + * \brief Construct a new handle. The handle takes ownership of the key. * \param key The key to store */ explicit constexpr evp_pkey_handle(EVP_PKEY* key) noexcept : m_key{key} {} @@ -475,7 +475,7 @@ namespace jwt { * * \param certstr String containing the certificate encoded as pem * \param pw Password used to decrypt certificate (leave empty if not encrypted) - * \param ec error_code for error_detection (gets cleared if no error occures) + * \param ec error_code for error_detection (gets cleared if no error ocurred) */ inline std::string extract_pubkey_from_cert(const std::string& certstr, const std::string& pw, std::error_code& ec) { @@ -2250,14 +2250,14 @@ namespace jwt { /** * Get type of contained JSON value * \return Type - * \throw std::logic_error An internal error occured + * \throw logic_error An internal error occured */ json::type get_type() const { return json_traits::get_type(val); } /** * Get the contained JSON value as a string * \return content as string - * \throw std::bad_cast Content was not a string + * \throw bad_cast Content was not a string */ typename json_traits::string_type as_string() const { return json_traits::as_string(val); } @@ -2267,7 +2267,7 @@ namespace jwt { * If the value is a decimal, it is rounded up to the closest integer * * \return content as date - * \throw std::bad_cast Content was not a date + * \throw bad_cast Content was not a date */ date as_date() const { using std::chrono::system_clock; @@ -2278,14 +2278,14 @@ namespace jwt { /** * Get the contained JSON value as an array * \return content as array - * \throw std::bad_cast Content was not an array + * \throw bad_cast Content was not an array */ typename json_traits::array_type as_array() const { return json_traits::as_array(val); } /** * Get the contained JSON value as a set of strings * \return content as set of strings - * \throw std::bad_cast Content was not an array of string + * \throw bad_cast Content was not an array of string */ set_t as_set() const { set_t res; @@ -2298,21 +2298,21 @@ namespace jwt { /** * Get the contained JSON value as an integer * \return content as int - * \throw std::bad_cast Content was not an int + * \throw bad_cast Content was not an int */ typename json_traits::integer_type as_int() const { return json_traits::as_int(val); } /** * Get the contained JSON value as a bool * \return content as bool - * \throw std::bad_cast Content was not a bool + * \throw bad_cast Content was not a bool */ typename json_traits::boolean_type as_bool() const { return json_traits::as_bool(val); } /** * Get the contained JSON value as a number * \return content as double - * \throw std::bad_cast Content was not a number + * \throw bad_cast Content was not a number */ typename json_traits::number_type as_number() const { return json_traits::as_number(val); } }; @@ -2325,10 +2325,10 @@ namespace jwt { invalid_json_exception() : runtime_error("invalid json") {} }; /** - * Attempt to access claim was unsuccessful + * Attempt to access claim or json key was unsuccessful */ struct claim_not_present_exception : exception, public std::out_of_range { - claim_not_present_exception() : out_of_range("claim not found") {} + claim_not_present_exception(const char* key) : out_of_range("claim '" key "' not found") {} }; } // namespace error @@ -2388,7 +2388,7 @@ namespace jwt { * \throw jwt::error::claim_not_present_exception if the claim was not present */ basic_claim_t get_claim(const typename json_traits::string_type& name) const { - if (!has_claim(name)) throw error::claim_not_present_exception(); + if (!has_claim(name)) throw error::claim_not_present_exception(name.c_str()); return basic_claim_t{claims.at(name)}; } @@ -2459,22 +2459,22 @@ namespace jwt { /** * Get issuer claim * \return issuer as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_issuer() const { return get_payload_claim("iss").as_string(); } /** * Get subject claim * \return subject as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_subject() const { return get_payload_claim("sub").as_string(); } /** * Get audience claim * \return audience as a set of strings - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a set (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a set (Should not happen in a valid token) */ typename basic_claim_t::set_t get_audience() const { auto aud = get_payload_claim("aud"); @@ -2485,29 +2485,29 @@ namespace jwt { /** * Get expires claim * \return expires as a date in utc - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a date (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a date (Should not happen in a valid token) */ date get_expires_at() const { return get_payload_claim("exp").as_date(); } /** * Get not valid before claim * \return nbf date in utc - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a date (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a date (Should not happen in a valid token) */ date get_not_before() const { return get_payload_claim("nbf").as_date(); } /** * Get issued at claim * \return issued at as date in utc - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a date (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a date (Should not happen in a valid token) */ date get_issued_at() const { return get_payload_claim("iat").as_date(); } /** * Get id claim * \return id as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_id() const { return get_payload_claim("jti").as_string(); } /** @@ -2520,7 +2520,7 @@ namespace jwt { /** * Get payload claim * \return Requested claim - * \throw std::runtime_error If claim was not present + * \throw runtime_error If claim was not present */ basic_claim_t get_payload_claim(const typename json_traits::string_type& name) const { return payload_claims.get_claim(name); @@ -2561,29 +2561,29 @@ namespace jwt { /** * Get algorithm claim * \return algorithm as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_algorithm() const { return get_header_claim("alg").as_string(); } /** * Get type claim * \return type as a string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_type() const { return get_header_claim("typ").as_string(); } /** * Get content type claim * \return content type as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_content_type() const { return get_header_claim("cty").as_string(); } /** * Get key id claim * \return key id as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_key_id() const { return get_header_claim("kid").as_string(); } /** @@ -2596,7 +2596,7 @@ namespace jwt { /** * Get header claim * \return Requested claim - * \throw std::runtime_error If claim was not present + * \throw runtime_error If claim was not present */ basic_claim_t get_header_claim(const typename json_traits::string_type& name) const { return header_claims.get_claim(name); @@ -2633,8 +2633,8 @@ namespace jwt { * \note Decodes using the jwt::base64url which supports an std::string * * \param token The token to parse - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ JWT_CLAIM_EXPLICIT decoded_jwt(const typename json_traits::string_type& token) : decoded_jwt(token, [](const typename json_traits::string_type& str) { @@ -2649,8 +2649,8 @@ namespace jwt { * return the results. * \param token The token to parse * \param decode The function to decode the token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ template decoded_jwt(const typename json_traits::string_type& token, Decode decode) : token(token) { @@ -3416,40 +3416,40 @@ namespace jwt { * * This returns the general type (e.g. RSA or EC), not a specific algorithm value. * \return key type as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_key_type() const { return get_jwk_claim("kty").as_string(); } /** * Get public key usage claim * \return usage parameter as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_use() const { return get_jwk_claim("use").as_string(); } /** * Get key operation types claim * \return key operation types as a set of strings - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename basic_claim_t::set_t get_key_operations() const { return get_jwk_claim("key_ops").as_set(); } /** * Get algorithm claim * \return algorithm as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_algorithm() const { return get_jwk_claim("alg").as_string(); } /** * Get key id claim * \return key id as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_key_id() const { return get_jwk_claim("kid").as_string(); } @@ -3460,52 +3460,52 @@ namespace jwt { * https://www.iana.org/assignments/jose/jose.xhtml#table-web-key-elliptic-curve * * \return curve as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_curve() const { return get_jwk_claim("crv").as_string(); } /** * Get x5c claim * \return x5c as an array - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a array (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a array (Should not happen in a valid token) */ typename json_traits::array_type get_x5c() const { return get_jwk_claim("x5c").as_array(); }; /** * Get X509 URL claim * \return x5u as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_x5u() const { return get_jwk_claim("x5u").as_string(); }; /** * Get X509 thumbprint claim * \return x5t as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_x5t() const { return get_jwk_claim("x5t").as_string(); }; /** * Get X509 SHA256 thumbprint claim * \return x5t#S256 as string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_x5t_sha256() const { return get_jwk_claim("x5t#S256").as_string(); }; /** * Get x5c claim as a string * \return x5c as an string - * \throw std::runtime_error If claim was not present - * \throw std::bad_cast Claim was present but not a string (Should not happen in a valid token) + * \throw runtime_error If claim was not present + * \throw bad_cast Claim was present but not a string (Should not happen in a valid token) */ typename json_traits::string_type get_x5c_key_value() const { auto x5c_array = get_jwk_claim("x5c").as_array(); - if (x5c_array.size() == 0) throw error::claim_not_present_exception(); + if (x5c_array.size() == 0) throw error::claim_not_present_exception("x5c"); return json_traits::as_string(x5c_array.front()); }; @@ -3581,7 +3581,7 @@ namespace jwt { /** * Get jwks claim * \return Requested claim - * \throw std::runtime_error If claim was not present + * \throw runtime_error If claim was not present */ basic_claim_t get_jwk_claim(const typename json_traits::string_type& name) const { return jwk_claims.get_claim(name); @@ -3621,7 +3621,7 @@ namespace jwt { if (!json_traits::parse(parsed_val, str)) throw error::invalid_json_exception(); const details::map_of_claims jwks_json = json_traits::as_object(parsed_val); - if (!jwks_json.has_claim("keys")) throw error::invalid_json_exception(); + if (!jwks_json.has_claim("keys")) throw error::claim_not_present_exception("keys"); auto jwk_list = jwks_json.get_claim("keys").as_array(); std::transform(jwk_list.begin(), jwk_list.end(), std::back_inserter(jwk_claims), @@ -3646,11 +3646,11 @@ namespace jwt { /** * Get jwk * \return Requested jwk by key_id - * \throw std::runtime_error If jwk was not present + * \throw runtime_error If jwk was not present */ jwk_t get_jwk(const typename json_traits::string_type& key_id) const { const auto maybe = find_by_kid(key_id); - if (maybe == end()) throw error::claim_not_present_exception(); + if (maybe == end()) throw error::claim_not_present_exception(key_id.c_str()); return *maybe; } @@ -3705,8 +3705,8 @@ namespace jwt { * \param token Token to decode * \param decode function that will pad and base64url decode the token * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ template decoded_jwt decode(const typename json_traits::string_type& token, Decode decode) { @@ -3717,8 +3717,8 @@ namespace jwt { * Decode a token * \param token Token to decode * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ template decoded_jwt decode(const typename json_traits::string_type& token) { diff --git a/include/jwt-cpp/traits/boost-json/defaults.h b/include/jwt-cpp/traits/boost-json/defaults.h index affeffe84..e01395132 100644 --- a/include/jwt-cpp/traits/boost-json/defaults.h +++ b/include/jwt-cpp/traits/boost-json/defaults.h @@ -34,8 +34,8 @@ namespace jwt { * Decode a token * \param token Token to decode * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ inline decoded_jwt decode(const std::string& token) { return decoded_jwt(token); @@ -50,8 +50,8 @@ namespace jwt { * \param token Token to decode * \param decode The token to parse * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ template decoded_jwt decode(const std::string& token, Decode decode) { @@ -62,7 +62,7 @@ namespace jwt { * Parse a jwk * \param token JWK Token to parse * \return Parsed JWK - * \throw std::runtime_error Token is not in correct format + * \throw runtime_error Token is not in correct format */ inline jwk parse_jwk(const traits::boost_json::string_type& token) { return jwk(token); @@ -72,7 +72,7 @@ namespace jwt { * Parse a jwks * \param token JWKs Token to parse * \return Parsed JWKs - * \throw std::runtime_error Token is not in correct format + * \throw runtime_error Token is not in correct format */ inline jwks parse_jwks(const traits::boost_json::string_type& token) { return jwks(token); diff --git a/include/jwt-cpp/traits/danielaparker-jsoncons/defaults.h b/include/jwt-cpp/traits/danielaparker-jsoncons/defaults.h index 47e12f5f0..b38929e61 100644 --- a/include/jwt-cpp/traits/danielaparker-jsoncons/defaults.h +++ b/include/jwt-cpp/traits/danielaparker-jsoncons/defaults.h @@ -34,8 +34,8 @@ namespace jwt { * Decode a token * \param token Token to decode * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ inline decoded_jwt decode(const std::string& token) { return decoded_jwt(token); @@ -50,8 +50,8 @@ namespace jwt { * \param token Token to decode * \param decode The token to parse * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ template decoded_jwt decode(const std::string& token, Decode decode) { @@ -62,7 +62,7 @@ namespace jwt { * Parse a jwk * \param token JWK Token to parse * \return Parsed JWK - * \throw std::runtime_error Token is not in correct format + * \throw runtime_error Token is not in correct format */ inline jwk parse_jwk(const traits::danielaparker_jsoncons::string_type& token) { return jwk(token); @@ -72,7 +72,7 @@ namespace jwt { * Parse a jwks * \param token JWKs Token to parse * \return Parsed JWKs - * \throw std::runtime_error Token is not in correct format + * \throw runtime_error Token is not in correct format */ inline jwks parse_jwks(const traits::danielaparker_jsoncons::string_type& token) { return jwks(token); diff --git a/include/jwt-cpp/traits/defaults.h.mustache b/include/jwt-cpp/traits/defaults.h.mustache index ab2a84721..e0463f99f 100644 --- a/include/jwt-cpp/traits/defaults.h.mustache +++ b/include/jwt-cpp/traits/defaults.h.mustache @@ -36,8 +36,8 @@ namespace jwt { * Decode a token * \param token Token to decode * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ inline decoded_jwt decode(const std::string& token) { return decoded_jwt(token); @@ -52,8 +52,8 @@ namespace jwt { * \param token Token to decode * \param decode The token to parse * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ template decoded_jwt decode(const std::string& token, Decode decode) { @@ -64,7 +64,7 @@ namespace jwt { * Parse a jwk * \param token JWK Token to parse * \return Parsed JWK - * \throw std::runtime_error Token is not in correct format + * \throw runtime_error Token is not in correct format */ inline jwk parse_jwk(const traits::{{traits_name}}::string_type& token) { return jwk(token); @@ -74,7 +74,7 @@ namespace jwt { * Parse a jwks * \param token JWKs Token to parse * \return Parsed JWKs - * \throw std::runtime_error Token is not in correct format + * \throw runtime_error Token is not in correct format */ inline jwks parse_jwks(const traits::{{traits_name}}::string_type& token) { return jwks(token); diff --git a/include/jwt-cpp/traits/kazuho-picojson/defaults.h b/include/jwt-cpp/traits/kazuho-picojson/defaults.h index 0c82133a6..36ea7cbaa 100644 --- a/include/jwt-cpp/traits/kazuho-picojson/defaults.h +++ b/include/jwt-cpp/traits/kazuho-picojson/defaults.h @@ -30,8 +30,8 @@ namespace jwt { * Decode a token * \param token Token to decode * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ inline decoded_jwt decode(const std::string& token) { return decoded_jwt(token); @@ -46,8 +46,8 @@ namespace jwt { * \param token Token to decode * \param decode The token to parse * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ template decoded_jwt decode(const std::string& token, Decode decode) { @@ -58,7 +58,7 @@ namespace jwt { * Parse a jwk * \param token JWK Token to parse * \return Parsed JWK - * \throw std::runtime_error Token is not in correct format + * \throw runtime_error Token is not in correct format */ inline jwk parse_jwk(const traits::kazuho_picojson::string_type& token) { return jwk(token); @@ -68,7 +68,7 @@ namespace jwt { * Parse a jwks * \param token JWKs Token to parse * \return Parsed JWKs - * \throw std::runtime_error Token is not in correct format + * \throw runtime_error Token is not in correct format */ inline jwks parse_jwks(const traits::kazuho_picojson::string_type& token) { return jwks(token); diff --git a/include/jwt-cpp/traits/nlohmann-json/defaults.h b/include/jwt-cpp/traits/nlohmann-json/defaults.h index c324075f8..5c51ae671 100644 --- a/include/jwt-cpp/traits/nlohmann-json/defaults.h +++ b/include/jwt-cpp/traits/nlohmann-json/defaults.h @@ -34,8 +34,8 @@ namespace jwt { * Decode a token * \param token Token to decode * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ inline decoded_jwt decode(const std::string& token) { return decoded_jwt(token); @@ -50,8 +50,8 @@ namespace jwt { * \param token Token to decode * \param decode The token to parse * \return Decoded token - * \throw std::invalid_argument Token is not in correct format - * \throw std::runtime_error Base64 decoding failed or invalid json + * \throw invalid_argument Token is not in correct format + * \throw runtime_error Base64 decoding failed or invalid json */ template decoded_jwt decode(const std::string& token, Decode decode) { @@ -62,7 +62,7 @@ namespace jwt { * Parse a jwk * \param token JWK Token to parse * \return Parsed JWK - * \throw std::runtime_error Token is not in correct format + * \throw runtime_error Token is not in correct format */ inline jwk parse_jwk(const traits::nlohmann_json::string_type& token) { return jwk(token); @@ -72,7 +72,7 @@ namespace jwt { * Parse a jwks * \param token JWKs Token to parse * \return Parsed JWKs - * \throw std::runtime_error Token is not in correct format + * \throw runtime_error Token is not in correct format */ inline jwks parse_jwks(const traits::nlohmann_json::string_type& token) { return jwks(token); From c465e4d64d35206e8fcea2dfb6bf4d956898ea85 Mon Sep 17 00:00:00 2001 From: Christopher McArthur Date: Tue, 4 Oct 2022 17:54:44 -0400 Subject: [PATCH 10/10] add missing error code --- include/jwt-cpp/jwt.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/jwt-cpp/jwt.h b/include/jwt-cpp/jwt.h index a6e636671..c7cb869ef 100644 --- a/include/jwt-cpp/jwt.h +++ b/include/jwt-cpp/jwt.h @@ -265,7 +265,8 @@ namespace jwt { rsa_private_encrypt_failed, get_key_failed, set_rsa_pss_saltlen_failed, - signature_decoding_failed + signature_decoding_failed, + size_exceeded_expected_length }; /** * \brief Error category for signature generation errors @@ -303,6 +304,8 @@ namespace jwt { return "failed to create signature: EVP_PKEY_CTX_set_rsa_pss_saltlen failed"; case signature_generation_error::signature_decoding_failed: return "failed to create signature: d2i_ECDSA_SIG failed"; + case signature_generation_error::size_exceeded_expected_length: + return "failed to create signature: calculated bignum for r or s components exceeds signature length" default: return "unknown signature generation error"; } } @@ -1227,7 +1230,6 @@ namespace jwt { } #ifdef JWT_OPENSSL_1_0_0 - auto rr = helper::bn2raw(sig->r); auto rs = helper::bn2raw(sig->s); #else @@ -1237,8 +1239,10 @@ namespace jwt { 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"); + if (rr.size() > signature_length / 2 || rs.size() > signature_length / 2){ + ec = error::signature_generation_error::size_exceeded_expected_length; + return {}; + } rr.insert(0, signature_length / 2 - rr.size(), '\0'); rs.insert(0, signature_length / 2 - rs.size(), '\0'); return rr + rs;