Skip to content

Commit

Permalink
scitokens_internal: catch matching exception type after jwt-cpp update (
Browse files Browse the repository at this point in the history
#125)

After updating the vendored jwt-cpp version in:
 a8c5977
the exception type if a claim is not found has changed,
breaking the "no kid claim" use case.

The vendored jwt-cpp version offers a convenience function
to check whether the header claim is present, use that instead of
accessing it and catching the exception.


Co-authored-by: Derek Weitzel <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 5, 2023
1 parent 3d17d51 commit e0251c9
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 5 deletions.
9 changes: 4 additions & 5 deletions src/scitokens_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,9 @@ class SciTokenKey {
m_private(private_contents) {}

std::string serialize(jwt::builder<jwt::traits::kazuho_picojson> &builder) {
std::error_code ec;
builder.set_key_id(m_kid);
if (m_kid != "none") {
builder.set_key_id(m_kid);
}
return builder.sign(*this);
}

Expand Down Expand Up @@ -496,10 +497,8 @@ class Validator {
std::string algorithm;
// Key id is optional in the RFC, set to blank if it doesn't exist
std::string key_id;
try {
if (jwt.has_key_id()) {
key_id = jwt.get_key_id();
} catch (const std::runtime_error &) {
// Don't do anything, key_id is empty, as it should be.
}
auto status =
get_public_key_pem(jwt.get_issuer(), key_id, public_pem, algorithm);
Expand Down
80 changes: 80 additions & 0 deletions test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,86 @@ TEST_F(SerializeTest, ExplicitTime) {
enforcer_destroy(enforcer);
}

class SerializeNoKidTest : public ::testing::Test {
protected:
void SetUp() override {
char *err_msg;
m_key = KeyPtr(scitoken_key_create("none", "ES256", ec_public,
ec_private, &err_msg),
scitoken_key_destroy);
ASSERT_TRUE(m_key.get() != nullptr);

m_token = TokenPtr(scitoken_create(m_key.get()), scitoken_destroy);
ASSERT_TRUE(m_token.get() != nullptr);

auto rv = scitoken_set_claim_string(
m_token.get(), "iss", "https://demo.scitokens.org/gtest", &err_msg);
ASSERT_TRUE(rv == 0);

rv = scitoken_store_public_ec_key("https://demo.scitokens.org/gtest",
"1", ec_public, &err_msg);
ASSERT_TRUE(rv == 0);

scitoken_set_lifetime(m_token.get(), 60);

m_audiences_array.push_back("https://demo.scitokens.org/");
m_audiences_array.push_back(nullptr);

const char *groups[3] = {nullptr, nullptr, nullptr};
const char group0[] = "group0";
const char group1[] = "group1";
groups[0] = group0;
groups[1] = group1;
rv = scitoken_set_claim_string_list(m_token.get(), "groups", groups,
&err_msg);
ASSERT_TRUE(rv == 0);

m_read_token.reset(scitoken_create(nullptr));
ASSERT_TRUE(m_read_token.get() != nullptr);
}

using KeyPtr = std::unique_ptr<void, decltype(&scitoken_key_destroy)>;
KeyPtr m_key{nullptr, scitoken_key_destroy};

using TokenPtr = std::unique_ptr<void, decltype(&scitoken_destroy)>;
TokenPtr m_token{nullptr, scitoken_destroy};

std::vector<const char *> m_audiences_array;

TokenPtr m_read_token{nullptr, scitoken_destroy};
};

TEST_F(SerializeNoKidTest, VerifyATJWTTest) {

char *err_msg = nullptr;

// Serialize as at+jwt token.
char *token_value = nullptr;
scitoken_set_serialize_profile(m_token.get(), SciTokenProfile::AT_JWT);
auto rv = scitoken_serialize(m_token.get(), &token_value, &err_msg);
ASSERT_TRUE(rv == 0);
std::unique_ptr<char, decltype(&free)> token_value_ptr(token_value, free);

// Accepts any profile.
rv = scitoken_deserialize_v2(token_value, m_read_token.get(), nullptr,
&err_msg);
ASSERT_TRUE(rv == 0);

// Accepts only an at+jwt token, should work with at+jwt token
scitoken_set_deserialize_profile(m_read_token.get(),
SciTokenProfile::AT_JWT);
rv = scitoken_deserialize_v2(token_value, m_read_token.get(), nullptr,
&err_msg);
ASSERT_TRUE(rv == 0);

// Accepts only SciToken 2.0; should fail
scitoken_set_deserialize_profile(m_read_token.get(),
SciTokenProfile::SCITOKENS_2_0);
rv = scitoken_deserialize_v2(token_value, m_read_token.get(), nullptr,
&err_msg);
ASSERT_FALSE(rv == 0);
}

int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
Expand Down

0 comments on commit e0251c9

Please sign in to comment.