From 803570cd4f7ffbb3d7a329b0b9450748b3ca335d Mon Sep 17 00:00:00 2001 From: Pritha Srivastava Date: Tue, 4 May 2021 22:25:58 +0530 Subject: [PATCH] rgw/sts: code to fetch certs using .well-known/openid-configuration url which is oidc standard compliant. The bug and fix were suggested by Pietari Hyvarinen Fixes: https://tracker.ceph.com/issues/50721 Signed-off-by: Pritha Srivastava --- src/rgw/rgw_rest_sts.cc | 40 +++++++++++++++++++++++++++++++++++++++- src/rgw/rgw_rest_sts.h | 2 ++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/rgw/rgw_rest_sts.cc b/src/rgw/rgw_rest_sts.cc index 25dd117450c55..7d51d699b6467 100644 --- a/src/rgw/rgw_rest_sts.cc +++ b/src/rgw/rgw_rest_sts.cc @@ -198,12 +198,50 @@ WebTokenEngine::get_from_jwt(const DoutPrefixProvider* dpp, const std::string& t return t; } +std::string +WebTokenEngine::get_cert_url(const string& iss, const DoutPrefixProvider *dpp, optional_yield y) const +{ + string cert_url; + string openidc_wellknown_url = iss + "/.well-known/openid-configuration"; + bufferlist openidc_resp; + RGWHTTPTransceiver openidc_req(cct, "GET", openidc_wellknown_url, &openidc_resp); + + //Headers + openidc_req.append_header("Content-Type", "application/x-www-form-urlencoded"); + + int res = openidc_req.process(y); + if (res < 0) { + ldpp_dout(dpp, 10) << "HTTP request res: " << res << dendl; + throw -EINVAL; + } + + //Debug only + ldpp_dout(dpp, 20) << "HTTP status: " << openidc_req.get_http_status() << dendl; + ldpp_dout(dpp, 20) << "JSON Response is: " << openidc_resp.c_str() << dendl; + + JSONParser parser; + if (parser.parse(openidc_resp.c_str(), openidc_resp.length())) { + JSONObj::data_val val; + if (parser.get_data("jwks_uri", &val)) { + cert_url = val.str.c_str(); + ldpp_dout(dpp, 20) << "Cert URL is: " << cert_url.c_str() << dendl; + } else { + ldpp_dout(dpp, 0) << "Malformed json returned while fetching openidc url" << dendl; + } + } + return cert_url; +} + void WebTokenEngine::validate_signature(const DoutPrefixProvider* dpp, const jwt::decoded_jwt& decoded, const string& algorithm, const string& iss, const vector& thumbprints, optional_yield y) const { if (algorithm != "HS256" && algorithm != "HS384" && algorithm != "HS512") { + string cert_url = get_cert_url(iss, dpp, y); + if (cert_url.empty()) { + throw -EINVAL; + } + // Get certificate - string cert_url = iss + "/protocol/openid-connect/certs"; bufferlist cert_resp; RGWHTTPTransceiver cert_req(cct, "GET", cert_url, &cert_resp); //Headers diff --git a/src/rgw/rgw_rest_sts.h b/src/rgw/rgw_rest_sts.h index 59c7fa59cb642..396b3cbe52b94 100644 --- a/src/rgw/rgw_rest_sts.h +++ b/src/rgw/rgw_rest_sts.h @@ -33,6 +33,8 @@ class WebTokenEngine : public rgw::auth::Engine { std::string get_role_tenant(const string& role_arn) const; + std::string get_cert_url(const string& iss, const DoutPrefixProvider *dpp,optional_yield y) const; + boost::optional get_from_jwt(const DoutPrefixProvider* dpp, const std::string& token, const req_state* const s, optional_yield y) const; -- 2.39.5